diff --git a/.gitignore b/.gitignore index adf8cf53..829090ca 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,12 @@ *.bmbp *.apbp *.apmc +*.apz5 *.pyc *.pyd *.sfc +*.z64 +*.n64 *.wixobj *.lck *.db3 diff --git a/BaseClasses.py b/BaseClasses.py index 55f88efe..ba14dcda 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -888,6 +888,8 @@ class Location(): locked: bool = False spot_type = 'Location' game: str = "Generic" + show_in_spoiler: bool = True + excluded: bool = False crystal: bool = False always_allow = staticmethod(lambda item, state: False) access_rule = staticmethod(lambda state: True) @@ -1031,24 +1033,24 @@ class Spoiler(): self.locations = OrderedDict() listed_locations = set() - lw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.LightWorld] + lw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.LightWorld and loc.show_in_spoiler] self.locations['Light World'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in lw_locations]) listed_locations.update(lw_locations) - dw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.DarkWorld] + dw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.DarkWorld and loc.show_in_spoiler] self.locations['Dark World'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in dw_locations]) listed_locations.update(dw_locations) - cave_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.Cave] + cave_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.Cave and loc.show_in_spoiler] self.locations['Caves'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in cave_locations]) listed_locations.update(cave_locations) for dungeon in self.world.dungeons.values(): - dungeon_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.dungeon == dungeon] + dungeon_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.dungeon == dungeon and loc.show_in_spoiler] self.locations[str(dungeon)] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in dungeon_locations]) listed_locations.update(dungeon_locations) - other_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations] + other_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.show_in_spoiler] if other_locations: self.locations['Other Locations'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in other_locations]) listed_locations.update(other_locations) diff --git a/Generate.py b/Generate.py index 927c9e0e..211d6f0a 100644 --- a/Generate.py +++ b/Generate.py @@ -501,7 +501,7 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b for option_name, option in AutoWorldRegister.world_types[ret.game].options.items(): if option_name in game_weights: try: - if issubclass(option, Options.OptionDict): + if issubclass(option, Options.OptionDict) or issubclass(option, Options.OptionList): setattr(ret, option_name, option.from_any(game_weights[option_name])) else: setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights))) diff --git a/Options.py b/Options.py index fbb19d88..27f97b80 100644 --- a/Options.py +++ b/Options.py @@ -245,6 +245,27 @@ class OptionDict(Option): return str(value) +class OptionList(Option): + default = [] + + def __init__(self, value: typing.List[str, typing.Any]): + self.value = value + + @classmethod + def from_text(cls, text: str): + return cls([option.strip() for option in text.split(",")]) + + @classmethod + def from_any(cls, data: typing.Any): + if type(data) == list: + return cls(data) + return cls.from_text(str(data)) + + def get_option_name(self, value): + return str(value) + + + local_objective = Toggle # local triforce pieces, local dungeon prizes etc. diff --git a/Utils.py b/Utils.py index b655e1d4..5f3cc0cb 100644 --- a/Utils.py +++ b/Utils.py @@ -201,6 +201,9 @@ def get_default_options() -> dict: "forge_directory": "Minecraft Forge server", "max_heap_size": "2G" }, + "oot_options": { + "rom_file": "The Legend of Zelda - Ocarina of Time.z64", + } } return options diff --git a/WebHostLib/downloads.py b/WebHostLib/downloads.py index 77dc179e..e7856a12 100644 --- a/WebHostLib/downloads.py +++ b/WebHostLib/downloads.py @@ -66,6 +66,8 @@ def download_slot_file(room_id, player_id: int): for name in zf.namelist(): if name.endswith("info.json"): fname = name.rsplit("/", 1)[0]+".zip" + elif slot_data.game == "Ocarina of Time": + fname = f"AP_{app.jinja_env.filters['suuid'](room_id)}_P{slot_data.player_id}_{slot_data.player_name}.apz5" else: return "Game download not supported." return send_file(io.BytesIO(slot_data.data), as_attachment=True, attachment_filename=fname) diff --git a/WebHostLib/templates/macros.html b/WebHostLib/templates/macros.html index 3e32b796..7c7161a7 100644 --- a/WebHostLib/templates/macros.html +++ b/WebHostLib/templates/macros.html @@ -16,6 +16,9 @@ {% elif patch.game == "Factorio" %}
  • Mod for player {{ patch.player_id }} - {{ patch.player_name }}
  • + {% elif patch.game == "Ocarina of Time" %} +
  • + APZ5 for player {{ patch.player_id }} - {{ patch.player_name }}
  • {% else %}
  • Patch for player {{ patch.player_id }} - {{ patch.player_name }}
  • diff --git a/WebHostLib/upload.py b/WebHostLib/upload.py index 97087629..8a010e3d 100644 --- a/WebHostLib/upload.py +++ b/WebHostLib/upload.py @@ -63,6 +63,12 @@ def uploads(): slots.add(Slot(data=zfile.open(file, "r").read(), player_name=slot_name, player_id=int(slot_id[1:]), game="Factorio")) + elif file.filename.endswith(".apz5"): + # .apz5 must be named specifically since they don't contain any metadata + _, seed_name, slot_id, slot_name = file.filename.split('.')[0].split('_', 3) + slots.add(Slot(data=zfile.open(file, "r").read(), player_name=slot_name, + player_id=int(slot_id[1:]), game="Ocarina of Time")) + elif file.filename.endswith(".txt"): spoiler = zfile.open(file, "r").read().decode("utf-8-sig") elif file.filename.endswith(".archipelago"): diff --git a/host.yaml b/host.yaml index 8fe346b0..ed65d37b 100644 --- a/host.yaml +++ b/host.yaml @@ -85,4 +85,7 @@ factorio_options: executable: "factorio\\bin\\x64\\factorio" minecraft_options: forge_directory: "Minecraft Forge server" - max_heap_size: "2G" \ No newline at end of file + max_heap_size: "2G" +oot_options: + # File name of the OoT v1.0 ROM + rom_file: "The Legend of Zelda - Ocarina of Time.z64" \ No newline at end of file diff --git a/playerSettings.yaml b/playerSettings.yaml index d503e922..bfec9c15 100644 --- a/playerSettings.yaml +++ b/playerSettings.yaml @@ -674,6 +674,618 @@ A Link to the Past: assured: 0 # Begin with a sword, the rest are placed randomly throughout the world vanilla: 0 # Swords are placed in vanilla locations in your own game (Uncle, Pyramid Fairy, Smiths, Pedestal) swordless: 0 # swordless mode + +Ocarina of Time: + logic_rules: # Set the logic used for the generator. + glitchless: 50 + glitched: 0 + no_logic: 0 + logic_no_night_tokens_without_suns_song: # Nighttime skulltulas will logically require Sun's Song. + false: 50 + true: 0 + open_forest: # Set the state of Kokiri Forest and the path to Deku Tree. + open: 50 + closed_deku: 0 + closed: 0 + open_kakariko: # Set the state of the Kakariko Village gate. + open: 50 + zelda: 0 + closed: 0 + open_door_of_time: # Open the Door of Time by default, without the Song of Time. + false: 0 + true: 50 + zora_fountain: # Set the state of King Zora, blocking the way to Zora's Fountain. + open: 0 + adult: 0 + closed: 50 + gerudo_fortress: # Set the requirements for access to Gerudo Fortress. + normal: 0 + fast: 50 + open: 0 + bridge: # Set the requirements for the Rainbow Bridge. + open: 0 + vanilla: 0 + stones: 0 + medallions: 50 + dungeons: 0 + tokens: 0 + trials: # Set the number of required trials in Ganon's Castle. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 6: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + starting_age: # Choose which age Link will start as. + child: 50 + adult: 0 + triforce_hunt: # Gather pieces of the Triforce scattered around the world to complete the game. + false: 50 + true: 0 + triforce_goal: # Number of Triforce pieces required to complete the game. Total number placed determined by the Item Pool setting. + # you can add additional values between minimum and maximum + 1: 0 # minimum value + 50: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + bombchus_in_logic: # Bombchus are properly considered in logic. The first found pack will have 20 chus; Kokiri Shop and Bazaar sell refills; bombchus open Bombchu Bowling. + false: 50 + true: 0 + bridge_stones: # Set the number of Spiritual Stones required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 3: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + bridge_medallions: # Set the number of medallions required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 6: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + bridge_rewards: # Set the number of dungeon rewards required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 9: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + bridge_tokens: # Set the number of Gold Skulltula Tokens required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 100: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + shuffle_mapcompass: # Control where to shuffle dungeon maps and compasses. + remove: 0 + startwith: 50 + vanilla: 0 + dungeon: 0 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_smallkeys: # Control where to shuffle dungeon small keys. + remove: 0 + vanilla: 0 + dungeon: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_fortresskeys: # Control where to shuffle the Gerudo Fortress small keys. + vanilla: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_bosskeys: # Control where to shuffle boss keys, except the Ganon's Castle Boss Key. + remove: 0 + vanilla: 0 + dungeon: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_ganon_bosskey: # Control where to shuffle the Ganon's Castle Boss Key. + remove: 50 + vanilla: 0 + dungeon: 0 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + on_lacs: 0 + enhance_map_compass: # Map tells if a dungeon is vanilla or MQ. Compass tells what the dungeon reward is. + false: 50 + true: 0 + lacs_condition: # Set the requirements for the Light Arrow Cutscene in the Temple of Time. + vanilla: 50 + stones: 0 + medallions: 0 + dungeons: 0 + tokens: 0 + lacs_stones: # Set the number of Spiritual Stones required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 3: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + lacs_medallions: # Set the number of medallions required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 6: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + lacs_rewards: # Set the number of dungeon rewards required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 9: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + lacs_tokens: # Set the number of Gold Skulltula Tokens required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 100: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + shuffle_song_items: # Set where songs can appear. + song: 50 + dungeon: 0 + any: 0 + shopsanity: # Randomizes shop contents. Set to "off" to not shuffle shops; "0" shuffles shops but does not allow multiworld items in shops. + off: 50 + "0": 0 + "1": 0 + "2": 0 + "3": 0 + "4": 0 + random_value: 0 + tokensanity: # Token rewards from Gold Skulltulas are shuffled into the pool. + off: 50 + dungeons: 0 + overworld: 0 + all: 0 + shuffle_scrubs: # Shuffle the items sold by Business Scrubs, and set the prices. + off: 50 + low: 0 + affordable: 0 + expensive: 0 + shuffle_cows: # Cows give items when Epona's Song is played. + false: 50 + true: 0 + shuffle_kokiri_sword: # Shuffle Kokiri Sword into the item pool. + false: 50 + true: 0 + shuffle_ocarinas: # Shuffle the Fairy Ocarina and Ocarina of Time into the item pool. + false: 50 + true: 0 + shuffle_weird_egg: # Shuffle the Weird Egg from Malon at Hyrule Castle. + false: 50 + true: 0 + shuffle_gerudo_card: # Shuffle the Gerudo Membership Card into the item pool. + false: 50 + true: 0 + shuffle_beans: # Adds a pack of 10 beans to the item pool and changes the bean salesman to sell one item for 60 rupees. + false: 50 + true: 0 + shuffle_medigoron_carpet_salesman: # Shuffle the items sold by Medigoron and the Haunted Wasteland Carpet Salesman. + false: 50 + true: 0 + skip_child_zelda: # Game starts with Zelda's Letter, the item at Zelda's Lullaby, and the relevant events already completed. + false: 50 + true: 0 + no_escape_sequence: # Skips the tower collapse sequence between the Ganondorf and Ganon fights. + false: 0 + true: 50 + no_guard_stealth: # The crawlspace into Hyrule Castle skips straight to Zelda. + false: 0 + true: 50 + no_epona_race: # Epona can always be summoned with Epona's Song. + false: 0 + true: 50 + skip_some_minigame_phases: # Dampe Race and Horseback Archery give both rewards if the second condition is met on the first attempt. + false: 0 + true: 50 + complete_mask_quest: # All masks are immediately available to borrow from the Happy Mask Shop. + false: 50 + true: 0 + useful_cutscenes: # Reenables the Poe cutscene in Forest Temple, Darunia in Fire Temple, and Twinrova introduction. Mostly useful for glitched. + false: 50 + true: 0 + fast_chests: # All chest animations are fast. If disabled, major items have a slow animation. + false: 0 + true: 50 + free_scarecrow: # Pulling out the ocarina near a scarecrow spot spawns Pierre without needing the song. + false: 50 + true: 0 + fast_bunny_hood: # Bunny Hood lets you move 1.5x faster like in Majora's Mask. + false: 50 + true: 0 + chicken_count: # Controls the number of Cuccos for Anju to give an item as child. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 7: 0 # maximum value + random: 50 + random-low: 0 + random-high: 0 + hints: # Gossip Stones can give hints about item locations. + none: 0 + mask: 0 + agony: 0 + always: 50 + false: 0 + hint_dist: # Choose the hint distribution to use. Affects the frequency of strong hints, which items are always hinted, etc. + balanced: 50 + ddr: 0 + league: 0 + mw2: 0 + scrubs: 0 + strong: 0 + tournament: 0 + useless: 0 + very_strong: 0 + text_shuffle: # Randomizes text in the game for comedic effect. + none: 50 + except_hints: 0 + complete: 0 + damage_multiplier: # Controls the amount of damage Link takes. + half: 0 + normal: 50 + double: 0 + quadruple: 0 + ohko: 0 + no_collectible_hearts: # Hearts will not drop from enemies or objects. + false: 50 + true: 0 + starting_tod: # Change the starting time of day. + default: 50 + sunrise: 0 + morning: 0 + noon: 0 + afternoon: 0 + sunset: 0 + evening: 0 + midnight: 0 + witching_hour: 0 + start_with_consumables: # Start the game with full Deku Sticks and Deku Nuts. + false: 50 + true: 0 + start_with_rupees: # Start with a full wallet. Wallet upgrades will also fill your wallet. + false: 50 + true: 0 + item_pool_value: # Changes the number of items available in the game. + plentiful: 0 + balanced: 50 + scarce: 0 + minimal: 0 + junk_ice_traps: # Adds ice traps to the item pool. + off: 0 + normal: 50 + extra: 0 + mayhem: 0 + onslaught: 0 + ice_trap_appearance: # Changes the appearance of ice traps as freestanding items. + major_only: 50 + junk_only: 0 + anything: 0 + logic_earliest_adult_trade: # Earliest item that can appear in the adult trade sequence. + pocket_egg: 0 + pocket_cucco: 0 + cojiro: 0 + odd_mushroom: 0 + poachers_saw: 0 + broken_sword: 0 + prescription: 50 + eyeball_frog: 0 + eyedrops: 0 + claim_check: 0 + logic_latest_adult_trade: # Latest item that can appear in the adult trade sequence. + pocket_egg: 0 + pocket_cucco: 0 + cojiro: 0 + odd_mushroom: 0 + poachers_saw: 0 + broken_sword: 0 + prescription: 0 + eyeball_frog: 0 + eyedrops: 0 + claim_check: 50 + default_targeting: # Default targeting option. + hold: 50 + switch: 0 + display_dpad: # Show dpad icon on HUD for quick actions (ocarina, hover boots, iron boots). + false: 0 + true: 50 + correct_model_colors: # Makes in-game models match their HUD element colors. + false: 0 + true: 50 + background_music: # Randomize or disable background music. + normal: 50 + off: 0 + randomized: 0 + fanfares: # Randomize or disable item fanfares. + normal: 50 + off: 0 + randomized: 0 + ocarina_fanfares: # Enable ocarina songs as fanfares. These are longer than usual fanfares. Does nothing without fanfares randomized. + false: 50 + true: 0 + kokiri_color: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + kokiri_green: 50 + goron_red: 0 + zora_blue: 0 + black: 0 + white: 0 + azure_blue: 0 + vivid_cyan: 0 + light_red: 0 + fuchsia: 0 + purple: 0 + majora_purple: 0 + twitch_purple: 0 + purple_heart: 0 + persian_rose: 0 + dirty_yellow: 0 + blush_pink: 0 + hot_pink: 0 + rose_pink: 0 + orange: 0 + gray: 0 + gold: 0 + silver: 0 + beige: 0 + teal: 0 + blood_red: 0 + blood_orange: 0 + royal_blue: 0 + sonic_blue: 0 + nes_green: 0 + dark_green: 0 + lumen: 0 + goron_color: # Choose a color. Uses the same options as "kokiri_color". + random_choice: 0 + completely_random: 0 + goron_red: 50 + zora_color: # Choose a color. Uses the same options as "kokiri_color". + random_choice: 0 + completely_random: 0 + zora_blue: 50 + silver_gauntlets_color: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + silver: 50 + gold: 0 + black: 0 + green: 0 + blue: 0 + bronze: 0 + red: 0 + sky_blue: 0 + pink: 0 + magenta: 0 + orange: 0 + lime: 0 + purple: 0 + golden_gauntlets_color: # Choose a color. Uses the same options as "silver_gauntlets_color". + random_choice: 0 + completely_random: 0 + gold: 50 + mirror_shield_frame_color: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + red: 50 + green: 0 + blue: 0 + yellow: 0 + cyan: 0 + magenta: 0 + orange: 0 + gold: 0 + purple: 0 + pink: 0 + navi_color_default_inner: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + rainbow: 0 + gold: 0 + white: 50 + green: 0 + light_blue: 0 + yellow: 0 + red: 0 + magenta: 0 + black: 0 + tatl: 0 + tael: 0 + fi: 0 + ciela: 0 + epona: 0 + ezlo: 0 + king_of_red_lions: 0 + linebeck: 0 + loftwing: 0 + midna: 0 + phantom_zelda: 0 + navi_color_default_outer: # Choose a color. Uses the same options as "navi_color_default_inner" plus "match_inner". + random_choice: 0 + completely_random: 0 + match_inner: 50 + navi_color_enemy_inner: # Choose a color. Uses the same options as "navi_color_default_inner". + random_choice: 0 + completely_random: 0 + yellow: 50 + navi_color_enemy_outer: # Choose a color. Uses the same options as "navi_color_default_inner" plus "match_inner". + random_choice: 0 + completely_random: 0 + match_inner: 50 + navi_color_npc_inner: # Choose a color. Uses the same options as "navi_color_default_inner". + random_choice: 0 + completely_random: 0 + light_blue: 50 + navi_color_npc_outer: # Choose a color. Uses the same options as "navi_color_default_inner" plus "match_inner". + random_choice: 0 + completely_random: 0 + match_inner: 50 + navi_color_prop_inner: # Choose a color. Uses the same options as "navi_color_default_inner". + random_choice: 0 + completely_random: 0 + green: 50 + navi_color_prop_outer: # Choose a color. Uses the same options as "navi_color_default_inner" plus "match_inner". + random_choice: 0 + completely_random: 0 + match_inner: 50 + sword_trail_duration: # Set the duration for sword trails. + # you can add additional values between minimum and maximum + 4: 50 # minimum value + 20: 0 # maximum value + random: 0 + random-low: 0 + random-high: 0 + sword_trail_color_inner: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + rainbow: 0 + white: 50 + red: 0 + green: 0 + blue: 0 + cyan: 0 + magenta: 0 + orange: 0 + gold: 0 + purple: 0 + pink: 0 + sword_trail_color_outer: # Uses the same options as "sword_trail_color_inner" plus "match_inner". + random_choice: 0 + completely_random: 0 + match_inner: 50 + bombchu_trail_color_inner: # Uses the same options as "sword_trail_color_inner". + random_choice: 0 + completely_random: 0 + red: 50 + bombchu_trail_color_outer: # Uses the same options as "sword_trail_color_inner" plus "match_inner". + random_choice: 0 + completely_random: 0 + match_inner: 50 + boomerang_trail_color_inner: # Uses the same options as "sword_trail_color_inner". + random_choice: 0 + completely_random: 0 + yellow: 50 + boomerang_trail_color_outer: # Uses the same options as "sword_trail_color_inner" plus "match_inner". + random_choice: 0 + completely_random: 0 + match_inner: 50 + heart_color: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + red: 50 + green: 0 + blue: 0 + yellow: 0 + magic_color: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + green: 50 + red: 0 + blue: 0 + purple: 0 + pink: 0 + yellow: 0 + white: 0 + a_button_color: # Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code. + random_choice: 0 + completely_random: 0 + n64_blue: 50 + n64_green: 0 + n64_red: 0 + gamecube_green: 0 + gamecube_red: 0 + gamecube_grey: 0 + yellow: 0 + black: 0 + white: 0 + magenta: 0 + ruby: 0 + sapphire: 0 + lime: 0 + cyan: 0 + purple: 0 + orange: 0 + b_button_color: # Choose a color. Uses the same options as "a_button_color". + random_choice: 0 + completely_random: 0 + n64_green: 50 + c_button_color: # Choose a color. Uses the same options as "a_button_color". + random_choice: 0 + completely_random: 0 + yellow: 50 + start_button_color: # Choose a color. Uses the same options as "a_button_color". + random_choice: 0 + completely_random: 0 + n64_red: 50 + sfx_navi_overworld: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + none: 0 + sfx_navi_enemy: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + none: 0 + sfx_low_hp: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + none: 0 + sfx_menu_cursor: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + none: 0 + sfx_menu_select: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + none: 0 + sfx_nightfall: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + none: 0 + sfx_horse_neigh: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + none: 0 + sfx_hover_boots: # Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound. + default: 50 + completely_random: 0 + random_ear_safe: 0 + random_choice: 0 + sfx_ocarina: # Change the sound of the ocarina. + ocarina: 50 + malon: 0 + whistle: 0 + harp: 0 + grind_organ: 0 + flute: 0 + logic_tricks: + [] + # meta_ignore, linked_options and triggers work for any game meta_ignore: # Nullify options specified in the meta.yaml file. Adding an option here guarantees it will not occur in your seed, even if the .yaml file specifies it mode: diff --git a/worlds/generic/Rules.py b/worlds/generic/Rules.py index eb769bd0..06177c48 100644 --- a/worlds/generic/Rules.py +++ b/worlds/generic/Rules.py @@ -13,6 +13,7 @@ def exclusion_rules(world, player: int, excluded_locations: set): for loc_name in excluded_locations: location = world.get_location(loc_name, player) add_item_rule(location, lambda i: not (i.advancement or i.never_exclude)) + location.excluded = True def set_rule(spot, rule): diff --git a/worlds/oot/Colors.py b/worlds/oot/Colors.py new file mode 100644 index 00000000..996c68bf --- /dev/null +++ b/worlds/oot/Colors.py @@ -0,0 +1,403 @@ +from collections import namedtuple +import random +import re + +Color = namedtuple('Color', ' R G B') + +tunic_colors = { + "Kokiri Green": Color(0x1E, 0x69, 0x1B), + "Goron Red": Color(0x64, 0x14, 0x00), + "Zora Blue": Color(0x00, 0x3C, 0x64), + "Black": Color(0x30, 0x30, 0x30), + "White": Color(0xF0, 0xF0, 0xFF), + "Azure Blue": Color(0x13, 0x9E, 0xD8), + "Vivid Cyan": Color(0x13, 0xE9, 0xD8), + "Light Red": Color(0xF8, 0x7C, 0x6D), + "Fuchsia": Color(0xFF, 0x00, 0xFF), + "Purple": Color(0x95, 0x30, 0x80), + "Majora Purple": Color(0x40, 0x00, 0x40), + "Twitch Purple": Color(0x64, 0x41, 0xA5), + "Purple Heart": Color(0x8A, 0x2B, 0xE2), + "Persian Rose": Color(0xFF, 0x14, 0x93), + "Dirty Yellow": Color(0xE0, 0xD8, 0x60), + "Blush Pink": Color(0xF8, 0x6C, 0xF8), + "Hot Pink": Color(0xFF, 0x69, 0xB4), + "Rose Pink": Color(0xFF, 0x90, 0xB3), + "Orange": Color(0xE0, 0x79, 0x40), + "Gray": Color(0xA0, 0xA0, 0xB0), + "Gold": Color(0xD8, 0xB0, 0x60), + "Silver": Color(0xD0, 0xF0, 0xFF), + "Beige": Color(0xC0, 0xA0, 0xA0), + "Teal": Color(0x30, 0xD0, 0xB0), + "Blood Red": Color(0x83, 0x03, 0x03), + "Blood Orange": Color(0xFE, 0x4B, 0x03), + "Royal Blue": Color(0x40, 0x00, 0x90), + "Sonic Blue": Color(0x50, 0x90, 0xE0), + "NES Green": Color(0x00, 0xD0, 0x00), + "Dark Green": Color(0x00, 0x25, 0x18), + "Lumen": Color(0x50, 0x8C, 0xF0), +} + +NaviColors = { # Inner Core Color Outer Glow Color + "Rainbow": (Color(0x00, 0x00, 0x00), Color(0x00, 0x00, 0x00)), + "Gold": (Color(0xFE, 0xCC, 0x3C), Color(0xFE, 0xC0, 0x07)), + "White": (Color(0xFF, 0xFF, 0xFF), Color(0x00, 0x00, 0xFF)), + "Green": (Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00)), + "Light Blue": (Color(0x96, 0x96, 0xFF), Color(0x96, 0x96, 0xFF)), + "Yellow": (Color(0xFF, 0xFF, 0x00), Color(0xC8, 0x9B, 0x00)), + "Red": (Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00)), + "Magenta": (Color(0xFF, 0x00, 0xFF), Color(0xC8, 0x00, 0x9B)), + "Black": (Color(0x00, 0x00, 0x00), Color(0x00, 0x00, 0x00)), + "Tatl": (Color(0xFF, 0xFF, 0xFF), Color(0xC8, 0x98, 0x00)), + "Tael": (Color(0x49, 0x14, 0x6C), Color(0xFF, 0x00, 0x00)), + "Fi": (Color(0x2C, 0x9E, 0xC4), Color(0x2C, 0x19, 0x83)), + "Ciela": (Color(0xE6, 0xDE, 0x83), Color(0xC6, 0xBE, 0x5B)), + "Epona": (Color(0xD1, 0x49, 0x02), Color(0x55, 0x1F, 0x08)), + "Ezlo": (Color(0x62, 0x9C, 0x5F), Color(0x3F, 0x5D, 0x37)), + "King of Red Lions": (Color(0xA8, 0x33, 0x17), Color(0xDE, 0xD7, 0xC5)), + "Linebeck": (Color(0x03, 0x26, 0x60), Color(0xEF, 0xFF, 0xFF)), + "Loftwing": (Color(0xD6, 0x2E, 0x31), Color(0xFD, 0xE6, 0xCC)), + "Midna": (Color(0x19, 0x24, 0x26), Color(0xD2, 0x83, 0x30)), + "Phantom Zelda": (Color(0x97, 0x7A, 0x6C), Color(0x6F, 0x46, 0x67)), +} + +sword_trail_colors = { + "Rainbow": Color(0x00, 0x00, 0x00), + "White": Color(0xFF, 0xFF, 0xFF), + "Red": Color(0xFF, 0x00, 0x00), + "Green": Color(0x00, 0xFF, 0x00), + "Blue": Color(0x00, 0x00, 0xFF), + "Cyan": Color(0x00, 0xFF, 0xFF), + "Magenta": Color(0xFF, 0x00, 0xFF), + "Orange": Color(0xFF, 0xA5, 0x00), + "Gold": Color(0xFF, 0xD7, 0x00), + "Purple": Color(0x80, 0x00, 0x80), + "Pink": Color(0xFF, 0x69, 0xB4), +} + +bombchu_trail_colors = { + "Rainbow": Color(0x00, 0x00, 0x00), + "Red": Color(0xFA, 0x00, 0x00), + "Green": Color(0x00, 0xFF, 0x00), + "Blue": Color(0x00, 0x00, 0xFF), + "Cyan": Color(0x00, 0xFF, 0xFF), + "Magenta": Color(0xFF, 0x00, 0xFF), + "Orange": Color(0xFF, 0xA5, 0x00), + "Gold": Color(0xFF, 0xD7, 0x00), + "Purple": Color(0x80, 0x00, 0x80), + "Pink": Color(0xFF, 0x69, 0xB4), +} + +boomerang_trail_colors = { + "Rainbow": Color(0x00, 0x00, 0x00), + "Yellow": Color(0xFF, 0xFF, 0x64), + "Red": Color(0xFF, 0x00, 0x00), + "Green": Color(0x00, 0xFF, 0x00), + "Blue": Color(0x00, 0x00, 0xFF), + "Cyan": Color(0x00, 0xFF, 0xFF), + "Magenta": Color(0xFF, 0x00, 0xFF), + "Orange": Color(0xFF, 0xA5, 0x00), + "Gold": Color(0xFF, 0xD7, 0x00), + "Purple": Color(0x80, 0x00, 0x80), + "Pink": Color(0xFF, 0x69, 0xB4), +} + +gauntlet_colors = { + "Silver": Color(0xFF, 0xFF, 0xFF), + "Gold": Color(0xFE, 0xCF, 0x0F), + "Black": Color(0x00, 0x00, 0x06), + "Green": Color(0x02, 0x59, 0x18), + "Blue": Color(0x06, 0x02, 0x5A), + "Bronze": Color(0x60, 0x06, 0x02), + "Red": Color(0xFF, 0x00, 0x00), + "Sky Blue": Color(0x02, 0x5D, 0xB0), + "Pink": Color(0xFA, 0x6A, 0x90), + "Magenta": Color(0xFF, 0x00, 0xFF), + "Orange": Color(0xDA, 0x38, 0x00), + "Lime": Color(0x5B, 0xA8, 0x06), + "Purple": Color(0x80, 0x00, 0x80), +} + +shield_frame_colors = { + "Red": Color(0xD7, 0x00, 0x00), + "Green": Color(0x00, 0xFF, 0x00), + "Blue": Color(0x00, 0x40, 0xD8), + "Yellow": Color(0xFF, 0xFF, 0x64), + "Cyan": Color(0x00, 0xFF, 0xFF), + "Magenta": Color(0xFF, 0x00, 0xFF), + "Orange": Color(0xFF, 0xA5, 0x00), + "Gold": Color(0xFF, 0xD7, 0x00), + "Purple": Color(0x80, 0x00, 0x80), + "Pink": Color(0xFF, 0x69, 0xB4), +} + +heart_colors = { + "Red": Color(0xFF, 0x46, 0x32), + "Green": Color(0x46, 0xC8, 0x32), + "Blue": Color(0x32, 0x46, 0xFF), + "Yellow": Color(0xFF, 0xE0, 0x00), +} + +magic_colors = { + "Green": Color(0x00, 0xC8, 0x00), + "Red": Color(0xC8, 0x00, 0x00), + "Blue": Color(0x00, 0x30, 0xFF), + "Purple": Color(0xB0, 0x00, 0xFF), + "Pink": Color(0xFF, 0x00, 0xC8), + "Yellow": Color(0xFF, 0xFF, 0x00), + "White": Color(0xFF, 0xFF, 0xFF), +} + +# A Button Text Cursor Shop Cursor Save/Death Cursor +# Pause Menu A Cursor Pause Menu A Icon A Note +a_button_colors = { + "N64 Blue": (Color(0x5A, 0x5A, 0xFF), Color(0x00, 0x50, 0xC8), Color(0x00, 0x50, 0xFF), Color(0x64, 0x64, 0xFF), + Color(0x00, 0x32, 0xFF), Color(0x00, 0x64, 0xFF), Color(0x50, 0x96, 0xFF)), + "N64 Green": (Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x64, 0x96, 0x64), + Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00)), + "N64 Red": (Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00), Color(0xC8, 0x64, 0x64), + Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00)), + "GameCube Green": (Color(0x00, 0xC8, 0x32), Color(0x00, 0xC8, 0x50), Color(0x00, 0xFF, 0x50), Color(0x64, 0xFF, 0x64), + Color(0x00, 0xFF, 0x32), Color(0x00, 0xFF, 0x64), Color(0x50, 0xFF, 0x96)), + "GameCube Red": (Color(0xFF, 0x1E, 0x1E), Color(0xC8, 0x00, 0x00), Color(0xFF, 0x00, 0x50), Color(0xFF, 0x64, 0x64), + Color(0xFF, 0x1E, 0x1E), Color(0xFF, 0x1E, 0x1E), Color(0xFF, 0x1E, 0x1E)), + "GameCube Grey": (Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78), + Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78)), + "Yellow": (Color(0xFF, 0xA0, 0x00), Color(0xFF, 0xA0, 0x00), Color(0xFF, 0xA0, 0x00), Color(0xFF, 0xA0, 0x00), + Color(0xFF, 0xFF, 0x00), Color(0xFF, 0x96, 0x00), Color(0xFF, 0xFF, 0x32)), + "Black": (Color(0x10, 0x10, 0x10), Color(0x00, 0x00, 0x00), Color(0x00, 0x00, 0x00), Color(0x10, 0x10, 0x10), + Color(0x00, 0x00, 0x00), Color(0x18, 0x18, 0x18), Color(0x18, 0x18, 0x18)), + "White": (Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF), + Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF)), + "Magenta": (Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF), + Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF)), + "Ruby": (Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00), + Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00)), + "Sapphire": (Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF), + Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF)), + "Lime": (Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00), + Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00)), + "Cyan": (Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF), + Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF)), + "Purple": (Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80), + Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80)), + "Orange": (Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00), + Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00)), +} + +# B Button +b_button_colors = { + "N64 Blue": Color(0x5A, 0x5A, 0xFF), + "N64 Green": Color(0x00, 0x96, 0x00), + "N64 Red": Color(0xC8, 0x00, 0x00), + "GameCube Green": Color(0x00, 0xC8, 0x32), + "GameCube Red": Color(0xFF, 0x1E, 0x1E), + "GameCube Grey": Color(0x78, 0x78, 0x78), + "Yellow": Color(0xFF, 0xA0, 0x00), + "Black": Color(0x10, 0x10, 0x10), + "White": Color(0xFF, 0xFF, 0xFF), + "Magenta": Color(0xFF, 0x00, 0xFF), + "Ruby": Color(0xFF, 0x00, 0x00), + "Sapphire": Color(0x00, 0x00, 0xFF), + "Lime": Color(0x00, 0xFF, 0x00), + "Cyan": Color(0x00, 0xFF, 0xFF), + "Purple": Color(0x80, 0x00, 0x80), + "Orange": Color(0xFF, 0x80, 0x00), +} + +# C Button Pause Menu C Cursor Pause Menu C Icon C Note +c_button_colors = { + "N64 Blue": (Color(0x5A, 0x5A, 0xFF), Color(0x00, 0x32, 0xFF), Color(0x00, 0x64, 0xFF), Color(0x50, 0x96, 0xFF)), + "N64 Green": (Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00)), + "N64 Red": (Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00)), + "GameCube Green": (Color(0x00, 0xC8, 0x32), Color(0x00, 0xFF, 0x32), Color(0x00, 0xFF, 0x64), Color(0x50, 0xFF, 0x96)), + "GameCube Red": (Color(0xFF, 0x1E, 0x1E), Color(0xFF, 0x1E, 0x1E), Color(0xFF, 0x1E, 0x1E), Color(0xFF, 0x1E, 0x1E)), + "GameCube Grey": (Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78), Color(0x78, 0x78, 0x78)), + "Yellow": (Color(0xFF, 0xA0, 0x00), Color(0xFF, 0xFF, 0x00), Color(0xFF, 0x96, 0x00), Color(0xFF, 0xFF, 0x32)), + "Black": (Color(0x10, 0x10, 0x10), Color(0x00, 0x00, 0x00), Color(0x18, 0x18, 0x18), Color(0x18, 0x18, 0x18)), + "White": (Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF), Color(0xFF, 0xFF, 0xFF)), + "Magenta": (Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF), Color(0xFF, 0x00, 0xFF)), + "Ruby": (Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00), Color(0xFF, 0x00, 0x00)), + "Sapphire": (Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF), Color(0x00, 0x00, 0xFF)), + "Lime": (Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00), Color(0x00, 0xFF, 0x00)), + "Cyan": (Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF), Color(0x00, 0xFF, 0xFF)), + "Purple": (Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80), Color(0x80, 0x00, 0x80)), + "Orange": (Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00), Color(0xFF, 0x80, 0x00)), +} + +# Start Button +start_button_colors = { + "N64 Blue": Color(0x5A, 0x5A, 0xFF), + "N64 Green": Color(0x00, 0x96, 0x00), + "N64 Red": Color(0xC8, 0x00, 0x00), + "GameCube Green": Color(0x00, 0xC8, 0x32), + "GameCube Red": Color(0xFF, 0x1E, 0x1E), + "GameCube Grey": Color(0x78, 0x78, 0x78), + "Yellow": Color(0xFF, 0xA0, 0x00), + "Black": Color(0x10, 0x10, 0x10), + "White": Color(0xFF, 0xFF, 0xFF), + "Magenta": Color(0xFF, 0x00, 0xFF), + "Ruby": Color(0xFF, 0x00, 0x00), + "Sapphire": Color(0x00, 0x00, 0xFF), + "Lime": Color(0x00, 0xFF, 0x00), + "Cyan": Color(0x00, 0xFF, 0xFF), + "Purple": Color(0x80, 0x00, 0x80), + "Orange": Color(0xFF, 0x80, 0x00), +} + +meta_color_choices = ["Random Choice", "Completely Random"] #, "Custom Color"] + + +def get_tunic_colors(): + return list(tunic_colors.keys()) + + +def get_tunic_color_options(): + return meta_color_choices + get_tunic_colors() + + +def get_navi_colors(): + return list(NaviColors.keys()) + + +def get_navi_color_options(outer=False): + if outer: + return ["[Same as Inner]"] + meta_color_choices + get_navi_colors() + else: + return meta_color_choices + get_navi_colors() + + +def get_sword_trail_colors(): + return list(sword_trail_colors.keys()) + + +def get_sword_trail_color_options(outer=False): + if outer: + return ["[Same as Inner]"] + meta_color_choices + get_sword_trail_colors() + else: + return meta_color_choices + get_sword_trail_colors() + + +def get_bombchu_trail_colors(): + return list(bombchu_trail_colors.keys()) + + +def get_bombchu_trail_color_options(outer=False): + if outer: + return ["[Same as Inner]"] + meta_color_choices + get_bombchu_trail_colors() + else: + return meta_color_choices + get_bombchu_trail_colors() + + +def get_boomerang_trail_colors(): + return list(boomerang_trail_colors.keys()) + + +def get_boomerang_trail_color_options(outer=False): + if outer: + return ["[Same as Inner]"] + meta_color_choices + get_boomerang_trail_colors() + else: + return meta_color_choices + get_boomerang_trail_colors() + + +def get_gauntlet_colors(): + return list(gauntlet_colors.keys()) + + +def get_gauntlet_color_options(): + return meta_color_choices + get_gauntlet_colors() + + +def get_shield_frame_colors(): + return list(shield_frame_colors.keys()) + + +def get_shield_frame_color_options(): + return meta_color_choices + get_shield_frame_colors() + + +def get_heart_colors(): + return list(heart_colors.keys()) + + +def get_heart_color_options(): + return meta_color_choices + get_heart_colors() + + +def get_magic_colors(): + return list(magic_colors.keys()) + + +def get_magic_color_options(): + return meta_color_choices + get_magic_colors() + + +def get_a_button_colors(): + return list(a_button_colors.keys()) + + +def get_a_button_color_options(): + return meta_color_choices + get_a_button_colors() + + +def get_b_button_colors(): + return list(b_button_colors.keys()) + + +def get_b_button_color_options(): + return meta_color_choices + get_b_button_colors() + + +def get_c_button_colors(): + return list(c_button_colors.keys()) + + +def get_c_button_color_options(): + return meta_color_choices + get_c_button_colors() + + +def get_start_button_colors(): + return list(start_button_colors.keys()) + + +def get_start_button_color_options(): + return meta_color_choices + get_start_button_colors() + + +def contrast_ratio(color1, color2): + # Based on accessibility standards (WCAG 2.0) + lum1 = relative_luminance(color1) + lum2 = relative_luminance(color2) + return (max(lum1, lum2) + 0.05) / (min(lum1, lum2) + 0.05) + + +def relative_luminance(color): + color_ratios = list(map(lum_color_ratio, color)) + return color_ratios[0] * 0.299 + color_ratios[1] * 0.587 + color_ratios[2] * 0.114 + + +def lum_color_ratio(val): + val /= 255 + if val <= 0.03928: + return val / 12.92 + else: + return pow((val + 0.055) / 1.055, 2.4) + + +def generate_random_color(): + return [random.getrandbits(8), random.getrandbits(8), random.getrandbits(8)] + + +def hex_to_color(option): + # build color from hex code + option = option[1:] if option[0] == "#" else option + if not re.search(r'^(?:[0-9a-fA-F]{3}){1,2}$', option): + raise Exception(f"Invalid color value provided: {option}") + if len(option) > 3: + return list(int(option[i:i + 2], 16) for i in (0, 2, 4)) + else: + return list(int(f'{option[i]}{option[i]}', 16) for i in (0, 1, 2)) + + +def color_to_hex(color): + return '#' + ''.join(['{:02X}'.format(c) for c in color]) diff --git a/worlds/oot/Cosmetics.py b/worlds/oot/Cosmetics.py new file mode 100644 index 00000000..b91b4606 --- /dev/null +++ b/worlds/oot/Cosmetics.py @@ -0,0 +1,814 @@ +from .Utils import data_path, __version__ +from .Colors import * +import logging +import worlds.oot.Music as music +import worlds.oot.Sounds as sfx +import worlds.oot.IconManip as icon +from .JSONDump import dump_obj, CollapseList, CollapseDict, AlignedDict, SortedDict +import json + +logger = logging.getLogger('') + +# Options are all lowercase and have underscores instead of spaces +# this needs to be undone for the oot generator +def format_cosmetic_option_result(option_result): + def format_word(word): + special_words = { + 'nes': 'NES', + 'gamecube': 'GameCube', + 'of': 'of' + } + return special_words.get(word, word.capitalize()) + words = option_result.split('_') + return ' '.join([format_word(word) for word in words]) + + +def patch_targeting(rom, ootworld, symbols): + # Set default targeting option to Hold + if ootworld.default_targeting == 'hold': + rom.write_byte(0xB71E6D, 0x01) + else: + rom.write_byte(0xB71E6D, 0x00) + + +def patch_dpad(rom, ootworld, symbols): + # Display D-Pad HUD + if ootworld.display_dpad: + rom.write_byte(symbols['CFG_DISPLAY_DPAD'], 0x01) + else: + rom.write_byte(symbols['CFG_DISPLAY_DPAD'], 0x00) + + + +def patch_music(rom, ootworld, symbols): + # patch music + if ootworld.background_music != 'normal' or ootworld.fanfares != 'normal': + music.restore_music(rom) + log, errors = music.randomize_music(rom, ootworld, {}) + if errors: + logger.error(errors) + else: + music.restore_music(rom) + + +def patch_model_colors(rom, color, model_addresses): + main_addresses, dark_addresses = model_addresses + + if color is None: + for address in main_addresses + dark_addresses: + original = rom.original.read_bytes(address, 3) + rom.write_bytes(address, original) + return + + for address in main_addresses: + rom.write_bytes(address, color) + + darkened_color = list(map(lambda light: int(max((light - 0x32) * 0.6, 0)), color)) + for address in dark_addresses: + rom.write_bytes(address, darkened_color) + + +def patch_tunic_icon(rom, tunic, color): + # patch tunic icon colors + icon_locations = { + 'Kokiri Tunic': 0x007FE000, + 'Goron Tunic': 0x007FF000, + 'Zora Tunic': 0x00800000, + } + + if color is not None: + tunic_icon = icon.generate_tunic_icon(color) + else: + tunic_icon = rom.original.read_bytes(icon_locations[tunic], 0x1000) + + rom.write_bytes(icon_locations[tunic], tunic_icon) + + +def patch_tunic_colors(rom, ootworld, symbols): + # patch tunic colors + tunics = [ + ('Kokiri Tunic', 'kokiri_color', 0x00B6DA38), + ('Goron Tunic', 'goron_color', 0x00B6DA3B), + ('Zora Tunic', 'zora_color', 0x00B6DA3E), + ] + tunic_color_list = get_tunic_colors() + + for tunic, tunic_setting, address in tunics: + tunic_option = format_cosmetic_option_result(ootworld.__dict__[tunic_setting]) + + # handle random + if tunic_option == 'Random Choice': + tunic_option = random.choice(tunic_color_list) + # handle completely random + if tunic_option == 'Completely Random': + color = generate_random_color() + # grab the color from the list + elif tunic_option in tunic_colors: + color = list(tunic_colors[tunic_option]) + # build color from hex code + else: + color = hex_to_color(tunic_option) + tunic_option = 'Custom' + # "Weird" weirdshots will crash if the Kokiri Tunic Green value is > 0x99. Brickwall it. + if ootworld.logic_rules != 'glitchless' and tunic == 'Kokiri Tunic': + color[1] = min(color[1],0x98) + rom.write_bytes(address, color) + + # patch the tunic icon + if [tunic, tunic_option] not in [['Kokiri Tunic', 'Kokiri Green'], ['Goron Tunic', 'Goron Red'], ['Zora Tunic', 'Zora Blue']]: + patch_tunic_icon(rom, tunic, color) + else: + patch_tunic_icon(rom, tunic, None) + + +def patch_navi_colors(rom, ootworld, symbols): + # patch navi colors + navi = [ + # colors for Navi + ('Navi Idle', 'navi_color_default', + [0x00B5E184], # Default (Player) + symbols.get('CFG_RAINBOW_NAVI_IDLE_INNER_ENABLED', None), symbols.get('CFG_RAINBOW_NAVI_IDLE_OUTER_ENABLED', None)), + ('Navi Targeting Enemy', 'navi_color_enemy', + [0x00B5E19C, 0x00B5E1BC], # Enemy, Boss + symbols.get('CFG_RAINBOW_NAVI_ENEMY_INNER_ENABLED', None), symbols.get('CFG_RAINBOW_NAVI_ENEMY_OUTER_ENABLED', None)), + ('Navi Targeting NPC', 'navi_color_npc', + [0x00B5E194], # NPC + symbols.get('CFG_RAINBOW_NAVI_NPC_INNER_ENABLED', None), symbols.get('CFG_RAINBOW_NAVI_NPC_OUTER_ENABLED', None)), + ('Navi Targeting Prop', 'navi_color_prop', + [0x00B5E174, 0x00B5E17C, 0x00B5E18C, 0x00B5E1A4, 0x00B5E1AC, + 0x00B5E1B4, 0x00B5E1C4, 0x00B5E1CC, 0x00B5E1D4], # Everything else + symbols.get('CFG_RAINBOW_NAVI_PROP_INNER_ENABLED', None), symbols.get('CFG_RAINBOW_NAVI_PROP_OUTER_ENABLED', None)), + ] + + navi_color_list = get_navi_colors() + rainbow_error = None + + for navi_action, navi_setting, navi_addresses, rainbow_inner_symbol, rainbow_outer_symbol in navi: + navi_option_inner = format_cosmetic_option_result(ootworld.__dict__[navi_setting+'_inner']) + navi_option_outer = format_cosmetic_option_result(ootworld.__dict__[navi_setting+'_outer']) + + # choose a random choice for the whole group + if navi_option_inner == 'Random Choice': + navi_option_inner = random.choice(navi_color_list) + if navi_option_outer == 'Random Choice': + navi_option_outer = random.choice(navi_color_list) + + if navi_option_outer == 'Match Inner': + navi_option_outer = navi_option_inner + + colors = [] + option_dict = {} + for address_index, address in enumerate(navi_addresses): + address_colors = {} + colors.append(address_colors) + for index, (navi_part, option, rainbow_symbol) in enumerate([ + ('inner', navi_option_inner, rainbow_inner_symbol), + ('outer', navi_option_outer, rainbow_outer_symbol), + ]): + color = None + + # set rainbow option + if rainbow_symbol is not None and option == 'Rainbow': + rom.write_byte(rainbow_symbol, 0x01) + color = [0x00, 0x00, 0x00] + elif rainbow_symbol is not None: + rom.write_byte(rainbow_symbol, 0x00) + elif option == 'Rainbow': + rainbow_error = "Rainbow Navi is not supported by this patch version. Using 'Completely Random' as a substitute." + option = 'Completely Random' + + # completely random is random for every subgroup + if color is None and option == 'Completely Random': + color = generate_random_color() + + # grab the color from the list + if color is None and option in NaviColors: + color = list(NaviColors[option][index]) + + # build color from hex code + if color is None: + color = hex_to_color(option) + option = 'Custom' + + # Check color validity + if color is None: + raise Exception(f'Invalid {navi_part} color {option} for {navi_action}') + + address_colors[navi_part] = color + option_dict[navi_part] = option + + # write color + color = address_colors['inner'] + [0xFF] + address_colors['outer'] + [0xFF] + rom.write_bytes(address, color) + + + if rainbow_error: + logger.error(rainbow_error) + + +def patch_sword_trails(rom, ootworld, symbols): + # patch sword trail duration + rom.write_byte(0x00BEFF8C, ootworld.sword_trail_duration) + + # patch sword trail colors + sword_trails = [ + ('Sword Trail', 'sword_trail_color', + [(0x00BEFF7C, 0xB0, 0x40, 0xB0, 0xFF), (0x00BEFF84, 0x20, 0x00, 0x10, 0x00)], + symbols.get('CFG_RAINBOW_SWORD_INNER_ENABLED', None), symbols.get('CFG_RAINBOW_SWORD_OUTER_ENABLED', None)), + ] + + sword_trail_color_list = get_sword_trail_colors() + rainbow_error = None + + for trail_name, trail_setting, trail_addresses, rainbow_inner_symbol, rainbow_outer_symbol in sword_trails: + option_inner = format_cosmetic_option_result(ootworld.__dict__[trail_setting+'_inner']) + option_outer = format_cosmetic_option_result(ootworld.__dict__[trail_setting+'_outer']) + + # handle random choice + if option_inner == 'Random Choice': + option_inner = random.choice(sword_trail_color_list) + if option_outer == 'Random Choice': + option_outer = random.choice(sword_trail_color_list) + + if option_outer == 'Match Inner': + option_outer = option_inner + + colors = [] + option_dict = {} + for address_index, (address, inner_transparency, inner_white_transparency, outer_transparency, outer_white_transparency) in enumerate(trail_addresses): + address_colors = {} + colors.append(address_colors) + transparency_dict = {} + for index, (trail_part, option, rainbow_symbol, white_transparency, transparency) in enumerate([ + ('inner', option_inner, rainbow_inner_symbol, inner_white_transparency, inner_transparency), + ('outer', option_outer, rainbow_outer_symbol, outer_white_transparency, outer_transparency), + ]): + color = None + + # set rainbow option + if rainbow_symbol is not None and option == 'Rainbow': + rom.write_byte(rainbow_symbol, 0x01) + color = [0x00, 0x00, 0x00] + elif rainbow_symbol is not None: + rom.write_byte(rainbow_symbol, 0x00) + elif option == 'Rainbow': + rainbow_error = "Rainbow Sword Trail is not supported by this patch version. Using 'Completely Random' as a substitute." + option = 'Completely Random' + + # completely random is random for every subgroup + if color is None and option == 'Completely Random': + color = generate_random_color() + + # grab the color from the list + if color is None and option in sword_trail_colors: + color = list(sword_trail_colors[option]) + + # build color from hex code + if color is None: + color = hex_to_color(option) + option = 'Custom' + + # Check color validity + if color is None: + raise Exception(f'Invalid {trail_part} color {option} for {trail_name}') + + # handle white transparency + if option == 'White': + transparency_dict[trail_part] = white_transparency + else: + transparency_dict[trail_part] = transparency + + address_colors[trail_part] = color + option_dict[trail_part] = option + + # write color + color = address_colors['outer'] + [transparency_dict['outer']] + address_colors['inner'] + [transparency_dict['inner']] + rom.write_bytes(address, color) + + if rainbow_error: + logger.error(rainbow_error) + + +def patch_bombchu_trails(rom, ootworld, symbols): + # patch bombchu trail colors + bombchu_trails = [ + ('Bombchu Trail', 'bombchu_trail_color', get_bombchu_trail_colors(), bombchu_trail_colors, + (symbols['CFG_BOMBCHU_TRAIL_INNER_COLOR'], symbols['CFG_BOMBCHU_TRAIL_OUTER_COLOR'], + symbols['CFG_RAINBOW_BOMBCHU_TRAIL_INNER_ENABLED'], symbols['CFG_RAINBOW_BOMBCHU_TRAIL_OUTER_ENABLED'])), + ] + + patch_trails(rom, ootworld, bombchu_trails) + + +def patch_boomerang_trails(rom, ootworld, symbols): + # patch boomerang trail colors + boomerang_trails = [ + ('Boomerang Trail', 'boomerang_trail_color', get_boomerang_trail_colors(), boomerang_trail_colors, + (symbols['CFG_BOOM_TRAIL_INNER_COLOR'], symbols['CFG_BOOM_TRAIL_OUTER_COLOR'], + symbols['CFG_RAINBOW_BOOM_TRAIL_INNER_ENABLED'], symbols['CFG_RAINBOW_BOOM_TRAIL_OUTER_ENABLED'])), + ] + + patch_trails(rom, ootworld, boomerang_trails) + + +def patch_trails(rom, ootworld, trails): + for trail_name, trail_setting, trail_color_list, trail_color_dict, trail_symbols in trails: + color_inner_symbol, color_outer_symbol, rainbow_inner_symbol, rainbow_outer_symbol = trail_symbols + option_inner = format_cosmetic_option_result(ootworld.__dict__[trail_setting+'_inner']) + option_outer = format_cosmetic_option_result(ootworld.__dict__[trail_setting+'_outer']) + + # handle random choice + if option_inner == 'Random Choice': + option_inner = random.choice(trail_color_list) + if option_outer == 'Random Choice': + option_outer = random.choice(trail_color_list) + + if option_outer == 'Match Inner': + option_outer = option_inner + + option_dict = {} + colors = {} + + for index, (trail_part, option, rainbow_symbol, color_symbol) in enumerate([ + ('inner', option_inner, rainbow_inner_symbol, color_inner_symbol), + ('outer', option_outer, rainbow_outer_symbol, color_outer_symbol), + ]): + color = None + + # set rainbow option + if option == 'Rainbow': + rom.write_byte(rainbow_symbol, 0x01) + color = [0x00, 0x00, 0x00] + else: + rom.write_byte(rainbow_symbol, 0x00) + + # handle completely random + if color is None and option == 'Completely Random': + # Specific handling for inner bombchu trails for contrast purposes. + if trail_name == 'Bombchu Trail' and trail_part == 'inner': + fixed_dark_color = [0, 0, 0] + color = [0, 0, 0] + # Avoid colors which have a low contrast so the bombchu ticking is still visible + while contrast_ratio(color, fixed_dark_color) <= 4: + color = generate_random_color() + else: + color = generate_random_color() + + # grab the color from the list + if color is None and option in trail_color_dict: + color = list(trail_color_dict[option]) + + # build color from hex code + if color is None: + color = hex_to_color(option) + option = 'Custom' + + option_dict[trail_part] = option + colors[trail_part] = color + + # write color + rom.write_bytes(color_symbol, color) + + + +def patch_gauntlet_colors(rom, ootworld, symbols): + # patch gauntlet colors + gauntlets = [ + ('Silver Gauntlets', 'silver_gauntlets_color', 0x00B6DA44, + ([0x173B4CC], [0x173B4D4, 0x173B50C, 0x173B514])), # GI Model DList colors + ('Gold Gauntlets', 'golden_gauntlets_color', 0x00B6DA47, + ([0x173B4EC], [0x173B4F4, 0x173B52C, 0x173B534])), # GI Model DList colors + ] + gauntlet_color_list = get_gauntlet_colors() + + for gauntlet, gauntlet_setting, address, model_addresses in gauntlets: + gauntlet_option = format_cosmetic_option_result(ootworld.__dict__[gauntlet_setting]) + + # handle random + if gauntlet_option == 'Random Choice': + gauntlet_option = random.choice(gauntlet_color_list) + # handle completely random + if gauntlet_option == 'Completely Random': + color = generate_random_color() + # grab the color from the list + elif gauntlet_option in gauntlet_colors: + color = list(gauntlet_colors[gauntlet_option]) + # build color from hex code + else: + color = hex_to_color(gauntlet_option) + gauntlet_option = 'Custom' + rom.write_bytes(address, color) + if ootworld.correct_model_colors: + patch_model_colors(rom, color, model_addresses) + else: + patch_model_colors(rom, None, model_addresses) + +def patch_shield_frame_colors(rom, ootworld, symbols): + # patch shield frame colors + shield_frames = [ + ('Mirror Shield Frame', 'mirror_shield_frame_color', + [0xFA7274, 0xFA776C, 0xFAA27C, 0xFAC564, 0xFAC984, 0xFAEDD4], + ([0x1616FCC], [0x1616FD4])), + ] + shield_frame_color_list = get_shield_frame_colors() + + for shield_frame, shield_frame_setting, addresses, model_addresses in shield_frames: + shield_frame_option = format_cosmetic_option_result(ootworld.__dict__[shield_frame_setting]) + + # handle random + if shield_frame_option == 'Random Choice': + shield_frame_option = random.choice(shield_frame_color_list) + # handle completely random + if shield_frame_option == 'Completely Random': + color = [random.getrandbits(8), random.getrandbits(8), random.getrandbits(8)] + # grab the color from the list + elif shield_frame_option in shield_frame_colors: + color = list(shield_frame_colors[shield_frame_option]) + # build color from hex code + else: + color = hex_to_color(shield_frame_option) + shield_frame_option = 'Custom' + for address in addresses: + rom.write_bytes(address, color) + if ootworld.correct_model_colors and shield_frame_option != 'Red': + patch_model_colors(rom, color, model_addresses) + else: + patch_model_colors(rom, None, model_addresses) + + +def patch_heart_colors(rom, ootworld, symbols): + # patch heart colors + hearts = [ + ('Heart Color', 'heart_color', symbols['CFG_HEART_COLOR'], 0xBB0994, + ([0x14DA474, 0x14DA594, 0x14B701C, 0x14B70DC], + [0x14B70FC, 0x14DA494, 0x14DA5B4, 0x14B700C, 0x14B702C, 0x14B703C, 0x14B704C, 0x14B705C, + 0x14B706C, 0x14B707C, 0x14B708C, 0x14B709C, 0x14B70AC, 0x14B70BC, 0x14B70CC])), # GI Model DList colors + ] + heart_color_list = get_heart_colors() + + for heart, heart_setting, symbol, file_select_address, model_addresses in hearts: + heart_option = format_cosmetic_option_result(ootworld.__dict__[heart_setting]) + + # handle random + if heart_option == 'Random Choice': + heart_option = random.choice(heart_color_list) + # handle completely random + if heart_option == 'Completely Random': + color = generate_random_color() + # grab the color from the list + elif heart_option in heart_colors: + color = list(heart_colors[heart_option]) + # build color from hex code + else: + color = hex_to_color(heart_option) + heart_option = 'Custom' + rom.write_int16s(symbol, color) # symbol for ingame HUD + rom.write_int16s(file_select_address, color) # file select normal hearts + if heart_option != 'Red': + rom.write_int16s(file_select_address + 6, color) # file select DD hearts + else: + original_dd_color = rom.original.read_bytes(file_select_address + 6, 6) + rom.write_bytes(file_select_address + 6, original_dd_color) + if ootworld.correct_model_colors and heart_option != 'Red': + patch_model_colors(rom, color, model_addresses) # heart model colors + icon.patch_overworld_icon(rom, color, 0xF43D80) # Overworld Heart Icon + else: + patch_model_colors(rom, None, model_addresses) + icon.patch_overworld_icon(rom, None, 0xF43D80) + +def patch_magic_colors(rom, ootworld, symbols): + # patch magic colors + magic = [ + ('Magic Meter Color', 'magic_color', symbols["CFG_MAGIC_COLOR"], + ([0x154C654, 0x154CFB4], [0x154C65C, 0x154CFBC])), # GI Model DList colors + ] + magic_color_list = get_magic_colors() + + for magic_color, magic_setting, symbol, model_addresses in magic: + magic_option = format_cosmetic_option_result(ootworld.__dict__[magic_setting]) + + if magic_option == 'Random Choice': + magic_option = random.choice(magic_color_list) + + if magic_option == 'Completely Random': + color = generate_random_color() + elif magic_option in magic_colors: + color = list(magic_colors[magic_option]) + else: + color = hex_to_color(magic_option) + magic_option = 'Custom' + rom.write_int16s(symbol, color) + if magic_option != 'Green' and ootworld.correct_model_colors: + patch_model_colors(rom, color, model_addresses) + icon.patch_overworld_icon(rom, color, 0xF45650, data_path('icons/magicSmallExtras.raw')) # Overworld Small Pot + icon.patch_overworld_icon(rom, color, 0xF47650, data_path('icons/magicLargeExtras.raw')) # Overworld Big Pot + else: + patch_model_colors(rom, None, model_addresses) + icon.patch_overworld_icon(rom, None, 0xF45650) + icon.patch_overworld_icon(rom, None, 0xF47650) + +def patch_button_colors(rom, ootworld, symbols): + buttons = [ + ('A Button Color', 'a_button_color', a_button_colors, + [('A Button Color', symbols['CFG_A_BUTTON_COLOR'], + None), + ('Text Cursor Color', symbols['CFG_TEXT_CURSOR_COLOR'], + [(0xB88E81, 0xB88E85, 0xB88E9)]), # Initial Inner Color + ('Shop Cursor Color', symbols['CFG_SHOP_CURSOR_COLOR'], + None), + ('Save/Death Cursor Color', None, + [(0xBBEBC2, 0xBBEBC3, 0xBBEBD6), (0xBBEDDA, 0xBBEDDB, 0xBBEDDE)]), # Save Cursor / Death Cursor + ('Pause Menu A Cursor Color', None, + [(0xBC7849, 0xBC784B, 0xBC784D), (0xBC78A9, 0xBC78AB, 0xBC78AD), (0xBC78BB, 0xBC78BD, 0xBC78BF)]), # Inner / Pulse 1 / Pulse 2 + ('Pause Menu A Icon Color', None, + [(0x845754, 0x845755, 0x845756)]), + ('A Note Color', symbols['CFG_A_NOTE_COLOR'], # For Textbox Song Display + [(0xBB299A, 0xBB299B, 0xBB299E), (0xBB2C8E, 0xBB2C8F, 0xBB2C92), (0xBB2F8A, 0xBB2F8B, 0xBB2F96)]), # Pause Menu Song Display + ]), + ('B Button Color', 'b_button_color', b_button_colors, + [('B Button Color', symbols['CFG_B_BUTTON_COLOR'], + None), + ]), + ('C Button Color', 'c_button_color', c_button_colors, + [('C Button Color', symbols['CFG_C_BUTTON_COLOR'], + None), + ('Pause Menu C Cursor Color', None, + [(0xBC7843, 0xBC7845, 0xBC7847), (0xBC7891, 0xBC7893, 0xBC7895), (0xBC78A3, 0xBC78A5, 0xBC78A7)]), # Inner / Pulse 1 / Pulse 2 + ('Pause Menu C Icon Color', None, + [(0x8456FC, 0x8456FD, 0x8456FE)]), + ('C Note Color', symbols['CFG_C_NOTE_COLOR'], # For Textbox Song Display + [(0xBB2996, 0xBB2997, 0xBB29A2), (0xBB2C8A, 0xBB2C8B, 0xBB2C96), (0xBB2F86, 0xBB2F87, 0xBB2F9A)]), # Pause Menu Song Display + ]), + ('Start Button Color', 'start_button_color', start_button_colors, + [('Start Button Color', None, + [(0xAE9EC6, 0xAE9EC7, 0xAE9EDA)]), + ]), + ] + + for button, button_setting, button_colors, patches in buttons: + button_option = format_cosmetic_option_result(ootworld.__dict__[button_setting]) + color_set = None + colors = {} + + # handle random + if button_option == 'Random Choice': + button_option = random.choice(list(button_colors.keys())) + # handle completely random + if button_option == 'Completely Random': + fixed_font_color = [10, 10, 10] + color = [0, 0, 0] + # Avoid colors which have a low contrast with the font inside buttons (eg. the A letter) + while contrast_ratio(color, fixed_font_color) <= 3: + color = generate_random_color() + # grab the color from the list + elif button_option in button_colors: + color_set = [button_colors[button_option]] if isinstance(button_colors[button_option][0], int) else list(button_colors[button_option]) + color = color_set[0] + # build color from hex code + else: + color = hex_to_color(button_option) + button_option = 'Custom' + + # apply all button color patches + for i, (patch, symbol, byte_addresses) in enumerate(patches): + if color_set is not None and len(color_set) > i and color_set[i]: + colors[patch] = color_set[i] + else: + colors[patch] = color + + if symbol: + rom.write_int16s(symbol, colors[patch]) + + if byte_addresses: + for r_addr, g_addr, b_addr in byte_addresses: + rom.write_byte(r_addr, colors[patch][0]) + rom.write_byte(g_addr, colors[patch][1]) + rom.write_byte(b_addr, colors[patch][2]) + + +def patch_sfx(rom, ootworld, symbols): + # Configurable Sound Effects + sfx_config = [ + ('sfx_navi_overworld', sfx.SoundHooks.NAVI_OVERWORLD), + ('sfx_navi_enemy', sfx.SoundHooks.NAVI_ENEMY), + ('sfx_low_hp', sfx.SoundHooks.HP_LOW), + ('sfx_menu_cursor', sfx.SoundHooks.MENU_CURSOR), + ('sfx_menu_select', sfx.SoundHooks.MENU_SELECT), + ('sfx_nightfall', sfx.SoundHooks.NIGHTFALL), + ('sfx_horse_neigh', sfx.SoundHooks.HORSE_NEIGH), + ('sfx_hover_boots', sfx.SoundHooks.BOOTS_HOVER), + ] + sound_dict = sfx.get_patch_dict() + sounds_keyword_label = {sound.value.keyword: sound.value.label for sound in sfx.Sounds} + sounds_label_keyword = {sound.value.label: sound.value.keyword for sound in sfx.Sounds} + + for setting, hook in sfx_config: + selection = ootworld.__dict__[setting].replace('_', '-') + + if selection == 'default': + for loc in hook.value.locations: + sound_id = rom.original.read_int16(loc) + rom.write_int16(loc, sound_id) + else: + if selection == 'random-choice': + selection = random.choice(sfx.get_hook_pool(hook)).value.keyword + elif selection == 'random-ear-safe': + selection = random.choice(sfx.get_hook_pool(hook, "TRUE")).value.keyword + elif selection == 'completely-random': + selection = random.choice(sfx.standard).value.keyword + sound_id = sound_dict[selection] + for loc in hook.value.locations: + rom.write_int16(loc, sound_id) + + + +def patch_instrument(rom, ootworld, symbols): + # Player Instrument + instruments = { + #'none': 0x00, + 'ocarina': 0x01, + 'malon': 0x02, + 'whistle': 0x03, + 'harp': 0x04, + 'grind_organ': 0x05, + 'flute': 0x06, + #'another_ocarina': 0x07, + } + + choice = ootworld.sfx_ocarina + if choice == 'random-choice': + choice = random.choice(list(instruments.keys())) + + rom.write_byte(0x00B53C7B, instruments[choice]) + rom.write_byte(0x00B4BF6F, instruments[choice]) # For Lost Woods Skull Kids' minigame in Lost Woods + + +legacy_cosmetic_data_headers = [ + 0x03481000, + 0x03480810, +] + +global_patch_sets = [ + patch_targeting, + patch_music, + patch_tunic_colors, + patch_navi_colors, + patch_sword_trails, + patch_gauntlet_colors, + patch_shield_frame_colors, + patch_sfx, + patch_instrument, +] + +patch_sets = { + 0x1F04FA62: { + "patches": [ + patch_dpad, + patch_sword_trails, + ], + "symbols": { + "CFG_DISPLAY_DPAD": 0x0004, + "CFG_RAINBOW_SWORD_INNER_ENABLED": 0x0005, + "CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x0006, + }, + }, + 0x1F05D3F9: { + "patches": [ + patch_dpad, + patch_sword_trails, + ], + "symbols": { + "CFG_DISPLAY_DPAD": 0x0004, + "CFG_RAINBOW_SWORD_INNER_ENABLED": 0x0005, + "CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x0006, + }, + }, + 0x1F0693FB: { + "patches": [ + patch_dpad, + patch_sword_trails, + patch_heart_colors, + patch_magic_colors, + ], + "symbols": { + "CFG_MAGIC_COLOR": 0x0004, + "CFG_HEART_COLOR": 0x000A, + "CFG_DISPLAY_DPAD": 0x0010, + "CFG_RAINBOW_SWORD_INNER_ENABLED": 0x0011, + "CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x0012, + } + }, + 0x1F073FC9: { + "patches": [ + patch_dpad, + patch_sword_trails, + patch_heart_colors, + patch_magic_colors, + patch_button_colors, + ], + "symbols": { + "CFG_MAGIC_COLOR": 0x0004, + "CFG_HEART_COLOR": 0x000A, + "CFG_A_BUTTON_COLOR": 0x0010, + "CFG_B_BUTTON_COLOR": 0x0016, + "CFG_C_BUTTON_COLOR": 0x001C, + "CFG_TEXT_CURSOR_COLOR": 0x0022, + "CFG_SHOP_CURSOR_COLOR": 0x0028, + "CFG_A_NOTE_COLOR": 0x002E, + "CFG_C_NOTE_COLOR": 0x0034, + "CFG_DISPLAY_DPAD": 0x003A, + "CFG_RAINBOW_SWORD_INNER_ENABLED": 0x003B, + "CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x003C, + } + }, + 0x1F073FD8: { + "patches": [ + patch_dpad, + patch_navi_colors, + patch_sword_trails, + patch_heart_colors, + patch_magic_colors, + patch_button_colors, + patch_boomerang_trails, + patch_bombchu_trails, + ], + "symbols": { + "CFG_MAGIC_COLOR": 0x0004, + "CFG_HEART_COLOR": 0x000A, + "CFG_A_BUTTON_COLOR": 0x0010, + "CFG_B_BUTTON_COLOR": 0x0016, + "CFG_C_BUTTON_COLOR": 0x001C, + "CFG_TEXT_CURSOR_COLOR": 0x0022, + "CFG_SHOP_CURSOR_COLOR": 0x0028, + "CFG_A_NOTE_COLOR": 0x002E, + "CFG_C_NOTE_COLOR": 0x0034, + "CFG_BOOM_TRAIL_INNER_COLOR": 0x003A, + "CFG_BOOM_TRAIL_OUTER_COLOR": 0x003D, + "CFG_BOMBCHU_TRAIL_INNER_COLOR": 0x0040, + "CFG_BOMBCHU_TRAIL_OUTER_COLOR": 0x0043, + "CFG_DISPLAY_DPAD": 0x0046, + "CFG_RAINBOW_SWORD_INNER_ENABLED": 0x0047, + "CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x0048, + "CFG_RAINBOW_BOOM_TRAIL_INNER_ENABLED": 0x0049, + "CFG_RAINBOW_BOOM_TRAIL_OUTER_ENABLED": 0x004A, + "CFG_RAINBOW_BOMBCHU_TRAIL_INNER_ENABLED": 0x004B, + "CFG_RAINBOW_BOMBCHU_TRAIL_OUTER_ENABLED": 0x004C, + "CFG_RAINBOW_NAVI_IDLE_INNER_ENABLED": 0x004D, + "CFG_RAINBOW_NAVI_IDLE_OUTER_ENABLED": 0x004E, + "CFG_RAINBOW_NAVI_ENEMY_INNER_ENABLED": 0x004F, + "CFG_RAINBOW_NAVI_ENEMY_OUTER_ENABLED": 0x0050, + "CFG_RAINBOW_NAVI_NPC_INNER_ENABLED": 0x0051, + "CFG_RAINBOW_NAVI_NPC_OUTER_ENABLED": 0x0052, + "CFG_RAINBOW_NAVI_PROP_INNER_ENABLED": 0x0053, + "CFG_RAINBOW_NAVI_PROP_OUTER_ENABLED": 0x0054, + } + }, +} + + +def patch_cosmetics(ootworld, rom): + # Use the world's slot seed for cosmetics + random.seed(ootworld.world.slot_seeds[ootworld.player]) + + # try to detect the cosmetic patch data format + versioned_patch_set = None + cosmetic_context = rom.read_int32(rom.sym('RANDO_CONTEXT') + 4) + if cosmetic_context >= 0x80000000 and cosmetic_context <= 0x80F7FFFC: + cosmetic_context = (cosmetic_context - 0x80400000) + 0x3480000 # convert from RAM to ROM address + cosmetic_version = rom.read_int32(cosmetic_context) + versioned_patch_set = patch_sets.get(cosmetic_version) + else: + # If cosmetic_context is not a valid pointer, then try to + # search over all possible legacy header locations. + for header in legacy_cosmetic_data_headers: + cosmetic_context = header + cosmetic_version = rom.read_int32(cosmetic_context) + if cosmetic_version in patch_sets: + versioned_patch_set = patch_sets[cosmetic_version] + break + + # patch version specific patches + if versioned_patch_set: + # offset the cosmetic_context struct for absolute addressing + cosmetic_context_symbols = { + sym: address + cosmetic_context + for sym, address in versioned_patch_set['symbols'].items() + } + + # warn if patching a legacy format + if cosmetic_version != rom.read_int32(rom.sym('COSMETIC_FORMAT_VERSION')): + logger.error("ROM uses old cosmetic patch format.") + + # patch cosmetics that use vanilla oot data, and always compatible + for patch_func in [patch for patch in global_patch_sets if patch not in versioned_patch_set['patches']]: + patch_func(rom, ootworld, {}) + + for patch_func in versioned_patch_set['patches']: + patch_func(rom, ootworld, cosmetic_context_symbols) + else: + # patch cosmetics that use vanilla oot data, and always compatible + for patch_func in global_patch_sets: + patch_func(rom, ootworld, {}) + + # Unknown patch format + logger.error("Unable to patch some cosmetics. ROM uses unknown cosmetic patch format.") diff --git a/worlds/oot/Dungeon.py b/worlds/oot/Dungeon.py new file mode 100644 index 00000000..6e227baa --- /dev/null +++ b/worlds/oot/Dungeon.py @@ -0,0 +1,56 @@ +class Dungeon(object): + + def __init__(self, world, name, hint, boss_key, small_keys, dungeon_items): + def to_array(obj): + if obj == None: + return [] + if isinstance(obj, list): + return obj + else: + return [obj] + + self.world = world + self.name = name + self.hint_text = hint + self.regions = [] + self.boss_key = to_array(boss_key) + self.small_keys = to_array(small_keys) + self.dungeon_items = to_array(dungeon_items) + + for region in world.world.regions: + if region.player == world.player and region.dungeon == self.name: + region.dungeon = self + self.regions.append(region) + + + def copy(self, new_world): + new_boss_key = [item.copy(new_world) for item in self.boss_key] + new_small_keys = [item.copy(new_world) for item in self.small_keys] + new_dungeon_items = [item.copy(new_world) for item in self.dungeon_items] + + new_dungeon = Dungeon(new_world, self.name, self.hint, new_boss_key, new_small_keys, new_dungeon_items) + + return new_dungeon + + + @property + def keys(self): + return self.small_keys + self.boss_key + + + @property + def all_items(self): + return self.dungeon_items + self.keys + + + def is_dungeon_item(self, item): + return item.name in [dungeon_item.name for dungeon_item in self.all_items] + + + def __str__(self): + return str(self.__unicode__()) + + + def __unicode__(self): + return '%s' % self.name + diff --git a/worlds/oot/DungeonList.py b/worlds/oot/DungeonList.py new file mode 100644 index 00000000..45ac4a72 --- /dev/null +++ b/worlds/oot/DungeonList.py @@ -0,0 +1,129 @@ +import os + +from .Dungeon import Dungeon +from .Utils import data_path + + +dungeon_table = [ + { + 'name': 'Deku Tree', + 'boss_key': 0, + 'small_key': 0, + 'small_key_mq': 0, + 'dungeon_item': 1, + }, + { + 'name': 'Dodongos Cavern', + 'hint': 'Dodongo\'s Cavern', + 'boss_key': 0, + 'small_key': 0, + 'small_key_mq': 0, + 'dungeon_item': 1, + }, + { + 'name': 'Jabu Jabus Belly', + 'hint': 'Jabu Jabu\'s Belly', + 'boss_key': 0, + 'small_key': 0, + 'small_key_mq': 0, + 'dungeon_item': 1, + }, + { + 'name': 'Forest Temple', + 'boss_key': 1, + 'small_key': 5, + 'small_key_mq': 6, + 'dungeon_item': 1, + }, + { + 'name': 'Bottom of the Well', + 'boss_key': 0, + 'small_key': 3, + 'small_key_mq': 2, + 'dungeon_item': 1, + }, + { + 'name': 'Fire Temple', + 'boss_key': 1, + 'small_key': 8, + 'small_key_mq': 5, + 'dungeon_item': 1, + }, + { + 'name': 'Ice Cavern', + 'boss_key': 0, + 'small_key': 0, + 'small_key_mq': 0, + 'dungeon_item': 1, + }, + { + 'name': 'Water Temple', + 'boss_key': 1, + 'small_key': 6, + 'small_key_mq': 2, + 'dungeon_item': 1, + }, + { + 'name': 'Shadow Temple', + 'boss_key': 1, + 'small_key': 5, + 'small_key_mq': 6, + 'dungeon_item': 1, + }, + { + 'name': 'Gerudo Training Grounds', + 'boss_key': 0, + 'small_key': 9, + 'small_key_mq': 3, + 'dungeon_item': 0, + }, + { + 'name': 'Spirit Temple', + 'boss_key': 1, + 'small_key': 5, + 'small_key_mq': 7, + 'dungeon_item': 1, + }, + { + 'name': 'Ganons Castle', + 'hint': 'Ganon\'s Castle', + 'boss_key': 1, + 'small_key': 2, + 'small_key_mq': 3, + 'dungeon_item': 0, + }, +] + + +def create_dungeons(ootworld): + ootworld.dungeons = [] + for dungeon_info in dungeon_table: + name = dungeon_info['name'] + hint = dungeon_info['hint'] if 'hint' in dungeon_info else name + + if ootworld.logic_rules == 'glitchless': + if not ootworld.dungeon_mq[name]: + dungeon_json = os.path.join(data_path('World'), name + '.json') + else: + dungeon_json = os.path.join(data_path('World'), name + ' MQ.json') + else: + if not ootworld.dungeon_mq[name]: + dungeon_json = os.path.join(data_path('Glitched World'), name + '.json') + else: + dungeon_json = os.path.join(data_path('Glitched World'), name + ' MQ.json') + + + ootworld.load_regions_from_json(dungeon_json) + + boss_keys = [ootworld.create_item(f'Boss Key ({name})') for i in range(dungeon_info['boss_key'])] + if not ootworld.dungeon_mq[dungeon_info['name']]: + small_keys = [ootworld.create_item(f'Small Key ({name})') for i in range(dungeon_info['small_key'])] + else: + small_keys = [ootworld.create_item(f'Small Key ({name})') for i in range(dungeon_info['small_key_mq'])] + dungeon_items = [ootworld.create_item(f'Map ({name})'), ootworld.create_item(f'Compass ({name})')] * dungeon_info['dungeon_item'] + if ootworld.shuffle_mapcompass in ['any_dungeon', 'overworld']: + for item in dungeon_items: + item.priority = True + + ootworld.dungeons.append(Dungeon(ootworld, name, hint, boss_keys, small_keys, dungeon_items)) + diff --git a/worlds/oot/Entrance.py b/worlds/oot/Entrance.py new file mode 100644 index 00000000..310fcee4 --- /dev/null +++ b/worlds/oot/Entrance.py @@ -0,0 +1,19 @@ + +from BaseClasses import Entrance +from .Regions import TimeOfDay + +class OOTEntrance(Entrance): + game: str = 'Ocarina of Time' + + def __init__(self, player, name='', parent=None): + super(OOTEntrance, self).__init__(player, name, parent) + self.access_rules = [] + self.reverse = None + self.replaces = None + self.assumed = None + self.type = None + self.shuffled = False + self.data = None + self.primary = False + self.always = False + self.never = False diff --git a/worlds/oot/EntranceShuffle.py b/worlds/oot/EntranceShuffle.py new file mode 100644 index 00000000..f1e91773 --- /dev/null +++ b/worlds/oot/EntranceShuffle.py @@ -0,0 +1,25 @@ + +def shuffle_random_entrances(ootworld): + world = ootworld.world + player = ootworld.player + + # Gather locations to keep reachable for validation + + # Set entrance data for all entrances + + # Determine entrance pools based on settings + + # Mark shuffled entrances + + # Build target entrance pools + + # Place priority entrances + + # Delete priority targets from one-way pools + + # Shuffle all entrance pools, in order + + # Verification steps: + # All entrances are properly connected to a region + # Game is beatable + # Validate world diff --git a/worlds/oot/HintList.py b/worlds/oot/HintList.py new file mode 100644 index 00000000..a53f9db3 --- /dev/null +++ b/worlds/oot/HintList.py @@ -0,0 +1,1292 @@ +import random + +# Abbreviations +# DMC Death Mountain Crater +# DMT Death Mountain Trail +# GC Goron City +# GF Gerudo Fortress +# GS Gold Skulltula +# GV Gerudo Valley +# HC Hyrule Castle +# HF Hyrule Field +# KF Kokiri Forest +# LH Lake Hylia +# LLR Lon Lon Ranch +# LW Lost Woods +# OGC Outside Ganon's Castle +# SFM Sacred Forest Meadow +# ZD Zora's Domain +# ZF Zora's Fountain +# ZR Zora's River + +class Hint(object): + name = "" + text = "" + type = [] + + def __init__(self, name, text, type, choice=None): + self.name = name + self.type = [type] if not isinstance(type, list) else type + + if isinstance(text, str): + self.text = text + else: + if choice == None: + self.text = random.choice(text) + else: + self.text = text[choice] + + +def getHint(item, clearer_hint=False): + if item in hintTable: + textOptions, clearText, hintType = hintTable[item] + if clearer_hint: + if clearText == None: + return Hint(item, textOptions, hintType, 0) + return Hint(item, clearText, hintType) + else: + return Hint(item, textOptions, hintType) + elif type(item) is str: + return Hint(item, item, 'generic') + else: # is an Item + return Hint(item.name, item.hint_text, 'item') + + +def getHintGroup(group, world): + ret = [] + for name in hintTable: + + hint = getHint(name, world.clearer_hints) + + if hint.name in world.always_hints and group == 'always': + hint.type = 'always' + + # Hint inclusion override from distribution + if group in world.added_hint_types or group in world.item_added_hint_types: + if hint.name in world.added_hint_types[group]: + hint.type = group + if nameIsLocation(name, hint.type, world): + location = world.get_location(name) + for i in world.item_added_hint_types[group]: + if i == location.item.name: + hint.type = group + for i in world.item_hint_type_overrides[group]: + if i == location.item.name: + hint.type = [] + type_override = False + if group in world.hint_type_overrides: + if name in world.hint_type_overrides[group]: + type_override = True + if group in world.item_hint_type_overrides: + if nameIsLocation(name, hint.type, world): + location = world.get_location(name) + if location.item.name in world.item_hint_type_overrides[group]: + type_override = True + + if group in hint.type and (name not in hintExclusions(world)) and not type_override: + ret.append(hint) + return ret + + +def getRequiredHints(world): + ret = [] + for name in hintTable: + hint = getHint(name) + if 'always' in hint.type or hint.name in conditional_always and conditional_always[hint.name](world): + ret.append(hint) + return ret + + +# Helpers for conditional always hints +def stones_required_by_settings(world): + stones = 0 + if world.bridge == 'stones': + stones = max(stones, world.bridge_stones) + if world.shuffle_ganon_bosskey == 'on_lacs' and world.lacs_condition == 'stones': + stones = max(stones, world.lacs_stones) + if world.bridge == 'dungeons': + stones = max(stones, world.bridge_rewards - 6) + if world.shuffle_ganon_bosskey == 'on_lacs' and world.lacs_condition == 'dungeons': + stones = max(stones, world.lacs_rewards - 6) + + return stones + + +def medallions_required_by_settings(world): + medallions = 0 + if world.bridge == 'medallions': + medallions = max(medallions, world.bridge_medallions) + if world.shuffle_ganon_bosskey == 'on_lacs' and world.lacs_condition == 'medallions': + medallions = max(medallions, world.lacs_medallions) + if world.bridge == 'dungeons': + medallions = max(medallions, max(world.bridge_rewards - 3, 0)) + if world.shuffle_ganon_bosskey == 'on_lacs' and world.lacs_condition == 'dungeons': + medallions = max(medallions, max(world.lacs_rewards - 3, 0)) + + return medallions + + +def tokens_required_by_settings(world): + tokens = 0 + if world.bridge == 'tokens': + tokens = max(tokens, world.bridge_tokens) + if world.shuffle_ganon_bosskey == 'on_lacs' and world.lacs_condition == 'tokens': + tokens = max(tokens, world.lacs_tokens) + + return tokens + + +# Hints required under certain settings +conditional_always = { + 'Market 10 Big Poes': lambda world: world.big_poe_count > 3, + 'Deku Theater Mask of Truth': lambda world: not world.complete_mask_quest, + 'Song from Ocarina of Time': lambda world: stones_required_by_settings(world) < 2, + 'HF Ocarina of Time Item': lambda world: stones_required_by_settings(world) < 2, + 'Sheik in Kakariko': lambda world: medallions_required_by_settings(world) < 5, + 'DMT Biggoron': lambda world: world.logic_earliest_adult_trade != 'claim_check' or world.logic_latest_adult_trade != 'claim_check', + 'Kak 30 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 30, + 'Kak 40 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 40, + 'Kak 50 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 50, +} + + +# table of hints, format is (name, hint text, clear hint text, type of hint) there are special characters that are read for certain in game commands: +# ^ is a box break +# & is a new line +# @ will print the player name +# # sets color to white (currently only used for dungeon reward hints). +hintTable = { + 'Triforce Piece': (["a triumph fork", "cheese", "a gold fragment"], "a Piece of the Triforce", "item"), + 'Magic Meter': (["mystic training", "pixie dust", "a green rectangle"], "a Magic Meter", 'item'), + 'Double Defense': (["a white outline", "damage decrease", "strengthened love"], "Double Defense", 'item'), + 'Slingshot': (["a seed shooter", "a rubberband", "a child's catapult"], "a Slingshot", 'item'), + 'Boomerang': (["a banana", "a stun stick"], "the Boomerang", 'item'), + 'Bow': (["an archery enabler", "a danger dart launcher"], "a Bow", 'item'), + 'Bomb Bag': (["an explosive container", "a blast bag"], "a Bomb Bag", 'item'), + 'Progressive Hookshot': (["Dampé's keepsake", "the Grapple Beam", "the BOING! chain"], "a Hookshot", 'item'), + 'Progressive Strength Upgrade': (["power gloves", "metal mittens", "the heavy lifty"], "a Strength Upgrade", 'item'), + 'Progressive Scale': (["a deeper dive", "a piece of Zora"], "a Zora Scale", 'item'), + 'Megaton Hammer': (["the dragon smasher", "the metal mallet", "the heavy hitter"], "the Megaton Hammer", 'item'), + 'Iron Boots': (["sink shoes", "clank cleats"], "the Iron Boots", 'item'), + 'Hover Boots': (["butter boots", "sacred slippers", "spacewalkers"], "the Hover Boots", 'item'), + 'Kokiri Sword': (["a butter knife", "a starter slasher", "a switchblade"], "the Kokiri Sword", 'item'), + 'Giants Knife': (["a fragile blade", "a breakable cleaver"], "the Giant's Knife", 'item'), + 'Biggoron Sword': (["the biggest blade", "a colossal cleaver"], "the Biggoron Sword", 'item'), + 'Master Sword': (["evil's bane"], "the Master Sword", 'item'), + 'Deku Shield': (["a wooden ward", "a burnable barrier"], "a Deku Shield", 'item'), + 'Hylian Shield': (["a steel safeguard", "Like Like's metal meal"], "a Hylian Shield", 'item'), + 'Mirror Shield': (["the reflective rampart", "Medusa's weakness", "a silvered surface"], "the Mirror Shield", 'item'), + 'Farores Wind': (["teleportation", "a relocation rune", "a green ball", "a green gust"], "Farore's Wind", 'item'), + 'Nayrus Love': (["a safe space", "an impregnable aura", "a blue barrier", "a blue crystal"], "Nayru's Love", 'item'), + 'Dins Fire': (["an inferno", "a heat wave", "a red ball"], "Din's Fire", 'item'), + 'Fire Arrows': (["the furnace firearm", "the burning bolts", "a magma missile"], "the Fire Arrows", 'item'), + 'Ice Arrows': (["the refrigerator rocket", "the frostbite bolts", "an iceberg maker"], "the Ice Arrows", 'item'), + 'Light Arrows': (["the shining shot", "the luminous launcher", "Ganondorf's bane", "the lighting bolts"], "the Light Arrows", 'item'), + 'Lens of Truth': (["a lie detector", "a ghost tracker", "true sight", "a detective's tool"], "the Lens of Truth", 'item'), + 'Ocarina': (["a flute", "a music maker"], "an Ocarina", 'item'), + 'Goron Tunic': (["ruby robes", "fireproof fabric", "cooking clothes"], "a Goron Tunic", 'item'), + 'Zora Tunic': (["a sapphire suit", "scuba gear", "a swimsuit"], "a Zora Tunic", 'item'), + 'Epona': (["a horse", "a four legged friend"], "Epona", 'item'), + 'Zeldas Lullaby': (["a song of royal slumber", "a triforce tune"], "Zelda's Lullaby", 'item'), + 'Eponas Song': (["an equestrian etude", "Malon's melody", "a ranch song"], "Epona's Song", 'item'), + 'Sarias Song': (["a song of dancing Gorons", "Saria's phone number"], "Saria's Song", 'item'), + 'Suns Song': (["Sunny Day", "the ReDead's bane", "the Gibdo's bane"], "the Sun's Song", 'item'), + 'Song of Time': (["a song 7 years long", "the tune of ages"], "the Song of Time", 'item'), + 'Song of Storms': (["Rain Dance", "a thunderstorm tune", "windmill acceleration"], "the Song of Storms", 'item'), + 'Minuet of Forest': (["the song of tall trees", "an arboreal anthem", "a green spark trail"], "the Minuet of Forest", 'item'), + 'Bolero of Fire': (["a song of lethal lava", "a red spark trail", "a volcanic verse"], "the Bolero of Fire", 'item'), + 'Serenade of Water': (["a song of a damp ditch", "a blue spark trail", "the lake's lyric"], "the Serenade of Water", 'item'), + 'Requiem of Spirit': (["a song of sandy statues", "an orange spark trail", "the desert ditty"], "the Requiem of Spirit", 'item'), + 'Nocturne of Shadow': (["a song of spooky spirits", "a graveyard boogie", "a haunted hymn", "a purple spark trail"], "the Nocturne of Shadow", 'item'), + 'Prelude of Light': (["a luminous prologue melody", "a yellow spark trail", "the temple traveler"], "the Prelude of Light", 'item'), + 'Bottle': (["a glass container", "an empty jar", "encased air"], "a Bottle", 'item'), + 'Rutos Letter': (["a call for help", "the note that Mweeps", "an SOS call", "a fishy stationery"], "Ruto's Letter", 'item'), + 'Bottle with Milk': (["cow juice", "a white liquid", "a baby's breakfast"], "a Milk Bottle", 'item'), + 'Bottle with Red Potion': (["a vitality vial", "a red liquid"], "a Red Potion Bottle", 'item'), + 'Bottle with Green Potion': (["a magic mixture", "a green liquid"], "a Green Potion Bottle", 'item'), + 'Bottle with Blue Potion': (["an ailment antidote", "a blue liquid"], "a Blue Potion Bottle", 'item'), + 'Bottle with Fairy': (["an imprisoned fairy", "an extra life", "Navi's cousin"], "a Fairy Bottle", 'item'), + 'Bottle with Fish': (["an aquarium", "a deity's snack"], "a Fish Bottle", 'item'), + 'Bottle with Blue Fire': (["a conflagration canteen", "an icemelt jar"], "a Blue Fire Bottle", 'item'), + 'Bottle with Bugs': (["an insectarium", "Skulltula finders"], "a Bug Bottle", 'item'), + 'Bottle with Poe': (["a spooky ghost", "a face in the jar"], "a Poe Bottle", 'item'), + 'Bottle with Big Poe': (["the spookiest ghost", "a sidequest spirit"], "a Big Poe Bottle", 'item'), + 'Stone of Agony': (["the shake stone", "the Rumble Pak (TM)"], "the Stone of Agony", 'item'), + 'Gerudo Membership Card': (["a girl club membership", "a desert tribe's pass"], "the Gerudo Card", 'item'), + 'Progressive Wallet': (["a mo' money holder", "a gem purse", "a portable bank"], "a Wallet", 'item'), + 'Deku Stick Capacity': (["a lumber rack", "more flammable twigs"], "Deku Stick Capacity", 'item'), + 'Deku Nut Capacity': (["more nuts", "flashbang storage"], "Deku Nut Capacity", 'item'), + 'Heart Container': (["a lot of love", "a Valentine's gift", "a boss's organ"], "a Heart Container", 'item'), + 'Piece of Heart': (["a little love", "a broken heart"], "a Piece of Heart", 'item'), + 'Piece of Heart (Treasure Chest Game)': ("a victory valentine", "a Piece of Heart", 'item'), + 'Recovery Heart': (["a free heal", "a hearty meal", "a Band-Aid"], "a Recovery Heart", 'item'), + 'Rupee (Treasure Chest Game)': ("the dollar of defeat", 'a Green Rupee', 'item'), + 'Deku Stick (1)': ("a breakable branch", 'a Deku Stick', 'item'), + 'Rupee (1)': (["a unique coin", "a penny", "a green gem"], "a Green Rupee", 'item'), + 'Rupees (5)': (["a common coin", "a blue gem"], "a Blue Rupee", 'item'), + 'Rupees (20)': (["couch cash", "a red gem"], "a Red Rupee", 'item'), + 'Rupees (50)': (["big bucks", "a purple gem", "wealth"], "a Purple Rupee", 'item'), + 'Rupees (200)': (["a juicy jackpot", "a yellow gem", "a giant gem", "great wealth"], "a Huge Rupee", 'item'), + 'Weird Egg': (["a chicken dilemma"], "the Weird Egg", 'item'), + 'Zeldas Letter': (["an autograph", "royal stationery", "royal snail mail"], "Zelda's Letter", 'item'), + 'Pocket Egg': (["a Cucco container", "a Cucco, eventually", "a fowl youth"], "the Pocket Egg", 'item'), + 'Pocket Cucco': (["a little clucker"], "the Pocket Cucco", 'item'), + 'Cojiro': (["a cerulean capon"], "Cojiro", 'item'), + 'Odd Mushroom': (["a powder ingredient"], "an Odd Mushroom", 'item'), + 'Odd Potion': (["Granny's goodies"], "an Odd Potion", 'item'), + 'Poachers Saw': (["a tree killer"], "the Poacher's Saw", 'item'), + 'Broken Sword': (["a shattered slicer"], "the Broken Sword", 'item'), + 'Prescription': (["a pill pamphlet", "a doctor's note"], "the Prescription", 'item'), + 'Eyeball Frog': (["a perceiving polliwog"], "the Eyeball Frog", 'item'), + 'Eyedrops': (["a vision vial"], "the Eyedrops", 'item'), + 'Claim Check': (["a three day wait"], "the Claim Check", 'item'), + 'Map': (["a dungeon atlas", "blueprints"], "a Map", 'item'), + 'Compass': (["a treasure tracker", "a magnetic needle"], "a Compass", 'item'), + 'BossKey': (["a master of unlocking", "a dungeon's master pass"], "a Boss Key", 'item'), + 'GanonBossKey': (["a master of unlocking", "a dungeon's master pass"], "a Boss Key", 'item'), + 'SmallKey': (["a tool for unlocking", "a dungeon pass", "a lock remover", "a lockpick"], "a Small Key", 'item'), + 'FortressSmallKey': (["a get out of jail free card"], "a Jail Key", 'item'), + 'KeyError': (["something mysterious", "an unknown treasure"], "An Error (Please Report This)", 'item'), + 'Arrows (5)': (["a few danger darts", "a few sharp shafts"], "Arrows (5 pieces)", 'item'), + 'Arrows (10)': (["some danger darts", "some sharp shafts"], "Arrows (10 pieces)", 'item'), + 'Arrows (30)': (["plenty of danger darts", "plenty of sharp shafts"], "Arrows (30 pieces)", 'item'), + 'Bombs (5)': (["a few explosives", "a few blast balls"], "Bombs (5 pieces)", 'item'), + 'Bombs (10)': (["some explosives", "some blast balls"], "Bombs (10 pieces)", 'item'), + 'Bombs (20)': (["lots-o-explosives", "plenty of blast balls"], "Bombs (20 pieces)", 'item'), + 'Ice Trap': (["a gift from Ganon", "a chilling discovery", "frosty fun"], "an Ice Trap", 'item'), + 'Magic Bean': (["a wizardly legume"], "a Magic Bean", 'item'), + 'Magic Bean Pack': (["wizardly legumes"], "Magic Beans", 'item'), + 'Bombchus': (["mice bombs", "proximity mice", "wall crawlers", "trail blazers"], "Bombchus", 'item'), + 'Bombchus (5)': (["a few mice bombs", "a few proximity mice", "a few wall crawlers", "a few trail blazers"], "Bombchus (5 pieces)", 'item'), + 'Bombchus (10)': (["some mice bombs", "some proximity mice", "some wall crawlers", "some trail blazers"], "Bombchus (10 pieces)", 'item'), + 'Bombchus (20)': (["plenty of mice bombs", "plenty of proximity mice", "plenty of wall crawlers", "plenty of trail blazers"], "Bombchus (20 pieces)", 'item'), + 'Deku Nuts (5)': (["some nuts", "some flashbangs", "some scrub spit"], "Deku Nuts (5 pieces)", 'item'), + 'Deku Nuts (10)': (["lots-o-nuts", "plenty of flashbangs", "plenty of scrub spit"], "Deku Nuts (10 pieces)", 'item'), + 'Deku Seeds (30)': (["catapult ammo", "lots-o-seeds"], "Deku Seeds (30 pieces)", 'item'), + 'Gold Skulltula Token': (["proof of destruction", "an arachnid chip", "spider remains", "one percent of a curse"], "a Gold Skulltula Token", 'item'), + + 'ZR Frogs Ocarina Game': (["an #amphibian feast# yields", "the #croaking choir's magnum opus# awards", "the #froggy finale# yields"], "the final reward from the #Frogs of Zora's River# is", 'always'), + 'KF Links House Cow': ("the #bovine bounty of a horseback hustle# gifts", "#Malon's obstacle course# leads to", 'always'), + + 'Song from Ocarina of Time': ("the #Ocarina of Time# teaches", None, ['song', 'sometimes']), + 'Song from Composers Grave': (["#ReDead in the Composers' Grave# guard", "the #Composer Brothers wrote#"], None, ['song', 'sometimes']), + 'Sheik in Forest': ("#in a meadow# Sheik teaches", None, ['song', 'sometimes']), + 'Sheik at Temple': ("Sheik waits at a #monument to time# to teach", None, ['song', 'sometimes']), + 'Sheik in Crater': ("the #crater's melody# is", None, ['song', 'sometimes']), + 'Sheik in Ice Cavern': ("the #frozen cavern# echoes with", None, ['song', 'sometimes']), + 'Sheik in Kakariko': ("a #ravaged village# mourns with", None, ['song', 'sometimes']), + 'Sheik at Colossus': ("a hero ventures #beyond the wasteland# to learn", None, ['song', 'sometimes']), + + 'Market 10 Big Poes': ("#ghost hunters# will be rewarded with", "catching #Big Poes# leads to", ['overworld', 'sometimes']), + 'Deku Theater Skull Mask': ("the #Skull Mask# yields", None, ['overworld', 'sometimes']), + 'Deku Theater Mask of Truth': ("showing a #truthful eye to the crowd# rewards", "the #Mask of Truth# yields", ['overworld', 'sometimes']), + 'HF Ocarina of Time Item': ("the #treasure thrown by Princess Zelda# is", None, ['overworld', 'sometimes']), + 'DMT Biggoron': ("#Biggoron# crafts", None, ['overworld', 'sometimes']), + 'Kak 50 Gold Skulltula Reward': (["#50 bug badges# rewards", "#50 spider souls# yields", "#50 auriferous arachnids# lead to"], "slaying #50 Gold Skulltulas# reveals", ['overworld', 'sometimes']), + 'Kak 40 Gold Skulltula Reward': (["#40 bug badges# rewards", "#40 spider souls# yields", "#40 auriferous arachnids# lead to"], "slaying #40 Gold Skulltulas# reveals", ['overworld', 'sometimes']), + 'Kak 30 Gold Skulltula Reward': (["#30 bug badges# rewards", "#30 spider souls# yields", "#30 auriferous arachnids# lead to"], "slaying #30 Gold Skulltulas# reveals", ['overworld', 'sometimes']), + 'Kak 20 Gold Skulltula Reward': (["#20 bug badges# rewards", "#20 spider souls# yields", "#20 auriferous arachnids# lead to"], "slaying #20 Gold Skulltulas# reveals", ['overworld', 'sometimes']), + 'Kak Anju as Child': (["#wrangling roosters# rewards", "#chucking chickens# gifts"], "#collecting cuccos# rewards", ['overworld', 'sometimes']), + 'GC Darunias Joy': ("a #groovin' goron# gifts", "#Darunia's dance# leads to", ['overworld', 'sometimes']), + 'LW Skull Kid': ("the #Skull Kid# grants", None, ['overworld', 'sometimes']), + 'LH Sun': ("staring into #the sun# grants", "shooting #the sun# grants", ['overworld', 'sometimes']), + 'Market Treasure Chest Game Reward': (["#gambling# grants", "there is a #1/32 chance# to win"], "the #treasure chest game# grants", ['overworld', 'sometimes']), + 'GF HBA 1500 Points': ("mastery of #horseback archery# grants", "scoring 1500 in #horseback archery# grants", ['overworld', 'sometimes']), + 'Graveyard Heart Piece Grave Chest': ("playing #Sun's Song# in a grave spawns", None, ['overworld', 'sometimes']), + 'GC Maze Left Chest': ("in #Goron City# the hammer unlocks", None, ['overworld', 'sometimes']), + 'GV Chest': ("in #Gerudo Valley# the hammer unlocks", None, ['overworld', 'sometimes']), + 'GV Cow': ("a #cow in Gerudo Valley# gifts", None, ['overworld', 'sometimes']), + 'HC GS Storms Grotto': ("a #spider behind a muddy wall# in a grotto holds", None, ['overworld', 'sometimes']), + 'HF GS Cow Grotto': ("a #spider behind webs# in a grotto holds", None, ['overworld', 'sometimes']), + 'HF Cow Grotto Cow': ("the #cobwebbed cow# gifts", "a #cow behind webs# in a grotto gifts", ['overworld', 'sometimes']), + 'ZF GS Hidden Cave': ("a spider high #above the icy waters# holds", None, ['overworld', 'sometimes']), + 'Wasteland Chest': (["#deep in the wasteland# is", "beneath #the sands#, flames reveal"], None, ['overworld', 'sometimes']), + 'Wasteland GS': ("a #spider in the wasteland# holds", None, ['overworld', 'sometimes']), + 'Graveyard Composers Grave Chest': (["#flames in the Composers' Grave# reveal", "the #Composer Brothers hid#"], None, ['overworld', 'sometimes']), + 'ZF Bottom Freestanding PoH': ("#under the icy waters# lies", None, ['overworld', 'sometimes']), + 'GC Pot Freestanding PoH': ("spinning #Goron pottery# contains", None, ['overworld', 'sometimes']), + 'ZD King Zora Thawed': ("a #defrosted dignitary# gifts", "unfreezing #King Zora# grants", ['overworld', 'sometimes']), + 'DMC Deku Scrub': ("a single #scrub in the crater# sells", None, ['overworld', 'sometimes']), + 'DMC GS Crate': ("a spider under a #crate in the crater# holds", None, ['overworld', 'sometimes']), + + 'Deku Tree MQ After Spinning Log Chest': ("a #temporal stone within a tree# contains", "a #temporal stone within the Deku Tree# contains", ['dungeon', 'sometimes']), + 'Deku Tree MQ GS Basement Graves Room': ("a #spider on a ceiling in a tree# holds", "a #spider on a ceiling in the Deku Tree# holds", ['dungeon', 'sometimes']), + 'Dodongos Cavern MQ GS Song of Time Block Room': ("a spider under #temporal stones in a cavern# holds", "a spider under #temporal stones in Dodongo's Cavern# holds", ['dungeon', 'sometimes']), + 'Jabu Jabus Belly Boomerang Chest': ("a school of #stingers swallowed by a deity# guard", "a school of #stingers swallowed by Jabu Jabu# guard", ['dungeon', 'sometimes']), + 'Jabu Jabus Belly MQ GS Invisible Enemies Room': ("a spider surrounded by #shadows in the belly of a deity# holds", "a spider surrounded by #shadows in Jabu Jabu's Belly# holds", ['dungeon', 'sometimes']), + 'Jabu Jabus Belly MQ Cow': ("a #cow swallowed by a deity# gifts", "a #cow swallowed by Jabu Jabu# gifts", ['dungeon', 'sometimes']), + 'Fire Temple Scarecrow Chest': ("a #scarecrow atop the volcano# hides", "#Pierre atop the Fire Temple# hides", ['dungeon', 'sometimes']), + 'Fire Temple Megaton Hammer Chest': ("the #Flare Dancer atop the volcano# guards a chest containing", "the #Flare Dancer atop the Fire Temple# guards a chest containing", ['dungeon', 'sometimes']), + 'Fire Temple MQ Chest On Fire': ("the #Flare Dancer atop the volcano# guards a chest containing", "the #Flare Dancer atop the Fire Temple# guards a chest containing", ['dungeon', 'sometimes']), + 'Fire Temple MQ GS Skull On Fire': ("a #spider under a block in the volcano# holds", "a #spider under a block in the Fire Temple# holds", ['dungeon', 'sometimes']), + 'Water Temple River Chest': ("beyond the #river under the lake# waits", "beyond the #river in the Water Temple# waits", ['dungeon', 'sometimes']), + 'Water Temple Boss Key Chest': ("dodging #rolling boulders under the lake# leads to", "dodging #rolling boulders in the Water Temple# leads to", ['dungeon', 'sometimes']), + 'Water Temple GS Behind Gate': ("a spider behind a #gate under the lake# holds", "a spider behind a #gate in the Water Temple# holds", ['dungeon', 'sometimes']), + 'Water Temple MQ Freestanding Key': ("hidden in a #box under the lake# lies", "hidden in a #box in the Water Temple# lies", ['dungeon', 'sometimes']), + 'Water Temple MQ GS Freestanding Key Area': ("the #locked spider under the lake# holds", "the #locked spider in the Water Temple# holds", ['dungeon', 'sometimes']), + 'Water Temple MQ GS Triple Wall Torch': ("a spider behind a #gate under the lake# holds", "a spider behind a #gate in the Water Temple# holds", ['dungeon', 'sometimes']), + 'Gerudo Training Grounds Underwater Silver Rupee Chest': (["those who seek #sunken silver rupees# will find", "the #thieves' underwater training# rewards"], None, ['dungeon', 'sometimes']), + 'Gerudo Training Grounds MQ Underwater Silver Rupee Chest': (["those who seek #sunken silver rupees# will find", "the #thieves' underwater training# rewards"], None, ['dungeon', 'sometimes']), + 'Gerudo Training Grounds Maze Path Final Chest': ("the final prize of #the thieves' training# is", None, ['dungeon', 'sometimes']), + 'Gerudo Training Grounds MQ Ice Arrows Chest': ("the final prize of #the thieves' training# is", None, ['dungeon', 'sometimes']), + 'Bottom of the Well Lens of Truth Chest': (["the well's #grasping ghoul# hides", "a #nether dweller in the well# holds"], "#Dead Hand in the well# holds", ['dungeon', 'sometimes']), + 'Bottom of the Well MQ Compass Chest': (["the well's #grasping ghoul# hides", "a #nether dweller in the well# holds"], "#Dead Hand in the well# holds", ['dungeon', 'sometimes']), + 'Spirit Temple Silver Gauntlets Chest': ("the treasure #sought by Nabooru# is", "upon the #Colossus's right hand# is", ['dungeon', 'sometimes']), + 'Spirit Temple Mirror Shield Chest': ("upon the #Colossus's left hand# is", None, ['dungeon', 'sometimes']), + 'Spirit Temple MQ Child Hammer Switch Chest': ("a #temporal paradox in the Colossus# yields", "a #temporal paradox in the Spirit Temple# yields", ['dungeon', 'sometimes']), + 'Spirit Temple MQ Symphony Room Chest': ("a #symphony in the Colossus# yields", "a #symphony in the Spirit Temple# yields", ['dungeon', 'sometimes']), + 'Spirit Temple MQ GS Symphony Room': ("a #spider's symphony in the Colossus# yields", "a #spider's symphony in the Spirit Temple# yields", ['dungeon', 'sometimes']), + 'Shadow Temple Invisible Floormaster Chest': ("shadows in an #invisible maze# guard", None, ['dungeon', 'sometimes']), + 'Shadow Temple MQ Bomb Flower Chest': ("shadows in an #invisible maze# guard", None, ['dungeon', 'sometimes']), + + 'KF Kokiri Sword Chest': ("the #hidden treasure of the Kokiri# is", None, 'exclude'), + 'KF Midos Top Left Chest': ("the #leader of the Kokiri# hides", "#inside Mido's house# is", 'exclude'), + 'KF Midos Top Right Chest': ("the #leader of the Kokiri# hides", "#inside Mido's house# is", 'exclude'), + 'KF Midos Bottom Left Chest': ("the #leader of the Kokiri# hides", "#inside Mido's house# is", 'exclude'), + 'KF Midos Bottom Right Chest': ("the #leader of the Kokiri# hides", "#inside Mido's house# is", 'exclude'), + 'Graveyard Shield Grave Chest': ("the #treasure of a fallen soldier# is", None, 'exclude'), + 'DMT Chest': ("hidden behind a wall on a #mountain trail# is", None, 'exclude'), + 'GC Maze Right Chest': ("in #Goron City# explosives unlock", None, 'exclude'), + 'GC Maze Center Chest': ("in #Goron City# explosives unlock", None, 'exclude'), + 'ZD Chest': ("fire #beyond a waterfall# reveals", None, 'exclude'), + 'Graveyard Hookshot Chest': ("a chest hidden by a #speedy spectre# holds", "#dead Dampé's first prize# is", 'exclude'), + 'GF Chest': ("on a #rooftop in the desert# lies", None, 'exclude'), + 'Kak Redead Grotto Chest': ("#zombies beneath the earth# guard", None, 'exclude'), + 'SFM Wolfos Grotto Chest': ("#wolves beneath the earth# guard", None, 'exclude'), + 'HF Near Market Grotto Chest': ("a #hole in a field near a drawbridge# holds", None, 'exclude'), + 'HF Southeast Grotto Chest': ("a #hole amongst trees in a field# holds", None, 'exclude'), + 'HF Open Grotto Chest': ("an #open hole in a field# holds", None, 'exclude'), + 'Kak Open Grotto Chest': ("an #open hole in a town# holds", None, 'exclude'), + 'ZR Open Grotto Chest': ("a #hole along a river# holds", None, 'exclude'), + 'KF Storms Grotto Chest': ("a #hole in a forest village# holds", None, 'exclude'), + 'LW Near Shortcuts Grotto Chest': ("a #hole in a wooded maze# holds", None, 'exclude'), + 'DMT Storms Grotto Chest': ("#hole flooded with rain on a mountain# holds", None, 'exclude'), + 'DMC Upper Grotto Chest': ("a #hole in a volcano# holds", None, 'exclude'), + + 'ToT Light Arrows Cutscene': ("the #final gift of a princess# is", None, 'exclude'), + 'LW Gift from Saria': (["a #potato hoarder# holds", "a rooty tooty #flutey cutey# gifts"], "#Saria's Gift# is", 'exclude'), + 'ZF Great Fairy Reward': ("the #fairy of winds# holds", None, 'exclude'), + 'HC Great Fairy Reward': ("the #fairy of fire# holds", None, 'exclude'), + 'Colossus Great Fairy Reward': ("the #fairy of love# holds", None, 'exclude'), + 'DMT Great Fairy Reward': ("a #magical fairy# gifts", None, 'exclude'), + 'DMC Great Fairy Reward': ("a #magical fairy# gifts", None, 'exclude'), + 'OGC Great Fairy Reward': ("the #fairy of strength# holds", None, 'exclude'), + + 'Song from Impa': ("#deep in a castle#, Impa teaches", None, 'exclude'), + 'Song from Malon': ("#a farm girl# sings", None, 'exclude'), + 'Song from Saria': ("#deep in the forest#, Saria teaches", None, 'exclude'), + 'Song from Windmill': ("a man #in a windmill# is obsessed with", None, 'exclude'), + + 'HC Malon Egg': ("a #girl looking for her father# gives", None, 'exclude'), + 'HC Zeldas Letter': ("a #princess in a castle# gifts", None, 'exclude'), + 'ZD Diving Minigame': ("an #unsustainable business model# gifts", "those who #dive for Zora rupees# will find", 'exclude'), + 'LH Child Fishing': ("#fishing in youth# bestows", None, 'exclude'), + 'LH Adult Fishing': ("#fishing in maturity# bestows", None, 'exclude'), + 'LH Lab Dive': ("a #diving experiment# is rewarded with", None, 'exclude'), + 'GC Rolling Goron as Adult': ("#comforting yourself# provides", "#reassuring a young Goron# is rewarded with", 'exclude'), + 'Market Bombchu Bowling First Prize': ("the #first explosive prize# is", None, 'exclude'), + 'Market Bombchu Bowling Second Prize': ("the #second explosive prize# is", None, 'exclude'), + 'Market Lost Dog': ("#puppy lovers# will find", "#rescuing Richard the Dog# is rewarded with", 'exclude'), + 'LW Ocarina Memory Game': (["the prize for a #game of Simon Says# is", "a #child sing-a-long# holds"], "#playing an Ocarina in Lost Woods# is rewarded with", 'exclude'), + 'Kak 10 Gold Skulltula Reward': (["#10 bug badges# rewards", "#10 spider souls# yields", "#10 auriferous arachnids# lead to"], "slaying #10 Gold Skulltulas# reveals", 'exclude'), + 'Kak Man on Roof': ("a #rooftop wanderer# holds", None, 'exclude'), + 'ZR Magic Bean Salesman': ("a seller of #colorful crops# has", "a #bean seller# offers", 'exclude'), + 'ZR Frogs in the Rain': ("#frogs in a storm# gift", None, 'exclude'), + 'GF HBA 1000 Points': ("scoring 1000 in #horseback archery# grants", None, 'exclude'), + 'Market Shooting Gallery Reward': ("#shooting in youth# grants", None, 'exclude'), + 'Kak Shooting Gallery Reward': ("#shooting in maturity# grants", None, 'exclude'), + 'LW Target in Woods': ("shooting a #target in the woods# grants", None, 'exclude'), + 'Kak Anju as Adult': ("a #chicken caretaker# offers adults", None, 'exclude'), + 'LLR Talons Chickens': ("#finding Super Cuccos# is rewarded with", None, 'exclude'), + 'GC Rolling Goron as Child': ("the prize offered by a #large rolling Goron# is", None, 'exclude'), + 'LH Underwater Item': ("the #sunken treasure in a lake# is", None, 'exclude'), + 'GF Gerudo Membership Card': ("#rescuing captured carpenters# is rewarded with", None, 'exclude'), + 'Wasteland Bombchu Salesman': ("a #carpet guru# sells", None, 'exclude'), + + 'Kak Impas House Freestanding PoH': ("#imprisoned in a house# lies", None, 'exclude'), + 'HF Tektite Grotto Freestanding PoH': ("#deep underwater in a hole# is", None, 'exclude'), + 'Kak Windmill Freestanding PoH': ("on a #windmill ledge# lies", None, 'exclude'), + 'Graveyard Dampe Race Freestanding PoH': ("#racing a ghost# leads to", "#dead Dampé's second# prize is", 'exclude'), + 'LLR Freestanding PoH': ("in a #ranch silo# lies", None, 'exclude'), + 'Graveyard Freestanding PoH': ("a #crate in a graveyard# hides", None, 'exclude'), + 'Graveyard Dampe Gravedigging Tour': ("a #gravekeeper digs up#", None, 'exclude'), + 'ZR Near Open Grotto Freestanding PoH': ("on top of a #pillar in a river# lies", None, 'exclude'), + 'ZR Near Domain Freestanding PoH': ("on a #river ledge by a waterfall# lies", None, 'exclude'), + 'LH Freestanding PoH': ("high on a #lab rooftop# one can find", None, 'exclude'), + 'ZF Iceberg Freestanding PoH': ("#floating on ice# is", None, 'exclude'), + 'GV Waterfall Freestanding PoH': ("behind a #desert waterfall# is", None, 'exclude'), + 'GV Crate Freestanding PoH': ("a #crate in a valley# hides", None, 'exclude'), + 'Colossus Freestanding PoH': ("on top of an #arch of stone# lies", None, 'exclude'), + 'DMT Freestanding PoH': ("above a #mountain cavern entrance# is", None, 'exclude'), + 'DMC Wall Freestanding PoH': ("nestled in a #volcanic wall# is", None, 'exclude'), + 'DMC Volcano Freestanding PoH': ("obscured by #volcanic ash# is", None, 'exclude'), + 'GF North F1 Carpenter': ("#defeating Gerudo guards# reveals", None, 'exclude'), + 'GF North F2 Carpenter': ("#defeating Gerudo guards# reveals", None, 'exclude'), + 'GF South F1 Carpenter': ("#defeating Gerudo guards# reveals", None, 'exclude'), + 'GF South F2 Carpenter': ("#defeating Gerudo guards# reveals", None, 'exclude'), + + 'Deku Tree Map Chest': ("in the #center of the Deku Tree# lies", None, 'exclude'), + 'Deku Tree Slingshot Chest': ("the #treasure guarded by a scrub# in the Deku Tree is", None, 'exclude'), + 'Deku Tree Slingshot Room Side Chest': ("the #treasure guarded by a scrub# in the Deku Tree is", None, 'exclude'), + 'Deku Tree Compass Chest': ("#pillars of wood# in the Deku Tree lead to", None, 'exclude'), + 'Deku Tree Compass Room Side Chest': ("#pillars of wood# in the Deku Tree lead to", None, 'exclude'), + 'Deku Tree Basement Chest': ("#webs in the Deku Tree# hide", None, 'exclude'), + + 'Deku Tree MQ Map Chest': ("in the #center of the Deku Tree# lies", None, 'exclude'), + 'Deku Tree MQ Compass Chest': ("a #treasure guarded by a large spider# in the Deku Tree is", None, 'exclude'), + 'Deku Tree MQ Slingshot Chest': ("#pillars of wood# in the Deku Tree lead to", None, 'exclude'), + 'Deku Tree MQ Slingshot Room Back Chest': ("#pillars of wood# in the Deku Tree lead to", None, 'exclude'), + 'Deku Tree MQ Basement Chest': ("#webs in the Deku Tree# hide", None, 'exclude'), + 'Deku Tree MQ Before Spinning Log Chest': ("#magical fire in the Deku Tree# leads to", None, 'exclude'), + + 'Dodongos Cavern Boss Room Chest': ("#above King Dodongo# lies", None, 'exclude'), + + 'Dodongos Cavern Map Chest': ("a #muddy wall in Dodongo's Cavern# hides", None, 'exclude'), + 'Dodongos Cavern Compass Chest': ("a #statue in Dodongo's Cavern# guards", None, 'exclude'), + 'Dodongos Cavern Bomb Flower Platform Chest': ("above a #maze of stone# in Dodongo's Cavern lies", None, 'exclude'), + 'Dodongos Cavern Bomb Bag Chest': ("the #second lizard cavern battle# yields", None, 'exclude'), + 'Dodongos Cavern End of Bridge Chest': ("a #chest at the end of a bridge# yields", None, 'exclude'), + + 'Dodongos Cavern MQ Map Chest': ("a #muddy wall in Dodongo's Cavern# hides", None, 'exclude'), + 'Dodongos Cavern MQ Bomb Bag Chest': ("an #elevated alcove# in Dodongo's Cavern holds", None, 'exclude'), + 'Dodongos Cavern MQ Compass Chest': ("#fire-breathing lizards# in Dodongo's Cavern guard", None, 'exclude'), + 'Dodongos Cavern MQ Larvae Room Chest': ("#baby spiders# in Dodongo's Cavern guard", None, 'exclude'), + 'Dodongos Cavern MQ Torch Puzzle Room Chest': ("above a #maze of stone# in Dodongo's Cavern lies", None, 'exclude'), + 'Dodongos Cavern MQ Under Grave Chest': ("#beneath a headstone# in Dodongo's Cavern lies", None, 'exclude'), + + 'Jabu Jabus Belly Map Chest': ("#tentacle trouble# in a deity's belly guards", "a #slimy thing# guards", 'exclude'), + 'Jabu Jabus Belly Compass Chest': ("#bubble trouble# in a deity's belly guards", "#bubbles# guard", 'exclude'), + + 'Jabu Jabus Belly MQ First Room Side Chest': ("shooting a #mouth cow# reveals", None, 'exclude'), + 'Jabu Jabus Belly MQ Map Chest': (["#pop rocks# hide", "an #explosive palate# holds"], "a #boulder before cows# hides", 'exclude'), + 'Jabu Jabus Belly MQ Second Room Lower Chest': ("near a #spiked elevator# lies", None, 'exclude'), + 'Jabu Jabus Belly MQ Compass Chest': ("a #drowning cow# unveils", None, 'exclude'), + 'Jabu Jabus Belly MQ Second Room Upper Chest': ("#moving anatomy# creates a path to", None, 'exclude'), + 'Jabu Jabus Belly MQ Basement Near Switches Chest': ("a #pair of digested cows# hold", None, 'exclude'), + 'Jabu Jabus Belly MQ Basement Near Vines Chest': ("a #pair of digested cows# hold", None, 'exclude'), + 'Jabu Jabus Belly MQ Near Boss Chest': ("the #final cows' reward# in a deity's belly is", None, 'exclude'), + 'Jabu Jabus Belly MQ Falling Like Like Room Chest': ("#cows protected by falling monsters# in a deity's belly guard", None, 'exclude'), + 'Jabu Jabus Belly MQ Boomerang Room Small Chest': ("a school of #stingers swallowed by a deity# guard", "a school of #stingers swallowed by Jabu Jabu# guard", 'exclude'), + 'Jabu Jabus Belly MQ Boomerang Chest': ("a school of #stingers swallowed by a deity# guard", "a school of #stingers swallowed by Jabu Jabu# guard", 'exclude'), + + 'Forest Temple First Room Chest': ("a #tree in the Forest Temple# supports", None, 'exclude'), + 'Forest Temple First Stalfos Chest': ("#defeating enemies beneath a falling ceiling# in Forest Temple yields", None, 'exclude'), + 'Forest Temple Well Chest': ("a #sunken chest deep in the woods# contains", None, 'exclude'), + 'Forest Temple Map Chest': ("a #fiery skull# in Forest Temple guards", None, 'exclude'), + 'Forest Temple Raised Island Courtyard Chest': ("a #chest on a small island# in the Forest Temple holds", None, 'exclude'), + 'Forest Temple Falling Ceiling Room Chest': ("beneath a #checkerboard falling ceiling# lies", None, 'exclude'), + 'Forest Temple Eye Switch Chest': ("a #sharp eye# will spot", "#blocks of stone# in the Forest Temple surround", 'exclude'), + 'Forest Temple Boss Key Chest': ("a #turned trunk# contains", None, 'exclude'), + 'Forest Temple Floormaster Chest': ("deep in the forest #shadows guard a chest# containing", None, 'exclude'), + 'Forest Temple Bow Chest': ("an #army of the dead# guards", "#Stalfos deep in the Forest Temple# guard", 'exclude'), + 'Forest Temple Red Poe Chest': ("#Joelle# guards", "a #red ghost# guards", 'exclude'), + 'Forest Temple Blue Poe Chest': ("#Beth# guards", "a #blue ghost# guards", 'exclude'), + 'Forest Temple Basement Chest': ("#revolving walls# in the Forest Temple conceal", None, 'exclude'), + + 'Forest Temple MQ First Room Chest': ("a #tree in the Forest Temple# supports", None, 'exclude'), + 'Forest Temple MQ Wolfos Chest': ("#defeating enemies beneath a falling ceiling# in Forest Temple yields", None, 'exclude'), + 'Forest Temple MQ Bow Chest': ("an #army of the dead# guards", "#Stalfos deep in the Forest Temple# guard", 'exclude'), + 'Forest Temple MQ Raised Island Courtyard Lower Chest': ("a #chest on a small island# in the Forest Temple holds", None, 'exclude'), + 'Forest Temple MQ Raised Island Courtyard Upper Chest': ("#high in a courtyard# within the Forest Temple is", None, 'exclude'), + 'Forest Temple MQ Well Chest': ("a #sunken chest deep in the woods# contains", None, 'exclude'), + 'Forest Temple MQ Map Chest': ("#Joelle# guards", "a #red ghost# guards", 'exclude'), + 'Forest Temple MQ Compass Chest': ("#Beth# guards", "a #blue ghost# guards", 'exclude'), + 'Forest Temple MQ Falling Ceiling Room Chest': ("beneath a #checkerboard falling ceiling# lies", None, 'exclude'), + 'Forest Temple MQ Basement Chest': ("#revolving walls# in the Forest Temple conceal", None, 'exclude'), + 'Forest Temple MQ Redead Chest': ("deep in the forest #undead guard a chest# containing", None, 'exclude'), + 'Forest Temple MQ Boss Key Chest': ("a #turned trunk# contains", None, 'exclude'), + + 'Fire Temple Near Boss Chest': ("#near a dragon# is", None, 'exclude'), + 'Fire Temple Flare Dancer Chest': ("the #Flare Dancer behind a totem# guards", None, 'exclude'), + 'Fire Temple Boss Key Chest': ("a #prison beyond a totem# holds", None, 'exclude'), + 'Fire Temple Big Lava Room Blocked Door Chest': ("#explosives over a lava pit# unveil", None, 'exclude'), + 'Fire Temple Big Lava Room Lower Open Door Chest': ("a #Goron trapped near lava# holds", None, 'exclude'), + 'Fire Temple Boulder Maze Lower Chest': ("a #Goron at the end of a maze# holds", None, 'exclude'), + 'Fire Temple Boulder Maze Upper Chest': ("a #Goron above a maze# holds", None, 'exclude'), + 'Fire Temple Boulder Maze Side Room Chest': ("a #Goron hidden near a maze# holds", None, 'exclude'), + 'Fire Temple Boulder Maze Shortcut Chest': ("a #blocked path# in Fire Temple holds", None, 'exclude'), + 'Fire Temple Map Chest': ("a #caged chest# in the Fire Temple hoards", None, 'exclude'), + 'Fire Temple Compass Chest': ("a #chest in a fiery maze# contains", None, 'exclude'), + 'Fire Temple Highest Goron Chest': ("a #Goron atop the Fire Temple# holds", None, 'exclude'), + + 'Fire Temple MQ Near Boss Chest': ("#near a dragon# is", None, 'exclude'), + 'Fire Temple MQ Megaton Hammer Chest': ("the #Flare Dancer in the depths of a volcano# guards", "the #Flare Dancer in the depths of the Fire Temple# guards", 'exclude'), + 'Fire Temple MQ Compass Chest': ("a #blocked path# in Fire Temple holds", None, 'exclude'), + 'Fire Temple MQ Lizalfos Maze Lower Chest': ("#crates in a maze# contain", None, 'exclude'), + 'Fire Temple MQ Lizalfos Maze Upper Chest': ("#crates in a maze# contain", None, 'exclude'), + 'Fire Temple MQ Map Room Side Chest': ("a #falling slug# in the Fire Temple guards", None, 'exclude'), + 'Fire Temple MQ Map Chest': ("using a #hammer in the depths of the Fire Temple# reveals", None, 'exclude'), + 'Fire Temple MQ Boss Key Chest': ("#illuminating a lava pit# reveals the path to", None, 'exclude'), + 'Fire Temple MQ Big Lava Room Blocked Door Chest': ("#explosives over a lava pit# unveil", None, 'exclude'), + 'Fire Temple MQ Lizalfos Maze Side Room Chest': ("a #Goron hidden near a maze# holds", None, 'exclude'), + 'Fire Temple MQ Freestanding Key': ("hidden #beneath a block of stone# lies", None, 'exclude'), + + 'Water Temple Map Chest': ("#rolling spikes# in the Water Temple surround", None, 'exclude'), + 'Water Temple Compass Chest': ("#roaming stingers in the Water Temple# guard", None, 'exclude'), + 'Water Temple Torches Chest': ("#fire in the Water Temple# reveals", None, 'exclude'), + 'Water Temple Dragon Chest': ("a #serpent's prize# in the Water Temple is", None, 'exclude'), + 'Water Temple Central Bow Target Chest': ("#blinding an eye# in the Water Temple leads to", None, 'exclude'), + 'Water Temple Central Pillar Chest': ("in the #depths of the Water Temple# lies", None, 'exclude'), + 'Water Temple Cracked Wall Chest': ("#through a crack# in the Water Temple is", None, 'exclude'), + 'Water Temple Longshot Chest': (["#facing yourself# reveals", "a #dark reflection# of yourself guards"], "#Dark Link# guards", 'exclude'), + + 'Water Temple MQ Central Pillar Chest': ("in the #depths of the Water Temple# lies", None, 'exclude'), + 'Water Temple MQ Boss Key Chest': ("fire in the Water Temple unlocks a #vast gate# revealing a chest with", None, 'exclude'), + 'Water Temple MQ Longshot Chest': ("#through a crack# in the Water Temple is", None, 'exclude'), + 'Water Temple MQ Compass Chest': ("#fire in the Water Temple# reveals", None, 'exclude'), + 'Water Temple MQ Map Chest': ("#sparring soldiers# in the Water Temple guard", None, 'exclude'), + + 'Spirit Temple Child Bridge Chest': ("a child conquers a #skull in green fire# in the Spirit Temple to reach", None, 'exclude'), + 'Spirit Temple Child Early Torches Chest': ("a child can find a #caged chest# in the Spirit Temple with", None, 'exclude'), + 'Spirit Temple Compass Chest': ("#across a pit of sand# in the Spirit Temple lies", None, 'exclude'), + 'Spirit Temple Early Adult Right Chest': ("#dodging boulders to collect silver rupees# in the Spirit Temple yields", None, 'exclude'), + 'Spirit Temple First Mirror Left Chest': ("a #shadow circling reflected light# in the Spirit Temple guards", None, 'exclude'), + 'Spirit Temple First Mirror Right Chest': ("a #shadow circling reflected light# in the Spirit Temple guards", None, 'exclude'), + 'Spirit Temple Map Chest': ("#before a giant statue# in the Spirit Temple lies", None, 'exclude'), + 'Spirit Temple Child Climb North Chest': ("#lizards in the Spirit Temple# guard", None, 'exclude'), + 'Spirit Temple Child Climb East Chest': ("#lizards in the Spirit Temple# guard", None, 'exclude'), + 'Spirit Temple Sun Block Room Chest': ("#torchlight among Beamos# in the Spirit Temple reveals", None, 'exclude'), + 'Spirit Temple Statue Room Hand Chest': ("a #statue in the Spirit Temple# holds", None, 'exclude'), + 'Spirit Temple Statue Room Northeast Chest': ("on a #ledge by a statue# in the Spirit Temple rests", None, 'exclude'), + 'Spirit Temple Near Four Armos Chest': ("those who #show the light among statues# in the Spirit Temple find", None, 'exclude'), + 'Spirit Temple Hallway Right Invisible Chest': ("the #Eye of Truth in the Spirit Temple# reveals", None, 'exclude'), + 'Spirit Temple Hallway Left Invisible Chest': ("the #Eye of Truth in the Spirit Temple# reveals", None, 'exclude'), + 'Spirit Temple Boss Key Chest': ("a #chest engulfed in flame# in the Spirit Temple holds", None, 'exclude'), + 'Spirit Temple Topmost Chest': ("those who #show the light above the Colossus# find", None, 'exclude'), + + 'Spirit Temple MQ Entrance Front Left Chest': ("#lying unguarded# in the Spirit Temple is", None, 'exclude'), + 'Spirit Temple MQ Entrance Back Right Chest': ("a #switch in a pillar# within the Spirit Temple drops", None, 'exclude'), + 'Spirit Temple MQ Entrance Front Right Chest': ("#collecting rupees through a water jet# reveals", None, 'exclude'), + 'Spirit Temple MQ Entrance Back Left Chest': ("an #eye blinded by stone# within the Spirit Temple conceals", None, 'exclude'), + 'Spirit Temple MQ Map Chest': ("surrounded by #fire and wrappings# lies", None, 'exclude'), + 'Spirit Temple MQ Map Room Enemy Chest': ("a child defeats a #gauntlet of monsters# within the Spirit Temple to find", None, 'exclude'), + 'Spirit Temple MQ Child Climb North Chest': ("#explosive sunlight# within the Spirit Temple uncovers", None, 'exclude'), + 'Spirit Temple MQ Child Climb South Chest': ("#trapped by falling enemies# within the Spirit Temple is", None, 'exclude'), + 'Spirit Temple MQ Compass Chest': ("#blinding the colossus# unveils", None, 'exclude'), + 'Spirit Temple MQ Statue Room Lullaby Chest': ("a #royal melody awakens the colossus# to reveal", None, 'exclude'), + 'Spirit Temple MQ Statue Room Invisible Chest': ("the #Eye of Truth# finds the colossus's hidden", None, 'exclude'), + 'Spirit Temple MQ Silver Block Hallway Chest': ("#the old hide what the young find# to reveal", None, 'exclude'), + 'Spirit Temple MQ Sun Block Room Chest': ("#sunlight in a maze of fire# hides", None, 'exclude'), + 'Spirit Temple MQ Leever Room Chest': ("#across a pit of sand# in the Spirit Temple lies", None, 'exclude'), + 'Spirit Temple MQ Beamos Room Chest': ("where #temporal stone blocks the path# within the Spirit Temple lies", None, 'exclude'), + 'Spirit Temple MQ Chest Switch Chest': ("a #chest of double purpose# holds", None, 'exclude'), + 'Spirit Temple MQ Boss Key Chest': ("a #temporal stone blocks the light# leading to", None, 'exclude'), + 'Spirit Temple MQ Mirror Puzzle Invisible Chest': ("those who #show the light above the Colossus# find", None, 'exclude'), + + 'Shadow Temple Map Chest': ("the #Eye of Truth# pierces a hall of faces to reveal", None, 'exclude'), + 'Shadow Temple Hover Boots Chest': ("a #nether dweller in the Shadow Temple# holds", "#Dead Hand in the Shadow Temple# holds", 'exclude'), + 'Shadow Temple Compass Chest': ("#mummies revealed by the Eye of Truth# guard", None, 'exclude'), + 'Shadow Temple Early Silver Rupee Chest': ("#spinning scythes# protect", None, 'exclude'), + 'Shadow Temple Invisible Blades Visible Chest': ("#invisible blades# guard", None, 'exclude'), + 'Shadow Temple Invisible Blades Invisible Chest': ("#invisible blades# guard", None, 'exclude'), + 'Shadow Temple Falling Spikes Lower Chest': ("#falling spikes# block the path to", None, 'exclude'), + 'Shadow Temple Falling Spikes Upper Chest': ("#falling spikes# block the path to", None, 'exclude'), + 'Shadow Temple Falling Spikes Switch Chest': ("#falling spikes# block the path to", None, 'exclude'), + 'Shadow Temple Invisible Spikes Chest': ("the #dead roam among invisible spikes# guarding", None, 'exclude'), + 'Shadow Temple Wind Hint Chest': ("an #invisible chest guarded by the dead# holds", None, 'exclude'), + 'Shadow Temple After Wind Enemy Chest': ("#mummies guarding a ferry# hide", None, 'exclude'), + 'Shadow Temple After Wind Hidden Chest': ("#mummies guarding a ferry# hide", None, 'exclude'), + 'Shadow Temple Spike Walls Left Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'), + 'Shadow Temple Boss Key Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'), + 'Shadow Temple Freestanding Key': ("#inside a burning skull# lies", None, 'exclude'), + + 'Shadow Temple MQ Compass Chest': ("the #Eye of Truth# pierces a hall of faces to reveal", None, 'exclude'), + 'Shadow Temple MQ Hover Boots Chest': ("#Dead Hand in the Shadow Temple# holds", None, 'exclude'), + 'Shadow Temple MQ Early Gibdos Chest': ("#mummies revealed by the Eye of Truth# guard", None, 'exclude'), + 'Shadow Temple MQ Map Chest': ("#spinning scythes# protect", None, 'exclude'), + 'Shadow Temple MQ Beamos Silver Rupees Chest': ("#collecting rupees in a vast cavern# with the Shadow Temple unveils", None, 'exclude'), + 'Shadow Temple MQ Falling Spikes Switch Chest': ("#falling spikes# block the path to", None, 'exclude'), + 'Shadow Temple MQ Falling Spikes Lower Chest': ("#falling spikes# block the path to", None, 'exclude'), + 'Shadow Temple MQ Falling Spikes Upper Chest': ("#falling spikes# block the path to", None, 'exclude'), + 'Shadow Temple MQ Invisible Spikes Chest': ("the #dead roam among invisible spikes# guarding", None, 'exclude'), + 'Shadow Temple MQ Boss Key Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'), + 'Shadow Temple MQ Spike Walls Left Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'), + 'Shadow Temple MQ Stalfos Room Chest': ("near an #empty pedestal# within the Shadow Temple lies", None, 'exclude'), + 'Shadow Temple MQ Invisible Blades Invisible Chest': ("#invisible blades# guard", None, 'exclude'), + 'Shadow Temple MQ Invisible Blades Visible Chest': ("#invisible blades# guard", None, 'exclude'), + 'Shadow Temple MQ Wind Hint Chest': ("an #invisible chest guarded by the dead# holds", None, 'exclude'), + 'Shadow Temple MQ After Wind Hidden Chest': ("#mummies guarding a ferry# hide", None, 'exclude'), + 'Shadow Temple MQ After Wind Enemy Chest': ("#mummies guarding a ferry# hide", None, 'exclude'), + 'Shadow Temple MQ Near Ship Invisible Chest': ("#caged near a ship# lies", None, 'exclude'), + 'Shadow Temple MQ Freestanding Key': ("#behind three burning skulls# lies", None, 'exclude'), + + 'Bottom of the Well Front Left Fake Wall Chest': ("the #Eye of Truth in the well# reveals", None, 'exclude'), + 'Bottom of the Well Front Center Bombable Chest': ("#gruesome debris# in the well hides", None, 'exclude'), + 'Bottom of the Well Right Bottom Fake Wall Chest': ("the #Eye of Truth in the well# reveals", None, 'exclude'), + 'Bottom of the Well Compass Chest': ("a #hidden entrance to a cage# in the well leads to", None, 'exclude'), + 'Bottom of the Well Center Skulltula Chest': ("a #spider guarding a cage# in the well protects", None, 'exclude'), + 'Bottom of the Well Back Left Bombable Chest': ("#gruesome debris# in the well hides", None, 'exclude'), + 'Bottom of the Well Invisible Chest': ("#Dead Hand's invisible secret# is", None, 'exclude'), + 'Bottom of the Well Underwater Front Chest': ("a #royal melody in the well# uncovers", None, 'exclude'), + 'Bottom of the Well Underwater Left Chest': ("a #royal melody in the well# uncovers", None, 'exclude'), + 'Bottom of the Well Map Chest': ("in the #depths of the well# lies", None, 'exclude'), + 'Bottom of the Well Fire Keese Chest': ("#perilous pits# in the well guard the path to", None, 'exclude'), + 'Bottom of the Well Like Like Chest': ("#locked in a cage# in the well lies", None, 'exclude'), + 'Bottom of the Well Freestanding Key': ("#inside a coffin# hides", None, 'exclude'), + + 'Bottom of the Well MQ Map Chest': ("a #royal melody in the well# uncovers", None, 'exclude'), + 'Bottom of the Well MQ Lens of Truth Chest': ("an #army of the dead# in the well guards", None, 'exclude'), + 'Bottom of the Well MQ Dead Hand Freestanding Key': ("#Dead Hand's explosive secret# is", None, 'exclude'), + 'Bottom of the Well MQ East Inner Room Freestanding Key': ("an #invisible path in the well# leads to", None, 'exclude'), + + 'Ice Cavern Map Chest': ("#winds of ice# surround", None, 'exclude'), + 'Ice Cavern Compass Chest': ("a #wall of ice# protects", None, 'exclude'), + 'Ice Cavern Iron Boots Chest': ("a #monster in a frozen cavern# guards", None, 'exclude'), + 'Ice Cavern Freestanding PoH': ("a #wall of ice# protects", None, 'exclude'), + + 'Ice Cavern MQ Iron Boots Chest': ("a #monster in a frozen cavern# guards", None, 'exclude'), + 'Ice Cavern MQ Compass Chest': ("#winds of ice# surround", None, 'exclude'), + 'Ice Cavern MQ Map Chest': ("a #wall of ice# protects", None, 'exclude'), + 'Ice Cavern MQ Freestanding PoH': ("#winds of ice# surround", None, 'exclude'), + + 'Gerudo Training Grounds Lobby Left Chest': ("a #blinded eye in the Gerudo Training Grounds# drops", None, 'exclude'), + 'Gerudo Training Grounds Lobby Right Chest': ("a #blinded eye in the Gerudo Training Grounds# drops", None, 'exclude'), + 'Gerudo Training Grounds Stalfos Chest': ("#soldiers walking on shifting sands# in the Gerudo Training Grounds guard", None, 'exclude'), + 'Gerudo Training Grounds Beamos Chest': ("#reptilian warriors# in the Gerudo Training Grounds protect", None, 'exclude'), + 'Gerudo Training Grounds Hidden Ceiling Chest': ("the #Eye of Truth# in the Gerudo Training Grounds reveals", None, 'exclude'), + 'Gerudo Training Grounds Maze Path First Chest': ("the first prize of #the thieves' training# is", None, 'exclude'), + 'Gerudo Training Grounds Maze Path Second Chest': ("the second prize of #the thieves' training# is", None, 'exclude'), + 'Gerudo Training Grounds Maze Path Third Chest': ("the third prize of #the thieves' training# is", None, 'exclude'), + 'Gerudo Training Grounds Maze Right Central Chest': ("the #Song of Time# in the Gerudo Training Grounds leads to", None, 'exclude'), + 'Gerudo Training Grounds Maze Right Side Chest': ("the #Song of Time# in the Gerudo Training Grounds leads to", None, 'exclude'), + 'Gerudo Training Grounds Hammer Room Clear Chest': ("#fiery foes# in the Gerudo Training Grounds guard", None, 'exclude'), + 'Gerudo Training Grounds Hammer Room Switch Chest': ("#engulfed in flame# where thieves train lies", None, 'exclude'), + 'Gerudo Training Grounds Eye Statue Chest': ("thieves #blind four faces# to find", None, 'exclude'), + 'Gerudo Training Grounds Near Scarecrow Chest': ("thieves #blind four faces# to find", None, 'exclude'), + 'Gerudo Training Grounds Before Heavy Block Chest': ("#before a block of silver# thieves can find", None, 'exclude'), + 'Gerudo Training Grounds Heavy Block First Chest': ("a #feat of strength# rewards thieves with", None, 'exclude'), + 'Gerudo Training Grounds Heavy Block Second Chest': ("a #feat of strength# rewards thieves with", None, 'exclude'), + 'Gerudo Training Grounds Heavy Block Third Chest': ("a #feat of strength# rewards thieves with", None, 'exclude'), + 'Gerudo Training Grounds Heavy Block Fourth Chest': ("a #feat of strength# rewards thieves with", None, 'exclude'), + 'Gerudo Training Grounds Freestanding Key': ("the #Song of Time# in the Gerudo Training Grounds leads to", None, 'exclude'), + + 'Gerudo Training Grounds MQ Lobby Right Chest': ("#thieves prepare for training# with", None, 'exclude'), + 'Gerudo Training Grounds MQ Lobby Left Chest': ("#thieves prepare for training# with", None, 'exclude'), + 'Gerudo Training Grounds MQ First Iron Knuckle Chest': ("#soldiers walking on shifting sands# in the Gerudo Training Grounds guard", None, 'exclude'), + 'Gerudo Training Grounds MQ Before Heavy Block Chest': ("#before a block of silver# thieves can find", None, 'exclude'), + 'Gerudo Training Grounds MQ Eye Statue Chest': ("thieves #blind four faces# to find", None, 'exclude'), + 'Gerudo Training Grounds MQ Flame Circle Chest': ("#engulfed in flame# where thieves train lies", None, 'exclude'), + 'Gerudo Training Grounds MQ Second Iron Knuckle Chest': ("#fiery foes# in the Gerudo Training Grounds guard", None, 'exclude'), + 'Gerudo Training Grounds MQ Dinolfos Chest': ("#reptilian warriors# in the Gerudo Training Grounds protect", None, 'exclude'), + 'Gerudo Training Grounds MQ Maze Right Central Chest': ("a #path of fire# leads thieves to", None, 'exclude'), + 'Gerudo Training Grounds MQ Maze Path First Chest': ("the first prize of #the thieves' training# is", None, 'exclude'), + 'Gerudo Training Grounds MQ Maze Right Side Chest': ("a #path of fire# leads thieves to", None, 'exclude'), + 'Gerudo Training Grounds MQ Maze Path Third Chest': ("the third prize of #the thieves' training# is", None, 'exclude'), + 'Gerudo Training Grounds MQ Maze Path Second Chest': ("the second prize of #the thieves' training# is", None, 'exclude'), + 'Gerudo Training Grounds MQ Hidden Ceiling Chest': ("the #Eye of Truth# in the Gerudo Training Grounds reveals", None, 'exclude'), + 'Gerudo Training Grounds MQ Heavy Block Chest': ("a #feat of strength# rewards thieves with", None, 'exclude'), + + 'Ganons Tower Boss Key Chest': ("the #Evil King# hoards", None, 'exclude'), + + 'Ganons Castle Forest Trial Chest': ("the #test of the wilds# holds", None, 'exclude'), + 'Ganons Castle Water Trial Left Chest': ("the #test of the seas# holds", None, 'exclude'), + 'Ganons Castle Water Trial Right Chest': ("the #test of the seas# holds", None, 'exclude'), + 'Ganons Castle Shadow Trial Front Chest': ("#music in the test of darkness# unveils", None, 'exclude'), + 'Ganons Castle Shadow Trial Golden Gauntlets Chest': ("#light in the test of darkness# unveils", None, 'exclude'), + 'Ganons Castle Spirit Trial Crystal Switch Chest': ("the #test of the sands# holds", None, 'exclude'), + 'Ganons Castle Spirit Trial Invisible Chest': ("the #test of the sands# holds", None, 'exclude'), + 'Ganons Castle Light Trial First Left Chest': ("the #test of radiance# holds", None, 'exclude'), + 'Ganons Castle Light Trial Second Left Chest': ("the #test of radiance# holds", None, 'exclude'), + 'Ganons Castle Light Trial Third Left Chest': ("the #test of radiance# holds", None, 'exclude'), + 'Ganons Castle Light Trial First Right Chest': ("the #test of radiance# holds", None, 'exclude'), + 'Ganons Castle Light Trial Second Right Chest': ("the #test of radiance# holds", None, 'exclude'), + 'Ganons Castle Light Trial Third Right Chest': ("the #test of radiance# holds", None, 'exclude'), + 'Ganons Castle Light Trial Invisible Enemies Chest': ("the #test of radiance# holds", None, 'exclude'), + 'Ganons Castle Light Trial Lullaby Chest': ("#music in the test of radiance# reveals", None, 'exclude'), + + 'Ganons Castle MQ Water Trial Chest': ("the #test of the seas# holds", None, 'exclude'), + 'Ganons Castle MQ Forest Trial Eye Switch Chest': ("the #test of the wilds# holds", None, 'exclude'), + 'Ganons Castle MQ Forest Trial Frozen Eye Switch Chest': ("the #test of the wilds# holds", None, 'exclude'), + 'Ganons Castle MQ Light Trial Lullaby Chest': ("#music in the test of radiance# reveals", None, 'exclude'), + 'Ganons Castle MQ Shadow Trial Bomb Flower Chest': ("the #test of darkness# holds", None, 'exclude'), + 'Ganons Castle MQ Shadow Trial Eye Switch Chest': ("the #test of darkness# holds", None, 'exclude'), + 'Ganons Castle MQ Spirit Trial Golden Gauntlets Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'), + 'Ganons Castle MQ Spirit Trial Sun Back Right Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'), + 'Ganons Castle MQ Spirit Trial Sun Back Left Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'), + 'Ganons Castle MQ Spirit Trial Sun Front Left Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'), + 'Ganons Castle MQ Spirit Trial First Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'), + 'Ganons Castle MQ Spirit Trial Invisible Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'), + 'Ganons Castle MQ Forest Trial Freestanding Key': ("the #test of the wilds# holds", None, 'exclude'), + + 'Deku Tree Queen Gohma Heart': ("the #Parasitic Armored Arachnid# holds", "#Queen Gohma# holds", 'exclude'), + 'Dodongos Cavern King Dodongo Heart': ("the #Infernal Dinosaur# holds", "#King Dodongo# holds", 'exclude'), + 'Jabu Jabus Belly Barinade Heart': ("the #Bio-Electric Anemone# holds", "#Barinade# holds", 'exclude'), + 'Forest Temple Phantom Ganon Heart': ("the #Evil Spirit from Beyond# holds", "#Phantom Ganon# holds", 'exclude'), + 'Fire Temple Volvagia Heart': ("the #Subterranean Lava Dragon# holds", "#Volvagia# holds", 'exclude'), + 'Water Temple Morpha Heart': ("the #Giant Aquatic Amoeba# holds", "#Morpha# holds", 'exclude'), + 'Spirit Temple Twinrova Heart': ("the #Sorceress Sisters# hold", "#Twinrova# holds", 'exclude'), + 'Shadow Temple Bongo Bongo Heart': ("the #Phantom Shadow Beast# holds", "#Bongo Bongo# holds", 'exclude'), + + 'Deku Tree GS Basement Back Room': ("a #spider deep within the Deku Tree# hides", None, 'exclude'), + 'Deku Tree GS Basement Gate': ("a #web protects a spider# within the Deku Tree holding", None, 'exclude'), + 'Deku Tree GS Basement Vines': ("a #web protects a spider# within the Deku Tree holding", None, 'exclude'), + 'Deku Tree GS Compass Room': ("a #spider atop the Deku Tree# holds", None, 'exclude'), + + 'Deku Tree MQ GS Lobby': ("a #spider in a crate# within the Deku Tree hides", None, 'exclude'), + 'Deku Tree MQ GS Compass Room': ("a #wall of rock protects a spider# within the Deku Tree holding", None, 'exclude'), + 'Deku Tree MQ GS Basement Back Room': ("a #spider deep within the Deku Tree# hides", None, 'exclude'), + + 'Dodongos Cavern GS Vines Above Stairs': ("a #spider entangled in vines# in Dodongo's Cavern guards", None, 'exclude'), + 'Dodongos Cavern GS Scarecrow': ("a #spider among explosive slugs# hides", None, 'exclude'), + 'Dodongos Cavern GS Alcove Above Stairs': ("a #spider just out of reach# in Dodongo's Cavern holds", None, 'exclude'), + 'Dodongos Cavern GS Back Room': ("a #spider behind a statue# in Dodongo's Cavern holds", None, 'exclude'), + 'Dodongos Cavern GS Side Room Near Lower Lizalfos': ("a #spider among bats# in Dodongo's Cavern holds", None, 'exclude'), + + 'Dodongos Cavern MQ GS Scrub Room': ("a #spider high on a wall# in Dodongo's Cavern holds", None, 'exclude'), + 'Dodongos Cavern MQ GS Lizalfos Room': ("a #spider on top of a pillar of rock# in Dodongo's Cavern holds", None, 'exclude'), + 'Dodongos Cavern MQ GS Larvae Room': ("a #spider in a crate# in Dodongo's Cavern holds", None, 'exclude'), + 'Dodongos Cavern MQ GS Back Area': ("a #spider among graves# in Dodongo's Cavern holds", None, 'exclude'), + + 'Jabu Jabus Belly GS Lobby Basement Lower': ("a #spider resting near a princess# in Jabu Jabu's Belly holds", None, 'exclude'), + 'Jabu Jabus Belly GS Lobby Basement Upper': ("a #spider resting near a princess# in Jabu Jabu's Belly holds", None, 'exclude'), + 'Jabu Jabus Belly GS Near Boss': ("#jellyfish surround a spider# holding", None, 'exclude'), + 'Jabu Jabus Belly GS Water Switch Room': ("a #spider guarded by a school of stingers# in Jabu Jabu's Belly holds", None, 'exclude'), + + 'Jabu Jabus Belly MQ GS Tailpasaran Room': ("a #spider surrounded by electricity# in Jabu Jabu's Belly holds", None, 'exclude'), + 'Jabu Jabus Belly MQ GS Boomerang Chest Room': ("a #spider guarded by a school of stingers# in Jabu Jabu's Belly holds", None, 'exclude'), + 'Jabu Jabus Belly MQ GS Near Boss': ("a #spider in a web within Jabu Jabu's Belly# holds", None, 'exclude'), + + 'Forest Temple GS Raised Island Courtyard': ("a #spider on a small island# in the Forest Temple holds", None, 'exclude'), + 'Forest Temple GS First Room': ("a #spider high on a wall of vines# in the Forest Temple holds", None, 'exclude'), + 'Forest Temple GS Level Island Courtyard': ("#stone columns# lead to a spider in the Forest Temple hiding", None, 'exclude'), + 'Forest Temple GS Lobby': ("a #spider among ghosts# in the Forest Temple guards", None, 'exclude'), + 'Forest Temple GS Basement': ("a #spider within revolving walls# in the Forest Temple holds", None, 'exclude'), + + 'Forest Temple MQ GS First Hallway': ("an #ivy-hidden spider# in the Forest Temple hoards", None, 'exclude'), + 'Forest Temple MQ GS Block Push Room': ("a #spider in a hidden nook# within the Forest Temple holds", None, 'exclude'), + 'Forest Temple MQ GS Raised Island Courtyard': ("a #spider on an arch# in the Forest Temple holds", None, 'exclude'), + 'Forest Temple MQ GS Level Island Courtyard': ("a #spider on a ledge# in the Forest Temple holds", None, 'exclude'), + 'Forest Temple MQ GS Well': ("#draining a well# in Forest Temple uncovers a spider with", None, 'exclude'), + + 'Fire Temple GS Song of Time Room': ("#eight tiles of malice# guard a spider holding", None, 'exclude'), + 'Fire Temple GS Boss Key Loop': ("#five tiles of malice# guard a spider holding", None, 'exclude'), + 'Fire Temple GS Boulder Maze': ("#explosives in a maze# unveil a spider hiding", None, 'exclude'), + 'Fire Temple GS Scarecrow Top': ("a #spider-friendly scarecrow# atop a volcano hides", "a #spider-friendly scarecrow# atop the Fire Temple hides", 'exclude'), + 'Fire Temple GS Scarecrow Climb': ("a #spider-friendly scarecrow# atop a volcano hides", "a #spider-friendly scarecrow# atop the Fire Temple hides", 'exclude'), + + 'Fire Temple MQ GS Above Fire Wall Maze': ("a #spider above a fiery maze# holds", None, 'exclude'), + 'Fire Temple MQ GS Fire Wall Maze Center': ("a #spider within a fiery maze# holds", None, 'exclude'), + 'Fire Temple MQ GS Big Lava Room Open Door': ("a #Goron trapped near lava# befriended a spider with", None, 'exclude'), + 'Fire Temple MQ GS Fire Wall Maze Side Room': ("a #spider beside a fiery maze# holds", None, 'exclude'), + + 'Water Temple GS Falling Platform Room': ("a #spider over a waterfall# in the Water Temple holds", None, 'exclude'), + 'Water Temple GS Central Pillar': ("a #spider in the center of the Water Temple# holds", None, 'exclude'), + 'Water Temple GS Near Boss Key Chest': ("a spider protected by #rolling boulders under the lake# hides", "a spider protected by #rolling boulders in the Water Temple# hides", 'exclude'), + 'Water Temple GS River': ("a #spider over a river# in the Water Temple holds", None, 'exclude'), + + 'Water Temple MQ GS Before Upper Water Switch': ("#beyond a pit of lizards# is a spider holding", None, 'exclude'), + 'Water Temple MQ GS Lizalfos Hallway': ("#lizards guard a spider# in the Water Temple with", None, 'exclude'), + 'Water Temple MQ GS River': ("a #spider over a river# in the Water Temple holds", None, 'exclude'), + + 'Spirit Temple GS Hall After Sun Block Room': ("a spider in the #hall of a knight# guards", None, 'exclude'), + 'Spirit Temple GS Boulder Room': ("a #spider behind a temporal stone# in the Spirit Temple yields", None, 'exclude'), + 'Spirit Temple GS Lobby': ("a #spider beside a statue# holds", None, 'exclude'), + 'Spirit Temple GS Sun on Floor Room': ("a #spider at the top of a deep shaft# in the Spirit Temple holds", None, 'exclude'), + 'Spirit Temple GS Metal Fence': ("a child defeats a #spider among bats# in the Spirit Temple to gain", None, 'exclude'), + + 'Spirit Temple MQ GS Leever Room': ("#above a pit of sand# in the Spirit Temple hides", None, 'exclude'), + 'Spirit Temple MQ GS Nine Thrones Room West': ("a spider in the #hall of a knight# guards", None, 'exclude'), + 'Spirit Temple MQ GS Nine Thrones Room North': ("a spider in the #hall of a knight# guards", None, 'exclude'), + 'Spirit Temple MQ GS Sun Block Room': ("#upon a web of glass# in the Spirit Temple sits a spider holding", None, 'exclude'), + + 'Shadow Temple GS Single Giant Pot': ("#beyond a burning skull# lies a spider with", None, 'exclude'), + 'Shadow Temple GS Falling Spikes Room': ("a #spider beyond falling spikes# holds", None, 'exclude'), + 'Shadow Temple GS Triple Giant Pot': ("#beyond three burning skulls# lies a spider with", None, 'exclude'), + 'Shadow Temple GS Like Like Room': ("a spider guarded by #invisible blades# holds", None, 'exclude'), + 'Shadow Temple GS Near Ship': ("a spider near a #docked ship# hoards", None, 'exclude'), + + 'Shadow Temple MQ GS Falling Spikes Room': ("a #spider beyond falling spikes# holds", None, 'exclude'), + 'Shadow Temple MQ GS Wind Hint Room': ("a #spider amidst roaring winds# in the Shadow Temple holds", None, 'exclude'), + 'Shadow Temple MQ GS After Wind': ("a #spider beneath gruesome debris# in the Shadow Temple hides", None, 'exclude'), + 'Shadow Temple MQ GS After Ship': ("a #fallen statue# reveals a spider with", None, 'exclude'), + 'Shadow Temple MQ GS Near Boss': ("a #suspended spider# guards", None, 'exclude'), + + 'Bottom of the Well GS Like Like Cage': ("a #spider locked in a cage# in the well holds", None, 'exclude'), + 'Bottom of the Well GS East Inner Room': ("an #invisible path in the well# leads to", None, 'exclude'), + 'Bottom of the Well GS West Inner Room': ("a #spider locked in a crypt# within the well guards", None, 'exclude'), + + 'Bottom of the Well MQ GS Basement': ("a #gauntlet of invisible spiders# protects", None, 'exclude'), + 'Bottom of the Well MQ GS Coffin Room': ("a #spider crawling near the dead# in the well holds", None, 'exclude'), + 'Bottom of the Well MQ GS West Inner Room': ("a #spider locked in a crypt# within the well guards", None, 'exclude'), + + 'Ice Cavern GS Push Block Room': ("a #spider above icy pits# holds", None, 'exclude'), + 'Ice Cavern GS Spinning Scythe Room': ("#spinning ice# guards a spider holding", None, 'exclude'), + 'Ice Cavern GS Heart Piece Room': ("a #spider behind a wall of ice# hides", None, 'exclude'), + + 'Ice Cavern MQ GS Scarecrow': ("a #spider above icy pits# holds", None, 'exclude'), + 'Ice Cavern MQ GS Ice Block': ("a #web of ice# surrounds a spider with", None, 'exclude'), + 'Ice Cavern MQ GS Red Ice': ("a #spider in fiery ice# hoards", None, 'exclude'), + + 'HF GS Near Kak Grotto': ("a #spider-guarded spider in a hole# hoards", None, 'exclude'), + + 'LLR GS Back Wall': ("night reveals a #spider in a ranch# holding", None, 'exclude'), + 'LLR GS Rain Shed': ("night reveals a #spider in a ranch# holding", None, 'exclude'), + 'LLR GS House Window': ("night reveals a #spider in a ranch# holding", None, 'exclude'), + 'LLR GS Tree': ("a spider hiding in a #ranch tree# holds", None, 'exclude'), + + 'KF GS Bean Patch': ("a #spider buried in a forest# holds", None, 'exclude'), + 'KF GS Know It All House': ("night in the past reveals a #spider in a forest# holding", None, 'exclude'), + 'KF GS House of Twins': ("night in the future reveals a #spider in a forest# holding", None, 'exclude'), + + 'LW GS Bean Patch Near Bridge': ("a #spider buried deep in a forest maze# holds", None, 'exclude'), + 'LW GS Bean Patch Near Theater': ("a #spider buried deep in a forest maze# holds", None, 'exclude'), + 'LW GS Above Theater': ("night reveals a #spider deep in a forest maze# holding", None, 'exclude'), + 'SFM GS': ("night reveals a #spider in a forest meadow# holding", None, 'exclude'), + + 'OGC GS': ("a #spider outside a tyrant's tower# holds", None, 'exclude'), + 'HC GS Tree': ("a spider hiding in a #tree outside of a castle# holds", None, 'exclude'), + 'Market GS Guard House': ("a #spider in a guarded crate# holds", None, 'exclude'), + + 'DMC GS Bean Patch': ("a #spider buried in a volcano# holds", None, 'exclude'), + + 'DMT GS Bean Patch': ("a #spider buried outside a cavern# holds", None, 'exclude'), + 'DMT GS Near Kak': ("a #spider hidden in a mountain nook# holds", None, 'exclude'), + 'DMT GS Above Dodongos Cavern': ("the hammer reveals a #spider on a mountain# holding", None, 'exclude'), + 'DMT GS Falling Rocks Path': ("the hammer reveals a #spider on a mountain# holding", None, 'exclude'), + + 'GC GS Center Platform': ("a #suspended spider# in Goron City holds", None, 'exclude'), + 'GC GS Boulder Maze': ("a spider in a #Goron City crate# holds", None, 'exclude'), + + 'Kak GS House Under Construction': ("night in the past reveals a #spider in a town# holding", None, 'exclude'), + 'Kak GS Skulltula House': ("night in the past reveals a #spider in a town# holding", None, 'exclude'), + 'Kak GS Guards House': ("night in the past reveals a #spider in a town# holding", None, 'exclude'), + 'Kak GS Tree': ("night in the past reveals a #spider in a town# holding", None, 'exclude'), + 'Kak GS Watchtower': ("night in the past reveals a #spider in a town# holding", None, 'exclude'), + 'Kak GS Above Impas House': ("night in the future reveals a #spider in a town# holding", None, 'exclude'), + + 'Graveyard GS Wall': ("night reveals a #spider in a graveyard# holding", None, 'exclude'), + 'Graveyard GS Bean Patch': ("a #spider buried in a graveyard# holds", None, 'exclude'), + + 'ZR GS Ladder': ("night in the past reveals a #spider in a river# holding", None, 'exclude'), + 'ZR GS Tree': ("a spider hiding in a #tree by a river# holds", None, 'exclude'), + 'ZR GS Above Bridge': ("night in the future reveals a #spider in a river# holding", None, 'exclude'), + 'ZR GS Near Raised Grottos': ("night in the future reveals a #spider in a river# holding", None, 'exclude'), + + 'ZD GS Frozen Waterfall': ("night reveals a #spider by a frozen waterfall# holding", None, 'exclude'), + 'ZF GS Above the Log': ("night reveals a #spider near a deity# holding", None, 'exclude'), + 'ZF GS Tree': ("a spider hiding in a #tree near a deity# holds", None, 'exclude'), + + 'LH GS Bean Patch': ("a #spider buried by a lake# holds", None, 'exclude'), + 'LH GS Small Island': ("night reveals a #spider by a lake# holding", None, 'exclude'), + 'LH GS Lab Wall': ("night reveals a #spider by a lake# holding", None, 'exclude'), + 'LH GS Lab Crate': ("a spider deed underwater in a #lab crate# holds", None, 'exclude'), + 'LH GS Tree': ("night reveals a #spider by a lake high in a tree# holding", None, 'exclude'), + + 'GV GS Bean Patch': ("a #spider buried in a valley# holds", None, 'exclude'), + 'GV GS Small Bridge': ("night in the past reveals a #spider in a valley# holding", None, 'exclude'), + 'GV GS Pillar': ("night in the future reveals a #spider in a valley# holding", None, 'exclude'), + 'GV GS Behind Tent': ("night in the future reveals a #spider in a valley# holding", None, 'exclude'), + + 'GF GS Archery Range': ("night reveals a #spider in a fortress# holding", None, 'exclude'), + 'GF GS Top Floor': ("night reveals a #spider in a fortress# holding", None, 'exclude'), + + 'Colossus GS Bean Patch': ("a #spider buried in the desert# holds", None, 'exclude'), + 'Colossus GS Hill': ("night reveals a #spider deep in the desert# holding", None, 'exclude'), + 'Colossus GS Tree': ("night reveals a #spider deep in the desert# holding", None, 'exclude'), + + 'KF Shop Item 1': ("a #child shopkeeper# sells", None, 'exclude'), + 'KF Shop Item 2': ("a #child shopkeeper# sells", None, 'exclude'), + 'KF Shop Item 3': ("a #child shopkeeper# sells", None, 'exclude'), + 'KF Shop Item 4': ("a #child shopkeeper# sells", None, 'exclude'), + 'KF Shop Item 5': ("a #child shopkeeper# sells", None, 'exclude'), + 'KF Shop Item 6': ("a #child shopkeeper# sells", None, 'exclude'), + 'KF Shop Item 7': ("a #child shopkeeper# sells", None, 'exclude'), + 'KF Shop Item 8': ("a #child shopkeeper# sells", None, 'exclude'), + + 'Kak Potion Shop Item 1': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + 'Kak Potion Shop Item 2': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + 'Kak Potion Shop Item 3': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + 'Kak Potion Shop Item 4': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + 'Kak Potion Shop Item 5': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + 'Kak Potion Shop Item 6': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + 'Kak Potion Shop Item 7': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + 'Kak Potion Shop Item 8': ("a #potion seller# offers", "the #Kakariko Potion Shop# offers", 'exclude'), + + 'Market Bombchu Shop Item 1': ("a #Bombchu merchant# sells", None, 'exclude'), + 'Market Bombchu Shop Item 2': ("a #Bombchu merchant# sells", None, 'exclude'), + 'Market Bombchu Shop Item 3': ("a #Bombchu merchant# sells", None, 'exclude'), + 'Market Bombchu Shop Item 4': ("a #Bombchu merchant# sells", None, 'exclude'), + 'Market Bombchu Shop Item 5': ("a #Bombchu merchant# sells", None, 'exclude'), + 'Market Bombchu Shop Item 6': ("a #Bombchu merchant# sells", None, 'exclude'), + 'Market Bombchu Shop Item 7': ("a #Bombchu merchant# sells", None, 'exclude'), + 'Market Bombchu Shop Item 8': ("a #Bombchu merchant# sells", None, 'exclude'), + + 'Market Potion Shop Item 1': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + 'Market Potion Shop Item 2': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + 'Market Potion Shop Item 3': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + 'Market Potion Shop Item 4': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + 'Market Potion Shop Item 5': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + 'Market Potion Shop Item 6': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + 'Market Potion Shop Item 7': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + 'Market Potion Shop Item 8': ("a #potion seller# offers", "the #Market Potion Shop# offers", 'exclude'), + + 'Market Bazaar Item 1': ("the #Market Bazaar# offers", None, 'exclude'), + 'Market Bazaar Item 2': ("the #Market Bazaar# offers", None, 'exclude'), + 'Market Bazaar Item 3': ("the #Market Bazaar# offers", None, 'exclude'), + 'Market Bazaar Item 4': ("the #Market Bazaar# offers", None, 'exclude'), + 'Market Bazaar Item 5': ("the #Market Bazaar# offers", None, 'exclude'), + 'Market Bazaar Item 6': ("the #Market Bazaar# offers", None, 'exclude'), + 'Market Bazaar Item 7': ("the #Market Bazaar# offers", None, 'exclude'), + 'Market Bazaar Item 8': ("the #Market Bazaar# offers", None, 'exclude'), + + 'Kak Bazaar Item 1': ("the #Kakariko Bazaar# offers", None, 'exclude'), + 'Kak Bazaar Item 2': ("the #Kakariko Bazaar# offers", None, 'exclude'), + 'Kak Bazaar Item 3': ("the #Kakariko Bazaar# offers", None, 'exclude'), + 'Kak Bazaar Item 4': ("the #Kakariko Bazaar# offers", None, 'exclude'), + 'Kak Bazaar Item 5': ("the #Kakariko Bazaar# offers", None, 'exclude'), + 'Kak Bazaar Item 6': ("the #Kakariko Bazaar# offers", None, 'exclude'), + 'Kak Bazaar Item 7': ("the #Kakariko Bazaar# offers", None, 'exclude'), + 'Kak Bazaar Item 8': ("the #Kakariko Bazaar# offers", None, 'exclude'), + + 'ZD Shop Item 1': ("a #Zora shopkeeper# sells", None, 'exclude'), + 'ZD Shop Item 2': ("a #Zora shopkeeper# sells", None, 'exclude'), + 'ZD Shop Item 3': ("a #Zora shopkeeper# sells", None, 'exclude'), + 'ZD Shop Item 4': ("a #Zora shopkeeper# sells", None, 'exclude'), + 'ZD Shop Item 5': ("a #Zora shopkeeper# sells", None, 'exclude'), + 'ZD Shop Item 6': ("a #Zora shopkeeper# sells", None, 'exclude'), + 'ZD Shop Item 7': ("a #Zora shopkeeper# sells", None, 'exclude'), + 'ZD Shop Item 8': ("a #Zora shopkeeper# sells", None, 'exclude'), + + 'GC Shop Item 1': ("a #Goron shopkeeper# sells", None, 'exclude'), + 'GC Shop Item 2': ("a #Goron shopkeeper# sells", None, 'exclude'), + 'GC Shop Item 3': ("a #Goron shopkeeper# sells", None, 'exclude'), + 'GC Shop Item 4': ("a #Goron shopkeeper# sells", None, 'exclude'), + 'GC Shop Item 5': ("a #Goron shopkeeper# sells", None, 'exclude'), + 'GC Shop Item 6': ("a #Goron shopkeeper# sells", None, 'exclude'), + 'GC Shop Item 7': ("a #Goron shopkeeper# sells", None, 'exclude'), + 'GC Shop Item 8': ("a #Goron shopkeeper# sells", None, 'exclude'), + + 'Deku Tree MQ Deku Scrub': ("a #scrub in the Deku Tree# sells", None, 'exclude'), + + 'HF Deku Scrub Grotto': ("a lonely #scrub in a hole# sells", None, 'exclude'), + 'LLR Deku Scrub Grotto Left': ("a #trio of scrubs# sells", None, 'exclude'), + 'LLR Deku Scrub Grotto Right': ("a #trio of scrubs# sells", None, 'exclude'), + 'LLR Deku Scrub Grotto Center': ("a #trio of scrubs# sells", None, 'exclude'), + + 'LW Deku Scrub Near Deku Theater Right': ("a pair of #scrubs in the woods# sells", None, 'exclude'), + 'LW Deku Scrub Near Deku Theater Left': ("a pair of #scrubs in the woods# sells", None, 'exclude'), + 'LW Deku Scrub Near Bridge': ("a #scrub by a bridge# sells", None, 'exclude'), + 'LW Deku Scrub Grotto Rear': ("a #scrub underground duo# sells", None, 'exclude'), + 'LW Deku Scrub Grotto Front': ("a #scrub underground duo# sells", None, 'exclude'), + + 'SFM Deku Scrub Grotto Rear': ("a #scrub underground duo# sells", None, 'exclude'), + 'SFM Deku Scrub Grotto Front': ("a #scrub underground duo# sells", None, 'exclude'), + + 'GC Deku Scrub Grotto Left': ("a #trio of scrubs# sells", None, 'exclude'), + 'GC Deku Scrub Grotto Right': ("a #trio of scrubs# sells", None, 'exclude'), + 'GC Deku Scrub Grotto Center': ("a #trio of scrubs# sells", None, 'exclude'), + + 'Dodongos Cavern Deku Scrub Near Bomb Bag Left': ("a pair of #scrubs in Dodongo's Cavern# sells", None, 'exclude'), + 'Dodongos Cavern Deku Scrub Side Room Near Dodongos': ("a #scrub guarded by Lizalfos# sells", None, 'exclude'), + 'Dodongos Cavern Deku Scrub Near Bomb Bag Right': ("a pair of #scrubs in Dodongo's Cavern# sells", None, 'exclude'), + 'Dodongos Cavern Deku Scrub Lobby': ("a #scrub in Dodongo's Cavern# sells", None, 'exclude'), + + 'Dodongos Cavern MQ Deku Scrub Lobby Rear': ("a pair of #scrubs in Dodongo's Cavern# sells", None, 'exclude'), + 'Dodongos Cavern MQ Deku Scrub Lobby Front': ("a pair of #scrubs in Dodongo's Cavern# sells", None, 'exclude'), + 'Dodongos Cavern MQ Deku Scrub Staircase': ("a #scrub in Dodongo's Cavern# sells", None, 'exclude'), + 'Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos': ("a #scrub guarded by Lizalfos# sells", None, 'exclude'), + + 'DMC Deku Scrub Grotto Left': ("a #trio of scrubs# sells", None, 'exclude'), + 'DMC Deku Scrub Grotto Right': ("a #trio of scrubs# sells", None, 'exclude'), + 'DMC Deku Scrub Grotto Center': ("a #trio of scrubs# sells", None, 'exclude'), + + 'ZR Deku Scrub Grotto Rear': ("a #scrub underground duo# sells", None, 'exclude'), + 'ZR Deku Scrub Grotto Front': ("a #scrub underground duo# sells", None, 'exclude'), + + 'Jabu Jabus Belly Deku Scrub': ("a #scrub in a deity# sells", None, 'exclude'), + + 'LH Deku Scrub Grotto Left': ("a #trio of scrubs# sells", None, 'exclude'), + 'LH Deku Scrub Grotto Right': ("a #trio of scrubs# sells", None, 'exclude'), + 'LH Deku Scrub Grotto Center': ("a #trio of scrubs# sells", None, 'exclude'), + + 'GV Deku Scrub Grotto Rear': ("a #scrub underground duo# sells", None, 'exclude'), + 'GV Deku Scrub Grotto Front': ("a #scrub underground duo# sells", None, 'exclude'), + + 'Colossus Deku Scrub Grotto Front': ("a #scrub underground duo# sells", None, 'exclude'), + 'Colossus Deku Scrub Grotto Rear': ("a #scrub underground duo# sells", None, 'exclude'), + + 'Ganons Castle Deku Scrub Center-Left': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + 'Ganons Castle Deku Scrub Center-Right': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + 'Ganons Castle Deku Scrub Right': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + 'Ganons Castle Deku Scrub Left': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + + 'Ganons Castle MQ Deku Scrub Right': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + 'Ganons Castle MQ Deku Scrub Center-Left': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + 'Ganons Castle MQ Deku Scrub Center': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + 'Ganons Castle MQ Deku Scrub Center-Right': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + 'Ganons Castle MQ Deku Scrub Left': ("#scrubs in Ganon's Castle# sell", None, 'exclude'), + + 'LLR Stables Left Cow': ("a #cow in a stable# gifts", None, 'exclude'), + 'LLR Stables Right Cow': ("a #cow in a stable# gifts", None, 'exclude'), + 'LLR Tower Right Cow': ("a #cow in a ranch silo# gifts", None, 'exclude'), + 'LLR Tower Left Cow': ("a #cow in a ranch silo# gifts", None, 'exclude'), + 'Kak Impas House Cow': ("a #cow imprisoned in a house# protects", None, 'exclude'), + 'DMT Cow Grotto Cow': ("a #cow in a luxurious hole# offers", None, 'exclude'), + + 'Desert Colossus -> Colossus Grotto': ("lifting a #rock in the desert# reveals", None, 'entrance'), + 'GV Grotto Ledge -> GV Octorok Grotto': ("a rock on #a ledge in the valley# hides", None, 'entrance'), + 'GC Grotto Platform -> GC Grotto': ("a #pool of lava# in Goron City blocks the way to", None, 'entrance'), + 'Gerudo Fortress -> GF Storms Grotto': ("a #storm within Gerudo's Fortress# reveals", None, 'entrance'), + 'Zoras Domain -> ZD Storms Grotto': ("a #storm within Zora's Domain# reveals", None, 'entrance'), + 'Hyrule Castle Grounds -> HC Storms Grotto': ("a #storm near the castle# reveals", None, 'entrance'), + 'GV Fortress Side -> GV Storms Grotto': ("a #storm in the valley# reveals", None, 'entrance'), + 'Desert Colossus -> Colossus Great Fairy Fountain': ("a #fractured desert wall# hides", None, 'entrance'), + 'Ganons Castle Grounds -> OGC Great Fairy Fountain': ("a #heavy pillar# outside the castle obstructs", None, 'entrance'), + 'Zoras Fountain -> ZF Great Fairy Fountain': ("a #fountain wall# hides", None, 'entrance'), + 'GV Fortress Side -> GV Carpenter Tent': ("a #tent in the valley# covers", None, 'entrance'), + 'Graveyard Warp Pad Region -> Shadow Temple Entryway': ("at the #back of the Graveyard#, there is", None, 'entrance'), + 'Lake Hylia -> Water Temple Lobby': ("deep #under a vast lake#, one can find", None, 'entrance'), + 'Gerudo Fortress -> Gerudo Training Grounds Lobby': ("paying a #fee to the Gerudos# grants access to", None, 'entrance'), + 'Zoras Fountain -> Jabu Jabus Belly Beginning': ("inside #Jabu Jabu#, one can find", None, 'entrance'), + 'Kakariko Village -> Bottom of the Well': ("a #village well# leads to", None, 'entrance'), + + 'KF Links House': ("Link's House", None, 'region'), + 'Temple of Time': ("the #Temple of Time#", None, 'region'), + 'KF Midos House': ("Mido's house", None, 'region'), + 'KF Sarias House': ("Saria's House", None, 'region'), + 'KF House of Twins': ("the #House of Twins#", None, 'region'), + 'KF Know It All House': ("Know-It-All Brothers' House", None, 'region'), + 'KF Kokiri Shop': ("the #Kokiri Shop#", None, 'region'), + 'LH Lab': ("the #Lakeside Laboratory#", None, 'region'), + 'LH Fishing Hole': ("the #Fishing Pond#", None, 'region'), + 'GV Carpenter Tent': ("the #Carpenters' tent#", None, 'region'), + 'Market Guard House': ("the #Guard House#", None, 'region'), + 'Market Mask Shop': ("the #Happy Mask Shop#", None, 'region'), + 'Market Bombchu Bowling': ("the #Bombchu Bowling Alley#", None, 'region'), + 'Market Potion Shop': ("the #Market Potion Shop#", None, 'region'), + 'Market Treasure Chest Game': ("the #Treasure Box Shop#", None, 'region'), + 'Market Bombchu Shop': ("the #Bombchu Shop#", None, 'region'), + 'Market Man in Green House': ("Man in Green's House", None, 'region'), + 'Kak Windmill': ("the #Windmill#", None, 'region'), + 'Kak Carpenter Boss House': ("the #Carpenters' Boss House#", None, 'region'), + 'Kak House of Skulltula': ("the #House of Skulltula#", None, 'region'), + 'Kak Impas House': ("Impa's House", None, 'region'), + 'Kak Impas House Back': ("Impa's cow cage", None, 'region'), + 'Kak Odd Medicine Building': ("Granny's Potion Shop", None, 'region'), + 'Graveyard Dampes House': ("Dampé's Hut", None, 'region'), + 'GC Shop': ("the #Goron Shop#", None, 'region'), + 'ZD Shop': ("the #Zora Shop#", None, 'region'), + 'LLR Talons House': ("Talon's House", None, 'region'), + 'LLR Stables': ("a #stable#", None, 'region'), + 'LLR Tower': ("the #Lon Lon Tower#", None, 'region'), + 'Market Bazaar': ("the #Market Bazaar#", None, 'region'), + 'Market Shooting Gallery': ("a #Slingshot Shooting Gallery#", None, 'region'), + 'Kak Bazaar': ("the #Kakariko Bazaar#", None, 'region'), + 'Kak Potion Shop Front': ("the #Kakariko Potion Shop#", None, 'region'), + 'Kak Potion Shop Back': ("the #Kakariko Potion Shop#", None, 'region'), + 'Kak Shooting Gallery': ("a #Bow Shooting Gallery#", None, 'region'), + 'Colossus Great Fairy Fountain': ("a #Great Fairy Fountain#", None, 'region'), + 'HC Great Fairy Fountain': ("a #Great Fairy Fountain#", None, 'region'), + 'OGC Great Fairy Fountain': ("a #Great Fairy Fountain#", None, 'region'), + 'DMC Great Fairy Fountain': ("a #Great Fairy Fountain#", None, 'region'), + 'DMT Great Fairy Fountain': ("a #Great Fairy Fountain#", None, 'region'), + 'ZF Great Fairy Fountain': ("a #Great Fairy Fountain#", None, 'region'), + 'Graveyard Shield Grave': ("a #grave with a free chest#", None, 'region'), + 'Graveyard Heart Piece Grave': ("a chest spawned by #Sun's Song#", None, 'region'), + 'Graveyard Composers Grave': ("the #Composers' Grave#", None, 'region'), + 'Graveyard Dampes Grave': ("Dampé's Grave", None, 'region'), + 'DMT Cow Grotto': ("a solitary #Cow#", None, 'region'), + 'HC Storms Grotto': ("a sandy grotto with #fragile walls#", None, 'region'), + 'HF Tektite Grotto': ("a pool guarded by a #Tektite#", None, 'region'), + 'HF Near Kak Grotto': ("a #Big Skulltula# guarding a Gold one", None, 'region'), + 'HF Cow Grotto': ("a grotto full of #spider webs#", None, 'region'), + 'Kak Redead Grotto': ("#ReDeads# guarding a chest", None, 'region'), + 'SFM Wolfos Grotto': ("#Wolfos# guarding a chest", None, 'region'), + 'GV Octorok Grotto': ("an #Octorok# guarding a rich pool", None, 'region'), + 'Deku Theater': ("the #Lost Woods Stage#", None, 'region'), + 'ZR Open Grotto': ("a #generic grotto#", None, 'region'), + 'DMC Upper Grotto': ("a #generic grotto#", None, 'region'), + 'DMT Storms Grotto': ("a #generic grotto#", None, 'region'), + 'Kak Open Grotto': ("a #generic grotto#", None, 'region'), + 'HF Near Market Grotto': ("a #generic grotto#", None, 'region'), + 'HF Open Grotto': ("a #generic grotto#", None, 'region'), + 'HF Southeast Grotto': ("a #generic grotto#", None, 'region'), + 'KF Storms Grotto': ("a #generic grotto#", None, 'region'), + 'LW Near Shortcuts Grotto': ("a #generic grotto#", None, 'region'), + 'HF Inside Fence Grotto': ("a #single Upgrade Deku Scrub#", None, 'region'), + 'LW Scrubs Grotto': ("#2 Deku Scrubs# including an Upgrade one", None, 'region'), + 'Colossus Grotto': ("2 Deku Scrubs", None, 'region'), + 'ZR Storms Grotto': ("2 Deku Scrubs", None, 'region'), + 'SFM Storms Grotto': ("2 Deku Scrubs", None, 'region'), + 'GV Storms Grotto': ("2 Deku Scrubs", None, 'region'), + 'LH Grotto': ("3 Deku Scrubs", None, 'region'), + 'DMC Hammer Grotto': ("3 Deku Scrubs", None, 'region'), + 'GC Grotto': ("3 Deku Scrubs", None, 'region'), + 'LLR Grotto': ("3 Deku Scrubs", None, 'region'), + 'ZR Fairy Grotto': ("a small #Fairy Fountain#", None, 'region'), + 'HF Fairy Grotto': ("a small #Fairy Fountain#", None, 'region'), + 'SFM Fairy Grotto': ("a small #Fairy Fountain#", None, 'region'), + 'ZD Storms Grotto': ("a small #Fairy Fountain#", None, 'region'), + 'GF Storms Grotto': ("a small #Fairy Fountain#", None, 'region'), + + '1001': ("Ganondorf 2022!", None, 'junk'), + '1002': ("They say that monarchy is a terrible system of governance.", None, 'junk'), + '1003': ("They say that Zelda is a poor leader.", None, 'junk'), + '1004': ("These hints can be quite useful. This is an exception.", None, 'junk'), + '1006': ("They say that all the Zora drowned in Wind Waker.", None, 'junk'), + '1008': ("'Member when Ganon was a blue pig?^I 'member.", None, 'junk'), + '1009': ("One who does not have Triforce can't go in.", None, 'junk'), + '1010': ("Save your future, end the Happy Mask Salesman.", None, 'junk'), + '1012': ("I'm stoned. Get it?", None, 'junk'), + '1013': ("Hoot! Hoot! Would you like me to repeat that?", None, 'junk'), + '1014': ("Gorons are stupid. They eat rocks.", None, 'junk'), + '1015': ("They say that Lon Lon Ranch prospered under Ingo.", None, 'junk'), + '1016': ("The single rupee is a unique item.", None, 'junk'), + '1017': ("Without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!", None, 'junk'), + '1018': ("Use bombs wisely.", None, 'junk'), + '1021': ("I found you, faker!", None, 'junk'), + '1022': ("You're comparing yourself to me?^Ha! You're not even good enough to be my fake.", None, 'junk'), + '1023': ("I'll make you eat those words.", None, 'junk'), + '1024': ("What happened to Sheik?", None, 'junk'), + '1025': ("L2P @.", None, 'junk'), + '1026': ("I've heard Sploosh Kaboom is a tricky game.", None, 'junk'), + '1027': ("I'm Lonk from Pennsylvania.", None, 'junk'), + '1028': ("I bet you'd like to have more bombs.", None, 'junk'), + '1029': ("When all else fails, use Fire.", None, 'junk'), + '1030': ("Here's a hint, @. Don't be bad.", None, 'junk'), + '1031': ("Game Over. Return of Ganon.", None, 'junk'), + '1032': ("May the way of the Hero lead to the Triforce.", None, 'junk'), + '1033': ("Can't find an item? Scan an Amiibo.", None, 'junk'), + '1034': ("They say this game has just a few glitches.", None, 'junk'), + '1035': ("BRRING BRRING This is Ulrira. Wrong number?", None, 'junk'), + '1036': ("Tingle Tingle Kooloo Limpah", None, 'junk'), + '1037': ("L is real 2041", None, 'junk'), + '1038': ("They say that Ganondorf will appear in the next Mario Tennis.", None, 'junk'), + '1039': ("Medigoron sells the earliest Breath of the Wild demo.", None, 'junk'), + '1040': ("There's a reason why I am special inquisitor!", None, 'junk'), + '1041': ("You were almost a @ sandwich.", None, 'junk'), + '1042': ("I'm a helpful hint Gossip Stone!^See, I'm helping.", None, 'junk'), + '1043': ("Dear @, please come to the castle. I've baked a cake for you.&Yours truly, princess Zelda.", None, 'junk'), + '1044': ("They say all toasters toast toast.", None, 'junk'), + '1045': ("They say that Okami is the best Zelda game.", None, 'junk'), + '1046': ("They say that quest guidance can be found at a talking rock.", None, 'junk'), + '1047': ("They say that the final item you're looking for can be found somewhere in Hyrule.", None, 'junk'), + '1048': ("Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.", None, 'junk'), + '1049': ("They say that Barinade fears Deku Nuts.", None, 'junk'), + '1050': ("They say that Flare Dancers do not fear Goron-crafted blades.", None, 'junk'), + '1051': ("They say that Morpha is easily trapped in a corner.", None, 'junk'), + '1052': ("They say that Bongo Bongo really hates the cold.", None, 'junk'), + '1053': ("They say that crouch stabs mimic the effects of your last attack.", None, 'junk'), + '1054': ("They say that bombing the hole Volvagia last flew into can be rewarding.", None, 'junk'), + '1055': ("They say that invisible ghosts can be exposed with Deku Nuts.", None, 'junk'), + '1056': ("They say that the real Phantom Ganon is bright and loud.", None, 'junk'), + '1057': ("They say that walking backwards is very fast.", None, 'junk'), + '1058': ("They say that leaping above the Market entrance enriches most children.", None, 'junk'), + '1059': ("They say that looking into darkness may find darkness looking back into you.", None, 'junk'), + '1060': ("You found a spiritual Stone! By which I mean, I worship Nayru.", None, 'junk'), + '1061': ("They say that the stick is mightier than the sword.", None, 'junk'), + '1062': ("Open your eyes.^Open your eyes.^Wake up, @.", None, 'junk'), + '1063': ("They say that arbitrary code execution leads to the credits sequence.", None, 'junk'), + '1064': ("They say that Twinrova always casts the same spell the first three times.", None, 'junk'), + '1065': ("They say that the Development branch may be unstable.", None, 'junk'), + '1066': ("You're playing a Randomizer. I'm randomized!^Here's a random number: #4#.&Enjoy your Randomizer!", None, 'junk'), + '1067': ("They say Ganondorf's bolts can be reflected with glass or steel.", None, 'junk'), + '1068': ("They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, boomerangs...^...rods, shovels, iron balls, angry bees...", None, 'junk'), + '1069': ("They say that you're wasting time reading this hint, but I disagree. Talk to me again!", None, 'junk'), + '1070': ("They say Ganondorf knows where to find the instrument of his doom.", None, 'junk'), + '1071': ("I heard @ is pretty good at Zelda.", None, 'junk'), + + 'Deku Tree': ("an ancient tree", "Deku Tree", 'dungeonName'), + 'Dodongos Cavern': ("an immense cavern", "Dodongo's Cavern", 'dungeonName'), + 'Jabu Jabus Belly': ("the belly of a deity", "Jabu Jabu's Belly", 'dungeonName'), + 'Forest Temple': ("a deep forest", "Forest Temple", 'dungeonName'), + 'Fire Temple': ("a high mountain", "Fire Temple", 'dungeonName'), + 'Water Temple': ("a vast lake", "Water Temple", 'dungeonName'), + 'Shadow Temple': ("the house of the dead", "Shadow Temple", 'dungeonName'), + 'Spirit Temple': ("the goddess of the sand", "Spirit Temple", 'dungeonName'), + 'Ice Cavern': ("a frozen maze", "Ice Cavern", 'dungeonName'), + 'Bottom of the Well': ("a shadow\'s prison", "Bottom of the Well", 'dungeonName'), + 'Gerudo Training Grounds': ("the test of thieves", "Gerudo Training Grounds", 'dungeonName'), + 'Ganons Castle': ("a conquered citadel", "Inside Ganon's Castle", 'dungeonName'), + + 'Queen Gohma': ("One inside an #ancient tree#...", "One in the #Deku Tree#...", 'boss'), + 'King Dodongo': ("One within an #immense cavern#...", "One in #Dodongo's Cavern#...", 'boss'), + 'Barinade': ("One in the #belly of a deity#...", "One in #Jabu Jabu's Belly#...", 'boss'), + 'Phantom Ganon': ("One in a #deep forest#...", "One in the #Forest Temple#...", 'boss'), + 'Volvagia': ("One on a #high mountain#...", "One in the #Fire Temple#...", 'boss'), + 'Morpha': ("One under a #vast lake#...", "One in the #Water Temple#...", 'boss'), + 'Bongo Bongo': ("One within the #house of the dead#...", "One in the #Shadow Temple#...", 'boss'), + 'Twinrova': ("One inside a #goddess of the sand#...", "One in the #Spirit Temple#...", 'boss'), + 'Links Pocket': ("One in #@'s pocket#...", "One #@ already has#...", 'boss'), + + 'bridge_vanilla': ("the #Shadow and Spirit Medallions# as well as the #Light Arrows#", None, 'bridge'), + 'bridge_stones': ("Spiritual Stones", None, 'bridge'), + 'bridge_medallions': ("Medallions", None, 'bridge'), + 'bridge_dungeons': ("Spiritual Stones and Medallions", None, 'bridge'), + 'bridge_tokens': ("Gold Skulltula Tokens", None, 'bridge'), + + 'ganonBK_dungeon': ("hidden somewhere #inside its castle#", None, 'ganonBossKey'), + 'ganonBK_vanilla': ("kept in a big chest #inside its tower#", None, 'ganonBossKey'), + 'ganonBK_overworld': ("hidden #outside of dungeons# in Hyrule", None, 'ganonBossKey'), + 'ganonBK_any_dungeon': ("hidden #inside a dungeon# in Hyrule", None, 'ganonBossKey'), + 'ganonBK_keysanity': ("hidden somewhere #in Hyrule#", None, 'ganonBossKey'), + 'ganonBK_triforce': ("given to the Hero once the #Triforce# is completed", None, 'ganonBossKey'), + + 'lacs_vanilla': ("the #Shadow and Spirit Medallions#", None, 'lacs'), + 'lacs_medallions': ("Medallions", None, 'lacs'), + 'lacs_stones': ("Spiritual Stones", None, 'lacs'), + 'lacs_dungeons': ("Spiritual Stones and Medallions", None, 'lacs'), + 'lacs_tokens': ("Gold Skulltula Tokens", None, 'lacs'), + + 'Spiritual Stone Text Start': ("3 Spiritual Stones found in Hyrule...", None, 'altar'), + 'Child Altar Text End': ("\x13\x07Ye who may become a Hero...&Stand with the Ocarina and&play the Song of Time.", None, 'altar'), + 'Adult Altar Text Start': ("When evil rules all, an awakening&voice from the Sacred Realm will&call those destined to be Sages,&who dwell in the \x05\x41five temples\x05\x40.", None, 'altar'), + 'Adult Altar Text End': ("Together with the Hero of Time,&the awakened ones will bind the&evil and return the light of peace&to the world...", None, 'altar'), + + 'Validation Line': ("Hmph... Since you made it this far,&I'll let you know what glorious&prize of Ganon's you likely&missed out on in my tower.^Behold...^", None, 'validation line'), + 'Light Arrow Location': ("Ha ha ha... You'll never beat me by&reflecting my lightning bolts&and unleashing the arrows from&", None, 'Light Arrow Location'), + '2001': ("Oh! It's @.&I was expecting someone called&Sheik. Do you know what&happened to them?", None, 'ganonLine'), + '2002': ("I knew I shouldn't have put the key&on the other side of my door.", None, 'ganonLine'), + '2003': ("Looks like it's time for a&round of tennis.", None, 'ganonLine'), + '2004': ("You'll never deflect my bolts of&energy with your sword,&then shoot me with those Light&Arrows you happen to have.", None, 'ganonLine'), + '2005': ("Why did I leave my trident&back in the desert?", None, 'ganonLine'), + '2006': ("Zelda is probably going to do&something stupid, like send you&back to your own timeline.^So this is quite meaningless.&Do you really want&to save this moron?", None, 'ganonLine'), + '2007': ("What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats.", None, 'ganonLine'), + '2008': ("I've learned this spell,&it's really neat,&I'll keep it later&for your treat!", None, 'ganonLine'), + '2009': ("Many tricks are up my sleeve,&to save yourself&you'd better leave!", None, 'ganonLine'), + '2010': ("After what you did to&Koholint Island, how can&you call me the bad guy?", None, 'ganonLine'), + '2011': ("Today, let's begin down&'The Hero is Defeated' timeline.", None, 'ganonLine'), +} + + +# This specifies which hints will never appear due to either having known or known useless contents or due to the locations not existing. +def hintExclusions(world, clear_cache=False): + if not clear_cache and world.hint_exclusions is not None: + return world.hint_exclusions + + world.hint_exclusions = [] + + for location in world.get_locations(): + if location.locked or location.excluded: + world.hint_exclusions.append(location.name) + + world_location_names = [ + location.name for location in world.get_locations()] + + location_hints = [] + for name in hintTable: + hint = getHint(name, world.clearer_hints) + if any(item in hint.type for item in + ['always', + 'sometimes', + 'overworld', + 'dungeon', + 'song']): + location_hints.append(hint) + + for hint in location_hints: + if hint.name not in world_location_names and hint.name not in world.hint_exclusions: + world.hint_exclusions.append(hint.name) + + return world.hint_exclusions + +def nameIsLocation(name, hint_type, world): + if isinstance(hint_type, (list, tuple)): + for htype in hint_type: + if htype in ['sometimes', 'song', 'overworld', 'dungeon', 'always'] and name not in hintExclusions(world): + return True + elif hint_type in ['sometimes', 'song', 'overworld', 'dungeon', 'always'] and name not in hintExclusions(world): + return True + return False + +hintExclusions.exclusions = None diff --git a/worlds/oot/Hints.py b/worlds/oot/Hints.py new file mode 100644 index 00000000..f7af1d12 --- /dev/null +++ b/worlds/oot/Hints.py @@ -0,0 +1,1070 @@ +import io +import hashlib +import logging +import os +import struct +import random +from collections import OrderedDict +import urllib.request +from urllib.error import URLError, HTTPError +import json +from enum import Enum + +from .HintList import getHint, getHintGroup, Hint, hintExclusions +from .Messages import update_message_by_id +from .TextBox import line_wrap +from .Utils import data_path, read_json + + +bingoBottlesForHints = ( + "Bottle", "Bottle with Red Potion","Bottle with Green Potion", "Bottle with Blue Potion", + "Bottle with Fairy", "Bottle with Fish", "Bottle with Blue Fire", "Bottle with Bugs", + "Bottle with Big Poe", "Bottle with Poe", +) + +defaultHintDists = [ + 'balanced.json', 'bingo.json', 'ddr.json', 'scrubs.json', 'strong.json', 'tournament.json', 'useless.json', 'very_strong.json' +] + +class RegionRestriction(Enum): + NONE = 0, + DUNGEON = 1, + OVERWORLD = 2, + + +class GossipStone(): + def __init__(self, name, location): + self.name = name + self.location = location + self.reachable = True + + +class GossipText(): + def __init__(self, text, colors=None, prefix="They say that "): + text = prefix + text + text = text[:1].upper() + text[1:] + self.text = text + self.colors = colors + + + def to_json(self): + return {'text': self.text, 'colors': self.colors} + + + def __str__(self): + return get_raw_text(line_wrap(colorText(self))) + +# Abbreviations +# DMC Death Mountain Crater +# DMT Death Mountain Trail +# GC Goron City +# GV Gerudo Valley +# HC Hyrule Castle +# HF Hyrule Field +# KF Kokiri Forest +# LH Lake Hylia +# LW Lost Woods +# SFM Sacred Forest Meadow +# ToT Temple of Time +# ZD Zora's Domain +# ZF Zora's Fountain +# ZR Zora's River + +gossipLocations = { + 0x0405: GossipStone('DMC (Bombable Wall)', 'DMC Gossip Stone'), + 0x0404: GossipStone('DMT (Biggoron)', 'DMT Gossip Stone'), + 0x041A: GossipStone('Colossus (Spirit Temple)', 'Colossus Gossip Stone'), + 0x0414: GossipStone('Dodongos Cavern (Bombable Wall)', 'Dodongos Cavern Gossip Stone'), + 0x0411: GossipStone('GV (Waterfall)', 'GV Gossip Stone'), + 0x0415: GossipStone('GC (Maze)', 'GC Maze Gossip Stone'), + 0x0419: GossipStone('GC (Medigoron)', 'GC Medigoron Gossip Stone'), + 0x040A: GossipStone('Graveyard (Shadow Temple)', 'Graveyard Gossip Stone'), + 0x0412: GossipStone('HC (Malon)', 'HC Malon Gossip Stone'), + 0x040B: GossipStone('HC (Rock Wall)', 'HC Rock Wall Gossip Stone'), + 0x0413: GossipStone('HC (Storms Grotto)', 'HC Storms Grotto Gossip Stone'), + 0x041F: GossipStone('KF (Deku Tree Left)', 'KF Deku Tree Gossip Stone (Left)'), + 0x0420: GossipStone('KF (Deku Tree Right)', 'KF Deku Tree Gossip Stone (Right)'), + 0x041E: GossipStone('KF (Outside Storms)', 'KF Gossip Stone'), + 0x0403: GossipStone('LH (Lab)', 'LH Lab Gossip Stone'), + 0x040F: GossipStone('LH (Southeast Corner)', 'LH Gossip Stone (Southeast)'), + 0x0408: GossipStone('LH (Southwest Corner)', 'LH Gossip Stone (Southwest)'), + 0x041D: GossipStone('LW (Bridge)', 'LW Gossip Stone'), + 0x0416: GossipStone('SFM (Maze Lower)', 'SFM Maze Gossip Stone (Lower)'), + 0x0417: GossipStone('SFM (Maze Upper)', 'SFM Maze Gossip Stone (Upper)'), + 0x041C: GossipStone('SFM (Saria)', 'SFM Saria Gossip Stone'), + 0x0406: GossipStone('ToT (Left)', 'ToT Gossip Stone (Left)'), + 0x0407: GossipStone('ToT (Left-Center)', 'ToT Gossip Stone (Left-Center)'), + 0x0410: GossipStone('ToT (Right)', 'ToT Gossip Stone (Right)'), + 0x040E: GossipStone('ToT (Right-Center)', 'ToT Gossip Stone (Right-Center)'), + 0x0409: GossipStone('ZD (Mweep)', 'ZD Gossip Stone'), + 0x0401: GossipStone('ZF (Fairy)', 'ZF Fairy Gossip Stone'), + 0x0402: GossipStone('ZF (Jabu)', 'ZF Jabu Gossip Stone'), + 0x040D: GossipStone('ZR (Near Grottos)', 'ZR Near Grottos Gossip Stone'), + 0x040C: GossipStone('ZR (Near Domain)', 'ZR Near Domain Gossip Stone'), + 0x041B: GossipStone('HF (Cow Grotto)', 'HF Cow Grotto Gossip Stone'), + + 0x0430: GossipStone('HF (Near Market Grotto)', 'HF Near Market Grotto Gossip Stone'), + 0x0432: GossipStone('HF (Southeast Grotto)', 'HF Southeast Grotto Gossip Stone'), + 0x0433: GossipStone('HF (Open Grotto)', 'HF Open Grotto Gossip Stone'), + 0x0438: GossipStone('Kak (Open Grotto)', 'Kak Open Grotto Gossip Stone'), + 0x0439: GossipStone('ZR (Open Grotto)', 'ZR Open Grotto Gossip Stone'), + 0x043C: GossipStone('KF (Storms Grotto)', 'KF Storms Grotto Gossip Stone'), + 0x0444: GossipStone('LW (Near Shortcuts Grotto)', 'LW Near Shortcuts Grotto Gossip Stone'), + 0x0447: GossipStone('DMT (Storms Grotto)', 'DMT Storms Grotto Gossip Stone'), + 0x044A: GossipStone('DMC (Upper Grotto)', 'DMC Upper Grotto Gossip Stone'), +} + +gossipLocations_reversemap = { + stone.name : stone_id for stone_id, stone in gossipLocations.items() +} + +def getItemGenericName(item): + if item.game != "Ocarina of Time": + return item.name + elif item.dungeonitem: + return item.type + else: + return item.name + + +def isRestrictedDungeonItem(dungeon, item): + if (item.map or item.compass) and dungeon.world.shuffle_mapcompass == 'dungeon': + return item in dungeon.dungeon_items + if item.type == 'SmallKey' and dungeon.world.shuffle_smallkeys == 'dungeon': + return item in dungeon.small_keys + if item.type == 'BossKey' and dungeon.world.shuffle_bosskeys == 'dungeon': + return item in dungeon.boss_key + if item.type == 'GanonBossKey' and dungeon.world.shuffle_ganon_bosskey == 'dungeon': + return item in dungeon.boss_key + return False + + +# Attach a player name to the item or location text. +# If the associated player of the item/location and the world are the same, does nothing. +# Otherwise, attaches the object's player's name to the string. +def attach_name(text, hinted_object, world): + if hinted_object.player == world.player: + return text + return f"{text} for {world.world.get_player_name(hinted_object.player)}" + + +def add_hint(world, groups, gossip_text, count, location=None, force_reachable=False): + world.hint_rng.shuffle(groups) + skipped_groups = [] + duplicates = [] + first = True + success = True + # early failure if not enough + if len(groups) < int(count): + return False + # Randomly round up, if we have enough groups left + total = int(world.hint_rng.random() + count) if len(groups) > count else int(count) + while total: + if groups: + group = groups.pop(0) + + if any(map(lambda id: gossipLocations[id].reachable, group)): + stone_names = [gossipLocations[id].location for id in group] + # stone_locations = [world.get_location(stone_name) for stone_name in stone_names] + # Taking out all checks on gossip stone reachability and hint logic + if not first or True: # or any(map(lambda stone_location: can_reach_hint(worlds, stone_location, location), stone_locations)): + # if first and location: + # # just name the event item after the gossip stone directly + # event_item = None + # for i, stone_name in enumerate(stone_names): + # # place the same event item in each location in the group + # if event_item is None: + # event_item = MakeEventItem(stone_name, stone_locations[i], event_item) + # else: + # MakeEventItem(stone_name, stone_locations[i], event_item) + + # # This mostly guarantees that we don't lock the player out of an item hint + # # by establishing a (hint -> item) -> hint -> item -> (first hint) loop + # location.add_rule(world.parser.parse_rule(repr(event_item.name))) + + total -= 1 + first = False + for id in group: + world.gossip_hints[id] = gossip_text + # Immediately start choosing duplicates from stones we passed up earlier + while duplicates and total: + group = duplicates.pop(0) + total -= 1 + for id in group: + world.gossip_hints[id] = gossip_text + else: + # Temporarily skip this stone but consider it for duplicates + duplicates.append(group) + else: + if not force_reachable: + # The stones are not readable at all in logic, so we ignore any kind of logic here + if not first: + total -= 1 + for id in group: + world.gossip_hints[id] = gossip_text + else: + # Temporarily skip this stone but consider it for duplicates + duplicates.append(group) + else: + # If flagged to guarantee reachable, then skip + # If no stones are reachable, then this will place nothing + skipped_groups.append(group) + else: + # Out of groups + if not force_reachable and len(duplicates) >= total: + # Didn't find any appropriate stones for this hint, but maybe enough completely unreachable ones. + # We'd rather not use reachable stones for this. + unr = [group for group in duplicates if all(map(lambda id: not gossipLocations[id].reachable, group))] + if len(unr) >= total: + duplicates = [group for group in duplicates if group not in unr[:total]] + for group in unr[:total]: + for id in group: + world.gossip_hints[id] = gossip_text + # Success + break + # Failure + success = False + break + groups.extend(duplicates) + groups.extend(skipped_groups) + return success + + + +def writeGossipStoneHints(world, messages): + for id, gossip_text in world.gossip_hints.items(): + update_message_by_id(messages, id, str(gossip_text), 0x23) + + +def filterTrailingSpace(text): + if text.endswith('& '): + return text[:-1] + else: + return text + + +hintPrefixes = [ + 'a few ', + 'some ', + 'plenty of ', + 'a ', + 'an ', + 'the ', + '', +] + +def getSimpleHintNoPrefix(item): + hint = getHint(item.name, True).text + + for prefix in hintPrefixes: + if hint.startswith(prefix): + # return without the prefix + return hint[len(prefix):] + + # no prefex + return hint + + +def colorText(gossip_text): + colorMap = { + 'White': '\x40', + 'Red': '\x41', + 'Green': '\x42', + 'Blue': '\x43', + 'Light Blue': '\x44', + 'Pink': '\x45', + 'Yellow': '\x46', + 'Black': '\x47', + } + + text = gossip_text.text + colors = list(gossip_text.colors) if gossip_text.colors is not None else [] + color = 'White' + + while '#' in text: + splitText = text.split('#', 2) + if len(colors) > 0: + color = colors.pop() + + for prefix in hintPrefixes: + if splitText[1].startswith(prefix): + splitText[0] += splitText[1][:len(prefix)] + splitText[1] = splitText[1][len(prefix):] + break + + splitText[1] = '\x05' + colorMap[color] + splitText[1] + '\x05\x40' + text = ''.join(splitText) + + return text + + +class HintAreaNotFound(RuntimeError): + pass + + +# Peforms a breadth first search to find the closest hint area from a given spot (location or entrance) +# May fail to find a hint if the given spot is only accessible from the root and not from any other region with a hint area +# Returns the name of the location if the spot is not in OoT +def get_hint_area(spot): + if spot.game == 'Ocarina of Time': + already_checked = [] + spot_queue = [spot] + + while spot_queue: + current_spot = spot_queue.pop(0) + already_checked.append(current_spot) + + parent_region = current_spot.parent_region + + if parent_region.dungeon: + return parent_region.dungeon.hint_text + elif parent_region.hint_text and (spot.parent_region.name == 'Root' or parent_region.name != 'Root'): + return parent_region.hint_text + + spot_queue.extend(list(filter(lambda ent: ent not in already_checked, parent_region.entrances))) + + raise HintAreaNotFound('No hint area could be found for %s [World %d]' % (spot, spot.world.id)) + else: + return spot.name + + +def get_woth_hint(world, checked): + locations = world.required_locations + locations = list(filter(lambda location: + location.name not in checked[location.player] + and not (world.woth_dungeon >= world.hint_dist_user['dungeons_woth_limit'] and location.parent_region.dungeon) + and location.name not in world.hint_exclusions + and location.name not in world.hint_type_overrides['woth'] + and location.item.name not in world.item_hint_type_overrides['woth'], + locations)) + + if not locations: + return None + + location = world.hint_rng.choice(locations) + checked[location.player].add(location.name) + + if location.parent_region.dungeon: + world.woth_dungeon += 1 + location_text = getHint(location.parent_region.dungeon.name, world.clearer_hints).text + else: + location_text = get_hint_area(location) + + if world.triforce_hunt: + return (GossipText('#%s# is on the path of gold.' % location_text, ['Light Blue']), location) + else: + return (GossipText('#%s# is on the way of the hero.' % location_text, ['Light Blue']), location) + + +def get_barren_hint(world, checked): + if not hasattr(world, 'get_barren_hint_prev'): + world.get_barren_hint_prev = RegionRestriction.NONE + + areas = list(filter(lambda area: + area not in checked[world.player] + and area not in world.hint_type_overrides['barren'] + and not (world.barren_dungeon >= world.hint_dist_user['dungeons_barren_limit'] and world.empty_areas[area]['dungeon']), + world.empty_areas.keys())) + + if not areas: + return None + + # Randomly choose between overworld or dungeon + dungeon_areas = list(filter(lambda area: world.empty_areas[area]['dungeon'], areas)) + overworld_areas = list(filter(lambda area: not world.empty_areas[area]['dungeon'], areas)) + if not dungeon_areas: + # no dungeons left, default to overworld + world.get_barren_hint_prev = RegionRestriction.OVERWORLD + elif not overworld_areas: + # no overworld left, default to dungeons + world.get_barren_hint_prev = RegionRestriction.DUNGEON + else: + if world.get_barren_hint_prev == RegionRestriction.NONE: + # 50/50 draw on the first hint + world.get_barren_hint_prev = world.hint_rng.choices([RegionRestriction.DUNGEON, RegionRestriction.OVERWORLD], [0.5, 0.5])[0] + elif world.get_barren_hint_prev == RegionRestriction.DUNGEON: + # weights 75% against drawing dungeon again + world.get_barren_hint_prev = world.hint_rng.choices([RegionRestriction.DUNGEON, RegionRestriction.OVERWORLD], [0.25, 0.75])[0] + elif world.get_barren_hint_prev == RegionRestriction.OVERWORLD: + # weights 75% against drawing overworld again + world.get_barren_hint_prev = world.hint_rng.choices([RegionRestriction.DUNGEON, RegionRestriction.OVERWORLD], [0.75, 0.25])[0] + + if world.get_barren_hint_prev == RegionRestriction.DUNGEON: + areas = dungeon_areas + else: + areas = overworld_areas + if not areas: + return None + + area_weights = [world.empty_areas[area]['weight'] for area in areas] + + area = world.hint_rng.choices(areas, weights=area_weights)[0] + if world.empty_areas[area]['dungeon']: + world.barren_dungeon += 1 + + checked[world.player].add(area) + + return (GossipText("plundering #%s# is a foolish choice." % area, ['Pink']), None) + + +def is_not_checked(location, checked): + return not (location.name in checked[location.player] or get_hint_area(location) in checked) + + +def get_good_item_hint(world, checked): + locations = list(filter(lambda location: + is_not_checked(location, checked) + and not location.locked + and location.name not in world.hint_exclusions + and location.name not in world.hint_type_overrides['item'] + and location.item.name not in world.item_hint_type_overrides['item'], + world.major_item_locations)) + if not locations: + return None + + location = world.hint_rng.choice(locations) + checked[location.player].add(location.name) + + item_text = getHint(getItemGenericName(location.item), world.clearer_hints).text + if location.parent_region.dungeon: + location_text = getHint(location.parent_region.dungeon.name, world.clearer_hints).text + return (GossipText('#%s# hoards #%s#.' % (attach_name(location_text, location, world), attach_name(item_text, location.item, world)), + ['Green', 'Red']), location) + else: + location_text = get_hint_area(location) + return (GossipText('#%s# can be found at #%s#.' % (attach_name(item_text, location.item, world), attach_name(location_text, location, world)), + ['Red', 'Green']), location) + + +def get_specific_item_hint(world, checked): + if len(world.named_item_pool) == 0: + logger = logging.getLogger('') + logger.info("Named item hint requested, but pool is empty.") + return None + while True: + itemname = world.named_item_pool.pop(0) + if itemname == "Bottle" and world.hint_dist == "bingo": + locations = [ + location for location in world.world.get_filled_locations() + if (is_not_checked(location, checked) + and location.name not in world.hint_exclusions + and location.item.name in bingoBottlesForHints + and not location.locked + and location.name not in world.hint_type_overrides['named-item']) + ] + else: + locations = [ + location for location in world.world.get_filled_locations() + if (is_not_checked(location, checked) + and location.name not in world.hint_exclusions + and location.item.name == itemname + and not location.locked + and location.name not in world.hint_type_overrides['named-item']) + ] + if len(locations) > 0: + break + if len(world.named_item_pool) == 0: + return None + + location = world.hint_rng.choice(locations) + checked[location.player].add(location.name) + item_text = getHint(getItemGenericName(location.item), world.clearer_hints).text + + if location.parent_region.dungeon: + location_text = getHint(location.parent_region.dungeon.name, world.clearer_hints).text + if world.hint_dist_user.get('vague_named_items', False): + return (GossipText('#%s# may be on the hero\'s path.' % (location_text), ['Green']), location) + else: + return (GossipText('#%s# hoards #%s#.' % (attach_name(location_text, location, world), attach_name(item_text, location.item, world)), + ['Green', 'Red']), location) + else: + location_text = get_hint_area(location) + if world.hint_dist_user.get('vague_named_items', False): + return (GossipText('#%s# may be on the hero\'s path.' % (location_text), ['Green']), location) + else: + return (GossipText('#%s# can be found at #%s#.' % (attach_name(item_text, location.item, world), attach_name(location_text, location, world)), + ['Red', 'Green']), location) + + +def get_random_location_hint(world, checked): + locations = list(filter(lambda location: + is_not_checked(location, checked) + and location.item.type not in ('Drop', 'Event', 'Shop', 'DungeonReward') + # and not (location.parent_region.dungeon and isRestrictedDungeonItem(location.parent_region.dungeon, location.item)) # AP already locks dungeon items + and not location.locked + and location.name not in world.hint_exclusions + and location.name not in world.hint_type_overrides['item'] + and location.item.name not in world.item_hint_type_overrides['item'], + world.world.get_filled_locations(world.player))) + if not locations: + return None + + location = world.hint_rng.choice(locations) + checked[location.player].add(location.name) + dungeon = location.parent_region.dungeon + + item_text = getHint(getItemGenericName(location.item), world.clearer_hints).text + if dungeon: + location_text = getHint(dungeon.name, world.clearer_hints).text + return (GossipText('#%s# hoards #%s#.' % (attach_name(location_text, location, world), attach_name(item_text, location.item, world)), + ['Green', 'Red']), location) + else: + location_text = get_hint_area(location) + return (GossipText('#%s# can be found at #%s#.' % (attach_name(item_text, location.item, world), attach_name(location_text, location, world)), + ['Red', 'Green']), location) + + +def get_specific_hint(world, checked, type): + hintGroup = getHintGroup(type, world) + hintGroup = list(filter(lambda hint: is_not_checked(world.get_location(hint.name), checked), hintGroup)) + if not hintGroup: + return None + + hint = world.hint_rng.choice(hintGroup) + location = world.get_location(hint.name) + checked[location.player].add(location.name) + + if location.name in world.hint_text_overrides: + location_text = world.hint_text_overrides[location.name] + else: + location_text = hint.text + if '#' not in location_text: + location_text = '#%s#' % location_text + item_text = getHint(getItemGenericName(location.item), world.clearer_hints).text + + return (GossipText('%s #%s#.' % (attach_name(location_text, location, world), attach_name(item_text, location.item, world)), + ['Green', 'Red']), location) + + +def get_sometimes_hint(world, checked): + return get_specific_hint(world, checked, 'sometimes') + + +def get_song_hint(world, checked): + return get_specific_hint(world, checked, 'song') + + +def get_overworld_hint(world, checked): + return get_specific_hint(world, checked, 'overworld') + + +def get_dungeon_hint(world, checked): + return get_specific_hint(world, checked, 'dungeon') + + +# probably broken +def get_entrance_hint(world, checked): + if not world.entrance_shuffle: + return None + + entrance_hints = list(filter(lambda hint: hint.name not in checked[world.player], getHintGroup('entrance', world))) + shuffled_entrance_hints = list(filter(lambda entrance_hint: world.get_entrance(entrance_hint.name).shuffled, entrance_hints)) + + regions_with_hint = [hint.name for hint in getHintGroup('region', world)] + valid_entrance_hints = list(filter(lambda entrance_hint: + (world.get_entrance(entrance_hint.name).connected_region.name in regions_with_hint or + world.get_entrance(entrance_hint.name).connected_region.dungeon), shuffled_entrance_hints)) + + if not valid_entrance_hints: + return None + + entrance_hint = world.hint_rng.choice(valid_entrance_hints) + entrance = world.get_entrance(entrance_hint.name) + checked[world.player].add(entrance.name) + + entrance_text = entrance_hint.text + + if '#' not in entrance_text: + entrance_text = '#%s#' % entrance_text + + connected_region = entrance.connected_region + if connected_region.dungeon: + region_text = getHint(connected_region.dungeon.name, world.clearer_hints).text + else: + region_text = getHint(connected_region.name, world.clearer_hints).text + + if '#' not in region_text: + region_text = '#%s#' % region_text + + return (GossipText('%s %s.' % (entrance_text, region_text), ['Light Blue', 'Green']), None) + + +def get_junk_hint(world, checked): + hints = getHintGroup('junk', world) + hints = list(filter(lambda hint: hint.name not in checked[world.player], hints)) + if not hints: + return None + + hint = world.hint_rng.choice(hints) + checked[world.player].add(hint.name) + + return (GossipText(hint.text, prefix=''), None) + + +hint_func = { + 'trial': lambda world, checked: None, + 'always': lambda world, checked: None, + 'woth': get_woth_hint, + 'barren': get_barren_hint, + 'item': get_good_item_hint, + 'sometimes': get_sometimes_hint, + 'song': get_song_hint, + 'overworld': get_overworld_hint, + 'dungeon': get_dungeon_hint, + 'entrance': get_entrance_hint, + 'random': get_random_location_hint, + 'junk': get_junk_hint, + 'named-item': get_specific_item_hint +} + +hint_dist_keys = { + 'trial', + 'always', + 'woth', + 'barren', + 'item', + 'song', + 'overworld', + 'dungeon', + 'entrance', + 'sometimes', + 'random', + 'junk', + 'named-item' +} + + + +# builds out general hints based on location and whether an item is required or not +def buildWorldGossipHints(world, checkedLocations=None): + # Seed the RNG + world.hint_rng = world.world.slot_seeds[world.player] + + # Gather woth, barren, major items + world.gather_hint_data() + + # rebuild hint exclusion list + hintExclusions(world, clear_cache=True) + + world.barren_dungeon = 0 + world.woth_dungeon = 0 + + # search = Search.max_explore([w.state for w in orlds]) + # for stone in gossipLocations.values(): + # stone.reachable = ( + # search.spot_access(world.get_location(stone.location)) + # and search.state_list[world.id].guarantee_hint()) + + if checkedLocations is None: + checkedLocations = {player: set() for player in world.world.player_ids} + + # If Ganondorf can be reached without Light Arrows, add to checkedLocations to prevent extra hinting + # Can only be forced with vanilla bridge + if world.bridge != 'vanilla': + try: + light_arrow_location = world.world.find_item("Light Arrows", world.player) + checkedLocations[light_arrow_location.player].add(light_arrow_location.name) + except StopIteration: # start with them + pass + + stoneIDs = list(gossipLocations.keys()) + + # world.distribution.configure_gossip(stoneIDs) + + if 'disabled' in world.hint_dist_user: + for stone_name in world.hint_dist_user['disabled']: + try: + stone_id = gossipLocations_reversemap[stone_name] + except KeyError: + raise ValueError(f'Gossip stone location "{stone_name}" is not valid') + stoneIDs.remove(stone_id) + (gossip_text, _) = get_junk_hint(world, checkedLocations) + world.gossip_hints[stone_id] = gossip_text + + stoneGroups = [] + if 'groups' in world.hint_dist_user: + for group_names in world.hint_dist_user['groups']: + group = [] + for stone_name in group_names: + try: + stone_id = gossipLocations_reversemap[stone_name] + except KeyError: + raise ValueError(f'Gossip stone location "{stone_name}" is not valid') + + stoneIDs.remove(stone_id) + group.append(stone_id) + stoneGroups.append(group) + # put the remaining locations into singleton groups + stoneGroups.extend([[id] for id in stoneIDs]) + + world.hint_rng.shuffle(stoneGroups) + + + # Load hint distro from distribution file or pre-defined settings + # + # 'fixed' key is used to mimic the tournament distribution, creating a list of fixed hint types to fill + # Once the fixed hint type list is exhausted, weighted random choices are taken like all non-tournament sets + # This diverges from the tournament distribution where leftover stones are filled with sometimes hints (or random if no sometimes locations remain to be hinted) + sorted_dist = {} + type_count = 1 + hint_dist = OrderedDict({}) + fixed_hint_types = [] + max_order = 0 + for hint_type in world.hint_dist_user['distribution']: + if world.hint_dist_user['distribution'][hint_type]['order'] > 0: + hint_order = int(world.hint_dist_user['distribution'][hint_type]['order']) + sorted_dist[hint_order] = hint_type + if max_order < hint_order: + max_order = hint_order + type_count = type_count + 1 + if (type_count - 1) < max_order: + raise Exception("There are gaps in the custom hint orders. Please revise your plando file to remove them.") + for i in range(1, type_count): + hint_type = sorted_dist[i] + if world.hint_dist_user['distribution'][hint_type]['copies'] > 0: + fixed_num = world.hint_dist_user['distribution'][hint_type]['fixed'] + hint_weight = world.hint_dist_user['distribution'][hint_type]['weight'] + else: + logging.getLogger('').warning("Hint copies is zero for type %s. Assuming this hint type should be disabled.", hint_type) + fixed_num = 0 + hint_weight = 0 + hint_dist[hint_type] = (hint_weight, world.hint_dist_user['distribution'][hint_type]['copies']) + hint_dist.move_to_end(hint_type) + fixed_hint_types.extend([hint_type] * int(fixed_num)) + + hint_types, hint_prob = zip(*hint_dist.items()) + hint_prob, _ = zip(*hint_prob) + + # Add required location hints, only if hint copies > 0 + if hint_dist['always'][1] > 0: + alwaysLocations = getHintGroup('always', world) + for hint in alwaysLocations: + location = world.get_location(hint.name) + checkedLocations[location.player].add(hint.name) + if location.item.name in bingoBottlesForHints and world.hint_dist == 'bingo': + always_item = 'Bottle' + else: + always_item = location.item.name + if always_item in world.named_item_pool: + world.named_item_pool.remove(always_item) + + if location.name in world.hint_text_overrides: + location_text = world.hint_text_overrides[location.name] + else: + location_text = getHint(location.name, world.clearer_hints).text + if '#' not in location_text: + location_text = '#%s#' % location_text + item_text = getHint(getItemGenericName(location.item), world.clearer_hints).text + add_hint(world, stoneGroups, GossipText('%s #%s#.' % (attach_name(location_text, location, world), attach_name(item_text, location.item, world)), + ['Green', 'Red']), hint_dist['always'][1], location, force_reachable=True) + logging.getLogger('').debug('Placed always hint for %s.', location.name) + + # Add trial hints, only if hint copies > 0 + if hint_dist['trial'][1] > 0: + if world.trials == 6: + add_hint(world, stoneGroups, GossipText("#Ganon's Tower# is protected by a powerful barrier.", ['Pink']), hint_dist['trial'][1], force_reachable=True) + elif world.trials == 0: + add_hint(world, stoneGroups, GossipText("Sheik dispelled the barrier around #Ganon's Tower#.", ['Yellow']), hint_dist['trial'][1], force_reachable=True) + elif world.trials < 6 and world.trials > 3: + for trial,skipped in world.skipped_trials.items(): + if skipped: + add_hint(world, stoneGroups,GossipText("the #%s Trial# was dispelled by Sheik." % trial, ['Yellow']), hint_dist['trial'][1], force_reachable=True) + elif world.trials <= 3 and world.trials > 0: + for trial,skipped in world.skipped_trials.items(): + if not skipped: + add_hint(world, stoneGroups, GossipText("the #%s Trial# protects Ganon's Tower." % trial, ['Pink']), hint_dist['trial'][1], force_reachable=True) + + # Add user-specified hinted item locations if using a built-in hint distribution + # Raise error if hint copies is zero + if len(world.named_item_pool) > 0 and world.hint_dist_user['named_items_required']: + if hint_dist['named-item'][1] == 0: + raise Exception('User-provided item hints were requested, but copies per named-item hint is zero') + else: + for i in range(0, len(world.named_item_pool)): + hint = get_specific_item_hint(world, checkedLocations) + if hint == None: + raise Exception('No valid hints for user-provided item') + else: + gossip_text, location = hint + place_ok = add_hint(world, stoneGroups, gossip_text, hint_dist['named-item'][1], location) + if not place_ok: + raise Exception('Not enough gossip stones for user-provided item hints') + + # Shuffle named items hints + # When all items are not required to be hinted, this allows for + # opportunity-style hints to be drawn at random from the defined list. + world.hint_rng.shuffle(world.named_item_pool) + + hint_types = list(hint_types) + hint_prob = list(hint_prob) + hint_counts = {} + + custom_fixed = True + while stoneGroups: + if fixed_hint_types: + hint_type = fixed_hint_types.pop(0) + copies = hint_dist[hint_type][1] + if copies > len(stoneGroups): + # Quiet to avoid leaking information. + logging.getLogger('').debug(f'Not enough gossip stone locations ({len(stoneGroups)} groups) for fixed hint type {hint_type} with {copies} copies, proceeding with available stones.') + copies = len(stoneGroups) + else: + custom_fixed = False + # Make sure there are enough stones left for each hint type + num_types = len(hint_types) + hint_types = list(filter(lambda htype: hint_dist[htype][1] <= len(stoneGroups), hint_types)) + new_num_types = len(hint_types) + if new_num_types == 0: + raise Exception('Not enough gossip stone locations for remaining weighted hint types.') + elif new_num_types < num_types: + hint_prob = [] + for htype in hint_types: + hint_prob.append(hint_dist[htype][0]) + try: + # Weight the probabilities such that hints that are over the expected proportion + # will be drawn less, and hints that are under will be drawn more. + # This tightens the variance quite a bit. The variance can be adjusted via the power + weighted_hint_prob = [] + for w1_type, w1_prob in zip(hint_types, hint_prob): + p = w1_prob + if p != 0: # If the base prob is 0, then it's 0 + for w2_type, w2_prob in zip(hint_types, hint_prob): + if w2_prob != 0: # If the other prob is 0, then it has no effect + # Raising this term to a power greater than 1 will decrease variance + # Conversely, a power less than 1 will increase variance + p = p * (((hint_counts.get(w2_type, 0) / w2_prob) + 1) / ((hint_counts.get(w1_type, 0) / w1_prob) + 1)) + weighted_hint_prob.append(p) + + hint_type = world.hint_rng.choices(hint_types, weights=weighted_hint_prob)[0] + copies = hint_dist[hint_type][1] + except IndexError: + raise Exception('Not enough valid hints to fill gossip stone locations.') + + hint = hint_func[hint_type](world, checkedLocations) + + if hint == None: + index = hint_types.index(hint_type) + hint_prob[index] = 0 + # Zero out the probability in the base distribution in case the probability list is modified + # to fit hint types in remaining gossip stones + hint_dist[hint_type] = (0.0, copies) + else: + gossip_text, location = hint + place_ok = add_hint(world, stoneGroups, gossip_text, copies, location) + if place_ok: + hint_counts[hint_type] = hint_counts.get(hint_type, 0) + 1 + if location is None: + logging.getLogger('').debug('Placed %s hint.', hint_type) + else: + logging.getLogger('').debug('Placed %s hint for %s.', hint_type, location.name) + if not place_ok and custom_fixed: + logging.getLogger('').debug('Failed to place %s fixed hint for %s.', hint_type, location.name) + fixed_hint_types.insert(0, hint_type) + + +# builds text that is displayed at the temple of time altar for child and adult, rewards pulled based off of item in a fixed order. +def buildAltarHints(world, messages, include_rewards=True, include_wincons=True): + # text that appears at altar as a child. + child_text = '\x08' + if include_rewards: + bossRewardsSpiritualStones = [ + ('Kokiri Emerald', 'Green'), + ('Goron Ruby', 'Red'), + ('Zora Sapphire', 'Blue'), + ] + child_text += getHint('Spiritual Stone Text Start', world.clearer_hints).text + '\x04' + for (reward, color) in bossRewardsSpiritualStones: + child_text += buildBossString(reward, color, world) + child_text += getHint('Child Altar Text End', world.clearer_hints).text + child_text += '\x0B' + update_message_by_id(messages, 0x707A, get_raw_text(child_text), 0x20) + + # text that appears at altar as an adult. + adult_text = '\x08' + adult_text += getHint('Adult Altar Text Start', world.clearer_hints).text + '\x04' + if include_rewards: + bossRewardsMedallions = [ + ('Light Medallion', 'Light Blue'), + ('Forest Medallion', 'Green'), + ('Fire Medallion', 'Red'), + ('Water Medallion', 'Blue'), + ('Shadow Medallion', 'Pink'), + ('Spirit Medallion', 'Yellow'), + ] + for (reward, color) in bossRewardsMedallions: + adult_text += buildBossString(reward, color, world) + if include_wincons: + adult_text += buildBridgeReqsString(world) + adult_text += '\x04' + adult_text += buildGanonBossKeyString(world) + else: + adult_text += getHint('Adult Altar Text End', world.clearer_hints).text + adult_text += '\x0B' + update_message_by_id(messages, 0x7057, get_raw_text(adult_text), 0x20) + + +# pulls text string from hintlist for reward after sending the location to hintlist. +def buildBossString(reward, color, world): + for location in world.world.get_filled_locations(world.player): + if location.item.name == reward: + item_icon = chr(location.item.special['item_id']) + location_text = getHint(location.name, world.clearer_hints).text + return str(GossipText("\x08\x13%s%s" % (item_icon, location_text), [color], prefix='')) + '\x04' + return '' + + +def buildBridgeReqsString(world): + string = "\x13\x12" # Light Arrow Icon + if world.bridge == 'open': + string += "The awakened ones will have #already created a bridge# to the castle where the evil dwells." + else: + item_req_string = getHint('bridge_' + world.bridge, world.clearer_hints).text + if world.bridge == 'medallions': + item_req_string = str(world.bridge_medallions) + ' ' + item_req_string + elif world.bridge == 'stones': + item_req_string = str(world.bridge_stones) + ' ' + item_req_string + elif world.bridge == 'dungeons': + item_req_string = str(world.bridge_rewards) + ' ' + item_req_string + elif world.bridge == 'tokens': + item_req_string = str(world.bridge_tokens) + ' ' + item_req_string + if '#' not in item_req_string: + item_req_string = '#%s#' % item_req_string + string += "The awakened ones will await for the Hero to collect %s." % item_req_string + return str(GossipText(string, ['Green'], prefix='')) + + +def buildGanonBossKeyString(world): + string = "\x13\x74" # Boss Key Icon + if world.shuffle_ganon_bosskey == 'remove': + string += "And the door to the \x05\x41evil one\x05\x40's chamber will be left #unlocked#." + else: + if world.shuffle_ganon_bosskey == 'on_lacs': + item_req_string = getHint('lacs_' + world.lacs_condition, world.clearer_hints).text + if world.lacs_condition == 'medallions': + item_req_string = str(world.lacs_medallions) + ' ' + item_req_string + elif world.lacs_condition == 'stones': + item_req_string = str(world.lacs_stones) + ' ' + item_req_string + elif world.lacs_condition == 'dungeons': + item_req_string = str(world.lacs_rewards) + ' ' + item_req_string + elif world.lacs_condition == 'tokens': + item_req_string = str(world.lacs_tokens) + ' ' + item_req_string + if '#' not in item_req_string: + item_req_string = '#%s#' % item_req_string + bk_location_string = "provided by Zelda once %s are retrieved" % item_req_string + else: + bk_location_string = getHint('ganonBK_' + world.shuffle_ganon_bosskey, world.clearer_hints).text + string += "And the \x05\x41evil one\x05\x40's key will be %s." % bk_location_string + return str(GossipText(string, ['Yellow'], prefix='')) + + +# fun new lines for Ganon during the final battle +def buildGanonText(world, messages): + # empty now unused messages to make space for ganon lines + update_message_by_id(messages, 0x70C8, " ") + update_message_by_id(messages, 0x70C9, " ") + update_message_by_id(messages, 0x70CA, " ") + + # lines before battle + ganonLines = getHintGroup('ganonLine', world) + world.hint_rng.shuffle(ganonLines) + text = get_raw_text(ganonLines.pop().text) + update_message_by_id(messages, 0x70CB, text) + + # light arrow hint or validation chest item + if world.starting_items['Light Arrows'] > 0: + text = get_raw_text(getHint('Light Arrow Location', world.clearer_hints).text) + text += "\x05\x42your pocket\x05\x40" + else: + try: + find_light_arrows = world.world.find_item('Light Arrows', world.player) + text = get_raw_text(getHint('Light Arrow Location', world.clearer_hints).text) + location = find_light_arrows + location_hint = get_hint_area(location) + if world.player != location.player: + text += "\x05\x42%s's\x05\x40 %s" % (world.world.get_player_name(location.player), get_raw_text(location_hint)) + else: + location_hint = location_hint.replace('Ganon\'s Castle', 'my castle') + text += get_raw_text(location_hint) + except StopIteration: + text = get_raw_text(getHint('Validation Line', world.clearer_hints).text) + for location in world.world.get_filled_locations(world.player): + if location.name == 'Ganons Tower Boss Key Chest': + text += get_raw_text(getHint(getItemGenericName(location.item), world.clearer_hints).text) + break + text += '!' + + update_message_by_id(messages, 0x70CC, text) + + +def get_raw_text(string): + text = '' + for char in string: + if char == '^': + text += '\x04' # box break + elif char == '&': + text += '\x01' # new line + elif char == '@': + text += '\x0F' # print player name + elif char == '#': + text += '\x05\x40' # sets color to white + else: + text += char + return text + + +def HintDistFiles(): + return [os.path.join(data_path('Hints/'), d) for d in defaultHintDists] + [ + os.path.join(data_path('Hints/'), d) + for d in sorted(os.listdir(data_path('Hints/'))) + if d.endswith('.json') and d not in defaultHintDists] + + +def HintDistList(): + dists = {} + for d in HintDistFiles(): + dist = read_json(d) + dist_name = dist['name'] + gui_name = dist['gui_name'] + dists.update({ dist_name: gui_name }) + return dists + + +def HintDistTips(): + tips = "" + first_dist = True + line_char_limit = 33 + for d in HintDistFiles(): + if not first_dist: + tips = tips + "\n" + else: + first_dist = False + dist = read_json(d) + gui_name = dist['gui_name'] + desc = dist['description'] + i = 0 + end_of_line = False + tips = tips + "" + for c in gui_name: + if c == " " and end_of_line: + tips = tips + "\n" + end_of_line = False + else: + tips = tips + c + i = i + 1 + if i > line_char_limit: + end_of_line = True + i = 0 + tips = tips + ": " + i = i + 2 + for c in desc: + if c == " " and end_of_line: + tips = tips + "\n" + end_of_line = False + else: + tips = tips + c + i = i + 1 + if i > line_char_limit: + end_of_line = True + i = 0 + tips = tips + "\n" + return tips diff --git a/worlds/oot/IconManip.py b/worlds/oot/IconManip.py new file mode 100644 index 00000000..5b573881 --- /dev/null +++ b/worlds/oot/IconManip.py @@ -0,0 +1,112 @@ +from .Utils import data_path + +# TODO +# Move the tunic to the generalized system + +# Function for adding hue to a greyscaled icon +def add_hue(image, color, tiff=False): + start = 154 if tiff else 0 + for i in range(start, len(image), 4): + try: + for x in range(3): + image[i+x] = int(((image[i+x]/255) * (color[x]/255)) * 255) + except: + pass + return image + + +# Function for adding belt to tunic +def add_belt(tunic, belt, tiff=False): + start = 154 if tiff else 0 + for i in range(start, len(tunic), 4): + try: + if belt[i+3] != 0: + alpha = belt[i+3] / 255 + for x in range(3): + tunic[i+x] = int((belt[i+x] * alpha) + (tunic[i+x] * (1 - alpha))) + except: + pass + return tunic + + +# Function for putting tunic colors together +def generate_tunic_icon(color): + with open(data_path('icons/grey.tiff'), 'rb') as grey_fil, open(data_path('icons/belt.tiff'), 'rb') as belt_fil: + grey = list(grey_fil.read()) + belt = list(belt_fil.read()) + return add_belt(add_hue(grey, color, True), belt, True)[154:] + +# END TODO + +# Function to add extra data on top of icon +def add_extra_data(rgbValues, fileName, intensity = 0.5): + fileRGB = [] + with open(fileName, "rb") as fil: + data = fil.read() + for i in range(0, len(data), 4): + fileRGB.append([data[i+0], data[i+1], data[i+2], data[i+3]]) + for i in range(len(rgbValues)): + alpha = fileRGB[i][3] / 255 + for x in range(3): + rgbValues[i][x] = int((fileRGB[i][x] * alpha + intensity) + (rgbValues[i][x] * (1 - alpha - intensity))) + +# Function for desaturating RGB values +def greyscaleRGB(rgbValues, intensity: int = 2): + for rgb in rgbValues: + rgb[0] = rgb[1] = rgb[2] = int((rgb[0] * 0.2126 + rgb[1] * 0.7152 + rgb[2] * 0.0722) * intensity) + return rgbValues + +# Converts rgb5a1 values to RGBA lists +def rgb5a1ToRGB(rgb5a1Bytes): + pixels = [] + for i in range(0, len(rgb5a1Bytes), 2): + bits = format(rgb5a1Bytes[i], '#010b')[2:] + format(rgb5a1Bytes[i+1], '#010b')[2:] + r = int(int(bits[0:5], 2) * (255/31)) + g = int(int(bits[5:10], 2) * (255/31)) + b = int(int(bits[10:15], 2) * (255/31)) + a = int(bits[15], 2) * 255 + pixels.append([r,g,b,a]) + return pixels + +# Adds a hue to RGB values +def addHueToRGB(rgbValues, color): + for rgb in rgbValues: + for i in range(3): + rgb[i] = int(((rgb[i]/255) * (color[i]/255)) * 255) + return rgbValues + +# Convert RGB to RGB5a1 format +def rgbToRGB5a1(rgbValues): + rgb5a1 = [] + for rgb in rgbValues: + r = int(rgb[0] / (255/31)) + r = r if r <= 31 else 31 + r = r if r >= 0 else 0 + g = int(rgb[1] / (255/31)) + g = g if g <= 31 else 31 + g = g if g >= 0 else 0 + b = int(rgb[2] / (255/31)) + b = b if b <= 31 else 31 + b = b if b >= 0 else 0 + a = int(rgb[3] / 255) + bits = format(r, '#07b')[2:] + format(g, '#07b')[2:] + format(b, '#07b')[2:] + format(a, '#03b')[2:] + rgb5a1.append(int(bits[:8], 2)) + rgb5a1.append(int(bits[8:], 2)) + for i in rgb5a1: + assert i <= 255, i + return bytes(rgb5a1) + +# Patch overworld icons +def patch_overworld_icon(rom, color, address, fileName = None): + original = rom.original.read_bytes(address, 0x800) + + if color is None: + rom.write_bytes(address, original) + return + + rgbBytes = rgb5a1ToRGB(original) + greyscaled = greyscaleRGB(rgbBytes) + rgbBytes = addHueToRGB(greyscaled, color) + if fileName != None: + add_extra_data(rgbBytes, fileName) + rom.write_bytes(address, rgbToRGB5a1(rgbBytes)) diff --git a/worlds/oot/ItemPool.py b/worlds/oot/ItemPool.py new file mode 100644 index 00000000..96af9ad0 --- /dev/null +++ b/worlds/oot/ItemPool.py @@ -0,0 +1,1410 @@ +from collections import namedtuple +from itertools import chain +from .Items import item_table +from .LocationList import location_groups +from decimal import Decimal, ROUND_HALF_UP + + +# Generates itempools and places fixed items based on settings. + +alwaysitems = ([ + 'Biggoron Sword', + 'Boomerang', + 'Lens of Truth', + 'Megaton Hammer', + 'Iron Boots', + 'Goron Tunic', + 'Zora Tunic', + 'Hover Boots', + 'Mirror Shield', + 'Stone of Agony', + 'Fire Arrows', + 'Ice Arrows', + 'Light Arrows', + 'Dins Fire', + 'Farores Wind', + 'Nayrus Love', + 'Rupee (1)'] + + ['Progressive Hookshot'] * 2 + + ['Deku Shield'] + + ['Hylian Shield'] + + ['Progressive Strength Upgrade'] * 3 + + ['Progressive Scale'] * 2 + + ['Recovery Heart'] * 6 + + ['Bow'] * 3 + + ['Slingshot'] * 3 + + ['Bomb Bag'] * 3 + + ['Bombs (5)'] * 2 + + ['Bombs (10)'] + + ['Bombs (20)'] + + ['Arrows (5)'] + + ['Arrows (10)'] * 5 + + ['Progressive Wallet'] * 2 + + ['Magic Meter'] * 2 + + ['Double Defense'] + + ['Deku Stick Capacity'] * 2 + + ['Deku Nut Capacity'] * 2 + + ['Piece of Heart (Treasure Chest Game)']) + + +easy_items = ([ + 'Biggoron Sword', + 'Kokiri Sword', + 'Boomerang', + 'Lens of Truth', + 'Megaton Hammer', + 'Iron Boots', + 'Goron Tunic', + 'Zora Tunic', + 'Hover Boots', + 'Mirror Shield', + 'Fire Arrows', + 'Light Arrows', + 'Dins Fire', + 'Progressive Hookshot', + 'Progressive Strength Upgrade', + 'Progressive Scale', + 'Progressive Wallet', + 'Magic Meter', + 'Deku Stick Capacity', + 'Deku Nut Capacity', + 'Bow', + 'Slingshot', + 'Bomb Bag', + 'Double Defense'] + + ['Heart Container'] * 16 + + ['Piece of Heart'] * 3) + +normal_items = ( + ['Heart Container'] * 8 + + ['Piece of Heart'] * 35) + + +item_difficulty_max = { + 'plentiful': {}, + 'balanced': {}, + 'scarce': { + 'Bombchus': 3, + 'Bombchus (5)': 1, + 'Bombchus (10)': 2, + 'Bombchus (20)': 0, + 'Magic Meter': 1, + 'Double Defense': 0, + 'Deku Stick Capacity': 1, + 'Deku Nut Capacity': 1, + 'Bow': 2, + 'Slingshot': 2, + 'Bomb Bag': 2, + 'Heart Container': 0, + }, + 'minimal': { + 'Bombchus': 1, + 'Bombchus (5)': 1, + 'Bombchus (10)': 0, + 'Bombchus (20)': 0, + 'Nayrus Love': 0, + 'Magic Meter': 1, + 'Double Defense': 0, + 'Deku Stick Capacity': 0, + 'Deku Nut Capacity': 0, + 'Bow': 1, + 'Slingshot': 1, + 'Bomb Bag': 1, + 'Heart Container': 0, + 'Piece of Heart': 0, + }, +} + +TriforceCounts = { + 'plentiful': Decimal(2.00), + 'balanced': Decimal(1.50), + 'scarce': Decimal(1.25), + 'minimal': Decimal(1.00), +} + +DT_vanilla = ( + ['Recovery Heart'] * 2) + +DT_MQ = ( + ['Deku Shield'] * 2 + + ['Rupees (50)']) + +DC_vanilla = ( + ['Rupees (20)']) + +DC_MQ = ( + ['Hylian Shield'] + + ['Rupees (5)']) + +JB_MQ = ( + ['Deku Nuts (5)'] * 4 + + ['Recovery Heart'] + + ['Deku Shield'] + + ['Deku Stick (1)']) + +FoT_vanilla = ( + ['Recovery Heart'] + + ['Arrows (10)'] + + ['Arrows (30)']) + +FoT_MQ = ( + ['Arrows (5)']) + +FiT_vanilla = ( + ['Rupees (200)']) + +FiT_MQ = ( + ['Bombs (20)'] + + ['Hylian Shield']) + +SpT_vanilla = ( + ['Deku Shield'] * 2 + + ['Recovery Heart'] + + ['Bombs (20)']) + +SpT_MQ = ( + ['Rupees (50)'] * 2 + + ['Arrows (30)']) + +ShT_vanilla = ( + ['Arrows (30)']) + +ShT_MQ = ( + ['Arrows (5)'] * 2 + + ['Rupees (20)']) + +BW_vanilla = ( + ['Recovery Heart'] + + ['Bombs (10)'] + + ['Rupees (200)'] + + ['Deku Nuts (5)'] + + ['Deku Nuts (10)'] + + ['Deku Shield'] + + ['Hylian Shield']) + +GTG_vanilla = ( + ['Arrows (30)'] * 3 + + ['Rupees (200)']) + +GTG_MQ = ( + ['Rupee (Treasure Chest Game)'] * 2 + + ['Arrows (10)'] + + ['Rupee (1)'] + + ['Rupees (50)']) + +GC_vanilla = ( + ['Rupees (5)'] * 3 + + ['Arrows (30)']) + +GC_MQ = ( + ['Arrows (10)'] * 2 + + ['Bombs (5)'] + + ['Rupees (20)'] + + ['Recovery Heart']) + + +normal_bottles = [ + 'Bottle', + 'Bottle with Milk', + 'Bottle with Red Potion', + 'Bottle with Green Potion', + 'Bottle with Blue Potion', + 'Bottle with Fairy', + 'Bottle with Fish', + 'Bottle with Bugs', + 'Bottle with Poe', + 'Bottle with Big Poe', + 'Bottle with Blue Fire'] + +bottle_count = 4 + + +dungeon_rewards = [ + 'Kokiri Emerald', + 'Goron Ruby', + 'Zora Sapphire', + 'Forest Medallion', + 'Fire Medallion', + 'Water Medallion', + 'Shadow Medallion', + 'Spirit Medallion', + 'Light Medallion' +] + + +normal_rupees = ( + ['Rupees (5)'] * 13 + + ['Rupees (20)'] * 5 + + ['Rupees (50)'] * 7 + + ['Rupees (200)'] * 3) + +shopsanity_rupees = ( + ['Rupees (5)'] * 2 + + ['Rupees (20)'] * 10 + + ['Rupees (50)'] * 10 + + ['Rupees (200)'] * 5 + + ['Progressive Wallet']) + + +vanilla_shop_items = { + 'KF Shop Item 1': 'Buy Deku Shield', + 'KF Shop Item 2': 'Buy Deku Nut (5)', + 'KF Shop Item 3': 'Buy Deku Nut (10)', + 'KF Shop Item 4': 'Buy Deku Stick (1)', + 'KF Shop Item 5': 'Buy Deku Seeds (30)', + 'KF Shop Item 6': 'Buy Arrows (10)', + 'KF Shop Item 7': 'Buy Arrows (30)', + 'KF Shop Item 8': 'Buy Heart', + 'Kak Potion Shop Item 1': 'Buy Deku Nut (5)', + 'Kak Potion Shop Item 2': 'Buy Fish', + 'Kak Potion Shop Item 3': 'Buy Red Potion [30]', + 'Kak Potion Shop Item 4': 'Buy Green Potion', + 'Kak Potion Shop Item 5': 'Buy Blue Fire', + 'Kak Potion Shop Item 6': 'Buy Bottle Bug', + 'Kak Potion Shop Item 7': 'Buy Poe', + 'Kak Potion Shop Item 8': 'Buy Fairy\'s Spirit', + 'Market Bombchu Shop Item 1': 'Buy Bombchu (5)', + 'Market Bombchu Shop Item 2': 'Buy Bombchu (10)', + 'Market Bombchu Shop Item 3': 'Buy Bombchu (10)', + 'Market Bombchu Shop Item 4': 'Buy Bombchu (10)', + 'Market Bombchu Shop Item 5': 'Buy Bombchu (20)', + 'Market Bombchu Shop Item 6': 'Buy Bombchu (20)', + 'Market Bombchu Shop Item 7': 'Buy Bombchu (20)', + 'Market Bombchu Shop Item 8': 'Buy Bombchu (20)', + 'Market Potion Shop Item 1': 'Buy Green Potion', + 'Market Potion Shop Item 2': 'Buy Blue Fire', + 'Market Potion Shop Item 3': 'Buy Red Potion [30]', + 'Market Potion Shop Item 4': 'Buy Fairy\'s Spirit', + 'Market Potion Shop Item 5': 'Buy Deku Nut (5)', + 'Market Potion Shop Item 6': 'Buy Bottle Bug', + 'Market Potion Shop Item 7': 'Buy Poe', + 'Market Potion Shop Item 8': 'Buy Fish', + 'Market Bazaar Item 1': 'Buy Hylian Shield', + 'Market Bazaar Item 2': 'Buy Bombs (5) [35]', + 'Market Bazaar Item 3': 'Buy Deku Nut (5)', + 'Market Bazaar Item 4': 'Buy Heart', + 'Market Bazaar Item 5': 'Buy Arrows (10)', + 'Market Bazaar Item 6': 'Buy Arrows (50)', + 'Market Bazaar Item 7': 'Buy Deku Stick (1)', + 'Market Bazaar Item 8': 'Buy Arrows (30)', + 'Kak Bazaar Item 1': 'Buy Hylian Shield', + 'Kak Bazaar Item 2': 'Buy Bombs (5) [35]', + 'Kak Bazaar Item 3': 'Buy Deku Nut (5)', + 'Kak Bazaar Item 4': 'Buy Heart', + 'Kak Bazaar Item 5': 'Buy Arrows (10)', + 'Kak Bazaar Item 6': 'Buy Arrows (50)', + 'Kak Bazaar Item 7': 'Buy Deku Stick (1)', + 'Kak Bazaar Item 8': 'Buy Arrows (30)', + 'ZD Shop Item 1': 'Buy Zora Tunic', + 'ZD Shop Item 2': 'Buy Arrows (10)', + 'ZD Shop Item 3': 'Buy Heart', + 'ZD Shop Item 4': 'Buy Arrows (30)', + 'ZD Shop Item 5': 'Buy Deku Nut (5)', + 'ZD Shop Item 6': 'Buy Arrows (50)', + 'ZD Shop Item 7': 'Buy Fish', + 'ZD Shop Item 8': 'Buy Red Potion [50]', + 'GC Shop Item 1': 'Buy Bombs (5) [25]', + 'GC Shop Item 2': 'Buy Bombs (10)', + 'GC Shop Item 3': 'Buy Bombs (20)', + 'GC Shop Item 4': 'Buy Bombs (30)', + 'GC Shop Item 5': 'Buy Goron Tunic', + 'GC Shop Item 6': 'Buy Heart', + 'GC Shop Item 7': 'Buy Red Potion [40]', + 'GC Shop Item 8': 'Buy Heart', +} + + +min_shop_items = ( + ['Buy Deku Shield'] + + ['Buy Hylian Shield'] + + ['Buy Goron Tunic'] + + ['Buy Zora Tunic'] + + ['Buy Deku Nut (5)'] * 2 + ['Buy Deku Nut (10)'] + + ['Buy Deku Stick (1)'] * 2 + + ['Buy Deku Seeds (30)'] + + ['Buy Arrows (10)'] * 2 + ['Buy Arrows (30)'] + ['Buy Arrows (50)'] + + ['Buy Bombchu (5)'] + ['Buy Bombchu (10)'] * 2 + ['Buy Bombchu (20)'] + + ['Buy Bombs (5) [25]'] + ['Buy Bombs (5) [35]'] + ['Buy Bombs (10)'] + ['Buy Bombs (20)'] + + ['Buy Green Potion'] + + ['Buy Red Potion [30]'] + + ['Buy Blue Fire'] + + ['Buy Fairy\'s Spirit'] + + ['Buy Bottle Bug'] + + ['Buy Fish']) + + +vanilla_deku_scrubs = { + 'ZR Deku Scrub Grotto Rear': 'Buy Red Potion [30]', + 'ZR Deku Scrub Grotto Front': 'Buy Green Potion', + 'SFM Deku Scrub Grotto Rear': 'Buy Red Potion [30]', + 'SFM Deku Scrub Grotto Front': 'Buy Green Potion', + 'LH Deku Scrub Grotto Left': 'Buy Deku Nut (5)', + 'LH Deku Scrub Grotto Right': 'Buy Bombs (5) [35]', + 'LH Deku Scrub Grotto Center': 'Buy Arrows (30)', + 'GV Deku Scrub Grotto Rear': 'Buy Red Potion [30]', + 'GV Deku Scrub Grotto Front': 'Buy Green Potion', + 'LW Deku Scrub Near Deku Theater Right': 'Buy Deku Nut (5)', + 'LW Deku Scrub Near Deku Theater Left': 'Buy Deku Stick (1)', + 'LW Deku Scrub Grotto Rear': 'Buy Arrows (30)', + 'Colossus Deku Scrub Grotto Rear': 'Buy Red Potion [30]', + 'Colossus Deku Scrub Grotto Front': 'Buy Green Potion', + 'DMC Deku Scrub': 'Buy Bombs (5) [35]', + 'DMC Deku Scrub Grotto Left': 'Buy Deku Nut (5)', + 'DMC Deku Scrub Grotto Right': 'Buy Bombs (5) [35]', + 'DMC Deku Scrub Grotto Center': 'Buy Arrows (30)', + 'GC Deku Scrub Grotto Left': 'Buy Deku Nut (5)', + 'GC Deku Scrub Grotto Right': 'Buy Bombs (5) [35]', + 'GC Deku Scrub Grotto Center': 'Buy Arrows (30)', + 'LLR Deku Scrub Grotto Left': 'Buy Deku Nut (5)', + 'LLR Deku Scrub Grotto Right': 'Buy Bombs (5) [35]', + 'LLR Deku Scrub Grotto Center': 'Buy Arrows (30)', +} + + +deku_scrubs_items = ( + ['Deku Nuts (5)'] * 5 + + ['Deku Stick (1)'] + + ['Bombs (5)'] * 5 + + ['Recovery Heart'] * 4 + + ['Rupees (5)'] * 4) # ['Green Potion'] + + +songlist = [ + 'Zeldas Lullaby', + 'Eponas Song', + 'Suns Song', + 'Sarias Song', + 'Song of Time', + 'Song of Storms', + 'Minuet of Forest', + 'Prelude of Light', + 'Bolero of Fire', + 'Serenade of Water', + 'Nocturne of Shadow', + 'Requiem of Spirit'] + + +skulltula_locations = ([ + 'KF GS Know It All House', + 'KF GS Bean Patch', + 'KF GS House of Twins', + 'LW GS Bean Patch Near Bridge', + 'LW GS Bean Patch Near Theater', + 'LW GS Above Theater', + 'SFM GS', + 'HF GS Near Kak Grotto', + 'HF GS Cow Grotto', + 'Market GS Guard House', + 'HC GS Tree', + 'HC GS Storms Grotto', + 'OGC GS', + 'LLR GS Tree', + 'LLR GS Rain Shed', + 'LLR GS House Window', + 'LLR GS Back Wall', + 'Kak GS House Under Construction', + 'Kak GS Skulltula House', + 'Kak GS Guards House', + 'Kak GS Tree', + 'Kak GS Watchtower', + 'Kak GS Above Impas House', + 'Graveyard GS Wall', + 'Graveyard GS Bean Patch', + 'DMT GS Bean Patch', + 'DMT GS Near Kak', + 'DMT GS Falling Rocks Path', + 'DMT GS Above Dodongos Cavern', + 'GC GS Boulder Maze', + 'GC GS Center Platform', + 'DMC GS Crate', + 'DMC GS Bean Patch', + 'ZR GS Ladder', + 'ZR GS Tree', + 'ZR GS Near Raised Grottos', + 'ZR GS Above Bridge', + 'ZD GS Frozen Waterfall', + 'ZF GS Tree', + 'ZF GS Above the Log', + 'ZF GS Hidden Cave', + 'LH GS Bean Patch', + 'LH GS Lab Wall', + 'LH GS Small Island', + 'LH GS Tree', + 'LH GS Lab Crate', + 'GV GS Small Bridge', + 'GV GS Bean Patch', + 'GV GS Behind Tent', + 'GV GS Pillar', + 'GF GS Archery Range', + 'GF GS Top Floor', + 'Wasteland GS', + 'Colossus GS Bean Patch', + 'Colossus GS Tree', + 'Colossus GS Hill']) + + +tradeitems = ( + 'Pocket Egg', + 'Pocket Cucco', + 'Cojiro', + 'Odd Mushroom', + 'Poachers Saw', + 'Broken Sword', + 'Prescription', + 'Eyeball Frog', + 'Eyedrops', + 'Claim Check') + +tradeitemoptions = ( + 'pocket_egg', + 'pocket_cucco', + 'cojiro', + 'odd_mushroom', + 'poachers_saw', + 'broken_sword', + 'prescription', + 'eyeball_frog', + 'eyedrops', + 'claim_check') + + +fixedlocations = { + 'Ganon': 'Triforce', + 'Pierre': 'Scarecrow Song', + 'Deliver Rutos Letter': 'Deliver Letter', + 'Master Sword Pedestal': 'Time Travel', + 'Market Bombchu Bowling Bombchus': 'Bombchu Drop', +} + +droplocations = { + 'Deku Baba Sticks': 'Deku Stick Drop', + 'Deku Baba Nuts': 'Deku Nut Drop', + 'Stick Pot': 'Deku Stick Drop', + 'Nut Pot': 'Deku Nut Drop', + 'Nut Crate': 'Deku Nut Drop', + 'Blue Fire': 'Blue Fire', + 'Lone Fish': 'Fish', + 'Fish Group': 'Fish', + 'Bug Rock': 'Bugs', + 'Bug Shrub': 'Bugs', + 'Wandering Bugs': 'Bugs', + 'Fairy Pot': 'Fairy', + 'Free Fairies': 'Fairy', + 'Wall Fairy': 'Fairy', + 'Butterfly Fairy': 'Fairy', + 'Gossip Stone Fairy': 'Fairy', + 'Bean Plant Fairy': 'Fairy', + 'Fairy Pond': 'Fairy', + 'Big Poe Kill': 'Big Poe', +} + +vanillaBK = { + 'Fire Temple Boss Key Chest': 'Boss Key (Fire Temple)', + 'Shadow Temple Boss Key Chest': 'Boss Key (Shadow Temple)', + 'Spirit Temple Boss Key Chest': 'Boss Key (Spirit Temple)', + 'Water Temple Boss Key Chest': 'Boss Key (Water Temple)', + 'Forest Temple Boss Key Chest': 'Boss Key (Forest Temple)', + + 'Fire Temple MQ Boss Key Chest': 'Boss Key (Fire Temple)', + 'Shadow Temple MQ Boss Key Chest': 'Boss Key (Shadow Temple)', + 'Spirit Temple MQ Boss Key Chest': 'Boss Key (Spirit Temple)', + 'Water Temple MQ Boss Key Chest': 'Boss Key (Water Temple)', + 'Forest Temple MQ Boss Key Chest': 'Boss Key (Forest Temple)', +} + +vanillaMC = { + 'Bottom of the Well Compass Chest': 'Compass (Bottom of the Well)', + 'Deku Tree Compass Chest': 'Compass (Deku Tree)', + 'Dodongos Cavern Compass Chest': 'Compass (Dodongos Cavern)', + 'Fire Temple Compass Chest': 'Compass (Fire Temple)', + 'Forest Temple Blue Poe Chest': 'Compass (Forest Temple)', + 'Ice Cavern Compass Chest': 'Compass (Ice Cavern)', + 'Jabu Jabus Belly Compass Chest': 'Compass (Jabu Jabus Belly)', + 'Shadow Temple Compass Chest': 'Compass (Shadow Temple)', + 'Spirit Temple Compass Chest': 'Compass (Spirit Temple)', + 'Water Temple Compass Chest': 'Compass (Water Temple)', + + 'Bottom of the Well Map Chest': 'Map (Bottom of the Well)', + 'Deku Tree Map Chest': 'Map (Deku Tree)', + 'Dodongos Cavern Map Chest': 'Map (Dodongos Cavern)', + 'Fire Temple Map Chest': 'Map (Fire Temple)', + 'Forest Temple Map Chest': 'Map (Forest Temple)', + 'Ice Cavern Map Chest': 'Map (Ice Cavern)', + 'Jabu Jabus Belly Map Chest': 'Map (Jabu Jabus Belly)', + 'Shadow Temple Map Chest': 'Map (Shadow Temple)', + 'Spirit Temple Map Chest': 'Map (Spirit Temple)', + 'Water Temple Map Chest': 'Map (Water Temple)', + + 'Bottom of the Well MQ Compass Chest': 'Compass (Bottom of the Well)', + 'Deku Tree MQ Compass Chest': 'Compass (Deku Tree)', + 'Dodongos Cavern MQ Compass Chest': 'Compass (Dodongos Cavern)', + 'Fire Temple MQ Compass Chest': 'Compass (Fire Temple)', + 'Forest Temple MQ Compass Chest': 'Compass (Forest Temple)', + 'Ice Cavern MQ Compass Chest': 'Compass (Ice Cavern)', + 'Jabu Jabus Belly MQ Compass Chest': 'Compass (Jabu Jabus Belly)', + 'Shadow Temple MQ Compass Chest': 'Compass (Shadow Temple)', + 'Spirit Temple MQ Compass Chest': 'Compass (Spirit Temple)', + 'Water Temple MQ Compass Chest': 'Compass (Water Temple)', + + 'Bottom of the Well MQ Map Chest': 'Map (Bottom of the Well)', + 'Deku Tree MQ Map Chest': 'Map (Deku Tree)', + 'Dodongos Cavern MQ Map Chest': 'Map (Dodongos Cavern)', + 'Fire Temple MQ Map Chest': 'Map (Fire Temple)', + 'Forest Temple MQ Map Chest': 'Map (Forest Temple)', + 'Ice Cavern MQ Map Chest': 'Map (Ice Cavern)', + 'Jabu Jabus Belly MQ Map Chest': 'Map (Jabu Jabus Belly)', + 'Shadow Temple MQ Map Chest': 'Map (Shadow Temple)', + 'Spirit Temple MQ Map Chest': 'Map (Spirit Temple)', + 'Water Temple MQ Map Chest': 'Map (Water Temple)', +} + +vanillaSK = { + 'Bottom of the Well Front Left Fake Wall Chest': 'Small Key (Bottom of the Well)', + 'Bottom of the Well Right Bottom Fake Wall Chest': 'Small Key (Bottom of the Well)', + 'Bottom of the Well Freestanding Key': 'Small Key (Bottom of the Well)', + 'Fire Temple Big Lava Room Blocked Door Chest': 'Small Key (Fire Temple)', + 'Fire Temple Big Lava Room Lower Open Door Chest': 'Small Key (Fire Temple)', + 'Fire Temple Boulder Maze Shortcut Chest': 'Small Key (Fire Temple)', + 'Fire Temple Boulder Maze Lower Chest': 'Small Key (Fire Temple)', + 'Fire Temple Boulder Maze Side Room Chest': 'Small Key (Fire Temple)', + 'Fire Temple Boulder Maze Upper Chest': 'Small Key (Fire Temple)', + 'Fire Temple Near Boss Chest': 'Small Key (Fire Temple)', + 'Fire Temple Highest Goron Chest': 'Small Key (Fire Temple)', + 'Forest Temple First Stalfos Chest': 'Small Key (Forest Temple)', + 'Forest Temple First Room Chest': 'Small Key (Forest Temple)', + 'Forest Temple Floormaster Chest': 'Small Key (Forest Temple)', + 'Forest Temple Red Poe Chest': 'Small Key (Forest Temple)', + 'Forest Temple Well Chest': 'Small Key (Forest Temple)', + 'Ganons Castle Light Trial Invisible Enemies Chest': 'Small Key (Ganons Castle)', + 'Ganons Castle Light Trial Lullaby Chest': 'Small Key (Ganons Castle)', + 'Gerudo Training Grounds Beamos Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Eye Statue Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Hammer Room Switch Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Heavy Block Third Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Hidden Ceiling Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Near Scarecrow Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Stalfos Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Underwater Silver Rupee Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds Freestanding Key': 'Small Key (Gerudo Training Grounds)', + 'Shadow Temple After Wind Hidden Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple Early Silver Rupee Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple Falling Spikes Switch Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple Invisible Floormaster Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple Freestanding Key': 'Small Key (Shadow Temple)', + 'Spirit Temple Child Early Torches Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple Early Adult Right Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple Near Four Armos Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple Statue Room Hand Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple Sun Block Room Chest': 'Small Key (Spirit Temple)', + 'Water Temple Central Bow Target Chest': 'Small Key (Water Temple)', + 'Water Temple Central Pillar Chest': 'Small Key (Water Temple)', + 'Water Temple Cracked Wall Chest': 'Small Key (Water Temple)', + 'Water Temple Dragon Chest': 'Small Key (Water Temple)', + 'Water Temple River Chest': 'Small Key (Water Temple)', + 'Water Temple Torches Chest': 'Small Key (Water Temple)', + + 'Bottom of the Well MQ Dead Hand Freestanding Key': 'Small Key (Bottom of the Well)', + 'Bottom of the Well MQ East Inner Room Freestanding Key': 'Small Key (Bottom of the Well)', + 'Fire Temple MQ Big Lava Room Blocked Door Chest': 'Small Key (Fire Temple)', + 'Fire Temple MQ Near Boss Chest': 'Small Key (Fire Temple)', + 'Fire Temple MQ Lizalfos Maze Side Room Chest': 'Small Key (Fire Temple)', + 'Fire Temple MQ Chest On Fire': 'Small Key (Fire Temple)', + 'Fire Temple MQ Freestanding Key': 'Small Key (Fire Temple)', + 'Forest Temple MQ Wolfos Chest': 'Small Key (Forest Temple)', + 'Forest Temple MQ First Room Chest': 'Small Key (Forest Temple)', + 'Forest Temple MQ Raised Island Courtyard Lower Chest': 'Small Key (Forest Temple)', + 'Forest Temple MQ Raised Island Courtyard Upper Chest': 'Small Key (Forest Temple)', + 'Forest Temple MQ Redead Chest': 'Small Key (Forest Temple)', + 'Forest Temple MQ Well Chest': 'Small Key (Forest Temple)', + 'Ganons Castle MQ Shadow Trial Eye Switch Chest': 'Small Key (Ganons Castle)', + 'Ganons Castle MQ Spirit Trial Sun Back Left Chest': 'Small Key (Ganons Castle)', + 'Ganons Castle MQ Forest Trial Freestanding Key': 'Small Key (Ganons Castle)', + 'Gerudo Training Grounds MQ Dinolfos Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds MQ Flame Circle Chest': 'Small Key (Gerudo Training Grounds)', + 'Gerudo Training Grounds MQ Underwater Silver Rupee Chest': 'Small Key (Gerudo Training Grounds)', + 'Shadow Temple MQ Falling Spikes Switch Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple MQ Invisible Blades Invisible Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple MQ Early Gibdos Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple MQ Near Ship Invisible Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple MQ Wind Hint Chest': 'Small Key (Shadow Temple)', + 'Shadow Temple MQ Freestanding Key': 'Small Key (Shadow Temple)', + 'Spirit Temple MQ Child Hammer Switch Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple MQ Child Climb South Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple MQ Map Room Enemy Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple MQ Entrance Back Left Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple MQ Entrance Front Right Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple MQ Mirror Puzzle Invisible Chest': 'Small Key (Spirit Temple)', + 'Spirit Temple MQ Silver Block Hallway Chest': 'Small Key (Spirit Temple)', + 'Water Temple MQ Central Pillar Chest': 'Small Key (Water Temple)', + 'Water Temple MQ Freestanding Key': 'Small Key (Water Temple)', +} + +junk_pool_base = [ + ('Bombs (5)', 8), + ('Bombs (10)', 2), + ('Arrows (5)', 8), + ('Arrows (10)', 2), + ('Deku Stick (1)', 5), + ('Deku Nuts (5)', 5), + ('Deku Seeds (30)', 5), + ('Rupees (5)', 10), + ('Rupees (20)', 4), + ('Rupees (50)', 1), +] + +pending_junk_pool = [] +junk_pool = [] + + +remove_junk_items = [ + 'Bombs (5)', + 'Deku Nuts (5)', + 'Deku Stick (1)', + 'Recovery Heart', + 'Arrows (5)', + 'Arrows (10)', + 'Arrows (30)', + 'Rupees (5)', + 'Rupees (20)', + 'Rupees (50)', + 'Rupees (200)', + 'Deku Nuts (10)', + 'Bombs (10)', + 'Bombs (20)', + 'Deku Seeds (30)', + 'Ice Trap', +] +remove_junk_set = set(remove_junk_items) + +exclude_from_major = [ + 'Deliver Letter', + 'Sell Big Poe', + 'Magic Bean', + 'Zeldas Letter', + 'Bombchus (5)', + 'Bombchus (10)', + 'Bombchus (20)', + 'Odd Potion', + 'Triforce Piece' +] + +item_groups = { + 'Junk': remove_junk_items, + 'JunkSong': ('Prelude of Light', 'Serenade of Water'), + 'AdultTrade': tradeitems, + 'Bottle': normal_bottles, + 'Spell': ('Dins Fire', 'Farores Wind', 'Nayrus Love'), + 'Shield': ('Deku Shield', 'Hylian Shield'), + 'Song': songlist, + 'NonWarpSong': songlist[0:6], + 'WarpSong': songlist[6:], + 'HealthUpgrade': ('Heart Container', 'Piece of Heart'), + 'ProgressItem': [name for (name, data) in item_table.items() if data[0] == 'Item' and data[1]], + 'MajorItem': [name for (name, data) in item_table.items() if (data[0] == 'Item' or data[0] == 'Song') and data[1] and name not in exclude_from_major], + 'DungeonReward': dungeon_rewards, + + 'ForestFireWater': ('Forest Medallion', 'Fire Medallion', 'Water Medallion'), + 'FireWater': ('Fire Medallion', 'Water Medallion'), +} + +random = None + + +def get_junk_pool(ootworld): + junk_pool[:] = list(junk_pool_base) + if ootworld.junk_ice_traps == 'on': + junk_pool.append(('Ice Trap', 10)) + elif ootworld.junk_ice_traps in ['mayhem', 'onslaught']: + junk_pool[:] = [('Ice Trap', 1)] + return junk_pool + + +def get_junk_item(count=1, pool=None, plando_pool=None): + global random + + if count < 1: + raise ValueError("get_junk_item argument 'count' must be greater than 0.") + + return_pool = [] + if pending_junk_pool: + pending_count = min(len(pending_junk_pool), count) + return_pool = [pending_junk_pool.pop() for _ in range(pending_count)] + count -= pending_count + + if pool and plando_pool: + jw_list = [(junk, weight) for (junk, weight) in junk_pool + if junk not in plando_pool or pool.count(junk) < plando_pool[junk].count] + try: + junk_items, junk_weights = zip(*jw_list) + except ValueError: + raise RuntimeError("Not enough junk is available in the item pool to replace removed items.") + else: + junk_items, junk_weights = zip(*junk_pool) + return_pool.extend(random.choices(junk_items, weights=junk_weights, k=count)) + + return return_pool + + +def replace_max_item(items, item, max): + count = 0 + for i,val in enumerate(items): + if val == item: + if count >= max: + items[i] = get_junk_item()[0] + count += 1 + + +def generate_itempool(ootworld): + world = ootworld.world + player = ootworld.player + global random + random = world.random + + junk_pool = get_junk_pool(ootworld) + + fixed_locations = list(filter(lambda loc: loc.name in fixedlocations, ootworld.get_locations())) + for location in fixed_locations: + item = fixedlocations[location.name] + world.push_item(location, ootworld.create_item(item), collect=False) + location.locked = True + + drop_locations = list(filter(lambda loc: loc.type == 'Drop', ootworld.get_locations())) + for drop_location in drop_locations: + item = droplocations[drop_location.name] + world.push_item(drop_location, ootworld.create_item(item), collect=False) + drop_location.locked = True + + # set up item pool + (pool, placed_items, skip_in_spoiler_locations) = get_pool_core(ootworld) + ootworld.itempool = [ootworld.create_item(item) for item in pool] + for (location_name, item) in placed_items.items(): + location = world.get_location(location_name, player) + world.push_item(location, ootworld.create_item(item), collect=False) + location.locked = True + location.event = True # make sure it's checked during fill + if location_name in skip_in_spoiler_locations: + location.show_in_spoiler = False + + + +# def try_collect_heart_container(world, pool): +# if 'Heart Container' in pool: +# pool.remove('Heart Container') +# pool.extend(get_junk_item()) +# world.state.collect(ItemFactory('Heart Container')) +# return True +# return False + + +# def try_collect_pieces_of_heart(world, pool): +# n = pool.count('Piece of Heart') + pool.count('Piece of Heart (Treasure Chest Game)') +# if n >= 4: +# for i in range(4): +# if 'Piece of Heart' in pool: +# pool.remove('Piece of Heart') +# world.state.collect(ItemFactory('Piece of Heart')) +# else: +# pool.remove('Piece of Heart (Treasure Chest Game)') +# world.state.collect(ItemFactory('Piece of Heart (Treasure Chest Game)')) +# pool.extend(get_junk_item()) +# return True +# return False + + +# def collect_pieces_of_heart(world, pool): +# success = try_collect_pieces_of_heart(world, pool) +# if not success: +# try_collect_heart_container(world, pool) + + +# def collect_heart_container(world, pool): +# success = try_collect_heart_container(world, pool) +# if not success: +# try_collect_pieces_of_heart(world, pool) + + +def get_pool_core(world): + global random + + pool = [] + placed_items = { + 'HC Zeldas Letter': 'Zeldas Letter', + } + skip_in_spoiler_locations = [] + + if world.shuffle_kokiri_sword: + pool.append('Kokiri Sword') + else: + placed_items['KF Kokiri Sword Chest'] = 'Kokiri Sword' + + ruto_bottles = 1 + if world.zora_fountain == 'open': + ruto_bottles = 0 + elif world.item_pool_value == 'plentiful': + ruto_bottles += 1 + + if world.skip_child_zelda: + placed_items['HC Malon Egg'] = 'Recovery Heart' + skip_in_spoiler_locations.append('HC Malon Egg') + elif world.shuffle_weird_egg: + pool.append('Weird Egg') + else: + placed_items['HC Malon Egg'] = 'Weird Egg' + + if world.shuffle_ocarinas: + pool.extend(['Ocarina'] * 2) + if world.item_pool_value == 'plentiful': + pending_junk_pool.append('Ocarina') + else: + placed_items['LW Gift from Saria'] = 'Ocarina' + placed_items['HF Ocarina of Time Item'] = 'Ocarina' + + if world.shuffle_cows: + pool.extend(get_junk_item(10 if world.dungeon_mq['Jabu Jabus Belly'] else 9)) + else: + cow_locations = ['LLR Stables Left Cow', 'LLR Stables Right Cow', 'LLR Tower Left Cow', 'LLR Tower Right Cow', + 'KF Links House Cow', 'Kak Impas House Cow', 'GV Cow', 'DMT Cow Grotto Cow', 'HF Cow Grotto Cow'] + if world.dungeon_mq['Jabu Jabus Belly']: + cow_locations.append('Jabu Jabus Belly MQ Cow') + for loc in cow_locations: + placed_items[loc] = 'Milk' + skip_in_spoiler_locations.append(loc) + + if world.shuffle_beans: + pool.append('Magic Bean Pack') + if world.item_pool_value == 'plentiful': + pending_junk_pool.append('Magic Bean Pack') + else: + placed_items['ZR Magic Bean Salesman'] = 'Magic Bean' + skip_in_spoiler_locations.append('ZR Magic Bean Salesman') + + if world.shuffle_medigoron_carpet_salesman: + pool.append('Giants Knife') + else: + placed_items['GC Medigoron'] = 'Giants Knife' + skip_in_spoiler_locations.append('GC Medigoron') + + if world.dungeon_mq['Deku Tree']: + skulltula_locations_final = skulltula_locations + [ + 'Deku Tree MQ GS Lobby', + 'Deku Tree MQ GS Compass Room', + 'Deku Tree MQ GS Basement Graves Room', + 'Deku Tree MQ GS Basement Back Room'] + else: + skulltula_locations_final = skulltula_locations + [ + 'Deku Tree GS Compass Room', + 'Deku Tree GS Basement Vines', + 'Deku Tree GS Basement Gate', + 'Deku Tree GS Basement Back Room'] + if world.dungeon_mq['Dodongos Cavern']: + skulltula_locations_final.extend([ + 'Dodongos Cavern MQ GS Scrub Room', + 'Dodongos Cavern MQ GS Song of Time Block Room', + 'Dodongos Cavern MQ GS Lizalfos Room', + 'Dodongos Cavern MQ GS Larvae Room', + 'Dodongos Cavern MQ GS Back Area']) + else: + skulltula_locations_final.extend([ + 'Dodongos Cavern GS Side Room Near Lower Lizalfos', + 'Dodongos Cavern GS Vines Above Stairs', + 'Dodongos Cavern GS Back Room', + 'Dodongos Cavern GS Alcove Above Stairs', + 'Dodongos Cavern GS Scarecrow']) + if world.dungeon_mq['Jabu Jabus Belly']: + skulltula_locations_final.extend([ + 'Jabu Jabus Belly MQ GS Tailpasaran Room', + 'Jabu Jabus Belly MQ GS Invisible Enemies Room', + 'Jabu Jabus Belly MQ GS Boomerang Chest Room', + 'Jabu Jabus Belly MQ GS Near Boss']) + else: + skulltula_locations_final.extend([ + 'Jabu Jabus Belly GS Water Switch Room', + 'Jabu Jabus Belly GS Lobby Basement Lower', + 'Jabu Jabus Belly GS Lobby Basement Upper', + 'Jabu Jabus Belly GS Near Boss']) + if world.dungeon_mq['Forest Temple']: + skulltula_locations_final.extend([ + 'Forest Temple MQ GS First Hallway', + 'Forest Temple MQ GS Block Push Room', + 'Forest Temple MQ GS Raised Island Courtyard', + 'Forest Temple MQ GS Level Island Courtyard', + 'Forest Temple MQ GS Well']) + else: + skulltula_locations_final.extend([ + 'Forest Temple GS First Room', + 'Forest Temple GS Lobby', + 'Forest Temple GS Raised Island Courtyard', + 'Forest Temple GS Level Island Courtyard', + 'Forest Temple GS Basement']) + if world.dungeon_mq['Fire Temple']: + skulltula_locations_final.extend([ + 'Fire Temple MQ GS Above Fire Wall Maze', + 'Fire Temple MQ GS Fire Wall Maze Center', + 'Fire Temple MQ GS Big Lava Room Open Door', + 'Fire Temple MQ GS Fire Wall Maze Side Room', + 'Fire Temple MQ GS Skull On Fire']) + else: + skulltula_locations_final.extend([ + 'Fire Temple GS Song of Time Room', + 'Fire Temple GS Boulder Maze', + 'Fire Temple GS Scarecrow Climb', + 'Fire Temple GS Scarecrow Top', + 'Fire Temple GS Boss Key Loop']) + if world.dungeon_mq['Water Temple']: + skulltula_locations_final.extend([ + 'Water Temple MQ GS Before Upper Water Switch', + 'Water Temple MQ GS Freestanding Key Area', + 'Water Temple MQ GS Lizalfos Hallway', + 'Water Temple MQ GS River', + 'Water Temple MQ GS Triple Wall Torch']) + else: + skulltula_locations_final.extend([ + 'Water Temple GS Behind Gate', + 'Water Temple GS River', + 'Water Temple GS Falling Platform Room', + 'Water Temple GS Central Pillar', + 'Water Temple GS Near Boss Key Chest']) + if world.dungeon_mq['Spirit Temple']: + skulltula_locations_final.extend([ + 'Spirit Temple MQ GS Symphony Room', + 'Spirit Temple MQ GS Leever Room', + 'Spirit Temple MQ GS Nine Thrones Room West', + 'Spirit Temple MQ GS Nine Thrones Room North', + 'Spirit Temple MQ GS Sun Block Room']) + else: + skulltula_locations_final.extend([ + 'Spirit Temple GS Metal Fence', + 'Spirit Temple GS Sun on Floor Room', + 'Spirit Temple GS Hall After Sun Block Room', + 'Spirit Temple GS Boulder Room', + 'Spirit Temple GS Lobby']) + if world.dungeon_mq['Shadow Temple']: + skulltula_locations_final.extend([ + 'Shadow Temple MQ GS Falling Spikes Room', + 'Shadow Temple MQ GS Wind Hint Room', + 'Shadow Temple MQ GS After Wind', + 'Shadow Temple MQ GS After Ship', + 'Shadow Temple MQ GS Near Boss']) + else: + skulltula_locations_final.extend([ + 'Shadow Temple GS Like Like Room', + 'Shadow Temple GS Falling Spikes Room', + 'Shadow Temple GS Single Giant Pot', + 'Shadow Temple GS Near Ship', + 'Shadow Temple GS Triple Giant Pot']) + if world.dungeon_mq['Bottom of the Well']: + skulltula_locations_final.extend([ + 'Bottom of the Well MQ GS Basement', + 'Bottom of the Well MQ GS Coffin Room', + 'Bottom of the Well MQ GS West Inner Room']) + else: + skulltula_locations_final.extend([ + 'Bottom of the Well GS West Inner Room', + 'Bottom of the Well GS East Inner Room', + 'Bottom of the Well GS Like Like Cage']) + if world.dungeon_mq['Ice Cavern']: + skulltula_locations_final.extend([ + 'Ice Cavern MQ GS Scarecrow', + 'Ice Cavern MQ GS Ice Block', + 'Ice Cavern MQ GS Red Ice']) + else: + skulltula_locations_final.extend([ + 'Ice Cavern GS Spinning Scythe Room', + 'Ice Cavern GS Heart Piece Room', + 'Ice Cavern GS Push Block Room']) + if world.tokensanity == 'off': + for location in skulltula_locations_final: + placed_items[location] = 'Gold Skulltula Token' + skip_in_spoiler_locations.append(location) + elif world.tokensanity == 'dungeons': + for location in skulltula_locations_final: + if world.get_location(location).scene >= 0x0A: + placed_items[location] = 'Gold Skulltula Token' + skip_in_spoiler_locations.append(location) + else: + pool.append('Gold Skulltula Token') + elif world.tokensanity == 'overworld': + for location in skulltula_locations_final: + if world.get_location(location).scene < 0x0A: + placed_items[location] = 'Gold Skulltula Token' + skip_in_spoiler_locations.append(location) + else: + pool.append('Gold Skulltula Token') + else: + pool.extend(['Gold Skulltula Token'] * 100) + + + if world.bombchus_in_logic: + pool.extend(['Bombchus'] * 4) + if world.dungeon_mq['Jabu Jabus Belly']: + pool.extend(['Bombchus']) + if world.dungeon_mq['Spirit Temple']: + pool.extend(['Bombchus'] * 2) + if not world.dungeon_mq['Bottom of the Well']: + pool.extend(['Bombchus']) + if world.dungeon_mq['Gerudo Training Grounds']: + pool.extend(['Bombchus']) + if world.shuffle_medigoron_carpet_salesman: + pool.append('Bombchus') + + else: + pool.extend(['Bombchus (5)'] + ['Bombchus (10)'] * 2) + if world.dungeon_mq['Jabu Jabus Belly']: + pool.extend(['Bombchus (10)']) + if world.dungeon_mq['Spirit Temple']: + pool.extend(['Bombchus (10)'] * 2) + if not world.dungeon_mq['Bottom of the Well']: + pool.extend(['Bombchus (10)']) + if world.dungeon_mq['Gerudo Training Grounds']: + pool.extend(['Bombchus (10)']) + if world.dungeon_mq['Ganons Castle']: + pool.extend(['Bombchus (10)']) + else: + pool.extend(['Bombchus (20)']) + if world.shuffle_medigoron_carpet_salesman: + pool.append('Bombchus (10)') + + if not world.shuffle_medigoron_carpet_salesman: + placed_items['Wasteland Bombchu Salesman'] = 'Bombchus (10)' + skip_in_spoiler_locations.append('Wasteland Bombchu Salesman') + + pool.extend(['Ice Trap']) + if not world.dungeon_mq['Gerudo Training Grounds']: + pool.extend(['Ice Trap']) + if not world.dungeon_mq['Ganons Castle']: + pool.extend(['Ice Trap'] * 4) + + if world.gerudo_fortress == 'open': + placed_items['GF North F1 Carpenter'] = 'Recovery Heart' + placed_items['GF North F2 Carpenter'] = 'Recovery Heart' + placed_items['GF South F1 Carpenter'] = 'Recovery Heart' + placed_items['GF South F2 Carpenter'] = 'Recovery Heart' + skip_in_spoiler_locations.extend(['GF North F1 Carpenter', 'GF North F2 Carpenter', 'GF South F1 Carpenter', 'GF South F2 Carpenter']) + elif world.shuffle_fortresskeys in ['any_dungeon', 'overworld', 'keysanity']: + if world.gerudo_fortress == 'fast': + pool.append('Small Key (Gerudo Fortress)') + placed_items['GF North F2 Carpenter'] = 'Recovery Heart' + placed_items['GF South F1 Carpenter'] = 'Recovery Heart' + placed_items['GF South F2 Carpenter'] = 'Recovery Heart' + skip_in_spoiler_locations.extend(['GF North F2 Carpenter', 'GF South F1 Carpenter', 'GF South F2 Carpenter']) + else: + pool.extend(['Small Key (Gerudo Fortress)'] * 4) + if world.item_pool_value == 'plentiful': + pending_junk_pool.append('Small Key (Gerudo Fortress)') + else: + if world.gerudo_fortress == 'fast': + placed_items['GF North F1 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['GF North F2 Carpenter'] = 'Recovery Heart' + placed_items['GF South F1 Carpenter'] = 'Recovery Heart' + placed_items['GF South F2 Carpenter'] = 'Recovery Heart' + skip_in_spoiler_locations.extend(['GF North F2 Carpenter', 'GF South F1 Carpenter', 'GF South F2 Carpenter']) + else: + placed_items['GF North F1 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['GF North F2 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['GF South F1 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['GF South F2 Carpenter'] = 'Small Key (Gerudo Fortress)' + + if world.shuffle_gerudo_card and world.gerudo_fortress != 'open': + pool.append('Gerudo Membership Card') + elif world.shuffle_gerudo_card: + pending_junk_pool.append('Gerudo Membership Card') + placed_items['GF Gerudo Membership Card'] = 'Ice Trap' + skip_in_spoiler_locations.append('GF Gerudo Membership Card') + else: + placed_items['GF Gerudo Membership Card'] = 'Gerudo Membership Card' + if world.shuffle_gerudo_card and world.item_pool_value == 'plentiful': + pending_junk_pool.append('Gerudo Membership Card') + + if world.item_pool_value == 'plentiful' and world.shuffle_smallkeys in ['any_dungeon', 'overworld', 'keysanity']: + pending_junk_pool.append('Small Key (Bottom of the Well)') + pending_junk_pool.append('Small Key (Forest Temple)') + pending_junk_pool.append('Small Key (Fire Temple)') + pending_junk_pool.append('Small Key (Water Temple)') + pending_junk_pool.append('Small Key (Shadow Temple)') + pending_junk_pool.append('Small Key (Spirit Temple)') + pending_junk_pool.append('Small Key (Gerudo Training Grounds)') + pending_junk_pool.append('Small Key (Ganons Castle)') + + if world.item_pool_value == 'plentiful' and world.shuffle_bosskeys in ['any_dungeon', 'overworld', 'keysanity']: + pending_junk_pool.append('Boss Key (Forest Temple)') + pending_junk_pool.append('Boss Key (Fire Temple)') + pending_junk_pool.append('Boss Key (Water Temple)') + pending_junk_pool.append('Boss Key (Shadow Temple)') + pending_junk_pool.append('Boss Key (Spirit Temple)') + + if world.item_pool_value == 'plentiful' and world.shuffle_ganon_bosskey in ['any_dungeon', 'overworld', 'keysanity']: + pending_junk_pool.append('Boss Key (Ganons Castle)') + + if world.shopsanity == 'off': + placed_items.update(vanilla_shop_items) + if world.bombchus_in_logic: + placed_items['KF Shop Item 8'] = 'Buy Bombchu (5)' + placed_items['Market Bazaar Item 4'] = 'Buy Bombchu (5)' + placed_items['Kak Bazaar Item 4'] = 'Buy Bombchu (5)' + pool.extend(normal_rupees) + skip_in_spoiler_locations.extend(vanilla_shop_items.keys()) + if world.bombchus_in_logic: + skip_in_spoiler_locations.remove('KF Shop Item 8') + skip_in_spoiler_locations.remove('Market Bazaar Item 4') + skip_in_spoiler_locations.remove('Kak Bazaar Item 4') + + else: + remain_shop_items = list(vanilla_shop_items.values()) + pool.extend(min_shop_items) + for item in min_shop_items: + remain_shop_items.remove(item) + + shop_slots_count = len(remain_shop_items) + shop_nonitem_count = len(world.shop_prices) + shop_item_count = shop_slots_count - shop_nonitem_count + + pool.extend(random.sample(remain_shop_items, shop_item_count)) + if shop_nonitem_count: + pool.extend(get_junk_item(shop_nonitem_count)) + if world.shopsanity == '0': + pool.extend(normal_rupees) + else: + pool.extend(shopsanity_rupees) + + if world.shuffle_scrubs != 'off': + if world.dungeon_mq['Deku Tree']: + pool.append('Deku Shield') + if world.dungeon_mq['Dodongos Cavern']: + pool.extend(['Deku Stick (1)', 'Deku Shield', 'Recovery Heart']) + else: + pool.extend(['Deku Nuts (5)', 'Deku Stick (1)', 'Deku Shield']) + if not world.dungeon_mq['Jabu Jabus Belly']: + pool.append('Deku Nuts (5)') + if world.dungeon_mq['Ganons Castle']: + pool.extend(['Bombs (5)', 'Recovery Heart', 'Rupees (5)', 'Deku Nuts (5)']) + else: + pool.extend(['Bombs (5)', 'Recovery Heart', 'Rupees (5)']) + pool.extend(deku_scrubs_items) + for _ in range(7): + pool.append('Arrows (30)' if random.randint(0,3) > 0 else 'Deku Seeds (30)') + + else: + if world.dungeon_mq['Deku Tree']: + placed_items['Deku Tree MQ Deku Scrub'] = 'Buy Deku Shield' + skip_in_spoiler_locations.append('Deku Tree MQ Deku Scrub') + if world.dungeon_mq['Dodongos Cavern']: + placed_items['Dodongos Cavern MQ Deku Scrub Lobby Rear'] = 'Buy Deku Stick (1)' + placed_items['Dodongos Cavern MQ Deku Scrub Lobby Front'] = 'Buy Deku Seeds (30)' + placed_items['Dodongos Cavern MQ Deku Scrub Staircase'] = 'Buy Deku Shield' + placed_items['Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos'] = 'Buy Red Potion [30]' + skip_in_spoiler_locations.extend(['Dodongos Cavern MQ Deku Scrub Lobby Rear', + 'Dodongos Cavern MQ Deku Scrub Lobby Front', + 'Dodongos Cavern MQ Deku Scrub Staircase', + 'Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos']) + else: + placed_items['Dodongos Cavern Deku Scrub Near Bomb Bag Left'] = 'Buy Deku Nut (5)' + placed_items['Dodongos Cavern Deku Scrub Side Room Near Dodongos'] = 'Buy Deku Stick (1)' + placed_items['Dodongos Cavern Deku Scrub Near Bomb Bag Right'] = 'Buy Deku Seeds (30)' + placed_items['Dodongos Cavern Deku Scrub Lobby'] = 'Buy Deku Shield' + skip_in_spoiler_locations.extend(['Dodongos Cavern Deku Scrub Near Bomb Bag Left', + 'Dodongos Cavern Deku Scrub Side Room Near Dodongos', + 'Dodongos Cavern Deku Scrub Near Bomb Bag Right', + 'Dodongos Cavern Deku Scrub Lobby']) + if not world.dungeon_mq['Jabu Jabus Belly']: + placed_items['Jabu Jabus Belly Deku Scrub'] = 'Buy Deku Nut (5)' + skip_in_spoiler_locations.append('Jabu Jabus Belly Deku Scrub') + if world.dungeon_mq['Ganons Castle']: + placed_items['Ganons Castle MQ Deku Scrub Right'] = 'Buy Deku Nut (5)' + placed_items['Ganons Castle MQ Deku Scrub Center-Left'] = 'Buy Bombs (5) [35]' + placed_items['Ganons Castle MQ Deku Scrub Center'] = 'Buy Arrows (30)' + placed_items['Ganons Castle MQ Deku Scrub Center-Right'] = 'Buy Red Potion [30]' + placed_items['Ganons Castle MQ Deku Scrub Left'] = 'Buy Green Potion' + skip_in_spoiler_locations.extend(['Ganons Castle MQ Deku Scrub Right', + 'Ganons Castle MQ Deku Scrub Center-Left', + 'Ganons Castle MQ Deku Scrub Center', + 'Ganons Castle MQ Deku Scrub Center-Right', + 'Ganons Castle MQ Deku Scrub Left']) + else: + placed_items['Ganons Castle Deku Scrub Center-Left'] = 'Buy Bombs (5) [35]' + placed_items['Ganons Castle Deku Scrub Center-Right'] = 'Buy Arrows (30)' + placed_items['Ganons Castle Deku Scrub Right'] = 'Buy Red Potion [30]' + placed_items['Ganons Castle Deku Scrub Left'] = 'Buy Green Potion' + skip_in_spoiler_locations.extend(['Ganons Castle Deku Scrub Right', + 'Ganons Castle Deku Scrub Center-Left', + 'Ganons Castle Deku Scrub Center-Right', + 'Ganons Castle Deku Scrub Left']) + placed_items.update(vanilla_deku_scrubs) + skip_in_spoiler_locations.extend(vanilla_deku_scrubs.keys()) + + pool.extend(alwaysitems) + + if world.dungeon_mq['Deku Tree']: + pool.extend(DT_MQ) + else: + pool.extend(DT_vanilla) + if world.dungeon_mq['Dodongos Cavern']: + pool.extend(DC_MQ) + else: + pool.extend(DC_vanilla) + if world.dungeon_mq['Jabu Jabus Belly']: + pool.extend(JB_MQ) + if world.dungeon_mq['Forest Temple']: + pool.extend(FoT_MQ) + else: + pool.extend(FoT_vanilla) + if world.dungeon_mq['Fire Temple']: + pool.extend(FiT_MQ) + else: + pool.extend(FiT_vanilla) + if world.dungeon_mq['Spirit Temple']: + pool.extend(SpT_MQ) + else: + pool.extend(SpT_vanilla) + if world.dungeon_mq['Shadow Temple']: + pool.extend(ShT_MQ) + else: + pool.extend(ShT_vanilla) + if not world.dungeon_mq['Bottom of the Well']: + pool.extend(BW_vanilla) + if world.dungeon_mq['Gerudo Training Grounds']: + pool.extend(GTG_MQ) + else: + pool.extend(GTG_vanilla) + if world.dungeon_mq['Ganons Castle']: + pool.extend(GC_MQ) + else: + pool.extend(GC_vanilla) + + for i in range(bottle_count): + if i >= ruto_bottles: + bottle = random.choice(normal_bottles) + pool.append(bottle) + else: + pool.append('Rutos Letter') + + earliest_trade = tradeitemoptions.index(world.logic_earliest_adult_trade) + latest_trade = tradeitemoptions.index(world.logic_latest_adult_trade) + if earliest_trade > latest_trade: + earliest_trade, latest_trade = latest_trade, earliest_trade + tradeitem = random.choice(tradeitems[earliest_trade:latest_trade+1]) + world.selected_adult_trade_item = tradeitem + pool.append(tradeitem) + + pool.extend(songlist) + if world.shuffle_song_items == 'any' and world.item_pool_value == 'plentiful': + pending_junk_pool.extend(songlist) + + if world.free_scarecrow: + item = world.create_item('Scarecrow Song') + world.world.push_precollected(item) + world.remove_from_start_inventory.append(item.name) + + if world.no_epona_race: + item = world.create_item('Epona') + world.world.push_precollected(item) + world.remove_from_start_inventory.append(item.name) + + if world.shuffle_mapcompass == 'remove' or world.shuffle_mapcompass == 'startwith': + for item in [item for dungeon in world.dungeons for item in dungeon.dungeon_items]: + world.world.push_precollected(item) + world.remove_from_start_inventory.append(item.name) + pool.extend(get_junk_item()) + if world.shuffle_smallkeys == 'remove': + for item in [item for dungeon in world.dungeons for item in dungeon.small_keys]: + world.world.push_precollected(item) + world.remove_from_start_inventory.append(item.name) + pool.extend(get_junk_item()) + if world.shuffle_bosskeys == 'remove': + for item in [item for dungeon in world.dungeons if dungeon.name != 'Ganons Castle' for item in dungeon.boss_key]: + world.world.push_precollected(item) + world.remove_from_start_inventory.append(item.name) + pool.extend(get_junk_item()) + if world.shuffle_ganon_bosskey in ['remove', 'triforce']: + for item in [item for dungeon in world.dungeons if dungeon.name == 'Ganons Castle' for item in dungeon.boss_key]: + world.world.push_precollected(item) + world.remove_from_start_inventory.append(item.name) + pool.extend(get_junk_item()) + + if world.shuffle_mapcompass == 'vanilla': + for location, item in vanillaMC.items(): + try: + world.get_location(location) + placed_items[location] = item + except KeyError: + continue + if world.shuffle_smallkeys == 'vanilla': + for location, item in vanillaSK.items(): + try: + world.get_location(location) + placed_items[location] = item + except KeyError: + continue + # Logic cannot handle vanilla key layout in some dungeons + # this is because vanilla expects the dungeon major item to be + # locked behind the keys, which is not always true in rando. + # We can resolve this by starting with some extra keys + if world.dungeon_mq['Spirit Temple']: + # Yes somehow you need 3 keys. This dungeon is bonkers + world.world.push_precollected(world.create_item('Small Key (Spirit Temple)')) + world.world.push_precollected(world.create_item('Small Key (Spirit Temple)')) + world.world.push_precollected(world.create_item('Small Key (Spirit Temple)')) + #if not world.dungeon_mq['Fire Temple']: + # world.state.collect(ItemFactory('Small Key (Fire Temple)')) + if world.shuffle_bosskeys == 'vanilla': + for location, item in vanillaBK.items(): + try: + world.get_location(location) + placed_items[location] = item + except KeyError: + continue + + + if not world.keysanity and not world.dungeon_mq['Fire Temple']: + item = world.create_item('Small Key (Fire Temple)') + world.world.push_precollected(item) + world.remove_from_start_inventory.append(item.name) + + if world.triforce_hunt: + triforce_count = int((TriforceCounts[world.item_pool_value] * world.triforce_goal).to_integral_value(rounding=ROUND_HALF_UP)) + pending_junk_pool.extend(['Triforce Piece'] * triforce_count) + + if world.shuffle_ganon_bosskey == 'on_lacs': + placed_items['ToT Light Arrows Cutscene'] = 'Boss Key (Ganons Castle)' + elif world.shuffle_ganon_bosskey == 'vanilla': + placed_items['Ganons Tower Boss Key Chest'] = 'Boss Key (Ganons Castle)' + + if world.item_pool_value == 'plentiful': + pool.extend(easy_items) + else: + pool.extend(normal_items) + + if not world.shuffle_kokiri_sword: + replace_max_item(pool, 'Kokiri Sword', 0) + + if world.junk_ice_traps == 'off': + replace_max_item(pool, 'Ice Trap', 0) + elif world.junk_ice_traps == 'onslaught': + for item in [item for item, weight in junk_pool_base] + ['Recovery Heart', 'Bombs (20)', 'Arrows (30)']: + replace_max_item(pool, item, 0) + + for item,max in item_difficulty_max[world.item_pool_value].items(): + replace_max_item(pool, item, max) + + if world.damage_multiplier in ['ohko', 'quadruple'] and world.item_pool_value == 'minimal': + pending_junk_pool.append('Nayrus Love') + + # world.distribution.alter_pool(world, pool) + + # Make sure our pending_junk_pool is empty. If not, remove some random junk here. + if pending_junk_pool: + + remove_junk_pool, _ = zip(*junk_pool_base) + # Omits Rupees (200) and Deku Nuts (10) + remove_junk_pool = list(remove_junk_pool) + ['Recovery Heart', 'Bombs (20)', 'Arrows (30)', 'Ice Trap'] + + junk_candidates = [item for item in pool if item in remove_junk_pool] + while pending_junk_pool: + pending_item = pending_junk_pool.pop() + if not junk_candidates: + raise RuntimeError("Not enough junk exists in item pool for %s to be added." % pending_item) + junk_item = random.choice(junk_candidates) + junk_candidates.remove(junk_item) + pool.remove(junk_item) + pool.append(pending_item) + + return (pool, placed_items, skip_in_spoiler_locations) diff --git a/worlds/oot/Items.py b/worlds/oot/Items.py new file mode 100644 index 00000000..fcdb2237 --- /dev/null +++ b/worlds/oot/Items.py @@ -0,0 +1,414 @@ +import typing + +from BaseClasses import Item + +def oot_data_to_ap_id(data, event): + if event or data[2] is None or data[0] == 'Shop': + return None + offset = 66000 + if data[0] in ['Item', 'BossKey', 'Compass', 'Map', 'SmallKey', 'Token', 'GanonBossKey', 'FortressSmallKey', 'Song']: + return offset + data[2] + else: + raise Exception(f'Unexpected OOT item type found: {data[0]}') + +def ap_id_to_oot_data(ap_id): + offset = 66000 + val = ap_id - offset + try: + return list(filter(lambda d: d[1][0] == 'Item' and d[1][2] == val, item_table.items()))[0] + except IndexError: + raise Exception(f'Could not find desired item ID: {ap_id}') + +class OOTItem(Item): + game: str = "Ocarina of Time" + + def __init__(self, name, player, data, event): + (type, advancement, index, special) = data + adv = True if advancement else False # this looks silly but the table uses True, False, and None + super(OOTItem, self).__init__(name, adv, oot_data_to_ap_id(data, event), player) + self.type = type + self.index = index + self.special = special or {} + self.looks_like_item = None + self.price = special.get('price', None) if special else None + self.internal = False + + # The playthrough calculation calls a function that uses "sweep_for_events(key_only=True)" + # This checks if the item it's looking for is a small key, using the small key property. + # Because of overlapping item fields, this means that OoT small keys are technically counted, unless we do this. + # This causes them to be double-collected during playthrough and generation. + @property + def smallkey(self) -> bool: + return False + + @property + def bigkey(self) -> bool: + return False + + @property + def dungeonitem(self) -> bool: + return self.type in ['SmallKey', 'FortressSmallKey', 'BossKey', 'GanonBossKey', 'Map', 'Compass'] + + + +# Progressive: True -> Advancement +# False -> Priority +# None -> Normal +# Item: (type, Progressive, GetItemID, special), +item_table = { + 'Bombs (5)': ('Item', None, 0x01, None), + 'Deku Nuts (5)': ('Item', None, 0x02, None), + 'Bombchus (10)': ('Item', True, 0x03, None), + 'Boomerang': ('Item', True, 0x06, None), + 'Deku Stick (1)': ('Item', None, 0x07, None), + 'Lens of Truth': ('Item', True, 0x0A, None), + 'Megaton Hammer': ('Item', True, 0x0D, None), + 'Cojiro': ('Item', True, 0x0E, None), + 'Bottle': ('Item', True, 0x0F, {'bottle': float('Inf')}), + 'Bottle with Milk': ('Item', True, 0x14, {'bottle': float('Inf')}), + 'Rutos Letter': ('Item', True, 0x15, None), + 'Deliver Letter': ('Item', True, None, {'bottle': float('Inf')}), + 'Sell Big Poe': ('Item', True, None, {'bottle': float('Inf')}), + 'Magic Bean': ('Item', True, 0x16, None), + 'Skull Mask': ('Item', True, 0x17, None), + 'Spooky Mask': ('Item', None, 0x18, None), + 'Keaton Mask': ('Item', None, 0x1A, None), + 'Bunny Hood': ('Item', None, 0x1B, None), + 'Mask of Truth': ('Item', True, 0x1C, None), + 'Pocket Egg': ('Item', True, 0x1D, None), + 'Pocket Cucco': ('Item', True, 0x1E, None), + 'Odd Mushroom': ('Item', True, 0x1F, None), + 'Odd Potion': ('Item', True, 0x20, None), + 'Poachers Saw': ('Item', True, 0x21, None), + 'Broken Sword': ('Item', True, 0x22, None), + 'Prescription': ('Item', True, 0x23, None), + 'Eyeball Frog': ('Item', True, 0x24, None), + 'Eyedrops': ('Item', True, 0x25, None), + 'Claim Check': ('Item', True, 0x26, None), + 'Kokiri Sword': ('Item', True, 0x27, None), + 'Giants Knife': ('Item', True, 0x28, None), + 'Deku Shield': ('Item', None, 0x29, None), + 'Hylian Shield': ('Item', None, 0x2A, None), + 'Mirror Shield': ('Item', True, 0x2B, None), + 'Goron Tunic': ('Item', True, 0x2C, None), + 'Zora Tunic': ('Item', True, 0x2D, None), + 'Iron Boots': ('Item', True, 0x2E, None), + 'Hover Boots': ('Item', True, 0x2F, None), + 'Stone of Agony': ('Item', True, 0x39, None), + 'Gerudo Membership Card': ('Item', True, 0x3A, None), + 'Heart Container': ('Item', None, 0x3D, None), + 'Piece of Heart': ('Item', None, 0x3E, None), + 'Boss Key': ('BossKey', True, 0x3F, None), + 'Compass': ('Compass', None, 0x40, None), + 'Map': ('Map', None, 0x41, None), + 'Small Key': ('SmallKey', True, 0x42, {'progressive': float('Inf')}), + 'Weird Egg': ('Item', True, 0x47, None), + 'Recovery Heart': ('Item', None, 0x48, None), + 'Arrows (5)': ('Item', None, 0x49, None), + 'Arrows (10)': ('Item', None, 0x4A, None), + 'Arrows (30)': ('Item', None, 0x4B, None), + 'Rupee (1)': ('Item', None, 0x4C, None), + 'Rupees (5)': ('Item', None, 0x4D, None), + 'Rupees (20)': ('Item', None, 0x4E, None), + 'Heart Container (Boss)': ('Item', None, 0x4F, None), + 'Milk': ('Item', None, 0x50, None), + 'Goron Mask': ('Item', None, 0x51, None), + 'Zora Mask': ('Item', None, 0x52, None), + 'Gerudo Mask': ('Item', None, 0x53, None), + 'Rupees (50)': ('Item', None, 0x55, None), + 'Rupees (200)': ('Item', None, 0x56, None), + 'Biggoron Sword': ('Item', True, 0x57, None), + 'Fire Arrows': ('Item', True, 0x58, None), + 'Ice Arrows': ('Item', True, 0x59, None), + 'Light Arrows': ('Item', True, 0x5A, None), + 'Gold Skulltula Token': ('Token', True, 0x5B, {'progressive': float('Inf')}), + 'Dins Fire': ('Item', True, 0x5C, None), + 'Nayrus Love': ('Item', True, 0x5E, None), + 'Farores Wind': ('Item', True, 0x5D, None), + 'Deku Nuts (10)': ('Item', None, 0x64, None), + 'Bombs (10)': ('Item', None, 0x66, None), + 'Bombs (20)': ('Item', None, 0x67, None), + 'Deku Seeds (30)': ('Item', None, 0x69, None), + 'Bombchus (5)': ('Item', True, 0x6A, None), + 'Bombchus (20)': ('Item', True, 0x6B, None), + 'Rupee (Treasure Chest Game)': ('Item', None, 0x72, None), + 'Piece of Heart (Treasure Chest Game)': ('Item', None, 0x76, None), + 'Ice Trap': ('Item', None, 0x7C, None), + 'Progressive Hookshot': ('Item', True, 0x80, {'progressive': 2}), + 'Progressive Strength Upgrade': ('Item', True, 0x81, {'progressive': 3}), + 'Bomb Bag': ('Item', True, 0x82, None), + 'Bow': ('Item', True, 0x83, None), + 'Slingshot': ('Item', True, 0x84, None), + 'Progressive Wallet': ('Item', True, 0x85, {'progressive': 3}), + 'Progressive Scale': ('Item', True, 0x86, {'progressive': 2}), + 'Deku Nut Capacity': ('Item', None, 0x87, None), + 'Deku Stick Capacity': ('Item', None, 0x88, None), + 'Bombchus': ('Item', True, 0x89, None), + 'Magic Meter': ('Item', True, 0x8A, None), + 'Ocarina': ('Item', True, 0x8B, None), + 'Bottle with Red Potion': ('Item', True, 0x8C, {'bottle': True, 'shop_object': 0x0F}), + 'Bottle with Green Potion': ('Item', True, 0x8D, {'bottle': True, 'shop_object': 0x0F}), + 'Bottle with Blue Potion': ('Item', True, 0x8E, {'bottle': True, 'shop_object': 0x0F}), + 'Bottle with Fairy': ('Item', True, 0x8F, {'bottle': True, 'shop_object': 0x0F}), + 'Bottle with Fish': ('Item', True, 0x90, {'bottle': True, 'shop_object': 0x0F}), + 'Bottle with Blue Fire': ('Item', True, 0x91, {'bottle': True, 'shop_object': 0x0F}), + 'Bottle with Bugs': ('Item', True, 0x92, {'bottle': True, 'shop_object': 0x0F}), + 'Bottle with Big Poe': ('Item', True, 0x93, {'shop_object': 0x0F}), + 'Bottle with Poe': ('Item', True, 0x94, {'bottle': True, 'shop_object': 0x0F}), + 'Boss Key (Forest Temple)': ('BossKey', True, 0x95, None), + 'Boss Key (Fire Temple)': ('BossKey', True, 0x96, None), + 'Boss Key (Water Temple)': ('BossKey', True, 0x97, None), + 'Boss Key (Spirit Temple)': ('BossKey', True, 0x98, None), + 'Boss Key (Shadow Temple)': ('BossKey', True, 0x99, None), + 'Boss Key (Ganons Castle)': ('GanonBossKey',True,0x9A,None), + 'Compass (Deku Tree)': ('Compass', None, 0x9B, None), + 'Compass (Dodongos Cavern)': ('Compass', None, 0x9C, None), + 'Compass (Jabu Jabus Belly)': ('Compass', None, 0x9D, None), + 'Compass (Forest Temple)': ('Compass', None, 0x9E, None), + 'Compass (Fire Temple)': ('Compass', None, 0x9F, None), + 'Compass (Water Temple)': ('Compass', None, 0xA0, None), + 'Compass (Spirit Temple)': ('Compass', None, 0xA1, None), + 'Compass (Shadow Temple)': ('Compass', None, 0xA2, None), + 'Compass (Bottom of the Well)': ('Compass', None, 0xA3, None), + 'Compass (Ice Cavern)': ('Compass', None, 0xA4, None), + 'Map (Deku Tree)': ('Map', None, 0xA5, None), + 'Map (Dodongos Cavern)': ('Map', None, 0xA6, None), + 'Map (Jabu Jabus Belly)': ('Map', None, 0xA7, None), + 'Map (Forest Temple)': ('Map', None, 0xA8, None), + 'Map (Fire Temple)': ('Map', None, 0xA9, None), + 'Map (Water Temple)': ('Map', None, 0xAA, None), + 'Map (Spirit Temple)': ('Map', None, 0xAB, None), + 'Map (Shadow Temple)': ('Map', None, 0xAC, None), + 'Map (Bottom of the Well)': ('Map', None, 0xAD, None), + 'Map (Ice Cavern)': ('Map', None, 0xAE, None), + 'Small Key (Forest Temple)': ('SmallKey', True, 0xAF, {'progressive': float('Inf')}), + 'Small Key (Fire Temple)': ('SmallKey', True, 0xB0, {'progressive': float('Inf')}), + 'Small Key (Water Temple)': ('SmallKey', True, 0xB1, {'progressive': float('Inf')}), + 'Small Key (Spirit Temple)': ('SmallKey', True, 0xB2, {'progressive': float('Inf')}), + 'Small Key (Shadow Temple)': ('SmallKey', True, 0xB3, {'progressive': float('Inf')}), + 'Small Key (Bottom of the Well)': ('SmallKey', True, 0xB4, {'progressive': float('Inf')}), + 'Small Key (Gerudo Training Grounds)': ('SmallKey',True, 0xB5, {'progressive': float('Inf')}), + 'Small Key (Gerudo Fortress)': ('FortressSmallKey',True, 0xB6, {'progressive': float('Inf')}), + 'Small Key (Ganons Castle)': ('SmallKey', True, 0xB7, {'progressive': float('Inf')}), + 'Double Defense': ('Item', True, 0xB8, None), + 'Magic Bean Pack': ('Item', True, 0xC9, None), + 'Triforce Piece': ('Item', True, 0xCA, {'progressive': float('Inf')}), + 'Zeldas Letter': ('Item', True, 0x0B, None), + 'Time Travel': ('Event', True, None, None), + 'Scarecrow Song': ('Event', True, None, None), + 'Triforce': ('Event', True, None, None), + + # Event items otherwise generated by generic event logic + # can be defined here to enforce their appearance in playthroughs. + 'Water Temple Clear': ('Event', True, None, None), + 'Forest Trial Clear': ('Event', True, None, None), + 'Fire Trial Clear': ('Event', True, None, None), + 'Water Trial Clear': ('Event', True, None, None), + 'Shadow Trial Clear': ('Event', True, None, None), + 'Spirit Trial Clear': ('Event', True, None, None), + 'Light Trial Clear': ('Event', True, None, None), + + 'Deku Stick Drop': ('Drop', True, None, None), + 'Deku Nut Drop': ('Drop', True, None, None), + 'Blue Fire': ('Drop', True, None, None), + 'Fairy': ('Drop', True, None, None), + 'Fish': ('Drop', True, None, None), + 'Bugs': ('Drop', True, None, None), + 'Big Poe': ('Drop', True, None, None), + 'Bombchu Drop': ('Drop', True, None, None), + + # Consumable refills defined mostly to placate 'starting with' options + 'Arrows': ('Refill', None, None, None), + 'Bombs': ('Refill', None, None, None), + 'Deku Seeds': ('Refill', None, None, None), + 'Deku Sticks': ('Refill', None, None, None), + 'Deku Nuts': ('Refill', None, None, None), + 'Rupees': ('Refill', None, None, None), + + 'Minuet of Forest': ('Song', True, 0xBB, + { + 'text_id': 0x73, + 'song_id': 0x02, + 'item_id': 0x5A, + }), + 'Bolero of Fire': ('Song', True, 0xBC, + { + 'text_id': 0x74, + 'song_id': 0x03, + 'item_id': 0x5B, + }), + 'Serenade of Water': ('Song', True, 0xBD, + { + 'text_id': 0x75, + 'song_id': 0x04, + 'item_id': 0x5C, + }), + 'Requiem of Spirit': ('Song', True, 0xBE, + { + 'text_id': 0x76, + 'song_id': 0x05, + 'item_id': 0x5D, + }), + 'Nocturne of Shadow': ('Song', True, 0xBF, + { + 'text_id': 0x77, + 'song_id': 0x06, + 'item_id': 0x5E, + }), + 'Prelude of Light': ('Song', True, 0xC0, + { + 'text_id': 0x78, + 'song_id': 0x07, + 'item_id': 0x5F, + }), + 'Zeldas Lullaby': ('Song', True, 0xC1, + { + 'text_id': 0xD4, + 'song_id': 0x0A, + 'item_id': 0x60, + }), + 'Eponas Song': ('Song', True, 0xC2, + { + 'text_id': 0xD2, + 'song_id': 0x09, + 'item_id': 0x61, + }), + 'Sarias Song': ('Song', True, 0xC3, + { + 'text_id': 0xD1, + 'song_id': 0x08, + 'item_id': 0x62, + }), + 'Suns Song': ('Song', True, 0xC4, + { + 'text_id': 0xD3, + 'song_id': 0x0B, + 'item_id': 0x63, + }), + 'Song of Time': ('Song', True, 0xC5, + { + 'text_id': 0xD5, + 'song_id': 0x0C, + 'item_id': 0x64, + }), + 'Song of Storms': ('Song', True, 0xC6, + { + 'text_id': 0xD6, + 'song_id': 0x0D, + 'item_id': 0x65, + }), + + 'Buy Deku Nut (5)': ('Shop', True, 0x00, {'object': 0x00BB, 'price': 15}), + 'Buy Arrows (30)': ('Shop', False, 0x01, {'object': 0x00D8, 'price': 60}), + 'Buy Arrows (50)': ('Shop', False, 0x02, {'object': 0x00D8, 'price': 90}), + 'Buy Bombs (5) [25]': ('Shop', False, 0x03, {'object': 0x00CE, 'price': 25}), + 'Buy Deku Nut (10)': ('Shop', True, 0x04, {'object': 0x00BB, 'price': 30}), + 'Buy Deku Stick (1)': ('Shop', True, 0x05, {'object': 0x00C7, 'price': 10}), + 'Buy Bombs (10)': ('Shop', False, 0x06, {'object': 0x00CE, 'price': 50}), + 'Buy Fish': ('Shop', True, 0x07, {'object': 0x00F4, 'price': 200}), + 'Buy Red Potion [30]': ('Shop', False, 0x08, {'object': 0x00EB, 'price': 30}), + 'Buy Green Potion': ('Shop', False, 0x09, {'object': 0x00EB, 'price': 30}), + 'Buy Blue Potion': ('Shop', False, 0x0A, {'object': 0x00EB, 'price': 100}), + 'Buy Hylian Shield': ('Shop', True, 0x0C, {'object': 0x00DC, 'price': 80}), + 'Buy Deku Shield': ('Shop', True, 0x0D, {'object': 0x00CB, 'price': 40}), + 'Buy Goron Tunic': ('Shop', True, 0x0E, {'object': 0x00F2, 'price': 200}), + 'Buy Zora Tunic': ('Shop', True, 0x0F, {'object': 0x00F2, 'price': 300}), + 'Buy Heart': ('Shop', False, 0x10, {'object': 0x00B7, 'price': 10}), + 'Buy Bombchu (10)': ('Shop', True, 0x15, {'object': 0x00D9, 'price': 99}), + 'Buy Bombchu (20)': ('Shop', True, 0x16, {'object': 0x00D9, 'price': 180}), + 'Buy Bombchu (5)': ('Shop', True, 0x18, {'object': 0x00D9, 'price': 60}), + 'Buy Deku Seeds (30)': ('Shop', False, 0x1D, {'object': 0x0119, 'price': 30}), + 'Sold Out': ('Shop', False, 0x26, {'object': 0x0148}), + 'Buy Blue Fire': ('Shop', True, 0x27, {'object': 0x0173, 'price': 300}), + 'Buy Bottle Bug': ('Shop', True, 0x28, {'object': 0x0174, 'price': 50}), + 'Buy Poe': ('Shop', False, 0x2A, {'object': 0x0176, 'price': 30}), + 'Buy Fairy\'s Spirit': ('Shop', True, 0x2B, {'object': 0x0177, 'price': 50}), + 'Buy Arrows (10)': ('Shop', False, 0x2C, {'object': 0x00D8, 'price': 20}), + 'Buy Bombs (20)': ('Shop', False, 0x2D, {'object': 0x00CE, 'price': 80}), + 'Buy Bombs (30)': ('Shop', False, 0x2E, {'object': 0x00CE, 'price': 120}), + 'Buy Bombs (5) [35]': ('Shop', False, 0x2F, {'object': 0x00CE, 'price': 35}), + 'Buy Red Potion [40]': ('Shop', False, 0x30, {'object': 0x00EB, 'price': 40}), + 'Buy Red Potion [50]': ('Shop', False, 0x31, {'object': 0x00EB, 'price': 50}), + + 'Kokiri Emerald': ('DungeonReward', True, None, + { + 'stone': True, + 'addr2_data': 0x80, + 'bit_mask': 0x00040000, + 'item_id': 0x6C, + 'actor_type': 0x13, + 'object_id': 0x00AD, + }), + 'Goron Ruby': ('DungeonReward', True, None, + { + 'stone': True, + 'addr2_data': 0x81, + 'bit_mask': 0x00080000, + 'item_id': 0x6D, + 'actor_type': 0x14, + 'object_id': 0x00AD, + }), + 'Zora Sapphire': ('DungeonReward', True, None, + { + 'stone': True, + 'addr2_data': 0x82, + 'bit_mask': 0x00100000, + 'item_id': 0x6E, + 'actor_type': 0x15, + 'object_id': 0x00AD, + }), + 'Forest Medallion': ('DungeonReward', True, None, + { + 'medallion': True, + 'addr2_data': 0x3E, + 'bit_mask': 0x00000001, + 'item_id': 0x66, + 'actor_type': 0x0B, + 'object_id': 0x00BA, + }), + 'Fire Medallion': ('DungeonReward', True, None, + { + 'medallion': True, + 'addr2_data': 0x3C, + 'bit_mask': 0x00000002, + 'item_id': 0x67, + 'actor_type': 0x09, + 'object_id': 0x00BA, + }), + 'Water Medallion': ('DungeonReward', True, None, + { + 'medallion': True, + 'addr2_data': 0x3D, + 'bit_mask': 0x00000004, + 'item_id': 0x68, + 'actor_type': 0x0A, + 'object_id': 0x00BA, + }), + 'Spirit Medallion': ('DungeonReward', True, None, + { + 'medallion': True, + 'addr2_data': 0x3F, + 'bit_mask': 0x00000008, + 'item_id': 0x69, + 'actor_type': 0x0C, + 'object_id': 0x00BA, + }), + 'Shadow Medallion': ('DungeonReward', True, None, + { + 'medallion': True, + 'addr2_data': 0x41, + 'bit_mask': 0x00000010, + 'item_id': 0x6A, + 'actor_type': 0x0D, + 'object_id': 0x00BA, + }), + 'Light Medallion': ('DungeonReward', True, None, + { + 'medallion': True, + 'addr2_data': 0x40, + 'bit_mask': 0x00000020, + 'item_id': 0x6B, + 'actor_type': 0x0E, + 'object_id': 0x00BA, + }), +} diff --git a/worlds/oot/JSONDump.py b/worlds/oot/JSONDump.py new file mode 100644 index 00000000..d653a3fd --- /dev/null +++ b/worlds/oot/JSONDump.py @@ -0,0 +1,122 @@ +import json + +from functools import reduce + +INDENT = ' ' + +class CollapseList(list): + pass +class CollapseDict(dict): + pass +class AlignedDict(dict): + def __init__(self, src_dict, depth): + self.depth = depth - 1 + super().__init__(src_dict) +class SortedDict(dict): + pass + + +def is_scalar(value): + return not is_list(value) and not is_dict(value) + + +def is_list(value): + return isinstance(value, list) or isinstance(value, tuple) + + +def is_dict(value): + return isinstance(value, dict) + + +def dump_scalar(obj, ensure_ascii=False): + return json.dumps(obj, ensure_ascii=ensure_ascii) + + +def dump_list(obj, current_indent='', ensure_ascii=False): + entries = [dump_obj(value, current_indent + INDENT, ensure_ascii=ensure_ascii) for value in obj] + + if len(entries) == 0: + return '[]' + + if isinstance(obj, CollapseList): + values_format = '{value}' + output_format = '[{values}]' + join_format = ', ' + else: + values_format = '{indent}{value}' + output_format = '[\n{values}\n{indent}]' + join_format = ',\n' + + output = output_format.format( + indent=current_indent, + values=join_format.join([values_format.format( + value=entry, + indent=current_indent + INDENT + ) for entry in entries]) + ) + + return output + + +def get_keys(obj, depth): + if depth == 0: + yield from obj.keys() + else: + for value in obj.values(): + yield from get_keys(value, depth - 1) + + +def dump_dict(obj, current_indent='', sub_width=None, ensure_ascii=False): + entries = [] + + key_width = None + if sub_width is not None: + sub_width = (sub_width[0]-1, sub_width[1]) + if sub_width[0] == 0: + key_width = sub_width[1] + + if isinstance(obj, AlignedDict): + sub_keys = get_keys(obj, obj.depth) + sub_width = (obj.depth, reduce(lambda acc, entry: max(acc, len(entry)), sub_keys, 0)) + + for key, value in obj.items(): + entries.append((dump_scalar(str(key), ensure_ascii), dump_obj(value, current_indent + INDENT, sub_width, ensure_ascii))) + + if key_width is None: + key_width = reduce(lambda acc, entry: max(acc, len(entry[0])), entries, 0) + + if len(entries) == 0: + return '{}' + + if isinstance(obj, SortedDict): + entries.sort(key=lambda item: item[0]) + + if isinstance(obj, CollapseDict): + values_format = '{key} {value}' + output_format = '{{{values}}}' + join_format = ', ' + else: + values_format = '{indent}{key:{padding}}{value}' + output_format = '{{\n{values}\n{indent}}}' + join_format = ',\n' + + output = output_format.format( + indent=current_indent, + values=join_format.join([values_format.format( + key='{key}:'.format(key=key), + value=value, + indent=current_indent + INDENT, + padding=key_width + 2, + ) for (key, value) in entries]) + ) + + return output + + +def dump_obj(obj, current_indent='', sub_width=None, ensure_ascii=False): + if is_list(obj): + return dump_list(obj, current_indent, ensure_ascii) + elif is_dict(obj): + return dump_dict(obj, current_indent, sub_width, ensure_ascii) + else: + return dump_scalar(obj, ensure_ascii) diff --git a/worlds/oot/LICENSE b/worlds/oot/LICENSE new file mode 100644 index 00000000..c10701c6 --- /dev/null +++ b/worlds/oot/LICENSE @@ -0,0 +1,26 @@ +MIT License + +Copyright (c) 2017 Amazing Ampharos +Copyright (c) 2021 espeon65536 + +Credit for contributions to Junglechief87 on this and to LLCoolDave and +KevinCathcart for their work on the Zelda Lttp Entrance Randomizer which +was the code base for this project. + +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/oot/Location.py b/worlds/oot/Location.py new file mode 100644 index 00000000..a8b659e7 --- /dev/null +++ b/worlds/oot/Location.py @@ -0,0 +1,53 @@ +from .LocationList import location_table +from BaseClasses import Location + +location_id_offset = 67000 +location_name_to_id = {name: (location_id_offset + index) for (index, name) in enumerate(location_table) + if location_table[name][0] not in ['Boss', 'Event', 'Drop', 'HintStone', 'Hint']} + +class OOTLocation(Location): + game: str = 'Ocarina of Time' + + def __init__(self, player, name='', code=None, address1=None, address2=None, default=None, type='Chest', scene=None, parent=None, filter_tags=None, internal=False): + super(OOTLocation, self).__init__(player, name, code, parent) + self.address1 = address1 + self.address2 = address2 + self.default = default + self.type = type + self.scene = scene + self.internal = internal + if filter_tags is None: + self.filter_tags = None + else: + self.filter_tags = list(filter_tags) + self.never = False # no idea what this does + + if type == 'Event': + self.event = True + + +def LocationFactory(locations, player: int): + ret = [] + singleton = False + if isinstance(locations, str): + locations = [locations] + singleton = True + for location in locations: + if location in location_table: + match_location = location + else: + match_location = next(filter(lambda k: k.lower() == location.lower(), location_table), None) + if match_location: + type, scene, default, addresses, vanilla_item, filter_tags = location_table[match_location] + if addresses is None: + addresses = (None, None) + address1, address2 = addresses + ret.append(OOTLocation(player, match_location, location_name_to_id.get(match_location, None), address1, address2, default, type, scene, filter_tags=filter_tags)) + else: + raise KeyError('Unknown Location: %s', location) + + if singleton: + return ret[0] + return ret + + diff --git a/worlds/oot/LocationList.py b/worlds/oot/LocationList.py new file mode 100644 index 00000000..e487522f --- /dev/null +++ b/worlds/oot/LocationList.py @@ -0,0 +1,932 @@ +from collections import OrderedDict + + +def shop_address(shop_id, shelf_id): + return 0xC71ED0 + (0x40 * shop_id) + (0x08 * shelf_id) + +# Abbreviations +# DMC Death Mountain Crater +# DMT Death Mountain Trail +# GC Goron City +# GF Gerudo Fortress +# GS Gold Skulltula +# GV Gerudo Valley +# HC Hyrule Castle +# HF Hyrule Field +# KF Kokiri Forest +# LH Lake Hylia +# LLR Lon Lon Ranch +# LW Lost Woods +# OGC Outside Ganon's Castle +# SFM Sacred Forest Meadow +# ToT Temple of Time +# ZD Zora's Domain +# ZF Zora's Fountain +# ZR Zora's River + +# The order of this table is reflected in the spoiler's list of locations (except Hints aren't included). +# Within a section, the order of types is: gifts/freestanding/chests, Deku Scrubs, Cows, Gold Skulltulas, Shops. + +# NPC Scrubs are on the overworld, while GrottoNPC is a special handler for Grottos +# Grottos scrubs are the same scene and actor, so we use a unique grotto ID for the scene + +# Note that the scene for skulltulas is not the actual scene the token appears in +# Rather, it is the index of the grouping used when storing skulltula collection +# For example, zora river, zora's domain, and zora fountain are all a single 'scene' for skulltulas + +# Location: Type Scene Default Addresses Vanilla Item Categories +location_table = OrderedDict([ + ## Dungeon Rewards + ("Links Pocket", ("Boss", None, None, None, 'Light Medallion', None)), + ("Queen Gohma", ("Boss", None, 0x6C, (0x0CA315F, 0x2079571), 'Kokiri Emerald', None)), + ("King Dodongo", ("Boss", None, 0x6D, (0x0CA30DF, 0x2223309), 'Goron Ruby', None)), + ("Barinade", ("Boss", None, 0x6E, (0x0CA36EB, 0x2113C19), 'Zora Sapphire', None)), + ("Phantom Ganon", ("Boss", None, 0x66, (0x0CA3D07, 0x0D4ED79), 'Forest Medallion', None)), + ("Volvagia", ("Boss", None, 0x67, (0x0CA3D93, 0x0D10135), 'Fire Medallion', None)), + ("Morpha", ("Boss", None, 0x68, (0x0CA3E1F, 0x0D5A3A9), 'Water Medallion', None)), + ("Bongo Bongo", ("Boss", None, 0x6A, (0x0CA3F43, 0x0D13E19), 'Shadow Medallion', None)), + ("Twinrova", ("Boss", None, 0x69, (0x0CA3EB3, 0x0D39FF1), 'Spirit Medallion', None)), + ("Ganon", ("Event", None, None, None, 'Triforce', None)), + + ## Songs + ("Song from Impa", ("Song", 0xFF, 0x26, (0x2E8E925, 0x2E8E925), 'Zeldas Lullaby', ("Hyrule Castle", "Market", "Songs"))), + ("Song from Malon", ("Song", 0xFF, 0x27, (0x0D7EB53, 0x0D7EBCF), 'Eponas Song', ("Lon Lon Ranch", "Songs",))), + ("Song from Saria", ("Song", 0xFF, 0x28, (0x20B1DB1, 0x20B1DB1), 'Sarias Song', ("Sacred Forest Meadow", "Forest", "Songs"))), + ("Song from Composers Grave", ("Song", 0xFF, 0x29, (0x332A871, 0x332A871), 'Suns Song', ("the Graveyard", "Kakariko", "Songs"))), + ("Song from Ocarina of Time", ("Song", 0xFF, 0x2A, (0x252FC89, 0x252FC89), 'Song of Time', ("Hyrule Field", "Songs", "Need Spiritual Stones"))), + ("Song from Windmill", ("Song", 0xFF, 0x2B, (0x0E42C07, 0x0E42B8B), 'Song of Storms', ("Kakariko Village", "Kakariko", "Songs"))), + ("Sheik in Forest", ("Song", 0xFF, 0x20, (0x20B0809, 0x20B0809), 'Minuet of Forest', ("Sacred Forest Meadow", "Forest", "Songs"))), + ("Sheik in Crater", ("Song", 0xFF, 0x21, (0x224D7F1, 0x224D7F1), 'Bolero of Fire', ("Death Mountain Crater", "Death Mountain", "Songs"))), + ("Sheik in Ice Cavern", ("Song", 0xFF, 0x22, (0x2BEC889, 0x2BEC889), 'Serenade of Water', ("Ice Cavern", "Songs",))), + ("Sheik at Colossus", ("Song", 0xFF, 0x23, (0x218C57D, 0x218C57D), 'Requiem of Spirit', ("Desert Colossus", "Songs",))), + ("Sheik in Kakariko", ("Song", 0xFF, 0x24, (0x2000FE1, 0x2000FE1), 'Nocturne of Shadow', ("Kakariko Village", "Kakariko", "Songs"))), + ("Sheik at Temple", ("Song", 0xFF, 0x25, (0x2531329, 0x2531329), 'Prelude of Light', ("Temple of Time", "Market", "Songs"))), + + ## Overworld + # Kokiri Forest + ("KF Midos Top Left Chest", ("Chest", 0x28, 0x00, None, 'Rupees (5)', ("Kokiri Forest", "Forest",))), + ("KF Midos Top Right Chest", ("Chest", 0x28, 0x01, None, 'Rupees (5)', ("Kokiri Forest", "Forest",))), + ("KF Midos Bottom Left Chest", ("Chest", 0x28, 0x02, None, 'Rupee (1)', ("Kokiri Forest", "Forest",))), + ("KF Midos Bottom Right Chest", ("Chest", 0x28, 0x03, None, 'Recovery Heart', ("Kokiri Forest", "Forest",))), + ("KF Kokiri Sword Chest", ("Chest", 0x55, 0x00, None, 'Kokiri Sword', ("Kokiri Forest", "Forest",))), + ("KF Storms Grotto Chest", ("Chest", 0x3E, 0x0C, None, 'Rupees (20)', ("Kokiri Forest", "Forest", "Grottos"))), + ("KF Links House Cow", ("NPC", 0x34, 0x15, None, 'Milk', ("KF Links House", "Forest", "Cow", "Minigames"))), + ("KF GS Know It All House", ("GS Token", 0x0C, 0x02, None, 'Gold Skulltula Token', ("Kokiri Forest", "Skulltulas",))), + ("KF GS Bean Patch", ("GS Token", 0x0C, 0x01, None, 'Gold Skulltula Token', ("Kokiri Forest", "Skulltulas",))), + ("KF GS House of Twins", ("GS Token", 0x0C, 0x04, None, 'Gold Skulltula Token', ("Kokiri Forest", "Skulltulas",))), + ("KF Shop Item 1", ("Shop", 0x2D, 0x30, (shop_address(0, 0), None), 'Buy Deku Shield', ("Kokiri Forest", "Forest", "Shops"))), + ("KF Shop Item 2", ("Shop", 0x2D, 0x31, (shop_address(0, 1), None), 'Buy Deku Nut (5)', ("Kokiri Forest", "Forest", "Shops"))), + ("KF Shop Item 3", ("Shop", 0x2D, 0x32, (shop_address(0, 2), None), 'Buy Deku Nut (10)', ("Kokiri Forest", "Forest", "Shops"))), + ("KF Shop Item 4", ("Shop", 0x2D, 0x33, (shop_address(0, 3), None), 'Buy Deku Stick (1)', ("Kokiri Forest", "Forest", "Shops"))), + ("KF Shop Item 5", ("Shop", 0x2D, 0x34, (shop_address(0, 4), None), 'Buy Deku Seeds (30)', ("Kokiri Forest", "Forest", "Shops"))), + ("KF Shop Item 6", ("Shop", 0x2D, 0x35, (shop_address(0, 5), None), 'Buy Arrows (10)', ("Kokiri Forest", "Forest", "Shops"))), + ("KF Shop Item 7", ("Shop", 0x2D, 0x36, (shop_address(0, 6), None), 'Buy Arrows (30)', ("Kokiri Forest", "Forest", "Shops"))), + ("KF Shop Item 8", ("Shop", 0x2D, 0x37, (shop_address(0, 7), None), 'Buy Heart', ("Kokiri Forest", "Forest", "Shops"))), + + # Lost Woods + ("LW Gift from Saria", ("Cutscene", 0xFF, 0x02, None, 'Ocarina', ("the Lost Woods", "Forest",))), + ("LW Ocarina Memory Game", ("NPC", 0x5B, 0x76, None, 'Piece of Heart', ("the Lost Woods", "Forest", "Minigames"))), + ("LW Target in Woods", ("NPC", 0x5B, 0x60, None, 'Slingshot', ("the Lost Woods", "Forest",))), + ("LW Near Shortcuts Grotto Chest", ("Chest", 0x3E, 0x14, None, 'Rupees (5)', ("the Lost Woods", "Forest", "Grottos"))), + ("Deku Theater Skull Mask", ("NPC", 0x3E, 0x77, None, 'Deku Stick Capacity', ("the Lost Woods", "Forest", "Grottos"))), + ("Deku Theater Mask of Truth", ("NPC", 0x3E, 0x7A, None, 'Deku Nut Capacity', ("the Lost Woods", "Forest", "Need Spiritual Stones", "Grottos"))), + ("LW Skull Kid", ("NPC", 0x5B, 0x3E, None, 'Piece of Heart', ("the Lost Woods", "Forest",))), + ("LW Deku Scrub Near Bridge", ("NPC", 0x5B, 0x77, None, 'Deku Stick Capacity', ("the Lost Woods", "Forest", "Deku Scrub", "Deku Scrub Upgrades"))), + ("LW Deku Scrub Near Deku Theater Left", ("NPC", 0x5B, 0x31, None, 'Buy Deku Stick (1)', ("the Lost Woods", "Forest", "Deku Scrub"))), + ("LW Deku Scrub Near Deku Theater Right", ("NPC", 0x5B, 0x30, None, 'Buy Deku Nut (5)', ("the Lost Woods", "Forest", "Deku Scrub"))), + ("LW Deku Scrub Grotto Front", ("GrottoNPC", 0xF5, 0x79, None, 'Deku Nut Capacity', ("the Lost Woods", "Forest", "Deku Scrub", "Deku Scrub Upgrades", "Grottos"))), + ("LW Deku Scrub Grotto Rear", ("GrottoNPC", 0xF5, 0x33, None, 'Buy Deku Seeds (30)', ("the Lost Woods", "Forest", "Deku Scrub", "Grottos"))), + ("LW GS Bean Patch Near Bridge", ("GS Token", 0x0D, 0x01, None, 'Gold Skulltula Token', ("the Lost Woods", "Skulltulas",))), + ("LW GS Bean Patch Near Theater", ("GS Token", 0x0D, 0x02, None, 'Gold Skulltula Token', ("the Lost Woods", "Skulltulas",))), + ("LW GS Above Theater", ("GS Token", 0x0D, 0x04, None, 'Gold Skulltula Token', ("the Lost Woods", "Skulltulas",))), + + # Sacred Forest Meadow + ("SFM Wolfos Grotto Chest", ("Chest", 0x3E, 0x11, None, 'Rupees (50)', ("Sacred Forest Meadow", "Forest", "Grottos"))), + ("SFM Deku Scrub Grotto Front", ("GrottoNPC", 0xEE, 0x3A, None, 'Buy Green Potion', ("Sacred Forest Meadow", "Forest", "Deku Scrub", "Grottos"))), + ("SFM Deku Scrub Grotto Rear", ("GrottoNPC", 0xEE, 0x39, None, 'Buy Red Potion [30]', ("Sacred Forest Meadow", "Forest", "Deku Scrub", "Grottos"))), + ("SFM GS", ("GS Token", 0x0D, 0x08, None, 'Gold Skulltula Token', ("Sacred Forest Meadow", "Skulltulas",))), + + # Hyrule Field + ("HF Ocarina of Time Item", ("NPC", 0x51, 0x0C, None, 'Ocarina', ("Hyrule Field", "Need Spiritual Stones",))), + ("HF Near Market Grotto Chest", ("Chest", 0x3E, 0x00, None, 'Rupees (5)', ("Hyrule Field", "Grottos",))), + ("HF Tektite Grotto Freestanding PoH", ("Collectable", 0x3E, 0x01, None, 'Piece of Heart', ("Hyrule Field", "Grottos",))), + ("HF Southeast Grotto Chest", ("Chest", 0x3E, 0x02, None, 'Rupees (20)', ("Hyrule Field", "Grottos",))), + ("HF Open Grotto Chest", ("Chest", 0x3E, 0x03, None, 'Rupees (5)', ("Hyrule Field", "Grottos",))), + ("HF Deku Scrub Grotto", ("GrottoNPC", 0xE6, 0x3E, None, 'Piece of Heart', ("Hyrule Field", "Deku Scrub", "Deku Scrub Upgrades", "Grottos"))), + ("HF Cow Grotto Cow", ("NPC", 0x3E, 0x16, None, 'Milk', ("Hyrule Field", "Cow", "Grottos"))), + ("HF GS Cow Grotto", ("GS Token", 0x0A, 0x01, None, 'Gold Skulltula Token', ("Hyrule Field", "Skulltulas", "Grottos"))), + ("HF GS Near Kak Grotto", ("GS Token", 0x0A, 0x02, None, 'Gold Skulltula Token', ("Hyrule Field", "Skulltulas", "Grottos"))), + + # Market + ("Market Shooting Gallery Reward", ("NPC", 0x42, 0x60, None, 'Slingshot', ("the Market", "Market", "Minigames"))), + ("Market Bombchu Bowling First Prize", ("NPC", 0x4B, 0x34, None, 'Bomb Bag', ("the Market", "Market", "Minigames"))), + ("Market Bombchu Bowling Second Prize", ("NPC", 0x4B, 0x3E, None, 'Piece of Heart', ("the Market", "Market", "Minigames"))), + ("Market Bombchu Bowling Bombchus", ("Event", 0x4B, None, None, 'Bombchu Drop', ("the Market", "Market", "Minigames"))), + ("Market Lost Dog", ("NPC", 0x35, 0x3E, None, 'Piece of Heart', ("the Market", "Market",))), + ("Market Treasure Chest Game Reward", ("Chest", 0x10, 0x0A, None, 'Piece of Heart (Treasure Chest Game)', ("the Market", "Market", "Minigames"))), + ("Market 10 Big Poes", ("NPC", 0x4D, 0x0F, None, 'Bottle', ("the Market", "Hyrule Castle",))), + ("Market GS Guard House", ("GS Token", 0x0E, 0x08, None, 'Gold Skulltula Token', ("the Market", "Skulltulas",))), + ("Market Bazaar Item 1", ("Shop", 0x2C, 0x30, (shop_address(4, 0), None), 'Buy Hylian Shield', ("the Market", "Market", "Shops"))), + ("Market Bazaar Item 2", ("Shop", 0x2C, 0x31, (shop_address(4, 1), None), 'Buy Bombs (5) [35]', ("the Market", "Market", "Shops"))), + ("Market Bazaar Item 3", ("Shop", 0x2C, 0x32, (shop_address(4, 2), None), 'Buy Deku Nut (5)', ("the Market", "Market", "Shops"))), + ("Market Bazaar Item 4", ("Shop", 0x2C, 0x33, (shop_address(4, 3), None), 'Buy Heart', ("the Market", "Market", "Shops"))), + ("Market Bazaar Item 5", ("Shop", 0x2C, 0x34, (shop_address(4, 4), None), 'Buy Arrows (10)', ("the Market", "Market", "Shops"))), + ("Market Bazaar Item 6", ("Shop", 0x2C, 0x35, (shop_address(4, 5), None), 'Buy Arrows (50)', ("the Market", "Market", "Shops"))), + ("Market Bazaar Item 7", ("Shop", 0x2C, 0x36, (shop_address(4, 6), None), 'Buy Deku Stick (1)', ("the Market", "Market", "Shops"))), + ("Market Bazaar Item 8", ("Shop", 0x2C, 0x37, (shop_address(4, 7), None), 'Buy Arrows (30)', ("the Market", "Market", "Shops"))), + + ("Market Potion Shop Item 1", ("Shop", 0x31, 0x30, (shop_address(3, 0), None), 'Buy Green Potion', ("the Market", "Market", "Shops"))), + ("Market Potion Shop Item 2", ("Shop", 0x31, 0x31, (shop_address(3, 1), None), 'Buy Blue Fire', ("the Market", "Market", "Shops"))), + ("Market Potion Shop Item 3", ("Shop", 0x31, 0x32, (shop_address(3, 2), None), 'Buy Red Potion [30]', ("the Market", "Market", "Shops"))), + ("Market Potion Shop Item 4", ("Shop", 0x31, 0x33, (shop_address(3, 3), None), 'Buy Fairy\'s Spirit', ("the Market", "Market", "Shops"))), + ("Market Potion Shop Item 5", ("Shop", 0x31, 0x34, (shop_address(3, 4), None), 'Buy Deku Nut (5)', ("the Market", "Market", "Shops"))), + ("Market Potion Shop Item 6", ("Shop", 0x31, 0x35, (shop_address(3, 5), None), 'Buy Bottle Bug', ("the Market", "Market", "Shops"))), + ("Market Potion Shop Item 7", ("Shop", 0x31, 0x36, (shop_address(3, 6), None), 'Buy Poe', ("the Market", "Market", "Shops"))), + ("Market Potion Shop Item 8", ("Shop", 0x31, 0x37, (shop_address(3, 7), None), 'Buy Fish', ("the Market", "Market", "Shops"))), + + ("Market Bombchu Shop Item 1", ("Shop", 0x32, 0x30, (shop_address(2, 0), None), 'Buy Bombchu (5)', ("the Market", "Market", "Shops"))), + ("Market Bombchu Shop Item 2", ("Shop", 0x32, 0x31, (shop_address(2, 1), None), 'Buy Bombchu (10)', ("the Market", "Market", "Shops"))), + ("Market Bombchu Shop Item 3", ("Shop", 0x32, 0x32, (shop_address(2, 2), None), 'Buy Bombchu (10)', ("the Market", "Market", "Shops"))), + ("Market Bombchu Shop Item 4", ("Shop", 0x32, 0x33, (shop_address(2, 3), None), 'Buy Bombchu (10)', ("the Market", "Market", "Shops"))), + ("Market Bombchu Shop Item 5", ("Shop", 0x32, 0x34, (shop_address(2, 4), None), 'Buy Bombchu (20)', ("the Market", "Market", "Shops"))), + ("Market Bombchu Shop Item 6", ("Shop", 0x32, 0x35, (shop_address(2, 5), None), 'Buy Bombchu (20)', ("the Market", "Market", "Shops"))), + ("Market Bombchu Shop Item 7", ("Shop", 0x32, 0x36, (shop_address(2, 6), None), 'Buy Bombchu (20)', ("the Market", "Market", "Shops"))), + ("Market Bombchu Shop Item 8", ("Shop", 0x32, 0x37, (shop_address(2, 7), None), 'Buy Bombchu (20)', ("the Market", "Market", "Shops"))), + + ("ToT Light Arrows Cutscene", ("Cutscene", 0xFF, 0x01, None, 'Light Arrows', ("Temple of Time", "Market",))), + + # Hyrule Castle + ("HC Malon Egg", ("NPC", 0x5F, 0x47, None, 'Weird Egg', ("Hyrule Castle", "Market",))), + ("HC Zeldas Letter", ("NPC", 0x4A, 0x0B, None, 'Zeldas Letter', ("Hyrule Castle", "Market",))), + ("HC Great Fairy Reward", ("Cutscene", 0xFF, 0x11, None, 'Dins Fire', ("Hyrule Castle", "Market", "Fairies"))), + ("HC GS Tree", ("GS Token", 0x0E, 0x04, None, 'Gold Skulltula Token', ("Hyrule Castle", "Skulltulas",))), + ("HC GS Storms Grotto", ("GS Token", 0x0E, 0x02, None, 'Gold Skulltula Token', ("Hyrule Castle", "Skulltulas", "Grottos"))), + + # Lon Lon Ranch + ("LLR Talons Chickens", ("NPC", 0x4C, 0x14, None, 'Bottle with Milk', ("Lon Lon Ranch", "Kakariko", "Minigames"))), + ("LLR Freestanding PoH", ("Collectable", 0x4C, 0x01, None, 'Piece of Heart', ("Lon Lon Ranch",))), + ("LLR Deku Scrub Grotto Left", ("GrottoNPC", 0xFC, 0x30, None, 'Buy Deku Nut (5)', ("Lon Lon Ranch", "Deku Scrub", "Grottos"))), + ("LLR Deku Scrub Grotto Center", ("GrottoNPC", 0xFC, 0x33, None, 'Buy Deku Seeds (30)', ("Lon Lon Ranch", "Deku Scrub", "Grottos"))), + ("LLR Deku Scrub Grotto Right", ("GrottoNPC", 0xFC, 0x37, None, 'Buy Bombs (5) [35]', ("Lon Lon Ranch", "Deku Scrub", "Grottos"))), + ("LLR Stables Left Cow", ("NPC", 0x36, 0x15, None, 'Milk', ("Lon Lon Ranch", "Cow",))), + ("LLR Stables Right Cow", ("NPC", 0x36, 0x16, None, 'Milk', ("Lon Lon Ranch", "Cow",))), + ("LLR Tower Left Cow", ("NPC", 0x4C, 0x16, None, 'Milk', ("Lon Lon Ranch", "Cow",))), + ("LLR Tower Right Cow", ("NPC", 0x4C, 0x15, None, 'Milk', ("Lon Lon Ranch", "Cow",))), + ("LLR GS House Window", ("GS Token", 0x0B, 0x04, None, 'Gold Skulltula Token', ("Lon Lon Ranch", "Skulltulas",))), + ("LLR GS Tree", ("GS Token", 0x0B, 0x08, None, 'Gold Skulltula Token', ("Lon Lon Ranch", "Skulltulas",))), + ("LLR GS Rain Shed", ("GS Token", 0x0B, 0x02, None, 'Gold Skulltula Token', ("Lon Lon Ranch", "Skulltulas",))), + ("LLR GS Back Wall", ("GS Token", 0x0B, 0x01, None, 'Gold Skulltula Token', ("Lon Lon Ranch", "Skulltulas",))), + + # Kakariko + ("Kak Anju as Child", ("NPC", 0x52, 0x0F, None, 'Bottle', ("Kakariko Village", "Kakariko", "Minigames"))), + ("Kak Anju as Adult", ("NPC", 0x52, 0x1D, None, 'Pocket Egg', ("Kakariko Village", "Kakariko",))), + ("Kak Impas House Freestanding PoH", ("Collectable", 0x37, 0x01, None, 'Piece of Heart', ("Kakariko Village", "Kakariko",))), + ("Kak Windmill Freestanding PoH", ("Collectable", 0x48, 0x01, None, 'Piece of Heart', ("Kakariko Village", "Kakariko",))), + ("Kak Man on Roof", ("NPC", 0x52, 0x3E, None, 'Piece of Heart', ("Kakariko Village", "Kakariko",))), + ("Kak Open Grotto Chest", ("Chest", 0x3E, 0x08, None, 'Rupees (20)', ("Kakariko Village", "Kakariko", "Grottos"))), + ("Kak Redead Grotto Chest", ("Chest", 0x3E, 0x0A, None, 'Rupees (200)', ("Kakariko Village", "Kakariko", "Grottos"))), + ("Kak Shooting Gallery Reward", ("NPC", 0x42, 0x30, None, 'Bow', ("Kakariko Village", "Kakariko", "Minigames"))), + ("Kak 10 Gold Skulltula Reward", ("NPC", 0x50, 0x45, None, 'Progressive Wallet', ("Kakariko Village", "Kakariko", "Skulltula House"))), + ("Kak 20 Gold Skulltula Reward", ("NPC", 0x50, 0x39, None, 'Stone of Agony', ("Kakariko Village", "Kakariko", "Skulltula House"))), + ("Kak 30 Gold Skulltula Reward", ("NPC", 0x50, 0x46, None, 'Progressive Wallet', ("Kakariko Village", "Kakariko", "Skulltula House"))), + ("Kak 40 Gold Skulltula Reward", ("NPC", 0x50, 0x03, None, 'Bombchus (10)', ("Kakariko Village", "Kakariko", "Skulltula House"))), + ("Kak 50 Gold Skulltula Reward", ("NPC", 0x50, 0x3E, None, 'Piece of Heart', ("Kakariko Village", "Kakariko", "Skulltula House"))), + ("Kak Impas House Cow", ("NPC", 0x37, 0x15, None, 'Milk', ("Kakariko Village", "Kakariko", "Cow"))), + ("Kak GS Tree", ("GS Token", 0x10, 0x20, None, 'Gold Skulltula Token', ("Kakariko Village", "Skulltulas",))), + ("Kak GS Guards House", ("GS Token", 0x10, 0x02, None, 'Gold Skulltula Token', ("Kakariko Village", "Skulltulas",))), + ("Kak GS Watchtower", ("GS Token", 0x10, 0x04, None, 'Gold Skulltula Token', ("Kakariko Village", "Skulltulas",))), + ("Kak GS Skulltula House", ("GS Token", 0x10, 0x10, None, 'Gold Skulltula Token', ("Kakariko Village", "Skulltulas",))), + ("Kak GS House Under Construction", ("GS Token", 0x10, 0x08, None, 'Gold Skulltula Token', ("Kakariko Village", "Skulltulas",))), + ("Kak GS Above Impas House", ("GS Token", 0x10, 0x40, None, 'Gold Skulltula Token', ("Kakariko Village", "Skulltulas",))), + ("Kak Bazaar Item 1", ("Shop", 0x2C, 0x38, (shop_address(5, 0), None), 'Buy Hylian Shield', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Bazaar Item 2", ("Shop", 0x2C, 0x39, (shop_address(5, 1), None), 'Buy Bombs (5) [35]', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Bazaar Item 3", ("Shop", 0x2C, 0x3A, (shop_address(5, 2), None), 'Buy Deku Nut (5)', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Bazaar Item 4", ("Shop", 0x2C, 0x3B, (shop_address(5, 3), None), 'Buy Heart', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Bazaar Item 5", ("Shop", 0x2C, 0x3D, (shop_address(5, 4), None), 'Buy Arrows (10)', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Bazaar Item 6", ("Shop", 0x2C, 0x3E, (shop_address(5, 5), None), 'Buy Arrows (50)', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Bazaar Item 7", ("Shop", 0x2C, 0x3F, (shop_address(5, 6), None), 'Buy Deku Stick (1)', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Bazaar Item 8", ("Shop", 0x2C, 0x40, (shop_address(5, 7), None), 'Buy Arrows (30)', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 1", ("Shop", 0x30, 0x30, (shop_address(1, 0), None), 'Buy Deku Nut (5)', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 2", ("Shop", 0x30, 0x31, (shop_address(1, 1), None), 'Buy Fish', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 3", ("Shop", 0x30, 0x32, (shop_address(1, 2), None), 'Buy Red Potion [30]', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 4", ("Shop", 0x30, 0x33, (shop_address(1, 3), None), 'Buy Green Potion', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 5", ("Shop", 0x30, 0x34, (shop_address(1, 4), None), 'Buy Blue Fire', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 6", ("Shop", 0x30, 0x35, (shop_address(1, 5), None), 'Buy Bottle Bug', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 7", ("Shop", 0x30, 0x36, (shop_address(1, 6), None), 'Buy Poe', ("Kakariko Village", "Kakariko", "Shops"))), + ("Kak Potion Shop Item 8", ("Shop", 0x30, 0x37, (shop_address(1, 7), None), 'Buy Fairy\'s Spirit', ("Kakariko Village", "Kakariko", "Shops"))), + + # Graveyard + ("Graveyard Shield Grave Chest", ("Chest", 0x40, 0x00, None, 'Hylian Shield', ("the Graveyard", "Kakariko",))), + ("Graveyard Heart Piece Grave Chest", ("Chest", 0x3F, 0x00, None, 'Piece of Heart', ("the Graveyard", "Kakariko",))), + ("Graveyard Composers Grave Chest", ("Chest", 0x41, 0x00, None, 'Bombs (5)', ("the Graveyard", "Kakariko",))), + ("Graveyard Freestanding PoH", ("Collectable", 0x53, 0x04, None, 'Piece of Heart', ("the Graveyard", "Kakariko",))), + ("Graveyard Dampe Gravedigging Tour", ("Collectable", 0x53, 0x08, None, 'Piece of Heart', ("the Graveyard", "Kakariko",))), + ("Graveyard Hookshot Chest", ("Chest", 0x48, 0x00, None, 'Progressive Hookshot', ("the Graveyard", "Kakariko",))), + ("Graveyard Dampe Race Freestanding PoH", ("Collectable", 0x48, 0x07, None, 'Piece of Heart', ("the Graveyard", "Kakariko", "Minigames"))), + ("Graveyard GS Bean Patch", ("GS Token", 0x10, 0x01, None, 'Gold Skulltula Token', ("the Graveyard", "Skulltulas",))), + ("Graveyard GS Wall", ("GS Token", 0x10, 0x80, None, 'Gold Skulltula Token', ("the Graveyard", "Skulltulas",))), + + # Death Mountain Trail + ("DMT Freestanding PoH", ("Collectable", 0x60, 0x1E, None, 'Piece of Heart', ("Death Mountain Trail", "Death Mountain",))), + ("DMT Chest", ("Chest", 0x60, 0x01, None, 'Rupees (50)', ("Death Mountain Trail", "Death Mountain",))), + ("DMT Storms Grotto Chest", ("Chest", 0x3E, 0x17, None, 'Rupees (200)', ("Death Mountain Trail", "Death Mountain", "Grottos"))), + ("DMT Great Fairy Reward", ("Cutscene", 0xFF, 0x13, None, 'Magic Meter', ("Death Mountain Trail", "Death Mountain", "Fairies"))), + ("DMT Biggoron", ("NPC", 0x60, 0x57, None, 'Biggoron Sword', ("Death Mountain Trail", "Death Mountain",))), + ("DMT Cow Grotto Cow", ("NPC", 0x3E, 0x15, None, 'Milk', ("Death Mountain Trail", "Death Mountain", "Cow", "Grottos"))), + ("DMT GS Near Kak", ("GS Token", 0x0F, 0x04, None, 'Gold Skulltula Token', ("Death Mountain Trail", "Skulltulas",))), + ("DMT GS Bean Patch", ("GS Token", 0x0F, 0x02, None, 'Gold Skulltula Token', ("Death Mountain Trail", "Skulltulas",))), + ("DMT GS Above Dodongos Cavern", ("GS Token", 0x0F, 0x08, None, 'Gold Skulltula Token', ("Death Mountain Trail", "Skulltulas",))), + ("DMT GS Falling Rocks Path", ("GS Token", 0x0F, 0x10, None, 'Gold Skulltula Token', ("Death Mountain Trail", "Skulltulas",))), + + # Goron City + ("GC Darunias Joy", ("NPC", 0x62, 0x54, None, 'Progressive Strength Upgrade', ("Goron City",))), + ("GC Pot Freestanding PoH", ("Collectable", 0x62, 0x1F, None, 'Piece of Heart', ("Goron City", "Goron City",))), + ("GC Rolling Goron as Child", ("NPC", 0x62, 0x34, None, 'Bomb Bag', ("Goron City",))), + ("GC Rolling Goron as Adult", ("NPC", 0x62, 0x2C, None, 'Goron Tunic', ("Goron City",))), + ("GC Medigoron", ("NPC", 0x62, 0x28, None, 'Giants Knife', ("Goron City",))), + ("GC Maze Left Chest", ("Chest", 0x62, 0x00, None, 'Rupees (200)', ("Goron City",))), + ("GC Maze Right Chest", ("Chest", 0x62, 0x01, None, 'Rupees (50)', ("Goron City",))), + ("GC Maze Center Chest", ("Chest", 0x62, 0x02, None, 'Rupees (50)', ("Goron City",))), + ("GC Deku Scrub Grotto Left", ("GrottoNPC", 0xFB, 0x30, None, 'Buy Deku Nut (5)', ("Goron City", "Deku Scrub", "Grottos"))), + ("GC Deku Scrub Grotto Center", ("GrottoNPC", 0xFB, 0x33, None, 'Buy Arrows (30)', ("Goron City", "Deku Scrub", "Grottos"))), + ("GC Deku Scrub Grotto Right", ("GrottoNPC", 0xFB, 0x37, None, 'Buy Bombs (5) [35]', ("Goron City", "Deku Scrub", "Grottos"))), + ("GC GS Center Platform", ("GS Token", 0x0F, 0x20, None, 'Gold Skulltula Token', ("Goron City", "Skulltulas",))), + ("GC GS Boulder Maze", ("GS Token", 0x0F, 0x40, None, 'Gold Skulltula Token', ("Goron City", "Skulltulas",))), + ("GC Shop Item 1", ("Shop", 0x2E, 0x30, (shop_address(8, 0), None), 'Buy Bombs (5) [25]', ("Goron City", "Shops",))), + ("GC Shop Item 2", ("Shop", 0x2E, 0x31, (shop_address(8, 1), None), 'Buy Bombs (10)', ("Goron City", "Shops",))), + ("GC Shop Item 3", ("Shop", 0x2E, 0x32, (shop_address(8, 2), None), 'Buy Bombs (20)', ("Goron City", "Shops",))), + ("GC Shop Item 4", ("Shop", 0x2E, 0x33, (shop_address(8, 3), None), 'Buy Bombs (30)', ("Goron City", "Shops",))), + ("GC Shop Item 5", ("Shop", 0x2E, 0x34, (shop_address(8, 4), None), 'Buy Goron Tunic', ("Goron City", "Shops",))), + ("GC Shop Item 6", ("Shop", 0x2E, 0x35, (shop_address(8, 5), None), 'Buy Heart', ("Goron City", "Shops",))), + ("GC Shop Item 7", ("Shop", 0x2E, 0x36, (shop_address(8, 6), None), 'Buy Red Potion [40]', ("Goron City", "Shops",))), + ("GC Shop Item 8", ("Shop", 0x2E, 0x37, (shop_address(8, 7), None), 'Buy Heart', ("Goron City", "Shops",))), + + # Death Mountain Crater + ("DMC Volcano Freestanding PoH", ("Collectable", 0x61, 0x08, None, 'Piece of Heart', ("Death Mountain Crater", "Death Mountain",))), + ("DMC Wall Freestanding PoH", ("Collectable", 0x61, 0x02, None, 'Piece of Heart', ("Death Mountain Crater", "Death Mountain",))), + ("DMC Upper Grotto Chest", ("Chest", 0x3E, 0x1A, None, 'Bombs (20)', ("Death Mountain Crater", "Death Mountain", "Grottos"))), + ("DMC Great Fairy Reward", ("Cutscene", 0xFF, 0x14, None, 'Magic Meter', ("Death Mountain Crater", "Death Mountain", "Fairies",))), + ("DMC Deku Scrub", ("NPC", 0x61, 0x37, None, 'Buy Bombs (5) [35]', ("Death Mountain Crater", "Death Mountain", "Deku Scrub"))), + ("DMC Deku Scrub Grotto Left", ("GrottoNPC", 0xF9, 0x30, None, 'Buy Deku Nut (5)', ("Death Mountain Crater", "Death Mountain", "Deku Scrub", "Grottos"))), + ("DMC Deku Scrub Grotto Center", ("GrottoNPC", 0xF9, 0x33, None, 'Buy Arrows (30)', ("Death Mountain Crater", "Death Mountain", "Deku Scrub", "Grottos"))), + ("DMC Deku Scrub Grotto Right", ("GrottoNPC", 0xF9, 0x37, None, 'Buy Bombs (5) [35]', ("Death Mountain Crater", "Death Mountain", "Deku Scrub", "Grottos"))), + ("DMC GS Crate", ("GS Token", 0x0F, 0x80, None, 'Gold Skulltula Token', ("Death Mountain Crater", "Skulltulas",))), + ("DMC GS Bean Patch", ("GS Token", 0x0F, 0x01, None, 'Gold Skulltula Token', ("Death Mountain Crater", "Skulltulas",))), + + # Zora's River + ("ZR Magic Bean Salesman", ("NPC", 0x54, 0x16, None, 'Magic Bean', ("Zora's River",))), + ("ZR Open Grotto Chest", ("Chest", 0x3E, 0x09, None, 'Rupees (20)', ("Zora's River", "Grottos",))), + ("ZR Frogs in the Rain", ("NPC", 0x54, 0x3E, None, 'Piece of Heart', ("Zora's River", "Minigames",))), + ("ZR Frogs Ocarina Game", ("NPC", 0x54, 0x76, None, 'Piece of Heart', ("Zora's River",))), + ("ZR Near Open Grotto Freestanding PoH", ("Collectable", 0x54, 0x04, None, 'Piece of Heart', ("Zora's River",))), + ("ZR Near Domain Freestanding PoH", ("Collectable", 0x54, 0x0B, None, 'Piece of Heart', ("Zora's River",))), + ("ZR Deku Scrub Grotto Front", ("GrottoNPC", 0xEB, 0x3A, None, 'Buy Green Potion', ("Zora's River", "Deku Scrub", "Grottos"))), + ("ZR Deku Scrub Grotto Rear", ("GrottoNPC", 0xEB, 0x39, None, 'Buy Red Potion [30]', ("Zora's River", "Deku Scrub", "Grottos"))), + ("ZR GS Tree", ("GS Token", 0x11, 0x02, None, 'Gold Skulltula Token', ("Zora's River", "Skulltulas",))), + ("ZR GS Ladder", ("GS Token", 0x11, 0x01, None, 'Gold Skulltula Token', ("Zora's River", "Skulltulas",))), + ("ZR GS Near Raised Grottos", ("GS Token", 0x11, 0x10, None, 'Gold Skulltula Token', ("Zora's River", "Skulltulas",))), + ("ZR GS Above Bridge", ("GS Token", 0x11, 0x08, None, 'Gold Skulltula Token', ("Zora's River", "Skulltulas",))), + + # Zora's Domain + ("ZD Diving Minigame", ("NPC", 0x58, 0x37, None, 'Progressive Scale', ("Zora's Domain", "Minigames",))), + ("ZD Chest", ("Chest", 0x58, 0x00, None, 'Piece of Heart', ("Zora's Domain", ))), + ("ZD King Zora Thawed", ("NPC", 0x58, 0x2D, None, 'Zora Tunic', ("Zora's Domain",))), + ("ZD GS Frozen Waterfall", ("GS Token", 0x11, 0x40, None, 'Gold Skulltula Token', ("Zora's Domain", "Skulltulas",))), + ("ZD Shop Item 1", ("Shop", 0x2F, 0x30, (shop_address(7, 0), None), 'Buy Zora Tunic', ("Zora's Domain", "Shops",))), + ("ZD Shop Item 2", ("Shop", 0x2F, 0x31, (shop_address(7, 1), None), 'Buy Arrows (10)', ("Zora's Domain", "Shops",))), + ("ZD Shop Item 3", ("Shop", 0x2F, 0x32, (shop_address(7, 2), None), 'Buy Heart', ("Zora's Domain", "Shops",))), + ("ZD Shop Item 4", ("Shop", 0x2F, 0x33, (shop_address(7, 3), None), 'Buy Arrows (30)', ("Zora's Domain", "Shops",))), + ("ZD Shop Item 5", ("Shop", 0x2F, 0x34, (shop_address(7, 4), None), 'Buy Deku Nut (5)', ("Zora's Domain", "Shops",))), + ("ZD Shop Item 6", ("Shop", 0x2F, 0x35, (shop_address(7, 5), None), 'Buy Arrows (50)', ("Zora's Domain", "Shops",))), + ("ZD Shop Item 7", ("Shop", 0x2F, 0x36, (shop_address(7, 6), None), 'Buy Fish', ("Zora's Domain", "Shops",))), + ("ZD Shop Item 8", ("Shop", 0x2F, 0x37, (shop_address(7, 7), None), 'Buy Red Potion [50]', ("Zora's Domain", "Shops",))), + + # Zora's Fountain + ("ZF Great Fairy Reward", ("Cutscene", 0xFF, 0x10, None, 'Farores Wind', ("Zora's Fountain", "Fairies",))), + ("ZF Iceberg Freestanding PoH", ("Collectable", 0x59, 0x01, None, 'Piece of Heart', ("Zora's Fountain",))), + ("ZF Bottom Freestanding PoH", ("Collectable", 0x59, 0x14, None, 'Piece of Heart', ("Zora's Fountain",))), + ("ZF GS Above the Log", ("GS Token", 0x11, 0x04, None, 'Gold Skulltula Token', ("Zora's Fountain", "Skulltulas",))), + ("ZF GS Tree", ("GS Token", 0x11, 0x80, None, 'Gold Skulltula Token', ("Zora's Fountain", "Skulltulas",))), + ("ZF GS Hidden Cave", ("GS Token", 0x11, 0x20, None, 'Gold Skulltula Token', ("Zora's Fountain", "Skulltulas",))), + + # Lake Hylia + ("LH Underwater Item", ("NPC", 0x57, 0x15, None, 'Rutos Letter', ("Lake Hylia",))), + ("LH Child Fishing", ("NPC", 0x49, 0x3E, None, 'Piece of Heart', ("Lake Hylia", "Minigames",))), + ("LH Adult Fishing", ("NPC", 0x49, 0x38, None, 'Progressive Scale', ("Lake Hylia", "Minigames",))), + ("LH Lab Dive", ("NPC", 0x38, 0x3E, None, 'Piece of Heart', ("Lake Hylia",))), + ("LH Freestanding PoH", ("Collectable", 0x57, 0x1E, None, 'Piece of Heart', ("Lake Hylia",))), + ("LH Sun", ("NPC", 0x57, 0x58, None, 'Fire Arrows', ("Lake Hylia",))), + ("LH Deku Scrub Grotto Left", ("GrottoNPC", 0xEF, 0x30, None, 'Buy Deku Nut (5)', ("Lake Hylia", "Deku Scrub", "Grottos"))), + ("LH Deku Scrub Grotto Center", ("GrottoNPC", 0xEF, 0x33, None, 'Buy Deku Seeds (30)', ("Lake Hylia", "Deku Scrub", "Grottos"))), + ("LH Deku Scrub Grotto Right", ("GrottoNPC", 0xEF, 0x37, None, 'Buy Bombs (5) [35]', ("Lake Hylia", "Deku Scrub", "Grottos"))), + ("LH GS Bean Patch", ("GS Token", 0x12, 0x01, None, 'Gold Skulltula Token', ("Lake Hylia", "Skulltulas",))), + ("LH GS Lab Wall", ("GS Token", 0x12, 0x04, None, 'Gold Skulltula Token', ("Lake Hylia", "Skulltulas",))), + ("LH GS Small Island", ("GS Token", 0x12, 0x02, None, 'Gold Skulltula Token', ("Lake Hylia", "Skulltulas",))), + ("LH GS Lab Crate", ("GS Token", 0x12, 0x08, None, 'Gold Skulltula Token', ("Lake Hylia", "Skulltulas",))), + ("LH GS Tree", ("GS Token", 0x12, 0x10, None, 'Gold Skulltula Token', ("Lake Hylia", "Skulltulas",))), + + # Gerudo Valley + ("GV Crate Freestanding PoH", ("Collectable", 0x5A, 0x02, None, 'Piece of Heart', ("Gerudo Valley", "Gerudo",))), + ("GV Waterfall Freestanding PoH", ("Collectable", 0x5A, 0x01, None, 'Piece of Heart', ("Gerudo Valley", "Gerudo",))), + ("GV Chest", ("Chest", 0x5A, 0x00, None, 'Rupees (50)', ("Gerudo Valley", "Gerudo",))), + ("GV Deku Scrub Grotto Front", ("GrottoNPC", 0xF0, 0x3A, None, 'Buy Green Potion', ("Gerudo Valley", "Gerudo", "Deku Scrub", "Grottos"))), + ("GV Deku Scrub Grotto Rear", ("GrottoNPC", 0xF0, 0x39, None, 'Buy Red Potion [30]', ("Gerudo Valley", "Gerudo", "Deku Scrub", "Grottos"))), + ("GV Cow", ("NPC", 0x5A, 0x15, None, 'Milk', ("Gerudo Valley", "Gerudo", "Cow"))), + ("GV GS Small Bridge", ("GS Token", 0x13, 0x02, None, 'Gold Skulltula Token', ("Gerudo Valley", "Skulltulas",))), + ("GV GS Bean Patch", ("GS Token", 0x13, 0x01, None, 'Gold Skulltula Token', ("Gerudo Valley", "Skulltulas",))), + ("GV GS Behind Tent", ("GS Token", 0x13, 0x08, None, 'Gold Skulltula Token', ("Gerudo Valley", "Skulltulas",))), + ("GV GS Pillar", ("GS Token", 0x13, 0x04, None, 'Gold Skulltula Token', ("Gerudo Valley", "Skulltulas",))), + + # Gerudo's Fortress + ("GF North F1 Carpenter", ("Collectable", 0x0C, 0x0C, None, 'Small Key (Gerudo Fortress)', ("Gerudo's Fortress", "Gerudo",))), + ("GF North F2 Carpenter", ("Collectable", 0x0C, 0x0A, None, 'Small Key (Gerudo Fortress)', ("Gerudo's Fortress", "Gerudo",))), + ("GF South F1 Carpenter", ("Collectable", 0x0C, 0x0E, None, 'Small Key (Gerudo Fortress)', ("Gerudo's Fortress", "Gerudo",))), + ("GF South F2 Carpenter", ("Collectable", 0x0C, 0x0F, None, 'Small Key (Gerudo Fortress)', ("Gerudo's Fortress", "Gerudo",))), + ("GF Gerudo Membership Card", ("NPC", 0x0C, 0x3A, None, 'Gerudo Membership Card', ("Gerudo's Fortress", "Gerudo",))), + ("GF Chest", ("Chest", 0x5D, 0x00, None, 'Piece of Heart', ("Gerudo's Fortress", "Gerudo",))), + ("GF HBA 1000 Points", ("NPC", 0x5D, 0x3E, None, 'Piece of Heart', ("Gerudo's Fortress", "Gerudo", "Minigames"))), + ("GF HBA 1500 Points", ("NPC", 0x5D, 0x30, None, 'Bow', ("Gerudo's Fortress", "Gerudo", "Minigames"))), + ("GF GS Top Floor", ("GS Token", 0x14, 0x02, None, 'Gold Skulltula Token', ("Gerudo's Fortress", "Skulltulas",))), + ("GF GS Archery Range", ("GS Token", 0x14, 0x01, None, 'Gold Skulltula Token', ("Gerudo's Fortress", "Skulltulas",))), + + # Wasteland + ("Wasteland Bombchu Salesman", ("NPC", 0x5E, 0x03, None, 'Bombchus (10)', ("Haunted Wasteland",))), + ("Wasteland Chest", ("Chest", 0x5E, 0x00, None, 'Rupees (50)', ("Haunted Wasteland",))), + ("Wasteland GS", ("GS Token", 0x15, 0x02, None, 'Gold Skulltula Token', ("Haunted Wasteland", "Skulltulas",))), + + # Colossus + ("Colossus Great Fairy Reward", ("Cutscene", 0xFF, 0x12, None, 'Nayrus Love', ("Desert Colossus", "Fairies",))), + ("Colossus Freestanding PoH", ("Collectable", 0x5C, 0x0D, None, 'Piece of Heart', ("Desert Colossus",))), + ("Colossus Deku Scrub Grotto Front", ("GrottoNPC", 0xFD, 0x3A, None, 'Buy Green Potion', ("Desert Colossus", "Deku Scrub", "Grottos"))), + ("Colossus Deku Scrub Grotto Rear", ("GrottoNPC", 0xFD, 0x39, None, 'Buy Red Potion [30]', ("Desert Colossus", "Deku Scrub", "Grottos"))), + ("Colossus GS Bean Patch", ("GS Token", 0x15, 0x01, None, 'Gold Skulltula Token', ("Desert Colossus", "Skulltulas",))), + ("Colossus GS Tree", ("GS Token", 0x15, 0x08, None, 'Gold Skulltula Token', ("Desert Colossus", "Skulltulas",))), + ("Colossus GS Hill", ("GS Token", 0x15, 0x04, None, 'Gold Skulltula Token', ("Desert Colossus", "Skulltulas",))), + + # Outside Ganon's Castle + ("OGC Great Fairy Reward", ("Cutscene", 0xFF, 0x15, None, 'Double Defense', ("outside Ganon's Castle", "Market", "Fairies"))), + ("OGC GS", ("GS Token", 0x0E, 0x01, None, 'Gold Skulltula Token', ("outside Ganon's Castle", "Skulltulas",))), + + ## Dungeons + # Deku Tree vanilla + ("Deku Tree Map Chest", ("Chest", 0x00, 0x03, None, 'Map (Deku Tree)', ("Deku Tree", "Vanilla",))), + ("Deku Tree Slingshot Room Side Chest", ("Chest", 0x00, 0x05, None, 'Recovery Heart', ("Deku Tree", "Vanilla",))), + ("Deku Tree Slingshot Chest", ("Chest", 0x00, 0x01, None, 'Slingshot', ("Deku Tree", "Vanilla",))), + ("Deku Tree Compass Chest", ("Chest", 0x00, 0x02, None, 'Compass (Deku Tree)', ("Deku Tree", "Vanilla",))), + ("Deku Tree Compass Room Side Chest", ("Chest", 0x00, 0x06, None, 'Recovery Heart', ("Deku Tree", "Vanilla",))), + ("Deku Tree Basement Chest", ("Chest", 0x00, 0x04, None, 'Recovery Heart', ("Deku Tree", "Vanilla",))), + ("Deku Tree GS Compass Room", ("GS Token", 0x00, 0x08, None, 'Gold Skulltula Token', ("Deku Tree", "Vanilla", "Skulltulas",))), + ("Deku Tree GS Basement Vines", ("GS Token", 0x00, 0x04, None, 'Gold Skulltula Token', ("Deku Tree", "Vanilla", "Skulltulas",))), + ("Deku Tree GS Basement Gate", ("GS Token", 0x00, 0x02, None, 'Gold Skulltula Token', ("Deku Tree", "Vanilla", "Skulltulas",))), + ("Deku Tree GS Basement Back Room", ("GS Token", 0x00, 0x01, None, 'Gold Skulltula Token', ("Deku Tree", "Vanilla", "Skulltulas",))), + # Deku Tree MQ + ("Deku Tree MQ Map Chest", ("Chest", 0x00, 0x03, None, 'Map (Deku Tree)', ("Deku Tree", "Master Quest",))), + ("Deku Tree MQ Slingshot Chest", ("Chest", 0x00, 0x06, None, 'Slingshot', ("Deku Tree", "Master Quest",))), + ("Deku Tree MQ Slingshot Room Back Chest", ("Chest", 0x00, 0x02, None, 'Deku Shield', ("Deku Tree", "Master Quest",))), + ("Deku Tree MQ Compass Chest", ("Chest", 0x00, 0x01, None, 'Compass (Deku Tree)', ("Deku Tree", "Master Quest",))), + ("Deku Tree MQ Basement Chest", ("Chest", 0x00, 0x04, None, 'Deku Shield', ("Deku Tree", "Master Quest",))), + ("Deku Tree MQ Before Spinning Log Chest", ("Chest", 0x00, 0x05, None, 'Recovery Heart', ("Deku Tree", "Master Quest",))), + ("Deku Tree MQ After Spinning Log Chest", ("Chest", 0x00, 0x00, None, 'Rupees (50)', ("Deku Tree", "Master Quest",))), + ("Deku Tree MQ Deku Scrub", ("NPC", 0x00, 0x34, None, 'Buy Deku Shield', ("Deku Tree", "Master Quest", "Deku Scrub",))), + ("Deku Tree MQ GS Lobby", ("GS Token", 0x00, 0x02, None, 'Gold Skulltula Token', ("Deku Tree", "Master Quest", "Skulltulas",))), + ("Deku Tree MQ GS Compass Room", ("GS Token", 0x00, 0x08, None, 'Gold Skulltula Token', ("Deku Tree", "Master Quest", "Skulltulas",))), + ("Deku Tree MQ GS Basement Graves Room", ("GS Token", 0x00, 0x04, None, 'Gold Skulltula Token', ("Deku Tree", "Master Quest", "Skulltulas",))), + ("Deku Tree MQ GS Basement Back Room", ("GS Token", 0x00, 0x01, None, 'Gold Skulltula Token', ("Deku Tree", "Master Quest", "Skulltulas",))), + # Deku Tree shared + ("Deku Tree Queen Gohma Heart", ("BossHeart", 0x11, 0x4F, None, 'Heart Container', ("Deku Tree", "Vanilla", "Master Quest",))), + + # Dodongo's Cavern vanilla + ("Dodongos Cavern Map Chest", ("Chest", 0x01, 0x08, None, 'Map (Dodongos Cavern)', ("Dodongo's Cavern", "Vanilla",))), + ("Dodongos Cavern Compass Chest", ("Chest", 0x01, 0x05, None, 'Compass (Dodongos Cavern)', ("Dodongo's Cavern", "Vanilla",))), + ("Dodongos Cavern Bomb Flower Platform Chest", ("Chest", 0x01, 0x06, None, 'Rupees (20)', ("Dodongo's Cavern", "Vanilla",))), + ("Dodongos Cavern Bomb Bag Chest", ("Chest", 0x01, 0x04, None, 'Bomb Bag', ("Dodongo's Cavern", "Vanilla",))), + ("Dodongos Cavern End of Bridge Chest", ("Chest", 0x01, 0x0A, None, 'Deku Shield', ("Dodongo's Cavern", "Vanilla",))), + ("Dodongos Cavern Deku Scrub Side Room Near Dodongos", ("NPC", 0x01, 0x31, None, 'Buy Deku Stick (1)', ("Dodongo's Cavern", "Vanilla", "Deku Scrub",))), + ("Dodongos Cavern Deku Scrub Lobby", ("NPC", 0x01, 0x34, None, 'Buy Deku Shield', ("Dodongo's Cavern", "Vanilla", "Deku Scrub",))), + ("Dodongos Cavern Deku Scrub Near Bomb Bag Left", ("NPC", 0x01, 0x30, None, 'Buy Deku Nut (5)', ("Dodongo's Cavern", "Vanilla", "Deku Scrub",))), + ("Dodongos Cavern Deku Scrub Near Bomb Bag Right", ("NPC", 0x01, 0x33, None, 'Buy Deku Seeds (30)', ("Dodongo's Cavern", "Vanilla", "Deku Scrub",))), + ("Dodongos Cavern GS Side Room Near Lower Lizalfos", ("GS Token", 0x01, 0x10, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Vanilla", "Skulltulas",))), + ("Dodongos Cavern GS Scarecrow", ("GS Token", 0x01, 0x02, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Vanilla", "Skulltulas",))), + ("Dodongos Cavern GS Alcove Above Stairs", ("GS Token", 0x01, 0x04, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Vanilla", "Skulltulas",))), + ("Dodongos Cavern GS Vines Above Stairs", ("GS Token", 0x01, 0x01, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Vanilla", "Skulltulas",))), + ("Dodongos Cavern GS Back Room", ("GS Token", 0x01, 0x08, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Vanilla", "Skulltulas",))), + # Dodongo's Cavern MQ + ("Dodongos Cavern MQ Map Chest", ("Chest", 0x01, 0x00, None, 'Map (Dodongos Cavern)', ("Dodongo's Cavern", "Master Quest",))), + ("Dodongos Cavern MQ Bomb Bag Chest", ("Chest", 0x01, 0x04, None, 'Bomb Bag', ("Dodongo's Cavern", "Master Quest",))), + ("Dodongos Cavern MQ Torch Puzzle Room Chest", ("Chest", 0x01, 0x03, None, 'Rupees (5)', ("Dodongo's Cavern", "Master Quest",))), + ("Dodongos Cavern MQ Larvae Room Chest", ("Chest", 0x01, 0x02, None, 'Deku Shield', ("Dodongo's Cavern", "Master Quest",))), + ("Dodongos Cavern MQ Compass Chest", ("Chest", 0x01, 0x05, None, 'Compass (Dodongos Cavern)', ("Dodongo's Cavern", "Master Quest",))), + ("Dodongos Cavern MQ Under Grave Chest", ("Chest", 0x01, 0x01, None, 'Hylian Shield', ("Dodongo's Cavern", "Master Quest",))), + ("Dodongos Cavern MQ Deku Scrub Lobby Front", ("NPC", 0x01, 0x33, None, 'Buy Deku Seeds (30)', ("Dodongo's Cavern", "Master Quest", "Deku Scrub",))), + ("Dodongos Cavern MQ Deku Scrub Lobby Rear", ("NPC", 0x01, 0x31, None, 'Buy Deku Stick (1)', ("Dodongo's Cavern", "Master Quest", "Deku Scrub",))), + ("Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos", ("NPC", 0x01, 0x39, None, 'Buy Red Potion [30]', ("Dodongo's Cavern", "Master Quest", "Deku Scrub",))), + ("Dodongos Cavern MQ Deku Scrub Staircase", ("NPC", 0x01, 0x34, None, 'Buy Deku Shield', ("Dodongo's Cavern", "Master Quest", "Deku Scrub",))), + ("Dodongos Cavern MQ GS Scrub Room", ("GS Token", 0x01, 0x02, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Master Quest", "Skulltulas",))), + ("Dodongos Cavern MQ GS Larvae Room", ("GS Token", 0x01, 0x10, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Master Quest", "Skulltulas",))), + ("Dodongos Cavern MQ GS Lizalfos Room", ("GS Token", 0x01, 0x04, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Master Quest", "Skulltulas",))), + ("Dodongos Cavern MQ GS Song of Time Block Room", ("GS Token", 0x01, 0x08, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Master Quest", "Skulltulas",))), + ("Dodongos Cavern MQ GS Back Area", ("GS Token", 0x01, 0x01, None, 'Gold Skulltula Token', ("Dodongo's Cavern", "Master Quest", "Skulltulas",))), + # Dodongo's Cavern shared + ("Dodongos Cavern Boss Room Chest", ("Chest", 0x12, 0x00, None, 'Bombs (5)', ("Dodongo's Cavern", "Vanilla", "Master Quest",))), + ("Dodongos Cavern King Dodongo Heart", ("BossHeart", 0x12, 0x4F, None, 'Heart Container', ("Dodongo's Cavern", "Vanilla", "Master Quest",))), + + # Jabu Jabu's Belly vanilla + ("Jabu Jabus Belly Boomerang Chest", ("Chest", 0x02, 0x01, None, 'Boomerang', ("Jabu Jabu's Belly", "Vanilla",))), + ("Jabu Jabus Belly Map Chest", ("Chest", 0x02, 0x02, None, 'Map (Jabu Jabus Belly)', ("Jabu Jabu's Belly", "Vanilla",))), + ("Jabu Jabus Belly Compass Chest", ("Chest", 0x02, 0x04, None, 'Compass (Jabu Jabus Belly)', ("Jabu Jabu's Belly", "Vanilla",))), + ("Jabu Jabus Belly Deku Scrub", ("NPC", 0x02, 0x30, None, 'Buy Deku Nut (5)', ("Jabu Jabu's Belly", "Vanilla", "Deku Scrub",))), + ("Jabu Jabus Belly GS Water Switch Room", ("GS Token", 0x02, 0x08, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Vanilla", "Skulltulas",))), + ("Jabu Jabus Belly GS Lobby Basement Lower", ("GS Token", 0x02, 0x01, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Vanilla", "Skulltulas",))), + ("Jabu Jabus Belly GS Lobby Basement Upper", ("GS Token", 0x02, 0x02, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Vanilla", "Skulltulas",))), + ("Jabu Jabus Belly GS Near Boss", ("GS Token", 0x02, 0x04, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Vanilla", "Skulltulas",))), + # Jabu Jabu's Belly MQ + ("Jabu Jabus Belly MQ Map Chest", ("Chest", 0x02, 0x03, None, 'Map (Jabu Jabus Belly)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ First Room Side Chest", ("Chest", 0x02, 0x05, None, 'Deku Nuts (5)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Second Room Lower Chest", ("Chest", 0x02, 0x02, None, 'Deku Nuts (5)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Compass Chest", ("Chest", 0x02, 0x00, None, 'Compass (Jabu Jabus Belly)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Basement Near Switches Chest", ("Chest", 0x02, 0x08, None, 'Deku Nuts (5)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Basement Near Vines Chest", ("Chest", 0x02, 0x04, None, 'Bombchus (10)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Boomerang Room Small Chest", ("Chest", 0x02, 0x01, None, 'Deku Nuts (5)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Boomerang Chest", ("Chest", 0x02, 0x06, None, 'Boomerang', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Falling Like Like Room Chest", ("Chest", 0x02, 0x09, None, 'Deku Stick (1)', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Second Room Upper Chest", ("Chest", 0x02, 0x07, None, 'Recovery Heart', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Near Boss Chest", ("Chest", 0x02, 0x0A, None, 'Deku Shield', ("Jabu Jabu's Belly", "Master Quest",))), + ("Jabu Jabus Belly MQ Cow", ("NPC", 0x02, 0x15, None, 'Milk', ("Jabu Jabu's Belly", "Master Quest", "Cow",))), + ("Jabu Jabus Belly MQ GS Boomerang Chest Room", ("GS Token", 0x02, 0x01, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Master Quest", "Skulltulas",))), + ("Jabu Jabus Belly MQ GS Tailpasaran Room", ("GS Token", 0x02, 0x04, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Master Quest", "Skulltulas",))), + ("Jabu Jabus Belly MQ GS Invisible Enemies Room", ("GS Token", 0x02, 0x08, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Master Quest", "Skulltulas",))), + ("Jabu Jabus Belly MQ GS Near Boss", ("GS Token", 0x02, 0x02, None, 'Gold Skulltula Token', ("Jabu Jabu's Belly", "Master Quest", "Skulltulas",))), + # Jabu Jabu's Belly shared + ("Jabu Jabus Belly Barinade Heart", ("BossHeart", 0x13, 0x4F, None, 'Heart Container', ("Jabu Jabu's Belly", "Vanilla", "Master Quest",))), + + # Bottom of the Well vanilla + ("Bottom of the Well Front Left Fake Wall Chest", ("Chest", 0x08, 0x08, None, 'Small Key (Bottom of the Well)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Front Center Bombable Chest", ("Chest", 0x08, 0x02, None, 'Bombchus (10)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Back Left Bombable Chest", ("Chest", 0x08, 0x04, None, 'Deku Nuts (10)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Underwater Left Chest", ("Chest", 0x08, 0x09, None, 'Recovery Heart', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Freestanding Key", ("Collectable", 0x08, 0x01, None, 'Small Key (Bottom of the Well)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Compass Chest", ("Chest", 0x08, 0x01, None, 'Compass (Bottom of the Well)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Center Skulltula Chest", ("Chest", 0x08, 0x0E, None, 'Deku Nuts (5)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Right Bottom Fake Wall Chest", ("Chest", 0x08, 0x05, None, 'Small Key (Bottom of the Well)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Fire Keese Chest", ("Chest", 0x08, 0x0A, None, 'Deku Shield', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Like Like Chest", ("Chest", 0x08, 0x0C, None, 'Hylian Shield', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Map Chest", ("Chest", 0x08, 0x07, None, 'Map (Bottom of the Well)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Underwater Front Chest", ("Chest", 0x08, 0x10, None, 'Bombs (10)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Invisible Chest", ("Chest", 0x08, 0x14, None, 'Rupees (200)', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well Lens of Truth Chest", ("Chest", 0x08, 0x03, None, 'Lens of Truth', ("Bottom of the Well", "Vanilla",))), + ("Bottom of the Well GS West Inner Room", ("GS Token", 0x08, 0x04, None, 'Gold Skulltula Token', ("Bottom of the Well", "Vanilla", "Skulltulas",))), + ("Bottom of the Well GS East Inner Room", ("GS Token", 0x08, 0x02, None, 'Gold Skulltula Token', ("Bottom of the Well", "Vanilla", "Skulltulas",))), + ("Bottom of the Well GS Like Like Cage", ("GS Token", 0x08, 0x01, None, 'Gold Skulltula Token', ("Bottom of the Well", "Vanilla", "Skulltulas",))), + # Bottom of the Well MQ + ("Bottom of the Well MQ Map Chest", ("Chest", 0x08, 0x03, None, 'Map (Bottom of the Well)', ("Bottom of the Well", "Master Quest",))), + ("Bottom of the Well MQ East Inner Room Freestanding Key", ("Collectable", 0x08, 0x01, None, 'Small Key (Bottom of the Well)', ("Bottom of the Well", "Master Quest",))), + ("Bottom of the Well MQ Compass Chest", ("Chest", 0x08, 0x02, None, 'Compass (Bottom of the Well)', ("Bottom of the Well", "Master Quest",))), + ("Bottom of the Well MQ Dead Hand Freestanding Key", ("Collectable", 0x08, 0x02, None, 'Small Key (Bottom of the Well)', ("Bottom of the Well", "Master Quest",))), + ("Bottom of the Well MQ Lens of Truth Chest", ("Chest", 0x08, 0x01, None, 'Lens of Truth', ("Bottom of the Well", "Master Quest",))), + ("Bottom of the Well MQ GS Coffin Room", ("GS Token", 0x08, 0x04, None, 'Gold Skulltula Token', ("Bottom of the Well", "Master Quest", "Skulltulas",))), + ("Bottom of the Well MQ GS West Inner Room", ("GS Token", 0x08, 0x02, None, 'Gold Skulltula Token', ("Bottom of the Well", "Master Quest", "Skulltulas",))), + ("Bottom of the Well MQ GS Basement", ("GS Token", 0x08, 0x01, None, 'Gold Skulltula Token', ("Bottom of the Well", "Master Quest", "Skulltulas",))), + + # Forest Temple vanilla + ("Forest Temple First Room Chest", ("Chest", 0x03, 0x03, None, 'Small Key (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple First Stalfos Chest", ("Chest", 0x03, 0x00, None, 'Small Key (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Raised Island Courtyard Chest", ("Chest", 0x03, 0x05, None, 'Recovery Heart', ("Forest Temple", "Vanilla",))), + ("Forest Temple Map Chest", ("Chest", 0x03, 0x01, None, 'Map (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Well Chest", ("Chest", 0x03, 0x09, None, 'Small Key (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Eye Switch Chest", ("Chest", 0x03, 0x04, None, 'Arrows (30)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Boss Key Chest", ("Chest", 0x03, 0x0E, None, 'Boss Key (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Floormaster Chest", ("Chest", 0x03, 0x02, None, 'Small Key (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Red Poe Chest", ("Chest", 0x03, 0x0D, None, 'Small Key (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Bow Chest", ("Chest", 0x03, 0x0C, None, 'Bow', ("Forest Temple", "Vanilla",))), + ("Forest Temple Blue Poe Chest", ("Chest", 0x03, 0x0F, None, 'Compass (Forest Temple)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Falling Ceiling Room Chest", ("Chest", 0x03, 0x07, None, 'Arrows (10)', ("Forest Temple", "Vanilla",))), + ("Forest Temple Basement Chest", ("Chest", 0x03, 0x0B, None, 'Arrows (5)', ("Forest Temple", "Vanilla",))), + ("Forest Temple GS First Room", ("GS Token", 0x03, 0x02, None, 'Gold Skulltula Token', ("Forest Temple", "Vanilla", "Skulltulas",))), + ("Forest Temple GS Lobby", ("GS Token", 0x03, 0x08, None, 'Gold Skulltula Token', ("Forest Temple", "Vanilla", "Skulltulas",))), + ("Forest Temple GS Raised Island Courtyard", ("GS Token", 0x03, 0x01, None, 'Gold Skulltula Token', ("Forest Temple", "Vanilla", "Skulltulas",))), + ("Forest Temple GS Level Island Courtyard", ("GS Token", 0x03, 0x04, None, 'Gold Skulltula Token', ("Forest Temple", "Vanilla", "Skulltulas",))), + ("Forest Temple GS Basement", ("GS Token", 0x03, 0x10, None, 'Gold Skulltula Token', ("Forest Temple", "Vanilla", "Skulltulas",))), + # Forest Temple MQ + ("Forest Temple MQ First Room Chest", ("Chest", 0x03, 0x03, None, 'Small Key (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Wolfos Chest", ("Chest", 0x03, 0x00, None, 'Small Key (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Well Chest", ("Chest", 0x03, 0x09, None, 'Small Key (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Raised Island Courtyard Lower Chest", ("Chest", 0x03, 0x01, None, 'Small Key (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Raised Island Courtyard Upper Chest", ("Chest", 0x03, 0x05, None, 'Small Key (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Boss Key Chest", ("Chest", 0x03, 0x0E, None, 'Boss Key (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Redead Chest", ("Chest", 0x03, 0x02, None, 'Small Key (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Map Chest", ("Chest", 0x03, 0x0D, None, 'Map (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Bow Chest", ("Chest", 0x03, 0x0C, None, 'Bow', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Compass Chest", ("Chest", 0x03, 0x0F, None, 'Compass (Forest Temple)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Falling Ceiling Room Chest", ("Chest", 0x03, 0x06, None, 'Arrows (5)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ Basement Chest", ("Chest", 0x03, 0x0B, None, 'Arrows (5)', ("Forest Temple", "Master Quest",))), + ("Forest Temple MQ GS First Hallway", ("GS Token", 0x03, 0x02, None, 'Gold Skulltula Token', ("Forest Temple", "Master Quest", "Skulltulas",))), + ("Forest Temple MQ GS Raised Island Courtyard", ("GS Token", 0x03, 0x01, None, 'Gold Skulltula Token', ("Forest Temple", "Master Quest", "Skulltulas",))), + ("Forest Temple MQ GS Level Island Courtyard", ("GS Token", 0x03, 0x04, None, 'Gold Skulltula Token', ("Forest Temple", "Master Quest", "Skulltulas",))), + ("Forest Temple MQ GS Well", ("GS Token", 0x03, 0x08, None, 'Gold Skulltula Token', ("Forest Temple", "Master Quest", "Skulltulas",))), + ("Forest Temple MQ GS Block Push Room", ("GS Token", 0x03, 0x10, None, 'Gold Skulltula Token', ("Forest Temple", "Master Quest", "Skulltulas",))), + # Forest Temple shared + ("Forest Temple Phantom Ganon Heart", ("BossHeart", 0x14, 0x4F, None, 'Heart Container', ("Forest Temple", "Vanilla", "Master Quest",))), + + # Fire Temple vanilla + ("Fire Temple Near Boss Chest", ("Chest", 0x04, 0x01, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Flare Dancer Chest", ("Chest", 0x04, 0x00, None, 'Bombs (10)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Boss Key Chest", ("Chest", 0x04, 0x0C, None, 'Boss Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Big Lava Room Lower Open Door Chest", ("Chest", 0x04, 0x04, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Big Lava Room Blocked Door Chest", ("Chest", 0x04, 0x02, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Boulder Maze Lower Chest", ("Chest", 0x04, 0x03, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Boulder Maze Side Room Chest", ("Chest", 0x04, 0x08, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Map Chest", ("Chest", 0x04, 0x0A, None, 'Map (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Boulder Maze Shortcut Chest", ("Chest", 0x04, 0x0B, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Boulder Maze Upper Chest", ("Chest", 0x04, 0x06, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Scarecrow Chest", ("Chest", 0x04, 0x0D, None, 'Rupees (200)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Compass Chest", ("Chest", 0x04, 0x07, None, 'Compass (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple Megaton Hammer Chest", ("Chest", 0x04, 0x05, None, 'Megaton Hammer', ("Fire Temple", "Vanilla",))), + ("Fire Temple Highest Goron Chest", ("Chest", 0x04, 0x09, None, 'Small Key (Fire Temple)', ("Fire Temple", "Vanilla",))), + ("Fire Temple GS Boss Key Loop", ("GS Token", 0x04, 0x02, None, 'Gold Skulltula Token', ("Fire Temple", "Vanilla", "Skulltulas",))), + ("Fire Temple GS Song of Time Room", ("GS Token", 0x04, 0x01, None, 'Gold Skulltula Token', ("Fire Temple", "Vanilla", "Skulltulas",))), + ("Fire Temple GS Boulder Maze", ("GS Token", 0x04, 0x04, None, 'Gold Skulltula Token', ("Fire Temple", "Vanilla", "Skulltulas",))), + ("Fire Temple GS Scarecrow Climb", ("GS Token", 0x04, 0x10, None, 'Gold Skulltula Token', ("Fire Temple", "Vanilla", "Skulltulas",))), + ("Fire Temple GS Scarecrow Top", ("GS Token", 0x04, 0x08, None, 'Gold Skulltula Token', ("Fire Temple", "Vanilla", "Skulltulas",))), + # Fire Temple MQ + ("Fire Temple MQ Map Room Side Chest", ("Chest", 0x04, 0x02, None, 'Hylian Shield', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Megaton Hammer Chest", ("Chest", 0x04, 0x00, None, 'Megaton Hammer', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Map Chest", ("Chest", 0x04, 0x0C, None, 'Map (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Near Boss Chest", ("Chest", 0x04, 0x07, None, 'Small Key (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Big Lava Room Blocked Door Chest", ("Chest", 0x04, 0x01, None, 'Small Key (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Boss Key Chest", ("Chest", 0x04, 0x04, None, 'Boss Key (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Lizalfos Maze Side Room Chest", ("Chest", 0x04, 0x08, None, 'Small Key (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Compass Chest", ("Chest", 0x04, 0x0B, None, 'Compass (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Lizalfos Maze Upper Chest", ("Chest", 0x04, 0x06, None, 'Bombs (10)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Lizalfos Maze Lower Chest", ("Chest", 0x04, 0x03, None, 'Bombs (10)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Freestanding Key", ("Collectable", 0x04, 0x1C, None, 'Small Key (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ Chest On Fire", ("Chest", 0x04, 0x05, None, 'Small Key (Fire Temple)', ("Fire Temple", "Master Quest",))), + ("Fire Temple MQ GS Big Lava Room Open Door", ("GS Token", 0x04, 0x01, None, 'Gold Skulltula Token', ("Fire Temple", "Master Quest", "Skulltulas",))), + ("Fire Temple MQ GS Skull On Fire", ("GS Token", 0x04, 0x04, None, 'Gold Skulltula Token', ("Fire Temple", "Master Quest", "Skulltulas",))), + ("Fire Temple MQ GS Fire Wall Maze Center", ("GS Token", 0x04, 0x08, None, 'Gold Skulltula Token', ("Fire Temple", "Master Quest", "Skulltulas",))), + ("Fire Temple MQ GS Fire Wall Maze Side Room", ("GS Token", 0x04, 0x10, None, 'Gold Skulltula Token', ("Fire Temple", "Master Quest", "Skulltulas",))), + ("Fire Temple MQ GS Above Fire Wall Maze", ("GS Token", 0x04, 0x02, None, 'Gold Skulltula Token', ("Fire Temple", "Master Quest", "Skulltulas",))), + # Fire Temple shared + ("Fire Temple Volvagia Heart", ("BossHeart", 0x15, 0x4F, None, 'Heart Container', ("Fire Temple", "Vanilla", "Master Quest",))), + + # Water Temple vanilla + ("Water Temple Compass Chest", ("Chest", 0x05, 0x09, None, 'Compass (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Map Chest", ("Chest", 0x05, 0x02, None, 'Map (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Cracked Wall Chest", ("Chest", 0x05, 0x00, None, 'Small Key (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Torches Chest", ("Chest", 0x05, 0x01, None, 'Small Key (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Boss Key Chest", ("Chest", 0x05, 0x05, None, 'Boss Key (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Central Pillar Chest", ("Chest", 0x05, 0x06, None, 'Small Key (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Central Bow Target Chest", ("Chest", 0x05, 0x08, None, 'Small Key (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Longshot Chest", ("Chest", 0x05, 0x07, None, 'Progressive Hookshot', ("Water Temple", "Vanilla",))), + ("Water Temple River Chest", ("Chest", 0x05, 0x03, None, 'Small Key (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple Dragon Chest", ("Chest", 0x05, 0x0A, None, 'Small Key (Water Temple)', ("Water Temple", "Vanilla",))), + ("Water Temple GS Behind Gate", ("GS Token", 0x05, 0x01, None, 'Gold Skulltula Token', ("Water Temple", "Vanilla", "Skulltulas",))), + ("Water Temple GS Near Boss Key Chest", ("GS Token", 0x05, 0x08, None, 'Gold Skulltula Token', ("Water Temple", "Vanilla", "Skulltulas",))), + ("Water Temple GS Central Pillar", ("GS Token", 0x05, 0x04, None, 'Gold Skulltula Token', ("Water Temple", "Vanilla", "Skulltulas",))), + ("Water Temple GS Falling Platform Room", ("GS Token", 0x05, 0x02, None, 'Gold Skulltula Token', ("Water Temple", "Vanilla", "Skulltulas",))), + ("Water Temple GS River", ("GS Token", 0x05, 0x10, None, 'Gold Skulltula Token', ("Water Temple", "Vanilla", "Skulltulas",))), + # Water Temple MQ + ("Water Temple MQ Longshot Chest", ("Chest", 0x05, 0x00, None, 'Progressive Hookshot', ("Water Temple", "Master Quest",))), + ("Water Temple MQ Map Chest", ("Chest", 0x05, 0x02, None, 'Map (Water Temple)', ("Water Temple", "Master Quest",))), + ("Water Temple MQ Compass Chest", ("Chest", 0x05, 0x01, None, 'Compass (Water Temple)', ("Water Temple", "Master Quest",))), + ("Water Temple MQ Central Pillar Chest", ("Chest", 0x05, 0x06, None, 'Small Key (Water Temple)', ("Water Temple", "Master Quest",))), + ("Water Temple MQ Boss Key Chest", ("Chest", 0x05, 0x05, None, 'Boss Key (Water Temple)', ("Water Temple", "Master Quest",))), + ("Water Temple MQ Freestanding Key", ("Collectable", 0x05, 0x01, None, 'Small Key (Water Temple)', ("Water Temple", "Master Quest",))), + ("Water Temple MQ GS Lizalfos Hallway", ("GS Token", 0x05, 0x01, None, 'Gold Skulltula Token', ("Water Temple", "Master Quest", "Skulltulas",))), + ("Water Temple MQ GS Before Upper Water Switch", ("GS Token", 0x05, 0x04, None, 'Gold Skulltula Token', ("Water Temple", "Master Quest", "Skulltulas",))), + ("Water Temple MQ GS River", ("GS Token", 0x05, 0x02, None, 'Gold Skulltula Token', ("Water Temple", "Master Quest", "Skulltulas",))), + ("Water Temple MQ GS Freestanding Key Area", ("GS Token", 0x05, 0x08, None, 'Gold Skulltula Token', ("Water Temple", "Master Quest", "Skulltulas",))), + ("Water Temple MQ GS Triple Wall Torch", ("GS Token", 0x05, 0x10, None, 'Gold Skulltula Token', ("Water Temple", "Master Quest", "Skulltulas",))), + # Water Temple shared + ("Water Temple Morpha Heart", ("BossHeart", 0x16, 0x4F, None, 'Heart Container', ("Water Temple", "Vanilla", "Master Quest",))), + + # Shadow Temple vanilla + ("Shadow Temple Map Chest", ("Chest", 0x07, 0x01, None, 'Map (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Hover Boots Chest", ("Chest", 0x07, 0x07, None, 'Hover Boots', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Compass Chest", ("Chest", 0x07, 0x03, None, 'Compass (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Early Silver Rupee Chest", ("Chest", 0x07, 0x02, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Invisible Blades Visible Chest", ("Chest", 0x07, 0x0C, None, 'Rupees (5)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Invisible Blades Invisible Chest", ("Chest", 0x07, 0x16, None, 'Arrows (30)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Falling Spikes Lower Chest", ("Chest", 0x07, 0x05, None, 'Arrows (10)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Falling Spikes Upper Chest", ("Chest", 0x07, 0x06, None, 'Rupees (5)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Falling Spikes Switch Chest", ("Chest", 0x07, 0x04, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Invisible Spikes Chest", ("Chest", 0x07, 0x09, None, 'Rupees (5)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Freestanding Key", ("Collectable", 0x07, 0x01, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Wind Hint Chest", ("Chest", 0x07, 0x15, None, 'Arrows (10)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple After Wind Enemy Chest", ("Chest", 0x07, 0x08, None, 'Rupees (5)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple After Wind Hidden Chest", ("Chest", 0x07, 0x14, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Spike Walls Left Chest", ("Chest", 0x07, 0x0A, None, 'Rupees (5)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Boss Key Chest", ("Chest", 0x07, 0x0B, None, 'Boss Key (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple Invisible Floormaster Chest", ("Chest", 0x07, 0x0D, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Vanilla",))), + ("Shadow Temple GS Like Like Room", ("GS Token", 0x07, 0x08, None, 'Gold Skulltula Token', ("Shadow Temple", "Vanilla", "Skulltulas",))), + ("Shadow Temple GS Falling Spikes Room", ("GS Token", 0x07, 0x02, None, 'Gold Skulltula Token', ("Shadow Temple", "Vanilla", "Skulltulas",))), + ("Shadow Temple GS Single Giant Pot", ("GS Token", 0x07, 0x01, None, 'Gold Skulltula Token', ("Shadow Temple", "Vanilla", "Skulltulas",))), + ("Shadow Temple GS Near Ship", ("GS Token", 0x07, 0x10, None, 'Gold Skulltula Token', ("Shadow Temple", "Vanilla", "Skulltulas",))), + ("Shadow Temple GS Triple Giant Pot", ("GS Token", 0x07, 0x04, None, 'Gold Skulltula Token', ("Shadow Temple", "Vanilla", "Skulltulas",))), + # Shadow Temple MQ + ("Shadow Temple MQ Early Gibdos Chest", ("Chest", 0x07, 0x03, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Map Chest", ("Chest", 0x07, 0x02, None, 'Map (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Near Ship Invisible Chest", ("Chest", 0x07, 0x0E, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Compass Chest", ("Chest", 0x07, 0x01, None, 'Compass (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Hover Boots Chest", ("Chest", 0x07, 0x07, None, 'Hover Boots', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Invisible Blades Invisible Chest", ("Chest", 0x07, 0x16, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Invisible Blades Visible Chest", ("Chest", 0x07, 0x0C, None, 'Rupees (5)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Beamos Silver Rupees Chest", ("Chest", 0x07, 0x0F, None, 'Arrows (5)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Falling Spikes Lower Chest", ("Chest", 0x07, 0x05, None, 'Arrows (10)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Falling Spikes Upper Chest", ("Chest", 0x07, 0x06, None, 'Rupees (5)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Falling Spikes Switch Chest", ("Chest", 0x07, 0x04, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Invisible Spikes Chest", ("Chest", 0x07, 0x09, None, 'Rupees (5)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Stalfos Room Chest", ("Chest", 0x07, 0x10, None, 'Rupees (20)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Wind Hint Chest", ("Chest", 0x07, 0x15, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ After Wind Hidden Chest", ("Chest", 0x07, 0x14, None, 'Arrows (5)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ After Wind Enemy Chest", ("Chest", 0x07, 0x08, None, 'Rupees (5)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Boss Key Chest", ("Chest", 0x07, 0x0B, None, 'Boss Key (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Spike Walls Left Chest", ("Chest", 0x07, 0x0A, None, 'Rupees (5)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Freestanding Key", ("Collectable", 0x07, 0x06, None, 'Small Key (Shadow Temple)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ Bomb Flower Chest", ("Chest", 0x07, 0x0D, None, 'Arrows (10)', ("Shadow Temple", "Master Quest",))), + ("Shadow Temple MQ GS Falling Spikes Room", ("GS Token", 0x07, 0x02, None, 'Gold Skulltula Token', ("Shadow Temple", "Master Quest", "Skulltulas",))), + ("Shadow Temple MQ GS Wind Hint Room", ("GS Token", 0x07, 0x01, None, 'Gold Skulltula Token', ("Shadow Temple", "Master Quest", "Skulltulas",))), + ("Shadow Temple MQ GS After Wind", ("GS Token", 0x07, 0x08, None, 'Gold Skulltula Token', ("Shadow Temple", "Master Quest", "Skulltulas",))), + ("Shadow Temple MQ GS After Ship", ("GS Token", 0x07, 0x10, None, 'Gold Skulltula Token', ("Shadow Temple", "Master Quest", "Skulltulas",))), + ("Shadow Temple MQ GS Near Boss", ("GS Token", 0x07, 0x04, None, 'Gold Skulltula Token', ("Shadow Temple", "Master Quest", "Skulltulas",))), + # Shadow Temple shared + ("Shadow Temple Bongo Bongo Heart", ("BossHeart", 0x18, 0x4F, None, 'Heart Container', ("Shadow Temple", "Vanilla", "Master Quest",))), + + # Spirit Temple shared + # Vanilla and MQ locations are mixed to ensure the positions of Silver Gauntlets/Mirror Shield chests are correct for both versions + ("Spirit Temple Child Bridge Chest", ("Chest", 0x06, 0x08, None, 'Deku Shield', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Child Early Torches Chest", ("Chest", 0x06, 0x00, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Child Climb North Chest", ("Chest", 0x06, 0x06, None, 'Bombchus (10)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Child Climb East Chest", ("Chest", 0x06, 0x0C, None, 'Deku Shield', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Map Chest", ("Chest", 0x06, 0x03, None, 'Map (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Sun Block Room Chest", ("Chest", 0x06, 0x01, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple MQ Entrance Front Left Chest", ("Chest", 0x06, 0x1A, None, 'Bombchus (10)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Entrance Back Right Chest", ("Chest", 0x06, 0x1F, None, 'Bombchus (10)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Entrance Front Right Chest", ("Chest", 0x06, 0x1B, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Entrance Back Left Chest", ("Chest", 0x06, 0x1E, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Map Chest", ("Chest", 0x06, 0x00, None, 'Map (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Map Room Enemy Chest", ("Chest", 0x06, 0x08, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Child Climb North Chest", ("Chest", 0x06, 0x06, None, 'Bombchus (10)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Child Climb South Chest", ("Chest", 0x06, 0x0C, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Compass Chest", ("Chest", 0x06, 0x03, None, 'Compass (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Silver Block Hallway Chest", ("Chest", 0x06, 0x1C, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Sun Block Room Chest", ("Chest", 0x06, 0x01, None, 'Recovery Heart', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple Silver Gauntlets Chest", ("Chest", 0x5C, 0x0B, None, 'Progressive Strength Upgrade', ("Spirit Temple", "Vanilla", "Master Quest", "Desert Colossus"))), + + ("Spirit Temple Compass Chest", ("Chest", 0x06, 0x04, None, 'Compass (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Early Adult Right Chest", ("Chest", 0x06, 0x07, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple First Mirror Left Chest", ("Chest", 0x06, 0x0D, None, 'Ice Trap', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple First Mirror Right Chest", ("Chest", 0x06, 0x0E, None, 'Recovery Heart', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Statue Room Northeast Chest", ("Chest", 0x06, 0x0F, None, 'Rupees (5)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Statue Room Hand Chest", ("Chest", 0x06, 0x02, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Near Four Armos Chest", ("Chest", 0x06, 0x05, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Hallway Right Invisible Chest", ("Chest", 0x06, 0x14, None, 'Recovery Heart', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Hallway Left Invisible Chest", ("Chest", 0x06, 0x15, None, 'Recovery Heart', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple MQ Child Hammer Switch Chest", ("Chest", 0x06, 0x1D, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Statue Room Lullaby Chest", ("Chest", 0x06, 0x0F, None, 'Rupees (5)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Statue Room Invisible Chest", ("Chest", 0x06, 0x02, None, 'Recovery Heart', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Leever Room Chest", ("Chest", 0x06, 0x04, None, 'Rupees (50)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Symphony Room Chest", ("Chest", 0x06, 0x07, None, 'Rupees (50)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Beamos Room Chest", ("Chest", 0x06, 0x19, None, 'Recovery Heart', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Chest Switch Chest", ("Chest", 0x06, 0x18, None, 'Ice Trap', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple MQ Boss Key Chest", ("Chest", 0x06, 0x05, None, 'Boss Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + ("Spirit Temple Mirror Shield Chest", ("Chest", 0x5C, 0x09, None, 'Mirror Shield', ("Spirit Temple", "Vanilla", "Master Quest", "Desert Colossus"))), + + ("Spirit Temple Boss Key Chest", ("Chest", 0x06, 0x0A, None, 'Boss Key (Spirit Temple)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple Topmost Chest", ("Chest", 0x06, 0x12, None, 'Bombs (20)', ("Spirit Temple", "Vanilla",))), + ("Spirit Temple MQ Mirror Puzzle Invisible Chest", ("Chest", 0x06, 0x12, None, 'Small Key (Spirit Temple)', ("Spirit Temple", "Master Quest",))), + + ("Spirit Temple GS Metal Fence", ("GS Token", 0x06, 0x10, None, 'Gold Skulltula Token', ("Spirit Temple", "Vanilla", "Skulltulas",))), + ("Spirit Temple GS Sun on Floor Room", ("GS Token", 0x06, 0x08, None, 'Gold Skulltula Token', ("Spirit Temple", "Vanilla", "Skulltulas",))), + ("Spirit Temple GS Hall After Sun Block Room", ("GS Token", 0x06, 0x01, None, 'Gold Skulltula Token', ("Spirit Temple", "Vanilla", "Skulltulas",))), + ("Spirit Temple GS Lobby", ("GS Token", 0x06, 0x04, None, 'Gold Skulltula Token', ("Spirit Temple", "Vanilla", "Skulltulas",))), + ("Spirit Temple GS Boulder Room", ("GS Token", 0x06, 0x02, None, 'Gold Skulltula Token', ("Spirit Temple", "Vanilla", "Skulltulas",))), + ("Spirit Temple MQ GS Sun Block Room", ("GS Token", 0x06, 0x01, None, 'Gold Skulltula Token', ("Spirit Temple", "Master Quest", "Skulltulas",))), + ("Spirit Temple MQ GS Leever Room", ("GS Token", 0x06, 0x02, None, 'Gold Skulltula Token', ("Spirit Temple", "Master Quest", "Skulltulas",))), + ("Spirit Temple MQ GS Symphony Room", ("GS Token", 0x06, 0x08, None, 'Gold Skulltula Token', ("Spirit Temple", "Master Quest", "Skulltulas",))), + ("Spirit Temple MQ GS Nine Thrones Room West", ("GS Token", 0x06, 0x04, None, 'Gold Skulltula Token', ("Spirit Temple", "Master Quest", "Skulltulas",))), + ("Spirit Temple MQ GS Nine Thrones Room North", ("GS Token", 0x06, 0x10, None, 'Gold Skulltula Token', ("Spirit Temple", "Master Quest", "Skulltulas",))), + + ("Spirit Temple Twinrova Heart", ("BossHeart", 0x17, 0x4F, None, 'Heart Container', ("Spirit Temple", "Vanilla", "Master Quest",))), + + # Ice Cavern vanilla + ("Ice Cavern Map Chest", ("Chest", 0x09, 0x00, None, 'Map (Ice Cavern)', ("Ice Cavern", "Vanilla",))), + ("Ice Cavern Compass Chest", ("Chest", 0x09, 0x01, None, 'Compass (Ice Cavern)', ("Ice Cavern", "Vanilla",))), + ("Ice Cavern Freestanding PoH", ("Collectable", 0x09, 0x01, None, 'Piece of Heart', ("Ice Cavern", "Vanilla",))), + ("Ice Cavern Iron Boots Chest", ("Chest", 0x09, 0x02, None, 'Iron Boots', ("Ice Cavern", "Vanilla",))), + ("Ice Cavern GS Spinning Scythe Room", ("GS Token", 0x09, 0x02, None, 'Gold Skulltula Token', ("Ice Cavern", "Vanilla", "Skulltulas",))), + ("Ice Cavern GS Heart Piece Room", ("GS Token", 0x09, 0x04, None, 'Gold Skulltula Token', ("Ice Cavern", "Vanilla", "Skulltulas",))), + ("Ice Cavern GS Push Block Room", ("GS Token", 0x09, 0x01, None, 'Gold Skulltula Token', ("Ice Cavern", "Vanilla", "Skulltulas",))), + # Ice Cavern MQ + ("Ice Cavern MQ Map Chest", ("Chest", 0x09, 0x01, None, 'Map (Ice Cavern)', ("Ice Cavern", "Master Quest",))), + ("Ice Cavern MQ Compass Chest", ("Chest", 0x09, 0x00, None, 'Compass (Ice Cavern)', ("Ice Cavern", "Master Quest",))), + ("Ice Cavern MQ Freestanding PoH", ("Collectable", 0x09, 0x01, None, 'Piece of Heart', ("Ice Cavern", "Master Quest",))), + ("Ice Cavern MQ Iron Boots Chest", ("Chest", 0x09, 0x02, None, 'Iron Boots', ("Ice Cavern", "Master Quest",))), + ("Ice Cavern MQ GS Red Ice", ("GS Token", 0x09, 0x02, None, 'Gold Skulltula Token', ("Ice Cavern", "Master Quest", "Skulltulas",))), + ("Ice Cavern MQ GS Ice Block", ("GS Token", 0x09, 0x04, None, 'Gold Skulltula Token', ("Ice Cavern", "Master Quest", "Skulltulas",))), + ("Ice Cavern MQ GS Scarecrow", ("GS Token", 0x09, 0x01, None, 'Gold Skulltula Token', ("Ice Cavern", "Master Quest", "Skulltulas",))), + + # Gerudo Training Grounds vanilla + ("Gerudo Training Grounds Lobby Left Chest", ("Chest", 0x0B, 0x13, None, 'Rupees (5)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Lobby Right Chest", ("Chest", 0x0B, 0x07, None, 'Arrows (10)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Stalfos Chest", ("Chest", 0x0B, 0x00, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Before Heavy Block Chest", ("Chest", 0x0B, 0x11, None, 'Arrows (30)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Heavy Block First Chest", ("Chest", 0x0B, 0x0F, None, 'Rupees (200)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Heavy Block Second Chest", ("Chest", 0x0B, 0x0E, None, 'Rupees (5)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Heavy Block Third Chest", ("Chest", 0x0B, 0x14, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Heavy Block Fourth Chest", ("Chest", 0x0B, 0x02, None, 'Ice Trap', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Eye Statue Chest", ("Chest", 0x0B, 0x03, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Near Scarecrow Chest", ("Chest", 0x0B, 0x04, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Hammer Room Clear Chest", ("Chest", 0x0B, 0x12, None, 'Arrows (10)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Hammer Room Switch Chest", ("Chest", 0x0B, 0x10, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Freestanding Key", ("Collectable", 0x0B, 0x01, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Maze Right Central Chest", ("Chest", 0x0B, 0x05, None, 'Bombchus (5)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Maze Right Side Chest", ("Chest", 0x0B, 0x08, None, 'Arrows (30)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Underwater Silver Rupee Chest", ("Chest", 0x0B, 0x0D, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Beamos Chest", ("Chest", 0x0B, 0x01, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Hidden Ceiling Chest", ("Chest", 0x0B, 0x0B, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Maze Path First Chest", ("Chest", 0x0B, 0x06, None, 'Rupees (50)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Maze Path Second Chest", ("Chest", 0x0B, 0x0A, None, 'Rupees (20)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Maze Path Third Chest", ("Chest", 0x0B, 0x09, None, 'Arrows (30)', ("Gerudo Training Grounds", "Vanilla",))), + ("Gerudo Training Grounds Maze Path Final Chest", ("Chest", 0x0B, 0x0C, None, 'Ice Arrows', ("Gerudo Training Grounds", "Vanilla",))), + # Gerudo Training Grounds MQ + ("Gerudo Training Grounds MQ Lobby Left Chest", ("Chest", 0x0B, 0x13, None, 'Arrows (10)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Lobby Right Chest", ("Chest", 0x0B, 0x07, None, 'Bombchus (5)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ First Iron Knuckle Chest", ("Chest", 0x0B, 0x00, None, 'Rupees (5)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Before Heavy Block Chest", ("Chest", 0x0B, 0x11, None, 'Arrows (10)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Heavy Block Chest", ("Chest", 0x0B, 0x02, None, 'Rupees (50)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Eye Statue Chest", ("Chest", 0x0B, 0x03, None, 'Bombchus (10)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Ice Arrows Chest", ("Chest", 0x0B, 0x04, None, 'Ice Arrows', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Second Iron Knuckle Chest", ("Chest", 0x0B, 0x12, None, 'Arrows (10)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Flame Circle Chest", ("Chest", 0x0B, 0x0E, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Maze Right Central Chest", ("Chest", 0x0B, 0x05, None, 'Rupees (5)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Maze Right Side Chest", ("Chest", 0x0B, 0x08, None, 'Rupee (Treasure Chest Game)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Underwater Silver Rupee Chest", ("Chest", 0x0B, 0x0D, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Dinolfos Chest", ("Chest", 0x0B, 0x01, None, 'Small Key (Gerudo Training Grounds)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Hidden Ceiling Chest", ("Chest", 0x0B, 0x0B, None, 'Rupees (50)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Maze Path First Chest", ("Chest", 0x0B, 0x06, None, 'Rupee (1)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Maze Path Third Chest", ("Chest", 0x0B, 0x09, None, 'Rupee (Treasure Chest Game)', ("Gerudo Training Grounds", "Master Quest",))), + ("Gerudo Training Grounds MQ Maze Path Second Chest", ("Chest", 0x0B, 0x0A, None, 'Rupees (20)', ("Gerudo Training Grounds", "Master Quest",))), + + # Ganon's Castle vanilla + ("Ganons Castle Forest Trial Chest", ("Chest", 0x0D, 0x09, None, 'Rupees (5)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Water Trial Left Chest", ("Chest", 0x0D, 0x07, None, 'Ice Trap', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Water Trial Right Chest", ("Chest", 0x0D, 0x06, None, 'Recovery Heart', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Shadow Trial Front Chest", ("Chest", 0x0D, 0x08, None, 'Rupees (5)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Shadow Trial Golden Gauntlets Chest", ("Chest", 0x0D, 0x05, None, 'Progressive Strength Upgrade', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial First Left Chest", ("Chest", 0x0D, 0x0C, None, 'Rupees (5)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial Second Left Chest", ("Chest", 0x0D, 0x0B, None, 'Ice Trap', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial Third Left Chest", ("Chest", 0x0D, 0x0D, None, 'Recovery Heart', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial First Right Chest", ("Chest", 0x0D, 0x0E, None, 'Ice Trap', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial Second Right Chest", ("Chest", 0x0D, 0x0A, None, 'Arrows (30)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial Third Right Chest", ("Chest", 0x0D, 0x0F, None, 'Ice Trap', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial Invisible Enemies Chest", ("Chest", 0x0D, 0x10, None, 'Small Key (Ganons Castle)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Light Trial Lullaby Chest", ("Chest", 0x0D, 0x11, None, 'Small Key (Ganons Castle)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Spirit Trial Crystal Switch Chest", ("Chest", 0x0D, 0x12, None, 'Bombchus (20)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Spirit Trial Invisible Chest", ("Chest", 0x0D, 0x14, None, 'Arrows (10)', ("Ganon's Castle", "Vanilla",))), + ("Ganons Castle Deku Scrub Left", ("NPC", 0x0D, 0x3A, None, 'Buy Green Potion', ("Ganon's Castle", "Vanilla", "Deku Scrub",))), + ("Ganons Castle Deku Scrub Center-Left", ("NPC", 0x0D, 0x37, None, 'Buy Bombs (5) [35]', ("Ganon's Castle", "Vanilla", "Deku Scrub",))), + ("Ganons Castle Deku Scrub Center-Right", ("NPC", 0x0D, 0x33, None, 'Buy Arrows (30)', ("Ganon's Castle", "Vanilla", "Deku Scrub",))), + ("Ganons Castle Deku Scrub Right", ("NPC", 0x0D, 0x39, None, 'Buy Red Potion [30]', ("Ganon's Castle", "Vanilla", "Deku Scrub",))), + # Ganon's Castle MQ + ("Ganons Castle MQ Forest Trial Freestanding Key", ("Collectable", 0x0D, 0x01, None, 'Small Key (Ganons Castle)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Forest Trial Eye Switch Chest", ("Chest", 0x0D, 0x02, None, 'Arrows (10)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Forest Trial Frozen Eye Switch Chest", ("Chest", 0x0D, 0x03, None, 'Bombs (5)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Water Trial Chest", ("Chest", 0x0D, 0x01, None, 'Rupees (20)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Shadow Trial Bomb Flower Chest", ("Chest", 0x0D, 0x00, None, 'Arrows (10)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Shadow Trial Eye Switch Chest", ("Chest", 0x0D, 0x05, None, 'Small Key (Ganons Castle)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Light Trial Lullaby Chest", ("Chest", 0x0D, 0x04, None, 'Recovery Heart', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Spirit Trial First Chest", ("Chest", 0x0D, 0x0A, None, 'Bombchus (10)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Spirit Trial Invisible Chest", ("Chest", 0x0D, 0x14, None, 'Arrows (10)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Spirit Trial Sun Front Left Chest", ("Chest", 0x0D, 0x09, None, 'Recovery Heart', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Spirit Trial Sun Back Left Chest", ("Chest", 0x0D, 0x08, None, 'Small Key (Ganons Castle)', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Spirit Trial Sun Back Right Chest", ("Chest", 0x0D, 0x07, None, 'Recovery Heart', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Spirit Trial Golden Gauntlets Chest", ("Chest", 0x0D, 0x06, None, 'Progressive Strength Upgrade', ("Ganon's Castle", "Master Quest",))), + ("Ganons Castle MQ Deku Scrub Left", ("NPC", 0x0D, 0x3A, None, 'Buy Green Potion', ("Ganon's Castle", "Master Quest", "Deku Scrub",))), + ("Ganons Castle MQ Deku Scrub Center-Left", ("NPC", 0x0D, 0x37, None, 'Buy Bombs (5) [35]', ("Ganon's Castle", "Master Quest", "Deku Scrub",))), + ("Ganons Castle MQ Deku Scrub Center", ("NPC", 0x0D, 0x33, None, 'Buy Arrows (30)', ("Ganon's Castle", "Master Quest", "Deku Scrub",))), + ("Ganons Castle MQ Deku Scrub Center-Right", ("NPC", 0x0D, 0x39, None, 'Buy Red Potion [30]', ("Ganon's Castle", "Master Quest", "Deku Scrub",))), + ("Ganons Castle MQ Deku Scrub Right", ("NPC", 0x0D, 0x30, None, 'Buy Deku Nut (5)', ("Ganon's Castle", "Master Quest", "Deku Scrub",))), + # Ganon's Castle shared + ("Ganons Tower Boss Key Chest", ("Chest", 0x0A, 0x0B, None, 'Boss Key (Ganons Castle)', ("Ganon's Castle", "Vanilla", "Master Quest",))), + + ## Events and Drops + ("Pierre", ("Event", None, None, None, 'Scarecrow Song', None)), + ("Deliver Rutos Letter", ("Event", None, None, None, 'Deliver Letter', None)), + ("Master Sword Pedestal", ("Event", None, None, None, 'Time Travel', None)), + + ("Deku Baba Sticks", ("Drop", None, None, None, 'Deku Stick Drop', None)), + ("Deku Baba Nuts", ("Drop", None, None, None, 'Deku Nut Drop', None)), + ("Stick Pot", ("Drop", None, None, None, 'Deku Stick Drop', None)), + ("Nut Pot", ("Drop", None, None, None, 'Deku Nut Drop', None)), + ("Nut Crate", ("Drop", None, None, None, 'Deku Nut Drop', None)), + ("Blue Fire", ("Drop", None, None, None, 'Blue Fire', None)), + ("Lone Fish", ("Drop", None, None, None, 'Fish', None)), + ("Fish Group", ("Drop", None, None, None, 'Fish', None)), + ("Bug Rock", ("Drop", None, None, None, 'Bugs', None)), + ("Bug Shrub", ("Drop", None, None, None, 'Bugs', None)), + ("Wandering Bugs", ("Drop", None, None, None, 'Bugs', None)), + ("Fairy Pot", ("Drop", None, None, None, 'Fairy', None)), + ("Free Fairies", ("Drop", None, None, None, 'Fairy', None)), + ("Wall Fairy", ("Drop", None, None, None, 'Fairy', None)), + ("Butterfly Fairy", ("Drop", None, None, None, 'Fairy', None)), + ("Gossip Stone Fairy", ("Drop", None, None, None, 'Fairy', None)), + ("Bean Plant Fairy", ("Drop", None, None, None, 'Fairy', None)), + ("Fairy Pond", ("Drop", None, None, None, 'Fairy', None)), + ("Big Poe Kill", ("Drop", None, None, None, 'Big Poe', None)), + + ## Hints + # These are not actual locations, but are filler spots used for hint reachability. + # Hint location types must start with 'Hint'. + ("DMC Gossip Stone", ("HintStone", None, None, None, None, None)), + ("DMT Gossip Stone", ("HintStone", None, None, None, None, None)), + ("Colossus Gossip Stone", ("HintStone", None, None, None, None, None)), + ("Dodongos Cavern Gossip Stone", ("HintStone", None, None, None, None, None)), + ("GV Gossip Stone", ("HintStone", None, None, None, None, None)), + ("GC Maze Gossip Stone", ("HintStone", None, None, None, None, None)), + ("GC Medigoron Gossip Stone", ("HintStone", None, None, None, None, None)), + ("Graveyard Gossip Stone", ("HintStone", None, None, None, None, None)), + ("HC Malon Gossip Stone", ("HintStone", None, None, None, None, None)), + ("HC Rock Wall Gossip Stone", ("HintStone", None, None, None, None, None)), + ("HC Storms Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("HF Cow Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("KF Deku Tree Gossip Stone (Left)", ("HintStone", None, None, None, None, None)), + ("KF Deku Tree Gossip Stone (Right)", ("HintStone", None, None, None, None, None)), + ("KF Gossip Stone", ("HintStone", None, None, None, None, None)), + ("LH Lab Gossip Stone", ("HintStone", None, None, None, None, None)), + ("LH Gossip Stone (Southeast)", ("HintStone", None, None, None, None, None)), + ("LH Gossip Stone (Southwest)", ("HintStone", None, None, None, None, None)), + ("LW Gossip Stone", ("HintStone", None, None, None, None, None)), + ("SFM Maze Gossip Stone (Lower)", ("HintStone", None, None, None, None, None)), + ("SFM Maze Gossip Stone (Upper)", ("HintStone", None, None, None, None, None)), + ("SFM Saria Gossip Stone", ("HintStone", None, None, None, None, None)), + ("ToT Gossip Stone (Left)", ("HintStone", None, None, None, None, None)), + ("ToT Gossip Stone (Left-Center)", ("HintStone", None, None, None, None, None)), + ("ToT Gossip Stone (Right)", ("HintStone", None, None, None, None, None)), + ("ToT Gossip Stone (Right-Center)", ("HintStone", None, None, None, None, None)), + ("ZD Gossip Stone", ("HintStone", None, None, None, None, None)), + ("ZF Fairy Gossip Stone", ("HintStone", None, None, None, None, None)), + ("ZF Jabu Gossip Stone", ("HintStone", None, None, None, None, None)), + ("ZR Near Grottos Gossip Stone", ("HintStone", None, None, None, None, None)), + ("ZR Near Domain Gossip Stone", ("HintStone", None, None, None, None, None)), + + ("HF Near Market Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("HF Southeast Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("HF Open Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("Kak Open Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("ZR Open Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("KF Storms Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("LW Near Shortcuts Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("DMT Storms Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + ("DMC Upper Grotto Gossip Stone", ("HintStone", None, None, None, None, None)), + + ("Ganondorf Hint", ("Hint", None, None, None, None, None)), +]) + +location_sort_order = { + loc: i for i, loc in enumerate(location_table.keys()) +} + +# Business Scrub Details +business_scrubs = [ + # id price text text replacement + (0x30, 20, 0x10A0, ["Deku Nuts", "a \x05\x42mysterious item\x05\x40"]), + (0x31, 15, 0x10A1, ["Deku Sticks", "a \x05\x42mysterious item\x05\x40"]), + (0x3E, 10, 0x10A2, ["Piece of Heart", "\x05\x42mysterious item\x05\x40"]), + (0x33, 40, 0x10CA, ["\x05\x41Deku Seeds", "a \x05\x42mysterious item"]), + (0x34, 50, 0x10CB, ["\x41Deku Shield", "\x42mysterious item"]), + (0x37, 40, 0x10CC, ["\x05\x41Bombs", "a \x05\x42mysterious item"]), + (0x38, 00, 0x10CD, ["\x05\x41Arrows", "a \x05\x42mysterious item"]), # unused + (0x39, 40, 0x10CE, ["\x05\x41Red Potion", "\x05\x42mysterious item"]), + (0x3A, 40, 0x10CF, ["Green Potion", "mysterious item"]), + (0x77, 40, 0x10DC, ["enable you to pick up more\x01\x05\x41Deku Sticks", "sell you a \x05\x42mysterious item"]), + (0x79, 40, 0x10DD, ["enable you to pick up more \x05\x41Deku\x01Nuts", "sell you a \x05\x42mysterious item"]), +] + +dungeons = ('Deku Tree', 'Dodongo\'s Cavern', 'Jabu Jabu\'s Belly', 'Forest Temple', 'Fire Temple', 'Water Temple', 'Spirit Temple', 'Shadow Temple', 'Ice Cavern', 'Bottom of the Well', 'Gerudo Training Grounds', 'Ganon\'s Castle') +location_groups = { + 'Song': [name for (name, data) in location_table.items() if data[0] == 'Song'], + 'Chest': [name for (name, data) in location_table.items() if data[0] == 'Chest'], + 'Collectable': [name for (name, data) in location_table.items() if data[0] == 'Collectable'], + 'BossHeart': [name for (name, data) in location_table.items() if data[0] == 'BossHeart'], + 'CollectableLike': [name for (name, data) in location_table.items() if data[0] in ('Collectable', 'BossHeart', 'GS Token')], + 'CanSee': [name for (name, data) in location_table.items() + if data[0] in ('Collectable', 'BossHeart', 'GS Token', 'Shop') + # Treasure Box Shop, Bombchu Bowling, Hyrule Field (OoT), Lake Hylia (RL/FA) + or data[0:2] in [('Chest', 0x10), ('NPC', 0x4B), ('NPC', 0x51), ('NPC', 0x57)]], + 'Dungeon': [name for (name, data) in location_table.items() if data[5] is not None and any(dungeon in data[5] for dungeon in dungeons)], +} + + +def location_is_viewable(loc_name, correct_chest_sizes): + return correct_chest_sizes and loc_name in location_groups['Chest'] or loc_name in location_groups['CanSee'] + + +# Function to run exactly once after after placing items in drop locations for each world +# Sets all Drop locations to a unique name in order to avoid name issues and to identify locations in the spoiler +# Also cause them to not be shown in the list of locations, only in playthrough +def set_drop_location_names(ootworld): + for region in ootworld.regions: + for location in region.locations: + if location.type == 'Drop': + location.name = location.parent_region.name + " " + location.name + location.show_in_spoiler = False diff --git a/worlds/oot/LogicTricks.py b/worlds/oot/LogicTricks.py new file mode 100644 index 00000000..90abc13a --- /dev/null +++ b/worlds/oot/LogicTricks.py @@ -0,0 +1,1359 @@ +known_logic_tricks = { + 'Fewer Tunic Requirements': { + 'name' : 'logic_fewer_tunic_requirements', + 'tags' : ("General", "Fire Temple", "Water Temple", "Gerudo Training Grounds", "Zora's Fountain",), + 'tooltip' : '''\ + Allows the following possible without Tunics: + - Enter Water Temple. The key below the center + pillar still requires Zora Tunic. + - Enter Fire Temple. Only the first floor is + accessible, and not Volvagia. + - Zora's Fountain Bottom Freestanding PoH. + Might not have enough health to resurface. + - Gerudo Training Grounds Underwater + Silver Rupee Chest. May need to make multiple + trips. + '''}, + 'Hidden Grottos without Stone of Agony': { + 'name' : 'logic_grottos_without_agony', + 'tags' : ("General", "Entrance",), + 'tooltip' : '''\ + Allows entering hidden grottos without the + Stone of Agony. + '''}, + 'Pass Through Visible One-Way Collisions': { + 'name' : 'logic_visible_collisions', + 'tags' : ("Entrance", "Kakariko Village",), + 'tooltip' : '''\ + Allows climbing through the platform to reach + Impa's House Back as adult with no items and + going through the Kakariko Village Gate as child + when coming from the Mountain Trail side. + '''}, + 'Child Deadhand without Kokiri Sword': { + 'name' : 'logic_child_deadhand', + 'tags' : ("Bottom of the Well",), + 'tooltip' : '''\ + Requires 9 sticks or 5 jump slashes. + '''}, + 'Second Dampe Race as Child': { + 'name' : 'logic_child_dampe_race_poh', + 'tags' : ("the Graveyard", "Entrance",), + 'tooltip' : '''\ + It is possible to complete the second dampe + race as child in under a minute, but it is + a strict time limit. + '''}, + 'Man on Roof without Hookshot': { + 'name' : 'logic_man_on_roof', + 'tags' : ("Kakariko Village",), + 'tooltip' : '''\ + Can be reached by side-hopping off + the watchtower. + '''}, + 'Dodongo\'s Cavern Staircase with Bow': { + 'name' : 'logic_dc_staircase', + 'tags' : ("Dodongo's Cavern",), + 'tooltip' : '''\ + The Bow can be used to knock down the stairs + with two well-timed shots. + '''}, + 'Dodongo\'s Cavern Spike Trap Room Jump without Hover Boots': { + 'name' : 'logic_dc_jump', + 'tags' : ("Dodongo's Cavern",), + 'tooltip' : '''\ + Jump is adult only. + '''}, + 'Dodongo\'s Cavern Vines GS from Below with Longshot': { + 'name' : 'logic_dc_vines_gs', + 'tags' : ("Dodongo's Cavern", "Skulltulas",), + 'tooltip' : '''\ + The vines upon which this Skulltula rests are one- + sided collision. You can use the Longshot to get it + from below, by shooting it through the vines, + bypassing the need to lower the staircase. + '''}, + 'Gerudo Fortress "Kitchen" with No Additional Items': { + 'name' : 'logic_gerudo_kitchen', + 'tags' : ("Gerudo's Fortress",), + 'tooltip' : '''\ + The logic normally guarantees one of Bow, Hookshot, + or Hover Boots. + '''}, + 'Deku Tree Basement Vines GS with Jump Slash': { + 'name' : 'logic_deku_basement_gs', + 'tags' : ("Deku Tree", "Skulltulas",), + 'tooltip' : '''\ + Can be defeated by doing a precise jump slash. + '''}, + 'Deku Tree Basement Web to Gohma with Bow': { + 'name' : 'logic_deku_b1_webs_with_bow', + 'tags' : ("Deku Tree", "Entrance",), + 'tooltip' : '''\ + All spider web walls in the Deku Tree basement can be burnt + as adult with just a bow by shooting through torches. This + trick only applies to the circular web leading to Gohma; + the two vertical webs are always in logic. + + Backflip onto the chest near the torch at the bottom of + the vine wall. With precise positioning you can shoot + through the torch to the right edge of the circular web. + + This allows completion of adult Deku Tree with no fire source. + '''}, + 'Deku Tree MQ Roll Under the Spiked Log': { + 'name' : 'logic_deku_mq_log', + 'tags' : ("Deku Tree",), + 'tooltip' : '''\ + You can get past the spiked log by rolling + to briefly shrink your hitbox. As adult, + the timing is a bit more precise. + '''}, + 'Hammer Rusted Switches Through Walls': { + 'name' : 'logic_rusted_switches', + 'tags' : ("Fire Temple", "Ganon's Castle",), + 'tooltip' : '''\ + Applies to: + - Fire Temple Highest Goron Chest. + - MQ Fire Temple Lizalfos Maze. + - MQ Spirit Trial. + '''}, + 'Bottom of the Well Map Chest with Strength & Sticks': { + 'name' : 'logic_botw_basement', + 'tags' : ("Bottom of the Well",), + 'tooltip' : '''\ + The chest in the basement can be reached with + strength by doing a jump slash with a lit + stick to access the bomb flowers. + '''}, + 'Bottom of the Well MQ Jump Over the Pits': { + 'name' : 'logic_botw_mq_pits', + 'tags' : ("Bottom of the Well",), + 'tooltip' : '''\ + While the pits in Bottom of the Well don't allow you to + jump just by running straight at them, you can still get + over them by side-hopping or backflipping across. With + explosives, this allows you to access the central areas + without Zelda's Lullaby. With Zelda's Lullaby, it allows + you to access the west inner room without explosives. + '''}, + 'Skip Forest Temple MQ Block Puzzle with Bombchu': { + 'name' : 'logic_forest_mq_block_puzzle', + 'tags' : ("Forest Temple",), + 'tooltip' : '''\ + Send the Bombchu straight up the center of the + wall directly to the left upon entering the room. + '''}, + 'Spirit Temple Child Side Bridge with Bombchu': { + 'name' : 'logic_spirit_child_bombchu', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + A carefully-timed Bombchu can hit the switch. + '''}, + 'Windmill PoH as Adult with Nothing': { + 'name' : 'logic_windmill_poh', + 'tags' : ("Kakariko Village",), + 'tooltip' : '''\ + Can jump up to the spinning platform from + below as adult. + '''}, + 'Crater\'s Bean PoH with Hover Boots': { + 'name' : 'logic_crater_bean_poh_with_hovers', + 'tags' : ("Death Mountain Crater",), + 'tooltip' : '''\ + Hover from the base of the bridge + near Goron City and walk up the + very steep slope. + '''}, + 'Zora\'s Domain Entry with Cucco': { + 'name' : 'logic_zora_with_cucco', + 'tags' : ("Zora's River",), + 'tooltip' : '''\ + Can fly behind the waterfall with + a cucco as child. + '''}, + 'Water Temple MQ Central Pillar with Fire Arrows': { + 'name' : 'logic_water_mq_central_pillar', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + Slanted torches have misleading hitboxes. Whenever + you see a slanted torch jutting out of the wall, + you can expect most or all of its hitbox is actually + on the other side that wall. This can make slanted + torches very finicky to light when using arrows. The + torches in the central pillar of MQ Water Temple are + a particularly egregious example. Logic normally + expects Din's Fire and Song of Time. + '''}, + 'Gerudo Training Grounds MQ Left Side Silver Rupees with Hookshot': { + 'name' : 'logic_gtg_mq_with_hookshot', + 'tags' : ("Gerudo Training Grounds",), + 'tooltip' : '''\ + The highest silver rupee can be obtained by + hookshotting the target and then immediately jump + slashing toward the rupee. + '''}, + 'Forest Temple East Courtyard Vines with Hookshot': { + 'name' : 'logic_forest_vines', + 'tags' : ("Forest Temple",), + 'tooltip' : '''\ + The vines in Forest Temple leading to where the well + drain switch is in the standard form can be barely + reached with just the Hookshot. + '''}, + 'Forest Temple East Courtyard GS with Boomerang': { + 'name' : 'logic_forest_outdoor_east_gs', + 'tags' : ("Forest Temple", "Entrance", "Skulltulas",), + 'tooltip' : '''\ + Precise Boomerang throws can allow child to + kill the Skulltula and collect the token. + '''}, + 'Forest Temple First Room GS with Difficult-to-Use Weapons': { + 'name' : 'logic_forest_first_gs', + 'tags' : ("Forest Temple", "Entrance", "Skulltulas",), + 'tooltip' : '''\ + Allows killing this Skulltula with Sword or Sticks by + jump slashing it as you let go from the vines. You will + take fall damage. + Also allows killing it as Child with a Bomb throw. It's + much more difficult to use a Bomb as child due to + Child Link's shorter height. + '''}, + 'Swim Through Forest Temple MQ Well with Hookshot': { + 'name' : 'logic_forest_well_swim', + 'tags' : ("Forest Temple",), + 'tooltip' : '''\ + Shoot the vines in the well as low and as far to + the right as possible, and then immediately swim + under the ceiling to the right. This can only be + required if Forest Temple is in its Master Quest + form. + '''}, + 'Forest Temple MQ Twisted Hallway Switch with Jump Slash': { + 'name' : 'logic_forest_mq_hallway_switch_jumpslash', + 'tags' : ("Forest Temple",), + 'tooltip' : '''\ + The switch to twist the hallway can be hit with + a jump slash through the glass block. To get in + front of the switch, either use the Hover Boots + or hit the shortcut switch at the top of the + room and jump from the glass blocks that spawn. + '''}, + 'Forest Temple MQ Twisted Hallway Switch with Hookshot': { + 'name' : 'logic_forest_mq_hallway_switch_hookshot', + 'tags' : ("Forest Temple",), + 'tooltip' : '''\ + There's a very small gap between the glass block + and the wall. Through that gap you can hookshot + the target on the ceiling. + '''}, + 'Death Mountain Trail Chest with Strength': { + 'name' : 'logic_dmt_bombable', + 'tags' : ("Death Mountain Trail",), + 'tooltip' : '''\ + Child Link can blow up the wall using a nearby bomb + flower. You must backwalk with the flower and then + quickly throw it toward the wall. + '''}, + 'Goron City Spinning Pot PoH with Strength': { + 'name' : 'logic_goron_city_pot_with_strength', + 'tags' : ("Goron City",), + 'tooltip' : '''\ + Allows for stopping the Goron City Spinning + Pot using a bomb flower alone, requiring + strength in lieu of inventory explosives. + '''}, + 'Adult Kokiri Forest GS with Hover Boots': { + 'name' : 'logic_adult_kokiri_gs', + 'tags' : ("Kokiri Forest", "Skulltulas",), + 'tooltip' : '''\ + Can be obtained without Hookshot by using the Hover + Boots off of one of the roots. + '''}, + 'Spirit Temple MQ Frozen Eye Switch without Fire': { + 'name' : 'logic_spirit_mq_frozen_eye', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + You can melt the ice by shooting an arrow through a + torch. The only way to find a line of sight for this + shot is to first spawn a Song of Time block, and then + stand on the very edge of it. + '''}, + 'Spirit Temple Shifting Wall with No Additional Items': { + 'name' : 'logic_spirit_wall', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + The logic normally guarantees a way of dealing with both + the Beamos and the Walltula before climbing the wall. + '''}, + 'Spirit Temple Main Room GS with Boomerang': { + 'name' : 'logic_spirit_lobby_gs', + 'tags' : ("Spirit Temple", "Skulltulas",), + 'tooltip' : '''\ + Standing on the highest part of the arm of the statue, a + precise Boomerang throw can kill and obtain this Gold + Skulltula. You must throw the Boomerang slightly off to + the side so that it curves into the Skulltula, as aiming + directly at it will clank off of the wall in front. + '''}, + 'Spirit Temple Main Room Jump from Hands to Upper Ledges': { + 'name' : 'logic_spirit_lobby_jump', + 'tags' : ("Spirit Temple", "Skulltulas",), + 'tooltip' : '''\ + A precise jump to obtain the following as adult + without needing one of Hookshot or Hover Boots: + - Spirit Temple Statue Room Northeast Chest + - Spirit Temple GS Lobby + '''}, + 'Spirit Temple MQ Sun Block Room GS with Boomerang': { + 'name' : 'logic_spirit_mq_sun_block_gs', + 'tags' : ("Spirit Temple", "Skulltulas",), + 'tooltip' : '''\ + Throw the Boomerang in such a way that it + curves through the side of the glass block + to hit the Gold Skulltula. + '''}, + 'Jabu Scrub as Adult with Jump Dive': { + 'name' : 'logic_jabu_scrub_jump_dive', + 'tags' : ("Jabu Jabu's Belly", "Entrance",), + 'tooltip' : '''\ + Standing above the underwater tunnel leading to the scrub, + jump down and swim through the tunnel. This allows adult to + access the scrub with no Scale or Iron Boots. + '''}, + 'Jabu MQ Song of Time Block GS with Boomerang': { + 'name' : 'logic_jabu_mq_sot_gs', + 'tags' : ("Jabu Jabu's Belly", "Skulltulas",), + 'tooltip' : '''\ + Allow the Boomerang to return to you through + the Song of Time block to grab the token. + '''}, + 'Bottom of the Well MQ Dead Hand Freestanding Key with Boomerang': { + 'name' : 'logic_botw_mq_dead_hand_key', + 'tags' : ("Bottom of the Well",), + 'tooltip' : '''\ + Boomerang can fish the item out of the rubble without + needing explosives to blow it up. + '''}, + 'Fire Temple Flame Wall Maze Skip': { + 'name' : 'logic_fire_flame_maze', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + If you move quickly you can sneak past the edge of + a flame wall before it can rise up to block you. + To do it without taking damage is more precise. + Allows you to progress without needing either a + Small Key or Hover Boots. + '''}, + 'Fire Temple MQ Flame Wall Maze Skip': { + 'name' : 'logic_fire_mq_flame_maze', + 'tags' : ("Fire Temple", "Skulltulas",), + 'tooltip' : '''\ + If you move quickly you can sneak past the edge of + a flame wall before it can rise up to block you. + To do it without taking damage is more precise. + Allows you to reach the side room GS without needing + Song of Time or Hover Boots. If either of "Fire Temple + MQ Lower to Upper Lizalfos Maze with Hover Boots" or + "with Precise Jump" are enabled, this also allows you + to progress deeper into the dungeon without Hookshot. + '''}, + 'Fire Temple MQ Climb without Fire Source': { + 'name' : 'logic_fire_mq_climb', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + You can use the Hover Boots to hover around to + the climbable wall, skipping the need to use a + fire source and spawn a Hookshot target. + '''}, + 'Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots': { + 'name' : 'logic_fire_mq_maze_hovers', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + Use the Hover Boots off of a crate to + climb to the upper maze without needing + to spawn and use the Hookshot targets. + '''}, + 'Fire Temple MQ Chest Near Boss without Breaking Crate': { + 'name' : 'logic_fire_mq_near_boss', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + The hitbox for the torch extends a bit outside of the crate. + Shoot a flaming arrow at the side of the crate to light the + torch without needing to get over there and break the crate. + '''}, + 'Fire Temple MQ Lizalfos Maze Side Room without Box': { + 'name' : 'logic_fire_mq_maze_side_room', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + You can walk from the blue switch to the door and + quickly open the door before the bars reclose. This + skips needing to reach the upper sections of the + maze to get a box to place on the switch. + '''}, + 'Fire Temple MQ Boss Key Chest without Bow': { + 'name' : 'logic_fire_mq_bk_chest', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + It is possible to light both of the timed torches + to unbar the door to the boss key chest's room + with just Din's Fire if you move very quickly + between the two torches. It is also possible to + unbar the door with just Din's by abusing an + oversight in the way the game counts how many + torches have been lit. + '''}, + 'Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot': { + 'name' : 'logic_fire_mq_above_maze_gs', + 'tags' : ("Fire Temple", "Skulltulas",), + 'tooltip' : '''\ + The floor of the room that contains this Skulltula + is only solid from above. From the maze below, the + Longshot can be shot through the ceiling to obtain + the token with two fewer small keys than normal. + '''}, + 'Zora\'s River Lower Freestanding PoH as Adult with Nothing': { + 'name' : 'logic_zora_river_lower', + 'tags' : ("Zora's River",), + 'tooltip' : '''\ + Adult can reach this PoH with a precise jump, + no Hover Boots required. + '''}, + 'Water Temple Cracked Wall with Hover Boots': { + 'name' : 'logic_water_cracked_wall_hovers', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + With a midair side-hop while wearing the Hover + Boots, you can reach the cracked wall without + needing to raise the water up to the middle level. + '''}, + 'Shadow Temple Freestanding Key with Bombchu': { + 'name' : 'logic_shadow_freestanding_key', + 'tags' : ("Shadow Temple",), + 'tooltip' : '''\ + Release the Bombchu with good timing so that + it explodes near the bottom of the pot. + '''}, + 'Shadow Temple MQ Invisible Blades Silver Rupees without Song of Time': { + 'name' : 'logic_shadow_mq_invisible_blades', + 'tags' : ("Shadow Temple",), + 'tooltip' : '''\ + The Like Like can be used to boost you into the + silver rupee that normally requires Song of Time. + This cannot be performed on OHKO since the Like + Like does not boost you high enough if you die. + '''}, + 'Shadow Temple MQ Lower Huge Pit without Fire Source': { + 'name' : 'logic_shadow_mq_huge_pit', + 'tags' : ("Shadow Temple",), + 'tooltip' : '''\ + Normally a frozen eye switch spawns some platforms + that you can use to climb down, but there's actually + a small piece of ground that you can stand on that + you can just jump down to. + '''}, + 'Backflip over Mido as Adult': { + 'name' : 'logic_mido_backflip', + 'tags' : ("the Lost Woods",), + 'tooltip' : '''\ + With a specific position and angle, you can + backflip over Mido. + '''}, + 'Fire Temple Boss Door without Hover Boots or Pillar': { + 'name' : 'logic_fire_boss_door_jump', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + The Fire Temple Boss Door can be reached with a precise + jump. You must be touching the side wall of the room so + that Link will grab the ledge from farther away than + is normally possible. + '''}, + 'Lake Hylia Lab Dive without Gold Scale': { + 'name' : 'logic_lab_diving', + 'tags' : ("Lake Hylia",), + 'tooltip' : '''\ + Remove the Iron Boots in the midst of + Hookshotting the underwater crate. + '''}, + 'Deliver Eye Drops with Bolero of Fire': { + 'name' : 'logic_biggoron_bolero', + 'tags' : ("Death Mountain Trail",), + 'tooltip' : '''\ + Playing a warp song normally causes a trade item to + spoil immediately, however, it is possible use Bolero + to reach Biggoron and still deliver the Eye Drops + before they spoil. If you do not wear the Goron Tunic, + the heat timer inside the crater will override the trade + item's timer. When you exit to Death Mountain Trail you + will have one second to show the Eye Drops before they + expire. You can get extra time to show the Eye Drops if + you warp immediately upon receiving them. If you don't + have many hearts, you may have to reset the heat timer + by quickly dipping in and out of Darunia's chamber. + This trick does not apply if "Randomize Warp Song + Destinations" is enabled, or if the settings are such + that trade items do not need to be delivered within a + time limit. + '''}, + 'Wasteland Crossing without Hover Boots or Longshot': { + 'name' : 'logic_wasteland_crossing', + 'tags' : ("Haunted Wasteland",), + 'tooltip' : '''\ + You can beat the quicksand by backwalking across it + in a specific way. + '''}, + 'Colossus Hill GS with Hookshot': { + 'name' : 'logic_colossus_gs', + 'tags' : ("Desert Colossus", "Skulltulas",), + 'tooltip' : '''\ + Somewhat precise. If you kill enough Leevers + you can get enough of a break to take some time + to aim more carefully. + '''}, + 'Dodongo\'s Cavern Scarecrow GS with Armos Statue': { + 'name' : 'logic_dc_scarecrow_gs', + 'tags' : ("Dodongo's Cavern", "Skulltulas",), + 'tooltip' : '''\ + You can jump off an Armos Statue to reach the + alcove with the Gold Skulltula. It takes quite + a long time to pull the statue the entire way. + The jump to the alcove can be a bit picky when + done as child. + '''}, + 'Kakariko Tower GS with Jump Slash': { + 'name' : 'logic_kakariko_tower_gs', + 'tags' : ("Kakariko Village", "Skulltulas",), + 'tooltip' : '''\ + Climb the tower as high as you can without + touching the Gold Skulltula, then let go and + jump slash immediately. You will take fall + damage. + '''}, + 'Deku Tree MQ Compass Room GS Boulders with Just Hammer': { + 'name' : 'logic_deku_mq_compass_gs', + 'tags' : ("Deku Tree", "Skulltulas",), + 'tooltip' : '''\ + Climb to the top of the vines, then let go + and jump slash immediately to destroy the + boulders using the Hammer, without needing + to spawn a Song of Time block. + '''}, + 'Lake Hylia Lab Wall GS with Jump Slash': { + 'name' : 'logic_lab_wall_gs', + 'tags' : ("Lake Hylia", "Skulltulas",), + 'tooltip' : '''\ + The jump slash to actually collect the + token is somewhat precise. + '''}, + 'Spirit Temple MQ Lower Adult without Fire Arrows': { + 'name' : 'logic_spirit_mq_lower_adult', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + It can be done with Din\'s Fire and Bow. + Whenever an arrow passes through a lit torch, it + resets the timer. It's finicky but it's also + possible to stand on the pillar next to the center + torch, which makes it easier. + '''}, + 'Spirit Temple Map Chest with Bow': { + 'name' : 'logic_spirit_map_chest', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + To get a line of sight from the upper torch to + the map chest torches, you must pull an Armos + statue all the way up the stairs. + '''}, + 'Spirit Temple Sun Block Room Chest with Bow': { + 'name' : 'logic_spirit_sun_chest', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + Using the blocks in the room as platforms you can + get lines of sight to all three torches. The timer + on the torches is quite short so you must move + quickly in order to light all three. + '''}, + 'Spirit Temple MQ Sun Block Room as Child without Song of Time': { + 'name' : 'logic_spirit_mq_sun_block_sot', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + While adult can easily jump directly to the switch that + unbars the door to the sun block room, child Link cannot + make the jump without spawning a Song of Time block to + jump from. You can skip this by throwing the crate down + onto the switch from above, which does unbar the door, + however the crate immediately breaks, so you must move + quickly to get through the door before it closes back up. + '''}, + 'Shadow Trial MQ Torch with Bow': { + 'name' : 'logic_shadow_trial_mq', + 'tags' : ("Ganon's Castle",), + 'tooltip' : '''\ + You can light the torch in this room without a fire + source by shooting an arrow through the lit torch + at the beginning of the room. Because the room is + so dark and the unlit torch is so far away, it can + be difficult to aim the shot correctly. + '''}, + 'Forest Temple NE Outdoors Ledge with Hover Boots': { + 'name' : 'logic_forest_outdoors_ledge', + 'tags' : ("Forest Temple", "Entrance",), + 'tooltip' : '''\ + With precise Hover Boots movement you can fall down + to this ledge from upper balconies. If done precisely + enough, it is not necessary to take fall damage. + In MQ, this skips a Longshot requirement. + In Vanilla, this can skip a Hookshot requirement in + entrance randomizer. + '''}, + 'Water Temple Boss Key Region with Hover Boots': { + 'name' : 'logic_water_boss_key_region', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + With precise Hover Boots movement it is possible + to reach the boss key chest's region without + needing the Longshot. It is not necessary to take + damage from the spikes. The Gold Skulltula Token + in the following room can also be obtained with + just the Hover Boots. + '''}, + 'Water Temple MQ North Basement GS without Small Key': { + 'name' : 'logic_water_mq_locked_gs', + 'tags' : ("Water Temple", "Skulltulas",), + 'tooltip' : '''\ + There is an invisible Hookshot target that can be used + to get over the gate that blocks you from going to this + Skulltula early. This avoids going through some rooms + that normally require a Small Key to access. If "Water + Temple North Basement Ledge with Precise Jump" is not + enabled, this also skips needing Hover Boots or + Scarecrow's Song to reach the locked door. + '''}, + 'Water Temple Falling Platform Room GS with Hookshot': { + 'name' : 'logic_water_falling_platform_gs_hookshot', + 'tags' : ("Water Temple", "Skulltulas",), + 'tooltip' : '''\ + If you stand on the very edge of the platform, this + Gold Skulltula can be obtained with only the Hookshot. + '''}, + 'Water Temple Falling Platform Room GS with Boomerang': { + 'name' : 'logic_water_falling_platform_gs_boomerang', + 'tags' : ("Water Temple", "Skulltulas", "Entrance",), + 'tooltip' : '''\ + If you stand on the very edge of the platform, this + Gold Skulltula can be obtained with only the Boomerang. + '''}, + 'Water Temple River GS without Iron Boots': { + 'name' : 'logic_water_river_gs', + 'tags' : ("Water Temple", "Skulltulas",), + 'tooltip' : '''\ + Standing on the exposed ground toward the end of + the river, a precise Longshot use can obtain the + token. The Longshot cannot normally reach far + enough to kill the Skulltula, however. You'll + first have to find some other way of killing it. + '''}, + 'Water Temple Entry without Iron Boots using Hookshot': { + 'name' : 'logic_water_hookshot_entry', + 'tags' : ("Lake Hylia",), + 'tooltip' : '''\ + When entering Water Temple using Gold Scale instead + of Iron Boots, the Longshot is usually used to be + able to hit the switch and open the gate. But, by + standing in a particular spot, the switch can be hit + with only the reach of the Hookshot. + '''}, + 'Death Mountain Trail Climb with Hover Boots': { + 'name' : 'logic_dmt_climb_hovers', + 'tags' : ("Death Mountain Trail",), + 'tooltip' : '''\ + It is possible to use the Hover Boots to bypass + needing to destroy the boulders blocking the path + to the top of Death Mountain. + '''}, + 'Death Mountain Trail Upper Red Rock GS without Hammer': { + 'name' : 'logic_trail_gs_upper', + 'tags' : ("Death Mountain Trail", "Skulltulas",), + 'tooltip' : '''\ + After killing the Skulltula, the token can be collected + by backflipping into the rock at the correct angle. + '''}, + 'Death Mountain Trail Lower Red Rock GS with Hookshot': { + 'name' : 'logic_trail_gs_lower_hookshot', + 'tags' : ("Death Mountain Trail", "Skulltulas",), + 'tooltip' : '''\ + After killing the Skulltula, the token can be fished + out of the rock without needing to destroy it, by + using the Hookshot in the correct way. + '''}, + 'Death Mountain Trail Lower Red Rock GS with Hover Boots': { + 'name' : 'logic_trail_gs_lower_hovers', + 'tags' : ("Death Mountain Trail", "Skulltulas",), + 'tooltip' : '''\ + After killing the Skulltula, the token can be + collected without needing to destroy the rock by + backflipping down onto it with the Hover Boots. + First use the Hover Boots to stand on a nearby + fence, and go for the Skulltula Token from there. + '''}, + 'Death Mountain Trail Lower Red Rock GS with Magic Bean': { + 'name' : 'logic_trail_gs_lower_bean', + 'tags' : ("Death Mountain Trail", "Skulltulas",), + 'tooltip' : '''\ + After killing the Skulltula, the token can be + collected without needing to destroy the rock by + jumping down onto it from the bean plant, + midflight, with precise timing and positioning. + '''}, + 'Death Mountain Crater Upper to Lower with Hammer': { + 'name' : 'logic_crater_upper_to_lower', + 'tags' : ("Death Mountain Crater",), + 'tooltip' : '''\ + With the Hammer, you can jump slash the rock twice + in the same jump in order to destroy it before you + fall into the lava. + '''}, + 'Zora\'s Domain Entry with Hover Boots': { + 'name' : 'logic_zora_with_hovers', + 'tags' : ("Zora's River",), + 'tooltip' : '''\ + Can hover behind the waterfall as adult. + '''}, + 'Zora\'s Domain GS with No Additional Items': { + 'name' : 'logic_domain_gs', + 'tags' : ("Zora's Domain", "Skulltulas",), + 'tooltip' : '''\ + A precise jump slash can kill the Skulltula and + recoil back onto the top of the frozen waterfall. + To kill it, the logic normally guarantees one of + Hookshot, Bow, or Magic. + '''}, + 'Shadow Temple River Statue with Bombchu': { + 'name' : 'logic_shadow_statue', + 'tags' : ("Shadow Temple",), + 'tooltip' : '''\ + By sending a Bombchu around the edge of the + gorge, you can knock down the statue without + needing a Bow. + Applies in both vanilla and MQ Shadow. + '''}, + 'Stop Link the Goron with Din\'s Fire': { + 'name' : 'logic_link_goron_dins', + 'tags' : ("Goron City",), + 'tooltip' : '''\ + The timing is quite awkward. + '''}, + 'Fire Temple Song of Time Room GS without Song of Time': { + 'name' : 'logic_fire_song_of_time', + 'tags' : ("Fire Temple", "Skulltulas",), + 'tooltip' : '''\ + A precise jump can be used to reach this room. + '''}, + 'Fire Temple Climb without Strength': { + 'name' : 'logic_fire_strength', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + A precise jump can be used to skip + pushing the block. + '''}, + 'Fire Temple MQ Big Lava Room Blocked Door without Hookshot': { + 'name' : 'logic_fire_mq_blocked_chest', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + There is a gap between the hitboxes of the flame + wall in the big lava room. If you know where this + gap is located, you can jump through it and skip + needing to use the Hookshot. To do this without + taking damage is more precise. + '''}, + 'Fire Temple MQ Lower to Upper Lizalfos Maze with Precise Jump': { + 'name' : 'logic_fire_mq_maze_jump', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + A precise jump off of a crate can be used to + climb to the upper maze without needing to spawn + and use the Hookshot targets. This trick + supersedes both "Fire Temple MQ Lower to Upper + Lizalfos Maze with Hover Boots" and "Fire Temple + MQ Lizalfos Maze Side Room without Box". + '''}, + 'Light Trial MQ without Hookshot': { + 'name' : 'logic_light_trial_mq', + 'tags' : ("Ganon's Castle",), + 'tooltip' : '''\ + If you move quickly you can sneak past the edge of + a flame wall before it can rise up to block you. + In this case to do it without taking damage is + especially precise. + '''}, + 'Ice Cavern MQ Scarecrow GS with No Additional Items': { + 'name' : 'logic_ice_mq_scarecrow', + 'tags' : ("Ice Cavern", "Skulltulas",), + 'tooltip' : '''\ + A precise jump can be used to reach this alcove. + '''}, + 'Ice Cavern MQ Red Ice GS without Song of Time': { + 'name' : 'logic_ice_mq_red_ice_gs', + 'tags' : ("Ice Cavern", "Skulltulas",), + 'tooltip' : '''\ + If you side-hop into the perfect position, you + can briefly stand on the platform with the red + ice just long enough to dump some blue fire. + '''}, + 'Ice Cavern Block Room GS with Hover Boots': { + 'name' : 'logic_ice_block_gs', + 'tags' : ("Ice Cavern", "Skulltulas",), + 'tooltip' : '''\ + The Hover Boots can be used to get in front of the + Skulltula to kill it with a jump slash. Then, the + Hover Boots can again be used to obtain the Token, + all without Hookshot or Boomerang. + '''}, + 'Reverse Wasteland': { + 'name' : 'logic_reverse_wasteland', + 'tags' : ("Haunted Wasteland",), + 'tooltip' : '''\ + By memorizing the path, you can travel through the + Wasteland in reverse. + Note that jumping to the carpet merchant as child + typically requires a fairly precise jump slash. + The equivalent trick for going forward through the + Wasteland is "Lensless Wasteland". + To cross the river of sand with no additional items, + be sure to also enable "Wasteland Crossing without + Hover Boots or Longshot". + Unless all overworld entrances are randomized, child + Link will not be expected to do anything at Gerudo's + Fortress. + '''}, + 'Zora\'s River Upper Freestanding PoH as Adult with Nothing': { + 'name' : 'logic_zora_river_upper', + 'tags' : ("Zora's River",), + 'tooltip' : '''\ + Adult can reach this PoH with a precise jump, + no Hover Boots required. + '''}, + 'Shadow Temple MQ Truth Spinner Gap with Longshot': { + 'name' : 'logic_shadow_mq_gap', + 'tags' : ("Shadow Temple",), + 'tooltip' : '''\ + You can Longshot a torch and jump-slash recoil onto + the tongue. It works best if you Longshot the right + torch from the left side of the room. + '''}, + 'Lost Woods Adult GS without Bean': { + 'name' : 'logic_lost_woods_gs_bean', + 'tags' : ("the Lost Woods", "Skulltulas",), + 'tooltip' : '''\ + You can collect the token with a precise + Hookshot use, as long as you can kill the + Skulltula somehow first. It can be killed + using Longshot, Bow, Bombchus or Din's Fire. + '''}, + 'Jabu Near Boss GS without Boomerang as Adult': { + 'name' : 'logic_jabu_boss_gs_adult', + 'tags' : ("Jabu Jabu's Belly", "Skulltulas", "Entrance",), + 'tooltip' : '''\ + You can easily get over to the door to the + near boss area early with Hover Boots. The + tricky part is getting through the door + without being able to use a box to keep the + switch pressed. One way is to quickly roll + from the switch and open the door before it + closes. + '''}, + 'Kakariko Rooftop GS with Hover Boots': { + 'name' : 'logic_kakariko_rooftop_gs', + 'tags' : ("Kakariko Village", "Skulltulas",), + 'tooltip' : '''\ + Take the Hover Boots from the entrance to Impa's + House over to the rooftop of Skulltula House. From + there, a precise Hover Boots backwalk with backflip + can be used to get onto a hill above the side of + the village. And then from there you can Hover onto + Impa's rooftop to kill the Skulltula and backflip + into the token. + '''}, + 'Graveyard Freestanding PoH with Boomerang': { + 'name' : 'logic_graveyard_poh', + 'tags' : ("the Graveyard",), + 'tooltip' : '''\ + Using a precise moving setup you can obtain + the Piece of Heart by having the Boomerang + interact with it along the return path. + '''}, + 'Hyrule Castle Storms Grotto GS with Just Boomerang': { + 'name' : 'logic_castle_storms_gs', + 'tags' : ("Hyrule Castle", "Skulltulas",), + 'tooltip' : '''\ + With precise throws, the Boomerang alone can + kill the Skulltula and collect the token, + without first needing to blow up the wall. + '''}, + 'Death Mountain Trail Soil GS without Destroying Boulder': { + 'name' : 'logic_dmt_soil_gs', + 'tags' : ("Death Mountain Trail", "Skulltulas",), + 'tooltip' : '''\ + Bugs will go into the soft soil even while the boulder is + still blocking the entrance. + Then, using a precise moving setup you can kill the Gold + Skulltula and obtain the token by having the Boomerang + interact with it along the return path. + '''}, + 'Gerudo Training Grounds Left Side Silver Rupees without Hookshot': { + 'name' : 'logic_gtg_without_hookshot', + 'tags' : ("Gerudo Training Grounds",), + 'tooltip' : '''\ + After collecting the rest of the silver rupees in the room, + you can reach the final silver rupee on the ceiling by being + pulled up into it after getting grabbed by the Wallmaster. + Then, you must also reach the exit of the room without the + use of the Hookshot. If you move quickly you can sneak past + the edge of a flame wall before it can rise up to block you. + To do so without taking damage is more precise. + '''}, + 'Gerudo Training Grounds MQ Left Side Silver Rupees without Hookshot': { + 'name' : 'logic_gtg_mq_without_hookshot', + 'tags' : ("Gerudo Training Grounds",), + 'tooltip' : '''\ + After collecting the rest of the silver rupees in the room, + you can reach the final silver rupee on the ceiling by being + pulled up into it after getting grabbed by the Wallmaster. + The Wallmaster will not track you to directly underneath the + rupee. You should take the last step to be under the rupee + after the Wallmaster has begun its attempt to grab you. + Also included with this trick is that fact that the switch + that unbars the door to the final chest of GTG can be hit + without a projectile, using a precise jump slash. + This trick supersedes "Gerudo Training Grounds MQ Left Side + Silver Rupees with Hookshot". + '''}, + 'Reach Gerudo Training Grounds Fake Wall Ledge with Hover Boots': { + 'name' : 'logic_gtg_fake_wall', + 'tags' : ("Gerudo Training Grounds",), + 'tooltip' : '''\ + A precise Hover Boots use from the top of the chest can allow + you to grab the ledge without needing the usual requirements. + In Master Quest, this always skips a Song of Time requirement. + In Vanilla, this skips a Hookshot requirement, but is only + relevant if "Gerudo Training Grounds Left Side Silver Rupees + without Hookshot" is enabled. + '''}, + 'Water Temple Cracked Wall with No Additional Items': { + 'name' : 'logic_water_cracked_wall_nothing', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + A precise jump slash (among other methods) will + get you to the cracked wall without needing the + Hover Boots or to raise the water to the middle + level. This trick supersedes "Water Temple + Cracked Wall with Hover Boots". + '''}, + 'Water Temple North Basement Ledge with Precise Jump': { + 'name' : 'logic_water_north_basement_ledge_jump', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + In the northern basement there's a ledge from where, in + vanilla Water Temple, boulders roll out into the room. + Normally to jump directly to this ledge logically + requires the Hover Boots, but with precise jump, it can + be done without them. This trick applies to both + Vanilla and Master Quest. + '''}, + 'Water Temple Torch Longshot': { + 'name' : 'logic_water_temple_torch_longshot', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + Stand on the eastern side of the central pillar and longshot + the torches on the bottom level. Swim through the corridor + and float up to the top level. This allows access to this + area and lower water levels without Iron Boots. + The majority of the tricks that allow you to skip Iron Boots + in the Water Temple are not going to be relevant unless this + trick is first enabled. + '''}, + 'Water Temple Central Pillar GS with Farore\'s Wind': { + 'name' : 'logic_water_central_gs_fw', + 'tags' : ("Water Temple", "Skulltulas",), + 'tooltip' : '''\ + If you set Farore's Wind inside the central pillar + and then return to that warp point after raising + the water to the highest level, you can obtain this + Skulltula Token with Hookshot or Boomerang. + '''}, + 'Water Temple Central Pillar GS with Iron Boots': { + 'name' : 'logic_water_central_gs_irons', + 'tags' : ("Water Temple", "Skulltulas",), + 'tooltip' : '''\ + After opening the middle water level door into the + central pillar, the door will stay unbarred so long + as you do not leave the room -- even if you were to + raise the water up to the highest level. With the + Iron Boots to go through the door after the water has + been raised, you can obtain the Skulltula Token with + the Hookshot. + '''}, + 'Water Temple Boss Key Jump Dive': { + 'name' : 'logic_water_bk_jump_dive', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + Stand on the very edge of the raised corridor leading from the + push block room to the rolling boulder corridor. Face the + gold skulltula on the waterfall and jump over the boulder + corridor floor into the pool of water, swimming right once + underwater. This allows access to the boss key room without + Iron boots. + '''}, + 'Water Temple Dragon Statue Jump Dive': { + 'name' : 'logic_water_dragon_jump_dive', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + If you come into the dragon statue room from the + serpent river, you can jump down from above and get + into the tunnel without needing either Iron Boots + or a Scale. This trick applies to both Vanilla and + Master Quest. In Vanilla, you must shoot the switch + from above with the Bow, and then quickly get + through the tunnel before the gate closes. + '''}, + 'Water Temple Dragon Statue Switch from Above the Water as Adult': { + 'name' : 'logic_water_dragon_adult', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + Normally you need both Hookshot and Iron Boots to hit the + switch and swim through the tunnel to get to the chest. But + by hitting the switch from dry land, using one of Bombchus, + Hookshot, or Bow, it is possible to skip one or both of + those requirements. After the gate has been opened, besides + just using the Iron Boots, a well-timed dive with at least + the Silver Scale could be used to swim through the tunnel. If + coming from the serpent river, a jump dive can also be used + to get into the tunnel. + '''}, + 'Water Temple Dragon Statue Switch from Above the Water as Child': { + 'name' : 'logic_water_dragon_child', + 'tags' : ("Water Temple", "Entrance",), + 'tooltip' : '''\ + It is possible for child to hit the switch from dry land + using one of Bombchus, Slingshot or Boomerang. Then, to + get to the chest, child can dive through the tunnel using + at least the Silver Scale. The timing and positioning of + this dive needs to be perfect to actually make it under the + gate, and it all needs to be done very quickly to be able to + get through before the gate closes. Be sure to enable "Water + Temple Dragon Statue Switch from Above the Water as Adult" + for adult's variant of this trick. + '''}, + 'Goron City Maze Left Chest with Hover Boots': { + 'name' : 'logic_goron_city_leftmost', + 'tags' : ("Goron City",), + 'tooltip' : '''\ + A precise backwalk starting from on top of the + crate and ending with a precisely-timed backflip + can reach this chest without needing either + the Hammer or Silver Gauntlets. + '''}, + 'Goron City Grotto with Hookshot While Taking Damage': { + 'name' : 'logic_goron_grotto', + 'tags' : ("Goron City",), + 'tooltip' : '''\ + It is possible to reach the Goron City Grotto by + quickly using the Hookshot while in the midst of + taking damage from the lava floor. This trick will + not be expected on OHKO or quadruple damage. + '''}, + 'Deku Tree Basement without Slingshot': { + 'name' : 'logic_deku_b1_skip', + 'tags' : ("Deku Tree",), + 'tooltip' : '''\ + A precise jump can be used to skip + needing to use the Slingshot to go + around B1 of the Deku Tree. If used + with the "Closed Forest" setting, a + Slingshot will not be guaranteed to + exist somewhere inside the Forest. + This trick applies to both Vanilla + and Master Quest. + '''}, + 'Spirit Temple Lower Adult Switch with Bombs': { + 'name' : 'logic_spirit_lower_adult_switch', + 'tags' : ("Spirit Temple",), + 'tooltip' : '''\ + A bomb can be used to hit the switch on the ceiling, + but it must be thrown from a particular distance + away and with precise timing. + '''}, + 'Forest Temple Outside Backdoor with Jump Slash': { + 'name' : 'logic_forest_outside_backdoor', + 'tags' : ("Forest Temple",), + 'tooltip' : '''\ + With a precise jump slash from above, + you can reach the backdoor to the west + courtyard without Hover Boots. Applies + to both Vanilla and Master Quest. + '''}, + 'Forest Temple East Courtyard Door Frame with Hover Boots': { + 'name' : 'logic_forest_door_frame', + 'tags' : ("Forest Temple",), + 'tooltip' : '''\ + A precise Hover Boots movement from the upper + balconies in this courtyard can be used to get on + top of the door frame. Applies to both Vanilla and + Master Quest. In Vanilla, from on top the door + frame you can summon Pierre, allowing you to access + the falling ceiling room early. In Master Quest, + this allows you to obtain the GS on the door frame + as adult without Hookshot or Song of Time. + '''}, + 'Dodongo\'s Cavern MQ Early Bomb Bag Area as Child': { + 'name' : 'logic_dc_mq_child_bombs', + 'tags' : ("Dodongo's Cavern",), + 'tooltip' : '''\ + With a precise jump slash from above, you + can reach the Bomb Bag area as only child + without needing a Slingshot. You will + take fall damage. + '''}, + 'Dodongo\'s Cavern Two Scrub Room with Strength': { + 'name' : 'logic_dc_scrub_room', + 'tags' : ("Dodongo's Cavern",), + 'tooltip' : '''\ + With help from a conveniently-positioned block, + Adult can quickly carry a bomb flower over to + destroy the mud wall blocking the room with two + Deku Scrubs. + '''}, + 'Dodongo\'s Cavern Child Slingshot Skips': { + 'name' : 'logic_dc_slingshot_skip', + 'tags' : ("Dodongo's Cavern",), + 'tooltip' : '''\ + With precise platforming, child can cross the + platforms while the flame circles are there. + When enabling this trick, it's recommended that + you also enable the Adult variant: "Dodongo's + Cavern Spike Trap Room Jump without Hover Boots". + '''}, + 'Dodongo\'s Cavern MQ Light the Eyes with Strength': { + 'name' : 'logic_dc_mq_eyes', + 'tags' : ("Dodongo's Cavern",), + 'tooltip' : '''\ + If you move very quickly, it is possible to use + the bomb flower at the top of the room to light + the eyes. To perform this trick as child is + significantly more difficult, but child will never + be expected to do so unless "Dodongo's Cavern MQ + Back Areas as Child without Explosives" is enabled. + Also, the bombable floor before King Dodongo can be + destroyed with Hammer if hit in the very center. + '''}, + 'Dodongo\'s Cavern MQ Back Areas as Child without Explosives': { + 'name' : 'logic_dc_mq_child_back', + 'tags' : ("Dodongo's Cavern",), + 'tooltip' : '''\ + Child can progress through the back areas without + explosives by throwing a pot at a switch to lower a + fire wall, and by defeating Armos to detonate bomb + flowers (among other methods). While these techniques + themselves are relatively simple, they're not + relevant unless "Dodongo's Cavern MQ Light the Eyes + with Strength" is enabled, which is a trick that + is particularly difficult for child to perform. + '''}, + 'Rolling Goron (Hot Rodder Goron) as Child with Strength': { + 'name' : 'logic_child_rolling_with_strength', + 'tags' : ("Goron City",), + 'tooltip' : '''\ + Use the bombflower on the stairs or near Medigoron. + Timing is tight, especially without backwalking. + '''}, + 'Goron City Spinning Pot PoH with Bombchu': { + 'name' : 'logic_goron_city_pot', + 'tags' : ("Goron City",), + 'tooltip' : '''\ + A Bombchu can be used to stop the spinning + pot, but it can be quite finicky to get it + to work. + '''}, + 'Gerudo Valley Crate PoH as Adult with Hover Boots': { + 'name' : 'logic_valley_crate_hovers', + 'tags' : ("Gerudo Valley",), + 'tooltip' : '''\ + From the far side of Gerudo Valley, a precise + Hover Boots movement and jump-slash recoil can + allow adult to reach the ledge with the crate + PoH without needing Longshot. You will take + fall damage. + '''}, + 'Jump onto the Lost Woods Bridge as Adult with Nothing': { + 'name' : 'logic_lost_woods_bridge', + 'tags' : ("the Lost Woods", "Entrance",), + 'tooltip' : '''\ + With very precise movement it's possible for + adult to jump onto the bridge without needing + Longshot, Hover Boots, or Bean. + '''}, + 'Spirit Trial without Hookshot': { + 'name' : 'logic_spirit_trial_hookshot', + 'tags' : ("Ganon's Castle",), + 'tooltip' : '''\ + A precise jump off of an Armos can + collect the highest rupee. + '''}, + 'Shadow Temple Stone Umbrella Skip': { + 'name' : 'logic_shadow_umbrella', + 'tags' : ("Shadow Temple",), + 'tooltip' : '''\ + A very precise Hover Boots movement + from off of the lower chest can get you + on top of the crushing spikes without + needing to pull the block. Applies to + both Vanilla and Master Quest. + '''}, + 'Shadow Temple Falling Spikes GS with Hover Boots': { + 'name' : 'logic_shadow_umbrella_gs', + 'tags' : ("Shadow Temple", "Skulltulas",), + 'tooltip' : '''\ + After killing the Skulltula, a very precise Hover Boots + movement from off of the lower chest can get you on top + of the crushing spikes without needing to pull the block. + From there, another very precise Hover Boots movement can + be used to obtain the token without needing the Hookshot. + Applies to both Vanilla and Master Quest. For obtaining + the chests in this room with just Hover Boots, be sure to + enable "Shadow Temple Stone Umbrella Skip". + '''}, + 'Water Temple Central Bow Target without Longshot or Hover Boots': { + 'name' : 'logic_water_central_bow', + 'tags' : ("Water Temple",), + 'tooltip' : '''\ + A very precise Bow shot can hit the eye + switch from the floor above. Then, you + can jump down into the hallway and make + through it before the gate closes. + It can also be done as child, using the + Slingshot instead of the Bow. + '''}, + 'Fire Temple East Tower without Scarecrow\'s Song': { + 'name' : 'logic_fire_scarecrow', + 'tags' : ("Fire Temple",), + 'tooltip' : '''\ + Also known as "Pixelshot". + The Longshot can reach the target on the elevator + itself, allowing you to skip needing to spawn the + scarecrow. + '''}, + 'Fire Trial MQ with Hookshot': { + 'name' : 'logic_fire_trial_mq', + 'tags' : ("Ganon's Castle",), + 'tooltip' : '''\ + It's possible to hook the target at the end of + fire trial with just Hookshot, but it requires + precise aim and perfect positioning. The main + difficulty comes from getting on the very corner + of the obelisk without falling into the lava. + '''}, + 'Shadow Temple Entry with Fire Arrows': { + 'name' : 'logic_shadow_fire_arrow_entry', + 'tags' : ("Shadow Temple",), + 'tooltip' : '''\ + It is possible to light all of the torches to + open the Shadow Temple entrance with just Fire + Arrows, but you must be very quick, precise, + and strategic with how you take your shots. + '''}, + 'Lensless Wasteland': { + 'name' : 'logic_lens_wasteland', + 'tags' : ("Lens of Truth","Haunted Wasteland",), + 'tooltip' : '''\ + By memorizing the path, you can travel through the + Wasteland without using the Lens of Truth to see + the Poe. + The equivalent trick for going in reverse through + the Wasteland is "Reverse Wasteland". + '''}, + 'Bottom of the Well without Lens of Truth': { + 'name' : 'logic_lens_botw', + 'tags' : ("Lens of Truth","Bottom of the Well",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Bottom of the Well. + '''}, + 'Ganon\'s Castle MQ without Lens of Truth': { + 'name' : 'logic_lens_castle_mq', + 'tags' : ("Lens of Truth","Ganon's Castle",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Ganon's Castle MQ. + '''}, + 'Ganon\'s Castle without Lens of Truth': { + 'name' : 'logic_lens_castle', + 'tags' : ("Lens of Truth","Ganon's Castle",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Ganon's Castle. + '''}, + 'Gerudo Training Grounds MQ without Lens of Truth': { + 'name' : 'logic_lens_gtg_mq', + 'tags' : ("Lens of Truth","Gerudo Training Grounds",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Gerudo Training Grounds MQ. + '''}, + 'Gerudo Training Grounds without Lens of Truth': { + 'name' : 'logic_lens_gtg', + 'tags' : ("Lens of Truth","Gerudo Training Grounds",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Gerudo Training Grounds. + '''}, + 'Jabu MQ without Lens of Truth': { + 'name' : 'logic_lens_jabu_mq', + 'tags' : ("Lens of Truth","Jabu Jabu's Belly",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Jabu MQ. + '''}, + 'Shadow Temple MQ before Invisible Moving Platform without Lens of Truth': { + 'name' : 'logic_lens_shadow_mq', + 'tags' : ("Lens of Truth","Shadow Temple",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Shadow Temple MQ before the invisible moving platform. + '''}, + 'Shadow Temple MQ beyond Invisible Moving Platform without Lens of Truth': { + 'name' : 'logic_lens_shadow_mq_back', + 'tags' : ("Lens of Truth","Shadow Temple",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Shadow Temple MQ beyond the invisible moving platform. + '''}, + 'Shadow Temple before Invisible Moving Platform without Lens of Truth': { + 'name' : 'logic_lens_shadow', + 'tags' : ("Lens of Truth","Shadow Temple",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Shadow Temple before the invisible moving platform. + '''}, + 'Shadow Temple beyond Invisible Moving Platform without Lens of Truth': { + 'name' : 'logic_lens_shadow_back', + 'tags' : ("Lens of Truth","Shadow Temple",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Shadow Temple beyond the invisible moving platform. + '''}, + 'Spirit Temple MQ without Lens of Truth': { + 'name' : 'logic_lens_spirit_mq', + 'tags' : ("Lens of Truth","Spirit Temple",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Spirit Temple MQ. + '''}, + 'Spirit Temple without Lens of Truth': { + 'name' : 'logic_lens_spirit', + 'tags' : ("Lens of Truth","Spirit Temple",), + 'tooltip' : '''\ + Removes the requirements for the Lens of Truth + in Spirit Temple. + '''}, +} + +normalized_name_tricks = {trick.casefold(): info for (trick, info) in known_logic_tricks.items()} \ No newline at end of file diff --git a/worlds/oot/MQ.py b/worlds/oot/MQ.py new file mode 100644 index 00000000..3120891e --- /dev/null +++ b/worlds/oot/MQ.py @@ -0,0 +1,732 @@ +# mzxrules 2018 +# In order to patch MQ to the existing data... +# +# Scenes: +# +# Ice Cavern (Scene 9) needs to have it's header altered to support MQ's path list. This +# expansion will delete the otherwise unused alternate headers command +# +# Transition actors will be patched over the old data, as the number of records is the same +# Path data will be appended to the end of the scene file. +# +# The size of a single path on file is NUM_POINTS * 6, rounded up to the nearest 4 byte boundary +# The total size consumed by the path data is NUM_PATHS * 8, plus the sum of all path file sizes +# padded to the nearest 0x10 bytes +# +# Collision: +# OoT's collision data consists of these elements: vertices, surface types, water boxes, +# camera behavior data, and polys. MQ's vertice and polygon geometry data is identical. +# However, the surface types and the collision exclusion flags bound to the polys have changed +# for some polygons, as well as the number of surface type records and camera type records. +# +# To patch collision, a flag denotes whether collision data cannot be written in place without +# expanding the size of the scene file. If true, the camera data is relocated to the end +# of the scene file, and the surface types are shifted down into where the camera types +# were situated. If false, the camera data isn't moved, but rather the surface type list +# will be shifted to the end of the camera data +# +# Rooms: +# +# Object file initialization data will be appended to the end of the room file. +# The total size consumed by the object file data is NUM_OBJECTS * 0x02, aligned to +# the nearest 0x04 bytes +# +# Actor spawn data will be appended to the end of the room file, after the objects. +# The total size consumed by the actor spawn data is NUM_ACTORS * 0x10 +# +# Finally: +# +# Scene and room files will be padded to the nearest 0x10 bytes +# +# Maps: +# Jabu Jabu's B1 map contains no chests in the vanilla layout. Because of this, +# the floor map data is missing a vertex pointer that would point within kaleido_scope. +# As such, if the file moves, the patch will break. + +from .Utils import data_path +from .Rom import Rom +import json +from struct import pack, unpack + +SCENE_TABLE = 0xB71440 + + +class File(object): + def __init__(self, file): + self.name = file['Name'] + self.start = int(file['Start'], 16) if 'Start' in file else 0 + self.end = int(file['End'], 16) if 'End' in file else self.start + self.remap = file['RemapStart'] if 'RemapStart' in file else None + self.from_file = self.start + + # used to update the file's associated dmadata record + self.dma_key = self.start + + if self.remap is not None: + self.remap = int(self.remap, 16) + + def __repr__(self): + remap = "None" + if self.remap is not None: + remap = "{0:x}".format(self.remap) + return "{0}: {1:x} {2:x}, remap {3}".format(self.name, self.start, self.end, remap) + + def relocate(self, rom:Rom): + if self.remap is None: + self.remap = rom.free_space() + + new_start = self.remap + + offset = new_start - self.start + new_end = self.end + offset + + rom.buffer[new_start:new_end] = rom.buffer[self.start:self.end] + self.start = new_start + self.end = new_end + update_dmadata(rom, self) + + # The file will now refer to the new copy of the file + def copy(self, rom:Rom): + self.dma_key = None + self.relocate(rom) + + +class CollisionMesh(object): + def __init__(self, rom:Rom, start, offset): + self.offset = offset + self.poly_addr = rom.read_int32(start + offset + 0x18) + self.polytypes_addr = rom.read_int32(start + offset + 0x1C) + self.camera_data_addr = rom.read_int32(start + offset + 0x20) + self.polytypes = (self.poly_addr - self.polytypes_addr) // 8 + + def write_to_scene(self, rom:Rom, start): + addr = start + self.offset + 0x18 + rom.write_int32s(addr, [self.poly_addr, self.polytypes_addr, self.camera_data_addr]) + + +class ColDelta(object): + def __init__(self, delta): + self.is_larger = delta['IsLarger'] + self.polys = delta['Polys'] + self.polytypes = delta['PolyTypes'] + self.cams = delta['Cams'] + + +class Icon(object): + def __init__(self, data): + self.icon = data["Icon"]; + self.count = data["Count"]; + self.points = [IconPoint(x) for x in data["IconPoints"]] + + def write_to_minimap(self, rom:Rom, addr): + rom.write_sbyte(addr, self.icon) + rom.write_byte(addr + 1, self.count) + cur = 2 + for p in self.points: + p.write_to_minimap(rom, addr + cur) + cur += 0x03 + + def write_to_floormap(self, rom:Rom, addr): + rom.write_int16(addr, self.icon) + rom.write_int32(addr + 0x10, self.count) + + cur = 0x14 + for p in self.points: + p.write_to_floormap(rom, addr + cur) + cur += 0x0C + + +class IconPoint(object): + def __init__(self, point): + self.flag = point["Flag"] + self.x = point["x"] + self.y = point["y"] + + def write_to_minimap(self, rom:Rom, addr): + rom.write_sbyte(addr, self.flag) + rom.write_byte(addr+1, self.x) + rom.write_byte(addr+2, self.y) + + def write_to_floormap(self, rom:Rom, addr): + rom.write_int16(addr, self.flag) + rom.write_f32(addr + 4, float(self.x)) + rom.write_f32(addr + 8, float(self.y)) + + +class Scene(object): + def __init__(self, scene): + self.file = File(scene['File']) + self.id = scene['Id'] + self.transition_actors = [convert_actor_data(x) for x in scene['TActors']] + self.rooms = [Room(x) for x in scene['Rooms']] + self.paths = [] + self.coldelta = ColDelta(scene["ColDelta"]) + self.minimaps = [[Icon(icon) for icon in minimap['Icons']] for minimap in scene['Minimaps']] + self.floormaps = [[Icon(icon) for icon in floormap['Icons']] for floormap in scene['Floormaps']] + temp_paths = scene['Paths'] + for item in temp_paths: + self.paths.append(item['Points']) + + + def write_data(self, rom:Rom): + # write floormap and minimap data + self.write_map_data(rom) + + # move file to remap address + if self.file.remap is not None: + self.file.relocate(rom) + + start = self.file.start + headcur = self.file.start + + room_list_offset = 0 + + code = rom.read_byte(headcur) + loop = 0x20 + while loop > 0 and code != 0x14: #terminator + loop -= 1 + + if code == 0x03: #collision + col_mesh_offset = rom.read_int24(headcur + 5) + col_mesh = CollisionMesh(rom, start, col_mesh_offset) + self.patch_mesh(rom, col_mesh); + + elif code == 0x04: #rooms + room_list_offset = rom.read_int24(headcur + 5) + + elif code == 0x0D: #paths + path_offset = self.append_path_data(rom) + rom.write_int32(headcur + 4, path_offset) + + elif code == 0x0E: #transition actors + t_offset = rom.read_int24(headcur + 5) + addr = self.file.start + t_offset + write_actor_data(rom, addr, self.transition_actors) + + headcur += 8 + code = rom.read_byte(headcur) + + # update file references + self.file.end = align16(self.file.end) + update_dmadata(rom, self.file) + update_scene_table(rom, self.id, self.file.start, self.file.end) + + # write room file data + for room in self.rooms: + room.write_data(rom) + if self.id == 6 and room.id == 6: + patch_spirit_temple_mq_room_6(rom, room.file.start) + + cur = self.file.start + room_list_offset + for room in self.rooms: + rom.write_int32s(cur, [room.file.start, room.file.end]) + cur += 0x08 + + + def write_map_data(self, rom:Rom): + if self.id >= 10: + return + + # write floormap + floormap_indices = 0xB6C934 + floormap_vrom = 0xBC7E00 + floormap_index = rom.read_int16(floormap_indices + (self.id * 2)) + floormap_index //= 2 # game uses texture index, where two textures are used per floor + + cur = floormap_vrom + (floormap_index * 0x1EC) + for floormap in self.floormaps: + for icon in floormap: + Icon.write_to_floormap(icon, rom, cur) + cur += 0xA4 + + + # fixes jabu jabu floor B1 having no chest data + if self.id == 2: + cur = floormap_vrom + (0x08 * 0x1EC + 4) + kaleido_scope_chest_verts = 0x803A3DA0 # hax, should be vram 0x8082EA00 + rom.write_int32s(cur, [0x17, kaleido_scope_chest_verts, 0x04]) + + # write minimaps + map_mark_vrom = 0xBF40D0 + map_mark_vram = 0x808567F0 + map_mark_array_vram = 0x8085D2DC # ptr array in map_mark_data to minimap "marks" + + array_vrom = map_mark_array_vram - map_mark_vram + map_mark_vrom + map_mark_scene_vram = rom.read_int32(self.id * 4 + array_vrom) + mark_vrom = map_mark_scene_vram - map_mark_vram + map_mark_vrom + + cur = mark_vrom + for minimap in self.minimaps: + for icon in minimap: + Icon.write_to_minimap(icon, rom, cur) + cur += 0x26 + + + def patch_mesh(self, rom:Rom, mesh:CollisionMesh): + start = self.file.start + + final_cams = [] + + # build final camera data + for cam in self.coldelta.cams: + data = cam['Data'] + pos = cam['PositionIndex'] + if pos < 0: + final_cams.append((data, 0)) + else: + addr = start + (mesh.camera_data_addr & 0xFFFFFF) + seg_off = rom.read_int32(addr + (pos * 8) + 4) + final_cams.append((data, seg_off)) + + types_move_addr = 0 + + # if data can't fit within the old mesh space, append camera data + if self.coldelta.is_larger: + types_move_addr = mesh.camera_data_addr + + # append to end of file + self.write_cam_data(rom, self.file.end, final_cams) + mesh.camera_data_addr = get_segment_address(2, self.file.end - self.file.start) + self.file.end += len(final_cams) * 8 + + else: + types_move_addr = mesh.camera_data_addr + (len(final_cams) * 8) + + # append in place + addr = self.file.start + (mesh.camera_data_addr & 0xFFFFFF) + self.write_cam_data(rom, addr, final_cams) + + # if polytypes needs to be moved, do so + if (types_move_addr != mesh.polytypes_addr): + a_start = self.file.start + (mesh.polytypes_addr & 0xFFFFFF) + b_start = self.file.start + (types_move_addr & 0xFFFFFF) + size = mesh.polytypes * 8 + + rom.buffer[b_start:b_start + size] = rom.buffer[a_start:a_start + size] + mesh.polytypes_addr = types_move_addr + + # patch polytypes + for item in self.coldelta.polytypes: + id = item['Id'] + high = item['High'] + low = item['Low'] + addr = self.file.start + (mesh.polytypes_addr & 0xFFFFFF) + (id * 8) + rom.write_int32s(addr, [high, low]) + + # patch poly data + for item in self.coldelta.polys: + id = item['Id'] + t = item['Type'] + flags = item['Flags'] + + addr = self.file.start + (mesh.poly_addr & 0xFFFFFF) + (id * 0x10) + vert_bit = rom.read_byte(addr + 0x02) & 0x1F # VertexA id data + rom.write_int16(addr, t) + rom.write_byte(addr + 0x02, (flags << 5) + vert_bit) + + # Write Mesh to Scene + mesh.write_to_scene(rom, self.file.start) + + + def write_cam_data(self, rom:Rom, addr, cam_data): + + for item in cam_data: + data, pos = item + rom.write_int32s(addr, [data, pos]) + addr += 8 + + + # appends path data to the end of the rom + # returns segment address to path data + def append_path_data(self, rom:Rom): + start = self.file.start + cur = self.file.end + records = [] + + for path in self.paths: + nodes = len(path) + offset = get_segment_address(2, cur - start) + records.append((nodes, offset)) + + #flatten + points = [x for points in path for x in points] + rom.write_int16s(cur, points) + path_size = align4(len(path) * 6) + cur += path_size + + records_offset = get_segment_address(2, cur - start) + for node, offset in records: + rom.write_byte(cur, node) + rom.write_int32(cur + 4, offset) + cur += 8 + + self.file.end = cur + return records_offset + + +class Room(object): + def __init__(self, room): + self.file = File(room['File']) + self.id = room['Id'] + self.objects = [int(x, 16) for x in room['Objects']] + self.actors = [convert_actor_data(x) for x in room['Actors']] + + def write_data(self, rom:Rom): + # move file to remap address + if self.file.remap is not None: + self.file.relocate(rom) + + headcur = self.file.start + + code = rom.read_byte(headcur) + loop = 0x20 + while loop != 0 and code != 0x14: #terminator + loop -= 1 + + if code == 0x01: # actors + offset = self.file.end - self.file.start + write_actor_data(rom, self.file.end, self.actors) + self.file.end += len(self.actors) * 0x10 + + rom.write_byte(headcur + 1, len(self.actors)) + rom.write_int32(headcur + 4, get_segment_address(3, offset)) + + elif code == 0x0B: # objects + offset = self.append_object_data(rom, self.objects) + + rom.write_byte(headcur + 1, len(self.objects)) + rom.write_int32(headcur + 4, get_segment_address(3, offset)) + + headcur += 8 + code = rom.read_byte(headcur) + + # update file reference + self.file.end = align16(self.file.end) + update_dmadata(rom, self.file) + + + def append_object_data(self, rom:Rom, objects): + offset = self.file.end - self.file.start + cur = self.file.end + rom.write_int16s(cur, objects) + + objects_size = align4(len(objects) * 2) + self.file.end += objects_size + return offset + + +def patch_files(rom:Rom, mq_scenes:list): + + data = get_json() + scenes = [Scene(x) for x in data] + for scene in scenes: + if scene.id in mq_scenes: + if scene.id == 9: + patch_ice_cavern_scene_header(rom) + scene.write_data(rom) + + + +def get_json(): + with open(data_path('mqu.json'), 'r') as stream: + data = json.load(stream) + return data + + +def convert_actor_data(str): + spawn_args = str.split(" ") + return [ int(x,16) for x in spawn_args ] + + +def get_segment_address(base, offset): + offset &= 0xFFFFFF + base *= 0x01000000 + return base + offset + + +def patch_ice_cavern_scene_header(rom): + rom.buffer[0x2BEB000:0x2BEB038] = rom.buffer[0x2BEB008:0x2BEB040] + rom.write_int32s(0x2BEB038, [0x0D000000, 0x02000000]) + + +def patch_spirit_temple_mq_room_6(rom:Rom, room_addr): + cur = room_addr + + actor_list_addr = 0 + cmd_actors_offset = 0 + + # scan for actor list and header end + code = rom.read_byte(cur) + while code != 0x14: #terminator + if code == 0x01: # actors + actor_list_addr = rom.read_int32(cur + 4) + cmd_actors_offset = cur - room_addr + + cur += 8 + code = rom.read_byte(cur) + + cur += 8 + + # original header size + header_size = cur - room_addr + + # set alternate header data location + alt_data_off = header_size + 8 + + # set new alternate header offset + alt_header_off = align16(alt_data_off + (4 * 3)) # alt header record size * num records + + # write alternate header data + # the first 3 words are mandatory. the last 3 are just to make the binary + # cleaner to read + rom.write_int32s(room_addr + alt_data_off, + [0, get_segment_address(3, alt_header_off), 0, 0, 0, 0]) + + # clone header + a_start = room_addr + a_end = a_start + header_size + b_start = room_addr + alt_header_off + b_end = b_start + header_size + + rom.buffer[b_start:b_end] = rom.buffer[a_start:a_end] + + # make the child header skip the first actor, + # which avoids the spawning of the block while in the hole + cmd_addr = room_addr + cmd_actors_offset + actor_list_addr += 0x10 + actors = rom.read_byte(cmd_addr + 1) + rom.write_byte(cmd_addr+1, actors - 1) + rom.write_int32(cmd_addr + 4, actor_list_addr) + + # move header + rom.buffer[a_start + 8:a_end + 8] = rom.buffer[a_start:a_end] + + # write alternate header command + seg = get_segment_address(3, alt_data_off) + rom.write_int32s(room_addr, [0x18000000, seg]) + + +def verify_remap(scenes): + def test_remap(file:File): + if file.remap is not None: + if file.start < file.remap: + return False + return True + print("test code: verify remap won't corrupt data") + + for scene in scenes: + file = scene.file + result = test_remap(file) + print("{0} - {1}".format(result, file)) + + for room in scene.rooms: + file = room.file + result = test_remap(file) + print("{0} - {1}".format(result, file)) + + +def update_dmadata(rom:Rom, file:File): + key, start, end, from_file = file.dma_key, file.start, file.end, file.from_file + rom.update_dmadata_record(key, start, end, from_file) + file.dma_key = file.start + +def update_scene_table(rom:Rom, sceneId, start, end): + cur = sceneId * 0x14 + SCENE_TABLE + rom.write_int32s(cur, [start, end]) + + +def write_actor_data(rom:Rom, cur, actors): + for actor in actors: + rom.write_int16s(cur, actor) + cur += 0x10 + +def align4(value): + return ((value + 3) // 4) * 4 + +def align16(value): + return ((value + 0xF) // 0x10) * 0x10 + +# This function inserts space in a ovl section at the section's offset +# The section size is expanded +# Every relocation entry in the section after the offet is moved accordingly +# Every relocation value that is after the inserted space is increased accordingly +def insert_space(rom, file, vram_start, insert_section, insert_offset, insert_size): + sections = [] + val_hi = {} + adr_hi = {} + + # get the ovl header + cur = file.end - rom.read_int32(file.end - 4) + section_total = 0 + for i in range(0, 4): + # build the section offsets + section_size = rom.read_int32(cur) + sections.append(section_total) + section_total += section_size + + # increase the section to be expanded + if insert_section == i: + rom.write_int32(cur, section_size + insert_size) + + cur += 4 + + # calculate the insert address in vram + insert_vram = sections[insert_section] + insert_offset + vram_start + insert_rom = sections[insert_section] + insert_offset + file.start + + # iterate over the relocation table + relocate_count = rom.read_int32(cur) + cur += 4 + for i in range(0, relocate_count): + entry = rom.read_int32(cur) + + # parse relocation entry + section = ((entry & 0xC0000000) >> 30) - 1 + type = (entry & 0x3F000000) >> 24 + offset = entry & 0x00FFFFFF + + # calculate relocation address in rom + address = file.start + sections[section] + offset + + # move relocation if section is increased and it's after the insert + if insert_section == section and offset >= insert_offset: + # rebuild new relocation entry + rom.write_int32(cur, + ((section + 1) << 30) | + (type << 24) | + (offset + insert_size)) + + # value contains the vram address + value = rom.read_int32(address) + raw_value = value + if type == 2: + # Data entry: value is the raw vram address + pass + elif type == 4: + # Jump OP: Get the address from a Jump instruction + value = 0x80000000 | (value & 0x03FFFFFF) << 2 + elif type == 5: + # Load High: Upper half of an address load + reg = (value >> 16) & 0x1F + val_hi[reg] = (value & 0x0000FFFF) << 16 + adr_hi[reg] = address + # Do not process, wait until the lower half is read + value = None + elif type == 6: + # Load Low: Lower half of the address load + reg = (value >> 21) & 0x1F + val_low = value & 0x0000FFFF + val_low = unpack('h', pack('H', val_low))[0] + # combine with previous load high + value = val_hi[reg] + val_low + else: + # unknown. OoT does not use any other types + value = None + + # update the vram values if it's been moved + if value != None and value >= insert_vram: + # value = new vram address + new_value = value + insert_size + + if type == 2: + # Data entry: value is the raw vram address + rom.write_int32(address, new_value) + elif type == 4: + # Jump OP: Set the address in the Jump instruction + op = rom.read_int32(address) & 0xFC000000 + new_value = (new_value & 0x0FFFFFFC) >> 2 + new_value = op | new_value + rom.write_int32(address, new_value) + elif type == 6: + # Load Low: Lower half of the address load + op = rom.read_int32(address) & 0xFFFF0000 + new_val_low = new_value & 0x0000FFFF + rom.write_int32(address, op | new_val_low) + + # Load High: Upper half of an address load + op = rom.read_int32(adr_hi[reg]) & 0xFFFF0000 + new_val_hi = (new_value & 0xFFFF0000) >> 16 + if new_val_low >= 0x8000: + # add 1 if the lower part is negative for borrow + new_val_hi += 1 + rom.write_int32(adr_hi[reg], op | new_val_hi) + + cur += 4 + + # Move rom bytes + rom.buffer[(insert_rom + insert_size):(file.end + insert_size)] = rom.buffer[insert_rom:file.end] + rom.buffer[insert_rom:(insert_rom + insert_size)] = [0] * insert_size + file.end += insert_size + + +def add_relocations(rom, file, addresses): + relocations = [] + sections = [] + header_size = rom.read_int32(file.end - 4) + header = file.end - header_size + cur = header + + # read section sizes and build offsets + section_total = 0 + for i in range(0, 4): + section_size = rom.read_int32(cur) + sections.append(section_total) + section_total += section_size + cur += 4 + + # get all entries in relocation table + relocate_count = rom.read_int32(cur) + cur += 4 + for i in range(0, relocate_count): + relocations.append(rom.read_int32(cur)) + cur += 4 + + # create new enties + for address in addresses: + if isinstance(address, tuple): + # if type provided use it + type, address = address + else: + # Otherwise, try to infer type from value + value = rom.read_int32(address) + op = value >> 26 + type = 2 # default: data + if op == 0x02 or op == 0x03: # j or jal + type = 4 + elif op == 0x0F: # lui + type = 5 + elif op == 0x08: # addi + type = 6 + + # Calculate section and offset + address = address - file.start + section = 0 + for section_start in sections: + if address >= section_start: + section += 1 + else: + break + offset = address - sections[section - 1] + + # generate relocation entry + relocations.append((section << 30) + | (type << 24) + | (offset & 0x00FFFFFF)) + + # Rebuild Relocation Table + cur = header + 0x10 + relocations.sort(key = lambda val: val & 0xC0FFFFFF) + rom.write_int32(cur, len(relocations)) + cur += 4 + for relocation in relocations: + rom.write_int32(cur, relocation) + cur += 4 + + # Add padded 0? + rom.write_int32(cur, 0) + cur += 4 + + # Update Header and File size + new_header_size = (cur + 4) - header + rom.write_int32(cur, new_header_size) + file.end += (new_header_size - header_size) diff --git a/worlds/oot/Messages.py b/worlds/oot/Messages.py new file mode 100644 index 00000000..fbd5881e --- /dev/null +++ b/worlds/oot/Messages.py @@ -0,0 +1,995 @@ +# text details: https://wiki.cloudmodding.com/oot/Text_Format + +import random +from .TextBox import line_wrap + +TEXT_START = 0x92D000 +ENG_TEXT_SIZE_LIMIT = 0x39000 +JPN_TEXT_SIZE_LIMIT = 0x3A150 + +JPN_TABLE_START = 0xB808AC +ENG_TABLE_START = 0xB849EC +CREDITS_TABLE_START = 0xB88C0C + +JPN_TABLE_SIZE = ENG_TABLE_START - JPN_TABLE_START +ENG_TABLE_SIZE = CREDITS_TABLE_START - ENG_TABLE_START + +EXTENDED_TABLE_START = JPN_TABLE_START # start writing entries to the jp table instead of english for more space +EXTENDED_TABLE_SIZE = JPN_TABLE_SIZE + ENG_TABLE_SIZE # 0x8360 bytes, 4204 entries + +# name of type, followed by number of additional bytes to read, follwed by a function that prints the code +CONTROL_CODES = { + 0x00: ('pad', 0, lambda _: '' ), + 0x01: ('line-break', 0, lambda _: '\n' ), + 0x02: ('end', 0, lambda _: '' ), + 0x04: ('box-break', 0, lambda _: '\nâ–¼\n' ), + 0x05: ('color', 1, lambda d: '' ), + 0x06: ('gap', 1, lambda d: '<' + str(d) + 'px gap>' ), + 0x07: ('goto', 2, lambda d: '' ), + 0x08: ('instant', 0, lambda _: '' ), + 0x09: ('un-instant', 0, lambda _: '' ), + 0x0A: ('keep-open', 0, lambda _: '' ), + 0x0B: ('event', 0, lambda _: '' ), + 0x0C: ('box-break-delay', 1, lambda d: '\nâ–¼\n' ), + 0x0E: ('fade-out', 1, lambda d: '' ), + 0x0F: ('name', 0, lambda _: '' ), + 0x10: ('ocarina', 0, lambda _: '' ), + 0x12: ('sound', 2, lambda d: '' ), + 0x13: ('icon', 1, lambda d: '' ), + 0x14: ('speed', 1, lambda d: '' ), + 0x15: ('background', 3, lambda d: '' ), + 0x16: ('marathon', 0, lambda _: '' ), + 0x17: ('race', 0, lambda _: '' ), + 0x18: ('points', 0, lambda _: '' ), + 0x19: ('skulltula', 0, lambda _: '' ), + 0x1A: ('unskippable', 0, lambda _: '' ), + 0x1B: ('two-choice', 0, lambda _: '' ), + 0x1C: ('three-choice', 0, lambda _: '' ), + 0x1D: ('fish', 0, lambda _: '' ), + 0x1E: ('high-score', 1, lambda d: '' ), + 0x1F: ('time', 0, lambda _: '' ), +} + +SPECIAL_CHARACTERS = { + 0x80: 'À', + 0x81: 'Ã', + 0x82: 'Â', + 0x83: 'Ä', + 0x84: 'Ç', + 0x85: 'È', + 0x86: 'É', + 0x87: 'Ê', + 0x88: 'Ë', + 0x89: 'Ã', + 0x8A: 'Ô', + 0x8B: 'Ö', + 0x8C: 'Ù', + 0x8D: 'Û', + 0x8E: 'Ü', + 0x8F: 'ß', + 0x90: 'à', + 0x91: 'á', + 0x92: 'â', + 0x93: 'ä', + 0x94: 'ç', + 0x95: 'è', + 0x96: 'é', + 0x97: 'ê', + 0x98: 'ë', + 0x99: 'ï', + 0x9A: 'ô', + 0x9B: 'ö', + 0x9C: 'ù', + 0x9D: 'û', + 0x9E: 'ü', + 0x9F: '[A]', + 0xA0: '[B]', + 0xA1: '[C]', + 0xA2: '[L]', + 0xA3: '[R]', + 0xA4: '[Z]', + 0xA5: '[C Up]', + 0xA6: '[C Down]', + 0xA7: '[C Left]', + 0xA8: '[C Right]', + 0xA9: '[Triangle]', + 0xAA: '[Control Stick]', +} + +UTF8_TO_OOT_SPECIAL = { + (0xc3, 0x80): 0x80, + (0xc3, 0xae): 0x81, + (0xc3, 0x82): 0x82, + (0xc3, 0x84): 0x83, + (0xc3, 0x87): 0x84, + (0xc3, 0x88): 0x85, + (0xc3, 0x89): 0x86, + (0xc3, 0x8a): 0x87, + (0xc3, 0x8b): 0x88, + (0xc3, 0x8f): 0x89, + (0xc3, 0x94): 0x8A, + (0xc3, 0x96): 0x8B, + (0xc3, 0x99): 0x8C, + (0xc3, 0x9b): 0x8D, + (0xc3, 0x9c): 0x8E, + (0xc3, 0x9f): 0x8F, + (0xc3, 0xa0): 0x90, + (0xc3, 0xa1): 0x91, + (0xc3, 0xa2): 0x92, + (0xc3, 0xa4): 0x93, + (0xc3, 0xa7): 0x94, + (0xc3, 0xa8): 0x95, + (0xc3, 0xa9): 0x96, + (0xc3, 0xaa): 0x97, + (0xc3, 0xab): 0x98, + (0xc3, 0xaf): 0x99, + (0xc3, 0xb4): 0x9A, + (0xc3, 0xb6): 0x9B, + (0xc3, 0xb9): 0x9C, + (0xc3, 0xbb): 0x9D, + (0xc3, 0xbc): 0x9E, +} + +GOSSIP_STONE_MESSAGES = list( range(0x0401, 0x04FF) ) # ids of the actual hints +GOSSIP_STONE_MESSAGES += [0x2053, 0x2054] # shared initial stone messages +TEMPLE_HINTS_MESSAGES = [0x7057, 0x707A] # dungeon reward hints from the temple of time pedestal +LIGHT_ARROW_HINT = [0x70CC] # ganondorf's light arrow hint line +GS_TOKEN_MESSAGES = [0x00B4, 0x00B5] # Get Gold Skulltula Token messages +ERROR_MESSAGE = 0x0001 + +# messages for shorter item messages +# ids are in the space freed up by move_shop_item_messages() +ITEM_MESSAGES = { + 0x0001: "\x08\x06\x30\x05\x41TEXT ID ERROR!\x05\x40", + 0x9001: "\x08\x13\x2DYou borrowed a \x05\x41Pocket Egg\x05\x40!\x01A Pocket Cucco will hatch from\x01it overnight. Be sure to give it\x01back.", + 0x0002: "\x08\x13\x2FYou returned the Pocket Cucco\x01and got \x05\x41Cojiro\x05\x40 in return!\x01Unlike other Cuccos, Cojiro\x01rarely crows.", + 0x0003: "\x08\x13\x30You got an \x05\x41Odd Mushroom\x05\x40!\x01It is sure to spoil quickly! Take\x01it to the Kakariko Potion Shop.", + 0x0004: "\x08\x13\x31You received an \x05\x41Odd Potion\x05\x40!\x01It may be useful for something...\x01Hurry to the Lost Woods!", + 0x0005: "\x08\x13\x32You returned the Odd Potion \x01and got the \x05\x41Poacher's Saw\x05\x40!\x01The young punk guy must have\x01left this.", + 0x0007: "\x08\x13\x48You got a \x01\x05\x41Deku Seeds Bullet Bag\x05\x40.\x01This bag can hold up to \x05\x4640\x05\x40\x01slingshot bullets.", + 0x0008: "\x08\x13\x33You traded the Poacher's Saw \x01for a \x05\x41Broken Goron's Sword\x05\x40!\x01Visit Biggoron to get it repaired!", + 0x0009: "\x08\x13\x34You checked in the Broken \x01Goron's Sword and received a \x01\x05\x41Prescription\x05\x40!\x01Go see King Zora!", + 0x000A: "\x08\x13\x37The Biggoron's Sword...\x01You got a \x05\x41Claim Check \x05\x40for it!\x01You can't wait for the sword!", + 0x000B: "\x08\x13\x2EYou got a \x05\x41Pocket Cucco, \x05\x40one\x01of Anju's prized hens! It fits \x01in your pocket.", + 0x000C: "\x08\x13\x3DYou got the \x05\x41Biggoron's Sword\x05\x40!\x01This blade was forged by a \x01master smith and won't break!", + 0x000D: "\x08\x13\x35You used the Prescription and\x01received an \x05\x41Eyeball Frog\x05\x40!\x01Be quick and deliver it to Lake \x01Hylia!", + 0x000E: "\x08\x13\x36You traded the Eyeball Frog \x01for the \x05\x41World's Finest Eye Drops\x05\x40!\x01Hurry! Take them to Biggoron!", + 0x0010: "\x08\x13\x25You borrowed a \x05\x41Skull Mask\x05\x40.\x01You feel like a monster while you\x01wear this mask!", + 0x0011: "\x08\x13\x26You borrowed a \x05\x41Spooky Mask\x05\x40.\x01You can scare many people\x01with this mask!", + 0x0012: "\x08\x13\x24You borrowed a \x05\x41Keaton Mask\x05\x40.\x01You'll be a popular guy with\x01this mask on!", + 0x0013: "\x08\x13\x27You borrowed a \x05\x41Bunny Hood\x05\x40.\x01The hood's long ears are so\x01cute!", + 0x0014: "\x08\x13\x28You borrowed a \x05\x41Goron Mask\x05\x40.\x01It will make your head look\x01big, though.", + 0x0015: "\x08\x13\x29You borrowed a \x05\x41Zora Mask\x05\x40.\x01With this mask, you can\x01become one of the Zoras!", + 0x0016: "\x08\x13\x2AYou borrowed a \x05\x41Gerudo Mask\x05\x40.\x01This mask will make you look\x01like...a girl?", + 0x0017: "\x08\x13\x2BYou borrowed a \x05\x41Mask of Truth\x05\x40.\x01Show it to many people!", + 0x0030: "\x08\x13\x06You found the \x05\x41Fairy Slingshot\x05\x40!", + 0x0031: "\x08\x13\x03You found the \x05\x41Fairy Bow\x05\x40!", + 0x0032: "\x08\x13\x02You got \x05\x41Bombs\x05\x40!\x01If you see something\x01suspicious, bomb it!", + 0x0033: "\x08\x13\x09You got \x05\x41Bombchus\x05\x40!", + 0x0034: "\x08\x13\x01You got a \x05\x41Deku Nut\x05\x40!", + 0x0035: "\x08\x13\x0EYou found the \x05\x41Boomerang\x05\x40!", + 0x0036: "\x08\x13\x0AYou found the \x05\x41Hookshot\x05\x40!\x01It's a spring-loaded chain that\x01you can cast out to hook things.", + 0x0037: "\x08\x13\x00You got a \x05\x41Deku Stick\x05\x40!", + 0x0038: "\x08\x13\x11You found the \x05\x41Megaton Hammer\x05\x40!\x01It's so heavy, you need to\x01use two hands to swing it!", + 0x0039: "\x08\x13\x0FYou found the \x05\x41Lens of Truth\x05\x40!\x01Mysterious things are hidden\x01everywhere!", + 0x003A: "\x08\x13\x08You found the \x05\x41Ocarina of Time\x05\x40!\x01It glows with a mystical light...", + 0x003C: "\x08\x13\x67You received the \x05\x41Fire\x01Medallion\x05\x40!\x01Darunia awakens as a Sage and\x01adds his power to yours!", + 0x003D: "\x08\x13\x68You received the \x05\x43Water\x01Medallion\x05\x40!\x01Ruto awakens as a Sage and\x01adds her power to yours!", + 0x003E: "\x08\x13\x66You received the \x05\x42Forest\x01Medallion\x05\x40!\x01Saria awakens as a Sage and\x01adds her power to yours!", + 0x003F: "\x08\x13\x69You received the \x05\x46Spirit\x01Medallion\x05\x40!\x01Nabooru awakens as a Sage and\x01adds her power to yours!", + 0x0040: "\x08\x13\x6BYou received the \x05\x44Light\x01Medallion\x05\x40!\x01Rauru the Sage adds his power\x01to yours!", + 0x0041: "\x08\x13\x6AYou received the \x05\x45Shadow\x01Medallion\x05\x40!\x01Impa awakens as a Sage and\x01adds her power to yours!", + 0x0042: "\x08\x13\x14You got an \x05\x41Empty Bottle\x05\x40!\x01You can put something in this\x01bottle.", + 0x0043: "\x08\x13\x15You got a \x05\x41Red Potion\x05\x40!\x01It will restore your health", + 0x0044: "\x08\x13\x16You got a \x05\x42Green Potion\x05\x40!\x01It will restore your magic.", + 0x0045: "\x08\x13\x17You got a \x05\x43Blue Potion\x05\x40!\x01It will recover your health\x01and magic.", + 0x0046: "\x08\x13\x18You caught a \x05\x41Fairy\x05\x40 in a bottle!\x01It will revive you\x01the moment you run out of life \x01energy.", + 0x0047: "\x08\x13\x19You got a \x05\x41Fish\x05\x40!\x01It looks so fresh and\x01delicious!", + 0x0048: "\x08\x13\x10You got a \x05\x41Magic Bean\x05\x40!\x01Find a suitable spot for a garden\x01and plant it.", + 0x9048: "\x08\x13\x10You got a \x05\x41Pack of Magic Beans\x05\x40!\x01Find suitable spots for a garden\x01and plant them.", + 0x004A: "\x08\x13\x07You received the \x05\x41Fairy Ocarina\x05\x40!\x01This is a memento from Saria.", + 0x004B: "\x08\x13\x3DYou got the \x05\x42Giant's Knife\x05\x40!\x01Hold it with both hands to\x01attack! It's so long, you\x01can't use it with a \x05\x44shield\x05\x40.", + 0x004C: "\x08\x13\x3EYou got a \x05\x44Deku Shield\x05\x40!", + 0x004D: "\x08\x13\x3FYou got a \x05\x44Hylian Shield\x05\x40!", + 0x004E: "\x08\x13\x40You found the \x05\x44Mirror Shield\x05\x40!\x01The shield's polished surface can\x01reflect light or energy.", + 0x004F: "\x08\x13\x0BYou found the \x05\x41Longshot\x05\x40!\x01It's an upgraded Hookshot.\x01It extends \x05\x41twice\x05\x40 as far!", + 0x0050: "\x08\x13\x42You got a \x05\x41Goron Tunic\x05\x40!\x01Going to a hot place? No worry!", + 0x0051: "\x08\x13\x43You got a \x05\x43Zora Tunic\x05\x40!\x01Wear it, and you won't drown\x01underwater.", + 0x0052: "\x08You got a \x05\x42Magic Jar\x05\x40!\x01Your Magic Meter is filled!", + 0x0053: "\x08\x13\x45You got the \x05\x41Iron Boots\x05\x40!\x01So heavy, you can't run.\x01So heavy, you can't float.", + 0x0054: "\x08\x13\x46You got the \x05\x41Hover Boots\x05\x40!\x01With these mysterious boots\x01you can hover above the ground.", + 0x0055: "\x08You got a \x05\x45Recovery Heart\x05\x40!\x01Your life energy is recovered!", + 0x0056: "\x08\x13\x4BYou upgraded your quiver to a\x01\x05\x41Big Quiver\x05\x40!\x01Now you can carry more arrows-\x01\x05\x4640 \x05\x40in total!", + 0x0057: "\x08\x13\x4CYou upgraded your quiver to\x01the \x05\x41Biggest Quiver\x05\x40!\x01Now you can carry to a\x01maximum of \x05\x4650\x05\x40 arrows!", + 0x0058: "\x08\x13\x4DYou found a \x05\x41Bomb Bag\x05\x40!\x01You found \x05\x4120 Bombs\x05\x40 inside!", + 0x0059: "\x08\x13\x4EYou got a \x05\x41Big Bomb Bag\x05\x40!\x01Now you can carry more \x01Bombs, up to a maximum of \x05\x4630\x05\x40!", + 0x005A: "\x08\x13\x4FYou got the \x01\x05\x41Biggest Bomb Bag\x05\x40!\x01Now, you can carry up to \x01\x05\x4640\x05\x40 Bombs!", + 0x005B: "\x08\x13\x51You found the \x05\x43Silver Gauntlets\x05\x40!\x01You feel the power to lift\x01big things with it!", + 0x005C: "\x08\x13\x52You found the \x05\x43Golden Gauntlets\x05\x40!\x01You can feel even more power\x01coursing through your arms!", + 0x005D: "\x08\x13\x1CYou put a \x05\x44Blue Fire\x05\x40\x01into the bottle!\x01This is a cool flame you can\x01use on red ice.", + 0x005E: "\x08\x13\x56You got an \x05\x43Adult's Wallet\x05\x40!\x01Now you can hold\x01up to \x05\x46200\x05\x40 \x05\x46Rupees\x05\x40.", + 0x005F: "\x08\x13\x57You got a \x05\x43Giant's Wallet\x05\x40!\x01Now you can hold\x01up to \x05\x46500\x05\x40 \x05\x46Rupees\x05\x40.", + 0x0060: "\x08\x13\x77You found a \x05\x41Small Key\x05\x40!\x01This key will open a locked \x01door. You can use it only\x01in this dungeon.", + 0x0066: "\x08\x13\x76You found the \x05\x41Dungeon Map\x05\x40!\x01It's the map to this dungeon.", + 0x0067: "\x08\x13\x75You found the \x05\x41Compass\x05\x40!\x01Now you can see the locations\x01of many hidden things in the\x01dungeon!", + 0x0068: "\x08\x13\x6FYou obtained the \x05\x41Stone of Agony\x05\x40!\x01If you equip a \x05\x44Rumble Pak\x05\x40, it\x01will react to nearby...secrets.", + 0x0069: "\x08\x13\x23You received \x05\x41Zelda's Letter\x05\x40!\x01Wow! This letter has Princess\x01Zelda's autograph!", + 0x006C: "\x08\x13\x49Your \x05\x41Deku Seeds Bullet Bag \x01\x05\x40has become bigger!\x01This bag can hold \x05\x4650\x05\x41 \x05\x40bullets!", + 0x006F: "\x08You got a \x05\x42Green Rupee\x05\x40!\x01That's \x05\x42one Rupee\x05\x40!", + 0x0070: "\x08\x13\x04You got the \x05\x41Fire Arrow\x05\x40!\x01If you hit your target,\x01it will catch fire.", + 0x0071: "\x08\x13\x0CYou got the \x05\x43Ice Arrow\x05\x40!\x01If you hit your target,\x01it will freeze.", + 0x0072: "\x08\x13\x12You got the \x05\x44Light Arrow\x05\x40!\x01The light of justice\x01will smite evil!", + 0x0073: "\x08\x06\x28You have learned the\x01\x06\x2F\x05\x42Minuet of Forest\x05\x40!", + 0x0074: "\x08\x06\x28You have learned the\x01\x06\x37\x05\x41Bolero of Fire\x05\x40!", + 0x0075: "\x08\x06\x28You have learned the\x01\x06\x29\x05\x43Serenade of Water\x05\x40!", + 0x0076: "\x08\x06\x28You have learned the\x01\x06\x2D\x05\x46Requiem of Spirit\x05\x40!", + 0x0077: "\x08\x06\x28You have learned the\x01\x06\x28\x05\x45Nocturne of Shadow\x05\x40!", + 0x0078: "\x08\x06\x28You have learned the\x01\x06\x32\x05\x44Prelude of Light\x05\x40!", + 0x0079: "\x08\x13\x50You got the \x05\x41Goron's Bracelet\x05\x40!\x01Now you can pull up Bomb\x01Flowers.", + 0x007A: "\x08\x13\x1DYou put a \x05\x41Bug \x05\x40in the bottle!\x01This kind of bug prefers to\x01live in small holes in the ground.", + 0x007B: "\x08\x13\x70You obtained the \x05\x41Gerudo's \x01Membership Card\x05\x40!\x01You can get into the Gerudo's\x01training ground.", + 0x0080: "\x08\x13\x6CYou got the \x05\x42Kokiri's Emerald\x05\x40!\x01This is the Spiritual Stone of \x01Forest passed down by the\x01Great Deku Tree.", + 0x0081: "\x08\x13\x6DYou obtained the \x05\x41Goron's Ruby\x05\x40!\x01This is the Spiritual Stone of \x01Fire passed down by the Gorons!", + 0x0082: "\x08\x13\x6EYou obtained \x05\x43Zora's Sapphire\x05\x40!\x01This is the Spiritual Stone of\x01Water passed down by the\x01Zoras!", + 0x0090: "\x08\x13\x00Now you can pick up \x01many \x05\x41Deku Sticks\x05\x40!\x01You can carry up to \x05\x4620\x05\x40 of them!", + 0x0091: "\x08\x13\x00You can now pick up \x01even more \x05\x41Deku Sticks\x05\x40!\x01You can carry up to \x05\x4630\x05\x40 of them!", + 0x0097: "\x08\x13\x20You caught a \x05\x41Poe \x05\x40in a bottle!\x01Something good might happen!", + 0x0098: "\x08\x13\x1AYou got \x05\x41Lon Lon Milk\x05\x40!\x01This milk is very nutritious!\x01There are two drinks in it.", + 0x0099: "\x08\x13\x1BYou found \x05\x41Ruto's Letter\x05\x40 in a\x01bottle! Show it to King Zora.", + 0x9099: "\x08\x13\x1BYou found \x05\x41a letter in a bottle\x05\x40!\x01You remove the letter from the\x01bottle, freeing it for other uses.", + 0x009A: "\x08\x13\x21You got a \x05\x41Weird Egg\x05\x40!\x01Feels like there's something\x01moving inside!", + 0x00A4: "\x08\x13\x3BYou got the \x05\x42Kokiri Sword\x05\x40!\x01This is a hidden treasure of\x01the Kokiri.", + 0x00A7: "\x08\x13\x01Now you can carry\x01many \x05\x41Deku Nuts\x05\x40!\x01You can hold up to \x05\x4630\x05\x40 nuts!", + 0x00A8: "\x08\x13\x01You can now carry even\x01more \x05\x41Deku Nuts\x05\x40! You can carry\x01up to \x05\x4640\x05\x41 \x05\x40nuts!", + 0x00AD: "\x08\x13\x05You got \x05\x41Din's Fire\x05\x40!\x01Its fireball engulfs everything!", + 0x00AE: "\x08\x13\x0DYou got \x05\x42Farore's Wind\x05\x40!\x01This is warp magic you can use!", + 0x00AF: "\x08\x13\x13You got \x05\x43Nayru's Love\x05\x40!\x01Cast this to create a powerful\x01protective barrier.", + 0x00B4: "\x08You got a \x05\x41Gold Skulltula Token\x05\x40!\x01You've collected \x05\x41\x19\x05\x40 tokens in total.", + 0x00B5: "\x08You destroyed a \x05\x41Gold Skulltula\x05\x40.\x01You got a token proving you \x01destroyed it!", #Unused + 0x00C2: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Collect four pieces total to get\x01another Heart Container.", + 0x00C3: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01So far, you've collected two \x01pieces.", + 0x00C4: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Now you've collected three \x01pieces!", + 0x00C5: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01You've completed another Heart\x01Container!", + 0x00C6: "\x08\x13\x72You got a \x05\x41Heart Container\x05\x40!\x01Your maximum life energy is \x01increased by one heart.", + 0x00C7: "\x08\x13\x74You got the \x05\x41Boss Key\x05\x40!\x01Now you can get inside the \x01chamber where the Boss lurks.", + 0x9002: "\x08You are a \x05\x43FOOL\x05\x40!", + 0x00CC: "\x08You got a \x05\x43Blue Rupee\x05\x40!\x01That's \x05\x43five Rupees\x05\x40!", + 0x00CD: "\x08\x13\x53You got the \x05\x43Silver Scale\x05\x40!\x01You can dive deeper than you\x01could before.", + 0x00CE: "\x08\x13\x54You got the \x05\x43Golden Scale\x05\x40!\x01Now you can dive much\x01deeper than you could before!", + 0x00D1: "\x08\x06\x14You've learned \x05\x42Saria's Song\x05\x40!", + 0x00D2: "\x08\x06\x11You've learned \x05\x41Epona's Song\x05\x40!", + 0x00D3: "\x08\x06\x0BYou've learned the \x05\x46Sun's Song\x05\x40!", + 0x00D4: "\x08\x06\x15You've learned \x05\x43Zelda's Lullaby\x05\x40!", + 0x00D5: "\x08\x06\x05You've learned the \x05\x44Song of Time\x05\x40!", + 0x00D6: "\x08You've learned the \x05\x45Song of Storms\x05\x40!", + 0x00DC: "\x08\x13\x58You got \x05\x41Deku Seeds\x05\x40!\x01Use these as bullets\x01for your Slingshot.", + 0x00DD: "\x08You mastered the secret sword\x01technique of the \x05\x41Spin Attack\x05\x40!", + 0x00E4: "\x08You can now use \x05\x42Magic\x05\x40!", + 0x00E5: "\x08Your \x05\x44defensive power\x05\x40 is enhanced!", + 0x00E6: "\x08You got a \x05\x46bundle of arrows\x05\x40!", + 0x00E8: "\x08Your magic power has been \x01enhanced! Now you have twice\x01as much \x05\x41Magic Power\x05\x40!", + 0x00E9: "\x08Your defensive power has been \x01enhanced! Damage inflicted by \x01enemies will be \x05\x41reduced by half\x05\x40.", + 0x00F0: "\x08You got a \x05\x41Red Rupee\x05\x40!\x01That's \x05\x41twenty Rupees\x05\x40!", + 0x00F1: "\x08You got a \x05\x45Purple Rupee\x05\x40!\x01That's \x05\x45fifty Rupees\x05\x40!", + 0x00F2: "\x08You got a \x05\x46Huge Rupee\x05\x40!\x01This Rupee is worth a whopping\x01\x05\x46two hundred Rupees\x05\x40!", + 0x00F9: "\x08\x13\x1EYou put a \x05\x41Big Poe \x05\x40in a bottle!\x01Let's sell it at the \x05\x41Ghost Shop\x05\x40!\x01Something good might happen!", + 0x9003: "\x08You found a piece of the \x05\x41Triforce\x05\x40!", +} + +KEYSANITY_MESSAGES = { + 0x001C: "\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09", + 0x0006: "\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09", + 0x001D: "\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09", + 0x001E: "\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09", + 0x002A: "\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09", + 0x0061: "\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for \x05\x41Ganon's Castle\x05\x40!\x09", + 0x0062: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x42Deku Tree\x05\x40!\x09", + 0x0063: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for \x05\x41Dodongo's Cavern\x05\x40!\x09", + 0x0064: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for \x05\x43Jabu Jabu's Belly\x05\x40!\x09", + 0x0065: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09", + 0x007C: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09", + 0x007D: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09", + 0x007E: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09", + 0x007F: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09", + 0x0087: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x44Ice Cavern\x05\x40!\x09", + 0x0088: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x42Deku Tree\x05\x40!\x09", + 0x0089: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for \x05\x41Dodongo's Cavern\x05\x40!\x09", + 0x008A: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for \x05\x43Jabu Jabu's Belly\x05\x40!\x09", + 0x008B: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09", + 0x008C: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09", + 0x008E: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09", + 0x008F: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09", + 0x0092: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x44Ice Cavern\x05\x40!\x09", + 0x0093: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09", + 0x0094: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09", + 0x0095: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09", + 0x009B: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09", + 0x009F: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Gerudo Training\x01Grounds\x05\x40!\x09", + 0x00A0: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Gerudo's Fortress\x05\x40!\x09", + 0x00A1: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for \x05\x41Ganon's Castle\x05\x40!\x09", + 0x00A2: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09", + 0x00A3: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09", + 0x00A5: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09", + 0x00A6: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09", + 0x00A9: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09", +} + +MISC_MESSAGES = { + 0x507B: (bytearray( + b"\x08I tell you, I saw him!\x04" \ + b"\x08I saw the ghostly figure of Damp\x96\x01" \ + b"the gravekeeper sinking into\x01" \ + b"his grave. It looked like he was\x01" \ + b"holding some kind of \x05\x41treasure\x05\x40!\x02" + ), None), + 0x0422: ("They say that once \x05\x41Morpha's Curse\x05\x40\x01is lifted, striking \x05\x42this stone\x05\x40 can\x01shift the tides of \x05\x44Lake Hylia\x05\x40.\x02", 0x23), + 0x401C: ("Please find my dear \05\x41Princess Ruto\x05\x40\x01immediately... Zora!\x12\x68\x7A", 0x23), + 0x9100: ("I am out of goods now.\x01Sorry!\x04The mark that will lead you to\x01the Spirit Temple is the \x05\x41flag on\x01the left \x05\x40outside the shop.\x01Be seeing you!\x02", 0x00) +} + + +# convert byte array to an integer +def bytes_to_int(bytes, signed=False): + return int.from_bytes(bytes, byteorder='big', signed=signed) + + +# convert int to an array of bytes of the given width +def int_to_bytes(num, width, signed=False): + return int.to_bytes(num, width, byteorder='big', signed=signed) + + +def display_code_list(codes): + message = "" + for code in codes: + message += str(code) + return message + + +def parse_control_codes(text): + if isinstance(text, list): + bytes = text + elif isinstance(text, bytearray): + bytes = list(text) + else: + bytes = list(text.encode('utf-8')) + + # Special characters encoded to utf-8 must be re-encoded to OoT's values for them. + # Tuple is used due to utf-8 encoding using two bytes. + i = 0 + while i < len(bytes) - 1: + if (bytes[i], bytes[i+1]) in UTF8_TO_OOT_SPECIAL: + bytes[i] = UTF8_TO_OOT_SPECIAL[(bytes[i], bytes[i+1])] + del bytes[i+1] + i += 1 + + text_codes = [] + index = 0 + while index < len(bytes): + next_char = bytes[index] + data = 0 + index += 1 + if next_char in CONTROL_CODES: + extra_bytes = CONTROL_CODES[next_char][1] + if extra_bytes > 0: + data = bytes_to_int(bytes[index : index + extra_bytes]) + index += extra_bytes + text_code = Text_Code(next_char, data) + text_codes.append(text_code) + if text_code.code == 0x02: # message end code + break + + return text_codes + + +# holds a single character or control code of a string +class Text_Code(): + + def display(self): + if self.code in CONTROL_CODES: + return CONTROL_CODES[self.code][2](self.data) + elif self.code in SPECIAL_CHARACTERS: + return SPECIAL_CHARACTERS[self.code] + elif self.code >= 0x7F: + return '?' + else: + return chr(self.code) + + def get_python_string(self): + if self.code in CONTROL_CODES: + ret = '' + subdata = self.data + for _ in range(0, CONTROL_CODES[self.code][1]): + ret = ('\\x%02X' % (subdata & 0xFF)) + ret + subdata = subdata >> 8 + ret = '\\x%02X' % self.code + ret + return ret + elif self.code in SPECIAL_CHARACTERS: + return '\\x%02X' % self.code + elif self.code >= 0x7F: + return '?' + else: + return chr(self.code) + + def get_string(self): + if self.code in CONTROL_CODES: + ret = '' + subdata = self.data + for _ in range(0, CONTROL_CODES[self.code][1]): + ret = chr(subdata & 0xFF) + ret + subdata = subdata >> 8 + ret = chr(self.code) + ret + return ret + else: + return chr(self.code) + + # writes the code to the given offset, and returns the offset of the next byte + def size(self): + size = 1 + if self.code in CONTROL_CODES: + size += CONTROL_CODES[self.code][1] + return size + + # writes the code to the given offset, and returns the offset of the next byte + def write(self, rom, offset): + rom.write_byte(TEXT_START + offset, self.code) + + extra_bytes = 0 + if self.code in CONTROL_CODES: + extra_bytes = CONTROL_CODES[self.code][1] + bytes_to_write = int_to_bytes(self.data, extra_bytes) + rom.write_bytes(TEXT_START + offset + 1, bytes_to_write) + + return offset + 1 + extra_bytes + + def __init__(self, code, data): + self.code = code + if code in CONTROL_CODES: + self.type = CONTROL_CODES[code][0] + else: + self.type = 'character' + self.data = data + + __str__ = __repr__ = display + +# holds a single message, and all its data +class Message(): + + def display(self): + meta_data = ["#" + str(self.index), + "ID: 0x" + "{:04x}".format(self.id), + "Offset: 0x" + "{:06x}".format(self.offset), + "Length: 0x" + "{:04x}".format(self.unpadded_length) + "/0x" + "{:04x}".format(self.length), + "Box Type: " + str(self.box_type), + "Postion: " + str(self.position)] + return ', '.join(meta_data) + '\n' + self.text + + def get_python_string(self): + ret = '' + for code in self.text_codes: + ret = ret + code.get_python_string() + return ret + + # check if this is an unused message that just contains it's own id as text + def is_id_message(self): + if self.unpadded_length == 5: + for i in range(4): + code = self.text_codes[i].code + if not (code in range(ord('0'),ord('9')+1) or code in range(ord('A'),ord('F')+1) or code in range(ord('a'),ord('f')+1) ): + return False + return True + return False + + + def parse_text(self): + self.text_codes = parse_control_codes(self.raw_text) + + index = 0 + for text_code in self.text_codes: + index += text_code.size() + if text_code.code == 0x02: # message end code + break + if text_code.code == 0x07: # goto + self.has_goto = True + self.ending = text_code + if text_code.code == 0x0A: # keep-open + self.has_keep_open = True + self.ending = text_code + if text_code.code == 0x0B: # event + self.has_event = True + self.ending = text_code + if text_code.code == 0x0E: # fade out + self.has_fade = True + self.ending = text_code + if text_code.code == 0x10: # ocarina + self.has_ocarina = True + self.ending = text_code + if text_code.code == 0x1B: # two choice + self.has_two_choice = True + if text_code.code == 0x1C: # three choice + self.has_three_choice = True + self.text = display_code_list(self.text_codes) + self.unpadded_length = index + + def is_basic(self): + return not (self.has_goto or self.has_keep_open or self.has_event or self.has_fade or self.has_ocarina or self.has_two_choice or self.has_three_choice) + + + # computes the size of a message, including padding + def size(self): + size = 0 + + for code in self.text_codes: + size += code.size() + + size = (size + 3) & -4 # align to nearest 4 bytes + + return size + + # applies whatever transformations we want to the dialogs + def transform(self, replace_ending=False, ending=None, always_allow_skip=True, speed_up_text=True): + + ending_codes = [0x02, 0x07, 0x0A, 0x0B, 0x0E, 0x10] + box_breaks = [0x04, 0x0C] + slows_text = [0x08, 0x09, 0x14] + + text_codes = [] + + # # speed the text + if speed_up_text: + text_codes.append(Text_Code(0x08, 0)) # allow instant + + # write the message + for code in self.text_codes: + # ignore ending codes if it's going to be replaced + if replace_ending and code.code in ending_codes: + pass + # ignore the "make unskippable flag" + elif always_allow_skip and code.code == 0x1A: + pass + # ignore anything that slows down text + elif speed_up_text and code.code in slows_text: + pass + elif speed_up_text and code.code in box_breaks: + # some special cases for text that needs to be on a timer + if (self.id == 0x605A or # twinrova transformation + self.id == 0x706C or # raru ending text + self.id == 0x70DD or # ganondorf ending text + self.id == 0x7070): # zelda ending text + text_codes.append(code) + text_codes.append(Text_Code(0x08, 0)) # allow instant + else: + text_codes.append(Text_Code(0x04, 0)) # un-delayed break + text_codes.append(Text_Code(0x08, 0)) # allow instant + else: + text_codes.append(code) + + if replace_ending: + if ending: + if speed_up_text and ending.code == 0x10: # ocarina + text_codes.append(Text_Code(0x09, 0)) # disallow instant text + text_codes.append(ending) # write special ending + text_codes.append(Text_Code(0x02, 0)) # write end code + + self.text_codes = text_codes + + + # writes a Message back into the rom, using the given index and offset to update the table + # returns the offset of the next message + def write(self, rom, index, offset): + + # construct the table entry + id_bytes = int_to_bytes(self.id, 2) + offset_bytes = int_to_bytes(offset, 3) + entry = id_bytes + bytes([self.opts, 0x00, 0x07]) + offset_bytes + # write it back + entry_offset = EXTENDED_TABLE_START + 8 * index + rom.write_bytes(entry_offset, entry) + + for code in self.text_codes: + offset = code.write(rom, offset) + + while offset % 4 > 0: + offset = Text_Code(0x00, 0).write(rom, offset) # pad to 4 byte align + + return offset + + + def __init__(self, raw_text, index, id, opts, offset, length): + + self.raw_text = raw_text + + self.index = index + self.id = id + self.opts = opts # Textbox type and y position + self.box_type = (self.opts & 0xF0) >> 4 + self.position = (self.opts & 0x0F) + self.offset = offset + self.length = length + + self.has_goto = False + self.has_keep_open = False + self.has_event = False + self.has_fade = False + self.has_ocarina = False + self.has_two_choice = False + self.has_three_choice = False + self.ending = None + + self.parse_text() + + # read a single message from rom + @classmethod + def from_rom(cls, rom, index): + + entry_offset = ENG_TABLE_START + 8 * index + entry = rom.read_bytes(entry_offset, 8) + next = rom.read_bytes(entry_offset + 8, 8) + + id = bytes_to_int(entry[0:2]) + opts = entry[2] + offset = bytes_to_int(entry[5:8]) + length = bytes_to_int(next[5:8]) - offset + + raw_text = rom.read_bytes(TEXT_START + offset, length) + + return cls(raw_text, index, id, opts, offset, length) + + @classmethod + def from_string(cls, text, id=0, opts=0x00): + bytes = list(text.encode('utf-8')) + [0x02] + + # Clean up garbage values added when encoding special characters again. + bytes = list(filter(lambda a: a != 194, bytes)) # 0xC2 added before each accent char. + i = 0 + while i < len(bytes) - 1: + if bytes[i] in SPECIAL_CHARACTERS and bytes[i] not in UTF8_TO_OOT_SPECIAL.values(): # This indicates it's one of the button chars (A button, etc). + # Have to delete 2 inserted garbage values. + del bytes[i-1] + del bytes[i-2] + i -= 2 + i+= 1 + + return cls(bytes, 0, id, opts, 0, len(bytes) + 1) + + @classmethod + def from_bytearray(cls, bytearray, id=0, opts=0x00): + bytes = list(bytearray) + [0x02] + + return cls(bytes, 0, id, opts, 0, len(bytes) + 1) + + __str__ = __repr__ = display + +# wrapper for updating the text of a message, given its message id +# if the id does not exist in the list, then it will add it +def update_message_by_id(messages, id, text, opts=None): + # get the message index + index = next( (m.index for m in messages if m.id == id), -1) + # update if it was found + if index >= 0: + update_message_by_index(messages, index, text, opts) + else: + add_message(messages, text, id, opts) + +# Gets the message by its ID. Returns None if the index does not exist +def get_message_by_id(messages, id): + # get the message index + index = next( (m.index for m in messages if m.id == id), -1) + if index >= 0: + return messages[index] + else: + return None + +# wrapper for updating the text of a message, given its index in the list +def update_message_by_index(messages, index, text, opts=None): + if opts is None: + opts = messages[index].opts + + if isinstance(text, bytearray): + messages[index] = Message.from_bytearray(text, messages[index].id, opts) + else: + messages[index] = Message.from_string(text, messages[index].id, opts) + messages[index].index = index + +# wrapper for adding a string message to a list of messages +def add_message(messages, text, id=0, opts=0x00): + if isinstance(text, bytearray): + messages.append( Message.from_bytearray(text, id, opts) ) + else: + messages.append( Message.from_string(text, id, opts) ) + messages[-1].index = len(messages) - 1 + +# holds a row in the shop item table (which contains pointers to the description and purchase messages) +class Shop_Item(): + + def display(self): + meta_data = ["#" + str(self.index), + "Item: 0x" + "{:04x}".format(self.get_item_id), + "Price: " + str(self.price), + "Amount: " + str(self.pieces), + "Object: 0x" + "{:04x}".format(self.object), + "Model: 0x" + "{:04x}".format(self.model), + "Description: 0x" + "{:04x}".format(self.description_message), + "Purchase: 0x" + "{:04x}".format(self.purchase_message),] + func_data = [ + "func1: 0x" + "{:08x}".format(self.func1), + "func2: 0x" + "{:08x}".format(self.func2), + "func3: 0x" + "{:08x}".format(self.func3), + "func4: 0x" + "{:08x}".format(self.func4),] + return ', '.join(meta_data) + '\n' + ', '.join(func_data) + + # write the shop item back + def write(self, rom, shop_table_address, index): + + entry_offset = shop_table_address + 0x20 * index + + bytes = [] + bytes += int_to_bytes(self.object, 2) + bytes += int_to_bytes(self.model, 2) + bytes += int_to_bytes(self.func1, 4) + bytes += int_to_bytes(self.price, 2, signed=True) + bytes += int_to_bytes(self.pieces, 2) + bytes += int_to_bytes(self.description_message, 2) + bytes += int_to_bytes(self.purchase_message, 2) + bytes += [0x00, 0x00] + bytes += int_to_bytes(self.get_item_id, 2) + bytes += int_to_bytes(self.func2, 4) + bytes += int_to_bytes(self.func3, 4) + bytes += int_to_bytes(self.func4, 4) + + rom.write_bytes(entry_offset, bytes) + + # read a single message + def __init__(self, rom, shop_table_address, index): + + entry_offset = shop_table_address + 0x20 * index + entry = rom.read_bytes(entry_offset, 0x20) + + self.index = index + self.object = bytes_to_int(entry[0x00:0x02]) + self.model = bytes_to_int(entry[0x02:0x04]) + self.func1 = bytes_to_int(entry[0x04:0x08]) + self.price = bytes_to_int(entry[0x08:0x0A]) + self.pieces = bytes_to_int(entry[0x0A:0x0C]) + self.description_message = bytes_to_int(entry[0x0C:0x0E]) + self.purchase_message = bytes_to_int(entry[0x0E:0x10]) + # 0x10-0x11 is always 0000 padded apparently + self.get_item_id = bytes_to_int(entry[0x12:0x14]) + self.func2 = bytes_to_int(entry[0x14:0x18]) + self.func3 = bytes_to_int(entry[0x18:0x1C]) + self.func4 = bytes_to_int(entry[0x1C:0x20]) + + __str__ = __repr__ = display + +# reads each of the shop items +def read_shop_items(rom, shop_table_address): + shop_items = [] + + for index in range(0, 100): + shop_items.append( Shop_Item(rom, shop_table_address, index) ) + + return shop_items + +# writes each of the shop item back into rom +def write_shop_items(rom, shop_table_address, shop_items): + for s in shop_items: + s.write(rom, shop_table_address, s.index) + +# these are unused shop items, and contain text ids that are used elsewhere, and should not be moved +SHOP_ITEM_EXCEPTIONS = [0x0A, 0x0B, 0x11, 0x12, 0x13, 0x14, 0x29] + +# returns a set of all message ids used for shop items +def get_shop_message_id_set(shop_items): + ids = set() + for shop in shop_items: + if shop.index not in SHOP_ITEM_EXCEPTIONS: + ids.add(shop.description_message) + ids.add(shop.purchase_message) + return ids + +# remove all messages that easy to tell are unused to create space in the message index table +def remove_unused_messages(messages): + messages[:] = [m for m in messages if not m.is_id_message()] + for index, m in enumerate(messages): + m.index = index + +# takes all messages used for shop items, and moves messages from the 00xx range into the unused 80xx range +def move_shop_item_messages(messages, shop_items): + # checks if a message id is in the item message range + def is_in_item_range(id): + bytes = int_to_bytes(id, 2) + return bytes[0] == 0x00 + # get the ids we want to move + ids = set( id for id in get_shop_message_id_set(shop_items) if is_in_item_range(id) ) + # update them in the message list + for id in ids: + # should be a singleton list, but in case something funky is going on, handle it as a list regardless + relevant_messages = [message for message in messages if message.id == id] + if len(relevant_messages) >= 2: + raise(TypeError("duplicate id in move_shop_item_messages")) + + for message in relevant_messages: + message.id |= 0x8000 + # update them in the shop item list + for shop in shop_items: + if is_in_item_range(shop.description_message): + shop.description_message |= 0x8000 + if is_in_item_range(shop.purchase_message): + shop.purchase_message |= 0x8000 + +def make_player_message(text): + player_text = '\x05\x42\x0F\x05\x40' + pronoun_mapping = { + "You have ": player_text + " ", + "You are ": player_text + " is ", + "You've ": player_text + " ", + "Your ": player_text + "'s ", + "You ": player_text + " ", + + "you have ": player_text + " ", + "you are ": player_text + " is ", + "you've ": player_text + " ", + "your ": player_text + "'s ", + "you ": player_text + " ", + } + + verb_mapping = { + 'obtained ': 'got ', + 'received ': 'got ', + 'learned ': 'got ', + 'borrowed ': 'got ', + 'found ': 'got ', + } + + new_text = text + + # Replace the first instance of a 'You' with the player name + lower_text = text.lower() + you_index = lower_text.find('you') + if you_index != -1: + for find_text, replace_text in pronoun_mapping.items(): + # if the index do not match, then it is not the first 'You' + if text.find(find_text) == you_index: + new_text = new_text.replace(find_text, replace_text, 1) + break + + # because names are longer, we shorten the verbs to they fit in the textboxes better + for find_text, replace_text in verb_mapping.items(): + new_text = new_text.replace(find_text, replace_text) + + wrapped_text = line_wrap(new_text, False, False, False) + if wrapped_text != new_text: + new_text = line_wrap(new_text, True, True, False) + + return new_text + + +# reduce item message sizes and add new item messages +# make sure to call this AFTER move_shop_item_messages() +def update_item_messages(messages, world): + new_item_messages = {**ITEM_MESSAGES, **KEYSANITY_MESSAGES} + for id, text in new_item_messages.items(): + if len(world.world.worlds) > 1: + update_message_by_id(messages, id, make_player_message(text), 0x23) + else: + update_message_by_id(messages, id, text, 0x23) + + for id, (text, opt) in MISC_MESSAGES.items(): + update_message_by_id(messages, id, text, opt) + + +# run all keysanity related patching to add messages for dungeon specific items +def add_item_messages(messages, shop_items, world): + move_shop_item_messages(messages, shop_items) + update_item_messages(messages, world) + + +# reads each of the game's messages into a list of Message objects +def read_messages(rom): + table_offset = ENG_TABLE_START + index = 0 + messages = [] + while True: + entry = rom.read_bytes(table_offset, 8) + id = bytes_to_int(entry[0:2]) + + if id == 0xFFFD: + table_offset += 8 + continue # this is only here to give an ending offset + if id == 0xFFFF: + break # this marks the end of the table + + messages.append( Message.from_rom(rom, index) ) + + index += 1 + table_offset += 8 + + return messages + +# write the messages back +def repack_messages(rom, messages, permutation=None, always_allow_skip=True, speed_up_text=True): + + rom.update_dmadata_record(TEXT_START, TEXT_START, TEXT_START + ENG_TEXT_SIZE_LIMIT) + + if permutation is None: + permutation = range(len(messages)) + + # repack messages + offset = 0 + text_size_limit = ENG_TEXT_SIZE_LIMIT + + for old_index, new_index in enumerate(permutation): + old_message = messages[old_index] + new_message = messages[new_index] + remember_id = new_message.id + new_message.id = old_message.id + + # modify message, making it represent how we want it to be written + new_message.transform(True, old_message.ending, always_allow_skip, speed_up_text) + + # actually write the message + offset = new_message.write(rom, old_index, offset) + + new_message.id = remember_id + + # raise an exception if too much is written + # we raise it at the end so that we know how much overflow there is + if offset > text_size_limit: + raise(TypeError("Message Text table is too large: 0x" + "{:x}".format(offset) + " written / 0x" + "{:x}".format(ENG_TEXT_SIZE_LIMIT) + " allowed.")) + + # end the table + table_index = len(messages) + entry = bytes([0xFF, 0xFD, 0x00, 0x00, 0x07]) + int_to_bytes(offset, 3) + entry_offset = EXTENDED_TABLE_START + 8 * table_index + rom.write_bytes(entry_offset, entry) + table_index += 1 + entry_offset = EXTENDED_TABLE_START + 8 * table_index + if 8 * (table_index + 1) > EXTENDED_TABLE_SIZE: + raise(TypeError("Message ID table is too large: 0x" + "{:x}".format(8 * (table_index + 1)) + " written / 0x" + "{:x}".format(EXTENDED_TABLE_SIZE) + " allowed.")) + rom.write_bytes(entry_offset, [0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + +# shuffles the messages in the game, making sure to keep various message types in their own group +def shuffle_messages(messages, except_hints=True, always_allow_skip=True): + + permutation = [i for i, _ in enumerate(messages)] + + def is_exempt(m): + hint_ids = ( + GOSSIP_STONE_MESSAGES + TEMPLE_HINTS_MESSAGES + LIGHT_ARROW_HINT + + list(KEYSANITY_MESSAGES.keys()) + shuffle_messages.shop_item_messages + + shuffle_messages.scrubs_message_ids + + [0x5036, 0x70F5] # Chicken count and poe count respectively + ) + shuffle_exempt = [ + 0x208D, # "One more lap!" for Cow in House race. + ] + is_hint = (except_hints and m.id in hint_ids) + is_error_message = (m.id == ERROR_MESSAGE) + is_shuffle_exempt = (m.id in shuffle_exempt) + return (is_hint or is_error_message or m.is_id_message() or is_shuffle_exempt) + + have_goto = list( filter(lambda m: not is_exempt(m) and m.has_goto, messages) ) + have_keep_open = list( filter(lambda m: not is_exempt(m) and m.has_keep_open, messages) ) + have_event = list( filter(lambda m: not is_exempt(m) and m.has_event, messages) ) + have_fade = list( filter(lambda m: not is_exempt(m) and m.has_fade, messages) ) + have_ocarina = list( filter(lambda m: not is_exempt(m) and m.has_ocarina, messages) ) + have_two_choice = list( filter(lambda m: not is_exempt(m) and m.has_two_choice, messages) ) + have_three_choice = list( filter(lambda m: not is_exempt(m) and m.has_three_choice, messages) ) + basic_messages = list( filter(lambda m: not is_exempt(m) and m.is_basic(), messages) ) + + + def shuffle_group(group): + group_permutation = [i for i, _ in enumerate(group)] + random.shuffle(group_permutation) + + for index_from, index_to in enumerate(group_permutation): + permutation[group[index_to].index] = group[index_from].index + + # need to use 'list' to force 'map' to actually run through + list( map( shuffle_group, [ + have_goto + have_keep_open + have_event + have_fade + basic_messages, + have_ocarina, + have_two_choice, + have_three_choice, + ])) + + return permutation diff --git a/worlds/oot/Music.py b/worlds/oot/Music.py new file mode 100644 index 00000000..6ed1ab54 --- /dev/null +++ b/worlds/oot/Music.py @@ -0,0 +1,484 @@ +#Much of this is heavily inspired from and/or based on az64's / Deathbasket's MM randomizer + +import random +import os +from .Utils import compare_version, data_path + + +# Format: (Title, Sequence ID) +bgm_sequence_ids = [ + ("Hyrule Field", 0x02), + ("Dodongos Cavern", 0x18), + ("Kakariko Adult", 0x19), + ("Battle", 0x1A), + ("Boss Battle", 0x1B), + ("Inside Deku Tree", 0x1C), + ("Market", 0x1D), + ("Title Theme", 0x1E), + ("House", 0x1F), + ("Jabu Jabu", 0x26), + ("Kakariko Child", 0x27), + ("Fairy Fountain", 0x28), + ("Zelda Theme", 0x29), + ("Fire Temple", 0x2A), + ("Forest Temple", 0x2C), + ("Castle Courtyard", 0x2D), + ("Ganondorf Theme", 0x2E), + ("Lon Lon Ranch", 0x2F), + ("Goron City", 0x30), + ("Miniboss Battle", 0x38), + ("Temple of Time", 0x3A), + ("Kokiri Forest", 0x3C), + ("Lost Woods", 0x3E), + ("Spirit Temple", 0x3F), + ("Horse Race", 0x40), + ("Ingo Theme", 0x42), + ("Fairy Flying", 0x4A), + ("Deku Tree", 0x4B), + ("Windmill Hut", 0x4C), + ("Shooting Gallery", 0x4E), + ("Sheik Theme", 0x4F), + ("Zoras Domain", 0x50), + ("Shop", 0x55), + ("Chamber of the Sages", 0x56), + ("Ice Cavern", 0x58), + ("Kaepora Gaebora", 0x5A), + ("Shadow Temple", 0x5B), + ("Water Temple", 0x5C), + ("Gerudo Valley", 0x5F), + ("Potion Shop", 0x60), + ("Kotake and Koume", 0x61), + ("Castle Escape", 0x62), + ("Castle Underground", 0x63), + ("Ganondorf Battle", 0x64), + ("Ganon Battle", 0x65), + ("Fire Boss", 0x6B), + ("Mini-game", 0x6C) +] + +fanfare_sequence_ids = [ + ("Game Over", 0x20), + ("Boss Defeated", 0x21), + ("Item Get", 0x22), + ("Ganondorf Appears", 0x23), + ("Heart Container Get", 0x24), + ("Treasure Chest", 0x2B), + ("Spirit Stone Get", 0x32), + ("Heart Piece Get", 0x39), + ("Escape from Ranch", 0x3B), + ("Learn Song", 0x3D), + ("Epona Race Goal", 0x41), + ("Medallion Get", 0x43), + ("Zelda Turns Around", 0x51), + ("Master Sword", 0x53), + ("Door of Time", 0x59) +] + +ocarina_sequence_ids = [ + ("Prelude of Light", 0x25), + ("Bolero of Fire", 0x33), + ("Minuet of Forest", 0x34), + ("Serenade of Water", 0x35), + ("Requiem of Spirit", 0x36), + ("Nocturne of Shadow", 0x37), + ("Saria's Song", 0x44), + ("Epona's Song", 0x45), + ("Zelda's Lullaby", 0x46), + ("Sun's Song", 0x47), + ("Song of Time", 0x48), + ("Song of Storms", 0x49) +] + +# Represents the information associated with a sequence, aside from the sequence data itself +class TableEntry(object): + def __init__(self, name, cosmetic_name, type = 0x0202, instrument_set = 0x03, replaces = -1, vanilla_id = -1): + self.name = name + self.cosmetic_name = cosmetic_name + self.replaces = replaces + self.vanilla_id = vanilla_id + self.type = type + self.instrument_set = instrument_set + + + def copy(self): + copy = TableEntry(self.name, self.cosmetic_name, self.type, self.instrument_set, self.replaces, self.vanilla_id) + return copy + + +# Represents actual sequence data, along with metadata for the sequence data block +class Sequence(object): + def __init__(self): + self.address = -1 + self.size = -1 + self.data = [] + + +def process_sequences(rom, sequences, target_sequences, disabled_source_sequences, disabled_target_sequences, ids, seq_type = 'bgm'): + # Process vanilla music data + for bgm in ids: + # Get sequence metadata + name = bgm[0] + cosmetic_name = name + type = rom.read_int16(0xB89AE8 + (bgm[1] * 0x10)) + instrument_set = rom.read_byte(0xB89911 + 0xDD + (bgm[1] * 2)) + id = bgm[1] + + # Create new sequences + seq = TableEntry(name, cosmetic_name, type, instrument_set, vanilla_id = id) + target = TableEntry(name, cosmetic_name, type, instrument_set, replaces = id) + + # Special handling for file select/fairy fountain + if seq.vanilla_id != 0x57 and cosmetic_name not in disabled_source_sequences: + sequences.append(seq) + if cosmetic_name not in disabled_target_sequences: + target_sequences.append(target) + + # If present, load the file containing custom music to exclude + try: + with open(os.path.join(data_path(), u'custom_music_exclusion.txt')) as excl_in: + seq_exclusion_list = excl_in.readlines() + seq_exclusion_list = [seq.rstrip() for seq in seq_exclusion_list if seq[0] != '#'] + seq_exclusion_list = [seq for seq in seq_exclusion_list if seq.endswith('.meta')] + except FileNotFoundError: + seq_exclusion_list = [] + + # Process music data in data/Music/ + # Each sequence requires a valid .seq sequence file and a .meta metadata file + # Current .meta format: Cosmetic Name\nInstrument Set\nPool + for dirpath, _, filenames in os.walk(u'./data/Music', followlinks=True): + for fname in filenames: + # Skip if included in exclusion file + if fname in seq_exclusion_list: + continue + + # Find meta file and check if corresponding seq file exists + if fname.endswith('.meta') and os.path.isfile(os.path.join(dirpath, fname.split('.')[0] + '.seq')): + # Read meta info + try: + with open(os.path.join(dirpath, fname), 'r') as stream: + lines = stream.readlines() + # Strip newline(s) + lines = [line.rstrip() for line in lines] + except FileNotFoundError as ex: + raise FileNotFoundError('No meta file for: "' + fname + '". This should never happen') + + # Create new sequence, checking third line for correct type + if (len(lines) > 2 and (lines[2].lower() == seq_type.lower() or lines[2] == '')) or (len(lines) <= 2 and seq_type == 'bgm'): + seq = TableEntry(os.path.join(dirpath, fname.split('.')[0]), lines[0], instrument_set = int(lines[1], 16)) + + if seq.instrument_set < 0x00 or seq.instrument_set > 0x25: + raise Exception('Sequence instrument must be in range [0x00, 0x25]') + + if seq.cosmetic_name not in disabled_source_sequences: + sequences.append(seq) + + return sequences, target_sequences + + +def shuffle_music(sequences, target_sequences, music_mapping, log): + sequence_dict = {} + sequence_ids = [] + + for sequence in sequences: + if sequence.cosmetic_name == "None": + raise Exception('Sequences should not be named "None" as that is used for disabled music. Sequence with improper name: %s' % sequence.name) + if sequence.cosmetic_name in sequence_dict: + raise Exception('Sequence names should be unique. Duplicate sequence name: %s' % sequence.cosmetic_name) + sequence_dict[sequence.cosmetic_name] = sequence + if sequence.cosmetic_name not in music_mapping.values(): + sequence_ids.append(sequence.cosmetic_name) + + # Shuffle the sequences + if len(sequences) < len(target_sequences): + raise Exception(f"Not enough custom music/fanfares ({len(sequences)}) to omit base Ocarina of Time sequences ({len(target_sequences)}).") + random.shuffle(sequence_ids) + + sequences = [] + for target_sequence in target_sequences: + sequence = sequence_dict[sequence_ids.pop()].copy() if target_sequence.cosmetic_name not in music_mapping \ + else ("None", 0x0) if music_mapping[target_sequence.cosmetic_name] == "None" \ + else sequence_dict[music_mapping[target_sequence.cosmetic_name]].copy() + sequences.append(sequence) + sequence.replaces = target_sequence.replaces + log[target_sequence.cosmetic_name] = sequence.cosmetic_name + + return sequences, log + + +def rebuild_sequences(rom, sequences): + # List of sequences (actual sequence data objects) containing the vanilla sequence data + old_sequences = [] + + for i in range(0x6E): + # Create new sequence object, an entry for the audio sequence + entry = Sequence() + # Get the address for the entry's pointer table entry + entry_address = 0xB89AE0 + (i * 0x10) + # Extract the info from the pointer table entry + entry.address = rom.read_int32(entry_address) + entry.size = rom.read_int32(entry_address + 0x04) + + # If size > 0, read the sequence data from the rom into the sequence object + if entry.size > 0: + entry.data = rom.read_bytes(entry.address + 0x029DE0, entry.size) + else: + s = [seq for seq in sequences if seq.replaces == i] + if s != [] and entry.address > 0 and entry.address < 128: + s = s.pop() + if s.replaces != 0x28: + s.replaces = entry.address + else: + # Special handling for file select/fairy fountain + entry.data = old_sequences[0x57].data + entry.size = old_sequences[0x57].size + + old_sequences.append(entry) + + # List of sequences containing the new sequence data + new_sequences = [] + address = 0 + # Byte array to hold the data for the whole audio sequence + new_audio_sequence = [] + + for i in range(0x6E): + new_entry = Sequence() + # If sequence size is 0, the address doesn't matter and it doesn't effect the current address + if old_sequences[i].size == 0: + new_entry.address = old_sequences[i].address + # Continue from the end of the new sequence table + else: + new_entry.address = address + + s = [seq for seq in sequences if seq.replaces == i] + if s != []: + assert len(s) == 1 + s = s.pop() + # If we are using a vanilla sequence, get its data from old_sequences + if s.vanilla_id != -1: + new_entry.size = old_sequences[s.vanilla_id].size + new_entry.data = old_sequences[s.vanilla_id].data + else: + # Read sequence info + try: + with open(s.name + '.seq', 'rb') as stream: + new_entry.data = bytearray(stream.read()) + new_entry.size = len(new_entry.data) + if new_entry.size <= 0x10: + raise Exception('Invalid sequence file "' + s.name + '.seq"') + new_entry.data[1] = 0x20 + except FileNotFoundError as ex: + raise FileNotFoundError('No sequence file for: "' + s.name + '"') + else: + new_entry.size = old_sequences[i].size + new_entry.data = old_sequences[i].data + + new_sequences.append(new_entry) + + # Concatenate the full audio sequence and the new sequence data + if new_entry.data != [] and new_entry.size > 0: + # Align sequences to 0x10 + if new_entry.size % 0x10 != 0: + new_entry.data.extend(bytearray(0x10 - (new_entry.size % 0x10))) + new_entry.size += 0x10 - (new_entry.size % 0x10) + new_audio_sequence.extend(new_entry.data) + # Increment the current address by the size of the new sequence + address += new_entry.size + + # Check if the new audio sequence is larger than the vanilla one + if address > 0x04F690: + # Zero out the old audio sequence + rom.buffer[0x029DE0 : 0x029DE0 + 0x04F690] = [0] * 0x04F690 + + # Append new audio sequence + new_address = rom.free_space() + rom.write_bytes(new_address, new_audio_sequence) + + #Update dmatable + rom.update_dmadata_record(0x029DE0, new_address, new_address + address) + + else: + # Write new audio sequence file + rom.write_bytes(0x029DE0, new_audio_sequence) + + # Update pointer table + for i in range(0x6E): + rom.write_int32(0xB89AE0 + (i * 0x10), new_sequences[i].address) + rom.write_int32(0xB89AE0 + (i * 0x10) + 0x04, new_sequences[i].size) + s = [seq for seq in sequences if seq.replaces == i] + if s != []: + assert len(s) == 1 + s = s.pop() + rom.write_int16(0xB89AE0 + (i * 0x10) + 0x08, s.type) + + # Update instrument sets + for i in range(0x6E): + base = 0xB89911 + 0xDD + (i * 2) + j = -1 + if new_sequences[i].size == 0: + try: + j = [seq for seq in sequences if seq.replaces == new_sequences[i].address].pop() + except: + j = -1 + else: + try: + j = [seq for seq in sequences if seq.replaces == i].pop() + except: + j = -1 + if j != -1: + rom.write_byte(base, j.instrument_set) + + +def shuffle_pointers_table(rom, ids, music_mapping, log): + # Read in all the Music data + bgm_data = {} + bgm_ids = [] + + for bgm in ids: + bgm_sequence = rom.read_bytes(0xB89AE0 + (bgm[1] * 0x10), 0x10) + bgm_instrument = rom.read_int16(0xB89910 + 0xDD + (bgm[1] * 2)) + bgm_data[bgm[0]] = (bgm[0], bgm_sequence, bgm_instrument) + if bgm[0] not in music_mapping.values(): + bgm_ids.append(bgm[0]) + + # shuffle data + random.shuffle(bgm_ids) + + # Write Music data back in random ordering + for bgm in ids: + if bgm[0] in music_mapping and music_mapping[bgm[0]] in bgm_data: + bgm_name = music_mapping[bgm[0]] + else: + bgm_name = bgm_ids.pop() + bgm_name, bgm_sequence, bgm_instrument = bgm_data[bgm_name] + rom.write_bytes(0xB89AE0 + (bgm[1] * 0x10), bgm_sequence) + rom.write_int16(0xB89910 + 0xDD + (bgm[1] * 2), bgm_instrument) + log[bgm[0]] = bgm_name + + # Write Fairy Fountain instrument to File Select (uses same track but different instrument set pointer for some reason) + rom.write_int16(0xB89910 + 0xDD + (0x57 * 2), rom.read_int16(0xB89910 + 0xDD + (0x28 * 2))) + return log + + +def randomize_music(rom, ootworld, music_mapping): + log = {} + errors = [] + sequences = [] + target_sequences = [] + fanfare_sequences = [] + fanfare_target_sequences = [] + disabled_source_sequences = {} + disabled_target_sequences = {} + + # Make sure we aren't operating directly on these. + music_mapping = music_mapping.copy() + bgm_ids = bgm_sequence_ids.copy() + ff_ids = fanfare_sequence_ids.copy() + + # Check if we have mapped music for BGM, Fanfares, or Ocarina Fanfares + bgm_mapped = any(bgm[0] in music_mapping for bgm in bgm_ids) + ff_mapped = any(ff[0] in music_mapping for ff in ff_ids) + ocarina_mapped = any(ocarina[0] in music_mapping for ocarina in ocarina_sequence_ids) + + # Include ocarina songs in fanfare pool if checked + if ootworld.ocarina_fanfares or ocarina_mapped: + ff_ids.extend(ocarina_sequence_ids) + + # Flag sequence locations that are set to off for disabling. + disabled_ids = [] + if ootworld.background_music == 'off': + disabled_ids += [music_id for music_id in bgm_ids] + if ootworld.fanfares == 'off': + disabled_ids += [music_id for music_id in ff_ids] + disabled_ids += [music_id for music_id in ocarina_sequence_ids] + for bgm in [music_id for music_id in bgm_ids + ff_ids + ocarina_sequence_ids]: + if music_mapping.get(bgm[0], '') == "None": + disabled_target_sequences[bgm[0]] = bgm + for bgm in disabled_ids: + if bgm[0] not in music_mapping: + music_mapping[bgm[0]] = "None" + disabled_target_sequences[bgm[0]] = bgm + + # Map music to itself if music is set to normal. + normal_ids = [] + if ootworld.background_music == 'normal' and bgm_mapped: + normal_ids += [music_id for music_id in bgm_ids] + if ootworld.fanfares == 'normal' and (ff_mapped or ocarina_mapped): + normal_ids += [music_id for music_id in ff_ids] + if not ootworld.ocarina_fanfares and ootworld.fanfares == 'normal' and ocarina_mapped: + normal_ids += [music_id for music_id in ocarina_sequence_ids] + for bgm in normal_ids: + if bgm[0] not in music_mapping: + music_mapping[bgm[0]] = bgm[0] + + # If not creating patch file, shuffle audio sequences. Otherwise, shuffle pointer table + # If generating from patch, also do a version check to make sure custom sequences are supported. + # custom_sequences_enabled = ootworld.compress_rom != 'Patch' + # if ootworld.patch_file != '': + # rom_version_bytes = rom.read_bytes(0x35, 3) + # rom_version = f'{rom_version_bytes[0]}.{rom_version_bytes[1]}.{rom_version_bytes[2]}' + # if compare_version(rom_version, '4.11.13') < 0: + # errors.append("Custom music is not supported by this patch version. Only randomizing vanilla music.") + # custom_sequences_enabled = False + # if custom_sequences_enabled: + # if ootworld.background_music in ['random', 'random_custom_only'] or bgm_mapped: + # process_sequences(rom, sequences, target_sequences, disabled_source_sequences, disabled_target_sequences, bgm_ids) + # if ootworld.background_music == 'random_custom_only': + # sequences = [seq for seq in sequences if seq.cosmetic_name not in [x[0] for x in bgm_ids] or seq.cosmetic_name in music_mapping.values()] + # sequences, log = shuffle_music(sequences, target_sequences, music_mapping, log) + + # if ootworld.fanfares in ['random', 'random_custom_only'] or ff_mapped or ocarina_mapped: + # process_sequences(rom, fanfare_sequences, fanfare_target_sequences, disabled_source_sequences, disabled_target_sequences, ff_ids, 'fanfare') + # if ootworld.fanfares == 'random_custom_only': + # fanfare_sequences = [seq for seq in fanfare_sequences if seq.cosmetic_name not in [x[0] for x in fanfare_sequence_ids] or seq.cosmetic_name in music_mapping.values()] + # fanfare_sequences, log = shuffle_music(fanfare_sequences, fanfare_target_sequences, music_mapping, log) + + # if disabled_source_sequences: + # log = disable_music(rom, disabled_source_sequences.values(), log) + + # rebuild_sequences(rom, sequences + fanfare_sequences) + # else: + if ootworld.background_music == 'randomized' or bgm_mapped: + log = shuffle_pointers_table(rom, bgm_ids, music_mapping, log) + + if ootworld.fanfares == 'randomized' or ff_mapped or ocarina_mapped: + log = shuffle_pointers_table(rom, ff_ids, music_mapping, log) + # end_else + if disabled_target_sequences: + log = disable_music(rom, disabled_target_sequences.values(), log) + + return log, errors + + +def disable_music(rom, ids, log): + # First track is no music + blank_track = rom.read_bytes(0xB89AE0 + (0 * 0x10), 0x10) + for bgm in ids: + rom.write_bytes(0xB89AE0 + (bgm[1] * 0x10), blank_track) + log[bgm[0]] = "None" + + return log + + +def restore_music(rom): + # Restore all music from original + for bgm in bgm_sequence_ids + fanfare_sequence_ids + ocarina_sequence_ids: + bgm_sequence = rom.original.read_bytes(0xB89AE0 + (bgm[1] * 0x10), 0x10) + rom.write_bytes(0xB89AE0 + (bgm[1] * 0x10), bgm_sequence) + bgm_instrument = rom.original.read_int16(0xB89910 + 0xDD + (bgm[1] * 2)) + rom.write_int16(0xB89910 + 0xDD + (bgm[1] * 2), bgm_instrument) + + # restore file select instrument + bgm_instrument = rom.original.read_int16(0xB89910 + 0xDD + (0x57 * 2)) + rom.write_int16(0xB89910 + 0xDD + (0x57 * 2), bgm_instrument) + + # Rebuild audioseq + orig_start, orig_end, orig_size = rom.original._get_dmadata_record(0x7470) + rom.write_bytes(orig_start, rom.original.read_bytes(orig_start, orig_size)) + + # If Audioseq was relocated + start, end, size = rom._get_dmadata_record(0x7470) + if start != 0x029DE0: + # Zero out old audioseq + rom.write_bytes(start, [0] * size) + rom.update_dmadata_record(start, orig_start, orig_end) + diff --git a/worlds/oot/N64Patch.py b/worlds/oot/N64Patch.py new file mode 100644 index 00000000..01c8e0f6 --- /dev/null +++ b/worlds/oot/N64Patch.py @@ -0,0 +1,271 @@ +import struct +import random +import io +import array +import zlib +import copy +import zipfile +from .ntype import BigStream + + +# get the next XOR key. Uses some location in the source rom. +# This will skip of 0s, since if we hit a block of 0s, the +# patch data will be raw. +def key_next(rom, key_address, address_range): + key = 0 + while key == 0: + key_address += 1 + if key_address > address_range[1]: + key_address = address_range[0] + key = rom.original.buffer[key_address] + return key, key_address + + +# creates a XOR block for the patch. This might break it up into +# multiple smaller blocks if there is a concern about the XOR key +# or if it is too long. +def write_block(rom, xor_address, xor_range, block_start, data, patch_data): + new_data = [] + key_offset = 0 + continue_block = False + + for b in data: + if b == 0: + # Leave 0s as 0s. Do not XOR + new_data += [0] + else: + # get the next XOR key + key, xor_address = key_next(rom, xor_address, xor_range) + + # if the XOR would result in 0, change the key. + # This requires breaking up the block. + if b == key: + write_block_section(block_start, key_offset, new_data, patch_data, continue_block) + new_data = [] + key_offset = 0 + continue_block = True + + # search for next safe XOR key + while b == key: + key_offset += 1 + key, xor_address = key_next(rom, xor_address, xor_range) + # if we aren't able to find one quickly, we may need to break again + if key_offset == 0xFF: + write_block_section(block_start, key_offset, new_data, patch_data, continue_block) + new_data = [] + key_offset = 0 + continue_block = True + + # XOR the key with the byte + new_data += [b ^ key] + + # Break the block if it's too long + if (len(new_data) == 0xFFFF): + write_block_section(block_start, key_offset, new_data, patch_data, continue_block) + new_data = [] + key_offset = 0 + continue_block = True + + # Save the block + write_block_section(block_start, key_offset, new_data, patch_data, continue_block) + return xor_address + + +# This saves a sub-block for the XOR block. If it's the first part +# then it will include the address to write to. Otherwise it will +# have a number of XOR keys to skip and then continue writing after +# the previous block +def write_block_section(start, key_skip, in_data, patch_data, is_continue): + if not is_continue: + patch_data.append_int32(start) + else: + patch_data.append_bytes([0xFF, key_skip]) + patch_data.append_int16(len(in_data)) + patch_data.append_bytes(in_data) + + +# This will create the patch file. Which can be applied to a source rom. +# xor_range is the range the XOR key will read from. This range is not +# too important, but I tried to choose from a section that didn't really +# have big gaps of 0s which we want to avoid. +def create_patch_file(rom, file, xor_range=(0x00B8AD30, 0x00F029A0)): + dma_start, dma_end = rom.get_dma_table_range() + + # add header + patch_data = BigStream([]) + patch_data.append_bytes(list(map(ord, 'ZPFv1'))) + patch_data.append_int32(dma_start) + patch_data.append_int32(xor_range[0]) + patch_data.append_int32(xor_range[1]) + + # get random xor key. This range is chosen because it generally + # doesn't have many sections of 0s + xor_address = random.Random().randint(*xor_range) + patch_data.append_int32(xor_address) + + new_buffer = copy.copy(rom.original.buffer) + + # write every changed DMA entry + for dma_index, (from_file, start, size) in rom.changed_dma.items(): + patch_data.append_int16(dma_index) + patch_data.append_int32(from_file) + patch_data.append_int32(start) + patch_data.append_int24(size) + + # We don't trust files that have modified DMA to have their + # changed addresses tracked correctly, so we invalidate the + # entire file + for address in range(start, start + size): + rom.changed_address[address] = rom.buffer[address] + + # Simulate moving the files to know which addresses have changed + if from_file >= 0: + old_dma_start, old_dma_end, old_size = rom.original.get_dmadata_record_by_key(from_file) + copy_size = min(size, old_size) + new_buffer[start:start+copy_size] = rom.original.read_bytes(from_file, copy_size) + new_buffer[start+copy_size:start+size] = [0] * (size - copy_size) + else: + # this is a new file, so we just fill with null data + new_buffer[start:start+size] = [0] * size + + # end of DMA entries + patch_data.append_int16(0xFFFF) + + # filter down the addresses that will actually need to change. + # Make sure to not include any of the DMA table addresses + changed_addresses = [address for address,value in rom.changed_address.items() \ + if (address >= dma_end or address < dma_start) and \ + (address in rom.force_patch or new_buffer[address] != value)] + changed_addresses.sort() + + # Write the address changes. We'll store the data with XOR so that + # the patch data won't be raw data from the patched rom. + data = [] + block_start = None + BLOCK_HEADER_SIZE = 7 # this is used to break up gaps + for address in changed_addresses: + # if there's a block to write and there's a gap, write it + if block_start: + block_end = block_start + len(data) - 1 + if address > block_end + BLOCK_HEADER_SIZE: + xor_address = write_block(rom, xor_address, xor_range, block_start, data, patch_data) + data = [] + block_start = None + block_end = None + + # start a new block + if not block_start: + block_start = address + block_end = address - 1 + + # save the new data + data += rom.buffer[block_end+1:address+1] + + # if there was any left over blocks, write them out + if block_start: + xor_address = write_block(rom, xor_address, xor_range, block_start, data, patch_data) + + # compress the patch file + patch_data = bytes(patch_data.buffer) + patch_data = zlib.compress(patch_data) + + # save the patch file + with open(file, 'wb') as outfile: + outfile.write(patch_data) + + +# This will apply a patch file to a source rom to generate a patched rom. +def apply_patch_file(rom, file, sub_file=None): + # load the patch file and decompress + if sub_file: + with zipfile.ZipFile(file, 'r') as patch_archive: + try: + with patch_archive.open(sub_file, 'r') as stream: + patch_data = stream.read() + except KeyError as ex: + raise FileNotFoundError('Patch file missing from archive. Invalid Player ID.') + else: + with open(file, 'rb') as stream: + patch_data = stream.read() + patch_data = BigStream(zlib.decompress(patch_data)) + + # make sure the header is correct + if patch_data.read_bytes(length=4) != b'ZPFv': + raise Exception("File is not in a Zelda Patch Format") + if patch_data.read_byte() != ord('1'): + # in the future we might want to have revisions for this format + raise Exception("Unsupported patch version.") + + # load the patch configuration info. The fact that the DMA Table is + # included in the patch is so that this might be able to work with + # other N64 games. + dma_start = patch_data.read_int32() + xor_range = (patch_data.read_int32(), patch_data.read_int32()) + xor_address = patch_data.read_int32() + + # Load all the DMA table updates. This will move the files around. + # A key thing is that some of these entries will list a source file + # that they are from, so we know where to copy from, no matter where + # in the DMA table this file has been moved to. Also important if a file + # is copied. This list is terminated with 0xFFFF + while True: + # Load DMA update + dma_index = patch_data.read_int16() + if dma_index == 0xFFFF: + break + + from_file = patch_data.read_int32() + start = patch_data.read_int32() + size = patch_data.read_int24() + + # Save new DMA Table entry + dma_entry = dma_start + (dma_index * 0x10) + end = start + size + rom.write_int32(dma_entry, start) + rom.write_int32(None, end) + rom.write_int32(None, start) + rom.write_int32(None, 0) + + if from_file != 0xFFFFFFFF: + # If a source file is listed, copy from there + old_dma_start, old_dma_end, old_size = rom.original.get_dmadata_record_by_key(from_file) + copy_size = min(size, old_size) + rom.write_bytes(start, rom.original.read_bytes(from_file, copy_size)) + rom.buffer[start+copy_size:start+size] = [0] * (size - copy_size) + else: + # if it's a new file, fill with 0s + rom.buffer[start:start+size] = [0] * size + + # Read in the XOR data blocks. This goes to the end of the file. + block_start = None + while not patch_data.eof(): + is_new_block = patch_data.read_byte() != 0xFF + + if is_new_block: + # start writing a new block + patch_data.seek_address(delta=-1) + block_start = patch_data.read_int32() + block_size = patch_data.read_int16() + else: + # continue writing from previous block + key_skip = patch_data.read_byte() + block_size = patch_data.read_int16() + # skip specified XOR keys + for _ in range(key_skip): + key, xor_address = key_next(rom, xor_address, xor_range) + + # read in the new data + data = [] + for b in patch_data.read_bytes(length=block_size): + if b == 0: + # keep 0s as 0s + data += [0] + else: + # The XOR will always be safe and will never produce 0 + key, xor_address = key_next(rom, xor_address, xor_range) + data += [b ^ key] + + # Save the new data to rom + rom.write_bytes(block_start, data) + block_start = block_start+block_size + diff --git a/worlds/oot/Options.py b/worlds/oot/Options.py new file mode 100644 index 00000000..36cf4d80 --- /dev/null +++ b/worlds/oot/Options.py @@ -0,0 +1,782 @@ +import typing +from Options import Option, DefaultOnToggle, Toggle, Choice, Range, OptionList +from .Colors import * +import worlds.oot.Sounds as sfx + + +class Logic(Choice): + """Set the logic used for the generator.""" + displayname = "Logic Rules" + option_glitchless = 0 + option_glitched = 1 + option_no_logic = 2 + + +class NightTokens(Toggle): + """Nighttime skulltulas will logically require Sun's Song.""" + displayname = "Nighttime Skulltulas Expect Sun's Song" + + +class Forest(Choice): + """Set the state of Kokiri Forest and the path to Deku Tree.""" + displayname = "Forest" + option_open = 0 + option_closed_deku = 1 + option_closed = 2 + alias_open_forest = 0 + alias_closed_forest = 2 + + +class Gate(Choice): + """Set the state of the Kakariko Village gate.""" + displayname = "Kakariko Gate" + option_open = 0 + option_zelda = 1 + option_closed = 2 + + +class DoorOfTime(DefaultOnToggle): + """Open the Door of Time by default, without the Song of Time.""" + displayname = "Open Door of Time" + + +class Fountain(Choice): + """Set the state of King Zora, blocking the way to Zora's Fountain.""" + displayname = "Zora's Fountain" + option_open = 0 + option_adult = 1 + option_closed = 2 + default = 2 + + +class Fortress(Choice): + """Set the requirements for access to Gerudo Fortress.""" + displayname = "Gerudo Fortress" + option_normal = 0 + option_fast = 1 + option_open = 2 + default = 1 + + +class Bridge(Choice): + """Set the requirements for the Rainbow Bridge.""" + displayname = "Rainbow Bridge Requirement" + option_open = 0 + option_vanilla = 1 + option_stones = 2 + option_medallions = 3 + option_dungeons = 4 + option_tokens = 5 + default = 3 + + +class Trials(Range): + """Set the number of required trials in Ganon's Castle.""" + displayname = "Ganon's Trials Count" + range_start = 0 + range_end = 6 + + +open_options: typing.Dict[str, type(Option)] = { + "open_forest": Forest, + "open_kakariko": Gate, + "open_door_of_time": DoorOfTime, + "zora_fountain": Fountain, + "gerudo_fortress": Fortress, + "bridge": Bridge, + "trials": Trials, +} + + +class StartingAge(Choice): + """Choose which age Link will start as.""" + displayname = "Starting Age" + option_child = 0 + option_adult = 1 + + +# TODO: document and name ER options +class InteriorEntrances(Choice): + option_off = 0 + option_simple = 1 + option_all = 2 + alias_false = 0 + + +class TriforceHunt(Toggle): + """Gather pieces of the Triforce scattered around the world to complete the game.""" + displayname = "Triforce Hunt" + + +class TriforceGoal(Range): + """Number of Triforce pieces required to complete the game. Total number placed determined by the Item Pool setting.""" + displayname = "Required Triforce Pieces" + range_start = 1 + range_end = 50 + default = 20 + + +class LogicalChus(Toggle): + """Bombchus are properly considered in logic. The first found pack will have 20 chus; Kokiri Shop and Bazaar sell refills; bombchus open Bombchu Bowling.""" + displayname = "Bombchus Considered in Logic" + + +world_options: typing.Dict[str, type(Option)] = { + "starting_age": StartingAge, + # "shuffle_interior_entrances": InteriorEntrances, + # "shuffle_grotto_entrances": Toggle, + # "shuffle_dungeon_entrances": Toggle, + # "shuffle_overworld_entrances": Toggle, + # "owl_drops": Toggle, + # "warp_songs": Toggle, + # "spawn_positions": Toggle, + "triforce_hunt": TriforceHunt, + "triforce_goal": TriforceGoal, + "bombchus_in_logic": LogicalChus, + # "mq_dungeons": make_range(0, 12), +} + + +class LacsCondition(Choice): + """Set the requirements for the Light Arrow Cutscene in the Temple of Time.""" + displayname = "Light Arrow Cutscene Requirement" + option_vanilla = 0 + option_stones = 1 + option_medallions = 2 + option_dungeons = 3 + option_tokens = 4 + + +class LacsStones(Range): + """Set the number of Spiritual Stones required for LACS.""" + displayname = "Spiritual Stones Required for LACS" + range_start = 0 + range_end = 3 + default = 3 + + +class LacsMedallions(Range): + """Set the number of medallions required for LACS.""" + displayname = "Medallions Required for LACS" + range_start = 0 + range_end = 6 + default = 6 + + +class LacsRewards(Range): + """Set the number of dungeon rewards required for LACS.""" + displayname = "Dungeon Rewards Required for LACS" + range_start = 0 + range_end = 9 + default = 9 + + +class LacsTokens(Range): + """Set the number of Gold Skulltula Tokens required for LACS.""" + displayname = "Tokens Required for LACS" + range_start = 0 + range_end = 100 + default = 100 + + +lacs_options: typing.Dict[str, type(Option)] = { + "lacs_condition": LacsCondition, + "lacs_stones": LacsStones, + "lacs_medallions": LacsMedallions, + "lacs_rewards": LacsRewards, + "lacs_tokens": LacsTokens, +} + + +class BridgeStones(Range): + """Set the number of Spiritual Stones required for the rainbow bridge.""" + displayname = "Spiritual Stones Required for Bridge" + range_start = 0 + range_end = 3 + default = 3 + + +class BridgeMedallions(Range): + """Set the number of medallions required for the rainbow bridge.""" + displayname = "Medallions Required for Bridge" + range_start = 0 + range_end = 6 + default = 6 + + +class BridgeRewards(Range): + """Set the number of dungeon rewards required for the rainbow bridge.""" + displayname = "Dungeon Rewards Required for Bridge" + range_start = 0 + range_end = 9 + default = 9 + + +class BridgeTokens(Range): + """Set the number of Gold Skulltula Tokens required for the rainbow bridge.""" + displayname = "Tokens Required for Bridge" + range_start = 0 + range_end = 100 + default = 100 + + +bridge_options: typing.Dict[str, type(Option)] = { + "bridge_stones": BridgeStones, + "bridge_medallions": BridgeMedallions, + "bridge_rewards": BridgeRewards, + "bridge_tokens": BridgeTokens, +} + + +class SongShuffle(Choice): + """Set where songs can appear.""" + displayname = "Shuffle Songs" + option_song = 0 + option_dungeon = 1 + option_any = 2 + + +class ShopShuffle(Choice): + """Randomizes shop contents. Set to "off" to not shuffle shops; "0" shuffles shops but does not allow multiworld items in shops.""" + displayname = "Shopsanity" + option_0 = 0 + option_1 = 1 + option_2 = 2 + option_3 = 3 + option_4 = 4 + option_random_value = 5 + option_off = 6 + default = 6 + alias_false = 6 + + +class TokenShuffle(Choice): + """Token rewards from Gold Skulltulas are shuffled into the pool.""" + displayname = "Tokensanity" + option_off = 0 + option_dungeons = 1 + option_overworld = 2 + option_all = 3 + alias_false = 0 + + +class ScrubShuffle(Choice): + """Shuffle the items sold by Business Scrubs, and set the prices.""" + displayname = "Scrub Shuffle" + option_off = 0 + option_low = 1 + option_regular = 2 + option_random_prices = 3 + alias_false = 0 + alias_affordable = 1 + alias_expensive = 2 + + +class ShuffleCows(Toggle): + """Cows give items when Epona's Song is played.""" + displayname = "Shuffle Cows" + + +class ShuffleSword(Toggle): + """Shuffle Kokiri Sword into the item pool.""" + displayname = "Shuffle Kokiri Sword" + + +class ShuffleOcarinas(Toggle): + """Shuffle the Fairy Ocarina and Ocarina of Time into the item pool.""" + displayname = "Shuffle Ocarinas" + + +class ShuffleEgg(Toggle): + """Shuffle the Weird Egg from Malon at Hyrule Castle.""" + displayname = "Shuffle Weird Egg" + + +class ShuffleCard(Toggle): + """Shuffle the Gerudo Membership Card into the item pool.""" + displayname = "Shuffle Gerudo Card" + + +class ShuffleBeans(Toggle): + """Adds a pack of 10 beans to the item pool and changes the bean salesman to sell one item for 60 rupees.""" + displayname = "Shuffle Magic Beans" + + +class ShuffleMedigoronCarpet(Toggle): + """Shuffle the items sold by Medigoron and the Haunted Wasteland Carpet Salesman.""" + displayname = "Shuffle Medigoron & Carpet Salesman" + + +shuffle_options: typing.Dict[str, type(Option)] = { + "shuffle_song_items": SongShuffle, + "shopsanity": ShopShuffle, + "tokensanity": TokenShuffle, + "shuffle_scrubs": ScrubShuffle, + "shuffle_cows": ShuffleCows, + "shuffle_kokiri_sword": ShuffleSword, + "shuffle_ocarinas": ShuffleOcarinas, + "shuffle_weird_egg": ShuffleEgg, + "shuffle_gerudo_card": ShuffleCard, + "shuffle_beans": ShuffleBeans, + "shuffle_medigoron_carpet_salesman": ShuffleMedigoronCarpet, +} + + +class ShuffleMapCompass(Choice): + """Control where to shuffle dungeon maps and compasses.""" + displayname = "Maps & Compasses" + option_remove = 0 + option_startwith = 1 + option_vanilla = 2 + option_dungeon = 3 + option_overworld = 4 + option_any_dungeon = 5 + option_keysanity = 6 + default = 1 + alias_anywhere = 6 + + +class ShuffleKeys(Choice): + """Control where to shuffle dungeon small keys.""" + displayname = "Small Keys" + option_remove = 0 + option_vanilla = 2 + option_dungeon = 3 + option_overworld = 4 + option_any_dungeon = 5 + option_keysanity = 6 + default = 3 + alias_keysy = 0 + alias_anywhere = 6 + + +class ShuffleGerudoKeys(Choice): + """Control where to shuffle the Gerudo Fortress small keys.""" + displayname = "Gerudo Fortress Keys" + option_vanilla = 0 + option_overworld = 1 + option_any_dungeon = 2 + option_keysanity = 3 + alias_anywhere = 3 + + +class ShuffleBossKeys(Choice): + """Control where to shuffle boss keys, except the Ganon's Castle Boss Key.""" + displayname = "Boss Keys" + option_remove = 0 + option_vanilla = 2 + option_dungeon = 3 + option_overworld = 4 + option_any_dungeon = 5 + option_keysanity = 6 + default = 3 + alias_keysy = 0 + alias_anywhere = 6 + + +class ShuffleGanonBK(Choice): + """Control where to shuffle the Ganon's Castle Boss Key.""" + displayname = "Ganon's Boss Key" + option_remove = 0 + option_vanilla = 2 + option_dungeon = 3 + option_overworld = 4 + option_any_dungeon = 5 + option_keysanity = 6 + option_on_lacs = 7 + default = 0 + alias_keysy = 0 + alias_anywhere = 6 + + +class EnhanceMC(Toggle): + """Map tells if a dungeon is vanilla or MQ. Compass tells what the dungeon reward is.""" + displayname = "Maps and Compasses Give Information" + + +dungeon_items_options: typing.Dict[str, type(Option)] = { + "shuffle_mapcompass": ShuffleMapCompass, + "shuffle_smallkeys": ShuffleKeys, + "shuffle_fortresskeys": ShuffleGerudoKeys, + "shuffle_bosskeys": ShuffleBossKeys, + "shuffle_ganon_bosskey": ShuffleGanonBK, + "enhance_map_compass": EnhanceMC, +} + + +class SkipChildZelda(Toggle): + """Game starts with Zelda's Letter, the item at Zelda's Lullaby, and the relevant events already completed.""" + displayname = "Skip Child Zelda" + + +class SkipEscape(DefaultOnToggle): + """Skips the tower collapse sequence between the Ganondorf and Ganon fights.""" + displayname = "Skip Tower Escape Sequence" + + +class SkipStealth(DefaultOnToggle): + """The crawlspace into Hyrule Castle skips straight to Zelda.""" + displayname = "Skip Child Stealth" + + +class SkipEponaRace(DefaultOnToggle): + """Epona can always be summoned with Epona's Song.""" + displayname = "Skip Epona Race" + + +class SkipMinigamePhases(DefaultOnToggle): + """Dampe Race and Horseback Archery give both rewards if the second condition is met on the first attempt.""" + displayname = "Skip Some Minigame Phases" + + +class CompleteMaskQuest(Toggle): + """All masks are immediately available to borrow from the Happy Mask Shop.""" + displayname = "Complete Mask Quest" + + +class UsefulCutscenes(Toggle): + """Reenables the Poe cutscene in Forest Temple, Darunia in Fire Temple, and Twinrova introduction. Mostly useful for glitched.""" + displayname = "Enable Useful Cutscenes" + + +class FastChests(DefaultOnToggle): + """All chest animations are fast. If disabled, major items have a slow animation.""" + displayname = "Fast Chest Cutscenes" + + +class FreeScarecrow(Toggle): + """Pulling out the ocarina near a scarecrow spot spawns Pierre without needing the song.""" + displayname = "Free Scarecrow's Song" + + +class FastBunny(Toggle): + """Bunny Hood lets you move 1.5x faster like in Majora's Mask.""" + displayname = "Fast Bunny Hood" + + +class ChickenCount(Range): + """Controls the number of Cuccos for Anju to give an item as child.""" + displayname = "Cucco Count" + range_start = 0 + range_end = 7 + default = 7 + + +timesavers_options: typing.Dict[str, type(Option)] = { + "skip_child_zelda": SkipChildZelda, + "no_escape_sequence": SkipEscape, + "no_guard_stealth": SkipStealth, + "no_epona_race": SkipEponaRace, + "skip_some_minigame_phases": SkipMinigamePhases, + "complete_mask_quest": CompleteMaskQuest, + "useful_cutscenes": UsefulCutscenes, + "fast_chests": FastChests, + "free_scarecrow": FreeScarecrow, + "fast_bunny_hood": FastBunny, + "chicken_count": ChickenCount, + # "big_poe_count": make_range(1, 10, 1), +} + + +class Hints(Choice): + """Gossip Stones can give hints about item locations.""" + displayname = "Gossip Stones" + option_none = 0 + option_mask = 1 + option_agony = 2 + option_always = 3 + default = 3 + alias_false = 0 + + +class HintDistribution(Choice): + """Choose the hint distribution to use. Affects the frequency of strong hints, which items are always hinted, etc.""" + displayname = "Hint Distribution" + option_balanced = 0 + option_ddr = 1 + option_league = 2 + option_mw2 = 3 + option_scrubs = 4 + option_strong = 5 + option_tournament = 6 + option_useless = 7 + option_very_strong = 8 + + +class TextShuffle(Choice): + """Randomizes text in the game for comedic effect.""" + displayname = "Text Shuffle" + option_none = 0 + option_except_hints = 1 + option_complete = 2 + alias_false = 0 + + +class DamageMultiplier(Choice): + """Controls the amount of damage Link takes.""" + displayname = "Damage Multiplier" + option_half = 0 + option_normal = 1 + option_double = 2 + option_quadruple = 3 + option_ohko = 4 + default = 1 + + +class HeroMode(Toggle): + """Hearts will not drop from enemies or objects.""" + displayname = "Hero Mode" + + +class StartingToD(Choice): + """Change the starting time of day.""" + displayname = "Starting Time of Day" + option_default = 0 + option_sunrise = 1 + option_morning = 2 + option_noon = 3 + option_afternoon = 4 + option_sunset = 5 + option_evening = 6 + option_midnight = 7 + option_witching_hour = 8 + + +class ConsumableStart(Toggle): + """Start the game with full Deku Sticks and Deku Nuts.""" + displayname = "Start with Consumables" + + +class RupeeStart(Toggle): + """Start with a full wallet. Wallet upgrades will also fill your wallet.""" + displayname = "Start with Rupees" + + +misc_options: typing.Dict[str, type(Option)] = { + # "clearer_hints": DefaultOnToggle, + "hints": Hints, + "hint_dist": HintDistribution, + "text_shuffle": TextShuffle, + "damage_multiplier": DamageMultiplier, + "no_collectible_hearts": HeroMode, + "starting_tod": StartingToD, + "start_with_consumables": ConsumableStart, + "start_with_rupees": RupeeStart, +} + +class ItemPoolValue(Choice): + """Changes the number of items available in the game.""" + displayname = "Item Pool" + option_plentiful = 0 + option_balanced = 1 + option_scarce = 2 + option_minimal = 3 + default = 1 + + +class IceTraps(Choice): + """Adds ice traps to the item pool.""" + displayname = "Ice Traps" + option_off = 0 + option_normal = 1 + option_on = 2 + option_mayhem = 3 + option_onslaught = 4 + default = 1 + alias_false = 0 + alias_true = 2 + alias_extra = 2 + + +class IceTrapVisual(Choice): + """Changes the appearance of ice traps as freestanding items.""" + displayname = "Ice Trap Appearance" + option_major_only = 0 + option_junk_only = 1 + option_anything = 2 + + +class AdultTradeItem(Choice): + option_pocket_egg = 0 + option_pocket_cucco = 1 + option_cojiro = 2 + option_odd_mushroom = 3 + option_poachers_saw = 4 + option_broken_sword = 5 + option_prescription = 6 + option_eyeball_frog = 7 + option_eyedrops = 8 + option_claim_check = 9 + + +class EarlyTradeItem(AdultTradeItem): + """Earliest item that can appear in the adult trade sequence.""" + displayname = "Adult Trade Sequence Earliest Item" + default = 6 + + +class LateTradeItem(AdultTradeItem): + """Latest item that can appear in the adult trade sequence.""" + displayname = "Adult Trade Sequence Latest Item" + default = 9 + + +itempool_options: typing.Dict[str, type(Option)] = { + "item_pool_value": ItemPoolValue, + "junk_ice_traps": IceTraps, + "ice_trap_appearance": IceTrapVisual, + "logic_earliest_adult_trade": EarlyTradeItem, + "logic_latest_adult_trade": LateTradeItem, +} + +# Start of cosmetic options + +def assemble_color_option(func, display_name: str, default_option: str, outer=False): + color_options = func() + if outer: + color_options.append("Match Inner") + format_color = lambda color: color.replace(' ', '_').lower() + color_to_id = {format_color(color): index for index, color in enumerate(color_options)} + class ColorOption(Choice): + """Choose a color. "random_choice" selects a random option. "completely_random" generates a random hex code.""" + displayname = display_name + default = color_options.index(default_option) + ColorOption.options.update(color_to_id) + ColorOption.name_lookup.update({id: color for (color, id) in color_to_id.items()}) + return ColorOption + + +class Targeting(Choice): + """Default targeting option.""" + displayname = "Default Targeting Option" + option_hold = 0 + option_switch = 1 + + +class DisplayDpad(DefaultOnToggle): + """Show dpad icon on HUD for quick actions (ocarina, hover boots, iron boots).""" + displayname = "Display D-Pad HUD" + + +class CorrectColors(DefaultOnToggle): + """Makes in-game models match their HUD element colors.""" + displayname = "Item Model Colors Match Cosmetics" + + +class Music(Choice): + option_normal = 0 + option_off = 1 + option_randomized = 2 + alias_false = 1 + + +class BackgroundMusic(Music): + """Randomize or disable background music.""" + displayname = "Background Music" + + +class Fanfares(Music): + """Randomize or disable item fanfares.""" + displayname = "Fanfares" + + +class OcarinaFanfares(Toggle): + """Enable ocarina songs as fanfares. These are longer than usual fanfares. Does nothing without fanfares randomized.""" + displayname = "Ocarina Songs as Fanfares" + + +class SwordTrailDuration(Range): + """Set the duration for sword trails.""" + displayname = "Sword Trail Duration" + range_start = 4 + range_end = 20 + default = 4 + + +cosmetic_options: typing.Dict[str, type(Option)] = { + "default_targeting": Targeting, + "display_dpad": DisplayDpad, + "correct_model_colors": CorrectColors, + "background_music": BackgroundMusic, + "fanfares": Fanfares, + "ocarina_fanfares": OcarinaFanfares, + "kokiri_color": assemble_color_option(get_tunic_color_options, "Kokiri Tunic", "Kokiri Green"), + "goron_color": assemble_color_option(get_tunic_color_options, "Goron Tunic", "Goron Red"), + "zora_color": assemble_color_option(get_tunic_color_options, "Zora Tunic", "Zora Blue"), + "silver_gauntlets_color": assemble_color_option(get_gauntlet_color_options, "Silver Gauntlets Color", "Silver"), + "golden_gauntlets_color": assemble_color_option(get_gauntlet_color_options, "Golden Gauntlets Color", "Gold"), + "mirror_shield_frame_color": assemble_color_option(get_shield_frame_color_options, "Mirror Shield Frame Color", "Red"), + "navi_color_default_inner": assemble_color_option(get_navi_color_options, "Navi Idle Inner", "White"), + "navi_color_default_outer": assemble_color_option(get_navi_color_options, "Navi Idle Outer", "Match Inner", outer=True), + "navi_color_enemy_inner": assemble_color_option(get_navi_color_options, "Navi Targeting Enemy Inner", "Yellow"), + "navi_color_enemy_outer": assemble_color_option(get_navi_color_options, "Navi Targeting Enemy Outer", "Match Inner", outer=True), + "navi_color_npc_inner": assemble_color_option(get_navi_color_options, "Navi Targeting NPC Inner", "Light Blue"), + "navi_color_npc_outer": assemble_color_option(get_navi_color_options, "Navi Targeting NPC Outer", "Match Inner", outer=True), + "navi_color_prop_inner": assemble_color_option(get_navi_color_options, "Navi Targeting Prop Inner", "Green"), + "navi_color_prop_outer": assemble_color_option(get_navi_color_options, "Navi Targeting Prop Outer", "Match Inner", outer=True), + "sword_trail_duration": SwordTrailDuration, + "sword_trail_color_inner": assemble_color_option(get_sword_trail_color_options, "Sword Trail Inner", "White"), + "sword_trail_color_outer": assemble_color_option(get_sword_trail_color_options, "Sword Trail Outer", "Match Inner", outer=True), + "bombchu_trail_color_inner": assemble_color_option(get_bombchu_trail_color_options, "Bombchu Trail Inner", "Red"), + "bombchu_trail_color_outer": assemble_color_option(get_bombchu_trail_color_options, "Bombchu Trail Outer", "Match Inner", outer=True), + "boomerang_trail_color_inner": assemble_color_option(get_boomerang_trail_color_options, "Boomerang Trail Inner", "Yellow"), + "boomerang_trail_color_outer": assemble_color_option(get_boomerang_trail_color_options, "Boomerang Trail Outer", "Match Inner", outer=True), + "heart_color": assemble_color_option(get_heart_color_options, "Heart Color", "Red"), + "magic_color": assemble_color_option(get_magic_color_options, "Magic Color", "Green"), + "a_button_color": assemble_color_option(get_a_button_color_options, "A Button Color", "N64 Blue"), + "b_button_color": assemble_color_option(get_b_button_color_options, "B Button Color", "N64 Green"), + "c_button_color": assemble_color_option(get_c_button_color_options, "C Button Color", "Yellow"), + "start_button_color": assemble_color_option(get_start_button_color_options, "Start Button Color", "N64 Red"), +} + +def assemble_sfx_option(sound_hook: sfx.SoundHooks, display_name: str): + options = sfx.get_setting_choices(sound_hook).keys() + sfx_to_id = {sfx.replace('-', '_'): index for index, sfx in enumerate(options)} + class SfxOption(Choice): + """Choose a sound effect. "random_choice" selects a random option. "random_ear_safe" selects a random safe option. "completely_random" selects any random sound.""" + displayname = display_name + SfxOption.options.update(sfx_to_id) + SfxOption.name_lookup.update({id: sfx for (sfx, id) in sfx_to_id.items()}) + return SfxOption + +class SfxOcarina(Choice): + """Change the sound of the ocarina.""" + displayname = "Ocarina Instrument" + option_ocarina = 1 + option_malon = 2 + option_whistle = 3 + option_harp = 4 + option_grind_organ = 5 + option_flute = 6 + default = 1 + +sfx_options: typing.Dict[str, type(Option)] = { + "sfx_navi_overworld": assemble_sfx_option(sfx.SoundHooks.NAVI_OVERWORLD, "Navi Overworld"), + "sfx_navi_enemy": assemble_sfx_option(sfx.SoundHooks.NAVI_ENEMY, "Navi Enemy"), + "sfx_low_hp": assemble_sfx_option(sfx.SoundHooks.HP_LOW, "Low HP"), + "sfx_menu_cursor": assemble_sfx_option(sfx.SoundHooks.MENU_CURSOR, "Menu Cursor"), + "sfx_menu_select": assemble_sfx_option(sfx.SoundHooks.MENU_SELECT, "Menu Select"), + "sfx_nightfall": assemble_sfx_option(sfx.SoundHooks.NIGHTFALL, "Nightfall"), + "sfx_horse_neigh": assemble_sfx_option(sfx.SoundHooks.HORSE_NEIGH, "Horse"), + "sfx_hover_boots": assemble_sfx_option(sfx.SoundHooks.BOOTS_HOVER, "Hover Boots"), + "sfx_ocarina": SfxOcarina, +} + + +# All options assembled into a single dict +oot_options: typing.Dict[str, type(Option)] = { + "logic_rules": Logic, + "logic_no_night_tokens_without_suns_song": NightTokens, + **open_options, + **world_options, + **bridge_options, + **dungeon_items_options, + **lacs_options, + **shuffle_options, + **timesavers_options, + **misc_options, + **itempool_options, + **cosmetic_options, + **sfx_options, + "logic_tricks": OptionList, +} diff --git a/worlds/oot/Patches.py b/worlds/oot/Patches.py new file mode 100644 index 00000000..1a27ab02 --- /dev/null +++ b/worlds/oot/Patches.py @@ -0,0 +1,2166 @@ +import struct +import itertools +import re +import zlib +from collections import defaultdict + +from .LocationList import business_scrubs +from .Hints import writeGossipStoneHints, buildAltarHints, \ + buildGanonText, getSimpleHintNoPrefix +from .Utils import data_path +from .Messages import read_messages, update_message_by_id, read_shop_items, \ + write_shop_items, remove_unused_messages, make_player_message, \ + add_item_messages, repack_messages, shuffle_messages, \ + get_message_by_id +from .MQ import patch_files, File, update_dmadata, insert_space, add_relocations +from .SaveContext import SaveContext +from .TextBox import character_table, NORMAL_LINE_WIDTH + + +# "Spoiler" argument deleted; can probably be replaced with calls to world.world +def patch_rom(world, rom): + with open(data_path('generated/rom_patch.txt'), 'r') as stream: + for line in stream: + address, value = [int(x, 16) for x in line.split(',')] + rom.write_int32(address, value) + rom.scan_dmadata_update() + + # Write Randomizer title screen logo + with open(data_path('title.bin'), 'rb') as stream: + writeAddress = 0x01795300 + titleBytesComp = stream.read() + titleBytesDiff = zlib.decompress(titleBytesComp) + + originalBytes = rom.original.buffer[writeAddress: writeAddress+ len(titleBytesDiff)] + titleBytes = bytearray([a ^ b for a, b in zip(titleBytesDiff, originalBytes)]) + rom.write_bytes(writeAddress, titleBytes) + + # Fixes the typo of keatan mask in the item select screen + with open(data_path('keaton.bin'), 'rb') as stream: + writeAddress = 0x8A7C00 + keatonBytesComp = stream.read() + keatonBytesDiff = zlib.decompress(keatonBytesComp) + + originalBytes = rom.original.buffer[writeAddress: writeAddress+ len(keatonBytesDiff)] + keatonBytes = bytearray([a ^ b for a, b in zip(keatonBytesDiff, originalBytes)]) + rom.write_bytes(writeAddress, keatonBytes) + + # Load Triforce model into a file + triforce_obj_file = File({ 'Name': 'object_gi_triforce' }) + triforce_obj_file.copy(rom) + with open(data_path('triforce.bin'), 'rb') as stream: + obj_data = stream.read() + rom.write_bytes(triforce_obj_file.start, obj_data) + triforce_obj_file.end = triforce_obj_file.start + len(obj_data) + update_dmadata(rom, triforce_obj_file) + # Add it to the extended object table + add_to_extended_object_table(rom, 0x193, triforce_obj_file) + + # Build a Double Defense model from the Heart Container model + dd_obj_file = File({ + 'Name': 'object_gi_hearts', + 'Start': '014D9000', + 'End': '014DA590', + }) + dd_obj_file.copy(rom) + # Update colors for the Double Defense variant + rom.write_bytes(dd_obj_file.start + 0x1294, [0xFF, 0xCF, 0x0F]) # Exterior Primary Color + rom.write_bytes(dd_obj_file.start + 0x12B4, [0xFF, 0x46, 0x32]) # Exterior Env Color + rom.write_int32s(dd_obj_file.start + 0x12A8, [0xFC173C60, 0x150C937F]) # Exterior Combine Mode + rom.write_bytes(dd_obj_file.start + 0x1474, [0xFF, 0xFF, 0xFF]) # Interior Primary Color + rom.write_bytes(dd_obj_file.start + 0x1494, [0xFF, 0xFF, 0xFF]) # Interior Env Color + update_dmadata(rom, dd_obj_file) + # Add it to the extended object table + add_to_extended_object_table(rom, 0x194, dd_obj_file) + + # Set default targeting option to Hold. I got fed up enough with this that I made it a main option + if world.default_targeting == 'hold': + rom.write_byte(0xB71E6D, 0x01) + else: + rom.write_byte(0xB71E6D, 0x00) + + # Create an option so that recovery hearts no longer drop by changing the code which checks Link's health when an item is spawned. + if world.no_collectible_hearts: + rom.write_byte(0xA895B7, 0x2E) + + # Force language to be English in the event a Japanese rom was submitted + rom.write_byte(0x3E, 0x45) + rom.force_patch.append(0x3E) + + # Increase the instance size of Bombchus prevent the heap from becoming corrupt when + # a Dodongo eats a Bombchu. Does not fix stale pointer issues with the animation + rom.write_int32(0xD6002C, 0x1F0) + + # Can always return to youth + rom.write_byte(0xCB6844, 0x35) + rom.write_byte(0x253C0E2, 0x03) # Moves sheik from pedestal + + # Fix Ice Cavern Alcove Camera + if not world.dungeon_mq['Ice Cavern']: + rom.write_byte(0x2BECA25,0x01); + rom.write_byte(0x2BECA2D,0x01); + + # Fix GS rewards to be static + rom.write_int32(0xEA3934, 0) + rom.write_bytes(0xEA3940, [0x10, 0x00]) + + # Fix horseback archery rewards to be static + rom.write_byte(0xE12BA5, 0x00) + rom.write_byte(0xE12ADD, 0x00) + + # Fix deku theater rewards to be static + rom.write_bytes(0xEC9A7C, [0x00, 0x00, 0x00, 0x00]) #Sticks + rom.write_byte(0xEC9CD5, 0x00) #Nuts + + # Fix deku scrub who sells stick upgrade + rom.write_bytes(0xDF8060, [0x00, 0x00, 0x00, 0x00]) + + # Fix deku scrub who sells nut upgrade + rom.write_bytes(0xDF80D4, [0x00, 0x00, 0x00, 0x00]) + + # Fix rolling goron as child reward to be static + rom.write_bytes(0xED2960, [0x00, 0x00, 0x00, 0x00]) + + # Fix proximity text boxes (Navi) (Part 1) + rom.write_bytes(0xDF8B84, [0x00, 0x00, 0x00, 0x00]) + + # Fix final magic bean to cost 99 + rom.write_byte(0xE20A0F, 0x63) + rom.write_bytes(0x94FCDD, [0x08, 0x39, 0x39]) + + # Remove locked door to Boss Key Chest in Fire Temple + if not world.keysanity and not world.dungeon_mq['Fire Temple']: + rom.write_byte(0x22D82B7, 0x3F) + # Remove the unused locked door in water temple + if not world.dungeon_mq['Water Temple']: + rom.write_byte(0x25B8197, 0x3F) + + if world.bombchus_in_logic: + rom.write_int32(rom.sym('BOMBCHUS_IN_LOGIC'), 1) + + # Change graveyard graves to not allow grabbing on to the ledge + rom.write_byte(0x0202039D, 0x20) + rom.write_byte(0x0202043C, 0x24) + + + # Fix Castle Courtyard to check for meeting Zelda, not Zelda fleeing, to block you + rom.write_bytes(0xCD5E76, [0x0E, 0xDC]) + rom.write_bytes(0xCD5E12, [0x0E, 0xDC]) + + # Cutscene for all medallions never triggers when leaving shadow or spirit temples(hopefully stops warp to colossus on shadow completion with boss reward shuffle) + rom.write_byte(0xACA409, 0xAD) + rom.write_byte(0xACA49D, 0xCE) + + # Speed Zelda's Letter scene + rom.write_bytes(0x290E08E, [0x05, 0xF0]) + rom.write_byte(0xEFCBA7, 0x08) + rom.write_byte(0xEFE7C7, 0x05) + #rom.write_byte(0xEFEAF7, 0x08) + #rom.write_byte(0xEFE7C7, 0x05) + rom.write_bytes(0xEFE938, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xEFE948, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xEFE950, [0x00, 0x00, 0x00, 0x00]) + + # Speed Zelda escaping from Hyrule Castle + Block_code = [0x00, 0x00, 0x00, 0x01, 0x00, 0x21, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02] + rom.write_bytes(0x1FC0CF8, Block_code) + + # songs as items flag + songs_as_items = (world.shuffle_song_items != 'song') or world.starting_songs + + if songs_as_items: + rom.write_byte(rom.sym('SONGS_AS_ITEMS'), 1) + + # Speed learning Zelda's Lullaby + rom.write_int32s(0x02E8E90C, [0x000003E8, 0x00000001]) # Terminator Execution + if songs_as_items: + rom.write_int16s(None, [0x0073, 0x001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0073, 0x003B, 0x003C, 0x003C]) # ID, start, end, end + + + rom.write_int32s(0x02E8E91C, [0x00000013, 0x0000000C]) # Textbox, Count + if songs_as_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0017, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D4, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Sun's Song + if songs_as_items: + rom.write_int32(0x0332A4A4, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x0332A4A4, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x0332A868, [0x00000013, 0x00000008]) # Textbox, Count + rom.write_int16s(None, [0x0018, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D3, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Saria's Song + if songs_as_items: + rom.write_int32(0x020B1734, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x020B1734, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x20B1DA8, [0x00000013, 0x0000000C]) # Textbox, Count + rom.write_int16s(None, [0x0015, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D1, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x020B19C0, [0x0000000A, 0x00000006]) # Link, Count + rom.write_int16s(0x020B19C8, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x020B19F8, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + rom.write_int32s(None, [0x80000000, # ??? + 0x00000000, 0x000001D4, 0xFFFFF731, # start_XYZ + 0x00000000, 0x000001D4, 0xFFFFF712]) # end_XYZ + + # Speed learning Epona's Song + rom.write_int32s(0x029BEF60, [0x000003E8, 0x00000001]) # Terminator Execution + if songs_as_items: + rom.write_int16s(None, [0x005E, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x005E, 0x000A, 0x000B, 0x000B]) # ID, start, end, end + + rom.write_int32s(0x029BECB0, [0x00000013, 0x00000002]) # Textbox, Count + if songs_as_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0009, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x00D2, 0x0000, 0x0009, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0xFFFF, 0x000A, 0x003C, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Song of Time + rom.write_int32s(0x0252FB98, [0x000003E8, 0x00000001]) # Terminator Execution + if songs_as_items: + rom.write_int16s(None, [0x0035, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0035, 0x003B, 0x003C, 0x003C]) # ID, start, end, end + + rom.write_int32s(0x0252FC80, [0x00000013, 0x0000000C]) # Textbox, Count + if songs_as_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0019, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D5, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32(0x01FC3B84, 0xFFFFFFFF) # Other Header?: frame_count + + # Speed learning Song of Storms + if songs_as_items: + rom.write_int32(0x03041084, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x03041084, 0x0000000A) # Header: frame_count + + rom.write_int32s(0x03041088, [0x00000013, 0x00000002]) # Textbox, Count + rom.write_int16s(None, [0x00D6, 0x0000, 0x0009, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0xFFFF, 0x00BE, 0x00C8, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Minuet of Forest + if songs_as_items: + rom.write_int32(0x020AFF84, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x020AFF84, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x020B0800, [0x00000013, 0x0000000A]) # Textbox, Count + rom.write_int16s(None, [0x000F, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0073, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x020AFF88, [0x0000000A, 0x00000005]) # Link, Count + rom.write_int16s(0x020AFF90, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x020AFFC1, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x020B0488, [0x00000056, 0x00000001]) # Music Change, Count + rom.write_int16s(None, [0x003F, 0x0021, 0x0022, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x020B04C0, [0x0000007C, 0x00000001]) # Music Fade Out, Count + rom.write_int16s(None, [0x0004, 0x0000, 0x0000, 0x0000]) #action, start, end, ???? + + # Speed learning Bolero of Fire + if songs_as_items: + rom.write_int32(0x0224B5D4, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x0224B5D4, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x0224D7E8, [0x00000013, 0x0000000A]) # Textbox, Count + rom.write_int16s(None, [0x0010, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0074, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x0224B5D8, [0x0000000A, 0x0000000B]) # Link, Count + rom.write_int16s(0x0224B5E0, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x0224B610, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x0224B7F0, [0x0000002F, 0x0000000E]) # Sheik, Count + rom.write_int16s(0x0224B7F8, [0x0000]) #action + rom.write_int16s(0x0224B828, [0x0000]) #action + rom.write_int16s(0x0224B858, [0x0000]) #action + rom.write_int16s(0x0224B888, [0x0000]) #action + + # Speed learning Serenade of Water + if songs_as_items: + rom.write_int32(0x02BEB254, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x02BEB254, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x02BEC880, [0x00000013, 0x00000010]) # Textbox, Count + rom.write_int16s(None, [0x0011, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0075, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x02BEB258, [0x0000000A, 0x0000000F]) # Link, Count + rom.write_int16s(0x02BEB260, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x02BEB290, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x02BEB530, [0x0000002F, 0x00000006]) # Sheik, Count + rom.write_int16s(0x02BEB538, [0x0000, 0x0000, 0x018A, 0x0000]) #action, start, end, ???? + rom.write_int32s(None, [0x1BBB0000, # ??? + 0xFFFFFB10, 0x8000011A, 0x00000330, # start_XYZ + 0xFFFFFB10, 0x8000011A, 0x00000330]) # end_XYZ + + rom.write_int32s(0x02BEC848, [0x00000056, 0x00000001]) # Music Change, Count + rom.write_int16s(None, [0x0059, 0x0021, 0x0022, 0x0000]) #action, start, end, ???? + + # Speed learning Nocturne of Shadow + rom.write_int32s(0x01FFE458, [0x000003E8, 0x00000001]) # Other Scene? Terminator Execution + rom.write_int16s(None, [0x002F, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + + rom.write_int32(0x01FFFDF4, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x02000FD8, [0x00000013, 0x0000000E]) # Textbox, Count + if songs_as_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0013, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0077, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x02000128, [0x000003E8, 0x00000001]) # Terminator Execution + if songs_as_items: + rom.write_int16s(None, [0x0032, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0032, 0x003A, 0x003B, 0x003B]) # ID, start, end, end + + # Speed learning Requiem of Spirit + rom.write_int32(0x0218AF14, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x0218C574, [0x00000013, 0x00000008]) # Textbox, Count + if songs_as_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0012, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0076, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x0218B478, [0x000003E8, 0x00000001]) # Terminator Execution + if songs_as_items: + rom.write_int16s(None, [0x0030, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0030, 0x003A, 0x003B, 0x003B]) # ID, start, end, end + + rom.write_int32s(0x0218AF18, [0x0000000A, 0x0000000B]) # Link, Count + rom.write_int16s(0x0218AF20, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int32s(None, [0x40000000, # ??? + 0xFFFFFAF9, 0x00000008, 0x00000001, # start_XYZ + 0xFFFFFAF9, 0x00000008, 0x00000001, # end_XYZ + 0x0F671408, 0x00000000, 0x00000001]) # normal_XYZ + rom.write_int16s(0x0218AF50, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + # Speed learning Prelude of Light + if songs_as_items: + rom.write_int32(0x0252FD24, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x0252FD24, 0x0000004A) # Header: frame_count + + rom.write_int32s(0x02531320, [0x00000013, 0x0000000E]) # Textbox, Count + rom.write_int16s(None, [0x0014, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0078, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x0252FF10, [0x0000002F, 0x00000009]) # Sheik, Count + rom.write_int16s(0x0252FF18, [0x0006, 0x0000, 0x0000, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x025313D0, [0x00000056, 0x00000001]) # Music Change, Count + rom.write_int16s(None, [0x003B, 0x0021, 0x0022, 0x0000]) #action, start, end, ???? + + # Speed scene after Deku Tree + rom.write_bytes(0x2077E20, [0x00, 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0x2078A10, [0x00, 0x0E, 0x00, 0x1F, 0x00, 0x20, 0x00, 0x20]) + Block_code = [0x00, 0x80, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x1E, 0x00, 0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] + rom.write_bytes(0x2079570, Block_code) + + # Speed scene after Dodongo's Cavern + rom.write_bytes(0x2221E88, [0x00, 0x0C, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0x2223308, [0x00, 0x81, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed scene after Jabu Jabu's Belly + rom.write_bytes(0xCA3530, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0x2113340, [0x00, 0x0D, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0x2113C18, [0x00, 0x82, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + rom.write_bytes(0x21131D0, [0x00, 0x01, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C]) + + # Speed scene after Forest Temple + rom.write_bytes(0xD4ED68, [0x00, 0x45, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD4ED78, [0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + rom.write_bytes(0x207B9D4, [0xFF, 0xFF, 0xFF, 0xFF]) + + # Speed scene after Fire Temple + rom.write_bytes(0x2001848, [0x00, 0x1E, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0xD100B4, [0x00, 0x62, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD10134, [0x00, 0x3C, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed scene after Water Temple + rom.write_bytes(0xD5A458, [0x00, 0x15, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD5A3A8, [0x00, 0x3D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + rom.write_bytes(0x20D0D20, [0x00, 0x29, 0x00, 0xC7, 0x00, 0xC8, 0x00, 0xC8]) + + # Speed scene after Shadow Temple + rom.write_bytes(0xD13EC8, [0x00, 0x61, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD13E18, [0x00, 0x41, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed scene after Spirit Temple + rom.write_bytes(0xD3A0A8, [0x00, 0x60, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD39FF0, [0x00, 0x3F, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed Nabooru defeat scene + rom.write_bytes(0x2F5AF84, [0x00, 0x00, 0x00, 0x05]) + rom.write_bytes(0x2F5C7DA, [0x00, 0x01, 0x00, 0x02]) + rom.write_bytes(0x2F5C7A2, [0x00, 0x03, 0x00, 0x04]) + rom.write_byte(0x2F5B369, 0x09) + rom.write_byte(0x2F5B491, 0x04) + rom.write_byte(0x2F5B559, 0x04) + rom.write_byte(0x2F5B621, 0x04) + rom.write_byte(0x2F5B761, 0x07) + rom.write_bytes(0x2F5B840, [0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x05]) #shorten white flash + + # Speed scene with all medallions + rom.write_bytes(0x2512680, [0x00, 0x74, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + + # Speed collapse of Ganon's Tower + rom.write_bytes(0x33FB328, [0x00, 0x76, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + + # Speed Phantom Ganon defeat scene + rom.write_bytes(0xC944D8, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC94548, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC94730, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC945A8, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC94594, [0x00, 0x00, 0x00, 0x00]) + + # Speed Twinrova defeat scene + rom.write_bytes(0xD678CC, [0x24, 0x01, 0x03, 0xA2, 0xA6, 0x01, 0x01, 0x42]) + rom.write_bytes(0xD67BA4, [0x10, 0x00]) + + # Speed scenes during final battle + # Ganondorf battle end + rom.write_byte(0xD82047, 0x09) + # Zelda descends + rom.write_byte(0xD82AB3, 0x66) + rom.write_byte(0xD82FAF, 0x65) + rom.write_int16s(0xD82D2E, [0x041F]) + rom.write_int16s(0xD83142, [0x006B]) + rom.write_bytes(0xD82DD8, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xD82ED4, [0x00, 0x00, 0x00, 0x00]) + rom.write_byte(0xD82FDF, 0x33) + # After tower collapse + rom.write_byte(0xE82E0F, 0x04) + # Ganon intro + rom.write_bytes(0xE83D28, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xE83B5C, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xE84C80, [0x10, 0x00]) + + # Speed completion of the trials in Ganon's Castle + rom.write_int16s(0x31A8090, [0x006B, 0x0001, 0x0002, 0x0002]) #Forest + rom.write_int16s(0x31A9E00, [0x006E, 0x0001, 0x0002, 0x0002]) #Fire + rom.write_int16s(0x31A8B18, [0x006C, 0x0001, 0x0002, 0x0002]) #Water + rom.write_int16s(0x31A9430, [0x006D, 0x0001, 0x0002, 0x0002]) #Shadow + rom.write_int16s(0x31AB200, [0x0070, 0x0001, 0x0002, 0x0002]) #Spirit + rom.write_int16s(0x31AA830, [0x006F, 0x0001, 0x0002, 0x0002]) #Light + + # Speed obtaining Fairy Ocarina + rom.write_bytes(0x2151230, [0x00, 0x72, 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3D]) + Block_code = [0x00, 0x4A, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x3C, 0x00, 0x81, 0xFF, 0xFF] + rom.write_bytes(0x2151240, Block_code) + rom.write_bytes(0x2150E20, [0xFF, 0xFF, 0xFA, 0x4C]) + + if world.shuffle_ocarinas: + symbol = rom.sym('OCARINAS_SHUFFLED') + rom.write_byte(symbol,0x01) + + # Speed Zelda Light Arrow cutscene + rom.write_bytes(0x2531B40, [0x00, 0x28, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0x2532FBC, [0x00, 0x75]) + rom.write_bytes(0x2532FEA, [0x00, 0x75, 0x00, 0x80]) + rom.write_byte(0x2533115, 0x05) + rom.write_bytes(0x2533141, [0x06, 0x00, 0x06, 0x00, 0x10]) + rom.write_bytes(0x2533171, [0x0F, 0x00, 0x11, 0x00, 0x40]) + rom.write_bytes(0x25331A1, [0x07, 0x00, 0x41, 0x00, 0x65]) + rom.write_bytes(0x2533642, [0x00, 0x50]) + rom.write_byte(0x253389D, 0x74) + rom.write_bytes(0x25338A4, [0x00, 0x72, 0x00, 0x75, 0x00, 0x79]) + rom.write_bytes(0x25338BC, [0xFF, 0xFF]) + rom.write_bytes(0x25338C2, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) + rom.write_bytes(0x25339C2, [0x00, 0x75, 0x00, 0x76]) + rom.write_bytes(0x2533830, [0x00, 0x31, 0x00, 0x81, 0x00, 0x82, 0x00, 0x82]) + + # Speed Bridge of Light cutscene + rom.write_bytes(0x292D644, [0x00, 0x00, 0x00, 0xA0]) + rom.write_bytes(0x292D680, [0x00, 0x02, 0x00, 0x0A, 0x00, 0x6C, 0x00, 0x00]) + rom.write_bytes(0x292D6E8, [0x00, 0x27]) + rom.write_bytes(0x292D718, [0x00, 0x32]) + rom.write_bytes(0x292D810, [0x00, 0x02, 0x00, 0x3C]) + rom.write_bytes(0x292D924, [0xFF, 0xFF, 0x00, 0x14, 0x00, 0x96, 0xFF, 0xFF]) + + #Speed Pushing of All Pushable Objects + rom.write_bytes(0xDD2B86, [0x40, 0x80]) #block speed + rom.write_bytes(0xDD2D26, [0x00, 0x01]) #block delay + rom.write_bytes(0xDD9682, [0x40, 0x80]) #milk crate speed + rom.write_bytes(0xDD981E, [0x00, 0x01]) #milk crate delay + rom.write_bytes(0xCE1BD0, [0x40, 0x80, 0x00, 0x00]) #amy puzzle speed + rom.write_bytes(0xCE0F0E, [0x00, 0x01]) #amy puzzle delay + rom.write_bytes(0xC77CA8, [0x40, 0x80, 0x00, 0x00]) #fire block speed + rom.write_bytes(0xC770C2, [0x00, 0x01]) #fire block delay + rom.write_bytes(0xCC5DBC, [0x29, 0xE1, 0x00, 0x01]) #forest basement puzzle delay + rom.write_bytes(0xDBCF70, [0x2B, 0x01, 0x00, 0x00]) #spirit cobra mirror startup + rom.write_bytes(0xDBCF70, [0x2B, 0x01, 0x00, 0x01]) #spirit cobra mirror delay + rom.write_bytes(0xDBA230, [0x28, 0x41, 0x00, 0x19]) #truth spinner speed + rom.write_bytes(0xDBA3A4, [0x24, 0x18, 0x00, 0x00]) #truth spinner delay + + #Speed Deku Seed Upgrade Scrub Cutscene + rom.write_bytes(0xECA900, [0x24, 0x03, 0xC0, 0x00]) #scrub angle + rom.write_bytes(0xECAE90, [0x27, 0x18, 0xFD, 0x04]) #skip straight to giving item + rom.write_bytes(0xECB618, [0x25, 0x6B, 0x00, 0xD4]) #skip straight to digging back in + rom.write_bytes(0xECAE70, [0x00, 0x00, 0x00, 0x00]) #never initialize cs camera + rom.write_bytes(0xE5972C, [0x24, 0x08, 0x00, 0x01]) #timer set to 1 frame for giving item + + # Remove remaining owls + rom.write_bytes(0x1FE30CE, [0x01, 0x4B]) + rom.write_bytes(0x1FE30DE, [0x01, 0x4B]) + rom.write_bytes(0x1FE30EE, [0x01, 0x4B]) + rom.write_bytes(0x205909E, [0x00, 0x3F]) + rom.write_byte(0x2059094, 0x80) + + # Darunia won't dance + rom.write_bytes(0x22769E4, [0xFF, 0xFF, 0xFF, 0xFF]) + + # Zora moves quickly + rom.write_bytes(0xE56924, [0x00, 0x00, 0x00, 0x00]) + + # Speed Jabu Jabu swallowing Link + rom.write_bytes(0xCA0784, [0x00, 0x18, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + + # Ruto no longer points to Zora Sapphire + rom.write_bytes(0xD03BAC, [0xFF, 0xFF, 0xFF, 0xFF]) + + # Ruto never disappears from Jabu Jabu's Belly + rom.write_byte(0xD01EA3, 0x00) + + #Shift octorock in jabu forward + rom.write_bytes(0x275906E, [0xFF, 0xB3, 0xFB, 0x20, 0xF9, 0x56]) + + #Move fire/forest temple switches down 1 unit to make it easier to press + rom.write_bytes(0x24860A8, [0xFC, 0xF4]) #forest basement 1 + rom.write_bytes(0x24860C8, [0xFC, 0xF4]) #forest basement 2 + rom.write_bytes(0x24860E8, [0xFC, 0xF4]) #forest basement 3 + rom.write_bytes(0x236C148, [0x11, 0x93]) #fire hammer room + + # Speed up Epona race start + rom.write_bytes(0x29BE984, [0x00, 0x00, 0x00, 0x02]) + rom.write_bytes(0x29BE9CA, [0x00, 0x01, 0x00, 0x02]) + + # Speed start of Horseback Archery + #rom.write_bytes(0x21B2064, [0x00, 0x00, 0x00, 0x02]) + #rom.write_bytes(0x21B20AA, [0x00, 0x01, 0x00, 0x02]) + + # Speed up Epona escape + rom.write_bytes(0x1FC8B36, [0x00, 0x2A]) + + # Speed up draining the well + rom.write_bytes(0xE0A010, [0x00, 0x2A, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0x2001110, [0x00, 0x2B, 0x00, 0xB7, 0x00, 0xB8, 0x00, 0xB8]) + + # Speed up opening the royal tomb for both child and adult + rom.write_bytes(0x2025026, [0x00, 0x01]) + rom.write_bytes(0x2023C86, [0x00, 0x01]) + rom.write_byte(0x2025159, 0x02) + rom.write_byte(0x2023E19, 0x02) + + #Speed opening of Door of Time + rom.write_bytes(0xE0A176, [0x00, 0x02]) + rom.write_bytes(0xE0A35A, [0x00, 0x01, 0x00, 0x02]) + + # Speed up Lake Hylia Owl Flight + rom.write_bytes(0x20E60D2, [0x00, 0x01]) + + # Speed up Death Mountain Trail Owl Flight + rom.write_bytes(0x223B6B2, [0x00, 0x01]) + + # Poacher's Saw no longer messes up Forest Stage + rom.write_bytes(0xAE72CC, [0x00, 0x00, 0x00, 0x00]) + + # Change Prelude CS to check for medallion + rom.write_bytes(0x00C805E6, [0x00, 0xA6]) + rom.write_bytes(0x00C805F2, [0x00, 0x01]) + + # Change Nocturne CS to check for medallions + rom.write_bytes(0x00ACCD8E, [0x00, 0xA6]) + rom.write_bytes(0x00ACCD92, [0x00, 0x01]) + rom.write_bytes(0x00ACCD9A, [0x00, 0x02]) + rom.write_bytes(0x00ACCDA2, [0x00, 0x04]) + + # Change King Zora to move even if Zora Sapphire is in inventory + rom.write_bytes(0x00E55BB0, [0x85, 0xCE, 0x8C, 0x3C]) + rom.write_bytes(0x00E55BB4, [0x84, 0x4F, 0x0E, 0xDA]) + + # Remove extra Forest Temple medallions + rom.write_bytes(0x00D4D37C, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Fire Temple medallions + rom.write_bytes(0x00AC9754, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0x00D0DB8C, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Water Temple medallions + rom.write_bytes(0x00D57F94, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Spirit Temple medallions + rom.write_bytes(0x00D370C4, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0x00D379C4, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Shadow Temple medallions + rom.write_bytes(0x00D116E0, [0x00, 0x00, 0x00, 0x00]) + + # Change Mido, Saria, and Kokiri to check for Deku Tree complete flag + # bitwise pointer for 0x80 + kokiriAddresses = [0xE52836, 0xE53A56, 0xE51D4E, 0xE51F3E, 0xE51D96, 0xE51E1E, 0xE51E7E, 0xE51EDE, 0xE51FC6, 0xE51F96, 0xE293B6, 0xE29B8E, 0xE62EDA, 0xE630D6, 0xE633AA, 0xE6369E] + for kokiri in kokiriAddresses: + rom.write_bytes(kokiri, [0x8C, 0x0C]) + # Kokiri + rom.write_bytes(0xE52838, [0x94, 0x48, 0x0E, 0xD4]) + rom.write_bytes(0xE53A58, [0x94, 0x49, 0x0E, 0xD4]) + rom.write_bytes(0xE51D50, [0x94, 0x58, 0x0E, 0xD4]) + rom.write_bytes(0xE51F40, [0x94, 0x4B, 0x0E, 0xD4]) + rom.write_bytes(0xE51D98, [0x94, 0x4B, 0x0E, 0xD4]) + rom.write_bytes(0xE51E20, [0x94, 0x4A, 0x0E, 0xD4]) + rom.write_bytes(0xE51E80, [0x94, 0x59, 0x0E, 0xD4]) + rom.write_bytes(0xE51EE0, [0x94, 0x4E, 0x0E, 0xD4]) + rom.write_bytes(0xE51FC8, [0x94, 0x49, 0x0E, 0xD4]) + rom.write_bytes(0xE51F98, [0x94, 0x58, 0x0E, 0xD4]) + # Saria + rom.write_bytes(0xE293B8, [0x94, 0x78, 0x0E, 0xD4]) + rom.write_bytes(0xE29B90, [0x94, 0x68, 0x0E, 0xD4]) + # Mido + rom.write_bytes(0xE62EDC, [0x94, 0x6F, 0x0E, 0xD4]) + rom.write_bytes(0xE630D8, [0x94, 0x4F, 0x0E, 0xD4]) + rom.write_bytes(0xE633AC, [0x94, 0x68, 0x0E, 0xD4]) + rom.write_bytes(0xE636A0, [0x94, 0x48, 0x0E, 0xD4]) + + # Change adult Kokiri Forest to check for Forest Temple complete flag + rom.write_bytes(0xE5369E, [0xB4, 0xAC]) + rom.write_bytes(0xD5A83C, [0x80, 0x49, 0x0E, 0xDC]) + + # Change adult Goron City to check for Fire Temple complete flag + rom.write_bytes(0xED59DC, [0x80, 0xC9, 0x0E, 0xDC]) + + # Change Pokey to check DT complete flag + rom.write_bytes(0xE5400A, [0x8C, 0x4C]) + rom.write_bytes(0xE5400E, [0xB4, 0xA4]) + if world.open_forest != 'closed': + rom.write_bytes(0xE5401C, [0x14, 0x0B]) + + # Fix Shadow Temple to check for different rewards for scene + rom.write_bytes(0xCA3F32, [0x00, 0x00, 0x25, 0x4A, 0x00, 0x10]) + + # Fix Spirit Temple to check for different rewards for scene + rom.write_bytes(0xCA3EA2, [0x00, 0x00, 0x25, 0x4A, 0x00, 0x08]) + + # Fix Biggoron to check a different flag. + rom.write_byte(0xED329B, 0x72) + rom.write_byte(0xED43E7, 0x72) + rom.write_bytes(0xED3370, [0x3C, 0x0D, 0x80, 0x12]) + rom.write_bytes(0xED3378, [0x91, 0xB8, 0xA6, 0x42, 0xA1, 0xA8, 0xA6, 0x42]) + rom.write_bytes(0xED6574, [0x00, 0x00, 0x00, 0x00]) + + # Remove the check on the number of days that passed for claim check. + rom.write_bytes(0xED4470, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xED4498, [0x00, 0x00, 0x00, 0x00]) + + # Fixed reward order for Bombchu Bowling + rom.write_bytes(0xE2E698, [0x80, 0xAA, 0xE2, 0x64]) + rom.write_bytes(0xE2E6A0, [0x80, 0xAA, 0xE2, 0x4C]) + rom.write_bytes(0xE2D440, [0x24, 0x19, 0x00, 0x00]) + + # Offset kakariko carpenter starting position + rom.write_bytes(0x1FF93A4, [0x01, 0x8D, 0x00, 0x11, 0x01, 0x6C, 0xFF, 0x92, 0x00, 0x00, 0x01, 0x78, 0xFF, 0x2E, 0x00, 0x00, 0x00, 0x03, 0xFD, 0x2B, 0x00, 0xC8, 0xFF, 0xF9, 0xFD, 0x03, 0x00, 0xC8, 0xFF, 0xA9, 0xFD, 0x5D, 0x00, 0xC8, 0xFE, 0x5F]) # re order the carpenter's path + rom.write_byte(0x1FF93D0, 0x06) # set the path points to 6 + rom.write_bytes(0x20160B6, [0x01, 0x8D, 0x00, 0x11, 0x01, 0x6C]) # set the carpenter's start position + + # Give hp after first ocarina minigame round + rom.write_bytes(0xDF2204, [0x24, 0x03, 0x00, 0x02]) + + # Allow owl to always carry the kid down Death Mountain + rom.write_bytes(0xE304F0, [0x24, 0x0E, 0x00, 0x01]) + + # Fix Vanilla Dodongo's Cavern Gossip Stone to not use a permanent flag for the fairy + if not world.dungeon_mq['Dodongos Cavern']: + rom.write_byte(0x1F281FE, 0x38) + + # Fix "...???" textbox outside Child Colossus Fairy to use the right flag and disappear once the wall is destroyed + rom.write_byte(0x21A026F, 0xDD) + + # Remove the "...???" textbox outside the Crater Fairy (change it to an actor that does nothing) + rom.write_int16s(0x225E7DC, [0x00B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF]) + + # Forbid Sun's Song from a bunch of cutscenes + Suns_scenes = [0x2016FC9, 0x2017219, 0x20173D9, 0x20174C9, 0x2017679, 0x20C1539, 0x20C15D9, 0x21A0719, 0x21A07F9, 0x2E90129, 0x2E901B9, 0x2E90249, 0x225E829, 0x225E939, 0x306D009] + for address in Suns_scenes: + rom.write_byte(address,0x01) + + # Allow Warp Songs in additional places + rom.write_byte(0xB6D3D2, 0x00) # Gerudo Training Grounds + rom.write_byte(0xB6D42A, 0x00) # Inside Ganon's Castle + + #Tell Sheik at Ice Cavern we are always an Adult + rom.write_int32(0xC7B9C0, 0x00000000) + rom.write_int32(0xC7BAEC, 0x00000000) + rom.write_int32(0xc7BCA4, 0x00000000) + + # Allow Farore's Wind in dungeons where it's normally forbidden + rom.write_byte(0xB6D3D3, 0x00) # Gerudo Training Grounds + rom.write_byte(0xB6D42B, 0x00) # Inside Ganon's Castle + + # Remove disruptive text from Gerudo Training Grounds and early Shadow Temple (vanilla) + Wonder_text = [0x27C00BC, 0x27C00CC, 0x27C00DC, 0x27C00EC, 0x27C00FC, 0x27C010C, 0x27C011C, 0x27C012C, 0x27CE080, + 0x27CE090, 0x2887070, 0x2887080, 0x2887090, 0x2897070, 0x28C7134, 0x28D91BC, 0x28A60F4, 0x28AE084, + 0x28B9174, 0x28BF168, 0x28BF178, 0x28BF188, 0x28A1144, 0x28A6104, 0x28D0094] + for address in Wonder_text: + rom.write_byte(address, 0xFB) + + # Speed dig text for Dampe + rom.write_bytes(0x9532F8, [0x08, 0x08, 0x08, 0x59]) + + # Make item descriptions into a single box + Short_item_descriptions = [0x92EC84, 0x92F9E3, 0x92F2B4, 0x92F37A, 0x92F513, 0x92F5C6, 0x92E93B, 0x92EA12] + for address in Short_item_descriptions: + rom.write_byte(address,0x02) + + et_original = rom.read_bytes(0xB6FBF0, 4 * 0x0614) + + exit_updates = [] + + def copy_entrance_record(source_index, destination_index, count=4): + ti = source_index * 4 + rom.write_bytes(0xB6FBF0 + destination_index * 4, et_original[ti:ti+(4 * count)]) + + def generate_exit_lookup_table(): + # Assumes that the last exit on a scene's exit list cannot be 0000 + exit_table = { + 0x0028: [0xAC95C2] #Jabu with the fish is entered from a cutscene hardcode + } + + def add_scene_exits(scene_start, offset = 0): + current = scene_start + offset + exit_list_start_off = 0 + exit_list_end_off = 0 + command = 0 + + while command != 0x14: + command = rom.read_byte(current) + if command == 0x18: # Alternate header list + header_list = scene_start + (rom.read_int32(current + 4) & 0x00FFFFFF) + for alt_id in range(0,3): + header_offset = rom.read_int32(header_list) & 0x00FFFFFF + if header_offset != 0: + add_scene_exits(scene_start, header_offset) + header_list += 4 + if command == 0x13: # Exit List + exit_list_start_off = rom.read_int32(current + 4) & 0x00FFFFFF + if command == 0x0F: # Lighting list, follows exit list + exit_list_end_off = rom.read_int32(current + 4) & 0x00FFFFFF + current += 8 + + if exit_list_start_off == 0 or exit_list_end_off == 0: + return + + # calculate the exit list length + list_length = (exit_list_end_off - exit_list_start_off) // 2 + last_id = rom.read_int16(scene_start + exit_list_end_off - 2) + if last_id == 0: + list_length -= 1 + + # update + addr = scene_start + exit_list_start_off + for _ in range(0, list_length): + index = rom.read_int16(addr) + if index not in exit_table: + exit_table[index] = [] + exit_table[index].append(addr) + addr += 2 + + scene_table = 0x00B71440 + for scene in range(0x00, 0x65): + scene_start = rom.read_int32(scene_table + (scene * 0x14)); + add_scene_exits(scene_start) + + return exit_table + + + def set_entrance_updates(entrances): + for entrance in entrances: + new_entrance = entrance.data + replaced_entrance = entrance.replaces.data + + exit_updates.append((new_entrance['index'], replaced_entrance['index'])) + + for address in new_entrance.get('addresses', []): + rom.write_int16(address, replaced_entrance['index']) + + if "blue_warp" in new_entrance: + if "blue_warp" in replaced_entrance: + blue_out_data = replaced_entrance["blue_warp"] + else: + blue_out_data = replaced_entrance["index"] + # Blue warps have multiple hardcodes leading to them. The good news is + # the blue warps (excluding deku sprout and lake fill special cases) each + # have a nice consistent 4-entry in the table we can just shuffle. So just + # catch all the hardcode with entrance table rewrite. This covers the + # Forest temple and Water temple blue warp revisits. Deku sprout remains + # vanilla as it never took you to the exit and the lake fill is handled + # above by removing the cutscene completely. Child has problems with Adult + # blue warps, so always use the return entrance if a child. + copy_entrance_record(blue_out_data + 2, new_entrance["blue_warp"] + 2, 2) + copy_entrance_record(replaced_entrance["index"], new_entrance["blue_warp"], 2) + + exit_table = generate_exit_lookup_table() + + if world.entrance_shuffle: + # Disable the fog state entirely to avoid fog glitches + rom.write_byte(rom.sym('NO_FOG_STATE'), 1) + + if world.disable_trade_revert: + # Disable trade quest timers and prevent trade items from ever reverting + rom.write_byte(rom.sym('DISABLE_TIMERS'), 0x01) + rom.write_int16s(0xB6D460, [0x0030, 0x0035, 0x0036]) # Change trade items revert table to prevent all reverts + + if world.shuffle_overworld_entrances: + rom.write_byte(rom.sym('OVERWORLD_SHUFFLED'), 1) + + # Prevent the ocarina cutscene from leading straight to hyrule field + rom.write_byte(rom.sym('OCARINAS_SHUFFLED'), 1) + + # Combine all fence hopping LLR exits to lead to the main LLR exit + for k in [0x028A, 0x028E, 0x0292]: # Southern, Western, Eastern Gates + exit_table[0x01F9] += exit_table[k] # Hyrule Field entrance from Lon Lon Ranch (main land entrance) + del exit_table[k] + exit_table[0x01F9].append(0xD52722) # 0x0476, Front Gate + + # Combine the water exits between Hyrule Field and Zora River to lead to the land entrance instead of the water entrance + exit_table[0x00EA] += exit_table[0x01D9] # Hyrule Field -> Zora River + exit_table[0x0181] += exit_table[0x0311] # Zora River -> Hyrule Field + del exit_table[0x01D9] + del exit_table[0x0311] + + # Change Impa escorts to bring link at the hyrule castle grounds entrance from market, instead of hyrule field + rom.write_int16(0xACAA2E, 0x0138) # 1st Impa escort + rom.write_int16(0xD12D6E, 0x0138) # 2nd+ Impa escort + + if world.shuffle_dungeon_entrances: + rom.write_byte(rom.sym('DUNGEONS_SHUFFLED'), 1) + + # Connect lake hylia fill exit to revisit exit + rom.write_int16(0xAC995A, 0x060C) + + # Tell the well water we are always a child. + rom.write_int32(0xDD5BF4, 0x00000000) + + # Make the Adult well blocking stone dissappear if the well has been drained by + # checking the well drain event flag instead of links age. This actor doesn't need a + # code check for links age as the stone is absent for child via the scene alternate + # lists. So replace the age logic with drain logic. + rom.write_int32(0xE2887C, rom.read_int32(0xE28870)) # relocate this to nop delay slot + rom.write_int32(0xE2886C, 0x95CEB4B0) # lhu + rom.write_int32(0xE28870, 0x31CE0080) # andi + + remove_entrance_blockers(rom) + + # Purge temp flags on entrance to spirit from colossus through the front door. + rom.write_byte(0x021862E3, 0xC2) + + if world.shuffle_overworld_entrances or world.shuffle_dungeon_entrances: + # Remove deku sprout and drop player at SFM after forest completion + rom.write_int16(0xAC9F96, 0x0608) + + if world.spawn_positions: + # Fix save warping inside Link's House to not be a special case + rom.write_int32(0xB06318, 0x00000000) + + # Set entrances to update, except grotto entrances which are handled on their own at a later point + set_entrance_updates(filter(lambda entrance: entrance.type != 'Grotto', world.get_shuffled_entrances())) + + for k, v in [(k,v) for k, v in exit_updates if k in exit_table]: + for addr in exit_table[k]: + rom.write_int16(addr, v) + + # Fix text for Pocket Cucco. + rom.write_byte(0xBEEF45, 0x0B) + + # Fix stupid alcove cameras in Ice Cavern -- thanks to krim and mzx for the help + rom.write_byte(0x2BECA25,0x01) + rom.write_byte(0x2BECA2D,0x01) + + configure_dungeon_info(rom, world) + + hash_icons = 0 + for i,icon in enumerate(world.file_hash): + hash_icons |= (icon << (5 * i)) + rom.write_int32(rom.sym('cfg_file_select_hash'), hash_icons) + + save_context = SaveContext() + + # Initial Save Data + if not world.useful_cutscenes: + save_context.write_bits(0x00D4 + 0x03 * 0x1C + 0x04 + 0x0, 0x08) # Forest Temple switch flag (Poe Sisters cutscene) + save_context.write_bits(0x00D4 + 0x05 * 0x1C + 0x04 + 0x1, 0x01) # Water temple switch flag (Ruto) + save_context.write_bits(0x00D4 + 0x51 * 0x1C + 0x04 + 0x2, 0x08) # Hyrule Field switch flag (Owl) + save_context.write_bits(0x00D4 + 0x55 * 0x1C + 0x04 + 0x0, 0x80) # Kokiri Forest switch flag (Owl) + save_context.write_bits(0x00D4 + 0x56 * 0x1C + 0x04 + 0x2, 0x40) # Sacred Forest Meadow switch flag (Owl) + save_context.write_bits(0x00D4 + 0x5B * 0x1C + 0x04 + 0x2, 0x01) # Lost Woods switch flag (Owl) + save_context.write_bits(0x00D4 + 0x5B * 0x1C + 0x04 + 0x3, 0x80) # Lost Woods switch flag (Owl) + save_context.write_bits(0x00D4 + 0x5C * 0x1C + 0x04 + 0x0, 0x80) # Desert Colossus switch flag (Owl) + save_context.write_bits(0x00D4 + 0x5F * 0x1C + 0x04 + 0x3, 0x20) # Hyrule Castle switch flag (Owl) + + save_context.write_bits(0x0ED4, 0x10) # "Met Deku Tree" + save_context.write_bits(0x0ED5, 0x20) # "Deku Tree Opened Mouth" + save_context.write_bits(0x0ED6, 0x08) # "Rented Horse From Ingo" + save_context.write_bits(0x0ED6, 0x10) # "Spoke to Mido After Deku Tree's Death" + save_context.write_bits(0x0EDA, 0x08) # "Began Nabooru Battle" + save_context.write_bits(0x0EDC, 0x80) # "Entered the Master Sword Chamber" + save_context.write_bits(0x0EDD, 0x20) # "Pulled Master Sword from Pedestal" + save_context.write_bits(0x0EE0, 0x80) # "Spoke to Kaepora Gaebora by Lost Woods" + save_context.write_bits(0x0EE7, 0x20) # "Nabooru Captured by Twinrova" + save_context.write_bits(0x0EE7, 0x10) # "Spoke to Nabooru in Spirit Temple" + save_context.write_bits(0x0EED, 0x20) # "Sheik, Spawned at Master Sword Pedestal as Adult" + save_context.write_bits(0x0EED, 0x01) # "Nabooru Ordered to Fight by Twinrova" + save_context.write_bits(0x0EED, 0x80) # "Watched Ganon's Tower Collapse / Caught by Gerudo" + save_context.write_bits(0x0EF9, 0x01) # "Greeted by Saria" + save_context.write_bits(0x0F0A, 0x04) # "Spoke to Ingo Once as Adult" + save_context.write_bits(0x0F0F, 0x40) # "Met Poe Collector in Ruined Market" + if not world.useful_cutscenes: + save_context.write_bits(0x0F1A, 0x04) # "Met Darunia in Fire Temple" + + save_context.write_bits(0x0ED7, 0x01) # "Spoke to Child Malon at Castle or Market" + save_context.write_bits(0x0ED7, 0x20) # "Spoke to Child Malon at Ranch" + save_context.write_bits(0x0ED7, 0x40) # "Invited to Sing With Child Malon" + save_context.write_bits(0x0F09, 0x10) # "Met Child Malon at Castle or Market" + save_context.write_bits(0x0F09, 0x20) # "Child Malon Said Epona Was Scared of You" + + save_context.write_bits(0x0F21, 0x04) # "Ruto in JJ (M3) Talk First Time" + save_context.write_bits(0x0F21, 0x02) # "Ruto in JJ (M2) Meet Ruto" + + save_context.write_bits(0x0EE2, 0x01) # "Began Ganondorf Battle" + save_context.write_bits(0x0EE3, 0x80) # "Began Bongo Bongo Battle" + save_context.write_bits(0x0EE3, 0x40) # "Began Barinade Battle" + save_context.write_bits(0x0EE3, 0x20) # "Began Twinrova Battle" + save_context.write_bits(0x0EE3, 0x10) # "Began Morpha Battle" + save_context.write_bits(0x0EE3, 0x08) # "Began Volvagia Battle" + save_context.write_bits(0x0EE3, 0x04) # "Began Phantom Ganon Battle" + save_context.write_bits(0x0EE3, 0x02) # "Began King Dodongo Battle" + save_context.write_bits(0x0EE3, 0x01) # "Began Gohma Battle" + + save_context.write_bits(0x0EE8, 0x01) # "Entered Deku Tree" + save_context.write_bits(0x0EE9, 0x80) # "Entered Temple of Time" + save_context.write_bits(0x0EE9, 0x40) # "Entered Goron City" + save_context.write_bits(0x0EE9, 0x20) # "Entered Hyrule Castle" + save_context.write_bits(0x0EE9, 0x10) # "Entered Zora's Domain" + save_context.write_bits(0x0EE9, 0x08) # "Entered Kakariko Village" + save_context.write_bits(0x0EE9, 0x02) # "Entered Death Mountain Trail" + save_context.write_bits(0x0EE9, 0x01) # "Entered Hyrule Field" + save_context.write_bits(0x0EEA, 0x04) # "Entered Ganon's Castle (Exterior)" + save_context.write_bits(0x0EEA, 0x02) # "Entered Death Mountain Crater" + save_context.write_bits(0x0EEA, 0x01) # "Entered Desert Colossus" + save_context.write_bits(0x0EEB, 0x80) # "Entered Zora's Fountain" + save_context.write_bits(0x0EEB, 0x40) # "Entered Graveyard" + save_context.write_bits(0x0EEB, 0x20) # "Entered Jabu-Jabu's Belly" + save_context.write_bits(0x0EEB, 0x10) # "Entered Lon Lon Ranch" + save_context.write_bits(0x0EEB, 0x08) # "Entered Gerudo's Fortress" + save_context.write_bits(0x0EEB, 0x04) # "Entered Gerudo Valley" + save_context.write_bits(0x0EEB, 0x02) # "Entered Lake Hylia" + save_context.write_bits(0x0EEB, 0x01) # "Entered Dodongo's Cavern" + save_context.write_bits(0x0F08, 0x08) # "Entered Hyrule Castle" + + # Set the number of chickens to collect + rom.write_byte(0x00E1E523, world.chicken_count) + + # Change Anju to always say how many chickens are needed + # Does not affect text for collecting item or afterwards + rom.write_int16(0x00E1F3C2, 0x5036) + rom.write_int16(0x00E1F3C4, 0x5036) + rom.write_int16(0x00E1F3C6, 0x5036) + rom.write_int16(0x00E1F3C8, 0x5036) + rom.write_int16(0x00E1F3CA, 0x5036) + rom.write_int16(0x00E1F3CC, 0x5036) + + # Make the Kakariko Gate not open with the MS + if world.open_kakariko != 'open': + rom.write_int32(0xDD3538, 0x34190000) # li t9, 0 + if world.open_kakariko != 'closed': + rom.write_byte(rom.sym('OPEN_KAKARIKO'), 1) + + if world.complete_mask_quest: + rom.write_byte(rom.sym('COMPLETE_MASK_QUEST'), 1) + + if world.skip_child_zelda: + save_context.give_item('Zeldas Letter') + # Archipelago forces this item to be local so it can always be given to the player. Usually it's a song so it's no problem. + item = world.get_location('Song from Impa').item + save_context.give_raw_item(item.name) + save_context.write_bits(0x0ED7, 0x04) # "Obtained Malon's Item" + save_context.write_bits(0x0ED7, 0x08) # "Woke Talon in castle" + save_context.write_bits(0x0ED7, 0x10) # "Talon has fled castle" + save_context.write_bits(0x0EDD, 0x01) # "Obtained Zelda's Letter" + save_context.write_bits(0x0EDE, 0x02) # "Learned Zelda's Lullaby" + save_context.write_bits(0x00D4 + 0x5F * 0x1C + 0x04 + 0x3, 0x10) # "Moved crates to access the courtyard" + if world.open_kakariko != 'closed': + save_context.write_bits(0x0F07, 0x40) # "Spoke to Gate Guard About Mask Shop" + if world.complete_mask_quest: + save_context.write_bits(0x0F07, 0x80) # "Soldier Wears Keaton Mask" + save_context.write_bits(0x0EF6, 0x8F) # "Sold Masks & Unlocked Masks" / "Obtained Mask of Truth" + save_context.write_bits(0x0EE4, 0xF0) # "Paid Back Mask Fees" + + if world.zora_fountain == 'open': + save_context.write_bits(0x0EDB, 0x08) # "Moved King Zora" + elif world.zora_fountain == 'adult': + rom.write_byte(rom.sym('MOVED_ADULT_KING_ZORA'), 1) + + # Make all chest opening animations fast + rom.write_byte(rom.sym('FAST_CHESTS'), int(world.fast_chests)) + + + # Set up Rainbow Bridge conditions + symbol = rom.sym('RAINBOW_BRIDGE_CONDITION') + count_symbol = rom.sym('RAINBOW_BRIDGE_COUNT') + if world.bridge == 'open': + rom.write_int32(symbol, 0) + save_context.write_bits(0xEDC, 0x20) # "Rainbow Bridge Built by Sages" + elif world.bridge == 'medallions': + rom.write_int32(symbol, 1) + rom.write_int16(count_symbol, world.bridge_medallions) + elif world.bridge == 'dungeons': + rom.write_int32(symbol, 2) + rom.write_int16(count_symbol, world.bridge_rewards) + elif world.bridge == 'stones': + rom.write_int32(symbol, 3) + rom.write_int16(count_symbol, world.bridge_stones) + elif world.bridge == 'vanilla': + rom.write_int32(symbol, 4) + elif world.bridge == 'tokens': + rom.write_int32(symbol, 5) + rom.write_int16(count_symbol, world.bridge_tokens) + + if world.triforce_hunt: + rom.write_int16(rom.sym('triforce_pieces_requied'), world.triforce_goal) + rom.write_int16(rom.sym('triforce_hunt_enabled'), 1) + + # Set up LACS conditions. + symbol = rom.sym('LACS_CONDITION') + count_symbol = rom.sym('LACS_CONDITION_COUNT') + if world.lacs_condition == 'medallions': + rom.write_int32(symbol, 1) + rom.write_int16(count_symbol, world.lacs_medallions) + elif world.lacs_condition == 'dungeons': + rom.write_int32(symbol, 2) + rom.write_int16(count_symbol, world.lacs_rewards) + elif world.lacs_condition == 'stones': + rom.write_int32(symbol, 3) + rom.write_int16(count_symbol, world.lacs_stones) + elif world.lacs_condition == 'tokens': + rom.write_int32(symbol, 4) + rom.write_int16(count_symbol, world.lacs_tokens) + else: + rom.write_int32(symbol, 0) + + if world.open_forest == 'open': + save_context.write_bits(0xED5, 0x10) # "Showed Mido Sword & Shield" + + if world.open_door_of_time: + save_context.write_bits(0xEDC, 0x08) # "Opened the Door of Time" + + # "fast-ganon" stuff + symbol = rom.sym('NO_ESCAPE_SEQUENCE') + if world.no_escape_sequence: + rom.write_bytes(0xD82A12, [0x05, 0x17]) # Sets exit from Ganondorf fight to entrance to Ganon fight + rom.write_bytes(0xB139A2, [0x05, 0x17]) # Sets Ganon deathwarp back to Ganon + rom.write_byte(symbol, 0x01) + else: + rom.write_byte(symbol, 0x00) + if world.skipped_trials['Forest']: + save_context.write_bits(0x0EEA, 0x08) # "Completed Forest Trial" + if world.skipped_trials['Fire']: + save_context.write_bits(0x0EEA, 0x40) # "Completed Fire Trial" + if world.skipped_trials['Water']: + save_context.write_bits(0x0EEA, 0x10) # "Completed Water Trial" + if world.skipped_trials['Spirit']: + save_context.write_bits(0x0EE8, 0x20) # "Completed Spirit Trial" + if world.skipped_trials['Shadow']: + save_context.write_bits(0x0EEA, 0x20) # "Completed Shadow Trial" + if world.skipped_trials['Light']: + save_context.write_bits(0x0EEA, 0x80) # "Completed Light Trial" + if world.trials == 0: + save_context.write_bits(0x0EED, 0x08) # "Dispelled Ganon's Tower Barrier" + + # open gerudo fortress + if world.gerudo_fortress == 'open': + if not world.shuffle_gerudo_card: + save_context.write_bits(0x00A5, 0x40) # Give Gerudo Card + save_context.write_bits(0x0EE7, 0x0F) # Free all 4 carpenters + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x04 + 0x1, 0x0F) # Thieves' Hideout switch flags (started all fights) + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x04 + 0x2, 0x01) # Thieves' Hideout switch flags (heard yells/unlocked doors) + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x04 + 0x3, 0xFE) # Thieves' Hideout switch flags (heard yells/unlocked doors) + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x0C + 0x2, 0xD4) # Thieves' Hideout collection flags (picked up keys, marks fights finished as well) + elif world.gerudo_fortress == 'fast': + save_context.write_bits(0x0EE7, 0x0E) # Free 3 carpenters + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x04 + 0x1, 0x0D) # Thieves' Hideout switch flags (started all fights) + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x04 + 0x2, 0x01) # Thieves' Hideout switch flags (heard yells/unlocked doors) + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x04 + 0x3, 0xDC) # Thieves' Hideout switch flags (heard yells/unlocked doors) + save_context.write_bits(0x00D4 + 0x0C * 0x1C + 0x0C + 0x2, 0xC4) # Thieves' Hideout collection flags (picked up keys, marks fights finished as well) + + # Add a gate-opening guard on the Wasteland side of the Gerudo gate when the card is shuffled or certain levels of ER. + # Overrides the generic guard at the bottom of the ladder in Gerudo Fortress + if world.shuffle_gerudo_card or world.shuffle_overworld_entrances or \ + world.shuffle_special_interior_entrances or world.spawn_positions: + # Add a gate opening guard on the Wasteland side of the Gerudo Fortress' gate + new_gate_opening_guard = [0x0138, 0xFAC8, 0x005D, 0xF448, 0x0000, 0x95B0, 0x0000, 0x0301] + rom.write_int16s(0x21BD3EC, new_gate_opening_guard) # Adult Day + rom.write_int16s(0x21BD62C, new_gate_opening_guard) # Adult Night + + # start with maps/compasses + if world.shuffle_mapcompass == 'startwith': + for dungeon in ['deku', 'dodongo', 'jabu', 'forest', 'fire', 'water', 'spirit', 'shadow', 'botw', 'ice']: + save_context.addresses['dungeon_items'][dungeon]['compass'].value = True + save_context.addresses['dungeon_items'][dungeon]['map'].value = True + + if world.shuffle_smallkeys == 'vanilla': + if world.dungeon_mq['Spirit Temple']: + save_context.addresses['keys']['spirit'].value = 3 + + if world.start_with_rupees: + rom.write_byte(rom.sym('MAX_RUPEES'), 0x01) + + # Set starting time of day + if world.starting_tod != 'default': + tod = { + 'sunrise': 0x4555, + 'morning': 0x6000, + 'noon': 0x8001, + 'afternoon': 0xA000, + 'sunset': 0xC001, + 'evening': 0xE000, + 'midnight': 0x0000, + 'witching-hour': 0x2000, + + } + save_context.addresses['time_of_day'].value = tod[world.starting_tod] + + if world.starting_age == 'adult': + save_context.addresses['link_age'].value = False # Set link's age to adult + save_context.addresses['scene_index'].value = 0x43 # Set the scene index to Temple of Time + save_context.addresses['equip_items']['master_sword'].value = True # Equip Master Sword by default + save_context.addresses['equip_items']['kokiri_tunic'].value = True # Equip Kokiri Tunic & Kokiri Boots by default + save_context.addresses['equip_items']['kokiri_boots'].value = True # (to avoid issues when going back child for the first time) + save_context.write_byte(0x0F33, 0x00) # Unset Swordless Flag (to avoid issues with sword getting unequipped) + + # Revert change that Skips the Epona Race + if not world.no_epona_race: + rom.write_int32(0xA9E838, 0x03E00008) + else: + save_context.write_bits(0xF0E, 0x01) # Set talked to Malon flag + + # skip castle guard stealth sequence + if world.no_guard_stealth: + # change the exit at child/day crawlspace to the end of zelda's goddess cutscene + rom.write_bytes(0x21F60DE, [0x05, 0xF0]) + + # patch mq scenes + mq_scenes = [] + if world.dungeon_mq['Deku Tree']: + mq_scenes.append(0) + if world.dungeon_mq['Dodongos Cavern']: + mq_scenes.append(1) + if world.dungeon_mq['Jabu Jabus Belly']: + mq_scenes.append(2) + if world.dungeon_mq['Forest Temple']: + mq_scenes.append(3) + if world.dungeon_mq['Fire Temple']: + mq_scenes.append(4) + if world.dungeon_mq['Water Temple']: + mq_scenes.append(5) + if world.dungeon_mq['Spirit Temple']: + mq_scenes.append(6) + if world.dungeon_mq['Shadow Temple']: + mq_scenes.append(7) + if world.dungeon_mq['Bottom of the Well']: + mq_scenes.append(8) + if world.dungeon_mq['Ice Cavern']: + mq_scenes.append(9) + # Scene 10 has no layout changes, so it doesn't need to be patched + if world.dungeon_mq['Gerudo Training Grounds']: + mq_scenes.append(11) + if world.dungeon_mq['Ganons Castle']: + mq_scenes.append(13) + + patch_files(rom, mq_scenes) + + ### Load Shop File + # Move shop actor file to free space + shop_item_file = File({ + 'Name':'En_GirlA', + 'Start':'00C004E0', + 'End':'00C02E00', + }) + shop_item_file.relocate(rom) + + # Increase the shop item table size + shop_item_vram_start = rom.read_int32(0x00B5E490 + (0x20 * 4) + 0x08) + insert_space(rom, shop_item_file, shop_item_vram_start, 1, 0x3C + (0x20 * 50), 0x20 * 50) + + # Add relocation entries for shop item table + new_relocations = [] + for i in range(50, 100): + new_relocations.append(shop_item_file.start + 0x1DEC + (i * 0x20) + 0x04) + new_relocations.append(shop_item_file.start + 0x1DEC + (i * 0x20) + 0x14) + new_relocations.append(shop_item_file.start + 0x1DEC + (i * 0x20) + 0x1C) + add_relocations(rom, shop_item_file, new_relocations) + + # update actor table + rom.write_int32s(0x00B5E490 + (0x20 * 4), + [shop_item_file.start, + shop_item_file.end, + shop_item_vram_start, + shop_item_vram_start + (shop_item_file.end - shop_item_file.start)]) + + # Update DMA Table + update_dmadata(rom, shop_item_file) + + # Create 2nd Bazaar Room + bazaar_room_file = File({ + 'Name':'shop1_room_1', + 'Start':'028E4000', + 'End':'0290D7B0', + }) + bazaar_room_file.copy(rom) + + # Add new Bazaar Room to Bazaar Scene + rom.write_int32s(0x28E3030, [0x00010000, 0x02000058]) #reduce position list size + rom.write_int32s(0x28E3008, [0x04020000, 0x02000070]) #expand room list size + + rom.write_int32s(0x28E3070, [0x028E4000, 0x0290D7B0, + bazaar_room_file.start, bazaar_room_file.end]) #room list + rom.write_int16s(0x28E3080, [0x0000, 0x0001]) # entrance list + rom.write_int16(0x28E4076, 0x0005) # Change shop to Kakariko Bazaar + #rom.write_int16(0x3489076, 0x0005) # Change shop to Kakariko Bazaar + + # Load Message and Shop Data + messages = read_messages(rom) + remove_unused_messages(messages) + shop_items = read_shop_items(rom, shop_item_file.start + 0x1DEC) + + # Set Big Poe count to get reward from buyer + poe_points = world.big_poe_count * 100 + rom.write_int16(0xEE69CE, poe_points) + # update dialogue + new_message = "\x08Hey, young man. What's happening \x01today? If you have a \x05\x41Poe\x05\x40, I will \x01buy it.\x04\x1AIf you earn \x05\x41%d points\x05\x40, you'll\x01be a happy man! Heh heh.\x04\x08Your card now has \x05\x45\x1E\x01 \x05\x40points.\x01Come back again!\x01Heh heh heh!\x02" % poe_points + update_message_by_id(messages, 0x70F5, new_message) + if world.big_poe_count != 10: + new_message = "\x1AOh, you brought a Poe today!\x04\x1AHmmmm!\x04\x1AVery interesting!\x01This is a \x05\x41Big Poe\x05\x40!\x04\x1AI'll buy it for \x05\x4150 Rupees\x05\x40.\x04On top of that, I'll put \x05\x41100\x01points \x05\x40on your card.\x04\x1AIf you earn \x05\x41%d points\x05\x40, you'll\x01be a happy man! Heh heh." % poe_points + update_message_by_id(messages, 0x70f7, new_message) + new_message = "\x1AWait a minute! WOW!\x04\x1AYou have earned \x05\x41%d points\x05\x40!\x04\x1AYoung man, you are a genuine\x01\x05\x41Ghost Hunter\x05\x40!\x04\x1AIs that what you expected me to\x01say? Heh heh heh!\x04\x1ABecause of you, I have extra\x01inventory of \x05\x41Big Poes\x05\x40, so this will\x01be the last time I can buy a \x01ghost.\x04\x1AYou're thinking about what I \x01promised would happen when you\x01earned %d points. Heh heh.\x04\x1ADon't worry, I didn't forget.\x01Just take this." % (poe_points, poe_points) + update_message_by_id(messages, 0x70f8, new_message) + + # Update Child Anju's dialogue + new_message = "\x08What should I do!?\x01My \x05\x41Cuccos\x05\x40 have all flown away!\x04You, little boy, please!\x01Please gather at least \x05\x41%d Cuccos\x05\x40\x01for me.\x02" % world.chicken_count + update_message_by_id(messages, 0x5036, new_message) + + # Update "Princess Ruto got the Spiritual Stone!" text before the midboss in Jabu + reward_text = {'Kokiri Emerald': "\x05\x42Kokiri Emerald\x05\x40", + 'Goron Ruby': "\x05\x41Goron Ruby\x05\x40", + 'Zora Sapphire': "\x05\x43Zora Sapphire\x05\x40", + 'Forest Medallion': "\x05\x42Forest Medallion\x05\x40", + 'Fire Medallion': "\x05\x41Fire Medallion\x05\x40", + 'Water Medallion': "\x05\x43Water Medallion\x05\x40", + 'Spirit Medallion': "\x05\x46Spirit Medallion\x05\x40", + 'Shadow Medallion': "\x05\x45Shadow Medallion\x05\x40", + 'Light Medallion': "\x05\x44Light Medallion\x05\x40" + } + new_message = "\x1a\x08Princess Ruto got the \x01%s!\x09\x01\x14\x02But\x14\x00 why Princess Ruto?\x02" % reward_text[world.get_location('Barinade').item.name] + update_message_by_id(messages, 0x4050, new_message) + + # use faster jabu elevator + if not world.dungeon_mq['Jabu Jabus Belly'] and world.shuffle_scrubs == 'off': + symbol = rom.sym('JABU_ELEVATOR_ENABLE') + rom.write_byte(symbol, 0x01) + + if world.skip_some_minigame_phases: + save_context.write_bits(0x00D4 + 0x48 * 0x1C + 0x08 + 0x3, 0x10) # Beat First Dampe Race (& Chest Spawned) + rom.write_byte(rom.sym('CHAIN_HBA_REWARDS'), 1) + # Update the first horseback archery text to make it clear both rewards are available from the start + update_message_by_id(messages, 0x6040, "Hey newcomer, you have a fine \x01horse!\x04I don't know where you stole \x01it from, but...\x04OK, how about challenging this \x01\x05\x41horseback archery\x05\x40?\x04Once the horse starts galloping,\x01shoot the targets with your\x01arrows. \x04Let's see how many points you \x01can score. You get 20 arrows.\x04If you can score \x05\x411,000 points\x05\x40, I will \x01give you something good! And even \x01more if you score \x05\x411,500 points\x05\x40!\x0B\x02") + + # Sets hooks for gossip stone changes + + symbol = rom.sym("GOSSIP_HINT_CONDITION"); + + if world.hints == 'none': + rom.write_int32(symbol, 0) + else: + writeGossipStoneHints(world, messages) + + if world.hints == 'mask': + rom.write_int32(symbol, 0) + elif world.hints == 'always': + rom.write_int32(symbol, 2) + else: + rom.write_int32(symbol, 1) + + + # build silly ganon lines + if world.misc_hints: + buildGanonText(world, messages) + + # Write item overrides + override_table = get_override_table(world) + rom.write_bytes(rom.sym('cfg_item_overrides'), get_override_table_bytes(override_table)) + rom.write_byte(rom.sym('PLAYER_ID'), world.player) # Write player ID + rom.write_bytes(rom.sym('AP_PLAYER_NAME'), bytearray(world.world.get_player_name(world.player), 'ascii')) + + # Revert Song Get Override Injection + if not songs_as_items: + # general get song + rom.write_int32(0xAE5DF8, 0x240200FF) + rom.write_int32(0xAE5E04, 0xAD0F00A4) + # requiem of spirit + rom.write_int32s(0xAC9ABC, [0x3C010001, 0x00300821]) + # sun song + rom.write_int32(0xE09F68, 0x8C6F00A4) + rom.write_int32(0xE09F74, 0x01CFC024) + rom.write_int32(0xE09FB0, 0x240F0001) + # song of time + rom.write_int32(0xDB532C, 0x24050003) + + + # Set damage multiplier + if world.damage_multiplier == 'half': + rom.write_byte(rom.sym('CFG_DAMAGE_MULTIPLYER'), 0xFF) + if world.damage_multiplier == 'normal': + rom.write_byte(rom.sym('CFG_DAMAGE_MULTIPLYER'), 0) + if world.damage_multiplier == 'double': + rom.write_byte(rom.sym('CFG_DAMAGE_MULTIPLYER'), 1) + if world.damage_multiplier == 'quadruple': + rom.write_byte(rom.sym('CFG_DAMAGE_MULTIPLYER'), 2) + if world.damage_multiplier == 'ohko': + rom.write_byte(rom.sym('CFG_DAMAGE_MULTIPLYER'), 3) + + # Patch songs and boss rewards + for location in world.world.get_filled_locations(world.player): + item = location.item + special = item.special if item.game == 'Ocarina of Time' else {} # this shouldn't matter hopefully + locationaddress = location.address1 + secondaryaddress = location.address2 + + if location.type == 'Song' and not songs_as_items: + bit_mask_pointer = 0x8C34 + ((special['item_id'] - 0x65) * 4) + rom.write_byte(locationaddress, special['song_id']) + next_song_id = special['song_id'] + 0x0D + rom.write_byte(secondaryaddress, next_song_id) + if location.name == 'Song from Impa': + rom.write_byte(0x0D12ECB, special['item_id']) + rom.write_byte(0x2E8E931, special['text_id']) #Fix text box + elif location.name == 'Song from Malon': + rom.write_byte(rom.sym('MALON_TEXT_ID'), special['text_id']) + elif location.name == 'Song from Composers Grave': + rom.write_int16(0xE09F66, bit_mask_pointer) + rom.write_byte(0x332A87D, special['text_id']) #Fix text box + elif location.name == 'Song from Saria': + rom.write_byte(0x0E2A02B, special['item_id']) + rom.write_byte(0x20B1DBD, special['text_id']) #Fix text box + elif location.name == 'Song from Ocarina of Time': + rom.write_byte(0x252FC95, special['text_id']) #Fix text box + elif location.name == 'Song from Windmill': + rom.write_byte(rom.sym('WINDMILL_SONG_ID'), next_song_id) + rom.write_byte(rom.sym('WINDMILL_TEXT_ID'), special['text_id']) + elif location.name == 'Sheik in Forest': + rom.write_byte(0x0C7BAA3, special['item_id']) + rom.write_byte(0x20B0815, special['text_id']) #Fix text box + elif location.name == 'Sheik at Temple': + rom.write_byte(0x0C805EF, special['item_id']) + rom.write_byte(0x2531335, special['text_id']) #Fix text box + elif location.name == 'Sheik in Crater': + rom.write_byte(0x0C7BC57, special['item_id']) + rom.write_byte(0x224D7FD, special['text_id']) #Fix text box + elif location.name == 'Sheik in Ice Cavern': + rom.write_byte(0x0C7BD77, special['item_id']) + rom.write_byte(0x2BEC895, special['text_id']) #Fix text box + elif location.name == 'Sheik in Kakariko': + rom.write_byte(0x0AC9A5B, special['item_id']) + rom.write_byte(0x2000FED, special['text_id']) #Fix text box + elif location.name == 'Sheik at Colossus': + rom.write_byte(0x218C589, special['text_id']) #Fix text box + elif location.type == 'Boss': + if location.name == 'Links Pocket': + save_context.give_item(item.name) + else: + rom.write_byte(locationaddress, special['item_id']) + rom.write_byte(secondaryaddress, special['addr2_data']) + bit_mask_hi = special['bit_mask'] >> 16 + bit_mask_lo = special['bit_mask'] & 0xFFFF + if location.name == 'Bongo Bongo': + rom.write_int16(0xCA3F32, bit_mask_hi) + rom.write_int16(0xCA3F36, bit_mask_lo) + elif location.name == 'Twinrova': + rom.write_int16(0xCA3EA2, bit_mask_hi) + rom.write_int16(0xCA3EA6, bit_mask_lo) + + # add a cheaper bombchu pack to the bombchu shop + # describe + update_message_by_id(messages, 0x80FE, '\x08\x05\x41Bombchu (5 pieces) 60 Rupees\x01\x05\x40This looks like a toy mouse, but\x01it\'s actually a self-propelled time\x01bomb!\x09\x0A', 0x03) + # purchase + update_message_by_id(messages, 0x80FF, '\x08Bombchu 5 Pieces 60 Rupees\x01\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x09', 0x03) + rbl_bombchu = shop_items[0x0018] + rbl_bombchu.price = 60 + rbl_bombchu.pieces = 5 + rbl_bombchu.get_item_id = 0x006A + rbl_bombchu.description_message = 0x80FE + rbl_bombchu.purchase_message = 0x80FF + + # Reduce 10 Pack Bombchus from 100 to 99 Rupees + shop_items[0x0015].price = 99 + shop_items[0x0019].price = 99 + shop_items[0x001C].price = 99 + update_message_by_id(messages, shop_items[0x001C].description_message, "\x08\x05\x41Bombchu (10 pieces) 99 Rupees\x01\x05\x40This looks like a toy mouse, but\x01it's actually a self-propelled time\x01bomb!\x09\x0A") + update_message_by_id(messages, shop_items[0x001C].purchase_message, "\x08Bombchu 10 pieces 99 Rupees\x09\x01\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40") + + shuffle_messages.shop_item_messages = [] + + # kokiri shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('KF Kokiri Shop').locations, True) + shop_objs |= {0x00FC, 0x00B2, 0x0101, 0x0102, 0x00FD, 0x00C5} # Shop objects + rom.write_byte(0x2587029, len(shop_objs)) + rom.write_int32(0x258702C, 0x0300F600) + rom.write_int16s(0x2596600, list(shop_objs)) + + # kakariko bazaar + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Kak Bazaar').locations) + shop_objs |= {0x005B, 0x00B2, 0x00C5, 0x0107, 0x00C9, 0x016B} # Shop objects + rom.write_byte(0x28E4029, len(shop_objs)) + rom.write_int32(0x28E402C, 0x03007A40) + rom.write_int16s(0x28EBA40, list(shop_objs)) + + # castle town bazaar + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Market Bazaar').locations) + shop_objs |= {0x005B, 0x00B2, 0x00C5, 0x0107, 0x00C9, 0x016B} # Shop objects + rom.write_byte(bazaar_room_file.start + 0x29, len(shop_objs)) + rom.write_int32(bazaar_room_file.start + 0x2C, 0x03007A40) + rom.write_int16s(bazaar_room_file.start + 0x7A40, list(shop_objs)) + + # goron shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('GC Shop').locations) + shop_objs |= {0x00C9, 0x00B2, 0x0103, 0x00AF} # Shop objects + rom.write_byte(0x2D33029, len(shop_objs)) + rom.write_int32(0x2D3302C, 0x03004340) + rom.write_int16s(0x2D37340, list(shop_objs)) + + # zora shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('ZD Shop').locations) + shop_objs |= {0x005B, 0x00B2, 0x0104, 0x00FE} # Shop objects + rom.write_byte(0x2D5B029, len(shop_objs)) + rom.write_int32(0x2D5B02C, 0x03004B40) + rom.write_int16s(0x2D5FB40, list(shop_objs)) + + # kakariko potion shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Kak Potion Shop Front').locations) + shop_objs |= {0x0159, 0x00B2, 0x0175, 0x0122} # Shop objects + rom.write_byte(0x2D83029, len(shop_objs)) + rom.write_int32(0x2D8302C, 0x0300A500) + rom.write_int16s(0x2D8D500, list(shop_objs)) + + # market potion shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Market Potion Shop').locations) + shop_objs |= {0x0159, 0x00B2, 0x0175, 0x00C5, 0x010C, 0x016B} # Shop objects + rom.write_byte(0x2DB0029, len(shop_objs)) + rom.write_int32(0x2DB002C, 0x03004E40) + rom.write_int16s(0x2DB4E40, list(shop_objs)) + + # bombchu shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Market Bombchu Shop').locations) + shop_objs |= {0x0165, 0x00B2} # Shop objects + rom.write_byte(0x2DD8029, len(shop_objs)) + rom.write_int32(0x2DD802C, 0x03006A40) + rom.write_int16s(0x2DDEA40, list(shop_objs)) + + # Scrub text stuff. + def update_scrub_text(message, text_replacement, default_price, price, item_name=None): + scrub_strip_text = ["some ", "1 piece ", "5 pieces ", "30 pieces "] + for text in scrub_strip_text: + message = message.replace(text.encode(), b'') + message = message.replace(text_replacement[0].encode(), text_replacement[1].encode()) + message = message.replace(b'they are', b'it is') + if default_price != price: + message = message.replace(('%d Rupees' % default_price).encode(), ('%d Rupees' % price).encode()) + if item_name is not None: + message = message.replace(b'mysterious item', item_name.encode()) + return message + + single_item_scrubs = { + 0x3E: world.get_location("HF Deku Scrub Grotto"), + 0x77: world.get_location("LW Deku Scrub Near Bridge"), + 0x79: world.get_location("LW Deku Scrub Grotto Front"), + } + + scrub_message_dict = {} + if world.shuffle_scrubs == 'off': + # Revert Deku Scrubs changes + rom.write_int32s(0xEBB85C, [ + 0x24010002, # addiu at, zero, 2 + 0x3C038012, # lui v1, 0x8012 + 0x14410004, # bne v0, at, 0xd8 + 0x2463A5D0, # addiu v1, v1, -0x5a30 + 0x94790EF0])# lhu t9, 0xef0(v1) + rom.write_int32(0xDF7CB0, + 0xA44F0EF0) # sh t7, 0xef0(v0) + + # Replace scrub text for 3 default shuffled scrubs. + for (scrub_item, default_price, text_id, text_replacement) in business_scrubs: + if scrub_item not in single_item_scrubs.keys(): + continue + scrub_message_dict[text_id] = update_scrub_text(get_message_by_id(messages, text_id).raw_text, text_replacement, default_price, default_price) + else: + # Rebuild Business Scrub Item Table + rom.seek_address(0xDF8684) + for (scrub_item, default_price, text_id, text_replacement) in business_scrubs: + price = world.scrub_prices[scrub_item] + rom.write_int16(None, price) # Price + rom.write_int16(None, 1) # Count + rom.write_int32(None, scrub_item) # Item + rom.write_int32(None, 0x80A74FF8) # Can_Buy_Func + rom.write_int32(None, 0x80A75354) # Buy_Func + + scrub_message_dict[text_id] = update_scrub_text(get_message_by_id(messages, text_id).raw_text, text_replacement, default_price, price) + + # update actor IDs + set_deku_salesman_data(rom) + + # Update scrub messages. + shuffle_messages.scrubs_message_ids = [] + for text_id, message in scrub_message_dict.items(): + update_message_by_id(messages, text_id, message) + if world.shuffle_scrubs == 'random': + shuffle_messages.scrubs_message_ids.append(text_id) + + if world.shuffle_grotto_entrances: + # Build the Grotto Load Table based on grotto entrance data + for entrance in world.get_shuffled_entrances(type='Grotto'): + if entrance.primary: + load_table_pointer = rom.sym('GROTTO_LOAD_TABLE') + 4 * entrance.data['grotto_id'] + rom.write_int16(load_table_pointer, entrance.data['entrance']) + rom.write_byte(load_table_pointer + 2, entrance.data['content']) + + # Update grotto actors based on their new entrance + set_grotto_shuffle_data(rom, world) + + if world.shuffle_cows: + rom.write_byte(rom.sym('SHUFFLE_COWS'), 0x01) + # Move some cows because they are too close from each other in vanilla + rom.write_bytes(0x33650CA, [0xFE, 0xD3, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x4A, 0x34]) # LLR Tower right cow + rom.write_bytes(0x2C550AE, [0x00, 0x82]) # LLR Stable right cow + set_cow_id_data(rom, world) + + if world.shuffle_beans: + rom.write_byte(rom.sym('SHUFFLE_BEANS'), 0x01) + # Update bean salesman messages to better fit the fact that he sells a randomized item + update_message_by_id(messages, 0x405E, "\x1AChomp chomp chomp...\x01We have... \x05\x41a mysterious item\x05\x40! \x01Do you want it...huh? Huh?\x04\x05\x41\x0860 Rupees\x05\x40 and it's yours!\x01Keyahahah!\x01\x1B\x05\x42Yes\x01No\x05\x40\x02") + update_message_by_id(messages, 0x4069, "You don't have enough money.\x01I can't sell it to you.\x01Chomp chomp...\x02") + update_message_by_id(messages, 0x406C, "We hope you like it!\x01Chomp chomp chomp.\x02") + # Change first magic bean to cost 60 (is used as the price for the one time item when beans are shuffled) + rom.write_byte(0xE209FD, 0x3C) + + if world.shuffle_medigoron_carpet_salesman: + rom.write_byte(rom.sym('SHUFFLE_CARPET_SALESMAN'), 0x01) + # Update carpet salesman messages to better fit the fact that he sells a randomized item + update_message_by_id(messages, 0x6077, "\x06\x41Well Come!\x04I am selling stuff, strange and \x01rare, from all over the world to \x01everybody.\x01Today's special is...\x04A mysterious item! \x01Intriguing! \x01I won't tell you what it is until \x01I see the money....\x04How about \x05\x41200 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02") + update_message_by_id(messages, 0x6078, "Thank you very much!\x04The mark that will lead you to\x01the Spirit Temple is the \x05\x41flag on\x01the left \x05\x40outside the shop.\x01Be seeing you!\x02") + + rom.write_byte(rom.sym('SHUFFLE_MEDIGORON'), 0x01) + # Update medigoron messages to better fit the fact that he sells a randomized item + update_message_by_id(messages, 0x304C, "I have something cool right here.\x01How about it...\x07\x30\x4F\x02") + update_message_by_id(messages, 0x304D, "How do you like it?\x02") + update_message_by_id(messages, 0x304F, "How about buying this cool item for \x01200 Rupees?\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02") + + if world.shuffle_smallkeys == 'remove' or world.shuffle_bosskeys == 'remove' or world.shuffle_ganon_bosskey == 'remove': + locked_doors = get_locked_doors(rom, world) + for _,[door_byte, door_bits] in locked_doors.items(): + save_context.write_bits(door_byte, door_bits) + + # Fix chest animations + if world.bombchus_in_logic: + bombchu_ids = [0x6A, 0x03, 0x6B] + for i in bombchu_ids: + item = read_rom_item(rom, i) + item['chest_type'] = 0 + write_rom_item(rom, i, item) + if world.bridge == 'tokens' or world.lacs_condition == 'tokens': + item = read_rom_item(rom, 0x5B) + item['chest_type'] = 0 + write_rom_item(rom, 0x5B, item) + + # Update chest type sizes + if world.correct_chest_sizes: + symbol = rom.sym('CHEST_SIZE_MATCH_CONTENTS') + rom.write_int32(symbol, 0x00000001) + # Move Ganon's Castle's Zelda's Lullaby Chest back so is reachable if large + if not world.dungeon_mq['Ganons Castle']: + rom.write_int16(0x321B176, 0xFC40) # original 0xFC48 + + # Move Spirit Temple Compass Chest if it is a small chest so it is reachable with hookshot + if not world.dungeon_mq['Spirit Temple']: + chest_name = 'Spirit Temple Compass Chest' + chest_address = 0x2B6B07C + location = world.get_location(chest_name) + item = read_rom_item(rom, location.item.index) + if item['chest_type'] in (1, 3): + rom.write_int16(chest_address + 2, 0x0190) # X pos + rom.write_int16(chest_address + 6, 0xFABC) # Z pos + + # Move Silver Gauntlets chest if it is small so it is reachable from Spirit Hover Seam + if world.logic_rules != 'glitchless': + chest_name = 'Spirit Temple Silver Gauntlets Chest' + chest_address_0 = 0x21A02D0 # Address in setup 0 + chest_address_2 = 0x21A06E4 # Address in setup 2 + location = world.get_location(chest_name) + item = read_rom_item(rom, location.item.index) + if item['chest_type'] in (1, 3): + rom.write_int16(chest_address_0 + 6, 0x0172) # Z pos + rom.write_int16(chest_address_2 + 6, 0x0172) # Z pos + + # give dungeon items the correct messages + add_item_messages(messages, shop_items, world) + if world.enhance_map_compass: + reward_list = {'Kokiri Emerald': "\x05\x42Kokiri Emerald\x05\x40", + 'Goron Ruby': "\x05\x41Goron Ruby\x05\x40", + 'Zora Sapphire': "\x05\x43Zora Sapphire\x05\x40", + 'Forest Medallion': "\x05\x42Forest Medallion\x05\x40", + 'Fire Medallion': "\x05\x41Fire Medallion\x05\x40", + 'Water Medallion': "\x05\x43Water Medallion\x05\x40", + 'Spirit Medallion': "\x05\x46Spirit Medallion\x05\x40", + 'Shadow Medallion': "\x05\x45Shadow Medallion\x05\x40", + 'Light Medallion': "\x05\x44Light Medallion\x05\x40" + } + dungeon_list = {'Deku Tree': ("the \x05\x42Deku Tree", 'Queen Gohma', 0x62, 0x88), + 'Dodongos Cavern': ("\x05\x41Dodongo\'s Cavern", 'King Dodongo', 0x63, 0x89), + 'Jabu Jabus Belly': ("\x05\x43Jabu Jabu\'s Belly", 'Barinade', 0x64, 0x8a), + 'Forest Temple': ("the \x05\x42Forest Temple", 'Phantom Ganon', 0x65, 0x8b), + 'Fire Temple': ("the \x05\x41Fire Temple", 'Volvagia', 0x7c, 0x8c), + 'Water Temple': ("the \x05\x43Water Temple", 'Morpha', 0x7d, 0x8e), + 'Spirit Temple': ("the \x05\x46Spirit Temple", 'Twinrova', 0x7e, 0x8f), + 'Ice Cavern': ("the \x05\x44Ice Cavern", None, 0x87, 0x92), + 'Bottom of the Well': ("the \x05\x45Bottom of the Well", None, 0xa2, 0xa5), + 'Shadow Temple': ("the \x05\x45Shadow Temple", 'Bongo Bongo', 0x7f, 0xa3), + } + for dungeon in world.dungeon_mq: + if dungeon in ['Gerudo Training Grounds', 'Ganons Castle']: + pass + elif dungeon in ['Bottom of the Well', 'Ice Cavern']: + dungeon_name, boss_name, compass_id, map_id = dungeon_list[dungeon] + if len(world.world.worlds) > 1: + map_message = "\x13\x76\x08\x05\x42\x0F\x05\x40 found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x09" % (dungeon_name) + else: + map_message = "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x01It\'s %s!\x09" % (dungeon_name, "masterful" if world.dungeon_mq[dungeon] else "ordinary") + + if world.mq_dungeons_random or world.mq_dungeons != 0 and world.mq_dungeons != 12: + update_message_by_id(messages, map_id, map_message) + else: + dungeon_name, boss_name, compass_id, map_id = dungeon_list[dungeon] + dungeon_reward = reward_list[world.get_location(boss_name).item.name] + if len(world.world.worlds) > 1: + compass_message = "\x13\x75\x08\x05\x42\x0F\x05\x40 found the \x05\x41Compass\x05\x40\x01for %s\x05\x40!\x09" % (dungeon_name) + else: + compass_message = "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for %s\x05\x40!\x01It holds the %s!\x09" % (dungeon_name, dungeon_reward) + update_message_by_id(messages, compass_id, compass_message) + if world.mq_dungeons_random or world.mq_dungeons != 0 and world.mq_dungeons != 12: + if len(world.world.worlds) > 1: + map_message = "\x13\x76\x08\x05\x42\x0F\x05\x40 found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x09" % (dungeon_name) + else: + map_message = "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x01It\'s %s!\x09" % (dungeon_name, "masterful" if world.dungeon_mq[dungeon] else "ordinary") + update_message_by_id(messages, map_id, map_message) + + # Set hints on the altar inside ToT + rom.write_int16(0xE2ADB2, 0x707A) + rom.write_int16(0xE2ADB6, 0x7057) + buildAltarHints(world, messages, include_rewards=world.misc_hints and not world.enhance_map_compass, include_wincons=world.misc_hints) + + # Set Dungeon Reward actors in Jabu Jabu to be accurate + jabu_actor_type = world.get_location('Barinade').item.special['actor_type'] + set_jabu_stone_actors(rom, jabu_actor_type) + # Also set the right object for the actor, since medallions and stones require different objects + # MQ is handled separately, as we include both objects in the object list in mqu.json (Scene 2, Room 6) + if not world.dungeon_mq['Jabu Jabus Belly']: + jabu_stone_object = world.get_location('Barinade').item.special['object_id'] + rom.write_int16(0x277D068, jabu_stone_object) + rom.write_int16(0x277D168, jabu_stone_object) + + # update happy mask shop to use new SOLD OUT text id + rom.write_int16(shop_item_file.start + 0x1726, shop_items[0x26].description_message) + + # Add 3rd Wallet Upgrade + rom.write_int16(0xB6D57E, 0x0003) + rom.write_int16(0xB6EC52, 999) + tycoon_message = "\x08\x13\x57You got a \x05\x43Tycoon's Wallet\x05\x40!\x01Now you can hold\x01up to \x05\x46999\x05\x40 \x05\x46Rupees\x05\x40." + if len(world.world.worlds) > 1: + tycoon_message = make_player_message(tycoon_message) + update_message_by_id(messages, 0x00F8, tycoon_message, 0x23) + + write_shop_items(rom, shop_item_file.start + 0x1DEC, shop_items) + + permutation = None + + # text shuffle + if world.text_shuffle == 'except_hints': + permutation = shuffle_messages(messages, except_hints=True) + elif world.text_shuffle == 'complete': + permutation = shuffle_messages(messages, except_hints=False) + + repack_messages(rom, messages, permutation) + + # output a text dump, for testing... + #with open('keysanity_' + str(world.seed) + '_dump.txt', 'w', encoding='utf-16') as f: + # messages = read_messages(rom) + # f.write('item_message_strings = {\n') + # for m in messages: + # f.write("\t0x%04X: \"%s\",\n" % (m.id, m.get_python_string())) + # f.write('}\n') + + if world.free_scarecrow: + # Played song as adult + save_context.write_bits(0x0EE6, 0x10) + # Direct scarecrow behavior + symbol = rom.sym('FREE_SCARECROW_ENABLED') + rom.write_byte(symbol, 0x01) + + # Enable MM-like Bunny Hood behavior (1.5× speed) + if world.fast_bunny_hood: + symbol = rom.sym('FAST_BUNNY_HOOD_ENABLED') + rom.write_byte(symbol, 0x01) + + # actually write the save table to rom + for (name, count) in world.starting_items.items(): + if count == 0: + continue + save_context.give_item(name, count) + + if world.starting_age == 'adult': + # When starting as adult, the pedestal doesn't handle child default equips when going back child the first time, so we have to equip them ourselves + save_context.equip_default_items('child') + save_context.equip_current_items(world.starting_age) + save_context.write_save_table(rom) + + return rom + + +NUM_VANILLA_OBJECTS = 0x192 +def add_to_extended_object_table(rom, object_id, object_file): + extended_id = object_id - NUM_VANILLA_OBJECTS - 1 + extended_object_table = rom.sym('EXTENDED_OBJECT_TABLE') + rom.write_int32s(extended_object_table + extended_id * 8, [object_file.start, object_file.end]) + + +item_row_struct = struct.Struct('>BBHHBBIIhh') # Match item_row_t in item_table.h +item_row_fields = [ + 'base_item_id', 'action_id', 'text_id', 'object_id', 'graphic_id', 'chest_type', + 'upgrade_fn', 'effect_fn', 'effect_arg1', 'effect_arg2', +] + + +def read_rom_item(rom, item_id): + addr = rom.sym('item_table') + (item_id * item_row_struct.size) + row_bytes = rom.read_bytes(addr, item_row_struct.size) + row = item_row_struct.unpack(row_bytes) + return { item_row_fields[i]: row[i] for i in range(len(item_row_fields)) } + + +def write_rom_item(rom, item_id, item): + addr = rom.sym('item_table') + (item_id * item_row_struct.size) + row = [item[f] for f in item_row_fields] + row_bytes = item_row_struct.pack(*row) + rom.write_bytes(addr, row_bytes) + + + +def get_override_table(world): + return list(filter(lambda val: val != None, map(get_override_entry, world.world.get_filled_locations(world.player)))) + + +override_struct = struct.Struct('>xBBBHBB') # match override_t in get_items.c +def get_override_table_bytes(override_table): + return b''.join(sorted(itertools.starmap(override_struct.pack, override_table))) + + +def get_override_entry(location): + scene = location.scene + default = location.default + player_id = location.item.player + if location.item.game != 'Ocarina of Time': + # This is an AP sendable. It's guaranteed to not be None. + item_id = 0x0C # Ocarina of Time item, otherwise unused + looks_like_item_id = 0 + else: + item_id = location.item.index + if None in [scene, default, item_id]: + return None + + if location.item.looks_like_item is not None: + looks_like_item_id = location.item.looks_like_item.index + else: + looks_like_item_id = 0 + + if location.type in ['NPC', 'BossHeart']: + type = 0 + elif location.type == 'Chest': + type = 1 + default &= 0x1F + elif location.type == 'Collectable': + type = 2 + elif location.type == 'GS Token': + type = 3 + elif location.type == 'Shop' and location.item.type != 'Shop': + type = 0 + elif location.type == 'GrottoNPC' and location.item.type != 'Shop': + type = 4 + elif location.type in ['Song', 'Cutscene']: + type = 5 + else: + return None + + return (scene, type, default, item_id, player_id, looks_like_item_id) + + +chestTypeMap = { + # small big boss + 0x0000: [0x5000, 0x0000, 0x2000], #Large + 0x1000: [0x7000, 0x1000, 0x1000], #Large, Appears, Clear Flag + 0x2000: [0x5000, 0x0000, 0x2000], #Boss Key’s Chest + 0x3000: [0x8000, 0x3000, 0x3000], #Large, Falling, Switch Flag + 0x4000: [0x6000, 0x4000, 0x4000], #Large, Invisible + 0x5000: [0x5000, 0x0000, 0x2000], #Small + 0x6000: [0x6000, 0x4000, 0x4000], #Small, Invisible + 0x7000: [0x7000, 0x1000, 0x1000], #Small, Appears, Clear Flag + 0x8000: [0x8000, 0x3000, 0x3000], #Small, Falling, Switch Flag + 0x9000: [0x9000, 0x9000, 0x9000], #Large, Appears, Zelda's Lullaby + 0xA000: [0xA000, 0xA000, 0xA000], #Large, Appears, Sun's Song Triggered + 0xB000: [0xB000, 0xB000, 0xB000], #Large, Appears, Switch Flag + 0xC000: [0x5000, 0x0000, 0x2000], #Large + 0xD000: [0x5000, 0x0000, 0x2000], #Large + 0xE000: [0x5000, 0x0000, 0x2000], #Large + 0xF000: [0x5000, 0x0000, 0x2000], #Large +} + + +def room_get_actors(rom, actor_func, room_data, scene, alternate=None): + actors = {} + room_start = alternate if alternate else room_data + command = 0 + while command != 0x14: # 0x14 = end header + command = rom.read_byte(room_data) + if command == 0x01: # actor list + actor_count = rom.read_byte(room_data + 1) + actor_list = room_start + (rom.read_int32(room_data + 4) & 0x00FFFFFF) + for _ in range(0, actor_count): + actor_id = rom.read_int16(actor_list) + entry = actor_func(rom, actor_id, actor_list, scene) + if entry: + actors[actor_list] = entry + actor_list = actor_list + 16 + if command == 0x18: # Alternate header list + header_list = room_start + (rom.read_int32(room_data + 4) & 0x00FFFFFF) + for alt_id in range(0,3): + header_data = room_start + (rom.read_int32(header_list) & 0x00FFFFFF) + if header_data != 0 and not alternate: + actors.update(room_get_actors(rom, actor_func, header_data, scene, room_start)) + header_list = header_list + 4 + room_data = room_data + 8 + return actors + + +def scene_get_actors(rom, actor_func, scene_data, scene, alternate=None, processed_rooms=None): + if processed_rooms == None: + processed_rooms = [] + actors = {} + scene_start = alternate if alternate else scene_data + command = 0 + while command != 0x14: # 0x14 = end header + command = rom.read_byte(scene_data) + if command == 0x04: #room list + room_count = rom.read_byte(scene_data + 1) + room_list = scene_start + (rom.read_int32(scene_data + 4) & 0x00FFFFFF) + for _ in range(0, room_count): + room_data = rom.read_int32(room_list); + + if not room_data in processed_rooms: + actors.update(room_get_actors(rom, actor_func, room_data, scene)) + processed_rooms.append(room_data) + room_list = room_list + 8 + if command == 0x0E: #transition actor list + actor_count = rom.read_byte(scene_data + 1) + actor_list = scene_start + (rom.read_int32(scene_data + 4) & 0x00FFFFFF) + for _ in range(0, actor_count): + actor_id = rom.read_int16(actor_list + 4) + entry = actor_func(rom, actor_id, actor_list, scene) + if entry: + actors[actor_list] = entry + actor_list = actor_list + 16 + if command == 0x18: # Alternate header list + header_list = scene_start + (rom.read_int32(scene_data + 4) & 0x00FFFFFF) + for alt_id in range(0,3): + header_data = scene_start + (rom.read_int32(header_list) & 0x00FFFFFF) + if header_data != 0 and not alternate: + actors.update(scene_get_actors(rom, actor_func, header_data, scene, scene_start, processed_rooms)) + header_list = header_list + 4 + + scene_data = scene_data + 8 + return actors + + +def get_actor_list(rom, actor_func): + actors = {} + scene_table = 0x00B71440 + for scene in range(0x00, 0x65): + scene_data = rom.read_int32(scene_table + (scene * 0x14)); + actors.update(scene_get_actors(rom, actor_func, scene_data, scene)) + return actors + + +def get_override_itemid(override_table, scene, type, flags): + for entry in override_table: + if entry[0] == scene and (entry[1] & 0x07) == type and entry[2] == flags: + return entry[4] + return None + +def remove_entrance_blockers(rom): + def remove_entrance_blockers_do(rom, actor_id, actor, scene): + if actor_id == 0x014E and scene == 97: + actor_var = rom.read_int16(actor + 14); + if actor_var == 0xFF01: + rom.write_int16(actor + 14, 0x0700) + get_actor_list(rom, remove_entrance_blockers_do) + +def set_cow_id_data(rom, world): + def set_cow_id(rom, actor_id, actor, scene): + nonlocal last_scene + nonlocal cow_count + nonlocal last_actor + + if actor_id == 0x01C6: #Cow + if scene == last_scene and last_actor != actor: + cow_count += 1 + else: + cow_count = 1 + + last_scene = scene + last_actor = actor + if world.dungeon_mq['Jabu Jabus Belly'] and scene == 2: #If its an MQ jabu cow + rom.write_int16(actor + 0x8, 1 if cow_count == 17 else 0) #Give all wall cows ID 0, and set cow 11's ID to 1 + else: + rom.write_int16(actor + 0x8, cow_count) + + last_actor = -1 + last_scene = -1 + cow_count = 1 + + get_actor_list(rom, set_cow_id) + + +def set_grotto_shuffle_data(rom, world): + def override_grotto_data(rom, actor_id, actor, scene): + if actor_id == 0x009B: #Grotto + actor_zrot = rom.read_int16(actor + 12) + actor_var = rom.read_int16(actor + 14) + grotto_type = (actor_var >> 8) & 0x0F + grotto_actor_id = (scene << 8) + (actor_var & 0x00FF) + + rom.write_int16(actor + 12, grotto_entrances_override[grotto_actor_id]) + rom.write_byte(actor + 14, grotto_type + 0x20) + + # Build the override table based on shuffled grotto entrances + grotto_entrances_override = {} + for entrance in world.get_shuffled_entrances(type='Grotto'): + if entrance.primary: + grotto_actor_id = (entrance.data['scene'] << 8) + entrance.data['content'] + grotto_entrances_override[grotto_actor_id] = entrance.replaces.data['index'] + else: + rom.write_int16(rom.sym('GROTTO_EXIT_LIST') + 2 * entrance.data['grotto_id'], entrance.replaces.data['index']) + + # Override grotto actors data with the new data + get_actor_list(rom, override_grotto_data) + + +def set_deku_salesman_data(rom): + def set_deku_salesman(rom, actor_id, actor, scene): + if actor_id == 0x0195: #Salesman + actor_var = rom.read_int16(actor + 14) + if actor_var == 6: + rom.write_int16(actor + 14, 0x0003) + + get_actor_list(rom, set_deku_salesman) + + +def set_jabu_stone_actors(rom, jabu_actor_type): + def set_jabu_stone_actor(rom, actor_id, actor, scene): + if scene == 2 and actor_id == 0x008B: # Demo_Effect in Jabu Jabu + actor_type = rom.read_byte(actor + 15) + if actor_type == 0x15: + rom.write_byte(actor + 15, jabu_actor_type) + + get_actor_list(rom, set_jabu_stone_actor) + + +def get_locked_doors(rom, world): + def locked_door(rom, actor_id, actor, scene): + actor_var = rom.read_int16(actor + 14) + actor_type = actor_var >> 6 + actor_flag = actor_var & 0x003F + + flag_id = (1 << actor_flag) + flag_byte = 3 - (actor_flag >> 3) + flag_bits = 1 << (actor_flag & 0x07) + + # If locked door, set the door's unlock flag + if world.shuffle_smallkeys == 'remove': + if actor_id == 0x0009 and actor_type == 0x02: + return [0x00D4 + scene * 0x1C + 0x04 + flag_byte, flag_bits] + if actor_id == 0x002E and actor_type == 0x0B: + return [0x00D4 + scene * 0x1C + 0x04 + flag_byte, flag_bits] + + # If boss door, set the door's unlock flag + if (world.shuffle_bosskeys == 'remove' and scene != 0x0A) or (world.shuffle_ganon_bosskey == 'remove' and scene == 0x0A): + if actor_id == 0x002E and actor_type == 0x05: + return [0x00D4 + scene * 0x1C + 0x04 + flag_byte, flag_bits] + + return get_actor_list(rom, locked_door) + + +def place_shop_items(rom, world, shop_items, messages, locations, init_shop_id=False): + if init_shop_id: + world.current_shop_id = 0x32 + + shop_objs = { 0x0148 } # "Sold Out" object + for location in locations: + if location.item.type == 'Shop': + shop_objs.add(location.item.special['object']) + rom.write_int16(location.address1, location.item.index) + else: + if location.item.game != "Ocarina of Time": + item_display = location.item + item_display.index = 0x0C # Ocarina of Time item + item_display.special = {} + elif location.item.looks_like_item is not None: + item_display = location.item.looks_like_item + else: + item_display = location.item + + # bottles in shops should look like empty bottles + # so that that are different than normal shop refils + if 'shop_object' in item_display.special: + rom_item = read_rom_item(rom, item_display.special['shop_object']) + else: + rom_item = read_rom_item(rom, item_display.index) + + shop_objs.add(rom_item['object_id']) + shop_id = world.current_shop_id + rom.write_int16(location.address1, shop_id) + shop_item = shop_items[shop_id] + + shop_item.object = rom_item['object_id'] + shop_item.model = rom_item['graphic_id'] - 1 + shop_item.price = location.price + shop_item.pieces = 1 + shop_item.get_item_id = location.default + shop_item.func1 = 0x808648CC + shop_item.func2 = 0x808636B8 + shop_item.func3 = 0x00000000 + shop_item.func4 = 0x80863FB4 + + message_id = (shop_id - 0x32) * 2 + shop_item.description_message = 0x8100 + message_id + shop_item.purchase_message = 0x8100 + message_id + 1 + + shuffle_messages.shop_item_messages.extend( + [shop_item.description_message, shop_item.purchase_message]) + + if getattr(item_display, 'dungeonitem', False) and location.item.game == "Ocarina of Time": + split_item_name = item_display.name.split('(') + split_item_name[1] = '(' + split_item_name[1] + + if location.item.name == 'Ice Trap': + split_item_name[0] = create_fake_name(split_item_name[0]) + + if len(world.world.worlds) > 1: # OOTWorld.MultiWorld.AutoWorld[] + description_text = '\x08\x05\x41%s %d Rupees\x01%s\x01\x05\x42%s\x05\x40\x01Special deal! ONE LEFT!\x09\x0A\x02' % (split_item_name[0], location.price, split_item_name[1], world.world.get_player_name(location.item.player)) + else: + description_text = '\x08\x05\x41%s %d Rupees\x01%s\x01\x05\x40Special deal! ONE LEFT!\x01Get it while it lasts!\x09\x0A\x02' % (split_item_name[0], location.price, split_item_name[1]) + purchase_text = '\x08%s %d Rupees\x09\x01%s\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02' % (split_item_name[0], location.price, split_item_name[1]) + else: + if item_display.game == "Ocarina of Time": + shop_item_name = getSimpleHintNoPrefix(item_display) + else: + shop_item_name = item_display.name + + if location.item.name == 'Ice Trap': + shop_item_name = create_fake_name(shop_item_name) + + if len(world.world.worlds) > 1: + shop_item_name = ''.join(filter(lambda char: char in character_table, shop_item_name)) + do_line_break = sum(character_table[char] for char in f"{shop_item_name} {location.price} Rupees") > NORMAL_LINE_WIDTH + description_text = '\x08\x05\x41%s%s%d Rupees\x01\x05\x42%s\x05\x40\x01Special deal! ONE LEFT!\x09\x0A\x02' % (shop_item_name, '\x01' if do_line_break else ' ', location.price, world.world.get_player_name(location.item.player)) + else: + description_text = '\x08\x05\x41%s %d Rupees\x01\x05\x40Special deal! ONE LEFT!\x01Get it while it lasts!\x09\x0A\x02' % (shop_item_name, location.price) + purchase_text = '\x08%s %d Rupees\x09\x01\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02' % (shop_item_name, location.price) + + update_message_by_id(messages, shop_item.description_message, description_text, 0x03) + update_message_by_id(messages, shop_item.purchase_message, purchase_text, 0x03) + + world.current_shop_id += 1 + + return shop_objs + + +def create_fake_name(item_name): + return item_name + "???" + + +def boss_reward_index(world, boss_name): + code = world.get_location(boss_name).item.special['item_id'] + if code >= 0x6C: + return code - 0x6C + else: + return 3 + code - 0x66 + + +def configure_dungeon_info(rom, world): + mq_enable = (world.mq_dungeons_random or world.mq_dungeons != 0 and world.mq_dungeons != 12) + enhance_map_compass = world.enhance_map_compass + + bosses = ['Queen Gohma', 'King Dodongo', 'Barinade', 'Phantom Ganon', + 'Volvagia', 'Morpha', 'Twinrova', 'Bongo Bongo'] + dungeon_rewards = [boss_reward_index(world, boss) for boss in bosses] + + codes = ['Deku Tree', 'Dodongos Cavern', 'Jabu Jabus Belly', 'Forest Temple', + 'Fire Temple', 'Water Temple', 'Spirit Temple', 'Shadow Temple', + 'Bottom of the Well', 'Ice Cavern', 'Tower (N/A)', + 'Gerudo Training Grounds', 'Hideout (N/A)', 'Ganons Castle'] + dungeon_is_mq = [1 if world.dungeon_mq.get(c) else 0 for c in codes] + + rom.write_int32(rom.sym('cfg_dungeon_info_enable'), 1) + rom.write_int32(rom.sym('cfg_dungeon_info_mq_enable'), int(mq_enable)) + rom.write_int32(rom.sym('cfg_dungeon_info_mq_need_map'), int(enhance_map_compass)) + rom.write_int32(rom.sym('cfg_dungeon_info_reward_enable'), int(world.misc_hints or enhance_map_compass)) + rom.write_int32(rom.sym('cfg_dungeon_info_reward_need_compass'), int(enhance_map_compass)) + rom.write_int32(rom.sym('cfg_dungeon_info_reward_need_altar'), int(not enhance_map_compass)) + rom.write_bytes(rom.sym('cfg_dungeon_rewards'), dungeon_rewards) + rom.write_bytes(rom.sym('cfg_dungeon_is_mq'), dungeon_is_mq) diff --git a/worlds/oot/Regions.py b/worlds/oot/Regions.py new file mode 100644 index 00000000..0cfda386 --- /dev/null +++ b/worlds/oot/Regions.py @@ -0,0 +1,61 @@ +from enum import unique, Enum + +from BaseClasses import Region + + +# copied from OoT-Randomizer/Region.py +@unique +class RegionType(Enum): + + Overworld = 1 + Interior = 2 + Dungeon = 3 + Grotto = 4 + + + @property + def is_indoors(self): + """Shorthand for checking if Interior or Dungeon""" + return self in (RegionType.Interior, RegionType.Dungeon, RegionType.Grotto) + +# Pretends to be an enum, but when the values are raw ints, it's much faster +class TimeOfDay(object): + NONE = 0 + DAY = 1 + DAMPE = 2 + ALL = DAY | DAMPE + + + + +class OOTRegion(Region): + game: str = "Ocarina of Time" + + def __init__(self, name: str, type, hint, player: int): + super(OOTRegion, self).__init__(name, type, hint, player) + self.price = None + self.time_passes = False + self.provides_time = TimeOfDay.NONE + self.scene = None + self.dungeon = None + + def get_scene(self): + if self.scene: + return self.scene + elif self.dungeon: + return self.dungeon.name + else: + return None + + def can_reach(self, state): + if state.stale[self.player]: + stored_age = state.age[self.player] + state._oot_update_age_reachable_regions(self.player) + state.age[self.player] = stored_age + if state.age[self.player] == 'child': + return self in state.child_reachable_regions[self.player] + elif state.age[self.player] == 'adult': + return self in state.adult_reachable_regions[self.player] + else: # we don't care about age + return self in state.child_reachable_regions[self.player] or self in state.adult_reachable_regions[self.player] + diff --git a/worlds/oot/Rom.py b/worlds/oot/Rom.py new file mode 100644 index 00000000..64a53b61 --- /dev/null +++ b/worlds/oot/Rom.py @@ -0,0 +1,321 @@ +import io +import itertools +import json +import logging +import os +import platform +import struct +import subprocess +import random +import copy +from Utils import local_path, is_frozen +from .Utils import subprocess_args, data_path, get_version_bytes, __version__ +from .ntype import BigStream, uint32 +from .crc import calculate_crc + +DMADATA_START = 0x7430 + +class Rom(BigStream): + + def __init__(self, file=None): + super().__init__([]) + + self.original = None + self.changed_address = {} + self.changed_dma = {} + self.force_patch = [] + + if file is None: + return + + decomp_file = 'ZOOTDEC.z64' + + os.chdir(local_path()) + + with open(data_path('generated/symbols.json'), 'r') as stream: + symbols = json.load(stream) + self.symbols = { name: int(addr, 16) for name, addr in symbols.items() } + + # If decompressed file already exists, read from it + if os.path.exists(decomp_file): + file = decomp_file + + if file == '': + # if not specified, try to read from the previously decompressed rom + file = decomp_file + try: + self.read_rom(file) + except FileNotFoundError: + # could not find the decompressed rom either + raise FileNotFoundError('Must specify path to base ROM') + else: + self.read_rom(file) + + # decompress rom, or check if it's already decompressed + self.decompress_rom_file(file, decomp_file) + + # Add file to maximum size + self.buffer.extend(bytearray([0x00] * (0x4000000 - len(self.buffer)))) + self.original = self.copy() + + # Add version number to header. + self.write_bytes(0x35, get_version_bytes(__version__)) + self.force_patch.extend([0x35, 0x36, 0x37]) + + + def copy(self): + new_rom = Rom() + new_rom.buffer = copy.copy(self.buffer) + new_rom.changed_address = copy.copy(self.changed_address) + new_rom.changed_dma = copy.copy(self.changed_dma) + new_rom.force_patch = copy.copy(self.force_patch) + return new_rom + + + def decompress_rom_file(self, file, decomp_file): + validCRC = [ + [0xEC, 0x70, 0x11, 0xB7, 0x76, 0x16, 0xD7, 0x2B], # Compressed + [0x70, 0xEC, 0xB7, 0x11, 0x16, 0x76, 0x2B, 0xD7], # Byteswap compressed + [0x93, 0x52, 0x2E, 0x7B, 0xE5, 0x06, 0xD4, 0x27], # Decompressed + ] + + # Validate ROM file + file_name = os.path.splitext(file) + romCRC = list(self.buffer[0x10:0x18]) + if romCRC not in validCRC: + # Bad CRC validation + raise RuntimeError('ROM file %s is not a valid OoT 1.0 US ROM.' % file) + elif len(self.buffer) < 0x2000000 or len(self.buffer) > (0x4000000) or file_name[1].lower() not in ['.z64', '.n64']: + # ROM is too big, or too small, or not a bad type + raise RuntimeError('ROM file %s is not a valid OoT 1.0 US ROM.' % file) + elif len(self.buffer) == 0x2000000: + # If Input ROM is compressed, then Decompress it + subcall = [] + + sub_dir = data_path("Decompress") + + if platform.system() == 'Windows': + if 8 * struct.calcsize("P") == 64: + subcall = [sub_dir + "\\Decompress.exe", file, decomp_file] + else: + subcall = [sub_dir + "\\Decompress32.exe", file, decomp_file] + elif platform.system() == 'Linux': + if platform.uname()[4] == 'aarch64' or platform.uname()[4] == 'arm64': + subcall = [sub_dir + "/Decompress_ARM64", file, decomp_file] + else: + subcall = [sub_dir + "/Decompress", file, decomp_file] + elif platform.system() == 'Darwin': + subcall = [sub_dir + "/Decompress.out", file, decomp_file] + else: + raise RuntimeError('Unsupported operating system for decompression. Please supply an already decompressed ROM.') + + if not os.path.exists(subcall[0]): + raise RuntimeError(f'Decompressor does not exist! Please place it at {subcall[0]}.') + subprocess.call(subcall, **subprocess_args()) + self.read_rom(decomp_file) + else: + # ROM file is a valid and already uncompressed + pass + + + def write_byte(self, address, value): + super().write_byte(address, value) + self.changed_address[self.last_address-1] = value + + + def write_bytes(self, address, values): + super().write_bytes(address, values) + self.changed_address.update(zip(range(address, address+len(values)), values)) + + + def restore(self): + self.buffer = copy.copy(self.original.buffer) + self.changed_address = {} + self.changed_dma = {} + self.force_patch = [] + self.last_address = None + self.write_bytes(0x35, get_version_bytes(__version__)) + self.force_patch.extend([0x35, 0x36, 0x37]) + + + def sym(self, symbol_name): + return self.symbols.get(symbol_name) + + + def write_to_file(self, file): + self.verify_dmadata() + self.update_header() + with open(file, 'wb') as outfile: + outfile.write(self.buffer) + + + def update_header(self): + crc = calculate_crc(self) + self.write_bytes(0x10, crc) + + + def read_rom(self, file): + # "Reads rom into bytearray" + try: + with open(file, 'rb') as stream: + self.buffer = bytearray(stream.read()) + except FileNotFoundError as ex: + raise FileNotFoundError('Invalid path to Base ROM: "' + file + '"') + + + # dmadata/file management helper functions + + def _get_dmadata_record(self, cur): + start = self.read_int32(cur) + end = self.read_int32(cur+0x04) + size = end-start + return start, end, size + + + def get_dmadata_record_by_key(self, key): + cur = DMADATA_START + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + while True: + if dma_start == 0 and dma_end == 0: + return None + if dma_start == key: + return dma_start, dma_end, dma_size + cur += 0x10 + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + + + def verify_dmadata(self): + cur = DMADATA_START + overlapping_records = [] + dma_data = [] + + while True: + this_start, this_end, this_size = self._get_dmadata_record(cur) + + if this_start == 0 and this_end == 0: + break + + dma_data.append((this_start, this_end, this_size)) + cur += 0x10 + + dma_data.sort(key=lambda v: v[0]) + + for i in range(0, len(dma_data) - 1): + this_start, this_end, this_size = dma_data[i] + next_start, next_end, next_size = dma_data[i + 1] + + if this_end > next_start: + overlapping_records.append( + '0x%08X - 0x%08X (Size: 0x%04X)\n0x%08X - 0x%08X (Size: 0x%04X)' % \ + (this_start, this_end, this_size, next_start, next_end, next_size) + ) + + if len(overlapping_records) > 0: + raise Exception("Overlapping DMA Data Records!\n%s" % \ + '\n-------------------------------------\n'.join(overlapping_records)) + + + # update dmadata record with start vrom address "key" + # if key is not found, then attempt to add a new dmadata entry + def update_dmadata_record(self, key, start, end, from_file=None): + cur, dma_data_end = self.get_dma_table_range() + dma_index = 0 + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + while dma_start != key: + if dma_start == 0 and dma_end == 0: + break + + cur += 0x10 + dma_index += 1 + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + + if cur >= (dma_data_end - 0x10): + raise Exception('dmadata update failed: key {0:x} not found in dmadata and dma table is full.'.format(key)) + else: + self.write_int32s(cur, [start, end, start, 0]) + if from_file == None: + if key == None: + from_file = -1 + else: + from_file = key + self.changed_dma[dma_index] = (from_file, start, end - start) + + + def get_dma_table_range(self): + cur = DMADATA_START + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + while True: + if dma_start == 0 and dma_end == 0: + raise Exception('Bad DMA Table: DMA Table entry missing.') + + if dma_start == DMADATA_START: + return (DMADATA_START, dma_end) + + cur += 0x10 + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + + + # This will scan for any changes that have been made to the DMA table + # This assumes any changes here are new files, so this should only be called + # after patching in the new files, but before vanilla files are repointed + def scan_dmadata_update(self): + cur = DMADATA_START + dma_data_end = None + dma_index = 0 + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + old_dma_start, old_dma_end, old_dma_size = self.original._get_dmadata_record(cur) + + while True: + if (dma_start == 0 and dma_end == 0) and \ + (old_dma_start == 0 and old_dma_end == 0): + break + + # If the entries do not match, the flag the changed entry + if not (dma_start == old_dma_start and dma_end == old_dma_end): + self.changed_dma[dma_index] = (-1, dma_start, dma_end - dma_start) + + cur += 0x10 + dma_index += 1 + dma_start, dma_end, dma_size = self._get_dmadata_record(cur) + old_dma_start, old_dma_end, old_dma_size = self.original._get_dmadata_record(cur) + + + # gets the last used byte of rom defined in the DMA table + def free_space(self): + cur = DMADATA_START + max_end = 0 + + while True: + this_start, this_end, this_size = self._get_dmadata_record(cur) + + if this_start == 0 and this_end == 0: + break + + max_end = max(max_end, this_end) + cur += 0x10 + max_end = ((max_end + 0x0F) >> 4) << 4 + return max_end + +def compress_rom_file(input_file, output_file): + subcall = [] + + compressor_path = data_path("Compress") + + if platform.system() == 'Windows': + if 8 * struct.calcsize("P") == 64: + compressor_path += "\\Compress.exe" + else: + compressor_path += "\\Compress32.exe" + elif platform.system() == 'Linux': + if platform.uname()[4] == 'aarch64' or platform.uname()[4] == 'arm64': + compressor_path += "/Compress_ARM64" + else: + compressor_path += "/Compress" + elif platform.system() == 'Darwin': + compressor_path += "/Compress.out" + else: + raise RuntimeError('Unsupported operating system for compression.') + + if not os.path.exists(compressor_path): + raise RuntimeError(f'Compressor does not exist! Please place it at {compressor_path}.') + process = subprocess.call([compressor_path, input_file, output_file], **subprocess_args(include_stdout=False)) diff --git a/worlds/oot/RuleParser.py b/worlds/oot/RuleParser.py new file mode 100644 index 00000000..5223d3c2 --- /dev/null +++ b/worlds/oot/RuleParser.py @@ -0,0 +1,507 @@ +import ast +from collections import defaultdict +from inspect import signature, _ParameterKind +import logging +import re + +from .Items import item_table +from .Location import OOTLocation +from .Regions import TimeOfDay, OOTRegion +from BaseClasses import CollectionState as State +from .Utils import data_path, read_json + +from worlds.generic.Rules import set_rule + + +escaped_items = {} +for item in item_table: + escaped_items[re.sub(r'[\'()[\]]', '', item.replace(' ', '_'))] = item + +event_name = re.compile(r'\w+') +# All generated lambdas must accept these keyword args! +# For evaluation at a certain age (required as all rules are evaluated at a specific age) +# or at a certain spot (can be omitted in many cases) +# or at a specific time of day (often unused) +kwarg_defaults = { + # 'age': None, + # 'spot': None, + # 'tod': TimeOfDay.NONE, +} + +allowed_globals = {'TimeOfDay': TimeOfDay} + +rule_aliases = {} +nonaliases = set() + +def load_aliases(): + j = read_json(data_path('LogicHelpers.json')) + for s, repl in j.items(): + if '(' in s: + rule, args = s[:-1].split('(', 1) + args = [re.compile(r'\b%s\b' % a.strip()) for a in args.split(',')] + else: + rule = s + args = () + rule_aliases[rule] = (args, repl) + nonaliases = escaped_items.keys() - rule_aliases.keys() + + +def isliteral(expr): + return isinstance(expr, (ast.Num, ast.Str, ast.Bytes, ast.NameConstant)) + + +class Rule_AST_Transformer(ast.NodeTransformer): + + def __init__(self, world, player): + self.world = world + self.player = player + self.events = set() + # map Region -> rule ast string -> item name + self.replaced_rules = defaultdict(dict) + # delayed rules need to keep: region name, ast node, event name + self.delayed_rules = [] + # lazy load aliases + if not rule_aliases: + load_aliases() + # final rule cache + self.rule_cache = {} + self.kwarg_defaults = kwarg_defaults.copy() # otherwise this gets contaminated between players + self.kwarg_defaults['player'] = self.player + + + def visit_Name(self, node): + if node.id in dir(self): + return getattr(self, node.id)(node) + elif node.id in rule_aliases: + args, repl = rule_aliases[node.id] + if args: + raise Exception('Parse Error: expected %d args for %s, not 0' % (len(args), node.id), + self.current_spot.name, ast.dump(node, False)) + return self.visit(ast.parse(repl, mode='eval').body) + elif node.id in escaped_items: + return ast.Call( + func=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr='has', + ctx=ast.Load()), + args=[ast.Str(escaped_items[node.id]), ast.Constant(self.player)], + keywords=[]) + elif node.id in self.world.__dict__: + # Settings are constant + return ast.parse('%r' % self.world.__dict__[node.id], mode='eval').body + elif node.id in State.__dict__: + return self.make_call(node, node.id, [], []) + elif node.id in self.kwarg_defaults or node.id in allowed_globals: + return node + elif event_name.match(node.id): + self.events.add(node.id.replace('_', ' ')) + return ast.Call( + func=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr='has', + ctx=ast.Load()), + args=[ast.Str(node.id.replace('_', ' ')), ast.Constant(self.player)], + keywords=[]) + else: + raise Exception('Parse Error: invalid node name %s' % node.id, self.current_spot.name, ast.dump(node, False)) + + def visit_Str(self, node): + return ast.Call( + func=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr='has', + ctx=ast.Load()), + args=[ast.Str(node.s), ast.Constant(self.player)], + keywords=[]) + + # python 3.8 compatibility: ast walking now uses visit_Constant for Constant subclasses + # this includes Num, Str, NameConstant, Bytes, and Ellipsis. We only handle Str. + def visit_Constant(self, node): + if isinstance(node, ast.Str): + return self.visit_Str(node) + return node + + + def visit_Tuple(self, node): + if len(node.elts) != 2: + raise Exception('Parse Error: Tuple must have 2 values', self.current_spot.name, ast.dump(node, False)) + + item, count = node.elts + + if not isinstance(item, (ast.Name, ast.Str)): + raise Exception('Parse Error: first value must be an item. Got %s' % item.__class__.__name__, self.current_spot.name, ast.dump(node, False)) + iname = item.id if isinstance(item, ast.Name) else item.s + + if not (isinstance(count, ast.Name) or isinstance(count, ast.Num)): + raise Exception('Parse Error: second value must be a number. Got %s' % item.__class__.__name__, self.current_spot.name, ast.dump(node, False)) + + if isinstance(count, ast.Name): + # Must be a settings constant + count = ast.parse('%r' % self.world.__dict__[count.id], mode='eval').body + + if iname in escaped_items: + iname = escaped_items[iname] + + if iname not in item_table: + self.events.add(iname) + + return ast.Call( + func=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr='has', + ctx=ast.Load()), + args=[ast.Str(iname), ast.Constant(self.player), count], + keywords=[]) + + + def visit_Call(self, node): + if not isinstance(node.func, ast.Name): + return node + + if node.func.id in dir(self): + return getattr(self, node.func.id)(node) + elif node.func.id in rule_aliases: + args, repl = rule_aliases[node.func.id] + if len(args) != len(node.args): + raise Exception('Parse Error: expected %d args for %s, not %d' % (len(args), node.func.id, len(node.args)), + self.current_spot.name, ast.dump(node, False)) + # straightforward string manip + for arg_re, arg_val in zip(args, node.args): + if isinstance(arg_val, ast.Name): + val = arg_val.id + elif isinstance(arg_val, ast.Constant): + val = repr(arg_val.value) + elif isinstance(arg_val, ast.Str): + val = repr(arg_val.s) + else: + raise Exception('Parse Error: invalid argument %s' % ast.dump(arg_val, False), + self.current_spot.name, ast.dump(node, False)) + repl = arg_re.sub(val, repl) + return self.visit(ast.parse(repl, mode='eval').body) + + new_args = [] + for child in node.args: + if isinstance(child, ast.Name): + if child.id in self.world.__dict__: + # child = ast.Attribute( + # value=ast.Attribute( + # value=ast.Name(id='state', ctx=ast.Load()), + # attr='world', + # ctx=ast.Load()), + # attr=child.id, + # ctx=ast.Load()) + child = ast.Constant(getattr(self.world, child.id)) + elif child.id in rule_aliases: + child = self.visit(child) + elif child.id in escaped_items: + child = ast.Str(escaped_items[child.id]) + else: + child = ast.Str(child.id.replace('_', ' ')) + elif not isinstance(child, ast.Str): + child = self.visit(child) + new_args.append(child) + + return self.make_call(node, node.func.id, new_args, node.keywords) + + + def visit_Subscript(self, node): + if isinstance(node.value, ast.Name): + s = node.slice if isinstance(node.slice, ast.Name) else node.slice.value + return ast.Subscript( + value=ast.Attribute( + # value=ast.Attribute( + # value=ast.Name(id='state', ctx=ast.Load()), + # attr='world', + # ctx=ast.Load()), + value=ast.Subscript( + value=ast.Attribute( + value=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr='world', + ctx=ast.Load()), + attr='worlds', + ctx=ast.Load()), + slice=ast.Index(value=ast.Constant(self.player)), + ctx=ast.Load()), + attr=node.value.id, + ctx=ast.Load()), + slice=ast.Index(value=ast.Str(s.id.replace('_', ' '))), + ctx=node.ctx) + else: + return node + + + def visit_Compare(self, node): + def escape_or_string(n): + if isinstance(n, ast.Name) and n.id in escaped_items: + return ast.Str(escaped_items[n.id]) + elif not isinstance(n, ast.Str): + return self.visit(n) + return n + + # Fast check for json can_use + if (len(node.ops) == 1 and isinstance(node.ops[0], ast.Eq) + and isinstance(node.left, ast.Name) and isinstance(node.comparators[0], ast.Name) + and node.left.id not in self.world.__dict__ and node.comparators[0].id not in self.world.__dict__): + return ast.NameConstant(node.left.id == node.comparators[0].id) + + node.left = escape_or_string(node.left) + node.comparators = list(map(escape_or_string, node.comparators)) + node.ops = list(map(self.visit, node.ops)) + + # if all the children are literals now, we can evaluate + if isliteral(node.left) and all(map(isliteral, node.comparators)): + # either we turn the ops into operator functions to apply (lots of work), + # or we compile, eval, and reparse the result + try: + res = eval(compile(ast.fix_missing_locations(ast.Expression(node)), '', 'eval')) + except TypeError as e: + raise Exception('Parse Error: %s' % e, self.current_spot.name, ast.dump(node, False)) + return self.visit(ast.parse('%r' % res, mode='eval').body) + return node + + + def visit_UnaryOp(self, node): + # visit the children first + self.generic_visit(node) + # if all the children are literals now, we can evaluate + if isliteral(node.operand): + res = eval(compile(ast.Expression(node), '', 'eval')) + return ast.parse('%r' % res, mode='eval').body + return node + + + def visit_BinOp(self, node): + # visit the children first + self.generic_visit(node) + # if all the children are literals now, we can evaluate + if isliteral(node.left) and isliteral(node.right): + res = eval(compile(ast.Expression(node), '', 'eval')) + return ast.parse('%r' % res, mode='eval').body + return node + + + def visit_BoolOp(self, node): + # Everything else must be visited, then can be removed/reduced to. + early_return = isinstance(node.op, ast.Or) + groupable = 'has_any' if early_return else 'has_all' + items = set() + new_values = [] + # if any elt is True(And)/False(Or), we can omit it + # if any is False(And)/True(Or), the whole node can be replaced with it + for elt in list(node.values): + if isinstance(elt, ast.Str): + items.add(elt.s) + elif isinstance(elt, ast.Name) and elt.id in nonaliases: + items.add(escaped_items[elt.id]) + else: + # It's possible this returns a single item check, + # but it's already wrapped in a Call. + elt = self.visit(elt) + if isinstance(elt, ast.NameConstant): + if elt.value == early_return: + return elt + # else omit it + elif (isinstance(elt, ast.Call) and isinstance(elt.func, ast.Attribute) + and elt.func.attr in ('has', groupable) and len(elt.args) == 1): + args = elt.args[0] + if isinstance(args, ast.Str): + items.add(args.s) + else: + items.update(it.s for it in args.elts) + elif isinstance(elt, ast.BoolOp) and node.op.__class__ == elt.op.__class__: + new_values.extend(elt.values) + else: + new_values.append(elt) + + # package up the remaining items and values + if not items and not new_values: + # all values were True(And)/False(Or) + return ast.NameConstant(not early_return) + + if items: + node.values = [ast.Call( + func=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr='has_any' if early_return else 'has_all', + ctx=ast.Load()), + args=[ast.Tuple(elts=[ast.Str(i) for i in items], ctx=ast.Load()), ast.Constant(self.player)], + keywords=[])] + new_values + else: + node.values = new_values + if len(node.values) == 1: + return node.values[0] + return node + + + # Generates an ast.Call invoking the given State function 'name', + # providing given args and keywords, and adding in additional + # keyword args from kwarg_defaults (age, etc.) + def make_call(self, node, name, args, keywords): + if not hasattr(State, name): + raise Exception('Parse Error: No such function State.%s' % name, self.current_spot.name, ast.dump(node, False)) + + for (k, v) in self.kwarg_defaults.items(): + keywords.append(ast.keyword(arg=f'{k}', value=ast.Constant(v))) + + return ast.Call( + func=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr=name, + ctx=ast.Load()), + args=args, + keywords=keywords) + + + def replace_subrule(self, target, node): + rule = ast.dump(node, False) + if rule in self.replaced_rules[target]: + return self.replaced_rules[target][rule] + + subrule_name = target + ' Subrule %d' % (1 + len(self.replaced_rules[target])) + # Save the info to be made into a rule later + self.delayed_rules.append((target, node, subrule_name)) + # Replace the call with a reference to that item + item_rule = ast.Call( + func=ast.Attribute( + value=ast.Name(id='state', ctx=ast.Load()), + attr='has', + ctx=ast.Load()), + args=[ast.Str(subrule_name), ast.Constant(self.player)], + keywords=[]) + # Cache the subrule for any others in this region + # (and reserve the item name in the process) + self.replaced_rules[target][rule] = item_rule + return item_rule + + + # Requires the target regions have been defined in the world. + def create_delayed_rules(self): + for region_name, node, subrule_name in self.delayed_rules: + region = self.world.world.get_region(region_name, self.player) + event = OOTLocation(self.player, subrule_name, type='Event', parent=region, internal=True) + event.show_in_spoiler = False + + self.current_spot = event + # This could, in theory, create further subrules. + access_rule = self.make_access_rule(self.visit(node)) + if access_rule is self.rule_cache.get('NameConstant(False)'): + event.access_rule = None + event.never = True + logging.getLogger('').debug('Dropping unreachable delayed event: %s', event.name) + else: + if access_rule is self.rule_cache.get('NameConstant(True)'): + event.always = True + set_rule(event, access_rule) + region.locations.append(event) + + self.world.make_event_item(subrule_name, event) + # Safeguard in case this is called multiple times per world + self.delayed_rules.clear() + + + def make_access_rule(self, body): + rule_str = ast.dump(body, False) + if rule_str not in self.rule_cache: + # requires consistent iteration on dicts + kwargs = [ast.arg(arg=k) for k in self.kwarg_defaults.keys()] + kwd = list(map(ast.Constant, self.kwarg_defaults.values())) + try: + self.rule_cache[rule_str] = eval(compile( + ast.fix_missing_locations( + ast.Expression(ast.Lambda( + args=ast.arguments( + posonlyargs=[], + args=[ast.arg(arg='state')], + defaults=[], + kwonlyargs=kwargs, + kw_defaults=kwd), + body=body))), + '', 'eval'), + # globals/locals. if undefined, everything in the namespace *now* would be allowed + allowed_globals) + except TypeError as e: + raise Exception('Parse Error: %s' % e, self.current_spot.name, ast.dump(body, False)) + return self.rule_cache[rule_str] + + + ## Handlers for specific internal functions used in the json logic. + + # at(region_name, rule) + # Creates an internal event at the remote region and depends on it. + def at(self, node): + # Cache this under the target (region) name + if len(node.args) < 2 or not isinstance(node.args[0], ast.Str): + raise Exception('Parse Error: invalid at() arguments', self.current_spot.name, ast.dump(node, False)) + return self.replace_subrule(node.args[0].s, node.args[1]) + + + # here(rule) + # Creates an internal event in the same region and depends on it. + def here(self, node): + if not node.args: + raise Exception('Parse Error: missing here() argument', self.current_spot.name, ast.dump(node, False)) + return self.replace_subrule( + self.current_spot.parent_region.name, + node.args[0]) + + ## Handlers for compile-time optimizations (former State functions) + + def at_day(self, node): + if self.world.ensure_tod_access: + # tod has DAY or (tod == NONE and (ss or find a path from a provider)) + # parsing is better than constructing this expression by hand + return ast.parse("(tod & TimeOfDay.DAY) if tod else (state.has_all(('Ocarina', 'Suns Song')) or state.search.can_reach(spot.parent_region, age=age, tod=TimeOfDay.DAY))", mode='eval').body + return ast.NameConstant(True) + + def at_dampe_time(self, node): + if self.world.ensure_tod_access: + # tod has DAMPE or (tod == NONE and (find a path from a provider)) + # parsing is better than constructing this expression by hand + return ast.parse("(tod & TimeOfDay.DAMPE) if tod else state.search.can_reach(spot.parent_region, age=age, tod=TimeOfDay.DAMPE)", mode='eval').body + return ast.NameConstant(True) + + def at_night(self, node): + if self.current_spot.type == 'GS Token' and self.world.logic_no_night_tokens_without_suns_song: + # Using visit here to resolve 'can_play' rule + return self.visit(ast.parse('can_play(Suns_Song)', mode='eval').body) + if self.world.ensure_tod_access: + # tod has DAMPE or (tod == NONE and (ss or find a path from a provider)) + # parsing is better than constructing this expression by hand + return ast.parse("(tod & TimeOfDay.DAMPE) if tod else (state.has_all(('Ocarina', 'Suns Song')) or state.search.can_reach(spot.parent_region, age=age, tod=TimeOfDay.DAMPE))", mode='eval').body + return ast.NameConstant(True) + + + # Parse entry point + # If spot is None, here() rules won't work. + def parse_rule(self, rule_string, spot=None): + self.current_spot = spot + return self.make_access_rule(self.visit(ast.parse(rule_string, mode='eval').body)) + + def parse_spot_rule(self, spot): + rule = spot.rule_string.split('#', 1)[0].strip() + + access_rule = self.parse_rule(rule, spot) + set_rule(spot, access_rule) + if access_rule is self.rule_cache.get('NameConstant(False)'): + spot.never = True + elif access_rule is self.rule_cache.get('NameConstant(True)'): + spot.always = True + + # Hijacking functions + def current_spot_child_access(self, node): + r = self.current_spot if type(self.current_spot) == OOTRegion else self.current_spot.parent_region + return ast.parse(f"state._oot_reach_as_age('{r.name}', 'child', {self.player})", mode='eval').body + + def current_spot_adult_access(self, node): + r = self.current_spot if type(self.current_spot) == OOTRegion else self.current_spot.parent_region + return ast.parse(f"state._oot_reach_as_age('{r.name}', 'adult', {self.player})", mode='eval').body + + def current_spot_starting_age_access(self, node): + return self.current_spot_child_access(node) if self.world.starting_age == 'child' else self.current_spot_adult_access(node) + + def has_bottle(self, node): + return ast.parse(f"state._oot_has_bottle({self.player})", mode='eval').body + + def can_live_dmg(self, node): + return ast.parse(f"state._oot_can_live_dmg({self.player}, {node.args[0].value})", mode='eval').body diff --git a/worlds/oot/Rules.py b/worlds/oot/Rules.py new file mode 100644 index 00000000..75c67d08 --- /dev/null +++ b/worlds/oot/Rules.py @@ -0,0 +1,203 @@ +from collections import deque +import logging + +from .SaveContext import SaveContext + +from BaseClasses import CollectionState +from worlds.generic.Rules import set_rule, add_rule, add_item_rule, forbid_item, item_in_locations +from ..AutoWorld import LogicMixin + + +class OOTLogic(LogicMixin): + + def _oot_has_stones(self, count, player): + return self.has_group("stones", player, count) + + def _oot_has_medallions(self, count, player): + return self.has_group("medallions", player, count) + + def _oot_has_dungeon_rewards(self, count, player): + return self.has_group("rewards", player, count) + + def _oot_has_bottle(self, player): + return self.has_group("bottles", player) + + # Used for fall damage and other situations where damage is unavoidable + def _oot_can_live_dmg(self, player, hearts): + mult = self.world.worlds[player].damage_multiplier + if hearts*4 >= 3: + return mult != 'ohko' and mult != 'quadruple' + elif hearts*4 < 3: + return mult != 'ohko' + else: + return True + + # This function operates by assuming different behavior based on the "level of recursion", handled manually. + # If it's called while self.age[player] is None, then it will set the age variable and then attempt to reach the region. + # If self.age[player] is not None, then it will compare it to the 'age' parameter, and return True iff they are equal. + # This lets us fake the OOT accessibility check that cares about age. Unfortunately it's still tied to the ground region. + def _oot_reach_as_age(self, regionname, age, player): + if self.age[player] is None: + self.age[player] = age + can_reach = self.world.get_region(regionname, player).can_reach(self) + self.age[player] = None + return can_reach + return self.age[player] == age + + # Store the age before calling this! + def _oot_update_age_reachable_regions(self, player): + self.stale[player] = False + for age in ['child', 'adult']: + self.age[player] = age + rrp = getattr(self, f'{age}_reachable_regions')[player] + bc = getattr(self, f'{age}_blocked_connections')[player] + queue = deque(getattr(self, f'{age}_blocked_connections')[player]) + start = self.world.get_region('Menu', player) + + # init on first call - this can't be done on construction since the regions don't exist yet + if not start in rrp: + rrp.add(start) + bc.update(start.exits) + queue.extend(start.exits) + + # run BFS on all connections, and keep track of those blocked by missing items + while queue: + connection = queue.popleft() + new_region = connection.connected_region + if new_region in rrp: + bc.remove(connection) + elif connection.can_reach(self): + rrp.add(new_region) + bc.remove(connection) + bc.update(new_region.exits) + queue.extend(new_region.exits) + self.path[new_region] = (new_region.name, self.path.get(connection, None)) + + +def set_rules(ootworld): + logger = logging.getLogger('') + + world = ootworld.world + player = ootworld.player + + if ootworld.logic_rules != 'no_logic': + if ootworld.triforce_hunt: + world.completion_condition[player] = lambda state: state.has('Triforce Piece', player, ootworld.triforce_goal) + else: + world.completion_condition[player] = lambda state: state.has('Triforce', player) + + # ganon can only carry triforce + world.get_location('Ganon', player).item_rule = lambda item: item.name == 'Triforce' + + # is_child = ootworld.parser.parse_rule('is_child') + # guarantee_hint = ootworld.parser.parse_rule('guarantee_hint') + + for location in ootworld.get_locations(): + if ootworld.shuffle_song_items == 'song': + if location.type == 'Song': + # must be a song, or there are songs in starting items; then it can be anything + add_item_rule(location, lambda item: + (ootworld.starting_songs and item.type != 'Song') + or (item.type == 'Song' and item.player == location.player)) + else: + add_item_rule(location, lambda item: item.type != 'Song') + + if location.type == 'Shop': + if location.name in ootworld.shop_prices: + add_item_rule(location, lambda item: item.type != 'Shop') + location.price = ootworld.shop_prices[location.name] + add_rule(location, create_shop_rule(location, ootworld.parser)) + else: + add_item_rule(location, lambda item: item.type == 'Shop' and item.player == location.player) + elif 'Deku Scrub' in location.name: + add_rule(location, create_shop_rule(location, ootworld.parser)) + else: + add_item_rule(location, lambda item: item.type != 'Shop') + + if ootworld.skip_child_zelda and location.name == 'Song from Impa': + limit_to_itemset(location, SaveContext.giveable_items) + add_item_rule(location, lambda item: item.player == location.player) + + if location.name == 'Forest Temple MQ First Room Chest' and ootworld.shuffle_bosskeys == 'dungeon' and ootworld.shuffle_smallkeys == 'dungeon' and ootworld.tokensanity == 'off': + # This location needs to be a small key. Make sure the boss key isn't placed here. + forbid_item(location, 'Boss Key (Forest Temple)', ootworld.player) + + # TODO: re-add hints once they are working + # if location.type == 'HintStone' and ootworld.hints == 'mask': + # location.add_rule(is_child) + + # if location.name in ootworld.always_hints: + # location.add_rule(guarantee_hint) + + +def create_shop_rule(location, parser): + def required_wallets(price): + if price > 500: + return 3 + if price > 200: + return 2 + if price > 99: + return 1 + return 0 + return parser.parse_rule('(Progressive_Wallet, %d)' % required_wallets(location.price)) + + +def limit_to_itemset(location, itemset): + old_rule = location.item_rule + location.item_rule = lambda item: item.name in itemset and old_rule(item) + + +# This function should be run once after the shop items are placed in the world. +# It should be run before other items are placed in the world so that logic has +# the correct checks for them. This is safe to do since every shop is still +# accessible when all items are obtained and every shop item is not. +# This function should also be called when a world is copied if the original world +# had called this function because the world.copy does not copy the rules +def set_shop_rules(ootworld): + found_bombchus = ootworld.parser.parse_rule('found_bombchus') + wallet = ootworld.parser.parse_rule('Progressive_Wallet') + wallet2 = ootworld.parser.parse_rule('(Progressive_Wallet, 2)') + for location in ootworld.world.get_filled_locations(): + if location.player == ootworld.player and location.item.type == 'Shop': + # Add wallet requirements + if location.item.name in ['Buy Arrows (50)', 'Buy Fish', 'Buy Goron Tunic', 'Buy Bombchu (20)', 'Buy Bombs (30)']: + add_rule(location, wallet) + elif location.item.name in ['Buy Zora Tunic', 'Buy Blue Fire']: + add_rule(location, wallet2) + + # Add adult only checks + if location.item.name in ['Buy Goron Tunic', 'Buy Zora Tunic']: + is_adult = ootworld.parser.parse_rule('is_adult', location) + add_rule(location, is_adult) + + # Add item prerequisite checks + if location.item.name in ['Buy Blue Fire', + 'Buy Blue Potion', + 'Buy Bottle Bug', + 'Buy Fish', + 'Buy Green Potion', + 'Buy Poe', + 'Buy Red Potion [30]', + 'Buy Red Potion [40]', + 'Buy Red Potion [50]', + 'Buy Fairy\'s Spirit']: + add_rule(location, lambda state: CollectionState._oot_has_bottle(state, ootworld.player)) + if location.item.name in ['Buy Bombchu (10)', 'Buy Bombchu (20)', 'Buy Bombchu (5)']: + add_rule(location, found_bombchus) + + +# This function should be ran once after setting up entrances and before placing items +# The goal is to automatically set item rules based on age requirements in case entrances were shuffled +def set_entrances_based_rules(ootworld): + + if ootworld.world.accessibility == 'beatable': + return + + all_state = ootworld.state_with_items(ootworld.itempool) + + for location in ootworld.get_locations(): + # If a shop is not reachable as adult, it can't have Goron Tunic or Zora Tunic as child can't buy these + if location.type == 'Shop' and not all_state._oot_reach_as_age(location.parent_region.name, 'adult', ootworld.player): + forbid_item(location, 'Buy Goron Tunic', ootworld.player) + forbid_item(location, 'Buy Zora Tunic', ootworld.player) + diff --git a/worlds/oot/SaveContext.py b/worlds/oot/SaveContext.py new file mode 100644 index 00000000..27156b27 --- /dev/null +++ b/worlds/oot/SaveContext.py @@ -0,0 +1,1000 @@ +from itertools import chain + +class Address(): + prev_address = None + + def __init__(self, address=None, size=4, mask=0xFFFFFFFF, max=None, choices=None, value=None): + if address is None: + self.address = Address.prev_address + else: + self.address = address + self.value = value + self.size = size + self.choices = choices + self.mask = mask + + Address.prev_address = self.address + self.size + + self.bit_offset = 0 + while mask & 1 == 0: + mask = mask >> 1 + self.bit_offset += 1 + + if max is None: + self.max = mask + else: + self.max = max + + + def get_value(self, default=0): + if self.value is None: + return default + return self.value + + + def get_value_raw(self): + if self.value is None: + return None + + value = self.value + if self.choices is not None: + value = self.choices[value] + if not isinstance(value, int): + raise ValueError("Invalid value type '%s'" % str(value)) + + if isinstance(value, bool): + value = 1 if value else 0 + if value > self.max: + value = self.max + + value = (value << self.bit_offset) & self.mask + return value + + + def set_value_raw(self, value): + if value is None: + self.value = None + return + + if not isinstance(value, int): + raise ValueError("Invalid value type '%s'" % str(value)) + + value = (value & self.mask) >> self.bit_offset + if value > self.max: + value = self.max + + if self.choices is not None: + for choice_name, choice_value in self.choices.items(): + if choice_value == value: + value = choice_name + break + + self.value = value + + + def get_writes(self, save_context): + if self.value is None: + return + + value = self.get_value_raw() + if value is None: + return + + values = zip(Address.to_bytes(value, self.size), + Address.to_bytes(self.mask, self.size)) + + for i, (byte, mask) in enumerate(values): + if mask == 0: + continue + if mask == 0xFF: + save_context.write_byte(self.address + i, byte) + else: + save_context.write_bits(self.address + i, byte, mask=mask) + + + def to_bytes(value, size): + ret = [] + for _ in range(size): + ret.insert(0, value & 0xFF) + value = value >> 8 + return ret + + +class SaveContext(): + def __init__(self): + self.save_bits = {} + self.save_bytes = {} + self.addresses = self.get_save_context_addresses() + + + # will set the bits of value to the offset in the save (or'ing them with what is already there) + def write_bits(self, address, value, mask=None, predicate=None): + if predicate and not predicate(value): + return + + if mask is not None: + value = value & mask + + if address in self.save_bytes: + old_val = self.save_bytes[address] + if mask is not None: + old_val &= ~mask + value = old_val | value + self.write_byte(address, value, predicate) + elif address in self.save_bits: + if mask is not None: + self.save_bits[address] &= ~mask + self.save_bits[address] |= value + else: + self.save_bits[address] = value + + + # will overwrite the byte at offset with the given value + def write_byte(self, address, value, predicate=None): + if predicate and not predicate(value): + return + + if address in self.save_bits: + del self.save_bits[address] + + self.save_bytes[address] = value + + + # will overwrite the byte at offset with the given value + def write_bytes(self, address, bytes, predicate=None): + for i, value in enumerate(bytes): + self.write_byte(address + i, value, predicate) + + + def write_save_entry(self, address): + if isinstance(address, dict): + for name, sub_address in address.items(): + self.write_save_entry(sub_address) + elif isinstance(address, list): + for sub_address in address: + self.write_save_entry(sub_address) + else: + address.get_writes(self) + + + def set_ammo_max(self): + ammo_maxes = { + 'stick' : ('stick_upgrade', [10, 10, 20, 30]), + 'nut' : ('nut_upgrade', [20, 20, 30, 40]), + 'bomb' : ('bomb_bag', [00, 20, 30, 40]), + 'bow' : ('quiver', [00, 30, 40, 50]), + 'slingshot' : ('bullet_bag', [00, 30, 40, 50]), + 'rupees' : ('wallet', [99, 200, 500, 999]), + } + + for ammo, (upgrade, maxes) in ammo_maxes.items(): + upgrade_count = self.addresses['upgrades'][upgrade].get_value() + try: + ammo_max = maxes[upgrade_count] + except IndexError: + ammo_max = maxes[-1] + if ammo == 'rupees': + self.addresses[ammo].max = ammo_max + else: + self.addresses['ammo'][ammo].max = ammo_max + + + # will overwrite the byte at offset with the given value + def write_save_table(self, rom): + self.set_ammo_max() + for name, address in self.addresses.items(): + self.write_save_entry(address) + + save_table = [] + for address, value in self.save_bits.items(): + if value != 0: + save_table += [(address & 0xFF00) >> 8, address & 0xFF, 0x00, value] + for address, value in self.save_bytes.items(): + save_table += [(address & 0xFF00) >> 8, address & 0xFF, 0x01, value] + save_table += [0x00,0x00,0x00,0x00] + + table_len = len(save_table) + if table_len > 0x400: + raise Exception("The Initial Save Table has exceeded its maximum capacity: 0x%03X/0x400" % table_len) + rom.write_bytes(rom.sym('INITIAL_SAVE_DATA'), save_table) + + + def give_bottle(self, item, count): + for bottle_id in range(4): + item_slot = 'bottle_%d' % (bottle_id + 1) + if self.addresses['item_slot'][item_slot].get_value(0xFF) != 0xFF: + continue + + self.addresses['item_slot'][item_slot].value = SaveContext.bottle_types[item] + count -= 1 + + if count == 0: + return + + + def give_health(self, health): + health += self.addresses['health_capacity'].get_value(0x30) / 0x10 + health += self.addresses['quest']['heart_pieces'].get_value() / 4 + + self.addresses['health_capacity'].value = int(health) * 0x10 + self.addresses['health'].value = int(health) * 0x10 + self.addresses['quest']['heart_pieces'].value = int((health % 1) * 4) + + + def give_raw_item(self, item): + if item.endswith(')'): + item_base, count = item[:-1].split(' (', 1) + if count.isdigit(): + return self.give_item(item_base, count=int(count)) + return self.give_item(item) + + + def give_item(self, item, count=1): + if item in SaveContext.bottle_types: + self.give_bottle(item, count) + elif item in ["Piece of Heart", "Piece of Heart (Treasure Chest Game)"]: + self.give_health(count / 4) + elif item == "Heart Container": + self.give_health(count) + elif item == "Bombchu Item": + self.give_bombchu_item() + elif item in SaveContext.save_writes_table: + for address, value in SaveContext.save_writes_table[item].items(): + if value is None: + value = count + elif isinstance(value, list): + value = value[min(len(value), count) - 1] + elif isinstance(value, bool): + value = 1 if value else 0 + + address_value = self.addresses + prev_sub_address = 'Save Context' + for sub_address in address.split('.'): + if sub_address not in address_value: + raise ValueError('Unknown key %s in %s of SaveContext' % (sub_address, prev_sub_address)) + + if isinstance(address_value, list): + sub_address = int(sub_address) + + address_value = address_value[sub_address] + prev_sub_address = sub_address + if not isinstance(address_value, Address): + raise ValueError('%s does not resolve to an Address in SaveContext' % (sub_address)) + + if isinstance(value, int) and value < address_value.get_value(): + continue + + address_value.value = value + else: + raise ValueError("Cannot give unknown starting item %s" % item) + + + def give_bombchu_item(self): + self.give_item("Bombchus", 0) + + + def equip_default_items(self, age): + self.equip_items(age, 'equips_' + age) + + + def equip_current_items(self, age): + self.equip_items(age, 'equips') + + + def equip_items(self, age, equip_type): + if age not in ['child', 'adult']: + raise ValueError("Age must be 'adult' or 'child', not %s" % age) + + if equip_type not in ['equips', 'equips_child', 'equips_adult']: + raise ValueError("Equip type must be 'equips', 'equips_child' or 'equips_adult', not %s" % equip_type) + + age = 'equips_' + age + c_buttons = list(self.addresses[age]['button_slots'].keys()) + for item_slot in SaveContext.equipable_items[age]['items']: + item = self.addresses['item_slot'][item_slot].get_value('none') + if item != 'none': + c_button = c_buttons.pop() + self.addresses[equip_type]['button_slots'][c_button].value = item_slot + self.addresses[equip_type]['button_items'][c_button].value = item + if not c_buttons: + break + + for equip_item, equip_addresses in self.addresses[age]['equips'].items(): + for item in SaveContext.equipable_items[age][equip_item]: + if self.addresses['equip_items'][item].get_value(): + item_value = self.addresses['equip_items'][item].get_value_raw() + self.addresses[equip_type]['equips'][equip_item].set_value_raw(item_value) + if equip_item == 'tunic': + self.addresses[equip_type]['equips'][equip_item].value = 1 + if equip_item == 'sword': + self.addresses[equip_type]['button_items']['b'].value = item + break + + + def get_save_context_addresses(self): + return { + 'entrance_index' : Address(0x0000, size=4), + 'link_age' : Address(size=4, max=1), + 'unk_00' : Address(size=2), + 'cutscene_index' : Address(size=2), + 'time_of_day' : Address(size=2), + 'unk_01' : Address(size=2), + 'night_flag' : Address(size=4, max=1), + 'unk_02' : Address(size=8), + 'id' : Address(size=6), + 'deaths' : Address(size=2), + 'file_name' : Address(size=8), + 'n64dd_flag' : Address(size=2), + 'health_capacity' : Address(size=2, max=0x140), + 'health' : Address(size=2, max=0x140), + 'magic_level' : Address(size=1, max=2), + 'magic' : Address(size=1, max=0x60), + 'rupees' : Address(size=2), + 'bgs_hits_left' : Address(size=2), + 'navi_timer' : Address(size=2), + 'magic_acquired' : Address(size=1, max=1), + 'unk_03' : Address(size=1), + 'double_magic' : Address(size=1, max=1), + 'double_defense' : Address(size=1, max=1), + 'bgs_flag' : Address(size=1, max=1), + 'unk_05' : Address(size=1), + + # Equiped Items + 'equips_child' : { + 'button_items' : { + 'b' : Address(size=1, choices=SaveContext.item_id_map), + 'left' : Address(size=1, choices=SaveContext.item_id_map), + 'down' : Address(size=1, choices=SaveContext.item_id_map), + 'right' : Address(size=1, choices=SaveContext.item_id_map), + }, + 'button_slots' : { + 'left' : Address(size=1, choices=SaveContext.slot_id_map), + 'down' : Address(size=1, choices=SaveContext.slot_id_map), + 'right' : Address(size=1, choices=SaveContext.slot_id_map), + }, + 'equips' : { + 'sword' : Address(0x0048, size=2, mask=0x000F), + 'shield' : Address(0x0048, size=2, mask=0x00F0), + 'tunic' : Address(0x0048, size=2, mask=0x0F00), + 'boots' : Address(0x0048, size=2, mask=0xF000), + }, + }, + 'equips_adult' : { + 'button_items' : { + 'b' : Address(size=1, choices=SaveContext.item_id_map), + 'left' : Address(size=1, choices=SaveContext.item_id_map), + 'down' : Address(size=1, choices=SaveContext.item_id_map), + 'right' : Address(size=1, choices=SaveContext.item_id_map), + }, + 'button_slots' : { + 'left' : Address(size=1, choices=SaveContext.slot_id_map), + 'down' : Address(size=1, choices=SaveContext.slot_id_map), + 'right' : Address(size=1, choices=SaveContext.slot_id_map), + }, + 'equips' : { + 'sword' : Address(0x0052, size=2, mask=0x000F), + 'shield' : Address(0x0052, size=2, mask=0x00F0), + 'tunic' : Address(0x0052, size=2, mask=0x0F00), + 'boots' : Address(0x0052, size=2, mask=0xF000), + }, + }, + 'unk_06' : Address(size=0x12), + 'scene_index' : Address(size=2), + + 'equips' : { + 'button_items' : { + 'b' : Address(size=1, choices=SaveContext.item_id_map), + 'left' : Address(size=1, choices=SaveContext.item_id_map), + 'down' : Address(size=1, choices=SaveContext.item_id_map), + 'right' : Address(size=1, choices=SaveContext.item_id_map), + }, + 'button_slots' : { + 'left' : Address(size=1, choices=SaveContext.slot_id_map), + 'down' : Address(size=1, choices=SaveContext.slot_id_map), + 'right' : Address(size=1, choices=SaveContext.slot_id_map), + }, + 'equips' : { + 'sword' : Address(0x0070, size=2, mask=0x000F, max=3), + 'shield' : Address(0x0070, size=2, mask=0x00F0, max=3), + 'tunic' : Address(0x0070, size=2, mask=0x0F00, max=3), + 'boots' : Address(0x0070, size=2, mask=0xF000, max=3), + }, + }, + 'unk_07' : Address(size=2), + + # Item Slots + 'item_slot' : { + 'stick' : Address(size=1, choices=SaveContext.item_id_map), + 'nut' : Address(size=1, choices=SaveContext.item_id_map), + 'bomb' : Address(size=1, choices=SaveContext.item_id_map), + 'bow' : Address(size=1, choices=SaveContext.item_id_map), + 'fire_arrow' : Address(size=1, choices=SaveContext.item_id_map), + 'dins_fire' : Address(size=1, choices=SaveContext.item_id_map), + 'slingshot' : Address(size=1, choices=SaveContext.item_id_map), + 'ocarina' : Address(size=1, choices=SaveContext.item_id_map), + 'bombchu' : Address(size=1, choices=SaveContext.item_id_map), + 'hookshot' : Address(size=1, choices=SaveContext.item_id_map), + 'ice_arrow' : Address(size=1, choices=SaveContext.item_id_map), + 'farores_wind' : Address(size=1, choices=SaveContext.item_id_map), + 'boomerang' : Address(size=1, choices=SaveContext.item_id_map), + 'lens' : Address(size=1, choices=SaveContext.item_id_map), + 'beans' : Address(size=1, choices=SaveContext.item_id_map), + 'hammer' : Address(size=1, choices=SaveContext.item_id_map), + 'light_arrow' : Address(size=1, choices=SaveContext.item_id_map), + 'nayrus_love' : Address(size=1, choices=SaveContext.item_id_map), + 'bottle_1' : Address(size=1, choices=SaveContext.item_id_map), + 'bottle_2' : Address(size=1, choices=SaveContext.item_id_map), + 'bottle_3' : Address(size=1, choices=SaveContext.item_id_map), + 'bottle_4' : Address(size=1, choices=SaveContext.item_id_map), + 'adult_trade' : Address(size=1, choices=SaveContext.item_id_map), + 'child_trade' : Address(size=1, choices=SaveContext.item_id_map), + }, + + # Item Ammo + 'ammo' : { + 'stick' : Address(size=1), + 'nut' : Address(size=1), + 'bomb' : Address(size=1), + 'bow' : Address(size=1), + 'fire_arrow' : Address(size=1, max=0), + 'dins_fire' : Address(size=1, max=0), + 'slingshot' : Address(size=1), + 'ocarina' : Address(size=1, max=0), + 'bombchu' : Address(size=1, max=50), + 'hookshot' : Address(size=1, max=0), + 'ice_arrow' : Address(size=1, max=0), + 'farores_wind' : Address(size=1, max=0), + 'boomerang' : Address(size=1, max=0), + 'lens' : Address(size=1, max=0), + 'beans' : Address(size=1, max=10), + }, + 'magic_beans_sold' : Address(size=1, max=10), + + # Equipment + 'equip_items' : { + 'kokiri_sword' : Address(0x009C, size=2, mask=0x0001), + 'master_sword' : Address(0x009C, size=2, mask=0x0002), + 'biggoron_sword' : Address(0x009C, size=2, mask=0x0004), + 'broken_knife' : Address(0x009C, size=2, mask=0x0008), + 'deku_shield' : Address(0x009C, size=2, mask=0x0010), + 'hylian_shield' : Address(0x009C, size=2, mask=0x0020), + 'mirror_shield' : Address(0x009C, size=2, mask=0x0040), + 'kokiri_tunic' : Address(0x009C, size=2, mask=0x0100), + 'goron_tunic' : Address(0x009C, size=2, mask=0x0200), + 'zora_tunic' : Address(0x009C, size=2, mask=0x0400), + 'kokiri_boots' : Address(0x009C, size=2, mask=0x1000), + 'iron_boots' : Address(0x009C, size=2, mask=0x2000), + 'hover_boots' : Address(0x009C, size=2, mask=0x4000), + }, + + 'unk_08' : Address(size=2), + + # Upgrades + 'upgrades' : { + 'quiver' : Address(0x00A0, mask=0x00000007, max=3), + 'bomb_bag' : Address(0x00A0, mask=0x00000038, max=3), + 'strength_upgrade' : Address(0x00A0, mask=0x000001C0, max=3), + 'diving_upgrade' : Address(0x00A0, mask=0x00000E00, max=2), + 'wallet' : Address(0x00A0, mask=0x00003000, max=3), + 'bullet_bag' : Address(0x00A0, mask=0x0001C000, max=3), + 'stick_upgrade' : Address(0x00A0, mask=0x000E0000, max=3), + 'nut_upgrade' : Address(0x00A0, mask=0x00700000, max=3), + }, + + # Medallions + 'quest' : { + 'medallions' : { + 'forest' : Address(0x00A4, mask=0x00000001), + 'fire' : Address(0x00A4, mask=0x00000002), + 'water' : Address(0x00A4, mask=0x00000004), + 'spirit' : Address(0x00A4, mask=0x00000008), + 'shadow' : Address(0x00A4, mask=0x00000010), + 'light' : Address(0x00A4, mask=0x00000020), + + }, + 'songs' : { + 'minuet_of_forest' : Address(0x00A4, mask=0x00000040), + 'bolero_of_fire' : Address(0x00A4, mask=0x00000080), + 'serenade_of_water' : Address(0x00A4, mask=0x00000100), + 'requiem_of_spirit' : Address(0x00A4, mask=0x00000200), + 'nocturne_of_shadow' : Address(0x00A4, mask=0x00000400), + 'prelude_of_light' : Address(0x00A4, mask=0x00000800), + 'zeldas_lullaby' : Address(0x00A4, mask=0x00001000), + 'eponas_song' : Address(0x00A4, mask=0x00002000), + 'sarias_song' : Address(0x00A4, mask=0x00004000), + 'suns_song' : Address(0x00A4, mask=0x00008000), + 'song_of_time' : Address(0x00A4, mask=0x00010000), + 'song_of_storms' : Address(0x00A4, mask=0x00020000), + }, + 'stones' : { + 'kokiris_emerald' : Address(0x00A4, mask=0x00040000), + 'gorons_ruby' : Address(0x00A4, mask=0x00080000), + 'zoras_sapphire' : Address(0x00A4, mask=0x00100000), + }, + 'stone_of_agony' : Address(0x00A4, mask=0x00200000), + 'gerudos_card' : Address(0x00A4, mask=0x00400000), + 'gold_skulltula' : Address(0x00A4, mask=0x00800000), + 'heart_pieces' : Address(0x00A4, mask=0xFF000000), + }, + + # Dungeon Items + 'dungeon_items' : { + 'deku' : { + 'boss_key' : Address(0x00A8, size=1, mask=0x01), + 'compass' : Address(0x00A8, size=1, mask=0x02), + 'map' : Address(0x00A8, size=1, mask=0x04), + }, + 'dodongo' : { + 'boss_key' : Address(0x00A9, size=1, mask=0x01), + 'compass' : Address(0x00A9, size=1, mask=0x02), + 'map' : Address(0x00A9, size=1, mask=0x04), + }, + 'jabu' : { + 'boss_key' : Address(0x00AA, size=1, mask=0x01), + 'compass' : Address(0x00AA, size=1, mask=0x02), + 'map' : Address(0x00AA, size=1, mask=0x04), + }, + 'forest' : { + 'boss_key' : Address(0x00AB, size=1, mask=0x01), + 'compass' : Address(0x00AB, size=1, mask=0x02), + 'map' : Address(0x00AB, size=1, mask=0x04), + }, + 'fire' : { + 'boss_key' : Address(0x00AC, size=1, mask=0x01), + 'compass' : Address(0x00AC, size=1, mask=0x02), + 'map' : Address(0x00AC, size=1, mask=0x04), + }, + 'water' : { + 'boss_key' : Address(0x00AD, size=1, mask=0x01), + 'compass' : Address(0x00AD, size=1, mask=0x02), + 'map' : Address(0x00AD, size=1, mask=0x04), + }, + 'spirit' : { + 'boss_key' : Address(0x00AE, size=1, mask=0x01), + 'compass' : Address(0x00AE, size=1, mask=0x02), + 'map' : Address(0x00AE, size=1, mask=0x04), + }, + 'shadow' : { + 'boss_key' : Address(0x00AF, size=1, mask=0x01), + 'compass' : Address(0x00AF, size=1, mask=0x02), + 'map' : Address(0x00AF, size=1, mask=0x04), + }, + 'botw' : { + 'boss_key' : Address(0x00B0, size=1, mask=0x01), + 'compass' : Address(0x00B0, size=1, mask=0x02), + 'map' : Address(0x00B0, size=1, mask=0x04), + }, + 'ice' : { + 'boss_key' : Address(0x00B1, size=1, mask=0x01), + 'compass' : Address(0x00B1, size=1, mask=0x02), + 'map' : Address(0x00B1, size=1, mask=0x04), + }, + 'gt' : { + 'boss_key' : Address(0x00B2, size=1, mask=0x01), + 'compass' : Address(0x00B2, size=1, mask=0x02), + 'map' : Address(0x00B2, size=1, mask=0x04), + }, + 'gtg' : { + 'boss_key' : Address(0x00B3, size=1, mask=0x01), + 'compass' : Address(0x00B3, size=1, mask=0x02), + 'map' : Address(0x00B3, size=1, mask=0x04), + }, + 'fortress' : { + 'boss_key' : Address(0x00B4, size=1, mask=0x01), + 'compass' : Address(0x00B4, size=1, mask=0x02), + 'map' : Address(0x00B4, size=1, mask=0x04), + }, + 'gc' : { + 'boss_key' : Address(0x00B5, size=1, mask=0x01), + 'compass' : Address(0x00B5, size=1, mask=0x02), + 'map' : Address(0x00B5, size=1, mask=0x04), + }, + 'unused' : Address(size=6), + }, + 'keys' : { + 'deku' : Address(size=1), + 'dodongo' : Address(size=1), + 'jabu' : Address(size=1), + 'forest' : Address(size=1), + 'fire' : Address(size=1), + 'water' : Address(size=1), + 'spirit' : Address(size=1), + 'shadow' : Address(size=1), + 'botw' : Address(size=1), + 'ice' : Address(size=1), + 'gt' : Address(size=1), + 'gtg' : Address(size=1), + 'fortress' : Address(size=1), + 'gc' : Address(size=1), + 'unused' : Address(size=5), + }, + 'defense_hearts' : Address(size=1, max=20), + 'gs_tokens' : Address(size=2, max=100), + 'triforce_pieces' : Address(0xD4 + 0x1C * 0x48 + 0x10, size=4), # Unused word in scene x48 + } + + + item_id_map = { + 'none' : 0xFF, + 'stick' : 0x00, + 'nut' : 0x01, + 'bomb' : 0x02, + 'bow' : 0x03, + 'fire_arrow' : 0x04, + 'dins_fire' : 0x05, + 'slingshot' : 0x06, + 'fairy_ocarina' : 0x07, + 'ocarina_of_time' : 0x08, + 'bombchu' : 0x09, + 'hookshot' : 0x0A, + 'longshot' : 0x0B, + 'ice_arrow' : 0x0C, + 'farores_wind' : 0x0D, + 'boomerang' : 0x0E, + 'lens' : 0x0F, + 'beans' : 0x10, + 'hammer' : 0x11, + 'light_arrow' : 0x12, + 'nayrus_love' : 0x13, + 'bottle' : 0x14, + 'red_potion' : 0x15, + 'green_potion' : 0x16, + 'blue_potion' : 0x17, + 'fairy' : 0x18, + 'fish' : 0x19, + 'milk' : 0x1A, + 'letter' : 0x1B, + 'blue_fire' : 0x1C, + 'bug' : 0x1D, + 'big_poe' : 0x1E, + 'half_milk' : 0x1F, + 'poe' : 0x20, + 'weird_egg' : 0x21, + 'chicken' : 0x22, + 'zeldas_letter' : 0x23, + 'keaton_mask' : 0x24, + 'skull_mask' : 0x25, + 'spooky_mask' : 0x26, + 'bunny_hood' : 0x27, + 'goron_mask' : 0x28, + 'zora_mask' : 0x29, + 'gerudo_mask' : 0x2A, + 'mask_of_truth' : 0x2B, + 'sold_out' : 0x2C, + 'pocket_egg' : 0x2D, + 'pocket_cucco' : 0x2E, + 'cojiro' : 0x2F, + 'odd_mushroom' : 0x30, + 'odd_potion' : 0x31, + 'poachers_saw' : 0x32, + 'broken_gorons_sword' : 0x33, + 'prescription' : 0x34, + 'eyeball_frog' : 0x35, + 'eye_drops' : 0x36, + 'claim_check' : 0x37, + 'bow_fire_arrow' : 0x38, + 'bow_ice_arrow' : 0x39, + 'bow_light_arrow' : 0x3A, + 'kokiri_sword' : 0x3B, + 'master_sword' : 0x3C, + 'biggoron_sword' : 0x3D, + 'deku_shield' : 0x3E, + 'hylian_shield' : 0x3F, + 'mirror_shield' : 0x40, + 'kokiri_tunic' : 0x41, + 'goron_tunic' : 0x42, + 'zora_tunic' : 0x43, + 'kokiri_boots' : 0x44, + 'iron_boots' : 0x45, + 'hover_boots' : 0x46, + 'bullet_bag_30' : 0x47, + 'bullet_bag_40' : 0x48, + 'bullet_bag_50' : 0x49, + 'quiver_30' : 0x4A, + 'quiver_40' : 0x4B, + 'quiver_50' : 0x4C, + 'bomb_bag_20' : 0x4D, + 'bomb_bag_30' : 0x4E, + 'bomb_bag_40' : 0x4F, + 'gorons_bracelet' : 0x40, + 'silver_gauntlets' : 0x41, + 'golden_gauntlets' : 0x42, + 'silver_scale' : 0x43, + 'golden_scale' : 0x44, + 'broken_giants_knife' : 0x45, + 'adults_wallet' : 0x46, + 'giants_wallet' : 0x47, + 'deku_seeds' : 0x48, + 'fishing_pole' : 0x49, + 'minuet' : 0x4A, + 'bolero' : 0x4B, + 'serenade' : 0x4C, + 'requiem' : 0x4D, + 'nocturne' : 0x4E, + 'prelude' : 0x4F, + 'zeldas_lullaby' : 0x50, + 'eponas_song' : 0x51, + 'sarias_song' : 0x52, + 'suns_song' : 0x53, + 'song_of_time' : 0x54, + 'song_of_storms' : 0x55, + 'forest_medallion' : 0x56, + 'fire_medallion' : 0x57, + 'water_medallion' : 0x58, + 'spirit_medallion' : 0x59, + 'shadow_medallion' : 0x5A, + 'light_medallion' : 0x5B, + 'kokiris_emerald' : 0x5C, + 'gorons_ruby' : 0x5D, + 'zoras_sapphire' : 0x5E, + 'stone_of_agony' : 0x5F, + 'gerudos_card' : 0x60, + 'gold_skulltula' : 0x61, + 'heart_container' : 0x62, + 'piece_of_heart' : 0x63, + 'boss_key' : 0x64, + 'compass' : 0x65, + 'dungeon_map' : 0x66, + 'small_key' : 0x67, + } + + + slot_id_map = { + 'stick' : 0x00, + 'nut' : 0x01, + 'bomb' : 0x02, + 'bow' : 0x03, + 'fire_arrow' : 0x04, + 'dins_fire' : 0x05, + 'slingshot' : 0x06, + 'ocarina' : 0x07, + 'bombchu' : 0x08, + 'hookshot' : 0x09, + 'ice_arrow' : 0x0A, + 'farores_wind' : 0x0B, + 'boomerang' : 0x0C, + 'lens' : 0x0D, + 'beans' : 0x0E, + 'hammer' : 0x0F, + 'light_arrow' : 0x10, + 'nayrus_love' : 0x11, + 'bottle_1' : 0x12, + 'bottle_2' : 0x13, + 'bottle_3' : 0x14, + 'bottle_4' : 0x15, + 'adult_trade' : 0x16, + 'child_trade' : 0x17, + } + + + bottle_types = { + "Bottle" : 'bottle', + "Bottle with Red Potion" : 'red_potion', + "Bottle with Green Potion" : 'green_potion', + "Bottle with Blue Potion" : 'blue_potion', + "Bottle with Fairy" : 'fairy', + "Bottle with Fish" : 'fish', + "Bottle with Milk" : 'milk', + "Rutos Letter" : 'letter', + "Bottle with Blue Fire" : 'blue_fire', + "Bottle with Bugs" : 'bug', + "Bottle with Big Poe" : 'big_poe', + "Bottle with Milk (Half)" : 'half_milk', + "Bottle with Poe" : 'poe', + } + + + save_writes_table = { + "Deku Stick Capacity": { + 'item_slot.stick' : 'stick', + 'upgrades.stick_upgrade' : [2,3], + }, + "Deku Sticks": { + 'item_slot.stick' : 'stick', + 'upgrades.stick_upgrade' : 1, + 'ammo.stick' : None, + }, + "Deku Nut Capacity": { + 'item_slot.nut' : 'nut', + 'upgrades.nut_upgrade' : [2,3], + }, + "Deku Nuts": { + 'item_slot.nut' : 'nut', + 'upgrades.nut_upgrade' : 1, + 'ammo.nut' : None, + }, + "Bomb Bag": { + 'item_slot.bomb' : 'bomb', + 'upgrades.bomb_bag' : None, + }, + "Bombs" : { + 'ammo.bomb' : None, + }, + "Bombchus" : { + 'item_slot.bombchu' : 'bombchu', + 'ammo.bombchu' : None, + }, + "Bow" : { + 'item_slot.bow' : 'bow', + 'upgrades.quiver' : None, + }, + "Arrows" : { + 'ammo.bow' : None, + }, + "Slingshot" : { + 'item_slot.slingshot' : 'slingshot', + 'upgrades.bullet_bag' : None, + }, + "Deku Seeds" : { + 'ammo.slingshot' : None, + }, + "Magic Bean" : { + 'item_slot.beans' : 'beans', + 'ammo.beans' : None, + 'magic_beans_sold' : None, + }, + "Fire Arrows" : {'item_slot.fire_arrow' : 'fire_arrow'}, + "Ice Arrows" : {'item_slot.ice_arrow' : 'ice_arrow'}, + "Light Arrows" : {'item_slot.light_arrow' : 'light_arrow'}, + "Dins Fire" : {'item_slot.dins_fire' : 'dins_fire'}, + "Farores Wind" : {'item_slot.farores_wind' : 'farores_wind'}, + "Nayrus Love" : {'item_slot.nayrus_love' : 'nayrus_love'}, + "Ocarina" : {'item_slot.ocarina' : ['fairy_ocarina', 'ocarina_of_time']}, + "Progressive Hookshot" : {'item_slot.hookshot' : ['hookshot', 'longshot']}, + "Boomerang" : {'item_slot.boomerang' : 'boomerang'}, + "Lens of Truth" : {'item_slot.lens' : 'lens'}, + "Megaton Hammer" : {'item_slot.hammer' : 'hammer'}, + "Pocket Egg" : {'item_slot.adult_trade' : 'pocket_egg'}, + "Pocket Cucco" : {'item_slot.adult_trade' : 'pocket_cucco'}, + "Cojiro" : {'item_slot.adult_trade' : 'cojiro'}, + "Odd Mushroom" : {'item_slot.adult_trade' : 'odd_mushroom'}, + "Poachers Saw" : {'item_slot.adult_trade' : 'poachers_saw'}, + "Broken Sword" : {'item_slot.adult_trade' : 'broken_knife'}, + "Prescription" : {'item_slot.adult_trade' : 'prescription'}, + "Eyeball Frog" : {'item_slot.adult_trade' : 'eyeball_frog'}, + "Eyedrops" : {'item_slot.adult_trade' : 'eye_drops'}, + "Claim Check" : {'item_slot.adult_trade' : 'claim_check'}, + "Weird Egg" : {'item_slot.child_trade' : 'weird_egg'}, + "Chicken" : {'item_slot.child_trade' : 'chicken'}, + "Zeldas Letter" : {'item_slot.child_trade' : 'zeldas_letter'}, + "Goron Tunic" : {'equip_items.goron_tunic' : True}, + "Zora Tunic" : {'equip_items.zora_tunic' : True}, + "Iron Boots" : {'equip_items.iron_boots' : True}, + "Hover Boots" : {'equip_items.hover_boots' : True}, + "Deku Shield" : {'equip_items.deku_shield' : True}, + "Hylian Shield" : {'equip_items.hylian_shield' : True}, + "Mirror Shield" : {'equip_items.mirror_shield' : True}, + "Kokiri Sword" : {'equip_items.kokiri_sword' : True}, + "Master Sword" : {'equip_items.master_sword' : True}, + "Giants Knife" : { + 'equip_items.biggoron_sword' : True, + 'bgs_hits_left' : 8, + }, + "Biggoron Sword" : { + 'equip_items.biggoron_sword' : True, + 'bgs_flag' : True, + 'bgs_hits_left' : 1, + }, + "Gerudo Membership Card" : {'quest.gerudos_card' : True}, + "Stone of Agony" : {'quest.stone_of_agony' : True}, + "Zeldas Lullaby" : {'quest.songs.zeldas_lullaby' : True}, + "Eponas Song" : {'quest.songs.eponas_song' : True}, + "Sarias Song" : {'quest.songs.sarias_song' : True}, + "Suns Song" : {'quest.songs.suns_song' : True}, + "Song of Time" : {'quest.songs.song_of_time' : True}, + "Song of Storms" : {'quest.songs.song_of_storms' : True}, + "Minuet of Forest" : {'quest.songs.minuet_of_forest' : True}, + "Bolero of Fire" : {'quest.songs.bolero_of_fire' : True}, + "Serenade of Water" : {'quest.songs.serenade_of_water' : True}, + "Requiem of Spirit" : {'quest.songs.requiem_of_spirit' : True}, + "Nocturne of Shadow" : {'quest.songs.nocturne_of_shadow' : True}, + "Prelude of Light" : {'quest.songs.prelude_of_light' : True}, + "Kokiri Emerald" : {'quest.stones.kokiris_emerald' : True}, + "Goron Ruby" : {'quest.stones.gorons_ruby' : True}, + "Zora Sapphire" : {'quest.stones.zoras_sapphire' : True}, + "Light Medallion" : {'quest.medallions.light' : True}, + "Forest Medallion" : {'quest.medallions.forest' : True}, + "Fire Medallion" : {'quest.medallions.fire' : True}, + "Water Medallion" : {'quest.medallions.water' : True}, + "Spirit Medallion" : {'quest.medallions.spirit' : True}, + "Shadow Medallion" : {'quest.medallions.shadow' : True}, + "Progressive Strength Upgrade" : {'upgrades.strength_upgrade' : None}, + "Progressive Scale" : {'upgrades.diving_upgrade' : None}, + "Progressive Wallet" : {'upgrades.wallet' : None}, + "Gold Skulltula Token" : { + 'quest.gold_skulltula' : True, + 'gs_tokens' : None, + }, + "Double Defense" : { + 'double_defense' : True, + 'defense_hearts' : 20, + }, + "Magic Meter" : { + 'magic_acquired' : True, + 'magic' : [0x30, 0x60], + 'magic_level' : None, + 'double_magic' : [False, True], + }, + "Rupee" : {'rupees' : None}, + "Rupees" : {'rupees' : None}, + "Magic Bean Pack" : { + 'item_slot.beans' : 'beans', + 'ammo.beans' : 10 + }, + "Triforce Piece" : {'triforce_pieces': None}, + } + + giveable_items = set(chain(save_writes_table.keys(), bottle_types.keys(), + ["Piece of Heart", "Piece of Heart (Treasure Chest Game)", "Heart Container", "Rupee (1)"])) + + + equipable_items = { + 'equips_adult' : { + 'items': [ + 'hookshot', + 'hammer', + 'bomb', + 'bow', + 'nut', + 'lens', + 'farores_wind', + 'dins_fire', + 'bombchu', + 'nayrus_love', + 'adult_trade', + 'bottle_1', + 'bottle_2', + 'bottle_3', + 'bottle_4', + ], + 'sword' : [ + 'biggoron_sword', + 'master_sword', + ], + 'shield' : [ + 'mirror_shield', + 'hylian_shield', + ], + 'tunic' : [ + 'goron_tunic', + 'zora_tunic', + 'kokiri_tunic', + ], + 'boots' : [ + 'kokiri_boots' + ], + }, + 'equips_child' : { + 'items': [ + 'bomb', + 'boomerang', + 'slingshot', + 'stick', + 'nut', + 'lens', + 'farores_wind', + 'dins_fire', + 'bombchu', + 'nayrus_love', + 'beans', + 'child_trade', + 'bottle_1', + 'bottle_2', + 'bottle_3', + 'bottle_4', + ], + 'sword' : [ + 'kokiri_sword', + ], + 'shield' : [ + 'deku_shield', + 'hylian_shield', + ], + 'tunic' : [ + 'kokiri_tunic', + ], + 'boots' : [ + 'kokiri_boots', + ], + } + } diff --git a/worlds/oot/Sounds.py b/worlds/oot/Sounds.py new file mode 100644 index 00000000..685e39c5 --- /dev/null +++ b/worlds/oot/Sounds.py @@ -0,0 +1,212 @@ +# SOUNDS.PY +# +# A data-oriented module created to avoid cluttering (and entangling) other, +# more important modules with sound data. +# +# Tags +# To easily fetch related sounds by their properties. This seems generally +# better than the alternative of defining long lists by hand. You still can, of +# course. Categorizing sounds with more useful tags will require some work. Do +# this as needed. +# +# Sounds +# These are a collection of data structures relating to sounds. Already I'm sure +# you get the picture. +# +# Sound Pools +# These are just groups of sounds, to be referenced by sfx settings. Could +# potentially merit enumerating later on. ¯\_(ツ)_/¯ +# +# Sound Hooks +# These are intended to gear themselves toward configurable settings, rather +# than to document every location where a particular sound is used. For example, +# suppose we want a setting to override all of Link's vocalizations. The sound +# hook would contain a bunch of addresses, whether they share the same default +# value or not. + +from enum import Enum +from collections import namedtuple + + +class Tags(Enum): + LOOPED = 0 + QUIET = 1 + IMMEDIATE = 2 # Delayed sounds are commonly undesirable + BRIEF = 3 # Punchy sounds, good for rapid fire + NEW = 4 + PAINFUL = 5 # Eardrum-piercing sounds + NAVI = 6 # Navi sounds (hand chosen) + HPLOW = 7 # Low HP sounds (hand chosen) + HOVERBOOT = 8 # Hover boot sounds (hand chosen) + NIGHTFALL = 9 # Nightfall sounds (hand chosen) + MENUSELECT = 10 # Menu selection sounds (hand chosen, could use some more) + MENUMOVE = 11 # Menu movement sounds (hand chosen, could use some more) + HORSE = 12 # Horse neigh sounds (hand chosen) + INC_NE = 20 # Incompatible with NAVI_ENEMY? (Verify) + # I'm now thinking it has to do with a limit of concurrent sounds) + +Sound = namedtuple('Sound', 'id keyword label tags') +class Sounds(Enum): + NONE = Sound(0x0000, 'none', 'None', [Tags.NAVI, Tags.HPLOW]) + ARMOS_GROAN = Sound(0x3848, 'armos', 'Armos', [Tags.HORSE, Tags.PAINFUL]) + BARK = Sound(0x28D8, 'bark', 'Bark', [Tags.BRIEF, Tags.NAVI, Tags.HPLOW, Tags.HOVERBOOT]) + BOMB_BOUNCE = Sound(0x282F, 'bomb-bounce', 'Bomb Bounce', [Tags.QUIET, Tags.HPLOW]) + BONGO_HIGH = Sound(0x3951, 'bongo-bongo-high', 'Bongo Bongo High', [Tags.MENUSELECT]) + BONGO_LOW = Sound(0x3950, 'bongo-bongo-low', 'Bongo Bongo Low', [Tags.QUIET, Tags.HPLOW, Tags.MENUMOVE]) + BOTTLE_CORK = Sound(0x286C, 'bottle-cork', 'Bottle Cork', [Tags.IMMEDIATE, Tags.BRIEF, Tags.QUIET]) + BOW_TWANG = Sound(0x1830, 'bow-twang', 'Bow Twang', [Tags.HPLOW, Tags.MENUMOVE]) + BUBBLE_LOL = Sound(0x38CA, 'bubble-laugh', 'Bubble Laugh', []) + BUSINESS_SCRUB = Sound(0x3882, 'business-scrub', 'Business Scrub', [Tags.PAINFUL, Tags.NAVI, Tags.HPLOW]) + CARROT_REFILL = Sound(0x4845, 'carrot-refill', 'Carrot Refill', [Tags.NAVI, Tags.HPLOW]) + CARTOON_FALL = Sound(0x28A0, 'cartoon-fall', 'Cartoon Fall', [Tags.PAINFUL, Tags.HOVERBOOT]) + CHANGE_ITEM = Sound(0x0835, 'change-item', 'Change Item', [Tags.IMMEDIATE, Tags.BRIEF, Tags.MENUSELECT]) + CHEST_OPEN = Sound(0x2820, 'chest-open', 'Chest Open', [Tags.PAINFUL]) + CHILD_CRINGE = Sound(0x683A, 'child-cringe', 'Child Cringe', [Tags.PAINFUL, Tags.IMMEDIATE, Tags.MENUSELECT]) + CHILD_GASP = Sound(0x6836, 'child-gasp', 'Child Gasp', [Tags.PAINFUL]) + CHILD_HURT = Sound(0x6825, 'child-hurt', 'Child Hurt', [Tags.PAINFUL]) + CHILD_OWO = Sound(0x6823, 'child-owo', 'Child owo', [Tags.PAINFUL]) + CHILD_PANT = Sound(0x6829, 'child-pant', 'Child Pant', [Tags.IMMEDIATE]) + CHILD_SCREAM = Sound(0x6828, 'child-scream', 'Child Scream', [Tags.PAINFUL, Tags.IMMEDIATE, Tags.MENUSELECT, Tags.HORSE]) + CUCCO_CLUCK = Sound(0x2812, 'cluck', 'Cluck', [Tags.BRIEF, Tags.NAVI, Tags.HPLOW]) + CUCCO_CROW = Sound(0x2813, 'cockadoodledoo', 'Cockadoodledoo', [Tags.PAINFUL, Tags.NAVI, Tags.NIGHTFALL]) + CURSED_ATTACK = Sound(0x6868, 'cursed-attack', 'Cursed Attack', [Tags.PAINFUL, Tags.IMMEDIATE]) + CURSED_SCREAM = Sound(0x6867, 'cursed-scream', 'Cursed Scream', [Tags.PAINFUL]) + DEKU_BABA_CHATTER = Sound(0x3860, 'deku-baba', 'Deku Baba', [Tags.MENUMOVE]) + DRAWBRIDGE_SET = Sound(0x280E, 'drawbridge-set', 'Drawbridge Set', [Tags.HPLOW]) + DUSK_HOWL = Sound(0x28AE, 'dusk-howl', 'Dusk Howl', [Tags.NAVI]) + EPONA_CHILD = Sound(0x2844, 'baby-epona', 'Epona (Baby)', [Tags.PAINFUL]) + EXPLODE_CRATE = Sound(0x2839, 'exploding-crate', 'Exploding Crate', [Tags.PAINFUL, Tags.NAVI]) + EXPLOSION = Sound(0x180E, 'explosion', 'Explosion', [Tags.PAINFUL, Tags.NAVI]) + FANFARE_SMALL = Sound(0x4824, 'fanfare-light', 'Fanfare (Light)', []) + FANFARE_MED = Sound(0x4831, 'fanfare-medium', 'Fanfare (Medium)', []) + FIELD_SHRUB = Sound(0x2877, 'field-shrub', 'Field Shrub', []) + FLARE_BOSS_LOL = Sound(0x3981, 'flare-dancer-laugh', 'Flare Dancer Laugh', [Tags.PAINFUL, Tags.IMMEDIATE, Tags.HOVERBOOT]) + FLARE_BOSS_STARTLE = Sound(0x398B, 'flare-dancer-startled', 'Flare Dancer Startled', []) + GANON_TENNIS = Sound(0x39CA, 'ganondorf-teh', 'Ganondorf "Teh!"', []) + GOHMA_LARVA_CROAK = Sound(0x395D, 'gohma-larva-croak', 'Gohma Larva Croak', []) + GOLD_SKULL_TOKEN = Sound(0x4843, 'gold-skull-token', 'Gold Skull Token', [Tags.NIGHTFALL]) + GORON_WAKE = Sound(0x38FC, 'goron-wake', 'Goron Wake', []) + GREAT_FAIRY = Sound(0x6858, 'great-fairy', 'Great Fairy', [Tags.PAINFUL, Tags.NAVI, Tags.NIGHTFALL, Tags.HORSE]) + GUAY = Sound(0x38B6, 'guay', 'Guay', [Tags.BRIEF, Tags.NAVI, Tags.HPLOW]) + GUNSHOT = Sound(0x4835, 'gunshot', 'Gunshot', []) + HAMMER_BONK = Sound(0x180A, 'hammer-bonk', 'Hammer Bonk', []) + HORSE_NEIGH = Sound(0x2805, 'horse-neigh', 'Horse Neigh', [Tags.PAINFUL, Tags.NAVI]) + HORSE_TROT = Sound(0x2804, 'horse-trot', 'Horse Trot', [Tags.HPLOW]) + HOVER_BOOTS = Sound(0x08C9, 'hover-boots', 'Hover Boots', [Tags.LOOPED, Tags.PAINFUL]) + HP_LOW = Sound(0x481B, 'low-health', 'HP Low', [Tags.INC_NE, Tags.NAVI]) + HP_RECOVER = Sound(0x480B, 'recover-health', 'HP Recover', [Tags.NAVI, Tags.HPLOW]) + ICE_SHATTER = Sound(0x0875, 'shattering-ice', 'Ice Shattering', [Tags.PAINFUL, Tags.NAVI]) + INGO_WOOAH = Sound(0x6854, 'ingo-wooah', 'Ingo "Wooah!"', [Tags.PAINFUL]) + IRON_BOOTS = Sound(0x080D, 'iron-boots', 'Iron Boots', [Tags.BRIEF, Tags.HPLOW, Tags.QUIET]) + IRON_KNUCKLE = Sound(0x3929, 'iron-knuckle', 'Iron Knuckle', []) + INGO_KAAH = Sound(0x6855, 'kaah', 'Kaah!', [Tags.PAINFUL]) + MOBLIN_CLUB_GROUND = Sound(0x38E1, 'moblin-club-ground', 'Moblin Club Ground', [Tags.PAINFUL]) + MOBLIN_CLUB_SWING = Sound(0x39EF, 'moblin-club-swing', 'Moblin Club Swing', [Tags.PAINFUL]) + MOO = Sound(0x28DF, 'moo', 'Moo', [Tags.NAVI, Tags.NIGHTFALL, Tags.HORSE, Tags.HPLOW]) + MWEEP = Sound(0x687A, 'mweep', 'Mweep!', [Tags.BRIEF, Tags.NAVI, Tags.MENUMOVE, Tags.MENUSELECT, Tags.NIGHTFALL, Tags.HPLOW, Tags.HORSE, Tags.HOVERBOOT]) + NAVI_HELLO = Sound(0x6844, 'navi-hello', 'Navi "Hello!"', [Tags.PAINFUL, Tags.NAVI]) + NAVI_HEY = Sound(0x685F, 'navi-hey', 'Navi "Hey!"', [Tags.PAINFUL, Tags.HPLOW]) + NAVI_RANDOM = Sound(0x6843, 'navi-random', 'Navi Random', [Tags.PAINFUL, Tags.HPLOW]) + NOTIFICATION = Sound(0x4820, 'notification', 'Notification', [Tags.NAVI, Tags.HPLOW]) + PHANTOM_GANON_LOL = Sound(0x38B0, 'phantom-ganon-laugh', 'Phantom Ganon Laugh', []) + PLANT_EXPLODE = Sound(0x284E, 'plant-explode', 'Plant Explode', []) + POE = Sound(0x38EC, 'poe', 'Poe', [Tags.PAINFUL, Tags.NAVI]) + POT_SHATTER = Sound(0x2887, 'shattering-pot', 'Pot Shattering', [Tags.NAVI, Tags.HPLOW]) + REDEAD_MOAN = Sound(0x38E4, 'redead-moan', 'Redead Moan', [Tags.NIGHTFALL]) + REDEAD_SCREAM = Sound(0x38E5, 'redead-scream', 'Redead Scream', [Tags.PAINFUL, Tags.NAVI, Tags.HORSE]) + RIBBIT = Sound(0x28B1, 'ribbit', 'Ribbit', [Tags.NAVI, Tags.HPLOW]) + RUPEE = Sound(0x4803, 'rupee', 'Rupee', []) + RUPEE_SILVER = Sound(0x28E8, 'silver-rupee', 'Rupee (Silver)', [Tags.HPLOW]) + RUTO_CHILD_CRASH = Sound(0x6860, 'ruto-crash', 'Ruto Crash', []) + RUTO_CHILD_EXCITED = Sound(0x6861, 'ruto-excited', 'Ruto Excited', [Tags.PAINFUL]) + RUTO_CHILD_GIGGLE = Sound(0x6863, 'ruto-giggle', 'Ruto Giggle', [Tags.PAINFUL, Tags.NAVI]) + RUTO_CHILD_LIFT = Sound(0x6864, 'ruto-lift', 'Ruto Lift', []) + RUTO_CHILD_THROWN = Sound(0x6865, 'ruto-thrown', 'Ruto Thrown', []) + RUTO_CHILD_WIGGLE = Sound(0x6866, 'ruto-wiggle', 'Ruto Wiggle', [Tags.PAINFUL, Tags.HORSE]) + SCRUB_NUTS_UP = Sound(0x387C, 'scrub-emerge', 'Scrub Emerge', []) + SHABOM_BOUNCE = Sound(0x3948, 'shabom-bounce', 'Shabom Bounce', [Tags.IMMEDIATE]) + SHABOM_POP = Sound(0x3949, 'shabom-pop', 'Shabom Pop', [Tags.IMMEDIATE, Tags.BRIEF, Tags.HOVERBOOT]) + SHELLBLADE = Sound(0x3849, 'shellblade', 'Shellblade', []) + SKULLTULA = Sound(0x39DA, 'skulltula', 'Skulltula', [Tags.BRIEF, Tags.NAVI]) + SOFT_BEEP = Sound(0x4804, 'soft-beep', 'Soft Beep', [Tags.NAVI, Tags.HPLOW]) + SPIKE_TRAP = Sound(0x38E9, 'spike-trap', 'Spike Trap', [Tags.LOOPED, Tags.PAINFUL]) + SPIT_NUT = Sound(0x387E, 'spit-nut', 'Spit Nut', [Tags.IMMEDIATE, Tags.BRIEF]) + STALCHILD_ATTACK = Sound(0x3831, 'stalchild-attack', 'Stalchild Attack', [Tags.PAINFUL, Tags.HORSE]) + STINGER_CRY = Sound(0x39A3, 'stinger-squeak', 'Stinger Squeak', [Tags.PAINFUL]) + SWITCH = Sound(0x2815, 'switch', 'Switch', [Tags.HPLOW]) + SWORD_BONK = Sound(0x181A, 'sword-bonk', 'Sword Bonk', [Tags.HPLOW]) + TALON_CRY = Sound(0x6853, 'talon-cry', 'Talon Cry', [Tags.PAINFUL]) + TALON_HMM = Sound(0x6852, 'talon-hmm', 'Talon "Hmm"', []) + TALON_SNORE = Sound(0x6850, 'talon-snore', 'Talon Snore', [Tags.NIGHTFALL]) + TALON_WTF = Sound(0x6851, 'talon-wtf', 'Talon Wtf', []) + TAMBOURINE = Sound(0x4842, 'tambourine', 'Tambourine', [Tags.QUIET, Tags.NAVI, Tags.HPLOW, Tags.HOVERBOOT]) + TARGETING_ENEMY = Sound(0x4830, 'target-enemy', 'Target Enemy', []) + TARGETING_NEUTRAL = Sound(0x480C, 'target-neutral', 'Target Neutral', []) + THUNDER = Sound(0x282E, 'thunder', 'Thunder', [Tags.NIGHTFALL]) + TIMER = Sound(0x481A, 'timer', 'Timer', [Tags.INC_NE, Tags.NAVI, Tags.HPLOW]) + TWINROVA_BICKER = Sound(0x39E7, 'twinrova-bicker', 'Twinrova Bicker', [Tags.LOOPED, Tags.PAINFUL]) + WOLFOS_HOWL = Sound(0x383C, 'wolfos-howl', 'Wolfos Howl', [Tags.PAINFUL]) + ZELDA_ADULT_GASP = Sound(0x6879, 'adult-zelda-gasp', 'Zelda Gasp (Adult)', [Tags.NAVI, Tags.HPLOW]) + + +# Sound pools +standard = [s for s in Sounds if Tags.LOOPED not in s.value.tags] +looping = [s for s in Sounds if Tags.LOOPED in s.value.tags] +no_painful = [s for s in standard if Tags.PAINFUL not in s.value.tags] +navi = [s for s in Sounds if Tags.NAVI in s.value.tags] +hp_low = [s for s in Sounds if Tags.HPLOW in s.value.tags] +hover_boots = [s for s in Sounds if Tags.HOVERBOOT in s.value.tags] +nightfall = [s for s in Sounds if Tags.NIGHTFALL in s.value.tags] +menu_select = [s for s in Sounds if Tags.MENUSELECT in s.value.tags] +menu_cursor = [s for s in Sounds if Tags.MENUMOVE in s.value.tags] +horse_neigh = [s for s in Sounds if Tags.HORSE in s.value.tags] + + +SoundHook = namedtuple('SoundHook', 'name pool locations') +class SoundHooks(Enum): + NAVI_OVERWORLD = SoundHook('Navi - Overworld', navi, [0xAE7EF2, 0xC26C7E]) + NAVI_ENEMY = SoundHook('Navi - Enemy', navi, [0xAE7EC6]) + HP_LOW = SoundHook('Low Health', hp_low, [0xADBA1A]) + BOOTS_HOVER = SoundHook('Hover Boots', hover_boots, [0xBDBD8A]) + NIGHTFALL = SoundHook('Nightfall', nightfall, [0xAD3466, 0xAD7A2E]) + MENU_SELECT = SoundHook('Menu Select', no_painful + menu_select, [ + 0xBA1BBE, 0xBA23CE, 0xBA2956, 0xBA321A, 0xBA72F6, 0xBA8106, 0xBA82EE, + 0xBA9DAE, 0xBA9EAE, 0xBA9FD2, 0xBAE6D6]) + MENU_CURSOR = SoundHook('Menu Cursor', no_painful + menu_cursor, [ + 0xBA165E, 0xBA1C1A, 0xBA2406, 0xBA327E, 0xBA3936, 0xBA77C2, 0xBA7886, + 0xBA7A06, 0xBA7A6E, 0xBA7AE6, 0xBA7D6A, 0xBA8186, 0xBA822E, 0xBA82A2, + 0xBAA11E, 0xBAE7C6]) + HORSE_NEIGH = SoundHook('Horse Neigh', horse_neigh, [ + 0xC18832, 0xC18C32, 0xC19A7E, 0xC19CBE, 0xC1A1F2, 0xC1A3B6, 0xC1B08A, + 0xC1B556, 0xC1C28A, 0xC1CC36, 0xC1EB4A, 0xC1F18E, 0xC6B136, 0xC6BBA2, + 0xC1E93A, 0XC6B366, 0XC6B562]) + + +# # Some enemies have a different cutting sound, making this a bit weird +# SWORD_SLASH = SoundHook('Sword Slash', standard, [0xAC2942]) + + +def get_patch_dict(): + return {s.value.keyword: s.value.id for s in Sounds} + + +def get_hook_pool(sound_hook, earsafeonly = "FALSE"): + if earsafeonly == "TRUE": + list = [s for s in sound_hook.value.pool if Tags.PAINFUL not in s.value.tags] + return list + else: + return sound_hook.value.pool + + +def get_setting_choices(sound_hook): + pool = sound_hook.value.pool + choices = {s.value.keyword: s.value.label for s in sorted(pool, key=lambda s: s.value.label)} + result = { + 'default': 'Default', + 'completely-random': 'Completely Random', + 'random-ear-safe': 'Random Ear-Safe', + 'random-choice': 'Random Choice', + 'none': 'None', + **choices, + } + return result diff --git a/worlds/oot/TextBox.py b/worlds/oot/TextBox.py new file mode 100644 index 00000000..4ea99757 --- /dev/null +++ b/worlds/oot/TextBox.py @@ -0,0 +1,369 @@ +import worlds.oot.Messages as Messages + +# Least common multiple of all possible character widths. A line wrap must occur when the combined widths of all of the +# characters on a line reach this value. +NORMAL_LINE_WIDTH = 1801800 + +# Attempting to display more lines in a single text box will cause additional lines to bleed past the bottom of the box. +LINES_PER_BOX = 4 + +# Attempting to display more characters in a single text box will cause buffer overflows. First, visual artifacts will +# appear in lower areas of the text box. Eventually, the text box will become uncloseable. +MAX_CHARACTERS_PER_BOX = 200 + +CONTROL_CHARS = { + 'LINE_BREAK': ['&', '\x01'], + 'BOX_BREAK': ['^', '\x04'], + 'NAME': ['@', '\x0F'], + 'COLOR': ['#', '\x05\x00'], +} +TEXT_END = '\x02' + + +def line_wrap(text, strip_existing_lines=False, strip_existing_boxes=False, replace_control_chars=True): + # Replace stand-in characters with their actual control code. + if replace_control_chars: + for char in CONTROL_CHARS.values(): + text = text.replace(char[0], char[1]) + + # Parse the text into a list of control codes. + text_codes = Messages.parse_control_codes(text) + + # Existing line/box break codes to strip. + strip_codes = [] + if strip_existing_boxes: + strip_codes.append(0x04) + if strip_existing_lines: + strip_codes.append(0x01) + + # Replace stripped codes with a space. + if strip_codes: + index = 0 + while index < len(text_codes): + text_code = text_codes[index] + if text_code.code in strip_codes: + # Check for existing whitespace near this control code. + # If one is found, simply remove this text code. + if index > 0 and text_codes[index-1].code == 0x20: + text_codes.pop(index) + continue + if index + 1 < len(text_codes) and text_codes[index+1].code == 0x20: + text_codes.pop(index) + continue + # Replace this text code with a space. + text_codes[index] = Messages.Text_Code(0x20, 0) + index += 1 + + # Split the text codes by current box breaks. + boxes = [] + start_index = 0 + end_index = 0 + for text_code in text_codes: + end_index += 1 + if text_code.code == 0x04: + boxes.append(text_codes[start_index:end_index]) + start_index = end_index + boxes.append(text_codes[start_index:end_index]) + + # Split the boxes into lines and words. + processed_boxes = [] + for box_codes in boxes: + line_width = NORMAL_LINE_WIDTH + icon_code = None + words = [] + + # Group the text codes into words. + index = 0 + while index < len(box_codes): + text_code = box_codes[index] + index += 1 + + # Check for an icon code and lower the width of this box if one is found. + if text_code.code == 0x13: + line_width = 1441440 + icon_code = text_code + + # Find us a whole word. + if text_code.code in [0x01, 0x04, 0x20]: + if index > 1: + words.append(box_codes[0:index-1]) + if text_code.code in [0x01, 0x04]: + # If we have ran into a line or box break, add it as a "word" as well. + words.append([box_codes[index-1]]) + box_codes = box_codes[index:] + index = 0 + if index > 0 and index == len(box_codes): + words.append(box_codes) + box_codes = [] + + # Arrange our words into lines. + lines = [] + start_index = 0 + end_index = 0 + box_count = 1 + while end_index < len(words): + # Our current confirmed line. + end_index += 1 + line = words[start_index:end_index] + + # If this word is a line/box break, trim our line back a word and deal with it later. + break_char = False + if words[end_index-1][0].code in [0x01, 0x04]: + line = words[start_index:end_index-1] + break_char = True + + # Check the width of the line after adding one more word. + if end_index == len(words) or break_char or calculate_width(words[start_index:end_index+1]) > line_width: + if line or lines: + lines.append(line) + start_index = end_index + + # If we've reached the end of the box, finalize it. + if end_index == len(words) or words[end_index-1][0].code == 0x04 or len(lines) == LINES_PER_BOX: + # Append the same icon to any wrapped boxes. + if icon_code and box_count > 1: + lines[0][0] = [icon_code] + lines[0][0] + processed_boxes.append(lines) + lines = [] + box_count += 1 + + # Construct our final string. + # This is a hideous level of list comprehension. Sorry. + return '\x04'.join('\x01'.join(' '.join(''.join(code.get_string() for code in word) for word in line) for line in box) for box in processed_boxes) + + +def calculate_width(words): + words_width = 0 + for word in words: + index = 0 + while index < len(word): + character = word[index] + index += 1 + if character.code in Messages.CONTROL_CODES: + if character.code == 0x06: + words_width += character.data + words_width += get_character_width(chr(character.code)) + spaces_width = get_character_width(' ') * (len(words) - 1) + + return words_width + spaces_width + + +def get_character_width(character): + try: + return character_table[character] + except KeyError: + if ord(character) < 0x20: + if character in control_code_width: + return sum([character_table[c] for c in control_code_width[character]]) + else: + return 0 + else: + # A sane default with the most common character width + return character_table[' '] + + +control_code_width = { + '\x0F': '00000000', + '\x16': '00\'00"', + '\x17': '00\'00"', + '\x18': '00000', + '\x19': '100', + '\x1D': '00', + '\x1E': '00000', + '\x1F': '00\'00"', +} + + +# Tediously measured by filling a full line of a gossip stone's text box with one character until it is reasonably full +# (with a right margin) and counting how many characters fit. OoT does not appear to use any kerning, but, if it does, +# it will only make the characters more space-efficient, so this is an underestimate of the number of letters per line, +# at worst. This ensures that we will never bleed text out of the text box while line wrapping. +# Larger numbers in the denominator mean more of that character fits on a line; conversely, larger values in this table +# mean the character is wider and can't fit as many on one line. +character_table = { + '\x0F': 655200, + '\x16': 292215, + '\x17': 292215, + '\x18': 300300, + '\x19': 145860, + '\x1D': 85800, + '\x1E': 300300, + '\x1F': 265980, + 'a': 51480, # LINE_WIDTH / 35 + 'b': 51480, # LINE_WIDTH / 35 + 'c': 51480, # LINE_WIDTH / 35 + 'd': 51480, # LINE_WIDTH / 35 + 'e': 51480, # LINE_WIDTH / 35 + 'f': 34650, # LINE_WIDTH / 52 + 'g': 51480, # LINE_WIDTH / 35 + 'h': 51480, # LINE_WIDTH / 35 + 'i': 25740, # LINE_WIDTH / 70 + 'j': 34650, # LINE_WIDTH / 52 + 'k': 51480, # LINE_WIDTH / 35 + 'l': 25740, # LINE_WIDTH / 70 + 'm': 81900, # LINE_WIDTH / 22 + 'n': 51480, # LINE_WIDTH / 35 + 'o': 51480, # LINE_WIDTH / 35 + 'p': 51480, # LINE_WIDTH / 35 + 'q': 51480, # LINE_WIDTH / 35 + 'r': 42900, # LINE_WIDTH / 42 + 's': 51480, # LINE_WIDTH / 35 + 't': 42900, # LINE_WIDTH / 42 + 'u': 51480, # LINE_WIDTH / 35 + 'v': 51480, # LINE_WIDTH / 35 + 'w': 81900, # LINE_WIDTH / 22 + 'x': 51480, # LINE_WIDTH / 35 + 'y': 51480, # LINE_WIDTH / 35 + 'z': 51480, # LINE_WIDTH / 35 + 'A': 81900, # LINE_WIDTH / 22 + 'B': 51480, # LINE_WIDTH / 35 + 'C': 72072, # LINE_WIDTH / 25 + 'D': 72072, # LINE_WIDTH / 25 + 'E': 51480, # LINE_WIDTH / 35 + 'F': 51480, # LINE_WIDTH / 35 + 'G': 81900, # LINE_WIDTH / 22 + 'H': 60060, # LINE_WIDTH / 30 + 'I': 25740, # LINE_WIDTH / 70 + 'J': 51480, # LINE_WIDTH / 35 + 'K': 60060, # LINE_WIDTH / 30 + 'L': 51480, # LINE_WIDTH / 35 + 'M': 81900, # LINE_WIDTH / 22 + 'N': 72072, # LINE_WIDTH / 25 + 'O': 81900, # LINE_WIDTH / 22 + 'P': 51480, # LINE_WIDTH / 35 + 'Q': 81900, # LINE_WIDTH / 22 + 'R': 60060, # LINE_WIDTH / 30 + 'S': 60060, # LINE_WIDTH / 30 + 'T': 51480, # LINE_WIDTH / 35 + 'U': 60060, # LINE_WIDTH / 30 + 'V': 72072, # LINE_WIDTH / 25 + 'W': 100100, # LINE_WIDTH / 18 + 'X': 72072, # LINE_WIDTH / 25 + 'Y': 60060, # LINE_WIDTH / 30 + 'Z': 60060, # LINE_WIDTH / 30 + ' ': 51480, # LINE_WIDTH / 35 + '1': 25740, # LINE_WIDTH / 70 + '2': 51480, # LINE_WIDTH / 35 + '3': 51480, # LINE_WIDTH / 35 + '4': 60060, # LINE_WIDTH / 30 + '5': 51480, # LINE_WIDTH / 35 + '6': 51480, # LINE_WIDTH / 35 + '7': 51480, # LINE_WIDTH / 35 + '8': 51480, # LINE_WIDTH / 35 + '9': 51480, # LINE_WIDTH / 35 + '0': 60060, # LINE_WIDTH / 30 + '!': 51480, # LINE_WIDTH / 35 + '?': 72072, # LINE_WIDTH / 25 + '\'': 17325, # LINE_WIDTH / 104 + '"': 34650, # LINE_WIDTH / 52 + '.': 25740, # LINE_WIDTH / 70 + ',': 25740, # LINE_WIDTH / 70 + '/': 51480, # LINE_WIDTH / 35 + '-': 34650, # LINE_WIDTH / 52 + '_': 51480, # LINE_WIDTH / 35 + '(': 42900, # LINE_WIDTH / 42 + ')': 42900, # LINE_WIDTH / 42 + '$': 51480 # LINE_WIDTH / 35 +} + +# To run tests, enter the following into a python3 REPL: +# >>> import Messages +# >>> from TextBox import line_wrap_tests +# >>> line_wrap_tests() +def line_wrap_tests(): + test_wrap_simple_line() + test_honor_forced_line_wraps() + test_honor_box_breaks() + test_honor_control_characters() + test_honor_player_name() + test_maintain_multiple_forced_breaks() + test_trim_whitespace() + test_support_long_words() + + +def test_wrap_simple_line(): + words = 'Hello World! Hello World! Hello World!' + expected = 'Hello World! Hello World! Hello\x01World!' + result = line_wrap(words) + + if result != expected: + print('"Wrap Simple Line" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Wrap Simple Line" test passed!') + + +def test_honor_forced_line_wraps(): + words = 'Hello World! Hello World!&Hello World! Hello World! Hello World!' + expected = 'Hello World! Hello World!\x01Hello World! Hello World! Hello\x01World!' + result = line_wrap(words) + + if result != expected: + print('"Honor Forced Line Wraps" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Forced Line Wraps" test passed!') + + +def test_honor_box_breaks(): + words = 'Hello World! Hello World!^Hello World! Hello World! Hello World!' + expected = 'Hello World! Hello World!\x04Hello World! Hello World! Hello\x01World!' + result = line_wrap(words) + + if result != expected: + print('"Honor Box Breaks" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Box Breaks" test passed!') + + +def test_honor_control_characters(): + words = 'Hello World! #Hello# World! Hello World!' + expected = 'Hello World! \x05\x00Hello\x05\x00 World! Hello\x01World!' + result = line_wrap(words) + + if result != expected: + print('"Honor Control Characters" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Control Characters" test passed!') + + +def test_honor_player_name(): + words = 'Hello @! Hello World! Hello World!' + expected = 'Hello \x0F! Hello World!\x01Hello World!' + result = line_wrap(words) + + if result != expected: + print('"Honor Player Name" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Player Name" test passed!') + + +def test_maintain_multiple_forced_breaks(): + words = 'Hello World!&&&Hello World!' + expected = 'Hello World!\x01\x01\x01Hello World!' + result = line_wrap(words) + + if result != expected: + print('"Maintain Multiple Forced Breaks" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Maintain Multiple Forced Breaks" test passed!') + + +def test_trim_whitespace(): + words = 'Hello World! & Hello World!' + expected = 'Hello World!\x01Hello World!' + result = line_wrap(words) + + if result != expected: + print('"Trim Whitespace" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Trim Whitespace" test passed!') + + +def test_support_long_words(): + words = 'Hello World! WWWWWWWWWWWWWWWWWWWW Hello World!' + expected = 'Hello World!\x01WWWWWWWWWWWWWWWWWWWW\x01Hello World!' + result = line_wrap(words) + + if result != expected: + print('"Support Long Words" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Support Long Words" test passed!') diff --git a/worlds/oot/Utils.py b/worlds/oot/Utils.py new file mode 100644 index 00000000..405cdd4d --- /dev/null +++ b/worlds/oot/Utils.py @@ -0,0 +1,97 @@ +import io, re, json +import os, sys +import subprocess +import Utils +from functools import lru_cache + +__version__ = Utils.__version__ + ' f.LUM' + +def data_path(*args): + return Utils.local_path('worlds', 'oot', 'data', *args) + +@lru_cache(maxsize=13) # Cache Overworld.json and the 12 dungeons +def read_json(file_path): + json_string = "" + with io.open(file_path, 'r') as file: + for line in file.readlines(): + json_string += line.split('#')[0].replace('\n', ' ') + json_string = re.sub(' +', ' ', json_string) + try: + return json.loads(json_string) + except json.JSONDecodeError as error: + raise Exception("JSON parse error around text:\n" + \ + json_string[error.pos-35:error.pos+35] + "\n" + \ + " ^^\n") + +def is_bundled(): + return getattr(sys, 'frozen', False) + +# From the pyinstaller Wiki: https://github.com/pyinstaller/pyinstaller/wiki/Recipe-subprocess +# Create a set of arguments which make a ``subprocess.Popen`` (and +# variants) call work with or without Pyinstaller, ``--noconsole`` or +# not, on Windows and Linux. Typical use:: +# subprocess.call(['program_to_run', 'arg_1'], **subprocess_args()) +def subprocess_args(include_stdout=True): + # The following is true only on Windows. + if hasattr(subprocess, 'STARTUPINFO'): + # On Windows, subprocess calls will pop up a command window by default + # when run from Pyinstaller with the ``--noconsole`` option. Avoid this + # distraction. + si = subprocess.STARTUPINFO() + si.dwFlags |= subprocess.STARTF_USESHOWWINDOW + # Windows doesn't search the path by default. Pass it an environment so + # it will. + env = os.environ + else: + si = None + env = None + + # ``subprocess.check_output`` doesn't allow specifying ``stdout``:: + # So, add it only if it's needed. + if include_stdout: + ret = {'stdout': subprocess.PIPE} + else: + ret = {} + + # On Windows, running this from the binary produced by Pyinstaller + # with the ``--noconsole`` option requires redirecting everything + # (stdin, stdout, stderr) to avoid an OSError exception + # "[Error 6] the handle is invalid." + ret.update({'stdin': subprocess.PIPE, + 'stderr': subprocess.PIPE, + 'startupinfo': si, + 'env': env }) + return ret + +def get_version_bytes(a): + version_bytes = [0x00, 0x00, 0x00] + if not a: + return version_bytes; + sa = a.replace('v', '').replace(' ', '.').split('.') + + for i in range(0,3): + try: + version_byte = int(sa[i]) + except ValueError: + break + version_bytes[i] = version_byte + + return version_bytes + +def compare_version(a, b): + if not a and not b: + return 0 + elif a and not b: + return 1 + elif not a and b: + return -1 + + sa = get_version_bytes(a) + sb = get_version_bytes(b) + + for i in range(0,3): + if sa[i] > sb[i]: + return 1 + if sa[i] < sb[i]: + return -1 + return 0 diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py new file mode 100644 index 00000000..00bd0215 --- /dev/null +++ b/worlds/oot/__init__.py @@ -0,0 +1,734 @@ +import logging +import os +import copy +from collections import Counter + +logger = logging.getLogger("Ocarina of Time") + +from .Location import OOTLocation, LocationFactory, location_name_to_id +from .Entrance import OOTEntrance +from .EntranceShuffle import shuffle_random_entrances +from .Items import OOTItem, item_table, oot_data_to_ap_id +from .ItemPool import generate_itempool, get_junk_item, get_junk_pool +from .Regions import OOTRegion, TimeOfDay +from .Rules import set_rules, set_shop_rules, set_entrances_based_rules +from .RuleParser import Rule_AST_Transformer +from .Options import oot_options +from .Utils import data_path, read_json +from .LocationList import business_scrubs, set_drop_location_names +from .DungeonList import dungeon_table, create_dungeons +from .LogicTricks import normalized_name_tricks +from .Rom import Rom +from .Patches import patch_rom +from .N64Patch import create_patch_file +from .Cosmetics import patch_cosmetics +from .Hints import hint_dist_keys, get_hint_area, buildWorldGossipHints +from .HintList import getRequiredHints + +from Utils import get_options, output_path +from BaseClasses import MultiWorld, CollectionState, RegionType +from Options import Range, Toggle, OptionList +from Fill import fill_restrictive, FillError +from ..AutoWorld import World + +location_id_offset = 67000 + +class OOTWorld(World): + game: str = "Ocarina of Time" + options: dict = oot_options + topology_present: bool = True + item_name_to_id = {item_name: oot_data_to_ap_id(data, False) for item_name, data in item_table.items() if data[2] is not None} + location_name_to_id = location_name_to_id + remote_items: bool = False + + data_version = 1 + + + def __new__(cls, world, player): + # Add necessary objects to CollectionState on initialization + orig_init = CollectionState.__init__ + orig_copy = CollectionState.copy + + def oot_init(self, parent: MultiWorld): + orig_init(self, parent) + self.child_reachable_regions = {player: set() for player in range(1, parent.players + 1)} + self.adult_reachable_regions = {player: set() for player in range(1, parent.players + 1)} + self.child_blocked_connections = {player: set() for player in range(1, parent.players + 1)} + self.adult_blocked_connections = {player: set() for player in range(1, parent.players + 1)} + self.age = {player: None for player in range(1, parent.players + 1)} + + def oot_copy(self): + ret = orig_copy(self) + ret.child_reachable_regions = {player: copy.copy(self.child_reachable_regions[player]) for player in + range(1, self.world.players + 1)} + ret.adult_reachable_regions = {player: copy.copy(self.adult_reachable_regions[player]) for player in + range(1, self.world.players + 1)} + ret.child_blocked_connections = {player: copy.copy(self.child_blocked_connections[player]) for player in + range(1, self.world.players + 1)} + ret.adult_blocked_connections = {player: copy.copy(self.adult_blocked_connections[player]) for player in + range(1, self.world.players + 1)} + return ret + + CollectionState.__init__ = oot_init + CollectionState.copy = oot_copy + # also need to add the names to the passed MultiWorld's CollectionState, since it was initialized before we could get to it + if world: + world.state.child_reachable_regions = {player: set() for player in range(1, world.players + 1)} + world.state.adult_reachable_regions = {player: set() for player in range(1, world.players + 1)} + world.state.child_blocked_connections = {player: set() for player in range(1, world.players + 1)} + world.state.adult_blocked_connections = {player: set() for player in range(1, world.players + 1)} + world.state.age = {player: None for player in range(1, world.players + 1)} + + return super().__new__(cls) + + + def generate_early(self): + # Player name MUST be at most 16 bytes ascii-encoded, otherwise won't write to ROM correctly + if len(bytes(self.world.get_player_name(self.player), 'ascii')) > 16: + raise Exception(f"OoT: Player {self.player}'s name ({self.world.get_player_name(self.player)}) must be ASCII-compatible") + + self.parser = Rule_AST_Transformer(self, self.player) + + for (option_name, option) in oot_options.items(): + result = getattr(self.world, option_name)[self.player] + if isinstance(result, Range): + option_value = int(result) + elif isinstance(result, Toggle): + option_value = bool(result) + elif isinstance(result, OptionList): + option_value = result.value + else: + option_value = result.current_key + setattr(self, option_name, option_value) + + self.shop_prices = {} + self.regions = [] # internal cache of regions for this world, used later + self.remove_from_start_inventory = [] # some items will be precollected but not in the inventory + self.starting_items = Counter() + self.starting_songs = False # whether starting_items contains a song + self.file_hash = [self.world.random.randint(0, 31) for i in range(5)] + + self.item_name_groups = { + "medallions": {"Light Medallion", "Forest Medallion", "Fire Medallion", "Water Medallion", "Shadow Medallion", "Spirit Medallion"}, + "stones": {"Kokiri Emerald", "Goron Ruby", "Zora Sapphire"}, + "rewards": {"Light Medallion", "Forest Medallion", "Fire Medallion", "Water Medallion", "Shadow Medallion", "Spirit Medallion", \ + "Kokiri Emerald", "Goron Ruby", "Zora Sapphire"}, + "bottles": {"Bottle", "Bottle with Milk", "Deliver Letter", "Sell Big Poe", "Bottle with Red Potion", "Bottle with Green Potion", \ + "Bottle with Blue Potion", "Bottle with Fairy", "Bottle with Fish", "Bottle with Blue Fire", "Bottle with Bugs", "Bottle with Poe"} + } + + # Incompatible option handling + # ER and glitched logic are not compatible; glitched takes priority + if self.logic_rules == 'glitched': + self.shuffle_interior_entrances = False + self.shuffle_grotto_entrances = False + self.shuffle_dungeon_entrances = False + self.shuffle_overworld_entrances = False + self.owl_drops = False + self.warp_songs = False + self.spawn_positions = False + + # Closed forest and adult start are not compatible; closed forest takes priority + if self.open_forest == 'closed': + self.starting_age = 'child' + + # Skip child zelda and shuffle egg are not compatible; skip-zelda takes priority + if self.skip_child_zelda: + self.shuffle_weird_egg = False + + # Determine skipped trials in GT + # This needs to be done before the logic rules in GT are parsed + trial_list = ['Forest', 'Fire', 'Water', 'Spirit', 'Shadow', 'Light'] + chosen_trials = self.world.random.sample(trial_list, self.trials) # chooses a list of trials to NOT skip + self.skipped_trials = {trial: (trial not in chosen_trials) for trial in trial_list} + + # Determine which dungeons are MQ + # Possible future plan: allow user to pick which dungeons are MQ + self.mq_dungeons = 0 # temporary disable for client-side issues + mq_dungeons = self.world.random.sample(dungeon_table, self.mq_dungeons) + self.dungeon_mq = {item['name']: (item in mq_dungeons) for item in dungeon_table} + + # Determine tricks in logic + for trick in self.logic_tricks: + normalized_name = trick.casefold() + if normalized_name in normalized_name_tricks: + setattr(self, normalized_name_tricks[normalized_name]['name'], True) + else: + raise Exception(f'Unknown OOT logic trick for player {self.player}: {trick}') + + # Not implemented for now, but needed to placate the generator. Remove as they are implemented + self.mq_dungeons_random = False # this will be a deprecated option later + self.ocarina_songs = False # just need to pull in the OcarinaSongs module + self.big_poe_count = 1 # disabled due to client-side issues for now + self.correct_chest_sizes = False # will probably never be implemented since multiworld items are always major + # ER options + self.shuffle_interior_entrances = 'off' + self.shuffle_grotto_entrances = False + self.shuffle_dungeon_entrances = False + self.shuffle_overworld_entrances = False + self.owl_drops = False + self.warp_songs = False + self.spawn_positions = False + + # Set internal names used by the OoT generator + self.keysanity = self.shuffle_smallkeys in ['keysanity', 'remove', 'any_dungeon', 'overworld'] # only 'keysanity' and 'remove' implemented + + # Hint stuff + self.misc_hints = True # this is just always on + self.clearer_hints = True # this is being enforced since non-oot items do not have non-clear hint text + self.gossip_hints = {} + self.required_locations = [] + self.empty_areas = {} + self.major_item_locations = [] + + # ER names + self.ensure_tod_access = (self.shuffle_interior_entrances != 'off') or self.shuffle_overworld_entrances or self.spawn_positions + self.entrance_shuffle = (self.shuffle_interior_entrances != 'off') or self.shuffle_grotto_entrances or self.shuffle_dungeon_entrances or \ + self.shuffle_overworld_entrances or self.owl_drops or self.warp_songs or self.spawn_positions + self.disable_trade_revert = (self.shuffle_interior_entrances != 'off') or self.shuffle_overworld_entrances + self.shuffle_special_interior_entrances = self.shuffle_interior_entrances == 'all' + + # fixing some options + self.starting_tod = self.starting_tod.replace('_', '-') # Fixes starting time spelling: "witching_hour" -> "witching-hour" + self.shopsanity = self.shopsanity.replace('_value', '') # can't set "random" manually + self.shuffle_scrubs = self.shuffle_scrubs.replace('_prices', '') + + + # Get hint distribution + self.hint_dist_user = read_json(data_path('Hints', f'{self.hint_dist}.json')) + + self.added_hint_types = {} + self.item_added_hint_types = {} + self.hint_exclusions = set() + if self.skip_child_zelda: + self.hint_exclusions.add('Song from Impa') + self.hint_type_overrides = {} + self.item_hint_type_overrides = {} + + # unused hint stuff + self.named_item_pool = {} + self.hint_text_overrides = {} + + for dist in hint_dist_keys: + self.added_hint_types[dist] = [] + for loc in self.hint_dist_user['add_locations']: + if 'types' in loc: + if dist in loc['types']: + self.added_hint_types[dist].append(loc['location']) + self.item_added_hint_types[dist] = [] + for i in self.hint_dist_user['add_items']: + if dist in i['types']: + self.item_added_hint_types[dist].append(i['item']) + self.hint_type_overrides[dist] = [] + for loc in self.hint_dist_user['remove_locations']: + if dist in loc['types']: + self.hint_type_overrides[dist].append(loc['location']) + self.item_hint_type_overrides[dist] = [] + for i in self.hint_dist_user['remove_items']: + if dist in i['types']: + self.item_hint_type_overrides[dist].append(i['item']) + + self.always_hints = [hint.name for hint in getRequiredHints(self)] + + + + def load_regions_from_json(self, file_path): + region_json = read_json(file_path) + + for region in region_json: + new_region = OOTRegion(region['region_name'], RegionType.Generic, None, self.player) + new_region.world = self.world + if 'scene' in region: + new_region.scene = region['scene'] + if 'hint' in region: + new_region.hint_text = region['hint'] + if 'dungeon' in region: + new_region.dungeon = region['dungeon'] + if 'time_passes' in region: + new_region.time_passes = region['time_passes'] + new_region.provides_time = TimeOfDay.ALL + if new_region.name == 'Ganons Castle Grounds': + new_region.provides_time = TimeOfDay.DAMPE + if 'locations' in region: + for location, rule in region['locations'].items(): + new_location = LocationFactory(location, self.player) + if new_location.type in ['HintStone', 'Hint']: + continue + new_location.parent_region = new_region + new_location.rule_string = rule + if self.world.logic_rules != 'none': + self.parser.parse_spot_rule(new_location) + if new_location.never: + # We still need to fill the location even if ALR is off. + logger.debug('Unreachable location: %s', new_location.name) + new_location.player = self.player + new_region.locations.append(new_location) + if 'events' in region: + for event, rule in region['events'].items(): + # Allow duplicate placement of events + lname = '%s from %s' % (event, new_region.name) + new_location = OOTLocation(self.player, lname, type='Event', parent=new_region) + new_location.rule_string = rule + if self.world.logic_rules != 'none': + self.parser.parse_spot_rule(new_location) + if new_location.never: + logger.debug('Dropping unreachable event: %s', new_location.name) + else: + new_location.player = self.player + new_region.locations.append(new_location) + self.make_event_item(event, new_location) + new_location.show_in_spoiler = False + if 'exits' in region: + for exit, rule in region['exits'].items(): + new_exit = OOTEntrance(self.player, '%s => %s' % (new_region.name, exit), new_region) + new_exit.vanilla_connected_region = exit + new_exit.rule_string = rule + if self.world.logic_rules != 'none': + self.parser.parse_spot_rule(new_exit) + if new_exit.never: + logger.debug('Dropping unreachable exit: %s', new_exit.name) + else: + new_region.exits.append(new_exit) + + self.world.regions.append(new_region) + self.regions.append(new_region) + self.world._recache() + + + def set_scrub_prices(self): + # Get Deku Scrub Locations + scrub_locations = [location for location in self.get_locations() if 'Deku Scrub' in location.name] + scrub_dictionary = {} + self.scrub_prices = {} + for location in scrub_locations: + if location.default not in scrub_dictionary: + scrub_dictionary[location.default] = [] + scrub_dictionary[location.default].append(location) + + # Loop through each type of scrub. + for (scrub_item, default_price, text_id, text_replacement) in business_scrubs: + price = default_price + if self.shuffle_scrubs == 'low': + price = 10 + elif self.shuffle_scrubs == 'random': + # this is a random value between 0-99 + # average value is ~33 rupees + price = int(self.world.random.betavariate(1, 2) * 99) + + # Set price in the dictionary as well as the location. + self.scrub_prices[scrub_item] = price + if scrub_item in scrub_dictionary: + for location in scrub_dictionary[scrub_item]: + location.price = price + if location.item is not None: + location.item.price = price + + + def random_shop_prices(self): + shop_item_indexes = ['7', '5', '8', '6'] + self.shop_prices = {} + for region in self.regions: + if self.shopsanity == 'random': + shop_item_count = self.world.random.randint(0,4) + else: + shop_item_count = int(self.shopsanity) + + for location in region.locations: + if location.type == 'Shop': + if location.name[-1:] in shop_item_indexes[:shop_item_count]: + self.shop_prices[location.name] = int(self.world.random.betavariate(1.5, 2) * 60) * 5 + + + def fill_bosses(self, bossCount=9): + rewardlist = ( + 'Kokiri Emerald', + 'Goron Ruby', + 'Zora Sapphire', + 'Forest Medallion', + 'Fire Medallion', + 'Water Medallion', + 'Spirit Medallion', + 'Shadow Medallion', + 'Light Medallion' + ) + boss_location_names = ( + 'Queen Gohma', + 'King Dodongo', + 'Barinade', + 'Phantom Ganon', + 'Volvagia', + 'Morpha', + 'Bongo Bongo', + 'Twinrova', + 'Links Pocket' + ) + boss_rewards = [self.create_item(reward) for reward in rewardlist] + boss_locations = [self.world.get_location(loc, self.player) for loc in boss_location_names] + + placed_prizes = [loc.item.name for loc in boss_locations if loc.item is not None] + unplaced_prizes = [item for item in boss_rewards if item.name not in placed_prizes] + empty_boss_locations = [loc for loc in boss_locations if loc.item is None] + prizepool = list(unplaced_prizes) + prize_locs = list(empty_boss_locations) + + while bossCount: + bossCount -= 1 + self.world.random.shuffle(prizepool) + self.world.random.shuffle(prize_locs) + item = prizepool.pop() + loc = prize_locs.pop() + self.world.push_item(loc, item, collect=False) + loc.locked = True + loc.event = True + + + def create_item(self, name: str): + if name in item_table: + return OOTItem(name, self.player, item_table[name], False) + return OOTItem(name, self.player, ('Event', True, None, None), True) + + + def make_event_item(self, name, location, item=None): + if item is None: + item = self.create_item(name) + self.world.push_item(location, item, collect=False) + location.locked = True + location.event = True + if name not in item_table: + location.internal = True + return item + + + def create_regions(self): # create and link regions + if self.logic_rules == 'glitchless': + world_type = 'World' + else: + world_type = 'Glitched World' + overworld_data_path = data_path(world_type, 'Overworld.json') + menu = OOTRegion('Menu', None, None, self.player) + start = OOTEntrance(self.player, 'New Game', menu) + menu.exits.append(start) + self.world.regions.append(menu) + self.load_regions_from_json(overworld_data_path) + start.connect(self.world.get_region('Root', self.player)) + create_dungeons(self) + self.parser.create_delayed_rules() + + if self.shopsanity != 'off': + self.random_shop_prices() + self.set_scrub_prices() + + # logger.info('Setting Entrances.') + # set_entrances(self) + # Enforce vanilla for now + for region in self.regions: + for exit in region.exits: + exit.connect(self.world.get_region(exit.vanilla_connected_region, self.player)) + if self.entrance_shuffle: + shuffle_random_entrances(self) + + + def set_rules(self): + set_rules(self) + + + def generate_basic(self): # generate item pools, place fixed items + # Generate itempool + generate_itempool(self) + junk_pool = get_junk_pool(self) + # Determine starting items + for item in self.world.precollected_items: + if item.player != self.player: + continue + if item.name in self.remove_from_start_inventory: + self.remove_from_start_inventory.remove(item.name) + else: + self.starting_items[item.name] += 1 + if item.type == 'Song': + self.starting_songs = True + # Call the junk fill and get a replacement + if item in self.itempool: + self.itempool.remove(item) + self.itempool.append(self.create_item(*get_junk_item(pool=junk_pool))) + if self.start_with_consumables: + self.starting_items['Deku Sticks'] = 30 + self.starting_items['Deku Nuts'] = 40 + if self.start_with_rupees: + self.starting_items['Rupees'] = 999 + + # Uniquely rename drop locations for each region and erase them from the spoiler + set_drop_location_names(self) + + # Fill boss prizes + self.fill_bosses() + + # relevant for both dungeon item fill and song fill + dungeon_song_locations = [ + "Deku Tree Queen Gohma Heart", + "Dodongos Cavern King Dodongo Heart", + "Jabu Jabus Belly Barinade Heart", + "Forest Temple Phantom Ganon Heart", + "Fire Temple Volvagia Heart", + "Water Temple Morpha Heart", + "Shadow Temple Bongo Bongo Heart", + "Spirit Temple Twinrova Heart", + "Song from Impa", + "Sheik in Ice Cavern", + "Bottom of the Well Lens of Truth Chest", "Bottom of the Well MQ Lens of Truth Chest", # only one exists + "Gerudo Training Grounds Maze Path Final Chest", "Gerudo Training Grounds MQ Ice Arrows Chest", # only one exists + ] + + # Place/set rules for dungeon items + itempools = { + 'dungeon': [], + 'overworld': [], + 'any_dungeon': [], + 'keysanity': [], + } + any_dungeon_locations = [] + for dungeon in self.dungeons: + itempools['dungeon'] = [] + # Put the dungeon items into their appropriate pools. + # Build in reverse order since we need to fill boss key first and pop() returns the last element + if self.shuffle_mapcompass in itempools: + itempools[self.shuffle_mapcompass].extend(dungeon.dungeon_items) + if self.shuffle_smallkeys in itempools: + itempools[self.shuffle_smallkeys].extend(dungeon.small_keys) + shufflebk = self.shuffle_bosskeys if dungeon.name != 'Ganons Castle' else self.shuffle_ganon_bosskey + if shufflebk in itempools: + itempools[shufflebk].extend(dungeon.boss_key) + + # We can't put a dungeon item on the end of a dungeon if a song is supposed to go there. Make sure not to include it. + dungeon_locations = [loc for region in dungeon.regions for loc in region.locations + if loc.item is None and (self.shuffle_song_items != 'dungeon' or loc.name not in dungeon_song_locations)] + if itempools['dungeon']: # only do this if there's anything to shuffle + self.world.random.shuffle(dungeon_locations) + fill_restrictive(self.world, self.state_with_items(self.itempool), dungeon_locations, itempools['dungeon'], True, True) + any_dungeon_locations.extend(dungeon_locations) # adds only the unfilled locations + + # Now fill items that can go into any dungeon. Retrieve the Gerudo Fortress keys from the pool if necessary + if self.shuffle_fortresskeys == 'any_dungeon': + fortresskeys = list(filter(lambda item: item.player == self.player and item.type == 'FortressSmallKey', self.itempool)) + itempools['any_dungeon'].extend(fortresskeys) + for key in fortresskeys: + self.itempool.remove(key) + if itempools['any_dungeon']: + itempools['any_dungeon'].sort(key=lambda item: {'GanonBossKey': 4, 'BossKey': 3, 'SmallKey': 2, 'FortressSmallKey': 1}.get(item.type, 0)) + self.world.random.shuffle(any_dungeon_locations) + fill_restrictive(self.world, self.state_with_items(self.itempool), any_dungeon_locations, itempools['any_dungeon'], True, True) + + # If anything is overworld-only, enforce them as local and not in the remaining dungeon locations + if itempools['overworld'] or self.shuffle_fortresskeys == 'overworld': + from worlds.generic.Rules import forbid_items_for_player + fortresskeys = {'Small Key (Gerudo Fortress)'} if self.shuffle_fortresskeys == 'overworld' else set() + local_overworld_items = set(map(lambda item: item.name, itempools['overworld'])).union(fortresskeys) + for location in self.world.get_locations(): + if location.player != self.player or location in any_dungeon_locations: + forbid_items_for_player(location, local_overworld_items, self.player) + self.itempool.extend(itempools['overworld']) + + # Dump keysanity items into the itempool + self.itempool.extend(itempools['keysanity']) + + # Now that keys are in the pool, we can forbid tunics from child-only shops + set_entrances_based_rules(self) + + # Place songs + # 5 built-in retries because this section can fail sometimes + if self.shuffle_song_items != 'any': + tries = 5 + if self.shuffle_song_items == 'song': + song_locations = list(filter(lambda location: location.type == 'Song', + self.world.get_unfilled_locations(player=self.player))) + elif self.shuffle_song_items == 'dungeon': + song_locations = list(filter(lambda location: location.name in dungeon_song_locations, + self.world.get_unfilled_locations(player=self.player))) + else: + raise Exception(f"Unknown song shuffle type: {self.shuffle_song_items}") + + songs = list(filter(lambda item: item.player == self.player and item.type == 'Song', self.itempool)) + for song in songs: + self.itempool.remove(song) + while tries: + try: + self.world.random.shuffle(songs) # shuffling songs makes it less likely to fail by placing ZL last + self.world.random.shuffle(song_locations) + fill_restrictive(self.world, self.state_with_items(self.itempool), song_locations[:], songs[:], True, True) + logger.debug(f"Successfully placed songs for player {self.player} after {6-tries} attempt(s)") + tries = 0 + except FillError as e: + tries -= 1 + if tries == 0: + raise e + logger.debug(f"Failed placing songs for player {self.player}. Retries left: {tries}") + # undo what was done + for song in songs: + song.location = None + song.world = None + for location in song_locations: + location.item = None + location.locked = False + location.event = False + + # Place shop items + # fast fill will fail because there is some logic on the shop items. we'll gather them up and place the shop items + if self.shopsanity != 'off': + shop_items = list(filter(lambda item: item.player == self.player and item.type == 'Shop', self.itempool)) + shop_locations = list(filter(lambda location: location.type == 'Shop' and location.name not in self.shop_prices, + self.world.get_unfilled_locations(player=self.player))) + shop_items.sort(key=lambda item: 1 if item.name in ["Buy Goron Tunic", "Buy Zora Tunic"] else 0) + self.world.random.shuffle(shop_locations) + for item in shop_items: + self.itempool.remove(item) + fill_restrictive(self.world, self.state_with_items(self.itempool), shop_locations, shop_items, True, True) + set_shop_rules(self) + + # Locations which are not sendable must be converted to events + # This includes all locations for which show_in_spoiler is false, and shuffled shop items. + for loc in self.get_locations(): + if loc.address is not None and (not loc.show_in_spoiler or (loc.item is not None and loc.item.type == 'Shop') + or (self.skip_child_zelda and loc.name in ['HC Zeldas Letter', 'Song from Impa'])): + loc.address = None + + # Gather items for ice trap appearances + self.fake_items = [] + if self.ice_trap_appearance in ['major_only', 'anything']: + self.fake_items.extend([item for item in self.itempool if item.index and self.is_major_item(item)]) + if self.ice_trap_appearance in ['junk_only', 'anything']: + self.fake_items.extend([item for item in self.itempool if item.index and not self.is_major_item(item) and item.name != 'Ice Trap']) + + # Put all remaining items into the general itempool + self.world.itempool += self.itempool + + # Kill unreachable events that can't be gotten even with all items + # Make sure to only kill actual internal events, not in-game "events" + all_state = self.state_with_items(self.itempool) + all_locations = [loc for loc in self.world.get_locations() if loc.player == self.player] + reachable = self.world.get_reachable_locations(all_state, self.player) + unreachable = [loc for loc in all_locations if loc.internal and loc.event and loc.locked and loc not in reachable] + for loc in unreachable: + loc.parent_region.locations.remove(loc) + # Exception: Sell Big Poe is an event which is only reachable if Bottle with Big Poe is in the item pool. + # We allow it to be removed only if Bottle with Big Poe is not in the itempool. + bigpoe = self.world.get_location('Sell Big Poe from Market Guard House', self.player) + if not all_state.has('Bottle with Big Poe', self.player) and bigpoe not in reachable: + bigpoe.parent_region.locations.remove(bigpoe) + self.world.clear_location_cache() + + # If fast scarecrow then we need to kill the Pierre location as it will be unreachable + if self.free_scarecrow: + loc = self.world.get_location("Pierre", self.player) + loc.parent_region.locations.remove(loc) + # If open zora's domain then we need to kill Deliver Rutos Letter + if self.zora_fountain == 'open': + loc = self.world.get_location("Deliver Rutos Letter", self.player) + loc.parent_region.locations.remove(loc) + + def pre_fill(self): + # If skip child zelda is active and Song from Impa is unfilled, put a local giveable item into it. + impa = self.world.get_location("Song from Impa", self.player) + if self.skip_child_zelda and impa.item is None: + from .SaveContext import SaveContext + item_to_place = self.world.random.choice([item for item in self.world.itempool + if item.player == self.player and item.name in SaveContext.giveable_items]) + self.world.push_item(impa, item_to_place, False) + impa.locked = True + impa.event = True + self.world.itempool.remove(item_to_place) + + # For now we will always output a patch file. + def generate_output(self, output_directory: str): + # Make ice traps appear as other random items + ice_traps = [loc.item for loc in self.get_locations() if loc.item.name == 'Ice Trap'] + for trap in ice_traps: + trap.looks_like_item = self.create_item(self.world.slot_seeds[self.player].choice(self.fake_items).name) + + outfile_name = f"AP_{self.world.seed_name}_P{self.player}_{self.world.get_player_name(self.player)}" + rom = Rom(file=get_options()['oot_options']['rom_file']) # a ROM must be provided, cannot produce patches without it + if self.hints != 'none': + buildWorldGossipHints(self) + patch_rom(self, rom) + patch_cosmetics(self, rom) + rom.update_header() + create_patch_file(rom, output_path(output_directory, outfile_name+'.apz5')) + rom.restore() + + + # Helper functions + def get_shuffled_entrances(self): + return [] + + # make this a generator later? + def get_locations(self): + return [loc for region in self.regions for loc in region.locations] + + def get_location(self, location): + return self.world.get_location(location, self.player) + + def get_region(self, region): + return self.world.get_region(region, self.player) + + def state_with_items(self, items): + ret = CollectionState(self.world) + for item in items: + self.collect(ret, item) + ret.sweep_for_events() + return ret + + def is_major_item(self, item: OOTItem): + if item.type == 'Token': + return self.bridge == 'tokens' or self.lacs_condition == 'tokens' + + if item.type in ('Drop', 'Event', 'Shop', 'DungeonReward') or not item.advancement: + return False + + if item.name.startswith('Bombchus') and not self.bombchus_in_logic: + return False + + if item.type in ['Map', 'Compass']: + return False + if item.type == 'SmallKey' and self.shuffle_smallkeys in ['dungeon', 'vanilla']: + return False + if item.type == 'FortressSmallKey' and self.shuffle_fortresskeys == 'vanilla': + return False + if item.type == 'BossKey' and self.shuffle_bosskeys in ['dungeon', 'vanilla']: + return False + if item.type == 'GanonBossKey' and self.shuffle_ganon_bosskey in ['dungeon', 'vanilla']: + return False + + return True + + + # Run this once for to gather up all required locations (for WOTH), barren regions (for foolish), and location of major items. + # required_locations and major_item_locations need to be ordered for deterministic hints. + def gather_hint_data(self): + if self.required_locations and self.empty_areas and self.major_item_locations: + return + + items_by_region = {} + for r in self.regions: + items_by_region[r.hint_text] = {'dungeon': False, 'weight': 0, 'prog_items': 0} + for d in self.dungeons: + items_by_region[d.hint_text] = {'dungeon': True, 'weight': 0, 'prog_items': 0} + del(items_by_region["Link's Pocket"]) + del(items_by_region[None]) + + for loc in self.get_locations(): + if loc.item.code: # is a real item + hint_area = get_hint_area(loc) + items_by_region[hint_area]['weight'] += 1 + if loc.item.advancement and (not loc.locked or loc.item.type == 'Song'): + # Non-locked progression. Increment counter + items_by_region[hint_area]['prog_items'] += 1 + # Skip item at location and see if game is still beatable + state = CollectionState(self.world) + state.locations_checked.add(loc) + if not self.world.can_beat_game(state): + self.required_locations.append(loc) + self.empty_areas = {region: info for (region, info) in items_by_region.items() if not info['prog_items']} + + for loc in self.world.get_filled_locations(): + if (loc.item.player == self.player and self.is_major_item(loc.item) + or (loc.item.player == self.player and loc.item.name in self.item_added_hint_types['item']) + or (loc.name in self.added_hint_types['item'] and loc.player == self.player)): + self.major_item_locations.append(loc) diff --git a/worlds/oot/crc.py b/worlds/oot/crc.py new file mode 100644 index 00000000..cfaa1b95 --- /dev/null +++ b/worlds/oot/crc.py @@ -0,0 +1,36 @@ +import itertools +from .ntype import BigStream, uint32 + +def calculate_crc(self): + + t1 = t2 = t3 = t4 = t5 = t6 = 0xDF26F436 + u32 = 0xFFFFFFFF + + m1 = self.read_bytes(0x1000, 0x100000) + words = map(uint32.value, zip(m1[0::4], m1[1::4], m1[2::4], m1[3::4])) + + m2 = self.read_bytes(0x750, 0x100) + words2 = map(uint32.value, zip(m2[0::4], m2[1::4], m2[2::4], m2[3::4])) + + for d, d2 in zip(words, itertools.cycle(words2)): + # keep t2 and t6 in u32 for comparisons; others can wait to be truncated + if ((t6 + d) & u32) < t6: + t4 += 1 + + t6 = (t6+d) & u32 + t3 ^= d + shift = d & 0x1F + r = ((d << shift) | (d >> (32 - shift))) + t5 += r + + if t2 > d: + t2 ^= r & u32 + else: + t2 ^= t6 ^ d + + t1 += d2 ^ d + + crc0 = (t6 ^ t4 ^ t3) & u32 + crc1 = (t5 ^ t2 ^ t1) & u32 + + return uint32.bytes(crc0) + uint32.bytes(crc1) \ No newline at end of file diff --git a/worlds/oot/data/.gitignore b/worlds/oot/data/.gitignore new file mode 100644 index 00000000..28cde53d --- /dev/null +++ b/worlds/oot/data/.gitignore @@ -0,0 +1,4 @@ +/Bingo +/Music +presets_default.json +settings_mapping.json \ No newline at end of file diff --git a/worlds/oot/data/Compress/Compress b/worlds/oot/data/Compress/Compress new file mode 100644 index 00000000..868d6df3 Binary files /dev/null and b/worlds/oot/data/Compress/Compress differ diff --git a/worlds/oot/data/Compress/Compress.exe b/worlds/oot/data/Compress/Compress.exe new file mode 100644 index 00000000..fbdac2c2 Binary files /dev/null and b/worlds/oot/data/Compress/Compress.exe differ diff --git a/worlds/oot/data/Compress/Compress.out b/worlds/oot/data/Compress/Compress.out new file mode 100644 index 00000000..e0e2f301 Binary files /dev/null and b/worlds/oot/data/Compress/Compress.out differ diff --git a/worlds/oot/data/Compress/Compress32.exe b/worlds/oot/data/Compress/Compress32.exe new file mode 100644 index 00000000..f8c25929 Binary files /dev/null and b/worlds/oot/data/Compress/Compress32.exe differ diff --git a/worlds/oot/data/Compress/Compress_ARM64 b/worlds/oot/data/Compress/Compress_ARM64 new file mode 100644 index 00000000..5c0336f5 Binary files /dev/null and b/worlds/oot/data/Compress/Compress_ARM64 differ diff --git a/worlds/oot/data/Compress/src/bSwap.h b/worlds/oot/data/Compress/src/bSwap.h new file mode 100644 index 00000000..e41d6673 --- /dev/null +++ b/worlds/oot/data/Compress/src/bSwap.h @@ -0,0 +1,20 @@ +#ifndef BSWAP_H +#define BSWAP_H + +#include + +uint32_t bSwap32(uint32_t a) +{ + return( (a & 0x000000FF) << 24 | + (a & 0x0000FF00) << 8 | + (a & 0x00FF0000) >> 8 | + (a & 0xFF000000) >> 24 ); +} + +uint16_t bSwap16(uint16_t a) +{ + return( (a & 0x00FF) << 8 | + (a & 0xFF00) >> 8 ); +} + +#endif diff --git a/worlds/oot/data/Compress/src/compressor.c b/worlds/oot/data/Compress/src/compressor.c new file mode 100644 index 00000000..ddd7c55e --- /dev/null +++ b/worlds/oot/data/Compress/src/compressor.c @@ -0,0 +1,601 @@ +#include +#include +#include +#include +#include +#include +#include "bSwap.h" +#include "yaz0.c" +#include "crc.c" + +/* Needed to compile on Windows */ +#ifdef _WIN32 +#include +#endif + +/* Different ROM sizes */ +#define UINTSIZE 0x1000000 +#define COMPSIZE 0x2000000 + +/* Number of extra bytes to add to compression buffer */ +#define COMPBUFF 0x250 + +//Structs {{{1 +/* DMA table entry */ +typedef struct +{ + uint32_t startV; + uint32_t endV; + uint32_t startP; + uint32_t endP; +} +table_t; + +/* Temporary storage for output data */ +typedef struct +{ + table_t table; + uint8_t* data; + uint8_t comp; + uint32_t size; +} +output_t; + +/* Archive struct */ +typedef struct +{ + uint32_t fileCount; + uint32_t* refSize; + uint32_t* srcSize; + uint8_t** ref; + uint8_t** src; +} +archive_t; +/* 1}}} */ + +/* Functions {{{1 */ +uint32_t findTable(uint8_t*); +void getTableEnt(table_t*, uint32_t*, uint32_t); +void* threadFunc(void*); +void errorCheck(int, char**); +void makeArchive(); +int32_t getNumCores(); +int32_t getNext(); +/* 1}}} */ + +/* Globals {{{1 */ +char* inName; +char* outName; +uint8_t* inROM; +uint8_t* outROM; +uint8_t* refTab; +pthread_mutex_t filelock; +pthread_mutex_t countlock; +int32_t numFiles, nextFile; +int32_t arcCount, outSize; +uint32_t* fileTab; +archive_t* archive; +output_t* out; +/* 1}}} */ + +/* int main(int, char**) {{{1 */ +int main(int argc, char** argv) +{ + FILE* file; + int32_t tabStart, tabSize, tabCount, junk; + volatile int32_t prev; + int32_t i, j, size, numCores, tempSize; + pthread_t* threads; + table_t tab; + + errorCheck(argc, argv); + printf("Zelda64 Compressor, Version 2\n"); + fflush(stdout); + + /* Open input, read into inROM */ + file = fopen(argv[1], "rb"); + fseek(file, 0, SEEK_END); + tempSize = ftell(file); + fseek(file, 0, SEEK_SET); + inROM = calloc(tempSize, sizeof(uint8_t)); + junk = fread(inROM, tempSize, 1, file); + fclose(file); + + /* Read archive if it exists*/ + file = fopen("ARCHIVE.bin", "rb"); + if(file != NULL) + { + /* Get number of files */ + printf("Loading Archive.\n"); + fflush(stdout); + archive = malloc(sizeof(archive_t)); + junk = fread(&(archive->fileCount), sizeof(uint32_t), 1, file); + + /* Allocate space for files and sizes */ + archive->refSize = malloc(sizeof(uint32_t) * archive->fileCount); + archive->srcSize = malloc(sizeof(uint32_t) * archive->fileCount); + archive->ref = malloc(sizeof(uint8_t*) * archive->fileCount); + archive->src = malloc(sizeof(uint8_t*) * archive->fileCount); + + /* Read in file size and then file data */ + for(i = 0; i < archive->fileCount; i++) + { + /* Decompressed "Reference" file */ + junk = fread(&tempSize, sizeof(uint32_t), 1, file); + archive->ref[i] = malloc(tempSize); + archive->refSize[i] = tempSize; + junk = fread(archive->ref[i], 1, tempSize, file); + + /* Compressed "Source" file */ + junk = fread(&tempSize, sizeof(uint32_t), 1, file); + archive->src[i] = malloc(tempSize); + archive->srcSize[i] = tempSize; + junk = fread(archive->src[i], 1, tempSize, file); + } + fclose(file); + } + else + { + printf("No archive found, this could take a while.\n"); + fflush(stdout); + archive = NULL; + } + + /* Find the file table and relevant info */ + tabStart = findTable(inROM); + fileTab = (uint32_t*)(inROM + tabStart); + getTableEnt(&tab, fileTab, 2); + tabSize = tab.endV - tab.startV; + tabCount = tabSize / 16; + + /* Allocate space for the exclusion list */ + /* Default to 1 (compress), set exclusions to 0 */ + file = fopen("dmaTable.dat", "r"); + size = tabCount - 1; + refTab = malloc(sizeof(uint8_t) * size); + memset(refTab, 1, size); + + /* The first 3 files are never compressed */ + /* They should never be given to the compression function anyway though */ + refTab[0] = refTab[1] = refTab[2] = 0; + + /* Read in the rest of the exclusion list */ + for(i = 0; fscanf(file, "%d", &j) == 1; i++) + { + /* Make sure the number is within the dmaTable */ + if(j > size || j < -size) + { + fprintf(stderr, "Error: Entry %d in dmaTable.dat is out of bounds\n", i); + exit(1); + } + + /* If j was negative, the file shouldn't exist */ + /* Otherwise, set file to not compress */ + if(j < 0) + refTab[(~j + 1)] = 2; + else + refTab[j] = 0; + } + fclose(file); + + /* Initialise some stuff */ + out = malloc(sizeof(output_t) * tabCount); + pthread_mutex_init(&filelock, NULL); + pthread_mutex_init(&countlock, NULL); + numFiles = tabCount; + outSize = COMPSIZE; + nextFile = 3; + arcCount = 0; + + /* Get CPU core count */ + numCores = getNumCores(); + threads = malloc(sizeof(pthread_t) * numCores); + printf("Detected %d cores.\n", (numCores)); + printf("Starting compression.\n"); + fflush(stdout); + + /* Create all the threads */ + for(i = 0; i < numCores; i++) + pthread_create(&threads[i], NULL, threadFunc, NULL); + + /* Wait for all of the threads to finish */ + for(i = 0; i < numCores; i++) + pthread_join(threads[i], NULL); + printf("\n"); + + /* Get size of new ROM */ + /* Start with size of first 3 files */ + tempSize = tabStart + tabSize; + for(i = 3; i < tabCount; i++) + tempSize += out[i].size; + + /* If ROM is too big, update size */ + if(tempSize > outSize) + outSize = tempSize; + + /* Setup for copying to outROM */ + printf("Files compressed, writing new ROM.\n"); + outROM = calloc(outSize, sizeof(uint8_t)); + memcpy(outROM, inROM, tabStart + tabSize); + prev = tabStart + tabSize; + tabStart += 0x20; + + /* Free some stuff */ + pthread_mutex_destroy(&filelock); + pthread_mutex_destroy(&countlock); + if(archive != NULL) + { + free(archive->ref); + free(archive->src); + free(archive->refSize); + free(archive->srcSize); + free(archive); + } + free(threads); + free(refTab); + + /* Write data to outROM */ + for(i = 3; i < tabCount; i++) + { + tab = out[i].table; + size = out[i].size; + tabStart += 0x10; + + /* Finish table and copy to outROM */ + if(tab.startV != tab.endV) + { + /* Set up physical addresses */ + tab.startP = prev; + if(out[i].comp == 1) + tab.endP = tab.startP + size; + else if(out[i].comp == 2) + tab.startP = tab.endP = 0xFFFFFFFF; + + /* If the file existed, write it */ + if(tab.startP != 0xFFFFFFFF) + memcpy(outROM + tab.startP, out[i].data, size); + + /* Write the table entry */ + tab.startV = bSwap32(tab.startV); + tab.endV = bSwap32(tab.endV); + tab.startP = bSwap32(tab.startP); + tab.endP = bSwap32(tab.endP); + memcpy(outROM + tabStart, &tab, sizeof(table_t)); + } + + prev += size; + if(out[i].data != NULL) + free(out[i].data); + } + free(out); + + /* Fix the CRC before writing the ROM */ + fix_crc(outROM); + + /* Make and fill the output ROM */ + file = fopen(outName, "wb"); + fwrite(outROM, outSize, 1, file); + fclose(file); + + /* Make the archive if needed */ + if(archive == NULL) + { + printf("Creating archive.\n"); + makeArchive(); + } + + /* Free up the last bit of memory */ + if(argc != 3) + free(outName); + free(inROM); + free(outROM); + + printf("Compression complete.\n"); + + return(0); +} +/* 1}}} */ + +/* uint32_t findTAble(uint8_t*) {{{1 */ +uint32_t findTable(uint8_t* argROM) +{ + uint32_t i; + uint32_t* tempROM; + + tempROM = (uint32_t*)argROM; + + /* Start at the end of the makerom (0x10600000) */ + /* Look for dma entry for the makeom */ + /* Should work for all Zelda64 titles */ + for(i = 1048; i+4 < UINTSIZE; i += 4) + { + if(tempROM[i] == 0x00000000) + if(tempROM[i+1] == 0x60100000) + return(i * 4); + } + + fprintf(stderr, "Error: Couldn't find dma table in ROM!\n"); + exit(1); +} +/* 1}}} */ + +/* void getTableEnt(table_t*, uint32_t*, uint32_t) {{{1 */ +void getTableEnt(table_t* tab, uint32_t* files, uint32_t i) +{ + tab->startV = bSwap32(files[i*4]); + tab->endV = bSwap32(files[(i*4)+1]); + tab->startP = bSwap32(files[(i*4)+2]); + tab->endP = bSwap32(files[(i*4)+3]); +} +/* 1}}} */ + +/* void* threadFunc(void*) {{{1 */ +void* threadFunc(void* null) +{ + uint8_t* src; + uint8_t* dst; + table_t t; + int32_t i, nextArchive, size, srcSize; + + while((i = getNext()) != -1) + { + /* Setup the src */ + getTableEnt(&(t), fileTab, i); + srcSize = t.endV - t.startV; + src = inROM + t.startV; + + /* If refTab is 1, compress */ + /* If refTab is 2, file shouldn't exist */ + /* Otherwise, just copy src into out */ + if(refTab[i] == 1) + { + pthread_mutex_lock(&countlock); + nextArchive = arcCount++; + pthread_mutex_unlock(&countlock); + + /* If uncompressed is the same as archive, just copy/paste the compressed */ + /* Otherwise, compress it manually */ + if((archive != NULL) && (memcmp(src, archive->ref[nextArchive], archive->refSize[nextArchive]) == 0)) + { + out[i].comp = 1; + size = archive->srcSize[nextArchive]; + out[i].data = malloc(size); + memcpy(out[i].data, archive->src[nextArchive], size); + } + else + { + size = srcSize + COMPBUFF; + dst = calloc(size, sizeof(uint8_t)); + yaz0_encode(src, srcSize, dst, &(size)); + out[i].comp = 1; + out[i].data = malloc(size); + memcpy(out[i].data, dst, size); + free(dst); + } + + if(archive != NULL) + { + free(archive->ref[nextArchive]); + free(archive->src[nextArchive]); + } + } + else if(refTab[i] == 2) + { + out[i].comp = 2; + size = 0; + out[i].data = NULL; + } + else + { + out[i].comp = 0; + size = srcSize; + out[i].data = malloc(size); + memcpy(out[i].data, src, size); + } + + /* Set up the table entry and size */ + out[i].table = t; + out[i].size = size; + } + + return(NULL); +} +/* 1}}} */ + +/* void makeArchive() {{{1 */ +void makeArchive() +{ + table_t tab; + uint32_t tabSize, tabCount, tabStart; + uint32_t fileSize, fileCount, i; + FILE* file; + + /* Find DMAtable info */ + tabStart = findTable(outROM); + fileTab = (uint32_t*)(outROM + tabStart); + getTableEnt(&tab, fileTab, 2); + tabSize = tab.endV - tab.startV; + tabCount = tabSize / 16; + fileCount = 0; + + /* Find the number of compressed files in the ROM */ + /* Ignore first 3 files, as they're never compressed */ + for(i = 3; i < tabCount; i++) + { + getTableEnt(&tab, fileTab, i); + + if(tab.endP != 0 && tab.endP != 0xFFFFFFFF) + fileCount++; + } + + /* Open output file */ + file = fopen("ARCHIVE.bin", "wb"); + if(file == NULL) + { + perror("ARCHIVE.bin"); + fprintf(stderr, "Error: Could not create archive\n"); + return; + } + + /* Write the archive data */ + fwrite(&fileCount, sizeof(uint32_t), 1, file); + + /* Write the fileSize and data for each ref & src */ + for(i = 3; i < tabCount; i++) + { + getTableEnt(&tab, fileTab, i); + + if(tab.endP != 0 && tab.endP != 0xFFFFFFFF) + { + /* Write the size and data for the decompressed portion */ + fileSize = tab.endV - tab.startV; + fwrite(&fileSize, sizeof(uint32_t), 1, file); + fwrite(inROM + tab.startV, 1, fileSize, file); + + /* Write the size and data for the compressed portion */ + fileSize = tab.endP - tab.startP; + fwrite(&fileSize, sizeof(uint32_t), 1, file); + fwrite((outROM + tab.startP), 1, fileSize, file); + } + } + + fclose(file); +} +/* 1}}} */ + +/* int32_t getNumCores() {{{1 */ +int32_t getNumCores() +{ + /* Windows */ + #ifdef _WIN32 + + SYSTEM_INFO info; + GetSystemInfo(&info); + return(info.dwNumberOfProcessors); + + /* Mac */ + #elif MACOS + + int nm[2]; + size_t len; + uint32_t count; + + len = 4; + nm[0] = CTL_HW; + nm[1] = HW_AVAILCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + + if (count < 1) + { + nm[1] = HW_NCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + if (count < 1) + count = 1; + } + return(count); + + /* Linux */ + #else + + return(sysconf(_SC_NPROCESSORS_ONLN)); + + #endif +} +/* 1}}} */ + +/* int32_t getNext() {{{1 */ +int32_t getNext() +{ + int32_t file, temp; + + pthread_mutex_lock(&filelock); + + file = nextFile++; + + /* Progress tracker */ + if (file < numFiles) + { + temp = numFiles - (file + 1); + printf("%d files remaining\n", temp); + fflush(stdout); + } + else + { + file = -1; + } + + pthread_mutex_unlock(&filelock); + + return(file); +} +/* 1}}} */ + +/* void errorCheck(int, char**) {{{1 */ +void errorCheck(int argc, char** argv) +{ + int i, j; + FILE* file; + + /* Check for arguments */ + if(argc < 2) + { + fprintf(stderr, "Usage: %s [Input ROM] \n", argv[0]); + exit(1); + } + + /* Check that input ROM exists & has permissions */ + inName = argv[1]; + file = fopen(inName, "rb"); + if(file == NULL) + { + perror(inName); + exit(1); + } + + /* Check that dmaTable.dat exists & has permissions */ + file = fopen("dmaTable.dat", "r"); + if(file == NULL) + { + perror("dmaTable.dat"); + fprintf(stderr, "Please make a dmaTable.dat file first\n"); + exit(1); + } + + /* Check that output ROM is writeable */ + /* Create output filename if needed */ + if(argc < 3) + { + i = strlen(inName) + 6; + outName = malloc(i); + strcpy(outName, inName); + for(; i >= 0; i--) + { + if(outName[i] == '.') + { + outName[i] = '\0'; + break; + } + } + strcat(outName, "-comp.z64"); + file = fopen(outName, "wb"); + if(file == NULL) + { + perror(outName); + free(outName); + exit(1); + } + fclose(file); + } + else + { + outName = argv[2]; + file = fopen(outName, "wb"); + if(file == NULL) + { + perror(outName); + exit(1); + } + fclose(file); + } +} +/* 1}}} */ diff --git a/worlds/oot/data/Compress/src/crc.c b/worlds/oot/data/Compress/src/crc.c new file mode 100644 index 00000000..ce27782e --- /dev/null +++ b/worlds/oot/data/Compress/src/crc.c @@ -0,0 +1,175 @@ +/* snesrc - SNES Recompiler + * + * Copyright notice for this file: + * Copyright (C) 2005 Parasyte + * + * Based on uCON64's N64 checksum algorithm by Andreas Sterbenz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include +#include + +#define ROL(i, b) (((i) << (b)) | ((i) >> (32 - (b)))) +#define BYTES2LONG(b) ( (b)[0] << 24 | \ + (b)[1] << 16 | \ + (b)[2] << 8 | \ + (b)[3] ) + +#define N64_HEADER_SIZE 0x40 +#define N64_BC_SIZE (0x1000 - N64_HEADER_SIZE) + +#define N64_CRC1 0x10 +#define N64_CRC2 0x14 + +#define CHECKSUM_START 0x00001000 +#define CHECKSUM_LENGTH 0x00100000 +#define CHECKSUM_CIC6102 0xF8CA4DDC +#define CHECKSUM_CIC6103 0xA3886759 +#define CHECKSUM_CIC6105 0xDF26F436 +#define CHECKSUM_CIC6106 0x1FEA617A + + +unsigned int crc_table[256]; + +void gen_table() +{ + uint32_t crc, poly; + int32_t i, j; + + poly = 0xEDB88320; + for (i = 0; i < 256; i++) { + crc = i; + for (j = 8; j > 0; j--) { + if (crc & 1) crc = (crc >> 1) ^ poly; + else crc >>= 1; + } + crc_table[i] = crc; + } +} + +unsigned int crc32(unsigned char *data, int len) +{ + uint32_t crc, i; + + crc = ~0; + for (i = 0; i < len; i++) + crc = (crc >> 8) ^ crc_table[(crc ^ data[i]) & 0xFF]; + + return ~crc; +} + + +int N64GetCIC(unsigned char *data) +{ + switch (crc32(&data[N64_HEADER_SIZE], N64_BC_SIZE)) { + case 0x6170A4A1: return 6101; + case 0x90BB6CB5: return 6102; + case 0x0B050EE0: return 6103; + case 0x98BC2C86: return 6105; + case 0xACC8580A: return 6106; + } + + return 0; +} + +int N64CalcCRC(unsigned int *crc, unsigned char *data) +{ + int32_t bootcode, i; + uint32_t seed, r, d; + uint32_t t1, t2, t3; + uint32_t t4, t5, t6; + + switch ((bootcode = N64GetCIC(data))) { + case 6101: + case 6102: + seed = CHECKSUM_CIC6102; + break; + case 6103: + seed = CHECKSUM_CIC6103; + break; + case 6105: + seed = CHECKSUM_CIC6105; + break; + case 6106: + seed = CHECKSUM_CIC6106; + break; + default: + return 0; + } + + t1 = t2 = t3 = t4 = t5 = t6 = seed; + + i = CHECKSUM_START; + while (i < (CHECKSUM_START + CHECKSUM_LENGTH)) { + d = BYTES2LONG(&data[i]); + if ((t6 + d) < t6) t4++; + t6 += d; + t3 ^= d; + r = ROL(d, (d & 0x1F)); + t5 += r; + if (t2 > d) t2 ^= r; + else t2 ^= t6 ^ d; + + if (bootcode == 6105) t1 += BYTES2LONG(&data[N64_HEADER_SIZE + 0x0710 + (i & 0xFF)]) ^ d; + else t1 += t5 ^ d; + + i += 4; + } + if (bootcode == 6103) { + crc[0] = (t6 ^ t4) + t3; + crc[1] = (t5 ^ t2) + t1; + } + else if (bootcode == 6106) { + crc[0] = (t6 * t4) + t3; + crc[1] = (t5 * t2) + t1; + } + else { + crc[0] = t6 ^ t4 ^ t3; + crc[1] = t5 ^ t2 ^ t1; + } + + return 1; +} + +void fix_crc (uint8_t* buffer) +{ + uint8_t CRC1[4]; + uint8_t CRC2[4]; + uint32_t crc[2]; + uint32_t i; + + gen_table(); + + /* If the CRC calc was successful, do stuff */ + if(N64CalcCRC(crc, buffer)) + { + for(i = 0; i < 4; i++) + { + CRC1[i] = (crc[0] >> (24-8*i))&0xFF; + CRC2[i] = (crc[1] >> (24-8*i))&0xFF; + } + + /* If the CRC1 changed, update it */ + if(crc[0] != BYTES2LONG(&buffer[N64_CRC1])) + memcpy(buffer + N64_CRC1, CRC1, 4); + + /* If the CRC2 changed, update it */ + if (crc[1] != BYTES2LONG(&buffer[N64_CRC2])) + memcpy(buffer + N64_CRC2, CRC2, 4); + } +} diff --git a/worlds/oot/data/Compress/src/yaz0.c b/worlds/oot/data/Compress/src/yaz0.c new file mode 100644 index 00000000..afd3db17 --- /dev/null +++ b/worlds/oot/data/Compress/src/yaz0.c @@ -0,0 +1,186 @@ +#include +#include +#include + +uint32_t RabinKarp(uint8_t*, int, int, uint32_t*); +uint32_t findBest(uint8_t*, int, int, uint32_t*, uint32_t*, uint32_t*, uint8_t*); +int yaz0_internal(uint8_t*, int, uint8_t*); +void yaz0_encode(uint8_t*, int, uint8_t*, int*); + +uint32_t RabinKarp(uint8_t* src, int srcSize, int srcPos, uint32_t* matchPos) +{ + int startPos, smp, i; + uint32_t hash, curHash, curSize; + uint32_t bestSize, bestPos; + + smp = srcSize - srcPos; + startPos = srcPos - 0x1000; + bestPos = bestSize = 0; + + /* If available size is too small, return */ + if(smp < 3) + return(0); + + /* If available size is too big, reduce it */ + if(smp > 0x111) + smp = 0x111; + + /* If start position is negative, make it 0 */ + if(startPos < 0) + startPos = 0; + + /* Generate "hash" by converting to an int */ + hash = bSwap32(*(int*)(src + srcPos)); + hash = hash >> 8; + curHash = bSwap32(*(int*)(src + startPos)); + curHash = curHash >> 8; + + /* Search through data */ + for(i = startPos; i < srcPos; i++) + { + /* If 3 bytes match, check for more */ + if(curHash == hash) + { + for(curSize = 3; curSize < smp; curSize++) + if(src[i + curSize] != src[srcPos + curSize]) + break; + + /* Uodate best if needed */ + if(curSize > bestSize) + { + bestSize = curSize; + bestPos = i; + if(bestSize == 0x111) + break; + } + } + + /* Scoot over 1 byte */ + curHash = (curHash << 8 | src[i + 3]) & 0x00FFFFFF; + } + + /* Set match position, return the size of the match */ + *matchPos = bestPos; + return(bestSize); +} + +uint32_t findBest(uint8_t* src, int srcSize, int srcPos, uint32_t* matchPos, uint32_t* pMatch, uint32_t* pSize, uint8_t* pFlag) +{ + int rv; + + /* Check to see if this location was found by a look-ahead */ + if(*pFlag == 1) + { + *pFlag = 0; + return(*pSize); + } + + /* Find best match */ + *pFlag = 0; + rv = RabinKarp(src, srcSize, srcPos, matchPos); + + /* Look-ahead */ + if(rv >= 3) + { + /* Find best match if current one were to be a 1 byte copy */ + *pSize = RabinKarp(src, srcSize, srcPos+1, pMatch); + if(*pSize >= rv+2) + { + rv = *pFlag = 1; + *matchPos = *pMatch; + } + } + + return(rv); +} + +int yaz0_internal(uint8_t* src, int srcSize, uint8_t* dst) +{ + int dstPos, srcPos, codeBytePos; + uint32_t numBytes, matchPos, dist, pMatch, pSize; + uint8_t codeByte, bitmask, pFlag; + + srcPos = codeBytePos = 0; + dstPos = codeBytePos + 1; + bitmask = 0x80; + codeByte = pFlag = 0; + + /* Go through all of src */ + while(srcPos < srcSize) + { + /* Try to find matching bytes for compressing */ + numBytes = findBest(src, srcSize, srcPos, &matchPos, &pMatch, &pSize, &pFlag); + + /* Single byte copy */ + if(numBytes < 3) + { + dst[dstPos++] = src[srcPos++]; + codeByte |= bitmask; + } + + /* Three byte encoding */ + else if (numBytes > 0x11) + { + dist = srcPos - matchPos - 1; + + /* Copy over 0R RR */ + dst[dstPos++] = dist >> 8; + dst[dstPos++] = dist & 0xFF; + + /* Reduce N if needed, copy over NN */ + if(numBytes > 0x111) + numBytes = 0x111; + dst[dstPos++] = (numBytes - 0x12) & 0xFF; + + srcPos += numBytes; + } + + /* Two byte encoding */ + else + { + dist = srcPos - matchPos - 1; + + /* Copy over NR RR */ + dst[dstPos++] = ((numBytes - 2) << 4) | (dist >> 8); + dst[dstPos++] = dist & 0xFF; + + srcPos += numBytes; + } + + /* Move bitmask to next byte */ + bitmask = bitmask >> 1; + + /* If all 8 bytes were used, write and move to the next one */ + if(bitmask == 0) + { + dst[codeBytePos] = codeByte; + codeBytePos = dstPos; + if(srcPos < srcSize) + dstPos++; + codeByte = 0; + bitmask = 0x80; + } + } + + /* Copy over last byte if it hasn't already */ + if(bitmask != 0) + dst[codeBytePos] = codeByte; + + /* Return size of dst */ + return(dstPos); +} + +void yaz0_encode(uint8_t* src, int srcSize, uint8_t* dst, int* dstSize) +{ + int temp; + + /* Write Yaz0 header */ + temp = bSwap32(srcSize); + memcpy(dst, "Yaz0", 4); + memcpy(dst + 4, &temp, 4); + + /* Encode, adjust dstSize */ + temp = yaz0_internal(src, srcSize, dst + 16); + *dstSize = (temp + 31) & -16; + return; +} diff --git a/worlds/oot/data/Decompress/Decompress b/worlds/oot/data/Decompress/Decompress new file mode 100644 index 00000000..7e9d80aa Binary files /dev/null and b/worlds/oot/data/Decompress/Decompress differ diff --git a/worlds/oot/data/Decompress/Decompress.exe b/worlds/oot/data/Decompress/Decompress.exe new file mode 100644 index 00000000..9cebb3b9 Binary files /dev/null and b/worlds/oot/data/Decompress/Decompress.exe differ diff --git a/worlds/oot/data/Decompress/Decompress.out b/worlds/oot/data/Decompress/Decompress.out new file mode 100644 index 00000000..196da476 Binary files /dev/null and b/worlds/oot/data/Decompress/Decompress.out differ diff --git a/worlds/oot/data/Decompress/Decompress32.exe b/worlds/oot/data/Decompress/Decompress32.exe new file mode 100644 index 00000000..d890fda2 Binary files /dev/null and b/worlds/oot/data/Decompress/Decompress32.exe differ diff --git a/worlds/oot/data/Decompress/Decompress_ARM64 b/worlds/oot/data/Decompress/Decompress_ARM64 new file mode 100644 index 00000000..5e397d3e Binary files /dev/null and b/worlds/oot/data/Decompress/Decompress_ARM64 differ diff --git a/worlds/oot/data/Decompress/src/bSwap.h b/worlds/oot/data/Decompress/src/bSwap.h new file mode 100644 index 00000000..80f4df8c --- /dev/null +++ b/worlds/oot/data/Decompress/src/bSwap.h @@ -0,0 +1,30 @@ +#ifndef BSWAP_H +#define BSWAP_H + +#include + +#if BYTE_ORDER == LITTLE_ENDIAN +#define bSwap32(x) _bSwap32(x) +#define bSwap16(x) _bSwap16(x) + +#elif BYTE_ORDER == BIG_ENDIAN +#define bSwap32(x) (x) +#define bSwap16(x) (x) + +#endif + +uint32_t _bSwap32(uint32_t a) +{ + return( (a & 0x000000FF) << 24 | + (a & 0x0000FF00) << 8 | + (a & 0x00FF0000) >> 8 | + (a & 0xFF000000) >> 24 ); +} + +uint16_t _bSwap16(uint16_t a) +{ + return( (a & 0x00FF) << 8 | + (a & 0xFF00) >> 8 ); +} + +#endif diff --git a/worlds/oot/data/Decompress/src/crc.c b/worlds/oot/data/Decompress/src/crc.c new file mode 100644 index 00000000..ce27782e --- /dev/null +++ b/worlds/oot/data/Decompress/src/crc.c @@ -0,0 +1,175 @@ +/* snesrc - SNES Recompiler + * + * Copyright notice for this file: + * Copyright (C) 2005 Parasyte + * + * Based on uCON64's N64 checksum algorithm by Andreas Sterbenz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include +#include + +#define ROL(i, b) (((i) << (b)) | ((i) >> (32 - (b)))) +#define BYTES2LONG(b) ( (b)[0] << 24 | \ + (b)[1] << 16 | \ + (b)[2] << 8 | \ + (b)[3] ) + +#define N64_HEADER_SIZE 0x40 +#define N64_BC_SIZE (0x1000 - N64_HEADER_SIZE) + +#define N64_CRC1 0x10 +#define N64_CRC2 0x14 + +#define CHECKSUM_START 0x00001000 +#define CHECKSUM_LENGTH 0x00100000 +#define CHECKSUM_CIC6102 0xF8CA4DDC +#define CHECKSUM_CIC6103 0xA3886759 +#define CHECKSUM_CIC6105 0xDF26F436 +#define CHECKSUM_CIC6106 0x1FEA617A + + +unsigned int crc_table[256]; + +void gen_table() +{ + uint32_t crc, poly; + int32_t i, j; + + poly = 0xEDB88320; + for (i = 0; i < 256; i++) { + crc = i; + for (j = 8; j > 0; j--) { + if (crc & 1) crc = (crc >> 1) ^ poly; + else crc >>= 1; + } + crc_table[i] = crc; + } +} + +unsigned int crc32(unsigned char *data, int len) +{ + uint32_t crc, i; + + crc = ~0; + for (i = 0; i < len; i++) + crc = (crc >> 8) ^ crc_table[(crc ^ data[i]) & 0xFF]; + + return ~crc; +} + + +int N64GetCIC(unsigned char *data) +{ + switch (crc32(&data[N64_HEADER_SIZE], N64_BC_SIZE)) { + case 0x6170A4A1: return 6101; + case 0x90BB6CB5: return 6102; + case 0x0B050EE0: return 6103; + case 0x98BC2C86: return 6105; + case 0xACC8580A: return 6106; + } + + return 0; +} + +int N64CalcCRC(unsigned int *crc, unsigned char *data) +{ + int32_t bootcode, i; + uint32_t seed, r, d; + uint32_t t1, t2, t3; + uint32_t t4, t5, t6; + + switch ((bootcode = N64GetCIC(data))) { + case 6101: + case 6102: + seed = CHECKSUM_CIC6102; + break; + case 6103: + seed = CHECKSUM_CIC6103; + break; + case 6105: + seed = CHECKSUM_CIC6105; + break; + case 6106: + seed = CHECKSUM_CIC6106; + break; + default: + return 0; + } + + t1 = t2 = t3 = t4 = t5 = t6 = seed; + + i = CHECKSUM_START; + while (i < (CHECKSUM_START + CHECKSUM_LENGTH)) { + d = BYTES2LONG(&data[i]); + if ((t6 + d) < t6) t4++; + t6 += d; + t3 ^= d; + r = ROL(d, (d & 0x1F)); + t5 += r; + if (t2 > d) t2 ^= r; + else t2 ^= t6 ^ d; + + if (bootcode == 6105) t1 += BYTES2LONG(&data[N64_HEADER_SIZE + 0x0710 + (i & 0xFF)]) ^ d; + else t1 += t5 ^ d; + + i += 4; + } + if (bootcode == 6103) { + crc[0] = (t6 ^ t4) + t3; + crc[1] = (t5 ^ t2) + t1; + } + else if (bootcode == 6106) { + crc[0] = (t6 * t4) + t3; + crc[1] = (t5 * t2) + t1; + } + else { + crc[0] = t6 ^ t4 ^ t3; + crc[1] = t5 ^ t2 ^ t1; + } + + return 1; +} + +void fix_crc (uint8_t* buffer) +{ + uint8_t CRC1[4]; + uint8_t CRC2[4]; + uint32_t crc[2]; + uint32_t i; + + gen_table(); + + /* If the CRC calc was successful, do stuff */ + if(N64CalcCRC(crc, buffer)) + { + for(i = 0; i < 4; i++) + { + CRC1[i] = (crc[0] >> (24-8*i))&0xFF; + CRC2[i] = (crc[1] >> (24-8*i))&0xFF; + } + + /* If the CRC1 changed, update it */ + if(crc[0] != BYTES2LONG(&buffer[N64_CRC1])) + memcpy(buffer + N64_CRC1, CRC1, 4); + + /* If the CRC2 changed, update it */ + if (crc[1] != BYTES2LONG(&buffer[N64_CRC2])) + memcpy(buffer + N64_CRC2, CRC2, 4); + } +} diff --git a/worlds/oot/data/Decompress/src/decompressor.c b/worlds/oot/data/Decompress/src/decompressor.c new file mode 100644 index 00000000..8a7cb69d --- /dev/null +++ b/worlds/oot/data/Decompress/src/decompressor.c @@ -0,0 +1,259 @@ +#include +#include +#include +#include +#include "crc.c" +#include "bSwap.h" + +#define UINTSIZE 0x01000000 +#define COMPSIZE 0x02000000 +#define DCMPSIZE 0x04000000 + +/* Structs */ +typedef struct +{ + uint32_t startV; /* Start Virtual Address */ + uint32_t endV; /* End Virtual Address */ + uint32_t startP; /* Start Physical Address */ + uint32_t endP; /* End Phycical Address */ +} +table_t; + +/* Functions */ +void decompress(uint8_t*, uint8_t*, int32_t); +table_t getTabEnt(uint32_t); +void setTabEnt(uint32_t, table_t); +void loadROM(char*); +int32_t findTable(); + +/* Globals */ +uint8_t* inROM; +uint8_t* outROM; +uint32_t* inTable; +uint32_t* outTable; + +int main(int argc, char** argv) +{ + FILE* outFile; + int32_t tabStart, tabSize, tabCount; + int32_t size, i; + table_t tab, tempTab; + char* name; + + /* Check arguments */ + if(argc < 2 || argc > 3) + { + fprintf(stderr, "Usage: %s [Input ROM] \n", argv[0]); + exit(1); + } + + /* If no output file was specified, make one */ + /* Add "-decomp.z64" to the end of the input file */ + if(argc != 3) + { + size = strlen(argv[1]); + name = malloc(size + 7); + strcpy(name, argv[1]); + for(i = size; i >= 0; i--) + { + if(name[i] == '.') + { + name[i] = '\0'; + break; + } + } + strcat(name, "-decomp.z64"); + } + + else + name = argv[2]; + + inROM = malloc(DCMPSIZE); + outROM = malloc(DCMPSIZE); + + /* Load the ROM into inROM and outROM */ + loadROM(argv[1]); + + /* Find table offsets */ + tabStart = findTable(); + inTable = (uint32_t*)(inROM + tabStart); + outTable = (uint32_t*)(outROM + tabStart); + tab = getTabEnt(2); + tabSize = tab.endV - tab.startV; + tabCount = tabSize / 16; + + /* Set everything past the table in outROM to 0 */ + memset((uint8_t*)(outROM) + tab.endV, 0, DCMPSIZE - tab.endV); + + for(i = 3; i < tabCount; i++) + { + tempTab = getTabEnt(i); + size = tempTab.endV - tempTab.startV; + + /* dmaTable will have 0xFFFFFFFF if file doesn't exist */ + if(tempTab.startP >= DCMPSIZE || tempTab.endP == 0xFFFFFFFF) + continue; + + /* Copy if not compressed, decompress otherwise */ + if(tempTab.endP == 0x00000000) + memcpy((void*)outROM + tempTab.startV, (void*)inROM + tempTab.startP, size); + else + decompress((void*)inROM + tempTab.startP, (void*)outROM + tempTab.startV, size); + + /* Clean up outROM's table */ + tempTab.startP = tempTab.startV; + tempTab.endP = 0x00000000; + setTabEnt(i, tempTab); + } + + /* Fix the CRC */ + fix_crc(outROM); + + /* Write the new ROM */ + outFile = fopen(name, "wb"); + fwrite(outROM, sizeof(uint32_t), UINTSIZE, outFile); + fclose(outFile); + free(outROM); + free(inROM); + + if(argc != 3) + free(name); + + return(0); +} + +int32_t findTable() +{ + int32_t i, temp; + uint32_t* tempROM; + + tempROM = (uint32_t*)inROM; + + /* Start at the end of the makerom (0x10600000) */ + /* Look for dma entry for the makeom */ + /* Should work for all Zelda64 titles */ + for(i = 1048; i+4 < UINTSIZE; i += 4) + { + if(tempROM[i] == 0x00000000) + if(tempROM[i+1] == 0x60100000) + return(i * 4); + } + + fprintf(stderr, "Error: Couldn't find table\n"); + exit(1); +} + +void loadROM(char* name) +{ + uint32_t size, i; + uint16_t* tempROM; + FILE* romFile; + + /* Open file, make sure it exists */ + romFile = fopen(name, "rb"); + if(romFile == NULL) + { + perror(name); + exit(1); + } + /* Find size of file */ + fseek(romFile, 0, SEEK_END); + size = ftell(romFile); + fseek(romFile, 0, SEEK_SET); + + /* If it's not the right size, exit */ + if(size != COMPSIZE) + { + fprintf(stderr, "Error, %s is not the correct size", name); + exit(1); + } + + /* Read to inROM, close romFile, and copy to outROM */ + fread(inROM, sizeof(char), size, romFile); + tempROM = (uint16_t*)inROM; + fclose(romFile); + + /* bSwap16 if needed */ + if (inROM[0] == 0x37) + for (i = 0; i < UINTSIZE; i++) + tempROM[i] = bSwap16(tempROM[i]); + + memcpy(outROM, inROM, size); +} + +table_t getTabEnt(uint32_t i) +{ + table_t tab; + + /* First 32 bytes are VROM start address, next 32 are VROM end address */ + /* Next 32 bytes are Physical start address, last 32 are Physical end address */ + tab.startV = bSwap32(inTable[i*4] ); + tab.endV = bSwap32(inTable[(i*4)+1]); + tab.startP = bSwap32(inTable[(i*4)+2]); + tab.endP = bSwap32(inTable[(i*4)+3]); + + return(tab); +} + +void setTabEnt(uint32_t i, table_t tab) +{ + /* First 32 bytes are VROM start address, next 32 are VROM end address */ + /* Next 32 bytes are Physical start address, last 32 are Physical end address */ + outTable[i*4] = bSwap32(tab.startV); + outTable[(i*4)+1] = bSwap32(tab.endV); + outTable[(i*4)+2] = bSwap32(tab.startP); + outTable[(i*4)+3] = bSwap32(tab.endP); +} + +void decompress(uint8_t* source, uint8_t* decomp, int32_t decompSize) +{ + uint32_t srcPlace = 0, dstPlace = 0; + uint32_t i, dist, copyPlace, numBytes; + uint8_t codeByte, byte1, byte2; + uint8_t bitCount = 0; + + source += 0x10; + while(dstPlace < decompSize) + { + /* If there are no more bits to test, get a new byte */ + if(!bitCount) + { + codeByte = source[srcPlace++]; + bitCount = 8; + } + + /* If bit 7 is a 1, just copy 1 byte from source to destination */ + /* Else do some decoding */ + if(codeByte & 0x80) + { + decomp[dstPlace++] = source[srcPlace++]; + } + else + { + /* Get 2 bytes from source */ + byte1 = source[srcPlace++]; + byte2 = source[srcPlace++]; + + /* Calculate distance to move in destination */ + /* And the number of bytes to copy */ + dist = ((byte1 & 0xF) << 8) | byte2; + copyPlace = dstPlace - (dist + 1); + numBytes = byte1 >> 4; + + /* Do more calculations on the number of bytes to copy */ + if(!numBytes) + numBytes = source[srcPlace++] + 0x12; + else + numBytes += 2; + + /* Copy data from a previous point in destination */ + /* to current point in destination */ + for(i = 0; i < numBytes; i++) + decomp[dstPlace++] = decomp[copyPlace++]; + } + + /* Set up for the next read cycle */ + codeByte = codeByte << 1; + bitCount--; + } +} diff --git a/worlds/oot/data/Glitched World/Bottom of the Well MQ.json b/worlds/oot/data/Glitched World/Bottom of the Well MQ.json new file mode 100644 index 00000000..ce168286 --- /dev/null +++ b/worlds/oot/data/Glitched World/Bottom of the Well MQ.json @@ -0,0 +1,29 @@ +[ + { + "region_name": "Bottom of the Well", + "dungeon": "Bottom of the Well", + "locations": { + "Bottom of the Well MQ Compass Chest": " + Kokiri_Sword or (Sticks and logic_child_deadhand)", + "Bottom of the Well MQ Map Chest": " + can_play(Zeldas_Lullaby) or has_explosives", + "Bottom of the Well MQ Lens of Truth Chest": " + has_explosives and + (Small_Key_Bottom_of_the_Well, 2)", + "Bottom of the Well MQ Dead Hand Freestanding Key": " + has_explosives or (logic_botw_mq_dead_hand_key and Boomerang)", + "Bottom of the Well MQ East Inner Room Freestanding Key": " + can_play(Zeldas_Lullaby) or has_explosives", + "Bottom of the Well MQ GS Basement": "can_child_attack", + "Bottom of the Well MQ GS West Inner Room": " + can_child_attack and + (can_play(Zeldas_Lullaby) or has_explosives)", + "Bottom of the Well MQ GS Coffin Room": " + can_child_attack and + (Small_Key_Bottom_of_the_Well, 2)" + }, + "exits": { + "Kakariko Village": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Bottom of the Well.json b/worlds/oot/data/Glitched World/Bottom of the Well.json new file mode 100644 index 00000000..d7fecf32 --- /dev/null +++ b/worlds/oot/data/Glitched World/Bottom of the Well.json @@ -0,0 +1,50 @@ +[ + { + "region_name": "Bottom of the Well", + "dungeon": "Bottom of the Well", + "exits": { + "Bottom of the Well Main Area" : "is_child and (can_child_attack or Nuts)" + } + }, + { + "region_name": "Bottom of the Well Main Area", + "dungeon": "Bottom of the Well", + "locations": { + "Bottom of the Well Front Left Fake Wall Chest": "True", + "Bottom of the Well Front Center Bombable Chest": "has_explosives", + "Bottom of the Well Right Bottom Fake Wall Chest": "True", + "Bottom of the Well Compass Chest": "True", + "Bottom of the Well Center Skulltula Chest": "True", + "Bottom of the Well Back Left Bombable Chest": "has_explosives", + "Bottom of the Well Freestanding Key": "Sticks or can_use(Dins_Fire) or Boomerang", + "Bottom of the Well Lens of Truth Chest": " + (can_play(Zeldas_Lullaby) or (Small_Key_Bottom_of_the_Well,3)) and + (Kokiri_Sword or Sticks)", + "Bottom of the Well Invisible Chest": "(can_play(Zeldas_Lullaby) or (Small_Key_Bottom_of_the_Well,3))", + "Bottom of the Well Underwater Front Chest": "can_play(Zeldas_Lullaby)", + "Bottom of the Well Underwater Left Chest": "can_play(Zeldas_Lullaby)", + "Bottom of the Well Map Chest": " + has_explosives or + (((Small_Key_Bottom_of_the_Well, 3) or + can_use(Dins_Fire) or Sticks) and + Progressive_Strength_Upgrade)", + "Bottom of the Well Fire Keese Chest": " + (Small_Key_Bottom_of_the_Well, 3)", + "Bottom of the Well Like Like Chest": " + (Small_Key_Bottom_of_the_Well, 3)", + "Bottom of the Well GS West Inner Room": " + (Boomerang or can_isg) and + (Small_Key_Bottom_of_the_Well, 3)", + "Bottom of the Well GS East Inner Room": " + (Boomerang or can_isg) and + (Small_Key_Bottom_of_the_Well, 3)", + "Bottom of the Well GS Like Like Cage": " + (Boomerang or can_isg) and + (Small_Key_Bottom_of_the_Well, 3)", + "Stick Pot": "True" + }, + "exits": { + "Bottom of the Well" : "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Deku Tree MQ.json b/worlds/oot/data/Glitched World/Deku Tree MQ.json new file mode 100644 index 00000000..c7871056 --- /dev/null +++ b/worlds/oot/data/Glitched World/Deku Tree MQ.json @@ -0,0 +1,49 @@ +[ + { + "region_name": "Deku Tree Lobby", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ Map Chest": "True", + "Deku Tree MQ Slingshot Chest": "can_child_attack", + "Deku Tree MQ Slingshot Room Back Chest": "Sticks or can_use(Dins_Fire)", + "Deku Tree MQ Basement Chest": "Sticks or can_use(Dins_Fire)", + "Deku Tree MQ GS Lobby": "can_child_attack" + }, + "exits": { + "KF Outside Deku Tree": "True", + "Deku Tree Compass Room": "Slingshot and (Sticks or can_use(Dins_Fire))", + "Deku Tree Boss Room": "Slingshot and (Sticks or can_use(Dins_Fire))" + } + }, + { + "region_name": "Deku Tree Compass Room", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ Compass Chest": "True", + "Deku Tree MQ GS Compass Room": " + Boomerang and ((Bombs and can_play(Song_of_Time)) or has_bombchus)" + }, + "exits": { + "Deku Tree Lobby": "True" + } + }, + { + "region_name": "Deku Tree Boss Room", + "dungeon": "Deku Tree", + "events": { + "Deku Tree Clear": "Buy_Deku_Shield and (Kokiri_Sword or Sticks)" + }, + "locations": { + "Deku Tree MQ Before Spinning Log Chest": "True", + "Deku Tree MQ After Spinning Log Chest": "can_play(Song_of_Time)", + "Deku Tree MQ GS Basement Graves Room": "Boomerang and can_play(Song_of_Time)", + "Deku Tree MQ GS Basement Back Room": "Boomerang", + "Deku Tree MQ Deku Scrub": "True", + "Deku Tree Queen Gohma Heart": "Buy_Deku_Shield and (Kokiri_Sword or Sticks)", + "Queen Gohma": "Buy_Deku_Shield and (Kokiri_Sword or Sticks)" + }, + "exits": { + "Deku Tree Lobby": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Deku Tree.json b/worlds/oot/data/Glitched World/Deku Tree.json new file mode 100644 index 00000000..ca9ea714 --- /dev/null +++ b/worlds/oot/data/Glitched World/Deku Tree.json @@ -0,0 +1,57 @@ +[ + { + "region_name": "Deku Tree Lobby", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree Map Chest": "True", + "Deku Tree Compass Chest": "True", + "Deku Tree Compass Room Side Chest": "True", + "Deku Tree Basement Chest": "is_adult or can_child_attack or Nuts", + "Deku Tree GS Compass Room": "is_adult or can_child_attack", + "Deku Tree GS Basement Vines": "is_adult or can_child_attack", + "Deku Tree GS Basement Gate": "is_adult or can_child_attack", + "Deku Tree GS Basement Back Room": " + (here(has_fire_source_with_torch or can_use(Bow)) and + here(can_use(Slingshot) or can_use(Bow)) and + here(can_blast_or_smash) and + here(can_use(Hookshot) or can_use(Boomerang) or can_hover)) or + (is_child and (has_explosives or Blue_Fire) and + (can_use(Boomerang) or can_hover) and has_fire_source_with_torch) or + (is_adult and has_explosives and Progressive_Hookshot and Hover_Boots and can_live_dmg(0.5) and + (Bow or has_fire_source))" + }, + "exits": { + "Deku Tree Slingshot Room": "here(has_shield)", + "Deku Tree Boss Room": "here(has_fire_source_with_torch()) or can_shield + or is_adult" + } + }, + { + "region_name": "Deku Tree Slingshot Room", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree Slingshot Chest": "True", + "Deku Tree Slingshot Room Side Chest": "True" + }, + "exits": { + "Deku Tree Lobby": "True" + } + }, + { + "region_name": "Deku Tree Boss Room", + "dungeon": "Deku Tree", + "events": { + "Deku Tree Clear": "(Nuts or can_use(Slingshot) or has_bombchus or can_use(Hookshot) or can_use(Bow) or can_use(Boomerang)) and + ((here(has_shield or can_use(Megaton_Hammer)) and (is_adult or Kokiri_Sword or Sticks)) or is_adult)" + }, + "locations": { + "Deku Tree Queen Gohma Heart": "(Nuts or can_use(Slingshot) or has_bombchus or can_use(Hookshot) or can_use(Bow) or can_use(Boomerang)) and + ((here(has_shield or can_use(Megaton_Hammer)) and (is_adult or Kokiri_Sword or Sticks)) or is_adult)", + "Queen Gohma": "(Nuts or can_use(Slingshot) or has_bombchus or can_use(Hookshot) or can_use(Bow) or can_use(Boomerang)) and + ((here(has_shield or can_use(Megaton_Hammer)) and (is_adult or Kokiri_Sword or Sticks)) or is_adult)" + }, + "exits": { + "Deku Tree Lobby": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Dodongos Cavern MQ.json b/worlds/oot/data/Glitched World/Dodongos Cavern MQ.json new file mode 100644 index 00000000..21c45675 --- /dev/null +++ b/worlds/oot/data/Glitched World/Dodongos Cavern MQ.json @@ -0,0 +1,65 @@ +[ + { + "region_name": "Dodongos Cavern Beginning", + "dungeon": "Dodongos Cavern", + "exits": { + "Dodongos Cavern Entryway": "True", + "Dodongos Cavern Lobby": "can_blast_or_smash or Progressive_Strength_Upgrade" + } + }, + { + "region_name": "Dodongos Cavern Lobby", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern MQ Map Chest": "True", + "Dodongos Cavern MQ Compass Chest": "is_adult or can_child_attack or Nuts", + "Dodongos Cavern MQ Larvae Room Chest": "can_use(Sticks) or has_fire_source", + "Dodongos Cavern MQ Torch Puzzle Room Chest": " + can_blast_or_smash or can_use(Sticks) or can_use(Dins_Fire) or + (is_adult and (logic_dc_jump or Hover_Boots or Progressive_Hookshot))", + "Dodongos Cavern MQ Bomb Bag Chest": " + is_adult or + (Slingshot and + (has_explosives or + ((Sticks or can_use(Dins_Fire)) and can_take_damage)))", + "Dodongos Cavern MQ GS Song of Time Block Room": " + can_play(Song_of_Time) and (can_child_attack or is_adult)", + "Dodongos Cavern MQ GS Larvae Room": "can_use(Sticks) or has_fire_source", + "Dodongos Cavern MQ GS Lizalfos Room": "can_blast_or_smash", + "Dodongos Cavern MQ GS Scrub Room": " + (can_use(Boomerang) and (Slingshot or (can_become_adult and has_explosives)) and + (has_explosives or (Progressive_Strength_Upgrade and + (Megaton_Hammer or + ((Sticks or can_use(Dins_Fire) or + (can_become_adult and (logic_dc_jump or Hover_Boots))) and + can_take_damage))))) or + (can_use(Hookshot) and (has_explosives or Progressive_Strength_Upgrade or + Bow or can_use(Dins_Fire)))", + "Dodongos Cavern MQ Deku Scrub Lobby Rear": "can_stun_deku", + "Dodongos Cavern MQ Deku Scrub Lobby Front": "can_stun_deku", + "Dodongos Cavern MQ Deku Scrub Staircase": "can_stun_deku", + "Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos": " + is_adult or has_explosives or + ((Sticks or can_use(Dins_Fire)) and can_take_damage)", + "Dodongos Cavern Gossip Stone": "True" + }, + "exits": { + "Dodongos Cavern Boss Area": "has_explosives" + } + }, + { + "region_name": "Dodongos Cavern Boss Area", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern MQ Under Grave Chest": "True", + "Dodongos Cavern Boss Room Chest": "True", + "Dodongos Cavern King Dodongo Heart": " + (Bombs or Progressive_Strength_Upgrade) and + (is_adult or Sticks or Kokiri_Sword)", + "King Dodongo": " + (Bombs or Progressive_Strength_Upgrade) and + (is_adult or Sticks or Kokiri_Sword)", + "Dodongos Cavern MQ GS Back Area": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Dodongos Cavern.json b/worlds/oot/data/Glitched World/Dodongos Cavern.json new file mode 100644 index 00000000..9271f594 --- /dev/null +++ b/worlds/oot/data/Glitched World/Dodongos Cavern.json @@ -0,0 +1,91 @@ +[ + { + "region_name": "Dodongos Cavern Beginning", + "dungeon": "Dodongos Cavern", + "exits": { + "Dodongos Cavern Lobby": " + here(can_blast_or_smash or Blue_Fire) or Progressive_Strength_Upgrade" + } + }, + { + "region_name": "Dodongos Cavern Lobby", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Map Chest": "True", + "Dodongos Cavern Compass Chest": " + is_adult or Sticks or + (can_use(Dins_Fire) and (Slingshot or has_explosives or Kokiri_Sword)) + or can_shield", + "Dodongos Cavern GS Side Room Near Lower Lizalfos": " + has_explosives or is_adult or can_child_attack or Blue_Fire", + "Dodongos Cavern GS Scarecrow": "True", + "Dodongos Cavern Deku Scrub Side Room Near Dodongos": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword or can_shield", + "Dodongos Cavern Deku Scrub Lobby": "True", + "Dodongos Cavern Gossip Stone": "True" + }, + "exits": { + "Dodongos Cavern Beginning": "True", + "Dodongos Cavern Climb": " + here( + (is_adult or can_shield or + ( (Sticks or can_use(Dins_Fire)) and + (Slingshot or Sticks or has_explosives or Kokiri_Sword) + ) + ) + ) and + (has_explosives or Progressive_Strength_Upgrade or + can_use(Dins_Fire) or can_use(Bow) )" + } + }, + { + "region_name": "Dodongos Cavern Climb", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Bomb Flower Platform Chest": "True", + "Dodongos Cavern GS Vines Above Stairs": "True", + "Dodongos Cavern Deku Scrub Near Bomb Bag Right": "can_blast_or_smash or (Blue_Fire and can_stun_deku)", + "Dodongos Cavern Deku Scrub Near Bomb Bag Left": "can_blast_or_smash or (Blue_Fire and can_stun_deku)" + }, + "exits": { + "Dodongos Cavern Lobby": "True", + "Dodongos Cavern Far Bridge": "True" + } + }, + { + "region_name": "Dodongos Cavern Far Bridge", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Bomb Bag Chest": "True", + "Dodongos Cavern End of Bridge Chest": "can_blast_or_smash or Blue_Fire", + "Dodongos Cavern GS Alcove Above Stairs": "can_use(Hookshot) or can_use(Boomerang) + or (can_live_dmg(0.5) and can_use(Hover_Boots)) or can_hover" + }, + "exits": { + "Dodongos Cavern Boss Area": "has_explosives", + "Dodongos Cavern Lobby": "True" + } + }, + { + "region_name": "Dodongos Cavern Boss Area", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Boss Room Chest": "True", + "Dodongos Cavern King Dodongo Heart": " + (Bombs or Progressive_Strength_Upgrade or + (has_bombchus and ((is_adult and can_shield) or (is_child and can_isg))) + ) and + (is_adult or Sticks or Kokiri_Sword)", + "King Dodongo": " + (Bombs or Progressive_Strength_Upgrade or + (has_bombchus and ((is_adult and can_shield) or (is_child and can_isg))) + ) and + (is_adult or Sticks or Kokiri_Sword)", + "Dodongos Cavern GS Back Room": "True" + }, + "exits": { + "Dodongos Cavern Lobby": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Fire Temple MQ.json b/worlds/oot/data/Glitched World/Fire Temple MQ.json new file mode 100644 index 00000000..de318978 --- /dev/null +++ b/worlds/oot/data/Glitched World/Fire Temple MQ.json @@ -0,0 +1,95 @@ +[ + { + "region_name": "Fire Temple Lower", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Map Room Side Chest": "True", + "Fire Temple MQ Near Boss Chest": " + ((Hover_Boots or (logic_fire_mq_near_boss and Bow)) and has_fire_source) or + (Progressive_Hookshot and (can_use(Fire_Arrows) or + (can_use(Dins_Fire) and + ((damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or can_use(Goron_Tunic) or + Bow or (Progressive_Hookshot, 2)))))" + }, + "exits": { + "DMC Central": "True", + "Fire Boss Room": " + has_fire_source and can_use(Goron_Tunic) and Megaton_Hammer and Boss_Key_Fire_Temple and + (logic_fire_boss_door_jump or Hover_Boots or at('Fire Temple Upper', True))", + "Fire Lower Locked Door": " + (Small_Key_Fire_Temple, 5) and + (has_explosives or Megaton_Hammer or Progressive_Hookshot)", + "Fire Big Lava Room": "can_use(Megaton_Hammer)" + } + }, + { + "region_name": "Fire Lower Locked Door", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Megaton Hammer Chest": "True", + "Fire Temple MQ Map Chest": "Megaton_Hammer" + } + }, + { + "region_name": "Fire Big Lava Room", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Boss Key Chest": " + has_fire_source and (Bow or logic_fire_mq_bk_chest) and + Progressive_Hookshot", + "Fire Temple MQ Big Lava Room Blocked Door Chest": " + has_fire_source and Progressive_Hookshot and has_explosives", + "Fire Temple MQ GS Big Lava Room Open Door": "True" + }, + "exits": { + "Fire Lower Maze": " + can_use(Goron_Tunic) and (Small_Key_Fire_Temple, 2) and has_fire_source" + } + }, + { + "region_name": "Fire Lower Maze", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Lizalfos Maze Lower Chest": "True", + "Fire Temple MQ Lizalfos Maze Side Room Chest": " + has_explosives and (logic_fire_mq_maze_side_room or can_use(Hookshot))" + }, + "exits": { + "Fire Upper Maze": " + (has_explosives or logic_rusted_switches) and can_use(Hookshot)" + } + }, + { + "region_name": "Fire Upper Maze", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Lizalfos Maze Upper Chest": "True", + "Fire Temple MQ Compass Chest": "has_explosives", + "Fire Temple MQ GS Skull On Fire": " + can_play(Song_of_Time) or can_use(Longshot)" + }, + "exits": { + "Fire Temple Upper": "(Small_Key_Fire_Temple, 3) and Bow" + } + }, + { + "region_name": "Fire Temple Upper", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Freestanding Key": "True", + "Fire Temple MQ Chest On Fire": "(Small_Key_Fire_Temple, 4)", + "Fire Temple MQ GS Fire Wall Maze Side Room": " + can_play(Song_of_Time) or Hover_Boots", + "Fire Temple MQ GS Fire Wall Maze Center": "has_explosives", + "Fire Temple MQ GS Above Fire Wall Maze": "(Small_Key_Fire_Temple, 5)" + } + }, + { + "region_name": "Fire Boss Room", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Volvagia Heart": "True", + "Volvagia": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Fire Temple.json b/worlds/oot/data/Glitched World/Fire Temple.json new file mode 100644 index 00000000..7b46428b --- /dev/null +++ b/worlds/oot/data/Glitched World/Fire Temple.json @@ -0,0 +1,96 @@ +[ + { + "region_name": "Fire Temple Lower", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Near Boss Chest" : "True", + "Fire Temple Flare Dancer Chest": " + ((Small_Key_Fire_Temple, 8) or not keysanity) and (can_use(Megaton_Hammer) or can_use(Hookshot) or has_explosives)", + "Fire Temple Boss Key Chest": "( + ((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)) or (can_mega and can_use(Hookshot))", + "Fire Temple Volvagia Heart": " + (can_use(Goron_Tunic) or (Fairy and has_explosives)) and can_use(Megaton_Hammer) and + (Boss_Key_Fire_Temple or at('Fire Temple Flame Maze', True))", + "Volvagia": " + (can_use(Goron_Tunic) or (Fairy and has_explosives)) and can_use(Megaton_Hammer) and + (Boss_Key_Fire_Temple or at('Fire Temple Flame Maze', True))", + "Fire Temple GS Boss Key Loop": " + ((Small_Key_Fire_Temple, 8) or not keysanity)" + }, + "exits": { + "Fire Temple Big Lava Room":"(Small_Key_Fire_Temple, 2)" + } + }, + { + "region_name": "Fire Temple Big Lava Room", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Big Lava Room Lower Open Door Chest": "True", + "Fire Temple Big Lava Room Blocked Door Chest": "has_explosives", + "Fire Temple GS Song of Time Room": "is_adult" + }, + "exits": { + "Fire Temple Lower": "True", + "Fire Temple Middle": " + (can_use(Goron_Tunic) or Fairy) and (Small_Key_Fire_Temple, 4) and + (has_explosives or can_use(Bow) or can_use(Hookshot))" + } + }, + { + "region_name": "Fire Temple Middle", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Boulder Maze Lower Chest": "True", + "Fire Temple Boulder Maze Upper Chest": "(Small_Key_Fire_Temple, 6) + or (has_explosives and can_live_dmg(0.5) and (Small_Key_Fire_Temple, 4))", + "Fire Temple Boulder Maze Side Room Chest": "True", + "Fire Temple Boulder Maze Shortcut Chest": "((Small_Key_Fire_Temple, 6) and has_explosives) or + (((has_explosives and can_live_dmg(0.5)) or can_weirdshot) and (Small_Key_Fire_Temple, 4))", + "Fire Temple Scarecrow Chest": "( + (Small_Key_Fire_Temple, 6) or (has_explosives and can_live_dmg(0.5) and (Small_Key_Fire_Temple, 4)) ) + and (can_use(Scarecrow) or can_hover)", + "Fire Temple Map Chest": " + (Small_Key_Fire_Temple, 6) or ((Small_Key_Fire_Temple, 5) and can_use(Bow)) or + (has_explosives and can_live_dmg(0.5) and (Small_Key_Fire_Temple, 4))", + "Fire Temple GS Boulder Maze": "(Small_Key_Fire_Temple, 4) and has_explosives", + "Fire Temple GS Scarecrow Climb": "( + (Small_Key_Fire_Temple, 6) or (has_explosives and can_live_dmg(0.5) and (Small_Key_Fire_Temple, 4)) ) + and (can_use(Scarecrow) or can_hover)", + "Fire Temple GS Scarecrow Top": "( + (Small_Key_Fire_Temple, 6) or (has_explosives and can_live_dmg(0.5) and (Small_Key_Fire_Temple, 4)) ) + and (can_use(Scarecrow) or can_hover)" + }, + "exits": { + "Fire Temple Flame Maze": "(Small_Key_Fire_Temple, 7)" + } + }, + { + "region_name": "Fire Temple Flame Maze", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Compass Chest": "(Small_Key_Fire_Temple, 7)" + }, + "exits": { + "Fire Temple Upper": "(Small_Key_Fire_Temple, 7)" + } + }, + { + "region_name": "Fire Temple Upper", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Highest Goron Chest": "( + can_use(Megaton_Hammer) or (has_explosives and can_live_dmg(1.0)) + ) or + ( + (can_mega and can_use(Hookshot)) or + (can_play(Song_of_Time) and + (can_use(Megaton_Hammer) or can_use(Hover_Boots) or (has_explosives and can_live_dmg(0.5)) ) + ) + + ) + ", + "Fire Temple Megaton Hammer Chest": "has_explosives or + can_use(Megaton_Hammer)" + } + } +] diff --git a/worlds/oot/data/Glitched World/Forest Temple MQ.json b/worlds/oot/data/Glitched World/Forest Temple MQ.json new file mode 100644 index 00000000..7b9c3e55 --- /dev/null +++ b/worlds/oot/data/Glitched World/Forest Temple MQ.json @@ -0,0 +1,146 @@ +[ + { + "region_name": "Forest Temple Lobby", + "dungeon": "Forest Temple", + "locations": { + #If entrances are shuffled, Adult might lose access to the Kokiri forest + #Babas for nuts. As this is sphere 0 for both ages, this case is covered + #by putting the babas here. + "Forest Temple Deku Baba Nuts": "True", + "Forest Temple Deku Baba Sticks": "True", + "Forest Temple MQ First Room Chest": "True", + "Forest Temple MQ GS First Hallway": "True" + }, + "exits": { + "Sacred Forest Meadow": "True", + "Forest Temple Central Area": "(Small_Key_Forest_Temple, 1)" + } + }, + { + "region_name": "Forest Temple Central Area", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Wolfos Chest": "can_play(Song_of_Time)", + "Forest Temple MQ GS Block Push Room": "True" + }, + "exits": { + "Forest Temple NW Outdoors": "can_use(Bow)", + "Forest Temple NE Outdoors": "can_use(Bow)", + "Forest Temple After Block Puzzle": " + (has_bombchus and logic_forest_mq_block_puzzle) or Progressive_Strength_Upgrade", + "Forest Temple Outdoor Ledge": " + (has_bombchus and logic_forest_mq_block_puzzle) or + Progressive_Strength_Upgrade or can_use(Hover_Boots)", + "Forest Temple Boss Region": " + Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg" + } + }, + { + "region_name": "Forest Temple After Block Puzzle", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Boss Key Chest": "(Small_Key_Forest_Temple, 3)" + }, + "exits": { + "Forest Temple Bow Region": "(Small_Key_Forest_Temple, 4)" + } + }, + { + "region_name": "Forest Temple Outdoor Ledge", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Redead Chest": "True" + }, + "exits": { + "Forest Temple NW Outdoors": "True" + } + }, + { + "region_name": "Forest Temple NW Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ GS Level Island Courtyard": "True" + }, + "exits": { + "Forest Temple NE Outdoors": " + can_use(Iron_Boots) or can_use(Longshot) or + (Progressive_Scale, 2) or (logic_forest_well_swim and can_use(Hookshot))", + "Forest Temple Outdoors Top Ledges": "can_use(Fire_Arrows)" + } + }, + { + "region_name": "Forest Temple NE Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Well Chest": "can_use(Bow)", + "Forest Temple MQ GS Raised Island Courtyard": "True", + "Forest Temple MQ GS Well": "can_use(Iron_Boots) or can_use(Bow)" + }, + "exits": { + "Forest Temple Outdoors Top Ledges": " + can_use(Longshot) or can_use(Hover_Boots) or can_play(Song_of_Time) or + (logic_forest_vines and can_use(Hookshot))", + "Forest Temple NE Outdoors Ledge": "can_use(Longshot)" + } + }, + { + "region_name": "Forest Temple Outdoors Top Ledges", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Raised Island Courtyard Upper Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors": "True" + } + }, + { + "region_name": "Forest Temple NE Outdoors Ledge", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Raised Island Courtyard Lower Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors": "True", + "Forest Temple Falling Room": "can_play(Song_of_Time)" + } + }, + { + "region_name": "Forest Temple Bow Region", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Jo and Beth": "can_use(Bow)" + }, + "locations": { + "Forest Temple MQ Bow Chest": "True", + "Forest Temple MQ Map Chest": "can_use(Bow)", + "Forest Temple MQ Compass Chest": "can_use(Bow)" + }, + "exits": { + "Forest Temple Falling Room": " + (Small_Key_Forest_Temple, 5) and + (can_use(Bow) or can_use(Dins_Fire))" # Only 5 keys because the door you could waste your key on is the door you're trying to use keys to get to. + } + }, + { + "region_name": "Forest Temple Falling Room", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Amy and Meg": "can_use(Bow) and (Small_Key_Forest_Temple, 6)" + }, + "locations": { + "Forest Temple MQ Falling Ceiling Room Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors Ledge": "True" + } + }, + { + "region_name": "Forest Temple Boss Region", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Basement Chest": "True", + "Forest Temple Phantom Ganon Heart": "Boss_Key_Forest_Temple", + "Phantom Ganon": "Boss_Key_Forest_Temple" + } + } +] diff --git a/worlds/oot/data/Glitched World/Forest Temple.json b/worlds/oot/data/Glitched World/Forest Temple.json new file mode 100644 index 00000000..68ab4273 --- /dev/null +++ b/worlds/oot/data/Glitched World/Forest Temple.json @@ -0,0 +1,163 @@ +[ + { + "region_name": "Forest Temple Lobby", + "dungeon": "Forest Temple", + "locations": { + #If entrances are shuffled, Adult might lose access to the Kokiri forest + #Babas for nuts. As this is sphere 0 for both ages, this case is covered + #by putting the babas here. + "Deku Baba Nuts": "is_adult", + "Deku Baba Sticks": "is_adult", + "Forest Temple First Room Chest": "True", + "Forest Temple First Stalfos Chest": "can_jumpslash", + "Forest Temple GS First Room": "can_use(Dins_Fire) or can_use_projectile or (can_jumpslash and can_live_dmg(0.5))", + "Forest Temple GS Lobby": "can_use(Hookshot) or can_use(Boomerang) or can_hover" + }, + "exits": { + "Forest Temple NW Outdoors": "True", + "Forest Temple NE Outdoors": "can_use(Bow) or can_use(Slingshot)", + "Forest Temple Block Push Room": "(Small_Key_Forest_Temple, 1)", + "Forest Temple Basement": "(Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg) or (can_use(Hover_Boots) and can_mega)", + "Forest Temple Falling Room": "can_hover or (can_use(Hover_Boots) and Bombs and can_live_dmg(0.5))", + "Forest Temple Boss Room": "is_adult" + } + }, + { + "region_name": "Forest Temple NW Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple GS Level Island Courtyard": " + can_use(Longshot) or + at('Forest Temple Outside Upper Ledge', can_use(Hookshot) or can_hover)" + }, + "exits": { + "Forest Temple Outdoors High Balconies": " + is_adult or + (has_explosives or + ((can_use(Boomerang) or Nuts or Buy_Deku_Shield) and + (Sticks or Kokiri_Sword or can_use(Slingshot))))", + "Forest Temple Outside Upper Ledge": "can_hover or (can_use(Hover_Boots) and has_explosives and can_live_dmg(0.5))", + "Forest Temple Boss Room": "is_child and can_live_dmg(0.5)" + } + }, + { + "region_name": "Forest Temple NE Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Raised Island Courtyard Chest": " + can_use(Hookshot) or + at('Forest Temple Falling Room', True) or can_hover", + "Forest Temple GS Raised Island Courtyard": " + can_use(Hookshot) or can_hover or + at('Forest Temple Falling Room', can_use(Bow) or can_use(Dins_Fire) or has_explosives or can_use(Boomerang))" + }, + "exits": { + "Forest Temple Outdoors High Balconies": "can_use(Hookshot)", + #Longshot can grab some very high up vines to drain the well. + "Forest Temple NW Outdoors": "can_use(Iron_Boots) or (Progressive_Scale, 2)", + "Forest Temple Lobby": "True", + "Forest Temple Falling Room": "can_hover or + at('Forest Temple Outdoors High Balconies', + can_use(Hover_Boots) and can_use(Scarecrow) and can_live_dmg(0.5))" + } + }, + { + "region_name": "Forest Temple Outdoors High Balconies", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Well Chest": "True", + "Forest Temple Map Chest": "True" + }, + "exits": { + "Forest Temple NW Outdoors": "True", + "Forest Temple NE Outdoors": "True" + } + }, + { + "region_name": "Forest Temple Falling Room", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Amy and Meg": "can_use(Bow)" + }, + "locations": { + "Forest Temple Falling Ceiling Room Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors": "True" + } + }, + { + "region_name": "Forest Temple Block Push Room", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Eye Switch Chest": " + Progressive_Strength_Upgrade and (can_use(Bow) or can_use(Slingshot))" + }, + "exits": { + "Forest Temple Outside Upper Ledge": "can_jumpslash", + "Forest Temple Bow Region": " + (Progressive_Strength_Upgrade or (can_mega and (can_hover or Hover_Boots))) + and (Small_Key_Forest_Temple, 3) and is_adult", + "Forest Temple Straightened Hall": " + (Progressive_Strength_Upgrade or (is_adult and can_mega and (can_hover or Hover_Boots))) + and (Small_Key_Forest_Temple, 2) and (can_use(Bow) or (can_use(Slingshot) and can_hover))" + } + }, + { + "region_name": "Forest Temple Straightened Hall", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Boss Key Chest": "True" + }, + "exits": { + "Forest Temple Outside Upper Ledge": "True" + } + }, + { + "region_name": "Forest Temple Outside Upper Ledge", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Floormaster Chest": "is_adult or can_child_damage" + }, + "exits": { + "Forest Temple NW Outdoors": "True" + } + }, + { + "region_name": "Forest Temple Bow Region", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Jo and Beth": "can_use(Bow)" + }, + "locations": { + "Forest Temple Bow Chest": "True", + "Forest Temple Red Poe Chest": "can_use(Bow)", + "Forest Temple Blue Poe Chest": "can_use(Bow)" + }, + "exits": { + "Forest Temple Falling Room": " + (Small_Key_Forest_Temple, 5) and (Bow or can_use(Dins_Fire))" + } + }, + { + "region_name": "Forest Temple Basement", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Basement Chest": "True", + "Forest Temple GS Basement": "can_use(Hookshot) or can_use(Boomerang) or can_hover" + }, + "exits":{ + "Forest Temple Boss Room": "Boss_Key_Forest_Temple" + } + }, + { + "region_name": "Forest Temple Boss Room", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Phantom Ganon Heart": "(can_use(Hookshot) or can_use(Bow)) or + (can_use(Slingshot) and (Kokiri_Sword or Sticks))", + "Phantom Ganon": "(can_use(Hookshot) or can_use(Bow)) or + (can_use(Slingshot) and (Kokiri_Sword or Sticks))" + } + } +] diff --git a/worlds/oot/data/Glitched World/Ganons Castle MQ.json b/worlds/oot/data/Glitched World/Ganons Castle MQ.json new file mode 100644 index 00000000..a1efb152 --- /dev/null +++ b/worlds/oot/data/Glitched World/Ganons Castle MQ.json @@ -0,0 +1,123 @@ +[ + { + "region_name": "Ganons Castle Lobby", + "exits": { + "Ganons Castle Grounds": "True", + "Ganons Castle Forest Trial": "True", + "Ganons Castle Fire Trial": "True", + "Ganons Castle Water Trial": "True", + "Ganons Castle Shadow Trial": "True", + "Ganons Castle Spirit Trial": "True", + "Ganons Castle Light Trial": "can_use(Golden_Gauntlets)", + "Ganons Castle Tower": " + (skipped_trials[Forest] or 'Forest Trial Clear') and + (skipped_trials[Fire] or 'Fire Trial Clear') and + (skipped_trials[Water] or 'Water Trial Clear') and + (skipped_trials[Shadow] or 'Shadow Trial Clear') and + (skipped_trials[Spirit] or 'Spirit Trial Clear') and + (skipped_trials[Light] or 'Light Trial Clear')", + "Ganons Castle Deku Scrubs": "logic_lens_castle_mq or can_use(Lens_of_Truth)" + } + }, + { + "region_name": "Ganons Castle Deku Scrubs", + "locations": { + "Ganons Castle MQ Deku Scrub Center-Left": "True", + "Ganons Castle MQ Deku Scrub Center": "True", + "Ganons Castle MQ Deku Scrub Center-Right": "True", + "Ganons Castle MQ Deku Scrub Left": "True", + "Ganons Castle MQ Deku Scrub Right": "True" + } + }, + { + "region_name": "Ganons Castle Forest Trial", + "dungeon": "Ganons Castle", + "events": { + "Forest Trial Clear": "can_use(Light_Arrows) and can_play(Song_of_Time)" + }, + "locations": { + "Ganons Castle MQ Forest Trial Eye Switch Chest": "Bow", + "Ganons Castle MQ Forest Trial Frozen Eye Switch Chest": "has_fire_source", + "Ganons Castle MQ Forest Trial Freestanding Key": "Progressive_Hookshot" + } + }, + { + "region_name": "Ganons Castle Fire Trial", + "dungeon": "Ganons Castle", + "events": { + "Fire Trial Clear": " + can_use(Goron_Tunic) and can_use(Golden_Gauntlets) and + can_use(Light_Arrows) and (can_use(Longshot) or Hover_Boots)" + } + }, + { + "region_name": "Ganons Castle Water Trial", + "dungeon": "Ganons Castle", + "events": { + "Water Trial Clear": " + Blue_Fire and can_use(Light_Arrows) and + (Small_Key_Ganons_Castle, 3)" + }, + "locations": { + "Ganons Castle MQ Water Trial Chest": "Blue_Fire", + "Blue Fire": "has_bottle" + } + }, + { + "region_name": "Ganons Castle Shadow Trial", + "dungeon": "Ganons Castle", + "events": { + "Shadow Trial Clear": " + can_use(Light_Arrows) and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and + (Hover_Boots or (Progressive_Hookshot and has_fire_source))" + }, + "locations": { + "Ganons Castle MQ Shadow Trial Bomb Flower Chest": " + (Bow and (Progressive_Hookshot or Hover_Boots)) or + (Hover_Boots and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and + (has_explosives or Progressive_Strength_Upgrade or can_use(Dins_Fire)))", + "Ganons Castle MQ Shadow Trial Eye Switch Chest": " + Bow and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and + (Hover_Boots or (Progressive_Hookshot and has_fire_source))" + } + }, + { + "region_name": "Ganons Castle Spirit Trial", + "dungeon": "Ganons Castle", + "events": { + "Spirit Trial Clear": " + can_use(Light_Arrows) and Megaton_Hammer and + has_bombchus and Fire_Arrows and Mirror_Shield" + }, + "locations": { + "Ganons Castle MQ Spirit Trial First Chest": "(Bow or logic_rusted_switches) and Megaton_Hammer", + "Ganons Castle MQ Spirit Trial Invisible Chest": " + (Bow or logic_rusted_switches) and Megaton_Hammer and + has_bombchus and (logic_lens_castle_mq or can_use(Lens_of_Truth))", + "Ganons Castle MQ Spirit Trial Sun Front Left Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield", + "Ganons Castle MQ Spirit Trial Sun Back Left Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield", + "Ganons Castle MQ Spirit Trial Golden Gauntlets Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield", + "Ganons Castle MQ Spirit Trial Sun Back Right Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield" + } + }, + { + "region_name": "Ganons Castle Light Trial", + "dungeon": "Ganons Castle", + "events": { + "Light Trial Clear": " + can_use(Light_Arrows) and Progressive_Hookshot and + (Small_Key_Ganons_Castle, 3)" + }, + "locations": { + "Ganons Castle MQ Light Trial Lullaby Chest": "can_play(Zeldas_Lullaby)" + } + } +] diff --git a/worlds/oot/data/Glitched World/Ganons Castle.json b/worlds/oot/data/Glitched World/Ganons Castle.json new file mode 100644 index 00000000..6c98545e --- /dev/null +++ b/worlds/oot/data/Glitched World/Ganons Castle.json @@ -0,0 +1,115 @@ +[ + { + "region_name": "Ganons Castle Lobby", + "dungeon": "Ganons Castle", + "exits": { + "Ganons Castle Grounds": "True", + "Ganons Castle Forest Trial": "True", + "Ganons Castle Fire Trial": "True", + "Ganons Castle Water Trial": "True", + "Ganons Castle Shadow Trial": "True", + "Ganons Castle Spirit Trial": "True", + "Ganons Castle Light Trial": "can_use(Golden_Gauntlets) or (Bombs and can_shield) or (can_mega and can_use(Hover_Boots))", + "Ganons Castle Tower": "True", + "Ganons Castle Deku Scrubs": "True" + } + }, + { + "region_name": "Ganons Castle Deku Scrubs", + "dungeon": "Ganons Castle", + "locations": { + "Ganons Castle Deku Scrub Center-Left": "True", + "Ganons Castle Deku Scrub Center-Right": "True", + "Ganons Castle Deku Scrub Right": "True", + "Ganons Castle Deku Scrub Left": "True" + } + }, + { + "region_name": "Ganons Castle Forest Trial", + "dungeon": "Ganons Castle", + "events": { + "Forest Trial Clear": "can_use(Light_Arrows) and (Fire_Arrows or Dins_Fire)" + }, + "locations": { + "Ganons Castle Forest Trial Chest": "True" + } + }, + { + "region_name": "Ganons Castle Fire Trial", + "dungeon": "Ganons Castle", + "events": { + "Fire Trial Clear": " + (can_use(Goron_Tunic) or Fairy) and (can_use(Golden_Gauntlets) or can_use(Hover_Boots)) and + can_use(Light_Arrows) and (can_use(Longshot) or (can_mega and can_use(Hover_Boots)))" + } + }, + { + "region_name": "Ganons Castle Water Trial", + "dungeon": "Ganons Castle", + "events": { + "Water Trial Clear": "(Blue_Fire or can_use(Hookshot)) and Megaton_Hammer and can_use(Light_Arrows)" + }, + "locations": { + "Ganons Castle Water Trial Left Chest": "True", + "Ganons Castle Water Trial Right Chest": "True", + "Blue Fire": "has_bottle" + } + }, + { + "region_name": "Ganons Castle Shadow Trial", + "dungeon": "Ganons Castle", + "events": { + "Shadow Trial Clear": " + can_use(Light_Arrows) and Megaton_Hammer and ( + (has_bombchus and can_isg) or + (has_explosives and Hover_Boots and can_shield) or + ( (can_use(Longshot) and (Hover_Boots or can_use(Dins_Fire))) + or can_use(Fire_Arrows) ))" + }, + "locations": { + "Ganons Castle Shadow Trial Front Chest": " + can_use(Fire_Arrows) or can_use(Hookshot) or + Hover_Boots or can_play(Song_of_Time) or can_mega", + "Ganons Castle Shadow Trial Golden Gauntlets Chest": "(has_bombchus and can_isg) or + (has_explosives and Hover_Boots and can_shield) or + ( (can_use(Longshot) and (Hover_Boots or can_use(Dins_Fire))) + or can_use(Fire_Arrows) )" + } + }, + { + "region_name": "Ganons Castle Spirit Trial", + "dungeon": "Ganons Castle", + "events": { + # includes below 2 reqs here + "Spirit Trial Clear": " + can_use(Light_Arrows) and Mirror_Shield and + (has_bombchus or (can_shield and (can_use(Longshot) or Bow)))" + }, + "locations": { + "Ganons Castle Spirit Trial Crystal Switch Chest": "True", + # include req for silver rupees here + "Ganons Castle Spirit Trial Invisible Chest": " + has_bombchus or (can_shield and (can_use(Longshot) or Bow))" + } + }, + { + "region_name": "Ganons Castle Light Trial", + "dungeon": "Ganons Castle", + "events": { + "Light Trial Clear": " + can_use(Light_Arrows) and (Progressive_Hookshot or (has_explosives and can_shield)) and + (Small_Key_Ganons_Castle, 2)" + }, + "locations": { + "Ganons Castle Light Trial First Left Chest": "True", + "Ganons Castle Light Trial Second Left Chest": "True", + "Ganons Castle Light Trial Third Left Chest": "True", + "Ganons Castle Light Trial First Right Chest": "True", + "Ganons Castle Light Trial Second Right Chest": "True", + "Ganons Castle Light Trial Third Right Chest": "True", + "Ganons Castle Light Trial Invisible Enemies Chest": "True", + "Ganons Castle Light Trial Lullaby Chest": " + can_play(Zeldas_Lullaby) and (Small_Key_Ganons_Castle, 1)" + } + } +] diff --git a/worlds/oot/data/Glitched World/Gerudo Training Grounds MQ.json b/worlds/oot/data/Glitched World/Gerudo Training Grounds MQ.json new file mode 100644 index 00000000..388d4b59 --- /dev/null +++ b/worlds/oot/data/Glitched World/Gerudo Training Grounds MQ.json @@ -0,0 +1,79 @@ +[ + { + "region_name": "Gerudo Training Grounds Lobby", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Lobby Left Chest": "True", + "Gerudo Training Grounds MQ Lobby Right Chest": "True", + "Gerudo Training Grounds MQ Hidden Ceiling Chest": "logic_lens_gtg_mq or can_use(Lens_of_Truth)", + "Gerudo Training Grounds MQ Maze Path First Chest": "True", + "Gerudo Training Grounds MQ Maze Path Second Chest": "True", + "Gerudo Training Grounds MQ Maze Path Third Chest": "(Small_Key_Gerudo_Training_Grounds, 1)" + }, + "exits": { + "Gerudo Fortress": "True", + "Gerudo Training Grounds Left Side": "has_fire_source", + "Gerudo Training Grounds Right Side": "Bow" + } + }, + { + "region_name": "Gerudo Training Grounds Right Side", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Dinolfos Chest": "True", + "Gerudo Training Grounds MQ Underwater Silver Rupee Chest": " + (Hover_Boots or at('Gerudo Training Grounds Central Maze Right', can_use(Longshot) or Bow)) and + has_fire_source and Iron_Boots and (logic_fewer_tunic_requirements or can_use(Zora_Tunic)) and + can_take_damage", + "Wall Fairy": "has_bottle and can_use(Bow)" #in the Dinalfos room shoot the Gerudo symbol above the door to the lava room. + } + }, + { + "region_name": "Gerudo Training Grounds Left Side", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ First Iron Knuckle Chest": "True" + }, + "exits": { + "Gerudo Training Grounds Stalfos Room": "can_use(Longshot) or (logic_gtg_mq_with_hookshot and can_use(Hookshot))" + } + }, + { + "region_name": "Gerudo Training Grounds Stalfos Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Before Heavy Block Chest": "True", + "Gerudo Training Grounds MQ Heavy Block Chest": "can_use(Silver_Gauntlets)", + "Blue Fire": "has_bottle" + }, + "exits": { + "Gerudo Training Grounds Back Areas": "can_play(Song_of_Time) and (logic_lens_gtg_mq or can_use(Lens_of_Truth)) and Blue_Fire" + } + }, + { + "region_name": "Gerudo Training Grounds Back Areas", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Eye Statue Chest": "Bow", + "Gerudo Training Grounds MQ Second Iron Knuckle Chest": "True", + "Gerudo Training Grounds MQ Flame Circle Chest": "True" + }, + "exits": { + "Gerudo Training Grounds Central Maze Right": "Megaton_Hammer", + "Gerudo Training Grounds Right Side": "can_use(Longshot)" + } + }, + { + "region_name": "Gerudo Training Grounds Central Maze Right", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Maze Right Central Chest": "True", + "Gerudo Training Grounds MQ Maze Right Side Chest": "True", + "Gerudo Training Grounds MQ Ice Arrows Chest": " + (Small_Key_Gerudo_Training_Grounds, 3)" + }, + "exits": { + "Gerudo Training Grounds Right Side": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Gerudo Training Grounds.json b/worlds/oot/data/Glitched World/Gerudo Training Grounds.json new file mode 100644 index 00000000..793c115b --- /dev/null +++ b/worlds/oot/data/Glitched World/Gerudo Training Grounds.json @@ -0,0 +1,112 @@ +[ + { + "region_name": "Gerudo Training Grounds Lobby", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Lobby Left Chest": "can_use(Bow) or can_use(Slingshot)", + "Gerudo Training Grounds Lobby Right Chest": "can_use(Bow) or can_use(Slingshot)", + "Gerudo Training Grounds Stalfos Chest": "can_jumpslash", + "Gerudo Training Grounds Beamos Chest": "has_explosives and can_jumpslash", + "Wall Fairy": "has_bottle and can_use(Bow)" #in the Beamos room shoot the Gerudo symbol above the door to the lava room. + }, + "exits": { + "Gerudo Training Grounds Heavy Block Room": "True", + "Gerudo Training Grounds Lava Room": " + here(has_explosives and can_jumpslash)", + "Gerudo Training Grounds Central Maze": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Central Maze", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Hidden Ceiling Chest": "(Small_Key_Gerudo_Training_Grounds, 3) + or (can_use(Hookshot) and can_mega) or (is_child and has_explosives and (can_live_dmg(0.5) or can_use(Nayrus_Love)))", + "Gerudo Training Grounds Maze Path First Chest": "(Small_Key_Gerudo_Training_Grounds, 4) + or (can_use(Hookshot) and can_mega) or (is_child and has_explosives and (can_live_dmg(1.0) or can_use(Nayrus_Love)))", + "Gerudo Training Grounds Maze Path Second Chest": "(Small_Key_Gerudo_Training_Grounds, 6) + or (can_use(Hookshot) and can_mega) or (is_child and has_explosives and (can_live_dmg(1.0) or can_use(Nayrus_Love)))", + "Gerudo Training Grounds Maze Path Third Chest": "(Small_Key_Gerudo_Training_Grounds, 7) + or (can_use(Hookshot) and can_mega) or (is_child and has_explosives and (can_live_dmg(0.5) or can_use(Nayrus_Love)))", + "Gerudo Training Grounds Maze Path Final Chest": "(Small_Key_Gerudo_Training_Grounds, 9) + or (can_use(Hookshot) and can_mega) or (is_child and has_explosives and (can_live_dmg(0.5) or can_use(Nayrus_Love)))" + }, + "exits": { + "Gerudo Training Grounds Central Maze Right": "(Small_Key_Gerudo_Training_Grounds, 9) + or (can_use(Hookshot) and can_mega) or (is_child and has_explosives)" + } + }, + { + "region_name": "Gerudo Training Grounds Central Maze Right", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Maze Right Central Chest": "True", + "Gerudo Training Grounds Maze Right Side Chest": "True", + "Gerudo Training Grounds Freestanding Key": "True" + }, + "exits": { + "Gerudo Training Grounds Lava Room": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Lava Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Underwater Silver Rupee Chest": " + can_use(Hookshot) and (can_play(Song_of_Time) or can_mega) and Iron_Boots" + }, + "exits": { + "Gerudo Training Grounds Central Maze Right": "can_play(Song_of_Time) or is_child + or (can_use(Hookshot) and can_use(Hover_Boots) and can_shield and Bombs)", + "Gerudo Training Grounds Hammer Room": "can_use(Hookshot)" + } + }, + { + "region_name": "Gerudo Training Grounds Hammer Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Hammer Room Clear Chest": "True", + "Gerudo Training Grounds Hammer Room Switch Chest": "can_use(Megaton_Hammer) or + can_live_dmg(0.5) or can_use(Nayrus_Love)" + }, + "exits": { + "Gerudo Training Grounds Eye Statue Lower": "can_use(Bow)", + "Gerudo Training Grounds Lava Room": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Eye Statue Lower", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Eye Statue Chest": "can_use(Bow)" + }, + "exits": { + "Gerudo Training Grounds Hammer Room": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Eye Statue Upper", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Near Scarecrow Chest": "can_use(Bow)" + }, + "exits": { + "Gerudo Training Grounds Eye Statue Lower": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Heavy Block Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Before Heavy Block Chest": "True", + "Gerudo Training Grounds Heavy Block First Chest": "can_use(Silver_Gauntlets)", + "Gerudo Training Grounds Heavy Block Second Chest": "can_use(Silver_Gauntlets)", + "Gerudo Training Grounds Heavy Block Third Chest": "can_use(Silver_Gauntlets)", + "Gerudo Training Grounds Heavy Block Fourth Chest": "can_use(Silver_Gauntlets)" + }, + "exits": { + "Gerudo Training Grounds Eye Statue Upper": "can_use(Hookshot) or can_hover or + (is_adult and (Hover_Boots or (can_shield and Bombs)))" + } + } +] diff --git a/worlds/oot/data/Glitched World/Ice Cavern MQ.json b/worlds/oot/data/Glitched World/Ice Cavern MQ.json new file mode 100644 index 00000000..9c5b7456 --- /dev/null +++ b/worlds/oot/data/Glitched World/Ice Cavern MQ.json @@ -0,0 +1,35 @@ +[ + { + "region_name": "Ice Cavern Beginning", + "dungeon": "Ice Cavern", + "exits": { + "Zoras Fountain": "True", + "Ice Cavern": "True" + } + }, + { + "region_name": "Ice Cavern", + "dungeon": "Ice Cavern", + "locations": { + "Blue Fire": "is_adult and has_bottle" + }, + "exits": { + "Ice Cavern Interior": "Blue_Fire" + } + }, + { + "region_name": "Ice Cavern Interior", + "dungeon": "Ice Cavern", + "locations": { + "Ice Cavern MQ Map Chest": "True", + "Ice Cavern MQ Compass Chest": "True", + "Ice Cavern MQ Iron Boots Chest": "True", + "Ice Cavern MQ Freestanding PoH": "has_explosives", + "Sheik in Ice Cavern": "True", + "Ice Cavern MQ GS Red Ice": "can_play(Song_of_Time)", + "Ice Cavern MQ GS Ice Block": "True", + "Ice Cavern MQ GS Scarecrow": " + can_use(Scarecrow) or (Hover_Boots and can_use(Longshot))" + } + } +] diff --git a/worlds/oot/data/Glitched World/Ice Cavern.json b/worlds/oot/data/Glitched World/Ice Cavern.json new file mode 100644 index 00000000..d445a9ec --- /dev/null +++ b/worlds/oot/data/Glitched World/Ice Cavern.json @@ -0,0 +1,31 @@ +[ + { ##Child must be able to hover to get in here so can_hover is always true as child + "region_name": "Ice Cavern Beginning", + "dungeon": "Ice Cavern", + "exits": { + "Ice Cavern": "is_adult or Sticks or can_use(Dins_Fire)" + } + }, + { + "region_name": "Ice Cavern", + "dungeon": "Ice Cavern", + "locations": { + # because child can always hover here, access to this chest is ageless and True + "Ice Cavern Map Chest": "Blue_Fire or (has_explosives and (can_live_dmg(0.5) or can_use(Nayrus_Love)))", + "Ice Cavern Compass Chest": "(is_adult or (is_child and (can_live_dmg(0.5) or can_use(Nayrus_Love)) )) and + (Blue_Fire or (has_explosives and (can_live_dmg(0.5) or can_use(Nayrus_Love)) ))", + "Ice Cavern Freestanding PoH": "(is_adult or (is_child and (can_live_dmg(0.5) or can_use(Nayrus_Love)))) and + (Blue_Fire or (is_adult and Bombs and can_shield and (can_live_dmg(0.5) or can_use(Nayrus_Love))) + or can_use(Boomerang))", + "Ice Cavern Iron Boots Chest": "(can_jumpslash or can_use(Slingshot) or can_use(Dins_Fire)) and (Blue_Fire or (can_use(Hover_Boots) and can_shield) or can_mega)", + "Sheik in Ice Cavern": "(can_jumpslash or can_use(Slingshot) or can_use(Dins_Fire)) and (Blue_Fire or (can_use(Hover_Boots) and can_shield) or can_mega)", + "Ice Cavern GS Spinning Scythe Room": "can_use(Hookshot) or can_use(Boomerang) or + (can_use(Hover_Boots) and can_mega)", + "Ice Cavern GS Heart Piece Room": "(is_adult or (is_child and (can_live_dmg(0.5) or can_use(Nayrus_Love)) )) and + (can_use(Boomerang) or can_use(Hookshot))", + "Ice Cavern GS Push Block Room": "(Blue_Fire or (can_use(Hover_Boots) and can_shield) or (is_adult and can_mega) or (is_child and can_live_dmg(0.5) and has_explosives)) + and (can_use(Hookshot) or can_use(Boomerang) or can_hover)", + "Blue Fire": "has_bottle" + } + } +] diff --git a/worlds/oot/data/Glitched World/Jabu Jabus Belly MQ.json b/worlds/oot/data/Glitched World/Jabu Jabus Belly MQ.json new file mode 100644 index 00000000..a23fbf9f --- /dev/null +++ b/worlds/oot/data/Glitched World/Jabu Jabus Belly MQ.json @@ -0,0 +1,61 @@ +[ + { + "region_name": "Jabu Jabus Belly Beginning", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly MQ Map Chest": "has_explosives", + "Jabu Jabus Belly MQ First Room Side Chest": "Slingshot" + }, + "exits": { + "Zoras Fountain": "True", + "Jabu Jabus Belly Main": "Slingshot" + } + }, + { + "region_name": "Jabu Jabus Belly Main", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly MQ Second Room Lower Chest": "True", + "Jabu Jabus Belly MQ Compass Chest": "True", + "Jabu Jabus Belly MQ Basement Near Vines Chest": "True", + "Jabu Jabus Belly MQ Basement Near Switches Chest": "True", + "Jabu Jabus Belly MQ Boomerang Room Small Chest": "True", + "Jabu Jabus Belly MQ Boomerang Chest": "True", + "Jabu Jabus Belly MQ GS Boomerang Chest Room": " + can_play(Song_of_Time) or (logic_jabu_mq_sot_gs and Boomerang)" + }, + "exits": { + "Jabu Jabus Belly Beginning": "True", + "Jabu Jabus Belly Depths": "has_explosives and Boomerang" + } + }, + { + "region_name": "Jabu Jabus Belly Depths", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly MQ Falling Like Like Room Chest": "True", + "Jabu Jabus Belly MQ GS Tailpasaran Room": "Sticks or can_use(Dins_Fire)", + "Jabu Jabus Belly MQ GS Invisible Enemies Room": "logic_lens_jabu_mq or can_use(Lens_of_Truth)" + }, + "exits": { + "Jabu Jabus Belly Main": "True", + "Jabu Jabus Belly Boss Area": " + Sticks or (Kokiri_Sword and can_use(Dins_Fire))" + } + }, + { + "region_name": "Jabu Jabus Belly Boss Area", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly MQ Cow" : "can_play(Eponas_Song)", + "Jabu Jabus Belly MQ Second Room Upper Chest": "True", + "Jabu Jabus Belly MQ Near Boss Chest": "True", + "Jabu Jabus Belly Barinade Heart": "True", + "Barinade": "True", + "Jabu Jabus Belly MQ GS Near Boss": "True" + }, + "exits": { + "Jabu Jabus Belly Main": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Jabu Jabus Belly.json b/worlds/oot/data/Glitched World/Jabu Jabus Belly.json new file mode 100644 index 00000000..572fa711 --- /dev/null +++ b/worlds/oot/data/Glitched World/Jabu Jabus Belly.json @@ -0,0 +1,49 @@ +[ + { + "region_name": "Jabu Jabus Belly Beginning", + "dungeon": "Jabu Jabus Belly", + "exits": { + "Jabu Jabus Belly Main": "can_use_projectile or can_isg" + } + }, + { + "region_name": "Jabu Jabus Belly Main", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly Boomerang Chest": "True", + "Jabu Jabus Belly GS Water Switch Room": "True", + "Jabu Jabus Belly GS Lobby Basement Lower": "can_use(Boomerang) or can_use(Hookshot) or can_hover", + "Jabu Jabus Belly GS Lobby Basement Upper": "can_use(Boomerang) or can_use(Hookshot) or can_hover", + "Jabu Jabus Belly Deku Scrub": "True" + }, + "exits": { + "Jabu Jabus Belly Beginning": "True", + "Jabu Jabus Belly Depths": "True" + } + }, + { + "region_name": "Jabu Jabus Belly Depths", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly Map Chest": "can_use(Boomerang)", + "Jabu Jabus Belly Compass Chest": "can_use(Boomerang) or Fairy + or (is_adult and (can_live_dmg(0.5) or Hover_Boots) and has_explosives)" + }, + "exits": { + "Jabu Jabus Belly Main": "True", + "Jabu Jabus Belly Boss Area": "can_use(Boomerang) or can_use(Hover_Boots) or can_mega" + } + }, + { + "region_name": "Jabu Jabus Belly Boss Area", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly Barinade Heart": "can_use(Boomerang) and (Sticks or Kokiri_Sword)", + "Barinade": "can_use(Boomerang) and (Sticks or Kokiri_Sword)", + "Jabu Jabus Belly GS Near Boss": "True" + }, + "exits": { + "Jabu Jabus Belly Main": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Overworld.json b/worlds/oot/data/Glitched World/Overworld.json new file mode 100644 index 00000000..056aa9ee --- /dev/null +++ b/worlds/oot/data/Glitched World/Overworld.json @@ -0,0 +1,1334 @@ +[ + { + "region_name": "Root", + "hint": "Link's Pocket", + "locations": { + "Links Pocket": "True" + }, + "exits": { + "Root Exits": "is_starting_age or Time_Travel", + "HC Garden Locations": "skip_child_zelda" + } + }, + { + "region_name": "Root Exits", + "exits": { + "KF Links House": "is_child and (starting_age == 'child' or Time_Travel)", + "Temple of Time": " + (is_adult and (starting_age == 'adult' or Time_Travel)) or + (can_play(Prelude_of_Light) and can_leave_forest)", + "Sacred Forest Meadow": "can_play(Minuet_of_Forest)", + "DMC Central": "can_play(Bolero_of_Fire) and can_leave_forest", + "Lake Hylia": "can_play(Serenade_of_Water) and can_leave_forest", + "Graveyard Warp Pad Region": "can_play(Nocturne_of_Shadow) and can_leave_forest", + "Desert Colossus": "can_play(Requiem_of_Spirit) and can_leave_forest" + } + }, + { + "region_name": "Kokiri Forest", + "hint": "Kokiri Forest", + "events": { + "Showed Mido Sword & Shield": "open_forest == 'open' or (is_child and Kokiri_Sword and Buy_Deku_Shield)" + }, + "locations": { + "KF Kokiri Sword Chest": "is_child", + "KF GS Know It All House": " + is_child and at_night and + (had_night_start or can_leave_forest or can_play(Suns_Song)) and can_child_attack", + "KF GS Bean Patch": " + can_plant_bugs and can_child_attack", + "KF GS House of Twins": " + is_adult and at_night and + (can_use(Hookshot) or can_use(Hover_Boots) or can_isg)", + "KF Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle" + }, + "exits": { + "KF Links House": "True", + "KF Midos House": "True", + "KF Sarias House": "True", + "KF House of Twins": "True", + "KF Know It All House": "True", + "KF Kokiri Shop": "True", + "KF Outside Deku Tree": "'Showed Mido Sword & Shield' or Sticks or is_adult", + "Lost Woods": "True", + "LW Bridge": "can_leave_forest", + "KF Storms Grotto": "can_play(Song_of_Storms)" + } + }, + { + "region_name": "KF Outside Deku Tree", + "hint": "Kokiri Forest", + "locations": { + "Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang", + "Deku Baba Nuts": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword or can_use(Dins_Fire)", + "KF Deku Tree Gossip Stone (Left)": "True", + "KF Deku Tree Gossip Stone (Right)": "True" + }, + "exits": { + #// Adult would technically come from Kokiri Forest, but the transition in both directions is True + "Deku Tree Lobby": "is_child or (is_adult and has_explosives and Hover_Boots)", + "Kokiri Forest": "True" + } + }, + { + "region_name": "KF Links House", + "hint": "Kokiri Forest", + "locations": { + "KF Links House Cow": "is_adult and can_play(Eponas_Song) and 'Links Cow'" + }, + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "KF Midos House", + "locations": { + "KF Midos Top Left Chest": "True", + "KF Midos Top Right Chest": "True", + "KF Midos Bottom Left Chest": "True", + "KF Midos Bottom Right Chest": "True" + } + }, + { + "region_name": "KF Sarias House" + }, + { + "region_name": "KF House of Twins" + }, + { + "region_name": "KF Know It All House" + }, + { + "region_name": "KF Kokiri Shop", + "locations": { + "KF Shop Item 1": "True", + "KF Shop Item 2": "True", + "KF Shop Item 3": "True", + "KF Shop Item 4": "True", + "KF Shop Item 5": "True", + "KF Shop Item 6": "True", + "KF Shop Item 7": "True", + "KF Shop Item 8": "True" + } + }, + { + "region_name": "Lost Woods", + "hint": "the Lost Woods", + "locations": { + "LW Skull Kid": "is_child and can_play(Sarias_Song)", + "LW Ocarina Memory Game": "is_child and Ocarina", + "LW Target in Woods": "can_use(Slingshot)", + "LW Deku Scrub Near Bridge": "is_child and can_stun_deku", + "LW GS Bean Patch Near Bridge": "can_plant_bugs and can_child_attack", + "LW Gossip Stone": "True", + "Bug Shrub": "is_child and can_cut_shrubs and has_bottle" + }, + "exits": { + "Kokiri Forest": "True", + "GC Woods Warp": "True", + "Zora River": "(can_dive or can_jumpslash) and can_leave_forest", + "LW Beyond Mido": "True", + "LW Near Shortcuts Grotto": "can_blast_or_smash" + #//Can Exit to Woods bridge with megaflip, but walking through kokiri forest is true anyway + } + }, + { + "region_name": "LW Beyond Mido", + "hint": "the Lost Woods", + "locations": { + "LW Deku Scrub Near Deku Theater Right": "is_child and can_stun_deku", + "LW Deku Scrub Near Deku Theater Left": "is_child and can_stun_deku", + "LW GS Above Theater": "is_adult and at_night and (here(can_plant_bean) or can_use(Longshot) or (has_bombchus and Progressive_Hookshot) or can_hover)", + "LW GS Bean Patch Near Theater": " + can_plant_bugs and + (can_child_attack or (shuffle_scrubs == 'off' and Buy_Deku_Shield))" + }, + "exits": { + "Lost Woods": "True", + "SFM Entryway": "True", + "Deku Theater": "True", + "LW Scrubs Grotto": "can_blast_or_smash" + } + }, + { + "region_name": "SFM Entryway", + "hint": "Sacred Forest Meadow", + "exits": { + "LW Beyond Mido": "True", + "Sacred Forest Meadow": " + is_adult or Slingshot or Sticks or has_explosives or + Kokiri_Sword or can_use(Dins_Fire)", + "SFM Wolfos Grotto": "can_blast_or_smash" + } + }, + { + "region_name": "Sacred Forest Meadow", + "hint": "Sacred Forest Meadow", + "locations": { + "Song from Saria": "is_child and Zeldas_Letter", + "Sheik in Forest": "is_adult", + "SFM GS": "(can_use(Hookshot) or can_hover) and at_night and is_adult", + "SFM Maze Gossip Stone (Lower)": "True", + "SFM Maze Gossip Stone (Upper)": "True", + "SFM Saria Gossip Stone": "True" + }, + "exits": { + "SFM Entryway": "True", + "Forest Temple Lobby": "can_use(Hookshot) or can_hover", + "SFM Fairy Grotto": "True", + "SFM Storms Grotto": "can_play(Song_of_Storms) and can_stun_deku" + } + }, + { + "region_name": "LW Bridge", + "hint": "the Lost Woods", + "locations": { + "LW Gift from Saria": "True" + }, + "exits": { + "Kokiri Forest": "True", + "Hyrule Field": "True" + } + }, + { + "region_name": "Hyrule Field", + "hint": "Hyrule Field", + "time_passes": true, + "locations": { + "HF Ocarina of Time Item": "is_child and has_all_stones", + "Song from Ocarina of Time": "is_child and has_all_stones", + "Big Poe Kill": "can_use(Bow) and can_ride_epona and has_bottle" + }, + "exits": { + "LW Bridge": "True", + "Lake Hylia": "True", + "Gerudo Valley": "True", + "Market": "True", + "Kakariko Village": "True", + "ZR Front": "True", + "Lon Lon Ranch": "True", + "HF Southeast Grotto": "can_blast_or_smash", + "HF Open Grotto": "True", + "HF Inside Fence Grotto": "can_blast_or_smash", + "HF Cow Grotto": " + (is_child and has_explosives) or (is_adult and (Megaton_Hammer or (has_explosives and can_shield)))", + "HF Near Market Grotto": "can_blast_or_smash", + "HF Fairy Grotto": "can_blast_or_smash", + "HF Near Kak Grotto": "can_blast_or_smash", + "HF Tektite Grotto": "can_blast_or_smash" + } + }, + { + "region_name": "Lake Hylia", + "hint": "Lake Hylia", + "time_passes": true, + "events": { + "Bonooru": "is_child and Ocarina" + }, + "locations": { + "Pierre": "is_adult and Bonooru and not free_scarecrow", + "LH Underwater Item": "is_child and can_dive", + "LH Sun": " + is_adult and + (can_use(Distant_Scarecrow) or 'Water Temple Clear' or can_hover) and can_use(Bow)", + "LH Freestanding PoH": " + is_adult and + (can_use(Scarecrow) or here(can_plant_bean))", + "LH GS Bean Patch": "can_plant_bugs and can_child_attack", + "LH GS Lab Wall": " + is_child and (Boomerang or can_jumpslash) and at_night", + "LH GS Small Island": "is_child and can_child_attack and at_night", + "LH GS Tree": "can_use(Hookshot) and at_night", + "LH Lab Gossip Stone": "True", + "LH Gossip Stone (Southeast)": "True", + "LH Gossip Stone (Southwest)": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle" + }, + "exits": { + "Hyrule Field": "True", + "Zoras Domain": "True", + "LH Lab": "True", + "LH Fishing Hole": " + is_child or can_use(Scarecrow) or here(can_plant_bean) or 'Water Temple Clear' or can_isg", + "Water Temple Lobby": "True", + "LH Grotto": "can_stun_deku" + } + }, + { + "region_name": "LH Lab", + "locations": { + "LH Lab Dive": " + (Progressive_Scale, 2) or + (Iron_Boots and can_use(Hookshot)) or (has_bottle and can_use(Hover_Boots))", + "LH GS Lab Crate": "Iron_Boots and can_use(Hookshot)" + } + }, + { + "region_name": "LH Fishing Hole", + "time_passes": true, + "locations": { + "LH Child Fishing": "is_child", + "LH Adult Fishing": "is_adult" + } + }, + { + "region_name": "Gerudo Valley", + "hint": "Gerudo Valley", + "time_passes": true, + "locations": { + "GV Waterfall Freestanding PoH": "True", + "GV Crate Freestanding PoH": "is_child or can_use(Longshot) or + at('GV Fortress Side', (can_use(Hover_Boots) or can_mega) and (can_live_dmg(0.5) or has_bottle or can_use(Nayrus_Love)))", + "GV GS Small Bridge": "(can_use(Boomerang) or (can_hover and is_child)) and at_night", + "GV GS Bean Patch": "can_plant_bugs and can_child_attack", + "GV Gossip Stone": "True", + "GV Cow": "is_child and can_play(Eponas_Song)" + }, + "exits": { + "Hyrule Field": "True", + "Lake Hylia": "True", + "GV Fortress Side": "( is_child and (can_jumpslash or can_mega) ) + or ( is_adult and (can_ride_epona or can_use(Hookshot) or gerudo_fortress == 'open' or can_mega))" + + } + }, + { + "region_name": "GV Fortress Side", + "hint": "Gerudo Valley", + "time_passes": true, + "locations": { + "GV Chest": "can_use(Megaton_Hammer)", + "GV GS Behind Tent": "can_use(Hookshot) and at_night", + "GV GS Pillar": "can_use(Hookshot) and at_night" + }, + "exits": { + "Gerudo Fortress": "True", + "GV Storms Grotto": "is_adult and can_play(Song_of_Storms)" + } + }, + { + "region_name": "Gerudo Fortress", + "hint": "Gerudo's Fortress", + "events": { + "Carpenter Rescue": "can_finish_GerudoFortress", + "GF Gate Open": "is_adult and Gerudo_Membership_Card" + }, + "locations": { + "GF Chest": "(is_child and can_mega) or + (is_adult and can_use(Hover_Boots) or can_use(Scarecrow) or can_use(Longshot) or can_mega)", + #// known softlock if child opens this chest, so only put it in logic for adult + "GF HBA 1000 Points": " + Gerudo_Membership_Card and can_ride_epona and Bow and is_adult", + "GF HBA 1500 Points": " + Gerudo_Membership_Card and can_ride_epona and Bow and is_adult", + "GF North F1 Carpenter": "is_adult or (is_child and can_child_damage)", + "GF North F2 Carpenter": "is_adult or (is_child and can_child_damage)", + "GF South F1 Carpenter": "is_adult or (is_child and can_child_damage)", + "GF South F2 Carpenter": "is_adult or (is_child and can_child_damage)", + "GF Gerudo Membership Card": "can_finish_GerudoFortress", + "GF GS Archery Range": "can_use(Hookshot) and at_night", + "GF GS Top Floor": "at_night and is_adult" + }, + "exits": { + "Haunted Wasteland": "is_child or 'GF Gate Open' or + ((Progressive_Hookshot and (Hover_Boots or can_mega)) or (can_isg and Bombs) )", + "Gerudo Training Grounds Lobby": "True" + } + }, + { + "region_name": "Haunted Wasteland", + "hint": "Haunted Wasteland", + "locations": { + "Wasteland Chest": "has_fire_source", + "Wasteland Bombchu Salesman": "Progressive_Wallet and can_jumpslash", + "Wasteland GS": "can_use(Boomerang) or (is_adult and (Progressive_Hookshot or (Bombs and can_shield)))" + }, + "exits": { + "Desert Colossus": "True", + "Gerudo Fortress": "is_adult or 'GF Gate Open'" + } + }, + { + "region_name": "Desert Colossus", + "hint": "Desert Colossus", + "time_passes": true, + "locations": { + "Colossus Freestanding PoH": " + (is_adult and here(can_plant_bean)) or + at('Mirror Shield Hand', can_mega) or + at('Silver Gauntlets Hand', can_mega)", + "Sheik at Colossus": "True", + "Colossus GS Bean Patch": "can_plant_bugs and can_child_attack", + "Colossus GS Tree": "can_use(Hookshot) and at_night", + "Colossus GS Hill": "at_night", + "Colossus Gossip Stone": "True" + }, + "exits": { + "Colossus Great Fairy Fountain": "has_explosives or (can_use(Hookshot) and can_use(Hover_Boots))", + "Spirit Temple Lobby": "True", + "Colossus Grotto": "can_use(Silver_Gauntlets)", + "Spirit Temple Outdoor Hands": "can_hover and can_use(Hover_Boots)" + } + }, + { + "region_name": "Colossus Great Fairy Fountain", + "locations": { + "Colossus Great Fairy Reward": "can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "Market", + "hint": "the Market", + "locations": { + "ToT Gossip Stone (Left)": "True", + "ToT Gossip Stone (Left-Center)": "True", + "ToT Gossip Stone (Right)": "True", + "ToT Gossip Stone (Right-Center)": "True" + }, + "exits": { + "Hyrule Field": "True", + "Temple of Time": "True", + "Hyrule Castle Grounds": "is_child", + "Ganons Castle Grounds": "is_adult", + "Market Guard House": "True", + "Market Bazaar": "is_child", + "Market Mask Shop": "is_child", + "Market Shooting Gallery": "is_child", + "Market Bombchu Bowling": "is_child", + "Market Potion Shop": "is_child", + "Market Treasure Chest Game": "is_child", + "Market Bombchu Shop": "is_child", + "Market Dog Lady House": "is_child", + "Market Man in Green House": "is_child" + } + }, + { + "region_name": "Temple of Time", + "hint": "Temple of Time", + "locations": { + "ToT Light Arrows Cutscene": "is_adult and can_trigger_lacs" + }, + "exits": { + "Market": "True", + "Beyond Door of Time": "can_play(Song_of_Time) or open_door_of_time or Hover_Boots" + #// only consider dot skip in logic if adult can get back as well + } + }, + { + "region_name": "Beyond Door of Time", + "hint": "Temple of Time", + "locations": { + "Master Sword Pedestal": "True", + "Sheik at Temple": "Forest_Medallion and is_adult" + }, + "exits": { + "Temple of Time": "True" + } + }, + { + "region_name": "Hyrule Castle Grounds", + "hint": "Hyrule Castle", + "time_passes": true, + "locations": { + "HC Malon Egg": "True", + "HC GS Tree": "can_child_attack", + "HC Malon Gossip Stone": "True", + "HC Rock Wall Gossip Stone": "True" + }, + "exits": { + "Market": "True", + #// garden will logically need weird-egg as letter first can screw over the mask quest + "HC Garden": "Weird_Egg or skip_child_zelda or (not shuffle_weird_egg)", + "HC Great Fairy Fountain": "True", + "HC Storms Grotto": "can_play(Song_of_Storms)" + } + }, + { + "region_name": "HC Garden", + "hint": "Hyrule Castle", + "exits": { + "HC Garden Locations": "True", + "Hyrule Castle Grounds": "True" + } + }, + { + # Directly reachable from Root in "Free Zelda" + "region_name": "HC Garden Locations", + "hint": "Hyrule Castle", + "locations": { + "HC Zeldas Letter": "True", + "Song from Impa": "True" + } + }, + { + "region_name": "HC Great Fairy Fountain", + "locations": { + "HC Great Fairy Reward": "can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "Ganons Castle Grounds", + "hint": "outside Ganon's Castle", + "locations": { + "OGC GS": "True" + }, + "exits": { + "Market": "True", + "OGC Great Fairy Fountain": "can_use(Golden_Gauntlets) or (has_explosives and can_live_dmg(0.5)) or can_use(Hover_Boots)", + "Ganons Castle Lobby": "(can_isg and has_explosives) or can_build_rainbow_bridge" + } + }, + { + "region_name": "OGC Great Fairy Fountain", + "locations": { + "OGC Great Fairy Reward": "can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "Market Guard House", + "events": { + "Sell Big Poe": "is_adult and Bottle_with_Big_Poe" + }, + "locations": { + "Market 10 Big Poes": " + is_adult and + (Big_Poe or (Bottle_with_Big_Poe, big_poe_count))", + "Market GS Guard House": "is_child" + } + }, + { + "region_name": "Market Bazaar", + "locations": { + "Market Bazaar Item 1": "True", + "Market Bazaar Item 2": "True", + "Market Bazaar Item 3": "True", + "Market Bazaar Item 4": "True", + "Market Bazaar Item 5": "True", + "Market Bazaar Item 6": "True", + "Market Bazaar Item 7": "True", + "Market Bazaar Item 8": "True" + } + }, + { + "region_name": "Market Mask Shop", + "events": { + "Skull Mask": "Zeldas_Letter and (complete_mask_quest or at('Kakariko Village', is_child))", + "Mask of Truth": "'Skull Mask' and + (complete_mask_quest or + (at('Lost Woods', is_child and can_play(Sarias_Song)) and + at('Graveyard', is_child and at_day) and + at('Hyrule Field', is_child and has_all_stones)))" + } + }, + { + "region_name": "Market Shooting Gallery", + "locations": { + "Market Shooting Gallery Reward": "True" + } + }, + { + "region_name": "Market Bombchu Bowling", + "locations": { + "Market Bombchu Bowling First Prize": "found_bombchus", + "Market Bombchu Bowling Second Prize": "found_bombchus", + "Market Bombchu Bowling Bombchus": "found_bombchus" + } + }, + { + "region_name": "Market Potion Shop", + "locations": { + "Market Potion Shop Item 1": "True", + "Market Potion Shop Item 2": "True", + "Market Potion Shop Item 3": "True", + "Market Potion Shop Item 4": "True", + "Market Potion Shop Item 5": "True", + "Market Potion Shop Item 6": "True", + "Market Potion Shop Item 7": "True", + "Market Potion Shop Item 8": "True" + } + }, + { + "region_name": "Market Treasure Chest Game", + "locations": { + "Market Treasure Chest Game Reward": "can_use(Lens_of_Truth)" + } + }, + { + "region_name": "Market Bombchu Shop", + "locations": { + "Market Bombchu Shop Item 1": "True", + "Market Bombchu Shop Item 2": "True", + "Market Bombchu Shop Item 3": "True", + "Market Bombchu Shop Item 4": "True", + "Market Bombchu Shop Item 5": "True", + "Market Bombchu Shop Item 6": "True", + "Market Bombchu Shop Item 7": "True", + "Market Bombchu Shop Item 8": "True" + } + }, + { + "region_name": "Market Dog Lady House", + "locations": { + "Market Lost Dog": "True" + } + }, + { + "region_name": "Market Man in Green House" + }, + { + "region_name": "Kakariko Village", + "hint": "Kakariko Village", + "locations": { + "Kak Man on Roof": "True", + "Kak Anju as Adult": "is_adult", + "Kak Anju as Child": "is_child", + "Sheik in Kakariko": " + is_adult and Forest_Medallion and Fire_Medallion and Water_Medallion", + "Kak GS House Under Construction": "is_child and at_night", + "Kak GS Skulltula House": "is_child and at_night", + "Kak GS Guards House": "is_child and at_night", + "Kak GS Tree": "is_child and at_night", + "Kak GS Watchtower": "at_night and + is_child and (Slingshot or has_bombchus or + ( (Sticks or Kokiri_Sword) and + ( can_live_dmg(0.5) or Fairy or can_use(Nayrus_Love) ) ) )", + "Kak GS Above Impas House": "can_use(Hookshot) and at_night", + "Bug Rock": "has_bottle" + }, + "exits": { + "Hyrule Field": "True", + "Kak Carpenter Boss House": "True", + "Kak House of Skulltula": "True", + "Kak Impas House": "True", + "Kak Impas House Back": "True", + "Kak Windmill": "True", + "Kak Bazaar": "is_adult or (is_child and can_jumpslash)", + "Kak Shooting Gallery": "is_adult", + "Bottom of the Well": "(is_child and ('Drain Well' or can_jumpslash or can_isg or Nuts)) + or (is_adult and has_explosives)", + "Kak Potion Shop Front": "is_adult", + "Kak Potion Shop Back": "is_adult", + "Kak Odd Medicine Building": "is_adult", + "Kak Redead Grotto": " + can_blast_or_smash and + (is_adult or + (Sticks or Kokiri_Sword or can_use(Dins_Fire)))", + "Kak Open Grotto": "True", + "Graveyard": "True", + "Death Mountain": "Zeldas_Letter or is_adult or open_kakariko == 'open' or can_hover" + } + }, + { + "region_name": "Kak Carpenter Boss House" + }, + { + "region_name": "Kak House of Skulltula", + "locations": { + "Kak 10 Gold Skulltula Reward": "(Gold_Skulltula_Token, 10)", + "Kak 20 Gold Skulltula Reward": "(Gold_Skulltula_Token, 20)", + "Kak 30 Gold Skulltula Reward": "(Gold_Skulltula_Token, 30)", + "Kak 40 Gold Skulltula Reward": "(Gold_Skulltula_Token, 40)", + "Kak 50 Gold Skulltula Reward": "(Gold_Skulltula_Token, 50)" + } + }, + { + "region_name": "Kak Impas House" + }, + { + "region_name": "Kak Impas House Back", + "locations": { + "Kak Impas House Freestanding PoH": "True", + "Kak Impas House Cow": "can_play(Eponas_Song)" + } + }, + { + "region_name": "Kak Windmill", + "hint": "Kakariko Village", + "events": { + "Drain Well": "is_child and can_play(Song_of_Storms)" + }, + "locations": { + "Kak Windmill Freestanding PoH": "is_adult or can_use(Boomerang)", + "Song from Windmill": "is_adult and Ocarina" + } + }, + { + "region_name": "Kak Bazaar", + "locations": { + "Kak Bazaar Item 1": "True", + "Kak Bazaar Item 2": "True", + "Kak Bazaar Item 3": "True", + "Kak Bazaar Item 4": "True", + "Kak Bazaar Item 5": "True", + "Kak Bazaar Item 6": "True", + "Kak Bazaar Item 7": "True", + "Kak Bazaar Item 8": "True" + } + }, + { + "region_name": "Kak Shooting Gallery", + "locations": { + "Kak Shooting Gallery Reward": "can_use(Bow)" + } + }, + { + "region_name": "Kak Potion Shop Front", + "hint": "Kakariko Village", + "locations": { + "Kak Potion Shop Item 1": "True", + "Kak Potion Shop Item 2": "True", + "Kak Potion Shop Item 3": "True", + "Kak Potion Shop Item 4": "True", + "Kak Potion Shop Item 5": "True", + "Kak Potion Shop Item 6": "True", + "Kak Potion Shop Item 7": "True", + "Kak Potion Shop Item 8": "True" + } + }, + { + "region_name": "Kak Potion Shop Back" + }, + { + "region_name": "Kak Odd Medicine Building" + }, + { + "region_name": "Graveyard", + "hint": "the Graveyard", + "locations": { + "Graveyard Freestanding PoH": " + (is_adult and here(can_plant_bean)) or + can_use(Hookshot) or can_hover", + "Graveyard Dampe Gravedigging Tour": "is_child", + "Graveyard GS Wall": "(can_use(Boomerang) or (can_hover and is_child)) and at_night", + "Graveyard GS Bean Patch": "can_plant_bugs and can_child_attack" + }, + "exits": { + "Graveyard Shield Grave": "True", + "Graveyard Composers Grave": "can_play(Zeldas_Lullaby) or at('Graveyard Warp Pad Region', True)", + "Graveyard Heart Piece Grave": "True", + "Graveyard Dampes Grave": "is_adult or at('Graveyard Warp Pad Region', True)", + "Graveyard Dampes House": "True", + "Kakariko Village": "True", + "Graveyard Warp Pad Region": "can_hover or can_use(Hookshot)" + } + }, + { + "region_name": "Graveyard Shield Grave", + "locations": { + "Graveyard Shield Grave Chest": "True" + } + }, + { + "region_name": "Graveyard Heart Piece Grave", + "locations": { + "Graveyard Heart Piece Grave Chest": "can_play(Suns_Song)" + } + }, + { + "region_name": "Graveyard Composers Grave", + "locations": { + "Graveyard Composers Grave Chest": "has_fire_source or (is_child and Sticks and (can_live_dmg(0.75) or can_use(Nayrus_Love)))", + "Song from Composers Grave": " + is_adult or + (Slingshot or Boomerang or Sticks or + has_explosives or Kokiri_Sword)" + } + }, + { + "region_name": "Graveyard Dampes Grave", + "hint": "the Graveyard", + "locations": { + "Graveyard Hookshot Chest": "True", + "Graveyard Dampe Race Freestanding PoH": "True", + "Nut Pot": "True" + } + }, + { + "region_name": "Graveyard Dampes House" + }, + { + "region_name": "Graveyard Warp Pad Region", + "hint": "the Graveyard", + "locations": { + "Graveyard Gossip Stone": "True" + }, + "exits": { + "Graveyard": "True", + "Shadow Temple Entryway": "can_use(Dins_Fire) or is_adult" + } + }, + { + "region_name": "Death Mountain", + "hint": "Death Mountain Trail", + "time_passes": true, + "locations": { + "DMT Chest": " + can_blast_or_smash or can_jumpslash or + (is_child and Progressive_Strength_Upgrade)", + "DMT Freestanding PoH": " + is_child or can_live_dmg(0.5) or + can_use(Nayrus_Love) or Fairy or Hover_Boots", + "DMT GS Bean Patch": " + can_plant_bugs and (has_explosives or Progressive_Strength_Upgrade)", + "DMT GS Near Kak": "can_blast_or_smash", + "DMT GS Falling Rocks Path": "at_night and is_adult", + "DMT GS Above Dodongos Cavern": "(can_use(Megaton_Hammer) or can_use(Hookshot)) and at_night" + }, + "exits": { + "Kakariko Village": "True", + "Goron City": "True", + "Death Mountain Summit": "here(can_blast_or_smash) or (is_child and can_isg) or can_use(Hookshot)", + "Dodongos Cavern Entryway": " + has_explosives or Progressive_Strength_Upgrade or is_adult", + "DMT Cow Grotto": "can_blast_or_smash", + "DMT Storms Grotto": "can_play(Song_of_Storms)" + } + }, + { + "region_name": "Death Mountain Summit", + "hint": "Death Mountain Trail", + "time_passes": true, + "locations": { + "DMT Biggoron": " + is_adult and + (Claim_Check or ( + at('DMC Upper', is_adult) and + at('Zoras Domain', is_adult) and ( + Eyedrops or Eyeball_Frog or Prescription or Broken_Sword or + at('GV Fortress Side', is_adult and ( + Poachers_Saw or Odd_Mushroom or Cojiro or Pocket_Cucco or Pocket_Egg)))))", + "DMT Gossip Stone": "True" + }, + "exits": { + "Death Mountain": "True", + "DMC Upper": "True", + "DMT Great Fairy Fountain": "here(can_blast_or_smash) or can_isg" + } + }, + { + "region_name": "Dodongos Cavern Entryway", + "exits": { + "Dodongos Cavern Beginning": "True", + "Death Mountain": "True" + } + }, + { + "region_name": "Goron City", + "hint": "Goron City", + "events": { + "GC Woods Warp Open": " + can_blast_or_smash or can_use(Dins_Fire) or can_use(Bow) or Progressive_Strength_Upgrade" + }, + "locations": { + "GC Maze Left Chest": " + can_use(Megaton_Hammer) or can_use(Silver_Gauntlets) or ((Progressive_Strength_Upgrade or has_explosives) and can_shield) + or (has_explosives and can_use(Hover_Boots))", + "GC Maze Center Chest": " + can_blast_or_smash or can_use(Silver_Gauntlets) or (Progressive_Strength_Upgrade and can_shield)", + "GC Maze Right Chest": " + can_blast_or_smash or can_use(Silver_Gauntlets) or (Progressive_Strength_Upgrade and can_shield)", + "GC Pot Freestanding PoH": " + is_child and + (has_explosives or Progressive_Strength_Upgrade) and + (( (can_play(Zeldas_Lullaby) or can_shield) and Sticks) or can_use(Dins_Fire))", + "GC Rolling Goron as Child": " + is_child and + (has_explosives or Progressive_Strength_Upgrade)", + "GC Rolling Goron as Adult": " + is_adult and + (Progressive_Strength_Upgrade or has_explosives or Bow or can_use(Dins_Fire) or Blue_Fire)", + "GC Medigoron": " + is_adult and Progressive_Wallet and + (can_blast_or_smash or Progressive_Strength_Upgrade or Blue_Fire)", + "GC GS Boulder Maze": "is_child and has_explosives", + "GC GS Center Platform": "is_adult", + "GC Maze Gossip Stone": " + can_blast_or_smash or can_use(Silver_Gauntlets) or (Progressive_Strength_Upgrade and can_shield)", + "GC Medigoron Gossip Stone": " + can_blast_or_smash or Progressive_Strength_Upgrade or Blue_Fire", + "Stick Pot": "is_child" + }, + "exits": { + "Death Mountain": "True", + "GC Woods Warp": "'GC Woods Warp Open'", + "GC Shop": " + has_explosives or Progressive_Strength_Upgrade or can_use(Bow) or + (is_child and (can_use(Dins_Fire) or (can_play(Zeldas_Lullaby) and Sticks)))", + "GC Darunias Chamber": " + (is_child and (can_play(Zeldas_Lullaby) or ((Progressive_Strength_Upgrade or has_explosives) and can_shield))) or + (is_adult and (Progressive_Strength_Upgrade or has_explosives or Bow))", + "GC Grotto": "can_hover or ( + is_adult and + ( (can_play(Song_of_Time) and + (can_live_dmg(1) or can_use(Goron_Tunic) or can_use(Longshot) or can_use(Nayrus_Love)) ) or + ((can_live_dmg(0.5) or can_use(Goron_Tunic)) and can_use(Hookshot)) or + ((can_use(Nayrus_Love) or can_use(Goron_Tunic)) and can_use(Hookshot))))" + } + }, + { + "region_name": "GC Woods Warp", + "events": { + "GC Woods Warp Open": "can_blast_or_smash or can_use(Dins_Fire)" + }, + "exits": { + "Goron City": "can_leave_forest and 'GC Woods Warp Open'", + "Lost Woods": "True" + } + }, + + { + "region_name": "GC Darunias Chamber", + "hint": "Goron City", + "events": { + "GC Woods Warp Open": "is_child and Sticks" + }, + "locations": { + "GC Darunias Joy": "is_child and can_play(Sarias_Song)" + }, + "exits": { + "Goron City": "True", + "DMC Lower": "is_adult or + (is_child and + (can_mega or (can_live_dmg(0.5) and has_explosives) or can_shield))" + } + }, + { + "region_name": "GC Shop", + "locations": { + "GC Shop Item 1": "True", + "GC Shop Item 2": "True", + "GC Shop Item 3": "True", + "GC Shop Item 4": "True", + "GC Shop Item 5": "True", + "GC Shop Item 6": "True", + "GC Shop Item 7": "True", + "GC Shop Item 8": "True" + } + }, + { + "region_name": "DMC Upper", + "hint": "Death Mountain Crater", + "locations": { + "DMC Wall Freestanding PoH": "True", + "DMC GS Crate": " + is_child and can_child_attack", + "DMC Deku Scrub": " + is_child and can_stun_deku", + "DMC Gossip Stone": "has_explosives" + }, + "exits": { + "Death Mountain Summit": "True", + "DMC Lower": "can_use(Hover_Boots) or can_mega", + "DMC Central": "(is_child and can_mega and (can_live_dmg(1) or Fairy or can_use(Nayrus_Love)) and Hylian_Shield) or + (is_adult and can_use(Goron_Tunic) and (can_use(Distant_Scarecrow) or can_mega) and + (can_live_dmg(1) or Fairy or can_use(Nayrus_Love)))", + "DMC Upper Grotto": "here(can_blast_or_smash)" + } + }, + { + "region_name": "DMC Lower", + "hint": "Death Mountain Crater", + "exits": { + "GC Darunias Chamber": "True", + "DMC Great Fairy Fountain": "can_use(Megaton_Hammer) or can_mega or is_child", + "DMC Central": " + can_use(Hover_Boots) or can_use(Hookshot) or can_mega", + "DMC Upper": "True", + "DMC Hammer Grotto": "can_use(Megaton_Hammer) or (can_mega and (can_use(Hookshot) or can_use(Bow)))" + } + }, + { + "region_name": "DMC Central", + "hint": "Death Mountain Crater", + "locations": { + "DMC Volcano Freestanding PoH": " + (is_adult and here(can_plant_bean)) or + can_use(Hover_Boots) or can_mega", + "Sheik in Crater": "is_adult", + "DMC GS Bean Patch": "can_plant_bugs and can_child_attack" + }, + "exits": { + "DMC Lower": " + (is_adult and here(can_plant_bean)) or + can_use(Hover_Boots) or can_use(Hookshot)", + "Fire Temple Lower": "is_adult" + } + }, + { + "region_name": "DMC Great Fairy Fountain", + "locations": { + "DMC Great Fairy Reward": "can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "DMT Great Fairy Fountain", + "locations": { + "DMT Great Fairy Reward": "can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "ZR Front", + "hint": "Zora's River", + "time_passes": true, + "locations": { + "ZR GS Tree": "is_child and can_child_attack" + }, + "exits": { + "Zora River": "is_adult or has_explosives", + "Hyrule Field": "True" + } + }, + { + "region_name": "Zora River", + "hint": "Zora's River", + "time_passes": true, + "locations": { + "ZR Magic Bean Salesman": "is_child", + "ZR Frogs Ocarina Game": " + is_child and can_play(Zeldas_Lullaby) and can_play(Sarias_Song) and + can_play(Suns_Song) and can_play(Eponas_Song) and + can_play(Song_of_Time) and can_play(Song_of_Storms)", + "ZR Frogs in the Rain": "is_child and can_play(Song_of_Storms)", + "ZR Near Open Grotto Freestanding PoH": "True", + "ZR Near Domain Freestanding PoH": "True", + "ZR GS Ladder": "is_child and at_night and can_child_attack", + "ZR GS Near Raised Grottos": "is_adult and (Progressive_Hookshot or can_hover) and at_night", + "ZR GS Above Bridge": "can_use(Hookshot) and at_night", + "ZR Near Grottos Gossip Stone": "True", + "ZR Near Domain Gossip Stone": "True" + }, + "exits": { + "ZR Front": "True", + "ZR Open Grotto": "True", + "ZR Fairy Grotto": "can_blast_or_smash", + "Lost Woods": "can_dive or can_use(Iron_Boots) or (is_child and (can_isg or Nuts)) or can_mega", + "ZR Storms Grotto": "can_play(Song_of_Storms) and can_stun_deku", + "Zoras Domain": "can_play(Zeldas_Lullaby) or can_mega or can_use(Hover_Boots) or is_child" + } + }, + { + "region_name": "Zoras Domain", + "hint": "Zora's Domain", + "locations": { + "ZD Diving Minigame": "is_child", + "ZD Chest": "can_use(Sticks)", + "Deliver Rutos Letter": "(is_child and Rutos_Letter) and zora_fountain != 'open'", + "ZD King Zora Thawed": "is_adult", + "ZD GS Frozen Waterfall": " + is_adult and at_night and (Progressive_Hookshot or Bow or Magic_Meter or has_explosives or + Biggoron_Sword or + at('Goron City', is_adult and Progressive_Wallet and (can_blast_or_smash or Progressive_Strength_Upgrade or Blue_Fire)))", + "ZD Gossip Stone": "True", + "Fish Group": "is_child and has_bottle", + "Stick Pot": "is_child", + "Nut Pot": "True" + }, + "exits": { + "Zora River": "True", + "Lake Hylia": "True", + "Zoras Fountain": "zora_fountain == 'open' or Deliver_Letter + or is_adult or (can_shield and has_bombchus)", + "ZD Shop": "True" + } + }, + { + "region_name": "Zoras Fountain", + "hint": "Zora's Fountain", + "locations": { + "ZF Iceberg Freestanding PoH": "is_adult", + "ZF Bottom Freestanding PoH": "is_adult and Iron_Boots", + "ZF GS Tree": "is_child", + "ZF GS Above the Log": "(can_use(Boomerang) or (can_hover and is_child)) and at_night", + "ZF GS Hidden Cave": "at_night and + ( + ((can_use(Silver_Gauntlets) and can_blast_or_smash) or (has_explosives and can_shield and (can_use(Bow) or can_use(Hookshot)))) + or (has_explosives and can_shield) + ) and (can_use(Hookshot) or can_hover)", + "ZF Fairy Gossip Stone": "True", + "ZF Jabu Gossip Stone": "True" + }, + "exits": { + "Zoras Domain": "True", + "Jabu Jabus Belly Beginning": "(is_child and (can_jumpslash or Fish)) or + (is_adult and Hover_Boots and has_bombchus and can_shield)", + "Ice Cavern": "is_adult or (is_child and can_hover)", + "ZF Great Fairy Fountain": "has_explosives or can_use(Hookshot)" + } + }, + { + "region_name": "ZD Shop", + "locations": { + "ZD Shop Item 1": "True", + "ZD Shop Item 2": "True", + "ZD Shop Item 3": "True", + "ZD Shop Item 4": "True", + "ZD Shop Item 5": "True", + "ZD Shop Item 6": "True", + "ZD Shop Item 7": "True", + "ZD Shop Item 8": "True" + } + }, + { + "region_name": "ZF Great Fairy Fountain", + "locations": { + "ZF Great Fairy Reward": "can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "Lon Lon Ranch", + "hint": "Lon Lon Ranch", + "events": { + "Epona": "(can_play(Eponas_Song) or can_hover) and is_adult", + "Links Cow": "(can_play(Eponas_Song) or can_hover) and is_adult" + }, + "locations": { + "Song from Malon": "is_child and Zeldas_Letter and Ocarina", + "LLR GS Tree": "is_child", + "LLR GS Rain Shed": "is_child and at_night", + "LLR GS House Window": "can_use(Boomerang) and at_night", + "LLR GS Back Wall": "can_use(Boomerang) and at_night" + }, + "exits": { + "Hyrule Field": "True", + "LLR Talons House": "True", + "LLR Stables": "True", + "LLR Tower": "True", + "LLR Grotto": "is_child and can_stun_deku" + } + }, + { + "region_name": "LLR Talons House", + "locations": { + "LLR Talons Chickens": "is_child and Zeldas_Letter" + } + }, + { + "region_name": "LLR Stables", + "locations": { + "LLR Stables Left Cow": "can_play(Eponas_Song)", + "LLR Stables Right Cow": "can_play(Eponas_Song)" + } + }, + { + "region_name": "LLR Tower", + "locations": { + "LLR Freestanding PoH": "True", + "LLR Tower Left Cow": "can_play(Eponas_Song)", + "LLR Tower Right Cow": "can_play(Eponas_Song)" + } + }, + { + "region_name": "Ganons Castle Tower", + "dungeon": "Ganons Castle", + "locations": { + "Ganons Tower Boss Key Chest": "True", + "Ganondorf Hint": "Boss_Key_Ganons_Castle", + "Ganon": "Boss_Key_Ganons_Castle and can_use(Light_Arrows)" + } + }, + { + "region_name": "KF Storms Grotto", + "locations": { + "KF Storms Grotto Chest": "True", + "KF Storms Grotto Gossip Stone": "True" + } + }, + { + "region_name": "LW Near Shortcuts Grotto", + "locations": { + "LW Near Shortcuts Grotto Chest": "True", + "LW Near Shortcuts Grotto Gossip Stone": "True" + } + }, + { + "region_name": "Deku Theater", + "locations": { + "Deku Theater Skull Mask": "is_child and 'Skull Mask'", + "Deku Theater Mask of Truth": "is_child and 'Mask of Truth'" + } + }, + { + "region_name": "LW Scrubs Grotto", + "locations": { + "LW Deku Scrub Grotto Rear": "True", + "LW Deku Scrub Grotto Front": "True" + } + }, + { + "region_name": "SFM Fairy Grotto", + "locations": { + "Free Fairies": "has_bottle" + } + }, + { + "region_name": "SFM Storms Grotto", + "locations": { + "SFM Deku Scrub Grotto Rear": "True", + "SFM Deku Scrub Grotto Front": "True" + } + }, + { + "region_name": "SFM Wolfos Grotto", + "locations": { + "SFM Wolfos Grotto Chest": "True" + } + }, + { + "region_name": "LLR Grotto", + "locations": { + "LLR Deku Scrub Grotto Left": "True", + "LLR Deku Scrub Grotto Right": "True", + "LLR Deku Scrub Grotto Center": "True" + } + }, + { + "region_name": "HF Southeast Grotto", + "locations": { + "HF Southeast Grotto Chest": "True", + "HF Southeast Grotto Gossip Stone": "True" + } + }, + { + "region_name": "HF Open Grotto", + "locations": { + "HF Open Grotto Chest": "True", + "HF Open Grotto Gossip Stone": "True" + } + }, + { + "region_name": "HF Inside Fence Grotto", + "locations": { + "HF Deku Scrub Grotto": "can_stun_deku" + } + }, + { + "region_name": "HF Cow Grotto", + "locations": { + "HF GS Cow Grotto": " + has_fire_source and (can_use(Hookshot) or can_use(Boomerang))", + "HF Cow Grotto Cow": "has_fire_source and can_play(Eponas_Song)", + "HF Cow Grotto Gossip Stone": "has_fire_source" + } + }, + { + "region_name": "HF Near Market Grotto", + "locations": { + "HF Near Market Grotto Chest": "True", + "HF Near Market Grotto Gossip Stone": "True" + } + }, + { + "region_name": "HF Fairy Grotto" + }, + { + "region_name": "HF Near Kak Grotto", + "locations": { + "HF GS Near Kak Grotto": "can_use(Boomerang) or can_use(Hookshot)" + } + }, + { + "region_name": "HF Tektite Grotto", + "locations": { + "HF Tektite Grotto Freestanding PoH": " + (Progressive_Scale, 2) or can_use(Iron_Boots)" + } + }, + { + "region_name": "HC Storms Grotto", + "locations": { + "HC GS Storms Grotto": "(can_use(Boomerang) or can_isg) and (has_explosives or Blue_Fire)", + "HC Storms Grotto Gossip Stone": "has_explosives or Blue_Fire" + } + }, + { + "region_name": "Kak Redead Grotto", + "locations": { + "Kak Redead Grotto Chest": "True" + } + }, + { + "region_name": "Kak Open Grotto", + "locations": { + "Kak Open Grotto Chest": "True", + "Kak Open Grotto Gossip Stone": "True" + } + }, + { + "region_name": "DMT Cow Grotto", + "locations": { + "DMT Cow Grotto Cow": "can_play(Eponas_Song)" + } + }, + { + "region_name": "DMT Storms Grotto", + "locations": { + "DMT Storms Grotto Chest": "True", + "DMT Storms Grotto Gossip Stone": "True" + } + }, + { + "region_name": "GC Grotto", + "locations": { + "GC Deku Scrub Grotto Left": "True", + "GC Deku Scrub Grotto Right": "True", + "GC Deku Scrub Grotto Center": "True" + } + }, + { + "region_name": "DMC Upper Grotto", + "locations": { + "DMC Upper Grotto Chest": "True", + "DMC Upper Grotto Gossip Stone": "True" + } + }, + { + "region_name": "DMC Hammer Grotto", + "locations": { + "DMC Deku Scrub Grotto Left": "True", + "DMC Deku Scrub Grotto Right": "True", + "DMC Deku Scrub Grotto Center": "True" + } + }, + { + "region_name": "ZR Open Grotto", + "locations": { + "ZR Open Grotto Chest": "True", + "ZR Open Grotto Gossip Stone": "True" + } + }, + { + "region_name": "ZR Fairy Grotto" + }, + { + "region_name": "ZR Storms Grotto", + "locations": { + "ZR Deku Scrub Grotto Rear": "True", + "ZR Deku Scrub Grotto Front": "True" + } + }, + { + "region_name": "LH Grotto", + "locations": { + "LH Deku Scrub Grotto Left": "True", + "LH Deku Scrub Grotto Right": "True", + "LH Deku Scrub Grotto Center": "True" + } + }, + { + "region_name": "Colossus Grotto", + "locations": { + "Colossus Deku Scrub Grotto Rear": "True", + "Colossus Deku Scrub Grotto Front": "True" + } + }, + { + "region_name": "GV Storms Grotto", + "locations": { + "GV Deku Scrub Grotto Rear": "True", + "GV Deku Scrub Grotto Front": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Shadow Temple MQ.json b/worlds/oot/data/Glitched World/Shadow Temple MQ.json new file mode 100644 index 00000000..6033e1c3 --- /dev/null +++ b/worlds/oot/data/Glitched World/Shadow Temple MQ.json @@ -0,0 +1,99 @@ +[ + { + "region_name": "Shadow Temple Entryway", + "dungeon": "Shadow Temple", + "exits": { + "Shadow Temple Beginning": " + (logic_lens_shadow_mq or can_use(Lens_of_Truth)) and + (can_use(Hover_Boots) or can_use(Hookshot))" + } + }, + { + "region_name": "Shadow Temple Beginning", + "dungeon": "Shadow Temple", + "exits": { + "Shadow Temple Entryway": "True", + "Shadow Temple First Beamos": "can_use(Fire_Arrows) or Hover_Boots", + "Shadow Temple Dead Hand Area": "has_explosives and (Small_Key_Shadow_Temple, 6)" + } + }, + { + "region_name": "Shadow Temple Dead Hand Area", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Compass Chest": "True", + "Shadow Temple MQ Hover Boots Chest": "can_play(Song_of_Time) and Bow" + } + }, + { + "region_name": "Shadow Temple First Beamos", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Map Chest": "True", + "Shadow Temple MQ Early Gibdos Chest": "True", + "Shadow Temple MQ Near Ship Invisible Chest": "True" + }, + "exits": { + "Shadow Temple Huge Pit": "has_explosives and (Small_Key_Shadow_Temple, 2)" + } + }, + { + "region_name": "Shadow Temple Huge Pit", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Invisible Blades Visible Chest": "can_play(Song_of_Time)", + "Shadow Temple MQ Invisible Blades Invisible Chest": "can_play(Song_of_Time)", + "Shadow Temple MQ Beamos Silver Rupees Chest": "can_use(Longshot)", + "Shadow Temple MQ Falling Spikes Lower Chest": "True", + "Shadow Temple MQ Falling Spikes Upper Chest": "Progressive_Strength_Upgrade", + "Shadow Temple MQ Falling Spikes Switch Chest": "Progressive_Strength_Upgrade", + "Shadow Temple MQ Invisible Spikes Chest": "Hover_Boots and (Small_Key_Shadow_Temple, 3)", + "Shadow Temple MQ Stalfos Room Chest": " + Hover_Boots and (Small_Key_Shadow_Temple, 3) and Progressive_Hookshot", + "Shadow Temple MQ GS Falling Spikes Room": "Progressive_Hookshot" + }, + "exits": { + "Shadow Temple Wind Tunnel": " + Hover_Boots and Progressive_Hookshot and (Small_Key_Shadow_Temple, 4)" + } + }, + { + "region_name": "Shadow Temple Wind Tunnel", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Wind Hint Chest": "True", + "Shadow Temple MQ After Wind Enemy Chest": "True", + "Shadow Temple MQ After Wind Hidden Chest": "True", + "Shadow Temple MQ GS Wind Hint Room": "True", + "Shadow Temple MQ GS After Wind": "True" + }, + "exits": { + "Shadow Temple Beyond Boat": " + can_play(Zeldas_Lullaby) and (Small_Key_Shadow_Temple, 5)" + } + }, + { + "region_name": "Shadow Temple Beyond Boat", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Bongo Bongo Heart": "Bow and Boss_Key_Shadow_Temple", + "Bongo Bongo": "Bow and Boss_Key_Shadow_Temple", + "Shadow Temple MQ GS After Ship": "True", + "Shadow Temple MQ GS Near Boss": "Bow" + }, + "exits": { + "Shadow Temple Invisible Maze": " + Bow and can_play(Song_of_Time) and can_use(Longshot)" + } + }, + { + "region_name": "Shadow Temple Invisible Maze", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Spike Walls Left Chest": "(Small_Key_Shadow_Temple, 6)", + "Shadow Temple MQ Boss Key Chest": "(Small_Key_Shadow_Temple, 6)", + "Shadow Temple MQ Bomb Flower Chest": "True", + "Shadow Temple MQ Freestanding Key": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Shadow Temple.json b/worlds/oot/data/Glitched World/Shadow Temple.json new file mode 100644 index 00000000..2d9985f3 --- /dev/null +++ b/worlds/oot/data/Glitched World/Shadow Temple.json @@ -0,0 +1,108 @@ +[ + { + "region_name": "Shadow Temple Entryway", + "dungeon": "Shadow Temple", + "exits": { + "Shadow Temple Beginning": "can_use(Hover_Boots) or can_use(Hookshot) or can_mega" + } + }, + { + "region_name": "Shadow Temple Beginning", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Map Chest": "can_jumpslash or (can_use(Dins_Fire) and has_projectile(child))", + "Shadow Temple Hover Boots Chest": "can_jumpslash" + }, + "exits": { + "Shadow Temple Entryway": "True", + "Shadow Temple First Beamos": "can_use(Hover_Boots) or can_mega", + "Shadow Boss": "can_hover and has_explosives and can_use(Hover_Boots) and + can_live_dmg(2.0)" + } + }, + { + "region_name": "Shadow Temple First Beamos", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Compass Chest": "can_jumpslash or can_use(Dins_Fire)", + "Shadow Temple Early Silver Rupee Chest": "is_adult or (is_child and can_hover)" + }, + "exits": { + "Shadow Temple Huge Pit": "has_explosives and (Small_Key_Shadow_Temple, 5)", + "Shadow Temple Boat": "can_jumpslash" + } + }, + { + "region_name": "Shadow Temple Huge Pit", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Invisible Blades Visible Chest": "can_jumpslash or Slingshot", + "Shadow Temple Invisible Blades Invisible Chest": "can_jumpslash or Slingshot", + "Shadow Temple Falling Spikes Lower Chest": "True", + "Shadow Temple Falling Spikes Upper Chest": "is_adult or can_hover", + "Shadow Temple Falling Spikes Switch Chest": "is_adult or can_hover", + "Shadow Temple Invisible Spikes Chest": "(Small_Key_Shadow_Temple, 5) and (can_jumpslash or can_use(Dins_Fire))", + "Shadow Temple Freestanding Key": " + (Small_Key_Shadow_Temple, 5) and (can_use(Hookshot) or can_hover) + and (Progressive_Strength_Upgrade or has_explosives)", + "Shadow Temple GS Like Like Room": "is_adult or can_use(Boomerang) or can_hover", + "Shadow Temple GS Falling Spikes Room": "can_use(Hookshot) or (is_adult and can_mega) or (is_child and can_hover)", + "Shadow Temple GS Single Giant Pot": "(Small_Key_Shadow_Temple, 5) and (can_use(Hookshot) or can_hover)" + }, + "exits": { + "Shadow Temple Wind Tunnel": "(can_use(Hookshot) or can_hover) and (Small_Key_Shadow_Temple, 5)" + } + }, + { + "region_name": "Shadow Temple Wind Tunnel", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Wind Hint Chest": "can_jumpslash or can_use(Dins_Fire)", + "Shadow Temple After Wind Enemy Chest": "can_jumpslash or can_use(Dins_Fire)", + "Shadow Temple After Wind Hidden Chest": "has_explosives" + }, + "exits": { + "Shadow Temple Boat": "(Small_Key_Shadow_Temple, 5)", + "Shadow Temple Huge Pit": "can_hover" + } + }, + { + "region_name": "Shadow Temple Boat", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple GS Near Ship": "can_use(Longshot) or (can_use(Hover_Boots) and can_mega) + or (is_child and can_hover)" + }, + "exits": { + "Shadow Temple Wind Tunnel": "(Small_Key_Shadow_Temple,5)", + "Shadow Temple Beyond Boat": "can_play(Zeldas_Lullaby) and + (is_adult or (is_child and can_hover))" + } + }, + { + "region_name": "Shadow Temple Beyond Boat", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Spike Walls Left Chest": "can_use(Dins_Fire) or can_live_dmg(0.5) or Fairy or can_use(Nayrus_Love) or + (can_use(Hookshot) and can_mega)", + "Shadow Temple Boss Key Chest": "can_use(Dins_Fire) or can_live_dmg(0.5) or Fairy or can_use(Nayrus_Love) or + (can_use(Hookshot) and can_mega)", + "Shadow Temple Invisible Floormaster Chest": "True", + "Shadow Temple GS Triple Giant Pot": "True" + }, + "exits": { + "Shadow Boss": "(has_bombchus or can_use(Distant_Scarecrow) or Bow or + (can_mega and can_use(Hover_Boots)) or can_hover) and + (Boss_Key_Shadow_Temple or (has_explosives and is_adult)) and + (can_mega or can_use(Hover_Boots)) and (Small_Key_Shadow_Temple, 5)" + } + }, + { + "region_name": "Shadow Boss", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Bongo Bongo Heart": "True", + "Bongo Bongo": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Spirit Temple MQ.json b/worlds/oot/data/Glitched World/Spirit Temple MQ.json new file mode 100644 index 00000000..8d8d91af --- /dev/null +++ b/worlds/oot/data/Glitched World/Spirit Temple MQ.json @@ -0,0 +1,134 @@ +[ + { + "region_name": "Spirit Temple Lobby", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Entrance Front Left Chest": "True", + "Spirit Temple MQ Entrance Back Left Chest": " + here(can_blast_or_smash) and + (can_use(Slingshot) or can_use(Bow))", + "Spirit Temple MQ Entrance Back Right Chest": " + has_bombchus or can_use(Bow) or can_use(Hookshot) or + can_use(Slingshot) or can_use(Boomerang)" + }, + "exits": { + "Desert Colossus": "True", + "Child Spirit Temple": "is_child", + "Adult Spirit Temple": " + has_bombchus and can_use(Longshot) and can_use(Silver_Gauntlets)" + } + }, + { + "region_name": "Child Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Map Room Enemy Chest": " + (Sticks or Kokiri_Sword) and + has_bombchus and Slingshot and can_use(Dins_Fire)", + "Spirit Temple MQ Map Chest": " + Sticks or Kokiri_Sword or has_explosives", + "Spirit Temple MQ Silver Block Hallway Chest": " + has_bombchus and (Small_Key_Spirit_Temple, 7) and Slingshot and + (can_use(Dins_Fire) or + here(is_adult and can_use(Longshot) and can_use(Silver_Gauntlets) and + (can_use(Fire_Arrows) or + (logic_spirit_mq_frozen_eye and Bow and can_play(Song_of_Time)))))" + }, + "exits": { + "Spirit Temple Shared": "has_bombchus and (Small_Key_Spirit_Temple, 2)" + } + }, + { + "region_name": "Adult Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Child Hammer Switch Chest": " + (Small_Key_Spirit_Temple, 7) and Megaton_Hammer and can_play(Requiem_of_Spirit)", + "Spirit Temple MQ Child Climb South Chest": "(Small_Key_Spirit_Temple, 7)", + "Spirit Temple MQ Statue Room Lullaby Chest": "can_play(Zeldas_Lullaby)", + "Spirit Temple MQ Statue Room Invisible Chest": "logic_lens_spirit_mq or can_use(Lens_of_Truth)", + "Spirit Temple MQ Beamos Room Chest": "(Small_Key_Spirit_Temple, 5)", + "Spirit Temple MQ Chest Switch Chest": " + (Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time)", + "Spirit Temple MQ Boss Key Chest": " + (Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time) and Mirror_Shield", + "Spirit Temple MQ GS Nine Thrones Room West": "(Small_Key_Spirit_Temple, 7)", + "Spirit Temple MQ GS Nine Thrones Room North": "(Small_Key_Spirit_Temple, 7)" + }, + "exits": { + "Lower Adult Spirit Temple": " + (can_use(Fire_Arrows) or + (logic_spirit_mq_lower_adult and can_use(Dins_Fire) and Bow)) and Mirror_Shield", + "Spirit Temple Shared": "True", + "Spirit Temple Boss Area": " + (Small_Key_Spirit_Temple, 6) and can_play(Zeldas_Lullaby) and Megaton_Hammer", + "Mirror Shield Hand": " + (Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time) and (logic_lens_spirit_mq or can_use(Lens_of_Truth))" + } + }, + { + "region_name": "Spirit Temple Shared", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Child Climb North Chest": "(Small_Key_Spirit_Temple, 6)", + "Spirit Temple MQ Compass Chest": " + ((Small_Key_Spirit_Temple, 7) and can_use(Slingshot)) or + (can_use(Longshot) and can_use(Silver_Gauntlets) and Bow) or + (Slingshot and Bow)", + "Spirit Temple MQ Sun Block Room Chest": " + can_play(Song_of_Time) or + (can_use(Longshot) and can_use(Silver_Gauntlets))", + "Spirit Temple MQ GS Sun Block Room": " + (logic_spirit_mq_sun_block_gs and can_play(Song_of_Time) and Boomerang) or + (can_use(Longshot) and can_use(Silver_Gauntlets))" + }, + "exits": { + "Silver Gauntlets Hand": " + ((Small_Key_Spirit_Temple, 7) and + (can_play(Song_of_Time) or + (can_use(Longshot) and can_use(Silver_Gauntlets)))) or + ((Small_Key_Spirit_Temple, 4) and can_play(Song_of_Time) and + (logic_lens_spirit_mq or can_use(Lens_of_Truth)))" + } + }, + { + "region_name": "Lower Adult Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Leever Room Chest": "True", + "Spirit Temple MQ Symphony Room Chest": " + (Small_Key_Spirit_Temple, 7) and Megaton_Hammer and Ocarina and + Song_of_Time and Eponas_Song and Suns_Song and + Song_of_Storms and Zeldas_Lullaby", + "Spirit Temple MQ Entrance Front Right Chest": "Megaton_Hammer", + "Spirit Temple MQ GS Leever Room": "True", + "Spirit Temple MQ GS Symphony Room": " + (Small_Key_Spirit_Temple, 7) and Megaton_Hammer and Ocarina and + Song_of_Time and Eponas_Song and Suns_Song and + Song_of_Storms and Zeldas_Lullaby" + } + }, + { + "region_name": "Spirit Temple Boss Area", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Mirror Puzzle Invisible Chest": "logic_lens_spirit_mq or can_use(Lens_of_Truth)", + "Spirit Temple Twinrova Heart": "Mirror_Shield and Boss_Key_Spirit_Temple", + "Twinrova": "Mirror_Shield and Boss_Key_Spirit_Temple" + } + }, + { + "region_name": "Mirror Shield Hand", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Mirror Shield Chest": "True" + } + }, + { + "region_name": "Silver Gauntlets Hand", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Silver Gauntlets Chest": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Spirit Temple.json b/worlds/oot/data/Glitched World/Spirit Temple.json new file mode 100644 index 00000000..63a6fb9e --- /dev/null +++ b/worlds/oot/data/Glitched World/Spirit Temple.json @@ -0,0 +1,171 @@ +[ + { + "region_name": "Spirit Temple Lobby", + "dungeon": "Spirit Temple", + "exits": { + "Desert Colossus": "True", + "Child Spirit Temple": "is_child or (is_adult and (can_mega or Hover_Boots))", + "Early Adult Spirit Temple": "can_use(Silver_Gauntlets) or can_use(Hover_Boots) or (is_adult and can_shield)" + } + }, + { + "region_name": "Child Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Child Bridge Chest": "is_adult or + ( + (can_use(Boomerang) or Slingshot or has_bombchus or can_mega) and + (Sticks or has_explosives or + ( (Nuts or can_use(Boomerang)) and + (can_use(Kokiri_Sword) or Slingshot) ) ))", + "Spirit Temple Child Early Torches Chest": "(is_adult and has_fire_source) or + (has_fire_source_with_torch and (here(is_adult) or + ( + (can_use(Boomerang) or Slingshot or has_bombchus or can_mega) and + (Sticks or has_explosives or + ( (Nuts or can_use(Boomerang)) and + (can_use(Kokiri_Sword) or Slingshot) ) ))))", + "Spirit Temple GS Metal Fence": "is_adult or + ( + (can_use(Boomerang) or Slingshot or has_bombchus or can_mega) and + (Sticks or has_explosives or + ( (Nuts or can_use(Boomerang)) and + (can_use(Kokiri_Sword) or Slingshot) ) ))", + "Nut Crate": "True" + }, + "exits": { + "Child Spirit Temple Climb": "(Small_Key_Spirit_Temple, 2) and + (is_child or ((can_mega and can_use(Longshot)) or can_use(Hover_Boots)) + )" + } + }, + { + "region_name": "Child Spirit Temple Climb", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Child Climb North Chest": "at('Spirit Temple Central Chamber', True) + or is_child or has_projectile(adult)", + "Spirit Temple Child Climb East Chest": "at('Spirit Temple Central Chamber', True) + or is_child or has_projectile(adult)", + "Spirit Temple GS Sun on Floor Room": "can_use(Boomerang) or can_use(Hookshot) or + (can_child_damage and (can_live_dmg(0.5) or Fairy or can_use(Nayrus_Love))) or + (is_adult and (can_live_dmg(0.5) or Fairy or can_use(Nayrus_Love)))" + }, + "exits": { + "Spirit Temple Central Chamber": "has_explosives" + } + }, + { + "region_name": "Early Adult Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Compass Chest": "can_play(Zeldas_Lullaby) and + (can_use(Hookshot) or can_hover) and has_projectile(either)", + "Spirit Temple Early Adult Right Chest": "has_projectile(either)", + "Spirit Temple First Mirror Left Chest": "(Small_Key_Spirit_Temple, 2)", + "Spirit Temple First Mirror Right Chest": "(Small_Key_Spirit_Temple, 2)", + "Spirit Temple GS Boulder Room": "has_projectile(either) and + (can_play(Song_of_Time) or can_use(Hover_Boots))" + }, + "exits": { + "Spirit Temple Central Chamber": "(Small_Key_Spirit_Temple, 2)" + } + }, + { + "region_name": "Spirit Temple Central Chamber", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Map Chest": "can_use(Bow) or has_fire_source_with_torch", + "Spirit Temple Sun Block Room Chest": "has_fire_source_with_torch or can_use(Bow)", + "Spirit Temple Statue Room Hand Chest": "can_play(Zeldas_Lullaby) + and can_jumpslash", + "Spirit Temple Statue Room Northeast Chest": "can_play(Zeldas_Lullaby) and can_jumpslash and + (can_use(Hookshot) or can_use(Hover_Boots) or can_mega)", + "Spirit Temple GS Hall After Sun Block Room": "can_use(Hookshot) or can_use(Boomerang) or can_hover", + "Spirit Temple GS Lobby": "can_use(Hookshot) or can_use(Boomerang) or can_hover + or can_use(Hover_Boots)" + }, + "exits": { + "Silver Gauntlets Hand": "True", + # access via Early Adult Spirit Temple requires 2 keys (+ jumpslash + explosives) + # access to Early Adult Spirit Temple guaranteed via can_jumpslash from here + "Spirit Temple Beyond Central Locked Door": "can_jumpslash and ( + (Small_Key_Spirit_Temple, 2) or + can_hover or + can_use(Hookshot)) and has_explosives", + "Child Spirit Temple Climb": "True", + "Spirit Temple Boss": "can_use(Hookshot) and can_live_dmg(0.5) and Mirror_Shield and has_explosives", + "Early Adult Spirit Temple": "can_jumpslash or can_hover or can_use(Hookshot)" + } + }, + { + "region_name": "Mirror Shield Hand", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Mirror Shield Chest": "True" + }, + "exits": { + "Desert Colossus": "True", + "Silver Gauntlets Hand": " + can_hover or can_use(Hookshot) or (can_use(Hover_Boots) and can_mega)", + "Spirit Temple Beyond Central Locked Door": "True" + } + }, + { + "region_name": "Silver Gauntlets Hand", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Silver Gauntlets Chest": "True" + }, + "exits": { + "Desert Colossus": "True", + "Mirror Shield Hand": "can_hover or (can_use(Hover_Boots) and can_mega)", + "Spirit Temple Central Chamber": "(Small_Key_Spirit_Temple, 2)" + } + }, + { + "region_name": "Spirit Temple Outdoor Hands", + "dungeon": "Spirit Temple", + "exits": { + "Silver Gauntlets Hand": "True", + "Mirror Shield Hand": "True" + } + }, + { + "region_name": "Spirit Temple Beyond Central Locked Door", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Near Four Armos Chest": "can_use(Mirror_Shield)", + "Spirit Temple Hallway Right Invisible Chest": "True", + "Spirit Temple Hallway Left Invisible Chest": "True" + }, + "exits": { + "Spirit Temple Beyond Final Locked Door": "(Small_Key_Spirit_Temple,5) and + (can_use(Hookshot) or has_explosives)", + "Mirror Shield Hand": "True", + "Spirit Temple Central Chamber": "has_explosives" + } + }, + { + "region_name": "Spirit Temple Beyond Final Locked Door", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Boss Key Chest": " + can_play(Zeldas_Lullaby) and (can_live_dmg(1.0) or (Bow and + Progressive_Hookshot))", + "Spirit Temple Topmost Chest": "can_use(Mirror_Shield)" + }, + "exits": { + "Spirit Temple Boss": "can_use(Mirror_Shield)", + "Spirit Temple Central Chamber": "can_use(Mirror_Shield) or can_use(Hookshot)" + } + }, + { + "region_name": "Spirit Temple Boss", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Twinrova Heart": "True", + "Twinrova": "True" + } + } +] diff --git a/worlds/oot/data/Glitched World/Water Temple MQ.json b/worlds/oot/data/Glitched World/Water Temple MQ.json new file mode 100644 index 00000000..633f9c3f --- /dev/null +++ b/worlds/oot/data/Glitched World/Water Temple MQ.json @@ -0,0 +1,58 @@ +[ + { + "region_name": "Water Temple Lobby", + "dungeon": "Water Temple", + "events": { + "Water Temple Clear": "Boss_Key_Water_Temple and can_use(Longshot)" + }, + "locations": { + "Water Temple MQ Map Chest": "has_fire_source and Iron_Boots", + "Water Temple MQ Central Pillar Chest": " + can_use(Zora_Tunic) and Iron_Boots and + (can_use(Fire_Arrows) or (can_use(Dins_Fire) and can_play(Song_of_Time)))", + # If the player leaves the dungeon without collecting the item at Morpha Heart, + # they won't be able to come back without Iron Boots. + # If it is the Iron Boots or an item required to get them, it means a soft-lock. + "Water Temple Morpha Heart": " + Boss_Key_Water_Temple and can_use(Longshot) and Iron_Boots", + "Morpha": "Boss_Key_Water_Temple and can_use(Longshot)" + }, + "exits": { + "Lake Hylia": "True", + "Water Temple Lowered Water Levels": "can_play(Zeldas_Lullaby) and Iron_Boots", + "Water Temple Dark Link Region": " + Small_Key_Water_Temple and can_use(Longshot) and Iron_Boots" + } + }, + { + "region_name": "Water Temple Lowered Water Levels", + "dungeon": "Water Temple", + "locations": { + "Water Temple MQ Compass Chest": "Bow or can_use(Dins_Fire)", + "Water Temple MQ Longshot Chest": "True", + "Water Temple MQ GS Lizalfos Hallway": "can_use(Dins_Fire)", + "Water Temple MQ GS Before Upper Water Switch": "can_use(Longshot)" + } + }, + { + "region_name": "Water Temple Dark Link Region", + "dungeon": "Water Temple", + "locations": { + "Water Temple MQ Boss Key Chest": "can_use(Dins_Fire)", + "Water Temple MQ GS River": "True" + }, + "exits": { + "Water Temple Basement Gated Areas": " + can_use(Dins_Fire) and (Hover_Boots or Ocarina)" + } + }, + { + "region_name": "Water Temple Basement Gated Areas", + "dungeon": "Water Temple", + "locations": { + "Water Temple MQ Freestanding Key": "True", + "Water Temple MQ GS Triple Wall Torch": "can_use(Fire_Arrows)", + "Water Temple MQ GS Freestanding Key Area": "(Small_Key_Water_Temple, 2)" + } + } +] diff --git a/worlds/oot/data/Glitched World/Water Temple.json b/worlds/oot/data/Glitched World/Water Temple.json new file mode 100644 index 00000000..c6b3c985 --- /dev/null +++ b/worlds/oot/data/Glitched World/Water Temple.json @@ -0,0 +1,174 @@ +[ + { + "region_name": "Water Temple Lobby", + "dungeon": "Water Temple", + "locations": {}, + "exits": { + "High Alcove": "is_adult or can_hover", + "Boss Area": "can_use(Longshot) or can_hover or (can_use(Hover_Boots) and (can_mega or Megaton_Hammer))", + "Dark Link Area": "(at('High Alcove', can_play(Zeldas_Lullaby)) or + (can_use(Hover_Boots) and (can_mega or Megaton_Hammer))) + and (Small_Key_Water_Temple, 4)", + "Under Entrance Block": "can_use(Hookshot) and Iron_Boots", + "Central Pillar from Lobby": "can_use(Hookshot) and Iron_Boots and + (Small_Key_Water_Temple, 4)", + "Compass Room": "can_use(Iron_Boots) and can_use(Hookshot)", + "Ruto Column": "can_use(Iron_Boots) or can_use(Longshot) or can_jumpslash" + } + }, + { + "region_name": "High Alcove", + "dungeon": "Water Temple", + "locations": {}, + "exits": { + "Compass Room": "is_adult", + "Ruto Column": "is_adult", + "Under Entrance Block": "can_use(Iron_Boots) and can_use(Hookshot)", + "Caged Skulltula": "is_adult", + "Dragon Head Area": "is_adult", + "Boss Key Area": "is_adult and + (Small_Key_Water_Temple, 4) + and (can_use(Longshot) or can_hover or Hover_Boots)", + "Boss Area": "can_play(Zeldas_Lullaby) and can_use(Longshot)", + "Water Temple Lobby": "can_play(Zeldas_Lullaby)" + + } + }, + { + "region_name": "Caged Skulltula", + "dungeon": "Water Temple", + "locations": { + "Water Temple GS Behind Gate": "(can_use(Hover_Boots) or can_hover or can_use(Hookshot)) and + (can_jumpslash or has_explosives)" + } + }, + { + "region_name": "Compass Room", + "dungeon": "Water Temple", + "locations": { + "Water Temple Compass Chest": "True" + } + }, + { + "region_name": "Under Entrance Block", + "dungeon": "Water Temple", + "locations": { + "Water Temple Central Bow Target Chest": "True" + } + }, + { + "region_name": "Ruto Column", + "dungeon": "Water Temple", + "locations": { + "Water Temple Map Chest": "is_adult or can_child_damage", + "Water Temple Cracked Wall Chest": "(can_use(Hookshot) and Iron_Boots) or + (can_play(Zeldas_Lullaby) and (can_use(Hookshot) or has_explosives)) ", + "Water Temple Torches Chest": "(here(is_child and can_use(Sticks)) or has_fire_source or can_use(Bow)) + and can_play(Zeldas_Lullaby)" + }, + "exits": { + "Central Pillar": "can_play(Zeldas_Lullaby) and + ((Small_Key_Water_Temple, 5) + or here(is_child and can_use(Sticks)) or has_fire_source or can_use(Bow))", + "Boss Key Area": "(Small_Key_Water_Temple, 4) and + (can_use(Longshot) or can_hover or can_use(Hover_Boots)) and can_play(Zeldas_Lullaby)", + "Dragon Head Area": "Progressive_Strength_Upgrade and (is_adult or can_child_attack) and can_play(Zeldas_Lullaby)", + "Caged Skulltula": "has_explosives and can_play(Zeldas_Lullaby)", + "Compass Room": "can_play(Zeldas_Lullaby) and can_use(Hookshot)", + "Under Entrance Block": "can_play(Zeldas_Lullaby) and + ( (can_use(Hookshot) and can_mega) or (can_use(Bow) and (Hover_Boots or can_use(Longshot)) + and (Progressive_Strength_Upgrade or (can_use(Hookshot) and can_mega))))", + "High Alcove": "(can_use(Hover_Boots) or can_use(Hookshot) or (is_adult and can_mega) or can_hover) + and can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "Central Pillar from Lobby", + "dungeon": "Water Temple", + "exits": { + "Central Pillar": "True" + } + }, + { + "region_name": "Central Pillar", + "dungeon": "Water Temple", + "locations": { + "Water Temple Central Pillar Chest": "can_use(Iron_Boots) and can_use(Hookshot) and + (at('Central Pillar from Lobby', True) or can_play(Zeldas_Lullaby))", + "Water Temple GS Central Pillar": "at('Central Pillar from Lobby', True) or + can_use(Longshot) or + at('High Alcove', + can_use(Farores_Wind) and can_play(Zeldas_Lullaby) + and (can_use(Hookshot) or can_use(Boomerang)))" + }, + "exits": { + "High Alcove": "(can_use(Hover_Boots) or can_use(Hookshot) or (is_adult and can_mega) or can_hover + or has_projectile(either)) + and can_play(Zeldas_Lullaby)", + "Compass Room": "can_play(Zeldas_Lullaby) and can_use(Hookshot)" + } + }, + { + "region_name": "Boss Key Area", + "dungeon": "Water Temple", + "locations": { + "Water Temple Boss Key Chest": "(Small_Key_Water_Temple, 5) and + (is_adult or can_hover)", + "Water Temple GS Near Boss Key Chest": "(is_adult or can_hover) and + (can_use(Hookshot) or can_use(Boomerang) or can_mega)" + } + }, + { + "region_name": "Dark Link Area", + "dungeon": "Water Temple", + "locations": { + "Water Temple Longshot Chest": "can_use(Hookshot)", + "Water Temple GS Falling Platform Room": "can_use(Hookshot)" + }, + "exits": { + "River": "can_play(Song_of_Time) or (can_use(Hookshot) and (Hover_Boots or (Bombs and can_live_dmg(0.5))))" + } + }, + { + "region_name": "River", + "dungeon": "Water Temple", + "locations": { + "Water Temple GS River": "can_use(Longshot) or (Iron_Boots and can_use(Hookshot))" + }, + "exits": { + "River Chest": "can_use(Bow) or (can_use(Longshot) and has_bottle and Iron_Boots)" + } + }, + { + "region_name": "River Chest", + "dungeon": "Water Temple", + "locations": { + "Water Temple River Chest": "True" + }, + "exits": { + "Dragon Head Area": "True", + "River": "(can_use(Longshot) or can_use(Bow)) and can_mega" + } + }, + { + "region_name": "Dragon Head Area", + "dungeon": "Water Temple", + "locations": { + "Water Temple Dragon Chest": "at('River Chest', is_adult) or has_bombchus or (Iron_Boots and can_use(Hookshot))" + }, + "exits": { + "River Chest": "can_hover" + } + }, + { + "region_name": "Boss Area", + "dungeon": "Water Temple", + "events": { + "Water Temple Clear": "can_jumpslash and (can_hover or Boss_Key_Water_Temple)" + }, + "locations": { + "Morpha": "can_jumpslash and (can_hover or Boss_Key_Water_Temple)", + "Water Temple Morpha Heart": "can_jumpslash and (can_hover or Boss_Key_Water_Temple)" + } + } +] diff --git a/worlds/oot/data/Hints/balanced.json b/worlds/oot/data/Hints/balanced.json new file mode 100644 index 00000000..f0e153ca --- /dev/null +++ b/worlds/oot/data/Hints/balanced.json @@ -0,0 +1,28 @@ +{ + "name": "balanced", + "gui_name": "Balanced", + "description": "Recommended hint spread.", + "add_locations": [], + "remove_locations": [], + "add_items": [], + "remove_items": [], + "dungeons_woth_limit": 2, + "dungeons_barren_limit": 1, + "named_items_required": true, + "vague_named_items": false, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 1}, + "woth": {"order": 3, "weight": 3.5, "fixed": 0, "copies": 1}, + "barren": {"order": 4, "weight": 2.0, "fixed": 0, "copies": 1}, + "entrance": {"order": 5, "weight": 3.0, "fixed": 0, "copies": 1}, + "sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 1}, + "random": {"order": 7, "weight": 6.0, "fixed": 0, "copies": 1}, + "item": {"order": 8, "weight": 5.0, "fixed": 0, "copies": 1}, + "song": {"order": 9, "weight": 1.0, "fixed": 0, "copies": 1}, + "overworld": {"order": 10, "weight": 2.0, "fixed": 0, "copies": 1}, + "dungeon": {"order": 11, "weight": 1.5, "fixed": 0, "copies": 1}, + "junk": {"order": 12, "weight": 3.0, "fixed": 0, "copies": 1}, + "named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 1} + } +} \ No newline at end of file diff --git a/worlds/oot/data/Hints/bingo.json b/worlds/oot/data/Hints/bingo.json new file mode 100644 index 00000000..c1a9730d --- /dev/null +++ b/worlds/oot/data/Hints/bingo.json @@ -0,0 +1,28 @@ +{ + "name": "bingo", + "gui_name": "Bingo", + "description": "Hints locations for items required for most bingo goals. Can be made board-specific by entering a Bingosync URL.", + "add_locations": [], + "remove_locations": [], + "add_items": [], + "remove_items": [], + "dungeons_woth_limit": 2, + "dungeons_barren_limit": 1, + "named_items_required": true, + "vague_named_items": false, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 0}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2}, + "woth": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 0}, + "barren": {"order": 4, "weight": 0.0, "fixed": 0, "copies": 0}, + "entrance": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 2}, + "sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 1}, + "random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 2}, + "item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2}, + "song": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2}, + "overworld": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 2}, + "dungeon": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 2}, + "junk": {"order": 12, "weight": 1.0, "fixed": 0, "copies": 1}, + "named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 2} + } +} diff --git a/worlds/oot/data/Hints/ddr.json b/worlds/oot/data/Hints/ddr.json new file mode 100644 index 00000000..c07113b6 --- /dev/null +++ b/worlds/oot/data/Hints/ddr.json @@ -0,0 +1,51 @@ +{ + "name": "ddr", + "gui_name": "DDR", + "description": "DDR weekly race hints. Duplicates of each hint, 2 WotH, 3 Barren, 3 Named-Item, remainder of hints are Sometimes. Prevents some items from being hinted in WotH or Sometimes.", + "add_locations": [ + { "location": "Deku Theater Skull Mask", "types": ["always"]} + ], + "remove_locations": [], + "add_items": [ + {"item":"Hover Boots", "types":["named-item"]}, + {"item":"Progressive Hookshot", "types":["named-item"]}, + {"item":"Dins Fire", "types":["named-item"]}, + {"item":"Bomb Bag", "types":["named-item"]}, + {"item":"Boomerang", "types":["named-item"]}, + {"item":"Bow", "types":["named-item"]}, + {"item":"Megaton Hammer", "types":["named-item"]}, + {"item":"Iron Boots", "types":["named-item"]}, + {"item":"Magic Meter", "types":["named-item"]}, + {"item":"Mirror Shield", "types":["named-item"]}, + {"item":"Fire Arrows", "types":["named-item"]}, + {"item":"Progressive Strength Upgrade", "types":["named-item"]} + ], + "remove_items": [ + { "item": "Zeldas Lullaby", "types": ["woth", "sometimes"] }, + { "item": "Rutos Letter", "types": ["woth", "sometimes"] }, + { "item": "Goron Tunic", "types": ["woth", "sometimes"] }, + { "item": "Zora Tunic", "types": ["woth", "sometimes"] }, + { "item": "Bow", "types": ["barren"]}, + { "item": "Bomb Bag", "types": ["barren"]}, + { "item": "Magic Meter", "types": ["barren"]} + ], + "dungeons_woth_limit": 1, + "dungeons_barren_limit": 1, + "named_items_required": false, + "vague_named_items": true, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2}, + "woth": {"order": 3, "weight": 0.0, "fixed": 2, "copies": 2}, + "barren": {"order": 4, "weight": 0.0, "fixed": 3, "copies": 2}, + "entrance": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 2}, + "sometimes": {"order": 13,"weight": 0.0, "fixed": 99, "copies": 2}, + "random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 2}, + "item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2}, + "song": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2}, + "overworld": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 2}, + "dungeon": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 2}, + "junk": {"order": 12, "weight": 0.0, "fixed": 0, "copies": 1}, + "named-item": {"order": 6, "weight": 0.0, "fixed": 3, "copies": 2} + } +} \ No newline at end of file diff --git a/worlds/oot/data/Hints/league.json b/worlds/oot/data/Hints/league.json new file mode 100644 index 00000000..1119cea0 --- /dev/null +++ b/worlds/oot/data/Hints/league.json @@ -0,0 +1,31 @@ +{ + "name": "league", + "gui_name": "League", + "description": "Hint Distro for the OoTR League", + "add_locations": [ + { "location": "Deku Theater Skull Mask", "types": ["always"] } + ], + "remove_locations": [], + "add_items": [], + "remove_items": [{"types": ["woth"], "item": "Zeldas Lullaby"}], + "dungeons_woth_limit": 2, + "dungeons_barren_limit": 1, + "named_items_required": true, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2}, + "woth": {"order": 3, "weight": 0.0, "fixed": 5, "copies": 2}, + "barren": {"order": 4, "weight": 0.0, "fixed": 3, "copies": 2}, + "entrance": {"order": 5, "weight": 0.0, "fixed": 4, "copies": 2}, + "sometimes": {"order": 6, "weight": 0.0, "fixed": 100, "copies": 2}, + "random": {"order": 7, "weight": 9.0, "fixed": 0, "copies": 2}, + "item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "named-item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2} + }, + "groups": [], + "disabled": [] +} diff --git a/worlds/oot/data/Hints/mw2.json b/worlds/oot/data/Hints/mw2.json new file mode 100644 index 00000000..f29f8ea7 --- /dev/null +++ b/worlds/oot/data/Hints/mw2.json @@ -0,0 +1,143 @@ +{ + "name": "mw2", + "gui_name": "MW Season 2", + "description": "Hints used for the multi-world tournament season 2.", + "add_locations": [ + { + "location": "Song from Ocarina of Time", + "types": [ + "always" + ] + }, + { + "location": "Deku Theater Skull Mask", + "types": [ + "always" + ] + }, + { + "location": "DMC Deku Scrub", + "types": [ + "always" + ] + } + ], + "remove_locations": [ + { + "location": "Haunted Wasteland", + "types": [ + "barren" + ] + }, + { + "location": "Temple of Time", + "types": [ + "barren" + ] + }, + { + "location": "Hyrule Castle", + "types": [ + "barren" + ] + }, + { + "location": "outside Ganon's Castle", + "types": [ + "barren" + ] + } + ], + "add_items": [], + "remove_items": [ + { + "item": "Zeldas Lullaby", + "types": [ + "woth" + ] + } + ], + "dungeons_woth_limit": 3, + "dungeons_barren_limit": 1, + "named_items_required": true, + "distribution": { + "trial": { + "order": 1, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "always": { + "order": 2, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "woth": { + "order": 3, + "weight": 0.0, + "fixed": 7, + "copies": 2 + }, + "barren": { + "order": 4, + "weight": 0.0, + "fixed": 3, + "copies": 2 + }, + "entrance": { + "order": 5, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "sometimes": { + "order": 6, + "weight": 0.0, + "fixed": 100, + "copies": 2 + }, + "random": { + "order": 7, + "weight": 9.0, + "fixed": 0, + "copies": 2 + }, + "item": { + "order": 0, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "song": { + "order": 0, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "overworld": { + "order": 0, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "dungeon": { + "order": 0, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "junk": { + "order": 0, + "weight": 0.0, + "fixed": 0, + "copies": 2 + }, + "named-item": { + "order": 8, + "weight": 0.0, + "fixed": 0, + "copies": 2 + } + } +} diff --git a/worlds/oot/data/Hints/scrubs.json b/worlds/oot/data/Hints/scrubs.json new file mode 100644 index 00000000..262ca010 --- /dev/null +++ b/worlds/oot/data/Hints/scrubs.json @@ -0,0 +1,33 @@ +{ + "name": "scrubs", + "gui_name": "Scrubs", + "description": "Tournament hints used for Scrubs Races. Duplicates of each hint, Skull Mask is an always hint, 5 WotH, 3 Foolish, 8 sometimes. Can also be used to simulate S3 Tournament hints.", + "add_locations": [ + { "location": "Deku Theater Skull Mask", "types": ["always"] }, + { "location": "Deku Theater Mask of Truth", "types": ["always"] } + ], + "remove_locations": [], + "add_items": [], + "remove_items": [], + "dungeons_woth_limit": 2, + "dungeons_barren_limit": 1, + "named_items_required": true, + "vague_named_items": false, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2}, + "woth": {"order": 3, "weight": 0.0, "fixed": 5, "copies": 2}, + "barren": {"order": 4, "weight": 0.0, "fixed": 3, "copies": 2}, + "entrance": {"order": 5, "weight": 0.0, "fixed": 4, "copies": 2}, + "sometimes": {"order": 6, "weight": 0.0, "fixed": 100, "copies": 2}, + "random": {"order": 7, "weight": 9.0, "fixed": 0, "copies": 2}, + "item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}, + "named-item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2} + }, + "groups": [], + "disabled": [] +} diff --git a/worlds/oot/data/Hints/strong.json b/worlds/oot/data/Hints/strong.json new file mode 100644 index 00000000..5892736d --- /dev/null +++ b/worlds/oot/data/Hints/strong.json @@ -0,0 +1,28 @@ +{ + "name": "strong", + "gui_name": "Strong", + "description": "More useful hints.", + "add_locations": [], + "remove_locations": [], + "add_items": [], + "remove_items": [], + "dungeons_woth_limit": 2, + "dungeons_barren_limit": 1, + "named_items_required": true, + "vague_named_items": false, + "distribution": { + "trial": {"order": 1, "weight": 0.00, "fixed": 0, "copies": 1}, + "always": {"order": 2, "weight": 0.00, "fixed": 0, "copies": 2}, + "woth": {"order": 3, "weight": 3.00, "fixed": 0, "copies": 2}, + "barren": {"order": 4, "weight": 3.00, "fixed": 0, "copies": 1}, + "entrance": {"order": 5, "weight": 1.00, "fixed": 0, "copies": 1}, + "sometimes": {"order": 6, "weight": 0.00, "fixed": 0, "copies": 1}, + "random": {"order": 7, "weight": 2.00, "fixed": 0, "copies": 1}, + "item": {"order": 8, "weight": 1.00, "fixed": 0, "copies": 1}, + "song": {"order": 9, "weight": 0.33, "fixed": 0, "copies": 1}, + "overworld": {"order": 10, "weight": 0.66, "fixed": 0, "copies": 1}, + "dungeon": {"order": 11, "weight": 0.66, "fixed": 0, "copies": 1}, + "junk": {"order": 12, "weight": 0.00, "fixed": 0, "copies": 1}, + "named-item": {"order": 13, "weight": 0.00, "fixed": 0, "copies": 1} + } +} \ No newline at end of file diff --git a/worlds/oot/data/Hints/tournament.json b/worlds/oot/data/Hints/tournament.json new file mode 100644 index 00000000..02488970 --- /dev/null +++ b/worlds/oot/data/Hints/tournament.json @@ -0,0 +1,32 @@ +{ + "name": "tournament", + "gui_name": "Tournament", + "description": "Tournament hints used for OoTR Season 4. Gossip stones in grottos are disabled. 4 WotH, 2 Barren, remainder filled with Sometimes. Always, WotH, and Barren hints duplicated.", + "add_locations": [], + "remove_locations": [], + "add_items": [], + "remove_items": [{"types": ["woth"], "item": "Zeldas Lullaby"}], + "dungeons_woth_limit": 2, + "dungeons_barren_limit": 1, + "named_items_required": true, + "vague_named_items": false, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2}, + "woth": {"order": 3, "weight": 0.0, "fixed": 4, "copies": 2}, + "barren": {"order": 4, "weight": 0.0, "fixed": 2, "copies": 2}, + "entrance": {"order": 5, "weight": 0.0, "fixed": 4, "copies": 1}, + "sometimes": {"order": 6, "weight": 0.0, "fixed": 99, "copies": 1}, + "random": {"order": 7, "weight": 9.0, "fixed": 0, "copies": 1}, + "item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1}, + "song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1}, + "overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1}, + "dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1}, + "junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1}, + "named-item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 1} + }, + "groups": [], + "disabled": [ + "HC (Storms Grotto)", "HF (Cow Grotto)", "HF (Near Market Grotto)", "HF (Southeast Grotto)", "HF (Open Grotto)", "Kak (Open Grotto)", "ZR (Open Grotto)", "KF (Storms Grotto)", "LW (Near Shortcuts Grotto)", "DMT (Storms Grotto)", "DMC (Upper Grotto)" + ] +} diff --git a/worlds/oot/data/Hints/useless.json b/worlds/oot/data/Hints/useless.json new file mode 100644 index 00000000..f0da50ac --- /dev/null +++ b/worlds/oot/data/Hints/useless.json @@ -0,0 +1,28 @@ +{ + "name": "useless", + "gui_name": "Useless", + "description": "Only junk hints.", + "add_locations": [], + "remove_locations": [], + "add_items": [], + "remove_items": [], + "dungeons_woth_limit": 2, + "dungeons_barren_limit": 1, + "named_items_required": false, + "vague_named_items": false, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 0}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 0}, + "woth": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 0}, + "barren": {"order": 4, "weight": 0.0, "fixed": 0, "copies": 0}, + "entrance": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 0}, + "sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 0}, + "random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 0}, + "item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 0}, + "song": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 0}, + "overworld": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 0}, + "dungeon": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 0}, + "junk": {"order": 12, "weight": 9.0, "fixed": 0, "copies": 1}, + "named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 0} + } +} \ No newline at end of file diff --git a/worlds/oot/data/Hints/very_strong.json b/worlds/oot/data/Hints/very_strong.json new file mode 100644 index 00000000..90402bf2 --- /dev/null +++ b/worlds/oot/data/Hints/very_strong.json @@ -0,0 +1,28 @@ +{ + "name": "very_strong", + "gui_name": "Very Strong", + "description": "Many powerful hints.", + "add_locations": [], + "remove_locations": [], + "add_items": [], + "remove_items": [], + "dungeons_woth_limit": 40, + "dungeons_barren_limit": 40, + "named_items_required": true, + "vague_named_items": false, + "distribution": { + "trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1}, + "always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2}, + "woth": {"order": 3, "weight": 3.0, "fixed": 0, "copies": 2}, + "barren": {"order": 4, "weight": 3.0, "fixed": 0, "copies": 1}, + "entrance": {"order": 5, "weight": 2.0, "fixed": 0, "copies": 1}, + "sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 1}, + "random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 1}, + "item": {"order": 8, "weight": 1.0, "fixed": 0, "copies": 1}, + "song": {"order": 9, "weight": 0.5, "fixed": 0, "copies": 1}, + "overworld": {"order": 10, "weight": 1.5, "fixed": 0, "copies": 1}, + "dungeon": {"order": 11, "weight": 1.5, "fixed": 0, "copies": 1}, + "junk": {"order": 12, "weight": 0.0, "fixed": 0, "copies": 1}, + "named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 1} + } +} \ No newline at end of file diff --git a/worlds/oot/data/LogicHelpers.json b/worlds/oot/data/LogicHelpers.json new file mode 100644 index 00000000..c1766a1e --- /dev/null +++ b/worlds/oot/data/LogicHelpers.json @@ -0,0 +1,114 @@ +{ + # Rules here define replacement "functions" or item aliases. + # The alias itself must always be alphanumeric only--string items bypass the aliasing. + # Rules should be simple python and can invoke other aliases or even the + # at/here metarules. + "Hookshot": "Progressive_Hookshot", + "Longshot": "(Progressive_Hookshot, 2)", + "Silver_Gauntlets": "(Progressive_Strength_Upgrade, 2)", + "Golden_Gauntlets": "(Progressive_Strength_Upgrade, 3)", + "Scarecrow": "Progressive_Hookshot and can_play(Scarecrow_Song)", + "Distant_Scarecrow": "(Progressive_Hookshot, 2) and can_play(Scarecrow_Song)", + # Items can be directly aliased, so all occurrences of that item name get replaced, + # but make sure that inside the rule you use the string 'item' form + # to avoid infinite recursion. + "Goron_Tunic": "'Goron Tunic' or Buy_Goron_Tunic", + "Zora_Tunic": "'Zora Tunic' or Buy_Zora_Tunic", + + # Refill aliases. If we start considering Bow etc refills we can enable these aliases + # without editing all logic files. + # "Bow": "'Bow'", + # "Slingshot": "'Slingshot'", + "Bombs": "Bomb_Bag", + "Deku_Shield": "Buy_Deku_Shield", + "Hylian_Shield": "Buy_Hylian_Shield", + "Nuts": "Buy_Deku_Nut_5 or Buy_Deku_Nut_10 or Deku_Nut_Drop", + "Sticks": "Buy_Deku_Stick_1 or Deku_Stick_Drop", + "Bugs": "'Bugs' or Buy_Bottle_Bug", + "Blue_Fire": "'Blue Fire' or Buy_Blue_Fire", + "Fish": "'Fish' or Buy_Fish", + "Fairy": "'Fairy' or Buy_Fairys_Spirit", + "Big_Poe": "'Big Poe'", + + "has_bombchus": "(Buy_Bombchu_5 or Buy_Bombchu_10 or Buy_Bombchu_20 or Bombchu_Drop) and (bombchus_in_logic or Bomb_Bag)", + "found_bombchus": "(bombchus_in_logic and (Bombchus or Bombchus_5 or Bombchus_10 or Bombchus_20)) or (not bombchus_in_logic and Bomb_Bag)", + "has_explosives": "Bombs or (bombchus_in_logic and has_bombchus)", + "is_child": "current_spot_child_access", + "is_adult": "current_spot_adult_access", + "is_starting_age": "current_spot_starting_age_access", + "is_glitched": "logic_rules != 'glitchless'", + "can_blast_or_smash": "has_explosives or can_use(Megaton_Hammer)", + "can_child_attack": "is_child and (Slingshot or Boomerang or Sticks or Kokiri_Sword or has_explosives or can_use(Dins_Fire))", + "can_child_damage": "is_child and (Slingshot or Sticks or Kokiri_Sword or has_explosives or can_use(Dins_Fire))", + "can_cut_shrubs": "is_adult or Sticks or Kokiri_Sword or Boomerang or has_explosives", + "can_dive": "Progressive_Scale", + "can_leave_forest": "open_forest != 'closed' or is_adult or is_glitched or Deku_Tree_Clear", + "can_plant_bugs": "is_child and Bugs", + "can_ride_epona": "is_adult and Epona and (can_play(Eponas_Song) or (is_glitched and can_hover))", + "can_stun_deku": "is_adult or (Slingshot or Boomerang or Sticks or Kokiri_Sword or has_explosives or can_use(Dins_Fire) or Nuts or Deku_Shield)", + "can_summon_gossip_fairy": "Ocarina and (Zeldas_Lullaby or Eponas_Song or Song_of_Time or Suns_Song)", + "can_summon_gossip_fairy_without_suns": "Ocarina and (Zeldas_Lullaby or Eponas_Song or Song_of_Time)", + "can_take_damage": "damage_multiplier != 'ohko' or Fairy or can_use(Nayrus_Love)", + "can_plant_bean": "is_child and (Magic_Bean or Magic_Bean_Pack)", + "can_play(song)": "Ocarina and song", + "can_open_bomb_grotto": "can_blast_or_smash and (Stone_of_Agony or logic_grottos_without_agony)", + "can_open_storm_grotto": "can_play(Song_of_Storms) and (Stone_of_Agony or logic_grottos_without_agony)", + # The last case in a conditional still needs a check, to prevent failure from falling through + # into what should be the 'else' case. + "can_use_projectile": "has_explosives or (is_adult and (Bow or Hookshot)) or (is_child and (Slingshot or Boomerang))", + "has_projectile(for_age)": "has_explosives + or (for_age == child and (Slingshot or Boomerang)) + or (for_age == adult and (Bow or Hookshot)) + or (for_age == both and (Slingshot or Boomerang) and (Bow or Hookshot)) + or (for_age == either and (Slingshot or Boomerang or Bow or Hookshot))", + + # 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. + "can_use(item)": "(_is_magic_item(item) and item and Magic_Meter) + or (_is_adult_item(item) and is_adult and item) + or (_is_magic_arrow(item) and is_adult and item and Bow and Magic_Meter) + or (_is_child_item(item) and is_child and item)", + "_is_magic_item(item)": "item == Dins_Fire or item == Farores_Wind or item == Nayrus_Love or item == Lens_of_Truth", + "_is_adult_item(item)": "item == Bow or item == Megaton_Hammer or item == Iron_Boots or item == Hover_Boots or item == Hookshot or item == Longshot or item == Silver_Gauntlets or item == Golden_Gauntlets or item == Goron_Tunic or item == Zora_Tunic or item == Scarecrow or item == Distant_Scarecrow or item == Mirror_Shield", + "_is_child_item(item)": "item == Slingshot or item == Boomerang or item == Kokiri_Sword or item == Sticks or item == Deku_Shield", + "_is_magic_arrow(item)": "item == Fire_Arrows or item == Light_Arrows", + + # Biggoron's trade path + # ER with certain settings disables timers and prevents items from reverting on save warp. + # Otherwise, to get to Biggoron requires: a trick, clearing boulders on DMT, or Darunia's Chamber + "guarantee_trade_path": "disable_trade_revert or can_blast_or_smash or 'Stop GC Rolling Goron as Adult' or (logic_dmt_climb_hovers and can_use(Hover_Boots)) or (logic_biggoron_bolero and not warp_songs and can_play(Bolero_of_Fire) and at('DMC Central Local', can_use(Hookshot) or can_use(Hover_Boots) or can_plant_bean))", + "guarantee_hint": "(hints == 'mask' and Mask_of_Truth) or (hints == 'agony' and Stone_of_Agony) or (hints != 'mask' and hints != 'agony')", + "has_fire_source": "can_use(Dins_Fire) or can_use(Fire_Arrows)", + "has_fire_source_with_torch": "has_fire_source or (is_child and Sticks)", + + # Gerudo Fortress + "can_finish_GerudoFortress": "(gerudo_fortress == 'normal' and (Small_Key_Gerudo_Fortress, 4) and (is_adult or Kokiri_Sword or is_glitched) and (is_adult and (Bow or Hookshot or Hover_Boots) or Gerudo_Membership_Card or logic_gerudo_kitchen or is_glitched)) + or (gerudo_fortress == 'fast' and Small_Key_Gerudo_Fortress and (is_adult or Kokiri_Sword or is_glitched)) + or (gerudo_fortress != 'normal' and gerudo_fortress != 'fast')", + # Mirror shield does not count because it cannot reflect scrub attack. + "has_shield": "(is_adult and Hylian_Shield) or (is_child and Deku_Shield)", + "can_shield": "(is_adult and (Hylian_Shield or Mirror_Shield)) or (is_child and Deku_Shield)", + "can_mega": "has_explosives and can_shield", + "can_isg": "can_shield and (is_adult or Sticks or Kokiri_Sword)", + "can_hover": "can_mega and can_isg", + "can_weirdshot": "can_mega and can_use(Hookshot)", + "can_jumpslash": "is_adult or Sticks or Kokiri_Sword", + + # Bridge Requirements + "has_all_stones": "Kokiri_Emerald and Goron_Ruby and Zora_Sapphire", + "has_all_medallions": "Forest_Medallion and Fire_Medallion and Water_Medallion and Shadow_Medallion and Spirit_Medallion and Light_Medallion", + "can_build_rainbow_bridge": "( + (bridge == 'open') or + (bridge == 'vanilla' and Shadow_Medallion and Spirit_Medallion and Light_Arrows) or + (bridge == 'stones' and _oot_has_stones(bridge_stones)) or + (bridge == 'medallions' and _oot_has_medallions(bridge_medallions)) or + (bridge == 'dungeons' and _oot_has_dungeon_rewards(bridge_rewards)) or + (bridge == 'tokens' and (Gold_Skulltula_Token, bridge_tokens)))", + "can_trigger_lacs": "( + (lacs_condition == 'vanilla' and Shadow_Medallion and Spirit_Medallion) or + (lacs_condition == 'stones' and _oot_has_stones(lacs_stones)) or + (lacs_condition == 'medallions' and _oot_has_medallions(lacs_medallions)) or + (lacs_condition == 'dungeons' and _oot_has_dungeon_rewards(lacs_rewards)) or + (lacs_condition == 'tokens' and (Gold_Skulltula_Token, lacs_tokens)))" +} diff --git a/worlds/oot/data/World/Bottom of the Well MQ.json b/worlds/oot/data/World/Bottom of the Well MQ.json new file mode 100644 index 00000000..e5644f62 --- /dev/null +++ b/worlds/oot/data/World/Bottom of the Well MQ.json @@ -0,0 +1,44 @@ +[ + { + "region_name": "Bottom of the Well", + "dungeon": "Bottom of the Well", + "exits": { + "Kakariko Village": "True", + "Bottom of the Well Perimeter": "is_child" + } + }, + { + "region_name": "Bottom of the Well Perimeter", + "dungeon": "Bottom of the Well", + "locations": { + "Bottom of the Well MQ Compass Chest": " + Kokiri_Sword or (Sticks and logic_child_deadhand)", + "Bottom of the Well MQ Dead Hand Freestanding Key": " + has_explosives or (logic_botw_mq_dead_hand_key and Boomerang)", + "Bottom of the Well MQ GS Basement": "can_child_attack", + "Bottom of the Well MQ GS Coffin Room": " + can_child_attack and (Small_Key_Bottom_of_the_Well, 2)", + "Wall Fairy": "has_bottle and Slingshot" # The fairy pot is obsolete + }, + "exits": { + "Bottom of the Well": "True", + "Bottom of the Well Middle": " + can_play(Zeldas_Lullaby) or (logic_botw_mq_pits and has_explosives)" + } + }, + { + "region_name": "Bottom of the Well Middle", + "dungeon": "Bottom of the Well", + "locations": { + "Bottom of the Well MQ Map Chest": "True", + "Bottom of the Well MQ Lens of Truth Chest": " + has_explosives and (Small_Key_Bottom_of_the_Well, 2)", + "Bottom of the Well MQ East Inner Room Freestanding Key": "True", + "Bottom of the Well MQ GS West Inner Room": " + can_child_attack and (logic_botw_mq_pits or has_explosives)" + }, + "exits": { + "Bottom of the Well Perimeter": "True" + } + } +] diff --git a/worlds/oot/data/World/Bottom of the Well.json b/worlds/oot/data/World/Bottom of the Well.json new file mode 100644 index 00000000..47fd8962 --- /dev/null +++ b/worlds/oot/data/World/Bottom of the Well.json @@ -0,0 +1,53 @@ +[ + { + "region_name": "Bottom of the Well", + "dungeon": "Bottom of the Well", + "exits": { + "Kakariko Village": "True", + "Bottom of the Well Main Area" : "is_child and (can_child_attack or Nuts)" + } + }, + { + "region_name": "Bottom of the Well Main Area", + "dungeon": "Bottom of the Well", + "locations": { + "Bottom of the Well Front Left Fake Wall Chest": "logic_lens_botw or can_use(Lens_of_Truth)", + "Bottom of the Well Front Center Bombable Chest": "has_explosives", + "Bottom of the Well Right Bottom Fake Wall Chest": "logic_lens_botw or can_use(Lens_of_Truth)", + "Bottom of the Well Compass Chest": "logic_lens_botw or can_use(Lens_of_Truth)", + "Bottom of the Well Center Skulltula Chest": "logic_lens_botw or can_use(Lens_of_Truth)", + "Bottom of the Well Back Left Bombable Chest": "has_explosives and (logic_lens_botw or can_use(Lens_of_Truth))", + "Bottom of the Well Freestanding Key": "Sticks or can_use(Dins_Fire)", + "Bottom of the Well Lens of Truth Chest": " + can_play(Zeldas_Lullaby) and + (Kokiri_Sword or (Sticks and logic_child_deadhand))", + #Sword not strictly necessary but frankly being forced to do this with sticks isn't fair + "Bottom of the Well Invisible Chest": "can_play(Zeldas_Lullaby) and (logic_lens_botw or can_use(Lens_of_Truth))", + "Bottom of the Well Underwater Front Chest": "can_play(Zeldas_Lullaby)", + "Bottom of the Well Underwater Left Chest": "can_play(Zeldas_Lullaby)", + "Bottom of the Well Map Chest": " + has_explosives or + ((((Small_Key_Bottom_of_the_Well, 3) and (logic_lens_botw or can_use(Lens_of_Truth))) or + can_use(Dins_Fire) or (logic_botw_basement and Sticks)) and + Progressive_Strength_Upgrade)", + "Bottom of the Well Fire Keese Chest": " + (Small_Key_Bottom_of_the_Well, 3) and (logic_lens_botw or can_use(Lens_of_Truth))", #These pits are really unfair. + "Bottom of the Well Like Like Chest": " + (Small_Key_Bottom_of_the_Well, 3) and (logic_lens_botw or can_use(Lens_of_Truth))", + "Bottom of the Well GS West Inner Room": " + Boomerang and (logic_lens_botw or can_use(Lens_of_Truth)) and + (Small_Key_Bottom_of_the_Well, 3)", + "Bottom of the Well GS East Inner Room": " + Boomerang and (logic_lens_botw or can_use(Lens_of_Truth)) and + (Small_Key_Bottom_of_the_Well, 3)", + "Bottom of the Well GS Like Like Cage": " + Boomerang and (logic_lens_botw or can_use(Lens_of_Truth)) and + (Small_Key_Bottom_of_the_Well, 3)", + "Stick Pot": "True", + "Nut Pot": "True" + }, + "exits": { + "Bottom of the Well" : "True" + } + } +] diff --git a/worlds/oot/data/World/Deku Tree MQ.json b/worlds/oot/data/World/Deku Tree MQ.json new file mode 100644 index 00000000..3fbafc35 --- /dev/null +++ b/worlds/oot/data/World/Deku Tree MQ.json @@ -0,0 +1,107 @@ +[ + { + "region_name": "Deku Tree Lobby", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ Map Chest": "True", + "Deku Tree MQ Slingshot Chest": "is_adult or can_child_attack", + "Deku Tree MQ Slingshot Room Back Chest": "has_fire_source_with_torch or can_use(Bow)", + "Deku Tree MQ Basement Chest": "has_fire_source_with_torch or can_use(Bow)", + "Deku Tree MQ GS Lobby": "is_adult or can_child_attack", + "Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang", + "Deku Baba Nuts": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword or can_use(Dins_Fire)" + }, + "exits": { + "KF Outside Deku Tree": "True", + "Deku Tree Compass Room": " + here(can_use(Slingshot) or can_use(Bow)) and + here(has_fire_source_with_torch or can_use(Bow))", + "Deku Tree Basement Water Room Front": " + here(can_use(Slingshot) or can_use(Bow)) and here(has_fire_source_with_torch)", + "Deku Tree Basement Ledge": "logic_deku_b1_skip or here(is_adult)" + } + }, + { + "region_name": "Deku Tree Compass Room", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ Compass Chest": "True", + "Deku Tree MQ GS Compass Room": " + (can_use(Hookshot) or can_use(Boomerang)) and + here(has_bombchus or + (Bombs and (can_play(Song_of_Time) or is_adult)) or + (can_use(Hammer) and (can_play(Song_of_Time) or logic_deku_mq_compass_gs)))" + }, + "exits": { + "Deku Tree Lobby": "True" + } + }, + { + "region_name": "Deku Tree Basement Water Room Front", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ Before Spinning Log Chest": "True" + }, + "exits": { + "Deku Tree Basement Water Room Back": " + logic_deku_mq_log or (is_child and (Deku_Shield or Hylian_Shield)) or + can_use(Longshot) or (can_use(Hookshot) and can_use(Iron_Boots))", + "Deku Tree Lobby": "True" + } + }, + { + "region_name": "Deku Tree Basement Water Room Back", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ After Spinning Log Chest": "can_play(Song_of_Time)" + }, + "exits": { + "Deku Tree Basement Back Room": " + (here(can_use(Sticks) or can_use(Dins_Fire)) or + at('Deku Tree Basement Water Room Front', can_use(Fire_Arrows))) and + here(is_adult or Kokiri_Sword or can_use_projectile or (Nuts and Sticks))", + "Deku Tree Basement Water Room Front": "True" + } + }, + { + "region_name": "Deku Tree Basement Back Room", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ GS Basement Graves Room": " + can_use(Longshot) or + (can_play(Song_of_Time) and (can_use(Boomerang) or can_use(Hookshot)))", + "Deku Tree MQ GS Basement Back Room": " + here(has_fire_source_with_torch) and + (can_use(Hookshot) or can_use(Boomerang))" + }, + "exits": { + "Deku Tree Basement Ledge": "is_child", + "Deku Tree Basement Water Room Back": " + can_use(Kokiri_Sword) or can_use_projectile or (Nuts and can_use(Sticks))" + } + }, + { + "region_name": "Deku Tree Basement Ledge", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree MQ Deku Scrub": "can_stun_deku", + "Deku Tree Queen Gohma Heart": " + here(has_fire_source_with_torch) and here(has_shield) and + (is_adult or Kokiri_Sword or Sticks)", + "Queen Gohma": " + here(has_fire_source_with_torch) and here(has_shield) and + (is_adult or Kokiri_Sword or Sticks)" + }, + "events": { + "Deku Tree Clear": " + here(has_fire_source_with_torch) and here(has_shield) and + (is_adult or Kokiri_Sword or Sticks)" + }, + "exits" : { + "Deku Tree Basement Back Room": "is_child", + "Deku Tree Lobby": "True" + } + } +] diff --git a/worlds/oot/data/World/Deku Tree.json b/worlds/oot/data/World/Deku Tree.json new file mode 100644 index 00000000..8f1c8f67 --- /dev/null +++ b/worlds/oot/data/World/Deku Tree.json @@ -0,0 +1,74 @@ +[ + { + "region_name": "Deku Tree Lobby", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree Map Chest": "True", + "Deku Tree Compass Chest": "True", + "Deku Tree Compass Room Side Chest": "True", + "Deku Tree Basement Chest": "is_adult or can_child_attack or Nuts", + "Deku Tree GS Compass Room": "is_adult or can_child_attack", + "Deku Tree GS Basement Vines": " + can_use_projectile or can_use(Dins_Fire) or + (logic_deku_basement_gs and (is_adult or Sticks or Kokiri_Sword))", + "Deku Tree GS Basement Gate": "is_adult or can_child_attack", + "Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang", + "Deku Baba Nuts": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword or can_use(Dins_Fire)" + }, + "exits": { + "KF Outside Deku Tree": "True", + "Deku Tree Slingshot Room": "here(has_shield)", + "Deku Tree Basement Backroom": " + (here(has_fire_source_with_torch or can_use(Bow)) and + here(can_use(Slingshot) or can_use(Bow))) or + (is_child and (logic_deku_b1_skip or here(is_adult)))", + "Deku Tree Boss Room": " + here(has_fire_source_with_torch or + (logic_deku_b1_webs_with_bow and can_use(Bow))) and + (logic_deku_b1_skip or here(is_adult or can_use(Slingshot)))" + } + }, + { + "region_name": "Deku Tree Slingshot Room", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree Slingshot Chest": "True", + "Deku Tree Slingshot Room Side Chest": "True" + }, + "exits": { + "Deku Tree Lobby": "True" + } + }, + { + "region_name": "Deku Tree Basement Backroom", + "dungeon": "Deku Tree", + "locations": { + "Deku Tree GS Basement Back Room": " + here(has_fire_source_with_torch or can_use(Bow)) and + here(can_blast_or_smash) and + (can_use(Boomerang) or can_use(Hookshot))" + }, + "exits": { + "Deku Tree Lobby": "True" + } + }, + { + "region_name": "Deku Tree Boss Room", + "dungeon": "Deku Tree", + "events": { + "Deku Tree Clear": " + here(has_shield) and (is_adult or Kokiri_Sword or Sticks)" + }, + "locations": { + "Deku Tree Queen Gohma Heart": " + here(has_shield) and (is_adult or Kokiri_Sword or Sticks)", + "Queen Gohma": " + here(has_shield) and (is_adult or Kokiri_Sword or Sticks)" + }, + "exits": { + "Deku Tree Lobby": "True" + } + } +] diff --git a/worlds/oot/data/World/Dodongos Cavern MQ.json b/worlds/oot/data/World/Dodongos Cavern MQ.json new file mode 100644 index 00000000..298604be --- /dev/null +++ b/worlds/oot/data/World/Dodongos Cavern MQ.json @@ -0,0 +1,90 @@ +[ + { + "region_name": "Dodongos Cavern Beginning", + "dungeon": "Dodongos Cavern", + "exits": { + "Death Mountain": "True", + "Dodongos Cavern Lobby": " + here(can_blast_or_smash or Progressive_Strength_Upgrade)" + } + }, + { + "region_name": "Dodongos Cavern Lobby", + "dungeon": "Dodongos Cavern", + "locations": { + "Deku Baba Sticks": "is_adult or Kokiri_Sword or can_use(Boomerang)", + "Dodongos Cavern MQ Map Chest": "True", + "Dodongos Cavern MQ Compass Chest": "is_adult or can_child_attack or Nuts", + "Dodongos Cavern MQ Larvae Room Chest": "can_use(Sticks) or has_fire_source", + "Dodongos Cavern MQ Torch Puzzle Room Chest": " + can_blast_or_smash or can_use(Sticks) or can_use(Dins_Fire) or + (is_adult and (logic_dc_jump or Hover_Boots or Progressive_Hookshot))", + "Dodongos Cavern MQ GS Song of Time Block Room": " + can_play(Song_of_Time) and (can_child_attack or is_adult)", + "Dodongos Cavern MQ GS Larvae Room": "can_use(Sticks) or has_fire_source", + "Dodongos Cavern MQ GS Lizalfos Room": "can_blast_or_smash", + "Dodongos Cavern MQ Deku Scrub Lobby Rear": "can_stun_deku", + "Dodongos Cavern MQ Deku Scrub Lobby Front": "can_stun_deku", + "Dodongos Cavern MQ Deku Scrub Staircase": "can_stun_deku", + "Dodongos Cavern Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle" + }, + "exits": { + "Dodongos Cavern Lower Right Side": " + here(can_blast_or_smash or + ((can_use(Sticks) or can_use(Dins_Fire)) and can_take_damage))", + "Dodongos Cavern Bomb Bag Area": " + is_adult or (here(is_adult) and has_explosives) or + (logic_dc_mq_child_bombs and (Kokiri_Sword or Sticks) and can_take_damage)", + "Dodongos Cavern Boss Area": " + has_explosives or + (logic_dc_mq_eyes and Progressive_Strength_Upgrade and + (is_adult or logic_dc_mq_child_back) and + (here(can_use(Sticks)) or can_use(Dins_Fire) or + (is_adult and (logic_dc_jump or Hammer or Hover_Boots or Hookshot))))" + } + }, + { + "region_name": "Dodongos Cavern Lower Right Side", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos": "can_stun_deku" + }, + "exits": { + "Dodongos Cavern Bomb Bag Area": " + (here(can_use(Bow)) or Progressive_Strength_Upgrade or + can_use(Dins_Fire) or has_explosives) and + can_use(Slingshot)" + } + }, + { + "region_name": "Dodongos Cavern Bomb Bag Area", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern MQ Bomb Bag Chest": "True", + "Dodongos Cavern MQ GS Scrub Room": " + (here(can_use(Bow)) or Progressive_Strength_Upgrade or + can_use(Dins_Fire) or has_explosives) and + (can_use(Hookshot) or can_use(Boomerang))" + }, + "exits": { + "Dodongos Cavern Lower Right Side": "True" + } + }, + { + "region_name": "Dodongos Cavern Boss Area", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern MQ Under Grave Chest": "True", + "Dodongos Cavern Boss Room Chest": "True", + "Dodongos Cavern King Dodongo Heart": " + can_blast_or_smash and (Bombs or Progressive_Strength_Upgrade) and + (is_adult or Sticks or Kokiri_Sword)", + "King Dodongo": " + can_blast_or_smash and (Bombs or Progressive_Strength_Upgrade) and + (is_adult or Sticks or Kokiri_Sword)", + "Dodongos Cavern MQ GS Back Area": "True", + "Fairy Pot": "has_bottle" + } + } +] diff --git a/worlds/oot/data/World/Dodongos Cavern.json b/worlds/oot/data/World/Dodongos Cavern.json new file mode 100644 index 00000000..e45bfe0e --- /dev/null +++ b/worlds/oot/data/World/Dodongos Cavern.json @@ -0,0 +1,105 @@ +[ + { + "region_name": "Dodongos Cavern Beginning", + "dungeon": "Dodongos Cavern", + "exits": { + "Death Mountain": "True", + "Dodongos Cavern Lobby": " + here(can_blast_or_smash or Progressive_Strength_Upgrade)" + } + }, + { + "region_name": "Dodongos Cavern Lobby", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Map Chest": "True", + "Dodongos Cavern GS Side Room Near Lower Lizalfos": " + has_explosives or is_adult or Slingshot or + Boomerang or Sticks or Kokiri_Sword", + "Dodongos Cavern GS Scarecrow": " + can_use(Scarecrow) or can_use(Longshot) or + (logic_dc_scarecrow_gs and (is_adult or can_child_attack))", + "Dodongos Cavern Deku Scrub Side Room Near Dodongos": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword", + "Dodongos Cavern Deku Scrub Lobby": "True", + "Dodongos Cavern Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle" + }, + "exits": { + "Dodongos Cavern Beginning": "True", + "Dodongos Cavern Staircase Room": " + here(is_adult or Sticks or + (can_use(Dins_Fire) and (Slingshot or has_explosives or Kokiri_Sword)))", + "Dodongos Cavern Far Bridge": "at('Dodongos Cavern Far Bridge', True)" + } + }, + { + "region_name": "Dodongos Cavern Staircase Room", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Compass Chest": "True", + "Dodongos Cavern GS Vines Above Stairs": " + has_explosives or Progressive_Strength_Upgrade or can_use(Dins_Fire) or + (logic_dc_staircase and can_use(Bow)) or + (logic_dc_vines_gs and can_use(Longshot))" + }, + "exits": { + "Dodongos Cavern Lobby": "True", + "Dodongos Cavern Climb": " + has_explosives or Progressive_Strength_Upgrade or + can_use(Dins_Fire) or (logic_dc_staircase and can_use(Bow))" + } + }, + { + "region_name": "Dodongos Cavern Climb", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Bomb Flower Platform Chest": "True", + "Dodongos Cavern Deku Scrub Near Bomb Bag Right": " + can_blast_or_smash or + (logic_dc_scrub_room and is_adult and Progressive_Strength_Upgrade)", + "Dodongos Cavern Deku Scrub Near Bomb Bag Left": " + can_blast_or_smash or + (logic_dc_scrub_room and is_adult and Progressive_Strength_Upgrade)" + }, + "exits": { + "Dodongos Cavern Lobby": "True", + "Dodongos Cavern Far Bridge": " + (is_child and (Slingshot or + (logic_dc_slingshot_skip and (Sticks or has_explosives or Kokiri_Sword)))) or + (is_adult and (Bow or Hover_Boots or can_use(Longshot) or logic_dc_jump))" + } + }, + { + "region_name": "Dodongos Cavern Far Bridge", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Bomb Bag Chest": "True", + "Dodongos Cavern End of Bridge Chest": "can_blast_or_smash", + "Dodongos Cavern GS Alcove Above Stairs": "can_use(Hookshot) or can_use(Boomerang)" + }, + "exits": { + "Dodongos Cavern Boss Area": "has_explosives", + "Dodongos Cavern Lobby": "True" + } + }, + { + "region_name": "Dodongos Cavern Boss Area", + "dungeon": "Dodongos Cavern", + "locations": { + "Dodongos Cavern Boss Room Chest": "True", + "Dodongos Cavern King Dodongo Heart": " + (Bombs or Progressive_Strength_Upgrade) and + (is_adult or Sticks or Kokiri_Sword)", + "King Dodongo": " + (Bombs or Progressive_Strength_Upgrade) and + (is_adult or Sticks or Kokiri_Sword)", + "Dodongos Cavern GS Back Room": "True", + "Fairy Pot": "has_bottle" + }, + "exits": { + "Dodongos Cavern Lobby": "True" + } + } +] diff --git a/worlds/oot/data/World/Fire Temple MQ.json b/worlds/oot/data/World/Fire Temple MQ.json new file mode 100644 index 00000000..5e1e177d --- /dev/null +++ b/worlds/oot/data/World/Fire Temple MQ.json @@ -0,0 +1,114 @@ +[ + { + "region_name": "Fire Temple Lower", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Map Room Side Chest": " + is_adult or Kokiri_Sword or Sticks or Slingshot or Bombs or can_use(Dins_Fire)", + "Fire Temple MQ Near Boss Chest": " + (logic_fewer_tunic_requirements or can_use(Goron_Tunic)) and + (((can_use(Hover_Boots) or (logic_fire_mq_near_boss and can_use(Bow))) and has_fire_source) or + (can_use(Hookshot) and (can_use(Fire_Arrows) or + (can_use(Dins_Fire) and + ((damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or + can_use(Goron_Tunic) or can_use(Bow) or can_use(Longshot))))))" + }, + "exits": { + "DMC Fire Temple Entrance": "True", + "Fire Boss Room": " + can_use(Goron_Tunic) and can_use(Megaton_Hammer) and Boss_Key_Fire_Temple and + ((has_fire_source and (logic_fire_boss_door_jump or Hover_Boots)) or at('Fire Temple Upper', True))", + "Fire Lower Locked Door": "(Small_Key_Fire_Temple, 5) and (is_adult or Kokiri_Sword)", + "Fire Big Lava Room": " + (logic_fewer_tunic_requirements or can_use(Goron_Tunic)) and can_use(Megaton_Hammer)" + } + }, + { + "region_name": "Fire Lower Locked Door", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Megaton Hammer Chest": "is_adult and (has_explosives or Megaton_Hammer or Hookshot)", + "Fire Temple MQ Map Chest": "can_use(Megaton_Hammer)", + "Fairy Pot": "has_bottle" + } + }, + { + "region_name": "Fire Big Lava Room", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Boss Key Chest": " + has_fire_source and (Bow or logic_fire_mq_bk_chest) and can_use(Hookshot)", + "Fire Temple MQ Big Lava Room Blocked Door Chest": " + has_fire_source and has_explosives and + (can_use(Hookshot) or logic_fire_mq_blocked_chest)", + "Fire Temple MQ GS Big Lava Room Open Door": "True", + "Fairy Pot": " + has_bottle and has_fire_source and (Bow or logic_fire_mq_bk_chest) and + (can_use(Hookshot) or logic_fire_song_of_time)" + + }, + "exits": { + "Fire Lower Maze": " + can_use(Goron_Tunic) and (Small_Key_Fire_Temple, 2) and + (has_fire_source or (logic_fire_mq_climb and Hover_Boots))" + } + }, + { + "region_name": "Fire Lower Maze", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Lizalfos Maze Lower Chest": "True", + "Fire Temple MQ Lizalfos Maze Side Room Chest": " + has_explosives and (logic_fire_mq_maze_side_room or at('Fire Upper Maze', True))" + }, + "exits": { + "Fire Upper Maze": " + ((has_explosives or logic_rusted_switches) and can_use(Hookshot)) or + (logic_fire_mq_maze_hovers and can_use(Hover_Boots)) or logic_fire_mq_maze_jump" + } + }, + { + "region_name": "Fire Upper Maze", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Lizalfos Maze Upper Chest": "True", + "Fire Temple MQ Compass Chest": "has_explosives", + "Fire Temple MQ GS Skull On Fire": " + (can_play(Song_of_Time) and can_use(Hookshot) and (has_explosives or logic_rusted_switches)) or + can_use(Longshot)", + "Wall Fairy": " + has_bottle and + ((can_play(Song_of_Time) and can_use(Hookshot) and (has_explosives or logic_rusted_switches)) or + can_use(Longshot))", + "Fairy Pot": "has_bottle and (Small_Key_Fire_Temple, 3)" + }, + "exits": { + "Fire Temple Upper": " + (Small_Key_Fire_Temple, 3) and + ((can_use(Bow) and can_use(Hookshot)) or can_use(Fire_Arrows))" + } + }, + { + "region_name": "Fire Temple Upper", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple MQ Freestanding Key": "can_use(Hookshot) or logic_fire_mq_flame_maze", + "Fire Temple MQ Chest On Fire": " + (can_use(Hookshot) or logic_fire_mq_flame_maze) and (Small_Key_Fire_Temple, 4)", + "Fire Temple MQ GS Fire Wall Maze Side Room": " + can_play(Song_of_Time) or Hover_Boots or logic_fire_mq_flame_maze", + "Fire Temple MQ GS Fire Wall Maze Center": "has_explosives", + "Fire Temple MQ GS Above Fire Wall Maze": " + (can_use(Hookshot) and (Small_Key_Fire_Temple, 5)) or + (logic_fire_mq_above_maze_gs and can_use(Longshot))" + } + }, + { + "region_name": "Fire Boss Room", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Volvagia Heart": "True", + "Volvagia": "True" + } + } +] diff --git a/worlds/oot/data/World/Fire Temple.json b/worlds/oot/data/World/Fire Temple.json new file mode 100644 index 00000000..dfc8f2d3 --- /dev/null +++ b/worlds/oot/data/World/Fire Temple.json @@ -0,0 +1,91 @@ +[ + { + "region_name": "Fire Temple Lower", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Near Boss Chest" : " + logic_fewer_tunic_requirements or can_use(Goron_Tunic)", + "Fire Temple Flare Dancer Chest": " + ((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)", + "Fire Temple Boss Key Chest": " + ((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)", + "Fire Temple Volvagia Heart": " + can_use(Goron_Tunic) and can_use(Megaton_Hammer) and Boss_Key_Fire_Temple and + (logic_fire_boss_door_jump or Hover_Boots or + at('Fire Temple Upper', can_play(Song_of_Time) or has_explosives))", + "Volvagia": " + can_use(Goron_Tunic) and can_use(Megaton_Hammer) and Boss_Key_Fire_Temple and + (logic_fire_boss_door_jump or Hover_Boots or + at('Fire Temple Upper', can_play(Song_of_Time) or has_explosives))", + "Fire Temple GS Boss Key Loop": " + ((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)", + "Fairy Pot": " + has_bottle and (can_use(Hover_Boots) or can_use(Hookshot)) and + (logic_fewer_tunic_requirements or can_use(Goron_Tunic))" + }, + "exits": { + "DMC Fire Temple Entrance": "True", + "Fire Temple Big Lava Room":" + (Small_Key_Fire_Temple, 2) and + (logic_fewer_tunic_requirements or can_use(Goron_Tunic))" + } + }, + { + "region_name": "Fire Temple Big Lava Room", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Big Lava Room Lower Open Door Chest": "True", + "Fire Temple Big Lava Room Blocked Door Chest": "is_adult and has_explosives", + "Fire Temple GS Song of Time Room": " + is_adult and (can_play(Song_of_Time) or logic_fire_song_of_time)" + }, + "exits": { + "Fire Temple Lower": "True", + "Fire Temple Middle": " + can_use(Goron_Tunic) and (Small_Key_Fire_Temple, 4) and + (Progressive_Strength_Upgrade or logic_fire_strength) and + (has_explosives or Bow or Progressive_Hookshot)" + } + }, + { + "region_name": "Fire Temple Middle", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Boulder Maze Lower Chest": "True", + "Fire Temple Boulder Maze Upper Chest": "(Small_Key_Fire_Temple, 6)", + "Fire Temple Boulder Maze Side Room Chest": "True", + "Fire Temple Boulder Maze Shortcut Chest": " + (Small_Key_Fire_Temple, 6) and has_explosives", + "Fire Temple Scarecrow Chest": " + (Small_Key_Fire_Temple, 6) and + (can_use(Scarecrow) or (logic_fire_scarecrow and can_use(Longshot)))", + "Fire Temple Map Chest": " + (Small_Key_Fire_Temple, 6) or ((Small_Key_Fire_Temple, 5) and can_use(Bow))", + "Fire Temple Compass Chest": "(Small_Key_Fire_Temple, 7)", + "Fire Temple GS Boulder Maze": "(Small_Key_Fire_Temple, 4) and has_explosives", + "Fire Temple GS Scarecrow Climb": " + (Small_Key_Fire_Temple, 6) and + (can_use(Scarecrow) or (logic_fire_scarecrow and can_use(Longshot)))", + "Fire Temple GS Scarecrow Top": " + (Small_Key_Fire_Temple, 6) and + (can_use(Scarecrow) or (logic_fire_scarecrow and can_use(Longshot)))" + }, + "exits": { + "Fire Temple Upper": " + (Small_Key_Fire_Temple, 8) or + ((Small_Key_Fire_Temple, 7) and + ((can_use(Hover_Boots) and can_use(Megaton_Hammer)) or logic_fire_flame_maze))" + } + }, + { + "region_name": "Fire Temple Upper", + "dungeon": "Fire Temple", + "locations": { + "Fire Temple Highest Goron Chest": " + can_use(Megaton_Hammer) and + (can_play(Song_of_Time) or (logic_rusted_switches and + (can_use(Hover_Boots) or has_explosives)))", + "Fire Temple Megaton Hammer Chest": "has_explosives" + } + } +] diff --git a/worlds/oot/data/World/Forest Temple MQ.json b/worlds/oot/data/World/Forest Temple MQ.json new file mode 100644 index 00000000..a2594122 --- /dev/null +++ b/worlds/oot/data/World/Forest Temple MQ.json @@ -0,0 +1,167 @@ +[ + { + "region_name": "Forest Temple Lobby", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ First Room Chest": " + is_adult or Bombs or can_use(Sticks) or Nuts or can_use(Boomerang) or + can_use(Dins_Fire) or Kokiri_Sword or can_use(Slingshot)", + "Forest Temple MQ GS First Hallway": "can_use(Hookshot) or can_use(Boomerang)" + }, + "exits": { + "SFM Forest Temple Entrance Ledge": "True", + "Forest Temple Central Area": " + (Small_Key_Forest_Temple, 1) and (is_adult or can_child_attack or Nuts)" + } + }, + { + "region_name": "Forest Temple Central Area", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Wolfos Chest": " + (can_play(Song_of_Time) or is_child) and + (is_adult or can_use(Dins_Fire) or + can_use(Sticks) or can_use(Slingshot) or Kokiri_Sword)", + "Forest Temple MQ GS Block Push Room": "is_adult or Kokiri_Sword", + "Fairy Pot": "has_bottle and (can_play(Song_of_Time) or is_child)" + }, + "exits": { + "Forest Temple NW Outdoors": "can_use(Bow) or can_use(Slingshot)", + "Forest Temple NE Outdoors": "can_use(Bow) or can_use(Slingshot)", + # End of the road for child + "Forest Temple After Block Puzzle": " + is_adult and (Progressive_Strength_Upgrade or + (logic_forest_mq_block_puzzle and has_bombchus and can_use(Hookshot)))", + "Forest Temple Outdoor Ledge": " + (logic_forest_mq_hallway_switch_jumpslash and can_use(Hover_Boots)) or + (logic_forest_mq_hallway_switch_hookshot and can_use(Hookshot))", + "Forest Temple Boss Region": " + Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg" + } + }, + { + "region_name": "Forest Temple After Block Puzzle", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Boss Key Chest": "(Small_Key_Forest_Temple, 3)" + }, + "exits": { + "Forest Temple Bow Region": "(Small_Key_Forest_Temple, 4)", + "Forest Temple Outdoor Ledge": " + (Small_Key_Forest_Temple, 3) or + (logic_forest_mq_hallway_switch_jumpslash and + (can_use(Hookshot) or logic_forest_outside_backdoor))", + "Forest Temple NW Outdoors": "(Small_Key_Forest_Temple, 2)" + # Only 2 keys because you must have had access to falling ceiling room to have wasted a key there + # and access to falling ceiling room means you must also have had to access to the lower area of this courtyard + } + }, + { + "region_name": "Forest Temple Outdoor Ledge", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Redead Chest": "True" + }, + "exits": { + "Forest Temple NW Outdoors": "True" + } + }, + { + "region_name": "Forest Temple NW Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ GS Level Island Courtyard": "True" + }, + "exits": { + "Forest Temple NE Outdoors": " + can_use(Iron_Boots) or can_use(Longshot) or + (Progressive_Scale, 2) or (logic_forest_well_swim and can_use(Hookshot))", + "Forest Temple Outdoors Top Ledges": "can_use(Fire_Arrows)" + } + }, + { + "region_name": "Forest Temple NE Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Well Chest": "can_use(Bow) or can_use(Slingshot)", + "Forest Temple MQ GS Raised Island Courtyard": " + can_use(Hookshot) or can_use(Boomerang) or + (can_use(Fire_Arrows) and + (can_play(Song_of_Time) or (can_use(Hover_Boots) and logic_forest_door_frame)))", + "Forest Temple MQ GS Well": " + (can_use(Iron_Boots) and can_use(Hookshot)) or can_use(Bow) or can_use(Slingshot)", + "Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang", + "Deku Baba Nuts": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword or can_use(Dins_Fire)" + }, + "exits": { + "Forest Temple Outdoors Top Ledges": " + can_use(Hookshot) and + (can_use(Longshot) or can_use(Hover_Boots) or can_play(Song_of_Time) or + logic_forest_vines)", + "Forest Temple NE Outdoors Ledge": "can_use(Longshot)" + } + }, + { + "region_name": "Forest Temple Outdoors Top Ledges", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Raised Island Courtyard Upper Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors": "True", + "Forest Temple NE Outdoors Ledge": "logic_forest_outdoors_ledge and can_use(Hover_Boots)" + } + }, + { + "region_name": "Forest Temple NE Outdoors Ledge", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Raised Island Courtyard Lower Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors": "True", + "Forest Temple Falling Room": "can_play(Song_of_Time)" + } + }, + { + "region_name": "Forest Temple Bow Region", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Jo and Beth": "can_use(Bow)" + }, + "locations": { + "Forest Temple MQ Bow Chest": "True", + "Forest Temple MQ Map Chest": "can_use(Bow)", + "Forest Temple MQ Compass Chest": "can_use(Bow)" + }, + "exits": { + "Forest Temple Falling Room": " + (Small_Key_Forest_Temple, 5) and (can_use(Bow) or can_use(Dins_Fire))" + # Only 5 keys because you must have had access to falling ceiling room to have wasted a key there + } + }, + { + "region_name": "Forest Temple Falling Room", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Amy and Meg": "can_use(Bow) and (Small_Key_Forest_Temple, 6)" + }, + "locations": { + "Forest Temple MQ Falling Ceiling Room Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors Ledge": "True" + } + }, + { + "region_name": "Forest Temple Boss Region", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple MQ Basement Chest": "True", + "Forest Temple Phantom Ganon Heart": "Boss_Key_Forest_Temple", + "Phantom Ganon": "Boss_Key_Forest_Temple" + } + } +] diff --git a/worlds/oot/data/World/Forest Temple.json b/worlds/oot/data/World/Forest Temple.json new file mode 100644 index 00000000..6381a3fc --- /dev/null +++ b/worlds/oot/data/World/Forest Temple.json @@ -0,0 +1,158 @@ +[ + { + "region_name": "Forest Temple Lobby", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple First Room Chest": "True", + "Forest Temple First Stalfos Chest": "is_adult or Kokiri_Sword", + "Forest Temple GS First Room": " + (is_adult and (Hookshot or Bow or Bombs)) or (is_child and (Boomerang or Slingshot)) or + has_bombchus or can_use(Dins_Fire) or (logic_forest_first_gs and (Bombs or + (can_jumpslash and can_take_damage)))", + "Forest Temple GS Lobby": "can_use(Hookshot) or can_use(Boomerang)", + "Fairy Pot": "has_bottle and (is_adult or can_child_attack or Nuts)" + }, + "exits": { + "SFM Forest Temple Entrance Ledge": "True", + "Forest Temple NW Outdoors": "can_play(Song_of_Time) or is_child", + "Forest Temple NE Outdoors": "can_use(Bow) or can_use(Slingshot)", + "Forest Temple Block Push Room": "(Small_Key_Forest_Temple, 1)", + "Forest Temple Boss Region": "Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg" + } + }, + { + "region_name": "Forest Temple NW Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple GS Level Island Courtyard": " + can_use(Longshot) or + at('Forest Temple Outside Upper Ledge', can_use(Hookshot))", + "Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang", + "Deku Baba Nuts": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword or can_use(Dins_Fire)" + }, + "exits": { + "Forest Temple NE Outdoors": "(Progressive_Scale, 2)", + #Other methods of crossing through the well are not currently relevant. + "Forest Temple Outdoors High Balconies": " + here(is_adult or has_explosives or + ((Boomerang or Nuts or Deku_Shield) and + (Sticks or Kokiri_Sword or Slingshot)))" + } + }, + { + "region_name": "Forest Temple NE Outdoors", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Raised Island Courtyard Chest": " + can_use(Hookshot) or + at('Forest Temple Falling Room', True) or + (logic_forest_outdoors_ledge and can_use(Hover_Boots) and at('Forest Temple Outdoors High Balconies', True))", + "Forest Temple GS Raised Island Courtyard": " + can_use(Hookshot) or (logic_forest_outdoor_east_gs and can_use(Boomerang)) or + at('Forest Temple Falling Room', can_use(Bow) or can_use(Dins_Fire) or has_explosives)", + "Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang", + "Deku Baba Nuts": " + is_adult or Slingshot or Sticks or + has_explosives or Kokiri_Sword or can_use(Dins_Fire)" + }, + "exits": { + "Forest Temple Outdoors High Balconies": " + can_use(Longshot) or (logic_forest_vines and can_use(Hookshot))", + #Longshot can grab some very high up vines to drain the well. + "Forest Temple NW Outdoors": "can_use(Iron_Boots) or (Progressive_Scale, 2)", + "Forest Temple Lobby": "True" + } + }, + { + "region_name": "Forest Temple Outdoors High Balconies", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Well Chest": "True", + "Forest Temple Map Chest": "True" + }, + "exits": { + "Forest Temple NW Outdoors": "True", + "Forest Temple NE Outdoors": "True", + "Forest Temple Falling Room": " + logic_forest_door_frame and can_use(Hover_Boots) and can_use(Scarecrow)" + } + }, + { + "region_name": "Forest Temple Falling Room", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Amy and Meg": "can_use(Bow)" + }, + "locations": { + "Forest Temple Falling Ceiling Room Chest": "True" + }, + "exits": { + "Forest Temple NE Outdoors": "True" + } + }, + { + "region_name": "Forest Temple Block Push Room", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Eye Switch Chest": " + Progressive_Strength_Upgrade and (can_use(Bow) or can_use(Slingshot))" + }, + "exits": { + #end of the road for child forest. No hovers and too short to climb push blocks + "Forest Temple Outside Upper Ledge": " + can_use(Hover_Boots) or (logic_forest_outside_backdoor and is_adult and Progressive_Strength_Upgrade)", + "Forest Temple Bow Region": " + Progressive_Strength_Upgrade and (Small_Key_Forest_Temple, 3) and is_adult", + "Forest Temple Straightened Hall": " + Progressive_Strength_Upgrade and (Small_Key_Forest_Temple, 2) and can_use(Bow)" + } + }, + { + "region_name": "Forest Temple Straightened Hall", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Boss Key Chest": "True" + }, + "exits": { + "Forest Temple Outside Upper Ledge": "True" + } + }, + { + "region_name": "Forest Temple Outside Upper Ledge", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Floormaster Chest": "True" + }, + "exits": { + "Forest Temple NW Outdoors": "True" + } + }, + { + "region_name": "Forest Temple Bow Region", + "dungeon": "Forest Temple", + "events": { + "Forest Temple Jo and Beth": "can_use(Bow)" + }, + "locations": { + "Forest Temple Bow Chest": "True", + "Forest Temple Red Poe Chest": "can_use(Bow)", + "Forest Temple Blue Poe Chest": "can_use(Bow)" + }, + "exits": { + "Forest Temple Falling Room": " + (Small_Key_Forest_Temple, 5) and (Bow or can_use(Dins_Fire))" + } + }, + { + "region_name": "Forest Temple Boss Region", + "dungeon": "Forest Temple", + "locations": { + "Forest Temple Basement Chest": "True", + "Forest Temple Phantom Ganon Heart": "Boss_Key_Forest_Temple", + "Phantom Ganon": "Boss_Key_Forest_Temple", + "Forest Temple GS Basement": "can_use(Hookshot) or can_use(Boomerang)" + } + } +] diff --git a/worlds/oot/data/World/Ganons Castle MQ.json b/worlds/oot/data/World/Ganons Castle MQ.json new file mode 100644 index 00000000..72b8a9e8 --- /dev/null +++ b/worlds/oot/data/World/Ganons Castle MQ.json @@ -0,0 +1,130 @@ +[ + { + "region_name": "Ganons Castle Lobby", + "dungeon": "Ganons Castle", + "exits": { + "Castle Grounds": "True", + "Ganons Castle Forest Trial": "True", + "Ganons Castle Fire Trial": "True", + "Ganons Castle Water Trial": "True", + "Ganons Castle Shadow Trial": "True", + "Ganons Castle Spirit Trial": "True", + "Ganons Castle Light Trial": "can_use(Golden_Gauntlets)", + "Ganons Castle Tower": " + (skipped_trials[Forest] or 'Forest Trial Clear') and + (skipped_trials[Fire] or 'Fire Trial Clear') and + (skipped_trials[Water] or 'Water Trial Clear') and + (skipped_trials[Shadow] or 'Shadow Trial Clear') and + (skipped_trials[Spirit] or 'Spirit Trial Clear') and + (skipped_trials[Light] or 'Light Trial Clear')", + "Ganons Castle Deku Scrubs": "logic_lens_castle_mq or can_use(Lens_of_Truth)" + } + }, + { + "region_name": "Ganons Castle Deku Scrubs", + "dungeon": "Ganons Castle", + "locations": { + "Ganons Castle MQ Deku Scrub Center-Left": "True", + "Ganons Castle MQ Deku Scrub Center": "True", + "Ganons Castle MQ Deku Scrub Center-Right": "True", + "Ganons Castle MQ Deku Scrub Left": "True", + "Ganons Castle MQ Deku Scrub Right": "True", + "Free Fairies": "has_bottle" + } + }, + { + "region_name": "Ganons Castle Forest Trial", + "dungeon": "Ganons Castle", + "events": { + "Forest Trial Clear": "can_use(Light_Arrows) and can_play(Song_of_Time)" + }, + "locations": { + "Ganons Castle MQ Forest Trial Eye Switch Chest": "Bow", + "Ganons Castle MQ Forest Trial Frozen Eye Switch Chest": "has_fire_source", + "Ganons Castle MQ Forest Trial Freestanding Key": "Progressive_Hookshot" + } + }, + { + "region_name": "Ganons Castle Fire Trial", + "dungeon": "Ganons Castle", + "events": { + "Fire Trial Clear": " + can_use(Goron_Tunic) and can_use(Golden_Gauntlets) and can_use(Light_Arrows) and + (can_use(Longshot) or Hover_Boots or (logic_fire_trial_mq and can_use(Hookshot)))" + } + }, + { + "region_name": "Ganons Castle Water Trial", + "dungeon": "Ganons Castle", + "events": { + "Water Trial Clear": " + Blue_Fire and can_use(Light_Arrows) and + (Small_Key_Ganons_Castle, 3)" + }, + "locations": { + "Ganons Castle MQ Water Trial Chest": "Blue_Fire", + "Blue Fire": "has_bottle" + } + }, + { + "region_name": "Ganons Castle Shadow Trial", + "dungeon": "Ganons Castle", + "events": { + "Shadow Trial Clear": " + can_use(Light_Arrows) and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and + (Hover_Boots or (Progressive_Hookshot and (has_fire_source or logic_shadow_trial_mq)))" + }, + "locations": { + "Ganons Castle MQ Shadow Trial Bomb Flower Chest": " + (Bow and (Progressive_Hookshot or Hover_Boots)) or + (Hover_Boots and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and + (has_explosives or Progressive_Strength_Upgrade or can_use(Dins_Fire)))", + "Ganons Castle MQ Shadow Trial Eye Switch Chest": " + Bow and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and + (Hover_Boots or (Progressive_Hookshot and (has_fire_source or logic_shadow_trial_mq)))" + } + }, + { + "region_name": "Ganons Castle Spirit Trial", + "dungeon": "Ganons Castle", + "events": { + "Spirit Trial Clear": " + can_use(Light_Arrows) and Megaton_Hammer and + has_bombchus and Fire_Arrows and Mirror_Shield" + }, + "locations": { + "Ganons Castle MQ Spirit Trial First Chest": "(Bow or logic_rusted_switches) and Megaton_Hammer", + "Ganons Castle MQ Spirit Trial Invisible Chest": " + (Bow or logic_rusted_switches) and Megaton_Hammer and + has_bombchus and (logic_lens_castle_mq or can_use(Lens_of_Truth))", + "Ganons Castle MQ Spirit Trial Sun Front Left Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield", + "Ganons Castle MQ Spirit Trial Sun Back Left Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield", + "Ganons Castle MQ Spirit Trial Golden Gauntlets Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield", + "Ganons Castle MQ Spirit Trial Sun Back Right Chest": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield", + "Nut Pot": " + Megaton_Hammer and has_bombchus and + can_use(Fire_Arrows) and Mirror_Shield" + } + }, + { + "region_name": "Ganons Castle Light Trial", + "dungeon": "Ganons Castle", + "events": { + "Light Trial Clear": " + can_use(Light_Arrows) and (Small_Key_Ganons_Castle, 3) and + (logic_lens_castle_mq or can_use(Lens_of_Truth)) and + (Progressive_Hookshot or logic_light_trial_mq)" + }, + "locations": { + "Ganons Castle MQ Light Trial Lullaby Chest": "can_play(Zeldas_Lullaby)" + } + } +] diff --git a/worlds/oot/data/World/Ganons Castle.json b/worlds/oot/data/World/Ganons Castle.json new file mode 100644 index 00000000..0fd39515 --- /dev/null +++ b/worlds/oot/data/World/Ganons Castle.json @@ -0,0 +1,123 @@ +[ + { + "region_name": "Ganons Castle Lobby", + "dungeon": "Ganons Castle", + "exits": { + "Castle Grounds": "True", + "Ganons Castle Forest Trial": "True", + "Ganons Castle Fire Trial": "True", + "Ganons Castle Water Trial": "True", + "Ganons Castle Shadow Trial": "True", + "Ganons Castle Spirit Trial": "True", + "Ganons Castle Light Trial": "can_use(Golden_Gauntlets)", + "Ganons Castle Tower": " + (skipped_trials[Forest] or 'Forest Trial Clear') and + (skipped_trials[Fire] or 'Fire Trial Clear') and + (skipped_trials[Water] or 'Water Trial Clear') and + (skipped_trials[Shadow] or 'Shadow Trial Clear') and + (skipped_trials[Spirit] or 'Spirit Trial Clear') and + (skipped_trials[Light] or 'Light Trial Clear')", + "Ganons Castle Deku Scrubs": "logic_lens_castle or can_use(Lens_of_Truth)" + } + }, + { + "region_name": "Ganons Castle Deku Scrubs", + "dungeon": "Ganons Castle", + "locations": { + "Ganons Castle Deku Scrub Center-Left": "True", + "Ganons Castle Deku Scrub Center-Right": "True", + "Ganons Castle Deku Scrub Right": "True", + "Ganons Castle Deku Scrub Left": "True", + "Free Fairies": "has_bottle" + } + }, + { + "region_name": "Ganons Castle Forest Trial", + "dungeon": "Ganons Castle", + "events": { + "Forest Trial Clear": "can_use(Light_Arrows) and (Fire_Arrows or Dins_Fire)" + }, + "locations": { + "Ganons Castle Forest Trial Chest": "True" + } + }, + { + "region_name": "Ganons Castle Fire Trial", + "dungeon": "Ganons Castle", + "events": { + "Fire Trial Clear": " + can_use(Goron_Tunic) and can_use(Golden_Gauntlets) and + can_use(Light_Arrows) and can_use(Longshot)" + } + }, + { + "region_name": "Ganons Castle Water Trial", + "dungeon": "Ganons Castle", + "events": { + "Water Trial Clear": "Blue_Fire and Megaton_Hammer and can_use(Light_Arrows)" + }, + "locations": { + "Ganons Castle Water Trial Left Chest": "True", + "Ganons Castle Water Trial Right Chest": "True", + "Fairy Pot": "Blue_Fire and has_bottle", + "Blue Fire": "has_bottle" + } + }, + { + "region_name": "Ganons Castle Shadow Trial", + "dungeon": "Ganons Castle", + "events": { + "Shadow Trial Clear": " + can_use(Light_Arrows) and Megaton_Hammer and + ((Fire_Arrows and (logic_lens_castle or can_use(Lens_of_Truth))) or + (can_use(Longshot) and (Hover_Boots or (Dins_Fire and (logic_lens_castle or can_use(Lens_of_Truth))))))" + }, + "locations": { + "Ganons Castle Shadow Trial Front Chest": " + can_use(Fire_Arrows) or Progressive_Hookshot or + Hover_Boots or can_play(Song_of_Time)", + "Ganons Castle Shadow Trial Golden Gauntlets Chest": " + can_use(Fire_Arrows) or + (can_use(Longshot) and (Hover_Boots or can_use(Dins_Fire)))" + } + }, + { + "region_name": "Ganons Castle Spirit Trial", + "dungeon": "Ganons Castle", + "events": { + "Spirit Trial Clear": " + can_use(Light_Arrows) and Mirror_Shield and has_bombchus and + (logic_spirit_trial_hookshot or Progressive_Hookshot)" + }, + "locations": { + "Ganons Castle Spirit Trial Crystal Switch Chest": " + (logic_spirit_trial_hookshot or Progressive_Hookshot)", + "Ganons Castle Spirit Trial Invisible Chest": " + (logic_spirit_trial_hookshot or Progressive_Hookshot) and + has_bombchus and (logic_lens_castle or can_use(Lens_of_Truth))", + "Nut Pot": " + (logic_spirit_trial_hookshot or Progressive_Hookshot) and + has_bombchus and Bow and Mirror_Shield" + } + }, + { + "region_name": "Ganons Castle Light Trial", + "dungeon": "Ganons Castle", + "events": { + "Light Trial Clear": " + can_use(Light_Arrows) and Progressive_Hookshot and + (Small_Key_Ganons_Castle, 2) and (logic_lens_castle or can_use(Lens_of_Truth))" + }, + "locations": { + "Ganons Castle Light Trial First Left Chest": "True", + "Ganons Castle Light Trial Second Left Chest": "True", + "Ganons Castle Light Trial Third Left Chest": "True", + "Ganons Castle Light Trial First Right Chest": "True", + "Ganons Castle Light Trial Second Right Chest": "True", + "Ganons Castle Light Trial Third Right Chest": "True", + "Ganons Castle Light Trial Invisible Enemies Chest": "logic_lens_castle or can_use(Lens_of_Truth)", + "Ganons Castle Light Trial Lullaby Chest": " + can_play(Zeldas_Lullaby) and (Small_Key_Ganons_Castle, 1)" + } + } +] diff --git a/worlds/oot/data/World/Gerudo Training Grounds MQ.json b/worlds/oot/data/World/Gerudo Training Grounds MQ.json new file mode 100644 index 00000000..34dc2f2f --- /dev/null +++ b/worlds/oot/data/World/Gerudo Training Grounds MQ.json @@ -0,0 +1,98 @@ +[ + { + "region_name": "Gerudo Training Grounds Lobby", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Lobby Left Chest": "True", + "Gerudo Training Grounds MQ Lobby Right Chest": "True", + "Gerudo Training Grounds MQ Hidden Ceiling Chest": "logic_lens_gtg_mq or can_use(Lens_of_Truth)", + "Gerudo Training Grounds MQ Maze Path First Chest": "True", + "Gerudo Training Grounds MQ Maze Path Second Chest": "True", + "Gerudo Training Grounds MQ Maze Path Third Chest": "(Small_Key_Gerudo_Training_Grounds, 1)" + }, + "exits": { + "Gerudo Fortress": "True", + "Gerudo Training Grounds Left Side": "here(has_fire_source)", + "Gerudo Training Grounds Right Side": "here(can_use(Bow) or can_use(Slingshot))" + } + }, + { + "region_name": "Gerudo Training Grounds Right Side", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Dinolfos Chest": "is_adult", + "Wall Fairy": "has_bottle and can_use(Bow)" #in the Dinalfos room shoot the Gerudo symbol above the door to the lava room. + }, + "exits": { + # Still requires has_fire_source in the room + "Gerudo Training Grounds Underwater": " + (Bow or can_use(Longshot)) and can_use(Hover_Boots)" + } + }, + { + "region_name": "Gerudo Training Grounds Underwater", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Underwater Silver Rupee Chest": " + has_fire_source and can_use(Iron_Boots) and + (logic_fewer_tunic_requirements or can_use(Zora_Tunic)) and can_take_damage" + } + }, + { + "region_name": "Gerudo Training Grounds Left Side", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ First Iron Knuckle Chest": "is_adult or Kokiri_Sword or has_explosives" + }, + "exits": { + "Gerudo Training Grounds Stalfos Room": " + can_use(Longshot) or logic_gtg_mq_without_hookshot or + (logic_gtg_mq_with_hookshot and can_use(Hookshot))" + } + }, + { + "region_name": "Gerudo Training Grounds Stalfos Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + # Very difficult to fight the Stalfos and Stulltulas under the time limit as child. + "Gerudo Training Grounds MQ Before Heavy Block Chest": "is_adult", + "Gerudo Training Grounds MQ Heavy Block Chest": "can_use(Silver_Gauntlets)", + "Blue Fire": "has_bottle" + }, + "exits": { + "Gerudo Training Grounds Back Areas": " + is_adult and (logic_lens_gtg_mq or can_use(Lens_of_Truth)) and Blue_Fire and + (can_play(Song_of_Time) or (logic_gtg_fake_wall and can_use(Hover_Boots)))" + } + }, + { + "region_name": "Gerudo Training Grounds Back Areas", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Eye Statue Chest": "Bow", + "Gerudo Training Grounds MQ Second Iron Knuckle Chest": "True", + "Gerudo Training Grounds MQ Flame Circle Chest": "can_use(Hookshot) or Bow or has_explosives" + }, + "exits": { + "Gerudo Training Grounds Central Maze Right": "Megaton_Hammer", + "Gerudo Training Grounds Right Side": "can_use(Longshot)" + } + }, + { + "region_name": "Gerudo Training Grounds Central Maze Right", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds MQ Maze Right Central Chest": "True", + "Gerudo Training Grounds MQ Maze Right Side Chest": "True", + # The switch that opens the door to the Ice Arrows chest can be hit with a precise jumpslash. + "Gerudo Training Grounds MQ Ice Arrows Chest": " + (Small_Key_Gerudo_Training_Grounds, 3)" + }, + "exits": { + # guarantees fire with torch + "Gerudo Training Grounds Underwater": " + can_use(Longshot) or (can_use(Hookshot) and Bow)", + "Gerudo Training Grounds Right Side": "can_use(Hookshot)" + } + } +] diff --git a/worlds/oot/data/World/Gerudo Training Grounds.json b/worlds/oot/data/World/Gerudo Training Grounds.json new file mode 100644 index 00000000..a5b4f940 --- /dev/null +++ b/worlds/oot/data/World/Gerudo Training Grounds.json @@ -0,0 +1,120 @@ +[ + { + "region_name": "Gerudo Training Grounds Lobby", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Lobby Left Chest": "can_use(Bow) or can_use(Slingshot)", + "Gerudo Training Grounds Lobby Right Chest": "can_use(Bow) or can_use(Slingshot)", + "Gerudo Training Grounds Stalfos Chest": "is_adult or Kokiri_Sword", + "Gerudo Training Grounds Beamos Chest": "has_explosives and (is_adult or Kokiri_Sword)", + "Wall Fairy": "has_bottle and can_use(Bow)" #in the Beamos room shoot the Gerudo symbol above the door to the lava room. + }, + "exits": { + "Gerudo Fortress": "True", + "Gerudo Training Grounds Heavy Block Room": " + (is_adult or Kokiri_Sword) and + (can_use(Hookshot) or logic_gtg_without_hookshot)", + "Gerudo Training Grounds Lava Room": " + here(has_explosives and (is_adult or Kokiri_Sword))", + "Gerudo Training Grounds Central Maze": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Central Maze", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Hidden Ceiling Chest": "(Small_Key_Gerudo_Training_Grounds, 3) and (logic_lens_gtg or can_use(Lens_of_Truth))", + "Gerudo Training Grounds Maze Path First Chest": "(Small_Key_Gerudo_Training_Grounds, 4)", + "Gerudo Training Grounds Maze Path Second Chest": "(Small_Key_Gerudo_Training_Grounds, 6)", + "Gerudo Training Grounds Maze Path Third Chest": "(Small_Key_Gerudo_Training_Grounds, 7)", + "Gerudo Training Grounds Maze Path Final Chest": "(Small_Key_Gerudo_Training_Grounds, 9)" + }, + "exits": { + "Gerudo Training Grounds Central Maze Right": "(Small_Key_Gerudo_Training_Grounds, 9)" + } + }, + { + "region_name": "Gerudo Training Grounds Central Maze Right", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Maze Right Central Chest": "True", + "Gerudo Training Grounds Maze Right Side Chest": "True", + "Gerudo Training Grounds Freestanding Key": "True" + }, + "exits": { + "Gerudo Training Grounds Hammer Room": "can_use(Hookshot)", + "Gerudo Training Grounds Lava Room": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Lava Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Underwater Silver Rupee Chest": " + can_use(Hookshot) and can_play(Song_of_Time) and Iron_Boots and + (logic_fewer_tunic_requirements or can_use(Zora_Tunic))" + }, + "exits": { + "Gerudo Training Grounds Central Maze Right": "can_play(Song_of_Time) or is_child", + "Gerudo Training Grounds Hammer Room": " + can_use(Longshot) or (can_use(Hookshot) and can_use(Hover_Boots))" + } + }, + { + "region_name": "Gerudo Training Grounds Hammer Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Hammer Room Clear Chest": "True", + "Gerudo Training Grounds Hammer Room Switch Chest": "can_use(Megaton_Hammer)" + }, + "exits": { + "Gerudo Training Grounds Eye Statue Lower": "can_use(Megaton_Hammer) and Bow", + "Gerudo Training Grounds Lava Room": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Eye Statue Lower", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Eye Statue Chest": "can_use(Bow)" + }, + "exits": { + "Gerudo Training Grounds Hammer Room": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Eye Statue Upper", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Near Scarecrow Chest": "can_use(Bow)" + }, + "exits": { + "Gerudo Training Grounds Eye Statue Lower": "True" + } + }, + { + "region_name": "Gerudo Training Grounds Heavy Block Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Before Heavy Block Chest": "True" + }, + "exits": { + "Gerudo Training Grounds Eye Statue Upper": " + (logic_lens_gtg or can_use(Lens_of_Truth)) and + (can_use(Hookshot) or (logic_gtg_fake_wall and can_use(Hover_Boots)))", + "Gerudo Training Grounds Like Like Room": " + can_use(Silver_Gauntlets) and (logic_lens_gtg or can_use(Lens_of_Truth)) and + (can_use(Hookshot) or (logic_gtg_fake_wall and can_use(Hover_Boots)))" + } + }, + { + "region_name": "Gerudo Training Grounds Like Like Room", + "dungeon": "Gerudo Training Grounds", + "locations": { + "Gerudo Training Grounds Heavy Block First Chest": "True", + "Gerudo Training Grounds Heavy Block Second Chest": "True", + "Gerudo Training Grounds Heavy Block Third Chest": "True", + "Gerudo Training Grounds Heavy Block Fourth Chest": "True" + } + } +] diff --git a/worlds/oot/data/World/Ice Cavern MQ.json b/worlds/oot/data/World/Ice Cavern MQ.json new file mode 100644 index 00000000..e7d0f43c --- /dev/null +++ b/worlds/oot/data/World/Ice Cavern MQ.json @@ -0,0 +1,48 @@ +[ + { + "region_name": "Ice Cavern Beginning", + "dungeon": "Ice Cavern", + "locations": { + "Fairy Pot": "has_bottle" + }, + "exits": { + "ZF Ice Ledge": "True", + "Ice Cavern Map Room": " + is_adult or can_use(Dins_Fire) or + (has_explosives and (can_use(Sticks) or can_use(Slingshot) or Kokiri_Sword))", + "Ice Cavern Compass Room": "is_adult and Blue_Fire", + "Ice Cavern Iron Boots Region": "Blue_Fire" + } + }, + { + "region_name": "Ice Cavern Map Room", + "dungeon": "Ice Cavern", + "locations": { + "Ice Cavern MQ Map Chest": " + Blue_Fire and + (is_adult or can_use(Sticks) or Kokiri_Sword or can_use_projectile)", + "Blue Fire": "has_bottle" + } + }, + { + "region_name": "Ice Cavern Iron Boots Region", + "dungeon": "Ice Cavern", + "locations": { + "Ice Cavern MQ Iron Boots Chest": "is_adult", + "Sheik in Ice Cavern": "is_adult", + "Ice Cavern MQ GS Ice Block": "is_adult or can_child_attack", + "Ice Cavern MQ GS Scarecrow": " + can_use(Scarecrow) or (Hover_Boots and can_use(Longshot)) or + (logic_ice_mq_scarecrow and is_adult)" + } + }, + { + "region_name": "Ice Cavern Compass Room", + "dungeon": "Ice Cavern", + "locations": { + "Ice Cavern MQ Compass Chest": "True", + "Ice Cavern MQ Freestanding PoH": "has_explosives", + "Ice Cavern MQ GS Red Ice": "can_play(Song_of_Time) or logic_ice_mq_red_ice_gs" + } + } +] diff --git a/worlds/oot/data/World/Ice Cavern.json b/worlds/oot/data/World/Ice Cavern.json new file mode 100644 index 00000000..f61596dd --- /dev/null +++ b/worlds/oot/data/World/Ice Cavern.json @@ -0,0 +1,35 @@ +[ + { + "region_name": "Ice Cavern Beginning", + "dungeon": "Ice Cavern", + "exits": { + "ZF Ice Ledge": "True", + #Frezzards are weird, they are immune to KS completely. Leave sticks out as 8/10 is a lot + "Ice Cavern": "here(is_adult or has_explosives or can_use(Dins_Fire))" + } + }, + { + "region_name": "Ice Cavern", + "dungeon": "Ice Cavern", + "locations": { + "Ice Cavern Map Chest": "Blue_Fire and is_adult", + "Ice Cavern Compass Chest": "Blue_Fire", + "Ice Cavern Iron Boots Chest": " + Blue_Fire and + (is_adult or Slingshot or Sticks or + Kokiri_Sword or can_use(Dins_Fire))", + "Sheik in Ice Cavern": " + Blue_Fire and + (is_adult or Slingshot or Sticks or + Kokiri_Sword or can_use(Dins_Fire))", + "Ice Cavern Freestanding PoH": "Blue_Fire", + "Ice Cavern GS Spinning Scythe Room": "can_use(Hookshot) or can_use(Boomerang)", + "Ice Cavern GS Heart Piece Room": " + Blue_Fire and (can_use(Hookshot) or can_use(Boomerang))", + "Ice Cavern GS Push Block Room": " + Blue_Fire and (can_use(Hookshot) or can_use(Boomerang) or + (logic_ice_block_gs and can_use(Hover_Boots)))", + "Blue Fire": "is_adult and has_bottle" + } + } +] diff --git a/worlds/oot/data/World/Jabu Jabus Belly MQ.json b/worlds/oot/data/World/Jabu Jabus Belly MQ.json new file mode 100644 index 00000000..1251dc21 --- /dev/null +++ b/worlds/oot/data/World/Jabu Jabus Belly MQ.json @@ -0,0 +1,66 @@ +[ + { + "region_name": "Jabu Jabus Belly Beginning", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Nut Pot": "True", + "Jabu Jabus Belly MQ Map Chest": "can_blast_or_smash", + "Jabu Jabus Belly MQ First Room Side Chest": "can_use(Slingshot)" + }, + "exits": { + "Zoras Fountain": "True", + "Jabu Jabus Belly Main": "here(is_child and can_use(Slingshot))" + } + }, + { + "region_name": "Jabu Jabus Belly Main", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly MQ Second Room Lower Chest": "True", + "Jabu Jabus Belly MQ Second Room Upper Chest": " + can_use(Hover_Boots) or can_use(Hookshot) or + at('Jabu Jabus Belly Boss Area', is_child)", + "Jabu Jabus Belly MQ Compass Chest": "True", + "Jabu Jabus Belly MQ Basement Near Vines Chest": "True", + "Jabu Jabus Belly MQ Basement Near Switches Chest": "True", + "Jabu Jabus Belly MQ Boomerang Room Small Chest": "True", + "Jabu Jabus Belly MQ Boomerang Chest": "True", + "Jabu Jabus Belly MQ GS Boomerang Chest Room": " + can_play(Song_of_Time) or (logic_jabu_mq_sot_gs and can_use(Boomerang))" + }, + "exits": { + "Jabu Jabus Belly Beginning": "True", + "Jabu Jabus Belly Depths": "has_explosives and can_use(Boomerang)" + } + }, + { + "region_name": "Jabu Jabus Belly Depths", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly MQ Falling Like Like Room Chest": "True", + "Jabu Jabus Belly MQ GS Tailpasaran Room": "Sticks or can_use(Dins_Fire)", + "Jabu Jabus Belly MQ GS Invisible Enemies Room": " + (logic_lens_jabu_mq or can_use(Lens_of_Truth)) or + at('Jabu Jabus Belly Main', can_use(Hover_Boots) and can_use(Hookshot))" + }, + "exits": { + "Jabu Jabus Belly Main": "True", + "Jabu Jabus Belly Boss Area": "Sticks or (can_use(Dins_Fire) and Kokiri_Sword)" + } + }, + { + "region_name": "Jabu Jabus Belly Boss Area", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly MQ Cow" : "can_play(Eponas_Song)", + "Jabu Jabus Belly MQ Near Boss Chest": "True", + "Jabu Jabus Belly Barinade Heart": "True", + "Barinade": "True", + "Jabu Jabus Belly MQ GS Near Boss": "True", + "Fairy Pot": "has_bottle" + }, + "exits": { + "Jabu Jabus Belly Main": "True" + } + } +] diff --git a/worlds/oot/data/World/Jabu Jabus Belly.json b/worlds/oot/data/World/Jabu Jabus Belly.json new file mode 100644 index 00000000..8b90da34 --- /dev/null +++ b/worlds/oot/data/World/Jabu Jabus Belly.json @@ -0,0 +1,53 @@ +[ + { + "region_name": "Jabu Jabus Belly Beginning", + "dungeon": "Jabu Jabus Belly", + "exits": { + "Zoras Fountain": "True", + "Jabu Jabus Belly Main": "can_use_projectile" + } + }, + { + "region_name": "Jabu Jabus Belly Main", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly Boomerang Chest": "True", + "Jabu Jabus Belly GS Water Switch Room": "True", + "Jabu Jabus Belly GS Lobby Basement Lower": "can_use(Boomerang) or can_use(Hookshot)", + "Jabu Jabus Belly GS Lobby Basement Upper": "can_use(Boomerang) or can_use(Hookshot)", + "Jabu Jabus Belly Deku Scrub": " + can_dive or is_child or logic_jabu_scrub_jump_dive or can_use(Iron_Boots)", + "Fairy Pot": "has_bottle" + }, + "exits": { + "Jabu Jabus Belly Beginning": "True", + "Jabu Jabus Belly Depths": "can_use(Boomerang)", + "Jabu Jabus Belly Boss Area": "logic_jabu_boss_gs_adult and can_use(Hover_Boots)" + } + }, + { + "region_name": "Jabu Jabus Belly Depths", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly Map Chest": "True", + "Jabu Jabus Belly Compass Chest": "True" + }, + "exits": { + "Jabu Jabus Belly Main": "True", + "Jabu Jabus Belly Boss Area": "Sticks or Kokiri_Sword" + } + }, + { + "region_name": "Jabu Jabus Belly Boss Area", + "dungeon": "Jabu Jabus Belly", + "locations": { + "Jabu Jabus Belly Barinade Heart": "can_use(Boomerang)", + "Barinade": "can_use(Boomerang)", + "Jabu Jabus Belly GS Near Boss": "True", + "Nut Pot": "True" + }, + "exits": { + "Jabu Jabus Belly Main": "True" + } + } +] diff --git a/worlds/oot/data/World/Overworld.json b/worlds/oot/data/World/Overworld.json new file mode 100644 index 00000000..398f3fed --- /dev/null +++ b/worlds/oot/data/World/Overworld.json @@ -0,0 +1,2276 @@ +[ + { + "region_name": "Root", + "hint": "Link's Pocket", + "locations": { + "Links Pocket": "True" + }, + "exits": { + "Root Exits": "is_starting_age or Time_Travel", + "HC Garden Locations": "skip_child_zelda" + } + }, + { + "region_name": "Root Exits", + "exits": { + "Child Spawn": "is_child and (starting_age == 'child' or Time_Travel)", + "Adult Spawn": "is_adult and (starting_age == 'adult' or Time_Travel)", + "Prelude of Light Warp": "can_play(Prelude_of_Light) and can_leave_forest", + "Minuet of Forest Warp": "can_play(Minuet_of_Forest)", + "Bolero of Fire Warp": "can_play(Bolero_of_Fire) and can_leave_forest", + "Serenade of Water Warp": "can_play(Serenade_of_Water) and can_leave_forest", + "Nocturne of Shadow Warp": "can_play(Nocturne_of_Shadow) and can_leave_forest", + "Requiem of Spirit Warp": "can_play(Requiem_of_Spirit) and can_leave_forest" + } + }, + { + "region_name": "Child Spawn", + "exits": { + "KF Links House": "True" + } + }, + { + "region_name": "Adult Spawn", + "exits": { + "Temple of Time": "True" + } + }, + { + "region_name": "Prelude of Light Warp", + "exits": { + "Temple of Time": "True" + } + }, + { + "region_name": "Minuet of Forest Warp", + "exits": { + "Sacred Forest Meadow": "True" + } + }, + { + "region_name": "Bolero of Fire Warp", + "exits": { + "DMC Central Local": "True" + } + }, + { + "region_name": "Serenade of Water Warp", + "exits": { + "Lake Hylia": "True" + } + }, + { + "region_name": "Nocturne of Shadow Warp", + "exits": { + "Graveyard Warp Pad Region": "True" + } + }, + { + "region_name": "Requiem of Spirit Warp", + "exits": { + "Desert Colossus": "True" + } + }, + { + "region_name": "Kokiri Forest", + "scene": "Kokiri Forest", + "hint": "Kokiri Forest", + "events": { + "Showed Mido Sword & Shield": "is_child and Kokiri_Sword and Buy_Deku_Shield" + }, + "locations": { + "KF Kokiri Sword Chest": "is_child", + "KF GS Know It All House": " + is_child and can_child_attack and at_night and + (had_night_start or can_leave_forest or can_play(Suns_Song))", + "KF GS Bean Patch": " + can_plant_bugs and can_child_attack", + "KF GS House of Twins": " + is_adult and at_night and + (can_use(Hookshot) or (logic_adult_kokiri_gs and can_use(Hover_Boots)))", + "KF Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle", + "Bean Plant Fairy": "can_plant_bean and can_play(Song_of_Storms) and has_bottle" + }, + "exits": { + "KF Links House": "True", + "KF Midos House": "True", + "KF Sarias House": "True", + "KF House of Twins": "True", + "KF Know It All House": "True", + "KF Kokiri Shop": "True", + "KF Outside Deku Tree": "is_adult or open_forest == 'open' or 'Showed Mido Sword & Shield'", + "Lost Woods": "True", + "LW Bridge From Forest": "can_leave_forest", + "KF Storms Grotto": "can_open_storm_grotto" + } + }, + { + "region_name": "KF Outside Deku Tree", + "scene": "Kokiri Forest", + "hint": "Kokiri Forest", + "events": { + "Showed Mido Sword & Shield": "is_child and Kokiri_Sword and Buy_Deku_Shield" + }, + "locations": { + #The Babas despawn for Adult on forest temple completion. For vanilla forest temple + #placement this is not an issue as Adult can go back to forest for the Baba's there. + #Entrance rando cannot rely on this for the case forest completion was done on non + #repeatable access. + "Deku Baba Sticks": "(is_adult and not entrance_shuffle) or can_use(Kokiri_Sword) or can_use(Boomerang)", + "Deku Baba Nuts": "is_adult and not entrance_shuffle", + "KF Deku Tree Gossip Stone (Left)": "True", + "KF Deku Tree Gossip Stone (Right)": "True" + }, + "exits": { + "Deku Tree Lobby": " + is_child or + (shuffle_dungeon_entrances and (open_forest == 'open' or 'Showed Mido Sword & Shield'))", + "Kokiri Forest": "is_adult or open_forest == 'open' or 'Showed Mido Sword & Shield'" + } + }, + { + "region_name": "KF Links House", + "scene": "KF Links House", + "locations": { + "KF Links House Cow": "is_adult and can_play(Eponas_Song) and 'Links Cow'" + }, + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "KF Midos House", + "scene": "KF Midos House", + "locations": { + "KF Midos Top Left Chest": "True", + "KF Midos Top Right Chest": "True", + "KF Midos Bottom Left Chest": "True", + "KF Midos Bottom Right Chest": "True" + }, + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "KF Sarias House", + "scene": "KF Sarias House", + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "KF House of Twins", + "scene": "KF House of Twins", + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "KF Know It All House", + "scene": "KF Know it All House", + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "KF Kokiri Shop", + "scene": "KF Kokiri Shop", + "locations": { + "KF Shop Item 1": "True", + "KF Shop Item 2": "True", + "KF Shop Item 3": "True", + "KF Shop Item 4": "True", + "KF Shop Item 5": "True", + "KF Shop Item 6": "True", + "KF Shop Item 7": "True", + "KF Shop Item 8": "True" + }, + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "LW Forest Exit", + "scene": "Lost Woods", + "hint": "the Lost Woods", + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "Lost Woods", + "scene": "Lost Woods", + "hint": "the Lost Woods", + "events": { + "Odd Mushroom Access": "is_adult and ('Cojiro Access' or Cojiro)", + "Poachers Saw Access": "is_adult and 'Odd Potion Access'" + }, + "locations": { + "LW Skull Kid": "is_child and can_play(Sarias_Song)", + "LW Ocarina Memory Game": "is_child and Ocarina", + "LW Target in Woods": "can_use(Slingshot)", + "LW Deku Scrub Near Bridge": "is_child and can_stun_deku", + "LW GS Bean Patch Near Bridge": "can_plant_bugs and can_child_attack", + "LW Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle", + "Bean Plant Fairy": "can_plant_bean and can_play(Song_of_Storms) and has_bottle", + "Bug Shrub": "is_child and can_cut_shrubs and has_bottle" + }, + "exits": { + "LW Forest Exit": "True", + "GC Woods Warp": "True", + "LW Bridge": " + is_adult and + (can_use(Hover_Boots) or can_use(Longshot) or + here(can_plant_bean) or logic_lost_woods_bridge)", + "Zora River": "can_leave_forest and (can_dive or can_use(Iron_Boots))", + "LW Beyond Mido": "is_child or logic_mido_backflip or can_play(Sarias_Song)", + "LW Near Shortcuts Grotto": "here(can_blast_or_smash)" + } + }, + { + "region_name": "LW Beyond Mido", + "scene": "Lost Woods", + "hint": "the Lost Woods", + "locations": { + "LW Deku Scrub Near Deku Theater Right": "is_child and can_stun_deku", + "LW Deku Scrub Near Deku Theater Left": "is_child and can_stun_deku", + "LW GS Above Theater": " + is_adult and at_night and + (here(can_plant_bean) or + (logic_lost_woods_gs_bean and can_use(Hookshot) and + (can_use(Longshot) or can_use(Bow) or has_bombchus or can_use(Dins_Fire))))", + "LW GS Bean Patch Near Theater": " + can_plant_bugs and + (can_child_attack or (shuffle_scrubs == 'off' and Buy_Deku_Shield))", + "Butterfly Fairy": "can_use(Sticks) and has_bottle" + }, + "exits": { + "LW Forest Exit": "True", + "Lost Woods": "is_child or can_play(Sarias_Song)", + "SFM Entryway": "True", + "Deku Theater": "True", + "LW Scrubs Grotto": "here(can_blast_or_smash)" + } + }, + { + "region_name": "Lost Woods Mushroom Timeout", + "scene": "Lost Woods", + "hint": "the Lost Woods", + "exits": { + "Lost Woods": "True" + } + }, + { + "region_name": "SFM Entryway", + "scene": "Sacred Forest Meadow", + "hint": "Sacred Forest Meadow", + "exits": { + "LW Beyond Mido": "True", + "Sacred Forest Meadow": " + is_adult or Slingshot or Sticks or + Kokiri_Sword or can_use(Dins_Fire)", + "SFM Wolfos Grotto": "can_open_bomb_grotto" + } + }, + { + "region_name": "Sacred Forest Meadow", + "scene": "Sacred Forest Meadow", + "hint": "Sacred Forest Meadow", + "locations": { + "Song from Saria": "is_child and Zeldas_Letter", + "Sheik in Forest": "is_adult", + "SFM GS": "can_use(Hookshot) and at_night", + "SFM Maze Gossip Stone (Lower)": "True", + "SFM Maze Gossip Stone (Upper)": "True", + "SFM Saria Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle" + }, + "exits": { + "SFM Entryway": "True", + "SFM Forest Temple Entrance Ledge": "can_use(Hookshot)", + "SFM Fairy Grotto": "True", + "SFM Storms Grotto": "can_open_storm_grotto" + } + }, + { + "region_name": "SFM Forest Temple Entrance Ledge", + "scene": "Sacred Forest Meadow", + "hint": "Sacred Forest Meadow", + "exits": { + "Sacred Forest Meadow": "True", + "Forest Temple Lobby": "True" + } + }, + { + "region_name": "LW Bridge From Forest", + "scene": "Lost Woods", + "hint": "the Lost Woods", + "locations": { + "LW Gift from Saria": "True" + }, + "exits": { + "LW Bridge": "True" + } + }, + { + "region_name": "LW Bridge", + "scene": "Lost Woods", + "hint": "the Lost Woods", + "exits": { + "Kokiri Forest": "True", + "Hyrule Field": "True", + "Lost Woods": "can_use(Longshot)" + } + }, + { + "region_name": "Hyrule Field", + "scene": "Hyrule Field", + "hint": "Hyrule Field", + "time_passes": true, + "locations": { + "HF Ocarina of Time Item": "is_child and has_all_stones", + "Song from Ocarina of Time": "is_child and has_all_stones", + "Big Poe Kill": "can_use(Bow) and can_ride_epona and has_bottle" + }, + "exits": { + "LW Bridge": "True", + "Lake Hylia": "True", + "Gerudo Valley": "True", + "Market Entrance": "True", + "Kakariko Village": "True", + "ZR Front": "True", + "Lon Lon Ranch": "True", + "HF Southeast Grotto": "here(can_blast_or_smash)", + "HF Open Grotto": "True", + "HF Inside Fence Grotto": "can_open_bomb_grotto", + "HF Cow Grotto": "(can_use(Megaton_Hammer) or is_child) and can_open_bomb_grotto", + # There is a hammerable boulder as adult which is not there as child + "HF Near Market Grotto": "here(can_blast_or_smash)", + "HF Fairy Grotto": "here(can_blast_or_smash)", + "HF Near Kak Grotto": "can_open_bomb_grotto", + "HF Tektite Grotto": "can_open_bomb_grotto" + } + }, + { + "region_name": "Lake Hylia", + "scene": "Lake Hylia", + "hint": "Lake Hylia", + "time_passes": true, + "events": { + "Bonooru": "is_child and Ocarina" + }, + "locations": { + "Pierre": "is_adult and Bonooru and not free_scarecrow", + "LH Underwater Item": "is_child and can_dive", + "LH Sun": " + is_adult and + (can_use(Distant_Scarecrow) or 'Water Temple Clear') and can_use(Bow)", + "LH Freestanding PoH": " + is_adult and (can_use(Scarecrow) or here(can_plant_bean))", + "LH GS Bean Patch": "can_plant_bugs and can_child_attack", + "LH GS Lab Wall": " + is_child and (Boomerang or + (logic_lab_wall_gs and (Sticks or Kokiri_Sword))) and at_night", + "LH GS Small Island": "is_child and can_child_attack and at_night", + "LH GS Tree": "can_use(Longshot) and at_night", + "LH Lab Gossip Stone": "True", + "LH Gossip Stone (Southeast)": "True", + "LH Gossip Stone (Southwest)": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Bean Plant Fairy": "can_plant_bean and can_play(Song_of_Storms) and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "is_child and can_cut_shrubs and has_bottle" + }, + "exits": { + "Hyrule Field": "True", + "Zoras Domain": "is_child and can_dive", + "LH Owl Flight": "is_child", + "LH Lab": "True", + "LH Fishing Island": " + is_child or can_use(Scarecrow) or + here(can_plant_bean) or 'Water Temple Clear'", + "Water Temple Lobby": " + can_use(Hookshot) and + (can_use(Iron_Boots) or + ((can_use(Longshot) or logic_water_hookshot_entry) and (Progressive_Scale, 2)))", + "LH Grotto": "True" + } + }, + { + "region_name": "LH Fishing Island", + "scene": "Lake Hylia", + "hint": "Lake Hylia", + "exits": { + "Lake Hylia": "True", + "LH Fishing Hole": "True" + } + }, + { + "region_name": "LH Owl Flight", + "scene": "Lake Hylia", + "hint": "Lake Hylia", + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "LH Lab", + "scene": "LH Lab", + "events": { + "Eyedrops Access": " + is_adult and + ('Eyeball Frog Access' or (Eyeball_Frog and disable_trade_revert))" + }, + "locations": { + "LH Lab Dive": " + (Progressive_Scale, 2) or + (logic_lab_diving and Iron_Boots and can_use(Hookshot))", + "LH GS Lab Crate": "Iron_Boots and can_use(Hookshot)" + }, + "exits": { + "Lake Hylia": "True" + } + }, + { + "region_name": "LH Fishing Hole", + "scene": "LH Fishing Hole", + "locations": { + "LH Child Fishing": "is_child", + "LH Adult Fishing": "is_adult" + }, + "exits": { + "LH Fishing Island": "True" + } + }, + { + "region_name": "Gerudo Valley", + "scene": "Gerudo Valley", + "hint": "Gerudo Valley", + "time_passes": true, + "locations": { + "GV GS Small Bridge": "can_use(Boomerang) and at_night", + "Bug Rock": "is_child and has_bottle" + }, + "exits": { + "Hyrule Field": "True", + "GV Upper Stream": "True", + "GV Crate Ledge": "is_child or can_use(Longshot)", + "GV Grotto Ledge": "True", + "GV Fortress Side": " + is_adult and + (can_ride_epona or can_use(Longshot) or gerudo_fortress == 'open' or 'Carpenter Rescue')" + } + }, + { + "region_name": "GV Upper Stream", + "scene": "Gerudo Valley", + "hint": "Gerudo Valley", + "time_passes": true, + "locations": { + "GV Waterfall Freestanding PoH": "True", + "GV GS Bean Patch": "can_plant_bugs and can_child_attack", + "GV Cow": "is_child and can_play(Eponas_Song)", + "GV Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Bean Plant Fairy": "can_plant_bean and can_play(Song_of_Storms) and has_bottle" + }, + "exits": { + "GV Lower Stream": "True" + } + }, + { + "region_name": "GV Lower Stream", + "scene": "Gerudo Valley", + "hint": "Gerudo Valley", + "time_passes": true, + "exits": { + "Lake Hylia": "True" + } + }, + { + "region_name": "GV Grotto Ledge", + "scene": "Gerudo Valley", + "hint": "Gerudo Valley", + "time_passes": true, + "exits": { + "GV Lower Stream": "True", + "GV Octorok Grotto": "can_use(Silver_Gauntlets)", + "GV Crate Ledge": "can_use(Longshot)" + } + }, + { + "region_name": "GV Crate Ledge", + "scene": "Gerudo Valley", + "hint": "Gerudo Valley", + "time_passes": true, + "locations": { + "GV Crate Freestanding PoH": "True" + }, + "exits": { + "GV Lower Stream": "True" + } + }, + { + "region_name": "GV Fortress Side", + "scene": "Gerudo Valley", + "hint": "Gerudo Valley", + "time_passes": true, + "events": { + "Broken Sword Access": "is_adult and ('Poachers Saw Access' or Poachers_Saw)" + }, + "locations": { + "GV Chest": "can_use(Megaton_Hammer)", + "GV GS Behind Tent": "can_use(Hookshot) and at_night", + "GV GS Pillar": "can_use(Hookshot) and at_night" + }, + "exits": { + "Gerudo Fortress": "True", + "GV Upper Stream": "True", + "GV Crate Ledge": " + logic_valley_crate_hovers and can_use(Hover_Boots) and can_take_damage", + "Gerudo Valley": " + is_child or can_ride_epona or can_use(Longshot) or + gerudo_fortress == 'open' or 'Carpenter Rescue'", + "GV Carpenter Tent": "is_adult", # Invisible as child so not in logic + "GV Storms Grotto": "is_adult and can_open_storm_grotto" # Not there as child + } + }, + { + "region_name": "GV Carpenter Tent", + "scene": "GV Carpenter Tent", + "exits": { + "GV Fortress Side": "True" + } + }, + { + "region_name": "Gerudo Fortress", + "scene": "Gerudo Fortress", + "hint": "Gerudo's Fortress", + "events": { + "Carpenter Rescue": "can_finish_GerudoFortress", + "GF Gate Open": "is_adult and Gerudo_Membership_Card" + }, + "locations": { + "GF Chest": " + can_use(Hover_Boots) or can_use(Scarecrow) or can_use(Longshot)", + "GF HBA 1000 Points": " + Gerudo_Membership_Card and can_ride_epona and Bow and at_day", + "GF HBA 1500 Points": " + Gerudo_Membership_Card and can_ride_epona and Bow and at_day", + "GF North F1 Carpenter": "is_adult or Kokiri_Sword", + "GF North F2 Carpenter": " + (is_adult or Kokiri_Sword) and + (Gerudo_Membership_Card or can_use(Bow) or can_use(Hookshot) + or can_use(Hover_Boots) or logic_gerudo_kitchen)", + "GF South F1 Carpenter": "is_adult or Kokiri_Sword", + "GF South F2 Carpenter": "is_adult or Kokiri_Sword", + "GF Gerudo Membership Card": "can_finish_GerudoFortress", + "GF GS Archery Range": " + can_use(Hookshot) and Gerudo_Membership_Card and at_night", + "GF GS Top Floor": " + is_adult and at_night and + (Gerudo_Membership_Card or can_use(Bow) or can_use(Hookshot) or + can_use(Hover_Boots) or logic_gerudo_kitchen)" + }, + "exits": { + "GV Fortress Side": "True", + "GF Outside Gate": "'GF Gate Open'", + "Gerudo Training Grounds Lobby": "Gerudo_Membership_Card and is_adult", + "GF Storms Grotto": "is_adult and can_open_storm_grotto" # Not there as child + } + }, + { + "region_name": "GF Outside Gate", + "scene": "Gerudo Fortress", + "hint": "Gerudo's Fortress", + "exits": { + "Gerudo Fortress": "is_adult or (shuffle_overworld_entrances and 'GF Gate Open')", + "Wasteland Near Fortress": "True" + } + }, + { + "region_name": "Wasteland Near Fortress", + "scene": "Haunted Wasteland", + "hint": "Haunted Wasteland", + "exits": { + "GF Outside Gate": "True", + "Haunted Wasteland": " + logic_wasteland_crossing or can_use(Hover_Boots) or can_use(Longshot)" + } + }, + { + "region_name": "Haunted Wasteland", + "scene": "Haunted Wasteland", + "hint": "Haunted Wasteland", + "locations": { + "Wasteland Chest": "has_fire_source", + "Wasteland Bombchu Salesman": " + Progressive_Wallet and + (is_adult or Sticks or Kokiri_Sword)", + "Wasteland GS": "can_use(Hookshot) or can_use(Boomerang)", + "Fairy Pot": "has_bottle", + "Nut Pot": "True" + }, + "exits": { + "Wasteland Near Colossus": "logic_lens_wasteland or can_use(Lens_of_Truth)", + "Wasteland Near Fortress": " + logic_wasteland_crossing or can_use(Hover_Boots) or can_use(Longshot)" + } + }, + { + "region_name": "Wasteland Near Colossus", + "scene": "Haunted Wasteland", + "hint": "Haunted Wasteland", + "exits": { + "Desert Colossus": "True", + "Haunted Wasteland": "logic_reverse_wasteland" + } + }, + { + "region_name": "Desert Colossus", + "scene": "Desert Colossus", + "hint": "Desert Colossus", + "time_passes": true, + "locations": { + "Colossus Freestanding PoH": "is_adult and here(can_plant_bean)", + "Colossus GS Bean Patch": "can_plant_bugs and can_child_attack", + "Colossus GS Tree": "can_use(Hookshot) and at_night", + "Colossus GS Hill": " + is_adult and at_night and + (here(can_plant_bean) or can_use(Longshot) or + (logic_colossus_gs and can_use(Hookshot)))", + "Colossus Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Fairy Pond": "can_play(Song_of_Storms) and has_bottle", + "Bug Rock": "has_bottle" + }, + "exits": { + "Colossus Great Fairy Fountain": "has_explosives", + "Spirit Temple Lobby": "True", + "Wasteland Near Colossus": "True", + "Colossus Grotto": "can_use(Silver_Gauntlets)" + } + }, + { + "region_name": "Desert Colossus From Spirit Lobby", + "scene": "Desert Colossus", + "hint": "Desert Colossus", + "locations": { + "Sheik at Colossus": "True" + }, + "exits": { + "Desert Colossus": "True" + } + }, + { + "region_name": "Colossus Great Fairy Fountain", + "scene": "Colossus Great Fairy Fountain", + "locations": { + "Colossus Great Fairy Reward": "can_play(Zeldas_Lullaby)" + }, + "exits": { + "Desert Colossus": "True" + } + }, + { + "region_name": "Market Entrance", + "scene": "Market Entrance", + "hint": "the Market", + "exits": { + "Hyrule Field": "is_adult or at_day", + "Market": "True", + "Market Guard House": "True" + } + }, + { + "region_name": "Market", + "scene": "Market", + "hint": "the Market", + "exits": { + "Market Entrance": "True", + "ToT Entrance": "True", + "Castle Grounds": "True", + "Market Bazaar": "is_child and at_day", + "Market Mask Shop": "is_child and at_day", + "Market Shooting Gallery": "is_child and at_day", + "Market Bombchu Bowling": "is_child", + "Market Potion Shop": "is_child and at_day", + "Market Treasure Chest Game": "is_child and at_night", + "Market Back Alley": "is_child" + } + }, + { + "region_name": "Market Back Alley", + "scene": "Market", + "hint": "the Market", + "exits": { + "Market": "True", + "Market Bombchu Shop": "at_night", + "Market Dog Lady House": "True", + "Market Man in Green House": "at_night" + } + }, + { + "region_name": "ToT Entrance", + "scene": "ToT Entrance", + "hint": "the Market", + "locations": { + "ToT Gossip Stone (Left)": "True", + "ToT Gossip Stone (Left-Center)": "True", + "ToT Gossip Stone (Right)": "True", + "ToT Gossip Stone (Right-Center)": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle" + }, + "exits": { + "Market": "True", + "Temple of Time": "True" + } + }, + { + "region_name": "Temple of Time", + "scene": "Temple of Time", + "hint": "Temple of Time", + "locations": { + "ToT Light Arrows Cutscene": "is_adult and can_trigger_lacs" + }, + "exits": { + "ToT Entrance": "True", + "Beyond Door of Time": "can_play(Song_of_Time) or open_door_of_time" + } + }, + { + "region_name": "Beyond Door of Time", + "scene": "Temple of Time", + "hint": "Temple of Time", + "locations": { + "Master Sword Pedestal": "True", + "Sheik at Temple": "Forest_Medallion and is_adult" + }, + "exits": { + "Temple of Time": "True" + } + }, + { + "region_name": "Castle Grounds", + "scene": "Castle Grounds", + "exits": { + "Market": "is_child or at_dampe_time", + "Hyrule Castle Grounds": "is_child", + "Ganons Castle Grounds": "is_adult" + } + }, + { + "region_name": "Hyrule Castle Grounds", + "scene": "Castle Grounds", + "hint": "Hyrule Castle", + "time_passes": true, + "locations": { + "HC Malon Egg": "True", + "HC GS Tree": "can_child_attack", + "HC Malon Gossip Stone": "True", + "HC Rock Wall Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Rock": "has_bottle" + }, + "exits": { + "Castle Grounds": "True", + "HC Garden": "Weird_Egg or skip_child_zelda or (not shuffle_weird_egg)", + "HC Great Fairy Fountain": "has_explosives", + "HC Storms Grotto": "can_open_storm_grotto" + } + }, + { + "region_name": "HC Garden", + "scene": "Castle Grounds", + "hint": "Hyrule Castle", + "exits": { + "HC Garden Locations": "True", + "Hyrule Castle Grounds": "True" + } + }, + { + # Directly reachable from Root in "Free Zelda" + "region_name": "HC Garden Locations", + "scene": "Castle Grounds", + "hint": "Hyrule Castle", + "locations": { + "HC Zeldas Letter": "True", + "Song from Impa": "True" + } + }, + { + "region_name": "HC Great Fairy Fountain", + "scene": "HC Great Fairy Fountain", + "locations": { + "HC Great Fairy Reward": "can_play(Zeldas_Lullaby)" + }, + "exits": { + "Castle Grounds": "True" + } + }, + { + "region_name": "Ganons Castle Grounds", + "scene": "Castle Grounds", + "hint": "outside Ganon's Castle", + "locations": { + "OGC GS": "True" + }, + "exits": { + "Castle Grounds": "True", + "OGC Great Fairy Fountain": "can_use(Golden_Gauntlets) and at_dampe_time", + "Ganons Castle Lobby": "can_build_rainbow_bridge and at_dampe_time" + } + }, + { + "region_name": "OGC Great Fairy Fountain", + "scene": "OGC Great Fairy Fountain", + "locations": { + "OGC Great Fairy Reward": "can_play(Zeldas_Lullaby)" + }, + "exits": { + "Castle Grounds": "True" + } + }, + { + "region_name": "Market Guard House", + "scene": "Market Guard House", + "events": { + "Sell Big Poe": "is_adult and Bottle_with_Big_Poe" + }, + "locations": { + "Market 10 Big Poes": " + is_adult and + (Big_Poe or (Bottle_with_Big_Poe, big_poe_count))", + "Market GS Guard House": "is_child" + }, + "exits": { + "Market Entrance": "True" + } + }, + { + "region_name": "Market Bazaar", + "scene": "Market Bazaar", + "locations": { + "Market Bazaar Item 1": "True", + "Market Bazaar Item 2": "True", + "Market Bazaar Item 3": "True", + "Market Bazaar Item 4": "True", + "Market Bazaar Item 5": "True", + "Market Bazaar Item 6": "True", + "Market Bazaar Item 7": "True", + "Market Bazaar Item 8": "True" + }, + "exits": { + "Market": "True" + } + }, + { + "region_name": "Market Mask Shop", + "scene": "Market Mask Shop", + "events": { + "Skull Mask": "Zeldas_Letter and (complete_mask_quest or at('Kakariko Village', is_child))", + "Mask of Truth": "'Skull Mask' and + (complete_mask_quest or + (at('Lost Woods', is_child and can_play(Sarias_Song)) and + at('Graveyard', is_child and at_day) and + at('Hyrule Field', is_child and has_all_stones)))" + }, + "exits": { + "Market": "True" + } + }, + { + "region_name": "Market Shooting Gallery", + "scene": "Market Shooting Gallery", + "locations": { + "Market Shooting Gallery Reward": "is_child" + }, + "exits": { + "Market": "True" + } + }, + { + "region_name": "Market Bombchu Bowling", + "scene": "Market Bombchu Bowling", + "locations": { + "Market Bombchu Bowling First Prize": "found_bombchus", + "Market Bombchu Bowling Second Prize": "found_bombchus", + "Market Bombchu Bowling Bombchus": "found_bombchus" + }, + "exits": { + "Market": "True" + } + }, + { + "region_name": "Market Potion Shop", + "scene": "Market Potion Shop", + "locations": { + "Market Potion Shop Item 1": "True", + "Market Potion Shop Item 2": "True", + "Market Potion Shop Item 3": "True", + "Market Potion Shop Item 4": "True", + "Market Potion Shop Item 5": "True", + "Market Potion Shop Item 6": "True", + "Market Potion Shop Item 7": "True", + "Market Potion Shop Item 8": "True" + }, + "exits": { + "Market": "True" + } + }, + { + "region_name": "Market Treasure Chest Game", + "scene": "Market Treasure Chest Game", + "locations": { + "Market Treasure Chest Game Reward": "can_use(Lens_of_Truth)" + }, + "exits": { + "Market": "True" + } + }, + { + "region_name": "Market Bombchu Shop", + "scene": "Market Bombchu Shop", + "locations": { + "Market Bombchu Shop Item 1": "True", + "Market Bombchu Shop Item 2": "True", + "Market Bombchu Shop Item 3": "True", + "Market Bombchu Shop Item 4": "True", + "Market Bombchu Shop Item 5": "True", + "Market Bombchu Shop Item 6": "True", + "Market Bombchu Shop Item 7": "True", + "Market Bombchu Shop Item 8": "True" + }, + "exits": { + "Market Back Alley": "True" + } + }, + { + "region_name": "Market Dog Lady House", + "scene": "Market Dog Lady House", + "locations": { + "Market Lost Dog": "is_child and at_night" + }, + "exits": { + "Market Back Alley": "True" + } + }, + { + "region_name": "Market Man in Green House", + "scene": "Market Man in Green House", + "exits": { + "Market Back Alley": "True" + } + }, + { + "region_name": "Kakariko Village", + "scene": "Kakariko Village", + "hint": "Kakariko Village", + "events": { + "Cojiro Access": "is_adult and 'Wake Up Adult Talon'", + "Kakariko Village Gate Open": "is_child and (Zeldas_Letter or open_kakariko == 'open')" + }, + "locations": { + "Sheik in Kakariko": " + is_adult and Forest_Medallion and Fire_Medallion and Water_Medallion", + "Kak Anju as Adult": "is_adult and at_day", + "Kak Anju as Child": "is_child and at_day", + "Kak GS House Under Construction": "is_child and at_night", + "Kak GS Skulltula House": "is_child and at_night", + "Kak GS Guards House": "is_child and at_night", + "Kak GS Tree": "is_child and at_night", + "Kak GS Watchtower": " + is_child and (Slingshot or has_bombchus or + (logic_kakariko_tower_gs and (Sticks or Kokiri_Sword) and + can_take_damage)) and at_night", + "Bug Rock": "has_bottle" + }, + "exits": { + "Hyrule Field": "True", + "Kak Carpenter Boss House": "True", + "Kak House of Skulltula": "True", + "Kak Impas House": "True", + "Kak Windmill": "True", + "Kak Bazaar": "is_adult and at_day", + "Kak Shooting Gallery": "is_adult and at_day", + "Bottom of the Well": " + 'Drain Well' and (is_child or shuffle_dungeon_entrances)", + "Kak Potion Shop Front": "is_child or at_day", + "Kak Redead Grotto": "can_open_bomb_grotto", + "Kak Impas Ledge": " + (is_child and at_day) or (is_adult and logic_visible_collisions)", + "Kak Impas Rooftop": " + can_use(Hookshot) or (logic_kakariko_rooftop_gs and can_use(Hover_Boots))", + "Kak Odd Medicine Rooftop": " + can_use(Hookshot) or + (logic_man_on_roof and + (is_adult or at_day or Slingshot or has_bombchus or + (logic_kakariko_tower_gs and (Sticks or Kokiri_Sword) and can_take_damage)))", + "Kak Backyard": "is_adult or at_day", + "Graveyard": "True", + "Kak Behind Gate": "is_adult or 'Kakariko Village Gate Open'" + } + }, + { + "region_name": "Kak Impas Ledge", + "scene": "Kakariko Village", + "hint": "Kakariko Village", + "exits": { + "Kak Impas House Back": "True", + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak Impas Rooftop", + "scene": "Kakariko Village", + "hint": "Kakariko Village", + "locations": { + "Kak GS Above Impas House": "is_adult and at_night" + }, + "exits": { + "Kak Impas Ledge": "True", + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak Odd Medicine Rooftop", + "scene": "Kakariko Village", + "hint": "Kakariko Village", + "locations": { + "Kak Man on Roof": "True" + }, + "exits": { + "Kakariko Village": "True", + "Kak Backyard": "True" + } + }, + { + "region_name": "Kak Backyard", + "scene": "Kakariko Village", + "hint": "Kakariko Village", + "exits": { + "Kakariko Village": "True", + "Kak Open Grotto": "True", + "Kak Odd Medicine Building": "is_adult", + "Kak Potion Shop Back": "is_adult and at_day" + } + }, + { + "region_name": "Kak Carpenter Boss House", + "scene": "Kak Carpenter Boss House", + "events": { + "Wake Up Adult Talon": "is_adult and (Pocket_Egg or Pocket_Cucco)" + }, + "exits": { + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak House of Skulltula", + "scene": "Kak House of Skulltula", + "locations": { + "Kak 10 Gold Skulltula Reward": "(Gold_Skulltula_Token, 10)", + "Kak 20 Gold Skulltula Reward": "(Gold_Skulltula_Token, 20)", + "Kak 30 Gold Skulltula Reward": "(Gold_Skulltula_Token, 30)", + "Kak 40 Gold Skulltula Reward": "(Gold_Skulltula_Token, 40)", + "Kak 50 Gold Skulltula Reward": "(Gold_Skulltula_Token, 50)" + }, + "exits": { + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak Impas House", + "scene": "Kak Impas House", + "exits": { + "Kakariko Village": "True", + "Kak Impas House Near Cow": "True" + } + }, + { + "region_name": "Kak Impas House Back", + "scene": "Kak Impas House", + "locations": { + "Kak Impas House Freestanding PoH": "True" + }, + "exits": { + "Kak Impas Ledge": "True", + "Kak Impas House Near Cow": "True" + } + }, + { + "region_name": "Kak Impas House Near Cow", + "locations": { + "Kak Impas House Cow": "can_play(Eponas_Song)" + } + }, + { + "region_name": "Kak Windmill", + "scene": "Windmill and Dampes Grave", + "events": { + "Drain Well": "is_child and can_play(Song_of_Storms)" + }, + "locations": { + "Kak Windmill Freestanding PoH": " + can_use(Boomerang) or + (logic_windmill_poh and is_adult) or 'Dampes Windmill Access'", + "Song from Windmill": "is_adult and Ocarina" + }, + "exits": { + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak Bazaar", + "scene": "Kak Bazaar", + "locations": { + "Kak Bazaar Item 1": "True", + "Kak Bazaar Item 2": "True", + "Kak Bazaar Item 3": "True", + "Kak Bazaar Item 4": "True", + "Kak Bazaar Item 5": "True", + "Kak Bazaar Item 6": "True", + "Kak Bazaar Item 7": "True", + "Kak Bazaar Item 8": "True" + }, + "exits": { + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak Shooting Gallery", + "scene": "Kak Shooting Gallery", + "locations": { + "Kak Shooting Gallery Reward": "is_adult and Bow" + }, + "exits": { + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak Potion Shop Front", + "scene": "Kak Potion Shop Front", + "locations": { + "Kak Potion Shop Item 1": "is_adult", + "Kak Potion Shop Item 2": "is_adult", + "Kak Potion Shop Item 3": "is_adult", + "Kak Potion Shop Item 4": "is_adult", + "Kak Potion Shop Item 5": "is_adult", + "Kak Potion Shop Item 6": "is_adult", + "Kak Potion Shop Item 7": "is_adult", + "Kak Potion Shop Item 8": "is_adult" + }, + "exits": { + "Kakariko Village": "True", + "Kak Potion Shop Back": "is_adult" + } + }, + { + "region_name": "Kak Potion Shop Back", + "scene": "Kak Potion Shop Back", + "exits": { + "Kak Backyard": "is_adult", + "Kak Potion Shop Front": "True" + } + }, + { + "region_name": "Kak Odd Medicine Building", + "scene": "Kak Odd Medicine Building", + "events": { + "Odd Potion Access": " + is_adult and + ('Odd Mushroom Access' or (Odd_Mushroom and disable_trade_revert))" + }, + "exits": { + "Kak Backyard": "True" + } + }, + { + "region_name": "Graveyard", + "scene": "Graveyard", + "hint": "the Graveyard", + "locations": { + "Graveyard Freestanding PoH": " + (is_adult and (here(can_plant_bean) or can_use(Longshot))) or + (logic_graveyard_poh and can_use(Boomerang))", + "Graveyard Dampe Gravedigging Tour": "is_child and at_dampe_time", + "Graveyard GS Wall": "can_use(Boomerang) and at_night", + "Graveyard GS Bean Patch": "can_plant_bugs and can_child_attack", + "Butterfly Fairy": "can_use(Sticks) and at_day and has_bottle", + "Bean Plant Fairy": "can_plant_bean and can_play(Song_of_Storms) and has_bottle", + "Bug Rock": "has_bottle" + }, + "exits": { + "Graveyard Shield Grave": "is_adult or at_night", + "Graveyard Composers Grave": "can_play(Zeldas_Lullaby)", + "Graveyard Heart Piece Grave": "is_adult or at_night", + "Graveyard Dampes Grave": "is_adult", + "Graveyard Dampes House": "is_adult or at_dampe_time", + "Kakariko Village": "True" + } + }, + { + "region_name": "Graveyard Shield Grave", + "scene": "Graveyard Shield Grave", + "locations": { + "Graveyard Shield Grave Chest": "True", + "Free Fairies": "can_blast_or_smash and has_bottle" + }, + "exits": { + "Graveyard": "True" + } + }, + { + "region_name": "Graveyard Heart Piece Grave", + "scene": "Graveyard Heart Piece Grave", + "locations": { + "Graveyard Heart Piece Grave Chest": "can_play(Suns_Song)" + }, + "exits": { + "Graveyard": "True" + } + }, + { + "region_name": "Graveyard Composers Grave", + "scene": "Graveyard Composers Grave", + "locations": { + "Graveyard Composers Grave Chest": "has_fire_source", + "Song from Composers Grave": " + is_adult or + (Slingshot or Boomerang or Sticks or + has_explosives or Kokiri_Sword)" + }, + "exits": { + "Graveyard": "True" + } + }, + { + "region_name": "Graveyard Dampes Grave", + "scene": "Windmill and Dampes Grave", + "events": { + "Dampes Windmill Access": "is_adult and can_play(Song_of_Time)" + }, + "locations": { + "Graveyard Hookshot Chest": "True", + "Graveyard Dampe Race Freestanding PoH": "is_adult or logic_child_dampe_race_poh", + "Nut Pot": "True" + }, + "exits": { + "Graveyard": "True", + "Kak Windmill": "is_adult and can_play(Song_of_Time)" + } + }, + { + "region_name": "Graveyard Dampes House", + "scene": "Graveyard Dampes House", + "exits": { + "Graveyard": "True" + } + }, + { + "region_name": "Graveyard Warp Pad Region", + "scene": "Graveyard", + "hint": "the Graveyard", + "locations": { + "Graveyard Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle" + }, + "exits": { + "Graveyard": "True", + "Shadow Temple Entryway": " + can_use(Dins_Fire) or + (logic_shadow_fire_arrow_entry and can_use(Fire_Arrows))" + } + }, + { + "region_name": "Kak Behind Gate", + "scene": "Kakariko Village", + "hint": "Kakariko Village", + "exits": { + "Kakariko Village": " + is_adult or logic_visible_collisions or 'Kakariko Village Gate Open' or open_kakariko == 'open'", + "Death Mountain": "True" + } + }, + { + "region_name": "Death Mountain", + "scene": "Death Mountain", + "hint": "Death Mountain Trail", + "time_passes": true, + "locations": { + "DMT Chest": " + can_blast_or_smash or + (logic_dmt_bombable and is_child and Progressive_Strength_Upgrade)", + "DMT Freestanding PoH": " + can_take_damage or can_use(Hover_Boots) or + (is_adult and here(can_plant_bean and (has_explosives or Progressive_Strength_Upgrade)))", + "DMT GS Bean Patch": " + can_plant_bugs and can_child_attack and + (has_explosives or Progressive_Strength_Upgrade or + (logic_dmt_soil_gs and can_use(Boomerang)))", + "DMT GS Near Kak": "can_blast_or_smash", + "DMT GS Above Dodongos Cavern": " + is_adult and at_night and + (can_use(Megaton_Hammer) or + (logic_trail_gs_lower_hookshot and can_use(Hookshot)) or + (logic_trail_gs_lower_hovers and can_use(Hover_Boots)) or + (logic_trail_gs_lower_bean and here(can_plant_bean and (has_explosives or Progressive_Strength_Upgrade))))", + "Bean Plant Fairy": " + can_plant_bean and can_play(Song_of_Storms) and has_bottle and + (has_explosives or Progressive_Strength_Upgrade)" + }, + "exits": { + "Kak Behind Gate": "True", + "Goron City": "True", + "Death Mountain Summit": " + here(can_blast_or_smash) or + (is_adult and here(can_plant_bean and Progressive_Strength_Upgrade)) or + (logic_dmt_climb_hovers and can_use(Hover_Boots))", + "Dodongos Cavern Beginning": " + has_explosives or Progressive_Strength_Upgrade or is_adult", + "DMT Storms Grotto": "can_open_storm_grotto" + } + }, + { + "region_name": "Death Mountain Summit", + "scene": "Death Mountain", + "hint": "Death Mountain Trail", + "time_passes": true, + "events": { + "Prescription Access": "is_adult and ('Broken Sword Access' or Broken_Sword)" + }, + "locations": { + "DMT Biggoron": " + is_adult and + (Claim_Check or + (guarantee_trade_path and + ('Eyedrops Access' or (Eyedrops and disable_trade_revert))))", + "DMT GS Falling Rocks Path": " + is_adult and (can_use(Megaton_Hammer) or logic_trail_gs_upper) and at_night", + "DMT Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Bug Rock": "is_child and has_bottle" + }, + "exits": { + "Death Mountain": "True", + "DMC Upper Local": "True", + "DMT Owl Flight": "is_child", + "DMT Cow Grotto": "here(can_blast_or_smash)", + "DMT Great Fairy Fountain": "here(can_blast_or_smash)" + } + }, + { + "region_name": "DMT Owl Flight", + "scene": "Death Mountain", + "exits": { + "Kak Impas Rooftop": "True" + } + }, + { + "region_name": "Goron City", + "scene": "Goron City", + "hint": "Goron City", + "events": { + "Goron City Child Fire": "is_child and can_use(Dins_Fire)", + "GC Woods Warp Open": " + can_blast_or_smash or can_use(Dins_Fire) or can_use(Bow) or + Progressive_Strength_Upgrade or 'Goron City Child Fire'", + "Stop GC Rolling Goron as Adult": " + is_adult and + (Progressive_Strength_Upgrade or has_explosives or Bow or + (logic_link_goron_dins and can_use(Dins_Fire)))" + }, + "locations": { + "GC Maze Left Chest": " + can_use(Megaton_Hammer) or can_use(Silver_Gauntlets) or + (logic_goron_city_leftmost and has_explosives and can_use(Hover_Boots))", + "GC Maze Center Chest": " + can_blast_or_smash or can_use(Silver_Gauntlets)", + "GC Maze Right Chest": " + can_blast_or_smash or can_use(Silver_Gauntlets)", + "GC Pot Freestanding PoH": " + is_child and 'Goron City Child Fire' and + (Bombs or (Progressive_Strength_Upgrade and logic_goron_city_pot_with_strength) or (has_bombchus and logic_goron_city_pot))", + "GC Rolling Goron as Child": " + is_child and + (has_explosives or (Progressive_Strength_Upgrade and logic_child_rolling_with_strength))", + "GC Medigoron": " + is_adult and Progressive_Wallet and + (can_blast_or_smash or Progressive_Strength_Upgrade)", + "GC Rolling Goron as Adult": "'Stop GC Rolling Goron as Adult'", + "GC GS Boulder Maze": "is_child and has_explosives", + "GC GS Center Platform": "is_adult", + "GC Maze Gossip Stone": " + can_blast_or_smash or can_use(Silver_Gauntlets)", + "GC Medigoron Gossip Stone": " + can_blast_or_smash or Progressive_Strength_Upgrade", + "Gossip Stone Fairy": " + can_summon_gossip_fairy_without_suns and has_bottle and + (can_blast_or_smash or Progressive_Strength_Upgrade)", + "Bug Rock": "(can_blast_or_smash or can_use(Silver_Gauntlets)) and has_bottle", + "Stick Pot": "is_child" + }, + "exits": { + "Death Mountain": "True", + "GC Woods Warp": "'GC Woods Warp Open'", + "GC Shop": " + (is_adult and 'Stop GC Rolling Goron as Adult') or + (is_child and (has_explosives or Progressive_Strength_Upgrade or 'Goron City Child Fire'))", + "GC Darunias Chamber": " + (is_adult and 'Stop GC Rolling Goron as Adult') or + (is_child and can_play(Zeldas_Lullaby))", + "GC Grotto Platform": " + is_adult and + ((can_play(Song_of_Time) and + ((damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or + can_use(Goron_Tunic) or can_use(Longshot) or can_use(Nayrus_Love))) or + (can_use(Hookshot) and + ((damage_multiplier != 'ohko' and can_use(Goron_Tunic)) or + can_use(Nayrus_Love) or + (damage_multiplier != 'ohko' and damage_multiplier != 'quadruple' and logic_goron_grotto))))" + } + }, + { + "region_name": "GC Woods Warp", + "scene": "Goron City", + "hint": "Goron City", + "events": { + "GC Woods Warp Open": "can_blast_or_smash or can_use(Dins_Fire)" + }, + "exits": { + "Goron City": "can_leave_forest and 'GC Woods Warp Open'", + "Lost Woods": "True" + } + }, + { + "region_name": "GC Darunias Chamber", + "scene": "Goron City", + "hint": "Goron City", + "events": { + "Goron City Child Fire": "can_use(Sticks)" + }, + "locations": { + "GC Darunias Joy": "is_child and can_play(Sarias_Song)" + }, + "exits": { + "Goron City": "True", + "DMC Lower Local": "is_adult" + } + }, + { + "region_name": "GC Grotto Platform", + "scene": "Goron City", + "hint": "Goron City", + "exits": { + "GC Grotto": "True", + "Goron City": " + (damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or + can_use(Goron_Tunic) or can_use(Nayrus_Love) or + (can_play(Song_of_Time) and can_use(Longshot))" + } + }, + { + "region_name": "GC Shop", + "scene": "GC Shop", + "locations": { + "GC Shop Item 1": "True", + "GC Shop Item 2": "True", + "GC Shop Item 3": "True", + "GC Shop Item 4": "True", + "GC Shop Item 5": "True", + "GC Shop Item 6": "True", + "GC Shop Item 7": "True", + "GC Shop Item 8": "True" + }, + "exits": { + "Goron City": "True" + } + }, + { + "region_name": "DMC Upper Nearby", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "exits": { + "DMC Upper Local": "can_use(Goron_Tunic)", + "Death Mountain Summit": "True", + "DMC Upper Grotto": "here(can_blast_or_smash)" + } + }, + { + "region_name": "DMC Upper Local", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "locations": { + "DMC Wall Freestanding PoH": "True", + "DMC GS Crate": "is_child and can_child_attack", + "DMC Gossip Stone": "has_explosives", + "Gossip Stone Fairy": " + has_explosives and can_summon_gossip_fairy_without_suns and has_bottle" + }, + "exits": { + "DMC Upper Nearby": "True", + "DMC Ladder Area Nearby": "True", + "DMC Central Nearby": " + can_use(Goron_Tunic) and can_use(Longshot) and + ((damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or + (Fairy and not entrance_shuffle) or can_use(Nayrus_Love))" + } + }, + { + "region_name": "DMC Ladder Area Nearby", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "locations": { + "DMC Deku Scrub": "is_child and can_stun_deku" + }, + "exits": { + "DMC Upper Nearby": "is_adult", + "DMC Lower Nearby": " + can_use(Hover_Boots) or + (logic_crater_upper_to_lower and can_use(Megaton_Hammer))" + } + }, + { + "region_name": "DMC Lower Nearby", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "exits": { + "DMC Lower Local": "can_use(Goron_Tunic)", + "GC Darunias Chamber": "True", + "DMC Great Fairy Fountain": "can_use(Megaton_Hammer)", + "DMC Hammer Grotto": "can_use(Megaton_Hammer)" + } + }, + { + "region_name": "DMC Lower Local", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "exits": { + "DMC Lower Nearby": "True", + "DMC Ladder Area Nearby": "True", + "DMC Central Nearby": "can_use(Hover_Boots) or can_use(Hookshot)", + "DMC Fire Temple Entrance": " + (can_use(Hover_Boots) or can_use(Hookshot)) and + (logic_fewer_tunic_requirements or can_use(Goron_Tunic))" + } + }, + { + "region_name": "DMC Central Nearby", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "locations": { + "DMC Volcano Freestanding PoH": " + is_adult and + (here(can_plant_bean) or + (logic_crater_bean_poh_with_hovers and Hover_Boots))", + "Sheik in Crater": "is_adult" + }, + "exits": { + "DMC Central Local": "can_use(Goron_Tunic)" + } + }, + { + "region_name": "DMC Central Local", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "locations": { + "DMC GS Bean Patch": "can_plant_bugs and can_child_attack", + "Bean Plant Fairy": "can_plant_bean and can_play(Song_of_Storms) and has_bottle" + }, + "exits": { + "DMC Central Nearby": "True", + "DMC Lower Nearby": " + is_adult and + (can_use(Hover_Boots) or can_use(Hookshot) or here(can_plant_bean))", + "DMC Upper Nearby": "is_adult and here(can_plant_bean)", + "DMC Fire Temple Entrance": " + (is_child and shuffle_dungeon_entrances) or + (is_adult and (logic_fewer_tunic_requirements or can_use(Goron_Tunic)))" + } + }, + { + "region_name": "DMC Fire Temple Entrance", + "scene": "Death Mountain Crater", + "hint": "Death Mountain Crater", + "exits": { + "Fire Temple Lower": "True", + "DMC Central Nearby": "can_use(Goron_Tunic)" + } + }, + { + "region_name": "DMC Great Fairy Fountain", + "scene": "DMC Great Fairy Fountain", + "locations": { + "DMC Great Fairy Reward": "can_play(Zeldas_Lullaby)" + }, + "exits": { + "DMC Lower Local": "True" + } + }, + { + "region_name": "DMT Great Fairy Fountain", + "scene": "DMT Great Fairy Fountain", + "locations": { + "DMT Great Fairy Reward": "can_play(Zeldas_Lullaby)" + }, + "exits": { + "Death Mountain Summit": "True" + } + }, + { + "region_name": "ZR Front", + "scene": "Zora River", + "hint": "Zora's River", + "time_passes": true, + "locations": { + "ZR GS Tree": "is_child and can_child_attack" + }, + "exits": { + "Zora River": "is_adult or has_explosives", + "Hyrule Field": "True" + } + }, + { + "region_name": "Zora River", + "scene": "Zora River", + "hint": "Zora's River", + "time_passes": true, + "locations": { + "ZR Magic Bean Salesman": "is_child", + "ZR Frogs Ocarina Game": " + is_child and can_play(Zeldas_Lullaby) and can_play(Sarias_Song) and + can_play(Suns_Song) and can_play(Eponas_Song) and + can_play(Song_of_Time) and can_play(Song_of_Storms)", + "ZR Frogs in the Rain": "is_child and can_play(Song_of_Storms)", + "ZR Near Open Grotto Freestanding PoH": " + is_child or can_use(Hover_Boots) or (is_adult and logic_zora_river_lower)", + "ZR Near Domain Freestanding PoH": " + is_child or can_use(Hover_Boots) or (is_adult and logic_zora_river_upper)", + "ZR GS Ladder": "is_child and at_night and can_child_attack", + "ZR GS Near Raised Grottos": "can_use(Hookshot) and at_night", + "ZR GS Above Bridge": "can_use(Hookshot) and at_night", + "ZR Near Grottos Gossip Stone": "True", + "ZR Near Domain Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Bean Plant Fairy": "can_plant_bean and can_play(Song_of_Storms) and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": " + (is_child or can_use(Hover_Boots) or (is_adult and logic_zora_river_lower)) and + can_cut_shrubs and has_bottle" + }, + "exits": { + "ZR Front": "True", + "ZR Open Grotto": "True", + "ZR Fairy Grotto": "here(can_blast_or_smash)", + "Lost Woods": "can_dive or can_use(Iron_Boots)", + "ZR Storms Grotto": "can_open_storm_grotto", + "ZR Behind Waterfall": " + can_play(Zeldas_Lullaby) or + (can_use(Hover_Boots) and logic_zora_with_hovers) or + (is_child and logic_zora_with_cucco)" + } + }, + { + "region_name": "ZR Behind Waterfall", + "scene": "Zora River", + "hint": "Zora's River", + "exits": { + "Zora River": "True", + "Zoras Domain": "True" + } + }, + { + "region_name": "ZR Top of Waterfall", + "scene": "Zora River", + "hint": "Zora's River", + "exits": { + "Zora River": "True" + } + }, + { + "region_name": "Zoras Domain", + "scene": "Zoras Domain", + "hint": "Zora's Domain", + "events": { + "King Zora Thawed": "is_adult and Blue_Fire", + "Eyeball Frog Access": " + is_adult and 'King Zora Thawed' and + (Eyedrops or Eyeball_Frog or Prescription or 'Prescription Access')" + }, + "locations": { + "ZD Diving Minigame": "is_child", + "ZD Chest": "can_use(Sticks)", + "Deliver Rutos Letter": " + is_child and Rutos_Letter and zora_fountain != 'open'", + "ZD King Zora Thawed": "'King Zora Thawed'", + "ZD GS Frozen Waterfall": " + is_adult and at_night and + (Progressive_Hookshot or Bow or Magic_Meter or logic_domain_gs)", + "ZD Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle", + "Fish Group": "is_child and has_bottle", + "Stick Pot": "is_child", + "Nut Pot": "True" + }, + "exits": { + "ZR Behind Waterfall": "True", + "Lake Hylia": "is_child and can_dive", + "ZD Behind King Zora": " + Deliver_Letter or zora_fountain == 'open' or + (zora_fountain == 'adult' and is_adult)", + "ZD Shop": "is_child or Blue_Fire", + "ZD Storms Grotto": "can_open_storm_grotto" + } + }, + { + "region_name": "ZD Behind King Zora", + "scene": "Zoras Domain", + "hint": "Zora's Domain", + "exits": { + "Zoras Domain": " + Deliver_Letter or zora_fountain == 'open' or + (zora_fountain == 'adult' and is_adult)", + "Zoras Fountain": "True" + } + }, + { + "region_name": "ZD Eyeball Frog Timeout", + "scene": "Zoras Domain", + "hint": "Zora's Domain", + "exits": { + "Zoras Domain": "True" + } + }, + { + "region_name": "Zoras Fountain", + "scene": "Zoras Fountain", + "hint": "Zora's Fountain", + "locations": { + "ZF Iceberg Freestanding PoH": "is_adult", + "ZF Bottom Freestanding PoH": " + is_adult and Iron_Boots and (logic_fewer_tunic_requirements or can_use(Zora_Tunic))", + "ZF GS Tree": "is_child", + "ZF GS Above the Log": "can_use(Boomerang) and at_night", + "ZF GS Hidden Cave": " + can_use(Silver_Gauntlets) and can_blast_or_smash and + can_use(Hookshot) and at_night", + "ZF Fairy Gossip Stone": "True", + "ZF Jabu Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy_without_suns and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and at_day and has_bottle" + }, + "exits": { + "ZD Behind King Zora": "True", + "Jabu Jabus Belly Beginning": "is_child and Fish", + "ZF Ice Ledge": "is_adult", + "ZF Great Fairy Fountain": "has_explosives" + } + }, + { + "region_name": "ZF Ice Ledge", + "scene": "Zoras Fountain", + "hint": "Zora's Fountain", + "exits": { + "Zoras Fountain": "True", + "Ice Cavern Beginning": "True" + } + }, + { + "region_name": "ZD Shop", + "scene": "ZD Shop", + "locations": { + "ZD Shop Item 1": "True", + "ZD Shop Item 2": "True", + "ZD Shop Item 3": "True", + "ZD Shop Item 4": "True", + "ZD Shop Item 5": "True", + "ZD Shop Item 6": "True", + "ZD Shop Item 7": "True", + "ZD Shop Item 8": "True" + }, + "exits": { + "Zoras Domain": "True" + } + }, + { + "region_name": "ZF Great Fairy Fountain", + "scene": "ZF Great Fairy Fountain", + "locations": { + "ZF Great Fairy Reward": "can_play(Zeldas_Lullaby)" + }, + "exits": { + "Zoras Fountain": "True" + } + }, + { + "region_name": "Lon Lon Ranch", + "scene": "Lon Lon Ranch", + "hint": "Lon Lon Ranch", + "events": { + "Epona": "can_play(Eponas_Song) and is_adult and at_day", + "Links Cow": "can_play(Eponas_Song) and is_adult and at_day" + }, + "locations": { + "Song from Malon": "is_child and Zeldas_Letter and Ocarina and at_day", + "LLR GS Tree": "is_child", + "LLR GS Rain Shed": "is_child and at_night", + "LLR GS House Window": "can_use(Boomerang) and at_night", + "LLR GS Back Wall": "can_use(Boomerang) and at_night" + }, + "exits": { + "Hyrule Field": "True", + "LLR Talons House": "is_adult or at_day", + "LLR Stables": "True", + "LLR Tower": "True", + "LLR Grotto": "is_child" + } + }, + { + "region_name": "LLR Talons House", + "scene": "LLR Talons House", + "locations": { + "LLR Talons Chickens": "is_child and at_day and Zeldas_Letter" + }, + "exits": { + "Lon Lon Ranch": "True" + } + }, + { + "region_name": "LLR Stables", + "scene": "LLR Stables", + "locations": { + "LLR Stables Left Cow": "can_play(Eponas_Song)", + "LLR Stables Right Cow": "can_play(Eponas_Song)" + }, + "exits": { + "Lon Lon Ranch": "True" + } + }, + { + "region_name": "LLR Tower", + "scene": "LLR Tower", + "locations": { + "LLR Freestanding PoH": "is_child", + "LLR Tower Left Cow": "can_play(Eponas_Song)", + "LLR Tower Right Cow": "can_play(Eponas_Song)" + }, + "exits": { + "Lon Lon Ranch": "True" + } + }, + { + "region_name": "Ganons Castle Tower", + "dungeon": "Ganons Castle", + "locations": { + "Ganons Tower Boss Key Chest": "True", + "Ganondorf Hint": "Boss_Key_Ganons_Castle", + "Ganon": "Boss_Key_Ganons_Castle and can_use(Light_Arrows)" + } + }, + { + "region_name": "GF Storms Grotto", + "scene": "GF Storms Grotto", + "locations": { + "Free Fairies": "has_bottle" + }, + "exits": { + "Gerudo Fortress": "True" + } + }, + { + "region_name": "ZD Storms Grotto", + "scene": "ZD Storms Grotto", + "locations": { + "Free Fairies": "has_bottle" + }, + "exits": { + "Zoras Domain": "True" + } + }, + { + "region_name": "KF Storms Grotto", + "scene": "KF Storms Grotto", + "locations": { + "KF Storms Grotto Chest": "True", + "KF Storms Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Kokiri Forest": "True" + } + }, + { + "region_name": "LW Near Shortcuts Grotto", + "scene": "LW Near Shortcuts Grotto", + "locations": { + "LW Near Shortcuts Grotto Chest": "True", + "LW Near Shortcuts Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Lost Woods": "True" + } + }, + { + "region_name": "Deku Theater", + "scene": "Deku Theater", + "locations": { + "Deku Theater Skull Mask": "is_child and 'Skull Mask'", + "Deku Theater Mask of Truth": "is_child and 'Mask of Truth'" + }, + "exits": { + "LW Beyond Mido": "True" + } + }, + { + "region_name": "LW Scrubs Grotto", + "scene": "LW Scrubs Grotto", + "locations": { + "LW Deku Scrub Grotto Rear": "can_stun_deku", + "LW Deku Scrub Grotto Front": "can_stun_deku" + }, + "exits": { + "LW Beyond Mido": "True" + } + }, + { + "region_name": "SFM Fairy Grotto", + "scene": "SFM Fairy Grotto", + "locations": { + "Free Fairies": "has_bottle" + }, + "exits": { + "Sacred Forest Meadow": "True" + } + }, + { + "region_name": "SFM Storms Grotto", + "scene": "SFM Storms Grotto", + "locations": { + "SFM Deku Scrub Grotto Rear": "can_stun_deku", + "SFM Deku Scrub Grotto Front": "can_stun_deku" + }, + "exits": { + "Sacred Forest Meadow": "True" + } + }, + { + "region_name": "SFM Wolfos Grotto", + "scene": "SFM Wolfos Grotto", + "locations": { + "SFM Wolfos Grotto Chest": " + is_adult or Slingshot or Sticks or + Kokiri_Sword or can_use(Dins_Fire)" + }, + "exits": { + "SFM Entryway": "True" + } + }, + { + "region_name": "LLR Grotto", + "scene": "LLR Grotto", + "locations": { + "LLR Deku Scrub Grotto Left": "can_stun_deku", + "LLR Deku Scrub Grotto Right": "can_stun_deku", + "LLR Deku Scrub Grotto Center": "can_stun_deku" + }, + "exits": { + "Lon Lon Ranch": "True" + } + }, + { + "region_name": "HF Southeast Grotto", + "scene": "HF Southeast Grotto", + "locations": { + "HF Southeast Grotto Chest": "True", + "HF Southeast Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HF Open Grotto", + "scene": "HF Open Grotto", + "locations": { + "HF Open Grotto Chest": "True", + "HF Open Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HF Inside Fence Grotto", + "scene": "HF Inside Fence Grotto", + "locations": { + "HF Deku Scrub Grotto": "can_stun_deku" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HF Cow Grotto", + "scene": "HF Cow Grotto", + "locations": { + "HF GS Cow Grotto": " + has_fire_source and (can_use(Hookshot) or can_use(Boomerang))", + "HF Cow Grotto Cow": "has_fire_source and can_play(Eponas_Song)", + "HF Cow Grotto Gossip Stone": "has_fire_source", + "Gossip Stone Fairy": "has_fire_source and can_summon_gossip_fairy and has_bottle", + "Bug Shrub": "has_fire_source and can_cut_shrubs and has_bottle", + "Nut Pot": "has_fire_source" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HF Near Market Grotto", + "scene": "HF Near Market Grotto", + "locations": { + "HF Near Market Grotto Chest": "True", + "HF Near Market Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HF Fairy Grotto", + "scene": "HF Fairy Grotto", + "locations": { + "Free Fairies": "has_bottle" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HF Near Kak Grotto", + "scene": "HF Near Kak Grotto", + "locations": { + "HF GS Near Kak Grotto": "can_use(Boomerang) or can_use(Hookshot)" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HF Tektite Grotto", + "scene": "HF Tektite Grotto", + "locations": { + "HF Tektite Grotto Freestanding PoH": " + (Progressive_Scale, 2) or can_use(Iron_Boots)" + }, + "exits": { + "Hyrule Field": "True" + } + }, + { + "region_name": "HC Storms Grotto", + "scene": "HC Storms Grotto", + "locations": { + "HC GS Storms Grotto": " + (can_blast_or_smash or (is_child and logic_castle_storms_gs)) and + (can_use(Boomerang) or can_use(Hookshot))", + "HC Storms Grotto Gossip Stone": "can_blast_or_smash", + "Gossip Stone Fairy": "can_blast_or_smash and can_summon_gossip_fairy and has_bottle", + "Wandering Bugs": "can_blast_or_smash and has_bottle", + "Nut Pot": "can_blast_or_smash" + }, + "exits": { + "Castle Grounds": "True" + } + }, + { + "region_name": "Kak Redead Grotto", + "scene": "Kak Redead Grotto", + "locations": { + "Kak Redead Grotto Chest": " + is_adult or + (Sticks or Kokiri_Sword or can_use(Dins_Fire))" + }, + "exits": { + "Kakariko Village": "True" + } + }, + { + "region_name": "Kak Open Grotto", + "scene": "Kak Open Grotto", + "locations": { + "Kak Open Grotto Chest": "True", + "Kak Open Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Kak Backyard": "True" + } + }, + { + "region_name": "DMT Cow Grotto", + "scene": "DMT Cow Grotto", + "locations": { + "DMT Cow Grotto Cow": "can_play(Eponas_Song)" + }, + "exits": { + "Death Mountain Summit": "True" + } + }, + { + "region_name": "DMT Storms Grotto", + "scene": "DMT Storms Grotto", + "locations": { + "DMT Storms Grotto Chest": "True", + "DMT Storms Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Death Mountain": "True" + } + }, + { + "region_name": "GC Grotto", + "scene": "GC Grotto", + "locations": { + "GC Deku Scrub Grotto Left": "can_stun_deku", + "GC Deku Scrub Grotto Right": "can_stun_deku", + "GC Deku Scrub Grotto Center": "can_stun_deku" + }, + "exits": { + "GC Grotto Platform": "True" + } + }, + { + "region_name": "DMC Upper Grotto", + "scene": "DMC Upper Grotto", + "locations": { + "DMC Upper Grotto Chest": "True", + "DMC Upper Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "DMC Upper Local": "True" + } + }, + { + "region_name": "DMC Hammer Grotto", + "scene": "DMC Hammer Grotto", + "locations": { + "DMC Deku Scrub Grotto Left": "can_stun_deku", + "DMC Deku Scrub Grotto Right": "can_stun_deku", + "DMC Deku Scrub Grotto Center": "can_stun_deku" + }, + "exits": { + "DMC Lower Local": "True" + } + }, + { + "region_name": "ZR Open Grotto", + "scene": "ZR Open Grotto", + "locations": { + "ZR Open Grotto Chest": "True", + "ZR Open Grotto Gossip Stone": "True", + "Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle", + "Butterfly Fairy": "can_use(Sticks) and has_bottle", + "Bug Shrub": "can_cut_shrubs and has_bottle", + "Lone Fish": "has_bottle" + }, + "exits": { + "Zora River": "True" + } + }, + { + "region_name": "ZR Fairy Grotto", + "scene": "ZR Fairy Grotto", + "locations": { + "Free Fairies": "has_bottle" + }, + "exits": { + "Zora River": "True" + } + }, + { + "region_name": "ZR Storms Grotto", + "scene": "ZR Storms Grotto", + "locations": { + "ZR Deku Scrub Grotto Rear": "can_stun_deku", + "ZR Deku Scrub Grotto Front": "can_stun_deku" + }, + "exits": { + "Zora River": "True" + } + }, + { + "region_name": "LH Grotto", + "scene": "LH Grotto", + "locations": { + "LH Deku Scrub Grotto Left": "can_stun_deku", + "LH Deku Scrub Grotto Right": "can_stun_deku", + "LH Deku Scrub Grotto Center": "can_stun_deku" + }, + "exits": { + "Lake Hylia": "True" + } + }, + { + "region_name": "Colossus Grotto", + "scene": "Colossus Grotto", + "locations": { + "Colossus Deku Scrub Grotto Rear": "can_stun_deku", + "Colossus Deku Scrub Grotto Front": "can_stun_deku" + }, + "exits": { + "Desert Colossus": "True" + } + }, + { + "region_name": "GV Octorok Grotto", + "scene": "GV Octorok Grotto", + "exits": { + "GV Grotto Ledge": "True" + } + }, + { + "region_name": "GV Storms Grotto", + "scene": "GV Storms Grotto", + "locations": { + "GV Deku Scrub Grotto Rear": "can_stun_deku", + "GV Deku Scrub Grotto Front": "can_stun_deku" + }, + "exits": { + "GV Fortress Side": "True" + } + } +] diff --git a/worlds/oot/data/World/Shadow Temple MQ.json b/worlds/oot/data/World/Shadow Temple MQ.json new file mode 100644 index 00000000..6a69c407 --- /dev/null +++ b/worlds/oot/data/World/Shadow Temple MQ.json @@ -0,0 +1,127 @@ +[ + { + "region_name": "Shadow Temple Entryway", + "dungeon": "Shadow Temple", + "exits": { + "Graveyard Warp Pad Region": "True", + "Shadow Temple Beginning": " + (logic_lens_shadow_mq or can_use(Lens_of_Truth)) and + (can_use(Hover_Boots) or can_use(Hookshot))" + } + }, + { + "region_name": "Shadow Temple Beginning", + "dungeon": "Shadow Temple", + "exits": { + "Shadow Temple Entryway": "True", + "Shadow Temple First Beamos": " + can_use(Fire_Arrows) or Hover_Boots or + (logic_shadow_mq_gap and can_use(Longshot))", + "Shadow Temple Dead Hand Area": "has_explosives and (Small_Key_Shadow_Temple, 6)" + } + }, + { + "region_name": "Shadow Temple Dead Hand Area", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Compass Chest": "True", + "Shadow Temple MQ Hover Boots Chest": "can_play(Song_of_Time) and Bow" + } + }, + { + "region_name": "Shadow Temple First Beamos", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Map Chest": "True", + "Shadow Temple MQ Early Gibdos Chest": "True", + "Shadow Temple MQ Near Ship Invisible Chest": "True" + }, + "exits": { + "Shadow Temple Upper Huge Pit": "has_explosives and (Small_Key_Shadow_Temple, 2)" + } + }, + { + "region_name": "Shadow Temple Upper Huge Pit", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Invisible Blades Visible Chest": " + can_play(Song_of_Time) or + (logic_shadow_mq_invisible_blades and damage_multiplier != 'ohko')", + "Shadow Temple MQ Invisible Blades Invisible Chest": " + can_play(Song_of_Time) or + (logic_shadow_mq_invisible_blades and damage_multiplier != 'ohko')" + }, + "exits": { + "Shadow Temple Lower Huge Pit": "has_fire_source or logic_shadow_mq_huge_pit" + } + }, + { + "region_name": "Shadow Temple Lower Huge Pit", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Beamos Silver Rupees Chest": "can_use(Longshot)", + "Shadow Temple MQ Falling Spikes Lower Chest": "True", + "Shadow Temple MQ Falling Spikes Upper Chest": " + (logic_shadow_umbrella and Hover_Boots) or Progressive_Strength_Upgrade", + "Shadow Temple MQ Falling Spikes Switch Chest": " + (logic_shadow_umbrella and Hover_Boots) or Progressive_Strength_Upgrade", + "Shadow Temple MQ Invisible Spikes Chest": " + Hover_Boots and (Small_Key_Shadow_Temple, 3) and + (logic_lens_shadow_mq_back or can_use(Lens_of_Truth))", + "Shadow Temple MQ Stalfos Room Chest": " + Hover_Boots and (Small_Key_Shadow_Temple, 3) and Progressive_Hookshot and + (logic_lens_shadow_mq_back or can_use(Lens_of_Truth))", + "Shadow Temple MQ GS Falling Spikes Room": " + (logic_shadow_umbrella_gs and Hover_Boots) or Progressive_Hookshot" + }, + "exits": { + "Shadow Temple Wind Tunnel": " + Hover_Boots and (logic_lens_shadow_mq_back or can_use(Lens_of_Truth)) and + Progressive_Hookshot and (Small_Key_Shadow_Temple, 4)" + } + }, + { + "region_name": "Shadow Temple Wind Tunnel", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Wind Hint Chest": "True", + "Shadow Temple MQ After Wind Enemy Chest": "True", + "Shadow Temple MQ After Wind Hidden Chest": "True", + "Shadow Temple MQ GS Wind Hint Room": "True", + "Shadow Temple MQ GS After Wind": "True", + "Nut Pot": "True" + }, + "exits": { + "Shadow Temple Beyond Boat": " + can_play(Zeldas_Lullaby) and (Small_Key_Shadow_Temple, 5)" + } + }, + { + "region_name": "Shadow Temple Beyond Boat", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Bongo Bongo Heart": " + (Bow or (logic_shadow_statue and has_bombchus)) and Boss_Key_Shadow_Temple", + "Bongo Bongo": " + (Bow or (logic_shadow_statue and has_bombchus)) and Boss_Key_Shadow_Temple", + "Shadow Temple MQ GS After Ship": "True", + "Shadow Temple MQ GS Near Boss": "Bow or (logic_shadow_statue and has_bombchus)" + }, + "exits": { + "Shadow Temple Invisible Maze": " + Bow and can_play(Song_of_Time) and can_use(Longshot)" + } + }, + { + "region_name": "Shadow Temple Invisible Maze", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple MQ Spike Walls Left Chest": " + can_use(Dins_Fire) and (Small_Key_Shadow_Temple, 6)", + "Shadow Temple MQ Boss Key Chest": " + can_use(Dins_Fire) and (Small_Key_Shadow_Temple, 6)", + "Shadow Temple MQ Bomb Flower Chest": "True", + "Shadow Temple MQ Freestanding Key": "True" + } + } +] diff --git a/worlds/oot/data/World/Shadow Temple.json b/worlds/oot/data/World/Shadow Temple.json new file mode 100644 index 00000000..2c4c8635 --- /dev/null +++ b/worlds/oot/data/World/Shadow Temple.json @@ -0,0 +1,93 @@ +[ + { + "region_name": "Shadow Temple Entryway", + "dungeon": "Shadow Temple", + "exits": { + "Graveyard Warp Pad Region": "True", + "Shadow Temple Beginning": " + (logic_lens_shadow or can_use(Lens_of_Truth)) and + (can_use(Hover_Boots) or can_use(Hookshot))" + } + }, + { + "region_name": "Shadow Temple Beginning", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Map Chest": "True", + "Shadow Temple Hover Boots Chest": "True", + "Nut Pot": "True" + }, + "exits": { + "Shadow Temple Entryway": "True", + "Shadow Temple First Beamos": "Hover_Boots" + } + }, + { + "region_name": "Shadow Temple First Beamos", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Compass Chest": "True", + "Shadow Temple Early Silver Rupee Chest": "True" + }, + "exits": { + "Shadow Temple Huge Pit": "has_explosives and (Small_Key_Shadow_Temple, 1)" + } + }, + { + "region_name": "Shadow Temple Huge Pit", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Invisible Blades Visible Chest": "True", + "Shadow Temple Invisible Blades Invisible Chest": "True", + "Shadow Temple Falling Spikes Lower Chest": "True", + "Shadow Temple Falling Spikes Upper Chest": "logic_shadow_umbrella or Progressive_Strength_Upgrade", + "Shadow Temple Falling Spikes Switch Chest": "logic_shadow_umbrella or Progressive_Strength_Upgrade", + "Shadow Temple Invisible Spikes Chest": " + (Small_Key_Shadow_Temple, 2) and (logic_lens_shadow_back or can_use(Lens_of_Truth))", + "Shadow Temple Freestanding Key": " + (Small_Key_Shadow_Temple, 2) and (logic_lens_shadow_back or can_use(Lens_of_Truth)) + and Progressive_Hookshot and + (Bombs or Progressive_Strength_Upgrade or + (logic_shadow_freestanding_key and has_bombchus))", + "Shadow Temple GS Like Like Room": "True", + "Shadow Temple GS Falling Spikes Room": "logic_shadow_umbrella_gs or Progressive_Hookshot", + "Shadow Temple GS Single Giant Pot": " + (Small_Key_Shadow_Temple, 2) and (logic_lens_shadow_back or can_use(Lens_of_Truth)) + and Progressive_Hookshot" + }, + "exits": { + "Shadow Temple Wind Tunnel": " + (logic_lens_shadow_back or can_use(Lens_of_Truth)) and + Progressive_Hookshot and (Small_Key_Shadow_Temple, 3)" + } + }, + { + "region_name": "Shadow Temple Wind Tunnel", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Wind Hint Chest": "True", + "Shadow Temple After Wind Enemy Chest": "True", + "Shadow Temple After Wind Hidden Chest": "True", + "Shadow Temple GS Near Ship": "can_use(Longshot) and (Small_Key_Shadow_Temple, 4)" + }, + "exits": { + "Shadow Temple Beyond Boat": "can_play(Zeldas_Lullaby) and (Small_Key_Shadow_Temple, 4)" + } + }, + { + "region_name": "Shadow Temple Beyond Boat", + "dungeon": "Shadow Temple", + "locations": { + "Shadow Temple Spike Walls Left Chest": "can_use(Dins_Fire)", + "Shadow Temple Boss Key Chest": "can_use(Dins_Fire)", + "Shadow Temple Invisible Floormaster Chest": "True", + "Shadow Temple Bongo Bongo Heart": " + (Small_Key_Shadow_Temple, 5) and Boss_Key_Shadow_Temple and + (Bow or can_use(Distant_Scarecrow) or (logic_shadow_statue and has_bombchus))", + "Bongo Bongo": " + (Small_Key_Shadow_Temple, 5) and Boss_Key_Shadow_Temple and + (Bow or can_use(Distant_Scarecrow) or (logic_shadow_statue and has_bombchus))", + "Shadow Temple GS Triple Giant Pot": "True" + } + } +] diff --git a/worlds/oot/data/World/Spirit Temple MQ.json b/worlds/oot/data/World/Spirit Temple MQ.json new file mode 100644 index 00000000..2494d201 --- /dev/null +++ b/worlds/oot/data/World/Spirit Temple MQ.json @@ -0,0 +1,147 @@ +[ + { + "region_name": "Spirit Temple Lobby", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Entrance Front Left Chest": "True", + "Spirit Temple MQ Entrance Back Left Chest": " + here(can_blast_or_smash) and + (can_use(Slingshot) or can_use(Bow))", + "Spirit Temple MQ Entrance Back Right Chest": " + has_bombchus or can_use(Bow) or can_use(Hookshot) or + can_use(Slingshot) or can_use(Boomerang)" + }, + "exits": { + "Desert Colossus From Spirit Lobby": "True", + "Child Spirit Temple": "is_child", + "Adult Spirit Temple": " + has_bombchus and can_use(Longshot) and can_use(Silver_Gauntlets)" + } + }, + { + "region_name": "Child Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Child Hammer Switch Chest": " + at('Adult Spirit Temple', (Small_Key_Spirit_Temple, 7) and Megaton_Hammer)", + "Spirit Temple MQ Map Room Enemy Chest": " + (Sticks or Kokiri_Sword) and + has_bombchus and Slingshot and can_use(Dins_Fire)", + "Spirit Temple MQ Map Chest": "Sticks or Kokiri_Sword or Bombs", + "Spirit Temple MQ Silver Block Hallway Chest": " + has_bombchus and (Small_Key_Spirit_Temple, 7) and Slingshot and + (can_use(Dins_Fire) or + at('Adult Spirit Temple', (can_use(Fire_Arrows) or + (logic_spirit_mq_frozen_eye and can_use(Bow) and can_play(Song_of_Time)))))", + "Fairy Pot": " + has_bottle and (Sticks or Kokiri_Sword) and + has_bombchus and Slingshot" + }, + "exits": { + "Spirit Temple Shared": "has_bombchus and (Small_Key_Spirit_Temple, 2)" + } + }, + { + "region_name": "Adult Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Child Climb South Chest": "(Small_Key_Spirit_Temple, 7)", + "Spirit Temple MQ Statue Room Lullaby Chest": "can_play(Zeldas_Lullaby)", + "Spirit Temple MQ Statue Room Invisible Chest": " + logic_lens_spirit_mq or can_use(Lens_of_Truth)", + "Spirit Temple MQ Beamos Room Chest": "(Small_Key_Spirit_Temple, 5)", + "Spirit Temple MQ Chest Switch Chest": " + (Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time)", + "Spirit Temple MQ Boss Key Chest": " + (Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time) and Mirror_Shield", + "Spirit Temple MQ GS Nine Thrones Room West": "(Small_Key_Spirit_Temple, 7)", + "Spirit Temple MQ GS Nine Thrones Room North": "(Small_Key_Spirit_Temple, 7)" + }, + "exits": { + "Lower Adult Spirit Temple": " + Mirror_Shield and (can_use(Fire_Arrows) or + (logic_spirit_mq_lower_adult and can_use(Dins_Fire) and Bow))", + "Spirit Temple Shared": "True", + "Spirit Temple Boss Area": " + (Small_Key_Spirit_Temple, 6) and can_play(Zeldas_Lullaby) and Megaton_Hammer", + "Mirror Shield Hand": " + (Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time) and + (logic_lens_spirit_mq or can_use(Lens_of_Truth))" + } + }, + { + #In this region, child reachability really means age-unknown, but with the caveat + #that child has as least entered the dungeon. is_adult means is_adult as usual. + #All child specific logic must be anded with 7 keys to convert child-as-unknown-age + #back to child. + "region_name": "Spirit Temple Shared", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Child Climb North Chest": "(Small_Key_Spirit_Temple, 6)", + "Spirit Temple MQ Compass Chest": " + (can_use(Slingshot) and (Small_Key_Spirit_Temple, 7)) or + can_use(Bow) or + (Bow and Slingshot)", + "Spirit Temple MQ Sun Block Room Chest": " + can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or + is_adult", + "Spirit Temple MQ GS Sun Block Room": " + (logic_spirit_mq_sun_block_gs and Boomerang and + (can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot)) or + is_adult" + }, + "exits": { + "Silver Gauntlets Hand": " + ((Small_Key_Spirit_Temple, 7) and + (can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or is_adult)) or + ((Small_Key_Spirit_Temple, 4) and can_play(Song_of_Time) and + (logic_lens_spirit_mq or can_use(Lens_of_Truth)))", + "Desert Colossus": " + ((Small_Key_Spirit_Temple, 7) and + (can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or is_adult)) or + ((Small_Key_Spirit_Temple, 4) and can_play(Song_of_Time) and + (logic_lens_spirit_mq or can_use(Lens_of_Truth)) and is_adult)" + } + }, + { + "region_name": "Lower Adult Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Leever Room Chest": "True", + "Spirit Temple MQ Symphony Room Chest": " + (Small_Key_Spirit_Temple, 7) and Megaton_Hammer and Ocarina and + Song_of_Time and Eponas_Song and Suns_Song and + Song_of_Storms and Zeldas_Lullaby", + "Spirit Temple MQ Entrance Front Right Chest": "Megaton_Hammer", + "Spirit Temple MQ GS Leever Room": "True", + "Spirit Temple MQ GS Symphony Room": " + (Small_Key_Spirit_Temple, 7) and Megaton_Hammer and Ocarina and + Song_of_Time and Eponas_Song and Suns_Song and + Song_of_Storms and Zeldas_Lullaby" + } + }, + { + "region_name": "Spirit Temple Boss Area", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple MQ Mirror Puzzle Invisible Chest": " + logic_lens_spirit_mq or can_use(Lens_of_Truth)", + "Spirit Temple Twinrova Heart": "Mirror_Shield and Boss_Key_Spirit_Temple", + "Twinrova": "Mirror_Shield and Boss_Key_Spirit_Temple" + } + }, + { + "region_name": "Mirror Shield Hand", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Mirror Shield Chest": "True" + } + }, + { + "region_name": "Silver Gauntlets Hand", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Silver Gauntlets Chest": "True" + } + } +] diff --git a/worlds/oot/data/World/Spirit Temple.json b/worlds/oot/data/World/Spirit Temple.json new file mode 100644 index 00000000..49708855 --- /dev/null +++ b/worlds/oot/data/World/Spirit Temple.json @@ -0,0 +1,192 @@ +[ + { + "region_name": "Spirit Temple Lobby", + "dungeon": "Spirit Temple", + "exits": { + "Desert Colossus From Spirit Lobby": "True", + "Child Spirit Temple": "is_child", + "Early Adult Spirit Temple": "can_use(Silver_Gauntlets)" + } + }, + { + "region_name": "Child Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Child Bridge Chest": " + (Boomerang or Slingshot or (has_bombchus and logic_spirit_child_bombchu)) and + (Sticks or has_explosives or + ((Nuts or Boomerang) and + (Kokiri_Sword or Slingshot)))", + "Spirit Temple Child Early Torches Chest": " + (Boomerang or Slingshot or (has_bombchus and logic_spirit_child_bombchu)) and + (Sticks or has_explosives or + ((Nuts or Boomerang) and (Kokiri_Sword or Slingshot))) and + (Sticks or can_use(Dins_Fire))", + "Spirit Temple GS Metal Fence": " + (Boomerang or Slingshot or (has_bombchus and logic_spirit_child_bombchu)) and + (Sticks or has_explosives or + ((Nuts or Boomerang) and (Kokiri_Sword or Slingshot)))" + }, + "exits": { + "Child Spirit Before Locked Door": "True" + } + }, + { + "region_name": "Child Spirit Before Locked Door", + "dungeon": "Spirit Temple", + "locations": { + "Nut Crate": "True" + }, + "exits": { + "Child Spirit Temple Climb": "(Small_Key_Spirit_Temple, 1)" + } + }, + { + "region_name": "Child Spirit Temple Climb", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Child Climb North Chest": " + has_projectile(both) or + (((Small_Key_Spirit_Temple, 3) or + ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and + can_use(Silver_Gauntlets) and has_projectile(adult)) or + ((Small_Key_Spirit_Temple, 5) and is_child and + has_projectile(child))", + "Spirit Temple Child Climb East Chest": " + has_projectile(both) or + (((Small_Key_Spirit_Temple, 3) or + ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and + can_use(Silver_Gauntlets) and has_projectile(adult)) or + ((Small_Key_Spirit_Temple, 5) and is_child and + has_projectile(child))", + "Spirit Temple GS Sun on Floor Room": " + has_projectile(both) or can_use(Dins_Fire) or + (can_take_damage and (Sticks or Kokiri_Sword or has_projectile(child))) or + (is_child and + (Small_Key_Spirit_Temple, 5) and has_projectile(child)) or + (((Small_Key_Spirit_Temple, 3) or + ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and + can_use(Silver_Gauntlets) and + (has_projectile(adult) or can_take_damage))" + }, + "exits": { + "Spirit Temple Central Chamber": "has_explosives", + "Child Spirit Before Locked Door": "(Small_Key_Spirit_Temple, 5)" + } + }, + { + "region_name": "Early Adult Spirit Temple", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Compass Chest": " + can_use(Hookshot) and can_play(Zeldas_Lullaby)", + "Spirit Temple Early Adult Right Chest": " + Bow or Progressive_Hookshot or has_bombchus or (Bombs and logic_spirit_lower_adult_switch)", + #requires a very specific Bombchu use, Hover Boots can be skipped by jumping on top of the rolling rock. + "Spirit Temple First Mirror Left Chest": "(Small_Key_Spirit_Temple, 3)", + "Spirit Temple First Mirror Right Chest": "(Small_Key_Spirit_Temple, 3)", + "Spirit Temple GS Boulder Room": " + can_play(Song_of_Time) and + (Bow or Progressive_Hookshot or has_bombchus or (Bombs and logic_spirit_lower_adult_switch))" + }, + "exits": { + "Spirit Temple Central Chamber": "(Small_Key_Spirit_Temple, 1)" + } + }, + { + "region_name": "Spirit Temple Central Chamber", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Map Chest": " + ((has_explosives or (Small_Key_Spirit_Temple, 3) or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and + (can_use(Dins_Fire) or + (((Magic_Meter and Fire_Arrows) or logic_spirit_map_chest) and Bow and Sticks))) or + ((Small_Key_Spirit_Temple, 5) and has_explosives and + can_use(Sticks)) or + ((Small_Key_Spirit_Temple, 3) and + (can_use(Fire_Arrows) or (logic_spirit_map_chest and Bow)) and + can_use(Silver_Gauntlets))", + "Spirit Temple Sun Block Room Chest": " + ((has_explosives or (Small_Key_Spirit_Temple, 3) or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and + (can_use(Dins_Fire) or + (((Magic_Meter and Fire_Arrows) or logic_spirit_sun_chest) and Bow and Sticks))) or + ((Small_Key_Spirit_Temple, 5) and has_explosives and + can_use(Sticks)) or + ((Small_Key_Spirit_Temple, 3) and + (can_use(Fire_Arrows) or (logic_spirit_sun_chest and Bow)) and + can_use(Silver_Gauntlets))", + "Spirit Temple Statue Room Hand Chest": " + (Small_Key_Spirit_Temple, 3) and can_use(Silver_Gauntlets) and + can_play(Zeldas_Lullaby)", + "Spirit Temple Statue Room Northeast Chest": " + (Small_Key_Spirit_Temple, 3) and can_use(Silver_Gauntlets) and can_play(Zeldas_Lullaby) and + (Progressive_Hookshot or Hover_Boots or logic_spirit_lobby_jump)", + "Spirit Temple GS Hall After Sun Block Room": " + (has_explosives and Boomerang and Progressive_Hookshot) or + (can_use(Boomerang) and (Small_Key_Spirit_Temple, 5) and has_explosives) or + (Progressive_Hookshot and can_use(Silver_Gauntlets) and + ((Small_Key_Spirit_Temple, 3) or + ((Small_Key_Spirit_Temple, 2) and Boomerang and bombchus_in_logic and not entrance_shuffle)))", + "Spirit Temple GS Lobby": " + ((has_explosives or (Small_Key_Spirit_Temple, 3) or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and + logic_spirit_lobby_gs and Boomerang and (Progressive_Hookshot or Hover_Boots or logic_spirit_lobby_jump)) or + (logic_spirit_lobby_gs and (Small_Key_Spirit_Temple, 5) and has_explosives and can_use(Boomerang)) or + ((Small_Key_Spirit_Temple, 3) and can_use(Silver_Gauntlets) and (Progressive_Hookshot or Hover_Boots or logic_spirit_lobby_jump))" + }, + "exits": { + "Spirit Temple Outdoor Hands": "True", + "Spirit Temple Beyond Central Locked Door": " + (Small_Key_Spirit_Temple, 4) and can_use(Silver_Gauntlets)", + "Child Spirit Temple Climb": "True" + } + }, + { + "region_name": "Spirit Temple Outdoor Hands", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Silver Gauntlets Chest": " + ((Small_Key_Spirit_Temple, 3) and (Progressive_Hookshot, 2) and has_explosives) or + (Small_Key_Spirit_Temple, 5)", + "Spirit Temple Mirror Shield Chest": " + (Small_Key_Spirit_Temple, 4) and can_use(Silver_Gauntlets) and has_explosives" + }, + "exits": { + "Desert Colossus": " + (is_child and (Small_Key_Spirit_Temple, 5)) or + (can_use(Silver_Gauntlets) and + (((Small_Key_Spirit_Temple, 3) and has_explosives) or (Small_Key_Spirit_Temple, 5)))" + } + }, + { + "region_name": "Spirit Temple Beyond Central Locked Door", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Near Four Armos Chest": "Mirror_Shield and has_explosives", + "Spirit Temple Hallway Left Invisible Chest": "(logic_lens_spirit or can_use(Lens_of_Truth)) and has_explosives", + "Spirit Temple Hallway Right Invisible Chest": "(logic_lens_spirit or can_use(Lens_of_Truth)) and has_explosives" + }, + "exits": { + "Spirit Temple Beyond Final Locked Door": " + (Small_Key_Spirit_Temple, 5) and + (logic_spirit_wall or can_use(Longshot) or has_bombchus or + ((Bombs or Nuts or can_use(Dins_Fire)) and + (Bow or can_use(Hookshot) or Megaton_Hammer)))" + } + }, + { + "region_name": "Spirit Temple Beyond Final Locked Door", + "dungeon": "Spirit Temple", + "locations": { + "Spirit Temple Boss Key Chest": " + can_play(Zeldas_Lullaby) and Bow and + Progressive_Hookshot", + "Spirit Temple Topmost Chest": "Mirror_Shield", + "Spirit Temple Twinrova Heart": " + Mirror_Shield and has_explosives and + Progressive_Hookshot and Boss_Key_Spirit_Temple", + "Twinrova": " + Mirror_Shield and has_explosives and + Progressive_Hookshot and Boss_Key_Spirit_Temple" + } + } +] diff --git a/worlds/oot/data/World/Water Temple MQ.json b/worlds/oot/data/World/Water Temple MQ.json new file mode 100644 index 00000000..05d3a782 --- /dev/null +++ b/worlds/oot/data/World/Water Temple MQ.json @@ -0,0 +1,76 @@ +[ + { + "region_name": "Water Temple Lobby", + "dungeon": "Water Temple", + "events": { + "Water Temple Clear": "Boss_Key_Water_Temple and can_use(Longshot)" + }, + "locations": { + "Water Temple Morpha Heart": "Boss_Key_Water_Temple and can_use(Longshot)", + "Morpha": "Boss_Key_Water_Temple and can_use(Longshot)" + }, + "exits": { + "Lake Hylia": "True", + "Water Temple Dive": " + (can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and can_use(Iron_Boots)", + "Water Temple Dark Link Region": " + Small_Key_Water_Temple and can_use(Longshot)" + } + }, + { + "region_name": "Water Temple Dive", + "dungeon": "Water Temple", + "locations": { + "Water Temple MQ Map Chest": "has_fire_source and can_use(Hookshot)", + "Water Temple MQ Central Pillar Chest": " + can_use(Zora_Tunic) and can_use(Hookshot) and + ((logic_water_mq_central_pillar and can_use(Fire_Arrows)) or + (can_use(Dins_Fire) and can_play(Song_of_Time)))" + }, + "exits": { + "Water Temple Lowered Water Levels": "can_play(Zeldas_Lullaby)" + } + }, + { + "region_name": "Water Temple Lowered Water Levels", + "dungeon": "Water Temple", + "locations": { + "Water Temple MQ Compass Chest": " + can_use(Bow) or can_use(Dins_Fire) or + at('Water Temple Lobby', can_use(Sticks) and has_explosives)", + "Water Temple MQ Longshot Chest": "can_use(Hookshot)", + "Water Temple MQ GS Lizalfos Hallway": "can_use(Dins_Fire)", + "Water Temple MQ GS Before Upper Water Switch": "can_use(Longshot)" + } + }, + { + "region_name": "Water Temple Dark Link Region", + "dungeon": "Water Temple", + "locations": { + "Water Temple MQ Boss Key Chest": " + (can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and can_use(Dins_Fire) and + (logic_water_dragon_jump_dive or can_dive or can_use(Iron_Boots))", + "Water Temple MQ GS River": "True", + "Fairy Pot": "has_bottle", + "Nut Pot": "True" + }, + "exits": { + "Water Temple Basement Gated Areas": " + (can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and + can_use(Dins_Fire) and can_use(Iron_Boots)" + } + }, + { + "region_name": "Water Temple Basement Gated Areas", + "dungeon": "Water Temple", + "locations": { + "Water Temple MQ Freestanding Key": " + Hover_Boots or can_use(Scarecrow) or logic_water_north_basement_ledge_jump", + "Water Temple MQ GS Triple Wall Torch": " + can_use(Fire_Arrows) and (Hover_Boots or can_use(Scarecrow))", + "Water Temple MQ GS Freestanding Key Area": " + logic_water_mq_locked_gs or ((Small_Key_Water_Temple, 2) and + (Hover_Boots or can_use(Scarecrow) or logic_water_north_basement_ledge_jump))" + } + } +] diff --git a/worlds/oot/data/World/Water Temple.json b/worlds/oot/data/World/Water Temple.json new file mode 100644 index 00000000..ec1a1a86 --- /dev/null +++ b/worlds/oot/data/World/Water Temple.json @@ -0,0 +1,162 @@ +[ + { + "region_name": "Water Temple Lobby", + "dungeon": "Water Temple", + "events": { + "Child Water Temple": "is_child", + # Child can access only the falling platform room as the sole entrant into Water Temple. + # Use Child_Water_Temple for cases where child assists after the water is lowered. + "Raise Water Level": " + (is_adult and (Hookshot or Hover_Boots or Bow)) or + (has_fire_source_with_torch and can_use_projectile)" + # Ensure that the water level can be raised if it were to be lowered. + }, + "exits": { + "Lake Hylia": "True", + "Water Temple Highest Water Level": "Raise_Water_Level", + "Water Temple Dive": " + (can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and + ((logic_water_temple_torch_longshot and can_use(Longshot)) or can_use(Iron_Boots))" + } + }, + { + "region_name": "Water Temple Highest Water Level", + "dungeon": "Water Temple", + "events": { + "Water Temple Clear": "Boss_Key_Water_Temple and can_use(Longshot)" + }, + "locations": { + "Morpha": "Boss_Key_Water_Temple and can_use(Longshot)", + "Water Temple Morpha Heart": "Boss_Key_Water_Temple and can_use(Longshot)", + "Fairy Pot": "has_bottle and can_use(Longshot)" + }, + "exits": { + "Water Temple Falling Platform Room": "(Small_Key_Water_Temple, 4)" + } + }, + { + "region_name": "Water Temple Dive", + "dungeon": "Water Temple", + "locations": { + "Water Temple Map Chest": "Raise_Water_Level", + "Water Temple Compass Chest": " + (can_play(Zeldas_Lullaby) or Iron_Boots) and can_use(Hookshot)", + "Water Temple Torches Chest": " + (Bow or can_use(Dins_Fire) or + (Child_Water_Temple and Sticks and Kokiri_Sword and Magic_Meter)) and + can_play(Zeldas_Lullaby)", + "Water Temple Central Bow Target Chest": " + Progressive_Strength_Upgrade and can_play(Zeldas_Lullaby) and + ((Bow and (logic_water_central_bow or Hover_Boots or can_use(Longshot))) or + (logic_water_central_bow and Child_Water_Temple and Slingshot and at('Water Temple Middle Water Level', True)))", + "Water Temple GS Behind Gate": " + (can_use(Hookshot) or can_use(Hover_Boots)) and + has_explosives and can_play(Zeldas_Lullaby) and + (can_use(Iron_Boots) or can_dive)", + "Water Temple GS Central Pillar": " + can_play(Zeldas_Lullaby) and + (((can_use(Longshot) or (logic_water_central_gs_fw and can_use(Hookshot) and can_use(Farores_Wind))) and + ((Small_Key_Water_Temple, 5) or can_use(Bow) or can_use(Dins_Fire))) or + (logic_water_central_gs_irons and can_use(Hookshot) and can_use(Iron_Boots) and + (can_use(Bow) or can_use(Dins_Fire))) or + (logic_water_central_gs_fw and Child_Water_Temple and Boomerang and can_use(Farores_Wind) and + (Sticks or can_use(Dins_Fire) or + ((Small_Key_Water_Temple, 5) and (can_use(Hover_Boots) or can_use(Bow))))))" + }, + "exits": { + "Water Temple Cracked Wall": " + can_play(Zeldas_Lullaby) and (can_use(Hookshot) or can_use(Hover_Boots)) and + (logic_water_cracked_wall_nothing or (logic_water_cracked_wall_hovers and can_use(Hover_Boots)))", + "Water Temple Middle Water Level": " + (Bow or can_use(Dins_Fire) or + ((Small_Key_Water_Temple, 5) and can_use(Hookshot)) or + (Child_Water_Temple and Sticks)) and + can_play(Zeldas_Lullaby)", + "Water Temple North Basement": " + (Small_Key_Water_Temple, 4) and + (can_use(Longshot) or (logic_water_boss_key_region and can_use(Hover_Boots))) and + (can_use(Iron_Boots) or can_play(Zeldas_Lullaby))", + "Water Temple Dragon Statue": " + can_play(Zeldas_Lullaby) and Progressive_Strength_Upgrade and + ((Iron_Boots and can_use(Hookshot)) or + (logic_water_dragon_adult and (has_bombchus or can_use(Bow) or can_use(Hookshot)) and (can_dive or Iron_Boots)) or + (logic_water_dragon_child and Child_Water_Temple and (has_bombchus or Slingshot or Boomerang) and can_dive))" + } + }, + { + "region_name": "Water Temple North Basement", + "dungeon": "Water Temple", + "locations": { + "Water Temple Boss Key Chest": " + (Small_Key_Water_Temple, 5) and + (logic_water_bk_jump_dive or can_use(Iron_Boots)) and + (logic_water_north_basement_ledge_jump or (has_explosives and Progressive_Strength_Upgrade) or Hover_Boots)", + "Water Temple GS Near Boss Key Chest": "True", + # Longshot just reaches without the need to actually go near, + # Otherwise you have hovers and just hover over and collect with a jump slash + "Fairy Pot": " + has_bottle and (Small_Key_Water_Temple, 5) and + (logic_water_bk_jump_dive or can_use(Iron_Boots)) and + (logic_water_north_basement_ledge_jump or (has_explosives and Progressive_Strength_Upgrade) or Hover_Boots)" + } + }, + { + "region_name": "Water Temple Cracked Wall", + "dungeon": "Water Temple", + "locations": { + "Water Temple Cracked Wall Chest": "has_explosives" + } + }, + { + "region_name": "Water Temple Dragon Statue", + "dungeon": "Water Temple", + "locations": { + "Water Temple Dragon Chest": "True" + } + }, + { + "region_name": "Water Temple Middle Water Level", + "dungeon": "Water Temple", + "locations": { + "Water Temple Central Pillar Chest": " + can_use(Iron_Boots) and can_use(Zora_Tunic) and can_use(Hookshot) and + ((Small_Key_Water_Temple, 5) or can_use(Bow) or can_use(Dins_Fire))" + }, + "exits": { + "Water Temple Cracked Wall": "True" + } + }, + { + "region_name": "Water Temple Falling Platform Room", + "dungeon": "Water Temple", + "locations": { + "Water Temple GS Falling Platform Room": " + can_use(Longshot) or + (logic_water_falling_platform_gs_hookshot and can_use(Hookshot)) or + (logic_water_falling_platform_gs_boomerang and can_use(Boomerang))" + }, + "exits": { + "Water Temple Dark Link Region": "(Small_Key_Water_Temple, 5) and can_use(Hookshot)" + } + }, + { + "region_name": "Water Temple Dark Link Region", + "dungeon": "Water Temple", + "locations": { + "Water Temple Longshot Chest": "True", + "Water Temple River Chest": "can_play(Song_of_Time) and Bow", + "Water Temple GS River": " + can_play(Song_of_Time) and + ((Iron_Boots and (can_use(Zora_Tunic) or logic_fewer_tunic_requirements)) or + (logic_water_river_gs and can_use(Longshot) and (Bow or has_bombchus)))", + "Fairy Pot": + "has_bottle and can_play(Song_of_Time)" + }, + "exits": { + "Water Temple Dragon Statue": " + (can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and + can_play(Song_of_Time) and Bow and + (Iron_Boots or logic_water_dragon_jump_dive or logic_water_dragon_adult)" + } + } +] diff --git a/worlds/oot/data/generated/.gitignore b/worlds/oot/data/generated/.gitignore new file mode 100644 index 00000000..fabb8b42 --- /dev/null +++ b/worlds/oot/data/generated/.gitignore @@ -0,0 +1 @@ +settings_list.json \ No newline at end of file diff --git a/worlds/oot/data/generated/rom_patch.txt b/worlds/oot/data/generated/rom_patch.txt new file mode 100644 index 00000000..37d58f49 --- /dev/null +++ b/worlds/oot/data/generated/rom_patch.txt @@ -0,0 +1,13571 @@ +10,107b733a +14,32bea9ca +d1b0,3480000 +d1b4,348ef10 +d1b8,3480000 +d1c0,0 +d1c4,0 +d1c8,0 +d1d0,0 +d1d4,0 +d1d8,0 +d1e0,0 +d1e4,0 +d1e8,0 +d1f0,0 +d1f4,0 +d1f8,0 +d200,0 +d204,0 +d208,0 +d210,0 +d214,0 +d218,0 +d220,0 +d224,0 +d228,0 +d230,0 +d234,0 +d238,0 +d240,0 +d244,0 +d248,0 +d250,0 +d254,0 +d258,0 +d260,0 +d264,0 +d268,0 +d270,0 +d274,0 +d278,0 +d280,0 +d284,0 +d288,0 +89e810,0 +89e814,0 +89e81c,0 +89e850,0 +89e854,0 +89e858,0 +89e85c,0 +89e868,0 +89e86c,0 +89e870,0 +89e890,0 +89e894,0 +89e898,0 +89e89c,0 +89e8a0,0 +89e8a4,0 +89e8a8,0 +89e8ac,0 +89e8b0,0 +89e8d0,0 +89e8d4,0 +89e8d8,0 +89e8dc,0 +89e8e0,0 +89e8e4,0 +89e8e8,0 +89e8ec,0 +89e8f0,0 +89e90c,0 +89e910,0 +89e914,0 +89e918,0 +89e91c,0 +89e920,0 +89e924,0 +89e928,0 +89e92c,0 +89e930,0 +89e94c,0 +89e950,0 +89e954,0 +89e958,0 +89e95c,0 +89e960,0 +89e964,0 +89e968,0 +89e96c,0 +89e970,0 +89e98c,0 +89e990,0 +89e994,0 +89e998,0 +89e99c,0 +89e9a0,0 +89e9a4,0 +89e9a8,0 +89e9ac,0 +89e9b0,0 +89e9cc,0 +89e9d0,0 +89e9d4,0 +89e9d8,0 +89e9dc,0 +89e9e0,0 +89e9e4,0 +89e9e8,0 +89e9ec,0 +89e9f0,0 +89ea0c,0 +89ea10,0 +89ea14,0 +89ea18,0 +89ea1c,0 +89ea20,0 +89ea24,0 +89ea28,0 +89ea2c,0 +89ea30,0 +89ea4c,0 +89ea50,0 +89ea54,0 +89ea58,0 +89ea5c,0 +89ea60,0 +89ea64,0 +89ea68,0 +89ea6c,0 +89ea70,0 +89ea8c,0 +89ea90,0 +89ea94,0 +89ea98,0 +89ea9c,0 +89eaa0,0 +89eaa4,0 +89eaa8,0 +89eaac,0 +89eab0,0 +89eacc,0 +89ead0,0 +89ead4,0 +89ead8,0 +89eadc,0 +89eae0,0 +89eae4,0 +89eae8,0 +89eaec,0 +89eaf0,0 +89eb0c,0 +89eb10,0 +89eb14,0 +89eb18,0 +89eb1c,0 +89eb20,0 +89eb24,0 +89eb28,0 +89eb2c,0 +89eb30,0 +89eb4c,0 +89eb50,0 +89eb54,0 +89eb58,0 +89eb5c,0 +89eb60,0 +89eb64,0 +89eb68,0 +89eb6c,0 +89eb70,0 +89eb8c,0 +89eb90,0 +89eb94,0 +89eb98,0 +89eb9c,0 +89eba0,0 +89eba4,0 +89eba8,0 +89ebac,0 +89ebb0,0 +89ebcc,0 +89ebd4,0 +89ebd8,0 +89ebe8,0 +89ebec,0 +89ebf0,0 +a88f78,c102355 +a89048,c10236e +a98c30,c1003c6 +a9e838,8100777 +ac7ad4,c100346 +ac8608,902025 +ac860c,848e00a4 +ac8610,34010043 +ac8614,0 +ac8618,0 +ac91b4,0 +ac9abc,c100407 +ac9ac0,0 +accd34,c1004bc +accd38,8e190000 +accde0,c101b62 +acce18,c1008d1 +acce1c,8e0200a4 +acce20,1060001e +acce24,0 +acce28,0 +acce2c,0 +acce34,0 +acce38,0 +acce3c,0 +acce88,c101a27 +acce8c,34040001 +acce90,0 +acce94,0 +acce98,0 +ad193c,10000012 +ada8a8,0 +ada8ac,0 +ada8b0,0 +ada97c,0 +ada9a8,0 +ada9bc,0 +adaa64,0 +adaa74,0 +adaa78,0 +adaba8,0 +adabcc,0 +adabe4,0 +ae5764,810069d +ae5768,0 +ae59e0,81006b9 +ae5df8,c1003ff +ae5e04,0 +ae74d8,340e0000 +ae807c,6010007 +ae8080,84b80030 +ae8084,c100b28 +ae8088,0 +ae8090,0 +ae8094,0 +ae8098,0 +ae986c,8100b08 +ae9870,3c01800f +ae9ed8,35ee0000 +aeb67c,c1009ae +aeb680,0 +aeb764,26380008 +aeb768,ae9802b0 +aeb76c,c101d9e +aeb778,400821 +af1814,c100e6a +af1818,0 +af74f8,afbf0044 +af74fc,c100a39 +af7500,0 +af7504,8fbf0044 +af7650,afbf0034 +af7654,c100a47 +af7658,0 +af765c,8fbf0034 +af76b8,afbf000c +af76bc,c100a2e +af76c4,8fbf000c +b06400,820f0ede +b0640c,31f80002 +b06bb8,34190000 +b06c2c,c1007b8 +b06c30,a2280020 +b10218,afa40020 +b1021c,30a8fffe +b10220,3401000e +b10224,15010006 +b10228,afa50024 +b1022c,10000030 +b10230,0 +b10234,4410002 +b10238,34010004 +b1023c,afa10024 +b10240,8fa60020 +b10244,3c010001 +b10248,242121c8 +b1024c,c12021 +b10250,afa40018 +b10254,c000ba0 +b10258,24050250 +b1025c,8fa20024 +b10260,8fa40018 +b10264,8fa60020 +b10268,24010001 +b1026c,27143 +b10270,15c10015 +b10274,ac820228 +b10278,3c01800a +b1027c,242f8dec +b10280,24388e18 +b10284,24398c00 +b10288,24289244 +b1028c,24298fa8 +b10290,242a8e24 +b10294,242b9250 +b10298,242c92a8 +b1029c,242d92b4 +b102f0,3c010001 +b102f4,242117a4 +b102f8,812021 +b102fc,c02058a +b10300,24050002 +b10304,1000ffcb +b10308,0 +b1030c,3c01800a +b10310,242f8218 +b10314,243882b8 +b10318,243981e0 +b1031c,24288700 +b10320,242983fc +b10324,242a82c4 +b10328,242b83e4 +b1032c,242c83d8 +b10cc0,c1004a4 +b10cc4,3c010001 +b12a34,c100650 +b12a38,0 +b12a60,8101f82 +b12e44,8101f91 +b17bb4,afbf001c +b17bb8,afa40140 +b17bbc,3c048040 +b17bc0,3406ef10 +b17bc4,c00037c +b17bc8,3c050348 +b17bcc,c100339 +b17bd0,0 +b17bd4,0 +b2b488,c100bf4 +b2b48c,0 +b2b490,0 +b2b494,0 +b2b498,0 +b2b49c,0 +b2b4f0,3c048013 +b2b4f4,24848a50 +b2b4f8,3c058040 +b2b4fc,24a52fac +b2b500,c015c0c +b2b504,34060018 +b2b508,3c048013 +b2b50c,24848a50 +b2b514,0 +b2b518,3c048013 +b2b51c,24848a5c +b2b520,c02cf77 +b2b524,0 +b2b528,0 +b2b52c,0 +b2b530,0 +b2b534,0 +b2b538,0 +b2b53c,0 +b2e82c,3c058001 +b2e830,8ca5b188 +b2e854,3c058001 +b2e858,8ca5b198 +b3dd3c,3c018040 +b3dd40,8c242fc8 +b3dd44,c02e195 +b3dd48,8c252fcc +b3dd4c,8fbf0014 +b3dd54,27bd0018 +b51694,c1007cb +b516c4,c1007d2 +b52784,c1007ec +b52788,0 +b5278c,8fbf003c +b5293c,10000018 +b54b38,c100766 +b54e5c,c100753 +b55428,a42063ed +b55a64,c10079d +b575c8,acae0000 +b58320,afbf0000 +b58324,c1009f3 +b58328,0 +b5832c,8fbf0000 +b58330,0 +b7ec4c,8009a3ac +ba16ac,c100cde +ba16b0,a42fca2a +ba16e0,c100ce9 +ba16e4,a439ca2a +ba18c4,340c00c8 +ba1980,340800c8 +ba19dc,0 +ba1c68,c100cf4 +ba1c6c,a42dca2a +ba1c70,850e4a38 +ba1cd0,c100cff +ba1cd4,a439ca2a +ba1d04,c100d0a +ba1d08,0 +ba1e20,340d00c8 +ba32cc,c100d15 +ba32d0,a439ca2a +ba3300,c100d20 +ba3304,a42bca2a +ba34dc,341800c8 +ba3654,0 +ba39d0,340d00c8 +baa168,c100cc8 +baa16c,a42eca2a +baa198,c100cd3 +baa19c,a42dca2a +baa3ac,a07025 +bac064,7821 +bac1bc,7821 +bac3ec,c821 +bac94c,c821 +bae5a4,a46b4a6c +bae5c8,0 +bae864,0 +baed6c,0 +baf4f4,c100d2b +baf4f8,2002025 +baf738,102825 +baf73c,c101867 +baf740,330400ff +baf744,8fb00018 +baf748,8fbf001c +baf74c,3e00008 +baf750,27bd0088 +baf754,0 +baf758,0 +baf75c,0 +baf760,0 +baf764,0 +baf768,0 +baf76c,0 +baf770,0 +baf774,0 +baf778,0 +baf77c,0 +baf780,0 +baf784,0 +baf788,0 +baf78c,0 +baf790,0 +baf794,0 +bb05fc,ffc0 +bb0600,ffb0ffb0 +bb5eac,0 +bb5eb0,0 +bb5fdc,0 +bb6134,0 +bb6138,0 +bb61e0,0 +bb61e4,0 +bb6688,c10065f +bb668c,0 +bb67c4,c10065f +bb67c8,1826021 +bb6cf0,c10068e +bb6cf4,0 +bb77b4,0 +bb7894,0 +bb7ba0,0 +bb7bfc,0 +bb7c88,c100659 +bb7c8c,1cf8821 +bb7d10,c100659 +bb7d14,0 +bc088c,c10066c +bc0890,0 +bcdbd8,c100d3d +bcecbc,8100377 +bcecc0,0 +bcecc4,0 +bcecc8,0 +bceccc,0 +bcecd0,0 +bcf73c,afbf0000 +bcf740,c10080a +bcf744,0 +bcf748,8fbf0000 +bcf914,c100802 +bcf918,0 +bd4c58,c100b9c +bd4c5c,270821 +bd5c58,c1005bb +bd5c5c,301c825 +bd6958,c100a24 +bd695c,0 +bd9a04,c1009d4 +bd9a08,0 +bda0a0,c10034a +bda0d8,c100367 +bda0e4,0 +bda264,c10036a +bda270,0 +bda2e8,c100385 +bda2ec,812a0002 +bda2f0,5600018 +bda2f4,0 +be1bc8,c1005cc +be1bcc,afa50034 +be1c98,3c014218 +be4a14,c100e18 +be4a40,c100e32 +be4a60,8100e4a +be4a64,0 +be5d8c,c100e74 +be5d90,0 +be9ac0,c1003a1 +be9ad8,c1003ac +be9adc,8fa20024 +be9ae4,8fa40028 +be9bdc,24018383 +bea044,c100480 +bea048,0 +c004ec,81005f5 +c0067c,28610064 +c0082c,340e0018 +c00830,8c4f00a0 +c01078,c10083f +c0107c,0 +c01080,0 +c01084,0 +c01088,0 +c0108c,0 +c018a0,c10060a +c064bc,c1009b8 +c06e5c,c1009b8 +c0722c,c1009b8 +c07230,add80008 +c07494,c1009b8 +c075a8,c1009c3 +c07648,c1009c3 +c0e77c,c1007b2 +c0e780,ac400428 +c5a9f0,c100cc3 +c6c7a8,c10061a +c6c920,c10061a +c6cedc,340b0001 +c6ed84,946f00a2 +c6ed88,31f80018 +c6ff30,46005402 +c6ff34,44054000 +c6ff38,4600848d +c6ff3c,44069000 +c6ff44,27bdffe8 +c6ff48,afbf0004 +c6ff4c,c1009ff +c6ff50,0 +c6ff54,8fbf0004 +c6ff58,27bd0018 +c6ff5c,3e00008 +c6ff60,0 +c6ff64,0 +c6ff68,0 +c6ff6c,0 +c6ff70,0 +c6ff74,0 +c72c64,c100bda +c72c68,2002021 +c72c70,15e00006 +c72c74,0 +c7bcf0,8cb91d38 +c7bcf4,34080004 +c7bcf8,8ca21c44 +c7bcfc,0 +c7bd00,0 +c7bd04,0 +c7bd08,0 +c82550,0 +c892dc,340e0001 +c8931c,340a0001 +c89744,c1003d3 +c89868,920e1d28 +c898a4,92191d29 +c898c8,920a1d2a +c8b24c,c1004ff +c8b250,2002025 +ca6dc0,8102390 +ca6dc4,0 +cb6874,c100697 +cc0038,c100460 +cc003c,8fa40018 +cc3fa8,a20101f8 +cc4024,0 +cc4038,c10099d +cc403c,240c0004 +cc453c,806 +cc8594,c1005df +cc8598,24180006 +cc85b8,c100dfd +cc85bc,afa50064 +cdf3ec,0 +cdf404,0 +cdf420,c1005af +cdf638,c1005c3 +cdf63c,e7a40034 +cdf790,2405001e +cf1ab8,0 +cf1abc,8f09b4a8 +cf1ac0,31280040 +cf1ac4,35390040 +cf1ac8,af19b4a8 +cf1acc,34090006 +cf73c8,c100bb4 +cf73cc,3c010001 +cf7ad4,c1005a9 +cf7ad8,afa50044 +d12f78,340f0000 +d357d4,c100b16 +d35efc,0 +d35f54,10000008 +d4bcb0,c100dd8 +d4bcb4,8619001c +d4be6c,c100981 +d52698,c1004db +d5269c,8e190024 +d5b264,c100aa4 +d5b660,8100aa7 +d5b664,0 +d5ff94,c100eb2 +d5ff98,44d9f800 +d62100,c100c65 +d62110,3c014248 +d62128,0 +d6215c,0 +d621cc,c100c73 +d621dc,3c014248 +d6221c,0 +d68d68,c100c1d +d68d6c,afb20044 +d68d70,3c098040 +d68d74,2529306c +d68d78,81290000 +d68d7c,11200186 +d68d80,8fbf004c +d68d84,c100c31 +d68d88,f7b80030 +d69c80,c100c39 +d6cc18,c100cbb +d6cc1c,0 +d6cdd4,c100cbf +d6cdd8,0 +d73118,0 +d73128,0 +d74964,1000000a +d7e140,340e0001 +d7e144,806f0ede +d7e160,3c04801d +d7e164,248484a0 +d7e168,848800a4 +d7e16c,34010063 +d7e170,14280003 +d7e174,34022049 +d7e178,10000006 +d7e17c,0 +d7e180,94690ed6 +d7e184,31290004 +d7e188,15200002 +d7e18c,34022044 +d7e190,34022043 +d7e194,8fbf0014 +d7e198,27bd0018 +d7e19c,3e00008 +d7e1a0,0 +d7e398,94890ed6 +d7e39c,31280014 +d7e3a0,34090014 +d7e3a4,3401005f +d7e3a8,14230005 +d7e3ac,0 +d7e3b0,1109000d +d7e3b4,0 +d7e3b8,3e00008 +d7e3bc,34020001 +d7e3c0,14c20009 +d7e3c4,34010063 +d7e3c8,14230007 +d7e3cc,8c8a0010 +d7e3d0,15400005 +d7e3d4,0 +d7e3d8,15090003 +d7e3dc,0 +d7e3e0,3e00008 +d7e3e4,34020001 +d7e3e8,3e00008 +d7e3ec,34020000 +d7e76c,8fb80044 +d7e778,871800a4 +d7e77c,80490ede +d7e784,34080001 +d7e788,2002021 +d7e798,15400002 +d7e79c,3419005f +d7e7a0,17380005 +d7e7a4,ae0b0180 +d7e890,0 +d7e8a0,10000007 +d7e8a4,314a0004 +d7e8b0,0 +d7e8b4,0 +d7e8c0,340b0014 +d7e8c8,14b5025 +d7e8cc,154b0014 +d7e8d4,340e0001 +d7e8d8,804f0ede +d7e8e0,5700000f +d7eb4c,0 +d7eb70,c100d5a +d7eb74,acc80004 +d7ebbc,0 +d7ebc8,c100d62 +d7ebf0,27bdffe8 +d7ebf4,afbf0014 +d7ebf8,c100d6d +d7ebfc,8ca21c44 +d7ec04,0 +d7ec10,c100d71 +d7ec14,971804c6 +d7ec2c,0 +d7ec34,c100d88 +d7ec40,0 +d7ec54,0 +d7ec60,8100d7a +d7ec70,8100da0 +db13d0,24090076 +db532c,c100430 +db53e8,81023c2 +db53ec,0 +dbec80,34020000 +dbf428,c1007f4 +dbf434,44989000 +dbf438,e652019c +dbf484,0 +dbf4a8,0 +dc7090,c100814 +dc7094,c60a0198 +dc87a0,0 +dc87bc,0 +dc87cc,0 +dc8828,1a00821 +dcbea8,3c014248 +dcbf24,3c014248 +dcbf30,3c014230 +dcbf9c,3c014230 +dd366c,3c0140d0 +dd367c,3c064000 +dd3684,3c074000 +dd3688,0 +dd368c,0 +dd3744,3c0140d0 +dd3754,3c064000 +dd375c,3c074000 +dd3760,0 +dd3764,0 +de1018,c1023db +de101c,0 +de1020,0 +de1024,0 +de1028,0 +de102c,0 +de1030,0 +de1034,0 +de1038,0 +de103c,0 +de1050,81023db +de1054,0 +df2644,76 +df7a90,340e0018 +df7a94,8c4f00a0 +df7cb0,c10063a +dfec3c,3c188012 +dfec40,8f18ae8c +dfec48,33190010 +dfec4c,0 +e09f68,806f0ede +e09f74,31f80004 +e09fb0,c100422 +e0ec50,c100c0b +e0ec54,2202825 +e11e98,9442a674 +e11e9c,304e0040 +e11ea0,51c00002 +e11ea4,1021 +e11ea8,34020001 +e11eac,3e00008 +e11eb0,0 +e11eb4,0 +e11eb8,0 +e11ebc,0 +e11ec0,0 +e11ec4,0 +e11ec8,0 +e11f90,c1004e6 +e11f94,0 +e12a04,c100e51 +e12a20,ac8302a4 +e1f72c,27bdffe8 +e1f730,afbf0014 +e1f734,c100e96 +e1f738,0 +e1f73c,8fbf0014 +e1f740,27bd0018 +e1f744,28410005 +e1f748,14200012 +e1f74c,24010005 +e1feac,c100ea8 +e1feb0,3c0743cf +e20410,c100b42 +e20414,0 +e206dc,c100b50 +e206e0,0 +e2076c,c100b60 +e20770,afa40020 +e20798,c100b58 +e2079c,0 +e24e7c,c1004b3 +e24e80,0 +e29388,810043e +e2a044,c100447 +e2b0b4,c10044f +e2b434,c100852 +e2b438,0 +e2b43c,0 +e2b440,0 +e2b444,0 +e2b448,0 +e2b44c,0 +e2b450,0 +e2b454,0 +e2b458,0 +e2b45c,0 +e2b460,0 +e2c03c,c100974 +e2c040,2442a5d0 +e2cc1c,3c058012 +e2cc20,24a5a5d0 +e2cc24,86080270 +e2cc28,15000009 +e2cc2c,90b9008a +e2d714,c100821 +e2d71c,340900bf +e2d720,0 +e2d890,c100830 +e2d894,0 +e2f090,34 +e429dc,c100554 +e429e0,0 +e429e4,10000053 +e429e8,0 +e42b5c,c10053a +e42b64,1000000d +e42b68,0 +e42c00,c100532 +e42c44,c10059b +e42c48,860e008a +e42c4c,15400045 +e50888,340403e7 +e55c4c,340c0000 +e56290,0 +e56294,340b401f +e56298,0 +e565d0,c100bfc +e565d4,0 +e565d8,2002025 +e59cd4,0 +e59cd8,0 +e59e68,8102414 +e59e6c,0 +e59ecc,810243d +e59ed0,0 +e5b2f4,c100e7f +e5b2f8,afa5001c +e5b538,c100e8b +e5b53c,3c07461c +e62630,a48001f8 +e62634,2463a5d0 +e62638,94790ed4 +e6263c,340f0090 +e62640,32fc024 +e62644,170f0006 +e62648,0 +e6264c,10000023 +e62650,34021045 +e62654,0 +e62658,0 +e6265c,0 +e62950,3c038012 +e62954,34010055 +e62958,2463a5d0 +e6295c,94680ed4 +e62960,31090080 +e62964,310a0010 +e62968,94680edc +e6296c,310b0001 +e62970,94680ed6 +e62974,310d1000 +e62978,12b7025 +e6297c,14d7825 +e62980,14410007 +e62984,34181010 +e62988,11c00003 +e6298c,0 +e62990,11f80010 +e62994,0 +e62998,3e00008 +e6299c,34020001 +e629a0,34010028 +e629a4,14410008 +e629a8,0 +e629ac,11c00009 +e629b0,0 +e629b4,15f80007 +e629b8,0 +e629bc,8c6c0004 +e629c0,1580fff5 +e629c4,0 +e629c8,3401005b +e629cc,1041fff2 +e629d0,0 +e629d4,3e00008 +e629d8,1021 +e629dc,0 +e629e0,0 +e629e4,0 +e6befc,0 +e6bf4c,340d0000 +e6bf50,0 +e7cc90,240e000c +e7d19c,c100d31 +e7d1a0,3c050600 +e7d1a4,10a80003 +e7d1a8,3025 +e81128,35cf0080 +e9e1b8,3c19801d +e9e1bc,8f39a1d8 +e9e1c0,33390001 +e9e1c4,34010000 +e9e1c8,0 +e9e1cc,0 +e9f59c,95cfa674 +e9f5a0,31f80040 +e9f5a4,53000002 +e9f5a8,1021 +e9f5ac,34020001 +e9f5b0,3e00008 +e9f5b4,0 +e9f5b8,0 +e9f5bc,0 +e9f678,c1004e6 +e9f67c,0 +e9f7a8,c1004e6 +e9f7ac,0 +ebb85c,c100625 +ebb864,14400012 +ebb86c,10000014 +ec1120,c1004e6 +ec1124,0 +ec68bc,8fad002c +ec68c0,340c000a +ec68c4,a5ac0110 +ec68c8,c101b2b +ec68cc,2002021 +ec68d0,0 +ec68d4,0 +ec68d8,0 +ec68dc,0 +ec68e0,0 +ec69ac,8fad002c +ec69b0,340c000a +ec69b4,a5ac0110 +ec69b8,c101b2b +ec69bc,2002021 +ec69c0,0 +ec69c4,0 +ec69c8,0 +ec69cc,0 +ec69d0,0 +ec6b04,81023a9 +ec6b08,0 +ec9ce4,2419007a +ed2858,20180008 +ed2fac,806e0f18 +ed2fec,340a0000 +ed5a28,340e0018 +ed5a2c,8ccf00a0 +ed645c,c10081d +ed6460,0 +ee7b84,c10094b +ee7b8c,0 +ee7b90,0 +ee7b94,0 +ee7b98,0 +ee7b9c,0 +ee7ba0,0 +ee7ba4,0 +ee7e4c,c100a8a +ef32b8,c100a7f +ef32bc,0 +ef32c0,8fbf003c +ef36e4,c100a55 +ef36e8,0 +ef373c,c100a67 +ef4f98,c100790 +ef4f9c,0 +26c10e0,38ff +3480000,80400020 +3480004,80400844 +3480008,80409f8c +3480020,3 +3480034,dfdfdfdf +3480038,dfdfdfdf +348003c,dfdfdfdf +3480040,dfdfdfdf +3480044,dfdfdfdf +3480048,dfdfdfdf +348004c,dfdfdfdf +3480050,dfdfdfdf +3480054,dfdfdfdf +3480058,dfdfdfdf +348005c,dfdfdfdf +3480060,dfdfdfdf +3480064,dfdfdfdf +3480068,dfdfdfdf +348006c,dfdfdfdf +3480070,dfdfdfdf +3480074,dfdfdfdf +3480078,dfdfdfdf +348007c,dfdfdfdf +3480080,dfdfdfdf +3480084,dfdfdfdf +3480088,dfdfdfdf +348008c,dfdfdfdf +3480090,dfdfdfdf +3480094,dfdfdfdf +3480098,dfdfdfdf +348009c,dfdfdfdf +34800a0,dfdfdfdf +34800a4,dfdfdfdf +34800a8,dfdfdfdf +34800ac,dfdfdfdf +34800b0,dfdfdfdf +34800b4,dfdfdfdf +34800b8,dfdfdfdf +34800bc,dfdfdfdf +34800c0,dfdfdfdf +34800c4,dfdfdfdf +34800c8,dfdfdfdf +34800cc,dfdfdfdf +34800d0,dfdfdfdf +34800d4,dfdfdfdf +34800d8,dfdfdfdf +34800dc,dfdfdfdf +34800e0,dfdfdfdf +34800e4,dfdfdfdf +34800e8,dfdfdfdf +34800ec,dfdfdfdf +34800f0,dfdfdfdf +34800f4,dfdfdfdf +34800f8,dfdfdfdf +34800fc,dfdfdfdf +3480100,dfdfdfdf +3480104,dfdfdfdf +3480108,dfdfdfdf +348010c,dfdfdfdf +3480110,dfdfdfdf +3480114,dfdfdfdf +3480118,dfdfdfdf +348011c,dfdfdfdf +3480120,dfdfdfdf +3480124,dfdfdfdf +3480128,dfdfdfdf +348012c,dfdfdfdf +3480130,dfdfdfdf +3480134,dfdfdfdf +3480138,dfdfdfdf +348013c,dfdfdfdf +3480140,dfdfdfdf +3480144,dfdfdfdf +3480148,dfdfdfdf +348014c,dfdfdfdf +3480150,dfdfdfdf +3480154,dfdfdfdf +3480158,dfdfdfdf +348015c,dfdfdfdf +3480160,dfdfdfdf +3480164,dfdfdfdf +3480168,dfdfdfdf +348016c,dfdfdfdf +3480170,dfdfdfdf +3480174,dfdfdfdf +3480178,dfdfdfdf +348017c,dfdfdfdf +3480180,dfdfdfdf +3480184,dfdfdfdf +3480188,dfdfdfdf +348018c,dfdfdfdf +3480190,dfdfdfdf +3480194,dfdfdfdf +3480198,dfdfdfdf +348019c,dfdfdfdf +34801a0,dfdfdfdf +34801a4,dfdfdfdf +34801a8,dfdfdfdf +34801ac,dfdfdfdf +34801b0,dfdfdfdf +34801b4,dfdfdfdf +34801b8,dfdfdfdf +34801bc,dfdfdfdf +34801c0,dfdfdfdf +34801c4,dfdfdfdf +34801c8,dfdfdfdf +34801cc,dfdfdfdf +34801d0,dfdfdfdf +34801d4,dfdfdfdf +34801d8,dfdfdfdf +34801dc,dfdfdfdf +34801e0,dfdfdfdf +34801e4,dfdfdfdf +34801e8,dfdfdfdf +34801ec,dfdfdfdf +34801f0,dfdfdfdf +34801f4,dfdfdfdf +34801f8,dfdfdfdf +34801fc,dfdfdfdf +3480200,dfdfdfdf +3480204,dfdfdfdf +3480208,dfdfdfdf +348020c,dfdfdfdf +3480210,dfdfdfdf +3480214,dfdfdfdf +3480218,dfdfdfdf +348021c,dfdfdfdf +3480220,dfdfdfdf +3480224,dfdfdfdf +3480228,dfdfdfdf +348022c,dfdfdfdf +3480230,dfdfdfdf +3480234,dfdfdfdf +3480238,dfdfdfdf +348023c,dfdfdfdf +3480240,dfdfdfdf +3480244,dfdfdfdf +3480248,dfdfdfdf +348024c,dfdfdfdf +3480250,dfdfdfdf +3480254,dfdfdfdf +3480258,dfdfdfdf +348025c,dfdfdfdf +3480260,dfdfdfdf +3480264,dfdfdfdf +3480268,dfdfdfdf +348026c,dfdfdfdf +3480270,dfdfdfdf +3480274,dfdfdfdf +3480278,dfdfdfdf +348027c,dfdfdfdf +3480280,dfdfdfdf +3480284,dfdfdfdf +3480288,dfdfdfdf +348028c,dfdfdfdf +3480290,dfdfdfdf +3480294,dfdfdfdf +3480298,dfdfdfdf +348029c,dfdfdfdf +34802a0,dfdfdfdf +34802a4,dfdfdfdf +34802a8,dfdfdfdf +34802ac,dfdfdfdf +34802b0,dfdfdfdf +34802b4,dfdfdfdf +34802b8,dfdfdfdf +34802bc,dfdfdfdf +34802c0,dfdfdfdf +34802c4,dfdfdfdf +34802c8,dfdfdfdf +34802cc,dfdfdfdf +34802d0,dfdfdfdf +34802d4,dfdfdfdf +34802d8,dfdfdfdf +34802dc,dfdfdfdf +34802e0,dfdfdfdf +34802e4,dfdfdfdf +34802e8,dfdfdfdf +34802ec,dfdfdfdf +34802f0,dfdfdfdf +34802f4,dfdfdfdf +34802f8,dfdfdfdf +34802fc,dfdfdfdf +3480300,dfdfdfdf +3480304,dfdfdfdf +3480308,dfdfdfdf +348030c,dfdfdfdf +3480310,dfdfdfdf +3480314,dfdfdfdf +3480318,dfdfdfdf +348031c,dfdfdfdf +3480320,dfdfdfdf +3480324,dfdfdfdf +3480328,dfdfdfdf +348032c,dfdfdfdf +3480330,dfdfdfdf +3480334,dfdfdfdf +3480338,dfdfdfdf +348033c,dfdfdfdf +3480340,dfdfdfdf +3480344,dfdfdfdf +3480348,dfdfdfdf +348034c,dfdfdfdf +3480350,dfdfdfdf +3480354,dfdfdfdf +3480358,dfdfdfdf +348035c,dfdfdfdf +3480360,dfdfdfdf +3480364,dfdfdfdf +3480368,dfdfdfdf +348036c,dfdfdfdf +3480370,dfdfdfdf +3480374,dfdfdfdf +3480378,dfdfdfdf +348037c,dfdfdfdf +3480380,dfdfdfdf +3480384,dfdfdfdf +3480388,dfdfdfdf +348038c,dfdfdfdf +3480390,dfdfdfdf +3480394,dfdfdfdf +3480398,dfdfdfdf +348039c,dfdfdfdf +34803a0,dfdfdfdf +34803a4,dfdfdfdf +34803a8,dfdfdfdf +34803ac,dfdfdfdf +34803b0,dfdfdfdf +34803b4,dfdfdfdf +34803b8,dfdfdfdf +34803bc,dfdfdfdf +34803c0,dfdfdfdf +34803c4,dfdfdfdf +34803c8,dfdfdfdf +34803cc,dfdfdfdf +34803d0,dfdfdfdf +34803d4,dfdfdfdf +34803d8,dfdfdfdf +34803dc,dfdfdfdf +34803e0,dfdfdfdf +34803e4,dfdfdfdf +34803e8,dfdfdfdf +34803ec,dfdfdfdf +34803f0,dfdfdfdf +34803f4,dfdfdfdf +34803f8,dfdfdfdf +34803fc,dfdfdfdf +3480400,dfdfdfdf +3480404,dfdfdfdf +3480408,dfdfdfdf +348040c,dfdfdfdf +3480410,dfdfdfdf +3480414,dfdfdfdf +3480418,dfdfdfdf +348041c,dfdfdfdf +3480420,dfdfdfdf +3480424,dfdfdfdf +3480428,dfdfdfdf +348042c,dfdfdfdf +3480430,dfdfdfdf +3480434,dfdfdfdf +3480438,dfdfdfdf +348043c,dfdfdfdf +3480440,dfdfdfdf +3480444,dfdfdfdf +3480448,dfdfdfdf +348044c,dfdfdfdf +3480450,dfdfdfdf +3480454,dfdfdfdf +3480458,dfdfdfdf +348045c,dfdfdfdf +3480460,dfdfdfdf +3480464,dfdfdfdf +3480468,dfdfdfdf +348046c,dfdfdfdf +3480470,dfdfdfdf +3480474,dfdfdfdf +3480478,dfdfdfdf +348047c,dfdfdfdf +3480480,dfdfdfdf +3480484,dfdfdfdf +3480488,dfdfdfdf +348048c,dfdfdfdf +3480490,dfdfdfdf +3480494,dfdfdfdf +3480498,dfdfdfdf +348049c,dfdfdfdf +34804a0,dfdfdfdf +34804a4,dfdfdfdf +34804a8,dfdfdfdf +34804ac,dfdfdfdf +34804b0,dfdfdfdf +34804b4,dfdfdfdf +34804b8,dfdfdfdf +34804bc,dfdfdfdf +34804c0,dfdfdfdf +34804c4,dfdfdfdf +34804c8,dfdfdfdf +34804cc,dfdfdfdf +34804d0,dfdfdfdf +34804d4,dfdfdfdf +34804d8,dfdfdfdf +34804dc,dfdfdfdf +34804e0,dfdfdfdf +34804e4,dfdfdfdf +34804e8,dfdfdfdf +34804ec,dfdfdfdf +34804f0,dfdfdfdf +34804f4,dfdfdfdf +34804f8,dfdfdfdf +34804fc,dfdfdfdf +3480500,dfdfdfdf +3480504,dfdfdfdf +3480508,dfdfdfdf +348050c,dfdfdfdf +3480510,dfdfdfdf +3480514,dfdfdfdf +3480518,dfdfdfdf +348051c,dfdfdfdf +3480520,dfdfdfdf +3480524,dfdfdfdf +3480528,dfdfdfdf +348052c,dfdfdfdf +3480530,dfdfdfdf +3480534,dfdfdfdf +3480538,dfdfdfdf +348053c,dfdfdfdf +3480540,dfdfdfdf +3480544,dfdfdfdf +3480548,dfdfdfdf +348054c,dfdfdfdf +3480550,dfdfdfdf +3480554,dfdfdfdf +3480558,dfdfdfdf +348055c,dfdfdfdf +3480560,dfdfdfdf +3480564,dfdfdfdf +3480568,dfdfdfdf +348056c,dfdfdfdf +3480570,dfdfdfdf +3480574,dfdfdfdf +3480578,dfdfdfdf +348057c,dfdfdfdf +3480580,dfdfdfdf +3480584,dfdfdfdf +3480588,dfdfdfdf +348058c,dfdfdfdf +3480590,dfdfdfdf +3480594,dfdfdfdf +3480598,dfdfdfdf +348059c,dfdfdfdf +34805a0,dfdfdfdf +34805a4,dfdfdfdf +34805a8,dfdfdfdf +34805ac,dfdfdfdf +34805b0,dfdfdfdf +34805b4,dfdfdfdf +34805b8,dfdfdfdf +34805bc,dfdfdfdf +34805c0,dfdfdfdf +34805c4,dfdfdfdf +34805c8,dfdfdfdf +34805cc,dfdfdfdf +34805d0,dfdfdfdf +34805d4,dfdfdfdf +34805d8,dfdfdfdf +34805dc,dfdfdfdf +34805e0,dfdfdfdf +34805e4,dfdfdfdf +34805e8,dfdfdfdf +34805ec,dfdfdfdf +34805f0,dfdfdfdf +34805f4,dfdfdfdf +34805f8,dfdfdfdf +34805fc,dfdfdfdf +3480600,dfdfdfdf +3480604,dfdfdfdf +3480608,dfdfdfdf +348060c,dfdfdfdf +3480610,dfdfdfdf +3480614,dfdfdfdf +3480618,dfdfdfdf +348061c,dfdfdfdf +3480620,dfdfdfdf +3480624,dfdfdfdf +3480628,dfdfdfdf +348062c,dfdfdfdf +3480630,dfdfdfdf +3480634,dfdfdfdf +3480638,dfdfdfdf +348063c,dfdfdfdf +3480640,dfdfdfdf +3480644,dfdfdfdf +3480648,dfdfdfdf +348064c,dfdfdfdf +3480650,dfdfdfdf +3480654,dfdfdfdf +3480658,dfdfdfdf +348065c,dfdfdfdf +3480660,dfdfdfdf +3480664,dfdfdfdf +3480668,dfdfdfdf +348066c,dfdfdfdf +3480670,dfdfdfdf +3480674,dfdfdfdf +3480678,dfdfdfdf +348067c,dfdfdfdf +3480680,dfdfdfdf +3480684,dfdfdfdf +3480688,dfdfdfdf +348068c,dfdfdfdf +3480690,dfdfdfdf +3480694,dfdfdfdf +3480698,dfdfdfdf +348069c,dfdfdfdf +34806a0,dfdfdfdf +34806a4,dfdfdfdf +34806a8,dfdfdfdf +34806ac,dfdfdfdf +34806b0,dfdfdfdf +34806b4,dfdfdfdf +34806b8,dfdfdfdf +34806bc,dfdfdfdf +34806c0,dfdfdfdf +34806c4,dfdfdfdf +34806c8,dfdfdfdf +34806cc,dfdfdfdf +34806d0,dfdfdfdf +34806d4,dfdfdfdf +34806d8,dfdfdfdf +34806dc,dfdfdfdf +34806e0,dfdfdfdf +34806e4,dfdfdfdf +34806e8,dfdfdfdf +34806ec,dfdfdfdf +34806f0,dfdfdfdf +34806f4,dfdfdfdf +34806f8,dfdfdfdf +34806fc,dfdfdfdf +3480700,dfdfdfdf +3480704,dfdfdfdf +3480708,dfdfdfdf +348070c,dfdfdfdf +3480710,dfdfdfdf +3480714,dfdfdfdf +3480718,dfdfdfdf +348071c,dfdfdfdf +3480720,dfdfdfdf +3480724,dfdfdfdf +3480728,dfdfdfdf +348072c,dfdfdfdf +3480730,dfdfdfdf +3480734,dfdfdfdf +3480738,dfdfdfdf +348073c,dfdfdfdf +3480740,dfdfdfdf +3480744,dfdfdfdf +3480748,dfdfdfdf +348074c,dfdfdfdf +3480750,dfdfdfdf +3480754,dfdfdfdf +3480758,dfdfdfdf +348075c,dfdfdfdf +3480760,dfdfdfdf +3480764,dfdfdfdf +3480768,dfdfdfdf +348076c,dfdfdfdf +3480770,dfdfdfdf +3480774,dfdfdfdf +3480778,dfdfdfdf +348077c,dfdfdfdf +3480780,dfdfdfdf +3480784,dfdfdfdf +3480788,dfdfdfdf +348078c,dfdfdfdf +3480790,dfdfdfdf +3480794,dfdfdfdf +3480798,dfdfdfdf +348079c,dfdfdfdf +34807a0,dfdfdfdf +34807a4,dfdfdfdf +34807a8,dfdfdfdf +34807ac,dfdfdfdf +34807b0,dfdfdfdf +34807b4,dfdfdfdf +34807b8,dfdfdfdf +34807bc,dfdfdfdf +34807c0,dfdfdfdf +34807c4,dfdfdfdf +34807c8,dfdfdfdf +34807cc,dfdfdfdf +34807d0,dfdfdfdf +34807d4,dfdfdfdf +34807d8,dfdfdfdf +34807dc,dfdfdfdf +34807e0,dfdfdfdf +34807e4,dfdfdfdf +34807e8,dfdfdfdf +34807ec,dfdfdfdf +34807f0,dfdfdfdf +34807f4,dfdfdfdf +34807f8,dfdfdfdf +34807fc,dfdfdfdf +3480800,dfdfdfdf +3480804,dfdfdfdf +3480808,dfdfdfdf +348080c,dfdfdfdf +3480810,dfdfdfdf +3480814,dfdfdfdf +3480818,dfdfdfdf +348081c,dfdfdfdf +3480820,dfdfdfdf +3480824,dfdfdfdf +3480828,dfdfdfdf +348082c,dfdfdfdf +3480830,dfdfdfdf +3480844,1f073fd8 +3480848,ff +348084c,ff +3480850,460032 +3480854,5a005a +3480858,ff0000 +348085c,960000 +3480860,ff00a0 +3480868,5000c8 +348086c,50 +3480870,ff0050 +3480874,9600ff +3480878,ff00ff +348087c,32ffff +3480880,64ffff64 +3480884,fa0000fa +3480888,100 +3480cd0,640000 +3480cd4,100 +3480ce4,27bdffe8 +3480ce8,afbf0010 +3480cec,c101f62 +3480cf4,3c028012 +3480cf8,2442d2a0 +3480cfc,240e0140 +3480d00,3c018010 +3480d04,ac2ee500 +3480d08,240f00f0 +3480d0c,8fbf0010 +3480d10,3e00008 +3480d14,27bd0018 +3480d18,3c088040 +3480d1c,ac4815d4 +3480d20,3e00008 +3480d24,340215c0 +3480d28,308400ff +3480d2c,3c088012 +3480d30,2508a5d0 +3480d34,3401008c +3480d38,10810016 +3480d3c,91020075 +3480d40,3401008d +3480d44,10810013 +3480d48,91020075 +3480d4c,10800011 +3480d50,91020074 +3480d54,3401008a +3480d58,1081000e +3480d5c,91020074 +3480d60,3401008b +3480d64,1081000b +3480d68,91020074 +3480d6c,34010058 +3480d70,10810008 +3480d74,34020000 +3480d78,34010078 +3480d7c,10810005 +3480d80,34020000 +3480d84,34010079 +3480d88,10810002 +3480d8c,34020000 +3480d90,340200ff +3480d94,3e00008 +3480d9c,8fa60030 +3480da0,810036d +3480da4,84c50004 +3480da8,8fb9002c +3480dac,810036d +3480db0,87250004 +3480db4,3c0a8041 +3480db8,254ab178 +3480dbc,8d4a0000 +3480dc0,11400004 +3480dc8,3c058041 +3480dcc,24a5b16c +3480dd0,8ca50000 +3480dd4,3e00008 +3480ddc,3c088041 +3480de0,2508b178 +3480de4,8d080000 +3480de8,11000004 +3480df0,3c038041 +3480df4,2463b168 +3480df8,8c630000 +3480dfc,30fc3 +3480e00,614026 +3480e04,1014023 +3480e08,a0880852 +3480e0c,3e00008 +3480e14,3c088040 +3480e18,25080cd6 +3480e1c,91080000 +3480e20,1500000c +3480e24,240bffff +3480e28,3c088041 +3480e2c,2508b178 +3480e30,8d080000 +3480e34,11000007 +3480e38,1405821 +3480e3c,3c088041 +3480e40,2508b164 +3480e44,8d080000 +3480e48,15000002 +3480e4c,240bffff +3480e50,340b0001 +3480e54,5600009 +3480e5c,27bdffe8 +3480e60,afab0010 +3480e64,afbf0014 +3480e68,c01c508 +3480e70,8fab0010 +3480e74,8fbf0014 +3480e78,27bd0018 +3480e7c,3e00008 +3480e84,90450003 +3480e88,3c088041 +3480e8c,2508b178 +3480e90,8d080000 +3480e94,11000004 +3480e9c,3c058041 +3480ea0,24a5b170 +3480ea4,8ca50000 +3480ea8,3e00008 +3480eb0,27bdffe8 +3480eb4,afb00010 +3480eb8,afbf0014 +3480ebc,3c088041 +3480ec0,2508b17c +3480ec4,8d080000 +3480ec8,31080001 +3480ecc,1500000b +3480ed0,34100041 +3480ed4,3c048041 +3480ed8,2484b178 +3480edc,8c840000 +3480ee0,10800006 +3480ee4,90500000 +3480ee8,3c088041 +3480eec,2508b174 +3480ef0,8d100000 +3480ef4,c101eb9 +3480efc,c101a77 +3480f04,2002821 +3480f08,8fb00010 +3480f0c,8fbf0014 +3480f10,3e00008 +3480f14,27bd0018 +3480f18,27bdffe0 +3480f1c,afa70010 +3480f20,afa20014 +3480f24,afa30018 +3480f28,afbf001c +3480f2c,c101ae8 +3480f30,e02821 +3480f34,8fa70010 +3480f38,8fa20014 +3480f3c,8fa30018 +3480f40,8fbf001c +3480f44,3e00008 +3480f48,27bd0020 +3480f4c,27bdffe8 +3480f50,afbf0010 +3480f54,8c881d2c +3480f58,34090001 +3480f5c,94e00 +3480f60,1091024 +3480f64,10400021 +3480f6c,94ca02dc +3480f70,3c0b8012 +3480f74,256ba5d0 +3480f78,948c00a4 +3480f7c,3401003d +3480f80,1181000a +3480f88,8a6021 +3480f8c,918d1d28 +3480f90,15a00014 +3480f98,340d0001 +3480f9c,a18d1d28 +3480fa0,254a0013 +3480fa4,1000000a +3480fac,340c0001 +3480fb0,14c6004 +3480fb4,916d0ef2 +3480fb8,1ac7024 +3480fbc,15c00009 +3480fc4,1ac7025 +3480fc8,a16e0ef2 +3480fcc,254a0010 +3480fd0,1294827 +3480fd4,1094024 +3480fd8,ac881d2c +3480fdc,c101a27 +3480fe0,1402021 +3480fe4,c1024e1 +3480fec,8fbf0010 +3480ff0,34020000 +3480ff4,3e00008 +3480ff8,27bd0018 +3480ffc,27bdffe8 +3481000,afbf0010 +3481004,c101a27 +3481008,20e4ffc6 +348100c,340200ff +3481010,8fbf0010 +3481014,3e00008 +3481018,27bd0018 +348101c,27bdffe0 +3481020,afa10010 +3481024,afa30014 +3481028,afbf0018 +348102c,c101a27 +3481030,34040023 +3481034,8fa10010 +3481038,8fa30014 +348103c,8fbf0018 +3481040,3e00008 +3481044,27bd0020 +3481048,27bdffe0 +348104c,afa60010 +3481050,afa70014 +3481054,afbf0018 +3481058,3c018012 +348105c,2421a5d0 +3481060,80280ede +3481064,35080001 +3481068,a0280ede +348106c,c101a27 +3481070,34040027 +3481074,8fa60010 +3481078,8fa70014 +348107c,8fbf0018 +3481080,3e00008 +3481084,27bd0020 +3481088,27bdffe8 +348108c,afa30010 +3481090,afbf0014 +3481094,3c018012 +3481098,2421a5d0 +348109c,80280ede +34810a0,35080004 +34810a4,a0280ede +34810a8,c101a27 +34810ac,34040029 +34810b0,8fa30010 +34810b4,8fbf0014 +34810b8,3e00008 +34810bc,27bd0018 +34810c0,27bdffd8 +34810c4,afa40010 +34810c8,afa20014 +34810cc,afaf0018 +34810d0,afbf0020 +34810d4,c101a27 +34810d8,3404002a +34810dc,34050003 +34810e0,8fa40010 +34810e4,8fa20014 +34810e8,8faf0018 +34810ec,8fbf0020 +34810f0,3e00008 +34810f4,27bd0028 +34810f8,607821 +34810fc,81ec0edf +3481100,318e0080 +3481104,11c00003 +3481108,34030005 +348110c,3e00008 +3481110,34020002 +3481114,3e00008 +3481118,601021 +348111c,85c200a4 +3481120,3c088012 +3481124,2508a5d0 +3481128,81090edf +348112c,35290080 +3481130,a1090edf +3481134,3e00008 +348113c,27bdfff0 +3481140,afbf0004 +3481144,c035886 +348114c,3c0c8012 +3481150,258ca5d0 +3481154,858d0f2e +3481158,8d980004 +348115c,13000002 +3481160,340e0001 +3481164,340e0002 +3481168,1ae6825 +348116c,a58d0f2e +3481170,8fbf0004 +3481174,27bd0010 +3481178,3e00008 +3481180,24090041 +3481184,27bdffe0 +3481188,afa80004 +348118c,afa90008 +3481190,afaa000c +3481194,afac0010 +3481198,3c0affff +348119c,a5403 +34811a0,3c08801d +34811a4,850c894c +34811a8,118a0002 +34811b0,a500894c +34811b4,3c08801e +34811b8,810a887c +34811bc,11400009 +34811c4,3c090036 +34811c8,94c03 +34811cc,a109887c +34811d0,3c090002 +34811d4,94c03 +34811d8,a109895f +34811dc,3c08801f +34811e0,a1008d38 +34811e4,8fac0010 +34811e8,8faa000c +34811ec,8fa90008 +34811f0,8fa80004 +34811f4,3e00008 +34811f8,27bd0020 +3481200,3c0a8010 +3481204,254ae49c +3481208,8d4a0000 +348120c,1140001e +3481214,3c08801d +3481218,250884a0 +348121c,3c0b0001 +3481220,356b04c4 +3481224,10b4020 +3481228,85090000 +348122c,3c0b0002 +3481230,356b26cc +3481234,14b5020 +3481238,94840 +348123c,12a5021 +3481240,85490000 +3481244,a5091956 +3481248,3c0c801e +348124c,258c84a0 +3481250,34090003 +3481254,a1891e5e +3481258,34090014 +348125c,a1091951 +3481260,34090001 +3481264,3c018040 +3481268,a02911fc +348126c,3c088012 +3481270,2508a5d0 +3481274,850913d2 +3481278,11200003 +3481280,34090001 +3481284,a50913d4 +3481288,3e00008 +3481290,3421241c +3481294,3c0d8040 +3481298,25ad11fc +348129c,81a90000 +34812a0,11200008 +34812a4,862a00a4 +34812a8,340b005e +34812ac,114b0005 +34812b0,3c0c801e +34812b4,258c84a0 +34812b8,34090003 +34812bc,a1891e5e +34812c0,a1a00000 +34812c4,3e00008 +34812cc,3c02801d +34812d0,244284a0 +34812d4,3c010001 +34812d8,411020 +34812dc,3401047e +34812e0,a4411e1a +34812e4,34010014 +34812e8,3e00008 +34812ec,a0411e15 +34812f0,27bdffe8 +34812f4,afbf0014 +34812f8,afa40018 +34812fc,8e190004 +3481300,17200015 +3481304,8e190000 +3481308,3c018010 +348130c,24219c90 +3481310,19c880 +3481314,3210820 +3481318,90210000 +348131c,34190052 +3481320,1721000d +3481324,8e190000 +3481328,960200a6 +348132c,304c0007 +3481330,398c0007 +3481334,15800008 +3481338,240400aa +348133c,c00a22d +3481344,14400004 +3481348,8e190000 +348134c,341900db +3481350,10000002 +3481354,ae190000 +3481358,340101e1 +348135c,8fbf0014 +3481360,8fa40018 +3481364,3e00008 +3481368,27bd0018 +348136c,3c088040 +3481370,81080cdf +3481374,11000005 +3481378,3c018012 +348137c,2421a5d0 +3481380,80280ed6 +3481384,35080001 +3481388,a0280ed6 +348138c,34080000 +3481390,3e00008 +3481394,adf90000 +3481398,3c0b801d +348139c,256b84a0 +34813a0,856b00a4 +34813a4,340c005a +34813a8,156c0003 +34813ac,340b01a5 +34813b0,a42b1e1a +34813b4,1000000e +34813b8,3c0c8012 +34813bc,258ca5d0 +34813c0,8d8c0004 +34813c4,15800008 +34813c8,3c0b8040 +34813cc,816b0cdf +34813d0,11600007 +34813d4,842b1e1a +34813d8,340c01a5 +34813dc,116c0002 +34813e4,10000002 +34813e8,340b0129 +34813ec,a42b1e1a +34813f0,3e00008 +34813fc,2202825 +3481400,3c0a801e +3481404,254aaa30 +3481408,c544002c +348140c,3c0bc43c +3481410,256b8000 +3481414,448b3000 +3481418,4606203c +3481420,45000026 +3481428,c5440024 +348142c,3c0bc28a +3481430,448b3000 +3481434,4606203c +348143c,4501001f +3481444,3c0b41c8 +3481448,448b3000 +348144c,4606203c +3481454,45000019 +348145c,3c098040 +3481460,252913f8 +3481464,814b0424 +3481468,1160000e +348146c,812e0000 +3481470,340c007e +3481474,116c000b +348147c,15c00009 +3481480,340c0001 +3481484,a12c0000 +3481488,3c0dc1a0 +348148c,ad4d0024 +3481490,3c0d4120 +3481494,ad4d0028 +3481498,3c0dc446 +348149c,25ad8000 +34814a0,ad4d002c +34814a4,11c00005 +34814ac,15600003 +34814b0,340d8000 +34814b4,a54d00b6 +34814b8,a1200000 +34814bc,3e00008 +34814c8,3c0a801e +34814cc,254aaa30 +34814d0,8d4b066c +34814d4,3c0cd000 +34814d8,258cffff +34814dc,16c5824 +34814e0,3e00008 +34814e4,ad4b066c +34814e8,27bdffe0 +34814ec,afbf0014 +34814f0,afa40018 +34814f4,1c17825 +34814f8,ac4f0680 +34814fc,34040001 +3481500,c01b638 +3481508,3c088040 +348150c,81080cd8 +3481510,15000007 +3481518,3c04801d +348151c,248484a0 +3481520,3c058040 +3481524,80a50cd9 +3481528,c037500 +3481530,8fa40018 +3481534,8c880138 +3481538,8d090010 +348153c,252a03d4 +3481540,ac8a029c +3481544,8fbf0014 +3481548,3e00008 +348154c,27bd0020 +3481550,27bdffe0 +3481554,afbf0014 +3481558,afa40018 +348155c,3c088040 +3481560,81080cd8 +3481564,1500001a +348156c,3c09801e +3481570,2529887c +3481574,81280000 +3481578,340b0036 +348157c,150b001e +3481584,3c088040 +3481588,810814c4 +348158c,1500001a +3481594,34080001 +3481598,3c018040 +348159c,a02814c4 +34815a0,3c04801d +34815a4,248484a0 +34815a8,3c058040 +34815ac,90a50cda +34815b0,34060000 +34815b4,c037385 +34815bc,34044802 +34815c0,c0191bc +34815c8,10000025 +34815d0,3c04801d +34815d4,248484a0 +34815d8,34050065 +34815dc,c01bf73 +34815e4,34040032 +34815e8,c01b638 +34815f0,1000000c +34815f8,8fa40018 +34815fc,3c05801d +3481600,24a584a0 +3481604,c008ab4 +348160c,10400014 +3481614,3c088040 +3481618,810814c4 +348161c,11000010 +3481624,8fa40018 +3481628,8c880138 +348162c,8d090010 +3481630,252a035c +3481634,ac8a029c +3481638,3c028012 +348163c,2442a5d0 +3481640,94490ee0 +3481644,352a0020 +3481648,a44a0ee0 +348164c,8c880004 +3481650,3c09ffff +3481654,2529ffff +3481658,1094024 +348165c,ac880004 +3481660,8fbf0014 +3481664,3e00008 +3481668,27bd0020 +348166c,860f00b6 +3481670,9739b4ae +3481674,3c09801e +3481678,2529aa30 +348167c,812a0424 +3481680,11400004 +3481688,3409007e +348168c,15490003 +3481694,3e00008 +3481698,340a0000 +348169c,3e00008 +34816a0,340a0001 +34816a4,8c8e0134 +34816a8,15c00002 +34816ac,3c0e4480 +34816b0,ac8e0024 +34816b4,3e00008 +34816b8,8fae0044 +34816bc,260501a4 +34816c0,27bdffe0 +34816c4,afbf0014 +34816c8,afa50018 +34816cc,8625001c +34816d0,52a03 +34816d4,c008134 +34816d8,30a5003f +34816dc,8fa50018 +34816e0,8fbf0014 +34816e4,3e00008 +34816e8,27bd0020 +34816ec,ae19066c +34816f0,8e0a0428 +34816f4,3c09801e +34816f8,2529aa30 +34816fc,854b00b6 +3481700,216b8000 +3481704,3e00008 +3481708,a52b00b6 +348170c,3c08801e +3481710,2508aa30 +3481714,810a0434 +3481718,340b0008 +348171c,154b0002 +3481720,34090007 +3481724,a1090434 +3481728,3e00008 +348172c,c606000c +3481730,3c08801e +3481734,2508aa30 +3481738,8d0901ac +348173c,3c0a0400 +3481740,254a2f98 +3481744,152a000b +3481748,8d0b01bc +348174c,3c0c42cf +3481750,156c0003 +3481754,3c0d4364 +3481758,10000006 +348175c,ad0d01bc +3481760,3c0c4379 +3481764,156c0003 +3481768,3c09803b +348176c,2529967c +3481770,ad090664 +3481774,3e00008 +3481778,260501a4 +348177c,a498017c +3481780,3c08801d +3481784,250884a0 +3481788,850900a4 +348178c,340a0002 +3481790,152a000e +3481794,8c890138 +3481798,8d290010 +348179c,252a3398 +34817a0,ac8a0184 +34817a4,340b0001 +34817a8,a48b017c +34817ac,27bdffe8 +34817b0,afbf0014 +34817b4,3c053dcd +34817b8,24a5cccd +34817bc,c0083e2 +34817c4,8fbf0014 +34817c8,27bd0018 +34817cc,3e00008 +34817d4,948e001c +34817d8,21cdffce +34817dc,5a00010 +34817e0,34020000 +34817e4,31a90007 +34817e8,340a0001 +34817ec,12a5004 +34817f0,d48c2 +34817f4,3c0c8012 +34817f8,258ca5d0 +34817fc,1896020 +3481800,918b05b4 +3481804,16a5824 +3481808,34020000 +348180c,11600004 +3481814,340d0026 +3481818,a48d001c +348181c,34020001 +3481820,3e00008 +3481828,94ae001c +348182c,21cdffce +3481830,5a0000b +3481834,34020000 +3481838,31a90007 +348183c,340a0001 +3481840,12a5004 +3481844,d48c2 +3481848,3c0c8012 +348184c,258ca5d0 +3481850,1896020 +3481854,918b05b4 +3481858,16a5825 +348185c,a18b05b4 +3481860,3e00008 +3481868,27bdfff0 +348186c,afbf0008 +3481870,28810032 +3481874,10200003 +3481878,801021 +348187c,320f809 +3481884,8fbf0008 +3481888,27bd0010 +348188c,3e00008 +3481894,3c08801d +3481898,250884a0 +348189c,3c098012 +34818a0,2529a5d0 +34818a4,950a00a4 +34818a8,3401003e +34818ac,15410002 +34818b0,912b1397 +34818b4,216aff2a +34818b8,960b001c +34818bc,216b0001 +34818c0,340c0001 +34818c4,16c6004 +34818c8,3401001c +34818cc,1410018 +34818d0,6812 +34818d4,12d7020 +34818d8,8dcf00e4 +34818dc,18f1024 +34818e0,3e00008 +34818e8,3c08801d +34818ec,250884a0 +34818f0,3c098012 +34818f4,2529a5d0 +34818f8,950a00a4 +34818fc,3401003e +3481900,15410002 +3481904,912b1397 +3481908,216aff2a +348190c,848b001c +3481910,216b0001 +3481914,340c0001 +3481918,16c6004 +348191c,3401001c +3481920,1410018 +3481924,6812 +3481928,12d7020 +348192c,8dcf00e4 +3481930,18f7825 +3481934,adcf00e4 +3481938,3e00008 +3481940,27bdffe8 +3481944,afbf0010 +3481948,c101f71 +3481950,8fbf0010 +3481954,27bd0018 +3481958,8fae0018 +348195c,3e00008 +3481960,3c018010 +3481964,340100ff +3481968,15210002 +348196c,92220000 +3481970,340200ff +3481974,3e00008 +3481978,34010009 +348197c,27bdffe8 +3481980,afa20010 +3481984,afbf0014 +3481988,c100683 +3481990,14400002 +3481994,91830000 +3481998,340300ff +348199c,8fa20010 +34819a0,8fbf0014 +34819a4,27bd0018 +34819a8,3e00008 +34819ac,34010009 +34819b0,27bdffe8 +34819b4,afa20010 +34819b8,afbf0014 +34819bc,960201e8 +34819c0,34010003 +34819c4,14410007 +34819cc,c100683 +34819d4,14400007 +34819dc,10000005 +34819e0,3403007a +34819e4,3401017a +34819e8,14610002 +34819f0,3403007a +34819f4,36280 +34819f8,18d2821 +34819fc,8fa20010 +3481a00,8fbf0014 +3481a04,3e00008 +3481a08,27bd0018 +3481a0c,27bdfff0 +3481a10,afbf0000 +3481a14,afa30004 +3481a18,afa40008 +3481a1c,c101f9e +3481a24,8fbf0000 +3481a28,8fa30004 +3481a2c,8fa40008 +3481a30,3e00008 +3481a34,27bd0010 +3481a38,6d7024 +3481a3c,15c00002 +3481a40,91ec0000 +3481a44,27ff003c +3481a48,3e00008 +3481a5c,3c088012 +3481a60,2508a5d0 +3481a64,8509009c +3481a68,352a0002 +3481a6c,3e00008 +3481a70,a50a009c +3481a74,3c058012 +3481a78,24a5a5d0 +3481a7c,3c088040 +3481a80,25081a50 +3481a84,8ca90068 +3481a88,ad090000 +3481a8c,8ca9006c +3481a90,ad090004 +3481a94,94a90070 +3481a98,a5090008 +3481a9c,94a9009c +3481aa0,a509000a +3481aa4,340807e4 +3481aa8,1054021 +3481aac,34090e64 +3481ab0,1254821 +3481ab4,340a0008 +3481ab8,8d0b0000 +3481abc,8d2c0000 +3481ac0,ad2b0000 +3481ac4,ad0c0000 +3481ac8,2508001c +3481acc,25290004 +3481ad0,254affff +3481ad4,1d40fff8 +3481adc,801be03 +3481ae4,27bdffe0 +3481ae8,afb00010 +3481aec,afb10014 +3481af0,afbf0018 +3481af4,3c108012 +3481af8,2610a5d0 +3481afc,3c118040 +3481b00,26311a50 +3481b04,8e080004 +3481b08,11000005 +3481b10,c1006e3 +3481b18,10000003 +3481b20,c1006f6 +3481b28,c1006d6 +3481b2c,34040000 +3481b30,c1006d6 +3481b34,34040001 +3481b38,c1006d6 +3481b3c,34040002 +3481b40,8fb00010 +3481b44,8fb10014 +3481b48,8fbf0018 +3481b4c,27bd0020 +3481b50,3e00008 +3481b58,2044021 +3481b5c,9109006c +3481b60,340100ff +3481b64,11210007 +3481b6c,2094821 +3481b70,91290074 +3481b74,3401002c +3481b78,11210002 +3481b80,a1090069 +3481b84,3e00008 +3481b8c,27bdffe8 +3481b90,afbf0010 +3481b94,8e280000 +3481b98,ae080040 +3481b9c,8e280004 +3481ba0,ae080044 +3481ba4,96280008 +3481ba8,a6080048 +3481bac,a2000f33 +3481bb0,9208004a +3481bb4,340100ff +3481bb8,15010003 +3481bc0,c100709 +3481bc8,8fbf0010 +3481bcc,27bd0018 +3481bd0,3e00008 +3481bd8,8e080040 +3481bdc,ae080068 +3481be0,8e080044 +3481be4,ae08006c +3481be8,96080048 +3481bec,9209009d +3481bf0,31290020 +3481bf4,15200002 +3481bfc,3108ffdf +3481c00,a6080070 +3481c04,92080068 +3481c08,340100ff +3481c0c,15010003 +3481c14,34080001 +3481c18,a2080f33 +3481c1c,3e00008 +3481c24,27bdffe8 +3481c28,afbf0010 +3481c2c,9608009c +3481c30,31080040 +3481c34,11000005 +3481c3c,96080070 +3481c40,3108ff0f +3481c44,35080030 +3481c48,a6080070 +3481c4c,92280001 +3481c50,a2080069 +3481c54,96280002 +3481c58,a608006a +3481c5c,8e280004 +3481c60,ae08006c +3481c64,c100723 +3481c68,34040000 +3481c6c,c100723 +3481c70,34040001 +3481c74,c100723 +3481c78,34040002 +3481c7c,8fbf0010 +3481c80,27bd0018 +3481c84,3e00008 +3481c8c,2044021 +3481c90,3c098040 +3481c94,25291d34 +3481c98,910a006c +3481c9c,340100ff +3481ca0,11410005 +3481ca8,12a4821 +3481cac,91290000 +3481cb0,1520001c +3481cb8,3c098040 +3481cbc,25291d2b +3481cc0,25290001 +3481cc4,912a0000 +3481cc8,11400013 +3481cd0,20a5821 +3481cd4,916b0074 +3481cd8,340100ff +3481cdc,1161fff8 +3481ce4,920c006c +3481ce8,118afff5 +3481cf0,920c006d +3481cf4,118afff2 +3481cfc,920c006e +3481d00,118affef +3481d08,a10b0069 +3481d0c,a10a006c +3481d10,10000004 +3481d18,340900ff +3481d1c,a1090069 +3481d20,a109006c +3481d24,3e00008 +3481d2c,90f0203 +3481d30,10d0b00 +3481d34,10101 +3481d38,1010001 +3481d3c,1010101 +3481d40,10001 +3481d44,1010101 +3481d48,1010100 +3481d4c,330821 +3481d50,200f0047 +3481d54,15ea000e +3481d58,3c028012 +3481d5c,8c42a5d4 +3481d60,8e6f00a4 +3481d64,f7a03 +3481d68,14400005 +3481d6c,34024830 +3481d70,15e20007 +3481d78,24190003 +3481d7c,10000004 +3481d80,34026311 +3481d84,15e20002 +3481d8c,24190003 +3481d90,3e00008 +3481d98,330821 +3481d9c,3c028012 +3481da0,8c42a5d4 +3481da4,8e6f00a4 +3481da8,f7a03 +3481dac,14400005 +3481db0,34024830 +3481db4,15e20007 +3481dbc,24190003 +3481dc0,10000004 +3481dc4,34026311 +3481dc8,15e20002 +3481dd0,24190003 +3481dd4,3e00008 +3481ddc,34010018 +3481de0,14810015 +3481de8,14400013 +3481df0,3c0a8012 +3481df4,254aa5d0 +3481df8,814800a6 +3481dfc,31080020 +3481e00,1100000d +3481e04,34020000 +3481e08,8148007b +3481e0c,34090007 +3481e10,11090005 +3481e14,34090008 +3481e18,11090003 +3481e20,810078e +3481e24,34020000 +3481e28,81480ed6 +3481e2c,35080001 +3481e30,a1480ed6 +3481e34,34020001 +3481e38,3e00008 +3481e40,3c018040 +3481e44,8c210ccc +3481e48,10200006 +3481e50,94480670 +3481e54,31010800 +3481e58,34080800 +3481e5c,3e00008 +3481e64,950804c6 +3481e68,3401000b +3481e6c,3e00008 +3481e74,27bdffe8 +3481e78,afa50000 +3481e7c,afa60004 +3481e80,afa70008 +3481e84,afbf0010 +3481e88,80a80000 +3481e8c,25090001 +3481e90,15200005 +3481e98,52025 +3481e9c,24a50008 +3481ea0,c015c0c +3481ea4,24c6fff8 +3481ea8,c1024eb +3481eb0,8fbf0010 +3481eb4,8fa70008 +3481eb8,8fa60004 +3481ebc,8fa50000 +3481ec0,8015c0c +3481ec4,27bd0018 +3481ec8,ac4d066c +3481ecc,a0400141 +3481ed0,a0400144 +3481ed4,340e00fe +3481ed8,3e00008 +3481edc,a04e0142 +3481ee0,a2250021 +3481ee4,3c108040 +3481ee8,26100898 +3481eec,26100004 +3481ef0,8e0a0000 +3481ef4,1140000b +3481efc,a7c02 +3481f00,1f17820 +3481f04,3158ff00 +3481f08,18c202 +3481f0c,17000003 +3481f10,315900ff +3481f14,81ea0000 +3481f18,32ac825 +3481f1c,81007bb +3481f20,a1f90000 +3481f24,3e00008 +3481f2c,27bdfff0 +3481f30,afbf0008 +3481f34,c1007d9 +3481f38,2264ffff +3481f3c,344a0000 +3481f40,8fbf0008 +3481f44,27bd0010 +3481f48,27bdfff0 +3481f4c,afbf0008 +3481f50,c1007d9 +3481f54,36440000 +3481f58,34500000 +3481f5c,8fbf0008 +3481f60,27bd0010 +3481f64,3c088040 +3481f68,25080025 +3481f6c,91080000 +3481f70,15000007 +3481f78,3c088012 +3481f7c,2508a5d0 +3481f80,1044020 +3481f84,91020024 +3481f88,10000007 +3481f90,840c0 +3481f94,3c028040 +3481f98,24420034 +3481f9c,1024020 +3481fa0,1044020 +3481fa4,91020000 +3481fa8,3e00008 +3481fb0,8fb60030 +3481fb4,8fb70034 +3481fb8,8fbe0038 +3481fbc,3c088040 +3481fc0,25080025 +3481fc4,a1000000 +3481fc8,3e00008 +3481fd0,3c0a8012 +3481fd4,8d4aa5d4 +3481fd8,15400006 +3481fdc,31780001 +3481fe0,17000007 +3481fe4,3c184230 +3481fe8,3c184250 +3481fec,3e00008 +3481ff4,17000002 +3481ff8,3c184210 +3481ffc,3c184238 +3482000,3e00008 +3482008,906e13e2 +348200c,90620068 +3482010,34010059 +3482014,10410002 +3482018,34010fff +348201c,340100ff +3482020,3e00008 +3482028,3c048012 +348202c,2484a5d0 +3482030,908e13e2 +3482034,90820068 +3482038,34010059 +348203c,10410002 +3482040,34010fff +3482044,340100ff +3482048,3e00008 +3482050,3c08801f +3482054,25085de0 +3482058,8d01009c +348205c,14200003 +3482060,46025102 +3482064,3c083f80 +3482068,44882000 +348206c,3e00008 +3482074,ac800118 +3482078,27ff0030 +348207c,3e00008 +3482080,ac8e0180 +3482084,3c018040 +3482088,8c210cbc +348208c,10200008 +3482094,81efa64c +3482098,34180009 +348209c,11f80002 +34820a0,34180001 +34820a4,34180000 +34820a8,3e00008 +34820b0,8defa670 +34820b4,31f80018 +34820b8,3e00008 +34820c0,3c018040 +34820c4,8c210cbc +34820c8,10200008 +34820d0,816ba64c +34820d4,340c0009 +34820d8,116c0002 +34820dc,340c0001 +34820e0,340c0000 +34820e4,3e00008 +34820ec,8d6ba670 +34820f0,316c0018 +34820f4,3e00008 +34820fc,3c018040 +3482100,8c210cbc +3482104,10200008 +348210c,3c098012 +3482110,812aa64c +3482114,340b0009 +3482118,114b0009 +348211c,34020000 +3482120,3e00008 +3482124,34020002 +3482128,3c098012 +348212c,812aa673 +3482130,314a0038 +3482134,15400002 +3482138,34020000 +348213c,34020002 +3482140,3e00008 +3482148,3c0a8040 +348214c,8d4a0cc0 +3482150,1140000a +3482154,34010001 +3482158,1141000b +348215c,34010002 +3482160,11410026 +3482164,34010003 +3482168,11410051 +348216c,34010004 +3482170,11410069 +3482174,34010005 +3482178,11410061 +348217c,34010000 +3482180,3e00008 +3482184,340a0000 +3482188,3401003f +348218c,415024 +3482190,340f0000 +3482194,31580001 +3482198,13000002 +34821a0,25ef0001 +34821a4,31580002 +34821a8,13000002 +34821b0,25ef0001 +34821b4,31580004 +34821b8,13000002 +34821c0,25ef0001 +34821c4,31580008 +34821c8,13000002 +34821d0,25ef0001 +34821d4,31580010 +34821d8,13000002 +34821e0,25ef0001 +34821e4,31580020 +34821e8,13000002 +34821f0,25ef0001 +34821f4,10000043 +34821fc,3c01001c +3482200,2421003f +3482204,415024 +3482208,340f0000 +348220c,31580001 +3482210,13000002 +3482218,25ef0001 +348221c,31580002 +3482220,13000002 +3482228,25ef0001 +348222c,31580004 +3482230,13000002 +3482238,25ef0001 +348223c,31580008 +3482240,13000002 +3482248,25ef0001 +348224c,31580010 +3482250,13000002 +3482258,25ef0001 +348225c,31580020 +3482260,13000002 +3482268,25ef0001 +348226c,3c180004 +3482270,158c024 +3482274,13000002 +348227c,25ef0001 +3482280,3c180008 +3482284,158c024 +3482288,13000002 +3482290,25ef0001 +3482294,3c180010 +3482298,158c024 +348229c,13000002 +34822a4,25ef0001 +34822a8,10000016 +34822b0,3c01001c +34822b4,415024 +34822b8,340f0000 +34822bc,3c180004 +34822c0,158c024 +34822c4,13000002 +34822cc,25ef0001 +34822d0,3c180008 +34822d4,158c024 +34822d8,13000002 +34822e0,25ef0001 +34822e4,3c180010 +34822e8,158c024 +34822ec,13000002 +34822f4,25ef0001 +34822f8,10000002 +3482300,84ef00d0 +3482304,34010000 +3482308,3c188040 +348230c,87180cd0 +3482310,3e00008 +3482314,1f8502a +3482318,34010018 +348231c,415024 +3482320,15410006 +3482328,90ef0084 +348232c,340a0012 +3482330,114f0002 +3482338,3401ffff +348233c,3e00008 +3482340,415024 +3482344,3c098040 +3482348,8d290cc4 +348234c,340a0001 +3482350,112a000e +3482354,340a0002 +3482358,112a0029 +348235c,340a0003 +3482360,112a0054 +3482364,340a0004 +3482368,112a0066 +3482370,340b0018 +3482374,4b5024 +3482378,156a0002 +348237c,34030000 +3482380,34030001 +3482384,3e00008 +348238c,3401003f +3482390,415024 +3482394,340c0000 +3482398,314b0001 +348239c,11600002 +34823a4,258c0001 +34823a8,314b0002 +34823ac,11600002 +34823b4,258c0001 +34823b8,314b0004 +34823bc,11600002 +34823c4,258c0001 +34823c8,314b0008 +34823cc,11600002 +34823d4,258c0001 +34823d8,314b0010 +34823dc,11600002 +34823e4,258c0001 +34823e8,314b0020 +34823ec,11600002 +34823f4,258c0001 +34823f8,10000043 +3482400,3c01001c +3482404,2421003f +3482408,415024 +348240c,340c0000 +3482410,314b0001 +3482414,11600002 +348241c,258c0001 +3482420,314b0002 +3482424,11600002 +348242c,258c0001 +3482430,314b0004 +3482434,11600002 +348243c,258c0001 +3482440,314b0008 +3482444,11600002 +348244c,258c0001 +3482450,314b0010 +3482454,11600002 +348245c,258c0001 +3482460,314b0020 +3482464,11600002 +348246c,258c0001 +3482470,3c0b0004 +3482474,14b5824 +3482478,11600002 +3482480,258c0001 +3482484,3c0b0008 +3482488,14b5824 +348248c,11600002 +3482494,258c0001 +3482498,3c0b0010 +348249c,14b5824 +34824a0,11600002 +34824a8,258c0001 +34824ac,10000016 +34824b4,3c01001c +34824b8,415024 +34824bc,340c0000 +34824c0,3c0b0004 +34824c4,14b5824 +34824c8,11600002 +34824d0,258c0001 +34824d4,3c0b0008 +34824d8,14b5824 +34824dc,11600002 +34824e4,258c0001 +34824e8,3c0b0010 +34824ec,14b5824 +34824f0,11600002 +34824f8,258c0001 +34824fc,10000002 +3482504,860c00d0 +3482508,34010000 +348250c,3c0b8040 +3482510,856b0cd2 +3482514,18b602a +3482518,15800002 +348251c,34030000 +3482520,34030001 +3482524,3e00008 +348252c,27bdffe4 +3482530,afb10014 +3482534,afbf0018 +3482538,3c038012 +348253c,2463a5d0 +3482540,860f001c +3482544,31f800ff +3482548,340100ff +348254c,17010004 +3482550,27110400 +3482554,90781397 +3482558,3318001f +348255c,27110430 +3482560,31e18000 +3482564,14200015 +348256c,3c088040 +3482570,8d080cc8 +3482574,1100000b +3482578,34010001 +348257c,11010003 +3482584,1000000d +348258c,806100a5 +3482590,30210020 +3482594,10200008 +348259c,10000007 +34825a4,c01e6d1 +34825ac,34010008 +34825b0,10410002 +34825b8,34112053 +34825bc,a611010e +34825c0,8fbf0018 +34825c4,8fb10014 +34825c8,3e00008 +34825cc,27bd001c +34825d0,9059008a +34825d4,340900ff +34825d8,11390007 +34825e0,2b290031 +34825e4,15200005 +34825e8,34190000 +34825ec,34190001 +34825f0,10000002 +34825f8,34190000 +34825fc,3e00008 +3482604,27bdfff0 +3482608,afa80000 +348260c,e7a20004 +3482610,e7a40008 +3482614,3c088040 +3482618,25080cd4 +348261c,91080000 +3482620,1100000f +3482624,340d0200 +3482628,3c08801e +348262c,2508aa30 +3482630,c5020028 +3482634,3c08c496 +3482638,44882000 +3482640,4604103c +3482648,45010004 +3482650,340d0200 +3482654,10000002 +348265c,340d00c0 +3482660,c7a40008 +3482664,c7a20004 +3482668,8fa80000 +348266c,3e00008 +3482670,27bd0010 +3482674,8e2a1d44 +3482678,314a0100 +348267c,1540000a +3482684,8e2a1d48 +3482688,314a0100 +348268c,15400007 +3482694,8e211d48 +3482698,342a0100 +348269c,ae2a1d48 +34826a0,10000003 +34826a4,5024 +34826a8,240c0000 +34826ac,340a0001 +34826b0,3e00008 +34826b8,27bdfff0 +34826bc,afbf0000 +34826c0,c10105e +34826c8,8ece1c44 +34826cc,3c18db06 +34826d0,8fbf0000 +34826d4,3e00008 +34826d8,27bd0010 +34826e0,27bdfff0 +34826e4,afbf0004 +34826e8,afa40008 +34826ec,afa1000c +34826f0,c100f54 +34826f4,2002021 +34826f8,8fbf0004 +34826fc,8fa40008 +3482700,8fa1000c +3482704,3e00008 +3482708,27bd0010 +348270c,27bdffe0 +3482710,afbf0004 +3482714,afa10008 +3482718,afa2000c +348271c,afa30010 +3482720,afac0014 +3482724,c100f7b +3482728,3002021 +348272c,40c821 +3482730,8fbf0004 +3482734,8fa10008 +3482738,8fa2000c +348273c,8fa30010 +3482740,8fac0014 +3482744,3e00008 +3482748,27bd0020 +348274c,3f800000 +3482750,34080004 +3482754,3c09801d +3482758,252984a0 +348275c,8d291c44 +3482760,11200016 +3482768,3c018040 +348276c,c436274c +3482774,46166302 +3482778,9127014f +348277c,1507000f +3482780,448f2000 +3482784,3c07803a +3482788,24e78bc0 +348278c,8d280664 +3482790,1507000a +3482798,3c088040 +348279c,25080ce0 +34827a0,91080000 +34827a4,11000005 +34827ac,3c083fc0 +34827b0,4488b000 +34827b8,46166302 +34827c0,44056000 +34827c4,3e00008 +34827cc,3c188040 +34827d0,97180848 +34827d4,a5d80794 +34827d8,3c188040 +34827dc,9718084a +34827e0,a5d80796 +34827e4,3c188040 +34827e8,9718084c +34827ec,a5d80798 +34827f0,ec021 +34827f4,3e00008 +34827fc,27bdffe8 +3482800,afbf0004 +3482804,afb00008 +3482808,808021 +348280c,3c048040 +3482810,9484086c +3482814,c100a19 +348281c,ae02022c +3482820,3c048040 +3482824,9484086e +3482828,c100a19 +3482830,ae020230 +3482834,3c048040 +3482838,94840870 +348283c,c100a19 +3482844,ae020234 +3482848,c100a19 +348284c,340400ff +3482850,ae020238 +3482854,8fbf0004 +3482858,8fb00008 +348285c,3e00008 +3482860,27bd0018 +3482864,28810020 +3482868,14200005 +348286c,288100e0 +3482870,10200003 +3482878,10000002 +348287c,861023 +3482880,851023 +3482884,3e00008 +3482888,304200ff +3482890,2b010192 +3482894,10200004 +348289c,3c088010 +34828a0,3e00008 +34828a4,25088ff8 +34828a8,3c088040 +34828ac,25080c9c +34828b0,3e00008 +34828b4,2718fe6d +34828b8,8e1821 +34828bc,28c10192 +34828c0,10200004 +34828c8,3c198010 +34828cc,3e00008 +34828d0,27398ff8 +34828d4,3c198040 +34828d8,27390c9c +34828dc,3e00008 +34828e0,24c6fe6d +34828e4,86190000 +34828e8,8e050004 +34828ec,26040008 +34828f0,194023 +34828f4,29010192 +34828f8,10200004 +3482900,3c138010 +3482904,3e00008 +3482908,26738ff8 +348290c,3c138040 +3482910,26730c9c +3482914,3e00008 +3482918,2508fe6d +348291c,8e040010 +3482920,28610192 +3482924,10200004 +348292c,3c138010 +3482930,8100a51 +3482934,26738ff8 +3482938,3c138040 +348293c,26730c9c +3482940,2463fe6d +3482944,378c0 +3482948,26f1021 +348294c,3e00008 +3482950,8c450000 +3482954,8fa40020 +3482958,3c088040 +348295c,81080cd7 +3482960,24060050 +3482964,1100000b +348296c,84860014 +3482970,50c00008 +3482974,24060050 +3482978,80a81d44 +348297c,c85824 +3482980,55600004 +3482984,24060050 +3482988,1064025 +348298c,a0a81d44 +3482990,24c60014 +3482994,3e00008 +348299c,27bdfff0 +34829a0,afbf0004 +34829a4,afa80008 +34829a8,afa9000c +34829ac,3c088040 +34829b0,81080cd7 +34829b4,11000009 +34829bc,86080014 +34829c0,11000006 +34829c8,82291d44 +34829cc,1094024 +34829d0,24020001 +34829d4,11000003 +34829dc,c01c6a5 +34829e4,8fbf0004 +34829e8,8fa80008 +34829ec,8fa9000c +34829f0,27bd0010 +34829f4,3e00008 +34829fc,8fb00034 +3482a00,848800b4 +3482a04,11000002 +3482a0c,a48000b0 +3482a10,3e00008 +3482a18,1b9fcd5 +3482a1c,fb251ad2 +3482a20,f2dc +3482a24,8022 +3482a28,23bdffec +3482a2c,afbf0010 +3482a30,9608001c +3482a34,31088000 +3482a38,1100000f +3482a40,3c038012 +3482a44,2463a5d0 +3482a48,946d0edc +3482a4c,31ad0400 +3482a50,11a0000b +3482a58,8c6e0004 +3482a5c,15c00008 +3482a64,948d1d2a +3482a68,35ae0001 +3482a6c,a48e1d2a +3482a70,10000003 +3482a78,c037385 +3482a80,8fbf0010 +3482a84,23bd0014 +3482a88,3e00008 +3482a90,8c6e0004 +3482a94,3e00008 +3482a9c,8488001c +3482aa0,34010002 +3482aa4,15010015 +3482aac,3c028012 +3482ab0,2442a5d0 +3482ab4,8c4b0004 +3482ab8,15600012 +3482ac0,3c098040 +3482ac4,25292b0c +3482ac8,ac890154 +3482acc,27bdffe0 +3482ad0,afbf0010 +3482ad4,afa50014 +3482ad8,8fa60014 +3482adc,3c058040 +3482ae0,24a52a18 +3482ae4,c009571 +3482ae8,24c41c24 +3482aec,8fbf0010 +3482af0,27bd0020 +3482af4,10000003 +3482afc,afa40000 +3482b00,afa50004 +3482b04,3e00008 +3482b0c,27bdffd8 +3482b10,afb00020 +3482b14,afbf0024 +3482b18,afa5002c +3482b1c,808025 +3482b20,c600015c +3482b24,3c01c4a4 +3482b28,24212000 +3482b2c,44811000 +3482b30,3c028012 +3482b34,2442a5d0 +3482b38,944b0edc +3482b3c,316c0400 +3482b40,944b0ee0 +3482b44,11800031 +3482b4c,94ad1d2a +3482b50,31ae0001 +3482b54,11c00006 +3482b5c,31adfffe +3482b60,a4ad1d2a +3482b64,34010200 +3482b68,1615826 +3482b6c,a44b0ee0 +3482b70,316c0200 +3482b74,1180000b +3482b7c,34010000 +3482b80,44812000 +3482b84,3c064080 +3482b88,44863000 +3482b90,46060200 +3482b94,4604403c +3482b9c,10000009 +3482ba4,3c01c42a +3482ba8,44812000 +3482bac,3c06c080 +3482bb0,44863000 +3482bb8,46060200 +3482bbc,4608203c +3482bc4,45000005 +3482bcc,46004106 +3482bd0,c008c42 +3482bd4,3405205e +3482bd8,2002025 +3482bdc,e604015c +3482be0,46022100 +3482be4,e6040028 +3482be8,4600240d +3482bec,44098000 +3482bf0,8fa2002c +3482bf4,8c5807c0 +3482bf8,8f190028 +3482bfc,240ffb57 +3482c00,a72f0012 +3482c04,a7290022 +3482c08,a7290032 +3482c0c,8fbf0024 +3482c10,8fb00020 +3482c14,27bd0028 +3482c18,3e00008 +3482c20,ac20753c +3482c24,3c018040 +3482c28,90210cdc +3482c2c,10200008 +3482c30,3c01801d +3482c34,242184a0 +3482c38,94211d2c +3482c3c,302100c0 +3482c40,14200003 +3482c48,801ce4c +3482c50,801ce45 +3482c58,3c088012 +3482c5c,2508a5d0 +3482c60,8d0a0004 +3482c64,11400006 +3482c68,8d090000 +3482c6c,3401003b +3482c70,15210008 +3482c78,3c0bc47a +3482c7c,ac8b0028 +3482c80,3401016d +3482c84,15210003 +3482c8c,3c0bc47a +3482c90,ac8b0028 +3482c94,3e00008 +3482c98,340e0001 +3482ca0,3c0f8040 +3482ca4,25ef2c9c +3482ca8,81ef0000 +3482cac,3c188040 +3482cb0,27182c9d +3482cb4,83180000 +3482cb8,1f87820 +3482cbc,5e00007 +3482cc0,34010003 +3482cc4,1e1082a +3482cc8,14200002 +3482cd0,340f0008 +3482cd4,10000003 +3482cd8,1f08004 +3482cdc,f7822 +3482ce0,1f08007 +3482ce4,90af003d +3482ce8,11e00004 +3482cf0,108043 +3482cf4,108400 +3482cf8,108403 +3482cfc,3e00008 +3482d08,4f1021 +3482d0c,3c098040 +3482d10,81292d04 +3482d14,11200008 +3482d18,8042a65c +3482d1c,3c0a801d +3482d20,254a84a0 +3482d24,8d491d44 +3482d28,31210002 +3482d2c,14200002 +3482d30,3402000a +3482d34,34020000 +3482d38,3e00008 +3482d40,594021 +3482d44,3c0a8040 +3482d48,814a2d04 +3482d4c,11400002 +3482d50,8109008c +3482d54,34090000 +3482d58,3e00008 +3482d60,1ee7821 +3482d64,3c0a8040 +3482d68,814a2d04 +3482d6c,11400002 +3482d70,81efa65c +3482d74,340f0000 +3482d78,3e00008 +3482d80,3c098040 +3482d84,81292d04 +3482d88,11200005 +3482d8c,3c0a801d +3482d90,254a84a0 +3482d94,8d491d44 +3482d98,35290002 +3482d9c,ad491d44 +3482da0,3e00008 +3482da4,afa50024 +3482e6c,ff00 +3482e70,3c0a8040 +3482e74,254a2e6e +3482e78,914b0000 +3482e7c,340c00ff +3482e80,a14c0000 +3482e84,34087fff +3482e88,15c80006 +3482e8c,3c098040 +3482e90,25292e2c +3482e94,116c000c +3482e98,b5840 +3482e9c,12b4821 +3482ea0,952e0000 +3482ea4,27bdfff0 +3482ea8,afbf0004 +3482eac,afa40008 +3482eb0,c100bc6 +3482eb4,1c02021 +3482eb8,407021 +3482ebc,8fbf0004 +3482ec0,8fa40008 +3482ec4,27bd0010 +3482ec8,3e00008 +3482ecc,a42e1e1a +3482ed0,9608001c +3482ed4,84303 +3482ed8,3108000f +3482edc,29090002 +3482ee0,1520000b +3482ee8,960d0018 +3482eec,27bdfff0 +3482ef0,afbf0004 +3482ef4,afa40008 +3482ef8,c100bc6 +3482efc,1a02021 +3482f00,406821 +3482f04,8fbf0004 +3482f08,8fa40008 +3482f0c,27bd0010 +3482f10,3e00008 +3482f14,270821 +3482f18,34087ff9 +3482f1c,884022 +3482f20,501000f +3482f24,34081000 +3482f28,884022 +3482f2c,500000c +3482f30,3c098012 +3482f34,2529a5d0 +3482f38,3c0a8040 +3482f3c,254a2da8 +3482f40,3c0b8040 +3482f44,256b2e6e +3482f48,a1680000 +3482f4c,84080 +3482f50,1485021 +3482f54,95440000 +3482f58,91480002 +3482f5c,a1281397 +3482f60,3e00008 +3482f64,801021 +3482f68,8c6d0004 +3482f6c,3c0e8040 +3482f70,81ce0cde +3482f74,1ae7825 +3482f78,11e0000a +3482f80,11c00006 +3482f88,946e0ed4 +3482f8c,31ce0010 +3482f90,1cd7025 +3482f94,11c00003 +3482f9c,3e00008 +3482fa0,340f0001 +3482fa4,3e00008 +3482fa8,340f0000 +3482fac,1000 +3482fb0,4800 +3482fb8,7000 +3482fbc,4800 +3482fc8,8040ef10 +3482fcc,42890 +3482fd0,34191000 +3482fd4,340a4800 +3482fd8,340d0000 +3482fdc,340c7000 +3482fe0,340e4800 +3482fe4,3e00008 +3482fe8,34180000 +3482ff0,3c088012 +3482ff4,2508a5d0 +3482ff8,95090eda +3482ffc,31290008 +3483000,15200008 +3483004,8d090004 +3483008,15200004 +348300c,3c098040 +3483010,81292fec +3483014,15200003 +348301c,3e00008 +3483020,34090000 +3483024,3e00008 +3483028,34090001 +348302c,3c08801d +3483030,25082578 +3483034,3409006c +3483038,8d0a6300 +348303c,112a0009 +3483040,340a0001 +3483044,340b0036 +3483048,ad0a6300 +348304c,a10b6304 +3483050,240cffff +3483054,810e63e7 +3483058,15cc0002 +348305c,340d0002 +3483060,a10d63e7 +3483064,3e00008 +3483068,24060022 +3483074,afb0003c +3483078,27bdffe0 +348307c,afbf0014 +3483080,3c098040 +3483084,2529306c +3483088,812a0000 +348308c,1540000a +3483094,8e4b0028 +3483098,3c0c4370 +348309c,16c082a +34830a0,14200005 +34830a4,340d0001 +34830a8,a12d0000 +34830ac,3404001b +34830b0,c032a9c +34830b8,8fbf0014 +34830bc,3e00008 +34830c0,27bd0020 +34830c4,8e721c44 +34830c8,240e0003 +34830cc,a22e05b0 +34830d0,926f07af +34830d4,4406b000 +34830d8,4407a000 +34830dc,3e00008 +34830e4,90580000 +34830e8,27bdffd0 +34830ec,afbf0014 +34830f0,afa40018 +34830f4,afa5001c +34830f8,afa60020 +34830fc,afa70024 +3483100,3c048040 +3483104,8084306c +3483108,1080001b +3483110,3c048040 +3483114,8c843070 +3483118,2885001e +348311c,14a00016 +3483124,28850050 +3483128,10a0000c +3483130,3c043d4d +3483134,2484cccd +3483138,ae4404d0 +348313c,2402025 +3483140,248404c8 +3483144,3c05437f +3483148,3c063f80 +348314c,3c074120 +3483150,c0190a0 +3483158,10000007 +348315c,2402025 +3483160,248404c8 +3483164,34050000 +3483168,3c063f80 +348316c,3c074120 +3483170,c0190a0 +3483178,8fbf0014 +348317c,8fa40018 +3483180,8fa5001c +3483184,8fa60020 +3483188,8fa70024 +348318c,3e00008 +3483190,27bd0030 +3483194,860800b6 +3483198,25084000 +348319c,a60800b6 +34831a0,34080001 +34831a4,a20805e8 +34831a8,a2000554 +34831ac,8e090004 +34831b0,240afffe +34831b4,1495824 +34831b8,ae0b0004 +34831bc,3c088040 +34831c0,25083204 +34831c4,3e00008 +34831c8,ae08013c +34831cc,860800b6 +34831d0,2508c000 +34831d4,a60800b6 +34831d8,34080001 +34831dc,a20805e8 +34831e0,a2000554 +34831e4,8e090004 +34831e8,240afffe +34831ec,1495824 +34831f0,ae0b0004 +34831f4,3c088040 +34831f8,25083204 +34831fc,3e00008 +3483200,ae08013c +3483204,27bdffd0 +3483208,afbf0014 +348320c,afa40018 +3483210,afa5001c +3483214,34080001 +3483218,a0880554 +348321c,8488001c +3483220,11000006 +3483228,3c048040 +348322c,8c843070 +3483230,24850001 +3483234,3c018040 +3483238,ac253070 +348323c,3c048040 +3483240,8c843070 +3483244,34050003 +3483248,14850009 +3483250,8fa40018 +3483254,8488001c +3483258,34090001 +348325c,11090002 +3483260,240539b0 +3483264,240539b1 +3483268,c008bf4 +3483270,28850028 +3483274,14a0001a +348327c,8fa40018 +3483280,24840028 +3483284,3c0543c8 +3483288,3c063f80 +348328c,3c0740c0 +3483290,c0190a0 +3483298,8fa40018 +348329c,24840558 +34832a0,c023270 +34832a8,8fa40018 +34832ac,c008bf4 +34832b0,2405311f +34832b4,3c048040 +34832b8,8c843070 +34832bc,34080061 +34832c0,14880007 +34832c8,8fa40018 +34832cc,8fa5001c +34832d0,8c8b0138 +34832d4,8d6b0010 +34832d8,256913ec +34832dc,ac89013c +34832e0,8fbf0014 +34832e4,3e00008 +34832e8,27bd0030 +34832ec,3c01c416 +34832f0,44816000 +34832f4,3e00008 +34832f8,3025 +34832fc,3c014416 +3483300,44816000 +3483304,3e00008 +3483308,3025 +348330c,afa40018 +3483310,3c08801e +3483314,2508aa30 +3483318,3e00008 +348331c,ad000678 +3483320,27bdffe8 +3483324,afaa0004 +3483328,846f4a2a +348332c,340a0002 +3483330,15ea0002 +3483334,340a0001 +3483338,a46a4a2a +348333c,846f4a2a +3483340,8faa0004 +3483344,3e00008 +3483348,27bd0018 +348334c,27bdffe8 +3483350,afaa0004 +3483354,846e4a2a +3483358,340a0002 +348335c,15ca0002 +3483360,340a0003 +3483364,a46a4a2a +3483368,846e4a2a +348336c,8faa0004 +3483370,3e00008 +3483374,27bd0018 +3483378,27bdffe8 +348337c,afaa0004 +3483380,85034a2a +3483384,340a0002 +3483388,146a0002 +348338c,340a0001 +3483390,a50a4a2a +3483394,85034a2a +3483398,8faa0004 +348339c,3e00008 +34833a0,27bd0018 +34833a4,27bdffe8 +34833a8,afaa0004 +34833ac,85034a2a +34833b0,340a0002 +34833b4,146a0002 +34833b8,340a0003 +34833bc,a50a4a2a +34833c0,85034a2a +34833c4,8faa0004 +34833c8,3e00008 +34833cc,27bd0018 +34833d0,27bdffe8 +34833d4,afaa0004 +34833d8,85034a2a +34833dc,340a0002 +34833e0,146a0002 +34833e4,340a0001 +34833e8,a50a4a2a +34833ec,85034a2a +34833f0,8faa0004 +34833f4,3e00008 +34833f8,27bd0018 +34833fc,27bdffe8 +3483400,afaa0004 +3483404,85034a2a +3483408,340a0002 +348340c,146a0002 +3483410,340a0003 +3483414,a50a4a2a +3483418,85034a2a +348341c,8faa0004 +3483420,3e00008 +3483424,27bd0018 +3483428,27bdffe8 +348342c,afaa0004 +3483430,a42bca2a +3483434,340a0002 +3483438,156a0002 +348343c,340a0003 +3483440,a50a4a2a +3483444,85034a2a +3483448,8faa0004 +348344c,3e00008 +3483450,27bd0018 +3483454,27bdffe8 +3483458,afaa0004 +348345c,85034a2a +3483460,340a0002 +3483464,146a0002 +3483468,340a0001 +348346c,a50a4a2a +3483470,85034a2a +3483474,8faa0004 +3483478,3e00008 +348347c,27bd0018 +3483480,27bdffe8 +3483484,afaa0004 +3483488,85034a2a +348348c,340a0002 +3483490,146a0002 +3483494,340a0003 +3483498,a50a4a2a +348349c,85034a2a +34834a0,8faa0004 +34834a4,3e00008 +34834a8,27bd0018 +34834ac,3c08801e +34834b0,25084ee8 +34834b4,3409f000 +34834b8,a5090000 +34834bc,3e00008 +34834c0,84cb4a2e +34834c4,24a56f04 +34834c8,8c880144 +34834cc,11050007 +34834d0,3c09801e +34834d4,2529aa30 +34834d8,3c0a446a +34834dc,254ac000 +34834e0,3c0bc324 +34834e4,ad2a0024 +34834e8,ad2b002c +34834ec,3e00008 +34834f4,27bdffd8 +34834f8,afbf0024 +34834fc,afa40028 +3483500,afa5002c +3483504,afa60030 +3483508,c022865 +348350c,8fa40030 +3483510,44822000 +3483514,44800000 +3483518,240e0002 +348351c,468021a0 +3483520,afae0018 +3483524,8fa40028 +3483528,8fa5002c +348352c,8fa60030 +3483530,3c073f80 +3483534,3c080400 +3483538,250832b0 +348353c,14c80002 +3483544,3c074040 +3483548,e7a60014 +348354c,e7a00010 +3483550,c023000 +3483554,e7a0001c +3483558,8fbf0024 +348355c,8fbf0024 +3483560,3e00008 +3483564,27bd0028 +3483568,3c0a8040 +348356c,814a0cd8 +3483570,11400003 +3483574,8ccb0138 +3483578,8d6b0010 +348357c,25690adc +3483580,3e00008 +3483584,acc90180 +3483588,27bdffe8 +348358c,afbf0014 +3483590,3c0a8040 +3483594,814a0cd8 +3483598,15400003 +34835a0,c037500 +34835a8,8fbf0014 +34835ac,3e00008 +34835b0,27bd0018 +34835b4,3c010080 +34835b8,3c180001 +34835bc,3e00008 +34835c0,8c4e0670 +34835c4,3c0a8040 +34835c8,814a0cd8 +34835cc,11400002 +34835d4,34180003 +34835d8,3c078012 +34835dc,24e7a5d0 +34835e0,3e00008 +34835e4,24010003 +34835e8,3c0a8040 +34835ec,814a0cd8 +34835f0,11400008 +34835f8,c100412 +3483600,3c08801e +3483604,25088966 +3483608,34090004 +348360c,a5090000 +3483614,8fbf0014 +3483618,3e00008 +348361c,27bd0018 +3483620,27bdffe0 +3483624,afbf0014 +3483628,afa10018 +348362c,afa4001c +3483630,3c0a8040 +3483634,814a0cd8 +3483638,1540000b +3483640,3c04801d +3483644,248484a0 +3483648,3c058040 +348364c,90a50cdb +3483650,34060000 +3483654,c037385 +348365c,34044802 +3483660,c0191bc +3483668,8fa4001c +348366c,8fa10018 +3483670,8fbf0014 +3483674,3e00008 +3483678,27bd0020 +3483680,27bdffe0 +3483684,afbf0014 +3483688,afa40018 +348368c,3c0d8040 +3483690,81ad367c +3483694,15a0000c +348369c,3c08801e +34836a0,2508aa30 +34836a4,8d090670 +34836a8,340a4000 +34836ac,12a5824 +34836b0,1160000d +34836b8,34080001 +34836bc,3c018040 +34836c0,a028367c +34836c4,10000023 +34836c8,3c08801e +34836cc,2508aa30 +34836d0,8d090670 +34836d4,340a4000 +34836d8,12a5824 +34836dc,1160000c +34836e4,1000001b +34836e8,24a420d8 +34836ec,c037519 +34836f4,24010002 +34836f8,14410016 +3483700,3c08801e +3483704,25088966 +3483708,34090004 +348370c,a5090000 +3483710,3c0b8012 +3483714,256ba5d0 +3483718,816c0ede +348371c,358c0001 +3483720,a16c0ede +3483724,3c09801e +3483728,2529a2ba +348372c,340802ae +3483730,a5280000 +3483734,3408002a +3483738,3c09801e +348373c,2529a2fe +3483740,a1280000 +3483744,34080014 +3483748,3c09801e +348374c,2529a2b5 +3483750,a1280000 +3483754,8fbf0014 +3483758,3e00008 +348375c,27bd0020 +3483760,27bdffd0 +3483764,afbf0014 +3483768,afa80018 +348376c,afa9001c +3483770,afaa0020 +3483774,afab0024 +3483778,afac0028 +348377c,afad002c +3483780,3c088012 +3483784,2508a5d0 +3483788,85090f20 +348378c,31290040 +3483790,1120000e +3483794,3c08801e +3483798,2508aa30 +348379c,8d09039c +34837a0,1120000a +34837a4,340a00a1 +34837a8,852b0000 +34837ac,154b0007 +34837b0,240cf7ff +34837b4,8d0d066c +34837b8,18d6824 +34837bc,ad0d066c +34837c0,ad00039c +34837c4,ad00011c +34837c8,ad200118 +34837cc,afad002c +34837d0,afac0028 +34837d4,afab0024 +34837d8,afaa0020 +34837dc,afa9001c +34837e0,afa80018 +34837e4,afbf0014 +34837e8,860e001c +34837ec,3e00008 +34837f0,27bd0030 +34837f4,27bdffd0 +34837f8,afbf0014 +34837fc,afa80018 +3483800,afa9001c +3483804,afaa0020 +3483808,84a800a4 +348380c,34090002 +3483810,1509000c +3483814,340a0006 +3483818,80880003 +348381c,150a0009 +3483824,3c088012 +3483828,2508a5d0 +348382c,85090f20 +3483830,31290040 +3483834,11200003 +348383c,c0083ad +3483844,8faa0020 +3483848,8fa9001c +348384c,8fa80018 +3483850,8fbf0014 +3483854,8602001c +3483858,3e00008 +348385c,27bd0030 +3483860,27bdffd0 +3483864,afbf001c +3483868,afa40020 +348386c,afa50024 +3483870,e7a00028 +3483874,4602003c +348387c,45010005 +3483884,c100ebc +348388c,10000003 +3483894,c100ebe +348389c,34060014 +34838a0,3407000a +34838a4,44801000 +34838a8,c7a00028 +34838ac,8fa50024 +34838b0,8fa40020 +34838b4,8fbf001c +34838b8,4602003c +34838bc,27bd0030 +34838c0,3e00008 +34838c8,27bdffd0 +34838cc,afbf001c +34838d0,afa40020 +34838d4,afa50024 +34838d8,e7a40028 +34838dc,e7a6002c +34838e0,4606203c +34838e8,45000003 +34838f0,c100ec9 +34838f8,34060014 +34838fc,3407000a +3483900,44801000 +3483904,c7a6002c +3483908,c7a40028 +348390c,8fa50024 +3483910,8fa40020 +3483914,8fbf001c +3483918,4606203c +348391c,27bd0030 +3483920,3e00008 +3483928,c100f2c +3483930,8fbf001c +3483934,27bd0020 +3483938,3e00008 +3483944,27bdffe8 +3483948,afbf0014 +348394c,c008ab4 +3483954,8fbf0014 +3483958,27bd0018 +348395c,8fa40018 +3483960,8c8a0138 +3483964,8d4a0010 +3483968,25431618 +348396c,3c088040 +3483970,81083940 +3483974,1100000a +3483978,3c098012 +348397c,2529a5d0 +3483980,95281406 +3483984,290105dc +3483988,14200005 +348398c,9488029c +3483990,31080002 +3483994,15000002 +348399c,254314d0 +34839a0,3e00008 +34839a8,3c188012 +34839ac,2718a5d0 +34839b0,8f180004 +34839b4,17000003 +34839bc,3c0a8041 +34839c0,254ab0c8 +34839c4,24780008 +34839c8,3e00008 +34839cc,adf802c0 +34839d0,3c0f8012 +34839d4,25efa5d0 +34839d8,8def0004 +34839dc,15e00003 +34839e4,3c0e8041 +34839e8,25ceb0c8 +34839ec,ac4e0004 +34839f0,3e00008 +34839f4,820f013f +34839fc,3c088040 +3483a00,810839f8 +3483a04,11000007 +3483a08,3c09801d +3483a0c,252984a0 +3483a10,8d281d44 +3483a14,31080002 +3483a18,11000002 +3483a20,34069100 +3483a24,3e00008 +3483a28,afa60020 +3483a2c,3c088040 +3483a30,810839f8 +3483a34,11000005 +3483a38,3c09801d +3483a3c,252984a0 +3483a40,8d281d44 +3483a44,35080002 +3483a48,ad281d44 +3483a4c,3e00008 +3483a50,34e74000 +3483a58,3c038012 +3483a5c,2463a5d0 +3483a60,8c6e0004 +3483a64,15c0000c +3483a68,24020005 +3483a6c,24020011 +3483a70,3c088040 +3483a74,81083a54 +3483a78,11000007 +3483a7c,3c09801d +3483a80,252984a0 +3483a84,8d281d44 +3483a88,31080002 +3483a8c,11000002 +3483a90,34020001 +3483a94,34020003 +3483a98,3e00008 +3483a9c,3c048010 +3483aa0,3c088040 +3483aa4,81083a54 +3483aa8,11000005 +3483aac,3c09801d +3483ab0,252984a0 +3483ab4,8d281d44 +3483ab8,35080002 +3483abc,ad281d44 +3483ac0,3e00008 +3483ac4,34e78000 +3483ac8,27bdffe8 +3483acc,afa20010 +3483ad0,afbf0014 +3483ad4,c10210d +3483ad8,46000306 +3483adc,406821 +3483ae0,8fa20010 +3483ae4,8fbf0014 +3483ae8,3e00008 +3483aec,27bd0018 +3483af0,3e00008 +3483af8,3c028041 +3483afc,8c439ec8 +3483b00,3c028041 +3483b04,24429c3e +3483b08,14620004 +3483b0c,3c038041 +3483b10,3c028041 +3483b14,24429c40 +3483b18,ac629ec8 +3483b1c,3e00008 +3483b24,3c028041 +3483b28,8c439ec8 +3483b2c,3c028041 +3483b30,24429c24 +3483b34,10620003 +3483b38,3c028041 +3483b3c,10000003 +3483b40,24429c44 +3483b44,3c028041 +3483b48,24429c26 +3483b4c,3c038041 +3483b50,3e00008 +3483b54,ac629ec8 +3483b58,27bdffc8 +3483b5c,afbf0034 +3483b60,afb40030 +3483b64,afb3002c +3483b68,afb20028 +3483b6c,afb10024 +3483b70,afb00020 +3483b74,809025 +3483b78,3c02801c +3483b7c,344284a0 +3483b80,3c030001 +3483b84,431021 +3483b88,90420745 +3483b8c,240300aa +3483b90,14430002 +3483b94,a08825 +3483b98,240200ff +3483b9c,3c03801c +3483ba0,346384a0 +3483ba4,8c700000 +3483ba8,8e0302b0 +3483bac,24640008 +3483bb0,ae0402b0 +3483bb4,3c04de00 +3483bb8,ac640000 +3483bbc,3c048041 +3483bc0,2484a0a0 +3483bc4,ac640004 +3483bc8,8e0302b0 +3483bcc,24640008 +3483bd0,ae0402b0 +3483bd4,3c04e700 +3483bd8,ac640000 +3483bdc,ac600004 +3483be0,8e0302b0 +3483be4,24640008 +3483be8,ae0402b0 +3483bec,3c04fc11 +3483bf0,34849623 +3483bf4,ac640000 +3483bf8,3c04ff2f +3483bfc,3484ffff +3483c00,ac640004 +3483c04,8e0402b0 +3483c08,24830008 +3483c0c,ae0302b0 +3483c10,3c03fa00 +3483c14,ac830000 +3483c18,401825 +3483c1c,c2102b +3483c20,10400002 +3483c24,261302a8 +3483c28,c01825 +3483c2c,2402ff00 +3483c30,621825 +3483c34,ac830004 +3483c38,24070001 +3483c3c,24060009 +3483c40,3c148041 +3483c44,2685a060 +3483c48,c101b95 +3483c4c,2602025 +3483c50,24020010 +3483c54,afa20018 +3483c58,afa20014 +3483c5c,263100bd +3483c60,afb10010 +3483c64,2647001b +3483c68,3025 +3483c6c,2685a060 +3483c70,c101bfd +3483c74,2602025 +3483c78,8e0202b0 +3483c7c,24430008 +3483c80,ae0302b0 +3483c84,3c03e700 +3483c88,ac430000 +3483c8c,ac400004 +3483c90,8fbf0034 +3483c94,8fb40030 +3483c98,8fb3002c +3483c9c,8fb20028 +3483ca0,8fb10024 +3483ca4,8fb00020 +3483ca8,3e00008 +3483cac,27bd0038 +3483cb0,3c028041 +3483cb4,8c439ec8 +3483cb8,3c028041 +3483cbc,24429c24 +3483cc0,10620021 +3483cc8,27bdffe8 +3483ccc,afbf0014 +3483cd0,90660000 +3483cd4,90620001 +3483cd8,22600 +3483cdc,42603 +3483ce0,42183 +3483ce4,3042003f +3483ce8,21040 +3483cec,3c038041 +3483cf0,24639c24 +3483cf4,621021 +3483cf8,3c038041 +3483cfc,ac629ec8 +3483d00,3c02801c +3483d04,344284a0 +3483d08,944300a4 +3483d0c,28620011 +3483d10,10400008 +3483d14,2825 +3483d18,3c028011 +3483d1c,3442a5d0 +3483d20,431021 +3483d24,804500bc +3483d28,52fc3 +3483d2c,30a50011 +3483d30,24a5ffef +3483d34,c100ed6 +3483d3c,8fbf0014 +3483d40,3e00008 +3483d44,27bd0018 +3483d48,3e00008 +3483d50,27bdffd8 +3483d54,afbf0024 +3483d58,afb10020 +3483d5c,afb0001c +3483d60,3c028040 +3483d64,8c4226dc +3483d68,14400003 +3483d6c,808025 +3483d70,10000019 +3483d74,908201e9 +3483d78,9487001c +3483d7c,73943 +3483d80,30e7007f +3483d84,3c02801c +3483d88,344284a0 +3483d8c,904600a5 +3483d90,802825 +3483d94,c101998 +3483d98,27a40010 +3483d9c,97b10014 +3483da0,16200003 +3483da8,1000000b +3483dac,920201e9 +3483db0,c101e92 +3483db4,93a40017 +3483db8,54400004 +3483dbc,90420007 +3483dc0,c101e92 +3483dc4,2202025 +3483dc8,90420007 +3483dcc,30420001 +3483dd0,54400001 +3483dd4,24020005 +3483dd8,8fbf0024 +3483ddc,8fb10020 +3483de0,8fb0001c +3483de4,3e00008 +3483de8,27bd0028 +3483dec,27bdffd8 +3483df0,afbf0024 +3483df4,afb10020 +3483df8,afb0001c +3483dfc,3c028040 +3483e00,8c4226dc +3483e04,14400003 +3483e08,808025 +3483e0c,10000017 +3483e10,908201e9 +3483e14,9487001c +3483e18,73943 +3483e1c,30e7007f +3483e20,3c02801c +3483e24,344284a0 +3483e28,904600a5 +3483e2c,802825 +3483e30,c101998 +3483e34,27a40010 +3483e38,97b10014 +3483e3c,16200003 +3483e44,10000009 +3483e48,920201e9 +3483e4c,c101e92 +3483e50,93a40017 +3483e54,54400004 +3483e58,90420007 +3483e5c,c101e92 +3483e60,2202025 +3483e64,90420007 +3483e68,30420002 +3483e6c,8fbf0024 +3483e70,8fb10020 +3483e74,8fb0001c +3483e78,3e00008 +3483e7c,27bd0028 +3483e80,27bdffd8 +3483e84,afbf0024 +3483e88,afb10020 +3483e8c,afb0001c +3483e90,3c02801c +3483e94,344284a0 +3483e98,94500020 +3483e9c,3c02801d +3483ea0,3442aa30 +3483ea4,8c42066c +3483ea8,3c033000 +3483eac,24630483 +3483eb0,431024 +3483eb4,544000ac +3483eb8,8fbf0024 +3483ebc,3c02801c +3483ec0,344284a0 +3483ec4,8c430008 +3483ec8,3c02800f +3483ecc,8c4213ec +3483ed0,546200a5 +3483ed4,8fbf0024 +3483ed8,3c028011 +3483edc,3442a5d0 +3483ee0,8c43135c +3483ee4,24020001 +3483ee8,1062009e +3483eec,3c02800e +3483ef0,3442f1b0 +3483ef4,8c420000 +3483ef8,30420020 +3483efc,5440009a +3483f00,8fbf0024 +3483f04,3c028011 +3483f08,3442a5d0 +3483f0c,8c42009c +3483f10,3c036000 +3483f14,431024 +3483f18,10400007 +3483f1c,3c028011 +3483f20,3442a5d0 +3483f24,8c420004 +3483f28,50400010 +3483f2c,32020200 +3483f30,10000085 +3483f34,3c028011 +3483f38,3442a5d0 +3483f3c,8042007b +3483f40,24030007 +3483f44,10430003 +3483f48,24030008 +3483f4c,14430086 +3483f50,8fbf0024 +3483f54,3c028011 +3483f58,3442a5d0 +3483f5c,8c420004 +3483f60,54400053 +3483f64,32100400 +3483f68,32020200 +3483f6c,10400026 +3483f70,3211ffff +3483f74,3c028011 +3483f78,3442a5d0 +3483f7c,9442009c +3483f80,30422000 +3483f84,50400021 +3483f88,32310100 +3483f8c,3c028011 +3483f90,3442a5d0 +3483f94,94420070 +3483f98,3042f000 +3483f9c,38422000 +3483fa0,2102b +3483fa4,24420001 +3483fa8,3c048011 +3483fac,3484a5d0 +3483fb0,21300 +3483fb4,94830070 +3483fb8,30630fff +3483fbc,621025 +3483fc0,a4820070 +3483fc4,3c04801d +3483fc8,3485aa30 +3483fcc,3c028007 +3483fd0,34429764 +3483fd4,40f809 +3483fd8,248484a0 +3483fdc,3c058010 +3483fe0,24a243a8 +3483fe4,afa20014 +3483fe8,24a743a0 +3483fec,afa70010 +3483ff0,24060004 +3483ff4,24a54394 +3483ff8,3c02800c +3483ffc,3442806c +3484000,40f809 +3484004,24040835 +3484008,32310100 +348400c,52200028 +3484010,32100400 +3484014,3c028011 +3484018,3442a5d0 +348401c,9442009c +3484020,30424000 +3484024,50400022 +3484028,32100400 +348402c,3c028011 +3484030,3442a5d0 +3484034,94420070 +3484038,3042f000 +348403c,24033000 +3484040,50430002 +3484044,24040001 +3484048,24040003 +348404c,3c038011 +3484050,3463a5d0 +3484054,42300 +3484058,94620070 +348405c,30420fff +3484060,441025 +3484064,a4620070 +3484068,3c04801d +348406c,3485aa30 +3484070,3c028007 +3484074,34429764 +3484078,40f809 +348407c,248484a0 +3484080,3c058010 +3484084,24a243a8 +3484088,afa20014 +348408c,24a743a0 +3484090,afa70010 +3484094,24060004 +3484098,24a54394 +348409c,3c02800c +34840a0,3442806c +34840a4,40f809 +34840a8,24040835 +34840ac,32100400 +34840b0,1200002d +34840b4,8fbf0024 +34840b8,3c02801c +34840bc,344284a0 +34840c0,3c030001 +34840c4,431021 +34840c8,94420934 +34840cc,14400027 +34840d0,8fb10020 +34840d4,3c028011 +34840d8,3442a5d0 +34840dc,9046007b +34840e0,24c2fff9 +34840e4,304200ff +34840e8,2c420002 +34840ec,10400020 +34840f0,8fb0001c +34840f4,3c02801c +34840f8,344284a0 +34840fc,431021 +3484100,90420758 +3484104,1440001a +3484108,3c02801d +348410c,3442aa30 +3484110,8c42066c +3484114,3c0308a0 +3484118,24630800 +348411c,431024 +3484120,14400013 +3484124,24070002 +3484128,3c04801d +348412c,3485aa30 +3484130,3c028038 +3484134,3442c9a0 +3484138,40f809 +348413c,248484a0 +3484140,10000009 +3484144,8fbf0024 +3484148,3442a5d0 +348414c,8042007b +3484150,24030007 +3484154,1043ffd5 +3484158,24030008 +348415c,1043ffd4 +3484160,32100400 +3484164,8fbf0024 +3484168,8fb10020 +348416c,8fb0001c +3484170,3e00008 +3484174,27bd0028 +3484178,3c028011 +348417c,3442a5d0 +3484180,8c42009c +3484184,3c036000 +3484188,431024 +348418c,10400006 +3484190,3c028011 +3484194,3442a5d0 +3484198,8c420004 +348419c,1040000a +34841a0,3c028040 +34841a4,3c028011 +34841a8,3442a5d0 +34841ac,9042007b +34841b0,2442fff9 +34841b4,304200ff +34841b8,2c420002 +34841bc,10400123 +34841c4,3c028040 +34841c8,9042088a +34841cc,1040011f +34841d4,27bdffc8 +34841d8,afbf0034 +34841dc,afb30030 +34841e0,afb2002c +34841e4,afb10028 +34841e8,afb00024 +34841ec,3c02801c +34841f0,344284a0 +34841f4,8c500000 +34841f8,8e0302b0 +34841fc,24640008 +3484200,ae0402b0 +3484204,3c04de00 +3484208,ac640000 +348420c,3c048041 +3484210,2484a0a0 +3484214,ac640004 +3484218,8e0302b0 +348421c,24640008 +3484220,ae0402b0 +3484224,3c04e700 +3484228,ac640000 +348422c,ac600004 +3484230,8e0302b0 +3484234,24640008 +3484238,ae0402b0 +348423c,3c04fc11 +3484240,34849623 +3484244,ac640000 +3484248,3c04ff2f +348424c,3484ffff +3484250,ac640004 +3484254,3c030001 +3484258,431021 +348425c,94520744 +3484260,240200aa +3484264,124200e0 +3484268,24070001 +348426c,261102a8 +3484270,8e0202b0 +3484274,24430008 +3484278,ae0302b0 +348427c,3c03fa00 +3484280,ac430000 +3484284,2403ff00 +3484288,2431825 +348428c,ac430004 +3484290,3025 +3484294,3c138041 +3484298,2665a040 +348429c,c101b95 +34842a0,2202025 +34842a4,24020010 +34842a8,afa20018 +34842ac,afa20014 +34842b0,24020040 +34842b4,afa20010 +34842b8,2407010f +34842bc,3025 +34842c0,2665a040 +34842c4,c101bfd +34842c8,2202025 +34842cc,240200ff +34842d0,16420023 +34842d4,3c028011 +34842d8,3c02801d +34842dc,3442aa30 +34842e0,8c42066c +34842e4,3c033000 +34842e8,24630483 +34842ec,431024 +34842f0,10400009 +34842f4,3c02801c +34842f8,8e0202b0 +34842fc,24430008 +3484300,ae0302b0 +3484304,3c03fa00 +3484308,ac430000 +348430c,2403ff46 +3484310,10000012 +3484314,ac430004 +3484318,344284a0 +348431c,8c430008 +3484320,3c02800f +3484324,8c4213ec +3484328,5462fff4 +348432c,8e0202b0 +3484330,3c028011 +3484334,3442a5d0 +3484338,8c43135c +348433c,24020001 +3484340,1062ffed +3484344,3c02800e +3484348,3442f1b0 +348434c,8c420000 +3484350,30420020 +3484354,5440ffe9 +3484358,8e0202b0 +348435c,3c028011 +3484360,3442a5d0 +3484364,9442009c +3484368,30422000 +348436c,1040002a +3484370,3c028011 +3484374,3442a5d0 +3484378,8c420004 +348437c,14400054 +3484380,3c028011 +3484384,24070001 +3484388,24060045 +348438c,3c058041 +3484390,24a5a070 +3484394,c101b95 +3484398,2202025 +348439c,3c028011 +34843a0,3442a5d0 +34843a4,94420070 +34843a8,3042f000 +34843ac,24032000 +34843b0,5443000e +34843b4,2402000c +34843b8,24020010 +34843bc,afa20018 +34843c0,afa20014 +34843c4,24020040 +34843c8,afa20010 +34843cc,24070102 +34843d0,3025 +34843d4,3c058041 +34843d8,24a5a070 +34843dc,c101bfd +34843e0,2202025 +34843e4,1000000c +34843e8,3c028011 +34843ec,afa20018 +34843f0,afa20014 +34843f4,24020042 +34843f8,afa20010 +34843fc,24070104 +3484400,3025 +3484404,3c058041 +3484408,24a5a070 +348440c,c101bfd +3484410,2202025 +3484414,3c028011 +3484418,3442a5d0 +348441c,9442009c +3484420,30424000 +3484424,1040002a +3484428,3c028011 +348442c,3442a5d0 +3484430,8c420004 +3484434,14400026 +3484438,3c028011 +348443c,24070001 +3484440,24060046 +3484444,3c058041 +3484448,24a5a070 +348444c,c101b95 +3484450,2202025 +3484454,3c028011 +3484458,3442a5d0 +348445c,94420070 +3484460,3042f000 +3484464,24033000 +3484468,5443000e +348446c,2402000c +3484470,24020010 +3484474,afa20018 +3484478,afa20014 +348447c,24020040 +3484480,afa20010 +3484484,2407011b +3484488,3025 +348448c,3c058041 +3484490,24a5a070 +3484494,c101bfd +3484498,2202025 +348449c,1000000c +34844a0,3c028011 +34844a4,afa20018 +34844a8,afa20014 +34844ac,24020042 +34844b0,afa20010 +34844b4,2407011d +34844b8,3025 +34844bc,3c058041 +34844c0,24a5a070 +34844c4,c101bfd +34844c8,2202025 +34844cc,3c028011 +34844d0,3442a5d0 +34844d4,9042007b +34844d8,2442fff9 +34844dc,304200ff +34844e0,2c420002 +34844e4,50400034 +34844e8,8e0202b0 +34844ec,240200ff +34844f0,1642001f +34844f4,24070001 +34844f8,3c02801c +34844fc,344284a0 +3484500,3c030001 +3484504,431021 +3484508,94420934 +348450c,10400009 +3484510,3c02801c +3484514,8e0202b0 +3484518,24430008 +348451c,ae0302b0 +3484520,3c03fa00 +3484524,ac430000 +3484528,2403ff46 +348452c,1000000f +3484530,ac430004 +3484534,344284a0 +3484538,3c030001 +348453c,431021 +3484540,90420758 +3484544,5440fff4 +3484548,8e0202b0 +348454c,3c02801d +3484550,3442aa30 +3484554,8c42066c +3484558,3c0308a0 +348455c,24630800 +3484560,431024 +3484564,5440ffec +3484568,8e0202b0 +348456c,24070001 +3484570,3c028011 +3484574,3442a5d0 +3484578,8046007b +348457c,3c128041 +3484580,2645a070 +3484584,c101b95 +3484588,2202025 +348458c,2402000c +3484590,afa20018 +3484594,afa20014 +3484598,2402004d +348459c,afa20010 +34845a0,24070111 +34845a4,3025 +34845a8,2645a070 +34845ac,c101bfd +34845b0,2202025 +34845b4,8e0202b0 +34845b8,24430008 +34845bc,ae0302b0 +34845c0,3c03e700 +34845c4,ac430000 +34845c8,ac400004 +34845cc,8fbf0034 +34845d0,8fb30030 +34845d4,8fb2002c +34845d8,8fb10028 +34845dc,8fb00024 +34845e0,3e00008 +34845e4,27bd0038 +34845e8,261102a8 +34845ec,8e0202b0 +34845f0,24430008 +34845f4,ae0302b0 +34845f8,3c03fa00 +34845fc,ac430000 +3484600,2403ffff +3484604,ac430004 +3484608,3025 +348460c,3c128041 +3484610,2645a040 +3484614,c101b95 +3484618,2202025 +348461c,24020010 +3484620,afa20018 +3484624,afa20014 +3484628,24020040 +348462c,afa20010 +3484630,2407010f +3484634,3025 +3484638,2645a040 +348463c,c101bfd +3484640,2202025 +3484644,1000ff24 +3484648,241200ff +348464c,3e00008 +3484654,3c028041 +3484658,8c42b0ac +348465c,10400274 +3484660,3c02801c +3484664,27bdff90 +3484668,afbf006c +348466c,afbe0068 +3484670,afb70064 +3484674,afb60060 +3484678,afb5005c +348467c,afb40058 +3484680,afb30054 +3484684,afb20050 +3484688,afb1004c +348468c,afb00048 +3484690,344284a0 +3484694,3c030001 +3484698,431021 +348469c,94430934 +34846a0,24020006 +34846a4,14620256 +34846a8,808025 +34846ac,3c02801c +34846b0,344284a0 +34846b4,3c030001 +34846b8,431021 +34846bc,94420948 +34846c0,1440024f +34846c4,3c02801c +34846c8,344284a0 +34846cc,431021 +34846d0,94420944 +34846d4,1440024a +34846d8,3c02801c +34846dc,344284a0 +34846e0,84420014 +34846e4,4430247 +34846e8,8fbf006c +34846ec,8c820004 +34846f0,24430008 +34846f4,ac830008 +34846f8,3c03de00 +34846fc,ac430000 +3484700,3c038041 +3484704,2463a0a0 +3484708,ac430004 +348470c,3c028011 +3484710,3442a5d0 +3484714,94430f2e +3484718,3c028041 +348471c,8c42b0a8 +3484720,10400012 +3484724,3025 +3484728,3c028041 +348472c,8c42b144 +3484730,10400010 +3484734,24060001 +3484738,30620001 +348473c,54400006 +3484740,30630002 +3484744,3c028041 +3484748,8c42b144 +348474c,1040000c +3484750,3025 +3484754,30630002 +3484758,24020001 +348475c,1460000a +3484760,afa2003c +3484764,10000008 +3484768,afa0003c +348476c,10000006 +3484770,afa0003c +3484774,24020001 +3484778,10000003 +348477c,afa2003c +3484780,24020001 +3484784,afa2003c +3484788,3c028041 +348478c,8c55b150 +3484790,12a00007 +3484794,2a01825 +3484798,3c028041 +348479c,9442a054 +34847a0,21840 +34847a4,621821 +34847a8,31840 +34847ac,24630001 +34847b0,3c028041 +34847b4,9442a054 +34847b8,210c0 +34847bc,24420057 +34847c0,431021 +34847c4,24030140 +34847c8,621823 +34847cc,38fc2 +34847d0,2238821 +34847d4,118843 +34847d8,26230001 +34847dc,afa30038 +34847e0,8e030008 +34847e4,24640008 +34847e8,ae040008 +34847ec,3c04fcff +34847f0,3484ffff +34847f4,ac640000 +34847f8,3c04fffd +34847fc,3484f6fb +3484800,ac640004 +3484804,8e030008 +3484808,24640008 +348480c,ae040008 +3484810,3c04fa00 +3484814,ac640000 +3484818,240400d0 +348481c,ac640004 +3484820,511021 +3484824,21380 +3484828,3c0300ff +348482c,3463f000 +3484830,431024 +3484834,3c04e400 +3484838,2484039c +348483c,441025 +3484840,afa20020 +3484844,111380 +3484848,431024 +348484c,34420024 +3484850,afa20024 +3484854,3c02e100 +3484858,afa20028 +348485c,afa0002c +3484860,3c02f100 +3484864,afa20030 +3484868,3c020400 +348486c,24420400 +3484870,afa20034 +3484874,27a20020 +3484878,27a70038 +348487c,8e030008 +3484880,24640008 +3484884,ae040008 +3484888,8c450004 +348488c,8c440000 +3484890,ac650004 +3484894,24420008 +3484898,14e2fff8 +348489c,ac640000 +34848a0,8e020008 +34848a4,24430008 +34848a8,ae030008 +34848ac,3c03e700 +34848b0,ac430000 +34848b4,ac400004 +34848b8,8e020008 +34848bc,24430008 +34848c0,ae030008 +34848c4,3c03fc11 +34848c8,34639623 +34848cc,ac430000 +34848d0,3c03ff2f +34848d4,3463ffff +34848d8,10c0004c +34848dc,ac430004 +34848e0,3c058041 +34848e4,24a5a080 +34848e8,94a70008 +34848ec,3025 +34848f0,c101b95 +34848f4,2002025 +34848f8,3c028041 +34848fc,8c42b0b0 +3484900,18400042 +3484904,3c028041 +3484908,3c128041 +348490c,26529ef0 +3484910,2414000a +3484914,9825 +3484918,3c1e8041 +348491c,3c168041 +3484920,26d69ecc +3484924,24429edc +3484928,afa20040 +348492c,3c028041 +3484930,2442a080 +3484934,afa20044 +3484938,3c178041 +348493c,8fc2b148 +3484940,5040000b +3484944,92420000 +3484948,92430000 +348494c,3c028011 +3484950,3442a5d0 +3484954,431021 +3484958,904200a8 +348495c,21042 +3484960,30420001 +3484964,50400024 +3484968,26730001 +348496c,92420000 +3484970,561021 +3484974,80460000 +3484978,28c20003 +348497c,5440001e +3484980,26730001 +3484984,24c6fffd +3484988,61840 +348498c,661821 +3484990,8fa20040 +3484994,621821 +3484998,90620000 +348499c,21600 +34849a0,90640002 +34849a4,42200 +34849a8,441025 +34849ac,90630001 +34849b0,31c00 +34849b4,431025 +34849b8,344200ff +34849bc,8e030008 +34849c0,24640008 +34849c4,ae040008 +34849c8,3c04fa00 +34849cc,ac640000 +34849d0,ac620004 +34849d4,24020010 +34849d8,afa20018 +34849dc,afa20014 +34849e0,afb40010 +34849e4,8fa70038 +34849e8,8fa50044 +34849ec,c101bfd +34849f0,2002025 +34849f4,26730001 +34849f8,2652000c +34849fc,8ee2b0b0 +3484a00,262102a +3484a04,1440ffcd +3484a08,26940011 +3484a0c,8e020008 +3484a10,24430008 +3484a14,ae030008 +3484a18,3c03fa00 +3484a1c,ac430000 +3484a20,2403ffff +3484a24,ac430004 +3484a28,8fa2003c +3484a2c,10400037 +3484a30,3c028041 +3484a34,3c058041 +3484a38,24a5a090 +3484a3c,94a70008 +3484a40,3025 +3484a44,c101b95 +3484a48,2002025 +3484a4c,3c028041 +3484a50,8c42b0b0 +3484a54,18400168 +3484a58,3c1e8041 +3484a5c,3c128041 +3484a60,26529ef0 +3484a64,2414000a +3484a68,9825 +3484a6c,3c168041 +3484a70,26d69ecc +3484a74,3c028041 +3484a78,2442a090 +3484a7c,afa20040 +3484a80,3c028011 +3484a84,3442a5d0 +3484a88,afa2003c +3484a8c,3c178041 +3484a90,8fc2b148 +3484a94,10400009 +3484a98,92420000 +3484a9c,8fa3003c +3484aa0,621021 +3484aa4,904200a8 +3484aa8,21042 +3484aac,30420001 +3484ab0,50400010 +3484ab4,26730001 +3484ab8,92420000 +3484abc,561021 +3484ac0,80460000 +3484ac4,2cc20003 +3484ac8,5040000a +3484acc,26730001 +3484ad0,24020010 +3484ad4,afa20018 +3484ad8,afa20014 +3484adc,afb40010 +3484ae0,8fa70038 +3484ae4,8fa50040 +3484ae8,c101bfd +3484aec,2002025 +3484af0,26730001 +3484af4,2652000c +3484af8,8ee2b0b0 +3484afc,262102a +3484b00,1440ffe3 +3484b04,26940011 +3484b08,3c028041 +3484b0c,8c42b0b0 +3484b10,18400010 +3484b14,26310012 +3484b18,3c128041 +3484b1c,26529ef2 +3484b20,2414000b +3484b24,9825 +3484b28,3c168041 +3484b2c,2803025 +3484b30,2202825 +3484b34,c102508 +3484b38,2402025 +3484b3c,26730001 +3484b40,2652000c +3484b44,8ec2b0b0 +3484b48,262102a +3484b4c,1440fff7 +3484b50,26940011 +3484b54,3c028041 +3484b58,9456a054 +3484b5c,16b0c0 +3484b60,26d60001 +3484b64,2d1b021 +3484b68,24070001 +3484b6c,24060011 +3484b70,3c058041 +3484b74,24a5a060 +3484b78,c101b95 +3484b7c,2002025 +3484b80,3c028041 +3484b84,8c42b0b0 +3484b88,18400024 +3484b8c,241e3000 +3484b90,3c118041 +3484b94,26319ef0 +3484b98,2413000b +3484b9c,9025 +3484ba0,3c178011 +3484ba4,36f7a5d0 +3484ba8,3c148041 +3484bac,82220001 +3484bb0,4430015 +3484bb4,26520001 +3484bb8,92220000 +3484bbc,2e21021 +3484bc0,904200bc +3484bc4,21e00 +3484bc8,31e03 +3484bcc,2863000a +3484bd0,50600001 +3484bd4,24020009 +3484bd8,21e00 +3484bdc,31e03 +3484be0,4620001 +3484be4,1025 +3484be8,a7be0020 +3484bec,24420030 +3484bf0,a3a20020 +3484bf4,2603025 +3484bf8,2c02825 +3484bfc,c102508 +3484c00,27a40020 +3484c04,26520001 +3484c08,2631000c +3484c0c,8e82b0b0 +3484c10,242102a +3484c14,1440ffe5 +3484c18,26730011 +3484c1c,26de0011 +3484c20,24070001 +3484c24,2406000e +3484c28,3c058041 +3484c2c,24a5a060 +3484c30,c101b95 +3484c34,2002025 +3484c38,3c028041 +3484c3c,8c42b0b0 +3484c40,18400027 +3484c44,3c028041 +3484c48,3c118041 +3484c4c,26319ef0 +3484c50,2413000a +3484c54,9025 +3484c58,3c178011 +3484c5c,36f7a5d0 +3484c60,2442a060 +3484c64,afa20038 +3484c68,3c148041 +3484c6c,92230000 +3484c70,2404000d +3484c74,14640002 +3484c78,2201025 +3484c7c,2403000a +3484c80,90420001 +3484c84,30420040 +3484c88,50400010 +3484c8c,26520001 +3484c90,2e31821 +3484c94,906200a8 +3484c98,30420001 +3484c9c,5040000b +3484ca0,26520001 +3484ca4,24020010 +3484ca8,afa20018 +3484cac,afa20014 +3484cb0,afb30010 +3484cb4,3c03825 +3484cb8,3025 +3484cbc,8fa50038 +3484cc0,c101bfd +3484cc4,2002025 +3484cc8,26520001 +3484ccc,2631000c +3484cd0,8e82b0b0 +3484cd4,242102a +3484cd8,1440ffe4 +3484cdc,26730011 +3484ce0,24070001 +3484ce4,2406000a +3484ce8,3c058041 +3484cec,24a5a060 +3484cf0,c101b95 +3484cf4,2002025 +3484cf8,3c028041 +3484cfc,8c42b0b0 +3484d00,18400022 +3484d04,3c028041 +3484d08,3c118041 +3484d0c,26319ef1 +3484d10,2413000a +3484d14,9025 +3484d18,3c178011 +3484d1c,36f7a5d0 +3484d20,2442a060 +3484d24,afa20038 +3484d28,3c148041 +3484d2c,92220000 +3484d30,30420020 +3484d34,50400010 +3484d38,26520001 +3484d3c,8ee200a4 +3484d40,3c030040 +3484d44,431024 +3484d48,5040000b +3484d4c,26520001 +3484d50,24020010 +3484d54,afa20018 +3484d58,afa20014 +3484d5c,afb30010 +3484d60,3c03825 +3484d64,3025 +3484d68,8fa50038 +3484d6c,c101bfd +3484d70,2002025 +3484d74,26520001 +3484d78,2631000c +3484d7c,8e82b0b0 +3484d80,242102a +3484d84,1440ffe9 +3484d88,26730011 +3484d8c,26de0022 +3484d90,24070001 +3484d94,24060010 +3484d98,3c058041 +3484d9c,24a5a060 +3484da0,c101b95 +3484da4,2002025 +3484da8,3c028041 +3484dac,8c42b0b0 +3484db0,18400024 +3484db4,3c118041 +3484db8,26319ef0 +3484dbc,2413000a +3484dc0,9025 +3484dc4,3c178011 +3484dc8,36f7a5d0 +3484dcc,3c028041 +3484dd0,2442a060 +3484dd4,afa20038 +3484dd8,3c148041 +3484ddc,92220001 +3484de0,30420010 +3484de4,50400012 +3484de8,26520001 +3484dec,92220000 +3484df0,2e21021 +3484df4,904200a8 +3484df8,21082 +3484dfc,30420001 +3484e00,5040000b +3484e04,26520001 +3484e08,24020010 +3484e0c,afa20018 +3484e10,afa20014 +3484e14,afb30010 +3484e18,3c03825 +3484e1c,3025 +3484e20,8fa50038 +3484e24,c101bfd +3484e28,2002025 +3484e2c,26520001 +3484e30,2631000c +3484e34,8e82b0b0 +3484e38,242102a +3484e3c,1440ffe7 +3484e40,26730011 +3484e44,26c20033 +3484e48,afa20038 +3484e4c,24070001 +3484e50,2406000f +3484e54,3c058041 +3484e58,24a5a060 +3484e5c,c101b95 +3484e60,2002025 +3484e64,3c028041 +3484e68,8c42b0b0 +3484e6c,18400053 +3484e70,3c148041 +3484e74,26949ef0 +3484e78,2808825 +3484e7c,2413000a +3484e80,9025 +3484e84,3c1e8011 +3484e88,37dea5d0 +3484e8c,3c028041 +3484e90,2442a060 +3484e94,afa2003c +3484e98,3c178041 +3484e9c,92220001 +3484ea0,30420010 +3484ea4,50400012 +3484ea8,26520001 +3484eac,92220000 +3484eb0,3c21021 +3484eb4,904200a8 +3484eb8,21042 +3484ebc,30420001 +3484ec0,5040000b +3484ec4,26520001 +3484ec8,24020010 +3484ecc,afa20018 +3484ed0,afa20014 +3484ed4,afb30010 +3484ed8,8fa70038 +3484edc,3025 +3484ee0,8fa5003c +3484ee4,c101bfd +3484ee8,2002025 +3484eec,26520001 +3484ef0,8ee2b0b0 +3484ef4,2631000c +3484ef8,242182a +3484efc,1460ffe7 +3484f00,26730011 +3484f04,12a0002d +3484f0c,1840002b +3484f10,26d60044 +3484f14,2412000b +3484f18,8825 +3484f1c,3c1e8041 +3484f20,3c158041 +3484f24,26b5b1b0 +3484f28,3c138041 +3484f2c,26739e54 +3484f30,3c028041 +3484f34,24429e58 +3484f38,afa20038 +3484f3c,3c178041 +3484f40,8fc2b14c +3484f44,5040000f +3484f48,92820000 +3484f4c,92820001 +3484f50,30420010 +3484f54,5040000b +3484f58,92820000 +3484f5c,92830000 +3484f60,3c028011 +3484f64,3442a5d0 +3484f68,431021 +3484f6c,904200a8 +3484f70,21082 +3484f74,30420001 +3484f78,5040000b +3484f7c,26310001 +3484f80,92820000 +3484f84,551021 +3484f88,90420000 +3484f8c,14400002 +3484f90,2602025 +3484f94,8fa40038 +3484f98,2403025 +3484f9c,c102508 +3484fa0,2c02825 +3484fa4,26310001 +3484fa8,2694000c +3484fac,8ee2b0b0 +3484fb0,222102a +3484fb4,1440ffe2 +3484fb8,26520011 +3484fbc,c102532 +3484fc0,2002025 +3484fc4,8e020008 +3484fc8,24430008 +3484fcc,ae030008 +3484fd0,3c03e900 +3484fd4,ac430000 +3484fd8,ac400004 +3484fdc,8e020008 +3484fe0,24430008 +3484fe4,ae030008 +3484fe8,3c03df00 +3484fec,ac430000 +3484ff0,10000003 +3484ff4,ac400004 +3484ff8,1000fed6 +3484ffc,26310012 +3485000,8fbf006c +3485004,8fbe0068 +3485008,8fb70064 +348500c,8fb60060 +3485010,8fb5005c +3485014,8fb40058 +3485018,8fb30054 +348501c,8fb20050 +3485020,8fb1004c +3485024,8fb00048 +3485028,3e00008 +348502c,27bd0070 +3485030,3e00008 +3485038,44860000 +348503c,44801000 +3485044,46020032 +348504c,45030011 +3485050,46007006 +3485054,460e603c +348505c,45000007 +3485060,460c0000 +3485064,4600703c +348506c,45000009 +3485074,3e00008 +3485078,46007006 +348507c,460e003c +3485084,45000003 +348508c,3e00008 +3485090,46007006 +3485094,3e00008 +348509c,3c02801c +34850a0,344284a0 +34850a4,c44000d4 +34850a8,3c028041 +34850ac,3e00008 +34850b0,e440b0b8 +34850b4,27bdffe8 +34850b8,afbf0014 +34850bc,3c028041 +34850c0,90429f98 +34850c4,5040001b +34850c8,3c028041 +34850cc,3c038011 +34850d0,3463a5d0 +34850d4,8c630070 +34850d8,31f02 +34850dc,1062000d +34850e0,21300 +34850e4,3c048011 +34850e8,3484a5d0 +34850ec,94830070 +34850f0,30630fff +34850f4,621025 +34850f8,a4820070 +34850fc,3c04801d +3485100,3485aa30 +3485104,3c028007 +3485108,34429764 +348510c,40f809 +3485110,248484a0 +3485114,3c028041 +3485118,90439f98 +348511c,24020001 +3485120,14620004 +3485124,3c028041 +3485128,3c028041 +348512c,a0409f98 +3485130,3c028041 +3485134,c44e9f90 +3485138,44800000 +3485140,46007032 +3485148,45010010 +348514c,3c02801c +3485150,344284a0 +3485154,c44000d4 +3485158,46007032 +3485160,45010019 +3485164,3c02801c +3485168,3c028041 +348516c,8c469e60 +3485170,3c028041 +3485174,c10140e +3485178,c44cb0b4 +348517c,3c02801c +3485180,344284a0 +3485184,1000000f +3485188,e44000d4 +348518c,344284a0 +3485190,c44c00d4 +3485194,3c028041 +3485198,c44eb0b8 +348519c,460e6032 +34851a4,45010008 +34851a8,3c02801c +34851ac,3c028041 +34851b0,c10140e +34851b4,8c469e64 +34851b8,3c02801c +34851bc,344284a0 +34851c0,e44000d4 +34851c4,3c02801c +34851c8,344284a0 +34851cc,c44000d4 +34851d0,3c028041 +34851d4,e440b0b4 +34851d8,3c028041 +34851dc,90429f99 +34851e0,24030001 +34851e4,1443000f +34851e8,24030002 +34851ec,3c02801c +34851f0,344284a0 +34851f4,94420322 +34851f8,3c038041 +34851fc,24639c4c +3485200,431021 +3485204,90420000 +3485208,10400018 +348520c,3c028041 +3485210,3c02801c +3485214,344284a0 +3485218,24030035 +348521c,10000012 +3485220,a4430322 +3485224,14430011 +3485228,3c028041 +348522c,3c02801c +3485230,344284a0 +3485234,94420322 +3485238,3c038041 +348523c,24639c4c +3485240,431021 +3485244,90420000 +3485248,10400006 +348524c,3c028041 +3485250,3c02801c +3485254,344284a0 +3485258,2403001f +348525c,a4430322 +3485260,3c028041 +3485264,a0409f99 +3485268,3c028041 +348526c,24429f8c +3485270,c4400008 +3485274,3c038040 +3485278,e460274c +348527c,9044000e +3485280,3c038040 +3485284,a0642c9d +3485288,9042000f +348528c,50400006 +3485290,3c028041 +3485294,2442ffff +3485298,3c038041 +348529c,c101db5 +34852a0,a0629f9b +34852a4,3c028041 +34852a8,90429f9c +34852ac,1040000b +34852b0,3c028041 +34852b4,3c02801c +34852b8,344284a0 +34852bc,94430014 +34852c0,2404dfff +34852c4,641824 +34852c8,a4430014 +34852cc,94430020 +34852d0,641824 +34852d4,a4430020 +34852d8,3c028041 +34852dc,90429f9d +34852e0,10400016 +34852e4,8fbf0014 +34852e8,3c02801c +34852ec,344284a0 +34852f0,90430016 +34852f4,31823 +34852f8,a0430016 +34852fc,90430017 +3485300,31823 +3485304,a0430017 +3485308,90430022 +348530c,31823 +3485310,a0430022 +3485314,90430023 +3485318,31823 +348531c,a0430023 +3485320,90430028 +3485324,31823 +3485328,a0430028 +348532c,90430029 +3485330,31823 +3485334,a0430029 +3485338,8fbf0014 +348533c,3e00008 +3485340,27bd0018 +3485344,850018 +3485348,1812 +348534c,24620001 +3485350,3042ffff +3485354,31a02 +3485358,431021 +348535c,21203 +3485360,3e00008 +3485364,304200ff +3485368,2402ffff +348536c,a0820002 +3485370,a0820001 +3485374,4a00031 +3485378,a0820000 +348537c,a01825 +3485380,28a503e8 +3485384,50a00001 +3485388,240303e7 +348538c,31c00 +3485390,31c03 +3485394,3c026666 +3485398,24426667 +348539c,620018 +34853a0,1010 +34853a4,21083 +34853a8,32fc3 +34853ac,451023 +34853b0,22880 +34853b4,a22821 +34853b8,52840 +34853bc,651823 +34853c0,21400 +34853c4,21403 +34853c8,1040001c +34853cc,a0830002 +34853d0,3c036666 +34853d4,24636667 +34853d8,430018 +34853dc,1810 +34853e0,31883 +34853e4,22fc3 +34853e8,651823 +34853ec,32880 +34853f0,a32821 +34853f4,52840 +34853f8,451023 +34853fc,a0820001 +3485400,31400 +3485404,21403 +3485408,1040000c +348540c,3c036666 +3485410,24636667 +3485414,430018 +3485418,1810 +348541c,31883 +3485420,22fc3 +3485424,651823 +3485428,32880 +348542c,a31821 +3485430,31840 +3485434,431023 +3485438,a0820000 +348543c,3e00008 +3485444,27bdffd0 +3485448,afbf002c +348544c,afb20028 +3485450,afb10024 +3485454,afb00020 +3485458,808025 +348545c,a08825 +3485460,afa7003c +3485464,8fb20040 +3485468,c101b95 +348546c,24070001 +3485470,93a7003c +3485474,afb20018 +3485478,afb20014 +348547c,83a2003d +3485480,2442005c +3485484,afa20010 +3485488,24e70037 +348548c,3025 +3485490,2202825 +3485494,c101bfd +3485498,2002025 +348549c,8fbf002c +34854a0,8fb20028 +34854a4,8fb10024 +34854a8,8fb00020 +34854ac,3e00008 +34854b0,27bd0030 +34854b4,27bdffe0 +34854b8,afbf001c +34854bc,afb20018 +34854c0,afb10014 +34854c4,afb00010 +34854c8,808025 +34854cc,24850074 +34854d0,24070001 +34854d4,4825 +34854d8,3c028041 +34854dc,24429d10 +34854e0,2408ffe0 +34854e4,3c048041 +34854e8,24849d58 +34854ec,90430000 +34854f0,1031824 +34854f4,14600005 +34854f8,80a60000 +34854fc,90430001 +3485500,30c600ff +3485504,50660001 +3485508,1274825 +348550c,24420004 +3485510,73840 +3485514,1444fff5 +3485518,24a50001 +348551c,3c028041 +3485520,ac49b1c0 +3485524,8e1100a4 +3485528,2442b1c0 +348552c,3223003f +3485530,a0430004 +3485534,9602009c +3485538,8203003e +348553c,10600002 +3485540,3042fffb +3485544,34420004 +3485548,3c038041 +348554c,a462b1c6 +3485550,112c02 +3485554,30a5007c +3485558,26030086 +348555c,2606008a +3485560,2407001b +3485564,90640000 +3485568,2482ffec +348556c,304200ff +3485570,2c42000d +3485574,50400004 +3485578,24630001 +348557c,54870001 +3485580,34a50001 +3485584,24630001 +3485588,5466fff7 +348558c,90640000 +3485590,3c028041 +3485594,a045b1c5 +3485598,9203007b +348559c,2462fff9 +34855a0,304200ff +34855a4,2c420002 +34855a8,14400003 +34855ac,2025 +34855b0,10000002 +34855b4,24030007 +34855b8,24040001 +34855bc,3c028041 +34855c0,2442b1c0 +34855c4,a0440008 +34855c8,a0430009 +34855cc,9203007d +34855d0,2462fff6 +34855d4,304200ff +34855d8,2c420002 +34855dc,14400003 +34855e0,2025 +34855e4,10000002 +34855e8,2403000a +34855ec,24040001 +34855f0,3c028041 +34855f4,2442b1c0 +34855f8,a044000a +34855fc,a043000b +3485600,86020ef6 +3485604,4400016 +3485608,2403002b +348560c,96020ef4 +3485610,210c2 +3485614,3042008f +3485618,2c430010 +348561c,10600012 +3485620,2403002b +3485624,50400007 +3485628,9203008b +348562c,3c038041 +3485630,24639c90 +3485634,431021 +3485638,90430000 +348563c,1000000d +3485640,24040001 +3485644,2462ffdf +3485648,304200ff +348564c,2c420003 +3485650,14400008 +3485654,24040001 +3485658,10000005 +348565c,2403002b +3485660,10000004 +3485664,24040001 +3485668,10000002 +348566c,24040001 +3485670,2025 +3485674,3c028041 +3485678,2442b1c0 +348567c,a043000d +3485680,a044000c +3485684,9203008a +3485688,2462ffd3 +348568c,304200ff +3485690,2c42000b +3485694,14400003 +3485698,24040001 +348569c,24030037 +34856a0,2025 +34856a4,3c028041 +34856a8,2442b1c0 +34856ac,a043000f +34856b0,a044000e +34856b4,9202003c +34856b8,10400005 +34856bc,3c028041 +34856c0,24030013 +34856c4,a043b1d1 +34856c8,10000004 +34856cc,24030001 +34856d0,24030012 +34856d4,a043b1d1 +34856d8,9203003a +34856dc,3c028041 +34856e0,a043b1d0 +34856e4,8e0200a0 +34856e8,21182 +34856ec,30420007 +34856f0,10400009 +34856f4,2025 +34856f8,401825 +34856fc,2c420004 +3485700,50400001 +3485704,24030003 +3485708,2463004f +348570c,306300ff +3485710,10000002 +3485714,24040001 +3485718,24030050 +348571c,3c028041 +3485720,2442b1c0 +3485724,a0440012 +3485728,a0430013 +348572c,8e0200a0 +3485730,21242 +3485734,30420007 +3485738,50400009 +348573c,2025 +3485740,401825 +3485744,2c420003 +3485748,50400001 +348574c,24030002 +3485750,24630052 +3485754,306300ff +3485758,10000002 +348575c,24040001 +3485760,24030053 +3485764,3c028041 +3485768,2442b1c0 +348576c,a0440014 +3485770,a0430015 +3485774,8e0300a0 +3485778,31b02 +348577c,30630003 +3485780,a0430016 +3485784,86050034 +3485788,3c048041 +348578c,c1014da +3485790,2484b1db +3485794,3c020080 +3485798,2221024 +348579c,10400002 +34857a0,2825 +34857a4,860500d0 +34857a8,3c048041 +34857ac,c1014da +34857b0,2484b1de +34857b4,860508c6 +34857b8,58a00001 +34857bc,2405ffff +34857c0,3c048041 +34857c4,c1014da +34857c8,2484b1e1 +34857cc,3c128041 +34857d0,2652b1c0 +34857d4,9202003d +34857d8,a2420017 +34857dc,8602002e +34857e0,22fc3 +34857e4,30a5000f +34857e8,a22821 +34857ec,52903 +34857f0,3c048041 +34857f4,c1014da +34857f8,2484b1d8 +34857fc,86050022 +3485800,3c048041 +3485804,c1014da +3485808,2484b1e4 +348580c,118982 +3485810,32310fff +3485814,a6510028 +3485818,8fbf001c +348581c,8fb20018 +3485820,8fb10014 +3485824,8fb00010 +3485828,3e00008 +348582c,27bd0020 +3485830,27bdff88 +3485834,afbf0074 +3485838,afbe0070 +348583c,afb7006c +3485840,afb60068 +3485844,afb50064 +3485848,afb40060 +348584c,afb3005c +3485850,afb20058 +3485854,afb10054 +3485858,afb00050 +348585c,3c020002 +3485860,a21021 +3485864,9443ca42 +3485868,24020008 +348586c,14620021 +3485870,808825 +3485874,3c020002 +3485878,a21021 +348587c,9442ca36 +3485880,14400006 +3485884,3c020002 +3485888,a21021 +348588c,9444ca2e +3485890,24020002 +3485894,10820009 +3485898,3c020002 +348589c,a21021 +34858a0,9442ca30 +34858a4,24040005 +34858a8,50440005 +34858ac,3c020002 +34858b0,24040016 +34858b4,14440010 +34858b8,3c020002 +34858bc,3c020002 +34858c0,a21021 +34858c4,9443ca38 +34858c8,31080 +34858cc,431021 +34858d0,21980 +34858d4,431021 +34858d8,21100 +34858dc,24420020 +34858e0,8ca401d8 +34858e4,c10152d +34858e8,822021 +34858ec,10000220 +34858f0,8fbf0074 +34858f4,3c020002 +34858f8,a21021 +34858fc,9042ca37 +3485900,1440001d +3485904,2c44009a +3485908,3c020002 +348590c,a22821 +3485910,90a2ca31 +3485914,34420080 +3485918,2c44009a +348591c,10800214 +3485920,8fbf0074 +3485924,2c440086 +3485928,14800211 +348592c,2442007a +3485930,24040001 +3485934,441004 +3485938,3c040008 +348593c,24840014 +3485940,442024 +3485944,1480003b +3485948,3c040002 +348594c,24840081 +3485950,442024 +3485954,54800030 +3485958,24020008 +348595c,3c030004 +3485960,24630002 +3485964,431024 +3485968,10400202 +348596c,8fbe0070 +3485970,10000039 +3485974,241600c8 +3485978,108001fd +348597c,8fbf0074 +3485980,2c440086 +3485984,5080000e +3485988,2442007a +348598c,24040004 +3485990,10440028 +3485994,2c440005 +3485998,5080001b +348599c,24030006 +34859a0,24040002 +34859a4,5044001c +34859a8,24020008 +34859ac,24030003 +34859b0,1043002d +34859b4,241600c8 +34859b8,100001ee +34859bc,8fbe0070 +34859c0,24040001 +34859c4,441004 +34859c8,3c040008 +34859cc,24840014 +34859d0,442024 +34859d4,14800017 +34859d8,3c040002 +34859dc,24840081 +34859e0,442024 +34859e4,5480000c +34859e8,24020008 +34859ec,3c030004 +34859f0,24630002 +34859f4,431024 +34859f8,104001dd +34859fc,8fbf0074 +3485a00,10000017 +3485a04,241600c8 +3485a08,10430017 +3485a0c,241600c8 +3485a10,100001d7 +3485a14,8fbf0074 +3485a18,431023 +3485a1c,21840 +3485a20,431821 +3485a24,318c0 +3485a28,431021 +3485a2c,10000006 +3485a30,305600ff +3485a34,31040 +3485a38,621021 +3485a3c,210c0 +3485a40,621821 +3485a44,307600ff +3485a48,12c001c9 +3485a4c,8fbf0074 +3485a50,10000006 +3485a54,8e220008 +3485a58,10000004 +3485a5c,8e220008 +3485a60,10000002 +3485a64,8e220008 +3485a68,8e220008 +3485a6c,24430008 +3485a70,ae230008 +3485a74,3c03e700 +3485a78,ac430000 +3485a7c,ac400004 +3485a80,8e220008 +3485a84,24430008 +3485a88,ae230008 +3485a8c,3c03fc11 +3485a90,34639623 +3485a94,ac430000 +3485a98,3c03ff2f +3485a9c,3463ffff +3485aa0,ac430004 +3485aa4,2c02825 +3485aa8,c1014d1 +3485aac,24040090 +3485ab0,afa20048 +3485ab4,afa20044 +3485ab8,a025 +3485abc,24030040 +3485ac0,3c028041 +3485ac4,afa20030 +3485ac8,3c028041 +3485acc,2442b1c0 +3485ad0,afa2004c +3485ad4,3c178041 +3485ad8,26f79e90 +3485adc,3c158041 +3485ae0,26b59e10 +3485ae4,8e240008 +3485ae8,24820008 +3485aec,ae220008 +3485af0,3c02fa00 +3485af4,ac820000 +3485af8,31600 +3485afc,32c00 +3485b00,451025 +3485b04,8fa50044 +3485b08,451025 +3485b0c,31a00 +3485b10,431025 +3485b14,ac820004 +3485b18,8fa20030 +3485b1c,24539d90 +3485b20,8fbe004c +3485b24,2670ff80 +3485b28,8fd20000 +3485b2c,92020000 +3485b30,3042001f +3485b34,50400012 +3485b38,26100004 +3485b3c,32420001 +3485b40,5682000f +3485b44,26100004 +3485b48,8e020000 +3485b4c,21f42 +3485b50,31880 +3485b54,751821 +3485b58,21602 +3485b5c,3042001f +3485b60,afa20010 +3485b64,96070002 +3485b68,73c00 +3485b6c,92060001 +3485b70,8c650000 +3485b74,c101511 +3485b78,2202025 +3485b7c,26100004 +3485b80,1613ffea +3485b84,129042 +3485b88,26730080 +3485b8c,16f3ffe5 +3485b90,27de0004 +3485b94,2c02825 +3485b98,c1014d1 +3485b9c,240400ff +3485ba0,afa20044 +3485ba4,26940001 +3485ba8,24020002 +3485bac,1682ffcd +3485bb0,240300ff +3485bb4,8fa50048 +3485bb8,9825 +3485bbc,24030040 +3485bc0,3c178041 +3485bc4,3c1e8041 +3485bc8,3c158041 +3485bcc,26b59e10 +3485bd0,2416000c +3485bd4,3c148041 +3485bd8,10000002 +3485bdc,2694b1d6 +3485be0,8fa50044 +3485be4,8e240008 +3485be8,24820008 +3485bec,ae220008 +3485bf0,3c02fa00 +3485bf4,ac820000 +3485bf8,31600 +3485bfc,33400 +3485c00,461025 +3485c04,451025 +3485c08,31a00 +3485c0c,431025 +3485c10,ac820004 +3485c14,26f29cf8 +3485c18,27d0b1c8 +3485c1c,92020000 +3485c20,5453000f +3485c24,26100002 +3485c28,92420000 +3485c2c,21080 +3485c30,551021 +3485c34,afb60010 +3485c38,92430001 +3485c3c,31a00 +3485c40,92470002 +3485c44,e33825 +3485c48,73c00 +3485c4c,92060001 +3485c50,8c450000 +3485c54,c101511 +3485c58,2202025 +3485c5c,26100002 +3485c60,1614ffee +3485c64,26520003 +3485c68,26730001 +3485c6c,327300ff +3485c70,24020002 +3485c74,1662ffda +3485c78,240300ff +3485c7c,3c028041 +3485c80,9456b1e8 +3485c84,24070001 +3485c88,3025 +3485c8c,3c058041 +3485c90,24a5a020 +3485c94,c101b95 +3485c98,2202025 +3485c9c,afa00038 +3485ca0,afa00034 +3485ca4,afa00030 +3485ca8,b825 +3485cac,3c108041 +3485cb0,26109cbc +3485cb4,8fa20044 +3485cb8,afa2003c +3485cbc,3c028041 +3485cc0,2442a020 +3485cc4,afa20040 +3485cc8,3c1e8041 +3485ccc,10000005 +3485cd0,27de9cf8 +3485cd4,afb50038 +3485cd8,afb40034 +3485cdc,afb30030 +3485ce0,240b825 +3485ce4,92120000 +3485ce8,92130001 +3485cec,92140002 +3485cf0,32c20001 +3485cf4,1440000e +3485cf8,8fb5003c +3485cfc,24050040 +3485d00,c1014d1 +3485d04,2402025 +3485d08,409025 +3485d0c,24050040 +3485d10,c1014d1 +3485d14,2602025 +3485d18,409825 +3485d1c,24050040 +3485d20,c1014d1 +3485d24,2802025 +3485d28,40a025 +3485d2c,8fb50048 +3485d30,16570007 +3485d34,8fa20030 +3485d38,14530005 +3485d3c,8fa20034 +3485d40,16820003 +3485d44,8fa20038 +3485d48,5055000e +3485d4c,92070003 +3485d50,8e230008 +3485d54,24620008 +3485d58,ae220008 +3485d5c,3c02fa00 +3485d60,ac620000 +3485d64,121600 +3485d68,132400 +3485d6c,441025 +3485d70,551025 +3485d74,142200 +3485d78,441025 +3485d7c,ac620004 +3485d80,92070003 +3485d84,2402000a +3485d88,afa20018 +3485d8c,24020006 +3485d90,afa20014 +3485d94,82020004 +3485d98,2442005c +3485d9c,afa20010 +3485da0,24e70037 +3485da4,3025 +3485da8,8fa50040 +3485dac,c101bfd +3485db0,2202025 +3485db4,26100005 +3485db8,161effc6 +3485dbc,16b042 +3485dc0,3c108041 +3485dc4,2610b1c0 +3485dc8,92020016 +3485dcc,8fb50044 +3485dd0,2a09025 +3485dd4,21840 +3485dd8,621821 +3485ddc,3c028041 +3485de0,24429e1c +3485de4,621821 +3485de8,90620000 +3485dec,21600 +3485df0,90640001 +3485df4,42400 +3485df8,441025 +3485dfc,90630002 +3485e00,31a00 +3485e04,431025 +3485e08,551025 +3485e0c,8e230008 +3485e10,24640008 +3485e14,ae240008 +3485e18,3c13fa00 +3485e1c,ac730000 +3485e20,ac620004 +3485e24,3c028041 +3485e28,24429ca0 +3485e2c,24030010 +3485e30,afa30010 +3485e34,90430005 +3485e38,31a00 +3485e3c,90470006 +3485e40,e33825 +3485e44,73c00 +3485e48,24060001 +3485e4c,3c058041 +3485e50,24a5a010 +3485e54,c101511 +3485e58,2202025 +3485e5c,2414ff00 +3485e60,2b4a025 +3485e64,8e220008 +3485e68,24430008 +3485e6c,ae230008 +3485e70,ac530000 +3485e74,ac540004 +3485e78,24070001 +3485e7c,2406000c +3485e80,3c058041 +3485e84,24a5a060 +3485e88,c101b95 +3485e8c,2202025 +3485e90,92020017 +3485e94,1440000e +3485e98,24100010 +3485e9c,24020010 +3485ea0,afa20018 +3485ea4,afa20014 +3485ea8,2402005c +3485eac,afa20010 +3485eb0,2407003c +3485eb4,3025 +3485eb8,3c058041 +3485ebc,24a5a060 +3485ec0,c101bfd +3485ec4,2202025 +3485ec8,10000014 +3485ecc,3c028041 +3485ed0,afb00018 +3485ed4,afb00014 +3485ed8,2415005c +3485edc,afb50010 +3485ee0,2407003a +3485ee4,3025 +3485ee8,3c138041 +3485eec,2665a060 +3485ef0,c101bfd +3485ef4,2202025 +3485ef8,afb00018 +3485efc,afb00014 +3485f00,afb50010 +3485f04,2407003e +3485f08,3025 +3485f0c,2665a060 +3485f10,c101bfd +3485f14,2202025 +3485f18,3c028041 +3485f1c,9042b1e6 +3485f20,2c42000a +3485f24,1040000b +3485f28,24070001 +3485f2c,2402000a +3485f30,afa20010 +3485f34,3c028041 +3485f38,8c479cb4 +3485f3c,24060001 +3485f40,3c058041 +3485f44,24a59ff0 +3485f48,c101511 +3485f4c,2202025 +3485f50,24070001 +3485f54,2406000b +3485f58,3c108041 +3485f5c,2605a060 +3485f60,c101b95 +3485f64,2202025 +3485f68,24020010 +3485f6c,afa20018 +3485f70,afa20014 +3485f74,24020086 +3485f78,afa20010 +3485f7c,2407003c +3485f80,3025 +3485f84,2605a060 +3485f88,c101bfd +3485f8c,2202025 +3485f90,3c028041 +3485f94,9042b1e3 +3485f98,2c42000a +3485f9c,1040001d +3485fa0,8e220008 +3485fa4,24430008 +3485fa8,ae230008 +3485fac,3c03fa00 +3485fb0,ac430000 +3485fb4,3c03f4ec +3485fb8,24633000 +3485fbc,2439025 +3485fc0,ac520004 +3485fc4,3c038041 +3485fc8,9062b154 +3485fcc,24440001 +3485fd0,a064b154 +3485fd4,3c038041 +3485fd8,24639ca0 +3485fdc,21082 +3485fe0,24040010 +3485fe4,afa40010 +3485fe8,9064000f +3485fec,42200 +3485ff0,90670010 +3485ff4,e43825 +3485ff8,73c00 +3485ffc,3046000f +3486000,3c058041 +3486004,24a5a030 +3486008,c101511 +348600c,2202025 +3486010,8e220008 +3486014,24430008 +3486018,ae230008 +348601c,3c03fa00 +3486020,ac430000 +3486024,ac540004 +3486028,2407000a +348602c,3025 +3486030,3c058041 +3486034,24a5a000 +3486038,c101b95 +348603c,2202025 +3486040,8fa2004c +3486044,2453001b +3486048,3c168041 +348604c,26d6b1d8 +3486050,3c148041 +3486054,26949ca0 +3486058,26820019 +348605c,afa20034 +3486060,24170001 +3486064,241e0008 +3486068,3c028041 +348606c,2442a000 +3486070,afa20038 +3486074,afa00020 +3486078,afa00024 +348607c,afa00028 +3486080,afa0002c +3486084,27b20020 +3486088,2401825 +348608c,2c02025 +3486090,90820000 +3486094,54570006 +3486098,2c42000a +348609c,8c620000 +34860a0,2442ffff +34860a4,ac620000 +34860a8,10000003 +34860ac,24020005 +34860b0,21023 +34860b4,30420006 +34860b8,8c650000 +34860bc,a21021 +34860c0,ac620004 +34860c4,24840001 +34860c8,1493fff1 +34860cc,24630004 +34860d0,92950000 +34860d4,26b50037 +34860d8,82820002 +34860dc,2a2a821 +34860e0,92820004 +34860e4,10400006 +34860e8,2801825 +34860ec,8fa4002c +34860f0,417c2 +34860f4,441021 +34860f8,21043 +34860fc,2a2a823 +3486100,80620001 +3486104,2442005c +3486108,80630003 +348610c,431021 +3486110,afa20030 +3486114,2c08025 +3486118,92060000 +348611c,2cc2000a +3486120,5040000b +3486124,26100001 +3486128,8e470000 +348612c,afbe0018 +3486130,afbe0014 +3486134,8fa20030 +3486138,afa20010 +348613c,2a73821 +3486140,8fa50038 +3486144,c101bfd +3486148,2202025 +348614c,26100001 +3486150,1613fff1 +3486154,26520004 +3486158,26730003 +348615c,26940005 +3486160,8fa20034 +3486164,1454ffc3 +3486168,26d60003 +348616c,8fbf0074 +3486170,8fbe0070 +3486174,8fb7006c +3486178,8fb60068 +348617c,8fb50064 +3486180,8fb40060 +3486184,8fb3005c +3486188,8fb20058 +348618c,8fb10054 +3486190,8fb00050 +3486194,3e00008 +3486198,27bd0078 +348619c,27bdffa0 +34861a0,afbf005c +34861a4,afbe0058 +34861a8,afb70054 +34861ac,afb60050 +34861b0,afb5004c +34861b4,afb40048 +34861b8,afb30044 +34861bc,afb20040 +34861c0,afb1003c +34861c4,afb00038 +34861c8,afa40060 +34861cc,afa50064 +34861d0,3c02801c +34861d4,344284a0 +34861d8,8c500000 +34861dc,261402b8 +34861e0,8e0202c0 +34861e4,24430008 +34861e8,ae0302c0 +34861ec,3c03de00 +34861f0,ac430000 +34861f4,3c038041 +34861f8,2463a0a0 +34861fc,ac430004 +3486200,8e0202c0 +3486204,24430008 +3486208,ae0302c0 +348620c,3c03e700 +3486210,ac430000 +3486214,ac400004 +3486218,8e0202c0 +348621c,24430008 +3486220,ae0302c0 +3486224,3c03fc11 +3486228,34639623 +348622c,ac430000 +3486230,3c03ff2f +3486234,3463ffff +3486238,ac430004 +348623c,8e0202c0 +3486240,24430008 +3486244,ae0302c0 +3486248,3c03fa00 +348624c,ac430000 +3486250,2403ffff +3486254,ac430004 +3486258,3c028041 +348625c,8c52b158 +3486260,24110054 +3486264,3c178041 +3486268,26f79fa0 +348626c,3c168041 +3486270,26d6b0bc +3486274,24150018 +3486278,241e000c +348627c,3242001f +3486280,21040 +3486284,129143 +3486288,571021 +348628c,90430000 +3486290,31880 +3486294,761821 +3486298,8c730000 +348629c,24070001 +34862a0,90460001 +34862a4,2602825 +34862a8,c101b95 +34862ac,2802025 +34862b0,afb50018 +34862b4,afb50014 +34862b8,afbe0010 +34862bc,2203825 +34862c0,3025 +34862c4,2602825 +34862c8,c101bfd +34862cc,2802025 +34862d0,26310020 +34862d4,240200f4 +34862d8,1622ffe9 +34862dc,3242001f +34862e0,8fa50064 +34862e4,c10160c +34862e8,2802025 +34862ec,8e0202c0 +34862f0,24430008 +34862f4,ae0302c0 +34862f8,3c03e700 +34862fc,ac430000 +3486300,ac400004 +3486304,8e0202c0 +3486308,24430008 +348630c,ae0302c0 +3486310,3c03fcff +3486314,3463ffff +3486318,ac430000 +348631c,3c03fffd +3486320,3463f6fb +3486324,ac430004 +3486328,8e0202c0 +348632c,24430008 +3486330,ae0302c0 +3486334,3c03fa00 +3486338,ac430000 +348633c,93a30063 +3486340,ac430004 +3486344,3c02e450 +3486348,244203c0 +348634c,afa20020 +3486350,afa00024 +3486354,3c02e100 +3486358,afa20028 +348635c,afa0002c +3486360,3c02f100 +3486364,afa20030 +3486368,3c020400 +348636c,24420400 +3486370,afa20034 +3486374,27a20020 +3486378,27a60038 +348637c,8e0302c0 +3486380,24640008 +3486384,ae0402c0 +3486388,8c450004 +348638c,8c440000 +3486390,ac650004 +3486394,24420008 +3486398,14c2fff8 +348639c,ac640000 +34863a0,8fbf005c +34863a4,8fbe0058 +34863a8,8fb70054 +34863ac,8fb60050 +34863b0,8fb5004c +34863b4,8fb40048 +34863b8,8fb30044 +34863bc,8fb20040 +34863c0,8fb1003c +34863c4,8fb00038 +34863c8,3e00008 +34863cc,27bd0060 +34863d0,3c028040 +34863d4,90420cdd +34863d8,10400002 +34863dc,3c02800f +34863e0,a0401640 +34863e4,3e00008 +34863ec,3c028041 +34863f0,9042b15c +34863f4,1040000d +34863f8,3c028011 +34863fc,3442a5d0 +3486400,8c430000 +3486404,24020517 +3486408,14620008 +3486410,27bdffe8 +3486414,afbf0014 +3486418,c1024e1 +3486420,8fbf0014 +3486424,3e00008 +3486428,27bd0018 +348642c,3e00008 +3486434,27bdffe8 +3486438,afbf0014 +348643c,3c028041 +3486440,8c42b18c +3486444,218c0 +3486448,3c048041 +348644c,2484b204 +3486450,641821 +3486454,8c630000 +3486458,1060000c +348645c,24420001 +3486460,220c0 +3486464,3c038041 +3486468,2463b204 +348646c,641821 +3486470,402825 +3486474,8c640000 +3486478,24420001 +348647c,1480fffc +3486480,24630008 +3486484,3c028041 +3486488,ac45b18c +348648c,c1026e9 +3486490,2404013c +3486494,3c038041 +3486498,ac62b188 +348649c,24030001 +34864a0,ac430130 +34864a4,8fbf0014 +34864a8,3e00008 +34864ac,27bd0018 +34864b0,801025 +34864b4,84a30000 +34864b8,2404000a +34864bc,14640012 +34864c0,24040015 +34864c4,24030010 +34864c8,14c30008 +34864cc,94a3001c +34864d0,31942 +34864d4,3063007f +34864d8,24040075 +34864dc,54640003 +34864e0,94a3001c +34864e4,3e00008 +34864e8,ac400000 +34864ec,3063001f +34864f0,a0400000 +34864f4,a0460001 +34864f8,24040001 +34864fc,a0440002 +3486500,3e00008 +3486504,a0430003 +3486508,14640010 +348650c,2404019c +3486510,90a3001d +3486514,24040006 +3486518,10640005 +348651c,24040011 +3486520,50640004 +3486524,90a30141 +3486528,3e00008 +348652c,ac400000 +3486530,90a30141 +3486534,a0400000 +3486538,a0460001 +348653c,24040002 +3486540,a0440002 +3486544,3e00008 +3486548,a0430003 +348654c,1464000a +3486550,2404003e +3486554,94a4001c +3486558,a0400000 +348655c,41a02 +3486560,3063001f +3486564,a0430001 +3486568,24030003 +348656c,a0430002 +3486570,3e00008 +3486574,a0440003 +3486578,54c4000d +348657c,a4400000 +3486580,2404011a +3486584,5464000a +3486588,a4400000 +348658c,3c038011 +3486590,3463a5d0 +3486594,90631397 +3486598,a0400000 +348659c,a0430001 +34865a0,24030004 +34865a4,a0430002 +34865a8,3e00008 +34865ac,a0470003 +34865b0,a0400002 +34865b4,a0460001 +34865b8,3e00008 +34865bc,a0470003 +34865c0,3c038041 +34865c4,8c67b18c +34865c8,24e7ffff +34865cc,4e00021 +34865d0,801025 +34865d4,27bdfff8 +34865d8,4825 +34865dc,3c0a8041 +34865e0,254ab204 +34865e4,1273021 +34865e8,61fc2 +34865ec,661821 +34865f0,31843 +34865f4,330c0 +34865f8,ca3021 +34865fc,8cc80000 +3486600,8cc60004 +3486604,afa60004 +3486608,a8302b +348660c,10c00003 +3486610,105302b +3486614,10000008 +3486618,2467ffff +348661c,50c00003 +3486620,ac480000 +3486624,10000004 +3486628,24690001 +348662c,8fa30004 +3486630,10000006 +3486634,ac430004 +3486638,e9182a +348663c,1060ffea +3486640,1273021 +3486644,ac400000 +3486648,ac400004 +348664c,3e00008 +3486650,27bd0008 +3486654,ac800000 +3486658,3e00008 +348665c,ac800004 +3486660,27bdffe0 +3486664,afbf001c +3486668,afb00018 +348666c,808025 +3486670,c10192c +3486674,27a40010 +3486678,8fa50010 +348667c,14a00004 +3486684,ae000000 +3486688,10000003 +348668c,ae000004 +3486690,c101970 +3486694,2002025 +3486698,2001025 +348669c,8fbf001c +34866a0,8fb00018 +34866a4,3e00008 +34866a8,27bd0020 +34866ac,27bdffe8 +34866b0,afbf0014 +34866b4,afb00010 +34866b8,afa40018 +34866bc,58202 +34866c0,afa5001c +34866c4,321000ff +34866c8,c101ea1 +34866cc,52402 +34866d0,c101e92 +34866d4,402025 +34866d8,3c038041 +34866dc,8fa40018 +34866e0,ac64b180 +34866e4,2463b180 +34866e8,8fa4001c +34866ec,ac640004 +34866f0,3c038040 +34866f4,90630024 +34866f8,701826 +34866fc,3182b +3486700,3c048041 +3486704,ac83b17c +3486708,3c038041 +348670c,ac62b178 +3486710,90440001 +3486714,3c038041 +3486718,ac64b174 +348671c,94440002 +3486720,3c038041 +3486724,ac64b170 +3486728,94440004 +348672c,3c038041 +3486730,ac64b16c +3486734,80440006 +3486738,3c038041 +348673c,ac64b168 +3486740,90420007 +3486744,30420001 +3486748,3c038041 +348674c,ac62b164 +3486750,3c028040 +3486754,a0500025 +3486758,8fbf0014 +348675c,8fb00010 +3486760,3e00008 +3486764,27bd0018 +3486768,3c028041 +348676c,ac40b180 +3486770,2442b180 +3486774,ac400004 +3486778,3c028041 +348677c,ac40b17c +3486780,3c028041 +3486784,ac40b178 +3486788,3c028041 +348678c,ac40b174 +3486790,3c028041 +3486794,ac40b170 +3486798,3c028041 +348679c,ac40b16c +34867a0,3c028041 +34867a4,ac40b168 +34867a8,3c028041 +34867ac,3e00008 +34867b0,ac40b164 +34867b4,8c830000 +34867b8,3c028040 +34867bc,ac43002c +34867c0,94830004 +34867c4,3c028040 +34867c8,a4430030 +34867cc,90830006 +34867d0,3c028040 +34867d4,3e00008 +34867d8,a4430032 +34867dc,afa40000 +34867e0,afa50004 +34867e4,3c028041 +34867e8,2442b1ec +34867ec,1825 +34867f0,24060003 +34867f4,8c450000 +34867f8,14a0000a +3486800,318c0 +3486804,3c028041 +3486808,2442b1ec +348680c,621821 +3486810,8fa20000 +3486814,ac620000 +3486818,8fa20004 +348681c,3e00008 +3486820,ac620004 +3486824,10a40003 +3486828,24630001 +348682c,1466fff1 +3486830,24420008 +3486834,3e00008 +348683c,3c028040 +3486840,94420028 +3486844,10400013 +3486848,2403ffff +348684c,27bdffe0 +3486850,afbf001c +3486854,afa00010 +3486858,afa00014 +348685c,a3a30011 +3486860,24040005 +3486864,a3a40012 +3486868,a3a30013 +348686c,3c038040 +3486870,94630026 +3486874,a3a30016 +3486878,a7a20014 +348687c,8fa40010 +3486880,c1019f7 +3486884,8fa50014 +3486888,8fbf001c +348688c,3e00008 +3486890,27bd0020 +3486894,3e00008 +348689c,27bdffe0 +34868a0,afbf001c +34868a4,3c0200ff +34868a8,34420500 +34868ac,442825 +34868b0,c101970 +34868b4,27a40010 +34868b8,8fa20010 +34868bc,10400005 +34868c0,8fbf001c +34868c4,402025 +34868c8,c1019f7 +34868cc,8fa50014 +34868d0,8fbf001c +34868d4,3e00008 +34868d8,27bd0020 +34868dc,3c038041 +34868e0,2462b1ec +34868e4,8c450008 +34868e8,8c44000c +34868ec,ac65b1ec +34868f0,ac440004 +34868f4,8c440010 +34868f8,8c430014 +34868fc,ac440008 +3486900,ac43000c +3486904,ac400010 +3486908,3e00008 +348690c,ac400014 +3486910,801825 +3486914,3084ffff +3486918,240205ff +348691c,1482000b +3486920,27bdfff8 +3486924,3c028011 +3486928,3442a660 +348692c,94430000 +3486930,24630001 +3486934,a4430000 +3486938,3c028040 +348693c,a4400028 +3486940,3c028040 +3486944,10000009 +3486948,a4400026 +348694c,3c020057 +3486950,24420058 +3486954,14620005 +3486958,3c02801c +348695c,344284a0 +3486960,8c431d38 +3486964,34630001 +3486968,ac431d38 +348696c,3e00008 +3486970,27bd0008 +3486974,27bdffe8 +3486978,afbf0014 +348697c,afb00010 +3486980,3c028041 +3486984,8c50b1ec +3486988,2442b1ec +348698c,94430004 +3486990,2402007c +3486994,1462000e +3486998,8fbf0014 +348699c,3c028040 +34869a0,90430024 +34869a4,3c028041 +34869a8,9042b1f2 +34869ac,54620009 +34869b0,8fb00010 +34869b4,c101db5 +34869bc,c101a37 +34869c4,c101a44 +34869c8,2002025 +34869cc,8fbf0014 +34869d0,8fb00010 +34869d4,3e00008 +34869d8,27bd0018 +34869dc,27bdffe8 +34869e0,afbf0014 +34869e4,afb00010 +34869e8,3c028041 +34869ec,8c50b180 +34869f0,1200000e +34869f4,8fbf0014 +34869f8,c1019ed +34869fc,2444b180 +3486a00,3c028041 +3486a04,8c42b1ec +3486a08,14500003 +3486a10,c101a37 +3486a18,c101a44 +3486a1c,2002025 +3486a20,c1019da +3486a28,8fbf0014 +3486a2c,8fb00010 +3486a30,3e00008 +3486a34,27bd0018 +3486a38,27bdffe0 +3486a3c,afbf001c +3486a40,3c028041 +3486a44,8c43b1ec +3486a48,2442b1ec +3486a4c,8c420004 +3486a50,afa30010 +3486a54,1060000d +3486a58,afa20014 +3486a5c,602025 +3486a60,c1019ab +3486a64,402825 +3486a68,3c02801d +3486a6c,3442aa30 +3486a70,3c038041 +3486a74,8c63b188 +3486a78,ac430428 +3486a7c,3c038041 +3486a80,8c63b178 +3486a84,80630000 +3486a88,a0430424 +3486a8c,8fbf001c +3486a90,3e00008 +3486a94,27bd0020 +3486a98,27bdffe8 +3486a9c,afbf0014 +3486aa0,c101a0f +3486aa8,3c02801d +3486aac,3442aa30 +3486ab0,8c42066c +3486ab4,3c03fcac +3486ab8,24632485 +3486abc,431024 +3486ac0,14400033 +3486ac4,3c028041 +3486ac8,3c02801d +3486acc,3442aa30 +3486ad0,94420088 +3486ad4,30420001 +3486ad8,1040002a +3486adc,1025 +3486ae0,3c02801d +3486ae4,3442aa30 +3486ae8,8c420670 +3486aec,3c03000c +3486af0,431024 +3486af4,14400023 +3486af8,1025 +3486afc,3c02800e +3486b00,3442f1b0 +3486b04,8c420000 +3486b08,30420020 +3486b0c,1440001d +3486b10,1025 +3486b14,3c02801c +3486b18,344284a0 +3486b1c,8c420794 +3486b20,14400018 +3486b24,1025 +3486b28,3c028041 +3486b2c,9042b160 +3486b30,24420001 +3486b34,304200ff +3486b38,2c430002 +3486b3c,14600012 +3486b40,3c038041 +3486b44,3c028041 +3486b48,c101a5d +3486b4c,a040b160 +3486b50,c101db1 +3486b58,10400005 +3486b60,c101dba +3486b68,1000000b +3486b6c,8fbf0014 +3486b70,c101a8e +3486b78,10000007 +3486b7c,8fbf0014 +3486b80,1025 +3486b84,3c038041 +3486b88,10000002 +3486b8c,a062b160 +3486b90,a040b160 +3486b94,8fbf0014 +3486b98,3e00008 +3486b9c,27bd0018 +3486ba0,27bdffd0 +3486ba4,afbf002c +3486ba8,afb40028 +3486bac,afb30024 +3486bb0,afb20020 +3486bb4,afb1001c +3486bb8,afb00018 +3486bbc,a09025 +3486bc0,10800013 +3486bc4,c08825 +3486bc8,10c00011 +3486bcc,808025 +3486bd0,4c10004 +3486bd4,c03825 +3486bd8,63823 +3486bdc,73e00 +3486be0,73e03 +3486be4,30e700ff +3486be8,3c02801c +3486bec,344284a0 +3486bf0,904600a5 +3486bf4,2002825 +3486bf8,c101998 +3486bfc,27a40010 +3486c00,97b30014 +3486c04,8fa20010 +3486c08,14400005 +3486c0c,93b40016 +3486c10,c1019da +3486c18,1000001b +3486c1c,2201025 +3486c20,8fa40010 +3486c24,c1019ab +3486c28,8fa50014 +3486c2c,3c028041 +3486c30,8c42b178 +3486c34,86040000 +3486c38,2403000a +3486c3c,1483000d +3486c40,80420000 +3486c44,2403007c +3486c48,56630006 +3486c4c,9603001c +3486c50,3c038040 +3486c54,90630024 +3486c58,50740001 +3486c5c,2402007c +3486c60,9603001c +3486c64,3063f01f +3486c68,22140 +3486c6c,641825 +3486c70,a603001c +3486c74,6230005 +3486c78,a2420424 +3486c7c,21023 +3486c80,21600 +3486c84,21603 +3486c88,a2420424 +3486c8c,8fbf002c +3486c90,8fb40028 +3486c94,8fb30024 +3486c98,8fb20020 +3486c9c,8fb1001c +3486ca0,8fb00018 +3486ca4,3e00008 +3486ca8,27bd0030 +3486cac,27bdffd8 +3486cb0,afbf0024 +3486cb4,afb20020 +3486cb8,afb1001c +3486cbc,afb00018 +3486cc0,808825 +3486cc4,3825 +3486cc8,3025 +3486ccc,802825 +3486cd0,c101998 +3486cd4,27a40010 +3486cd8,8fa20010 +3486cdc,54400005 +3486ce0,97a40014 +3486ce4,3c028040 +3486ce8,90520024 +3486cec,10000002 +3486cf0,2404005b +3486cf4,93b20016 +3486cf8,c101ea1 +3486d00,c101e92 +3486d04,402025 +3486d08,408025 +3486d0c,ae200134 +3486d10,3c028040 +3486d14,a0520025 +3486d18,3025 +3486d1c,96050002 +3486d20,3c04801c +3486d24,3c02800d +3486d28,3442ce14 +3486d2c,40f809 +3486d30,348484a0 +3486d34,3c028040 +3486d38,90420024 +3486d3c,50520005 +3486d40,92050001 +3486d44,c1019ed +3486d48,27a40010 +3486d4c,10000009 +3486d50,8fbf0024 +3486d54,3c04801c +3486d58,3c028006 +3486d5c,3442fdcc +3486d60,40f809 +3486d64,348484a0 +3486d68,c101eb9 +3486d6c,2002025 +3486d70,8fbf0024 +3486d74,8fb20020 +3486d78,8fb1001c +3486d7c,8fb00018 +3486d80,3e00008 +3486d84,27bd0028 +3486d88,27bdffe8 +3486d8c,afbf0014 +3486d90,afb00010 +3486d94,3c028011 +3486d98,3442a5d0 +3486d9c,94500eec +3486da0,32100002 +3486da4,1600000c +3486da8,3c028040 +3486dac,90420cd5 +3486db0,50400004 +3486db4,3c028011 +3486db8,c101a27 +3486dbc,24040002 +3486dc0,3c028011 +3486dc4,3442a5d0 +3486dc8,94430eec +3486dcc,34630002 +3486dd0,a4430eec +3486dd4,3c028040 +3486dd8,90430cd5 +3486ddc,14600002 +3486de0,24020001 +3486de4,10102b +3486de8,8fbf0014 +3486dec,8fb00010 +3486df0,3e00008 +3486df4,27bd0018 +3486df8,94830004 +3486dfc,94820006 +3486e00,620018 +3486e04,9082000c +3486e08,1812 +3486e14,620018 +3486e18,1012 +3486e1c,3e00008 +3486e24,27bdffe8 +3486e28,afbf0014 +3486e2c,afb00010 +3486e30,c101b7e +3486e34,808025 +3486e38,96030008 +3486e3c,620018 +3486e40,1012 +3486e44,8fbf0014 +3486e48,8fb00010 +3486e4c,3e00008 +3486e50,27bd0018 +3486e54,27bdff98 +3486e58,afbf0064 +3486e5c,afb60060 +3486e60,afb5005c +3486e64,afb40058 +3486e68,afb30054 +3486e6c,afb20050 +3486e70,afb1004c +3486e74,afb00048 +3486e78,808025 +3486e7c,a0a025 +3486e80,c0a825 +3486e84,94b10004 +3486e88,94a20006 +3486e8c,470018 +3486e90,9012 +3486e94,90b6000b +3486e98,90b3000a +3486e9c,139d40 +3486ea0,3c0200e0 +3486ea4,2629824 +3486ea8,1614c0 +3486eac,3c030018 +3486eb0,431024 +3486eb4,2629825 +3486eb8,2622ffff +3486ebc,30420fff +3486ec0,531025 +3486ec4,3c03fd00 +3486ec8,431025 +3486ecc,afa20010 +3486ed0,c101b7e +3486ed4,a02025 +3486ed8,550018 +3486edc,8e820000 +3486ee0,1812 +3486ee4,431021 +3486ee8,afa20014 +3486eec,2ec30002 +3486ef0,10600003 +3486ef4,24020010 +3486ef8,24020004 +3486efc,2c21004 +3486f00,510018 +3486f04,1812 +3486f08,2463003f +3486f0c,317c3 +3486f10,3042003f +3486f14,431021 +3486f18,210c0 +3486f1c,3c030003 +3486f20,3463fe00 +3486f24,431024 +3486f28,531025 +3486f2c,3c03f500 +3486f30,431025 +3486f34,afa20018 +3486f38,3c040700 +3486f3c,afa4001c +3486f40,3c03e600 +3486f44,afa30020 +3486f48,afa00024 +3486f4c,3c03f400 +3486f50,afa30028 +3486f54,2623ffff +3486f58,31b80 +3486f5c,3c0500ff +3486f60,34a5f000 +3486f64,651824 +3486f68,2652ffff +3486f6c,129080 +3486f70,32520ffc +3486f74,721825 +3486f78,642025 +3486f7c,afa4002c +3486f80,3c04e700 +3486f84,afa40030 +3486f88,afa00034 +3486f8c,afa20038 +3486f90,afa0003c +3486f94,3c02f200 +3486f98,afa20040 +3486f9c,afa30044 +3486fa0,27a20010 +3486fa4,27a60048 +3486fa8,8e030008 +3486fac,24640008 +3486fb0,ae040008 +3486fb4,8c450004 +3486fb8,8c440000 +3486fbc,ac650004 +3486fc0,24420008 +3486fc4,1446fff8 +3486fc8,ac640000 +3486fcc,8fbf0064 +3486fd0,8fb60060 +3486fd4,8fb5005c +3486fd8,8fb40058 +3486fdc,8fb30054 +3486fe0,8fb20050 +3486fe4,8fb1004c +3486fe8,8fb00048 +3486fec,3e00008 +3486ff0,27bd0068 +3486ff4,27bdffe0 +3486ff8,8fa80030 +3486ffc,8fa20034 +3487000,8faa0038 +3487004,94a30004 +3487008,31a80 +348700c,14400002 +3487010,62001a +3487014,7000d +3487018,4812 +348701c,94a30006 +3487020,471021 +3487024,21380 +3487028,3c0b00ff +348702c,356bf000 +3487030,4b1024 +3487034,1482821 +3487038,52880 +348703c,30a50fff +3487040,451025 +3487044,3c05e400 +3487048,451025 +348704c,afa20000 +3487050,73b80 +3487054,eb3824 +3487058,84080 +348705c,31080fff +3487060,e83825 +3487064,afa70004 +3487068,3c02e100 +348706c,afa20008 +3487070,660018 +3487074,1012 +3487078,21140 +348707c,3042ffff +3487080,afa2000c +3487084,3c02f100 +3487088,afa20010 +348708c,31a80 +3487090,15400002 +3487094,6a001a +3487098,7000d +348709c,1012 +34870a0,3042ffff +34870a4,94c00 +34870a8,491025 +34870ac,afa20014 +34870b0,afbd0018 +34870b4,27a50018 +34870b8,8c820008 +34870bc,24430008 +34870c0,ac830008 +34870c4,8fa30018 +34870c8,8c670004 +34870cc,8c660000 +34870d0,ac470004 +34870d4,ac460000 +34870d8,24620008 +34870dc,1445fff6 +34870e0,afa20018 +34870e4,3e00008 +34870e8,27bd0020 +34870ec,27bdffa0 +34870f0,afbf005c +34870f4,afb10058 +34870f8,afb00054 +34870fc,afa00010 +3487100,3c0201a0 +3487104,24422000 +3487108,afa20014 +348710c,3c110003 +3487110,362295c0 +3487114,afa20018 +3487118,c1026f8 +348711c,27a40010 +3487120,afa0001c +3487124,3c020084 +3487128,24426000 +348712c,afa20020 +3487130,3402b400 +3487134,afa20024 +3487138,c1026f8 +348713c,27a4001c +3487140,afa00028 +3487144,3c02007b +3487148,3442d000 +348714c,afa2002c +3487150,3c100008 +3487154,361088a0 +3487158,afb00030 +348715c,c1026f8 +3487160,27a40028 +3487164,afa00034 +3487168,3c0201a3 +348716c,3442c000 +3487170,afa20038 +3487174,24023b00 +3487178,afa2003c +348717c,c1026f8 +3487180,27a40034 +3487184,afa00040 +3487188,3c020085 +348718c,3442e000 +3487190,afa20044 +3487194,24021d80 +3487198,afa20048 +348719c,c1026f8 +34871a0,27a40040 +34871a4,8fa20010 +34871a8,2631a300 +34871ac,518821 +34871b0,3c038041 +34871b4,ac71a090 +34871b8,24422980 +34871bc,3c038041 +34871c0,ac62a080 +34871c4,8fa20028 +34871c8,3c038041 +34871cc,ac62a070 +34871d0,3c038041 +34871d4,8fa4001c +34871d8,ac64a060 +34871dc,3c048041 +34871e0,3c038041 +34871e4,2463d710 +34871e8,ac83a040 +34871ec,3c048041 +34871f0,3c038041 +34871f4,2463df10 +34871f8,ac83a030 +34871fc,2610f7a0 +3487200,501021 +3487204,3c038041 +3487208,ac62a020 +348720c,8fa20034 +3487210,24441e00 +3487214,3c038041 +3487218,ac64a010 +348721c,244435c0 +3487220,3c038041 +3487224,ac64a000 +3487228,8fa30040 +348722c,24631980 +3487230,3c048041 +3487234,ac839ff0 +3487238,3c038041 +348723c,ac629fe0 +3487240,3c118041 +3487244,c101b89 +3487248,2624a050 +348724c,408025 +3487250,c1026e9 +3487254,402025 +3487258,104fc2 +348725c,1304821 +3487260,2a100002 +3487264,16000018 +3487268,ae22a050 +348726c,94843 +3487270,3c038041 +3487274,2463c248 +3487278,2025 +348727c,3025 +3487280,2204025 +3487284,2407fff0 +3487288,8d05a050 +348728c,a42821 +3487290,90620000 +3487294,21102 +3487298,471025 +348729c,a0a20000 +34872a0,8d02a050 +34872a4,441021 +34872a8,90650000 +34872ac,a72825 +34872b0,a0450001 +34872b4,24c60001 +34872b8,24630001 +34872bc,c9102a +34872c0,1440fff1 +34872c4,24840002 +34872c8,8fbf005c +34872cc,8fb10058 +34872d0,8fb00054 +34872d4,3e00008 +34872d8,27bd0060 +34872dc,3c038040 +34872e0,9462084e +34872e4,2463084e +34872e8,94640002 +34872ec,94630004 +34872f0,3c058041 +34872f4,8ca5b130 +34872f8,a4a20000 +34872fc,a4a40002 +3487300,a4a30004 +3487304,3c058041 +3487308,8ca6b12c +348730c,a4c20000 +3487310,8ca5b12c +3487314,a4a40004 +3487318,a4a30008 +348731c,240500ff +3487320,1445000a +3487324,3c058041 +3487328,24050046 +348732c,14850007 +3487330,3c058041 +3487334,24050032 +3487338,14650004 +348733c,3c058041 +3487340,1825 +3487344,2025 +3487348,240200c8 +348734c,8ca5b128 +3487350,a4a20000 +3487354,a4a40002 +3487358,a4a30004 +348735c,3c058041 +3487360,8ca5b124 +3487364,a4a20000 +3487368,a4a40002 +348736c,a4a30004 +3487370,3c028041 +3487374,8c43b120 +3487378,3c028040 +348737c,94450854 +3487380,24420854 +3487384,94440002 +3487388,94420004 +348738c,a4650000 +3487390,a4640002 +3487394,a4620004 +3487398,3c028041 +348739c,8c43b11c +34873a0,3c028040 +34873a4,9445085a +34873a8,2442085a +34873ac,94440002 +34873b0,94420004 +34873b4,a4650000 +34873b8,a4640002 +34873bc,a4620004 +34873c0,3c028041 +34873c4,8c43b118 +34873c8,3c028040 +34873cc,94450860 +34873d0,24420860 +34873d4,94440002 +34873d8,94420004 +34873dc,a4650000 +34873e0,a4640002 +34873e4,a4620004 +34873e8,3c028041 +34873ec,8c42b114 +34873f0,3c068040 +34873f4,94c30872 +34873f8,a4430000 +34873fc,3c028041 +3487400,8c43b110 +3487404,24c20872 +3487408,94440002 +348740c,a4640000 +3487410,3c038041 +3487414,8c63b10c +3487418,94440004 +348741c,a4640000 +3487420,3c038041 +3487424,8c63b108 +3487428,3c058040 +348742c,94a40878 +3487430,a4640000 +3487434,3c038041 +3487438,8c64b104 +348743c,24a30878 +3487440,94670002 +3487444,a4870000 +3487448,3c048041 +348744c,8c84b100 +3487450,94670004 +3487454,a4870000 +3487458,3c048041 +348745c,8c84b0fc +3487460,94c80872 +3487464,94470002 +3487468,94460004 +348746c,a4880000 +3487470,a4870002 +3487474,a4860004 +3487478,3c048041 +348747c,8c84b0ec +3487480,94a60878 +3487484,94650002 +3487488,94630004 +348748c,a4860000 +3487490,a4850002 +3487494,a4830004 +3487498,94420002 +348749c,3043ffff +34874a0,2c6300ce +34874a4,50600001 +34874a8,240200cd +34874ac,24420032 +34874b0,3047ffff +34874b4,3c028040 +34874b8,94420876 +34874bc,3043ffff +34874c0,2c6300ce +34874c4,50600001 +34874c8,240200cd +34874cc,24420032 +34874d0,3046ffff +34874d4,3c028040 +34874d8,94420878 +34874dc,3043ffff +34874e0,2c6300ce +34874e4,50600001 +34874e8,240200cd +34874ec,24420032 +34874f0,3044ffff +34874f4,3c028040 +34874f8,9442087a +34874fc,3043ffff +3487500,2c6300ce +3487504,50600001 +3487508,240200cd +348750c,24420032 +3487510,3043ffff +3487514,3c028040 +3487518,9442087c +348751c,3045ffff +3487520,2ca500ce +3487524,50a00001 +3487528,240200cd +348752c,24420032 +3487530,3c058041 +3487534,8ca8b0f8 +3487538,3c058040 +348753c,94a50872 +3487540,30a9ffff +3487544,2d2900ce +3487548,15200002 +348754c,3042ffff +3487550,240500cd +3487554,24a50032 +3487558,a5050000 +348755c,a5070002 +3487560,a5060004 +3487564,3c058041 +3487568,8ca5b0e8 +348756c,a4a40000 +3487570,a4a30002 +3487574,a4a20004 +3487578,3c028041 +348757c,8c43b0f0 +3487580,3c028040 +3487584,94450872 +3487588,24420872 +348758c,94440002 +3487590,94420004 +3487594,a4650000 +3487598,a4640002 +348759c,a4620004 +34875a0,3c028041 +34875a4,8c43b0e0 +34875a8,3c028040 +34875ac,94450878 +34875b0,24420878 +34875b4,94440002 +34875b8,94420004 +34875bc,a4650000 +34875c0,a4640002 +34875c4,a4620004 +34875c8,3c028041 +34875cc,8c43b0dc +34875d0,3c028040 +34875d4,94460866 +34875d8,24440866 +34875dc,94850002 +34875e0,94840004 +34875e4,a4660000 +34875e8,a4650002 +34875ec,a4640004 +34875f0,94420866 +34875f4,3043ffff +34875f8,2c6300ce +34875fc,50600001 +3487600,240200cd +3487604,24420032 +3487608,3044ffff +348760c,3c028040 +3487610,94420868 +3487614,3043ffff +3487618,2c6300ce +348761c,50600001 +3487620,240200cd +3487624,24420032 +3487628,3043ffff +348762c,3c028040 +3487630,9442086a +3487634,3045ffff +3487638,2ca500ce +348763c,50a00001 +3487640,240200cd +3487644,24420032 +3487648,3042ffff +348764c,3c058041 +3487650,8ca5b0d8 +3487654,a4a40000 +3487658,a4a30002 +348765c,a4a20004 +3487660,3c058041 +3487664,8ca5b0d0 +3487668,a4a40000 +348766c,a4a30002 +3487670,3e00008 +3487674,a4a20004 +3487678,3c028011 +348767c,3442a5d0 +3487680,8c4200a0 +3487684,21302 +3487688,30420003 +348768c,21840 +3487690,621821 +3487694,3c028041 +3487698,24429e1c +348769c,621821 +34876a0,90640000 +34876a4,42600 +34876a8,90620001 +34876ac,21400 +34876b0,822021 +34876b4,90620002 +34876b8,21200 +34876bc,3e00008 +34876c0,821021 +34876c4,3c028041 +34876c8,9042b190 +34876cc,3e00008 +34876d0,2102b +34876d4,3c038041 +34876d8,9062b190 +34876dc,24420001 +34876e0,3e00008 +34876e4,a062b190 +34876e8,3c028041 +34876ec,9042b190 +34876f0,1040001b +34876f4,2442ffff +34876f8,27bdffd8 +34876fc,afbf0024 +3487700,afb10020 +3487704,afb0001c +3487708,3c038041 +348770c,a062b190 +3487710,3c108038 +3487714,3610e578 +3487718,24050014 +348771c,3c11801d +3487720,200f809 +3487724,3624aa30 +3487728,24020014 +348772c,afa20014 +3487730,afa00010 +3487734,26100130 +3487738,3825 +348773c,24060003 +3487740,3625aa30 +3487744,200f809 +3487748,262484a0 +348774c,8fbf0024 +3487750,8fb10020 +3487754,8fb0001c +3487758,3e00008 +348775c,27bd0028 +3487760,3e00008 +3487768,3e00008 +3487770,24020140 +3487774,3e00008 +3487778,a4821424 +348777c,27bdffe0 +3487780,afbf001c +3487784,afb10018 +3487788,afb00014 +348778c,808025 +3487790,8c8208c4 +3487794,24420001 +3487798,c102587 +348779c,ac8208c4 +34877a0,3c028041 +34877a4,9442b142 +34877a8,8e0308c4 +34877ac,1462001e +34877b0,8fbf001c +34877b4,920200b2 +34877b8,34420001 +34877bc,a20200b2 +34877c0,3c04801c +34877c4,348484a0 +34877c8,3c110001 +34877cc,918821 +34877d0,86221e1a +34877d4,ae020000 +34877d8,948200a4 +34877dc,a6020066 +34877e0,3c108009 +34877e4,3602d894 +34877e8,40f809 +34877ec,261005d4 +34877f0,3c04a34b +34877f4,200f809 +34877f8,3484e820 +34877fc,3c028011 +3487800,3442a5d0 +3487804,2403fff8 +3487808,a4431412 +348780c,240200a0 +3487810,a6221e1a +3487814,24020014 +3487818,a2221e15 +348781c,24020001 +3487820,a2221e5e +3487824,8fbf001c +3487828,8fb10018 +348782c,8fb00014 +3487830,3e00008 +3487834,27bd0020 +3487838,8c8200a0 +348783c,34423000 +3487840,ac8200a0 +3487844,3c028041 +3487848,9042b193 +348784c,304200ff +3487850,10400005 +3487854,52840 +3487858,3c028010 +348785c,451021 +3487860,94428cec +3487864,a4820034 +3487868,3e00008 +3487870,24020001 +3487874,3e00008 +3487878,a082003e +348787c,24020012 +3487880,2406ffff +3487884,24070016 +3487888,821821 +348788c,80630074 +3487890,54660004 +3487894,24420001 +3487898,822021 +348789c,3e00008 +34878a0,a0850074 +34878a4,1447fff9 +34878a8,821821 +34878ac,3e00008 +34878b4,862021 +34878b8,908200a8 +34878bc,a22825 +34878c0,3e00008 +34878c4,a08500a8 +34878c8,852021 +34878cc,908200bc +34878d0,21e00 +34878d4,31e03 +34878d8,4620001 +34878dc,1025 +34878e0,24420001 +34878e4,3e00008 +34878e8,a08200bc +34878ec,24020001 +34878f0,a082003d +34878f4,24020014 +34878f8,a08200cf +34878fc,24020140 +3487900,3e00008 +3487904,a4821424 +3487908,24020001 +348790c,a0820032 +3487910,a082003a +3487914,24020030 +3487918,a48213f4 +348791c,3e00008 +3487920,a0820033 +3487924,24020002 +3487928,a0820032 +348792c,24020001 +3487930,a082003a +3487934,a082003c +3487938,24020060 +348793c,a48213f4 +3487940,3e00008 +3487944,a0820033 +3487948,24020007 +348794c,3e00008 +3487950,a082007b +3487954,24020001 +3487958,a21004 +348795c,8c8500a4 +3487960,a22825 +3487964,3e00008 +3487968,ac8500a4 +348796c,27bdffe8 +3487970,afbf0014 +3487974,c101db5 +348797c,8fbf0014 +3487980,3e00008 +3487984,27bd0018 +3487988,24020010 +348798c,a0820082 +3487990,9082009a +3487994,2442000a +3487998,3e00008 +348799c,a082009a +34879a0,3c028041 +34879a4,9042b193 +34879a8,304200ff +34879ac,10400005 +34879b0,52840 +34879b4,3c028010 +34879b8,451021 +34879bc,94428cec +34879c0,a4820034 +34879c4,3e00008 +34879cc,3c028041 +34879d0,9042b192 +34879d4,1040000c +34879d8,3c028041 +34879dc,94820f06 +34879e0,34420040 +34879e4,a4820f06 +34879e8,3c028041 +34879ec,9042b191 +34879f0,54400009 +34879f4,94820f06 +34879f8,94820ef4 +34879fc,3042fb87 +3487a00,3e00008 +3487a04,a4820ef4 +3487a08,9042b191 +3487a0c,1040000c +3487a14,94820f06 +3487a18,34420080 +3487a1c,a4820f06 +3487a20,94820ef6 +3487a24,24038f00 +3487a28,431025 +3487a2c,a4820ef6 +3487a30,94820ee4 +3487a34,2403f000 +3487a38,431025 +3487a3c,a4820ee4 +3487a40,3e00008 +3487a48,2c8200cb +3487a4c,1040000b +3487a50,41880 +3487a54,641021 +3487a58,21080 +3487a5c,3c058041 +3487a60,24a5a0c8 +3487a64,a21021 +3487a68,80430000 +3487a6c,3182b +3487a70,31823 +3487a74,3e00008 +3487a78,431024 +3487a7c,3e00008 +3487a80,1025 +3487a84,27bdffe0 +3487a88,afbf001c +3487a8c,afb20018 +3487a90,afb10014 +3487a94,afb00010 +3487a98,808025 +3487a9c,3c128011 +3487aa0,3652a5d0 +3487aa4,c101e92 +3487aa8,2002025 +3487aac,2008825 +3487ab0,8c420008 +3487ab4,2002825 +3487ab8,40f809 +3487abc,2402025 +3487ac0,1622fff8 +3487ac4,408025 +3487ac8,2201025 +3487acc,8fbf001c +3487ad0,8fb20018 +3487ad4,8fb10014 +3487ad8,8fb00010 +3487adc,3e00008 +3487ae0,27bd0020 +3487ae4,27bdffe8 +3487ae8,afbf0014 +3487aec,8c82000c +3487af0,84860012 +3487af4,84850010 +3487af8,3c048011 +3487afc,40f809 +3487b00,3484a5d0 +3487b04,8fbf0014 +3487b08,3e00008 +3487b0c,27bd0018 +3487b10,3e00008 +3487b14,a01025 +3487b18,8082007d +3487b1c,21027 +3487b20,2102b +3487b24,3e00008 +3487b28,24420008 +3487b2c,8c8200a0 +3487b30,21182 +3487b34,30420007 +3487b38,10400005 +3487b40,38420001 +3487b44,2102b +3487b48,3e00008 +3487b4c,24420035 +3487b50,3e00008 +3487b54,24020054 +3487b58,8c8200a0 +3487b5c,210c2 +3487b60,30420007 +3487b64,10400005 +3487b6c,38420001 +3487b70,2102b +3487b74,3e00008 +3487b78,24420033 +3487b7c,3e00008 +3487b80,24020032 +3487b84,8c8200a0 +3487b88,30420007 +3487b8c,10400005 +3487b94,38420001 +3487b98,2102b +3487b9c,3e00008 +3487ba0,24420030 +3487ba4,3e00008 +3487ba8,24020004 +3487bac,8c8300a0 +3487bb0,31b82 +3487bb4,30630007 +3487bb8,10600005 +3487bbc,24040001 +3487bc0,14640004 +3487bc4,2402007b +3487bc8,3e00008 +3487bcc,24020060 +3487bd0,24020005 +3487bd4,3e00008 +3487bdc,8c8300a0 +3487be0,31b02 +3487be4,30630003 +3487be8,10600005 +3487bec,24040001 +3487bf0,14640004 +3487bf4,240200c7 +3487bf8,3e00008 +3487bfc,24020046 +3487c00,24020045 +3487c04,3e00008 +3487c0c,8c8200a0 +3487c10,21242 +3487c14,30420007 +3487c18,2102b +3487c1c,3e00008 +3487c20,24420037 +3487c24,8c8200a0 +3487c28,21502 +3487c2c,30420007 +3487c30,2c420002 +3487c34,2c420001 +3487c38,3e00008 +3487c3c,24420079 +3487c40,8c8200a0 +3487c44,21442 +3487c48,30420007 +3487c4c,2c420002 +3487c50,2c420001 +3487c54,3e00008 +3487c58,24420077 +3487c5c,9082003a +3487c60,2102b +3487c64,3e00008 +3487c68,244200b9 +3487c6c,8083007c +3487c70,2402ffff +3487c74,50620007 +3487c78,2402006b +3487c7c,80830094 +3487c80,28630006 +3487c84,10600003 +3487c88,2402006a +3487c8c,3e00008 +3487c90,24020003 +3487c94,3e00008 +3487c9c,8083007b +3487ca0,2402ffff +3487ca4,10620003 +3487cac,3e00008 +3487cb0,2402000c +3487cb4,3e00008 +3487cb8,2402003b +3487cbc,8c8300a0 +3487cc0,30630007 +3487cc4,14600002 +3487cc8,a01025 +3487ccc,2402004d +3487cd0,3e00008 +3487cd8,8c8300a0 +3487cdc,30630038 +3487ce0,14600002 +3487ce4,a01025 +3487ce8,2402004d +3487cec,3e00008 +3487cf4,8c8300a0 +3487cf8,3c040001 +3487cfc,3484c000 +3487d00,641824 +3487d04,14600002 +3487d08,a01025 +3487d0c,2402004d +3487d10,3e00008 +3487d18,94820eda +3487d1c,30420008 +3487d20,14400010 +3487d28,80830086 +3487d2c,2402001b +3487d30,1062000e +3487d38,80830087 +3487d3c,1062000d +3487d44,80830088 +3487d48,1062000c +3487d4c,2403001b +3487d50,80840089 +3487d54,1483000a +3487d58,a01025 +3487d5c,3e00008 +3487d60,240200c8 +3487d64,3e00008 +3487d68,240200c8 +3487d6c,3e00008 +3487d70,240200c8 +3487d74,3e00008 +3487d78,240200c8 +3487d7c,240200c8 +3487d80,3e00008 +3487d88,27bdffe8 +3487d8c,afbf0014 +3487d90,c1026e4 +3487d98,c101c3b +3487da0,c1024fd +3487da8,c10190d +3487db0,c102310 +3487db8,8fbf0014 +3487dbc,3e00008 +3487dc0,27bd0018 +3487dc4,27bdffe8 +3487dc8,afbf0014 +3487dcc,c101aa6 +3487dd4,c100fa0 +3487ddc,c102233 +3487de4,c101cb7 +3487dec,c10142d +3487df4,c1018f4 +3487dfc,8fbf0014 +3487e00,3e00008 +3487e04,27bd0018 +3487e08,27bdffe8 +3487e0c,afbf0014 +3487e10,afb00010 +3487e14,3c10801c +3487e18,361084a0 +3487e1c,8e040000 +3487e20,c101195 +3487e24,248402a8 +3487e28,8e040000 +3487e2c,c102591 +3487e30,248402a8 +3487e34,8fbf0014 +3487e38,8fb00010 +3487e3c,3e00008 +3487e40,27bd0018 +3487e44,27bdffe8 +3487e48,afbf0014 +3487e4c,c1018fb +3487e54,c1026df +3487e5c,c102323 +3487e64,c101427 +3487e6c,8fbf0014 +3487e70,3e00008 +3487e74,27bd0018 +3487e78,3c02801c +3487e7c,344284a0 +3487e80,3c030001 +3487e84,431021 +3487e88,84430988 +3487e8c,14600022 +3487e90,3c02801c +3487e94,344284a0 +3487e98,3c030001 +3487e9c,431021 +3487ea0,84420992 +3487ea4,14400014 +3487ea8,21840 +3487eac,3c028011 +3487eb0,3442a5d0 +3487eb4,8c420004 +3487eb8,14400009 +3487ebc,3c028011 +3487ec0,3442a5d0 +3487ec4,8c4300a0 +3487ec8,3c020001 +3487ecc,3442c007 +3487ed0,621824 +3487ed4,14600026 +3487ed8,24020001 +3487edc,3c028011 +3487ee0,3442a5d0 +3487ee4,8c4200a0 +3487ee8,21382 +3487eec,30420007 +3487ef0,3e00008 +3487ef4,2102b +3487ef8,621821 +3487efc,3c028011 +3487f00,3442a5d0 +3487f04,8c4200a0 +3487f08,621006 +3487f0c,30420007 +3487f10,3e00008 +3487f14,2102b +3487f18,344284a0 +3487f1c,3c040001 +3487f20,441021 +3487f24,84440992 +3487f28,1480000a +3487f2c,3c028011 +3487f30,24020003 +3487f34,14620007 +3487f38,3c028011 +3487f3c,3442a5d0 +3487f40,8c42009c +3487f44,3c03000c +3487f48,431024 +3487f4c,3e00008 +3487f50,2102b +3487f54,3442a5d0 +3487f58,9442009c +3487f5c,42080 +3487f60,2463ffff +3487f64,832021 +3487f68,821007 +3487f6c,30420001 +3487f70,3e00008 +3487f78,27bdffe0 +3487f7c,afbf001c +3487f80,3c028040 +3487f84,9042088b +3487f88,10400010 +3487f8c,3c028040 +3487f90,2406000c +3487f94,3c028041 +3487f98,8c45b194 +3487f9c,c102456 +3487fa0,27a40010 +3487fa4,3c028011 +3487fa8,97a30010 +3487fac,a4435dd2 +3487fb0,93a30012 +3487fb4,a0435dd4 +3487fb8,97a30010 +3487fbc,a4435dda +3487fc0,93a30012 +3487fc4,a0435ddc +3487fc8,3c028040 +3487fcc,9042088c +3487fd0,10400010 +3487fd4,8fbf001c +3487fd8,2406000a +3487fdc,3c028041 +3487fe0,8c45b194 +3487fe4,c102456 +3487fe8,27a40010 +3487fec,3c028011 +3487ff0,97a30010 +3487ff4,a4435dce +3487ff8,93a30012 +3487ffc,a0435dd0 +3488000,97a30010 +3488004,a4435dd6 +3488008,93a30012 +348800c,a0435dd8 +3488010,8fbf001c +3488014,3e00008 +3488018,27bd0020 +348801c,3c02801d +3488020,3442aa30 +3488024,8c420678 +3488028,10400063 +3488030,8c430130 +3488034,10600060 +348803c,8c4201c8 +3488040,2c43001f +3488044,1060005c +348804c,27bdffd8 +3488050,afbf0024 +3488054,afb10020 +3488058,afb0001c +348805c,280c0 +3488060,2028023 +3488064,108080 +3488068,2028023 +348806c,108100 +3488070,3c028011 +3488074,2028021 +3488078,3c028040 +348807c,9042088d +3488080,10400018 +3488084,2610572c +3488088,3c118041 +348808c,24060006 +3488090,8e25b194 +3488094,c102456 +3488098,27a40010 +348809c,93a20010 +34880a0,a2020192 +34880a4,93a20011 +34880a8,a2020193 +34880ac,93a20012 +34880b0,a2020194 +34880b4,8e25b194 +34880b8,24060006 +34880bc,24a5000c +34880c0,c102456 +34880c4,27a40010 +34880c8,93a20010 +34880cc,a202019a +34880d0,93a20011 +34880d4,a202019b +34880d8,93a20012 +34880dc,1000000c +34880e0,a202019c +34880e4,3c028040 +34880e8,9044087e +34880ec,a2040192 +34880f0,2442087e +34880f4,90430001 +34880f8,a2030193 +34880fc,90420002 +3488100,a2020194 +3488104,a204019a +3488108,a203019b +348810c,a202019c +3488110,3c028040 +3488114,9042088e +3488118,10400018 +348811c,3c028040 +3488120,3c118041 +3488124,24060005 +3488128,8e25b194 +348812c,c102456 +3488130,27a40010 +3488134,93a20010 +3488138,a2020196 +348813c,93a20011 +3488140,a2020197 +3488144,93a20012 +3488148,a2020198 +348814c,8e25b194 +3488150,24060005 +3488154,24a5000a +3488158,c102456 +348815c,27a40010 +3488160,93a20010 +3488164,a202019e +3488168,93a20011 +348816c,a202019f +3488170,93a20012 +3488174,1000000b +3488178,a20201a0 +348817c,90440881 +3488180,a2040196 +3488184,24420881 +3488188,90430001 +348818c,a2030197 +3488190,90420002 +3488194,a2020198 +3488198,a204019e +348819c,a203019f +34881a0,a20201a0 +34881a4,8fbf0024 +34881a8,8fb10020 +34881ac,8fb0001c +34881b0,3e00008 +34881b4,27bd0028 +34881b8,3e00008 +34881c0,27bdffd0 +34881c4,afbf002c +34881c8,afb20028 +34881cc,afb10024 +34881d0,afb00020 +34881d4,3c028040 +34881d8,90430884 +34881dc,240200fa +34881e0,14620008 +34881e4,24100001 +34881e8,3c028040 +34881ec,24420884 +34881f0,90500001 +34881f4,90420002 +34881f8,2028025 +34881fc,321000ff +3488200,10802b +3488204,3c028040 +3488208,90430887 +348820c,240200fa +3488210,14620008 +3488214,24110001 +3488218,3c028040 +348821c,24420887 +3488220,90510001 +3488224,90420002 +3488228,2228825 +348822c,323100ff +3488230,11882b +3488234,3c128041 +3488238,24060009 +348823c,8e45b194 +3488240,c102456 +3488244,27a40010 +3488248,8e45b194 +348824c,24060009 +3488250,24a50012 +3488254,c102456 +3488258,27a40014 +348825c,24060007 +3488260,8e45b194 +3488264,c102456 +3488268,27a40018 +348826c,8e45b194 +3488270,24060007 +3488274,24a5000e +3488278,c102456 +348827c,27a4001c +3488280,3c02801c +3488284,344284a0 +3488288,8c421c4c +348828c,10400064 +3488290,8fbf002c +3488294,240500da +3488298,3c068011 +348829c,24c65c3c +34882a0,3c088040 +34882a4,3c078040 +34882a8,3c0a8040 +34882ac,254c0887 +34882b0,3c098040 +34882b4,252b0884 +34882b8,8c430130 +34882bc,50600055 +34882c0,8c420124 +34882c4,84430000 +34882c8,54650052 +34882cc,8c420124 +34882d0,8c43016c +34882d4,320c0 +34882d8,832023 +34882dc,42080 +34882e0,832023 +34882e4,42100 +34882e8,2484faf0 +34882ec,862021 +34882f0,8c4d0170 +34882f4,d18c0 +34882f8,6d1823 +34882fc,31880 +3488300,6d1823 +3488304,31900 +3488308,2463faf0 +348830c,910d088f +3488310,11a0000e +3488314,661821 +3488318,97ae0010 +348831c,a48e0192 +3488320,93ad0012 +3488324,a08d0194 +3488328,a46e0192 +348832c,a06d0194 +3488330,97ae0014 +3488334,a48e019a +3488338,93ad0016 +348833c,a08d019c +3488340,a46e019a +3488344,10000012 +3488348,a06d019c +348834c,12000011 +3488350,90ed0890 +3488354,912f0884 +3488358,a08f0192 +348835c,916e0001 +3488360,a08e0193 +3488364,916d0002 +3488368,a08d0194 +348836c,a06f0192 +3488370,a06e0193 +3488374,a06d0194 +3488378,a08f019a +348837c,a08e019b +3488380,a08d019c +3488384,a06f019a +3488388,a06e019b +348838c,a06d019c +3488390,90ed0890 +3488394,11a0000d +3488398,97ae0018 +348839c,a48e0196 +34883a0,93ad001a +34883a4,a08d0198 +34883a8,a46e0196 +34883ac,a06d0198 +34883b0,97ae001c +34883b4,a48e019e +34883b8,93ad001e +34883bc,a08d01a0 +34883c0,a46e019e +34883c4,10000012 +34883c8,a06d01a0 +34883cc,52200011 +34883d0,8c420124 +34883d4,914f0887 +34883d8,a08f0196 +34883dc,918e0001 +34883e0,a08e0197 +34883e4,918d0002 +34883e8,a08d0198 +34883ec,a06f0196 +34883f0,a06e0197 +34883f4,a06d0198 +34883f8,a08f019e +34883fc,a08e019f +3488400,a08d01a0 +3488404,a06f019e +3488408,a06e019f +348840c,a06d01a0 +3488410,8c420124 +3488414,5440ffa9 +3488418,8c430130 +348841c,8fbf002c +3488420,8fb20028 +3488424,8fb10024 +3488428,8fb00020 +348842c,3e00008 +3488430,27bd0030 +3488434,27bdffd8 +3488438,afbf001c +348843c,f7b40020 +3488440,3c028040 +3488444,9042088f +3488448,1040000a +348844c,46006506 +3488450,24060009 +3488454,3c028041 +3488458,8c45b194 +348845c,c102456 +3488460,27a40010 +3488464,93a20010 +3488468,93a30011 +348846c,10000006 +3488470,93a40012 +3488474,3c048040 +3488478,90820884 +348847c,24840884 +3488480,90830001 +3488484,90840002 +3488488,240500fa +348848c,14450043 +3488490,642825 +3488494,14a00041 +348849c,3c028041 +34884a0,c4409e68 +34884a4,4600a002 +34884a8,3c028041 +34884ac,c4429e6c +34884b0,46020000 +34884b4,3c028041 +34884b8,c4429e70 +34884bc,4600103e +34884c4,45030005 +34884c8,46020001 +34884cc,4600000d +34884d0,44020000 +34884d4,10000006 +34884d8,304200ff +34884dc,4600000d +34884e0,44020000 +34884e4,3c038000 +34884e8,431025 +34884ec,304200ff +34884f0,3c038041 +34884f4,c4609e74 +34884f8,4600a002 +34884fc,3c038041 +3488500,c4629e6c +3488504,46020000 +3488508,3c038041 +348850c,c4629e70 +3488510,4600103e +3488518,45030005 +348851c,46020001 +3488520,4600000d +3488524,44030000 +3488528,10000006 +348852c,306300ff +3488530,4600000d +3488534,44030000 +3488538,3c048000 +348853c,641825 +3488540,306300ff +3488544,3c048041 +3488548,c4809e78 +348854c,4600a002 +3488550,3c048041 +3488554,c4829e7c +3488558,46020000 +348855c,3c048041 +3488560,c4829e70 +3488564,4600103e +348856c,45030005 +3488570,46020001 +3488574,4600000d +3488578,44040000 +348857c,10000040 +3488580,308400ff +3488584,4600000d +3488588,44040000 +348858c,3c058000 +3488590,852025 +3488594,1000003a +3488598,308400ff +348859c,44820000 +34885a4,46800020 +34885a8,46140002 +34885ac,3c028041 +34885b0,c4429e70 +34885b4,4600103e +34885bc,45030005 +34885c0,46020001 +34885c4,4600000d +34885c8,44020000 +34885cc,10000006 +34885d0,304200ff +34885d4,4600000d +34885d8,44020000 +34885dc,3c058000 +34885e0,451025 +34885e4,304200ff +34885e8,44830000 +34885f0,46800020 +34885f4,46140002 +34885f8,3c038041 +34885fc,c4629e70 +3488600,4600103e +3488608,45030005 +348860c,46020001 +3488610,4600000d +3488614,44030000 +3488618,10000006 +348861c,306300ff +3488620,4600000d +3488624,44030000 +3488628,3c058000 +348862c,651825 +3488630,306300ff +3488634,44840000 +348863c,46800020 +3488640,46140002 +3488644,3c048041 +3488648,c4829e70 +348864c,4600103e +3488654,45030005 +3488658,46020001 +348865c,4600000d +3488660,44040000 +3488664,10000006 +3488668,308400ff +348866c,4600000d +3488670,44040000 +3488674,3c058000 +3488678,852025 +348867c,308400ff +3488680,21600 +3488684,42200 +3488688,441025 +348868c,31c00 +3488690,431025 +3488694,344200ff +3488698,8fbf001c +348869c,d7b40020 +34886a0,3e00008 +34886a4,27bd0028 +34886a8,27bdffd8 +34886ac,afbf0024 +34886b0,afb20020 +34886b4,afb1001c +34886b8,afb00018 +34886bc,3c02801c +34886c0,344284a0 +34886c4,90421cda +34886c8,24030004 +34886cc,10430015 +34886d0,2c430005 +34886d4,50600006 +34886d8,2442fffb +34886dc,24030002 +34886e0,50430008 +34886e4,3c028040 +34886e8,10000013 +34886ec,3c028040 +34886f0,304200fb +34886f4,54400010 +34886f8,3c028040 +34886fc,10000005 +3488700,3c028040 +3488704,90500891 +3488708,3c028040 +348870c,1000000d +3488710,90510892 +3488714,90500893 +3488718,3c028040 +348871c,10000009 +3488720,90510894 +3488724,3c028040 +3488728,90500895 +348872c,3c028040 +3488730,10000004 +3488734,90510896 +3488738,90500897 +348873c,3c028040 +3488740,90510898 +3488744,2111025 +3488748,1040005b +348874c,8fbf0024 +3488750,3c128041 +3488754,2406000e +3488758,8e45b194 +348875c,c102456 +3488760,27a40010 +3488764,2406000c +3488768,8e45b194 +348876c,c102456 +3488770,27a40014 +3488774,1200000a +3488778,3c02801c +348877c,344284a0 +3488780,90431cda +3488784,318c0 +3488788,3c02800f +348878c,431021 +3488790,97a30010 +3488794,a4438214 +3488798,93a30012 +348879c,a0438216 +34887a0,1220000a +34887a4,3c02801c +34887a8,344284a0 +34887ac,90431cda +34887b0,318c0 +34887b4,3c02800f +34887b8,431021 +34887bc,97a30014 +34887c0,a4438218 +34887c4,93a30016 +34887c8,a043821a +34887cc,12000010 +34887d0,3c02801d +34887d4,3c02801c +34887d8,344284a0 +34887dc,97a30010 +34887e0,a4431cf0 +34887e4,93a30012 +34887e8,a0431cf2 +34887ec,97a30010 +34887f0,a4431d04 +34887f4,93a30012 +34887f8,a0431d06 +34887fc,97a30010 +3488800,a4431d18 +3488804,93a30012 +3488808,a0431d1a +348880c,3c02801d +3488810,3442aa30 +3488814,8c42067c +3488818,10400027 +348881c,8fbf0024 +3488820,8c430130 +3488824,10600025 +3488828,8fb20020 +348882c,12000010 +3488830,24430234 +3488834,93a40010 +3488838,44840000 +3488840,46800020 +3488844,e4400234 +3488848,93a20011 +348884c,44820000 +3488854,46800020 +3488858,e4600004 +348885c,93a20012 +3488860,44820000 +3488868,46800020 +348886c,e4600008 +3488870,12200011 +3488874,8fbf0024 +3488878,93a20014 +348887c,44820000 +3488884,46800020 +3488888,e4600010 +348888c,93a20015 +3488890,44820000 +3488898,46800020 +348889c,e4600014 +34888a0,93a20016 +34888a4,44820000 +34888ac,46800020 +34888b0,e4600018 +34888b4,8fbf0024 +34888b8,8fb20020 +34888bc,8fb1001c +34888c0,8fb00018 +34888c4,3e00008 +34888c8,27bd0028 +34888cc,27bdffe8 +34888d0,afbf0014 +34888d4,3c038041 +34888d8,8c62b194 +34888dc,24420001 +34888e0,c101fde +34888e4,ac62b194 +34888e8,c102007 +34888f0,c102070 +34888f8,c1021aa +3488900,8fbf0014 +3488904,3e00008 +3488908,27bd0018 +348890c,27bdffe8 +3488910,afbf0014 +3488914,801025 +3488918,2c430193 +348891c,10600006 +3488920,a02025 +3488924,210c0 +3488928,3c03800f +348892c,34638ff8 +3488930,10000008 +3488934,431021 +3488938,2442fe6e +348893c,21080 +3488940,2403fff8 +3488944,431024 +3488948,3c038040 +348894c,24630c9c +3488950,621021 +3488954,8c450000 +3488958,8c460004 +348895c,3c028000 +3488960,24420df0 +3488964,40f809 +3488968,c53023 +348896c,8fbf0014 +3488970,3e00008 +3488974,27bd0018 +3488978,27bdffe8 +348897c,afbf0014 +3488980,801025 +3488984,a02025 +3488988,a4450000 +348898c,c102243 +3488990,8c450004 +3488994,8fbf0014 +3488998,3e00008 +348899c,27bd0018 +34889a0,27bdffe8 +34889a4,afbf0014 +34889a8,afb00010 +34889ac,3c028041 +34889b0,2442c204 +34889b4,24450040 +34889b8,94430000 +34889bc,1064000b +34889c0,408025 +34889c4,54600006 +34889c8,24420008 +34889cc,802825 +34889d0,c10225e +34889d4,402025 +34889d8,10000005 +34889dc,2001025 +34889e0,5445fff6 +34889e4,94430000 +34889e8,8025 +34889ec,2001025 +34889f0,8fbf0014 +34889f4,8fb00010 +34889f8,3e00008 +34889fc,27bd0018 +3488a00,3c03801c +3488a04,346384a0 +3488a08,8c620000 +3488a0c,8c860004 +3488a10,8c4502d0 +3488a14,24a70008 +3488a18,ac4702d0 +3488a1c,3c02db06 +3488a20,24420018 +3488a24,aca20000 +3488a28,aca60004 +3488a2c,8c650000 +3488a30,8c840004 +3488a34,8ca302c0 +3488a38,24660008 +3488a3c,aca602c0 +3488a40,ac620000 +3488a44,3e00008 +3488a48,ac640004 +3488a4c,27bdffe0 +3488a50,afbf0014 +3488a54,f7b40018 +3488a58,3c02800a +3488a5c,3442a78c +3488a60,40f809 +3488a64,46006506 +3488a68,2442000c +3488a6c,2025 +3488a70,1000000a +3488a74,2405000c +3488a78,c4600000 +3488a7c,46140002 +3488a80,e4600000 +3488a84,24630004 +3488a88,5462fffc +3488a8c,c4600000 +3488a90,24840004 +3488a94,10850003 +3488a98,24420010 +3488a9c,1000fff6 +3488aa0,2443fff4 +3488aa4,8fbf0014 +3488aa8,d7b40018 +3488aac,3e00008 +3488ab0,27bd0020 +3488ab4,27bdffd8 +3488ab8,afbf0024 +3488abc,afb30020 +3488ac0,afb2001c +3488ac4,afb10018 +3488ac8,afb00014 +3488acc,809825 +3488ad0,a09025 +3488ad4,c08025 +3488ad8,3c118002 +3488adc,26222438 +3488ae0,3025 +3488ae4,2002825 +3488ae8,40f809 +3488aec,2402025 +3488af0,26312554 +3488af4,3025 +3488af8,2002825 +3488afc,220f809 +3488b00,2402025 +3488b04,2602825 +3488b08,3c028005 +3488b0c,244270c0 +3488b10,40f809 +3488b14,2002025 +3488b18,8fbf0024 +3488b1c,8fb30020 +3488b20,8fb2001c +3488b24,8fb10018 +3488b28,8fb00014 +3488b2c,3e00008 +3488b30,27bd0028 +3488b34,44860000 +3488b38,24020063 +3488b3c,54820005 +3488b40,84a20000 +3488b44,3c028041 +3488b48,c4429e84 +3488b4c,3e00008 +3488b50,46020002 +3488b54,240300f1 +3488b58,54430008 +3488b5c,24030015 +3488b60,24020046 +3488b64,1082000d +3488b68,2402002f +3488b6c,1482000e +3488b70,3c028041 +3488b74,3e00008 +3488b78,c4409e80 +3488b7c,1443000a +3488b80,24020011 +3488b84,90a3001d +3488b88,14620007 +3488b8c,3c028041 +3488b90,c4429e84 +3488b94,3e00008 +3488b98,46020002 +3488b9c,3c028041 +3488ba0,3e00008 +3488ba4,c4409e80 +3488ba8,3e00008 +3488bb0,27bdffd8 +3488bb4,afbf001c +3488bb8,afb20018 +3488bbc,afb10014 +3488bc0,afb00010 +3488bc4,f7b40020 +3488bc8,48202 +3488bcc,afa40028 +3488bd0,a08825 +3488bd4,c09025 +3488bd8,4487a000 +3488bdc,108600 +3488be0,108603 +3488be4,c102268 +3488be8,42402 +3488bec,c102280 +3488bf0,402025 +3488bf4,4406a000 +3488bf8,2202825 +3488bfc,c1022cd +3488c00,2002025 +3488c04,c102293 +3488c08,46000306 +3488c0c,2604ffff +3488c10,2403025 +3488c14,2202825 +3488c18,42600 +3488c1c,c1022ad +3488c20,42603 +3488c24,8fbf001c +3488c28,8fb20018 +3488c2c,8fb10014 +3488c30,8fb00010 +3488c34,d7b40020 +3488c38,3e00008 +3488c3c,27bd0028 +3488c40,27bdffe0 +3488c44,afbf001c +3488c48,afb10018 +3488c4c,afb00014 +3488c50,3c108041 +3488c54,2610c204 +3488c58,26110040 +3488c5c,a6000000 +3488c60,c1026e9 +3488c64,24041e70 +3488c68,ae020004 +3488c6c,26100008 +3488c70,5611fffb +3488c74,a6000000 +3488c78,8fbf001c +3488c7c,8fb10018 +3488c80,8fb00014 +3488c84,3e00008 +3488c88,27bd0020 +3488c8c,3c028041 +3488c90,a440c204 +3488c94,2442c204 +3488c98,a4400008 +3488c9c,a4400010 +3488ca0,a4400018 +3488ca4,a4400020 +3488ca8,a4400028 +3488cac,a4400030 +3488cb0,3e00008 +3488cb4,a4400038 +3488cb8,27bdffe8 +3488cbc,afbf0014 +3488cc0,afb00010 +3488cc4,afa5001c +3488cc8,10a0000e +3488ccc,afa60020 +3488cd0,808025 +3488cd4,93a40023 +3488cd8,50800002 +3488cdc,97a40020 +3488ce0,3084ffff +3488ce4,c101ea1 +3488cec,c101e92 +3488cf0,402025 +3488cf4,94430004 +3488cf8,a6030000 +3488cfc,80420006 +3488d00,a2020002 +3488d04,8fbf0014 +3488d08,8fb00010 +3488d0c,3e00008 +3488d10,27bd0018 +3488d14,27bdffe0 +3488d18,afbf001c +3488d1c,afb00018 +3488d20,808025 +3488d24,30e700ff +3488d28,90c600a5 +3488d2c,c101998 +3488d30,27a40010 +3488d34,8fa50010 +3488d38,8fa60014 +3488d3c,c10232e +3488d40,2002025 +3488d44,8fbf001c +3488d48,8fb00018 +3488d4c,3e00008 +3488d50,27bd0020 +3488d54,27bdffd8 +3488d58,afbf0024 +3488d5c,afb10020 +3488d60,afb0001c +3488d64,808025 +3488d68,a08825 +3488d6c,3c028041 +3488d70,8c429e28 +3488d74,afa20010 +3488d78,3825 +3488d7c,a03025 +3488d80,802825 +3488d84,c102345 +3488d88,27a40010 +3488d8c,3c028041 +3488d90,8c479e88 +3488d94,2203025 +3488d98,2002825 +3488d9c,c1022ec +3488da0,8fa40010 +3488da4,8fbf0024 +3488da8,8fb10020 +3488dac,8fb0001c +3488db0,3e00008 +3488db4,27bd0028 +3488db8,27bdffd8 +3488dbc,afbf0024 +3488dc0,afb10020 +3488dc4,afb0001c +3488dc8,808025 +3488dcc,9083001d +3488dd0,24020011 +3488dd4,10620007 +3488dd8,a08825 +3488ddc,3c028001 +3488de0,24423268 +3488de4,40f809 +3488dec,10000010 +3488df0,8fbf0024 +3488df4,3c028041 +3488df8,8c429e2c +3488dfc,afa20010 +3488e00,3825 +3488e04,a03025 +3488e08,802825 +3488e0c,c102345 +3488e10,27a40010 +3488e14,3c028041 +3488e18,8c479e88 +3488e1c,2203025 +3488e20,2002825 +3488e24,c1022ec +3488e28,8fa40010 +3488e2c,8fbf0024 +3488e30,8fb10020 +3488e34,8fb0001c +3488e38,3e00008 +3488e3c,27bd0028 +3488e40,27bdffd8 +3488e44,afbf0024 +3488e48,afb10020 +3488e4c,afb0001c +3488e50,808025 +3488e54,a08825 +3488e58,3c028041 +3488e5c,8c429e30 +3488e60,afa20010 +3488e64,2407004f +3488e68,a03025 +3488e6c,802825 +3488e70,c102345 +3488e74,27a40010 +3488e78,3c028041 +3488e7c,8c479e8c +3488e80,2203025 +3488e84,2002825 +3488e88,c1022ec +3488e8c,8fa40010 +3488e90,8fbf0024 +3488e94,8fb10020 +3488e98,8fb0001c +3488e9c,3e00008 +3488ea0,27bd0028 +3488ea4,27bdffd8 +3488ea8,afbf0024 +3488eac,afb10020 +3488eb0,afb0001c +3488eb4,808025 +3488eb8,a08825 +3488ebc,3c028041 +3488ec0,8c429e34 +3488ec4,afa20010 +3488ec8,3825 +3488ecc,a03025 +3488ed0,802825 +3488ed4,c102345 +3488ed8,27a40010 +3488edc,3c028041 +3488ee0,8c479e90 +3488ee4,2203025 +3488ee8,2002825 +3488eec,c1022ec +3488ef0,8fa40010 +3488ef4,8fbf0024 +3488ef8,8fb10020 +3488efc,8fb0001c +3488f00,3e00008 +3488f04,27bd0028 +3488f08,27bdffd8 +3488f0c,afbf0024 +3488f10,afb10020 +3488f14,afb0001c +3488f18,808025 +3488f1c,a08825 +3488f20,3c028041 +3488f24,8c429e38 +3488f28,afa20010 +3488f2c,2407000c +3488f30,a03025 +3488f34,802825 +3488f38,c102345 +3488f3c,27a40010 +3488f40,3c028041 +3488f44,8c479e94 +3488f48,2203025 +3488f4c,2002825 +3488f50,c1022ec +3488f54,8fa40010 +3488f58,8fbf0024 +3488f5c,8fb10020 +3488f60,8fb0001c +3488f64,3e00008 +3488f68,27bd0028 +3488f6c,27bdffd0 +3488f70,afbf002c +3488f74,afb10028 +3488f78,afb00024 +3488f7c,808025 +3488f80,afa00010 +3488f84,afa00014 +3488f88,9482001c +3488f8c,24030001 +3488f90,14430008 +3488f94,a08825 +3488f98,24070015 +3488f9c,90a600a5 +3488fa0,802825 +3488fa4,c101998 +3488fa8,27a40010 +3488fac,10000012 +3488fb0,afa00018 +3488fb4,24030007 +3488fb8,14430008 +3488fbc,24030a0c +3488fc0,24070058 +3488fc4,90a600a5 +3488fc8,802825 +3488fcc,c101998 +3488fd0,27a40010 +3488fd4,10000008 +3488fd8,afa00018 +3488fdc,54430006 +3488fe0,afa00018 +3488fe4,3c050010 +3488fe8,34a5010a +3488fec,c101970 +3488ff0,27a40010 +3488ff4,afa00018 +3488ff8,8fa50010 +3488ffc,8fa60014 +3489000,c10232e +3489004,27a40018 +3489008,97a20018 +348900c,10400008 +3489010,2203025 +3489014,3c028041 +3489018,8c479e80 +348901c,2002825 +3489020,c1022ec +3489024,8fa40018 +3489028,10000005 +348902c,8fbf002c +3489030,2002825 +3489034,c1022ad +3489038,82040141 +348903c,8fbf002c +3489040,8fb10028 +3489044,8fb00024 +3489048,3e00008 +348904c,27bd0030 +3489050,27bdffd0 +3489054,afbf002c +3489058,afb10028 +348905c,afb00024 +3489060,808025 +3489064,afa00010 +3489068,afa00014 +348906c,9482001c +3489070,10400004 +3489074,a08825 +3489078,24030005 +348907c,54430007 +3489080,afa00018 +3489084,24070034 +3489088,922600a5 +348908c,2002825 +3489090,c101998 +3489094,27a40010 +3489098,afa00018 +348909c,8fa50010 +34890a0,8fa60014 +34890a4,c10232e +34890a8,27a40018 +34890ac,97a20018 +34890b0,10400008 +34890b4,2203025 +34890b8,3c028041 +34890bc,8c479e80 +34890c0,2002825 +34890c4,c1022ec +34890c8,8fa40018 +34890cc,10000005 +34890d0,8fbf002c +34890d4,2002825 +34890d8,c1022ad +34890dc,82040147 +34890e0,8fbf002c +34890e4,8fb10028 +34890e8,8fb00024 +34890ec,3e00008 +34890f0,27bd0030 +34890f4,27bdffd8 +34890f8,afbf0024 +34890fc,afb10020 +3489100,afb0001c +3489104,808025 +3489108,a08825 +348910c,3c028041 +3489110,8c429e28 +3489114,afa20010 +3489118,2407003e +348911c,a03025 +3489120,802825 +3489124,c102345 +3489128,27a40010 +348912c,3c028041 +3489130,8c479e80 +3489134,2203025 +3489138,2002825 +348913c,c1022ec +3489140,8fa40010 +3489144,8fbf0024 +3489148,8fb10020 +348914c,8fb0001c +3489150,3e00008 +3489154,27bd0028 +3489158,801025 +348915c,14c00002 +3489160,a6001b +3489164,7000d +3489168,2810 +348916c,3812 +3489170,3c03aaaa +3489174,3463aaab +3489178,e30019 +348917c,1810 +3489180,31882 +3489184,32040 +3489188,831821 +348918c,31840 +3489190,e31823 +3489194,44850000 +3489198,4a10004 +348919c,468000a1 +34891a0,3c048041 +34891a4,d4809ea0 +34891a8,46201080 +34891ac,462010a0 +34891b0,44860000 +34891b4,4c10004 +34891b8,46800021 +34891bc,3c048041 +34891c0,d4849ea0 +34891c4,46240000 +34891c8,46200020 +34891cc,46001083 +34891d0,3c048041 +34891d4,c4849e98 +34891d8,46022101 +34891dc,24640001 +34891e0,3c068041 +34891e4,24c69e3c +34891e8,32840 +34891ec,a32821 +34891f0,c52821 +34891f4,90a50001 +34891f8,44850000 +3489200,46800020 +3489204,46040002 +3489208,42840 +348920c,a42821 +3489210,c53021 +3489214,90c50001 +3489218,44853000 +3489220,468031a0 +3489224,46023182 +3489228,46060000 +348922c,3c058041 +3489230,c4a69e9c +3489234,4600303e +348923c,45030005 +3489240,46060001 +3489244,4600000d +3489248,44050000 +348924c,10000006 +3489250,30a700ff +3489254,4600000d +3489258,44050000 +348925c,3c068000 +3489260,a62825 +3489264,30a700ff +3489268,3c068041 +348926c,24c69e3c +3489270,32840 +3489274,a32821 +3489278,c52821 +348927c,90a50002 +3489280,44850000 +3489288,46800020 +348928c,46040002 +3489290,42840 +3489294,a42821 +3489298,c53021 +348929c,90c50002 +34892a0,44853000 +34892a8,468031a0 +34892ac,46023182 +34892b0,46060000 +34892b4,3c058041 +34892b8,c4a69e9c +34892bc,4600303e +34892c4,45030005 +34892c8,46060001 +34892cc,4600000d +34892d0,44050000 +34892d4,10000006 +34892d8,30a600ff +34892dc,4600000d +34892e0,44050000 +34892e4,3c068000 +34892e8,a62825 +34892ec,30a600ff +34892f0,32840 +34892f4,a31821 +34892f8,3c088041 +34892fc,25089e3c +3489300,681821 +3489304,90650000 +3489308,44850000 +3489310,46800020 +3489314,46040002 +3489318,41840 +348931c,641821 +3489320,681821 +3489324,90630000 +3489328,44832000 +3489330,46802120 +3489334,46022082 +3489338,46020000 +348933c,3c038041 +3489340,c4629e9c +3489344,4600103e +348934c,45030005 +3489350,46020001 +3489354,4600000d +3489358,44030000 +348935c,10000006 +3489360,a0430000 +3489364,4600000d +3489368,44030000 +348936c,3c048000 +3489370,641825 +3489374,a0430000 +3489378,a0470001 +348937c,3e00008 +3489380,a0460002 +3489384,3c028011 +3489388,3442a5d0 +348938c,24030140 +3489390,a4431424 +3489394,90440032 +3489398,41840 +348939c,641821 +34893a0,31900 +34893a4,3e00008 +34893a8,a0430033 +34893ac,24a20002 +34893b0,24a50082 +34893b4,24065700 +34893b8,24070004 +34893bc,9443fffe +34893c0,50660008 +34893c4,24420004 +34893c8,50600006 +34893cc,24420004 +34893d0,94430000 +34893d4,2c630004 +34893d8,54600001 +34893dc,a4470000 +34893e0,24420004 +34893e4,5445fff6 +34893e8,9443fffe +34893ec,3e00008 +34893f4,27bdffe8 +34893f8,afbf0014 +34893fc,c1026e9 +3489400,24040400 +3489404,3c038041 +3489408,ac62b198 +348940c,3c038041 +3489410,ac62b19c +3489414,8fbf0014 +3489418,3e00008 +348941c,27bd0018 +3489420,80820000 +3489424,10400026 +3489428,24870001 +348942c,3c038041 +3489430,8c68b198 +3489434,25080400 +3489438,3c038041 +348943c,8c63b19c +3489440,5825 +3489444,3c0aff00 +3489448,254a0fff +348944c,30c60fff +3489450,240df000 +3489454,3c098041 +3489458,2529a050 +348945c,240c0001 +3489460,68202b +3489464,54800005 +3489468,a0620000 +348946c,11600014 +3489470,3c028041 +3489474,3e00008 +3489478,ac43b19c +348947c,30a40fff +3489480,42300 +3489484,8c620000 +3489488,4a1024 +348948c,441025 +3489490,4d1024 +3489494,461025 +3489498,ac620000 +348949c,24630004 +34894a0,95220004 +34894a4,a22821 +34894a8,24e70001 +34894ac,80e2ffff +34894b0,1440ffeb +34894b4,1805825 +34894b8,3c028041 +34894bc,ac43b19c +34894c0,3e00008 +34894c8,27bdffb8 +34894cc,afbf0044 +34894d0,afbe0040 +34894d4,afb7003c +34894d8,afb60038 +34894dc,afb50034 +34894e0,afb40030 +34894e4,afb3002c +34894e8,afb20028 +34894ec,afb10024 +34894f0,afb00020 +34894f4,80a825 +34894f8,b025 +34894fc,9025 +3489500,3c138041 +3489504,2673a050 +3489508,3c178041 +348950c,3c148041 +3489510,3c1e38e3 +3489514,24070012 +3489518,2c03025 +348951c,2602825 +3489520,c101b95 +3489524,2a02025 +3489528,8ef0b198 +348952c,8e82b19c +3489530,202102b +3489534,50400026 +3489538,26520001 +348953c,37d18e39 +3489540,82020000 +3489544,2002825 +3489548,2442ffe0 +348954c,510018 +3489550,1810 +3489554,31883 +3489558,227c3 +348955c,641823 +3489560,14720016 +3489564,26100004 +3489568,8ca70000 +348956c,73b02 +3489570,510018 +3489574,1810 +3489578,31883 +348957c,641823 +3489580,330c0 +3489584,c33021 +3489588,63040 +348958c,96630006 +3489590,afa30018 +3489594,96630004 +3489598,afa30014 +348959c,8ca30000 +34895a0,30630fff +34895a4,afa30010 +34895a8,30e70fff +34895ac,463023 +34895b0,2602825 +34895b4,c101bfd +34895b8,2a02025 +34895bc,8e82b19c +34895c0,202102b +34895c4,5440ffdf +34895c8,82020000 +34895cc,26520001 +34895d0,24020006 +34895d4,1642ffcf +34895d8,26d60012 +34895dc,3c028041 +34895e0,8c43b198 +34895e4,3c028041 +34895e8,ac43b19c +34895ec,8fbf0044 +34895f0,8fbe0040 +34895f4,8fb7003c +34895f8,8fb60038 +34895fc,8fb50034 +3489600,8fb40030 +3489604,8fb3002c +3489608,8fb20028 +348960c,8fb10024 +3489610,8fb00020 +3489614,3e00008 +3489618,27bd0048 +348961c,3c028041 +3489620,24030001 +3489624,ac43b1a4 +3489628,3c038041 +348962c,8c62b1a8 +3489630,2c440006 +3489634,50800001 +3489638,24020005 +348963c,3e00008 +3489640,ac62b1a8 +3489644,27bdffb8 +3489648,afbf0044 +348964c,afbe0040 +3489650,afb6003c +3489654,afb50038 +3489658,afb40034 +348965c,afb30030 +3489660,afb2002c +3489664,afb10028 +3489668,afb00024 +348966c,3a0f025 +3489670,3c028041 +3489674,9442b1a0 +3489678,10400133 +348967c,3a0a825 +3489680,3c02801d +3489684,3442aa30 +3489688,8c42066c +348968c,3c033000 +3489690,24630483 +3489694,431024 +3489698,1440012b +348969c,808025 +34896a0,3c02801c +34896a4,344284a0 +34896a8,8c430008 +34896ac,3c02800f +34896b0,8c4213ec +34896b4,54620125 +34896b8,2a0e825 +34896bc,3c028011 +34896c0,3442a5d0 +34896c4,8c47135c +34896c8,14e0011f +34896cc,3c02800e +34896d0,3442f1b0 +34896d4,8c420000 +34896d8,30420020 +34896dc,1440011a +34896e0,3c028041 +34896e4,8c43b1a4 +34896e8,24020001 +34896ec,1062000a +34896f0,3c02801c +34896f4,344284a0 +34896f8,3c030001 +34896fc,431021 +3489700,94430934 +3489704,24020006 +3489708,54620110 +348970c,2a0e825 +3489710,10000009 +3489714,3c038041 +3489718,344284a0 +348971c,3c030001 +3489720,431021 +3489724,94430934 +3489728,24020006 +348972c,14620007 +3489730,3c028041 +3489734,3c038041 +3489738,8c62b1a8 +348973c,3042001f +3489740,ac62b1a8 +3489744,10000022 +3489748,241300ff +348974c,8c42b1a8 +3489750,2c430006 +3489754,1060000a +3489758,2c43006a +348975c,29a00 +3489760,2629823 +3489764,3c02cccc +3489768,3442cccd +348976c,2620019 +3489770,9810 +3489774,139882 +3489778,10000015 +348977c,327300ff +3489780,14600013 +3489784,241300ff +3489788,2c4300ba +348978c,1060000b +3489790,21a00 +3489794,621023 +3489798,24429769 +348979c,3c03cccc +34897a0,3463cccd +34897a4,430019 +34897a8,1010 +34897ac,29982 +34897b0,139827 +34897b4,10000006 +34897b8,327300ff +34897bc,3c028041 +34897c0,ac40b1a4 +34897c4,3c028041 +34897c8,100000df +34897cc,ac40b1a8 +34897d0,3c038041 +34897d4,8c62b1a8 +34897d8,24420001 +34897dc,ac62b1a8 +34897e0,3c028011 +34897e4,3442a5d0 +34897e8,8c4808c4 +34897ec,19000011 +34897f0,1001025 +34897f4,e05025 +34897f8,3c056666 +34897fc,24a56667 +3489800,254a0001 +3489804,401825 +3489808,450018 +348980c,2010 +3489810,42083 +3489814,217c3 +3489818,2863000a +348981c,1060fff8 +3489820,821023 +3489824,15400005 +3489828,3c028041 +348982c,10000002 +3489830,240a0001 +3489834,240a0001 +3489838,3c028041 +348983c,9445b142 +3489840,18a00010 +3489844,a01025 +3489848,3c066666 +348984c,24c66667 +3489850,24e70001 +3489854,401825 +3489858,460018 +348985c,2010 +3489860,42083 +3489864,217c3 +3489868,2863000a +348986c,1060fff8 +3489870,821023 +3489874,54e00005 +3489878,1473821 +348987c,10000002 +3489880,24070001 +3489884,24070001 +3489888,1473821 +348988c,24f40001 +3489890,3c028041 +3489894,2442a050 +3489898,94430004 +348989c,740018 +34898a0,2012 +34898a4,3c038041 +34898a8,2463a030 +34898ac,94660004 +34898b0,862021 +34898b4,497c2 +34898b8,2449021 +34898bc,129043 +34898c0,129023 +34898c4,265200a0 +34898c8,94420006 +34898cc,44820000 +34898d4,46800021 +34898d8,3c028041 +34898dc,d4469ea8 +34898e0,46260002 +34898e4,3c028041 +34898e8,d4429eb0 +34898ec,46201001 +34898f0,3c028041 +34898f4,d4449eb8 +34898f8,46240000 +34898fc,4620000d +3489900,44060000 +3489904,94620006 +3489908,44820000 +3489910,46800021 +3489914,46260002 +3489918,46201081 +348991c,3c028041 +3489920,d4409ec0 +3489924,46201080 +3489928,46241080 +348992c,4620100d +3489930,44110000 +3489934,24e20009 +3489938,210c2 +348993c,210c0 +3489940,3a2e823 +3489944,27a40020 +3489948,941021 +348994c,19400015 +3489950,a0400000 +3489954,2549ffff +3489958,894821 +348995c,806025 +3489960,3c0b6666 +3489964,256b6667 +3489968,10b0018 +348996c,1810 +3489970,31883 +3489974,817c3 +3489978,621823 +348997c,31080 +3489980,431021 +3489984,21040 +3489988,1021023 +348998c,24420030 +3489990,a1220000 +3489994,604025 +3489998,1201025 +348999c,144cfff2 +34899a0,2529ffff +34899a4,8a1021 +34899a8,2403002f +34899ac,a0430000 +34899b0,147102a +34899b4,10400012 +34899b8,873821 +34899bc,8a5021 +34899c0,3c086666 +34899c4,25086667 +34899c8,a80018 +34899cc,1810 +34899d0,31883 +34899d4,517c3 +34899d8,621823 +34899dc,31080 +34899e0,431021 +34899e4,21040 +34899e8,a21023 +34899ec,24420030 +34899f0,a0e20000 +34899f4,24e7ffff +34899f8,14eafff3 +34899fc,602825 +3489a00,8e020008 +3489a04,24430008 +3489a08,ae030008 +3489a0c,3c03de00 +3489a10,ac430000 +3489a14,3c038041 +3489a18,2463a0a0 +3489a1c,ac430004 +3489a20,8e020008 +3489a24,24430008 +3489a28,ae030008 +3489a2c,3c03e700 +3489a30,ac430000 +3489a34,ac400004 +3489a38,8e020008 +3489a3c,24430008 +3489a40,ae030008 +3489a44,3c03fc11 +3489a48,34639623 +3489a4c,ac430000 +3489a50,3c03ff2f +3489a54,3463ffff +3489a58,ac430004 +3489a5c,8e030008 +3489a60,24620008 +3489a64,ae020008 +3489a68,3c16fa00 +3489a6c,ac760000 +3489a70,3c02dad3 +3489a74,24420b00 +3489a78,2621025 +3489a7c,ac620004 +3489a80,c102508 +3489a84,2402825 +3489a88,3c028041 +3489a8c,9442a054 +3489a90,540018 +3489a94,a012 +3489a98,292a021 +3489a9c,8e020008 +3489aa0,24430008 +3489aa4,ae030008 +3489aa8,ac560000 +3489aac,3c03f4ec +3489ab0,24633000 +3489ab4,2639825 +3489ab8,ac530004 +3489abc,3c028041 +3489ac0,8c46b1a8 +3489ac4,63042 +3489ac8,24070001 +3489acc,30c6000f +3489ad0,3c128041 +3489ad4,2645a030 +3489ad8,c101b95 +3489adc,2002025 +3489ae0,2645a030 +3489ae4,94a20006 +3489ae8,afa20018 +3489aec,94a20004 +3489af0,afa20014 +3489af4,afb10010 +3489af8,2803825 +3489afc,3025 +3489b00,c101bfd +3489b04,2002025 +3489b08,c102532 +3489b0c,2002025 +3489b10,8e020008 +3489b14,24430008 +3489b18,ae030008 +3489b1c,3c03e900 +3489b20,ac430000 +3489b24,ac400004 +3489b28,8e020008 +3489b2c,24430008 +3489b30,ae030008 +3489b34,3c03df00 +3489b38,ac430000 +3489b3c,ac400004 +3489b40,10000002 +3489b44,2a0e825 +3489b48,2a0e825 +3489b4c,3c0e825 +3489b50,8fbf0044 +3489b54,8fbe0040 +3489b58,8fb6003c +3489b5c,8fb50038 +3489b60,8fb40034 +3489b64,8fb30030 +3489b68,8fb2002c +3489b6c,8fb10028 +3489b70,8fb00024 +3489b74,3e00008 +3489b78,27bd0048 +3489b7c,3c028040 +3489b80,a040306c +3489b84,3c028040 +3489b88,3e00008 +3489b8c,ac403070 +3489b90,3c038041 +3489b94,3c028050 +3489b98,24420000 +3489b9c,3e00008 +3489ba0,ac62b1ac +3489ba4,3082000f +3489ba8,10400009 +3489bac,3c038041 +3489bb0,417c3 +3489bb4,21702 +3489bb8,821821 +3489bbc,3063000f +3489bc0,431023 +3489bc4,24420010 +3489bc8,822021 +3489bcc,3c038041 +3489bd0,8c62b1ac +3489bd4,442021 +3489bd8,3e00008 +3489bdc,ac64b1ac +3489be0,27bdffe8 +3489be4,afbf0014 +3489be8,afb00010 +3489bec,808025 +3489bf0,c1026e9 +3489bf4,8c840008 +3489bf8,402025 +3489bfc,ae020000 +3489c00,8e060008 +3489c04,3c028000 +3489c08,24420df0 +3489c0c,40f809 +3489c10,8e050004 +3489c14,8fbf0014 +3489c18,8fb00010 +3489c1c,3e00008 +3489c20,27bd0018 +3489c24,33c2 +3489c28,664399c4 +3489c2c,cc45ffc6 +3489c30,ff47ffc8 +3489c34,ff49e0ca +3489c38,c24ba3cc +3489c3c,854d660d +3489c40,440f2200 +3489c44,85d1a352 +3489c48,c2d3e045 +3489c4c,1010101 +3489c50,1010101 +3489c54,1010101 +3489c58,1010101 +3489c5c,1010101 +3489c78,1010000 +3489c80,1010101 +3489c84,1000101 +3489c88,10101 +3489c8c,10000 +3489c90,2b242525 +3489c94,26262626 +3489c98,27272727 +3489c9c,27272727 +3489ca0,500080d +3489ca4,1051508 +3489ca8,d01052a +3489cac,80d0127 +3489cb0,f080b01 +3489cb4,4d510b02 +3489cbc,97ff6350 +3489cc0,45ff5028 +3489cc4,57456397 +3489cc8,ff5e45ff +3489ccc,9f006545 +3489cd0,ff63ff6c +3489cd4,45fff063 +3489cd8,7345ffff +3489cdc,ff503aff +3489ce0,ffff573a +3489ce4,ffffff5e +3489ce8,3affffff +3489cec,653affff +3489cf0,ff6c3aff +3489cf4,ffff733a +3489cf8,5a0c00 +3489cfc,720c0096 +3489d00,c009618 +3489d04,1652a00 +3489d08,4e2a005a +3489d0c,2a000000 +3489d10,c004e00 +3489d14,c015a00 +3489d18,c026600 +3489d1c,c037200 +3489d20,c047e00 +3489d24,c058a00 +3489d28,c064e0c +3489d2c,75a0c +3489d30,c09660c +3489d34,a720c +3489d38,c0c7e0c +3489d3c,c0d8a0c +3489d40,c0e4e18 +3489d44,c0f5a18 +3489d48,c106618 +3489d4c,c117218 +3489d50,c127e18 +3489d54,c138a18 +3489d58,ffff +3489d5c,ffff +3489d60,ffff +3489d64,ffff +3489d68,ffff +3489d6c,ffff +3489d70,ffff +3489d74,ffff +3489d78,ffff +3489d7c,ffff +3489d80,ffff +3489d84,ffff +3489d88,ffff +3489d8c,ffff +3489d90,c3b7e2a +3489d94,c3c8a2a +3489d98,c3d962a +3489d9c,ffff +3489da0,c3e7e36 +3489da4,b3f8b37 +3489da8,b409737 +3489dac,ffff +3489db0,c417e42 +3489db4,c428a42 +3489db8,c439642 +3489dbc,ffff +3489dc0,c447e4f +3489dc4,c458a4f +3489dc8,c46964f +3489dcc,ffff +3489dd0,c149600 +3489dd4,ffff +3489dd8,2c061b31 +3489ddc,2c072931 +3489de0,2c083731 +3489de4,2a096f51 +3489de8,2c0a722a +3489dec,ffff +3489df0,2c00370a +3489df4,2c01371a +3489df8,2c022922 +3489dfc,2c031b1a +3489e00,2c041b0a +3489e04,2c052902 +3489e08,ffff +3489e0c,ffff +3489e10,8040a070 +3489e14,8040a060 +3489e18,80409ff0 +3489e1c,c8ff6482 +3489e20,82ffff64 +3489e24,64ff5aff +3489e28,bd1400 +3489e2c,aa0200 +3489e30,bd1300 +3489e34,15c6300 +3489e38,de2f00 +3489e3c,e01010e0 +3489e40,e01010e0 +3489e44,1010e0e0 +3489e48,1010e0e0 +3489e4c,10e0e010 +3489e50,10000000 +3489e54,4d510000 +3489e58,4e6f726d +3489e5c,616c0000 +3489e60,bdcccccd +3489e64,3dcccccd +3489e68,43510000 +3489e6c,41100000 +3489e70,4f000000 +3489e74,42080000 +3489e78,c20c0000 +3489e7c,420c0000 +3489e80,3f800000 +3489e84,3f000000 +3489e88,41c80000 +3489e8c,3fa00000 +3489e90,40000000 +3489e94,40200000 +3489e98,3f800000 +3489e9c,4f000000 +3489ea0,41f00000 +3489ea8,3ff80000 +3489eb0,406e0000 +3489eb8,3ff00000 +3489ec0,40080000 +3489ec8,80409c24 +3489ecc,10203 +3489ed0,4050607 +3489ed4,ffffffff +3489ed8,ffff0000 +3489edc,ff00ff +3489ee0,3c000064 +3489ee4,ffff8200 +3489ee8,c832ffc8 +3489eec,c8000000 +3489ef0,104465 +3489ef4,6b750000 +3489efc,110446f +3489f00,646f6e67 +3489f04,6f000000 +3489f08,2104a61 +3489f0c,62750000 +3489f14,3d0466f +3489f18,72657374 +3489f20,4d04669 +3489f24,72650000 +3489f2c,5d05761 +3489f30,74657200 +3489f38,7d05368 +3489f3c,61646f77 +3489f44,6d05370 +3489f48,69726974 +3489f50,890426f +3489f54,74570000 +3489f5c,9104963 +3489f60,65000000 +3489f68,ca04765 +3489f6c,7275646f +3489f74,b804754 +3489f78,47000000 +3489f80,dc04761 +3489f84,6e6f6e00 +3489f8c,2 +3489f94,3f800000 +3489fa0,1 +3489fa4,30006 +3489fa8,70009 +3489fac,b000e +3489fb0,f0010 +3489fb4,110019 +3489fb8,1a002b +3489fbc,2c002e +3489fc0,300032 +3489fc4,35003c +3489fc8,400041 +3489fcc,460051 +3489fd0,540109 +3489fd4,10b010c +3489fd8,10e010f +3489fdc,1100113 +3489fe4,100010 +3489fe8,a0301 +3489fec,1000000 +3489ff4,100010 +3489ff8,20002 +3489ffc,2000000 +348a004,80008 +348a008,a0301 +348a00c,1000000 +348a014,100010 +348a018,30301 +348a01c,1000000 +348a024,100018 +348a028,10301 +348a02c,1000000 +348a034,100010 +348a038,100301 +348a03c,1000000 +348a044,200020 +348a048,10302 +348a04c,2000000 +348a054,8000e +348a058,5f0301 +348a05c,1000000 +348a064,180018 +348a068,140003 +348a06c,4000000 +348a074,200020 +348a078,5a0003 +348a07c,4000000 +348a084,100010 +348a088,60301 +348a08c,1000000 +348a094,100010 +348a098,30003 +348a09c,4000000 +348a0a0,e7000000 +348a0a8,d9000000 +348a0b0,ed000000 +348a0b4,5003c0 +348a0b8,ef002cf0 +348a0bc,504244 +348a0c0,df000000 +348a0dc,4d8e0032 +348a0e0,ce2001 +348a0e4,80407cd8 +348a0e8,80407768 +348a0ec,ffffffff +348a0f0,4d8c0034 +348a0f4,bb1201 +348a0f8,80407b10 +348a0fc,80407768 +348a100,ffffffff +348a104,4d090033 +348a108,d92801 +348a10c,80407b10 +348a110,80407768 +348a114,ffffffff +348a118,53030031 +348a11c,e93500 +348a120,80407b10 +348a124,80407768 +348a128,ffffffff +348a12c,53060030 +348a130,e73300 +348a134,80407b10 +348a138,80407768 +348a13c,ffffffff +348a140,530e0035 +348a144,e83400 +348a148,80407b10 +348a14c,80407768 +348a150,ffffffff +348a154,4d000037 +348a158,c71b01 +348a15c,80407b10 +348a160,80407768 +348a164,ffffffff +348a168,530a0036 +348a16c,dd2d00 +348a170,80407b10 +348a174,80407768 +348a178,ffffffff +348a17c,530b004f +348a180,dd2e00 +348a184,80407b10 +348a188,80407768 +348a18c,ffffffff +348a190,530f0039 +348a194,ea3600 +348a198,80407b10 +348a19c,80407768 +348a1a0,ffffffff +348a1a4,53230069 +348a1a8,ef3b00 +348a1ac,80407b10 +348a1b0,804079cc +348a1b4,ffffffff +348a1b8,5308003a +348a1bc,de2f00 +348a1c0,80407b10 +348a1c4,80407768 +348a1c8,ffffffff +348a1cc,53110038 +348a1d0,f64100 +348a1d4,80407b10 +348a1d8,80407768 +348a1dc,ffffffff +348a1e0,532f0002 +348a1e4,1095e00 +348a1e8,80407b10 +348a1ec,80407768 +348a1f0,ffffffff +348a1f4,53140042 +348a1f8,c60100 +348a1fc,80407b10 +348a200,80407768 +348a204,ffffffff +348a208,53150043 +348a20c,eb3800 +348a210,80407b10 +348a214,80407768 +348a218,ffffffff +348a21c,53160044 +348a220,eb3700 +348a224,80407b10 +348a228,80407768 +348a22c,ffffffff +348a230,53170045 +348a234,eb3900 +348a238,80407b10 +348a23c,80407768 +348a240,ffffffff +348a244,53180046 +348a248,c60100 +348a24c,80407b10 +348a250,80407768 +348a254,ffffffff +348a258,531a0098 +348a25c,df3000 +348a260,80407b10 +348a264,80407768 +348a268,ffffffff +348a26c,531b0099 +348a270,10b4500 +348a274,80407d18 +348a278,80407768 +348a27c,ffffffff +348a280,53100048 +348a284,f33e01 +348a288,80407b10 +348a28c,80407768 +348a290,ffffffff +348a294,53250010 +348a298,1364f00 +348a29c,80407b10 +348a2a0,80407768 +348a2a4,ffffffff +348a2a8,53260011 +348a2ac,1353200 +348a2b0,80407b10 +348a2b4,80407768 +348a2b8,ffffffff +348a2bc,5322000b +348a2c0,1094400 +348a2c4,80407b10 +348a2c8,80407768 +348a2cc,ffffffff +348a2d0,53240012 +348a2d4,1343100 +348a2d8,80407b10 +348a2dc,80407768 +348a2e0,ffffffff +348a2e4,53270013 +348a2e8,1375000 +348a2ec,80407b10 +348a2f0,80407768 +348a2f4,ffffffff +348a2f8,532b0017 +348a2fc,1385100 +348a300,80407b10 +348a304,80407768 +348a308,ffffffff +348a30c,532d9001 +348a310,da2900 +348a314,80407b10 +348a318,80407768 +348a31c,ffffffff +348a320,532e000b +348a324,1094400 +348a328,80407b10 +348a32c,80407768 +348a330,ffffffff +348a334,53300003 +348a338,1415400 +348a33c,80407b10 +348a340,80407768 +348a344,ffffffff +348a348,53310004 +348a34c,1405300 +348a350,80407b10 +348a354,80407768 +348a358,ffffffff +348a35c,53320005 +348a360,f54000 +348a364,80407b10 +348a368,80407768 +348a36c,ffffffff +348a370,53330008 +348a374,1435600 +348a378,80407b10 +348a37c,80407768 +348a380,ffffffff +348a384,53340009 +348a388,1465700 +348a38c,80407b10 +348a390,80407768 +348a394,ffffffff +348a398,5335000d +348a39c,1495a00 +348a3a0,80407b10 +348a3a4,80407768 +348a3a8,ffffffff +348a3ac,5336000e +348a3b0,13f5200 +348a3b4,80407b10 +348a3b8,80407768 +348a3bc,ffffffff +348a3c0,5337000a +348a3c4,1425500 +348a3c8,80407b10 +348a3cc,80407768 +348a3d0,ffffffff +348a3d4,533b00a4 +348a3d8,18d7400 +348a3dc,80407b10 +348a3e0,80407768 +348a3e4,ffffffff +348a3e8,533d004b +348a3ec,f84300 +348a3f0,80407b10 +348a3f4,80407768 +348a3f8,ffffffff +348a3fc,533e004c +348a400,cb1d01 +348a404,80407b10 +348a408,80407768 +348a40c,ffffffff +348a410,533f004d +348a414,dc2c01 +348a418,80407b10 +348a41c,80407768 +348a420,ffffffff +348a424,5340004e +348a428,ee3a00 +348a42c,80407b10 +348a430,80407768 +348a434,ffffffff +348a438,53420050 +348a43c,f23c00 +348a440,80407b10 +348a444,80407768 +348a448,ffffffff +348a44c,53430051 +348a450,f23d00 +348a454,80407b10 +348a458,80407768 +348a45c,ffffffff +348a460,53450053 +348a464,1184700 +348a468,80407b10 +348a46c,80407768 +348a470,ffffffff +348a474,53460054 +348a478,1575f00 +348a47c,80407b10 +348a480,80407768 +348a484,ffffffff +348a488,534b0056 +348a48c,be1600 +348a490,80407b10 +348a494,80407768 +348a498,ffffffff +348a49c,534c0057 +348a4a0,be1700 +348a4a4,80407b10 +348a4a8,80407768 +348a4ac,ffffffff +348a4b0,534d0058 +348a4b4,bf1800 +348a4b8,80407b10 +348a4bc,80407768 +348a4c0,ffffffff +348a4c4,534e0059 +348a4c8,bf1900 +348a4cc,80407b10 +348a4d0,80407768 +348a4d4,ffffffff +348a4d8,534f005a +348a4dc,bf1a00 +348a4e0,80407b10 +348a4e4,80407768 +348a4e8,ffffffff +348a4ec,5351005b +348a4f0,12d4900 +348a4f4,80407b10 +348a4f8,80407768 +348a4fc,ffffffff +348a500,5352005c +348a504,12d4a00 +348a508,80407b10 +348a50c,80407768 +348a510,ffffffff +348a514,535300cd +348a518,db2a00 +348a51c,80407b10 +348a520,80407768 +348a524,ffffffff +348a528,535400ce +348a52c,db2b00 +348a530,80407b10 +348a534,80407768 +348a538,ffffffff +348a53c,536f0068 +348a540,c82100 +348a544,80407b10 +348a548,80407768 +348a54c,ffffffff +348a550,5370007b +348a554,d72400 +348a558,80407b10 +348a55c,80407768 +348a560,ffffffff +348a564,5341004a +348a568,10e4600 +348a56c,80407b10 +348a570,80407948 +348a574,ffffffff +348a578,4d5800dc +348a57c,1194801 +348a580,80407cf4 +348a584,80407768 +348a588,ffffffff +348a58c,3d7200c6 +348a590,bd1301 +348a594,80407b10 +348a598,80407770 +348a59c,ffffffff +348a5a0,3e7a00c2 +348a5a4,bd1401 +348a5a8,80407b10 +348a5ac,80407770 +348a5b0,ffffffff +348a5b4,537400c7 +348a5b8,b90a02 +348a5bc,80407b10 +348a5c0,80407768 +348a5c4,ffffffff +348a5c8,53750067 +348a5cc,b80b01 +348a5d0,80407b10 +348a5d4,80407768 +348a5d8,ffffffff +348a5dc,53760066 +348a5e0,c81c01 +348a5e4,80407b10 +348a5e8,80407768 +348a5ec,ffffffff +348a5f0,53770060 +348a5f4,aa0203 +348a5f8,80407b10 +348a5fc,80407768 +348a600,ffffffff +348a604,53780052 +348a608,cd1e01 +348a60c,80407b10 +348a610,80407768 +348a614,ffffffff +348a618,53790052 +348a61c,cd1f01 +348a620,80407b10 +348a624,80407768 +348a628,ffffffff +348a62c,5356005e +348a630,d12200 +348a634,80407b10 +348a638,804079a0 +348a63c,1ffff +348a640,5357005f +348a644,d12300 +348a648,80407b10 +348a64c,804079a0 +348a650,2ffff +348a654,5321009a +348a658,da2900 +348a65c,80407b10 +348a660,80407768 +348a664,ffffffff +348a668,4d830055 +348a66c,b70901 +348a670,80407b10 +348a674,80407768 +348a678,ffffffff +348a67c,4d9200e6 +348a680,d82501 +348a684,80407cbc +348a688,80407768 +348a68c,ffffffff +348a690,4d9300e6 +348a694,d82601 +348a698,80407cbc +348a69c,80407768 +348a6a0,ffffffff +348a6a4,4d9400e6 +348a6a8,d82701 +348a6ac,80407cbc +348a6b0,80407768 +348a6b4,ffffffff +348a6b8,4d84006f +348a6bc,17f6d01 +348a6c0,80407b10 +348a6c4,80407768 +348a6c8,ffffffff +348a6cc,4d8500cc +348a6d0,17f6e01 +348a6d4,80407b10 +348a6d8,80407768 +348a6dc,ffffffff +348a6e0,4d8600f0 +348a6e4,17f6f01 +348a6e8,80407b10 +348a6ec,80407768 +348a6f0,ffffffff +348a6f4,3d7200c6 +348a6f8,bd1301 +348a6fc,80407b10 +348a700,80407770 +348a704,ffffffff +348a708,53820098 +348a70c,df3000 +348a710,80407b10 +348a714,80407768 +348a718,ffffffff +348a71c,53280014 +348a720,1505b00 +348a724,80407b10 +348a728,80407768 +348a72c,ffffffff +348a730,53290015 +348a734,1515c00 +348a738,80407b10 +348a73c,80407768 +348a740,ffffffff +348a744,532a0016 +348a748,1525d00 +348a74c,80407b10 +348a750,80407768 +348a754,ffffffff +348a758,53500079 +348a75c,1475800 +348a760,80407b10 +348a764,80407768 +348a768,ffffffff +348a76c,4d8700f1 +348a770,17f7101 +348a774,80407b10 +348a778,80407768 +348a77c,ffffffff +348a780,4d8800f2 +348a784,17f7201 +348a788,80407b10 +348a78c,80407768 +348a790,ffffffff +348a794,533d000c +348a798,f84300 +348a79c,80407b10 +348a7a0,80407870 +348a7a4,ffffffff +348a7a8,53040070 +348a7ac,1586000 +348a7b0,80407b10 +348a7b4,80407768 +348a7b8,ffffffff +348a7bc,530c0071 +348a7c0,1586100 +348a7c4,80407b10 +348a7c8,80407768 +348a7cc,ffffffff +348a7d0,53120072 +348a7d4,1586200 +348a7d8,80407b10 +348a7dc,80407768 +348a7e0,ffffffff +348a7e4,5b7100b4 +348a7e8,15c6301 +348a7ec,80407b10 +348a7f0,80407768 +348a7f4,ffffffff +348a7f8,530500ad +348a7fc,15d6400 +348a800,80407b10 +348a804,80407768 +348a808,ffffffff +348a80c,530d00ae +348a810,15d6500 +348a814,80407b10 +348a818,80407768 +348a81c,ffffffff +348a820,531300af +348a824,15d6600 +348a828,80407b10 +348a82c,80407768 +348a830,ffffffff +348a834,53470007 +348a838,17b6c00 +348a83c,80407b10 +348a840,80407768 +348a844,ffffffff +348a848,53480007 +348a84c,17b6c00 +348a850,80407b10 +348a854,80407768 +348a858,ffffffff +348a85c,4d8a0037 +348a860,c71b01 +348a864,80407b10 +348a868,80407768 +348a86c,ffffffff +348a870,4d8b0037 +348a874,c71b01 +348a878,80407b10 +348a87c,80407768 +348a880,ffffffff +348a884,4d8c0034 +348a888,bb1201 +348a88c,80407b10 +348a890,80407768 +348a894,ffffffff +348a898,4d8d0034 +348a89c,bb1201 +348a8a0,80407b10 +348a8a4,80407768 +348a8a8,ffffffff +348a8ac,4d020032 +348a8b0,ce2001 +348a8b4,80407cd8 +348a8b8,80407768 +348a8bc,ffffffff +348a8c0,4d8f0032 +348a8c4,ce2001 +348a8c8,80407cd8 +348a8cc,80407768 +348a8d0,ffffffff +348a8d4,4d900032 +348a8d8,ce2001 +348a8dc,80407cd8 +348a8e0,80407768 +348a8e4,ffffffff +348a8e8,4d910032 +348a8ec,ce2001 +348a8f0,80407cd8 +348a8f4,80407768 +348a8f8,ffffffff +348a8fc,4d9500dc +348a900,1194801 +348a904,80407cf4 +348a908,80407768 +348a90c,ffffffff +348a910,4d960033 +348a914,d92801 +348a918,80407b10 +348a91c,80407768 +348a920,ffffffff +348a924,4d970033 +348a928,d92801 +348a92c,80407b10 +348a930,80407768 +348a934,ffffffff +348a938,53190047 +348a93c,f43f00 +348a940,80407b10 +348a944,80407768 +348a948,ffffffff +348a94c,531d007a +348a950,1746800 +348a954,80407b10 +348a958,80407768 +348a95c,ffffffff +348a960,531c005d +348a964,1736700 +348a968,80407b10 +348a96c,80407768 +348a970,ffffffff +348a974,53200097 +348a978,1766a00 +348a97c,80407b10 +348a980,80407768 +348a984,ffffffff +348a988,531e00f9 +348a98c,1767000 +348a990,80407b10 +348a994,80407768 +348a998,ffffffff +348a99c,537700f3 +348a9a0,aa0201 +348a9a4,80407b10 +348a9a8,80407768 +348a9ac,ffffffff +348a9b0,4d8400f4 +348a9b4,17f6d01 +348a9b8,80407b10 +348a9bc,80407768 +348a9c0,ffffffff +348a9c4,4d8500f5 +348a9c8,17f6e01 +348a9cc,80407b10 +348a9d0,80407768 +348a9d4,ffffffff +348a9d8,4d8600f6 +348a9dc,17f6f01 +348a9e0,80407b10 +348a9e4,80407768 +348a9e8,ffffffff +348a9ec,4d8700f7 +348a9f0,17f7101 +348a9f4,80407b10 +348a9f8,80407768 +348a9fc,ffffffff +348aa00,537a00fa +348aa04,bd1401 +348aa08,80407b10 +348aa0c,80407770 +348aa10,ffffffff +348aa14,53980090 +348aa18,c71b01 +348aa1c,80407b10 +348aa20,80407768 +348aa24,ffffffff +348aa28,53990091 +348aa2c,c71b01 +348aa30,80407b10 +348aa34,80407768 +348aa38,ffffffff +348aa3c,539a00a7 +348aa40,bb1201 +348aa44,80407b10 +348aa48,80407768 +348aa4c,ffffffff +348aa50,539b00a8 +348aa54,bb1201 +348aa58,80407b10 +348aa5c,80407768 +348aa60,ffffffff +348aa64,5349006c +348aa68,17b7300 +348aa6c,80407b10 +348aa70,80407768 +348aa74,ffffffff +348aa78,53419002 +348aa80,80407b10 +348aa84,8040796c +348aa88,ffffffff +348aac8,ffffffff +348aacc,dd2d00 +348aad0,80407b18 +348aad4,80407768 +348aad8,ffffffff +348aadc,ffffffff +348aae0,1475800 +348aae4,80407b2c +348aae8,80407768 +348aaec,ffffffff +348aaf0,ffffffff +348aaf4,bf1800 +348aaf8,80407b58 +348aafc,80407768 +348ab00,ffffffff +348ab04,ffffffff +348ab08,e93500 +348ab0c,80407b84 +348ab10,80407768 +348ab14,ffffffff +348ab18,ffffffff +348ab1c,e73300 +348ab20,80407bac +348ab24,80407768 +348ab28,ffffffff +348ab2c,ffffffff +348ab30,d12200 +348ab34,80407bdc +348ab38,80407768 +348ab3c,ffffffff +348ab40,ffffffff +348ab44,db2a00 +348ab48,80407c0c +348ab4c,80407768 +348ab50,ffffffff +348ab54,ffffffff +348ab58,bb1201 +348ab5c,80407c24 +348ab60,80407768 +348ab64,ffffffff +348ab68,ffffffff +348ab6c,c71b01 +348ab70,80407c40 +348ab74,80407768 +348ab78,ffffffff +348ab7c,ffffffff +348ab80,d92800 +348ab84,80407c6c +348ab88,80407768 +348ab8c,ffffffff +348ab90,ffffffff +348ab94,cd1e00 +348ab98,80407c5c +348ab9c,80407768 +348aba0,ffffffff +348aba4,ffffffff +348aba8,10e4600 +348abac,80407c9c +348abb0,80407768 +348abb4,ffffffff +348abb8,53410043 +348abbc,c60100 +348abc0,80407b10 +348abc4,8040787c +348abc8,15ffff +348abcc,53410044 +348abd0,c60100 +348abd4,80407b10 +348abd8,8040787c +348abdc,16ffff +348abe0,53410045 +348abe4,c60100 +348abe8,80407b10 +348abec,8040787c +348abf0,17ffff +348abf4,53410046 +348abf8,1776b00 +348abfc,80407b10 +348ac00,8040787c +348ac04,18ffff +348ac08,53410047 +348ac0c,f43f00 +348ac10,80407b10 +348ac14,8040787c +348ac18,19ffff +348ac1c,5341005d +348ac20,1736700 +348ac24,80407b10 +348ac28,8040787c +348ac2c,1cffff +348ac30,5341007a +348ac34,1746800 +348ac38,80407b10 +348ac3c,8040787c +348ac40,1dffff +348ac44,534100f9 +348ac48,1767000 +348ac4c,80407b10 +348ac50,8040787c +348ac54,1effff +348ac58,53410097 +348ac5c,1766a00 +348ac60,80407b10 +348ac64,8040787c +348ac68,20ffff +348ac6c,53410006 +348ac70,b90a02 +348ac74,80407b10 +348ac78,804078b4 +348ac7c,10003 +348ac80,5341001c +348ac84,b90a02 +348ac88,80407b10 +348ac8c,804078b4 +348ac90,10004 +348ac94,5341001d +348ac98,b90a02 +348ac9c,80407b10 +348aca0,804078b4 +348aca4,10005 +348aca8,5341001e +348acac,b90a02 +348acb0,80407b10 +348acb4,804078b4 +348acb8,10006 +348acbc,5341002a +348acc0,b90a02 +348acc4,80407b10 +348acc8,804078b4 +348accc,10007 +348acd0,53410061 +348acd4,b90a02 +348acd8,80407b10 +348acdc,804078b4 +348ace0,1000a +348ace4,53410062 +348ace8,b80b01 +348acec,80407b10 +348acf0,804078b4 +348acf4,20000 +348acf8,53410063 +348acfc,b80b01 +348ad00,80407b10 +348ad04,804078b4 +348ad08,20001 +348ad0c,53410064 +348ad10,b80b01 +348ad14,80407b10 +348ad18,804078b4 +348ad1c,20002 +348ad20,53410065 +348ad24,b80b01 +348ad28,80407b10 +348ad2c,804078b4 +348ad30,20003 +348ad34,5341007c +348ad38,b80b01 +348ad3c,80407b10 +348ad40,804078b4 +348ad44,20004 +348ad48,5341007d +348ad4c,b80b01 +348ad50,80407b10 +348ad54,804078b4 +348ad58,20005 +348ad5c,5341007e +348ad60,b80b01 +348ad64,80407b10 +348ad68,804078b4 +348ad6c,20006 +348ad70,5341007f +348ad74,b80b01 +348ad78,80407b10 +348ad7c,804078b4 +348ad80,20007 +348ad84,534100a2 +348ad88,b80b01 +348ad8c,80407b10 +348ad90,804078b4 +348ad94,20008 +348ad98,53410087 +348ad9c,b80b01 +348ada0,80407b10 +348ada4,804078b4 +348ada8,20009 +348adac,53410088 +348adb0,c81c01 +348adb4,80407b10 +348adb8,804078b4 +348adbc,40000 +348adc0,53410089 +348adc4,c81c01 +348adc8,80407b10 +348adcc,804078b4 +348add0,40001 +348add4,5341008a +348add8,c81c01 +348addc,80407b10 +348ade0,804078b4 +348ade4,40002 +348ade8,5341008b +348adec,c81c01 +348adf0,80407b10 +348adf4,804078b4 +348adf8,40003 +348adfc,5341008c +348ae00,c81c01 +348ae04,80407b10 +348ae08,804078b4 +348ae0c,40004 +348ae10,5341008e +348ae14,c81c01 +348ae18,80407b10 +348ae1c,804078b4 +348ae20,40005 +348ae24,5341008f +348ae28,c81c01 +348ae2c,80407b10 +348ae30,804078b4 +348ae34,40006 +348ae38,534100a3 +348ae3c,c81c01 +348ae40,80407b10 +348ae44,804078b4 +348ae48,40007 +348ae4c,534100a5 +348ae50,c81c01 +348ae54,80407b10 +348ae58,804078b4 +348ae5c,40008 +348ae60,53410092 +348ae64,c81c01 +348ae68,80407b10 +348ae6c,804078b4 +348ae70,40009 +348ae74,53410093 +348ae78,aa0203 +348ae7c,80407b10 +348ae80,804078c8 +348ae84,3ffff +348ae88,53410094 +348ae8c,aa0203 +348ae90,80407b10 +348ae94,804078c8 +348ae98,4ffff +348ae9c,53410095 +348aea0,aa0203 +348aea4,80407b10 +348aea8,804078c8 +348aeac,5ffff +348aeb0,534100a6 +348aeb4,aa0203 +348aeb8,80407b10 +348aebc,804078c8 +348aec0,6ffff +348aec4,534100a9 +348aec8,aa0203 +348aecc,80407b10 +348aed0,804078c8 +348aed4,7ffff +348aed8,5341009b +348aedc,aa0203 +348aee0,80407b10 +348aee4,804078c8 +348aee8,8ffff +348aeec,5341009f +348aef0,aa0203 +348aef4,80407b10 +348aef8,804078c8 +348aefc,bffff +348af00,534100a0 +348af04,aa0203 +348af08,80407b10 +348af0c,804078c8 +348af10,cffff +348af14,534100a1 +348af18,aa0203 +348af1c,80407b10 +348af20,804078c8 +348af24,dffff +348af28,534100e9 +348af2c,1941300 +348af30,80407b10 +348af34,804078ec +348af38,ffffffff +348af3c,534100e4 +348af40,cd1e00 +348af44,80407b10 +348af48,80407908 +348af4c,ffffffff +348af50,534100e8 +348af54,cd1f00 +348af58,80407b10 +348af5c,80407924 +348af60,ffffffff +348af64,53410073 +348af68,b60300 +348af6c,80407b10 +348af70,80407954 +348af74,6ffff +348af78,53410074 +348af7c,b60400 +348af80,80407b10 +348af84,80407954 +348af88,7ffff +348af8c,53410075 +348af90,b60500 +348af94,80407b10 +348af98,80407954 +348af9c,8ffff +348afa0,53410076 +348afa4,b60600 +348afa8,80407b10 +348afac,80407954 +348afb0,9ffff +348afb4,53410077 +348afb8,b60700 +348afbc,80407b10 +348afc0,80407954 +348afc4,affff +348afc8,53410078 +348afcc,b60800 +348afd0,80407b10 +348afd4,80407954 +348afd8,bffff +348afdc,534100d4 +348afe0,b60400 +348afe4,80407b10 +348afe8,80407954 +348afec,cffff +348aff0,534100d2 +348aff4,b60600 +348aff8,80407b10 +348affc,80407954 +348b000,dffff +348b004,534100d1 +348b008,b60300 +348b00c,80407b10 +348b010,80407954 +348b014,effff +348b018,534100d3 +348b01c,b60800 +348b020,80407b10 +348b024,80407954 +348b028,fffff +348b02c,534100d5 +348b030,b60500 +348b034,80407b10 +348b038,80407954 +348b03c,10ffff +348b040,534100d6 +348b044,b60700 +348b048,80407b10 +348b04c,80407954 +348b050,11ffff +348b054,534100f8 +348b058,d12300 +348b05c,80407b10 +348b060,80407838 +348b064,3ffff +348b068,53149099 +348b06c,10b4500 +348b070,80407b10 +348b074,80407768 +348b078,ffffffff +348b07c,53419048 +348b080,f33e00 +348b084,80407b10 +348b088,80407988 +348b08c,ffffffff +348b090,53419003 +348b094,1933500 +348b098,80407b10 +348b09c,8040777c +348b0a0,ffffffff +348b0a8,1 +348b0ac,1 +348b0b0,d +348b0b4,41200000 +348b0b8,41200000 +348b0bc,8040a070 +348b0c0,8040a060 +348b0c8,df000000 +348b0d0,80112f1a +348b0d4,80112f14 +348b0d8,80112f0e +348b0dc,80112f08 +348b0e0,8011320a +348b0e4,80113204 +348b0e8,801131fe +348b0ec,801131f8 +348b0f0,801131f2 +348b0f4,801131ec +348b0f8,801131e6 +348b0fc,801131e0 +348b100,8012be1e +348b104,8012be20 +348b108,8012be1c +348b10c,8012be12 +348b110,8012be14 +348b114,8012be10 +348b118,801c7672 +348b11c,801c767a +348b120,801c7950 +348b124,8011bd50 +348b128,8011bd38 +348b12c,801d8b9e +348b130,801d8b92 +348b134,c80000 +348b13c,ff0046 +348b140,32ffff +348c288,db000 +348c28c,db000 +348c290,db000 +348c294,cb000 +348c298,cb000 +348c29c,ca000 +348c2a4,db000 +348c2a8,db000 +348c2c0,e8ac00 +348c2c4,e8ac00 +348c2c8,e8ac00 +348c2cc,e8ac00 +348c2f4,d77d0 +348c2f8,2e3ab0 +348c2fc,7d0c90 +348c300,8ffffffd +348c304,c96e00 +348c308,2e4ac00 +348c30c,effffff4 +348c310,ab0e500 +348c314,c95e000 +348c318,e59c000 +348c330,79000 +348c334,5ceeb40 +348c338,cc8a990 +348c33c,da79000 +348c340,8ecb400 +348c344,4adda0 +348c348,797e2 +348c34c,c88aae0 +348c350,6ceed70 +348c354,79000 +348c358,79000 +348c368,6dea0000 +348c36c,c94d6000 +348c370,c94d6033 +348c374,6deb6bc6 +348c378,8cb600 +348c37c,7ca4cec4 +348c380,3109c3bb +348c384,9c3bb +348c388,2ced4 +348c3a0,4cefb00 +348c3a4,ad50000 +348c3a8,8e30000 +348c3ac,9ec0000 +348c3b0,7e4db0ab +348c3b4,bb05e8aa +348c3b8,bc008ed6 +348c3bc,7e936ed0 +348c3c0,8ded9ea +348c3d8,ca000 +348c3dc,ca000 +348c3e0,ca000 +348c3e4,ca000 +348c408,c900 +348c40c,7e200 +348c410,cb000 +348c414,e8000 +348c418,6f3000 +348c41c,8e0000 +348c420,8e0000 +348c424,6f4000 +348c428,e8000 +348c42c,cb000 +348c430,7e200 +348c434,c900 +348c440,bb0000 +348c444,5e4000 +348c448,ca000 +348c44c,ad000 +348c450,7e100 +348c454,6f400 +348c458,6f400 +348c45c,7e100 +348c460,ad000 +348c464,ca000 +348c468,5e4000 +348c46c,bb0000 +348c480,a8000 +348c484,c8a8ab0 +348c488,3beda10 +348c48c,3beda10 +348c490,c8a8ab0 +348c494,a8000 +348c4bc,ca000 +348c4c0,ca000 +348c4c4,ca000 +348c4c8,affffff8 +348c4cc,ca000 +348c4d0,ca000 +348c4d4,ca000 +348c50c,dd000 +348c510,ec000 +348c514,4f8000 +348c518,9d0000 +348c53c,dffb00 +348c57c,ec000 +348c580,ec000 +348c598,bc0 +348c59c,4e60 +348c5a0,bc00 +348c5a4,3e800 +348c5a8,ad000 +348c5ac,1e9000 +348c5b0,9e2000 +348c5b4,da0000 +348c5b8,7e30000 +348c5bc,cb00000 +348c5c0,6e500000 +348c5d0,3ceeb00 +348c5d4,bd57e90 +348c5d8,e900bd0 +348c5dc,5f7009e0 +348c5e0,6f6cb9e0 +348c5e4,5f7009e0 +348c5e8,e900bd0 +348c5ec,bd57e90 +348c5f0,3ceeb00 +348c608,affe000 +348c60c,8e000 +348c610,8e000 +348c614,8e000 +348c618,8e000 +348c61c,8e000 +348c620,8e000 +348c624,8e000 +348c628,8ffffe0 +348c640,8deea00 +348c644,c837e90 +348c648,cc0 +348c64c,2ea0 +348c650,bd20 +348c654,bd400 +348c658,bd4000 +348c65c,bd40000 +348c660,2fffffd0 +348c678,7ceea00 +348c67c,c837e90 +348c680,cb0 +348c684,27e90 +348c688,bffb00 +348c68c,27da0 +348c690,ad0 +348c694,5c627db0 +348c698,9deeb30 +348c6b0,2de00 +348c6b4,bde00 +348c6b8,7d9e00 +348c6bc,2d79e00 +348c6c0,bb09e00 +348c6c4,6e409e00 +348c6c8,9ffffff7 +348c6cc,9e00 +348c6d0,9e00 +348c6e8,cffff50 +348c6ec,ca00000 +348c6f0,ca00000 +348c6f4,ceeea00 +348c6f8,38e90 +348c6fc,bc0 +348c700,bc0 +348c704,5c638e90 +348c708,9deda00 +348c720,aeec30 +348c724,ae83980 +348c728,e900000 +348c72c,4faeec40 +348c730,6fd55dc0 +348c734,5f9009e0 +348c738,e9009e0 +348c73c,cd55dc0 +348c740,3ceec40 +348c758,5fffffd0 +348c75c,da0 +348c760,7e40 +348c764,cc00 +348c768,4e800 +348c76c,ad000 +348c770,da000 +348c774,8e4000 +348c778,cc0000 +348c790,5ceec30 +348c794,dc45db0 +348c798,e900bd0 +348c79c,bc45d90 +348c7a0,4dffc20 +348c7a4,1db45cc0 +348c7a8,5f6009e0 +348c7ac,2eb35cd0 +348c7b0,7deec50 +348c7c8,6deeb00 +348c7cc,db37e90 +348c7d0,5f500bd0 +348c7d4,5f500be0 +348c7d8,db37ee0 +348c7dc,6dedbe0 +348c7e0,bc0 +348c7e4,9749e70 +348c7e8,5ded800 +348c808,ec000 +348c80c,ec000 +348c81c,ec000 +348c820,ec000 +348c840,ec000 +348c844,ec000 +348c854,dd000 +348c858,ec000 +348c85c,4f8000 +348c860,9d0000 +348c878,29c8 +348c87c,7bed93 +348c880,8dda4000 +348c884,8dda4000 +348c888,7bec93 +348c88c,29c8 +348c8b4,affffff8 +348c8c0,affffff8 +348c8e8,ac810000 +348c8ec,4adeb600 +348c8f0,6add6 +348c8f4,6add6 +348c8f8,4adeb600 +348c8fc,ac810000 +348c918,4beec30 +348c91c,9a46ea0 +348c920,1da0 +348c924,2cd30 +348c928,cc100 +348c92c,e9000 +348c934,e9000 +348c938,e9000 +348c950,1aeed70 +348c954,cd739e4 +348c958,7e2000c9 +348c95c,ba0aeeca +348c960,d76e64da +348c964,d69c00aa +348c968,d76e64da +348c96c,ba0aeeca +348c970,6e400000 +348c974,ad83000 +348c978,8dee90 +348c988,3ed000 +348c98c,9de600 +348c990,cbcb00 +348c994,3e8ad00 +348c998,8e26f60 +348c99c,cc00ea0 +348c9a0,2effffd0 +348c9a4,8e5008f5 +348c9a8,cd0001ea +348c9c0,effec40 +348c9c4,e905dc0 +348c9c8,e900ae0 +348c9cc,e905dc0 +348c9d0,efffd50 +348c9d4,e904bd2 +348c9d8,e9005f6 +348c9dc,e904be3 +348c9e0,effed80 +348c9f8,9ded80 +348c9fc,8e936b0 +348ca00,db00000 +348ca04,3f900000 +348ca08,5f700000 +348ca0c,1e900000 +348ca10,db00000 +348ca14,8e947b0 +348ca18,9ded80 +348ca30,5ffed800 +348ca34,5f65ae80 +348ca38,5f600cd0 +348ca3c,5f6009e0 +348ca40,5f6009f0 +348ca44,5f6009e0 +348ca48,5f600cd0 +348ca4c,5f65ae80 +348ca50,5ffed800 +348ca68,dffffe0 +348ca6c,db00000 +348ca70,db00000 +348ca74,db00000 +348ca78,dffffc0 +348ca7c,db00000 +348ca80,db00000 +348ca84,db00000 +348ca88,dfffff0 +348caa0,bfffff4 +348caa4,bd00000 +348caa8,bd00000 +348caac,bd00000 +348cab0,bffffc0 +348cab4,bd00000 +348cab8,bd00000 +348cabc,bd00000 +348cac0,bd00000 +348cad8,1aeed60 +348cadc,be738a0 +348cae0,4e900000 +348cae4,8f400000 +348cae8,9f10bff2 +348caec,7f4007f2 +348caf0,4e9007f2 +348caf4,be739f2 +348caf8,1beed90 +348cb10,5f6009e0 +348cb14,5f6009e0 +348cb18,5f6009e0 +348cb1c,5f6009e0 +348cb20,5fffffe0 +348cb24,5f6009e0 +348cb28,5f6009e0 +348cb2c,5f6009e0 +348cb30,5f6009e0 +348cb48,dffffb0 +348cb4c,db000 +348cb50,db000 +348cb54,db000 +348cb58,db000 +348cb5c,db000 +348cb60,db000 +348cb64,db000 +348cb68,dffffb0 +348cb80,cfff40 +348cb84,7f40 +348cb88,7f40 +348cb8c,7f40 +348cb90,7f40 +348cb94,7f30 +348cb98,75009e00 +348cb9c,8d64dc00 +348cba0,2beec500 +348cbb8,5f6009e7 +348cbbc,5f609e70 +348cbc0,5f69e700 +348cbc4,5fbe8000 +348cbc8,5fedb000 +348cbcc,5f87e800 +348cbd0,5f60ae40 +348cbd4,5f601dc0 +348cbd8,5f6006ea +348cbf0,cc00000 +348cbf4,cc00000 +348cbf8,cc00000 +348cbfc,cc00000 +348cc00,cc00000 +348cc04,cc00000 +348cc08,cc00000 +348cc0c,cc00000 +348cc10,cfffff7 +348cc28,afa00cf8 +348cc2c,aed02ee8 +348cc30,add59be8 +348cc34,adaac8e8 +348cc38,ad5de1e8 +348cc3c,ad0db0e8 +348cc40,ad0000e8 +348cc44,ad0000e8 +348cc48,ad0000e8 +348cc60,5fc008e0 +348cc64,5fe608e0 +348cc68,5fcb08e0 +348cc6c,5f7e48e0 +348cc70,5f5ca8e0 +348cc74,5f57e8e0 +348cc78,5f50dce0 +348cc7c,5f509ee0 +348cc80,5f502ee0 +348cc98,4ceeb20 +348cc9c,cd56ea0 +348cca0,3e800ae0 +348cca4,7f5008f2 +348cca8,7f4008f4 +348ccac,7f5008f2 +348ccb0,3e800ae0 +348ccb4,cd56eb0 +348ccb8,4ceeb20 +348ccd0,dffed60 +348ccd4,db05ce2 +348ccd8,db006f6 +348ccdc,db006f6 +348cce0,db05ce2 +348cce4,dffed60 +348cce8,db00000 +348ccec,db00000 +348ccf0,db00000 +348cd08,4ceeb20 +348cd0c,cd56ea0 +348cd10,3e800ae0 +348cd14,7f5008f2 +348cd18,7f4008f4 +348cd1c,7f5008f1 +348cd20,3e800ad0 +348cd24,cd56ea0 +348cd28,4cefc20 +348cd2c,ae50 +348cd30,c80 +348cd40,5ffeeb20 +348cd44,5f717eb0 +348cd48,5f700cd0 +348cd4c,5f716ea0 +348cd50,5fffea00 +348cd54,5f72ae40 +348cd58,5f700db0 +348cd5c,5f7008e5 +348cd60,5f7000db +348cd78,6ceeb30 +348cd7c,dc45a90 +348cd80,4f600000 +348cd84,ec60000 +348cd88,5ceeb40 +348cd8c,6cc0 +348cd90,8e0 +348cd94,c735cd0 +348cd98,8deec50 +348cdb0,cffffffb +348cdb4,db000 +348cdb8,db000 +348cdbc,db000 +348cdc0,db000 +348cdc4,db000 +348cdc8,db000 +348cdcc,db000 +348cdd0,db000 +348cde8,4f7009e0 +348cdec,4f7009e0 +348cdf0,4f7009e0 +348cdf4,4f7009e0 +348cdf8,4f7009e0 +348cdfc,3f7009e0 +348ce00,2e700ad0 +348ce04,dc45dc0 +348ce08,5ceec40 +348ce20,ad0003e8 +348ce24,6f5008e3 +348ce28,e900bc0 +348ce2c,bc00d90 +348ce30,8e15e40 +348ce34,2e7ad00 +348ce38,cbca00 +348ce3c,9de600 +348ce40,3ed000 +348ce58,e80000ad +348ce5c,da0000cb +348ce60,cb0000da +348ce64,ac0ec0e8 +348ce68,8d6de1e5 +348ce6c,6e9bd8e0 +348ce70,1ec8acd0 +348ce74,de37ec0 +348ce78,cd00ea0 +348ce90,6e7007e7 +348ce94,ad21db0 +348ce98,2daad20 +348ce9c,7ee700 +348cea0,3ee200 +348cea4,bdda00 +348cea8,7e67e60 +348ceac,3ea00bd0 +348ceb0,bd2004e9 +348cec8,ae2005e8 +348cecc,2da00cc0 +348ced0,7e57e50 +348ced4,ccda00 +348ced8,4ed200 +348cedc,db000 +348cee0,db000 +348cee4,db000 +348cee8,db000 +348cf00,efffff8 +348cf04,bd3 +348cf08,7e70 +348cf0c,3ea00 +348cf10,bd100 +348cf14,8e5000 +348cf18,4e90000 +348cf1c,cc00000 +348cf20,1ffffffa +348cf30,4ffc00 +348cf34,4f5000 +348cf38,4f5000 +348cf3c,4f5000 +348cf40,4f5000 +348cf44,4f5000 +348cf48,4f5000 +348cf4c,4f5000 +348cf50,4f5000 +348cf54,4f5000 +348cf58,4f5000 +348cf5c,4ffc00 +348cf70,6e500000 +348cf74,cb00000 +348cf78,7e30000 +348cf7c,da0000 +348cf80,9e2000 +348cf84,1e9000 +348cf88,ad000 +348cf8c,3e800 +348cf90,bc00 +348cf94,4e60 +348cf98,bc0 +348cfa0,dfe000 +348cfa4,8e000 +348cfa8,8e000 +348cfac,8e000 +348cfb0,8e000 +348cfb4,8e000 +348cfb8,8e000 +348cfbc,8e000 +348cfc0,8e000 +348cfc4,8e000 +348cfc8,8e000 +348cfcc,dfe000 +348cfe0,5ed200 +348cfe4,dcdb00 +348cfe8,ad25e80 +348cfec,7e5007e5 +348d044,fffffffd +348d04c,2ca0000 +348d050,2c9000 +348d090,5ceeb10 +348d094,b936da0 +348d098,bc0 +348d09c,8deffc0 +348d0a0,3e930bd0 +348d0a4,4f827ed0 +348d0a8,aeedbd0 +348d0b8,d900000 +348d0bc,d900000 +348d0c0,d900000 +348d0c4,d900000 +348d0c8,dbdec40 +348d0cc,de65dc0 +348d0d0,db008e0 +348d0d4,da007f2 +348d0d8,db008e0 +348d0dc,de64db0 +348d0e0,dbdec40 +348d100,8ded70 +348d104,7e936a0 +348d108,cc00000 +348d10c,db00000 +348d110,cc00000 +348d114,7e936a0 +348d118,8ded70 +348d128,bc0 +348d12c,bc0 +348d130,bc0 +348d134,bc0 +348d138,5dedcc0 +348d13c,dc48ec0 +348d140,5f600cc0 +348d144,7f300bc0 +348d148,5f600cc0 +348d14c,dc48ec0 +348d150,5dedcc0 +348d170,3beec30 +348d174,cd54cc0 +348d178,4f6007e0 +348d17c,6ffffff3 +348d180,4f500000 +348d184,cc538c0 +348d188,3beec60 +348d198,5ded0 +348d19c,cb200 +348d1a0,d9000 +348d1a4,e8000 +348d1a8,dffffd0 +348d1ac,e8000 +348d1b0,e8000 +348d1b4,e8000 +348d1b8,e8000 +348d1bc,e8000 +348d1c0,e8000 +348d1e0,5dedcc0 +348d1e4,dc48ec0 +348d1e8,5f600cc0 +348d1ec,7f300bc0 +348d1f0,5f600cc0 +348d1f4,dc48ec0 +348d1f8,5dedcb0 +348d1fc,ca0 +348d200,9947e60 +348d204,4cee900 +348d208,da00000 +348d20c,da00000 +348d210,da00000 +348d214,da00000 +348d218,dbded40 +348d21c,de65da0 +348d220,db00bc0 +348d224,da00bc0 +348d228,da00bc0 +348d22c,da00bc0 +348d230,da00bc0 +348d240,bc000 +348d250,9ffc000 +348d254,bc000 +348d258,bc000 +348d25c,bc000 +348d260,bc000 +348d264,bc000 +348d268,effffe0 +348d278,7e000 +348d288,7ffe000 +348d28c,7e000 +348d290,7e000 +348d294,7e000 +348d298,7e000 +348d29c,7e000 +348d2a0,7e000 +348d2a4,7e000 +348d2a8,1bd000 +348d2ac,dfe7000 +348d2b0,bc00000 +348d2b4,bc00000 +348d2b8,bc00000 +348d2bc,bc00000 +348d2c0,bc03dc2 +348d2c4,bc3db00 +348d2c8,bddc000 +348d2cc,bfce500 +348d2d0,bd0cd10 +348d2d4,bc03db0 +348d2d8,bc007e8 +348d2e8,eff4000 +348d2ec,5f4000 +348d2f0,5f4000 +348d2f4,5f4000 +348d2f8,5f4000 +348d2fc,5f4000 +348d300,5f4000 +348d304,5f4000 +348d308,4f5000 +348d30c,ea000 +348d310,8efb0 +348d330,8dddaec0 +348d334,8e4dc5e4 +348d338,8d0cb0e6 +348d33c,8d0ba0e7 +348d340,8d0ba0e7 +348d344,8d0ba0e7 +348d348,8d0ba0e7 +348d368,dbded40 +348d36c,de65da0 +348d370,db00bc0 +348d374,da00bc0 +348d378,da00bc0 +348d37c,da00bc0 +348d380,da00bc0 +348d3a0,4ceeb20 +348d3a4,cd56da0 +348d3a8,1e700ad0 +348d3ac,5f6008e0 +348d3b0,1e700ad0 +348d3b4,cd46db0 +348d3b8,4ceeb20 +348d3d8,dbdec30 +348d3dc,de65db0 +348d3e0,db009e0 +348d3e4,da007e0 +348d3e8,db008e0 +348d3ec,de65db0 +348d3f0,dbeec40 +348d3f4,d900000 +348d3f8,d900000 +348d3fc,d900000 +348d410,4cedcc0 +348d414,cc47ec0 +348d418,1e700cc0 +348d41c,5f600bc0 +348d420,2e700cc0 +348d424,cc47ec0 +348d428,5cedbc0 +348d42c,ac0 +348d430,ac0 +348d434,ac0 +348d448,ccdef9 +348d44c,ce8300 +348d450,cb0000 +348d454,ca0000 +348d458,ca0000 +348d45c,ca0000 +348d460,ca0000 +348d480,4ceea10 +348d484,bd45b60 +348d488,bd40000 +348d48c,3bddb20 +348d490,4da0 +348d494,b945ea0 +348d498,5ceeb20 +348d4b0,8e0000 +348d4b4,8e0000 +348d4b8,6fffffb0 +348d4bc,8e0000 +348d4c0,8e0000 +348d4c4,8e0000 +348d4c8,8e0000 +348d4cc,6e7000 +348d4d0,befb0 +348d4f0,da00bc0 +348d4f4,da00bc0 +348d4f8,da00bc0 +348d4fc,da00bc0 +348d500,da00bc0 +348d504,bd47ec0 +348d508,5dedbc0 +348d528,6e3007e3 +348d52c,d900bc0 +348d530,ad01e80 +348d534,5e48e20 +348d538,dacb00 +348d53c,9de700 +348d540,3ee000 +348d560,e80000ac +348d564,ca0000ca +348d568,ac0db0e7 +348d56c,6e3dd5e2 +348d570,eabcad0 +348d574,ce79eb0 +348d578,ae15f80 +348d598,3da00bc0 +348d59c,6e69e40 +348d5a0,9ee700 +348d5a4,2ed000 +348d5a8,ccda00 +348d5ac,9e46e70 +348d5b0,6e7009e4 +348d5d0,6e5005e5 +348d5d4,da00bd0 +348d5d8,9e00e90 +348d5dc,3e78e30 +348d5e0,cccc00 +348d5e4,7ee700 +348d5e8,de000 +348d5ec,da000 +348d5f0,8e5000 +348d5f4,dea0000 +348d608,bffffc0 +348d60c,5e70 +348d610,3d900 +348d614,cb000 +348d618,bd2000 +348d61c,9e40000 +348d620,dffffc0 +348d630,6dea0 +348d634,bd300 +348d638,cb000 +348d63c,cb000 +348d640,5ea000 +348d644,bfd2000 +348d648,7e9000 +348d64c,db000 +348d650,cb000 +348d654,cb000 +348d658,bd400 +348d65c,5dea0 +348d668,ca000 +348d66c,ca000 +348d670,ca000 +348d674,ca000 +348d678,ca000 +348d67c,ca000 +348d680,ca000 +348d684,ca000 +348d688,ca000 +348d68c,ca000 +348d690,ca000 +348d694,ca000 +348d698,ca000 +348d6a0,bed3000 +348d6a4,4e9000 +348d6a8,da000 +348d6ac,ca000 +348d6b0,bc400 +348d6b4,5efa0 +348d6b8,bd500 +348d6bc,cb000 +348d6c0,da000 +348d6c4,da000 +348d6c8,5e8000 +348d6cc,bec2000 +348d6f0,5ded83a7 +348d6f4,9838dec3 +348d768,7f024429 +348d76c,3c334133 +348d770,41334633 +348d774,44297f02 +348d7a4,5409 +348d7a8,4dc548ff +348d7ac,41ff43ff +348d7b0,47ff49ff +348d7b4,43ff20c5 +348d7b8,c0000 +348d7e4,3f75 +348d7e8,49ff33ff +348d7ec,28ff2dff +348d7f0,33ff39ff +348d7f4,3cff00ff +348d7f8,770000 +348d824,329d +348d828,37ff1bff +348d82c,21ff28ff +348d830,2fff35ff +348d834,3cff00ff +348d838,9d0000 +348d864,329e +348d868,35ff21ff +348d86c,28ff06ff +348d870,9ff3cff +348d874,42ff00ff +348d878,9e0000 +348d8a4,359e +348d8a8,39ff27ff +348d8ac,2eff00ff +348d8b0,2ff42ff +348d8b4,48ff00ff +348d8b8,9e0000 +348d8e4,3a9e +348d8e8,3eff2eff +348d8ec,35ff00ff +348d8f0,dff48ff +348d8f4,4dff00ff +348d8f8,9e0000 +348d924,3e9e +348d928,42ff35ff +348d92c,3bff1bff +348d930,27ff4dff +348d934,53ff00ff +348d938,9e0000 +348d964,439e +348d968,47ff3bff +348d96c,41ff47ff +348d970,4dff52ff +348d974,58ff00ff +348d978,9e0000 +348d9a4,4d9e +348d9a8,4dff41ff +348d9ac,47ff4dff +348d9b0,52ff57ff +348d9b4,5cff00ff +348d9b8,9e0000 +348d9d4,3f04474f +348d9d8,3e663e66 +348d9dc,43664666 +348d9e0,48664d66 +348d9e4,57665bc5 +348d9e8,53ff47ff +348d9ec,4dff52ff +348d9f0,57ff5cff +348d9f4,60ff0eff +348d9f8,19c56666 +348d9fc,66666466 +348da00,61665f66 +348da04,5c665a66 +348da08,504f3f04 +348da10,6605 +348da14,4ec34bff +348da18,41ff41ff +348da1c,45ff48ff +348da20,4cff4fff +348da24,55ff59ff +348da28,4fff4dff +348da2c,52ff57ff +348da30,5cff60ff +348da34,64ff61ff +348da38,67ff66ff +348da3c,64ff62ff +348da40,60ff5dff +348da44,5bff57ff +348da48,49ff0ec3 +348da4c,50000 +348da50,3958 +348da54,44ff31ff +348da58,20ff25ff +348da5c,2bff31ff +348da60,38ff3eff +348da64,44ff49ff +348da68,4dff52ff +348da6c,57ff5cff +348da70,60ff64ff +348da74,68ff67ff +348da78,64ff60ff +348da7c,5cff58ff +348da80,53ff4eff +348da84,48ff43ff +348da88,32ff00ff +348da8c,580000 +348da90,2f71 +348da94,36ff1dff +348da98,1fff26ff +348da9c,2dff34ff +348daa0,3aff41ff +348daa4,47ff4cff +348daa8,52ff57ff +348daac,5cff60ff +348dab0,64ff68ff +348dab4,67ff64ff +348dab8,60ff5bff +348dabc,57ff51ff +348dac0,4cff46ff +348dac4,40ff3aff +348dac8,27ff00ff +348dacc,710000 +348dad0,2f71 +348dad4,36ff21ff +348dad8,16ff00ff +348dadc,ff00ff +348dae0,2cff47ff +348dae4,4cff52ff +348dae8,57ff5cff +348daec,60ff64ff +348daf0,67ff67ff +348daf4,64ff60ff +348daf8,5bff57ff +348dafc,52ff0dff +348db00,ff00ff +348db04,aff33ff +348db08,21ff00ff +348db0c,710000 +348db10,3371 +348db14,3aff28ff +348db18,22ff0fff +348db1c,13ff19ff +348db20,39ff4cff +348db24,52ff57ff +348db28,5bff60ff +348db2c,64ff67ff +348db30,67ff64ff +348db34,60ff5cff +348db38,57ff52ff +348db3c,4cff1dff +348db40,12ff14ff +348db44,19ff2dff +348db48,1bff00ff +348db4c,710000 +348db50,3871 +348db54,3dff2fff +348db58,33ff3aff +348db5c,40ff46ff +348db60,4cff51ff +348db64,57ff5bff +348db68,60ff64ff +348db6c,67ff68ff +348db70,64ff60ff +348db74,5cff57ff +348db78,52ff4cff +348db7c,47ff41ff +348db80,3aff34ff +348db84,2dff26ff +348db88,12ff00ff +348db8c,710000 +348db90,3569 +348db94,37ff33ff +348db98,3aff40ff +348db9c,46ff4cff +348dba0,51ff57ff +348dba4,5bff60ff +348dba8,64ff67ff +348dbac,68ff64ff +348dbb0,60ff5cff +348dbb4,57ff52ff +348dbb8,4dff47ff +348dbbc,41ff3aff +348dbc0,34ff2dff +348dbc4,26ff1fff +348dbc8,6ff00ff +348dbcc,690000 +348dbd0,1e21 +348dbd4,2f600ff +348dbd8,ff00ff +348dbdc,ff00ff +348dbe0,ff00ff +348dbe4,2ff1eff +348dbe8,60ff68ff +348dbec,64ff60ff +348dbf0,5cff57ff +348dbf4,52ff2cff +348dbf8,6ff00ff +348dbfc,ff00ff +348dc00,ff00ff +348dc04,ff00ff +348dc08,ff00f6 +348dc0c,210000 +348dc14,3b00ae +348dc18,cc00cc +348dc1c,cc00cc +348dc20,cc00cc +348dc24,cc03ec +348dc28,62ff64ff +348dc2c,60ff5cff +348dc30,57ff52ff +348dc34,4dff00ff +348dc38,ec00cc +348dc3c,cc00cc +348dc40,cc00cc +348dc44,cc00cc +348dc48,ae003b +348dc64,5f9e +348dc68,65ff60ff +348dc6c,5cff57ff +348dc70,52ff4dff +348dc74,47ff00ff +348dc78,9e0000 +348dca4,659e +348dca8,63ff5cff +348dcac,57ff52ff +348dcb0,4dff47ff +348dcb4,41ff00ff +348dcb8,9e0000 +348dce4,649e +348dce8,61ff58ff +348dcec,53ff35ff +348dcf0,31ff41ff +348dcf4,3bff00ff +348dcf8,9e0000 +348dd24,609e +348dd28,5eff53ff +348dd2c,4dff00ff +348dd30,ff3bff +348dd34,35ff00ff +348dd38,9e0000 +348dd64,5d9e +348dd68,5bff4dff +348dd6c,48ff00ff +348dd70,6ff35ff +348dd74,2eff00ff +348dd78,9e0000 +348dda4,5a9e +348dda8,57ff48ff +348ddac,42ff03ff +348ddb0,cff2eff +348ddb4,28ff00ff +348ddb8,9e0000 +348dde4,559e +348dde8,53ff42ff +348ddec,3cff2dff +348ddf0,28ff28ff +348ddf4,1fff00ff +348ddf8,9e0000 +348de24,4b91 +348de28,44ff33ff +348de2c,35ff2fff +348de30,28ff1fff +348de34,7ff00ff +348de38,900000 +348de64,1229 +348de68,f700ff +348de6c,ff00ff +348de70,ff00ff +348de74,ff00f8 +348de78,2e0000 +348dea8,30008c +348deac,990099 +348deb0,990099 +348deb4,8c0030 +348df10,f0f0f0f0 +348df14,f0f0f0f0 +348df18,f0f0f0f0 +348df1c,f0f0f0f0 +348df20,f0f0f0f0 +348df24,f0f0f0f0 +348df28,dff0f0f0 +348df2c,f0f0f0f0 +348df30,f0f0f0f0 +348df34,f0f0f0df +348df38,dff0f0f0 +348df3c,f0f0f0f0 +348df40,f0f0f0f0 +348df44,f0f0f0df +348df48,dfcff0f0 +348df4c,f0f0f0f0 +348df50,f0f0f0f0 +348df54,f0f0cfcf +348df58,cfcff0f0 +348df5c,f0f0f0f0 +348df60,f0f0f0f0 +348df64,f0f0cfcf +348df68,cfcfcff0 +348df6c,f0f0f0f0 +348df70,f0f0f0f0 +348df74,f0cfcfcf +348df78,cfcfcff0 +348df7c,f0f0f0f0 +348df80,f0f0f0f0 +348df84,f0cfcfcf +348df88,cfcfcfcf +348df8c,f0f0f0f0 +348df90,f0f0f0f0 +348df94,cfcfcfcf +348df98,cfbfbfbf +348df9c,f0f0f0f0 +348dfa0,f0f0f0f0 +348dfa4,bfbfbfbf +348dfa8,bfbfbfbf +348dfac,f0f0f0f0 +348dfb0,f0f0f0bf +348dfb4,bfbfbfbf +348dfb8,bfbfbfbf +348dfbc,bff0f0f0 +348dfc0,f0f0f0bf +348dfc4,bfbff0f0 +348dfc8,f0f0f0f0 +348dfcc,f0f0f0f0 +348dfd0,f0f0f0f0 +348dfd4,f0f0f0f0 +348dfd8,f0f0f0f0 +348dfdc,f0f0f0f0 +348dfe0,f0f0f0f0 +348dfe4,f0f0f0f0 +348dfe8,f0f0f0f0 +348dfec,f0f0f0f0 +348dff0,f0f0f0f0 +348dff4,f0f0f0f0 +348dff8,f0f0f0f0 +348dffc,f0f0f0f0 +348e000,f0f0f0f0 +348e004,f0f0f0f0 +348e008,f0f0f0f0 +348e00c,f0f0f0f0 +348e010,f0f0f0f0 +348e014,f0f0f0f0 +348e018,f0f0f0f0 +348e01c,f0f0f0f0 +348e020,f0f0f0f0 +348e024,f0f0f0cf +348e028,cff0f0f0 +348e02c,f0f0f0f0 +348e030,f0f0f0f0 +348e034,f0f0f0cf +348e038,cfcff0f0 +348e03c,f0f0f0f0 +348e040,f0f0f0f0 +348e044,f0f0bfcf +348e048,cfcff0f0 +348e04c,f0f0f0f0 +348e050,f0f0f0f0 +348e054,f0f0bfcf +348e058,cfcff0f0 +348e05c,f0f0f0f0 +348e060,f0f0f0f0 +348e064,f0bfcfbf +348e068,bfbfbff0 +348e06c,f0f0f0f0 +348e070,f0f0f0f0 +348e074,f0bfbfbf +348e078,bfbfbff0 +348e07c,f0f0f0f0 +348e080,f0f0f0f0 +348e084,bfbfbfbf +348e088,bfbfbfbf +348e08c,f0f0f0f0 +348e090,f0f0f0f0 +348e094,bfbfbfbf +348e098,bfbfbfbf +348e09c,f0f0f0f0 +348e0a0,f0f0f0f0 +348e0a4,bfbfbfbf +348e0a8,bfbfbfaf +348e0ac,f0f0f0f0 +348e0b0,f0f0f0af +348e0b4,bfbfbfbf +348e0b8,afafaff0 +348e0bc,f0f0f0f0 +348e0c0,f0f0f0bf +348e0c4,bfbfaff0 +348e0c8,f0f0f0f0 +348e0cc,f0f0f0f0 +348e0d0,f0f0f0f0 +348e0d4,f0f0f0f0 +348e0d8,f0f0f0f0 +348e0dc,f0f0f0f0 +348e0e0,f0f0f0f0 +348e0e4,f0f0f0f0 +348e0e8,f0f0f0f0 +348e0ec,f0f0f0f0 +348e0f0,f0f0f0f0 +348e0f4,f0f0f0f0 +348e0f8,f0f0f0f0 +348e0fc,f0f0f0f0 +348e100,f0f0f0f0 +348e104,f0f0f0f0 +348e108,f0f0f0f0 +348e10c,f0f0f0f0 +348e110,f0f0f0f0 +348e114,f0f0f0f0 +348e118,f0f0f0f0 +348e11c,f0f0f0f0 +348e120,f0f0f0f0 +348e124,f0f0f0ef +348e128,eff0f0f0 +348e12c,f0f0f0f0 +348e130,f0f0f0f0 +348e134,f0f0f0ef +348e138,bfbff0f0 +348e13c,f0f0f0f0 +348e140,f0f0f0f0 +348e144,f0f0dfdf +348e148,bfbff0f0 +348e14c,f0f0f0f0 +348e150,f0f0f0f0 +348e154,f0f0dfbf +348e158,afaff0f0 +348e15c,f0f0f0f0 +348e160,f0f0f0f0 +348e164,f0dfdfaf +348e168,afafaff0 +348e16c,f0f0f0f0 +348e170,f0f0f0f0 +348e174,f0dfafaf +348e178,afafaff0 +348e17c,f0f0f0f0 +348e180,f0f0f0f0 +348e184,dfdfafaf +348e188,afafaff0 +348e18c,f0f0f0f0 +348e190,f0f0f0f0 +348e194,dfdfafaf +348e198,afafaf9f +348e19c,f0f0f0f0 +348e1a0,f0f0f0f0 +348e1a4,cfafafaf +348e1a8,afaf9f9f +348e1ac,f0f0f0f0 +348e1b0,f0f0f0cf +348e1b4,cfafafaf +348e1b8,9f9ff0f0 +348e1bc,f0f0f0f0 +348e1c0,f0f0f0cf +348e1c4,afafaf9f +348e1c8,f0f0f0f0 +348e1cc,f0f0f0f0 +348e1d0,f0f0f0cf +348e1d4,aff0f0f0 +348e1d8,f0f0f0f0 +348e1dc,f0f0f0f0 +348e1e0,f0f0f0f0 +348e1e4,f0f0f0f0 +348e1e8,f0f0f0f0 +348e1ec,f0f0f0f0 +348e1f0,f0f0f0f0 +348e1f4,f0f0f0f0 +348e1f8,f0f0f0f0 +348e1fc,f0f0f0f0 +348e200,f0f0f0f0 +348e204,f0f0f0f0 +348e208,f0f0f0f0 +348e20c,f0f0f0f0 +348e210,f0f0f0f0 +348e214,f0f0f0f0 +348e218,f0f0f0f0 +348e21c,f0f0f0f0 +348e220,f0f0f0f0 +348e224,f0f0f0ff +348e228,ff9ff0f0 +348e22c,f0f0f0f0 +348e230,f0f0f0f0 +348e234,f0f0ffff +348e238,ff9ff0f0 +348e23c,f0f0f0f0 +348e240,f0f0f0f0 +348e244,f0f0ffff +348e248,9f9ff0f0 +348e24c,f0f0f0f0 +348e250,f0f0f0f0 +348e254,f0f0ffff +348e258,9f9ff0f0 +348e25c,f0f0f0f0 +348e260,f0f0f0f0 +348e264,f0efef9f +348e268,9f9f9ff0 +348e26c,f0f0f0f0 +348e270,f0f0f0f0 +348e274,f0efef9f +348e278,9f9f8ff0 +348e27c,f0f0f0f0 +348e280,f0f0f0f0 +348e284,f0efef9f +348e288,9f8f8ff0 +348e28c,f0f0f0f0 +348e290,f0f0f0f0 +348e294,efef9f9f +348e298,8f8f8ff0 +348e29c,f0f0f0f0 +348e2a0,f0f0f0f0 +348e2a4,efef9f8f +348e2a8,8f8f8ff0 +348e2ac,f0f0f0f0 +348e2b0,f0f0f0ef +348e2b4,efef8f8f +348e2b8,8f8ff0f0 +348e2bc,f0f0f0f0 +348e2c0,f0f0f0ef +348e2c4,ef8f8f8f +348e2c8,f0f0f0f0 +348e2cc,f0f0f0f0 +348e2d0,f0f0f0ef +348e2d4,ef8f8ff0 +348e2d8,f0f0f0f0 +348e2dc,f0f0f0f0 +348e2e0,f0f0f0f0 +348e2e4,8ff0f0f0 +348e2e8,f0f0f0f0 +348e2ec,f0f0f0f0 +348e2f0,f0f0f0f0 +348e2f4,f0f0f0f0 +348e2f8,f0f0f0f0 +348e2fc,f0f0f0f0 +348e300,f0f0f0f0 +348e304,f0f0f0f0 +348e308,f0f0f0f0 +348e30c,f0f0f0f0 +348e310,f0f0f0f0 +348e314,f0f0f0f0 +348e318,f0f0f0f0 +348e31c,f0f0f0f0 +348e320,f0f0f0f0 +348e324,f0f0f0ff +348e328,ff7ff0f0 +348e32c,f0f0f0f0 +348e330,f0f0f0f0 +348e334,f0f0ffff +348e338,ff7ff0f0 +348e33c,f0f0f0f0 +348e340,f0f0f0f0 +348e344,f0f0ffff +348e348,ff7ff0f0 +348e34c,f0f0f0f0 +348e350,f0f0f0f0 +348e354,f0f0ffff +348e358,7f7ff0f0 +348e35c,f0f0f0f0 +348e360,f0f0f0f0 +348e364,f0ffffff +348e368,7f7ff0f0 +348e36c,f0f0f0f0 +348e370,f0f0f0f0 +348e374,f0ffffff +348e378,7f7ff0f0 +348e37c,f0f0f0f0 +348e380,f0f0f0f0 +348e384,f0ffff7f +348e388,7f7f7ff0 +348e38c,f0f0f0f0 +348e390,f0f0f0f0 +348e394,ffffff7f +348e398,7f7f6ff0 +348e39c,f0f0f0f0 +348e3a0,f0f0f0f0 +348e3a4,ffffff7f +348e3a8,7f6f6ff0 +348e3ac,f0f0f0f0 +348e3b0,f0f0f0f0 +348e3b4,ffffff7f +348e3b8,7f6ff0f0 +348e3bc,f0f0f0f0 +348e3c0,f0f0f0f0 +348e3c4,ffff7f7f +348e3c8,f0f0f0f0 +348e3cc,f0f0f0f0 +348e3d0,f0f0f0ff +348e3d4,ffff7ff0 +348e3d8,f0f0f0f0 +348e3dc,f0f0f0f0 +348e3e0,f0f0f0f0 +348e3e4,fffff0f0 +348e3e8,f0f0f0f0 +348e3ec,f0f0f0f0 +348e3f0,f0f0f0f0 +348e3f4,f0f0f0f0 +348e3f8,f0f0f0f0 +348e3fc,f0f0f0f0 +348e400,f0f0f0f0 +348e404,f0f0f0f0 +348e408,f0f0f0f0 +348e40c,f0f0f0f0 +348e410,f0f0f0f0 +348e414,f0f0f0f0 +348e418,f0f0f0f0 +348e41c,f0f0f0f0 +348e420,f0f0f0f0 +348e424,f0f0ffff +348e428,ff5ff0f0 +348e42c,f0f0f0f0 +348e430,f0f0f0f0 +348e434,f0f0ffff +348e438,ff5ff0f0 +348e43c,f0f0f0f0 +348e440,f0f0f0f0 +348e444,f0f0ffff +348e448,ff5ff0f0 +348e44c,f0f0f0f0 +348e450,f0f0f0f0 +348e454,f0f0ffff +348e458,ff5ff0f0 +348e45c,f0f0f0f0 +348e460,f0f0f0f0 +348e464,f0f0ffff +348e468,ff5ff0f0 +348e46c,f0f0f0f0 +348e470,f0f0f0f0 +348e474,f0ffffff +348e478,5f5ff0f0 +348e47c,f0f0f0f0 +348e480,f0f0f0f0 +348e484,f0ffffff +348e488,5f5ff0f0 +348e48c,f0f0f0f0 +348e490,f0f0f0f0 +348e494,f0ffffff +348e498,5f5ff0f0 +348e49c,f0f0f0f0 +348e4a0,f0f0f0f0 +348e4a4,f0ffffff +348e4a8,5f5ff0f0 +348e4ac,f0f0f0f0 +348e4b0,f0f0f0f0 +348e4b4,ffffffff +348e4b8,5ff0f0f0 +348e4bc,f0f0f0f0 +348e4c0,f0f0f0f0 +348e4c4,ffffff5f +348e4c8,5ff0f0f0 +348e4cc,f0f0f0f0 +348e4d0,f0f0f0f0 +348e4d4,ffffff5f +348e4d8,f0f0f0f0 +348e4dc,f0f0f0f0 +348e4e0,f0f0f0f0 +348e4e4,ffffff5f +348e4e8,f0f0f0f0 +348e4ec,f0f0f0f0 +348e4f0,f0f0f0f0 +348e4f4,f0f0fff0 +348e4f8,f0f0f0f0 +348e4fc,f0f0f0f0 +348e500,f0f0f0f0 +348e504,f0f0f0f0 +348e508,f0f0f0f0 +348e50c,f0f0f0f0 +348e510,f0f0f0f0 +348e514,f0f0f0f0 +348e518,f0f0f0f0 +348e51c,f0f0f0f0 +348e520,f0f0f0f0 +348e524,f0f0ffff +348e528,fffff0f0 +348e52c,f0f0f0f0 +348e530,f0f0f0f0 +348e534,f0f0ffff +348e538,fffff0f0 +348e53c,f0f0f0f0 +348e540,f0f0f0f0 +348e544,f0f0ffff +348e548,ff3ff0f0 +348e54c,f0f0f0f0 +348e550,f0f0f0f0 +348e554,f0f0ffff +348e558,ff3ff0f0 +348e55c,f0f0f0f0 +348e560,f0f0f0f0 +348e564,f0f0ffff +348e568,ff3ff0f0 +348e56c,f0f0f0f0 +348e570,f0f0f0f0 +348e574,f0f0ffff +348e578,ff3ff0f0 +348e57c,f0f0f0f0 +348e580,f0f0f0f0 +348e584,f0f0ffff +348e588,ff3ff0f0 +348e58c,f0f0f0f0 +348e590,f0f0f0f0 +348e594,f0ffffff +348e598,ff3ff0f0 +348e59c,f0f0f0f0 +348e5a0,f0f0f0f0 +348e5a4,f0ffffff +348e5a8,fff0f0f0 +348e5ac,f0f0f0f0 +348e5b0,f0f0f0f0 +348e5b4,f0ffffff +348e5b8,fff0f0f0 +348e5bc,f0f0f0f0 +348e5c0,f0f0f0f0 +348e5c4,f0ffffff +348e5c8,fff0f0f0 +348e5cc,f0f0f0f0 +348e5d0,f0f0f0f0 +348e5d4,f0ffffff +348e5d8,fff0f0f0 +348e5dc,f0f0f0f0 +348e5e0,f0f0f0f0 +348e5e4,f0ffffff +348e5e8,fff0f0f0 +348e5ec,f0f0f0f0 +348e5f0,f0f0f0f0 +348e5f4,f0f0f0ff +348e5f8,f0f0f0f0 +348e5fc,f0f0f0f0 +348e600,f0f0f0f0 +348e604,f0f0f0f0 +348e608,f0f0f0f0 +348e60c,f0f0f0f0 +348e610,f0f0f0f0 +348e614,f0f0f0f0 +348e618,f0f0f0f0 +348e61c,f0f0f0f0 +348e620,f0f0f0f0 +348e624,f0f0ffff +348e628,fffff0f0 +348e62c,f0f0f0f0 +348e630,f0f0f0f0 +348e634,f0f0ffff +348e638,fffff0f0 +348e63c,f0f0f0f0 +348e640,f0f0f0f0 +348e644,f0f0ffff +348e648,fffff0f0 +348e64c,f0f0f0f0 +348e650,f0f0f0f0 +348e654,f0f0ffff +348e658,fffff0f0 +348e65c,f0f0f0f0 +348e660,f0f0f0f0 +348e664,f0f0ffff +348e668,fffff0f0 +348e66c,f0f0f0f0 +348e670,f0f0f0f0 +348e674,f0f0ffff +348e678,fffff0f0 +348e67c,f0f0f0f0 +348e680,f0f0f0f0 +348e684,f0f0ffff +348e688,fffff0f0 +348e68c,f0f0f0f0 +348e690,f0f0f0f0 +348e694,f0f0ffff +348e698,fffff0f0 +348e69c,f0f0f0f0 +348e6a0,f0f0f0f0 +348e6a4,f0f0ffff +348e6a8,fffff0f0 +348e6ac,f0f0f0f0 +348e6b0,f0f0f0f0 +348e6b4,f0f0ffff +348e6b8,fffff0f0 +348e6bc,f0f0f0f0 +348e6c0,f0f0f0f0 +348e6c4,f0f0ffff +348e6c8,fffff0f0 +348e6cc,f0f0f0f0 +348e6d0,f0f0f0f0 +348e6d4,f0f0ffff +348e6d8,fffff0f0 +348e6dc,f0f0f0f0 +348e6e0,f0f0f0f0 +348e6e4,f0f0ffff +348e6e8,fffff0f0 +348e6ec,f0f0f0f0 +348e6f0,f0f0f0f0 +348e6f4,f0f0ffff +348e6f8,fffff0f0 +348e6fc,f0f0f0f0 +348e700,f0f0f0f0 +348e704,f0f0f0f0 +348e708,f0f0f0f0 +348e70c,f0f0f0f0 +348e710,f0f0f0f0 +348e714,f0f0f0f0 +348e718,f0f0f0f0 +348e71c,f0f0f0f0 +348e720,f0f0f0f0 +348e724,f0f0ffff +348e728,fffff0f0 +348e72c,f0f0f0f0 +348e730,f0f0f0f0 +348e734,f0f0ffff +348e738,fffff0f0 +348e73c,f0f0f0f0 +348e740,f0f0f0f0 +348e744,f0f03fff +348e748,fffff0f0 +348e74c,f0f0f0f0 +348e750,f0f0f0f0 +348e754,f0f03fff +348e758,fffff0f0 +348e75c,f0f0f0f0 +348e760,f0f0f0f0 +348e764,f0f03fff +348e768,fffff0f0 +348e76c,f0f0f0f0 +348e770,f0f0f0f0 +348e774,f0f03fff +348e778,fffff0f0 +348e77c,f0f0f0f0 +348e780,f0f0f0f0 +348e784,f0f03fff +348e788,fffff0f0 +348e78c,f0f0f0f0 +348e790,f0f0f0f0 +348e794,f0f03fff +348e798,fffffff0 +348e79c,f0f0f0f0 +348e7a0,f0f0f0f0 +348e7a4,f0f0f0ff +348e7a8,fffffff0 +348e7ac,f0f0f0f0 +348e7b0,f0f0f0f0 +348e7b4,f0f0f0ff +348e7b8,fffffff0 +348e7bc,f0f0f0f0 +348e7c0,f0f0f0f0 +348e7c4,f0f0f0ff +348e7c8,fffffff0 +348e7cc,f0f0f0f0 +348e7d0,f0f0f0f0 +348e7d4,f0f0f0ff +348e7d8,fffffff0 +348e7dc,f0f0f0f0 +348e7e0,f0f0f0f0 +348e7e4,f0f0f0ff +348e7e8,fffffff0 +348e7ec,f0f0f0f0 +348e7f0,f0f0f0f0 +348e7f4,f0f0f0f0 +348e7f8,fff0f0f0 +348e7fc,f0f0f0f0 +348e800,f0f0f0f0 +348e804,f0f0f0f0 +348e808,f0f0f0f0 +348e80c,f0f0f0f0 +348e810,f0f0f0f0 +348e814,f0f0f0f0 +348e818,f0f0f0f0 +348e81c,f0f0f0f0 +348e820,f0f0f0f0 +348e824,f0f05fff +348e828,fffff0f0 +348e82c,f0f0f0f0 +348e830,f0f0f0f0 +348e834,f0f05fff +348e838,fffff0f0 +348e83c,f0f0f0f0 +348e840,f0f0f0f0 +348e844,f0f05fff +348e848,fffff0f0 +348e84c,f0f0f0f0 +348e850,f0f0f0f0 +348e854,f0f05fff +348e858,fffff0f0 +348e85c,f0f0f0f0 +348e860,f0f0f0f0 +348e864,f0f05fff +348e868,fffff0f0 +348e86c,f0f0f0f0 +348e870,f0f0f0f0 +348e874,f0f05f5f +348e878,fffffff0 +348e87c,f0f0f0f0 +348e880,f0f0f0f0 +348e884,f0f05f5f +348e888,fffffff0 +348e88c,f0f0f0f0 +348e890,f0f0f0f0 +348e894,f0f05f5f +348e898,fffffff0 +348e89c,f0f0f0f0 +348e8a0,f0f0f0f0 +348e8a4,f0f05f5f +348e8a8,fffffff0 +348e8ac,f0f0f0f0 +348e8b0,f0f0f0f0 +348e8b4,f0f0f05f +348e8b8,ffffffff +348e8bc,f0f0f0f0 +348e8c0,f0f0f0f0 +348e8c4,f0f0f05f +348e8c8,5fffffff +348e8cc,f0f0f0f0 +348e8d0,f0f0f0f0 +348e8d4,f0f0f0f0 +348e8d8,5fffffff +348e8dc,f0f0f0f0 +348e8e0,f0f0f0f0 +348e8e4,f0f0f0f0 +348e8e8,5fffffff +348e8ec,f0f0f0f0 +348e8f0,f0f0f0f0 +348e8f4,f0f0f0f0 +348e8f8,f0fff0f0 +348e8fc,f0f0f0f0 +348e900,f0f0f0f0 +348e904,f0f0f0f0 +348e908,f0f0f0f0 +348e90c,f0f0f0f0 +348e910,f0f0f0f0 +348e914,f0f0f0f0 +348e918,f0f0f0f0 +348e91c,f0f0f0f0 +348e920,f0f0f0f0 +348e924,f0f07fff +348e928,fff0f0f0 +348e92c,f0f0f0f0 +348e930,f0f0f0f0 +348e934,f0f07fff +348e938,fffff0f0 +348e93c,f0f0f0f0 +348e940,f0f0f0f0 +348e944,f0f07fff +348e948,fffff0f0 +348e94c,f0f0f0f0 +348e950,f0f0f0f0 +348e954,f0f07f7f +348e958,fffff0f0 +348e95c,f0f0f0f0 +348e960,f0f0f0f0 +348e964,f0f07f7f +348e968,fffffff0 +348e96c,f0f0f0f0 +348e970,f0f0f0f0 +348e974,f0f07f7f +348e978,fffffff0 +348e97c,f0f0f0f0 +348e980,f0f0f0f0 +348e984,f07f7f7f +348e988,7ffffff0 +348e98c,f0f0f0f0 +348e990,f0f0f0f0 +348e994,f06f7f7f +348e998,7fffffff +348e99c,f0f0f0f0 +348e9a0,f0f0f0f0 +348e9a4,f06f6f7f +348e9a8,7fffffff +348e9ac,f0f0f0f0 +348e9b0,f0f0f0f0 +348e9b4,f0f06f7f +348e9b8,7fffffff +348e9bc,f0f0f0f0 +348e9c0,f0f0f0f0 +348e9c4,f0f0f0f0 +348e9c8,7f7fffff +348e9cc,f0f0f0f0 +348e9d0,f0f0f0f0 +348e9d4,f0f0f0f0 +348e9d8,f07fffff +348e9dc,fff0f0f0 +348e9e0,f0f0f0f0 +348e9e4,f0f0f0f0 +348e9e8,f0f0ffff +348e9ec,f0f0f0f0 +348e9f0,f0f0f0f0 +348e9f4,f0f0f0f0 +348e9f8,f0f0f0f0 +348e9fc,f0f0f0f0 +348ea00,f0f0f0f0 +348ea04,f0f0f0f0 +348ea08,f0f0f0f0 +348ea0c,f0f0f0f0 +348ea10,f0f0f0f0 +348ea14,f0f0f0f0 +348ea18,f0f0f0f0 +348ea1c,f0f0f0f0 +348ea20,f0f0f0f0 +348ea24,f0f09fff +348ea28,fff0f0f0 +348ea2c,f0f0f0f0 +348ea30,f0f0f0f0 +348ea34,f0f09fff +348ea38,fffff0f0 +348ea3c,f0f0f0f0 +348ea40,f0f0f0f0 +348ea44,f0f09f9f +348ea48,fffff0f0 +348ea4c,f0f0f0f0 +348ea50,f0f0f0f0 +348ea54,f0f09f9f +348ea58,fffff0f0 +348ea5c,f0f0f0f0 +348ea60,f0f0f0f0 +348ea64,f09f9f9f +348ea68,9fffeff0 +348ea6c,f0f0f0f0 +348ea70,f0f0f0f0 +348ea74,f08f9f9f +348ea78,9fefeff0 +348ea7c,f0f0f0f0 +348ea80,f0f0f0f0 +348ea84,f08f8f9f +348ea88,9fefeff0 +348ea8c,f0f0f0f0 +348ea90,f0f0f0f0 +348ea94,f08f8f8f +348ea98,9f9fefef +348ea9c,f0f0f0f0 +348eaa0,f0f0f0f0 +348eaa4,f08f8f8f +348eaa8,8f9fefef +348eaac,f0f0f0f0 +348eab0,f0f0f0f0 +348eab4,f0f08f8f +348eab8,8f8fefef +348eabc,eff0f0f0 +348eac0,f0f0f0f0 +348eac4,f0f0f0f0 +348eac8,8f8f8fef +348eacc,eff0f0f0 +348ead0,f0f0f0f0 +348ead4,f0f0f0f0 +348ead8,f08f8fef +348eadc,eff0f0f0 +348eae0,f0f0f0f0 +348eae4,f0f0f0f0 +348eae8,f0f0f08f +348eaec,f0f0f0f0 +348eaf0,f0f0f0f0 +348eaf4,f0f0f0f0 +348eaf8,f0f0f0f0 +348eafc,f0f0f0f0 +348eb00,f0f0f0f0 +348eb04,f0f0f0f0 +348eb08,f0f0f0f0 +348eb0c,f0f0f0f0 +348eb10,f0f0f0f0 +348eb14,f0f0f0f0 +348eb18,f0f0f0f0 +348eb1c,f0f0f0f0 +348eb20,f0f0f0f0 +348eb24,f0f0f0ef +348eb28,eff0f0f0 +348eb2c,f0f0f0f0 +348eb30,f0f0f0f0 +348eb34,f0f0bfbf +348eb38,eff0f0f0 +348eb3c,f0f0f0f0 +348eb40,f0f0f0f0 +348eb44,f0f0bfbf +348eb48,dfdff0f0 +348eb4c,f0f0f0f0 +348eb50,f0f0f0f0 +348eb54,f0f0afbf +348eb58,bfdff0f0 +348eb5c,f0f0f0f0 +348eb60,f0f0f0f0 +348eb64,f0afafaf +348eb68,afdfdff0 +348eb6c,f0f0f0f0 +348eb70,f0f0f0f0 +348eb74,f0afafaf +348eb78,afafdff0 +348eb7c,f0f0f0f0 +348eb80,f0f0f0f0 +348eb84,f0afafaf +348eb88,afafdfdf +348eb8c,f0f0f0f0 +348eb90,f0f0f0f0 +348eb94,9fafafaf +348eb98,afafdfdf +348eb9c,f0f0f0f0 +348eba0,f0f0f0f0 +348eba4,9f9fafaf +348eba8,afafafcf +348ebac,f0f0f0f0 +348ebb0,f0f0f0f0 +348ebb4,f0f09f9f +348ebb8,afafafcf +348ebbc,cff0f0f0 +348ebc0,f0f0f0f0 +348ebc4,f0f0f0f0 +348ebc8,9fafafaf +348ebcc,cff0f0f0 +348ebd0,f0f0f0f0 +348ebd4,f0f0f0f0 +348ebd8,f0f0f0af +348ebdc,cff0f0f0 +348ebe0,f0f0f0f0 +348ebe4,f0f0f0f0 +348ebe8,f0f0f0f0 +348ebec,f0f0f0f0 +348ebf0,f0f0f0f0 +348ebf4,f0f0f0f0 +348ebf8,f0f0f0f0 +348ebfc,f0f0f0f0 +348ec00,f0f0f0f0 +348ec04,f0f0f0f0 +348ec08,f0f0f0f0 +348ec0c,f0f0f0f0 +348ec10,f0f0f0f0 +348ec14,f0f0f0f0 +348ec18,f0f0f0f0 +348ec1c,f0f0f0f0 +348ec20,f0f0f0f0 +348ec24,f0f0f0cf +348ec28,cff0f0f0 +348ec2c,f0f0f0f0 +348ec30,f0f0f0f0 +348ec34,f0f0cfcf +348ec38,cff0f0f0 +348ec3c,f0f0f0f0 +348ec40,f0f0f0f0 +348ec44,f0f0cfcf +348ec48,cfbff0f0 +348ec4c,f0f0f0f0 +348ec50,f0f0f0f0 +348ec54,f0f0cfcf +348ec58,cfbff0f0 +348ec5c,f0f0f0f0 +348ec60,f0f0f0f0 +348ec64,f0bfbfbf +348ec68,cfcfbff0 +348ec6c,f0f0f0f0 +348ec70,f0f0f0f0 +348ec74,f0bfbfbf +348ec78,bfbfbff0 +348ec7c,f0f0f0f0 +348ec80,f0f0f0f0 +348ec84,bfbfbfbf +348ec88,bfbfbfbf +348ec8c,f0f0f0f0 +348ec90,f0f0f0f0 +348ec94,bfbfbfbf +348ec98,bfbfbfbf +348ec9c,f0f0f0f0 +348eca0,f0f0f0f0 +348eca4,afafbfbf +348eca8,bfbfbfbf +348ecac,f0f0f0f0 +348ecb0,f0f0f0f0 +348ecb4,f0afafaf +348ecb8,bfbfbfbf +348ecbc,aff0f0f0 +348ecc0,f0f0f0f0 +348ecc4,f0f0f0f0 +348ecc8,f0afbfbf +348eccc,bff0f0f0 +348ecd0,f0f0f0f0 +348ecd4,f0f0f0f0 +348ecd8,f0f0f0f0 +348ecdc,f0f0f0f0 +348ece0,f0f0f0f0 +348ece4,f0f0f0f0 +348ece8,f0f0f0f0 +348ecec,f0f0f0f0 +348ecf0,f0f0f0f0 +348ecf4,f0f0f0f0 +348ecf8,f0f0f0f0 +348ecfc,f0f0f0f0 +348ed00,f0f0f0f0 +348ed04,f0f0f0f0 +348ed08,f0f0f0f0 +348ed0c,f0f0f0f0 +348ed10,f0f0f0f0 +348ed14,f0f0f0f0 +348ed18,f0f0f0f0 +348ed1c,f0f0f0f0 +348ed20,f0f0f0f0 +348ed24,f0f0f0df +348ed28,f0f0f0f0 +348ed2c,f0f0f0f0 +348ed30,f0f0f0f0 +348ed34,f0f0f0df +348ed38,dff0f0f0 +348ed3c,f0f0f0f0 +348ed40,f0f0f0f0 +348ed44,f0f0cfdf +348ed48,dff0f0f0 +348ed4c,f0f0f0f0 +348ed50,f0f0f0f0 +348ed54,f0f0cfcf +348ed58,cfcff0f0 +348ed5c,f0f0f0f0 +348ed60,f0f0f0f0 +348ed64,f0cfcfcf +348ed68,cfcff0f0 +348ed6c,f0f0f0f0 +348ed70,f0f0f0f0 +348ed74,f0cfcfcf +348ed78,cfcfcff0 +348ed7c,f0f0f0f0 +348ed80,f0f0f0f0 +348ed84,cfcfcfcf +348ed88,cfcfcff0 +348ed8c,f0f0f0f0 +348ed90,f0f0f0f0 +348ed94,bfbfcfcf +348ed98,cfcfcfcf +348ed9c,f0f0f0f0 +348eda0,f0f0f0f0 +348eda4,bfbfbfbf +348eda8,bfbfbfbf +348edac,f0f0f0f0 +348edb0,f0f0f0bf +348edb4,bfbfbfbf +348edb8,bfbfbfbf +348edbc,bff0f0f0 +348edc0,f0f0f0f0 +348edc4,f0f0f0f0 +348edc8,f0f0bfbf +348edcc,bff0f0f0 +348edd0,f0f0f0f0 +348edd4,f0f0f0f0 +348edd8,f0f0f0f0 +348eddc,f0f0f0f0 +348ede0,f0f0f0f0 +348ede4,f0f0f0f0 +348ede8,f0f0f0f0 +348edec,f0f0f0f0 +348edf0,f0f0f0f0 +348edf4,f0f0f0f0 +348edf8,f0f0f0f0 +348edfc,f0f0f0f0 +348ee00,f0f0f0f0 +348ee04,f0f0f0f0 +348ee08,f0f0f0f0 +348ee0c,f0f0f0f0 +348ee10,f0f0f0f0 +348ee14,f0f0f0f0 +348ee18,f0f0f0f0 +348ee1c,f0f0f0f0 +348ee20,f0f0f0f0 +348ee24,f0f0f0df +348ee28,dff0f0f0 +348ee2c,f0f0f0f0 +348ee30,f0f0f0f0 +348ee34,f0f0f0df +348ee38,dff0f0f0 +348ee3c,f0f0f0f0 +348ee40,f0f0f0f0 +348ee44,f0f0dfdf +348ee48,dfdff0f0 +348ee4c,f0f0f0f0 +348ee50,f0f0f0f0 +348ee54,f0f0dfdf +348ee58,dfdff0f0 +348ee5c,f0f0f0f0 +348ee60,f0f0f0f0 +348ee64,f0f0cfcf +348ee68,cfcff0f0 +348ee6c,f0f0f0f0 +348ee70,f0f0f0f0 +348ee74,f0cfcfcf +348ee78,cfcfcff0 +348ee7c,f0f0f0f0 +348ee80,f0f0f0f0 +348ee84,f0cfcfcf +348ee88,cfcfcff0 +348ee8c,f0f0f0f0 +348ee90,f0f0f0f0 +348ee94,cfcfcfcf +348ee98,cfcfcfcf +348ee9c,f0f0f0f0 +348eea0,f0f0f0f0 +348eea4,cfcfcfcf +348eea8,cfcfcfcf +348eeac,f0f0f0f0 +348eeb0,f0f0f0bf +348eeb4,bfbfbfbf +348eeb8,bfbfbfbf +348eebc,bff0f0f0 +348eec0,f0f0f0f0 +348eec4,f0f0f0f0 +348eec8,f0f0f0f0 +348eecc,f0f0f0f0 +348eed0,f0f0f0f0 +348eed4,f0f0f0f0 +348eed8,f0f0f0f0 +348eedc,f0f0f0f0 +348eee0,f0f0f0f0 +348eee4,f0f0f0f0 +348eee8,f0f0f0f0 +348eeec,f0f0f0f0 +348eef0,f0f0f0f0 +348eef4,f0f0f0f0 +348eef8,f0f0f0f0 +348eefc,f0f0f0f0 +348ef00,f0f0f0f0 +348ef04,f0f0f0f0 +348ef08,f0f0f0f0 +348ef0c,f0f0f0f0 diff --git a/worlds/oot/data/generated/symbols.json b/worlds/oot/data/generated/symbols.json new file mode 100644 index 00000000..35618aed --- /dev/null +++ b/worlds/oot/data/generated/symbols.json @@ -0,0 +1,183 @@ +{ + "ADULT_INIT_ITEMS": "03481D2C", + "ADULT_VALID_ITEMS": "03481D34", + "AP_PLAYER_NAME": "03480834", + "AUDIO_THREAD_INFO": "03482FAC", + "AUDIO_THREAD_INFO_MEM_SIZE": "03482FCC", + "AUDIO_THREAD_INFO_MEM_START": "03482FC8", + "AUDIO_THREAD_MEM_START": "0348EF10", + "BOMBCHUS_IN_LOGIC": "03480CBC", + "CFG_A_BUTTON_COLOR": "03480854", + "CFG_A_NOTE_COLOR": "03480872", + "CFG_BOMBCHU_TRAIL_INNER_COLOR": "03480884", + "CFG_BOMBCHU_TRAIL_OUTER_COLOR": "03480887", + "CFG_BOOM_TRAIL_INNER_COLOR": "0348087E", + "CFG_BOOM_TRAIL_OUTER_COLOR": "03480881", + "CFG_B_BUTTON_COLOR": "0348085A", + "CFG_C_BUTTON_COLOR": "03480860", + "CFG_C_NOTE_COLOR": "03480878", + "CFG_DAMAGE_MULTIPLYER": "03482C9C", + "CFG_DISPLAY_DPAD": "0348088A", + "CFG_HEART_COLOR": "0348084E", + "CFG_MAGIC_COLOR": "03480848", + "CFG_RAINBOW_BOMBCHU_TRAIL_INNER_ENABLED": "0348088F", + "CFG_RAINBOW_BOMBCHU_TRAIL_OUTER_ENABLED": "03480890", + "CFG_RAINBOW_BOOM_TRAIL_INNER_ENABLED": "0348088D", + "CFG_RAINBOW_BOOM_TRAIL_OUTER_ENABLED": "0348088E", + "CFG_RAINBOW_NAVI_ENEMY_INNER_ENABLED": "03480893", + "CFG_RAINBOW_NAVI_ENEMY_OUTER_ENABLED": "03480894", + "CFG_RAINBOW_NAVI_IDLE_INNER_ENABLED": "03480891", + "CFG_RAINBOW_NAVI_IDLE_OUTER_ENABLED": "03480892", + "CFG_RAINBOW_NAVI_NPC_INNER_ENABLED": "03480895", + "CFG_RAINBOW_NAVI_NPC_OUTER_ENABLED": "03480896", + "CFG_RAINBOW_NAVI_PROP_INNER_ENABLED": "03480897", + "CFG_RAINBOW_NAVI_PROP_OUTER_ENABLED": "03480898", + "CFG_RAINBOW_SWORD_INNER_ENABLED": "0348088B", + "CFG_RAINBOW_SWORD_OUTER_ENABLED": "0348088C", + "CFG_SHOP_CURSOR_COLOR": "0348086C", + "CFG_TEXT_CURSOR_COLOR": "03480866", + "CHAIN_HBA_REWARDS": "03483940", + "CHEST_SIZE_MATCH_CONTENTS": "034826DC", + "COMPLETE_MASK_QUEST": "0348B191", + "COOP_CONTEXT": "03480020", + "COOP_VERSION": "03480020", + "COSMETIC_CONTEXT": "03480844", + "COSMETIC_FORMAT_VERSION": "03480844", + "CURRENT_GROTTO_ID": "03482E6E", + "DEBUG_OFFSET": "0348288C", + "DISABLE_TIMERS": "03480CDC", + "DPAD_TEXTURE": "0348D710", + "DUNGEONS_SHUFFLED": "03480CDE", + "EXTENDED_OBJECT_TABLE": "03480C9C", + "EXTERN_DAMAGE_MULTIPLYER": "03482C9D", + "FAST_BUNNY_HOOD_ENABLED": "03480CE0", + "FAST_CHESTS": "03480CD6", + "FONT_TEXTURE": "0348C248", + "FREE_SCARECROW_ENABLED": "03480CCC", + "GET_CHEST_OVERRIDE_COLOR_WRAPPER": "0348270C", + "GET_CHEST_OVERRIDE_SIZE_WRAPPER": "034826E0", + "GET_ITEM_TRIGGERED": "034813F8", + "GOSSIP_HINT_CONDITION": "03480CC8", + "GROTTO_EXIT_LIST": "03482E2C", + "GROTTO_LOAD_TABLE": "03482DA8", + "INCOMING_ITEM": "03480028", + "INCOMING_PLAYER": "03480026", + "INITIAL_SAVE_DATA": "0348089C", + "JABU_ELEVATOR_ENABLE": "03480CD4", + "LACS_CONDITION": "03480CC4", + "LACS_CONDITION_COUNT": "03480CD2", + "MALON_GAVE_ICETRAP": "0348367C", + "MALON_TEXT_ID": "03480CDB", + "MAX_RUPEES": "0348B193", + "MOVED_ADULT_KING_ZORA": "03482FEC", + "NO_ESCAPE_SEQUENCE": "0348B15C", + "NO_FOG_STATE": "03480CDD", + "OCARINAS_SHUFFLED": "03480CD5", + "OPEN_KAKARIKO": "0348B192", + "OUTGOING_ITEM": "03480030", + "OUTGOING_KEY": "0348002C", + "OUTGOING_PLAYER": "03480032", + "OVERWORLD_SHUFFLED": "03480CDF", + "PAYLOAD_END": "0348EF10", + "PAYLOAD_START": "03480000", + "PLAYED_WARP_SONG": "034811FC", + "PLAYER_ID": "03480024", + "PLAYER_NAMES": "03480034", + "PLAYER_NAME_ID": "03480025", + "RAINBOW_BRIDGE_CONDITION": "03480CC0", + "RAINBOW_BRIDGE_COUNT": "03480CD0", + "RANDO_CONTEXT": "03480000", + "SHUFFLE_BEANS": "03482D04", + "SHUFFLE_CARPET_SALESMAN": "034839F8", + "SHUFFLE_COWS": "03480CD7", + "SHUFFLE_MEDIGORON": "03483A54", + "SONGS_AS_ITEMS": "03480CD8", + "SOS_ITEM_GIVEN": "034814C4", + "SPEED_MULTIPLIER": "0348274C", + "START_TWINROVA_FIGHT": "0348306C", + "TIME_TRAVEL_SAVED_EQUIPS": "03481A50", + "TRIFORCE_ICON_TEXTURE": "0348DF10", + "TWINROVA_ACTION_TIMER": "03483070", + "WINDMILL_SONG_ID": "03480CD9", + "WINDMILL_TEXT_ID": "03480CDA", + "a_button": "0348B120", + "a_note_b": "0348B10C", + "a_note_font_glow_base": "0348B0F4", + "a_note_font_glow_max": "0348B0F0", + "a_note_g": "0348B110", + "a_note_glow_base": "0348B0FC", + "a_note_glow_max": "0348B0F8", + "a_note_r": "0348B114", + "active_item_action_id": "0348B174", + "active_item_fast_chest": "0348B164", + "active_item_graphic_id": "0348B168", + "active_item_object_id": "0348B16C", + "active_item_row": "0348B178", + "active_item_text_id": "0348B170", + "active_override": "0348B180", + "active_override_is_outgoing": "0348B17C", + "b_button": "0348B11C", + "beating_dd": "0348B128", + "beating_no_dd": "0348B130", + "c_button": "0348B118", + "c_note_b": "0348B100", + "c_note_font_glow_base": "0348B0E4", + "c_note_font_glow_max": "0348B0E0", + "c_note_g": "0348B104", + "c_note_glow_base": "0348B0EC", + "c_note_glow_max": "0348B0E8", + "c_note_r": "0348B108", + "cfg_dungeon_info_enable": "0348B0AC", + "cfg_dungeon_info_mq_enable": "0348B150", + "cfg_dungeon_info_mq_need_map": "0348B14C", + "cfg_dungeon_info_reward_enable": "0348B0A8", + "cfg_dungeon_info_reward_need_altar": "0348B144", + "cfg_dungeon_info_reward_need_compass": "0348B148", + "cfg_dungeon_is_mq": "0348B1B0", + "cfg_dungeon_rewards": "03489ECC", + "cfg_file_select_hash": "0348B158", + "cfg_item_overrides": "0348B204", + "defaultDDHeart": "0348B134", + "defaultHeart": "0348B13C", + "dpad_sprite": "0348A040", + "dummy_actor": "0348B188", + "dungeon_count": "0348B0B0", + "dungeons": "03489EF0", + "empty_dlist": "0348B0C8", + "extern_ctxt": "03489F8C", + "font_sprite": "0348A050", + "freecam_modes": "03489C4C", + "hash_sprites": "0348B0BC", + "hash_symbols": "03489FA0", + "heap_next": "0348B1AC", + "heart_sprite": "03489FE0", + "icon_sprites": "03489E10", + "item_digit_sprite": "0348A000", + "item_overrides_count": "0348B18C", + "item_table": "0348A0C8", + "items_sprite": "0348A070", + "key_rupee_clock_sprite": "0348A010", + "last_fog_distance": "0348B0B4", + "linkhead_skull_sprite": "03489FF0", + "medal_colors": "03489EDC", + "medals_sprite": "0348A080", + "normal_dd": "0348B124", + "normal_no_dd": "0348B12C", + "object_slots": "0348C204", + "pending_freezes": "0348B190", + "pending_item_queue": "0348B1EC", + "quest_items_sprite": "0348A060", + "rupee_colors": "03489E1C", + "satisified_pending_frames": "0348B160", + "scene_fog_distance": "0348B0B8", + "setup_db": "0348A0A0", + "song_note_sprite": "0348A020", + "stones_sprite": "0348A090", + "text_cursor_border_base": "0348B0D4", + "text_cursor_border_max": "0348B0D0", + "text_cursor_inner_base": "0348B0DC", + "text_cursor_inner_max": "0348B0D8", + "triforce_hunt_enabled": "0348B1A0", + "triforce_pieces_requied": "0348B142", + "triforce_sprite": "0348A030" +} \ No newline at end of file diff --git a/worlds/oot/data/icons/belt.tiff b/worlds/oot/data/icons/belt.tiff new file mode 100644 index 00000000..02f45797 Binary files /dev/null and b/worlds/oot/data/icons/belt.tiff differ diff --git a/worlds/oot/data/icons/grey.tiff b/worlds/oot/data/icons/grey.tiff new file mode 100644 index 00000000..0148d55d Binary files /dev/null and b/worlds/oot/data/icons/grey.tiff differ diff --git a/worlds/oot/data/icons/magicLargeExtras.raw b/worlds/oot/data/icons/magicLargeExtras.raw new file mode 100644 index 00000000..450ce504 Binary files /dev/null and b/worlds/oot/data/icons/magicLargeExtras.raw differ diff --git a/worlds/oot/data/icons/magicSmallExtras.raw b/worlds/oot/data/icons/magicSmallExtras.raw new file mode 100644 index 00000000..8d74e0c3 Binary files /dev/null and b/worlds/oot/data/icons/magicSmallExtras.raw differ diff --git a/worlds/oot/data/keaton.bin b/worlds/oot/data/keaton.bin new file mode 100644 index 00000000..081a5240 --- /dev/null +++ b/worlds/oot/data/keaton.bin @@ -0,0 +1,2 @@ +xœÕ‘AJÅP EÃEÂç#—‚tø×à +\Ã¥ƒ¿‡®2t \„÷•þ¢(¯S -ô¥9Iî}f)2lú‘Dê÷‚QTÛç¼'›ÞØxÖ+4îÉf±ø뎙niáS®<ŒÈÐsÄkTÀ%¢Y>ÅLW¢…y0œÁšbÈ«C¢ÈÓKƒ(Z[d6/5âVáÚ_¼‘ç÷É­•¿sökóoUÍ??_7¾ TG_|ý×FLÒ@Þp¿ñý(SÎ¥yôõ%"Jž½Þx§–ºÊ?ôè@à›Ví¥Ö=Žü§ø„JU \ No newline at end of file diff --git a/worlds/oot/data/mqu.json b/worlds/oot/data/mqu.json new file mode 100644 index 00000000..cd336a12 --- /dev/null +++ b/worlds/oot/data/mqu.json @@ -0,0 +1,38465 @@ +[ + { + "File": { + "Name": "Scene 0", + "Start": "02499000", + "End": "024A6A10", + "RemapStart": null + }, + "Id": 0, + "TActors": [ + "01FF 00FF 002E FE39 0190 01C7 6000 003F", + "06FF 05FF 002E FA01 FD08 042E 4000 01C9", + "04FF 03FF 002E FFB5 FC90 0244 8000 01D5", + "08FF 07FF 002E F68C FD08 FE3B 2000 003F", + "0BFF 09FF 002E FC80 F8A8 FC3C 105B 007F", + "02FF 01FF 002E FC58 0190 03A8 6000 008C", + "00FF 0AFF 002E FDD0 0320 0000 C000 007F", + "07FF 06FF 002E F8C1 FD08 0302 0000 007F", + "05FF 04FF 002E FEB1 FC90 03C0 4000 0099", + "00FF 03FF 0023 0000 FEC0 0000 C000 00BF", + "03FF 09FF 0023 FD85 FBB4 0000 C000 00BF", + "07FF 03FF 0023 FBE1 FCCC 0000 4000 013F" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 0, Room 0", + "Start": "024A7000", + "End": "024BC2F0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "0164", + "0170", + "012F" + ], + "Actors": [ + "00C7 FFB9 0320 00FC 0000 0000 0000 0001", + "00C7 FFA8 0000 FE95 0000 0000 0000 0001", + "0013 FFCA 0106 FE73 4000 4AAB 0000 0003", + "0013 FE28 035C FFD8 0000 BB06 0000 0003", + "0095 005F 0085 FECC 4000 F49F 0000 0000", + "0125 0188 0000 FF62 0000 DDDE 0000 FF01", + "0125 0164 0000 FF15 0000 DDDE 0000 FF01", + "0125 0134 0000 FEDD 0000 DDDE 0000 FF01", + "0125 008F 0133 FE6F 0000 0000 0000 FF01", + "0125 0051 0125 FE60 0000 0000 0000 FF01", + "0055 FF3D 0320 FF3D 0000 9F4A 0000 0000", + "0055 0100 0320 FFBB 0000 0000 0000 0000", + "011B 0000 FFE8 0000 0028 0006 0000 8001", + "011B FE5F 0190 01AB 0000 0000 0000 0103", + "011B FDE9 0320 0000 0000 0000 0000 0103", + "011B 0076 0000 FEBB 0014 0000 0000 1F02", + "011B 01D1 0168 0072 001C 0000 0000 1F02", + "011B 011A 0168 0168 0014 0000 0000 1F02", + "0015 FFEA 010E FFA8 0000 0000 0000 2403", + "0095 0116 0168 014C 0000 A000 0000 8102", + "0125 FFF5 0000 FEA8 0000 0000 0000 FF02", + "0125 FF61 0000 FED2 0000 0000 0000 FF02", + "002B 0192 0168 00C5 0000 B333 0000 0006", + "002B 0141 03D5 011D 0000 A000 0000 0008", + "005E FF67 0000 0002 0000 0000 0000 03E7", + "005E 0190 0168 0079 0000 B555 0000 03E7", + "005E FE16 0320 FFDC 0000 CAAB 0000 03E7", + "012A FEC9 0320 FEC9 0000 E000 0000 2700", + "01A0 0117 0168 014D 0000 6000 0000 FFFF", + "000A 014D 0168 00FD 0000 20B6 0000 0823", + "000F 0000 0000 0000 0000 4000 0000 0FC5", + "000F FE15 0320 FFFF 0000 4000 0000 19CA", + "000F FE7C 0190 0185 0000 6000 0000 1FD6" + ] + }, + { + "File": { + "Name": "Scene 0, Room 1", + "Start": "024BD000", + "End": "024C1150", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "015C" + ], + "Actors": [ + "0125 FD7D 0190 031E 0000 0000 0000 FF01", + "0125 FD72 0190 0246 0000 0000 0000 FF01", + "0125 FCEC 0190 02BE 0000 0000 0000 FF01", + "0055 FD5C 0190 02B1 0000 0000 0000 0001", + "0015 FDAE 0190 0348 0000 0000 0000 2303", + "0125 FDC4 0190 02D7 0000 0000 0000 FF02", + "0125 FDC1 0190 0273 0000 0000 0000 FF02", + "0125 FD20 0190 031B 0000 0000 0000 FF02", + "0125 FD0F 0190 0266 0000 0000 0000 FF02", + "002B FD2C 0190 0394 0000 0000 0000 0006", + "002B FC89 0190 02DB 0000 0000 0000 0006", + "012A FC68 021E 0396 0000 6000 0000 0C02" + ] + }, + { + "File": { + "Name": "Scene 0, Room 2", + "Start": "024C2000", + "End": "024C7E30", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "011D", + "0163", + "0190", + "00A8" + ], + "Actors": [ + "0095 FB63 017D 0577 4000 5F4A 0000 0000", + "0095 FA8D 0191 04A3 4000 6000 0000 0000", + "0037 FB17 02EC 04E1 0000 616C 0000 0000", + "0125 FC14 0118 04BE 0000 C71C 0000 FF01", + "0125 FC07 0118 04ED 0000 C71C 0000 FF01", + "0125 FB34 0118 03EC 0000 0000 0000 FF01", + "0125 FB01 0118 0400 0000 0000 0000 FF01", + "011B FA8E 0118 04A4 0000 0000 0000 1F02", + "011B FB5E 0163 0576 0000 0000 0000 1F02", + "011B FB68 01E0 05CD 0000 0000 0000 1F02", + "012C FB42 0186 04B8 0000 E000 0000 0080", + "0015 FB98 0290 0623 0000 0000 0000 2203", + "0095 FBDF 0302 0670 4000 A000 0000 8108", + "002B FAE6 0118 045D 0000 0000 0000 0006", + "002B FABD 01E0 054B 0000 0000 0000 0006", + "01D1 FB48 0223 056E 0000 E000 0000 39FF", + "01D1 FB72 0223 0544 0000 E000 0000 39FF", + "01D1 FB73 0223 0598 0000 E000 0000 39FF", + "01D1 FB9D 0223 056E 0000 E000 0000 39FF", + "0173 FBD7 024E 0432 0005 0022 0001 3F04", + "0127 FB97 0290 05BD 0000 A000 0000 0003", + "0127 FB61 0290 05F2 0000 A000 0000 0004", + "0127 FB2B 0290 0616 0000 A000 0000 0008", + "000A FA91 01E0 056F 0000 E000 0000 0801", + "000F FBE9 0265 0435 0CCD E5B0 0EEF 1FFF", + "0051 FBD6 0230 042A 0000 E000 0000 0121" + ] + }, + { + "File": { + "Name": "Scene 0, Room 3", + "Start": "024C8000", + "End": "024DC1A0", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "0164", + "0170", + "012F" + ], + "Actors": [ + "00C7 001F FCB3 FF2C 0000 7E94 0000 0001", + "0125 FFD9 FC90 0076 0000 0000 0000 FF01", + "0125 0005 FC90 0077 0000 0000 0000 FF01", + "0125 FCD9 FCD6 FF1C 0000 0000 0000 FF01", + "0125 FD04 FCCC 0118 0000 E000 0000 FF01", + "0125 FCDB FCCC 00ED 0000 E000 0000 FF01", + "0055 FF7B FCB3 FEE2 0000 0000 0000 0000", + "0055 FF97 FC90 0085 0000 8000 0000 0000", + "0055 FE38 FCCF FFD6 0000 0000 0000 0001", + "011B FDA8 FCCC FEDD 0014 0011 000A 3208", + "017D FE93 FC77 FEDE 0000 0000 0001 FF10", + "0125 FFF9 FCB3 FEB8 0000 0000 0000 FF02", + "0125 FFF1 FCB3 FEFB 0000 0000 0000 FF02", + "005E FF9A FC90 00F4 0000 E000 0000 03C2", + "012A FF9A FCB3 FE66 0000 0000 0000 0200", + "012A 0040 FC90 00FF 0000 0000 0000 1400", + "0195 FDCE FCCC 014C 0000 0000 0000 0004", + "012A FFB4 FD29 0227 0000 8000 0000 1502", + "000A 0035 FDC1 FEEA 0000 8000 0014 8524", + "000F FD85 FCCC 0000 0000 4000 0000 0FC6", + "000F 002D FC8C 00F5 FBBC B8E4 0000 1FCB" + ] + }, + { + "File": { + "Name": "Scene 0, Room 4", + "Start": "024DD000", + "End": "024E1BD0", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "0170" + ], + "Actors": [ + "0125 0050 FC90 0318 0000 0000 0000 FF01", + "0125 0032 FC90 02EE 0000 0000 0000 FF01", + "0125 FF37 FC90 02ED 0000 0000 0000 FF01", + "0125 FF1D FC90 0316 0000 0000 0000 FF01", + "0060 FFB6 FC90 0416 0000 8000 0000 FF00", + "002B FF43 FC90 041B 0000 0000 0000 0006", + "002B 002F FC90 041C 0000 0000 0000 0006", + "002B FFB3 FD7F 03D0 0000 0000 0000 0008", + "005E FEE7 FC90 0371 0000 0000 0000 1099", + "005E FEE6 FC90 0411 0000 0000 0000 1099", + "0173 FEE7 FCCC 0371 0002 001A 0000 3F06", + "0173 FEE6 FCCC 0411 0002 001A 0000 3F06" + ] + }, + { + "File": { + "Name": "Scene 0, Room 5", + "Start": "024E2000", + "End": "024EA320", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "000D", + "0170", + "0190", + "00A8", + "00A2" + ], + "Actors": [ + "00C7 FB1E FC90 0382 0000 0000 0000 0001", + "0037 FABD FCDA 0437 0000 4000 0000 0000", + "0125 FAE3 FC9A 0346 0000 0000 0000 FF01", + "0125 FAB0 FC9A 0346 0000 0000 0000 FF01", + "0125 FDE6 FC90 038B 0000 0000 0000 FF02", + "0125 FE11 FC90 038A 0000 0000 0000 FF02", + "0125 FE2E FC90 0361 0000 0000 0000 FF02", + "002B FC6B FDE2 0428 0000 0000 0000 0009", + "01D1 FAAB FC90 042E 0000 0000 0000 B9FF", + "005E FDF0 FC90 03D8 0000 0000 0000 03FE", + "005E FB77 FC90 047B 0000 0000 0000 1089", + "005E FB78 FC90 03E1 0000 0000 0000 1089", + "012A FDF1 FC90 045A 0000 0000 0000 3E20", + "000A FAA0 FC90 0436 0000 C000 0000 5AA0", + "000A FE84 FC90 0405 0000 4000 0000 5905", + "0050 FCBD FC77 041A 0000 4000 0000 FF00", + "0051 FCBD FCA4 041A 0000 4000 0000 00FF", + "0050 FCBD FC6D 041A 0000 0000 0000 FF01" + ] + }, + { + "File": { + "Name": "Scene 0, Room 6", + "Start": "024EB000", + "End": "024EFEC0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "000D", + "0170" + ], + "Actors": [ + "0013 F81D FE0B 04C9 0000 6000 0000 0003", + "0125 F8FD FD08 0333 0000 0000 0000 FF01", + "0125 F882 FD08 0332 0000 0000 0000 FF01", + "0060 F8C9 FD08 042A 0000 4000 0000 FF00", + "002B F909 FD08 047A 0000 0000 0000 0007", + "002B F869 FD08 0471 0000 0000 0000 0007", + "002B F909 FD08 03DF 0000 0000 0000 0007", + "002B F863 FD08 03E0 0000 0000 0000 0007", + "002B F8C2 FDEB 04FE 0000 0000 0000 0009", + "002B F8BB FDF4 0366 0000 0000 0000 0009", + "002B F8C0 FE43 042C 0000 0000 0000 0008", + "002B F813 FE16 042F 0000 0000 0000 0008" + ] + }, + { + "File": { + "Name": "Scene 0, Room 7", + "Start": "024F0000", + "End": "024F8910", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "00A8", + "0190", + "00A2" + ], + "Actors": [ + "00C7 F959 FD08 0144 0000 5A50 0000 0001", + "0013 F857 FD43 000A 0000 0000 0000 0003", + "0013 F8AE FD44 005F 0000 0000 0000 0003", + "0013 F803 FD44 0061 0000 0000 0000 0003", + "0013 F85A FD44 00B9 0000 0000 0000 0003", + "0125 F893 FD08 025C 0000 0000 0000 FF01", + "0055 FA0E FCF7 0001 0000 C000 0000 0000", + "0055 F73C FD08 FEF5 0000 2000 0000 0000", + "0095 F82E FEE8 005B 0000 0000 0000 8104", + "0112 F71F FD1C 0082 0000 0000 0000 193F", + "0112 F7DD FD1C FFA9 0000 0000 0000 193F", + "0112 F913 FD1C 012A 0000 0000 0000 193F", + "0112 F93A FD1C FF60 0000 0000 0000 193F", + "0125 F759 FD08 0038 0000 0000 0000 FF02", + "0125 F78B FD08 015E 0000 0000 0000 FF02", + "0125 F95C FD08 00C4 0000 0000 0000 FF02", + "0125 F972 FD08 FF88 0000 0000 0000 FF02", + "01D1 F7A2 FD08 005D 0000 0000 0000 39FF", + "01D1 F7DB FD43 00D9 0000 2000 0000 39FF", + "01D1 F84C FD85 0122 0000 0000 0000 39FF", + "01D1 F8CA FDCC 00F2 0000 6000 0000 39FF", + "01D1 F8FA FE13 0073 0000 0000 0000 39FF", + "005E F857 FD08 0005 0000 0000 0000 03F8", + "005E F85B FD08 00B5 0000 0000 0000 03F8", + "005E F803 FD08 005B 0000 0000 0000 03F8", + "005E F8AD FD08 0059 0000 0000 0000 03F8", + "012A F859 FD08 005A 0000 0000 0000 3820", + "009D F718 FCF9 0081 0000 4000 0000 0000", + "009D F715 FCF9 FFEC 0000 4000 0000 0000", + "009D F7E1 FCF9 0115 0000 0000 0000 0000", + "009D F8ED FCF9 FFE9 0000 0000 0000 0000", + "009D F916 FCF9 011A 0000 0000 0000 0000", + "009D F9A4 FCF9 00B4 0000 C000 0000 0000", + "009D F945 FCF9 FF4F 0000 E222 0000 0000", + "009D F7DC FCF9 FF98 0000 0000 0000 0000", + "000F FAB5 FCCC 0003 0000 C000 0000 1FC7", + "000F F707 FD08 FEB9 0000 2000 0000 1FCF" + ] + }, + { + "File": { + "Name": "Scene 0, Room 8", + "Start": "024F9000", + "End": "024F9D00", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "0164", + "000E", + "00A4", + "012B", + "00B7", + "015C" + ], + "Actors": [ + "0125 F554 F8E6 FD5E 0000 0000 0000 FF01", + "0125 F647 F8E2 FD0F 0000 0000 0000 FF01", + "0055 F58D FD08 FD41 0000 2000 0000 0001", + "0095 F563 FD8E FD16 0000 2000 0000 8101", + "0125 F607 FD08 FE4F 0000 0000 0000 FF02", + "0125 F6A5 FD08 FDB5 0000 0000 0000 FF02", + "0125 F56C FD08 FDF6 0000 0000 0000 FF02", + "002B F63C FD08 FD5D 0000 0000 0000 0007", + "002B F5A5 FD08 FE03 0000 0000 0000 0007", + "002B F5F1 FD08 FD12 0000 0000 0000 0007", + "002B F561 FD08 FDA2 0000 0000 0000 0007" + ] + }, + { + "File": { + "Name": "Scene 0, Room 9", + "Start": "024FA000", + "End": "025038A0", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "0164", + "0170" + ], + "Actors": [ + "0125 FEF4 F8A8 FD7B 0000 0000 0000 FF01", + "0125 FEF0 F8A8 FDBD 0000 0000 0000 FF01", + "0125 FEF0 F8A8 FDFB 0000 0000 0000 FF01", + "0192 FE8F F8A8 FC78 0000 0000 0000 0001", + "0192 FC4D F8A8 FD0B 0000 0000 0000 0002", + "0192 FD6C F8A8 FC49 0000 0000 0000 9C03", + "0015 FC8B F862 FF47 0000 0000 0000 2E03", + "0015 FCCC F858 FFB4 0000 0000 0000 3003", + "0015 FE9E F869 FF32 0000 0000 0000 3103" + ] + }, + { + "File": { + "Name": "Scene 0, Room 10", + "Start": "02504000", + "End": "02508D80", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "0164", + "000E", + "00A4", + "012B", + "00B7", + "0170" + ], + "Actors": [ + "0125 FA5D 0348 00A7 0000 727D 0000 FF01", + "0125 FA15 0348 008C 0000 7333 0000 FF01", + "0125 FD84 0320 00A1 0000 0000 0000 FF01", + "0125 FD4B 0320 00B6 0000 0000 0000 FF01", + "0055 FCA6 02D0 00BA 0000 BF4A 0000 0000", + "0015 FB73 0334 0145 0000 0000 0000 2603", + "002B FB10 02D0 0093 0000 0000 0000 0007", + "002B FA77 0348 FFA3 0000 0B61 0000 0007", + "002B FA72 0348 0046 0000 0000 0000 0006", + "002B FB7C 03E0 01C5 0000 0000 0000 0008", + "002B FBE7 03CF FEF0 0000 0000 0000 0008", + "002B FC0A 03E8 0140 0000 8000 0000 0008", + "005E FD73 0320 FF97 0000 C000 0000 2400", + "005E FBD5 02D0 FFFB 0000 C000 0000 1053", + "0173 FBD5 030C FFFB 0002 0014 0000 3F06", + "012A FD1D 0320 FF6D 0000 0000 0000 3D00", + "01A0 FCDB 02D0 FFFE 0000 4000 0000 FFFF", + "01A0 FCDB 02D0 FFC2 0000 4000 0000 FFFF", + "000A FA2D 049B 0001 0000 C000 0013 8522", + "000A FBC6 0334 0183 0000 0000 0000 10A6", + "0050 FBC8 0258 0000 0000 0000 0000 3D02" + ] + }, + { + "File": { + "Name": "Scene 0, Room 11", + "Start": "02509000", + "End": "02510170", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "0164", + "000E", + "00A4", + "012B", + "00B7" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": true, + "Polys": [ + { + "Id": 459, + "Type": 11, + "Flags": 0 + }, + { + "Id": 460, + "Type": 11, + "Flags": 0 + }, + { + "Id": 461, + "Type": 12, + "Flags": 0 + }, + { + "Id": 462, + "Type": 12, + "Flags": 0 + }, + { + "Id": 570, + "Type": 13, + "Flags": 1 + }, + { + "Id": 571, + "Type": 13, + "Flags": 1 + }, + { + "Id": 572, + "Type": 14, + "Flags": 1 + }, + { + "Id": 573, + "Type": 14, + "Flags": 1 + }, + { + "Id": 574, + "Type": 15, + "Flags": 0 + }, + { + "Id": 575, + "Type": 15, + "Flags": 0 + }, + { + "Id": 576, + "Type": 15, + "Flags": 0 + }, + { + "Id": 577, + "Type": 15, + "Flags": 0 + }, + { + "Id": 578, + "Type": 15, + "Flags": 0 + }, + { + "Id": 579, + "Type": 15, + "Flags": 0 + }, + { + "Id": 580, + "Type": 15, + "Flags": 0 + }, + { + "Id": 581, + "Type": 15, + "Flags": 0 + }, + { + "Id": 582, + "Type": 15, + "Flags": 0 + }, + { + "Id": 583, + "Type": 15, + "Flags": 0 + }, + { + "Id": 584, + "Type": 15, + "Flags": 0 + }, + { + "Id": 585, + "Type": 15, + "Flags": 0 + }, + { + "Id": 586, + "Type": 15, + "Flags": 0 + }, + { + "Id": 587, + "Type": 15, + "Flags": 0 + }, + { + "Id": 588, + "Type": 15, + "Flags": 0 + }, + { + "Id": 589, + "Type": 15, + "Flags": 0 + }, + { + "Id": 590, + "Type": 15, + "Flags": 0 + }, + { + "Id": 591, + "Type": 15, + "Flags": 0 + }, + { + "Id": 592, + "Type": 15, + "Flags": 0 + }, + { + "Id": 593, + "Type": 15, + "Flags": 0 + }, + { + "Id": 594, + "Type": 15, + "Flags": 0 + }, + { + "Id": 595, + "Type": 15, + "Flags": 0 + }, + { + "Id": 596, + "Type": 15, + "Flags": 0 + }, + { + "Id": 597, + "Type": 15, + "Flags": 0 + }, + { + "Id": 598, + "Type": 15, + "Flags": 0 + }, + { + "Id": 599, + "Type": 15, + "Flags": 0 + }, + { + "Id": 600, + "Type": 15, + "Flags": 0 + }, + { + "Id": 601, + "Type": 15, + "Flags": 0 + }, + { + "Id": 602, + "Type": 15, + "Flags": 0 + }, + { + "Id": 603, + "Type": 15, + "Flags": 0 + }, + { + "Id": 604, + "Type": 15, + "Flags": 0 + }, + { + "Id": 605, + "Type": 15, + "Flags": 0 + }, + { + "Id": 678, + "Type": 16, + "Flags": 0 + }, + { + "Id": 679, + "Type": 16, + "Flags": 0 + }, + { + "Id": 680, + "Type": 17, + "Flags": 0 + }, + { + "Id": 681, + "Type": 17, + "Flags": 0 + }, + { + "Id": 682, + "Type": 17, + "Flags": 0 + }, + { + "Id": 683, + "Type": 17, + "Flags": 0 + }, + { + "Id": 684, + "Type": 16, + "Flags": 0 + }, + { + "Id": 685, + "Type": 16, + "Flags": 0 + }, + { + "Id": 688, + "Type": 17, + "Flags": 0 + }, + { + "Id": 689, + "Type": 17, + "Flags": 0 + }, + { + "Id": 690, + "Type": 17, + "Flags": 0 + }, + { + "Id": 691, + "Type": 17, + "Flags": 0 + }, + { + "Id": 700, + "Type": 18, + "Flags": 0 + }, + { + "Id": 701, + "Type": 18, + "Flags": 0 + }, + { + "Id": 726, + "Type": 16, + "Flags": 0 + }, + { + "Id": 727, + "Type": 16, + "Flags": 0 + }, + { + "Id": 754, + "Type": 18, + "Flags": 0 + }, + { + "Id": 755, + "Type": 18, + "Flags": 0 + }, + { + "Id": 756, + "Type": 18, + "Flags": 0 + }, + { + "Id": 763, + "Type": 18, + "Flags": 0 + }, + { + "Id": 764, + "Type": 18, + "Flags": 0 + }, + { + "Id": 811, + "Type": 19, + "Flags": 0 + }, + { + "Id": 812, + "Type": 19, + "Flags": 0 + }, + { + "Id": 813, + "Type": 17, + "Flags": 0 + }, + { + "Id": 814, + "Type": 17, + "Flags": 0 + }, + { + "Id": 819, + "Type": 19, + "Flags": 0 + }, + { + "Id": 820, + "Type": 19, + "Flags": 0 + }, + { + "Id": 824, + "Type": 15, + "Flags": 0 + }, + { + "Id": 825, + "Type": 15, + "Flags": 0 + }, + { + "Id": 826, + "Type": 15, + "Flags": 0 + }, + { + "Id": 827, + "Type": 15, + "Flags": 0 + }, + { + "Id": 828, + "Type": 15, + "Flags": 0 + }, + { + "Id": 829, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1161, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1173, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1174, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1175, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1176, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1177, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1194, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1195, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1196, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1197, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1202, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1203, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1204, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1205, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1206, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1207, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1208, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1209, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1210, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1211, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1212, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1213, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1214, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1215, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1216, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1217, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1300, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1301, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1306, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1307, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1328, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1329, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1330, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1331, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1332, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1333, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1334, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1335, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1336, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1337, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1338, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1339, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1421, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1422, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1479, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1480, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1481, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1482, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1483, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1484, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1485, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1486, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1487, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1488, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1489, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1520, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1536, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1537, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1538, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1539, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1540, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1541, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1548, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1549, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1550, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1551, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1566, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1567, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1568, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1570, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1571, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1572, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1573, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1574, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1579, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1580, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1581, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1582, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1583, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1589, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1590, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1591, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1592, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1593, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1594, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1595, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1596, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1601, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1602, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1603, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1610, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1611, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1612, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1619, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1620, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1661, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1662, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1663, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1664, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1679, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1759, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1760, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1761, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1762, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1763, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1764, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1809, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1810, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1890, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1891, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1906, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1907, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1920, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1921, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1930, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1931, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1932, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1933, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1934, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1935, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1936, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1937, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1938, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1939, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1940, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1941, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1942, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1943, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1944, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1945, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1946, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1947, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1948, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1949, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1954, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1955, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1956, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1957, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1958, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1959, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1960, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1961, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1962, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1963, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1964, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1977, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1978, + "Type": 16, + "Flags": 0 + }, + { + "Id": 2021, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2022, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2023, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2024, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2025, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2026, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2027, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2028, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2029, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2030, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2031, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2032, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2033, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2034, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2035, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2036, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2037, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2038, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2039, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2040, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2041, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2042, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2043, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2044, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2166, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2167, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2168, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2169, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2170, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2171, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2172, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2173, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2174, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2197, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2198, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2199, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2200, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2201, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2202, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2203, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2204, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2205, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2206, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2207, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2208, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2209, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2210, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2218, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2219, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2220, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2257, + "Type": 16, + "Flags": 0 + }, + { + "Id": 2258, + "Type": 16, + "Flags": 0 + }, + { + "Id": 2289, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2290, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2293, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2294, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2295, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2296, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2297, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2298, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2310, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2311, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2312, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2313, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2314, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2315, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2316, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2317, + "Type": 30, + "Flags": 0 + }, + { + "Id": 2318, + "Type": 30, + "Flags": 0 + }, + { + "Id": 2319, + "Type": 30, + "Flags": 0 + }, + { + "Id": 2320, + "Type": 30, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 11, + "High": 49159, + "Low": 30720 + }, + { + "Id": 12, + "High": 49158, + "Low": 30720 + }, + { + "Id": 13, + "High": 4194309, + "Low": 145354 + }, + { + "Id": 14, + "High": 6291461, + "Low": 14282 + }, + { + "Id": 15, + "High": 8388613, + "Low": 145354 + }, + { + "Id": 16, + "High": 5, + "Low": 12288 + }, + { + "Id": 17, + "High": 7, + "Low": 20480 + }, + { + "Id": 18, + "High": 6, + "Low": 20480 + }, + { + "Id": 19, + "High": 8, + "Low": 20480 + }, + { + "Id": 20, + "High": 2, + "Low": 30722 + }, + { + "Id": 21, + "High": 2, + "Low": 12290 + }, + { + "Id": 22, + "High": 10485765, + "Low": 14282 + }, + { + "Id": 23, + "High": 10485763, + "Low": 14282 + }, + { + "Id": 24, + "High": 10485764, + "Low": 14282 + }, + { + "Id": 25, + "High": 5, + "Low": 20480 + }, + { + "Id": 26, + "High": 10, + "Low": 20480 + }, + { + "Id": 27, + "High": 10, + "Low": 12288 + }, + { + "Id": 28, + "High": 7, + "Low": 16384 + }, + { + "Id": 29, + "High": 7, + "Low": 14272 + }, + { + "Id": 30, + "High": 517, + "Low": 14304 + } + ], + "Cams": [ + { + "Data": 1572867, + "PositionIndex": 0 + }, + { + "Data": 1572867, + "PositionIndex": 1 + }, + { + "Data": 1966086, + "PositionIndex": 2 + }, + { + "Data": 1441795, + "PositionIndex": 3 + }, + { + "Data": 1441795, + "PositionIndex": 4 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 4259840, + "PositionIndex": -1 + }, + { + "Data": 327680, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 40, + "y": -33 + }, + { + "Flag": 6, + "x": 49, + "y": -42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 48, + "y": -63 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 84, + "y": -39 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 0, + "x": 46, + "y": -59 + }, + { + "Flag": 4, + "x": 77, + "y": -26 + }, + { + "Flag": 5, + "x": 65, + "y": -61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 55, + "y": 0 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 71, + "y": 50 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 64, + "y": 62 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 4, + "x": 76, + "y": 37 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 46, + "y": 50 + }, + { + "Flag": 5, + "x": 76, + "y": 52 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 50, + "y": 23 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 46, + "y": 50 + }, + { + "Flag": 6, + "x": 58, + "y": 60 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 1", + "Start": "01F12000", + "End": "01F27140", + "RemapStart": null + }, + "Id": 1, + "TActors": [ + "00FF 01FF 0023 0474 0000 FEC0 4000 003F", + "00FF 09FF 0023 0474 0213 FEC0 4000 003F", + "00FF 09FF 0023 0474 0213 FC68 4000 003F", + "07FF 08FF 0023 026C 004C F520 4000 003F", + "07FF 08FF 0023 0251 004C F11A 4000 003F", + "09FF 0CFF 0023 0924 0213 FC68 4000 003F", + "09FF 0AFF 0023 0924 0213 FEC0 4000 003F", + "07FF 00FF 002E 0000 004C F84E 0000 003F", + "04FF 03FF 002E 0AE3 0064 F680 2AAB 0085", + "01FF 03FF 002E 0DE8 0064 FB04 8000 0085", + "0AFF 03FF 002E 10F3 0213 FDA8 8000 0086", + "0CFF 03FF 002E 0EC4 0213 FC68 4000 0086", + "01FF 0BFF 002E 0A00 0000 0078 0000 003F", + "08FF 0EFF 002E 05C1 004C EF7B 8000 007F", + "0DFF 04FF 002E 0981 0064 F4B2 0000 01DE", + "02FF 0FFF 002E F858 0000 FD1C 0000 003F", + "06FF 09FF 002E 0730 019B FA38 0000 01E7", + "05FF 02FF 002E F858 0213 FD24 8000 00A5", + "00FF 05FF 002E F9F4 0213 FEC0 C000 007F", + "01FF 01FF 002E 0DE8 0064 FDD0 0000 00B6", + "10FF 07FF 002E FE98 0010 F520 4000 00A0", + "02FF 00FF 002E FCB8 0000 FA10 4000 0083", + "00FF 04FF 002E 05B4 0050 FC68 4000 009B" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 1, Room 0", + "Start": "01F28000", + "End": "01F438A0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "01B9 FC37 0000 FC6C 0000 4000 0000 3E14", + "0058 FE5C FF4C FB64 0000 0000 0000 00FF", + "0058 0000 FF4C FCF4 0000 0000 0000 00FF", + "0058 01A4 FF4C FB64 0000 0000 0000 000A", + "0059 0000 0000 0014 0000 0000 0000 0007", + "0059 0334 0000 FA10 0000 C000 0000 A000", + "0059 FCCC 0000 FC68 0000 4000 0000 A01D", + "0059 0334 0000 FEC0 0000 C000 0000 A01F", + "003F 0000 00C4 F92A 0000 0000 0000 001A", + "011B 0010 FF67 FC05 0096 0000 0032 0C15", + "0112 FFD8 0000 0014 0000 0000 0000 3FD8", + "0112 0000 0000 0014 0000 0000 0000 3FD8", + "0112 0028 0000 0014 0000 0000 0000 3FD8", + "012A FC97 0213 F9FC 0000 4000 0000 0300", + "012A 01AD FF60 F94B 0000 0000 0000 0A00", + "0185 0242 0238 FC5F 0000 4000 0000 0338", + "0195 FC7E 0000 FEE7 0000 4000 0000 0003", + "0195 FC43 0000 FEA4 0000 4000 0000 0001", + "004C FEDB 0014 0133 0000 0000 0000 FFFF", + "004C FFFE 0000 FB6E 0000 0000 0000 FFFF", + "004C 0122 0014 0133 0000 0000 0000 FFFF", + "004C 0352 0213 FC65 0000 0000 0000 FFFF", + "0127 01B0 FF60 F949 0000 0000 0000 000E", + "0127 FE4D FF60 F948 0000 0000 0000 0011", + "0127 030F 0213 FC65 0000 4000 0000 0015", + "0127 0322 0213 FC34 0000 C000 0000 0015", + "0127 0327 0213 FC96 0000 0000 0000 0015", + "000A 03B6 0000 FA11 0000 4000 0000 0820", + "000A 0365 0050 FC68 0000 C000 0000 0644", + "005E FD03 0000 FA83 0000 0000 0000 03C3" + ] + }, + { + "File": { + "Name": "Scene 1, Room 1", + "Start": "01F44000", + "End": "01F4DB00", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "012B 085C FF61 FE97 0000 0000 0000 0001", + "012B 085C FF61 FE20 0000 0000 0000 1201", + "0037 0C9B 0160 FE70 0000 C16C 0000 0001", + "0059 0A00 0000 FF95 0000 8000 0000 A001", + "0013 0D2D 00E7 FEA4 0000 0000 0000 0000", + "002F 0DC1 0064 FC7E 0000 093F 0000 FFFF", + "002F 0E06 0064 FBC2 0000 F1C7 0000 FFFF", + "0111 06BF 0000 FF69 0000 0000 0000 4400", + "0111 0717 0000 FF66 0000 0000 0000 4601", + "0111 0D72 0028 FE2B 0000 0000 0000 5000", + "0111 0E62 0028 FE2E 0000 0000 0000 5210", + "004C 085D 00A0 FD9B 0000 0000 0000 FFFF", + "004C 09A1 0000 FE6D 0000 0000 0000 FFFF", + "004C 0B2F 00A9 FF35 4000 671C 0000 FFFF", + "004C 0B43 00EA FF41 4000 671C 0000 FFFF", + "004C 0B46 0125 FF43 438E 671C 0000 FFFF", + "004C 0B4F 0154 FEEE 8000 0000 0000 FFFF", + "004C 0B5A 006B FF4F 4000 671C 0000 FFFF", + "004C 0B5D 0154 FF2A 8000 0000 0000 FFFF", + "004C 0B7A 0154 FE99 8000 0000 0000 FFFF", + "004C 0B8E 0154 FE3B 8000 0000 0000 FFFF", + "004C 0B90 0154 FEE0 8000 0000 0000 FFFF", + "004C 0BA2 0138 FE03 4000 11C7 0000 FFFF", + "004C 0BAE 0154 FE71 8000 0000 0000 FFFF", + "0127 09A0 0000 FE6E 0000 0000 0000 0008", + "0127 0B7E 00F0 FE11 0000 0000 0000 8012", + "012A 0B7E 0104 FE0C 0000 11C7 0000 3602" + ] + }, + { + "File": { + "Name": "Scene 1, Room 2", + "Start": "01F4E000", + "End": "01F55DA0", + "RemapStart": "1F4DCD0" + }, + "Id": 2, + "Objects": [ + "002B", + "018A", + "0031", + "00A4", + "011B", + "0170", + "0024", + "008B", + "0168", + "0039" + ], + "Actors": [ + "012B F85B FF9F F8F8 0000 0000 0000 2200", + "00C7 F893 0000 FC6B 0000 0000 0000 0001", + "0037 F779 02D0 FBA6 0000 C000 0000 0000", + "0037 F930 02D0 FBA6 0000 4000 0000 0000", + "0059 F858 0000 FBF0 0000 8000 0000 A002", + "005C F858 01E0 F894 0000 C000 0000 000B", + "011B F858 0014 FAE9 001E 0024 0000 BF14", + "008A F71B 0000 FAAE 0000 0000 0000 0401", + "008A F993 0000 FAAE 0000 0000 0000 0401", + "005E F7DF 0000 FBAC 0000 0000 0000 2400", + "0117 F71B 0000 FAAE 0000 0000 0000 1165", + "0117 F773 0000 F8D6 0000 0000 0000 1165", + "0117 F695 017C F8D4 0000 0000 0000 1165", + "0117 F88D 0273 FB25 0000 0000 0000 1165", + "0117 FA18 0213 FBC5 0000 0000 0000 1165", + "0117 F93B 0000 FA4B 0000 0000 0000 0165", + "0111 F6A9 0000 F8F4 0000 0000 0000 6603", + "0111 F6C7 0000 FB77 0000 0000 0000 6802", + "0111 FA0B 0000 F8F8 0000 0000 0000 6A02", + "0111 F9EA 0000 FB6F 0000 0000 0000 6C03", + "0195 F857 01EA F844 0000 0000 0000 0004", + "004C F7EA 0014 F97F 0000 0000 0000 FFFF", + "004C F7EA 0014 F9BB 0000 0000 0000 FFFF", + "004C F7EA 0014 F9F7 0000 0000 0000 FFFF", + "004C F7EA 0014 FA33 0000 0000 0000 FFFF", + "004C F7EA 0014 FA6F 0000 0000 0000 FFFF", + "004C F7EA 0014 FAAB 0000 0000 0000 FFFF", + "004C F7EA 0014 FAE7 0000 0000 0000 FFFF", + "004C F808 0037 FC34 4000 4000 0000 FFFF", + "004C F821 0014 FAE7 0000 0000 0000 FFFF", + "004C F891 0014 FAE7 0000 0000 0000 FFFF", + "004C F8CC 0014 F97F 0000 0000 0000 FFFF", + "004C F8CC 0014 F9BB 0000 0000 0000 FFFF", + "004C F8CC 0014 F9F7 0000 0000 0000 FFFF", + "004C F8CC 0014 FA33 0000 0000 0000 FFFF", + "004C F8CC 0014 FA6F 0000 0000 0000 FFFF", + "004C F8CC 0014 FAAB 0000 0000 0000 FFFF", + "004C F8CC 0014 FAE7 0000 0000 0000 FFFF", + "01A0 F695 017C F8D4 0000 0000 0000 FFFF", + "01A0 F696 0213 FBC4 0000 0000 0000 FFFF", + "01A0 F772 0000 F8D5 0000 0000 0000 FFFF", + "01A0 F93E 0000 F8D4 0000 0000 0000 FFFF", + "01A0 FA19 0213 FBC4 0000 0000 0000 FFFF", + "01A0 FA1A 017C F8D3 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 3", + "Start": "01F56000", + "End": "01F63DC0", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "002B", + "001B", + "0163", + "00A4", + "0024", + "015C" + ], + "Actors": [ + "003B 0F0B 0028 FA0A 0000 0000 0000 0006", + "0025 0F81 0064 F78F 0000 0000 0000 0500", + "0025 0B0D 0064 F857 0000 0000 0000 0501", + "0025 10A5 0213 FBE1 0000 0000 0000 0600", + "0025 115A 0213 FA96 0000 0000 0000 0601", + "0015 10AA 0064 F9D9 0000 ACCD 0000 1803", + "0095 0DF3 0213 F845 0000 0000 0000 8204", + "0111 0F1D 0213 FCD5 0000 0000 0000 5403", + "0111 0F1B 0213 FC37 0000 0000 0000 5603", + "0111 124F 0213 FBD1 0000 0000 0000 5801", + "0111 1255 0213 FB56 0000 0000 0000 5A01", + "0127 0EB0 01D7 FADA 0000 0000 0000 00FF", + "0127 0ED7 01D7 FA99 0000 0000 0000 00FF", + "0127 0EF8 01D7 FA63 0000 0000 0000 00FF", + "0127 0F3A 01D7 FA45 0000 0000 0000 00FF", + "0127 0F7D 01D7 FA3F 0000 0000 0000 00FF", + "0127 0FBC 01D7 FA40 0000 0000 0000 00FF", + "0127 0FE3 0213 FA31 0000 0000 0000 00FF", + "0127 0FFB 0213 FA1A 0000 0000 0000 00FF", + "0127 1025 0213 F9E7 0000 0000 0000 00FF", + "0127 1042 0213 F9D3 0000 0000 0000 00FF", + "0127 1052 01D7 F9BE 0000 0000 0000 00FF", + "0127 107B 01D7 F98D 0000 0000 0000 00FF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 4", + "Start": "01F64000", + "End": "01F6D850", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "002B", + "0031", + "0163", + "00A2", + "0009", + "0170" + ], + "Actors": [ + "000D 06AA 0078 F9C1 0000 45B0 0000 0000", + "000D 06C1 0078 FCA6 0000 0000 0000 0000", + "000D 081F 0078 FB46 0000 BC72 0000 0000", + "0112 06E1 0156 FC2A 0000 0000 0003 18DB", + "0112 07FE 013A F894 0000 0000 0003 18DE", + "0111 0734 0050 F8B5 0000 0000 0000 5C03", + "0111 08E0 0050 F75B 0000 0000 0000 5E00", + "0111 08C0 0050 FAA7 0000 0000 0000 6201", + "0111 05FF 0050 FAED 0000 0000 0000 6403", + "004C 06C7 012D FBD9 5555 C000 0000 FFFF", + "004C 06CE 011B FBA5 5555 B777 0000 FFFF", + "004C 06D4 012D FC01 5555 DC72 0000 FFFF", + "004C 06F3 00F2 FB84 5555 A38E 0000 FFFF", + "004C 0718 00B5 FB77 4000 8000 0000 FFFF", + "004C 0742 007F FB78 4000 8000 0000 FFFF", + "004C 07E1 00B3 F82A 4000 3111 0000 FFFF", + "004C 07E8 011F F836 471C 31C7 0000 FFFF", + "004C 07EB 007F F805 4000 2AAB 0000 FFFF", + "004C 07EC 00F9 F814 5555 3111 0000 FFFF", + "004C 07F8 0128 F87D 471C 51C7 0000 FFFF", + "004C 06F3 0050 FD27 0000 0000 0000 FFFF", + "004C 08B0 0064 F64C 0000 0000 0000 FFFF", + "01A0 08B8 0050 FB3B 0000 C000 0000 FFFF", + "01A0 08B8 0050 FB77 0000 C000 0000 FFFF", + "01A0 08DB 0050 F8A4 0000 C000 0000 FFFF", + "01A0 08DB 0050 F8E0 0000 C000 0000 FFFF", + "01A0 0600 0050 FA55 0000 C000 0000 FFFF", + "01A0 0600 0050 FA91 0000 C000 0000 FFFF", + "01A0 0722 0050 FD18 0000 0000 0000 FFFF", + "01A0 075E 0050 FD18 0000 0000 0000 FFFF", + "009D 06DD 0165 FC11 ACCD 6000 0000 0000", + "009D 07F6 0158 F87B BA50 D27D 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 1, Room 5", + "Start": "01F6E000", + "End": "01F73EE0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "002B", + "0031", + "000C", + "00A4", + "000D", + "000E", + "012B" + ], + "Actors": [ + "0125 F74A 0213 FDD4 0000 0000 0000 0301", + "0125 F756 0213 FFC8 0000 0000 0000 0301", + "0125 F93D 0213 FFD3 0000 0000 0000 0301", + "0125 F947 0213 FDBD 0000 0000 0000 0301", + "0012 F788 0213 FE98 0000 EE39 0000 FFFF", + "0012 F8E1 0213 FF7F 0000 616C 0000 FFFF", + "0012 F8E7 0213 FE40 0000 B05B 0000 FFFF", + "004C F85B 0277 FEBE 0000 0000 0000 FFFF", + "000A F858 0213 FFE4 0000 0000 0000 1805" + ] + }, + { + "File": { + "Name": "Scene 1, Room 6", + "Start": "01F74000", + "End": "01F76400", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "002B", + "0024", + "0177", + "001E", + "0170", + "000E" + ], + "Actors": [ + "0095 080D 019B F911 0000 8000 0000 8210", + "002B 06B2 0303 F97C 0000 0000 0000 0008", + "002B 06D0 0303 F914 0000 0000 0000 0008", + "002B 072F 0303 F8C2 0000 0000 0000 0008", + "002B 0795 0303 F918 0000 0000 0000 0008", + "002B 07B6 0303 F982 0000 0000 0000 0008", + "01A0 0659 019B F90B 0000 4000 0000 FFFF", + "01A0 0659 019B F947 0000 4000 0000 FFFF", + "01A0 0713 019B F848 0000 0000 0000 FFFF", + "01A0 074F 019B F848 0000 0000 0000 FFFF", + "01A0 0807 019B F912 0000 4000 0000 FFFF", + "01A0 0807 019B F94E 0000 4000 0000 FFFF", + "000A 070F 019B F952 0000 8000 0000 7522" + ] + }, + { + "File": { + "Name": "Scene 1, Room 7", + "Start": "01F77000", + "End": "01F7E6D0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "002B", + "001F", + "001B", + "0038", + "015C", + "0024", + "0031", + "00A2", + "0154", + "0179", + "012B" + ], + "Actors": [ + "002F FF35 0010 F48F 0000 0000 0000 FFFF", + "002F 0016 0010 F466 0000 2666 0000 FFFF", + "0112 FFC4 004C F762 0000 0000 0000 3FF0", + "0112 FFEC 004C F762 0000 0000 0000 3FF0", + "0112 0014 004C F762 0000 0000 0000 3FF0", + "0112 003C 004C F762 0000 0000 0000 3FF0", + "0111 0102 0010 F411 0000 0000 0000 7A04", + "0111 FEF7 0010 F63D 0000 0000 0000 7C03", + "012A FFFF 007E F36C 0000 0000 0000 2000", + "009D 0000 007E F374 0000 0000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 1, Room 8", + "Start": "01F7F000", + "End": "01F88400", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "002B", + "001F", + "001B", + "0038", + "015C", + "0024", + "0031", + "00A2", + "0154", + "0179", + "012B" + ], + "Actors": [ + "0054 050A 0010 F09A 0000 4000 0000 FFFF", + "0054 051D 0010 F0C4 0000 4000 0000 FFFF", + "0054 0540 0010 F0E1 0000 4000 0000 FFFF", + "0054 0525 0010 F103 0000 4000 0000 FFFF", + "0054 0541 0010 F128 0000 4000 0000 FFFF", + "0054 051D 0010 F148 0000 4000 0000 FFFF", + "0054 053B 0010 F160 0000 4000 0000 FFFF", + "01B4 04A9 0042 F0FF 4000 C000 0000 FF01", + "01B4 04F9 0010 F0FF 4000 4000 0000 1901", + "0125 06E5 0010 F09C 0000 0000 0000 FF01", + "0049 0677 0010 F196 0000 0000 0000 2FFC", + "0049 06B0 0010 F194 0000 0000 0000 2FFC", + "0049 06EA 0010 F193 0000 0000 0000 2FFC", + "002F 0530 004C F324 0000 349F 0000 FFFF", + "002F 06AB 004C F340 0000 D777 0000 FFFF", + "0025 0616 0010 F22C 0000 0000 0000 FFFF", + "0095 0611 00C4 F194 0000 0000 0000 8201", + "012A 0452 0094 F082 4000 0000 0000 1903", + "012A 06AD 0010 F133 0000 0000 0000 3C03", + "0111 03ED 004C F181 0000 0000 0000 4003", + "0111 042A 004C F181 0000 0000 0000 4212", + "0111 06DE 004C F386 0000 0000 0000 6E04", + "0111 04C7 004C F383 0000 0000 0000 7804", + "0185 06AE 0045 F132 0000 0000 002C FFFF", + "004C 04FC 0057 F087 4000 0000 0000 FFFF", + "004C 04D8 009B F085 4000 0000 0000 FFFF", + "004C 04AF 00D8 F084 4000 0000 0000 FFFF", + "004C 0487 00C4 F0AF 0000 0000 0000 FFFF", + "004C 046D 009E F0AF 4000 C000 0000 FFFF", + "009D 0509 0010 F259 0000 0000 0000 0000", + "009D 06B3 0010 F25A 0000 0000 0000 0000", + "009D 05DE 0010 F259 0000 0000 0000 0000", + "009D 065E 0010 F0D9 0000 C000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 1, Room 9", + "Start": "01F89000", + "End": "01F94550", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "0125 06B1 019B FB22 0000 0000 0000 FF01", + "00FF 0654 015F FD8A 0000 0000 0000 FF40", + "00FF 06CC 015F FE3E 0000 0000 0000 FF40", + "00FF 06CC 015F FEF2 0000 0000 0000 FF40", + "00FF 07EE 015F FEC0 0000 0000 0000 FF40", + "0015 07A3 015F FDAC 0000 0000 0000 3003", + "005E 04E0 0213 FEA0 0000 0000 0000 2400", + "005E 0727 01D7 FF0F 0000 0000 0000 03E7", + "005E 062D 019B FF24 0000 0000 0000 10E7", + "005E 062E 019B FE93 0000 0000 0000 10E7", + "005E 062E 019B FE15 0000 0000 0000 10E7", + "0111 0723 024F FDB5 0000 0000 0000 4C01", + "0111 05FC 024F FB37 0000 0000 0000 4E03", + "000A 0672 024F FDFA 0000 0000 0000 59A3" + ] + }, + { + "File": { + "Name": "Scene 1, Room 10", + "Start": "01F95000", + "End": "01F9CE50", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "0013 0E1F 0245 FEF8 0000 C000 0000 0003", + "0013 0FF8 027F FF06 0000 8E39 0000 0003", + "0013 1011 0247 FE74 0000 07D2 0000 0003", + "0037 0A5F 028B FEBF 0000 C000 0000 0000", + "0037 0CAC 028B FEC2 0000 C000 0000 0000", + "0037 0F00 028B FEBF 0000 C0B6 0000 0000", + "0125 0C75 019B FE1B 0000 0000 0000 FF01", + "0059 10E9 0213 FDFB 0000 F555 0000 A009", + "002F 0BBF 019B FE38 0000 DD28 0000 FFFF", + "002F 0BE8 019B FF52 0000 B6C1 0000 FFFF", + "002F 0BFB 019B FE4B 0000 D8E4 0000 FFFF", + "00FF 0A96 019B FE52 0000 0000 0000 FF40", + "00FF 0B86 0213 FEC0 0000 0000 0000 FF41", + "005E 0E28 0213 FEFA 0000 0000 0000 03E8", + "005E 09FC 0213 FE8E 0000 0000 0000 10A8", + "005E 0ADC 0213 FEF7 0000 0000 0000 10A8", + "0111 0C7B 019B FF65 0000 0000 0000 7210", + "0111 0A90 019B FE1D 0000 0000 0000 7410", + "004C 1028 0242 FE5F 4000 0E39 0000 FFFF", + "000F 0A2A 0213 FEC0 0000 C000 0000 1FD4" + ] + }, + { + "File": { + "Name": "Scene 1, Room 11", + "Start": "01F9D000", + "End": "01F9F080", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "002B", + "0168" + ], + "Actors": [ + "0195 09FD 0000 01BE 0000 8000 0000 0007" + ] + }, + { + "File": { + "Name": "Scene 1, Room 12", + "Start": "01FA0000", + "End": "01FA8730", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "0013 0C11 024F FDA7 0000 8000 0000 0003", + "0013 0D1D 01F3 FBC4 0000 C000 0000 0003", + "0049 0C28 0213 FC67 0000 0000 0000 2FF9", + "0049 0B6E 0213 FC69 0000 0000 0000 2FFA", + "012A 0A99 019B FCE5 0000 0000 0000 3903", + "0111 0CFF 019B FCDB 0000 0000 0000 7610", + "0111 0CFE 019B FD0F 0000 0000 0000 7801", + "012A 0AB3 019B FBDC 0000 0000 0000 3A00", + "004C 0C10 0227 FD6E 0000 0000 0000 FFFF", + "0127 0AB1 019B FBDE 0000 0000 0000 8004", + "01A0 0AD8 019B FCD6 0000 4000 0000 FFFF", + "01A0 0C77 019B FC7F 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 13", + "Start": "01FA9000", + "End": "01FAB480", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "002B", + "00A4", + "0024", + "000D", + "015C", + "004A", + "012B" + ], + "Actors": [ + "0125 0A36 0064 F2C5 0000 0000 0000 FF01", + "0125 0A54 0064 F2D8 0000 0000 0000 FF01", + "0060 0915 0064 F38C 0000 0000 0000 FF00", + "0060 09F2 0064 F38C 0000 0000 0000 FF00", + "0013 0980 0145 F312 0000 0000 0000 0000", + "0095 0895 01B8 F2C2 0000 4000 0000 8202" + ] + }, + { + "File": { + "Name": "Scene 1, Room 14", + "Start": "01FAC000", + "End": "01FAE490", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "002B", + "012B", + "00A2", + "000E", + "0009" + ], + "Actors": [ + "0125 0505 004C EDAB 0000 0000 0000 FF01", + "000D 05C0 004C EE8D 0000 0000 0000 0000", + "0111 067F 004C EF29 0000 0000 0000 7004", + "0111 0670 004C EDAA 0000 0000 0000 7E04", + "009D 05C2 004C EE32 0000 0000 0000 0000", + "000A 05C1 004C EE21 0000 8000 0000 5541" + ] + }, + { + "File": { + "Name": "Scene 1, Room 15", + "Start": "01FAF000", + "End": "01FB1850", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "002B", + "0190", + "0024", + "015C", + "00A8" + ], + "Actors": [ + "0095 F793 0027 FF1E 0000 8000 0000 0000", + "0037 F7F4 0168 FE40 0000 8000 0000 0000", + "0037 F85A 0168 FF08 0000 8000 0000 0000", + "0037 F922 0168 FEA0 0000 8000 0000 0000", + "0095 F920 0000 FF02 0000 8000 0000 8208", + "01D1 F792 0000 FE2A 0000 0000 0000 88FF", + "01D1 F792 0000 FE8E 0000 0000 0000 88FF", + "01D1 F792 0000 FEF2 0000 0000 0000 88FF", + "01D1 F7F6 0000 FEF2 0000 0000 0000 88FF", + "01D1 F7F6 0000 FE8E 0000 0000 0000 88FF", + "01D1 F7F6 0000 FE2A 0000 0000 0000 88FF", + "01D1 F85A 0000 FEF2 0000 0000 0000 88FF", + "01D1 F85A 0000 FE8E 0000 0000 0000 88FF", + "01D1 F85A 0000 FE2A 0000 0000 0000 88FF", + "01D1 F8BE 0000 FEF2 0000 0000 0000 88FF", + "01D1 F8BE 0000 FE8E 0000 0000 0000 88FF", + "01D1 F8BE 0000 FE2A 0000 0000 0000 88FF", + "01D1 F922 0000 FE8E 0000 0000 0000 88FF", + "01D1 F922 0000 FE2A 0000 0000 0000 88FF", + "01D1 F922 0000 FEF2 0000 0000 0000 88FF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 16", + "Start": "01FB2000", + "End": "01FB7550", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "002B", + "001F", + "001B", + "0059", + "0038", + "0179", + "00A4", + "015C", + "0024" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": true, + "Polys": [ + { + "Id": 778, + "Type": 14, + "Flags": 0 + }, + { + "Id": 779, + "Type": 14, + "Flags": 0 + }, + { + "Id": 798, + "Type": 15, + "Flags": 0 + }, + { + "Id": 799, + "Type": 15, + "Flags": 0 + }, + { + "Id": 800, + "Type": 15, + "Flags": 0 + }, + { + "Id": 801, + "Type": 15, + "Flags": 0 + }, + { + "Id": 802, + "Type": 15, + "Flags": 0 + }, + { + "Id": 803, + "Type": 15, + "Flags": 0 + }, + { + "Id": 804, + "Type": 15, + "Flags": 0 + }, + { + "Id": 805, + "Type": 15, + "Flags": 0 + }, + { + "Id": 806, + "Type": 15, + "Flags": 0 + }, + { + "Id": 807, + "Type": 15, + "Flags": 0 + }, + { + "Id": 808, + "Type": 15, + "Flags": 0 + }, + { + "Id": 809, + "Type": 15, + "Flags": 0 + }, + { + "Id": 810, + "Type": 15, + "Flags": 0 + }, + { + "Id": 811, + "Type": 15, + "Flags": 0 + }, + { + "Id": 812, + "Type": 15, + "Flags": 0 + }, + { + "Id": 813, + "Type": 15, + "Flags": 0 + }, + { + "Id": 814, + "Type": 15, + "Flags": 0 + }, + { + "Id": 815, + "Type": 15, + "Flags": 0 + }, + { + "Id": 816, + "Type": 16, + "Flags": 0 + }, + { + "Id": 820, + "Type": 15, + "Flags": 0 + }, + { + "Id": 821, + "Type": 15, + "Flags": 0 + }, + { + "Id": 822, + "Type": 17, + "Flags": 0 + }, + { + "Id": 848, + "Type": 18, + "Flags": 0 + }, + { + "Id": 849, + "Type": 18, + "Flags": 0 + }, + { + "Id": 978, + "Type": 19, + "Flags": 0 + }, + { + "Id": 999, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1000, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1043, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1044, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1069, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1070, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1199, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1200, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1245, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1246, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1247, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1248, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1249, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1250, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1251, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1252, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1300, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1301, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1308, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1309, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1310, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1311, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1312, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1313, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1314, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1315, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1316, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1317, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1318, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1319, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1320, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1321, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1322, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1323, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1324, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1325, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1326, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1327, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1328, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1329, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1332, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1333, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1340, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1341, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1387, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1388, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1389, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1390, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1397, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1398, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1409, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1410, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1411, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1412, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1415, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1416, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1431, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1432, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1433, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1434, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1455, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1456, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1470, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1471, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1472, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1473, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1476, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1477, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1478, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1486, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1487, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1488, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1491, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1492, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1493, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1494, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1495, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1496, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1513, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1514, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1515, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1516, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1517, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1518, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1531, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1532, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1533, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1538, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1539, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1540, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1541, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1550, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1551, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1552, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1553, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1554, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1563, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1564, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1565, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1566, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1567, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1568, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1605, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1606, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1607, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1608, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1609, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1610, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1611, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1612, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1613, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1614, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1615, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1618, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1619, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1620, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1621, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1622, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1623, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1624, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1625, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1626, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1627, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1628, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1629, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1630, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1631, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1632, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1636, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1637, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1639, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1641, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1642, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1643, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1644, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1647, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1648, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1649, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1650, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1651, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1652, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1653, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1654, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1655, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1656, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1657, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1681, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1682, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1683, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1684, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1722, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1723, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1724, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1725, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1740, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1741, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1742, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1743, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1763, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1764, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1765, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1766, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1787, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1788, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1791, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1792, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1797, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1798, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1801, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1802, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1803, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1804, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1805, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1806, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1807, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1808, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1836, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1837, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1838, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1839, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1840, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1841, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1842, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1843, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1871, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1872, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1873, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1874, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1875, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1876, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1877, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1892, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1893, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1894, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1915, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1916, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1927, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1928, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1929, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1930, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1931, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1932, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1933, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1934, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1965, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1966, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1967, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1968, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1969, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1970, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1971, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1972, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1973, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1974, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1975, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1976, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1977, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1978, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1979, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1980, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2037, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2038, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2041, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2042, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2059, + "Type": 39, + "Flags": 0 + }, + { + "Id": 2060, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2061, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2062, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2063, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2064, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2065, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2066, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2067, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2068, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2069, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2070, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2071, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2072, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2073, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2074, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2075, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2076, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2077, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2078, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2079, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2080, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2081, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2082, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2083, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2084, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2085, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2086, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2087, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2088, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2089, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2090, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2091, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2092, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2093, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2094, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2095, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2096, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2097, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2098, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2099, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2100, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2101, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2102, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2103, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2104, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2105, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2106, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2107, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2108, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2109, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2110, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2111, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2112, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2113, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2114, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2115, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2116, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2117, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2118, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2119, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2120, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2121, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2122, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2123, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2124, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2125, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2126, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2127, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2128, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2129, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2130, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2131, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2132, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2133, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2134, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2135, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2136, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2144, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2145, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2146, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2147, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2148, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2149, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2150, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2151, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2152, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2153, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2193, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2194, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2195, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2196, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2200, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2201, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2202, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2203, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2204, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2205, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2206, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2207, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2216, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2217, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2218, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2219, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2242, + "Type": 40, + "Flags": 0 + }, + { + "Id": 2243, + "Type": 40, + "Flags": 0 + }, + { + "Id": 2470, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2471, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2480, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2481, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2531, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2532, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2533, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2534, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2535, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2536, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2537, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2538, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2539, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2550, + "Type": 25, + "Flags": 0 + }, + { + "Id": 2551, + "Type": 25, + "Flags": 0 + }, + { + "Id": 2566, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2567, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2568, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2569, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2576, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2577, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2578, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2579, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2580, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2581, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2582, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2583, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2584, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2585, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2586, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2587, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2588, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2589, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2590, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2591, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2592, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2593, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2594, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2595, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2596, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2597, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2598, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2599, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2600, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2601, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2602, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2603, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2604, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2605, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2606, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2607, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2608, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2609, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2610, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2611, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2612, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2613, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2614, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2615, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2616, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2617, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2618, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2619, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2620, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2621, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2622, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2623, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2624, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2625, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2626, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2627, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2628, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2629, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2630, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2631, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2632, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2633, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2642, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2643, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2644, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2645, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2646, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2647, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2648, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2649, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2650, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2651, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2652, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2653, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2654, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2655, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2656, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2657, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2702, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2703, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2704, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2705, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2706, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2707, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2708, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2709, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2736, + "Type": 42, + "Flags": 1 + }, + { + "Id": 2737, + "Type": 42, + "Flags": 1 + }, + { + "Id": 2738, + "Type": 21, + "Flags": 1 + }, + { + "Id": 2739, + "Type": 21, + "Flags": 1 + }, + { + "Id": 2762, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2763, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2764, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2765, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2766, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2767, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2768, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2769, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2770, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2771, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2772, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2773, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2774, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2775, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2776, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2777, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2778, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2779, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2780, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2781, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2834, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2835, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2848, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2849, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2856, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2857, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2862, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2863, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2864, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2865, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2866, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2867, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2868, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2869, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2870, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2871, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2872, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2873, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2905, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2908, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2909, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2914, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2915, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2916, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2917, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2918, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2919, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2922, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2923, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2924, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2925, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2926, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2927, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2928, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2929, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2960, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2961, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2967, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2968, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2969, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2970, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2971, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2972, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2974, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2975, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2976, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2977, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2978, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2979, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2993, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2994, + "Type": 44, + "Flags": 0 + }, + { + "Id": 3010, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3011, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3022, + "Type": 48, + "Flags": 0 + }, + { + "Id": 3023, + "Type": 48, + "Flags": 0 + }, + { + "Id": 3026, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3027, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3030, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3031, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3036, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3037, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3046, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3047, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3054, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3055, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3056, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3057, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3058, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3059, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3060, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3061, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3105, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3106, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3107, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3108, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3114, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3115, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3138, + "Type": 14, + "Flags": 0 + }, + { + "Id": 3139, + "Type": 14, + "Flags": 0 + }, + { + "Id": 3163, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3164, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3169, + "Type": 51, + "Flags": 0 + }, + { + "Id": 3170, + "Type": 51, + "Flags": 0 + }, + { + "Id": 3188, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3189, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3190, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3227, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3228, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3229, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3230, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3231, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3239, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3240, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3241, + "Type": 52, + "Flags": 0 + }, + { + "Id": 3242, + "Type": 52, + "Flags": 0 + }, + { + "Id": 3315, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3316, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3317, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3318, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3319, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3320, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3321, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3322, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3323, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3324, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3325, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3326, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3327, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3328, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3329, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3330, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3331, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3332, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3333, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3334, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3360, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3361, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3362, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3363, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3379, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3380, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3381, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3382, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3391, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3392, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3417, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3418, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3419, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3420, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3421, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3422, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3423, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3424, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3429, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3430, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3437, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3438, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3455, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3456, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3499, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3500, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3501, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3502, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3503, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3504, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3505, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3506, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3507, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3508, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3529, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3530, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3531, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3532, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3543, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3544, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3545, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3552, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3553, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3560, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3561, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3566, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3569, + "Type": 29, + "Flags": 0 + }, + { + "Id": 3570, + "Type": 29, + "Flags": 0 + }, + { + "Id": 3605, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3606, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3611, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3612, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3623, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3624, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3635, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3636, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3659, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3660, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3661, + "Type": 54, + "Flags": 0 + }, + { + "Id": 3662, + "Type": 54, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 10, + "High": 1, + "Low": 14272 + }, + { + "Id": 12, + "High": 2, + "Low": 30656 + }, + { + "Id": 13, + "High": 2, + "Low": 14272 + }, + { + "Id": 14, + "High": 3, + "Low": 14272 + }, + { + "Id": 15, + "High": 16385, + "Low": 30663 + }, + { + "Id": 16, + "High": 16384, + "Low": 22464 + }, + { + "Id": 17, + "High": 16384, + "Low": 22471 + }, + { + "Id": 18, + "High": 1, + "Low": 30666 + }, + { + "Id": 19, + "High": 3, + "Low": 30656 + }, + { + "Id": 20, + "High": 258, + "Low": 800704 + }, + { + "Id": 21, + "High": 4194304, + "Low": 151690 + }, + { + "Id": 22, + "High": 6291456, + "Low": 20618 + }, + { + "Id": 23, + "High": 2, + "Low": 12362 + }, + { + "Id": 24, + "High": 1, + "Low": 20544 + }, + { + "Id": 25, + "High": 2, + "Low": 12352 + }, + { + "Id": 26, + "High": 1, + "Low": 12352 + }, + { + "Id": 27, + "High": 2, + "Low": 20544 + }, + { + "Id": 28, + "High": 2, + "Low": 12416 + }, + { + "Id": 29, + "High": 0, + "Low": 20610 + }, + { + "Id": 30, + "High": 2, + "Low": 20618 + }, + { + "Id": 31, + "High": 2, + "Low": 20610 + }, + { + "Id": 32, + "High": 1, + "Low": 20608 + }, + { + "Id": 33, + "High": 8388608, + "Low": 20618 + }, + { + "Id": 34, + "High": 0, + "Low": 20618 + }, + { + "Id": 35, + "High": 16385, + "Low": 20736 + }, + { + "Id": 36, + "High": 16384, + "Low": 20736 + }, + { + "Id": 37, + "High": 0, + "Low": 20544 + }, + { + "Id": 38, + "High": 1, + "Low": 20546 + }, + { + "Id": 39, + "High": 16385, + "Low": 20743 + }, + { + "Id": 40, + "High": 3, + "Low": 20544 + }, + { + "Id": 41, + "High": 2, + "Low": 12354 + }, + { + "Id": 42, + "High": 6291456, + "Low": 151690 + }, + { + "Id": 43, + "High": 1, + "Low": 12416 + }, + { + "Id": 44, + "High": 1, + "Low": 12418 + }, + { + "Id": 45, + "High": 0, + "Low": 12418 + }, + { + "Id": 46, + "High": 2, + "Low": 12418 + }, + { + "Id": 47, + "High": 2, + "Low": 20608 + }, + { + "Id": 48, + "High": 0, + "Low": 12416 + }, + { + "Id": 49, + "High": 3, + "Low": 22464 + }, + { + "Id": 50, + "High": 1, + "Low": 22464 + }, + { + "Id": 51, + "High": 2, + "Low": 14282 + }, + { + "Id": 52, + "High": 4, + "Low": 22464 + }, + { + "Id": 53, + "High": 3, + "Low": 20608 + }, + { + "Id": 54, + "High": 512, + "Low": 12448 + } + ], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 2, + "x": 55, + "y": -36 + }, + { + "Flag": 3, + "x": 54, + "y": -51 + }, + { + "Flag": 5, + "x": 13, + "y": -61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 0, + "x": 47, + "y": -40 + }, + { + "Flag": 1, + "x": 51, + "y": -3 + }, + { + "Flag": 4, + "x": 47, + "y": -47 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 23, + "y": -25 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 69, + "y": 14 + }, + { + "Flag": 4, + "x": 69, + "y": 30 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 54, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 69, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 37, + "y": 49 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 59, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 68, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 2", + "Start": "0273E000", + "End": "027537C0", + "RemapStart": null + }, + "Id": 2, + "TActors": [ + "0FFF 05FF 002E 0550 FF10 F7B9 0000 0094", + "01FF 00FF 002E 0000 FF10 FB99 0000 0095", + "02FF 01FF 002E 0000 FEFC F675 0000 0099", + "04FF 06FF 002E FAB0 00A0 F714 8000 00A0", + "07FF 02FF 002E 0000 FEFC F071 0000 0093", + "07FF 0CFF 002E FD6C FEFC EBC1 8000 003F", + "08FF 07FF 002E 0000 FEFC EB49 0000 008D", + "07FF 0BFF 002E 0294 FEFC EBC1 8000 0081", + "01FF 04FF 002E FD94 00A0 F959 C000 0092", + "05FF 01FF 002E 026C FF10 F959 C000 003F", + "0AFF 07FF 002E FBDC FEFC EDB5 4000 003F", + "09FF 07FF 002E 0424 FEFC EDB5 C000 003F", + "0EFF 03FF 002E 01CC FBF7 F369 C000 00BC", + "03FF 0DFF 002E FDBB FBF7 F54A DD28 00BB", + "0EFF 01FF 002E 0139 FB7F F959 C000 003F", + "02FF 03FF 0023 FFD8 FD82 F3F5 4000 00BF", + "02FF 03FF 0023 0028 FD82 F305 4000 00BF", + "02FF 03FF 0023 FEFC FD82 F2B5 4000 00BF", + "02FF 03FF 0023 FED4 FD82 F4D1 4000 00BF", + "02FF 03FF 0023 00DC FD82 F37D 4000 00BF", + "02FF 03FF 0023 FFC4 FD82 F229 4000 00BF", + "03FF 06FF 002E FC17 FC59 F2F1 C000 009F" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 2, Room 0", + "Start": "02754000", + "End": "02758070", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0096", + "018B", + "012B", + "000E", + "0163", + "0007", + "0012", + "013A", + "0190", + "00A8", + "0031" + ], + "Actors": [ + "000E FFFE FEB6 FF20 0000 0000 0000 FF00", + "0125 00D5 FEB6 FE72 0000 0000 0000 FF01", + "0125 FF25 FEAC FFC3 0000 0000 0000 FF01", + "01C6 00E8 FF2D FDC3 0000 E666 0000 0000", + "01C6 FF20 FF2D FDBB 0000 199A 0000 0000", + "00E6 FFFE FEAB FECF 0000 0000 0000 3D02", + "0127 FFFF FEAC FED8 0000 0000 0000 0000", + "002D FF25 FF10 FE68 0000 0000 0000 FFFF", + "002D FEF7 FF9D FE99 0000 0000 0000 FFFF", + "002D FF05 FF42 FEF5 0000 0000 0000 FFFF", + "0173 00C5 FF4A FDF1 0000 0019 0001 3F00", + "0173 FF35 FF4A FDE7 0000 0016 0001 3F00", + "000A 00C8 FF10 FF10 0000 4000 0018 8045", + "0112 FF37 FF44 FDE6 0000 0000 0004 1915", + "0112 00C7 FF44 FDF4 0000 0000 0004 1918", + "0111 FF49 FEB6 FE3F 0000 0000 0000 7804", + "0111 00CA FEAC FFC2 0000 0000 0000 640C", + "000A 0000 FEAC FF91 0000 0000 003D B823" + ] + }, + { + "File": { + "Name": "Scene 2, Room 1", + "Start": "02759000", + "End": "0275EE90", + "RemapStart": "27581B0" + }, + "Id": 1, + "Objects": [ + "0096", + "018B", + "012B", + "000E", + "0021", + "0026", + "00D5", + "00AC", + "00B7", + "0059", + "013A" + ], + "Actors": [ + "0015 FE7A F9EF F961 0000 0000 0000 0100", + "0015 FE19 FA2E F95B 0000 0000 0000 0200", + "0015 FDDB FA80 F953 0000 0000 0000 0300", + "0034 0092 FD3C F904 0000 0000 0000 FFFF", + "0034 FF7A FFB8 F9B2 0000 0000 0000 FFFF", + "00B6 FF54 FEAC F9EF 0000 238E 0000 01FF", + "00B6 FF17 FEB6 F955 0000 0000 0000 01FF", + "00B6 FF4F FEAC F8BE 0000 E4FA 0000 01FF", + "0015 FF27 FEBA F9AC 0000 0000 0000 2703", + "0015 FF32 FEB2 F8FB 0000 0000 0000 2803", + "01C6 FEF2 F9F0 F954 DBBC 6666 EE39 0000", + "01C6 0115 FF06 F8DC 0000 D1C7 0000 0000", + "00C8 0000 FCFD F959 0000 0000 0000 FF01", + "00E6 FED2 F9F0 F967 0000 0000 0000 0F03", + "00E6 FD9C FB2E F8D4 0000 0000 0000 1902", + "00C8 0078 0050 F9D1 0000 0000 0000 1D03", + "018C FF89 FB22 F965 0000 0000 0000 0000", + "0173 00D8 FF27 F8F7 0000 0005 0001 3F00", + "000A 00BF FB2F F907 0000 9111 0000 5042", + "0112 00D8 FF22 F8F7 0000 D1C7 0004 1904", + "015F 0155 FB2F F958 0005 0005 0005 15C6", + "0111 FD4F FB2F F8F8 0000 0000 0000 7208", + "0111 FD4B FB2F F9B2 0000 0000 0000 740C", + "011B 01E4 FEC0 F959 001E 000C 0000 3631", + "000A FD6C FB2F F952 0000 C000 000F B800", + "000A 0161 FF24 F98B 0000 0000 0004 8907", + "00DF 01E4 FEC0 F959 0000 C000 0000 0B80" + ] + }, + { + "File": { + "Name": "Scene 2, Room 2", + "Start": "0275F000", + "End": "027681D0", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0096", + "00A3", + "018B", + "012B", + "0021", + "0012", + "000E", + "0163", + "013A", + "0031", + "00AC", + "0024", + "015C", + "00D5" + ], + "Actors": [ + "0125 FF40 FEAC F377 0000 0000 0000 FF01", + "0125 015E FEAC F232 0000 0000 0000 FF01", + "0034 FFC3 FF60 F33D 0000 0000 0000 FFFF", + "0034 FEFB FF45 F406 0000 0000 0000 FFFF", + "00B6 0000 FE70 F17D 0000 0000 0000 00FF", + "01C6 00EB FF66 F555 0B61 749F 0000 0000", + "00A1 00D8 FEAC F400 0000 0000 0000 0202", + "0127 00F5 FF48 F518 0000 0000 0000 0006", + "0127 015E FEAC F233 0000 0000 0000 0008", + "0127 FF40 FEAC F375 0000 0000 0000 0009", + "0127 00DC FF4A F51A 0000 C93F 0000 0011", + "0127 0112 FF4D F51A 0000 BB06 0000 001A", + "0173 00F8 FF61 F51F 0000 0014 0001 3F00", + "0112 00F8 FF5B F52D 0000 0000 0004 1953" + ] + }, + { + "File": { + "Name": "Scene 2, Room 3", + "Start": "02769000", + "End": "02770160", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0096", + "00A3", + "018B", + "012B", + "0021", + "0012", + "000E", + "0163", + "013A", + "0031", + "00AC", + "0024", + "015C", + "00D5" + ], + "Actors": [ + "0125 0131 FB4A F267 0000 0000 0000 FF01", + "0125 00E7 FB49 F209 0000 0000 0000 FF01", + "0125 FFA5 FB4A F501 0000 0000 0000 FF01", + "0034 FFF6 FB8A F2FE 0000 0000 0000 FFFF", + "01C6 FE81 FC51 F3A9 0000 4444 0000 0000", + "01C6 FED8 FC8B F212 0000 02D8 0000 0000", + "00A1 00DE FBA7 F33A 0000 0000 0000 0203", + "00E6 002C FBA6 F1F4 0000 0000 0000 3C00", + "00E6 FFF1 FB4C F2FE 0000 0000 0000 3A02", + "015F FFF4 FA88 F307 0000 0000 0003 0EBF", + "002D 001A FBCE F268 0000 0000 0000 FFFF", + "000A 010E FCBF F233 0000 5E94 0003 8048", + "000A FF6B FD04 F4F0 0000 F27D 0007 8064", + "0112 FEDF FC84 F236 0000 0000 0004 1983", + "0112 FEE6 FC96 F22B 0000 0000 0004 1983", + "0112 FED2 FC98 F238 0000 0000 0004 1983", + "0112 FE97 FC4D F3AF 0000 0000 0004 1987", + "0112 FEA0 FC59 F3A5 0000 0000 0004 1987", + "0112 FE94 FC4B F39F 0000 0000 0004 1987", + "011B FDD0 FC09 F2F4 001E 000D 0000 382F", + "011B FDED FBA7 F51F 001E 000C 0000 3731", + "00DF FDED FC09 F51F 0000 6000 0000 0B80", + "00DF FDD0 FC09 F2F4 0000 4000 0000 0C81" + ] + }, + { + "File": { + "Name": "Scene 2, Room 4", + "Start": "02771000", + "End": "02775050", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0096", + "012B", + "011C", + "00D4", + "001B", + "00AC", + "011D", + "018B", + "00CB", + "00DC" + ], + "Actors": [ + "012D FA9B FFEF F7BD 0000 0000 0000 3DC1", + "012D FAC3 FFEF F7BD 0000 0000 0000 3DC1", + "012D FB2B FFAF F9CF 0000 4000 4000 3DC1", + "012D FB03 FFAF F9CE 4000 0000 0000 3DC1", + "0125 FBBF FFD8 FA2F 0000 0000 0000 FF01", + "00B6 FAB7 FFEC F934 0000 0000 0000 00FF", + "00B6 FBA7 FFD8 F951 0000 0000 0000 00FF", + "0025 FB33 0278 FA5A 0000 0000 0000 FFFF", + "01C6 FADC 0100 FB45 0000 80B6 0000 0000", + "01C6 FB17 FF94 F9F0 0000 0000 0000 0000", + "00E6 FCD3 004F F955 0000 0000 0000 1200", + "0110 FAC3 FFF4 F7BC 0000 0000 0000 FFFF", + "0110 FA9B FFF4 F7BD 0000 0000 0000 FFFF", + "0112 FADD 010F FB15 0000 0000 0004 19BD" + ] + }, + { + "File": { + "Name": "Scene 2, Room 5", + "Start": "02776000", + "End": "0277C020", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0096", + "00D4", + "018B", + "011C", + "000E", + "012B", + "00DC", + "00CB", + "015C", + "0024" + ], + "Actors": [ + "012D 05AF FF60 FB7C 0000 0000 0000 3DC1", + "012D 05AF FF05 FB7C 0000 0000 0000 3EC1", + "0125 05C5 FE48 FAAA 0000 0000 0000 FF01", + "0125 069B FE48 F9D8 0000 0000 0000 FF01", + "00DD 0541 0183 FA58 0000 0000 0000 FFFF", + "00DD 066A 01E0 F96A 0000 0000 0000 FFFF", + "01C6 05B0 FF0E FB7C 0000 8000 0000 0000", + "01C6 076A FF65 F968 0000 C000 0000 0000", + "0095 0570 002A F973 5DDE 2222 0000 8302", + "0112 05B2 FF1E FB38 0000 0000 0004 193E", + "0112 0726 FF7A F968 0000 0000 0004 1968", + "0112 05AB FF78 FB2F 0000 0000 0004 1AFD", + "012A 05B0 FFC4 FB5C 0000 0000 0000 1403", + "0111 0519 FEDA F82B 0000 0000 0000 6212", + "000A 050D FF82 F876 0000 BF4A 0028 852A" + ] + }, + { + "File": { + "Name": "Scene 2, Room 6", + "Start": "0277D000", + "End": "02781240", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0096", + "00A3", + "015F", + "0012", + "0021", + "0056", + "0026", + "0090", + "00AD", + "012B", + "018B", + "00BA" + ], + "Actors": [ + "0063 FAA9 019B F646 0000 0000 0000 FFFF", + "01C6 F94F 00CF F2E7 0000 4000 0000 0000", + "00A1 FAB0 FC2C F2F2 0000 4000 0000 0004", + "00C8 FAB0 FBFF F2F1 0000 C000 0000 1F00", + "0125 FBC2 0050 F2EE 0000 0000 0000 FF01", + "0125 FAB0 0050 F1EA 0000 0000 0000 FF01", + "008B FAB0 FC4C F2F1 0000 4000 0000 1015", + "0112 F99F 00E1 F2E9 0000 0000 0004 1920", + "0173 FAB0 FC5E F2F1 0006 0003 0000 3F3A" + ] + }, + { + "File": { + "Name": "Scene 2, Room 7", + "Start": "02782000", + "End": "02785520", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0096", + "0022", + "00D5", + "0012", + "0056", + "0036", + "012B", + "0163", + "001B" + ], + "Actors": [ + "0025 0000 FEAC ED12 0000 0000 0000 FFFF", + "00A1 0006 FEAC EEFE 0000 8000 0000 0206", + "00E6 0001 FEAB EBC6 0000 0000 0000 0D00", + "0127 FFDB FEAC EBCB 0000 0000 0000 001C", + "0127 001F FEAC EBC7 0000 5BBC 0000 001C", + "0110 FD66 FEAC EDC1 0000 0000 0000 FFFF", + "0110 FE00 FEAC EE10 0000 0000 0000 FFFF", + "000F 033B FEAC EDB1 0000 C000 0000 1FD6", + "011B FCB8 FEAC EDB3 001E 000B 0000 3432", + "011B FD71 FEAC ECA5 001E 000B 0000 3532", + "00DF FD71 FEAC ECA5 0000 0000 0000 0A82", + "00DF FCB8 FEAC EDB3 0000 4000 0000 0A82" + ] + }, + { + "File": { + "Name": "Scene 2, Room 8", + "Start": "02786000", + "End": "02789880", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0096", + "00A3", + "00D5", + "000E" + ], + "Actors": [ + "0187 FF8F FEAC E9DB 0000 0000 0000 2FFF", + "00DE 0001 0014 E957 0000 0000 0000 0B00" + ] + }, + { + "File": { + "Name": "Scene 2, Room 9", + "Start": "0278A000", + "End": "0278DC70", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0096", + "00A3", + "00D5", + "000E" + ], + "Actors": [ + "0187 0607 FEAC ED23 0000 0000 0000 2BFF", + "00DE 0619 0014 EDB9 0000 C000 0000 0A02" + ] + }, + { + "File": { + "Name": "Scene 2, Room 10", + "Start": "0278E000", + "End": "02791830", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0096", + "00A3", + "00D5" + ], + "Actors": [ + "0187 F9EA 0021 EDC8 0000 0000 0000 33FF", + "00DE F9E6 0014 EDB5 0000 4000 0000 0C01" + ] + }, + { + "File": { + "Name": "Scene 2, Room 11", + "Start": "02792000", + "End": "02795800", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0096", + "00A3", + "000E", + "018B", + "00A8", + "0190", + "00D4", + "012B", + "011C", + "00CB", + "00DC", + "0090", + "00A4" + ], + "Actors": [ + "012D 03A5 012E E9DB 0000 0000 0000 25C1", + "012D 03A5 012E EA03 0000 0000 0000 25C1", + "012D 0182 012D E9DB 0000 0000 0000 27C1", + "012D 0182 012D EA02 0000 0000 0000 27C1", + "0125 028C FEAC E9C9 0000 0000 0000 FF01", + "00DD 03EB 00E0 E9F1 0000 C000 0000 FFFF", + "00DD 0144 00CF E9EC 0000 0000 0000 FFFF", + "01C6 014E FF36 E9F3 0000 5333 0000 0000", + "01C6 03DC FF17 E9DF 0000 CD83 0000 0000", + "005E 0316 FEAC EB04 0AAB 8000 0000 03C1", + "0187 0274 FFC4 EAA4 0000 0000 0000 07FF", + "01D1 03EB 006F E9EF 0000 0000 0000 80FF", + "01D1 03EB 00CA EA48 0000 0000 0000 80FF", + "01D1 0446 00CA E9EE 0000 0000 0000 80FF", + "01D1 03EA 00C9 E993 0000 0000 0000 80FF", + "01D1 013F 00CA E994 0000 0000 0000 80FF", + "01D1 00E6 00CA E9ED 0000 0000 0000 80FF", + "01D1 013F 00CA EA46 0000 0000 0000 80FF", + "01D1 013F 006C E9ED 0000 0000 0000 80FF", + "0112 03AD FF1B E9F2 0000 0000 0004 18E5", + "0112 03B2 FF21 E9FE 0000 0000 0004 18E5", + "0112 03B2 FF21 E9E5 0000 0000 0004 18E5", + "0112 017B FF38 E9E5 0000 0000 0004 19A7", + "0112 0178 FF43 E9EC 0000 0000 0004 19A7", + "0112 0179 FF44 E9DA 0000 0000 0004 19A7", + "000A 0297 FEAC E8D3 0000 8000 0000 70E9", + "0111 0264 FEC6 E8D4 0000 0000 0000 7A08", + "0112 028D FEAC E9C8 0000 0000 0003 1AFF", + "0112 028C FEAC E9C8 0000 0000 0003 1AFF", + "0112 028D FEAC E9C7 0000 0000 0003 1AFF", + "0111 02CE FEAC E8D7 0000 0000 0000 7E0B" + ] + }, + { + "File": { + "Name": "Scene 2, Room 12", + "Start": "02796000", + "End": "02799CD0", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0096", + "00A3", + "0190", + "00A8", + "013A", + "012B", + "0024", + "015C", + "0163", + "0022", + "0012" + ], + "Actors": [ + "0095 FC89 FECB E8E8 0000 2000 0000 0000", + "0035 FDD9 FEAC E988 0000 0000 0000 FFFF", + "0035 FD02 FEAC E986 0000 0000 0000 FFFF", + "0035 FD6A FEAC EA4D 0000 0000 0000 FFFF", + "00E6 FD71 FEAB E9CC 0000 038E 0000 3D02", + "01D1 FE14 FF28 E9D0 0000 0000 0000 38FF", + "015F FD71 FDDB E9CD 0000 0000 0003 0F7F", + "0127 FE65 FF96 E9CE 0000 0000 0000 000E", + "0127 FC8B FEAC E8ED 0000 0000 0000 0010", + "002D FDEE FFC9 E92F 0000 0000 0000 FFFF", + "002D FCC6 FF58 EA37 0000 0000 0000 FFFF", + "0095 FE71 FFC5 E9C6 9E94 4EEF 0000 8304" + ] + }, + { + "File": { + "Name": "Scene 2, Room 13", + "Start": "0279A000", + "End": "0279CB50", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0096", + "00A3", + "0026", + "000D", + "011C", + "0036", + "0024", + "015C" + ], + "Actors": [ + "012D FBEC FB0F F6E4 0000 1D28 0000 05C1", + "0013 FBE1 FBA7 F796 0000 0000 0000 8003", + "0013 FAEC FC32 F6AA 0000 3DDE 0000 8003", + "0013 FBBA FC33 F5B3 0000 1BBC 0000 8003", + "00E6 FB98 FB2E F62A 0000 0000 0000 3B02", + "018C FC25 FB4D F5D4 0000 E38E 0000 0000", + "018C FC99 FB75 F6F4 0000 A38E 0000 0000", + "0187 FC20 FB2F F6B6 0000 0000 0000 17FF", + "000F FB85 FBA7 F73D 0000 5DDE 0000 1FFE", + "000F FB83 FBA7 F73E 0000 DDDE 0000 1FFE", + "0095 FB43 FBEF F772 C000 DDDE 0000 8308" + ] + }, + { + "File": { + "Name": "Scene 2, Room 14", + "Start": "0279D000", + "End": "027A31E0", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0096", + "000E", + "0026", + "001B", + "0190", + "00A8", + "012B", + "00D4", + "00CB", + "00DC", + "015C", + "0024", + "0090", + "0059", + "013A" + ], + "Actors": [ + "003A 0438 FAFD F72B 0000 8000 0000 000A", + "003A 039B FAF3 F6CD 0000 0000 0000 000A", + "0125 04CC FB57 F5A9 0000 0000 0000 FF01", + "00DD 04DE FAF3 F65A 0000 0000 0000 FFFF", + "0025 03A0 FB7F F370 0000 C7D2 0000 FFFF", + "00E6 04D8 FAF2 F6B1 0000 0000 0000 3902", + "00C8 044C FAFD F6B1 0000 0000 0000 3902", + "01D1 03AD FAF3 F5FC 0000 0000 0000 B8FF", + "000A 0508 FB57 F5B1 0000 0000 0000 5041", + "0095 03AC FAF3 F5E8 0000 0000 0000 8301", + "0111 02B9 FC73 F6F2 0000 0000 0000 6604", + "015F 044A FB36 F91C 0005 0005 0005 15C6", + "015F 024C FBCF F6AF 0005 0005 0002 15C6", + "000A 02BB FBCF F6B8 0000 C000 0000 10C6", + "0111 02BB FBE9 F673 0000 0000 0000 6808" + ] + }, + { + "File": { + "Name": "Scene 2, Room 15", + "Start": "027A4000", + "End": "027A66E0", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0096", + "00A3", + "0007", + "0012", + "0021", + "0056", + "0026", + "00AC" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": true, + "Polys": [ + { + "Id": 69, + "Type": 2, + "Flags": 0 + }, + { + "Id": 77, + "Type": 2, + "Flags": 0 + }, + { + "Id": 78, + "Type": 3, + "Flags": 0 + }, + { + "Id": 79, + "Type": 3, + "Flags": 0 + }, + { + "Id": 81, + "Type": 2, + "Flags": 0 + }, + { + "Id": 82, + "Type": 2, + "Flags": 0 + }, + { + "Id": 83, + "Type": 2, + "Flags": 0 + }, + { + "Id": 84, + "Type": 2, + "Flags": 0 + }, + { + "Id": 85, + "Type": 2, + "Flags": 0 + }, + { + "Id": 86, + "Type": 2, + "Flags": 0 + }, + { + "Id": 95, + "Type": 3, + "Flags": 0 + }, + { + "Id": 97, + "Type": 2, + "Flags": 0 + }, + { + "Id": 98, + "Type": 2, + "Flags": 0 + }, + { + "Id": 100, + "Type": 3, + "Flags": 0 + }, + { + "Id": 109, + "Type": 2, + "Flags": 0 + }, + { + "Id": 110, + "Type": 2, + "Flags": 0 + }, + { + "Id": 111, + "Type": 2, + "Flags": 0 + }, + { + "Id": 112, + "Type": 2, + "Flags": 0 + }, + { + "Id": 113, + "Type": 2, + "Flags": 0 + }, + { + "Id": 114, + "Type": 2, + "Flags": 0 + }, + { + "Id": 116, + "Type": 3, + "Flags": 0 + }, + { + "Id": 117, + "Type": 3, + "Flags": 0 + }, + { + "Id": 118, + "Type": 2, + "Flags": 0 + }, + { + "Id": 126, + "Type": 2, + "Flags": 0 + }, + { + "Id": 130, + "Type": 3, + "Flags": 0 + }, + { + "Id": 132, + "Type": 3, + "Flags": 0 + }, + { + "Id": 143, + "Type": 3, + "Flags": 0 + }, + { + "Id": 144, + "Type": 3, + "Flags": 0 + }, + { + "Id": 145, + "Type": 4, + "Flags": 0 + }, + { + "Id": 146, + "Type": 4, + "Flags": 0 + }, + { + "Id": 157, + "Type": 4, + "Flags": 0 + }, + { + "Id": 158, + "Type": 4, + "Flags": 0 + }, + { + "Id": 159, + "Type": 4, + "Flags": 0 + }, + { + "Id": 160, + "Type": 4, + "Flags": 0 + }, + { + "Id": 161, + "Type": 2, + "Flags": 0 + }, + { + "Id": 162, + "Type": 2, + "Flags": 0 + }, + { + "Id": 167, + "Type": 3, + "Flags": 0 + }, + { + "Id": 173, + "Type": 2, + "Flags": 0 + }, + { + "Id": 174, + "Type": 2, + "Flags": 0 + }, + { + "Id": 175, + "Type": 3, + "Flags": 0 + }, + { + "Id": 176, + "Type": 3, + "Flags": 0 + }, + { + "Id": 177, + "Type": 3, + "Flags": 0 + }, + { + "Id": 183, + "Type": 3, + "Flags": 0 + }, + { + "Id": 184, + "Type": 3, + "Flags": 0 + }, + { + "Id": 185, + "Type": 2, + "Flags": 0 + }, + { + "Id": 186, + "Type": 2, + "Flags": 0 + }, + { + "Id": 187, + "Type": 2, + "Flags": 0 + }, + { + "Id": 188, + "Type": 2, + "Flags": 0 + }, + { + "Id": 197, + "Type": 2, + "Flags": 0 + }, + { + "Id": 198, + "Type": 2, + "Flags": 0 + }, + { + "Id": 199, + "Type": 2, + "Flags": 0 + }, + { + "Id": 200, + "Type": 2, + "Flags": 0 + }, + { + "Id": 201, + "Type": 2, + "Flags": 0 + }, + { + "Id": 202, + "Type": 2, + "Flags": 0 + }, + { + "Id": 203, + "Type": 2, + "Flags": 0 + }, + { + "Id": 204, + "Type": 2, + "Flags": 0 + }, + { + "Id": 271, + "Type": 2, + "Flags": 0 + }, + { + "Id": 272, + "Type": 2, + "Flags": 0 + }, + { + "Id": 273, + "Type": 2, + "Flags": 0 + }, + { + "Id": 274, + "Type": 2, + "Flags": 0 + }, + { + "Id": 275, + "Type": 2, + "Flags": 0 + }, + { + "Id": 276, + "Type": 2, + "Flags": 0 + }, + { + "Id": 277, + "Type": 2, + "Flags": 0 + }, + { + "Id": 278, + "Type": 2, + "Flags": 0 + }, + { + "Id": 287, + "Type": 2, + "Flags": 0 + }, + { + "Id": 288, + "Type": 2, + "Flags": 0 + }, + { + "Id": 289, + "Type": 2, + "Flags": 0 + }, + { + "Id": 290, + "Type": 2, + "Flags": 0 + }, + { + "Id": 291, + "Type": 3, + "Flags": 0 + }, + { + "Id": 292, + "Type": 3, + "Flags": 0 + }, + { + "Id": 298, + "Type": 3, + "Flags": 0 + }, + { + "Id": 299, + "Type": 3, + "Flags": 0 + }, + { + "Id": 300, + "Type": 3, + "Flags": 0 + }, + { + "Id": 301, + "Type": 2, + "Flags": 0 + }, + { + "Id": 302, + "Type": 2, + "Flags": 0 + }, + { + "Id": 308, + "Type": 3, + "Flags": 0 + }, + { + "Id": 313, + "Type": 5, + "Flags": 0 + }, + { + "Id": 314, + "Type": 5, + "Flags": 0 + }, + { + "Id": 317, + "Type": 6, + "Flags": 0 + }, + { + "Id": 318, + "Type": 6, + "Flags": 0 + }, + { + "Id": 321, + "Type": 5, + "Flags": 0 + }, + { + "Id": 322, + "Type": 5, + "Flags": 0 + }, + { + "Id": 323, + "Type": 7, + "Flags": 0 + }, + { + "Id": 324, + "Type": 7, + "Flags": 0 + }, + { + "Id": 325, + "Type": 2, + "Flags": 0 + }, + { + "Id": 326, + "Type": 2, + "Flags": 0 + }, + { + "Id": 327, + "Type": 2, + "Flags": 0 + }, + { + "Id": 328, + "Type": 2, + "Flags": 0 + }, + { + "Id": 329, + "Type": 2, + "Flags": 0 + }, + { + "Id": 330, + "Type": 2, + "Flags": 0 + }, + { + "Id": 331, + "Type": 2, + "Flags": 0 + }, + { + "Id": 332, + "Type": 2, + "Flags": 0 + }, + { + "Id": 333, + "Type": 2, + "Flags": 0 + }, + { + "Id": 334, + "Type": 3, + "Flags": 0 + }, + { + "Id": 335, + "Type": 3, + "Flags": 0 + }, + { + "Id": 336, + "Type": 3, + "Flags": 0 + }, + { + "Id": 337, + "Type": 3, + "Flags": 0 + }, + { + "Id": 338, + "Type": 3, + "Flags": 0 + }, + { + "Id": 339, + "Type": 2, + "Flags": 0 + }, + { + "Id": 340, + "Type": 2, + "Flags": 0 + }, + { + "Id": 341, + "Type": 2, + "Flags": 0 + }, + { + "Id": 342, + "Type": 2, + "Flags": 0 + }, + { + "Id": 343, + "Type": 2, + "Flags": 0 + }, + { + "Id": 344, + "Type": 2, + "Flags": 0 + }, + { + "Id": 345, + "Type": 3, + "Flags": 0 + }, + { + "Id": 346, + "Type": 3, + "Flags": 0 + }, + { + "Id": 347, + "Type": 8, + "Flags": 0 + }, + { + "Id": 348, + "Type": 8, + "Flags": 0 + }, + { + "Id": 349, + "Type": 9, + "Flags": 0 + }, + { + "Id": 350, + "Type": 2, + "Flags": 0 + }, + { + "Id": 351, + "Type": 2, + "Flags": 0 + }, + { + "Id": 352, + "Type": 10, + "Flags": 0 + }, + { + "Id": 353, + "Type": 10, + "Flags": 0 + }, + { + "Id": 354, + "Type": 10, + "Flags": 0 + }, + { + "Id": 355, + "Type": 10, + "Flags": 0 + }, + { + "Id": 356, + "Type": 10, + "Flags": 0 + }, + { + "Id": 357, + "Type": 10, + "Flags": 0 + }, + { + "Id": 358, + "Type": 10, + "Flags": 0 + }, + { + "Id": 359, + "Type": 10, + "Flags": 0 + }, + { + "Id": 360, + "Type": 10, + "Flags": 0 + }, + { + "Id": 361, + "Type": 10, + "Flags": 0 + }, + { + "Id": 362, + "Type": 10, + "Flags": 0 + }, + { + "Id": 363, + "Type": 10, + "Flags": 0 + }, + { + "Id": 364, + "Type": 10, + "Flags": 0 + }, + { + "Id": 365, + "Type": 10, + "Flags": 0 + }, + { + "Id": 366, + "Type": 10, + "Flags": 0 + }, + { + "Id": 367, + "Type": 10, + "Flags": 0 + }, + { + "Id": 368, + "Type": 10, + "Flags": 0 + }, + { + "Id": 369, + "Type": 10, + "Flags": 0 + }, + { + "Id": 370, + "Type": 10, + "Flags": 0 + }, + { + "Id": 371, + "Type": 10, + "Flags": 0 + }, + { + "Id": 372, + "Type": 10, + "Flags": 0 + }, + { + "Id": 373, + "Type": 10, + "Flags": 0 + }, + { + "Id": 374, + "Type": 10, + "Flags": 0 + }, + { + "Id": 375, + "Type": 10, + "Flags": 0 + }, + { + "Id": 376, + "Type": 10, + "Flags": 0 + }, + { + "Id": 377, + "Type": 10, + "Flags": 0 + }, + { + "Id": 378, + "Type": 10, + "Flags": 0 + }, + { + "Id": 379, + "Type": 10, + "Flags": 0 + }, + { + "Id": 380, + "Type": 10, + "Flags": 0 + }, + { + "Id": 381, + "Type": 10, + "Flags": 0 + }, + { + "Id": 382, + "Type": 10, + "Flags": 0 + }, + { + "Id": 383, + "Type": 10, + "Flags": 0 + }, + { + "Id": 384, + "Type": 10, + "Flags": 0 + }, + { + "Id": 385, + "Type": 10, + "Flags": 0 + }, + { + "Id": 386, + "Type": 10, + "Flags": 0 + }, + { + "Id": 387, + "Type": 10, + "Flags": 0 + }, + { + "Id": 388, + "Type": 10, + "Flags": 0 + }, + { + "Id": 389, + "Type": 10, + "Flags": 0 + }, + { + "Id": 390, + "Type": 10, + "Flags": 0 + }, + { + "Id": 391, + "Type": 10, + "Flags": 0 + }, + { + "Id": 418, + "Type": 5, + "Flags": 0 + }, + { + "Id": 421, + "Type": 5, + "Flags": 0 + }, + { + "Id": 433, + "Type": 2, + "Flags": 0 + }, + { + "Id": 434, + "Type": 2, + "Flags": 0 + }, + { + "Id": 456, + "Type": 11, + "Flags": 0 + }, + { + "Id": 457, + "Type": 11, + "Flags": 0 + }, + { + "Id": 458, + "Type": 11, + "Flags": 0 + }, + { + "Id": 508, + "Type": 11, + "Flags": 0 + }, + { + "Id": 509, + "Type": 11, + "Flags": 0 + }, + { + "Id": 510, + "Type": 11, + "Flags": 0 + }, + { + "Id": 511, + "Type": 11, + "Flags": 0 + }, + { + "Id": 512, + "Type": 11, + "Flags": 0 + }, + { + "Id": 538, + "Type": 5, + "Flags": 0 + }, + { + "Id": 539, + "Type": 5, + "Flags": 0 + }, + { + "Id": 540, + "Type": 5, + "Flags": 0 + }, + { + "Id": 551, + "Type": 5, + "Flags": 0 + }, + { + "Id": 552, + "Type": 5, + "Flags": 0 + }, + { + "Id": 571, + "Type": 12, + "Flags": 0 + }, + { + "Id": 573, + "Type": 12, + "Flags": 0 + }, + { + "Id": 577, + "Type": 12, + "Flags": 0 + }, + { + "Id": 578, + "Type": 12, + "Flags": 0 + }, + { + "Id": 579, + "Type": 12, + "Flags": 0 + }, + { + "Id": 589, + "Type": 7, + "Flags": 0 + }, + { + "Id": 590, + "Type": 7, + "Flags": 0 + }, + { + "Id": 591, + "Type": 12, + "Flags": 0 + }, + { + "Id": 592, + "Type": 7, + "Flags": 0 + }, + { + "Id": 593, + "Type": 7, + "Flags": 0 + }, + { + "Id": 594, + "Type": 7, + "Flags": 0 + }, + { + "Id": 595, + "Type": 7, + "Flags": 0 + }, + { + "Id": 626, + "Type": 11, + "Flags": 0 + }, + { + "Id": 627, + "Type": 11, + "Flags": 0 + }, + { + "Id": 636, + "Type": 11, + "Flags": 0 + }, + { + "Id": 637, + "Type": 11, + "Flags": 0 + }, + { + "Id": 638, + "Type": 11, + "Flags": 0 + }, + { + "Id": 639, + "Type": 11, + "Flags": 0 + }, + { + "Id": 646, + "Type": 6, + "Flags": 0 + }, + { + "Id": 647, + "Type": 6, + "Flags": 0 + }, + { + "Id": 648, + "Type": 6, + "Flags": 0 + }, + { + "Id": 649, + "Type": 6, + "Flags": 0 + }, + { + "Id": 650, + "Type": 6, + "Flags": 0 + }, + { + "Id": 661, + "Type": 6, + "Flags": 0 + }, + { + "Id": 662, + "Type": 6, + "Flags": 0 + }, + { + "Id": 712, + "Type": 7, + "Flags": 0 + }, + { + "Id": 713, + "Type": 7, + "Flags": 0 + }, + { + "Id": 724, + "Type": 7, + "Flags": 0 + }, + { + "Id": 725, + "Type": 7, + "Flags": 0 + }, + { + "Id": 726, + "Type": 7, + "Flags": 0 + }, + { + "Id": 727, + "Type": 7, + "Flags": 0 + }, + { + "Id": 752, + "Type": 2, + "Flags": 0 + }, + { + "Id": 753, + "Type": 2, + "Flags": 0 + }, + { + "Id": 754, + "Type": 2, + "Flags": 0 + }, + { + "Id": 759, + "Type": 2, + "Flags": 0 + }, + { + "Id": 760, + "Type": 2, + "Flags": 0 + }, + { + "Id": 771, + "Type": 3, + "Flags": 0 + }, + { + "Id": 772, + "Type": 3, + "Flags": 0 + }, + { + "Id": 773, + "Type": 3, + "Flags": 0 + }, + { + "Id": 774, + "Type": 3, + "Flags": 0 + }, + { + "Id": 775, + "Type": 3, + "Flags": 0 + }, + { + "Id": 776, + "Type": 2, + "Flags": 0 + }, + { + "Id": 779, + "Type": 2, + "Flags": 0 + }, + { + "Id": 780, + "Type": 2, + "Flags": 0 + }, + { + "Id": 782, + "Type": 2, + "Flags": 0 + }, + { + "Id": 783, + "Type": 2, + "Flags": 0 + }, + { + "Id": 830, + "Type": 2, + "Flags": 0 + }, + { + "Id": 831, + "Type": 2, + "Flags": 0 + }, + { + "Id": 839, + "Type": 12, + "Flags": 0 + }, + { + "Id": 840, + "Type": 12, + "Flags": 0 + }, + { + "Id": 841, + "Type": 13, + "Flags": 0 + }, + { + "Id": 842, + "Type": 13, + "Flags": 0 + }, + { + "Id": 843, + "Type": 13, + "Flags": 0 + }, + { + "Id": 844, + "Type": 13, + "Flags": 0 + }, + { + "Id": 852, + "Type": 13, + "Flags": 0 + }, + { + "Id": 853, + "Type": 13, + "Flags": 0 + }, + { + "Id": 874, + "Type": 12, + "Flags": 0 + }, + { + "Id": 875, + "Type": 12, + "Flags": 0 + }, + { + "Id": 882, + "Type": 12, + "Flags": 0 + }, + { + "Id": 883, + "Type": 12, + "Flags": 0 + }, + { + "Id": 888, + "Type": 2, + "Flags": 0 + }, + { + "Id": 889, + "Type": 2, + "Flags": 0 + }, + { + "Id": 894, + "Type": 6, + "Flags": 0 + }, + { + "Id": 896, + "Type": 11, + "Flags": 0 + }, + { + "Id": 897, + "Type": 11, + "Flags": 0 + }, + { + "Id": 898, + "Type": 11, + "Flags": 0 + }, + { + "Id": 899, + "Type": 11, + "Flags": 0 + }, + { + "Id": 900, + "Type": 11, + "Flags": 0 + }, + { + "Id": 901, + "Type": 11, + "Flags": 0 + }, + { + "Id": 902, + "Type": 11, + "Flags": 0 + }, + { + "Id": 903, + "Type": 11, + "Flags": 0 + }, + { + "Id": 904, + "Type": 11, + "Flags": 0 + }, + { + "Id": 905, + "Type": 11, + "Flags": 0 + }, + { + "Id": 906, + "Type": 11, + "Flags": 0 + }, + { + "Id": 907, + "Type": 11, + "Flags": 0 + }, + { + "Id": 908, + "Type": 11, + "Flags": 0 + }, + { + "Id": 909, + "Type": 11, + "Flags": 0 + }, + { + "Id": 910, + "Type": 11, + "Flags": 0 + }, + { + "Id": 911, + "Type": 11, + "Flags": 0 + }, + { + "Id": 912, + "Type": 11, + "Flags": 0 + }, + { + "Id": 913, + "Type": 11, + "Flags": 0 + }, + { + "Id": 914, + "Type": 11, + "Flags": 0 + }, + { + "Id": 915, + "Type": 11, + "Flags": 0 + }, + { + "Id": 916, + "Type": 11, + "Flags": 0 + }, + { + "Id": 917, + "Type": 11, + "Flags": 0 + }, + { + "Id": 918, + "Type": 11, + "Flags": 0 + }, + { + "Id": 919, + "Type": 11, + "Flags": 0 + }, + { + "Id": 920, + "Type": 11, + "Flags": 0 + }, + { + "Id": 921, + "Type": 11, + "Flags": 0 + }, + { + "Id": 922, + "Type": 11, + "Flags": 0 + }, + { + "Id": 923, + "Type": 11, + "Flags": 0 + }, + { + "Id": 924, + "Type": 11, + "Flags": 0 + }, + { + "Id": 925, + "Type": 11, + "Flags": 0 + }, + { + "Id": 926, + "Type": 11, + "Flags": 0 + }, + { + "Id": 927, + "Type": 11, + "Flags": 0 + }, + { + "Id": 928, + "Type": 11, + "Flags": 0 + }, + { + "Id": 929, + "Type": 11, + "Flags": 0 + }, + { + "Id": 930, + "Type": 11, + "Flags": 0 + }, + { + "Id": 931, + "Type": 11, + "Flags": 0 + }, + { + "Id": 932, + "Type": 11, + "Flags": 0 + }, + { + "Id": 933, + "Type": 11, + "Flags": 0 + }, + { + "Id": 934, + "Type": 11, + "Flags": 0 + }, + { + "Id": 935, + "Type": 11, + "Flags": 0 + }, + { + "Id": 936, + "Type": 11, + "Flags": 0 + }, + { + "Id": 937, + "Type": 11, + "Flags": 0 + }, + { + "Id": 938, + "Type": 11, + "Flags": 0 + }, + { + "Id": 939, + "Type": 11, + "Flags": 0 + }, + { + "Id": 940, + "Type": 11, + "Flags": 0 + }, + { + "Id": 941, + "Type": 14, + "Flags": 0 + }, + { + "Id": 942, + "Type": 11, + "Flags": 0 + }, + { + "Id": 943, + "Type": 14, + "Flags": 0 + }, + { + "Id": 944, + "Type": 11, + "Flags": 0 + }, + { + "Id": 945, + "Type": 11, + "Flags": 0 + }, + { + "Id": 946, + "Type": 11, + "Flags": 0 + }, + { + "Id": 947, + "Type": 11, + "Flags": 0 + }, + { + "Id": 948, + "Type": 14, + "Flags": 0 + }, + { + "Id": 949, + "Type": 11, + "Flags": 0 + }, + { + "Id": 950, + "Type": 14, + "Flags": 0 + }, + { + "Id": 951, + "Type": 11, + "Flags": 0 + }, + { + "Id": 952, + "Type": 14, + "Flags": 0 + }, + { + "Id": 953, + "Type": 14, + "Flags": 0 + }, + { + "Id": 958, + "Type": 15, + "Flags": 0 + }, + { + "Id": 959, + "Type": 15, + "Flags": 0 + }, + { + "Id": 960, + "Type": 15, + "Flags": 0 + }, + { + "Id": 961, + "Type": 15, + "Flags": 0 + }, + { + "Id": 962, + "Type": 15, + "Flags": 0 + }, + { + "Id": 963, + "Type": 15, + "Flags": 0 + }, + { + "Id": 964, + "Type": 15, + "Flags": 0 + }, + { + "Id": 965, + "Type": 15, + "Flags": 0 + }, + { + "Id": 966, + "Type": 15, + "Flags": 0 + }, + { + "Id": 967, + "Type": 15, + "Flags": 0 + }, + { + "Id": 968, + "Type": 15, + "Flags": 0 + }, + { + "Id": 969, + "Type": 15, + "Flags": 0 + }, + { + "Id": 970, + "Type": 15, + "Flags": 0 + }, + { + "Id": 971, + "Type": 15, + "Flags": 0 + }, + { + "Id": 972, + "Type": 15, + "Flags": 0 + }, + { + "Id": 973, + "Type": 15, + "Flags": 0 + }, + { + "Id": 974, + "Type": 15, + "Flags": 0 + }, + { + "Id": 975, + "Type": 15, + "Flags": 0 + }, + { + "Id": 976, + "Type": 15, + "Flags": 0 + }, + { + "Id": 977, + "Type": 15, + "Flags": 0 + }, + { + "Id": 984, + "Type": 16, + "Flags": 0 + }, + { + "Id": 985, + "Type": 17, + "Flags": 0 + }, + { + "Id": 986, + "Type": 18, + "Flags": 0 + }, + { + "Id": 987, + "Type": 19, + "Flags": 0 + }, + { + "Id": 988, + "Type": 20, + "Flags": 0 + }, + { + "Id": 989, + "Type": 21, + "Flags": 0 + }, + { + "Id": 990, + "Type": 22, + "Flags": 0 + }, + { + "Id": 991, + "Type": 23, + "Flags": 0 + }, + { + "Id": 992, + "Type": 24, + "Flags": 0 + }, + { + "Id": 993, + "Type": 25, + "Flags": 0 + }, + { + "Id": 994, + "Type": 26, + "Flags": 0 + }, + { + "Id": 995, + "Type": 27, + "Flags": 0 + }, + { + "Id": 996, + "Type": 28, + "Flags": 0 + }, + { + "Id": 997, + "Type": 29, + "Flags": 0 + }, + { + "Id": 998, + "Type": 30, + "Flags": 0 + }, + { + "Id": 999, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1000, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1001, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1002, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1003, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1004, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1005, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1006, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1007, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1008, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1009, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1010, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1011, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1012, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1013, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1014, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1015, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1016, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1017, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1018, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1019, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1020, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1021, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1022, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1023, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1024, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1025, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1026, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1027, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1028, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1029, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1030, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1031, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1032, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1033, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1034, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1035, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1036, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1037, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1038, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1039, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1040, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1041, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1042, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1043, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1044, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1045, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1046, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1047, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1048, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1049, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1050, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1051, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1052, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1053, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1054, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1055, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1056, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1057, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1058, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1059, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1060, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1061, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1062, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1063, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1089, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1090, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1091, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1111, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1112, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1113, + "Type": 44, + "Flags": 0 + }, + { + "Id": 1114, + "Type": 44, + "Flags": 0 + }, + { + "Id": 1115, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1117, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1118, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1119, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1120, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1121, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1122, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1123, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1124, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1125, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1126, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1127, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1128, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1129, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1130, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1131, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1132, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1133, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1134, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1135, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1136, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1137, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1138, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1139, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1140, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1141, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1142, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1143, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1144, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1145, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1146, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1147, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1148, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1149, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1150, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1151, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1152, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1153, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1154, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1155, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1156, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1157, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1158, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1159, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1160, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1161, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1162, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1163, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1164, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1165, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1166, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1167, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1168, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1169, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1170, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1171, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1172, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1173, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1174, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1175, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1176, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1177, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1178, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1179, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1180, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1181, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1182, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1183, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1184, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1185, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1186, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1187, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1188, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1189, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1190, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1191, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1192, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1193, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1194, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1195, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1196, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1197, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1198, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1199, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1200, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1201, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1202, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1215, + "Type": 47, + "Flags": 0 + }, + { + "Id": 1216, + "Type": 47, + "Flags": 0 + }, + { + "Id": 1218, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1219, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1220, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1222, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1223, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1224, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1225, + "Type": 47, + "Flags": 0 + }, + { + "Id": 1226, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1227, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1231, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1245, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1248, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1249, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1254, + "Type": 49, + "Flags": 0 + }, + { + "Id": 1255, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1256, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1257, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1258, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1263, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1264, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1265, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1266, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1267, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1330, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1340, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1341, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1342, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1343, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1344, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1349, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1350, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1450, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1451, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1453, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1454, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1455, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1456, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1457, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1458, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1469, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1470, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1473, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1474, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1475, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1476, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1477, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1478, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1479, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1480, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1481, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1482, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1483, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1484, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1485, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1486, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1487, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1488, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1489, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1490, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1491, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1492, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1493, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1494, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1495, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1496, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1497, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1498, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1499, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1505, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1506, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1508, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1509, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1510, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1511, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1513, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1524, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1525, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1526, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1527, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1528, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1529, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1542, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1543, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1544, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1545, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1546, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1547, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1548, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1549, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1550, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1551, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1552, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1557, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1624, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1625, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1817, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1818, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1822, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1823, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1824, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1825, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1826, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1827, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1828, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1829, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1830, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1831, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1832, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1833, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1836, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1837, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1839, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1840, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1841, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1842, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1843, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1847, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1848, + "Type": 51, + "Flags": 1 + }, + { + "Id": 1849, + "Type": 51, + "Flags": 1 + }, + { + "Id": 1850, + "Type": 51, + "Flags": 1 + }, + { + "Id": 1851, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1852, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1853, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1854, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1855, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1856, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1857, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1858, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1859, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1860, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1861, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1862, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1863, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1864, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1865, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1866, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1867, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1868, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1869, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1870, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1872, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1873, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1878, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1879, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1880, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1889, + "Type": 52, + "Flags": 0 + }, + { + "Id": 1890, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1912, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1913, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1914, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1926, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1929, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1942, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1943, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1944, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1945, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1946, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1947, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1948, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1949, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1951, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1952, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1955, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1956, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2024, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2025, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2026, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2027, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2064, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2065, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2068, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2069, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2076, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2077, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2079, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2080, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2081, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2082, + "Type": 10, + "Flags": 0 + }, + { + "Id": 2083, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2084, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2089, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2090, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2217, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2218, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2219, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2340, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2341, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2342, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2343, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2344, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2345, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2446, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2447, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2448, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2449, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2460, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2461, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2462, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2463, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2464, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2465, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2476, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2477, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2478, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2479, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2490, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2491, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2492, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2493, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2494, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2495, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2496, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2497, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2508, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2509, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2510, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2511, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2522, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2523, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2524, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2525, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2526, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2527, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2528, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2529, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2538, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2539, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2540, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2541, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2542, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2543, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2552, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2553, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2554, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2555, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2556, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2557, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2558, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2559, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2568, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2569, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2570, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2571, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2580, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2581, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2582, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2583, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2588, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2589, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2598, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2599, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2600, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2601, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2606, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2607, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2608, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2609, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2614, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2615, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2616, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2617, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2632, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2633, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2634, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2635, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2644, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2645, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2646, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2647, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2652, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2653, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2654, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2655, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2656, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2657, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2680, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2681, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2682, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2683, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2684, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2685, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2686, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2687, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2688, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2689, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2690, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2691, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2692, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2706, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2707, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2708, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2709, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2710, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2711, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2712, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2713, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2722, + "Type": 56, + "Flags": 0 + }, + { + "Id": 2723, + "Type": 56, + "Flags": 0 + }, + { + "Id": 2724, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2725, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2735, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2736, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2737, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2738, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2739, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2740, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2741, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2742, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2743, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2744, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2745, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2746, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2747, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2770, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2771, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2772, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2773, + "Type": 58, + "Flags": 0 + }, + { + "Id": 2774, + "Type": 58, + "Flags": 0 + }, + { + "Id": 2775, + "Type": 58, + "Flags": 0 + }, + { + "Id": 2780, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2781, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2782, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2783, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2792, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2793, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2794, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2795, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2800, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2801, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2802, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2803, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2804, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2805, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2806, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2807, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2808, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2809, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2810, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2811, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2812, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2813, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2814, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2815, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2816, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2817, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2818, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2819, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2820, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2821, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2822, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2823, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2824, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2825, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2826, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2827, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2828, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2829, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2830, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2831, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2832, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2833, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2834, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2835, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2852, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2853, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2854, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2855, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2858, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2859, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2862, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2863, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2864, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2865, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2870, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2871, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2872, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2873, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2874, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2875, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2876, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2877, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2878, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2879, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2880, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2881, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2882, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2883, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2884, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2885, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2886, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2887, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2888, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2889, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2890, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2891, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2892, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2893, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2894, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2895, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2896, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2897, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2930, + "Type": 61, + "Flags": 0 + }, + { + "Id": 2931, + "Type": 61, + "Flags": 0 + }, + { + "Id": 2932, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2933, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2936, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2937, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2940, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2941, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2942, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2943, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2948, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2949, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2950, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2951, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2952, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2953, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2954, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2955, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2956, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2957, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2958, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2959, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2960, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2961, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2962, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2963, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2964, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2965, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2966, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2967, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2968, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2969, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2970, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2971, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2972, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2973, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2974, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2975, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3008, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3009, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3010, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3011, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3014, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3015, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3018, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3019, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3020, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3021, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3026, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3027, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3028, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3029, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3030, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3031, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3032, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3033, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3034, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3035, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3036, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3037, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3038, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3039, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3040, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3041, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3042, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3043, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3044, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3045, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3046, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3047, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3048, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3049, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3050, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3051, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3052, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3053, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3054, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3055, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3056, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3057, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3058, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3059, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3060, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3061, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3062, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3063, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3064, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3065, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3066, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3067, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3068, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3069, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3076, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3077, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3078, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3079, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3080, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3081, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3082, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3083, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3084, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3085, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3086, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3087, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3088, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3089, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3090, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3091, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3092, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3093, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3094, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3095, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3096, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3097, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3098, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3099, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3100, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3101, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3102, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3103, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3104, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3105, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3106, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3107, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3108, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3109, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3110, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3111, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3112, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3113, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3114, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3115, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3116, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3117, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3118, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3119, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3120, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3121, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3122, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3123, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3124, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3125, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3126, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3127, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3128, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3129, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3130, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3131, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3164, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3165, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3166, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3167, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3170, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3171, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3174, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3175, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3176, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3177, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3182, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3183, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3184, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3185, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3186, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3187, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3188, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3189, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3222, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3223, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3225, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3226, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3227, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3228, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3229, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3230, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3231, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3233, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3276, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3277, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3278, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3279, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3304, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3305, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3306, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3307, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3308, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3309, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3310, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3311, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3312, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3313, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3314, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3315, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3316, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3317, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3328, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3329, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3527, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3529, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3531, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3533, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3534, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3535, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3536, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3537, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3538, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3539, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3540, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3541, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3542, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3543, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3544, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3545, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3546, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3547, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3548, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3607, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3608, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3609, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3610, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3621, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3622, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3637, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3638, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3639, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3640, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3641, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3646, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3647, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3652, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3653, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3658, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3659, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3664, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3665, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3680, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3681, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3682, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3683, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3684, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3685, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3686, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3687, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3688, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3689, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3690, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3699, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3700, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3705, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3706, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3711, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3712, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3724, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3725, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3726, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3756, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3757, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3770, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3772, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3773, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3784, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3785, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3790, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3791, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3796, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3797, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3806, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3807, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3808, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3809, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3810, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3811, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3812, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3813, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3814, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3815, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3816, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3831, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3832, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3837, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3838, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3843, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3844, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3850, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3851, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3852, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3863, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3864, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3865, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3866, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3871, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3872, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3873, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3874, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3883, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3884, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3895, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3896, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3897, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3898, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3899, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3900, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3901, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3902, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3913, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3914, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3964, + "Type": 64, + "Flags": 0 + }, + { + "Id": 3965, + "Type": 64, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 2, + "High": -2147418112, + "Low": 12291 + }, + { + "Id": 3, + "High": -2147418110, + "Low": 12291 + }, + { + "Id": 4, + "High": -2147418111, + "Low": 12291 + }, + { + "Id": 5, + "High": -2147418109, + "Low": 30723 + }, + { + "Id": 6, + "High": 65539, + "Low": 12291 + }, + { + "Id": 7, + "High": 65539, + "Low": 30723 + }, + { + "Id": 8, + "High": -2147417856, + "Low": 12291 + }, + { + "Id": 9, + "High": -2147417855, + "Low": 12291 + }, + { + "Id": 10, + "High": 0, + "Low": 12291 + }, + { + "Id": 11, + "High": 65538, + "Low": 12291 + }, + { + "Id": 12, + "High": 65537, + "Low": 30723 + }, + { + "Id": 13, + "High": 65538, + "Low": 30723 + }, + { + "Id": 14, + "High": 604045314, + "Low": 12291 + }, + { + "Id": 15, + "High": 65536, + "Low": 143363 + }, + { + "Id": 16, + "High": 604045314, + "Low": 9187331 + }, + { + "Id": 17, + "High": 604045314, + "Low": 126627843 + }, + { + "Id": 18, + "High": 604045314, + "Low": 798723 + }, + { + "Id": 19, + "High": 604045314, + "Low": 17575939 + }, + { + "Id": 20, + "High": 604045314, + "Low": 25964547 + }, + { + "Id": 21, + "High": 604045314, + "Low": 34353155 + }, + { + "Id": 22, + "High": 604045314, + "Low": 40644611 + }, + { + "Id": 23, + "High": 604045314, + "Low": 118239235 + }, + { + "Id": 24, + "High": 604045314, + "Low": 107753475 + }, + { + "Id": 25, + "High": 604045314, + "Low": 101462019 + }, + { + "Id": 26, + "High": 604045314, + "Low": 93065219 + }, + { + "Id": 27, + "High": 604045314, + "Low": 84684803 + }, + { + "Id": 28, + "High": 604045314, + "Low": 76288003 + }, + { + "Id": 29, + "High": 604045314, + "Low": 67899395 + }, + { + "Id": 30, + "High": 604045314, + "Low": 59510787 + }, + { + "Id": 31, + "High": 604045314, + "Low": 51122179 + }, + { + "Id": 32, + "High": 604045314, + "Low": 84676611 + }, + { + "Id": 33, + "High": 604045314, + "Low": 93073411 + }, + { + "Id": 34, + "High": 604045314, + "Low": 67907587 + }, + { + "Id": 35, + "High": 604045314, + "Low": 7090179 + }, + { + "Id": 36, + "High": 604045314, + "Low": 124530691 + }, + { + "Id": 37, + "High": 604045314, + "Low": 116142083 + }, + { + "Id": 38, + "High": 604045314, + "Low": 90976259 + }, + { + "Id": 39, + "High": 604045314, + "Low": 76296195 + }, + { + "Id": 40, + "High": 604045314, + "Low": 59518979 + }, + { + "Id": 41, + "High": 604045314, + "Low": 49033219 + }, + { + "Id": 42, + "High": 604045314, + "Low": 42741763 + }, + { + "Id": 43, + "High": 604045314, + "Low": 51130371 + }, + { + "Id": 44, + "High": 65536, + "Low": 4099 + }, + { + "Id": 45, + "High": 8454144, + "Low": 12291 + }, + { + "Id": 46, + "High": 2162688, + "Low": 12291 + }, + { + "Id": 47, + "High": 49154, + "Low": 30723 + }, + { + "Id": 48, + "High": 49154, + "Low": 12291 + }, + { + "Id": 49, + "High": 2146306, + "Low": 12291 + }, + { + "Id": 50, + "High": 65536, + "Low": 30723 + }, + { + "Id": 51, + "High": -2147483648, + "Low": 12291 + }, + { + "Id": 52, + "High": 0, + "Low": 30723 + }, + { + "Id": 53, + "High": 65537, + "Low": 34109443 + }, + { + "Id": 54, + "High": 65537, + "Low": 67663875 + }, + { + "Id": 55, + "High": 65536, + "Low": 90732547 + }, + { + "Id": 56, + "High": 65536, + "Low": 67663875 + }, + { + "Id": 57, + "High": 65536, + "Low": 42498051 + }, + { + "Id": 58, + "High": 65537, + "Low": 101218307 + }, + { + "Id": 59, + "High": 65537, + "Low": 143363 + }, + { + "Id": 60, + "High": 65539, + "Low": 4099 + }, + { + "Id": 61, + "High": 65537, + "Low": 4099 + }, + { + "Id": 62, + "High": 65540, + "Low": 12291 + }, + { + "Id": 63, + "High": 65541, + "Low": 30723 + }, + { + "Id": 64, + "High": 512, + "Low": 12323 + } + ], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 3997696, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 3, + "x": 48, + "y": -68 + }, + { + "Flag": 5, + "x": 50, + "y": -66 + }, + { + "Flag": 7, + "x": 55, + "y": -50 + }, + { + "Flag": 9, + "x": 58, + "y": 1 + }, + { + "Flag": 10, + "x": 62, + "y": -45 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 65, + "y": -37 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 6, + "IconPoints": [ + { + "Flag": 0, + "x": 37, + "y": -49 + }, + { + "Flag": 1, + "x": 65, + "y": -38 + }, + { + "Flag": 2, + "x": 52, + "y": -48 + }, + { + "Flag": 4, + "x": 46, + "y": -36 + }, + { + "Flag": 6, + "x": 59, + "y": -41 + }, + { + "Flag": 8, + "x": 52, + "y": -26 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 3, + "x": 66, + "y": 50 + }, + { + "Flag": 5, + "x": 72, + "y": 47 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 72, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 4, + "x": 64, + "y": 62 + }, + { + "Flag": 8, + "x": 79, + "y": 38 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 10, + "x": 64, + "y": 45 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 67, + "y": 32 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 68, + "y": 45 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 79, + "y": 33 + }, + { + "Flag": 6, + "x": 61, + "y": 41 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 48, + "y": 57 + }, + { + "Flag": 2, + "x": 77, + "y": 55 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 3", + "Start": "023CF000", + "End": "023E4F90", + "RemapStart": null + }, + "Id": 3, + "TActors": [ + "01FF 00FF 0009 0077 0167 003C 0000 003F", + "04FF 02FF 0009 0077 01D3 F62C 0000 003F", + "0BFF 05FF 002E FAA9 017F FA60 4000 007F", + "07FF 0FFF 002E 067F 020B F4C4 8000 0099", + "0BFF 08FF 0009 FA22 020B F8B8 8000 003F", + "14FF 0DFF 002E 0676 04CC F308 C000 02C0", + "0DFF 06FF 002E 01F3 033B F308 C000 0095", + "0CFF 06FF 002E FE83 033B F308 4000 0095", + "04FF 06FF 002E 0077 01D3 F43E 8000 007F", + "08FF 0AFF 002E FF87 0320 F506 4000 003F", + "07FF 0AFF 002E 0167 0320 F506 C000 003F", + "08FF 15FF 002E F995 020B F516 8000 007F", + "08FF 12FF 002E F92F 020B F802 C000 007F", + "03FF 10FF 002E 0645 01CF FA60 4000 007F", + "02FF 05FF 002E FD07 017F FA60 C000 007F", + "08FF 02FF 002E FD63 00F3 F74C 2000 00A5", + "07FF 02FF 002E 038B 00F3 F74C E0B6 00AA", + "03FF 02FF 0009 03E7 01CF FA60 C000 003F", + "07FF 09FF 0023 04F1 FFB3 F920 0000 00BF", + "08FF 09FF 0023 FBFA FFB2 F920 0000 00BF", + "02FF 11FF 0023 0077 002D F9E2 0000 009B", + "14FF 0FFF 0023 084C 032D F28B 0000 00BF", + "13FF 15FF 0023 F91F 02AB F308 8000 00BF", + "02FF 01FF 0009 0077 017F FDBC 0000 0086", + "10FF 0FFF 0009 07C7 0193 F8E4 8000 0083", + "13FF 0BFF 002E F91F 04CC F8E4 0000 02C2", + "13FF 0CFF 002E FA78 04CC F308 4000 02C1", + "0EFF 14FF 002E 07CF 04CC F8E4 8000 02C4", + "16FF 11FF 002E 0077 FCF5 F503 0000 0154" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 3, Room 0", + "Start": "023E5000", + "End": "023F2BC0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "015C" + ], + "Actors": [ + "0095 01C3 038D 0217 0000 C000 0000 0000", + "0095 01C3 027F 0236 0000 C000 0000 0000", + "0095 01C3 045F 026D 0000 C000 0000 0000", + "0095 01C3 0311 027B 0000 C000 0000 0000", + "0095 01C3 01ED 02A4 0000 C000 0000 0000", + "0037 0069 03FD 01F8 0000 671C 0000 0000", + "000A 018C 047F 0194 0000 4000 000D 8843", + "012A FF58 035C 0243 0000 505B 0000 0D00" + ] + }, + { + "File": { + "Name": "Scene 3, Room 1", + "Start": "023F3000", + "End": "023F8B60", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0190", + "00A8" + ], + "Actors": [ + "0037 0077 0209 FE85 0000 0000 0000 0000", + "0037 0077 01C6 FEFA 0000 0000 0000 0000", + "0037 0077 0201 FF75 0000 0000 0000 0000", + "0095 0048 0243 FDD3 0000 0000 0000 8402" + ] + }, + { + "File": { + "Name": "Scene 3, Room 2", + "Start": "023F9000", + "End": "02408A30", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0007", + "0039", + "00B7", + "015C", + "0190", + "00A8", + "0099" + ], + "Actors": [ + "0173 FFEA 0166 F957 0002 001D 0000 3F8C", + "0173 0106 0166 F959 0002 001F 0000 3F8C", + "0173 FFE9 0166 FA77 0002 001E 0000 3F8C", + "0173 0106 0166 FA77 0002 0020 0000 3F8C", + "0087 0077 00E9 F9E2 0000 0000 0000 001B", + "0105 FFEA 011D F958 0000 0000 0000 001C", + "0105 FFEA 011D FA78 0000 0000 0000 011D", + "0105 0107 011D F958 0000 0000 0000 021E", + "0105 0107 011D FA78 0000 0000 0000 031F", + "0111 02A3 0139 FC23 0000 9F4A 0000 400F", + "0111 FE53 0139 FC2B 0000 6000 0000 420F", + "0111 02D0 0139 FBF3 0000 9F4A 0000 4403", + "0111 FE23 0139 FBF6 0000 6000 0000 4603", + "0111 0276 0139 FC51 0000 9F4A 0000 4809", + "0111 FE80 0139 FC57 0000 6000 0000 4A09", + "012A FE66 0221 F852 0000 2000 0000 2502", + "012A 028A 0221 F852 0000 E000 0000 2A02", + "0173 FFE9 0166 F957 0002 005D 0000 2C8D", + "0173 FFE9 0166 FA73 0002 005E 0000 2D8D", + "0173 0108 0166 F957 0002 005F 0000 2E8D", + "0173 0106 0166 FA77 0002 0060 0000 2F8D" + ] + }, + { + "File": { + "Name": "Scene 3, Room 3", + "Start": "02409000", + "End": "0240CA10", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024" + ], + "Actors": [ + "0008 062F 0206 FA27 0000 C000 0000 83F0", + "0008 062F 0206 FA2F 0000 C000 0000 83F0", + "0008 062F 0206 FA91 0000 C000 0000 83F0", + "0008 062F 0206 FA99 0000 C000 0000 83F0" + ] + }, + { + "File": { + "Name": "Scene 3, Room 4", + "Start": "0240D000", + "End": "024102B0", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0190", + "00A8" + ], + "Actors": [ + "0173 0078 0208 F4C6 0000 0021 0001 3F05", + "01D1 0078 01D4 F484 0000 0000 0000 B820" + ] + }, + { + "File": { + "Name": "Scene 3, Room 5", + "Start": "02411000", + "End": "024145E0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0032" + ], + "Actors": [ + "0008 FAC0 01B6 FA27 0000 4000 0000 83F0", + "0008 FAC0 01B6 FA2F 0000 4000 0000 83F0", + "0008 FAC0 01B6 FA91 0000 4000 0000 83F0", + "0008 FAC0 01B6 FA99 0000 4000 0000 83F0", + "0002 FC18 017F FA60 0000 4000 0000 FFFF", + "0187 FCC2 017F FA60 0000 0000 0000 4FFF" + ] + }, + { + "File": { + "Name": "Scene 3, Room 6", + "Start": "02415000", + "End": "0241E4C0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0032", + "0190", + "00A8", + "0183" + ], + "Actors": [ + "01AF 0000 01D3 F2F4 0000 0E39 0000 FF00", + "01AF 00FA 01D3 F2F4 0000 F1C7 0000 FF00", + "000A 0077 01D3 F290 0000 8000 0000 7840", + "000A 0077 033B F290 0000 8000 0015 B08C", + "0086 00D1 033B F308 0000 0000 0000 1500", + "01D1 0078 01D4 F3F8 0000 8000 0000 B820", + "0111 005A 01D3 F201 0000 0000 0000 6203", + "0111 008E 01D3 F201 0000 0000 0000 6412", + "0111 00CE 033B F1D1 0000 0000 0000 6603", + "0111 0020 033B F43C 0000 8000 0000 6803", + "0111 001E 033B F1D1 0000 0000 0000 6A03", + "0111 00CA 033B F43C 0000 8000 0000 6C03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 7", + "Start": "0241F000", + "End": "02432000", + "RemapStart": "241E5A0" + }, + "Id": 7, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "0036", + "0039", + "011C", + "00B7", + "015C", + "0190", + "00A8" + ], + "Actors": [ + "012D 021B 03DC F506 0000 4000 0000 FFC2", + "012D 03F7 0211 F6DE 0000 6000 0000 FFC2", + "0095 02C0 0389 F42F 0000 0000 0000 0000", + "0055 0604 0143 F5A0 0000 160B 0000 0000", + "0055 0446 00CB F5F1 0000 DF4A 0000 0001", + "0055 0464 00C4 F815 0000 25B0 0000 0001", + "0095 03FD 0212 F6D8 0000 6000 0000 8401", + "000A 05F0 0143 F545 0000 8000 0000 5841", + "000A 038D 0320 F3F3 0000 8000 0000 5845", + "000A 04B5 FF14 F920 0000 C000 0000 5849", + "01D1 0280 01EA F4A8 0000 0000 0000 2822", + "01D1 0280 0186 F588 0000 2000 0000 A823", + "01D1 06C5 017F F618 0000 0000 0000 3924", + "00E4 04F1 00AE F920 0000 0000 0000 0026", + "012A 04F3 0064 F8D0 0000 0000 0000 2602", + "01D1 06C5 0143 F5DC 0000 0000 0000 B927", + "01D1 06C5 01CF F596 0000 0000 0000 B928", + "01D1 0308 0186 F611 0000 2000 0000 2829" + ] + }, + { + "File": { + "Name": "Scene 3, Room 8", + "Start": "02432000", + "End": "02449B70", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "0036", + "0039", + "0007", + "00B7", + "015C" + ], + "Actors": [ + "000E FC5A 00BC F496 0000 293F 0000 FF00", + "000E FC0E 00BC F5A0 0000 1D28 0000 FF00", + "000E FACE 00BC F651 0000 3333 0000 FF00", + "0095 FECF 0301 F47E 0000 C000 0000 0000", + "0095 FECF 014D F49D 0000 C000 0000 0000", + "0095 FECF 026E F4BF 0000 C000 0000 0000", + "0037 FEB7 0370 F506 0000 C000 0000 0000", + "0095 FB6E 01A8 F9A7 0000 705B 0000 8404", + "000F FEC3 034D F4E3 438E C000 0000 0FE1", + "00E4 FBFD 00AE F920 0000 0000 0000 0026", + "0015 FB9C 01F8 F4D9 0000 0000 0000 2D03", + "0015 FB7B 01F8 F512 0000 0000 0000 2E03", + "0015 FB60 01F8 F548 0000 0000 0000 2F03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 9", + "Start": "0244A000", + "End": "02454190", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0007", + "0039", + "00B7" + ], + "Actors": [ + "0095 FBAD FF06 F894 0000 4000 0000 8408", + "000A 04B5 FF14 F920 0000 C000 0000 5849", + "00E4 0077 FEE6 F8E4 0000 0000 0000 0026", + "012A 04F3 0064 F8D0 0000 0000 0000 2602", + "0015 0073 FF14 F925 0000 0000 0000 3803", + "0015 000F FF14 F925 0000 0000 0000 3903", + "0015 00D7 FF14 F925 0000 0000 0000 3A03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 10", + "Start": "02455000", + "End": "0245A3E0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "0036", + "0039" + ], + "Actors": [ + "0037 0030 038D F501 0000 293F 0000 0001", + "005E 0078 0320 F57D 0000 8000 0000 2400", + "000F FFB4 0320 F505 0000 3555 0000 1FE1" + ] + }, + { + "File": { + "Name": "Scene 3, Room 11", + "Start": "0245B000", + "End": "02465BD0", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "00B7", + "011C" + ], + "Actors": [ + "012D FA22 02AB F8F7 4000 0000 0000 FFC2", + "0069 FA16 04EF F946 0000 E9F5 0000 FFFF", + "0069 F944 04EF FACC 0000 F3E9 0000 FFFF", + "00FF F851 026F FB14 0000 4000 0000 0542", + "00FF F851 026F FC04 0000 4000 0000 0542", + "00FF F711 025B FC04 0000 0000 0000 0546", + "0139 F711 025B FC04 0000 0000 0000 0005", + "00FF F879 034B FB8C 0000 4000 0000 0702", + "00FF F8F1 034B FB8C 0000 4000 0000 0702", + "00FF F9B9 0337 FB8C 0000 0000 0000 0706", + "0139 F9B9 0337 FB8C 0000 0000 0000 0007", + "011B F781 026F FB16 0014 0029 0000 088F", + "012D F941 026F FACA 0000 8000 0000 0FC1", + "012D FA5C 03FF FB50 0000 8000 0000 0FC1", + "01B4 F9D7 02AB FAC4 0000 0000 0000 0F01", + "01B4 FA63 02E7 FAC4 0000 0000 0000 0F01", + "012A FA5C 03FF FB8B 0000 C000 0000 0F03", + "0095 FA74 017F FC22 0000 C000 0000 8410", + "01B4 FA22 028C F95B C000 0000 0000 1301", + "01B4 FA22 0228 F95B C000 0000 0000 1301", + "012A FA22 020B F933 0000 0000 0000 1313", + "0068 F91F 04FE F439 0000 0000 0000 7F13" + ] + }, + { + "File": { + "Name": "Scene 3, Room 12", + "Start": "02466000", + "End": "0246E3E0", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "0099" + ], + "Actors": [ + "0173 FE52 0371 F2B2 0002 001E 0000 3F94", + "0173 FE52 0371 F2B2 0002 005E 0000 0A95", + "000A FE36 033B F259 0000 4000 0000 182D", + "0093 FD3D 051C F2CC 0000 C000 0000 021D", + "0105 FE51 033B F2AE 0000 0000 0000 011D" + ] + }, + { + "File": { + "Name": "Scene 3, Room 13", + "Start": "0246F000", + "End": "02477AB0", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0070", + "0071", + "0099" + ], + "Actors": [ + "0173 0225 0371 F2B2 0002 001F 0000 3F94", + "0173 0225 0371 F2B2 0002 005F 0000 0B95", + "000A 023F 033B F256 0000 C000 0000 180F", + "0093 0339 051C F2CC 0000 4000 0000 031E", + "0105 0225 033B F2AE 0000 0000 0000 021E", + "0111 033E 033B F1C9 0000 0000 0000 4C03", + "0111 03AD 033B F1C8 0000 0000 0000 4E09", + "0111 0373 033B F1C8 0000 0000 0000 5009" + ] + }, + { + "File": { + "Name": "Scene 3, Room 14", + "Start": "02478000", + "End": "0247DBB0", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0070", + "0071", + "0179" + ], + "Actors": [ + "00E3 07CF 0422 FAD6 0000 0000 0000 FF00", + "0173 05EF 0549 FAD6 0003 0019 0000 3F97", + "0068 07CF 04FE F439 0000 0000 0000 FF18", + "012A 05EF 0549 FAD6 0000 4000 0000 1892", + "01B4 07D0 04FE F90C 4000 0000 0000 3801", + "005E 07F5 04BF FAD6 0000 C000 0000 03F8", + "012A 07C8 04CC FAD6 0000 4000 0000 3820", + "0110 0908 0445 FC96 0000 0000 0000 3808", + "0110 093C 0445 FC97 0000 0000 0000 3908", + "0110 063F 04CC FAD6 0000 4000 0000 3A03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 15", + "Start": "0247E000", + "End": "02480690", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024" + ], + "Actors": [ + "0037 0728 02C6 F446 0000 8000 0000 0000", + "0037 0816 02C3 F44A 0000 8000 0000 0000", + "0037 0815 02C6 F537 0000 8000 0000 0000", + "0037 0725 02C6 F58B 0000 8000 0000 0000", + "0037 0866 02C3 F5DD 0000 8000 0000 0000", + "0037 077A 02C6 F6C3 0000 8000 0000 0000", + "0037 07CA 02C8 F768 0000 8000 0000 0000", + "0089 07C7 02AB F628 0000 8000 0000 FFFF", + "000A 0867 02F2 F628 0000 0000 000E 8926", + "011B 07C0 0193 F405 0032 002C 0014 4998", + "012A 0728 0193 F7B8 0000 0000 0000 0E00", + "012A 0817 0193 F769 0000 0000 0000 1900" + ] + }, + { + "File": { + "Name": "Scene 3, Room 16", + "Start": "02481000", + "End": "02485FA0", + "RemapStart": "2480760" + }, + "Id": 16, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0099" + ], + "Actors": [ + "0173 06B8 020E FAC1 0002 0020 0000 3F94", + "0173 06B8 020E FAC1 0002 0060 0000 0C95", + "0093 07ED 0373 FA42 0000 4000 0000 011F", + "0093 0933 025B FA60 0000 C000 0000 041F", + "0105 06B5 01CF FAC4 0000 4000 0000 031F", + "0093 0829 0373 FA06 0000 4000 0000 001F", + "0111 066F 01CF FA07 0000 0000 0000 5603", + "0111 066D 01CF F9CC 0000 0000 0000 5809" + ] + }, + { + "File": { + "Name": "Scene 3, Room 17", + "Start": "02486000", + "End": "0248F150", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "015C", + "00B0" + ], + "Actors": [ + "0037 FEA6 FD30 FBB1 0000 6000 0000 0000", + "0037 FEDE FD30 FB75 0000 6000 0000 0001", + "0088 0077 FCF5 F9E2 0000 8000 0000 FFFF", + "000A FE8C FCF5 F7F0 0000 A000 0000 592B", + "00E3 0077 FCF5 FBFB 0000 8000 0000 1001", + "012A 031D FCF5 F9E2 0000 C000 0000 1000", + "00E3 0077 FCF5 F7C9 0000 0000 0000 1101", + "012A 0077 FDC6 FC0F 0000 0000 0000 1102", + "012A 0266 FD80 F9E2 8000 C000 0000 1203", + "00E3 0291 FCF5 F9E2 0000 C000 0000 1201", + "0087 0077 FCF5 F9E2 0000 0000 0000 001B", + "0111 FE33 FCF5 FBB9 0000 6000 0000 7003", + "0111 FEA1 FCF5 FC2D 0000 6000 0000 7203", + "0111 FE7D FCF5 FC06 0000 6000 0000 740B", + "0111 FE58 FCF5 FBDF 0000 6000 0000 7608" + ] + }, + { + "File": { + "Name": "Scene 3, Room 18", + "Start": "02490000", + "End": "02491340", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "000B", + "0098" + ], + "Actors": [ + "0090 F83D 01F7 F8CE 0000 53E9 0000 7F00", + "000A F7F4 01F7 F804 0000 C000 0000 7842" + ] + }, + { + "File": { + "Name": "Scene 3, Room 19", + "Start": "02492000", + "End": "02492510", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "000B" + ], + "Actors": [ + "0011 F91D 05BB F30A 0000 0000 0000 0001", + "0173 F9F0 0595 F274 0000 0014 0000 3F92", + "0068 F91F 04FE F439 0000 0000 0000 3F13", + "011B F913 04B6 F3C9 0000 0000 0000 1691" + ] + }, + { + "File": { + "Name": "Scene 3, Room 20", + "Start": "02493000", + "End": "02494300", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0070", + "0071", + "000B" + ], + "Actors": [ + "0069 07CE 04FC F639 0000 8000 0000 01FC", + "0069 07D1 04F5 F78B 0000 8000 0000 01FC", + "0011 07CE 05C0 F302 0000 C0B6 0000 0001", + "011B 071A 04CC F309 0000 0000 0000 1791", + "0068 07CF 04FE F439 0000 0000 0000 BF18" + ] + }, + { + "File": { + "Name": "Scene 3, Room 21", + "Start": "02495000", + "End": "02496780", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "000B" + ], + "Actors": [ + "008E F996 020B F48A 0000 8000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 3, Room 22", + "Start": "02497000", + "End": "02498DE0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "015C", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 327680, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 6, + "IconPoints": [ + { + "Flag": 3, + "x": 53, + "y": -64 + }, + { + "Flag": 5, + "x": 65, + "y": -9 + }, + { + "Flag": 12, + "x": 49, + "y": -1 + }, + { + "Flag": 13, + "x": 40, + "y": 0 + }, + { + "Flag": 14, + "x": 18, + "y": -2 + }, + { + "Flag": 15, + "x": 59, + "y": 0 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 4, + "IconPoints": [ + { + "Flag": 0, + "x": 49, + "y": -1 + }, + { + "Flag": 1, + "x": 71, + "y": -13 + }, + { + "Flag": 2, + "x": 11, + "y": -25 + }, + { + "Flag": 6, + "x": 84, + "y": -16 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 65, + "y": -30 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 41, + "y": -24 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 50, + "y": -11 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 72, + "y": 57 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 69, + "y": 39 + }, + { + "Flag": 9, + "x": 62, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 71, + "y": 59 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 13, + "x": 80, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 15, + "x": 49, + "y": 50 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 6, + "x": 65, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 39, + "y": 35 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 53, + "y": 5 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 65, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 14, + "x": 64, + "y": 31 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 75, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 12, + "x": 69, + "y": 52 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 58, + "y": 27 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 4", + "Start": "022D8000", + "End": "022F2970", + "RemapStart": null + }, + "Id": 4, + "TActors": [ + "05FF 04FF 0023 0820 0992 FD80 4000 00BF", + "0AFF 02FF 0023 FC04 07C6 0000 0000 00BF", + "06FF 01FF 0023 0618 076C 0000 8000 007F", + "08FF 06FF 0023 0618 0ED8 0000 8000 007F", + "0DFF 0BFF 0023 F90C 0ED8 0000 8000 007F", + "09FF 10FF 002E 0154 0B7C 00BE 4000 009F", + "04FF 15FF 0009 0BFE 080C 0000 4000 003F", + "0AFF 09FF 0009 FDD0 0B7C 00BE 4000 003F", + "0AFF 0BFF 002E F90C 0AF0 FEB6 0000 0099", + "0BFF 0AFF 0009 F90C 0AF0 014A 0000 003F", + "0DFF 0CFF 0009 F6BE 1130 0014 C000 0098", + "0CFF 18FF 0009 F576 0FA0 009F C000 003F", + "13FF 01FF 002E 0618 00F0 FA10 0000 00A9", + "14FF 0100 0009 0618 0064 F9E8 0000 003F", + "15FF 01FF 0009 0A8C 00C8 0000 C000 009E", + "16FF 01FF 0009 0618 00C8 062C 8000 003F", + "02FF 00FF 002E FE5C 00C8 0000 4000 00A8", + "00FF 11FF 002E FEE8 0000 008C 8000 007F", + "17FF 05FF 002E 06F4 0AF0 FA24 0000 00BE", + "10FF 06FF 002E 062C 0AF0 014A 8000 00BF", + "10FF 06FF 002E 04CE 0AF0 003C 4000 00BF", + "06FF 05FF 002E 060E 0AF0 FEB6 8000 00BF", + "05FF 07FF 0009 062C 0FA0 FDB2 0000 003F", + "08FF 07FF 002E 062C 1130 FDB2 8000 00B5", + "0BFF 0AFF 0009 FA56 0BA4 0000 4000 003F", + "11FF 03FF 002E FEE8 0000 FC7C 8000 007F", + "0AFF 18FF 002E F593 0B18 FF69 E000 007F", + "05FF 04FF 0009 0A14 0AF0 0000 C000 003F", + "10FF 05FF 0009 05B4 0B7C FD8A 4000 009A", + "03FF 12FF 002E 0000 0000 FB28 4000 007F", + "0AFF 0EFF 002E FB5C 0E60 FF3B A0B6 01FD", + "0EFF 0DFF 0009 F6EE 1054 FD03 E000 009B", + "12FF 0FFF 002E 00EE 0000 FC94 0000 007F", + "19FF 0AFF 0009 FBDE 0AF0 FC76 E000 003F", + "0FFF 00FF 0009 0118 0000 008C 0000 0097", + "1AFF 02FF 002E F9E8 00C8 0000 4000 0154", + "01FF 00FF 0009 01A4 00C8 0000 C000 003F" + ], + "Paths": [ + { + "Points": [ + [ + -310, + 0, + -318 + ], + [ + -309, + 0, + -127 + ] + ] + }, + { + "Points": [ + [ + 1879, + 100, + -1883 + ], + [ + 1685, + 100, + -1881 + ] + ] + }, + { + "Points": [ + [ + 1536, + 200, + 2035 + ], + [ + 1536, + 200, + 1860 + ] + ] + }, + { + "Points": [ + [ + 1462, + 2800, + -1817 + ], + [ + 1658, + 2800, + -1815 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 4, Room 0", + "Start": "022F3000", + "End": "022FA2C0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "002C", + "000E", + "00A4", + "018E" + ], + "Actors": [ + "0040 0172 0140 0000 0000 C000 0000 0601", + "0040 0172 0104 0000 0000 C000 0000 0C00", + "0040 0172 00C8 0000 0000 C000 0000 0D00", + "000C 0000 0004 0220 0000 0000 0000 00FF", + "0008 006A 00F6 FF6F 0000 0000 0000 0284", + "005E FF7C 00A0 014C 0000 0000 0000 1128", + "005E FF9A 00C7 FF6F 0000 0000 0000 1128", + "005E 0003 00DB FF74 0000 0000 0000 1128", + "005E 0083 00A0 0149 0000 0000 0000 1128", + "0111 FE9B 0000 03BD 0000 0000 0000 560F", + "0111 0164 0001 03BF 0000 0000 0000 580F" + ] + }, + { + "File": { + "Name": "Scene 4, Room 1", + "Start": "022FB000", + "End": "023079E0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "002C", + "011C", + "00A4", + "000E", + "0024", + "015C" + ], + "Actors": [ + "012D 049C 0000 0086 0000 0000 0000 2AC1", + "012D 05C5 00F0 FAAA 0000 0000 0000 2AC1", + "012D 06A8 0000 FF2A 0000 0000 0000 2AC1", + "012D 06A9 0000 0399 0000 0000 0000 2AC1", + "008D 04E2 0000 0492 0000 0000 0000 00FF", + "008D 07FA 0000 0492 0000 8000 0000 00FF", + "0046 066B 0000 0431 0000 4000 0000 0001", + "0046 079A 0000 023B 0000 0000 0000 0001", + "0046 07AE 0000 FE67 0000 4000 0000 0001", + "00CF 0618 00C8 05DC 0000 8000 0000 0701", + "0043 073A 0000 FD1A 0000 0000 0000 FF01", + "0046 0514 0000 035B 0000 0000 0000 0000", + "0046 061E 0000 FC5F 0000 C000 0000 0000", + "0046 079A 0000 037B 0000 C000 0000 0000", + "005E 05EF 00F0 FA37 0000 0000 0000 10A9", + "005E 0864 016E FCBA 0000 0000 0000 10A9", + "005E 0631 00C8 0514 0000 0000 0000 106A", + "0111 066E 0068 FB14 0000 0000 0000 4009", + "0111 08B2 0190 FCD7 0000 0000 0000 420F", + "0111 0662 00C8 05C3 0000 0000 0000 440F" + ] + }, + { + "File": { + "Name": "Scene 4, Room 2", + "Start": "02308000", + "End": "02317FD0", + "RemapStart": "2307B30" + }, + "Id": 2, + "Objects": [ + "002C", + "000E", + "00A4", + "0170", + "009D", + "00B0", + "011C", + "0190", + "00A8", + "0024", + "015C" + ], + "Actors": [ + "003B FC6A 0000 FFD5 0000 0000 0000 0006", + "012D FB35 008C FE16 0000 0000 0000 FFC0", + "0098 FA71 00C8 0000 0000 4000 0000 FFFF", + "0041 FC04 0BB8 0000 0000 4000 0000 000E", + "006F FAD5 00C8 0329 0000 8000 0000 0800", + "005E FAD8 00C8 0184 0000 4000 0000 10C8", + "005E FB35 00C8 FE16 0000 0000 0000 10C8", + "005E FB97 016D FD78 0000 0000 0000 10C8", + "0111 FA6E 00C8 FD39 0000 0000 0000 5A0E", + "0111 FA6F 00C8 FD6C 0000 0000 0000 5C0A", + "01A0 FA4F 00C8 FDEA 0000 4000 0000 FFFF", + "01A0 FA4F 00C8 FE5F 0000 4000 0000 FFFF", + "01A0 FB45 012C FCF9 0000 0000 0000 FFFF", + "01A0 FB4B 00C8 02C5 0000 4000 0000 FFFF", + "01A0 FB4B 00C8 0301 0000 4000 0000 FFFF", + "01A0 FB96 0190 FD72 0000 0000 0000 FFFF", + "000A FAF9 00C8 03C5 0000 4000 0000 5847" + ] + }, + { + "File": { + "Name": "Scene 4, Room 3", + "Start": "02318000", + "End": "0231A4E0", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "002C", + "00A4", + "000E", + "009E" + ], + "Actors": [ + "0099 FE97 0050 FAEC 0000 0000 0000 FFFF", + "0049 FE97 0050 FAEC 0000 0000 0000 0FFF", + "000A FE97 0050 FAEC 0000 0000 0000 11A0" + ] + }, + { + "File": { + "Name": "Scene 4, Room 4", + "Start": "0231B000", + "End": "02322890", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "002C", + "000E", + "011C", + "00A4", + "001B", + "0170", + "0190", + "00A8", + "0024" + ], + "Actors": [ + "012D 0893 08D4 016A 0000 0000 0000 2BC1", + "012D 098A 0B6E 0004 4000 0000 0000 FFC2", + "012A 088E 0820 FFC7 0000 C000 0000 0401", + "0025 092F 09D8 FFE6 0000 0000 0000 FFFF", + "006F 0950 0820 0000 0000 4000 0000 0401", + "006F 0A10 0820 0000 0000 C000 0000 0401", + "0112 09D8 0802 0156 0000 0000 0002 18BF", + "0112 09D8 0802 0156 0000 0000 0002 193F", + "0112 09D8 0802 0156 0000 0000 0002 19BF", + "005E 0923 08E8 02BF 0000 0000 0000 106B", + "01A0 07EE 0820 0037 0000 0000 0000 FFFF", + "01A0 082A 0820 0037 0000 0000 0000 FFFF", + "01A0 0857 0820 FFC2 0000 4000 0000 FFFF", + "01A0 0866 0820 0037 0000 0000 0000 FFFF", + "01A0 088D 0820 FFC8 0000 0000 0000 FFFF", + "01A0 08C9 0820 FFC8 0000 0000 0000 FFFF", + "000A 09AA 0820 FFCE 0000 8000 0000 080B" + ] + }, + { + "File": { + "Name": "Scene 4, Room 5", + "Start": "02323000", + "End": "0232D230", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "002C", + "000E", + "011C", + "00A4", + "001B", + "0170", + "0190", + "00A8", + "0024" + ], + "Actors": [ + "012D 0617 0C80 FEA6 0000 0000 0000 2CC1", + "012D 07E4 0B7C FE22 0000 0000 0000 2CC1", + "012D 085C 0AB5 FB64 0000 0000 0000 2CC1", + "012D 08D4 0AB4 FB64 0000 0000 0000 2CC1", + "012D 098F 0B7C FE9F 0000 0000 0000 2CC1", + "012D 098F 0B7C 0154 0000 0000 0000 2CC1", + "0095 08E5 0B38 FB9B 0000 C000 0000 0000", + "012A 0895 0AF0 FBA2 0000 0000 0000 2C01", + "0025 06F1 0AF0 0231 0000 0000 0000 FFFF", + "0025 076C 0AF0 FCBD 0000 0000 0000 FFFF", + "0025 0885 0AF0 FFB9 0000 0000 0000 FFFF", + "0025 08D7 0AF0 0207 0000 0000 0000 FFFF", + "004E 062C 0C76 FCEA 0000 0000 0000 FFFF", + "00CF 0820 0B7C FD80 0000 4000 0000 0000", + "00CF 0708 0AF0 FB50 0000 0000 0000 2D02", + "00CF 07A8 0AF0 FB50 0000 0000 0000 2D02", + "00CF 0898 0AF0 FBF0 0000 0000 0000 2E02", + "006F 0887 0AF0 042D 0000 8000 0000 0302", + "006F 06E4 0B7C 04B9 0000 8000 0000 0A02", + "0112 0AC5 0B2E 0001 0000 0000 0006 1ABF", + "01D1 0761 0BC9 FE2A 0000 0000 0000 10FF", + "012A 084B 0AE6 0481 0000 0000 0000 0303", + "012A 06E2 0B7C 04CC 0000 0000 0000 0A03", + "012A 073F 0AF0 FA55 0000 0000 0000 3E20", + "01A0 06AE 0B7C 0538 0000 0000 0000 FFFF", + "01A0 06AE 0B7C 0508 0000 0000 0000 FFFF", + "01A0 0719 0B7C 0532 0000 4000 0000 FFFF", + "01A0 084C 0AF0 0482 0000 4000 0000 FFFF", + "01A0 08B6 0AF0 04AB 0000 0000 0000 FFFF", + "01A0 08B6 0AF0 047B 0000 0000 0000 FFFF", + "000A 08B4 0AF0 04A6 0000 4000 0000 5CC3", + "000A 0712 0B7C 0532 0000 4000 0000 5CE6", + "0110 06A3 0BB2 0534 0000 0000 0000 FFFF", + "0110 06A3 0BB2 050A 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 6", + "Start": "0232E000", + "End": "02334FA0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "002C", + "011C", + "00A4", + "000E", + "0024", + "015C" + ], + "Actors": [ + "012D 060D 0BA0 FED0 0000 0000 0000 FFC2", + "0111 06DC 0AF0 FF65 0000 0000 0000 7212", + "0111 071B 0AF0 FFAE 0000 0000 0000 7409", + "0111 06FD 0AF0 FF86 0000 0000 0000 760B" + ] + }, + { + "File": { + "Name": "Scene 4, Room 7", + "Start": "02335000", + "End": "023389E0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "002C", + "0025", + "011C" + ], + "Actors": [ + "012D 05B4 1098 FCA7 0000 0000 0000 FFC2", + "012D 062A 1250 FD3A 4000 0000 0000 FFC2", + "0038 053E 0FA0 FD5D 0000 0000 0000 FFFF", + "0038 05BE 1054 FD68 0000 8000 0000 FFFF", + "0112 0594 0FE8 FD39 0000 0000 0006 18BF", + "0112 0594 0FE8 FD39 0000 0000 0006 1AFF", + "0112 05B2 1038 FE8A 0000 0000 0006 18B5", + "0112 05B2 1038 FE8A 0000 0000 0006 1AF5", + "0173 05B1 103D FE8B 0000 0036 0001 3F00" + ] + }, + { + "File": { + "Name": "Scene 4, Room 8", + "Start": "02339000", + "End": "02342AC0", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "002C", + "011C", + "00A4", + "000E", + "0024", + "015C" + ], + "Actors": [ + "012D 05D4 1248 FD38 0000 0000 0000 3DC1", + "012D 073C 1248 FEC8 0000 2000 0000 3DC1", + "012D 05C9 122C 014F EE39 0000 F8E4 FF40", + "012A 07D3 1248 FE25 0000 2000 0000 3D01", + "0049 0792 1248 FE77 0000 0000 0000 1378", + "00FF 0792 1248 FE75 0000 2000 0000 FF00", + "0095 0792 1248 FE76 FF4A 2000 0000 8504", + "012A 04C5 1130 FDB1 0000 0000 0000 3800" + ] + }, + { + "File": { + "Name": "Scene 4, Room 9", + "Start": "02343000", + "End": "0234B770", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "002C", + "018E" + ], + "Actors": [ + "0008 FEC9 0BAE 0077 0000 0000 0000 03F4", + "0008 FEC9 0BAE 0105 0000 8000 0000 03F4", + "0008 0058 0BAE 0078 0000 0000 0000 03F4", + "0008 0059 0BAE 0106 0000 8000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 4, Room 10", + "Start": "0234C000", + "End": "023644A0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "002C", + "000E", + "00A4", + "0170", + "009D", + "00B0", + "011C", + "0190", + "00A8", + "0024", + "015C" + ], + "Actors": [ + "0041 FB3C 0E74 0000 0000 0000 0000 0110", + "0041 FC04 0BB8 0000 0000 4000 0000 000E", + "000C F8D5 0AF0 FD65 00B6 49F5 0000 00FF", + "000C F85A 0AF0 FB9D 0000 4000 0000 00FF", + "000C F8F8 0AF0 FCE3 FF4A 1DDE 0000 00FF", + "000C F770 0AF0 0210 FF4A 6000 0000 00FF", + "000C F7D7 0AF0 FCBD 0000 2000 0000 00FF", + "000C F83B 0AF0 FDDA 0000 3555 0000 00FF", + "000C FBF1 0AF0 FD85 0000 6000 0000 00FF", + "000C F9C0 0AF0 FDC2 0000 2000 0000 00FF", + "000C F892 0AF0 02A8 0000 0000 0000 00FF", + "000C F897 0AF0 01B8 0000 4000 0000 00FF", + "000C F897 0AF0 03E8 0000 0000 0000 00FF", + "000C F8E5 0AF0 02FB 0000 4000 0000 00FF", + "000C F8E6 0AF0 0399 0000 4000 0000 00FF", + "000C F835 0AF0 FC39 0000 2AAB 0000 00FF", + "000C F932 0AF0 02A8 0000 0000 0000 00FF", + "000C F984 0AF0 0392 0000 4000 0000 00FF", + "000C F987 0AF0 FE48 0000 4000 0000 00FF", + "000C F987 0AF0 01B8 0000 4000 0000 00FF", + "000C F987 0AF0 0258 0000 4000 0000 00FF", + "000C F98A 0AF0 0445 0000 4000 0000 00FF", + "000C F955 0AF0 FCE1 0000 DF4A 0000 00FF", + "000C FA23 0AF0 FEC3 0000 2000 0000 00FF", + "000C FA31 0AF0 FD4E 0000 2000 0000 00FF", + "000C FA38 0AF0 0129 0000 6000 0000 00FF", + "000C FA97 0AF0 FE59 0000 2000 0000 00FF", + "000C FAB2 0AF0 FC5F 0000 5555 0000 00FF", + "000C F769 0AF0 FD2F 0000 2000 0000 00FF", + "000C FAC5 0AF0 0227 0000 2000 0000 00FF", + "000C FB0C 0AF0 FDF1 0000 1777 0000 00FF", + "000C FB36 0AF0 0227 0000 6000 0000 00FF", + "000C FB86 0AF0 FD8A 0000 2000 0000 00FF", + "000C FB9B 0AF0 0343 FF4A 6000 0000 00FF", + "000C FCDA 0AF0 FDFE 0000 2000 0000 00FF", + "000C FC68 0AF0 FDFB 0000 6000 0000 00FF", + "000C F895 0AF0 FDA2 0000 F777 0000 00FF", + "000C F7D8 0AF0 FE12 0000 76C1 0000 00FF", + "000C F9B3 0AF0 FD53 0000 DF4A 0000 00FF", + "000C F757 0AF0 FDB0 0000 599A 0000 00FF", + "008D F702 0B18 FDFD 0000 6000 0000 0039", + "0095 FAEC 0EB8 004A 4000 6000 0000 8502", + "0112 F640 0BF7 FEB7 0000 0000 0006 1AFF", + "01D1 FCE6 0AF0 0003 0000 0000 0000 9837", + "01D6 FAC5 0B91 FF15 0000 0000 0000 1836", + "01D6 FC9E 0AF0 FD9A 0000 2000 0000 9836", + "0173 FCE8 0AF0 0004 0003 0000 0000 3FA5", + "0111 F757 0B18 FF5D 0000 0000 0000 4604", + "0111 F59F 0B18 FDB1 0000 0000 0000 4803", + "0111 F8C7 0AF0 FBA6 0000 0000 0000 4A03", + "0111 F7C2 0AF0 FD7A 0000 0000 0000 4C04", + "0111 F6F1 0AF0 0346 0000 0000 0000 4E12", + "0111 F713 0AF0 0323 0000 0000 0000 500B", + "012A F74F 0AF0 FC3A 0000 2000 0000 3900" + ] + }, + { + "File": { + "Name": "Scene 4, Room 11", + "Start": "02365000", + "End": "023687C0", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "002C", + "00A4", + "000E", + "011C", + "0024", + "015C", + "0154" + ], + "Actors": [ + "012D F82E 0B69 0062 0000 4000 0000 FFC0", + "012D F9E6 0B68 0066 0000 C000 0000 FFC0", + "012A F84A 0BA4 FF85 0000 4000 0000 1901", + "000C F976 0BA4 0000 0000 C000 0000 00FF", + "000C F976 0BA4 FF74 0000 C000 0000 00FF", + "000C F976 0BA4 FEE8 0000 C000 0000 00FF", + "000C F976 0BA4 008C 0000 C000 0000 00FF", + "000C F976 0BA4 0118 0000 C000 0000 00FF", + "008D F89C 0B54 0001 0000 C000 0000 00FF", + "00CF F9E6 0AF0 FFFD 0000 C000 0000 0B02", + "0095 FA35 0B1C FFFE C000 4000 0000 8508" + ] + }, + { + "File": { + "Name": "Scene 4, Room 12", + "Start": "02369000", + "End": "0236BB80", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "002C", + "0025", + "005D", + "000D", + "0085", + "00A4", + "005F" + ], + "Actors": [ + "0112 F64E 1035 0099 0000 0000 0006 1AFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 13", + "Start": "0236C000", + "End": "02378BE0", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "002C", + "00A4", + "000E", + "011C", + "0024", + "015C", + "0154" + ], + "Actors": [ + "012D F688 11E4 FFCF 0000 0000 0000 3CC1", + "012D F70D 1130 FF02 0000 A000 0000 3CC1", + "01C9 F8F6 120C 0237 0000 638E 0009 18FF", + "0041 F6DB 1144 FED4 0000 E000 0000 0211", + "0049 F77C 1248 017C 0000 4000 0000 117A", + "0008 F704 1293 017C 0000 4000 0000 03F5", + "0008 F77C 1293 0104 0000 4000 0000 03F5", + "0008 F77C 1293 01F4 0000 4000 0000 03F5", + "0008 F7F4 1293 017C 0000 4000 0000 03F5", + "012A F6AA 1130 FF00 0000 0000 0000 3C03", + "012A FA34 1130 012C 0000 2000 0000 3A00", + "000A F77C 1248 017C 0000 E000 0000 5845" + ] + }, + { + "File": { + "Name": "Scene 4, Room 14", + "Start": "02379000", + "End": "0237B260", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "002C", + "00A4", + "000E", + "0032" + ], + "Actors": [ + "0071 F8A4 1068 FC84 0000 A000 0000 0F00", + "0112 FAC9 0F5A FEA8 0000 0000 0006 1AFD", + "0002 F81B 1054 FC05 0000 0000 0000 FFFF", + "0002 F9A7 1018 FD8D 0000 0000 0000 0003", + "0173 FAC8 0F5F FEA9 0000 003E 0001 3F00" + ] + }, + { + "File": { + "Name": "Scene 4, Room 15", + "Start": "0237C000", + "End": "0237D1D0", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "002C", + "0032", + "000D" + ], + "Actors": [ + "0013 00CA 0040 FFFA 0000 4000 0000 0003", + "0183 0064 0000 FDD9 0000 0000 0000 FF40", + "0002 0066 0000 FDAA 0000 0000 0000 FFFF", + "0002 011B 0000 FEC0 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 16", + "Start": "0237E000", + "End": "02389970", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "002C", + "00A4", + "000E", + "011C", + "0170" + ], + "Actors": [ + "0112 020B 0B2F 00F6 0000 0000 0006 1AFF", + "005E 04C4 0D2A FFCE E38E 4000 0000 03FC", + "005E 035E 0B59 FF52 0000 0000 0000 03FC", + "005E 025C 0B59 FF3E 0000 0000 0000 03FC", + "005E 04C4 0CDA FFCE E38E 4000 0000 105F", + "0111 05D5 0AF0 0182 0000 0000 0000 5209", + "0111 05A5 0AF0 01BD 0000 0000 0000 5409", + "012A 04AF 0AF0 FF64 0000 2000 0000 3C20", + "01A0 04BA 0B7C 00A3 0000 E000 0000 FFFF", + "01A0 03E7 0ADC FE6E 0000 4000 0000 FFFF", + "01A0 0581 0AF0 FB68 0000 0000 0000 FFFF", + "01A0 0180 0B7C 015F 0000 4000 0000 FFFF", + "01A0 057F 0B18 FD0C 0000 4000 0000 FFFF", + "0110 04F3 0B7C 00C8 0000 2000 0000 FFFF", + "0110 04BA 0BB3 00A3 0000 1E94 0000 FFFF", + "0110 02AD 0ADC 00B7 0000 0000 0000 FFFF", + "0110 057D 0AF0 FC31 0000 0000 0000 FFFF", + "0110 01CC 0B7C 0172 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 17", + "Start": "0238A000", + "End": "02393140", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "002C", + "00C9", + "000E", + "00D4", + "00F2" + ], + "Actors": [ + "011B FEE8 0000 FDBC 0000 0000 0000 12A9", + "012A FEE8 0000 FDBC 0000 0000 0000 0901", + "00DD FEE6 0082 FF70 0000 0000 0000 FFFF", + "006F FEE8 0000 FE20 0000 8000 0000 0900", + "006F FEED 0000 FEE8 0000 0000 0000 0900", + "01AE FECA 0000 FEC2 0000 0000 0000 2403", + "0008 FE9D 0032 FDBC 0000 0000 0000 03F4", + "0008 FE9D 0032 FF4C 0000 0000 0000 03F4", + "0008 FF33 0032 FDBC 0000 0000 0000 03F4", + "0008 FF33 0032 FF4C 0000 0000 0000 03F4", + "000A FF24 0000 FF24 0000 4000 0000 7542", + "000A FF10 0000 FE8E 0000 0000 0000 082C" + ] + }, + { + "File": { + "Name": "Scene 4, Room 18", + "Start": "02394000", + "End": "02397B80", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "002C", + "005F", + "0106", + "016C" + ], + "Actors": [ + "0113 0152 0014 FA54 0000 0000 0000 FF01", + "006B 00FA FFF8 FAF0 0000 0000 0000 FFFF", + "006B 01AE FFF8 FAF0 0000 0000 0000 FFFF", + "006B 0154 FFF8 FB40 0000 0000 0000 0007", + "006B 01AE FFF8 FB90 0000 0000 0000 000D", + "006B 00FA FFF8 FB90 0000 0000 0000 0011", + "0169 0151 0014 FA3A 0000 C000 0000 0001", + "0183 0153 0014 F9E5 0000 0000 0000 FF40", + "0111 00BB 0014 FA57 0000 0000 0000 5E12", + "0111 00BC 0014 FA16 0000 0000 0000 6004", + "0111 01E7 0014 FA56 0000 0000 0000 6212", + "0111 01E6 0014 FA15 0000 0000 0000 6404", + "0111 0026 0000 FB65 0000 0000 0000 6604", + "0111 002A 0000 FAEE 0000 0000 0000 6804", + "0111 0208 0000 FC51 0000 0000 0000 6A12", + "0111 0023 0000 FC4E 0000 0000 0000 6C12" + ] + }, + { + "File": { + "Name": "Scene 4, Room 19", + "Start": "02398000", + "End": "0239C1E0", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "002C", + "00A4", + "005F", + "000E", + "011C" + ], + "Actors": [ + "006B 0442 00E8 F8DA 0000 0000 0000 FFFF", + "006B 0442 00E8 F98E 0000 0000 0000 0003", + "006B 0492 00E8 F934 0000 0000 0000 0007", + "006B 04E2 00E8 F8DA 0000 0000 0000 0009", + "006B 04E2 00E8 F98E 0000 0000 0000 000D", + "006B 0532 00E8 F934 0000 0000 0000 0011", + "006B 0582 00E8 F8DA 0000 0000 0000 0015", + "006B 0582 00E8 F98E 0000 0000 0000 0019", + "008D 03C6 00A0 F933 0000 4000 0000 00FF", + "0112 032E 0138 F931 0000 0000 0006 1AFE", + "0112 0330 0136 F933 0000 0000 0001 1AFE", + "005E 04E8 00F0 F935 0000 0000 0000 2400", + "005E 036E 0104 F95D 0000 0000 0000 2400", + "0111 034D 0104 F9C9 0000 0000 0000 6E12", + "0111 0385 0104 F9C7 0000 0000 0000 700F", + "000A 0358 0104 F8D8 0000 C000 0000 27E4" + ] + }, + { + "File": { + "Name": "Scene 4, Room 20", + "Start": "0239D000", + "End": "023A3D10", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "002C", + "000E", + "00A4", + "00C9", + "0024", + "015C" + ], + "Actors": [ + "012A 06F5 0064 F8BE 0000 C000 0000 0101", + "006F 0730 0064 F8C4 0000 C000 0000 0100", + "0095 07E7 0098 F8B8 0000 C000 0000 8501", + "01AE 0757 0064 F8A5 0000 C000 0000 0423", + "0008 06CC 0098 F871 0000 C000 0000 03F5", + "0008 06CC 0098 F907 0000 C000 0000 03F5" + ] + }, + { + "File": { + "Name": "Scene 4, Room 21", + "Start": "023A4000", + "End": "023AC4C0", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "002C", + "00A4", + "00B7" + ], + "Actors": [ + "0043 0CEE 0078 0000 0000 0000 0000 2F00", + "0049 0CEE 0078 0000 0000 0000 0000 3FFF", + "0015 0D94 0280 FEB5 0000 0000 0000 2F03", + "0015 0CEB 01B8 00B4 0000 0000 0000 3003", + "0015 0DAE 0280 0140 0000 4000 0000 3403", + "005E 0CEB 01B8 FF57 0000 0000 0000 2400" + ] + }, + { + "File": { + "Name": "Scene 4, Room 22", + "Start": "023AD000", + "End": "023B3B00", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "002C", + "000E", + "00A4", + "00C9", + "00D4" + ], + "Actors": [ + "006F 0616 00C8 07D0 0000 8000 0000 0200", + "01AE 0600 00C8 07F3 0000 8000 0000 0843", + "0008 0663 00FA 076C 0000 8000 0000 03F5", + "005E 05C9 00C4 076D 0000 0000 0000 1042", + "000A 0640 00C8 0852 0000 4000 0000 5841" + ] + }, + { + "File": { + "Name": "Scene 4, Room 23", + "Start": "023B4000", + "End": "023BAD20", + "RemapStart": null + }, + "Id": 23, + "Objects": [ + "002C", + "0025", + "005D", + "000D", + "0085", + "00A4", + "005F", + "000E", + "00C9" + ], + "Actors": [ + "006F 05DC 0AF0 F900 0000 4000 0000 0500", + "01AE 05B6 0AF0 F8E7 0000 4000 0000 1463", + "0008 0640 0B24 F8AD 0000 4000 0000 03F5", + "0008 0640 0B24 F943 0000 4000 0000 03F5", + "012A 0640 0AF0 F8F8 0000 4000 0000 0500", + "000A 0550 0AF0 F8C6 0000 8000 0000 5848" + ] + }, + { + "File": { + "Name": "Scene 4, Room 24", + "Start": "023BB000", + "End": "023C0540", + "RemapStart": null + }, + "Id": 24, + "Objects": [ + "002C", + "009E", + "00AA" + ], + "Actors": [ + "0099 F490 0B68 008B 0000 0000 0000 FFFF", + "0047 F490 0B18 008B 0000 4000 0000 FFFF", + "0049 F490 0B68 008B 0000 4000 0000 0FFF", + "0015 F48F 0B18 0089 0000 0000 0000 1C11" + ] + }, + { + "File": { + "Name": "Scene 4, Room 25", + "Start": "023C1000", + "End": "023C7AE0", + "RemapStart": null + }, + "Id": 25, + "Objects": [ + "002C", + "0024", + "015C", + "001B" + ], + "Actors": [ + "0025 FCC8 0AF0 FB8A 0000 E000 0000 FFFF", + "0095 FD8E 0B36 FAC6 0000 E000 0000 8510", + "0008 FC8E 0B23 FB61 0000 2000 0000 03F5", + "0008 FCF3 0B27 FBC8 0000 A000 0000 03F5" + ] + }, + { + "File": { + "Name": "Scene 4, Room 26", + "Start": "023C8000", + "End": "023CE8A0", + "RemapStart": null + }, + "Id": 26, + "Objects": [ + "002C", + "000E", + "00A4", + "0170", + "009D", + "00B0", + "011C", + "0190", + "00A8", + "0024", + "015C" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 1054, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1055, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1056, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1057, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1058, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1059, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1060, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1061, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1062, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1063, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1291, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1292, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1293, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1294, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1295, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1296, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1297, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1298, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1301, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1302, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1303, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1304, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1305, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1306, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1309, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1310, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1311, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1312, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1313, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1314, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1315, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1316, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1317, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1318, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1319, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1320, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1321, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1322, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1325, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1326, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1329, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1330, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1331, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1332, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1335, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1336, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1337, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1338, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1339, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1340, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1341, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1342, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1343, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1344, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1345, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1346, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1347, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1348, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1349, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1350, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1351, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1352, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1353, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1354, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1355, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1356, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1357, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1358, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1359, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1360, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1361, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1362, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1363, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1364, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1365, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1366, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1367, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1368, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1369, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1374, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1375, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1376, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1377, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1378, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1379, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1380, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1381, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1382, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1383, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1384, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1385, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1386, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1387, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1388, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1393, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1394, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1395, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1396, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1397, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1398, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1401, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1402, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1403, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1404, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1405, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1406, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1407, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1408, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1417, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1418, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1419, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1420, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1421, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1422, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1425, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1426, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1427, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1428, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1433, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1434, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1435, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1436, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1439, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1440, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1441, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1442, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1443, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1444, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1445, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1446, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1447, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1448, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1449, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1452, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1453, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1454, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1455, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1456, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1459, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1460, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1461, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1462, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1463, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1464, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1466, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1467, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1468, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1469, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1470, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1471, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1472, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1473, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1474, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1475, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1476, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1477, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1478, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1479, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1480, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1481, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1482, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1483, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1491, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1492, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1493, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1494, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1496, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1497, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1501, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1502, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1503, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1504, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1505, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1506, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1508, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1509, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1512, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1513, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1523, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1525, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1526, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1527, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1528, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1529, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1530, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1531, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1532, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1533, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1534, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1535, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1536, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1537, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1538, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1539, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1540, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1541, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1542, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1543, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1544, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1545, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1546, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1547, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1551, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1554, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1555, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1556, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1557, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1558, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1559, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1560, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1561, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1562, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1563, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1564, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1565, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1568, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1570, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1571, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1572, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1573, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1574, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1575, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1576, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1577, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1578, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1579, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1580, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1581, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1582, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1583, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1584, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1585, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1586, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1587, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1588, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1589, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1592, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1593, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1594, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1595, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1596, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1597, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1598, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1599, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1600, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1601, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1604, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1605, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1606, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1607, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1608, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1609, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1610, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1611, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1618, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1619, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1620, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1621, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1622, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1623, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1624, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1625, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1626, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1627, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1628, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1631, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1632, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1641, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1642, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1643, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1644, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1647, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1648, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1649, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1652, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1653, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1654, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1655, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1656, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1659, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1660, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1661, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1662, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1663, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1664, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1671, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1672, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1675, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1676, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1677, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1678, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1679, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1681, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1694, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1695, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1699, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1700, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1701, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1702, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1703, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1704, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1705, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1706, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1707, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1708, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1709, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1710, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1711, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1712, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1713, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1714, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1715, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1717, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1725, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1733, + "Type": 44, + "Flags": 0 + }, + { + "Id": 1739, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1740, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1741, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1742, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1743, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1746, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1747, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1748, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1749, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1752, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1753, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1765, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1766, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1773, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1774, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1781, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1785, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1786, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1795, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1796, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1799, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1800, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1801, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1806, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1807, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1810, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1811, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1919, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1968, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2156, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2157, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2158, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2159, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2315, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2316, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2324, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2325, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2326, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2327, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2328, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2329, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2330, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2331, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2332, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2333, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2334, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2335, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2336, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2337, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2338, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2339, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2340, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2341, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2342, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2343, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2344, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2345, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2346, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2347, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2348, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2349, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2350, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2351, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2352, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2353, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2354, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2355, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2356, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2371, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2372, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2373, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2378, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2382, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2383, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2384, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2385, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2386, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2391, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2392, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2393, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2394, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2395, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2396, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2399, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2401, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2405, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2433, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2434, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2438, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2610, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2611, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2612, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2613, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2614, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2615, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2616, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2730, + "Type": 49, + "Flags": 0 + }, + { + "Id": 2731, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3498, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3499, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3500, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3744, + "Type": 51, + "Flags": 0 + }, + { + "Id": 3767, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3768, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3769, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3770, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3771, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3772, + "Type": 50, + "Flags": 1 + }, + { + "Id": 4187, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4188, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4189, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4190, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4191, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4192, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4193, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4194, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4195, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4196, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4197, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4198, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4199, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4200, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4213, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4214, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4215, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4216, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4217, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4218, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4223, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4224, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4225, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4226, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4227, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4228, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4229, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4230, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4241, + "Type": 34, + "Flags": 0 + }, + { + "Id": 4242, + "Type": 34, + "Flags": 0 + }, + { + "Id": 4243, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4244, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4245, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4246, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4247, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4249, + "Type": 34, + "Flags": 0 + }, + { + "Id": 4264, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4265, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4266, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4276, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4277, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4278, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4279, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4280, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4281, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4282, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4283, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4284, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4285, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4291, + "Type": 56, + "Flags": 0 + }, + { + "Id": 4356, + "Type": 57, + "Flags": 0 + }, + { + "Id": 4357, + "Type": 57, + "Flags": 0 + }, + { + "Id": 4374, + "Type": 58, + "Flags": 0 + }, + { + "Id": 4375, + "Type": 58, + "Flags": 0 + }, + { + "Id": 4376, + "Type": 59, + "Flags": 0 + }, + { + "Id": 4377, + "Type": 59, + "Flags": 0 + }, + { + "Id": 4380, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4381, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4382, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4383, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4384, + "Type": 61, + "Flags": 1 + }, + { + "Id": 4385, + "Type": 61, + "Flags": 1 + }, + { + "Id": 4386, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4387, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4388, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4389, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4390, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4391, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4392, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4393, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4394, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4395, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4396, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4397, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4398, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4399, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4404, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4405, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4408, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4409, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4410, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4411, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4414, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4415, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4643, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4644, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4652, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4653, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4654, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4655, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4656, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4657, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4658, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4659, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4660, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4661, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4709, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4710, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4711, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4712, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4713, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4714, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4715, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4716, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4717, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4718, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4719, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4720, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4721, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4722, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4723, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4724, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4725, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4726, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4727, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4728, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4737, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4738, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4853, + "Type": 66, + "Flags": 0 + }, + { + "Id": 4854, + "Type": 66, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 34, + "High": 5, + "Low": 20480 + }, + { + "Id": 35, + "High": 2146309, + "Low": 2050 + }, + { + "Id": 36, + "High": 2146306, + "Low": 2050 + }, + { + "Id": 37, + "High": 49154, + "Low": 20482 + }, + { + "Id": 38, + "High": 49154, + "Low": 2050 + }, + { + "Id": 39, + "High": 604028933, + "Low": 2050 + }, + { + "Id": 40, + "High": 2146306, + "Low": 20482 + }, + { + "Id": 41, + "High": 402653189, + "Low": 20482 + }, + { + "Id": 42, + "High": 2, + "Low": 40962 + }, + { + "Id": 43, + "High": 5, + "Low": 40962 + }, + { + "Id": 44, + "High": 4, + "Low": 40962 + }, + { + "Id": 45, + "High": 4, + "Low": 30736 + }, + { + "Id": 46, + "High": 4, + "Low": 20480 + }, + { + "Id": 47, + "High": 606126085, + "Low": 20482 + }, + { + "Id": 48, + "High": 606126082, + "Low": 20482 + }, + { + "Id": 49, + "High": 1, + "Low": 2050 + }, + { + "Id": 50, + "High": 6, + "Low": 20482 + }, + { + "Id": 51, + "High": 4, + "Low": 30727 + }, + { + "Id": 52, + "High": 604028931, + "Low": 20482 + }, + { + "Id": 53, + "High": 5, + "Low": 20496 + }, + { + "Id": 54, + "High": 2, + "Low": 151554 + }, + { + "Id": 55, + "High": 49154, + "Low": 12290 + }, + { + "Id": 56, + "High": 2, + "Low": 20480 + }, + { + "Id": 57, + "High": 5, + "Low": 20506 + }, + { + "Id": 58, + "High": 5, + "Low": 20490 + }, + { + "Id": 59, + "High": 24581, + "Low": 20482 + }, + { + "Id": 60, + "High": 2, + "Low": 143362 + }, + { + "Id": 61, + "High": 402653186, + "Low": 20482 + }, + { + "Id": 62, + "High": 8388610, + "Low": 151554 + }, + { + "Id": 63, + "High": 8388610, + "Low": 143362 + }, + { + "Id": 64, + "High": 4, + "Low": 151554 + }, + { + "Id": 65, + "High": 604028931, + "Low": 2050 + }, + { + "Id": 66, + "High": 517, + "Low": 2082 + } + ], + "Cams": [ + { + "Data": 1835011, + "PositionIndex": 0 + }, + { + "Data": 1441795, + "PositionIndex": 1 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 24, + "y": -40 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 3, + "x": 75, + "y": -47 + }, + { + "Flag": 6, + "x": 72, + "y": -51 + }, + { + "Flag": 8, + "x": 65, + "y": -12 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 78, + "y": -35 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 1, + "x": 67, + "y": -58 + }, + { + "Flag": 2, + "x": 48, + "y": -30 + }, + { + "Flag": 4, + "x": 63, + "y": -14 + }, + { + "Flag": 7, + "x": 36, + "y": -45 + }, + { + "Flag": 12, + "x": 47, + "y": -26 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 26, + "y": -34 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 53, + "y": 70 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 40, + "y": 47 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 57, + "y": 48 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 3, + "x": 67, + "y": 73 + }, + { + "Flag": 6, + "x": 58, + "y": 76 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 78, + "y": 62 + }, + { + "Flag": 12, + "x": 77, + "y": 58 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 4, + "x": 60, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 72, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 8, + "x": 66, + "y": 57 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 51, + "y": 61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 5", + "Start": "025B8000", + "End": "025CDCF0", + "RemapStart": null + }, + "Id": 5, + "TActors": [ + "00FF 11FF 0023 0294 0000 0000 0000 01BF", + "04FF 00FF 0023 0294 01CC FE98 0000 01BF", + "00FF 14FF 0023 0294 030C 0000 0000 01BF", + "00FF 03FF 0023 FE98 0000 026C C000 01BF", + "14FF 00FF 0023 0000 01CC 02BC C000 01BF", + "02FF 01FF 0023 FF4C FE0C 00A0 8000 01BF", + "15FF 08FF 0023 F9E8 0104 F6FA 0000 01BF", + "09FF 00FF 0023 FB8C FEFC FE52 0000 01BF", + "05FF 00FF 0009 FCB8 030C FF4C 4000 0095", + "0CFF 00FF 002E FF4C 0000 F902 0000 003F", + "05FF 06FF 002E F510 02F8 FF4C C000 007F", + "0CFF 0EFF 002E FF4C 0000 F39E 8000 0068", + "0EFF 0FFF 002E FD58 0078 F1AA C000 01E6", + "13FF 11FF 002E 0492 030C 00B4 C000 01F7", + "01FF 00FF 002E FF4C 0050 0014 0000 003F", + "01FF 00FF 002E FF4C 01CC FE84 8000 003F", + "0BFF 00FF 0009 FF4C 0334 FB28 0000 003F", + "0AFF 00FF 002E FCB8 01CC FF4C 4000 00BB", + "06FF 0DFF 002E F3D0 0424 F984 8000 007F", + "07FF 0DFF 002E F3D0 0424 F18C 0000 007F", + "09FF 08FF 002E FB8C 003C F93E 8000 009B", + "0CFF 10FF 002E FB00 006C F57E 8000 007F", + "0FFF 0CFF 0009 FC90 0078 F57E 0000 0082", + "12FF 11FF 002E 0492 0000 00B4 C000 00BE", + "0AFF 00FF 002E FCB8 035C 0122 4000 00BF", + "16FF 0BFF 002E FF4C 0406 F7F4 0000 0154", + "07FF 15FF 0023 F3D0 0334 EF84 0000 00BF" + ], + "Paths": [ + { + "Points": [ + [ + -2561, + 621, + -186 + ], + [ + -2058, + 121, + -204 + ], + [ + -1797, + 114, + -186 + ], + [ + -1307, + 725, + -186 + ] + ] + }, + { + "Points": [ + [ + -1554, + 428, + -180 + ], + [ + -1784, + 145, + -180 + ], + [ + -1554, + 428, + -180 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 5, Room 0", + "Start": "025CE000", + "End": "025E3C80", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0190", + "00A8" + ], + "Actors": [ + "012D FF4D 0087 FBBA 0000 8000 0000 FFC2", + "012D FDA2 03A6 0165 0000 8000 0000 FFC2", + "012D FDFF 01B7 FF49 0000 C000 0000 FFC2", + "012D 0099 02F7 FF46 0000 4000 0000 FFC2", + "012D 0183 02F7 FF4D 0000 C000 0000 FFC2", + "012D FBE2 00BB FF24 4000 0000 0000 FFC2", + "0064 FCF4 030C FF4C 0000 0000 0000 1FFF", + "0064 FF50 0334 FBE4 0000 0000 0000 3FFF", + "0065 FF4C 02FD FF4C 0000 0000 0000 FF00", + "0185 FD4E 03A0 0156 0000 8000 0000 857F", + "012D FF9C 0000 01CD 0000 0000 0000 0EC1", + "012D FEFB 0000 FC68 0000 0000 0000 0EC1", + "01BB FF4D 0000 0204 0000 8000 0000 0FCE", + "01BB FF4D FF4C FBC4 0000 0000 0000 0FCE", + "01BB FCA2 003C FF49 0000 4000 0000 0FCE", + "012A FC65 003C FF4C 0000 0000 0000 0E00", + "0064 FF4C 030C 0064 0000 0000 0000 0FD9", + "012E FD4E 035C 0156 0000 8000 0000 1C9E", + "012D 003C 0000 FF4A 0000 0000 0000 1FC1", + "01BB FF4D 01CC 01E1 0000 8000 0000 00F9", + "012A FF27 01CC 019F 0000 0000 0000 3900", + "01BB 01E3 030C FF4D 0000 C000 0000 00FA", + "012A 0206 030C FF71 0000 0000 0000 3A00", + "012A FE2C 01CC FF49 0000 0000 0000 3B20" + ] + }, + { + "File": { + "Name": "Scene 5, Room 1", + "Start": "025E4000", + "End": "025EE160", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0190", + "00A8", + "0170" + ], + "Actors": [ + "0064 FF4C 030C FFC4 0000 0000 0000 2FFF", + "0065 FF4C 02FD FF4C 0000 0000 0000 FF00", + "0185 FED4 01B0 FFF9 0000 8000 0000 857F", + "01A0 FF2E 02BC FEB0 0000 0000 0000 FFFF", + "01A0 FF6A 02BB FEB0 0000 0000 0000 FFFF", + "01D6 FF4B 0325 FF4D 0000 0000 0000 1106", + "01D6 FF4B 03D4 FF4D 0000 0000 0000 9106", + "005E FE8E 03CF FE8E 2000 2000 0000 110A", + "005E 000A 03CF FE8E 2000 E000 0000 110A", + "005E FE8E 03CF 000A 2000 6000 0000 110A", + "005E 000A 03CF 000A 2000 A000 0000 110A", + "01BB FF4D FFBF FF9E 4000 0000 0000 1FCA", + "012E FED4 017C FFF9 0000 8000 0000 1C9D" + ] + }, + { + "File": { + "Name": "Scene 5, Room 2", + "Start": "025EF000", + "End": "025F4B90", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0170", + "011D", + "00E5" + ], + "Actors": [ + "012D 0206 FFCB 0257 4000 0000 0000 FFC2", + "00EC 01AF FEBD 00FB 0000 0000 0000 0000", + "012C 01A2 FE48 013D 4000 0000 0000 FFFC", + "012C 00B3 FE48 013E 0000 C000 4000 FFFC", + "012C 0101 FE48 01E0 0000 0000 4000 FFFC", + "012C 0012 FE07 00F0 0000 8000 4000 FFFC", + "012C 0101 FE48 0168 0000 0000 4000 FFFC", + "012C 003B FE48 013E 0000 C000 4000 FFFC", + "012C 0036 FDF4 00F0 0000 8000 4000 FFFC", + "01A0 0019 FE0C 0246 0000 4000 0000 FFFF", + "01A0 0019 FE0C 020A 0000 4000 0000 FFFF", + "01A0 005B FE0C 027C 0000 0000 0000 FFFF", + "01A0 0066 FE0C 00CC 0000 0000 0000 FFFF", + "01A0 0097 FE0C 027C 0000 0000 0000 FFFF", + "01A0 001F FE0C 027C 0000 0000 0000 FFFF", + "01A0 00A2 FE0C 00CC 0000 0000 0000 FFFF", + "01A0 00D7 FE0C 016E 0000 4000 0000 FFFF", + "01A0 00D7 FE0C 01AA 0000 4000 0000 FFFF", + "01A0 01C7 FE0C 016D 0000 4000 0000 FFFF", + "01A0 01C7 FE0C 01A9 0000 4000 0000 FFFF", + "01A0 00DE FE0C 00CC 0000 0000 0000 FFFF", + "01A0 00D7 FE0C 01E6 0000 4000 0000 FFFF", + "01A0 012B FE0C 01E5 0000 4000 0000 FFFF", + "000A 0294 FF92 0258 0000 4000 0023 8846", + "0112 02A4 FF5D 0257 0000 0000 0006 18A3", + "012A 00DC FDFD 00C9 0000 0000 0000 3903", + "01BB 016A FE95 00F5 C000 C000 0000 1FF9", + "012A 0011 FDFD 00C9 0000 0000 0000 3A03", + "01BB 01AC FE95 0293 C000 0000 0000 1FFA" + ] + }, + { + "File": { + "Name": "Scene 5, Room 3", + "Start": "025F5000", + "End": "025FB710", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0059", + "00A4", + "0024", + "011C", + "0170", + "0154", + "015C", + "0032" + ], + "Actors": [ + "012D FBB6 0000 035C 0000 0000 0000 FFC0", + "012D FE27 0064 035A 0000 C000 0000 FFC2", + "012D FAE5 00C6 035D 0000 4000 0000 FFC2", + "0112 F6F5 018B 035E 0000 0000 0007 1AFF", + "0065 003C 02FD 032A 0000 0000 0000 FF00", + "0002 F819 012C 02FD 0000 0000 0000 0003", + "0002 F819 012C 03C6 0000 0000 0000 0003", + "01A0 F9DD 0000 02E8 0000 0000 0000 FFFF", + "01A0 F9DD 0000 03CF 0000 0000 0000 FFFF", + "01A0 F9DD 0000 0318 0000 0000 0000 FFFF", + "01A0 FA19 0000 03CF 0000 0000 0000 FFFF", + "01A0 FC21 0000 03D0 0000 0000 0000 FFFF", + "01A0 FC1E 0000 02E8 0000 0000 0000 FFFF", + "01A0 F72C 0140 02E8 0000 0000 0000 FFFF", + "01A0 F768 0140 02E7 0000 0000 0000 FFFF", + "01A0 F779 0140 03D1 0000 0000 0000 FFFF", + "01C9 F8DE 012C 0363 0000 4000 0005 18CB", + "0095 F752 0208 035F 8000 0000 0000 8610", + "0065 F95C 007D 032A 0000 0000 0000 1A02", + "0111 F6F6 0140 0302 0000 4000 0000 4204", + "0111 F6F6 0140 0328 0000 4000 0000 4804", + "005E FC4F 01AD 035C 0000 0000 2000 10E7", + "005E FC4F 0173 0379 0000 0000 2000 10E7", + "005E FC4F 0173 033A 0000 0000 2000 10E7", + "01BB F7AA 0140 035B 0000 4000 0000 1FE7", + "0111 F6F7 0140 03B0 0000 4000 0000 5209", + "0111 F6F7 0140 0389 0000 4000 0000 6A09" + ] + }, + { + "File": { + "Name": "Scene 5, Room 4", + "Start": "025FC000", + "End": "02601FE0", + "RemapStart": "25FB8D0" + }, + "Id": 4, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0170" + ], + "Actors": [ + "005E 0483 0320 FCC7 0000 0000 0000 2400", + "0065 0514 02FD FF4C 0000 4000 0000 FF00", + "01A0 04B5 0320 FBF4 0000 0000 0000 FFFF", + "01A0 04F1 0320 FBF4 0000 0000 0000 FFFF", + "01A0 055E 0320 FBF4 0000 0000 0000 FFFF", + "01A0 0600 0320 FC66 0000 4000 0000 FFFF", + "01A0 0600 0320 FCCB 0000 4000 0000 FFFF", + "01A0 0600 0320 FD38 0000 4000 0000 FFFF", + "01A0 059A 0320 FBF4 0000 0000 0000 FFFF", + "0110 0504 0320 FD93 0000 0000 0000 FFFF", + "0110 0571 0320 FD93 0000 0000 0000 FFFF", + "0110 053D 0320 FD93 0000 0000 0000 FFFF", + "0110 05BE 0320 FD92 0000 0000 0000 FFFF", + "0111 04C6 0320 FD97 0000 0000 0000 4003", + "0111 0462 0320 FD97 0000 0000 0000 4E03", + "0111 0494 0320 FD97 0000 0000 0000 5003" + ] + }, + { + "File": { + "Name": "Scene 5, Room 5", + "Start": "02602000", + "End": "0260C5F0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "000D", + "0024", + "015C" + ], + "Actors": [ + "003B F87A 00DD 005E 0000 0000 0000 0000", + "012D FB2F 03B1 FF4C 4000 4000 0000 FFC2", + "0112 F5F8 0335 FE9E 0000 0000 0006 183F", + "0112 F5F3 0344 FE95 0000 0000 0006 193F", + "0112 F5F5 0339 FE9B 0000 0000 0006 1ABF", + "0173 F5F4 033A FFFE 0006 003E 001E 3F00", + "0064 F9EE 01A9 FF4C 0000 C000 0000 7180", + "012D F5FF 0259 FF4C 0000 0000 0000 3DC1", + "012D F5FF 01F5 FF4C 0000 0000 0000 3DC1", + "0112 F5F5 0336 0009 FF4A 0000 0006 1AFD", + "0112 F5F4 032D FFFE 0000 0000 0006 1AFD", + "0112 F5F2 033D FFF4 0000 0000 0006 1AFD", + "012D F701 00F4 FED2 0000 0000 0000 3EC1", + "012D F768 008B FE7B 0000 0000 0000 3EC1", + "012D F779 007B 001E 0000 0000 0000 3EC1", + "012D F6E0 0114 001A 0000 0000 0000 3EC1", + "012D F79F 0053 FF37 0000 0000 0000 3EC1", + "012D F69B 0158 FF8C 0000 0000 0000 3EC1", + "012A FB24 03E3 FF4C 0000 0000 4000 3E03" + ] + }, + { + "File": { + "Name": "Scene 5, Room 6", + "Start": "0260D000", + "End": "026182C0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0059", + "0125", + "011C", + "0032" + ], + "Actors": [ + "012D F502 0328 FF0A 0000 C000 0000 FFC2", + "0183 F42D 0424 FA20 0000 0000 0000 FF40", + "0002 F3D6 0230 FE82 0000 416C 0000 FFFF", + "0002 F375 0230 FE39 0000 416C 0000 FFFF", + "0002 F373 0230 FE9D 0000 416C 0000 FFFF", + "0183 F369 0424 FA23 0000 0000 0000 FF41", + "0183 F3A4 02F8 FDE4 0000 0000 0000 FF40", + "0111 F38C 0424 F9A4 0000 0000 0000 560E", + "0111 F410 0424 F9A6 0000 0000 0000 580E", + "0111 F254 0320 FD11 0000 0000 0000 5A0C", + "0111 F254 0320 FD52 0000 0000 0000 5C12", + "0111 F254 0320 FCD6 0000 0000 0000 6012", + "0064 F3E4 02AD FCBE 0000 C000 0000 5FC3", + "0064 F2CA 02AD FF4C 0000 4000 0000 5FC3", + "0064 F39B 0389 FC25 0000 0000 0000 5FC3", + "0187 F3D3 03FC FC11 0000 0000 0000 0FFF", + "0065 F3A6 0251 FDE4 0000 0000 0000 3203", + "0064 F1DC 02D5 FDE6 0000 0000 0000 5FF2" + ] + }, + { + "File": { + "Name": "Scene 5, Room 7", + "Start": "02619000", + "End": "0261E550", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0059", + "0125", + "013B", + "013A", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "011C", + "000E", + "0090", + "0190", + "00A8" + ], + "Actors": [ + "0112 F3D2 048B EF25 0000 0000 0006 18A5", + "01BB F3D0 041F EFAC C000 0000 0000 0FE5", + "0111 F400 0438 F048 0000 0000 0000 640A", + "0111 F39F 0438 F049 0000 0000 0000 6612" + ] + }, + { + "File": { + "Name": "Scene 5, Room 8", + "Start": "0261F000", + "End": "0262CCD0", + "RemapStart": "0261EF00" + }, + "Id": 8, + "Objects": [ + "0059", + "0170", + "011C", + "011D", + "00A4" + ], + "Actors": [ + "012D F802 00E3 F863 4000 0000 0000 FFC2", + "012D F983 FFCB F861 4000 0000 0000 FFC2", + "012D FB52 00CF F8C4 4000 0000 0000 FFC2", + "012D F9E8 00EE F793 0000 0000 0000 FFC2", + "0112 FA3A FF7C F8DD 0000 0000 0006 18BF", + "0112 F75D 0073 F864 0000 0000 0006 18BF", + "0112 FA39 FF7C F8C5 0000 0000 0006 1AFF", + "00D4 FA74 0032 F862 0000 0000 0000 00FF", + "01A0 F76C 003C F846 0000 4000 0000 FFFF", + "01A0 F76C 003C F882 0000 4000 0000 FFFF", + "01A0 FB7F 003C F87A 0000 0000 0000 FFFF", + "01A0 FBBC 003C F87A 0000 0000 0000 FFFF", + "01A0 F833 FF24 F84C 0000 4000 0000 FFFF", + "01A0 F833 FF24 F888 0000 4000 0000 FFFF", + "01A0 F90E FF24 F82A 0000 0000 0000 FFFF", + "01A0 F94A FF24 F82A 0000 0000 0000 FFFF", + "0110 F75E 006C F839 0000 0000 0000 FFFF", + "0110 F75E 006C F889 0000 0000 0000 FFFF", + "0110 F75E 006C F860 0000 0000 0000 FFFF", + "005E F8B6 0088 F805 1555 E000 0000 109B", + "005E F8B5 0088 F8C0 1555 A000 0000 109B" + ] + }, + { + "File": { + "Name": "Scene 5, Room 9", + "Start": "0262D000", + "End": "02634FE0", + "RemapStart": "262CD30" + }, + "Id": 9, + "Objects": [ + "0059", + "013A", + "011C", + "00A4", + "000E", + "0170" + ], + "Actors": [ + "012D FB8C 0027 FA68 0000 0000 0000 FFC2", + "01A0 FBD3 FEFC FA86 0000 0000 0000 FFFF", + "01A0 FB17 003C F9E1 0000 0000 0000 FFFF", + "01A0 FAEF FEFC FAEC 0000 4000 0000 FFFF", + "01A0 FC27 FEFC FACB 0000 4000 0000 FFFF", + "01A0 FAF7 FEFC FB4B 0000 0000 0000 FFFF", + "000A FB8B 003C FC05 0000 0000 0000 27E5", + "005E FB4F 003C FC03 0000 0000 0000 1093", + "005E FBC8 003C FC03 0000 0000 0000 1093", + "01BB FB8C 003C FBB4 0000 8000 0000 0FD3", + "01BB FB14 003C FBB4 0000 8000 0000 0FD3", + "01BB FC04 003C FBB4 0000 8000 0000 0FD3", + "01BB FB14 00B4 FBB4 0000 8000 0000 0FD3", + "01BB FB8C 00B4 FBB4 0000 8000 0000 0FD3", + "01BB FC04 00B4 FBB4 0000 8000 0000 0FD3", + "0111 FBF7 003C F9DF 0000 0000 0000 680E", + "012A FAE5 003C FA82 0000 0000 0000 3E03", + "015F FB8C FEDE FB0F 0000 0000 0000 0FBF" + ] + }, + { + "File": { + "Name": "Scene 5, Room 10", + "Start": "02635000", + "End": "0263AFB0", + "RemapStart": "2634E40" + }, + "Id": 10, + "Objects": [ + "0059", + "0170", + "011C", + "000E", + "0024", + "015C", + "001B" + ], + "Actors": [ + "0025 FC00 043C 0079 0000 0000 0000 FFFF", + "0112 FC02 0219 010D 0000 0000 0006 1B3F", + "0065 FC0E 02FD 001E 0000 0000 0000 FF00", + "01A0 FBB1 01CC FEC5 0000 0000 0000 FFFF", + "01A0 FB82 01CC FF73 0000 0000 0000 FFFF", + "01A0 FC4F 01CC FEC5 0000 0000 0000 FFFF", + "01A0 FB7B 01CC FF23 0000 4000 0000 FFFF", + "01A0 FB83 01CC 00AD 0000 0000 0000 FFFF", + "01A0 FB82 035C 0038 0000 0000 0000 FFFF", + "01A0 FC8C 035C 0041 0000 4000 0000 FFFF", + "01A0 FC84 01CC FFA5 0000 0000 0000 FFFF", + "0110 FB72 01CC 0061 0000 0000 0000 FFFF", + "0110 FC20 035C 017E 0000 0000 0000 FFFF", + "0095 FB7E 035C 003A 0000 4000 0000 8604", + "012D FC07 035C 0018 0000 0000 0000 24C1", + "012D FBFD 0190 00CB 0000 0000 0000 24C1", + "012A FC85 01B4 FFA7 0000 0000 0000 2403", + "0111 FC23 01CC 00FF 0000 0000 0000 7003", + "0111 FBFE 01CC 0101 0000 0000 0000 7203", + "0111 FBDA 01CC 0100 0000 0000 0000 7403" + ] + }, + { + "File": { + "Name": "Scene 5, Room 11", + "Start": "0263B000", + "End": "0263F9B0", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "00B0", + "0090", + "0085" + ], + "Actors": [ + "0112 FF99 0360 FB0F 0000 0000 0006 18BF", + "0112 FEFE 035F FB10 0000 0000 0006 1AFF", + "0080 FFA3 039C F97D 0000 C000 ED83 0F10", + "0080 FEE8 03DC F8FD 0000 C000 ED83 0F10", + "0080 FEF2 035B F9FD 0000 4000 127D 0F10", + "012D FEE7 0406 F81C 0000 0000 0000 3EC1", + "012D FFAE 0406 F81C 0000 0000 0000 3EC1", + "012D FEE8 0334 FB00 0000 0000 0000 3EC1", + "012D FFB0 0334 FB00 0000 0000 0000 3EC1", + "012A FF4E 04FB F7E3 4000 0000 0000 3E03" + ] + }, + { + "File": { + "Name": "Scene 5, Room 12", + "Start": "02640000", + "End": "02646D90", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0059", + "013B", + "011C", + "0154", + "00A4", + "0170", + "0024", + "015C" + ], + "Actors": [ + "012D FF4A 00CF F60A 4000 0000 0000 FFC2", + "012D FC1A 00F7 F740 4000 0000 0000 FFC2", + "012D FAFF 00EB F5F0 4000 0000 0000 FFC2", + "0160 FE0C FF60 F4CA 0000 0000 0000 0000", + "0160 008C FF60 F74A 0000 0000 0000 0000", + "01BB FE98 0064 F470 8000 0000 0000 0FFF", + "01BB FF10 0064 F470 8000 0000 0000 0FFF", + "01BB FF88 0064 F470 8000 0000 0000 0FFF", + "01BB 0000 0064 F470 8000 0000 0000 0FFF", + "01A0 FE7A 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FED1 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FFA9 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FFF9 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FE8D 0000 F7E3 0000 0000 0000 FFFF", + "01A0 FFF5 0000 F7E5 0000 0000 0000 FFFF", + "01A0 007E FF60 F64B 0000 0000 0000 FFFF", + "01A0 FF89 FF60 F64F 0000 0000 0000 FFFF", + "01A0 FF05 FF60 F555 0000 0000 0000 FFFF", + "01A0 000B FF60 F54F 0000 0000 0000 FFFF", + "01A0 FE0E FF60 F59B 0000 0000 0000 FFFF", + "01A0 FE39 FF60 F6A6 0000 0000 0000 FFFF", + "0095 FE76 0000 F3C8 0000 4000 0000 8608", + "01C9 FD46 003C F722 0000 0000 0005 18CC" + ] + }, + { + "File": { + "Name": "Scene 5, Room 13", + "Start": "02647000", + "End": "02647A00", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0059", + "0125", + "013B", + "013A", + "0020" + ], + "Actors": [ + "0136 F3D0 0410 F588 0000 4000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 5, Room 14", + "Start": "02648000", + "End": "0264EE60", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0059", + "011C", + "000E", + "0170", + "000C" + ], + "Actors": [ + "012D FE55 FFEB F1A6 0000 4000 0000 FFC2", + "0012 FF5A FF60 F34B 0000 C16C 0000 FFFF", + "0012 FF17 FED4 F1EE 0000 C0B6 0000 FFFF", + "0012 FF52 FED4 F179 0000 0000 0000 FFFF", + "0012 FF71 FED4 F1F1 0000 C0B6 0000 FFFF", + "0012 FFDA FF60 F332 0000 DA50 0000 FFFF", + "0012 FF41 FED4 F22E 0000 0000 0000 FFFF", + "0012 FF52 FEF8 F13B 0000 D3E9 0000 FFFF", + "01A0 0024 FEC0 F18C 0000 4000 0000 FFFF", + "01A0 FEF1 FED4 F10E 0000 0000 0000 FFFF", + "01A0 FE73 FF60 F116 0000 4000 0000 FFFF", + "01A0 001E FF60 F371 0000 0000 0000 FFFF", + "01A0 FFAB FED4 F27C 0000 4000 0000 FFFF", + "0065 FF4B FEDE F29A 0000 0000 0000 1804", + "0111 001C FF60 F117 0000 0000 0000 7604", + "0111 FFE4 FF60 F117 0000 0000 0000 7804" + ] + }, + { + "File": { + "Name": "Scene 5, Room 15", + "Start": "0264F000", + "End": "02656430", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "000E", + "00A4", + "0090" + ], + "Actors": [ + "0112 FC2D 0095 F3DA 0000 0000 0000 10FF", + "0112 FC94 0099 F2EF 0000 0000 0000 11FF", + "005E FD53 00C8 F366 0000 0000 2000 1126", + "005E FBCD 00C8 F366 0000 0000 E000 1126", + "005E FC5A 0078 F492 0000 0000 0000 1126", + "005E FC5C 0078 F232 0000 0000 0000 1126", + "012A FD34 0078 F46E 0000 0000 0000 3803", + "015F FC2C FF10 F3E0 0000 0000 0000 0E3F", + "015F FC90 FF10 F2F0 0000 0000 0000 0E3F", + "015F FCCC FF10 F390 0000 0000 0000 0E3F" + ] + }, + { + "File": { + "Name": "Scene 5, Room 16", + "Start": "02657000", + "End": "0265AAD0", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "0059", + "000E", + "0032", + "0170", + "00AA" + ], + "Actors": [ + "0112 FAFA 00A5 F40C 0000 0000 0006 18BF", + "0002 FAFB 006C F456 0000 0000 0000 FFFF", + "01A0 FA64 006C F4C5 0000 4000 0000 FFFF", + "01A0 FA65 006C F489 0000 4000 0000 FFFF", + "01A0 FB9B 006C F492 0000 4000 0000 FFFF", + "01A0 FB9B 006C F4CE 0000 4000 0000 FFFF", + "01A0 FA64 006C F532 0000 4000 0000 FFFF", + "0015 FA60 006C F534 0000 0000 0000 0111", + "0111 FA77 006C F42F 0000 0000 0000 7A12", + "0111 FB82 006C F429 0000 0000 0000 7C0E" + ] + }, + { + "File": { + "Name": "Scene 5, Room 17", + "Start": "0265B000", + "End": "02663A20", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0059", + "000E", + "011C", + "00A4", + "00CA", + "0190", + "00A8" + ], + "Actors": [ + "01D1 03D4 0168 0083 0000 4000 0000 08FF", + "005E 03DA 0000 0062 0000 0000 0000 2400", + "0065 03E3 02FD 00B4 0000 0000 0000 FF00", + "0173 064C 0214 00B3 0000 0018 0001 3F00", + "0185 03E7 035B 0152 0000 8000 0000 853F", + "000A 0565 01CC 00BB 0000 4000 0017 B120", + "00D2 03CD 0000 00B4 0000 C000 0000 1004", + "0112 064E 020A 00B3 0000 0000 0006 18D7", + "012E 03E7 030C 0152 0000 8000 0000 1C9C", + "012D 041C 0190 00B5 0000 0000 0000 1FC1", + "012D 035C 0000 0104 0000 0000 0000 1FC1", + "012D 035C 0000 0063 0000 0000 0000 1FC1", + "012D 035C 030C 0106 0000 0000 0000 1FC1", + "0111 0463 0000 003E 0000 4000 0000 4A0E", + "0111 0463 0000 0125 0000 4000 0000 4C0E", + "005E 034A 0384 0017 1C72 2000 0000 1137", + "005E 047B 0384 0017 1C72 E000 0000 1137", + "005E 034B 0384 0151 1C72 6000 0000 1137", + "005E 047C 0384 0152 1C72 A000 0000 1137", + "005E 0474 0014 001E 0000 C000 0000 10BE", + "005E 0474 0014 014A 0000 C000 0000 10BE" + ] + }, + { + "File": { + "Name": "Scene 5, Room 18", + "Start": "02664000", + "End": "026680C0", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0059", + "000E", + "011C", + "00E5", + "001B" + ], + "Actors": [ + "00EC 0630 0000 00B2 0000 0000 0000 0000", + "0025 06B8 014F 011B 0000 0000 0000 FFFF", + "0025 06B5 014F 0054 0000 0000 0000 FFFF", + "0112 071E 004B 00B6 0000 0000 0006 1ABF", + "0065 0546 02FD 00B4 0000 C000 0000 FF00", + "0173 071F 0057 00B3 0000 0000 0001 3F00", + "000A 066E 0000 00AC 0000 4000 0000 1801", + "012D 04BA FFC4 0104 0000 0000 0000 1FC1", + "012D 04BA FFC4 0064 0000 0000 0000 1FC1", + "0187 05D4 0000 00F8 0000 0000 0000 7FFF" + ] + }, + { + "File": { + "Name": "Scene 5, Room 19", + "Start": "02669000", + "End": "0266C930", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0059", + "000E", + "011C", + "0032" + ], + "Actors": [ + "0002 0612 030C 010C 0000 0000 0000 FFFF", + "0002 0615 030C 006B 0000 0000 0000 FFFF", + "0002 05CE 030C 00C0 0000 0000 0000 FFFF", + "0173 071D 0360 00B5 0000 000A 0001 3F00", + "000A 05E4 0310 00B6 0000 C000 0009 B822", + "0112 071E 0356 00B5 0000 0000 0006 1AC9" + ] + }, + { + "File": { + "Name": "Scene 5, Room 20", + "Start": "0266D000", + "End": "02673740", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "0059", + "000E", + "011C", + "0170", + "001B", + "0024", + "015C", + "00A4" + ], + "Actors": [ + "0025 028D 02C2 03B9 0000 8000 0000 FFFF", + "0025 0292 03E0 00B8 0000 0000 0000 FFFF", + "0112 0293 0218 040A 0000 0000 0006 197F", + "0065 026C 02FD 0334 0000 0000 0000 FF00", + "01A0 0330 01C6 01FE 0000 C000 0000 FFFF", + "01A0 0330 01C6 023A 0000 C000 0000 FFFF", + "01A0 020D 01D6 03BA 0000 4000 0000 FFFF", + "01A0 020C 01D6 0347 0000 4000 0000 FFFF", + "01A0 031B 01D6 032A 0000 4000 0000 FFFF", + "01A0 031B 01D6 0366 0000 4000 0000 FFFF", + "01A0 02AE 01D6 03F8 0000 0000 0000 FFFF", + "01A0 010E 01CC 01F8 0000 0000 0000 FFFF", + "01A0 01B5 01CC 0240 0000 0000 0000 FFFF", + "01A0 02BA 01CC 018F 0000 4000 0000 FFFF", + "0095 0334 01C6 021C 0000 4000 0000 8601", + "005E 02E6 01C6 01F4 0000 0000 0000 1062", + "01BB 02D1 01CC 021A 0000 C000 0000 0FE2", + "0111 0200 01CC 0243 0000 0000 0000 4402", + "0111 025A 01D6 03FE 0000 0000 0000 4609", + "0111 0315 01D6 03B3 0000 0000 0000 540E", + "0111 0300 01C6 0235 0000 0000 0000 6E03", + "0111 02FF 01C6 0205 0000 0000 0000 7E03" + ] + }, + { + "File": { + "Name": "Scene 5, Room 21", + "Start": "02674000", + "End": "0267B4A0", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "0059", + "013B", + "011C", + "0024", + "015C" + ], + "Actors": [ + "012D F516 0131 F0C8 0000 0000 0000 FFC0", + "012D F432 00AF F3B3 0000 0000 0000 FFC0", + "012D F681 00AF F31E 0000 0000 0000 FFC0", + "012D F472 00AF F61A 0000 0000 0000 FFC0", + "012D F60D 00AF F553 0000 0000 0000 FFC0", + "012D F802 00AF F432 0000 0000 0000 FFC0", + "012D F95A 00A1 F588 0000 0000 0000 FFC0", + "012D F7A2 0175 F687 0000 8000 0000 FFC2", + "012D F8A7 018C F53B 8000 8000 0000 FFC2", + "0160 F536 00C3 EEE6 0000 0000 0000 0000", + "0160 F600 006E F632 0000 0000 0000 0000", + "0160 F718 006E F2C2 0000 0000 0000 0000", + "0160 F7DF 006E F521 0000 0000 0000 0000", + "0160 F8A6 006E F639 0000 0000 0000 0000", + "0160 F91D 006E F4F7 0000 0000 0000 0000", + "0095 F5FB 01F9 F554 0000 0000 582E 8602", + "011B F4BB 017C F008 0028 0000 0000 47AB", + "011B F4D2 017C EEFA 0028 0000 0000 47AB", + "0111 F74E 0104 F649 0000 0000 0000 5E09", + "0111 F778 0104 F668 0000 0000 0000 6212" + ] + }, + { + "File": { + "Name": "Scene 5, Room 22", + "Start": "0267C000", + "End": "026850F0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 327680, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 88, + "y": -60 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 62, + "y": -23 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 88, + "y": -60 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 88, + "y": -60 + }, + { + "Flag": 5, + "x": 49, + "y": -43 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 6, + "x": 75, + "y": -65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 6, + "x": 81, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 75, + "y": 55 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 77, + "y": 40 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 74, + "y": 61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 73, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 73, + "y": 63 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 6", + "Start": "02ADE000", + "End": "02AF7B40", + "RemapStart": null + }, + "Id": 6, + "TActors": [ + "19FF 18FF 002E 0140 06C5 FCC2 4000 00B5", + "1AFF 19FF 002E FF38 06C5 FCC2 4000 0093", + "0FFF 05FF 002E 030C 01E0 FCAE C000 0086", + "0FFF 00FF 002E 0424 0000 FDB6 0000 003F", + "0DFF 00FF 002E 055C 001E FDD1 D555 02C3", + "00FF 0EFF 002E 02EC 001E FDD1 AAAB 00B1", + "0BFF 14FF 002E 0528 03EB 05C2 4000 005A", + "0BFF 0AFF 002E FBDC 03EB 05C2 C000 0059", + "09FF 08FF 002E F95C 034B 01D6 8000 00A4", + "04FF 01FF 002E FBDC 0028 FBAA 0000 02DE", + "03FF 01FF 002E FAA4 001E FDD1 2AAB 007F", + "02FF 01FF 002E FD14 001E FDD1 D555 007F", + "16FF 18FF 002E 02A8 0661 FC72 0000 02C1", + "18FF 17FF 002E 02A8 0607 FE41 0000 0080", + "17FF 11FF 002E 0424 034B 0096 4000 02DC", + "15FF 12FF 002E 0762 034B FE66 0000 0096", + "14FF 13FF 002E 07A8 03EB 0496 8000 007F", + "13FF 12FF 002E 07A8 034B 01D6 8000 00AF", + "12FF 11FF 002E 06A4 034B 0096 C000 00AC", + "10FF 11FF 002E 0424 034B FF2E 4000 007F", + "10FF 05FF 002E 02BC 032D FDC6 8000 02DB", + "0AFF 09FF 002E F95C 03EB 0496 8000 02D5", + "07FF 08FF 002E FC54 034B FF2E C000 00A4", + "06FF 05FF 002E 003C 019D FD76 8000 0087", + "05FF 04FF 002E FD6C 01E0 FCAE C000 02D2", + "07FF 05FF 002E FDBC 032D FDC6 8000 0088", + "03FF 1BFF 002E FA65 001E FAD1 6000 007F", + "1BFF 02FF 002E FCCD 001E FA4A 1F4A 007F", + "0CFF 0DFF 002E 0621 FF7E F9BD 0000 0082", + "00FF 01FF 0023 FD8D FFCE FFFF C000 003F", + "1CFF 05FF 002E 003C 03EF F8EA 0000 0154", + "06FF 00FF 0023 0000 0179 FFC3 8000 00BF", + "19FF 05FF 0023 003C 05D0 FBBE 8000 00BF" + ], + "Paths": [ + { + "Points": [ + [ + -486, + -50, + -1 + ], + [ + -403, + -50, + -44 + ] + ] + }, + { + "Points": [ + [ + 1466, + -80, + -1423 + ], + [ + 1466, + -80, + -743 + ] + ] + }, + { + "Points": [ + [ + 1673, + -80, + -743 + ], + [ + 1673, + -80, + -1423 + ] + ] + }, + { + "Points": [ + [ + -555, + 1776, + -675 + ], + [ + -449, + 1823, + -717 + ], + [ + -440, + 1772, + -805 + ], + [ + -463, + 1818, + -902 + ], + [ + -565, + 1781, + -934 + ], + [ + -652, + 1827, + -906 + ], + [ + -685, + 1772, + -809 + ], + [ + -662, + 1823, + -722 + ], + [ + -555, + 1776, + -675 + ] + ] + }, + { + "Points": [ + [ + -565, + 1827, + -498 + ], + [ + -685, + 1767, + -442 + ], + [ + -740, + 1836, + -304 + ], + [ + -699, + 1762, + -179 + ], + [ + -551, + 1818, + -110 + ], + [ + -422, + 1758, + -170 + ], + [ + -366, + 1832, + -304 + ], + [ + -417, + 1758, + -452 + ], + [ + -565, + 1827, + -498 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 6, Room 0", + "Start": "02AF8000", + "End": "02B08F40", + "RemapStart": "2AF7C00" + }, + "Id": 0, + "Objects": [ + "00F1", + "016D", + "0163", + "000E", + "013A", + "011E", + "011C", + "0025", + "00B3", + "00B7" + ], + "Actors": [ + "012D 0000 01BA FF94 0000 0000 0000 FFC2", + "0127 FF60 FF6A 010E 0000 0000 0000 000B", + "0127 0000 0118 FFC4 0000 0000 0000 800C", + "0127 015E FFFF 00DC 0000 0E39 0000 800E", + "0127 00A0 FF6A 010E 0000 0000 0000 0010", + "0127 042E 0001 FEDE 0000 0000 0000 001D", + "012A 042E 0001 FEDE 0000 0000 0000 2301", + "012A 015C 0019 00CD 0000 8000 0000 2502", + "012A FF36 0107 0324 C000 0000 0000 2603", + "0117 03F8 FFCE FFB7 0000 0000 0000 1FF7", + "0117 00A0 FF6A 010C 0000 0000 0000 1FF7", + "0117 FF60 FF6A 010E 0000 0000 0000 1FF7", + "0117 03C7 0000 FDDD 0000 0000 0000 1FF7", + "0117 02E8 FFCE 0004 0000 0000 0000 1FF7", + "00C3 FE12 FFCE FFFF 0000 4000 0000 0006", + "000A FF83 FFCE 0021 0000 8000 0000 507A", + "000A 007D 006F FF4F 0000 8000 0026 807F", + "0111 FF01 FF6A 02E6 0000 0000 0000 4203", + "0111 0132 FF6A 02AA 0000 0000 0000 6403", + "0111 FED7 FF6A 02AF 0000 0000 0000 6204", + "0117 0055 FFCE 005A 0000 0000 0000 0177", + "0111 0104 FF6A 02DF 0000 0000 0000 440E", + "015F 02E6 FF01 FFFF 000A 0005 0007 18D7", + "0185 012E FFCD 0136 0000 EAAB 0016 083F", + "0185 FEE6 FFCD 0138 0000 1555 0016 087F", + "000A 0084 006F 0021 0000 8000 0037 885B", + "000A FF79 006F FF4F 0000 8000 0025 885E" + ] + }, + { + "File": { + "Name": "Scene 6, Room 1", + "Start": "02B09000", + "End": "02B12300", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "00F1", + "016D", + "0163", + "000E", + "013A", + "011E", + "011C", + "0025", + "00B3", + "00B7" + ], + "Actors": [ + "0038 FB83 0000 FF24 0000 0000 0000 FFFF", + "0038 FC36 0000 FEA6 0000 0000 0000 FFFF", + "0013 FB7C 0048 FE0B 0000 1555 0000 0000", + "0013 FC3B 0048 FE0B 0000 EAAB 0000 0000", + "0127 FBDC 0000 FD58 0000 0000 0000 8005", + "012A FC37 0028 FC51 0000 0000 0000 0D01", + "0049 FB7C 0000 FDDF 0000 0000 0000 2FF8", + "0049 FC3B 0000 FDDF 0000 0000 0000 2FF8", + "0049 FB18 0000 FF23 0000 0000 0000 2FF8", + "0049 FCA4 0000 FF20 0000 0000 0000 2FF8", + "012A FBDC 00A9 FDD2 0000 0000 0000 3802", + "0111 FC82 FFCE FFCE 0000 0000 0000 4004", + "000A FBDE 00A7 FF8C 0000 0000 000D 885D", + "0015 FB81 0000 FDE9 0000 0000 0000 2C03", + "0015 FC30 0000 FDE9 0000 0000 0000 2E03" + ] + }, + { + "File": { + "Name": "Scene 6, Room 2", + "Start": "02B13000", + "End": "02B18C10", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "00F1", + "016D", + "0163", + "0098", + "00A2", + "0179" + ], + "Actors": [ + "0090 FE0A 001E FD22 0000 0000 0000 7FFE", + "0090 FE5C 001E FACB 0000 C000 0000 7FFE", + "0090 FE5F 001E FB8B 0000 C000 0000 7FFE", + "009D FDB6 001E FD67 0000 0000 0000 0000", + "009D FE65 001E FD67 0000 0000 0000 0000", + "00FD FDB1 0020 FBE3 0000 8000 0000 0021", + "012A FE64 001E FD66 0000 0000 0000 2100", + "0127 FDAF 001E FAC4 0000 0000 0000 0028", + "01B4 FDB5 0050 FC50 0000 0000 0000 3601", + "012A FDAE 0046 FA93 0000 2000 0000 3602", + "0127 FCEE 0077 FC5E 0000 0000 0000 003C", + "0127 FE5B FFAA FBF4 0000 0000 0000 003D", + "0111 FE82 001E FB18 0000 0000 0000 6803", + "0111 FE83 001E FB49 0000 0000 0000 660E" + ] + }, + { + "File": { + "Name": "Scene 6, Room 3", + "Start": "02B19000", + "End": "02B1CB50", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "00F1", + "016D", + "000E", + "00D6", + "000D", + "00A4", + "0114", + "00A2" + ], + "Actors": [ + "0013 F8F2 00BC FC63 0000 4000 0000 0003", + "0013 FAD0 0000 FC7A 0000 C000 0000 0003", + "0013 FA39 0051 FB8E 0000 0000 0000 0003", + "0013 F932 007A FDD5 0000 560B 0000 0003", + "0013 F9DD FFAA FBE2 0000 0000 0000 0003", + "005E F980 001E FB7B 0000 0000 0000 2400", + "005E FA39 001E FB7B 0000 0000 0000 2400", + "005E F980 001E FD38 0000 0000 0000 2400", + "005E FA39 001E FD38 0000 0000 0000 2400", + "009D F9A6 001E FAC6 0000 4000 0000 0000", + "00FD F9DF 001E FBE3 0000 0000 0000 002A", + "012A F9A4 001E FAC8 0000 0000 0000 2A00", + "00F6 F9E3 001E FD1C 0000 0000 0000 0002", + "000A F9E3 001E FD1B 0000 8000 0000 0820", + "000A F9DB 001E FB9A 0000 0000 0000 7848" + ] + }, + { + "File": { + "Name": "Scene 6, Room 4", + "Start": "02B1D000", + "End": "02B24270", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "000E", + "001F", + "0059", + "008B", + "000D", + "00D4", + "00CB", + "00DC", + "00F2" + ], + "Actors": [ + "002F FBD3 01EB FCE3 0000 5555 0000 FFFF", + "002F FBEA 01F3 FD2B 0000 6444 0000 FFFF", + "002F FD1D 01E0 FC02 0000 E38E 0000 FFFF", + "002F FCD0 01E0 FBAF 0000 ECCD 0000 FFFF", + "00DD FBDE 0100 FB13 0000 0000 0000 FFFF", + "0150 FC67 01E0 FC87 C000 C000 0000 0F00", + "0159 FB78 02AE FC90 0000 0000 0000 000F", + "012A FBDE 0028 FB0E 0000 0000 0000 3E43", + "012A FBDA 01E3 FB76 0000 0000 0000 3E43", + "01BB FC18 00EC FB0A 4000 C000 0000 0FFE", + "000A FD11 01E0 FBB9 0000 5C72 0000 7066", + "008A FCD1 01E0 FCF8 0000 8000 0000 0A00", + "0111 FBF5 0028 FB28 0000 0000 0000 460E", + "0185 FC68 01E0 FC8C 0000 0000 000B 04BF", + "000A FC2A 02BF FD7D 0000 4000 000F 884C" + ] + }, + { + "File": { + "Name": "Scene 6, Room 5", + "Start": "02B25000", + "End": "02B3CF40", + "RemapStart": "2B24380" + }, + "Id": 5, + "Objects": [ + "00F1", + "016D", + "00AB", + "00B0", + "00A4", + "012A", + "000E", + "0154", + "0190", + "00A8", + "016C", + "000B", + "0170" + ], + "Actors": [ + "0011 0042 0161 FB5C 0000 0000 0000 0001", + "008E 01DA 02F2 FD30 0000 C4FA 0000 0000", + "0158 003C 070A FBB2 0000 0000 0000 0000", + "015A 003C 0421 FA02 0000 0000 0000 FFFF", + "0169 003C 014D FC14 0000 0000 0000 0000", + "0169 FE34 032D FC36 0000 0000 0000 0000", + "0169 0244 032D FC36 0000 0000 0000 0000", + "0169 0244 014D FA56 0000 0000 0000 0000", + "0169 FE34 014D FA56 0000 0000 0000 0000", + "005E FF80 0287 FCB6 0000 0000 0000 2400", + "005E 00F4 0287 FCB1 0000 0000 0000 2400", + "01A0 023A 014D F9EA 0000 0000 0000 FFFF", + "01A0 01FE 014D F9EA 0000 0000 0000 FFFF", + "0110 FEF1 01F4 FC29 0000 0000 0000 FFFF", + "0156 003C 0487 FA63 0000 0000 0000 0004", + "012A 003C 0258 FD62 0000 8000 0000 0782", + "012A FEBA 029B FB2E 0000 0000 0000 0820", + "0157 003C 03CD FBBE 0000 0000 0000 0017", + "011D FDD1 032D F9F9 0000 0000 0000 FFE5", + "011D 029F 014D FB65 0000 0000 0000 FFE8", + "0011 01AA 0411 FB2B 0000 0000 0000 3302", + "012A FEBE 01B9 FA17 0000 C000 0000 3402", + "011D FF76 0287 FD1B 0000 0000 0000 FFF6", + "01D6 FDE6 02C9 FB96 0000 0000 0000 3838", + "01D6 FED9 0190 FC15 0000 0000 0000 B838", + "012E 01BD 02A2 FB0F 0000 0000 0000 1CB3", + "01D1 FE2A 01B8 FC04 0000 0000 0000 19FF", + "005E FE34 01ED FA56 0000 0000 0000 10C6", + "005E 0244 01ED FA56 0000 0000 0000 10C6", + "005E 003C 01ED FC14 0000 0000 0000 10C6", + "0111 027F 014D FB38 0000 0000 0000 4E03", + "01C9 02A1 01E0 FC41 0000 8000 0005 017F", + "0111 FDF7 032D F9D8 0000 0000 0000 4C08", + "0111 FDAD 032D F9D8 0000 0000 0000 480E", + "0111 FDD1 014D FB47 0000 0000 0000 6A0F", + "0111 02C0 014D FB38 0000 0000 0000 5210", + "0173 003B 0444 FA7E 0006 0005 0000 3C24", + "0185 01BD 02A2 FB0F 0000 0000 000B 8AF3", + "000A 003C 0164 FB3C 0000 8000 0034 B803", + "000A 020E 0502 F9C0 0000 8000 0033 888F", + "000A 02AC 032D F9FF 0000 0000 0000 6902", + "011B 003D 03C7 FBBE 001E 0000 0064 2791" + ] + }, + { + "File": { + "Name": "Scene 6, Room 6", + "Start": "02B3D000", + "End": "02B41800", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "00F1", + "016D", + "0163", + "000E", + "013A", + "011E", + "011C", + "0025", + "00B3", + "00B7" + ], + "Actors": [ + "00FF 021C 00D5 FE33 0000 0000 0000 09C7", + "012D 0000 01BA FF94 0000 0000 0000 FFC2", + "00FF 021C 019D FEFB 0000 0000 0000 09C3", + "0139 021C 00D5 FE33 0000 0000 0000 0009", + "01D5 021C 019D FEFB 0000 0000 0000 0009", + "012A 021C 015B FDD1 0000 0000 0000 0A02", + "00FF 021C 00D5 FFC3 0000 0000 0000 3FC3", + "000A 003A 022C FE65 0000 0000 000A 885C" + ] + }, + { + "File": { + "Name": "Scene 6, Room 7", + "Start": "02B42000", + "End": "02B47510", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "00F1", + "016D", + "002C" + ], + "Actors": [ + "0045 FD5A 0337 FEA5 0000 2444 0000 0000", + "0008 FCE0 0378 FED6 0000 0000 0000 03F4", + "0008 FCE0 0375 FF89 0000 0000 0000 03F4", + "0008 FD64 035A FE52 0000 0000 0000 03F4", + "0008 FDBC 036B FF2E 0000 0000 0000 03F4", + "0008 FE14 035B FE52 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 8", + "Start": "02B48000", + "End": "02B50070", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "000E", + "005D", + "000B", + "0024", + "015C", + "011C", + "0179" + ], + "Actors": [ + "012D FAC2 04B3 0010 4000 0000 0000 FFC2", + "01B4 FB85 0462 0190 0000 0000 0000 FF01", + "0069 FB4F 034B 0079 0000 9777 0000 FFFE", + "0069 FA09 034B FF19 0000 53E9 0000 FFFE", + "0069 F9B2 034B 0101 0000 B333 0000 FFFE", + "0150 FA95 034B FF74 0000 0000 0000 2421", + "00B7 F960 034B FF4D 0000 0000 0000 0001", + "0150 FAD1 034B FF74 0000 0000 0000 2B21", + "0049 F919 034B 0046 0000 4000 0000 2FF8", + "0049 FA63 034B 008C 0000 0000 0000 2FF8", + "0049 FB03 034B FE84 0000 0000 0000 2FF8", + "0049 FB03 034B FEC0 0000 0000 0000 2FF8", + "0049 F97D 034B 0046 0000 4000 0000 2FF8", + "0049 FA63 034B 00FA 0000 0000 0000 2FF8", + "0049 FA63 034B 0168 0000 0000 0000 2FF8", + "012A FAB8 039B FFAB 0000 0000 0000 3803", + "01B4 FAC1 0442 000B 0000 0000 0000 3901", + "0150 FA95 034B FFD8 0000 0000 0000 3921", + "0011 FA27 034B FF99 0000 0000 0000 3A02", + "0150 F9CD 034B 0078 0000 0000 0000 3A21", + "0011 FA0E 034B 00B8 0000 0000 0000 3B02", + "0150 F969 034B FE70 0000 0000 0000 3B21", + "0111 FB04 039B 01B0 0000 0000 0000 5603", + "0095 FB9A 0462 01A5 0000 0000 0000 8701", + "0111 F99D 039B FE42 0000 0000 0000 5410", + "000A FBC8 046C FE3E 0000 4000 002B 8901" + ] + }, + { + "File": { + "Name": "Scene 6, Room 9", + "Start": "02B51000", + "End": "02B56DF0", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "00F1", + "016D", + "002C", + "0024" + ], + "Actors": [ + "0037 F95C 0463 0342 0000 8000 0000 0001", + "0008 F8F9 03CD 0336 0000 0000 0000 03F4", + "0008 F8F9 037E 024E 0000 0000 0000 03F4", + "0008 F8FA 041D 041E 0000 0000 0000 03F4", + "0008 F9BC 041D 041D 0000 0000 0000 03F4", + "0008 F9BC 03CB 0337 0000 0000 0000 03F4", + "0008 F9BD 037B 024F 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 10", + "Start": "02B57000", + "End": "02B5F1A0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "00F1", + "016D", + "016C", + "0106" + ], + "Actors": [ + "0008 F88E 0417 0537 0000 0000 0000 03F4", + "0008 F88E 0417 064F 0000 0000 0000 03F4", + "0008 F952 0412 06CE 0000 0000 0000 03F4", + "0008 FAF6 0411 06CE 0000 0000 0000 03F4", + "0008 FB00 0411 04BA 0000 0000 0000 03F4", + "0113 FB1E 03EB 05C4 0000 C000 0000 1901", + "0169 FB41 03EB 05C2 0000 8000 0000 0001", + "0169 F8E4 03EB 054A 0000 4000 0000 0000", + "0169 F8E4 03EB 063A 0000 4000 0000 0000", + "0169 F9D4 03EB 054A 0000 4000 0000 0000", + "0169 F9D4 03EB 063A 0000 4000 0000 0000", + "0169 FAC4 03EB 054A 0000 4000 0000 0000", + "0169 FAC4 03EB 063A 0000 4000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 6, Room 11", + "Start": "02B60000", + "End": "02B61010", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "00F1", + "016D", + "016C", + "0106" + ], + "Actors": [] + }, + { + "File": { + "Name": "Scene 6, Room 12", + "Start": "02B62000", + "End": "02B64060", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "00F1", + "016D", + "000E", + "0024", + "015C", + "007C" + ], + "Actors": [ + "0037 05E5 0046 F8C5 0000 0000 0000 0000", + "0037 06A3 0046 F88E 0000 0000 0000 0000", + "0037 05BA 0046 F84D 0000 0000 0000 0000", + "0037 06B9 0046 F90B 0000 0000 0000 0000", + "0037 062C 0046 F822 0000 0000 0000 0002", + "0037 0657 0046 F8E5 0000 0000 0000 0001", + "0037 0621 0046 F879 0000 0000 0000 0001", + "0037 0627 0046 F92C 0000 0000 0000 0001", + "0037 05A4 0046 F91B 0000 0000 0000 0001", + "0095 06C7 0000 F966 4000 A000 0000 8708", + "000A 0625 FF7E F828 0000 8000 0000 5AA7" + ] + }, + { + "File": { + "Name": "Scene 6, Room 13", + "Start": "02B65000", + "End": "02B6A850", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "00F1", + "016D", + "011F", + "0059", + "0190", + "00A8", + "00F0", + "012A", + "011F", + "0030" + ], + "Actors": [ + "0107 0517 007B FAB8 0000 0000 0000 00FF", + "004B 0621 FF7E FA53 0000 0000 0000 0000", + "0130 05BA FFB0 FA71 0000 0000 0000 0301", + "0130 0689 FFB0 FD19 0000 0000 0000 0302", + "0150 0533 0085 FCD2 0000 4000 0000 0300", + "01BB 0523 FFDF FBC5 0000 4000 0000 0FF8", + "01BB 0721 FFDF FB3E 0000 C000 0000 0FF9", + "01BB 0523 FFDF FCD3 0000 4000 0000 0FFA", + "01BB 0523 FFDF FAB7 0000 4000 0000 0FFB", + "012A 0621 001E FD9F 0000 0000 0000 3C01", + "01BB 0721 FFDF FC4D 0000 C000 0000 0FFC", + "01D1 072C 00A9 FC4C 0000 0000 0000 81FF", + "012E 04E1 FFDF FAB7 0000 0000 0000 1C7A", + "012E 04E1 FFDF FBC5 0000 0000 0000 1C82", + "012E 04E1 FFDF FCD3 0000 0000 0000 1CF9", + "012E 0760 FFDF FC4D 0000 0000 0000 1D3B", + "012E 0760 FFDF FB3E 0000 0000 0000 1D78" + ] + }, + { + "File": { + "Name": "Scene 6, Room 14", + "Start": "02B6B000", + "End": "02B6FC90", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "00F1", + "016D", + "0017", + "000E", + "0024", + "015C" + ], + "Actors": [ + "00A7 0264 FF61 FBB8 0000 0000 0000 0041", + "012E 0175 001E FC98 0000 0000 0000 1CB1", + "0095 0205 010E FC15 8000 0000 0000 8702", + "0185 0175 001E FC98 0000 00B6 000B 8AF1", + "000A 0166 001E FA90 0000 8000 0000 7AA4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 15", + "Start": "02B70000", + "End": "02B78470", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "0032", + "000B", + "0059", + "0085" + ], + "Actors": [ + "0002 0489 01E0 FC09 0000 DA50 0000 0002", + "0002 048B 01E0 FD5A 0000 B333 0000 0002", + "0011 0480 01E0 FC96 0000 0000 0000 0000", + "0008 04C9 0035 FC50 0000 0000 0000 03F4", + "0008 04C9 0035 FD13 0000 0000 0000 03F4", + "01BB 0460 01D1 FAF6 4000 C000 0000 0FD1", + "0187 047A 027D FB16 0000 0000 0000 47FF", + "0011 03D0 01E0 FC72 0000 0000 0000 3A02", + "0150 054B 0212 FCB4 0000 C000 0000 3A30", + "0011 046A 01E0 FCD4 0000 0000 0000 3B02", + "0150 0549 0212 FD56 0000 C000 0000 3B30", + "0011 044E 01E0 FC57 0000 0000 0000 3D02", + "0150 054B 0212 FC0A 0000 C000 0000 3D30", + "00B7 0417 01E0 FC03 0000 0000 0000 0002", + "0111 04B4 0000 FC72 0000 0000 0000 6E03", + "0111 04B4 0000 FBFC 0000 0000 0000 7003", + "0080 04C4 0000 FD13 0000 C000 0000 0410", + "0080 03FC 0000 FC50 0000 4000 0000 0410", + "011B 0335 01E0 FCAE 0064 0012 0004 3291" + ] + }, + { + "File": { + "Name": "Scene 6, Room 16", + "Start": "02B79000", + "End": "02B7F190", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "00F1", + "016D", + "002C", + "011C", + "016C" + ], + "Actors": [ + "012D 037B 0410 FF2A 4000 0000 0000 FFC2", + "012D 02BC 03F7 FE62 4000 0000 0000 FFC2", + "0049 02B7 0337 FF34 0000 0000 0000 2FFF", + "0049 0344 0337 FEA7 0000 0000 0000 2FFF", + "000C 0300 0337 FEEA 0000 2000 0000 00FF", + "0008 0264 0358 FE52 0000 0000 0000 03F4", + "0008 0314 0358 FE52 0000 0000 0000 03F4", + "0008 0398 0376 FED6 0000 0000 0000 03F4", + "0008 0398 0373 FF89 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 17", + "Start": "02B80000", + "End": "02B89610", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "00F1", + "016D", + "000E", + "008B", + "0190", + "00A8" + ], + "Actors": [ + "0110 0566 043B 00BE 0000 C000 0000 FFFF", + "012A 05B7 034B FEDD 0000 0000 0000 2C20", + "01D6 0566 0374 00BD 0000 0000 0000 1839", + "01D6 0566 03D8 00BD 0000 0000 0000 9839", + "01D6 0566 02E7 00BD 0000 0000 0000 183A", + "01D6 05BB 034B FEE7 0000 0000 0000 983A", + "008A 0510 034B 0037 0000 4000 0000 0400", + "008A 05BD 034B 0037 0000 8000 0000 0400", + "008A 05B9 034B FF8B 0000 C000 0000 0400", + "008A 050D 034B FF91 0000 0000 0000 0401", + "000A 066D 034B FF89 0000 4000 0000 7979" + ] + }, + { + "File": { + "Name": "Scene 6, Room 18", + "Start": "02B8A000", + "End": "02B8FCB0", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "0190", + "00A8", + "001B", + "000E", + "0114" + ], + "Actors": [ + "0025 0782 048B FFB6 0000 E9F5 0000 FFFE", + "0025 07FB 048B 00F3 0000 A71C 0000 FFFE", + "0183 07F8 034B FF24 0000 0000 0000 FF40", + "0150 0893 03E0 FF26 0000 C000 0000 1600", + "00B7 07F8 034B FF24 0000 0000 0000 0003", + "0173 0821 0360 005B 0000 0030 0001 3F00", + "01D6 0762 034B FEAC 0000 0000 0000 1838", + "01D6 07F8 034B FF24 0000 0000 0000 9838", + "0112 0820 034B 005B 0000 0000 0002 192F", + "0112 0820 034B 005B 0000 0000 0000 192F", + "000A 0820 034B 005B 0000 4000 0000 5F98" + ] + }, + { + "File": { + "Name": "Scene 6, Room 19", + "Start": "02B90000", + "End": "02B95DE0", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "00F1", + "016D", + "000E", + "000B" + ], + "Actors": [ + "008E 07A7 03EA 041B 0000 8000 0000 8000", + "0008 0745 0419 041F 0000 0000 0000 03F4", + "0008 0745 03CE 0337 0000 0000 0000 03F4", + "0008 0745 037A 024E 0000 0000 0000 03F4", + "0008 0808 041A 041F 0000 0000 0000 03F4", + "0008 0808 03CB 0337 0000 0000 0000 03F4", + "0008 0809 0379 024F 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 20", + "Start": "02B96000", + "End": "02B9E1C0", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "00F1", + "016D", + "016C", + "0106" + ], + "Actors": [ + "0008 0605 0416 04BB 0000 0000 0000 03F4", + "0008 060F 0416 06CC 0000 0000 0000 03F4", + "0008 07B3 0416 06CD 0000 0000 0000 03F4", + "0008 0877 0417 064E 0000 0000 0000 03F4", + "0008 0878 0416 0537 0000 0000 0000 03F4", + "0113 05EB 03EB 05C1 0000 4000 0000 1A01", + "0169 05C3 03EB 05C2 0000 0000 0000 0001", + "0169 0640 03EB 054A 0000 C000 0000 0000", + "0169 0640 03EB 063A 0000 C000 0000 0000", + "0169 0730 03EB 054A 0000 C000 0000 0000", + "0169 0730 03EB 063A 0000 C000 0000 0000", + "0169 0820 03EB 054A 0000 C000 0000 0000", + "0169 0820 03EB 063A 0000 C000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 6, Room 21", + "Start": "02B9F000", + "End": "02BA3650", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "00F1", + "016D", + "000E", + "0098" + ], + "Actors": [ + "0090 0761 0369 FD84 0000 0000 0000 7FFE", + "0008 06F2 038F FD59 0000 0000 0000 03F4", + "0008 07D1 038F FD59 0000 0000 0000 03F4", + "000A 0763 0369 FD57 0000 8000 0000 27E5" + ] + }, + { + "File": { + "Name": "Scene 6, Room 22", + "Start": "02BA4000", + "End": "02BA70D0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "00F1", + "016D", + "015C", + "0024", + "0106", + "016C" + ], + "Actors": [ + "0113 02A9 0661 FADB 0000 0000 0000 FF02", + "0169 02AA 0661 F9C7 0000 C000 0000 0001", + "0169 02DC 0661 F995 0000 0000 0000 0001", + "0169 0278 0661 F995 0000 8000 0000 0001", + "0169 01B3 0661 FAF0 0000 4000 0000 0001", + "0169 01E5 0661 FB22 0000 0000 0000 0001", + "0169 01B3 0661 FB54 0000 C000 0000 0001", + "0169 039D 0661 FAF0 0000 4000 0000 0001", + "0169 039D 0661 FB54 0000 C000 0000 0001", + "0169 036B 0661 FB22 0000 8000 0000 0001", + "0095 019A 06C9 FB22 4000 4000 0000 8704", + "0095 02A9 06AC F97C 4000 0000 0000 8710" + ] + }, + { + "File": { + "Name": "Scene 6, Room 23", + "Start": "02BA8000", + "End": "02BB1190", + "RemapStart": null + }, + "Id": 23, + "Objects": [ + "00F1", + "016D", + "00B7", + "00A4", + "000D", + "0025" + ], + "Actors": [ + "0095 02A9 04B0 FFA9 4000 0000 0000 0000", + "0038 0298 0607 FF1E 0000 182E 0000 FFFF", + "0013 0242 0686 00B9 0000 4889 0000 0000", + "0013 031C 0548 00DB 0000 A666 0000 0000", + "0013 0223 04B1 0006 0000 2CCD 0000 0000", + "0013 0316 0673 FF3E 0000 E000 0000 0000", + "00FA 02A8 04DB FFA9 0000 0000 0000 0000", + "00FA 02A8 053F FFA9 0000 0000 0000 0000", + "00FA 02A8 0413 FFA9 0000 0000 0000 0000", + "00FA 02A8 03AF FFA9 0000 0000 0000 0000", + "0117 02D3 03D1 FFB5 0000 0000 0000 1FC0", + "0117 0246 0435 FFB5 0000 0000 0000 1FC0", + "0117 02F2 050C FFB5 0000 0000 0000 1FC0", + "0117 0284 0570 FFB5 0000 0000 0000 1FC0", + "0117 02A9 049D FFB5 0000 0000 0000 1FC0", + "0111 033D 034B 00FA 0000 0000 0000 0203", + "0111 0213 034B 00F9 0000 0000 0000 0403", + "005E 0243 0387 0021 0000 0000 0000 03C0", + "005E 0243 0643 FEDF 0000 0000 0000 03C0", + "005E 030C 0387 0021 0000 0000 0000 03C0", + "005E 030C 0643 FEE2 0000 0000 0000 03C0", + "0117 02BF 034B 00A0 0000 0000 0000 0140" + ] + }, + { + "File": { + "Name": "Scene 6, Room 24", + "Start": "02BB2000", + "End": "02BB84B0", + "RemapStart": null + }, + "Id": 24, + "Objects": [ + "00F1", + "016D" + ], + "Actors": [ + "0008 024E 068F FC95 0000 0000 0000 03F4", + "0008 0302 068F FC92 0000 0000 0000 03F4", + "012E 02A7 0661 FCD0 0000 0000 0000 1CB5", + "0111 030D 06C5 FCB7 0000 0000 0000 7403", + "0111 024B 06C5 FCB4 0000 0000 0000 7204", + "0185 02A7 0661 FCD0 0000 0000 000B 8AF5" + ] + }, + { + "File": { + "Name": "Scene 6, Room 25", + "Start": "02BB9000", + "End": "02BCEB70", + "RemapStart": null + }, + "Id": 25, + "Objects": [ + "00F1", + "016D", + "00AB", + "00B0", + "00A4", + "012A", + "000E", + "0154", + "0190", + "00A8", + "016C", + "000B", + "0170" + ], + "Actors": [ + "0158 003C 070A FBB2 0000 0000 0000 0000", + "01A0 010E 064D FB5E 0000 0000 0000 FFFF", + "01A0 FF6A 064D FB5E 0000 0000 0000 FFFF", + "01A0 010E 064D FB8E 0000 0000 0000 FFFF", + "01A0 FF6A 064D FB8E 0000 0000 0000 FFFF", + "012A FF6D 064D FB5E 0000 0000 0000 1301", + "0150 003C 0675 FC84 0000 8000 0000 1700", + "0157 003C 064D FBBE 0000 0000 0000 0017", + "0112 FF59 06C5 FCC2 0000 0000 0000 3FE9", + "0111 00F4 06C5 FC83 0000 0000 0000 7803", + "0111 FF86 06C5 FD1B 0000 0000 0000 7A03", + "0111 00FA 06C5 FD1B 0000 0000 0000 7C03", + "0111 FF85 06C5 FC84 0000 0000 0000 760F" + ] + }, + { + "File": { + "Name": "Scene 6, Room 26", + "Start": "02BCF000", + "End": "02BDBB20", + "RemapStart": null + }, + "Id": 26, + "Objects": [ + "00F1", + "016D", + "00AB", + "001B", + "005D", + "000E", + "012A", + "0025" + ], + "Actors": [ + "0038 FDDF 06CF FCC2 0000 8000 0000 FFFF", + "0025 FFE8 0797 FED0 0000 C000 0000 FFFE", + "0158 003C 070A FBB2 0000 0000 0000 0000", + "00B7 FDD2 06CF FECE 0000 0000 0000 0004", + "0049 003C 06CF FECB 0000 0000 0000 2FED", + "0150 FDD1 0765 FD74 0000 8000 0000 2D00", + "0069 FDD5 06F0 FD5D 0000 0000 0000 30FB", + "0069 0235 0723 FE0E 0000 0000 0000 40FB", + "000A 0030 06CF FDD1 0000 4000 0000 6852" + ] + }, + { + "File": { + "Name": "Scene 6, Room 27", + "Start": "02BDC000", + "End": "02BE16C0", + "RemapStart": null + }, + "Id": 27, + "Objects": [ + "00F1", + "016D", + "0069", + "0032" + ], + "Actors": [ + "0049 FBA4 FFEC FA73 0000 0000 0000 0FFF", + "0049 FB15 FFEC FA22 0000 0000 0000 0FFF", + "0049 FB1F FFEC F88F 0000 0000 0000 0FFF", + "0049 FCA3 FFEC F895 0000 0000 0000 0FFF", + "0049 FC24 FFEC F84D 0000 0000 0000 0FFF", + "0049 FB8F FFEC F852 0000 0000 0000 0FFF", + "0049 FC38 FFEC FA6F 0000 0000 0000 0FFF", + "0002 FBE3 0096 F8F9 0000 0000 0000 0003", + "00AF FBE1 001E F970 0000 0000 0000 0002", + "0111 FB72 001E F875 0000 0000 0000 5C03", + "0111 FC41 001E F876 0000 0000 0000 5E03", + "0111 FCAB 001E F8D3 0000 0000 0000 6010", + "0111 FB1E 001E F8C4 0000 0000 0000 5A12" + ] + }, + { + "File": { + "Name": "Scene 6, Room 28", + "Start": "02BE2000", + "End": "02BEAA20", + "RemapStart": null + }, + "Id": 28, + "Objects": [ + "00F1", + "016D", + "00AB", + "00B0", + "00A4", + "012A", + "000E", + "0154", + "0190", + "00A8", + "016C", + "000B", + "0170" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 3109, + "Type": 8, + "Flags": 0 + }, + { + "Id": 3110, + "Type": 8, + "Flags": 0 + }, + { + "Id": 3111, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3112, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3551, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3552, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3553, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3554, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3555, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3556, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3557, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3558, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3559, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3560, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3561, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3562, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3563, + "Type": 64, + "Flags": 0 + }, + { + "Id": 3564, + "Type": 64, + "Flags": 0 + }, + { + "Id": 3729, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3730, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3731, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3732, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3733, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3734, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3735, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3736, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3737, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3738, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3739, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3740, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3741, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3742, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4133, + "Type": 66, + "Flags": 0 + }, + { + "Id": 4134, + "Type": 66, + "Flags": 0 + }, + { + "Id": 4212, + "Type": 8, + "Flags": 0 + }, + { + "Id": 4213, + "Type": 8, + "Flags": 0 + }, + { + "Id": 4348, + "Type": 67, + "Flags": 0 + }, + { + "Id": 4349, + "Type": 67, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 3, + "High": 49164, + "Low": 30733 + }, + { + "Id": 8, + "High": 805306379, + "Low": 12290 + }, + { + "Id": 60, + "High": 15, + "Low": 12301 + }, + { + "Id": 61, + "High": 11, + "Low": 20493 + }, + { + "Id": 62, + "High": 16395, + "Low": 134232002 + }, + { + "Id": 63, + "High": 16395, + "Low": 134238210 + }, + { + "Id": 64, + "High": 16395, + "Low": 134230018 + }, + { + "Id": 65, + "High": 49163, + "Low": 12290 + }, + { + "Id": 66, + "High": 11, + "Low": 12289 + }, + { + "Id": 67, + "High": 523, + "Low": 12322 + } + ], + "Cams": [ + { + "Data": 1966086, + "PositionIndex": 0 + }, + { + "Data": 1441795, + "PositionIndex": 1 + }, + { + "Data": 1441795, + "PositionIndex": 2 + }, + { + "Data": 1966086, + "PositionIndex": 3 + }, + { + "Data": 1441795, + "PositionIndex": 4 + }, + { + "Data": 1441795, + "PositionIndex": 5 + }, + { + "Data": 1638403, + "PositionIndex": 6 + }, + { + "Data": 1638403, + "PositionIndex": 7 + }, + { + "Data": 1638403, + "PositionIndex": 8 + }, + { + "Data": 1638403, + "PositionIndex": 9 + }, + { + "Data": 1638403, + "PositionIndex": 10 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 131072, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 18, + "x": 46, + "y": -30 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 1, + "x": 23, + "y": -33 + }, + { + "Flag": 2, + "x": 56, + "y": -11 + }, + { + "Flag": 5, + "x": 83, + "y": -25 + }, + { + "Flag": 24, + "x": 84, + "y": -39 + }, + { + "Flag": 25, + "x": 74, + "y": -37 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 47, + "y": 0 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 3, + "x": 46, + "y": -20 + }, + { + "Flag": 6, + "x": 28, + "y": -19 + }, + { + "Flag": 12, + "x": 25, + "y": -25 + }, + { + "Flag": 15, + "x": 50, + "y": -13 + }, + { + "Flag": 28, + "x": 48, + "y": -29 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 9, + "IconPoints": [ + { + "Flag": 0, + "x": 14, + "y": -24 + }, + { + "Flag": 4, + "x": 55, + "y": -14 + }, + { + "Flag": 7, + "x": 78, + "y": -2 + }, + { + "Flag": 8, + "x": 14, + "y": -16 + }, + { + "Flag": 26, + "x": 42, + "y": -43 + }, + { + "Flag": 27, + "x": 50, + "y": -43 + }, + { + "Flag": 29, + "x": 25, + "y": -35 + }, + { + "Flag": 30, + "x": 42, + "y": -36 + }, + { + "Flag": 31, + "x": 50, + "y": -36 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 4, + "IconPoints": [ + { + "Flag": 26, + "x": 27, + "y": 35 + }, + { + "Flag": 27, + "x": 36, + "y": 35 + }, + { + "Flag": 30, + "x": 27, + "y": 28 + }, + { + "Flag": 31, + "x": 36, + "y": 28 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 29, + "x": 67, + "y": 63 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 71, + "y": 62 + }, + { + "Flag": 8, + "x": 71, + "y": 48 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 3, + "x": 56, + "y": 54 + }, + { + "Flag": 15, + "x": 69, + "y": 42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 28, + "x": 60, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 76, + "y": 40 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 70, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 4, + "x": 68, + "y": 42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 25, + "x": 78, + "y": 58 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 24, + "x": 78, + "y": 58 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 71, + "y": 55 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 18, + "x": 75, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 6, + "x": 78, + "y": 55 + }, + { + "Flag": 12, + "x": 70, + "y": 70 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 76, + "y": 37 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 57, + "y": 23 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 7", + "Start": "027A7000", + "End": "027BF3C0", + "RemapStart": null + }, + "Id": 7, + "TActors": [ + "00FF 04FF 002E F7FA FFC1 FE6B C000 007F", + "00FF 01FF 002E FCE6 FFC1 FD53 8000 007F", + "00FF 02FF 0009 FFA2 FFC1 FF47 4000 0099", + "03FF 15FF 0009 F54A FAAD FF14 8000 003F", + "08FF 05FF 0009 0EFF FDE1 0037 C000 0096", + "05FF 06FF 002E 0D1E FDE1 FE56 8000 007F", + "05FF 07FF 002E 0D1E FDE1 0218 0000 007F", + "10FF 09FF 0009 1246 FB89 09FB 0000 003F", + "0BFF 09FF 0009 09AE FAC1 05C2 0000 0097", + "12FF 0BFF 0009 09AE FB4D 031A 0000 0098", + "0EFF 0BFF 002E 07BA FAC1 043C 4000 01C8", + "0FFF 0CFF 0009 EC59 FAAD F9CE C000 003F", + "0FFF 0DFF 002E EF2E FAAD F6F9 8000 02DB", + "0FFF 11FF 002E EF2E FAAD FCA2 0000 003F", + "0FFF 15FF 002E F202 FAAD F9CE 4000 009A", + "14FF 12FF 0009 1124 FAAD FD7A 0000 003F", + "12FF 13FF 0009 1278 FAAD FF82 4000 003F", + "15FF 14FF 0009 1124 FAAD FA82 0000 0095", + "0AFF 09FF 0023 05BF FAC1 0E1F 8000 013F", + "05FF 02FF 0023 08E4 FED1 0037 C000 013F", + "08FF 09FF 0023 0FB2 FC29 0554 C000 013F", + "16FF 03FF 002E F54A FAAD 034C 8000 0154", + "06FF 15FF 0023 0F8F FCF1 FB36 C000 00BF" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 7, Room 0", + "Start": "027C0000", + "End": "027CB0C0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0190", + "00A8", + "0179" + ], + "Actors": [ + "01B4 F8D3 0008 FE6B 4000 4000 0000 0701", + "01B4 F8D3 FFA4 FE6B 4000 4000 0000 0701", + "01D1 FB97 FF71 FF47 0000 4000 0000 B80D", + "01D1 FB97 FFD5 FF47 0000 4000 0000 B80E", + "0111 FBEB FFC1 FF7E 0000 4000 0000 7003", + "0111 FBEB FFC1 FF10 0000 4000 0000 7203", + "011D F9B9 FFC1 003C 0000 8000 0000 03FB", + "011D FD1D FFC1 003C 0000 8000 0000 03FC", + "011D FA26 FFC1 003C 0000 8000 0000 03FD", + "011D FCB0 FFC1 003C 0000 8000 0000 03FE", + "012A F9ED 0005 005F 0000 8000 0000 0712", + "011C F911 0005 005F 0000 8000 0000 0000", + "011C FAC9 0005 005F 0000 8000 0000 0000", + "00AE F8D6 FFC1 FE6B 0000 C000 0000 0003", + "00AE FB06 FFC1 FF47 0000 C000 0000 0003", + "00AE FBCE FFC1 FF47 0000 C000 0000 0003", + "00AE FCE6 FFC1 FE2F 0000 0000 0000 0003", + "00AE FDFE FFC1 FF47 0000 C000 0000 0003" + ] + }, + { + "File": { + "Name": "Scene 7, Room 1", + "Start": "027CC000", + "End": "027CDAC0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0190", + "00A8", + "0098" + ], + "Actors": [ + "0090 FCA7 FFC1 FCA2 0000 60B6 0000 7F02", + "0090 FCC4 FFC1 FC55 0000 25B0 0000 7F02", + "0090 FD04 FFC1 FCAB 0000 9A50 0000 7F02", + "0090 FD19 FFC1 FC3E 0000 D8E4 0000 7F02", + "0111 FD6F FFC1 FC4B 0000 0000 0000 4E03", + "0111 FD37 FFC1 FC08 0000 0000 0000 5803", + "000A FCE6 FFC1 FC18 0000 8000 0000 1801" + ] + }, + { + "File": { + "Name": "Scene 7, Room 2", + "Start": "027CE000", + "End": "027D8910", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "011C", + "0179" + ], + "Actors": [ + "01B4 0420 FFC1 0037 0000 4000 0000 0501", + "005E 0565 004B FFBF 0AAB C000 0000 1085", + "005E 0565 004B 00AF 0AAB C000 0000 1085", + "00AE 0146 FFC1 FF47 0000 4000 0000 0004", + "00AE 0146 FFC1 0127 0000 4000 0000 0004", + "00AE 0D1E FDE1 0037 0000 C000 0000 0006", + "00F7 029A FFC1 0037 0000 0000 0000 0B00", + "00BE 013C 0011 FF47 0000 4000 0000 0201", + "00F7 029A FFC1 0037 0000 0000 0000 0B01", + "00F7 01C8 0011 0037 0000 0000 0000 0B03", + "00F7 0231 0011 FF81 0000 D555 0000 0B03", + "00F7 0303 0011 FF81 0000 AAAB 0000 0B03", + "00F7 0231 0011 00ED 0000 2AAB 0000 0B03", + "00F7 0303 0011 00ED 0000 5555 0000 0B03", + "00F7 058D FFC1 0037 0000 0000 0000 0B02", + "0110 016E 0150 0072 0000 0000 0000 3009", + "0110 016B FFC1 FFF9 0000 0000 0000 310E", + "0110 016B FFC1 FFC2 0000 0000 0000 3904", + "0110 016D 0150 0034 0000 0000 0000 3A03" + ] + }, + { + "File": { + "Name": "Scene 7, Room 3", + "Start": "027D9000", + "End": "027DB940", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "00B0", + "005D", + "0024", + "015C" + ], + "Actors": [ + "0095 F3E9 FA87 020F 4000 0000 0000 8804", + "00AE F54A FAAD 0135 0000 0000 0000 0005" + ] + }, + { + "File": { + "Name": "Scene 7, Room 4", + "Start": "027DC000", + "End": "027DDC40", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0190", + "00A8", + "0179", + "00A6" + ], + "Actors": [ + "00A5 F61A FFC1 FEA6 0000 0000 0000 FFFF", + "00A5 F620 FFC1 FE11 0000 0000 0000 FFFF", + "00A5 F678 FFC1 FDCE 0000 0000 0000 FFFF", + "00A5 F688 FFC1 FEED 0000 0000 0000 FFFF", + "00A5 F6DB FFC1 FEB1 0000 0000 0000 FFFF", + "00A5 F6E1 FFC1 FE1C 0000 0000 0000 FFFF", + "00A4 F688 FFC1 FE63 0000 0000 0000 FFFF", + "000A F562 FFC1 FE64 0000 C000 0001 15E7" + ] + }, + { + "File": { + "Name": "Scene 7, Room 5", + "Start": "027DE000", + "End": "027E3A60", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008B" + ], + "Actors": [ + "008A 0D1E FDE1 0037 0000 C000 0000 0700", + "00AE 0D1E FDE1 0037 0000 C000 0000 0006", + "00BE 0E14 FE31 0037 0000 C000 0000 1E01", + "0183 0D1E FDE1 0037 0000 0000 0000 FF41" + ] + }, + { + "File": { + "Name": "Scene 7, Room 6", + "Start": "027E4000", + "End": "027EB570", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0031", + "011C", + "0032", + "0024", + "015C", + "0154", + "00A8", + "0190", + "00B7" + ], + "Actors": [ + "0037 0B68 FE31 FC3F 0000 4000 0000 0000", + "0037 0DE6 FE31 FAA1 0000 0000 0000 0000", + "0037 0EC2 FE31 FB36 0000 C000 0000 0000", + "0037 0F32 FE31 FCEE 0000 C000 0000 0001", + "0117 0AFA FDE1 FC3F 0000 0000 0000 1FC1", + "0117 0BBF FE59 FB3A 0000 0000 0000 1FC1", + "0117 0CAB FDE1 FBDB 0000 0000 0000 1FC1", + "0117 0D47 FDE1 FCBA 0000 0000 0000 1FC1", + "0117 0DE6 FDE1 FA2E 0000 0000 0000 1FC1", + "0117 0D1F FE14 FC4D 0000 0000 0000 0141", + "0173 0FE1 FE20 FB35 0000 FFA6 0000 2181", + "0187 0D1E FDE1 FE2E 0000 0000 0000 1FFF", + "00AE 0F8A FDE1 FB36 0000 0000 0000 0007", + "00AF 0EB8 FDE1 FCEE 0000 4000 0000 0103", + "00B1 0D1E FDE1 FC4E 0000 0000 0000 0000", + "000A 0F98 FDE1 FCEE 0000 4000 0000 0822" + ] + }, + { + "File": { + "Name": "Scene 7, Room 7", + "Start": "027EC000", + "End": "027EDAB0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0098", + "000D" + ], + "Actors": [ + "0090 0C8C FDE1 02D6 0000 8000 0000 7FFE", + "0090 0DAA FDE1 02D1 0000 8000 0000 7FFE", + "005E 0CEE FDE1 033E 0000 8000 0000 2400", + "005E 0D50 FDE1 033B 0000 8000 0000 2400", + "0187 0D1E FDE1 0260 0000 0000 0000 1FFF", + "000A 0D22 FDE1 0375 0000 0000 0000 7843" + ] + }, + { + "File": { + "Name": "Scene 7, Room 8", + "Start": "027EE000", + "End": "027F3060", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008B", + "0024", + "0085", + "011C" + ], + "Actors": [ + "012D 10A2 FD69 01A8 4000 0000 0000 FFC2", + "0037 10A2 FDBC 00FD 0000 4000 0000 0001", + "008A 1322 FD69 00FD 0000 8000 0000 0400", + "008A 10A2 FC29 035E 0000 8000 0000 0700", + "0080 115F FCED 0128 0000 8000 F333 0210", + "0080 11F0 FD1E 00D8 0000 0000 0CCD 0210", + "00BC 10A2 FCBD 0266 0000 0000 0000 0000", + "00BC 10A2 FCBD 045A 0000 0000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 7, Room 9", + "Start": "027F4000", + "End": "02800B60", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008B", + "0085", + "005D", + "012F", + "011C", + "0179", + "0031" + ], + "Actors": [ + "012D 083E FCC4 0D2C 20B6 305B 0000 FFC2", + "01B4 0B18 FAE9 0D07 0000 0000 0000 0F01", + "01B4 0BD3 FB1F 0D07 0000 0000 0000 0F01", + "01B4 0C8E FB55 0D07 0000 0000 0000 0F01", + "01B4 0D48 FB89 0D07 0000 0000 0000 0F01", + "0069 0EB7 FB6E 0C33 0000 8000 0000 FFFE", + "008A 0E5E FB89 0CE9 0000 8000 0000 0700", + "008A 0EFE FB89 0CE9 0000 8000 0000 0700", + "0080 083E FAC1 0D2C 0000 0000 0000 1220", + "0080 083E FAC1 0D2C 0000 0000 0000 1620", + "008A 083E FAC1 0D2C 0000 4000 0000 0501", + "012A 0677 FAC1 0D2C 0000 4000 0000 0903", + "0141 0B4D FAC1 0A91 0000 127D 0000 0027", + "0117 07B2 FAC1 0D2C 0000 0000 0000 1FD1", + "0117 083E FBBC 0D2C 0000 0000 0000 1FD1", + "0117 083E FC36 0D2C 0000 0000 0000 1FD1", + "0117 0853 FAC1 0BD6 0000 0000 0000 1FD1", + "0117 08CA FAC1 0D2C 0000 0000 0000 1FD1", + "0117 0727 FB56 0D32 0000 0000 0000 0151", + "004C 0EAE FB89 0D0E 0000 0000 0000 FFFF", + "012A 11A6 FB4D 0D2E 0000 BF4A 0000 0F82", + "00BC 0B7D FB55 0A55 0000 0000 0000 0000", + "00BC 0EAE FCBD 09F0 0000 0000 0000 0000", + "00BC 0EAE FCBD 0874 0000 0000 0000 0005", + "00BC 0EAE FC1D 0BD0 0000 0000 0000 0005", + "00AF 06AF FAC1 0D2C 0000 C000 0000 0903", + "00AF 0A92 FAC1 07DE 0000 0000 0000 0000", + "00AE 0F56 FB17 0B48 0000 0000 0000 0008", + "000A 083E FCF8 0E87 0000 0000 0011 892F", + "0183 0EAE FB89 0D0E 0000 0000 0000 FF41" + ] + }, + { + "File": { + "Name": "Scene 7, Room 10", + "Start": "02801000", + "End": "028087A0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "012F", + "0024", + "015C", + "0085" + ], + "Actors": [ + "00FF 03C1 FAC1 0E65 0000 0000 0000 FF02", + "0095 0302 FB08 0FE2 C000 4000 0000 8802", + "0141 046C FAC1 1007 0000 8000 0000 0026", + "0111 0266 FAC1 0DFB 0000 0000 0000 4803", + "0111 031E FAC1 0DF6 0000 0000 0000 4A04", + "0111 0495 FB61 0E7B 0000 0000 0000 5603", + "0111 0495 FB61 0E15 0000 0000 0000 5A03", + "012A 02E2 FB61 0FE3 0000 0000 0000 0400", + "0080 0277 FAC1 0E88 0000 4000 0000 0210", + "00AE 03C1 FAC1 0EAB 0000 0000 0000 0009", + "00BC 01FF FB89 0F0F 0000 0000 0000 0001", + "00BC 02C7 FB89 0F0F 0000 0000 0000 0001", + "000A 0453 FC00 0E4B 0000 4000 0004 8844", + "000A 01F9 FAC1 0E49 0000 4000 0000 5945", + "000A 00E0 FB61 0FF0 0000 C000 0000 5886" + ] + }, + { + "File": { + "Name": "Scene 7, Room 11", + "Start": "02809000", + "End": "0280CD40", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0098", + "0179", + "011C" + ], + "Actors": [ + "012D 09AE FC79 04B0 4000 0000 0000 FFC2", + "012D 09AE FC79 057C 4000 0000 0000 FFC2", + "01B4 097C FBED 0360 0000 0000 0000 0801", + "01B4 097C FBED 03C4 0000 0000 0000 0801", + "01B4 09AE FB61 04B0 0000 0000 0000 0801", + "01B4 09AE FB61 057C 0000 0000 0000 0801", + "01B4 09E0 FBED 0360 0000 0000 0000 0801", + "01B4 09E0 FBED 03C4 0000 0000 0000 0801", + "0090 0849 FAC1 049F 0000 1555 0000 0102", + "0090 0B17 FAC1 04C1 0000 EAAB 0000 0102", + "0117 07FA FB4D 0351 0000 0000 0000 1FC8", + "0117 0857 FB37 0511 0000 0000 0000 1FC8", + "0117 08CE FB4D 03DC 0000 0000 0000 1FC8", + "0117 09AE FC31 037D 0000 0000 0000 1FC8", + "0117 09AE FAC1 04B8 0000 0000 0000 1FC8", + "0117 09AE FBB4 04B0 0000 0000 0000 1FC8", + "0117 09AE FBB4 057C 0000 0000 0000 1FC8", + "0117 0A91 FACF 0441 0000 0000 0000 1FC8", + "0117 0AAA FB4D 036C 0000 0000 0000 1FC8", + "0117 0B7C FB0F 042D 0000 0000 0000 1FC8", + "0117 09AE FAC1 0434 0000 0000 0000 0288", + "00AE 09AE FAC1 046E 0000 0000 0000 000C", + "000A 09AE FAC1 03F4 0000 8000 0000 7889" + ] + }, + { + "File": { + "Name": "Scene 7, Room 12", + "Start": "0280D000", + "End": "02812720", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "005D", + "00D4", + "00AA", + "00CD", + "000D", + "0024", + "015C", + "0031" + ], + "Actors": [ + "0015 E91E FAAD F9BB 0000 0000 0000 0611", + "0112 EC3B FBE6 F9CD 0000 C000 0001 19F8", + "0008 E87D FC59 FB1A 0000 0000 0000 03F7", + "0008 E87E FC56 F883 0000 0000 0000 03F7", + "0008 EBBE FBD1 F87D 0000 0000 0000 03F7", + "0008 EBC3 FBD1 FB16 0000 0000 0000 03F7", + "004C E818 FBB1 F91D 0000 0000 0000 FFFF", + "004C E818 FBB1 FA8A 0000 0000 0000 FFFF", + "00BB EA00 FAC1 F94F 0000 D555 0000 00FF", + "00BB EA00 FAC1 FA4A 0000 2AAB 0000 00FF", + "00BB EADA FAC1 F9CD 0000 8000 0000 00FF", + "00AF EA49 FAAD F9CD 0000 8000 0000 0002" + ] + }, + { + "File": { + "Name": "Scene 7, Room 13", + "Start": "02813000", + "End": "02813FB0", + "RemapStart": "2812800" + }, + "Id": 13, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000D", + "0024" + ], + "Actors": [ + "0013 EFC0 FACB F583 0000 0000 0000 0003", + "0013 EE98 FAD0 F582 0000 0000 0000 0003", + "0013 EF91 FB2A F6E0 0000 8000 0000 0003", + "0013 EEA5 FADB F6DD 0000 8000 0000 0003", + "0037 F07B FB4D F5F6 0000 0000 0000 0002", + "0037 F03D FB4D F5BB 0000 C000 0000 0002", + "0037 EDE6 FB4D F63D 0000 0000 0000 0002", + "0037 F07D FB4D F67B 0000 0000 0000 0002", + "0111 EF31 FAAD F59F 0000 0000 0000 4C0E", + "00BC EE48 FAAD F631 0000 C000 0000 0003", + "00BC F014 FAAD F631 0000 C000 0000 0002", + "000A F07B FAAD F5BD 0000 8000 0000 27EB", + "000A EDE4 FAAD F5B8 0000 8000 0000 588A" + ] + }, + { + "File": { + "Name": "Scene 7, Room 14", + "Start": "02814000", + "End": "02819940", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0032" + ], + "Actors": [ + "0008 04A2 FC66 052D 0000 0000 0000 03F7", + "0008 04A3 FC66 034A 0000 0000 0000 03F7", + "0008 0762 FBF6 034E 0000 0000 0000 03F7", + "0008 0762 FBF6 052A 0000 0000 0000 03F7", + "0002 045A FBC5 0439 0000 4000 0000 0003", + "0002 05D1 FAD5 043B 0000 4000 0000 0003", + "000A 04E4 FBC5 043B 0000 4000 0000 79D0" + ] + }, + { + "File": { + "Name": "Scene 7, Room 15", + "Start": "0281A000", + "End": "02821270", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "005D", + "00D4", + "00CB", + "00DC", + "00F2" + ], + "Actors": [ + "0069 EE15 FAAD F894 0000 6222 0000 FFFF", + "0069 F04A FAAD FB05 0000 E000 0000 FFFF", + "00DD EE69 FAAD F9CF 0000 4000 0000 FFFF", + "0008 EDAB FB00 F84A 0000 0000 0000 03F7", + "0008 EDAB FB00 FB50 0000 0000 0000 03F7", + "0008 F0B2 FB00 F84A 0000 0000 0000 03F7", + "0008 F0B4 FB00 FB50 0000 0000 0000 03F7", + "00AE EF2E FAAD F9CE 0000 0000 0000 000A" + ] + }, + { + "File": { + "Name": "Scene 7, Room 16", + "Start": "02822000", + "End": "02824880", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000D", + "00D4", + "00DC", + "00F2", + "00CB", + "0190", + "00A8", + "00B7" + ], + "Actors": [ + "0013 1377 FC38 0A9A 0000 8000 0000 0003", + "0013 13E1 FC31 0611 0000 0000 0000 0003", + "0013 163E FC5A 09D8 0000 9555 0000 0003", + "00DD 1605 FB89 0856 0000 C000 0000 FFFF", + "0015 162C FBFC 061D 0000 0000 0000 2003", + "0015 163F FBFC 0635 0000 0000 0000 2103", + "01D1 1625 FB89 0631 0000 0000 0002 380A", + "01D1 1624 FB89 0A7D 0000 0000 0000 3812", + "0117 13E1 FB89 0801 0000 0000 0000 1FC3", + "0117 1426 FB89 090B 0000 0000 0000 1FC3", + "0117 1461 FB89 073C 0000 0000 0000 1FC3", + "0117 1496 FB89 0995 0000 0000 0000 1FC3", + "0117 151C FB89 07B9 0000 0000 0000 1FC3", + "0117 155A FB89 08C3 0000 0000 0000 1FC3", + "0117 1571 FB89 09AC 0000 0000 0000 1FC3", + "0117 15E1 FB89 076A 0000 0000 0000 1FC3", + "0117 1605 FB89 0856 0000 0000 0000 1FC3", + "0117 1623 FBED 0A7E 0000 0000 0000 1FC3", + "0117 1376 FB89 085A 0000 0000 0000 0283", + "00AF 1664 FB89 0856 0000 4000 0000 0303", + "00B1 14C6 FB89 0857 0000 C000 0000 0001", + "000A 1736 FB89 088C 0000 4000 0000 6856", + "000A 1735 FB89 081F 0000 4000 0000 588C" + ] + }, + { + "File": { + "Name": "Scene 7, Room 17", + "Start": "02825000", + "End": "02827CD0", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000B", + "00A6", + "0031", + "012F" + ], + "Actors": [ + "00A4 EF30 FAAD FE36 0000 8000 0000 FFFF", + "0111 EE21 FAAD FCD5 0000 0000 0000 660B", + "0111 F03C FAAD FCD5 0000 0000 0000 680A", + "004C EE50 FAAD FE96 0000 216C 0000 FFFF", + "004C EE64 FAAD FD4A 0000 27D2 0000 FFFF", + "004C EE86 FAAD FE63 0000 D1C7 0000 FFFF", + "004C EE98 FAAD FD9E 0000 DD28 0000 FFFF", + "004C EED2 FAAD FE52 0000 6C17 0000 FFFF", + "004C EEFA FAAD FD44 0000 F99A 0000 FFFF", + "004C EF5D FAAD FD78 0000 149F 0000 FFFF", + "004C EF99 FAAD FEB9 0000 1555 0000 FFFF", + "004C EFB5 FAAD FE02 0000 1777 0000 FFFF", + "004C EFD1 FAAD FE86 0000 A16C 0000 FFFF", + "004C EFD5 FAAD FCF2 0000 22D8 0000 FFFF", + "004C EFEE FAAD FD3B 0000 B8E4 0000 FFFF", + "004C EFF7 FAAD FE35 0000 E444 0000 FFFF", + "000A EF2F FAAD FE95 0000 0000 0000 794D" + ] + }, + { + "File": { + "Name": "Scene 7, Room 18", + "Start": "02828000", + "End": "02835280", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000D", + "0024", + "0085" + ], + "Actors": [ + "0037 0BA9 FC0D 002C 0000 0000 0000 0001", + "0080 0A37 FB4D 0137 0000 0000 0000 0110", + "0080 0B20 FB4D 018C 0000 8000 0000 0210", + "00AE 1124 FAAD FE6A 0000 0000 0000 000B", + "00BC 0BAC FB82 FF5B 0000 0000 0000 0004", + "00BC 0BD2 FB82 0162 0000 C000 0000 0004", + "00BC 0E02 FB82 FF82 0000 C000 0000 0004", + "00BC 0F94 FAE2 0070 0000 8000 0000 0004", + "00BC 105C FAE2 FE93 0000 0000 0000 0004", + "00BC 1124 FAE2 0070 0000 8000 0000 0004" + ] + }, + { + "File": { + "Name": "Scene 7, Room 19", + "Start": "02836000", + "End": "02838D20", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C" + ], + "Actors": [ + "0090 1376 FAAD FF9E 0000 44FA 0000 7F01", + "0090 138C FAAD FF2B 0000 1A50 0000 7F01", + "0090 13A2 FAAD FFCB 0000 5B06 0000 7F01", + "0090 13C5 FAAD FF5C 0000 305B 0000 7F01", + "0095 13F4 FB5D FF82 4000 C000 0000 8801", + "0183 1343 FAAD FF81 0000 0000 0000 FF40", + "0173 13ED FB37 FF82 0000 FFA6 0000 2228", + "000A 13D0 FAAD FFED 0000 4000 0000 6855" + ] + }, + { + "File": { + "Name": "Scene 7, Room 20", + "Start": "02839000", + "End": "0283AE20", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008D", + "0098", + "0024", + "015C" + ], + "Actors": [ + "0090 109D FAAD FBD2 0000 1555 0000 7FFE", + "0090 11AF FAAD FBC7 0000 EAAB 0000 7FFE", + "0095 1063 FAAD FAED 0000 1C72 0000 8808", + "0111 107E FAAD FC6C 0000 0000 0000 5C01", + "0111 11C5 FAAD FC66 0000 0000 0000 640C", + "011D 1086 FAAD FB64 0000 0000 0000 00F6", + "011D 11C3 FAAD FB61 0000 0000 0000 03F7", + "00BE 106F FAC7 FAE1 0000 0000 0000 1302", + "00BE 11D9 FAC7 FD19 0000 8000 0000 1C02", + "000A 11E7 FAAD FD0D 0000 4000 0000 6934", + "000A 1129 FAAD FBCC 0000 8000 0000 7888" + ] + }, + { + "File": { + "Name": "Scene 7, Room 21", + "Start": "0283B000", + "End": "028464B0", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0031", + "011C", + "0032", + "0024", + "015C", + "0154", + "00A8", + "0190", + "00B7" + ], + "Actors": [ + "012D F22A FC15 FC83 0000 4000 0000 0CC1", + "012D F34A FAAD FC8A 0000 0000 0000 0CC1", + "012E 123E FB78 F82B 0000 C000 0001 1CB8", + "0095 0F26 FC4A FA29 0000 4000 0000 0000", + "0037 0F47 FB9D FA32 0000 4000 0000 0002", + "01C9 0F84 FBED F9A0 0000 4000 0003 0539", + "00FF 0F62 FAAD FA32 0000 0000 0000 1D02", + "00FF 117E FA9E F9CE 0000 0000 0000 1DC6", + "0139 117E FA9E F9CE 0000 0000 0000 001D", + "0015 0F83 FBED F94C 0000 0000 0000 2203", + "0015 0F82 FBED F9E8 0000 0000 0000 2303", + "0015 F26F FC15 FC61 0000 0000 0000 3903", + "0015 F271 FC15 FC8C 0000 0000 0000 3A03", + "0015 F3A4 FB4F FD7A 0000 0000 0000 3C03", + "0095 F7FF FA35 FA75 4000 0000 0000 8810", + "01D1 F39E FAAD FD12 0000 0000 0002 B8FF", + "0002 04B9 FC32 F842 0000 0000 0000 0003", + "0002 0ABA FC21 F825 0000 0000 0000 0003", + "0173 F55C FAF3 FDAC 0006 0011 001E 2084", + "0111 F6A0 FAAD FA42 0000 0000 0000 7009", + "0111 F74A FAAD FA42 0000 0000 0000 7609", + "0111 F4D5 FAAD FE0F 0000 0000 0000 7A0A", + "0111 F5C0 FAAD FE14 0000 0000 0000 7C0E", + "012A F230 FC15 FC53 0000 0000 0000 1A00", + "004C F6EF FAAD FCFE 0000 8000 0000 FFFF", + "004C F70D FAAD FC93 0000 8000 0000 FFFF", + "004C F722 FAAD FD19 0000 8000 0000 FFFF", + "004C F736 FAAD FCBD 0000 8000 0000 FFFF", + "004C F74B FAAD FCF3 0000 8000 0000 FFFF", + "012A F39B FAD0 FD44 0000 8000 0000 0C02", + "00BE F72F FAD5 FD45 0000 0000 0000 1000", + "00B0 1282 FA8D F82A 0000 0000 0000 3800", + "000A 0F5A FB4D FAAA 0000 C000 0000 684E" + ] + }, + { + "File": { + "Name": "Scene 7, Room 22", + "Start": "02847000", + "End": "028499A0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 131072, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 41, + "y": -17 + }, + { + "Flag": 7, + "x": 27, + "y": -24 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 81, + "y": -20 + }, + { + "Flag": 3, + "x": 74, + "y": -37 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 12, + "x": 96, + "y": -51 + }, + { + "Flag": 16, + "x": 46, + "y": -42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 12, + "IconPoints": [ + { + "Flag": 4, + "x": 43, + "y": -66 + }, + { + "Flag": 5, + "x": 37, + "y": -66 + }, + { + "Flag": 6, + "x": 33, + "y": -72 + }, + { + "Flag": 8, + "x": 85, + "y": -18 + }, + { + "Flag": 9, + "x": 61, + "y": -42 + }, + { + "Flag": 10, + "x": 15, + "y": -4 + }, + { + "Flag": 11, + "x": 25, + "y": -4 + }, + { + "Flag": 13, + "x": 19, + "y": -29 + }, + { + "Flag": 14, + "x": 78, + "y": -15 + }, + { + "Flag": 15, + "x": 60, + "y": -70 + }, + { + "Flag": 21, + "x": 92, + "y": -29 + }, + { + "Flag": 20, + "x": 87, + "y": -20 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 31, + "y": -45 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 77, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 77, + "y": 76 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 76, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 83, + "y": 67 + }, + { + "Flag": 14, + "x": 84, + "y": 59 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 76, + "y": 67 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 4, + "x": 78, + "y": 62 + }, + { + "Flag": 5, + "x": 74, + "y": 62 + }, + { + "Flag": 6, + "x": 71, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 77, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 10, + "x": 71, + "y": 65 + }, + { + "Flag": 11, + "x": 80, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 16, + "x": 73, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 12, + "x": 87, + "y": 64 + }, + { + "Flag": 22, + "x": 87, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 13, + "x": 77, + "y": 66 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 21, + "x": 78, + "y": 66 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 8, + "x": 76, + "y": 66 + }, + { + "Flag": 20, + "x": 78, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 14, + "x": 77, + "y": 62 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 15, + "x": 56, + "y": 67 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 16, + "x": 73, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 14, + "x": 77, + "y": 62 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 8", + "Start": "032C6000", + "End": "032D2560", + "RemapStart": null + }, + "Id": 8, + "TActors": [ + "01FF 00FF 002E FC86 0000 FF9C 0000 009F", + "03FF 00FF 002E 0366 0000 FCA4 0000 02D5", + "03FF 00FF 002E 0474 0000 FA74 8000 00BB", + "05FF 00FF 002E 01C2 0000 FC7C 0000 008A", + "06FF 00FF 002E FE66 0000 FC7C 0000 008C", + "00FF 02FF 002E F9DE 0000 FD1C C000 02D4", + "00FF 04FF 002E 0384 FFEC 00D2 4000 0056", + "00FF 01FF 0023 FECA FEE8 FDE4 0000 00BF", + "00FF 01FF 0023 FC7C FEE8 FA24 0000 00BF", + "00FF 01FF 0023 0000 FF10 FD1C 0000 00BF", + "05FF 01FF 0023 0172 FEE8 FB82 0000 00BF", + "00FF 01FF 0023 0280 FEE8 FA10 0000 00BF", + "03FF 01FF 0023 044C FEE8 FB28 C000 00BF", + "03FF 01FF 0023 0384 FEE8 FBB4 C000 00BF", + "03FF 01FF 0023 0410 FEE8 FC7C C000 00BF" + ], + "Paths": [ + { + "Points": [ + [ + 847, + -391, + -1432 + ], + [ + 565, + -654, + -1240 + ], + [ + 123, + -664, + -1109 + ], + [ + -41, + -645, + -634 + ], + [ + -8, + -654, + -282 + ], + [ + 75, + -645, + 29 + ] + ] + }, + { + "Points": [ + [ + 1286, + -391, + -1123 + ], + [ + 1066, + -673, + -1077 + ], + [ + 834, + -654, + -841 + ], + [ + 443, + -645, + -757 + ], + [ + 249, + -654, + -459 + ], + [ + 107, + -664, + -158 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 8, Room 0", + "Start": "032D3000", + "End": "032E85F0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "0095 0455 0048 FD27 0000 C000 0000 0000", + "0095 0456 0068 FCEC 0000 C000 0000 0000", + "0037 FEC9 00A0 FE67 0000 C000 0000 0001", + "0011 FFFE 0000 FD1A 0000 0000 0000 0001", + "0090 001D 0000 0254 0000 DC72 0000 7F02", + "0112 FD92 0062 F9EF 0000 0000 0004 18BF", + "0112 FD92 0062 F9EF 0000 0000 0004 18BF", + "0112 027F 0060 F9EE 0000 0000 0004 18BF", + "0112 FD92 0062 F9EF 0000 0000 0004 19FF", + "0112 027F 0061 F9EC 0000 0000 0004 19FF", + "0112 FD92 0062 F9EF 0000 0000 0004 1AFF", + "0112 027F 0061 F9ED 0000 0000 0004 1AFF", + "0112 027F 0061 F9EE 0000 0000 0004 1AFF", + "0183 0153 0000 FE4B 0000 0000 0000 FF40", + "012A 0064 0058 F967 2EEF CAAB 0000 0303", + "00D7 0000 0000 FD1C 0000 0000 0000 0003", + "000A 0001 0000 FCE1 0000 0000 0000 0823", + "01BB 020F 0000 FF49 0000 4000 0000 0FC5", + "012A FE84 0056 FF61 0000 C000 0000 0502", + "0127 FDE3 0000 FE6C 0000 0000 0000 0006", + "0127 FDF7 0000 FE9F 0000 0000 0000 0007", + "01BB 0002 FFF6 FD44 C000 0000 0000 0FC8", + "012A 0452 0000 FCD0 0000 0000 0000 0800", + "01BB FC7C FFF6 F9E8 4000 0000 0000 0FC9", + "012A 015B 0074 FEC0 4000 8000 0000 0A03", + "005E 017B 0000 FCB6 0000 0000 0000 03CA", + "0127 FE8E 0032 FF60 0000 0000 0000 000B", + "005E FEC6 0000 FCBE 0000 0000 0000 03CC", + "012A FF34 0000 FDE0 0000 0000 0000 0C00", + "012E 000A FFF6 FA08 0000 8000 0001 1C8D", + "01BB FE0C 0000 FD1C 0000 C000 0000 0FCD", + "01BB 0000 0000 FB00 0000 8000 0000 0FCD", + "01BB 0000 0000 FED4 0000 0000 0000 0FCD", + "01BB 021C 0000 FD1C 0000 4000 0000 0FCD", + "0185 000A 0000 FA22 0000 0000 000B 8ACD", + "011B 0003 0000 FD4C 0032 0000 0004 2091", + "0015 FFAD FF24 FEA2 0000 0000 0000 2103", + "0015 FFAD FF24 FEEE 0000 0000 0000 2203", + "00BE 0427 0018 FCF0 0000 C000 0000 2502", + "00BE FFC0 000A 03D7 0000 4000 0000 2602", + "0111 0153 0000 FE87 0000 0000 0000 4E09", + "00BE 00CA 0018 0155 0000 8000 0000 2702", + "0111 01A0 0000 FE87 0000 0000 0000 500B", + "00BE FBC8 0018 FA3B 0000 0000 0000 2802", + "0111 010D 0000 FE88 0000 0000 0000 5203", + "00BE FF38 0018 FF3B 0000 0000 0000 2902", + "0111 01A5 0000 FF52 0000 0000 0000 5412", + "00BE FA1D 0010 FCB0 0000 0000 0000 2A02", + "00BE 0345 0000 012C 0000 8000 0000 2B02", + "00BE FFC3 FFB3 F99A 0000 0000 0000 2C02", + "00BE FB74 FF4E FD7C 0000 8000 0000 2D02", + "0173 FC38 003B 0057 0002 0000 0000 2E26", + "0173 FFBE 003E 01BB 0004 0000 0001 2F26", + "012A 04E2 0074 FA31 C000 4000 0000 3B03" + ] + }, + { + "File": { + "Name": "Scene 8, Room 1", + "Start": "032E9000", + "End": "032F42D0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "003B FECA FD20 FF5F 0000 0000 0000 0008", + "0037 FC82 FDF8 FB73 0000 1333 0000 0002", + "0037 FD15 FDF8 FC38 0000 1A50 0000 0002", + "0037 FD3F FDE9 FD00 0000 13E9 0000 0002", + "0011 FFE6 FD92 FEBC 0000 0000 0000 0000", + "0090 0238 FD30 005A 0000 2C17 0000 7F02", + "0090 025B FD30 0022 0000 305B 0000 7F02", + "0090 0276 FD30 0080 0000 E889 0000 7F02", + "0090 028B FD30 00AD 0000 A5B0 0000 7F02", + "0090 02CC FD30 00A7 0000 9555 0000 7F02", + "0008 FDAC FD6E FEA2 0000 0000 0000 03F7", + "0008 FDAD FD6E FF06 0000 0000 0000 03F7", + "0008 0000 FD30 0009 0000 0000 0000 03F7", + "0008 012B FD30 FFC0 0000 0000 0000 03F7", + "0008 01AB FD30 00BC 0000 0000 0000 03F7", + "0008 02B5 FD30 FFEF 0000 0000 0000 03F7", + "0008 02F6 FD30 0059 0000 0000 0000 03F7", + "0183 027F FD30 FA4E 0000 0000 0000 FF40", + "0130 0352 FE6F FA65 0000 0000 0001 0D00", + "0130 0504 FE5C FB9E 0000 0000 0001 0D01", + "0095 FC76 FD30 FA29 0000 0000 0000 8901", + "000A 02D4 FD30 0021 0000 582E 000E B141", + "012A 0061 FDD0 FCF3 0000 F111 0000 0E00", + "011B 0004 FDD0 FD12 001E 0000 0004 2091", + "011B FECB FD25 FDDF 001E 0000 0004 2091", + "011B 0171 FD30 FB82 001E 0000 0004 2091", + "011B 0281 FD30 FA13 001E 0000 0004 2091", + "0015 043B FD30 FB6A 0000 0000 0000 3C03", + "0015 0414 FD30 FB39 0000 0000 0000 3D03", + "0015 045A FD30 FB39 0000 0000 0000 3E03" + ] + }, + { + "File": { + "Name": "Scene 8, Room 2", + "Start": "032F5000", + "End": "032F8190", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "008D", + "0187", + "000E", + "015C", + "0098", + "0024", + "00A4", + "0009" + ], + "Actors": [ + "0090 F927 0000 FD1E 0000 4000 0000 7FFE", + "000D F6DB 0032 FD91 0000 0000 0000 0000", + "005E F7DB 0000 FC40 0000 0000 0000 2400", + "0095 F612 0000 FC6A 0000 0000 0000 8904", + "005E F8A3 0000 FC40 0000 0000 0000 100F", + "00BD F84E 0028 FCE0 0000 8000 0000 010F", + "005E F7DB 0000 FDF8 0000 0000 0000 1010", + "00BD F7B8 0028 FD58 0000 0000 0000 0110", + "005E F713 0000 FC40 0000 0000 0000 1011", + "00BD F6BE 0028 FCE0 0000 8000 0000 0111", + "0015 F867 000A FCA1 0000 0000 0000 2003", + "0015 F7A1 000A FD93 0000 0000 0000 2303" + ] + }, + { + "File": { + "Name": "Scene 8, Room 3", + "Start": "032F9000", + "End": "032FAC60", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "0011 03EC 00B1 FBD6 0000 0000 0000 0000", + "008E 03E6 0000 FC11 0000 6AAB 0000 0000", + "01BB 02E4 FFF6 FB50 4000 4000 0000 0FFF", + "01BB 02E4 FFF6 FBC8 4000 4000 0000 0FFF", + "01BB 0370 FFF6 FC5E 4000 4000 0000 0FFF", + "01BB 03AC FFF6 FB3C 4000 4000 0000 0FFF", + "01BB 03D4 FFF6 FB50 4000 C000 0000 0FFF", + "01BB 03D4 FFF6 FBC8 4000 C000 0000 0FFF", + "01BB 0460 FFF6 FC5E 4000 C000 0000 0FFF", + "01BB 049C FFF6 FB3C 4000 C000 0000 0FFF", + "011B 0473 0000 FAA9 001E 0000 0004 2291", + "011B 0364 0000 FC80 001E 0000 0004 2291" + ] + }, + { + "File": { + "Name": "Scene 8, Room 4", + "Start": "032FB000", + "End": "032FD450", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "008D", + "0187", + "000E", + "00A6", + "012B" + ], + "Actors": [ + "0125 05B2 FFEC FF7E 0000 0000 0000 FF01", + "0125 05D4 FFEC FFCF 0000 0000 0000 FF01", + "0125 05F9 FFEC 0002 0000 0000 0000 FF01", + "0125 0644 FFEC 0003 0000 0000 0000 FF01", + "00A5 0464 FFEC 003A 0000 C000 0000 FFFF", + "00A5 0464 FFEC 0173 0000 C000 0000 FFFF", + "00A5 059D FFEC 0036 0000 C000 0000 FFFF", + "00A5 059D FFEC 0170 0000 C000 0000 FFFF", + "00A4 04FC FFF0 00D1 0000 C000 0000 FFFF", + "0015 0644 FFEC FFA8 0000 0000 0000 0211", + "000A 0524 FFEC 0079 0000 C000 0000 1802", + "00BE 062C 0000 FFA6 0000 C000 0000 2102" + ] + }, + { + "File": { + "Name": "Scene 8, Room 5", + "Start": "032FE000", + "End": "03300960", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "0112 00A0 0061 FB05 0000 0000 0004 18BF", + "0112 00A0 0061 FB05 0000 0000 0004 18BF", + "0112 00A0 0061 FB05 0000 0000 0004 19FF", + "0112 00A0 0061 FB05 0000 0000 0004 1AFF", + "00AE 017C 0000 FB32 0000 0000 0000 0002", + "0015 008C 0000 FB3E 0000 0000 0000 0111", + "0111 0120 0000 FB28 0000 0000 0000 4803", + "0111 01B6 0000 FB2E 0000 0000 0000 4A03", + "0111 01BC 0000 FBA6 0000 0000 0000 4C03" + ] + }, + { + "File": { + "Name": "Scene 8, Room 6", + "Start": "03301000", + "End": "03303E80", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "008D", + "0187", + "00A2", + "000D", + "0024", + "00AA", + "015C" + ], + "Actors": [ + "0013 FE98 0023 FBB1 0000 4000 0000 8003", + "0013 FEB3 001A FB92 0000 0000 0000 8003", + "0013 FED9 001F FBAC 0000 C000 0000 8003", + "0037 FE52 0000 FBB5 0000 0000 0000 0002", + "0037 FEB4 0000 FC1B 0000 0000 0000 0002", + "009D FEB7 0000 FBC3 0000 0000 0000 0000", + "0095 FEB6 0000 FBB9 0000 0000 0000 8902" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 6, + "Type": 1, + "Flags": 0 + }, + { + "Id": 10, + "Type": 1, + "Flags": 0 + }, + { + "Id": 16, + "Type": 2, + "Flags": 0 + }, + { + "Id": 17, + "Type": 2, + "Flags": 0 + }, + { + "Id": 18, + "Type": 2, + "Flags": 0 + }, + { + "Id": 19, + "Type": 2, + "Flags": 0 + }, + { + "Id": 20, + "Type": 2, + "Flags": 0 + }, + { + "Id": 21, + "Type": 2, + "Flags": 0 + }, + { + "Id": 22, + "Type": 3, + "Flags": 0 + }, + { + "Id": 23, + "Type": 3, + "Flags": 0 + }, + { + "Id": 24, + "Type": 3, + "Flags": 0 + }, + { + "Id": 25, + "Type": 3, + "Flags": 0 + }, + { + "Id": 26, + "Type": 3, + "Flags": 0 + }, + { + "Id": 27, + "Type": 3, + "Flags": 0 + }, + { + "Id": 28, + "Type": 3, + "Flags": 0 + }, + { + "Id": 29, + "Type": 4, + "Flags": 0 + }, + { + "Id": 30, + "Type": 4, + "Flags": 0 + }, + { + "Id": 31, + "Type": 4, + "Flags": 0 + }, + { + "Id": 32, + "Type": 4, + "Flags": 0 + }, + { + "Id": 33, + "Type": 4, + "Flags": 0 + }, + { + "Id": 34, + "Type": 4, + "Flags": 0 + }, + { + "Id": 35, + "Type": 5, + "Flags": 0 + }, + { + "Id": 36, + "Type": 5, + "Flags": 0 + }, + { + "Id": 37, + "Type": 6, + "Flags": 0 + }, + { + "Id": 38, + "Type": 6, + "Flags": 0 + }, + { + "Id": 39, + "Type": 7, + "Flags": 0 + }, + { + "Id": 40, + "Type": 7, + "Flags": 0 + }, + { + "Id": 41, + "Type": 8, + "Flags": 0 + }, + { + "Id": 42, + "Type": 8, + "Flags": 0 + }, + { + "Id": 43, + "Type": 7, + "Flags": 0 + }, + { + "Id": 44, + "Type": 7, + "Flags": 0 + }, + { + "Id": 45, + "Type": 9, + "Flags": 0 + }, + { + "Id": 46, + "Type": 9, + "Flags": 0 + }, + { + "Id": 47, + "Type": 10, + "Flags": 0 + }, + { + "Id": 48, + "Type": 10, + "Flags": 0 + }, + { + "Id": 49, + "Type": 11, + "Flags": 0 + }, + { + "Id": 50, + "Type": 11, + "Flags": 0 + }, + { + "Id": 51, + "Type": 8, + "Flags": 0 + }, + { + "Id": 52, + "Type": 8, + "Flags": 0 + }, + { + "Id": 53, + "Type": 7, + "Flags": 0 + }, + { + "Id": 54, + "Type": 7, + "Flags": 0 + }, + { + "Id": 55, + "Type": 12, + "Flags": 0 + }, + { + "Id": 56, + "Type": 12, + "Flags": 0 + }, + { + "Id": 57, + "Type": 7, + "Flags": 0 + }, + { + "Id": 58, + "Type": 7, + "Flags": 0 + }, + { + "Id": 59, + "Type": 5, + "Flags": 0 + }, + { + "Id": 60, + "Type": 5, + "Flags": 0 + }, + { + "Id": 61, + "Type": 13, + "Flags": 0 + }, + { + "Id": 62, + "Type": 13, + "Flags": 0 + }, + { + "Id": 63, + "Type": 14, + "Flags": 0 + }, + { + "Id": 64, + "Type": 14, + "Flags": 0 + }, + { + "Id": 65, + "Type": 5, + "Flags": 0 + }, + { + "Id": 66, + "Type": 5, + "Flags": 0 + }, + { + "Id": 67, + "Type": 15, + "Flags": 0 + }, + { + "Id": 68, + "Type": 15, + "Flags": 0 + }, + { + "Id": 69, + "Type": 16, + "Flags": 0 + }, + { + "Id": 70, + "Type": 16, + "Flags": 0 + }, + { + "Id": 71, + "Type": 5, + "Flags": 0 + }, + { + "Id": 72, + "Type": 5, + "Flags": 0 + }, + { + "Id": 73, + "Type": 5, + "Flags": 0 + }, + { + "Id": 74, + "Type": 5, + "Flags": 0 + }, + { + "Id": 75, + "Type": 17, + "Flags": 0 + }, + { + "Id": 76, + "Type": 17, + "Flags": 0 + }, + { + "Id": 77, + "Type": 6, + "Flags": 0 + }, + { + "Id": 78, + "Type": 6, + "Flags": 0 + }, + { + "Id": 79, + "Type": 5, + "Flags": 0 + }, + { + "Id": 80, + "Type": 5, + "Flags": 0 + }, + { + "Id": 81, + "Type": 5, + "Flags": 0 + }, + { + "Id": 82, + "Type": 5, + "Flags": 0 + }, + { + "Id": 83, + "Type": 7, + "Flags": 0 + }, + { + "Id": 84, + "Type": 7, + "Flags": 0 + }, + { + "Id": 85, + "Type": 7, + "Flags": 0 + }, + { + "Id": 86, + "Type": 7, + "Flags": 0 + }, + { + "Id": 87, + "Type": 7, + "Flags": 0 + }, + { + "Id": 88, + "Type": 7, + "Flags": 0 + }, + { + "Id": 89, + "Type": 7, + "Flags": 0 + }, + { + "Id": 90, + "Type": 7, + "Flags": 0 + }, + { + "Id": 91, + "Type": 7, + "Flags": 0 + }, + { + "Id": 92, + "Type": 7, + "Flags": 0 + }, + { + "Id": 93, + "Type": 7, + "Flags": 0 + }, + { + "Id": 94, + "Type": 7, + "Flags": 0 + }, + { + "Id": 95, + "Type": 7, + "Flags": 0 + }, + { + "Id": 96, + "Type": 7, + "Flags": 0 + }, + { + "Id": 97, + "Type": 18, + "Flags": 1 + }, + { + "Id": 98, + "Type": 18, + "Flags": 1 + }, + { + "Id": 99, + "Type": 19, + "Flags": 1 + }, + { + "Id": 100, + "Type": 19, + "Flags": 1 + }, + { + "Id": 101, + "Type": 7, + "Flags": 0 + }, + { + "Id": 102, + "Type": 7, + "Flags": 0 + }, + { + "Id": 103, + "Type": 7, + "Flags": 0 + }, + { + "Id": 104, + "Type": 7, + "Flags": 0 + }, + { + "Id": 105, + "Type": 7, + "Flags": 0 + }, + { + "Id": 106, + "Type": 7, + "Flags": 0 + }, + { + "Id": 107, + "Type": 7, + "Flags": 0 + }, + { + "Id": 108, + "Type": 7, + "Flags": 0 + }, + { + "Id": 109, + "Type": 7, + "Flags": 0 + }, + { + "Id": 110, + "Type": 7, + "Flags": 0 + }, + { + "Id": 111, + "Type": 7, + "Flags": 0 + }, + { + "Id": 112, + "Type": 7, + "Flags": 0 + }, + { + "Id": 113, + "Type": 7, + "Flags": 0 + }, + { + "Id": 114, + "Type": 7, + "Flags": 0 + }, + { + "Id": 115, + "Type": 7, + "Flags": 0 + }, + { + "Id": 116, + "Type": 7, + "Flags": 0 + }, + { + "Id": 117, + "Type": 7, + "Flags": 0 + }, + { + "Id": 118, + "Type": 7, + "Flags": 0 + }, + { + "Id": 119, + "Type": 7, + "Flags": 0 + }, + { + "Id": 120, + "Type": 7, + "Flags": 0 + }, + { + "Id": 121, + "Type": 7, + "Flags": 0 + }, + { + "Id": 122, + "Type": 7, + "Flags": 0 + }, + { + "Id": 123, + "Type": 7, + "Flags": 1 + }, + { + "Id": 124, + "Type": 7, + "Flags": 1 + }, + { + "Id": 125, + "Type": 7, + "Flags": 1 + }, + { + "Id": 126, + "Type": 7, + "Flags": 1 + }, + { + "Id": 127, + "Type": 7, + "Flags": 1 + }, + { + "Id": 128, + "Type": 7, + "Flags": 1 + }, + { + "Id": 129, + "Type": 7, + "Flags": 1 + }, + { + "Id": 130, + "Type": 7, + "Flags": 1 + }, + { + "Id": 131, + "Type": 7, + "Flags": 0 + }, + { + "Id": 132, + "Type": 7, + "Flags": 0 + }, + { + "Id": 133, + "Type": 7, + "Flags": 0 + }, + { + "Id": 134, + "Type": 7, + "Flags": 0 + }, + { + "Id": 135, + "Type": 7, + "Flags": 1 + }, + { + "Id": 136, + "Type": 7, + "Flags": 1 + }, + { + "Id": 137, + "Type": 7, + "Flags": 1 + }, + { + "Id": 138, + "Type": 7, + "Flags": 1 + }, + { + "Id": 139, + "Type": 7, + "Flags": 1 + }, + { + "Id": 140, + "Type": 7, + "Flags": 1 + }, + { + "Id": 141, + "Type": 7, + "Flags": 1 + }, + { + "Id": 142, + "Type": 7, + "Flags": 1 + }, + { + "Id": 143, + "Type": 7, + "Flags": 1 + }, + { + "Id": 144, + "Type": 7, + "Flags": 1 + }, + { + "Id": 145, + "Type": 7, + "Flags": 1 + }, + { + "Id": 146, + "Type": 7, + "Flags": 1 + }, + { + "Id": 147, + "Type": 7, + "Flags": 1 + }, + { + "Id": 148, + "Type": 7, + "Flags": 1 + }, + { + "Id": 149, + "Type": 7, + "Flags": 1 + }, + { + "Id": 150, + "Type": 7, + "Flags": 1 + }, + { + "Id": 151, + "Type": 7, + "Flags": 1 + }, + { + "Id": 152, + "Type": 7, + "Flags": 1 + }, + { + "Id": 153, + "Type": 7, + "Flags": 1 + }, + { + "Id": 154, + "Type": 7, + "Flags": 1 + }, + { + "Id": 155, + "Type": 7, + "Flags": 0 + }, + { + "Id": 156, + "Type": 7, + "Flags": 0 + }, + { + "Id": 157, + "Type": 7, + "Flags": 0 + }, + { + "Id": 158, + "Type": 7, + "Flags": 0 + }, + { + "Id": 159, + "Type": 7, + "Flags": 1 + }, + { + "Id": 160, + "Type": 7, + "Flags": 1 + }, + { + "Id": 161, + "Type": 7, + "Flags": 1 + }, + { + "Id": 162, + "Type": 7, + "Flags": 1 + }, + { + "Id": 163, + "Type": 7, + "Flags": 0 + }, + { + "Id": 164, + "Type": 7, + "Flags": 0 + }, + { + "Id": 165, + "Type": 7, + "Flags": 1 + }, + { + "Id": 166, + "Type": 7, + "Flags": 1 + }, + { + "Id": 167, + "Type": 20, + "Flags": 0 + }, + { + "Id": 168, + "Type": 20, + "Flags": 0 + }, + { + "Id": 169, + "Type": 20, + "Flags": 0 + }, + { + "Id": 170, + "Type": 20, + "Flags": 0 + }, + { + "Id": 171, + "Type": 20, + "Flags": 0 + }, + { + "Id": 172, + "Type": 20, + "Flags": 0 + }, + { + "Id": 173, + "Type": 20, + "Flags": 0 + }, + { + "Id": 174, + "Type": 20, + "Flags": 0 + }, + { + "Id": 175, + "Type": 20, + "Flags": 0 + }, + { + "Id": 176, + "Type": 20, + "Flags": 0 + }, + { + "Id": 177, + "Type": 20, + "Flags": 0 + }, + { + "Id": 178, + "Type": 20, + "Flags": 0 + }, + { + "Id": 179, + "Type": 20, + "Flags": 0 + }, + { + "Id": 180, + "Type": 20, + "Flags": 0 + }, + { + "Id": 181, + "Type": 20, + "Flags": 0 + }, + { + "Id": 182, + "Type": 20, + "Flags": 0 + }, + { + "Id": 183, + "Type": 20, + "Flags": 0 + }, + { + "Id": 184, + "Type": 20, + "Flags": 0 + }, + { + "Id": 185, + "Type": 20, + "Flags": 0 + }, + { + "Id": 186, + "Type": 20, + "Flags": 0 + }, + { + "Id": 187, + "Type": 20, + "Flags": 0 + }, + { + "Id": 188, + "Type": 20, + "Flags": 0 + }, + { + "Id": 189, + "Type": 20, + "Flags": 0 + }, + { + "Id": 190, + "Type": 20, + "Flags": 0 + }, + { + "Id": 191, + "Type": 20, + "Flags": 0 + }, + { + "Id": 192, + "Type": 20, + "Flags": 0 + }, + { + "Id": 193, + "Type": 20, + "Flags": 0 + }, + { + "Id": 194, + "Type": 20, + "Flags": 0 + }, + { + "Id": 195, + "Type": 20, + "Flags": 0 + }, + { + "Id": 196, + "Type": 20, + "Flags": 0 + }, + { + "Id": 197, + "Type": 20, + "Flags": 0 + }, + { + "Id": 198, + "Type": 20, + "Flags": 0 + }, + { + "Id": 199, + "Type": 7, + "Flags": 0 + }, + { + "Id": 200, + "Type": 7, + "Flags": 0 + }, + { + "Id": 201, + "Type": 7, + "Flags": 0 + }, + { + "Id": 202, + "Type": 7, + "Flags": 0 + }, + { + "Id": 203, + "Type": 7, + "Flags": 0 + }, + { + "Id": 204, + "Type": 7, + "Flags": 0 + }, + { + "Id": 205, + "Type": 7, + "Flags": 0 + }, + { + "Id": 206, + "Type": 21, + "Flags": 0 + }, + { + "Id": 207, + "Type": 8, + "Flags": 0 + }, + { + "Id": 208, + "Type": 8, + "Flags": 0 + }, + { + "Id": 209, + "Type": 7, + "Flags": 0 + }, + { + "Id": 210, + "Type": 7, + "Flags": 0 + }, + { + "Id": 211, + "Type": 7, + "Flags": 0 + }, + { + "Id": 212, + "Type": 7, + "Flags": 0 + }, + { + "Id": 213, + "Type": 7, + "Flags": 0 + }, + { + "Id": 214, + "Type": 7, + "Flags": 0 + }, + { + "Id": 215, + "Type": 7, + "Flags": 0 + }, + { + "Id": 216, + "Type": 7, + "Flags": 0 + }, + { + "Id": 217, + "Type": 7, + "Flags": 0 + }, + { + "Id": 218, + "Type": 7, + "Flags": 0 + }, + { + "Id": 219, + "Type": 7, + "Flags": 0 + }, + { + "Id": 220, + "Type": 7, + "Flags": 0 + }, + { + "Id": 221, + "Type": 22, + "Flags": 0 + }, + { + "Id": 222, + "Type": 22, + "Flags": 0 + }, + { + "Id": 223, + "Type": 22, + "Flags": 0 + }, + { + "Id": 224, + "Type": 22, + "Flags": 0 + }, + { + "Id": 225, + "Type": 7, + "Flags": 0 + }, + { + "Id": 226, + "Type": 7, + "Flags": 0 + }, + { + "Id": 227, + "Type": 7, + "Flags": 0 + }, + { + "Id": 228, + "Type": 7, + "Flags": 0 + }, + { + "Id": 229, + "Type": 7, + "Flags": 0 + }, + { + "Id": 230, + "Type": 7, + "Flags": 0 + }, + { + "Id": 231, + "Type": 7, + "Flags": 0 + }, + { + "Id": 232, + "Type": 7, + "Flags": 0 + }, + { + "Id": 233, + "Type": 22, + "Flags": 0 + }, + { + "Id": 234, + "Type": 22, + "Flags": 0 + }, + { + "Id": 235, + "Type": 7, + "Flags": 0 + }, + { + "Id": 236, + "Type": 7, + "Flags": 0 + }, + { + "Id": 237, + "Type": 7, + "Flags": 0 + }, + { + "Id": 238, + "Type": 7, + "Flags": 0 + }, + { + "Id": 239, + "Type": 7, + "Flags": 0 + }, + { + "Id": 240, + "Type": 7, + "Flags": 0 + }, + { + "Id": 241, + "Type": 7, + "Flags": 0 + }, + { + "Id": 242, + "Type": 7, + "Flags": 0 + }, + { + "Id": 243, + "Type": 7, + "Flags": 0 + }, + { + "Id": 244, + "Type": 7, + "Flags": 0 + }, + { + "Id": 245, + "Type": 7, + "Flags": 0 + }, + { + "Id": 246, + "Type": 7, + "Flags": 0 + }, + { + "Id": 247, + "Type": 7, + "Flags": 0 + }, + { + "Id": 248, + "Type": 7, + "Flags": 0 + }, + { + "Id": 249, + "Type": 22, + "Flags": 0 + }, + { + "Id": 250, + "Type": 22, + "Flags": 0 + }, + { + "Id": 251, + "Type": 7, + "Flags": 0 + }, + { + "Id": 252, + "Type": 7, + "Flags": 0 + }, + { + "Id": 253, + "Type": 7, + "Flags": 0 + }, + { + "Id": 254, + "Type": 7, + "Flags": 0 + }, + { + "Id": 255, + "Type": 7, + "Flags": 0 + }, + { + "Id": 256, + "Type": 7, + "Flags": 0 + }, + { + "Id": 257, + "Type": 7, + "Flags": 0 + }, + { + "Id": 258, + "Type": 7, + "Flags": 0 + }, + { + "Id": 259, + "Type": 7, + "Flags": 0 + }, + { + "Id": 260, + "Type": 7, + "Flags": 0 + }, + { + "Id": 261, + "Type": 7, + "Flags": 0 + }, + { + "Id": 262, + "Type": 7, + "Flags": 0 + }, + { + "Id": 263, + "Type": 23, + "Flags": 0 + }, + { + "Id": 264, + "Type": 23, + "Flags": 0 + }, + { + "Id": 265, + "Type": 24, + "Flags": 0 + }, + { + "Id": 266, + "Type": 24, + "Flags": 0 + }, + { + "Id": 267, + "Type": 23, + "Flags": 0 + }, + { + "Id": 268, + "Type": 23, + "Flags": 0 + }, + { + "Id": 269, + "Type": 24, + "Flags": 0 + }, + { + "Id": 270, + "Type": 24, + "Flags": 0 + }, + { + "Id": 271, + "Type": 23, + "Flags": 0 + }, + { + "Id": 272, + "Type": 23, + "Flags": 0 + }, + { + "Id": 273, + "Type": 7, + "Flags": 0 + }, + { + "Id": 274, + "Type": 7, + "Flags": 0 + }, + { + "Id": 275, + "Type": 7, + "Flags": 0 + }, + { + "Id": 276, + "Type": 7, + "Flags": 0 + }, + { + "Id": 277, + "Type": 7, + "Flags": 0 + }, + { + "Id": 278, + "Type": 7, + "Flags": 0 + }, + { + "Id": 279, + "Type": 7, + "Flags": 0 + }, + { + "Id": 280, + "Type": 7, + "Flags": 0 + }, + { + "Id": 281, + "Type": 7, + "Flags": 0 + }, + { + "Id": 282, + "Type": 7, + "Flags": 0 + }, + { + "Id": 283, + "Type": 23, + "Flags": 0 + }, + { + "Id": 284, + "Type": 23, + "Flags": 0 + }, + { + "Id": 285, + "Type": 25, + "Flags": 0 + }, + { + "Id": 286, + "Type": 25, + "Flags": 0 + }, + { + "Id": 287, + "Type": 7, + "Flags": 0 + }, + { + "Id": 288, + "Type": 7, + "Flags": 0 + }, + { + "Id": 289, + "Type": 7, + "Flags": 0 + }, + { + "Id": 290, + "Type": 7, + "Flags": 0 + }, + { + "Id": 291, + "Type": 25, + "Flags": 0 + }, + { + "Id": 292, + "Type": 25, + "Flags": 0 + }, + { + "Id": 293, + "Type": 23, + "Flags": 0 + }, + { + "Id": 294, + "Type": 23, + "Flags": 0 + }, + { + "Id": 295, + "Type": 23, + "Flags": 0 + }, + { + "Id": 296, + "Type": 23, + "Flags": 0 + }, + { + "Id": 297, + "Type": 24, + "Flags": 0 + }, + { + "Id": 298, + "Type": 24, + "Flags": 0 + }, + { + "Id": 299, + "Type": 7, + "Flags": 0 + }, + { + "Id": 300, + "Type": 7, + "Flags": 0 + }, + { + "Id": 301, + "Type": 23, + "Flags": 0 + }, + { + "Id": 302, + "Type": 23, + "Flags": 0 + }, + { + "Id": 303, + "Type": 7, + "Flags": 0 + }, + { + "Id": 304, + "Type": 7, + "Flags": 0 + }, + { + "Id": 305, + "Type": 7, + "Flags": 0 + }, + { + "Id": 306, + "Type": 7, + "Flags": 0 + }, + { + "Id": 307, + "Type": 7, + "Flags": 0 + }, + { + "Id": 308, + "Type": 7, + "Flags": 0 + }, + { + "Id": 309, + "Type": 7, + "Flags": 0 + }, + { + "Id": 310, + "Type": 7, + "Flags": 0 + }, + { + "Id": 311, + "Type": 7, + "Flags": 0 + }, + { + "Id": 312, + "Type": 7, + "Flags": 0 + }, + { + "Id": 313, + "Type": 7, + "Flags": 0 + }, + { + "Id": 314, + "Type": 7, + "Flags": 0 + }, + { + "Id": 315, + "Type": 7, + "Flags": 0 + }, + { + "Id": 316, + "Type": 7, + "Flags": 0 + }, + { + "Id": 317, + "Type": 7, + "Flags": 0 + }, + { + "Id": 318, + "Type": 7, + "Flags": 0 + }, + { + "Id": 319, + "Type": 7, + "Flags": 0 + }, + { + "Id": 320, + "Type": 7, + "Flags": 0 + }, + { + "Id": 321, + "Type": 23, + "Flags": 0 + }, + { + "Id": 322, + "Type": 23, + "Flags": 0 + }, + { + "Id": 323, + "Type": 25, + "Flags": 0 + }, + { + "Id": 324, + "Type": 25, + "Flags": 0 + }, + { + "Id": 325, + "Type": 23, + "Flags": 0 + }, + { + "Id": 326, + "Type": 23, + "Flags": 0 + }, + { + "Id": 327, + "Type": 25, + "Flags": 0 + }, + { + "Id": 328, + "Type": 25, + "Flags": 0 + }, + { + "Id": 329, + "Type": 23, + "Flags": 0 + }, + { + "Id": 330, + "Type": 23, + "Flags": 0 + }, + { + "Id": 331, + "Type": 23, + "Flags": 0 + }, + { + "Id": 332, + "Type": 23, + "Flags": 0 + }, + { + "Id": 333, + "Type": 26, + "Flags": 0 + }, + { + "Id": 334, + "Type": 26, + "Flags": 0 + }, + { + "Id": 335, + "Type": 7, + "Flags": 0 + }, + { + "Id": 336, + "Type": 7, + "Flags": 0 + }, + { + "Id": 337, + "Type": 7, + "Flags": 0 + }, + { + "Id": 338, + "Type": 7, + "Flags": 0 + }, + { + "Id": 339, + "Type": 26, + "Flags": 0 + }, + { + "Id": 340, + "Type": 26, + "Flags": 0 + }, + { + "Id": 341, + "Type": 23, + "Flags": 0 + }, + { + "Id": 342, + "Type": 23, + "Flags": 0 + }, + { + "Id": 343, + "Type": 7, + "Flags": 0 + }, + { + "Id": 344, + "Type": 7, + "Flags": 0 + }, + { + "Id": 345, + "Type": 7, + "Flags": 0 + }, + { + "Id": 346, + "Type": 7, + "Flags": 0 + }, + { + "Id": 347, + "Type": 7, + "Flags": 0 + }, + { + "Id": 348, + "Type": 7, + "Flags": 0 + }, + { + "Id": 349, + "Type": 7, + "Flags": 0 + }, + { + "Id": 350, + "Type": 7, + "Flags": 0 + }, + { + "Id": 351, + "Type": 8, + "Flags": 0 + }, + { + "Id": 352, + "Type": 8, + "Flags": 0 + }, + { + "Id": 353, + "Type": 7, + "Flags": 0 + }, + { + "Id": 354, + "Type": 7, + "Flags": 0 + }, + { + "Id": 355, + "Type": 7, + "Flags": 0 + }, + { + "Id": 356, + "Type": 7, + "Flags": 0 + }, + { + "Id": 357, + "Type": 7, + "Flags": 0 + }, + { + "Id": 358, + "Type": 7, + "Flags": 0 + }, + { + "Id": 359, + "Type": 7, + "Flags": 0 + }, + { + "Id": 360, + "Type": 7, + "Flags": 0 + }, + { + "Id": 361, + "Type": 8, + "Flags": 0 + }, + { + "Id": 362, + "Type": 8, + "Flags": 0 + }, + { + "Id": 363, + "Type": 7, + "Flags": 0 + }, + { + "Id": 364, + "Type": 7, + "Flags": 0 + }, + { + "Id": 365, + "Type": 7, + "Flags": 0 + }, + { + "Id": 366, + "Type": 7, + "Flags": 0 + }, + { + "Id": 367, + "Type": 7, + "Flags": 0 + }, + { + "Id": 368, + "Type": 7, + "Flags": 0 + }, + { + "Id": 369, + "Type": 8, + "Flags": 0 + }, + { + "Id": 370, + "Type": 8, + "Flags": 0 + }, + { + "Id": 371, + "Type": 27, + "Flags": 0 + }, + { + "Id": 372, + "Type": 27, + "Flags": 0 + }, + { + "Id": 373, + "Type": 7, + "Flags": 0 + }, + { + "Id": 374, + "Type": 7, + "Flags": 0 + }, + { + "Id": 375, + "Type": 7, + "Flags": 0 + }, + { + "Id": 376, + "Type": 7, + "Flags": 0 + }, + { + "Id": 377, + "Type": 24, + "Flags": 0 + }, + { + "Id": 378, + "Type": 24, + "Flags": 0 + }, + { + "Id": 379, + "Type": 7, + "Flags": 0 + }, + { + "Id": 380, + "Type": 7, + "Flags": 0 + }, + { + "Id": 381, + "Type": 7, + "Flags": 0 + }, + { + "Id": 382, + "Type": 7, + "Flags": 0 + }, + { + "Id": 383, + "Type": 7, + "Flags": 0 + }, + { + "Id": 384, + "Type": 7, + "Flags": 0 + }, + { + "Id": 385, + "Type": 7, + "Flags": 0 + }, + { + "Id": 386, + "Type": 7, + "Flags": 0 + }, + { + "Id": 387, + "Type": 7, + "Flags": 0 + }, + { + "Id": 388, + "Type": 7, + "Flags": 0 + }, + { + "Id": 389, + "Type": 7, + "Flags": 0 + }, + { + "Id": 390, + "Type": 7, + "Flags": 0 + }, + { + "Id": 391, + "Type": 7, + "Flags": 0 + }, + { + "Id": 392, + "Type": 7, + "Flags": 0 + }, + { + "Id": 393, + "Type": 28, + "Flags": 1 + }, + { + "Id": 394, + "Type": 28, + "Flags": 1 + }, + { + "Id": 395, + "Type": 28, + "Flags": 1 + }, + { + "Id": 396, + "Type": 28, + "Flags": 1 + }, + { + "Id": 397, + "Type": 28, + "Flags": 1 + }, + { + "Id": 398, + "Type": 28, + "Flags": 1 + }, + { + "Id": 399, + "Type": 28, + "Flags": 1 + }, + { + "Id": 400, + "Type": 28, + "Flags": 1 + }, + { + "Id": 401, + "Type": 29, + "Flags": 1 + }, + { + "Id": 402, + "Type": 29, + "Flags": 1 + }, + { + "Id": 403, + "Type": 28, + "Flags": 1 + }, + { + "Id": 404, + "Type": 28, + "Flags": 1 + }, + { + "Id": 405, + "Type": 7, + "Flags": 0 + }, + { + "Id": 406, + "Type": 7, + "Flags": 0 + }, + { + "Id": 407, + "Type": 7, + "Flags": 0 + }, + { + "Id": 408, + "Type": 7, + "Flags": 0 + }, + { + "Id": 409, + "Type": 7, + "Flags": 0 + }, + { + "Id": 410, + "Type": 7, + "Flags": 0 + }, + { + "Id": 411, + "Type": 7, + "Flags": 0 + }, + { + "Id": 412, + "Type": 7, + "Flags": 0 + }, + { + "Id": 413, + "Type": 7, + "Flags": 0 + }, + { + "Id": 414, + "Type": 7, + "Flags": 0 + }, + { + "Id": 415, + "Type": 7, + "Flags": 0 + }, + { + "Id": 416, + "Type": 7, + "Flags": 0 + }, + { + "Id": 417, + "Type": 7, + "Flags": 0 + }, + { + "Id": 418, + "Type": 7, + "Flags": 0 + }, + { + "Id": 419, + "Type": 7, + "Flags": 0 + }, + { + "Id": 420, + "Type": 7, + "Flags": 0 + }, + { + "Id": 421, + "Type": 7, + "Flags": 0 + }, + { + "Id": 422, + "Type": 7, + "Flags": 0 + }, + { + "Id": 423, + "Type": 7, + "Flags": 0 + }, + { + "Id": 424, + "Type": 7, + "Flags": 0 + }, + { + "Id": 425, + "Type": 7, + "Flags": 0 + }, + { + "Id": 426, + "Type": 7, + "Flags": 0 + }, + { + "Id": 427, + "Type": 7, + "Flags": 0 + }, + { + "Id": 428, + "Type": 7, + "Flags": 0 + }, + { + "Id": 429, + "Type": 7, + "Flags": 0 + }, + { + "Id": 430, + "Type": 7, + "Flags": 0 + }, + { + "Id": 431, + "Type": 7, + "Flags": 0 + }, + { + "Id": 432, + "Type": 7, + "Flags": 0 + }, + { + "Id": 433, + "Type": 7, + "Flags": 0 + }, + { + "Id": 434, + "Type": 7, + "Flags": 0 + }, + { + "Id": 435, + "Type": 7, + "Flags": 0 + }, + { + "Id": 436, + "Type": 7, + "Flags": 0 + }, + { + "Id": 437, + "Type": 7, + "Flags": 0 + }, + { + "Id": 438, + "Type": 7, + "Flags": 0 + }, + { + "Id": 439, + "Type": 7, + "Flags": 0 + }, + { + "Id": 440, + "Type": 7, + "Flags": 0 + }, + { + "Id": 441, + "Type": 7, + "Flags": 0 + }, + { + "Id": 442, + "Type": 7, + "Flags": 0 + }, + { + "Id": 443, + "Type": 7, + "Flags": 0 + }, + { + "Id": 444, + "Type": 7, + "Flags": 0 + }, + { + "Id": 445, + "Type": 7, + "Flags": 0 + }, + { + "Id": 446, + "Type": 7, + "Flags": 0 + }, + { + "Id": 447, + "Type": 7, + "Flags": 0 + }, + { + "Id": 448, + "Type": 7, + "Flags": 0 + }, + { + "Id": 449, + "Type": 7, + "Flags": 0 + }, + { + "Id": 450, + "Type": 7, + "Flags": 0 + }, + { + "Id": 451, + "Type": 7, + "Flags": 0 + }, + { + "Id": 452, + "Type": 7, + "Flags": 0 + }, + { + "Id": 453, + "Type": 7, + "Flags": 0 + }, + { + "Id": 454, + "Type": 7, + "Flags": 0 + }, + { + "Id": 455, + "Type": 7, + "Flags": 0 + }, + { + "Id": 456, + "Type": 7, + "Flags": 0 + }, + { + "Id": 457, + "Type": 7, + "Flags": 0 + }, + { + "Id": 458, + "Type": 7, + "Flags": 0 + }, + { + "Id": 459, + "Type": 7, + "Flags": 0 + }, + { + "Id": 460, + "Type": 7, + "Flags": 0 + }, + { + "Id": 461, + "Type": 7, + "Flags": 0 + }, + { + "Id": 462, + "Type": 7, + "Flags": 0 + }, + { + "Id": 463, + "Type": 7, + "Flags": 0 + }, + { + "Id": 464, + "Type": 7, + "Flags": 0 + }, + { + "Id": 465, + "Type": 7, + "Flags": 0 + }, + { + "Id": 466, + "Type": 7, + "Flags": 0 + }, + { + "Id": 467, + "Type": 7, + "Flags": 0 + }, + { + "Id": 468, + "Type": 7, + "Flags": 0 + }, + { + "Id": 469, + "Type": 7, + "Flags": 0 + }, + { + "Id": 470, + "Type": 7, + "Flags": 0 + }, + { + "Id": 471, + "Type": 7, + "Flags": 0 + }, + { + "Id": 472, + "Type": 7, + "Flags": 0 + }, + { + "Id": 473, + "Type": 7, + "Flags": 0 + }, + { + "Id": 474, + "Type": 7, + "Flags": 0 + }, + { + "Id": 475, + "Type": 7, + "Flags": 0 + }, + { + "Id": 476, + "Type": 7, + "Flags": 0 + }, + { + "Id": 477, + "Type": 7, + "Flags": 0 + }, + { + "Id": 478, + "Type": 7, + "Flags": 0 + }, + { + "Id": 479, + "Type": 7, + "Flags": 0 + }, + { + "Id": 480, + "Type": 7, + "Flags": 0 + }, + { + "Id": 481, + "Type": 7, + "Flags": 0 + }, + { + "Id": 482, + "Type": 7, + "Flags": 0 + }, + { + "Id": 483, + "Type": 7, + "Flags": 0 + }, + { + "Id": 484, + "Type": 7, + "Flags": 0 + }, + { + "Id": 485, + "Type": 7, + "Flags": 0 + }, + { + "Id": 486, + "Type": 7, + "Flags": 0 + }, + { + "Id": 487, + "Type": 7, + "Flags": 0 + }, + { + "Id": 488, + "Type": 7, + "Flags": 0 + }, + { + "Id": 489, + "Type": 7, + "Flags": 0 + }, + { + "Id": 490, + "Type": 7, + "Flags": 0 + }, + { + "Id": 491, + "Type": 7, + "Flags": 0 + }, + { + "Id": 492, + "Type": 7, + "Flags": 0 + }, + { + "Id": 493, + "Type": 7, + "Flags": 0 + }, + { + "Id": 494, + "Type": 7, + "Flags": 0 + }, + { + "Id": 495, + "Type": 7, + "Flags": 0 + }, + { + "Id": 496, + "Type": 7, + "Flags": 0 + }, + { + "Id": 497, + "Type": 7, + "Flags": 0 + }, + { + "Id": 498, + "Type": 7, + "Flags": 0 + }, + { + "Id": 499, + "Type": 7, + "Flags": 0 + }, + { + "Id": 500, + "Type": 7, + "Flags": 0 + }, + { + "Id": 501, + "Type": 7, + "Flags": 0 + }, + { + "Id": 502, + "Type": 7, + "Flags": 0 + }, + { + "Id": 503, + "Type": 7, + "Flags": 0 + }, + { + "Id": 504, + "Type": 7, + "Flags": 0 + }, + { + "Id": 505, + "Type": 7, + "Flags": 0 + }, + { + "Id": 506, + "Type": 7, + "Flags": 0 + }, + { + "Id": 507, + "Type": 7, + "Flags": 0 + }, + { + "Id": 508, + "Type": 7, + "Flags": 0 + }, + { + "Id": 509, + "Type": 7, + "Flags": 0 + }, + { + "Id": 510, + "Type": 7, + "Flags": 0 + }, + { + "Id": 511, + "Type": 7, + "Flags": 0 + }, + { + "Id": 512, + "Type": 7, + "Flags": 0 + }, + { + "Id": 513, + "Type": 7, + "Flags": 0 + }, + { + "Id": 514, + "Type": 7, + "Flags": 0 + }, + { + "Id": 515, + "Type": 7, + "Flags": 0 + }, + { + "Id": 516, + "Type": 7, + "Flags": 0 + }, + { + "Id": 517, + "Type": 7, + "Flags": 0 + }, + { + "Id": 518, + "Type": 7, + "Flags": 0 + }, + { + "Id": 519, + "Type": 7, + "Flags": 0 + }, + { + "Id": 520, + "Type": 7, + "Flags": 0 + }, + { + "Id": 521, + "Type": 7, + "Flags": 0 + }, + { + "Id": 522, + "Type": 7, + "Flags": 0 + }, + { + "Id": 523, + "Type": 7, + "Flags": 0 + }, + { + "Id": 524, + "Type": 7, + "Flags": 0 + }, + { + "Id": 525, + "Type": 7, + "Flags": 0 + }, + { + "Id": 526, + "Type": 7, + "Flags": 0 + }, + { + "Id": 527, + "Type": 7, + "Flags": 0 + }, + { + "Id": 528, + "Type": 7, + "Flags": 0 + }, + { + "Id": 529, + "Type": 7, + "Flags": 0 + }, + { + "Id": 530, + "Type": 7, + "Flags": 0 + }, + { + "Id": 531, + "Type": 7, + "Flags": 0 + }, + { + "Id": 532, + "Type": 7, + "Flags": 0 + }, + { + "Id": 533, + "Type": 7, + "Flags": 0 + }, + { + "Id": 534, + "Type": 7, + "Flags": 0 + }, + { + "Id": 535, + "Type": 7, + "Flags": 0 + }, + { + "Id": 536, + "Type": 7, + "Flags": 0 + }, + { + "Id": 537, + "Type": 7, + "Flags": 0 + }, + { + "Id": 538, + "Type": 7, + "Flags": 0 + }, + { + "Id": 539, + "Type": 7, + "Flags": 0 + }, + { + "Id": 540, + "Type": 7, + "Flags": 0 + }, + { + "Id": 541, + "Type": 8, + "Flags": 0 + }, + { + "Id": 542, + "Type": 8, + "Flags": 0 + }, + { + "Id": 543, + "Type": 7, + "Flags": 0 + }, + { + "Id": 544, + "Type": 7, + "Flags": 0 + }, + { + "Id": 545, + "Type": 7, + "Flags": 0 + }, + { + "Id": 546, + "Type": 7, + "Flags": 0 + }, + { + "Id": 547, + "Type": 7, + "Flags": 0 + }, + { + "Id": 548, + "Type": 7, + "Flags": 0 + }, + { + "Id": 549, + "Type": 7, + "Flags": 0 + }, + { + "Id": 550, + "Type": 7, + "Flags": 0 + }, + { + "Id": 551, + "Type": 7, + "Flags": 0 + }, + { + "Id": 552, + "Type": 7, + "Flags": 0 + }, + { + "Id": 553, + "Type": 7, + "Flags": 0 + }, + { + "Id": 554, + "Type": 7, + "Flags": 0 + }, + { + "Id": 555, + "Type": 8, + "Flags": 0 + }, + { + "Id": 556, + "Type": 8, + "Flags": 0 + }, + { + "Id": 557, + "Type": 8, + "Flags": 0 + }, + { + "Id": 558, + "Type": 8, + "Flags": 0 + }, + { + "Id": 559, + "Type": 7, + "Flags": 0 + }, + { + "Id": 560, + "Type": 7, + "Flags": 0 + }, + { + "Id": 561, + "Type": 7, + "Flags": 0 + }, + { + "Id": 562, + "Type": 30, + "Flags": 0 + }, + { + "Id": 563, + "Type": 7, + "Flags": 0 + }, + { + "Id": 564, + "Type": 7, + "Flags": 0 + }, + { + "Id": 565, + "Type": 7, + "Flags": 0 + }, + { + "Id": 566, + "Type": 7, + "Flags": 0 + }, + { + "Id": 567, + "Type": 31, + "Flags": 0 + }, + { + "Id": 568, + "Type": 31, + "Flags": 0 + }, + { + "Id": 569, + "Type": 7, + "Flags": 0 + }, + { + "Id": 570, + "Type": 7, + "Flags": 0 + }, + { + "Id": 571, + "Type": 8, + "Flags": 0 + }, + { + "Id": 572, + "Type": 8, + "Flags": 0 + }, + { + "Id": 573, + "Type": 30, + "Flags": 0 + }, + { + "Id": 574, + "Type": 30, + "Flags": 0 + }, + { + "Id": 575, + "Type": 27, + "Flags": 0 + }, + { + "Id": 576, + "Type": 7, + "Flags": 0 + }, + { + "Id": 577, + "Type": 7, + "Flags": 0 + }, + { + "Id": 578, + "Type": 8, + "Flags": 0 + }, + { + "Id": 579, + "Type": 8, + "Flags": 0 + }, + { + "Id": 580, + "Type": 8, + "Flags": 0 + }, + { + "Id": 581, + "Type": 22, + "Flags": 0 + }, + { + "Id": 582, + "Type": 22, + "Flags": 0 + }, + { + "Id": 583, + "Type": 22, + "Flags": 0 + }, + { + "Id": 584, + "Type": 22, + "Flags": 0 + }, + { + "Id": 585, + "Type": 32, + "Flags": 0 + }, + { + "Id": 586, + "Type": 33, + "Flags": 0 + }, + { + "Id": 587, + "Type": 7, + "Flags": 0 + }, + { + "Id": 588, + "Type": 7, + "Flags": 0 + }, + { + "Id": 589, + "Type": 7, + "Flags": 0 + }, + { + "Id": 590, + "Type": 7, + "Flags": 0 + }, + { + "Id": 591, + "Type": 7, + "Flags": 0 + }, + { + "Id": 592, + "Type": 27, + "Flags": 0 + }, + { + "Id": 593, + "Type": 27, + "Flags": 0 + }, + { + "Id": 594, + "Type": 8, + "Flags": 0 + }, + { + "Id": 595, + "Type": 7, + "Flags": 0 + }, + { + "Id": 596, + "Type": 22, + "Flags": 0 + }, + { + "Id": 597, + "Type": 22, + "Flags": 0 + }, + { + "Id": 598, + "Type": 22, + "Flags": 0 + }, + { + "Id": 599, + "Type": 7, + "Flags": 0 + }, + { + "Id": 600, + "Type": 34, + "Flags": 0 + }, + { + "Id": 601, + "Type": 27, + "Flags": 0 + }, + { + "Id": 602, + "Type": 7, + "Flags": 0 + }, + { + "Id": 603, + "Type": 7, + "Flags": 0 + }, + { + "Id": 604, + "Type": 27, + "Flags": 0 + }, + { + "Id": 605, + "Type": 27, + "Flags": 0 + }, + { + "Id": 606, + "Type": 27, + "Flags": 0 + }, + { + "Id": 607, + "Type": 27, + "Flags": 0 + }, + { + "Id": 608, + "Type": 27, + "Flags": 0 + }, + { + "Id": 609, + "Type": 27, + "Flags": 0 + }, + { + "Id": 610, + "Type": 8, + "Flags": 0 + }, + { + "Id": 611, + "Type": 8, + "Flags": 0 + }, + { + "Id": 612, + "Type": 7, + "Flags": 0 + }, + { + "Id": 613, + "Type": 7, + "Flags": 0 + }, + { + "Id": 614, + "Type": 7, + "Flags": 0 + }, + { + "Id": 615, + "Type": 7, + "Flags": 0 + }, + { + "Id": 616, + "Type": 7, + "Flags": 0 + }, + { + "Id": 617, + "Type": 7, + "Flags": 0 + }, + { + "Id": 618, + "Type": 27, + "Flags": 0 + }, + { + "Id": 619, + "Type": 27, + "Flags": 0 + }, + { + "Id": 620, + "Type": 35, + "Flags": 0 + }, + { + "Id": 621, + "Type": 35, + "Flags": 0 + }, + { + "Id": 622, + "Type": 22, + "Flags": 0 + }, + { + "Id": 623, + "Type": 22, + "Flags": 0 + }, + { + "Id": 624, + "Type": 27, + "Flags": 0 + }, + { + "Id": 625, + "Type": 22, + "Flags": 0 + }, + { + "Id": 626, + "Type": 34, + "Flags": 0 + }, + { + "Id": 627, + "Type": 34, + "Flags": 0 + }, + { + "Id": 628, + "Type": 22, + "Flags": 0 + }, + { + "Id": 629, + "Type": 7, + "Flags": 0 + }, + { + "Id": 630, + "Type": 7, + "Flags": 0 + }, + { + "Id": 631, + "Type": 22, + "Flags": 0 + }, + { + "Id": 632, + "Type": 22, + "Flags": 0 + }, + { + "Id": 633, + "Type": 7, + "Flags": 0 + }, + { + "Id": 634, + "Type": 8, + "Flags": 0 + }, + { + "Id": 635, + "Type": 8, + "Flags": 0 + }, + { + "Id": 636, + "Type": 7, + "Flags": 0 + }, + { + "Id": 637, + "Type": 7, + "Flags": 0 + }, + { + "Id": 638, + "Type": 7, + "Flags": 0 + }, + { + "Id": 639, + "Type": 7, + "Flags": 0 + }, + { + "Id": 640, + "Type": 7, + "Flags": 0 + }, + { + "Id": 641, + "Type": 7, + "Flags": 0 + }, + { + "Id": 642, + "Type": 7, + "Flags": 0 + }, + { + "Id": 643, + "Type": 7, + "Flags": 0 + }, + { + "Id": 644, + "Type": 7, + "Flags": 0 + }, + { + "Id": 645, + "Type": 7, + "Flags": 0 + }, + { + "Id": 646, + "Type": 22, + "Flags": 0 + }, + { + "Id": 647, + "Type": 22, + "Flags": 0 + }, + { + "Id": 648, + "Type": 8, + "Flags": 0 + }, + { + "Id": 649, + "Type": 35, + "Flags": 0 + }, + { + "Id": 650, + "Type": 27, + "Flags": 0 + }, + { + "Id": 651, + "Type": 22, + "Flags": 0 + }, + { + "Id": 652, + "Type": 22, + "Flags": 0 + }, + { + "Id": 653, + "Type": 22, + "Flags": 0 + }, + { + "Id": 654, + "Type": 22, + "Flags": 0 + }, + { + "Id": 655, + "Type": 8, + "Flags": 0 + }, + { + "Id": 656, + "Type": 8, + "Flags": 0 + }, + { + "Id": 657, + "Type": 22, + "Flags": 0 + }, + { + "Id": 658, + "Type": 22, + "Flags": 0 + }, + { + "Id": 659, + "Type": 7, + "Flags": 0 + }, + { + "Id": 660, + "Type": 7, + "Flags": 0 + }, + { + "Id": 661, + "Type": 7, + "Flags": 0 + }, + { + "Id": 662, + "Type": 7, + "Flags": 0 + }, + { + "Id": 663, + "Type": 8, + "Flags": 0 + }, + { + "Id": 664, + "Type": 8, + "Flags": 0 + }, + { + "Id": 665, + "Type": 8, + "Flags": 0 + }, + { + "Id": 666, + "Type": 8, + "Flags": 0 + }, + { + "Id": 667, + "Type": 7, + "Flags": 0 + }, + { + "Id": 668, + "Type": 7, + "Flags": 0 + }, + { + "Id": 669, + "Type": 7, + "Flags": 0 + }, + { + "Id": 670, + "Type": 7, + "Flags": 0 + }, + { + "Id": 671, + "Type": 7, + "Flags": 0 + }, + { + "Id": 672, + "Type": 7, + "Flags": 0 + }, + { + "Id": 673, + "Type": 8, + "Flags": 0 + }, + { + "Id": 674, + "Type": 8, + "Flags": 0 + }, + { + "Id": 675, + "Type": 22, + "Flags": 0 + }, + { + "Id": 676, + "Type": 22, + "Flags": 0 + }, + { + "Id": 677, + "Type": 8, + "Flags": 0 + }, + { + "Id": 678, + "Type": 8, + "Flags": 0 + }, + { + "Id": 679, + "Type": 27, + "Flags": 0 + }, + { + "Id": 680, + "Type": 27, + "Flags": 0 + }, + { + "Id": 681, + "Type": 8, + "Flags": 0 + }, + { + "Id": 682, + "Type": 8, + "Flags": 0 + }, + { + "Id": 683, + "Type": 7, + "Flags": 0 + }, + { + "Id": 684, + "Type": 7, + "Flags": 0 + }, + { + "Id": 685, + "Type": 7, + "Flags": 0 + }, + { + "Id": 686, + "Type": 7, + "Flags": 0 + }, + { + "Id": 687, + "Type": 7, + "Flags": 0 + }, + { + "Id": 688, + "Type": 7, + "Flags": 0 + }, + { + "Id": 689, + "Type": 8, + "Flags": 0 + }, + { + "Id": 690, + "Type": 8, + "Flags": 0 + }, + { + "Id": 691, + "Type": 8, + "Flags": 0 + }, + { + "Id": 692, + "Type": 8, + "Flags": 0 + }, + { + "Id": 693, + "Type": 7, + "Flags": 0 + }, + { + "Id": 694, + "Type": 22, + "Flags": 0 + }, + { + "Id": 695, + "Type": 8, + "Flags": 0 + }, + { + "Id": 696, + "Type": 7, + "Flags": 0 + }, + { + "Id": 697, + "Type": 7, + "Flags": 0 + }, + { + "Id": 698, + "Type": 8, + "Flags": 0 + }, + { + "Id": 699, + "Type": 8, + "Flags": 0 + }, + { + "Id": 700, + "Type": 7, + "Flags": 0 + }, + { + "Id": 701, + "Type": 7, + "Flags": 0 + }, + { + "Id": 702, + "Type": 7, + "Flags": 0 + }, + { + "Id": 703, + "Type": 22, + "Flags": 0 + }, + { + "Id": 704, + "Type": 22, + "Flags": 0 + }, + { + "Id": 705, + "Type": 27, + "Flags": 0 + }, + { + "Id": 706, + "Type": 27, + "Flags": 0 + }, + { + "Id": 707, + "Type": 27, + "Flags": 0 + }, + { + "Id": 708, + "Type": 7, + "Flags": 0 + }, + { + "Id": 709, + "Type": 7, + "Flags": 0 + }, + { + "Id": 710, + "Type": 7, + "Flags": 0 + }, + { + "Id": 711, + "Type": 7, + "Flags": 0 + }, + { + "Id": 712, + "Type": 7, + "Flags": 0 + }, + { + "Id": 713, + "Type": 7, + "Flags": 0 + }, + { + "Id": 714, + "Type": 8, + "Flags": 0 + }, + { + "Id": 715, + "Type": 8, + "Flags": 0 + }, + { + "Id": 716, + "Type": 22, + "Flags": 0 + }, + { + "Id": 717, + "Type": 22, + "Flags": 0 + }, + { + "Id": 718, + "Type": 7, + "Flags": 0 + }, + { + "Id": 719, + "Type": 7, + "Flags": 0 + }, + { + "Id": 720, + "Type": 22, + "Flags": 0 + }, + { + "Id": 721, + "Type": 22, + "Flags": 0 + }, + { + "Id": 722, + "Type": 7, + "Flags": 0 + }, + { + "Id": 723, + "Type": 7, + "Flags": 0 + }, + { + "Id": 724, + "Type": 22, + "Flags": 0 + }, + { + "Id": 725, + "Type": 22, + "Flags": 0 + }, + { + "Id": 726, + "Type": 7, + "Flags": 0 + }, + { + "Id": 727, + "Type": 7, + "Flags": 0 + }, + { + "Id": 728, + "Type": 8, + "Flags": 0 + }, + { + "Id": 729, + "Type": 8, + "Flags": 0 + }, + { + "Id": 730, + "Type": 8, + "Flags": 0 + }, + { + "Id": 731, + "Type": 7, + "Flags": 0 + }, + { + "Id": 732, + "Type": 7, + "Flags": 0 + }, + { + "Id": 733, + "Type": 7, + "Flags": 0 + }, + { + "Id": 734, + "Type": 7, + "Flags": 0 + }, + { + "Id": 735, + "Type": 8, + "Flags": 0 + }, + { + "Id": 736, + "Type": 8, + "Flags": 0 + }, + { + "Id": 737, + "Type": 22, + "Flags": 0 + }, + { + "Id": 738, + "Type": 22, + "Flags": 0 + }, + { + "Id": 739, + "Type": 27, + "Flags": 0 + }, + { + "Id": 740, + "Type": 8, + "Flags": 0 + }, + { + "Id": 741, + "Type": 8, + "Flags": 0 + }, + { + "Id": 742, + "Type": 8, + "Flags": 0 + }, + { + "Id": 743, + "Type": 8, + "Flags": 0 + }, + { + "Id": 744, + "Type": 8, + "Flags": 0 + }, + { + "Id": 745, + "Type": 8, + "Flags": 0 + }, + { + "Id": 746, + "Type": 7, + "Flags": 0 + }, + { + "Id": 747, + "Type": 7, + "Flags": 0 + }, + { + "Id": 748, + "Type": 7, + "Flags": 0 + }, + { + "Id": 749, + "Type": 7, + "Flags": 0 + }, + { + "Id": 750, + "Type": 22, + "Flags": 0 + }, + { + "Id": 751, + "Type": 22, + "Flags": 0 + }, + { + "Id": 752, + "Type": 22, + "Flags": 0 + }, + { + "Id": 753, + "Type": 22, + "Flags": 0 + }, + { + "Id": 754, + "Type": 27, + "Flags": 0 + }, + { + "Id": 755, + "Type": 27, + "Flags": 0 + }, + { + "Id": 756, + "Type": 27, + "Flags": 0 + }, + { + "Id": 757, + "Type": 7, + "Flags": 0 + }, + { + "Id": 758, + "Type": 7, + "Flags": 0 + }, + { + "Id": 759, + "Type": 7, + "Flags": 0 + }, + { + "Id": 760, + "Type": 8, + "Flags": 0 + }, + { + "Id": 761, + "Type": 22, + "Flags": 0 + }, + { + "Id": 762, + "Type": 22, + "Flags": 0 + }, + { + "Id": 763, + "Type": 22, + "Flags": 0 + }, + { + "Id": 764, + "Type": 22, + "Flags": 0 + }, + { + "Id": 765, + "Type": 27, + "Flags": 0 + }, + { + "Id": 766, + "Type": 27, + "Flags": 0 + }, + { + "Id": 767, + "Type": 27, + "Flags": 0 + }, + { + "Id": 768, + "Type": 27, + "Flags": 0 + }, + { + "Id": 769, + "Type": 27, + "Flags": 0 + }, + { + "Id": 770, + "Type": 27, + "Flags": 0 + }, + { + "Id": 771, + "Type": 27, + "Flags": 0 + }, + { + "Id": 772, + "Type": 7, + "Flags": 0 + }, + { + "Id": 773, + "Type": 7, + "Flags": 0 + }, + { + "Id": 774, + "Type": 34, + "Flags": 0 + }, + { + "Id": 775, + "Type": 34, + "Flags": 0 + }, + { + "Id": 776, + "Type": 36, + "Flags": 0 + }, + { + "Id": 777, + "Type": 36, + "Flags": 0 + }, + { + "Id": 778, + "Type": 8, + "Flags": 0 + }, + { + "Id": 779, + "Type": 27, + "Flags": 0 + }, + { + "Id": 780, + "Type": 1, + "Flags": 0 + }, + { + "Id": 781, + "Type": 1, + "Flags": 0 + }, + { + "Id": 782, + "Type": 7, + "Flags": 0 + }, + { + "Id": 783, + "Type": 7, + "Flags": 0 + }, + { + "Id": 784, + "Type": 7, + "Flags": 0 + }, + { + "Id": 785, + "Type": 7, + "Flags": 0 + }, + { + "Id": 786, + "Type": 8, + "Flags": 0 + }, + { + "Id": 787, + "Type": 8, + "Flags": 0 + }, + { + "Id": 788, + "Type": 22, + "Flags": 0 + }, + { + "Id": 789, + "Type": 22, + "Flags": 0 + }, + { + "Id": 790, + "Type": 8, + "Flags": 0 + }, + { + "Id": 791, + "Type": 8, + "Flags": 0 + }, + { + "Id": 792, + "Type": 7, + "Flags": 0 + }, + { + "Id": 793, + "Type": 7, + "Flags": 0 + }, + { + "Id": 794, + "Type": 8, + "Flags": 0 + }, + { + "Id": 795, + "Type": 8, + "Flags": 0 + }, + { + "Id": 796, + "Type": 8, + "Flags": 0 + }, + { + "Id": 797, + "Type": 8, + "Flags": 0 + }, + { + "Id": 798, + "Type": 7, + "Flags": 0 + }, + { + "Id": 799, + "Type": 7, + "Flags": 0 + }, + { + "Id": 800, + "Type": 36, + "Flags": 0 + }, + { + "Id": 801, + "Type": 36, + "Flags": 0 + }, + { + "Id": 802, + "Type": 8, + "Flags": 0 + }, + { + "Id": 803, + "Type": 8, + "Flags": 0 + }, + { + "Id": 804, + "Type": 34, + "Flags": 0 + }, + { + "Id": 805, + "Type": 34, + "Flags": 0 + }, + { + "Id": 806, + "Type": 22, + "Flags": 0 + }, + { + "Id": 807, + "Type": 22, + "Flags": 0 + }, + { + "Id": 808, + "Type": 22, + "Flags": 0 + }, + { + "Id": 809, + "Type": 22, + "Flags": 0 + }, + { + "Id": 810, + "Type": 22, + "Flags": 0 + }, + { + "Id": 811, + "Type": 34, + "Flags": 0 + }, + { + "Id": 812, + "Type": 34, + "Flags": 0 + }, + { + "Id": 813, + "Type": 34, + "Flags": 0 + }, + { + "Id": 814, + "Type": 27, + "Flags": 0 + }, + { + "Id": 815, + "Type": 27, + "Flags": 0 + }, + { + "Id": 816, + "Type": 8, + "Flags": 0 + }, + { + "Id": 817, + "Type": 8, + "Flags": 0 + }, + { + "Id": 818, + "Type": 7, + "Flags": 0 + }, + { + "Id": 819, + "Type": 8, + "Flags": 0 + }, + { + "Id": 820, + "Type": 36, + "Flags": 0 + }, + { + "Id": 821, + "Type": 36, + "Flags": 0 + }, + { + "Id": 822, + "Type": 36, + "Flags": 0 + }, + { + "Id": 823, + "Type": 36, + "Flags": 0 + }, + { + "Id": 824, + "Type": 8, + "Flags": 0 + }, + { + "Id": 825, + "Type": 7, + "Flags": 0 + }, + { + "Id": 826, + "Type": 27, + "Flags": 0 + }, + { + "Id": 827, + "Type": 27, + "Flags": 0 + }, + { + "Id": 828, + "Type": 27, + "Flags": 0 + }, + { + "Id": 829, + "Type": 8, + "Flags": 0 + }, + { + "Id": 830, + "Type": 8, + "Flags": 0 + }, + { + "Id": 831, + "Type": 8, + "Flags": 0 + }, + { + "Id": 832, + "Type": 8, + "Flags": 0 + }, + { + "Id": 833, + "Type": 8, + "Flags": 0 + }, + { + "Id": 834, + "Type": 27, + "Flags": 0 + }, + { + "Id": 835, + "Type": 27, + "Flags": 0 + }, + { + "Id": 836, + "Type": 27, + "Flags": 0 + }, + { + "Id": 837, + "Type": 2, + "Flags": 0 + }, + { + "Id": 838, + "Type": 2, + "Flags": 0 + }, + { + "Id": 839, + "Type": 34, + "Flags": 0 + }, + { + "Id": 840, + "Type": 34, + "Flags": 0 + }, + { + "Id": 841, + "Type": 8, + "Flags": 0 + }, + { + "Id": 842, + "Type": 7, + "Flags": 0 + }, + { + "Id": 843, + "Type": 7, + "Flags": 0 + }, + { + "Id": 844, + "Type": 7, + "Flags": 0 + }, + { + "Id": 845, + "Type": 36, + "Flags": 0 + }, + { + "Id": 846, + "Type": 36, + "Flags": 0 + }, + { + "Id": 847, + "Type": 8, + "Flags": 0 + }, + { + "Id": 848, + "Type": 8, + "Flags": 0 + }, + { + "Id": 849, + "Type": 8, + "Flags": 0 + }, + { + "Id": 850, + "Type": 8, + "Flags": 0 + }, + { + "Id": 851, + "Type": 7, + "Flags": 0 + }, + { + "Id": 852, + "Type": 7, + "Flags": 0 + }, + { + "Id": 853, + "Type": 22, + "Flags": 0 + }, + { + "Id": 854, + "Type": 22, + "Flags": 0 + }, + { + "Id": 855, + "Type": 22, + "Flags": 0 + }, + { + "Id": 856, + "Type": 22, + "Flags": 0 + }, + { + "Id": 857, + "Type": 22, + "Flags": 0 + }, + { + "Id": 858, + "Type": 22, + "Flags": 0 + }, + { + "Id": 859, + "Type": 22, + "Flags": 0 + }, + { + "Id": 860, + "Type": 22, + "Flags": 0 + }, + { + "Id": 861, + "Type": 22, + "Flags": 0 + }, + { + "Id": 862, + "Type": 22, + "Flags": 0 + }, + { + "Id": 863, + "Type": 22, + "Flags": 0 + }, + { + "Id": 864, + "Type": 22, + "Flags": 0 + }, + { + "Id": 865, + "Type": 22, + "Flags": 0 + }, + { + "Id": 866, + "Type": 22, + "Flags": 0 + }, + { + "Id": 867, + "Type": 22, + "Flags": 0 + }, + { + "Id": 868, + "Type": 7, + "Flags": 0 + }, + { + "Id": 869, + "Type": 7, + "Flags": 0 + }, + { + "Id": 870, + "Type": 7, + "Flags": 0 + }, + { + "Id": 871, + "Type": 7, + "Flags": 0 + }, + { + "Id": 872, + "Type": 7, + "Flags": 0 + }, + { + "Id": 873, + "Type": 7, + "Flags": 0 + }, + { + "Id": 874, + "Type": 7, + "Flags": 0 + }, + { + "Id": 875, + "Type": 7, + "Flags": 0 + }, + { + "Id": 876, + "Type": 7, + "Flags": 0 + }, + { + "Id": 877, + "Type": 7, + "Flags": 0 + }, + { + "Id": 878, + "Type": 7, + "Flags": 0 + }, + { + "Id": 879, + "Type": 7, + "Flags": 0 + }, + { + "Id": 880, + "Type": 7, + "Flags": 0 + }, + { + "Id": 881, + "Type": 7, + "Flags": 0 + }, + { + "Id": 882, + "Type": 7, + "Flags": 0 + }, + { + "Id": 883, + "Type": 7, + "Flags": 0 + }, + { + "Id": 884, + "Type": 7, + "Flags": 0 + }, + { + "Id": 885, + "Type": 7, + "Flags": 0 + }, + { + "Id": 886, + "Type": 7, + "Flags": 0 + }, + { + "Id": 887, + "Type": 7, + "Flags": 0 + }, + { + "Id": 888, + "Type": 8, + "Flags": 0 + }, + { + "Id": 889, + "Type": 8, + "Flags": 0 + }, + { + "Id": 890, + "Type": 8, + "Flags": 0 + }, + { + "Id": 891, + "Type": 8, + "Flags": 0 + }, + { + "Id": 892, + "Type": 8, + "Flags": 0 + }, + { + "Id": 893, + "Type": 8, + "Flags": 0 + }, + { + "Id": 894, + "Type": 7, + "Flags": 0 + }, + { + "Id": 895, + "Type": 7, + "Flags": 0 + }, + { + "Id": 896, + "Type": 7, + "Flags": 0 + }, + { + "Id": 897, + "Type": 7, + "Flags": 0 + }, + { + "Id": 898, + "Type": 7, + "Flags": 0 + }, + { + "Id": 899, + "Type": 7, + "Flags": 0 + }, + { + "Id": 900, + "Type": 8, + "Flags": 0 + }, + { + "Id": 901, + "Type": 8, + "Flags": 0 + }, + { + "Id": 902, + "Type": 7, + "Flags": 0 + }, + { + "Id": 903, + "Type": 7, + "Flags": 0 + }, + { + "Id": 904, + "Type": 7, + "Flags": 0 + }, + { + "Id": 905, + "Type": 7, + "Flags": 0 + }, + { + "Id": 906, + "Type": 7, + "Flags": 0 + }, + { + "Id": 907, + "Type": 7, + "Flags": 0 + }, + { + "Id": 908, + "Type": 7, + "Flags": 0 + }, + { + "Id": 909, + "Type": 7, + "Flags": 0 + }, + { + "Id": 910, + "Type": 7, + "Flags": 0 + }, + { + "Id": 911, + "Type": 7, + "Flags": 0 + }, + { + "Id": 912, + "Type": 25, + "Flags": 0 + }, + { + "Id": 913, + "Type": 25, + "Flags": 0 + }, + { + "Id": 916, + "Type": 25, + "Flags": 0 + }, + { + "Id": 917, + "Type": 25, + "Flags": 0 + }, + { + "Id": 918, + "Type": 22, + "Flags": 0 + }, + { + "Id": 919, + "Type": 22, + "Flags": 0 + }, + { + "Id": 920, + "Type": 7, + "Flags": 0 + }, + { + "Id": 921, + "Type": 7, + "Flags": 0 + }, + { + "Id": 922, + "Type": 7, + "Flags": 0 + }, + { + "Id": 923, + "Type": 7, + "Flags": 0 + }, + { + "Id": 924, + "Type": 8, + "Flags": 0 + }, + { + "Id": 925, + "Type": 8, + "Flags": 0 + }, + { + "Id": 926, + "Type": 22, + "Flags": 0 + }, + { + "Id": 927, + "Type": 22, + "Flags": 0 + }, + { + "Id": 928, + "Type": 7, + "Flags": 0 + }, + { + "Id": 929, + "Type": 7, + "Flags": 0 + }, + { + "Id": 930, + "Type": 7, + "Flags": 0 + }, + { + "Id": 931, + "Type": 7, + "Flags": 0 + }, + { + "Id": 932, + "Type": 22, + "Flags": 0 + }, + { + "Id": 933, + "Type": 22, + "Flags": 0 + }, + { + "Id": 934, + "Type": 7, + "Flags": 0 + }, + { + "Id": 935, + "Type": 7, + "Flags": 0 + }, + { + "Id": 936, + "Type": 7, + "Flags": 0 + }, + { + "Id": 937, + "Type": 7, + "Flags": 0 + }, + { + "Id": 938, + "Type": 8, + "Flags": 0 + }, + { + "Id": 939, + "Type": 8, + "Flags": 0 + }, + { + "Id": 940, + "Type": 7, + "Flags": 0 + }, + { + "Id": 941, + "Type": 7, + "Flags": 0 + }, + { + "Id": 942, + "Type": 7, + "Flags": 0 + }, + { + "Id": 943, + "Type": 7, + "Flags": 0 + }, + { + "Id": 944, + "Type": 36, + "Flags": 0 + }, + { + "Id": 945, + "Type": 36, + "Flags": 0 + }, + { + "Id": 946, + "Type": 22, + "Flags": 0 + }, + { + "Id": 947, + "Type": 22, + "Flags": 0 + }, + { + "Id": 948, + "Type": 22, + "Flags": 0 + }, + { + "Id": 949, + "Type": 22, + "Flags": 0 + }, + { + "Id": 952, + "Type": 33, + "Flags": 0 + }, + { + "Id": 953, + "Type": 33, + "Flags": 0 + }, + { + "Id": 954, + "Type": 33, + "Flags": 0 + }, + { + "Id": 955, + "Type": 33, + "Flags": 0 + }, + { + "Id": 960, + "Type": 33, + "Flags": 0 + }, + { + "Id": 961, + "Type": 33, + "Flags": 0 + }, + { + "Id": 962, + "Type": 33, + "Flags": 0 + }, + { + "Id": 963, + "Type": 33, + "Flags": 0 + }, + { + "Id": 964, + "Type": 29, + "Flags": 1 + }, + { + "Id": 965, + "Type": 29, + "Flags": 1 + }, + { + "Id": 966, + "Type": 29, + "Flags": 1 + }, + { + "Id": 967, + "Type": 29, + "Flags": 1 + }, + { + "Id": 968, + "Type": 28, + "Flags": 1 + }, + { + "Id": 969, + "Type": 28, + "Flags": 1 + }, + { + "Id": 970, + "Type": 28, + "Flags": 1 + }, + { + "Id": 971, + "Type": 28, + "Flags": 1 + }, + { + "Id": 972, + "Type": 28, + "Flags": 1 + }, + { + "Id": 973, + "Type": 28, + "Flags": 1 + }, + { + "Id": 988, + "Type": 8, + "Flags": 0 + }, + { + "Id": 989, + "Type": 8, + "Flags": 0 + }, + { + "Id": 990, + "Type": 22, + "Flags": 0 + }, + { + "Id": 991, + "Type": 22, + "Flags": 0 + }, + { + "Id": 992, + "Type": 8, + "Flags": 0 + }, + { + "Id": 993, + "Type": 8, + "Flags": 0 + }, + { + "Id": 998, + "Type": 8, + "Flags": 0 + }, + { + "Id": 999, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1000, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1001, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1002, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1003, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1004, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1005, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1006, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1007, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1008, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1009, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1010, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1011, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1012, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1013, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1014, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1015, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1016, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1017, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1018, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1019, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1020, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1021, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1022, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1023, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1028, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1029, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1284, + "Type": 27, + "Flags": 1 + }, + { + "Id": 1285, + "Type": 27, + "Flags": 1 + }, + { + "Id": 1332, + "Type": 24, + "Flags": 1 + }, + { + "Id": 1449, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1450, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1453, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1454, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1455, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1456, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1457, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1458, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1459, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1460, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1461, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1462, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1463, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1464, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1465, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1466, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1467, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1468, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1469, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1470, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1473, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1474, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1475, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1476, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1477, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1478, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1479, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1480, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1481, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1482, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1483, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1484, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1495, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1496, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1497, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1498, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1499, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1500, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1501, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1502, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1503, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1504, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1515, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1516, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1517, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1518, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1519, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1520, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1524, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1525, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1526, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1543, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1544, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1545, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1546, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1563, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1564, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1565, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1566, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1567, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1568, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1570, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1571, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1572, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1573, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1574, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1583, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1584, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1585, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1586, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1587, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1588, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1589, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1590, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1591, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1592, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1593, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1594, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1613, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1614, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1615, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1618, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1636, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1637, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1639, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1647, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1648, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1649, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1650, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1651, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1652, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1653, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1654, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1655, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1656, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1657, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1658, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1659, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1660, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1665, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1666, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1667, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1670, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1671, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1672, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1673, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1674, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1675, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1676, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1677, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1678, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1679, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1681, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1682, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1683, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1684, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1685, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1724, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1725, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1726, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1727, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1728, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1729, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1730, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1731, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1732, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1733, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1734, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1735, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1736, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1737, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1738, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1739, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1740, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1741, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1742, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1743, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1744, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1745, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1746, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1747, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1748, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1749, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1752, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1753, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1754, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1755, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1756, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1757, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1758, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1759, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1760, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1761, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1762, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1763, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1764, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1765, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1766, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1767, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1768, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1769, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1770, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1771, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1772, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1773, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1774, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1775, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1776, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1777, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1778, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1779, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1780, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1781, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1782, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1783, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1784, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1785, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1786, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1787, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1788, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1789, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1790, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1791, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1792, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1793, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1899, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1900, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1901, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1902, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1903, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1904, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1905, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1906, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1907, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1908, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1909, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1910, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1911, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1912, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1913, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1914, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1915, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1916, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1917, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1918, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1919, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1920, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1921, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1922, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1923, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1924, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1925, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1926, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1927, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1928, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1929, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1930, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1931, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1932, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1933, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1934, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1935, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1936, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1937, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1938, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1939, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1940, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1941, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1942, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1943, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1944, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1945, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1946, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1947, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1948, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1951, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1952, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1953, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1954, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1957, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1958, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1959, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1960, + "Type": 20, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 1, + "High": 49161, + "Low": 12290 + }, + { + "Id": 2, + "High": 604028938, + "Low": 12290 + }, + { + "Id": 3, + "High": 49163, + "Low": 12290 + }, + { + "Id": 4, + "High": 604028939, + "Low": 12290 + }, + { + "Id": 5, + "High": 10485772, + "Low": 14274 + }, + { + "Id": 6, + "High": 10485764, + "Low": 14274 + }, + { + "Id": 7, + "High": 12, + "Low": 14274 + }, + { + "Id": 8, + "High": 12, + "Low": 12290 + }, + { + "Id": 9, + "High": 0, + "Low": 12290 + }, + { + "Id": 10, + "High": 10485761, + "Low": 12290 + }, + { + "Id": 11, + "High": 10485763, + "Low": 12290 + }, + { + "Id": 12, + "High": 1, + "Low": 12290 + }, + { + "Id": 13, + "High": 10485765, + "Low": 14274 + }, + { + "Id": 14, + "High": 10485766, + "Low": 14274 + }, + { + "Id": 15, + "High": 10485767, + "Low": 14274 + }, + { + "Id": 16, + "High": 10485768, + "Low": 14274 + }, + { + "Id": 17, + "High": 2, + "Low": 12290 + }, + { + "Id": 18, + "High": 4194316, + "Low": 145354 + }, + { + "Id": 19, + "High": 6291468, + "Low": 14282 + }, + { + "Id": 20, + "High": 2146316, + "Low": 14274 + }, + { + "Id": 21, + "High": 12, + "Low": 26562 + }, + { + "Id": 22, + "High": 11, + "Low": 12290 + }, + { + "Id": 23, + "High": 12, + "Low": 14282 + }, + { + "Id": 24, + "High": 9, + "Low": 12298 + }, + { + "Id": 25, + "High": 12, + "Low": 12298 + }, + { + "Id": 26, + "High": 10, + "Low": 12298 + }, + { + "Id": 27, + "High": 9, + "Low": 12290 + }, + { + "Id": 28, + "High": 2097164, + "Low": 14282 + }, + { + "Id": 29, + "High": 2097164, + "Low": 14274 + }, + { + "Id": 30, + "High": 49164, + "Low": 14274 + }, + { + "Id": 31, + "High": 49164, + "Low": 12290 + }, + { + "Id": 32, + "High": 8388620, + "Low": 143370 + }, + { + "Id": 33, + "High": 8388620, + "Low": 145354 + }, + { + "Id": 34, + "High": 10, + "Low": 12290 + }, + { + "Id": 35, + "High": 13, + "Low": 12290 + }, + { + "Id": 36, + "High": 14, + "Low": 12290 + } + ], + "Cams": [ + { + "Data": 1966086, + "PositionIndex": 3 + }, + { + "Data": 1966086, + "PositionIndex": 6 + }, + { + "Data": 1966086, + "PositionIndex": 0 + }, + { + "Data": 1441795, + "PositionIndex": 4 + }, + { + "Data": 1441795, + "PositionIndex": 5 + }, + { + "Data": 1441795, + "PositionIndex": 7 + }, + { + "Data": 1441795, + "PositionIndex": 8 + }, + { + "Data": 1441795, + "PositionIndex": 2 + }, + { + "Data": 1441795, + "PositionIndex": 1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 131072, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 84, + "y": -38 + }, + { + "Flag": 3, + "x": 57, + "y": -18 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 72, + "y": -32 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 60, + "y": 18 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 73, + "y": 61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 74, + "y": 66 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 9", + "Start": "02BEB000", + "End": "02BFC610", + "RemapStart": null + }, + "Id": 9, + "TActors": [ + "01FF 0AFF 0023 FD66 009B 059A AFA5 013F", + "03FF 08FF 0023 0386 00AC FCF7 1F4A 013F", + "02FF 03FF 0023 0032 0014 0102 44FA 013F", + "01FF 02FF 0023 FF8B 0006 025C C000 013F", + "01FF 00FF 0023 009A 0007 076B 4000 013F", + "03FF 04FF 0023 FF05 0009 FE95 C000 013F", + "04FF 05FF 0023 FE4F 001A FC3D 9E94 013F", + "06FF 05FF 0023 FAC7 0084 FFAF 9C72 013F", + "08FF 09FF 0023 0383 00AC F9E8 CD83 013F", + "03FF 0BFF 0023 02FC FFE5 001B EAAB 013F", + "07FF 0AFF 002E FC9E 0050 04C0 20B6 003F", + "06FF 07FF 002E FAC4 0118 02D9 2000 0054" + ], + "Paths": [ + { + "Points": [ + [ + 603, + 206, + 1826 + ], + [ + 553, + 32, + 1882 + ], + [ + 511, + 32, + 2001 + ], + [ + 560, + 32, + 2154 + ], + [ + 192, + 32, + 2575 + ], + [ + -31, + 32, + 2587 + ] + ] + }, + { + "Points": [ + [ + 298, + 498, + -134 + ], + [ + 302, + 55, + 60 + ], + [ + 255, + 55, + 211 + ], + [ + -7, + 55, + 265 + ], + [ + -327, + 55, + 322 + ] + ] + }, + { + "Points": [ + [ + -638, + 452, + -1163 + ], + [ + -453, + 63, + -974 + ], + [ + -359, + 51, + -824 + ], + [ + -382, + 63, + -671 + ], + [ + -500, + 85, + -545 + ], + [ + -445, + 70, + -356 + ] + ] + }, + { + "Points": [ + [ + 1475, + 702, + -1248 + ], + [ + 1308, + 231, + -911 + ], + [ + 1080, + 231, + -644 + ] + ] + }, + { + "Points": [ + [ + 900, + 700, + -1694 + ], + [ + 1062, + 230, + -1560 + ], + [ + 1059, + 230, + -1483 + ], + [ + 1056, + 230, + -1402 + ], + [ + 969, + 230, + -1236 + ], + [ + 962, + 230, + -1166 + ], + [ + 955, + 230, + -1101 + ], + [ + 1024, + 230, + -996 + ], + [ + 1024, + 230, + -954 + ], + [ + 1024, + 230, + -954 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 9, Room 0", + "Start": "02BFD000", + "End": "02C05660", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 0144 0003 08E8 0000 0000 0000 0000", + "01C7 011F 0003 092A 0000 0000 0000 0000", + "0130 0258 0004 0725 0000 0000 0001 0D00", + "0111 00F8 000A 08EF 0000 0000 0000 4003", + "0112 00C3 0002 0A2D 0000 0000 0000 3FE8", + "0112 00A8 0002 09E5 0000 0000 0000 3FE8" + ] + }, + { + "File": { + "Name": "Scene 9, Room 1", + "Start": "02C06000", + "End": "02C12540", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "0121 0004 FFF6 0422 0000 0000 0000 0000", + "001B FF7C FFF6 04E4 0000 0000 0000 FFFE", + "001B 008C FFF6 04E8 0000 0000 0000 FFFE", + "01C7 00CC 01A4 038E 0000 0000 0000 0001", + "01C7 010C 01A4 03D4 0000 0000 0000 0001", + "0111 0033 000B 02CE 0000 0000 0000 4A03", + "0111 0034 000A 0300 0000 0000 0000 4C03", + "012A 0140 0062 0374 1111 F333 02D8 2813", + "01B4 FFCD 0033 0348 4000 0000 0000 2801", + "01B4 0031 0033 0348 4000 0000 0000 2801", + "01B4 0031 0097 0348 4000 0000 0000 2801", + "01B4 FFCD 0097 0348 4000 0000 0000 2801" + ] + }, + { + "File": { + "Name": "Scene 9, Room 2", + "Start": "02C13000", + "End": "02C18AF0", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 FEE0 000C 0192 0000 0000 0000 0000", + "01C7 FF2C 000D 018E 0000 0000 0000 0000", + "01C7 FEA1 000B 01A7 0000 0000 0000 0000", + "01C7 FEFE 000B 01CD 0000 0000 0000 0000", + "0130 012A 01C3 0040 0000 0000 0001 0D01", + "01C7 FFED 000D 00C1 0000 0000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 9, Room 3", + "Start": "02C19000", + "End": "02C21080", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 0280 0000 FEC8 0000 0000 0000 0000", + "01C7 0266 0000 FEDC 0000 0000 0000 0000", + "01C7 0255 0000 FF00 0000 0000 0000 0000", + "01C7 0256 0000 FF2B 0000 0000 0000 0000", + "01C7 025F 0000 FF56 0000 0000 0000 0000", + "01AF 010F 0000 FE6F 0000 0000 0000 FF01", + "0121 FFDD 0000 FE67 0000 3BBC 0000 FFFF", + "0121 021D 0000 FE09 0000 E2D8 0000 FFFF", + "01C8 02B3 0007 FF27 0000 AE39 0000 0500", + "00EF FF7A 0000 FE32 0000 0000 0000 0021", + "00EF FF87 0000 FE5E 0000 0000 0000 0022", + "00EF FF72 0000 FE87 0000 0000 0000 0023", + "0111 01B1 0000 FD24 0000 0000 0000 4E12", + "0111 0239 0000 FF51 0000 0000 0000 5001", + "00EF 0241 00AC FCCE 0000 0000 0000 0029", + "0111 0209 0000 FF7D 0000 0000 0000 5203", + "00EF 0266 00AC FCFE 0000 0000 0000 002A", + "00EF 0290 00AC FD2E 0000 0000 0000 002B", + "0111 008A 0000 FD60 0000 0000 0000 5812" + ] + }, + { + "File": { + "Name": "Scene 9, Room 4", + "Start": "02C22000", + "End": "02C29670", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 FEFB 001F FCB8 0000 0000 0000 0000", + "0130 FD82 01C1 FB75 0000 0000 0001 0D02", + "0112 FE70 0013 FE48 0000 0000 0000 3FE6", + "0112 FE49 0013 FE65 0000 0000 0000 3FE6", + "0112 FE1E 0014 FE7E 0000 0000 0000 3FE6" + ] + }, + { + "File": { + "Name": "Scene 9, Room 5", + "Start": "02C2A000", + "End": "02C32890", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "00F0 F86A 0096 FD4E 0000 0000 0000 FFFF", + "01D1 F8EE 0000 FD49 0000 0000 0000 11FF", + "01C9 FB6E 0077 FAA2 0000 0000 0009 18FF", + "01AF F9E4 0029 FC43 0000 4000 0000 FF01", + "01AF FB7C 003D FD55 0000 40B6 0000 FF01", + "0013 F941 0155 FD14 0000 4000 0000 0004", + "0013 F947 0155 FD7F 0000 4000 0000 0004", + "0095 FB80 00B9 F987 0000 2889 0000 8A01", + "0095 FA8E 0000 FF17 0000 8000 0000 8A04", + "012A FD2E 00DB FCB3 8000 0000 0000 2613", + "01B4 FA47 0032 FF06 0000 0000 4000 2601", + "01B4 FAAC 0032 FF06 0000 0000 4000 2601", + "01B4 FA8E 0064 FF06 0000 0000 0000 2601", + "01B4 FA8E 0032 FEFC 4000 0000 0000 2601", + "00EF FA62 0078 FF65 0000 0000 0000 002D", + "00EF FA96 0078 FF61 0000 0000 0000 002E", + "00EF FAC9 0078 FF61 0000 0000 0000 002F", + "01C7 FD05 00AE FC80 0000 0000 0000 0002" + ] + }, + { + "File": { + "Name": "Scene 9, Room 6", + "Start": "02C33000", + "End": "02C37260", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 FA31 0162 0239 0000 0000 0000 0001", + "01C7 F9D1 0193 0261 0000 0000 0000 0001", + "01C7 FA0C 01BB 0146 0000 0000 0000 0001", + "0013 F9DB 0175 01FA 0000 A222 0000 0004", + "0013 FACE 015C 009F 0000 3333 0000 0004", + "0111 FAB8 0111 027F 0000 0000 0000 5412", + "0111 FA8C 010B 0254 0000 0000 0000 560E" + ] + }, + { + "File": { + "Name": "Scene 9, Room 7", + "Start": "02C38000", + "End": "02C3D8F0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "006B", + "008A", + "000E", + "0090", + "0032" + ], + "Actors": [ + "01C8 FC80 0116 0498 C000 2000 0000 FF02", + "0048 FBAC 0122 0294 0000 0000 0000 0008", + "000A FC13 0118 042C 0000 216C 0000 15C2", + "0002 FBB8 011A 03C4 0000 9A50 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 9, Room 8", + "Start": "02C3E000", + "End": "02C3F950", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "0121 0455 00AC FB43 0000 0000 0000 0000", + "0121 04C3 00AC FBCC 0000 0000 0000 0000", + "0130 05BE 02C3 FB25 0000 0000 0001 0D03", + "0130 0381 02AF F969 0000 0000 0001 0D04", + "0112 0432 00AC FD2E 0000 0000 0000 3FE7", + "0112 0456 00AC FD70 0000 0000 0000 3FE7" + ] + }, + { + "File": { + "Name": "Scene 9, Room 9", + "Start": "02C40000", + "End": "02C48650", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "0121 0358 00B6 F695 0000 0000 0000 0000", + "0121 0129 0106 F60F 0000 0EEF 0000 0000", + "00F0 025A 00E2 F65C 0000 0000 0000 FFFF", + "01D1 010C 0070 F7EF 0000 0000 0000 10FF", + "01D1 0115 0070 F76C 0000 0CCD 0000 10FF", + "0121 02C8 0016 F6FF 0000 0000 0000 FFFF", + "01C7 02E6 0016 F660 0000 0000 0000 0000", + "01C7 030F 0016 F66B 0000 0000 0000 0000", + "01C7 0387 0016 F6CF 0000 0000 0000 0000", + "01C7 03A1 0016 F701 0000 0000 0000 0000", + "0111 0386 0016 F560 0000 0000 0000 6E0B", + "0111 01C3 0016 F55A 0000 0000 0000 6C0B", + "000A 0113 0106 F5D0 0000 8EEF 0000 0800", + "0015 04AC 00B7 F749 0000 0000 0000 0106", + "0095 0178 00D5 F800 0000 0000 0000 8A02", + "012A 0294 FFCB F754 0000 0000 0000 2713", + "01B4 04A8 00DE F744 0000 1C72 0000 2701", + "01B4 04A8 0106 F744 0000 1C72 0000 2701", + "00EF 0178 00D5 F800 0000 0000 0000 003B" + ] + }, + { + "File": { + "Name": "Scene 9, Room 10", + "Start": "02C49000", + "End": "02C4D3E0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [] + }, + { + "File": { + "Name": "Scene 9, Room 11", + "Start": "02C4E000", + "End": "02C53900", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "00EF 04B1 FFB9 0288 0000 0000 0000 02FF", + "00F0 05D3 FFEA 019D 0000 0000 0000 FFFF", + "01C7 0541 FFB9 0104 0000 0000 0000 0000", + "01C7 055F FFB9 0123 0000 0000 0000 0000", + "01C7 0540 FFB9 014C 0000 0000 0000 0000", + "01C7 052D FFB9 0171 0000 0000 0000 0000", + "01C7 0529 FFB9 019A 0000 0000 0000 0000", + "01C7 052F FFB9 01BA 0000 0000 0000 0000", + "01C7 0536 FFB9 01D9 0000 0000 0000 0000", + "01C7 047D FFB9 0040 0000 0000 0000 0000", + "01C7 0492 FFB9 0061 0000 0000 0000 0000", + "01AF 04DE FFB9 016B 0000 0000 0000 FF00", + "01AF 04D9 FFB9 0075 0000 0000 0000 FF00", + "0095 0463 001D 004F 0000 1D28 0000 0000", + "000A 04B2 FFB9 0289 0000 0000 0003 B821", + "012A 045A FFA8 0068 0000 0000 0000 0303", + "011B 05D4 FFC3 019E 0014 0000 0014 4689" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 678, + "Type": 0, + "Flags": 1 + }, + { + "Id": 679, + "Type": 0, + "Flags": 1 + }, + { + "Id": 680, + "Type": 0, + "Flags": 1 + }, + { + "Id": 681, + "Type": 0, + "Flags": 1 + }, + { + "Id": 682, + "Type": 0, + "Flags": 1 + }, + { + "Id": 683, + "Type": 0, + "Flags": 1 + }, + { + "Id": 684, + "Type": 0, + "Flags": 1 + }, + { + "Id": 685, + "Type": 0, + "Flags": 1 + }, + { + "Id": 686, + "Type": 0, + "Flags": 1 + }, + { + "Id": 687, + "Type": 0, + "Flags": 1 + }, + { + "Id": 688, + "Type": 0, + "Flags": 1 + }, + { + "Id": 689, + "Type": 0, + "Flags": 1 + }, + { + "Id": 690, + "Type": 0, + "Flags": 1 + }, + { + "Id": 691, + "Type": 0, + "Flags": 1 + }, + { + "Id": 692, + "Type": 0, + "Flags": 1 + }, + { + "Id": 693, + "Type": 0, + "Flags": 1 + }, + { + "Id": 694, + "Type": 0, + "Flags": 1 + }, + { + "Id": 695, + "Type": 0, + "Flags": 1 + }, + { + "Id": 696, + "Type": 0, + "Flags": 1 + }, + { + "Id": 697, + "Type": 0, + "Flags": 1 + }, + { + "Id": 1490, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1491, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1598, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1599, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1600, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1601, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1602, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1603, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1606, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1607, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1608, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1609, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1610, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1611, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1614, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1615, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1622, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1623, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1624, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1625, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1626, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1627, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1628, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1629, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1630, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1631, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1632, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1636, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1637, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1639, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1641, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1642, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1643, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1644, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1647, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1648, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1649, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1650, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1651, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1652, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1653, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1654, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1655, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1656, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1657, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1658, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1659, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1660, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1661, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1662, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1663, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1664, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1665, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1666, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1667, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1686, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1687, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1688, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1689, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1693, + "Type": 42, + "Flags": 1 + }, + { + "Id": 1733, + "Type": 42, + "Flags": 1 + }, + { + "Id": 2002, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2022, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2023, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2024, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2056, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2057, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2066, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2067, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2071, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2082, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2083, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2088, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2089, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2090, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2091, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2092, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2093, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2094, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2095, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2096, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2097, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2098, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2103, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2104, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2113, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2114, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2115, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2116, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2117, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2118, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2119, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2120, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2121, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2122, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2123, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2124, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2125, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2126, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2127, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2128, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2129, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2130, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2131, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2132, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2133, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2134, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2135, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2136, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2137, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2138, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2139, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2140, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2141, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2142, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2143, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2144, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2304, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2305, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2306, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2307, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2308, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2309, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2310, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2311, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2312, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2313, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2314, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2315, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2316, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2317, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2318, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2319, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2320, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2321, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2322, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2323, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2324, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2325, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2326, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2327, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2328, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2329, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2330, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2331, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2332, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2333, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2337, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2338, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2341, + "Type": 49, + "Flags": 0 + }, + { + "Id": 2342, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2343, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2344, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2345, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2346, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2384, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2385, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2386, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2387, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2475, + "Type": 51, + "Flags": 0 + }, + { + "Id": 2487, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2488, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2489, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2490, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2491, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2492, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2493, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2573, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2574, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2575, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2576, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2577, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2578, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2579, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2580, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2593, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2594, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2595, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2665, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2666, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2667, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2668, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2669, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2670, + "Type": 54, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 0, + "High": 0, + "Low": 18376 + }, + { + "Id": 1, + "High": 1, + "Low": 16402 + }, + { + "Id": 2, + "High": 49153, + "Low": 51272 + }, + { + "Id": 3, + "High": 49153, + "Low": 16386 + }, + { + "Id": 4, + "High": 49153, + "Low": 16392 + }, + { + "Id": 5, + "High": 49154, + "Low": 16392 + }, + { + "Id": 6, + "High": 49153, + "Low": 16402 + }, + { + "Id": 7, + "High": 1, + "Low": 16386 + }, + { + "Id": 8, + "High": 49409, + "Low": 802818 + }, + { + "Id": 9, + "High": 0, + "Low": 16392 + }, + { + "Id": 10, + "High": 1, + "Low": 16408 + }, + { + "Id": 11, + "High": 40963, + "Low": 51340 + }, + { + "Id": 12, + "High": 3, + "Low": 51352 + }, + { + "Id": 13, + "High": 3, + "Low": 16536 + }, + { + "Id": 14, + "High": 3, + "Low": 51336 + }, + { + "Id": 15, + "High": 3, + "Low": 16520 + }, + { + "Id": 16, + "High": 2, + "Low": 16392 + }, + { + "Id": 17, + "High": 2, + "Low": 51272 + }, + { + "Id": 18, + "High": 2, + "Low": 16456 + }, + { + "Id": 19, + "High": 40962, + "Low": 16396 + }, + { + "Id": 20, + "High": 2, + "Low": 16520 + }, + { + "Id": 21, + "High": 2, + "Low": 51336 + }, + { + "Id": 22, + "High": 40962, + "Low": 16460 + }, + { + "Id": 23, + "High": 2, + "Low": 51464 + }, + { + "Id": 24, + "High": 2, + "Low": 16648 + }, + { + "Id": 25, + "High": 2, + "Low": 16408 + }, + { + "Id": 26, + "High": 0, + "Low": 18392 + }, + { + "Id": 27, + "High": 3, + "Low": 16642 + }, + { + "Id": 28, + "High": 3, + "Low": 51458 + }, + { + "Id": 30, + "High": 49154, + "Low": 51464 + }, + { + "Id": 31, + "High": 0, + "Low": 51464 + }, + { + "Id": 32, + "High": 40961, + "Low": 51468 + }, + { + "Id": 33, + "High": 2097152, + "Low": 18376 + }, + { + "Id": 34, + "High": 2097152, + "Low": 51458 + }, + { + "Id": 35, + "High": 0, + "Low": 16520 + }, + { + "Id": 36, + "High": 805306370, + "Low": 51464 + }, + { + "Id": 37, + "High": 805306370, + "Low": 51468 + }, + { + "Id": 38, + "High": 49154, + "Low": 16456 + }, + { + "Id": 39, + "High": 0, + "Low": 16584 + }, + { + "Id": 41, + "High": 2, + "Low": 51400 + }, + { + "Id": 42, + "High": 0, + "Low": 53192 + }, + { + "Id": 43, + "High": 2, + "Low": 18376 + }, + { + "Id": 44, + "High": 49154, + "Low": 51336 + }, + { + "Id": 45, + "High": 3, + "Low": 51340 + }, + { + "Id": 46, + "High": 2097155, + "Low": 51340 + }, + { + "Id": 47, + "High": 2097152, + "Low": 16520 + }, + { + "Id": 48, + "High": 49154, + "Low": 51272 + }, + { + "Id": 49, + "High": 40962, + "Low": 51336 + }, + { + "Id": 50, + "High": 40962, + "Low": 51340 + }, + { + "Id": 51, + "High": 2, + "Low": 51352 + }, + { + "Id": 52, + "High": 2, + "Low": 16472 + }, + { + "Id": 53, + "High": 2, + "Low": 51276 + }, + { + "Id": 54, + "High": 2, + "Low": 51330 + } + ], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 0, + "x": 66, + "y": -2 + }, + { + "Flag": 1, + "x": 77, + "y": -46 + }, + { + "Flag": 2, + "x": 27, + "y": -45 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 71, + "y": 59 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 48, + "y": 36 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 73, + "y": 67 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 10", + "Start": "02EE3000", + "End": "02EF37B0", + "RemapStart": null + }, + "Id": 10, + "TActors": [ + "0303 02FF 002E 0000 012C 01FA 8000 008A", + "0505 04FF 002E FE06 0230 0000 4000 007F", + "0101 00FF 002E 01FA 0028 0000 C000 007F", + "0700 00FF 002E FE70 0000 0000 4000 007F", + "0102 02FF 002E 0000 0104 FE70 0000 008A", + "0304 04FF 002E 0190 0208 0000 C000 007F", + "08FF 05FF 002E 0000 0320 01F4 0000 0154", + "0606 08FF 002E 01F4 0320 0000 C000 0154", + "09FF 06FF 002E 0000 05F0 01F4 0000 0154" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 10, Room 0", + "Start": "02EF4000", + "End": "02EFBED0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B" + ], + "Actors": [ + "003B FFF3 0000 001D 0000 0000 0000 00FF", + "0025 001A 0000 FF7B 0000 C000 0000 FFFE", + "0025 0023 0000 0077 0000 C000 0000 FFFE", + "0008 00E8 0078 00ED 0000 0000 0000 03F4", + "0008 00F0 0078 FF14 0000 0000 0000 03F4", + "0008 FF14 0078 FF13 0000 0000 0000 03F4", + "0008 FF15 0078 00EF 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 1", + "Start": "02EFC000", + "End": "02F03770", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B" + ], + "Actors": [ + "0008 0285 00B4 FEA6 0000 0000 0000 03F4", + "0008 01C2 00F0 FDE6 0000 0000 0000 03F4", + "0008 01EB 00B4 FF02 0000 0000 0000 03F4", + "0008 016A 00F0 FE82 0000 0000 0000 03F4", + "0008 FFAC 0154 FDF9 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 2", + "Start": "02F04000", + "End": "02F0B850", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B", + "0032", + "000E" + ], + "Actors": [ + "003B 00AE 0104 001D 0000 0000 0000 00FE", + "0008 00EA 0176 00ED 0000 0000 0000 03F4", + "0008 00F0 0176 FF12 0000 0000 0000 03F4", + "0008 FF13 0176 FF12 0000 0000 0000 03F4", + "0008 FF15 0176 00EF 0000 0000 0000 03F4", + "0002 FF49 0104 FFF4 0000 8000 0000 FFFF", + "0002 00A1 0104 FFF9 0000 8000 0000 FFFF", + "0049 0002 0104 FFFF 0000 0000 0000 6FCA", + "0187 FFA2 0104 FFF5 0000 0000 0000 2BFF", + "000A FFFF 0104 FFFF 0000 0000 0000 27EB" + ] + }, + { + "File": { + "Name": "Scene 10, Room 3", + "Start": "02F0C000", + "End": "02F13730", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B", + "0032", + "000E" + ], + "Actors": [ + "003B 0025 012C 026E 0000 0000 0000 00FD", + "0008 0159 01B8 0284 0000 0000 0000 03F4", + "0008 00FF 01B8 01EA 0000 0000 0000 03F4", + "0008 0219 01F4 01C3 0000 0000 0000 03F4", + "0008 0181 01F4 0169 0000 0000 0000 03F4", + "0008 0208 0258 FFAC 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 4", + "Start": "02F14000", + "End": "02F1D0D0", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "0106", + "000E" + ], + "Actors": [ + "003B 0025 0208 FF86 0000 0000 0000 00FC", + "0113 FEDD 0208 0025 0000 4000 0000 FF02", + "0113 FEDE 0208 FFE0 0000 4000 0000 FF03", + "0008 00EA 0276 00EE 0000 0000 0000 03F4", + "0008 00F1 0276 FF14 0000 0000 0000 03F4", + "0008 FF14 0276 FF14 0000 0000 0000 03F4", + "0008 FF16 0276 00EE 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 5", + "Start": "02F1E000", + "End": "02F26B10", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [ + "003B FD76 0230 0010 0000 0000 0000 00FB", + "0008 FD7C 02D0 01BE 0000 0000 0000 03F4", + "0008 FE16 02D0 0163 0000 0000 0000 03F4", + "0008 FE95 030C 01E4 0000 0000 0000 03F4", + "0008 FE3D 030C 027F 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 6", + "Start": "02F27000", + "End": "02F30BA0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [ + "003B 0012 05F0 0335 0000 0000 0000 00F9" + ] + }, + { + "File": { + "Name": "Scene 10, Room 7", + "Start": "02F31000", + "End": "02F3B7A0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B", + "00B0" + ], + "Actors": [ + "003B 0143 FF24 027F 0000 0000 0000 00FF", + "0013 0053 008C 023C 0000 0000 0000 0000", + "0013 00E1 008C 028A 0000 0000 0000 0000", + "0013 016D 008C 023F 0000 0000 0000 0000", + "0013 FEA0 001B 01DD 0000 0000 0000 0000", + "0013 FDF9 00A0 0007 0000 0000 0000 0000", + "0013 FDEC 004E 0168 0000 0000 0000 0000", + "0013 FF53 FFDB 0291 0000 0000 0000 0000", + "005E 008D FF24 01CC 0000 0000 0000 2400", + "005E 0126 FF24 01CD 0000 0000 0000 2400", + "005E FDB5 0000 FFBC 0000 0000 0000 2400", + "005E FE3A 0000 FFBC 0000 0000 0000 2400" + ] + }, + { + "File": { + "Name": "Scene 10, Room 8", + "Start": "02F3C000", + "End": "02F42BE0", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [ + "003B FFF9 030C 00C5 0000 0000 0000 00FA", + "0111 FE5A 0320 FEFE 0000 0000 0000 400E", + "0111 FE82 0320 FED4 0000 0000 0000 4203", + "0111 FEAA 0320 FEAB 0000 0000 0000 440F", + "0111 FED6 0320 FE81 0000 0000 0000 460F", + "0111 FEFF 0320 FE58 0000 0000 0000 4803", + "0111 FE82 0320 FEFD 0000 0000 0000 4A09", + "0111 FEAA 0320 FED4 0000 0000 0000 4C09", + "0111 FED3 0320 FEAB 0000 0000 0000 4E03", + "0111 FEFE 0320 FE81 0000 0000 0000 503F", + "0111 01A2 0320 FEFB 0000 0000 0000 523F", + "0111 0179 0320 FED3 0000 0000 0000 5409", + "0111 0152 0320 FEAC 0000 0000 0000 5609", + "0111 012C 0320 FE84 0000 0000 0000 5803", + "0111 0104 0320 FE5C 0000 0000 0000 5A03", + "0111 017A 0320 FEFB 0000 0000 0000 5C03", + "0111 0151 0320 FED4 0000 0000 0000 5E3F", + "0111 012B 0320 FEAC 0000 0000 0000 603F", + "0111 0104 0320 FE84 0000 0000 0000 6209" + ] + }, + { + "File": { + "Name": "Scene 10, Room 9", + "Start": "02F43000", + "End": "02F48920", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 2097155, + "PositionIndex": 0 + }, + { + "Data": 2097155, + "PositionIndex": 1 + }, + { + "Data": 2097155, + "PositionIndex": 2 + }, + { + "Data": 2097155, + "PositionIndex": 3 + }, + { + "Data": 2097155, + "PositionIndex": 4 + }, + { + "Data": 2097155, + "PositionIndex": 5 + }, + { + "Data": 2097155, + "PositionIndex": 6 + }, + { + "Data": 0, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [], + "Minimaps": [] + }, + { + "File": { + "Name": "Scene 11", + "Start": "02875000", + "End": "02886530", + "RemapStart": null + }, + "Id": 11, + "TActors": [ + "06FF 08FF 0023 0320 FFB0 FA10 C000 003F", + "02FF 01FF 002E F9D4 FFB0 FD94 0000 009F", + "03FF 02FF 002E F9D5 00A0 F789 0000 009C", + "0AFF 03FF 002E F9D7 009F F257 0000 007F", + "08FF 00FF 002E FFC4 FFB0 FBB4 0000 003F", + "07FF 00FF 002E 035C FFB0 FF4C C000 009A", + "01FF 00FF 002E FC2C FFB0 FF4C 4000 0098", + "04FF 03FF 002E FCF7 00EF F545 C000 007F", + "04FF 05FF 002E 0337 FFAF F544 4000 0099", + "06FF 05FF 002E 05A3 FFAF F698 8000 0099", + "09FF 06FF 002E 0782 FF10 FA48 C000 008C", + "06FF 07FF 002E 05C8 FFB1 FDA8 0000 009E", + "08FF 04FF 002E FFB2 00EF F7F4 8000 0084", + "08FF 08FF 002E FDE4 FFB0 FB50 4000 003F", + "08FF 08FF 002E FF24 FFB0 FAB0 4000 003F", + "08FF 08FF 002E 0064 FFB0 FAB0 C000 0080", + "08FF 08FF 002E 01F4 FFB0 FB00 0000 003F", + "08FF 08FF 002E FED4 FFB0 F9C0 0000 003F", + "08FF 08FF 002E FD94 FFB0 F880 0000 003F", + "08FF 08FF 002E FFC4 FFB0 F8D0 C000 02DD", + "08FF 08FF 002E 00B4 FFB0 F880 8000 02D4", + "08FF 08FF 002E 0064 FFB0 F970 4000 02D7" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 11, Room 0", + "Start": "02887000", + "End": "02896F90", + "RemapStart": "2886530" + }, + "Id": 0, + "Objects": [ + "004D", + "00A4", + "000E", + "0090", + "00B9", + "0177", + "012F" + ], + "Actors": [ + "000A 009D FFEC FE70 0000 6000 0000 5D47", + "000A FEE8 FFEC FE70 0000 A000 0000 5953", + "005E FF60 FFE8 FF38 0000 0000 0000 1098", + "005E 0028 FFE8 FF38 0000 0000 0000 1098", + "012A FFC4 0118 FFFA 0000 8000 0000 1A02", + "0111 FEBC FFEC FF4F 0000 0000 0000 7603", + "0111 FEBC FFEC FFB8 0000 0000 0000 780F", + "0111 00C5 FFEC FF4D 0000 0000 0000 7A0E", + "0111 00C7 FFEC FFB1 0000 0000 0000 7C03" + ] + }, + { + "File": { + "Name": "Scene 11, Room 1", + "Start": "02897000", + "End": "028A0290", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "004D", + "000E", + "0090", + "0106", + "0183" + ], + "Actors": [ + "0113 F9A3 FFA6 FFED 0000 4E39 0000 FF03", + "000A F976 0078 FE12 0000 8000 001F 89A0", + "0187 F9BA FFA6 FF85 0000 0000 0000 7C3C" + ] + }, + { + "File": { + "Name": "Scene 11, Room 2", + "Start": "028A1000", + "End": "028A5F80", + "RemapStart": "28a0350" + }, + "Id": 2, + "Objects": [ + "004D", + "002C", + "011F", + "000E", + "0090", + "018E", + "011C", + "000B", + "006B", + "0114" + ], + "Actors": [ + "0121 F8A5 FFB0 FC3D 0000 8000 0000 0000", + "01C7 FB40 0140 F813 0000 0000 0000 0002", + "01C7 FB11 0140 F814 0000 0000 0000 0002", + "01C7 FB70 0140 F814 0000 0000 0000 0002", + "01C7 FB19 0111 FB07 0000 0000 0000 0002", + "01C7 FB62 00D8 FB63 0000 0000 0000 0002", + "01C7 FB21 00A0 FBB8 0000 0000 0000 0002", + "01C7 F8A4 0078 FC00 0000 0000 0000 0002", + "01C7 FB13 0066 FC17 0000 0000 0000 0002", + "01C7 FB61 00A0 F7AC 0000 0000 0000 0000", + "01C7 FB4B 00A0 F7E0 0000 0000 0000 0000", + "01C7 FB6E 00A0 F7E0 0000 0000 0000 0000", + "01C7 FB0F 00A0 F7ED 0000 0000 0000 0000", + "01C7 FB2D 00A0 F7FA 0000 0000 0000 0000", + "000C F9D9 00A0 F907 0000 0000 0000 00FF", + "000C F91D 0062 F9BF 0000 C000 0000 00FF", + "000C FA88 FFB0 FC19 0000 C000 0000 00FF", + "0011 F9CB FFB0 FACF 0000 0000 0000 0001", + "012D F9D6 0166 F997 4000 0000 0000 FFC2", + "012D FB3E 0168 F99C 4000 0000 0000 FFC2", + "012D F9D4 0166 FC12 4000 0000 0000 FFC2", + "0011 F9D5 00C1 F9F5 0000 4000 0000 1102", + "0187 F9F2 FFB0 FCAF 0000 0000 0000 705A", + "0117 F9D4 FFB0 FCDC 0000 8000 0000 015C", + "0117 FB23 00A0 F7C0 0000 0000 0000 1FDC", + "0117 F9FA 0035 FA45 0000 0000 0000 1FDC", + "0117 FA38 00C8 FC18 0000 0000 0000 1FDC", + "0117 F8A2 FFB0 FC44 0000 0000 0000 1FDC", + "0117 FB13 FF90 FC65 0000 0000 0000 1FDC", + "012D FA11 00A0 F894 0000 0000 0000 1CC1" + ] + }, + { + "File": { + "Name": "Scene 11, Room 3", + "Start": "028A6000", + "End": "028ADC20", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "004D", + "000E", + "0090", + "0190", + "00A8", + "00A4", + "0032", + "0024", + "006B" + ], + "Actors": [ + "01CD FB7B 0117 F545 0000 C000 0000 0000", + "00F0 F962 00B4 F4D4 0000 4000 0000 FFFF", + "005E F962 0077 F4D4 0000 0000 0000 03FF", + "01D1 FB49 009F F548 0000 4000 0006 38FF", + "0002 FA8C 009F F5CD 0000 0000 0000 0002", + "0002 FA1F 009F F51C 0000 0000 0000 0002", + "0037 F9BC 01C1 F64D 0000 0000 0000 0001", + "0037 FB31 01C1 F54F 0000 C000 0000 0001", + "0037 F9E6 01C1 F551 0000 0D83 0000 0001", + "0187 FA03 0117 F5F4 0000 0000 0000 0C3C", + "0139 F9D7 FFD7 F347 0000 0000 0000 000B", + "00FF F9D7 FFD7 F347 0000 0000 0000 0BC7", + "00FF F9D7 009F F40F 0000 0000 0000 0BC3", + "00EF FCA0 00EF F547 0000 C000 0000 030F", + "000A FACD 009F F4D6 0000 8000 0000 7951" + ] + }, + { + "File": { + "Name": "Scene 11, Room 4", + "Start": "028AE000", + "End": "028B8150", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "004D", + "000E", + "0090", + "000D", + "011C", + "017F", + "002C" + ], + "Actors": [ + "012D FFB7 0044 F545 0000 11C7 0000 FFC0", + "012D FF59 00EF F757 0000 0000 0000 FFC0", + "000A FFBF 0180 F31F 0000 8000 0015 8063", + "012A FFC7 FF69 F48D 0000 0000 0000 0403", + "0112 FFB6 00A7 F546 0000 0000 0001 1093", + "0062 FF9C 0002 F50D FC72 905B 0000 0015", + "0062 FFF2 000B F52A FC72 4FA5 0000 0015", + "0062 FF79 0028 F55C F555 D05B 0000 0015", + "0062 FFCA FFF0 F57C FC72 105B 0000 0015", + "0061 FFB3 FF5F F545 0000 0000 0000 0015", + "0049 FFC7 FF69 F48E 0000 0000 0000 3FFE", + "0049 FF3C FF69 F4BE 0000 0000 0000 3FFE", + "0049 003D FF69 F4C6 0000 0000 0000 3FFE", + "0049 FF06 FF69 F540 0000 0000 0000 3FFE", + "0049 0068 FF69 F54F 0000 0000 0000 3FFE", + "0049 FF30 FF69 F5C6 0000 0000 0000 3FFE", + "0049 002B FF69 F5CD 0000 0000 0000 3FFE", + "0049 FFB0 FF69 F5FB 0000 0000 0000 3FFE" + ] + }, + { + "File": { + "Name": "Scene 11, Room 5", + "Start": "028B9000", + "End": "028BE0E0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "004D", + "000E", + "0090", + "00B7", + "0106", + "0025" + ], + "Actors": [ + "0113 0562 FFBF F53A 0000 C000 0000 FF02", + "0038 05E6 FFAF F487 0000 0000 0000 FFFF", + "0038 0532 FFAF F5F2 0000 705B 0000 FFFF", + "000A 05A6 0064 F544 0000 C000 0038 884E", + "012A 06C9 FF9C F4CD 0000 0000 0000 1000", + "0049 05A6 FFBF F546 0000 0000 0000 2FD0", + "000A 05A1 FFAF F427 0000 8000 0000 7952", + "0187 05A8 FFBF F542 0000 0000 0000 643C", + "012A 05A3 006E F6B4 C000 0000 0000 3803" + ] + }, + { + "File": { + "Name": "Scene 11, Room 6", + "Start": "028BF000", + "End": "028C6F40", + "RemapStart": "28BE190" + }, + "Id": 6, + "Objects": [ + "004D", + "002B", + "005D", + "011C", + "00A4", + "000E", + "0179", + "0170", + "000B" + ], + "Actors": [ + "005E 0595 FF11 FBD7 0000 0000 0000 2400", + "0069 054B FEDD F887 0000 0000 0000 FFFE", + "0069 0678 FEDD F9CE 0000 0000 0000 FFFE", + "0069 0579 FECC FA97 0000 0000 0000 FFFE", + "012A 05E3 FFAF F781 0000 0000 0000 0001", + "012D 041A FFB1 FA10 0000 0000 0000 00C1", + "0117 05D4 FF2A F9EA 0000 0000 0000 018C", + "0117 0618 FF11 F8BB 0000 0000 0000 1FCC", + "0117 046E FF11 F8CF 0000 0000 0000 1FCC", + "0117 057C FF11 F98B 0000 0000 0000 1FCC", + "0117 0618 FF11 FA9C 0000 0000 0000 1FCC", + "0117 043B FF11 FAA2 0000 0000 0000 1FCC", + "0117 0525 FF11 FB25 0000 0000 0000 1FCC", + "012D 0536 FE7B F8B8 0000 0000 0000 0CC1", + "012D 04D1 FE7B F98B 0000 0000 0000 0CC1", + "012D 0641 FE7A F99C 0000 0000 0000 0CC1", + "005E 071D FF10 FA19 0000 0000 0000 107F", + "0049 0619 FF11 F8BE 0000 0000 0000 207F", + "0049 046F FF11 F8CE 0000 0000 0000 207F", + "0049 057E FF11 F98A 0000 0000 0000 207F", + "0049 0619 FF11 FA9C 0000 0000 0000 207F", + "0049 043D FF11 FAA6 0000 0000 0000 207F", + "0049 0523 FF11 FB23 0000 0000 0000 207F" + ] + }, + { + "File": { + "Name": "Scene 11, Room 7", + "Start": "028C7000", + "End": "028CF330", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "004D", + "000E", + "0090", + "0038", + "000C", + "001B" + ], + "Actors": [ + "0025 058E FFB9 FEC6 0000 D8E4 0000 FFFE", + "0025 0644 FFBB FF7C 0000 CFA5 0000 FFFE", + "0025 04CC FFB0 FF3A 0000 CC17 0000 FFFF", + "0012 063F FFB0 FE7C 0000 BE94 0000 FFFF", + "0012 060E FFB0 0023 0000 B555 0000 FFFF", + "0054 04A7 FFEC 0061 0000 6000 0000 FFFF", + "000A 05C9 0078 FF45 0000 8000 001E 8841", + "0187 0611 FFC5 FF55 0000 0000 0000 783C", + "0112 05C9 0070 FDD0 0000 0000 0001 1AE7" + ] + }, + { + "File": { + "Name": "Scene 11, Room 8", + "Start": "028D0000", + "End": "028D8210", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "004D", + "002B", + "005D", + "011C", + "00A4", + "000E", + "0179", + "0170", + "000B" + ], + "Actors": [ + "01CD FEE9 0078 FB64 0000 0000 0000 0001", + "01A0 FFC5 FFB0 F9C2 0000 0000 0000 FFFF", + "0008 0038 00EF F8E9 0000 0000 0000 03F8", + "0008 FF56 00EF F8E9 0000 0000 0000 03F8", + "005E FF63 00C8 FB63 0000 0000 0000 2400", + "005E 0026 00C8 FB63 0000 0000 0000 2400", + "012A FFC4 FFB0 F9C2 0000 0000 0000 0101", + "0112 01F4 FFB0 FAD5 0000 8000 0000 3FC2", + "000A 003A 00F0 F88B 0000 0000 0001 BB24", + "000A 00B6 FFB0 FA11 0000 C000 0000 5885", + "000A FD7F FFB0 F9FE 0000 8000 0000 5986", + "000A 0153 FFB0 F971 0000 0000 0000 5E48", + "000A FED5 FFB0 F82F 0000 C000 0000 5E49", + "000A FE48 FFB0 F81C 0000 8000 0000 59CA", + "000A FFEB 00C9 FB29 0000 4000 0000 5AAB" + ] + }, + { + "File": { + "Name": "Scene 11, Room 9", + "Start": "028D9000", + "End": "028DC8F0", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "004D", + "000E", + "0090", + "00B5", + "0021", + "0059", + "013B", + "011C", + "0026", + "0036", + "0056", + "000B" + ], + "Actors": [ + "018C 08E5 FE47 FA7C 0000 2CCD 0000 0000", + "018C 091A FEA8 FA32 0000 EFA5 0000 0000", + "00D4 0901 FDD5 FA4D 0000 0000 0000 00FF", + "0063 0900 FFD9 FA47 0000 0000 0000 FFFF", + "00C5 08D0 FC40 FA1C 0000 20B6 0000 FFFF", + "012D 0903 FD64 F95A 0000 0000 0000 FFC2", + "012D 09EF FD61 FA46 0000 C000 0000 FFC2", + "012D 0811 FD61 FA48 0000 4000 0000 FFC2", + "012D 0903 FD61 FB38 0000 8000 0000 FFC2", + "000A 0887 FF94 F9D0 0000 C000 001B 884D", + "0117 083D FF66 F9E8 0000 0000 0000 00DB", + "0117 0995 FC86 F9B4 0000 0000 0000 1FDB", + "0117 08FE FCE3 FA48 0000 0000 0000 1FDB", + "0117 0870 FC7C FADD 0000 0000 0000 1FDB", + "000F 08FC FF0B FA47 0000 0000 0000 0FF9" + ] + }, + { + "File": { + "Name": "Scene 11, Room 10", + "Start": "028DD000", + "End": "028E2C60", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "004D", + "000E", + "0090", + "00E5", + "0114" + ], + "Actors": [ + "0121 F9C3 009F F05F 0000 0000 0000 0000", + "0121 F978 00D2 F046 0000 0C17 0000 0000", + "00EC FA3D 008B F099 0000 0000 0000 0000", + "00EC F97A 008B F107 0000 0000 0000 0000", + "00EC FA29 008B F191 0000 0000 0000 0000", + "000A F979 00D2 F043 0000 93E9 0000 7AA2" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 1572867, + "PositionIndex": 0 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [], + "Minimaps": [] + }, + { + "File": { + "Name": "Scene 13", + "Start": "0318E000", + "End": "031AF7C0", + "RemapStart": null + }, + "Id": 13, + "TActors": [ + "10FF 01FF 0023 0000 FF10 012A 8000 003F", + "0BFF 0AFF 0023 F1C9 FF2E FCB8 4000 003F", + "01FF 00FF 002E 0000 0096 0251 0000 007F", + "09FF 09FF 002E F881 FF10 FCB8 4000 007F", + "03FF 02FF 002E 0930 FF06 FCB8 C000 02D6", + "0AFF 08FF 002E F499 FF10 FCB8 4000 02D4", + "06FF 05FF 002E 0487 006E 048F 9555 007F", + "07FF 06FF 002E 06F3 006E 08C1 9555 00B8", + "01FF 05FF 002E 0268 0096 00E3 1555 003F", + "02FF 01FF 002E 04D0 FF10 FCB8 C000 003F", + "01FF 09FF 002E FAD9 FF10 FCB8 C000 003F", + "01FF 0EFF 002E FD98 0096 F88D 9555 003F", + "0CFF 01FF 002E 0268 0096 F88D EAAB 003F", + "04FF 03FF 002E 0DA4 FF10 FCB8 C000 0082", + "0DFF 0CFF 002E 0844 00D2 EE67 EAAB 008B", + "0FFF 0EFF 002E F860 0099 F0EB 1555 0081", + "01FF 11FF 002E FD98 0096 00E3 EAAB 003F", + "12FF 11FF 002E FB1B 0096 02B3 2AAB 008F", + "13FF 12FF 002E FAF0 0096 057D 6AAB 008E", + "08FF 09FF 002E F72F FF10 FCB8 4000 02D5", + "12FF 12FF 002E F993 0096 02B2 6AAB 0088" + ], + "Paths": [ + { + "Points": [ + [ + -27, + 190, + 1079 + ], + [ + -27, + 302, + 1376 + ], + [ + -27, + 412, + 1771 + ], + [ + -27, + 311, + 1374 + ], + [ + -27, + 197, + 1091 + ] + ] + }, + { + "Points": [ + [ + 34, + 242, + 1079 + ], + [ + 34, + 280, + 1246 + ], + [ + 34, + 338, + 1504 + ], + [ + 33, + 366, + 1777 + ], + [ + 35, + 335, + 1504 + ], + [ + 33, + 307, + 1373 + ], + [ + 34, + 287, + 1246 + ], + [ + 34, + 242, + 1094 + ] + ] + }, + { + "Points": [ + [ + -2603, + -270, + -1010 + ], + [ + -2558, + -270, + -994 + ], + [ + -2521, + -270, + -964 + ], + [ + -2493, + -270, + -930 + ], + [ + -2476, + -270, + -887 + ], + [ + -2469, + -270, + -843 + ], + [ + -2472, + -270, + -796 + ], + [ + -2489, + -270, + -754 + ], + [ + -2518, + -270, + -716 + ], + [ + -2555, + -270, + -687 + ], + [ + -2600, + -270, + -666 + ], + [ + -2647, + -270, + -661 + ], + [ + -2694, + -270, + -666 + ], + [ + -2738, + -270, + -683 + ], + [ + -2775, + -270, + -711 + ], + [ + -2802, + -270, + -746 + ], + [ + -2820, + -270, + -792 + ], + [ + -2827, + -270, + -839 + ], + [ + -2820, + -270, + -886 + ], + [ + -2801, + -270, + -931 + ], + [ + -2774, + -270, + -967 + ], + [ + -2737, + -270, + -995 + ], + [ + -2694, + -270, + -1009 + ], + [ + -2647, + -270, + -1014 + ], + [ + -2603, + -270, + -1010 + ] + ] + }, + { + "Points": [ + [ + 860, + 247, + -2283 + ], + [ + 920, + 182, + -2242 + ], + [ + 914, + 84, + -2241 + ], + [ + 860, + 54, + -2274 + ], + [ + 806, + 94, + -2310 + ], + [ + 803, + 185, + -2313 + ], + [ + 860, + 235, + -2284 + ] + ] + }, + { + "Points": [ + [ + -1513, + 176, + 569 + ], + [ + -1511, + 268, + 571 + ] + ] + }, + { + "Points": [ + [ + -1684, + 283, + 854 + ], + [ + -1682, + 194, + 856 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 13, Room 0", + "Start": "031B0000", + "End": "031B91C0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0179", + "005D", + "0106", + "0038", + "0085", + "00A4" + ], + "Actors": [ + "0054 FF91 00D2 0318 0000 0000 0000 FFFF", + "0054 006D 00D2 0318 0000 0000 0000 FFFF", + "0113 0003 0096 02B2 0000 0000 0000 FF02", + "0008 005A 0173 073E 0000 0000 0000 03F5", + "0008 FFA5 0118 05AD 0000 0000 0000 03F5", + "0008 FFA7 0173 073D 0000 0000 0000 03F5", + "0008 005A 0118 05AE 0000 0000 0000 03F5", + "005E FF66 010E 027A 0000 0000 0000 2400", + "005E 0095 010E 0278 0000 0000 0000 2400", + "0069 FFE5 00BE 0437 0000 0000 0000 00FB", + "0069 0022 00F2 0436 0000 0000 0000 11FB", + "0080 0046 0096 0319 0000 C000 0000 0310" + ] + }, + { + "File": { + "Name": "Scene 13, Room 1", + "Start": "031BA000", + "End": "031D69B0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0179", + "000E", + "009A", + "0168", + "004A" + ], + "Actors": [ + "01B6 0000 FF10 0062 0000 8000 0000 0002", + "01A7 0000 FF10 FCB8 0000 0000 0000 0000", + "0097 0000 FF10 FCB8 0000 0000 0000 0005", + "0092 FB44 FF10 FCB8 0000 4000 0000 0401", + "0112 FDA3 0096 00AE 0000 0000 0000 3FF7", + "0112 FDC2 0096 00B9 0000 0000 0000 3FF7" + ] + }, + { + "File": { + "Name": "Scene 13, Room 2", + "Start": "031D7000", + "End": "031DE7E0", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0179", + "006B", + "000E", + "0085", + "00E5", + "013A", + "00A6", + "0114", + "00B7" + ], + "Actors": [ + "00A5 07A7 FF06 FDDF 0000 982E 0000 FFFF", + "0121 0714 FF06 FD69 0000 8666 0000 FFFF", + "0121 0766 FF06 FCBA 0000 DA50 0000 FFFF", + "0121 078C FF06 FBAE 0000 F8E4 0000 FFFF", + "01C7 07C0 FF06 FDC9 0000 0000 0000 0000", + "01C7 0790 FF06 FDD9 0000 0000 0000 0000", + "01C7 077C FF06 FE01 0000 0000 0000 0000", + "01C7 07FC FF06 FDB1 0000 0000 0000 0000", + "01C7 07A8 FF06 FB9D 0000 0000 0000 0000", + "01C7 07D8 FF06 FBA5 0000 0000 0000 0000", + "01C7 074C FF06 FB69 0000 0000 0000 0000", + "01C7 0774 FF06 FB81 0000 0000 0000 0000", + "01C7 0806 003C FD65 0000 0000 0000 0002", + "01C7 0791 003C FD6E 0000 0000 0000 0002", + "01C7 0748 003C FDC8 0000 0000 0000 0002", + "01C7 07D2 003C FBD4 0000 0000 0000 0002", + "01C7 0762 003C FBD4 0000 0000 0000 0002", + "01C7 06FF 003C FB8B 0000 0000 0000 0002", + "00F0 06C4 FF24 FCB8 0000 0000 0000 FFFF", + "00EF 06DA FF06 FB80 0000 0000 0000 00FF", + "00EF 06CF FF06 FDEF 0000 0000 0000 00FF", + "00EF 0830 FF06 FC0D 0000 0000 0000 00FF", + "000A 06D9 FF06 FB81 0000 8E39 0000 59C1", + "00EF 08A1 FF13 FC87 0000 0000 0000 000D", + "00EF 0896 FF0E FCB3 0000 0000 0000 000D", + "00EF 0892 FF12 FCE3 0000 0000 0000 000D", + "00EF 0898 FF15 FD0D 0000 0000 0000 000D", + "012A 07B5 FF06 FDF9 0000 0000 0000 3C03", + "015F 06C6 FF06 FCB7 0004 0006 0005 1F0B", + "0015 06CF FF06 FDF0 0000 0000 0000 3F03" + ] + }, + { + "File": { + "Name": "Scene 13, Room 3", + "Start": "031DF000", + "End": "031E8990", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0179", + "006B", + "0114", + "000D", + "000E", + "0090" + ], + "Actors": [ + "0013 0B4C FFDE FD6D 0000 2889 0000 0004", + "01B7 0BD8 FEC0 FC7C 0000 4000 0000 0000", + "01B7 0AE8 FEC0 FC04 0000 4000 0000 0000", + "0013 0B01 FEE0 FDB3 0000 84FA 0000 0003", + "0013 0B9F FEE2 FD4C 0000 C38E 0000 8003", + "0013 0BC3 FFA1 FBFA 0000 25B0 0000 0000", + "00EF 0B5A FF88 FA36 0000 0000 0000 00FF", + "0117 0AC5 FE5C FD03 0000 0000 0000 1142", + "0117 0B60 FF25 FC35 0000 0000 0000 1142", + "0117 0B59 FF88 FA3A 0000 0000 0000 1142", + "0117 0CB5 FEC6 FD77 0000 0000 0000 1142", + "0117 0B59 FEC0 FB11 0000 0000 0000 1142", + "0117 0A16 FEC0 FCDE 0000 0000 0000 0142", + "00EF 0D2A FF10 FC4A 0000 C000 0000 0006", + "00EF 0D2A FF10 FC87 0000 C000 0000 0006", + "00EF 0D2A FF10 FCBE 0000 C000 0000 0006", + "00EF 0D2A FF10 FCF8 0000 C000 0000 0006", + "00EF 0D2A FF10 FD27 0000 C000 0000 0006" + ] + }, + { + "File": { + "Name": "Scene 13, Room 4", + "Start": "031E9000", + "End": "031F0C90", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0179", + "006B", + "00ED", + "00CA", + "00BA", + "0075" + ], + "Actors": [ + "01A7 0F7A FF2E FCB8 0000 C000 0000 0001", + "00D2 0F7A FFA6 FCB8 2000 C000 0000 0002", + "0008 0F08 FF3B FD2C 0000 0000 0000 03FE", + "0008 0F09 FF3B FC4B 0000 0000 0000 03FE", + "0111 0DD8 FF10 FC5D 0000 0000 0000 7203", + "0111 0DD5 FF10 FD0D 0000 0000 0000 7409" + ] + }, + { + "File": { + "Name": "Scene 13, Room 5", + "Start": "031F1000", + "End": "031F8540", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0179", + "00AA", + "0069", + "0032", + "00A4" + ], + "Actors": [ + "005E 0435 0136 0493 0000 9555 0000 2400", + "0002 03FA 006E 0277 0000 BA50 0000 FFFF", + "0002 02F5 006E 0318 0000 3777 0000 FFFF", + "00BC 0476 015E 0470 0000 9555 0000 0004", + "0015 04B2 0136 044C 0000 0000 0000 0111" + ] + }, + { + "File": { + "Name": "Scene 13, Room 6", + "Start": "031F9000", + "End": "03208BF0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0179", + "0069", + "011C", + "0190", + "00A8", + "0038", + "008B", + "000E", + "0090" + ], + "Actors": [ + "012D 0508 001E 0755 0000 1555 0000 FFC2", + "0054 0666 0032 05D1 0000 D555 0000 FFFF", + "01B4 058F FFB9 084C 0000 1555 0000 FF01", + "0054 058F 015E 084C 0000 1555 0000 0000", + "00BC 0783 00AB 082C 0000 9555 0000 0004", + "00BC 0629 009F 08F4 0000 9555 0000 0004", + "00BC 0550 00A4 045C 0000 1555 0000 0004", + "00BC 03F6 00A4 0524 0000 1555 0000 0004", + "008A 04DF 0032 06ED 0000 1555 0000 0500", + "008A 0718 FFCE 0777 0000 4000 0000 0500", + "008A 064F 0032 0616 0000 0000 0000 0501", + "008A 05F6 0032 070B 0000 2AAB 0000 0501", + "008A 0669 001E 07DB 0000 5555 0000 0501", + "008A 0601 0076 08AB 0000 6AAB 0000 0501", + "000A 04DB 00DC 04B6 0000 5555 0005 8942", + "000A 0699 0096 0627 0000 5555 0007 8023", + "012A 03E5 0097 0505 0000 1555 0000 0502", + "012A 0796 0097 084D 0000 9555 0000 0782", + "012A 058F FFB9 084C 0000 1555 0000 3820", + "01D6 058F 0097 084C 0000 1555 0000 183A", + "01D6 058F 00FA 084C 0000 1555 0000 983A" + ] + }, + { + "File": { + "Name": "Scene 13, Room 7", + "Start": "03209000", + "End": "03210C90", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0179", + "0069", + "00ED", + "00BA", + "00BC", + "0075" + ], + "Actors": [ + "01A7 07DE 008C 0A58 0000 9555 0000 0006", + "00C9 07DE 0104 0A5E 2000 9555 0000 0002", + "0008 0807 0096 09C0 0000 0000 0000 03FB", + "0008 0743 0096 0A32 0000 0000 0000 03FB", + "0111 0751 006E 08CC 0000 0000 0000 6A03", + "0111 06BE 006E 0916 0000 0000 0000 6C0F" + ] + }, + { + "File": { + "Name": "Scene 13, Room 8", + "Start": "03211000", + "End": "0321A070", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0179", + "002C", + "008B", + "011C", + "00B7", + "011F" + ], + "Actors": [ + "012D F5AC 0028 FCB9 4000 0000 0000 FFC2", + "000C F623 FEF2 FC38 0000 1C72 0000 00FF", + "000C F621 FEF2 FD2F 0000 638E 0000 00FF", + "008A F5AB FF88 FCB9 0000 8000 0000 0501", + "0130 F57A FEF2 FC0E 0000 51C7 0000 0C02", + "0015 F5A1 FF10 FDDB 0000 0000 0000 3D03", + "0015 F636 FF10 FBB8 0000 0000 0000 3E03" + ] + }, + { + "File": { + "Name": "Scene 13, Room 9", + "Start": "0321B000", + "End": "03226890", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0179", + "000E", + "0090", + "001B", + "0025" + ], + "Actors": [ + "0008 F7F9 FF5A FC30 0000 0000 0000 83F0", + "0008 F810 FF5A FC30 0000 0000 0000 83F0", + "0008 F805 FF5A FC3B 0000 0000 0000 83F0", + "0008 F7AC FF5B FC3B 0000 0000 0000 83F0", + "0008 F7B7 FF5B FC30 0000 0000 0000 83F0", + "0008 F7A1 FF5B FC30 0000 0000 0000 83F0", + "0038 F90F FF10 FC28 0000 2B61 0000 FFFF", + "0038 F9EE FF10 FD66 0000 CFA5 0000 FFFF", + "0025 F957 FF10 FD30 0000 4C17 0000 FFFE", + "000A F7D5 FF7E FC40 0000 8000 0011 8904", + "012E F77D FF14 FCB6 0000 4000 0001 1C91", + "0112 F74B FF10 FCBB 0000 0000 0000 3FF6" + ] + }, + { + "File": { + "Name": "Scene 13, Room 10", + "Start": "03227000", + "End": "0322DB70", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0179", + "001B", + "00ED", + "00BA", + "00A7", + "0075", + "0024" + ], + "Actors": [ + "01B6 F269 FF2E FCB8 0000 4000 0000 0000", + "0008 F334 FF38 FD28 0000 0000 0000 03FA", + "0008 F333 FF38 FC47 0000 0000 0000 03FA", + "0095 F334 FF3C FD3E 0000 0000 0000 0000", + "01B4 F25E FF60 FCE7 4000 4000 0000 3601", + "01B4 F25E FF60 FC83 4000 4000 0000 3601", + "01B4 F25E FFC4 FCE7 4000 4000 0000 3601", + "01B4 F25E FFC4 FC83 4000 4000 0000 3601", + "012A F333 FF18 FC48 0000 0000 0000 3613" + ] + }, + { + "File": { + "Name": "Scene 13, Room 11", + "Start": "0322E000", + "End": "03234950", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0179", + "001B", + "00ED", + "00BA", + "00A7", + "0075", + "0024" + ], + "Actors": [ + "01A7 EFCB FF4C FCB8 0000 4000 0000 0002", + "00A6 EFCC FFC4 FCB9 2000 4000 0000 0002", + "0008 F03E FF56 FC4C 0000 0000 0000 03FA", + "0008 F03B FF56 FD29 0000 0000 0000 03FA", + "0111 F0FE FF2E FD09 0000 0000 0000 760E", + "0111 F0FB FF2E FC5B 0000 0000 0000 7803" + ] + }, + { + "File": { + "Name": "Scene 13, Room 12", + "Start": "03235000", + "End": "03240370", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0179", + "000E", + "0090", + "0069", + "0031", + "005D", + "008B", + "00A4" + ], + "Actors": [ + "01B4 0624 0096 F125 0000 EAAB 0000 0000", + "005E 0232 0096 F806 0000 1555 0000 2400", + "004C 0512 0096 F728 0000 0000 0000 FFFF", + "00BC 072C 00FC F03A 0000 0889 0000 0000", + "00AF 0500 0096 F57C 0000 2AAB 0000 0000", + "0069 035C 00E8 F716 0000 0000 0000 33FB", + "008A 05FA 0096 EFEA 0000 0000 0000 0500", + "008A 04FE 0096 F3DA 0000 EAAB 0000 0501", + "008A 0632 0096 F19C 0000 0000 0000 0501", + "008A 067F 0096 F1BB 0000 8000 0000 0501", + "000A 0213 00FA F62A 0000 AAAB 0009 8940", + "000A 06DD 01CE F1F5 0000 6AAB 000C 8845", + "0112 0511 0096 F727 0000 0000 0003 1809", + "0117 052A 0096 F72A 0000 0000 0000 1FCB", + "0117 04FF 0096 F3D9 0000 0000 0000 1FCB", + "0117 05F9 0096 EFEB 0000 0000 0000 1FCB", + "0117 0725 0098 F019 0000 0000 0000 1FCB", + "0117 044C 0096 F606 0000 0000 0000 1FCB", + "0117 0281 0096 F827 0000 0000 0000 014B", + "012A 05A3 003F F300 0000 6AAB 0000 0C02", + "01B4 05F6 0096 F27E 0000 EAAB 0000 3D01", + "005E 0505 0064 F354 0000 EAAB 0000 107D" + ] + }, + { + "File": { + "Name": "Scene 13, Room 13", + "Start": "03241000", + "End": "03248D40", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0179", + "00F1", + "016D", + "00BA", + "00ED", + "0087", + "0075" + ], + "Actors": [ + "01A7 092F 00F0 ECD0 0000 EAAB 0000 0004", + "00A9 092E 0168 ECD4 2000 EAAB 0000 0002", + "0008 0956 00FA ED6A 0000 0000 0000 03FD", + "0008 0893 00FA ECFD 0000 0000 0000 03FD", + "0111 0819 00D2 EE10 0000 0000 0000 640E", + "0111 08A9 00D2 EE5C 0000 0000 0000 7009" + ] + }, + { + "File": { + "Name": "Scene 13, Room 14", + "Start": "03249000", + "End": "032531A0", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0179", + "002C", + "0025", + "005D", + "011C", + "009A", + "008B" + ], + "Actors": [ + "012D F9D5 0098 F495 0000 1555 0000 FFC0", + "0038 FA4C 0097 F652 0000 DC72 0000 FFFF", + "0038 FA20 0097 F6DB 0000 24FA 0000 FFFF", + "0046 FB7C 0014 F244 0000 9555 0000 0001", + "0046 FCE9 0014 F74B 0000 D555 0000 0001", + "0046 F8D6 0014 F644 0000 9555 0000 0001", + "0043 FD53 0014 F47E 0000 1555 0000 FF01", + "0043 FAD1 0014 F550 0000 1555 0000 FF01", + "0043 F96F 0014 F36E 0000 1555 0000 FF01", + "0046 FDE3 0014 F58A 0000 1555 0000 0000", + "0046 FC54 0014 F511 0000 1555 0000 0000", + "0046 FCDE 0014 F607 0000 1555 0000 0000", + "0046 FA80 0014 F2CE 0000 1555 0000 0000", + "0046 F83F 0014 F400 0000 1555 0000 0000", + "0092 FC31 003D F158 0000 1555 0000 FF00", + "0092 FA97 003B F749 0000 9555 0000 FF00", + "008A FC6D 0098 F1C1 0000 0000 0000 0500", + "012D F8ED 0099 F10E 0000 1555 0000 01C1", + "0117 FC36 0098 F15D 0000 0000 0000 1FC1", + "0117 F89D 00DE F53F 0000 0000 0000 1FC1", + "0117 F804 00F4 F2E6 0000 0000 0000 1FC1", + "0117 FD52 0280 F47F 0000 0000 0000 1FC1", + "0117 F989 0078 F7AB 0000 0000 0000 1FC1", + "0117 FD8E 0096 F832 0000 0000 0000 0141" + ] + }, + { + "File": { + "Name": "Scene 13, Room 15", + "Start": "03254000", + "End": "0325BD40", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0179", + "002C", + "00BA", + "00ED", + "009D", + "0075" + ], + "Actors": [ + "01A7 F775 00B7 EF54 0000 1555 0000 0003", + "00A8 F775 012F EF58 2000 1555 0000 0002", + "0008 F80F 00C1 EF7B 0000 0000 0000 03FC", + "0008 F74A 00C1 EFEC 0000 0000 0000 03FC", + "0111 F882 0099 F08B 0000 0000 0000 6E03", + "0111 F7FC 0099 F0D0 0000 0000 0000 700F" + ] + }, + { + "File": { + "Name": "Scene 13, Room 16", + "Start": "0325C000", + "End": "0325EE20", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "0179", + "000E", + "009A", + "0168", + "004A" + ], + "Actors": [ + "0195 FF3F FF10 02B6 0000 349F 0000 0000", + "0195 005C FF10 03C9 0000 9555 0000 0005", + "0195 FF43 FF10 0361 0000 5555 0000 0007", + "0195 FFAC FF10 03CA 0000 6AAB 0000 0006", + "0195 00D2 FF10 0366 0000 AAAB 0000 0008", + "0018 FFFF FF72 02F9 0000 0000 0000 0004" + ] + }, + { + "File": { + "Name": "Scene 13, Room 17", + "Start": "0325F000", + "End": "032676A0", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0179", + "016C", + "0106", + "0025", + "000D" + ], + "Actors": [ + "0008 FD5C 0100 039A 00B6 AAAB 0000 83F0", + "0008 FD67 00FF 0386 0000 AB61 0000 83F0", + "0008 FD58 00FF 038A FF4A AAAB 0000 83F0", + "0008 FE24 0100 023F FF4A AAAB 0000 83F0", + "0008 FE2F 00FF 022C 00B6 AAAB 0000 83F0", + "0008 FE20 00FF 0230 0000 AB61 0000 83F0", + "0008 FC25 00FF 0118 0000 2B61 0000 83F0", + "0008 FC30 00FF 0104 00B6 2AAB 0000 83F0", + "0008 FC34 00FF 0114 0000 2B61 0000 83F0", + "0038 FC68 0096 01BF 0000 0000 0000 FFFF", + "0013 FD83 0124 0214 0000 CCCD 0000 0000", + "0013 FC21 010F 02C8 0000 9A50 0000 0000", + "0113 FC4F 019B 0336 0000 6AAB 0000 FF03", + "0169 FCEB 0096 0244 0000 0AAB 0000 0001", + "0169 FCB9 0096 0227 0000 4E39 0000 0001", + "0169 FCCD 0096 0274 0000 CAAB 0000 0001", + "0169 FC9D 0096 0258 0000 8AAB 0000 0001", + "012A FCC2 0096 024C 0000 1555 0000 0F01", + "01B4 FC50 019A 0337 0000 0000 0000 3701", + "012A FD8E 0141 00F4 0000 EAAB 0000 3712" + ] + }, + { + "File": { + "Name": "Scene 13, Room 18", + "Start": "03268000", + "End": "03274670", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0179", + "012A", + "00AB", + "000E", + "0090", + "00A4", + "0163", + "000B", + "000E", + "0090", + "0098", + "005D" + ], + "Actors": [ + "0008 F8FA 00D7 0363 0000 2B61 0000 83F0", + "0008 F8F5 00D7 0354 FF4A 2AAB 0000 83F0", + "0008 F8EA 00D7 0367 0000 2B61 0000 83F0", + "0008 F9E0 00D7 01D5 FF4A 2AAB 0000 83F0", + "0008 F9DB 00D7 01C5 00B6 2AAB 0000 83F0", + "0008 F9D0 00D7 01D9 FF4A 2AAB 0000 83F0", + "0090 FA6B 0096 0415 0000 AAAB 0000 7FFE", + "0090 FBBE 0096 041D 0000 EAAB 0000 7F02", + "0090 FB65 0096 04AA 0000 CD83 0000 7F01", + "0069 FA17 00BE 0237 0000 3333 0000 42FB", + "0069 F96D 010E 0356 0000 693F 0000 52FB", + "000A FABA 0096 04DC 0000 C71C 003C B6C6", + "000A FB96 00FA 0564 0000 0AAB 003E 8907", + "012A F9D0 0172 034F 8000 0000 0000 0803", + "000A FC0D 00FA 047F 0000 4AAB 003D 8848", + "000A FB35 00FA 0400 0000 8AAB 0038 8909", + "01B5 FB69 01C1 04AC 0000 2AAB 0000 0A01", + "01B5 FB69 0096 04AC 0000 2AAB 0000 0A02", + "01B5 FB69 0186 04AC 0000 2AAB 0000 0A00", + "000A F9CE 0096 021F 0000 AAAB 0000 506A", + "0150 FAF8 0145 056E 0000 6AAB 0000 0E00", + "000A F901 0096 037E 0000 AAAB 0000 6954", + "0112 FAFC 0096 029F 0000 0000 0000 3FF7", + "0150 FB33 0136 03E9 0000 0AAB 0000 3830", + "0011 FB4F 0096 04D5 0000 0000 0000 3902", + "0150 FABA 0154 0447 0000 2AAB 0000 3930", + "0150 FBCF 010E 03FE 0000 EAAB 0000 3A30", + "0150 FC1A 010E 050D 0000 AAAB 0000 3B30", + "0150 FA9F 0136 04E2 0000 47D2 0000 3C30", + "0150 FC2A 0136 0475 0000 CAAB 0000 3D30", + "0150 FBA5 0136 0578 0000 8E39 0000 3E30" + ] + }, + { + "File": { + "Name": "Scene 13, Room 19", + "Start": "03275000", + "End": "0327CD40", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0179", + "0072", + "0073", + "00BA", + "00ED", + "00B3", + "0075" + ], + "Actors": [ + "01A7 FA05 00B4 0714 0000 6AAB 0000 0005", + "00C3 FA05 012C 0714 2000 6AAB 0000 0002", + "0008 FA9E 00C1 06F1 0000 0000 0000 03F9", + "0008 F9DA 00C1 067E 0000 0000 0000 03F9", + "0111 FA86 0096 0586 0000 0000 0000 660C", + "0111 FB18 0096 05DC 0000 0000 0000 680F" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 2403, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2404, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2405, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2406, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2407, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2408, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2409, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2410, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2473, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2474, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2475, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2476, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2477, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2478, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2479, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2480, + "Type": 57, + "Flags": 4 + } + ], + "PolyTypes": [], + "Cams": [ + { + "Data": 1572867, + "PositionIndex": 0 + }, + { + "Data": 1572867, + "PositionIndex": 1 + }, + { + "Data": 1572867, + "PositionIndex": 2 + }, + { + "Data": 1572867, + "PositionIndex": 3 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [], + "Minimaps": [] + } +] \ No newline at end of file diff --git a/worlds/oot/data/title.bin b/worlds/oot/data/title.bin new file mode 100644 index 00000000..9c1307a6 Binary files /dev/null and b/worlds/oot/data/title.bin differ diff --git a/worlds/oot/data/triforce.bin b/worlds/oot/data/triforce.bin new file mode 100644 index 00000000..24e8668f Binary files /dev/null and b/worlds/oot/data/triforce.bin differ diff --git a/worlds/oot/ntype.py b/worlds/oot/ntype.py new file mode 100644 index 00000000..dcd40bf1 --- /dev/null +++ b/worlds/oot/ntype.py @@ -0,0 +1,230 @@ +# Written by mzxrules + +import struct + + +class uint16: + _struct = struct.Struct('>H') + def write(buffer, address, value): + struct.pack_into('>H', buffer, address, value) + + def read(buffer, address=0): + return uint16._struct.unpack_from(buffer, address)[0] + + def bytes(value): + value = value & 0xFFFF + return [(value >> 8) & 0xFF, value & 0xFF] + + def value(values): + return (values[0] << 8) | values[1] + + +class uint32: + _struct = struct.Struct('>I') + def write(buffer, address, value): + struct.pack_into('>I', buffer, address, value) + + def read(buffer, address=0): + return uint32._struct.unpack_from(buffer, address)[0] + + def bytes(value): + value = value & 0xFFFFFFFF + return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF] + + def value(values): + return (values[0] << 24) | (values[1] << 16) | (values[2] << 8) | values[3] + + +class int32: + _struct = struct.Struct('>i') + def write(buffer, address, value): + struct.pack_into('>i', buffer, address, value) + + def read(buffer, address=0): + return int32._struct.unpack_from(buffer, address)[0] + + def bytes(value): + value = value & 0xFFFFFFFF + return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF] + + def value(values): + value = (values[0] << 24) | (values[1] << 16) | (values[2] << 8) | values[3] + if value >= 0x80000000: + value ^= 0xFFFFFFFF + value += 1 + return value + + +class uint24: + def write(buffer, address, value): + byte_arr = bytes(value) + buffer[address:address + 3] = byte_arr[0:3] + + def read(buffer, address=0): + return (buffer[address+0] << 16) | (buffer[address+1] << 8) | buffer[address+2] + + def bytes(value): + value = value & 0xFFFFFF + return [(value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF] + + def value(values): + return (values[0] << 16) | (values[1] << 8) | values[2] + + +class BigStream(object): + + def __init__(self, buffer:bytearray): + self.last_address = 0 + self.buffer = buffer + + + def seek_address(self, address=None, delta=None): + if delta is None: + self.last_address = address + else: + self.last_address += delta + + + def eof(self): + return self.last_address >= len(self.buffer) + + + def read_byte(self, address=None): + if address == None: + address = self.last_address + self.last_address = address + 1 + return self.buffer[address] + + + def read_bytes(self, address=None, length=1): + if address == None: + address = self.last_address + self.last_address = address + length + return self.buffer[address : address + length] + + + def read_int16(self, address=None): + if address == None: + address = self.last_address + return uint16.value(self.read_bytes(address, 2)) + + + def read_int24(self, address=None): + if address == None: + address = self.last_address + return uint24.value(self.read_bytes(address, 3)) + + + def read_int32(self, address=None): + if address == None: + address = self.last_address + return uint32.value(self.read_bytes(address, 4)) + + + def write_byte(self, address, value): + if address == None: + address = self.last_address + self.buffer[address] = value + self.last_address = address + 1 + + + def write_sbyte(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, struct.pack('b', value)) + + + def write_int16(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, uint16.bytes(value)) + + + def write_int24(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, uint24.bytes(value)) + + + def write_int32(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, uint32.bytes(value)) + + + def write_f32(self, address, value:float): + if address == None: + address = self.last_address + self.write_bytes(address, struct.pack('>f', value)) + + + def write_bytes(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + self.last_address = startaddress + len(values) + self.buffer[startaddress:startaddress + len(values)] = values + + + def write_int16s(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + for i, value in enumerate(values): + self.write_int16(startaddress + (i * 2), value) + + + def write_int24s(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + for i, value in enumerate(values): + self.write_int24(startaddress + (i * 3), value) + + + def write_int32s(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + for i, value in enumerate(values): + self.write_int32(startaddress + (i * 4), value) + + + def append_byte(self, value): + self.buffer.append(value) + + + def append_sbyte(self, value): + self.append_bytes(struct.pack('b', value)) + + + def append_int16(self, value): + self.append_bytes(uint16.bytes(value)) + + + def append_int24(self, value): + self.append_bytes(uint24.bytes(value)) + + + def append_int32(self, value): + self.append_bytes(uint32.bytes(value)) + + + def append_f32(self, value:float): + self.append_bytes(struct.pack('>f', value)) + + + def append_bytes(self, values): + for value in values: + self.append_byte(value) + + + def append_int16s(self, values): + for value in values: + self.append_int16(value) + + + def append_int24s(self, values): + for value in values: + self.append_int24(value) + + + def append_int32s(self, values): + for value in values: + self.append_int32(value)