diff --git a/README.md b/README.md index 2cc3c18aa09d..6da719751a5d 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ Currently, the following games are supported: * Mega Man 2 * Yacht Dice * Faxanadu +* Super Mario Land 2: 6 Golden Coins For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 64a1362bf380..396a7d61d70c 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -160,6 +160,9 @@ # Super Mario 64 /worlds/sm64ex/ @N00byKing +# Super Mario Land 2: 6 Golden Coins +/worlds/marioland2/ @Alchav + # Super Mario World /worlds/smw/ @PoryGone diff --git a/worlds/marioland2/LICENSE b/worlds/marioland2/LICENSE new file mode 100644 index 000000000000..7ac515f432f1 --- /dev/null +++ b/worlds/marioland2/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2023 Alex "Alchav" Avery + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/worlds/marioland2/__init__.py b/worlds/marioland2/__init__.py new file mode 100644 index 000000000000..6b748e7383c2 --- /dev/null +++ b/worlds/marioland2/__init__.py @@ -0,0 +1,450 @@ +import base64 +import Utils +import settings +from copy import deepcopy + +from worlds.AutoWorld import World, WebWorld +from BaseClasses import Region, Location, Item, ItemClassification, Tutorial + +from . import client +from .rom import generate_output, SuperMarioLand2ProcedurePatch +from .options import SML2Options +from .locations import (locations, location_name_to_id, level_name_to_id, level_id_to_name, START_IDS, coins_coords, + auto_scroll_max) +from .items import items +from .sprites import level_sprites +from .sprite_randomizer import randomize_enemies, randomize_platforms +from .logic import has_pipe_up, has_pipe_down, has_pipe_left, has_pipe_right, has_level_progression, is_auto_scroll +from . import logic + + +class MarioLand2Settings(settings.Group): + class SML2RomFile(settings.UserFilePath): + """File name of the Super Mario Land 2 1.0 ROM""" + description = "Super Mario Land 2 - 6 Golden Coins (USA, Europe) 1.0 ROM File" + copy_to = "Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb" + md5s = [SuperMarioLand2ProcedurePatch.hash] + + rom_file: SML2RomFile = SML2RomFile(SML2RomFile.copy_to) + + +class MarioLand2WebWorld(WebWorld): + setup_en = Tutorial( + "Multiworld Setup Guide", + "A guide to playing Super Mario Land 2 with Archipelago.", + "English", + "setup_en.md", + "setup/en", + ["Alchav"] + ) + + tutorials = [setup_en] + + +class MarioLand2World(World): + """Super Mario Land 2 is a classic platformer that follows Mario on a quest to reclaim his castle from the + villainous Wario. This iconic game features 32 levels, unique power-ups, and introduces Wario as Mario's + arch-rival.""" # -ChatGPT + + game = "Super Mario Land 2" + + settings_key = "sml2_options" + settings: MarioLand2Settings + + location_name_to_id = location_name_to_id + item_name_to_id = {item_name: ID for ID, item_name in enumerate(items, START_IDS)} + + web = MarioLand2WebWorld() + + item_name_groups = { + "Level Progression": { + item_name for item_name in items if item_name.endswith(("Progression", "Secret", "Secret 1", "Secret 2")) + and "Auto Scroll" not in item_name + }, + "Bells": {item_name for item_name in items if "Bell" in item_name}, + "Golden Coins": {"Mario Coin", "Macro Coin", "Space Coin", "Tree Coin", "Turtle Coin", "Pumpkin Coin"}, + "Coins": {"1 Coin", *{f"{i} Coins" for i in range(2, 169)}}, + "Powerups": {"Mushroom", "Fire Flower", "Carrot"}, + "Difficulties": {"Easy Mode", "Normal Mode"}, + "Auto Scroll Traps": {item_name for item_name in items + if "Auto Scroll" in item_name and "Cancel" not in item_name}, + "Cancel Auto Scrolls": {item_name for item_name in items if "Cancel Auto Scroll" in item_name}, + } + + location_name_groups = { + "Bosses": { + "Tree Zone 5 - Boss", "Space Zone 2 - Boss", "Macro Zone 4 - Boss", + "Pumpkin Zone 4 - Boss", "Mario Zone 4 - Boss", "Turtle Zone 3 - Boss" + }, + "Normal Exits": {location for location in locations if locations[location]["type"] == "level"}, + "Secret Exits": {location for location in locations if locations[location]["type"] == "secret"}, + "Bells": {location for location in locations if locations[location]["type"] == "bell"}, + "Coins": {location for location in location_name_to_id if "Coin" in location} + } + + options_dataclass = SML2Options + options: SML2Options + + generate_output = generate_output + + def __init__(self, world, player: int): + super().__init__(world, player) + self.auto_scroll_levels = [] + self.num_coin_locations = [] + self.max_coin_locations = {} + self.sprite_data = {} + self.coin_fragments_required = 0 + + def generate_early(self): + self.sprite_data = deepcopy(level_sprites) + if self.options.randomize_enemies: + randomize_enemies(self.sprite_data, self.random) + if self.options.randomize_platforms: + randomize_platforms(self.sprite_data, self.random) + + if self.options.marios_castle_midway_bell: + self.sprite_data["Mario's Castle"][35]["sprite"] = "Midway Bell" + + if self.options.auto_scroll_chances == "vanilla": + self.auto_scroll_levels = [int(i in [19, 25, 30]) for i in range(32)] + else: + self.auto_scroll_levels = [int(self.random.randint(1, 100) <= self.options.auto_scroll_chances) + for _ in range(32)] + + self.auto_scroll_levels[level_name_to_id["Mario's Castle"]] = 0 + unbeatable_scroll_levels = ["Tree Zone 3", "Macro Zone 2", "Space Zone 1", "Turtle Zone 2", "Pumpkin Zone 2"] + if not self.options.shuffle_midway_bells: + unbeatable_scroll_levels.append("Pumpkin Zone 1") + for level, i in enumerate(self.auto_scroll_levels): + if i == 1: + if self.options.auto_scroll_mode in ("global_cancel_item", "level_cancel_items"): + self.auto_scroll_levels[level] = 2 + elif self.options.auto_scroll_mode == "chaos": + if (self.options.accessibility == "full" + and level_id_to_name[level] in unbeatable_scroll_levels): + self.auto_scroll_levels[level] = 2 + else: + self.auto_scroll_levels[level] = self.random.randint(1, 3) + elif (self.options.accessibility == "full" + and level_id_to_name[level] in unbeatable_scroll_levels): + self.auto_scroll_levels[level] = 0 + if self.auto_scroll_levels[level] == 1 and "trap" in self.options.auto_scroll_mode.current_key: + self.auto_scroll_levels[level] = 3 + + def create_regions(self): + menu_region = Region("Menu", self.player, self.multiworld) + self.multiworld.regions.append(menu_region) + created_regions = [] + for location_name, data in locations.items(): + region_name = location_name.split(" -")[0] + if region_name in created_regions: + region = self.multiworld.get_region(region_name, self.player) + else: + region = Region(region_name, self.player, self.multiworld) + if region_name == "Tree Zone Secret Course": + region_to_connect = self.multiworld.get_region("Tree Zone 2", self.player) + elif region_name == "Space Zone Secret Course": + region_to_connect = self.multiworld.get_region("Space Zone 1", self.player) + elif region_name == "Macro Zone Secret Course": + region_to_connect = self.multiworld.get_region("Macro Zone 1", self.player) + elif region_name == "Pumpkin Zone Secret Course 1": + region_to_connect = self.multiworld.get_region("Pumpkin Zone 2", self.player) + elif region_name == "Pumpkin Zone Secret Course 2": + region_to_connect = self.multiworld.get_region("Pumpkin Zone 3", self.player) + elif region_name == "Turtle Zone Secret Course": + region_to_connect = self.multiworld.get_region("Turtle Zone 2", self.player) + elif region_name.split(" ")[-1].isdigit() and int(region_name.split(" ")[-1]) > 1: + region_to_connect = self.multiworld.get_region(" ".join(region_name.split(" ")[:2]) + + f" {int(region_name.split(' ')[2]) - 1}", + self.player) + else: + region_to_connect = menu_region + region_to_connect.connect(region) + self.multiworld.regions.append(region) + created_regions.append(region_name) + + if "Midway Bell" in location_name and not self.options.shuffle_midway_bells: + continue + if location_name == "Mario's Castle - Midway Bell" and not self.options.marios_castle_midway_bell: + continue + region.locations.append(MarioLand2Location(self.player, location_name, + self.location_name_to_id[location_name], region)) + self.multiworld.get_region("Macro Zone Secret Course", self.player).connect( + self.multiworld.get_region("Macro Zone 4", self.player)) + self.multiworld.get_region("Macro Zone 4", self.player).connect( + self.multiworld.get_region("Macro Zone Secret Course", self.player)) + + castle = self.multiworld.get_region("Mario's Castle", self.player) + wario = MarioLand2Location(self.player, "Mario's Castle - Wario", parent=castle) + castle.locations.append(wario) + wario.place_locked_item(MarioLand2Item("Wario Defeated", ItemClassification.progression, None, self.player)) + + if self.options.coinsanity: + coinsanity_checks = self.options.coinsanity_checks.value + self.num_coin_locations = [[region, 1] for region in created_regions if region != "Mario's Castle"] + self.max_coin_locations = {region: len(coins_coords[region]) for region in created_regions + if region != "Mario's Castle"} + if self.options.accessibility == "full" or self.options.auto_scroll_mode == "always": + for level in self.max_coin_locations: + if level in auto_scroll_max and self.auto_scroll_levels[level_name_to_id[level]] in (1, 3): + if isinstance(auto_scroll_max[level], tuple): + self.max_coin_locations[level] = min( + auto_scroll_max[level][int(self.options.shuffle_midway_bells.value)], + self.max_coin_locations[level]) + else: + self.max_coin_locations[level] = min(auto_scroll_max[level], self.max_coin_locations[level]) + coinsanity_checks = min(sum(self.max_coin_locations.values()), coinsanity_checks) + for i in range(coinsanity_checks - 31): + self.num_coin_locations.sort(key=lambda region: self.max_coin_locations[region[0]] / region[1]) + self.num_coin_locations[-1][1] += 1 + coin_locations = [] + for level, coins in self.num_coin_locations: + coin_thresholds = self.random.sample(range(1, self.max_coin_locations[level] + 1), coins) + coin_locations += [f"{level} - {i} Coin{'s' if i > 1 else ''}" for i in coin_thresholds] + for location_name in coin_locations: + region = self.multiworld.get_region(location_name.split(" -")[0], self.player) + region.locations.append(MarioLand2Location(self.player, location_name, + self.location_name_to_id[location_name], parent=region)) + + def set_rules(self): + entrance_rules = { + "Menu -> Space Zone 1": lambda state: state.has("Hippo Bubble", self.player) + or (state.has("Carrot", self.player) + and not is_auto_scroll(state, self.player, "Hippo Zone")), + "Space Zone 1 -> Space Zone Secret Course": lambda state: state.has("Space Zone Secret", self.player), + "Space Zone 1 -> Space Zone 2": lambda state: has_level_progression(state, "Space Zone Progression", self.player), + "Tree Zone 1 -> Tree Zone 2": lambda state: has_level_progression(state, "Tree Zone Progression", self.player), + "Tree Zone 2 -> Tree Zone Secret Course": lambda state: state.has("Tree Zone Secret", self.player), + "Tree Zone 2 -> Tree Zone 3": lambda state: has_level_progression(state, "Tree Zone Progression", self.player, 2), + "Tree Zone 4 -> Tree Zone 5": lambda state: has_level_progression(state, "Tree Zone Progression", self.player, 3), + "Macro Zone 1 -> Macro Zone Secret Course": lambda state: state.has("Macro Zone Secret 1", self.player), + "Macro Zone Secret Course -> Macro Zone 4": lambda state: state.has("Macro Zone Secret 2", self.player), + "Macro Zone 1 -> Macro Zone 2": lambda state: has_level_progression(state, "Macro Zone Progression", self.player), + "Macro Zone 2 -> Macro Zone 3": lambda state: has_level_progression(state, "Macro Zone Progression", self.player, 2), + "Macro Zone 3 -> Macro Zone 4": lambda state: has_level_progression(state, "Macro Zone Progression", self.player, 3), + "Macro Zone 4 -> Macro Zone Secret Course": lambda state: state.has("Macro Zone Secret 2", self.player), + "Pumpkin Zone 1 -> Pumpkin Zone 2": lambda state: has_level_progression(state, "Pumpkin Zone Progression", self.player), + "Pumpkin Zone 2 -> Pumpkin Zone Secret Course 1": lambda state: state.has("Pumpkin Zone Secret 1", self.player), + "Pumpkin Zone 2 -> Pumpkin Zone 3": lambda state: has_level_progression(state, "Pumpkin Zone Progression", self.player, 2), + "Pumpkin Zone 3 -> Pumpkin Zone Secret Course 2": lambda state: state.has("Pumpkin Zone Secret 2", self.player), + "Pumpkin Zone 3 -> Pumpkin Zone 4": lambda state: has_level_progression(state, "Pumpkin Zone Progression", self.player, 3), + "Mario Zone 1 -> Mario Zone 2": lambda state: has_level_progression(state, "Mario Zone Progression", self.player), + "Mario Zone 2 -> Mario Zone 3": lambda state: has_level_progression(state, "Mario Zone Progression", self.player, 2), + "Mario Zone 3 -> Mario Zone 4": lambda state: has_level_progression(state, "Mario Zone Progression", self.player, 3), + "Turtle Zone 1 -> Turtle Zone 2": lambda state: has_level_progression(state, "Turtle Zone Progression", self.player), + "Turtle Zone 2 -> Turtle Zone Secret Course": lambda state: state.has("Turtle Zone Secret", self.player), + "Turtle Zone 2 -> Turtle Zone 3": lambda state: has_level_progression(state, "Turtle Zone Progression", self.player, 2), + } + + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + # Require the other coins just to ensure they are being added to start inventory properly, + # and so they show up in Playthrough as required + entrance_rules["Menu -> Mario's Castle"] = lambda state: (state.has_all( + ["Tree Coin", "Space Coin", "Macro Coin", "Pumpkin Coin", "Turtle Coin"], self.player) + and state.has("Mario Coin Fragment", self.player, self.coin_fragments_required)) + else: + entrance_rules["Menu -> Mario's Castle"] = lambda state: state.has_from_list_unique([ + "Tree Coin", "Space Coin", "Macro Coin", "Pumpkin Coin", "Mario Coin", "Turtle Coin" + ], self.player, self.options.required_golden_coins) + + + for entrance, rule in entrance_rules.items(): + self.multiworld.get_entrance(entrance, self.player).access_rule = rule + + for location in self.multiworld.get_locations(self.player): + if location.name.endswith(("Coins", "Coin")): + rule = getattr(logic, location.parent_region.name.lower().replace(" ", "_") + "_coins", None) + if rule: + coins = int(location.name.split(" ")[-2]) + location.access_rule = lambda state, coin_rule=rule, num_coins=coins: \ + coin_rule(state, self.player, num_coins) + else: + rule = getattr(logic, location.name.lower().replace( + " - ", "_").replace(" ", "_").replace("'", ""), None) + if rule: + location.access_rule = lambda state, loc_rule=rule: loc_rule(state, self.player) + self.multiworld.completion_condition[self.player] = lambda state: state.has("Wario Defeated", self.player) + + def create_items(self): + item_counts = { + "Space Zone Progression": 1, + "Space Zone Secret": 1, + "Tree Zone Progression": 3, + "Tree Zone Secret": 1, + "Macro Zone Progression": 3, + "Macro Zone Secret 1": 1, + "Macro Zone Secret 2": 1, + "Pumpkin Zone Progression": 3, + "Pumpkin Zone Secret 1": 1, + "Pumpkin Zone Secret 2": 1, + "Mario Zone Progression": 3, + "Turtle Zone Progression": 2, + "Turtle Zone Secret": 1, + "Mushroom": 1, + "Fire Flower": 1, + "Carrot": 1, + "Space Physics": 1, + "Hippo Bubble": 1, + "Water Physics": 1, + "Super Star Duration Increase": 2, + "Mario Coin Fragment": 0, + } + + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + # There are 5 Zone Progression items that can be condensed. + item_counts["Mario Coin Fragment"] = 1 + ((5 * self.options.mario_coin_fragment_percentage) // 100) + + if self.options.coinsanity: + coin_count = sum([level[1] for level in self.num_coin_locations]) + max_coins = sum(self.max_coin_locations.values()) + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + removed_coins = (coin_count * self.options.mario_coin_fragment_percentage) // 100 + coin_count -= removed_coins + item_counts["Mario Coin Fragment"] += removed_coins + # Randomly remove some coin items for variety + coin_count -= (coin_count // self.random.randint(100, max(100, coin_count))) + + if coin_count: + coin_bundle_sizes = [max_coins // coin_count] * coin_count + remainder = max_coins - sum(coin_bundle_sizes) + for i in range(remainder): + coin_bundle_sizes[i] += 1 + for a, b in zip(range(1, len(coin_bundle_sizes), 2), range(2, len(coin_bundle_sizes), 2)): + split = self.random.randint(1, coin_bundle_sizes[a] + coin_bundle_sizes[b] - 1) + coin_bundle_sizes[a], coin_bundle_sizes[b] = split, coin_bundle_sizes[a] + coin_bundle_sizes[b] - split + for coin_bundle_size in coin_bundle_sizes: + item_name = f"{coin_bundle_size} Coin{'s' if coin_bundle_size > 1 else ''}" + if item_name in item_counts: + item_counts[item_name] += 1 + else: + item_counts[item_name] = 1 + + if self.options.shuffle_golden_coins == "shuffle": + for item in self.item_name_groups["Golden Coins"]: + item_counts[item] = 1 + elif self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + for item in ("Tree Coin", "Space Coin", "Macro Coin", "Pumpkin Coin", "Turtle Coin"): + self.multiworld.push_precollected(self.create_item(item)) + else: + for item, location_name in ( + ("Mario Coin", "Mario Zone 4 - Boss"), + ("Tree Coin", "Tree Zone 5 - Boss"), + ("Space Coin", "Space Zone 2 - Boss"), + ("Macro Coin", "Macro Zone 4 - Boss"), + ("Pumpkin Coin", "Pumpkin Zone 4 - Boss"), + ("Turtle Coin", "Turtle Zone 3 - Boss") + ): + location = self.multiworld.get_location(location_name, self.player) + location.place_locked_item(self.create_item(item)) + location.address = None + location.item.code = None + + if self.options.shuffle_midway_bells: + for item in [item for item in items if "Midway Bell" in item]: + if item != "Mario's Castle Midway Bell" or self.options.marios_castle_midway_bell: + item_counts[item] = 1 + + if self.options.difficulty_mode == "easy_to_normal": + item_counts["Normal Mode"] = 1 + elif self.options.difficulty_mode == "normal_to_easy": + item_counts["Easy Mode"] = 1 + + if self.options.shuffle_pipe_traversal == "single": + item_counts["Pipe Traversal"] = 1 + elif self.options.shuffle_pipe_traversal == "split": + item_counts["Pipe Traversal - Right"] = 1 + item_counts["Pipe Traversal - Left"] = 1 + item_counts["Pipe Traversal - Up"] = 1 + item_counts["Pipe Traversal - Down"] = 1 + else: + self.multiworld.push_precollected(self.create_item("Pipe Traversal")) + + if any(self.auto_scroll_levels): + if self.options.auto_scroll_mode == "global_trap_item": + item_counts["Auto Scroll"] = 1 + elif self.options.auto_scroll_mode == "global_cancel_item": + item_counts["Cancel Auto Scroll"] = 1 + else: + for level, i in enumerate(self.auto_scroll_levels): + if i == 3: + item_counts[f"Auto Scroll - {level_id_to_name[level]}"] = 1 + elif i == 2: + item_counts[f"Cancel Auto Scroll - {level_id_to_name[level]}"] = 1 + + for item in self.multiworld.precollected_items[self.player]: + if item.name in item_counts and item_counts[item.name] > 0: + item_counts[item.name] -= 1 + + location_count = len(self.multiworld.get_unfilled_locations(self.player)) + items_to_add = location_count - sum(item_counts.values()) + if items_to_add > 0: + mario_coin_frags = 0 + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + mario_coin_frags = (items_to_add * self.options.mario_coin_fragment_percentage) // 100 + item_counts["Mario Coin Fragment"] += mario_coin_frags + item_counts["Super Star Duration Increase"] += items_to_add - mario_coin_frags + elif items_to_add < 0: + if self.options.coinsanity: + for i in range(1, 168): + coin_name = f"{i} Coin{'s' if i > 1 else ''}" + if coin_name in item_counts: + amount_to_remove = min(-items_to_add, item_counts[coin_name]) + item_counts[coin_name] -= amount_to_remove + items_to_add += amount_to_remove + if items_to_add >= 0: + break + + double_progression_items = ["Tree Zone Progression", "Macro Zone Progression", "Pumpkin Zone Progression", + "Mario Zone Progression", "Turtle Zone Progression"] + self.random.shuffle(double_progression_items) + while sum(item_counts.values()) > location_count: + if double_progression_items: + double_progression_item = double_progression_items.pop() + item_counts[double_progression_item] -= 2 + item_counts[double_progression_item + " x2"] = 1 + continue + if self.options.auto_scroll_mode in ("level_trap_items", "level_cancel_items", + "chaos"): + auto_scroll_item = self.random.choice([item for item in item_counts if "Auto Scroll" in item]) + level = auto_scroll_item.split("- ")[1] + self.auto_scroll_levels[level_name_to_id[level]] = 0 + del item_counts[auto_scroll_item] + continue + raise Exception(f"Too many items in the item pool for Super Mario Land 2 player {self.player_name}") + # item = self.random.choice(list(item_counts)) + # item_counts[item] -= 1 + # if item_counts[item] == 0: + # del item_counts[item] + # self.multiworld.push_precollected(self.create_item(item)) + + self.coin_fragments_required = max((item_counts["Mario Coin Fragment"] + * self.options.mario_coin_fragments_required_percentage) // 100, 1) + + for item_name, count in item_counts.items(): + self.multiworld.itempool += [self.create_item(item_name) for _ in range(count)] + + def fill_slot_data(self): + return { + "energy_link": self.options.energy_link.value + } + + def create_item(self, name: str) -> Item: + return MarioLand2Item(name, items[name], self.item_name_to_id[name], self.player) + + def get_filler_item_name(self): + return "1 Coin" + + def modify_multidata(self, multidata: dict): + rom_name = bytearray(f'AP{Utils.__version__.replace(".", "")[0:3]}_{self.player}_{self.multiworld.seed:11}\0', + 'utf8')[:21] + rom_name.extend([0] * (21 - len(rom_name))) + new_name = base64.b64encode(bytes(rom_name)).decode() + multidata["connect_names"][new_name] = multidata["connect_names"][self.player_name] + + +class MarioLand2Location(Location): + game = "Super Mario Land 2" + + +class MarioLand2Item(Item): + game = "Super Mario Land 2" diff --git a/worlds/marioland2/basepatch.bsdiff4 b/worlds/marioland2/basepatch.bsdiff4 new file mode 100644 index 000000000000..a8818419a6b8 Binary files /dev/null and b/worlds/marioland2/basepatch.bsdiff4 differ diff --git a/worlds/marioland2/client.py b/worlds/marioland2/client.py new file mode 100644 index 000000000000..c63727c3e269 --- /dev/null +++ b/worlds/marioland2/client.py @@ -0,0 +1,249 @@ +import base64 +import logging + +from NetUtils import ClientStatus +from worlds._bizhawk.client import BizHawkClient +from worlds._bizhawk import read, write, guarded_write + +from .rom_addresses import rom_addresses + +logger = logging.getLogger("Client") + +BANK_EXCHANGE_RATE = 20000000000 + + +class MarioLand2Client(BizHawkClient): + system = ("GB", "SGB") + patch_suffix = ".apsml2" + game = "Super Mario Land 2" + + def __init__(self): + super().__init__() + self.locations_array = [] + self.previous_level = None + + async def validate_rom(self, ctx): + game_name = await read(ctx.bizhawk_ctx, [(0x134, 10, "ROM")]) + game_name = game_name[0].decode("ascii") + if game_name == "MARIOLAND2": + ctx.game = self.game + ctx.items_handling = 0b111 + return True + return False + + async def set_auth(self, ctx): + auth_name = await read(ctx.bizhawk_ctx, [(0x77777, 21, "ROM")]) + auth_name = base64.b64encode(auth_name[0]).decode() + ctx.auth = auth_name + + async def game_watcher(self, ctx): + from . import START_IDS + from .items import items + from .locations import locations, level_id_to_name, coins_coords, location_name_to_id + + (game_loaded_check, level_data, music, auto_scroll_levels, current_level, + midway_point, bcd_lives, num_items_received, coins, options) = \ + await read(ctx.bizhawk_ctx, [(0x0046, 10, "CartRAM"), (0x0848, 42, "CartRAM"), (0x0469, 1, "CartRAM"), + (rom_addresses["Auto_Scroll_Levels_B"], 32, "ROM"), + (0x0269, 1, "CartRAM"), (0x02A0, 1, "CartRAM"), (0x022C, 1, "CartRAM"), + (0x00F0, 2, "CartRAM"), (0x0262, 2, "CartRAM"), + (rom_addresses["Coins_Required"], 8, "ROM")]) + + coins_required = int.from_bytes(options[:2], "big") + difficulty_mode = options[2] + star_count = int.from_bytes(options[3:5], "big") + midway_bells = options[5] + energy_link = options[6] + coin_mode = options[7] + + current_level = int.from_bytes(current_level, "big") + auto_scroll_levels = list(auto_scroll_levels) + midway_point = int.from_bytes(midway_point, "big") + music = int.from_bytes(music, "big") + level_data = list(level_data) + lives = bcd_lives.hex() + num_items_received = int.from_bytes(num_items_received, "big") + if num_items_received == 0xFFFF: + num_items_received = 0 + + items_received = [list(items.keys())[item.item - START_IDS] for item in ctx.items_received] + write_num_items_received = len(items_received).to_bytes(2, "big") + + level_progression = { + "Space Zone Progression", + "Tree Zone Progression", + "Macro Zone Progression", + "Pumpkin Zone Progression", + "Mario Zone Progression", + "Turtle Zone Progression", + } + for level_item in level_progression: + for _ in range(items_received.count(level_item + " x2")): + items_received += ([level_item] * 2) + + if "Pipe Traversal" in items_received: + items_received += ["Pipe Traversal - Left", "Pipe Traversal - Right", + "Pipe Traversal - Up", "Pipe Traversal - Down"] + + if coin_mode == 2 and items_received.count("Mario Coin Fragment") >= coins_required: + items_received.append("Mario Coin") + + if current_level == 255 and self.previous_level != 255: + if coin_mode < 2: + logger.info(f"Golden Coins required: {coins_required}") + else: + logger.info(f"Mario Coin Fragments required: {coins_required}. " + f"You have {items_received.count('Mario Coin Fragment')}") + self.previous_level = current_level + + # There is no music in the title screen demos, this is how we guard against anything in the demos registering. + # There is also no music at the door to Mario's Castle, which is why the above is before this check. + if game_loaded_check != b'\x124Vx\xff\xff\xff\xff\xff\xff' or music == 0: + return + + locations_checked = [] + if current_level in level_id_to_name: + level_name = level_id_to_name[current_level] + coin_tile_data = await read(ctx.bizhawk_ctx, [(0xB000 + ((coords[1] * 256) + coords[0]), 1, "System Bus") + for coords in coins_coords[level_name]]) + num_coins = len([tile[0] for tile in coin_tile_data if tile[0] in (0x7f, 0x60, 0x07)]) + locations_checked = [location_name_to_id[f"{level_name} - {i} Coin{'s' if i > 1 else ''}"] + for i in range(1, num_coins + 1)] + + new_lives = int(lives) + energy_link_add = None + if energy_link: + if new_lives == 0: + if (f"EnergyLink{ctx.team}" in ctx.stored_data + and ctx.stored_data[f"EnergyLink{ctx.team}"] + and ctx.stored_data[f"EnergyLink{ctx.team}"] >= BANK_EXCHANGE_RATE): + new_lives = 1 + energy_link_add = -BANK_EXCHANGE_RATE + elif new_lives > 1: + energy_link_add = BANK_EXCHANGE_RATE * (new_lives - 1) + new_lives = 1 + # Convert back to binary-coded-decimal + new_lives = int(str(new_lives), 16) + + new_coins = coins.hex() + new_coins = int(new_coins[2:] + new_coins[:2]) + for item in items_received[num_items_received:]: + if item.endswith("Coins") or item == "1 Coin": + new_coins += int(item.split(" ")[0]) + # Limit to 999 and convert back to binary-coded-decimal + new_coins = int(str(min(new_coins, 999)), 16).to_bytes(2, "little") + + modified_level_data = level_data.copy() + for ID, (location, data) in enumerate(locations.items(), START_IDS): + if "clear_condition" in data: + if items_received.count(data["clear_condition"][0]) >= data["clear_condition"][1]: + modified_level_data[data["ram_index"]] |= (0x08 if data["type"] == "bell" + else 0x01 if data["type"] == "secret" else 0x80) + + if data["type"] == "level" and level_data[data["ram_index"]] & 0x40: + locations_checked.append(ID) + if data["type"] == "secret" and level_data[data["ram_index"]] & 0x02: + locations_checked.append(ID) + elif data["type"] == "bell" and data["id"] == current_level and midway_point == 0xFF: + locations_checked.append(ID) + + invincibility_length = int((832.0 / (star_count + 1)) + * (items_received.count("Super Star Duration Increase") + 1)) + + if "Easy Mode" in items_received: + difficulty_mode = 1 + elif "Normal Mode" in items_received: + difficulty_mode = 0 + + data_writes = [ + (rom_addresses["Space_Physics"], [0x7e] if "Space Physics" in items_received else [0xaf], "ROM"), + (rom_addresses["Get_Hurt_To_Big_Mario"], [1] if "Mushroom" in items_received else [0], "ROM"), + (rom_addresses["Get_Mushroom_A"], [0xea, 0x16, 0xa2] if "Mushroom" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Mushroom_B"], [0xea, 0x16, 0xa2] if "Mushroom" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Mushroom_C"], [00] if "Mushroom" in items_received else [0xd8], "ROM"), + (rom_addresses["Get_Carrot_A"], [0xea, 0x16, 0xa2] if "Carrot" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Carrot_B"], [0xea, 0x16, 0xa2] if "Carrot" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Carrot_C"], [00] if "Carrot" in items_received else [0xc8], "ROM"), + (rom_addresses["Get_Fire_Flower_A"], [0xea, 0x16, 0xa2] if "Fire Flower" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Fire_Flower_B"], [0xea, 0x16, 0xa2] if "Fire Flower" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Fire_Flower_C"], [00] if "Fire Flower" in items_received else [0xc8], "ROM"), + (rom_addresses["Invincibility_Star_A"], [(invincibility_length >> 8) + 1], "ROM"), + (rom_addresses["Invincibility_Star_B"], [invincibility_length & 0xFF], "ROM"), + (rom_addresses["Enable_Bubble"], [0xcb, 0xd7] if "Hippo Bubble" in items_received else [0, 0], "ROM"), + (rom_addresses["Enable_Swim"], [0xcb, 0xcf] if "Water Physics" in items_received else [0, 0], "ROM"), + (rom_addresses["Pipe_Traversal_A"], [16] if "Pipe Traversal - Down" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_B"], [32] if "Pipe Traversal - Up" in items_received else [10], "ROM"), + (rom_addresses["Pipe_Traversal_C"], [48] if "Pipe Traversal - Right" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_D"], [64] if "Pipe Traversal - Left" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_A"], [5] if "Pipe Traversal - Down" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_B"], [5] if "Pipe Traversal - Up" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_C"], [5] if "Pipe Traversal - Right" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_D"], [5] if "Pipe Traversal - Left" in items_received else [0], "ROM"), + (0x022c, [new_lives], "CartRAM"), + (0x02E4, [difficulty_mode], "CartRAM"), + (0x0848, modified_level_data, "CartRAM"), + (0x0262, new_coins, "CartRAM"), + ] + + if items_received: + data_writes.append((0x00F0, write_num_items_received, "CartRAM")) + + if midway_point == 0xFF and midway_bells: + # after registering the check for the midway bell, clear the value just for safety. + data_writes.append((0x02A0, [0], "CartRAM")) + + for i in range(32): + if auto_scroll_levels[i] == 3: + if "Auto Scroll" in items_received or f"Auto Scroll - {level_id_to_name[i]}" in items_received: + auto_scroll_levels[i] = 1 + if i == current_level: + data_writes.append((0x02C8, [0x01], "CartRAM")) + else: + auto_scroll_levels[i] = 0 + elif auto_scroll_levels[i] == 2: + if ("Cancel Auto Scroll" in items_received + or f"Cancel Auto Scroll - {level_id_to_name[i]}" in items_received): + auto_scroll_levels[i] = 0 + if i == current_level: + data_writes.append((0x02C8, [0x00], "CartRAM")) + else: + auto_scroll_levels[i] = 1 + data_writes.append((rom_addresses["Auto_Scroll_Levels"], auto_scroll_levels, "ROM")) + + success = await guarded_write(ctx.bizhawk_ctx, data_writes, [(0x0848, level_data, "CartRAM"), + (0x022C, [int.from_bytes(bcd_lives, "big")], + "CartRAM"), + [0x0262, coins, "CartRAM"]]) + + if success and energy_link_add is not None: + await ctx.send_msgs([{ + "cmd": "Set", "key": f"EnergyLink{ctx.team}", "operations": + [{"operation": "add", "value": energy_link_add}, + {"operation": "max", "value": 0}], + }]) + + if not ctx.server or not ctx.server.socket.open or ctx.server.socket.closed: + return + + if locations_checked and locations_checked != self.locations_array: + self.locations_array = locations_checked + await ctx.send_msgs([{"cmd": "LocationChecks", "locations": locations_checked}]) + + if music == 0x18: + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True + + def on_package(self, ctx, cmd: str, args: dict): + super().on_package(ctx, cmd, args) + if cmd == 'Connected': + if ctx.slot_data["energy_link"]: + ctx.set_notify(f"EnergyLink{ctx.team}") + if ctx.ui: + ctx.ui.enable_energy_link() + ctx.ui.energy_link_label.text = "Lives: Standby" + elif cmd == "SetReply" and args["key"].startswith("EnergyLink"): + if ctx.ui: + ctx.ui.energy_link_label.text = f"Lives: {int(args['value'] / BANK_EXCHANGE_RATE)}" + elif cmd == "Retrieved": + if f"EnergyLink{ctx.team}" in args["keys"] and args['keys'][f'EnergyLink{ctx.team}'] and ctx.ui: + ctx.ui.energy_link_label.text = f"Lives: {int(args['keys'][f'EnergyLink{ctx.team}'] / BANK_EXCHANGE_RATE)}" diff --git a/worlds/marioland2/docs/en_Super Mario Land 2.md b/worlds/marioland2/docs/en_Super Mario Land 2.md new file mode 100644 index 000000000000..59aa073c6d9e --- /dev/null +++ b/worlds/marioland2/docs/en_Super Mario Land 2.md @@ -0,0 +1,61 @@ +# Super Mario Land 2: 6 Golden Coins + +## Where is the options page? + +The [player options page for this game](../player-options) contains all the options you need to configure and export a +config file. + +## What items and locations get shuffled? + +Completing a level's exits results in a location check instead of automatically bringing you to the next level. +Where there are secret exits, the secret exit will be a separate location check. There is one exception, Hippo Zone, +that does not have a separate check for its secret exit. The Hippo Zone secret exit will still bring you to the Space +Zone. + +Unlocking paths to new levels requires finding or receiving Zone Progression items. For example, receiving the first +"Turtle Zone Progression" will unlock the path from Turtle Zone 1 to Turtle Zone 2. Paths to secret levels are separate +items, so Turtle Zone Secret will open the path from Turtle Zone 2 to the Turtle Zone Secret Course. + +Depending on settings, there may be some "Zone Progression x2" items that open two paths at once. + +The path from Tree Zone 2 to the branch to Tree Zone 3 and 4 is one unlock, so both levels will open at this point. + +Besides the zone progression unlocks, the following items are always shuffled: +- Mushroom: required to become Big Mario. If you are Fire or Bunny Mario and take damage, and have not obtained the +Mushroom, you will drop straight down to Small Mario. +- Fire Flower: required to become Fire Mario. +- Carrot: required to become Bunny Mario. +- Hippo Bubble: required to use the bubbles in Hippo Zone to fly. +- Water Physics: Mario will fall through water as though it is air until this is obtained. +- Space Physics: the Space Zone levels will have normal gravity until this is obtained. +- Super Star Duration Increase: you begin with a drastically lowered invincibility star duration, and these items will +increase it. + +Additionally, the following items can be shuffled depending on your YAML options: +- The 6 Golden Coins: note that the game will still show you the coin being sent to the castle when defeating a boss +regardless of whether the coin is actually obtained in that location. +- Mario Coin Fragments: As an alternative to shuffling the 6 Golden Coins, you can shuffle Mario Coin Fragments, +a chosen percentage of which are needed to assemble the Mario Coin. You will start with the other 5 coins. +- Midway Bells: ringing bells results in a location check, and the midway check points are shuffled as items. +Note that you may have to backtrack from the midway point to reach some secret exits! +- Normal Mode/Easy Mode: you can start the game in Normal Mode with an Easy Mode "upgrade" in the item pool, or start in +Easy Mode with a Normal Mode "trap" item, swapping the difficulty. +- Auto Scroll: auto-scrolling levels can be set to not auto scroll until this trap item is received. +- Pipe Traversal: required to enter pipes. Can also be split into 4 items, each enabling pipe entry from a different +direction. +- Coins: if Coinsanity is enabled, coins will be shuffled into the item pool. A number of checks will be added to each +level for obtaining a specific number of coins within a single playthrough of the level. + + +## When the player receives an item, what happens? + +There is no in-game indication that an item has been received. You will need to watch the client or web tracker to be +sure you're aware of the items you've received. + +## Special Thanks to: + +- [froggestspirit](https://github.com/froggestspirit) for his Super Mario Land 2 disassembly. While very incomplete, it +had enough memory values mapped out to make my work significantly easier. +- [slashinfty](https://github.com/slashinfty), the author of the +[Super Mario Land 2 Randomizer](https://sml2r.download/) for permitting me to port features such as Randomize Enemies +and Randomize Platforms directly from it. \ No newline at end of file diff --git a/worlds/marioland2/docs/setup_en.md b/worlds/marioland2/docs/setup_en.md new file mode 100644 index 000000000000..581d36e7864f --- /dev/null +++ b/worlds/marioland2/docs/setup_en.md @@ -0,0 +1,75 @@ +# Setup Guide for Super Mario Land 2: 6 Golden Coins + +## Important + +As we are using BizHawk, this guide is only applicable to Windows and Linux systems. + +## Required Software + +- BizHawk: [BizHawk Releases from TASVideos](https://tasvideos.org/BizHawk/ReleaseHistory) + - Version 2.9.1 is recommended. + - Detailed installation instructions for BizHawk can be found at the above link. + - Windows users must run the prereq installer first, which can also be found at the above link. +- The built-in Archipelago client, which can be installed [here](https://github.com/ArchipelagoMW/Archipelago/releases) +- A Super Mario Land 2: 6 Golden Coins version 1.0 ROM file. The Archipelago community cannot provide this. + +## Configuring BizHawk + +Once BizHawk has been installed, open EmuHawk and change the following settings: + +- Under Config > Customize > Advanced, make sure the box for AutoSaveRAM is checked, and click the 5s button. + This reduces the possibility of losing save data in emulator crashes. +- Under Config > Customize, check the "Run in background" box. This will prevent disconnecting from the client while +EmuHawk is running in the background. + +It is strongly recommended to associate Game Boy ROM extensions (\*.gb) to the EmuHawk we've just installed. +To do so, we simply have to search any Game Boy ROM we happened to own, right click and select "Open with...", unfold +the list that appears and select the bottom option "Look for another application", then browse to the BizHawk folder +and select EmuHawk.exe. + +## Configuring your YAML file + +### What is a YAML file and why do I need one? + +Your YAML file contains a set of configuration options which provide the generator with information about how it should +generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy +an experience customized for their taste, and different players in the same multiworld can all have different options. + +### Where do I get a YAML file? + +You can generate a yaml or download a template by visiting the [Super Mario Land 2 Player Options Page](/games/Super%20Mario%20Land%202/player-options) + +## Joining a MultiWorld Game + +### Generating and Patching a Game + +1. Create your options file (YAML). +2. Follow the general Archipelago instructions for [generating a game](../../Archipelago/setup/en#generating-a-game). +This will generate an output file for you. Your patch file will have a `.apsml2` file extension. +3. Open `ArchipelagoLauncher.exe` +4. Select "Open Patch" on the left side and select your patch file. +5. If this is your first time patching, you will be prompted to locate your vanilla ROM. +6. A patched `.gb` file will be created in the same place as the patch file. +7. On your first time opening a patch with BizHawk Client, you will also be asked to locate `EmuHawk.exe` in your +BizHawk install. + +You must connect Super Mario Land 2 to a server, even for a single player game, or progress cannot be made. + +### Connect to the Multiserver + +By default, opening a patch file will do steps 1-5 below for you automatically. Even so, keep them in your memory just +in case you have to close and reopen a window mid-game for some reason. + +1. Super Mario Land 2 uses Archipelago's BizHawk Client. If the client isn't still open from when you patched your +game, you can re-open it from the launcher. +2. Ensure EmuHawk is running the patched ROM. +3. In EmuHawk, go to `Tools > Lua Console`. This window must stay open while playing. +4. In the Lua Console window, go to `Script > Open Script…`. +5. Navigate to your Archipelago install folder and open `data/lua/connector_bizhawk_generic.lua`. +6. The emulator may freeze every few seconds until it manages to connect to the client. This is expected. The BizHawk +Client window should indicate that it connected and recognized Super Mario Land 2. +7. To connect the client to the server, enter your room's address and port (e.g. `archipelago.gg:38281`) into the +top text field of the client and click Connect. + +To connect the client to the multiserver simply put `
:` on the textfield on top and press enter (if the +server uses password, type in the bottom textfield `/connect
: [password]`) \ No newline at end of file diff --git a/worlds/marioland2/items.py b/worlds/marioland2/items.py new file mode 100644 index 000000000000..a50a20b7ca86 --- /dev/null +++ b/worlds/marioland2/items.py @@ -0,0 +1,79 @@ +from BaseClasses import ItemClassification +from .locations import level_name_to_id +from .options import CoinsanityChecks + +items = { + "Space Zone Progression": ItemClassification.progression, + "Space Zone Secret": ItemClassification.progression, + "Tree Zone Progression": ItemClassification.progression, + "Tree Zone Progression x2": ItemClassification.progression, + "Tree Zone Secret": ItemClassification.progression, + "Macro Zone Progression": ItemClassification.progression, + "Macro Zone Progression x2": ItemClassification.progression, + "Macro Zone Secret 1": ItemClassification.progression, + "Macro Zone Secret 2": ItemClassification.progression_skip_balancing, + "Pumpkin Zone Progression": ItemClassification.progression, + "Pumpkin Zone Progression x2": ItemClassification.progression, + "Pumpkin Zone Secret 1": ItemClassification.progression, + "Pumpkin Zone Secret 2": ItemClassification.progression, + "Mario Zone Progression": ItemClassification.progression, + "Mario Zone Progression x2": ItemClassification.progression, + "Turtle Zone Progression": ItemClassification.progression, + "Turtle Zone Progression x2": ItemClassification.progression, + "Turtle Zone Secret": ItemClassification.progression, + "Tree Coin": ItemClassification.progression_skip_balancing, + "Space Coin": ItemClassification.progression_skip_balancing, + "Macro Coin": ItemClassification.progression_skip_balancing, + "Pumpkin Coin": ItemClassification.progression_skip_balancing, + "Mario Coin": ItemClassification.progression_skip_balancing, + "Turtle Coin": ItemClassification.progression_skip_balancing, + "Mario Coin Fragment": ItemClassification.progression_skip_balancing, + "Mushroom": ItemClassification.progression, + "Fire Flower": ItemClassification.progression, + "Carrot": ItemClassification.progression, + "Space Physics": ItemClassification.progression_skip_balancing, + "Hippo Bubble": ItemClassification.progression_skip_balancing, + "Water Physics": ItemClassification.progression, + "Pipe Traversal": ItemClassification.progression, + "Pipe Traversal - Down": ItemClassification.progression, + "Pipe Traversal - Up": ItemClassification.progression, + "Pipe Traversal - Right": ItemClassification.progression, + "Pipe Traversal - Left": ItemClassification.progression_skip_balancing, + "Super Star Duration Increase": ItemClassification.filler, + "Easy Mode": ItemClassification.useful, + "Normal Mode": ItemClassification.trap, + "Auto Scroll": ItemClassification.trap, + **{f"Auto Scroll - {level}": ItemClassification.trap for level in level_name_to_id if level != "Wario's Castle"}, + "Cancel Auto Scroll": ItemClassification.progression, + **{f"Cancel Auto Scroll - {level}": ItemClassification.progression for level in level_name_to_id + if level != "Wario's Castle"}, + "Mushroom Zone Midway Bell": ItemClassification.filler, + "Tree Zone 1 Midway Bell": ItemClassification.filler, + "Tree Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Tree Zone 4 Midway Bell": ItemClassification.progression_skip_balancing, + "Tree Zone 5 Midway Bell": ItemClassification.filler, + "Space Zone 1 Midway Bell": ItemClassification.filler, + "Space Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 1 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 3 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 4 Midway Bell": ItemClassification.filler, + "Pumpkin Zone 1 Midway Bell": ItemClassification.progression_skip_balancing, + "Pumpkin Zone 2 Midway Bell": ItemClassification.filler, + "Pumpkin Zone 3 Midway Bell": ItemClassification.filler, + "Pumpkin Zone 4 Midway Bell": ItemClassification.filler, + "Mario Zone 1 Midway Bell": ItemClassification.progression_skip_balancing, + "Mario Zone 2 Midway Bell": ItemClassification.filler, + "Mario Zone 3 Midway Bell": ItemClassification.filler, + "Mario Zone 4 Midway Bell": ItemClassification.filler, + "Turtle Zone 1 Midway Bell": ItemClassification.filler, + "Turtle Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Turtle Zone 3 Midway Bell": ItemClassification.filler, + "Mario's Castle Midway Bell": ItemClassification.progression_skip_balancing, + "1 Coin": ItemClassification.filler, + **{f"{i} Coins": ItemClassification.filler for i in range(2, CoinsanityChecks.range_end)} +} + +for level in {"Turtle Zone Secret Course", "Macro Zone Secret Course", "Turtle Zone 3", "Scenic Course", + "Mario Zone 2"}: + items[f"Cancel Auto Scroll - {level}"] = ItemClassification.useful diff --git a/worlds/marioland2/locations.py b/worlds/marioland2/locations.py new file mode 100644 index 000000000000..02ae1cca9dc5 --- /dev/null +++ b/worlds/marioland2/locations.py @@ -0,0 +1,498 @@ +START_IDS = 1 + +locations = { + "Mushroom Zone - Normal Exit": {"id": 0x00, "ram_index": 0, "type": "level"}, + "Mushroom Zone - Midway Bell": {"id": 0x00, "ram_index": 0, "clear_condition": ("Mushroom Zone Midway Bell", 1), "type": "bell"}, + "Scenic Course - Normal Exit": {"id": 0x19, "ram_index": 40, "type": "level"}, + "Tree Zone 1 - Normal Exit": {"id": 0x01, "ram_index": 1, "clear_condition": ("Tree Zone Progression", 1), "type": "level"}, + "Tree Zone 1 - Midway Bell": {"id": 0x01, "ram_index": 1, "clear_condition": ("Tree Zone 1 Midway Bell", 1), "type": "bell"}, + "Tree Zone 2 - Normal Exit": {"id": 0x02, "ram_index": 2, "clear_condition": ("Tree Zone Progression", 2), "type": "level"}, + "Tree Zone 2 - Secret Exit": {"id": 0x02, "ram_index": 2, "clear_condition": ("Tree Zone Secret", 1), "type": "secret"}, + "Tree Zone 2 - Midway Bell": {"id": 0x02, "ram_index": 2, "clear_condition": ("Tree Zone 2 Midway Bell", 1), "type": "bell"}, + "Tree Zone 3 - Normal Exit": {"id": 0x04, "ram_index": 4, "clear_condition": ("Tree Zone Progression", 3), "type": "level"}, + "Tree Zone 4 - Normal Exit": {"id": 0x03, "ram_index": 3, "clear_condition": ("Tree Zone Progression", 3), "type": "level"}, + "Tree Zone 4 - Midway Bell": {"id": 0x03, "ram_index": 3, "clear_condition": ("Tree Zone 4 Midway Bell", 1), "type": "bell"}, + "Tree Zone 5 - Boss": {"id": 0x05, "ram_index": 5, "clear_condition": ("Tree Coin", 1), "type": "level"}, + "Tree Zone 5 - Midway Bell": {"id": 0x05, "ram_index": 5, "clear_condition": ("Tree Zone 5 Midway Bell", 1), "type": "bell"}, + "Tree Zone Secret Course - Normal Exit": {"id": 0x1D, "ram_index": 36, "type": "level"}, + "Hippo Zone - Normal or Secret Exit": {"id": 0x11, "ram_index": 31, "type": "level"}, + "Space Zone 1 - Normal Exit": {"id": 0x12, "ram_index": 16, "clear_condition": ("Space Zone Progression", 1), "type": "level"}, + "Space Zone 1 - Secret Exit": {"id": 0x12, "ram_index": 16, "clear_condition": ("Space Zone Secret", 1), "type": "secret"}, + "Space Zone 1 - Midway Bell": {"id": 0x12, "ram_index": 16, "clear_condition": ("Space Zone 1 Midway Bell", 1), "type": "bell"}, + "Space Zone Secret Course - Normal Exit": {"id": 0x1C, "ram_index": 41, "type": "level"}, + "Space Zone 2 - Boss": {"id": 0x13, "ram_index": 17, "clear_condition": ("Space Coin", 1), "type": "level"}, + "Space Zone 2 - Midway Bell": {"id": 0x13, "ram_index": 17, "clear_condition": ("Space Zone 2 Midway Bell", 1), "type": "bell"}, + "Macro Zone 1 - Normal Exit": {"id": 0x14, "ram_index": 11, "clear_condition": ("Macro Zone Progression", 1), "type": "level"}, + "Macro Zone 1 - Secret Exit": {"id": 0x14, "ram_index": 11, "clear_condition": ("Macro Zone Secret 1", 1), "type": "secret"}, + "Macro Zone 1 - Midway Bell": {"id": 0x14, "ram_index": 11, "clear_condition": ("Macro Zone 1 Midway Bell", 1), "type": "bell"}, + "Macro Zone 2 - Normal Exit": {"id": 0x15, "ram_index": 12, "clear_condition": ("Macro Zone Progression", 2), "type": "level"}, + "Macro Zone 2 - Midway Bell": {"id": 0x15, "ram_index": 12, "clear_condition": ("Macro Zone 2 Midway Bell", 1), "type": "bell"}, + "Macro Zone 3 - Normal Exit": {"id": 0x16, "ram_index": 13, "clear_condition": ("Macro Zone Progression", 3), "type": "level"}, + "Macro Zone 3 - Midway Bell": {"id": 0x16, "ram_index": 13, "clear_condition": ("Macro Zone 3 Midway Bell", 1), "type": "bell"}, + "Macro Zone 4 - Boss": {"id": 0x17, "ram_index": 14, "clear_condition": ("Macro Coin", 1), "type": "level"}, + "Macro Zone 4 - Midway Bell": {"id": 0x17, "ram_index": 14, "clear_condition": ("Macro Zone 4 Midway Bell", 1), "type": "bell"}, + "Macro Zone Secret Course - Normal Exit": {"id": 0x1E, "ram_index": 35, "clear_condition": ("Macro Zone Secret 2", 1), "type": "level"}, + "Pumpkin Zone 1 - Normal Exit": {"id": 0x06, "ram_index": 6, "clear_condition": ("Pumpkin Zone Progression", 1), "type": "level"}, + "Pumpkin Zone 1 - Midway Bell": {"id": 0x06, "ram_index": 6, "clear_condition": ("Pumpkin Zone 1 Midway Bell", 1), "type": "bell"}, + "Pumpkin Zone 2 - Normal Exit": {"id": 0x07, "ram_index": 7, "clear_condition": ("Pumpkin Zone Progression", 2), "type": "level"}, + "Pumpkin Zone 2 - Secret Exit": {"id": 0x07, "ram_index": 7, "clear_condition": ("Pumpkin Zone Secret 1", 1), "type": "secret"}, + "Pumpkin Zone 2 - Midway Bell": {"id": 0x07, "ram_index": 7, "clear_condition": ("Pumpkin Zone 2 Midway Bell", 2), "type": "bell"}, + "Pumpkin Zone 3 - Normal Exit": {"id": 0x08, "ram_index": 8, "clear_condition": ("Pumpkin Zone Progression", 3), "type": "level"}, + "Pumpkin Zone 3 - Secret Exit": {"id": 0x08, "ram_index": 8, "clear_condition": ("Pumpkin Zone Secret 2", 1), "type": "secret"}, + "Pumpkin Zone 3 - Midway Bell": {"id": 0x08, "ram_index": 8, "clear_condition": ("Pumpkin Zone 3 Midway Bell", 3), "type": "bell"}, + "Pumpkin Zone 4 - Boss": {"id": 0x09, "ram_index": 9, "clear_condition": ("Pumpkin Coin", 1), "type": "level"}, + "Pumpkin Zone 4 - Midway Bell": {"id": 0x09, "ram_index": 9, "clear_condition": ("Pumpkin Zone 4 Midway Bell", 1), "type": "bell"}, + "Pumpkin Zone Secret Course 1 - Normal Exit": {"id": 0x1B, "ram_index": 38, "type": "level"}, + "Pumpkin Zone Secret Course 2 - Normal Exit": {"id": 0x1F, "ram_index": 39, "type": "level"}, + "Mario Zone 1 - Normal Exit": {"id": 0x0A, "ram_index": 26, "clear_condition": ("Mario Zone Progression", 1), "type": "level"}, + "Mario Zone 1 - Midway Bell": {"id": 0x0A, "ram_index": 26, "clear_condition": ("Mario Zone 1 Midway Bell", 1), "type": "bell"}, + "Mario Zone 2 - Normal Exit": {"id": 0x0B, "ram_index": 27, "clear_condition": ("Mario Zone Progression", 2), "type": "level"}, + "Mario Zone 2 - Midway Bell": {"id": 0x0B, "ram_index": 27, "clear_condition": ("Mario Zone 2 Midway Bell", 1), "type": "bell"}, + "Mario Zone 3 - Normal Exit": {"id": 0x0C, "ram_index": 28, "clear_condition": ("Mario Zone Progression", 3), "type": "level"}, + "Mario Zone 3 - Midway Bell": {"id": 0x0C, "ram_index": 28, "clear_condition": ("Mario Zone 3 Midway Bell", 1), "type": "bell"}, + "Mario Zone 4 - Boss": {"id": 0x0D, "ram_index": 29, "clear_condition": ("Mario Coin", 1), "type": "level"}, + "Mario Zone 4 - Midway Bell": {"id": 0x0D, "ram_index": 29, "clear_condition": ("Mario Zone 4 Midway Bell", 1), "type": "bell"}, + "Turtle Zone 1 - Normal Exit": {"id": 0x0E, "ram_index": 21, "clear_condition": ("Turtle Zone Progression", 1), "type": "level"}, + "Turtle Zone 1 - Midway Bell": {"id": 0x0E, "ram_index": 21, "clear_condition": ("Turtle Zone 1 Midway Bell", 1), "type": "bell"}, + "Turtle Zone 2 - Normal Exit": {"id": 0x0F, "ram_index": 22, "clear_condition": ("Turtle Zone Progression", 2), "type": "level"}, + "Turtle Zone 2 - Secret Exit": {"id": 0x0F, "ram_index": 22, "clear_condition": ("Turtle Zone Secret", 1), "type": "secret"}, + "Turtle Zone 2 - Midway Bell": {"id": 0x0F, "ram_index": 22, "clear_condition": ("Turtle Zone 2 Midway Bell", 1), "type": "bell"}, + "Turtle Zone 3 - Boss": {"id": 0x10, "ram_index": 23, "clear_condition": ("Turtle Coin", 1), "type": "level"}, + "Turtle Zone 3 - Midway Bell": {"id": 0x10, "ram_index": 23, "clear_condition": ("Turtle Zone 3 Midway Bell", 1), "type": "bell"}, + "Turtle Zone Secret Course - Normal Exit": {"id": 0x1A, "ram_index": 37, "type": "level"}, + "Mario's Castle - Midway Bell": {"id": 24, "ram_index": 24, "clear_condition": ("Mario's Castle Midway Bell", 1), "type": "bell"}, +} + + +coins_coords = { + "Mushroom Zone": + [(22, 28), (24, 28), (42, 28), (43, 28), (74, 36), (74, 37), (74, 38), (76, 36), (76, 37), + (76, 38), (78, 36), (78, 37), (78, 38), (80, 36), (80, 37), (80, 38), (82, 36), (82, 37), + (82, 38), (83, 25), (84, 25), (84, 36), (84, 37), (84, 38), (85, 25), (86, 25), (86, 36), + (86, 37), (86, 38), (87, 25), (88, 36), (88, 37), (88, 38), (116, 24), (117, 24), (118, 24), + (151, 28), (152, 28), (180, 28), (181, 24), (181, 28), (182, 24), (182, 28), (183, 24), (183, 28), + (184, 24), (184, 28), (185, 24), (185, 28), (186, 24), (186, 28), (187, 24), (187, 28), (188, 24), + (188, 28), (189, 28), (211, 25), (212, 25), (212, 36), (212, 37), (212, 38), (212, 39), (213, 25), + (213, 36), (213, 37), (213, 38), (213, 39), (214, 25), (214, 36), (214, 37), (214, 38), (214, 39), + (215, 25), (216, 25), (217, 25), (217, 36), (217, 37), (217, 38), (217, 39), (218, 25), (218, 36), + (218, 37), (218, 38), (218, 39), (219, 25), (219, 36), (219, 37), (219, 38), (219, 39), (220, 25), + (231, 24), (232, 24)], + "Tree Zone 1": + [(27, 30), (28, 30), (29, 30), (33, 27), (34, 27), (35, 27), (40, 30), (41, 30), (42, 30), (47, 27), + (48, 27), (49, 27), (56, 30), (57, 30), (58, 30), (64, 30), (65, 30), (66, 30), (88, 30), (89, 30), + (90, 30), (94, 30), (95, 30), (96, 30), (100, 30), (101, 30), (102, 30), (106, 27), (107, 27), + (108, 27), (112, 30), (113, 30), (114, 30), (119, 28), (138, 30), (139, 30), (140, 30), (150, 28), + (151, 20), (151, 28), (152, 20), (152, 26), (152, 28), (153, 26), (153, 28), (154, 26), (154, 28), + (155, 26), (155, 28), (156, 26), (156, 28), (157, 20), (157, 26), (157, 28), (158, 20), (158, 26), + (158, 28), (159, 26), (159, 28), (160, 28), (161, 28), (176, 13), (177, 13), (177, 29), (178, 13), + (178, 29), (179, 13), (179, 29), (180, 13), (181, 13), (182, 13), (183, 13), (184, 13), (185, 13), + (186, 13), (187, 13), (187, 29), (188, 13), (188, 29), (189, 13), (189, 29), (190, 13), (191, 13), + (192, 13), (193, 13), (194, 13), (195, 13), (196, 13), (197, 13), (197, 29), (198, 13), (198, 29), + (199, 13), (199, 29), (200, 13), (201, 13), (202, 13), (203, 13), (204, 13), (205, 13), (206, 13), + (207, 27), (208, 13), (208, 27), (209, 14), (209, 27), (210, 10), (210, 11), (210, 12), (210, 13), + (210, 14), (210, 15), (211, 14), (212, 13), (219, 30), (220, 30), (221, 30), (229, 27), (230, 27), + (231, 27)], + "Tree Zone 2": + [(27, 11), (28, 11), (42, 10), (43, 10), (44, 10), (51, 28), (61, 9), (65, 26), (66, 26), (67, 26), + (70, 24), (71, 24), (72, 10), (72, 24), (73, 10), (73, 24), (75, 10), (76, 10), (76, 26), (77, 26), + (78, 10), (78, 26), (79, 10), (80, 24), (81, 10), (81, 24), (82, 10), (82, 24), (83, 24), (127, 7), + (128, 7), (129, 7), (130, 7), (136, 43), (138, 9), (138, 10), (138, 11), (139, 41), (140, 41), + (141, 41), (142, 9), (142, 10), (142, 11), (144, 41), (145, 41), (146, 9), (146, 10), (146, 11), + (146, 41), (149, 41), (150, 41), (151, 41), (154, 41), (155, 41), (156, 41), (159, 41), (160, 41), + (161, 41), (164, 41), (165, 41), (166, 41), (169, 41), (170, 41), (171, 41), (174, 41), (175, 41), + (176, 41), (182, 3), (188, 42), (188, 43), (188, 44), (189, 42), (189, 43), (189, 44), (190, 42), + (190, 43), (190, 44), (191, 42), (191, 43), (191, 44), (192, 42), (192, 43), (192, 44), (193, 42), + (193, 43), (193, 44), (213, 8), (213, 9), (213, 10), (213, 11), (213, 12), (213, 13), (213, 14), + (213, 15), (213, 16), (213, 17), (213, 18), (213, 19), (213, 20), (213, 21), (213, 22), (213, 23), + (213, 24), (213, 25)], + "Tree Zone Secret Course": + [(10, 24), (11, 24), (12, 24), (17, 23), (39, 24), (40, 24), (41, 24), (42, 24), (45, 24), + (46, 24), (47, 24), (48, 24), (51, 25), (52, 25), (53, 25), (54, 25), (58, 26), (59, 26), + (60, 26), (61, 24), (61, 25), (62, 24), (62, 25), (63, 24), (63, 25), (64, 24), (64, 25), + (67, 25), (68, 26), (69, 27), (70, 27), (73, 26), (74, 27), (75, 27), (76, 27), (80, 23), + (80, 24), (81, 23), (81, 24), (82, 23), (82, 24), (83, 23), (83, 24), (87, 25), (88, 24), + (89, 24), (90, 25), (91, 26), (100, 23), (114, 27), (114, 28), (115, 27), (115, 28), (116, 27), + (116, 28), (117, 27), (117, 28), (118, 27), (118, 28), (119, 27), (119, 28), (120, 27), + (120, 28), (121, 27), (121, 28), (128, 27), (128, 28), (131, 27), (131, 28), (134, 27), + (134, 28), (137, 27), (137, 28), (138, 27), (138, 28), (143, 27), (143, 28), (159, 23)], + "Tree Zone 4": + [(22, 10), (24, 12), (26, 10), (28, 27), (29, 11), (30, 11), (31, 11), (32, 11), (33, 11), (34, 11), + (35, 11), (37, 10), (38, 12), (41, 11), (43, 12), (61, 11), (70, 11), (79, 11), (89, 11), (103, 22), + (103, 25), (103, 28), (105, 22), (105, 25), (105, 28), (107, 22), (107, 25), (107, 28), (109, 22), + (109, 25), (109, 28), (111, 22), (111, 25), (111, 28), (113, 22), (113, 25), (113, 28), (115, 22), + (115, 25), (115, 28), (117, 22), (117, 25), (117, 28), (122, 22), (122, 25), (122, 28), (124, 22), + (124, 25), (124, 28), (126, 22), (126, 25), (126, 28), (128, 22), (128, 25), (128, 28), (130, 22), + (130, 25), (130, 28), (132, 22), (132, 25), (132, 28), (134, 22), (134, 25), (134, 28), (136, 22), + (136, 25), (136, 28), (171, 10), (196, 26), (196, 29), (197, 26), (197, 29), (198, 26), (198, 29), + (199, 26), (199, 29), (200, 26), (200, 29)], + "Tree Zone 3": + [(18, 11), (18, 12), (19, 11), (19, 12), (20, 11), (20, 12), (21, 11), (21, 12), (22, 11), (22, 12), + (26, 40), (27, 11), (27, 12), (28, 11), (28, 12), (29, 11), (29, 12), (30, 11), (30, 12), (31, 11), + (31, 12), (48, 41), (49, 41), (50, 41), (51, 41), (61, 25), (77, 24)], + "Tree Zone 5": + [(23, 41), (84, 39), (85, 39), (116, 42), (123, 39), (132, 39), (134, 36), (134, 39), (134, 43), + (134, 44), (135, 43), (135, 44), (136, 36), (136, 39), (136, 43), (136, 44), (137, 43), (137, 44), + (138, 36), (138, 39), (138, 43), (138, 44), (139, 43), (139, 44), (140, 36), (140, 39), (140, 43), + (140, 44), (141, 43), (141, 44), (142, 36), (142, 39), (142, 43), (142, 44), (144, 36), (144, 39), + (146, 36), (146, 39)], + "Scenic Course": + [(24, 28), (39, 28), (54, 28), (72, 28), (87, 28), (103, 28), (117, 28)], + "Hippo Zone": + [(2, 20), (3, 3), (15, 26), (16, 26), (17, 26), (28, 4), (28, 7), (28, 10), (28, 13), (29, 4), + (29, 7), (29, 10), (29, 13), (29, 21), (30, 4), (30, 7), (30, 10), (30, 13), (32, 15), (33, 15), + (34, 15), (35, 15), (36, 15), (37, 15), (41, 12), (41, 13), (42, 11), (43, 10), (44, 10), (45, 10), + (46, 11), (47, 12), (47, 13), (48, 14), (49, 15), (50, 15), (51, 15), (52, 14), (53, 12), (53, 13), + (54, 11), (55, 10), (56, 10), (57, 10), (58, 11), (59, 12), (59, 13), (60, 14), (61, 15), (62, 15), + (63, 15), (64, 14), (65, 12), (65, 13), (66, 11), (67, 10), (68, 10), (69, 10), (70, 11), (71, 12), + (71, 13), (72, 14), (73, 15), (74, 15), (75, 15), (76, 14), (77, 12), (77, 13), (84, 11), (85, 11), + (85, 22), (86, 22), (91, 6), (92, 6), (92, 11), (93, 6), (93, 11), (94, 11), (95, 16), (96, 12), + (96, 16), (97, 8), (97, 12), (97, 16), (98, 8), (98, 12), (99, 8), (112, 6), (112, 7), (112, 12), + (112, 13), (113, 2), (113, 5), (113, 8), (113, 11), (113, 14), (113, 17), (114, 2), (114, 5), + (114, 8), (114, 11), (114, 14), (114, 17), (115, 3), (115, 4), (115, 9), (115, 10), (115, 15), + (115, 16), (124, 3), (124, 4), (124, 9), (124, 10), (124, 15), (124, 16), (125, 2), (125, 5), + (125, 8), (125, 11), (125, 14), (125, 17), (126, 2), (126, 5), (126, 8), (126, 11), (126, 14), + (126, 17), (127, 6), (127, 7), (127, 12), (127, 13), (129, 13), (130, 13), (131, 13), (132, 13), + (132, 22), (133, 13), (134, 13), (135, 13), (136, 13), (136, 21), (137, 13), (138, 13), (139, 13), + (139, 22), (140, 13), (141, 13), (142, 13), (154, 7), (155, 7), (156, 7), (157, 10), (158, 10), + (159, 10), (162, 15), (162, 16), (162, 17), (164, 15), (164, 16), (164, 17), (166, 15), (166, 16), + (166, 17), (168, 15), (168, 16), (168, 17), (170, 15), (170, 16), (170, 17), (172, 15), (172, 16), + (172, 17), (174, 15), (174, 16), (174, 17), (176, 15), (176, 16), (176, 17)], + "Space Zone 1": + [(38, 26), (45, 25), (46, 25), (47, 25), (57, 24), (58, 24), (59, 24), (60, 19), (60, 23), (61, 23), + (62, 23), (63, 23), (75, 24), (89, 16), (89, 17), (89, 18), (89, 19), (90, 16), (90, 17), (90, 18), + (90, 19), (91, 16), (91, 17), (91, 18), (91, 19), (92, 16), (92, 17), (92, 18), (92, 19), (93, 16), + (93, 17), (93, 18), (93, 19), (104, 22), (105, 22), (114, 22), (115, 22), (125, 10), (126, 9), + (127, 8), (128, 8), (129, 8), (130, 8), (131, 8), (132, 9), (133, 10), (136, 10), (137, 9), + (138, 8), (139, 8), (140, 8), (141, 8), (142, 8), (143, 9), (144, 10), (147, 10), (148, 9), + (149, 8), (150, 8), (151, 8), (152, 8), (153, 8), (154, 9), (155, 10), (155, 18), (155, 19), + (155, 20), (156, 17), (156, 18), (156, 19), (156, 20), (156, 21), (157, 16), (157, 17), (157, 18), + (157, 19), (157, 20), (157, 21), (157, 22), (158, 10), (158, 16), (158, 17), (158, 18), (158, 19), + (158, 20), (158, 21), (158, 22), (159, 9), (159, 16), (159, 17), (159, 18), (159, 19), (159, 20), + (159, 21), (159, 22), (160, 8), (160, 16), (160, 17), (160, 18), (160, 19), (160, 20), (160, 21), + (160, 22), (161, 8), (161, 16), (161, 17), (161, 18), (161, 19), (161, 20), (161, 21), (161, 22), + (162, 8), (162, 17), (162, 18), (162, 19), (162, 20), (162, 21), (163, 8), (163, 18), (163, 19), + (163, 20), (164, 8), (165, 9), (166, 10), (168, 10), (169, 9), (170, 8), (171, 8), (172, 8), + (173, 8), (174, 8), (175, 9), (176, 10)], + "Space Zone Secret Course": + [(16, 22), (16, 23), (16, 24), (18, 21), (18, 22), (18, 23), (20, 21), (20, 22), (20, 23), + (22, 20), (22, 21), (22, 22), (24, 19), (24, 20), (24, 21), (26, 18), (26, 19), (26, 20), + (28, 18), (28, 19), (28, 20), (30, 17), (30, 18), (30, 19), (36, 15), (36, 16), (36, 17), + (38, 14), (38, 15), (38, 16), (40, 13), (40, 14), (40, 15), (40, 24), (41, 24), (42, 13), + (42, 14), (42, 15), (44, 12), (44, 13), (44, 14), (46, 12), (46, 13), (46, 14), (48, 12), + (48, 13), (48, 14), (50, 11), (50, 12), (50, 13), (50, 27), (51, 27), (52, 10), (52, 11), + (52, 12), (52, 27), (53, 27), (54, 27), (58, 11), (58, 12), (58, 13), (60, 12), (60, 13), + (60, 14), (62, 12), (62, 13), (62, 14), (64, 12), (64, 13), (64, 14), (66, 13), (66, 14), + (66, 15), (68, 13), (68, 14), (68, 15), (70, 14), (70, 15), (70, 16), (72, 15), (72, 16), + (72, 17), (74, 16), (74, 17), (74, 18), (80, 18), (80, 19), (80, 20), (82, 19), (82, 20), + (82, 21), (84, 19), (84, 20), (84, 21), (86, 20), (86, 21), (86, 22), (88, 21), (88, 22), + (88, 23)], + "Space Zone 2": + [(11, 13), (12, 13), (13, 13), (20, 8), (21, 8), (22, 8), (25, 5), (26, 5), (27, 5), (33, 6), + (34, 6), (35, 6), (36, 10), (37, 10), (38, 10), (45, 7), (46, 7), (47, 7), (59, 5), (60, 5), + (61, 5), (64, 3), (93, 8), (94, 8), (95, 8), (96, 11), (97, 11), (98, 11), (100, 6), (101, 6), + (102, 6), (102, 8), (120, 5), (124, 12), (124, 13), (125, 12), (125, 13), (126, 12), (126, 13), + (127, 3), (127, 12), (127, 13), (128, 3), (128, 7), (129, 3), (129, 7), (130, 7), (148, 6), + (148, 7), (148, 8), (149, 5), (149, 6), (149, 7), (149, 8), (149, 9), (150, 5), (150, 6), (150, 7), + (150, 8), (150, 9), (151, 5), (151, 6), (151, 7), (151, 8), (151, 9), (152, 5), (152, 6), (152, 7), + (152, 8), (152, 9), (153, 6), (153, 7), (153, 8), (165, 7), (165, 8), (166, 7), (166, 8), (167, 7), + (167, 8), (168, 7), (168, 8), (169, 7), (169, 8), (170, 7), (170, 8), (171, 7), (171, 8), (181, 9), + (185, 4), (200, 3), (200, 6), (200, 9), (201, 3), (201, 6), (201, 9), (202, 3), (202, 6), (202, 9), + (203, 3), (203, 6), (203, 9), (204, 3), (204, 6), (204, 9), (205, 3), (205, 6), (205, 9), (206, 3), + (206, 6), (206, 9), (207, 3), (207, 6), (207, 9), (208, 3), (208, 6), (208, 9), (209, 3), (209, 6), + (209, 9), (210, 3), (210, 6), (210, 9), (230, 12), (231, 12), (232, 12), (236, 2), (236, 3), + (236, 4), (236, 5), (237, 2), (237, 3), (237, 4), (237, 5), (238, 2), (238, 3), (238, 4), (238, 5), + (248, 10)], + "Turtle Zone 1": + [(22, 34), (27, 37), (28, 37), (29, 37), (30, 37), (31, 37), (32, 37), (33, 37), (34, 37), + (35, 37), (36, 37), (46, 32), (46, 33), (47, 32), (47, 33), (50, 32), (50, 33), (51, 32), + (51, 33), (54, 32), (54, 33), (55, 32), (55, 33), (56, 33), (57, 33), (58, 32), (58, 33), + (59, 32), (59, 33), (62, 32), (62, 33), (63, 32), (63, 33), (66, 32), (66, 33), (67, 32), + (67, 33), (73, 43), (74, 43), (75, 43), (77, 41), (78, 41), (79, 41), (81, 40), (82, 40), + (83, 40), (85, 41), (86, 41), (87, 41), (122, 36), (123, 36), (124, 36), (125, 36), (126, 36), + (127, 36), (130, 36), (131, 36), (132, 36), (133, 36), (134, 36), (135, 36), (136, 36), (137, 36), + (138, 36), (139, 36), (140, 36), (141, 36), (143, 34), (163, 36), (164, 36), (166, 36), (167, 36), + (169, 36), (170, 36), (180, 37), (181, 37), (182, 37), (183, 37), (184, 37), (185, 37), (188, 44), + (189, 44)], + "Turtle Zone 2": + [(6, 34), (11, 34), (15, 43), (48, 36), (51, 28), (56, 35), (57, 35), (59, 42), (61, 20), (62, 20), + (62, 35), (63, 20), (63, 35), (64, 20), (65, 20), (67, 35), (68, 35), (72, 39), (79, 34), + (82, 35), (87, 42), (96, 43), (105, 43), (107, 43), (109, 43), (118, 28), (121, 28), (139, 39), + (142, 39)], + "Turtle Zone Secret Course": + [(19, 27), (39, 27), (39, 28), (40, 26), (40, 27), (41, 25), (41, 27), (42, 25), (42, 27), + (43, 26), (43, 27), (44, 27), (44, 28), (48, 25), (48, 26), (48, 27), (48, 28), (49, 25), + (49, 27), (50, 25), (50, 27), (51, 25), (51, 27), (52, 26), (52, 28), (53, 27), (61, 25), + (61, 28), (62, 25), (62, 26), (62, 27), (62, 28), (63, 25), (63, 28), (64, 26), (73, 26), + (73, 27), (74, 25), (74, 28), (75, 25), (75, 28), (76, 25), (76, 28), (77, 26), (77, 27), + (82, 25), (82, 26), (82, 27), (82, 28), (83, 28), (84, 28), (85, 28), (87, 27), (89, 27), + (89, 28), (90, 26), (90, 27), (91, 25), (91, 27), (92, 25), (92, 27), (93, 26), (93, 27), + (94, 27), (94, 28), (98, 24), (98, 25), (98, 26), (98, 27), (99, 25), (100, 26), (101, 27), + (102, 24), (102, 25), (102, 26), (102, 27), (108, 24), (108, 25), (108, 26), (108, 27), + (109, 24), (109, 27), (110, 24), (110, 27), (111, 24), (111, 27), (112, 25), (112, 26), + (116, 24), (116, 27), (117, 23), (117, 26), (117, 27), (118, 23), (118, 25), (118, 27), + (119, 23), (119, 25), (119, 27), (120, 24), (120, 27), (121, 28), (122, 28), (123, 28)], + "Turtle Zone 3": + [(16, 25), (17, 25), (18, 25), (19, 25), (20, 25), (21, 25), (22, 25), (23, 25), (24, 25), + (35, 24), (36, 24), (37, 24), (38, 24), (39, 24), (40, 24), (41, 24), (42, 24), (43, 24), + (75, 28), (75, 29), (76, 28), (76, 29), (81, 28), (81, 29), (82, 28), (82, 29), (92, 26), + (93, 26), (94, 26), (98, 26), (99, 26), (100, 26), (123, 26), (124, 26), (126, 26), (127, 26), + (129, 26), (130, 26), (146, 22), (146, 29), (147, 22), (147, 29), (148, 22), (150, 22), (151, 22), + (152, 23), (152, 29), (153, 29), (154, 22), (155, 22), (156, 22), (158, 29), (159, 29), (161, 22), + (162, 22), (163, 22), (165, 22), (166, 22), (167, 22), (169, 22), (170, 22), (171, 22)], + "Mario Zone 1": + [(18, 44), (47, 36), (47, 37), (47, 38), (47, 39), (49, 36), (49, 37), (49, 38), (50, 36), (50, 37), + (50, 38), (52, 36), (52, 37), (52, 38), (53, 36), (53, 37), (53, 38), (60, 35), (60, 36), (60, 37), + (61, 35), (61, 36), (61, 37), (64, 35), (64, 36), (64, 37), (65, 35), (65, 36), (65, 37), (71, 36), + (78, 36), (78, 37), (78, 38), (98, 38), (145, 42), (146, 22), (146, 23), (146, 25), (146, 26), + (146, 42), (147, 22), (147, 23), (147, 25), (147, 26), (147, 30), (147, 31), (147, 32), (147, 42), + (148, 22), (148, 23), (148, 25), (148, 30), (148, 31), (148, 32), (148, 42), (149, 21), (149, 22), + (149, 23), (149, 24), (149, 30), (149, 31), (149, 42), (150, 21), (150, 22), (150, 23), (150, 24), + (150, 26), (150, 27), (150, 28), (150, 30), (150, 31), (150, 42), (151, 27), (151, 28), (151, 30), + (151, 31), (151, 42), (152, 27), (152, 29), (152, 30), (152, 31), (152, 42), (153, 27), (153, 29), + (153, 30), (153, 42), (154, 27), (154, 29), (154, 30), (164, 20), (167, 21), (167, 26), (167, 34), + (168, 21), (168, 25), (168, 27), (168, 33), (168, 35), (169, 20), (169, 24), (169, 28), (169, 33), + (169, 35), (170, 20), (170, 23), (170, 29), (170, 32), (170, 35), (171, 20), (171, 23), (171, 29), + (171, 32), (171, 36), (171, 37), (172, 21), (172, 22), (172, 30), (172, 31)], + "Mario Zone 2": + [(25, 24), (25, 27), (26, 24), (26, 27), (27, 24), (27, 27), (81, 27), (112, 24), (113, 24), + (114, 24), (115, 24), (116, 24), (117, 24), (118, 24), (121, 24), (122, 24), (123, 24), (124, 24), + (125, 24), (126, 24), (127, 24), (138, 26), (139, 26), (140, 24), (140, 28), (141, 24), (141, 28), + (144, 26), (145, 26), (146, 24), (146, 28), (147, 28), (151, 26), (152, 24), (152, 28), (153, 24), + (153, 28), (156, 26), (157, 26), (158, 24), (158, 28), (159, 24), (159, 28), (162, 26), (163, 26), + (164, 28), (165, 28)], + "Mario Zone 3": + [(8, 28), (11, 28), (14, 28), (17, 28), (20, 28), (23, 28), (54, 25), (100, 27), (109, 18), + (109, 19), (110, 18), (110, 19), (111, 17), (111, 18), (111, 19), (112, 17), (112, 18), (112, 19), + (127, 17), (127, 18), (127, 19), (128, 17), (128, 18), (128, 19), (129, 18), (129, 19), (130, 18), + (130, 19), (130, 20), (131, 18), (131, 19), (131, 20), (132, 18), (132, 19), (132, 20), (133, 18), + (133, 19), (133, 20), (133, 27), (134, 18), (134, 19), (134, 20), (157, 28), (158, 28), (159, 28), + (160, 28), (161, 28), (168, 28), (169, 28), (170, 28), (171, 28), (172, 28), (189, 44), (199, 28), + (200, 28), (201, 28), (202, 28), (203, 28), (214, 27), (217, 27), (220, 27), (223, 27)], + "Mario Zone 4": + [(20, 25), (114, 24), (114, 25), (114, 26), (115, 24), (115, 25), (115, 26), (115, 27), (115, 28), + (115, 29), (116, 24), (116, 25), (116, 26), (116, 27), (116, 29), (117, 24), (117, 25), (117, 26), + (117, 27), (117, 28), (117, 29), (118, 24), (118, 25), (118, 26), (118, 27), (118, 28), (118, 29), + (119, 24), (119, 25), (119, 27), (119, 28), (119, 29), (120, 24), (120, 25), (120, 26), (120, 27), + (120, 28), (120, 29), (121, 24), (121, 25), (121, 26), (121, 27), (121, 28), (121, 29), (122, 12), + (122, 24), (122, 25), (122, 26), (122, 27), (122, 29), (123, 12), (123, 24), (123, 25), (123, 26), + (123, 27), (123, 28), (123, 29), (124, 12), (124, 24), (124, 25), (124, 26), (124, 27), (124, 28), + (124, 29), (125, 12), (179, 12)], + "Pumpkin Zone 1": + [(23, 12), (55, 24), (55, 26), (56, 27), (57, 24), (57, 26), (63, 24), (63, 26), (64, 27), + (65, 24), (65, 26), (71, 24), (71, 26), (72, 27), (73, 24), (73, 26), (79, 24), (79, 26), + (80, 27), (81, 24), (81, 26), (86, 25), (86, 27), (92, 4), (93, 27), (95, 25), (95, 27), (98, 4), + (102, 26), (102, 28), (104, 4), (104, 26), (104, 28), (165, 14), (166, 15), (171, 20), (172, 21), + (173, 22), (175, 24), (176, 25), (177, 26), (179, 28), (180, 29), (189, 6)], + "Pumpkin Zone 2": + [(34, 26), (40, 21), (41, 21), (42, 21), (43, 21), (48, 20), (49, 20), (50, 20), (50, 41), + (51, 20), (51, 41), (52, 41), (53, 41), (54, 41), (56, 21), (57, 21), (58, 21), (59, 21), + (61, 41), (62, 41), (64, 20), (65, 20), (66, 20), (67, 20), (114, 36), (115, 35), (115, 36), + (116, 34), (116, 35), (116, 36), (132, 20), (132, 21), (132, 22), (132, 23), (132, 24), + (144, 23), (169, 27)], + "Pumpkin Zone 3": + [(18, 26), (20, 26), (22, 26), (24, 26), (26, 26), (31, 18), (32, 18), (33, 18), (34, 18), + (35, 18), (36, 18), (37, 18), (38, 18), (39, 18), (40, 18), (41, 18), (42, 18), (48, 24), + (52, 20), (52, 24), (56, 24), (87, 27), (88, 27), (89, 27), (90, 27), (94, 27), (95, 27), + (96, 27), (97, 27), (101, 27), (102, 27), (103, 27), (104, 27), (104, 42), (108, 27), (109, 27), + (110, 27), (111, 27), (115, 27), (116, 27), (117, 27), (118, 27), (134, 35), (134, 41), + (135, 35), (135, 41), (136, 35), (136, 41), (137, 35), (137, 41), (138, 35), (138, 41), + (139, 35), (139, 41), (140, 41), (225, 38), (226, 37), (227, 36), (227, 37), (227, 38), + (227, 39), (227, 40), (227, 41), (228, 37), (229, 38)], + "Pumpkin Zone Secret Course 1": + [(14, 15), (16, 9), (16, 10), (16, 11), (16, 12), (16, 13), (16, 14), (16, 15), (16, 16), + (17, 9), (17, 10), (17, 11), (17, 12), (17, 13), (17, 14), (17, 15), (17, 16), (18, 9), + (18, 10), (18, 11), (18, 12), (18, 13), (18, 14), (18, 15), (18, 16), (19, 9), (19, 10), + (19, 11), (19, 12), (19, 13), (19, 14), (19, 15), (19, 16), (20, 9), (20, 10), (20, 11), + (20, 12), (20, 13), (20, 14), (20, 15), (20, 16), (21, 9), (21, 10), (21, 11), (21, 12), + (21, 13), (21, 14), (21, 15), (21, 16), (22, 9), (22, 10), (22, 11), (22, 12), (22, 13), + (22, 14), (22, 15), (22, 16), (23, 9), (23, 10), (23, 11), (23, 12), (23, 13), (23, 14), + (23, 15), (23, 16), (24, 9), (24, 10), (24, 11), (24, 12), (24, 13), (24, 14), (24, 15), + (24, 16), (25, 9), (25, 10), (25, 11), (25, 12), (25, 13), (25, 14), (25, 15), (25, 16), + (26, 9), (26, 10), (26, 11), (26, 12), (26, 13), (26, 14), (26, 15), (27, 16), (28, 9), + (28, 10), (28, 11), (28, 12), (28, 13), (28, 14), (28, 15), (28, 16), (29, 9), (29, 10), + (29, 11), (29, 12), (29, 13), (29, 14), (29, 15), (29, 16), (30, 9), (30, 10), (30, 11), + (30, 12), (30, 13), (30, 14), (30, 15), (30, 16), (31, 9), (31, 10), (31, 11), (31, 12), + (31, 13), (31, 14), (31, 15), (31, 16), (32, 9), (32, 10), (32, 11), (32, 12), (32, 13), + (32, 14), (32, 15), (32, 16), (33, 9), (33, 10), (33, 11), (33, 12), (33, 13), (33, 14), + (33, 15), (33, 16), (34, 9), (34, 10), (34, 11), (34, 12), (34, 13), (34, 14), (34, 15), + (34, 16), (35, 9), (35, 10), (35, 11), (35, 12), (35, 13), (35, 14), (35, 15), (35, 16), + (36, 9), (36, 10), (36, 11), (36, 12), (36, 13), (36, 14), (36, 15), (36, 16), (37, 9), + (37, 10), (37, 11), (37, 12), (37, 13), (37, 14), (37, 15), (37, 16), (39, 16), (40, 9), + (40, 10), (40, 11), (40, 12), (40, 13), (40, 14), (40, 15), (40, 16), (41, 9), (41, 10), + (41, 11), (41, 12), (41, 13), (41, 14), (41, 15), (41, 16), (42, 9), (42, 10), (42, 11), + (42, 12), (42, 13), (42, 14), (42, 15), (42, 16), (43, 9), (43, 10), (43, 11), (43, 12), + (43, 13), (43, 14), (43, 15), (43, 16), (44, 9), (44, 10), (44, 11), (44, 12), (44, 13), + (44, 14), (44, 15), (44, 16), (45, 9), (45, 10), (45, 11), (45, 12), (45, 13), (45, 14), + (45, 15), (45, 16), (46, 9), (46, 10), (46, 11), (46, 12), (46, 13), (46, 14), (46, 15), + (46, 16), (47, 9), (47, 10), (47, 11), (47, 12), (47, 13), (47, 14), (47, 15), (47, 16), + (48, 9), (48, 10), (48, 11), (48, 12), (48, 13), (48, 14), (48, 15), (48, 16), (49, 9), + (49, 10), (49, 11), (49, 12), (49, 13), (49, 14), (49, 15), (49, 16), (52, 9), (52, 10), + (52, 11), (52, 12), (52, 13), (52, 14), (52, 15), (52, 16), (53, 9), (53, 10), (53, 11), + (53, 12), (53, 13), (53, 14), (53, 15), (53, 16), (54, 9), (54, 10), (54, 11), (54, 12), + (54, 13), (54, 14), (54, 15), (54, 16), (55, 9), (55, 10), (55, 11), (55, 12), (55, 13), + (55, 14), (55, 15), (55, 16), (56, 9), (56, 10), (56, 11), (56, 12), (56, 13), (56, 14), + (56, 15), (56, 16), (57, 9), (57, 10), (57, 11), (57, 12), (57, 13), (57, 14), (57, 15), + (57, 16), (58, 9), (58, 10), (58, 11), (58, 12), (58, 13), (58, 14), (58, 15), (58, 16), + (59, 9), (59, 10), (59, 11), (59, 12), (59, 13), (59, 14), (59, 15), (59, 16), (60, 9), + (60, 10), (60, 11), (60, 12), (60, 13), (60, 14), (60, 15), (60, 16), (61, 9), (61, 10), + (61, 11), (61, 12), (61, 13), (61, 14), (61, 15), (61, 16), (64, 9), (64, 10), (64, 11), + (64, 12), (64, 13), (64, 14), (64, 15), (64, 16), (65, 9), (65, 10), (65, 11), (65, 12), + (65, 13), (65, 14), (65, 15), (65, 16), (66, 9), (66, 10), (66, 11), (66, 12), (66, 13), + (66, 14), (66, 15), (66, 16), (67, 9), (67, 10), (67, 11), (67, 12), (67, 13), (67, 14), + (67, 15), (67, 16), (68, 9), (68, 10), (68, 11), (68, 12), (68, 13), (68, 14), (68, 15), + (68, 16), (69, 9), (69, 10), (69, 11), (69, 12), (69, 13), (69, 14), (69, 15), (69, 16), + (70, 9), (70, 10), (70, 11), (70, 12), (70, 13), (70, 14), (70, 15), (70, 16), (71, 9), + (71, 10), (71, 11), (71, 12), (71, 13), (71, 14), (71, 15), (71, 16), (72, 9), (72, 10), + (72, 11), (72, 12), (72, 13), (72, 14), (72, 15), (72, 16), (73, 9), (73, 10), (73, 11), + (73, 12), (73, 13), (73, 14), (73, 15), (73, 16)], + "Pumpkin Zone Secret Course 2": + [(12, 6), (72, 7), (73, 7), (80, 7), (81, 7), (85, 8), (90, 10), (91, 10), (94, 10), + (95, 10), (98, 9), (99, 9), (102, 9), (103, 9)], + "Pumpkin Zone 4": + [(18, 28), (19, 28), (20, 28), (21, 28), (83, 37), (83, 38), (84, 37), (84, 38), (85, 37), + (85, 38), (85, 39), (86, 37), (87, 37), (87, 40), (88, 37), (88, 38), (88, 39), (88, 40), + (89, 37), (89, 38), (89, 39), (89, 40), (90, 37), (90, 38), (91, 37), (91, 38), (92, 37), + (92, 38), (92, 39), (92, 40), (93, 23), (93, 37), (93, 40), (94, 23), (94, 37), (94, 40), + (103, 23), (104, 23), (113, 23), (114, 23), (169, 30), (170, 28), (170, 30), (171, 26), + (171, 28), (171, 30), (172, 24), (172, 26), (172, 28), (172, 30), (173, 24), (173, 26), + (173, 28), (173, 30), (174, 26), (174, 28), (174, 30), (175, 28), (175, 30), (176, 30), + (198, 37), (198, 38), (199, 37), (199, 38), (204, 37), (204, 38), (205, 37), (205, 38), + (210, 37), (210, 38), (211, 37), (211, 38), (216, 37), (216, 38), (217, 37), (217, 38)], + "Macro Zone 1": + [(22, 32), (22, 33), (22, 34), (23, 20), (23, 21), (23, 22), (23, 38), (23, 39), (23, 40), (24, 26), + (24, 27), (24, 28), (39, 42), (40, 41), (41, 40), (42, 39), (49, 43), (62, 42), (62, 43), (62, 44), + (68, 42), (68, 43), (68, 44), (75, 42), (75, 43), (75, 44), (84, 40), (84, 41), (84, 42), (87, 39), + (89, 42), (89, 43), (89, 44), (107, 42), (108, 42), (109, 42), (118, 42), (119, 42), (120, 42), + (121, 42), (122, 42), (128, 42), (128, 43), (130, 42), (130, 43), (134, 42), (134, 43), (140, 42), + (141, 42), (142, 42), (143, 42), (144, 42), (154, 42), (155, 42), (156, 42), (163, 22), (163, 23), + (164, 21), (164, 22), (164, 23), (165, 22), (165, 23), (166, 21), (166, 22), (166, 23), (167, 22), + (167, 23), (168, 21), (168, 22), (168, 23), (169, 22), (169, 23), (170, 21), (170, 22), (170, 23), + (171, 22), (171, 23), (177, 40), (182, 40), (189, 41), (189, 42), (189, 43), (189, 44), (189, 45), + (205, 46), (206, 46), (208, 37), (209, 37), (212, 41), (213, 41), (214, 41), (215, 41), (216, 41), + (220, 37), (221, 37), (224, 46), (225, 46), (234, 43), (246, 38), (246, 39), (246, 40), (246, 41), + (246, 42), (246, 43)], + "Macro Zone 2": + [(18, 28), (19, 27), (22, 28), (23, 27), (25, 26), (27, 27), (28, 27), (31, 27), (32, 27), (41, 29), + (42, 29), (43, 29), (55, 29), (57, 29), (60, 29), (62, 29), (69, 27), (70, 27), (71, 27), (74, 27), + (75, 27), (76, 27), (79, 27), (80, 27), (81, 27), (84, 27), (85, 27), (86, 27), (99, 40), + (137, 37), (180, 40), (181, 8), (182, 8), (183, 8), (184, 8), (185, 8), (186, 8), (187, 8), + (188, 8), (189, 8), (190, 8), (191, 8), (192, 8), (193, 8), (194, 8), (195, 8), (196, 8), (197, 8), + (198, 8), (199, 8), (200, 8), (201, 8), (202, 8), (204, 8), (205, 8), (206, 8), (207, 8), (208, 8), + (209, 8), (210, 8), (211, 8), (212, 8), (213, 8), (215, 8), (216, 8), (217, 8), (217, 11), + (218, 8), (218, 9), (218, 10), (218, 11), (218, 12), (219, 11)], + "Macro Zone 3": + [(24, 23), (37, 28), (38, 28), (39, 28), (40, 28), (57, 30), (58, 30), (59, 30), (65, 17), (65, 18), + (65, 19), (66, 17), (66, 18), (66, 19), (67, 17), (67, 18), (67, 19), (68, 17), (68, 18), (68, 19), + (69, 17), (69, 18), (69, 19), (70, 17), (70, 18), (70, 19), (73, 17), (73, 18), (73, 19), (74, 17), + (74, 18), (74, 19), (75, 17), (75, 18), (75, 19), (76, 17), (76, 18), (76, 19), (77, 17), (77, 18), + (77, 19), (78, 17), (78, 18), (78, 19), (85, 43), (95, 17), (95, 18), (95, 19), (95, 20), (96, 17), + (96, 18), (96, 19), (96, 20), (97, 17), (97, 18), (97, 19), (97, 20), (98, 17), (98, 18), (98, 19), + (98, 20), (100, 17), (100, 18), (100, 19), (100, 20), (101, 17), (101, 18), (101, 19), (101, 20), + (103, 42), (104, 42), (105, 42), (106, 42), (107, 42), (116, 42), (117, 42), (118, 42), (119, 42), + (120, 42), (121, 42), (122, 42), (129, 19), (131, 42), (132, 42), (133, 42), (134, 42), (135, 42), + (136, 42), (165, 21), (165, 22), (166, 21), (166, 22), (171, 21), (171, 22), (172, 21), (172, 22), + (176, 20), (176, 21), (176, 22), (179, 20), (179, 21), (179, 22), (183, 21), (183, 22), (184, 21), + (184, 22), (194, 27), (194, 28), (197, 27), (197, 28), (200, 27), (200, 28), (203, 25), (203, 27), + (203, 28), (205, 18), (205, 19), (206, 18), (206, 19)], + "Macro Zone 4": + [(16, 28), (34, 28), (39, 28), (39, 29), (39, 30), (40, 28), (40, 29), (40, 30), (41, 28), (41, 29), + (41, 30), (62, 29), (63, 29), (64, 29), (65, 29), (66, 29), (67, 29), (68, 29), (69, 29), (81, 17), + (81, 18), (82, 17), (82, 18), (83, 17), (83, 18), (84, 17), (84, 18), (85, 17), (85, 18), (86, 17), + (86, 18), (87, 17), (87, 18), (87, 28), (88, 17), (88, 18), (114, 28), (144, 22), (146, 27), + (146, 28), (147, 27), (147, 28), (148, 27), (148, 28), (149, 27), (149, 28), (150, 27), (150, 28), + (151, 27), (151, 28), (152, 27), (152, 28), (153, 27), (153, 28), (154, 27), (154, 28), (155, 27), + (155, 28), (156, 27), (156, 28), (157, 27), (157, 28), (158, 27), (158, 28)], + "Macro Zone Secret Course": + [(21, 24), (70, 27), (70, 28), (71, 27), (71, 28), (72, 27), (72, 28), (73, 27), (73, 28), + (74, 27), (74, 28), (75, 27), (75, 28), (76, 24), (76, 25), (76, 26), (76, 27), (76, 28), + (77, 24), (77, 25), (77, 26), (77, 27), (77, 28), (78, 24), (78, 25), (78, 26), (78, 27), + (78, 28), (79, 24), (79, 25), (79, 26), (79, 27), (80, 25), (80, 26), (81, 25), (81, 26), + (88, 25), (108, 30)], + "Mario's Castle": + [(7, 25), (160, 44), (167, 28), (247, 26)], +} +powerup_coords = { + "Mushroom Zone": [(42, 28), (151, 28), (152, 28), (188, 28)], + "Scenic Course": [(39, 28), (72, 28), (117, 28)], + "Tree Zone 1": [(119, 28), (152, 28)], + "Tree Zone 2": [(43, 10), (61, 9), (51, 28), (130, 7), (182, 3), (136, 43)], + "Tree Zone Secret Course": [(17, 23), (100, 23), (159, 23)], + "Tree Zone 3": [(26, 40), (77, 24)], + "Tree Zone 4": [(28, 27), (105, 25), (136, 22), (171, 10)], + "Tree Zone 5": [(123, 39), (138, 39), (146, 36)], + "Pumpkin Zone 1": [(23, 12), (72, 27), (98, 4), (189, 6)], + "Pumpkin Zone 2": [(144, 23)], + "Pumpkin Zone Secret Course 1": [(14, 15)], + "Pumpkin Zone 3": [(52, 20), (104, 42), (139, 35), (140, 41)], + "Pumpkin Zone Secret Course 2": [(12, 6), (85, 8)], + "Pumpkin Zone 4": [(83, 38), (94, 40), (104, 23)], + "Mario Zone 1": [(18, 44), (98, 38), (145, 42), (164, 20)], + "Mario Zone 2": [(81, 27)], + "Mario Zone 3": [(54, 25), (100, 27), (134, 18), (189, 44), (214, 27)], + "Mario Zone 4": [(20, 25), (124, 12), (179, 12)], + "Turtle Zone 1": [(22, 34), (56, 33), (57, 33), (143, 34), (189, 44)], + "Turtle Zone 2": [(82, 35), (139, 39), ], + "Turtle Zone Secret Course": [(19, 27), (53, 27), (64, 26), (87, 27), (121, 28), (122, 28), (123, 28)], + "Turtle Zone 3": [(39, 24), (94, 26), (152, 23)], + "Hippo Zone": [(3, 3), (2, 20), (15, 26), (16, 26), (29, 21), (86, 22), (137, 13)], + "Space Zone 1": [(75, 24), (114, 22)], + # "Space Zone Secret Course": [], + "Space Zone 2": [(64, 3), (102, 8), (120, 5), (207, 6), (210, 9), (248, 10)], + "Macro Zone 1": [(49, 43), (87, 39), (177, 40), (164, 21), (166, 21), (170, 21), (234, 43)], + "Macro Zone 2": [(25, 26), (99, 40), (137, 37), (180, 40)], + "Macro Zone 3": [(24, 23), (85, 43), (129, 19), (203, 25)], + "Macro Zone 4": [(16, 28), (87, 28), (144, 22)], + "Macro Zone Secret Course": [(21, 24), (88, 25), (108, 30)], + "Mario's Castle": [(7, 25), (160, 44), (167, 28), (247, 26)] +} +for zone, coords_list in powerup_coords.items(): + for coords in coords_list: + coins_coords[zone].remove(coords) + +location_name_to_id = {location_name: ID for ID, location_name in enumerate(locations, START_IDS)} +loc_id = START_IDS + len(locations) +for level, coin_coords in coins_coords.items(): + for i in range(1, len(coin_coords) + 1): + location_name_to_id[f"{level} - {i} Coin{'s' if i > 1 else ''}"] = loc_id + loc_id += 1 + +# eligible_levels = [0, 1, 2, 3, 5, 8, 9, 11, 13, 14, 16, 19, 20, 22, 23, 25, 30, 31] + +level_id_to_name = { + 0: "Mushroom Zone", 25: "Scenic Course", 1: "Tree Zone 1", 2: "Tree Zone 2", 4: "Tree Zone 3", 3: "Tree Zone 4", + 5: "Tree Zone 5", 29: "Tree Zone Secret Course", 17: "Hippo Zone", 18: "Space Zone 1", + 28: "Space Zone Secret Course", 19: "Space Zone 2", 20: "Macro Zone 1", 21: "Macro Zone 2", 22: "Macro Zone 3", + 23: "Macro Zone 4", 30: "Macro Zone Secret Course", 6: "Pumpkin Zone 1", 7: "Pumpkin Zone 2", + 8: "Pumpkin Zone 3", 9: "Pumpkin Zone 4", 27: "Pumpkin Zone Secret Course 1", 31: "Pumpkin Zone Secret Course 2", + 10: "Mario Zone 1", 11: "Mario Zone 2", 12: "Mario Zone 3", 13: "Mario Zone 4", 14: "Turtle Zone 1", + 15: "Turtle Zone 2", 16: "Turtle Zone 3", 26: "Turtle Zone Secret Course", 24: "Mario's Castle" +} + +level_name_to_id = {name: level_id for level_id, name in level_id_to_name.items()} + +auto_scroll_max = { + "Mushroom Zone": 84, + "Hippo Zone": 160, + "Tree Zone 1": 87, + "Tree Zone 2": 68, + "Tree Zone 3": 4, + "Tree Zone 4": 28, + "Tree Zone 5": 22, + "Space Zone 1": 72, + "Space Zone 2": 113, + "Space Zone Secret Course": 96, + "Macro Zone 1": 74, + "Macro Zone 2": 27, + "Macro Zone 3": 63, + "Macro Zone 4": 59, + "Pumpkin Zone 1": (0, 12), + "Pumpkin Zone 2": 23, + "Pumpkin Zone 3": 50, + "Pumpkin Zone 4": 45, + "Pumpkin Zone Secret Course 1": 172, + "Mario Zone 1": 68, + "Mario Zone 3": 29, + "Mario Zone 4": 60, + "Turtle Zone 1": 66, + "Turtle Zone 2": 8, +} diff --git a/worlds/marioland2/logic.py b/worlds/marioland2/logic.py new file mode 100644 index 000000000000..4cf3630ca26d --- /dev/null +++ b/worlds/marioland2/logic.py @@ -0,0 +1,607 @@ +from .locations import level_name_to_id + + +def is_auto_scroll(state, player, level): + level_id = level_name_to_id[level] + if state.has_any(["Cancel Auto Scroll", f"Cancel Auto Scroll - {level}"], player): + return False + return state.multiworld.worlds[player].auto_scroll_levels[level_id] > 0 + + +def has_pipe_right(state, player): + return state.has_any(["Pipe Traversal - Right", "Pipe Traversal"], player) + + +def has_pipe_left(state, player): + return state.has_any(["Pipe Traversal - Left", "Pipe Traversal"], player) + + +def has_pipe_down(state, player): + return state.has_any(["Pipe Traversal - Down", "Pipe Traversal"], player) + + +def has_pipe_up(state, player): + return state.has_any(["Pipe Traversal - Up", "Pipe Traversal"], player) + + +def has_level_progression(state, item, player, count=1): + return state.count(item, player) + (state.count(item + " x2", player) * 2) >= count + + +def mushroom_zone_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Mushroom Zone") + reachable_coins = 38 + if state.has_any(["Mushroom", "Fire Flower"], player) or not auto_scroll: + # Was able to get all but 1, being lenient. + reachable_coins += 2 + if has_pipe_down(state, player): + # There's 24 in each of the underground sections. + # The first one requires missing some question mark blocks if auto scrolling (the last +4). + # If you go in the second without pipe up, you can get everything except the last 5 plus the ones in the first + # underground section. + reachable_coins += 19 + if has_pipe_up(state, player) or not auto_scroll: + reachable_coins += 5 + if has_pipe_up(state, player): + reachable_coins += 20 + if not auto_scroll: + reachable_coins += 4 + return coins <= reachable_coins + + +def tree_zone_1_coins(state, player, coins): + return coins <= 87 or not is_auto_scroll(state, player, "Tree Zone 1") + + +def tree_zone_2_normal_exit(state, player): + return has_pipe_right(state, player) or state.has("Tree Zone 2 Midway Bell", player) + + +def tree_zone_2_secret_exit(state, player): + return has_pipe_right(state, player) and state.has("Carrot", player) + + +def tree_zone_2_midway_bell(state, player): + return has_pipe_right(state, player) or state.has("Tree Zone 2 Midway Bell", player) + + +def tree_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Tree Zone 2") + reachable_coins = 18 + if has_pipe_right(state, player): + reachable_coins += 38 + if state.has("Carrot", player): + reachable_coins += 12 + if not auto_scroll: + reachable_coins += 30 + elif state.has("Tree Zone 2 Midway Bell", player): + reachable_coins = 30 + if not auto_scroll: + reachable_coins += 8 + return coins <= reachable_coins + + +def tree_zone_3_normal_exit(state, player): + return not is_auto_scroll(state, player, "Tree Zone 3") + + +def tree_zone_3_coins(state, player, coins): + if is_auto_scroll(state, player, "Tree Zone 3"): + return coins <= 4 + if coins <= 19: + return True + elif state.has_any(["Mushroom", "Fire Flower"], player) and coins <= 21: + return True + return state.has("Carrot", player) + + +def tree_zone_4_normal_exit(state, player): + return has_pipe_down(state, player) and tree_zone_4_midway_bell(state, player) + + +def tree_zone_4_midway_bell(state, player): + return ((has_pipe_right(state, player) and has_pipe_up(state, player)) + or state.has("Tree Zone 4 Midway Bell", player)) + + +def tree_zone_4_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Tree Zone 4") + reachable_coins = 0 + if has_pipe_up(state, player): + reachable_coins += 14 + if has_pipe_right(state, player): + reachable_coins += 4 + if has_pipe_down(state, player): + reachable_coins += 10 + if not auto_scroll: + reachable_coins += 46 + elif state.has("Tree Zone 4 Midway Bell", player): + if not auto_scroll: + if has_pipe_left(state, player): + reachable_coins += 18 + if has_pipe_down(state, player): + reachable_coins += 10 + if has_pipe_up(state, player): + reachable_coins += 46 + elif has_pipe_down(state, player): + reachable_coins += 10 + return coins <= reachable_coins + + +def tree_zone_5_boss(state, player): + return has_pipe_right(state, player) and (has_pipe_up(state, player) or state.has("Carrot", player)) + + +def tree_zone_5_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Tree Zone 5") + reachable_coins = 0 + # Not actually sure if these platforms can be randomized / can make the coin blocks unreachable from below + if ((not state.multiworld.worlds[player].options.randomize_platforms) + or state.has_any(["Mushroom", "Fire Flower"], player)): + reachable_coins += 2 + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 2 + if state.has("Carrot", player): + reachable_coins += 18 + if has_pipe_up(state, player) and not auto_scroll: + reachable_coins += 13 + elif has_pipe_up(state, player): + reachable_coins += 13 + return coins <= reachable_coins + + +def pumpkin_zone_1_normal_exit(state, player): + return pumpkin_zone_1_midway_bell(state, player) + + +def pumpkin_zone_1_midway_bell(state, player): + return ((has_pipe_down(state, player) and not is_auto_scroll(state, player, "Pumpkin Zone 1")) + or state.has("Pumpkin Zone 1 Midway Bell", player)) + + +def pumpkin_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 1") + if auto_scroll: + return coins <= 12 and state.has("Pumpkin Zone 1 Midway Bell", player) + reachable_coins = 0 + if state.has("Pumpkin Zone 1 Midway Bell", player) or has_pipe_down(state, player): + reachable_coins += 38 + if has_pipe_up(state, player): + reachable_coins += 2 + return coins <= reachable_coins + + +def pumpkin_zone_2_normal_exit(state, player): + return has_pipe_down(state, player) and has_pipe_up(state, player) and has_pipe_right(state, player) and state.has( + "Water Physics", player) and not is_auto_scroll(state, player, "Pumpkin Zone 2") + + +def pumpkin_zone_2_secret_exit(state, player): + return pumpkin_zone_2_normal_exit(state, player) and state.has_any(["Mushroom", "Fire Flower"], player) + + +def pumpkin_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 2") + reachable_coins = 17 + if has_pipe_down(state, player): + if not auto_scroll: + reachable_coins += 7 + if (has_pipe_up(state, player) or auto_scroll) and state.has("Water Physics", player): + reachable_coins += 6 + if has_pipe_right(state, player) and not auto_scroll: + reachable_coins += 1 + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 5 + return coins <= reachable_coins + + +def pumpkin_zone_secret_course_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone Secret Course 1") + # We'll be a bit forgiving. + if coins <= 20: + return True + if state.has("Carrot", player): + if auto_scroll: + return coins <= 172 + return True + return False + + +def pumpkin_zone_3_secret_exit(state, player): + return state.has("Carrot", player) + + +def pumpkin_zone_3_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 3") + reachable_coins = 38 + if has_pipe_up(state, player) and ((not auto_scroll) or has_pipe_down(state, player)): + reachable_coins += 12 + if has_pipe_down(state, player) and not auto_scroll: + reachable_coins += 11 + return coins <= reachable_coins + + +def pumpkin_zone_4_boss(state, player): + return has_pipe_right(state, player) + + +def pumpkin_zone_4_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 4") + reachable_coins = 29 + if has_pipe_down(state, player): + if auto_scroll: + if has_pipe_up(state, player): + reachable_coins += 16 + else: + reachable_coins += 4 + else: + reachable_coins += 28 + # both sets of coins are down, but you need pipe up to return to go down to the next set in one playthrough + if has_pipe_up(state, player): + reachable_coins += 16 + return coins <= reachable_coins + + +def mario_zone_1_normal_exit(state, player): + if has_pipe_right(state, player): + if state.has_any(["Mushroom", "Fire Flower", "Carrot", "Mario Zone 1 Midway Bell"], player): + return True + if is_auto_scroll(state, player, "Mario Zone 1"): + return True + return False + + +def mario_zone_1_midway_bell(state, player): + # It is possible to get as small mario, but it is a very precise jump and you will die afterward. + return ((state.has_any(["Mushroom", "Fire Flower", "Carrot"], player) and has_pipe_right(state, player)) + or state.has("Mario Zone 1 Midway Bell", player)) + + +def mario_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Mario Zone 1") + reachable_coins = 0 + if has_pipe_right(state, player) or (has_pipe_left(state, player) + and state.has("Mario Zone 1 Midway Bell", player) and not auto_scroll): + reachable_coins += 32 + if has_pipe_right(state, player) and (state.has_any(["Mushroom", "Fire Flower", "Carrot"], player) + or not auto_scroll): + reachable_coins += 8 + # coins from end section. I was able to get 13 as small mario, giving some leniency + if state.has("Carrot", player): + reachable_coins += 28 + else: + reachable_coins += 12 + if state.has("Fire Flower", player) and not auto_scroll: + reachable_coins += 46 + return coins <= reachable_coins + + +def mario_zone_3_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Mario Zone 3") + reachable_coins = 10 + if state.has("Carrot", player): + reachable_spike_coins = 15 + else: + sprites = state.multiworld.worlds[player].sprite_data["Mario Zone 3"] + reachable_spike_coins = min(3, len({sprites[i]["sprite"] == "Claw Grabber" for i in (17, 18, 25)}) + + state.has("Mushroom", player) + state.has("Fire Flower", player)) * 5 + reachable_coins += reachable_spike_coins + if not auto_scroll: + reachable_coins += 10 + if state.has("Fire Flower", player): + reachable_coins += 22 + if auto_scroll: + reachable_coins -= 3 + reachable_spike_coins + return coins <= reachable_coins + + +def mario_zone_4_boss(state, player): + return has_pipe_right(state, player) + + +def mario_zone_4_coins(state, player, coins): + return coins <= 60 or not is_auto_scroll(state, player, "Mario Zone 4") + + +def not_blocked_by_sharks(state, player): + sharks = [state.multiworld.worlds[player].sprite_data["Turtle Zone 1"][i]["sprite"] + for i in (27, 28)].count("Shark") + if state.has("Carrot", player) or not sharks: + return True + if sharks == 2: + return state.has_all(["Mushroom", "Fire Flower"], player) + if sharks == 1: + return state.has_any(["Mushroom", "Fire Flower"], player) + return False + + +def turtle_zone_1_normal_exit(state, player): + return not_blocked_by_sharks(state, player) + + +def turtle_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Turtle Zone 1") + reachable_coins = 30 + if not_blocked_by_sharks(state, player): + reachable_coins += 13 + if auto_scroll: + reachable_coins -= 1 + if state.has("Water Physics", player) or state.has("Carrot", player): + reachable_coins += 10 + if state.has("Carrot", player): + reachable_coins += 24 + if auto_scroll: + reachable_coins -= 10 + return coins <= reachable_coins + + +def turtle_zone_2_normal_exit(state, player): + return (has_pipe_up(state, player) and has_pipe_down(state, player) and has_pipe_right(state, player) and + has_pipe_left(state, player) and state.has("Water Physics", player) + and not is_auto_scroll(state, player, "Turtle Zone 2")) + + +def turtle_zone_2_secret_exit(state, player): + return (has_pipe_up(state, player) and state.has("Water Physics", player) + and not is_auto_scroll(state, player, "Turtle Zone 2")) + + +def turtle_zone_2_midway_bell(state, player): + return ((state.has("Water Physics", player) and not is_auto_scroll(state, player, "Turtle Zone 2")) + or state.has("Turtle Zone 2 Midway Bell", player)) + + +def turtle_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Turtle Zone 2") + reachable_coins = 2 + if auto_scroll: + if state.has("Water Physics", player): + reachable_coins += 6 + else: + reachable_coins += 2 + if state.has("Water Physics", player): + reachable_coins += 20 + elif state.has("Turtle Zone 2 Midway Bell", player): + reachable_coins += 4 + if (has_pipe_right(state, player) and has_pipe_down(state, player) + and state.has_any(["Water Physics", "Turtle Zone 2 Midway Bell"], player)): + reachable_coins += 1 + if has_pipe_left(state, player) and has_pipe_up(state, player): + reachable_coins += 1 + if state.has("Water Physics", player): + reachable_coins += 1 + return coins <= reachable_coins + + +def turtle_zone_secret_course_normal_exit(state, player): + return state.has_any(["Fire Flower", "Carrot"], player) + + +def turtle_zone_secret_course_coins(state, player, coins): + reachable_coins = 53 + if state.has("Carrot", player): + reachable_coins += 44 + elif state.has("Fire Flower", player): + reachable_coins += 36 # was able to get 38, some leniency + return coins <= reachable_coins + + +def turtle_zone_3_boss(state, player): + return has_pipe_right(state, player) + + +def turtle_zone_3_coins(state, player, coins): + return state.has_any(["Water Physics", "Mushroom", "Fire Flower", "Carrot"], player) or coins <= 51 + + +def hippo_zone_normal_or_secret_exit(state, player): + return (state.has_any(["Hippo Bubble", "Water Physics"], player) + or (state.has("Carrot", player) + and not is_auto_scroll(state, player, "Hippo Zone"))) + + +def hippo_zone_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Hippo Zone") + # This is all somewhat forgiving. + reachable_coins = 4 + if auto_scroll: + if state.has("Hippo Bubble", player): + reachable_coins = 160 + elif state.has("Carrot", player): + reachable_coins = 90 + elif state.has("Water Physics", player): + reachable_coins = 28 + else: + if state.has_any(["Water Physics", "Hippo Bubble", "Carrot"], player): + reachable_coins += 108 + if state.has_any(["Mushroom", "Fire Flower", "Hippo Bubble"], player): + reachable_coins += 6 + if state.has_all(["Fire Flower", "Water Physics"], player): + reachable_coins += 1 + if state.has("Hippo Bubble", player): + reachable_coins += 52 + return coins <= reachable_coins + + +def space_zone_1_normal_exit(state, player): + # It is possible, however tricky, to beat the Moon Stage without Carrot or Space Physics. + # However, it requires somewhat precisely jumping off enemies. Enemy shuffle may make this impossible. + # Instead, I will just always make one or the other required, since it is difficult without them anyway. + return state.has_any(["Space Physics", "Carrot"], player) + + +def space_zone_1_secret_exit(state, player): + # One or the other is actually necessary for the secret exit. + return state.has_any(["Space Physics", "Carrot"], player) and not is_auto_scroll(state, player, "Space Zone 1") + + +def space_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Space Zone 1") + if auto_scroll: + reachable_coins = 12 + if state.has_any(["Carrot", "Space Physics"], player): + reachable_coins += 20 + # If you have Space Physics, you can't make it up to the upper section. We have to assume you might have it, + # so the coins up there must be out of logic if there is auto scrolling. + if state.has("Space Physics", player): + reachable_coins += 40 + return coins <= reachable_coins + return (coins <= 21 or (coins <= 50 and state.has_any(["Mushroom", "Fire Flower"], player)) + or state.has_any(["Carrot", "Space Physics"], player)) + + +def space_zone_2_midway_bell(state, player): + return state.has_any(["Space Physics", "Space Zone 2 Midway Bell", "Mushroom", "Fire Flower", "Carrot"], player) + + +def space_zone_2_boss(state, player): + if has_pipe_right(state, player): + if state.has("Space Physics", player): + return True + if (state.has("Space Zone 2 Midway Bell", player) + or not state.multiworld.worlds[player].options.shuffle_midway_bells): + # Reaching the midway bell without space physics requires taking damage once. Reaching the end pipe from the + # midway bell also requires taking damage once. + if state.has_any(["Mushroom", "Fire Flower", "Carrot"], player): + return True + else: + # With no midway bell, you'll have to be able to take damage twice. + if state.has("Mushroom", player) and state.has_any(["Fire Flower", "Carrot"], player): + return True + return False + + +def space_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Space Zone 2") + reachable_coins = 12 + if state.has_any(["Mushroom", "Fire Flower", "Carrot", "Space Physics"], player): + reachable_coins += 15 + if state.has("Space Physics", player) or not auto_scroll: + reachable_coins += 4 # last few bottom row question mark blocks that are hard to get when auto scrolling. + if (state.has("Space Physics", player) or ( + state.has("Mushroom", player) and state.has_any(["Fire Flower", "Carrot"], player))): + reachable_coins += 3 + if state.has("Space Physics", player): + reachable_coins += 79 + if not auto_scroll: + reachable_coins += 21 + return coins <= reachable_coins + + +def space_zone_secret_course_coins(state, player, coins): + return coins <= 96 or not is_auto_scroll(state, player, "Space Zone Secret Course") + + +def macro_zone_1_normal_exit(state, player): + return has_pipe_down(state, player) or state.has("Macro Zone 1 Midway Bell", player) + + +def macro_zone_1_secret_exit(state, player): + return state.has("Fire Flower", player) and has_pipe_up(state, player) and macro_zone_1_midway_bell(state, player) + + +def macro_zone_1_midway_bell(state, player): + return has_pipe_down(state, player) or state.has("Macro Zone 1 Midway Bell", player) + + +def macro_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 1") + reachable_coins = 0 + if has_pipe_down(state, player): + reachable_coins += 69 + if auto_scroll: + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 5 + else: + reachable_coins += 9 + if state.has("Fire Flower", player): + reachable_coins += 19 + elif state.has("Macro Zone 1 Midway Bell", player): + if auto_scroll: + reachable_coins += 16 + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 5 + else: + reachable_coins += 67 + return coins <= reachable_coins + + +def macro_zone_secret_course_coins(state, player, coins): + return state.has_any(["Mushroom", "Fire Flower"], player) + + +def macro_zone_2_normal_exit(state, player): + return (has_pipe_down(state, player) or state.has("Macro Zone 2 Midway Bell", player)) and state.has( + "Water Physics", player) and has_pipe_up(state, player) and not is_auto_scroll(state, player, "Macro Zone 2") + + +def macro_zone_2_midway_bell(state, player): + return ((has_pipe_down(state, player) and state.has("Water Physics", player)) + or state.has("Macro Zone 2 Midway Bell", player)) + + +def macro_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 2") + if coins <= 27: + return True + if has_pipe_up(state, player) and state.has("Water Physics", player) and not auto_scroll: + if has_pipe_down(state, player): + return True + if state.has("Macro Zone 2 Midway Bell", player): + # Cannot return to the first section from the bell + return coins <= 42 + return False + + +def macro_zone_3_normal_exit(state, player): + return ((has_pipe_down(state, player) and has_pipe_up(state, player)) + or state.has("Macro Zone 3 Midway Bell", player)) + + +def macro_zone_3_midway_bell(state, player): + return macro_zone_3_normal_exit(state, player) + + +def macro_zone_3_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 3") + reachable_coins = 7 + if not auto_scroll: + reachable_coins += 17 + if has_pipe_up(state, player) and has_pipe_down(state, player): + if auto_scroll: + reachable_coins += 56 + else: + return True + elif has_pipe_up(state, player): + if auto_scroll: + reachable_coins += 12 + else: + reachable_coins += 36 + elif has_pipe_down(state, player): + reachable_coins += 18 + if state.has("Macro Zone 3 - Midway Bell", player): + reachable_coins = max(reachable_coins, 30) + return coins <= reachable_coins + + +def macro_zone_4_boss(state, player): + return has_pipe_right(state, player) + + +def macro_zone_4_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 4") + reachable_coins = 61 + if auto_scroll: + reachable_coins -= 8 + if state.has("Carrot", player): + reachable_coins += 6 + return coins <= reachable_coins + + +def marios_castle_wario(state, player): + return has_pipe_right(state, player) and has_pipe_left(state, player) + + +def marios_castle_midway_bell(state, player): + return ((has_pipe_right(state, player) and has_pipe_left(state, player)) + or state.has("Mario's Castle Midway Bell", player)) diff --git a/worlds/marioland2/options.py b/worlds/marioland2/options.py new file mode 100644 index 000000000000..cad4d60cf2ce --- /dev/null +++ b/worlds/marioland2/options.py @@ -0,0 +1,198 @@ +from Options import Toggle, Choice, NamedRange, Range, PerGameCommonOptions, ItemsAccessibility +from dataclasses import dataclass + + +class ShuffleGoldenCoins(Choice): + """ + Vanilla: Golden Coins are received when defeating bosses. + Shuffle: Shuffle the Golden Coins into the item pool and make bosses location checks. + Mario Coin Fragment Hunt: You start with all Golden Coins except the Mario Coin, which has been fragmented into many pieces. + You will see a Golden Coin being received when defeating bosses regardless of whether you are actually getting a coin. + """ + display_name = "Shuffle Golden Coins" + default = 0 + option_vanilla = 0 + option_shuffle = 1 + option_mario_coin_fragment_hunt = 2 + + +class GoldenCoinsRequired(Range): + """ + Number of Golden Coins required to enter Mario's Castle. Ignored on Mario Coin Fragment Hunt. + """ + display_name = "Golden Coins Required" + range_start = 0 + range_end = 6 + default = 6 + + +class MarioCoinFragmentPercentage(Range): + """ + Percentage of filler items to be replaced with Mario Coin Fragments. Note that the Coinsanity and Coinsanity + Checks options will greatly impact the number of replaceable filler items. There may be as few as 6 available + slots for Mario Coin Fragments if Coinsanity is off. + """ + display_name = "Mario Coin Fragment Percentage" + range_start = 1 + range_end = 100 + default = 20 + + +class MarioCoinFragmentsRequiredPercentage(Range): + """ + Percentage of the Mario Coins in the item pool that are required to put the Mario Coin together. + """ + display_name = "Mario Coin Fragments Required Percentage" + range_start = 1 + range_end = 100 + default = 75 + + +class ShuffleMidwayBells(Toggle): + """ + Shuffle the Midway Bells into the item pool. Ringing a bell will trigger a location check. + Obtaining a Midway Bell will be permanent, and some levels will require backtracking from the midway point to reach + secret exits. + """ + display_name = "Shuffle Midway Bells" + + +class MariosCastleMidwayBell(Toggle): + """ + Adds a Midway Bell to the final stage, just before the Wario fight. + """ + display_name = "Mario's Castle Midway Bell" + + +class Coinsanity(Toggle): + """ + Shuffles the singular coins found freestanding and in question mark blocks into the item pool, and adds location + checks made by obtaining a sufficient number of coins in particular levels within a single playthrough. + """ + default_name = "Coinsanity" + + +class CoinsanityChecks(Range): + """ + Number of Coinsanity checks. + A higher number means more checks, and smaller coin amounts per coin item in the item pool. + If Accessibility is set to Full, auto-scroll levels may have a lower maximum count, which may lead to this + value being limited. + """ + default_name = "Coinsanity Checks" + range_start = 31 + range_end = 2599 + default = 150 + + +class DifficultyMode(Choice): + """ + Play in normal or easy mode. You can also start in Normal Mode with an "upgrade" to Easy Mode in the item pool, + or start in Easy Mode with a Normal Mode "trap" in the item pool. + """ + display_name = "Difficulty Mode" + option_normal = 0 + option_easy = 1 + option_normal_to_easy = 2 + option_easy_to_normal = 3 + default = 0 + + +class ShufflePipeTraversal(Choice): + """ + Single: Shuffle a Pipe Traversal item into the item pool, which is required to enter any pipes. + Split: Shuffle 4 Pipe Traversal items, one required for entering pipes from each direction. + Note that being unable to enter pipes is very limiting and affects nearly half of all levels. + """ + display_name = "Shuffle Pipe Traversal" + option_off = 0 + option_single = 1 + option_split = 2 + default = 0 + + +class RandomizeEnemies(Toggle): + """ + Randomize enemies throughout levels. + """ + display_name = "Randomize Enemies" + + +class RandomizePlatforms(Toggle): + """ + Randomize platforms throughout levels. + """ + display_name = "Randomize Platforms" + + +class AutoScrollChances(NamedRange): + """ + Chance per eligible level to be made into an auto scroll level. Can also set to Vanilla to leave them unchanged. + """ + display_name = "Auto Scroll Chance" + range_start = 0 + range_end = 100 + special_range_names = {"vanilla": -1, "none": 0, "all": 100} + default = -1 + + +class AutoScrollMode(Choice): + """ + Always: Any auto scroll levels will always auto-scroll. + Global Trap Item: Auto scroll levels will only auto-scroll after obtaining the Auto Scroll trap item. + Level Trap Items: As with Trap Item, but there is a separate trap item for each auto scroll level. + Global Cancel Item: Auto Scroll levels will stop auto-scrolling after obtaining the Auto Scroll Cancel item. + Level Cancel Items: As with Cancel Item, but there is a separate cancel item for each auto scroll level. + Chaos: Each level will randomly always auto scroll, have an Auto Scroll Trap, or have an Auto Scroll Cancel item. + The effects of Trap and Cancel items are permanent! If Accessibility is not set to Full, + Traps may cause locations to become permanently unreachable. + With individual level items, the number of auto scroll levels may be limited by the available space in the item + pool. + """ + display_name = "Auto Scroll Mode" + option_always = 0 + option_global_trap_item = 1 + option_level_trap_items = 2 + option_global_cancel_item = 3 + option_level_cancel_items = 4 + option_chaos = 5 + default = 0 + + +class RandomizeMusic(Toggle): + """ + Randomize the music that plays in levels and overworld areas. + """ + display_name = "Randomize Music" + + +class EnergyLink(Toggle): + """ + All extra lives beyond 1 are transferred into the server's shared EnergyLink storage. If you drop to 0, + 1 will be replenished if there is sufficient energy stored. + """ + display_name = "Energy Link" + default = 1 + + + + +@dataclass +class SML2Options(PerGameCommonOptions): + accessibility: ItemsAccessibility + shuffle_golden_coins: ShuffleGoldenCoins + required_golden_coins: GoldenCoinsRequired + mario_coin_fragment_percentage: MarioCoinFragmentPercentage + mario_coin_fragments_required_percentage: MarioCoinFragmentsRequiredPercentage + coinsanity: Coinsanity + coinsanity_checks: CoinsanityChecks + shuffle_midway_bells: ShuffleMidwayBells + marios_castle_midway_bell: MariosCastleMidwayBell + shuffle_pipe_traversal: ShufflePipeTraversal + auto_scroll_mode: AutoScrollMode + auto_scroll_chances: AutoScrollChances + difficulty_mode: DifficultyMode + randomize_enemies: RandomizeEnemies + randomize_platforms: RandomizePlatforms + randomize_music: RandomizeMusic + energy_link: EnergyLink diff --git a/worlds/marioland2/rom.py b/worlds/marioland2/rom.py new file mode 100644 index 000000000000..2a19a9cb8cad --- /dev/null +++ b/worlds/marioland2/rom.py @@ -0,0 +1,146 @@ +import hashlib +import os +import pkgutil + +import Utils + +from worlds.Files import APProcedurePatch, APTokenMixin, APTokenTypes +from settings import get_settings + +from .rom_addresses import rom_addresses +from .sprites import sprite_name_to_id + + +def randomize_music(patch, random): + # overworld + overworld_music_tracks = [0x05, 0x06, 0x0D, 0x0E, 0x10, 0x12, 0x1B, 0x1C, 0x1E] + random.shuffle(overworld_music_tracks) + for i, track in zip([0x3004F, 0x3EA9B, 0x3D186, 0x3D52B, 0x3D401, 0x3D297, 0x3D840, 0x3D694, 0x3D758], + overworld_music_tracks): + patch.write_bytes(i, track) + # levels + for i in range(0x5619, 0x5899, 0x14): + patch.write_bytes(i, random.choice([0x01, 0x0B, 0x11, 0x13, 0x14, 0x17, 0x1D, 0x1F, 0x28])) + + +def generate_output(self, output_directory: str): + + patch = SuperMarioLand2ProcedurePatch(player=self.player, player_name=self.player_name) + + patch.write_file("basepatch.bsdiff4", pkgutil.get_data(__name__, "basepatch.bsdiff4")) + random = self.random + + if self.options.marios_castle_midway_bell: + # Remove Question Mark Block + patch.write_bytes(0x4F012, 0x5D) + # Fix level pointer to read midway bell flag + patch.write_bytes(0x3E569, 0x18) + patch.write_bytes(0x3E56A, 0x18) + # Position and screen coordinates + patch.write_bytes(0x383B, [0xD4, 0x01, 0x4D, 0x0A, 0xC0, 0x01, 0x50, 0x0A]) + + if self.options.coinsanity: + # Add platform to return to start of Pumpkin Zone Secret Course 1 + patch.write_bytes(0x258B6, 0x3B) + patch.write_bytes(0x258F8, 0x7a) + patch.write_bytes(0x2594D, 0x67) + patch.write_bytes(0x259A8, 0x68) + patch.write_bytes(0x259A9, 0x60) + + i = 0xe077 + for level, sprites in self.sprite_data.items(): + for sprite_data in sprites: + sprite_id = sprite_name_to_id[sprite_data["sprite"]] + data = [((sprite_id & 0b01000000) >> 2) | ((sprite_id & 0b00111000) << 2) | sprite_data["screen"], + ((sprite_id & 0b00000111) << 5) | sprite_data["x"], + sprite_data["misc"] | sprite_data["y"]] + patch.write_bytes(i, data) + i += 3 + patch.write_bytes(i, 255) + i += 1 + + if self.options.randomize_music: + randomize_music(patch, random) + + if self.options.shuffle_golden_coins: + patch.write_bytes(rom_addresses["Coin_Shuffle"], 0x40) + if self.options.shuffle_midway_bells: + patch.write_bytes(rom_addresses["Disable_Midway_Bell"], 0xC9) + + if self.options.coinsanity: + for section in ("A", "B"): + for i in range(0, 30): + patch.write_bytes(rom_addresses[f"Coinsanity_{section}"] + i, 0x00) + + star_count = max(len([loc for loc in self.multiworld.get_filled_locations() if loc.item.player == self.player + and loc.item.name == "Super Star Duration Increase"]), 1) + patch.write_bytes(rom_addresses["Star_Count"], star_count // 256) + patch.write_bytes(rom_addresses["Star_Count"] + 1, star_count - (star_count // 256)) + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + patch.write_bytes(rom_addresses["Coins_Required"], self.coin_fragments_required // 256) + patch.write_bytes(rom_addresses["Coins_Required"] + 1, self.coin_fragments_required % 256) + patch.write_bytes(rom_addresses["Required_Golden_Coins"], 6) + else: + patch.write_bytes(rom_addresses["Coins_Required"] + 1, self.options.required_golden_coins.value) + patch.write_bytes(rom_addresses["Required_Golden_Coins"], self.options.required_golden_coins.value) + patch.write_bytes(rom_addresses["Midway_Bells"], self.options.shuffle_midway_bells.value) + patch.write_bytes(rom_addresses["Energy_Link"], self.options.energy_link.value) + patch.write_bytes(rom_addresses["Difficulty_Mode"], self.options.difficulty_mode.value) + patch.write_bytes(rom_addresses["Coin_Mode"], self.options.shuffle_golden_coins.value) + + for level, i in enumerate(self.auto_scroll_levels): + # We set 0 if no auto scroll or auto scroll trap, so it defaults to no auto scroll. 1 if always or cancel items. + patch.write_bytes(rom_addresses["Auto_Scroll_Levels"] + level, max(0, i - 1)) + patch.write_bytes(rom_addresses["Auto_Scroll_Levels_B"] + level, i) + + if self.options.energy_link: + # start with 1 life if Energy Link is on so that you don't deposit lives at the start of the game. + patch.write_bytes(rom_addresses["Starting_Lives"], 1) + + rom_name = bytearray(f'AP{Utils.__version__.replace(".", "")[0:3]}_{self.player}_{self.multiworld.seed:11}\0', + 'utf8')[:21] + rom_name.extend([0] * (21 - len(rom_name))) + patch.write_bytes(0x77777, rom_name) + patch.write_file("tokens.bin", patch.get_token_binary()) + patch.write(os.path.join(output_directory, + f"{self.multiworld.get_out_file_name_base(self.player)}{patch.patch_file_ending}")) + + +class SuperMarioLand2ProcedurePatch(APProcedurePatch, APTokenMixin): + hash = "a8413347d5df8c9d14f97f0330d67bce" + patch_file_ending = ".apsml2" + game = "Super Mario Land 2" + result_file_ending = ".gb" + procedure = [ + ("apply_bsdiff4", ["basepatch.bsdiff4"]), + ("apply_tokens", ["tokens.bin"]), + ] + + @classmethod + def get_source_data(cls) -> bytes: + return get_base_rom_bytes() + + def write_bytes(self, offset, value): + if isinstance(value, int): + value = [value] + self.write_token(APTokenTypes.WRITE, offset, bytes(value)) + + +def get_base_rom_bytes(): + file_name = get_base_rom_path() + with open(file_name, "rb") as file: + base_rom_bytes = bytes(file.read()) + + basemd5 = hashlib.md5() + basemd5.update(base_rom_bytes) + if SuperMarioLand2ProcedurePatch.hash != basemd5.hexdigest(): + raise Exception("Supplied Base Rom does not match known MD5 for Super Mario Land 1.0. " + "Get the correct game and version, then dump it") + return base_rom_bytes + + +def get_base_rom_path(): + file_name = get_settings()["sml2_options"]["rom_file"] + if not os.path.exists(file_name): + file_name = Utils.user_path(file_name) + return file_name \ No newline at end of file diff --git a/worlds/marioland2/rom_addresses.py b/worlds/marioland2/rom_addresses.py new file mode 100644 index 000000000000..e4b4f69cd71e --- /dev/null +++ b/worlds/marioland2/rom_addresses.py @@ -0,0 +1,39 @@ +rom_addresses = { + "Space_Physics": 0x4e7, + "Pipe_Traversal_A": 0x11a4, + "Pipe_Traversal_SFX_A": 0x11a9, + "Pipe_Traversal_B": 0x11d6, + "Pipe_Traversal_SFX_B": 0x11e7, + "Pipe_Traversal_C": 0x1226, + "Pipe_Traversal_SFX_C": 0x123f, + "Pipe_Traversal_D": 0x1256, + "Pipe_Traversal_SFX_D": 0x125b, + "Enable_Swim": 0x1d17, + "Coinsanity_B": 0x1d86, + "Auto_Scroll_Levels": 0x1f71, + "Starting_Lives": 0x2920, + "Get_Hurt_To_Big_Mario": 0x31c7, + "Get_Mushroom_A": 0x345c, + "Get_Fire_Flower_A": 0x346d, + "Get_Carrot_A": 0x347e, + "Invincibility_Star_A": 0x349e, + "Invincibility_Star_B": 0x34a3, + "Enable_Bubble": 0x34e5, + "Coinsanity_A": 0x591f, + "Coin_Shuffle": 0x304ce, + "Required_Golden_Coins": 0x306e9, + "Disable_Midway_Bell": 0x3ef1e, + "Get_Carrot_C": 0x6092f, + "Get_Mushroom_C": 0x60930, + "Get_Fire_Flower_C": 0x60933, + "Get_Mushroom_B": 0x60ddb, + "Get_Carrot_B": 0x60de7, + "Get_Fire_Flower_B": 0x60df3, + "Coins_Required": 0x80139, + "Difficulty_Mode": 0x8013b, + "Star_Count": 0x8013c, + "Midway_Bells": 0x8013e, + "Energy_Link": 0x8013f, + "Coin_Mode": 0x80140, + "Auto_Scroll_Levels_B": 0x80141, +} diff --git a/worlds/marioland2/sprite_randomizer.py b/worlds/marioland2/sprite_randomizer.py new file mode 100644 index 000000000000..8440da2b37f6 --- /dev/null +++ b/worlds/marioland2/sprite_randomizer.py @@ -0,0 +1,131 @@ +# Based on SML2R enemy and platform randomizer +# # https://github.com/slashinfty/sml2r-node/blob/862128c73d336d6cbfbf6290c09f3eff103688e8/src/index.ts#L284 + +def randomize_enemies(sprite_data, random): + for level, level_sprite_data in sprite_data.items(): + shuffle = () + if level in ("Mushroom Zone", "Macro Zone 4"): + shuffle = ("Koopa Troopa", "Goomba", "Paragoomba (Vertical)", "Paragoomba (Diagonal)") + elif level in ("Scenic Course", "Pumpkin Zone Secret Course 1"): + shuffle = ("Goomba", "Paragoomba (Vertical)", "Paragoomba (Diagonal)") + elif level == "Tree Zone 1": + shuffle = ("Money Bag/Bopping Toady", "Ragumo/Aqua Kuribo", "Pencil/Spikey", "Kyotonbo") + elif level == "Tree Zone 2": + shuffle = ("Noko Bombette/Bear", "No 48/Mogyo") + elif level == "Tree Zone 3": + shuffle = ("Battle Beetle", "Be", "Ant") + elif level == "Tree Zone 5": + shuffle = ("Paragoomba (Diagonal)", "Dondon", "Paragoomba (Vertical)") + elif level == "Pumpkin Zone 2": + shuffle = ("Boo/Bomubomu", "Kyororo", "Honebon/F Boy", "Karakara", "Star (Vertical)/Blurp (Horizontal)", + "Star (Horizontal)/Blurp (Vertical)") + elif level == "Pumpkin Zone 3": + shuffle = ("Boo/Bomubomu", "Unibo/Terekuribo") + elif level == "Mario Zone 1": + shuffle = ("Koopa Troopa", "Neiji/Buichi", "Tatenoko") + elif level == "Mario Zone 2": + shuffle = ("Paragoomba (Diagonal)", "Goomba", "Paragoomba (Vertical)", "Noko Bombette/Bear", + "Boo/Bomubomu") + elif level == "Turtle Zone 1": + shuffle = ("Horizontal Blurp", "Shark", "Cheep Cheep (Vertical)", "Paragoomba (Diagonal)", "Goomba", + "Spiny Cheep Cheep", "Paragoomba (Vertical)", + "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)") + elif level == "Hippo Zone": + shuffle = ("Horizontal Blurp", "Dondon", "Unibo/Terekuribo", "Toriuo") + elif level == "Space Zone 2": + shuffle = ("Tosenbo/Pikku", "Star (Vertical)/Blurp (Horizontal)", "Star (Horizontal)/Blurp (Vertical)") + elif level == "Macro Zone 1": + shuffle = ("Kyotonbo", "Goronto", "Dokanto", "Chikunto") + elif level == "Macro Zone 2": + shuffle = ("Cheep Cheep (Vertical)", "Battle Beetle", "Be", + "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "Ant") + elif level == "Macro Zone 3": + shuffle = ("Koopa Troopa", "Paragoomba (Diagonal)", "Goomba", "Be", "Paragoomba (Vertical)", + "Honebon/F Boy") + elif level == "Pumpkin Zone Secret Course 2": + shuffle = ("Koopa Troopa", "Goomba") + for sprite in level_sprite_data: + if level == "Pumpkin Zone 1": + if sprite["sprite"] == "Falling Spike": + shuffle = ("Boo/Bomubomu", "Falling Spike", "Kurokyura/Jack-in-the-Box", "Masked Ghoul/Bullet Bill") + elif sprite["sprite"] == "Falling Spike on Chain": + shuffle = ("Boo/Bomubomu", "Falling Spike on Chain", "Kurokyura/Jack-in-the-Box", + "Masked Ghoul/Bullet Bill") + else: + shuffle = ("Boo/Bomubomu", "Kurokyura/Jack-in-the-Box", "Masked Ghoul/Bullet Bill") + elif level == "Pumpkin Zone 4": + if sprite["sprite"] == "Falling Spike on Chain": + shuffle = ("Boo/Bomubomu", "Falling Spike on Chain", "Masked Ghoul/Bullet Bill", "Rerere/Poro", + "Tosenbo/Pikku") + else: + shuffle = ("Boo/Bomubomu", "Masked Ghoul/Bullet Bill", "Rerere/Poro", "Tosenbo/Pikku") + elif level == "Mario Zone 3": + if sprite["sprite"] == "Claw Grabber": + shuffle = ("Koopa Troopa", "Diagonal Ball on Chain", "Kiddokatto", "Claw Grabber", + "Masked Ghoul/Bullet Bill") + elif sprite["sprite"] in ("Koopa Troopa", "Diagonal Ball on Chain", "Kiddokatto"): + shuffle = ("Koopa Troopa", "Diagonal Ball on Chain", "Kiddokatto", "Masked Ghoul/Bullet Bill") + else: + shuffle = () + elif level == "Mario Zone 4": + if sprite["sprite"] == "Spinning Spike/Tamara": + shuffle = ("Goomba", "Spinning Spike/Tamara", "Boo/Bomubomu", "Masked Ghoul/Bullet Bill") + elif sprite["sprite"] == "Moving Saw (Floor)": + shuffle = ("Goomba", "Moving Saw (Floor)", "Boo/Bomubomu", "Masked Ghoul/Bullet Bill") + else: + shuffle = ("Goomba", "Boo/Bomubomu", "Masked Ghoul/Bullet Bill") + elif level == "Turtle Zone 3": + if sprite["sprite"] == "Pencil/Spikey": + shuffle = ("Koopa Troopa", "Paragoomba (Diagonal)", "Ragumo/Aqua Kuribo", "Pencil/Spikey", + "Paragoomba (Vertical)", "Honebon/F Boy") + else: + shuffle = ("Koopa Troopa", "Paragoomba (Diagonal)", "Ragumo/Aqua Kuribo", + "Paragoomba (Vertical)", "Honebon/F Boy") + elif level == "Space Zone 1": + if sprite["sprite"] == "Boo/Bomubomu": + shuffle = ("Boo/Bomubomu", "No 48/Mogyo") + else: + shuffle = ("Boo/Bomubomu", "No 48/Mogyo", "Rerere/Poro") + elif level == "Mario's Castle": + if sprite["sprite"] in ("Fire Pakkun Zo (Large)", "Fire Pakkun Zo (Left)"): + shuffle = ("Fire Pakkun Zo (Large)", "Fire Pakkun Zo (Left)") + else: + shuffle = ("Spike Ball (Large)", "Spike Ball (Small)") + elif level == "Tree Zone 4": + # Deviation from SML2R: No Buichis placed into non-Buichi locations, as they can place under the + # underground question mark blocks. Potentially could make a list of which ones are allowed to become + # Buichis? + if sprite["sprite"] in ("Runaway Heart Block/Bibi", "Piranha Plant (Downward)/Grubby", + "Spinning Platform (Horizontal)/Skeleton Bee", + "Spinning Spike (Horizontal)/Unera"): + shuffle = ("Runaway Heart Block/Bibi", "Piranha Plant (Downward)/Grubby", + "Spinning Platform (Horizontal)/Skeleton Bee", "Spinning Spike (Horizontal)/Unera") + elif sprite["sprite"] == "Neiji/Buichi": + shuffle = ("Runaway Heart Block/Bibi", "Neiji/Buichi", "Piranha Plant (Downward)/Grubby", + "Spinning Platform (Horizontal)/Skeleton Bee", "Spinning Spike (Horizontal)/Unera") + else: + shuffle = () + if sprite["sprite"] in ("Piranha Plant", "Fire Piranha Plant"): + if level not in ("Pumpkin Zone 2", "Pumpkin Zone 4", "Macro Zone 3"): + shuffle = ("Piranha Plant", "Fire Piranha Plant") + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) + elif level == "Mario's Castle" and sprite["sprite"] == "Karamenbo" and not random.randint(0, 9): + sprite["y"] += 1 + + +def randomize_platforms(sprite_data, random): + shuffle = ("Moving Platform (Small, Vertical)", "Moving Platform (Large, Vertical)", + "Moving Platform (Small, Horizontal)", "Moving Platform (Large, Horizontal)", + "Moving Platform (Large, Diagonal)", "Falling Platform") + for sprite in sprite_data["Tree Zone 3"]: + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) + shuffle = ("Cloud Platform (Horizontal)", "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)") + for sprite in sprite_data["Tree Zone 5"]: + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) + shuffle = ("Falling Bone Platform", "Rising Bone Platform", "Skull Platform") + for sprite in sprite_data["Mario's Castle"]: + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) diff --git a/worlds/marioland2/sprites.py b/worlds/marioland2/sprites.py new file mode 100644 index 000000000000..33a14731295e --- /dev/null +++ b/worlds/marioland2/sprites.py @@ -0,0 +1,1016 @@ +sprite_name_to_id = { + "Ant": 93, "Ragumo/Aqua Kuribo": 32, "Battle Beetle": 51, "Be": 52, "Noko Bombette/Bear": 68, + "Runaway Heart Block/Bibi": 53, "Star (Vertical)/Blurp (Horizontal)": 94, + "Star (Horizontal)/Blurp (Vertical)": 95, "Boo/Bomubomu": 77, + "Money Bag/Bopping Toady": 31, "Neiji/Buichi": 64, "Masked Ghoul/Bullet Bill": 83, + "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)": 61, "Cheep Cheep (Vertical)": 7, + "Chikunto": 39, "Dokanto": 37, "Dondon": 57, "Honebon/F Boy": 85, "Fire Pakkun Zo (Large)": 104, + "Fire Pakkun Zo (Left)": 105, "Fire Pakkun Zo (Right)": 106, "Fire Piranha Plant": 13, "Floating Face": 100, + "Genkottsu (1.5 Tiles)": 99, "Genkottsu (2 Tiles)": 98, "Goomba": 9, "Goronto": 35, + "Piranha Plant (Downward)/Grubby": 66, "Kurokyura/Jack-in-the-Box": 81, + "Karakara": 86, "Karamenbo": 102, "Kiddokatto": 72, "Koopa Troopa": 1, "Kyororo": 84, "Kyotonbo": 34, + "No 48/Mogyo": 88, "Paragoomba (Diagonal)": 8, "Paragoomba (Vertical)": 58, "Tosenbo/Pikku": 92, + "Piranha Plant": 12, "Rerere/Poro": 90, "Shark": 6, + "Spinning Platform (Horizontal)/Skeleton Bee": 62, "Pencil/Spikey": 33, + "Spiny Cheep Cheep": 11, "Spinning Spike/Tamara": 67, "Tatenoko": 75, "Unibo/Terekuribo": 87, + "Toriuo": 91, "Spinning Spike (Horizontal)/Unera": 65, "Claw Grabber": 73, + "Diagonal Ball on Chain": 71, "Falling Spike": 78, "Falling Spike on Chain": 79, "Spinning Spike (Vertical)": 80, + "Spike Ball (Large)": 110, "Spike Ball (Small)": 111, "Moving Saw (Ceiling)": 74, "Moving Saw (Floor)": 76, + "Moving Platform (Small, Vertical)": 40, "Moving Platform (Large, Vertical)": 41, + "Moving Platform (Small, Horizontal)": 42, "Moving Platform (Large, Horizontal)": 43, + "Moving Platform (Large, Diagonal)": 45, "Falling Platform": 46, "Rising Platform": 47, + "Rotating Platform (Small)": 48, "Owl Platform (Vertical)": 55, "Cloud Platform (Horizontal)": 56, + "Spinning Platform (Vertical)": 63, "Falling Bone Platform": 96, "Rising Bone Platform": 97, "Skull Platform": 103, + "Propeller Platform": 107, "Heart": 15, "Mushroom": 27, "Flower": 28, "Carrot": 29, "Star": 30, + "Mushroom Block": 17, "Flower Block": 18, "Carrot Block": 19, "Star Block": 20, "Heart Block": 21, + "Money Bag Block": 25, "Bubble": 24, "Midway Bell": 23, "Bonus Bell": 22, "Horizontal Blurp": 5, + "Big Diagonal Moving Platform": 44} + +sprite_id_to_name = {a: b for b, a in sprite_name_to_id.items()} + +level_sprites = { + "Mushroom Zone": [ + {"screen": 1, "sprite": "Goomba", "x": 27, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 9, "y": 24, "misc": 32}, + {"screen": 2, "sprite": "Mushroom Block", "x": 21, "y": 23, "misc": 32}, + {"screen": 4, "sprite": "Goomba", "x": 7, "y": 26, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 11, "y": 18, "misc": 32}, + {"screen": 6, "sprite": "Paragoomba (Diagonal)", "x": 19, "y": 22, "misc": 160}, + {"screen": 8, "sprite": "Piranha Plant", "x": 6, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Piranha Plant", "x": 22, "y": 30, "misc": 160}, + {"screen": 9, "sprite": "Heart Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 9, "sprite": "Star Block", "x": 17, "y": 23, "misc": 32}, + {"screen": 10, "sprite": "Goomba", "x": 5, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Goomba", "x": 17, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Midway Bell", "x": 29, "y": 20, "misc": 32}, + {"screen": 11, "sprite": "Goomba", "x": 1, "y": 30, "misc": 32}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 13, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 20, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Flower Block", "x": 25, "y": 23, "misc": 32}, + {"screen": 12, "sprite": "Heart", "x": 15, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Goomba", "x": 3, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Piranha Plant", "x": 16, "y": 30, "misc": 32}, + {"screen": 14, "sprite": "Goomba", "x": 11, "y": 22, "misc": 32}, + {"screen": 14, "sprite": "Koopa Troopa", "x": 20, "y": 22, "misc": 160}, + {"screen": 15, "sprite": "Bonus Bell", "x": 21, "y": 13, "misc": 32}], + "Tree Zone 1": [ + {"screen": 1, "sprite": "Star Block", "x": 17, "y": 21, "misc": 32}, + {"screen": 2, "sprite": "Ragumo/Aqua Kuribo", "x": 5, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Heart", "x": 19, "y": 30, "misc": 0}, + {"screen": 2, "sprite": "Ragumo/Aqua Kuribo", "x": 23, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Money Bag/Bopping Toady", "x": 1, "y": 30, "misc": 160}, + {"screen": 3, "sprite": "Money Bag/Bopping Toady", "x": 20, "y": 24, "misc": 160}, + {"screen": 4, "sprite": "Money Bag/Bopping Toady", "x": 9, "y": 24, "misc": 32}, + {"screen": 4, "sprite": "Heart", "x": 13, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Money Bag/Bopping Toady", "x": 31, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Pencil/Spikey", "x": 3, "y": 24, "misc": 160}, + {"screen": 5, "sprite": "Kyotonbo", "x": 21, "y": 22, "misc": 160}, + {"screen": 6, "sprite": "Money Bag/Bopping Toady", "x": 11, "y": 24, "misc": 160}, + {"screen": 6, "sprite": "Money Bag/Bopping Toady", "x": 23, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Pencil/Spikey", "x": 28, "y": 24, "misc": 160}, + {"screen": 7, "sprite": "Heart Block", "x": 29, "y": 5, "misc": 32}, + {"screen": 8, "sprite": "Midway Bell", "x": 13, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Money Bag/Bopping Toady", "x": 29, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Ragumo/Aqua Kuribo", "x": 10, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Kyotonbo", "x": 15, "y": 10, "misc": 160}, + {"screen": 9, "sprite": "Mushroom Block", "x": 17, "y": 23, "misc": 32}, + {"screen": 10, "sprite": "Kyotonbo", "x": 3, "y": 10, "misc": 160}, + {"screen": 10, "sprite": "Pencil/Spikey", "x": 19, "y": 24, "misc": 160}, + {"screen": 10, "sprite": "Star Block", "x": 25, "y": 21, "misc": 32}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 7, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 27, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 31, "y": 24, "misc": 32}, + {"screen": 12, "sprite": "Money Bag/Bopping Toady", "x": 15, "y": 24, "misc": 32}, + {"screen": 13, "sprite": "Ragumo/Aqua Kuribo", "x": 3, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Money Bag/Bopping Toady", "x": 23, "y": 24, "misc": 32}, + {"screen": 14, "sprite": "Money Bag/Bopping Toady", "x": 15, "y": 30, "misc": 160}, + {"screen": 14, "sprite": "Kyotonbo", "x": 31, "y": 24, "misc": 160}, + {"screen": 15, "sprite": "Bonus Bell", "x": 19, "y": 13, "misc": 32}, + {"screen": 15, "sprite": "Heart Block", "x": 25, "y": 15, "misc": 32}], + "Tree Zone 2": [ + {"screen": 2, "sprite": "No 48/Mogyo", "x": 9, "y": 30, "misc": 0}, + {"screen": 2, "sprite": "Mushroom Block", "x": 23, "y": 19, "misc": 0}, + {"screen": 2, "sprite": "No 48/Mogyo", "x": 27, "y": 30, "misc": 0}, + {"screen": 3, "sprite": "Mushroom Block", "x": 7, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "No 48/Mogyo", "x": 15, "y": 28, "misc": 160}, + {"screen": 3, "sprite": "Heart Block", "x": 27, "y": 17, "misc": 0}, + {"screen": 4, "sprite": "No 48/Mogyo", "x": 3, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "No 48/Mogyo", "x": 17, "y": 28, "misc": 160}, + {"screen": 5, "sprite": "Noko Bombette/Bear", "x": 1, "y": 30, "misc": 128}, + {"screen": 5, "sprite": "No 48/Mogyo", "x": 7, "y": 28, "misc": 32}, + {"screen": 6, "sprite": "Falling Platform", "x": 22, "y": 22, "misc": 0}, + {"screen": 7, "sprite": "Midway Bell", "x": 3, "y": 14, "misc": 0}, + {"screen": 7, "sprite": "No 48/Mogyo", "x": 15, "y": 30, "misc": 0}, + {"screen": 7, "sprite": "No 48/Mogyo", "x": 17, "y": 8, "misc": 32}, + {"screen": 7, "sprite": "Money Bag Block", "x": 19, "y": 19, "misc": 32}, + {"screen": 7, "sprite": "No 48/Mogyo", "x": 19, "y": 0, "misc": 32}, + {"screen": 8, "sprite": "Mushroom Block", "x": 5, "y": 13, "misc": 0}, + {"screen": 8, "sprite": "Noko Bombette/Bear", "x": 11, "y": 24, "misc": 0}, + {"screen": 8, "sprite": "Carrot Block", "x": 17, "y": 21, "misc": 64}, + {"screen": 9, "sprite": "Noko Bombette/Bear", "x": 3, "y": 30, "misc": 64}, + {"screen": 9, "sprite": "Noko Bombette/Bear", "x": 23, "y": 30, "misc": 64}, + {"screen": 10, "sprite": "Noko Bombette/Bear", "x": 11, "y": 30, "misc": 64}, + {"screen": 10, "sprite": "Noko Bombette/Bear", "x": 31, "y": 30, "misc": 64}, + {"screen": 11, "sprite": "Money Bag Block", "x": 5, "y": 19, "misc": 0}, + {"screen": 11, "sprite": "Mushroom Block", "x": 13, "y": 5, "misc": 0}, + {"screen": 11, "sprite": "Heart", "x": 19, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 3, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 5, "y": 16, "misc": 0}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 13, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Heart", "x": 27, "y": 8, "misc": 32}, + {"screen": 14, "sprite": "Bonus Bell", "x": 21, "y": 15, "misc": 32}], + "Tree Zone 4": [ + {"screen": 1, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 11, "y": 26, "misc": 160}, + {"screen": 1, "sprite": "Runaway Heart Block/Bibi", "x": 20, "y": 24, "misc": 0}, + {"screen": 1, "sprite": "Flower Block", "x": 25, "y": 21, "misc": 32}, + {"screen": 2, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 16, "y": 24, "misc": 128}, + {"screen": 3, "sprite": "Neiji/Buichi", "x": 18, "y": 18, "misc": 0}, + {"screen": 3, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 28, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Neiji/Buichi", "x": 4, "y": 18, "misc": 0}, + {"screen": 4, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 12, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Neiji/Buichi", "x": 22, "y": 18, "misc": 0}, + {"screen": 4, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 28, "y": 30, "misc": 0}, + {"screen": 5, "sprite": "Neiji/Buichi", "x": 8, "y": 18, "misc": 128}, + {"screen": 6, "sprite": "Runaway Heart Block/Bibi", "x": 12, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 13, "y": 12, "misc": 160}, + {"screen": 6, "sprite": "Mushroom Block", "x": 19, "y": 17, "misc": 32}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 23, "y": 28, "misc": 128}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 25, "y": 18, "misc": 160}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 31, "y": 24, "misc": 160}, + {"screen": 7, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 2, "y": 24, "misc": 0}, + {"screen": 7, "sprite": "Runaway Heart Block/Bibi", "x": 28, "y": 24, "misc": 128}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 1, "y": 12, "misc": 32}, + {"screen": 8, "sprite": "Piranha Plant (Downward)/Grubby", "x": 5, "y": 28, "misc": 0}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 5, "y": 18, "misc": 32}, + {"screen": 8, "sprite": "Runaway Heart Block/Bibi", "x": 14, "y": 24, "misc": 0}, + {"screen": 8, "sprite": "Star Block", "x": 17, "y": 11, "misc": 32}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 19, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Star Block", "x": 17, "y": 19, "misc": 0}, + {"screen": 9, "sprite": "Piranha Plant (Downward)/Grubby", "x": 21, "y": 20, "misc": 0}, + {"screen": 9, "sprite": "Spinning Spike/Tamara", "x": 23, "y": 27, "misc": 0}, + {"screen": 10, "sprite": "Midway Bell", "x": 0, "y": 18, "misc": 0}, + {"screen": 10, "sprite": "Spinning Spike/Tamara", "x": 5, "y": 27, "misc": 0}, + {"screen": 10, "sprite": "Piranha Plant (Downward)/Grubby", "x": 11, "y": 20, "misc": 0}, + {"screen": 10, "sprite": "Spinning Spike/Tamara", "x": 17, "y": 27, "misc": 0}, + {"screen": 10, "sprite": "Mushroom Block", "x": 23, "y": 19, "misc": 0}, + {"screen": 12, "sprite": "Runaway Heart Block/Bibi", "x": 2, "y": 24, "misc": 32}, + {"screen": 12, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 28, "y": 24, "misc": 32}, + {"screen": 13, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 32}], + "Tree Zone 3": [ + {"screen": 0, "sprite": "Moving Platform (Large, Vertical)", "x": 19, "y": 10, "misc": 32}, + {"screen": 0, "sprite": "Carrot Block", "x": 25, "y": 25, "misc": 0}, + {"screen": 0, "sprite": "Ant", "x": 28, "y": 18, "misc": 32}, + {"screen": 1, "sprite": "Ant", "x": 0, "y": 22, "misc": 64}, + {"screen": 1, "sprite": "Battle Beetle", "x": 10, "y": 24, "misc": 64}, + {"screen": 1, "sprite": "Moving Platform (Large, Diagonal)", "x": 11, "y": 22, "misc": 32}, + {"screen": 1, "sprite": "Fire Piranha Plant", "x": 18, "y": 20, "misc": 128}, + {"screen": 1, "sprite": "Cheep Cheep (Vertical)", "x": 18, "y": 21, "misc": 0}, + {"screen": 1, "sprite": "Mushroom Block", "x": 21, "y": 15, "misc": 64}, + {"screen": 1, "sprite": "Heart Block", "x": 21, "y": 7, "misc": 64}, + {"screen": 1, "sprite": "Be", "x": 30, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Piranha Plant", "x": 4, "y": 24, "misc": 192}, + {"screen": 2, "sprite": "Be", "x": 14, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Fire Piranha Plant", "x": 20, "y": 24, "misc": 192}, + {"screen": 2, "sprite": "Falling Platform", "x": 24, "y": 27, "misc": 0}, + {"screen": 2, "sprite": "Heart Block", "x": 25, "y": 19, "misc": 0}, + {"screen": 3, "sprite": "Falling Platform", "x": 0, "y": 25, "misc": 0}, + {"screen": 3, "sprite": "Falling Platform", "x": 0, "y": 31, "misc": 32}, + {"screen": 3, "sprite": "Cheep Cheep (Vertical)", "x": 4, "y": 15, "misc": 64}, + {"screen": 3, "sprite": "Falling Platform", "x": 8, "y": 31, "misc": 32}, + {"screen": 3, "sprite": "Ant", "x": 20, "y": 30, "misc": 0}, + {"screen": 3, "sprite": "Heart Block", "x": 27, "y": 17, "misc": 32}, + {"screen": 3, "sprite": "Heart Block", "x": 29, "y": 5, "misc": 32}, + {"screen": 4, "sprite": "Fire Piranha Plant", "x": 4, "y": 22, "misc": 192}, + {"screen": 4, "sprite": "Moving Platform (Small, Horizontal)", "x": 8, "y": 19, "misc": 0}, + {"screen": 4, "sprite": "Ant", "x": 12, "y": 20, "misc": 64}, + {"screen": 4, "sprite": "Moving Platform (Small, Vertical)", "x": 14, "y": 2, "misc": 64}, + {"screen": 4, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 0}, + {"screen": 4, "sprite": "Money Bag Block", "x": 27, "y": 15, "misc": 32}, + {"screen": 4, "sprite": "Heart Block", "x": 27, "y": 17, "misc": 64}], + "Tree Zone 5": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 15, "y": 17, "misc": 64}, + {"screen": 1, "sprite": "Rotating Platform (Small)", "x": 15, "y": 19, "misc": 64}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 2, "y": 26, "misc": 192}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 16, "y": 26, "misc": 192}, + {"screen": 2, "sprite": "Heart Block", "x": 17, "y": 13, "misc": 64}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 26, "y": 26, "misc": 192}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 6, "y": 22, "misc": 192}, + {"screen": 3, "sprite": "Owl Platform (Vertical)", "x": 23, "y": 28, "misc": 64}, + {"screen": 4, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 11, "y": 19, "misc": 64}, + {"screen": 5, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 1, "y": 21, "misc": 64}, + {"screen": 5, "sprite": "Cloud Platform (Horizontal)", "x": 18, "y": 20, "misc": 64}, + {"screen": 5, "sprite": "Cloud Platform (Horizontal)", "x": 26, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Cloud Platform (Horizontal)", "x": 2, "y": 20, "misc": 64}, + {"screen": 6, "sprite": "Midway Bell", "x": 18, "y": 20, "misc": 64}, + {"screen": 6, "sprite": "Heart Block", "x": 23, "y": 21, "misc": 64}, + {"screen": 6, "sprite": "Dondon", "x": 30, "y": 14, "misc": 64}, + {"screen": 7, "sprite": "Carrot Block", "x": 9, "y": 19, "misc": 64}, + {"screen": 7, "sprite": "Rotating Platform (Small)", "x": 9, "y": 21, "misc": 64}, + {"screen": 7, "sprite": "Heart Block", "x": 23, "y": 13, "misc": 64}, + {"screen": 7, "sprite": "Rotating Platform (Small)", "x": 23, "y": 23, "misc": 64}, + {"screen": 8, "sprite": "Mushroom Block", "x": 21, "y": 13, "misc": 64}, + {"screen": 9, "sprite": "Star Block", "x": 5, "y": 7, "misc": 64}, + {"screen": 9, "sprite": "Paragoomba (Vertical)", "x": 7, "y": 14, "misc": 64}, + {"screen": 9, "sprite": "Paragoomba (Vertical)", "x": 27, "y": 20, "misc": 64}, + {"screen": 9, "sprite": "Paragoomba (Vertical)", "x": 31, "y": 16, "misc": 64}, + {"screen": 10, "sprite": "Cloud Platform (Horizontal)", "x": 20, "y": 22, "misc": 64}, + {"screen": 10, "sprite": "Paragoomba (Vertical)", "x": 31, "y": 18, "misc": 64}, + {"screen": 11, "sprite": "Cloud Platform (Horizontal)", "x": 8, "y": 22, "misc": 64}, + {"screen": 11, "sprite": "Paragoomba (Vertical)", "x": 16, "y": 25, "misc": 64}], + "Pumpkin Zone 1": [ + {"screen": 1, "sprite": "Falling Spike on Chain", "x": 9, "y": 14, "misc": 160}, + {"screen": 1, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 0}, + {"screen": 1, "sprite": "Masked Ghoul/Bullet Bill", "x": 19, "y": 30, "misc": 0}, + {"screen": 1, "sprite": "Falling Spike on Chain", "x": 27, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Falling Spike on Chain", "x": 17, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Falling Spike on Chain", "x": 23, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Falling Spike on Chain", "x": 29, "y": 22, "misc": 32}, + {"screen": 3, "sprite": "Masked Ghoul/Bullet Bill", "x": 1, "y": 30, "misc": 160}, + {"screen": 3, "sprite": "Masked Ghoul/Bullet Bill", "x": 21, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 5, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Carrot Block", "x": 17, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 21, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Falling Spike", "x": 27, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Boo/Bomubomu", "x": 1, "y": 28, "misc": 0}, + {"screen": 6, "sprite": "Masked Ghoul/Bullet Bill", "x": 2, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Heart Block", "x": 5, "y": 7, "misc": 0}, + {"screen": 6, "sprite": "Boo/Bomubomu", "x": 9, "y": 28, "misc": 128}, + {"screen": 6, "sprite": "Fire Piranha Plant", "x": 16, "y": 2, "misc": 192}, + {"screen": 6, "sprite": "Midway Bell", "x": 24, "y": 22, "misc": 32}, + {"screen": 7, "sprite": "Falling Spike", "x": 1, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Masked Ghoul/Bullet Bill", "x": 9, "y": 30, "misc": 160}, + {"screen": 7, "sprite": "Falling Spike", "x": 27, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Masked Ghoul/Bullet Bill", "x": 31, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Piranha Plant", "x": 16, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Masked Ghoul/Bullet Bill", "x": 17, "y": 24, "misc": 160}, + {"screen": 8, "sprite": "Fire Piranha Plant", "x": 24, "y": 30, "misc": 160}, + {"screen": 9, "sprite": "Masked Ghoul/Bullet Bill", "x": 7, "y": 22, "misc": 160}, + {"screen": 9, "sprite": "Falling Spike on Chain", "x": 11, "y": 10, "misc": 160}, + {"screen": 9, "sprite": "Piranha Plant", "x": 20, "y": 14, "misc": 32}, + {"screen": 9, "sprite": "Falling Spike on Chain", "x": 23, "y": 30, "misc": 128}, + {"screen": 10, "sprite": "Cheep Cheep (Vertical)", "x": 30, "y": 11, "misc": 160}, + {"screen": 11, "sprite": "Cheep Cheep (Vertical)", "x": 6, "y": 19, "misc": 32}, + {"screen": 11, "sprite": "Kurokyura/Jack-in-the-Box", "x": 11, "y": 30, "misc": 0}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 3, "misc": 32}, + {"screen": 11, "sprite": "Heart Block", "x": 27, "y": 11, "misc": 0}], + "Pumpkin Zone 2": [ + {"screen": 1, "sprite": "Karakara", "x": 7, "y": 30, "misc": 160}, + {"screen": 1, "sprite": "Karakara", "x": 15, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Karakara", "x": 23, "y": 30, "misc": 160}, + {"screen": 2, "sprite": "Piranha Plant", "x": 20, "y": 30, "misc": 160}, + {"screen": 3, "sprite": "Honebon/F Boy", "x": 4, "y": 11, "misc": 160}, + {"screen": 3, "sprite": "Cheep Cheep (Vertical)", "x": 4, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 13, "y": 28, "misc": 192}, + {"screen": 3, "sprite": "Mushroom Block", "x": 17, "y": 21, "misc": 64}, + {"screen": 4, "sprite": "Kyororo", "x": 29, "y": 30, "misc": 160}, + {"screen": 5, "sprite": "Honebon/F Boy", "x": 6, "y": 24, "misc": 32}, + {"screen": 5, "sprite": "Kyororo", "x": 13, "y": 30, "misc": 160}, + {"screen": 5, "sprite": "Kyororo", "x": 29, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Midway Bell", "x": 1, "y": 16, "misc": 32}, + {"screen": 6, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 21, "y": 30, "misc": 192}, + {"screen": 6, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 28, "y": 25, "misc": 64}, + {"screen": 7, "sprite": "Mushroom", "x": 3, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Boo/Bomubomu", "x": 9, "y": 13, "misc": 160}, + {"screen": 7, "sprite": "Boo/Bomubomu", "x": 13, "y": 21, "misc": 160}, + {"screen": 7, "sprite": "Heart", "x": 29, "y": 14, "misc": 32}, + {"screen": 8, "sprite": "Carrot", "x": 7, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Flower", "x": 13, "y": 14, "misc": 32}, + {"screen": 8, "sprite": "Heart", "x": 19, "y": 20, "misc": 32}, + {"screen": 9, "sprite": "Star Block", "x": 1, "y": 13, "misc": 32}, + {"screen": 9, "sprite": "Kyororo", "x": 19, "y": 30, "misc": 64}, + {"screen": 9, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 20, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Kyororo", "x": 21, "y": 16, "misc": 32}, + {"screen": 10, "sprite": "Kyororo", "x": 5, "y": 14, "misc": 32}, + {"screen": 10, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 7, "y": 28, "misc": 32}, + {"screen": 10, "sprite": "Kyororo", "x": 22, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 0, "y": 26, "misc": 192}, + {"screen": 11, "sprite": "Falling Spike", "x": 5, "y": 24, "misc": 64}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 7, "y": 30, "misc": 32}, + {"screen": 11, "sprite": "Kyororo", "x": 10, "y": 16, "misc": 32}, + {"screen": 11, "sprite": "Falling Spike", "x": 15, "y": 24, "misc": 64}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 19, "y": 28, "misc": 192}, + {"screen": 12, "sprite": "Karakara", "x": 9, "y": 30, "misc": 32}, + {"screen": 12, "sprite": "Karakara", "x": 17, "y": 30, "misc": 32}, + {"screen": 12, "sprite": "Karakara", "x": 25, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Karakara", "x": 19, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Bonus Bell", "x": 21, "y": 11, "misc": 32}], + "Pumpkin Zone 3": [ + {"screen": 1, "sprite": "Unibo/Terekuribo", "x": 21, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Unibo/Terekuribo", "x": 21, "y": 20, "misc": 160}, + {"screen": 3, "sprite": "Carrot Block", "x": 9, "y": 7, "misc": 32}, + {"screen": 3, "sprite": "Boo/Bomubomu", "x": 19, "y": 23, "misc": 32}, + {"screen": 4, "sprite": "Boo/Bomubomu", "x": 1, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Boo/Bomubomu", "x": 19, "y": 14, "misc": 160}, + {"screen": 6, "sprite": "Moving Platform (Small, Horizontal)", "x": 0, "y": 8, "misc": 64}, + {"screen": 6, "sprite": "Moving Platform (Small, Horizontal)", "x": 0, "y": 14, "misc": 64}, + {"screen": 6, "sprite": "Flower Block", "x": 17, "y": 19, "misc": 64}, + {"screen": 7, "sprite": "Unibo/Terekuribo", "x": 1, "y": 26, "misc": 32}, + {"screen": 7, "sprite": "Boo/Bomubomu", "x": 17, "y": 18, "misc": 64}, + {"screen": 8, "sprite": "Fire Piranha Plant", "x": 16, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Heart Block", "x": 23, "y": 5, "misc": 64}, + {"screen": 8, "sprite": "Flower Block", "x": 25, "y": 17, "misc": 64}, + {"screen": 9, "sprite": "Midway Bell", "x": 5, "y": 22, "misc": 32}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 19, "y": 22, "misc": 160}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 2, "y": 27, "misc": 32}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 25, "y": 14, "misc": 160}, + {"screen": 11, "sprite": "Carrot Block", "x": 7, "y": 13, "misc": 32}, + {"screen": 11, "sprite": "Boo/Bomubomu", "x": 23, "y": 18, "misc": 160}, + {"screen": 13, "sprite": "Boo/Bomubomu", "x": 3, "y": 28, "misc": 32}, + {"screen": 13, "sprite": "Boo/Bomubomu", "x": 12, "y": 5, "misc": 64}, + {"screen": 14, "sprite": "Unibo/Terekuribo", "x": 3, "y": 28, "misc": 160}, + {"screen": 14, "sprite": "Boo/Bomubomu", "x": 5, "y": 18, "misc": 192}, + {"screen": 14, "sprite": "Unibo/Terekuribo", "x": 14, "y": 24, "misc": 32}, + {"screen": 14, "sprite": "Bonus Bell", "x": 21, "y": 13, "misc": 64}], + "Pumpkin Zone 4": [ + {"screen": 1, "sprite": "Tosenbo/Pikku", "x": 19, "y": 30, "misc": 160}, + {"screen": 1, "sprite": "Piranha Plant", "x": 24, "y": 0, "misc": 64}, + {"screen": 2, "sprite": "Boo/Bomubomu", "x": 9, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Boo/Bomubomu", "x": 24, "y": 21, "misc": 160}, + {"screen": 3, "sprite": "Boo/Bomubomu", "x": 23, "y": 26, "misc": 160}, + {"screen": 3, "sprite": "Falling Spike on Chain", "x": 29, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Falling Spike on Chain", "x": 3, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Falling Spike on Chain", "x": 9, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Tosenbo/Pikku", "x": 28, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Mushroom Block", "x": 7, "y": 11, "misc": 64}, + {"screen": 5, "sprite": "Boo/Bomubomu", "x": 17, "y": 26, "misc": 192}, + {"screen": 5, "sprite": "Heart Block", "x": 29, "y": 15, "misc": 64}, + {"screen": 6, "sprite": "Carrot Block", "x": 17, "y": 13, "misc": 32}, + {"screen": 7, "sprite": "Midway Bell", "x": 15, "y": 24, "misc": 32}, + {"screen": 8, "sprite": "Falling Spike on Chain", "x": 3, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Rerere/Poro", "x": 10, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Falling Spike on Chain", "x": 17, "y": 22, "misc": 160}, + {"screen": 8, "sprite": "Falling Spike on Chain", "x": 27, "y": 22, "misc": 160}, + {"screen": 9, "sprite": "Rerere/Poro", "x": 3, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Falling Spike on Chain", "x": 9, "y": 22, "misc": 160}, + {"screen": 10, "sprite": "Masked Ghoul/Bullet Bill", "x": 19, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Masked Ghoul/Bullet Bill", "x": 25, "y": 26, "misc": 160}, + {"screen": 10, "sprite": "Masked Ghoul/Bullet Bill", "x": 31, "y": 22, "misc": 32}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 5, "y": 18, "misc": 32}, + {"screen": 12, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 16, "misc": 192}, + {"screen": 12, "sprite": "Masked Ghoul/Bullet Bill", "x": 25, "y": 16, "misc": 192}, + {"screen": 13, "sprite": "Masked Ghoul/Bullet Bill", "x": 6, "y": 16, "misc": 192}, + {"screen": 13, "sprite": "Flower Block", "x": 13, "y": 23, "misc": 32}, + {"screen": 13, "sprite": "Masked Ghoul/Bullet Bill", "x": 18, "y": 16, "misc": 192}, + {"screen": 13, "sprite": "Money Bag Block", "x": 25, "y": 23, "misc": 32}, + {"screen": 14, "sprite": "Boo/Bomubomu", "x": 13, "y": 30, "misc": 160}], + "Mario Zone 1": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 5, "y": 23, "misc": 64}, + {"screen": 1, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 7, "y": 9, "misc": 64}, + {"screen": 1, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 13, "y": 13, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 13, "y": 30, "misc": 192}, + {"screen": 1, "sprite": "Spinning Spike (Vertical)", "x": 19, "y": 22, "misc": 0}, + {"screen": 1, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 19, "y": 15, "misc": 32}, + {"screen": 2, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 13, "y": 27, "misc": 64}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 25, "y": 18, "misc": 64}, + {"screen": 3, "sprite": "Spinning Platform (Vertical)", "x": 1, "y": 18, "misc": 64}, + {"screen": 3, "sprite": "Spinning Platform (Vertical)", "x": 7, "y": 18, "misc": 64}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 19, "y": 26, "misc": 192}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 31, "y": 14, "misc": 192}, + {"screen": 4, "sprite": "Spinning Platform (Vertical)", "x": 23, "y": 20, "misc": 64}, + {"screen": 4, "sprite": "Tatenoko", "x": 26, "y": 15, "misc": 192}, + {"screen": 4, "sprite": "Spinning Platform (Vertical)", "x": 29, "y": 20, "misc": 64}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 11, "y": 16, "misc": 192}, + {"screen": 5, "sprite": "Spinning Platform (Vertical)", "x": 19, "y": 22, "misc": 64}, + {"screen": 5, "sprite": "Spinning Platform (Vertical)", "x": 23, "y": 22, "misc": 64}, + {"screen": 6, "sprite": "Carrot Block", "x": 5, "y": 11, "misc": 64}, + {"screen": 6, "sprite": "Midway Bell", "x": 16, "y": 12, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 19, "y": 20, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 21, "y": 24, "misc": 192}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 12, "y": 30, "misc": 64}, + {"screen": 8, "sprite": "Heart Block", "x": 13, "y": 17, "misc": 64}, + {"screen": 9, "sprite": "Mushroom Block", "x": 3, "y": 19, "misc": 64}, + {"screen": 9, "sprite": "Neiji/Buichi", "x": 3, "y": 0, "misc": 96}, + {"screen": 9, "sprite": "Neiji/Buichi", "x": 11, "y": 0, "misc": 224}, + {"screen": 9, "sprite": "Neiji/Buichi", "x": 19, "y": 0, "misc": 224}, + {"screen": 9, "sprite": "Heart Block", "x": 27, "y": 7, "misc": 32}, + {"screen": 9, "sprite": "Spinning Platform (Vertical)", "x": 29, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Tatenoko", "x": 4, "y": 13, "misc": 32}, + {"screen": 10, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 7, "y": 21, "misc": 64}, + {"screen": 10, "sprite": "Carrot Block", "x": 9, "y": 7, "misc": 32}, + {"screen": 10, "sprite": "Spinning Platform (Vertical)", "x": 9, "y": 18, "misc": 32}, + {"screen": 10, "sprite": "Bonus Bell", "x": 19, "y": 17, "misc": 64}], + "Mario Zone 2": [ + {"screen": 1, "sprite": "Boo/Bomubomu", "x": 9, "y": 28, "misc": 32}, + {"screen": 1, "sprite": "Boo/Bomubomu", "x": 31, "y": 22, "misc": 160}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 6, "y": 18, "misc": 160}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 15, "y": 21, "misc": 160}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 3, "y": 20, "misc": 160}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 12, "y": 18, "misc": 160}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 28, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Mushroom Block", "x": 3, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Heart", "x": 8, "y": 28, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 9, "y": 20, "misc": 192}, + {"screen": 5, "sprite": "Carrot Block", "x": 17, "y": 11, "misc": 64}, + {"screen": 5, "sprite": "Goomba", "x": 25, "y": 26, "misc": 192}, + {"screen": 5, "sprite": "Money Bag Block", "x": 27, "y": 19, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 3, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Star Block", "x": 7, "y": 11, "misc": 64}, + {"screen": 7, "sprite": "Noko Bombette/Bear", "x": 6, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Midway Bell", "x": 5, "y": 18, "misc": 32}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 21, "y": 28, "misc": 160}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 31, "y": 16, "misc": 32}, + {"screen": 9, "sprite": "Mushroom Block", "x": 11, "y": 15, "misc": 32}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 19, "y": 20, "misc": 160}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 5, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Mushroom", "x": 1, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Goomba", "x": 9, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Flower", "x": 17, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Carrot", "x": 25, "y": 14, "misc": 32}, + {"screen": 12, "sprite": "Boo/Bomubomu", "x": 12, "y": 16, "misc": 32}, + {"screen": 12, "sprite": "Boo/Bomubomu", "x": 24, "y": 20, "misc": 160}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 16, "y": 28, "misc": 32}, + {"screen": 14, "sprite": "Noko Bombette/Bear", "x": 12, "y": 28, "misc": 32}, + {"screen": 14, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 32}], + "Mario Zone 3": [ + {"screen": 1, "sprite": "Kurokyura/Jack-in-the-Box", "x": 15, "y": 23, "misc": 160}, + {"screen": 1, "sprite": "Kiddokatto", "x": 21, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Masked Ghoul/Bullet Bill", "x": 4, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Diagonal Ball on Chain", "x": 9, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Diagonal Ball on Chain", "x": 1, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Mushroom Block", "x": 13, "y": 17, "misc": 32}, + {"screen": 3, "sprite": "Diagonal Ball on Chain", "x": 25, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 24, "misc": 160}, + {"screen": 4, "sprite": "Diagonal Ball on Chain", "x": 27, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 24, "misc": 160}, + {"screen": 6, "sprite": "Carrot Block", "x": 9, "y": 21, "misc": 32}, + {"screen": 6, "sprite": "Kiddokatto", "x": 25, "y": 30, "misc": 160}, + {"screen": 7, "sprite": "Masked Ghoul/Bullet Bill", "x": 26, "y": 28, "misc": 32}, + {"screen": 7, "sprite": "Midway Bell", "x": 27, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Kurokyura/Jack-in-the-Box", "x": 11, "y": 21, "misc": 32}, + {"screen": 8, "sprite": "Heart Block", "x": 13, "y": 3, "misc": 32}, + {"screen": 8, "sprite": "Kiddokatto", "x": 31, "y": 30, "misc": 160}, + {"screen": 9, "sprite": "Claw Grabber", "x": 23, "y": 28, "misc": 32}, + {"screen": 10, "sprite": "Claw Grabber", "x": 13, "y": 28, "misc": 32}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 4, "y": 28, "misc": 64}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 5, "y": 20, "misc": 160}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 8, "y": 12, "misc": 192}, + {"screen": 11, "sprite": "Kiddokatto", "x": 26, "y": 20, "misc": 32}, + {"screen": 11, "sprite": "Heart Block", "x": 27, "y": 23, "misc": 64}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 28, "y": 18, "misc": 192}, + {"screen": 12, "sprite": "Claw Grabber", "x": 11, "y": 28, "misc": 32}, + {"screen": 12, "sprite": "Kiddokatto", "x": 21, "y": 20, "misc": 32}, + {"screen": 13, "sprite": "Mushroom Block", "x": 13, "y": 21, "misc": 32}, + {"screen": 13, "sprite": "Masked Ghoul/Bullet Bill", "x": 18, "y": 28, "misc": 160}, + {"screen": 13, "sprite": "Kurokyura/Jack-in-the-Box", "x": 25, "y": 21, "misc": 32}, + {"screen": 14, "sprite": "Diagonal Ball on Chain", "x": 9, "y": 30, "misc": 32}, + {"screen": 14, "sprite": "Masked Ghoul/Bullet Bill", "x": 26, "y": 24, "misc": 160}, + {"screen": 15, "sprite": "Claw Grabber", "x": 3, "y": 18, "misc": 32}, + {"screen": 15, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 32}], + "Mario Zone 4": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 9, "y": 17, "misc": 32}, + {"screen": 1, "sprite": "Spinning Spike/Tamara", "x": 9, "y": 25, "misc": 160}, + {"screen": 1, "sprite": "Spinning Spike/Tamara", "x": 29, "y": 25, "misc": 32}, + {"screen": 2, "sprite": "Masked Ghoul/Bullet Bill", "x": 12, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Spinning Spike/Tamara", "x": 29, "y": 21, "misc": 160}, + {"screen": 3, "sprite": "Spinning Spike/Tamara", "x": 15, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 26, "misc": 160}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 24, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Masked Ghoul/Bullet Bill", "x": 2, "y": 26, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 22, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 2, "y": 14, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 14, "y": 8, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 26, "y": 2, "misc": 32}, + {"screen": 7, "sprite": "Spinning Spike/Tamara", "x": 9, "y": 25, "misc": 160}, + {"screen": 7, "sprite": "Spinning Spike/Tamara", "x": 15, "y": 21, "misc": 32}, + {"screen": 7, "sprite": "Spinning Spike/Tamara", "x": 21, "y": 25, "misc": 160}, + {"screen": 7, "sprite": "Mushroom Block", "x": 25, "y": 23, "misc": 0}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 17, "y": 26, "misc": 128}, + {"screen": 8, "sprite": "Masked Ghoul/Bullet Bill", "x": 30, "y": 24, "misc": 0}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 11, "y": 30, "misc": 128}, + {"screen": 9, "sprite": "Midway Bell", "x": 16, "y": 24, "misc": 0}, + {"screen": 9, "sprite": "Goomba", "x": 26, "y": 30, "misc": 0}, + {"screen": 10, "sprite": "Moving Saw (Ceiling)", "x": 17, "y": 26, "misc": 0}, + {"screen": 10, "sprite": "Moving Saw (Floor)", "x": 19, "y": 22, "misc": 128}, + {"screen": 11, "sprite": "Mushroom Block", "x": 7, "y": 23, "misc": 0}, + {"screen": 11, "sprite": "Moving Saw (Ceiling)", "x": 25, "y": 26, "misc": 128}, + {"screen": 11, "sprite": "Moving Saw (Floor)", "x": 27, "y": 22, "misc": 0}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 29, "y": 30, "misc": 0}, + {"screen": 13, "sprite": "Moving Saw (Floor)", "x": 9, "y": 28, "misc": 128}, + {"screen": 13, "sprite": "Moving Saw (Floor)", "x": 19, "y": 28, "misc": 0}, + {"screen": 14, "sprite": "Spinning Spike/Tamara", "x": 13, "y": 25, "misc": 0}, + {"screen": 14, "sprite": "Goomba", "x": 21, "y": 30, "misc": 128}], + "Turtle Zone 1": [ + {"screen": 1, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 2, "y": 16, "misc": 192}, + {"screen": 1, "sprite": "Horizontal Blurp", "x": 12, "y": 21, "misc": 64}, + {"screen": 1, "sprite": "Mushroom Block", "x": 13, "y": 3, "misc": 64}, + {"screen": 2, "sprite": "Horizontal Blurp", "x": 1, "y": 18, "misc": 64}, + {"screen": 2, "sprite": "Spiny Cheep Cheep", "x": 11, "y": 26, "misc": 64}, + {"screen": 2, "sprite": "Cheep Cheep (Vertical)", "x": 26, "y": 28, "misc": 192}, + {"screen": 3, "sprite": "Goomba", "x": 3, "y": 8, "misc": 64}, + {"screen": 3, "sprite": "Goomba", "x": 17, "y": 8, "misc": 64}, + {"screen": 3, "sprite": "Star Block", "x": 17, "y": 1, "misc": 64}, + {"screen": 3, "sprite": "Cheep Cheep (Vertical)", "x": 18, "y": 28, "misc": 192}, + {"screen": 3, "sprite": "Heart Block", "x": 19, "y": 1, "misc": 64}, + {"screen": 3, "sprite": "Shark", "x": 27, "y": 26, "misc": 192}, + {"screen": 4, "sprite": "Paragoomba (Diagonal)", "x": 1, "y": 4, "misc": 64}, + {"screen": 4, "sprite": "Goomba", "x": 10, "y": 8, "misc": 64}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 1, "y": 16, "misc": 64}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 9, "y": 22, "misc": 192}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 16, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Shark", "x": 12, "y": 21, "misc": 64}, + {"screen": 6, "sprite": "Midway Bell", "x": 21, "y": 18, "misc": 64}, + {"screen": 6, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 25, "y": 16, "misc": 64}, + {"screen": 7, "sprite": "Spiny Cheep Cheep", "x": 21, "y": 17, "misc": 64}, + {"screen": 7, "sprite": "Horizontal Blurp", "x": 25, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Cheep Cheep (Vertical)", "x": 7, "y": 20, "misc": 64}, + {"screen": 8, "sprite": "Shark", "x": 15, "y": 14, "misc": 192}, + {"screen": 8, "sprite": "Spiny Cheep Cheep", "x": 25, "y": 24, "misc": 192}, + {"screen": 8, "sprite": "Mushroom Block", "x": 31, "y": 3, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 15, "y": 24, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 23, "y": 20, "misc": 192}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 29, "y": 26, "misc": 192}, + {"screen": 10, "sprite": "Shark", "x": 10, "y": 18, "misc": 192}, + {"screen": 10, "sprite": "Money Bag Block", "x": 11, "y": 31, "misc": 32}, + {"screen": 11, "sprite": "Shark", "x": 5, "y": 22, "misc": 64}, + {"screen": 11, "sprite": "Horizontal Blurp", "x": 16, "y": 28, "misc": 192}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 9, "misc": 64}, + {"screen": 11, "sprite": "Heart Block", "x": 27, "y": 23, "misc": 64}], + "Turtle Zone 2": [ + {"screen": 0, "sprite": "Shark", "x": 17, "y": 12, "misc": 192}, + {"screen": 0, "sprite": "Carrot Block", "x": 21, "y": 19, "misc": 64}, + {"screen": 0, "sprite": "Masked Ghoul/Bullet Bill", "x": 22, "y": 28, "misc": 192}, + {"screen": 1, "sprite": "Honebon/F Boy", "x": 13, "y": 12, "misc": 192}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 19, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Karakara", "x": 28, "y": 27, "misc": 64}, + {"screen": 2, "sprite": "Shark", "x": 7, "y": 10, "misc": 64}, + {"screen": 2, "sprite": "Karakara", "x": 17, "y": 27, "misc": 64}, + {"screen": 2, "sprite": "Karakara", "x": 23, "y": 22, "misc": 64}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 25, "y": 14, "misc": 32}, + {"screen": 3, "sprite": "Karakara", "x": 2, "y": 1, "misc": 64}, + {"screen": 3, "sprite": "Karakara", "x": 6, "y": 14, "misc": 192}, + {"screen": 3, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 24, "misc": 192}, + {"screen": 3, "sprite": "Flower Block", "x": 21, "y": 11, "misc": 64}, + {"screen": 4, "sprite": "Pencil/Spikey", "x": 7, "y": 26, "misc": 192}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 10, "y": 14, "misc": 160}, + {"screen": 4, "sprite": "Pencil/Spikey", "x": 11, "y": 26, "misc": 192}, + {"screen": 4, "sprite": "Karakara", "x": 21, "y": 22, "misc": 64}, + {"screen": 4, "sprite": "Karakara", "x": 28, "y": 12, "misc": 192}, + {"screen": 5, "sprite": "Pencil/Spikey", "x": 1, "y": 24, "misc": 192}, + {"screen": 5, "sprite": "Star Block", "x": 5, "y": 5, "misc": 64}, + {"screen": 5, "sprite": "Masked Ghoul/Bullet Bill", "x": 26, "y": 24, "misc": 192}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 30, "y": 10, "misc": 32}, + {"screen": 6, "sprite": "Masked Ghoul/Bullet Bill", "x": 6, "y": 28, "misc": 64}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 10, "y": 22, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 14, "y": 26, "misc": 32}, + {"screen": 6, "sprite": "Midway Bell", "x": 15, "y": 4, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 18, "y": 10, "misc": 64}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 26, "y": 2, "misc": 64}, + {"screen": 7, "sprite": "Karakara", "x": 8, "y": 14, "misc": 160}, + {"screen": 7, "sprite": "Karakara", "x": 19, "y": 27, "misc": 192}, + {"screen": 8, "sprite": "Flower", "x": 5, "y": 4, "misc": 64}, + {"screen": 8, "sprite": "Heart Block", "x": 7, "y": 3, "misc": 64}, + {"screen": 8, "sprite": "Pencil/Spikey", "x": 11, "y": 24, "misc": 32}, + {"screen": 8, "sprite": "Money Bag Block", "x": 23, "y": 13, "misc": 64}, + {"screen": 9, "sprite": "Pencil/Spikey", "x": 9, "y": 24, "misc": 192}, + {"screen": 9, "sprite": "Pencil/Spikey", "x": 19, "y": 24, "misc": 64}, + {"screen": 10, "sprite": "Rising Platform", "x": 4, "y": 22, "misc": 64}, + {"screen": 10, "sprite": "Rising Platform", "x": 10, "y": 16, "misc": 64}, + {"screen": 10, "sprite": "Bonus Bell", "x": 21, "y": 9, "misc": 64}, + {"screen": 12, "sprite": "Pencil/Spikey", "x": 5, "y": 24, "misc": 192}, + {"screen": 12, "sprite": "Pencil/Spikey", "x": 9, "y": 24, "misc": 192}, + {"screen": 12, "sprite": "Karakara", "x": 19, "y": 24, "misc": 64}, + {"screen": 12, "sprite": "Karakara", "x": 26, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Karakara", "x": 1, "y": 26, "misc": 192}, + {"screen": 13, "sprite": "Pencil/Spikey", "x": 15, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Honebon/F Boy", "x": 24, "y": 28, "misc": 192}, + {"screen": 14, "sprite": "Pencil/Spikey", "x": 1, "y": 24, "misc": 192}, + {"screen": 14, "sprite": "Shark", "x": 14, "y": 26, "misc": 64}], + "Turtle Zone 3": [ + {"screen": 1, "sprite": "Ragumo/Aqua Kuribo", "x": 1, "y": 26, "misc": 160}, + {"screen": 1, "sprite": "Ragumo/Aqua Kuribo", "x": 31, "y": 22, "misc": 160}, + {"screen": 2, "sprite": "Carrot Block", "x": 15, "y": 15, "misc": 32}, + {"screen": 2, "sprite": "Pencil/Spikey", "x": 29, "y": 14, "misc": 160}, + {"screen": 3, "sprite": "Pencil/Spikey", "x": 13, "y": 22, "misc": 160}, + {"screen": 3, "sprite": "Pencil/Spikey", "x": 21, "y": 26, "misc": 32}, + {"screen": 4, "sprite": "Ragumo/Aqua Kuribo", "x": 5, "y": 24, "misc": 32}, + {"screen": 5, "sprite": "Paragoomba (Vertical)", "x": 0, "y": 24, "misc": 160}, + {"screen": 5, "sprite": "Midway Bell", "x": 12, "y": 18, "misc": 32}, + {"screen": 5, "sprite": "Ragumo/Aqua Kuribo", "x": 27, "y": 20, "misc": 32}, + {"screen": 5, "sprite": "Mushroom Block", "x": 29, "y": 19, "misc": 32}, + {"screen": 6, "sprite": "Honebon/F Boy", "x": 1, "y": 30, "misc": 160}, + {"screen": 6, "sprite": "Ragumo/Aqua Kuribo", "x": 7, "y": 20, "misc": 160}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 24, "y": 20, "misc": 160}, + {"screen": 7, "sprite": "Ragumo/Aqua Kuribo", "x": 6, "y": 28, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 27, "y": 28, "misc": 160}, + {"screen": 8, "sprite": "Ragumo/Aqua Kuribo", "x": 7, "y": 28, "misc": 160}, + {"screen": 8, "sprite": "Ragumo/Aqua Kuribo", "x": 19, "y": 28, "misc": 32}, + {"screen": 9, "sprite": "Mushroom Block", "x": 17, "y": 13, "misc": 32}, + {"screen": 9, "sprite": "Honebon/F Boy", "x": 27, "y": 22, "misc": 160}, + {"screen": 9, "sprite": "Money Bag Block", "x": 29, "y": 11, "misc": 32}, + {"screen": 11, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 24, "misc": 160}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 19, "y": 30, "misc": 160}], + "Hippo Zone": [ + {"screen": 0, "sprite": "Money Bag Block", "x": 5, "y": 7, "misc": 32}, + {"screen": 0, "sprite": "Heart Block", "x": 7, "y": 5, "misc": 0}, + {"screen": 0, "sprite": "Heart Block", "x": 31, "y": 19, "misc": 32}, + {"screen": 1, "sprite": "Heart Block", "x": 1, "y": 19, "misc": 32}, + {"screen": 1, "sprite": "Bubble", "x": 6, "y": 24, "misc": 0}, + {"screen": 1, "sprite": "Mushroom Block", "x": 27, "y": 9, "misc": 32}, + {"screen": 2, "sprite": "Toriuo", "x": 11, "y": 8, "misc": 160}, + {"screen": 2, "sprite": "Unibo/Terekuribo", "x": 25, "y": 26, "misc": 128}, + {"screen": 2, "sprite": "Toriuo", "x": 29, "y": 8, "misc": 160}, + {"screen": 3, "sprite": "Toriuo", "x": 11, "y": 8, "misc": 32}, + {"screen": 3, "sprite": "Unibo/Terekuribo", "x": 17, "y": 26, "misc": 128}, + {"screen": 3, "sprite": "Heart Block", "x": 17, "y": 25, "misc": 0}, + {"screen": 4, "sprite": "Toriuo", "x": 3, "y": 8, "misc": 160}, + {"screen": 4, "sprite": "Unibo/Terekuribo", "x": 9, "y": 26, "misc": 128}, + {"screen": 4, "sprite": "Toriuo", "x": 21, "y": 8, "misc": 32}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 6, "y": 10, "misc": 160}, + {"screen": 5, "sprite": "Mushroom Block", "x": 13, "y": 11, "misc": 32}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 19, "y": 12, "misc": 32}, + {"screen": 5, "sprite": "Unibo/Terekuribo", "x": 25, "y": 10, "misc": 128}, + {"screen": 5, "sprite": "Unibo/Terekuribo", "x": 27, "y": 18, "misc": 0}, + {"screen": 6, "sprite": "Unibo/Terekuribo", "x": 7, "y": 22, "misc": 128}, + {"screen": 6, "sprite": "Unibo/Terekuribo", "x": 11, "y": 12, "misc": 128}, + {"screen": 6, "sprite": "Horizontal Blurp", "x": 13, "y": 14, "misc": 160}, + {"screen": 6, "sprite": "Bubble", "x": 14, "y": 30, "misc": 0}, + {"screen": 7, "sprite": "Dondon", "x": 13, "y": 10, "misc": 128}, + {"screen": 7, "sprite": "Dondon", "x": 15, "y": 18, "misc": 128}, + {"screen": 7, "sprite": "Dondon", "x": 17, "y": 26, "misc": 0}, + {"screen": 7, "sprite": "Toriuo", "x": 25, "y": 8, "misc": 160}, + {"screen": 8, "sprite": "Toriuo", "x": 5, "y": 8, "misc": 160}, + {"screen": 8, "sprite": "Flower Block", "x": 19, "y": 25, "misc": 0}, + {"screen": 8, "sprite": "Toriuo", "x": 21, "y": 8, "misc": 160}, + {"screen": 8, "sprite": "Toriuo", "x": 31, "y": 8, "misc": 32}, + {"screen": 9, "sprite": "Money Bag Block", "x": 11, "y": 5, "misc": 0}, + {"screen": 9, "sprite": "Horizontal Blurp", "x": 15, "y": 12, "misc": 160}, + {"screen": 9, "sprite": "Horizontal Blurp", "x": 27, "y": 10, "misc": 160}, + {"screen": 10, "sprite": "Dondon", "x": 9, "y": 14, "misc": 0}, + {"screen": 10, "sprite": "Dondon", "x": 13, "y": 24, "misc": 0}, + {"screen": 10, "sprite": "Toriuo", "x": 19, "y": 8, "misc": 32}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 5, "misc": 0}], + "Space Zone 1": [ + {"screen": 1, "sprite": "Boo/Bomubomu", "x": 19, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Boo/Bomubomu", "x": 3, "y": 26, "misc": 160}, + {"screen": 3, "sprite": "Boo/Bomubomu", "x": 5, "y": 26, "misc": 160}, + {"screen": 3, "sprite": "Rerere/Poro", "x": 25, "y": 5, "misc": 160}, + {"screen": 4, "sprite": "Money Bag Block", "x": 9, "y": 21, "misc": 0}, + {"screen": 4, "sprite": "Money Bag Block", "x": 11, "y": 29, "misc": 0}, + {"screen": 4, "sprite": "Heart", "x": 13, "y": 6, "misc": 32}, + {"screen": 4, "sprite": "Mushroom Block", "x": 23, "y": 15, "misc": 32}, + {"screen": 5, "sprite": "No 48/Mogyo", "x": 1, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Heart", "x": 5, "y": 16, "misc": 0}, + {"screen": 5, "sprite": "Boo/Bomubomu", "x": 23, "y": 28, "misc": 160}, + {"screen": 6, "sprite": "Rerere/Poro", "x": 18, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Flower Block", "x": 5, "y": 11, "misc": 32}, + {"screen": 7, "sprite": "Rerere/Poro", "x": 6, "y": 20, "misc": 160}, + {"screen": 7, "sprite": "Midway Bell", "x": 15, "y": 22, "misc": 32}, + {"screen": 7, "sprite": "Rerere/Poro", "x": 19, "y": 13, "misc": 32}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 1, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Money Bag Block", "x": 7, "y": 21, "misc": 32}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 17, "y": 28, "misc": 32}, + {"screen": 9, "sprite": "Heart Block", "x": 3, "y": 15, "misc": 0}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 8, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Rerere/Poro", "x": 31, "y": 15, "misc": 160}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 31, "y": 20, "misc": 32}, + {"screen": 11, "sprite": "Boo/Bomubomu", "x": 3, "y": 28, "misc": 32}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 11, "misc": 32}], + "Space Zone 2": [ + {"screen": 2, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 5, "y": 22, "misc": 128}, + {"screen": 2, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 25, "y": 16, "misc": 128}, + {"screen": 2, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 27, "y": 30, "misc": 128}, + {"screen": 3, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 11, "y": 10, "misc": 128}, + {"screen": 4, "sprite": "Mushroom", "x": 1, "y": 6, "misc": 0}, + {"screen": 4, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 3, "y": 30, "misc": 128}, + {"screen": 4, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 23, "y": 26, "misc": 128}, + {"screen": 5, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 1, "y": 22, "misc": 128}, + {"screen": 5, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 9, "y": 26, "misc": 128}, + {"screen": 5, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 27, "y": 14, "misc": 0}, + {"screen": 6, "sprite": "Mushroom Block", "x": 13, "y": 15, "misc": 0}, + {"screen": 6, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 19, "y": 18, "misc": 128}, + {"screen": 7, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 13, "y": 22, "misc": 128}, + {"screen": 7, "sprite": "Mushroom Block", "x": 17, "y": 9, "misc": 0}, + {"screen": 7, "sprite": "Tosenbo/Pikku", "x": 27, "y": 24, "misc": 128}, + {"screen": 8, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 3, "y": 16, "misc": 128}, + {"screen": 9, "sprite": "Tosenbo/Pikku", "x": 3, "y": 16, "misc": 0}, + {"screen": 9, "sprite": "Tosenbo/Pikku", "x": 25, "y": 16, "misc": 0}, + {"screen": 10, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 13, "y": 16, "misc": 128}, + {"screen": 10, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 25, "y": 16, "misc": 128}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 15, "y": 20, "misc": 128}, + {"screen": 11, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 25, "y": 22, "misc": 0}, + {"screen": 12, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 5, "y": 16, "misc": 128}, + {"screen": 12, "sprite": "Mushroom Block", "x": 31, "y": 11, "misc": 0}, + {"screen": 13, "sprite": "Star Block", "x": 5, "y": 17, "misc": 0}, + {"screen": 13, "sprite": "Tosenbo/Pikku", "x": 7, "y": 17, "misc": 128}, + {"screen": 13, "sprite": "Midway Bell", "x": 19, "y": 20, "misc": 0}, + {"screen": 13, "sprite": "Mushroom", "x": 31, "y": 6, "misc": 0}, + {"screen": 15, "sprite": "Tosenbo/Pikku", "x": 1, "y": 26, "misc": 128}, + {"screen": 15, "sprite": "Mushroom Block", "x": 17, "y": 19, "misc": 0}], + "Macro Zone 1": [ + {"screen": 1, "sprite": "Kyotonbo", "x": 1, "y": 22, "misc": 0}, + {"screen": 1, "sprite": "Goronto", "x": 23, "y": 26, "misc": 128}, + {"screen": 2, "sprite": "Moving Platform (Large, Horizontal)", "x": 20, "y": 31, + "misc": 64}, {"screen": 3, "sprite": "Chikunto", "x": 1, "y": 16, "misc": 64}, + {"screen": 3, "sprite": "Mushroom Block", "x": 3, "y": 21, "misc": 64}, + {"screen": 4, "sprite": "Chikunto", "x": 19, "y": 28, "misc": 192}, + {"screen": 5, "sprite": "Big Diagonal Moving Platform", "x": 12, "y": 23, + "misc": 64}, + {"screen": 5, "sprite": "Moving Platform (Large, Horizontal)", "x": 14, "y": 31, + "misc": 64}, + {"screen": 5, "sprite": "Carrot Block", "x": 15, "y": 13, "misc": 64}, + {"screen": 6, "sprite": "Dokanto", "x": 25, "y": 28, "misc": 64}, + {"screen": 6, "sprite": "Carrot Block", "x": 31, "y": 27, "misc": 64}, + {"screen": 7, "sprite": "Kyotonbo", "x": 27, "y": 28, "misc": 64}, + {"screen": 8, "sprite": "Flower Block", "x": 1, "y": 27, "misc": 64}, + {"screen": 8, "sprite": "Chikunto", "x": 9, "y": 28, "misc": 64}, + {"screen": 9, "sprite": "Heart Block", "x": 11, "y": 27, "misc": 64}, + {"screen": 9, "sprite": "Chikunto", "x": 19, "y": 28, "misc": 192}, + {"screen": 9, "sprite": "Money Bag Block", "x": 25, "y": 27, "misc": 64}, + {"screen": 9, "sprite": "Goronto", "x": 29, "y": 28, "misc": 64}, + {"screen": 10, "sprite": "Heart Block", "x": 9, "y": 9, "misc": 32}, + {"screen": 10, "sprite": "Heart Block", "x": 13, "y": 9, "misc": 32}, + {"screen": 10, "sprite": "Midway Bell", "x": 15, "y": 26, "misc": 64}, + {"screen": 10, "sprite": "Heart Block", "x": 21, "y": 9, "misc": 32}, + {"screen": 10, "sprite": "Moving Platform (Large, Horizontal)", "x": 30, "y": 31, + "misc": 64}, + {"screen": 11, "sprite": "Carrot Block", "x": 3, "y": 15, "misc": 64}, + {"screen": 11, "sprite": "Falling Platform", "x": 26, "y": 17, "misc": 64}, + {"screen": 12, "sprite": "Moving Platform (Large, Horizontal)", "x": 28, "y": 31, + "misc": 64}, {"screen": 13, "sprite": "Kyotonbo", "x": 3, "y": 18, "misc": 192}, + {"screen": 13, "sprite": "Chikunto", "x": 17, "y": 28, "misc": 64}, + {"screen": 13, "sprite": "Dokanto", "x": 25, "y": 18, "misc": 64}, + {"screen": 14, "sprite": "Kyotonbo", "x": 0, "y": 28, "misc": 32}, + {"screen": 14, "sprite": "Moving Platform (Large, Horizontal)", "x": 0, "y": 31, + "misc": 64}, {"screen": 14, "sprite": "Goronto", "x": 12, "y": 26, "misc": 32}, + {"screen": 14, "sprite": "Dokanto", "x": 19, "y": 28, "misc": 192}, + {"screen": 14, "sprite": "Flower Block", "x": 21, "y": 21, "misc": 64}, + {"screen": 15, "sprite": "Big Diagonal Moving Platform", "x": 13, "y": 21, + "misc": 64}, + {"screen": 15, "sprite": "Bonus Bell", "x": 21, "y": 11, "misc": 64}], + "Macro Zone 2": [ + {"screen": 1, "sprite": "Ant", "x": 10, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Mushroom Block", "x": 19, "y": 19, "misc": 32}, + {"screen": 1, "sprite": "Piranha Plant", "x": 28, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Ant", "x": 21, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Battle Beetle", "x": 23, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Ant", "x": 5, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Fire Piranha Plant", "x": 22, "y": 2, "misc": 192}, + {"screen": 4, "sprite": "Ant", "x": 8, "y": 26, "misc": 160}, + {"screen": 4, "sprite": "Fire Piranha Plant", "x": 18, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Piranha Plant", "x": 6, "y": 30, "misc": 160}, + {"screen": 5, "sprite": "Battle Beetle", "x": 16, "y": 26, "misc": 32}, + {"screen": 6, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 5, "y": 26, "misc": 192}, + {"screen": 6, "sprite": "Carrot Block", "x": 7, "y": 15, "misc": 64}, + {"screen": 6, "sprite": "Ant", "x": 16, "y": 18, "misc": 64}, + {"screen": 7, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 0, "y": 23, "misc": 192}, + {"screen": 7, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 11, "y": 28, "misc": 64}, + {"screen": 7, "sprite": "Fire Piranha Plant", "x": 30, "y": 20, "misc": 192}, + {"screen": 8, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 15, "y": 28, "misc": 64}, + {"screen": 8, "sprite": "Star Block", "x": 19, "y": 9, "misc": 64}, + {"screen": 8, "sprite": "Piranha Plant", "x": 30, "y": 22, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 11, "y": 28, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 17, "y": 28, "misc": 64}, + {"screen": 9, "sprite": "Midway Bell", "x": 31, "y": 14, "misc": 64}, + {"screen": 10, "sprite": "Ant", "x": 1, "y": 18, "misc": 64}, + {"screen": 10, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 31, "y": 28, "misc": 64}, + {"screen": 11, "sprite": "Ant", "x": 3, "y": 16, "misc": 64}, + {"screen": 11, "sprite": "Star Block", "x": 9, "y": 15, "misc": 64}, + {"screen": 11, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 19, "y": 15, "misc": 160}, + {"screen": 11, "sprite": "Cheep Cheep (Vertical)", "x": 21, "y": 29, "misc": 64}, + {"screen": 12, "sprite": "Be", "x": 9, "y": 14, "misc": 32}, + {"screen": 12, "sprite": "Be", "x": 21, "y": 24, "misc": 32}, + {"screen": 12, "sprite": "Be", "x": 27, "y": 24, "misc": 32}, + {"screen": 13, "sprite": "Mushroom Block", "x": 7, "y": 23, "misc": 32}, + {"screen": 13, "sprite": "Bonus Bell", "x": 21, "y": 15, "misc": 32}], + "Macro Zone 3": [ + {"screen": 1, "sprite": "Koopa Troopa", "x": 0, "y": 26, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 9, "y": 22, "misc": 32}, + {"screen": 1, "sprite": "Carrot Block", "x": 17, "y": 13, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 23, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Goomba", "x": 4, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Goomba", "x": 29, "y": 26, "misc": 32}, + {"screen": 3, "sprite": "Piranha Plant", "x": 28, "y": 2, "misc": 64}, + {"screen": 4, "sprite": "Piranha Plant (Downward)/Grubby", "x": 4, "y": 25, "misc": 160}, + {"screen": 4, "sprite": "Goomba", "x": 14, "y": 30, "misc": 160}, + {"screen": 4, "sprite": "Goomba", "x": 30, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Piranha Plant (Downward)/Grubby", "x": 8, "y": 25, "misc": 32}, + {"screen": 5, "sprite": "Money Bag Block", "x": 11, "y": 21, "misc": 64}, + {"screen": 5, "sprite": "Honebon/F Boy", "x": 11, "y": 30, "misc": 64}, + {"screen": 5, "sprite": "Paragoomba (Diagonal)", "x": 23, "y": 28, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 15, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 23, "y": 26, "misc": 64}, + {"screen": 7, "sprite": "Mushroom Block", "x": 1, "y": 23, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 11, "y": 26, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 21, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Heart Block", "x": 3, "y": 5, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 7, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 17, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Star Block", "x": 29, "y": 23, "misc": 64}, + {"screen": 8, "sprite": "Midway Bell", "x": 31, "y": 22, "misc": 32}, + {"screen": 9, "sprite": "Be", "x": 31, "y": 18, "misc": 32}, + {"screen": 10, "sprite": "Be", "x": 11, "y": 18, "misc": 32}, + {"screen": 11, "sprite": "Piranha Plant", "x": 16, "y": 24, "misc": 160}, + {"screen": 12, "sprite": "Carrot Block", "x": 23, "y": 17, "misc": 32}, + {"screen": 13, "sprite": "Koopa Troopa", "x": 7, "y": 4, "misc": 160}, + {"screen": 13, "sprite": "Paragoomba (Vertical)", "x": 15, "y": 24, "misc": 128}, + {"screen": 13, "sprite": "Bonus Bell", "x": 23, "y": 5, "misc": 0}], + "Macro Zone 4": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 1, "y": 23, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 7, "y": 28, "misc": 160}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 17, "y": 24, "misc": 32}, + {"screen": 2, "sprite": "Runaway Heart Block/Bibi", "x": 5, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "Goomba", "x": 11, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Goomba", "x": 21, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Piranha Plant", "x": 6, "y": 24, "misc": 32}, + {"screen": 5, "sprite": "Piranha Plant (Downward)/Grubby", "x": 4, "y": 25, "misc": 32}, + {"screen": 5, "sprite": "Money Bag Block", "x": 11, "y": 7, "misc": 32}, + {"screen": 5, "sprite": "Carrot Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 19, "y": 30, "misc": 160}, + {"screen": 6, "sprite": "Goomba", "x": 7, "y": 30, "misc": 160}, + {"screen": 6, "sprite": "Goomba", "x": 11, "y": 18, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 25, "y": 30, "misc": 160}, + {"screen": 7, "sprite": "Runaway Heart Block/Bibi", "x": 5, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Fire Piranha Plant", "x": 24, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Midway Bell", "x": 3, "y": 20, "misc": 32}, + {"screen": 8, "sprite": "Piranha Plant", "x": 8, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Goomba", "x": 26, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Mushroom Block", "x": 1, "y": 11, "misc": 32}, + {"screen": 9, "sprite": "Goomba", "x": 1, "y": 20, "misc": 32}, + {"screen": 9, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 16, "misc": 160}, + {"screen": 10, "sprite": "Paragoomba (Diagonal)", "x": 29, "y": 26, "misc": 160}, + {"screen": 11, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 26, "misc": 32}], + "Mario's Castle": [ + {"screen": 0, "sprite": "Mushroom Block", "x": 15, "y": 17, "misc": 32}, + {"screen": 1, "sprite": "Falling Bone Platform", "x": 14, "y": 27, "misc": 32}, + {"screen": 1, "sprite": "Falling Bone Platform", "x": 22, "y": 27, "misc": 32}, + {"screen": 1, "sprite": "Skull Platform", "x": 25, "y": 30, "misc": 64}, + {"screen": 1, "sprite": "Rising Bone Platform", "x": 30, "y": 28, "misc": 32}, + {"screen": 2, "sprite": "Skull Platform", "x": 5, "y": 30, "misc": 64}, + {"screen": 2, "sprite": "Falling Bone Platform", "x": 16, "y": 27, "misc": 32}, + {"screen": 2, "sprite": "Falling Bone Platform", "x": 24, "y": 27, "misc": 32}, + {"screen": 2, "sprite": "Skull Platform", "x": 29, "y": 30, "misc": 64}, + {"screen": 3, "sprite": "Rising Bone Platform", "x": 0, "y": 28, "misc": 32}, + {"screen": 3, "sprite": "Skull Platform", "x": 3, "y": 30, "misc": 64}, + {"screen": 3, "sprite": "Rising Bone Platform", "x": 18, "y": 28, "misc": 32}, + {"screen": 3, "sprite": "Skull Platform", "x": 25, "y": 30, "misc": 64}, + {"screen": 3, "sprite": "Falling Bone Platform", "x": 26, "y": 27, "misc": 32}, + {"screen": 3, "sprite": "Skull Platform", "x": 27, "y": 30, "misc": 64}, + {"screen": 4, "sprite": "Rising Bone Platform", "x": 2, "y": 28, "misc": 32}, + {"screen": 4, "sprite": "Genkottsu (1.5 Tiles)", "x": 22, "y": 31, "misc": 64}, + {"screen": 5, "sprite": "Genkottsu (2 Tiles)", "x": 6, "y": 31, "misc": 64}, + {"screen": 5, "sprite": "Karamenbo", "x": 14, "y": 20, "misc": 32}, + {"screen": 5, "sprite": "Karamenbo", "x": 20, "y": 20, "misc": 32}, + {"screen": 5, "sprite": "Genkottsu (2 Tiles)", "x": 22, "y": 31, "misc": 64}, + {"screen": 6, "sprite": "Karamenbo", "x": 1, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Karamenbo", "x": 8, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Karamenbo", "x": 21, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Propeller Platform", "x": 4, "y": 30, "misc": 64}, + {"screen": 7, "sprite": "Propeller Platform", "x": 16, "y": 30, "misc": 64}, + {"screen": 7, "sprite": "Floating Face", "x": 19, "y": 26, "misc": 32}, + {"screen": 8, "sprite": "Propeller Platform", "x": 4, "y": 30, "misc": 64}, + {"screen": 8, "sprite": "Floating Face", "x": 17, "y": 29, "misc": 32}, + {"screen": 8, "sprite": "Floating Face", "x": 17, "y": 23, "misc": 32}, + {"screen": 8, "sprite": "Propeller Platform", "x": 18, "y": 30, "misc": 64}, + {"screen": 9, "sprite": "Floating Face", "x": 15, "y": 28, "misc": 32}, + {"screen": 9, "sprite": "Floating Face", "x": 16, "y": 22, "misc": 32}, + {"screen": 10, "sprite": "Mushroom Block", "x": 1, "y": 23, "misc": 64}, + {"screen": 10, "sprite": "Spike Ball (Large)", "x": 11, "y": 28, "misc": 64}, + {"screen": 10, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 10, "sprite": "Spike Ball (Small)", "x": 29, "y": 30, "misc": 64}, + {"screen": 11, "sprite": "Fire Pakkun Zo (Left)", "x": 8, "y": 28, "misc": 192}, + {"screen": 11, "sprite": "Fire Pakkun Zo (Left)", "x": 14, "y": 26, "misc": 64}, + {"screen": 11, "sprite": "Spike Ball (Large)", "x": 31, "y": 30, "misc": 192}, + {"screen": 12, "sprite": "Fire Pakkun Zo (Large)", "x": 15, "y": 26, "misc": 64}, + {"screen": 12, "sprite": "Fire Pakkun Zo (Left)", "x": 24, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Fire Pakkun Zo (Left)", "x": 0, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Fire Pakkun Zo (Left)", "x": 8, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Spike Ball (Large)", "x": 29, "y": 30, "misc": 64}, + {"screen": 14, "sprite": "Spike Ball (Small)", "x": 12, "y": 26, "misc": 192}, + {"screen": 15, "sprite": "Fire Pakkun Zo (Right)", "x": 4, "y": 16, "misc": 64}, + {"screen": 15, "sprite": "Mushroom Block", "x": 15, "y": 19, "misc": 32}], + "Scenic Course": [ + {"screen": 1, "sprite": "Paragoomba (Diagonal)", "x": 1, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 11, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Paragoomba (Diagonal)", "x": 21, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 31, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Paragoomba (Diagonal)", "x": 9, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 2, "sprite": "Goomba", "x": 19, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Paragoomba (Diagonal)", "x": 29, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Diagonal)", "x": 7, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Goomba", "x": 17, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Star Block", "x": 19, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Diagonal)", "x": 27, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Goomba", "x": 5, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Goomba", "x": 15, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Mushroom Block", "x": 17, "y": 23, "misc": 32}, + {"screen": 4, "sprite": "Paragoomba (Diagonal)", "x": 25, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Paragoomba (Diagonal)", "x": 3, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 17, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 1, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Paragoomba (Diagonal)", "x": 11, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 21, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Paragoomba (Diagonal)", "x": 31, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Paragoomba (Diagonal)", "x": 9, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Flower Block", "x": 11, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Paragoomba (Diagonal)", "x": 19, "y": 30, "misc": 32}], + "Turtle Zone Secret Course": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 7, "y": 21, "misc": 32}, + {"screen": 1, "sprite": "Heart Block", "x": 27, "y": 15, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 29, "y": 28, "misc": 32}, + {"screen": 3, "sprite": "Flower Block", "x": 11, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Money Bag Block", "x": 1, "y": 19, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 31, "y": 28, "misc": 32}, + {"screen": 5, "sprite": "Carrot Block", "x": 15, "y": 21, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 1, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Piranha Plant", "x": 6, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Mushroom Block", "x": 19, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Flower Block", "x": 21, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Carrot Block", "x": 23, "y": 23, "misc": 32}], + "Pumpkin Zone Secret Course 1": [ + {"screen": 0, "sprite": "Carrot Block", "x": 29, "y": 29, "misc": 0}, + {"screen": 1, "sprite": "Paragoomba (Vertical)", "x": 22, "y": 0, "misc": 32}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 14, "y": 2, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 6, "y": 4, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 30, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 23, "y": 4, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 15, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 25, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 19, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 29, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Goomba", "x": 11, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Goomba", "x": 29, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Goomba", "x": 15, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Star", "x": 25, "y": 24, "misc": 32}], + "Space Zone Secret Course": [ + {"screen": 2, "sprite": "Rerere/Poro", "x": 2, "y": 2, "misc": 32}, + {"screen": 3, "sprite": "Rerere/Poro", "x": 14, "y": 20, "misc": 0}, + {"screen": 4, "sprite": "Heart", "x": 3, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Heart", "x": 5, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Rerere/Poro", "x": 26, "y": 2, "misc": 32}, + {"screen": 5, "sprite": "Heart Block", "x": 21, "y": 19, "misc": 0}], + "Tree Zone Secret Course": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 3, "y": 13, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 9, "y": 24, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 13, "y": 14, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 25, "y": 16, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 3, "y": 20, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 19, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 27, "y": 22, "misc": 32}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 11, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 19, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 31, "y": 26, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 9, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 17, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 25, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 1, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 11, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 17, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 29, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Heart Block", "x": 9, "y": 13, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 17, "y": 26, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 27, "y": 26, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 1, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 11, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 21, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 31, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 7, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 17, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 27, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Koopa Troopa", "x": 5, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Koopa Troopa", "x": 13, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Koopa Troopa", "x": 21, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Heart Block", "x": 31, "y": 13, "misc": 32}], + "Macro Zone Secret Course": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 11, "y": 15, "misc": 32}, + {"screen": 1, "sprite": "Falling Platform", "x": 28, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Falling Platform", "x": 12, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Falling Platform", "x": 18, "y": 26, "misc": 32}, + {"screen": 3, "sprite": "Heart Block", "x": 11, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Flower Block", "x": 17, "y": 17, "misc": 32}, + {"screen": 6, "sprite": "Heart Block", "x": 25, "y": 27, "misc": 32}], + "Pumpkin Zone Secret Course 2": [ + {"screen": 0, "sprite": "Flower Block", "x": 25, "y": 11, "misc": 0}, + {"screen": 1, "sprite": "Heart Block", "x": 9, "y": 17, "misc": 0}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 16, "y": 20, "misc": 0}, + {"screen": 1, "sprite": "Heart Block", "x": 23, "y": 15, "misc": 0}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 29, "y": 20, "misc": 0}, + {"screen": 2, "sprite": "Heart Block", "x": 5, "y": 13, "misc": 0}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 13, "y": 20, "misc": 0}, + {"screen": 2, "sprite": "Goomba", "x": 21, "y": 20, "misc": 0}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 31, "y": 20, "misc": 0}, + {"screen": 3, "sprite": "Heart Block", "x": 17, "y": 17, "misc": 0}, + {"screen": 3, "sprite": "Heart Block", "x": 25, "y": 13, "misc": 0}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 1, "y": 20, "misc": 0}, + {"screen": 4, "sprite": "Falling Platform", "x": 18, "y": 24, "misc": 0}, + {"screen": 5, "sprite": "Falling Platform", "x": 2, "y": 22, "misc": 0}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 10, "y": 22, "misc": 0}, + {"screen": 5, "sprite": "Mushroom Block", "x": 11, "y": 15, "misc": 0}, + {"screen": 5, "sprite": "Falling Platform", "x": 18, "y": 24, "misc": 0}, + {"screen": 5, "sprite": "Falling Platform", "x": 26, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Falling Platform", "x": 2, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Falling Platform", "x": 10, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Falling Platform", "x": 18, "y": 24, "misc": 0}, + {"screen": 7, "sprite": "Goomba", "x": 13, "y": 18, "misc": 0}, + {"screen": 7, "sprite": "Heart Block", "x": 15, "y": 17, "misc": 0}, + {"screen": 7, "sprite": "Goomba", "x": 29, "y": 18, "misc": 0}, + {"screen": 8, "sprite": "Heart Block", "x": 9, "y": 17, "misc": 0}, + {"screen": 8, "sprite": "Goomba", "x": 11, "y": 18, "misc": 0}, + {"screen": 8, "sprite": "Heart Block", "x": 23, "y": 17, "misc": 0}, + {"screen": 8, "sprite": "Goomba", "x": 25, "y": 18, "misc": 0}, + {"screen": 9, "sprite": "Falling Platform", "x": 12, "y": 20, "misc": 0}, + {"screen": 9, "sprite": "Heart", "x": 23, "y": 16, "misc": 0}, + {"screen": 10, "sprite": "Falling Platform", "x": 0, "y": 22, "misc": 0}, + {"screen": 10, "sprite": "Heart", "x": 17, "y": 14, "misc": 0}]}