diff --git a/Launcher.py b/Launcher.py index 8a3d53f8..9f9aaa4f 100644 --- a/Launcher.py +++ b/Launcher.py @@ -132,7 +132,7 @@ components: Iterable[Component] = ( Component('Text Client', 'CommonClient', 'ArchipelagoTextClient'), # SNI Component('SNI Client', 'SNIClient', - file_identifier=SuffixIdentifier('.apz3', '.apm3', '.apsoe', '.aplttp', '.apsm', '.apsmz3', '.apdkc3')), + file_identifier=SuffixIdentifier('.apz3', '.apm3', '.apsoe', '.aplttp', '.apsm', '.apsmz3', '.apdkc3', '.apsmw')), Component('LttP Adjuster', 'LttPAdjuster'), # Factorio Component('Factorio Client', 'FactorioClient'), diff --git a/Patch.py b/Patch.py index 9b2c88a6..6ac75dc9 100644 --- a/Patch.py +++ b/Patch.py @@ -171,6 +171,7 @@ GAME_SM = "Super Metroid" GAME_SOE = "Secret of Evermore" GAME_SMZ3 = "SMZ3" GAME_DKC3 = "Donkey Kong Country 3" +GAME_SMW = "Super Mario World" supported_games = {"A Link to the Past", "Super Metroid", "Secret of Evermore", "SMZ3", "Donkey Kong Country 3"} preferred_endings = { diff --git a/README.md b/README.md index c8362ddd..a8228203 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Currently, the following games are supported: * Starcraft 2: Wings of Liberty * Donkey Kong Country 3 * Dark Souls 3 +* Super Mario World For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/SNIClient.py b/SNIClient.py index 477cde86..9170c845 100644 --- a/SNIClient.py +++ b/SNIClient.py @@ -30,7 +30,7 @@ from worlds.sm.Rom import ROM_PLAYER_LIMIT as SM_ROM_PLAYER_LIMIT from worlds.smz3.Rom import ROM_PLAYER_LIMIT as SMZ3_ROM_PLAYER_LIMIT import Utils from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser -from Patch import GAME_ALTTP, GAME_SM, GAME_SMZ3, GAME_DKC3 +from Patch import GAME_ALTTP, GAME_SM, GAME_SMZ3, GAME_DKC3, GAME_SMW snes_logger = logging.getLogger("SNES") @@ -236,6 +236,10 @@ async def deathlink_kill_player(ctx: Context): snes_buffered_write(ctx, WRAM_START + 0x0A50, bytes([255])) # deal 255 of damage at next opportunity if not ctx.death_link_allow_survive: snes_buffered_write(ctx, WRAM_START + 0x09D6, bytes([0, 0])) # set current reserve to 0 + elif ctx.game == GAME_SMW: + from worlds.smw.Client import deathlink_kill_player as smw_deathlink_kill_player + await smw_deathlink_kill_player(ctx) + await snes_flush_writes(ctx) await asyncio.sleep(1) @@ -1041,6 +1045,9 @@ async def game_watcher(ctx: Context): from worlds.dkc3.Client import dkc3_rom_init init_handled = await dkc3_rom_init(ctx) + if not init_handled: + from worlds.smw.Client import smw_rom_init + init_handled = await smw_rom_init(ctx) if not init_handled: game_name = await snes_read(ctx, SM_ROMNAME_START, 5) if game_name is None: @@ -1299,6 +1306,9 @@ async def game_watcher(ctx: Context): elif ctx.game == GAME_DKC3: from worlds.dkc3.Client import dkc3_game_watcher await dkc3_game_watcher(ctx) + elif ctx.game == GAME_SMW: + from worlds.smw.Client import smw_game_watcher + await smw_game_watcher(ctx) async def run_game(romfile): diff --git a/Utils.py b/Utils.py index 93627ffd..c5fc0003 100644 --- a/Utils.py +++ b/Utils.py @@ -288,6 +288,11 @@ def get_default_options() -> OptionsType: "sni": "SNI", "rom_start": True, }, + "smw_options": { + "rom_file": "Super Mario World (USA).sfc", + "sni": "SNI", + "rom_start": True, + }, } return options diff --git a/host.yaml b/host.yaml index 901e6cd7..b1141355 100644 --- a/host.yaml +++ b/host.yaml @@ -138,3 +138,12 @@ dkc3_options: # True for operating system default program # Alternatively, a path to a program to open the .sfc file with rom_start: true +smw_options: + # File name of the SMW US rom + rom_file: "Super Mario World (USA).sfc" + # Set this to your SNI folder location if you want the MultiClient to attempt an auto start, does nothing if not found + sni: "SNI" + # Set this to false to never autostart a rom (such as after patching) + # True for operating system default program + # Alternatively, a path to a program to open the .sfc file with + rom_start: true diff --git a/inno_setup.iss b/inno_setup.iss index cfdfec7b..9a2a4044 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -55,6 +55,7 @@ Name: "core"; Description: "Core Files"; Types: full hosting playing Name: "generator"; Description: "Generator"; Types: full hosting Name: "generator/sm"; Description: "Super Metroid ROM Setup"; Types: full hosting; ExtraDiskSpaceRequired: 3145728; Flags: disablenouninstallwarning Name: "generator/dkc3"; Description: "Donkey Kong Country 3 ROM Setup"; Types: full hosting; ExtraDiskSpaceRequired: 3145728; Flags: disablenouninstallwarning +Name: "generator/smw"; Description: "Super Mario World ROM Setup"; Types: full hosting; ExtraDiskSpaceRequired: 3145728; Flags: disablenouninstallwarning Name: "generator/soe"; Description: "Secret of Evermore ROM Setup"; Types: full hosting; ExtraDiskSpaceRequired: 3145728; Flags: disablenouninstallwarning Name: "generator/lttp"; Description: "A Link to the Past ROM Setup and Enemizer"; Types: full hosting; ExtraDiskSpaceRequired: 5191680 Name: "generator/oot"; Description: "Ocarina of Time ROM Setup"; Types: full hosting; ExtraDiskSpaceRequired: 100663296; Flags: disablenouninstallwarning @@ -64,6 +65,7 @@ Name: "client/sni"; Description: "SNI Client"; Types: full playing Name: "client/sni/lttp"; Description: "SNI Client - A Link to the Past Patch Setup"; Types: full playing; Flags: disablenouninstallwarning Name: "client/sni/sm"; Description: "SNI Client - Super Metroid Patch Setup"; Types: full playing; Flags: disablenouninstallwarning Name: "client/sni/dkc3"; Description: "SNI Client - Donkey Kong Country 3 Patch Setup"; Types: full playing; Flags: disablenouninstallwarning +Name: "client/sni/smw"; Description: "SNI Client - Super Mario World Patch Setup"; Types: full playing; Flags: disablenouninstallwarning Name: "client/factorio"; Description: "Factorio"; Types: full playing Name: "client/minecraft"; Description: "Minecraft"; Types: full playing; ExtraDiskSpaceRequired: 226894278 Name: "client/oot"; Description: "Ocarina of Time"; Types: full playing @@ -79,6 +81,7 @@ NAME: "{app}"; Flags: setntfscompression; Permissions: everyone-modify users-mod Source: "{code:GetROMPath}"; DestDir: "{app}"; DestName: "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"; Flags: external; Components: client/sni/lttp or generator/lttp Source: "{code:GetSMROMPath}"; DestDir: "{app}"; DestName: "Super Metroid (JU).sfc"; Flags: external; Components: client/sni/sm or generator/sm Source: "{code:GetDKC3ROMPath}"; DestDir: "{app}"; DestName: "Donkey Kong Country 3 - Dixie Kong's Double Trouble! (USA) (En,Fr).sfc"; Flags: external; Components: client/sni/dkc3 or generator/dkc3 +Source: "{code:GetSMWROMPath}"; DestDir: "{app}"; DestName: "Super Mario World (USA).sfc"; Flags: external; Components: client/sni/smw or generator/smw Source: "{code:GetSoEROMPath}"; DestDir: "{app}"; DestName: "Secret of Evermore (USA).sfc"; Flags: external; Components: generator/soe Source: "{code:GetOoTROMPath}"; DestDir: "{app}"; DestName: "The Legend of Zelda - Ocarina of Time.z64"; Flags: external; Components: client/oot or generator/oot Source: "{#source_path}\*"; Excludes: "*.sfc, *.log, data\sprites\alttpr, SNI, EnemizerCLI, Archipelago*.exe"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs @@ -151,6 +154,11 @@ Root: HKCR; Subkey: "{#MyAppName}dkc3patch"; ValueData: "Arc Root: HKCR; Subkey: "{#MyAppName}dkc3patch\DefaultIcon"; ValueData: "{app}\ArchipelagoSNIClient.exe,0"; ValueType: string; ValueName: ""; Components: client/sni Root: HKCR; Subkey: "{#MyAppName}dkc3patch\shell\open\command"; ValueData: """{app}\ArchipelagoSNIClient.exe"" ""%1"""; ValueType: string; ValueName: ""; Components: client/sni +Root: HKCR; Subkey: ".apsmw"; ValueData: "{#MyAppName}smwpatch"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; Components: client/sni +Root: HKCR; Subkey: "{#MyAppName}smwpatch"; ValueData: "Archipelago Super Mario World Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; Components: client/sni +Root: HKCR; Subkey: "{#MyAppName}smwpatch\DefaultIcon"; ValueData: "{app}\ArchipelagoSNIClient.exe,0"; ValueType: string; ValueName: ""; Components: client/sni +Root: HKCR; Subkey: "{#MyAppName}smwpatch\shell\open\command"; ValueData: """{app}\ArchipelagoSNIClient.exe"" ""%1"""; ValueType: string; ValueName: ""; Components: client/sni + Root: HKCR; Subkey: ".apsmz3"; ValueData: "{#MyAppName}smz3patch"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; Components: client/sni Root: HKCR; Subkey: "{#MyAppName}smz3patch"; ValueData: "Archipelago SMZ3 Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; Components: client/sni Root: HKCR; Subkey: "{#MyAppName}smz3patch\DefaultIcon"; ValueData: "{app}\ArchipelagoSNIClient.exe,0"; ValueType: string; ValueName: ""; Components: client/sni @@ -217,6 +225,9 @@ var SMRomFilePage: TInputFileWizardPage; var dkc3rom: string; var DKC3RomFilePage: TInputFileWizardPage; +var smwrom: string; +var SMWRomFilePage: TInputFileWizardPage; + var soerom: string; var SoERomFilePage: TInputFileWizardPage; @@ -308,6 +319,8 @@ begin Result := not (SMROMFilePage.Values[0] = '') else if (assigned(DKC3ROMFilePage)) and (CurPageID = DKC3ROMFilePage.ID) then Result := not (DKC3ROMFilePage.Values[0] = '') + else if (assigned(SMWROMFilePage)) and (CurPageID = SMWROMFilePage.ID) then + Result := not (SMWROMFilePage.Values[0] = '') else if (assigned(SoEROMFilePage)) and (CurPageID = SoEROMFilePage.ID) then Result := not (SoEROMFilePage.Values[0] = '') else if (assigned(OoTROMFilePage)) and (CurPageID = OoTROMFilePage.ID) then @@ -364,6 +377,22 @@ begin Result := ''; end; +function GetSMWROMPath(Param: string): string; +begin + if Length(smwrom) > 0 then + Result := smwrom + else if Assigned(SMWRomFilePage) then + begin + R := CompareStr(GetSNESMD5OfFile(SMWROMFilePage.Values[0]), 'cdd3c8c37322978ca8669b34bc89c804') + if R <> 0 then + MsgBox('Super Mario World ROM validation failed. Very likely wrong file.', mbInformation, MB_OK); + + Result := SMWROMFilePage.Values[0] + end + else + Result := ''; + end; + function GetSoEROMPath(Param: string): string; begin if Length(soerom) > 0 then @@ -412,6 +441,10 @@ begin if Length(dkc3rom) = 0 then DKC3RomFilePage:= AddRomPage('Donkey Kong Country 3 - Dixie Kong''s Double Trouble! (USA) (En,Fr).sfc'); + smwrom := CheckRom('Super Mario World (USA).sfc', 'cdd3c8c37322978ca8669b34bc89c804'); + if Length(smwrom) = 0 then + SMWRomFilePage:= AddRomPage('Super Mario World (USA).sfc'); + soerom := CheckRom('Secret of Evermore (USA).sfc', '6e9c94511d04fac6e0a1e582c170be3a'); if Length(soerom) = 0 then SoEROMFilePage:= AddRomPage('Secret of Evermore (USA).sfc'); @@ -427,6 +460,8 @@ begin Result := not (WizardIsComponentSelected('client/sni/sm') or WizardIsComponentSelected('generator/sm')); if (assigned(DKC3ROMFilePage)) and (PageID = DKC3ROMFilePage.ID) then Result := not (WizardIsComponentSelected('client/sni/dkc3') or WizardIsComponentSelected('generator/dkc3')); + if (assigned(SMWROMFilePage)) and (PageID = SMWROMFilePage.ID) then + Result := not (WizardIsComponentSelected('client/sni/smw') or WizardIsComponentSelected('generator/smw')); if (assigned(SoEROMFilePage)) and (PageID = SoEROMFilePage.ID) then Result := not (WizardIsComponentSelected('generator/soe')); if (assigned(OoTROMFilePage)) and (PageID = OoTROMFilePage.ID) then diff --git a/worlds/smw/Aesthetics.py b/worlds/smw/Aesthetics.py new file mode 100644 index 00000000..624440c5 --- /dev/null +++ b/worlds/smw/Aesthetics.py @@ -0,0 +1,202 @@ + +mario_palettes = [ + [0x5F, 0x63, 0x1D, 0x58, 0x0A, 0x00, 0x1F, 0x39, 0xC4, 0x44, 0x08, 0x4E, 0x70, 0x67, 0xB6, 0x30, 0xDF, 0x35, 0xFF, 0x03], # Mario + [0x3F, 0x4F, 0x1D, 0x58, 0x40, 0x11, 0xE0, 0x3F, 0x07, 0x3C, 0xAE, 0x7C, 0xB3, 0x7D, 0x00, 0x2F, 0x5F, 0x16, 0xFF, 0x03], # Luigi + [0x5F, 0x63, 0x1D, 0x58, 0x0A, 0x00, 0x1F, 0x03, 0xC4, 0x44, 0x08, 0x4E, 0x70, 0x67, 0x16, 0x02, 0xDF, 0x35, 0xFF, 0x03], # Wario + [0x5F, 0x63, 0x1D, 0x58, 0x0A, 0x00, 0x12, 0x7C, 0xC4, 0x44, 0x08, 0x4E, 0x70, 0x67, 0x0D, 0x58, 0xDF, 0x35, 0xFF, 0x03], # Waluigi + [0x5F, 0x63, 0x1D, 0x58, 0x0A, 0x00, 0x00, 0x7C, 0xC4, 0x44, 0x08, 0x4E, 0x70, 0x67, 0x00, 0x58, 0xDF, 0x35, 0xFF, 0x03], # Geno + [0x5F, 0x63, 0x1D, 0x58, 0x0A, 0x00, 0x1F, 0x7C, 0xC4, 0x44, 0x08, 0x4E, 0x70, 0x67, 0x16, 0x58, 0xDF, 0x35, 0xFF, 0x03], # Princess + [0x5F, 0x63, 0x1D, 0x58, 0x0A, 0x00, 0xE0, 0x00, 0xC4, 0x44, 0x08, 0x4E, 0x70, 0x67, 0x80, 0x00, 0xDF, 0x35, 0xFF, 0x03], # Dark + [0x5F, 0x63, 0x1D, 0x58, 0x0A, 0x00, 0xFF, 0x01, 0xC4, 0x44, 0x08, 0x4E, 0x70, 0x67, 0x5F, 0x01, 0xDF, 0x35, 0xFF, 0x03], # Sponge +] + +fire_mario_palettes = [ + [0x5F, 0x63, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x08, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Mario + [0x1F, 0x3B, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x40, 0x11, 0xE0, 0x01, 0xE0, 0x02, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Luigi + [0x5F, 0x63, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x08, 0x00, 0x16, 0x02, 0x1F, 0x03, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Wario + [0x5F, 0x63, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x08, 0x00, 0x0D, 0x58, 0x12, 0x7C, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Waluigi + [0x5F, 0x63, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x08, 0x00, 0x00, 0x58, 0x00, 0x7C, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Geno + [0x5F, 0x63, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x08, 0x00, 0x16, 0x58, 0x1F, 0x7C, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Princess + [0x5F, 0x63, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x08, 0x00, 0x80, 0x00, 0xE0, 0x00, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Dark + [0x5F, 0x63, 0x1D, 0x58, 0x29, 0x25, 0xFF, 0x7F, 0x08, 0x00, 0x5F, 0x01, 0xFF, 0x01, 0x7B, 0x57, 0xDF, 0x0D, 0xFF, 0x03], # Sponge +] + +ow_mario_palettes = [ + [0x16, 0x00, 0x1F, 0x00], # Mario + [0x80, 0x02, 0xE0, 0x03], # Luigi + [0x16, 0x02, 0x1F, 0x03], # Wario + [0x0D, 0x58, 0x12, 0x7C], # Waluigi + [0x00, 0x58, 0x00, 0x7C], # Geno + [0x16, 0x58, 0x1F, 0x7C], # Princess + [0x80, 0x00, 0xE0, 0x00], # Dark + [0x5F, 0x01, 0xFF, 0x01], # Sponge +] + +level_music_address_data = [ + 0x284DB, + 0x284DC, + 0x284DD, + 0x284DE, + 0x284DF, + 0x284E0, + 0x284E1, + 0x284E2, +] + +level_music_value_data = [ + 0x02, + 0x06, + 0x01, + 0x08, + 0x07, + 0x03, + 0x05, + 0x12, +] + +ow_music_address_data = [ + [0x25BC8, 0x20D8A], + [0x25BC9, 0x20D8B], + [0x25BCA, 0x20D8C], + [0x25BCB, 0x20D8D], + [0x25BCC, 0x20D8E], + [0x25BCD, 0x20D8F], + [0x25BCE, 0x20D90], + [0x16C7] +] + +ow_music_value_data = [ + 0x02, + 0x03, + 0x04, + 0x06, + 0x07, + 0x09, + 0x05, + 0x01, +] + +valid_foreground_palettes = { + 0x00: [0x00, 0x01, 0x03, 0x04, 0x05, 0x07], # Normal 1 + 0x01: [0x03, 0x04, 0x05, 0x07], # Castle 1 + 0x02: [0x01, 0x02, 0x03, 0x04, 0x05, 0x07], # Rope 1 + 0x03: [0x02, 0x03, 0x04, 0x05, 0x07], # Underground 1 + 0x04: [0x01, 0x02, 0x03, 0x04, 0x05, 0x07], # Switch Palace 1 + 0x05: [0x04, 0x05], # Ghost House 1 + 0x06: [0x01, 0x02, 0x03, 0x04, 0x05, 0x07], # Rope 2 + 0x07: [0x00, 0x01, 0x03, 0x04, 0x05, 0x07], # Normal 2 + 0x08: [0x01, 0x02, 0x03, 0x04, 0x05, 0x07], # Rope 3 + 0x09: [0x01, 0x02, 0x03, 0x04, 0x05, 0x07], # Underground 2 + 0x0A: [0x01, 0x02, 0x03, 0x04, 0x05, 0x07], # Switch Palace 2 + 0x0B: [0x03, 0x04, 0x05, 0x07], # Castle 2 + #0x0C: [], # Cloud/Forest + 0x0D: [0x04, 0x05], # Ghost House 2 + 0x0E: [0x02, 0x03, 0x04, 0x05, 0x07], # Underground 3 +} + +valid_background_palettes = { + 0x06861B: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Ghost House Exit + 0xFFD900: [0x01], # P. Hills + 0xFFDAB9: [0x04], # Water + 0xFFDC71: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Hills & Clouds + 0xFFDD44: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Clouds + 0xFFDE54: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Small Hills + 0xFFDF59: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Mountains & Clouds + 0xFFE103: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Castle Pillars + 0xFFE472: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Big Hills + 0xFFE674: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Bonus + 0xFFE684: [0x01, 0x03, 0x05, 0x06], # Stars + 0xFFE7C0: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07], # Mountains + 0xFFE8EE: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Empty/Layer 2 + 0xFFE8FE: [0x01, 0x06], # Cave + 0xFFEC82: [0x00, 0x02, 0x03, 0x05, 0x06, 0x07], # Bushes + 0xFFEF80: [0x01, 0x03, 0x05, 0x06], # Ghost House + 0xFFF175: [0x00, 0x01, 0x02, 0x03, 0x05, 0x06], # Ghost Ship + 0xFFF45A: [0x01, 0x03, 0x06], # Castle +} + +valid_background_colors = { + 0x06861B: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Ghost House Exit + 0xFFD900: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # P. Hills + 0xFFDAB9: [0x02, 0x03, 0x05], # Water + 0xFFDC71: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Hills & Clouds + 0xFFDD44: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Clouds + 0xFFDE54: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Small Hills + 0xFFDF59: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Mountains & Clouds + 0xFFE103: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Castle Pillars + 0xFFE472: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Big Hills + 0xFFE674: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Bonus + 0xFFE684: [0x02, 0x03, 0x04, 0x05], # Stars + 0xFFE7C0: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Mountains + 0xFFE8EE: [0x03, 0x05], # Empty/Layer 2 + 0xFFE8FE: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Cave + 0xFFEC82: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Bushes + 0xFFEF80: [0x03, 0x04], # Ghost House + 0xFFF175: [0x02, 0x03, 0x04, 0x05], # Ghost Ship + 0xFFF45A: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], # Castle +} + +def generate_shuffled_level_music(world, player): + shuffled_level_music = level_music_value_data.copy() + + if world.music_shuffle[player] == "consistent": + world.random.shuffle(shuffled_level_music) + elif world.music_shuffle[player] == "singularity": + single_song = world.random.choice(shuffled_level_music) + shuffled_level_music = [single_song for i in range(len(shuffled_level_music))] + + return shuffled_level_music + +def generate_shuffled_ow_music(world, player): + shuffled_ow_music = ow_music_value_data.copy() + + if world.music_shuffle[player] == "consistent" or world.music_shuffle[player] == "full": + world.random.shuffle(shuffled_ow_music) + elif world.music_shuffle[player] == "singularity": + single_song = world.random.choice(shuffled_ow_music) + shuffled_ow_music = [single_song for i in range(len(shuffled_ow_music))] + + return shuffled_ow_music + +def generate_shuffled_header_data(rom, world, player): + if world.music_shuffle[player] != "full" and not world.foreground_palette_shuffle[player] and not world.background_palette_shuffle[player]: + return + + for level_id in range(0, 0x200): + layer1_ptr_list = list(rom.read_bytes(0x2E000 + level_id * 3, 3)) + layer1_ptr = (layer1_ptr_list[2] << 16 | layer1_ptr_list[1] << 8 | layer1_ptr_list[0]) + + if layer1_ptr == 0x68000: + # Unused Levels + continue + + if layer1_ptr >= 0x70000: + layer1_ptr -= 0x8000 + + layer1_ptr -= 0x38000 + + level_header = list(rom.read_bytes(layer1_ptr, 5)) + + tileset = level_header[4] & 0x0F + + if world.music_shuffle[player] == "full": + level_header[2] &= 0x8F + level_header[2] |= (world.random.randint(0, 7) << 5) + + if (world.foreground_palette_shuffle[player] and tileset in valid_foreground_palettes): + level_header[3] &= 0xF8 + level_header[3] |= world.random.choice(valid_foreground_palettes[tileset]) + + if world.background_palette_shuffle[player]: + layer2_ptr_list = list(rom.read_bytes(0x2E600 + level_id * 3, 3)) + layer2_ptr = (layer2_ptr_list[2] << 16 | layer2_ptr_list[1] << 8 | layer2_ptr_list[0]) + + if layer2_ptr in valid_background_palettes: + level_header[0] &= 0x1F + level_header[0] |= (world.random.choice(valid_background_palettes[layer2_ptr]) << 5) + + if layer2_ptr in valid_background_colors: + level_header[1] &= 0x1F + level_header[1] |= (world.random.choice(valid_background_colors[layer2_ptr]) << 5) + + rom.write_bytes(layer1_ptr, bytes(level_header)) diff --git a/worlds/smw/Client.py b/worlds/smw/Client.py new file mode 100644 index 00000000..6ddd4e10 --- /dev/null +++ b/worlds/smw/Client.py @@ -0,0 +1,455 @@ +import logging +import asyncio +import time + +from NetUtils import ClientStatus, color +from worlds import AutoWorldRegister +from SNIClient import Context, snes_buffered_write, snes_flush_writes, snes_read +from .Names.TextBox import generate_received_text +from Patch import GAME_SMW + +snes_logger = logging.getLogger("SNES") + +ROM_START = 0x000000 +WRAM_START = 0xF50000 +WRAM_SIZE = 0x20000 +SRAM_START = 0xE00000 + +SAVEDATA_START = WRAM_START + 0xF000 +SAVEDATA_SIZE = 0x500 + +SMW_ROMHASH_START = 0x7FC0 +ROMHASH_SIZE = 0x15 + +SMW_PROGRESS_DATA = WRAM_START + 0x1F02 +SMW_DRAGON_COINS_DATA = WRAM_START + 0x1F2F +SMW_PATH_DATA = WRAM_START + 0x1EA2 +SMW_EVENT_ROM_DATA = ROM_START + 0x2D608 +SMW_ACTIVE_LEVEL_DATA = ROM_START + 0x37F70 + +SMW_GOAL_DATA = ROM_START + 0x01BFA0 +SMW_REQUIRED_BOSSES_DATA = ROM_START + 0x01BFA1 +SMW_REQUIRED_EGGS_DATA = ROM_START + 0x01BFA2 +SMW_SEND_MSG_DATA = ROM_START + 0x01BFA3 +SMW_RECEIVE_MSG_DATA = ROM_START + 0x01BFA4 +SMW_DEATH_LINK_ACTIVE_ADDR = ROM_START + 0x01BFA5 +SMW_DRAGON_COINS_ACTIVE_ADDR = ROM_START + 0x01BFA6 +SMW_SWAMP_DONUT_GH_ADDR = ROM_START + 0x01BFA7 + +SMW_GAME_STATE_ADDR = WRAM_START + 0x100 +SMW_MARIO_STATE_ADDR = WRAM_START + 0x71 +SMW_BOSS_STATE_ADDR = WRAM_START + 0xD9B +SMW_ACTIVE_BOSS_ADDR = WRAM_START + 0x13FC +SMW_CURRENT_LEVEL_ADDR = WRAM_START + 0x13BF +SMW_MESSAGE_BOX_ADDR = WRAM_START + 0x1426 +SMW_BONUS_STAR_ADDR = WRAM_START + 0xF48 +SMW_EGG_COUNT_ADDR = WRAM_START + 0x1F24 +SMW_BOSS_COUNT_ADDR = WRAM_START + 0x1F26 +SMW_NUM_EVENTS_ADDR = WRAM_START + 0x1F2E +SMW_SFX_ADDR = WRAM_START + 0x1DFC +SMW_PAUSE_ADDR = WRAM_START + 0x13D4 +SMW_MESSAGE_QUEUE_ADDR = WRAM_START + 0xC391 + +SMW_RECV_PROGRESS_ADDR = WRAM_START + 0x1F2B + +SMW_GOAL_LEVELS = [0x28, 0x31, 0x32] +SMW_INVALID_MARIO_STATES = [0x05, 0x06, 0x0A, 0x0C, 0x0D] +SMW_BAD_TEXT_BOX_LEVELS = [0x26, 0x02, 0x4B] +SMW_BOSS_STATES = [0x80, 0xC0, 0xC1] +SMW_UNCOLLECTABLE_LEVELS = [0x25, 0x07, 0x0B, 0x40, 0x0E, 0x1F, 0x20, 0x1B, 0x1A, 0x35, 0x34, 0x31, 0x32] + +async def deathlink_kill_player(ctx: Context): + if ctx.game == GAME_SMW: + game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1) + if game_state[0] != 0x14: + return + + mario_state = await snes_read(ctx, SMW_MARIO_STATE_ADDR, 0x1) + if mario_state[0] != 0x00: + return + + message_box = await snes_read(ctx, SMW_MESSAGE_BOX_ADDR, 0x1) + if message_box[0] != 0x00: + return + + pause_state = await snes_read(ctx, SMW_PAUSE_ADDR, 0x1) + if pause_state[0] != 0x00: + return + + snes_buffered_write(ctx, WRAM_START + 0x9D, bytes([0x30])) # Freeze Gameplay + snes_buffered_write(ctx, WRAM_START + 0x1DFB, bytes([0x09])) # Death Music + snes_buffered_write(ctx, WRAM_START + 0x0DDA, bytes([0xFF])) # Flush Music Buffer + snes_buffered_write(ctx, WRAM_START + 0x1407, bytes([0x00])) # Flush Cape Fly Phase + snes_buffered_write(ctx, WRAM_START + 0x140D, bytes([0x00])) # Flush Spin Jump Flag + snes_buffered_write(ctx, WRAM_START + 0x188A, bytes([0x00])) # Flush Empty Byte because the game does it + snes_buffered_write(ctx, WRAM_START + 0x7D, bytes([0x90])) # Mario Y Speed + snes_buffered_write(ctx, WRAM_START + 0x1496, bytes([0x30])) # Death Timer + snes_buffered_write(ctx, SMW_MARIO_STATE_ADDR, bytes([0x09])) # Mario State -> Dead + + await snes_flush_writes(ctx) + + from SNIClient import DeathState + ctx.death_state = DeathState.dead + ctx.last_death_link = time.time() + + return + + +async def smw_rom_init(ctx: Context): + if not ctx.rom: + ctx.finished_game = False + ctx.death_link_allow_survive = False + game_hash = await snes_read(ctx, SMW_ROMHASH_START, ROMHASH_SIZE) + if game_hash is None or game_hash == bytes([0] * ROMHASH_SIZE) or game_hash[:3] != b"SMW": + return False + else: + ctx.game = GAME_SMW + ctx.items_handling = 0b111 # remote items + + ctx.rom = game_hash + + receive_option = await snes_read(ctx, SMW_RECEIVE_MSG_DATA, 0x1) + send_option = await snes_read(ctx, SMW_SEND_MSG_DATA, 0x1) + + ctx.receive_option = receive_option[0] + ctx.send_option = send_option[0] + + ctx.message_queue = [] + + ctx.allow_collect = True + + death_link = await snes_read(ctx, SMW_DEATH_LINK_ACTIVE_ADDR, 1) + if death_link: + await ctx.update_death_link(bool(death_link[0] & 0b1)) + return True + + +def add_message_to_queue(ctx: Context, new_message): + + if not hasattr(ctx, "message_queue"): + ctx.message_queue = [] + + ctx.message_queue.append(new_message) + + return + + +async def handle_message_queue(ctx: Context): + + game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1) + if game_state[0] != 0x14: + return + + mario_state = await snes_read(ctx, SMW_MARIO_STATE_ADDR, 0x1) + if mario_state[0] != 0x00: + return + + message_box = await snes_read(ctx, SMW_MESSAGE_BOX_ADDR, 0x1) + if message_box[0] != 0x00: + return + + pause_state = await snes_read(ctx, SMW_PAUSE_ADDR, 0x1) + if pause_state[0] != 0x00: + return + + current_level = await snes_read(ctx, SMW_CURRENT_LEVEL_ADDR, 0x1) + if current_level[0] in SMW_BAD_TEXT_BOX_LEVELS: + return + + boss_state = await snes_read(ctx, SMW_BOSS_STATE_ADDR, 0x1) + if boss_state[0] in SMW_BOSS_STATES: + return + + active_boss = await snes_read(ctx, SMW_ACTIVE_BOSS_ADDR, 0x1) + if active_boss[0] != 0x00: + return + + if not hasattr(ctx, "message_queue") or len(ctx.message_queue) == 0: + return + + next_message = ctx.message_queue.pop(0) + + snes_buffered_write(ctx, SMW_MESSAGE_QUEUE_ADDR, bytes(next_message)) + snes_buffered_write(ctx, SMW_MESSAGE_BOX_ADDR, bytes([0x03])) + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([0x22])) + + await snes_flush_writes(ctx) + + return + + +async def smw_game_watcher(ctx: Context): + if ctx.game == GAME_SMW: + # SMW_TODO: Handle Deathlink + game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1) + mario_state = await snes_read(ctx, SMW_MARIO_STATE_ADDR, 0x1) + if game_state is None: + # We're not properly connected + return + elif game_state[0] >= 0x18: + if not ctx.finished_game: + current_level = await snes_read(ctx, SMW_CURRENT_LEVEL_ADDR, 0x1) + + if current_level[0] in SMW_GOAL_LEVELS: + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True + return + elif game_state[0] < 0x0B: + # We haven't loaded a save file + ctx.message_queue = [] + return + elif mario_state[0] in SMW_INVALID_MARIO_STATES: + # Mario can't come to the phone right now + return + + if "DeathLink" in ctx.tags and game_state[0] == 0x14 and ctx.last_death_link + 1 < time.time(): + currently_dead = mario_state[0] == 0x09 + await ctx.handle_deathlink_state(currently_dead) + + # Check for Egg Hunt ending + goal = await snes_read(ctx, SMW_GOAL_DATA, 0x1) + if game_state[0] == 0x14 and goal[0] == 1: + current_level = await snes_read(ctx, SMW_CURRENT_LEVEL_ADDR, 0x1) + message_box = await snes_read(ctx, SMW_MESSAGE_BOX_ADDR, 0x1) + egg_count = await snes_read(ctx, SMW_EGG_COUNT_ADDR, 0x1) + required_egg_count = await snes_read(ctx, SMW_REQUIRED_EGGS_DATA, 0x1) + + if current_level[0] == 0x28 and message_box[0] == 0x01 and egg_count[0] >= required_egg_count[0]: + snes_buffered_write(ctx, WRAM_START + 0x13C6, bytes([0x08])) + snes_buffered_write(ctx, WRAM_START + 0x13CE, bytes([0x01])) + snes_buffered_write(ctx, WRAM_START + 0x1DE9, bytes([0x01])) + snes_buffered_write(ctx, SMW_GAME_STATE_ADDR, bytes([0x18])) + + await snes_flush_writes(ctx) + return + + egg_count = await snes_read(ctx, SMW_EGG_COUNT_ADDR, 0x1) + boss_count = await snes_read(ctx, SMW_BOSS_COUNT_ADDR, 0x1) + display_count = await snes_read(ctx, SMW_BONUS_STAR_ADDR, 0x1) + + if goal[0] == 0 and boss_count[0] > display_count[0]: + snes_buffered_write(ctx, SMW_BONUS_STAR_ADDR, bytes([boss_count[0]])) + await snes_flush_writes(ctx) + elif goal[0] == 1 and egg_count[0] > display_count[0]: + snes_buffered_write(ctx, SMW_BONUS_STAR_ADDR, bytes([egg_count[0]])) + await snes_flush_writes(ctx) + + await handle_message_queue(ctx) + + new_checks = [] + event_data = await snes_read(ctx, SMW_EVENT_ROM_DATA, 0x60) + progress_data = bytearray(await snes_read(ctx, SMW_PROGRESS_DATA, 0x0F)) + dragon_coins_data = bytearray(await snes_read(ctx, SMW_DRAGON_COINS_DATA, 0x0C)) + dragon_coins_active = await snes_read(ctx, SMW_DRAGON_COINS_ACTIVE_ADDR, 0x1) + from worlds.smw.Rom import item_rom_data, ability_rom_data + from worlds.smw.Levels import location_id_to_level_id, level_info_dict + for loc_name, level_data in location_id_to_level_id.items(): + loc_id = AutoWorldRegister.world_types[ctx.game].location_name_to_id[loc_name] + if loc_id not in ctx.locations_checked: + + event_id = event_data[level_data[0]] + + if level_data[1] == 2: + # Dragon Coins Check + if not dragon_coins_active or dragon_coins_active[0] == 0: + continue + + progress_byte = (level_data[0] // 8) + progress_bit = 7 - (level_data[0] % 8) + + data = dragon_coins_data[progress_byte] + masked_data = data & (1 << progress_bit) + bit_set = (masked_data != 0) + + if bit_set: + # SMW_TODO: Handle non-included checks + new_checks.append(loc_id) + else: + event_id_value = event_id + level_data[1] + + progress_byte = (event_id_value // 8) + progress_bit = 7 - (event_id_value % 8) + + data = progress_data[progress_byte] + masked_data = data & (1 << progress_bit) + bit_set = (masked_data != 0) + + if bit_set: + # SMW_TODO: Handle non-included checks + new_checks.append(loc_id) + + verify_game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1) + if verify_game_state is None or verify_game_state[0] < 0x0B or verify_game_state[0] > 0x29: + # We have somehow exited the save file (or worse) + print("Exit Save File") + return + + rom = await snes_read(ctx, SMW_ROMHASH_START, ROMHASH_SIZE) + if rom != ctx.rom: + ctx.rom = None + print("Exit ROM") + # We have somehow loaded a different ROM + return + + for new_check_id in new_checks: + ctx.locations_checked.add(new_check_id) + location = ctx.location_names[new_check_id] + snes_logger.info( + f'New Check: {location} ({len(ctx.locations_checked)}/{len(ctx.missing_locations) + len(ctx.checked_locations)})') + await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": [new_check_id]}]) + + if game_state[0] != 0x14: + # Don't receive items or collect locations outside of in-level mode + return + + recv_count = await snes_read(ctx, SMW_RECV_PROGRESS_ADDR, 1) + recv_index = recv_count[0] + + if recv_index < len(ctx.items_received): + item = ctx.items_received[recv_index] + recv_index += 1 + logging.info('Received %s from %s (%s) (%d/%d in list)' % ( + color(ctx.item_names[item.item], 'red', 'bold'), + color(ctx.player_names[item.player], 'yellow'), + ctx.location_names[item.location], recv_index, len(ctx.items_received))) + + if ctx.receive_option == 1 or (ctx.receive_option == 2 and ((item.flags & 1) != 0)): + if item.item != 0xBC0012: + # Don't send messages for Boss Tokens + item_name = ctx.item_names[item.item] + player_name = ctx.player_names[item.player] + + receive_message = generate_received_text(item_name, player_name) + add_message_to_queue(ctx, receive_message) + + snes_buffered_write(ctx, SMW_RECV_PROGRESS_ADDR, bytes([recv_index])) + if item.item in item_rom_data: + item_count = await snes_read(ctx, WRAM_START + item_rom_data[item.item][0], 0x1) + increment = item_rom_data[item.item][1] + + new_item_count = item_count[0] + if increment > 1: + new_item_count = increment + else: + new_item_count += increment + + if verify_game_state[0] == 0x14 and len(item_rom_data[item.item]) > 2: + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([item_rom_data[item.item][2]])) + + snes_buffered_write(ctx, WRAM_START + item_rom_data[item.item][0], bytes([new_item_count])) + elif item.item in ability_rom_data: + # Handle Upgrades + for rom_data in ability_rom_data[item.item]: + data = await snes_read(ctx, WRAM_START + rom_data[0], 1) + masked_data = data[0] | (1 << rom_data[1]) + snes_buffered_write(ctx, WRAM_START + rom_data[0], bytes([masked_data])) + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([0x3E])) # SMW_TODO: Custom sounds for each + elif item.item == 0xBC000A: + # Handle Progressive Powerup + data = await snes_read(ctx, WRAM_START + 0x1F2D, 1) + mushroom_data = data[0] & (1 << 0) + fire_flower_data = data[0] & (1 << 1) + cape_data = data[0] & (1 << 2) + if mushroom_data == 0: + masked_data = data[0] | (1 << 0) + snes_buffered_write(ctx, WRAM_START + 0x1F2D, bytes([masked_data])) + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([0x3E])) + elif fire_flower_data == 0: + masked_data = data[0] | (1 << 1) + snes_buffered_write(ctx, WRAM_START + 0x1F2D, bytes([masked_data])) + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([0x3E])) + elif cape_data == 0: + masked_data = data[0] | (1 << 2) + snes_buffered_write(ctx, WRAM_START + 0x1F2D, bytes([masked_data])) + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([0x41])) + else: + # Extra Powerup? + pass + elif item.item == 0xBC0015: + # Handle Literature Trap + from .Names.LiteratureTrap import lit_trap_text_list + import random + rand_trap = random.choice(lit_trap_text_list) + + for message in rand_trap: + add_message_to_queue(ctx, message) + + await snes_flush_writes(ctx) + + # Handle Collected Locations + new_events = 0 + path_data = bytearray(await snes_read(ctx, SMW_PATH_DATA, 0x60)) + donut_gh_swapped = await snes_read(ctx, SMW_SWAMP_DONUT_GH_ADDR, 0x1) + new_dragon_coin = False + for loc_id in ctx.checked_locations: + if loc_id not in ctx.locations_checked: + ctx.locations_checked.add(loc_id) + loc_name = ctx.location_names[loc_id] + + if loc_name not in location_id_to_level_id: + continue + + level_data = location_id_to_level_id[loc_name] + + if level_data[1] == 2: + # Dragon Coins Check + + progress_byte = (level_data[0] // 8) + progress_bit = 7 - (level_data[0] % 8) + + data = dragon_coins_data[progress_byte] + new_data = data | (1 << progress_bit) + dragon_coins_data[progress_byte] = new_data + + new_dragon_coin = True + else: + if level_data[0] in SMW_UNCOLLECTABLE_LEVELS: + continue + + event_id = event_data[level_data[0]] + event_id_value = event_id + level_data[1] + + progress_byte = (event_id_value // 8) + progress_bit = 7 - (event_id_value % 8) + + data = progress_data[progress_byte] + masked_data = data & (1 << progress_bit) + bit_set = (masked_data != 0) + + if bit_set: + continue + + new_events += 1 + new_data = data | (1 << progress_bit) + progress_data[progress_byte] = new_data + + tile_id = await snes_read(ctx, SMW_ACTIVE_LEVEL_DATA + level_data[0], 0x1) + + level_info = level_info_dict[tile_id[0]] + + path = level_info.exit1Path if level_data[1] == 0 else level_info.exit2Path + + if donut_gh_swapped[0] != 0 and tile_id[0] == 0x04: + # Handle Swapped Donut GH Exits + path = level_info.exit2Path if level_data[1] == 0 else level_info.exit1Path + + if not path: + continue + + this_end_path = path_data[tile_id[0]] + new_data = this_end_path | path.thisEndDirection + path_data[tile_id[0]] = new_data + + other_end_path = path_data[path.otherLevelID] + new_data = other_end_path | path.otherEndDirection + path_data[path.otherLevelID] = new_data + + if new_dragon_coin: + snes_buffered_write(ctx, SMW_DRAGON_COINS_DATA, bytes(dragon_coins_data)) + if new_events > 0: + snes_buffered_write(ctx, SMW_PROGRESS_DATA, bytes(progress_data)) + snes_buffered_write(ctx, SMW_PATH_DATA, bytes(path_data)) + old_events = await snes_read(ctx, SMW_NUM_EVENTS_ADDR, 0x1) + snes_buffered_write(ctx, SMW_NUM_EVENTS_ADDR, bytes([old_events[0] + new_events])) + + await snes_flush_writes(ctx) diff --git a/worlds/smw/Items.py b/worlds/smw/Items.py new file mode 100644 index 00000000..e650aef4 --- /dev/null +++ b/worlds/smw/Items.py @@ -0,0 +1,69 @@ +import typing + +from BaseClasses import Item, ItemClassification +from .Names import ItemName + + +class ItemData(typing.NamedTuple): + code: typing.Optional[int] + progression: bool + trap: bool = False + quantity: int = 1 + event: bool = False + + +class SMWItem(Item): + game: str = "Super Mario World" + + +# Separate tables for each type of item. +junk_table = { + ItemName.one_up_mushroom: ItemData(0xBC0001, False), +} + +collectable_table = { + ItemName.yoshi_egg: ItemData(0xBC0002, True), +} + +upgrade_table = { + ItemName.mario_run: ItemData(0xBC0003, True), + ItemName.mario_carry: ItemData(0xBC0004, True), + ItemName.mario_swim: ItemData(0xBC0005, True), + ItemName.mario_spin_jump: ItemData(0xBC0006, True), + ItemName.mario_climb: ItemData(0xBC0007, True), + ItemName.yoshi_activate: ItemData(0xBC0008, True), + ItemName.p_switch: ItemData(0xBC0009, True), + ItemName.progressive_powerup: ItemData(0xBC000A, True), + ItemName.p_balloon: ItemData(0xBC000B, True), + ItemName.super_star_active: ItemData(0xBC000D, True), +} + +switch_palace_table = { + ItemName.yellow_switch_palace: ItemData(0xBC000E, True), + ItemName.green_switch_palace: ItemData(0xBC000F, True), + ItemName.red_switch_palace: ItemData(0xBC0010, True), + ItemName.blue_switch_palace: ItemData(0xBC0011, True), +} + +trap_table = { + ItemName.ice_trap: ItemData(0xBC0013, False, True), + ItemName.stun_trap: ItemData(0xBC0014, False, True), + ItemName.literature_trap: ItemData(0xBC0015, False, True), +} + +event_table = { + ItemName.victory: ItemData(0xBC0000, True), + ItemName.koopaling: ItemData(0xBC0012, True), +} + +# Complete item table. +item_table = { + **junk_table, + **collectable_table, + **upgrade_table, + **switch_palace_table, + **trap_table, + **event_table, +} + +lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code} diff --git a/worlds/smw/Levels.py b/worlds/smw/Levels.py new file mode 100644 index 00000000..0783ebfd --- /dev/null +++ b/worlds/smw/Levels.py @@ -0,0 +1,579 @@ + +from .Names import LocationName + +class SMWPath(): + thisEndDirection: int + otherLevelID: int + otherEndDirection: int + + def __init__(self, thisEndDirection: int, otherLevelID: int, otherEndDirection: int): + self.thisEndDirection = thisEndDirection + self.otherLevelID = otherLevelID + self.otherEndDirection = otherEndDirection + + +class SMWLevel(): + levelName: str + levelIDAddress: int + #eventIDAddress: int + eventIDValue: int + #progressByte: int + #progressBit: int + exit1Path: SMWPath + exit2Path: SMWPath + + def __init__(self, levelName: str, levelIDAddress: int, eventIDValue: int, exit1Path: SMWPath = None, exit2Path: SMWPath = None): + self.levelName = levelName + self.levelIDAddress = levelIDAddress + #self.eventIDAddress = eventIDAddress # Inferred from: LevelIDValue (Dict Key): $2D608 + LevelIDValue + self.eventIDValue = eventIDValue + #self.progressByte = progressByte # Inferred from EventIDValue: (ID / 8) + $1F02 + #self.progressBit = progressBit # Inferred from EventIDValue: 1 << (7 - (ID % 8)) + self.exit1Path = exit1Path + self.exit2Path = exit2Path + + +level_info_dict = { + 0x28: SMWLevel(LocationName.yoshis_house, 0x37A76, 0x00), + 0x29: SMWLevel(LocationName.yoshis_island_1_region, 0x37A83, 0x01, SMWPath(0x08, 0x14, 0x04)), + 0x14: SMWLevel(LocationName.yellow_switch_palace, 0x37812, 0x02), + 0x2A: SMWLevel(LocationName.yoshis_island_2_region, 0x37A89, 0x03, SMWPath(0x08, 0x27, 0x04)), + 0x27: SMWLevel(LocationName.yoshis_island_3_region, 0x37A69, 0x04, SMWPath(0x01, 0x26, 0x04)), + 0x26: SMWLevel(LocationName.yoshis_island_4_region, 0x37A4B, 0x05, SMWPath(0x08, 0x25, 0x01)), + 0x25: SMWLevel(LocationName.yoshis_island_castle_region, 0x37A29, 0x06, SMWPath(0x08, 0x15, 0x04)), + + 0x15: SMWLevel(LocationName.donut_plains_1_region, 0x37815, 0x07, SMWPath(0x02, 0x09, 0x04), SMWPath(0x08, 0x0A, 0x04)), + 0x09: SMWLevel(LocationName.donut_plains_2_region, 0x376D3, 0x09, SMWPath(0x08, 0x04, 0x02), SMWPath(0x02, 0x08, 0x01)), + 0x0A: SMWLevel(LocationName.donut_secret_1_region, 0x376E5, 0x10, SMWPath(0x08, 0x04, 0x04), SMWPath(0x01, 0x13, 0x08)), + 0x08: SMWLevel(LocationName.green_switch_palace, 0x376D1, 0x28), + 0x04: SMWLevel(LocationName.donut_ghost_house_region, 0x376A5, 0x0B, SMWPath(0x08, 0x03, 0x04), SMWPath(0x01, 0x05, 0x02)), + 0x13: SMWLevel(LocationName.donut_secret_house_region, 0x37807, 0x12, SMWPath(0x01, 0x2F, 0x04), SMWPath(0x04, 0x16, 0x08)), # SMW_TODO: Check this wrt pipe behavior + 0x05: SMWLevel(LocationName.donut_plains_3_region, 0x376A9, 0x0D, SMWPath(0x01, 0x06, 0x08)), + 0x06: SMWLevel(LocationName.donut_plains_4_region, 0x376CB, 0x0E, SMWPath(0x01, 0x07, 0x02)), + 0x2F: SMWLevel(LocationName.donut_secret_2_region, 0x37B10, 0x14, SMWPath(0x01, 0x05, 0x04)), + 0x07: SMWLevel(LocationName.donut_plains_castle_region, 0x376CD, 0x0F, SMWPath(0x08, 0x3E, 0x04)), + 0x03: SMWLevel(LocationName.donut_plains_top_secret, 0x37685, 0xFF), + 0x16: SMWLevel(LocationName.donut_plains_star_road, 0x37827, 0xFF), + + 0x3E: SMWLevel(LocationName.vanilla_dome_1_region, 0x37C25, 0x15, SMWPath(0x01, 0x3C, 0x04), SMWPath(0x02, 0x2D, 0x04)), + 0x3C: SMWLevel(LocationName.vanilla_dome_2_region, 0x37C08, 0x17, SMWPath(0x08, 0x2B, 0x04), SMWPath(0x01, 0x3F, 0x08)), + 0x2D: SMWLevel(LocationName.vanilla_secret_1_region, 0x37AE3, 0x1D, SMWPath(0x08, 0x01, 0x02), SMWPath(0x02, 0x2C, 0x01)), + 0x2B: SMWLevel(LocationName.vanilla_ghost_house_region, 0x37AC8, 0x19, SMWPath(0x01, 0x2E, 0x08)), + 0x2E: SMWLevel(LocationName.vanilla_dome_3_region, 0x37AEC, 0x1A, SMWPath(0x04, 0x3D, 0x08)), + 0x3D: SMWLevel(LocationName.vanilla_dome_4_region, 0x37C0C, 0x1B, SMWPath(0x04, 0x40, 0x08)), + 0x3F: SMWLevel(LocationName.red_switch_palace, 0x37C2A, 0x29), + 0x01: SMWLevel(LocationName.vanilla_secret_2_region, 0x3763C, 0x1F, SMWPath(0x01, 0x02, 0x02)), + 0x02: SMWLevel(LocationName.vanilla_secret_3_region, 0x3763E, 0x20, SMWPath(0x01, 0x0B, 0x02)), + 0x0B: SMWLevel(LocationName.vanilla_fortress_region, 0x37730, 0x21, SMWPath(0x01, 0x0C, 0x02)), + 0x40: SMWLevel(LocationName.vanilla_dome_castle_region, 0x37C2C, 0x1C, SMWPath(0x04, 0x0F, 0x02)), + 0x2C: SMWLevel(LocationName.vanilla_dome_star_road, 0x37AE0, 0xFF), + + 0x0C: SMWLevel(LocationName.butter_bridge_1_region, 0x37734, 0x22, SMWPath(0x01, 0x0D, 0x02)), + 0x0D: SMWLevel(LocationName.butter_bridge_2_region, 0x37736, 0x23, SMWPath(0x01, 0x0E, 0x02)), + 0x0F: SMWLevel(LocationName.cheese_bridge_region, 0x37754, 0x25, SMWPath(0x01, 0x10, 0x02), SMWPath(0x04, 0x11, 0x08)), + 0x11: SMWLevel(LocationName.soda_lake_region, 0x37784, 0x60, SMWPath(0x04, 0x12, 0x04)), + 0x10: SMWLevel(LocationName.cookie_mountain_region, 0x37757, 0x27, SMWPath(0x04, 0x0E, 0x04)), + 0x0E: SMWLevel(LocationName.twin_bridges_castle_region, 0x3773A, 0x24, SMWPath(0x01, 0x42, 0x08)), + 0x12: SMWLevel(LocationName.twin_bridges_star_road, 0x377F0, 0xFF), + + 0x42: SMWLevel(LocationName.forest_of_illusion_1_region, 0x37C78, 0x2A, SMWPath(0x01, 0x44, 0x08), SMWPath(0x02, 0x41, 0x01)), + 0x44: SMWLevel(LocationName.forest_of_illusion_2_region, 0x37CAA, 0x2C, SMWPath(0x04, 0x47, 0x08), SMWPath(0x01, 0x45, 0x02)), + 0x47: SMWLevel(LocationName.forest_of_illusion_3_region, 0x37CC8, 0x2E, SMWPath(0x02, 0x41, 0x04), SMWPath(0x04, 0x20, 0x01)), + 0x43: SMWLevel(LocationName.forest_of_illusion_4_region, 0x37CA4, 0x32, SMWPath(0x01, 0x44, 0x02), SMWPath(0x04, 0x46, 0x08)), + 0x41: SMWLevel(LocationName.forest_ghost_house_region, 0x37C76, 0x30, SMWPath(0x01, 0x42, 0x02), SMWPath(0x02, 0x43, 0x08)), + 0x46: SMWLevel(LocationName.forest_secret_region, 0x37CC4, 0x34, SMWPath(0x04, 0x1F, 0x01)), + 0x45: SMWLevel(LocationName.blue_switch_palace, 0x37CAC, 0x37), + 0x1F: SMWLevel(LocationName.forest_fortress_region, 0x37906, 0x35, SMWPath(0x02, 0x1E, 0x01)), + 0x20: SMWLevel(LocationName.forest_castle_region, 0x37928, 0x61, SMWPath(0x04, 0x22, 0x08)), + 0x1E: SMWLevel(LocationName.forest_star_road, 0x37904, 0x36), + + 0x22: SMWLevel(LocationName.chocolate_island_1_region, 0x37968, 0x62, SMWPath(0x02, 0x21, 0x01)), + 0x24: SMWLevel(LocationName.chocolate_island_2_region, 0x379B5, 0x46, SMWPath(0x02, 0x23, 0x01), SMWPath(0x04, 0x3B, 0x01)), + 0x23: SMWLevel(LocationName.chocolate_island_3_region, 0x379B3, 0x48, SMWPath(0x04, 0x23, 0x08), SMWPath(0x02, 0x1B, 0x01)), + 0x1D: SMWLevel(LocationName.chocolate_island_4_region, 0x378DF, 0x4B, SMWPath(0x02, 0x1C, 0x01)), + 0x1C: SMWLevel(LocationName.chocolate_island_5_region, 0x378DC, 0x4C, SMWPath(0x08, 0x1A, 0x04)), + 0x21: SMWLevel(LocationName.chocolate_ghost_house_region, 0x37965, 0x63, SMWPath(0x04, 0x24, 0x08)), + 0x1B: SMWLevel(LocationName.chocolate_fortress_region, 0x378BF, 0x4A, SMWPath(0x04, 0x1D, 0x08)), + 0x3B: SMWLevel(LocationName.chocolate_secret_region, 0x37B97, 0x4F, SMWPath(0x02, 0x1A, 0x02)), + 0x1A: SMWLevel(LocationName.chocolate_castle_region, 0x378BC, 0x4D, SMWPath(0x08, 0x18, 0x02)), + + 0x18: SMWLevel(LocationName.sunken_ghost_ship_region, 0x3787E, 0x4E, SMWPath(0x08, 0x3A, 0x01)), + 0x3A: SMWLevel(LocationName.valley_of_bowser_1_region, 0x37B7B, 0x38, SMWPath(0x02, 0x39, 0x01)), + 0x39: SMWLevel(LocationName.valley_of_bowser_2_region, 0x37B79, 0x39, SMWPath(0x02, 0x38, 0x01), SMWPath(0x08, 0x35, 0x04)), + 0x37: SMWLevel(LocationName.valley_of_bowser_3_region, 0x37B74, 0x3D, SMWPath(0x08, 0x33, 0x04)), + 0x33: SMWLevel(LocationName.valley_of_bowser_4_region, 0x37B54, 0x3E, SMWPath(0x01, 0x34, 0x02), SMWPath(0x08, 0x30, 0x04)), + 0x38: SMWLevel(LocationName.valley_ghost_house_region, 0x37B77, 0x3B, SMWPath(0x02, 0x37, 0x01), SMWPath(0x08, 0x34, 0x04)), + 0x35: SMWLevel(LocationName.valley_fortress_region, 0x37B59, 0x41, SMWPath(0x08, 0x32, 0x04)), + 0x34: SMWLevel(LocationName.valley_castle_region, 0x37B57, 0x40, SMWPath(0x08, 0x31, 0x04)), + 0x31: SMWLevel(LocationName.front_door, 0x37B37, 0x45), + 0x81: SMWLevel(LocationName.front_door, 0x37B37, 0x45), # Fake Extra Front Door + 0x32: SMWLevel(LocationName.back_door, 0x37B39, 0x42), + 0x82: SMWLevel(LocationName.back_door, 0x37B39, 0x42), # Fake Extra Back Door + 0x30: SMWLevel(LocationName.valley_star_road, 0x37B34, 0x44), + + 0x5B: SMWLevel(LocationName.star_road_donut, 0x37DD3, 0x50), + 0x58: SMWLevel(LocationName.star_road_1_region, 0x37DA4, 0x51, None, SMWPath(0x02, 0x53, 0x04)), + 0x53: SMWLevel(LocationName.star_road_vanilla, 0x37D82, 0x53), + 0x54: SMWLevel(LocationName.star_road_2_region, 0x37D85, 0x54, None, SMWPath(0x08, 0x52, 0x02)), + 0x52: SMWLevel(LocationName.star_road_twin_bridges, 0x37D67, 0x56), + 0x56: SMWLevel(LocationName.star_road_3_region, 0x37D89, 0x57, None, SMWPath(0x01, 0x57, 0x02)), + 0x57: SMWLevel(LocationName.star_road_forest, 0x37D8C, 0x59), + 0x59: SMWLevel(LocationName.star_road_4_region, 0x37DAA, 0x5A, None, SMWPath(0x04, 0x5C, 0x08)), + 0x5C: SMWLevel(LocationName.star_road_valley, 0x37DDC, 0x5C), + 0x5A: SMWLevel(LocationName.star_road_5_region, 0x37DB7, 0x5D, SMWPath(0x02, 0x5B, 0x01), SMWPath(0x08, 0x55, 0x04)), + 0x55: SMWLevel(LocationName.star_road_special, 0x37D87, 0x5F), + + 0x4D: SMWLevel(LocationName.special_star_road, 0x37D31, 0x64), + 0x4E: SMWLevel(LocationName.special_zone_1_region, 0x37D33, 0x65, SMWPath(0x01, 0x4F, 0x02)), + 0x4F: SMWLevel(LocationName.special_zone_2_region, 0x37D36, 0x66, SMWPath(0x01, 0x50, 0x02)), + 0x50: SMWLevel(LocationName.special_zone_3_region, 0x37D39, 0x67, SMWPath(0x01, 0x51, 0x02)), + 0x51: SMWLevel(LocationName.special_zone_4_region, 0x37D3C, 0x68, SMWPath(0x01, 0x4C, 0x01)), + 0x4C: SMWLevel(LocationName.special_zone_5_region, 0x37D1C, 0x69, SMWPath(0x02, 0x4B, 0x01)), + 0x4B: SMWLevel(LocationName.special_zone_6_region, 0x37D19, 0x6A, SMWPath(0x02, 0x4A, 0x01)), + 0x4A: SMWLevel(LocationName.special_zone_7_region, 0x37D16, 0x6B, SMWPath(0x02, 0x49, 0x01)), + 0x49: SMWLevel(LocationName.special_zone_8_region, 0x37D13, 0x6C, SMWPath(0x02, 0x48, 0x01)), + 0x48: SMWLevel(LocationName.special_complete, 0x37D11, 0x6D), +} + +full_level_list = [ + 0x28, 0x29, 0x14, 0x2A, 0x27, 0x26, 0x25, + 0x15, 0x09, 0x0A, 0x08, 0x04, 0x13, 0x05, 0x06, 0x2F, 0x07, 0x03, 0x16, + 0x3E, 0x3C, 0x2D, 0x2B, 0x2E, 0x3D, 0x3F, 0x01, 0x02, 0x0B, 0x40, 0x2C, + 0x0C, 0x0D, 0x0F, 0x11, 0x10, 0x0E, 0x12, + 0x42, 0x44, 0x47, 0x43, 0x41, 0x46, 0x45, 0x1F, 0x20, 0x1E, + 0x22, 0x24, 0x23, 0x1D, 0x1C, 0x21, 0x1B, 0x3B, 0x1A, + 0x18, 0x3A, 0x39, 0x37, 0x33, 0x38, 0x35, 0x34, 0x31, 0x32, 0x30, + 0x5B, 0x58, 0x53, 0x54, 0x52, 0x56, 0x57, 0x59, 0x5C, 0x5A, 0x55, + 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x4C, 0x4B, 0x4A, 0x49, 0x48, +] + +submap_level_list = [ + 0x28, 0x29, 0x2A, 0x27, 0x26, 0x25, + 0x2F, + 0x3E, 0x3C, 0x2D, 0x2B, 0x2E, 0x3D, 0x3F, 0x40, 0x2C, + 0x42, 0x44, 0x47, 0x43, 0x41, 0x46, 0x45, + 0x3B, + 0x3A, 0x39, 0x37, 0x33, 0x38, 0x35, 0x34, 0x31, 0x32, 0x30, + 0x5B, 0x58, 0x53, 0x54, 0x52, 0x56, 0x57, 0x59, 0x5C, 0x5A, 0x55, + 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x4C, 0x4B, 0x4A, 0x49, 0x48, +] + +easy_castle_fortress_levels = [ + 0x07, + 0x40, + 0x1F, + 0x20, + 0x1B, + 0x34, +] + +hard_castle_fortress_levels = [ + 0x25, + 0x0B, + 0x0E, + 0x1A, + 0x35, +] + +easy_single_levels = [ + 0x29, + 0x2A, + 0x27, + 0x26, + 0x05, + 0x06, + 0x2F, + 0x2E, + 0x3D, + 0x01, + 0x0C, + 0x0D, + 0x46, + 0x1D, +] + +hard_single_levels = [ + 0x2B, + 0x02, + 0x11, + 0x10, + 0x22, + 0x1C, + 0x21, + 0x3B, + 0x3A, + 0x37, + 0x4E, + 0x4F, + 0x50, + 0x51, + 0x4C, + 0x4B, + 0x4A, + 0x49, +] + +easy_double_levels = [ + 0x15, + 0x09, + 0x0F, + 0x42, + 0x43, + 0x24, + 0x38, + 0x58, + 0x54, + 0x56, +] + +hard_double_levels = [ + 0x0A, + 0x04, + 0x13, + 0x3E, + 0x3C, + 0x2D, + 0x44, + 0x47, + 0x41, + 0x23, + 0x33, + 0x39, + 0x59, + 0x5A, +] + +switch_palace_levels = [ + 0x14, + 0x08, + 0x3F, + 0x45, +] + +location_id_to_level_id = { + LocationName.yoshis_island_1_exit_1: [0x29, 0], + LocationName.yoshis_island_1_dragon: [0x29, 2], + LocationName.yoshis_island_2_exit_1: [0x2A, 0], + LocationName.yoshis_island_2_dragon: [0x2A, 2], + LocationName.yoshis_island_3_exit_1: [0x27, 0], + LocationName.yoshis_island_3_dragon: [0x27, 2], + LocationName.yoshis_island_4_exit_1: [0x26, 0], + LocationName.yoshis_island_4_dragon: [0x26, 2], + LocationName.yoshis_island_castle: [0x25, 0], + LocationName.yoshis_island_koopaling: [0x25, 0], + LocationName.yellow_switch_palace: [0x14, 0], + + LocationName.donut_plains_1_exit_1: [0x15, 0], + LocationName.donut_plains_1_exit_2: [0x15, 1], + LocationName.donut_plains_1_dragon: [0x15, 2], + LocationName.donut_plains_2_exit_1: [0x09, 0], + LocationName.donut_plains_2_exit_2: [0x09, 1], + LocationName.donut_plains_2_dragon: [0x09, 2], + LocationName.donut_plains_3_exit_1: [0x05, 0], + LocationName.donut_plains_3_dragon: [0x05, 2], + LocationName.donut_plains_4_exit_1: [0x06, 0], + LocationName.donut_plains_4_dragon: [0x06, 2], + LocationName.donut_secret_1_exit_1: [0x0A, 0], + LocationName.donut_secret_1_exit_2: [0x0A, 1], + LocationName.donut_secret_1_dragon: [0x0A, 2], + LocationName.donut_secret_2_exit_1: [0x2F, 0], + LocationName.donut_secret_2_dragon: [0x2F, 2], + LocationName.donut_ghost_house_exit_1: [0x04, 0], + LocationName.donut_ghost_house_exit_2: [0x04, 1], + LocationName.donut_secret_house_exit_1: [0x13, 0], + LocationName.donut_secret_house_exit_2: [0x13, 1], + LocationName.donut_plains_castle: [0x07, 0], + LocationName.donut_plains_koopaling: [0x07, 0], + LocationName.green_switch_palace: [0x08, 0], + + LocationName.vanilla_dome_1_exit_1: [0x3E, 0], + LocationName.vanilla_dome_1_exit_2: [0x3E, 1], + LocationName.vanilla_dome_1_dragon: [0x3E, 2], + LocationName.vanilla_dome_2_exit_1: [0x3C, 0], + LocationName.vanilla_dome_2_exit_2: [0x3C, 1], + LocationName.vanilla_dome_2_dragon: [0x3C, 2], + LocationName.vanilla_dome_3_exit_1: [0x2E, 0], + LocationName.vanilla_dome_3_dragon: [0x2E, 2], + LocationName.vanilla_dome_4_exit_1: [0x3D, 0], + LocationName.vanilla_dome_4_dragon: [0x3D, 2], + LocationName.vanilla_secret_1_exit_1: [0x2D, 0], + LocationName.vanilla_secret_1_exit_2: [0x2D, 1], + LocationName.vanilla_secret_1_dragon: [0x2D, 2], + LocationName.vanilla_secret_2_exit_1: [0x01, 0], + LocationName.vanilla_secret_2_dragon: [0x01, 2], + LocationName.vanilla_secret_3_exit_1: [0x02, 0], + LocationName.vanilla_secret_3_dragon: [0x02, 2], + LocationName.vanilla_ghost_house_exit_1: [0x2B, 0], + LocationName.vanilla_ghost_house_dragon: [0x2B, 2], + LocationName.vanilla_fortress: [0x0B, 0], + LocationName.vanilla_reznor: [0x0B, 0], + LocationName.vanilla_dome_castle: [0x40, 0], + LocationName.vanilla_dome_koopaling: [0x40, 0], + LocationName.red_switch_palace: [0x3F, 0], + + LocationName.butter_bridge_1_exit_1: [0x0C, 0], + LocationName.butter_bridge_1_dragon: [0x0C, 2], + LocationName.butter_bridge_2_exit_1: [0x0D, 0], + LocationName.butter_bridge_2_dragon: [0x0D, 2], + LocationName.cheese_bridge_exit_1: [0x0F, 0], + LocationName.cheese_bridge_exit_2: [0x0F, 1], + LocationName.cheese_bridge_dragon: [0x0F, 2], + LocationName.cookie_mountain_exit_1: [0x10, 0], + LocationName.cookie_mountain_dragon: [0x10, 2], + LocationName.soda_lake_exit_1: [0x11, 0], + LocationName.soda_lake_dragon: [0x11, 2], + LocationName.twin_bridges_castle: [0x0E, 0], + LocationName.twin_bridges_koopaling: [0x0E, 0], + + LocationName.forest_of_illusion_1_exit_1: [0x42, 0], + LocationName.forest_of_illusion_1_exit_2: [0x42, 1], + LocationName.forest_of_illusion_2_exit_1: [0x44, 0], + LocationName.forest_of_illusion_2_exit_2: [0x44, 1], + LocationName.forest_of_illusion_2_dragon: [0x44, 2], + LocationName.forest_of_illusion_3_exit_1: [0x47, 0], + LocationName.forest_of_illusion_3_exit_2: [0x47, 1], + LocationName.forest_of_illusion_3_dragon: [0x47, 2], + LocationName.forest_of_illusion_4_exit_1: [0x43, 0], + LocationName.forest_of_illusion_4_exit_2: [0x43, 1], + LocationName.forest_of_illusion_4_dragon: [0x43, 2], + LocationName.forest_ghost_house_exit_1: [0x41, 0], + LocationName.forest_ghost_house_exit_2: [0x41, 1], + LocationName.forest_ghost_house_dragon: [0x41, 2], + LocationName.forest_secret_exit_1: [0x46, 0], + LocationName.forest_secret_dragon: [0x46, 2], + LocationName.forest_fortress: [0x1F, 0], + LocationName.forest_reznor: [0x1F, 0], + LocationName.forest_castle: [0x20, 0], + LocationName.forest_koopaling: [0x20, 0], + LocationName.forest_castle_dragon: [0x20, 2], + LocationName.blue_switch_palace: [0x45, 0], + + LocationName.chocolate_island_1_exit_1: [0x22, 0], + LocationName.chocolate_island_1_dragon: [0x22, 2], + LocationName.chocolate_island_2_exit_1: [0x24, 0], + LocationName.chocolate_island_2_exit_2: [0x24, 1], + LocationName.chocolate_island_2_dragon: [0x24, 2], + LocationName.chocolate_island_3_exit_1: [0x23, 0], + LocationName.chocolate_island_3_exit_2: [0x23, 1], + LocationName.chocolate_island_3_dragon: [0x23, 2], + LocationName.chocolate_island_4_exit_1: [0x1D, 0], + LocationName.chocolate_island_4_dragon: [0x1D, 2], + LocationName.chocolate_island_5_exit_1: [0x1C, 0], + LocationName.chocolate_island_5_dragon: [0x1C, 2], + LocationName.chocolate_ghost_house_exit_1: [0x21, 0], + LocationName.chocolate_secret_exit_1: [0x3B, 0], + LocationName.chocolate_fortress: [0x1B, 0], + LocationName.chocolate_reznor: [0x1B, 0], + LocationName.chocolate_castle: [0x1A, 0], + LocationName.chocolate_koopaling: [0x1A, 0], + + LocationName.sunken_ghost_ship: [0x18, 0], + LocationName.sunken_ghost_ship_dragon: [0x18, 2], + + LocationName.valley_of_bowser_1_exit_1: [0x3A, 0], + LocationName.valley_of_bowser_1_dragon: [0x3A, 2], + LocationName.valley_of_bowser_2_exit_1: [0x39, 0], + LocationName.valley_of_bowser_2_exit_2: [0x39, 1], + LocationName.valley_of_bowser_2_dragon: [0x39, 2], + LocationName.valley_of_bowser_3_exit_1: [0x37, 0], + LocationName.valley_of_bowser_3_dragon: [0x37, 2], + LocationName.valley_of_bowser_4_exit_1: [0x33, 0], + LocationName.valley_of_bowser_4_exit_2: [0x33, 1], + LocationName.valley_ghost_house_exit_1: [0x38, 0], + LocationName.valley_ghost_house_exit_2: [0x38, 1], + LocationName.valley_ghost_house_dragon: [0x38, 2], + LocationName.valley_fortress: [0x35, 0], + LocationName.valley_reznor: [0x35, 0], + LocationName.valley_castle: [0x34, 0], + LocationName.valley_koopaling: [0x34, 0], + LocationName.valley_castle_dragon: [0x34, 2], + + LocationName.star_road_1_exit_1: [0x58, 0], + LocationName.star_road_1_exit_2: [0x58, 1], + LocationName.star_road_1_dragon: [0x58, 2], + LocationName.star_road_2_exit_1: [0x54, 0], + LocationName.star_road_2_exit_2: [0x54, 1], + LocationName.star_road_3_exit_1: [0x56, 0], + LocationName.star_road_3_exit_2: [0x56, 1], + LocationName.star_road_4_exit_1: [0x59, 0], + LocationName.star_road_4_exit_2: [0x59, 1], + LocationName.star_road_5_exit_1: [0x5A, 0], + LocationName.star_road_5_exit_2: [0x5A, 1], + + LocationName.special_zone_1_exit_1: [0x4E, 0], + LocationName.special_zone_1_dragon: [0x4E, 2], + LocationName.special_zone_2_exit_1: [0x4F, 0], + LocationName.special_zone_2_dragon: [0x4F, 2], + LocationName.special_zone_3_exit_1: [0x50, 0], + LocationName.special_zone_3_dragon: [0x50, 2], + LocationName.special_zone_4_exit_1: [0x51, 0], + LocationName.special_zone_4_dragon: [0x51, 2], + LocationName.special_zone_5_exit_1: [0x4C, 0], + LocationName.special_zone_5_dragon: [0x4C, 2], + LocationName.special_zone_6_exit_1: [0x4B, 0], + LocationName.special_zone_6_dragon: [0x4B, 2], + LocationName.special_zone_7_exit_1: [0x4A, 0], + LocationName.special_zone_7_dragon: [0x4A, 2], + LocationName.special_zone_8_exit_1: [0x49, 0], + LocationName.special_zone_8_dragon: [0x49, 2], +} + +def generate_level_list(world, player): + + if not world.level_shuffle[player]: + out_level_list = full_level_list.copy() + out_level_list[0x00] = 0x03 + out_level_list[0x11] = 0x28 + + if world.bowser_castle_doors[player] == "fast": + out_level_list[0x41] = 0x82 + out_level_list[0x42] = 0x32 + elif world.bowser_castle_doors[player] == "slow": + out_level_list[0x41] = 0x31 + out_level_list[0x42] = 0x81 + + return out_level_list + + shuffled_level_list = [] + easy_castle_fortress_levels_copy = easy_castle_fortress_levels.copy() + world.random.shuffle(easy_castle_fortress_levels_copy) + hard_castle_fortress_levels_copy = hard_castle_fortress_levels.copy() + world.random.shuffle(hard_castle_fortress_levels_copy) + easy_single_levels_copy = easy_single_levels.copy() + world.random.shuffle(easy_single_levels_copy) + hard_single_levels_copy = hard_single_levels.copy() + world.random.shuffle(hard_single_levels_copy) + easy_double_levels_copy = easy_double_levels.copy() + world.random.shuffle(easy_double_levels_copy) + hard_double_levels_copy = hard_double_levels.copy() + world.random.shuffle(hard_double_levels_copy) + switch_palace_levels_copy = switch_palace_levels.copy() + world.random.shuffle(switch_palace_levels_copy) + + # Yoshi's Island + shuffled_level_list.append(0x03) + shuffled_level_list.append(easy_single_levels_copy.pop(0)) + shuffled_level_list.append(0x14) + shuffled_level_list.append(easy_single_levels_copy.pop(0)) + shuffled_level_list.append(easy_single_levels_copy.pop(0)) + shuffled_level_list.append(easy_single_levels_copy.pop(0)) + shuffled_level_list.append(easy_castle_fortress_levels_copy.pop(0)) + + # Donut Plains + shuffled_level_list.append(easy_double_levels_copy.pop(0)) + shuffled_level_list.append(easy_double_levels_copy.pop(0)) + shuffled_level_list.append(easy_double_levels_copy.pop(0)) + shuffled_level_list.append(0x08) + shuffled_level_list.append(easy_double_levels_copy.pop(0)) + shuffled_level_list.append(easy_double_levels_copy.pop(0)) + shuffled_level_list.append(easy_single_levels_copy.pop(0)) + shuffled_level_list.append(easy_single_levels_copy.pop(0)) + shuffled_level_list.append(easy_single_levels_copy.pop(0)) + shuffled_level_list.append(easy_castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(0x28) + shuffled_level_list.append(0x16) + + single_levels_copy = (easy_single_levels_copy.copy() + hard_single_levels_copy.copy()) + world.random.shuffle(single_levels_copy) + + castle_fortress_levels_copy = (easy_castle_fortress_levels_copy.copy() + hard_castle_fortress_levels_copy.copy()) + world.random.shuffle(castle_fortress_levels_copy) + + double_levels_copy = (easy_double_levels_copy.copy() + hard_double_levels_copy.copy()) + world.random.shuffle(double_levels_copy) + + # Vanilla Dome + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(0x3F) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(0x2C) + + # Twin Bridges + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(0x12) + + # Forest of Illusion + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(0x45) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(0x1E) + + # Chocolate Island + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + + # Valley of Bowser + shuffled_level_list.append(0x18) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + shuffled_level_list.append(castle_fortress_levels_copy.pop(0)) + + # Front/Back Door + if world.bowser_castle_doors[player] == "fast": + shuffled_level_list.append(0x82) + shuffled_level_list.append(0x32) + elif world.bowser_castle_doors[player] == "slow": + shuffled_level_list.append(0x31) + shuffled_level_list.append(0x81) + else: + shuffled_level_list.append(0x31) + shuffled_level_list.append(0x32) + + shuffled_level_list.append(0x30) + + # Star Road + shuffled_level_list.append(0x5B) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(0x53) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(0x52) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(0x57) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(0x5C) + shuffled_level_list.append(double_levels_copy.pop(0)) + shuffled_level_list.append(0x55) + + # Special Zone + shuffled_level_list.append(0x4D) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(single_levels_copy.pop(0)) + shuffled_level_list.append(0x48) + + return shuffled_level_list diff --git a/worlds/smw/Locations.py b/worlds/smw/Locations.py new file mode 100644 index 00000000..a997f92f --- /dev/null +++ b/worlds/smw/Locations.py @@ -0,0 +1,233 @@ +import typing + +from BaseClasses import Location +from .Names import LocationName + + +class SMWLocation(Location): + game: str = "Super Mario World" + + def __init__(self, player: int, name: str = '', address: int = None, parent=None, prog_byte: int = None, prog_bit: int = None): + super().__init__(player, name, address, parent) + self.progress_byte = prog_byte + self.progress_bit = prog_bit + + +level_location_table = { + LocationName.yoshis_island_1_exit_1: 0xBC0000, + LocationName.yoshis_island_2_exit_1: 0xBC0001, + LocationName.yoshis_island_3_exit_1: 0xBC0002, + LocationName.yoshis_island_4_exit_1: 0xBC0003, + LocationName.yoshis_island_castle: 0xBC0004, + LocationName.yoshis_island_koopaling: 0xBC00A0, + + LocationName.yellow_switch_palace: 0xBC0005, + + LocationName.donut_plains_1_exit_1: 0xBC0006, + LocationName.donut_plains_1_exit_2: 0xBC0007, + LocationName.donut_plains_2_exit_1: 0xBC0008, + LocationName.donut_plains_2_exit_2: 0xBC0009, + LocationName.donut_plains_3_exit_1: 0xBC000A, + LocationName.donut_plains_4_exit_1: 0xBC000B, + LocationName.donut_secret_1_exit_1: 0xBC000C, + LocationName.donut_secret_1_exit_2: 0xBC000D, + LocationName.donut_secret_2_exit_1: 0xBC0063, + LocationName.donut_ghost_house_exit_1: 0xBC000E, + LocationName.donut_ghost_house_exit_2: 0xBC000F, + LocationName.donut_secret_house_exit_1: 0xBC0010, + LocationName.donut_secret_house_exit_2: 0xBC0011, + LocationName.donut_plains_castle: 0xBC0012, + LocationName.donut_plains_koopaling: 0xBC00A1, + + LocationName.green_switch_palace: 0xBC0013, + + LocationName.vanilla_dome_1_exit_1: 0xBC0014, + LocationName.vanilla_dome_1_exit_2: 0xBC0015, + LocationName.vanilla_dome_2_exit_1: 0xBC0016, + LocationName.vanilla_dome_2_exit_2: 0xBC0017, + LocationName.vanilla_dome_3_exit_1: 0xBC0018, + LocationName.vanilla_dome_4_exit_1: 0xBC0019, + LocationName.vanilla_secret_1_exit_1: 0xBC001A, + LocationName.vanilla_secret_1_exit_2: 0xBC001B, + LocationName.vanilla_secret_2_exit_1: 0xBC001C, + LocationName.vanilla_secret_3_exit_1: 0xBC001D, + LocationName.vanilla_ghost_house_exit_1: 0xBC001E, + LocationName.vanilla_fortress: 0xBC0020, + LocationName.vanilla_reznor: 0xBC00B0, + LocationName.vanilla_dome_castle: 0xBC0021, + LocationName.vanilla_dome_koopaling: 0xBC00A2, + + LocationName.red_switch_palace: 0xBC0022, + + LocationName.butter_bridge_1_exit_1: 0xBC0023, + LocationName.butter_bridge_2_exit_1: 0xBC0024, + LocationName.cheese_bridge_exit_1: 0xBC0025, + LocationName.cheese_bridge_exit_2: 0xBC0026, + LocationName.cookie_mountain_exit_1: 0xBC0027, + LocationName.soda_lake_exit_1: 0xBC0028, + LocationName.twin_bridges_castle: 0xBC0029, + LocationName.twin_bridges_koopaling: 0xBC00A3, + + LocationName.forest_of_illusion_1_exit_1: 0xBC002A, + LocationName.forest_of_illusion_1_exit_2: 0xBC002B, + LocationName.forest_of_illusion_2_exit_1: 0xBC002C, + LocationName.forest_of_illusion_2_exit_2: 0xBC002D, + LocationName.forest_of_illusion_3_exit_1: 0xBC002E, + LocationName.forest_of_illusion_3_exit_2: 0xBC002F, + LocationName.forest_of_illusion_4_exit_1: 0xBC0030, + LocationName.forest_of_illusion_4_exit_2: 0xBC0031, + LocationName.forest_ghost_house_exit_1: 0xBC0032, + LocationName.forest_ghost_house_exit_2: 0xBC0033, + LocationName.forest_secret_exit_1: 0xBC0034, + LocationName.forest_fortress: 0xBC0035, + LocationName.forest_reznor: 0xBC00B1, + LocationName.forest_castle: 0xBC0036, + LocationName.forest_koopaling: 0xBC00A4, + + LocationName.blue_switch_palace: 0xBC0037, + + LocationName.chocolate_island_1_exit_1: 0xBC0038, + LocationName.chocolate_island_2_exit_1: 0xBC0039, + LocationName.chocolate_island_2_exit_2: 0xBC003A, + LocationName.chocolate_island_3_exit_1: 0xBC003B, + LocationName.chocolate_island_3_exit_2: 0xBC003C, + LocationName.chocolate_island_4_exit_1: 0xBC003D, + LocationName.chocolate_island_5_exit_1: 0xBC003E, + LocationName.chocolate_ghost_house_exit_1: 0xBC003F, + LocationName.chocolate_secret_exit_1: 0xBC0041, + LocationName.chocolate_fortress: 0xBC0042, + LocationName.chocolate_reznor: 0xBC00B2, + LocationName.chocolate_castle: 0xBC0043, + LocationName.chocolate_koopaling: 0xBC00A5, + + LocationName.sunken_ghost_ship: 0xBC0044, + + LocationName.valley_of_bowser_1_exit_1: 0xBC0045, + LocationName.valley_of_bowser_2_exit_1: 0xBC0046, + LocationName.valley_of_bowser_2_exit_2: 0xBC0047, + LocationName.valley_of_bowser_3_exit_1: 0xBC0048, + LocationName.valley_of_bowser_4_exit_1: 0xBC0049, + LocationName.valley_of_bowser_4_exit_2: 0xBC004A, + LocationName.valley_ghost_house_exit_1: 0xBC004B, + LocationName.valley_ghost_house_exit_2: 0xBC004C, + LocationName.valley_fortress: 0xBC004E, + LocationName.valley_reznor: 0xBC00B3, + LocationName.valley_castle: 0xBC004F, + LocationName.valley_koopaling: 0xBC00A6, + + LocationName.star_road_1_exit_1: 0xBC0051, + LocationName.star_road_1_exit_2: 0xBC0052, + LocationName.star_road_2_exit_1: 0xBC0053, + LocationName.star_road_2_exit_2: 0xBC0054, + LocationName.star_road_3_exit_1: 0xBC0055, + LocationName.star_road_3_exit_2: 0xBC0056, + LocationName.star_road_4_exit_1: 0xBC0057, + LocationName.star_road_4_exit_2: 0xBC0058, + LocationName.star_road_5_exit_1: 0xBC0059, + LocationName.star_road_5_exit_2: 0xBC005A, + + LocationName.special_zone_1_exit_1: 0xBC005B, + LocationName.special_zone_2_exit_1: 0xBC005C, + LocationName.special_zone_3_exit_1: 0xBC005D, + LocationName.special_zone_4_exit_1: 0xBC005E, + LocationName.special_zone_5_exit_1: 0xBC005F, + LocationName.special_zone_6_exit_1: 0xBC0060, + LocationName.special_zone_7_exit_1: 0xBC0061, + LocationName.special_zone_8_exit_1: 0xBC0062, +} + +dragon_coin_location_table = { + LocationName.yoshis_island_1_dragon: 0xBC0100, + LocationName.yoshis_island_2_dragon: 0xBC0101, + LocationName.yoshis_island_3_dragon: 0xBC0102, + LocationName.yoshis_island_4_dragon: 0xBC0103, + + LocationName.donut_plains_1_dragon: 0xBC0106, + LocationName.donut_plains_2_dragon: 0xBC0108, + LocationName.donut_plains_3_dragon: 0xBC010A, + LocationName.donut_plains_4_dragon: 0xBC010B, + LocationName.donut_secret_1_dragon: 0xBC010C, + LocationName.donut_secret_2_dragon: 0xBC010D, + + LocationName.vanilla_dome_1_dragon: 0xBC0114, + LocationName.vanilla_dome_2_dragon: 0xBC0116, + LocationName.vanilla_dome_3_dragon: 0xBC0118, + LocationName.vanilla_dome_4_dragon: 0xBC0119, + LocationName.vanilla_secret_1_dragon: 0xBC011A, + LocationName.vanilla_secret_2_dragon: 0xBC011C, + LocationName.vanilla_secret_3_dragon: 0xBC011D, + LocationName.vanilla_ghost_house_dragon: 0xBC011E, + + LocationName.butter_bridge_1_dragon: 0xBC0123, + LocationName.butter_bridge_2_dragon: 0xBC0124, + LocationName.cheese_bridge_dragon: 0xBC0125, + LocationName.cookie_mountain_dragon: 0xBC0127, + LocationName.soda_lake_dragon: 0xBC0128, + + LocationName.forest_of_illusion_2_dragon: 0xBC012C, + LocationName.forest_of_illusion_3_dragon: 0xBC012E, + LocationName.forest_of_illusion_4_dragon: 0xBC0130, + LocationName.forest_ghost_house_dragon: 0xBC0132, + LocationName.forest_secret_dragon: 0xBC0134, + LocationName.forest_castle_dragon: 0xBC0136, + + LocationName.chocolate_island_1_dragon: 0xBC0138, + LocationName.chocolate_island_2_dragon: 0xBC0139, + LocationName.chocolate_island_3_dragon: 0xBC013B, + LocationName.chocolate_island_4_dragon: 0xBC013D, + LocationName.chocolate_island_5_dragon: 0xBC013E, + + LocationName.sunken_ghost_ship_dragon: 0xBC0144, + + LocationName.valley_of_bowser_1_dragon: 0xBC0145, + LocationName.valley_of_bowser_2_dragon: 0xBC0146, + LocationName.valley_of_bowser_3_dragon: 0xBC0148, + LocationName.valley_ghost_house_dragon: 0xBC014B, + LocationName.valley_castle_dragon: 0xBC014F, + + LocationName.star_road_1_dragon: 0xBC0151, + + LocationName.special_zone_1_dragon: 0xBC015B, + LocationName.special_zone_2_dragon: 0xBC015C, + LocationName.special_zone_3_dragon: 0xBC015D, + LocationName.special_zone_4_dragon: 0xBC015E, + LocationName.special_zone_5_dragon: 0xBC015F, + LocationName.special_zone_6_dragon: 0xBC0160, + LocationName.special_zone_7_dragon: 0xBC0161, + LocationName.special_zone_8_dragon: 0xBC0162, +} + +bowser_location_table = { + LocationName.bowser: 0xBC0200, +} + +yoshi_house_location_table = { + LocationName.yoshis_house: 0xBC0201, +} + +all_locations = { + **level_location_table, + **dragon_coin_location_table, + **bowser_location_table, + **yoshi_house_location_table, +} + +location_table = {} + + +def setup_locations(world, player: int): + location_table = {**level_location_table} + + # Dragon Coins here + if world.dragon_coin_checks[player].value: + location_table.update({**dragon_coin_location_table}) + + if world.goal[player] == "yoshi_egg_hunt": + location_table.update({**yoshi_house_location_table}) + else: + location_table.update({**bowser_location_table}) + + return location_table + + +lookup_id_to_name: typing.Dict[int, str] = {id: name for name, _ in all_locations.items()} diff --git a/worlds/smw/Names/ItemName.py b/worlds/smw/Names/ItemName.py new file mode 100644 index 00000000..72c984b0 --- /dev/null +++ b/worlds/smw/Names/ItemName.py @@ -0,0 +1,32 @@ +# Junk Definitions +one_up_mushroom = "1-Up Mushroom" + +# Collectable Definitions +yoshi_egg = "Yoshi Egg" + +# Upgrade Definitions +mario_run = "Run" +mario_carry = "Carry" +mario_swim = "Swim" +mario_spin_jump = "Spin Jump" +mario_climb = "Climb" +yoshi_activate = "Yoshi" +p_switch = "P-Switch" +p_balloon = "P-Balloon" +progressive_powerup = "Progressive Powerup" +super_star_active = "Super Star Activate" + +# Switch Palace Definitions +yellow_switch_palace = "Yellow Switch Palace" +green_switch_palace = "Green Switch Palace" +red_switch_palace = "Red Switch Palace" +blue_switch_palace = "Blue Switch Palace" + +# Trap Definitions +ice_trap = "Ice Trap" +stun_trap = "Stun Trap" +literature_trap = "Literature Trap" + +# Other Definitions +victory = "The Princess" +koopaling = "Boss Token" diff --git a/worlds/smw/Names/LiteratureTrap.py b/worlds/smw/Names/LiteratureTrap.py new file mode 100644 index 00000000..94c03822 --- /dev/null +++ b/worlds/smw/Names/LiteratureTrap.py @@ -0,0 +1,52 @@ +lit_trap_text_list = [ +[[0x8, 0x1f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x4d, 0x4e, 0x53, 0x1f, 0x45, 0x44, 0x40, 0x51, 0x1b, 0x9f, 0x5, 0x44, 0x40, 0x51, 0x1f, 0x48, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4c, 0x48, 0x4d, 0x43, 0x1c, 0x4a, 0x48, 0x4b, 0x4b, 0x44, 0x51, 0x1b, 0x1f, 0x5, 0x44, 0x40, 0x51, 0x9f, 0x48, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4b, 0x48, 0x53, 0x53, 0x4b, 0x44, 0x1c, 0x43, 0x44, 0x40, 0x53, 0x47, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x41, 0x51, 0x48, 0x4d, 0x46, 0x52, 0x1f, 0x40, 0x41, 0x4e, 0x54, 0x53, 0x1f, 0x53, 0x4e, 0x53, 0x40, 0xcb, 0x4e, 0x41, 0x4b, 0x48, 0x53, 0x44, 0x51, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1b, 0x1f, 0x8, 0x9f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x45, 0x40, 0x42, 0x44, 0x1f, 0x4c, 0x58, 0x1f, 0x45, 0x44, 0x40, 0x51, 0x9b, ], [0x8, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x4f, 0x44, 0x51, 0x4c, 0x48, 0x53, 0x1f, 0x48, 0x53, 0x9f, 0x53, 0x4e, 0x1f, 0x4f, 0x40, 0x52, 0x52, 0x1f, 0x4e, 0x55, 0x44, 0x51, 0x1f, 0x4c, 0x44, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x1f, 0x4c, 0x44, 0x1b, 0x9f, 0x0, 0x4d, 0x43, 0x1f, 0x56, 0x47, 0x44, 0x4d, 0x1f, 0x48, 0x53, 0x1f, 0x47, 0x40, 0x52, 0x9f, 0x46, 0x4e, 0x4d, 0x44, 0x1f, 0x4f, 0x40, 0x52, 0x53, 0x1f, 0x8, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x9f, 0x53, 0x54, 0x51, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x48, 0x4d, 0x4d, 0x44, 0x51, 0x1f, 0x44, 0x58, 0xc4, 0x53, 0x4e, 0x1f, 0x52, 0x44, 0x44, 0x1f, 0x48, 0x53, 0x52, 0x1f, 0x4f, 0x40, 0x53, 0x47, 0x1b, 0x9f, 0x16, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x45, 0x44, 0x40, 0x51, 0x1f, 0x47, 0x40, 0xd2, ], [0x46, 0x4e, 0x4d, 0x44, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x9f, 0x41, 0x44, 0x1f, 0x4d, 0x4e, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1b, 0x1f, 0xe, 0x4d, 0x4b, 0x58, 0x1f, 0x88, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x51, 0x44, 0x4c, 0x40, 0x48, 0x4d, 0x1b, 0x9f, 0x1c, 0x7, 0x44, 0x51, 0x41, 0x44, 0x51, 0x53, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x0, 0x41, 0x4e, 0x54, 0x53, 0x1f, 0x53, 0x47, 0x51, 0x44, 0x44, 0x1f, 0x53, 0x47, 0x48, 0x4d, 0x46, 0xd2, 0x8, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x40, 0x41, 0x52, 0x4e, 0x4b, 0x54, 0x53, 0x44, 0x4b, 0x58, 0x9f, 0x4f, 0x4e, 0x52, 0x48, 0x53, 0x48, 0x55, 0x44, 0x1b, 0x1f, 0x5, 0x48, 0x51, 0x52, 0x53, 0x1d, 0x9f, 0x4, 0x43, 0x56, 0x40, 0x51, 0x43, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x40, 0x9f, 0x55, 0x40, 0x4c, 0x4f, 0x48, 0x51, 0x44, 0x1b, 0x1f, 0x12, 0x44, 0x42, 0x4e, 0x4d, 0x43, 0x1d, 0x9f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x40, 0x1f, 0x4f, 0x40, 0x51, 0x53, 0x9f, 0x4e, 0x45, 0x1f, 0x47, 0x48, 0x4c, 0x1f, 0x1c, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x8, 0x9f, 0x43, 0x48, 0x43, 0x4d, 0x5d, 0x53, 0x1f, 0x4a, 0x4d, 0x4e, 0x56, 0x1f, 0x47, 0x4e, 0x56, 0x9f, ], [0x4f, 0x4e, 0x53, 0x44, 0x4d, 0x53, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x4f, 0x40, 0x51, 0x53, 0x9f, 0x4c, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x41, 0x44, 0x1f, 0x1c, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x53, 0x47, 0x48, 0x51, 0x52, 0x53, 0x44, 0x43, 0x1f, 0x45, 0x4e, 0x51, 0x1f, 0x4c, 0x58, 0x9f, 0x41, 0x4b, 0x4e, 0x4e, 0x43, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x48, 0x51, 0x43, 0x1d, 0x9f, 0x8, 0x1f, 0x56, 0x40, 0x52, 0x9f, 0x54, 0x4d, 0x42, 0x4e, 0x4d, 0x43, 0x48, 0x53, 0x48, 0x4e, 0x4d, 0x40, 0x4b, 0x4b, 0x58, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x48, 0x51, 0x51, 0x44, 0x55, 0x4e, 0x42, 0x40, 0x41, 0x4b, 0x58, 0x1f, 0x48, 0xcd, 0x4b, 0x4e, 0x55, 0x44, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x47, 0x48, 0x4c, 0x1b, 0x9f, ], [0x1c, 0xc, 0x44, 0x58, 0x44, 0x51, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x12, 0x40, 0x58, 0x1a, 0x1f, 0x8, 0x1f, 0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x46, 0x51, 0x44, 0x44, 0x4d, 0x9f, 0x44, 0x46, 0x46, 0x52, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0x40, 0x4c, 0x1a, 0x1f, 0x8, 0x9f, 0x43, 0x4e, 0x1a, 0x1f, 0x8, 0x1f, 0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1d, 0x9f, 0x12, 0x40, 0x4c, 0x1c, 0x8, 0x1c, 0x40, 0x4c, 0x1a, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x8, 0x9f, 0x56, 0x4e, 0x54, 0x4b, 0x43, 0x1f, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x48, 0x4d, 0x9f, 0x40, 0x1f, 0x41, 0x4e, 0x40, 0x53, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x8, 0x9f, 0x56, 0x4e, 0x54, 0x4b, 0x43, 0x1f, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x9f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x40, 0x1f, 0x46, 0x4e, 0x40, 0x53, 0x1b, 0x1b, 0x1b, 0x1f, 0x0, 0x4d, 0xc3, ], [0x8, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x48, 0xcd, 0x53, 0x47, 0x44, 0x1f, 0x51, 0x40, 0x48, 0x4d, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x48, 0x4d, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x43, 0x40, 0x51, 0x4a, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x4e, 0x4d, 0x1f, 0xc0, 0x53, 0x51, 0x40, 0x48, 0x4d, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x9f, 0x42, 0x40, 0x51, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x9f, 0x53, 0x51, 0x44, 0x44, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x58, 0x1f, 0x40, 0x51, 0x44, 0x1f, 0x52, 0x4e, 0x9f, 0x46, 0x4e, 0x4e, 0x43, 0x1d, 0x1f, 0x52, 0x4e, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x1d, 0x1f, 0x58, 0x4e, 0xd4, 0x52, 0x44, 0x44, 0x1a, 0x1f, 0x12, 0x4e, 0x1f, 0x8, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x44, 0x40, 0xd3, ], [0x53, 0x47, 0x44, 0x4c, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x1f, 0x41, 0x4e, 0x57, 0x1b, 0x1f, 0x0, 0x4d, 0xc3, 0x8, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x9f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x40, 0x1f, 0x45, 0x4e, 0x57, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x8, 0x9f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x48, 0x4d, 0x1f, 0xc0, 0x47, 0x4e, 0x54, 0x52, 0x44, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x8, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x9f, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x40, 0x9f, 0x4c, 0x4e, 0x54, 0x52, 0x44, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x8, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x9f, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x40, 0x4d, 0x43, 0x9f, ], [0x53, 0x47, 0x44, 0x51, 0x44, 0x1b, 0x1f, 0x12, 0x40, 0x58, 0x1a, 0x1f, 0x8, 0x1f, 0x56, 0x48, 0x4b, 0xcb, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x40, 0x4d, 0x58, 0x56, 0x47, 0x44, 0x51, 0x44, 0x9a, 0x8, 0x1f, 0x43, 0x4e, 0x1f, 0x52, 0x4e, 0x1f, 0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x46, 0x51, 0x44, 0x44, 0xcd, 0x44, 0x46, 0x46, 0x52, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0x40, 0x4c, 0x1a, 0x9f, 0x13, 0x47, 0x40, 0x4d, 0x4a, 0x1f, 0x58, 0x4e, 0x54, 0x1a, 0x1f, 0x13, 0x47, 0x40, 0x4d, 0x4a, 0x9f, 0x58, 0x4e, 0x54, 0x1d, 0x1f, 0x12, 0x40, 0x4c, 0x1c, 0x8, 0x1c, 0x40, 0x4c, 0x1a, 0x9f, 0x1c, 0x12, 0x44, 0x54, 0x52, 0x52, 0x1f, 0x9f, 0x9f, ]], +[[0x1, 0x54, 0x53, 0x1d, 0x1f, 0x52, 0x4e, 0x45, 0x53, 0x1a, 0x1f, 0x56, 0x47, 0x40, 0x53, 0x9f, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x9f, 0x58, 0x4e, 0x4d, 0x43, 0x44, 0x51, 0x1f, 0x56, 0x48, 0x4d, 0x43, 0x4e, 0x56, 0x9f, 0x41, 0x51, 0x44, 0x40, 0x4a, 0x52, 0x1e, 0x1f, 0x8, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x44, 0x40, 0x52, 0x53, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x9, 0x54, 0x4b, 0x48, 0x44, 0x53, 0x9f, 0x48, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x54, 0x4d, 0x1b, 0x1f, 0x0, 0x51, 0x48, 0x52, 0x44, 0x9d, 0x45, 0x40, 0x48, 0x51, 0x1f, 0x52, 0x54, 0x4d, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x4a, 0x48, 0x4b, 0xcb, 0x53, 0x47, 0x44, 0x1f, 0x44, 0x4d, 0x55, 0x48, 0x4e, 0x54, 0x52, 0x1f, 0x4c, 0x4e, 0x4e, 0x4d, 0x1d, 0x9f, ], [0x16, 0x47, 0x4e, 0x1f, 0x48, 0x52, 0x1f, 0x40, 0x4b, 0x51, 0x44, 0x40, 0x43, 0x58, 0x9f, 0x52, 0x48, 0x42, 0x4a, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x4f, 0x40, 0x4b, 0x44, 0x1f, 0x56, 0x48, 0x53, 0xc7, 0x46, 0x51, 0x48, 0x44, 0x45, 0x1d, 0x1f, 0x13, 0x47, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x4e, 0x54, 0x9f, 0x47, 0x44, 0x51, 0x1f, 0x4c, 0x40, 0x48, 0x43, 0x1f, 0x40, 0x51, 0x53, 0x1f, 0x45, 0x40, 0x51, 0x9f, 0x4c, 0x4e, 0x51, 0x44, 0x1f, 0x45, 0x40, 0x48, 0x51, 0x1f, 0x53, 0x47, 0x40, 0x4d, 0x9f, 0x52, 0x47, 0x44, 0x1b, 0x1f, 0x1, 0x44, 0x1f, 0x4d, 0x4e, 0x53, 0x1f, 0x47, 0x44, 0x51, 0x9f, 0x4c, 0x40, 0x48, 0x43, 0x1d, 0x1f, 0x52, 0x48, 0x4d, 0x42, 0x44, 0x1f, 0x52, 0x47, 0x44, 0x1f, 0x48, 0xd2, 0x44, 0x4d, 0x55, 0x48, 0x4e, 0x54, 0x52, 0x1b, 0x1f, 0x7, 0x44, 0x51, 0x9f, ], [0x55, 0x44, 0x52, 0x53, 0x40, 0x4b, 0x1f, 0x4b, 0x48, 0x55, 0x44, 0x51, 0x58, 0x1f, 0x48, 0x52, 0x9f, 0x41, 0x54, 0x53, 0x1f, 0x52, 0x48, 0x42, 0x4a, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x46, 0x51, 0x44, 0x44, 0xcd, 0x0, 0x4d, 0x43, 0x1f, 0x4d, 0x4e, 0x4d, 0x44, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x45, 0x4e, 0x4e, 0x4b, 0xd2, 0x43, 0x4e, 0x1f, 0x56, 0x44, 0x40, 0x51, 0x1f, 0x48, 0x53, 0x1b, 0x1f, 0x42, 0x40, 0x52, 0x53, 0x9f, 0x48, 0x53, 0x1f, 0x4e, 0x45, 0x45, 0x1b, 0x1f, 0x8, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x4c, 0x58, 0x9f, 0x4b, 0x40, 0x43, 0x58, 0x1d, 0x1f, 0xe, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x4c, 0x58, 0x9f, 0x4b, 0x4e, 0x55, 0x44, 0x1a, 0x1f, 0xe, 0x1d, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x52, 0x47, 0x44, 0x9f, 0x4a, 0x4d, 0x44, 0x56, 0x1f, 0x52, 0x47, 0x44, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x1a, 0x9f, ], [0x1c, 0x12, 0x47, 0x40, 0x4a, 0x44, 0x52, 0x4f, 0x44, 0x40, 0x51, 0x44, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x8, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x41, 0x44, 0x52, 0x53, 0x1f, 0x4e, 0xc5, 0x53, 0x48, 0x4c, 0x44, 0x52, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x56, 0x4e, 0x51, 0x52, 0x53, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x48, 0x4c, 0x44, 0x52, 0x1d, 0x1f, 0x48, 0xd3, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x40, 0x46, 0x44, 0x1f, 0x4e, 0x45, 0x9f, 0x56, 0x48, 0x52, 0x43, 0x4e, 0x4c, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0xc4, 0x40, 0x46, 0x44, 0x1f, 0x4e, 0x45, 0x9f, 0x45, 0x4e, 0x4e, 0x4b, 0x48, 0x52, 0x47, 0x4d, 0x44, 0x52, 0x52, 0x1d, 0x1f, 0x48, 0x53, 0x9f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x44, 0x4f, 0x4e, 0x42, 0x47, 0x1f, 0x4e, 0x45, 0x9f, ], [0x41, 0x44, 0x4b, 0x48, 0x44, 0x45, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0xc4, 0x44, 0x4f, 0x4e, 0x42, 0x47, 0x1f, 0x4e, 0x45, 0x9f, 0x48, 0x4d, 0x42, 0x51, 0x44, 0x43, 0x54, 0x4b, 0x48, 0x53, 0x58, 0x1d, 0x1f, 0x48, 0x53, 0x9f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x44, 0x40, 0x52, 0x4e, 0x4d, 0x1f, 0x4e, 0x45, 0x9f, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x52, 0x44, 0x40, 0x52, 0x4e, 0x4d, 0x1f, 0x4e, 0x45, 0x9f, 0x43, 0x40, 0x51, 0x4a, 0x4d, 0x44, 0x52, 0x52, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x4f, 0x51, 0x48, 0x4d, 0x46, 0x1f, 0x4e, 0x45, 0x9f, ], [0x47, 0x4e, 0x4f, 0x44, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x56, 0x48, 0x4d, 0x53, 0x44, 0x51, 0x1f, 0x4e, 0x45, 0x1f, 0x43, 0x44, 0x52, 0x4f, 0x40, 0x48, 0x51, 0x9b, 0x1c, 0x3, 0x48, 0x42, 0x4a, 0x44, 0x4d, 0x52, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0xc, 0x40, 0x51, 0x4b, 0x44, 0x58, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x43, 0x44, 0x40, 0x43, 0x1d, 0x9f, 0x53, 0x4e, 0x1f, 0x41, 0x44, 0x46, 0x48, 0x4d, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1b, 0x9f, 0x13, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x48, 0x52, 0x1f, 0x4d, 0x4e, 0x1f, 0x43, 0x4e, 0x54, 0x41, 0x53, 0x9f, 0x56, 0x47, 0x40, 0x53, 0x44, 0x55, 0x44, 0x51, 0x1d, 0x1f, 0x40, 0x41, 0x4e, 0x54, 0x53, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x1f, 0x51, 0x44, 0x46, 0x48, 0x52, 0x53, 0x44, 0xd1, 0x4e, 0x45, 0x1f, 0x47, 0x48, 0x52, 0x1f, 0x41, 0x54, 0x51, 0x48, 0x40, 0x4b, 0x1f, 0x56, 0x40, 0x52, 0x9f, 0x52, 0x48, 0x46, 0x4d, 0x44, 0x43, 0x1f, 0x41, 0x58, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x42, 0x4b, 0x44, 0x51, 0x46, 0x58, 0x4c, 0x40, 0x4d, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x9f, ], [0x42, 0x4b, 0x44, 0x51, 0x4a, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x54, 0x4d, 0x43, 0x44, 0x51, 0x53, 0x40, 0x4a, 0x44, 0x51, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x42, 0x47, 0x48, 0x44, 0x45, 0x1f, 0x4c, 0x4e, 0x54, 0x51, 0x4d, 0x44, 0x51, 0x9b, 0x12, 0x42, 0x51, 0x4e, 0x4e, 0x46, 0x44, 0x1f, 0x52, 0x48, 0x46, 0x4d, 0x44, 0x43, 0x1f, 0x48, 0x53, 0x9b, 0x40, 0x4d, 0x43, 0x1f, 0x12, 0x42, 0x51, 0x4e, 0x4e, 0x46, 0x44, 0x5d, 0x52, 0x1f, 0x4d, 0x40, 0x4c, 0xc4, 0x56, 0x40, 0x52, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x54, 0x4f, 0x4e, 0x4d, 0x9f, 0x5d, 0x42, 0x47, 0x40, 0x4d, 0x46, 0x44, 0x1d, 0x1f, 0x45, 0x4e, 0x51, 0x9f, 0x40, 0x4d, 0x58, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1f, 0x47, 0x44, 0x1f, 0x42, 0x47, 0x4e, 0x52, 0x44, 0x9f, ], [0x53, 0x4e, 0x1f, 0x4f, 0x54, 0x53, 0x1f, 0x47, 0x48, 0x52, 0x1f, 0x47, 0x40, 0x4d, 0x43, 0x9f, 0x53, 0x4e, 0x1b, 0x1f, 0xe, 0x4b, 0x43, 0x1f, 0xc, 0x40, 0x51, 0x4b, 0x44, 0x58, 0x1f, 0x56, 0x40, 0xd2, 0x40, 0x52, 0x1f, 0x43, 0x44, 0x40, 0x43, 0x1f, 0x40, 0x52, 0x1f, 0x40, 0x9f, 0x43, 0x4e, 0x4e, 0x51, 0x1c, 0x4d, 0x40, 0x48, 0x4b, 0x1b, 0x9f, 0x1c, 0x3, 0x48, 0x42, 0x4a, 0x44, 0x4d, 0x52, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0xc, 0x40, 0x4d, 0x58, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x4b, 0x48, 0x55, 0x44, 0x9f, 0x43, 0x44, 0x52, 0x44, 0x51, 0x55, 0x44, 0x1f, 0x43, 0x44, 0x40, 0x53, 0x47, 0x1b, 0x1f, 0x0, 0x4d, 0xc3, 0x52, 0x4e, 0x4c, 0x44, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x43, 0x48, 0x44, 0x9f, 0x43, 0x44, 0x52, 0x44, 0x51, 0x55, 0x44, 0x1f, 0x4b, 0x48, 0x45, 0x44, 0x1b, 0x1f, 0x2, 0x40, 0x4d, 0x9f, 0x58, 0x4e, 0x54, 0x1f, 0x46, 0x48, 0x55, 0x44, 0x1f, 0x48, 0x53, 0x1f, 0x53, 0x4e, 0x9f, 0x53, 0x47, 0x44, 0x4c, 0x1e, 0x1f, 0x13, 0x47, 0x44, 0x4d, 0x1f, 0x43, 0x4e, 0x1f, 0x4d, 0x4e, 0x53, 0x9f, 0x41, 0x44, 0x1f, 0x53, 0x4e, 0x4e, 0x1f, 0x44, 0x40, 0x46, 0x44, 0x51, 0x1f, 0x53, 0x4e, 0x9f, 0x43, 0x44, 0x40, 0x4b, 0x1f, 0x4e, 0x54, 0x53, 0x1f, 0x43, 0x44, 0x40, 0x53, 0x47, 0x1f, 0x48, 0x4d, 0x9f, ], [0x49, 0x54, 0x43, 0x46, 0x44, 0x4c, 0x44, 0x4d, 0x53, 0x1b, 0x1f, 0x5, 0x4e, 0x51, 0x9f, 0x44, 0x55, 0x44, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x55, 0x44, 0x51, 0x58, 0x1f, 0x56, 0x48, 0x52, 0xc4, 0x42, 0x40, 0x4d, 0x4d, 0x4e, 0x53, 0x1f, 0x52, 0x44, 0x44, 0x1f, 0x40, 0x4b, 0x4b, 0x9f, 0x44, 0x4d, 0x43, 0x52, 0x1b, 0x1f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x8, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x40, 0x1f, 0x53, 0x51, 0x54, 0x53, 0x47, 0x9f, 0x54, 0x4d, 0x48, 0x55, 0x44, 0x51, 0x52, 0x40, 0x4b, 0x4b, 0x58, 0x9f, 0x40, 0x42, 0x4a, 0x4d, 0x4e, 0x56, 0x4b, 0x44, 0x43, 0x46, 0x44, 0x43, 0x1d, 0x1f, 0x53, 0x47, 0x40, 0xd3, 0x40, 0x1f, 0x52, 0x48, 0x4d, 0x46, 0x4b, 0x44, 0x1f, 0x4c, 0x40, 0x4d, 0x1f, 0x48, 0x4d, 0x9f, 0x4f, 0x4e, 0x52, 0x52, 0x44, 0x52, 0x52, 0x48, 0x4e, 0x4d, 0x1f, 0x4e, 0x45, 0x1f, 0x40, 0x9f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x45, 0x4e, 0x51, 0x53, 0x54, 0x4d, 0x44, 0x1d, 0x1f, 0x4c, 0x54, 0x52, 0xd3, 0x41, 0x44, 0x1f, 0x48, 0x4d, 0x1f, 0x56, 0x40, 0x4d, 0x53, 0x1f, 0x4e, 0x45, 0x1f, 0x40, 0x9f, 0x56, 0x48, 0x45, 0x44, 0x1b, 0x1f, 0x1c, 0x0, 0x54, 0x52, 0x53, 0x44, 0x4d, 0x1f, 0x9f, ]], +[[0x13, 0x47, 0x44, 0x1f, 0x53, 0x51, 0x54, 0x53, 0x47, 0x1f, 0x40, 0x4b, 0x56, 0x40, 0x58, 0x52, 0x9f, 0x42, 0x40, 0x51, 0x51, 0x48, 0x44, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x40, 0x4c, 0x41, 0x48, 0x46, 0x54, 0x48, 0x53, 0x58, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x56, 0x4e, 0x51, 0x43, 0x52, 0x1f, 0x54, 0x52, 0x44, 0x43, 0x1f, 0x53, 0x4e, 0x9f, 0x44, 0x57, 0x4f, 0x51, 0x44, 0x52, 0x52, 0x1f, 0x48, 0x53, 0x1b, 0x9f, 0x1c, 0x7, 0x44, 0x51, 0x41, 0x44, 0x51, 0x53, 0x1f, 0x9f, 0x9f, 0x9f, ]], +[[0x5d, 0x8, 0x1f, 0x43, 0x40, 0x51, 0x44, 0x52, 0x40, 0x58, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x47, 0x40, 0x55, 0x44, 0x4d, 0x5d, 0x53, 0x1f, 0x47, 0x40, 0x43, 0x1f, 0x4c, 0x54, 0x42, 0x47, 0x9f, 0x4f, 0x51, 0x40, 0x42, 0x53, 0x48, 0x42, 0x44, 0x1d, 0x5d, 0x1f, 0x52, 0x40, 0x48, 0x43, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x10, 0x54, 0x44, 0x44, 0x4d, 0x1b, 0x1f, 0x5d, 0x16, 0x47, 0x44, 0x4d, 0x1f, 0x88, 0x56, 0x40, 0x52, 0x1f, 0x58, 0x4e, 0x54, 0x51, 0x1f, 0x40, 0x46, 0x44, 0x1d, 0x1f, 0x8, 0x9f, 0x40, 0x4b, 0x56, 0x40, 0x58, 0x52, 0x1f, 0x43, 0x48, 0x43, 0x1f, 0x48, 0x53, 0x1f, 0x45, 0x4e, 0x51, 0x9f, 0x47, 0x40, 0x4b, 0x45, 0x1c, 0x40, 0x4d, 0x1c, 0x47, 0x4e, 0x54, 0x51, 0x1f, 0x40, 0x9f, 0x43, 0x40, 0x58, 0x1b, 0x1f, 0x16, 0x47, 0x58, 0x1d, 0x9f, ], [0x52, 0x4e, 0x4c, 0x44, 0x53, 0x48, 0x4c, 0x44, 0x52, 0x1f, 0x8, 0x5d, 0x55, 0x44, 0x9f, 0x41, 0x44, 0x4b, 0x48, 0x44, 0x55, 0x44, 0x43, 0x1f, 0x40, 0x52, 0x1f, 0x4c, 0x40, 0x4d, 0x58, 0x9f, 0x40, 0x52, 0x1f, 0x52, 0x48, 0x57, 0x1f, 0x48, 0x4c, 0x4f, 0x4e, 0x52, 0x52, 0x48, 0x41, 0x4b, 0x44, 0x9f, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x52, 0x1f, 0x41, 0x44, 0x45, 0x4e, 0x51, 0x44, 0x9f, 0x41, 0x51, 0x44, 0x40, 0x4a, 0x45, 0x40, 0x52, 0x53, 0x1b, 0x5d, 0x9f, 0x1c, 0x2, 0x40, 0x51, 0x51, 0x4e, 0x4b, 0x4b, 0x1f, 0x9f, 0x9f, 0x9f, ]], +[[0xb, 0x48, 0x45, 0x44, 0x1d, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x48, 0x53, 0x52, 0x9f, 0x51, 0x54, 0x4b, 0x44, 0x52, 0x1d, 0x1f, 0x48, 0x53, 0x52, 0x9f, 0x4e, 0x41, 0x4b, 0x48, 0x46, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x52, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x48, 0x53, 0x52, 0x1f, 0x45, 0x51, 0x44, 0x44, 0x43, 0x4e, 0x4c, 0x52, 0x1d, 0x1f, 0x48, 0x52, 0x9f, 0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x40, 0x1f, 0x52, 0x4e, 0x4d, 0x4d, 0x44, 0x53, 0x1b, 0x9f, 0x18, 0x4e, 0x54, 0x5d, 0x51, 0x44, 0x1f, 0x46, 0x48, 0x55, 0x44, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x45, 0x4e, 0x51, 0x4c, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x47, 0x40, 0x55, 0xc4, 0x53, 0x4e, 0x1f, 0x56, 0x51, 0x48, 0x53, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x9f, ], [0x52, 0x4e, 0x4d, 0x4d, 0x44, 0x53, 0x1f, 0x58, 0x4e, 0x54, 0x51, 0x52, 0x44, 0x4b, 0x45, 0x1b, 0x9f, 0x1c, 0xb, 0x5d, 0x4, 0x4d, 0x46, 0x4b, 0x44, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0xb, 0x48, 0x4a, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x4e, 0x4e, 0x4d, 0x1f, 0x4e, 0x55, 0x44, 0xd1, 0x53, 0x47, 0x44, 0x1f, 0x43, 0x40, 0x58, 0x1f, 0x4c, 0x58, 0x1f, 0x46, 0x44, 0x4d, 0x48, 0x54, 0x52, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x41, 0x51, 0x40, 0x56, 0x4d, 0x1f, 0x40, 0x51, 0x44, 0x1f, 0x4b, 0x4e, 0x52, 0xd3, 0x4e, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x52, 0x44, 0x1f, 0x45, 0x4e, 0x4e, 0x4b, 0x52, 0x9f, 0x1c, 0x7, 0x40, 0x48, 0x4a, 0x54, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x8, 0x4d, 0x1f, 0x40, 0x1f, 0x47, 0x4e, 0x4b, 0x44, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x46, 0x51, 0x4e, 0x54, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x4b, 0x48, 0x55, 0x44, 0xc3, 0x40, 0x1f, 0x47, 0x4e, 0x41, 0x41, 0x48, 0x53, 0x1b, 0x1f, 0xd, 0x4e, 0x53, 0x1f, 0x40, 0x9f, 0x4d, 0x40, 0x52, 0x53, 0x58, 0x1d, 0x1f, 0x43, 0x48, 0x51, 0x53, 0x58, 0x1d, 0x1f, 0x56, 0x44, 0x53, 0x9f, 0x47, 0x4e, 0x4b, 0x44, 0x1d, 0x1f, 0x45, 0x48, 0x4b, 0x4b, 0x44, 0x43, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x44, 0x4d, 0x43, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x56, 0x4e, 0x51, 0x4c, 0x52, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x40, 0x4d, 0x1f, 0x4e, 0x4e, 0x59, 0x58, 0x1f, 0x52, 0x4c, 0x44, 0x4b, 0x4b, 0x9d, 0x4d, 0x4e, 0x51, 0x1f, 0x58, 0x44, 0x53, 0x1f, 0x40, 0x1f, 0x43, 0x51, 0x58, 0x1d, 0x9f, ], [0x41, 0x40, 0x51, 0x44, 0x1d, 0x1f, 0x52, 0x40, 0x4d, 0x43, 0x58, 0x1f, 0x47, 0x4e, 0x4b, 0x44, 0x9f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x4d, 0x4e, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1f, 0x48, 0x4d, 0x1f, 0x48, 0xd3, 0x53, 0x4e, 0x1f, 0x52, 0x48, 0x53, 0x1f, 0x43, 0x4e, 0x56, 0x4d, 0x1f, 0x4e, 0x4d, 0x1f, 0x4e, 0x51, 0x9f, 0x53, 0x4e, 0x1f, 0x44, 0x40, 0x53, 0x1b, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x40, 0x9f, 0x47, 0x4e, 0x41, 0x41, 0x48, 0x53, 0x1c, 0x47, 0x4e, 0x4b, 0x44, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x4c, 0x44, 0x40, 0x4d, 0x52, 0x9f, 0x42, 0x4e, 0x4c, 0x45, 0x4e, 0x51, 0x53, 0x1b, 0x1f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, ]], +[[0x5d, 0x6, 0x4e, 0x4e, 0x43, 0x1f, 0xc, 0x4e, 0x51, 0x4d, 0x48, 0x4d, 0x46, 0x1a, 0x5d, 0x9f, 0x52, 0x40, 0x48, 0x43, 0x1f, 0x1, 0x48, 0x4b, 0x41, 0x4e, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0xc4, 0x4c, 0x44, 0x40, 0x4d, 0x53, 0x1f, 0x48, 0x53, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x1f, 0x52, 0x54, 0x4d, 0x9f, 0x56, 0x40, 0x52, 0x1f, 0x52, 0x47, 0x48, 0x4d, 0x48, 0x4d, 0x46, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x46, 0x51, 0x40, 0x52, 0x52, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x55, 0x44, 0x51, 0xd8, 0x46, 0x51, 0x44, 0x44, 0x4d, 0x1b, 0x1f, 0x1, 0x54, 0x53, 0x1f, 0x6, 0x40, 0x4d, 0x43, 0x40, 0x4b, 0xc5, 0x4b, 0x4e, 0x4e, 0x4a, 0x44, 0x43, 0x1f, 0x40, 0x53, 0x1f, 0x47, 0x48, 0x4c, 0x1f, 0x45, 0x51, 0x4e, 0xcc, 0x54, 0x4d, 0x43, 0x44, 0x51, 0x1f, 0x4b, 0x4e, 0x4d, 0x46, 0x1f, 0x41, 0x54, 0x52, 0x47, 0x58, 0x9f, ], [0x44, 0x58, 0x44, 0x41, 0x51, 0x4e, 0x56, 0x52, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x52, 0x53, 0x54, 0x42, 0x4a, 0x1f, 0x4e, 0x54, 0x53, 0x1f, 0x45, 0x54, 0x51, 0x53, 0x47, 0x44, 0x51, 0x9f, 0x53, 0x47, 0x40, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x41, 0x51, 0x48, 0x4c, 0x1f, 0x4e, 0x45, 0x9f, 0x47, 0x48, 0x52, 0x1f, 0x52, 0x47, 0x40, 0x43, 0x58, 0x1f, 0x47, 0x40, 0x53, 0x1b, 0x9f, 0x5d, 0x16, 0x47, 0x40, 0x53, 0x1f, 0x43, 0x4e, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x4c, 0x44, 0x40, 0x4d, 0x1e, 0x5d, 0x1f, 0x47, 0x44, 0x1f, 0x52, 0x40, 0x48, 0x43, 0x1b, 0x9f, 0x5d, 0x3, 0x4e, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x56, 0x48, 0x52, 0x47, 0x1f, 0x4c, 0x44, 0x1f, 0x40, 0x9f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x4c, 0x4e, 0x51, 0x4d, 0x48, 0x4d, 0x46, 0x1d, 0x1f, 0x4e, 0x51, 0x9f, ], [0x4c, 0x44, 0x40, 0x4d, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x48, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x40, 0x9f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x4c, 0x4e, 0x51, 0x4d, 0x48, 0x4d, 0x46, 0x9f, 0x56, 0x47, 0x44, 0x53, 0x47, 0x44, 0x51, 0x1f, 0x8, 0x1f, 0x56, 0x40, 0x4d, 0x53, 0x1f, 0x48, 0x53, 0x9f, 0x4e, 0x51, 0x1f, 0x4d, 0x4e, 0x53, 0x1d, 0x1f, 0x4e, 0x51, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x58, 0x4e, 0x54, 0x1f, 0x45, 0x44, 0x44, 0x4b, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x53, 0x47, 0x48, 0xd2, 0x4c, 0x4e, 0x51, 0x4d, 0x48, 0x4d, 0x46, 0x1d, 0x1f, 0x4e, 0x51, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x48, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x40, 0x1f, 0x4c, 0x4e, 0x51, 0x4d, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0xce, 0x41, 0x44, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x4e, 0x4d, 0x1e, 0x5d, 0x1f, 0x5d, 0x0, 0x4b, 0x4b, 0x9f, ], [0x4e, 0x45, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x40, 0x53, 0x1f, 0x4e, 0x4d, 0x42, 0x44, 0x1d, 0x5d, 0x9f, 0x52, 0x40, 0x48, 0x43, 0x1f, 0x1, 0x48, 0x4b, 0x41, 0x4e, 0x1b, 0x9f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x5d, 0x6, 0x4e, 0x4e, 0x43, 0x1f, 0x4c, 0x4e, 0x51, 0x4d, 0x48, 0x4d, 0x46, 0x1a, 0x5d, 0x1f, 0x47, 0xc4, 0x52, 0x40, 0x48, 0x43, 0x1f, 0x40, 0x53, 0x1f, 0x4b, 0x40, 0x52, 0x53, 0x1b, 0x1f, 0x5d, 0x16, 0x44, 0x9f, 0x43, 0x4e, 0x4d, 0x5d, 0x53, 0x1f, 0x56, 0x40, 0x4d, 0x53, 0x1f, 0x40, 0x4d, 0x58, 0x9f, 0x40, 0x43, 0x55, 0x44, 0x4d, 0x53, 0x54, 0x51, 0x44, 0x52, 0x1f, 0x47, 0x44, 0x51, 0x44, 0x1d, 0x9f, 0x53, 0x47, 0x40, 0x4d, 0x4a, 0x1f, 0x58, 0x4e, 0x54, 0x1a, 0x1f, 0x18, 0x4e, 0x54, 0x9f, 0x4c, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x53, 0x51, 0x58, 0x1f, 0x4e, 0x55, 0x44, 0x51, 0x1f, 0x13, 0x47, 0xc4, 0x7, 0x48, 0x4b, 0x4b, 0x1f, 0x4e, 0x51, 0x1f, 0x40, 0x42, 0x51, 0x4e, 0x52, 0x52, 0x1f, 0x13, 0x47, 0xc4, 0x16, 0x40, 0x53, 0x44, 0x51, 0x1b, 0x5d, 0x1f, 0x1, 0x58, 0x1f, 0x53, 0x47, 0x48, 0x52, 0x1f, 0x47, 0xc4, ], [0x4c, 0x44, 0x40, 0x4d, 0x53, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x42, 0x4e, 0x4d, 0x55, 0x44, 0x51, 0x52, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x56, 0x40, 0x52, 0x9f, 0x40, 0x53, 0x1f, 0x40, 0x4d, 0x1f, 0x44, 0x4d, 0x43, 0x1b, 0x1f, 0x5d, 0x16, 0x47, 0x40, 0x53, 0x1f, 0xc0, 0x4b, 0x4e, 0x53, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x52, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x43, 0x4e, 0x1f, 0x54, 0x52, 0x44, 0x1f, 0x6, 0x4e, 0x4e, 0x43, 0x9f, 0x4c, 0x4e, 0x51, 0x4d, 0x48, 0x4d, 0x46, 0x1f, 0x45, 0x4e, 0x51, 0x1a, 0x5d, 0x1f, 0x52, 0x40, 0x48, 0xc3, 0x6, 0x40, 0x4d, 0x43, 0x40, 0x4b, 0x45, 0x1b, 0x1f, 0x5d, 0xd, 0x4e, 0x56, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x4c, 0x44, 0x40, 0x4d, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x56, 0x40, 0x4d, 0xd3, ], [0x53, 0x4e, 0x1f, 0x46, 0x44, 0x53, 0x1f, 0x51, 0x48, 0x43, 0x1f, 0x4e, 0x45, 0x1f, 0x4c, 0x44, 0x1d, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x4e, 0x4d, 0x5d, 0x53, 0x9f, 0x41, 0x44, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x53, 0x48, 0x4b, 0x4b, 0x1f, 0x8, 0x9f, 0x4c, 0x4e, 0x55, 0x44, 0x1f, 0x4e, 0x45, 0x45, 0x1b, 0x1b, 0x9f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x5d, 0x13, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x48, 0x52, 0x1f, 0x4d, 0x4e, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x9f, 0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x4b, 0x4e, 0x4e, 0x4a, 0x48, 0x4d, 0x46, 0x1d, 0x1f, 0x48, 0x45, 0x9f, 0x58, 0x4e, 0x54, 0x1f, 0x56, 0x40, 0x4d, 0x53, 0x1f, 0x53, 0x4e, 0x1f, 0x45, 0x48, 0x4d, 0x43, 0x9f, 0x52, 0x4e, 0x4c, 0x44, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1b, 0x1f, 0x18, 0x4e, 0x54, 0x9f, 0x42, 0x44, 0x51, 0x53, 0x40, 0x48, 0x4d, 0x4b, 0x58, 0x1f, 0x54, 0x52, 0x54, 0x40, 0x4b, 0x4b, 0x58, 0x9f, 0x45, 0x48, 0x4d, 0x43, 0x1f, 0x52, 0x4e, 0x4c, 0x44, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1d, 0x1f, 0x48, 0xc5, 0x58, 0x4e, 0x54, 0x1f, 0x4b, 0x4e, 0x4e, 0x4a, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x48, 0x53, 0x9f, 0x48, 0x52, 0x1f, 0x4d, 0x4e, 0x53, 0x1f, 0x40, 0x4b, 0x56, 0x40, 0x58, 0x52, 0x9f, ], [0x50, 0x54, 0x48, 0x53, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x52, 0x4e, 0x4c, 0x44, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x56, 0x44, 0x51, 0xc4, 0x40, 0x45, 0x53, 0x44, 0x51, 0x1b, 0x5d, 0x1f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x3, 0x51, 0x54, 0x4c, 0x4c, 0x44, 0x51, 0x1d, 0x1f, 0x41, 0x44, 0x40, 0x53, 0x1d, 0x1f, 0x40, 0x4d, 0xc3, 0x4f, 0x48, 0x4f, 0x44, 0x51, 0x1d, 0x1f, 0x41, 0x4b, 0x4e, 0x56, 0x1b, 0x9f, 0x7, 0x40, 0x51, 0x4f, 0x44, 0x51, 0x1d, 0x1f, 0x52, 0x53, 0x51, 0x48, 0x4a, 0x44, 0x1d, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x52, 0x4e, 0x4b, 0x43, 0x48, 0x44, 0x51, 0x1d, 0x1f, 0x46, 0x4e, 0x1b, 0x9f, 0x5, 0x51, 0x44, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x45, 0x4b, 0x40, 0x4c, 0x44, 0x1f, 0x40, 0x4d, 0xc3, 0x52, 0x44, 0x40, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x46, 0x51, 0x40, 0x52, 0x52, 0x44, 0x52, 0x1d, 0x9f, 0x13, 0x48, 0x4b, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x43, 0x40, 0x56, 0x4d, 0x48, 0x4d, 0x46, 0x9f, 0x11, 0x44, 0x43, 0x1f, 0x12, 0x53, 0x40, 0x51, 0x1f, 0x4f, 0x40, 0x52, 0x52, 0x44, 0x52, 0x1b, 0x9f, ], [0x1c, 0xc, 0x42, 0x2, 0x40, 0x45, 0x45, 0x51, 0x44, 0x58, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x13, 0x47, 0x44, 0x1f, 0x53, 0x44, 0x40, 0x51, 0x52, 0x1f, 0x8, 0x1f, 0x45, 0x44, 0x44, 0x4b, 0x9f, 0x53, 0x4e, 0x43, 0x40, 0x58, 0x1f, 0x8, 0x5d, 0x4b, 0x4b, 0x1f, 0x56, 0x40, 0x48, 0x53, 0x1f, 0x53, 0xce, 0x52, 0x47, 0x44, 0x43, 0x1f, 0x53, 0x4e, 0x4c, 0x4e, 0x51, 0x51, 0x4e, 0x56, 0x1b, 0x9f, 0x13, 0x47, 0x4e, 0x54, 0x46, 0x47, 0x1f, 0x8, 0x5d, 0x4b, 0x4b, 0x1f, 0x4d, 0x4e, 0x53, 0x9f, 0x52, 0x4b, 0x44, 0x44, 0x4f, 0x1f, 0x53, 0x47, 0x48, 0x52, 0x1f, 0x4d, 0x48, 0x46, 0x47, 0x53, 0x9f, 0xd, 0x4e, 0x51, 0x1f, 0x45, 0x48, 0x4d, 0x43, 0x1f, 0x52, 0x54, 0x51, 0x42, 0x44, 0x40, 0x52, 0x44, 0x9f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x52, 0x4e, 0x51, 0x51, 0x4e, 0x56, 0x1b, 0x1f, 0xc, 0x58, 0x9f, 0x44, 0x58, 0x44, 0x52, 0x1f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x4a, 0x44, 0x44, 0x4f, 0x9f, ], [0x53, 0x47, 0x44, 0x48, 0x51, 0x1f, 0x52, 0x48, 0x46, 0x47, 0x53, 0x1b, 0x1f, 0x8, 0x9f, 0x43, 0x40, 0x51, 0x44, 0x1f, 0x4d, 0x4e, 0x53, 0x1f, 0x41, 0x44, 0x9f, 0x53, 0x44, 0x40, 0x51, 0x1c, 0x41, 0x4b, 0x48, 0x4d, 0x43, 0x44, 0x43, 0x1b, 0x1f, 0x8, 0x9f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x41, 0x44, 0x1f, 0x45, 0x51, 0x44, 0x44, 0x1f, 0x53, 0x4e, 0x9f, 0x53, 0x40, 0x4b, 0x4a, 0x1f, 0xd, 0x4e, 0x53, 0x1f, 0x42, 0x47, 0x4e, 0x4a, 0x44, 0x43, 0x9f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x46, 0x51, 0x48, 0x44, 0x45, 0x1d, 0x9f, 0x42, 0x4b, 0x44, 0x40, 0x51, 0x1c, 0x4c, 0x48, 0x4d, 0x43, 0x44, 0x43, 0x1b, 0x1f, 0xc, 0x58, 0x9f, 0x4c, 0x4e, 0x54, 0x53, 0x47, 0x1f, 0x42, 0x40, 0x4d, 0x4d, 0x4e, 0x53, 0x9f, ], [0x41, 0x44, 0x53, 0x51, 0x40, 0x58, 0x1f, 0x13, 0x47, 0x44, 0x1f, 0x40, 0x4d, 0x46, 0x54, 0x48, 0x52, 0xc7, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x8, 0x1f, 0x4a, 0x4d, 0x4e, 0x56, 0x1b, 0x1f, 0x18, 0x44, 0x52, 0x1d, 0x9f, 0x8, 0x5d, 0x4b, 0x4b, 0x1f, 0x4a, 0x44, 0x44, 0x4f, 0x1f, 0x4c, 0x58, 0x1f, 0x53, 0x44, 0x40, 0x51, 0xd2, 0x53, 0x48, 0x4b, 0x1f, 0x4b, 0x40, 0x53, 0x44, 0x51, 0x1b, 0x1f, 0x1, 0x54, 0x53, 0x1f, 0x4c, 0x58, 0x9f, 0x46, 0x51, 0x48, 0x44, 0x45, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x4d, 0x44, 0x55, 0x44, 0x51, 0x9f, 0x46, 0x4e, 0x1b, 0x1f, 0x1c, 0xc, 0x42, 0x2, 0x40, 0x45, 0x45, 0x51, 0x44, 0x58, 0x1f, 0x9f, 0x9f, 0x9f, ]], +[[0x16, 0x47, 0x4e, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x52, 0x1d, 0x1f, 0x2, 0x40, 0x4d, 0x1b, 0x9f, 0x16, 0x47, 0x4e, 0x1f, 0x53, 0x51, 0x48, 0x44, 0x52, 0x1d, 0x1f, 0x3, 0x4e, 0x44, 0x52, 0x1b, 0x9f, 0x16, 0x47, 0x4e, 0x1f, 0x4b, 0x4e, 0x55, 0x44, 0x52, 0x1d, 0x1f, 0xb, 0x48, 0x55, 0x44, 0x52, 0x1b, 0x9f, 0x1c, 0xc, 0x42, 0x2, 0x40, 0x45, 0x45, 0x51, 0x44, 0x58, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x13, 0x47, 0x44, 0x1f, 0x4b, 0x48, 0x53, 0x53, 0x4b, 0x44, 0x1f, 0x50, 0x54, 0x44, 0x44, 0x4d, 0x9f, 0x40, 0x4b, 0x4b, 0x1f, 0x46, 0x4e, 0x4b, 0x43, 0x44, 0x4d, 0x1f, 0x5, 0x4b, 0x44, 0x56, 0x9f, 0x47, 0x48, 0x52, 0x52, 0x48, 0x4d, 0x46, 0x1f, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x52, 0x44, 0x40, 0x1b, 0x1f, 0x13, 0x4e, 0x1f, 0x52, 0x53, 0x4e, 0x4f, 0x1f, 0x44, 0x40, 0x42, 0x47, 0x9f, 0x56, 0x40, 0x55, 0x44, 0x1f, 0x7, 0x44, 0x51, 0x1f, 0x42, 0x4b, 0x54, 0x53, 0x42, 0x47, 0x1f, 0x53, 0xce, 0x52, 0x40, 0x55, 0x44, 0x1f, 0x12, 0x47, 0x44, 0x1f, 0x55, 0x44, 0x4d, 0x53, 0x54, 0x51, 0x44, 0x43, 0x9f, 0x41, 0x51, 0x40, 0x55, 0x44, 0x4b, 0x58, 0x1b, 0x1f, 0x0, 0x52, 0x1f, 0x52, 0x47, 0x44, 0x9f, 0x40, 0x53, 0x53, 0x40, 0x42, 0x4a, 0x44, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x44, 0x40, 0x9f, ], [0x48, 0x4d, 0x1f, 0x51, 0x40, 0x46, 0x44, 0x1f, 0x0, 0x9f, 0x47, 0x4e, 0x4b, 0x43, 0x44, 0x51, 0x4c, 0x40, 0x4d, 0x1f, 0x42, 0x40, 0x4c, 0x44, 0x9f, 0x4d, 0x48, 0x46, 0x47, 0x1f, 0x0, 0x4b, 0x4e, 0x4d, 0x46, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x52, 0x40, 0x4d, 0x43, 0x1f, 0x5, 0x48, 0x52, 0x47, 0x4d, 0x44, 0x53, 0x1f, 0x48, 0x4d, 0x9f, 0x47, 0x40, 0x4d, 0x43, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x52, 0x40, 0x56, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x50, 0x54, 0x44, 0x44, 0x4d, 0x1f, 0x4c, 0x48, 0x43, 0x52, 0x4a, 0x58, 0x1b, 0x1f, 0x7, 0x44, 0x9f, 0x52, 0x53, 0x40, 0x51, 0x44, 0x43, 0x1f, 0x40, 0x53, 0x1f, 0x47, 0x44, 0x51, 0x1f, 0x48, 0x4d, 0x9f, 0x56, 0x4e, 0x4d, 0x43, 0x44, 0x51, 0x1f, 0x5, 0x4e, 0x51, 0x1f, 0x4e, 0x45, 0x53, 0x44, 0x4d, 0x9f, ], [0x47, 0x44, 0x5d, 0x43, 0x1f, 0x41, 0x44, 0x44, 0x4d, 0x1f, 0x53, 0x4e, 0x4b, 0x43, 0x9f, 0x13, 0x47, 0x40, 0x53, 0x1f, 0x52, 0x54, 0x42, 0x47, 0x1f, 0x40, 0x52, 0x1f, 0x52, 0x47, 0x44, 0x9f, 0x2, 0x4e, 0x54, 0x4b, 0x43, 0x1f, 0x4d, 0x44, 0x55, 0x44, 0x51, 0x1f, 0x41, 0x44, 0x1f, 0x16, 0x47, 0xce, 0x47, 0x4e, 0x55, 0x44, 0x51, 0x44, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1d, 0x9f, 0x41, 0x51, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x46, 0x4e, 0x4b, 0x43, 0x1b, 0x1f, 0x7, 0x44, 0x9f, 0x52, 0x40, 0x56, 0x1f, 0x47, 0x44, 0x51, 0x1f, 0x4f, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x40, 0x4d, 0xc3, 0x50, 0x54, 0x48, 0x42, 0x4a, 0x4b, 0x58, 0x1f, 0x7, 0x44, 0x1f, 0x4b, 0x4e, 0x4e, 0x4a, 0x44, 0x43, 0x9f, 0x54, 0x4f, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x42, 0x4b, 0x48, 0x45, 0x45, 0x1f, 0x47, 0x44, 0x9f, ], [0x45, 0x40, 0x42, 0x44, 0x43, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x52, 0x40, 0x56, 0x1f, 0x40, 0x9f, 0x42, 0x40, 0x55, 0x44, 0x1f, 0x0, 0x41, 0x4e, 0x55, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x56, 0x40, 0x55, 0x44, 0x1f, 0x8, 0x4d, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x47, 0x44, 0x51, 0x9f, 0x44, 0x46, 0x46, 0x52, 0x1f, 0x47, 0x44, 0x1f, 0x4f, 0x4b, 0x40, 0x42, 0x44, 0x43, 0x1b, 0x9f, 0x13, 0x47, 0x44, 0x1f, 0x4b, 0x48, 0x53, 0x53, 0x4b, 0x44, 0x1f, 0x50, 0x54, 0x44, 0x44, 0x4d, 0x9f, 0x40, 0x4b, 0x4b, 0x1f, 0x46, 0x4e, 0x4b, 0x43, 0x44, 0x4d, 0x1f, 0x14, 0x4f, 0x4e, 0x4d, 0x9f, 0x47, 0x48, 0x52, 0x1f, 0x52, 0x47, 0x4e, 0x54, 0x4b, 0x43, 0x44, 0x51, 0x1f, 0x52, 0x53, 0x4e, 0x4e, 0xc3, 0x7, 0x44, 0x51, 0x1f, 0x44, 0x58, 0x44, 0x52, 0x1f, 0x40, 0x4b, 0x4b, 0x1f, 0x41, 0x4b, 0x54, 0x44, 0x9f, ], [0x6, 0x4b, 0x4e, 0x56, 0x44, 0x43, 0x1f, 0x4e, 0x45, 0x1f, 0x47, 0x44, 0x51, 0x1f, 0x53, 0x51, 0x54, 0xc4, 0x14, 0x4d, 0x43, 0x58, 0x48, 0x4d, 0x46, 0x1f, 0x46, 0x51, 0x40, 0x53, 0x48, 0x53, 0x54, 0x43, 0x44, 0x9b, 0x1c, 0xc, 0x42, 0x2, 0x40, 0x45, 0x45, 0x51, 0x44, 0x58, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x7, 0x40, 0x51, 0x4f, 0x44, 0x51, 0x1d, 0x1f, 0x53, 0x51, 0x44, 0x40, 0x53, 0x1f, 0x58, 0x4e, 0x54, 0xd1, 0x56, 0x4e, 0x51, 0x43, 0x52, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x42, 0x40, 0x51, 0x44, 0x9f, 0x5, 0x4e, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x4c, 0x40, 0x58, 0x1f, 0x42, 0x40, 0x54, 0x52, 0xc4, 0x49, 0x4e, 0x58, 0x1f, 0x4e, 0x51, 0x1f, 0x43, 0x44, 0x52, 0x4f, 0x40, 0x48, 0x51, 0x9f, 0x12, 0x48, 0x4d, 0x46, 0x1f, 0x58, 0x4e, 0x54, 0x51, 0x1f, 0x52, 0x4e, 0x4d, 0x46, 0x52, 0x1f, 0x4e, 0xc5, 0x47, 0x44, 0x40, 0x4b, 0x53, 0x47, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x4b, 0x4e, 0x55, 0x44, 0x1f, 0xe, 0xc5, 0x43, 0x51, 0x40, 0x46, 0x4e, 0x4d, 0x52, 0x1f, 0x45, 0x4b, 0x40, 0x4c, 0x48, 0x4d, 0x46, 0x9f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x40, 0x41, 0x4e, 0x55, 0x44, 0x1b, 0x9f, ], [0x1c, 0xc, 0x42, 0x2, 0x40, 0x45, 0x45, 0x51, 0x44, 0x58, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x13, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x4e, 0x4d, 0x4b, 0x58, 0x1f, 0x4e, 0x4d, 0xc4, 0x42, 0x40, 0x53, 0x42, 0x47, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x56, 0x40, 0xd2, 0x2, 0x40, 0x53, 0x42, 0x47, 0x1c, 0x24, 0x24, 0x1d, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x9f, 0x52, 0x4f, 0x44, 0x42, 0x48, 0x45, 0x48, 0x44, 0x43, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x40, 0x9f, 0x42, 0x4e, 0x4d, 0x42, 0x44, 0x51, 0x4d, 0x1f, 0x45, 0x4e, 0x51, 0x1f, 0x4e, 0x4d, 0x44, 0x5d, 0x52, 0x9f, 0x52, 0x40, 0x45, 0x44, 0x53, 0x58, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x45, 0x40, 0x42, 0xc4, 0x4e, 0x45, 0x1f, 0x43, 0x40, 0x4d, 0x46, 0x44, 0x51, 0x52, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x51, 0x44, 0x40, 0x4b, 0x1f, 0x40, 0x4d, 0x43, 0x9f, ], [0x48, 0x4c, 0x4c, 0x44, 0x43, 0x48, 0x40, 0x53, 0x44, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4f, 0x51, 0x4e, 0x42, 0x44, 0x52, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x40, 0x9f, 0x51, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x40, 0x4b, 0x1f, 0x4c, 0x48, 0x4d, 0x43, 0x1b, 0x1f, 0xe, 0x51, 0xd1, 0x56, 0x40, 0x52, 0x1f, 0x42, 0x51, 0x40, 0x59, 0x58, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x42, 0x4e, 0x54, 0x4b, 0x43, 0x1f, 0x41, 0x44, 0x1f, 0x46, 0x51, 0x4e, 0x54, 0x4d, 0x43, 0x44, 0x43, 0x9b, 0x0, 0x4b, 0x4b, 0x1f, 0x47, 0x44, 0x1f, 0x47, 0x40, 0x43, 0x1f, 0x53, 0x4e, 0x1f, 0x43, 0x4e, 0x9f, 0x56, 0x40, 0x52, 0x1f, 0x40, 0x52, 0x4a, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x40, 0x52, 0x9f, 0x52, 0x4e, 0x4e, 0x4d, 0x1f, 0x40, 0x52, 0x1f, 0x47, 0x44, 0x1f, 0x43, 0x48, 0x43, 0x1d, 0x1f, 0x47, 0xc4, ], [0x56, 0x4e, 0x54, 0x4b, 0x43, 0x1f, 0x4d, 0x4e, 0x1f, 0x4b, 0x4e, 0x4d, 0x46, 0x44, 0x51, 0x1f, 0x41, 0xc4, 0x42, 0x51, 0x40, 0x59, 0x58, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x56, 0x4e, 0x54, 0x4b, 0x43, 0x9f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x53, 0x4e, 0x1f, 0x45, 0x4b, 0x58, 0x1f, 0x4c, 0x4e, 0x51, 0x44, 0x9f, 0x4c, 0x48, 0x52, 0x52, 0x48, 0x4e, 0x4d, 0x52, 0x1b, 0x1f, 0xe, 0x51, 0x51, 0x9f, 0x56, 0x4e, 0x54, 0x4b, 0x43, 0x1f, 0x41, 0x44, 0x1f, 0x42, 0x51, 0x40, 0x59, 0x58, 0x1f, 0x53, 0x4e, 0x9f, 0x45, 0x4b, 0x58, 0x1f, 0x4c, 0x4e, 0x51, 0x44, 0x1f, 0x4c, 0x48, 0x52, 0x52, 0x48, 0x4e, 0x4d, 0x52, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x52, 0x40, 0x4d, 0x44, 0x1f, 0x48, 0x45, 0x1f, 0x47, 0x44, 0x9f, 0x43, 0x48, 0x43, 0x4d, 0x5d, 0x53, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x48, 0x45, 0x1f, 0x47, 0x44, 0x9f, ], [0x56, 0x40, 0x52, 0x1f, 0x52, 0x40, 0x4d, 0x44, 0x1f, 0x47, 0x44, 0x1f, 0x47, 0x40, 0x43, 0x1f, 0x53, 0xce, 0x45, 0x4b, 0x58, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1b, 0x1f, 0x8, 0x45, 0x1f, 0x47, 0x44, 0x9f, 0x45, 0x4b, 0x44, 0x56, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x47, 0x44, 0x1f, 0x56, 0x40, 0x52, 0x9f, 0x42, 0x51, 0x40, 0x59, 0x58, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x43, 0x48, 0x43, 0x4d, 0x5d, 0x53, 0x9f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x53, 0x4e, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x48, 0x45, 0x1f, 0x47, 0xc4, 0x43, 0x48, 0x43, 0x4d, 0x5d, 0x53, 0x1f, 0x56, 0x40, 0x4d, 0x53, 0x1f, 0x53, 0x4e, 0x1f, 0x47, 0x44, 0x9f, 0x56, 0x40, 0x52, 0x1f, 0x52, 0x40, 0x4d, 0x44, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0x40, 0x43, 0x9f, 0x53, 0x4e, 0x1b, 0x1f, 0x1c, 0x7, 0x44, 0x4b, 0x4b, 0x44, 0x51, 0x1f, 0x9f, ]], +[[0x5d, 0x13, 0x47, 0x44, 0x58, 0x5d, 0x51, 0x44, 0x1f, 0x53, 0x51, 0x58, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0xce, 0x4a, 0x48, 0x4b, 0x4b, 0x1f, 0x4c, 0x44, 0x1d, 0x5d, 0x9f, 0x18, 0x4e, 0x52, 0x52, 0x40, 0x51, 0x48, 0x40, 0x4d, 0x1f, 0x53, 0x4e, 0x4b, 0x43, 0x1f, 0x47, 0x48, 0xcc, 0x42, 0x40, 0x4b, 0x4c, 0x4b, 0x58, 0x1b, 0x1f, 0x5d, 0xd, 0x4e, 0x1f, 0x4e, 0x4d, 0x44, 0x5d, 0x52, 0x9f, 0x53, 0x51, 0x58, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x1f, 0x4a, 0x48, 0x4b, 0x4b, 0x9f, 0x58, 0x4e, 0x54, 0x1d, 0x5d, 0x1f, 0x2, 0x4b, 0x44, 0x55, 0x48, 0x4d, 0x46, 0x44, 0x51, 0x9f, 0x42, 0x51, 0x48, 0x44, 0x43, 0x1b, 0x1f, 0x5d, 0x13, 0x47, 0x44, 0x4d, 0x1f, 0x56, 0x47, 0x58, 0x9f, 0x40, 0x51, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x52, 0x47, 0x4e, 0x4e, 0x53, 0x48, 0x4d, 0x46, 0x9f, ], [0x40, 0x53, 0x1f, 0x4c, 0x44, 0x1e, 0x5d, 0x1f, 0x18, 0x4e, 0x52, 0x52, 0x40, 0x51, 0x48, 0x40, 0x4d, 0x9f, 0x40, 0x52, 0x4a, 0x44, 0x43, 0x1b, 0x1f, 0x5d, 0x13, 0x47, 0x44, 0x58, 0x5d, 0x51, 0x44, 0x9f, 0x52, 0x47, 0x4e, 0x4e, 0x53, 0x48, 0x4d, 0x46, 0x1f, 0x40, 0x53, 0x9f, 0x44, 0x55, 0x44, 0x51, 0x58, 0x4e, 0x4d, 0x44, 0x1d, 0x5d, 0x9f, 0x2, 0x4b, 0x44, 0x55, 0x48, 0x4d, 0x46, 0x44, 0x51, 0x9f, 0x40, 0x4d, 0x52, 0x56, 0x44, 0x51, 0x44, 0x43, 0x1b, 0x1f, 0x5d, 0x13, 0x47, 0x44, 0x58, 0x5d, 0x51, 0xc4, 0x53, 0x51, 0x58, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x1f, 0x4a, 0x48, 0x4b, 0x4b, 0x9f, 0x44, 0x55, 0x44, 0x51, 0x58, 0x4e, 0x4d, 0x44, 0x1b, 0x5d, 0x1f, 0x0, 0x4d, 0x43, 0x9f, ], [0x56, 0x47, 0x40, 0x53, 0x1f, 0x43, 0x48, 0x45, 0x45, 0x44, 0x51, 0x44, 0x4d, 0x42, 0x44, 0x9f, 0x43, 0x4e, 0x44, 0x52, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x4c, 0x40, 0x4a, 0x44, 0x1e, 0x9f, 0x1c, 0x7, 0x44, 0x4b, 0x4b, 0x44, 0x51, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x18, 0x4e, 0x54, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x41, 0x51, 0x40, 0x48, 0x4d, 0x52, 0x1f, 0x48, 0xcd, 0x58, 0x4e, 0x54, 0x51, 0x1f, 0x47, 0x44, 0x40, 0x43, 0x1b, 0x1f, 0x18, 0x4e, 0x54, 0x9f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x45, 0x44, 0x44, 0x53, 0x1f, 0x48, 0x4d, 0x1f, 0x58, 0x4e, 0x54, 0x51, 0x9f, 0x52, 0x47, 0x4e, 0x44, 0x52, 0x1b, 0x1f, 0x18, 0x4e, 0x54, 0x1f, 0x42, 0x40, 0x4d, 0x9f, 0x52, 0x53, 0x44, 0x44, 0x51, 0x1f, 0x58, 0x4e, 0x54, 0x51, 0x52, 0x44, 0x4b, 0x45, 0x1f, 0x40, 0x4d, 0xd8, 0x43, 0x48, 0x51, 0x44, 0x42, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x42, 0x47, 0x4e, 0x4e, 0x52, 0x44, 0x1b, 0x1f, 0x18, 0x4e, 0x54, 0x5d, 0x51, 0x44, 0x1f, 0x4e, 0x4d, 0x9f, 0x58, 0x4e, 0x54, 0x51, 0x1f, 0x4e, 0x56, 0x4d, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x58, 0x4e, 0x54, 0x9f, ], [0x4a, 0x4d, 0x4e, 0x56, 0x1f, 0x56, 0x47, 0x40, 0x53, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x4a, 0x4d, 0x4e, 0x56, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x18, 0xe, 0x14, 0x1f, 0x40, 0x51, 0x44, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4e, 0x4d, 0x44, 0x1f, 0x56, 0x47, 0x4e, 0x5d, 0x4b, 0x4b, 0x9f, 0x43, 0x44, 0x42, 0x48, 0x43, 0x44, 0x1f, 0x56, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x53, 0x4e, 0x9f, 0x46, 0x4e, 0x1b, 0x1b, 0x1b, 0x1f, 0x1c, 0x12, 0x54, 0x44, 0x52, 0x52, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x16, 0x47, 0x44, 0x4d, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x9f, 0x44, 0x4b, 0x48, 0x4c, 0x48, 0x4d, 0x40, 0x53, 0x44, 0x43, 0x1f, 0x40, 0x4b, 0x4b, 0x9f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x48, 0x52, 0x9f, 0x48, 0x4c, 0x4f, 0x4e, 0x52, 0x52, 0x48, 0x41, 0x4b, 0x44, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x4d, 0x9f, 0x56, 0x47, 0x40, 0x53, 0x44, 0x55, 0x44, 0x51, 0x1f, 0x51, 0x44, 0x4c, 0x40, 0x48, 0x4d, 0x52, 0x1d, 0x9f, 0x47, 0x4e, 0x56, 0x44, 0x55, 0x44, 0x51, 0x9f, 0x48, 0x4c, 0x4f, 0x51, 0x4e, 0x41, 0x40, 0x41, 0x4b, 0x44, 0x1d, 0x1f, 0x4c, 0x54, 0x52, 0x53, 0x9f, 0x41, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x53, 0x51, 0x54, 0x53, 0x47, 0x1b, 0x9f, ], [0x1c, 0x3, 0x4e, 0x58, 0x4b, 0x44, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x5d, 0xc, 0x58, 0x1f, 0x4c, 0x48, 0x4d, 0x43, 0x1d, 0x5d, 0x1f, 0x47, 0x44, 0x9f, 0x52, 0x40, 0x48, 0x43, 0x1d, 0x1f, 0x5d, 0x51, 0x44, 0x41, 0x44, 0x4b, 0x52, 0x1f, 0x40, 0x53, 0x9f, 0x52, 0x53, 0x40, 0x46, 0x4d, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1b, 0x1f, 0x6, 0x48, 0x55, 0x44, 0x9f, 0x4c, 0x44, 0x1f, 0x4f, 0x51, 0x4e, 0x41, 0x4b, 0x44, 0x4c, 0x52, 0x1d, 0x1f, 0x46, 0x48, 0x55, 0x44, 0x9f, 0x4c, 0x44, 0x1f, 0x56, 0x4e, 0x51, 0x4a, 0x1d, 0x1f, 0x46, 0x48, 0x55, 0x44, 0x1f, 0x4c, 0x44, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x4e, 0x52, 0x53, 0x1f, 0x40, 0x41, 0x52, 0x53, 0x51, 0x54, 0x52, 0x44, 0x9f, 0x42, 0x51, 0x58, 0x4f, 0x53, 0x4e, 0x46, 0x51, 0x40, 0x4c, 0x1f, 0x4e, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4c, 0x4e, 0x52, 0x53, 0x1f, 0x48, 0x4d, 0x53, 0x51, 0x48, 0x42, 0x40, 0x53, 0x44, 0x9f, ], [0x40, 0x4d, 0x40, 0x4b, 0x58, 0x52, 0x48, 0x52, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x8, 0x1f, 0x40, 0xcc, 0x48, 0x4d, 0x1f, 0x4c, 0x58, 0x1f, 0x4e, 0x56, 0x4d, 0x1f, 0x4f, 0x51, 0x4e, 0x4f, 0x44, 0x51, 0x9f, 0x40, 0x53, 0x4c, 0x4e, 0x52, 0x4f, 0x47, 0x44, 0x51, 0x44, 0x1b, 0x1f, 0x8, 0x1f, 0x42, 0x40, 0x4d, 0x9f, 0x43, 0x48, 0x52, 0x4f, 0x44, 0x4d, 0x52, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x4d, 0x1f, 0x56, 0x48, 0x53, 0xc7, 0x40, 0x51, 0x53, 0x48, 0x45, 0x48, 0x42, 0x48, 0x40, 0x4b, 0x9f, 0x52, 0x53, 0x48, 0x4c, 0x54, 0x4b, 0x40, 0x4d, 0x53, 0x52, 0x1b, 0x1f, 0x1, 0x54, 0x53, 0x1f, 0x8, 0x9f, 0x40, 0x41, 0x47, 0x4e, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x43, 0x54, 0x4b, 0x4b, 0x9f, 0x51, 0x4e, 0x54, 0x53, 0x48, 0x4d, 0x44, 0x1f, 0x4e, 0x45, 0x9f, ], [0x44, 0x57, 0x48, 0x52, 0x53, 0x44, 0x4d, 0x42, 0x44, 0x1b, 0x1f, 0x8, 0x1f, 0x42, 0x51, 0x40, 0x55, 0xc4, 0x45, 0x4e, 0x51, 0x1f, 0x4c, 0x44, 0x4d, 0x53, 0x40, 0x4b, 0x9f, 0x44, 0x57, 0x40, 0x4b, 0x53, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1b, 0x1f, 0x13, 0x47, 0x40, 0x53, 0x9f, 0x48, 0x52, 0x1f, 0x56, 0x47, 0x58, 0x1f, 0x8, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x9f, 0x42, 0x47, 0x4e, 0x52, 0x44, 0x4d, 0x1f, 0x4c, 0x58, 0x1f, 0x4e, 0x56, 0x4d, 0x9f, 0x4f, 0x40, 0x51, 0x53, 0x48, 0x42, 0x54, 0x4b, 0x40, 0x51, 0x9f, 0x4f, 0x51, 0x4e, 0x45, 0x44, 0x52, 0x52, 0x48, 0x4e, 0x4d, 0x1d, 0x1f, 0x4e, 0x51, 0x9f, 0x51, 0x40, 0x53, 0x47, 0x44, 0x51, 0x1f, 0x42, 0x51, 0x44, 0x40, 0x53, 0x44, 0x43, 0x1f, 0x48, 0x53, 0x9d, ], [0x45, 0x4e, 0x51, 0x1f, 0x8, 0x1f, 0x40, 0x4c, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4e, 0x4d, 0x4b, 0x58, 0x9f, 0x4e, 0x4d, 0x44, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x1b, 0xdd, 0x1c, 0x3, 0x4e, 0x58, 0x4b, 0x44, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0xb, 0x48, 0x45, 0x44, 0x1f, 0x48, 0x52, 0x1f, 0x48, 0x4d, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x44, 0x4b, 0xd8, 0x52, 0x53, 0x51, 0x40, 0x4d, 0x46, 0x44, 0x51, 0x1f, 0x53, 0x47, 0x40, 0x4d, 0x9f, 0x40, 0x4d, 0x58, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x53, 0x47, 0xc4, 0x4c, 0x48, 0x4d, 0x43, 0x1f, 0x4e, 0x45, 0x1f, 0x4c, 0x40, 0x4d, 0x1f, 0x42, 0x4e, 0x54, 0x4b, 0x43, 0x9f, 0x48, 0x4d, 0x55, 0x44, 0x4d, 0x53, 0x1b, 0x1f, 0x16, 0x44, 0x1f, 0x56, 0x4e, 0x54, 0x4b, 0x43, 0x9f, 0x4d, 0x4e, 0x53, 0x1f, 0x43, 0x40, 0x51, 0x44, 0x1f, 0x53, 0x4e, 0x9f, 0x42, 0x4e, 0x4d, 0x42, 0x44, 0x48, 0x55, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x52, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x40, 0x51, 0x44, 0x9f, ], [0x51, 0x44, 0x40, 0x4b, 0x4b, 0x58, 0x1f, 0x4c, 0x44, 0x51, 0x44, 0x9f, 0x42, 0x4e, 0x4c, 0x4c, 0x4e, 0x4d, 0x4f, 0x4b, 0x40, 0x42, 0x44, 0x52, 0x1f, 0x4e, 0x45, 0x9f, 0x44, 0x57, 0x48, 0x52, 0x53, 0x44, 0x4d, 0x42, 0x44, 0x1b, 0x1f, 0x8, 0x45, 0x1f, 0x56, 0x44, 0x9f, 0x42, 0x4e, 0x54, 0x4b, 0x43, 0x1f, 0x45, 0x4b, 0x58, 0x1f, 0x4e, 0x54, 0x53, 0x1f, 0x4e, 0x45, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x56, 0x48, 0x4d, 0x43, 0x4e, 0x56, 0x1f, 0x47, 0x40, 0x4d, 0x43, 0x9f, 0x48, 0x4d, 0x1f, 0x47, 0x40, 0x4d, 0x43, 0x1d, 0x1f, 0x47, 0x4e, 0x55, 0x44, 0x51, 0x9f, 0x4e, 0x55, 0x44, 0x51, 0x1f, 0x53, 0x47, 0x48, 0x52, 0x1f, 0x46, 0x51, 0x44, 0x40, 0x53, 0x9f, 0x42, 0x48, 0x53, 0x58, 0x1d, 0x1f, 0x46, 0x44, 0x4d, 0x53, 0x4b, 0x58, 0x9f, ], [0x51, 0x44, 0x4c, 0x4e, 0x55, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x51, 0x4e, 0x4e, 0x45, 0x52, 0x1d, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x4f, 0x44, 0x44, 0x4f, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0xd3, 0x53, 0x47, 0x44, 0x1f, 0x50, 0x54, 0x44, 0x44, 0x51, 0x1f, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x52, 0x9f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x40, 0x51, 0x44, 0x1f, 0x46, 0x4e, 0x48, 0x4d, 0x46, 0x9f, 0x4e, 0x4d, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x53, 0x51, 0x40, 0x4d, 0x46, 0x44, 0x9f, 0x42, 0x4e, 0x48, 0x4d, 0x42, 0x48, 0x43, 0x44, 0x4d, 0x42, 0x44, 0x52, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4f, 0x4b, 0x40, 0x4d, 0x4d, 0x48, 0x4d, 0x46, 0x52, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x42, 0x51, 0x4e, 0x52, 0x52, 0x1c, 0x4f, 0x54, 0x51, 0x4f, 0x4e, 0x52, 0x44, 0x52, 0x1d, 0x9f, ], [0x53, 0x47, 0x44, 0x1f, 0x56, 0x4e, 0x4d, 0x43, 0x44, 0x51, 0x45, 0x54, 0x4b, 0x9f, 0x42, 0x47, 0x40, 0x48, 0x4d, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x44, 0x55, 0x44, 0x4d, 0x53, 0x52, 0x1d, 0x9f, 0x56, 0x4e, 0x51, 0x4a, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x9f, 0x46, 0x44, 0x4d, 0x44, 0x51, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x52, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x4b, 0x44, 0x40, 0x43, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4c, 0x4e, 0x52, 0x53, 0x1f, 0x4e, 0x54, 0x53, 0x51, 0x44, 0x9f, 0x51, 0x44, 0x52, 0x54, 0x4b, 0x53, 0x52, 0x1d, 0x1f, 0x48, 0x53, 0x1f, 0x56, 0x4e, 0x54, 0x4b, 0x43, 0x9f, 0x4c, 0x40, 0x4a, 0x44, 0x1f, 0x40, 0x4b, 0x4b, 0x1f, 0x45, 0x48, 0x42, 0x53, 0x48, 0x4e, 0x4d, 0x9f, ], [0x56, 0x48, 0x53, 0x47, 0x1f, 0x48, 0x53, 0x52, 0x9f, 0x42, 0x4e, 0x4d, 0x55, 0x44, 0x4d, 0x53, 0x48, 0x4e, 0x4d, 0x40, 0x4b, 0x48, 0x53, 0x48, 0x44, 0x52, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x45, 0x4e, 0x51, 0x44, 0x52, 0x44, 0x44, 0x4d, 0x9f, 0x42, 0x4e, 0x4d, 0x42, 0x4b, 0x54, 0x52, 0x48, 0x4e, 0x4d, 0x52, 0x1f, 0x4c, 0x4e, 0x52, 0x53, 0x9f, 0x52, 0x53, 0x40, 0x4b, 0x44, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x54, 0x4d, 0x4f, 0x51, 0x4e, 0x45, 0x48, 0x53, 0x40, 0x41, 0x4b, 0x44, 0x1b, 0x9f, 0x1c, 0x3, 0x4e, 0x58, 0x4b, 0x44, 0x1f, 0x9f, 0x9f, ]], +[[0x13, 0x47, 0x44, 0x1f, 0x52, 0x53, 0x4e, 0x51, 0x58, 0x1f, 0x52, 0x4e, 0x1f, 0x45, 0x40, 0x51, 0x1b, 0x9f, 0x8, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x41, 0x44, 0x46, 0x48, 0x4d, 0x4d, 0x48, 0x4d, 0x46, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x14, 0x4d, 0x48, 0x55, 0x44, 0x51, 0x52, 0x44, 0x1f, 0x56, 0x40, 0x52, 0x9f, 0x42, 0x51, 0x44, 0x40, 0x53, 0x44, 0x43, 0x1b, 0x1f, 0x13, 0x47, 0x48, 0x52, 0x1f, 0x47, 0x40, 0x52, 0x9f, 0x4c, 0x40, 0x43, 0x44, 0x1f, 0x40, 0x1f, 0x4b, 0x4e, 0x53, 0x1f, 0x4e, 0x45, 0x9f, 0x4f, 0x44, 0x4e, 0x4f, 0x4b, 0x44, 0x1f, 0x55, 0x44, 0x51, 0x58, 0x1f, 0x40, 0x4d, 0x46, 0x51, 0x58, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x41, 0x44, 0x44, 0x4d, 0x1f, 0x56, 0x48, 0x43, 0x44, 0x4b, 0x58, 0x9f, 0x51, 0x44, 0x46, 0x40, 0x51, 0x43, 0x44, 0x43, 0x1f, 0x40, 0x52, 0x1f, 0x40, 0x1f, 0x41, 0x40, 0x43, 0x9f, ], [0x4c, 0x4e, 0x55, 0x44, 0x1b, 0x1f, 0x1c, 0x0, 0x43, 0x40, 0x4c, 0x52, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x5, 0x4e, 0x51, 0x1f, 0x48, 0x4d, 0x52, 0x53, 0x40, 0x4d, 0x42, 0x44, 0x1d, 0x1f, 0x4e, 0x4d, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4f, 0x4b, 0x40, 0x4d, 0x44, 0x53, 0x1f, 0x4, 0x40, 0x51, 0x53, 0x47, 0x1d, 0x9f, 0x4c, 0x40, 0x4d, 0x1f, 0x47, 0x40, 0x43, 0x1f, 0x40, 0x4b, 0x56, 0x40, 0x58, 0x52, 0x9f, 0x40, 0x52, 0x52, 0x54, 0x4c, 0x44, 0x43, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x47, 0x44, 0x9f, 0x56, 0x40, 0x52, 0x1f, 0x4c, 0x4e, 0x51, 0x44, 0x9f, 0x48, 0x4d, 0x53, 0x44, 0x4b, 0x4b, 0x48, 0x46, 0x44, 0x4d, 0x53, 0x1f, 0x53, 0x47, 0x40, 0x4d, 0x9f, 0x43, 0x4e, 0x4b, 0x4f, 0x47, 0x48, 0x4d, 0x52, 0x1f, 0x41, 0x44, 0x42, 0x40, 0x54, 0x52, 0x44, 0x9f, 0x47, 0x44, 0x1f, 0x47, 0x40, 0x43, 0x1f, 0x40, 0x42, 0x47, 0x48, 0x44, 0x55, 0x44, 0x43, 0x1f, 0x52, 0xce, ], [0x4c, 0x54, 0x42, 0x47, 0x1c, 0x53, 0x47, 0x44, 0x1f, 0x56, 0x47, 0x44, 0x44, 0x4b, 0x1d, 0x9f, 0xd, 0x44, 0x56, 0x1f, 0x18, 0x4e, 0x51, 0x4a, 0x1d, 0x1f, 0x56, 0x40, 0x51, 0x52, 0x1f, 0x40, 0x4d, 0xc3, 0x52, 0x4e, 0x1f, 0x4e, 0x4d, 0x1c, 0x56, 0x47, 0x48, 0x4b, 0x52, 0x53, 0x1f, 0x40, 0x4b, 0x4b, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x43, 0x4e, 0x4b, 0x4f, 0x47, 0x48, 0x4d, 0x52, 0x1f, 0x47, 0x40, 0x43, 0x9f, 0x44, 0x55, 0x44, 0x51, 0x1f, 0x43, 0x4e, 0x4d, 0x44, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x4c, 0x54, 0x42, 0xca, 0x40, 0x41, 0x4e, 0x54, 0x53, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x56, 0x40, 0x53, 0x44, 0xd1, 0x47, 0x40, 0x55, 0x48, 0x4d, 0x46, 0x1f, 0x40, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x9f, 0x53, 0x48, 0x4c, 0x44, 0x1b, 0x1f, 0x1, 0x54, 0x53, 0x9f, ], [0x42, 0x4e, 0x4d, 0x55, 0x44, 0x51, 0x52, 0x44, 0x4b, 0x58, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x43, 0x4e, 0x4b, 0x4f, 0x47, 0x48, 0x4d, 0x52, 0x1f, 0x47, 0x40, 0x43, 0x9f, 0x40, 0x4b, 0x56, 0x40, 0x58, 0x52, 0x1f, 0x41, 0x44, 0x4b, 0x48, 0x44, 0x55, 0x44, 0x43, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x45, 0x40, 0xd1, 0x4c, 0x4e, 0x51, 0x44, 0x1f, 0x48, 0x4d, 0x53, 0x44, 0x4b, 0x4b, 0x48, 0x46, 0x44, 0x4d, 0x53, 0x9f, 0x53, 0x47, 0x40, 0x4d, 0x1f, 0x4c, 0x40, 0x4d, 0x1b, 0x45, 0x4e, 0x51, 0x9f, 0x4f, 0x51, 0x44, 0x42, 0x48, 0x52, 0x44, 0x4b, 0x58, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x40, 0x4c, 0xc4, 0x51, 0x44, 0x40, 0x52, 0x4e, 0x4d, 0x52, 0x1b, 0x1f, 0x1c, 0x0, 0x43, 0x40, 0x4c, 0x52, 0x1f, 0x9f, ]], +[[0x8, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x4a, 0x4d, 0x4e, 0x56, 0x4d, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x40, 0x51, 0x44, 0x1f, 0x40, 0x4d, 0x9f, 0x48, 0x4d, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x44, 0x1f, 0x4d, 0x54, 0x4c, 0x41, 0x44, 0x51, 0x1f, 0x4e, 0xc5, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x52, 0x1d, 0x1f, 0x52, 0x48, 0x4c, 0x4f, 0x4b, 0x58, 0x9f, 0x41, 0x44, 0x42, 0x40, 0x54, 0x52, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x48, 0x52, 0x9f, 0x40, 0x4d, 0x1f, 0x48, 0x4d, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x44, 0x1f, 0x40, 0x4c, 0x4e, 0x54, 0x4d, 0xd3, 0x4e, 0x45, 0x1f, 0x52, 0x4f, 0x40, 0x42, 0x44, 0x1f, 0x45, 0x4e, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x9f, 0x53, 0x4e, 0x1f, 0x41, 0x44, 0x1f, 0x48, 0x4d, 0x1b, 0x1f, 0x7, 0x4e, 0x56, 0x44, 0x55, 0x44, 0x51, 0x9d, ], [0x4d, 0x4e, 0x53, 0x1f, 0x44, 0x55, 0x44, 0x51, 0x58, 0x1f, 0x4e, 0x4d, 0x44, 0x1f, 0x4e, 0x45, 0x9f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x48, 0x52, 0x1f, 0x48, 0x4d, 0x47, 0x40, 0x41, 0x48, 0x53, 0x44, 0x43, 0x9b, 0x13, 0x47, 0x44, 0x51, 0x44, 0x45, 0x4e, 0x51, 0x44, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x9f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x41, 0x44, 0x1f, 0x40, 0x1f, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x44, 0x9f, 0x4d, 0x54, 0x4c, 0x41, 0x44, 0x51, 0x1f, 0x4e, 0x45, 0x9f, 0x48, 0x4d, 0x47, 0x40, 0x41, 0x48, 0x53, 0x44, 0x43, 0x1f, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x52, 0x1b, 0x9f, 0x0, 0x4d, 0x58, 0x1f, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x44, 0x1f, 0x4d, 0x54, 0x4c, 0x41, 0x44, 0x51, 0x9f, 0x43, 0x48, 0x55, 0x48, 0x43, 0x44, 0x43, 0x1f, 0x41, 0x58, 0x9f, ], [0x48, 0x4d, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x58, 0x1f, 0x48, 0x52, 0x1f, 0x40, 0x52, 0x9f, 0x4d, 0x44, 0x40, 0x51, 0x1f, 0x53, 0x4e, 0x1f, 0x4d, 0x4e, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1f, 0x40, 0xd2, 0x4c, 0x40, 0x4a, 0x44, 0x52, 0x1f, 0x4d, 0x4e, 0x1f, 0x4e, 0x43, 0x43, 0x52, 0x1d, 0x1f, 0x52, 0x4e, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x40, 0x55, 0x44, 0x51, 0x40, 0x46, 0x44, 0x9f, 0x4f, 0x4e, 0x4f, 0x54, 0x4b, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x4e, 0x45, 0x1f, 0x40, 0x4b, 0x4b, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4f, 0x4b, 0x40, 0x4d, 0x44, 0x53, 0x52, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0xc4, 0x14, 0x4d, 0x48, 0x55, 0x44, 0x51, 0x52, 0x44, 0x1f, 0x42, 0x40, 0x4d, 0x1f, 0x41, 0x44, 0x9f, 0x52, 0x40, 0x48, 0x43, 0x1f, 0x53, 0x4e, 0x1f, 0x41, 0x44, 0x1f, 0x59, 0x44, 0x51, 0x4e, 0x1b, 0x9f, ], [0x5, 0x51, 0x4e, 0x4c, 0x1f, 0x53, 0x47, 0x48, 0x52, 0x1f, 0x48, 0x53, 0x9f, 0x45, 0x4e, 0x4b, 0x4b, 0x4e, 0x56, 0x52, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4f, 0x4e, 0x4f, 0x54, 0x4b, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x56, 0x47, 0x4e, 0x4b, 0x44, 0x1f, 0x14, 0x4d, 0x48, 0x55, 0x44, 0x51, 0x52, 0x44, 0x1f, 0x48, 0x52, 0x9f, 0x40, 0x4b, 0x52, 0x4e, 0x1f, 0x59, 0x44, 0x51, 0x4e, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x40, 0x4d, 0x58, 0x1f, 0x4f, 0x44, 0x4e, 0x4f, 0x4b, 0x44, 0x9f, 0x58, 0x4e, 0x54, 0x1f, 0x4c, 0x40, 0x58, 0x1f, 0x4c, 0x44, 0x44, 0x53, 0x1f, 0x45, 0x51, 0x4e, 0x4c, 0x9f, 0x53, 0x48, 0x4c, 0x44, 0x1f, 0x53, 0x4e, 0x1f, 0x53, 0x48, 0x4c, 0x44, 0x1f, 0x40, 0x51, 0x44, 0x9f, ], [0x4c, 0x44, 0x51, 0x44, 0x4b, 0x58, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4f, 0x51, 0x4e, 0x43, 0x54, 0x42, 0x53, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x40, 0x9f, 0x43, 0x44, 0x51, 0x40, 0x4d, 0x46, 0x44, 0x43, 0x9f, 0x48, 0x4c, 0x40, 0x46, 0x48, 0x4d, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1b, 0x9f, 0x1c, 0x0, 0x43, 0x40, 0x4c, 0x52, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x5, 0x40, 0x51, 0x1f, 0x4e, 0x55, 0x44, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x48, 0x52, 0x53, 0xd8, 0x4c, 0x4e, 0x54, 0x4d, 0x53, 0x40, 0x48, 0x4d, 0x52, 0x1f, 0x42, 0x4e, 0x4b, 0x43, 0x1f, 0x13, 0x4e, 0x9f, 0x43, 0x54, 0x4d, 0x46, 0x44, 0x4e, 0x4d, 0x52, 0x1f, 0x43, 0x44, 0x44, 0x4f, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x42, 0x40, 0x55, 0x44, 0x51, 0x4d, 0x52, 0x1f, 0x4e, 0x4b, 0x43, 0x1f, 0x16, 0x44, 0x9f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x40, 0x56, 0x40, 0x58, 0x1d, 0x1f, 0x44, 0x51, 0x44, 0x9f, 0x41, 0x51, 0x44, 0x40, 0x4a, 0x1f, 0x4e, 0x45, 0x1f, 0x43, 0x40, 0x58, 0x1d, 0x1f, 0x13, 0x4e, 0x9f, 0x52, 0x44, 0x44, 0x4a, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4f, 0x40, 0x4b, 0x44, 0x9f, 0x44, 0x4d, 0x42, 0x47, 0x40, 0x4d, 0x53, 0x44, 0x43, 0x1f, 0x46, 0x4e, 0x4b, 0x43, 0x1b, 0x9f, ], [0x13, 0x47, 0x44, 0x1f, 0x43, 0x56, 0x40, 0x51, 0x55, 0x44, 0x52, 0x1f, 0x4e, 0x45, 0x9f, 0x58, 0x4e, 0x51, 0x44, 0x1f, 0x4c, 0x40, 0x43, 0x44, 0x1f, 0x4c, 0x48, 0x46, 0x47, 0x53, 0x58, 0x9f, 0x52, 0x4f, 0x44, 0x4b, 0x4b, 0x52, 0x1d, 0x1f, 0x16, 0x47, 0x48, 0x4b, 0x44, 0x9f, 0x47, 0x40, 0x4c, 0x4c, 0x44, 0x51, 0x52, 0x1f, 0x45, 0x44, 0x4b, 0x4b, 0x1f, 0x4b, 0x48, 0x4a, 0x44, 0x9f, 0x51, 0x48, 0x4d, 0x46, 0x48, 0x4d, 0x46, 0x1f, 0x41, 0x44, 0x4b, 0x4b, 0x52, 0x1f, 0x8, 0x4d, 0x9f, 0x4f, 0x4b, 0x40, 0x42, 0x44, 0x52, 0x1f, 0x43, 0x44, 0x44, 0x4f, 0x1d, 0x1f, 0x56, 0x47, 0x44, 0x51, 0xc4, 0x43, 0x40, 0x51, 0x4a, 0x1f, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x52, 0x1f, 0x52, 0x4b, 0x44, 0x44, 0x4f, 0x9d, 0x8, 0x4d, 0x1f, 0x47, 0x4e, 0x4b, 0x4b, 0x4e, 0x56, 0x1f, 0x47, 0x40, 0x4b, 0x4b, 0x52, 0x9f, ], [0x41, 0x44, 0x4d, 0x44, 0x40, 0x53, 0x47, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x45, 0x44, 0x4b, 0x4b, 0x52, 0x9b, 0x5, 0x4e, 0x51, 0x1f, 0x40, 0x4d, 0x42, 0x48, 0x44, 0x4d, 0x53, 0x1f, 0x4a, 0x48, 0x4d, 0x46, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x44, 0x4b, 0x55, 0x48, 0x52, 0x47, 0x1f, 0x4b, 0x4e, 0x51, 0x43, 0x9f, 0x13, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x4c, 0x40, 0x4d, 0x58, 0x1f, 0x40, 0x9f, 0x46, 0x4b, 0x44, 0x40, 0x4c, 0x48, 0x4d, 0x46, 0x1f, 0x46, 0x4e, 0x4b, 0x43, 0x44, 0x4d, 0x9f, 0x47, 0x4e, 0x40, 0x51, 0x43, 0x1f, 0x13, 0x47, 0x44, 0x58, 0x1f, 0x52, 0x47, 0x40, 0x4f, 0x44, 0x43, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x56, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x53, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x42, 0x40, 0x54, 0x46, 0x47, 0x53, 0x9f, ], [0x13, 0x4e, 0x1f, 0x47, 0x48, 0x43, 0x44, 0x1f, 0x48, 0x4d, 0x1f, 0x46, 0x44, 0x4c, 0x52, 0x1f, 0x4e, 0xcd, 0x47, 0x48, 0x4b, 0x53, 0x1f, 0x4e, 0x45, 0x1f, 0x52, 0x56, 0x4e, 0x51, 0x43, 0x1b, 0x1f, 0xe, 0x4d, 0x9f, 0x52, 0x48, 0x4b, 0x55, 0x44, 0x51, 0x1f, 0x4d, 0x44, 0x42, 0x4a, 0x4b, 0x40, 0x42, 0x44, 0x52, 0x9f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x52, 0x53, 0x51, 0x54, 0x4d, 0x46, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x45, 0x4b, 0x4e, 0x56, 0x44, 0x51, 0x48, 0x4d, 0x46, 0x1f, 0x52, 0x53, 0x40, 0x51, 0x52, 0x1d, 0x9f, 0x4e, 0x4d, 0x1f, 0x42, 0x51, 0x4e, 0x56, 0x4d, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x9f, 0x47, 0x54, 0x4d, 0x46, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x43, 0x51, 0x40, 0x46, 0x4e, 0x4d, 0x1c, 0x45, 0x48, 0x51, 0x44, 0x1d, 0x1f, 0x48, 0x4d, 0x9f, ], [0x53, 0x56, 0x48, 0x52, 0x53, 0x44, 0x43, 0x1f, 0x56, 0x48, 0x51, 0x44, 0x1f, 0x13, 0x47, 0x44, 0x58, 0x9f, 0x4c, 0x44, 0x52, 0x47, 0x44, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x9f, 0x4e, 0x45, 0x1f, 0x4c, 0x4e, 0x4e, 0x4d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x52, 0x54, 0x4d, 0x1b, 0x9f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x5, 0x40, 0x51, 0x1f, 0x4e, 0x55, 0x44, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x48, 0x52, 0x53, 0xd8, 0x4c, 0x4e, 0x54, 0x4d, 0x53, 0x40, 0x48, 0x4d, 0x52, 0x1f, 0x42, 0x4e, 0x4b, 0x43, 0x1f, 0x13, 0x4e, 0x9f, 0x43, 0x54, 0x4d, 0x46, 0x44, 0x4e, 0x4d, 0x52, 0x1f, 0x43, 0x44, 0x44, 0x4f, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x42, 0x40, 0x55, 0x44, 0x51, 0x4d, 0x52, 0x1f, 0x4e, 0x4b, 0x43, 0x1f, 0x16, 0x44, 0x9f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x40, 0x56, 0x40, 0x58, 0x1d, 0x1f, 0x44, 0x51, 0x44, 0x9f, 0x41, 0x51, 0x44, 0x40, 0x4a, 0x1f, 0x4e, 0x45, 0x1f, 0x43, 0x40, 0x58, 0x1d, 0x1f, 0x13, 0x4e, 0x9f, 0x42, 0x4b, 0x40, 0x48, 0x4c, 0x1f, 0x4e, 0x54, 0x51, 0x9f, 0x4b, 0x4e, 0x4d, 0x46, 0x1c, 0x45, 0x4e, 0x51, 0x46, 0x4e, 0x53, 0x53, 0x44, 0x4d, 0x9f, ], [0x46, 0x4e, 0x4b, 0x43, 0x1b, 0x1f, 0x6, 0x4e, 0x41, 0x4b, 0x44, 0x53, 0x52, 0x1f, 0x53, 0x47, 0x44, 0xd8, 0x42, 0x40, 0x51, 0x55, 0x44, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x45, 0x4e, 0x51, 0x9f, 0x53, 0x47, 0x44, 0x4c, 0x52, 0x44, 0x4b, 0x55, 0x44, 0x52, 0x1f, 0x0, 0x4d, 0x43, 0x9f, 0x47, 0x40, 0x51, 0x4f, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x46, 0x4e, 0x4b, 0x43, 0x1d, 0x9f, 0x56, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x4d, 0x4e, 0x1f, 0x4c, 0x40, 0x4d, 0x9f, 0x43, 0x44, 0x4b, 0x55, 0x44, 0x52, 0x1f, 0x13, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x4b, 0x40, 0x58, 0x9f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x4b, 0x4e, 0x4d, 0x46, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x4c, 0x40, 0x4d, 0x58, 0x1f, 0x40, 0x1f, 0x52, 0x4e, 0x4d, 0x46, 0x1f, 0x16, 0x40, 0x52, 0x9f, ], [0x52, 0x54, 0x4d, 0x46, 0x1f, 0x54, 0x4d, 0x47, 0x44, 0x40, 0x51, 0x43, 0x1f, 0x41, 0x58, 0x9f, 0x4c, 0x44, 0x4d, 0x1f, 0x4e, 0x51, 0x1f, 0x44, 0x4b, 0x55, 0x44, 0x52, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x4f, 0x48, 0x4d, 0x44, 0x52, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x51, 0x4e, 0x40, 0x51, 0x48, 0x4d, 0xc6, 0x4e, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x47, 0x44, 0x48, 0x46, 0x47, 0x53, 0x1d, 0x1f, 0x13, 0x47, 0xc4, 0x56, 0x48, 0x4d, 0x43, 0x52, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x4c, 0x4e, 0x40, 0x4d, 0x48, 0x4d, 0xc6, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4d, 0x48, 0x46, 0x47, 0x53, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x45, 0x48, 0x51, 0x44, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x51, 0x44, 0x43, 0x1d, 0x1f, 0x48, 0x53, 0x9f, 0x45, 0x4b, 0x40, 0x4c, 0x48, 0x4d, 0x46, 0x1f, 0x52, 0x4f, 0x51, 0x44, 0x40, 0x43, 0x1b, 0x9f, ], [0x13, 0x47, 0x44, 0x1f, 0x53, 0x51, 0x44, 0x44, 0x52, 0x1f, 0x4b, 0x48, 0x4a, 0x44, 0x9f, 0x53, 0x4e, 0x51, 0x42, 0x47, 0x44, 0x52, 0x1f, 0x41, 0x4b, 0x40, 0x59, 0x44, 0x43, 0x9f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x1b, 0x9f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x13, 0x47, 0x44, 0x1f, 0x41, 0x44, 0x4b, 0x4b, 0x52, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x9f, 0x51, 0x48, 0x4d, 0x46, 0x48, 0x4d, 0x46, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x43, 0x40, 0x4b, 0x44, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x4c, 0x44, 0x4d, 0x9f, 0x4b, 0x4e, 0x4e, 0x4a, 0x44, 0x43, 0x1f, 0x54, 0x4f, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x9f, 0x45, 0x40, 0x42, 0x44, 0x52, 0x1f, 0x4f, 0x40, 0x4b, 0x44, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x4d, 0x9f, 0x43, 0x51, 0x40, 0x46, 0x4e, 0x4d, 0x5d, 0x52, 0x1f, 0x48, 0x51, 0x44, 0x1f, 0x4c, 0x4e, 0x51, 0x44, 0x9f, 0x45, 0x48, 0x44, 0x51, 0x42, 0x44, 0x1f, 0x53, 0x47, 0x40, 0x4d, 0x1f, 0x45, 0x48, 0x51, 0x44, 0x9f, 0xb, 0x40, 0x48, 0x43, 0x1f, 0x4b, 0x4e, 0x56, 0x1f, 0x53, 0x47, 0x44, 0x48, 0x51, 0x9f, ], [0x53, 0x4e, 0x56, 0x44, 0x51, 0x52, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0x4e, 0x54, 0x52, 0x44, 0x52, 0x9f, 0x45, 0x51, 0x40, 0x48, 0x4b, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x4c, 0x4e, 0x54, 0x4d, 0x53, 0x40, 0x48, 0x4d, 0x1f, 0x52, 0x4c, 0x4e, 0x4a, 0x44, 0x43, 0x9f, 0x41, 0x44, 0x4d, 0x44, 0x40, 0x53, 0x47, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x4e, 0x4e, 0x4d, 0x1b, 0x9f, 0x13, 0x47, 0x44, 0x1f, 0x43, 0x56, 0x40, 0x51, 0x55, 0x44, 0x52, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x9f, 0x47, 0x44, 0x40, 0x51, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x53, 0x51, 0x40, 0x4c, 0x4f, 0x1f, 0x4e, 0xc5, 0x43, 0x4e, 0x4e, 0x4c, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x58, 0x1f, 0x45, 0x4b, 0x44, 0x43, 0x9f, 0x53, 0x47, 0x44, 0x48, 0x51, 0x1f, 0x47, 0x40, 0x4b, 0x4b, 0x1d, 0x1f, 0x53, 0x4e, 0x9f, ], [0x43, 0x58, 0x48, 0x4d, 0x46, 0x1f, 0x45, 0x40, 0x4b, 0x4b, 0x1f, 0x1, 0x44, 0x4d, 0x44, 0x40, 0x53, 0xc7, 0x47, 0x48, 0x52, 0x1f, 0x45, 0x44, 0x44, 0x53, 0x1d, 0x1f, 0x41, 0x44, 0x4d, 0x44, 0x40, 0x53, 0x47, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x4e, 0x4e, 0x4d, 0x1b, 0x1f, 0x5, 0x40, 0x51, 0x1f, 0x4e, 0x55, 0x44, 0xd1, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x48, 0x52, 0x53, 0x58, 0x9f, 0x4c, 0x4e, 0x54, 0x4d, 0x53, 0x40, 0x48, 0x4d, 0x52, 0x1f, 0x46, 0x51, 0x48, 0x4c, 0x1f, 0x13, 0x4e, 0x9f, 0x43, 0x54, 0x4d, 0x46, 0x44, 0x4e, 0x4d, 0x52, 0x1f, 0x43, 0x44, 0x44, 0x4f, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x42, 0x40, 0x55, 0x44, 0x51, 0x4d, 0x52, 0x1f, 0x43, 0x48, 0x4c, 0x1f, 0x16, 0x44, 0x9f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x40, 0x56, 0x40, 0x58, 0x1d, 0x1f, 0x44, 0x51, 0x44, 0x9f, ], [0x41, 0x51, 0x44, 0x40, 0x4a, 0x1f, 0x4e, 0x45, 0x1f, 0x43, 0x40, 0x58, 0x1d, 0x1f, 0x13, 0x4e, 0x9f, 0x56, 0x48, 0x4d, 0x1f, 0x4e, 0x54, 0x51, 0x1f, 0x47, 0x40, 0x51, 0x4f, 0x52, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x46, 0x4e, 0x4b, 0x43, 0x1f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x47, 0x48, 0x4c, 0x1a, 0x9f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x11, 0x4e, 0x40, 0x43, 0x52, 0x1f, 0x46, 0x4e, 0x1f, 0x44, 0x55, 0x44, 0x51, 0x1f, 0x44, 0x55, 0x44, 0xd1, 0x4e, 0x4d, 0x1d, 0x1f, 0xe, 0x55, 0x44, 0x51, 0x1f, 0x51, 0x4e, 0x42, 0x4a, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x54, 0x4d, 0x43, 0x44, 0x51, 0x1f, 0x53, 0x51, 0x44, 0x44, 0x1d, 0x1f, 0x1, 0x58, 0x9f, 0x42, 0x40, 0x55, 0x44, 0x52, 0x1f, 0x56, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x4d, 0x44, 0x55, 0x44, 0x51, 0x9f, 0x52, 0x54, 0x4d, 0x1f, 0x47, 0x40, 0x52, 0x1f, 0x52, 0x47, 0x4e, 0x4d, 0x44, 0x1d, 0x1f, 0x1, 0x58, 0x9f, 0x52, 0x53, 0x51, 0x44, 0x40, 0x4c, 0x52, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x4d, 0x44, 0x55, 0x44, 0xd1, 0x45, 0x48, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x44, 0x40, 0x1b, 0x1f, 0xe, 0x55, 0x44, 0xd1, 0x52, 0x4d, 0x4e, 0x56, 0x1f, 0x41, 0x58, 0x1f, 0x56, 0x48, 0x4d, 0x53, 0x44, 0x51, 0x9f, ], [0x52, 0x4e, 0x56, 0x4d, 0x1d, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4c, 0x44, 0x51, 0x51, 0x58, 0x1f, 0x45, 0x4b, 0x4e, 0x56, 0x44, 0x51, 0x52, 0x9f, 0x4e, 0x45, 0x1f, 0x9, 0x54, 0x4d, 0x44, 0x1d, 0x1f, 0xe, 0x55, 0x44, 0x51, 0x9f, 0x46, 0x51, 0x40, 0x52, 0x52, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x4e, 0x55, 0x44, 0x51, 0x9f, 0x52, 0x53, 0x4e, 0x4d, 0x44, 0x1d, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x54, 0x4d, 0x43, 0x44, 0x51, 0x9f, 0x4c, 0x4e, 0x54, 0x4d, 0x53, 0x40, 0x48, 0x4d, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4c, 0x4e, 0x4e, 0x4d, 0x1b, 0x1f, 0x11, 0x4e, 0x40, 0x43, 0x52, 0x1f, 0x46, 0x4e, 0x9f, 0x44, 0x55, 0x44, 0x51, 0x1f, 0x44, 0x55, 0x44, 0x51, 0x1f, 0x4e, 0x4d, 0x1f, 0x14, 0x4d, 0x43, 0x44, 0xd1, ], [0x42, 0x4b, 0x4e, 0x54, 0x43, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x54, 0x4d, 0x43, 0x44, 0x51, 0x9f, 0x52, 0x53, 0x40, 0x51, 0x1d, 0x1f, 0x18, 0x44, 0x53, 0x1f, 0x45, 0x44, 0x44, 0x53, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x56, 0x40, 0x4d, 0x43, 0x44, 0x51, 0x48, 0x4d, 0x46, 0x9f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x46, 0x4e, 0x4d, 0x44, 0x1f, 0x13, 0x54, 0x51, 0x4d, 0x1f, 0x40, 0x53, 0x9f, 0x4b, 0x40, 0x52, 0x53, 0x1f, 0x53, 0x4e, 0x1f, 0x47, 0x4e, 0x4c, 0x44, 0x1f, 0x40, 0x45, 0x40, 0x51, 0x9b, 0x4, 0x58, 0x44, 0x52, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x45, 0x48, 0x51, 0x44, 0x1f, 0x40, 0x4d, 0xc3, 0x52, 0x56, 0x4e, 0x51, 0x43, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x52, 0x44, 0x44, 0x4d, 0x9f, 0x0, 0x4d, 0x43, 0x1f, 0x47, 0x4e, 0x51, 0x51, 0x4e, 0x51, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x9f, ], [0x47, 0x40, 0x4b, 0x4b, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x52, 0x53, 0x4e, 0x4d, 0x44, 0x9f, 0xb, 0x4e, 0x4e, 0x4a, 0x1f, 0x40, 0x53, 0x1f, 0x4b, 0x40, 0x52, 0x53, 0x1f, 0x4e, 0x4d, 0x9f, 0x4c, 0x44, 0x40, 0x43, 0x4e, 0x56, 0x52, 0x1f, 0x46, 0x51, 0x44, 0x44, 0x4d, 0x1f, 0x0, 0x4d, 0x43, 0x9f, 0x53, 0x51, 0x44, 0x44, 0x52, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0x48, 0x4b, 0x4b, 0x52, 0x9f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x4b, 0x4e, 0x4d, 0x46, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x9f, 0x4a, 0x4d, 0x4e, 0x56, 0x4d, 0x1b, 0x1f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, ]], +[[0x13, 0x47, 0x51, 0x44, 0x44, 0x1f, 0x11, 0x48, 0x4d, 0x46, 0x52, 0x1f, 0x45, 0x4e, 0x51, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4, 0x4b, 0x55, 0x44, 0x4d, 0x1c, 0x4a, 0x48, 0x4d, 0x46, 0x52, 0x9f, 0x54, 0x4d, 0x43, 0x44, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x4a, 0x58, 0x1d, 0x9f, 0x12, 0x44, 0x55, 0x44, 0x4d, 0x1f, 0x45, 0x4e, 0x51, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x3, 0x56, 0x40, 0x51, 0x45, 0x1c, 0x4b, 0x4e, 0x51, 0x43, 0x52, 0x1f, 0x48, 0x4d, 0x9f, 0x53, 0x47, 0x44, 0x48, 0x51, 0x1f, 0x47, 0x40, 0x4b, 0x4b, 0x52, 0x1f, 0x4e, 0x45, 0x9f, 0x52, 0x53, 0x4e, 0x4d, 0x44, 0x1d, 0x1f, 0xd, 0x48, 0x4d, 0x44, 0x1f, 0x45, 0x4e, 0x51, 0x9f, 0xc, 0x4e, 0x51, 0x53, 0x40, 0x4b, 0x1f, 0xc, 0x44, 0x4d, 0x1f, 0x43, 0x4e, 0x4e, 0x4c, 0x44, 0x43, 0x9f, ], [0x53, 0x4e, 0x1f, 0x43, 0x48, 0x44, 0x1d, 0x1f, 0xe, 0x4d, 0x44, 0x1f, 0x45, 0x4e, 0x51, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x3, 0x40, 0x51, 0x4a, 0x1f, 0xb, 0x4e, 0x51, 0x43, 0x1f, 0x4e, 0x4d, 0x9f, 0x47, 0x48, 0x52, 0x1f, 0x43, 0x40, 0x51, 0x4a, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x4d, 0x44, 0x1f, 0x8, 0xcd, 0x53, 0x47, 0x44, 0x1f, 0xb, 0x40, 0x4d, 0x43, 0x1f, 0x4e, 0x45, 0x1f, 0xc, 0x4e, 0x51, 0x43, 0x4e, 0xd1, 0x56, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x12, 0x47, 0x40, 0x43, 0x4e, 0x56, 0x52, 0x9f, 0x4b, 0x48, 0x44, 0x1b, 0x1f, 0xe, 0x4d, 0x44, 0x1f, 0x11, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x9f, 0x51, 0x54, 0x4b, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x40, 0x4b, 0x4b, 0x1d, 0x1f, 0xe, 0x4d, 0xc4, 0x11, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x1f, 0x45, 0x48, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x4c, 0x9d, ], [0xe, 0x4d, 0x44, 0x1f, 0x11, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x1f, 0x41, 0x51, 0x48, 0x4d, 0x46, 0x9f, 0x53, 0x47, 0x44, 0x4c, 0x1f, 0x40, 0x4b, 0x4b, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x48, 0x4d, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x43, 0x40, 0x51, 0x4a, 0x4d, 0x44, 0x52, 0x52, 0x1f, 0x41, 0x48, 0x4d, 0x43, 0x9f, 0x53, 0x47, 0x44, 0x4c, 0x1d, 0x1f, 0x8, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0xb, 0x40, 0x4d, 0x43, 0x9f, 0x4e, 0x45, 0x1f, 0xc, 0x4e, 0x51, 0x43, 0x4e, 0x51, 0x1f, 0x56, 0x47, 0x44, 0x51, 0x44, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x12, 0x47, 0x40, 0x43, 0x4e, 0x56, 0x52, 0x1f, 0x4b, 0x48, 0x44, 0x1b, 0x9f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, ]], +[[0x0, 0x4b, 0x4b, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x46, 0x4e, 0x4b, 0x43, 0x9f, 0x43, 0x4e, 0x44, 0x52, 0x1f, 0x4d, 0x4e, 0x53, 0x1f, 0x46, 0x4b, 0x48, 0x53, 0x53, 0x44, 0x51, 0x1d, 0x9f, 0xd, 0x4e, 0x53, 0x1f, 0x40, 0x4b, 0x4b, 0x1f, 0x53, 0x47, 0x4e, 0x52, 0x44, 0x1f, 0x56, 0x47, 0x4e, 0x9f, 0x56, 0x40, 0x4d, 0x43, 0x44, 0x51, 0x1f, 0x40, 0x51, 0x44, 0x1f, 0x4b, 0x4e, 0x52, 0x53, 0x1b, 0x9f, 0x13, 0x47, 0x44, 0x1f, 0x4e, 0x4b, 0x43, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x48, 0x52, 0x9f, 0x52, 0x53, 0x51, 0x4e, 0x4d, 0x46, 0x1f, 0x43, 0x4e, 0x44, 0x52, 0x1f, 0x4d, 0x4e, 0x53, 0x9f, 0x56, 0x48, 0x53, 0x47, 0x44, 0x51, 0x1d, 0x1f, 0x3, 0x44, 0x44, 0x4f, 0x1f, 0x51, 0x4e, 0x4e, 0x53, 0xd2, 0x40, 0x51, 0x44, 0x1f, 0x4d, 0x4e, 0x53, 0x1f, 0x51, 0x44, 0x40, 0x42, 0x47, 0x44, 0x43, 0x1f, 0x41, 0xd8, ], [0x53, 0x47, 0x44, 0x1f, 0x45, 0x51, 0x4e, 0x52, 0x53, 0x1b, 0x1f, 0x5, 0x51, 0x4e, 0x4c, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x40, 0x52, 0x47, 0x44, 0x52, 0x1f, 0x40, 0x1f, 0x45, 0x48, 0x51, 0x44, 0x9f, 0x52, 0x47, 0x40, 0x4b, 0x4b, 0x1f, 0x41, 0x44, 0x1f, 0x56, 0x4e, 0x4a, 0x44, 0x4d, 0x1d, 0x1f, 0x0, 0x9f, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x52, 0x47, 0x40, 0x43, 0x4e, 0x56, 0x52, 0x1f, 0x52, 0x47, 0x40, 0x4b, 0x4b, 0x9f, 0x52, 0x4f, 0x51, 0x48, 0x4d, 0x46, 0x1b, 0x1f, 0x11, 0x44, 0x4d, 0x44, 0x56, 0x44, 0x43, 0x9f, 0x52, 0x47, 0x40, 0x4b, 0x4b, 0x1f, 0x41, 0x44, 0x1f, 0x41, 0x4b, 0x40, 0x43, 0x44, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x41, 0x51, 0x4e, 0x4a, 0x44, 0x4d, 0x1d, 0x9f, ], [0x13, 0x47, 0x44, 0x1f, 0x42, 0x51, 0x4e, 0x56, 0x4d, 0x4b, 0x44, 0x52, 0x52, 0x9f, 0x40, 0x46, 0x40, 0x48, 0x4d, 0x1f, 0x52, 0x47, 0x40, 0x4b, 0x4b, 0x1f, 0x41, 0x44, 0x9f, 0x4a, 0x48, 0x4d, 0x46, 0x1b, 0x1f, 0x1c, 0x13, 0x4e, 0x4b, 0x4a, 0x48, 0x44, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x16, 0x47, 0x4e, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x52, 0x1d, 0x1f, 0x2, 0x40, 0x4d, 0x1b, 0x9f, 0x16, 0x47, 0x4e, 0x1f, 0x53, 0x51, 0x48, 0x44, 0x52, 0x1d, 0x1f, 0x3, 0x4e, 0x44, 0x52, 0x1b, 0x9f, 0x16, 0x47, 0x4e, 0x1f, 0x4b, 0x4e, 0x55, 0x44, 0x52, 0x1d, 0x1f, 0xb, 0x48, 0x55, 0x44, 0x52, 0x1b, 0x9f, 0x1c, 0xc, 0x42, 0x2, 0x40, 0x45, 0x45, 0x51, 0x44, 0x58, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x6, 0x4e, 0x4d, 0x44, 0x1f, 0x40, 0x56, 0x40, 0x58, 0x1d, 0x1f, 0x46, 0x4e, 0x4d, 0x44, 0x9f, 0x40, 0x47, 0x44, 0x40, 0x43, 0x1d, 0x1f, 0x4, 0x42, 0x47, 0x4e, 0x44, 0x52, 0x1f, 0x51, 0x4e, 0x4b, 0xcb, 0x54, 0x4d, 0x40, 0x4d, 0x52, 0x56, 0x44, 0x51, 0x44, 0x43, 0x1b, 0x1f, 0x4, 0x4c, 0x4f, 0x53, 0x58, 0x9d, 0x4e, 0x4f, 0x44, 0x4d, 0x1d, 0x1f, 0x43, 0x54, 0x52, 0x53, 0x58, 0x1d, 0x1f, 0x43, 0x44, 0x40, 0x43, 0x9d, 0x16, 0x47, 0x58, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x40, 0x4b, 0x4b, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x16, 0x44, 0x58, 0x51, 0x45, 0x4e, 0x4b, 0x4a, 0x1f, 0x45, 0x4b, 0x44, 0x43, 0x1e, 0x9f, 0x16, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x43, 0x51, 0x40, 0x46, 0x4e, 0x4d, 0xd2, 0x46, 0x4e, 0x4d, 0x44, 0x1f, 0x53, 0x4e, 0x46, 0x44, 0x53, 0x47, 0x44, 0x51, 0x1e, 0x9f, ], [0xb, 0x44, 0x40, 0x55, 0x48, 0x4d, 0x46, 0x1f, 0x16, 0x44, 0x58, 0x51, 0x52, 0x1f, 0x53, 0x4e, 0x9f, 0x56, 0x48, 0x4d, 0x43, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x56, 0x44, 0x40, 0x53, 0x47, 0x44, 0x51, 0x1e, 0x9f, 0x12, 0x44, 0x53, 0x53, 0x48, 0x4d, 0x46, 0x1f, 0x47, 0x44, 0x51, 0x43, 0x41, 0x44, 0x40, 0x52, 0x53, 0xd2, 0x45, 0x51, 0x44, 0x44, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x44, 0x53, 0x47, 0x44, 0x51, 0x1e, 0x9f, 0x6, 0x4e, 0x4d, 0x44, 0x1d, 0x1f, 0x4e, 0x54, 0x51, 0x9f, 0x52, 0x40, 0x45, 0x44, 0x46, 0x54, 0x40, 0x51, 0x43, 0x52, 0x1d, 0x1f, 0x46, 0x4e, 0x4d, 0x44, 0x1d, 0x9f, 0x41, 0x54, 0x53, 0x1f, 0x56, 0x47, 0x48, 0x53, 0x47, 0x44, 0x51, 0x1e, 0x1f, 0x7, 0x40, 0x55, 0x44, 0x9f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x45, 0x4b, 0x4e, 0x56, 0x4d, 0x1f, 0x53, 0x4e, 0x1f, 0x52, 0x4e, 0x4c, 0xc4, ], [0x4d, 0x44, 0x56, 0x1f, 0x16, 0x44, 0x58, 0x51, 0x1f, 0x16, 0x47, 0x44, 0x4d, 0x9f, 0x42, 0x51, 0x54, 0x44, 0x4b, 0x1f, 0x13, 0x47, 0x51, 0x44, 0x40, 0x43, 0x52, 0x1f, 0x52, 0x4e, 0x4c, 0xc4, 0x4e, 0x53, 0x47, 0x44, 0x51, 0x52, 0x1f, 0x45, 0x44, 0x40, 0x51, 0x1e, 0x1f, 0x0, 0x51, 0x44, 0x9f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x52, 0x1f, 0x40, 0x56, 0x40, 0x58, 0x9f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x47, 0x44, 0x51, 0x44, 0x1e, 0x1f, 0x16, 0x47, 0x58, 0x1d, 0x9f, 0x4e, 0x47, 0x1d, 0x1f, 0x56, 0x47, 0x58, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x44, 0x4c, 0x4f, 0x53, 0xd8, 0x16, 0x44, 0x58, 0x51, 0x1e, 0x1f, 0x1c, 0xc, 0x42, 0x2, 0x40, 0x45, 0x45, 0x51, 0x44, 0x58, 0x1f, 0x9f, 0x9f, ]], +[[0xc, 0x51, 0x1b, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0xc, 0x51, 0x52, 0x1b, 0x9f, 0x3, 0x54, 0x51, 0x52, 0x4b, 0x44, 0x58, 0x1d, 0x1f, 0x4e, 0x45, 0x1f, 0x4d, 0x54, 0x4c, 0x41, 0x44, 0xd1, 0x45, 0x4e, 0x54, 0x51, 0x1d, 0x1f, 0xf, 0x51, 0x48, 0x55, 0x44, 0x53, 0x9f, 0x3, 0x51, 0x48, 0x55, 0x44, 0x1d, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x4f, 0x51, 0x4e, 0x54, 0x43, 0x9f, 0x53, 0x4e, 0x1f, 0x52, 0x40, 0x58, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x9f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x4f, 0x44, 0x51, 0x45, 0x44, 0x42, 0x53, 0x4b, 0x58, 0x9f, 0x4d, 0x4e, 0x51, 0x4c, 0x40, 0x4b, 0x1d, 0x1f, 0x53, 0x47, 0x40, 0x4d, 0x4a, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x55, 0x44, 0x51, 0x58, 0x1f, 0x4c, 0x54, 0x42, 0x47, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x58, 0x9f, ], [0x56, 0x44, 0x51, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4b, 0x40, 0x52, 0x53, 0x9f, 0x4f, 0x44, 0x4e, 0x4f, 0x4b, 0x44, 0x1f, 0x58, 0x4e, 0x54, 0x5d, 0x43, 0x9f, 0x44, 0x57, 0x4f, 0x44, 0x42, 0x53, 0x1f, 0x53, 0x4e, 0x1f, 0x41, 0x44, 0x9f, 0x48, 0x4d, 0x55, 0x4e, 0x4b, 0x55, 0x44, 0x43, 0x1f, 0x48, 0x4d, 0x9f, 0x40, 0x4d, 0x58, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1f, 0x52, 0x53, 0x51, 0x40, 0x4d, 0x46, 0x44, 0x9f, 0x4e, 0x51, 0x1f, 0x4c, 0x58, 0x52, 0x53, 0x44, 0x51, 0x48, 0x4e, 0x54, 0x52, 0x1d, 0x9f, 0x41, 0x44, 0x42, 0x40, 0x54, 0x52, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x58, 0x1f, 0x49, 0x54, 0x52, 0x53, 0x9f, 0x43, 0x48, 0x43, 0x4d, 0x5d, 0x53, 0x1f, 0x47, 0x4e, 0x4b, 0x43, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x9f, ], [0x52, 0x54, 0x42, 0x47, 0x1f, 0x4d, 0x4e, 0x4d, 0x52, 0x44, 0x4d, 0x52, 0x44, 0x1b, 0x9f, 0x1c, 0x11, 0x4e, 0x56, 0x4b, 0x48, 0x4d, 0x46, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0xb, 0x4e, 0x55, 0x44, 0x1d, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x9f, 0x50, 0x54, 0x48, 0x42, 0x4a, 0x4b, 0x58, 0x1f, 0x40, 0x51, 0x51, 0x44, 0x52, 0x53, 0x52, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x46, 0x44, 0x4d, 0x53, 0x4b, 0x44, 0x1f, 0x47, 0x44, 0x40, 0x51, 0x53, 0x1d, 0x9f, 0x12, 0x44, 0x48, 0x59, 0x44, 0x43, 0x1f, 0x47, 0x48, 0x4c, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x4c, 0xd8, 0x41, 0x44, 0x40, 0x54, 0x53, 0x48, 0x45, 0x54, 0x4b, 0x1f, 0x45, 0x4e, 0x51, 0x4c, 0x9f, 0x13, 0x47, 0x40, 0x53, 0x1f, 0x56, 0x40, 0x52, 0x1f, 0x53, 0x40, 0x4a, 0x44, 0x4d, 0x9f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x4c, 0x44, 0x1d, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x9f, 0x4c, 0x40, 0x4d, 0x4d, 0x44, 0x51, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x52, 0x53, 0x48, 0x4b, 0xcb, ], [0x46, 0x51, 0x48, 0x44, 0x55, 0x44, 0x52, 0x1f, 0x4c, 0x44, 0x1b, 0x1f, 0xb, 0x4e, 0x55, 0x44, 0x1d, 0x9f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x4f, 0x40, 0x51, 0x43, 0x4e, 0x4d, 0x52, 0x1f, 0x4d, 0x4e, 0x9f, 0x41, 0x44, 0x4b, 0x4e, 0x55, 0x44, 0x43, 0x1f, 0x45, 0x51, 0x4e, 0x4c, 0x9f, 0x4b, 0x4e, 0x55, 0x48, 0x4d, 0x46, 0x1d, 0x1f, 0x53, 0x4e, 0x4e, 0x4a, 0x1f, 0x4c, 0x44, 0x1f, 0x52, 0xce, 0x52, 0x53, 0x51, 0x4e, 0x4d, 0x46, 0x4b, 0x58, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x9f, 0x43, 0x44, 0x4b, 0x48, 0x46, 0x47, 0x53, 0x1f, 0x48, 0x4d, 0x1f, 0x47, 0x48, 0x4c, 0x9f, 0x13, 0x47, 0x40, 0x53, 0x1d, 0x1f, 0x40, 0x52, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x52, 0x44, 0x44, 0x1d, 0x9f, 0x48, 0x53, 0x1f, 0x52, 0x53, 0x48, 0x4b, 0x4b, 0x1f, 0x40, 0x41, 0x40, 0x4d, 0x43, 0x4e, 0x4d, 0x52, 0x9f, ], [0x4c, 0x44, 0x1f, 0x4d, 0x4e, 0x53, 0x1b, 0x1b, 0x1b, 0x9f, 0x1c, 0x0, 0x4b, 0x48, 0x46, 0x47, 0x48, 0x44, 0x51, 0x48, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x8, 0x1f, 0x42, 0x40, 0x4d, 0x4d, 0x4e, 0x53, 0x1f, 0x44, 0x57, 0x4f, 0x51, 0x44, 0x52, 0x52, 0x9f, 0x48, 0x53, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x52, 0x54, 0x51, 0x44, 0x4b, 0x58, 0x1f, 0x58, 0x4e, 0xd4, 0x40, 0x4d, 0x43, 0x1f, 0x44, 0x55, 0x44, 0x51, 0x58, 0x41, 0x4e, 0x43, 0x58, 0x1f, 0x47, 0x40, 0x55, 0xc4, 0x40, 0x1f, 0x4d, 0x4e, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x9f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x48, 0x52, 0x1f, 0x4e, 0x51, 0x1f, 0x52, 0x47, 0x4e, 0x54, 0x4b, 0xc3, 0x41, 0x44, 0x1f, 0x40, 0x4d, 0x1f, 0x44, 0x57, 0x48, 0x52, 0x53, 0x44, 0x4d, 0x42, 0x44, 0x1f, 0x4e, 0xc5, 0x58, 0x4e, 0x54, 0x51, 0x52, 0x1f, 0x41, 0x44, 0x58, 0x4e, 0x4d, 0x43, 0x1f, 0x58, 0x4e, 0x54, 0x1b, 0x9f, 0x16, 0x47, 0x40, 0x53, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x54, 0x52, 0x44, 0x9f, ], [0x4e, 0x45, 0x1f, 0x4c, 0x58, 0x1f, 0x42, 0x51, 0x44, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1d, 0x1f, 0x48, 0xc5, 0x8, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x1f, 0x44, 0x4d, 0x53, 0x48, 0x51, 0x44, 0x4b, 0x58, 0x9f, 0x42, 0x4e, 0x4d, 0x53, 0x40, 0x48, 0x4d, 0x44, 0x43, 0x1f, 0x47, 0x44, 0x51, 0x44, 0x1e, 0x1f, 0xc, 0xd8, 0x46, 0x51, 0x44, 0x40, 0x53, 0x1f, 0x4c, 0x48, 0x52, 0x44, 0x51, 0x48, 0x44, 0x52, 0x1f, 0x48, 0x4d, 0x9f, 0x53, 0x47, 0x48, 0x52, 0x1f, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x9f, 0x41, 0x44, 0x44, 0x4d, 0x1f, 0x7, 0x44, 0x40, 0x53, 0x47, 0x42, 0x4b, 0x48, 0x45, 0x45, 0x5d, 0x52, 0x9f, 0x4c, 0x48, 0x52, 0x44, 0x51, 0x48, 0x44, 0x52, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x8, 0x9f, 0x56, 0x40, 0x53, 0x42, 0x47, 0x44, 0x43, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x45, 0x44, 0x4b, 0x53, 0x9f, ], [0x44, 0x40, 0x42, 0x47, 0x1f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x41, 0x44, 0x46, 0x48, 0x4d, 0x4d, 0x48, 0x4d, 0x46, 0x1b, 0x1f, 0x4c, 0x58, 0x9f, 0x46, 0x51, 0x44, 0x40, 0x53, 0x1f, 0x53, 0x47, 0x4e, 0x54, 0x46, 0x47, 0x53, 0x1f, 0x48, 0x4d, 0x9f, 0x4b, 0x48, 0x55, 0x48, 0x4d, 0x46, 0x1f, 0x48, 0x52, 0x1f, 0x47, 0x48, 0x4c, 0x52, 0x44, 0x4b, 0x45, 0x9b, 0x8, 0x45, 0x1f, 0x40, 0x4b, 0x4b, 0x1f, 0x44, 0x4b, 0x52, 0x44, 0x9f, 0x4f, 0x44, 0x51, 0x48, 0x52, 0x47, 0x44, 0x43, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0x44, 0x9f, 0x51, 0x44, 0x4c, 0x40, 0x48, 0x4d, 0x44, 0x43, 0x1d, 0x1f, 0x8, 0x1f, 0x52, 0x47, 0x4e, 0x54, 0x4b, 0xc3, 0x52, 0x53, 0x48, 0x4b, 0x4b, 0x1f, 0x42, 0x4e, 0x4d, 0x53, 0x48, 0x4d, 0x54, 0x44, 0x1f, 0x53, 0x4e, 0x9f, ], [0x41, 0x44, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x48, 0x45, 0x1f, 0x40, 0x4b, 0x4b, 0x9f, 0x44, 0x4b, 0x52, 0x44, 0x1f, 0x51, 0x44, 0x4c, 0x40, 0x48, 0x4d, 0x44, 0x43, 0x1d, 0x1f, 0x40, 0x4d, 0xc3, 0x47, 0x44, 0x1f, 0x56, 0x44, 0x51, 0x44, 0x9f, 0x40, 0x4d, 0x4d, 0x48, 0x47, 0x48, 0x4b, 0x40, 0x53, 0x44, 0x43, 0x1d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x54, 0x4d, 0x48, 0x55, 0x44, 0x51, 0x52, 0x44, 0x1f, 0x56, 0x4e, 0x54, 0x4b, 0x43, 0x9f, 0x53, 0x54, 0x51, 0x4d, 0x1f, 0x53, 0x4e, 0x1f, 0x40, 0x1f, 0x4c, 0x48, 0x46, 0x47, 0x53, 0x58, 0x9f, 0x52, 0x53, 0x51, 0x40, 0x4d, 0x46, 0x44, 0x51, 0x1b, 0x1f, 0x8, 0x1f, 0x52, 0x47, 0x4e, 0x54, 0x4b, 0xc3, 0x4d, 0x4e, 0x53, 0x1f, 0x52, 0x44, 0x44, 0x4c, 0x1f, 0x40, 0x1f, 0x4f, 0x40, 0x51, 0x53, 0x1f, 0x4e, 0xc5, ], [0x48, 0x53, 0x1b, 0x1f, 0x1c, 0x1, 0x51, 0x4e, 0x4d, 0x53, 0x44, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x8, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x43, 0x51, 0x44, 0x40, 0x4c, 0x53, 0x1f, 0x48, 0x4d, 0x9f, 0x4c, 0x58, 0x1f, 0x4b, 0x48, 0x45, 0x44, 0x1d, 0x1f, 0x43, 0x51, 0x44, 0x40, 0x4c, 0x52, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x52, 0x53, 0x40, 0x58, 0x44, 0x43, 0x9f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x4c, 0x44, 0x1f, 0x44, 0x55, 0x44, 0x51, 0x9f, 0x40, 0x45, 0x53, 0x44, 0x51, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x42, 0x47, 0x40, 0x4d, 0x46, 0x44, 0xc3, 0x4c, 0x58, 0x1f, 0x48, 0x43, 0x44, 0x40, 0x52, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x58, 0x9f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x46, 0x4e, 0x4d, 0x44, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x1f, 0x4c, 0x44, 0x1d, 0x9f, ], [0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x56, 0x48, 0x4d, 0x44, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x9f, 0x56, 0x40, 0x53, 0x44, 0x51, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x40, 0x4b, 0x53, 0x44, 0x51, 0x44, 0xc3, 0x53, 0x47, 0x44, 0x1f, 0x42, 0x4e, 0x4b, 0x4e, 0x51, 0x1f, 0x4e, 0x45, 0x1f, 0x4c, 0x58, 0x9f, 0x4c, 0x48, 0x4d, 0x43, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x48, 0x52, 0x1f, 0x48, 0x52, 0x9f, 0x4e, 0x4d, 0x44, 0x1b, 0x1f, 0x8, 0x5d, 0x4c, 0x1f, 0x46, 0x4e, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x9f, 0x53, 0x44, 0x4b, 0x4b, 0x1f, 0x48, 0x53, 0x1f, 0x1c, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x53, 0x40, 0x4a, 0xc4, 0x42, 0x40, 0x51, 0x44, 0x1f, 0x4d, 0x4e, 0x53, 0x1f, 0x53, 0x4e, 0x1f, 0x52, 0x4c, 0x48, 0x4b, 0x44, 0x9f, 0x40, 0x53, 0x1f, 0x40, 0x4d, 0x58, 0x1f, 0x4f, 0x40, 0x51, 0x53, 0x1f, 0x4e, 0x45, 0x1f, 0x48, 0x53, 0x9b, ], [0x1c, 0x1, 0x51, 0x4e, 0x4d, 0x53, 0x44, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x13, 0x47, 0x48, 0x52, 0x1f, 0x52, 0x53, 0x4e, 0x51, 0x58, 0x1f, 0x52, 0x47, 0x40, 0x4b, 0x4b, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x1f, 0x4c, 0x40, 0x4d, 0x1f, 0x53, 0x44, 0x40, 0x42, 0xc7, 0x47, 0x48, 0x52, 0x1f, 0x52, 0x4e, 0x4d, 0x1d, 0x1f, 0x0, 0x4d, 0x43, 0x9f, 0x2, 0x51, 0x48, 0x52, 0x4f, 0x48, 0x4d, 0x1f, 0x2, 0x51, 0x48, 0x52, 0x4f, 0x48, 0x40, 0x4d, 0x9f, 0x52, 0x47, 0x40, 0x4b, 0x4b, 0x1f, 0x4d, 0x44, 0x5d, 0x44, 0x51, 0x1f, 0x46, 0x4e, 0x1f, 0x41, 0x58, 0x9d, 0x5, 0x51, 0x4e, 0x4c, 0x1f, 0x53, 0x47, 0x48, 0x52, 0x1f, 0x43, 0x40, 0x58, 0x1f, 0x53, 0x4e, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x44, 0x4d, 0x43, 0x48, 0x4d, 0x46, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x1d, 0x1f, 0x1, 0x54, 0x53, 0x1f, 0x56, 0x44, 0x1f, 0x48, 0x4d, 0x9f, ], [0x48, 0x53, 0x1f, 0x52, 0x47, 0x40, 0x4b, 0x4b, 0x1f, 0x41, 0x44, 0x9f, 0x51, 0x44, 0x4c, 0x44, 0x4c, 0x41, 0x44, 0x51, 0x44, 0x43, 0x1b, 0x1f, 0x16, 0x44, 0x9f, 0x45, 0x44, 0x56, 0x1d, 0x1f, 0x56, 0x44, 0x1f, 0x47, 0x40, 0x4f, 0x4f, 0x58, 0x1f, 0x45, 0x44, 0x56, 0x9d, 0x56, 0x44, 0x1f, 0x41, 0x40, 0x4d, 0x43, 0x1f, 0x4e, 0x45, 0x9f, 0x41, 0x51, 0x4e, 0x53, 0x47, 0x44, 0x51, 0x52, 0x1b, 0x1f, 0x5, 0x4e, 0x51, 0x1f, 0x47, 0x44, 0x9f, 0x53, 0x4e, 0x1c, 0x43, 0x40, 0x58, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x52, 0x47, 0x44, 0x43, 0x52, 0x9f, 0x47, 0x48, 0x52, 0x1f, 0x41, 0x4b, 0x4e, 0x4e, 0x43, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x4c, 0x44, 0x9f, 0x12, 0x47, 0x40, 0x4b, 0x4b, 0x1f, 0x41, 0x44, 0x1f, 0x4c, 0x58, 0x9f, ], [0x41, 0x51, 0x4e, 0x53, 0x47, 0x44, 0x51, 0x1b, 0x9f, 0x1c, 0x12, 0x47, 0x40, 0x4a, 0x44, 0x52, 0x4f, 0x44, 0x40, 0x51, 0x44, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x7, 0x4e, 0x56, 0x44, 0x55, 0x44, 0x51, 0x1f, 0x4c, 0x44, 0x40, 0x4d, 0x1f, 0x58, 0x4e, 0x54, 0x51, 0x9f, 0x4b, 0x48, 0x45, 0x44, 0x1f, 0x48, 0x52, 0x1d, 0x1f, 0x4c, 0x44, 0x44, 0x53, 0x1f, 0x48, 0x53, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x4b, 0x48, 0x55, 0x44, 0x1f, 0x48, 0x53, 0x1b, 0x1f, 0x3, 0x4e, 0x9f, 0x4d, 0x4e, 0x53, 0x1f, 0x52, 0x47, 0x54, 0x4d, 0x1f, 0x48, 0x53, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x42, 0x40, 0x4b, 0x4b, 0x1f, 0x48, 0x53, 0x1f, 0x47, 0x40, 0x51, 0x43, 0x9f, 0x4d, 0x40, 0x4c, 0x44, 0x52, 0x1b, 0x1f, 0x8, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x4d, 0x4e, 0x53, 0x9f, 0x52, 0x4e, 0x1f, 0x41, 0x40, 0x43, 0x1f, 0x40, 0x52, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x40, 0x51, 0x44, 0x9b, 0x8, 0x53, 0x1f, 0x4b, 0x4e, 0x4e, 0x4a, 0x52, 0x1f, 0x4f, 0x4e, 0x4e, 0x51, 0x44, 0x52, 0x53, 0x9f, ], [0x56, 0x47, 0x44, 0x4d, 0x1f, 0x58, 0x4e, 0x54, 0x1f, 0x40, 0x51, 0x44, 0x9f, 0x51, 0x48, 0x42, 0x47, 0x44, 0x52, 0x53, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x45, 0x40, 0x54, 0x4b, 0x53, 0x1c, 0x45, 0x48, 0x4d, 0x43, 0x44, 0x51, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x9f, 0x45, 0x48, 0x4d, 0x43, 0x1f, 0x45, 0x40, 0x54, 0x4b, 0x53, 0x52, 0x1f, 0x44, 0x55, 0x44, 0x4d, 0x9f, 0x48, 0x4d, 0x1f, 0x4f, 0x40, 0x51, 0x40, 0x43, 0x48, 0x52, 0x44, 0x1b, 0x1f, 0xb, 0x4e, 0x55, 0x44, 0x9f, 0x58, 0x4e, 0x54, 0x51, 0x1f, 0x4b, 0x48, 0x45, 0x44, 0x1d, 0x1f, 0x4f, 0x4e, 0x4e, 0x51, 0x1f, 0x40, 0xd2, 0x48, 0x53, 0x1f, 0x48, 0x52, 0x1b, 0x1f, 0x18, 0x4e, 0x54, 0x1f, 0x4c, 0x40, 0x58, 0x9f, 0x4f, 0x44, 0x51, 0x47, 0x40, 0x4f, 0x52, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x52, 0x4e, 0x4c, 0x44, 0x9f, ], [0x4f, 0x4b, 0x44, 0x40, 0x52, 0x40, 0x4d, 0x53, 0x1d, 0x9f, 0x53, 0x47, 0x51, 0x48, 0x4b, 0x4b, 0x48, 0x4d, 0x46, 0x1d, 0x9f, 0x46, 0x4b, 0x4e, 0x51, 0x48, 0x4e, 0x54, 0x52, 0x1f, 0x47, 0x4e, 0x54, 0x51, 0x52, 0x1d, 0x9f, 0x44, 0x55, 0x44, 0x4d, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x9f, 0x4f, 0x4e, 0x4e, 0x51, 0x47, 0x4e, 0x54, 0x52, 0x44, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x52, 0x44, 0x53, 0x53, 0x48, 0x4d, 0x46, 0x1f, 0x52, 0x54, 0x4d, 0x1f, 0x48, 0x52, 0x9f, 0x51, 0x44, 0x45, 0x4b, 0x44, 0x42, 0x53, 0x44, 0x43, 0x1f, 0x45, 0x51, 0x4e, 0x4c, 0x1f, 0x53, 0x47, 0xc4, 0x56, 0x48, 0x4d, 0x43, 0x4e, 0x56, 0x52, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0x44, 0x9f, ], [0x40, 0x4b, 0x4c, 0x52, 0x47, 0x4e, 0x54, 0x52, 0x44, 0x1f, 0x40, 0x52, 0x9f, 0x41, 0x51, 0x48, 0x46, 0x47, 0x53, 0x4b, 0x58, 0x1f, 0x40, 0x52, 0x1f, 0x45, 0x51, 0x4e, 0x4c, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x51, 0x48, 0x42, 0x47, 0x1f, 0x4c, 0x40, 0x4d, 0x5d, 0x52, 0x9f, 0x40, 0x41, 0x4e, 0x43, 0x44, 0x1b, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x4d, 0x4e, 0x56, 0x9f, 0x4c, 0x44, 0x4b, 0x53, 0x52, 0x1f, 0x41, 0x44, 0x45, 0x4e, 0x51, 0x44, 0x1f, 0x48, 0x53, 0x52, 0x9f, 0x43, 0x4e, 0x4e, 0x51, 0x1f, 0x40, 0x52, 0x1f, 0x44, 0x40, 0x51, 0x4b, 0x58, 0x1f, 0x48, 0x4d, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x52, 0x4f, 0x51, 0x48, 0x4d, 0x46, 0x1b, 0x1f, 0x8, 0x1f, 0x43, 0x4e, 0x9f, 0x4d, 0x4e, 0x53, 0x1f, 0x52, 0x44, 0x44, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x40, 0x9f, ], [0x50, 0x54, 0x48, 0x44, 0x53, 0x1f, 0x4c, 0x48, 0x4d, 0x43, 0x1f, 0x4c, 0x40, 0x58, 0x9f, 0x4b, 0x48, 0x55, 0x44, 0x1f, 0x40, 0x52, 0x9f, 0x42, 0x4e, 0x4d, 0x53, 0x44, 0x4d, 0x53, 0x44, 0x43, 0x4b, 0x58, 0x1f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x9d, 0x40, 0x4d, 0x43, 0x1f, 0x47, 0x40, 0x55, 0x44, 0x1f, 0x40, 0x52, 0x9f, 0x42, 0x47, 0x44, 0x44, 0x51, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x47, 0x4e, 0x54, 0x46, 0x47, 0x53, 0x52, 0x9d, 0x40, 0x52, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x1f, 0x4f, 0x40, 0x4b, 0x40, 0x42, 0x44, 0x1b, 0x9f, 0x1c, 0x13, 0x47, 0x4e, 0x51, 0x44, 0x40, 0x54, 0x1f, 0x9f, 0x9f, ]], +[[0x16, 0x44, 0x1f, 0x4c, 0x54, 0x52, 0x53, 0x1f, 0x4b, 0x44, 0x40, 0x51, 0x4d, 0x1f, 0x53, 0x4e, 0x9f, 0x51, 0x44, 0x40, 0x56, 0x40, 0x4a, 0x44, 0x4d, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x4a, 0x44, 0x44, 0x4f, 0x9f, 0x4e, 0x54, 0x51, 0x52, 0x44, 0x4b, 0x55, 0x44, 0x52, 0x1f, 0x40, 0x56, 0x40, 0x4a, 0x44, 0x1d, 0x9f, 0x4d, 0x4e, 0x53, 0x1f, 0x41, 0x58, 0x1f, 0x4c, 0x44, 0x42, 0x47, 0x40, 0x4d, 0x48, 0x42, 0x40, 0x4b, 0x9f, 0x40, 0x48, 0x43, 0x52, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x41, 0x58, 0x1f, 0x40, 0x4d, 0x9f, 0x48, 0x4d, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x44, 0x9f, 0x44, 0x57, 0x4f, 0x44, 0x42, 0x53, 0x40, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0xc4, 0x43, 0x40, 0x56, 0x4d, 0x1d, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x43, 0x4e, 0x44, 0x52, 0x9f, ], [0x4d, 0x4e, 0x53, 0x1f, 0x45, 0x4e, 0x51, 0x52, 0x40, 0x4a, 0x44, 0x1f, 0x54, 0x52, 0x9f, 0x44, 0x55, 0x44, 0x4d, 0x1f, 0x48, 0x4d, 0x1f, 0x4e, 0x54, 0x51, 0x9f, 0x52, 0x4e, 0x54, 0x4d, 0x43, 0x44, 0x52, 0x53, 0x1f, 0x52, 0x4b, 0x44, 0x44, 0x4f, 0x1b, 0x1f, 0x8, 0x9f, 0x4a, 0x4d, 0x4e, 0x56, 0x1f, 0x4e, 0x45, 0x1f, 0x4d, 0x4e, 0x1f, 0x4c, 0x4e, 0x51, 0x44, 0x9f, 0x44, 0x4d, 0x42, 0x4e, 0x54, 0x51, 0x40, 0x46, 0x48, 0x4d, 0x46, 0x1f, 0x45, 0x40, 0x42, 0x53, 0x9f, 0x53, 0x47, 0x40, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x54, 0x4d, 0x50, 0x54, 0x44, 0x52, 0x53, 0x48, 0x4e, 0x4d, 0x40, 0x41, 0x4b, 0x44, 0x9f, 0x40, 0x41, 0x48, 0x4b, 0x48, 0x53, 0x58, 0x1f, 0x4e, 0x45, 0x1f, 0x4c, 0x40, 0x4d, 0x1f, 0x53, 0x4e, 0x9f, ], [0x44, 0x4b, 0x44, 0x55, 0x40, 0x53, 0x44, 0x1f, 0x47, 0x48, 0x52, 0x1f, 0x4b, 0x48, 0x45, 0x44, 0x9f, 0x41, 0x58, 0x1f, 0x40, 0x1f, 0x42, 0x4e, 0x4d, 0x52, 0x42, 0x48, 0x4e, 0x54, 0x52, 0x9f, 0x44, 0x4d, 0x43, 0x44, 0x40, 0x55, 0x4e, 0x54, 0x51, 0x1b, 0x1f, 0x8, 0x53, 0x1f, 0x48, 0x52, 0x9f, 0x52, 0x4e, 0x4c, 0x44, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x4e, 0x1f, 0x41, 0x44, 0x9f, 0x40, 0x41, 0x4b, 0x44, 0x1f, 0x53, 0x4e, 0x1f, 0x4f, 0x40, 0x48, 0x4d, 0x53, 0x1f, 0x40, 0x9f, 0x4f, 0x40, 0x51, 0x53, 0x48, 0x42, 0x54, 0x4b, 0x40, 0x51, 0x9f, 0x4f, 0x48, 0x42, 0x53, 0x54, 0x51, 0x44, 0x1d, 0x1f, 0x4e, 0x51, 0x1f, 0x53, 0x4e, 0x9f, 0x42, 0x40, 0x51, 0x55, 0x44, 0x1f, 0x40, 0x1f, 0x52, 0x53, 0x40, 0x53, 0x54, 0x44, 0x1d, 0x9f, ], [0x40, 0x4d, 0x43, 0x1f, 0x52, 0x4e, 0x1f, 0x53, 0x4e, 0x1f, 0x4c, 0x40, 0x4a, 0x44, 0x1f, 0x40, 0x9f, 0x45, 0x44, 0x56, 0x1f, 0x4e, 0x41, 0x49, 0x44, 0x42, 0x53, 0x52, 0x9f, 0x41, 0x44, 0x40, 0x54, 0x53, 0x48, 0x45, 0x54, 0x4b, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x1f, 0x48, 0x53, 0x9f, 0x48, 0x52, 0x1f, 0x45, 0x40, 0x51, 0x1f, 0x4c, 0x4e, 0x51, 0x44, 0x9f, 0x46, 0x4b, 0x4e, 0x51, 0x48, 0x4e, 0x54, 0x52, 0x1f, 0x53, 0x4e, 0x1f, 0x42, 0x40, 0x51, 0x55, 0x44, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x4f, 0x40, 0x48, 0x4d, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x55, 0x44, 0x51, 0xd8, 0x40, 0x53, 0x4c, 0x4e, 0x52, 0x4f, 0x47, 0x44, 0x51, 0x44, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x4c, 0x44, 0x43, 0x48, 0x54, 0x4c, 0x1f, 0x53, 0x47, 0x51, 0x4e, 0x54, 0x46, 0x47, 0x9f, ], [0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x56, 0x44, 0x1f, 0x4b, 0x4e, 0x4e, 0x4a, 0x1d, 0x9f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x4c, 0x4e, 0x51, 0x40, 0x4b, 0x4b, 0x58, 0x1f, 0x56, 0x44, 0x9f, 0x42, 0x40, 0x4d, 0x1f, 0x43, 0x4e, 0x1b, 0x1f, 0x13, 0x4e, 0x1f, 0x40, 0x45, 0x45, 0x44, 0x42, 0x53, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x50, 0x54, 0x40, 0x4b, 0x48, 0x53, 0x58, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0xc4, 0x43, 0x40, 0x58, 0x1d, 0x1f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x48, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x47, 0x48, 0x46, 0x47, 0x44, 0x52, 0x53, 0x1f, 0x4e, 0x45, 0x1f, 0x40, 0x51, 0x53, 0x52, 0x1b, 0x9f, 0x1c, 0x13, 0x47, 0x4e, 0x51, 0x44, 0x40, 0x54, 0x1f, 0x9f, 0x9f, ]], +[[0x8, 0x45, 0x1f, 0x4e, 0x4d, 0x44, 0x1f, 0x40, 0x43, 0x55, 0x40, 0x4d, 0x42, 0x44, 0x52, 0x9f, 0x42, 0x4e, 0x4d, 0x45, 0x48, 0x43, 0x44, 0x4d, 0x53, 0x4b, 0x58, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0xc4, 0x43, 0x48, 0x51, 0x44, 0x42, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x4e, 0x45, 0x1f, 0x47, 0x48, 0x52, 0x9f, 0x43, 0x51, 0x44, 0x40, 0x4c, 0x52, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x44, 0x4d, 0x43, 0x44, 0x40, 0x55, 0x4e, 0x51, 0x52, 0x1f, 0x53, 0x4e, 0x1f, 0x4b, 0x48, 0x55, 0x44, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4b, 0x48, 0x45, 0x44, 0x1f, 0x56, 0x47, 0x48, 0x42, 0x47, 0x1f, 0x47, 0x44, 0x9f, 0x47, 0x40, 0x52, 0x1f, 0x48, 0x4c, 0x40, 0x46, 0x48, 0x4d, 0x44, 0x43, 0x1d, 0x1f, 0x47, 0x44, 0x9f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x4c, 0x44, 0x44, 0x53, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x1f, 0x40, 0x9f, ], [0x52, 0x54, 0x42, 0x42, 0x44, 0x52, 0x52, 0x1f, 0x54, 0x4d, 0x44, 0x57, 0x4f, 0x44, 0x42, 0x53, 0x44, 0xc3, 0x48, 0x4d, 0x1f, 0x42, 0x4e, 0x4c, 0x4c, 0x4e, 0x4d, 0x1f, 0x47, 0x4e, 0x54, 0x51, 0x52, 0x1b, 0x9f, 0x7, 0x44, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x4f, 0x54, 0x53, 0x1f, 0x52, 0x4e, 0x4c, 0x44, 0x9f, 0x53, 0x47, 0x48, 0x4d, 0x46, 0x52, 0x1f, 0x41, 0x44, 0x47, 0x48, 0x4d, 0x43, 0x1d, 0x9f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x4f, 0x40, 0x52, 0x52, 0x1f, 0x40, 0x4d, 0x9f, 0x48, 0x4d, 0x55, 0x48, 0x52, 0x48, 0x41, 0x4b, 0x44, 0x9f, 0x41, 0x4e, 0x54, 0x4d, 0x43, 0x40, 0x51, 0x58, 0x1b, 0x1f, 0xd, 0x44, 0x56, 0x1d, 0x9f, 0x54, 0x4d, 0x48, 0x55, 0x44, 0x51, 0x52, 0x40, 0x4b, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, ], [0x4c, 0x4e, 0x51, 0x44, 0x1f, 0x4b, 0x48, 0x41, 0x44, 0x51, 0x40, 0x4b, 0x1f, 0x4b, 0x40, 0x56, 0x52, 0x9f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x41, 0x44, 0x46, 0x48, 0x4d, 0x1f, 0x53, 0x4e, 0x9f, 0x44, 0x52, 0x53, 0x40, 0x41, 0x4b, 0x48, 0x52, 0x47, 0x9f, 0x53, 0x47, 0x44, 0x4c, 0x52, 0x44, 0x4b, 0x55, 0x44, 0x52, 0x1f, 0x40, 0x51, 0x4e, 0x54, 0x4d, 0x43, 0x9f, 0x40, 0x4d, 0x43, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x48, 0x4d, 0x1f, 0x47, 0x48, 0x4c, 0x1d, 0x1f, 0x4e, 0xd1, 0x53, 0x47, 0x44, 0x1f, 0x4e, 0x4b, 0x43, 0x1f, 0x4b, 0x40, 0x56, 0x52, 0x1f, 0x41, 0x44, 0x9f, 0x44, 0x57, 0x4f, 0x40, 0x4d, 0x43, 0x44, 0x43, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x48, 0x4d, 0x53, 0x44, 0x51, 0x4f, 0x51, 0x44, 0x53, 0x44, 0x43, 0x1f, 0x48, 0x4d, 0x1f, 0x47, 0x48, 0xd2, ], [0x45, 0x40, 0x55, 0x4e, 0x51, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x1f, 0x4c, 0x4e, 0x51, 0x44, 0x9f, 0x4b, 0x48, 0x41, 0x44, 0x51, 0x40, 0x4b, 0x1f, 0x52, 0x44, 0x4d, 0x52, 0x44, 0x1d, 0x1f, 0x40, 0x4d, 0xc3, 0x47, 0x44, 0x1f, 0x56, 0x48, 0x4b, 0x4b, 0x1f, 0x4b, 0x48, 0x55, 0x44, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x9f, 0x53, 0x47, 0x44, 0x1f, 0x4b, 0x48, 0x42, 0x44, 0x4d, 0x52, 0x44, 0x1f, 0x4e, 0x45, 0x1f, 0x40, 0x9f, 0x47, 0x48, 0x46, 0x47, 0x44, 0x51, 0x1f, 0x4e, 0x51, 0x43, 0x44, 0x51, 0x1f, 0x4e, 0x45, 0x9f, 0x41, 0x44, 0x48, 0x4d, 0x46, 0x52, 0x1b, 0x1f, 0x9f, 0x9f, 0x9f, ]], +[[0x8, 0x5d, 0x4c, 0x1f, 0x4d, 0x4e, 0x41, 0x4e, 0x43, 0x58, 0x1a, 0x1f, 0x16, 0x47, 0x4e, 0x9f, 0x40, 0x51, 0x44, 0x1f, 0x58, 0x4e, 0x54, 0x1e, 0x1f, 0x0, 0x51, 0x44, 0x1f, 0x58, 0x4e, 0x54, 0x9f, 0x4d, 0x4e, 0x41, 0x4e, 0x43, 0x58, 0x1d, 0x1f, 0x53, 0x4e, 0x4e, 0x1e, 0x1f, 0x13, 0x47, 0x44, 0x4d, 0x9f, 0x53, 0x47, 0x44, 0x51, 0x44, 0x5d, 0x52, 0x1f, 0x40, 0x1f, 0x4f, 0x40, 0x48, 0x51, 0x1f, 0x4e, 0x45, 0x9f, 0x54, 0x52, 0x1d, 0x1f, 0x43, 0x4e, 0x4d, 0x5d, 0x53, 0x1f, 0x53, 0x44, 0x4b, 0x4b, 0x1a, 0x9f, 0x13, 0x47, 0x44, 0x58, 0x5d, 0x43, 0x1f, 0x41, 0x40, 0x4d, 0x48, 0x52, 0x47, 0x1f, 0x54, 0x52, 0x1d, 0x9f, 0x58, 0x4e, 0x54, 0x1f, 0x4a, 0x4d, 0x4e, 0x56, 0x1b, 0x1f, 0x7, 0x4e, 0x56, 0x9f, 0x43, 0x51, 0x44, 0x40, 0x51, 0x58, 0x1f, 0x53, 0x4e, 0x1f, 0x41, 0x44, 0x9f, ], [0x52, 0x4e, 0x4c, 0x44, 0x41, 0x4e, 0x43, 0x58, 0x1a, 0x1f, 0x7, 0x4e, 0x56, 0x9f, 0x4f, 0x54, 0x41, 0x4b, 0x48, 0x42, 0x1d, 0x1f, 0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x40, 0x9f, 0x45, 0x51, 0x4e, 0x46, 0x1f, 0x13, 0x4e, 0x1f, 0x53, 0x44, 0x4b, 0x4b, 0x1f, 0x58, 0x4e, 0x54, 0x51, 0x9f, 0x4d, 0x40, 0x4c, 0x44, 0x1f, 0x53, 0x47, 0x44, 0x1f, 0x4b, 0x48, 0x55, 0x44, 0x4b, 0x4e, 0x4d, 0x46, 0x9f, 0x43, 0x40, 0x58, 0x1f, 0x13, 0x4e, 0x1f, 0x40, 0x4d, 0x1f, 0x40, 0x43, 0x4c, 0x48, 0x51, 0x48, 0x4d, 0xc6, 0x41, 0x4e, 0x46, 0x1a, 0x1f, 0x1c, 0x3, 0x48, 0x42, 0x4a, 0x48, 0x4d, 0x52, 0x4e, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, ]], +[[0x7, 0x4e, 0x56, 0x1f, 0x47, 0x40, 0x4f, 0x4f, 0x58, 0x1f, 0x48, 0x52, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x4b, 0x48, 0x53, 0x53, 0x4b, 0x44, 0x1f, 0x52, 0x53, 0x4e, 0x4d, 0x44, 0x1f, 0x13, 0x47, 0x40, 0x53, 0x9f, 0x51, 0x40, 0x4c, 0x41, 0x4b, 0x44, 0x52, 0x1f, 0x48, 0x4d, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x51, 0x4e, 0x40, 0x43, 0x1f, 0x40, 0x4b, 0x4e, 0x4d, 0x44, 0x1d, 0x1f, 0x0, 0x4d, 0x43, 0x9f, 0x43, 0x4e, 0x44, 0x52, 0x4d, 0x5d, 0x53, 0x1f, 0x42, 0x40, 0x51, 0x44, 0x1f, 0x40, 0x41, 0x4e, 0x54, 0xd3, 0x42, 0x40, 0x51, 0x44, 0x44, 0x51, 0x52, 0x1d, 0x1f, 0x0, 0x4d, 0x43, 0x9f, 0x44, 0x57, 0x48, 0x46, 0x44, 0x4d, 0x42, 0x48, 0x44, 0x52, 0x1f, 0x4d, 0x44, 0x55, 0x44, 0x51, 0x9f, 0x45, 0x44, 0x40, 0x51, 0x52, 0x1b, 0x1f, 0x16, 0x47, 0x4e, 0x52, 0x44, 0x1f, 0x42, 0x4e, 0x40, 0x53, 0x9f, ], [0x4e, 0x45, 0x1f, 0x44, 0x4b, 0x44, 0x4c, 0x44, 0x4d, 0x53, 0x40, 0x4b, 0x1f, 0x41, 0x51, 0x4e, 0x56, 0xcd, 0x0, 0x1f, 0x4f, 0x40, 0x52, 0x52, 0x48, 0x4d, 0x46, 0x1f, 0x54, 0x4d, 0x48, 0x55, 0x44, 0x51, 0x52, 0xc4, 0x4f, 0x54, 0x53, 0x1f, 0x4e, 0x4d, 0x1b, 0x1f, 0x0, 0x4d, 0x43, 0x9f, 0x48, 0x4d, 0x43, 0x44, 0x4f, 0x44, 0x4d, 0x43, 0x44, 0x4d, 0x53, 0x1f, 0x40, 0x52, 0x1f, 0x53, 0x47, 0xc4, 0x52, 0x54, 0x4d, 0x1d, 0x1f, 0x0, 0x52, 0x52, 0x4e, 0x42, 0x48, 0x40, 0x53, 0x44, 0x52, 0x1f, 0x4e, 0xd1, 0x46, 0x4b, 0x4e, 0x56, 0x52, 0x1f, 0x40, 0x4b, 0x4e, 0x4d, 0x44, 0x1d, 0x9f, 0x5, 0x54, 0x4b, 0x45, 0x48, 0x4b, 0x4b, 0x48, 0x4d, 0x46, 0x9f, 0x40, 0x41, 0x52, 0x4e, 0x4b, 0x54, 0x53, 0x44, 0x1f, 0x43, 0x44, 0x42, 0x51, 0x44, 0x44, 0x1f, 0x8, 0xcd, ], [0x42, 0x40, 0x52, 0x54, 0x40, 0x4b, 0x1f, 0x52, 0x48, 0x4c, 0x4f, 0x4b, 0x48, 0x42, 0x48, 0x53, 0x58, 0x9b, 0x1c, 0x3, 0x48, 0x42, 0x4a, 0x48, 0x4d, 0x52, 0x4e, 0x4d, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, ]], +[[0x1, 0x44, 0x42, 0x40, 0x54, 0x52, 0x44, 0x1f, 0x8, 0x1f, 0x42, 0x4e, 0x54, 0x4b, 0x43, 0x9f, 0x4d, 0x4e, 0x53, 0x1f, 0x52, 0x53, 0x4e, 0x4f, 0x1f, 0x45, 0x4e, 0x51, 0x1f, 0x43, 0x44, 0x40, 0x53, 0xc7, 0x7, 0x44, 0x1f, 0x4a, 0x48, 0x4d, 0x43, 0x4b, 0x58, 0x1f, 0x52, 0x53, 0x4e, 0x4f, 0x4f, 0x44, 0x43, 0x9f, 0x45, 0x4e, 0x51, 0x1f, 0x4c, 0x44, 0x1b, 0x1f, 0x13, 0x47, 0x44, 0x9f, 0x42, 0x40, 0x51, 0x51, 0x48, 0x40, 0x46, 0x44, 0x1f, 0x47, 0x44, 0x4b, 0x43, 0x1f, 0x41, 0x54, 0x53, 0x9f, 0x49, 0x54, 0x52, 0x53, 0x1f, 0x4e, 0x54, 0x51, 0x52, 0x44, 0x4b, 0x55, 0x44, 0x52, 0x1f, 0x0, 0x4d, 0xc3, 0x48, 0x4c, 0x4c, 0x4e, 0x51, 0x53, 0x40, 0x4b, 0x48, 0x53, 0x58, 0x9f, 0x1c, 0x3, 0x48, 0x42, 0x4a, 0x48, 0x4d, 0x52, 0x4e, 0x4d, 0x1f, 0x9f, ]], +[[0x5, 0x4e, 0x51, 0x1d, 0x1f, 0x4b, 0x48, 0x4a, 0x44, 0x1f, 0x40, 0x4b, 0x4c, 0x4e, 0x52, 0x53, 0x9f, 0x44, 0x55, 0x44, 0x51, 0x58, 0x4e, 0x4d, 0x44, 0x1f, 0x44, 0x4b, 0x52, 0x44, 0x1f, 0x48, 0x4d, 0x9f, 0x4e, 0x54, 0x51, 0x1f, 0x42, 0x4e, 0x54, 0x4d, 0x53, 0x51, 0x58, 0x1d, 0x1f, 0x8, 0x9f, 0x52, 0x53, 0x40, 0x51, 0x53, 0x44, 0x43, 0x1f, 0x4e, 0x54, 0x53, 0x1f, 0x56, 0x48, 0x53, 0x47, 0x9f, 0x4c, 0x58, 0x1f, 0x52, 0x47, 0x40, 0x51, 0x44, 0x1f, 0x4e, 0x45, 0x9f, 0x4e, 0x4f, 0x53, 0x48, 0x4c, 0x48, 0x52, 0x4c, 0x1b, 0x1f, 0x8, 0x9f, 0x41, 0x44, 0x4b, 0x48, 0x44, 0x55, 0x44, 0x43, 0x1f, 0x48, 0x4d, 0x1f, 0x47, 0x40, 0x51, 0x43, 0x9f, 0x56, 0x4e, 0x51, 0x4a, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x4f, 0x51, 0x4e, 0x46, 0x51, 0x44, 0x52, 0x52, 0x9f, ], [0x40, 0x4d, 0x43, 0x1f, 0x40, 0x42, 0x53, 0x48, 0x4e, 0x4d, 0x1d, 0x1f, 0x41, 0x54, 0x53, 0x9f, 0x4d, 0x4e, 0x56, 0x1d, 0x1f, 0x40, 0x45, 0x53, 0x44, 0x51, 0x1f, 0x45, 0x48, 0x51, 0x52, 0x53, 0x9f, 0x41, 0x44, 0x48, 0x4d, 0x46, 0x1f, 0x5d, 0x45, 0x4e, 0x51, 0x5d, 0x9f, 0x52, 0x4e, 0x42, 0x48, 0x44, 0x53, 0x58, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x53, 0x47, 0x44, 0x4d, 0x9f, 0x5d, 0x40, 0x46, 0x40, 0x48, 0x4d, 0x52, 0x53, 0x5d, 0x1f, 0x48, 0x53, 0x1d, 0x1f, 0x8, 0x9f, 0x40, 0x52, 0x52, 0x48, 0x46, 0x4d, 0x1f, 0x4c, 0x58, 0x52, 0x44, 0x4b, 0x45, 0x1f, 0x4d, 0x4e, 0x9f, 0x51, 0x40, 0x4d, 0x4a, 0x1f, 0x4e, 0x51, 0x1f, 0x40, 0x4d, 0x58, 0x1f, 0x4b, 0x48, 0x4c, 0x48, 0x53, 0x9d, 0x40, 0x4d, 0x43, 0x1f, 0x52, 0x54, 0x42, 0x47, 0x1f, 0x40, 0x4d, 0x9f, ], [0x40, 0x53, 0x53, 0x48, 0x53, 0x54, 0x43, 0x44, 0x1f, 0x48, 0x52, 0x1f, 0x55, 0x44, 0x51, 0x58, 0x9f, 0x4c, 0x54, 0x42, 0x47, 0x1f, 0x40, 0x46, 0x40, 0x48, 0x4d, 0x52, 0x53, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x53, 0x51, 0x44, 0x4d, 0x43, 0x1f, 0x4e, 0x45, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x53, 0x48, 0x4c, 0x44, 0x52, 0x1b, 0x1f, 0x1, 0x54, 0x53, 0x1f, 0x4c, 0x58, 0x9f, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x1f, 0x47, 0x40, 0x52, 0x1f, 0x41, 0x44, 0x42, 0x4e, 0x4c, 0x44, 0x9f, 0x4e, 0x4d, 0x44, 0x1f, 0x4e, 0x45, 0x1f, 0x48, 0x4d, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x44, 0x9f, 0x4f, 0x4e, 0x52, 0x52, 0x48, 0x41, 0x48, 0x4b, 0x48, 0x53, 0x48, 0x44, 0x52, 0x1b, 0x9f, 0x16, 0x47, 0x40, 0x53, 0x1f, 0x40, 0x1f, 0x4f, 0x47, 0x51, 0x40, 0x52, 0x44, 0x1f, 0x1c, 0x9f, ], [0x52, 0x53, 0x48, 0x4b, 0x4b, 0x1f, 0x48, 0x53, 0x5d, 0x52, 0x1f, 0x40, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x9f, 0x4f, 0x47, 0x51, 0x40, 0x52, 0x44, 0x1f, 0x40, 0x4d, 0x43, 0x1f, 0x40, 0x1f, 0x46, 0x4e, 0x4e, 0x43, 0x9f, 0x55, 0x48, 0x44, 0x56, 0x1f, 0x4e, 0x45, 0x1f, 0x4b, 0x48, 0x45, 0x44, 0x1d, 0x1f, 0x40, 0x4d, 0x43, 0x9f, 0x40, 0x1f, 0x4c, 0x40, 0x4d, 0x1f, 0x52, 0x47, 0x4e, 0x54, 0x4b, 0x43, 0x4d, 0x5d, 0x53, 0x9f, 0x40, 0x42, 0x42, 0x44, 0x4f, 0x53, 0x1f, 0x40, 0x4d, 0x58, 0x1f, 0x4e, 0x53, 0x47, 0x44, 0x51, 0x1b, 0x9f, 0x53, 0x47, 0x40, 0x53, 0x1f, 0x4c, 0x54, 0x42, 0x47, 0x1f, 0x8, 0x5d, 0x55, 0x44, 0x9f, 0x4b, 0x44, 0x40, 0x51, 0x4d, 0x44, 0x43, 0x9f, 0x54, 0x4d, 0x43, 0x44, 0x51, 0x46, 0x51, 0x4e, 0x54, 0x4d, 0x43, 0x1b, 0x1f, 0x14, 0x4d, 0x53, 0x48, 0xcb, ], [0x52, 0x4e, 0x4c, 0x44, 0x1f, 0x46, 0x40, 0x4d, 0x46, 0x1f, 0x52, 0x54, 0x42, 0x42, 0x44, 0x44, 0x43, 0xd2, 0x48, 0x4d, 0x1f, 0x4f, 0x54, 0x53, 0x53, 0x48, 0x4d, 0x46, 0x1f, 0x53, 0x47, 0x44, 0x9f, 0x56, 0x4e, 0x51, 0x4b, 0x43, 0x1f, 0x48, 0x4d, 0x1f, 0x40, 0x1f, 0x52, 0x53, 0x51, 0x40, 0x48, 0x53, 0x9f, 0x49, 0x40, 0x42, 0x4a, 0x44, 0x53, 0x1d, 0x1f, 0x48, 0x53, 0x52, 0x9f, 0x43, 0x44, 0x45, 0x48, 0x4d, 0x48, 0x53, 0x48, 0x4e, 0x4d, 0x1f, 0x48, 0x52, 0x9f, 0x4f, 0x4e, 0x52, 0x52, 0x48, 0x41, 0x48, 0x4b, 0x48, 0x53, 0x58, 0x1b, 0x9f, 0x1c, 0x4, 0x4b, 0x4b, 0x48, 0x52, 0x4e, 0x4d, 0x1f, 0x9f, 0x9f, ]], +] \ No newline at end of file diff --git a/worlds/smw/Names/LocationName.py b/worlds/smw/Names/LocationName.py new file mode 100644 index 00000000..2b42cd21 --- /dev/null +++ b/worlds/smw/Names/LocationName.py @@ -0,0 +1,364 @@ +# Level Definitions +yoshis_house = "Yoshi's House" +yoshis_house_tile = "Yoshi's House - Tile" + +yoshis_island_1_exit_1 = "Yoshi's Island 1 - Normal Exit" +yoshis_island_1_dragon = "Yoshi's Island 1 - Dragon Coins" +yoshis_island_2_exit_1 = "Yoshi's Island 2 - Normal Exit" +yoshis_island_2_dragon = "Yoshi's Island 2 - Dragon Coins" +yoshis_island_3_exit_1 = "Yoshi's Island 3 - Normal Exit" +yoshis_island_3_dragon = "Yoshi's Island 3 - Dragon Coins" +yoshis_island_4_exit_1 = "Yoshi's Island 4 - Normal Exit" +yoshis_island_4_dragon = "Yoshi's Island 4 - Dragon Coins" +yoshis_island_castle = "#1 Iggy's Castle - Normal Exit" +yoshis_island_koopaling = "#1 Iggy's Castle - Boss" + +yellow_switch_palace = "Yellow Switch Palace" + +donut_plains_1_exit_1 = "Donut Plains 1 - Normal Exit" +donut_plains_1_exit_2 = "Donut Plains 1 - Secret Exit" +donut_plains_1_dragon = "Donut Plains 1 - Dragon Coins" +donut_plains_2_exit_1 = "Donut Plains 2 - Normal Exit" +donut_plains_2_exit_2 = "Donut Plains 2 - Secret Exit" +donut_plains_2_dragon = "Donut Plains 2 - Dragon Coins" +donut_plains_3_exit_1 = "Donut Plains 3 - Normal Exit" +donut_plains_3_dragon = "Donut Plains 3 - Dragon Coins" +donut_plains_4_exit_1 = "Donut Plains 4 - Normal Exit" +donut_plains_4_dragon = "Donut Plains 4 - Dragon Coins" +donut_secret_1_exit_1 = "Donut Secret 1 - Normal Exit" +donut_secret_1_exit_2 = "Donut Secret 1 - Secret Exit" +donut_secret_1_dragon = "Donut Secret 1 - Dragon Coins" +donut_secret_2_exit_1 = "Donut Secret 2 - Normal Exit" +donut_secret_2_dragon = "Donut Secret 2 - Dragon Coins" +donut_ghost_house_exit_1 = "Donut Ghost House - Normal Exit" +donut_ghost_house_exit_2 = "Donut Ghost House - Secret Exit" +donut_secret_house_exit_1 = "Donut Secret House - Normal Exit" +donut_secret_house_exit_2 = "Donut Secret House - Secret Exit" +donut_plains_castle = "#2 Morton's Castle - Normal Exit" +donut_plains_koopaling = "#2 Morton's Castle - Boss" + +green_switch_palace = "Green Switch Palace" + +vanilla_dome_1_exit_1 = "Vanilla Dome 1 - Normal Exit" +vanilla_dome_1_exit_2 = "Vanilla Dome 1 - Secret Exit" +vanilla_dome_1_dragon = "Vanilla Dome 1 - Dragon Coins" +vanilla_dome_2_exit_1 = "Vanilla Dome 2 - Normal Exit" +vanilla_dome_2_exit_2 = "Vanilla Dome 2 - Secret Exit" +vanilla_dome_2_dragon = "Vanilla Dome 2 - Dragon Coins" +vanilla_dome_3_exit_1 = "Vanilla Dome 3 - Normal Exit" +vanilla_dome_3_dragon = "Vanilla Dome 3 - Dragon Coins" +vanilla_dome_4_exit_1 = "Vanilla Dome 4 - Normal Exit" +vanilla_dome_4_dragon = "Vanilla Dome 4 - Dragon Coins" +vanilla_secret_1_exit_1 = "Vanilla Secret 1 - Normal Exit" +vanilla_secret_1_exit_2 = "Vanilla Secret 1 - Secret Exit" +vanilla_secret_1_dragon = "Vanilla Secret 1 - Dragon Coins" +vanilla_secret_2_exit_1 = "Vanilla Secret 2 - Normal Exit" +vanilla_secret_2_dragon = "Vanilla Secret 2 - Dragon Coins" +vanilla_secret_3_exit_1 = "Vanilla Secret 3 - Normal Exit" +vanilla_secret_3_dragon = "Vanilla Secret 3 - Dragon Coins" +vanilla_ghost_house_exit_1 = "Vanilla Ghost House - Normal Exit" +vanilla_ghost_house_dragon = "Vanilla Ghost House - Dragon Coins" +vanilla_fortress = "Vanilla Fortress - Normal Exit" +vanilla_reznor = "Vanilla Fortress - Boss" +vanilla_dome_castle = "#3 Lemmy's Castle - Normal Exit" +vanilla_dome_koopaling = "#3 Lemmy's Castle - Boss" + +red_switch_palace = "Red Switch Palace" + +butter_bridge_1_exit_1 = "Butter Bridge 1 - Normal Exit" +butter_bridge_1_dragon = "Butter Bridge 1 - Dragon Coins" +butter_bridge_2_exit_1 = "Butter Bridge 2 - Normal Exit" +butter_bridge_2_dragon = "Butter Bridge 2 - Dragon Coins" +cheese_bridge_exit_1 = "Cheese Bridge - Normal Exit" +cheese_bridge_exit_2 = "Cheese Bridge - Secret Exit" +cheese_bridge_dragon = "Cheese Bridge - Dragon Coins" +cookie_mountain_exit_1 = "Cookie Mountain - Normal Exit" +cookie_mountain_dragon = "Cookie Mountain - Dragon Coins" +soda_lake_exit_1 = "Soda Lake - Normal Exit" +soda_lake_dragon = "Soda Lake - Dragon Coins" +twin_bridges_castle = "#4 Ludwig's Castle - Normal Exit" +twin_bridges_koopaling = "#4 Ludwig's Castle - Boss" + +forest_of_illusion_1_exit_1 = "Forest of Illusion 1 - Normal Exit" +forest_of_illusion_1_exit_2 = "Forest of Illusion 1 - Secret Exit" +forest_of_illusion_2_exit_1 = "Forest of Illusion 2 - Normal Exit" +forest_of_illusion_2_exit_2 = "Forest of Illusion 2 - Secret Exit" +forest_of_illusion_2_dragon = "Forest of Illusion 2 - Dragon Coins" +forest_of_illusion_3_exit_1 = "Forest of Illusion 3 - Normal Exit" +forest_of_illusion_3_exit_2 = "Forest of Illusion 3 - Secret Exit" +forest_of_illusion_3_dragon = "Forest of Illusion 3 - Dragon Coins" +forest_of_illusion_4_exit_1 = "Forest of Illusion 4 - Normal Exit" +forest_of_illusion_4_exit_2 = "Forest of Illusion 4 - Secret Exit" +forest_of_illusion_4_dragon = "Forest of Illusion 4 - Dragon Coins" +forest_ghost_house_exit_1 = "Forest Ghost House - Normal Exit" +forest_ghost_house_exit_2 = "Forest Ghost House - Secret Exit" +forest_ghost_house_dragon = "Forest Ghost House - Dragon Coins" +forest_secret_exit_1 = "Forest Secret - Normal Exit" +forest_secret_dragon = "Forest Secret - Dragon Coins" +forest_fortress = "Forest Fortress - Normal Exit" +forest_reznor = "Forest Fortress - Boss" +forest_castle = "#5 Roy's Castle - Normal Exit" +forest_castle_dragon = "#5 Roy's Castle - Dragon Coins" +forest_koopaling = "#5 Roy's Castle - Boss" + +blue_switch_palace = "Blue Switch Palace" + +chocolate_island_1_exit_1 = "Chocolate Island 1 - Normal Exit" +chocolate_island_1_dragon = "Chocolate Island 1 - Dragon Coins" +chocolate_island_2_exit_1 = "Chocolate Island 2 - Normal Exit" +chocolate_island_2_exit_2 = "Chocolate Island 2 - Secret Exit" +chocolate_island_2_dragon = "Chocolate Island 2 - Dragon Coins" +chocolate_island_3_exit_1 = "Chocolate Island 3 - Normal Exit" +chocolate_island_3_exit_2 = "Chocolate Island 3 - Secret Exit" +chocolate_island_3_dragon = "Chocolate Island 3 - Dragon Coins" +chocolate_island_4_exit_1 = "Chocolate Island 4 - Normal Exit" +chocolate_island_4_dragon = "Chocolate Island 4 - Dragon Coins" +chocolate_island_5_exit_1 = "Chocolate Island 5 - Normal Exit" +chocolate_island_5_dragon = "Chocolate Island 5 - Dragon Coins" +chocolate_ghost_house_exit_1 = "Choco-Ghost House - Normal Exit" +chocolate_secret_exit_1 = "Chocolate Secret - Normal Exit" +chocolate_fortress = "Chocolate Fortress - Normal Exit" +chocolate_reznor = "Chocolate Fortress Defeat" +chocolate_castle = "#6 Wendy's Castle - Normal Exit" +chocolate_koopaling = "#6 Wendy's Castle - Boss" + +sunken_ghost_ship = "Sunken Ghost Ship - Normal Exit" +sunken_ghost_ship_dragon = "Sunken Ghost Ship - Dragon Coins" + +valley_of_bowser_1_exit_1 = "Valley of Bowser 1 - Normal Exit" +valley_of_bowser_1_dragon = "Valley of Bowser 1 - Dragon Coins" +valley_of_bowser_2_exit_1 = "Valley of Bowser 2 - Normal Exit" +valley_of_bowser_2_exit_2 = "Valley of Bowser 2 - Secret Exit" +valley_of_bowser_2_dragon = "Valley of Bowser 2 - Dragon Coins" +valley_of_bowser_3_exit_1 = "Valley of Bowser 3 - Normal Exit" +valley_of_bowser_3_dragon = "Valley of Bowser 3 - Dragon Coins" +valley_of_bowser_4_exit_1 = "Valley of Bowser 4 - Normal Exit" +valley_of_bowser_4_exit_2 = "Valley of Bowser 4 - Secret Exit" +valley_ghost_house_exit_1 = "Valley Ghost House - Normal Exit" +valley_ghost_house_exit_2 = "Valley Ghost House - Secret Exit" +valley_ghost_house_dragon = "Valley Ghost House - Dragon Coins" +valley_fortress = "Valley Fortress - Normal Exit" +valley_reznor = "Valley Fortress - Boss" +valley_castle = "#7 Larry's Castle - Normal Exit" +valley_castle_dragon = "#7 Larry's Castle - Dragon Coins" +valley_koopaling = "#7 Larry's Castle - Boss" + +front_door = "Front Door" +back_door = "Back Door" +bowser = "Bowser" + +star_road_1_exit_1 = "Star Road 1 - Normal Exit" +star_road_1_exit_2 = "Star Road 1 - Secret Exit" +star_road_1_dragon = "Star Road 1 - Dragon Coins" +star_road_2_exit_1 = "Star Road 2 - Normal Exit" +star_road_2_exit_2 = "Star Road 2 - Secret Exit" +star_road_3_exit_1 = "Star Road 3 - Normal Exit" +star_road_3_exit_2 = "Star Road 3 - Secret Exit" +star_road_4_exit_1 = "Star Road 4 - Normal Exit" +star_road_4_exit_2 = "Star Road 4 - Secret Exit" +star_road_5_exit_1 = "Star Road 5 - Normal Exit" +star_road_5_exit_2 = "Star Road 5 - Secret Exit" + +special_zone_1_exit_1 = "Gnarly - Normal Exit" +special_zone_1_dragon = "Gnarly - Dragon Coins" +special_zone_2_exit_1 = "Tubular - Normal Exit" +special_zone_2_dragon = "Tubular - Dragon Coins" +special_zone_3_exit_1 = "Way Cool - Normal Exit" +special_zone_3_dragon = "Way Cool - Dragon Coins" +special_zone_4_exit_1 = "Awesome - Normal Exit" +special_zone_4_dragon = "Awesome - Dragon Coins" +special_zone_5_exit_1 = "Groovy - Normal Exit" +special_zone_5_dragon = "Groovy - Dragon Coins" +special_zone_6_exit_1 = "Mondo - Normal Exit" +special_zone_6_dragon = "Mondo - Dragon Coins" +special_zone_7_exit_1 = "Outrageous - Normal Exit" +special_zone_7_dragon = "Outrageous - Dragon Coins" +special_zone_8_exit_1 = "Funky - Normal Exit" +special_zone_8_dragon = "Funky - Dragon Coins" + + +# Region Definitions +menu_region = "Menu" + +yoshis_island_region = "Yoshi's Island" +donut_plains_region = "Donut Plains" +vanilla_dome_region = "Vanilla Dome" +twin_bridges_region = "Twin Bridges" +forest_of_illusion_region = "Forest of Illusion" +chocolate_island_region = "Chocolate Island" +valley_of_bowser_region = "Valley of Bowser" +star_road_region = "Star Road" +special_zone_region = "Special Zone" + +yoshis_island_1_tile = "Yoshi's Island 1 - Tile" +yoshis_island_1_region = "Yoshi's Island 1" +yoshis_island_2_tile = "Yoshi's Island 2 - Tile" +yoshis_island_2_region = "Yoshi's Island 2" +yoshis_island_3_tile = "Yoshi's Island 3 - Tile" +yoshis_island_3_region = "Yoshi's Island 3" +yoshis_island_4_tile = "Yoshi's Island 4 - Tile" +yoshis_island_4_region = "Yoshi's Island 4" +yoshis_island_castle_tile = "#1 Iggy's Castle - Tile" +yoshis_island_castle_region = "#1 Iggy's Castle" + +yellow_switch_palace_tile = "Yellow Switch Palace - Tile" + +donut_plains_1_tile = "Donut Plains 1 - Tile" +donut_plains_1_region = "Donut Plains 1" +donut_plains_2_tile = "Donut Plains 2 - Tile" +donut_plains_2_region = "Donut Plains 2" +donut_plains_3_tile = "Donut Plains 3 - Tile" +donut_plains_3_region = "Donut Plains 3" +donut_plains_4_tile = "Donut Plains 4 - Tile" +donut_plains_4_region = "Donut Plains 4" +donut_secret_1_tile = "Donut Secret 1 - Tile" +donut_secret_1_region = "Donut Secret 1" +donut_secret_2_tile = "Donut Secret 2 - Tile" +donut_secret_2_region = "Donut Secret 2" +donut_ghost_house_tile = "Donut Ghost House - Tile" +donut_ghost_house_region = "Donut Ghost House" +donut_secret_house_tile = "Donut Secret House - Tile" +donut_secret_house_region = "Donut Secret House" +donut_plains_castle_tile = "#2 Morton's Castle - Tile" +donut_plains_castle_region = "#2 Morton's Castle" +donut_plains_top_secret = "Top Secret Area" +donut_plains_top_secret_tile = "Top Secret Area - Tile" +donut_plains_star_road = "Donut Plains - Star Road" + +green_switch_palace_tile = "Green Switch Palace - Tile" + +vanilla_dome_1_tile = "Vanilla Dome 1 - Tile" +vanilla_dome_1_region = "Vanilla Dome 1" +vanilla_dome_2_tile = "Vanilla Dome 2 - Tile" +vanilla_dome_2_region = "Vanilla Dome 2" +vanilla_dome_3_tile = "Vanilla Dome 3 - Tile" +vanilla_dome_3_region = "Vanilla Dome 3" +vanilla_dome_4_tile = "Vanilla Dome 4 - Tile" +vanilla_dome_4_region = "Vanilla Dome 4" +vanilla_secret_1_tile = "Vanilla Secret 1 - Tile" +vanilla_secret_1_region = "Vanilla Secret 1" +vanilla_secret_2_tile = "Vanilla Secret 2 - Tile" +vanilla_secret_2_region = "Vanilla Secret 2" +vanilla_secret_3_tile = "Vanilla Secret 3 - Tile" +vanilla_secret_3_region = "Vanilla Secret 3" +vanilla_ghost_house_tile = "Vanilla Ghost House - Tile" +vanilla_ghost_house_region = "Vanilla Ghost House" +vanilla_fortress_tile = "Vanilla Fortress - Tile" +vanilla_fortress_region = "Vanilla Fortress" +vanilla_dome_castle_tile = "#3 Lemmy's Castle - Tile" +vanilla_dome_castle_region = "#3 Lemmy's Castle" +vanilla_dome_star_road = "Vanilla Dome - Star Road" + +red_switch_palace_tile = "Red Switch Palace - Tile" + +butter_bridge_1_tile = "Butter Bridge 1 - Tile" +butter_bridge_1_region = "Butter Bridge 1" +butter_bridge_2_tile = "Butter Bridge 2 - Tile" +butter_bridge_2_region = "Butter Bridge 2" +cheese_bridge_tile = "Cheese Bridge - Tile" +cheese_bridge_region = "Cheese Bridge" +cookie_mountain_tile = "Cookie Mountain - Tile" +cookie_mountain_region = "Cookie Mountain" +soda_lake_tile = "Soda Lake - Tile" +soda_lake_region = "Soda Lake" +twin_bridges_castle_tile = "#4 Ludwig's Castle - Tile" +twin_bridges_castle_region = "#4 Ludwig's Castle" +twin_bridges_star_road = "Twin Bridges - Star Road" + +forest_of_illusion_1_tile = "Forest of Illusion 1 - Tile" +forest_of_illusion_1_region = "Forest of Illusion 1" +forest_of_illusion_2_tile = "Forest of Illusion 2 - Tile" +forest_of_illusion_2_region = "Forest of Illusion 2" +forest_of_illusion_3_tile = "Forest of Illusion 3 - Tile" +forest_of_illusion_3_region = "Forest of Illusion 3" +forest_of_illusion_4_tile = "Forest of Illusion 4 - Tile" +forest_of_illusion_4_region = "Forest of Illusion 4" +forest_ghost_house_tile = "Forest Ghost House - Tile" +forest_ghost_house_region = "Forest Ghost House" +forest_secret_tile = "Forest Secret - Tile" +forest_secret_region = "Forest Secret" +forest_fortress_tile = "Forest Fortress - Tile" +forest_fortress_region = "Forest Fortress" +forest_castle_tile = "#5 Roy's Castle - Tile" +forest_castle_region = "#5 Roy's Castle" +forest_star_road = "Forest of Illusion - Star Road" + +blue_switch_palace_tile = "Blue Switch Palace - Tile" + +chocolate_island_1_tile = "Chocolate Island 1 - Tile" +chocolate_island_1_region = "Chocolate Island 1" +chocolate_island_2_tile = "Chocolate Island 2 - Tile" +chocolate_island_2_region = "Chocolate Island 2" +chocolate_island_3_tile = "Chocolate Island 3 - Tile" +chocolate_island_3_region = "Chocolate Island 3" +chocolate_island_4_tile = "Chocolate Island 4 - Tile" +chocolate_island_4_region = "Chocolate Island 4" +chocolate_island_5_tile = "Chocolate Island 5 - Tile" +chocolate_island_5_region = "Chocolate Island 5" +chocolate_ghost_house_tile = "Choco-Ghost House - Tile" +chocolate_ghost_house_region = "Choco-Ghost House" +chocolate_secret_tile = "Chocolate Secret - Tile" +chocolate_secret_region = "Chocolate Secret" +chocolate_fortress_tile = "Chocolate Fortress - Tile" +chocolate_fortress_region = "Chocolate Fortress" +chocolate_castle_tile = "#6 Wendy's Castle - Tile" +chocolate_castle_region = "#6 Wendy's Castle" + +sunken_ghost_ship_tile = "Sunken Ghost Ship - Tile" +sunken_ghost_ship_region = "Sunken Ghost Ship" + +valley_of_bowser_1_tile = "Valley of Bowser 1 - Tile" +valley_of_bowser_1_region = "Valley of Bowser 1" +valley_of_bowser_2_tile = "Valley of Bowser 2 - Tile" +valley_of_bowser_2_region = "Valley of Bowser 2" +valley_of_bowser_3_tile = "Valley of Bowser 3 - Tile" +valley_of_bowser_3_region = "Valley of Bowser 3" +valley_of_bowser_4_tile = "Valley of Bowser 4 - Tile" +valley_of_bowser_4_region = "Valley of Bowser 4" +valley_ghost_house_tile = "Valley Ghost House - Tile" +valley_ghost_house_region = "Valley Ghost House" +valley_fortress_tile = "Valley Fortress - Tile" +valley_fortress_region = "Valley Fortress" +valley_castle_tile = "#7 Larry's Castle - Tile" +valley_castle_region = "#7 Larry's Castle" +valley_star_road = "Valley of Bowser - Star Road" + +front_door_tile = "Front Door - Tile" +back_door_tile = "Back Door - Tile" +bowser_region = "Bowser - Region" + +star_road_donut = "Star Road - Donut Plains" +star_road_1_tile = "Star Road 1 - Tile" +star_road_1_region = "Star Road 1" +star_road_vanilla = "Star Road - Vanilla Dome" +star_road_2_tile = "Star Road 2 - Tile" +star_road_2_region = "Star Road 2" +star_road_twin_bridges = "Star Road - Twin Bridges" +star_road_3_tile = "Star Road 3 - Tile" +star_road_3_region = "Star Road 3" +star_road_forest = "Star Road - Forest of Illusion" +star_road_4_tile = "Star Road 4 - Tile" +star_road_4_region = "Star Road 4" +star_road_valley = "Star Road - Valley of Bowser" +star_road_5_tile = "Star Road 5 - Tile" +star_road_5_region = "Star Road 5" +star_road_special = "Star Road - Special Zone" + +special_star_road = "Special Zone - Star Road" +special_zone_1_tile = "Gnarly - Tile" +special_zone_1_region = "Gnarly" +special_zone_2_tile = "Tubular - Tile" +special_zone_2_region = "Tubular" +special_zone_3_tile = "Way Cool - Tile" +special_zone_3_region = "Way Cool" +special_zone_4_tile = "Awesome - Tile" +special_zone_4_region = "Awesome" +special_zone_5_tile = "Groovy - Tile" +special_zone_5_region = "Groovy" +special_zone_6_tile = "Mondo - Tile" +special_zone_6_region = "Mondo" +special_zone_7_tile = "Outrageous - Tile" +special_zone_7_region = "Outrageous" +special_zone_8_tile = "Funky - Tile" +special_zone_8_region = "Funky" +special_complete = "Special Zone - Star Road - Complete" diff --git a/worlds/smw/Names/TextBox.py b/worlds/smw/Names/TextBox.py new file mode 100644 index 00000000..cecf0886 --- /dev/null +++ b/worlds/smw/Names/TextBox.py @@ -0,0 +1,140 @@ + +from BaseClasses import MultiWorld + +import math + + +text_mapping = { + "A": 0x00, "B": 0x01, "C": 0x02, "D": 0x03, "E": 0x04, "F": 0x05, "G": 0x06, "H": 0x07, "I": 0x08, "J": 0x09, + "K": 0x0A, "L": 0x0B, "M": 0x0C, "N": 0x0D, "O": 0x0E, "P": 0x0F, "Q": 0x10, "R": 0x11, "S": 0x12, "T": 0x13, + "U": 0x14, "V": 0x15, "W": 0x16, "X": 0x17, "Y": 0x18, "Z": 0x19, + + "!": 0x1A, ".": 0x1B, "-": 0x1C, ",": 0x1D, "?": 0x1E, " ": 0x1F, + + "0": 0x22, "1": 0x23, "2": 0x24, "3": 0x25, "4": 0x26, "5": 0x27, "6": 0x28, "7": 0x29, "8": 0x2A, "9": 0x2B, + + "a": 0x40, "b": 0x41, "c": 0x42, "d": 0x43, "e": 0x44, "f": 0x45, "g": 0x46, "h": 0x47, "i": 0x48, "j": 0x49, + "k": 0x4A, "l": 0x4B, "m": 0x4C, "n": 0x4D, "o": 0x4E, "p": 0x4F, "q": 0x50, "r": 0x51, "s": 0x52, "t": 0x53, + "u": 0x54, "v": 0x55, "w": 0x56, "x": 0x57, "y": 0x58, "z": 0x59, + + "#": 0x5A, "(": 0x5B, ")": 0x5C, "'": 0x5D +} + +title_text_mapping = { + "A": [0x0A, 0x38], "B": [0x0B, 0x38], "C": [0x0C, 0x38], "D": [0x0D, 0x38], "E": [0x0E, 0x38], + "F": [0x0F, 0x38], "G": [0x10, 0x38], "H": [0x11, 0x38], "I": [0x12, 0x38], "J": [0x13, 0x38], + "K": [0x14, 0x38], "L": [0x15, 0x38], "M": [0x16, 0x38], "N": [0x17, 0x38], "O": [0x18, 0x38], + "P": [0x19, 0x38], "Q": [0x1A, 0x38], "R": [0x1B, 0x38], "S": [0x1C, 0x38], "T": [0x1D, 0x38], + "U": [0x1E, 0x38], "V": [0x1F, 0x38], "W": [0x20, 0x38], "X": [0x21, 0x38], "Y": [0x22, 0x38], + "Z": [0x23, 0x38], " ": [0xFC, 0x38], ".": [0x24, 0x38], + "0": [0x00, 0x38], "1": [0x01, 0x38], "2": [0x02, 0x38], "3": [0x03, 0x38], "4": [0x04, 0x38], + "5": [0x05, 0x38], "6": [0x06, 0x38], "7": [0x07, 0x38], "8": [0x08, 0x38], "9": [0x09, 0x38], +} + + +def string_to_bytes(input_string): + out_array = bytearray() + for letter in input_string: + out_array.append(text_mapping[letter] if letter in text_mapping else text_mapping["."]) + + return out_array + + +def generate_text_box(input_string): + out_bytes = bytearray() + box_line_count = 0 + box_line_chr_count = 0 + for word in input_string.split(): + if box_line_chr_count + len(word) > 18: + out_bytes[-1] += 0x80 + box_line_count += 1 + box_line_chr_count = 0 + + out_bytes.extend(string_to_bytes(word)) + box_line_chr_count += len(word) + + if box_line_chr_count < 18: + box_line_chr_count += 1 + out_bytes.append(0x1F) + + for i in range(box_line_count, 8): + out_bytes.append(0x9F) + + return out_bytes + + +def generate_goal_text(world: MultiWorld, player: int): + out_array = bytearray() + if world.goal[player] == "yoshi_egg_hunt": + required_yoshi_eggs = max(math.floor( + world.number_of_yoshi_eggs[player].value * (world.percentage_of_yoshi_eggs[player].value / 100.0)), 1) + out_array += bytearray([0x9F, 0x9F]) + out_array += string_to_bytes(" You must acquire") + out_array[-1] += 0x80 + out_array += string_to_bytes(f' {required_yoshi_eggs:02} Yoshi Eggs,') + out_array[-1] += 0x80 + out_array += string_to_bytes("then return here.") + out_array[-1] += 0x80 + out_array += bytearray([0x9F, 0x9F, 0x9F]) + else: + bosses_required = world.bosses_required[player].value + out_array += bytearray([0x9F, 0x9F]) + out_array += string_to_bytes(" You must defeat") + out_array[-1] += 0x80 + out_array += string_to_bytes(f' {bosses_required:02} Bosses,') + out_array[-1] += 0x80 + out_array += string_to_bytes("then defeat Bowser") + out_array[-1] += 0x80 + out_array += bytearray([0x9F, 0x9F, 0x9F]) + + return out_array + + +def generate_received_text(item_name: str, player_name: str): + out_array = bytearray() + + item_name = item_name[:18] + player_name = player_name[:18] + + item_buffer = max(0, math.floor((18 - len(item_name)) / 2)) + player_buffer = max(0, math.floor((18 - len(player_name)) / 2)) + + out_array += bytearray([0x9F, 0x9F]) + out_array += string_to_bytes(" Received") + out_array[-1] += 0x80 + out_array += bytearray([0x1F] * item_buffer) + out_array += string_to_bytes(item_name) + out_array[-1] += 0x80 + out_array += string_to_bytes(" from") + out_array[-1] += 0x80 + out_array += bytearray([0x1F] * player_buffer) + out_array += string_to_bytes(player_name) + out_array[-1] += 0x80 + out_array += bytearray([0x9F, 0x9F]) + + return out_array + + +def generate_sent_text(item_name: str, player_name: str): + out_array = bytearray() + + item_name = item_name[:18] + player_name = player_name[:18] + + item_buffer = max(0, math.floor((18 - len(item_name)) / 2)) + player_buffer = max(0, math.floor((18 - len(player_name)) / 2)) + + out_array += bytearray([0x9F, 0x9F]) + out_array += string_to_bytes(" Sent") + out_array[-1] += 0x80 + out_array += bytearray([0x1F] * item_buffer) + out_array += string_to_bytes(item_name) + out_array[-1] += 0x80 + out_array += string_to_bytes(" to") + out_array[-1] += 0x80 + out_array += bytearray([0x1F] * player_buffer) + out_array += string_to_bytes(player_name) + out_array[-1] += 0x80 + out_array += bytearray([0x9F, 0x9F]) + + return out_array diff --git a/worlds/smw/Options.py b/worlds/smw/Options.py new file mode 100644 index 00000000..80af63f5 --- /dev/null +++ b/worlds/smw/Options.py @@ -0,0 +1,236 @@ +import typing + +from Options import Choice, Range, Option, Toggle, DeathLink, DefaultOnToggle, OptionList + + +class Goal(Choice): + """ + Determines the goal of the seed + Bowser: Defeat Koopalings, reach Bowser's Castle and defeat Bowser + Yoshi Egg Hunt: Find a certain number of Yoshi Eggs + """ + display_name = "Goal" + option_bowser = 0 + option_yoshi_egg_hunt = 1 + default = 0 + + +class BossesRequired(Range): + """ + How many Bosses (Koopalings or Reznor) must be defeated in order to defeat Bowser + """ + display_name = "Bosses Required" + range_start = 0 + range_end = 11 + default = 7 + + +class NumberOfYoshiEggs(Range): + """ + How many Yoshi Eggs are in the pool for Yoshi Egg Hunt + """ + display_name = "Total Number of Yoshi Eggs" + range_start = 1 + range_end = 80 + default = 50 + + +class PercentageOfYoshiEggs(Range): + """ + What Percentage of Yoshi Eggs are required to finish Yoshi Egg Hunt + """ + display_name = "Required Percentage of Yoshi Eggs" + range_start = 1 + range_end = 100 + default = 100 + + +class DragonCoinChecks(Toggle): + """ + Whether collecting 5 Dragon Coins in each level will grant a check + """ + display_name = "Dragon Coin Checks" + + +class BowserCastleDoors(Choice): + """ + How the doors of Bowser's Castle behave + Vanilla: Front and Back Doors behave as vanilla + Fast: Both doors behave as the Back Door + Slow: Both doors behave as the Front Door + "Front Door" requires beating all 8 Rooms + "Back Door" only requires going through the dark hallway to Bowser + """ + display_name = "Bowser Castle Doors" + option_vanilla = 0 + option_fast = 1 + option_slow = 2 + default = 0 + + +class LevelShuffle(Toggle): + """ + Whether levels are shuffled + """ + display_name = "Level Shuffle" + + +class SwapDonutGhostHouseExits(Toggle): + """ + If enabled, this option will swap which overworld direction the two exits of the level at the Donut Ghost House overworld tile go: + False: Normal Exit goes up, Secret Exit goes right. + True: Normal Exit goes right, Secret Exit goes up. + """ + display_name = "Swap Donut GH Exits" + + +class DisplaySentItemPopups(Choice): + """ + What messages to display in-game for items sent + """ + display_name = "Display Sent Item Popups" + option_none = 0 + option_all = 1 + default = 1 + + +class DisplayReceivedItemPopups(Choice): + """ + What messages to display in-game for items received + """ + display_name = "Display Received Item Popups" + option_none = 0 + option_all = 1 + option_progression = 2 + default = 2 + + +class TrapFillPercentage(Range): + """ + Replace a percentage of junk items in the item pool with random traps + """ + display_name = "Trap Fill Percentage" + range_start = 0 + range_end = 100 + default = 0 + + +class BaseTrapWeight(Choice): + """ + Base Class for Trap Weights + """ + option_none = 0 + option_low = 1 + option_medium = 2 + option_high = 4 + default = 2 + + +class IceTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes the level to become slippery + """ + display_name = "Ice Trap Weight" + + +class StunTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which briefly stuns Mario + """ + display_name = "Stun Trap Weight" + + +class LiteratureTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes the player to read literature + """ + display_name = "Literature Trap Weight" + + +class Autosave(DefaultOnToggle): + """ + Whether a save prompt will appear after every level + """ + display_name = "Autosave" + + +class MusicShuffle(Choice): + """ + Music shuffle type + None: No Music is shuffled + Consistent: Each music track is consistently shuffled throughout the game + Full: Each individual level has a random music track + Singularity: The entire game uses one song for overworld and one song for levels + """ + display_name = "Music Shuffle" + option_none = 0 + option_consistent = 1 + option_full = 2 + option_singularity = 3 + default = 0 + + +class MarioPalette(Choice): + """ + Mario palette color + """ + display_name = "Mario Palette" + option_mario = 0 + option_luigi = 1 + option_wario = 2 + option_waluigi = 3 + option_geno = 4 + option_princess = 5 + option_dark = 6 + option_sponge = 7 + default = 0 + + +class ForegroundPaletteShuffle(Toggle): + """ + Whether to shuffle level foreground palettes + """ + display_name = "Foreground Palette Shuffle" + + +class BackgroundPaletteShuffle(Toggle): + """ + Whether to shuffle level background palettes + """ + display_name = "Background Palette Shuffle" + + +class StartingLifeCount(Range): + """ + How many extra lives to start the game with + """ + display_name = "Starting Life Count" + range_start = 1 + range_end = 99 + default = 5 + + + +smw_options: typing.Dict[str, type(Option)] = { + "death_link": DeathLink, + "goal": Goal, + "bosses_required": BossesRequired, + "number_of_yoshi_eggs": NumberOfYoshiEggs, + "percentage_of_yoshi_eggs": PercentageOfYoshiEggs, + "dragon_coin_checks": DragonCoinChecks, + "bowser_castle_doors": BowserCastleDoors, + "level_shuffle": LevelShuffle, + "swap_donut_gh_exits": SwapDonutGhostHouseExits, + #"display_sent_item_popups": DisplaySentItemPopups, + "display_received_item_popups": DisplayReceivedItemPopups, + "trap_fill_percentage": TrapFillPercentage, + "ice_trap_weight": IceTrapWeight, + "stun_trap_weight": StunTrapWeight, + "literature_trap_weight": LiteratureTrapWeight, + "autosave": Autosave, + "music_shuffle": MusicShuffle, + "mario_palette": MarioPalette, + "foreground_palette_shuffle": ForegroundPaletteShuffle, + "background_palette_shuffle": BackgroundPaletteShuffle, + "starting_life_count": StartingLifeCount, +} diff --git a/worlds/smw/Regions.py b/worlds/smw/Regions.py new file mode 100644 index 00000000..7af7b888 --- /dev/null +++ b/worlds/smw/Regions.py @@ -0,0 +1,1187 @@ +import typing + +from BaseClasses import MultiWorld, Region, RegionType, Entrance +from .Locations import SMWLocation +from .Levels import level_info_dict +from .Names import LocationName, ItemName +from ..generic.Rules import add_rule, set_rule + + +def create_regions(world, player: int, active_locations): + menu_region = create_region(world, player, active_locations, 'Menu', None) + + yoshis_island_region = create_region(world, player, active_locations, LocationName.yoshis_island_region, None) + donut_plains_region = create_region(world, player, active_locations, LocationName.donut_plains_region, None) + vanilla_dome_region = create_region(world, player, active_locations, LocationName.vanilla_dome_region, None) + twin_bridges_region = create_region(world, player, active_locations, LocationName.twin_bridges_region, None) + forest_of_illusion_region = create_region(world, player, active_locations, LocationName.forest_of_illusion_region, None) + chocolate_island_region = create_region(world, player, active_locations, LocationName.chocolate_island_region, None) + valley_of_bowser_region = create_region(world, player, active_locations, LocationName.valley_of_bowser_region, None) + star_road_region = create_region(world, player, active_locations, LocationName.star_road_region, None) + special_zone_region = create_region(world, player, active_locations, LocationName.special_zone_region, None) + + + yoshis_house_tile = create_region(world, player, active_locations, LocationName.yoshis_house_tile, None) + + yoshis_house_region_locations = [] + if world.goal[player] == "yoshi_egg_hunt": + yoshis_house_region_locations.append(LocationName.yoshis_house) + yoshis_house_region = create_region(world, player, active_locations, LocationName.yoshis_house, + yoshis_house_region_locations) + + yoshis_island_1_tile = create_region(world, player, active_locations, LocationName.yoshis_island_1_tile, None) + yoshis_island_1_region = create_region(world, player, active_locations, LocationName.yoshis_island_1_region, None) + yoshis_island_1_exit_1 = create_region(world, player, active_locations, LocationName.yoshis_island_1_exit_1, + [LocationName.yoshis_island_1_exit_1]) + + yoshis_island_2_tile = create_region(world, player, active_locations, LocationName.yoshis_island_2_tile, None) + yoshis_island_2_region = create_region(world, player, active_locations, LocationName.yoshis_island_2_region, None) + yoshis_island_2_exit_1 = create_region(world, player, active_locations, LocationName.yoshis_island_2_exit_1, + [LocationName.yoshis_island_2_exit_1]) + + yoshis_island_3_tile = create_region(world, player, active_locations, LocationName.yoshis_island_3_tile, None) + yoshis_island_3_region = create_region(world, player, active_locations, LocationName.yoshis_island_3_region, None) + yoshis_island_3_exit_1 = create_region(world, player, active_locations, LocationName.yoshis_island_3_exit_1, + [LocationName.yoshis_island_3_exit_1]) + + yoshis_island_4_tile = create_region(world, player, active_locations, LocationName.yoshis_island_4_tile, None) + yoshis_island_4_region = create_region(world, player, active_locations, LocationName.yoshis_island_4_region, None) + yoshis_island_4_exit_1 = create_region(world, player, active_locations, LocationName.yoshis_island_4_exit_1, + [LocationName.yoshis_island_4_exit_1]) + + yoshis_island_castle_tile = create_region(world, player, active_locations, LocationName.yoshis_island_castle_tile, None) + yoshis_island_castle_region = create_region(world, player, active_locations, LocationName.yoshis_island_castle_region, None) + yoshis_island_castle = create_region(world, player, active_locations, LocationName.yoshis_island_castle, + [LocationName.yoshis_island_castle, LocationName.yoshis_island_koopaling]) + + yellow_switch_palace_tile = create_region(world, player, active_locations, LocationName.yellow_switch_palace_tile, None) + yellow_switch_palace = create_region(world, player, active_locations, LocationName.yellow_switch_palace, + [LocationName.yellow_switch_palace]) + + + donut_plains_1_tile = create_region(world, player, active_locations, LocationName.donut_plains_1_tile, None) + donut_plains_1_region = create_region(world, player, active_locations, LocationName.donut_plains_1_region, None) + donut_plains_1_exit_1 = create_region(world, player, active_locations, LocationName.donut_plains_1_exit_1, + [LocationName.donut_plains_1_exit_1]) + donut_plains_1_exit_2 = create_region(world, player, active_locations, LocationName.donut_plains_1_exit_2, + [LocationName.donut_plains_1_exit_2]) + + donut_plains_2_tile = create_region(world, player, active_locations, LocationName.donut_plains_2_tile, None) + donut_plains_2_region = create_region(world, player, active_locations, LocationName.donut_plains_2_region, None) + donut_plains_2_exit_1 = create_region(world, player, active_locations, LocationName.donut_plains_2_exit_1, + [LocationName.donut_plains_2_exit_1]) + donut_plains_2_exit_2 = create_region(world, player, active_locations, LocationName.donut_plains_2_exit_2, + [LocationName.donut_plains_2_exit_2]) + + donut_plains_3_tile = create_region(world, player, active_locations, LocationName.donut_plains_3_tile, None) + donut_plains_3_region = create_region(world, player, active_locations, LocationName.donut_plains_3_region, None) + donut_plains_3_exit_1 = create_region(world, player, active_locations, LocationName.donut_plains_3_exit_1, + [LocationName.donut_plains_3_exit_1]) + + donut_plains_4_tile = create_region(world, player, active_locations, LocationName.donut_plains_4_tile, None) + donut_plains_4_region = create_region(world, player, active_locations, LocationName.donut_plains_4_region, None) + donut_plains_4_exit_1 = create_region(world, player, active_locations, LocationName.donut_plains_4_exit_1, + [LocationName.donut_plains_4_exit_1]) + + donut_secret_1_tile = create_region(world, player, active_locations, LocationName.donut_secret_1_tile, None) + donut_secret_1_region = create_region(world, player, active_locations, LocationName.donut_secret_1_region, None) + donut_secret_1_exit_1 = create_region(world, player, active_locations, LocationName.donut_secret_1_exit_1, + [LocationName.donut_secret_1_exit_1]) + donut_secret_1_exit_2 = create_region(world, player, active_locations, LocationName.donut_secret_1_exit_2, + [LocationName.donut_secret_1_exit_2]) + + donut_secret_2_tile = create_region(world, player, active_locations, LocationName.donut_secret_2_tile, None) + donut_secret_2_region = create_region(world, player, active_locations, LocationName.donut_secret_2_region, None) + donut_secret_2_exit_1 = create_region(world, player, active_locations, LocationName.donut_secret_2_exit_1, + [LocationName.donut_secret_2_exit_1]) + + donut_ghost_house_tile = create_region(world, player, active_locations, LocationName.donut_ghost_house_tile, None) + donut_ghost_house_region = create_region(world, player, active_locations, LocationName.donut_ghost_house_region, None) + donut_ghost_house_exit_1 = create_region(world, player, active_locations, LocationName.donut_ghost_house_exit_1, + [LocationName.donut_ghost_house_exit_1]) + donut_ghost_house_exit_2 = create_region(world, player, active_locations, LocationName.donut_ghost_house_exit_2, + [LocationName.donut_ghost_house_exit_2]) + + donut_secret_house_tile = create_region(world, player, active_locations, LocationName.donut_secret_house_tile, None) + donut_secret_house_region = create_region(world, player, active_locations, LocationName.donut_secret_house_region, None) + donut_secret_house_exit_1 = create_region(world, player, active_locations, LocationName.donut_secret_house_exit_1, + [LocationName.donut_secret_house_exit_1]) + donut_secret_house_exit_2 = create_region(world, player, active_locations, LocationName.donut_secret_house_exit_2, + [LocationName.donut_secret_house_exit_2]) + + donut_plains_castle_tile = create_region(world, player, active_locations, LocationName.donut_plains_castle_tile, None) + donut_plains_castle_region = create_region(world, player, active_locations, LocationName.donut_plains_castle_region, None) + donut_plains_castle = create_region(world, player, active_locations, LocationName.donut_plains_castle, + [LocationName.donut_plains_castle, LocationName.donut_plains_koopaling]) + + green_switch_palace_tile = create_region(world, player, active_locations, LocationName.green_switch_palace_tile, None) + green_switch_palace = create_region(world, player, active_locations, LocationName.green_switch_palace, + [LocationName.green_switch_palace]) + + donut_plains_top_secret_tile = create_region(world, player, active_locations, LocationName.donut_plains_top_secret_tile, None) + donut_plains_top_secret = create_region(world, player, active_locations, LocationName.donut_plains_top_secret, None) + + + vanilla_dome_1_tile = create_region(world, player, active_locations, LocationName.vanilla_dome_1_tile, None) + vanilla_dome_1_region = create_region(world, player, active_locations, LocationName.vanilla_dome_1_region, None) + vanilla_dome_1_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_dome_1_exit_1, + [LocationName.vanilla_dome_1_exit_1]) + vanilla_dome_1_exit_2 = create_region(world, player, active_locations, LocationName.vanilla_dome_1_exit_2, + [LocationName.vanilla_dome_1_exit_2]) + + vanilla_dome_2_tile = create_region(world, player, active_locations, LocationName.vanilla_dome_2_tile, None) + vanilla_dome_2_region = create_region(world, player, active_locations, LocationName.vanilla_dome_2_region, None) + vanilla_dome_2_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_dome_2_exit_1, + [LocationName.vanilla_dome_2_exit_1]) + vanilla_dome_2_exit_2 = create_region(world, player, active_locations, LocationName.vanilla_dome_2_exit_2, + [LocationName.vanilla_dome_2_exit_2]) + + vanilla_dome_3_tile = create_region(world, player, active_locations, LocationName.vanilla_dome_3_tile, None) + vanilla_dome_3_region = create_region(world, player, active_locations, LocationName.vanilla_dome_3_region, None) + vanilla_dome_3_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_dome_3_exit_1, + [LocationName.vanilla_dome_3_exit_1]) + + vanilla_dome_4_tile = create_region(world, player, active_locations, LocationName.vanilla_dome_4_tile, None) + vanilla_dome_4_region = create_region(world, player, active_locations, LocationName.vanilla_dome_4_region, None) + vanilla_dome_4_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_dome_4_exit_1, + [LocationName.vanilla_dome_4_exit_1]) + + vanilla_secret_1_tile = create_region(world, player, active_locations, LocationName.vanilla_secret_1_tile, None) + vanilla_secret_1_region = create_region(world, player, active_locations, LocationName.vanilla_secret_1_region, None) + vanilla_secret_1_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_secret_1_exit_1, + [LocationName.vanilla_secret_1_exit_1]) + vanilla_secret_1_exit_2 = create_region(world, player, active_locations, LocationName.vanilla_secret_1_exit_2, + [LocationName.vanilla_secret_1_exit_2]) + + vanilla_secret_2_tile = create_region(world, player, active_locations, LocationName.vanilla_secret_2_tile, None) + vanilla_secret_2_region = create_region(world, player, active_locations, LocationName.vanilla_secret_2_region, None) + vanilla_secret_2_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_secret_2_exit_1, + [LocationName.vanilla_secret_2_exit_1]) + + vanilla_secret_3_tile = create_region(world, player, active_locations, LocationName.vanilla_secret_3_tile, None) + vanilla_secret_3_region = create_region(world, player, active_locations, LocationName.vanilla_secret_3_region, None) + vanilla_secret_3_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_secret_3_exit_1, + [LocationName.vanilla_secret_3_exit_1]) + + vanilla_ghost_house_tile = create_region(world, player, active_locations, LocationName.vanilla_ghost_house_tile, None) + vanilla_ghost_house_region = create_region(world, player, active_locations, LocationName.vanilla_ghost_house_region, None) + vanilla_ghost_house_exit_1 = create_region(world, player, active_locations, LocationName.vanilla_ghost_house_exit_1, + [LocationName.vanilla_ghost_house_exit_1]) + + vanilla_fortress_tile = create_region(world, player, active_locations, LocationName.vanilla_fortress_tile, None) + vanilla_fortress_region = create_region(world, player, active_locations, LocationName.vanilla_fortress_region, None) + vanilla_fortress = create_region(world, player, active_locations, LocationName.vanilla_fortress, + [LocationName.vanilla_fortress, LocationName.vanilla_reznor]) + + vanilla_dome_castle_tile = create_region(world, player, active_locations, LocationName.vanilla_dome_castle_tile, None) + vanilla_dome_castle_region = create_region(world, player, active_locations, LocationName.vanilla_dome_castle_region, None) + vanilla_dome_castle = create_region(world, player, active_locations, LocationName.vanilla_dome_castle, + [LocationName.vanilla_dome_castle, LocationName.vanilla_dome_koopaling]) + + red_switch_palace_tile = create_region(world, player, active_locations, LocationName.red_switch_palace_tile, None) + red_switch_palace = create_region(world, player, active_locations, LocationName.red_switch_palace, + [LocationName.red_switch_palace]) + + + butter_bridge_1_tile = create_region(world, player, active_locations, LocationName.butter_bridge_1_tile, None) + butter_bridge_1_region = create_region(world, player, active_locations, LocationName.butter_bridge_1_region, None) + butter_bridge_1_exit_1 = create_region(world, player, active_locations, LocationName.butter_bridge_1_exit_1, + [LocationName.butter_bridge_1_exit_1]) + + butter_bridge_2_tile = create_region(world, player, active_locations, LocationName.butter_bridge_2_tile, None) + butter_bridge_2_region = create_region(world, player, active_locations, LocationName.butter_bridge_2_region, None) + butter_bridge_2_exit_1 = create_region(world, player, active_locations, LocationName.butter_bridge_2_exit_1, + [LocationName.butter_bridge_2_exit_1]) + + cheese_bridge_tile = create_region(world, player, active_locations, LocationName.cheese_bridge_tile, None) + cheese_bridge_region = create_region(world, player, active_locations, LocationName.cheese_bridge_region, None) + cheese_bridge_exit_1 = create_region(world, player, active_locations, LocationName.cheese_bridge_exit_1, + [LocationName.cheese_bridge_exit_1]) + cheese_bridge_exit_2 = create_region(world, player, active_locations, LocationName.cheese_bridge_exit_2, + [LocationName.cheese_bridge_exit_2]) + + cookie_mountain_tile = create_region(world, player, active_locations, LocationName.cookie_mountain_tile, None) + cookie_mountain_region = create_region(world, player, active_locations, LocationName.cookie_mountain_region, None) + cookie_mountain_exit_1 = create_region(world, player, active_locations, LocationName.cookie_mountain_exit_1, + [LocationName.cookie_mountain_exit_1]) + + soda_lake_tile = create_region(world, player, active_locations, LocationName.soda_lake_tile, None) + soda_lake_region = create_region(world, player, active_locations, LocationName.soda_lake_region, None) + soda_lake_exit_1 = create_region(world, player, active_locations, LocationName.soda_lake_exit_1, + [LocationName.soda_lake_exit_1]) + + twin_bridges_castle_tile = create_region(world, player, active_locations, LocationName.twin_bridges_castle_tile, None) + twin_bridges_castle_region = create_region(world, player, active_locations, LocationName.twin_bridges_castle_region, None) + twin_bridges_castle = create_region(world, player, active_locations, LocationName.twin_bridges_castle, + [LocationName.twin_bridges_castle, LocationName.twin_bridges_koopaling]) + + + forest_of_illusion_1_tile = create_region(world, player, active_locations, LocationName.forest_of_illusion_1_tile, None) + forest_of_illusion_1_region = create_region(world, player, active_locations, LocationName.forest_of_illusion_1_region, None) + forest_of_illusion_1_exit_1 = create_region(world, player, active_locations, LocationName.forest_of_illusion_1_exit_1, + [LocationName.forest_of_illusion_1_exit_1]) + forest_of_illusion_1_exit_2 = create_region(world, player, active_locations, LocationName.forest_of_illusion_1_exit_2, + [LocationName.forest_of_illusion_1_exit_2]) + + forest_of_illusion_2_tile = create_region(world, player, active_locations, LocationName.forest_of_illusion_2_tile, None) + forest_of_illusion_2_region = create_region(world, player, active_locations, LocationName.forest_of_illusion_2_region, None) + forest_of_illusion_2_exit_1 = create_region(world, player, active_locations, LocationName.forest_of_illusion_2_exit_1, + [LocationName.forest_of_illusion_2_exit_1]) + forest_of_illusion_2_exit_2 = create_region(world, player, active_locations, LocationName.forest_of_illusion_2_exit_2, + [LocationName.forest_of_illusion_2_exit_2]) + + forest_of_illusion_3_tile = create_region(world, player, active_locations, LocationName.forest_of_illusion_3_tile, None) + forest_of_illusion_3_region = create_region(world, player, active_locations, LocationName.forest_of_illusion_3_region, None) + forest_of_illusion_3_exit_1 = create_region(world, player, active_locations, LocationName.forest_of_illusion_3_exit_1, + [LocationName.forest_of_illusion_3_exit_1]) + forest_of_illusion_3_exit_2 = create_region(world, player, active_locations, LocationName.forest_of_illusion_3_exit_2, + [LocationName.forest_of_illusion_3_exit_2]) + + forest_of_illusion_4_tile = create_region(world, player, active_locations, LocationName.forest_of_illusion_4_tile, None) + forest_of_illusion_4_region = create_region(world, player, active_locations, LocationName.forest_of_illusion_4_region, None) + forest_of_illusion_4_exit_1 = create_region(world, player, active_locations, LocationName.forest_of_illusion_4_exit_1, + [LocationName.forest_of_illusion_4_exit_1]) + forest_of_illusion_4_exit_2 = create_region(world, player, active_locations, LocationName.forest_of_illusion_4_exit_2, + [LocationName.forest_of_illusion_4_exit_2]) + + forest_ghost_house_tile = create_region(world, player, active_locations, LocationName.forest_ghost_house_tile, None) + forest_ghost_house_region = create_region(world, player, active_locations, LocationName.forest_ghost_house_region, None) + forest_ghost_house_exit_1 = create_region(world, player, active_locations, LocationName.forest_ghost_house_exit_1, + [LocationName.forest_ghost_house_exit_1]) + forest_ghost_house_exit_2 = create_region(world, player, active_locations, LocationName.forest_ghost_house_exit_2, + [LocationName.forest_ghost_house_exit_2]) + + forest_secret_tile = create_region(world, player, active_locations, LocationName.forest_secret_tile, None) + forest_secret_region = create_region(world, player, active_locations, LocationName.forest_secret_region, None) + forest_secret_exit_1 = create_region(world, player, active_locations, LocationName.forest_secret_exit_1, + [LocationName.forest_secret_exit_1]) + + forest_fortress_tile = create_region(world, player, active_locations, LocationName.forest_fortress_tile, None) + forest_fortress_region = create_region(world, player, active_locations, LocationName.forest_fortress_region, None) + forest_fortress = create_region(world, player, active_locations, LocationName.forest_fortress, + [LocationName.forest_fortress, LocationName.forest_reznor]) + + forest_castle_tile = create_region(world, player, active_locations, LocationName.forest_castle_tile, None) + forest_castle_region = create_region(world, player, active_locations, LocationName.forest_castle_region, None) + forest_castle = create_region(world, player, active_locations, LocationName.forest_castle, + [LocationName.forest_castle, LocationName.forest_koopaling]) + + blue_switch_palace_tile = create_region(world, player, active_locations, LocationName.blue_switch_palace_tile, None) + blue_switch_palace = create_region(world, player, active_locations, LocationName.blue_switch_palace, + [LocationName.blue_switch_palace]) + + + chocolate_island_1_tile = create_region(world, player, active_locations, LocationName.chocolate_island_1_tile, None) + chocolate_island_1_region = create_region(world, player, active_locations, LocationName.chocolate_island_1_region, None) + chocolate_island_1_exit_1 = create_region(world, player, active_locations, LocationName.chocolate_island_1_exit_1, + [LocationName.chocolate_island_1_exit_1]) + + chocolate_island_2_tile = create_region(world, player, active_locations, LocationName.chocolate_island_2_tile, None) + chocolate_island_2_region = create_region(world, player, active_locations, LocationName.chocolate_island_2_region, None) + chocolate_island_2_exit_1 = create_region(world, player, active_locations, LocationName.chocolate_island_2_exit_1, + [LocationName.chocolate_island_2_exit_1]) + chocolate_island_2_exit_2 = create_region(world, player, active_locations, LocationName.chocolate_island_2_exit_2, + [LocationName.chocolate_island_2_exit_2]) + + chocolate_island_3_tile = create_region(world, player, active_locations, LocationName.chocolate_island_3_tile, None) + chocolate_island_3_region = create_region(world, player, active_locations, LocationName.chocolate_island_3_region, None) + chocolate_island_3_exit_1 = create_region(world, player, active_locations, LocationName.chocolate_island_3_exit_1, + [LocationName.chocolate_island_3_exit_1]) + chocolate_island_3_exit_2 = create_region(world, player, active_locations, LocationName.chocolate_island_3_exit_2, + [LocationName.chocolate_island_3_exit_2]) + + chocolate_island_4_tile = create_region(world, player, active_locations, LocationName.chocolate_island_4_tile, None) + chocolate_island_4_region = create_region(world, player, active_locations, LocationName.chocolate_island_4_region, None) + chocolate_island_4_exit_1 = create_region(world, player, active_locations, LocationName.chocolate_island_4_exit_1, + [LocationName.chocolate_island_4_exit_1]) + + chocolate_island_5_tile = create_region(world, player, active_locations, LocationName.chocolate_island_5_tile, None) + chocolate_island_5_region = create_region(world, player, active_locations, LocationName.chocolate_island_5_region, None) + chocolate_island_5_exit_1 = create_region(world, player, active_locations, LocationName.chocolate_island_5_exit_1, + [LocationName.chocolate_island_5_exit_1]) + + chocolate_ghost_house_tile = create_region(world, player, active_locations, LocationName.chocolate_ghost_house_tile, None) + chocolate_ghost_house_region = create_region(world, player, active_locations, LocationName.chocolate_ghost_house_region, None) + chocolate_ghost_house_exit_1 = create_region(world, player, active_locations, LocationName.chocolate_ghost_house_exit_1, + [LocationName.chocolate_ghost_house_exit_1]) + + chocolate_secret_tile = create_region(world, player, active_locations, LocationName.chocolate_secret_tile, None) + chocolate_secret_region = create_region(world, player, active_locations, LocationName.chocolate_secret_region, None) + chocolate_secret_exit_1 = create_region(world, player, active_locations, LocationName.chocolate_secret_exit_1, + [LocationName.chocolate_secret_exit_1]) + + chocolate_fortress_tile = create_region(world, player, active_locations, LocationName.chocolate_fortress_tile, None) + chocolate_fortress_region = create_region(world, player, active_locations, LocationName.chocolate_fortress_region, None) + chocolate_fortress = create_region(world, player, active_locations, LocationName.chocolate_fortress, + [LocationName.chocolate_fortress, LocationName.chocolate_reznor]) + + chocolate_castle_tile = create_region(world, player, active_locations, LocationName.chocolate_castle_tile, None) + chocolate_castle_region = create_region(world, player, active_locations, LocationName.chocolate_castle_region, None) + chocolate_castle = create_region(world, player, active_locations, LocationName.chocolate_castle, + [LocationName.chocolate_castle, LocationName.chocolate_koopaling]) + + sunken_ghost_ship_tile = create_region(world, player, active_locations, LocationName.sunken_ghost_ship_tile, None) + sunken_ghost_ship_region = create_region(world, player, active_locations, LocationName.sunken_ghost_ship_region, None) + sunken_ghost_ship = create_region(world, player, active_locations, LocationName.sunken_ghost_ship, + [LocationName.sunken_ghost_ship]) + + + valley_of_bowser_1_tile = create_region(world, player, active_locations, LocationName.valley_of_bowser_1_tile, None) + valley_of_bowser_1_region = create_region(world, player, active_locations, LocationName.valley_of_bowser_1_region, None) + valley_of_bowser_1_exit_1 = create_region(world, player, active_locations, LocationName.valley_of_bowser_1_exit_1, + [LocationName.valley_of_bowser_1_exit_1]) + + valley_of_bowser_2_tile = create_region(world, player, active_locations, LocationName.valley_of_bowser_2_tile, None) + valley_of_bowser_2_region = create_region(world, player, active_locations, LocationName.valley_of_bowser_2_region, None) + valley_of_bowser_2_exit_1 = create_region(world, player, active_locations, LocationName.valley_of_bowser_2_exit_1, + [LocationName.valley_of_bowser_2_exit_1]) + valley_of_bowser_2_exit_2 = create_region(world, player, active_locations, LocationName.valley_of_bowser_2_exit_2, + [LocationName.valley_of_bowser_2_exit_2]) + + valley_of_bowser_3_tile = create_region(world, player, active_locations, LocationName.valley_of_bowser_3_tile, None) + valley_of_bowser_3_region = create_region(world, player, active_locations, LocationName.valley_of_bowser_3_region, None) + valley_of_bowser_3_exit_1 = create_region(world, player, active_locations, LocationName.valley_of_bowser_3_exit_1, + [LocationName.valley_of_bowser_3_exit_1]) + + valley_of_bowser_4_tile = create_region(world, player, active_locations, LocationName.valley_of_bowser_4_tile, None) + valley_of_bowser_4_region = create_region(world, player, active_locations, LocationName.valley_of_bowser_4_region, None) + valley_of_bowser_4_exit_1 = create_region(world, player, active_locations, LocationName.valley_of_bowser_4_exit_1, + [LocationName.valley_of_bowser_4_exit_1]) + valley_of_bowser_4_exit_2 = create_region(world, player, active_locations, LocationName.valley_of_bowser_4_exit_2, + [LocationName.valley_of_bowser_4_exit_2]) + + valley_ghost_house_tile = create_region(world, player, active_locations, LocationName.valley_ghost_house_tile, None) + valley_ghost_house_region = create_region(world, player, active_locations, LocationName.valley_ghost_house_region, None) + valley_ghost_house_exit_1 = create_region(world, player, active_locations, LocationName.valley_ghost_house_exit_1, + [LocationName.valley_ghost_house_exit_1]) + valley_ghost_house_exit_2 = create_region(world, player, active_locations, LocationName.valley_ghost_house_exit_2, + [LocationName.valley_ghost_house_exit_2]) + + valley_fortress_tile = create_region(world, player, active_locations, LocationName.valley_fortress_tile, None) + valley_fortress_region = create_region(world, player, active_locations, LocationName.valley_fortress_region, None) + valley_fortress = create_region(world, player, active_locations, LocationName.valley_fortress, + [LocationName.valley_fortress, LocationName.valley_reznor]) + + valley_castle_tile = create_region(world, player, active_locations, LocationName.valley_castle_tile, None) + valley_castle_region = create_region(world, player, active_locations, LocationName.valley_castle_region, None) + valley_castle = create_region(world, player, active_locations, LocationName.valley_castle, + [LocationName.valley_castle, LocationName.valley_koopaling]) + + front_door_tile = create_region(world, player, active_locations, LocationName.front_door_tile, None) + front_door_region = create_region(world, player, active_locations, LocationName.front_door, None) + back_door_tile = create_region(world, player, active_locations, LocationName.back_door_tile, None) + back_door_region = create_region(world, player, active_locations, LocationName.back_door, None) + bowser_region_locations = [] + if world.goal[player] == "bowser": + bowser_region_locations += [LocationName.bowser] + bowser_region = create_region(world, player, active_locations, LocationName.bowser_region, bowser_region_locations) + + + donut_plains_star_road = create_region(world, player, active_locations, LocationName.donut_plains_star_road, None) + vanilla_dome_star_road = create_region(world, player, active_locations, LocationName.vanilla_dome_star_road, None) + twin_bridges_star_road = create_region(world, player, active_locations, LocationName.twin_bridges_star_road, None) + forest_star_road = create_region(world, player, active_locations, LocationName.forest_star_road, None) + valley_star_road = create_region(world, player, active_locations, LocationName.valley_star_road, None) + star_road_donut = create_region(world, player, active_locations, LocationName.star_road_donut, None) + star_road_vanilla = create_region(world, player, active_locations, LocationName.star_road_vanilla, None) + star_road_twin_bridges = create_region(world, player, active_locations, LocationName.star_road_twin_bridges, None) + star_road_forest = create_region(world, player, active_locations, LocationName.star_road_forest, None) + star_road_valley = create_region(world, player, active_locations, LocationName.star_road_valley, None) + star_road_special = create_region(world, player, active_locations, LocationName.star_road_special, None) + special_star_road = create_region(world, player, active_locations, LocationName.special_star_road, None) + + star_road_1_tile = create_region(world, player, active_locations, LocationName.star_road_1_tile, None) + star_road_1_region = create_region(world, player, active_locations, LocationName.star_road_1_region, None) + star_road_1_exit_1 = create_region(world, player, active_locations, LocationName.star_road_1_exit_1, + [LocationName.star_road_1_exit_1]) + star_road_1_exit_2 = create_region(world, player, active_locations, LocationName.star_road_1_exit_2, + [LocationName.star_road_1_exit_2]) + + star_road_2_tile = create_region(world, player, active_locations, LocationName.star_road_2_tile, None) + star_road_2_region = create_region(world, player, active_locations, LocationName.star_road_2_region, None) + star_road_2_exit_1 = create_region(world, player, active_locations, LocationName.star_road_2_exit_1, + [LocationName.star_road_2_exit_1]) + star_road_2_exit_2 = create_region(world, player, active_locations, LocationName.star_road_2_exit_2, + [LocationName.star_road_2_exit_2]) + + star_road_3_tile = create_region(world, player, active_locations, LocationName.star_road_3_tile, None) + star_road_3_region = create_region(world, player, active_locations, LocationName.star_road_3_region, None) + star_road_3_exit_1 = create_region(world, player, active_locations, LocationName.star_road_3_exit_1, + [LocationName.star_road_3_exit_1]) + star_road_3_exit_2 = create_region(world, player, active_locations, LocationName.star_road_3_exit_2, + [LocationName.star_road_3_exit_2]) + + star_road_4_tile = create_region(world, player, active_locations, LocationName.star_road_4_tile, None) + star_road_4_region = create_region(world, player, active_locations, LocationName.star_road_4_region, None) + star_road_4_exit_1 = create_region(world, player, active_locations, LocationName.star_road_4_exit_1, + [LocationName.star_road_4_exit_1]) + star_road_4_exit_2 = create_region(world, player, active_locations, LocationName.star_road_4_exit_2, + [LocationName.star_road_4_exit_2]) + + star_road_5_tile = create_region(world, player, active_locations, LocationName.star_road_5_tile, None) + star_road_5_region = create_region(world, player, active_locations, LocationName.star_road_5_region, None) + star_road_5_exit_1 = create_region(world, player, active_locations, LocationName.star_road_5_exit_1, + [LocationName.star_road_5_exit_1]) + star_road_5_exit_2 = create_region(world, player, active_locations, LocationName.star_road_5_exit_2, + [LocationName.star_road_5_exit_2]) + + + special_zone_1_tile = create_region(world, player, active_locations, LocationName.special_zone_1_tile, None) + special_zone_1_region = create_region(world, player, active_locations, LocationName.special_zone_1_region, None) + special_zone_1_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_1_exit_1, + [LocationName.special_zone_1_exit_1]) + + special_zone_2_tile = create_region(world, player, active_locations, LocationName.special_zone_2_tile, None) + special_zone_2_region = create_region(world, player, active_locations, LocationName.special_zone_2_region, None) + special_zone_2_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_2_exit_1, + [LocationName.special_zone_2_exit_1]) + + special_zone_3_tile = create_region(world, player, active_locations, LocationName.special_zone_3_tile, None) + special_zone_3_region = create_region(world, player, active_locations, LocationName.special_zone_3_region, None) + special_zone_3_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_3_exit_1, + [LocationName.special_zone_3_exit_1]) + + special_zone_4_tile = create_region(world, player, active_locations, LocationName.special_zone_4_tile, None) + special_zone_4_region = create_region(world, player, active_locations, LocationName.special_zone_4_region, None) + special_zone_4_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_4_exit_1, + [LocationName.special_zone_4_exit_1]) + + special_zone_5_tile = create_region(world, player, active_locations, LocationName.special_zone_5_tile, None) + special_zone_5_region = create_region(world, player, active_locations, LocationName.special_zone_5_region, None) + special_zone_5_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_5_exit_1, + [LocationName.special_zone_5_exit_1]) + + special_zone_6_tile = create_region(world, player, active_locations, LocationName.special_zone_6_tile, None) + special_zone_6_region = create_region(world, player, active_locations, LocationName.special_zone_6_region, None) + special_zone_6_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_6_exit_1, + [LocationName.special_zone_6_exit_1]) + + special_zone_7_tile = create_region(world, player, active_locations, LocationName.special_zone_7_tile, None) + special_zone_7_region = create_region(world, player, active_locations, LocationName.special_zone_7_region, None) + special_zone_7_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_7_exit_1, + [LocationName.special_zone_7_exit_1]) + + special_zone_8_tile = create_region(world, player, active_locations, LocationName.special_zone_8_tile, None) + special_zone_8_region = create_region(world, player, active_locations, LocationName.special_zone_8_region, None) + special_zone_8_exit_1 = create_region(world, player, active_locations, LocationName.special_zone_8_exit_1, + [LocationName.special_zone_8_exit_1]) + special_complete = create_region(world, player, active_locations, LocationName.special_complete, None) + + + # Set up the regions correctly. + world.regions += [ + menu_region, + yoshis_island_region, + donut_plains_region, + vanilla_dome_region, + twin_bridges_region, + forest_of_illusion_region, + chocolate_island_region, + valley_of_bowser_region, + star_road_region, + special_zone_region, + yoshis_house_tile, + yoshis_house_region, + yoshis_island_1_tile, + yoshis_island_1_region, + yoshis_island_1_exit_1, + yoshis_island_2_tile, + yoshis_island_2_region, + yoshis_island_2_exit_1, + yoshis_island_3_tile, + yoshis_island_3_region, + yoshis_island_3_exit_1, + yoshis_island_4_tile, + yoshis_island_4_region, + yoshis_island_4_exit_1, + yoshis_island_castle_tile, + yoshis_island_castle_region, + yoshis_island_castle, + yellow_switch_palace_tile, + yellow_switch_palace, + donut_plains_1_tile, + donut_plains_1_region, + donut_plains_1_exit_1, + donut_plains_1_exit_2, + donut_plains_2_tile, + donut_plains_2_region, + donut_plains_2_exit_1, + donut_plains_2_exit_2, + donut_plains_3_tile, + donut_plains_3_region, + donut_plains_3_exit_1, + donut_plains_4_tile, + donut_plains_4_region, + donut_plains_4_exit_1, + donut_secret_1_tile, + donut_secret_1_region, + donut_secret_1_exit_1, + donut_secret_1_exit_2, + donut_secret_2_tile, + donut_secret_2_region, + donut_secret_2_exit_1, + donut_ghost_house_tile, + donut_ghost_house_region, + donut_ghost_house_exit_1, + donut_ghost_house_exit_2, + donut_secret_house_tile, + donut_secret_house_region, + donut_secret_house_exit_1, + donut_secret_house_exit_2, + donut_plains_castle_tile, + donut_plains_castle_region, + donut_plains_castle, + green_switch_palace_tile, + green_switch_palace, + donut_plains_top_secret_tile, + donut_plains_top_secret, + vanilla_dome_1_tile, + vanilla_dome_1_region, + vanilla_dome_1_exit_1, + vanilla_dome_1_exit_2, + vanilla_dome_2_tile, + vanilla_dome_2_region, + vanilla_dome_2_exit_1, + vanilla_dome_2_exit_2, + vanilla_dome_3_tile, + vanilla_dome_3_region, + vanilla_dome_3_exit_1, + vanilla_dome_4_tile, + vanilla_dome_4_region, + vanilla_dome_4_exit_1, + vanilla_secret_1_tile, + vanilla_secret_1_region, + vanilla_secret_1_exit_1, + vanilla_secret_1_exit_2, + vanilla_secret_2_tile, + vanilla_secret_2_region, + vanilla_secret_2_exit_1, + vanilla_secret_3_tile, + vanilla_secret_3_region, + vanilla_secret_3_exit_1, + vanilla_ghost_house_tile, + vanilla_ghost_house_region, + vanilla_ghost_house_exit_1, + vanilla_fortress_tile, + vanilla_fortress_region, + vanilla_fortress, + vanilla_dome_castle_tile, + vanilla_dome_castle_region, + vanilla_dome_castle, + red_switch_palace_tile, + red_switch_palace, + butter_bridge_1_tile, + butter_bridge_1_region, + butter_bridge_1_exit_1, + butter_bridge_2_tile, + butter_bridge_2_region, + butter_bridge_2_exit_1, + cheese_bridge_tile, + cheese_bridge_region, + cheese_bridge_exit_1, + cheese_bridge_exit_2, + cookie_mountain_tile, + cookie_mountain_region, + cookie_mountain_exit_1, + soda_lake_tile, + soda_lake_region, + soda_lake_exit_1, + twin_bridges_castle_tile, + twin_bridges_castle_region, + twin_bridges_castle, + forest_of_illusion_1_tile, + forest_of_illusion_1_region, + forest_of_illusion_1_exit_1, + forest_of_illusion_1_exit_2, + forest_of_illusion_2_tile, + forest_of_illusion_2_region, + forest_of_illusion_2_exit_1, + forest_of_illusion_2_exit_2, + forest_of_illusion_3_tile, + forest_of_illusion_3_region, + forest_of_illusion_3_exit_1, + forest_of_illusion_3_exit_2, + forest_of_illusion_4_tile, + forest_of_illusion_4_region, + forest_of_illusion_4_exit_1, + forest_of_illusion_4_exit_2, + forest_ghost_house_tile, + forest_ghost_house_region, + forest_ghost_house_exit_1, + forest_ghost_house_exit_2, + forest_secret_tile, + forest_secret_region, + forest_secret_exit_1, + forest_fortress_tile, + forest_fortress_region, + forest_fortress, + forest_castle_tile, + forest_castle_region, + forest_castle, + blue_switch_palace_tile, + blue_switch_palace, + chocolate_island_1_tile, + chocolate_island_1_region, + chocolate_island_1_exit_1, + chocolate_island_2_tile, + chocolate_island_2_region, + chocolate_island_2_exit_1, + chocolate_island_2_exit_2, + chocolate_island_3_tile, + chocolate_island_3_region, + chocolate_island_3_exit_1, + chocolate_island_3_exit_2, + chocolate_island_4_tile, + chocolate_island_4_region, + chocolate_island_4_exit_1, + chocolate_island_5_tile, + chocolate_island_5_region, + chocolate_island_5_exit_1, + chocolate_ghost_house_tile, + chocolate_ghost_house_region, + chocolate_ghost_house_exit_1, + chocolate_secret_tile, + chocolate_secret_region, + chocolate_secret_exit_1, + chocolate_fortress_tile, + chocolate_fortress_region, + chocolate_fortress, + chocolate_castle_tile, + chocolate_castle_region, + chocolate_castle, + sunken_ghost_ship_tile, + sunken_ghost_ship_region, + sunken_ghost_ship, + valley_of_bowser_1_tile, + valley_of_bowser_1_region, + valley_of_bowser_1_exit_1, + valley_of_bowser_2_tile, + valley_of_bowser_2_region, + valley_of_bowser_2_exit_1, + valley_of_bowser_2_exit_2, + valley_of_bowser_3_tile, + valley_of_bowser_3_region, + valley_of_bowser_3_exit_1, + valley_of_bowser_4_tile, + valley_of_bowser_4_region, + valley_of_bowser_4_exit_1, + valley_of_bowser_4_exit_2, + valley_ghost_house_tile, + valley_ghost_house_region, + valley_ghost_house_exit_1, + valley_ghost_house_exit_2, + valley_fortress_tile, + valley_fortress_region, + valley_fortress, + valley_castle_tile, + valley_castle_region, + valley_castle, + front_door_tile, + front_door_region, + back_door_tile, + back_door_region, + bowser_region, + donut_plains_star_road, + vanilla_dome_star_road, + twin_bridges_star_road, + forest_star_road, + valley_star_road, + star_road_donut, + star_road_vanilla, + star_road_twin_bridges, + star_road_forest, + star_road_valley, + star_road_special, + special_star_road, + star_road_1_tile, + star_road_1_region, + star_road_1_exit_1, + star_road_1_exit_2, + star_road_2_tile, + star_road_2_region, + star_road_2_exit_1, + star_road_2_exit_2, + star_road_3_tile, + star_road_3_region, + star_road_3_exit_1, + star_road_3_exit_2, + star_road_4_tile, + star_road_4_region, + star_road_4_exit_1, + star_road_4_exit_2, + star_road_5_tile, + star_road_5_region, + star_road_5_exit_1, + star_road_5_exit_2, + special_zone_1_tile, + special_zone_1_region, + special_zone_1_exit_1, + special_zone_2_tile, + special_zone_2_region, + special_zone_2_exit_1, + special_zone_3_tile, + special_zone_3_region, + special_zone_3_exit_1, + special_zone_4_tile, + special_zone_4_region, + special_zone_4_exit_1, + special_zone_5_tile, + special_zone_5_region, + special_zone_5_exit_1, + special_zone_6_tile, + special_zone_6_region, + special_zone_6_exit_1, + special_zone_7_tile, + special_zone_7_region, + special_zone_7_exit_1, + special_zone_8_tile, + special_zone_8_region, + special_zone_8_exit_1, + special_complete, + ] + + + if world.dragon_coin_checks[player]: + add_location_to_region(world, player, active_locations, LocationName.yoshis_island_1_region, LocationName.yoshis_island_1_dragon, + lambda state: (state.has(ItemName.mario_spin_jump, player) and + state.has(ItemName.progressive_powerup, player, 1))) + add_location_to_region(world, player, active_locations, LocationName.yoshis_island_2_region, LocationName.yoshis_island_2_dragon, + lambda state: (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.mario_climb, player))) + add_location_to_region(world, player, active_locations, LocationName.yoshis_island_3_region, LocationName.yoshis_island_3_dragon, + lambda state: state.has(ItemName.p_switch, player)) + add_location_to_region(world, player, active_locations, LocationName.yoshis_island_4_region, LocationName.yoshis_island_4_dragon, + lambda state: (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.mario_swim, player) or + (state.has(ItemName.mario_carry, player) and state.has(ItemName.p_switch, player)))) + add_location_to_region(world, player, active_locations, LocationName.donut_plains_1_region, LocationName.donut_plains_1_dragon, + lambda state: (state.has(ItemName.mario_climb, player) or + state.has(ItemName.yoshi_activate, player) or + (state.has(ItemName.progressive_powerup, player, 3) and state.has(ItemName.mario_run, player)))) + add_location_to_region(world, player, active_locations, LocationName.donut_plains_2_region, LocationName.donut_plains_2_dragon) + add_location_to_region(world, player, active_locations, LocationName.donut_plains_3_region, LocationName.donut_plains_3_dragon, + lambda state: ((state.has(ItemName.mario_spin_jump, player) and state.has(ItemName.progressive_powerup, player, 1) and state.has(ItemName.mario_climb, player) or + state.has(ItemName.yoshi_activate, player) or + (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3))))) + add_location_to_region(world, player, active_locations, LocationName.donut_plains_4_region, LocationName.donut_plains_4_dragon) + add_location_to_region(world, player, active_locations, LocationName.donut_secret_1_region, LocationName.donut_secret_1_dragon, + lambda state: state.has(ItemName.mario_swim, player)) + add_location_to_region(world, player, active_locations, LocationName.donut_secret_2_region, LocationName.donut_secret_2_dragon, + lambda state: (state.has(ItemName.mario_climb, player) or state.has(ItemName.yoshi_activate, player))) + add_location_to_region(world, player, active_locations, LocationName.vanilla_dome_1_region, LocationName.vanilla_dome_1_dragon, + lambda state: (state.has(ItemName.mario_carry, player) and + state.has(ItemName.mario_run, player) and + (state.has(ItemName.super_star_active, player) or + state.has(ItemName.progressive_powerup, player, 1)))) + add_location_to_region(world, player, active_locations, LocationName.vanilla_dome_2_region, LocationName.vanilla_dome_2_dragon, + lambda state: (state.has(ItemName.mario_swim, player) and + state.has(ItemName.p_switch, player) and + (state.has(ItemName.mario_climb, player) or state.has(ItemName.yoshi_activate, player)))) + add_location_to_region(world, player, active_locations, LocationName.vanilla_dome_3_region, LocationName.vanilla_dome_3_dragon) + add_location_to_region(world, player, active_locations, LocationName.vanilla_dome_4_region, LocationName.vanilla_dome_4_dragon) + add_location_to_region(world, player, active_locations, LocationName.vanilla_secret_1_region, LocationName.vanilla_secret_1_dragon, + lambda state: (state.has(ItemName.mario_climb, player) and + state.has(ItemName.mario_carry, player))) + add_location_to_region(world, player, active_locations, LocationName.vanilla_secret_2_region, LocationName.vanilla_secret_2_dragon, + lambda state: (state.has(ItemName.mario_run, player) and + state.has(ItemName.progressive_powerup, player, 3))) + add_location_to_region(world, player, active_locations, LocationName.vanilla_secret_3_region, LocationName.vanilla_secret_3_dragon, + lambda state: state.has(ItemName.mario_swim, player)) + add_location_to_region(world, player, active_locations, LocationName.vanilla_ghost_house_region, LocationName.vanilla_ghost_house_dragon, + lambda state: state.has(ItemName.mario_climb, player)) + add_location_to_region(world, player, active_locations, LocationName.butter_bridge_1_region, LocationName.butter_bridge_1_dragon) + add_location_to_region(world, player, active_locations, LocationName.butter_bridge_2_region, LocationName.butter_bridge_2_dragon, + lambda state: (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.progressive_powerup, player, 3))) + add_location_to_region(world, player, active_locations, LocationName.cheese_bridge_region, LocationName.cheese_bridge_dragon, + lambda state: (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.mario_climb, player))) + add_location_to_region(world, player, active_locations, LocationName.cookie_mountain_region, LocationName.cookie_mountain_dragon, + lambda state: (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.mario_climb, player))) + add_location_to_region(world, player, active_locations, LocationName.soda_lake_region, LocationName.soda_lake_dragon, + lambda state: state.has(ItemName.mario_swim, player)) + add_location_to_region(world, player, active_locations, LocationName.forest_of_illusion_2_region, LocationName.forest_of_illusion_2_dragon, + lambda state: state.has(ItemName.mario_swim, player)) + add_location_to_region(world, player, active_locations, LocationName.forest_of_illusion_3_region, LocationName.forest_of_illusion_3_dragon, + lambda state: (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.mario_carry, player))) + add_location_to_region(world, player, active_locations, LocationName.forest_of_illusion_4_region, LocationName.forest_of_illusion_4_dragon, + lambda state: (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.mario_carry, player) or + state.has(ItemName.p_switch, player) or + state.has(ItemName.progressive_powerup, player, 2))) + add_location_to_region(world, player, active_locations, LocationName.forest_ghost_house_region, LocationName.forest_ghost_house_dragon, + lambda state: state.has(ItemName.p_switch, player)) + add_location_to_region(world, player, active_locations, LocationName.forest_secret_region, LocationName.forest_secret_dragon) + add_location_to_region(world, player, active_locations, LocationName.forest_castle_region, LocationName.forest_castle_dragon) + add_location_to_region(world, player, active_locations, LocationName.chocolate_island_1_region, LocationName.chocolate_island_1_dragon, + lambda state: state.has(ItemName.mario_swim, player)) + add_location_to_region(world, player, active_locations, LocationName.chocolate_island_2_region, LocationName.chocolate_island_2_dragon, + lambda state: (state.has(ItemName.blue_switch_palace, player) and + (state.has(ItemName.p_switch, player) or + state.has(ItemName.green_switch_palace, player) or + (state.has(ItemName.yellow_switch_palace, player) or state.has(ItemName.red_switch_palace, player))))) + add_location_to_region(world, player, active_locations, LocationName.chocolate_island_3_region, LocationName.chocolate_island_3_dragon) + add_location_to_region(world, player, active_locations, LocationName.chocolate_island_4_region, LocationName.chocolate_island_4_dragon, + lambda state: (state.has(ItemName.mario_run, player) and + state.has(ItemName.progressive_powerup, player, 3))) + add_location_to_region(world, player, active_locations, LocationName.chocolate_island_5_region, LocationName.chocolate_island_5_dragon, + lambda state: (state.has(ItemName.mario_swim, player) or + (state.has(ItemName.mario_carry, player) and state.has(ItemName.p_switch, player)))) + add_location_to_region(world, player, active_locations, LocationName.sunken_ghost_ship_region, LocationName.sunken_ghost_ship_dragon, + lambda state: (state.has(ItemName.mario_swim, player) and + state.has(ItemName.super_star_active, player) and + state.has(ItemName.progressive_powerup, player, 3))) + add_location_to_region(world, player, active_locations, LocationName.valley_of_bowser_1_region, LocationName.valley_of_bowser_1_dragon) + add_location_to_region(world, player, active_locations, LocationName.valley_of_bowser_2_region, LocationName.valley_of_bowser_2_dragon) + add_location_to_region(world, player, active_locations, LocationName.valley_of_bowser_3_region, LocationName.valley_of_bowser_3_dragon) + add_location_to_region(world, player, active_locations, LocationName.valley_ghost_house_region, LocationName.valley_ghost_house_dragon, + lambda state: state.has(ItemName.p_switch, player)) + add_location_to_region(world, player, active_locations, LocationName.valley_castle_region, LocationName.valley_castle_dragon) + add_location_to_region(world, player, active_locations, LocationName.star_road_1_region, LocationName.star_road_1_dragon, + lambda state: (state.has(ItemName.mario_spin_jump, player) and + state.has(ItemName.progressive_powerup, player, 1))) + add_location_to_region(world, player, active_locations, LocationName.special_zone_1_region, LocationName.special_zone_1_dragon, + lambda state: state.has(ItemName.mario_climb, player)) + add_location_to_region(world, player, active_locations, LocationName.special_zone_2_region, LocationName.special_zone_2_dragon, + lambda state: state.has(ItemName.p_balloon, player)) + add_location_to_region(world, player, active_locations, LocationName.special_zone_3_region, LocationName.special_zone_3_dragon, + lambda state: state.has(ItemName.yoshi_activate, player)) + add_location_to_region(world, player, active_locations, LocationName.special_zone_4_region, LocationName.special_zone_4_dragon, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + add_location_to_region(world, player, active_locations, LocationName.special_zone_5_region, LocationName.special_zone_5_dragon, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + add_location_to_region(world, player, active_locations, LocationName.special_zone_6_region, LocationName.special_zone_6_dragon, + lambda state: state.has(ItemName.mario_swim, player)) + add_location_to_region(world, player, active_locations, LocationName.special_zone_7_region, LocationName.special_zone_7_dragon, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + add_location_to_region(world, player, active_locations, LocationName.special_zone_8_region, LocationName.special_zone_8_dragon, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + + + +def connect_regions(world, player, level_to_tile_dict): + names: typing.Dict[str, int] = {} + + connect(world, player, names, "Menu", LocationName.yoshis_island_region) + connect(world, player, names, LocationName.yoshis_island_region, LocationName.yoshis_island_1_tile) + connect(world, player, names, LocationName.yoshis_island_region, LocationName.yoshis_island_2_tile) + + # Connect regions within levels using rules + connect(world, player, names, LocationName.yoshis_island_1_region, LocationName.yoshis_island_1_exit_1) + connect(world, player, names, LocationName.yoshis_island_2_region, LocationName.yoshis_island_2_exit_1) + connect(world, player, names, LocationName.yoshis_island_3_region, LocationName.yoshis_island_3_exit_1) + connect(world, player, names, LocationName.yoshis_island_4_region, LocationName.yoshis_island_4_exit_1) + connect(world, player, names, LocationName.yoshis_island_castle_region, LocationName.yoshis_island_castle, + lambda state: (state.has(ItemName.mario_climb, player))) + + connect(world, player, names, LocationName.donut_plains_1_region, LocationName.donut_plains_1_exit_1) + connect(world, player, names, LocationName.donut_plains_1_region, LocationName.donut_plains_1_exit_2, + lambda state: (state.has(ItemName.mario_carry, player) and + (state.has(ItemName.yoshi_activate, player) or + state.has(ItemName.green_switch_palace, player) or + (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3))))) + connect(world, player, names, LocationName.donut_plains_2_region, LocationName.donut_plains_2_exit_1) + connect(world, player, names, LocationName.donut_plains_2_region, LocationName.donut_plains_2_exit_2, + lambda state: (state.has(ItemName.mario_carry, player) and + (state.has(ItemName.yoshi_activate, player) or + (state.has(ItemName.mario_spin_jump, player) and state.has(ItemName.mario_climb, player) and state.has(ItemName.progressive_powerup, player, 1))))) + connect(world, player, names, LocationName.donut_secret_1_region, LocationName.donut_secret_1_exit_1, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.donut_secret_1_region, LocationName.donut_secret_1_exit_2, + lambda state: (state.has(ItemName.mario_carry, player) and + state.has(ItemName.mario_swim, player) and + state.has(ItemName.p_switch, player))) + connect(world, player, names, LocationName.donut_ghost_house_region, LocationName.donut_ghost_house_exit_1, + lambda state: (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3))) + connect(world, player, names, LocationName.donut_ghost_house_region, LocationName.donut_ghost_house_exit_2, + lambda state: (state.has(ItemName.mario_climb, player) or + (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3)))) + connect(world, player, names, LocationName.donut_secret_house_region, LocationName.donut_secret_house_exit_1, + lambda state: state.has(ItemName.p_switch, player)) + connect(world, player, names, LocationName.donut_secret_house_region, LocationName.donut_secret_house_exit_2, + lambda state: (state.has(ItemName.p_switch, player) and state.has(ItemName.mario_carry, player) and + (state.has(ItemName.mario_climb, player) or + (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3))))) + connect(world, player, names, LocationName.donut_plains_3_region, LocationName.donut_plains_3_exit_1) + connect(world, player, names, LocationName.donut_plains_4_region, LocationName.donut_plains_4_exit_1) + connect(world, player, names, LocationName.donut_secret_2_region, LocationName.donut_secret_2_exit_1) + connect(world, player, names, LocationName.donut_plains_castle_region, LocationName.donut_plains_castle) + + connect(world, player, names, LocationName.vanilla_dome_1_region, LocationName.vanilla_dome_1_exit_1, + lambda state: (state.has(ItemName.mario_run, player) and + (state.has(ItemName.super_star_active, player) or + state.has(ItemName.progressive_powerup, player, 1)))) + connect(world, player, names, LocationName.vanilla_dome_1_region, LocationName.vanilla_dome_1_exit_2, + lambda state: (state.has(ItemName.mario_carry, player) and + ((state.has(ItemName.yoshi_activate, player) and state.has(ItemName.mario_climb, player)) or + (state.has(ItemName.yoshi_activate, player) and state.has(ItemName.red_switch_palace, player)) or + (state.has(ItemName.red_switch_palace, player) and state.has(ItemName.mario_climb, player))))) + connect(world, player, names, LocationName.vanilla_dome_2_region, LocationName.vanilla_dome_2_exit_1, + lambda state: (state.has(ItemName.mario_swim, player) and + (state.has(ItemName.mario_climb, player) or state.has(ItemName.yoshi_activate, player)))) + connect(world, player, names, LocationName.vanilla_dome_2_region, LocationName.vanilla_dome_2_exit_2, + lambda state: (state.has(ItemName.mario_swim, player) and + state.has(ItemName.p_switch, player) and + state.has(ItemName.mario_carry, player) and + (state.has(ItemName.mario_climb, player) or state.has(ItemName.yoshi_activate, player)))) + connect(world, player, names, LocationName.vanilla_secret_1_region, LocationName.vanilla_secret_1_exit_1, + lambda state: state.has(ItemName.mario_climb, player)) + connect(world, player, names, LocationName.vanilla_secret_1_region, LocationName.vanilla_secret_1_exit_2, + lambda state: (state.has(ItemName.mario_climb, player) and + (state.has(ItemName.mario_carry, player) and state.has(ItemName.blue_switch_palace, player)))) + connect(world, player, names, LocationName.vanilla_ghost_house_region, LocationName.vanilla_ghost_house_exit_1, + lambda state: state.has(ItemName.p_switch, player)) + connect(world, player, names, LocationName.vanilla_dome_3_region, LocationName.vanilla_dome_3_exit_1) + connect(world, player, names, LocationName.vanilla_dome_4_region, LocationName.vanilla_dome_4_exit_1) + connect(world, player, names, LocationName.vanilla_secret_2_region, LocationName.vanilla_secret_2_exit_1) + connect(world, player, names, LocationName.vanilla_secret_3_region, LocationName.vanilla_secret_3_exit_1, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.vanilla_fortress_region, LocationName.vanilla_fortress, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.vanilla_dome_castle_region, LocationName.vanilla_dome_castle) + + connect(world, player, names, LocationName.butter_bridge_1_region, LocationName.butter_bridge_1_exit_1) + connect(world, player, names, LocationName.butter_bridge_2_region, LocationName.butter_bridge_2_exit_1) + connect(world, player, names, LocationName.cheese_bridge_region, LocationName.cheese_bridge_exit_1, + lambda state: state.has(ItemName.mario_climb, player)) + connect(world, player, names, LocationName.cheese_bridge_region, LocationName.cheese_bridge_exit_2, + lambda state: (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3))) + connect(world, player, names, LocationName.soda_lake_region, LocationName.soda_lake_exit_1, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.cookie_mountain_region, LocationName.cookie_mountain_exit_1) + connect(world, player, names, LocationName.twin_bridges_castle_region, LocationName.twin_bridges_castle, + lambda state: (state.has(ItemName.mario_run, player) and + state.has(ItemName.mario_climb, player))) + + connect(world, player, names, LocationName.forest_of_illusion_1_region, LocationName.forest_of_illusion_1_exit_1) + connect(world, player, names, LocationName.forest_of_illusion_1_region, LocationName.forest_of_illusion_1_exit_2, + lambda state: (state.has(ItemName.mario_carry, player) and + state.has(ItemName.p_balloon, player))) + connect(world, player, names, LocationName.forest_of_illusion_2_region, LocationName.forest_of_illusion_2_exit_1, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.forest_of_illusion_2_region, LocationName.forest_of_illusion_2_exit_2, + lambda state: (state.has(ItemName.mario_swim, player) and + state.has(ItemName.mario_carry, player))) + connect(world, player, names, LocationName.forest_of_illusion_3_region, LocationName.forest_of_illusion_3_exit_1, + lambda state: (state.has(ItemName.mario_carry, player) or + state.has(ItemName.yoshi_activate, player))) + connect(world, player, names, LocationName.forest_of_illusion_3_region, LocationName.forest_of_illusion_3_exit_2, + lambda state: (state.has(ItemName.mario_swim, player) and + state.has(ItemName.mario_carry, player) and + state.has(ItemName.progressive_powerup, player, 1))) + connect(world, player, names, LocationName.forest_of_illusion_4_region, LocationName.forest_of_illusion_4_exit_1) + connect(world, player, names, LocationName.forest_of_illusion_4_region, LocationName.forest_of_illusion_4_exit_2, + lambda state: state.has(ItemName.mario_carry, player)) + connect(world, player, names, LocationName.forest_ghost_house_region, LocationName.forest_ghost_house_exit_1, + lambda state: state.has(ItemName.p_switch, player)) + connect(world, player, names, LocationName.forest_ghost_house_region, LocationName.forest_ghost_house_exit_2, + lambda state: state.has(ItemName.p_switch, player)) + connect(world, player, names, LocationName.forest_secret_region, LocationName.forest_secret_exit_1) + connect(world, player, names, LocationName.forest_fortress_region, LocationName.forest_fortress) + connect(world, player, names, LocationName.forest_castle_region, LocationName.forest_castle) + + connect(world, player, names, LocationName.chocolate_island_1_region, LocationName.chocolate_island_1_exit_1, + lambda state: state.has(ItemName.p_switch, player)) + connect(world, player, names, LocationName.chocolate_island_2_region, LocationName.chocolate_island_2_exit_1) + connect(world, player, names, LocationName.chocolate_island_2_region, LocationName.chocolate_island_2_exit_2, + lambda state: state.has(ItemName.mario_carry, player)) + connect(world, player, names, LocationName.chocolate_island_3_region, LocationName.chocolate_island_3_exit_1, + lambda state: (state.has(ItemName.mario_climb, player) or + (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3)))) + connect(world, player, names, LocationName.chocolate_island_3_region, LocationName.chocolate_island_3_exit_2, + lambda state: (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3))) + connect(world, player, names, LocationName.chocolate_island_4_region, LocationName.chocolate_island_4_exit_1) + connect(world, player, names, LocationName.chocolate_island_5_region, LocationName.chocolate_island_5_exit_1) + connect(world, player, names, LocationName.chocolate_ghost_house_region, LocationName.chocolate_ghost_house_exit_1) + connect(world, player, names, LocationName.chocolate_fortress_region, LocationName.chocolate_fortress) + connect(world, player, names, LocationName.chocolate_secret_region, LocationName.chocolate_secret_exit_1, + lambda state: state.has(ItemName.mario_run, player)) + connect(world, player, names, LocationName.chocolate_castle_region, LocationName.chocolate_castle, + lambda state: (state.has(ItemName.progressive_powerup, player, 1))) + + connect(world, player, names, LocationName.sunken_ghost_ship_region, LocationName.sunken_ghost_ship, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.valley_of_bowser_1_region, LocationName.valley_of_bowser_1_exit_1) + connect(world, player, names, LocationName.valley_of_bowser_2_region, LocationName.valley_of_bowser_2_exit_1) + connect(world, player, names, LocationName.valley_of_bowser_2_region, LocationName.valley_of_bowser_2_exit_2, + lambda state: state.has(ItemName.mario_carry, player)) + connect(world, player, names, LocationName.valley_of_bowser_3_region, LocationName.valley_of_bowser_3_exit_1) + connect(world, player, names, LocationName.valley_of_bowser_4_region, LocationName.valley_of_bowser_4_exit_1, + lambda state: state.has(ItemName.mario_climb, player)) + connect(world, player, names, LocationName.valley_of_bowser_4_region, LocationName.valley_of_bowser_4_exit_2, + lambda state: (state.has(ItemName.mario_climb, player) and + state.has(ItemName.mario_carry, player) and + state.has(ItemName.yoshi_activate, player))) + connect(world, player, names, LocationName.valley_ghost_house_region, LocationName.valley_ghost_house_exit_1, + lambda state: state.has(ItemName.p_switch, player)) + connect(world, player, names, LocationName.valley_ghost_house_region, LocationName.valley_ghost_house_exit_2, + lambda state: (state.has(ItemName.p_switch, player) and + state.has(ItemName.mario_carry, player) and + state.has(ItemName.mario_run, player))) + connect(world, player, names, LocationName.valley_fortress_region, LocationName.valley_fortress, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + connect(world, player, names, LocationName.valley_castle_region, LocationName.valley_castle) + connect(world, player, names, LocationName.front_door, LocationName.bowser_region, + lambda state: (state.has(ItemName.mario_climb, player) and + state.has(ItemName.mario_run, player) and + state.has(ItemName.mario_swim, player) and + state.has(ItemName.progressive_powerup, player, 1) and + state.has(ItemName.koopaling, player, world.bosses_required[player].value))) + connect(world, player, names, LocationName.back_door, LocationName.bowser_region, + lambda state: state.has(ItemName.koopaling, player, world.bosses_required[player].value)) + + connect(world, player, names, LocationName.star_road_1_region, LocationName.star_road_1_exit_1, + lambda state: (state.has(ItemName.mario_spin_jump, player) and + state.has(ItemName.progressive_powerup, player, 1))) + connect(world, player, names, LocationName.star_road_1_region, LocationName.star_road_1_exit_2, + lambda state: (state.has(ItemName.mario_spin_jump, player) and + state.has(ItemName.mario_carry, player) and + state.has(ItemName.progressive_powerup, player, 1))) + connect(world, player, names, LocationName.star_road_2_region, LocationName.star_road_2_exit_1, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.star_road_2_region, LocationName.star_road_2_exit_2, + lambda state: (state.has(ItemName.mario_swim, player) and + state.has(ItemName.mario_carry, player))) + connect(world, player, names, LocationName.star_road_3_region, LocationName.star_road_3_exit_1) + connect(world, player, names, LocationName.star_road_3_region, LocationName.star_road_3_exit_2, + lambda state: state.has(ItemName.mario_carry, player)) + connect(world, player, names, LocationName.star_road_4_region, LocationName.star_road_4_exit_1) + connect(world, player, names, LocationName.star_road_4_region, LocationName.star_road_4_exit_2, + lambda state: (state.has(ItemName.mario_carry, player) and + (state.has(ItemName.yoshi_activate, player) or + (state.has(ItemName.green_switch_palace, player) and state.has(ItemName.red_switch_palace, player))))) + connect(world, player, names, LocationName.star_road_5_region, LocationName.star_road_5_exit_1, + lambda state: state.has(ItemName.p_switch, player)) + connect(world, player, names, LocationName.star_road_5_region, LocationName.star_road_5_exit_2, + lambda state: (state.has(ItemName.mario_carry, player) and + state.has(ItemName.mario_climb, player) and + state.has(ItemName.p_switch, player) and + state.has(ItemName.yellow_switch_palace, player) and + state.has(ItemName.green_switch_palace, player) and + state.has(ItemName.red_switch_palace, player) and + state.has(ItemName.blue_switch_palace, player))) + + connect(world, player, names, LocationName.special_zone_1_region, LocationName.special_zone_1_exit_1, + lambda state: (state.has(ItemName.mario_climb, player) and + (state.has(ItemName.p_switch, player) or + (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3))))) + connect(world, player, names, LocationName.special_zone_2_region, LocationName.special_zone_2_exit_1, + lambda state: state.has(ItemName.p_balloon, player)) + connect(world, player, names, LocationName.special_zone_3_region, LocationName.special_zone_3_exit_1, + lambda state: (state.has(ItemName.mario_climb, player) or + state.has(ItemName.p_switch, player) or + (state.has(ItemName.mario_run, player) and state.has(ItemName.progressive_powerup, player, 3)))) + connect(world, player, names, LocationName.special_zone_4_region, LocationName.special_zone_4_exit_1, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + connect(world, player, names, LocationName.special_zone_5_region, LocationName.special_zone_5_exit_1, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + connect(world, player, names, LocationName.special_zone_6_region, LocationName.special_zone_6_exit_1, + lambda state: state.has(ItemName.mario_swim, player)) + connect(world, player, names, LocationName.special_zone_7_region, LocationName.special_zone_7_exit_1, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + connect(world, player, names, LocationName.special_zone_8_region, LocationName.special_zone_8_exit_1, + lambda state: state.has(ItemName.progressive_powerup, player, 1)) + + + + # Connect levels to each other + for current_level_id, current_level_data in level_info_dict.items(): + # Connect tile regions to correct level regions + + if current_level_id not in level_to_tile_dict.keys(): + continue + + current_tile_id = level_to_tile_dict[current_level_id] + current_tile_data = level_info_dict[current_tile_id] + current_tile_name = current_tile_data.levelName + if ("Star Road - " not in current_tile_name) and (" - Star Road" not in current_tile_name): + current_tile_name += " - Tile" + connect(world, player, names, current_tile_name, current_level_data.levelName) + # Connect Exit regions to next tile regions + if current_tile_data.exit1Path: + next_tile_id = current_tile_data.exit1Path.otherLevelID + if world.swap_donut_gh_exits[player] and current_tile_id == 0x04: + next_tile_id = current_tile_data.exit2Path.otherLevelID + next_tile_name = level_info_dict[next_tile_id].levelName + if ("Star Road - " not in next_tile_name) and (" - Star Road" not in next_tile_name): + next_tile_name += " - Tile" + current_exit_name = (current_level_data.levelName + " - Normal Exit") + connect(world, player, names, current_exit_name, next_tile_name) + if current_tile_data.exit2Path: + next_tile_id = current_tile_data.exit2Path.otherLevelID + if world.swap_donut_gh_exits[player] and current_tile_id == 0x04: + next_tile_id = current_tile_data.exit1Path.otherLevelID + next_tile_name = level_info_dict[next_tile_id].levelName + if ("Star Road - " not in next_tile_name) and (" - Star Road" not in next_tile_name): + next_tile_name += " - Tile" + current_exit_name = (current_level_data.levelName + " - Secret Exit") + connect(world, player, names, current_exit_name, next_tile_name) + + connect(world, player, names, LocationName.donut_plains_star_road, LocationName.star_road_donut) + connect(world, player, names, LocationName.star_road_donut, LocationName.donut_plains_star_road) + connect(world, player, names, LocationName.star_road_donut, LocationName.star_road_1_tile) + connect(world, player, names, LocationName.vanilla_dome_star_road, LocationName.star_road_vanilla) + connect(world, player, names, LocationName.star_road_vanilla, LocationName.vanilla_dome_star_road) + connect(world, player, names, LocationName.star_road_vanilla, LocationName.star_road_2_tile) + connect(world, player, names, LocationName.twin_bridges_star_road, LocationName.star_road_twin_bridges) + connect(world, player, names, LocationName.star_road_twin_bridges, LocationName.twin_bridges_star_road) + connect(world, player, names, LocationName.star_road_twin_bridges, LocationName.star_road_3_tile) + connect(world, player, names, LocationName.forest_star_road, LocationName.star_road_forest) + connect(world, player, names, LocationName.star_road_forest, LocationName.forest_star_road) + connect(world, player, names, LocationName.star_road_forest, LocationName.star_road_4_tile) + connect(world, player, names, LocationName.valley_star_road, LocationName.star_road_valley) + connect(world, player, names, LocationName.star_road_valley, LocationName.valley_star_road) + connect(world, player, names, LocationName.star_road_valley, LocationName.star_road_5_tile) + connect(world, player, names, LocationName.star_road_special, LocationName.special_star_road) + connect(world, player, names, LocationName.special_star_road, LocationName.star_road_special) + connect(world, player, names, LocationName.special_star_road, LocationName.special_zone_1_tile) + + connect(world, player, names, LocationName.star_road_valley, LocationName.front_door_tile) + + + +def create_region(world: MultiWorld, player: int, active_locations, name: str, locations=None): + ret = Region(name, RegionType.Generic, name, player) + ret.world = world + if locations: + for locationName in locations: + loc_id = active_locations.get(locationName, 0) + if loc_id: + location = SMWLocation(player, locationName, loc_id, ret) + ret.locations.append(location) + + return ret + +def add_location_to_region(world: MultiWorld, player: int, active_locations, region_name: str, location_name: str, + rule: typing.Optional[typing.Callable] = None): + region = world.get_region(region_name, player) + loc_id = active_locations.get(location_name, 0) + if loc_id: + location = SMWLocation(player, location_name, loc_id, region) + region.locations.append(location) + if rule: + add_rule(location, rule) + + + +def connect(world: MultiWorld, player: int, used_names: typing.Dict[str, int], source: str, target: str, + rule: typing.Optional[typing.Callable] = None): + source_region = world.get_region(source, player) + target_region = world.get_region(target, player) + + if target not in used_names: + used_names[target] = 1 + name = target + else: + used_names[target] += 1 + name = target + (' ' * used_names[target]) + + connection = Entrance(player, name, source_region) + + if rule: + connection.access_rule = rule + + source_region.exits.append(connection) + connection.connect(target_region) diff --git a/worlds/smw/Rom.py b/worlds/smw/Rom.py new file mode 100644 index 00000000..6c750d74 --- /dev/null +++ b/worlds/smw/Rom.py @@ -0,0 +1,846 @@ +import Utils +from Patch import read_rom, APDeltaPatch +from .Aesthetics import generate_shuffled_header_data +from .Locations import lookup_id_to_name, all_locations +from .Levels import level_info_dict, full_level_list, submap_level_list, location_id_to_level_id +from .Names.TextBox import generate_goal_text, title_text_mapping, generate_text_box + +USHASH = 'cdd3c8c37322978ca8669b34bc89c804' +ROM_PLAYER_LIMIT = 65535 + +import hashlib +import os +import math + + +ability_rom_data = { + 0xBC0003: [[0x1F2C, 0x7]], # Run 0x80 + 0xBC0004: [[0x1F2C, 0x6]], # Carry 0x40 + 0xBC0005: [[0x1F2C, 0x2]], # Swim 0x04 + 0xBC0006: [[0x1F2C, 0x3]], # Spin Jump 0x08 + 0xBC0007: [[0x1F2C, 0x5]], # Climb 0x20 + 0xBC0008: [[0x1F2C, 0x1]], # Yoshi 0x02 + 0xBC0009: [[0x1F2C, 0x4]], # P-Switch 0x10 + #0xBC000A: [[]] + 0xBC000B: [[0x1F2D, 0x3]], # P-Balloon 0x08 + 0xBC000D: [[0x1F2D, 0x4]], # Super Star 0x10 +} + + +item_rom_data = { + 0xBC0001: [0x18E4, 0x1], # 1-Up Mushroom + + 0xBC0002: [0x1F24, 0x1, 0x1F], # Yoshi Egg + 0xBC0012: [0x1F26, 0x1, 0x09], # Boss Token + + 0xBC000E: [0x1F28, 0x1, 0x1C], # Yellow Switch Palace + 0xBC000F: [0x1F27, 0x1, 0x1C], # Green Switch Palace + 0xBC0010: [0x1F2A, 0x1, 0x1C], # Red Switch Palace + 0xBC0011: [0x1F29, 0x1, 0x1C], # Blue Switch Palace + + 0xBC0013: [0x0086, 0x1, 0x0E], # Ice Trap + 0xBC0014: [0x18BD, 0x7F, 0x18], # Stun Trap +} + +music_rom_data = [ + +] + +level_music_ids = [ + +] + + +class SMWDeltaPatch(APDeltaPatch): + hash = USHASH + game = "Super Mario World" + patch_file_ending = ".apsmw" + + @classmethod + def get_source_data(cls) -> bytes: + return get_base_rom_bytes() + + +class LocalRom: + + def __init__(self, file, patch=True, vanillaRom=None, name=None, hash=None): + self.name = name + self.hash = hash + self.orig_buffer = None + + with open(file, 'rb') as stream: + self.buffer = read_rom(stream) + + def read_bit(self, address: int, bit_number: int) -> bool: + bitflag = (1 << bit_number) + return ((self.buffer[address] & bitflag) != 0) + + def read_byte(self, address: int) -> int: + return self.buffer[address] + + def read_bytes(self, startaddress: int, length: int) -> bytes: + return self.buffer[startaddress:startaddress + length] + + def write_byte(self, address: int, value: int): + self.buffer[address] = value + + def write_bytes(self, startaddress: int, values): + self.buffer[startaddress:startaddress + len(values)] = values + + def write_to_file(self, file): + with open(file, 'wb') as outfile: + outfile.write(self.buffer) + + def read_from_file(self, file): + with open(file, 'rb') as stream: + self.buffer = bytearray(stream.read()) + + +def handle_ability_code(rom): + # Lock Abilities + + #rom.write_byte(0xC581, 0x01) # No Stars + #rom.write_byte(0x62E6, 0x01) # No Star Music + #rom.write_byte(0xC300, 0x01) # No P-Balloons + #rom.write_byte(0xC305, 0x01) # No P-Balloons + + # Run + rom.write_bytes(0x5977, bytearray([0x22, 0x10, 0xBA, 0x03])) # JSL $03BA10 + rom.write_bytes(0x597B, bytearray([0xEA] * 0x04)) + + RUN_SUB_ADDR = 0x01BA10 + rom.write_bytes(RUN_SUB_ADDR + 0x00, bytearray([0xDA])) # PHX + rom.write_bytes(RUN_SUB_ADDR + 0x01, bytearray([0x08])) # PHP + rom.write_bytes(RUN_SUB_ADDR + 0x02, bytearray([0x90, 0x03])) # BCC +0x03 + rom.write_bytes(RUN_SUB_ADDR + 0x04, bytearray([0xC8])) # INY + rom.write_bytes(RUN_SUB_ADDR + 0x05, bytearray([0xA9, 0x70])) # LDA #70 + rom.write_bytes(RUN_SUB_ADDR + 0x07, bytearray([0xAA])) # TAX + rom.write_bytes(RUN_SUB_ADDR + 0x08, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(RUN_SUB_ADDR + 0x0B, bytearray([0x89, 0x80])) # BIT #80 + rom.write_bytes(RUN_SUB_ADDR + 0x0D, bytearray([0xF0, 0x04])) # BEQ +0x04 + rom.write_bytes(RUN_SUB_ADDR + 0x0F, bytearray([0x8A])) # TXA + rom.write_bytes(RUN_SUB_ADDR + 0x10, bytearray([0x8D, 0xE4, 0x13])) # STA $13E4 + rom.write_bytes(RUN_SUB_ADDR + 0x13, bytearray([0x8A])) # TXA + rom.write_bytes(RUN_SUB_ADDR + 0x14, bytearray([0x28])) # PLP + rom.write_bytes(RUN_SUB_ADDR + 0x15, bytearray([0xFA])) # PLX + rom.write_bytes(RUN_SUB_ADDR + 0x16, bytearray([0x6B])) # RTL + # End Run + + # Purple Block Carry + rom.write_bytes(0x726F, bytearray([0x22, 0x28, 0xBA, 0x03])) # JSL $03BA28 + rom.write_bytes(0x7273, bytearray([0xEA] * 0x02)) + + PURPLE_BLOCK_CARRY_SUB_ADDR = 0x01BA28 + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x01, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x04, bytearray([0x89, 0x40])) # BIT #40 + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x06, bytearray([0xF0, 0x09])) # BEQ +0x09 + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x09, bytearray([0xAD, 0x8F, 0x14])) # LDA $148F + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x0C, bytearray([0x0D, 0x7A, 0x18])) # ORA $187A + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x0F, bytearray([0x80, 0x03])) # BRA +0x03 + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x11, bytearray([0x28])) # PLP + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x12, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(PURPLE_BLOCK_CARRY_SUB_ADDR + 0x14, bytearray([0x6B])) # RTL + # End Purple Block Carry + + # Springboard Carry + rom.write_bytes(0xE6DA, bytearray([0x22, 0x40, 0xBA, 0x03])) # JSL $03BA40 + rom.write_bytes(0xE6DE, bytearray([0xEA] * 0x04)) + + SPRINGBOARD_CARRY_SUB_ADDR = 0x01BA40 + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x00, bytearray([0x48])) # PHA + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x01, bytearray([0x08])) # PHP + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x02, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x05, bytearray([0x89, 0x40])) # BIT #40 + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x07, bytearray([0xF0, 0x08])) # BEQ +0x08 + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x09, bytearray([0xA9, 0x0B])) # LDA #0B + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x0B, bytearray([0x9D, 0xC8, 0x14])) # STA $14C8, X + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x0E, bytearray([0x9E, 0x02, 0x16])) # STZ $1602, X + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x11, bytearray([0x28])) # PLP + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x12, bytearray([0x68])) # PLA + rom.write_bytes(SPRINGBOARD_CARRY_SUB_ADDR + 0x13, bytearray([0x6B])) # RTL + # End Springboard Carry + + # Shell Carry + rom.write_bytes(0xAA66, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(0xAA69, bytearray([0x89, 0x40])) # BIT #40 + rom.write_bytes(0xAA6B, bytearray([0xF0, 0x07])) # BEQ +0x07 + rom.write_bytes(0xAA6D, bytearray([0x22, 0x60, 0xBA, 0x03])) # JSL $03BA60 + rom.write_bytes(0xAA71, bytearray([0xEA] * 0x02)) + + SHELL_CARRY_SUB_ADDR = 0x01BA60 + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x01, bytearray([0xA9, 0x0B])) # LDA #0B + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x03, bytearray([0x9D, 0xC8, 0x14])) # STA $14C8, X + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x06, bytearray([0xEE, 0x70, 0x14])) # INC $1470 + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x09, bytearray([0xA9, 0x0B])) # LDA #08 + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x0B, bytearray([0x8D, 0x98, 0x14])) # STA $1498 + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x0E, bytearray([0x28])) # PLP + rom.write_bytes(SHELL_CARRY_SUB_ADDR + 0x0F, bytearray([0x6B])) # RTL + # End Shell Carry + + # Yoshi Carry + rom.write_bytes(0xF309, bytearray([0x22, 0x70, 0xBA, 0x03])) # JSL $03BA70 + rom.write_bytes(0xF30D, bytearray([0xEA] * 0x06)) + + YOSHI_CARRY_SUB_ADDR = 0x01BA70 + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x01, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x04, bytearray([0x89, 0x40])) # BIT #40 + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x06, bytearray([0xF0, 0x0A])) # BEQ +0x0A + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x08, bytearray([0xA9, 0x12])) # LDA #12 + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x0A, bytearray([0x8D, 0xA3, 0x14])) # STA $14A3 + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x0D, bytearray([0xA9, 0x21])) # LDA #21 + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x0F, bytearray([0x8D, 0xFC, 0x1D])) # STA $1DFC + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x12, bytearray([0x28])) # PLP + rom.write_bytes(YOSHI_CARRY_SUB_ADDR + 0x13, bytearray([0x6B])) # RTL + # End Yoshi Carry + + # Climb + rom.write_bytes(0x4D72, bytearray([0x5C, 0x88, 0xBA, 0x03])) # JML $03BA88 + rom.write_bytes(0x4D76, bytearray([0xEA] * 0x03)) + + CLIMB_SUB_ADDR = 0x01BA88 + rom.write_bytes(CLIMB_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(CLIMB_SUB_ADDR + 0x01, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(CLIMB_SUB_ADDR + 0x04, bytearray([0x89, 0x20])) # BIT #20 + rom.write_bytes(CLIMB_SUB_ADDR + 0x06, bytearray([0xF0, 0x09])) # BEQ +0x09 + rom.write_bytes(CLIMB_SUB_ADDR + 0x08, bytearray([0xA5, 0x8B])) # LDA $8B + rom.write_bytes(CLIMB_SUB_ADDR + 0x0A, bytearray([0x85, 0x74])) # STA $74 + rom.write_bytes(CLIMB_SUB_ADDR + 0x0C, bytearray([0x28])) # PLP + rom.write_bytes(CLIMB_SUB_ADDR + 0x0D, bytearray([0x5C, 0x17, 0xDB, 0x00])) # JML $00DB17 + rom.write_bytes(CLIMB_SUB_ADDR + 0x11, bytearray([0x28])) # PLP + rom.write_bytes(CLIMB_SUB_ADDR + 0x12, bytearray([0x5C, 0x76, 0xCD, 0x00])) # JML $00CD76 + # End Climb + + # P-Switch + rom.write_bytes(0xAB1A, bytearray([0x22, 0xA0, 0xBA, 0x03])) # JSL $03BAA0 + rom.write_bytes(0xAB1E, bytearray([0xEA] * 0x01)) + + P_SWITCH_SUB_ADDR = 0x01BAA0 + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x01, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x04, bytearray([0x89, 0x10])) # BIT #10 + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x06, bytearray([0xF0, 0x04])) # BEQ +0x04 + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x08, bytearray([0xA9, 0xB0])) # LDA #B0 + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x0A, bytearray([0x80, 0x02])) # BRA +0x02 + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x0C, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x0E, bytearray([0x99, 0xAD, 0x14])) # STA $14AD + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x11, bytearray([0x28])) # PLP + rom.write_bytes(P_SWITCH_SUB_ADDR + 0x12, bytearray([0x6B])) # RTL + # End P-Switch + + # Spin Jump + rom.write_bytes(0x5645, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(0x5648, bytearray([0x89, 0x08])) # BIT #08 + rom.write_bytes(0x564A, bytearray([0xF0, 0x12])) # BEQ +0x12 + rom.write_bytes(0x564C, bytearray([0x22, 0xB8, 0xBA, 0x03])) # JSL $03BAB8 + + SPIN_JUMP_SUB_ADDR = 0x01BAB8 + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x01, bytearray([0x1A])) # INC + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x02, bytearray([0x8D, 0x0D, 0x14])) # STA $140D + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x05, bytearray([0xA9, 0x04])) # LDA #04 + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x07, bytearray([0x8D, 0xFC, 0x1D])) # STA $1DFC + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x0A, bytearray([0xA4, 0x76])) # LDY #76 + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x0C, bytearray([0x28])) # PLP + rom.write_bytes(SPIN_JUMP_SUB_ADDR + 0x0D, bytearray([0x6B])) # RTL + # End Spin Jump + + # Spin Jump from Water + rom.write_bytes(0x6A89, bytearray([0x22, 0xF8, 0xBB, 0x03])) # JSL $03BBF8 + rom.write_bytes(0x6A8D, bytearray([0xEA] * 0x05)) + + SPIN_JUMP_WATER_SUB_ADDR = 0x01BBF8 + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x01, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x04, bytearray([0x89, 0x08])) # BIT #08 + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x06, bytearray([0xF0, 0x09])) # BEQ +0x09 + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x08, bytearray([0x1A])) # INC + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x09, bytearray([0x8D, 0x0D, 0x14])) # STA $140D + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x0C, bytearray([0xA9, 0x04])) # LDA #04 + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x0E, bytearray([0x8D, 0xFC, 0x1D])) # STA $1DFC + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x11, bytearray([0x28])) # PLP + rom.write_bytes(SPIN_JUMP_WATER_SUB_ADDR + 0x12, bytearray([0x6B])) # RTL + # End Spin Jump from Water + + # Spin Jump from Springboard + rom.write_bytes(0xE693, bytearray([0x22, 0x0C, 0xBC, 0x03])) # JSL $03BC0C + rom.write_bytes(0xE697, bytearray([0xEA] * 0x01)) + + SPIN_JUMP_SPRING_SUB_ADDR = 0x01BC0C + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x01, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x04, bytearray([0x89, 0x08])) # BIT #08 + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x06, bytearray([0xF0, 0x05])) # BEQ +0x05 + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x08, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x0A, bytearray([0x8D, 0x0D, 0x14])) # STA $140D + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x0D, bytearray([0x28])) # PLP + rom.write_bytes(SPIN_JUMP_SPRING_SUB_ADDR + 0x0E, bytearray([0x6B])) # RTL + # End Spin Jump from Springboard + + # Swim + rom.write_bytes(0x5A25, bytearray([0x22, 0xC8, 0xBA, 0x03])) # JSL $03BAC8 + rom.write_bytes(0x5A29, bytearray([0xEA] * 0x04)) + + SWIM_SUB_ADDR = 0x01BAC8 + rom.write_bytes(SWIM_SUB_ADDR + 0x00, bytearray([0x48])) # PHA + rom.write_bytes(SWIM_SUB_ADDR + 0x01, bytearray([0x08])) # PHP + rom.write_bytes(SWIM_SUB_ADDR + 0x02, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(SWIM_SUB_ADDR + 0x05, bytearray([0x89, 0x04])) # BIT #04 + rom.write_bytes(SWIM_SUB_ADDR + 0x07, bytearray([0xF0, 0x0C])) # BEQ +0x0C + rom.write_bytes(SWIM_SUB_ADDR + 0x09, bytearray([0x28])) # PLP + rom.write_bytes(SWIM_SUB_ADDR + 0x0A, bytearray([0x68])) # PLA + rom.write_bytes(SWIM_SUB_ADDR + 0x0B, bytearray([0xDD, 0x84, 0xD9])) # CMP $D489, X + rom.write_bytes(SWIM_SUB_ADDR + 0x0E, bytearray([0xB0, 0x03])) # BCS +0x03 + rom.write_bytes(SWIM_SUB_ADDR + 0x10, bytearray([0xBD, 0x84, 0xD9])) # LDA $D489, X + rom.write_bytes(SWIM_SUB_ADDR + 0x13, bytearray([0x80, 0x0A])) # BRA +0x0A + rom.write_bytes(SWIM_SUB_ADDR + 0x15, bytearray([0x28])) # PLP + rom.write_bytes(SWIM_SUB_ADDR + 0x16, bytearray([0x68])) # PLA + rom.write_bytes(SWIM_SUB_ADDR + 0x17, bytearray([0xDD, 0xBE, 0xDE])) # CMP $DEBE, X + rom.write_bytes(SWIM_SUB_ADDR + 0x1A, bytearray([0xB0, 0x03])) # BCS +0x03 + rom.write_bytes(SWIM_SUB_ADDR + 0x1C, bytearray([0xBD, 0xBE, 0xDE])) # LDA $DEBE, X + rom.write_bytes(SWIM_SUB_ADDR + 0x1F, bytearray([0x6B])) # RTL + # End Swim + + # Item Swim + rom.write_bytes(0x59D7, bytearray([0x22, 0xE8, 0xBA, 0x03])) # JSL $03BAE8 + rom.write_bytes(0x59DB, bytearray([0xEA] * 0x02)) + + SWIM_SUB_ADDR = 0x01BAE8 + rom.write_bytes(SWIM_SUB_ADDR + 0x00, bytearray([0x48])) # PHA + rom.write_bytes(SWIM_SUB_ADDR + 0x01, bytearray([0x08])) # PHP + rom.write_bytes(SWIM_SUB_ADDR + 0x02, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(SWIM_SUB_ADDR + 0x05, bytearray([0x89, 0x04])) # BIT #04 + rom.write_bytes(SWIM_SUB_ADDR + 0x07, bytearray([0xF0, 0x0A])) # BEQ +0x0A + rom.write_bytes(SWIM_SUB_ADDR + 0x09, bytearray([0x28])) # PLP + rom.write_bytes(SWIM_SUB_ADDR + 0x0A, bytearray([0x68])) # PLA + rom.write_bytes(SWIM_SUB_ADDR + 0x0B, bytearray([0xC9, 0xF0])) # CMP #F0 + rom.write_bytes(SWIM_SUB_ADDR + 0x0D, bytearray([0xB0, 0x02])) # BCS +0x02 + rom.write_bytes(SWIM_SUB_ADDR + 0x0F, bytearray([0xA9, 0xF0])) # LDA #F0 + rom.write_bytes(SWIM_SUB_ADDR + 0x11, bytearray([0x80, 0x08])) # BRA +0x08 + rom.write_bytes(SWIM_SUB_ADDR + 0x13, bytearray([0x28])) # PLP + rom.write_bytes(SWIM_SUB_ADDR + 0x14, bytearray([0x68])) # PLA + rom.write_bytes(SWIM_SUB_ADDR + 0x15, bytearray([0xC9, 0xFF])) # CMP #FF + rom.write_bytes(SWIM_SUB_ADDR + 0x17, bytearray([0xB0, 0x02])) # BCS +0x02 + rom.write_bytes(SWIM_SUB_ADDR + 0x19, bytearray([0xA9, 0x00])) # LDA #00 + rom.write_bytes(SWIM_SUB_ADDR + 0x1B, bytearray([0x6B])) # RTL + # End Item Swim + + # Yoshi + rom.write_bytes(0x109FB, bytearray([0x22, 0x08, 0xBB, 0x03])) # JSL $03BB08 + rom.write_bytes(0x109FF, bytearray([0xEA] * 0x02)) + + YOSHI_SUB_ADDR = 0x01BB08 + rom.write_bytes(YOSHI_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(YOSHI_SUB_ADDR + 0x01, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(YOSHI_SUB_ADDR + 0x04, bytearray([0x89, 0x02])) # BIT #02 + rom.write_bytes(YOSHI_SUB_ADDR + 0x06, bytearray([0xF0, 0x06])) # BEQ +0x06 + rom.write_bytes(YOSHI_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(YOSHI_SUB_ADDR + 0x09, bytearray([0xB9, 0xA1, 0x88])) # LDA $88A1, Y + rom.write_bytes(YOSHI_SUB_ADDR + 0x0C, bytearray([0x80, 0x04])) # BRA +0x04 + rom.write_bytes(YOSHI_SUB_ADDR + 0x0E, bytearray([0x28])) # PLP + rom.write_bytes(YOSHI_SUB_ADDR + 0x0F, bytearray([0xB9, 0xA2, 0x88])) # LDA $88A2, Y + rom.write_bytes(YOSHI_SUB_ADDR + 0x12, bytearray([0x9D, 0x1C, 0x15])) # STA $151C, X + rom.write_bytes(YOSHI_SUB_ADDR + 0x15, bytearray([0x6B])) # RTL + # End Yoshi + + # Baby Yoshi + rom.write_bytes(0xA2B8, bytearray([0x22, 0x20, 0xBB, 0x03])) # JSL $03BB20 + rom.write_bytes(0xA2BC, bytearray([0xEA] * 0x01)) + + YOSHI_SUB_ADDR = 0x01BB20 + rom.write_bytes(YOSHI_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(YOSHI_SUB_ADDR + 0x01, bytearray([0x9C, 0x1E, 0x14])) # STZ $141E + rom.write_bytes(YOSHI_SUB_ADDR + 0x04, bytearray([0xAD, 0x2C, 0x1F])) # LDA $1F2C + rom.write_bytes(YOSHI_SUB_ADDR + 0x07, bytearray([0x89, 0x02])) # BIT #02 + rom.write_bytes(YOSHI_SUB_ADDR + 0x09, bytearray([0xF0, 0x05])) # BEQ +0x05 + rom.write_bytes(YOSHI_SUB_ADDR + 0x0B, bytearray([0x28])) # PLP + rom.write_bytes(YOSHI_SUB_ADDR + 0x0C, bytearray([0xA9, 0x35])) # LDA #35 + rom.write_bytes(YOSHI_SUB_ADDR + 0x0E, bytearray([0x80, 0x03])) # BRA +0x03 + rom.write_bytes(YOSHI_SUB_ADDR + 0x10, bytearray([0x28])) # PLP + rom.write_bytes(YOSHI_SUB_ADDR + 0x11, bytearray([0xA9, 0x70])) # LDA #70 + rom.write_bytes(YOSHI_SUB_ADDR + 0x13, bytearray([0x6B])) # RTL + # End Baby Yoshi + + # Midway Gate + rom.write_bytes(0x72E4, bytearray([0x22, 0x38, 0xBB, 0x03])) # JSL $03BB38 + + MIDWAY_GATE_SUB_ADDR = 0x01BB38 + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x01, bytearray([0xAD, 0x2D, 0x1F])) # LDA $1F2D + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x04, bytearray([0x89, 0x01])) # BIT #01 + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x06, bytearray([0xF0, 0x07])) # BEQ +0x07 + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x09, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x0B, bytearray([0x85, 0x19])) # STA $19 + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x0D, bytearray([0x80, 0x01])) # BRA +0x01 + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x0F, bytearray([0x28])) # PLP + rom.write_bytes(MIDWAY_GATE_SUB_ADDR + 0x10, bytearray([0x6B])) # RTL + # End Midway Gate + + # Mushroom + rom.write_bytes(0x5156, bytearray([0x22, 0x50, 0xBB, 0x03])) # JSL $03BB50 + rom.write_bytes(0x515A, bytearray([0xEA] * 0x04)) + + MUSHROOM_SUB_ADDR = 0x01BB50 + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x01, bytearray([0xAD, 0x2D, 0x1F])) # LDA $1F2D + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x04, bytearray([0x89, 0x01])) # BIT #01 + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x06, bytearray([0xF0, 0x05])) # BEQ +0x05 + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x09, bytearray([0xE6, 0x19])) # INC $19 + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x0B, bytearray([0x80, 0x01])) # BRA +0x01 + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x0D, bytearray([0x28])) # PLP + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x0E, bytearray([0xA9, 0x00])) # LDA #00 + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x10, bytearray([0x85, 0x71])) # STA $72 + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x12, bytearray([0x64, 0x9D])) # STZ $9D + rom.write_bytes(MUSHROOM_SUB_ADDR + 0x14, bytearray([0x6B])) # RTL + # End Mushroom + + # Take Damage + rom.write_bytes(0x5142, bytearray([0x22, 0x65, 0xBB, 0x03])) # JSL $03BB65 + rom.write_bytes(0x5146, bytearray([0x60] * 0x01)) # RTS + + DAMAGE_SUB_ADDR = 0x01BB65 + rom.write_bytes(DAMAGE_SUB_ADDR + 0x00, bytearray([0x8D, 0x97, 0x14])) # STA $1497 + rom.write_bytes(DAMAGE_SUB_ADDR + 0x03, bytearray([0x80, 0xF4])) # BRA -0x0C + # End Take Damage + + # Fire Flower Cycle + rom.write_bytes(0x5187, bytearray([0x22, 0x6A, 0xBB, 0x03])) # JSL $03BB6A + rom.write_bytes(0x518B, bytearray([0x60] * 0x01)) # RTS + + PALETTE_CYCLE_SUB_ADDR = 0x01BB6A + rom.write_bytes(PALETTE_CYCLE_SUB_ADDR + 0x00, bytearray([0xCE, 0x9B, 0x14])) # DEC $149B + rom.write_bytes(PALETTE_CYCLE_SUB_ADDR + 0x03, bytearray([0xF0, 0xEF])) # BEQ -0x11 + rom.write_bytes(PALETTE_CYCLE_SUB_ADDR + 0x05, bytearray([0x6B])) # RTL + # End Fire Flower Cycle + + # Pipe Exit + rom.write_bytes(0x526D, bytearray([0x22, 0x70, 0xBB, 0x03])) # JSL $03BB70 + rom.write_bytes(0x5271, bytearray([0x60, 0xEA] * 0x01)) # RTS, NOP + + PIPE_EXIT_SUB_ADDR = 0x01BB70 + rom.write_bytes(PIPE_EXIT_SUB_ADDR + 0x00, bytearray([0x9C, 0x19, 0x14])) # STZ $1419 + rom.write_bytes(PIPE_EXIT_SUB_ADDR + 0x03, bytearray([0xA9, 0x00])) # LDA #00 + rom.write_bytes(PIPE_EXIT_SUB_ADDR + 0x05, bytearray([0x85, 0x71])) # STA $72 + rom.write_bytes(PIPE_EXIT_SUB_ADDR + 0x07, bytearray([0x64, 0x9D])) # STZ $9D + rom.write_bytes(PIPE_EXIT_SUB_ADDR + 0x09, bytearray([0x6B])) # RTL + # End Pipe Exit + + # Cape Transform + rom.write_bytes(0x5168, bytearray([0x22, 0x7A, 0xBB, 0x03])) # JSL $03BB7A + rom.write_bytes(0x516C, bytearray([0xEA] * 0x01)) # RTS, NOP + rom.write_bytes(0x516D, bytearray([0xF0, 0xD1])) # BEQ -0x2F + + CAPE_TRANSFORM_SUB_ADDR = 0x01BB7A + rom.write_bytes(CAPE_TRANSFORM_SUB_ADDR + 0x00, bytearray([0xA5, 0x19])) # LDA $19 + rom.write_bytes(CAPE_TRANSFORM_SUB_ADDR + 0x02, bytearray([0x4A])) # LSR + rom.write_bytes(CAPE_TRANSFORM_SUB_ADDR + 0x03, bytearray([0xD0, 0xDF])) # BNE -0x21 + rom.write_bytes(CAPE_TRANSFORM_SUB_ADDR + 0x05, bytearray([0x6B])) # RTL + # End Cape Transform + + # Fire Flower + rom.write_bytes(0xC5F7, bytearray([0x22, 0x80, 0xBB, 0x03])) # JSL $03BB80 + + FIRE_FLOWER_SUB_ADDR = 0x01BB80 + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x01, bytearray([0xAD, 0x2D, 0x1F])) # LDA $1F2D + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x04, bytearray([0x89, 0x02])) # BIT #02 + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x06, bytearray([0xF0, 0x07])) # BEQ +0x07 + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x09, bytearray([0xA9, 0x03])) # LDA #03 + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x0B, bytearray([0x85, 0x19])) # STA $19 + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x0D, bytearray([0x80, 0x01])) # BRA +0x01 + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x0F, bytearray([0x28])) # PLP + rom.write_bytes(FIRE_FLOWER_SUB_ADDR + 0x10, bytearray([0x6B])) # RTL + # End Fire Flower + + # Cape + rom.write_bytes(0xC598, bytearray([0x22, 0x91, 0xBB, 0x03])) # JSL $03BB91 + + CAPE_SUB_ADDR = 0x01BB91 + rom.write_bytes(CAPE_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(CAPE_SUB_ADDR + 0x01, bytearray([0xAD, 0x2D, 0x1F])) # LDA $1F2D + rom.write_bytes(CAPE_SUB_ADDR + 0x04, bytearray([0x89, 0x04])) # BIT #04 + rom.write_bytes(CAPE_SUB_ADDR + 0x06, bytearray([0xF0, 0x07])) # BEQ +0x07 + rom.write_bytes(CAPE_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(CAPE_SUB_ADDR + 0x09, bytearray([0xA9, 0x02])) # LDA #02 + rom.write_bytes(CAPE_SUB_ADDR + 0x0B, bytearray([0x85, 0x19])) # STA $19 + rom.write_bytes(CAPE_SUB_ADDR + 0x0D, bytearray([0x80, 0x01])) # BRA +0x01 + rom.write_bytes(CAPE_SUB_ADDR + 0x0F, bytearray([0x28])) # PLP + rom.write_bytes(CAPE_SUB_ADDR + 0x10, bytearray([0x6B])) # RTL + # End Cape + + # P-Balloon + rom.write_bytes(0xC2FF, bytearray([0x22, 0xA2, 0xBB, 0x03])) # JSL $03BBA2 + rom.write_bytes(0xC303, bytearray([0xEA] * 0x06)) + + P_BALLOON_SUB_ADDR = 0x01BBA2 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x01, bytearray([0xAD, 0x2D, 0x1F])) # LDA $1F2D + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x04, bytearray([0x89, 0x08])) # BIT #08 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x06, bytearray([0xF0, 0x0D])) # BEQ +0x0D + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x09, bytearray([0xA9, 0x09])) # LDA #09 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x0B, bytearray([0x8D, 0xF3, 0x13])) # STA $13F3 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x0E, bytearray([0xA9, 0xFF])) # LDA #FF + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x10, bytearray([0x8D, 0x91, 0x18])) # STA $1891 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x13, bytearray([0x80, 0x0B])) # BRA +0x0B + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x15, bytearray([0x28])) # PLP + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x16, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x18, bytearray([0x8D, 0xF3, 0x13])) # STA $13F3 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x1B, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x1D, bytearray([0x8D, 0x91, 0x18])) # STA $1891 + rom.write_bytes(P_BALLOON_SUB_ADDR + 0x20, bytearray([0x6B])) # RTL + # End P-Balloon + + # Star + rom.write_bytes(0xC580, bytearray([0x22, 0xC8, 0xBB, 0x03])) # JSL $03BBC8 + rom.write_bytes(0xC584, bytearray([0xEA] * 0x01)) + + STAR_SUB_ADDR = 0x01BBC8 + rom.write_bytes(STAR_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(STAR_SUB_ADDR + 0x01, bytearray([0xAD, 0x2D, 0x1F])) # LDA $1F2D + rom.write_bytes(STAR_SUB_ADDR + 0x04, bytearray([0x89, 0x10])) # BIT #10 + rom.write_bytes(STAR_SUB_ADDR + 0x06, bytearray([0xF0, 0x08])) # BEQ +0x08 + rom.write_bytes(STAR_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(STAR_SUB_ADDR + 0x09, bytearray([0xA9, 0xFF])) # LDA #FF + rom.write_bytes(STAR_SUB_ADDR + 0x0B, bytearray([0x8D, 0x90, 0x14])) # STA $1490 + rom.write_bytes(STAR_SUB_ADDR + 0x0E, bytearray([0x80, 0x06])) # BRA +0x06 + rom.write_bytes(STAR_SUB_ADDR + 0x10, bytearray([0x28])) # PLP + rom.write_bytes(STAR_SUB_ADDR + 0x11, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(STAR_SUB_ADDR + 0x13, bytearray([0x8D, 0x90, 0x14])) # STA $1490 + rom.write_bytes(STAR_SUB_ADDR + 0x16, bytearray([0x6B])) # RTL + # End Star + + # Star Timer + rom.write_bytes(0x62E3, bytearray([0x22, 0xE0, 0xBB, 0x03])) # JSL $03BBE0 + + STAR_TIMER_SUB_ADDR = 0x01BBE0 + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x01, bytearray([0xAD, 0x2D, 0x1F])) # LDA $1F2D + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x04, bytearray([0x89, 0x10])) # BIT #10 + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x06, bytearray([0xF0, 0x07])) # BEQ +0x07 + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x09, bytearray([0xA5, 0x13])) # LDA $13 + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x0B, bytearray([0xC0, 0x1E])) # CPY #1E + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x0D, bytearray([0x80, 0x05])) # BRA +0x05 + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x0F, bytearray([0x28])) # PLP + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x10, bytearray([0xA5, 0x13])) # LDA $13 + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x12, bytearray([0xC0, 0x01])) # CPY #01 + rom.write_bytes(STAR_TIMER_SUB_ADDR + 0x14, bytearray([0x6B])) # RTL + # End Star Timer + + return + + +def handle_yoshi_box(rom): + + rom.write_bytes(0xEC3D, bytearray([0xEA] * 0x03)) # NOP Lines that cause Yoshi Rescue Box normally + + rom.write_bytes(0x2B20F, bytearray([0x20, 0x60, 0xDC])) # JSR $05DC60 + + YOSHI_BOX_SUB_ADDR = 0x02DC60 + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x01, bytearray([0xAD, 0x26, 0x14])) # LDA $1426 + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x04, bytearray([0xC9, 0x03])) # CMP #03 + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x06, bytearray([0xF0, 0x06])) # BEQ +0x06 + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x09, bytearray([0xB9, 0xD9, 0xA5])) # LDA $A5B9, Y + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x0C, bytearray([0x80, 0x08])) # BRA +0x08 + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x0E, bytearray([0x28])) # PLP + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x0F, bytearray([0xDA])) # PHX + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x10, bytearray([0xBB])) # TYX + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x11, bytearray([0xBF, 0x00, 0xC2, 0x7E])) # LDA $7EC200, X + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x15, bytearray([0xFA])) # PLX + rom.write_bytes(YOSHI_BOX_SUB_ADDR + 0x16, bytearray([0x60])) # RTS + + return + + +def handle_bowser_damage(rom): + + rom.write_bytes(0x1A509, bytearray([0x20, 0x50, 0xBC])) # JSR $03BC50 + + BOWSER_BALLS_SUB_ADDR = 0x01BC50 + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x01, bytearray([0xAD, 0x48, 0x0F])) # LDA $F48 + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x04, bytearray([0xCF, 0xA1, 0xBF, 0x03])) # CMP $03BFA1 + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x08, bytearray([0x90, 0x06])) # BCC +0x06 + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x0A, bytearray([0x28])) # PLP + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x0B, bytearray([0xEE, 0xB8, 0x14])) # INC $14B8 + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x0E, bytearray([0x80, 0x01])) # BRA +0x01 + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x10, bytearray([0x28])) # PLP + rom.write_bytes(BOWSER_BALLS_SUB_ADDR + 0x11, bytearray([0x60])) # RTS + + return + + +def handle_level_shuffle(rom, active_level_dict): + rom.write_bytes(0x37600, bytearray([0x00] * 0x800)) # Duplicate Level Table + + rom.write_bytes(0x2D89C, bytearray([0x00, 0xF6, 0x06])) # Level Load Pointer + rom.write_bytes(0x20F46, bytearray([0x00, 0xF6, 0x06])) # Mid Gate Pointer + rom.write_bytes(0x20E7B, bytearray([0x00, 0xF6, 0x06])) # Level Name Pointer + rom.write_bytes(0x21543, bytearray([0x00, 0xF6, 0x06])) # Also Level Name Pointer? + rom.write_bytes(0x20F64, bytearray([0x00, 0xF6, 0x06])) # Level Beaten Pointer + + ### Fix Translevel Check + rom.write_bytes(0x2D8AE, bytearray([0x20, 0x00, 0xDD])) # JSR $DD00 + rom.write_bytes(0x2D8B1, bytearray([0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA])) # NOP NOP NOP NOP NOP + + rom.write_bytes(0x2D7CB, bytearray([0x20, 0x00, 0xDD])) # JSR $DD00 + rom.write_bytes(0x2D7CE, bytearray([0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA])) # NOP NOP NOP NOP NOP + + rom.write_bytes(0x2DD00, bytearray([0xDA])) # PHX + rom.write_bytes(0x2DD01, bytearray([0x08])) # PHP + rom.write_bytes(0x2DD02, bytearray([0xE2, 0x30])) # SEP #30 + rom.write_bytes(0x2DD04, bytearray([0xAE, 0xBF, 0x13])) # LDX $13BF + rom.write_bytes(0x2DD07, bytearray([0xE0, 0x25])) # CPX #25 + rom.write_bytes(0x2DD09, bytearray([0x90, 0x04])) # BCC $DD0F + rom.write_bytes(0x2DD0B, bytearray([0xA2, 0x01])) # LDX #01 + rom.write_bytes(0x2DD0D, bytearray([0x80, 0x02])) # BRA $DD11 + rom.write_bytes(0x2DD0F, bytearray([0xA2, 0x00])) # LDX #00 + rom.write_bytes(0x2DD11, bytearray([0x86, 0x0F])) # STX $0F + rom.write_bytes(0x2DD13, bytearray([0x28])) # PLP + rom.write_bytes(0x2DD14, bytearray([0xFA])) # PLX + rom.write_bytes(0x2DD15, bytearray([0x60])) # RTS + ### End Fix Translevel Check + + ### Fix Snake Blocks + rom.write_bytes(0x192FB, bytearray([0x20, 0x1D, 0xBC])) # JSR $03BC1D + + SNAKE_BLOCKS_SUB_ADDR = 0x01BC1D + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x01, bytearray([0xAD, 0xBF, 0x13])) # LDA $13BF + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x04, bytearray([0xC9, 0x20])) # CMP #20 + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x06, bytearray([0xF0, 0x05])) # BEQ +0x05 + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x08, bytearray([0x28])) # PLP + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x09, bytearray([0xA9, 0x01])) # LDA #01 + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x0B, bytearray([0x80, 0x03])) # BRA +0x03 + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x0D, bytearray([0x28])) # PLP + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x0E, bytearray([0xA9, 0x00])) # LDA #00 + rom.write_bytes(SNAKE_BLOCKS_SUB_ADDR + 0x10, bytearray([0x60])) # RTS + ### End Fix Snake Blocks + + for level_id, level_data in level_info_dict.items(): + if level_id not in active_level_dict.keys(): + continue + + tile_id = active_level_dict[level_id] + tile_data = level_info_dict[tile_id] + + if level_id > 0x80: + level_id = level_id - 0x50 + + rom.write_byte(tile_data.levelIDAddress, level_id) + rom.write_byte(0x2D608 + level_id, tile_data.eventIDValue) + + for level_id, tile_id in active_level_dict.items(): + rom.write_byte(0x37F70 + level_id, tile_id) + + +def handle_collected_paths(rom): + rom.write_bytes(0x1F5B, bytearray([0x22, 0x30, 0xBC, 0x03])) # JSL $03BC30 + rom.write_bytes(0x1F5F, bytearray([0xEA] * 0x02)) + + COLLECTED_PATHS_SUB_ADDR = 0x01BC30 + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x00, bytearray([0x08])) # PHP + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x01, bytearray([0xAD, 0x00, 0x01])) # LDA $0100 + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x04, bytearray([0xC9, 0x0B])) # CMP #0B + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x06, bytearray([0xD0, 0x04])) # BNE +0x04 + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x08, bytearray([0x22, 0xAD, 0xDA, 0x04])) # JSL $04DAAD + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x0C, bytearray([0x28])) # PLP + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x0D, bytearray([0xEE, 0x00, 0x01])) # INC $0100 + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x10, bytearray([0xAD, 0xAF, 0x0D])) # LDA $0DAF + rom.write_bytes(COLLECTED_PATHS_SUB_ADDR + 0x13, bytearray([0x6B])) # RTL + + +def handle_music_shuffle(rom, world, player): + from .Aesthetics import generate_shuffled_level_music, generate_shuffled_ow_music, level_music_address_data, ow_music_address_data + + shuffled_level_music = generate_shuffled_level_music(world, player) + for i in range(len(shuffled_level_music)): + rom.write_byte(level_music_address_data[i], shuffled_level_music[i]) + + shuffled_ow_music = generate_shuffled_ow_music(world, player) + for i in range(len(shuffled_ow_music)): + for addr in ow_music_address_data[i]: + rom.write_byte(addr, shuffled_ow_music[i]) + + +def handle_mario_palette(rom, world, player): + from .Aesthetics import mario_palettes, fire_mario_palettes, ow_mario_palettes + + chosen_palette = world.mario_palette[player].value + + rom.write_bytes(0x32C8, bytes(mario_palettes[chosen_palette])) + rom.write_bytes(0x32F0, bytes(fire_mario_palettes[chosen_palette])) + rom.write_bytes(0x359C, bytes(ow_mario_palettes[chosen_palette])) + + +def handle_swap_donut_gh_exits(rom): + rom.write_bytes(0x2567C, bytes([0xC0])) + rom.write_bytes(0x25873, bytes([0xA9])) + rom.write_bytes(0x25875, bytes([0x85])) + rom.write_bytes(0x25954, bytes([0x92])) + rom.write_bytes(0x25956, bytes([0x0A])) + rom.write_bytes(0x25E31, bytes([0x00, 0x00, 0xD8, 0x04, 0x24, 0x00, 0x98, 0x04, 0x48, 0x00, 0xD8, 0x03, 0x6C, 0x00, 0x56, 0x03, + 0x90, 0x00, 0x56, 0x03, 0xB4, 0x00, 0x56, 0x03, 0x10, 0x05, 0x18, 0x05, 0x28, 0x09, 0x24, 0x05, + 0x38, 0x0B, 0x14, 0x07, 0xEC, 0x09, 0x12, 0x05, 0xF0, 0x09, 0xD2, 0x04, 0xF4, 0x09, 0x92, 0x04])) + rom.write_bytes(0x26371, bytes([0x32])) + + +def patch_rom(world, rom, player, active_level_dict): + local_random = world.slot_seeds[player] + + goal_text = generate_goal_text(world, player) + + rom.write_bytes(0x2A6E2, goal_text) + rom.write_byte(0x2B1D8, 0x80) + + intro_text = generate_text_box("Bowser has stolen all of Mario's abilities. Can you help Mario travel across Dinosaur land to get them back and save the Princess from him?") + rom.write_bytes(0x2A5D9, intro_text) + + # Force all 8 Bowser's Castle Rooms + rom.write_byte(0x3A680, 0xD4) + rom.write_byte(0x3A684, 0xD4) + rom.write_byte(0x3A688, 0xD4) + rom.write_byte(0x3A68C, 0xD4) + rom.write_byte(0x3A705, 0xD3) + rom.write_byte(0x3A763, 0xD2) + rom.write_byte(0x3A800, 0xD1) + rom.write_byte(0x3A83D, 0xCF) + rom.write_byte(0x3A932, 0xCE) + rom.write_byte(0x3A9E1, 0xCD) + rom.write_byte(0x3AA75, 0xCC) + + # Prevent Title Screen Deaths + rom.write_byte(0x1C6A, 0x80) + + # Title Screen Text + player_name_bytes = bytearray() + player_name = world.get_player_name(player) + for i in range(16): + char = " " + if i < len(player_name): + char = world.get_player_name(player)[i] + upper_char = char.upper() + if upper_char not in title_text_mapping: + for byte in title_text_mapping["."]: + player_name_bytes.append(byte) + else: + for byte in title_text_mapping[upper_char]: + player_name_bytes.append(byte) + + rom.write_bytes(0x2B7F1, player_name_bytes) # MARIO A + rom.write_bytes(0x2B726, player_name_bytes) # MARIO A + + rom.write_bytes(0x2B815, bytearray([0xFC, 0x38] * 0x10)) # MARIO B + rom.write_bytes(0x2B74A, bytearray([0xFC, 0x38] * 0x10)) # MARIO B + rom.write_bytes(0x2B839, bytearray([0x71, 0x31, 0x74, 0x31, 0x2D, 0x31, 0x84, 0x30, + 0x82, 0x30, 0x6F, 0x31, 0x73, 0x31, 0x70, 0x31, + 0x71, 0x31, 0x75, 0x31, 0x83, 0x30, 0xFC, 0x38, + 0xFC, 0x38, 0xFC, 0x38, 0xFC, 0x38, 0xFC, 0x38])) # MARIO C + rom.write_bytes(0x2B76E, bytearray([0xFC, 0x38] * 0x10)) # MARIO C + rom.write_bytes(0x2B79E, bytearray([0xFC, 0x38] * 0x05)) # EMPTY + rom.write_bytes(0x2B7AE, bytearray([0xFC, 0x38] * 0x05)) # EMPTY + rom.write_bytes(0x2B8A8, bytearray([0xFC, 0x38] * 0x0D)) # 2 PLAYER GAME + + rom.write_bytes(0x2B85D, bytearray([0xFC, 0x38] * 0x0A)) # ERASE + + rom.write_bytes(0x2B88E, bytearray([0x2C, 0x31, 0x73, 0x31, 0x75, 0x31, 0x82, 0x30, 0x30, 0x31, 0xFC, 0x38, 0x31, 0x31, 0x73, 0x31, + 0x73, 0x31, 0x7C, 0x30, 0xFC, 0x38, 0xFC, 0x38, 0xFC, 0x38])) # 1 Player Game + + rom.write_bytes(0x2B6D7, bytearray([0xFC, 0x38, 0xFC, 0x38, 0x16, 0x38, 0x18, 0x38, 0x0D, 0x38, 0xFC, 0x38, 0x0B, 0x38, 0x22, 0x38, + 0xFC, 0x38, 0x19, 0x38, 0x18, 0x38, 0x1B, 0x38, 0x22, 0x38, 0x10, 0x38, 0x18, 0x38, 0x17, 0x38, + 0x0E, 0x38, 0xFC, 0x38, 0xFC, 0x38])) # Mod by PoryGone + + # Title Options + rom.write_bytes(0x1E6A, bytearray([0x01])) + rom.write_bytes(0x1E6C, bytearray([0x01])) + rom.write_bytes(0x1E6E, bytearray([0x01])) + + # Always allow Start+Select + rom.write_bytes(0x2267, bytearray([0xEA, 0xEA])) + + # Always bring up save prompt on beating a level + if world.autosave[player]: + rom.write_bytes(0x20F93, bytearray([0x00])) + + # Starting Life Count + rom.write_bytes(0x1E25, bytearray([world.starting_life_count[player].value - 1])) + + # Repurpose Bonus Stars counter for Boss Token or Yoshi Eggs + rom.write_bytes(0x3F1AA, bytearray([0x00] * 0x20)) + rom.write_bytes(0x20F9F, bytearray([0xEA] * 0x3B)) + + # Prevent Switch Palaces setting the Switch Palace flags + rom.write_bytes(0x6EC9A, bytearray([0xEA, 0xEA])) + rom.write_bytes(0x6EB1, bytearray([0xEA, 0xEA])) + rom.write_bytes(0x6EB4, bytearray([0xEA, 0xEA, 0xEA])) + + handle_ability_code(rom) + + handle_yoshi_box(rom) + handle_bowser_damage(rom) + + handle_collected_paths(rom) + + # Handle Level Shuffle + handle_level_shuffle(rom, active_level_dict) + + # Handle Music Shuffle + if world.music_shuffle[player] != "none": + handle_music_shuffle(rom, world, player) + + generate_shuffled_header_data(rom, world, player) + + if world.swap_donut_gh_exits[player]: + handle_swap_donut_gh_exits(rom) + + handle_mario_palette(rom, world, player) + + # Store all relevant option results in ROM + rom.write_byte(0x01BFA0, world.goal[player].value) + rom.write_byte(0x01BFA1, world.bosses_required[player].value) + required_yoshi_eggs = max(math.floor( + world.number_of_yoshi_eggs[player].value * (world.percentage_of_yoshi_eggs[player].value / 100.0)), 1) + rom.write_byte(0x01BFA2, required_yoshi_eggs) + #rom.write_byte(0x01BFA3, world.display_sent_item_popups[player].value) + rom.write_byte(0x01BFA4, world.display_received_item_popups[player].value) + rom.write_byte(0x01BFA5, world.death_link[player].value) + rom.write_byte(0x01BFA6, world.dragon_coin_checks[player].value) + rom.write_byte(0x01BFA7, world.swap_donut_gh_exits[player].value) + + + from Main import __version__ + rom.name = bytearray(f'SMW{__version__.replace(".", "")[0:3]}_{player}_{world.seed:11}\0', 'utf8')[:21] + rom.name.extend([0] * (21 - len(rom.name))) + rom.write_bytes(0x7FC0, rom.name) + + +def get_base_rom_bytes(file_name: str = "") -> bytes: + base_rom_bytes = getattr(get_base_rom_bytes, "base_rom_bytes", None) + if not base_rom_bytes: + file_name = get_base_rom_path(file_name) + base_rom_bytes = bytes(read_rom(open(file_name, "rb"))) + + basemd5 = hashlib.md5() + basemd5.update(base_rom_bytes) + if USHASH != basemd5.hexdigest(): + raise Exception('Supplied Base Rom does not match known MD5 for US(1.0) release. ' + 'Get the correct game and version, then dump it') + get_base_rom_bytes.base_rom_bytes = base_rom_bytes + return base_rom_bytes + +def get_base_rom_path(file_name: str = "") -> str: + options = Utils.get_options() + if not file_name: + file_name = options["smw_options"]["rom_file"] + if not os.path.exists(file_name): + file_name = Utils.local_path(file_name) + return file_name diff --git a/worlds/smw/Rules.py b/worlds/smw/Rules.py new file mode 100644 index 00000000..bf9fedb8 --- /dev/null +++ b/worlds/smw/Rules.py @@ -0,0 +1,20 @@ +import math + +from BaseClasses import MultiWorld +from .Names import LocationName, ItemName +from ..AutoWorld import LogicMixin +from ..generic.Rules import add_rule, set_rule + + +def set_rules(world: MultiWorld, player: int): + + if world.goal[player] == "yoshi_egg_hunt": + required_yoshi_eggs = max(math.floor( + world.number_of_yoshi_eggs[player].value * (world.percentage_of_yoshi_eggs[player].value / 100.0)), 1) + + add_rule(world.get_location(LocationName.yoshis_house, player), + lambda state: state.has(ItemName.yoshi_egg, player, required_yoshi_eggs)) + else: + add_rule(world.get_location(LocationName.bowser, player), lambda state: state.has(ItemName.mario_carry, player)) + + world.completion_condition[player] = lambda state: state.has(ItemName.victory, player) diff --git a/worlds/smw/__init__.py b/worlds/smw/__init__.py new file mode 100644 index 00000000..46ce4de7 --- /dev/null +++ b/worlds/smw/__init__.py @@ -0,0 +1,253 @@ +import os +import typing +import math +import threading + +from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification +from .Items import SMWItem, ItemData, item_table +from .Locations import SMWLocation, all_locations, setup_locations +from .Options import smw_options +from .Regions import create_regions, connect_regions +from .Levels import full_level_list, generate_level_list, location_id_to_level_id +from .Rules import set_rules +from ..generic.Rules import add_rule +from .Names import ItemName, LocationName +from ..AutoWorld import WebWorld, World +from .Rom import LocalRom, patch_rom, get_base_rom_path, SMWDeltaPatch +import Patch + + +class SMWWeb(WebWorld): + theme = "grass" + + setup_en = Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Super Mario World randomizer connected to an Archipelago Multiworld.", + "English", + "setup_en.md", + "setup/en", + ["PoryGone"] + ) + + tutorials = [setup_en] + + +class SMWWorld(World): + """ + Super Mario World is an action platforming game. + The Princess has been kidnapped by Bowser again, but Mario has somehow + lost all of his abilities. Can he get them back in time to save the Princess? + """ + game: str = "Super Mario World" + option_definitions = smw_options + topology_present = False + data_version = 1 + required_client_version = (0, 3, 5) + + item_name_to_id = {name: data.code for name, data in item_table.items()} + location_name_to_id = all_locations + + active_level_dict: typing.Dict[int,int] + web = SMWWeb() + + def __init__(self, world: MultiWorld, player: int): + self.rom_name_available_event = threading.Event() + super().__init__(world, player) + + @classmethod + def stage_assert_generate(cls, world): + rom_file = get_base_rom_path() + if not os.path.exists(rom_file): + raise FileNotFoundError(rom_file) + + def _get_slot_data(self): + return { + #"death_link": self.world.death_link[self.player].value, + "active_levels": self.active_level_dict, + } + + def _create_items(self, name: str): + data = item_table[name] + return [self.create_item(name)] * data.quantity + + def fill_slot_data(self) -> dict: + slot_data = self._get_slot_data() + for option_name in smw_options: + option = getattr(self.world, option_name)[self.player] + slot_data[option_name] = option.value + + return slot_data + + def generate_basic(self): + itempool: typing.List[SMWItem] = [] + + self.active_level_dict = dict(zip(generate_level_list(self.world, self.player), full_level_list)) + self.topology_present = self.world.level_shuffle[self.player] + + connect_regions(self.world, self.player, self.active_level_dict) + + # Add Boss Token amount requirements for Worlds + add_rule(self.world.get_region(LocationName.donut_plains_1_tile, self.player).entrances[0], lambda state: state.has(ItemName.koopaling, self.player, 1)) + add_rule(self.world.get_region(LocationName.vanilla_dome_1_tile, self.player).entrances[0], lambda state: state.has(ItemName.koopaling, self.player, 2)) + add_rule(self.world.get_region(LocationName.forest_of_illusion_1_tile, self.player).entrances[0], lambda state: state.has(ItemName.koopaling, self.player, 4)) + add_rule(self.world.get_region(LocationName.chocolate_island_1_tile, self.player).entrances[0], lambda state: state.has(ItemName.koopaling, self.player, 5)) + add_rule(self.world.get_region(LocationName.valley_of_bowser_1_tile, self.player).entrances[0], lambda state: state.has(ItemName.koopaling, self.player, 6)) + + total_required_locations = 96 + if self.world.dragon_coin_checks[self.player]: + total_required_locations += 49 + + itempool += [self.create_item(ItemName.mario_run)] + itempool += [self.create_item(ItemName.mario_carry)] + itempool += [self.create_item(ItemName.mario_swim)] + itempool += [self.create_item(ItemName.mario_spin_jump)] + itempool += [self.create_item(ItemName.mario_climb)] + itempool += [self.create_item(ItemName.yoshi_activate)] + itempool += [self.create_item(ItemName.p_switch)] + itempool += [self.create_item(ItemName.p_balloon)] + itempool += [self.create_item(ItemName.super_star_active)] + itempool += [self.create_item(ItemName.progressive_powerup)] * 3 + itempool += [self.create_item(ItemName.yellow_switch_palace)] + itempool += [self.create_item(ItemName.green_switch_palace)] + itempool += [self.create_item(ItemName.red_switch_palace)] + itempool += [self.create_item(ItemName.blue_switch_palace)] + + if self.world.goal[self.player] == "yoshi_egg_hunt": + itempool += [self.create_item(ItemName.yoshi_egg)] * self.world.number_of_yoshi_eggs[self.player] + self.world.get_location(LocationName.yoshis_house, self.player).place_locked_item(self.create_item(ItemName.victory)) + else: + self.world.get_location(LocationName.bowser, self.player).place_locked_item(self.create_item(ItemName.victory)) + + junk_count = total_required_locations - len(itempool) + trap_weights = [] + trap_weights += ([ItemName.ice_trap] * self.world.ice_trap_weight[self.player].value) + trap_weights += ([ItemName.stun_trap] * self.world.stun_trap_weight[self.player].value) + trap_weights += ([ItemName.literature_trap] * self.world.literature_trap_weight[self.player].value) + trap_count = 0 if (len(trap_weights) == 0) else math.ceil(junk_count * (self.world.trap_fill_percentage[self.player].value / 100.0)) + junk_count -= trap_count + + trap_pool = [] + for i in range(trap_count): + trap_item = self.world.random.choice(trap_weights) + trap_pool += [self.create_item(trap_item)] + + itempool += trap_pool + + itempool += [self.create_item(ItemName.one_up_mushroom)] * junk_count + + boss_location_names = [LocationName.yoshis_island_koopaling, LocationName.donut_plains_koopaling, LocationName.vanilla_dome_koopaling, + LocationName.twin_bridges_koopaling, LocationName.forest_koopaling, LocationName.chocolate_koopaling, + LocationName.valley_koopaling, LocationName.vanilla_reznor, LocationName.forest_reznor, LocationName.chocolate_reznor, LocationName.valley_reznor] + + for location_name in boss_location_names: + self.world.get_location(location_name, self.player).place_locked_item(self.create_item(ItemName.koopaling)) + + self.world.itempool += itempool + + + def generate_output(self, output_directory: str): + try: + world = self.world + player = self.player + + rom = LocalRom(get_base_rom_path()) + patch_rom(self.world, rom, self.player, self.active_level_dict) + + outfilepname = f'_P{player}' + outfilepname += f"_{world.player_name[player].replace(' ', '_')}" \ + if world.player_name[player] != 'Player%d' % player else '' + + rompath = os.path.join(output_directory, f'AP_{world.seed_name}{outfilepname}.sfc') + rom.write_to_file(rompath) + self.rom_name = rom.name + + patch = SMWDeltaPatch(os.path.splitext(rompath)[0]+SMWDeltaPatch.patch_file_ending, player=player, + player_name=world.player_name[player], patched_path=rompath) + patch.write() + except: + raise + finally: + if os.path.exists(rompath): + os.unlink(rompath) + self.rom_name_available_event.set() # make sure threading continues and errors are collected + + def modify_multidata(self, multidata: dict): + import base64 + # wait for self.rom_name to be available. + self.rom_name_available_event.wait() + rom_name = getattr(self, "rom_name", None) + # we skip in case of error, so that the original error in the output thread is the one that gets raised + if rom_name: + new_name = base64.b64encode(bytes(self.rom_name)).decode() + multidata["connect_names"][new_name] = multidata["connect_names"][self.world.player_name[self.player]] + + def extend_hint_information(self, hint_data: typing.Dict[int, typing.Dict[int, str]]): + if self.topology_present: + world_names = [ + LocationName.yoshis_island_region, + LocationName.donut_plains_region, + LocationName.vanilla_dome_region, + LocationName.twin_bridges_region, + LocationName.forest_of_illusion_region, + LocationName.chocolate_island_region, + LocationName.valley_of_bowser_region, + LocationName.star_road_region, + LocationName.special_zone_region, + ] + world_cutoffs = [ + 0x07, + 0x13, + 0x1F, + 0x26, + 0x30, + 0x39, + 0x44, + 0x4F, + 0x59 + ] + er_hint_data = {} + for loc_name, level_data in location_id_to_level_id.items(): + level_id = level_data[0] + + if level_id not in self.active_level_dict: + continue + + keys_list = list(self.active_level_dict.keys()) + level_index = keys_list.index(level_id) + for i in range(len(world_cutoffs)): + if level_index >= world_cutoffs[i]: + continue + + if self.world.dragon_coin_checks[self.player].value == 0 and "Dragon Coins" in loc_name: + continue + + location = self.world.get_location(loc_name, self.player) + er_hint_data[location.address] = world_names[i] + break + + hint_data[self.player] = er_hint_data + + def create_regions(self): + location_table = setup_locations(self.world, self.player) + create_regions(self.world, self.player, location_table) + + def create_item(self, name: str, force_non_progression=False) -> Item: + data = item_table[name] + + if force_non_progression: + classification = ItemClassification.filler + elif name == ItemName.yoshi_egg: + classification = ItemClassification.progression_skip_balancing + elif data.progression: + classification = ItemClassification.progression + elif data.trap: + classification = ItemClassification.trap + else: + classification = ItemClassification.filler + + created_item = SMWItem(name, classification, data.code, self.player) + + return created_item + + def set_rules(self): + set_rules(self.world, self.player) diff --git a/worlds/smw/docs/en_Super Mario World.md b/worlds/smw/docs/en_Super Mario World.md new file mode 100644 index 00000000..87a96e55 --- /dev/null +++ b/worlds/smw/docs/en_Super Mario World.md @@ -0,0 +1,43 @@ +# Super Mario World + +## Where is the settings page? + +The [player settings page for this game](../player-settings) contains all the options you need to configure and export a config file. + +## What does randomization do to this game? + +Mario's basic abilities are removed, and placed into the item pool as items that any player can find. This includes: +- Carry +- Climb +- Run +- P-Switch +- Swim +- Spin Jump +- Yoshi + +Additionally, the ability to use powerups (Mushrooms, Fire Flowers, Capes, Stars, and P-Balloons) are shuffled into the item pool, as are the Four Switch Palaces. + +## What is the goal of Super Mario World when randomized? + +There are two goals which can be chosen: +- `Bowser`: Reach Bowser's Castle and defeat Bowser, after defeating a certain number of bosses. +- `Yoshi Egg Hunt`: Collect a certain number of Yoshi Eggs, then return to Yoshi's House + +## What items and locations get shuffled? + +Each unique level exit awards a location check. Optionally, collecting five Dragon Coins in each level can also award a location check. +Mario's various abilities and powerups as described above are placed into the item pool. +If the player is playing Yoshi Egg Hunt, a certain number of Yoshi Eggs will be placed into the item pool. +Any additional items that are needed to fill out the item pool with be 1-Up Mushrooms. + +## Which items can be in another player's world? + +Any shuffled item can be in other players' worlds. + +## What does another world's item look like in Super Mario World + +Items do not have an appearance in Super Mario World. + +## When the player receives an item, what happens? + +The player can choose to receive a text box in-game when they receive an item. Regardless of that choice, items will be queued, and granted when the player next enters a level. diff --git a/worlds/smw/docs/setup_en.md b/worlds/smw/docs/setup_en.md new file mode 100644 index 00000000..178b7392 --- /dev/null +++ b/worlds/smw/docs/setup_en.md @@ -0,0 +1,149 @@ +# Super Mario World Randomizer Setup Guide + +## Required Software + +- [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases). Make sure to check the box for `SNI Client - Super Mario World Patch Setup` + + +- Hardware or software capable of loading and playing SNES ROM files + - An emulator capable of connecting to SNI such as: + - snes9x-rr from: [snes9x rr](https://github.com/gocha/snes9x-rr/releases), + - BizHawk from: [BizHawk Website](http://tasvideos.org/BizHawk.html) + - RetroArch 1.10.3 or newer from: [RetroArch Website](https://retroarch.com?page=platforms). Or, + - An SD2SNES, FXPak Pro ([FXPak Pro Store Page](https://krikzz.com/store/home/54-fxpak-pro.html)), or other + compatible hardware +- Your legally obtained Super Mario World ROM file, probably named `Super Mario World (USA).sfc` + +## Installation Procedures + +### Windows Setup + +1. During the installation of Archipelago, you will have been asked to install the SNI Client. If you did not do this, + or you are on an older version, you may run the installer again to install the SNI Client. +2. During setup, you will be asked to locate your base ROM file. This is your Super Mario World ROM file. +3. If you are using an emulator, you should assign your Lua capable emulator as your default program for launching ROM + files. + 1. Extract your emulator's folder to your Desktop, or somewhere you will remember. + 2. Right-click on a ROM file and select **Open with...** + 3. Check the box next to **Always use this app to open .sfc files** + 4. Scroll to the bottom of the list and click the grey text **Look for another App on this PC** + 5. Browse for your emulator's `.exe` file and click **Open**. This file should be located inside the folder you + extracted in step one. + +## Create a Config (.yaml) File + +### What is a config file and why do I need one? + +See the guide on setting up a basic YAML at the Archipelago setup +guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en) + +### Where do I get a config file? + +The Player Settings page on the website allows you to configure your personal settings and export a config file from +them. Player settings page: [Super Mario World Player Settings Page](/games/Super%20Mario%20World/player-settings) + +### Verifying your config file + +If you would like to validate your config file to make sure it works, you may do so on the YAML Validator page. YAML +validator page: [YAML Validation page](/mysterycheck) + +## Joining a MultiWorld Game + +### Obtain your patch file and create your ROM + +When you join a multiworld game, you will be asked to provide your config file to whomever is hosting. Once that is done, +the host will provide you with either a link to download your patch file, or with a zip file containing everyone's patch +files. Your patch file should have a `.apsmw` extension. + +Put your patch file on your desktop or somewhere convenient, and double click it. This should automatically launch the +client, and will also create your ROM in the same place as your patch file. + +### Connect to the client + +#### With an emulator + +When the client launched automatically, SNI should have also automatically launched in the background. If this is its +first time launching, you may be prompted to allow it to communicate through the Windows Firewall. + +##### snes9x-rr + +1. Load your ROM file if it hasn't already been loaded. +2. Click on the File menu and hover on **Lua Scripting** +3. Click on **New Lua Script Window...** +4. In the new window, click **Browse...** +5. Select the connector lua file included with your client + - Look in the Archipelago folder for `/SNI/lua/x64` or `/SNI/lua/x86` depending on if the + emulator is 64-bit or 32-bit. +6. If you see an error while loading the script that states `socket.dll missing` or similar, navigate to the folder of +the lua you are using in your file explorer and copy the `socket.dll` to the base folder of your snes9x install. + +##### BizHawk + +1. Ensure you have the BSNES core loaded. You may do this by clicking on the Tools menu in BizHawk and following these + menu options: + `Config --> Cores --> SNES --> BSNES` + Once you have changed the loaded core, you must restart BizHawk. +2. Load your ROM file if it hasn't already been loaded. +3. Click on the Tools menu and click on **Lua Console** +4. Click the button to open a new Lua script. +5. Select the `Connector.lua` file included with your client + - Look in the Archipelago folder for `/SNI/lua/x64` or `/SNI/lua/x86` depending on if the + emulator is 64-bit or 32-bit. Please note the most recent versions of BizHawk are 64-bit only. + +##### RetroArch 1.10.3 or newer + +You only have to do these steps once. Note, RetroArch 1.9.x will not work as it is older than 1.10.3. + +1. Enter the RetroArch main menu screen. +2. Go to Settings --> User Interface. Set "Show Advanced Settings" to ON. +3. Go to Settings --> Network. Set "Network Commands" to ON. (It is found below Request Device 16.) Leave the default + Network Command Port at 55355. + +![Screenshot of Network Commands setting](/static/generated/docs/A%20Link%20to%20the%20Past/retroarch-network-commands-en.png) +4. Go to Main Menu --> Online Updater --> Core Downloader. Scroll down and select "Nintendo - SNES / SFC (bsnes-mercury + Performance)". + +When loading a ROM, be sure to select a **bsnes-mercury** core. These are the only cores that allow external tools to +read ROM data. + +#### With hardware + +This guide assumes you have downloaded the correct firmware for your device. If you have not done so already, please do +this now. SD2SNES and FXPak Pro users may download the appropriate firmware on the SD2SNES releases page. SD2SNES +releases page: [SD2SNES Releases Page](https://github.com/RedGuyyyy/sd2snes/releases) + +Other hardware may find helpful information on the usb2snes platforms +page: [usb2snes Supported Platforms Page](http://usb2snes.com/#supported-platforms) + +1. Close your emulator, which may have auto-launched. +2. Power on your device and load the ROM. + +### Connect to the Archipelago Server + +The patch file which launched your client should have automatically connected you to the AP Server. There are a few +reasons this may not happen however, including if the game is hosted on the website but was generated elsewhere. If the +client window shows "Server Status: Not Connected", simply ask the host for the address of the server, and copy/paste it +into the "Server" input field then press enter. + +The client will attempt to reconnect to the new server address, and should momentarily show "Server Status: Connected". + +### Play the game + +When the client shows both SNES Device and Server as connected, you're ready to begin playing. Congratulations on +successfully joining a multiworld game! + +## Hosting a MultiWorld game + +The recommended way to host a game is to use our hosting service. The process is relatively simple: + +1. Collect config files from your players. +2. Create a zip file containing your players' config files. +3. Upload that zip file to the Generate page above. + - Generate page: [WebHost Seed Generation Page](/generate) +4. Wait a moment while the seed is generated. +5. When the seed is generated, you will be redirected to a "Seed Info" page. +6. Click "Create New Room". This will take you to the server page. Provide the link to this page to your players, so + they may download their patch files from there. +7. Note that a link to a MultiWorld Tracker is at the top of the room page. The tracker shows the progress of all + players in the game. Any observers may also be given the link to this page. +8. Once all players have joined, you may begin playing.