diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c35ff50f..d3c9be35b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,7 @@ if(SRB2_CONFIG_ENABLE_TESTS) # https://github.com/catchorg/Catch2 CPMAddPackage( NAME Catch2 - VERSION 3.1.1 + VERSION 3.4.0 GITHUB_REPOSITORY catchorg/Catch2 OPTIONS "CATCH_INSTALL_DOCS OFF" diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 8567a782c..c7ff38591 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -43,6 +43,7 @@ #include "../k_podium.h" #include "../k_bot.h" #include "../z_zone.h" +#include "../music.h" #include "../r_draw.h" #include "../k_dialogue.hpp" @@ -1848,6 +1849,7 @@ bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wor if (argV[1] == 0) skipstats = 1; + G_BeginLevelExit(); exitcountdown = 1; if (server) @@ -1980,6 +1982,49 @@ bool CallFunc_DialogueSetCustomSpeaker(ACSVM::Thread *thread, const ACSVM::Word return false; } +/*-------------------------------------------------- + bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Halts the level exit if it's happening. +--------------------------------------------------*/ +bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + (void)argV; + (void)argC; + + exitcountdown = 0; + return false; +} + +/*-------------------------------------------------- + bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Exits the level. +--------------------------------------------------*/ +bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + (void)argV; + (void)argC; + + if (exitcountdown == 1) + { + // An exit is already in progress. + return false; + } + + if (argC >= 1) + { + skipstats = (argV[0] == 0); + } + + G_BeginLevelExit(); + exitcountdown = 1; + + if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0); + return false; +} + /*-------------------------------------------------- bool CallFunc_DialogueNewText(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) @@ -2003,6 +2048,47 @@ bool CallFunc_DialogueNewText(ACSVM::Thread *thread, const ACSVM::Word *argV, AC return false; } +/*-------------------------------------------------- + bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Play a tune. If it's already playing, restart from the + beginning. +--------------------------------------------------*/ +bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + ACSVM::MapScope *map = thread->scopeMap; + + Music_Play(map->getString(argV[0])->str); + + return false; +} + +/*-------------------------------------------------- + bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Stop every tune that is currently playing. +--------------------------------------------------*/ +bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + Music_StopAll(); + + return false; +} + +/*-------------------------------------------------- + bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Change the actual song lump that a tune will play. +--------------------------------------------------*/ +bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + ACSVM::MapScope *map = thread->scopeMap; + + Music_Remap(map->getString(argV[0])->str, map->getString(argV[1])->str); + + return false; +} + /*-------------------------------------------------- bool CallFunc_Get/SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) diff --git a/src/acs/call-funcs.hpp b/src/acs/call-funcs.hpp index 49f2fa9fa..48ce72e84 100644 --- a/src/acs/call-funcs.hpp +++ b/src/acs/call-funcs.hpp @@ -89,6 +89,11 @@ bool CallFunc_SetLineRenderStyle(ACSVM::Thread *thread, const ACSVM::Word *argV, bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_DialogueSetSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_DialogueSetCustomSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index e99ed033a..ad0c3e106 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -172,6 +172,11 @@ Environment::Environment() addFuncDataACS0( 503, addCallFunc(CallFunc_SetLineRenderStyle)); addFuncDataACS0( 504, addCallFunc(CallFunc_MapWarp)); addFuncDataACS0( 505, addCallFunc(CallFunc_AddBot)); + addFuncDataACS0( 506, addCallFunc(CallFunc_StopLevelExit)); + addFuncDataACS0( 507, addCallFunc(CallFunc_ExitLevel)); + addFuncDataACS0( 508, addCallFunc(CallFunc_MusicPlay)); + addFuncDataACS0( 509, addCallFunc(CallFunc_MusicStopAll)); + addFuncDataACS0( 510, addCallFunc(CallFunc_MusicRemap)); addFuncDataACS0( 600, addCallFunc(CallFunc_DialogueSetSpeaker)); addFuncDataACS0( 601, addCallFunc(CallFunc_DialogueSetCustomSpeaker)); diff --git a/src/acs/interface.cpp b/src/acs/interface.cpp index bba86c3b9..4c14a8e2e 100644 --- a/src/acs/interface.cpp +++ b/src/acs/interface.cpp @@ -315,6 +315,22 @@ void ACS_RunEmeraldScript(mobj_t *mo) map->scriptStartType(ACS_ST_EMERALD, scriptInfo); } +/*-------------------------------------------------- + void ACS_RunGameOverScript(void) + + See header file for description. +--------------------------------------------------*/ +void ACS_RunGameOverScript(void) +{ + Environment *env = &ACSEnv; + + ACSVM::GlobalScope *const global = env->getGlobalScope(0); + ACSVM::HubScope *const hub = global->getHubScope(0); + ACSVM::MapScope *const map = hub->getMapScope(0); + + map->scriptStartType(ACS_ST_GAMEOVER, {}); +} + /*-------------------------------------------------- void ACS_Tick(void) diff --git a/src/acs/interface.h b/src/acs/interface.h index 206414663..5e9c9ba9f 100644 --- a/src/acs/interface.h +++ b/src/acs/interface.h @@ -179,6 +179,17 @@ void ACS_RunCatcherScript(mobj_t *mo); void ACS_RunEmeraldScript(mobj_t *mo); +/*-------------------------------------------------- + void ACS_RunGameOverScript(void); + + Runs the map's special scripts for exiting + the level, due to a losing condition and + without any extra lives to retry. +--------------------------------------------------*/ + +void ACS_RunGameOverScript(void); + + /*-------------------------------------------------- void ACS_Tick(void); diff --git a/src/acs/thread.hpp b/src/acs/thread.hpp index 97caf5447..0b20271af 100644 --- a/src/acs/thread.hpp +++ b/src/acs/thread.hpp @@ -42,6 +42,7 @@ enum acs_scriptType_e ACS_ST_OVERTIME = 7, // OVERTIME: Runs when Overtime starts in timed game modes. ACS_ST_UFO = 8, // UFO: Runs when the UFO Catcher is destroyed in a Special Stage. ACS_ST_EMERALD = 9, // EMERALD: Runs when the Chaos Emerald is collected in a Special Stage. + ACS_ST_GAMEOVER = 10, // GAMEOVER: Runs when the level ends due to a losing condition and no player has an extra life. }; // diff --git a/src/d_main.c b/src/d_main.c index 1028e192c..432a20e72 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1517,7 +1517,8 @@ void D_SRB2Main(void) // // search for mainwad maps // - P_InitMapData(false); + P_InitMapData(); + basenummapheaders = nummapheaders; CON_SetLoadingProgress(LOADED_IWAD); @@ -1528,7 +1529,7 @@ void D_SRB2Main(void) // // search for pwad maps // - P_InitMapData(true); + P_InitMapData(); CON_SetLoadingProgress(LOADED_PWAD); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f49647810..7ad288f25 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -242,11 +242,6 @@ static void Command_Eval(void); static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}}; -#ifdef LJOYSTICK -static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, {3, "/dev/js2"}, - {4, "/dev/js3"}, {0, NULL}}; -#endif - static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}}; static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; @@ -287,12 +282,12 @@ consvar_t cv_playername[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("name4", "Knuckles", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name4_OnChange) }; // player colors -UINT16 lastgoodcolor[MAXSPLITSCREENPLAYERS] = {SKINCOLOR_BLUE, SKINCOLOR_BLUE, SKINCOLOR_BLUE, SKINCOLOR_BLUE}; +UINT16 lastgoodcolor[MAXSPLITSCREENPLAYERS] = {SKINCOLOR_NONE, SKINCOLOR_NONE, SKINCOLOR_NONE, SKINCOLOR_NONE}; consvar_t cv_playercolor[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("color", "Red", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color1_OnChange), - CVAR_INIT ("color2", "Orange", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange), - CVAR_INIT ("color3", "Blue", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color3_OnChange), - CVAR_INIT ("color4", "Red", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color4_OnChange) + CVAR_INIT ("color", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color1_OnChange), + CVAR_INIT ("color2", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange), + CVAR_INIT ("color3", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color3_OnChange), + CVAR_INIT ("color4", "Default", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color4_OnChange) }; // player's skin, saved for commodity, when using a favorite skins wad.. consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = { @@ -344,7 +339,6 @@ consvar_t cv_skipmapcheck = CVAR_INIT ("skipmapcheck", "Off", CV_SAVE, CV_OnOff, consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse); -#if (defined (LJOYSTICK) || defined (HAVE_SDL)) consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale), CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2), @@ -352,23 +346,6 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("padscale4", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale4) }; -#ifdef LJOYSTICK -consvar_t cv_joyport[MAXSPLITSCREENPLAYERS] = { //Alam: for later - CVAR_INIT ("padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL), - CVAR_INIT ("padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL), - CVAR_INIT ("padport3", "/dev/js0", CV_SAVE, joyport_cons_t, NULL), - CVAR_INIT ("padport4", "/dev/js0", CV_SAVE, joyport_cons_t, NULL) -}; -#endif -#else -consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save - CVAR_INIT ("padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL), - CVAR_INIT ("padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL), - CVAR_INIT ("padscale3", "1", CV_SAVE|CV_HIDEN, NULL, NULL), - CVAR_INIT ("padscale4", "1", CV_SAVE|CV_HIDEN, NULL, NULL) -}; -#endif - // SRB2kart consvar_t cv_items[NUMKARTRESULTS-1] = { CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL), @@ -1079,9 +1056,6 @@ void D_RegisterClientCommands(void) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { CV_RegisterVar(&cv_joyscale[i]); -#ifdef LJOYSTICK - CV_RegisterVar(&cv_joyport[i]); -#endif } // s_sound.c @@ -1102,12 +1076,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_soundtest); - CV_RegisterVar(&cv_invincmusicfade); - CV_RegisterVar(&cv_growmusicfade); - - CV_RegisterVar(&cv_resetspecialmusic); - - CV_RegisterVar(&cv_resume); CV_RegisterVar(&cv_perfstats); // ingame object placing @@ -1516,7 +1484,7 @@ static void SendNameAndColor(const UINT8 n) CV_StealthSetValue(&cv_playercolor[n], SKINCOLOR_NONE); } - sendColor = cv_playercolor[n].value; + lastgoodcolor[playernum] = sendColor = cv_playercolor[n].value; } // ditto for follower colour: @@ -5776,7 +5744,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) if (G_GamestateUsesExitLevel() == false) return; - G_ExitLevel(); + G_FinishExitLevel(); } static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) @@ -6833,14 +6801,11 @@ static void Skin_OnChange(const UINT8 p) return; } - if (p == 0) + if (!CV_CheatsEnabled() && !(netgame || K_CanChangeRules(false)) + && (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y { - if (!CV_CheatsEnabled() && !(multiplayer || netgame) // In single player. - && (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y - { - CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name); - return; - } + CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name); + return; } if (CanChangeSkin(g_localplayers[p])) @@ -6890,7 +6855,7 @@ static void Color_OnChange(const UINT8 p) UINT16 color = cv_playercolor[p].value; boolean colorisgood = (color == SKINCOLOR_NONE || K_ColorUsable(color, false, true) == true); - if (Playing() && splitscreen < p) + if (Playing() && p <= splitscreen) { if (P_PlayerMoving(g_localplayers[p]) == true) { diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 1206bf7dc..acf6b8336 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -48,9 +48,6 @@ extern consvar_t cv_splitplayers; extern consvar_t cv_seenames; extern consvar_t cv_usemouse; extern consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS]; -#ifdef LJOYSTICK -extern consvar_t cv_joyport[MAXSPLITSCREENPLAYERS]; -#endif // normally in p_mobj but the .h is not read extern consvar_t cv_itemrespawntime; diff --git a/src/deh_lua.c b/src/deh_lua.c index 7b9555104..db3d4cbc5 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -142,6 +142,7 @@ static inline int lib_freeslot(lua_State *L) CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); strcpy(FREE_SKINCOLORS[i],word); + skincolors[i].cache_spraycan = UINT16_MAX; numskincolors++; lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT + i); r++; diff --git a/src/deh_soc.c b/src/deh_soc.c index 7e5613444..76488462e 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -216,6 +216,13 @@ void clear_levels(void) } } + if (gamedata && gamedata->spraycans) + { + UINT16 i; + for (i = 0; i < gamedata->numspraycans; i++) + gamedata->spraycans[i].map = NEXTMAP_INVALID; + } + // Exit the current gamemap as a safeguard if (Playing()) COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed @@ -319,6 +326,7 @@ void readfreeslots(MYFILE *f) CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); strcpy(FREE_SKINCOLORS[i],word); + skincolors[i].cache_spraycan = UINT16_MAX; numskincolors++; break; } @@ -2534,6 +2542,14 @@ static void readcondition(UINT16 set, UINT32 id, char *word2) return; } } + else if (fastcmp(params[0], "CHARACTERWINS")) + { + PARAMCHECK(2); + ty = UC_CHARACTERWINS; + stringvar = Z_StrDup(params[1]); + re = -1; + x1 = atoi(params[2]); + } else if ((offset=0) || fastcmp(params[0], "ALLCHAOS") || (++offset && fastcmp(params[0], "ALLSUPER")) || (++offset && fastcmp(params[0], "ALLEMERALDS"))) @@ -2613,6 +2629,15 @@ static void readcondition(UINT16 set, UINT32 id, char *word2) stringvar = Z_StrDup(params[1]); re = -1; } + else if (fastcmp(params[0], "SPRAYCAN")) + { + PARAMCHECK(1); + ty = UC_SPRAYCAN; + re = get_skincolor(params[1]); + + // Force at head of the list? + x1 = (params[2] && (params[2][0] == 'Y' || params[2][0] == 'T')) ? 1 : 0; + } else if ((offset=0) || fastcmp(params[0], "AND") || (++offset && fastcmp(params[0], "COMMA"))) { @@ -2645,22 +2670,8 @@ static void readcondition(UINT16 set, UINT32 id, char *word2) { PARAMCHECK(1); ty = UCRP_ISCHARACTER; -#if 0 - { - re = R_SkinAvailable(params[1]); - - if (re < 0) - { - deh_warning("Invalid character %s for condition ID %d", params[1], id+1); - return; - } - } -#else - { - stringvar = Z_StrDup(params[1]); - re = -1; - } -#endif + stringvar = Z_StrDup(params[1]); + re = -1; } else if (fastcmp(params[0], "ISENGINECLASS")) { @@ -3007,6 +3018,7 @@ void readmaincfg(MYFILE *f, boolean mainfile) strlwr(gamedatafilename); savemoddata = true; majormods = false; + gamedata->loaded = false; // Also save a time attack folder filenamelen = strlen(gamedatafilename)-4; // Strip off the extension diff --git a/src/deh_tables.c b/src/deh_tables.c index e234782a7..8e7506af3 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1190,6 +1190,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_EMBLEM25", "S_EMBLEM26", + // Spray Can + "S_SPRAYCAN", + // Chaos Emeralds "S_CHAOSEMERALD1", "S_CHAOSEMERALD2", @@ -3923,24 +3926,6 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_APPLE7", "S_APPLE8", - // D00Dkart - Fall Flowers - "S_DOOD_FLOWER1", - "S_DOOD_FLOWER2", - "S_DOOD_FLOWER3", - "S_DOOD_FLOWER4", - "S_DOOD_FLOWER5", - "S_DOOD_FLOWER6", - - // D00Dkart - Super Circuit Box - "S_DOOD_BOX1", - "S_DOOD_BOX2", - "S_DOOD_BOX3", - "S_DOOD_BOX4", - "S_DOOD_BOX5", - - // D00Dkart - Diddy Kong Racing Bumper - "S_DOOD_BALLOON", - // Chaotix Big Ring "S_BIGRING01", "S_BIGRING02", @@ -4807,6 +4792,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_REDFLAG", // Red CTF Flag "MT_BLUEFLAG", // Blue CTF Flag "MT_EMBLEM", + "MT_SPRAYCAN", "MT_EMERALD", "MT_EMERALDSPARK", "MT_EMERALDFLARE", @@ -5583,12 +5569,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_BIGPUMA", "MT_APPLE", - "MT_DOOD_FLOWER1", - "MT_DOOD_FLOWER2", - "MT_DOOD_FLOWER3", - "MT_DOOD_FLOWER4", - "MT_DOOD_BOX", - "MT_DOOD_BALLOON", "MT_BIGRING", "MT_SNES_DONUTBUSH1", diff --git a/src/dehacked.c b/src/dehacked.c index c63ab376b..66567fb05 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -605,9 +605,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } // end while if (gamedataadded) + { + basenummapheaders = nummapheaders; G_LoadGameData(); + } - if (gamestate == GS_TITLESCREEN) + if (gamestate == GS_MENU || gamestate == GS_TITLESCREEN) { if (introchanged) { diff --git a/src/doomdef.h b/src/doomdef.h index 75264bbd0..9fffb78b4 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -232,6 +232,7 @@ struct skincolor_t UINT8 invshade; // Signpost color shade UINT16 chatcolor; // Chat color boolean accessible; // Accessible by the color command + setup menu + UINT16 cache_spraycan; // Cache for associated spraycan id }; #define FOLLOWERCOLOR_MATCH UINT16_MAX diff --git a/src/doomstat.h b/src/doomstat.h index c4f8b37e7..26ea96cdb 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -531,6 +531,9 @@ struct mapheader_t UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts. UINT8 cutscenenum; ///< Cutscene number to use, 0 for none. + UINT32 _saveid; ///< Purely assistive in gamedata save processes + UINT16 cache_spraycan; ///< Cached Spraycan ID + // Lua information UINT8 numCustomOptions; ///< Internal. For Lua custom value support. customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. @@ -548,7 +551,7 @@ struct mapheader_t #define LF2_FINISHNEEDED (1<<3) ///< Not available in Time Attack modes until you beat the level extern mapheader_t** mapheaderinfo; -extern INT32 nummapheaders, mapallocsize; +extern INT32 nummapheaders, basenummapheaders, mapallocsize; struct unloaded_mapheader_t { @@ -710,6 +713,8 @@ extern INT32 luabanks[NUM_LUABANKS]; extern INT32 nummaprings; //keep track of spawned rings/coins +extern UINT8 nummapspraycans; + extern UINT32 bluescore; ///< Blue Team Scores extern UINT32 redscore; ///< Red Team Scores @@ -762,8 +767,15 @@ extern UINT8 maxXtraLife; // Max extra lives from rings extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations +struct exitcondition_t +{ + boolean losing; + boolean retry; +}; + // For racing extern tic_t racecountdown, exitcountdown, musiccountdown; +extern exitcondition_t g_exit; #define DEFAULT_GRAVITY (4*FRACUNIT/5) extern fixed_t gravity; diff --git a/src/g_demo.c b/src/g_demo.c index 38a2e15bf..6708cfd84 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -4161,7 +4161,7 @@ boolean G_CheckDemoStatus(void) I_Quit(); if (multiplayer && !demo.title) - G_ExitLevel(); + G_FinishExitLevel(); else { G_StopDemo(); diff --git a/src/g_game.c b/src/g_game.c index 08fc60159..e26f13a48 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -193,6 +193,7 @@ quake_t *g_quakes = NULL; // Map Header Information mapheader_t** mapheaderinfo = {NULL}; INT32 nummapheaders = 0; +INT32 basenummapheaders = 0; INT32 mapallocsize = 0; unloaded_mapheader_t *unloadedmapheaders = NULL; @@ -219,6 +220,8 @@ UINT32 bluescore, redscore; // CTF and Team Match team scores // ring count... for PERFECT! INT32 nummaprings = 0; +UINT8 nummapspraycans = 0; + // Elminates unnecessary searching. boolean CheckForBustableBlocks; boolean CheckForBouncySector; @@ -274,6 +277,7 @@ mobj_t *hunt2; mobj_t *hunt3; tic_t racecountdown, exitcountdown, musiccountdown; // for racing +exitcondition_t g_exit; fixed_t gravity; fixed_t mapobjectscale; @@ -394,13 +398,6 @@ consvar_t cv_pauseifunfocused = CVAR_INIT ("pauseifunfocused", "Yes", CV_SAVE, C // Display song credits consvar_t cv_songcredits = CVAR_INIT ("songcredits", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_invincmusicfade = CVAR_INIT ("invincmusicfade", "300", CV_SAVE, CV_Unsigned, NULL); -consvar_t cv_growmusicfade = CVAR_INIT ("growmusicfade", "500", CV_SAVE, CV_Unsigned, NULL); - -consvar_t cv_resetspecialmusic = CVAR_INIT ("resetspecialmusic", "Yes", CV_SAVE, CV_YesNo, NULL); - -consvar_t cv_resume = CVAR_INIT ("resume", "Yes", CV_SAVE, CV_YesNo, NULL); - consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("kickstartaccel", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange), CVAR_INIT ("kickstartaccel2", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange2), @@ -805,9 +802,7 @@ const char *G_BuildMapName(INT32 map) */ INT32 G_MapNumber(const char * name) { -#ifdef NEXTMAPINSOC if (strncasecmp("NEXTMAP_", name, 8) != 0) -#endif { INT32 map; UINT32 hash = quickncasehash(name, MAXMAPLUMPNAME); @@ -826,7 +821,6 @@ INT32 G_MapNumber(const char * name) return NEXTMAP_INVALID; } -#ifdef NEXTMAPINSOC name += 8; if (strcasecmp("EVALUATION", name) == 0) @@ -835,9 +829,10 @@ INT32 G_MapNumber(const char * name) return NEXTMAP_CREDITS; if (strcasecmp("CEREMONY", name) == 0) return NEXTMAP_CEREMONY; - //if (strcasecmp("TITLE", name) == 0) + if (strcasecmp("TITLE", name) == 0) return NEXTMAP_TITLE; -#endif + + return NEXTMAP_INVALID; } /** Clips the console player's mouse aiming to the current view. @@ -1284,6 +1279,7 @@ void G_StartTitleCard(void) ST_startTitleCard(); // play the sound + if (gamestate != GS_CEREMONY) { sfxenum_t kstart = sfx_kstart; if (K_CheckBossIntro() == true) @@ -2927,95 +2923,116 @@ void G_AddPlayer(INT32 playernum) demo_extradata[playernum] |= DXD_JOINDATA|DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN|DXD_FOLLOWER; // Set everything } -void G_ExitLevel(void) +void G_BeginLevelExit(void) +{ + g_exit.losing = true; + g_exit.retry = false; + + if (grandprixinfo.gp == true) + { + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + K_PlayerFinishGrandPrix(&players[i]); + } + } + } + + if (!G_GametypeUsesLives() || skipstats != 0) + { + g_exit.losing = false; // never force a retry + } + else if (specialstageinfo.valid == true || (gametyperules & GTR_BOSS)) + { + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator && !players[i].bot) + { + if (!K_IsPlayerLosing(&players[i])) + { + g_exit.losing = false; + break; + } + } + } + } + else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE) + { + g_exit.losing = (grandprixinfo.wonround != true); + } + + if (g_exit.losing) + { + // You didn't win... + + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator && !players[i].bot) + { + if (players[i].lives > 0) + { + g_exit.retry = true; + break; + } + } + } + } + + if (g_exit.losing && specialstageinfo.valid) + { + exitcountdown = TICRATE; + } + else + { + exitcountdown = raceexittime+1; + } + + if (g_exit.losing) + { + if (!g_exit.retry) + { + ACS_RunGameOverScript(); + } + } +} + +void G_FinishExitLevel(void) { G_ResetAllDeviceRumbles(); if (gamestate == GS_LEVEL) { - UINT8 i; - boolean doretry = false; - - if (grandprixinfo.gp == true) + if (g_exit.retry) { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator) - { - K_PlayerFinishGrandPrix(&players[i]); - } - } - } - - if (!G_GametypeUsesLives() || skipstats != 0) - ; // never force a retry - else if (specialstageinfo.valid == true || (gametyperules & GTR_BOSS)) - { - doretry = true; - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator && !players[i].bot) - { - if (!K_IsPlayerLosing(&players[i])) - { - doretry = false; - break; - } - } - } - } - else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE) - { - doretry = (grandprixinfo.wonround != true); - } - - if (doretry) - { - // You didn't win... - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator && !players[i].bot) - { - if (players[i].lives > 0) - { - break; - } - } - } - - if (i == MAXPLAYERS) - { - // GAME OVER, try again from the start! - if (grandprixinfo.gp == true - && grandprixinfo.eventmode == GPEVENT_SPECIAL) - { - // We were in a Special Stage. - // We can still progress to the podium when we game over here. - doretry = false; - } - else if (netgame) - { - ; // Restart cup here whenever we do Online GP - } - else - { - // Back to the menu with you. - G_HandleSaveLevel(true); - D_QuitNetGame(); - CL_Reset(); - D_ClearState(); - M_StartControlPanel(); - } - } - else + // Restart cup here whenever we do Online GP + if (!netgame) { // We have lives, just redo this one course. G_SetRetryFlag(); + return; } + } + else if (g_exit.losing) + { + // We were in a Special Stage. + // We can still progress to the podium when we game over here. + const boolean special = grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_SPECIAL; - if (doretry == true) + if (!netgame && !special) { + // Back to the menu with you. + G_HandleSaveLevel(true); + D_QuitNetGame(); + CL_Reset(); + D_ClearState(); + M_StartControlPanel(); return; } } @@ -4390,7 +4407,7 @@ void G_LoadGameSettings(void) } #define GD_VERSIONCHECK 0xBA5ED123 // Change every major version, as usual -#define GD_VERSIONMINOR 5 // Change every format update +#define GD_VERSIONMINOR 6 // Change every format update typedef enum { @@ -4711,55 +4728,136 @@ void G_LoadGameData(void) } } + UINT16 *tempmapidreferences = NULL; + numgamedatamapheaders = READUINT32(save.p); - for (i = 0; i < numgamedatamapheaders; i++) + if (numgamedatamapheaders) { - char mapname[MAXMAPLUMPNAME]; - INT16 mapnum; + tempmapidreferences = Z_Malloc( + numgamedatamapheaders * sizeof (UINT16), + PU_STATIC, + NULL + ); - READSTRINGL(save.p, mapname, MAXMAPLUMPNAME); - mapnum = G_MapNumber(mapname); - - recorddata_t dummyrecord; - - dummyrecord.mapvisited = READUINT8(save.p); - dummyrecord.time = (tic_t)READUINT32(save.p); - dummyrecord.lap = (tic_t)READUINT32(save.p); - - if (mapnum < nummapheaders && mapheaderinfo[mapnum]) + for (i = 0; i < numgamedatamapheaders; i++) { - // Valid mapheader, time to populate with record data. + char mapname[MAXMAPLUMPNAME]; + UINT16 mapnum; - dummyrecord.mapvisited &= MV_MAX; - M_Memcpy(&mapheaderinfo[mapnum]->records, &dummyrecord, sizeof(recorddata_t)); + READSTRINGL(save.p, mapname, MAXMAPLUMPNAME); + mapnum = G_MapNumber(mapname); + + tempmapidreferences[i] = (UINT16)mapnum; + + recorddata_t dummyrecord; + + dummyrecord.mapvisited = READUINT8(save.p); + dummyrecord.time = (tic_t)READUINT32(save.p); + dummyrecord.lap = (tic_t)READUINT32(save.p); + + if (mapnum < nummapheaders && mapheaderinfo[mapnum]) + { + // Valid mapheader, time to populate with record data. + + dummyrecord.mapvisited &= MV_MAX; + M_Memcpy(&mapheaderinfo[mapnum]->records, &dummyrecord, sizeof(recorddata_t)); + } + else if ( + ((dummyrecord.mapvisited & MV_PERSISTUNLOADED) != 0 + && (dummyrecord.mapvisited & MV_BEATEN) != 0) + || dummyrecord.time != 0 + || dummyrecord.lap != 0 + ) + { + // Invalid, but we don't want to lose all the juicy statistics. + // Instead, update a FILO linked list of "unloaded mapheaders". + + unloaded_mapheader_t *unloadedmap = + Z_Malloc( + sizeof(unloaded_mapheader_t), + PU_STATIC, NULL + ); + + // Establish properties, for later retrieval on file add. + unloadedmap->lumpname = Z_StrDup(mapname); + unloadedmap->lumpnamehash = quickncasehash(unloadedmap->lumpname, MAXMAPLUMPNAME); + + // Insert at the head, just because it's convenient. + unloadedmap->next = unloadedmapheaders; + unloadedmapheaders = unloadedmap; + + // Finally, copy into. + M_Memcpy(&unloadedmap->records, &dummyrecord, sizeof(recorddata_t)); + } } - else if ( - ((dummyrecord.mapvisited & MV_PERSISTUNLOADED) != 0 - && (dummyrecord.mapvisited & MV_BEATEN) != 0) - || dummyrecord.time != 0 - || dummyrecord.lap != 0 - ) + } + + if (versionMinor > 5) + { + gamedata->gotspraycans = 0; + gamedata->numspraycans = READUINT16(save.p); + Z_Free(gamedata->spraycans); + + if (gamedata->numspraycans) { - // Invalid, but we don't want to lose all the juicy statistics. - // Instead, update a FILO linked list of "unloaded mapheaders". + gamedata->spraycans = Z_Malloc( + (gamedata->numspraycans * sizeof(candata_t)), + PU_STATIC, NULL); - unloaded_mapheader_t *unloadedmap = - Z_Malloc( - sizeof(unloaded_mapheader_t), - PU_STATIC, NULL - ); + for (i = 0; i < gamedata->numspraycans; i++) + { + gamedata->spraycans[i].col = SKINCOLOR_NONE; + gamedata->spraycans[i].map = NEXTMAP_INVALID; - // Establish properties, for later retrieval on file add. - unloadedmap->lumpname = Z_StrDup(mapname); - unloadedmap->lumpnamehash = quickncasehash(unloadedmap->lumpname, MAXMAPLUMPNAME); + UINT16 col = READUINT16(save.p); + UINT32 _saveid = READUINT32(save.p); - // Insert at the head, just because it's convenient. - unloadedmap->next = unloadedmapheaders; - unloadedmapheaders = unloadedmap; + if (col < SKINCOLOR_FIRSTFREESLOT) + { + gamedata->spraycans[i].col = col; + skincolors[col].cache_spraycan = i; + } - // Finally, copy into. - M_Memcpy(&unloadedmap->records, &dummyrecord, sizeof(recorddata_t)); + if (_saveid >= numgamedatamapheaders) + { + // Can has not been grabbed on any map, this is intentional. + continue; + } + + UINT16 map = tempmapidreferences[_saveid]; + if (map >= nummapheaders || !mapheaderinfo[map]) + { + //CONS_Printf("LOAD - Can %u, color %s - id %u (unloaded header)\n", i, skincolors[col].name, _saveid); + continue; + } + + //CONS_Printf("LOAD - Can %u, color %s - id %u, map %d\n", i, skincolors[col].name, _saveid, map); + + gamedata->spraycans[i].map = map; + + if (gamedata->gotspraycans != i) + { + //CONS_Printf("LOAD - Swapping gotten can %u, color %s with prior ungotten can %u\n", i, skincolors[col].name, gamedata->gotspraycans); + + // All grabbed cans should be at the head of the list. + // Let's swap with the can the disjoint occoured at. + // This will prevent a gap from occouring on reload. + candata_t copycan = gamedata->spraycans[gamedata->gotspraycans]; + gamedata->spraycans[gamedata->gotspraycans] = gamedata->spraycans[i]; + gamedata->spraycans[i] = copycan; + + mapheaderinfo[copycan.map]->cache_spraycan = i; + } + + mapheaderinfo[map]->cache_spraycan = gamedata->gotspraycans; + + gamedata->gotspraycans++; + } + } + else + { + gamedata->spraycans = NULL; } } @@ -4890,20 +4988,15 @@ void G_LoadGameData(void) if (tempskinreferences) Z_Free(tempskinreferences); + if (tempmapidreferences) + Z_Free(tempmapidreferences); // done P_SaveBufferFree(&save); finalisegamedata: { - // Don't consider loaded until it's a success! - // It used to do this much earlier, but this would cause the gamedata to - // save over itself when it I_Errors from the corruption landing point below, - // which can accidentally delete players' legitimate data if the code ever has any tiny mistakes! - gamedata->loaded = true; - - // Silent update unlockables in case they're out of sync with conditions - M_UpdateUnlockablesAndExtraEmblems(false, true); + M_FinaliseGameData(); return; } @@ -5018,12 +5111,16 @@ void G_SaveGameData(void) for (i = 0; i < nummapheaders; i++) { + // No spraycan attached. + if (mapheaderinfo[i]->cache_spraycan >= gamedata->numspraycans // It's safe to assume a level with no mapvisited will have no other data worth keeping, since you get MV_VISITED just for opening it. - if (!(mapheaderinfo[i]->records.mapvisited & MV_MAX)) + && !(mapheaderinfo[i]->records.mapvisited & MV_MAX)) { + mapheaderinfo[i]->_saveid = UINT32_MAX; continue; } + mapheaderinfo[i]->_saveid = numgamedatamapheaders; numgamedatamapheaders++; } @@ -5046,6 +5143,13 @@ void G_SaveGameData(void) length += 4 + (numgamedatamapheaders * (MAXMAPLUMPNAME+1+4+4)); + length += 2; + + if (gamedata->numspraycans) + { + length += (gamedata->numspraycans * (2 + 4)); + } + UINT32 numgamedatacups = 0; unloaded_cupheader_t *unloadedcup; @@ -5241,7 +5345,8 @@ void G_SaveGameData(void) for (i = 0; i < nummapheaders; i++) { - if (!(mapheaderinfo[i]->records.mapvisited & MV_MAX)) + if (mapheaderinfo[i]->cache_spraycan >= gamedata->numspraycans + && !(mapheaderinfo[i]->records.mapvisited & MV_MAX)) continue; WRITESTRINGL(save.p, mapheaderinfo[i]->lumpname, MAXMAPLUMPNAME); @@ -5281,7 +5386,28 @@ void G_SaveGameData(void) } } } + + WRITEUINT16(save.p, gamedata->numspraycans); // 2 + // gamedata->numspraycans * (2 + 4) + + for (i = 0; i < gamedata->numspraycans; i++) + { + WRITEUINT16(save.p, gamedata->spraycans[i].col); + + UINT32 _saveid = UINT32_MAX; + + UINT16 map = gamedata->spraycans[i].map; + + if (map < nummapheaders && mapheaderinfo[map]) + { + _saveid = mapheaderinfo[map]->_saveid; + } + + //CONS_Printf("SAVE - Can %u, color %s - id %u, map %d\n", i, skincolors[gamedata->spraycans[i].col].name, _saveid, map); + + WRITEUINT32(save.p, _saveid); + } WRITEUINT32(save.p, numgamedatacups); // 4 diff --git a/src/g_game.h b/src/g_game.h index 72e9ce005..e781f17ee 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -101,13 +101,6 @@ extern consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff; -extern consvar_t cv_invincmusicfade; -extern consvar_t cv_growmusicfade; - -extern consvar_t cv_resetspecialmusic; - -extern consvar_t cv_resume; - // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) #define MAXPLMOVE (50) @@ -206,7 +199,8 @@ boolean G_GametypeUsesLives(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); INT16 G_SometimesGetDifferentEncore(void); -void G_ExitLevel(void); +void G_BeginLevelExit(void); +void G_FinishExitLevel(void); void G_NextLevel(void); void G_GetNextMap(void); void G_Continue(void); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 145a6b464..ba480ea9a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4773,7 +4773,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if (spriterotangle != 0 && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) { - rollangle = R_GetRollAngle(vflip + rollangle = R_GetRollAngle(papersprite == vflip ? spriterotangle : InvAngle(spriterotangle)); rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); diff --git a/src/info.c b/src/info.c index 0980ee74b..a1fca74c2 100644 --- a/src/info.c +++ b/src/info.c @@ -636,7 +636,7 @@ char sprnames[NUMSPRITES + 1][5] = "POKE", // Pokey "AUDI", // Audience members "DECO", // Old 1.0 Kart Decoratives + New misc ones - "DOOD", // All the old D00Dkart objects + "SPCN", // Spray Can replaces all the old D00Dkart objects "SNES", // Sprites for SNES remake maps "GBAS", // Sprites for GBA remake maps "SPRS", // Sapphire Coast Spring Shell @@ -1862,6 +1862,9 @@ state_t states[NUMSTATES] = {SPR_EMBM, 24, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM25 {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 + // Spray Can + {SPR_SPCN, FF_ANIMATE|FF_SEMIBRIGHT, -1, {NULL}, 15, 2, S_NULL}, // S_SPRAYCAN + // Chaos Emeralds {SPR_EMRC, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 {SPR_EMRC, FF_FULLBRIGHT|FF_ADD, 1, {NULL}, 0, 0, S_CHAOSEMERALD1}, // S_CHAOSEMERALD2 @@ -4630,21 +4633,6 @@ state_t states[NUMSTATES] = {SPR_DECO, FF_FULLBRIGHT|20, 2, {NULL}, 0, 0, S_APPLE8}, //S_APPLE7 {SPR_DECO, FF_FULLBRIGHT|21, 2, {NULL}, 0, 0, S_APPLE1}, //S_APPLE8 - {SPR_DOOD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DOOD_FLOWER1 - {SPR_DOOD, 1, 14, {NULL}, 0, 0, S_DOOD_FLOWER3}, // S_DOOD_FLOWER2 - {SPR_DOOD, 2, 14, {NULL}, 0, 0, S_DOOD_FLOWER2}, // S_DOOD_FLOWER3 - {SPR_DOOD, 3, 7, {NULL}, 0, 0, S_DOOD_FLOWER5}, // S_DOOD_FLOWER4 - {SPR_DOOD, 4, 7, {NULL}, 0, 0, S_DOOD_FLOWER4}, // S_DOOD_FLOWER5 - {SPR_DOOD, 5, -1, {NULL}, 0, 0, S_NULL}, // S_DOOD_FLOWER6 - - {SPR_DOOD, 6, 2, {NULL}, 0, 0, S_DOOD_BOX2}, // S_DOOD_BOX1 - {SPR_DOOD, 7, 2, {NULL}, 0, 0, S_DOOD_BOX3}, // S_DOOD_BOX2 - {SPR_DOOD, 8, 2, {NULL}, 0, 0, S_DOOD_BOX4}, // S_DOOD_BOX3 - {SPR_DOOD, 9, 2, {NULL}, 0, 0, S_DOOD_BOX5}, // S_DOOD_BOX4 - {SPR_DOOD, 10, 2, {NULL}, 0, 0, S_DOOD_BOX1}, // S_DOOD_BOX5 - - {SPR_DOOD, 11, -1, {NULL}, 0, 0, S_NULL}, // S_DOOD_BALLOON - {SPR_BRNG, 0, 2, {NULL}, 0, 0, S_BIGRING02}, // S_BIGRING01 {SPR_BRNG, 1, 2, {NULL}, 0, 0, S_BIGRING03}, // S_BIGRING02 {SPR_BRNG, 2, 2, {NULL}, 0, 0, S_BIGRING04}, // S_BIGRING03 @@ -8276,7 +8264,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_SPRAYCAN + 2807, // doomednum + S_SPRAYCAN, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 30*FRACUNIT, // radius + 80*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, @@ -25704,168 +25719,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_DOOD_FLOWER1 - 2805, // doomednum - S_DOOD_FLOWER1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 1048576, // radius - 2097152, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - 33558528, // flags - S_NULL // raisestate - }, - - { // MT_DOOD_FLOWER2 - 2800, // doomednum - S_DOOD_FLOWER2, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 1048576, // radius - 2621440, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - 33558528, // flags - S_NULL // raisestate - }, - - { // MT_DOOD_FLOWER3 - 2801, // doomednum - S_DOOD_FLOWER4, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 1048576, // radius - 6291456, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - 33558528, // flags - S_NULL // raisestate - }, - - { // MT_DOOD_FLOWER4 - 2802, // doomednum - S_DOOD_FLOWER6, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 524288, // radius - 2097152, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - 33558528, // flags - S_NULL // raisestate - }, - - { // MT_DOOD_BOX - 2809, // doomednum - S_DOOD_BOX1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 1048576, // radius - 2097152, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - 33554944, // flags - S_NULL // raisestate - }, - - { // MT_DOOD_BALLOON - 2807, // doomednum - S_DOOD_BALLOON, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 91*FRACUNIT, // radius - 166*FRACUNIT, // height - 0, // display offset - 0, // mass - 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - { // MT_BIGRING 2808, // doomednum S_BIGRING01, // spawnstate @@ -30463,189 +30316,189 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }; skincolor_t skincolors[MAXSKINCOLORS] = { - {"Default", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_NONE + {"Default", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_NONE - {"White", { 0, 0, 0, 0, 1, 2, 5, 8, 9, 11, 14, 17, 20, 22, 25, 28}, SKINCOLOR_BLACK, 8, 0, true}, // SKINCOLOR_WHITE - {"Silver", { 0, 1, 2, 3, 5, 7, 9, 12, 13, 15, 18, 20, 23, 25, 27, 30}, SKINCOLOR_NICKEL, 8, 0, true}, // SKINCOLOR_SILVER - {"Grey", { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, SKINCOLOR_GREY, 8, V_LAVENDERMAP, true}, // SKINCOLOR_GREY - {"Nickel", { 3, 5, 8, 11, 15, 17, 19, 21, 23, 24, 25, 26, 27, 29, 30, 31}, SKINCOLOR_SILVER, 8, V_GRAYMAP, true}, // SKINCOLOR_NICKEL - {"Black", { 4, 7, 11, 15, 20, 22, 24, 27, 28, 28, 28, 29, 29, 30, 30, 31}, SKINCOLOR_WHITE, 8, V_GRAYMAP, true}, // SKINCOLOR_BLACK - {"Skunk", { 0, 1, 2, 3, 4, 10, 16, 21, 23, 24, 25, 26, 27, 28, 29, 31}, SKINCOLOR_VOMIT, 8, V_GRAYMAP, true}, // SKINCOLOR_SKUNK - {"Fairy", { 0, 0, 252, 252, 200, 201, 211, 14, 16, 18, 20, 22, 24, 26, 28, 31}, SKINCOLOR_ARTICHOKE, 12, V_PINKMAP, true}, // SKINCOLOR_FAIRY - {"Popcorn", { 0, 80, 80, 81, 82, 218, 240, 11, 13, 16, 18, 21, 23, 26, 28, 31}, SKINCOLOR_PIGEON, 12, V_TANMAP, true}, // SKINCOLOR_POPCORN - {"Artichoke", { 80, 88, 89, 98, 99, 91, 12, 14, 16, 18, 20, 22, 24, 26, 28, 31}, SKINCOLOR_FAIRY, 12, V_GREENMAP, true}, // SKINCOLOR_ARTICHOKE - {"Pigeon", { 0, 128, 129, 130, 146, 170, 14, 15, 17, 19, 21, 23, 25, 27, 29, 31}, SKINCOLOR_POPCORN, 12, V_SKYMAP, true}, // SKINCOLOR_PIGEON - {"Sepia", { 0, 1, 3, 5, 7, 9, 241, 242, 243, 245, 247, 249, 236, 237, 238, 239}, SKINCOLOR_LEATHER, 6, V_TANMAP, true}, // SKINCOLOR_SEPIA - {"Beige", { 0, 208, 216, 217, 240, 241, 242, 243, 245, 247, 249, 250, 251, 237, 238, 239}, SKINCOLOR_BROWN, 2, V_BROWNMAP, true}, // SKINCOLOR_BEIGE - {"Caramel", {208, 48, 216, 217, 218, 220, 221, 223, 224, 226, 228, 230, 232, 234, 236, 239}, SKINCOLOR_CERULEAN, 8, V_TANMAP, true}, // SKINCOLOR_CARAMEL - {"Peach", { 0, 208, 48, 216, 218, 221, 212, 213, 214, 215, 206, 207, 197, 198, 199, 254}, SKINCOLOR_CYAN, 8, V_TANMAP, true}, // SKINCOLOR_PEACH - {"Brown", {216, 217, 219, 221, 224, 225, 227, 229, 230, 232, 234, 235, 237, 239, 29, 30}, SKINCOLOR_BEIGE, 8, V_BROWNMAP, true}, // SKINCOLOR_BROWN - {"Leather", {218, 221, 224, 227, 229, 231, 233, 235, 237, 239, 28, 28, 29, 29, 30, 31}, SKINCOLOR_SEPIA, 8, V_BROWNMAP, true}, // SKINCOLOR_LEATHER - {"Pink", { 0, 208, 208, 209, 209, 210, 211, 211, 212, 213, 214, 215, 41, 43, 45, 46}, SKINCOLOR_PISTACHIO, 8, V_PINKMAP, true}, // SKINCOLOR_PINK - {"Rose", {209, 210, 211, 211, 212, 213, 214, 215, 41, 42, 43, 44, 45, 71, 46, 47}, SKINCOLOR_MOSS, 8, V_PINKMAP, true}, // SKINCOLOR_ROSE - {"Cinnamon", {216, 221, 224, 226, 228, 60, 61, 43, 44, 45, 71, 46, 47, 29, 30, 31}, SKINCOLOR_WRISTWATCH, 6, V_REDMAP, true}, // SKINCOLOR_CINNAMON - {"Ruby", { 0, 208, 209, 210, 211, 213, 39, 40, 41, 43, 186, 186, 169, 169, 253, 254}, SKINCOLOR_SAPPHIRE, 8, V_REDMAP, true}, // SKINCOLOR_RUBY - {"Raspberry", { 0, 208, 209, 210, 32, 33, 34, 35, 37, 39, 41, 43, 44, 45, 46, 47}, SKINCOLOR_MINT, 8, V_REDMAP, true}, // SKINCOLOR_RASPBERRY - {"Red", {209, 210, 32, 34, 36, 38, 39, 40, 41, 42, 43, 44 , 45, 71, 46, 47}, SKINCOLOR_GREEN, 6, V_REDMAP, true}, // SKINCOLOR_RED - {"Crimson", {210, 33, 35, 38, 40, 42, 43, 45, 71, 71, 46, 46, 47, 47, 30, 31}, SKINCOLOR_PINETREE, 6, V_REDMAP, true}, // SKINCOLOR_CRIMSON - {"Maroon", { 32, 33, 35, 37, 39, 41, 43, 237, 26, 26, 27, 27, 28, 29, 30, 31}, SKINCOLOR_TOXIC, 8, V_REDMAP, true}, // SKINCOLOR_MAROON - {"Lemonade", { 0, 80, 81, 82, 83, 216, 210, 211, 212, 213, 214, 215, 43, 44, 71, 47}, SKINCOLOR_THUNDER, 8, V_PINKMAP, true}, // SKINCOLOR_LEMONADE - {"Scarlet", { 48, 49, 50, 51, 53, 34, 36, 38, 184, 185, 168, 168, 169, 169, 254, 31}, SKINCOLOR_ALGAE, 10, V_REDMAP, true}, // SKINCOLOR_SCARLET - {"Ketchup", { 72, 73, 64, 51, 52, 54, 34, 36, 38, 40, 42, 43, 44, 71, 46, 47}, SKINCOLOR_MUSTARD, 10, V_REDMAP, true}, // SKINCOLOR_KETCHUP - {"Dawn", { 0, 208, 216, 209, 210, 211, 212, 57, 58, 59, 60, 61, 63, 71, 47, 31}, SKINCOLOR_DUSK, 8, V_ORANGEMAP, true}, // SKINCOLOR_DAWN - {"Sunslam", { 82, 72, 73, 64, 51, 53, 55, 213, 214, 195, 195, 173, 174, 175, 253, 254}, SKINCOLOR_MOONSET, 8, V_ORANGEMAP, true}, // SKINCOLOR_SUNSLAM - {"Creamsicle", { 0, 0, 208, 208, 48, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 63}, SKINCOLOR_PERIWINKLE, 8, V_ORANGEMAP, true}, // SKINCOLOR_CREAMSICLE - {"Orange", {208, 48, 49, 50, 51, 52, 53, 54, 55, 57, 59, 60, 62, 44, 71, 47}, SKINCOLOR_BLUE, 8, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE - {"Rosewood", { 50, 52, 55, 56, 58, 59, 60, 61, 62, 63, 44, 45, 71, 46, 47, 30}, SKINCOLOR_MIDNIGHT, 6, V_ORANGEMAP, true}, // SKINCOLOR_ROSEWOOD - {"Tangerine", { 80, 81, 82, 83, 64, 51, 52, 54, 55, 57, 58, 60, 61, 63, 71, 47}, SKINCOLOR_LIME, 8, V_ORANGEMAP, true}, // SKINCOLOR_TANGERINE - {"Tan", { 0, 80, 81, 82, 83, 84, 85, 86, 87, 245, 246, 248, 249, 251, 237, 239}, SKINCOLOR_RUST, 8, V_TANMAP, true}, // SKINCOLOR_TAN - {"Cream", { 0, 80, 80, 81, 81, 49, 51, 222, 224, 227, 230, 233, 236, 239, 29, 31}, SKINCOLOR_COPPER, 10, V_TANMAP, true}, // SKINCOLOR_CREAM - {"Gold", { 0, 80, 81, 83, 64, 65, 66, 67, 68, 215, 69, 70, 44, 71, 46, 47}, SKINCOLOR_SLATE, 8, V_GOLDMAP, true}, // SKINCOLOR_GOLD - {"Royal", { 80, 81, 83, 64, 65, 223, 229, 196, 196, 197, 197, 198, 199, 29, 30, 31}, SKINCOLOR_PLATINUM, 6, V_GOLDMAP, true}, // SKINCOLOR_ROYAL - {"Bronze", { 83, 64, 65, 66, 67, 215, 69, 70, 44, 44, 45, 71, 46, 47, 29, 31}, SKINCOLOR_STEEL, 8, V_GOLDMAP, true}, // SKINCOLOR_BRONZE - {"Copper", { 0, 82, 64, 65, 67, 68, 70, 237, 239, 28, 28, 29, 29, 30, 30, 31}, SKINCOLOR_CREAM, 6, V_GOLDMAP, true}, // SKINCOLOR_COPPER - {"Yellow", { 0, 80, 81, 82, 83, 73, 84, 74, 64, 65, 66, 67, 68, 69, 70, 71}, SKINCOLOR_AQUAMARINE, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW - {"Mustard", { 80, 81, 82, 83, 64, 65, 65, 76, 76, 77, 77, 78, 79, 237, 239, 29}, SKINCOLOR_KETCHUP, 8, V_YELLOWMAP, true}, // SKINCOLOR_MUSTARD - {"Banana", { 80, 81, 83, 72, 73, 74, 75, 76, 77, 78, 79, 236, 237, 238, 239, 30}, SKINCOLOR_EMERALD, 8, V_YELLOWMAP, true}, // SKINCOLOR_BANANA - {"Olive", { 80, 82, 73, 74, 75, 76, 77, 78, 79, 236, 237, 238, 239, 28, 29, 31}, SKINCOLOR_TEAL, 8, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE - {"Crocodile", { 0, 80, 81, 88, 88, 188, 189, 76, 76, 77, 78, 79, 236, 237, 238, 239}, SKINCOLOR_VIOLET, 8, V_YELLOWMAP, true}, // SKINCOLOR_CROCODILE - {"Peridot", { 0, 80, 81, 88, 188, 189, 190, 191, 94, 94, 95, 95, 109, 110, 111, 31}, SKINCOLOR_NAVY, 6, V_GREENMAP, true}, // SKINCOLOR_PERIDOT - {"Vomit", { 0, 208, 216, 209, 218, 51, 65, 76, 191, 191, 126, 143, 138, 175, 169, 254}, SKINCOLOR_SKUNK, 8, V_GREENMAP, true}, // SKINCOLOR_VOMIT - {"Garden", { 81, 82, 83, 73, 64, 65, 66, 92, 92, 93, 93, 94, 95, 109, 110, 111}, SKINCOLOR_LAVENDER, 6, V_GREENMAP, true}, // SKINCOLOR_GARDEN - {"Lime", { 0, 80, 81, 88, 188, 189, 114, 114, 115, 115, 116, 116, 117, 118, 119, 111}, SKINCOLOR_TANGERINE, 8, V_GREENMAP, true}, // SKINCOLOR_LIME - {"Handheld", { 83, 72, 73, 74, 75, 76, 102, 104, 105, 106, 107, 108, 109, 110, 111, 31}, SKINCOLOR_ULTRAMARINE, 8, V_GREENMAP, true}, // SKINCOLOR_HANDHELD - {"Tea", { 0, 80, 80, 81, 88, 89, 90, 91, 92, 93, 94, 95, 109, 110, 111, 31}, SKINCOLOR_BLOSSOM, 8, V_GREENMAP, true}, // SKINCOLOR_TEA - {"Pistachio", { 0, 80, 88, 88, 89, 90, 91, 102, 103, 104, 105, 106, 107, 108, 109, 110}, SKINCOLOR_PINK, 6, V_GREENMAP, true}, // SKINCOLOR_PISTACHIO - {"Moss", { 88, 89, 90, 91, 91, 92, 93, 94, 107, 107, 108, 108, 109, 109, 110, 111}, SKINCOLOR_ROSE, 8, V_GREENMAP, true}, // SKINCOLOR_MOSS - {"Camouflage", {208, 84, 85, 240, 241, 243, 245, 94, 107, 108, 108, 109, 109, 110, 110, 111}, SKINCOLOR_CAMOUFLAGE, 8, V_GREENMAP, true}, // SKINCOLOR_CAMOUFLAGE - {"Mint", { 0, 88, 88, 89, 89, 100, 101, 102, 125, 126, 143, 143, 138, 175, 169, 254}, SKINCOLOR_RASPBERRY, 8, V_GREENMAP, true}, // SKINCOLOR_MINT - {"Green", { 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}, SKINCOLOR_RED, 8, V_GREENMAP, true}, // SKINCOLOR_GREEN - {"Pinetree", { 97, 99, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 30, 30, 31}, SKINCOLOR_CRIMSON, 8, V_GREENMAP, true}, // SKINCOLOR_PINETREE - {"Turtle", { 96, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 119, 111}, SKINCOLOR_MAGENTA, 8, V_GREENMAP, true}, // SKINCOLOR_TURTLE - {"Swamp", { 96, 112, 113, 114, 115, 116, 117, 118, 119, 119, 29, 29, 30, 30, 31, 31}, SKINCOLOR_BYZANTIUM, 8, V_GREENMAP, true}, // SKINCOLOR_SWAMP - {"Dream", { 0, 0, 208, 208, 48, 89, 98, 100, 148, 148, 172, 172, 173, 173, 174, 175}, SKINCOLOR_POMEGRANATE, 8, V_GREENMAP, true}, // SKINCOLOR_DREAM - {"Plague", { 80, 88, 96, 112, 113, 124, 142, 149, 149, 173, 174, 175, 169, 253, 254, 31}, SKINCOLOR_NOVA, 8, V_GREENMAP, true}, // SKINCOLOR_PLAGUE - {"Emerald", { 0, 120, 121, 112, 113, 114, 115, 125, 125, 126, 126, 127, 138, 175, 253, 254}, SKINCOLOR_BANANA, 8, V_GREENMAP, true}, // SKINCOLOR_EMERALD - {"Algae", {128, 129, 130, 131, 132, 133, 134, 115, 115, 116, 116, 117, 118, 119, 110, 111}, SKINCOLOR_SCARLET, 10, V_GREENMAP, true}, // SKINCOLOR_ALGAE - {"Aquamarine", { 0, 128, 120, 121, 122, 123, 124, 125, 126, 126, 127, 127, 118, 118, 119, 111}, SKINCOLOR_YELLOW, 8, V_AQUAMAP, true}, // SKINCOLOR_AQUAMARINE - {"Turquoise", {128, 120, 121, 122, 123, 141, 141, 142, 142, 143, 143, 138, 138, 139, 139, 31}, SKINCOLOR_MAUVE, 10, V_AQUAMAP, true}, // SKINCOLOR_TURQUOISE - {"Teal", { 0, 120, 120, 121, 140, 141, 142, 143, 143, 138, 138, 139, 139, 254, 254, 31}, SKINCOLOR_OLIVE, 8, V_AQUAMAP, true}, // SKINCOLOR_TEAL - {"Robin", { 0, 80, 81, 82, 83, 88, 121, 140, 133, 133, 134, 135, 136, 137, 138, 139}, SKINCOLOR_THISTLE, 8, V_SKYMAP, true}, // SKINCOLOR_ROBIN - {"Cyan", { 0, 0, 128, 128, 255, 131, 132, 134, 142, 142, 143, 127, 118, 119, 110, 111}, SKINCOLOR_PEACH, 8, V_SKYMAP, true}, // SKINCOLOR_CYAN - {"Jawz", { 0, 0, 128, 128, 129, 146, 133, 134, 135, 149, 149, 173, 173, 174, 175, 31}, SKINCOLOR_LILAC, 10, V_SKYMAP, true}, // SKINCOLOR_JAWZ - {"Cerulean", { 0, 128, 129, 130, 131, 132, 133, 135, 136, 136, 137, 137, 138, 138, 139, 31}, SKINCOLOR_CARAMEL, 8, V_SKYMAP, true}, // SKINCOLOR_CERULEAN - {"Navy", {128, 129, 130, 132, 134, 135, 136, 137, 137, 138, 138, 139, 139, 29, 30, 31}, SKINCOLOR_PERIDOT, 8, V_SKYMAP, true}, // SKINCOLOR_NAVY - {"Platinum", { 0, 0, 0, 144, 144, 145, 9, 11, 14, 142, 136, 137, 138, 138, 139, 31}, SKINCOLOR_ROYAL, 8, V_GRAYMAP, true}, // SKINCOLOR_PLATINUM - {"Slate", { 0, 0, 144, 144, 144, 145, 145, 145, 170, 170, 171, 171, 172, 173, 174, 175}, SKINCOLOR_GOLD, 10, 0, true}, // SKINCOLOR_SLATE - {"Steel", { 0, 144, 144, 145, 145, 170, 170, 171, 171, 172, 172, 173, 173, 174, 175, 31}, SKINCOLOR_BRONZE, 10, V_GRAYMAP, true}, // SKINCOLOR_STEEL - {"Thunder", { 80, 81, 82, 83, 64, 65, 11, 171, 172, 173, 173, 157, 158, 159, 254, 31}, SKINCOLOR_LEMONADE, 8, V_GOLDMAP, true}, // SKINCOLOR_THUNDER - {"Nova", { 0, 83, 49, 50, 51, 32, 192, 148, 148, 172, 173, 174, 175, 29, 30, 31}, SKINCOLOR_PLAGUE, 10, V_BLUEMAP, true}, // SKINCOLOR_NOVA - {"Rust", {208, 48, 216, 217, 240, 241, 242, 171, 172, 173, 24, 25, 26, 28, 29, 31}, SKINCOLOR_TAN, 8, V_BROWNMAP, true}, // SKINCOLOR_RUST - {"Wristwatch", { 48, 218, 221, 224, 227, 231, 196, 173, 173, 174, 159, 159, 253, 253, 254, 31}, SKINCOLOR_CINNAMON, 8, V_BROWNMAP, true}, // SKINCOLOR_WRISTWATCH - {"Jet", {145, 146, 147, 148, 149, 173, 173, 174, 175, 175, 28, 28, 29, 29, 30, 31}, SKINCOLOR_TAFFY, 8, V_GRAYMAP, true}, // SKINCOLOR_JET - {"Sapphire", { 0, 128, 129, 131, 133, 135, 149, 150, 152, 154, 156, 158, 159, 253, 254, 31}, SKINCOLOR_RUBY, 6, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE - {"Ultramarine", { 0, 0, 120, 120, 121, 133, 135, 149, 149, 166, 166, 167, 168, 169, 254, 31}, SKINCOLOR_HANDHELD, 10, V_SKYMAP, true}, // SKINCOLOR_ULTRAMARINE - {"Periwinkle", { 0, 0, 144, 144, 145, 146, 147, 149, 150, 152, 154, 155, 157, 159, 253, 254}, SKINCOLOR_CREAMSICLE, 8, V_BLUEMAP, true}, // SKINCOLOR_PERIWINKLE - {"Blue", {144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 158, 253, 254, 31}, SKINCOLOR_ORANGE, 8, V_BLUEMAP, true}, // SKINCOLOR_BLUE - {"Midnight", {146, 148, 149, 150, 152, 153, 155, 157, 159, 253, 253, 254, 254, 31, 31, 31}, SKINCOLOR_ROSEWOOD, 8, V_BLUEMAP, true}, // SKINCOLOR_MIDNIGHT - {"Blueberry", { 0, 144, 145, 146, 147, 171, 172, 166, 166, 167, 167, 168, 168, 175, 169, 253}, SKINCOLOR_PURPLE, 8, V_BLUEMAP, true}, // SKINCOLOR_BLUEBERRY - {"Thistle", { 0, 0, 0, 252, 252, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 254}, SKINCOLOR_ROBIN, 8, V_PURPLEMAP, true}, // SKINCOLOR_THISTLE - {"Purple", { 0, 252, 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 169, 253, 254}, SKINCOLOR_BLUEBERRY, 10, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE - {"Pastel", { 0, 128, 128, 129, 129, 146, 170, 162, 163, 164, 165, 166, 167, 168, 169, 254}, SKINCOLOR_FUCHSIA, 11, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL - {"Moonset", { 0, 144, 145, 146, 170, 162, 163, 184, 184, 207, 207, 44, 45, 46, 47, 31}, SKINCOLOR_SUNSLAM, 10, V_MAGENTAMAP, true}, // SKINCOLOR_MOONSET - {"Dusk", {252, 200, 201, 192, 193, 194, 172, 172, 173, 173, 174, 174, 175, 169, 253, 254}, SKINCOLOR_DAWN, 6, V_MAGENTAMAP, true}, // SKINCOLOR_DUSK - {"Violet", {176, 177, 178, 179, 180, 181, 182, 183, 184, 165, 165, 166, 167, 168, 169, 254}, SKINCOLOR_CROCODILE, 8, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET - {"Magenta", {252, 200, 177, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 31}, SKINCOLOR_TURTLE, 8, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA - {"Fuchsia", {208, 209, 209, 32, 33, 182, 183, 184, 185, 185, 186, 186, 187, 253, 254, 31}, SKINCOLOR_PASTEL, 11, V_MAGENTAMAP, true}, // SKINCOLOR_FUCHSIA - {"Toxic", { 0, 0, 88, 88, 89, 6, 8, 10, 193, 194, 195, 184, 185, 186, 187, 31}, SKINCOLOR_MAROON, 8, V_LAVENDERMAP, true}, // SKINCOLOR_TOXIC - {"Mauve", { 80, 81, 82, 83, 64, 50, 201, 192, 193, 194, 195, 173, 174, 175, 253, 254}, SKINCOLOR_TURQUOISE, 8, V_LAVENDERMAP, true}, // SKINCOLOR_MAUVE - {"Lavender", {252, 177, 179, 192, 193, 194, 195, 196, 196, 197, 197, 198, 198, 199, 30, 31}, SKINCOLOR_GARDEN, 6, V_LAVENDERMAP, true}, // SKINCOLOR_LAVENDER - {"Byzantium", {145, 192, 193, 194, 195, 196, 197, 198, 199, 199, 29, 29, 30, 30, 31, 31}, SKINCOLOR_SWAMP, 8, V_LAVENDERMAP, true}, // SKINCOLOR_BYZANTIUM - {"Pomegranate", {208, 209, 210, 211, 212, 213, 214, 195, 195, 196, 196, 197, 198, 199, 29, 30}, SKINCOLOR_DREAM, 8, V_LAVENDERMAP, true}, // SKINCOLOR_POMEGRANATE - {"Lilac", { 0, 0, 0, 252, 252, 176, 200, 201, 179, 192, 193, 194, 195, 196, 197, 198}, SKINCOLOR_JAWZ, 6, V_PINKMAP, true}, // SKINCOLOR_LILAC - {"Blossom", { 0, 252, 252, 176, 200, 177, 201, 202, 202, 34, 36, 38, 40, 42, 45, 46}, SKINCOLOR_TEA, 8, V_PINKMAP, true}, // SKINCOLOR_BLOSSOM - {"Taffy", { 0, 252, 252, 200, 200, 201, 202, 203, 204, 204, 205, 206, 207, 43, 45, 47}, SKINCOLOR_JET, 8, V_PINKMAP, true}, // SKINCOLOR_TAFFY + {"White", { 0, 0, 0, 0, 1, 2, 5, 8, 9, 11, 14, 17, 20, 22, 25, 28}, SKINCOLOR_BLACK, 8, 0, true, UINT16_MAX}, // SKINCOLOR_WHITE + {"Silver", { 0, 1, 2, 3, 5, 7, 9, 12, 13, 15, 18, 20, 23, 25, 27, 30}, SKINCOLOR_NICKEL, 8, 0, true, UINT16_MAX}, // SKINCOLOR_SILVER + {"Grey", { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, SKINCOLOR_GREY, 8, V_LAVENDERMAP, true, UINT16_MAX}, // SKINCOLOR_GREY + {"Nickel", { 3, 5, 8, 11, 15, 17, 19, 21, 23, 24, 25, 26, 27, 29, 30, 31}, SKINCOLOR_SILVER, 8, V_GRAYMAP, true, UINT16_MAX}, // SKINCOLOR_NICKEL + {"Black", { 4, 7, 11, 15, 20, 22, 24, 27, 28, 28, 28, 29, 29, 30, 30, 31}, SKINCOLOR_WHITE, 8, V_GRAYMAP, true, UINT16_MAX}, // SKINCOLOR_BLACK + {"Skunk", { 0, 1, 2, 3, 4, 10, 16, 21, 23, 24, 25, 26, 27, 28, 29, 31}, SKINCOLOR_VOMIT, 8, V_GRAYMAP, true, UINT16_MAX}, // SKINCOLOR_SKUNK + {"Fairy", { 0, 0, 252, 252, 200, 201, 211, 14, 16, 18, 20, 22, 24, 26, 28, 31}, SKINCOLOR_ARTICHOKE, 12, V_PINKMAP, true, UINT16_MAX}, // SKINCOLOR_FAIRY + {"Popcorn", { 0, 80, 80, 81, 82, 218, 240, 11, 13, 16, 18, 21, 23, 26, 28, 31}, SKINCOLOR_PIGEON, 12, V_TANMAP, true, UINT16_MAX}, // SKINCOLOR_POPCORN + {"Artichoke", { 80, 88, 89, 98, 99, 91, 12, 14, 16, 18, 20, 22, 24, 26, 28, 31}, SKINCOLOR_FAIRY, 12, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_ARTICHOKE + {"Pigeon", { 0, 128, 129, 130, 146, 170, 14, 15, 17, 19, 21, 23, 25, 27, 29, 31}, SKINCOLOR_POPCORN, 12, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_PIGEON + {"Sepia", { 0, 1, 3, 5, 7, 9, 241, 242, 243, 245, 247, 249, 236, 237, 238, 239}, SKINCOLOR_LEATHER, 6, V_TANMAP, true, UINT16_MAX}, // SKINCOLOR_SEPIA + {"Beige", { 0, 208, 216, 217, 240, 241, 242, 243, 245, 247, 249, 250, 251, 237, 238, 239}, SKINCOLOR_BROWN, 2, V_BROWNMAP, true, UINT16_MAX}, // SKINCOLOR_BEIGE + {"Caramel", {208, 48, 216, 217, 218, 220, 221, 223, 224, 226, 228, 230, 232, 234, 236, 239}, SKINCOLOR_CERULEAN, 8, V_TANMAP, true, UINT16_MAX}, // SKINCOLOR_CARAMEL + {"Peach", { 0, 208, 48, 216, 218, 221, 212, 213, 214, 215, 206, 207, 197, 198, 199, 254}, SKINCOLOR_CYAN, 8, V_TANMAP, true, UINT16_MAX}, // SKINCOLOR_PEACH + {"Brown", {216, 217, 219, 221, 224, 225, 227, 229, 230, 232, 234, 235, 237, 239, 29, 30}, SKINCOLOR_BEIGE, 8, V_BROWNMAP, true, UINT16_MAX}, // SKINCOLOR_BROWN + {"Leather", {218, 221, 224, 227, 229, 231, 233, 235, 237, 239, 28, 28, 29, 29, 30, 31}, SKINCOLOR_SEPIA, 8, V_BROWNMAP, true, UINT16_MAX}, // SKINCOLOR_LEATHER + {"Pink", { 0, 208, 208, 209, 209, 210, 211, 211, 212, 213, 214, 215, 41, 43, 45, 46}, SKINCOLOR_PISTACHIO, 8, V_PINKMAP, true, UINT16_MAX}, // SKINCOLOR_PINK + {"Rose", {209, 210, 211, 211, 212, 213, 214, 215, 41, 42, 43, 44, 45, 71, 46, 47}, SKINCOLOR_MOSS, 8, V_PINKMAP, true, UINT16_MAX}, // SKINCOLOR_ROSE + {"Cinnamon", {216, 221, 224, 226, 228, 60, 61, 43, 44, 45, 71, 46, 47, 29, 30, 31}, SKINCOLOR_WRISTWATCH, 6, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_CINNAMON + {"Ruby", { 0, 208, 209, 210, 211, 213, 39, 40, 41, 43, 186, 186, 169, 169, 253, 254}, SKINCOLOR_SAPPHIRE, 8, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_RUBY + {"Raspberry", { 0, 208, 209, 210, 32, 33, 34, 35, 37, 39, 41, 43, 44, 45, 46, 47}, SKINCOLOR_MINT, 8, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_RASPBERRY + {"Red", {209, 210, 32, 34, 36, 38, 39, 40, 41, 42, 43, 44 , 45, 71, 46, 47}, SKINCOLOR_GREEN, 6, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_RED + {"Crimson", {210, 33, 35, 38, 40, 42, 43, 45, 71, 71, 46, 46, 47, 47, 30, 31}, SKINCOLOR_PINETREE, 6, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_CRIMSON + {"Maroon", { 32, 33, 35, 37, 39, 41, 43, 237, 26, 26, 27, 27, 28, 29, 30, 31}, SKINCOLOR_TOXIC, 8, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_MAROON + {"Lemonade", { 0, 80, 81, 82, 83, 216, 210, 211, 212, 213, 214, 215, 43, 44, 71, 47}, SKINCOLOR_THUNDER, 8, V_PINKMAP, true, UINT16_MAX}, // SKINCOLOR_LEMONADE + {"Scarlet", { 48, 49, 50, 51, 53, 34, 36, 38, 184, 185, 168, 168, 169, 169, 254, 31}, SKINCOLOR_ALGAE, 10, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_SCARLET + {"Ketchup", { 72, 73, 64, 51, 52, 54, 34, 36, 38, 40, 42, 43, 44, 71, 46, 47}, SKINCOLOR_MUSTARD, 10, V_REDMAP, true, UINT16_MAX}, // SKINCOLOR_KETCHUP + {"Dawn", { 0, 208, 216, 209, 210, 211, 212, 57, 58, 59, 60, 61, 63, 71, 47, 31}, SKINCOLOR_DUSK, 8, V_ORANGEMAP, true, UINT16_MAX}, // SKINCOLOR_DAWN + {"Sunslam", { 82, 72, 73, 64, 51, 53, 55, 213, 214, 195, 195, 173, 174, 175, 253, 254}, SKINCOLOR_MOONSET, 8, V_ORANGEMAP, true, UINT16_MAX}, // SKINCOLOR_SUNSLAM + {"Creamsicle", { 0, 0, 208, 208, 48, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 63}, SKINCOLOR_PERIWINKLE, 8, V_ORANGEMAP, true, UINT16_MAX}, // SKINCOLOR_CREAMSICLE + {"Orange", {208, 48, 49, 50, 51, 52, 53, 54, 55, 57, 59, 60, 62, 44, 71, 47}, SKINCOLOR_BLUE, 8, V_ORANGEMAP, true, UINT16_MAX}, // SKINCOLOR_ORANGE + {"Rosewood", { 50, 52, 55, 56, 58, 59, 60, 61, 62, 63, 44, 45, 71, 46, 47, 30}, SKINCOLOR_MIDNIGHT, 6, V_ORANGEMAP, true, UINT16_MAX}, // SKINCOLOR_ROSEWOOD + {"Tangerine", { 80, 81, 82, 83, 64, 51, 52, 54, 55, 57, 58, 60, 61, 63, 71, 47}, SKINCOLOR_LIME, 8, V_ORANGEMAP, true, UINT16_MAX}, // SKINCOLOR_TANGERINE + {"Tan", { 0, 80, 81, 82, 83, 84, 85, 86, 87, 245, 246, 248, 249, 251, 237, 239}, SKINCOLOR_RUST, 8, V_TANMAP, true, UINT16_MAX}, // SKINCOLOR_TAN + {"Cream", { 0, 80, 80, 81, 81, 49, 51, 222, 224, 227, 230, 233, 236, 239, 29, 31}, SKINCOLOR_COPPER, 10, V_TANMAP, true, UINT16_MAX}, // SKINCOLOR_CREAM + {"Gold", { 0, 80, 81, 83, 64, 65, 66, 67, 68, 215, 69, 70, 44, 71, 46, 47}, SKINCOLOR_SLATE, 8, V_GOLDMAP, true, UINT16_MAX}, // SKINCOLOR_GOLD + {"Royal", { 80, 81, 83, 64, 65, 223, 229, 196, 196, 197, 197, 198, 199, 29, 30, 31}, SKINCOLOR_PLATINUM, 6, V_GOLDMAP, true, UINT16_MAX}, // SKINCOLOR_ROYAL + {"Bronze", { 83, 64, 65, 66, 67, 215, 69, 70, 44, 44, 45, 71, 46, 47, 29, 31}, SKINCOLOR_STEEL, 8, V_GOLDMAP, true, UINT16_MAX}, // SKINCOLOR_BRONZE + {"Copper", { 0, 82, 64, 65, 67, 68, 70, 237, 239, 28, 28, 29, 29, 30, 30, 31}, SKINCOLOR_CREAM, 6, V_GOLDMAP, true, UINT16_MAX}, // SKINCOLOR_COPPER + {"Yellow", { 0, 80, 81, 82, 83, 73, 84, 74, 64, 65, 66, 67, 68, 69, 70, 71}, SKINCOLOR_AQUAMARINE, 8, V_YELLOWMAP, true, UINT16_MAX}, // SKINCOLOR_YELLOW + {"Mustard", { 80, 81, 82, 83, 64, 65, 65, 76, 76, 77, 77, 78, 79, 237, 239, 29}, SKINCOLOR_KETCHUP, 8, V_YELLOWMAP, true, UINT16_MAX}, // SKINCOLOR_MUSTARD + {"Banana", { 80, 81, 83, 72, 73, 74, 75, 76, 77, 78, 79, 236, 237, 238, 239, 30}, SKINCOLOR_EMERALD, 8, V_YELLOWMAP, true, UINT16_MAX}, // SKINCOLOR_BANANA + {"Olive", { 80, 82, 73, 74, 75, 76, 77, 78, 79, 236, 237, 238, 239, 28, 29, 31}, SKINCOLOR_TEAL, 8, V_YELLOWMAP, true, UINT16_MAX}, // SKINCOLOR_OLIVE + {"Crocodile", { 0, 80, 81, 88, 88, 188, 189, 76, 76, 77, 78, 79, 236, 237, 238, 239}, SKINCOLOR_VIOLET, 8, V_YELLOWMAP, true, UINT16_MAX}, // SKINCOLOR_CROCODILE + {"Peridot", { 0, 80, 81, 88, 188, 189, 190, 191, 94, 94, 95, 95, 109, 110, 111, 31}, SKINCOLOR_NAVY, 6, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_PERIDOT + {"Vomit", { 0, 208, 216, 209, 218, 51, 65, 76, 191, 191, 126, 143, 138, 175, 169, 254}, SKINCOLOR_SKUNK, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_VOMIT + {"Garden", { 81, 82, 83, 73, 64, 65, 66, 92, 92, 93, 93, 94, 95, 109, 110, 111}, SKINCOLOR_LAVENDER, 6, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_GARDEN + {"Lime", { 0, 80, 81, 88, 188, 189, 114, 114, 115, 115, 116, 116, 117, 118, 119, 111}, SKINCOLOR_TANGERINE, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_LIME + {"Handheld", { 83, 72, 73, 74, 75, 76, 102, 104, 105, 106, 107, 108, 109, 110, 111, 31}, SKINCOLOR_ULTRAMARINE, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_HANDHELD + {"Tea", { 0, 80, 80, 81, 88, 89, 90, 91, 92, 93, 94, 95, 109, 110, 111, 31}, SKINCOLOR_BLOSSOM, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_TEA + {"Pistachio", { 0, 80, 88, 88, 89, 90, 91, 102, 103, 104, 105, 106, 107, 108, 109, 110}, SKINCOLOR_PINK, 6, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_PISTACHIO + {"Moss", { 88, 89, 90, 91, 91, 92, 93, 94, 107, 107, 108, 108, 109, 109, 110, 111}, SKINCOLOR_ROSE, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_MOSS + {"Camouflage", {208, 84, 85, 240, 241, 243, 245, 94, 107, 108, 108, 109, 109, 110, 110, 111}, SKINCOLOR_CAMOUFLAGE, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_CAMOUFLAGE + {"Mint", { 0, 88, 88, 89, 89, 100, 101, 102, 125, 126, 143, 143, 138, 175, 169, 254}, SKINCOLOR_RASPBERRY, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_MINT + {"Green", { 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}, SKINCOLOR_RED, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_GREEN + {"Pinetree", { 97, 99, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 30, 30, 31}, SKINCOLOR_CRIMSON, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_PINETREE + {"Turtle", { 96, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 119, 111}, SKINCOLOR_MAGENTA, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_TURTLE + {"Swamp", { 96, 112, 113, 114, 115, 116, 117, 118, 119, 119, 29, 29, 30, 30, 31, 31}, SKINCOLOR_BYZANTIUM, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_SWAMP + {"Dream", { 0, 0, 208, 208, 48, 89, 98, 100, 148, 148, 172, 172, 173, 173, 174, 175}, SKINCOLOR_POMEGRANATE, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_DREAM + {"Plague", { 80, 88, 96, 112, 113, 124, 142, 149, 149, 173, 174, 175, 169, 253, 254, 31}, SKINCOLOR_NOVA, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_PLAGUE + {"Emerald", { 0, 120, 121, 112, 113, 114, 115, 125, 125, 126, 126, 127, 138, 175, 253, 254}, SKINCOLOR_BANANA, 8, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_EMERALD + {"Algae", {128, 129, 130, 131, 132, 133, 134, 115, 115, 116, 116, 117, 118, 119, 110, 111}, SKINCOLOR_SCARLET, 10, V_GREENMAP, true, UINT16_MAX}, // SKINCOLOR_ALGAE + {"Aquamarine", { 0, 128, 120, 121, 122, 123, 124, 125, 126, 126, 127, 127, 118, 118, 119, 111}, SKINCOLOR_YELLOW, 8, V_AQUAMAP, true, UINT16_MAX}, // SKINCOLOR_AQUAMARINE + {"Turquoise", {128, 120, 121, 122, 123, 141, 141, 142, 142, 143, 143, 138, 138, 139, 139, 31}, SKINCOLOR_MAUVE, 10, V_AQUAMAP, true, UINT16_MAX}, // SKINCOLOR_TURQUOISE + {"Teal", { 0, 120, 120, 121, 140, 141, 142, 143, 143, 138, 138, 139, 139, 254, 254, 31}, SKINCOLOR_OLIVE, 8, V_AQUAMAP, true, UINT16_MAX}, // SKINCOLOR_TEAL + {"Robin", { 0, 80, 81, 82, 83, 88, 121, 140, 133, 133, 134, 135, 136, 137, 138, 139}, SKINCOLOR_THISTLE, 8, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_ROBIN + {"Cyan", { 0, 0, 128, 128, 255, 131, 132, 134, 142, 142, 143, 127, 118, 119, 110, 111}, SKINCOLOR_PEACH, 8, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_CYAN + {"Jawz", { 0, 0, 128, 128, 129, 146, 133, 134, 135, 149, 149, 173, 173, 174, 175, 31}, SKINCOLOR_LILAC, 10, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_JAWZ + {"Cerulean", { 0, 128, 129, 130, 131, 132, 133, 135, 136, 136, 137, 137, 138, 138, 139, 31}, SKINCOLOR_CARAMEL, 8, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_CERULEAN + {"Navy", {128, 129, 130, 132, 134, 135, 136, 137, 137, 138, 138, 139, 139, 29, 30, 31}, SKINCOLOR_PERIDOT, 8, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_NAVY + {"Platinum", { 0, 0, 0, 144, 144, 145, 9, 11, 14, 142, 136, 137, 138, 138, 139, 31}, SKINCOLOR_ROYAL, 8, V_GRAYMAP, true, UINT16_MAX}, // SKINCOLOR_PLATINUM + {"Slate", { 0, 0, 144, 144, 144, 145, 145, 145, 170, 170, 171, 171, 172, 173, 174, 175}, SKINCOLOR_GOLD, 10, 0, true, UINT16_MAX}, // SKINCOLOR_SLATE + {"Steel", { 0, 144, 144, 145, 145, 170, 170, 171, 171, 172, 172, 173, 173, 174, 175, 31}, SKINCOLOR_BRONZE, 10, V_GRAYMAP, true, UINT16_MAX}, // SKINCOLOR_STEEL + {"Thunder", { 80, 81, 82, 83, 64, 65, 11, 171, 172, 173, 173, 157, 158, 159, 254, 31}, SKINCOLOR_LEMONADE, 8, V_GOLDMAP, true, UINT16_MAX}, // SKINCOLOR_THUNDER + {"Nova", { 0, 83, 49, 50, 51, 32, 192, 148, 148, 172, 173, 174, 175, 29, 30, 31}, SKINCOLOR_PLAGUE, 10, V_BLUEMAP, true, UINT16_MAX}, // SKINCOLOR_NOVA + {"Rust", {208, 48, 216, 217, 240, 241, 242, 171, 172, 173, 24, 25, 26, 28, 29, 31}, SKINCOLOR_TAN, 8, V_BROWNMAP, true, UINT16_MAX}, // SKINCOLOR_RUST + {"Wristwatch", { 48, 218, 221, 224, 227, 231, 196, 173, 173, 174, 159, 159, 253, 253, 254, 31}, SKINCOLOR_CINNAMON, 8, V_BROWNMAP, true, UINT16_MAX}, // SKINCOLOR_WRISTWATCH + {"Jet", {145, 146, 147, 148, 149, 173, 173, 174, 175, 175, 28, 28, 29, 29, 30, 31}, SKINCOLOR_TAFFY, 8, V_GRAYMAP, true, UINT16_MAX}, // SKINCOLOR_JET + {"Sapphire", { 0, 128, 129, 131, 133, 135, 149, 150, 152, 154, 156, 158, 159, 253, 254, 31}, SKINCOLOR_RUBY, 6, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_SAPPHIRE + {"Ultramarine", { 0, 0, 120, 120, 121, 133, 135, 149, 149, 166, 166, 167, 168, 169, 254, 31}, SKINCOLOR_HANDHELD, 10, V_SKYMAP, true, UINT16_MAX}, // SKINCOLOR_ULTRAMARINE + {"Periwinkle", { 0, 0, 144, 144, 145, 146, 147, 149, 150, 152, 154, 155, 157, 159, 253, 254}, SKINCOLOR_CREAMSICLE, 8, V_BLUEMAP, true, UINT16_MAX}, // SKINCOLOR_PERIWINKLE + {"Blue", {144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 158, 253, 254, 31}, SKINCOLOR_ORANGE, 8, V_BLUEMAP, true, UINT16_MAX}, // SKINCOLOR_BLUE + {"Midnight", {146, 148, 149, 150, 152, 153, 155, 157, 159, 253, 253, 254, 254, 31, 31, 31}, SKINCOLOR_ROSEWOOD, 8, V_BLUEMAP, true, UINT16_MAX}, // SKINCOLOR_MIDNIGHT + {"Blueberry", { 0, 144, 145, 146, 147, 171, 172, 166, 166, 167, 167, 168, 168, 175, 169, 253}, SKINCOLOR_PURPLE, 8, V_BLUEMAP, true, UINT16_MAX}, // SKINCOLOR_BLUEBERRY + {"Thistle", { 0, 0, 0, 252, 252, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 254}, SKINCOLOR_ROBIN, 8, V_PURPLEMAP, true, UINT16_MAX}, // SKINCOLOR_THISTLE + {"Purple", { 0, 252, 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 169, 253, 254}, SKINCOLOR_BLUEBERRY, 10, V_PURPLEMAP, true, UINT16_MAX}, // SKINCOLOR_PURPLE + {"Pastel", { 0, 128, 128, 129, 129, 146, 170, 162, 163, 164, 165, 166, 167, 168, 169, 254}, SKINCOLOR_FUCHSIA, 11, V_PURPLEMAP, true, UINT16_MAX}, // SKINCOLOR_PASTEL + {"Moonset", { 0, 144, 145, 146, 170, 162, 163, 184, 184, 207, 207, 44, 45, 46, 47, 31}, SKINCOLOR_SUNSLAM, 10, V_MAGENTAMAP, true, UINT16_MAX}, // SKINCOLOR_MOONSET + {"Dusk", {252, 200, 201, 192, 193, 194, 172, 172, 173, 173, 174, 174, 175, 169, 253, 254}, SKINCOLOR_DAWN, 6, V_MAGENTAMAP, true, UINT16_MAX}, // SKINCOLOR_DUSK + {"Violet", {176, 177, 178, 179, 180, 181, 182, 183, 184, 165, 165, 166, 167, 168, 169, 254}, SKINCOLOR_CROCODILE, 8, V_MAGENTAMAP, true, UINT16_MAX}, // SKINCOLOR_VIOLET + {"Magenta", {252, 200, 177, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 31}, SKINCOLOR_TURTLE, 8, V_MAGENTAMAP, true, UINT16_MAX}, // SKINCOLOR_MAGENTA + {"Fuchsia", {208, 209, 209, 32, 33, 182, 183, 184, 185, 185, 186, 186, 187, 253, 254, 31}, SKINCOLOR_PASTEL, 11, V_MAGENTAMAP, true, UINT16_MAX}, // SKINCOLOR_FUCHSIA + {"Toxic", { 0, 0, 88, 88, 89, 6, 8, 10, 193, 194, 195, 184, 185, 186, 187, 31}, SKINCOLOR_MAROON, 8, V_LAVENDERMAP, true, UINT16_MAX}, // SKINCOLOR_TOXIC + {"Mauve", { 80, 81, 82, 83, 64, 50, 201, 192, 193, 194, 195, 173, 174, 175, 253, 254}, SKINCOLOR_TURQUOISE, 8, V_LAVENDERMAP, true, UINT16_MAX}, // SKINCOLOR_MAUVE + {"Lavender", {252, 177, 179, 192, 193, 194, 195, 196, 196, 197, 197, 198, 198, 199, 30, 31}, SKINCOLOR_GARDEN, 6, V_LAVENDERMAP, true, UINT16_MAX}, // SKINCOLOR_LAVENDER + {"Byzantium", {145, 192, 193, 194, 195, 196, 197, 198, 199, 199, 29, 29, 30, 30, 31, 31}, SKINCOLOR_SWAMP, 8, V_LAVENDERMAP, true, UINT16_MAX}, // SKINCOLOR_BYZANTIUM + {"Pomegranate", {208, 209, 210, 211, 212, 213, 214, 195, 195, 196, 196, 197, 198, 199, 29, 30}, SKINCOLOR_DREAM, 8, V_LAVENDERMAP, true, UINT16_MAX}, // SKINCOLOR_POMEGRANATE + {"Lilac", { 0, 0, 0, 252, 252, 176, 200, 201, 179, 192, 193, 194, 195, 196, 197, 198}, SKINCOLOR_JAWZ, 6, V_PINKMAP, true, UINT16_MAX}, // SKINCOLOR_LILAC + {"Blossom", { 0, 252, 252, 176, 200, 177, 201, 202, 202, 34, 36, 38, 40, 42, 45, 46}, SKINCOLOR_TEA, 8, V_PINKMAP, true, UINT16_MAX}, // SKINCOLOR_BLOSSOM + {"Taffy", { 0, 252, 252, 200, 200, 201, 202, 203, 204, 204, 205, 206, 207, 43, 45, 47}, SKINCOLOR_JET, 8, V_PINKMAP, true, UINT16_MAX}, // SKINCOLOR_TAFFY // super (todo: replace these with the kart ones) - {"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1 - {"Super Silver 2", {0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, SKINCOLOR_BLACK, 6, 0, false}, // SKINCOLOR_SUPERSILVER2 - {"Super Silver 3", {0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, SKINCOLOR_BLACK, 5, 0, false}, // SKINCOLOR_SUPERSILVER3 - {"Super Silver 4", {0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false}, // SKINCOLOR_SUPERSILVER4 - {"Super Silver 5", {0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false}, // SKINCOLOR_SUPERSILVER5 + {"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERSILVER1 + {"Super Silver 2", {0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, SKINCOLOR_BLACK, 6, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERSILVER2 + {"Super Silver 3", {0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, SKINCOLOR_BLACK, 5, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERSILVER3 + {"Super Silver 4", {0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERSILVER4 + {"Super Silver 5", {0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERSILVER5 - {"Super Red 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, SKINCOLOR_CYAN, 15, 0, false}, // SKINCOLOR_SUPERRED1 - {"Super Red 2", {0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, SKINCOLOR_CYAN, 14, V_PINKMAP, false}, // SKINCOLOR_SUPERRED2 - {"Super Red 3", {0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, SKINCOLOR_CYAN, 13, V_REDMAP, false}, // SKINCOLOR_SUPERRED3 - {"Super Red 4", {0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, SKINCOLOR_CYAN, 11, V_REDMAP, false}, // SKINCOLOR_SUPERRED4 - {"Super Red 5", {0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, SKINCOLOR_CYAN, 10, V_REDMAP, false}, // SKINCOLOR_SUPERRED5 + {"Super Red 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, SKINCOLOR_CYAN, 15, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERRED1 + {"Super Red 2", {0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, SKINCOLOR_CYAN, 14, V_PINKMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRED2 + {"Super Red 3", {0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, SKINCOLOR_CYAN, 13, V_REDMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRED3 + {"Super Red 4", {0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, SKINCOLOR_CYAN, 11, V_REDMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRED4 + {"Super Red 5", {0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, SKINCOLOR_CYAN, 10, V_REDMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRED5 - {"Super Orange 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, SKINCOLOR_SAPPHIRE, 15, 0, false}, // SKINCOLOR_SUPERORANGE1 - {"Super Orange 2", {0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, SKINCOLOR_SAPPHIRE, 12, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE2 - {"Super Orange 3", {0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, SKINCOLOR_SAPPHIRE, 9, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE3 - {"Super Orange 4", {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, SKINCOLOR_SAPPHIRE, 4, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE4 - {"Super Orange 5", {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_SAPPHIRE, 3, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE5 + {"Super Orange 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, SKINCOLOR_SAPPHIRE, 15, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERORANGE1 + {"Super Orange 2", {0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, SKINCOLOR_SAPPHIRE, 12, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERORANGE2 + {"Super Orange 3", {0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, SKINCOLOR_SAPPHIRE, 9, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERORANGE3 + {"Super Orange 4", {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, SKINCOLOR_SAPPHIRE, 4, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERORANGE4 + {"Super Orange 5", {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_SAPPHIRE, 3, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERORANGE5 - {"Super Gold 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, SKINCOLOR_PERIWINKLE, 15, 0, false}, // SKINCOLOR_SUPERGOLD1 - {"Super Gold 2", {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, SKINCOLOR_PERIWINKLE, 9, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD2 - {"Super Gold 3", {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, SKINCOLOR_PERIWINKLE, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD3 - {"Super Gold 4", {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, SKINCOLOR_PERIWINKLE, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD4 - {"Super Gold 5", {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_PERIWINKLE, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD5 + {"Super Gold 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, SKINCOLOR_PERIWINKLE, 15, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERGOLD1 + {"Super Gold 2", {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, SKINCOLOR_PERIWINKLE, 9, V_YELLOWMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERGOLD2 + {"Super Gold 3", {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, SKINCOLOR_PERIWINKLE, 8, V_YELLOWMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERGOLD3 + {"Super Gold 4", {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, SKINCOLOR_PERIWINKLE, 8, V_YELLOWMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERGOLD4 + {"Super Gold 5", {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_PERIWINKLE, 8, V_YELLOWMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERGOLD5 - {"Super Peridot 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, SKINCOLOR_BLUEBERRY, 15, 0, false}, // SKINCOLOR_SUPERPERIDOT1 - {"Super Peridot 2", {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, SKINCOLOR_BLUEBERRY, 4, V_GREENMAP, false}, // SKINCOLOR_SUPERPERIDOT2 - {"Super Peridot 3", {0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, SKINCOLOR_BLUEBERRY, 3, V_GREENMAP, false}, // SKINCOLOR_SUPERPERIDOT3 - {"Super Peridot 4", {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, SKINCOLOR_BLUEBERRY, 3, V_GREENMAP, false}, // SKINCOLOR_SUPERPERIDOT4 - {"Super Peridot 5", {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, SKINCOLOR_BLUEBERRY, 3, V_GREENMAP, false}, // SKINCOLOR_SUPERPERIDOT5 + {"Super Peridot 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, SKINCOLOR_BLUEBERRY, 15, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERPERIDOT1 + {"Super Peridot 2", {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, SKINCOLOR_BLUEBERRY, 4, V_GREENMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPERIDOT2 + {"Super Peridot 3", {0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, SKINCOLOR_BLUEBERRY, 3, V_GREENMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPERIDOT3 + {"Super Peridot 4", {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, SKINCOLOR_BLUEBERRY, 3, V_GREENMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPERIDOT4 + {"Super Peridot 5", {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, SKINCOLOR_BLUEBERRY, 3, V_GREENMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPERIDOT5 - {"Super Sky 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, SKINCOLOR_RUST, 15, 0, false}, // SKINCOLOR_SUPERSKY1 - {"Super Sky 2", {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, SKINCOLOR_RUST, 4, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY2 - {"Super Sky 3", {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY3 - {"Super Sky 4", {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY4 - {"Super Sky 5", {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY5 + {"Super Sky 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, SKINCOLOR_RUST, 15, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERSKY1 + {"Super Sky 2", {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, SKINCOLOR_RUST, 4, V_SKYMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERSKY2 + {"Super Sky 3", {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, SKINCOLOR_RUST, 3, V_SKYMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERSKY3 + {"Super Sky 4", {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, SKINCOLOR_RUST, 3, V_SKYMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERSKY4 + {"Super Sky 5", {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, SKINCOLOR_RUST, 3, V_SKYMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERSKY5 - {"Super Purple 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, SKINCOLOR_EMERALD, 15, 0, false}, // SKINCOLOR_SUPERPURPLE1 - {"Super Purple 2", {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, SKINCOLOR_EMERALD, 4, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE2 - {"Super Purple 3", {0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE3 - {"Super Purple 4", {0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE4 - {"Super Purple 5", {0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE5 + {"Super Purple 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, SKINCOLOR_EMERALD, 15, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERPURPLE1 + {"Super Purple 2", {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, SKINCOLOR_EMERALD, 4, V_PURPLEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPURPLE2 + {"Super Purple 3", {0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPURPLE3 + {"Super Purple 4", {0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPURPLE4 + {"Super Purple 5", {0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERPURPLE5 - {"Super Rust 1", {0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, SKINCOLOR_CYAN, 14, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST1 - {"Super Rust 2", {0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, SKINCOLOR_CYAN, 10, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST2 - {"Super Rust 3", {0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, SKINCOLOR_CYAN, 9, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST3 - {"Super Rust 4", {0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST4 - {"Super Rust 5", {0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST5 + {"Super Rust 1", {0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, SKINCOLOR_CYAN, 14, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRUST1 + {"Super Rust 2", {0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, SKINCOLOR_CYAN, 10, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRUST2 + {"Super Rust 3", {0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, SKINCOLOR_CYAN, 9, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRUST3 + {"Super Rust 4", {0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRUST4 + {"Super Rust 5", {0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERRUST5 - {"Super Tan 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, SKINCOLOR_BROWN, 14, 0, false}, // SKINCOLOR_SUPERTAN1 - {"Super Tan 2", {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, SKINCOLOR_BROWN, 13, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN2 - {"Super Tan 3", {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, SKINCOLOR_BROWN, 12, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN3 - {"Super Tan 4", {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, SKINCOLOR_BROWN, 11, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN4 - {"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN5 + {"Super Tan 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, SKINCOLOR_BROWN, 14, 0, false, UINT16_MAX}, // SKINCOLOR_SUPERTAN1 + {"Super Tan 2", {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, SKINCOLOR_BROWN, 13, V_BROWNMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERTAN2 + {"Super Tan 3", {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, SKINCOLOR_BROWN, 12, V_BROWNMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERTAN3 + {"Super Tan 4", {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, SKINCOLOR_BROWN, 11, V_BROWNMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERTAN4 + {"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false, UINT16_MAX}, // SKINCOLOR_SUPERTAN5 - {"Chaos Emerald 1", { 0, 88, 188, 98, 114, 116, 117, 119, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD1 - {"Chaos Emerald 2", { 0, 80, 82, 74, 65, 52, 56, 60, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD2 - {"Chaos Emerald 3", { 0, 252, 201, 179, 182, 183, 185, 187, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD3 - {"Chaos Emerald 4", { 0, 144, 146, 147, 149, 165, 167, 169, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD4 - {"Chaos Emerald 5", { 0, 1, 144, 4, 9, 170, 14, 21, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD5 - {"Chaos Emerald 6", { 0, 208, 50, 32, 34, 37, 40, 44, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD6 - {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD7 + {"Chaos Emerald 1", { 0, 88, 188, 98, 114, 116, 117, 119, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_CHAOSEMERALD1 + {"Chaos Emerald 2", { 0, 80, 82, 74, 65, 52, 56, 60, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_CHAOSEMERALD2 + {"Chaos Emerald 3", { 0, 252, 201, 179, 182, 183, 185, 187, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_CHAOSEMERALD3 + {"Chaos Emerald 4", { 0, 144, 146, 147, 149, 165, 167, 169, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_CHAOSEMERALD4 + {"Chaos Emerald 5", { 0, 1, 144, 4, 9, 170, 14, 21, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_CHAOSEMERALD5 + {"Chaos Emerald 6", { 0, 208, 50, 32, 34, 37, 40, 44, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_CHAOSEMERALD6 + {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_CHAOSEMERALD7 - {"Invinc Flash", { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_INVINCFLASH + {"Invinc Flash", { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_INVINCFLASH - {"Position", { 8, 9, 11, 12, 14, 15, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM - {"Position Win 1", {152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 158, 159, 253, 254, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_WIN1 - {"Position Win 2", {134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 138, 138, 139, 139, 254, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_WIN2 - {"Position Win 3", {255, 255, 122, 122, 123, 123, 141, 141, 142, 142, 143, 143, 138, 139, 254, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_WIN3 - {"Position Lose 1", { 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 71, 46, 47, 29, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_LOSE1 - {"Position Lose 2", { 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 44, 45, 46, 47, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_LOSE2 - {"Position Lose 3", { 73, 74, 75, 76, 76, 77, 77, 78, 78, 79, 79, 236, 237, 238, 239, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_LOSE3 - {"Position Best 1", { 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 71, 46, 47, 29, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_BEST1 - {"Position Best 2", { 73, 74, 75, 76, 76, 77, 77, 78, 78, 79, 79, 236, 237, 238, 239, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_BEST2 - {"Position Best 3", {112, 112, 113, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 110, 111, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_BEST3 - {"Position Best 4", {255, 255, 122, 122, 123, 123, 141, 141, 142, 142, 143, 143, 138, 139, 254, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_BEST4 - {"Position Best 5", {152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 158, 159, 253, 254, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_BEST5 - {"Position Best 6", {181, 181, 182, 182, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 29, 30}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_POSNUM_BEST6 + {"Position", { 8, 9, 11, 12, 14, 15, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM + {"Position Win 1", {152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 158, 159, 253, 254, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_WIN1 + {"Position Win 2", {134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 138, 138, 139, 139, 254, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_WIN2 + {"Position Win 3", {255, 255, 122, 122, 123, 123, 141, 141, 142, 142, 143, 143, 138, 139, 254, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_WIN3 + {"Position Lose 1", { 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 71, 46, 47, 29, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_LOSE1 + {"Position Lose 2", { 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 44, 45, 46, 47, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_LOSE2 + {"Position Lose 3", { 73, 74, 75, 76, 76, 77, 77, 78, 78, 79, 79, 236, 237, 238, 239, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_LOSE3 + {"Position Best 1", { 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 71, 46, 47, 29, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_BEST1 + {"Position Best 2", { 73, 74, 75, 76, 76, 77, 77, 78, 78, 79, 79, 236, 237, 238, 239, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_BEST2 + {"Position Best 3", {112, 112, 113, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 110, 111, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_BEST3 + {"Position Best 4", {255, 255, 122, 122, 123, 123, 141, 141, 142, 142, 143, 143, 138, 139, 254, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_BEST4 + {"Position Best 5", {152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 158, 159, 253, 254, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_BEST5 + {"Position Best 6", {181, 181, 182, 182, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 29, 30}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_POSNUM_BEST6 - {"Intermission", {0,80,80,81,81,81,84,85,86,87,246,248,251,26,28,31}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_INTERMISSION + {"Intermission", {0,80,80,81,81,81,84,85,86,87,246,248,251,26,28,31}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_INTERMISSION }; /** Patches the mobjinfo, state, and skincolor tables. diff --git a/src/info.h b/src/info.h index 8d7d35fef..dec72563c 100644 --- a/src/info.h +++ b/src/info.h @@ -1189,7 +1189,7 @@ typedef enum sprite SPR_POKE, // Pokey SPR_AUDI, // Audience members SPR_DECO, // Old 1.0 Kart Decoratives + New misc ones - SPR_DOOD, // All the old D00Dkart objects + SPR_SPCN, // Spray Can replaces all the old D00Dkart objects SPR_SNES, // Sprites for SNES remake maps SPR_GBAS, // Sprites for GBA remake maps SPR_SPRS, // Sapphire Coast Spring Shell @@ -2345,6 +2345,9 @@ typedef enum state S_EMBLEM25, S_EMBLEM26, + // Spray Can + S_SPRAYCAN, + // Chaos Emeralds S_CHAOSEMERALD1, S_CHAOSEMERALD2, @@ -5077,24 +5080,6 @@ typedef enum state S_APPLE7, S_APPLE8, - // D00Dkart - Fall Flowers - S_DOOD_FLOWER1, - S_DOOD_FLOWER2, - S_DOOD_FLOWER3, - S_DOOD_FLOWER4, - S_DOOD_FLOWER5, - S_DOOD_FLOWER6, - - // D00Dkart - Super Circuit Box - S_DOOD_BOX1, - S_DOOD_BOX2, - S_DOOD_BOX3, - S_DOOD_BOX4, - S_DOOD_BOX5, - - // D00Dkart - Diddy Kong Racing Bumper - S_DOOD_BALLOON, - // Chaotix Big Ring S_BIGRING01, S_BIGRING02, @@ -5997,6 +5982,7 @@ typedef enum mobj_type MT_REDFLAG, // Red CTF Flag MT_BLUEFLAG, // Blue CTF Flag MT_EMBLEM, + MT_SPRAYCAN, MT_EMERALD, MT_EMERALDSPARK, MT_EMERALDFLARE, @@ -6772,12 +6758,6 @@ typedef enum mobj_type MT_BIGPUMA, MT_APPLE, - MT_DOOD_FLOWER1, - MT_DOOD_FLOWER2, - MT_DOOD_FLOWER3, - MT_DOOD_FLOWER4, - MT_DOOD_BOX, - MT_DOOD_BALLOON, MT_BIGRING, MT_SNES_DONUTBUSH1, diff --git a/src/k_grandprix.c b/src/k_grandprix.c index dfbb65669..0d4b4b654 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -844,6 +844,12 @@ boolean K_CanChangeRules(boolean allowdemos) --------------------------------------------------*/ void K_PlayerFinishGrandPrix(player_t *player) { + if (grandprixinfo.wonround == true) + { + // This was already completed. + return; + } + if (player->exiting == false) { // You did not finish diff --git a/src/k_menudraw.c b/src/k_menudraw.c index e2e046c7b..23c989505 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -1299,7 +1299,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y) if (i == 0) { - n = l = r = M_GetColorBefore(&p->colors, p->color, (numoptions/2) - 1); + n = l = r = M_GetColorBefore(&p->colors, p->color, (numoptions/2) - (numoptions & 1)); } else if (subtract) { @@ -1428,7 +1428,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y) if (i == 0) { - n = l = r = M_GetColorBefore(&p->colors, p->followercolor, (numoptions/2) - 1); + n = l = r = M_GetColorBefore(&p->colors, p->followercolor, (numoptions/2) - (numoptions & 1)); } else if (subtract) { @@ -6055,8 +6055,14 @@ challengedesc: static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y) { UINT8 lasttype = UINT8_MAX, curtype; + + // M_GetLevelEmblems is ONE-indexed, urgh + mapnum++; + emblem_t *emblem = M_GetLevelEmblems(mapnum); + boolean hasmedals = (emblem != NULL); + while (emblem) { switch (emblem->type) @@ -6097,13 +6103,32 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y) if (gamedata->collected[emblem-emblemlocations]) V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), - R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE)); + R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE)); else V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); emblem = M_GetLevelEmblems(-1); x -= 8; } + + // Undo offset + mapnum--; + + if (hasmedals) + x -= 4; + + if (mapheaderinfo[mapnum]->cache_spraycan < gamedata->numspraycans) + { + UINT16 col = gamedata->spraycans[mapheaderinfo[mapnum]->cache_spraycan].col; + + if (col < numskincolors) + { + V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName("GOTCAN", PU_CACHE), + R_GetTranslationColormap(TC_RAINBOW, col, GTC_MENUCACHE)); + //V_DrawRightAlignedThinString(x - 2, y, 0, skincolors[col].name); + } + x -= 8; + } } static void M_DrawStatsMaps(void) @@ -6252,7 +6277,7 @@ static void M_DrawStatsMaps(void) } } - M_DrawMapMedals(mnum+1, medalspos - 8, y); + M_DrawMapMedals(mnum, medalspos - 8, y); if (mapheaderinfo[mnum]->menuttl[0]) { diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9af9ccd32..bd1771a89 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2869,7 +2869,8 @@ static int lib_gExitLevel(lua_State *L) // Moved this bit to G_SetCustomExitVars if (n >= 1) // Don't run the reset to defaults option lib_gSetCustomExitVars(L); - G_ExitLevel(); + G_BeginLevelExit(); + G_FinishExitLevel(); return 0; } diff --git a/src/m_cond.c b/src/m_cond.c index b66ee1af8..eecc73ae6 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -621,14 +621,30 @@ void M_ClearStats(void) void M_ClearSecrets(void) { - INT32 i; + memset(gamedata->collected, 0, sizeof(gamedata->collected)); + memset(gamedata->unlocked, 0, sizeof(gamedata->unlocked)); + memset(gamedata->unlockpending, 0, sizeof(gamedata->unlockpending)); + if (!dedicated) + memset(netUnlocked, 0, sizeof(netUnlocked)); + memset(gamedata->achieved, 0, sizeof(gamedata->achieved)); - for (i = 0; i < MAXEMBLEMS; ++i) - gamedata->collected[i] = false; - for (i = 0; i < MAXUNLOCKABLES; ++i) - gamedata->unlocked[i] = gamedata->unlockpending[i] = netUnlocked[i] = false; - for (i = 0; i < MAXCONDITIONSETS; ++i) - gamedata->achieved[i] = false; + Z_Free(gamedata->spraycans); + gamedata->spraycans = NULL; + gamedata->numspraycans = 0; + gamedata->gotspraycans = 0; + + UINT16 i; + for (i = 0; i < nummapheaders; i++) + { + if (!mapheaderinfo[i]) + continue; + mapheaderinfo[i]->cache_spraycan = UINT16_MAX; + } + + for (i = 0; i < numskincolors; i++) + { + skincolors[i].cache_spraycan = UINT16_MAX; + } Z_Free(gamedata->challengegrid); gamedata->challengegrid = NULL; @@ -640,6 +656,142 @@ void M_ClearSecrets(void) gamedata->chaokeys = 3; // Start with 3 !! } +// For lack of a better idea on where to put this +static void M_Shuffle_UINT16(UINT16 *list, size_t len) +{ + size_t i; + UINT16 temp; + + while (len > 1) + { + i = M_RandomKey(len); + + if (i == --len) + continue; + + temp = list[i]; + list[i] = list[len]; + list[len] = temp; + } +} + +static void M_AssignSpraycans(void) +{ + // Very convenient I'm programming this on + // the release date of "Bomb Rush Cyberfunk". + // ~toast 180823 (committed a day later) + + // Init ordered list of skincolors + UINT16 tempcanlist[MAXSKINCOLORS]; + UINT16 listlen = 0, prependlen = 0; + + UINT32 i, j; + conditionset_t *c; + condition_t *cn; + + const UINT16 prependoffset = MAXSKINCOLORS-1; + + // None of the following accounts for cans being removed, only added... + for (i = 0; i < MAXCONDITIONSETS; ++i) + { + c = &conditionSets[i]; + if (!c->numconditions) + continue; + + for (j = 0; j < c->numconditions; ++j) + { + cn = &c->condition[j]; + if (cn->type != UC_SPRAYCAN) + continue; + + // G_LoadGamedata, G_SaveGameData doesn't support custom skincolors right now. + if (cn->requirement >= SKINCOLOR_FIRSTFREESLOT) //numskincolors) + continue; + + if (skincolors[cn->requirement].cache_spraycan != UINT16_MAX) + continue; + + // Still invalid, just in case it isn't assigned one later + skincolors[cn->requirement].cache_spraycan = UINT16_MAX-1; + + if (!cn->extrainfo1) + { + //CONS_Printf("DDD - Adding standard can color %d\n", cn->requirement); + + tempcanlist[listlen] = cn->requirement; + listlen++; + continue; + } + + //CONS_Printf("DDD - Prepending early can color %d\n", cn->requirement); + + tempcanlist[prependoffset - prependlen] = cn->requirement; + prependlen++; + } + } + + if (listlen) + { + // Swap the standard colours for random order + M_Shuffle_UINT16(tempcanlist, listlen); + } + else if (!prependlen) + { + return; + } + + if (prependlen) + { + // Swap the early colours for random order + M_Shuffle_UINT16(tempcanlist + prependoffset - (prependlen - 1), prependlen); + + // Put at the front of the main list + // (technically reverses the prepend order, but it + // was LITERALLY just shuffled so it doesn't matter) + while (prependlen) + { + prependlen--; + tempcanlist[listlen] = tempcanlist[prependlen]; + tempcanlist[prependlen] = tempcanlist[prependoffset - prependlen]; + listlen++; + } + } + + gamedata->spraycans = Z_Realloc( + gamedata->spraycans, + sizeof(candata_t) * (gamedata->numspraycans + listlen), + PU_STATIC, + NULL); + + for (i = 0; i < listlen; i++) + { + gamedata->spraycans[gamedata->numspraycans].map = NEXTMAP_INVALID; + gamedata->spraycans[gamedata->numspraycans].col = tempcanlist[i]; + + skincolors[tempcanlist[i]].cache_spraycan = gamedata->numspraycans; + + gamedata->numspraycans++; + } +} + +void M_FinaliseGameData(void) +{ + //M_PopulateChallengeGrid(); -- This can be done lazily when we actually need it + + // Place the spraycans, which CAN'T be done lazily. + M_AssignSpraycans(); + + // Don't consider loaded until it's a success! + // It used to do this much earlier, but this would cause the gamedata + // to save over itself when it I_Errors from corruption, which can + // accidentally delete players' legitimate data if the code ever has + // any tiny mistakes! + gamedata->loaded = true; + + // Silent update unlockables in case they're out of sync with conditions + M_UpdateUnlockablesAndExtraEmblems(false, true); +} + // ---------------------- // Condition set checking // ---------------------- @@ -664,14 +816,15 @@ void M_UpdateConditionSetsPending(void) switch (cn->type) { + case UC_CHARACTERWINS: case UCRP_ISCHARACTER: { cn->requirement = R_SkinAvailable(cn->stringvar); if (cn->requirement < 0) { - CONS_Alert(CONS_WARNING, "UCRP_ISCHARACTER: Invalid character %s for condition ID %d", cn->stringvar, cn->id+1); - return; + CONS_Alert(CONS_WARNING, "UC TYPE %u: Invalid character %s for condition ID %d", cn->type, cn->stringvar, cn->id+1); + continue; } Z_Free(cn->stringvar); @@ -826,6 +979,12 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) case UC_MAPTIME: // Requires time on map <= x return (G_GetBestTime(cn->extrainfo1) <= (unsigned)cn->requirement); + case UC_CHARACTERWINS: + if (cn->requirement < 0) + return false; + + return (skins[cn->requirement].records.wins >= (UINT32)cn->extrainfo1); + case UC_ALLCHAOS: case UC_ALLSUPER: case UC_ALLEMERALDS: @@ -870,6 +1029,19 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) return false; case UC_PASSWORD: return (cn->stringvar == NULL); + case UC_SPRAYCAN: + { + if (cn->requirement <= 0 + || cn->requirement >= numskincolors) + return false; + + UINT16 can_id = skincolors[cn->requirement].cache_spraycan; + + if (can_id >= gamedata->numspraycans) + return false; + + return (gamedata->spraycans[can_id].map < nummapheaders); + } // Just for string building case UC_AND: @@ -1185,6 +1357,19 @@ static const char *M_GetConditionString(condition_t *cn) return work; } + case UC_CHARACTERWINS: + { + if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) + return va("INVALID CHAR CONDITION \"%d:%d:%d\"", cn->type, cn->requirement, cn->extrainfo1); + work = (R_SkinUsable(-1, cn->requirement, false)) + ? skins[cn->requirement].realname + : "???"; + return va("win %d Round%s as %s", + cn->extrainfo1, + cn->extrainfo1 == 1 ? "" : "s", + work); + } + case UC_ALLCHAOS: case UC_ALLSUPER: case UC_ALLEMERALDS: @@ -1322,6 +1507,28 @@ static const char *M_GetConditionString(condition_t *cn) return NULL; case UC_PASSWORD: return "enter a secret password"; + case UC_SPRAYCAN: + { + if (cn->requirement <= 0 + || cn->requirement >= numskincolors) + return va("INVALID SPRAYCAN COLOR \"%d\"", cn->requirement); + + UINT16 can_id = skincolors[cn->requirement].cache_spraycan; + + if (can_id >= gamedata->numspraycans) + return va("INVALID SPRAYCAN ID \"%d:%u\"", + cn->requirement, + skincolors[cn->requirement].cache_spraycan + ); + + if (can_id == 0) + return "grab a Spray Can"; // Special case for the head of the list + + if (gamedata->spraycans[0].map >= nummapheaders) + return NULL; // Don't tease that there are many until you have one + + return va("grab %d Spray Cans", can_id + 1); + } case UC_AND: return "&"; diff --git a/src/m_cond.h b/src/m_cond.h index e93ef7857..b330b942e 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -41,6 +41,8 @@ typedef enum UC_MAPSPBATTACK, // MAPSPBATTACK [map] UC_MAPTIME, // MAPTIME [map] [time to beat, tics] + UC_CHARACTERWINS, // CHARACTERWINS [character] [x rounds] + UC_ALLCHAOS, // ALLCHAOS [minimum difficulty] UC_ALLSUPER, // ALLSUPER [minimum difficulty] UC_ALLEMERALDS, // ALLEMERALDS [minimum difficulty] @@ -58,6 +60,8 @@ typedef enum UC_PASSWORD, // Type in something funny + UC_SPRAYCAN, // Grab a spraycan + // Just for string building UC_AND, UC_COMMA, @@ -251,12 +255,20 @@ typedef enum { GDGT_MAX } roundsplayed_t; +struct candata_t +{ + UINT16 col; + UINT16 map; +}; + // GAMEDATA STRUCTURE // Everything that would get saved in gamedata.dat struct gamedata_t { // WHENEVER OR NOT WE'RE READY TO SAVE boolean loaded; + + // DEFERRED EVENTS RELATING TO CHALLENGE PROCESSING boolean deferredsave; boolean deferredconditioncheck; @@ -270,6 +282,11 @@ struct gamedata_t boolean unlocked[MAXUNLOCKABLES]; boolean unlockpending[MAXUNLOCKABLES]; + // SPRAYCANS COLLECTED + UINT16 numspraycans; + UINT16 gotspraycans; + candata_t* spraycans; + // CHALLENGE GRID UINT16 challengegridwidth; UINT16 *challengegrid; @@ -338,10 +355,11 @@ char *M_BuildConditionSetString(UINT16 unlockid); void M_AddRawCondition(UINT16 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2, char *stringvar); void M_UpdateConditionSetsPending(void); -// Clearing secrets +// Gamedata clear/init void M_ClearConditionSet(UINT16 set); void M_ClearSecrets(void); void M_ClearStats(void); +void M_FinaliseGameData(void); boolean M_NotFreePlay(void); UINT16 M_CheckCupEmeralds(UINT8 difficulty); diff --git a/src/menus/options-data-erase-1.c b/src/menus/options-data-erase-1.c index a4a75202c..ac31e16e2 100644 --- a/src/menus/options-data-erase-1.c +++ b/src/menus/options-data-erase-1.c @@ -60,6 +60,9 @@ static void M_EraseDataResponse(INT32 ch) // Delete the data // see also G_LoadGameData // We do these in backwards order to prevent things from being immediately re-unlocked. + + gamedata->loaded = false; + if (optionsmenu.erasecontext & EC_TIMEATTACK) G_ClearRecords(); if (optionsmenu.erasecontext & EC_STATISTICS) @@ -67,7 +70,7 @@ static void M_EraseDataResponse(INT32 ch) if (optionsmenu.erasecontext & EC_CHALLENGES) M_ClearSecrets(); - M_UpdateUnlockablesAndExtraEmblems(false, true); + M_FinaliseGameData(); // Don't softlock the Stereo on if you won't be able to access it anymore!? if (soundtest.playing && M_SecretUnlocked(SECRET_SOUNDTEST, true) == false) diff --git a/src/p_inter.c b/src/p_inter.c index dcafd07e7..890644320 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -601,26 +601,83 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Secret emblem thingy case MT_EMBLEM: { - boolean gotcollected = false; - if (!P_CanPickupEmblem(player, special->health - 1)) return; - if (P_IsLocalPlayer(player) && !gamedata->collected[special->health-1]) + if (!P_IsLocalPlayer(player)) { - gamedata->collected[special->health-1] = gotcollected = true; + // Must be party. + return; + } + + if (!gamedata->collected[special->health-1]) + { + gamedata->collected[special->health-1] = true; if (!M_UpdateUnlockablesAndExtraEmblems(true, true)) S_StartSound(NULL, sfx_ncitem); gamedata->deferredsave = true; } - if (netgame) + // Don't delete the object, just fade it. + return; + } + + case MT_SPRAYCAN: + { + if (demo.playback) { - // Don't delete the object in netgames, just fade it. + // Never collect emblems in replays. return; } - break; + if (player->bot) + { + // Your nefarious opponent puppy can't grab these for you. + return; + } + + if (!P_IsLocalPlayer(player)) + { + // Must be party. + return; + } + + // See also P_SprayCanInit + UINT16 can_id = mapheaderinfo[gamemap-1]->cache_spraycan; + + if (can_id < gamedata->numspraycans) + { + // Assigned to this level, has been grabbed + return; + } + // Prevent footguns - these won't persist when custom levels are unloaded + else if (gamemap-1 < basenummapheaders) + { + // Unassigned, get the next grabbable colour + can_id = gamedata->gotspraycans; + } + + if (can_id >= gamedata->numspraycans) + { + // We've exhausted all the spraycans to grab. + return; + } + + if (gamedata->spraycans[can_id].map >= nummapheaders) + { + gamedata->spraycans[can_id].map = gamemap-1; + mapheaderinfo[gamemap-1]->cache_spraycan = can_id; + + gamedata->gotspraycans++; + + if (!M_UpdateUnlockablesAndExtraEmblems(true, true)) + S_StartSound(NULL, sfx_ncitem); + gamedata->deferredsave = true; + } + + // Don't delete the object, just fade it. + P_SprayCanInit(special); + return; } // CTF Flags diff --git a/src/p_local.h b/src/p_local.h index a09caf896..eaf1d6349 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -196,6 +196,8 @@ boolean P_AutoPause(void); void P_ElementalFire(player_t *player, boolean cropcircle); void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound); +void P_SprayCanInit(mobj_t* mobj); + void P_HaltPlayerOrbit(player_t *player); void P_ExitPlayerOrbit(player_t *player); boolean P_PlayerOrbit(player_t *player); diff --git a/src/p_mobj.c b/src/p_mobj.c index be5b61046..bea139da0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7170,7 +7170,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1)) { trans = tr_trans50; - mobj->renderflags |= (tr_trans50 << RF_TRANSSHIFT); } if (mobj->reactiontime > 0 @@ -12226,6 +12225,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt // Ring-like items, float additional units unless args[0] is set. case MT_SPIKEBALL: case MT_EMBLEM: + case MT_SPRAYCAN: case MT_RING: case MT_BLUESPHERE: offset += mthing->thing_args[0] ? 0 : 24*FRACUNIT; @@ -12435,6 +12435,34 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) return true; } +void P_SprayCanInit(mobj_t* mobj) +{ + // See also P_TouchSpecialThing + UINT16 can_id = mapheaderinfo[gamemap-1]->cache_spraycan; + + if (can_id < gamedata->numspraycans) + { + // Assigned to this level, has been grabbed + mobj->renderflags = (tr_trans50 << RF_TRANSSHIFT); + } + // Prevent footguns - these won't persist when custom levels are unloaded + else if (gamemap-1 < basenummapheaders) + { + // Unassigned, get the next grabbable colour + can_id = gamedata->gotspraycans; + mobj->renderflags = 0; + } + + if (can_id < gamedata->numspraycans) + { + mobj->color = gamedata->spraycans[can_id].col; + } + else + { + mobj->renderflags = RF_DONTDRAW; + } +} + static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj) { fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor; @@ -12895,6 +12923,23 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj) } break; } + case MT_SPRAYCAN: + { + if (nummapspraycans) + { + if (nummapspraycans != UINT8_MAX) + nummapspraycans++; + + P_RemoveMobj(mobj); + return false; + } + + P_SetScale(mobj, mobj->destscale = 2*mobj->scale); + + P_SprayCanInit(mobj); + nummapspraycans++; + break; + } case MT_SKYBOX: { P_InitSkyboxPoint(mobj, mthing); diff --git a/src/p_saveg.c b/src/p_saveg.c index b171b1091..9899d7b2d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4272,6 +4272,10 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) { P_InitSkyboxPoint(mobj, mobj->spawnpoint); } + else if (mobj->type == MT_SPRAYCAN) + { + P_SprayCanInit(mobj); + } if (diff2 & MD2_WAYPOINTCAP) P_SetTarget(&waypointcap, mobj); @@ -5813,6 +5817,10 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending) WRITEUINT32(save->p, racecountdown); WRITEUINT32(save->p, exitcountdown); + // exitcondition_t + WRITEUINT8(save->p, g_exit.losing); + WRITEUINT8(save->p, g_exit.retry); + WRITEFIXED(save->p, gravity); WRITEFIXED(save->p, mapobjectscale); @@ -5988,6 +5996,10 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading) racecountdown = READUINT32(save->p); exitcountdown = READUINT32(save->p); + // exitcondition_t + g_exit.losing = READUINT8(save->p); + g_exit.retry = READUINT8(save->p); + gravity = READFIXED(save->p); mapobjectscale = READFIXED(save->p); diff --git a/src/p_setup.c b/src/p_setup.c index 14fa88c42..958bfa22e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -462,6 +462,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 num) mapheaderinfo[num]->justPlayed = 0; mapheaderinfo[num]->anger = 0; + mapheaderinfo[num]->cache_spraycan = UINT16_MAX; + mapheaderinfo[num]->customopts = NULL; mapheaderinfo[num]->numCustomOptions = 0; } @@ -813,6 +815,22 @@ static void P_SpawnMapThings(boolean spawnemblems) } Z_Free(loopends); + + if (spawnemblems) + { + const UINT8 recommendedcans = +#ifdef DEVELOP + !(mapheaderinfo[gamemap-1]->typeoflevel & TOL_RACE) ? 0 : +#endif + 1; + + if (nummapspraycans > recommendedcans) + CONS_Alert(CONS_ERROR, "SPRAY CANS: Map has too many Spray Cans (%d)!", nummapspraycans); +#ifdef DEVELOP + else if (nummapspraycans != recommendedcans) + CONS_Alert(CONS_ERROR, "SPRAY CANS: Krew-made Race maps need a Spray Can placed!"); +#endif + } } // Experimental groovy write function! @@ -1205,46 +1223,6 @@ static void P_LoadSidedefs(UINT8 *data) sd->toptexture = sd->midtexture = sd->bottomtexture = 0; break; - case 413: // Change music - { - if (!isfrontside) - break; - - char process[8+1]; - - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') - { - M_Memcpy(process,msd->bottomtexture,8); - process[8] = '\0'; - sd->bottomtexture = get_number(process); - } - - if (!(msd->midtexture[0] == '-' && msd->midtexture[1] == '\0') || msd->midtexture[1] != '\0') - { - M_Memcpy(process,msd->midtexture,8); - process[8] = '\0'; - sd->midtexture = get_number(process); - } - - if (msd->toptexture[0] != '-' && msd->toptexture[1] != '\0') - { - sd->line->stringargs[0] = Z_Malloc(7, PU_LEVEL, NULL); - M_Memcpy(process,msd->toptexture,8); - process[8] = '\0'; - - // If they type in O_ or D_ and their music name, just shrug, - // then copy the rest instead. - if ((process[0] == 'O' || process[0] == 'D') && process[7]) - M_Memcpy(sd->line->stringargs[0], process+2, 6); - else // Assume it's a proper music name. - M_Memcpy(sd->line->stringargs[0], process, 6); - sd->line->stringargs[0][6] = '\0'; - } - - break; - } - case 414: // Play SFX { sd->toptexture = sd->midtexture = sd->bottomtexture = 0; @@ -5673,28 +5651,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[4] = lines[i].frontsector->ceilingheight >> FRACBITS; break; - case 413: //Change music - if (lines[i].flags & ML_NOCLIMB) - lines[i].args[1] |= TMM_ALLPLAYERS; - if (lines[i].flags & ML_SKEWTD) - lines[i].args[1] |= TMM_OFFSET; - if (lines[i].flags & ML_NOSKEW) - lines[i].args[1] |= TMM_FADE; - if (lines[i].flags & ML_BLOCKPLAYERS) - lines[i].args[1] |= TMM_NORELOAD; - if (lines[i].flags & ML_NOTBOUNCY) - lines[i].args[1] |= TMM_FORCERESET; - if (lines[i].flags & ML_MIDSOLID) - lines[i].args[1] |= TMM_NOLOOP; - if (lines[i].flags & ML_MIDPEG) - lines[i].args[1] |= TMM_NOCREDIT; - lines[i].args[2] = sides[lines[i].sidenum[0]].midtexture; - lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; - lines[i].args[4] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; - lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0; - lines[i].args[6] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1; - lines[i].args[7] = sides[lines[i].sidenum[0]].bottomtexture; - break; case 414: //Play sound effect lines[i].args[3] = tag; if (tag != 0) @@ -7557,6 +7513,8 @@ static void P_InitLevelSettings(void) maptargets = numtargets = 0; battleprisons = false; + nummapspraycans = 0; + // emerald hunt hunt1 = hunt2 = hunt3 = NULL; @@ -7592,6 +7550,9 @@ static void P_InitLevelSettings(void) racecountdown = exitcountdown = musiccountdown = exitfadestarted = 0; curlap = bestlap = 0; // SRB2Kart + g_exit.losing = false; + g_exit.retry = false; + // Gamespeed and frantic items gamespeed = KARTSPEED_EASY; franticitems = false; @@ -8235,7 +8196,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) if (K_PodiumSequence()) { // mapmusrng is set by local player position in K_ResetCeremony - P_ResetLevelMusic(); P_LoadLevelMusic(); } else if (gamestate == GS_LEVEL) @@ -8693,7 +8653,7 @@ lumpnum_t wadnamelump = LUMPERROR; INT16 wadnamemap = 0; // gamemap based // Initialising map data (and catching replacements)... -UINT8 P_InitMapData(boolean existingmapheaders) +UINT8 P_InitMapData(void) { UINT8 ret = 0; INT32 i, j; @@ -8745,7 +8705,7 @@ UINT8 P_InitMapData(boolean existingmapheaders) if (maplump == LUMPERROR) { #ifndef DEVELOP - if (!existingmapheaders) + if (!basenummapheaders) { I_Error("P_InitMapData: Base map %s has a header but no level\n", name); } @@ -8762,7 +8722,7 @@ UINT8 P_InitMapData(boolean existingmapheaders) ret |= MAPRET_ADDED; CONS_Printf("%s\n", name); - if (existingmapheaders && mapheaderinfo[i]->lumpnum != LUMPERROR) + if (basenummapheaders && mapheaderinfo[i]->lumpnum != LUMPERROR) { G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you @@ -9079,7 +9039,7 @@ boolean P_MultiSetupWadFiles(boolean fullsetup) if (partadd_stage == 2) { - UINT8 mapsadded = P_InitMapData(true); + UINT8 mapsadded = P_InitMapData(); if (!mapsadded) CONS_Printf(M_GetText("No maps added\n")); diff --git a/src/p_setup.h b/src/p_setup.h index 1d474dd10..bcffd85b2 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -114,7 +114,7 @@ boolean P_AddWadFile(const char *wadfilename); #define MAPRET_ADDED (1) #define MAPRET_CURRENTREPLACED (1<<1) -UINT8 P_InitMapData(boolean existingmapheaders); +UINT8 P_InitMapData(void); extern lumpnum_t wadnamelump; extern INT16 wadnamemap; #define WADNAMECHECK(name) (!strncmp(name, "WADNAME", 7)) diff --git a/src/p_spec.c b/src/p_spec.c index bd8791484..85003e43e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2886,88 +2886,6 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha } break; - case 413: // Change music - // FIXME: port to new music system -#if 0 - // console player only unless TMM_ALLPLAYERS is set - if ((args[1] & TMM_ALLPLAYERS) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction) - { - boolean musicsame = (!stringargs[0] || !stringargs[0][0] || !strnicmp(stringargs[0], S_MusicName(), 7)); - UINT16 tracknum = (UINT16)max(args[7], 0); - INT32 position = (INT32)max(args[2], 0); - UINT32 prefadems = (UINT32)max(args[3], 0); - UINT32 postfadems = (UINT32)max(args[4], 0); - UINT8 fadetarget = (UINT8)max(args[5], 0); - INT16 fadesource = (INT16)max(args[6], -1); - - // Seek offset from current song position - if (args[1] & TMM_OFFSET) - { - // adjust for loop point if subtracting - if (position < 0 && S_GetMusicLength() && - S_GetMusicPosition() > S_GetMusicLoopPoint() && - S_GetMusicPosition() + position < S_GetMusicLoopPoint()) - position = max(S_GetMusicLength() - (S_GetMusicLoopPoint() - (S_GetMusicPosition() + position)), 0); - else - position = max(S_GetMusicPosition() + position, 0); - } - - // Fade current music to target volume (if music won't be changed) - if ((args[1] & TMM_FADE) && fadetarget && musicsame) - { - // 0 fadesource means fade from current volume. - // meaning that we can't specify volume 0 as the source volume -- this starts at 1. - if (!fadesource) - fadesource = -1; - - if (!postfadems) - S_SetInternalMusicVolume(fadetarget); - else - S_FadeMusicFromVolume(fadetarget, fadesource, postfadems); - - if (position) - S_SetMusicPosition(position); - } - // Change the music and apply position/fade operations - else - { - if (!stringargs[0]) - break; - - strncpy(mapmusname, stringargs[0], 7); - mapmusname[6] = 0; - - mapmusflags = tracknum & MUSIC_TRACKMASK; - if (!(args[1] & TMM_NORELOAD)) - mapmusflags |= MUSIC_RELOADRESET; - if (args[1] & TMM_FORCERESET) - mapmusflags |= MUSIC_FORCERESET; - - mapmusposition = position; - mapmusresume = 0; - - S_ChangeMusicEx(mapmusname, mapmusflags, !(args[1] & TMM_NOLOOP), position, - !(args[1] & TMM_FADE) ? prefadems : 0, - !(args[1] & TMM_FADE) ? postfadems : 0); - - if (!(args[1] & TMM_NOCREDIT)) - S_ShowMusicCredit(); - - if ((args[1] & TMM_FADE) && fadetarget) - { - if (!postfadems) - S_SetInternalMusicVolume(fadetarget); - else - S_FadeMusicFromVolume(fadetarget, fadesource, postfadems); - } - } - - // Except, you can use the TMM_NORELOAD flag to change this behavior. - // if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. - } -#endif - break; - case 414: // Play SFX P_PlaySFX(stringargs[0] ? get_number(stringargs[0]) : sfx_None, mo, callsec, args[3], args[1], args[2]); break; diff --git a/src/p_user.c b/src/p_user.c index 8882f7872..b3f88115f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1318,19 +1318,12 @@ void P_DoPlayerExit(player_t *player, pflags_t flags) if (P_CheckRacers() && !exitcountdown) { - if (specialout == true) - { - exitcountdown = TICRATE; - } - else - { - exitcountdown = raceexittime+1; - } + G_BeginLevelExit(); } } else if (!exitcountdown) // All other gametypes { - exitcountdown = raceexittime+1; + G_BeginLevelExit(); } if (grandprixinfo.gp == true && player->bot == false && losing == false) @@ -3777,7 +3770,7 @@ void P_DoTimeOver(player_t *player) if (!exitcountdown) { - exitcountdown = raceexittime; + G_BeginLevelExit(); } } diff --git a/src/r_main.c b/src/r_main.c index d50c43644..50fee5b58 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -151,7 +151,6 @@ static void ChaseCam2_OnChange(void); static void ChaseCam3_OnChange(void); static void ChaseCam4_OnChange(void); -consvar_t cv_tailspickup = CVAR_INIT ("tailspickup", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_chasecam[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("chasecam", "On", CV_CALL, CV_OnOff, ChaseCam_OnChange), CVAR_INIT ("chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChange), @@ -181,8 +180,6 @@ consvar_t cv_homremoval = CVAR_INIT ("homremoval", "Yes", CV_SAVE, homremoval_co consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL); -consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL); - consvar_t cv_drawpickups = CVAR_INIT ("drawpickups", "Yes", CV_CHEAT, CV_YesNo, NULL); consvar_t cv_debugfinishline = CVAR_INIT ("debugfinishline", "Off", CV_CHEAT, CV_OnOff, NULL); @@ -1693,7 +1690,6 @@ void R_RegisterEngineStuff(void) UINT8 i; CV_RegisterVar(&cv_gravity); - CV_RegisterVar(&cv_tailspickup); CV_RegisterVar(&cv_allowmlook); CV_RegisterVar(&cv_homremoval); diff --git a/src/r_main.h b/src/r_main.h index 0f5560308..c201a50be 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -133,7 +133,6 @@ extern consvar_t cv_ffloorclip; extern consvar_t cv_drawdist, cv_drawdist_precip; extern consvar_t cv_fov[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_skybox; -extern consvar_t cv_tailspickup; extern consvar_t cv_drawpickups; extern consvar_t cv_debugfinishline; diff --git a/src/s_sound.c b/src/s_sound.c index eb6c9a2e1..e6abc1791 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -59,12 +59,6 @@ static void GameDigiMusic_OnChange(void); static void PlayMusicIfUnfocused_OnChange(void); static void PlaySoundIfUnfocused_OnChange(void); -#ifdef HAVE_OPENMPT -static void ModFilter_OnChange(void); -#endif - -consvar_t cv_samplerate = CVAR_INIT ("samplerate", "22050", 0, CV_Unsigned, NULL); //Alam: For easy hacking? - // stereo reverse consvar_t stereoreverse = CVAR_INIT ("stereoreverse", "Off", CV_SAVE, CV_OnOff, NULL); @@ -93,26 +87,10 @@ consvar_t cv_closedcaptioning = CVAR_INIT ("closedcaptioning", "Off", CV_SAVE|CV consvar_t cv_gamedigimusic = CVAR_INIT ("music", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange); consvar_t cv_gamesounds = CVAR_INIT ("sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange); -static CV_PossibleValue_t music_resync_threshold_cons_t[] = { - {0, "MIN"}, - {1000, "MAX"}, - {0, NULL} -}; - -consvar_t cv_music_resync_threshold = CVAR_INIT ("music_resync_threshold", "100", CV_SAVE|CV_CALL, music_resync_threshold_cons_t, I_UpdateSongLagThreshold); -consvar_t cv_music_resync_powerups_only = CVAR_INIT ("music_resync_powerups_only", "No", CV_SAVE|CV_CALL, CV_YesNo, I_UpdateSongLagConditions); - // Window focus sound sytem toggles consvar_t cv_playmusicifunfocused = CVAR_INIT ("playmusicifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlayMusicIfUnfocused_OnChange); consvar_t cv_playsoundifunfocused = CVAR_INIT ("playsoundsifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlaySoundIfUnfocused_OnChange); -#ifdef HAVE_OPENMPT -openmpt_module *openmpt_mhandle = NULL; - -static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; -consvar_t cv_modfilter = CVAR_INIT ("modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange); -#endif - #define S_MAX_VOLUME 127 // when to clip out sounds @@ -249,19 +227,11 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&precachesound); CV_RegisterVar(&surround); - CV_RegisterVar(&cv_samplerate); CV_RegisterVar(&cv_playsoundifunfocused); CV_RegisterVar(&cv_playmusicifunfocused); CV_RegisterVar(&cv_gamesounds); CV_RegisterVar(&cv_gamedigimusic); - CV_RegisterVar(&cv_music_resync_threshold); - CV_RegisterVar(&cv_music_resync_powerups_only); - -#ifdef HAVE_OPENMPT - CV_RegisterVar(&cv_modfilter); -#endif - COM_AddCommand("tunes", Command_Tunes_f); COM_AddCommand("restartaudio", Command_RestartAudio_f); COM_AddCommand("playsound", Command_PlaySound); @@ -2509,11 +2479,3 @@ static void PlaySoundIfUnfocused_OnChange(void) if (window_notinfocus && !cv_playsoundifunfocused.value) S_StopSounds(); } - -#ifdef HAVE_OPENMPT -void ModFilter_OnChange(void) -{ - if (openmpt_mhandle) - openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); -} -#endif diff --git a/src/s_sound.h b/src/s_sound.h index 805413604..d101f307c 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -19,18 +19,10 @@ #include "command.h" #include "tables.h" // angle_t -#ifdef HAVE_OPENMPT -#include "libopenmpt/libopenmpt.h" -#endif - #ifdef __cplusplus extern "C" { #endif -#ifdef HAVE_OPENMPT -extern openmpt_module *openmpt_mhandle; -#endif - // mask used to indicate sound origin is player item pickup #define PICKUP_SOUND 0x8000 @@ -52,13 +44,6 @@ extern consvar_t cv_gamesounds; extern consvar_t cv_playmusicifunfocused; extern consvar_t cv_playsoundifunfocused; -extern consvar_t cv_music_resync_threshold; -extern consvar_t cv_music_resync_powerups_only; - -#ifdef HAVE_OPENMPT -extern consvar_t cv_modfilter; -#endif - extern CV_PossibleValue_t soundvolume_cons_t[]; typedef enum diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 88eb183e5..7a2a09d23 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -115,7 +115,6 @@ rendermode_t chosenrendermode = render_none; // set by command line arguments // synchronize page flipping with screen refresh consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "Off", CV_SAVE, CV_OnOff, NULL); -static consvar_t cv_stretch = CVAR_INIT ("stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL); static consvar_t cv_alwaysgrabmouse = CVAR_INIT ("alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL); UINT8 graphics_started = 0; // Is used in console.c and screen.c @@ -1606,7 +1605,6 @@ void I_StartupGraphics(void) COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); COM_AddCommand ("vid_mode", VID_Command_Mode_f); CV_RegisterVar (&cv_vidwait); - CV_RegisterVar (&cv_stretch); CV_RegisterVar (&cv_alwaysgrabmouse); disable_mouse = static_cast(M_CheckParm("-nomouse")); disable_fullscreen = M_CheckParm("-win") ? SDL_TRUE : SDL_FALSE; diff --git a/src/typedef.h b/src/typedef.h index 7bbc232b6..93427ad47 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -134,6 +134,7 @@ TYPEDEF (unloaded_mapheader_t); TYPEDEF (tolinfo_t); TYPEDEF (cupheader_t); TYPEDEF (unloaded_cupheader_t); +TYPEDEF (exitcondition_t); // font.h TYPEDEF (font_t); @@ -238,6 +239,7 @@ TYPEDEF (condition_t); TYPEDEF (conditionset_t); TYPEDEF (emblem_t); TYPEDEF (unlockable_t); +TYPEDEF (candata_t); TYPEDEF (gamedata_t); TYPEDEF (challengegridextradata_t); diff --git a/src/y_inter.c b/src/y_inter.c index 391d0861b..6c980a7ee 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -71,6 +71,7 @@ static patch_t *widebgpatch = NULL; static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK static patch_t *interpic = NULL; // custom picture defined in map header +#define INFINITE_TIMER (INT16_MAX) // just some arbitrarily large value that won't easily overflow static INT32 timer; static INT32 powertype = PWRLV_DISABLED; @@ -86,6 +87,16 @@ intertype_t intertype = int_none; static huddrawlist_h luahuddrawlist_intermission; +static boolean Y_CanSkipIntermission(void) +{ + if (!netgame) + { + return true; + } + + return false; +} + static void Y_UnloadData(void); // @@ -1533,6 +1544,17 @@ finalcounter: } } + if (Y_CanSkipIntermission()) + { + K_drawButton( + 2*FRACUNIT, + (BASEVIDHEIGHT - 16)*FRACUNIT, + 0, + kp_button_a[1], + M_MenuConfirmHeld(0) + ); + } + else { const INT32 tickDown = (timer + 1)/TICRATE; @@ -1578,6 +1600,46 @@ void Y_Ticker(void) LUA_HOOK(IntermissionThinker); + if (Y_CanSkipIntermission()) + { + if (M_MenuConfirmPressed(0)) + { + // If there is a roundqueue, make time for it. + // Else, end instantly on button press. + // Actually, give it a slight delay, so the "kaching" sound isn't cut off. + const tic_t end = roundqueue.size != 0 ? 3*TICRATE : TICRATE; + + if (intertic == -1) // card flip hasn't started + { + if (sorttic != -1) + { + intertic = sorttic; + } + else + { + intertic = 0; + timer = end; + } + } + else if (timer >= INFINITE_TIMER && intertic >= sorttic + 16) // card done flipping + { + const INT32 kaching = sorttic + 16 + (2*TICRATE); + + if (intertic < kaching) + { + intertic = kaching; // kaching immediately + } + + timer = end; + } + } + + if (intertic == -1) + { + return; + } + } + intertic++; // Team scramble code for team match and CTF. @@ -1590,7 +1652,7 @@ void Y_Ticker(void) P_DoTeamscrambling(); }*/ - if ((timer && !--timer) + if ((timer < INFINITE_TIMER && --timer <= 0) || (intertic == endtic)) { Y_EndIntermission(); @@ -1665,6 +1727,12 @@ void Y_Ticker(void) r++; data.jitter[data.num[q]] = 1; + // Player can skip the tally, kaching! + if (Y_CanSkipIntermission() && timer < INFINITE_TIMER) + { + data.increase[data.num[q]] = 0; + } + if (powertype != PWRLV_DISABLED) { // Power Levels @@ -1815,6 +1883,21 @@ void Y_StartIntermission(void) sorttic = max((timer/2) - 2*TICRATE, 2*TICRATE); } + // TODO: code's a mess, I'm just making it extra clear + // that this piece of code is supposed to take priority + // over the above. :) + if (Y_CanSkipIntermission()) + { + timer = INFINITE_TIMER; // doesn't count down + + if (sorttic != -1) + { + // Will start immediately, but must be triggered. + // Needs to be TICRATE to bypass a condition in Y_Ticker. + sorttic = TICRATE; + } + } + // We couldn't display the intermission even if we wanted to. // But we still need to give the players their score bonuses, dummy. //if (dedicated) return;