diff --git a/bin/Mingw/Debug/.gitignore b/bin/Mingw/Debug/.gitignore index 834f313e..3458ff76 100644 --- a/bin/Mingw/Debug/.gitignore +++ b/bin/Mingw/Debug/.gitignore @@ -1,3 +1,4 @@ *.exe *.mo r_opengl.dll +*.bat diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore index 834f313e..3458ff76 100644 --- a/bin/Mingw/Release/.gitignore +++ b/bin/Mingw/Release/.gitignore @@ -1,3 +1,4 @@ *.exe *.mo r_opengl.dll +*.bat diff --git a/src/command.c b/src/command.c index a1f0a46b..305a5eee 100644 --- a/src/command.c +++ b/src/command.c @@ -1088,32 +1088,42 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) if (var->PossibleValue[0].strvalue && !stricmp(var->PossibleValue[0].strvalue, "MIN")) // bounded cvar { +#define MINVAL 0 +#define MAXVAL 1 INT32 i; - // search for maximum - for (i = 1; var->PossibleValue[i].strvalue; i++) - if (!stricmp(var->PossibleValue[i].strvalue, "MAX")) - break; + #ifdef PARANOIA - if (!var->PossibleValue[i].strvalue) + if (!var->PossibleValue[MAXVAL].strvalue) I_Error("Bounded cvar \"%s\" without maximum!\n", var->name); #endif - if ((v != INT32_MIN && v < var->PossibleValue[0].value) || !stricmp(valstr, "MIN")) + // search for other + for (i = MAXVAL+1; var->PossibleValue[i].strvalue; i++) + if (!stricmp(var->PossibleValue[i].strvalue, valstr)) + { + var->value = var->PossibleValue[i].value; + var->string = var->PossibleValue[i].strvalue; + goto finish; + } + + if ((v != INT32_MIN && v < var->PossibleValue[MINVAL].value) || !stricmp(valstr, "MIN")) { - v = var->PossibleValue[0].value; - valstr = var->PossibleValue[0].strvalue; + v = var->PossibleValue[MINVAL].value; + valstr = var->PossibleValue[MINVAL].strvalue; override = true; overrideval = v; } - else if ((v != INT32_MIN && v > var->PossibleValue[i].value) || !stricmp(valstr, "MAX")) + else if ((v != INT32_MIN && v > var->PossibleValue[MAXVAL].value) || !stricmp(valstr, "MAX")) { - v = var->PossibleValue[i].value; - valstr = var->PossibleValue[i].strvalue; + v = var->PossibleValue[MAXVAL].value; + valstr = var->PossibleValue[MAXVAL].strvalue; override = true; overrideval = v; } if (v == INT32_MIN) goto badinput; +#undef MINVAL +#undef MAXVAL } else { @@ -1453,7 +1463,6 @@ void CV_AddValue(consvar_t *var, INT32 increment) if (var->PossibleValue) { -#define MINVAL 0 if (var == &cv_nextmap) { // Special case for the nextmap variable, used only directly from the menu @@ -1478,33 +1487,52 @@ void CV_AddValue(consvar_t *var, INT32 increment) } if (newvalue == oldvalue) - gt = -1; // don't loop forever if there's none of a certain gametype + break; // don't loop forever if there's none of a certain gametype if(!mapheaderinfo[newvalue]) continue; // Don't allocate the header. That just makes memory usage skyrocket. - } while (newvalue != oldvalue && !M_CanShowLevelInList(newvalue, gt)); + } while (!M_CanShowLevelInList(newvalue, gt)); var->value = newvalue + 1; var->func(); return; } } +#define MINVAL 0 +#define MAXVAL 1 else if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN")) - { - // search the next to last - for (max = 0; var->PossibleValue[max+1].strvalue; max++) - ; + { // SRB2Kart +#ifdef PARANOIA + if (!var->PossibleValue[MAXVAL].strvalue) + I_Error("Bounded cvar \"%s\" without maximum!\n", var->name); +#endif - if (newvalue < var->PossibleValue[MINVAL].value) // add the max+1 - newvalue += var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1; + if (newvalue < var->PossibleValue[MINVAL].value || newvalue > var->PossibleValue[MAXVAL].value) + { + INT32 currentindice = -1, newindice; + for (max = MAXVAL+1; var->PossibleValue[max].strvalue; max++) + if (var->PossibleValue[max].value == var->value) + currentindice = max; - newvalue = var->PossibleValue[MINVAL].value + (newvalue - var->PossibleValue[MINVAL].value) - % (var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1); + if (currentindice == -1 && max != MAXVAL+1) + newindice = ((increment > 0) ? MAXVAL : max) + increment; + else + newindice = currentindice + increment; - CV_SetValue(var, newvalue); -#undef MINVAL + if (newindice >= max || newindice <= MAXVAL) + { + newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value; + CV_SetValue(var, newvalue); + } + else + CV_Set(var, var->PossibleValue[newindice].strvalue); + } + else + CV_SetValue(var, newvalue); } +#undef MINVAL +#undef MAXVAL else { INT32 currentindice = -1, newindice; @@ -1514,8 +1542,6 @@ void CV_AddValue(consvar_t *var, INT32 increment) if (var->PossibleValue[max].value == var->value) currentindice = max; - max--; - if (var == &cv_chooseskin) { // Special case for the chooseskin variable, used only directly from the menu @@ -1578,7 +1604,7 @@ void CV_AddValue(consvar_t *var, INT32 increment) var->value); #endif - newindice = (currentindice + increment + max + 1) % (max+1); + newindice = (currentindice + increment + max) % max; CV_Set(var, var->PossibleValue[newindice].strvalue); } } diff --git a/src/console.c b/src/console.c index c0f12055..43d5df2d 100644 --- a/src/console.c +++ b/src/console.c @@ -139,6 +139,21 @@ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Gray"}, {2, {0, NULL}}; consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t menuhighlight_cons_t[] = +{ + {0, "Game type"}, + {V_YELLOWMAP, "Always yellow"}, + {V_PURPLEMAP, "Always purple"}, + {V_GREENMAP, "Always green"}, + {V_BLUEMAP, "Always blue"}, + {V_REDMAP, "Always red"}, + {V_GRAYMAP, "Always gray"}, + {V_ORANGEMAP, "Always orange"}, + {V_SKYMAP, "Always sky-blue"}, + {0, NULL} +}; +consvar_t cons_menuhighlight = {"menuhighlight", "Game type", CV_SAVE, menuhighlight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + static void CON_Print(char *msg); // @@ -227,13 +242,7 @@ static void CONS_Bind_f(void) // Font colormap colors // TODO: This could probably be improved somehow... // These colormaps are 99% identical, with just a few changed bytes -UINT8 *yellowmap; -UINT8 *purplemap; -UINT8 *lgreenmap; -UINT8 *bluemap; -UINT8 *graymap; -UINT8 *redmap; -UINT8 *orangemap; +UINT8 *yellowmap, *purplemap, *greenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap; // Console BG color UINT8 *consolebgmap = NULL; @@ -278,39 +287,34 @@ static void CONS_backcolor_Change(void) static void CON_SetupColormaps(void) { INT32 i; + UINT8 *memorysrc = (UINT8 *)Z_Malloc((256*8), PU_STATIC, NULL); - yellowmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - graymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - purplemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - lgreenmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - bluemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - redmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - orangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + purplemap = memorysrc; + yellowmap = (purplemap+256); + greenmap = (yellowmap+256); + bluemap = (greenmap+256); + redmap = (bluemap+256); + graymap = (redmap+256); + orangemap = (graymap+256); + skymap = (orangemap+256); // setup the other colormaps, for console text // these don't need to be aligned, unless you convert the // V_DrawMappedPatch() into optimised asm. - for (i = 0; i < 256; i++) - { - yellowmap[i] = (UINT8)i; // remap each color to itself... - graymap[i] = (UINT8)i; - purplemap[i] = (UINT8)i; - lgreenmap[i] = (UINT8)i; - bluemap[i] = (UINT8)i; - redmap[i] = (UINT8)i; - orangemap[i] = (UINT8)i; - } + for (i = 0; i < (256*8); i++, ++memorysrc) + *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... // SRB2Kart: Different console font, new colors - yellowmap[120] = (UINT8)103; purplemap[120] = (UINT8)194; - lgreenmap[120] = (UINT8)162; + yellowmap[120] = (UINT8)103; + greenmap[120] = (UINT8)162; bluemap[120] = (UINT8)228; graymap[120] = (UINT8)10; - redmap[120] = (UINT8)126; - orangemap[120] = (UINT8)85; + redmap[120] = (UINT8)126; // battle + orangemap[120] = (UINT8)85; // record attack + skymap[120] = (UINT8)214; // race // Init back colormap CON_SetupBackColormap(); @@ -367,6 +371,7 @@ void CON_Init(void) CV_RegisterVar(&cons_height); CV_RegisterVar(&cons_backpic); CV_RegisterVar(&cons_backcolor); + CV_RegisterVar(&cons_menuhighlight); COM_AddCommand("bind", CONS_Bind_f); } else @@ -1620,6 +1625,6 @@ void CON_Drawer(void) if (con_curlines > 0) CON_DrawConsole(); else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS - || gamestate == GS_VOTING) + || gamestate == GS_VOTING || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS) CON_DrawHudlines(); } diff --git a/src/console.h b/src/console.h index 8cf6483f..896214c9 100644 --- a/src/console.h +++ b/src/console.h @@ -36,9 +36,9 @@ extern INT32 con_clearlines; // lines of top of screen to refresh extern boolean con_hudupdate; // hud messages have changed, need refresh extern UINT32 con_scalefactor; // console text scale factor -extern consvar_t cons_backcolor; +extern consvar_t cons_backcolor, cons_menuhighlight; -extern UINT8 *yellowmap, *purplemap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap; +extern UINT8 *yellowmap, *purplemap, *greenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap; // Console bg color (auto updated to match) extern UINT8 *consolebgmap; diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0d3b9141..67055f09 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1166,7 +1166,7 @@ static inline void CL_DrawConnectionStatus(void) INT32 ccstime = I_GetTime(); // Draw background fade - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); // Draw the bottom box. M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); @@ -1559,7 +1559,7 @@ static void SV_SavedGame(void) { size_t length; UINT8 *savebuffer; - XBOXSTATIC char tmpsave[256]; + XBOXSTATIC char tmpsave[264]; if (!cv_dumpconsistency.value) return; @@ -1601,7 +1601,7 @@ static void CL_LoadReceivedSavegame(void) { UINT8 *savebuffer = NULL; size_t length, decompressedlen; - XBOXSTATIC char tmpsave[256]; + XBOXSTATIC char tmpsave[264]; sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); @@ -2062,7 +2062,7 @@ static void CL_ConnectToServer(boolean viams) tic_t asksent; #endif #ifdef JOININGAME - XBOXSTATIC char tmpsave[256]; + XBOXSTATIC char tmpsave[264]; sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); #endif @@ -2145,6 +2145,8 @@ static void CL_ConnectToServer(boolean viams) } while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); + if (netgame) + F_StartWaitingPlayers(); DEBFILE(va("Synchronisation Finished\n")); displayplayer = consoleplayer; @@ -2430,6 +2432,9 @@ static void CL_RemovePlayer(INT32 playernum) } } + if (K_IsPlayerWanted(&players[playernum])) + K_CalculateBattleWanted(); + if (gametype == GT_CTF) P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! @@ -2490,7 +2495,7 @@ static void CL_RemovePlayer(INT32 playernum) if (G_TagGametype()) //Check if you still have a game. Location flexible. =P P_CheckSurvivors(); else if (G_BattleGametype()) // SRB2Kart - K_CheckBalloons(); + K_CheckBumpers(); else if (G_RaceGametype()) P_CheckRacers(); } @@ -3534,7 +3539,7 @@ static void HandleConnect(SINT8 node) #ifdef JOININGAME if (nodewaiting[node]) { - if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING) && newnode) + if (node && newnode) { SV_SendSaveGame(node); // send a complete game state DEBFILE("send savegame\n"); @@ -3705,7 +3710,8 @@ static void HandlePacketFromAwayNode(SINT8 node) if (client) { maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); - gametype = netbuffer->u.servercfg.gametype; + if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES) + I_Error("Bad gametype in cliserv!"); modifiedgame = netbuffer->u.servercfg.modifiedgame; for (j = 0; j < MAXPLAYERS; j++) adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; @@ -3746,13 +3752,12 @@ static void HandlePacketFromAwayNode(SINT8 node) /// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook? /// Shouldn't them be downloaded even at intermission time? /// Also, according to HandleConnect, the server will send the savegame even during intermission... - if (netbuffer->u.servercfg.gamestate == GS_LEVEL - /*|| netbuffer->u.servercfg.gamestate == GS_INTERMISSION - || netbuffer->u.servercfg.gamestate == GS_VOTING*/) - cl_mode = CL_DOWNLOADSAVEGAME; - else + /// Sryder 2018-07-05: If we don't want to send the player config another way we need to send the gamestate + /// At almost any gamestate there could be joiners... So just always send gamestate? + cl_mode = ((server) ? CL_CONNECTED : CL_DOWNLOADSAVEGAME); +#else + cl_mode = CL_CONNECTED; #endif - cl_mode = CL_CONNECTED; break; } @@ -3874,9 +3879,8 @@ FILESTAMP // Update the nettics nettics[node] = realend; - // Don't do anything for packets of type NODEKEEPALIVE? - if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE - || netbuffer->packettype == PT_NODEKEEPALIVEMIS) + // This should probably still timeout though, as the node should always have a player 1 number + if (netconsole == -1) break; // If a client sends a ticcmd it should mean they are done receiving the savegame @@ -3886,6 +3890,12 @@ FILESTAMP /// \todo Use a separate cvar for that kind of timeout? freezetimeout[node] = I_GetTime() + connectiontimeout; + // Don't do anything for packets of type NODEKEEPALIVE? + // Sryder 2018/07/01: Update the freezetimeout still! + if (netbuffer->packettype == PT_NODEKEEPALIVE + || netbuffer->packettype == PT_NODEKEEPALIVEMIS) + break; + // Copy ticcmd G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); @@ -4335,7 +4345,7 @@ static INT16 Consistancy(void) { if (!playeringame[i]) ret ^= 0xCCCC; - else if (!players[i].mo); + else if (!players[i].mo || gamestate != GS_LEVEL); else { ret += players[i].mo->x; @@ -4346,7 +4356,7 @@ static INT16 Consistancy(void) } // I give up // Coop desynching enemies is painful - if (!G_RaceGametype()) + if (gamestate == GS_LEVEL) ret += P_GetRandSeed(); #ifdef MOBJCONSISTANCY @@ -4355,70 +4365,73 @@ static INT16 Consistancy(void) DEBFILE(va("Consistancy = %u\n", ret)); return ret; } - for (th = thinkercap.next; th != &thinkercap; th = th->next) + if (gamestate == GS_LEVEL) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - - mo = (mobj_t *)th; - - if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) + for (th = thinkercap.next; th != &thinkercap; th = th->next) { - ret -= mo->type; - ret += mo->x; - ret -= mo->y; - ret += mo->z; - ret -= mo->momx; - ret += mo->momy; - ret -= mo->momz; - ret += mo->angle; - ret -= mo->flags; - ret += mo->flags2; - ret -= mo->eflags; - if (mo->target) + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo = (mobj_t *)th; + + if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) { - ret += mo->target->type; - ret -= mo->target->x; - ret += mo->target->y; - ret -= mo->target->z; - ret += mo->target->momx; - ret -= mo->target->momy; - ret += mo->target->momz; - ret -= mo->target->angle; - ret += mo->target->flags; - ret -= mo->target->flags2; - ret += mo->target->eflags; - ret -= mo->target->state - states; - ret += mo->target->tics; - ret -= mo->target->sprite; - ret += mo->target->frame; + ret -= mo->type; + ret += mo->x; + ret -= mo->y; + ret += mo->z; + ret -= mo->momx; + ret += mo->momy; + ret -= mo->momz; + ret += mo->angle; + ret -= mo->flags; + ret += mo->flags2; + ret -= mo->eflags; + if (mo->target) + { + ret += mo->target->type; + ret -= mo->target->x; + ret += mo->target->y; + ret -= mo->target->z; + ret += mo->target->momx; + ret -= mo->target->momy; + ret += mo->target->momz; + ret -= mo->target->angle; + ret += mo->target->flags; + ret -= mo->target->flags2; + ret += mo->target->eflags; + ret -= mo->target->state - states; + ret += mo->target->tics; + ret -= mo->target->sprite; + ret += mo->target->frame; + } + else + ret ^= 0x3333; + if (mo->tracer && mo->tracer->type != MT_OVERLAY) + { + ret += mo->tracer->type; + ret -= mo->tracer->x; + ret += mo->tracer->y; + ret -= mo->tracer->z; + ret += mo->tracer->momx; + ret -= mo->tracer->momy; + ret += mo->tracer->momz; + ret -= mo->tracer->angle; + ret += mo->tracer->flags; + ret -= mo->tracer->flags2; + ret += mo->tracer->eflags; + ret -= mo->tracer->state - states; + ret += mo->tracer->tics; + ret -= mo->tracer->sprite; + ret += mo->tracer->frame; + } + else + ret ^= 0xAAAA; + ret -= mo->state - states; + ret += mo->tics; + ret -= mo->sprite; + ret += mo->frame; } - else - ret ^= 0x3333; - if (mo->tracer && mo->tracer->type != MT_OVERLAY) - { - ret += mo->tracer->type; - ret -= mo->tracer->x; - ret += mo->tracer->y; - ret -= mo->tracer->z; - ret += mo->tracer->momx; - ret -= mo->tracer->momy; - ret += mo->tracer->momz; - ret -= mo->tracer->angle; - ret += mo->tracer->flags; - ret -= mo->tracer->flags2; - ret += mo->tracer->eflags; - ret -= mo->tracer->state - states; - ret += mo->tracer->tics; - ret -= mo->tracer->sprite; - ret += mo->tracer->frame; - } - else - ret ^= 0xAAAA; - ret -= mo->state - states; - ret += mo->tics; - ret -= mo->sprite; - ret += mo->frame; } } #endif diff --git a/src/d_main.c b/src/d_main.c index 367a0e08..adeb6b1a 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -125,10 +125,12 @@ INT32 postimgparam3; postimg_t postimgtype4 = postimg_none; INT32 postimgparam4; #ifdef _XBOX -boolean nomidimusic = true, nosound = true; +boolean nomidimusic = false; +boolean nosound = true; boolean nodigimusic = true; #else -boolean nomidimusic = false, nosound = false; +boolean nomidimusic = false; +boolean nosound = false; boolean nodigimusic = false; // No fmod-based music #endif @@ -295,15 +297,15 @@ static void D_Display(void) { // set for all later wipedefindex = gamestate; // wipe_xxx_toblack - if (gamestate == GS_INTERMISSION) + if (gamestate == GS_TITLESCREEN && wipegamestate != GS_INTRO) + wipedefindex = wipe_timeattack_toblack; + else if (gamestate == GS_INTERMISSION) { if (intertype == int_spec) // Special Stage wipedefindex = wipe_specinter_toblack; else //if (intertype != int_coop) // Multiplayer wipedefindex = wipe_multinter_toblack; } - else if (gamestate == GS_VOTING) - wipedefindex = wipe_multinter_toblack; if (rendermode != render_none) { @@ -315,6 +317,8 @@ static void D_Display(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + if (wipegamestate == GS_LEVEL && rendermode != render_none) + V_SetPaletteLump("PLAYPAL"); // Reset the palette } F_WipeStartScreen(); @@ -368,6 +372,7 @@ static void D_Display(void) case GS_EVALUATION: F_GameEvaluationDrawer(); + HU_Erase(); HU_Drawer(); break; @@ -383,10 +388,19 @@ static void D_Display(void) case GS_TITLESCREEN: F_TitleScreenDrawer(); + if (wipe) + wipedefindex = wipe_titlescreen_toblack; break; case GS_WAITINGPLAYERS: // The clientconnect drawer is independent... + if (netgame) + { + // I don't think HOM from nothing drawing is independent... + F_WaitingPlayersDrawer(); + HU_Erase(); + HU_Drawer(); + } case GS_DEDICATEDSERVER: case GS_NULL: break; @@ -526,7 +540,7 @@ static void D_Display(void) wipegamestate = gamestate; // draw pause pic - if (paused && cv_showhud.value && (!menuactive || netgame)) + if (paused && cv_showhud.value) { INT32 py; patch_t *patch; @@ -812,9 +826,9 @@ void D_StartTitle(void) F_StartTitleScreen(); CON_ToggleOff(); - // Reset the palette - if (rendermode != render_none) - V_SetPaletteLump("PLAYPAL"); + // Reset the palette -- SRB2Kart: actually never mind let's do this in the middle of every fade + /*if (rendermode != render_none) + V_SetPaletteLump("PLAYPAL");*/ } // @@ -942,6 +956,10 @@ static void IdentifyVersion(void) D_AddFile(va(pandf,srb2waddir,"maps.kart")); D_AddFile(va(pandf,srb2waddir,"sounds.kart")); +#ifdef USE_PATCH_KART + D_AddFile(va(pandf,srb2waddir,"patch.kart")); +#endif + #if !defined (HAVE_SDL) || defined (HAVE_MIXER) { #if defined (DC) && 0 @@ -1240,25 +1258,23 @@ void D_SRB2Main(void) #ifndef DEVELOP // md5s last updated 12/14/14 // Check MD5s of autoloaded files - W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad - W_VerifyFileMD5(1, ASSET_HASH_GFX_DTA); // gfx.kart - W_VerifyFileMD5(2, ASSET_HASH_CHARS_DTA); // chars.kart - W_VerifyFileMD5(3, ASSET_HASH_MAPS_DTA); // maps.kart - // sounds.kart - since music is large, we'll ignore it for now. - + mainwads = 0; + W_VerifyFileMD5(mainwads, ASSET_HASH_SRB2_SRB); mainwads++; // srb2.srb/srb2.wad #ifdef USE_PATCH_DTA - W_VerifyFileMD5(4, ASSET_HASH_PATCH_DTA); // patch.dta + W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_DTA); mainwads++; // patch.dta +#endif + W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); mainwads++; // gfx.kart + W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); mainwads++; // chars.kart + W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); mainwads++; // maps.kart + //W_VerifyFileMD5(mainwads, ASSET_HASH_SOUNDS_KART); mainwads++; // sounds.kart - doesn't trigger modifiedgame, doesn't need an MD5...? +#ifdef USE_PATCH_KART + W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); mainwads++; // patch.kart #endif // don't check music.dta because people like to modify it, and it doesn't matter if they do // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. #endif //ifndef DEVELOP - mainwads = 4; // there are 4 wads not to unload -#ifdef USE_PATCH_DTA - ++mainwads; // patch.dta adds one more -#endif - cht_Init(); //---------------------------------------------------- READY SCREEN @@ -1325,7 +1341,7 @@ void D_SRB2Main(void) if (dedicated) { nosound = true; - nomidimusic = nodigimusic = true; + /*nomidimusic = */nodigimusic = true; } else { @@ -1334,17 +1350,17 @@ void D_SRB2Main(void) if (M_CheckParm("-nosound")) nosound = true; if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic - nomidimusic = nodigimusic = true; + /*nomidimusic = */nodigimusic = true; else { - if (M_CheckParm("-nomidimusic")) - nomidimusic = true; ; // WARNING: DOS version initmusic in I_StartupSound + /*if (M_CheckParm("-nomidimusic")) + nomidimusic = true; ; // WARNING: DOS version initmusic in I_StartupSound*/ if (M_CheckParm("-nodigmusic")) nodigimusic = true; // WARNING: DOS version initmusic in I_StartupSound } I_StartupSound(); I_InitMusic(); - S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); + S_Init(cv_soundvolume.value, cv_digmusicvolume.value);//, cv_midimusicvolume.value); CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); diff --git a/src/d_main.h b/src/d_main.h index 6dc273b1..88387a57 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -41,7 +41,7 @@ void D_SRB2Main(void); // Called by IO functions when input is detected. void D_PostEvent(const event_t *ev); #ifndef DOXYGEN -FUNCMATH void D_PostEvent_end(void); // delimiter for locking memory +void D_PostEvent_end(void); // delimiter for locking memory #endif void D_ProcessEvents(void); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5a4227c3..2c99f60d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -109,10 +109,12 @@ static void Color4_OnChange(void); static void DummyConsvar_OnChange(void); static void SoundTest_OnChange(void); +static void BaseNumLaps_OnChange(void); static void KartFrantic_OnChange(void); static void KartSpeed_OnChange(void); static void KartMirror_OnChange(void); static void KartComeback_OnChange(void); +static void KartEliminateLast_OnChange(void); #ifdef NETGAME_DEVMODE static void Fishcake_OnChange(void); @@ -220,7 +222,7 @@ static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Rando static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Non-Random"}, {3, "None"}, {0, NULL}}; -static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; +//static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; static CV_PossibleValue_t match_scoring_cons_t[] = {{0, "Normal"}, {1, "Classic"}, {0, NULL}}; static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}}; @@ -244,7 +246,7 @@ consvar_t cv_competitionboxes = {"competitionboxes", "Random", CV_NETVAR|CV_CHEA #ifdef SEENAMES static CV_PossibleValue_t seenames_cons_t[] = {{0, "Off"}, {1, "Colorless"}, {2, "Team"}, {3, "Ally/Foe"}, {0, NULL}}; -consvar_t cv_seenames = {"seenames", "Ally/Foe", CV_SAVE, seenames_cons_t, 0, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_seenames = {"seenames", "Off", CV_SAVE, seenames_cons_t, 0, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -271,26 +273,15 @@ INT32 cv_debug; consvar_t cv_usemouse = {"use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL}; -#if defined (DC) || defined (_XBOX) || defined (WMINPUT) || defined (_WII) //joystick 1 and 2 consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -#elif defined (PSP) || defined (GP2X) || defined (_NDS) //only one joystick -consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick2 = {"use_joystick2", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -#else //all esle, no joystick -consvar_t cv_usejoystick = {"use_joystick", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick2 = {"use_joystick2", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick3 = {"use_joystick3", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, +consvar_t cv_usejoystick3 = {"use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick3, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick4 = {"use_joystick4", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, +consvar_t cv_usejoystick4 = {"use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick4, 0, NULL, NULL, 0, 0, NULL}; -#endif + #if (defined (LJOYSTICK) || defined (HAVE_SDL)) #ifdef LJOYSTICK consvar_t cv_joyport = {"joyport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -315,7 +306,7 @@ consvar_t cv_matchboxes = {"matchboxes", "Normal", CV_NETVAR|CV_CHEAT, matchboxe consvar_t cv_specialrings = {"specialrings", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_powerstones = {"powerstones", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_recycler = {"tv_recycler", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +/*consvar_t cv_recycler = {"tv_recycler", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_teleporters = {"tv_teleporter", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_superring = {"tv_superring", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_supersneakers = {"tv_supersneaker", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -326,45 +317,56 @@ consvar_t cv_ringshield = {"tv_ringshield", "5", CV_NETVAR|CV_CHEAT, chanc consvar_t cv_forceshield = {"tv_forceshield", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_bombshield = {"tv_bombshield", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_1up = {"tv_1up", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_eggmanbox = {"tv_eggman", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_eggmanbox = {"tv_eggman", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};*/ // SRB2kart -consvar_t cv_magnet = {"magnets", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_boo = {"boos", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_mushroom = {"mushrooms", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_triplemushroom = {"triplemushrooms", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_megashroom = {"megashrooms", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_goldshroom = {"goldshrooms", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_star = {"stars", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_triplebanana = {"triplebananas", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fakeitem = {"fakeitems", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_banana = {"bananas", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_greenshell = {"greenshells", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_redshell = {"redshells", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_laserwisp = {"laserwisps", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_triplegreenshell = {"triplegreenshells", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_bobomb = {"bobombs", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_blueshell = {"blueshells", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_jaws = {"jaws", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fireflower = {"fireflowers", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_tripleredshell = {"tripleredshells", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lightning = {"lightning", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_feather = {"feathers", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_sneaker = {"sneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_rocketsneaker = {"rocketsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_invincibility = {"invincibility", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_banana = {"banana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_eggmanmonitor = {"eggmanmonitor", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_orbinaut = {"orbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_jawz = {"jawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mine = {"mine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ballhog = {"ballhog", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_selfpropelledbomb = {"selfpropelledbomb", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grow = {"grow", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_shrink = {"shrink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lightningshield = {"lightningshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_hyudoro = {"hyudoro", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_pogospring = {"pogospring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_triplesneaker = {"triplesneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_triplebanana = {"triplebanana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_tripleorbinaut = {"tripleorbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_dualjawz = {"dualjawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_karthud = {"karthud", "Default", CV_SAVE|CV_CALL, karthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartminimap_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_kartminimap = {"kartminimap", "4", CV_SAVE, kartminimap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartcheck = {"kartcheck", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t kartstarsfx_cons_t[] = {{0, "Music"}, {1, "SMK"}, {0, NULL}}; -consvar_t cv_kartstarsfx = {"kartstarsfx", "SMK", CV_SAVE, kartstarsfx_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t kartinvinsfx_cons_t[] = {{0, "Music"}, {1, "SFX"}, {0, NULL}}; +consvar_t cv_kartinvinsfx = {"kartinvinsfx", "SFX", CV_SAVE, kartinvinsfx_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartspeed = {"kartspeed", "Normal", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t kartballoons_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}}; -consvar_t cv_kartballoons = {"kartballoons", "3", CV_NETVAR|CV_CHEAT, kartballoons_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}}; +consvar_t cv_kartbumpers = {"kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartmirror = {"kartmirror", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartMirror_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t speedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; -consvar_t cv_speedometer = {"speedometer", "Off", CV_SAVE, speedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; +consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}}; +consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// this might be a debug or it might be an undocumented regular feature +consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL, CV_OnOff, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; +consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; +consvar_t cv_kartdebugamount = {"kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartdebugshrink = {"kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -403,10 +405,11 @@ consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, point static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {50, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; +consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; // log elemental hazards -- not a netvar, is local to current player consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -429,7 +432,7 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {3, "Vote"}, {0, NULL}}; +static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Same"}, {1, "Next"}, {2, "Random"}, {3, "Vote"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Vote", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "All"}, {0, NULL}}; consvar_t cv_playersforexit = {"playersforexit", "One", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -442,6 +445,7 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL}; INT16 gametype = GT_RACE; // SRB2kart +boolean forceresetplayers = false; UINT8 splitscreen = 0; boolean circuitmap = true; // SRB2kart INT32 adminplayers[MAXPLAYERS]; @@ -579,7 +583,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_friendlyfire); CV_RegisterVar(&cv_pointlimit); CV_RegisterVar(&cv_numlaps); - CV_RegisterVar(&cv_usemapnumlaps); + CV_RegisterVar(&cv_basenumlaps); CV_RegisterVar(&cv_hazardlog); @@ -603,7 +607,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_competitionboxes); CV_RegisterVar(&cv_matchboxes); - CV_RegisterVar(&cv_recycler); + /*CV_RegisterVar(&cv_recycler); CV_RegisterVar(&cv_teleporters); CV_RegisterVar(&cv_superring); CV_RegisterVar(&cv_supersneakers); @@ -614,7 +618,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_forceshield); CV_RegisterVar(&cv_bombshield); CV_RegisterVar(&cv_1up); - CV_RegisterVar(&cv_eggmanbox); + CV_RegisterVar(&cv_eggmanbox);*/ K_RegisterKartStuff(); // SRB2kart @@ -865,7 +869,7 @@ void D_RegisterClientCommands(void) // s_sound.c CV_RegisterVar(&cv_soundvolume); CV_RegisterVar(&cv_digmusicvolume); - CV_RegisterVar(&cv_midimusicvolume); + //CV_RegisterVar(&cv_midimusicvolume); CV_RegisterVar(&cv_numChannels); // i_cdmus.c @@ -1159,7 +1163,7 @@ UINT8 CanChangeSkin(INT32 playernum) return true; // Can change skin during initial countdown. - if (leveltime < 4*TICRATE) + if (leveltime < starttime) return true; if (G_TagGametype()) @@ -1882,6 +1886,8 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese static char buf[2+MAX_WADPATH+1+4]; static char *buf_p = buf; + forceresetplayers = false; + // The supplied data are assumed to be good. I_Assert(delay >= 0 && delay <= 2); @@ -1962,16 +1968,22 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese void D_SetupVote(void) { - char buf[8]; - char *p = buf; + UINT8 buf[6*2]; // five UINT16 maps (at twice the width of a UINT8), and two gametypes + UINT8 *p = buf; INT32 i; + UINT8 secondgt = G_SometimesGetDifferentGametype(); - for (i = 0; i < 4; i++) + WRITEUINT8(p, gametype); + WRITEUINT8(p, secondgt); + + for (i = 0; i < 5; i++) { - if (i == 3) - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, true, false)); + if (i == 2) // sometimes a different gametype + WRITEUINT16(p, G_RandMap(G_TOLFlag(secondgt), prevmap, false, false, 0, true)); + else if (i >= 3) // unknown-random and force-unknown MAP HELL + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, true, false, (i-2), (i < 4))); else - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, false)); + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, false, 0, true)); } SendNetXCmd(XD_SETUPVOTE, buf, p - buf); @@ -1997,7 +2009,9 @@ void D_PickVote(void) char* p = buf; SINT8 temppicks[MAXPLAYERS]; SINT8 templevels[MAXPLAYERS]; + SINT8 votecompare = -1; UINT8 numvotes = 0, key = 0; + boolean force = true; INT32 i; for (i = 0; i < MAXPLAYERS; i++) @@ -2009,6 +2023,10 @@ void D_PickVote(void) temppicks[numvotes] = i; templevels[numvotes] = votes[i]; numvotes++; + if (votecompare == -1) + votecompare = votes[i]; + else if (votes[i] != votecompare) + force = false; } } @@ -2017,7 +2035,10 @@ void D_PickVote(void) if (numvotes > 0) { WRITESINT8(p, temppicks[key]); - WRITESINT8(p, templevels[key]); + if (force && templevels[key] == 3 && numvotes > 1) + WRITESINT8(p, 4); + else + WRITESINT8(p, templevels[key]); } else { @@ -2109,7 +2130,6 @@ static void Command_Map_f(void) // Don't do any variable setting here. Wait until you get your // map packet first to avoid sending the same info twice! newgametype = gametype_cons_t[j].value; - break; } @@ -2127,26 +2147,23 @@ static void Command_Map_f(void) } } + if (!(i = COM_CheckParm("-force")) && newgametype == gametype) // SRB2Kart + newresetplayers = false; // if not forcing and gametypes is the same + // don't use a gametype the map doesn't support - if (cv_debug || COM_CheckParm("-force") || cv_skipmapcheck.value) + if (cv_debug || i || cv_skipmapcheck.value) ; // The player wants us to trek on anyway. Do so. // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer // Alternatively, bail if the map header is completely missing anyway. - else if (!mapheaderinfo[newmapnum-1] - || !(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype))) + else { - char gametypestring[32] = "Single Player"; - - if (multiplayer) - for (i = 0; gametype_cons_t[i].strvalue != NULL; i++) - if (gametype_cons_t[i].value == newgametype) - { - strcpy(gametypestring, gametype_cons_t[i].strvalue); - break; - } - - CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring); - return; + if (!mapheaderinfo[newmapnum-1] + || !(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype))) + { + CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, + (multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player")); + return; + } } // Prevent warping to locked levels @@ -2232,6 +2249,9 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) emeralds = 0; } + if (modeattacking) // i remember moving this here in internal fixed a heisenbug so + SetPlayerSkinByNum(0, cv_chooseskin.value-1); + #ifdef HAVE_BLUA LUAh_MapChange(); #endif @@ -2243,15 +2263,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) if (timingdemo) G_DoneLevelLoad(); - if (modeattacking) - { - SetPlayerSkinByNum(0, cv_chooseskin.value-1); - players[0].skincolor = cv_playercolor.value; // srb2kart - - // a copy of color - if (players[0].mo) - players[0].mo->color = players[0].skincolor; - } if (metalrecording) G_BeginMetal(); if (demorecording) // Okay, level loaded, character spawned and skinned, @@ -2276,7 +2287,7 @@ static void Command_Pause(void) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer))) { - if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) + if (!paused && (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS))) { CONS_Printf(M_GetText("You can't pause here.\n")); return; @@ -2351,7 +2362,7 @@ static void Command_Suicide(void) return; } - /*if (!G_RaceGametype()) // srb2kart: not necessary, suiciding makes you lose a balloon in battle, so it's not desirable to use as a way to escape a hit + /*if (!G_RaceGametype()) // srb2kart: not necessary, suiciding makes you lose a bumper in battle, so it's not desirable to use as a way to escape a hit { CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n")); return; @@ -2518,18 +2529,12 @@ static void Command_Teamchange_f(void) return; } - if (G_GametypeHasTeams()) - { - if (NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam || - (players[consoleplayer].spectator && !NetPacket.packet.newteam)) - error = true; - } - else if (G_GametypeHasSpectators()) - { - if ((players[consoleplayer].spectator && !NetPacket.packet.newteam) || - (!players[consoleplayer].spectator && NetPacket.packet.newteam == 3)) - error = true; - } + if (players[consoleplayer].spectator) + error = !(NetPacket.packet.newteam || (players[consoleplayer].pflags & PF_WANTSTOJOIN)); // :lancer: + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[consoleplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); @@ -2615,18 +2620,12 @@ static void Command_Teamchange2_f(void) return; } - if (G_GametypeHasTeams()) - { - if (NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam || - (players[secondarydisplayplayer].spectator && !NetPacket.packet.newteam)) - error = true; - } - else if (G_GametypeHasSpectators()) - { - if ((players[secondarydisplayplayer].spectator && !NetPacket.packet.newteam) || - (!players[secondarydisplayplayer].spectator && NetPacket.packet.newteam == 3)) - error = true; - } + if (players[secondarydisplayplayer].spectator) + error = !(NetPacket.packet.newteam || (players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN)); + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[secondarydisplayplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); @@ -2712,18 +2711,12 @@ static void Command_Teamchange3_f(void) return; } - if (G_GametypeHasTeams()) - { - if (NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam || - (players[thirddisplayplayer].spectator && !NetPacket.packet.newteam)) - error = true; - } - else if (G_GametypeHasSpectators()) - { - if ((players[thirddisplayplayer].spectator && !NetPacket.packet.newteam) || - (!players[thirddisplayplayer].spectator && NetPacket.packet.newteam == 3)) - error = true; - } + if (players[thirddisplayplayer].spectator) + error = !(NetPacket.packet.newteam || (players[thirddisplayplayer].pflags & PF_WANTSTOJOIN)); + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[thirddisplayplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); @@ -2809,18 +2802,12 @@ static void Command_Teamchange4_f(void) return; } - if (G_GametypeHasTeams()) - { - if (NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam || - (players[fourthdisplayplayer].spectator && !NetPacket.packet.newteam)) - error = true; - } - else if (G_GametypeHasSpectators()) - { - if ((players[fourthdisplayplayer].spectator && !NetPacket.packet.newteam) || - (!players[fourthdisplayplayer].spectator && NetPacket.packet.newteam == 3)) - error = true; - } + if (players[fourthdisplayplayer].spectator) + error = !(NetPacket.packet.newteam || (players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN)); + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[fourthdisplayplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); @@ -3020,24 +3007,23 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) } // Prevent multiple changes in one go. - if (G_TagGametype()) + if (players[playernum].spectator && !(players[playernum].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam) + return; + else if (G_TagGametype()) { if (((players[playernum].pflags & PF_TAGIT) && NetPacket.packet.newteam == 1) || (!(players[playernum].pflags & PF_TAGIT) && NetPacket.packet.newteam == 2) || - (players[playernum].spectator && NetPacket.packet.newteam == 0) || (!players[playernum].spectator && NetPacket.packet.newteam == 3)) return; } else if (G_GametypeHasTeams()) { - if ((NetPacket.packet.newteam && (NetPacket.packet.newteam == (unsigned)players[playernum].ctfteam)) || - (players[playernum].spectator && !NetPacket.packet.newteam)) + if (NetPacket.packet.newteam && (NetPacket.packet.newteam == (unsigned)players[playernum].ctfteam)) return; } else if (G_GametypeHasSpectators()) { - if ((players[playernum].spectator && !NetPacket.packet.newteam) || - (!players[playernum].spectator && NetPacket.packet.newteam == 3)) + if (!players[playernum].spectator && NetPacket.packet.newteam == 3) return; } else @@ -3109,19 +3095,26 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) } //Safety first! - if (players[playernum].mo) + // (not respawning spectators here...) + if (!players[playernum].spectator) { - if (!players[playernum].spectator) - P_DamageMobj(players[playernum].mo, NULL, NULL, 10000); - else + if (players[playernum].mo) { - P_RemoveMobj(players[playernum].mo); - players[playernum].mo = NULL; - players[playernum].playerstate = PST_REBORN; + //if (!players[playernum].spectator) + P_DamageMobj(players[playernum].mo, NULL, NULL, 10000); + /*else + { + if (players[playernum].mo) + { + P_RemoveMobj(players[playernum].mo); + players[playernum].mo = NULL; + } + players[playernum].playerstate = PST_REBORN; + }*/ } + else + players[playernum].playerstate = PST_REBORN; } - else - players[playernum].playerstate = PST_REBORN; //Now that we've done our error checking and killed the player //if necessary, put the player on the correct team/status. @@ -3135,7 +3128,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) } else if (NetPacket.packet.newteam != 3) // .newteam == 1 or 2. { - players[playernum].spectator = false; + players[playernum].pflags |= PF_WANTSTOJOIN; //players[playernum].spectator = false; players[playernum].pflags &= ~PF_TAGGED;//Just in case. if (NetPacket.packet.newteam == 1) //Make the player IT. @@ -3145,7 +3138,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) } else // Just join the game. { - players[playernum].spectator = false; + players[playernum].pflags |= PF_WANTSTOJOIN; //players[playernum].spectator = false; //If joining after hidetime in normal tag, default to being IT. if (gametype == GT_TAG && (leveltime > (hidetime * TICRATE))) @@ -3165,7 +3158,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) else { players[playernum].ctfteam = NetPacket.packet.newteam; - players[playernum].spectator = false; + players[playernum].pflags |= PF_WANTSTOJOIN; //players[playernum].spectator = false; } } else if (G_GametypeHasSpectators()) @@ -3173,7 +3166,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (!NetPacket.packet.newteam) players[playernum].spectator = true; else - players[playernum].spectator = false; + players[playernum].pflags |= PF_WANTSTOJOIN; //players[playernum].spectator = false; } if (NetPacket.packet.autobalance) @@ -3205,7 +3198,9 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[playernum], '\x84', M_GetText("Blue Team"), '\x80'); } else if (NetPacket.packet.newteam == 3) - CONS_Printf(M_GetText("%s entered the game.\n"), player_names[playernum]); + /*CONS_Printf(M_GetText("%s entered the game.\n"), player_names[playernum])*/; + else if (players[playernum].pflags & PF_WANTSTOJOIN) + players[playernum].pflags &= ~PF_WANTSTOJOIN; else CONS_Printf(M_GetText("%s became a spectator.\n"), player_names[playernum]); @@ -3228,10 +3223,18 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) } } + if (gamestate != GS_LEVEL) + return; + // Clear player score and rings if a spectator. if (players[playernum].spectator) { - //players[playernum].score = 0; // SRB2kart + if (G_BattleGametype()) // SRB2kart + { + players[playernum].marescore = 0; + if (K_IsPlayerWanted(&players[playernum])) + K_CalculateBattleWanted(); + } players[playernum].health = 1; if (players[playernum].mo) players[playernum].mo->health = 1; @@ -3241,7 +3244,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (G_TagGametype()) P_CheckSurvivors(); else if (G_BattleGametype()) - K_CheckBalloons(); // SRB2Kart + K_CheckBumpers(); // SRB2Kart else if (G_RaceGametype()) P_CheckRacers(); // also SRB2Kart } @@ -3886,7 +3889,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) if (ncs != FS_FOUND || toomany) { - char message[256]; + char message[275]; if (toomany) sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename); @@ -4033,27 +4036,12 @@ static void Command_ModDetails_f(void) // static void Command_ShowGametype_f(void) { - INT32 j; - const char *gametypestr = NULL; - - if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op" + if (!(netgame || multiplayer)) // print "Single player" instead of "Race" { - CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player")); + CONS_Printf(M_GetText("Current gametype is %s\n"), "Single Player"); return; } - // find name string for current gametype - for (j = 0; gametype_cons_t[j].strvalue; j++) - { - if (gametype_cons_t[j].value == gametype) - { - gametypestr = gametype_cons_t[j].strvalue; - break; - } - } - if (gametypestr) - CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr); - else // string for current gametype was not found above (should never happen) - CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype); + CONS_Printf(M_GetText("Current gametype is %s\n"), gametype_cons_t[gametype].strvalue); } /** Plays the intro. @@ -4186,20 +4174,9 @@ static void TimeLimit_OnChange(void) */ void D_GameTypeChanged(INT32 lastgametype) { - if (netgame) - { - INT32 j; - const char *oldgt = NULL, *newgt = NULL; - for (j = 0; gametype_cons_t[j].strvalue; j++) - { - if (gametype_cons_t[j].value == lastgametype) - oldgt = gametype_cons_t[j].strvalue; - if (gametype_cons_t[j].value == gametype) - newgt = gametype_cons_t[j].strvalue; - } - if (oldgt && newgt) - CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt); - } + if (multiplayer) + CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), gametype_cons_t[lastgametype].strvalue, gametype_cons_t[gametype].strvalue); + // Only do the following as the server, not as remote admin. // There will always be a server, and this only needs to be done once. if (server && (multiplayer || netgame)) @@ -4275,7 +4252,7 @@ void D_GameTypeChanged(INT32 lastgametype) // When swapping to a gametype that supports spectators, // make everyone a spectator initially. - /*if (!splitscreen && (G_GametypeHasSpectators())) + /*if (G_GametypeHasSpectators()) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) @@ -4603,6 +4580,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) { INT32 i; + UINT8 gt, secondgt; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -4618,13 +4596,19 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) return; } - for (i = 0; i < 4; i++) + gt = (UINT8)READUINT8(*cp); + secondgt = (UINT8)READUINT8(*cp); + + for (i = 0; i < 5; i++) { - votelevels[i] = (INT16)READUINT16(*cp); - if (!mapheaderinfo[votelevels[i]]) - P_AllocMapHeader(votelevels[i]); + votelevels[i][0] = (UINT16)READUINT16(*cp); + votelevels[i][1] = gt; + if (!mapheaderinfo[votelevels[i][0]]) + P_AllocMapHeader(votelevels[i][0]); } + votelevels[2][1] = secondgt; + G_SetGamestate(GS_VOTING); Y_StartVote(); } @@ -4749,7 +4733,7 @@ static void Command_RestartAudio_f(void) I_SetSfxVolume(cv_soundvolume.value); I_SetDigMusicVolume(cv_digmusicvolume.value); - I_SetMIDIMusicVolume(cv_midimusicvolume.value); + //I_SetMIDIMusicVolume(cv_midimusicvolume.value); if (Playing()) // Gotta make sure the player is in a level P_RestoreMusic(&players[consoleplayer]); @@ -5214,26 +5198,73 @@ static void Command_ShowTime_f(void) } // SRB2Kart: On change messages +static void BaseNumLaps_OnChange(void) +{ + if (gamestate == GS_LEVEL) + { + if (cv_basenumlaps.value) + CONS_Printf(M_GetText("Number of laps will be changed to %d next round.\n"), cv_basenumlaps.value); + else + CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n")); + } +} + + static void KartFrantic_OnChange(void) { - if (cv_kartfrantic.value != franticitems && gamestate == GS_LEVEL) + if ((boolean)cv_kartfrantic.value != franticitems && gamestate == GS_LEVEL && leveltime > starttime) CONS_Printf(M_GetText("Frantic items will be turned %s next round.\n"), cv_kartfrantic.value ? M_GetText("on") : M_GetText("off")); + else + { + CONS_Printf(M_GetText("Frantic items has been turned %s.\n"), cv_kartfrantic.value ? M_GetText("on") : M_GetText("off")); + franticitems = (boolean)cv_kartfrantic.value; + } } static void KartSpeed_OnChange(void) { - if (cv_kartspeed.value != gamespeed && G_RaceGametype() && gamestate == GS_LEVEL) - CONS_Printf(M_GetText("Game speed will be changed to \"%s\" next round.\n"), cv_kartspeed.string); + if (G_RaceGametype()) + { + if ((UINT8)cv_kartspeed.value != gamespeed && gamestate == GS_LEVEL && leveltime > starttime) + CONS_Printf(M_GetText("Game speed will be changed to \"%s\" next round.\n"), cv_kartspeed.string); + else + { + CONS_Printf(M_GetText("Game speed has been changed to \"%s\".\n"), cv_kartspeed.string); + gamespeed = (UINT8)cv_kartspeed.value; + } + } } static void KartMirror_OnChange(void) { - if (cv_kartmirror.value != mirrormode && G_RaceGametype() && gamestate == GS_LEVEL) - CONS_Printf(M_GetText("Mirror Mode will be turned %s next round.\n"), cv_kartmirror.value ? M_GetText("on") : M_GetText("off")); + if (G_RaceGametype()) + { + if ((boolean)cv_kartmirror.value != mirrormode && gamestate == GS_LEVEL /*&& leveltime > starttime*/) + CONS_Printf(M_GetText("Mirrored tracks will be turned %s next round.\n"), cv_kartmirror.value ? M_GetText("on") : M_GetText("off")); + else + { + CONS_Printf(M_GetText("Mirrored tracks has been turned %s.\n"), cv_kartmirror.value ? M_GetText("on") : M_GetText("off")); + mirrormode = (boolean)cv_kartmirror.value; + } + } } static void KartComeback_OnChange(void) { - if (cv_kartcomeback.value != comeback && G_BattleGametype() && gamestate == GS_LEVEL) - CONS_Printf(M_GetText("Karma Comeback will be turned %s next round.\n"), cv_kartcomeback.value ? M_GetText("on") : M_GetText("off")); -} \ No newline at end of file + if (G_BattleGametype()) + { + if ((boolean)cv_kartcomeback.value != comeback && gamestate == GS_LEVEL && leveltime > starttime) + CONS_Printf(M_GetText("Karma Comeback will be turned %s next round.\n"), cv_kartcomeback.value ? M_GetText("on") : M_GetText("off")); + else + { + CONS_Printf(M_GetText("Karma Comeback has been turned %s.\n"), cv_kartcomeback.value ? M_GetText("on") : M_GetText("off")); + comeback = (boolean)cv_kartcomeback.value; + } + } +} + +static void KartEliminateLast_OnChange(void) +{ + if (G_RaceGametype() && cv_karteliminatelast.value) + P_CheckRacers(); +} diff --git a/src/d_netcmd.h b/src/d_netcmd.h index ad957ed7..371df720 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -77,7 +77,7 @@ extern consvar_t cv_friendlyfire; extern consvar_t cv_pointlimit; extern consvar_t cv_timelimit; extern consvar_t cv_numlaps; -extern consvar_t cv_usemapnumlaps; +extern consvar_t cv_basenumlaps; extern UINT32 timelimitintics; extern consvar_t cv_allowexitlevel; @@ -103,31 +103,37 @@ extern consvar_t cv_pause; extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_respawntime; -extern consvar_t cv_teleporters, cv_superring, cv_supersneakers, cv_invincibility; +/*extern consvar_t cv_teleporters, cv_superring, cv_supersneakers, cv_invincibility; extern consvar_t cv_jumpshield, cv_watershield, cv_ringshield, cv_forceshield, cv_bombshield; extern consvar_t cv_1up, cv_eggmanbox; -extern consvar_t cv_recycler; +extern consvar_t cv_recycler;*/ // SRB2kart items -extern consvar_t cv_magnet, cv_boo, cv_mushroom, cv_triplemushroom, cv_megashroom; -extern consvar_t cv_goldshroom, cv_star, cv_triplebanana, cv_fakeitem, cv_banana; -extern consvar_t cv_greenshell, cv_redshell, cv_laserwisp, cv_triplegreenshell, cv_bobomb; -extern consvar_t cv_blueshell, cv_jaws, cv_fireflower, cv_tripleredshell, cv_lightning; -extern consvar_t cv_feather; +extern consvar_t cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana; +extern consvar_t cv_eggmanmonitor, cv_orbinaut, cv_jawz, cv_mine; +extern consvar_t cv_ballhog, cv_selfpropelledbomb, cv_grow, cv_shrink; +extern consvar_t cv_lightningshield, cv_hyudoro, cv_pogospring; + +extern consvar_t cv_triplesneaker, cv_triplebanana, cv_tripleorbinaut, cv_dualjawz; extern consvar_t cv_karthud; extern consvar_t cv_kartminimap; extern consvar_t cv_kartcheck; -extern consvar_t cv_kartstarsfx; +extern consvar_t cv_kartinvinsfx; extern consvar_t cv_kartspeed; -extern consvar_t cv_kartballoons; +extern consvar_t cv_kartbumpers; extern consvar_t cv_kartfrantic; extern consvar_t cv_kartcomeback; extern consvar_t cv_kartmirror; -extern consvar_t cv_speedometer; +extern consvar_t cv_kartspeedometer; +extern consvar_t cv_kartvoices; + +extern consvar_t cv_karteliminatelast; extern consvar_t cv_votetime; +extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugcheckpoint, cv_kartdebugshrink; + extern consvar_t cv_itemfinder; extern consvar_t cv_inttime, cv_advancemap, cv_playersforexit; diff --git a/src/d_player.h b/src/d_player.h index 2ca419d9..7b5aeafc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -108,8 +108,8 @@ typedef enum // Did you get a time-over? PF_TIMEOVER = 1<<10, - // Ready for Super? - PF_SUPERREADY = 1<<11, + // SRB2Kart: Spectator that wants to join + PF_WANTSTOJOIN = 1<<11, // Character action status PF_JUMPED = 1<<12, @@ -230,93 +230,105 @@ typedef enum NUMPOWERS } powertype_t; +typedef enum +{ + KITEM_SAD = -1, + KITEM_NONE = 0, + KITEM_SNEAKER, + KITEM_ROCKETSNEAKER, + KITEM_INVINCIBILITY, + KITEM_BANANA, + KITEM_EGGMAN, + KITEM_ORBINAUT, + KITEM_JAWZ, + KITEM_MINE, + KITEM_BALLHOG, + KITEM_SPB, + KITEM_GROW, + KITEM_SHRINK, + KITEM_LIGHTNINGSHIELD, + KITEM_HYUDORO, + KITEM_POGOSPRING, + KITEM_KITCHENSINK, + + NUMKARTITEMS, + + // Additional roulette numbers, only used for K_KartGetItemResult + KRITEM_TRIPLESNEAKER = NUMKARTITEMS, + KRITEM_TRIPLEBANANA, + KRITEM_TENFOLDBANANA, + KRITEM_TRIPLEORBINAUT, + KRITEM_DUALJAWZ, + + NUMKARTRESULTS +} kartitems_t; + //{ SRB2kart - kartstuff typedef enum { // Basic gameplay things k_position, // Used for Kart positions, mostly for deterministic stuff k_oldposition, // Used for taunting when you pass someone - k_positiondelay, // Prevents player from taunting continuously if two people were neck-and-neck + k_positiondelay, // Used for position number, so it can grow when passing/being passed k_prevcheck, // Previous checkpoint distance; for p_user.c (was "pw_pcd") k_nextcheck, // Next checkpoint distance; for p_user.c (was "pw_ncd") k_waypoint, // Waypoints. k_starpostwp, // Temporarily stores player waypoint for... some reason. Used when respawning and finishing. - k_lakitu, // Timer for Lakitu to carry and drop the player + k_respawn, // Timer for the DEZ laser respawn effect k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir") - k_lapanimation, // Used to make a swoopy lap lakitu, maybe other effects in the future + //k_lapanimation, // Used to make a swoopy lap lakitu, maybe other effects in the future k_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics k_voices, // Used to stop the player saying more voices than it should k_tauntvoices, // Used to specifically stop taunt voice spam + k_instashield, // Instashield no-damage animation timer - k_boosting, // Determines if you're currently shroom-boosting - k_floorboost, // Prevents Mushroom sounds for a breif duration when triggered by a floor panel - k_spinout, // Separate confirmation to prevent endless wipeout loops + k_floorboost, // Prevents Sneaker sounds for a breif duration when triggered by a floor panel k_spinouttype, // Determines whether to thrust forward or not while spinning out; 0 = move forwards, 1 = stay still k_drift, // Drifting Left or Right, plus a bigger counter = sharper turn k_driftend, // Drift has ended, used to adjust character angle after drift k_driftcharge, // Charge your drift so you can release a burst of speed k_driftboost, // Boost you get from drifting - k_boostcharge, // Charge-up for boosting at the start of the race, or when Lakitu drops you + k_boostcharge, // Charge-up for boosting at the start of the race, or when dropping from respawn k_jmp, // In Mario Kart, letting go of the jump button stops the drift k_offroad, // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed + k_pogospring, // Pogo spring bounce effect k_brakestop, // Wait until you've made a complete stop for a few tics before letting brake go in reverse. + k_waterskip, // Water skipping counter k_itemroulette, // Used for the roulette when deciding what item to give you (was "pw_kartitem") k_roulettetype, // Used for the roulette, for deciding type (currently only used for Battle, to give you better items from Karma items) - k_itemclose, // Used to animate the item window closing (was "pw_psychic") + + // Item held stuff + k_itemtype, // KITEM_ constant for item number + k_itemamount, // Amount of said item + k_itemheld, // Are you holding an item? // Some items use timers for their duration or effects - k_magnettimer, // Duration of Magnet's item-break and item box pull - k_bootimer, // Duration of the boo offroad effect itself - k_bootaketimer, // You are stealing an item, this is your timer - k_boostolentimer, // You are being stolen from, this is your timer - k_mushroomtimer, // Duration of the Mushroom Boost itself - k_growshrinktimer, // > 0 = Big, < 0 = small - k_squishedtimer, // Squished frame timer - k_goldshroomtimer, // Gold Mushroom duration timer - k_startimer, // Invincibility timer - k_spinouttimer, // Spin-out from a banana peel or oil slick (was "pw_bananacam") - k_laserwisptimer, // The duration and relative angle of the laser - k_justbumped, // Prevent players from endlessly bumping into each other - k_deathsentence, // 30 seconds to live... (Blue Shell murder timer (not actually 30 sec, I just couldn't help the FF reference :p)) - k_poweritemtimer, // Battle mode, how long before you're allowed another power item (Star, Megashroom) - k_comebacktimer, // Battle mode, how long before you become a bomb after death - - // Each item needs its own power slot, for the HUD and held use - // *** ADDING A NEW ITEM? ADD IT TO K_DoBooSteal PLEASE!! -Salt *** - k_magnet, // 0x1 = Magnet in inventory - k_boo, // 0x1 = Boo in inventory - k_mushroom, // 0x1 = 1 Mushroom in inventory, 0x2 = 2 Mushrooms in inventory - // 0x4 = 3 Mushrooms in inventory - k_megashroom, // 0x1 = Mega Mushroom in inventory - k_goldshroom, // 0x1 = Gold Mushroom in inventory - k_star, // 0x1 = Star in inventory - k_triplebanana, // 0x1 = 1 Banana following, 0x2 = 2 Bananas following - // 0x4 = 3 Bananas following, 0x8 = Triple Banana in inventory - k_fakeitem, // 0x1 = Fake Item being held, 0x2 = Fake Item in inventory - k_banana, // 0x1 = Banana being held, 0x2 = Banana in inventory - k_greenshell, // 0x1 = Green Shell being held, 0x2 = Green Shell in inventory - k_redshell, // 0x1 = Red Shell being held, 0x2 = Red Shell in inventory - k_laserwisp, // 0x1 = Laser Wisp in inventory - k_triplegreenshell, // 0x1 = 1 Green Shell orbiting, 0x2 = 2 Green Shells orbiting - // 0x4 = 3 Green Shells orbiting, 0x8 = Triple Green Shell in inventory - k_bobomb, // 0x1 = Bob-omb being held, 0x2 = Bob-omb in inventory - k_blueshell, // 0x1 = Blue Shell in inventory - k_jaws, // 0x1 = 1 Jaws orbiting, 0x2 = 2 Jaws orbiting, - // 0x4 = 2x Jaws in inventory - k_fireflower, // 0x1 = Fire Flower in inventory - k_tripleredshell, // 0x1 = 1 Red Shell orbiting, 0x2 = 2 Red Shells orbiting - // 0x4 = 3 Red Shells orbiting, 0x8 = Triple Red Shell in inventory - k_lightning, // 0x1 = Lightning in inventory - k_feather, // 0x1 = Feather in inventory, 0x2 = Player is feather jumping - k_kitchensink, // 0x1 = Sink in inventory + k_attractiontimer, // Duration of Lightning Shield's item-break and item box pull + k_hyudorotimer, // Duration of the Hyudoro offroad effect itself + k_stealingtimer, // You are stealing an item, this is your timer + k_stolentimer, // You are being stolen from, this is your timer + k_sneakertimer, // Duration of the Sneaker Boost itself + k_growshrinktimer, // > 0 = Big, < 0 = small + k_squishedtimer, // Squished frame timer + k_rocketsneakertimer, // Rocket Sneaker duration timer + k_invincibilitytimer, // Invincibility timer + k_deathsentence, // 30 seconds to live... (SPB murder timer (not actually 30 sec, I just couldn't help the FF reference :p)) + k_eggmanheld, // Eggman monitor held, separate from k_itemheld so it doesn't stop you from getting items + k_bananadrag, // After a second of holding a banana behind you, you start to slow down + k_spinouttimer, // Spin-out from a banana peel or oil slick (was "pw_bananacam") + k_wipeoutslow, // Timer before you slowdown when getting wiped out + k_justbumped, // Prevent players from endlessly bumping into each other + k_comebacktimer, // Battle mode, how long before you become a bomb after death + k_sadtimer, // How long you've been sad // Battle Mode vars - k_balloon, // Number of balloons left - k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a balloon + k_bumper, // Number of bumpers left + k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a bumper k_comebackmode, // 0 = bomb, 1 = item + k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo NUMKARTSTUFF } kartstufftype_t; @@ -511,7 +523,7 @@ typedef struct player_s tic_t startedtime; // Time which you started this mare with. tic_t finishedtime; // Time it took you to finish the mare (used for display) INT16 finishedrings; // The rings you had left upon finishing the mare - UINT32 marescore; // score for this nights stage + UINT32 marescore; // SRB2Kart: Battle score UINT32 lastmarescore; // score for the last mare UINT8 lastmare; // previous mare INT32 maxlink; // maximum link obtained diff --git a/src/dehacked.c b/src/dehacked.c index 878dbb49..03884474 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1824,8 +1824,10 @@ static actionpointer_t actionpointers[] = {{A_RemoteAction}, "A_REMOTEACTION"}, {{A_ToggleFlameJet}, "A_TOGGLEFLAMEJET"}, {{A_ItemPop}, "A_ITEMPOP"}, // SRB2kart - {{A_RedShellChase}, "A_REDSHELLCHASE"}, // SRB2kart - {{A_BobombExplode}, "A_BOBOMBEXPLODE"}, // SRB2kart + {{A_JawzChase}, "A_JAWZCHASE"}, // SRB2kart + {{A_JawzExplode}, "A_JAWZEXPLODE"}, // SRB2kart + {{A_MineExplode}, "A_MINEEXPLODE"}, // SRB2kart + {{A_BallhogExplode}, "A_BALLHOGEXPLODE"}, // SRB2kart {{A_OrbitNights}, "A_ORBITNIGHTS"}, {{A_GhostMe}, "A_GHOSTME"}, {{A_SetObjectState}, "A_SETOBJECTSTATE"}, @@ -3081,10 +3083,11 @@ static void readmaincfg(MYFILE *f) // Also save a time attack folder filenamelen = strlen(gamedatafilename)-4; // Strip off the extension - strncpy(timeattackfolder, gamedatafilename, min(filenamelen, sizeof (timeattackfolder))); + filenamelen = min(filenamelen, sizeof (timeattackfolder)); + strncpy(timeattackfolder, gamedatafilename, filenamelen); timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0'; - strncpy(savegamename, timeattackfolder, sizeof (timeattackfolder)); + strncpy(savegamename, timeattackfolder, filenamelen); strlcat(savegamename, "%u.ssg", sizeof(savegamename)); // can't use sprintf since there is %u in savegamename strcatbf(savegamename, srb2home, PATHSEP); @@ -3181,6 +3184,14 @@ static void readwipes(MYFILE *f) else if (fastcmp(pword, "FINAL")) wipeoffset = wipe_specinter_final; } + else if (fastncmp(word, "VOTING_", 10)) + { + pword = word + 10; + if (fastcmp(pword, "TOBLACK")) + wipeoffset = wipe_specinter_toblack; + else if (fastcmp(pword, "FINAL")) + wipeoffset = wipe_specinter_final; + } else if (fastncmp(word, "MULTINTER_", 10)) { pword = word + 10; @@ -5806,15 +5817,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FIREBALL2", "S_FIREBALL3", "S_FIREBALL4", - "S_FIREBALL5", - "S_FIREBALL6", - "S_FIREBALL7", "S_FIREBALLEXP1", "S_FIREBALLEXP2", "S_FIREBALLEXP3", - "S_FIREBALLEXP4", - "S_FIREBALLEXP5", - "S_FIREBALLEXP6", "S_SHELL", "S_SHELL1", "S_SHELL2", @@ -6242,9 +6247,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_DRIFTDUST3", "S_DRIFTDUST4", - // Magnet Burst + // Lightning Shield Burst - // Mushroom Fire Trail + // Sneaker Fire Trail "S_KARTFIRE1", "S_KARTFIRE2", "S_KARTFIRE3", @@ -6254,7 +6259,33 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_KARTFIRE7", "S_KARTFIRE8", - //{ Fake Item + // Invincibility Sparks + "S_KARTINVULN_SMALL1", + "S_KARTINVULN_SMALL2", + "S_KARTINVULN_SMALL3", + "S_KARTINVULN_SMALL4", + "S_KARTINVULN_SMALL5", + + "S_KARTINVULN_LARGE1", + "S_KARTINVULN_LARGE2", + "S_KARTINVULN_LARGE3", + "S_KARTINVULN_LARGE4", + "S_KARTINVULN_LARGE5", + + // Invincibility flash overlay + "S_INVULNFLASH1", + "S_INVULNFLASH2", + "S_INVULNFLASH3", + "S_INVULNFLASH4", + + // Wipeout dust trail + "S_WIPEOUTTRAIL1", + "S_WIPEOUTTRAIL2", + "S_WIPEOUTTRAIL3", + "S_WIPEOUTTRAIL4", + "S_WIPEOUTTRAIL5", + + //{ Eggman Monitor "S_FAKEITEM1", "S_FAKEITEM2", "S_FAKEITEM3", @@ -6283,81 +6314,74 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit //} // Banana - "S_BANANAITEM", - "S_DEADBANANA", + "S_BANANA", + "S_BANANA_DEAD", - //{ Green Shell - "S_TRIPLEGREENSHIELD1", - "S_TRIPLEGREENSHIELD2", - "S_TRIPLEGREENSHIELD3", - "S_TRIPLEGREENSHIELD4", - "S_TRIPLEGREENSHIELD5", - "S_TRIPLEGREENSHIELD6", - "S_TRIPLEGREENSHIELD7", - "S_TRIPLEGREENSHIELD8", - "S_GREENSHIELD1", - "S_GREENSHIELD2", - "S_GREENSHIELD3", - "S_GREENSHIELD4", - "S_GREENSHIELD5", - "S_GREENSHIELD6", - "S_GREENSHIELD7", - "S_GREENSHIELD8", - "S_GREENITEM1", - "S_GREENITEM2", - "S_GREENITEM3", - "S_GREENITEM4", - "S_GREENITEM5", - "S_GREENITEM6", - "S_GREENITEM7", - "S_GREENITEM8", - "S_DEADGREEN", + //{ Orbinaut + "S_ORBINAUT1", + "S_ORBINAUT2", + "S_ORBINAUT3", + "S_ORBINAUT4", + "S_ORBINAUT5", + "S_ORBINAUT6", + "S_ORBINAUT_SHIELD", + "S_ORBINAUT_DEAD", + "S_ORBINAUT_SHIELDDEAD", //} - //{ Red Shell - "S_TRIPLEREDSHIELD1", - "S_TRIPLEREDSHIELD2", - "S_TRIPLEREDSHIELD3", - "S_TRIPLEREDSHIELD4", - "S_TRIPLEREDSHIELD5", - "S_TRIPLEREDSHIELD6", - "S_TRIPLEREDSHIELD7", - "S_TRIPLEREDSHIELD8", - "S_REDSHIELD1", - "S_REDSHIELD2", - "S_REDSHIELD3", - "S_REDSHIELD4", - "S_REDSHIELD5", - "S_REDSHIELD6", - "S_REDSHIELD7", - "S_REDSHIELD8", - "S_REDITEM1", - "S_REDITEM2", - "S_REDITEM3", - "S_REDITEM4", - "S_REDITEM5", - "S_REDITEM6", - "S_REDITEM7", - "S_REDITEM8", - "S_DEADRED", + //{ Jawz + "S_JAWZ1", + "S_JAWZ2", + "S_JAWZ3", + "S_JAWZ4", + "S_JAWZ5", + "S_JAWZ6", + "S_JAWZ7", + "S_JAWZ8", + "S_JAWZ_DUD1", + "S_JAWZ_DUD2", + "S_JAWZ_DUD3", + "S_JAWZ_DUD4", + "S_JAWZ_DUD5", + "S_JAWZ_DUD6", + "S_JAWZ_DUD7", + "S_JAWZ_DUD8", + "S_JAWZ_SHIELD1", + "S_JAWZ_SHIELD2", + "S_JAWZ_SHIELD3", + "S_JAWZ_SHIELD4", + "S_JAWZ_SHIELD5", + "S_JAWZ_SHIELD6", + "S_JAWZ_SHIELD7", + "S_JAWZ_SHIELD8", + "S_JAWZ_DEAD1", + "S_JAWZ_DEAD2", //} - "S_FIRETRAIL1", - "S_FIRETRAIL2", - "S_FIRETRAIL3", - "S_FIRETRAIL4", - "S_FIRETRAIL5", - "S_FIRETRAIL6", - "S_FIRETRAIL7", - "S_FIRETRAIL8", - "S_FIRETRAIL9", - - // Bob-omb - "S_BOMBSHIELD", - "S_BOMBITEM", - "S_BOMBAIR", - "S_BOMBEXPLODE", - "S_BOMBEXPLOSION1", - "S_BOMBEXPLOSION2", + // Special Stage Mine + "S_SSMINE1", + "S_SSMINE2", + "S_SSMINE3", + "S_SSMINE4", + "S_SSMINE_SHIELD1", + "S_SSMINE_SHIELD2", + "S_SSMINE_AIR1", + "S_SSMINE_AIR2", + "S_SSMINE_DEPLOY1", + "S_SSMINE_DEPLOY2", + "S_SSMINE_DEPLOY3", + "S_SSMINE_DEPLOY4", + "S_SSMINE_DEPLOY5", + "S_SSMINE_DEPLOY6", + "S_SSMINE_DEPLOY7", + "S_SSMINE_DEPLOY8", + "S_SSMINE_DEPLOY9", + "S_SSMINE_DEPLOY10", + "S_SSMINE_DEPLOY11", + "S_SSMINE_DEPLOY12", + "S_SSMINE_DEPLOY13", + "S_SSMINE_EXPLODE", + "S_MINEEXPLOSION1", + "S_MINEEXPLOSION2", // New explosion "S_QUICKBOOM1", @@ -6382,14 +6406,41 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SLOWBOOM9", "S_SLOWBOOM10", - // Blue Shell - Blue Lightning for now... + // Ballhog + "S_BALLHOG1", + "S_BALLHOG2", + "S_BALLHOG3", + "S_BALLHOG4", + "S_BALLHOG5", + "S_BALLHOG6", + "S_BALLHOG7", + "S_BALLHOG8", + "S_BALLHOG_DEAD", + "S_BALLHOGBOOM1", + "S_BALLHOGBOOM2", + "S_BALLHOGBOOM3", + "S_BALLHOGBOOM4", + "S_BALLHOGBOOM5", + "S_BALLHOGBOOM6", + "S_BALLHOGBOOM7", + "S_BALLHOGBOOM8", + "S_BALLHOGBOOM9", + "S_BALLHOGBOOM10", + "S_BALLHOGBOOM11", + "S_BALLHOGBOOM12", + "S_BALLHOGBOOM13", + "S_BALLHOGBOOM14", + "S_BALLHOGBOOM15", + "S_BALLHOGBOOM16", + + // Self-Propelled Bomb - just an explosion for now... "S_BLUELIGHTNING1", "S_BLUELIGHTNING2", "S_BLUELIGHTNING3", "S_BLUELIGHTNING4", "S_BLUEEXPLODE", - // Lightning + // Grow/shrink beams "S_LIGHTNING1", "S_LIGHTNING2", "S_LIGHTNING3", @@ -6401,14 +6452,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SINKTRAIL2", "S_SINKTRAIL3", - // Battle Mode balloon - "S_BATTLEBALLOON1", - "S_BATTLEBALLOON2", - "S_BATTLEBALLOON3", + // Battle Mode bumper + "S_BATTLEBUMPER1", + "S_BATTLEBUMPER2", + "S_BATTLEBUMPER3", - // Lakitu - "S_LAKITU1", - "S_LAKITU2", + // DEZ respawn laser + "S_DEZLASER", // Pokey "S_POKEY1", @@ -6488,15 +6538,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_DOOD_BOX4", "S_DOOD_BOX5", - // D00Dkart - Diddy Kong Racing Balloon + // D00Dkart - Diddy Kong Racing Bumper "S_DOOD_BALLOON", - // D00Dkart - Big Ring - "S_DOOD_RING1", - "S_DOOD_RING2", - "S_DOOD_RING3", - "S_DOOD_RING4", - "S_DOOD_RING5", + // Chaotix Big Ring + "S_BIGRING01", + "S_BIGRING02", + "S_BIGRING03", + "S_BIGRING04", + "S_BIGRING05", + "S_BIGRING06", + "S_BIGRING07", + "S_BIGRING08", + "S_BIGRING09", + "S_BIGRING10", + "S_BIGRING11", + "S_BIGRING12", // SNES Objects "S_SNES_DONUTBUSH1", @@ -6568,28 +6625,38 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FIREDITEM3", "S_FIREDITEM4", + "S_INSTASHIELDA1", // No damage instashield effect + "S_INSTASHIELDA2", + "S_INSTASHIELDA3", + "S_INSTASHIELDA4", + "S_INSTASHIELDA5", + "S_INSTASHIELDA6", + "S_INSTASHIELDA7", + "S_INSTASHIELDB1", + "S_INSTASHIELDB2", + "S_INSTASHIELDB3", + "S_INSTASHIELDB4", + "S_INSTASHIELDB5", + "S_INSTASHIELDB6", + "S_INSTASHIELDB7", + "S_PLAYERARROW", // Above player arrow - "S_PLAYERARROW_MUSHROOM", - "S_PLAYERARROW_GREENSHELL", - "S_PLAYERARROW_BANANA", - "S_PLAYERARROW_FAKEITEM", - "S_PLAYERARROW_BOO", - "S_PLAYERARROW_FEATHER", - "S_PLAYERARROW_REDSHELL", - "S_PLAYERARROW_BOBOMB", - "S_PLAYERARROW_FIREFLOWER", - "S_PLAYERARROW_TRIPLEGREENSHELL", - "S_PLAYERARROW_TRIPLEBANANA", - "S_PLAYERARROW_TRIPLEREDSHELL", - "S_PLAYERARROW_STAR", - "S_PLAYERARROW_MEGASHROOM", - "S_PLAYERARROW_KITCHENSINK", - "S_PLAYERARROW_EMPTY", - "S_PLAYERARROW_ROULETTE", + "S_PLAYERARROW_BOX", + "S_PLAYERARROW_ITEM", + "S_PLAYERARROW_NUMBER", + "S_PLAYERARROW_X", + "S_PLAYERARROW_WANTED1", + "S_PLAYERARROW_WANTED2", + "S_PLAYERARROW_WANTED3", + "S_PLAYERARROW_WANTED4", + "S_PLAYERARROW_WANTED5", + "S_PLAYERARROW_WANTED6", + "S_PLAYERARROW_WANTED7", "S_PLAYERBOMB", // Player bomb overlay "S_PLAYERITEM", // Player item overlay - "S_PLAYERBOMB_WHEEL", + + "S_KARMAWHEEL", // Karma player wheels #ifdef SEENAMES "S_NAMECHECK", @@ -7108,52 +7175,48 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_RANDOMITEM", "MT_RANDOMITEMPOP", - "MT_MUSHROOMTRAIL", + "MT_SNEAKERTRAIL", + "MT_SPARKLETRAIL", + "MT_INVULNFLASH", + "MT_WIPEOUTTRAIL", "MT_DRIFT", "MT_DRIFTDUST", "MT_FAKESHIELD", "MT_FAKEITEM", - "MT_TRIPLEBANANASHIELD1", // Banana Stuff - "MT_TRIPLEBANANASHIELD2", - "MT_TRIPLEBANANASHIELD3", - "MT_BANANASHIELD", - "MT_BANANAITEM", + "MT_BANANA", + "MT_BANANA_SHIELD", // Banana Stuff - "MT_TRIPLEGREENSHIELD1", // Green shell stuff - "MT_TRIPLEGREENSHIELD2", - "MT_TRIPLEGREENSHIELD3", - "MT_GREENSHIELD", - "MT_GREENITEM", - "MT_FIRETRAIL", + "MT_ORBINAUT", // Orbinaut stuff + "MT_ORBINAUT_SHIELD", - "MT_TRIPLEREDSHIELD1", // Red shell stuff - "MT_TRIPLEREDSHIELD2", - "MT_TRIPLEREDSHIELD3", - "MT_REDSHIELD", - "MT_REDITEM", - "MT_REDITEMDUD", + "MT_JAWZ", // Jawz stuff + "MT_JAWZ_DUD", + "MT_JAWZ_SHIELD", - "MT_BOMBSHIELD", // Bob-omb stuff - "MT_BOMBITEM", - "MT_BOMBEXPLOSION", - "MT_BOMBEXPLOSIONSOUND", + "MT_SSMINE_SHIELD", // Special Stage Mine stuff + "MT_SSMINE", + "MT_MINEEXPLOSION", + "MT_MINEEXPLOSIONSOUND", "MT_SMOLDERING", // New explosion "MT_BOOMEXPLODE", "MT_BOOMPARTICLE", - "MT_BLUELIGHTNING", // Lightning stuff + "MT_BALLHOG", // Ballhog + "MT_BALLHOGBOOM", + + "MT_BLUELIGHTNING", // Grow/shrink stuff "MT_BLUEEXPLOSION", "MT_LIGHTNING", "MT_SINK", // Kitchen Sink Stuff "MT_SINKTRAIL", - "MT_BATTLEBALLOON", // Battle Mode balloon + "MT_BATTLEBUMPER", // Battle Mode bumper - "MT_LAKITU", + "MT_DEZLASER", "MT_POKEY", // Huh, thought this was a default asset for some reason, guess not. @@ -7189,7 +7252,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_DOOD_FLOWER4", "MT_DOOD_BOX", "MT_DOOD_BALLOON", - "MT_DOOD_RING", + "MT_BIGRING", "MT_SNES_DONUTBUSH1", "MT_SNES_DONUTBUSH2", @@ -7224,7 +7287,14 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FIREDITEM", + "MT_INSTASHIELDA", + "MT_INSTASHIELDB", + "MT_PLAYERARROW", + "MT_PLAYERWANTED", + + "MT_KARMAHITBOX", + "MT_KARMAWHEEL", #ifdef SEENAMES "MT_NAMECHECK", @@ -7349,8 +7419,8 @@ static const char *const PLAYERFLAG_LIST[] = { // Did you get a time-over? "TIMEOVER", - // Ready for Super? - "SUPERREADY", + // SRB2Kart: spectator that wants to join + "WANTSTOJOIN", // Character action status "JUMPED", @@ -7428,64 +7498,64 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart. "SILVER", // 03 // SKINCOLOR_SILVER "CLOUDY", // 04 // SKINCOLOR_CLOUDY "GREY", // 05 // SKINCOLOR_GREY - "DARKGREY", // 06 // SKINCOLOR_DARKGREY + "NICKEL", // 06 // SKINCOLOR_NICKEL "BLACK", // 07 // SKINCOLOR_BLACK "SALMON", // 08 // SKINCOLOR_SALMON "PINK", // 09 // SKINCOLOR_PINK - "LIGHTRED", // 10 // SKINCOLOR_LIGHTRED - "SHINYRED", // 11 // SKINCOLOR_SHINYRED + "ROSE", // 10 // SKINCOLOR_ROSE + "RASPBERRY", // 11 // SKINCOLOR_RASPBERRY "RED", // 12 // SKINCOLOR_RED - "DARKPINK", // 13 // SKINCOLOR_DARKPINK - "DARKRED", // 14 // SKINCOLOR_DARKRED + "RUBY", // 13 // SKINCOLOR_RUBY + "CRIMSON", // 14 // SKINCOLOR_CRIMSON "DAWN", // 15 // SKINCOLOR_DAWN - "ORANGE", // 16 // SKINCOLOR_ORANGE - "SHINYORANGE", // 17 // SKINCOLOR_SHINYORANGE - "DARKORANGE", // 18 // SKINCOLOR_DARKORANGE - "GOLDENBROWN", // 19 // SKINCOLOR_GOLDENBROWN - "ROSEWOOD", // 20 // SKINCOLOR_ROSEWOOD - "DARKROSEWOOD", // 21 // SKINCOLOR_DARKROSEWOOD + "CREAMSICLE", // 16 // SKINCOLOR_CREAMSICLE + "ORANGE", // 17 // SKINCOLOR_ORANGE + "PUMPKIN", // 18 // SKINCOLOR_PUMPKIN + "ROSEWOOD", // 19 // SKINCOLOR_ROSEWOOD + "BURGUNDY", // 20 // SKINCOLOR_BURGUNDY + "BRONZE", // 21 // SKINCOLOR_BRONZE "SEPIA", // 22 // SKINCOLOR_SEPIA "BEIGE", // 23 // SKINCOLOR_BEIGE "BROWN", // 24 // SKINCOLOR_BROWN "LEATHER", // 25 // SKINCOLOR_LEATHER - "YELLOW", // 26 // SKINCOLOR_YELLOW - "PEACH", // 27 // SKINCOLOR_PEACH - "LIGHTORANGE", // 28 // SKINCOLOR_LIGHTORANGE - "CARAMEL", // 29 // SKINCOLOR_CARAMEL - "GOLD", // 30 // SKINCOLOR_GOLD - "SHINYCARAMEL", // 31 // SKINCOLOR_SHINYCARAMEL - "VOMIT", // 32 // SKINCOLOR_VOMIT - "GARDEN", // 33 // SKINCOLOR_GARDEN - "LIGHTARMY", // 34 // SKINCOLOR_LIGHTARMY - "ARMY", // 35 // SKINCOLOR_ARMY - "PISTACHIO", // 36 // SKINCOLOR_PISTACHIO - "ROBOHOOD", // 37 // SKINCOLOR_ROBOHOOD - "OLIVE", // 38 // SKINCOLOR_OLIVE - "DARKARMY", // 39 // SKINCOLOR_DARKARMY - "LIGHTGREEN", // 40 // SKINCOLOR_LIGHTGREEN - "UGLYGREEN", // 41 // SKINCOLOR_UGLYGREEN - "NEONGREEN", // 42 // SKINCOLOR_NEONGREEN - "GREEN", // 43 // SKINCOLOR_GREEN - "DARKGREEN", // 44 // SKINCOLOR_DARKGREEN + "PEACH", // 26 // SKINCOLOR_PEACH + "CARAMEL", // 27 // SKINCOLOR_CARAMEL + "TANGERINE", // 28 // SKINCOLOR_TANGERINE + "GOLD", // 29 // SKINCOLOR_GOLD + "VOMIT", // 30 // SKINCOLOR_VOMIT + "YELLOW", // 31 // SKINCOLOR_YELLOW + "CANARY", // 32 // SKINCOLOR_CANARY + "OLIVE", // 33 // SKINCOLOR_OLIVE + "GARDEN", // 34 // SKINCOLOR_GARDEN + "LIME", // 35 // SKINCOLOR_LIME + "TEA", // 36 // SKINCOLOR_TEA + "ARMY", // 37 // SKINCOLOR_ARMY + "PISTACHIO", // 38 // SKINCOLOR_PISTACHIO + "MOSS", // 39 // SKINCOLOR_MOSS + "MINT", // 40 // SKINCOLOR_MINT + "GREEN", // 41 // SKINCOLOR_GREEN + "ROBOHOOD", // 42 // SKINCOLOR_ROBOHOOD + "PINETREE", // 43 // SKINCOLOR_PINETREE + "EMERALD", // 44 // SKINCOLOR_EMERALD "SWAMP", // 45 // SKINCOLOR_SWAMP - "FROST", // 46 // SKINCOLOR_FROST - "SLATE", // 47 // SKINCOLOR_SLATE - "LIGHTBLUE", // 48 // SKINCOLOR_LIGHTBLUE - "CYAN", // 49 // SKINCOLOR_CYAN - "CERULEAN", // 50 // SKINCOLOR_CERULEAN - "TURQUOISE", // 51 // SKINCOLOR_TURQUOISE - "TEAL", // 52 // SKINCOLOR_TEAL - "STEELBLUE", // 53 // SKINCOLOR_STEELBLUE - "BLUE", // 54 // SKINCOLOR_BLUE - "SHINYBLUE", // 55 // SKINCOLOR_SHINYBLUE + "AQUA", // 46 // SKINCOLOR_AQUA + "TEAL", // 47 // SKINCOLOR_TEAL + "CYAN", // 48 // SKINCOLOR_CYAN + "CERULEAN", // 49 // SKINCOLOR_CERULEAN + "SLATE", // 50 // SKINCOLOR_SLATE + "STEEL", // 51 // SKINCOLOR_STEEL + "PERIWINKLE", // 52 // SKINCOLOR_PERIWINKLE + "BLUE", // 53 // SKINCOLOR_BLUE + "SAPPHIRE", // 54 // SKINCOLOR_SAPPHIRE + "BLUEBERRY", // 55 // SKINCOLOR_BLUEBERRY "NAVY", // 56 // SKINCOLOR_NAVY - "DARKBLUE", // 57 // SKINCOLOR_DARKBLUE - "JETBLACK", // 58 // SKINCOLOR_JETBLACK - "LILAC", // 59 // SKINCOLOR_LILAC - "PURPLE", // 60 // SKINCOLOR_PURPLE - "LAVENDER", // 61 // SKINCOLOR_LAVENDER + "JET", // 57 // SKINCOLOR_JET + "DUSK", // 58 // SKINCOLOR_DUSK + "PURPLE", // 59 // SKINCOLOR_PURPLE + "LAVENDER", // 60 // SKINCOLOR_LAVENDER + "INDIGO", // 61 // SKINCOLOR_INDIGO "BYZANTIUM", // 62 // SKINCOLOR_BYZANTIUM - "INDIGO", // 63 // SKINCOLOR_INDIGO + "LILAC", // 63 // SKINCOLOR_LILAC // Super special awesome Super flashing colors! "SUPER1", // SKINCOLOR_SUPER1 @@ -7550,17 +7620,16 @@ static const char *const KARTSTUFF_LIST[] = { "NEXTCHECK", "WAYPOINT", "STARPOSTWP", - "LAKITU", + "RESPAWN", "THROWDIR", - "LAPANIMATION", + //"LAPANIMATION", "CARDANIMATION", "VOICES", "TAUNTVOICES", + "INSTASHIELD", - "BOOSTING", "FLOORBOOST", - "SPINOUT", "SPINOUTTYPE", "DRIFT", @@ -7570,53 +7639,42 @@ static const char *const KARTSTUFF_LIST[] = { "BOOSTCHARGE", "JMP", "OFFROAD", + "POGOSPRING", "BRAKESTOP", + "WATERSKIP", "ITEMROULETTE", "ROULETTETYPE", - "ITEMCLOSE", - "MAGNETTIMER", - "BOOTIMER", - "BOOTAKETIMER", - "BOOSTOLENTIMER", - "MUSHROOMTIMER", + // Item held stuff + "ITEMTYPE", + "ITEMAMOUNT", + "ITEMHELD", + + // Some items use timers for their duration or effects + "ATTRACTIONTIMER", + "HYUDOROTIMER", + "STEALINGTIMER", + "STOLENTIMER", + "SNEAKERTIMER", "GROWSHRINKTIMER", "SQUISHEDTIMER", - "GOLDSHROOMTIMER", - "STARTIMER", - "SPINOUTTIMER", - "LASERWISPTIMER", - "JUSTBUMPED", + "ROCKETSNEAKERTIMER", + "INVINCIBILITYTIMER", "DEATHSENTENCE", - "POWERITEMTIMER", + "EGGMANHELD", + "BANANADRAG", + "SPINOUTTIMER", + "WIPEOUTSLOW", + "JUSTBUMPED", "COMEBACKTIMER", + "SADTIMER", - "MAGNET", - "BOO", - "MUSHROOM", - "MEGASHROOM", - "GOLDSHROOM", - "STAR", - "TRIPLEBANANA", - "FAKEITEM", - "BANANA", - "GREENSHELL", - "REDSHELL", - "LASERWISP", - "TRIPLEGREENSHELL", - "BOBOMB", - "BLUESHELL", - "JAWS", - "FIREFLOWER", - "TRIPLEREDSHELL", - "LIGHTNING", - "FEATHER", - "KITCHENSINK", - - "BALLOON", + // Battle Mode vars + "BUMPER", "COMEBACKPOINTS", - "COMEBACKMODE" + "COMEBACKMODE", + "WANTED", }; static const char *const HUDITEMS_LIST[] = { @@ -8494,7 +8552,7 @@ fixed_t get_number(const char *word) #endif } -void FUNCMATH DEH_Check(void) +void DEH_Check(void) { #if defined(_DEBUG) || defined(PARANOIA) const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); diff --git a/src/doomdata.h b/src/doomdata.h index e916a151..1b91c94d 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -207,8 +207,8 @@ typedef struct #define ZSHIFT 4 -extern const char *Color_Names[MAXSKINCOLORS]; -extern const UINT8 Color_Opposite[MAXSKINCOLORS*2]; +//extern const char *Color_Names[MAXSKINCOLORS]; +//extern const UINT8 Color_Opposite[MAXSKINCOLORS*2]; #define NUMMAPS 1035 diff --git a/src/doomdef.h b/src/doomdef.h index 278dc002..2e4f45b2 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -161,6 +161,9 @@ extern FILE *logstream; // Comment or uncomment this as necessary. //#define USE_PATCH_DTA +// Kart has it's own, as well. +#define USE_PATCH_KART + // Modification options // If you want to take advantage of the Master Server's ability to force clients to update // to the latest version, fill these out. Otherwise, just comment out UPDATE_ALERT and leave @@ -234,64 +237,64 @@ typedef enum SKINCOLOR_SILVER, SKINCOLOR_CLOUDY, SKINCOLOR_GREY, - SKINCOLOR_DARKGREY, + SKINCOLOR_NICKEL, SKINCOLOR_BLACK, SKINCOLOR_SALMON, SKINCOLOR_PINK, - SKINCOLOR_LIGHTRED, - SKINCOLOR_SHINYRED, + SKINCOLOR_ROSE, + SKINCOLOR_RASPBERRY, SKINCOLOR_RED, - SKINCOLOR_DARKPINK, - SKINCOLOR_DARKRED, + SKINCOLOR_RUBY, + SKINCOLOR_CRIMSON, SKINCOLOR_DAWN, + SKINCOLOR_CREAMSICLE, SKINCOLOR_ORANGE, - SKINCOLOR_SHINYORANGE, - SKINCOLOR_DARKORANGE, - SKINCOLOR_GOLDENBROWN, + SKINCOLOR_PUMPKIN, SKINCOLOR_ROSEWOOD, - SKINCOLOR_DARKROSEWOOD, + SKINCOLOR_BURGUNDY, + SKINCOLOR_BRONZE, SKINCOLOR_SEPIA, SKINCOLOR_BEIGE, SKINCOLOR_BROWN, SKINCOLOR_LEATHER, - SKINCOLOR_YELLOW, SKINCOLOR_PEACH, - SKINCOLOR_LIGHTORANGE, SKINCOLOR_CARAMEL, + SKINCOLOR_TANGERINE, SKINCOLOR_GOLD, - SKINCOLOR_SHINYCARAMEL, SKINCOLOR_VOMIT, + SKINCOLOR_YELLOW, + SKINCOLOR_CANARY, + SKINCOLOR_OLIVE, SKINCOLOR_GARDEN, - SKINCOLOR_LIGHTARMY, + SKINCOLOR_LIME, + SKINCOLOR_TEA, SKINCOLOR_ARMY, SKINCOLOR_PISTACHIO, - SKINCOLOR_ROBOHOOD, - SKINCOLOR_OLIVE, - SKINCOLOR_DARKARMY, - SKINCOLOR_LIGHTGREEN, - SKINCOLOR_UGLYGREEN, - SKINCOLOR_NEONGREEN, + SKINCOLOR_MOSS, + SKINCOLOR_MINT, SKINCOLOR_GREEN, - SKINCOLOR_DARKGREEN, + SKINCOLOR_ROBOHOOD, + SKINCOLOR_PINETREE, + SKINCOLOR_EMERALD, SKINCOLOR_SWAMP, - SKINCOLOR_FROST, - SKINCOLOR_SLATE, - SKINCOLOR_LIGHTBLUE, + SKINCOLOR_AQUA, + SKINCOLOR_TEAL, SKINCOLOR_CYAN, SKINCOLOR_CERULEAN, - SKINCOLOR_TURQUOISE, - SKINCOLOR_TEAL, - SKINCOLOR_STEELBLUE, + SKINCOLOR_SLATE, + SKINCOLOR_STEEL, + SKINCOLOR_PERIWINKLE, SKINCOLOR_BLUE, - SKINCOLOR_SHINYBLUE, + SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl + SKINCOLOR_BLUEBERRY, SKINCOLOR_NAVY, - SKINCOLOR_DARKBLUE, - SKINCOLOR_JETBLACK, - SKINCOLOR_LILAC, + SKINCOLOR_JET, + SKINCOLOR_DUSK, SKINCOLOR_PURPLE, SKINCOLOR_LAVENDER, - SKINCOLOR_BYZANTIUM, SKINCOLOR_INDIGO, + SKINCOLOR_BYZANTIUM, + SKINCOLOR_LILAC, // Careful! MAXSKINCOLORS cannot be greater than 0x40 -- Which it is now. MAXSKINCOLORS, @@ -541,4 +544,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note Required for proper collision with moving sloped surfaces that have sector specials on them. #define SECTORSPECIALSAFTERTHINK +/// SRB2Kart: Camera always has noclip. +/// \note Kind of problematic. If we decide to keep this on, we'll need serious map changes. +//#define NOCLIPCAM + #endif // __DOOMDEF__ diff --git a/src/doomstat.h b/src/doomstat.h index ea5151b1..8f1469a3 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -80,6 +80,7 @@ extern INT16 gametype; extern UINT8 splitscreen; extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean fromlevelselect; +extern boolean forceresetplayers; // ======================================== // Internal parameters for sound rendering. @@ -303,21 +304,19 @@ enum TypeOfLevel }; // Gametypes -enum GameType +enum GameType // SRB2Kart { - GT_COOP = 0, // also used in single player - GT_COMPETITION, // Classic "Race" - GT_RACE, + GT_RACE = 0, // also used in record attack + GT_MATCH, // battle, but renaming would be silly + NUMGAMETYPES, - GT_MATCH, + // the following have been left in on account of just not wanting to deal with removing all the checks for them + GT_COOP, + GT_COMPETITION, GT_TEAMMATCH, - GT_TAG, GT_HIDEANDSEEK, - - GT_CTF, // capture the flag - - NUMGAMETYPES + GT_CTF }; // If you alter this list, update gametype_cons_t in m_menu.c @@ -409,12 +408,17 @@ extern UINT16 spacetimetics; extern UINT16 extralifetics; // SRB2kart -extern INT32 bootime; -extern INT32 boostealtime; -extern INT32 mushroomtime; +extern tic_t introtime; +extern tic_t starttime; +extern INT32 hyudorotime; +extern INT32 stealtime; +extern INT32 sneakertime; extern INT32 itemtime; extern INT32 comebacktime; extern INT32 bumptime; +extern INT32 wipeoutslowtime; +extern INT32 wantedreduce; +extern INT32 wantedfrequency; extern UINT8 introtoplay; extern UINT8 creditscutscene; @@ -445,15 +449,18 @@ extern boolean franticitems; extern boolean mirrormode; extern boolean comeback; -extern tic_t lightningcooldown; -extern tic_t blueshellincoming; -extern UINT8 blueshellplayer; +extern SINT8 battlewanted[4]; +extern tic_t wantedcalcdelay; +extern tic_t indirectitemcooldown; +extern tic_t spbincoming; +extern UINT8 spbplayer; +extern tic_t mapreset; extern boolean legitimateexit; extern boolean comebackshowninfo; extern tic_t curlap, bestlap; -extern INT16 votelevels[4]; +extern INT16 votelevels[5][2]; extern SINT8 votes[MAXPLAYERS]; extern SINT8 pickedvote; diff --git a/src/f_finale.c b/src/f_finale.c index 913d7625..ab79fa78 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -58,6 +58,9 @@ static patch_t *ttkart; // *vroom* KART static patch_t *ttcheckers; // *vroom* KART static patch_t *ttkflash; // flash screen +static patch_t *driver[2]; // Driving character on the waiting screen +static UINT8 *waitcolormap; // colormap for the spinning character + static void F_SkyScroll(INT32 scrollspeed); // @@ -525,6 +528,7 @@ static const char *credits[] = { "\"Nev3r\"", "\"Ritz\"", "\"Spherallic\"", + "\"DirkTheHusky\"", "", "\1Produced By", "Kart Krew", @@ -590,7 +594,7 @@ void F_CreditDrawer(void) UINT16 i; fixed_t y = (80< vid.height) + if (((y>>FRACBITS) * vid.dupy) > vid.height) break; } @@ -682,13 +686,20 @@ boolean F_CreditResponder(event_t *event) break; } - /*if (!(timesBeaten) && !(netgame || multiplayer)) - return false;*/ - if (event->type != ev_keydown) return false; - if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE) + if (key == KEY_DOWNARROW || key == KEY_SPACE) + { + if (!timetonext && !finalecount) + animtimer += 7; + return false; + } + + /*if (!(timesBeaten) && !(netgame || multiplayer)) + return false;*/ + + if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_BACKSPACE) return false; if (keypressed) @@ -903,36 +914,52 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. - if (finalecount < 50) - V_DrawFill(0, 0, 320, 200, 31); - else - // Draw that sky! - F_SkyScroll(titlescrollspeed); - - // Don't draw outside of the title screewn, or if the patch isn't there. + // Don't draw outside of the title screen, or if the patch isn't there. if (!ttbanner || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)) - return; - - V_DrawSmallScaledPatch(84, 36, 0, ttbanner); - - if (finalecount < 20) { - if (finalecount >= 10) + F_SkyScroll(titlescrollspeed); + return; + } + + if (finalecount < 50) + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + + V_DrawSmallScaledPatch(84, 36, 0, ttbanner); + + if (finalecount >= 20) + V_DrawSmallScaledPatch(84, 87, 0, ttkart); + else if (finalecount >= 10) V_DrawSciencePatch((84<>1; + + F_SkyScroll(titlescrollspeed); - // Checkers, only need to be drawn after the whiteout, but we can do it here because it won't be seen before anyway V_DrawSciencePatch(0, 0 - FixedMul(40<= 50 && finalecount < 55) - { - V_DrawFill(0, 0, 320, 200, 120); - V_DrawSmallScaledPatch(84, 36, 0, ttkflash); + if (transval) + V_DrawFadeScreen(120, 10 - transval); + + V_DrawSmallScaledPatch(84, 36, 0, ttbanner); + + V_DrawSmallScaledPatch(84, 87, 0, ttkart); + + if (!transval) + return; + + V_DrawSmallScaledPatch(84, 36, transval<lumppat[1], PU_LEVEL); + } +} + +void F_WaitingPlayersTicker(void) +{ + if (paused) + return; + + finalecount++; + + // dumb hack, only start the music on the 1st tick so if you instantly go into the map you aren't hearing a tic of music + if (finalecount == 2) + S_ChangeMusicInternal("WAIT2J", true); +} + +void F_WaitingPlayersDrawer(void) +{ + UINT32 frame = (finalecount % 8) / 4; // The game only tics every other frame while waitingplayers + INT32 flags = V_FLIP; + const char *waittext1 = "You will join"; + const char *waittext2 = "the next race..."; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + V_DrawCreditString((160 - (V_CreditStringWidth(waittext1)>>1))<>1))<width / 2, 150<scene[scenenum].fadecolor) { - V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,cutscenes[cutnum]->scene[scenenum].fadecolor); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, cutscenes[cutnum]->scene[scenenum].fadecolor); F_WipeEndScreen(); F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeinid, true); @@ -1256,7 +1330,7 @@ void F_CutsceneDrawer(void) F_WipeStartScreen(); } } - V_DrawFill(0,0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); if (cutscenes[cutnum]->scene[scenenum].picname[picnum][0] != '\0') { diff --git a/src/f_finale.h b/src/f_finale.h index 1f23643b..1eb9fb33 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -35,10 +35,14 @@ void F_CutsceneTicker(void); void F_TitleDemoTicker(void); // Called by main loop. -FUNCMATH void F_GameEndDrawer(void); +void F_GameEndDrawer(void); void F_IntroDrawer(void); void F_TitleScreenDrawer(void); +void F_StartWaitingPlayers(void); +void F_WaitingPlayersTicker(void); +void F_WaitingPlayersDrawer(void); + void F_GameEvaluationDrawer(void); void F_StartGameEvaluation(void); void F_GameEvaluationTicker(void); @@ -78,6 +82,7 @@ enum wipe_level_toblack, wipe_intermission_toblack, + wipe_voting_toblack, wipe_continuing_toblack, wipe_titlescreen_toblack, wipe_timeattack_toblack, @@ -94,6 +99,7 @@ enum wipe_level_final, wipe_intermission_final, + wipe_voting_final, wipe_continuing_final, wipe_titlescreen_final, wipe_timeattack_final, @@ -107,9 +113,10 @@ enum wipe_specinter_final, wipe_multinter_final, - NUMWIPEDEFS + NUMWIPEDEFS, + WIPEFINALSHIFT = wipe_level_final - wipe_level_toblack }; -#define WIPEFINALSHIFT 13 + extern UINT8 wipedefs[NUMWIPEDEFS]; #endif diff --git a/src/f_wipe.c b/src/f_wipe.c index ed5736cb..ad0a2740 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -46,8 +46,9 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 99, // wipe_credits_intermediate (0) 0, // wipe_level_toblack - UINT8_MAX, // wipe_intermission_toblack - UINT8_MAX, // wipe_continuing_toblack + UINT8_MAX, // wipe_intermission_toblack + 0, // wipe_voting_toblack, + UINT8_MAX, // wipe_continuing_toblack 3, // wipe_titlescreen_toblack 0, // wipe_timeattack_toblack 99, // wipe_credits_toblack @@ -56,12 +57,13 @@ UINT8 wipedefs[NUMWIPEDEFS] = { UINT8_MAX, // wipe_intro_toblack (hardcoded) UINT8_MAX, // wipe_cutscene_toblack (hardcoded) - 0, // wipe_specinter_toblack - 0, // wipe_multinter_toblack - 0, // wipe_speclevel_towhite + UINT8_MAX, // wipe_specinter_toblack + UINT8_MAX, // wipe_multinter_toblack + 99, // wipe_speclevel_towhite - 0, // wipe_level_final + 3, // wipe_level_final 0, // wipe_intermission_final + 0, // wipe_voting_final 0, // wipe_continuing_final 3, // wipe_titlescreen_final 0, // wipe_timeattack_final diff --git a/src/g_game.c b/src/g_game.c index 9224ad84..223e203d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -95,7 +95,7 @@ boolean imcontinuing = false; boolean runemeraldmanager = false; // menu demo things -UINT8 numDemos = 3; +UINT8 numDemos = 0; //3; -- i'm FED UP of losing my skincolour to a broken demo. change this back when we make new ones UINT32 demoDelayTime = 15*TICRATE; UINT32 demoIdleTime = 3*TICRATE; @@ -132,7 +132,7 @@ boolean useNightsSS = false; UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_blueteam = SKINCOLOR_BLUE; UINT8 skincolor_redring = SKINCOLOR_RED; -UINT8 skincolor_bluering = SKINCOLOR_STEELBLUE; +UINT8 skincolor_bluering = SKINCOLOR_STEEL; tic_t countdowntimer = 0; boolean countdowntimeup = false; @@ -207,12 +207,17 @@ UINT16 spacetimetics = 11*TICRATE + (TICRATE/2); UINT16 extralifetics = 4*TICRATE; // SRB2kart -INT32 bootime = 7*TICRATE; -INT32 boostealtime = TICRATE/2; -INT32 mushroomtime = TICRATE + (TICRATE/3); +tic_t introtime = 108+5; // plus 5 for white fade +tic_t starttime = 6*TICRATE + (3*TICRATE/4); +INT32 hyudorotime = 7*TICRATE; +INT32 stealtime = TICRATE/2; +INT32 sneakertime = TICRATE + (TICRATE/3); INT32 itemtime = 8*TICRATE; INT32 comebacktime = 10*TICRATE; INT32 bumptime = 6; +INT32 wipeoutslowtime = 20; +INT32 wantedreduce = 5*TICRATE; +INT32 wantedfrequency = 10*TICRATE; INT32 gameovertics = 15*TICRATE; @@ -248,21 +253,24 @@ boolean franticitems; // Frantic items currently enabled? boolean comeback; // Battle Mode's karma comeback is on/off // Voting system -INT16 votelevels[4]; // Levels that were rolled by the host +INT16 votelevels[5][2]; // Levels that were rolled by the host SINT8 votes[MAXPLAYERS]; // Each player's vote SINT8 pickedvote; // What vote the host rolls -// Server-sided variables -tic_t lightningcooldown; // Cooldown before any more lightning/blue shell is awarded -tic_t blueshellincoming; // Timer before blue shell hits, can switch targets at this point -UINT8 blueshellplayer; // Player num that used the last blue shell +// Server-sided, synched variables +SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points +tic_t wantedcalcdelay; // Time before it recalculates WANTED +tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded +tic_t spbincoming; // Timer before SPB hits, can switch targets at this point +UINT8 spbplayer; // Player num that used the last SPB +tic_t mapreset; // Map reset delay when enough players have joined an empty game -// Client-sided variables (NEVER use in anything that needs to be synced with other players) +// Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? tic_t curlap; // Current lap time tic_t bestlap; // Best lap time -static INT16 randmapbuffer[NUMMAPS]; // Buffer for maps RandMap is allowed to roll +static INT16 randmapbuffer[NUMMAPS+1]; // Buffer for maps RandMap is allowed to roll tic_t hidetime; @@ -307,13 +315,6 @@ static struct { // Your naming conventions are stupid and useless. // There is no conflict here. -typedef struct demoghost { - UINT8 checksum[16]; - UINT8 *buffer, *p, color; - UINT16 version; - mobj_t oldmo, *mo; - struct demoghost *next; -} demoghost; demoghost *ghosts = NULL; boolean precache = true; // if true, load all graphics at start @@ -1189,7 +1190,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) INT32 laim, th, tspeed, forward, side, axis; //i const INT32 speed = 1; // these ones used for multiple conditions - boolean turnleft, turnright, invertmouse, mouseaiming, lookaxis, analogjoystickmove, gamepadjoystickmove, kbl, rd; + boolean turnleft, turnright, invertmouse, mouseaiming, lookaxis, usejoystick, analogjoystickmove, gamepadjoystickmove, kbl, rd; player_t *player; camera_t *thiscam; angle_t lang; @@ -1286,6 +1287,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) break; } + usejoystick = (analogjoystickmove || gamepadjoystickmove); turnright = InputDown(gc_turnright, ssplayer); turnleft = InputDown(gc_turnleft, ssplayer); @@ -1346,8 +1348,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->driftturn = (INT16)(cmd->driftturn - (mousex*(mirrormode ? -1 : 1)*8)); } - // Bounce pad strafing - if (!demoplayback && ((player->pflags & PF_FORCESTRAFE) || (player->kartstuff[k_feather] & 2))) + // Speed bump strafing + if (!demoplayback && ((player->pflags & PF_FORCESTRAFE) || (player->kartstuff[k_pogospring]))) { if (turnright) side += sidemove[1]; @@ -1360,42 +1362,23 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } } - //{ SRB2kart - Drift support - // limit turning to angleturn[1] to stop mouselook letting you look too fast - if (cmd->angleturn > angleturn[1]) - cmd->angleturn = angleturn[1]; - else if (cmd->angleturn < -angleturn[1]) - cmd->angleturn = -angleturn[1]; - - if (cmd->driftturn > angleturn[1]) - cmd->driftturn = angleturn[1]; - else if (cmd->driftturn < -angleturn[1]) - cmd->driftturn = -angleturn[1]; - - if (player->mo) - cmd->angleturn = K_GetKartTurnValue(player, cmd->angleturn); - - // SRB2kart - no additional angle if not moving - if ((player->mo && player->speed > 0) || (leveltime > 140 && cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE) || (player->spectator || objectplacing)) - lang += (cmd->angleturn<<16); - if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls { - if (InputDown(gc_accelerate, ssplayer) || (cv_usejoystick.value && axis > 0)) + if (InputDown(gc_accelerate, ssplayer) || (usejoystick && axis > 0)) cmd->buttons |= BT_ACCELERATE; - if (InputDown(gc_brake, ssplayer) || (cv_usejoystick.value && axis > 0)) + if (InputDown(gc_brake, ssplayer) || (usejoystick && axis > 0)) cmd->buttons |= BT_BRAKE; axis = JoyAxis(AXISAIM, ssplayer); - if (InputDown(gc_aimforward, ssplayer) || (gamepadjoystickmove && axis < 0) || (analogjoystickmove && axis < 0)) + if (InputDown(gc_aimforward, ssplayer) || (usejoystick && axis < 0)) forward += forwardmove[1]; - if (InputDown(gc_aimbackward, ssplayer) || (gamepadjoystickmove && axis > 0) || (analogjoystickmove && axis > 0)) + if (InputDown(gc_aimbackward, ssplayer) || (usejoystick && axis > 0)) forward -= forwardmove[1]; } else { // forward with key or button // SRB2kart - we use an accel/brake instead of forward/backward. axis = JoyAxis(AXISMOVE, ssplayer); - if (InputDown(gc_accelerate, ssplayer) || (gamepadjoystickmove && axis > 0) || player->kartstuff[k_mushroomtimer]) + if (InputDown(gc_accelerate, ssplayer) || (gamepadjoystickmove && axis > 0) || player->kartstuff[k_sneakertimer]) { cmd->buttons |= BT_ACCELERATE; forward = forwardmove[1]; // 50 @@ -1424,20 +1407,20 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // But forward/backward IS used for aiming. axis = JoyAxis(AXISAIM, ssplayer); - if (InputDown(gc_aimforward, ssplayer) || (cv_usejoystick.value && axis < 0)) + if (InputDown(gc_aimforward, ssplayer) || (usejoystick && axis < 0)) cmd->buttons |= BT_FORWARD; - if (InputDown(gc_aimbackward, ssplayer) || (cv_usejoystick.value && axis > 0)) + if (InputDown(gc_aimbackward, ssplayer) || (usejoystick && axis > 0)) cmd->buttons |= BT_BACKWARD; } // fire with any button/key axis = JoyAxis(AXISFIRE, ssplayer); - if (InputDown(gc_fire, ssplayer) || (cv_usejoystick.value && axis > 0)) + if (InputDown(gc_fire, ssplayer) || (usejoystick && axis > 0)) cmd->buttons |= BT_ATTACK; // drift with any button/key axis = JoyAxis(AXISDRIFT, ssplayer); - if (InputDown(gc_drift, ssplayer) || (cv_usejoystick.value && axis > 0)) + if (InputDown(gc_drift, ssplayer) || (usejoystick && axis > 0)) cmd->buttons |= BT_DRIFT; // Lua scriptable buttons @@ -1534,6 +1517,29 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->sidemove = (SINT8)(cmd->sidemove + side); } + //{ SRB2kart - Drift support + // Not grouped with the rest of turn stuff because it needs to know what buttons you're pressing for rubber-burn turn + // limit turning to angleturn[1] to stop mouselook letting you look too fast + if (cmd->angleturn > angleturn[1]) + cmd->angleturn = angleturn[1]; + else if (cmd->angleturn < -angleturn[1]) + cmd->angleturn = -angleturn[1]; + + if (cmd->driftturn > angleturn[1]) + cmd->driftturn = angleturn[1]; + else if (cmd->driftturn < -angleturn[1]) + cmd->driftturn = -angleturn[1]; + + if (player->mo) + cmd->angleturn = K_GetKartTurnValue(player, cmd->angleturn); + + // SRB2kart - no additional angle if not moving + if (((player->mo && player->speed > 0) // Moving + || (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn + || (player->spectator || objectplacing)) // Not a physical player + && !(player->kartstuff[k_spinouttimer] && player->kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout + lang += (cmd->angleturn<<16); + cmd->angleturn = (INT16)(lang >> 16); if (!hu_stopped) @@ -1837,7 +1843,7 @@ boolean G_Responder(event_t *ev) // SRB2Kart: Ehhh, who cares, Mario Kart's designed around screen-cheating anyway /*if (gametype != GT_RACE) { - if (players[consoleplayer].kartstuff[k_balloon] > 0) + if (players[consoleplayer].kartstuff[k_bumper] > 0) continue; }*/ @@ -1928,7 +1934,7 @@ boolean G_Responder(event_t *ev) else if (gamestate == GS_GAMEEND || gamestate == GS_EVALUATION || gamestate == GS_CREDITS) return true; - else if (gamestate == GS_INTERMISSION || gamestate == GS_VOTING) + else if (gamestate == GS_INTERMISSION || gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS) if (HU_Responder(ev)) return true; // chat ate the event @@ -2181,9 +2187,13 @@ void G_Ticker(boolean run) break; case GS_TITLESCREEN: - case GS_WAITINGPLAYERS: F_TitleScreenTicker(run); break; + case GS_WAITINGPLAYERS: + if (netgame) + F_WaitingPlayersTicker(); + HU_Ticker(); + break; case GS_DEDICATEDSERVER: case GS_NULL: @@ -2192,6 +2202,11 @@ void G_Ticker(boolean run) if (run) { + if (G_GametypeHasSpectators() + && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING // definitely good + || gamestate == GS_WAITINGPLAYERS)) // definitely a problem if we don't do it at all in this gamestate, but might need more protection? + K_CheckSpectateStatus(); + if (pausedelay) pausedelay--; @@ -2244,19 +2259,33 @@ static inline void G_PlayerFinishLevel(INT32 player) p->starpostnum = 0; p->starpostcount = 0; - if (rendermode == render_soft) - V_SetPaletteLump(GetPalette()); // Reset the palette - // SRB2kart: Increment the "matches played" counter. if (player == consoleplayer) { - if (legitimateexit && !demoplayback) // (yes you're allowed to unlock stuff this way when the game is modified) + if (legitimateexit && !demoplayback && !mapreset) // (yes you're allowed to unlock stuff this way when the game is modified) { - matchesplayed++; - if (M_UpdateUnlockablesAndExtraEmblems(true)) + UINT8 i = 0; + + if (netgame) { - S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(true); // only save if unlocked something + // check to see if there's anyone else at all + for (; i < MAXPLAYERS; i++) + { + if (i == consoleplayer) + continue; + if (playeringame[i] && !stplyr->spectator) + break; + } + } + + if (i != MAXPLAYERS) // Not FREE PLAY + { + matchesplayed++; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + { + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); // only save if unlocked something + } } } @@ -2271,7 +2300,7 @@ static inline void G_PlayerFinishLevel(INT32 player) void G_PlayerReborn(INT32 player) { player_t *p; - INT32 score; + INT32 score, marescore; INT32 lives; INT32 continues; UINT8 charability; @@ -2316,11 +2345,12 @@ void G_PlayerReborn(INT32 player) // SRB2kart INT32 starpostwp; - INT32 offroad; - INT32 balloon; + INT32 bumper; INT32 comebackpoints; + INT32 wanted; score = players[player].score; + marescore = players[player].marescore; lives = players[player].lives; continues = players[player].continues; ctfteam = players[player].ctfteam; @@ -2373,14 +2403,15 @@ void G_PlayerReborn(INT32 player) // SRB2kart starpostwp = players[player].kartstuff[k_starpostwp]; - offroad = players[player].kartstuff[k_offroad]; - balloon = players[player].kartstuff[k_balloon]; + bumper = players[player].kartstuff[k_bumper]; comebackpoints = players[player].kartstuff[k_comebackpoints]; + wanted = players[player].kartstuff[k_wanted]; p = &players[player]; memset(p, 0, sizeof (*p)); p->score = score; + p->marescore = marescore; p->lives = lives; p->continues = continues; p->pflags = pflags; @@ -2431,11 +2462,10 @@ void G_PlayerReborn(INT32 player) // SRB2kart p->kartstuff[k_starpostwp] = starpostwp; // TODO: get these out of kartstuff, it causes desync - p->kartstuff[k_offroad] = offroad; - - p->kartstuff[k_balloon] = balloon; + p->kartstuff[k_bumper] = bumper; p->kartstuff[k_comebackpoints] = comebackpoints; p->kartstuff[k_comebacktimer] = comebacktime; + p->kartstuff[k_wanted] = wanted; // Don't do anything immediately p->pflags |= PF_USEDOWN; @@ -2461,14 +2491,14 @@ void G_PlayerReborn(INT32 player) P_RestoreMusic(p); - if (leveltime > 157 && !p->spectator) - p->kartstuff[k_lakitu] = 48; // Lakitu Spawner + if (leveltime > (starttime + (TICRATE/2)) && !p->spectator) + p->kartstuff[k_respawn] = 48; // Respawn effect if (gametype == GT_COOP) P_FindEmerald(); // scan for emeralds to hunt for // Reset Nights score and max link to 0 on death - p->marescore = p->maxlink = 0; + p->maxlink = 0; // If NiGHTS, find lowest mare to start with. p->mare = P_FindLowestMare(); @@ -2980,7 +3010,7 @@ void G_ExitLevel(void) CV_SetValue(&cv_teamscramble, cv_scrambleonchange.value); } - if (gametype != GT_COOP) + if (netgame || multiplayer) CONS_Printf(M_GetText("The round has ended.\n")); // Remove CEcho text on round end. @@ -2997,10 +3027,11 @@ void G_ExitLevel(void) boolean G_IsSpecialStage(INT32 mapnum) { #if 0 - if (gametype == GT_COOP && modeattacking != ATTACKING_RECORD && mapnum >= sstage_start && mapnum <= sstage_end) - return true; -#endif + return (gametype == GT_COOP && modeattacking != ATTACKING_RECORD && mapnum >= sstage_start && mapnum <= sstage_end); +#else + (void)mapnum; return false; +#endif } // @@ -3048,7 +3079,7 @@ boolean G_GametypeHasSpectators(void) #if 0 return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); #else - return true; + return (!splitscreen);//true; #endif } @@ -3062,6 +3093,42 @@ boolean G_BattleGametype(void) return (gametype == GT_MATCH); } +// +// G_SometimesGetDifferentGametype +// +// I pity the fool who adds more gametypes later, because it'll require some element of randomisation which needs to be synched... +// Although given this only gets called for the host, you could probably get away with M_Random. +// +INT16 G_SometimesGetDifferentGametype(void) +{ + if (randmapbuffer[NUMMAPS] != -1) + return gametype; + + randmapbuffer[NUMMAPS] = gametype; + + if (gametype == GT_MATCH) + return GT_RACE; + return GT_MATCH; +} + +// +// G_GetGametypeColor +// +// Pretty and consistent ^u^ +// See also M_GetGametypeColor. +// +UINT8 G_GetGametypeColor(INT16 gt) +{ + if (modeattacking // == ATTACKING_RECORD + || gamestate == GS_TIMEATTACK) + return orangemap[120]; + if (gt == GT_MATCH) + return redmap[120]; + if (gt == GT_RACE) + return skymap[120]; + return 247; // FALLBACK +} + // // G_RaceGametype // @@ -3131,12 +3198,15 @@ static INT32 TOLMaps(INT16 tolflags) * has those flags. * \author Graue */ -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer) +static INT16 *okmaps = NULL; +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon) { - INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); INT32 numokmaps = 0; INT16 ix, bufx; + if (!okmaps) + okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); + // Find all the maps that are ok and and put them in an array. for (ix = 0; ix < NUMMAPS; ix++) { @@ -3147,7 +3217,9 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignoreb if ((mapheaderinfo[ix]->typeoflevel & tolflags) != tolflags || ix == pprevmap - || (M_MapLocked(ix+1) && !dedicated)) + || (!dedicated && M_MapLocked(ix+1)) + || (!maphell && (mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU)) // this is bad + || ((maphell == 2) && !(mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU))) // gasp isokmap = false; if (!ignorebuffer) @@ -3171,10 +3243,12 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignoreb if (numokmaps == 0) { if (!ignorebuffer) - return G_RandMap(tolflags, pprevmap, dontadd, true); // If there's no matches, (An incredibly silly function chain, buuut... :V) + return G_RandMap(tolflags, pprevmap, dontadd, true, maphell, callagainsoon); // If there's no matches, (An incredibly silly function chain, buuut... :V) + if (maphell) + return G_RandMap(tolflags, pprevmap, dontadd, true, maphell-1, callagainsoon); ix = 0; // Sorry, none match. You get MAP01. - for (bufx = 0; bufx < NUMMAPS; bufx++) + for (bufx = 0; bufx < NUMMAPS+1; bufx++) randmapbuffer[bufx] = -1; // if we're having trouble finding a map we should probably clear it } else @@ -3182,13 +3256,17 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignoreb ix = okmaps[M_RandomKey(numokmaps)]; if (!dontadd) { - for (bufx = NUMMAPS; bufx > 0; bufx--) + for (bufx = NUMMAPS-1; bufx > 0; bufx--) randmapbuffer[bufx] = randmapbuffer[bufx-1]; randmapbuffer[0] = ix; } } - Z_Free(okmaps); + if (!callagainsoon) + { + Z_Free(okmaps); + okmaps = NULL; + } return ix; } @@ -3198,7 +3276,7 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignoreb // static void G_DoCompleted(void) { - INT32 i; + INT32 i, j = 0; boolean gottoken = false; tokenlist = 0; // Reset the list @@ -3212,7 +3290,20 @@ static void G_DoCompleted(void) for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) + { + // SRB2Kart: exitlevel shouldn't get you the points + if (!players[i].exiting && !(players[i].pflags & PF_TIMEOVER)) + { + players[i].pflags |= PF_TIMEOVER; + if (P_IsLocalPlayer(&players[i])) + j++; + } G_PlayerFinishLevel(i); // take away cards and stuff + } + + // play some generic music if there's no win/cool/lose music going on (for exitlevel commands) + if (G_RaceGametype() && j == splitscreen+1) + S_ChangeMusicInternal("racent", true); if (automapactive) AM_Stop(); @@ -3253,6 +3344,9 @@ static void G_DoCompleted(void) else cm = (INT16)(mapheaderinfo[cm]->nextlevel-1); + if (cm == 1100-1) // !!! WHENEVER WE GET GRAND PRIX, GO TO AWARDS MAP INSTEAD !!! + cm = cm+1; + if (cm >= NUMMAPS || cm < 0) // out of range (either 1100-1102 or error) { cm = nextmap; //Start the loop again so that the error checking below is executed. @@ -3315,7 +3409,7 @@ static void G_DoCompleted(void) if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-4] != -1) // we're getting pretty full, so lets clear it { - for (i = 0; i < NUMMAPS; i++) + for (i = 0; i < NUMMAPS+1; i++) randmapbuffer[i] = -1; } @@ -3324,7 +3418,7 @@ static void G_DoCompleted(void) if (cv_advancemap.value == 0) // Stay on same map. nextmap = prevmap; else if (cv_advancemap.value == 2) // Go to random map. - nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, false); + nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, false, 0, false); } // We are committed to this map now. @@ -3366,19 +3460,44 @@ void G_AfterIntermission(void) // void G_NextLevel(void) { + boolean dovote = false; + if ((cv_advancemap.value == 3 && gamestate != GS_VOTING) && !modeattacking && !skipstats && (multiplayer || netgame)) + { + UINT8 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + dovote = true; + break; + } + } + } + + if (dovote) gameaction = ga_startvote; else + { + if (gamestate != GS_VOTING) + forceresetplayers = false; gameaction = ga_worlddone; + } } static void G_DoWorldDone(void) { if (server) { - // SRB2kart: don't reset player between maps - D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); + // SRB2Kart + D_MapChange(nextmap+1, + gametype, + ultimatemode, + forceresetplayers, + 0, + false, + false); } gameaction = ga_nothing; @@ -3410,6 +3529,7 @@ static void G_DoStartContinue(void) { I_Assert(!netgame && !multiplayer); + legitimateexit = false; G_PlayerFinishLevel(consoleplayer); // take away cards and stuff F_StartContinue(); @@ -3656,7 +3776,7 @@ void G_SaveGameData(boolean force) if (force) // SRB2Kart: for enabling unlocks online, even if the game is modified modifiedgame = savemoddata; // L-let's just sort of... hack around the cheat protection, because I'm too worried about just removing it @@; - else if (modifiedgame && !savemoddata) + else if (modifiedgame && !savemoddata) { free(savebuffer); save_p = savebuffer = NULL; @@ -3967,9 +4087,16 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, U if (demoplayback) COM_BufAddText("stopdemo\n"); + + while (ghosts) + { + demoghost *next = ghosts->next; + Z_Free(ghosts); + ghosts = next; + } ghosts = NULL; - for (i = 0; i < NUMMAPS; i++) + for (i = 0; i < NUMMAPS+1; i++) randmapbuffer[i] = -1; // this leave the actual game if needed @@ -4023,11 +4150,12 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean if (!demoplayback && !netgame) // Netgame sets random seed elsewhere, demo playback sets seed just before us! P_SetRandSeed(M_RandomizedSeed()); // Use a more "Random" random seed - if (resetplayer) + //SRB2Kart - Score is literally the only thing you SHOULDN'T reset at all times + //if (resetplayer) { // Clear a bunch of variables tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; - countdown = countdown2 = 0; + countdown = countdown2 = mapreset = 0; for (i = 0; i < MAXPLAYERS; i++) { @@ -4036,6 +4164,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean players[i].starpostx = players[i].starposty = players[i].starpostz = 0; players[i].starpostcount = 0; // srb2kart +#if 0 if (netgame || multiplayer) { players[i].lives = cv_startinglives.value; @@ -4052,13 +4181,23 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean players[i].continues = 1; } + players[i].xtralife = 0; +#else + players[i].lives = 1; // SRB2Kart +#endif + // The latter two should clear by themselves, but just in case players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS); // Clear cheatcodes too, just in case. players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); - players[i].score = players[i].xtralife = 0; + players[i].marescore = 0; + + if (resetplayer) // SRB2Kart + { + players[i].score = 0; + } } // Reset unlockable triggers @@ -4860,6 +4999,7 @@ void G_GhostTicker(void) p->next = g->next; else ghosts = g->next; + Z_Free(g); continue; } p = g; @@ -5592,8 +5732,7 @@ void G_DoPlayDemo(char *defdemoname) memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; P_SetRandSeed(randseed); - //G_InitNew(false, G_BuildMapName(gamemap), false, true); // resetplayer needs to be false to retain score - G_InitNew(false, G_BuildMapName(gamemap), true, true); // ...but uh, for demos? doing that makes them start in different positions depending on the last demo you watched + G_InitNew(false, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer. // Set skin SetPlayerSkin(0, skin); @@ -5803,29 +5942,28 @@ void G_AddGhost(char *defdemoname) mthing = playerstarts[0]; I_Assert(mthing); { // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling. - fixed_t x,y,z; - sector_t *sector; - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; - sector = R_PointInSubsector(x, y)->sector; + fixed_t z,f,c; + gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST); + gh->mo->angle = FixedAngle(mthing->angle*FRACUNIT); + f = gh->mo->floorz; + c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height; if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) { - z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; + z = c; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); - if (z < sector->floorheight) - z = sector->floorheight; + if (z < f) + z = f; } else { - z = sector->floorheight; + z = f; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); - if (z > sector->ceilingheight - mobjinfo[MT_PLAYER].height) - z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; + if (z > c) + z = c; } - gh->mo = P_SpawnMobj(x, y, z, MT_GHOST); - gh->mo->angle = FixedAngle(mthing->angle*FRACUNIT); + gh->mo->z = z; } gh->mo->state = states+S_KART_STND1; // SRB2kart - was S_PLAY_STND gh->mo->sprite = gh->mo->state->sprite; @@ -6023,8 +6161,13 @@ boolean G_CheckDemoStatus(void) { boolean saved; - if(ghosts) // ... ... ... - ghosts = NULL; // :) + while (ghosts) + { + demoghost *next = ghosts->next; + Z_Free(ghosts); + ghosts = next; + } + ghosts = NULL; // DO NOT end metal sonic demos here diff --git a/src/g_game.h b/src/g_game.h index fa188824..47c51d93 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -168,6 +168,17 @@ void G_WriteMetalTic(mobj_t *metal); void G_SaveMetal(UINT8 **buffer); void G_LoadMetal(UINT8 **buffer); +// Your naming conventions are stupid and useless. +// There is no conflict here. +typedef struct demoghost { + UINT8 checksum[16]; + UINT8 *buffer, *p, color; + UINT16 version; + mobj_t oldmo, *mo; + struct demoghost *next; +} demoghost; +extern demoghost *ghosts; + void G_DoPlayDemo(char *defdemoname); void G_TimeDemo(const char *name); void G_AddGhost(char *defdemoname); @@ -184,6 +195,8 @@ boolean G_GametypeUsesLives(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); boolean G_BattleGametype(void); +INT16 G_SometimesGetDifferentGametype(void); +UINT8 G_GetGametypeColor(INT16 gt); boolean G_RaceGametype(void); boolean G_TagGametype(void); void G_ExitLevel(void); @@ -237,6 +250,6 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer); +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon); #endif diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 99cc3613..f1949325 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -209,7 +209,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // if it's meant to cover the whole screen, black out the rest // cx and cy are possibly *slightly* off from float maths // This is done before here compared to software because we directly alter cx and cy to centre - if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + /*if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); @@ -217,7 +217,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, const UINT8 *source = (const UINT8 *)(column) + 3; HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); Z_Free(realpatch); - } + }*/ // centre screen if (vid.width != BASEVIDWIDTH * vid.dupx) { @@ -292,9 +292,9 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, { FSurfaceInfo Surf; Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value]; - else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[cv_translucenthud.value]; - else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; + if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[hudtrans]; + else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[hudtrans]; + else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[hudtrans]; else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); @@ -357,7 +357,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // if it's meant to cover the whole screen, black out the rest // cx and cy are possibly *slightly* off from float maths // This is done before here compared to software because we directly alter cx and cy to centre - if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + /*if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); @@ -365,7 +365,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal const UINT8 *source = (const UINT8 *)(column) + 3; HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); Z_Free(realpatch); - } + }*/ // centre screen if (vid.width != BASEVIDWIDTH * vid.dupx) { @@ -446,9 +446,9 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal { FSurfaceInfo Surf; Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value]; - else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[cv_translucenthud.value]; - else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; + if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[hudtrans]; + else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[hudtrans]; + else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[hudtrans]; else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); @@ -576,29 +576,33 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum // | /| // |/ | // 0--1 -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) { - FOutVector v[4]; - FSurfaceInfo Surf; + FOutVector v[4]; + FSurfaceInfo Surf; - // setup some neat-o translucency effect - if (!height) //cool hack 0 height is full height - height = vid.height; + v[0].x = v[3].x = -1.0f; + v[2].x = v[1].x = 1.0f; + v[0].y = v[1].y = -1.0f; + v[2].y = v[3].y = 1.0f; + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].x = v[3].x = -1.0f; - v[2].x = v[1].x = 1.0f; - v[0].y = v[1].y = 1.0f-((height<<1)/(float)vid.height); - v[2].y = v[3].y = 1.0f; - v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + v[0].sow = v[3].sow = 0.0f; + v[2].sow = v[1].sow = 1.0f; + v[0].tow = v[1].tow = 1.0f; + v[2].tow = v[3].tow = 0.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 1.0f; - v[2].tow = v[3].tow = 0.0f; - - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = (UINT8)((0xff/2) * ((float)height / vid.height)); //calum: varies console alpha - HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); + if (color & 0xFF00) // Do COLORMAP fade. + { + Surf.FlatColor.rgba = UINT2RGBA(0x01010160); + Surf.FlatColor.s.alpha = (strength*8); + } + else // Do TRANSMAP** fade. + { + Surf.FlatColor.rgba = pLocalPalette[color].rgba; + Surf.FlatColor.s.alpha = (UINT8)(strength*25.5f); + } + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } // Draw the console background with translucency support @@ -900,6 +904,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) PF_Modulated|PF_NoTexture|PF_NoDepthTest); } + // -------------------+ // HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that. // -------------------+ @@ -1005,6 +1010,104 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } +// -----------------+ +// HWR_DrawDiag : draw flat coloured rectangle, with no texture +// -----------------+ +void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color) +{ + FOutVector v[4]; + FSurfaceInfo Surf; + float fx, fy, fw, fh, fwait = 0; + + if (wh < 0) + return; // consistency w/ software + +// 3--2 +// | /| +// |/ | +// 0--1 + + fx = (float)x; + fy = (float)y; + fw = fh = (float)wh; + + if (!(color & V_NOSCALESTART)) + { + float dupx = (float)vid.dupx, dupy = (float)vid.dupy; + + fx *= dupx; + fy *= dupy; + fw *= dupx; + fh *= dupy; + + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (color & V_SNAPTORIGHT) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(color & V_SNAPTOLEFT)) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (color & V_SNAPTOBOTTOM) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(color & V_SNAPTOTOP)) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (fx >= vid.width || fy >= vid.height) + return; + if (fx < 0) + { + fw += fx; + fx = 0; + } + if (fy < 0) + { + fh += fy; + fy = 0; + } + + if (fw <= 0 || fh <= 0) + return; + if (fx + fw > vid.width) + { + fwait = fw - ((float)vid.width - fx); + fw = (float)vid.width - fx; + } + if (fy + fh > vid.height) + fh = (float)vid.height - fy; + + fx = -1 + fx / (vid.width / 2); + fy = 1 - fy / (vid.height / 2); + fw = fw / (vid.width / 2); + fh = fh / (vid.height / 2); + + v[0].x = v[3].x = fx; + v[2].x = v[1].x = fx + fw; + v[0].y = v[1].y = fy; + v[3].y = fy - fh; + v[2].y = fy - fwait; + + //Hurdler: do we still use this argb color? if not, we should remove it + v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].sow = v[3].sow = 0.0f; + v[2].sow = v[1].sow = 1.0f; + v[0].tow = v[1].tow = 0.0f; + v[2].tow = v[3].tow = 1.0f; + + Surf.FlatColor = V_GetColor(color); + + HWD.pfnDrawPolygon(&Surf, v, 4, + PF_Modulated|PF_NoTexture|PF_NoDepthTest); +} + + + #ifdef HAVE_PNG #ifndef _MSC_VER diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index eeb5afbd..ee0cca74 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -499,23 +499,46 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], //"SPRG", &lspr[NOLIGHT], //"BSPR", + &lspr[NOLIGHT], //"RNDM", - &lspr[NOLIGHT], //"SPRK", &lspr[NOLIGHT], //"KFRE", &lspr[NOLIGHT], //"DRIF", - &lspr[NOLIGHT], //"FAKE", - &lspr[NOLIGHT], //"DFAK", + &lspr[NOLIGHT], //"DSMO", + + &lspr[NOLIGHT], //"FITM", &lspr[NOLIGHT], //"BANA", - &lspr[NOLIGHT], //"DBAN", &lspr[NOLIGHT], //"GSHE", - &lspr[NOLIGHT], //"GSTR", - &lspr[NOLIGHT], //"DGSH", &lspr[NOLIGHT], //"RSHE", - &lspr[NOLIGHT], //"RSTR", - &lspr[NOLIGHT], //"DRSH", - &lspr[NOLIGHT], //"BOMB", + &lspr[NOLIGHT], //"SSMN", &lspr[NOLIGHT], //"BLIG", - &lspr[NOLIGHT], //"LIGH" + &lspr[NOLIGHT], //"LIGH", + &lspr[NOLIGHT], //"SINK", + &lspr[NOLIGHT], //"SITR", + &lspr[NOLIGHT], //"KBLN", + + &lspr[NOLIGHT], //"LAKI", + + &lspr[NOLIGHT], //"POKE", + &lspr[NOLIGHT], //"AUDI", + &lspr[NOLIGHT], //"DECO", + &lspr[NOLIGHT], //"DOOD", + &lspr[NOLIGHT], //"SNES", + &lspr[NOLIGHT], //"GBAS", + &lspr[NOLIGHT], //"SPRS", + &lspr[NOLIGHT], //"BUZB", + &lspr[NOLIGHT], //"CHOM", + &lspr[NOLIGHT], //"SACO", + &lspr[NOLIGHT], //"CRAB", + &lspr[NOLIGHT], //"SHAD", + + &lspr[NOLIGHT], //"BUMP", + &lspr[NOLIGHT], //"FLEN", + &lspr[NOLIGHT], //"CLAS", + &lspr[NOLIGHT], //"PSHW", + + &lspr[NOLIGHT], //"ARRO", + + &lspr[NOLIGHT], //"PBOM" // Free slots &lspr[NOLIGHT], diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index cd87b722..4b088dfd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -59,7 +59,7 @@ struct hwdriver_s hwdriver; // ========================================================================== -static void HWR_AddSprites(sector_t *sec); +static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer); static void HWR_ProjectSprite(mobj_t *thing); #ifdef HWPRECIP static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); @@ -582,7 +582,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size + if ((UINT32)nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size { CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX); return; @@ -3234,7 +3234,7 @@ static void HWR_AddPolyObjectPlanes(void) // : Draw one or more line segments. // Notes : Sets gr_cursectorlight to the light of the parent sector, to modulate wall textures // -----------------+ -static void HWR_Subsector(size_t num) +static void HWR_Subsector(size_t num, UINT8 ssplayer) { INT16 count; seg_t *line; @@ -3602,7 +3602,7 @@ static void HWR_Subsector(size_t num) { // draw sprites first, coz they are clipped to the solidsegs of // subsectors more 'in front' - HWR_AddSprites(gr_frontsector); + HWR_AddSprites(gr_frontsector, ssplayer); //Hurdler: at this point validcount must be the same, but is not because // gr_frontsector doesn't point anymore to sub->sector due to @@ -3654,7 +3654,7 @@ static boolean HWR_CheckHackBBox(fixed_t *bb) // BP: big hack for a test in lighning ref : 1249753487AB fixed_t *hwbbox; -static void HWR_RenderBSPNode(INT32 bspnum) +static void HWR_RenderBSPNode(INT32 bspnum, UINT8 ssplayer) { /*//GZDoom code if(bspnum == -1) @@ -3694,12 +3694,12 @@ static void HWR_RenderBSPNode(INT32 bspnum) if (bspnum == -1) { //*(gr_drawsubsector_p++) = 0; - HWR_Subsector(0); + HWR_Subsector(0, ssplayer); } else { //*(gr_drawsubsector_p++) = bspnum&(~NF_SUBSECTOR); - HWR_Subsector(bspnum&(~NF_SUBSECTOR)); + HWR_Subsector(bspnum&(~NF_SUBSECTOR), ssplayer); } return; } @@ -3711,14 +3711,14 @@ static void HWR_RenderBSPNode(INT32 bspnum) hwbbox = bsp->bbox[side]; // Recursively divide front space. - HWR_RenderBSPNode(bsp->children[side]); + HWR_RenderBSPNode(bsp->children[side], ssplayer); // Possibly divide back space. if (HWR_CheckBBox(bsp->bbox[side^1])) { // BP: big hack for a test in lighning ref : 1249753487AB hwbbox = bsp->bbox[side^1]; - HWR_RenderBSPNode(bsp->children[side^1]); + HWR_RenderBSPNode(bsp->children[side^1], ssplayer); } } @@ -5110,7 +5110,7 @@ static void HWR_DrawSprites(void) // During BSP traversal, this adds sprites by sector. // -------------------------------------------------------------------------- static UINT8 sectorlight; -static void HWR_AddSprites(sector_t *sec) +static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer) { mobj_t *thing; #ifdef HWPRECIP @@ -5140,6 +5140,25 @@ static void HWR_AddSprites(sector_t *sec) if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) continue; + if (splitscreen) + { + if (thing->eflags & MFE_DRAWONLYFORP1) + if (ssplayer != 1) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP2) + if (ssplayer != 2) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) + if (ssplayer != 3) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) + if (ssplayer != 4) + continue; + } + approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); if (approx_dist <= limit_dist) @@ -5150,8 +5169,31 @@ static void HWR_AddSprites(sector_t *sec) { // Draw everything in sector, no checks for (thing = sec->thinglist; thing; thing = thing->snext) - if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)) - HWR_ProjectSprite(thing); + { + if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) + continue; + + if (splitscreen) + { + if (thing->eflags & MFE_DRAWONLYFORP1) + if (ssplayer != 1) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP2) + if (ssplayer != 2) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) + if (ssplayer != 3) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) + if (ssplayer != 4) + continue; + } + + HWR_ProjectSprite(thing); + } } #ifdef HWPRECIP @@ -5388,23 +5430,15 @@ static void HWR_ProjectSprite(mobj_t *thing) else if (thing->color) { // New colormap stuff for skins Tails 06-07-2002 - if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player! + if (thing->colorized) + vis->colormap = R_GetTranslationColormap(TC_RAINBOW, thing->color, GTC_CACHE); + else if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player! { - if (thing->colorized) - vis->colormap = R_GetTranslationColormap(TC_STARMAN, thing->color, GTC_CACHE); - else - { - size_t skinnum = (skin_t*)thing->skin-skins; - vis->colormap = R_GetTranslationColormap((INT32)skinnum, thing->color, GTC_CACHE); - } + size_t skinnum = (skin_t*)thing->skin-skins; + vis->colormap = R_GetTranslationColormap((INT32)skinnum, thing->color, GTC_CACHE); } else - { - if (vis->mobj && vis->mobj->colorized) - vis->colormap = R_GetTranslationColormap(TC_STARMAN, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE); - else - vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE); - } + vis->colormap = R_GetTranslationColormap(TC_DEFAULT, thing->color, GTC_CACHE); } else vis->colormap = colormaps; @@ -5666,13 +5700,31 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) { const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); postimg_t *type; + UINT8 ssplayer = 0; - if (splitscreen && player == &players[secondarydisplayplayer]) - type = &postimgtype2; - else if (splitscreen > 1 && player == &players[thirddisplayplayer]) - type = &postimgtype3; - else if (splitscreen > 2 && player == &players[fourthdisplayplayer]) - type = &postimgtype4; + if (splitscreen) + { + if (player == &players[secondarydisplayplayer]) + { + type = &postimgtype2; + ssplayer = 2; + } + else if (splitscreen > 1 && player == &players[thirddisplayplayer]) + { + type = &postimgtype3; + ssplayer = 3; + } + else if (splitscreen > 2 && player == &players[fourthdisplayplayer]) + { + type = &postimgtype4; + ssplayer = 4; + } + else + { + type = &postimgtype; + ssplayer = 1; + } + } else type = &postimgtype; @@ -5789,7 +5841,7 @@ if (0) validcount++; - HWR_RenderBSPNode((INT32)numnodes-1); + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) @@ -5806,18 +5858,18 @@ if (0) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //left + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //left dup_viewangle += ANGLE_90; if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) { HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //back + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //back } dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //right + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //right dup_viewangle += ANGLE_90; } @@ -5881,17 +5933,35 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) { const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); postimg_t *type; + UINT8 ssplayer = 0; const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on FRGBAFloat ClearColor; - if (splitscreen && player == &players[secondarydisplayplayer]) - type = &postimgtype2; - else if (splitscreen > 1 && player == &players[thirddisplayplayer]) - type = &postimgtype3; - else if (splitscreen > 2 && player == &players[fourthdisplayplayer]) - type = &postimgtype4; + if (splitscreen) + { + if (player == &players[secondarydisplayplayer]) + { + type = &postimgtype2; + ssplayer = 2; + } + else if (splitscreen > 1 && player == &players[thirddisplayplayer]) + { + type = &postimgtype3; + ssplayer = 3; + } + else if (splitscreen > 2 && player == &players[fourthdisplayplayer]) + { + type = &postimgtype4; + ssplayer = 4; + } + else + { + type = &postimgtype; + ssplayer = 1; + } + } else type = &postimgtype; @@ -6019,7 +6089,7 @@ if (0) validcount++; - HWR_RenderBSPNode((INT32)numnodes-1); + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) @@ -6036,18 +6106,18 @@ if (0) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //left + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //left dup_viewangle += ANGLE_90; if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) { HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //back + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //back } dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //right + HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //right dup_viewangle += ANGLE_90; } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index f0efc1c5..f74814f0 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -33,7 +33,7 @@ void HWR_Shutdown(void); void HWR_clearAutomap(void); void HWR_drawAMline(const fline_t *fl, INT32 color); -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height); +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength); void HWR_DrawConsoleBack(UINT32 color, INT32 height); void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); @@ -46,13 +46,13 @@ void HWR_SetViewSize(void); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, const UINT8 *colormap); void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); -void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, fixed_t scale, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); void HWR_PrepLevelCache(size_t pnumtextures); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right. +void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color); void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); void HWR_AddCommands(void); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8bb4c959..087718e2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -41,6 +41,7 @@ #include "../r_things.h" #include "../r_draw.h" #include "../p_tick.h" +#include "../k_kart.h" // colortranslations #include "hw_main.h" #include "../v_video.h" @@ -938,6 +939,7 @@ spritemd2found: static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) { + UINT8 i; UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; @@ -963,252 +965,46 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, image = gpatch->mipmap.grInfo.data; blendimage = blendgpatch->mipmap.grInfo.data; - switch (color) + // Average all of the translation's colors { - case SKINCOLOR_IVORY: - blendcolor = V_GetColor(0); - break; - case SKINCOLOR_WHITE: - blendcolor = V_GetColor(3); - break; - case SKINCOLOR_SILVER: - blendcolor = V_GetColor(7); - break; - case SKINCOLOR_CLOUDY: - blendcolor = V_GetColor(13); - break; - case SKINCOLOR_GREY: - blendcolor = V_GetColor(15); - break; - case SKINCOLOR_DARKGREY: - blendcolor = V_GetColor(23); - break; - case SKINCOLOR_BLACK: - blendcolor = V_GetColor(27); - break; - case SKINCOLOR_SALMON: - blendcolor = V_GetColor(123); - break; - case SKINCOLOR_PINK: - blendcolor = V_GetColor(147); - break; - case SKINCOLOR_LIGHTRED: - blendcolor = V_GetColor(127); - break; - case SKINCOLOR_SHINYRED: - blendcolor = V_GetColor(130); - break; - case SKINCOLOR_RED: - blendcolor = V_GetColor(132); - break; - case SKINCOLOR_DARKPINK: - blendcolor = V_GetColor(151); - break; - case SKINCOLOR_DARKRED: - blendcolor = V_GetColor(139); - break; - case SKINCOLOR_DAWN: - blendcolor = V_GetColor(89); - break; - case SKINCOLOR_ORANGE: - blendcolor = V_GetColor(87); - break; - case SKINCOLOR_SHINYORANGE: - blendcolor = V_GetColor(91); - break; - case SKINCOLOR_DARKORANGE: - blendcolor = V_GetColor(95); - break; - case SKINCOLOR_GOLDENBROWN: - blendcolor = V_GetColor(119); - break; - case SKINCOLOR_ROSEWOOD: - blendcolor = V_GetColor(155); - break; - case SKINCOLOR_DARKROSEWOOD: - blendcolor = V_GetColor(159); - break; - case SKINCOLOR_SEPIA: - blendcolor = V_GetColor(37); - break; - case SKINCOLOR_BEIGE: - blendcolor = V_GetColor(39); - break; - case SKINCOLOR_BROWN: - blendcolor = V_GetColor(55); - break; - case SKINCOLOR_LEATHER: - blendcolor = V_GetColor(61); - break; - case SKINCOLOR_YELLOW: - blendcolor = V_GetColor(104); - break; - case SKINCOLOR_PEACH: - blendcolor = V_GetColor(71); - break; - case SKINCOLOR_LIGHTORANGE: - blendcolor = V_GetColor(83); - break; - case SKINCOLOR_CARAMEL: - blendcolor = V_GetColor(79); - break; - case SKINCOLOR_GOLD: - blendcolor = V_GetColor(115); - break; - case SKINCOLOR_SHINYCARAMEL: - blendcolor = V_GetColor(78); - break; - case SKINCOLOR_VOMIT: - blendcolor = V_GetColor(114); - break; - case SKINCOLOR_GARDEN: - blendcolor = V_GetColor(179); - break; - case SKINCOLOR_LIGHTARMY: - blendcolor = V_GetColor(177); - break; - case SKINCOLOR_ARMY: - blendcolor = V_GetColor(179); - break; - case SKINCOLOR_PISTACHIO: - blendcolor = V_GetColor(166); - break; - case SKINCOLOR_ROBOHOOD: - blendcolor = V_GetColor(182); - break; - case SKINCOLOR_OLIVE: - blendcolor = V_GetColor(108); - break; - case SKINCOLOR_DARKARMY: - blendcolor = V_GetColor(183); - break; - case SKINCOLOR_LIGHTGREEN: - blendcolor = V_GetColor(163); - break; - case SKINCOLOR_UGLYGREEN: - blendcolor = V_GetColor(185); - break; - case SKINCOLOR_NEONGREEN: - blendcolor = V_GetColor(187); - break; - case SKINCOLOR_GREEN: - blendcolor = V_GetColor(167); - break; - case SKINCOLOR_DARKGREEN: - blendcolor = V_GetColor(171); - break; - case SKINCOLOR_SWAMP: - blendcolor = V_GetColor(190); - break; - case SKINCOLOR_FROST: - blendcolor = V_GetColor(215); - break; - case SKINCOLOR_SLATE: - blendcolor = V_GetColor(201); - break; - case SKINCOLOR_LIGHTBLUE: - blendcolor = V_GetColor(227); - break; - case SKINCOLOR_CYAN: - blendcolor = V_GetColor(213); - break; - case SKINCOLOR_CERULEAN: - blendcolor = V_GetColor(217); - break; - case SKINCOLOR_TURQUOISE: - blendcolor = V_GetColor(220); - break; - case SKINCOLOR_TEAL: - blendcolor = V_GetColor(221); - break; - case SKINCOLOR_STEELBLUE: - blendcolor = V_GetColor(203); - break; - case SKINCOLOR_BLUE: - blendcolor = V_GetColor(231); - break; - case SKINCOLOR_SHINYBLUE: - blendcolor = V_GetColor(234); - break; - case SKINCOLOR_NAVY: - blendcolor = V_GetColor(206); - break; - case SKINCOLOR_DARKBLUE: - blendcolor = V_GetColor(238); - break; - case SKINCOLOR_JETBLACK: - blendcolor = V_GetColor(207); - break; - case SKINCOLOR_LILAC: - blendcolor = V_GetColor(123); - break; - case SKINCOLOR_PURPLE: - blendcolor = V_GetColor(195); - break; - case SKINCOLOR_LAVENDER: - blendcolor = V_GetColor(251); - break; - case SKINCOLOR_BYZANTIUM: - blendcolor = V_GetColor(254); - break; - case SKINCOLOR_INDIGO: - blendcolor = V_GetColor(199); - break; + UINT16 r, g, b; + UINT8 div = 0; - case SKINCOLOR_SUPER1: - blendcolor = V_GetColor(97); - break; - case SKINCOLOR_SUPER2: - blendcolor = V_GetColor(100); - break; - case SKINCOLOR_SUPER3: - blendcolor = V_GetColor(103); - break; - case SKINCOLOR_SUPER4: - blendcolor = V_GetColor(113); - break; - case SKINCOLOR_SUPER5: - blendcolor = V_GetColor(116); - break; + blendcolor = V_GetColor(colortranslations[color][0]); + r = (UINT16)blendcolor.s.red; + g = (UINT16)blendcolor.s.green; + b = (UINT16)blendcolor.s.blue; - case SKINCOLOR_TSUPER1: - blendcolor = V_GetColor(81); - break; - case SKINCOLOR_TSUPER2: - blendcolor = V_GetColor(82); - break; - case SKINCOLOR_TSUPER3: - blendcolor = V_GetColor(84); - break; - case SKINCOLOR_TSUPER4: - blendcolor = V_GetColor(85); - break; - case SKINCOLOR_TSUPER5: - blendcolor = V_GetColor(87); - break; + for (i = 1; i < 16; i++) + { + RGBA_t nextcolor = V_GetColor(colortranslations[color][i]); + UINT8 mul = 1; + // Weight these shades more. Indices 1-9 weren't randomly picked, they are commonly used on sprites and are generally what the colors "look" like + if (i >= 1 && i <= 9) + mul++; + // The mid & dark tons on the minimap icons get weighted even harder + if (i == 4 || i == 6) + mul += 2; + // And the shade between them, why not + if (i == 5) + mul++; + r += (UINT16)(nextcolor.s.red)*mul; + g += (UINT16)(nextcolor.s.green)*mul; + b += (UINT16)(nextcolor.s.blue)*mul; + div += mul; + } - case SKINCOLOR_KSUPER1: - blendcolor = V_GetColor(122); - break; - case SKINCOLOR_KSUPER2: - blendcolor = V_GetColor(123); - break; - case SKINCOLOR_KSUPER3: - blendcolor = V_GetColor(124); - break; - case SKINCOLOR_KSUPER4: - blendcolor = V_GetColor(125); - break; - case SKINCOLOR_KSUPER5: - blendcolor = V_GetColor(126); - break; - default: - blendcolor = V_GetColor(247); - break; + // This shouldn't happen. + if (div < 1) + div = 1; + + blendcolor.s.red = (UINT8)(r/div); + blendcolor.s.green = (UINT8)(g/div); + blendcolor.s.blue = (UINT8)(b/div); } - // starman support, could theoretically support boss ones too - if (skinnum == TC_STARMAN) + // rainbow support, could theoretically support boss ones too + if (skinnum == TC_RAINBOW) { while (size--) { @@ -1228,13 +1024,13 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, colorbright = (blendcolor.s.red+blendcolor.s.green+blendcolor.s.blue)/3; tempcolor = (finalbright*blendcolor.s.red)/colorbright; - tempcolor = min(255, max(0, tempcolor)); + tempcolor = min(255, tempcolor); cur->s.red = (UINT8)tempcolor; tempcolor = (finalbright*blendcolor.s.green)/colorbright; - tempcolor = min(255, max(0, tempcolor)); + tempcolor = min(255, tempcolor); cur->s.green = (UINT8)tempcolor; tempcolor = (finalbright*blendcolor.s.blue)/colorbright; - tempcolor = min(255, max(0, tempcolor)); + tempcolor = min(255, tempcolor); cur->s.blue = (UINT8)tempcolor; cur->s.alpha = image->s.alpha; } @@ -1490,7 +1286,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { if (spr->mobj->colorized) - skinnum = TC_STARMAN; + skinnum = TC_RAINBOW; else { skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 135cedfc..6114748b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1846,23 +1846,6 @@ static void HU_DrawCEcho(void) --cechotimer; } -static void HU_drawGametype(void) -{ - INT32 i = 0; - - for (i = 0; gametype_cons_t[i].strvalue; i++) - { - if (gametype_cons_t[i].value == gametype) - { - if (splitscreen) - V_DrawString(4, 184, 0, gametype_cons_t[i].strvalue); - else - V_DrawString(4, 192, 0, gametype_cons_t[i].strvalue); - return; - } - } -} - // // demo info stuff // @@ -1950,7 +1933,7 @@ void HU_Drawer(void) || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND - || gamestate == GS_VOTING) // SRB2kart + || gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS) // SRB2kart return; // draw multiplayer rankings @@ -2119,19 +2102,25 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) // // HU_DrawTabRankings // -void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer) +void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol) { - INT32 i; + INT32 i, j, rightoffset = 240; const UINT8 *colormap; //this function is designed for 9 or less score lines only I_Assert(scorelines <= 9); - V_DrawFill(1, 26, 318, 1, 0); //Draw a horizontal line because it looks nice! + V_DrawFill(1, 26, 318, 1, 0); // Draw a horizontal line because it looks nice! + if (scorelines > 9) + { + V_DrawFill(160, 26, 1, 154, 0); // Draw a vertical line to separate the two sides. + V_DrawFill(1, 180, 318, 1, 0); // And a horizontal line near the bottom. + rightoffset = 156; + } for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator) + if (players[tab[i].num].spectator || !players[tab[i].num].mo) continue; //ignore them. if (!splitscreen) // don't draw it on splitscreen, @@ -2141,94 +2130,70 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } V_DrawString(x + 20, y, - ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_60TRANS) - | V_ALLOWLOWERCASE, tab[i].name); + ((tab[i].num == whiteplayer) + ? hilicol|V_ALLOWLOWERCASE + : V_ALLOWLOWERCASE), + tab[i].name); - // Draw emeralds - if (!players[tab[i].num].powers[pw_super] - || ((leveltime/7) & 1)) + if (players[tab[i].num].mo->color) { - HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); - } - - if (players[tab[i].num].health <= 0) - V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, livesback); - else - V_DrawSmallScaledPatch (x, y-4, 0, livesback); - - if (tab[i].color == 0) - { - colormap = colormaps; - if (players[tab[i].num].powers[pw_super]) - V_DrawSmallScaledPatch(x, y-4, 0, superprefix[players[tab[i].num].skin]); + colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE); + if (players[tab[i].num].mo->colorized) + colormap = R_GetTranslationColormap(TC_RAINBOW, players[tab[i].num].mo->color, GTC_CACHE); else + colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE); + + V_DrawSmallMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); + if (G_BattleGametype() && players[tab[i].num].kartstuff[k_bumper] > 0) { - if (players[tab[i].num].health <= 0) - V_DrawSmallTranslucentPatch(x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]); - else - V_DrawSmallScaledPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin]); - } - } - else - { - if (players[tab[i].num].powers[pw_super]) - { - colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); - } - else - { - colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) - V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); - else - V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); + INT32 bumperx = x-5; + for (j = 0; j < players[tab[i].num].kartstuff[k_bumper]; j++) + { + bumperx -= 3; + V_DrawSmallMappedPatch(bumperx, y+6, 0, W_CachePatchName("K_BLNICO", PU_CACHE), colormap); + } } } - if (G_GametypeUsesLives()) //show lives - V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives)); - else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) - { - if (players[tab[i].num].health <= 0) - V_DrawSmallTranslucentPatch(x-32, y-4, V_60TRANS, tagico); - else - V_DrawSmallScaledPatch(x-32, y-4, 0, tagico); - } + if (G_BattleGametype() && players[tab[i].num].kartstuff[k_bumper] <= 0) + V_DrawSmallScaledPatch(x-2, y-4, 0, W_CachePatchName("K_NOBLNS", PU_CACHE)); if (G_RaceGametype()) { - if (circuitmap) +#define timestring(time) va("%i:%02i.%02i", G_TicsToMinutes(time, true), G_TicsToSeconds(time), G_TicsToCentiseconds(time)) + if (players[tab[i].num].exiting) { - if (players[tab[i].num].exiting) - V_DrawRightAlignedString(x+240, y, V_YELLOWMAP, va("%d:%02d.%02d", - players[tab[i].num].realtime/(60*TICRATE), - players[tab[i].num].realtime/TICRATE % 60, - players[tab[i].num].realtime % TICRATE)); - //V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); - else - V_DrawRightAlignedString(x+240, y, 0, va("(CP%02d) %d:%02d.%02d", - tab[i].count, - players[tab[i].num].starposttime/(60*TICRATE), - players[tab[i].num].starposttime/TICRATE % 60, - (int)((players[tab[i].num].starposttime % TICRATE) * (100.00f/TICRATE)))); - //V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x, y-4, hilicol, "FIN"); + V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime)); + } + else if (players[tab[i].num].pflags & PF_TIMEOVER) + V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "TIME OVER..."); + else if (circuitmap) + { + V_DrawRightAlignedString(x, y-4, 0, "Lap"); + V_DrawRightAlignedString(x, y+4, 0, va("%d", tab[i].count)); + V_DrawRightAlignedString(x+rightoffset, y, 0, timestring(players[tab[i].num].starposttime)); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedString(x+rightoffset, y, 0, timestring(tab[i].count)); +#undef timestring } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+rightoffset, y, 0, va("%u", tab[i].count)); y += 16; + if (i == 9) + { + y = 32; + x += BASEVIDWIDTH/2; + } } } // // HU_DrawTeamTabRankings // -void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) +/*void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) { INT32 i,x,y; INT32 redplayers = 0, blueplayers = 0; @@ -2396,7 +2361,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline x += BASEVIDWIDTH/2; } } -} +}*/ // // HU_DrawEmeralds @@ -2492,12 +2457,22 @@ static void HU_DrawRankings(void) { patch_t *p; playersort_t tab[MAXPLAYERS]; - INT32 i, j, scorelines; + INT32 i, j, scorelines, hilicol, numplayersingame = 0; boolean completed[MAXPLAYERS]; - UINT32 whiteplayer; + UINT32 whiteplayer = MAXPLAYERS; + + if (cons_menuhighlight.value) + hilicol = cons_menuhighlight.value; + else if (modeattacking) + hilicol = V_ORANGEMAP; + else + hilicol = ((gametype == GT_RACE) ? V_SKYMAP : V_REDMAP); // draw the current gametype in the lower right - HU_drawGametype(); + if (modeattacking) + V_DrawString(4, 188, hilicol, "Record Attack"); + else + V_DrawString(4, 188, hilicol, gametype_cons_t[gametype].strvalue); if (G_GametypeHasTeams()) { @@ -2522,29 +2497,32 @@ static void HU_DrawRankings(void) { if (cv_timelimit.value && timelimitintics > 0) { - INT32 timeval = (timelimitintics+1-leveltime)/TICRATE; + UINT32 timeval = (timelimitintics + starttime + 1 - leveltime); + if (timeval > timelimitintics+1) + timeval = timelimitintics; + timeval /= TICRATE; - if (leveltime <= timelimitintics) + if (leveltime <= (timelimitintics + starttime)) { V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, va("%u", timeval)); + V_DrawCenteredString(64, 16, hilicol, va("%u", timeval)); } // overtime - if ((leveltime > (timelimitintics + TICRATE/2)) && cv_overtime.value) + if (!players[consoleplayer].exiting && (leveltime > (timelimitintics + starttime + TICRATE/2)) && cv_overtime.value) { V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, "OVERTIME"); + V_DrawCenteredString(64, 16, hilicol, "OVERTIME"); } } if (cv_pointlimit.value > 0) { V_DrawCenteredString(256, 8, 0, "POINT LIMIT"); - V_DrawCenteredString(256, 16, 0, va("%d", cv_pointlimit.value)); + V_DrawCenteredString(256, 16, hilicol, va("%d", cv_pointlimit.value)); } } - else if (gametype == GT_COOP) + /*else if (gametype == GT_COOP) { INT32 totalscore = 0; for (i = 0; i < MAXPLAYERS; i++) @@ -2555,19 +2533,23 @@ static void HU_DrawRankings(void) V_DrawCenteredString(256, 8, 0, "TOTAL SCORE"); V_DrawCenteredString(256, 16, 0, va("%u", totalscore)); - } + }*/ else { if (circuitmap) { - V_DrawCenteredString(64, 8, 0, "NUMBER OF LAPS"); - V_DrawCenteredString(64, 16, 0, va("%d", cv_numlaps.value)); + V_DrawCenteredString(64, 8, 0, "LAP COUNT"); + V_DrawCenteredString(64, 16, hilicol, va("%d", cv_numlaps.value)); } + + V_DrawCenteredString(256, 8, 0, "GAME SPEED"); + V_DrawCenteredString(256, 16, hilicol, cv_kartspeed.string); } // When you play, you quickly see your score because your name is displayed in white. // When playing back a demo, you quickly see who's the view. - whiteplayer = demoplayback ? displayplayer : consoleplayer; + if (!splitscreen) + whiteplayer = demoplayback ? displayplayer : consoleplayer; scorelines = 0; memset(completed, 0, sizeof (completed)); @@ -2576,83 +2558,61 @@ static void HU_DrawRankings(void) for (i = 0; i < MAXPLAYERS; i++) { tab[i].num = -1; - tab[i].name = 0; + tab[i].name = NULL; + tab[i].count = INT32_MAX; - if (G_RaceGametype() && !circuitmap) - tab[i].count = INT32_MAX; - } - - for (j = 0; j < MAXPLAYERS; j++) - { - if (!playeringame[j] || players[j].spectator) + if (!playeringame[i] || players[i].spectator) continue; + numplayersingame++; + } + + if (netgame && numplayersingame <= 1) + K_drawKartFreePlay(leveltime); + + for (j = 0; j < numplayersingame; j++) + { + UINT8 lowestposition = MAXPLAYERS; for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator) - { - if (G_RaceGametype()) - { - if (circuitmap) - { - if ((unsigned)players[i].laps+1 >= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].laps+1; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - } - } - else - { - if (players[i].realtime <= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].realtime; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - } - } - } - else if (gametype == GT_COMPETITION) - { - // todo put something more fitting for the gametype here, such as current - // number of categories led - if (players[i].score >= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].score; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - tab[scorelines].emeralds = players[i].powers[pw_emeralds]; - } - } - else - { - if (players[i].score >= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].score; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - tab[scorelines].emeralds = players[i].powers[pw_emeralds]; - } - } - } + if (!playeringame[i] || players[i].spectator || completed[i]) + continue; + + if (players[i].kartstuff[k_position] >= lowestposition) + continue; + + tab[scorelines].num = i; + lowestposition = players[i].kartstuff[k_position]; } - completed[tab[scorelines].num] = true; + + i = tab[scorelines].num; + + completed[i] = true; + + tab[scorelines].name = player_names[i]; + + if (G_RaceGametype()) + { + if (circuitmap) + tab[scorelines].count = players[i].laps+1; + else + tab[scorelines].count = players[i].realtime; + } + else + tab[scorelines].count = players[i].marescore; + scorelines++; } if (scorelines > 20) scorelines = 20; //dont draw past bottom of screen, show the best only - if (G_GametypeHasTeams()) - HU_DrawTeamTabRankings(tab, whiteplayer); //separate function for Spazzo's silly request - else if (scorelines <= 9) - HU_DrawTabRankings(40, 32, tab, scorelines, whiteplayer); - else - HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer); + /*if (G_GametypeHasTeams()) + HU_DrawTeamTabRankings(tab, whiteplayer); //separate function for Spazzo's silly request -- gotta fix this up later + else if (scorelines > 10)*/ + HU_DrawTabRankings(((scorelines > 9) ? 32 : 40), 32, tab, scorelines, whiteplayer, hilicol); + /*else + HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer);*/ // draw spectators in a ticker across the bottom if (!splitscreen && G_GametypeHasSpectators()) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 2a99be4b..b4a78338 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -21,7 +21,7 @@ //------------------------------------ // heads up font //------------------------------------ -#define HU_FONTSTART '\x1E' // the first font character +#define HU_FONTSTART '\x19' // the first font character #define HU_FONTEND '~' #define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1) @@ -55,8 +55,6 @@ typedef struct { UINT32 count; INT32 num; - INT32 color; - INT32 emeralds; const char *name; } playersort_t; @@ -100,7 +98,7 @@ void HU_Init(void); void HU_LoadGraphics(void); // reset heads up when consoleplayer respawns. -FUNCMATH void HU_Start(void); +void HU_Start(void); boolean HU_Responder(event_t *ev); @@ -109,10 +107,12 @@ void HU_Drawer(void); char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); -void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard. void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer); void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); +void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol); +//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer); +//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds); INT32 HU_CreateTeamScoresTbl(playersort_t *tab, UINT32 dmtotals[]); diff --git a/src/i_addrinfo.c b/src/i_addrinfo.c index eb29e360..4dafd8f8 100644 --- a/src/i_addrinfo.c +++ b/src/i_addrinfo.c @@ -86,10 +86,10 @@ static HMODULE WS_getfunctions(HMODULE tmp) { if (tmp != NULL) { - WS_getaddrinfo = (p_getaddrinfo)GetProcAddress(tmp, "getaddrinfo"); + WS_getaddrinfo = (p_getaddrinfo)((void *)GetProcAddress(tmp, "getaddrinfo")); if (WS_getaddrinfo == NULL) return NULL; - WS_freeaddrinfo = (p_freeaddrinfo)GetProcAddress(tmp, "freeaddrinfo"); + WS_freeaddrinfo = (p_freeaddrinfo)((void *)GetProcAddress(tmp, "freeaddrinfo")); if (WS_freeaddrinfo == NULL) { WS_getaddrinfo = NULL; diff --git a/src/i_joy.h b/src/i_joy.h index 316011fc..00302eb0 100644 --- a/src/i_joy.h +++ b/src/i_joy.h @@ -50,7 +50,7 @@ struct JoyType_s }; typedef struct JoyType_s JoyType_t; /** \brief Joystick info - for palyer 1 and 2's joystick/gamepad + for palyer[sic] 1-4's joystick/gamepad */ extern JoyType_t Joystick, Joystick2, Joystick3, Joystick4; diff --git a/src/info.c b/src/info.c index 27383773..41e89ae6 100644 --- a/src/info.c +++ b/src/info.c @@ -55,11 +55,11 @@ char sprnames[NUMSPRITES + 1][5] = "GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI", "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", //SRB2kart Sprites - "SPRG","BSPR","RNDM","RPOP","KFRE","DRIF","DUST","FITM","DFAK","BANA", - "DBAN","GSHE","DGSH","RSHE","DRSH","BOMB","KRBM","BLIG","LIGH","SINK", - "SITR","KBLN","LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS", - "BUZB","CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW","ARRO", - "PBOM" + "SPRG","BSPR","RNDM","RPOP","KFRE","KINV","KINF","WIPD","DRIF","DUST", + "FITM","BANA","ORBN","JAWZ","SSMN","KRBM","BHOG","BHBM","BLIG","LIGH", + "SINK","SITR","KBLN","DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS", + "SPRS","BUZB","CHOM","SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS", + "PSHW","ISTA","ISTB","ARRO","ITEM","ITMI","ITMN","WANT","PBOM","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2125,19 +2125,13 @@ state_t states[NUMSTATES] = {SPR_FFWR, 3, 3, {NULL}, 0, 0, S_FIREFLOWER1}, // S_FIREFLOWER4 // Thrown Mario Fireball - {SPR_FBLL, FF_FULLBRIGHT, 3, {NULL}, MT_FIRETRAIL, 0, S_FIREBALL2}, // S_FIREBALL1 - {SPR_FBLL, FF_FULLBRIGHT|1, 3, {NULL}, MT_FIRETRAIL, 0, S_FIREBALL3}, // S_FIREBALL2 - {SPR_FBLL, FF_FULLBRIGHT|2, 3, {NULL}, MT_FIRETRAIL, 0, S_FIREBALL4}, // S_FIREBALL3 - {SPR_FBLL, FF_FULLBRIGHT|3, 3, {NULL}, MT_FIRETRAIL, 0, S_FIREBALL5}, // S_FIREBALL4 - {SPR_FBLL, FF_FULLBRIGHT|4, 3, {NULL}, MT_FIRETRAIL, 0, S_FIREBALL6}, // S_FIREBALL5 - {SPR_FBLL, FF_FULLBRIGHT|5, 3, {NULL}, MT_FIRETRAIL, 0, S_FIREBALL7}, // S_FIREBALL6 - {SPR_FBLL, FF_FULLBRIGHT|6, 3, {NULL}, MT_FIRETRAIL, 0, S_FIREBALL1}, // S_FIREBALL7 - {SPR_FBLL, FF_FULLBRIGHT|7, 3, {NULL}, 0, 0, S_FIREBALLEXP2}, // S_FIREBALLEXP1 - {SPR_FBLL, FF_FULLBRIGHT|8, 3, {NULL}, 0, 0, S_FIREBALLEXP3}, // S_FIREBALLEXP2 - {SPR_FBLL, FF_FULLBRIGHT|9, 3, {NULL}, 0, 0, S_FIREBALLEXP4}, // S_FIREBALLEXP3 - {SPR_FBLL, FF_FULLBRIGHT|10, 3, {NULL}, 0, 0, S_FIREBALLEXP5}, // S_FIREBALLEXP4 - {SPR_FBLL, FF_FULLBRIGHT|11, 3, {NULL}, 0, 0, S_FIREBALLEXP6}, // S_FIREBALLEXP5 - {SPR_FBLL, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_NULL}, // S_FIREBALLEXP6 + {SPR_FBLL, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FIREBALL2}, // S_FIREBALL1 + {SPR_FBLL, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_FIREBALL3}, // S_FIREBALL2 + {SPR_FBLL, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_FIREBALL4}, // S_FIREBALL3 + {SPR_FBLL, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_FIREBALL1}, // S_FIREBALL4 + {SPR_FBLL, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_FIREBALLEXP2}, // S_FIREBALLEXP1 + {SPR_FBLL, FF_FULLBRIGHT|5, 3, {NULL}, 0, 0, S_FIREBALLEXP3}, // S_FIREBALLEXP2 + {SPR_FBLL, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_FIREBALLEXP3 // Turtle Shell {SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHELL @@ -2540,43 +2534,43 @@ state_t states[NUMSTATES] = {SPR_BSPR, 2, 1, {NULL}, 0, 0, S_BDIAG8}, // S_BDIAG7 {SPR_BSPR, 1, 1, {NULL}, 0, 0, S_BDIAG1}, // S_BDIAG8 - {SPR_RNDM, 0, 3, {NULL}, 0, 0, S_RANDOMITEM2}, // S_RANDOMITEM1 - {SPR_RNDM, 1, 3, {NULL}, 0, 0, S_RANDOMITEM3}, // S_RANDOMITEM2 - {SPR_RNDM, 2, 3, {NULL}, 0, 0, S_RANDOMITEM4}, // S_RANDOMITEM3 - {SPR_RNDM, 3, 3, {NULL}, 0, 0, S_RANDOMITEM5}, // S_RANDOMITEM4 - {SPR_RNDM, 4, 3, {NULL}, 0, 0, S_RANDOMITEM6}, // S_RANDOMITEM5 - {SPR_RNDM, 5, 3, {NULL}, 0, 0, S_RANDOMITEM7}, // S_RANDOMITEM6 - {SPR_RNDM, 6, 3, {NULL}, 0, 0, S_RANDOMITEM8}, // S_RANDOMITEM7 - {SPR_RNDM, 7, 3, {NULL}, 0, 0, S_RANDOMITEM9}, // S_RANDOMITEM8 - {SPR_RNDM, 8, 3, {NULL}, 0, 0, S_RANDOMITEM10}, // S_RANDOMITEM9 - {SPR_RNDM, 9, 3, {NULL}, 0, 0, S_RANDOMITEM11}, // S_RANDOMITEM10 - {SPR_RNDM, 10, 3, {NULL}, 0, 0, S_RANDOMITEM12}, // S_RANDOMITEM11 - {SPR_RNDM, 11, 3, {NULL}, 0, 0, S_RANDOMITEM13}, // S_RANDOMITEM12 - {SPR_RNDM, 12, 3, {NULL}, 0, 0, S_RANDOMITEM14}, // S_RANDOMITEM13 - {SPR_RNDM, 13, 3, {NULL}, 0, 0, S_RANDOMITEM15}, // S_RANDOMITEM14 - {SPR_RNDM, 14, 3, {NULL}, 0, 0, S_RANDOMITEM16}, // S_RANDOMITEM15 - {SPR_RNDM, 15, 3, {NULL}, 0, 0, S_RANDOMITEM17}, // S_RANDOMITEM16 - {SPR_RNDM, 16, 3, {NULL}, 0, 0, S_RANDOMITEM18}, // S_RANDOMITEM17 - {SPR_RNDM, 17, 3, {NULL}, 0, 0, S_RANDOMITEM19}, // S_RANDOMITEM18 - {SPR_RNDM, 18, 3, {NULL}, 0, 0, S_RANDOMITEM20}, // S_RANDOMITEM19 - {SPR_RNDM, 19, 3, {NULL}, 0, 0, S_RANDOMITEM21}, // S_RANDOMITEM20 - {SPR_RNDM, 20, 3, {NULL}, 0, 0, S_RANDOMITEM22}, // S_RANDOMITEM21 - {SPR_RNDM, 21, 3, {NULL}, 0, 0, S_RANDOMITEM23}, // S_RANDOMITEM22 - {SPR_RNDM, 22, 3, {NULL}, 0, 0, S_RANDOMITEM24}, // S_RANDOMITEM23 - {SPR_RNDM, 23, 3, {NULL}, 0, 0, S_RANDOMITEM1}, // S_RANDOMITEM24 - {SPR_RNDM, 0, 1, {A_ItemPop}, 0, 0, S_NULL}, // S_DEADRANDOMITEM + {SPR_RNDM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM2}, // S_RANDOMITEM1 + {SPR_RNDM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM3}, // S_RANDOMITEM2 + {SPR_RNDM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM4}, // S_RANDOMITEM3 + {SPR_RNDM, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM5}, // S_RANDOMITEM4 + {SPR_RNDM, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM6}, // S_RANDOMITEM5 + {SPR_RNDM, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM7}, // S_RANDOMITEM6 + {SPR_RNDM, 6|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM8}, // S_RANDOMITEM7 + {SPR_RNDM, 7|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM9}, // S_RANDOMITEM8 + {SPR_RNDM, 8|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM10}, // S_RANDOMITEM9 + {SPR_RNDM, 9|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM11}, // S_RANDOMITEM10 + {SPR_RNDM, 10|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM12}, // S_RANDOMITEM11 + {SPR_RNDM, 11|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM13}, // S_RANDOMITEM12 + {SPR_RNDM, 12|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM14}, // S_RANDOMITEM13 + {SPR_RNDM, 13|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM15}, // S_RANDOMITEM14 + {SPR_RNDM, 14|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM16}, // S_RANDOMITEM15 + {SPR_RNDM, 15|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM17}, // S_RANDOMITEM16 + {SPR_RNDM, 16|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM18}, // S_RANDOMITEM17 + {SPR_RNDM, 17|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM19}, // S_RANDOMITEM18 + {SPR_RNDM, 18|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM20}, // S_RANDOMITEM19 + {SPR_RNDM, 19|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM21}, // S_RANDOMITEM20 + {SPR_RNDM, 20|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM22}, // S_RANDOMITEM21 + {SPR_RNDM, 21|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM23}, // S_RANDOMITEM22 + {SPR_RNDM, 22|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM24}, // S_RANDOMITEM23 + {SPR_RNDM, 23|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM1}, // S_RANDOMITEM24 + {SPR_RNDM, 0|FF_FULLBRIGHT, 1, {A_ItemPop}, 0, 0, S_NULL}, // S_DEADRANDOMITEM {SPR_RPOP, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_RANDOMITEMPOP2}, // S_RANDOMITEMPOP1 {SPR_RPOP, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_RANDOMITEMPOP3}, // S_RANDOMITEMPOP2 {SPR_RPOP, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_RANDOMITEMPOP4}, // S_RANDOMITEMPOP3 {SPR_RPOP, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_NULL}, // S_RANDOMITEMPOP4 - {SPR_DRIF, 0, 2, {NULL}, 0, 0, S_DRIFTSPARK2}, // S_DRIFTSPARK1 - {SPR_DRIF, 1, 2, {NULL}, 0, 0, S_DRIFTSPARK3}, // S_DRIFTSPARK2 - {SPR_DRIF, 2, 2, {NULL}, 0, 0, S_DRIFTSPARK1}, // S_DRIFTSPARK3 - {SPR_DRIF, 3, 2, {NULL}, 0, 0, S_DRIFTSPARK5}, // S_DRIFTSPARK4 - {SPR_DRIF, 4, 2, {NULL}, 0, 0, S_DRIFTSPARK6}, // S_DRIFTSPARK5 - {SPR_DRIF, 5, 2, {NULL}, 0, 0, S_DRIFTSPARK4}, // S_DRIFTSPARK6 + {SPR_DRIF, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK2}, // S_DRIFTSPARK1 + {SPR_DRIF, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK3}, // S_DRIFTSPARK2 + {SPR_DRIF, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK1}, // S_DRIFTSPARK3 + {SPR_DRIF, 3|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK5}, // S_DRIFTSPARK4 + {SPR_DRIF, 4|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK6}, // S_DRIFTSPARK5 + {SPR_DRIF, 5|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK4}, // S_DRIFTSPARK6 {SPR_DUST, 0, 3, {NULL}, 0, 0, S_DRIFTDUST2}, // S_DRIFTDUST1 {SPR_DUST, 1, 3, {NULL}, 0, 0, S_DRIFTDUST3}, // S_DRIFTDUST2 @@ -2592,131 +2586,176 @@ state_t states[NUMSTATES] = {SPR_KFRE, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_KARTFIRE8}, // S_KARTFIRE7 {SPR_KFRE, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_NULL}, // S_KARTFIRE8 - {SPR_FITM, 0, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 - {SPR_FITM, 1, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2 - {SPR_FITM, 2, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3 - {SPR_FITM, 3, 3, {NULL}, 0, 0, S_FAKEITEM5}, // S_FAKEITEM4 - {SPR_FITM, 4, 3, {NULL}, 0, 0, S_FAKEITEM6}, // S_FAKEITEM5 - {SPR_FITM, 5, 3, {NULL}, 0, 0, S_FAKEITEM7}, // S_FAKEITEM6 - {SPR_FITM, 6, 3, {NULL}, 0, 0, S_FAKEITEM8}, // S_FAKEITEM7 - {SPR_FITM, 7, 3, {NULL}, 0, 0, S_FAKEITEM9}, // S_FAKEITEM8 - {SPR_FITM, 8, 3, {NULL}, 0, 0, S_FAKEITEM10}, // S_FAKEITEM9 - {SPR_FITM, 9, 3, {NULL}, 0, 0, S_FAKEITEM11}, // S_FAKEITEM10 - {SPR_FITM, 10, 3, {NULL}, 0, 0, S_FAKEITEM12}, // S_FAKEITEM11 - {SPR_FITM, 11, 3, {NULL}, 0, 0, S_FAKEITEM13}, // S_FAKEITEM12 - {SPR_FITM, 12, 3, {NULL}, 0, 0, S_FAKEITEM14}, // S_FAKEITEM13 - {SPR_FITM, 13, 3, {NULL}, 0, 0, S_FAKEITEM15}, // S_FAKEITEM14 - {SPR_FITM, 14, 3, {NULL}, 0, 0, S_FAKEITEM16}, // S_FAKEITEM15 - {SPR_FITM, 15, 3, {NULL}, 0, 0, S_FAKEITEM17}, // S_FAKEITEM16 - {SPR_FITM, 16, 3, {NULL}, 0, 0, S_FAKEITEM18}, // S_FAKEITEM17 - {SPR_FITM, 17, 3, {NULL}, 0, 0, S_FAKEITEM19}, // S_FAKEITEM18 - {SPR_FITM, 18, 3, {NULL}, 0, 0, S_FAKEITEM20}, // S_FAKEITEM19 - {SPR_FITM, 19, 3, {NULL}, 0, 0, S_FAKEITEM21}, // S_FAKEITEM20 - {SPR_FITM, 20, 3, {NULL}, 0, 0, S_FAKEITEM22}, // S_FAKEITEM21 - {SPR_FITM, 21, 3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22 // ***** - {SPR_FITM, 22, 3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23 // ***** - {SPR_FITM, 23, 3, {NULL}, 0, 0, S_FAKEITEM1}, // S_FAKEITEM24 // ***** - {SPR_DFAK, 0, 175, {NULL}, 0, 0, S_FAKEITEM1}, // S_DEADFAKEITEM + {SPR_KINV, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL2}, // S_KARTINVULN_SMALL1 + {SPR_KINV, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL3}, // S_KARTINVULN_SMALL2 + {SPR_KINV, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL4}, // S_KARTINVULN_SMALL3 + {SPR_KINV, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL5}, // S_KARTINVULN_SMALL4 + {SPR_KINV, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_NULL}, // S_KARTINVULN_SMALL5 - {SPR_BANA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BANANAITEM - {SPR_DBAN, 0, 175, {NULL}, 0, 0, S_NULL}, // S_DEADBANANA + {SPR_KINV, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE2}, // S_KARTINVULN_LARGE1 + {SPR_KINV, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE3}, // S_KARTINVULN_LARGE2 + {SPR_KINV, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE4}, // S_KARTINVULN_LARGE3 + {SPR_KINV, FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE5}, // S_KARTINVULN_LARGE4 + {SPR_KINV, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_NULL}, // S_KARTINVULN_LARGE5 - {SPR_GSHE, 0, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD2}, // S_TRIPLEGREENSHIELD1 - {SPR_GSHE, 1, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD3}, // S_TRIPLEGREENSHIELD2 - {SPR_GSHE, 2, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD4}, // S_TRIPLEGREENSHIELD3 - {SPR_GSHE, 3, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD5}, // S_TRIPLEGREENSHIELD4 - {SPR_GSHE, 4, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD6}, // S_TRIPLEGREENSHIELD5 - {SPR_GSHE, 5, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD7}, // S_TRIPLEGREENSHIELD6 - {SPR_GSHE, 6, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD8}, // S_TRIPLEGREENSHIELD7 - {SPR_GSHE, 7, 1, {NULL}, 0, 0, S_TRIPLEGREENSHIELD1}, // S_TRIPLEGREENSHIELD8 - {SPR_GSHE, 0, 1, {NULL}, 0, 0, S_GREENSHIELD2}, // S_GREENSHIELD1 - {SPR_GSHE, 1, 1, {NULL}, 0, 0, S_GREENSHIELD3}, // S_GREENSHIELD2 - {SPR_GSHE, 2, 1, {NULL}, 0, 0, S_GREENSHIELD4}, // S_GREENSHIELD3 - {SPR_GSHE, 3, 1, {NULL}, 0, 0, S_GREENSHIELD5}, // S_GREENSHIELD4 - {SPR_GSHE, 4, 1, {NULL}, 0, 0, S_GREENSHIELD6}, // S_GREENSHIELD5 - {SPR_GSHE, 5, 1, {NULL}, 0, 0, S_GREENSHIELD7}, // S_GREENSHIELD6 - {SPR_GSHE, 6, 1, {NULL}, 0, 0, S_GREENSHIELD8}, // S_GREENSHIELD7 - {SPR_GSHE, 7, 1, {NULL}, 0, 0, S_GREENSHIELD1}, // S_GREENSHIELD8 - {SPR_GSHE, 0, 1, {NULL}, 0, 0, S_GREENITEM2}, // S_GREENITEM1 - {SPR_GSHE, 1, 1, {NULL}, 0, 0, S_GREENITEM3}, // S_GREENITEM2 - {SPR_GSHE, 2, 1, {NULL}, 0, 0, S_GREENITEM4}, // S_GREENITEM3 - {SPR_GSHE, 3, 1, {NULL}, 0, 0, S_GREENITEM5}, // S_GREENITEM4 - {SPR_GSHE, 4, 1, {NULL}, 0, 0, S_GREENITEM6}, // S_GREENITEM5 - {SPR_GSHE, 5, 1, {NULL}, 0, 0, S_GREENITEM7}, // S_GREENITEM6 - {SPR_GSHE, 6, 1, {NULL}, 0, 0, S_GREENITEM8}, // S_GREENITEM7 - {SPR_GSHE, 7, 1, {NULL}, 0, 0, S_GREENITEM1}, // S_GREENITEM8 - {SPR_DGSH, 0, 175, {NULL}, 0, 0, S_NULL}, // S_DEADGREEN + {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1 + {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2 + {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90|1, 1, {NULL}, 0, 0, S_INVULNFLASH4}, // S_INVULNFLASH3 + {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH1}, // S_INVULNFLASH4 - {SPR_RSHE, 0, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD2}, // S_TRIPLEREDSHIELD1 - {SPR_RSHE, 1, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD3}, // S_TRIPLEREDSHIELD2 - {SPR_RSHE, 2, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD4}, // S_TRIPLEREDSHIELD3 - {SPR_RSHE, 3, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD5}, // S_TRIPLEREDSHIELD4 - {SPR_RSHE, 4, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD6}, // S_TRIPLEREDSHIELD5 - {SPR_RSHE, 5, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD7}, // S_TRIPLEREDSHIELD6 - {SPR_RSHE, 6, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD8}, // S_TRIPLEREDSHIELD7 - {SPR_RSHE, 7, 1, {NULL}, 0, 0, S_TRIPLEREDSHIELD1}, // S_TRIPLEREDSHIELD8 - {SPR_RSHE, 0, 1, {NULL}, 0, 0, S_REDSHIELD2}, // S_REDSHIELD1 - {SPR_RSHE, 1, 1, {NULL}, 0, 0, S_REDSHIELD3}, // S_REDSHIELD2 - {SPR_RSHE, 2, 1, {NULL}, 0, 0, S_REDSHIELD4}, // S_REDSHIELD3 - {SPR_RSHE, 3, 1, {NULL}, 0, 0, S_REDSHIELD5}, // S_REDSHIELD4 - {SPR_RSHE, 4, 1, {NULL}, 0, 0, S_REDSHIELD6}, // S_REDSHIELD5 - {SPR_RSHE, 5, 1, {NULL}, 0, 0, S_REDSHIELD7}, // S_REDSHIELD6 - {SPR_RSHE, 6, 1, {NULL}, 0, 0, S_REDSHIELD8}, // S_REDSHIELD7 - {SPR_RSHE, 7, 1, {NULL}, 0, 0, S_REDSHIELD1}, // S_REDSHIELD8 - {SPR_RSHE, 0, 1, {A_RedShellChase}, 0, 0, S_REDITEM2}, // S_REDITEM1 - {SPR_RSHE, 1, 1, {A_RedShellChase}, 0, 0, S_REDITEM3}, // S_REDITEM2 - {SPR_RSHE, 2, 1, {A_RedShellChase}, 0, 0, S_REDITEM4}, // S_REDITEM3 - {SPR_RSHE, 3, 1, {A_RedShellChase}, 0, 0, S_REDITEM5}, // S_REDITEM4 - {SPR_RSHE, 4, 1, {A_RedShellChase}, 0, 0, S_REDITEM6}, // S_REDITEM5 - {SPR_RSHE, 5, 1, {A_RedShellChase}, 0, 0, S_REDITEM7}, // S_REDITEM6 - {SPR_RSHE, 6, 1, {A_RedShellChase}, 0, 0, S_REDITEM8}, // S_REDITEM7 - {SPR_RSHE, 7, 1, {A_RedShellChase}, 0, 0, S_REDITEM1}, // S_REDITEM8 - {SPR_DRSH, 0, 175, {NULL}, 0, 0, S_NULL}, // S_DEADRED + {SPR_WIPD, 0, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL2}, // S_WIPEOUTTRAIL1 + {SPR_WIPD, 1, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL3}, // S_WIPEOUTTRAIL2 + {SPR_WIPD, 2, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL4}, // S_WIPEOUTTRAIL3 + {SPR_WIPD, 3, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL5}, // S_WIPEOUTTRAIL4 + {SPR_WIPD, 4, 3, {NULL}, 0, 0, S_NULL}, // S_WIPEOUTTRAIL5 - {SPR_FBLL, 13, 3, {NULL}, 0, 0, S_FIRETRAIL2}, // S_FIRETRAIL1 - {SPR_FBLL, 14, 3, {NULL}, 0, 0, S_FIRETRAIL3}, // S_FIRETRAIL2 - {SPR_FBLL, 15, 3, {NULL}, 0, 0, S_FIRETRAIL4}, // S_FIRETRAIL3 - {SPR_FBLL, 16, 3, {NULL}, 0, 0, S_FIRETRAIL5}, // S_FIRETRAIL4 - {SPR_FBLL, 17, 3, {NULL}, 0, 0, S_FIRETRAIL6}, // S_FIRETRAIL5 - {SPR_FBLL, 18, 3, {NULL}, 0, 0, S_FIRETRAIL7}, // S_FIRETRAIL6 - {SPR_FBLL, 19, 3, {NULL}, 0, 0, S_FIRETRAIL8}, // S_FIRETRAIL7 - {SPR_FBLL, 20, 3, {NULL}, 0, 0, S_FIRETRAIL9}, // S_FIRETRAIL8 - {SPR_FBLL, 21, 3, {NULL}, 0, 0, S_NULL}, // S_FIRETRAIL9 + {SPR_FITM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 + {SPR_FITM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2 + {SPR_FITM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3 + {SPR_FITM, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM5}, // S_FAKEITEM4 + {SPR_FITM, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM6}, // S_FAKEITEM5 + {SPR_FITM, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM7}, // S_FAKEITEM6 + {SPR_FITM, 6|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM8}, // S_FAKEITEM7 + {SPR_FITM, 7|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM9}, // S_FAKEITEM8 + {SPR_FITM, 8|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM10}, // S_FAKEITEM9 + {SPR_FITM, 9|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM11}, // S_FAKEITEM10 + {SPR_FITM, 10|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM12}, // S_FAKEITEM11 + {SPR_FITM, 11|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM13}, // S_FAKEITEM12 + {SPR_FITM, 12|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM14}, // S_FAKEITEM13 + {SPR_FITM, 13|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM15}, // S_FAKEITEM14 + {SPR_FITM, 14|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM16}, // S_FAKEITEM15 + {SPR_FITM, 15|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM17}, // S_FAKEITEM16 + {SPR_FITM, 16|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM18}, // S_FAKEITEM17 + {SPR_FITM, 17|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM19}, // S_FAKEITEM18 + {SPR_FITM, 18|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM20}, // S_FAKEITEM19 + {SPR_FITM, 19|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM21}, // S_FAKEITEM20 + {SPR_FITM, 20|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM22}, // S_FAKEITEM21 + {SPR_FITM, 21|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22 // ***** + {SPR_FITM, 22|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23 // ***** + {SPR_FITM, 23|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM1}, // S_FAKEITEM24 // ***** + {SPR_FITM, 24|FF_FULLBRIGHT, 175, {NULL}, 0, 0, S_FAKEITEM1}, // S_DEADFAKEITEM - {SPR_BOMB, 0, 1, {NULL}, 0, 0, S_BOMBSHIELD}, // S_BOMBSHIELD - {SPR_BOMB, 0, 1, {A_GrenadeRing}, 0, 0, S_BOMBITEM}, // S_BOMBITEM - {SPR_BOMB, 0, 1, {NULL}, 0, 0, S_BOMBAIR}, // S_BOMBAIR - {SPR_BOMB, 0, 1, {A_BobombExplode}, MT_BOMBEXPLOSION, 0, S_NULL}, // S_BOMBEXPLODE - {SPR_NULL, 0, 6, {NULL}, 0, 0, S_BOMBEXPLOSION2}, // S_BOMBEXPLOSION1 - {SPR_NULL, 1, 22, {A_ForceStop}, 0, 0, S_NULL}, // S_BOMBEXPLOSION2 + {SPR_BANA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BANANA + {SPR_BANA, 1, 175, {NULL}, 0, 0, S_NULL}, // S_BANANA_DEAD - {SPR_KRBM, 0, 1, {NULL}, 0, 0, S_QUICKBOOM2}, // S_QUICKBOOM1 - {SPR_KRBM, 1, 1, {NULL}, 0, 0, S_QUICKBOOM3}, // S_QUICKBOOM2 - {SPR_KRBM, 2, 1, {NULL}, 0, 0, S_QUICKBOOM4}, // S_QUICKBOOM3 - {SPR_KRBM, 3, 1, {NULL}, 0, 0, S_QUICKBOOM5}, // S_QUICKBOOM4 - {SPR_KRBM, 4, 1, {NULL}, 0, 0, S_QUICKBOOM6}, // S_QUICKBOOM5 - {SPR_KRBM, 5, 1, {NULL}, 0, 0, S_QUICKBOOM7}, // S_QUICKBOOM6 - {SPR_KRBM, 6, 1, {NULL}, 0, 0, S_QUICKBOOM8}, // S_QUICKBOOM7 - {SPR_KRBM, 7, 2, {NULL}, 0, 0, S_QUICKBOOM9}, // S_QUICKBOOM8 - {SPR_KRBM, 8, 2, {NULL}, 0, 0, S_QUICKBOOM10}, // S_QUICKBOOM9 - {SPR_KRBM, 9, 2, {NULL}, 0, 0, S_NULL}, // S_QUICKBOOM10 + {SPR_ORBN, 0, 1, {NULL}, 0, 0, S_ORBINAUT2}, // S_ORBINAUT1 + {SPR_ORBN, 1, 1, {NULL}, 0, 0, S_ORBINAUT3}, // S_ORBINAUT2 + {SPR_ORBN, 2, 1, {NULL}, 0, 0, S_ORBINAUT4}, // S_ORBINAUT3 + {SPR_ORBN, 3, 1, {NULL}, 0, 0, S_ORBINAUT5}, // S_ORBINAUT4 + {SPR_ORBN, 4, 1, {NULL}, 0, 0, S_ORBINAUT6}, // S_ORBINAUT5 + {SPR_ORBN, 5, 1, {NULL}, 0, 0, S_ORBINAUT1}, // S_ORBINAUT6 + {SPR_ORBN, 7, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD}, // S_ORBINAUT_SHIELD + {SPR_ORBN, 6, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_DEAD + {SPR_ORBN, 8, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_SHIELDDEAD - {SPR_KRBM, 0, 3, {NULL}, 0, 0, S_SLOWBOOM2}, // S_SLOWBOOM1 - {SPR_KRBM, 1, 3, {NULL}, 0, 0, S_SLOWBOOM3}, // S_SLOWBOOM2 - {SPR_KRBM, 2, 3, {NULL}, 0, 0, S_SLOWBOOM4}, // S_SLOWKBOOM3 - {SPR_KRBM, 3, 3, {NULL}, 0, 0, S_SLOWBOOM5}, // S_SLOWBOOM4 - {SPR_KRBM, 4, 3, {NULL}, 0, 0, S_SLOWBOOM6}, // S_SLOWBOOM5 - {SPR_KRBM, 5, 3, {NULL}, 0, 0, S_SLOWBOOM7}, // S_SLOWBOOM6 - {SPR_KRBM, 6, 3, {NULL}, 0, 0, S_SLOWBOOM8}, // S_SLOWBOOM7 - {SPR_KRBM, 7, 5, {NULL}, 0, 0, S_SLOWBOOM9}, // S_SLOWBOOM8 - {SPR_KRBM, 8, 5, {NULL}, 0, 0, S_SLOWBOOM10}, // S_SLOWBOOM9 - {SPR_KRBM, 9, 5, {NULL}, 0, 0, S_NULL}, // S_SLOWBOOM10 + {SPR_JAWZ, 0, 1, {A_JawzChase}, 0, 0, S_JAWZ2}, // S_JAWZ1 + {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ3}, // S_JAWZ2 + {SPR_JAWZ, 1, 1, {A_JawzChase}, 0, 0, S_JAWZ4}, // S_JAWZ3 + {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ5}, // S_JAWZ4 + {SPR_JAWZ, 2, 1, {A_JawzChase}, 0, 0, S_JAWZ6}, // S_JAWZ5 + {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ7}, // S_JAWZ6 + {SPR_JAWZ, 3, 1, {A_JawzChase}, 0, 0, S_JAWZ8}, // S_JAWZ7 + {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ1}, // S_JAWZ8 + + {SPR_JAWZ, 0, 1, {NULL}, 0, 0, S_JAWZ_DUD2}, // S_JAWZ_DUD1 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD3}, // S_JAWZ_DUD2 + {SPR_JAWZ, 1, 1, {NULL}, 0, 0, S_JAWZ_DUD4}, // S_JAWZ_DUD3 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD5}, // S_JAWZ_DUD4 + {SPR_JAWZ, 2, 1, {NULL}, 0, 0, S_JAWZ_DUD6}, // S_JAWZ_DUD5 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD7}, // S_JAWZ_DUD6 + {SPR_JAWZ, 3, 1, {NULL}, 0, 0, S_JAWZ_DUD8}, // S_JAWZ_DUD7 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD1}, // S_JAWZ_DUD8 + + {SPR_JAWZ, 0, 1, {NULL}, 0, 0, S_JAWZ_SHIELD2}, // S_JAWZ_SHIELD1 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_SHIELD3}, // S_JAWZ_SHIELD2 + {SPR_JAWZ, 1, 1, {NULL}, 0, 0, S_JAWZ_SHIELD4}, // S_JAWZ_SHIELD3 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_SHIELD5}, // S_JAWZ_SHIELD4 + {SPR_JAWZ, 2, 1, {NULL}, 0, 0, S_JAWZ_SHIELD6}, // S_JAWZ_SHIELD5 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_SHIELD7}, // S_JAWZ_SHIELD6 + {SPR_JAWZ, 3, 1, {NULL}, 0, 0, S_JAWZ_SHIELD8}, // S_JAWZ_SHIELD7 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_SHIELD1}, // S_JAWZ_SHIELD8 + + {SPR_JAWZ, 5, 175, {NULL}, 0, 0, S_JAWZ_DEAD2}, // S_JAWZ_DEAD1 + {SPR_NULL, 0, 1, {A_JawzExplode}, 0, 0, S_NULL}, // S_JAWZ_DEAD2 + + {SPR_SSMN, 0, 30, {NULL}, 0, 0, S_SSMINE2}, // S_SSMINE1 + {SPR_SSMN, 3, 3, {NULL}, 0, 0, S_SSMINE3}, // S_SSMINE2 + {SPR_SSMN, 2, 3, {NULL}, 0, 0, S_SSMINE4}, // S_SSMINE3 + {SPR_SSMN, 1, 3, {NULL}, 0, 0, S_SSMINE1}, // S_SSMINE4 + {SPR_SSMN, 4, 1, {NULL}, 0, 0, S_SSMINE_SHIELD2}, // S_SSMINE_SHIELD1 + {SPR_SSMN, 5, 1, {NULL}, 0, 0, S_SSMINE_SHIELD1}, // S_SSMINE_SHIELD2 + {SPR_SSMN, 4, 1, {NULL}, 0, 0, S_SSMINE_AIR2}, // S_SSMINE_AIR1 + {SPR_SSMN, 5, 1, {NULL}, 0, 0, S_SSMINE_AIR1}, // S_SSMINE_AIR2 + {SPR_SSMN, 6, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY2}, // S_SSMINE_DEPLOY1 + {SPR_SSMN, 7, 5, {NULL}, 0, 0, S_SSMINE_DEPLOY3}, // S_SSMINE_DEPLOY2 + {SPR_SSMN, 8, 7, {NULL}, 0, 0, S_SSMINE_DEPLOY4}, // S_SSMINE_DEPLOY3 + {SPR_SSMN, 9, 1, {NULL}, 0, 0, S_SSMINE_DEPLOY5}, // S_SSMINE_DEPLOY4 + {SPR_SSMN, 10, 1, {NULL}, 0, 0, S_SSMINE_DEPLOY6}, // S_SSMINE_DEPLOY5 + {SPR_SSMN, 9, 1, {NULL}, 0, 0, S_SSMINE_DEPLOY7}, // S_SSMINE_DEPLOY6 + {SPR_SSMN, 10, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY8}, // S_SSMINE_DEPLOY7 + {SPR_SSMN, 11, 1, {A_PlaySound}, sfx_cdfm39, 1, S_SSMINE_DEPLOY9}, // S_SSMINE_DEPLOY8 + {SPR_SSMN, 10, 1, {NULL}, 0, 0, S_SSMINE_DEPLOY10}, // S_SSMINE_DEPLOY9 + {SPR_SSMN, 11, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY11}, // S_SSMINE_DEPLOY10 + {SPR_SSMN, 12, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY12}, // S_SSMINE_DEPLOY11 + {SPR_SSMN, 13, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY13}, // S_SSMINE_DEPLOY12 + {SPR_SSMN, 14, 3, {NULL}, 0, 0, S_SSMINE1}, // S_SSMINE_DEPLOY13 + {SPR_SSMN, 3, 1, {A_MineExplode}, MT_MINEEXPLOSION, 0, S_NULL}, // S_SSMINE_EXPLODE + {SPR_NULL, 0, 6, {NULL}, 0, 0, S_MINEEXPLOSION2}, // S_MINEEXPLOSION1 + {SPR_NULL, 1, 22, {A_ForceStop}, 0, 0, S_NULL}, // S_MINEEXPLOSION2 + + {SPR_KRBM, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_QUICKBOOM2}, // S_QUICKBOOM1 + {SPR_KRBM, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_QUICKBOOM3}, // S_QUICKBOOM2 + {SPR_KRBM, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_QUICKBOOM4}, // S_QUICKBOOM3 + {SPR_KRBM, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_QUICKBOOM5}, // S_QUICKBOOM4 + {SPR_KRBM, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_QUICKBOOM6}, // S_QUICKBOOM5 + {SPR_KRBM, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_QUICKBOOM7}, // S_QUICKBOOM6 + {SPR_KRBM, FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_QUICKBOOM8}, // S_QUICKBOOM7 + {SPR_KRBM, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_QUICKBOOM9}, // S_QUICKBOOM8 + {SPR_KRBM, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_QUICKBOOM10}, // S_QUICKBOOM9 + {SPR_KRBM, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_NULL}, // S_QUICKBOOM10 + + {SPR_KRBM, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_SLOWBOOM2}, // S_SLOWBOOM1 + {SPR_KRBM, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_SLOWBOOM3}, // S_SLOWBOOM2 + {SPR_KRBM, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_SLOWBOOM4}, // S_SLOWKBOOM3 + {SPR_KRBM, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_SLOWBOOM5}, // S_SLOWBOOM4 + {SPR_KRBM, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_SLOWBOOM6}, // S_SLOWBOOM5 + {SPR_KRBM, FF_FULLBRIGHT|5, 3, {NULL}, 0, 0, S_SLOWBOOM7}, // S_SLOWBOOM6 + {SPR_KRBM, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_SLOWBOOM8}, // S_SLOWBOOM7 + {SPR_KRBM, FF_FULLBRIGHT|7, 5, {NULL}, 0, 0, S_SLOWBOOM9}, // S_SLOWBOOM8 + {SPR_KRBM, FF_FULLBRIGHT|8, 5, {NULL}, 0, 0, S_SLOWBOOM10}, // S_SLOWBOOM9 + {SPR_KRBM, FF_FULLBRIGHT|9, 5, {NULL}, 0, 0, S_NULL}, // S_SLOWBOOM10 + + {SPR_BHOG, 0, 3, {A_PlaySound}, sfx_s1bd, 1, S_BALLHOG2}, // S_BALLHOG1 + {SPR_BHOG, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BALLHOG3}, // S_BALLHOG2 + {SPR_BHOG, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_BALLHOG4}, // S_BALLHOG3 + {SPR_BHOG, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_BALLHOG5}, // S_BALLHOG4 + {SPR_BHOG, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_BALLHOG6}, // S_BALLHOG5 + {SPR_BHOG, 5, 2, {NULL}, 0, 0, S_BALLHOG7}, // S_BALLHOG6 + {SPR_BHOG, 6, 1, {NULL}, 0, 0, S_BALLHOG8}, // S_BALLHOG7 + {SPR_BHOG, 7, 1, {NULL}, 0, 0, S_BALLHOG1}, // S_BALLHOG8 + {SPR_NULL, 0, 1, {A_BallhogExplode}, 0, 0, S_NULL}, // S_BALLHOG_DEAD + {SPR_BHBM, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BALLHOGBOOM2}, // S_BALLHOGBOOM1 + {SPR_BHBM, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BALLHOGBOOM3}, // S_BALLHOGBOOM2 + {SPR_BHBM, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BALLHOGBOOM4}, // S_BALLHOGBOOM3 + {SPR_BHBM, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_BALLHOGBOOM5}, // S_BALLHOGBOOM4 + {SPR_BHBM, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BALLHOGBOOM6}, // S_BALLHOGBOOM5 + {SPR_BHBM, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BALLHOGBOOM7}, // S_BALLHOGBOOM6 + {SPR_BHBM, FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_BALLHOGBOOM8}, // S_BALLHOGBOOM7 + {SPR_BHBM, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_BALLHOGBOOM9}, // S_BALLHOGBOOM8 + {SPR_BHBM, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BALLHOGBOOM10}, // S_BALLHOGBOOM9 + {SPR_BHBM, FF_FULLBRIGHT|9, 1, {NULL}, 0, 0, S_BALLHOGBOOM11}, // S_BALLHOGBOOM10 + {SPR_BHBM, FF_FULLBRIGHT|10, 1, {NULL}, 0, 0, S_BALLHOGBOOM12}, // S_BALLHOGBOOM11 + {SPR_BHBM, FF_FULLBRIGHT|11, 1, {NULL}, 0, 0, S_BALLHOGBOOM13}, // S_BALLHOGBOOM12 + {SPR_BHBM, FF_FULLBRIGHT|12, 1, {NULL}, 0, 0, S_BALLHOGBOOM14}, // S_BALLHOGBOOM13 + {SPR_BHBM, FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_BALLHOGBOOM15}, // S_BALLHOGBOOM14 + {SPR_BHBM, FF_FULLBRIGHT|14, 1, {NULL}, 0, 0, S_BALLHOGBOOM16}, // S_BALLHOGBOOM15 + {SPR_BHBM, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_NULL}, // S_BALLHOGBOOM16 {SPR_BLIG, 0, 2, {NULL}, 0, 0, S_BLUELIGHTNING2}, // S_BLUELIGHTNING1 {SPR_BLIG, 1, 2, {NULL}, 0, 0, S_BLUELIGHTNING3}, // S_BLUELIGHTNING2 {SPR_BLIG, 2, 2, {NULL}, 0, 0, S_BLUELIGHTNING4}, // S_BLUELIGHTNING3 {SPR_BLIG, 3, 2, {NULL}, 0, 0, S_NULL}, // S_BLUELIGHTNING4 - {SPR_BOMB, 0, 1, {A_BobombExplode}, MT_BLUEEXPLOSION, 0, S_NULL}, // S_BLUEEXPLODE + {SPR_SSMN, 0, 1, {A_MineExplode}, MT_BLUEEXPLOSION, 0, S_NULL}, // S_BLUEEXPLODE {SPR_LIGH, 0, 2, {NULL}, 0, 0, S_LIGHTNING2}, // S_LIGHTNING1 {SPR_LIGH, 1, 2, {NULL}, 0, 0, S_LIGHTNING3}, // S_LIGHTNING2 @@ -2728,12 +2767,11 @@ state_t states[NUMSTATES] = {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 {SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3 - {SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BATTLEBALLOON1}, // S_BATTLEBALLOON1 - {SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBALLOON2}, // S_BATTLEBALLOON2 - {SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBALLOON3}, // S_BATTLEBALLOON3 + {SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BATTLEBUMPER1}, // S_BATTLEBUMPER1 + {SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBUMPER2}, // S_BATTLEBUMPER2 + {SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBUMPER3}, // S_BATTLEBUMPER3 - {SPR_LAKI, 0, 64, {NULL}, 1, 0, S_LAKITU2}, // S_LAKITU1 - {SPR_LAKI, 1, 35, {NULL}, 0, 0, S_NULL}, // S_LAKITU2 + {SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER {SPR_POKE, 0, 2, {A_MoveAbsolute}, 0, 2, S_POKEY2}, // S_POKEY1 {SPR_POKE, 1, 2, {A_MoveAbsolute}, 0, 2, S_POKEY3}, // S_POKEY2 @@ -2812,12 +2850,20 @@ state_t states[NUMSTATES] = {SPR_DOOD, 11, -1, {NULL}, 0, 0, S_NULL}, // S_DOOD_BALLOON - {SPR_DOOD, 12, 4, {NULL}, 0, 0, S_DOOD_RING2}, // S_DOOD_RING1 - {SPR_DOOD, 13, 4, {NULL}, 0, 0, S_DOOD_RING3}, // S_DOOD_RING2 - {SPR_DOOD, 14, 4, {NULL}, 0, 0, S_DOOD_RING4}, // S_DOOD_RING3 - {SPR_DOOD, 15, 4, {NULL}, 0, 0, S_DOOD_RING5}, // S_DOOD_RING4 - {SPR_DOOD, 16, 4, {NULL}, 0, 0, S_DOOD_RING1}, // S_DOOD_RING5 + {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 + {SPR_BRNG, 3, 2, {NULL}, 0, 0, S_BIGRING05}, // S_BIGRING04 + {SPR_BRNG, 4, 2, {NULL}, 0, 0, S_BIGRING06}, // S_BIGRING05 + {SPR_BRNG, 5, 2, {NULL}, 0, 0, S_BIGRING07}, // S_BIGRING06 + {SPR_BRNG, 6, 2, {NULL}, 0, 0, S_BIGRING08}, // S_BIGRING05 + {SPR_BRNG, 7, 2, {NULL}, 0, 0, S_BIGRING09}, // S_BIGRING05 + {SPR_BRNG, 8, 2, {NULL}, 0, 0, S_BIGRING10}, // S_BIGRING05 + {SPR_BRNG, 9, 2, {NULL}, 0, 0, S_BIGRING11}, // S_BIGRING10 + {SPR_BRNG, 10, 2, {NULL}, 0, 0, S_BIGRING12}, // S_BIGRING11 + {SPR_BRNG, 11, 2, {NULL}, 0, 0, S_BIGRING01}, // S_BIGRING12 + {SPR_SNES, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNES_DONUTBUSH1 {SPR_SNES, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SNES_DONUTBUSH2 {SPR_SNES, 2, -1, {NULL}, 0, 0, S_NULL}, // S_SNES_DONUTBUSH3 @@ -2885,29 +2931,41 @@ state_t states[NUMSTATES] = {SPR_PSHW, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_FIREDITEM4}, // S_FIREDITEM3 {SPR_PSHW, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_NULL}, // S_FIREDITEM4 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30, 2, {NULL}, 0, 0, S_INSTASHIELDA2}, // S_INSTASHIELDA1 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|1, 2, {NULL}, 0, 0, S_INSTASHIELDA3}, // S_INSTASHIELDA2 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|2, 2, {NULL}, 0, 0, S_INSTASHIELDA4}, // S_INSTASHIELDA3 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|3, 2, {NULL}, 0, 0, S_INSTASHIELDA5}, // S_INSTASHIELDA4 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|4, 2, {NULL}, 0, 0, S_INSTASHIELDA6}, // S_INSTASHIELDA5 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|5, 2, {NULL}, 0, 0, S_INSTASHIELDA7}, // S_INSTASHIELDA6 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|6, 2, {NULL}, 0, 0, S_NULL}, // S_INSTASHIELDA7 + + {SPR_ISTB, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_INSTASHIELDB2}, // S_INSTASHIELDB1 + {SPR_ISTB, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_INSTASHIELDB3}, // S_INSTASHIELDB2 + {SPR_ISTB, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_INSTASHIELDB4}, // S_INSTASHIELDB3 + {SPR_ISTB, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_INSTASHIELDB5}, // S_INSTASHIELDB4 + {SPR_ISTB, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_INSTASHIELDB6}, // S_INSTASHIELDB5 + {SPR_ISTB, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_INSTASHIELDB7}, // S_INSTASHIELDB6 + {SPR_ISTB, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_NULL}, // S_INSTASHIELDB7 + // Above player arrow {SPR_ARRO, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW - {SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_MUSHROOM - {SPR_ARRO, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_GREENSHELL - {SPR_ARRO, FF_FULLBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BANANA - {SPR_ARRO, FF_FULLBRIGHT|4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FAKEITEM - {SPR_ARRO, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOO - {SPR_ARRO, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FEATHER - {SPR_ARRO, FF_FULLBRIGHT|7, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_REDSHELL - {SPR_ARRO, FF_FULLBRIGHT|8, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOBOMB - {SPR_ARRO, FF_FULLBRIGHT|9, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_FIREFLOWER - {SPR_ARRO, FF_FULLBRIGHT|10, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEGREENSHELL - {SPR_ARRO, FF_FULLBRIGHT|11, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEBANANA - {SPR_ARRO, FF_FULLBRIGHT|12, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_TRIPLEREDSHELL - {SPR_ARRO, FF_FULLBRIGHT|13, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_STAR - {SPR_ARRO, FF_FULLBRIGHT|14, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_MEGASHROOM - {SPR_ARRO, FF_FULLBRIGHT|15, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_KITCHENSINK - {SPR_ARRO, FF_FULLBRIGHT|16, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_EMPTY - {SPR_ARRO, FF_FULLBRIGHT|FF_ANIMATE|1, -1, {NULL}, 5, 3, S_NULL}, // S_PLAYERARROW_ROULETTE + {SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOX + {SPR_ITEM, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_ITEM + {SPR_ITMN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_NUMBER + {SPR_ITMN, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_X + {SPR_WANT, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_PLAYERARROW_WANTED2}, // S_PLAYERARROW_WANTED1 + {SPR_WANT, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED3}, // S_PLAYERARROW_WANTED2 + {SPR_WANT, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED4}, // S_PLAYERARROW_WANTED3 + {SPR_WANT, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED5}, // S_PLAYERARROW_WANTED4 + {SPR_WANT, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED6}, // S_PLAYERARROW_WANTED5 + {SPR_WANT, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED7}, // S_PLAYERARROW_WANTED6 + {SPR_WANT, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED1}, // S_PLAYERARROW_WANTED7 + {SPR_PBOM, FF_ANIMATE, -1, {NULL}, 3, 3, S_NULL}, // S_PLAYERBOMB {SPR_RNDM, FF_ANIMATE, -1, {NULL}, 23, 3, S_NULL}, // S_PLAYERITEM - {SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERWHEEL + + {SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_KARMAWHEEL #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -12004,7 +12062,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_FIREBALL -1, // doomednum S_FIREBALL1, // spawnstate - 140, // spawnhealth + 1000, // spawnhealth S_FIREBALLEXP1, // seestate sfx_None, // seesound 8, // reactiontime @@ -12016,15 +12074,15 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_FIREBALLEXP1, // missilestate S_FIREBALLEXP1, // deathstate S_FIREBALLEXP1, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_mario1, // deathsound + 10*FRACUNIT, // speed + 4*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset 100, // mass 1, // damage sfx_None, // activesound - MF_SHOOTABLE|MF_BOUNCE, // flags + MF_NOBLOCKMAP|MF_FIRE|MF_MISSILE, // flags S_NULL // raisestate }, @@ -13021,7 +13079,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // speed 16*FRACUNIT, // radius 48*FRACUNIT, // height - 0, // display offset + -1, // display offset 1000, // mass 8, // damage sfx_None, // activesound @@ -14293,14 +14351,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - MT_SPARK, // mass + MT_EXPLODE, // mass 0, // damage sfx_None, // activesound MF_NOCLIP, // flags S_NULL // raisestate }, - { // MT_MUSHROOMTRAIL + { // MT_SNEAKERTRAIL -1, // doomednum S_KARTFIRE1, // spawnstate 1, // spawnhealth @@ -14327,6 +14385,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SPARKLETRAIL + -1, // doomednum + S_KARTINVULN_SMALL1, // 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 + 8, // speed + 14*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_INVULNFLASH + -1, // doomednum + S_INVULNFLASH1, // 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 + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_WIPEOUTTRAIL + -1, // doomednum + S_WIPEOUTTRAIL1, // spawnstate + 1, // 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 + 8, // speed + 14*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_DRIFT -1, // doomednum S_DRIFTSPARK1, // spawnstate @@ -14431,121 +14570,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_fake, // activesound - MF_SHOOTABLE, // flags + MF_BOUNCE|MF_SHOOTABLE, // flags S_NULL // raisestate }, - { // MT_TRIPLEBANANASHIELD1 + { // MT_BANANA -1, // doomednum - S_BANANAITEM, // 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_DEADBANANA, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - k_banana, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_TRIPLEBANANASHIELD2 - -1, // doomednum - S_BANANAITEM, // 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_DEADBANANA, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - k_banana, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_TRIPLEBANANASHIELD3 - -1, // doomednum - S_BANANAITEM, // 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_DEADBANANA, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - k_banana, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_BANANASHIELD - -1, // doomednum - S_BANANAITEM, // 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_DEADBANANA, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - k_banana, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_BANANAITEM - -1, // doomednum - S_BANANAITEM, // spawnstate + S_BANANA, // spawnstate 2, // spawnhealth S_NULL, // seestate sfx_tossed, // seesound @@ -14556,7 +14587,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_DEADBANANA, // deathstate + S_BANANA_DEAD, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed @@ -14566,13 +14597,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_peel, // activesound - MF_SHOOTABLE, // flags + MF_BOUNCE|MF_SHOOTABLE, // flags S_NULL // raisestate }, - { // MT_TRIPLEGREENSHIELD1 + { // MT_BANANA_SHIELD -1, // doomednum - S_TRIPLEGREENSHIELD1, // spawnstate + S_BANANA, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14583,12 +14614,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_DEADGREEN, // deathstate + S_BANANA_DEAD, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 10*FRACUNIT, // radius + 24*FRACUNIT, // height 0, // display offset 100, // mass 1, // damage @@ -14597,101 +14628,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_TRIPLEGREENSHIELD2 + { // MT_ORBINAUT -1, // doomednum - S_TRIPLEGREENSHIELD4, // 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_DEADGREEN, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_TRIPLEGREENSHIELD3 - -1, // doomednum - S_TRIPLEGREENSHIELD7, // 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_DEADGREEN, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_GREENSHIELD - -1, // doomednum - S_GREENSHIELD1, // 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_DEADGREEN, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - k_greenshell, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_GREENITEM - -1, // doomednum - S_GREENITEM1, // spawnstate + S_ORBINAUT1, // spawnstate 7, // spawnhealth S_NULL, // seestate sfx_tossed, // seesound 8, // reactiontime - sfx_mario1, // attacksound + sfx_s3k49, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_DEADGREEN, // deathstate + S_ORBINAUT_DEAD,// deathstate S_NULL, // xdeathstate sfx_shbrk, // deathsound 64*FRACUNIT, // speed @@ -14700,14 +14650,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 100, // mass 1, // damage - sfx_grnshl, // activesound + sfx_s3k96, // activesound MF_SHOOTABLE|MF_BOUNCE, // flags S_NULL // raisestate }, - { // MT_FIRETRAIL + { // MT_ORBINAUT_SHIELD -1, // doomednum - S_FIRETRAIL1, // spawnstate + S_ORBINAUT_SHIELD, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14718,37 +14668,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_ORBINAUT_SHIELDDEAD, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_TRIPLEREDSHIELD1 - -1, // doomednum - S_TRIPLEREDSHIELD2, // 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_DEADRED, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed + 10*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset @@ -14759,90 +14682,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_TRIPLEREDSHIELD2 + { // MT_JAWZ -1, // doomednum - S_TRIPLEREDSHIELD5, // 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_DEADRED, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_TRIPLEREDSHIELD3 - -1, // doomednum - S_TRIPLEREDSHIELD8, // 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_DEADRED, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_REDSHIELD - -1, // doomednum - S_REDSHIELD1, // 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_DEADRED, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - k_redshell, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_REDITEM - -1, // doomednum - S_REDITEM1, // spawnstate + S_JAWZ1, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_tossed, // seesound @@ -14853,8 +14695,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_DEADRED, // deathstate - S_NULL, // xdeathstate + S_JAWZ_DEAD1, // deathstate + S_JAWZ_DEAD2, // xdeathstate sfx_shbrk, // deathsound 7*FRACUNIT, // speed 16*FRACUNIT, // radius @@ -14862,14 +14704,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 100, // mass 1, // damage - sfx_redshl, // activesound + sfx_s3kc0s, // activesound MF_SHOOTABLE, // flags S_NULL // raisestate }, - { // MT_REDITEMDUD + { // MT_JAWZ_DUD -1, // doomednum - S_REDITEM1, // spawnstate + S_JAWZ_DUD1, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_tossed, // seesound @@ -14880,8 +14722,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_DEADRED, // deathstate - S_NULL, // xdeathstate + S_JAWZ_DEAD1, // deathstate + S_JAWZ_DEAD2, // xdeathstate sfx_shbrk, // deathsound 56*FRACUNIT, // speed 16*FRACUNIT, // radius @@ -14889,28 +14731,28 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 100, // mass 1, // damage - sfx_redshl, // activesound + sfx_s3kc0s, // activesound MF_SHOOTABLE, // flags S_NULL // raisestate }, - { // MT_BOMBSHIELD + { // MT_JAWZ_SHIELD -1, // doomednum - S_BOMBSHIELD, // spawnstate + S_JAWZ_SHIELD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 256*FRACUNIT, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BOMBEXPLODE, // deathstate - S_NULL, // xdeathstate + S_JAWZ_DEAD1, // deathstate + S_JAWZ_DEAD2, // xdeathstate sfx_None, // deathsound - k_bobomb, // speed + 10*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset @@ -14921,36 +14763,63 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BOMBITEM + { // MT_SSMINE + -1, // doomednum + S_SSMINE_AIR1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_tossed, // seesound + 6*TICRATE, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 288*FRACUNIT, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SSMINE_EXPLODE, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_bomb, // activesound + MF_BOUNCE|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_SSMINE_SHIELD -1, // doomednum - S_BOMBAIR, // spawnstate - 1, // spawnhealth + S_SSMINE_SHIELD1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_tossed, // seesound - 105, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 288*FRACUNIT, // painchance + 320*FRACUNIT, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BOMBEXPLODE, // deathstate + S_SSMINE_EXPLODE, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 10*FRACUNIT, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 1, // damage - sfx_bomb, // activesound - MF_BOUNCE|MF_SHOOTABLE, // flags + sfx_None, // activesound + MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BOMBEXPLOSION + { // MT_MINEEXPLOSION -1, // doomednum - S_BOMBEXPLOSION1, // spawnstate + S_MINEEXPLOSION1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14975,7 +14844,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BOMBEXPLOSIONSOUND + { // MT_MINEEXPLOSIONSOUND -1, // doomednum S_INVISIBLE, // spawnstate 100, // spawnhealth @@ -15083,6 +14952,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BALLHOG + -1, // doomednum + S_BALLHOG1, // spawnstate + 140, // 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_BALLHOG_DEAD, // deathstate + S_NULL, // xdeathstate + sfx_hogbom, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SHOOTABLE|MF_BOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_BALLHOGBOOM + -1, // doomednum + S_BALLHOGBOOM1, // 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 + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags + S_NULL // raisestate + }, + { // MT_BLUELIGHTNING -1, // doomednum S_BLUELIGHTNING1, // spawnstate @@ -15123,7 +15046,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BOMBEXPLODE, // deathstate + S_SSMINE_EXPLODE, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed @@ -15169,7 +15092,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_SINK, // spawnstate 105, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_tossed, // seesound 8, // reactiontime sfx_None, // attacksound 256*FRACUNIT, // painstate @@ -15187,7 +15110,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_bomb, // activesound - MF_BOUNCE|MF_FLOAT|MF_NOCLIPTHING|MF_MISSILE|MF_SHOOTABLE, // flags + MF_BOUNCE|MF_SHOOTABLE, // flags S_NULL // raisestate }, @@ -15218,9 +15141,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BATTLEBALLOON + { // MT_BATTLEBUMPER -1, // doomednum - S_BATTLEBALLOON1,// spawnstate + S_BATTLEBUMPER1,// spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -15245,9 +15168,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_LAKITU + { // MT_DEZLASER -1, // doomednum - S_LAKITU1, // spawnstate + S_DEZLASER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -15262,13 +15185,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 8, // speed - 64*FRACUNIT, // radius - 57*FRACUNIT, // height - 0, // display offset + 42*FRACUNIT, // radius + 8*FRACUNIT, // height + 1, // display offset 16, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, @@ -16055,9 +15978,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_DOOD_RING + { // MT_BIGRING 2808, // doomednum - S_DOOD_RING1, // spawnstate + S_BIGRING01, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -16072,13 +15995,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 1048576, // radius - 2097152, // height + 26*FRACUNIT, // radius + 62*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - 33554944, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, @@ -16105,7 +16028,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOTHINK, // flags S_NULL // raisestate }, @@ -16132,7 +16055,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOTHINK, // flags S_NULL // raisestate }, @@ -16159,7 +16082,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOTHINK, // flags S_NULL // raisestate }, @@ -16730,6 +16653,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_INSTASHIELDA + -1, // doomednum + S_INSTASHIELDA1, // 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 + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_INSTASHIELDB + -1, // doomednum + S_INSTASHIELDB1, // 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 + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 2, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_PLAYERARROW -1, // doomednum S_PLAYERARROW, // spawnstate @@ -16757,6 +16734,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_PLAYERWANTED + -1, // doomednum + S_PLAYERARROW_WANTED1, // 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 + 8, // speed + 36*FRACUNIT, // radius + 37*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_KARMAHITBOX + -1, // doomednum + S_PLAYERBOMB, // spawnstate + 1000, // spawnhealth + S_PLAYERITEM, // seestate + sfx_kc2e, // seesound + 8, // reactiontime + sfx_s3k4e, // 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 + 26*FRACUNIT, // radius + 52*FRACUNIT, // height + -1, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_KARMAWHEEL + -1, // doomednum + S_KARMAWHEEL, // 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 + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index a223beca..3186fc88 100644 --- a/src/info.h +++ b/src/info.h @@ -164,8 +164,10 @@ void A_DualAction(); void A_RemoteAction(); void A_ToggleFlameJet(); void A_ItemPop(); // SRB2kart -void A_RedShellChase(); // SRB2kart -void A_BobombExplode(); // SRB2kart +void A_JawzChase(); // SRB2kart +void A_JawzExplode(); // SRB2kart +void A_MineExplode(); // SRB2kart +void A_BallhogExplode(); // SRB2kart void A_OrbitNights(); void A_GhostMe(); void A_SetObjectState(); @@ -580,28 +582,29 @@ typedef enum sprite SPR_RNDM, // Random Item Box SPR_RPOP, // Random Item Box Pop - SPR_KFRE, // Mushroom fire trail + SPR_KFRE, // Sneaker fire trail + SPR_KINV, // Invincibility sparkle trail + SPR_KINF, // Invincibility flash + SPR_WIPD, // Wipeout dust trail SPR_DRIF, // Drift Sparks SPR_DUST, // Drift Dust // Kart Items - SPR_FITM, // Fake Item box - SPR_DFAK, // Dead Fake Item + SPR_FITM, // Eggman Monitor SPR_BANA, // Banana Peel - SPR_DBAN, // Dead Banana Peel - SPR_GSHE, // Green Shell - SPR_DGSH, // Dead Green Shell - SPR_RSHE, // Red Shell - SPR_DRSH, // Dead Red Shell - SPR_BOMB, // Bob-omb - SPR_KRBM, - SPR_BLIG, // Blue Lightning - SPR_LIGH, // Lightning + SPR_ORBN, // Orbinaut + SPR_JAWZ, // Jawz + SPR_SSMN, // SS Mine + SPR_KRBM, // SS Mine BOOM + SPR_BHOG, // Ballhog + SPR_BHBM, // Ballhog BOOM + SPR_BLIG, // Self-Propelled Bomb + SPR_LIGH, // Grow/shrink beams (Metallic Maddness) SPR_SINK, // Kitchen Sink SPR_SITR, // Kitchen Sink Trail - SPR_KBLN, // Battle Mode Balloon + SPR_KBLN, // Battle Mode Bumper - SPR_LAKI, // Lakitu + SPR_DEZL, // DEZ Laser respawn // Additional Kart Objects SPR_POKE, // Pokey @@ -616,16 +619,25 @@ typedef enum sprite SPR_SACO, // Sapphire Coast Fauna SPR_CRAB, // Crystal Abyss mobs SPR_SHAD, // TD shadows + SPR_BRNG, // Chaotix Big Ring SPR_BUMP, // Player/shell bump SPR_FLEN, // Shell hit graphics stuff SPR_CLAS, // items clash SPR_PSHW, // thrown indicator + SPR_ISTA, // instashield layer A + SPR_ISTB, // instashield layer B SPR_ARRO, // player arrows + SPR_ITEM, + SPR_ITMI, + SPR_ITMN, + SPR_WANT, SPR_PBOM, // player bomb + SPR_VIEW, // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw! + SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMSPRITES @@ -2647,15 +2659,9 @@ typedef enum state S_FIREBALL2, S_FIREBALL3, S_FIREBALL4, - S_FIREBALL5, - S_FIREBALL6, - S_FIREBALL7, S_FIREBALLEXP1, S_FIREBALLEXP2, S_FIREBALLEXP3, - S_FIREBALLEXP4, - S_FIREBALLEXP5, - S_FIREBALLEXP6, S_SHELL, S_SHELL1, S_SHELL2, @@ -3085,7 +3091,7 @@ typedef enum state // Magnet Burst - // Mushroom Fire Trail + // Sneaker Fire Trail S_KARTFIRE1, S_KARTFIRE2, S_KARTFIRE3, @@ -3095,7 +3101,33 @@ typedef enum state S_KARTFIRE7, S_KARTFIRE8, - //{ Fake Item + // Invincibility Sparks + S_KARTINVULN_SMALL1, + S_KARTINVULN_SMALL2, + S_KARTINVULN_SMALL3, + S_KARTINVULN_SMALL4, + S_KARTINVULN_SMALL5, + + S_KARTINVULN_LARGE1, + S_KARTINVULN_LARGE2, + S_KARTINVULN_LARGE3, + S_KARTINVULN_LARGE4, + S_KARTINVULN_LARGE5, + + // Invincibility flash + S_INVULNFLASH1, + S_INVULNFLASH2, + S_INVULNFLASH3, + S_INVULNFLASH4, + + // Wipeout dust trail + S_WIPEOUTTRAIL1, + S_WIPEOUTTRAIL2, + S_WIPEOUTTRAIL3, + S_WIPEOUTTRAIL4, + S_WIPEOUTTRAIL5, + + //{ Eggman Monitor S_FAKEITEM1, S_FAKEITEM2, S_FAKEITEM3, @@ -3124,81 +3156,74 @@ typedef enum state //} // Banana - S_BANANAITEM, - S_DEADBANANA, + S_BANANA, + S_BANANA_DEAD, - //{ Green Shell - S_TRIPLEGREENSHIELD1, - S_TRIPLEGREENSHIELD2, - S_TRIPLEGREENSHIELD3, - S_TRIPLEGREENSHIELD4, - S_TRIPLEGREENSHIELD5, - S_TRIPLEGREENSHIELD6, - S_TRIPLEGREENSHIELD7, - S_TRIPLEGREENSHIELD8, - S_GREENSHIELD1, - S_GREENSHIELD2, - S_GREENSHIELD3, - S_GREENSHIELD4, - S_GREENSHIELD5, - S_GREENSHIELD6, - S_GREENSHIELD7, - S_GREENSHIELD8, - S_GREENITEM1, - S_GREENITEM2, - S_GREENITEM3, - S_GREENITEM4, - S_GREENITEM5, - S_GREENITEM6, - S_GREENITEM7, - S_GREENITEM8, - S_DEADGREEN, + //{ Orbinaut + S_ORBINAUT1, + S_ORBINAUT2, + S_ORBINAUT3, + S_ORBINAUT4, + S_ORBINAUT5, + S_ORBINAUT6, + S_ORBINAUT_SHIELD, + S_ORBINAUT_DEAD, + S_ORBINAUT_SHIELDDEAD, //} - //{ Red Shell - S_TRIPLEREDSHIELD1, - S_TRIPLEREDSHIELD2, - S_TRIPLEREDSHIELD3, - S_TRIPLEREDSHIELD4, - S_TRIPLEREDSHIELD5, - S_TRIPLEREDSHIELD6, - S_TRIPLEREDSHIELD7, - S_TRIPLEREDSHIELD8, - S_REDSHIELD1, - S_REDSHIELD2, - S_REDSHIELD3, - S_REDSHIELD4, - S_REDSHIELD5, - S_REDSHIELD6, - S_REDSHIELD7, - S_REDSHIELD8, - S_REDITEM1, - S_REDITEM2, - S_REDITEM3, - S_REDITEM4, - S_REDITEM5, - S_REDITEM6, - S_REDITEM7, - S_REDITEM8, - S_DEADRED, + //{ Jawz + S_JAWZ1, + S_JAWZ2, + S_JAWZ3, + S_JAWZ4, + S_JAWZ5, + S_JAWZ6, + S_JAWZ7, + S_JAWZ8, + S_JAWZ_DUD1, + S_JAWZ_DUD2, + S_JAWZ_DUD3, + S_JAWZ_DUD4, + S_JAWZ_DUD5, + S_JAWZ_DUD6, + S_JAWZ_DUD7, + S_JAWZ_DUD8, + S_JAWZ_SHIELD1, + S_JAWZ_SHIELD2, + S_JAWZ_SHIELD3, + S_JAWZ_SHIELD4, + S_JAWZ_SHIELD5, + S_JAWZ_SHIELD6, + S_JAWZ_SHIELD7, + S_JAWZ_SHIELD8, + S_JAWZ_DEAD1, + S_JAWZ_DEAD2, //} - S_FIRETRAIL1, - S_FIRETRAIL2, - S_FIRETRAIL3, - S_FIRETRAIL4, - S_FIRETRAIL5, - S_FIRETRAIL6, - S_FIRETRAIL7, - S_FIRETRAIL8, - S_FIRETRAIL9, - - // Bob-omb - S_BOMBSHIELD, - S_BOMBITEM, - S_BOMBAIR, - S_BOMBEXPLODE, - S_BOMBEXPLOSION1, - S_BOMBEXPLOSION2, + // Special Stage Mine + S_SSMINE1, + S_SSMINE2, + S_SSMINE3, + S_SSMINE4, + S_SSMINE_SHIELD1, + S_SSMINE_SHIELD2, + S_SSMINE_AIR1, + S_SSMINE_AIR2, + S_SSMINE_DEPLOY1, + S_SSMINE_DEPLOY2, + S_SSMINE_DEPLOY3, + S_SSMINE_DEPLOY4, + S_SSMINE_DEPLOY5, + S_SSMINE_DEPLOY6, + S_SSMINE_DEPLOY7, + S_SSMINE_DEPLOY8, + S_SSMINE_DEPLOY9, + S_SSMINE_DEPLOY10, + S_SSMINE_DEPLOY11, + S_SSMINE_DEPLOY12, + S_SSMINE_DEPLOY13, + S_SSMINE_EXPLODE, + S_MINEEXPLOSION1, + S_MINEEXPLOSION2, // New explosion S_QUICKBOOM1, @@ -3223,14 +3248,41 @@ typedef enum state S_SLOWBOOM9, S_SLOWBOOM10, - // Blue Shell - Blue Lightning for now... + // Ballhog + S_BALLHOG1, + S_BALLHOG2, + S_BALLHOG3, + S_BALLHOG4, + S_BALLHOG5, + S_BALLHOG6, + S_BALLHOG7, + S_BALLHOG8, + S_BALLHOG_DEAD, + S_BALLHOGBOOM1, + S_BALLHOGBOOM2, + S_BALLHOGBOOM3, + S_BALLHOGBOOM4, + S_BALLHOGBOOM5, + S_BALLHOGBOOM6, + S_BALLHOGBOOM7, + S_BALLHOGBOOM8, + S_BALLHOGBOOM9, + S_BALLHOGBOOM10, + S_BALLHOGBOOM11, + S_BALLHOGBOOM12, + S_BALLHOGBOOM13, + S_BALLHOGBOOM14, + S_BALLHOGBOOM15, + S_BALLHOGBOOM16, + + // Self-Propelled Bomb - just an explosion for now... S_BLUELIGHTNING1, S_BLUELIGHTNING2, S_BLUELIGHTNING3, S_BLUELIGHTNING4, S_BLUEEXPLODE, - // Lightning + // Size-Down S_LIGHTNING1, S_LIGHTNING2, S_LIGHTNING3, @@ -3242,14 +3294,13 @@ typedef enum state S_SINKTRAIL2, S_SINKTRAIL3, - // Battle Mode balloons - S_BATTLEBALLOON1, - S_BATTLEBALLOON2, - S_BATTLEBALLOON3, + // Battle Mode bumpers + S_BATTLEBUMPER1, + S_BATTLEBUMPER2, + S_BATTLEBUMPER3, - // Lakitu - S_LAKITU1, - S_LAKITU2, + // DEZ Laser respawn + S_DEZLASER, // Pokey S_POKEY1, @@ -3329,15 +3380,22 @@ typedef enum state S_DOOD_BOX4, S_DOOD_BOX5, - // D00Dkart - Diddy Kong Racing Balloon + // D00Dkart - Diddy Kong Racing Bumper S_DOOD_BALLOON, - // D00Dkart - Big Ring - S_DOOD_RING1, - S_DOOD_RING2, - S_DOOD_RING3, - S_DOOD_RING4, - S_DOOD_RING5, + // Chaotix Big Ring + S_BIGRING01, + S_BIGRING02, + S_BIGRING03, + S_BIGRING04, + S_BIGRING05, + S_BIGRING06, + S_BIGRING07, + S_BIGRING08, + S_BIGRING09, + S_BIGRING10, + S_BIGRING11, + S_BIGRING12, // SNES Objects S_SNES_DONUTBUSH1, @@ -3409,28 +3467,38 @@ typedef enum state S_FIREDITEM3, S_FIREDITEM4, + S_INSTASHIELDA1, // No damage instashield effect + S_INSTASHIELDA2, + S_INSTASHIELDA3, + S_INSTASHIELDA4, + S_INSTASHIELDA5, + S_INSTASHIELDA6, + S_INSTASHIELDA7, + S_INSTASHIELDB1, + S_INSTASHIELDB2, + S_INSTASHIELDB3, + S_INSTASHIELDB4, + S_INSTASHIELDB5, + S_INSTASHIELDB6, + S_INSTASHIELDB7, + S_PLAYERARROW, // Above player arrow - S_PLAYERARROW_MUSHROOM, - S_PLAYERARROW_GREENSHELL, - S_PLAYERARROW_BANANA, - S_PLAYERARROW_FAKEITEM, - S_PLAYERARROW_BOO, - S_PLAYERARROW_FEATHER, - S_PLAYERARROW_REDSHELL, - S_PLAYERARROW_BOBOMB, - S_PLAYERARROW_FIREFLOWER, - S_PLAYERARROW_TRIPLEGREENSHELL, - S_PLAYERARROW_TRIPLEBANANA, - S_PLAYERARROW_TRIPLEREDSHELL, - S_PLAYERARROW_STAR, - S_PLAYERARROW_MEGASHROOM, - S_PLAYERARROW_KITCHENSINK, - S_PLAYERARROW_EMPTY, - S_PLAYERARROW_ROULETTE, + S_PLAYERARROW_BOX, + S_PLAYERARROW_ITEM, + S_PLAYERARROW_NUMBER, + S_PLAYERARROW_X, + S_PLAYERARROW_WANTED1, + S_PLAYERARROW_WANTED2, + S_PLAYERARROW_WANTED3, + S_PLAYERARROW_WANTED4, + S_PLAYERARROW_WANTED5, + S_PLAYERARROW_WANTED6, + S_PLAYERARROW_WANTED7, S_PLAYERBOMB, S_PLAYERITEM, - S_PLAYERWHEEL, + + S_KARMAWHEEL, #ifdef SEENAMES S_NAMECHECK, @@ -3966,52 +4034,48 @@ typedef enum mobj_type MT_RANDOMITEM, MT_RANDOMITEMPOP, - MT_MUSHROOMTRAIL, + MT_SNEAKERTRAIL, + MT_SPARKLETRAIL, + MT_INVULNFLASH, + MT_WIPEOUTTRAIL, MT_DRIFT, MT_DRIFTDUST, MT_FAKESHIELD, MT_FAKEITEM, - MT_TRIPLEBANANASHIELD1, // Banana Stuff - MT_TRIPLEBANANASHIELD2, - MT_TRIPLEBANANASHIELD3, - MT_BANANASHIELD, - MT_BANANAITEM, + MT_BANANA, // Banana Stuff + MT_BANANA_SHIELD, - MT_TRIPLEGREENSHIELD1, // Green shell stuff - MT_TRIPLEGREENSHIELD2, - MT_TRIPLEGREENSHIELD3, - MT_GREENSHIELD, - MT_GREENITEM, - MT_FIRETRAIL, + MT_ORBINAUT, // Orbinaut stuff + MT_ORBINAUT_SHIELD, - MT_TRIPLEREDSHIELD1, // Red shell stuff - MT_TRIPLEREDSHIELD2, - MT_TRIPLEREDSHIELD3, - MT_REDSHIELD, - MT_REDITEM, - MT_REDITEMDUD, + MT_JAWZ, // Jawz stuff + MT_JAWZ_DUD, + MT_JAWZ_SHIELD, - MT_BOMBSHIELD, // Bob-omb stuff - MT_BOMBITEM, - MT_BOMBEXPLOSION, - MT_BOMBEXPLOSIONSOUND, + MT_SSMINE, // Mine stuff + MT_SSMINE_SHIELD, + MT_MINEEXPLOSION, + MT_MINEEXPLOSIONSOUND, MT_SMOLDERING, // New explosion MT_BOOMEXPLODE, MT_BOOMPARTICLE, - MT_BLUELIGHTNING, // Lightning stuff + MT_BALLHOG, // Ballhog + MT_BALLHOGBOOM, + + MT_BLUELIGHTNING, // Grow/shrink stuff MT_BLUEEXPLOSION, MT_LIGHTNING, MT_SINK, // Kitchen Sink Stuff MT_SINKTRAIL, - MT_BATTLEBALLOON, // Battle Mode balloons + MT_BATTLEBUMPER, // Battle Mode bumpers - MT_LAKITU, + MT_DEZLASER, MT_POKEY, // Huh, thought this was a default asset for some reason, guess not. @@ -4047,7 +4111,7 @@ typedef enum mobj_type MT_DOOD_FLOWER4, MT_DOOD_BOX, MT_DOOD_BALLOON, - MT_DOOD_RING, + MT_BIGRING, MT_SNES_DONUTBUSH1, MT_SNES_DONUTBUSH2, @@ -4082,7 +4146,14 @@ typedef enum mobj_type MT_FIREDITEM, + MT_INSTASHIELDA, + MT_INSTASHIELDB, + MT_PLAYERARROW, + MT_PLAYERWANTED, + + MT_KARMAHITBOX, + MT_KARMAWHEEL, #ifdef SEENAMES MT_NAMECHECK, diff --git a/src/k_kart.c b/src/k_kart.c index 27080423..6792895a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -17,6 +17,7 @@ #include "v_video.h" #include "z_zone.h" #include "m_misc.h" +#include "m_cond.h" #include "k_kart.h" #include "f_finale.h" @@ -25,9 +26,11 @@ // franticitems is Frantic Mode items, bool // mirrormode is Mirror Mode (duh), bool // comeback is Battle Mode's karma comeback, also bool -// lightningcooldown is timer before anyone's allowed another lightning/blue shell -// blueshellincoming is the timer before k_deathsentence is cast on the player in 1st -// blueshellplayer is the last player who fired one +// battlewanted is an array of the WANTED player nums, -1 for no player in that slot +// indirectitemcooldown is timer before anyone's allowed another Shrink/SPB +// spbincoming is the timer before k_deathsentence is cast on the player in 1st +// spbplayer is the last player who fired a SPB +// mapreset is set when enough players fill an empty server //{ SRB2kart Color Code @@ -45,143 +48,217 @@ const char *KartColor_Names[MAXSKINCOLORS] = "Silver", // 03 // SKINCOLOR_SILVER "Cloudy", // 04 // SKINCOLOR_CLOUDY "Grey", // 05 // SKINCOLOR_GREY - "Dark Grey", // 06 // SKINCOLOR_DARKGREY + "Nickel", // 06 // SKINCOLOR_NICKEL "Black", // 07 // SKINCOLOR_BLACK "Salmon", // 08 // SKINCOLOR_SALMON "Pink", // 09 // SKINCOLOR_PINK - "Light Red", // 10 // SKINCOLOR_LIGHTRED - "Shiny Red", // 11 // SKINCOLOR_SHINYRED + "Rose", // 10 // SKINCOLOR_ROSE + "Raspberry", // 11 // SKINCOLOR_RASPBERRY "Red", // 12 // SKINCOLOR_RED - "Dark Pink", // 13 // SKINCOLOR_DARKPINK - "Dark Red", // 14 // SKINCOLOR_DARKRED + "Ruby", // 13 // SKINCOLOR_RUBY + "Crimson", // 14 // SKINCOLOR_CRIMSON "Dawn", // 15 // SKINCOLOR_DAWN - "Orange", // 16 // SKINCOLOR_ORANGE - "Shiny Orange", // 17 // SKINCOLOR_SHINYORANGE - "Dark Orange", // 18 // SKINCOLOR_DARKORANGE - "Golden Brown", // 19 // SKINCOLOR_GOLDENBROWN - "Rosewood", // 20 // SKINCOLOR_ROSEWOOD - "Dark Rosewood", // 21 // SKINCOLOR_DARKROSEWOOD + "Creamsicle", // 16 // SKINCOLOR_CREAMSICLE + "Orange", // 17 // SKINCOLOR_ORANGE + "Pumpkin", // 18 // SKINCOLOR_PUMPKIN + "Rosewood", // 19 // SKINCOLOR_ROSEWOOD + "Burgundy", // 20 // SKINCOLOR_BURGUNDY + "Bronze", // 21 // SKINCOLOR_BRONZE "Sepia", // 22 // SKINCOLOR_SEPIA "Beige", // 23 // SKINCOLOR_BEIGE "Brown", // 24 // SKINCOLOR_BROWN "Leather", // 25 // SKINCOLOR_LEATHER - "Yellow", // 26 // SKINCOLOR_YELLOW - "Peach", // 27 // SKINCOLOR_PEACH - "Light Orange", // 28 // SKINCOLOR_LIGHTORANGE - "Caramel", // 29 // SKINCOLOR_CARAMEL - "Gold", // 30 // SKINCOLOR_GOLD - "Shiny Caramel", // 31 // SKINCOLOR_SHINYCARAMEL - "Vomit", // 32 // SKINCOLOR_VOMIT - "Garden", // 33 // SKINCOLOR_GARDEN - "Light Army", // 34 // SKINCOLOR_LIGHTARMY - "Army", // 35 // SKINCOLOR_ARMY - "Pistachio", // 36 // SKINCOLOR_PISTACHIO - "Robo-Hood", // 37 // SKINCOLOR_ROBOHOOD - "Olive", // 38 // SKINCOLOR_OLIVE - "Dark Army", // 39 // SKINCOLOR_DARKARMY - "Light Green", // 40 // SKINCOLOR_LIGHTGREEN - "Ugly Green", // 41 // SKINCOLOR_UGLYGREEN - "Neon Green", // 42 // SKINCOLOR_NEONGREEN - "Green", // 43 // SKINCOLOR_GREEN - "Dark Green", // 44 // SKINCOLOR_DARKGREEN + "Peach", // 26 // SKINCOLOR_PEACH + "Caramel", // 27 // SKINCOLOR_CARAMEL + "Tangerine", // 28 // SKINCOLOR_TANGERINE + "Gold", // 29 // SKINCOLOR_GOLD + "Vomit", // 30 // SKINCOLOR_VOMIT + "Yellow", // 31 // SKINCOLOR_YELLOW + "Canary", // 32 // SKINCOLOR_CANARY + "Olive", // 33 // SKINCOLOR_OLIVE + "Garden", // 34 // SKINCOLOR_GARDEN + "Lime", // 35 // SKINCOLOR_LIME + "Tea", // 36 // SKINCOLOR_TEA + "Army", // 37 // SKINCOLOR_ARMY + "Pistachio", // 38 // SKINCOLOR_PISTACHIO + "Moss", // 39 // SKINCOLOR_MOSS + "Mint", // 40 // SKINCOLOR_MINT + "Green", // 41 // SKINCOLOR_GREEN + "Robo-Hood", // 42 // SKINCOLOR_ROBOHOOD + "Pinetree", // 43 // SKINCOLOR_PINETREE + "Emerald", // 44 // SKINCOLOR_EMERALD "Swamp", // 45 // SKINCOLOR_SWAMP - "Frost", // 46 // SKINCOLOR_FROST - "Slate", // 47 // SKINCOLOR_SLATEBLUE - "Light Blue", // 48 // SKINCOLOR_LIGHTBLUE - "Cyan", // 49 // SKINCOLOR_CYAN - "Cerulean", // 50 // SKINCOLOR_CERULEAN - "Turquoise", // 51 // SKINCOLOR_TURQUOISE - "Teal", // 52 // SKINCOLOR_TEAL - "Steel Blue", // 53 // SKINCOLOR_STEELBLUE - "Blue", // 54 // SKINCOLOR_BLUE - "Shiny Blue", // 55 // SKINCOLOR_SHINYBLUE + "Aqua", // 46 // SKINCOLOR_AQUA + "Teal", // 47 // SKINCOLOR_TEAL + "Cyan", // 48 // SKINCOLOR_CYAN + "Cerulean", // 49 // SKINCOLOR_CERULEAN + "Slate", // 50 // SKINCOLOR_SLATE + "Steel", // 51 // SKINCOLOR_STEEL + "Periwinkle", // 52 // SKINCOLOR_PERIWINKLE + "Blue", // 53 // SKINCOLOR_BLUE + "Sapphire", // 54 // SKINCOLOR_SAPPHIRE + "Blueberry", // 55 // SKINCOLOR_BLUEBERRY "Navy", // 56 // SKINCOLOR_NAVY - "Dark Blue", // 57 // SKINCOLOR_DARKBLUE - "Jet Black", // 58 // SKINCOLOR_JETBLACK - "Lilac", // 59 // SKINCOLOR_LILAC - "Purple", // 60 // SKINCOLOR_PURPLE - "Lavender", // 61 // SKINCOLOR_LAVENDER + "Jet", // 57 // SKINCOLOR_JET + "Dusk", // 58 // SKINCOLOR_DUSK + "Purple", // 59 // SKINCOLOR_PURPLE + "Lavender", // 60 // SKINCOLOR_LAVENDER + "Indigo", // 61 // SKINCOLOR_INDIGO "Byzantium", // 62 // SKINCOLOR_BYZANTIUM - "Indigo" // 63 // SKINCOLOR_INDIGO + "Lilac" // 63 // SKINCOLOR_LILAC +}; + +// Color_Opposite replacement; frame setting has not been changed from 8 for most, should be done later +const UINT8 KartColor_Opposite[MAXSKINCOLORS*2] = +{ + SKINCOLOR_NONE,8, // 00 // SKINCOLOR_NONE + SKINCOLOR_BLACK,8, // 01 // SKINCOLOR_IVORY + SKINCOLOR_NICKEL,8, // 02 // SKINCOLOR_WHITE + SKINCOLOR_GREY,8, // 03 // SKINCOLOR_SILVER + SKINCOLOR_CLOUDY,8, // 04 // SKINCOLOR_CLOUDY + SKINCOLOR_SILVER,8, // 05 // SKINCOLOR_GREY + SKINCOLOR_WHITE,8, // 06 // SKINCOLOR_NICKEL + SKINCOLOR_IVORY,8, // 07 // SKINCOLOR_BLACK + SKINCOLOR_TEA,8, // 08 // SKINCOLOR_SALMON + SKINCOLOR_ARMY,8, // 09 // SKINCOLOR_PINK + SKINCOLOR_MOSS,8, // 10 // SKINCOLOR_ROSE + SKINCOLOR_MINT,10, // 11 // SKINCOLOR_RASPBERRY + SKINCOLOR_GREEN,8, // 12 // SKINCOLOR_RED + SKINCOLOR_EMERALD,6, // 13 // SKINCOLOR_RUBY + SKINCOLOR_PINETREE,6, // 14 // SKINCOLOR_CRIMSON + SKINCOLOR_DUSK,8, // 15 // SKINCOLOR_DAWN + SKINCOLOR_PERIWINKLE,8, // 16 // SKINCOLOR_CREAMSICLE + SKINCOLOR_BLUE,8, // 17 // SKINCOLOR_ORANGE + SKINCOLOR_BLUEBERRY,8, // 18 // SKINCOLOR_PUMPKIN + SKINCOLOR_NAVY,8, // 19 // SKINCOLOR_ROSEWOOD + SKINCOLOR_JET,8, // 20 // SKINCOLOR_BURGUNDY + SKINCOLOR_STEEL,8, // 21 // SKINCOLOR_BRONZE + SKINCOLOR_LEATHER,6, // 22 // SKINCOLOR_SEPIA + SKINCOLOR_BROWN,2, // 23 // SKINCOLOR_BEIGE + SKINCOLOR_BEIGE,8, // 24 // SKINCOLOR_BROWN + SKINCOLOR_SEPIA,8, // 25 // SKINCOLOR_LEATHER + SKINCOLOR_SLATE,8, // 26 // SKINCOLOR_PEACH + SKINCOLOR_TEAL,8, // 27 // SKINCOLOR_CARAMEL + SKINCOLOR_LIME,8, // 28 // SKINCOLOR_TANGERINE + SKINCOLOR_LAVENDER,6, // 29 // SKINCOLOR_GOLD + SKINCOLOR_ROBOHOOD,8, // 30 // SKINCOLOR_VOMIT + SKINCOLOR_BYZANTIUM,8, // 31 // SKINCOLOR_YELLOW + SKINCOLOR_PURPLE,8, // 32 // SKINCOLOR_CANARY + SKINCOLOR_INDIGO,8, // 33 // SKINCOLOR_OLIVE + SKINCOLOR_AQUA,8, // 34 // SKINCOLOR_GARDEN + SKINCOLOR_TANGERINE,8, // 35 // SKINCOLOR_LIME + SKINCOLOR_SALMON,8, // 36 // SKINCOLOR_TEA + SKINCOLOR_PINK,6, // 37 // SKINCOLOR_ARMY + SKINCOLOR_CYAN,8, // 38 // SKINCOLOR_PISTACHIO + SKINCOLOR_ROSE,8, // 39 // SKINCOLOR_MOSS + SKINCOLOR_RASPBERRY,6, // 40 // SKINCOLOR_MINT + SKINCOLOR_RED,8, // 41 // SKINCOLOR_GREEN + SKINCOLOR_VOMIT,8, // 42 // SKINCOLOR_ROBOHOOD + SKINCOLOR_CRIMSON,8, // 43 // SKINCOLOR_PINETREE + SKINCOLOR_RUBY,8, // 44 // SKINCOLOR_EMERALD + SKINCOLOR_SAPPHIRE,8, // 45 // SKINCOLOR_SWAMP + SKINCOLOR_GARDEN,10, // 46 // SKINCOLOR_AQUA + SKINCOLOR_CARAMEL,8, // 47 // SKINCOLOR_TEAL + SKINCOLOR_PISTACHIO,6, // 48 // SKINCOLOR_CYAN + SKINCOLOR_LILAC,8, // 49 // SKINCOLOR_CERULEAN + SKINCOLOR_PEACH,8, // 50 // SKINCOLOR_SLATE + SKINCOLOR_BRONZE,10, // 51 // SKINCOLOR_STEEL + SKINCOLOR_CREAMSICLE,8, // 52 // SKINCOLOR_PERIWINKLE + SKINCOLOR_ORANGE,8, // 53 // SKINCOLOR_BLUE + SKINCOLOR_SWAMP,8, // 54 // SKINCOLOR_SAPPHIRE + SKINCOLOR_PUMPKIN,8, // 55 // SKINCOLOR_BLUEBERRY + SKINCOLOR_ROSEWOOD,8, // 56 // SKINCOLOR_NAVY + SKINCOLOR_BURGUNDY,6, // 57 // SKINCOLOR_JET + SKINCOLOR_DAWN,8, // 58 // SKINCOLOR_DUSK + SKINCOLOR_CANARY,8, // 59 // SKINCOLOR_PURPLE + SKINCOLOR_GOLD,10, // 60 // SKINCOLOR_LAVENDER + SKINCOLOR_OLIVE,8, // 61 // SKINCOLOR_INDIGO + SKINCOLOR_YELLOW,8, // 62 // SKINCOLOR_BYZANTIUM + SKINCOLOR_CERULEAN,8 // 63 // SKINCOLOR_LILAC }; UINT8 colortranslations[MAXSKINCOLORS][16] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // SKINCOLOR_NONE - {120, 120, 120, 120, 0, 0, 0, 0, 1, 1, 2, 2, 4, 6, 8, 10}, // SKINCOLOR_IVORY - { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}, // SKINCOLOR_WHITE - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, // SKINCOLOR_SILVER + {120, 120, 120, 120, 0, 1, 3, 4, 6, 7, 10, 14, 18, 22, 25, 28}, // SKINCOLOR_IVORY + {120, 120, 0, 1, 3, 4, 6, 7, 9, 11, 13, 16, 19, 23, 26, 29}, // SKINCOLOR_WHITE + { 0, 1, 3, 5, 6, 8, 10, 11, 13, 15, 16, 18, 20, 24, 27, 30}, // SKINCOLOR_SILVER { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, // SKINCOLOR_CLOUDY - { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, // SKINCOLOR_GREY - { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, // SKINCOLOR_DARKGREY - { 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_BLACK - {120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127}, // SKINCOLOR_SALMON - {144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 151}, // SKINCOLOR_PINK - {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135}, // SKINCOLOR_LIGHTRED - {120, 121, 123, 124, 126, 127, 129, 130, 132, 133, 135, 136, 138, 139, 141, 143}, // SKINCOLOR_SHINYRED + { 8, 9, 10, 12, 13, 15, 16, 19, 19, 20, 21, 23, 25, 27, 29, 31}, // SKINCOLOR_GREY + { 16, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31}, // SKINCOLOR_NICKEL + { 16, 17, 19, 21, 22, 24, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31}, // SKINCOLOR_BLACK + {120, 120, 120, 121, 121, 122, 122, 123, 124, 125, 126, 128, 129, 131, 133, 135}, // SKINCOLOR_SALMON + {121, 121, 121, 121, 121, 122, 144, 145, 146, 147, 148, 149, 150, 150, 150, 151}, // SKINCOLOR_PINK + {144, 145, 146, 147, 148, 149, 150, 151, 134, 135, 136, 137, 138, 139, 140, 141}, // SKINCOLOR_ROSE + {120, 121, 122, 123, 124, 125, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139}, // SKINCOLOR_RASPBERRY {125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140}, // SKINCOLOR_RED - {144, 145, 146, 147, 148, 149, 150, 151, 134, 135, 136, 137, 138, 139, 140, 141}, // SKINCOLOR_DARKPINK - {136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142, 143, 143}, // SKINCOLOR_DARKRED - {120, 121, 122, 123, 124, 147, 88, 89, 149, 91, 92, 151, 94, 95, 152, 153}, // SKINCOLOR_DAWN - { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}, // SKINCOLOR_ORANGE - { 80, 81, 83, 85, 86, 88, 90, 91, 93, 95, 152, 153, 154, 156, 157, 159}, // SKINCOLOR_SHINYORANGE - { 88, 89, 90, 91, 92, 93, 94, 95, 152, 153, 154, 155, 156, 157, 158, 159}, // SKINCOLOR_DARKORANGE - {112, 113, 114, 115, 116, 117, 118, 119, 156, 156, 157, 157, 158, 158, 159, 159}, // SKINCOLOR_GOLDENBROWN - {152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, 159}, // SKINCOLOR_ROSEWOOD - {152, 153, 154, 155, 156, 157, 158, 159, 139, 140, 141, 142, 143, 31, 31, 31}, // SKINCOLOR_DARKROSEWOOD - { 3, 5, 7, 32, 9, 34, 36, 37, 39, 42, 45, 59, 60, 61, 62, 63}, // SKINCOLOR_SEPIA + {120, 121, 144, 146, 149, 132, 132, 133, 134, 135, 197, 197, 198, 198, 199, 255}, // SKINCOLOR_RUBY + {130, 131, 132, 133, 134, 136, 137, 138, 139, 139, 140, 140, 141, 141, 142, 143}, // SKINCOLOR_CRIMSON + {120, 121, 122, 123, 124, 147, 147, 148, 90, 91, 92, 93, 94, 95, 152, 154}, // SKINCOLOR_DAWN + {120, 120, 80, 80, 81, 82, 83, 83, 84, 85, 86, 88, 89, 91, 93, 95}, // SKINCOLOR_CREAMSICLE + { 80, 81, 82, 83, 84, 85, 86, 88, 89, 91, 94, 95, 154, 156, 158, 159}, // SKINCOLOR_ORANGE + { 84, 85, 86, 87, 88, 90, 92, 93, 94, 95, 152, 153, 154, 156, 157, 159}, // SKINCOLOR_PUMPKIN + { 90, 91, 92, 93, 94, 152, 153, 154, 155, 156, 157, 158, 159, 139, 141, 143}, // SKINCOLOR_ROSEWOOD + { 94, 95, 152, 153, 154, 156, 157, 159, 141, 141, 141, 142, 142, 143, 143, 31}, // SKINCOLOR_BURGUNDY + {112, 113, 114, 115, 116, 117, 118, 119, 156, 157, 158, 159, 141, 141, 142, 143}, // SKINCOLOR_BRONZE + { 0, 1, 3, 5, 7, 9, 34, 36, 38, 40, 42, 44, 60, 61, 62, 63}, // SKINCOLOR_SEPIA { 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}, // SKINCOLOR_BEIGE { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}, // SKINCOLOR_BROWN - { 57, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 28, 29, 30, 31}, // SKINCOLOR_LEATHER - { 97, 98, 99, 100, 101, 102, 103, 104, 113, 113, 114, 115, 115, 115, 116, 117}, // SKINCOLOR_YELLOW - { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}, // SKINCOLOR_PEACH - { 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87}, // SKINCOLOR_LIGHTORANGE - { 72, 73, 74, 75, 76, 77, 78, 79, 48, 49, 50, 51, 52, 53, 54, 55}, // SKINCOLOR_CARAMEL - {112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119}, // SKINCOLOR_GOLD - { 64, 66, 68, 70, 72, 74, 76, 78, 48, 50, 52, 54, 56, 58, 60, 62}, // SKINCOLOR_SHINYCARAMEL + { 51, 52, 53, 55, 56, 57, 58, 60, 61, 63, 28, 28, 29, 29, 30, 31}, // SKINCOLOR_LEATHER + { 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 48, 50, 53, 56, 59}, // SKINCOLOR_PEACH + { 64, 66, 68, 70, 72, 74, 76, 78, 48, 50, 52, 54, 56, 58, 60, 62}, // SKINCOLOR_CARAMEL + { 98, 98, 112, 112, 113, 113, 84, 85, 87, 89, 91, 93, 95, 153, 156, 159}, // SKINCOLOR_TANGERINE + {112, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119}, // SKINCOLOR_GOLD {121, 144, 145, 72, 73, 84, 114, 115, 107, 108, 109, 183, 223, 207, 30, 246}, // SKINCOLOR_VOMIT - { 98, 99, 112, 101, 113, 114, 106, 179, 180, 181, 182, 172, 183, 173, 174, 175}, // SKINCOLOR_GARDEN - {176, 176, 176, 176, 177, 177, 177, 177, 178, 178, 178, 178, 179, 179, 179, 179}, // SKINCOLOR_LIGHTARMY - {176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183}, // SKINCOLOR_ARMY - {176, 176, 177, 177, 178, 178, 179, 179, 166, 167, 168, 169, 170, 171, 172, 173}, // SKINCOLOR_PISTACHIO - {177, 177, 178, 178, 165, 165, 167, 167, 182, 182, 171, 171, 183, 183, 173, 173}, // SKINCOLOR_ROBOHOOD - {105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 31, 31}, // SKINCOLOR_OLIVE - {176, 177, 178, 179, 170, 181, 182, 183, 173, 173, 174, 174, 175, 175, 31, 31}, // SKINCOLOR_DARKARMY - {160, 160, 161, 161, 162, 162, 163, 163, 164, 164, 165, 165, 166, 166, 167, 167}, // SKINCOLOR_LIGHTGREEN - {184, 184, 184, 184, 185, 185, 185, 185, 186, 186, 186, 186, 187, 187, 187, 187}, // SKINCOLOR_UGLYGREEN - {184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190, 190, 191, 191}, // SKINCOLOR_NEONGREEN + { 96, 97, 98, 100, 101, 102, 104, 113, 114, 115, 116, 117, 118, 119, 156, 159}, // SKINCOLOR_YELLOW + { 96, 97, 99, 100, 102, 104, 105, 105, 106, 107, 107, 108, 109, 109, 110, 111}, // SKINCOLOR_CANARY + {105, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 31}, // SKINCOLOR_OLIVE + { 98, 99, 112, 101, 113, 114, 106, 179, 180, 180, 181, 182, 183, 173, 174, 175}, // SKINCOLOR_GARDEN + { 96, 97, 99, 100, 102, 104, 160, 162, 164, 166, 168, 171, 223, 223, 207, 31}, // SKINCOLOR_LIME + {120, 120, 176, 176, 176, 177, 177, 178, 178, 179, 180, 180, 181, 181, 182, 183}, // SKINCOLOR_TEA + {176, 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183}, // SKINCOLOR_ARMY + {120, 120, 176, 176, 177, 177, 178, 179, 165, 166, 167, 168, 169, 170, 171, 172}, // SKINCOLOR_PISTACHIO + {178, 178, 178, 179, 179, 180, 181, 182, 183, 172, 172, 173, 173, 174, 174, 175}, // SKINCOLOR_MOSS + {120, 176, 176, 176, 177, 163, 164, 165, 167, 221, 221, 222, 223, 207, 207, 31}, // SKINCOLOR_MINT {160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175}, // SKINCOLOR_GREEN - {168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 173, 173, 174, 174, 175, 175}, // SKINCOLOR_DARKGREEN - {187, 187, 188, 188, 189, 189, 190, 190, 191, 191, 175, 175, 30, 30, 31, 31}, // SKINCOLOR_SWAMP - {224, 225, 226, 212, 213, 213, 214, 215, 220, 221, 172, 222, 173, 223, 174, 175}, // SKINCOLOR_FROST - {200, 200, 200, 200, 201, 201, 201, 201, 202, 202, 202, 202, 203, 203, 203, 203}, // SKINCOLOR_SLATE - {224, 224, 225, 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231}, // SKINCOLOR_LIGHTBLUE - {208, 208, 209, 210, 210, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 219}, // SKINCOLOR_CYAN - {216, 216, 216, 216, 217, 217, 217, 217, 218, 218, 218, 218, 219, 219, 219, 219}, // SKINCOLOR_CERULEAN - {208, 208, 209, 210, 210, 211, 212, 213, 213, 214, 215, 220, 220, 221, 222, 223}, // SKINCOLOR_TURQOISE - {220, 220, 220, 220, 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223}, // SKINCOLOR_TEAL - {200, 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207}, // SKINCOLOR_STEELBLUE + {176, 176, 177, 178, 165, 166, 167, 167, 168, 169, 182, 182, 182, 183, 183, 183}, // SKINCOLOR_ROBOHOOD + {160, 161, 162, 164, 165, 167, 169, 170, 171, 171, 172, 173, 174, 175, 30, 31}, // SKINCOLOR_PINETREE + {160, 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190, 191, 175}, // SKINCOLOR_EMERALD + {186, 187, 188, 188, 188, 189, 189, 190, 190, 191, 175, 175, 30, 30, 31, 31}, // SKINCOLOR_SWAMP + {120, 208, 208, 210, 212, 214, 220, 220, 220, 221, 221, 222, 222, 223, 223, 191}, // SKINCOLOR_AQUA + {210, 213, 220, 220, 220, 221, 221, 221, 221, 222, 222, 222, 223, 223, 191, 31}, // SKINCOLOR_TEAL + {120, 208, 209, 210, 211, 212, 213, 215, 216, 216, 216, 217, 217, 218, 218, 219}, // SKINCOLOR_CYAN + {208, 209, 211, 213, 215, 216, 216, 217, 217, 218, 218, 219, 205, 206, 207, 207}, // SKINCOLOR_CERULEAN + {120, 120, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 204, 205, 206, 207}, // SKINCOLOR_SLATE + {120, 200, 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 207, 31}, // SKINCOLOR_STEEL + {120, 224, 225, 226, 226, 227, 228, 228, 229, 230, 231, 234, 235, 237, 239, 241}, // SKINCOLOR_PERIWINKLE {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239}, // SKINCOLOR_BLUE - {224, 225, 226, 228, 229, 231, 232, 234, 235, 237, 238, 240, 241, 243, 244, 246}, // SKINCOLOR_SHINYBLUE - {200, 201, 202, 203, 204, 205, 206, 238, 239, 240, 241, 242, 243, 244, 245, 246}, // SKINCOLOR_NAVY - {231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246}, // SKINCOLOR_DARKBLUE - {200, 201, 202, 203, 204, 205, 206, 207, 28, 28, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_JETBLACK - {120, 120, 121, 121, 122, 122, 123, 123, 192, 192, 248, 248, 249, 249, 250, 250}, // SKINCOLOR_LILAC - {192, 192, 193, 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199, 199}, // SKINCOLOR_PURPLE - {248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255}, // SKINCOLOR_LAVENDER - {192, 248, 249, 250, 251, 252, 253, 254, 255, 255, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_BYZANTIUM + {208, 209, 211, 213, 215, 217, 229, 230, 232, 234, 236, 238, 240, 242, 244, 246}, // SKINCOLOR_SAPPHIRE + {228, 229, 230, 231, 232, 233, 234, 235, 237, 238, 239, 240, 242, 243, 244, 245}, // SKINCOLOR_BLUEBERRY + {215, 216, 217, 218, 204, 205, 206, 237, 238, 239, 240, 241, 242, 243, 244, 245}, // SKINCOLOR_NAVY + {200, 201, 202, 203, 204, 205, 206, 207, 28, 28, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_JET + {192, 192, 248, 249, 250, 251, 204, 204, 205, 205, 206, 206, 207, 29, 30, 31}, // SKINCOLOR_DUSK + {192, 192, 192, 193, 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199}, // SKINCOLOR_PURPLE + {248, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255}, // SKINCOLOR_LAVENDER {192, 193, 194, 195, 196, 197, 198, 199, 255, 255, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_INDIGO + {192, 248, 249, 250, 251, 252, 253, 254, 255, 255, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_BYZANTIUM + {120, 120, 120, 121, 121, 122, 122, 123, 192, 248, 249, 250, 251, 252, 253, 254}, // SKINCOLOR_LILAC /* Removed Colours - {192, 192, 248, 249, 250, 251, 229, 204, 230, 205, 206, 239, 240, 241, 242, 243}, // SKINCOLOR_DUSK - { 1, 145, 125, 73, 83, 114, 106, 180, 187, 168, 219, 205, 236, 206, 199, 255}, // SKINCOLOR_RAINBOW + {120, 121, 123, 124, 126, 127, 129, 130, 132, 133, 135, 136, 138, 139, 141, 143}, // SKINCOLOR_RUBY, removed for other colors + { 80, 81, 83, 85, 86, 88, 90, 91, 93, 95, 152, 153, 154, 156, 157, 159}, // SKINCOLOR_AMBER, removed for other colors + {224, 225, 226, 228, 229, 231, 232, 234, 235, 237, 238, 240, 241, 243, 244, 246}, // SKINCOLOR_SAPPHIRE, removed for other colors + {160, 160, 160, 184, 184, 184, 185, 185, 185, 186, 187, 187, 188, 188, 189, 190}, // SKINCOLOR_JADE, removed for other colors + {224, 225, 226, 212, 213, 213, 214, 215, 220, 221, 172, 222, 173, 223, 174, 175}, // SKINCOLOR_FROST, merged into Aqua + { 72, 73, 74, 75, 76, 77, 78, 79, 48, 49, 50, 51, 52, 53, 54, 55}, // SKINCOLOR_CARAMEL, new Caramel was previously Shiny Caramel + { 1, 145, 125, 73, 83, 114, 106, 180, 187, 168, 219, 205, 236, 206, 199, 255}, // SKINCOLOR_RAINBOW, is Vomit 2.0 */ }; -/** \brief Generates the starman colourmaps that are used when a player has the invincibility power +/** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power \param dest_colormap colormap to populate \param skincolor translation color */ -void K_StarmanColormap(UINT8 *dest_colormap, UINT8 skincolor) +void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) { INT32 i, j; RGBA_t color; @@ -250,9 +327,9 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) return; } - else if (skinnum == TC_STARMAN) + else if (skinnum == TC_RAINBOW) { - K_StarmanColormap(dest_colormap, color); + K_RainbowColormap(dest_colormap, color); return; } @@ -296,38 +373,44 @@ UINT8 K_GetKartColorByName(const char *name) void K_RegisterKartStuff(void) { - CV_RegisterVar(&cv_magnet); - CV_RegisterVar(&cv_boo); - CV_RegisterVar(&cv_mushroom); - CV_RegisterVar(&cv_triplemushroom); - CV_RegisterVar(&cv_megashroom); - CV_RegisterVar(&cv_goldshroom); - CV_RegisterVar(&cv_star); - CV_RegisterVar(&cv_triplebanana); - CV_RegisterVar(&cv_fakeitem); + CV_RegisterVar(&cv_sneaker); + CV_RegisterVar(&cv_rocketsneaker); + CV_RegisterVar(&cv_invincibility); CV_RegisterVar(&cv_banana); - CV_RegisterVar(&cv_greenshell); - CV_RegisterVar(&cv_redshell); - CV_RegisterVar(&cv_laserwisp); - CV_RegisterVar(&cv_triplegreenshell); - CV_RegisterVar(&cv_bobomb); - CV_RegisterVar(&cv_blueshell); - CV_RegisterVar(&cv_jaws); - CV_RegisterVar(&cv_fireflower); - CV_RegisterVar(&cv_tripleredshell); - CV_RegisterVar(&cv_lightning); - CV_RegisterVar(&cv_feather); + CV_RegisterVar(&cv_eggmanmonitor); + CV_RegisterVar(&cv_orbinaut); + CV_RegisterVar(&cv_jawz); + CV_RegisterVar(&cv_mine); + CV_RegisterVar(&cv_ballhog); + CV_RegisterVar(&cv_selfpropelledbomb); + CV_RegisterVar(&cv_grow); + CV_RegisterVar(&cv_shrink); + CV_RegisterVar(&cv_lightningshield); + CV_RegisterVar(&cv_hyudoro); + CV_RegisterVar(&cv_pogospring); + + CV_RegisterVar(&cv_triplesneaker); + CV_RegisterVar(&cv_triplebanana); + CV_RegisterVar(&cv_tripleorbinaut); + CV_RegisterVar(&cv_dualjawz); CV_RegisterVar(&cv_kartminimap); CV_RegisterVar(&cv_kartcheck); - CV_RegisterVar(&cv_kartstarsfx); + CV_RegisterVar(&cv_kartinvinsfx); CV_RegisterVar(&cv_kartspeed); - CV_RegisterVar(&cv_kartballoons); + CV_RegisterVar(&cv_kartbumpers); CV_RegisterVar(&cv_kartfrantic); CV_RegisterVar(&cv_kartcomeback); CV_RegisterVar(&cv_kartmirror); - CV_RegisterVar(&cv_speedometer); + CV_RegisterVar(&cv_kartspeedometer); + CV_RegisterVar(&cv_kartvoices); + CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_votetime); + + CV_RegisterVar(&cv_kartdebugitem); + CV_RegisterVar(&cv_kartdebugamount); + CV_RegisterVar(&cv_kartdebugcheckpoint); + CV_RegisterVar(&cv_kartdebugshrink); } //} @@ -342,8 +425,10 @@ boolean K_IsPlayerLosing(player_t *player) for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator) - pcount++; + if (!playeringame[i] || players[i].spectator) + continue; + if (players[i].kartstuff[k_position] > pcount) + pcount = players[i].kartstuff[k_position]; } if (pcount <= 1) @@ -356,151 +441,120 @@ boolean K_IsPlayerLosing(player_t *player) return (player->kartstuff[k_position] > winningpos); } +boolean K_IsPlayerWanted(player_t *player) +{ + UINT8 i; + if (!(G_BattleGametype())) + return false; + for (i = 0; i < 4; i++) + { + if (battlewanted[i] == -1) + break; + if (player == &players[battlewanted[i]]) + return true; + } + return false; +} + //{ SRB2kart Roulette Code - Position Based -#define NUMKARTITEMS 19 -#define NUMKARTODDS 40 +#define NUMKARTODDS 80 // Less ugly 2D arrays -static INT32 K_KartItemOddsDistance_Retro[NUMKARTITEMS][9] = +static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] = { //P-Odds 0 1 2 3 4 5 6 7 8 - /*Magnet*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Magnet - /*Boo*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0 }, // Boo - /*Mushroom*/ {20, 0, 0, 3, 7, 6, 0, 0, 0 }, // Mushroom - /*Triple Mushroom*/ { 0, 0, 0, 0, 3, 8, 7, 4, 0 }, // Triple Mushroom - /*Mega Mushroom*/ { 0, 0, 0, 0, 0, 0, 1, 1, 2 }, // Mega Mushroom - /*Gold Mushroom*/ { 0, 0, 0, 0, 0, 3, 5, 4, 0 }, // Gold Mushroom - /*Star*/ { 0, 0, 0, 0, 0, 1, 6, 9,18 }, // Star - - /*Triple Banana*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Triple Banana - /*Fake Item*/ { 0, 4, 2, 1, 0, 0, 0, 0, 0 }, // Fake Item + /*Sneaker*/ {20, 0, 0, 3, 5, 5, 0, 0, 0 }, // Sneaker + /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 2, 5, 4, 0 }, // Rocket Sneaker + /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 5, 6,16 }, // Invincibility /*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana - /*Green Shell*/ { 0, 6, 4, 3, 2, 0, 0, 0, 0 }, // Green Shell - /*Red Shell*/ { 0, 0, 3, 2, 2, 1, 0, 0, 0 }, // Red Shell - /*Triple Green Shell*/ { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, // Triple Green Shell - /*Bob-omb*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Bob-omb - /*Blue Shell*/ { 0, 0, 1, 2, 4, 3, 1, 0, 0 }, // Blue Shell - /*Fire Flower*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Fire Flower - /*Triple Red Shell*/ { 0, 0, 0, 1, 1, 0, 0, 0, 0 }, // Triple Red Shell - /*Lightning*/ { 0, 0, 0, 0, 0, 0, 1, 2, 0 }, // Lightning - - /*Feather*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Feather + /*Eggman Monitor*/ { 0, 4, 3, 2, 0, 0, 0, 0, 0 }, // Eggman Monitor + /*Orbinaut*/ { 0, 6, 5, 4, 2, 0, 0, 0, 0 }, // Orbinaut + /*Jawz*/ { 0, 0, 3, 2, 2, 1, 0, 0, 0 }, // Jawz + /*Mine*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Mine + /*Ballhog*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Ballhog + /*Self-Propelled Bomb*/ { 0, 0, 1, 1, 1, 2, 2, 3, 2 }, // Self-Propelled Bomb + /*Grow*/ { 0, 0, 0, 0, 1, 2, 4, 6, 4 }, // Grow + /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 1, 0 }, // Shrink + /*Lightning Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Lightning Shield + /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro + /*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring + /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink + /*Sneaker x3*/ { 0, 0, 0, 0, 3, 6, 5, 3, 0 }, // Sneaker x3 + /*Banana x3*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 + /*Banana x10*/ { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10 + /*Orbinaut x3*/ { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, // Orbinaut x3 + /*Jawz x2*/ { 0, 0, 0, 1, 1, 0, 0, 0, 0 } // Jawz x2 }; -static INT32 K_KartItemOddsBalloons[NUMKARTITEMS][6] = +static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] = { - //P-Odds 0 1 2 3 4 5 - /*Magnet*/ { 0, 0, 0, 0, 0, 0 }, // Magnet - /*Boo*/ { 0, 0, 1, 1, 0, 0 }, // Boo - /*Mushroom*/ { 3, 1, 2, 2, 0, 2 }, // Mushroom - /*Triple Mushroom*/ { 3, 0, 0, 0, 0, 2 }, // Triple Mushroom - /*Mega Mushroom*/ { 4, 2, 0, 0, 0, 2 }, // Mega Mushroom - /*Gold Mushroom*/ { 0, 0, 0, 0, 0, 0 }, // Gold Mushroom - /*Star*/ { 4, 2, 1, 0, 0, 2 }, // Star - - /*Triple Banana*/ { 0, 2, 2, 1, 1, 2 }, // Triple Banana - /*Fake Item*/ { 0, 0, 2, 2, 3, 0 }, // Fake Item - /*Banana*/ { 0, 0, 2, 3, 6, 0 }, // Banana - /*Green Shell*/ { 0, 0, 3, 5,10, 0 }, // Green Shell - /*Red Shell*/ { 3, 3, 2, 1, 0, 2 }, // Red Shell - /*Triple Green Shell*/ { 0, 3, 1, 1, 0, 2 }, // Triple Green Shell - /*Bob-omb*/ { 0, 3, 2, 1, 0, 2 }, // Bob-omb - /*Blue Shell*/ { 0, 0, 0, 0, 0, 0 }, // Blue Shell - /*Fire Flower*/ { 0, 2, 1, 1, 0, 2 }, // Fire Flower - /*Triple Red Shell*/ { 3, 2, 0, 0, 0, 2 }, // Triple Red Shell - /*Lightning*/ { 0, 0, 0, 0, 0, 0 }, // Lightning - - /*Feather*/ { 0, 0, 1, 2, 0, 0 } // Feather + //P-Odds 0 1 2 3 + /*Sneaker*/ { 3, 2, 2, 2 }, // Sneaker + /*Rocket Sneaker*/ { 0, 0, 0, 0 }, // Rocket Sneaker + /*Invincibility*/ { 4, 2, 1, 2 }, // Invincibility + /*Banana*/ { 0, 0, 2, 0 }, // Banana + /*Eggman Monitor*/ { 0, 0, 1, 0 }, // Eggman Monitor + /*Orbinaut*/ { 0, 1, 4, 0 }, // Orbinaut + /*Jawz*/ { 1, 3, 2, 2 }, // Jawz + /*Mine*/ { 1, 3, 2, 2 }, // Mine + /*Ballhog*/ { 1, 2, 2, 2 }, // Ballhog + /*Self-Propelled Bomb*/ { 0, 0, 0, 0 }, // Self-Propelled Bomb + /*Grow*/ { 4, 2, 0, 2 }, // Grow + /*Shrink*/ { 0, 0, 0, 0 }, // Shrink + /*Lightning Shield*/ { 0, 0, 0, 0 }, // Lightning Shield + /*Hyudoro*/ { 0, 0, 1, 0 }, // Hyudoro + /*Pogo Spring*/ { 0, 0, 1, 0 }, // Pogo Spring + /*Kitchen Sink*/ { 0, 0, 0, 0 }, // Kitchen Sink + /*Sneaker x3*/ { 2, 0, 0, 2 }, // Sneaker x3 + /*Banana x3*/ { 0, 1, 1, 1 }, // Banana x3 + /*Banana x10*/ { 1, 0, 0, 1 }, // Banana x10 + /*Orbinaut x3*/ { 0, 2, 1, 2 }, // Orbinaut x3 + /*Jawz x2*/ { 3, 2, 0, 2 } // Jawz x2 }; /** \brief Item Roulette for Kart \param player player \param getitem what item we're looking for - \param retrokart whether or not we're getting old or new item odds \return void */ -static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retrokart) +static void K_KartGetItemResult(player_t *player, SINT8 getitem) { switch (getitem) { - case 1: // Magnet - player->kartstuff[k_magnet] = 1; + // Special roulettes first, then the generic ones are handled by default + case KRITEM_TRIPLESNEAKER: // Sneaker x3 + player->kartstuff[k_itemtype] = KITEM_SNEAKER; + player->kartstuff[k_itemamount] = 3; break; - case 2: // Boo - player->kartstuff[k_boo] = 1; + case KRITEM_TRIPLEBANANA: // Banana x3 + player->kartstuff[k_itemtype] = KITEM_BANANA; + player->kartstuff[k_itemamount] = 3; break; - case 4: // Triple Mushroom - player->kartstuff[k_mushroom] = 4; + case KRITEM_TENFOLDBANANA: // Banana x10 + player->kartstuff[k_itemtype] = KITEM_BANANA; + player->kartstuff[k_itemamount] = 10; break; - case 5: // Mega Mushroom - player->kartstuff[k_megashroom] = 1; + case KRITEM_TRIPLEORBINAUT: // Orbinaut x3 + player->kartstuff[k_itemtype] = KITEM_ORBINAUT; + player->kartstuff[k_itemamount] = 3; break; - case 6: // Gold Mushroom - player->kartstuff[k_goldshroom] = 1; + case KRITEM_DUALJAWZ: // Jawz x2 + player->kartstuff[k_itemtype] = KITEM_JAWZ; + player->kartstuff[k_itemamount] = 2; break; - case 7: // Star - player->kartstuff[k_star] = 1; - break; - case 8: // Triple Banana - player->kartstuff[k_triplebanana] |= 8; - break; - case 9: // Fake Item - player->kartstuff[k_fakeitem] |= 2; - break; - case 10: // Banana - player->kartstuff[k_banana] |= 2; - break; - case 11: // Green Shell - player->kartstuff[k_greenshell] |= 2; - break; - case 12: // Red Shell - player->kartstuff[k_redshell] |= 2; - break; - case 13: // Triple Green Shell - or - Laser Wisp - if (retrokart) - player->kartstuff[k_triplegreenshell] |= 8; + default: + if (getitem <= 0 || getitem >= NUMKARTRESULTS) // Sad (Fallback) + { + if (getitem != 0) + CONS_Printf("ERROR: P_KartGetItemResult - Item roulette gave bad item (%d) :(\n", getitem); + player->kartstuff[k_itemtype] = KITEM_SAD; + } else - player->kartstuff[k_laserwisp] = 1; - break; - case 14: // Bob-omb - or - 3x Orbinaut (Triple Green Shell) - if (retrokart) - player->kartstuff[k_bobomb] |= 2; - else - player->kartstuff[k_triplegreenshell] |= 8; - break; - case 15: // Blue Shell - or - Specialstage Mines (Bob-omb) - if (retrokart) - player->kartstuff[k_blueshell] = 1; - else - player->kartstuff[k_bobomb] |= 2; - lightningcooldown = 20*TICRATE; - break; - case 16: // Fire Flower - or - Deton (Blue Shell) - if (retrokart) - player->kartstuff[k_fireflower] = 1; - else - player->kartstuff[k_blueshell] |= 4; - break; - case 17: // Triple Red Shell - or - 2x Jaws - if (retrokart) - player->kartstuff[k_tripleredshell] |= 8; - else - player->kartstuff[k_jaws] = 1; - break; - case 18: // Lightning - player->kartstuff[k_lightning] = 1; - lightningcooldown = 20*TICRATE; - break; - case 19: // Feather - player->kartstuff[k_feather] |= 1; - break; - default: // Mushroom - Doing it here as a fail-safe - if (getitem != 3) - CONS_Printf("ERROR: P_KartGetItemResult - Item roulette gave bad item (%d), giving Mushroom instead.\n", getitem); - player->kartstuff[k_mushroom] = 1; + player->kartstuff[k_itemtype] = getitem; + player->kartstuff[k_itemamount] = 1; break; } } @@ -512,45 +566,177 @@ static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retro \return void */ -static INT32 K_KartGetItemOdds(INT32 pos, INT32 itemnum, boolean mashed) +static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) { + const INT32 distvar = (64*14); INT32 newodds; + INT32 i; + UINT8 pingame = 0, pexiting = 0, pinvin = 0; + SINT8 first = -1, second = -1; + INT32 secondist = 0; if (G_BattleGametype()) - newodds = K_KartItemOddsBalloons[itemnum-1][pos]; + newodds = K_KartItemOddsBattle[item-1][pos]; else - newodds = K_KartItemOddsDistance_Retro[itemnum-1][pos]; + newodds = K_KartItemOddsRace[item-1][pos]; - if (itemnum == 1 || itemnum == 4 || itemnum == 5 || itemnum == 6 - || itemnum == 7 || itemnum == 8 || itemnum == 12 || itemnum == 13 || itemnum == 14 || itemnum == 15 - || itemnum == 16 || itemnum == 17 || itemnum == 18) // Powerful items! + for (i = 0; i < MAXPLAYERS; i++) { - if (franticitems) - newodds *= 2; - if (mashed) - newodds /= 2; + if (!playeringame[i] || players[i].spectator) + continue; + + pingame++; + if (players[i].exiting) + pexiting++; + if (players[i].mo) + { + if (players[i].kartstuff[k_position] == 1 && first == -1) + first = i; + if (players[i].kartstuff[k_position] == 2 && second == -1) + second = i; + if (players[i].kartstuff[k_itemtype] == KITEM_INVINCIBILITY + || players[i].kartstuff[k_itemtype] == KITEM_GROW + || players[i].kartstuff[k_invincibilitytimer] + || players[i].kartstuff[k_growshrinktimer] > 0) + pinvin++; + } } + if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB + { + secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x, + players[first].mo->y - players[second].mo->y), + players[first].mo->z - players[second].mo->z) / mapheaderinfo[gamemap-1]->mobj_scale; + if (franticitems) + secondist = (15*secondist/14); + if (pingame < 6 && !G_BattleGametype()) + secondist = ((28+(6-pingame))*secondist/28); + } + + // POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items. + // First, it multiplies it by 2 if franticitems is true; easy-peasy. + // Then, it multiplies it further if there's less than 5 players in game. + // This is done to make low player count races more fair & interesting. (1v1s are basically the same as franticitems false in a normal race) + // Lastly, it *divides* it by your mashed value, which was determined in K_KartItemRoulette, to punish those who are impatient. + // The last two are very fractional and complicated, very sorry! +#define POWERITEMODDS(odds) \ + if (franticitems) \ + odds *= 2; \ + if (pingame < 6 && !G_BattleGametype()) \ + odds = FixedMul(odds*FRACUNIT, FRACUNIT+min((6-pingame)*(FRACUNIT/25), FRACUNIT))/FRACUNIT; \ + if (mashed > 0) \ + odds = FixedDiv(odds*FRACUNIT, mashed+FRACUNIT)/FRACUNIT \ + + switch (item) + { + case KITEM_SNEAKER: + if ((!cv_sneaker.value) && (!modeattacking)) newodds = 0; + break; + case KITEM_ROCKETSNEAKER: + POWERITEMODDS(newodds); + if (!cv_rocketsneaker.value) newodds = 0; + break; + case KITEM_INVINCIBILITY: + POWERITEMODDS(newodds); + if ((!cv_invincibility.value) || (pinvin > 2)) newodds = 0; + break; + case KITEM_BANANA: + if (!cv_banana.value) newodds = 0; + break; + case KITEM_EGGMAN: + if (!cv_eggmanmonitor.value) newodds = 0; + break; + case KITEM_ORBINAUT: + if (!cv_orbinaut.value) newodds = 0; + break; + case KITEM_JAWZ: + POWERITEMODDS(newodds); + if (!cv_jawz.value) newodds = 0; + break; + case KITEM_MINE: + POWERITEMODDS(newodds); + if (!cv_mine.value) newodds = 0; + break; + case KITEM_BALLHOG: + POWERITEMODDS(newodds); + if (!cv_ballhog.value) newodds = 0; + break; + case KITEM_SPB: + POWERITEMODDS(newodds); + if ((!cv_selfpropelledbomb.value) + || (indirectitemcooldown > 0) + || (pexiting > 0) + || (secondist/distvar < (4+gamespeed))) + newodds = 0; + newodds *= min((secondist/distvar)-(3+gamespeed), 3); + break; + case KITEM_GROW: + POWERITEMODDS(newodds); + if ((!cv_grow.value) || (pinvin > 2)) newodds = 0; + break; + case KITEM_SHRINK: + POWERITEMODDS(newodds); + if ((!cv_shrink.value) + || (indirectitemcooldown > 0) + || (pingame-1 <= pexiting)) newodds = 0; + break; + case KITEM_LIGHTNINGSHIELD: + POWERITEMODDS(newodds); + if (!cv_lightningshield.value) newodds = 0; + break; + case KITEM_HYUDORO: + if (!cv_hyudoro.value) newodds = 0; + break; + case KITEM_POGOSPRING: + if (!cv_pogospring.value) newodds = 0; + break; + case KITEM_KITCHENSINK: + newodds = 0; // Not obtained via normal means. + break; + case KRITEM_TRIPLESNEAKER: + POWERITEMODDS(newodds); + if (!cv_triplesneaker.value) newodds = 0; + break; + case KRITEM_TRIPLEBANANA: + POWERITEMODDS(newodds); + if (!cv_triplebanana.value) newodds = 0; + break; + case KRITEM_TENFOLDBANANA: + POWERITEMODDS(newodds); + if (!cv_triplebanana.value) newodds = 0; + break; + case KRITEM_TRIPLEORBINAUT: + POWERITEMODDS(newodds); + if (!cv_tripleorbinaut.value) newodds = 0; + break; + case KRITEM_DUALJAWZ: + POWERITEMODDS(newodds); + if (!cv_dualjawz.value) newodds = 0; + break; + default: + break; + } +#undef POWERITEMODDS + return newodds; } //{ SRB2kart Roulette Code - Distance Based, no waypoints -static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) +static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) { + const INT32 distvar = (64*14); INT32 i; - INT32 pingame = 0, pexiting = 0; - INT32 roulettestop; - INT32 prandom; + UINT8 pingame = 0; + UINT8 roulettestop; INT32 pdis = 0, useodds = 0; - INT32 spawnchance[NUMKARTITEMS * NUMKARTODDS]; + INT32 spawnchance[NUMKARTRESULTS * NUMKARTODDS]; INT32 chance = 0, numchoices = 0; - INT32 distvar = (64*14); - INT32 avgballoon = 0; - INT32 secondist = 0; - SINT8 first = -1; - SINT8 second = -1; - boolean mashed = false; + INT32 avgbumper = 0; + boolean oddsvalid[9]; + UINT8 disttable[14]; + UINT8 distlen = 0; + fixed_t mashed = 0; // This makes the roulette cycle through items - if this is 0, you shouldn't be here. if (player->kartstuff[k_itemroulette]) @@ -558,147 +744,183 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) else return; - // This makes the roulette produce the random noises. - if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player)) - S_StartSound(NULL,sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8)); - - roulettestop = (TICRATE*1) + (3*(pingame - player->kartstuff[k_position])); - - // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. - // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. - // Finally, if you get past this check, now you can actually start calculating what item you get. - if ((cmd->buttons & BT_ATTACK) && player->kartstuff[k_itemroulette] >= roulettestop) - mashed = true; // Mashing halves your chances for the good items - else if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) - return; - - if (cmd->buttons & BT_ATTACK) - player->pflags |= PF_ATTACKDOWN; - - // Initializes existing spawnchance values - for (i = 0; i < (NUMKARTITEMS * NUMKARTODDS); i++) - spawnchance[i] = 0; - // Gotta check how many players are active at this moment. for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) continue; pingame++; - if (players[i].exiting) - pexiting++; - if (players[i].kartstuff[k_balloon] > 0) - avgballoon += players[i].kartstuff[k_balloon]; + if (players[i].kartstuff[k_bumper] > 0) + avgbumper += players[i].kartstuff[k_bumper]; } if (pingame) - avgballoon /= pingame; + avgbumper /= pingame; + + // This makes the roulette produce the random noises. + if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8)); + + roulettestop = (TICRATE*1) + (3*(pingame - player->kartstuff[k_position])); + + // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. + // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. + // Finally, if you get past this check, now you can actually start calculating what item you get. + if ((cmd->buttons & BT_ATTACK) && !(player->kartstuff[k_eggmanheld] || player->kartstuff[k_itemheld]) && player->kartstuff[k_itemroulette] >= roulettestop) + { + // Mashing reduces your chances for the good items + mashed = FixedDiv((player->kartstuff[k_itemroulette])*FRACUNIT, ((TICRATE*3)+roulettestop)*FRACUNIT) - FRACUNIT; + } + else if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) + return; + + if (cmd->buttons & BT_ATTACK) + player->pflags |= PF_ATTACKDOWN; + + if (cv_kartdebugitem.value != 0) + { + K_KartGetItemResult(player, cv_kartdebugitem.value); + player->kartstuff[k_itemamount] = cv_kartdebugamount.value; + player->kartstuff[k_itemroulette] = 0; + return; + } + + // Initializes existing spawnchance values + for (i = 0; i < (NUMKARTRESULTS * NUMKARTODDS); i++) + spawnchance[i] = 0; + + for (i = 0; i < 9; i++) + { + INT32 j; + boolean available = false; + + if (G_BattleGametype() && i > 5) + { + oddsvalid[i] = false; + break; + } + + for (j = 0; j < NUMKARTRESULTS; j++) + { + if (K_KartGetItemOdds(i, j, mashed) > 0) + { + available = true; + break; + } + } + + oddsvalid[i] = available; + } for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator && players[i].mo) - { - if (players[i].kartstuff[k_position] < player->kartstuff[k_position]) - pdis += P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x, - players[i].mo->y - player->mo->y), - players[i].mo->z - player->mo->z) / mapheaderinfo[gamemap-1]->mobj_scale - * (pingame - players[i].kartstuff[k_position]) - / ((pingame - 1) * (pingame + 1) / 3); - if (players[i].kartstuff[k_position] == 1 && first == -1) - first = i; - if (players[i].kartstuff[k_position] == 2 && second == -1) - second = i; - } + if (playeringame[i] && !players[i].spectator && players[i].mo + && players[i].kartstuff[k_position] < player->kartstuff[k_position]) + pdis += P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x, + players[i].mo->y - player->mo->y), + players[i].mo->z - player->mo->z) / mapheaderinfo[gamemap-1]->mobj_scale + * (pingame - players[i].kartstuff[k_position]) + / ((pingame - 1) * (pingame + 1) / 3); } - if (first != -1 && second != -1 && !secondist) // calculate 2nd's distance from 1st, for blue shell - secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x, - players[first].mo->y - players[second].mo->y), - players[first].mo->z - players[second].mo->z) / mapheaderinfo[gamemap-1]->mobj_scale - * (pingame - 1) - / ((pingame - 1) * (pingame + 1) / 3); - - player->kartstuff[k_itemclose] = 0; // Reset the item window closer. +#define SETUPDISTTABLE(odds, num) \ + for (i = num; i; --i) disttable[distlen++] = odds if (G_BattleGametype()) // Battle Mode { - if (player->kartstuff[k_roulettetype] == 1) - useodds = 5; + if (oddsvalid[0]) SETUPDISTTABLE(0,1); + if (oddsvalid[1]) SETUPDISTTABLE(1,1); + if (oddsvalid[2]) SETUPDISTTABLE(2,1); + + if (player->kartstuff[k_roulettetype] == 1 && oddsvalid[3]) // Player-controlled "Karma" items + useodds = 3; else { - useodds = (player->kartstuff[k_balloon]-avgballoon)+2; // 0 is two balloons below average, 2 is average, 4 is two balloons above average - if (useodds > 4) - useodds = 4; - if (useodds < 0) - useodds = 0; + SINT8 wantedpos = (player->kartstuff[k_bumper]-avgbumper)+2; // 0 is two bumpers below average, 2 is average + if (wantedpos > 2) + wantedpos = 2; + if (wantedpos < 0) + wantedpos = 0; + useodds = disttable[(wantedpos * distlen) / 3]; } } else { - if (franticitems) // Frantic items make the distances between everyone artifically higher :P - { + if (oddsvalid[1]) SETUPDISTTABLE(1,1); + if (oddsvalid[2]) SETUPDISTTABLE(2,1); + if (oddsvalid[3]) SETUPDISTTABLE(3,1); + if (oddsvalid[4]) SETUPDISTTABLE(4,2); + if (oddsvalid[5]) SETUPDISTTABLE(5,2); + if (oddsvalid[6]) SETUPDISTTABLE(6,3); + if (oddsvalid[7]) SETUPDISTTABLE(7,3); + if (oddsvalid[8]) SETUPDISTTABLE(8,1); + + if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items pdis = (15*pdis/14); - secondist = (15*pdis/14); + if (pingame < 6 && !G_BattleGametype()) + pdis = ((28+(6-pingame))*pdis/28); + + if (pingame == 1 && oddsvalid[0]) // Record Attack, or just alone + useodds = 0; + else if (pdis <= 0) // (64*14) * 0 = 0 + useodds = disttable[0]; + else if (pdis > distvar * ((12 * distlen) / 14)) // (64*14) * 12 = 10752 + useodds = disttable[distlen-1]; + else + { + for (i = 1; i < 12; i++) + { + if (pdis <= distvar * ((i * distlen) / 14)) + { + useodds = disttable[((i * distlen) / 14)]; + break; + } + } } - if (pingame == 1) useodds = 0; // Record Attack, or just alone - else if (pdis <= distvar * 0) useodds = 1; // (64*14) * 0 = 0 - else if (pdis <= distvar * 1) useodds = 2; // (64*14) * 1 = 896 - else if (pdis <= distvar * 2) useodds = 3; // (64*14) * 2 = 1792 - else if (pdis <= distvar * 4) useodds = 4; // (64*14) * 4 = 3584 - else if (pdis <= distvar * 6) useodds = 5; // (64*14) * 6 = 5376 - else if (pdis <= distvar * 9) useodds = 6; // (64*14) * 9 = 8064 - else if (pdis <= distvar * 12) useodds = 7; // (64*14) * 12 = 10752 - else useodds = 8; } - //CONS_Printf("%d %d\n", secondist, distvar*2); +#undef SETUPDISTTABLE + + //CONS_Printf("Got useodds %d. (position: %d, distance: %d)\n", useodds, player->kartstuff[k_position], pdis); #define SETITEMRESULT(pos, itemnum) \ for (chance = 0; chance < K_KartGetItemOdds(pos, itemnum, mashed); chance++) \ spawnchance[numchoices++] = itemnum - // Check the game type to differentiate odds. - //if (gametype == GT_RETRO) - //{ - if (cv_magnet.value) SETITEMRESULT(useodds, 1); // Magnet - if (cv_boo.value) SETITEMRESULT(useodds, 2); // Boo - if (cv_mushroom.value || modeattacking) SETITEMRESULT(useodds, 3); // Mushroom - if (cv_triplemushroom.value) SETITEMRESULT(useodds, 4); // Triple Mushroom - if (cv_megashroom.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 5); // Mega Mushroom - if (cv_goldshroom.value) SETITEMRESULT(useodds, 6); // Gold Mushroom - if (cv_star.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 7); // Star - if (cv_triplebanana.value) SETITEMRESULT(useodds, 8); // Triple Banana - if (cv_fakeitem.value) SETITEMRESULT(useodds, 9); // Fake Item - if (cv_banana.value) SETITEMRESULT(useodds, 10); // Banana - if (cv_greenshell.value) SETITEMRESULT(useodds, 11); // Green Shell - if (cv_redshell.value) SETITEMRESULT(useodds, 12); // Red Shell - if (cv_triplegreenshell.value) SETITEMRESULT(useodds, 13); // Triple Green Shell - if (cv_bobomb.value) SETITEMRESULT(useodds, 14); // Bob-omb - if (cv_blueshell.value && pexiting == 0 - && (secondist > distvar*4) && !lightningcooldown) SETITEMRESULT(useodds, 15); // Blue Shell - if (cv_fireflower.value) SETITEMRESULT(useodds, 16); // Fire Flower - if (cv_tripleredshell.value) SETITEMRESULT(useodds, 17); // Triple Red Shell - if (cv_lightning.value && pingame > pexiting && !lightningcooldown) SETITEMRESULT(useodds, 18); // Lightning - if (cv_feather.value) SETITEMRESULT(useodds, 19); // Feather + SETITEMRESULT(useodds, KITEM_SNEAKER); // Sneaker + SETITEMRESULT(useodds, KITEM_ROCKETSNEAKER); // Rocket Sneaker + SETITEMRESULT(useodds, KITEM_INVINCIBILITY); // Invincibility + SETITEMRESULT(useodds, KITEM_BANANA); // Banana + SETITEMRESULT(useodds, KITEM_EGGMAN); // Eggman Monitor + SETITEMRESULT(useodds, KITEM_ORBINAUT); // Orbinaut + SETITEMRESULT(useodds, KITEM_JAWZ); // Jawz + SETITEMRESULT(useodds, KITEM_MINE); // Mine + SETITEMRESULT(useodds, KITEM_BALLHOG); // Ballhog + SETITEMRESULT(useodds, KITEM_SPB); // Self-Propelled Bomb + SETITEMRESULT(useodds, KITEM_GROW); // Grow + SETITEMRESULT(useodds, KITEM_SHRINK); // Shrink + SETITEMRESULT(useodds, KITEM_LIGHTNINGSHIELD); // Lightning Shield + SETITEMRESULT(useodds, KITEM_HYUDORO); // Hyudoro + SETITEMRESULT(useodds, KITEM_POGOSPRING); // Pogo Spring + //SETITEMRESULT(useodds, KITEM_KITCHENSINK); // Kitchen Sink - prandom = P_RandomKey(numchoices); - - // Award the player whatever power is rolled - if (numchoices > 0) - K_KartGetItemResult(player, spawnchance[prandom], true); - else - CONS_Printf("ERROR: P_KartItemRoulette - There were no choices given by the roulette (useodds = %d).\n", useodds); - //} - /*else if (gametype == GT_NEO) - { - - } - else - CONS_Printf("ERROR: P_KartItemRoulette - There's no applicable game type!\n"); - */ + SETITEMRESULT(useodds, KRITEM_TRIPLESNEAKER); // Sneaker x3 + SETITEMRESULT(useodds, KRITEM_TRIPLEBANANA); // Banana x3 + SETITEMRESULT(useodds, KRITEM_TENFOLDBANANA); // Banana x10 + SETITEMRESULT(useodds, KRITEM_TRIPLEORBINAUT); // Orbinaut x3 + SETITEMRESULT(useodds, KRITEM_DUALJAWZ); // Jawz x2 #undef SETITEMRESULT + // Award the player whatever power is rolled + if (numchoices > 0) + K_KartGetItemResult(player, spawnchance[P_RandomKey(numchoices)]); + else + { + player->kartstuff[k_itemtype] = KITEM_SAD; + player->kartstuff[k_itemamount] = 1; + } + player->kartstuff[k_itemroulette] = 0; // Since we're done, clear the roulette number player->kartstuff[k_roulettetype] = 0; // This too @@ -710,11 +932,46 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) //{ SRB2kart p_user.c Stuff +static fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) +{ + fixed_t weight = 5<type) + { + case MT_PLAYER: + if (!mobj->player) + break; + if (against->player && !against->player->kartstuff[k_spinouttimer] && mobj->player->kartstuff[k_spinouttimer]) + weight = 0; // Do not bump + else + weight = (mobj->player->kartweight)<player) + weight = (against->player->kartweight)<player) + weight = (against->player->kartweight+3)<player && mobj2->player->playerstate != PST_LIVE)) return; - if ((mobj1->player && mobj1->player->kartstuff[k_lakitu]) - || (mobj2->player && mobj2->player->kartstuff[k_lakitu])) + if ((mobj1->player && mobj1->player->kartstuff[k_respawn]) + || (mobj2->player && mobj2->player->kartstuff[k_respawn])) return; // Don't bump if you've recently bumped - if ((mobj1->player && mobj1->player->kartstuff[k_justbumped]) - || (mobj2->player && mobj1->player->kartstuff[k_justbumped])) + if (mobj1->player && mobj1->player->kartstuff[k_justbumped]) { - if (mobj1->player) - mobj1->player->kartstuff[k_justbumped] = bumptime; - if (mobj2->player) - mobj2->player->kartstuff[k_justbumped] = bumptime; + mobj1->player->kartstuff[k_justbumped] = bumptime; return; } - S_StartSound(mobj1, sfx_s3k49); - - fx = P_SpawnMobj(mobj1->x/2 + mobj2->x/2, mobj1->y/2 + mobj2->y/2, mobj1->z/2 + mobj2->z/2, MT_BUMP); - if (mobj1->eflags & MFE_VERTICALFLIP) - fx->eflags |= MFE_VERTICALFLIP; - else - fx->eflags &= ~MFE_VERTICALFLIP; - fx->scale = mobj1->scale; - - if (bounce == true) // Perform a Goomba Bounce. - mobj1->momz = -mobj1->momz; - else + if (mobj2->player && mobj2->player->kartstuff[k_justbumped]) { - fixed_t newz = mobj1->momz; - mobj1->momz = mobj2->momz; - if (solid == false) - mobj2->momz = newz; + mobj2->player->kartstuff[k_justbumped] = bumptime; + return; } - mass1 = mass2 = 5*FRACUNIT; + mass1 = K_GetMobjWeight(mobj1, mobj2); - if (mobj1->player) - mass1 = (mobj1->player->kartweight)*FRACUNIT; - - if (mobj2->player) - mass2 = (mobj2->player->kartweight)*FRACUNIT; - else if (solid == true) + if (solid == true && mass1 > 0) mass2 = mass1; + else + mass2 = K_GetMobjWeight(mobj2, mobj1); momdifx = mobj1->momx - mobj2->momx; momdify = mobj1->momy - mobj2->momy; @@ -783,8 +1020,19 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) momdify = FixedMul((25*mapheaderinfo[gamemap-1]->mobj_scale), normalisedy); } - distx = mobj1->x - mobj2->x; - disty = mobj1->y - mobj2->y; + /*if (mass1 == 0 && mass2 > 0) + { + nobumpx = mobj2->momx; + nobumpy = mobj2->momy; + } + else if (mass2 == 0 && mass1 > 0) + { + nobumpx = mobj1->momx; + nobumpy = mobj1->momy; + }*/ + + distx = (mobj1->x + mobj2->momx) - (mobj2->x + mobj1->momx); + disty = (mobj1->y + mobj2->momy) - (mobj2->y + mobj1->momy); if (distx == 0 && disty == 0) { @@ -802,15 +1050,39 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) p = FixedDiv(dot, FixedMul(distx, distx)+FixedMul(disty, disty)); - mobj1->momx = mobj1->momx - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), p), distx); - mobj1->momy = mobj1->momy - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), p), disty); + if (bounce == true && mass2 > 0) // Perform a Goomba Bounce. + mobj1->momz = -mobj1->momz; + else + { + fixed_t newz = mobj1->momz; + if (mass2 > 0) + mobj1->momz = mobj2->momz; + if (mass1 > 0 && solid == false) + mobj2->momz = newz; + } - if (solid == false) + if (mass2 > 0) + { + mobj1->momx = mobj1->momx - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), p), distx); + mobj1->momy = mobj1->momy - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), p), disty); + } + + if (mass1 > 0 && solid == false) { mobj2->momx = mobj2->momx - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), p), -distx); mobj2->momy = mobj2->momy - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), p), -disty); } + // Do the bump fx when we've CONFIRMED we can bump. + S_StartSound(mobj1, sfx_s3k49); + + fx = P_SpawnMobj(mobj1->x/2 + mobj2->x/2, mobj1->y/2 + mobj2->y/2, mobj1->z/2 + mobj2->z/2, MT_BUMP); + if (mobj1->eflags & MFE_VERTICALFLIP) + fx->eflags |= MFE_VERTICALFLIP; + else + fx->eflags &= ~MFE_VERTICALFLIP; + fx->scale = mobj1->scale; + // Because this is done during collision now, rmomx and rmomy need to be recalculated // so that friction doesn't immediately decide to stop the player if they're at a standstill // Also set justbumped here @@ -819,6 +1091,11 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) mobj1->player->rmomx = mobj1->momx - mobj1->player->cmomx; mobj1->player->rmomy = mobj1->momy - mobj1->player->cmomy; mobj1->player->kartstuff[k_justbumped] = bumptime; + if (mobj1->player->kartstuff[k_spinouttimer]) + { + mobj1->player->kartstuff[k_wipeoutslow] += wipeoutslowtime+1; + mobj1->player->kartstuff[k_spinouttimer] += wipeoutslowtime+1; + } } if (mobj2->player) @@ -826,6 +1103,11 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) mobj2->player->rmomx = mobj2->momx - mobj2->player->cmomx; mobj2->player->rmomy = mobj2->momy - mobj2->player->cmomy; mobj2->player->kartstuff[k_justbumped] = bumptime; + if (mobj2->player->kartstuff[k_spinouttimer]) + { + mobj2->player->kartstuff[k_wipeoutslow] += wipeoutslowtime+1; + mobj2->player->kartstuff[k_spinouttimer] += wipeoutslowtime+1; + } } } @@ -894,7 +1176,7 @@ static void K_UpdateOffroad(player_t *player) // A higher kart weight means you can stay offroad for longer without losing speed offroad = (1872 + 5*156 - kartweight*156)*offroadstrength; - //if (player->kartstuff[k_growshrinktimer] > 1) // megashroom slows down half as fast + //if (player->kartstuff[k_growshrinktimer] > 1) // grow slows down half as fast // offroad /= 2; player->kartstuff[k_offroad] += offroad; @@ -907,51 +1189,59 @@ static void K_UpdateOffroad(player_t *player) player->kartstuff[k_offroad] = 0; } -/** \brief Calculates the lakitu timer and drop-boosting +/** \brief Calculates the respawn timer and drop-boosting \param player player object passed from K_KartPlayerThink \return void */ -void K_LakituChecker(player_t *player) +void K_RespawnChecker(player_t *player) { ticcmd_t *cmd = &player->cmd; - if (player->kartstuff[k_lakitu] == 44) - { - mobj_t *mo; - angle_t newangle; - fixed_t newx; - fixed_t newy; - fixed_t newz; - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 0); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 0); - if (player->mo->eflags & MFE_VERTICALFLIP) - newz = player->mo->z - 128*(mapheaderinfo[gamemap-1]->mobj_scale); - else - newz = player->mo->z + 64*(mapheaderinfo[gamemap-1]->mobj_scale); - mo = P_SpawnMobj(newx, newy, newz, MT_LAKITU); - if (mo) - { - if (player->mo->eflags & MFE_VERTICALFLIP) - mo->eflags |= MFE_VERTICALFLIP; - mo->angle = newangle+ANGLE_180; - P_SetTarget(&mo->target, player->mo); - } - } + if (player->spectator) + return; - if (player->kartstuff[k_lakitu] > 3) + if (player->kartstuff[k_respawn] > 3) { - player->kartstuff[k_lakitu]--; + player->kartstuff[k_respawn]--; player->mo->momz = 0; player->powers[pw_flashing] = 2; player->powers[pw_nocontrol] = 2; - if (leveltime % 15 == 0) - S_StartSound(player->mo, sfx_lkt3); + if (leveltime % 8 == 0) + { + INT32 i; + if (!mapreset) + S_StartSound(player->mo, sfx_s3kcas); + + for (i = 0; i < 8; i++) + { + mobj_t *mo; + angle_t newangle; + fixed_t newx, newy, newz; + + newangle = FixedAngle(((360/8)*i)*FRACUNIT); + newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31*player->mo->scale); + newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31*player->mo->scale); + if (player->mo->eflags & MFE_VERTICALFLIP) + newz = player->mo->z + player->mo->height; + else + newz = player->mo->z; + + mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER); + if (mo) + { + if (player->mo->eflags & MFE_VERTICALFLIP) + mo->eflags |= MFE_VERTICALFLIP; + P_SetTarget(&mo->target, player->mo); + mo->angle = newangle+ANGLE_90; + mo->momz = (8*FRACUNIT)*P_MobjFlip(player->mo); + } + } + } } - // That's enough pointless fishing for now. - if (player->kartstuff[k_lakitu] > 0 && player->kartstuff[k_lakitu] <= 3) + + if (player->kartstuff[k_respawn] > 0 && player->kartstuff[k_respawn] <= 3) { if (!P_IsObjectOnGround(player->mo)) { @@ -961,15 +1251,15 @@ void K_LakituChecker(player_t *player) if (cmd->buttons & BT_ACCELERATE) { player->powers[pw_flashing] = 0; - player->kartstuff[k_lakitu] = 0; + player->kartstuff[k_respawn] = 0; } } else { - player->kartstuff[k_lakitu]--; + player->kartstuff[k_respawn]--; // Quick! You only have three tics to boost! if (cmd->buttons & BT_ACCELERATE) - K_DoMushroom(player, true); + K_DoSneaker(player, true); } } } @@ -1027,51 +1317,91 @@ void K_KartMoveAnimation(player_t *player) } } +static void K_TauntVoiceTimers(player_t *player) +{ + if (!player) + return; + + player->kartstuff[k_tauntvoices] = 6*TICRATE; + player->kartstuff[k_voices] = 4*TICRATE; +} + +static void K_RegularVoiceTimers(player_t *player) +{ + if (!player) + return; + + player->kartstuff[k_voices] = 4*TICRATE; + + if (player->kartstuff[k_tauntvoices] < 4*TICRATE) + player->kartstuff[k_tauntvoices] = 4*TICRATE; +} + static void K_PlayTauntSound(mobj_t *source) { +#if 1 + sfxenum_t pick = P_RandomKey(4); // Gotta roll the RNG every time this is called for sync reasons + boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]); + + if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2)) + S_StartSound(source, sfx_taunt1+pick); + + if (!tasteful) + return; + + K_TauntVoiceTimers(source->player); +#else if (source->player && source->player->kartstuff[k_tauntvoices]) // Prevents taunt sounds from playing every time the button is pressed return; S_StartSound(source, sfx_taunt1+P_RandomKey(4)); - if (source->player) - { - source->player->kartstuff[k_tauntvoices] = 6*TICRATE; - source->player->kartstuff[k_voices] = 3*TICRATE; - } + K_TauntVoiceTimers(source->player); +#endif } static void K_PlayOvertakeSound(mobj_t *source) { - if (source->player && source->player->kartstuff[k_voices]) // Prevents taunt sounds from playing every time the button is pressed +#if 1 + boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]); + + if (!G_RaceGametype()) // Only in race return; // 4 seconds from before race begins, 10 seconds afterwards - if (leveltime < 14*TICRATE) + if (leveltime < starttime+(10*TICRATE)) + return; + + if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2)) + S_StartSound(source, sfx_slow); + + if (!tasteful) + return; + + K_RegularVoiceTimers(source->player); +#else + if (source->player && source->player->kartstuff[k_voices]) // Prevents taunt sounds from playing every time the button is pressed + return; + + if (!G_RaceGametype()) // Only in race + return; + + // 4 seconds from before race begins, 10 seconds afterwards + if (leveltime < starttime+(10*TICRATE)) return; S_StartSound(source, sfx_slow); - if (source->player) - { - source->player->kartstuff[k_voices] = 3*TICRATE; - - if (source->player->kartstuff[k_tauntvoices] < 3*TICRATE) - source->player->kartstuff[k_tauntvoices] = 3*TICRATE; - } + K_RegularVoiceTimers(source->player); +#endif } static void K_PlayHitEmSound(mobj_t *source) { - S_StartSound(source, sfx_hitem); + if (cv_kartvoices.value) + S_StartSound(source, sfx_hitem); - if (source->player) - { - source->player->kartstuff[k_voices] = 3*TICRATE; - - if (source->player->kartstuff[k_tauntvoices] < 3*TICRATE) - source->player->kartstuff[k_tauntvoices] = 3*TICRATE; - } + K_RegularVoiceTimers(source->player); } void K_MomentumToFacing(player_t *player) @@ -1082,7 +1412,9 @@ void K_MomentumToFacing(player_t *player) dangle = InvAngle(dangle); // If you aren't on the ground or are moving in too different of a direction don't do this - if (!P_IsObjectOnGround(player->mo) || dangle > ANGLE_90) + if (player->mo->eflags & MFE_JUSTHITFLOOR) + ; // Just hit floor ALWAYS redirects + else if (!P_IsObjectOnGround(player->mo) || dangle > ANGLE_90) return; P_Thrust(player->mo, player->mo->angle, player->speed - FixedMul(player->speed, player->mo->friction)); @@ -1096,30 +1428,26 @@ static fixed_t K_GetKartBoostPower(player_t *player, boolean speed) fixed_t boostpower = FRACUNIT; fixed_t boostvalue = 0; - // Offroad is separate, it's difficult to factor it in with a variable value anyway. - if (!(player->kartstuff[k_startimer] || player->kartstuff[k_bootimer] || player->kartstuff[k_mushroomtimer]) - && player->kartstuff[k_offroad] >= 0 && speed) - boostpower = FixedDiv(boostpower, player->kartstuff[k_offroad] + FRACUNIT); + if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow] == 1) // Slow down after you've been bumped + return 0; - if (player->kartstuff[k_growshrinktimer] > 1 - && (player->kartstuff[k_growshrinktimer] > ((itemtime + TICRATE*2) - 25) - || player->kartstuff[k_growshrinktimer] <= 26)) - { // Mega Mushroom - Mid-size - if (speed) - { - boostvalue = max(boostvalue, FRACUNIT/8); // + 12.5% - } - } - if (player->kartstuff[k_growshrinktimer] < ((itemtime + TICRATE*2) - 25) - && player->kartstuff[k_growshrinktimer] > 26) - { // Mega Mushroom + // Offroad is separate, it's difficult to factor it in with a variable value anyway. + if (!(player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_hyudorotimer] || player->kartstuff[k_sneakertimer]) + && player->kartstuff[k_offroad] >= 0 && speed) + boostpower = FixedDiv(boostpower, player->kartstuff[k_offroad] + FRACUNIT); + + if (player->kartstuff[k_bananadrag] > TICRATE) + boostpower = 4*boostpower/5; + + if (player->kartstuff[k_growshrinktimer] > 0) + { // Grow if (speed) { boostvalue = max(boostvalue, FRACUNIT/5); // + 20% } } - if (player->kartstuff[k_startimer]) - { // Star + if (player->kartstuff[k_invincibilitytimer]) + { // Invincibility if (speed) boostvalue = max(boostvalue, 3*(FRACUNIT/8)); // + 37.5% else @@ -1132,8 +1460,8 @@ static fixed_t K_GetKartBoostPower(player_t *player, boolean speed) else boostvalue = max(boostvalue, 4*FRACUNIT); // + 400% } - if (player->kartstuff[k_mushroomtimer]) - { // Mushroom + if (player->kartstuff[k_sneakertimer]) + { // Sneaker if (speed) { switch (gamespeed) @@ -1166,6 +1494,9 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) UINT8 kartspeed = player->kartspeed; fixed_t finalspeed; + if (doboostpower && !player->kartstuff[k_pogospring] && !P_IsObjectOnGround(player->mo)) + return (75*mapheaderinfo[gamemap-1]->mobj_scale); // air speed cap + switch (gamespeed) { case 0: @@ -1179,7 +1510,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) break; } - if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) + if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) kartspeed = 1; k_speed += kartspeed*3; // 153 - 177 @@ -1196,7 +1527,7 @@ fixed_t K_GetKartAccel(player_t *player) fixed_t k_accel = 32; // 36; UINT8 kartspeed = player->kartspeed; - if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) + if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) kartspeed = 1; //k_accel += 3 * (9 - kartspeed); // 36 - 60 @@ -1225,18 +1556,22 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove if (!onground) return 0; // If the player isn't on the ground, there is no change in speed - if (forwardmove <= 0 && player->kartstuff[k_brakestop] < 6) // Don't start reversing with brakes until you've made a stop first - { - if (player->speed < 8*FRACUNIT) - player->kartstuff[k_brakestop]++; - return 0; - } - else if (forwardmove > 0) - player->kartstuff[k_brakestop] = 0; - // ACCELCODE!!!1!11! oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale); newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION); + + if (player->kartstuff[k_pogospring]) // Pogo Spring minimum/maximum thrust + { + const fixed_t scale = mapheaderinfo[gamemap-1]->mobj_scale + abs(player->mo->scale - mapheaderinfo[gamemap-1]->mobj_scale); + const fixed_t minspeed = 24*scale; + const fixed_t maxspeed = 36*scale; + + if (newspeed > maxspeed && player->kartstuff[k_pogospring] == 2) + newspeed = maxspeed; + if (newspeed < minspeed) + newspeed = minspeed; + } + finalspeed = newspeed - oldspeed; // forwardmove is: @@ -1259,98 +1594,149 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove return finalspeed; } -void K_SpinPlayer(player_t *player, mobj_t *source) +void K_DoInstashield(player_t *player) { + mobj_t *layera; + mobj_t *layerb; + + if (player->kartstuff[k_instashield] > 0) + return; + + player->kartstuff[k_instashield] = 15; // length of instashield animation + S_StartSound(player->mo, sfx_cdpcm9); + + layera = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDA); + P_SetTarget(&layera->target, player->mo); + + layerb = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDB); + P_SetTarget(&layerb->target, player->mo); +} + +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem) +{ + const UINT8 scoremultiply = ((K_IsPlayerWanted(player) && !trapitem) ? 2 : 1); + if (player->health <= 0) return; - if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) - || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 - || (G_BattleGametype() && ((player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0 + || player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 + || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + { + K_DoInstashield(player); return; + } if (source && source != player->mo && source->player) K_PlayHitEmSound(source); - player->kartstuff[k_mushroomtimer] = 0; + //player->kartstuff[k_sneakertimer] = 0; player->kartstuff[k_driftboost] = 0; if (G_BattleGametype()) { if (source && source->player && player != source->player) - P_AddPlayerScore(source->player, 1); - - if (player->kartstuff[k_balloon] > 0) { - if (player->kartstuff[k_balloon] == 1) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); - player->kartstuff[k_balloon]--; + P_AddPlayerScore(source->player, scoremultiply); + if (!trapitem) + { + source->player->kartstuff[k_wanted] -= wantedreduce; + player->kartstuff[k_wanted] -= (wantedreduce/2); + } } - K_CheckBalloons(); + if (player->kartstuff[k_bumper] > 0) + { + if (player->kartstuff[k_bumper] == 1) + { + mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! + P_SetTarget(&karmahitbox->target, player->mo); + karmahitbox->destscale = player->mo->scale; + P_SetScale(karmahitbox, player->mo->scale); + CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + } + player->kartstuff[k_bumper]--; + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); + } + + K_CheckBumpers(); } player->kartstuff[k_comebacktimer] = comebacktime; + player->kartstuff[k_spinouttype] = type; + if (player->kartstuff[k_spinouttype] <= 0) { - if (player->kartstuff[k_spinouttype] == 0) - player->kartstuff[k_spinouttimer] = 3*TICRATE/2; // Explosion/Banana Wipeout - else - player->kartstuff[k_spinouttimer] = 3*TICRATE/2; // Oil Slick Wipeout + player->kartstuff[k_spinouttimer] = 3*TICRATE/2; // Banana Spinout - // At Wipeout, playerspeed is increased to 1/4 their regular speed, moving them forward + // At spinout, player speed is increased to 1/4 their regular speed, moving them forward if (player->speed < K_GetKartSpeed(player, true)/4) P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale)); S_StartSound(player->mo, sfx_slip); } else - player->kartstuff[k_spinouttimer] = 1*TICRATE; // ? Whipeout + player->kartstuff[k_spinouttimer] = TICRATE+20; // Wipeout player->powers[pw_flashing] = K_GetKartFlashing(); - player->kartstuff[k_spinout] = player->kartstuff[k_spinouttimer]; - if (player->mo->state != &states[S_KART_SPIN]) P_SetPlayerMobjState(player->mo, S_KART_SPIN); - player->kartstuff[k_spinouttype] = 0; - + player->kartstuff[k_instashield] = 15; return; } void K_SquishPlayer(player_t *player, mobj_t *source) { + const UINT8 scoremultiply = (K_IsPlayerWanted(player) ? 2 : 1); + if (player->health <= 0) return; - if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_startimer] > 0 - || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 - || (G_BattleGametype() && ((player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_invincibilitytimer] > 0 + || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 + || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + { + K_DoInstashield(player); return; + } - player->kartstuff[k_mushroomtimer] = 0; + player->kartstuff[k_sneakertimer] = 0; player->kartstuff[k_driftboost] = 0; if (G_BattleGametype()) { if (source && source->player && player != source->player) - P_AddPlayerScore(source->player, 1); - - if (player->kartstuff[k_balloon] > 0) { - if (player->kartstuff[k_balloon] == 1) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); - player->kartstuff[k_balloon]--; + P_AddPlayerScore(source->player, scoremultiply); + source->player->kartstuff[k_wanted] -= wantedreduce; + player->kartstuff[k_wanted] -= (wantedreduce/2); } - K_CheckBalloons(); + if (player->kartstuff[k_bumper] > 0) + { + if (player->kartstuff[k_bumper] == 1) + { + mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! + P_SetTarget(&karmahitbox->target, player->mo); + karmahitbox->destscale = player->mo->scale; + P_SetScale(karmahitbox, player->mo->scale); + CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + } + player->kartstuff[k_bumper]--; + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); + } + + K_CheckBumpers(); } player->kartstuff[k_comebacktimer] = comebacktime; - player->kartstuff[k_squishedtimer] = 1*TICRATE; + player->kartstuff[k_squishedtimer] = 2*TICRATE; player->powers[pw_flashing] = K_GetKartFlashing(); @@ -1361,63 +1747,68 @@ void K_SquishPlayer(player_t *player, mobj_t *source) P_PlayRinglossSound(player->mo); + player->kartstuff[k_instashield] = 15; return; } void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer { + const UINT8 scoremultiply = (K_IsPlayerWanted(player) ? 2 : 1); + if (player->health <= 0) return; - if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) - || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 - || (G_BattleGametype() && ((player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0 + || player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 + || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + { + K_DoInstashield(player); return; + } player->mo->momz = 18*(mapheaderinfo[gamemap-1]->mobj_scale); player->mo->momx = player->mo->momy = 0; - player->kartstuff[k_mushroomtimer] = 0; + player->kartstuff[k_sneakertimer] = 0; player->kartstuff[k_driftboost] = 0; if (G_BattleGametype()) { if (source && source->player && player != source->player) { - if (source->player->kartstuff[k_balloon] <= 0) - { - source->player->kartstuff[k_comebackpoints] += 2; - if (netgame && cv_hazardlog.value) - CONS_Printf(M_GetText("%s bombed %s!\n"), player_names[source->player-players], player_names[player-players]); - if (source->player->kartstuff[k_comebackpoints] >= 3) - K_StealBalloon(source->player, player, true); - } - P_AddPlayerScore(source->player, 1); + P_AddPlayerScore(source->player, scoremultiply); + source->player->kartstuff[k_wanted] -= wantedreduce; + player->kartstuff[k_wanted] -= (wantedreduce/2); } - if (player->kartstuff[k_balloon] > 0) + if (player->kartstuff[k_bumper] > 0) { - if (player->kartstuff[k_balloon] == 1) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); - player->kartstuff[k_balloon]--; + if (player->kartstuff[k_bumper] == 1) + { + mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! + P_SetTarget(&karmahitbox->target, player->mo); + karmahitbox->destscale = player->mo->scale; + P_SetScale(karmahitbox, player->mo->scale); + CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + } + player->kartstuff[k_bumper]--; + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); } - K_CheckBalloons(); + K_CheckBumpers(); } player->kartstuff[k_comebacktimer] = comebacktime; player->kartstuff[k_spinouttype] = 1; player->kartstuff[k_spinouttimer] = 2*TICRATE+(TICRATE/2); - player->kartstuff[k_spinout] = player->kartstuff[k_spinouttimer]; player->powers[pw_flashing] = K_GetKartFlashing(); if (player->mo->state != &states[S_KART_SPIN]) P_SetPlayerMobjState(player->mo, S_KART_SPIN); - player->kartstuff[k_spinouttype] = 0; - P_PlayRinglossSound(player->mo); if (P_IsLocalPlayer(player)) @@ -1426,12 +1817,13 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju quake.time = 5; } + player->kartstuff[k_instashield] = 15; return; } -void K_StealBalloon(player_t *player, player_t *victim, boolean force) +void K_StealBumper(player_t *player, player_t *victim, boolean force) { - INT32 newballoon; + INT32 newbumper; angle_t newangle, diff; fixed_t newx, newy; mobj_t *newmo; @@ -1442,54 +1834,57 @@ void K_StealBalloon(player_t *player, player_t *victim, boolean force) if (player->health <= 0 || victim->health <= 0) return; - if (force) - ; - else + if (!force) { - if (victim->kartstuff[k_balloon] <= 0) // || player->kartstuff[k_balloon] >= cv_kartballoons.value+2 + if (victim->kartstuff[k_bumper] <= 0) // || player->kartstuff[k_bumper] >= cv_kartbumpers.value+2 return; - if ((player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) - || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 - || (player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer])) - || (victim->powers[pw_flashing] > 0 || victim->kartstuff[k_squishedtimer] > 0 || (victim->kartstuff[k_spinouttimer] > 0 && victim->kartstuff[k_spinout] > 0) - || victim->kartstuff[k_startimer] > 0 || victim->kartstuff[k_growshrinktimer] > 0 || victim->kartstuff[k_bootimer] > 0)) + if (player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0) return; + + if (victim->powers[pw_flashing] > 0 || victim->kartstuff[k_squishedtimer] > 0 || victim->kartstuff[k_spinouttimer] > 0 + || victim->kartstuff[k_invincibilitytimer] > 0 || victim->kartstuff[k_growshrinktimer] > 0 || victim->kartstuff[k_hyudorotimer] > 0) + { + K_DoInstashield(victim); + return; + } } if (netgame) { - if (player->kartstuff[k_balloon] <= 0) + if (player->kartstuff[k_bumper] <= 0) CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); else if (cv_hazardlog.value) - CONS_Printf(M_GetText("%s stole a balloon from %s!\n"), player_names[player-players], player_names[victim-players]); + CONS_Printf(M_GetText("%s stole a bumper from %s!\n"), player_names[player-players], player_names[victim-players]); } - newballoon = player->kartstuff[k_balloon]; - if (newballoon <= 1) + newbumper = player->kartstuff[k_bumper]; + if (newbumper <= 1) diff = 0; else - diff = FixedAngle(360*FRACUNIT/newballoon); + diff = FixedAngle(360*FRACUNIT/newbumper); newangle = player->mo->angle; newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBALLOON); - newmo->threshold = newballoon; + newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER); + newmo->threshold = newbumper; P_SetTarget(&newmo->tracer, victim->mo); P_SetTarget(&newmo->target, player->mo); - newmo->angle = (diff * (newballoon-1)); + newmo->angle = (diff * (newbumper-1)); newmo->color = victim->skincolor; - if (newballoon+1 < 2) - P_SetMobjState(newmo, S_BATTLEBALLOON3); - else if (newballoon+1 < 3) - P_SetMobjState(newmo, S_BATTLEBALLOON2); + if (newbumper+1 < 2) + P_SetMobjState(newmo, S_BATTLEBUMPER3); + else if (newbumper+1 < 3) + P_SetMobjState(newmo, S_BATTLEBUMPER2); else - P_SetMobjState(newmo, S_BATTLEBALLOON1); + P_SetMobjState(newmo, S_BATTLEBUMPER1); - player->kartstuff[k_balloon]++; + S_StartSound(player->mo, sfx_3db06); + + player->kartstuff[k_bumper]++; player->kartstuff[k_comebackpoints] = 0; player->powers[pw_flashing] = K_GetKartFlashing(); player->kartstuff[k_comebacktimer] = comebacktime; @@ -1497,6 +1892,7 @@ void K_StealBalloon(player_t *player, player_t *victim, boolean force) /*victim->powers[pw_flashing] = K_GetKartFlashing(); victim->kartstuff[k_comebacktimer] = comebacktime;*/ + victim->kartstuff[k_instashield] = 15; return; } @@ -1585,15 +1981,15 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 } // Spawns the purely visual explosion -void K_SpawnBobombExplosion(mobj_t *source, UINT8 color) +void K_SpawnMineExplosion(mobj_t *source, UINT8 color) { INT32 i, radius, height; mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING); mobj_t *dust; mobj_t *truc; - smoldering->tics = TICRATE*3; INT32 speed, speed2; + smoldering->tics = TICRATE*3; radius = source->radius>>FRACBITS; height = source->height>>FRACBITS; @@ -1715,6 +2111,18 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle th->momx = FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); + if (type == MT_ORBINAUT) + { + if (source && source->player) + th->color = source->player->skincolor; + else + th->color = SKINCOLOR_CLOUDY; + } + else if (type == MT_JAWZ || type == MT_JAWZ_DUD) + { + S_StartSound(th, th->info->activesound); + } + x = x + P_ReturnThrustX(source, an, source->radius + th->radius); y = y + P_ReturnThrustY(source, an, source->radius + th->radius); throwmo = P_SpawnMobj(x, y, z, MT_FIREDITEM); @@ -1739,12 +2147,12 @@ void K_SpawnBoostTrail(player_t *player) I_Assert(!P_MobjWasRemoved(player->mo)); if (!P_IsObjectOnGround(player->mo) - || player->kartstuff[k_bootimer] != 0 - || (G_BattleGametype() && player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer])) + || player->kartstuff[k_hyudorotimer] != 0 + || (G_BattleGametype() && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])) return; if (player->mo->eflags & MFE_VERTICALFLIP) - ground = player->mo->ceilingz - FixedMul(mobjinfo[MT_MUSHROOMTRAIL].height, player->mo->scale); + ground = player->mo->ceilingz - FixedMul(mobjinfo[MT_SNEAKERTRAIL].height, player->mo->scale); else ground = player->mo->floorz; @@ -1762,10 +2170,10 @@ void K_SpawnBoostTrail(player_t *player) { ground = P_GetZAt(player->mo->standingslope, newx, newy); if (player->mo->eflags & MFE_VERTICALFLIP) - ground -= FixedMul(mobjinfo[MT_MUSHROOMTRAIL].height, player->mo->scale); + ground -= FixedMul(mobjinfo[MT_SNEAKERTRAIL].height, player->mo->scale); } #endif - flame = P_SpawnMobj(newx, newy, ground, MT_MUSHROOMTRAIL); + flame = P_SpawnMobj(newx, newy, ground, MT_SNEAKERTRAIL); P_SetTarget(&flame->target, player->mo); flame->angle = travelangle; @@ -1789,6 +2197,54 @@ void K_SpawnBoostTrail(player_t *player) } } +void K_SpawnSparkleTrail(mobj_t *mo) +{ + const INT32 rad = (mo->radius*2)>>FRACBITS; + mobj_t *sparkle; + INT32 i; + + I_Assert(mo != NULL); + I_Assert(!P_MobjWasRemoved(mo)); + + for (i = 0; i < 3; i++) + { + fixed_t newx = mo->x + mo->momx + (P_RandomRange(-rad, rad)<y + mo->momy + (P_RandomRange(-rad, rad)<z + mo->momz + (P_RandomRange(0, mo->height>>FRACBITS)<target, mo); + sparkle->destscale = mo->destscale; + P_SetScale(sparkle, mo->scale); + sparkle->eflags = (sparkle->eflags & ~MFE_VERTICALFLIP)|(mo->eflags & MFE_VERTICALFLIP); + sparkle->color = mo->color; + //sparkle->colorized = mo->colorized; + } +} + +void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent) +{ + mobj_t *dust; + + I_Assert(mo != NULL); + I_Assert(!P_MobjWasRemoved(mo)); + + dust = P_SpawnMobj(mo->x + (P_RandomRange(-25,25)<y + (P_RandomRange(-25,25)<z, MT_WIPEOUTTRAIL); + + P_SetTarget(&dust->target, mo); + dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy); + dust->destscale = mo->scale; + P_SetScale(dust, mo->scale); + dust->eflags = (dust->eflags & ~MFE_VERTICALFLIP)|(mo->eflags & MFE_VERTICALFLIP); + + if (translucent) + dust->flags2 |= MF2_SHADOW; +} + // K_DriftDustHandling // Parameters: // spawner: The map object that is spawning the drift dust @@ -1806,20 +2262,24 @@ void K_DriftDustHandling(mobj_t *spawner) if (spawner->player) { - angle_t playerangle; - - if (spawner->player->speed < 5<player->cmd.forwardmove < 0) + if (spawner->player->pflags & PF_SKIDDOWN) { - playerangle = spawner->angle+ANGLE_180; + anglediff = abs(spawner->angle - spawner->player->frameangle); + if (leveltime % 6 == 0) + S_StartSound(spawner, sfx_screec); // repeated here because it doesn't always happen to be within the range when this is the case } else { - playerangle = spawner->angle; + angle_t playerangle = spawner->angle; + + if (spawner->player->speed < 5<player->cmd.forwardmove < 0) + playerangle += ANGLE_180; + + anglediff = abs(playerangle - R_PointToAngle2(0, 0, spawner->player->rmomx, spawner->player->rmomy)); } - anglediff = abs(playerangle - R_PointToAngle2(0, 0, spawner->player->rmomx, spawner->player->rmomy)); } else { @@ -1838,25 +2298,73 @@ void K_DriftDustHandling(mobj_t *spawner) fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST); + if (spawner->eflags & MFE_VERTICALFLIP) + { + dust->z += spawner->height - dust->height; + } dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<momz = P_MobjFlip(spawner) * P_RandomRange(1, 4)<scale = spawner->scale/2; dust->destscale = spawner->scale * 3; + if (leveltime % 6 == 0) - { S_StartSound(spawner, sfx_screec); - } + + // Now time for a bunch of flag shit, groooooaann... + if (spawner->flags2 & MF2_DONTDRAW) + dust->flags2 |= MF2_DONTDRAW; + else + dust->flags2 &= ~MF2_DONTDRAW; + + if (spawner->eflags & MFE_VERTICALFLIP) + dust->eflags |= MFE_VERTICALFLIP; + else + dust->eflags &= ~MFE_VERTICALFLIP; + + if (spawner->eflags & MFE_DRAWONLYFORP1) + dust->eflags |= MFE_DRAWONLYFORP1; + else + dust->eflags &= ~MFE_DRAWONLYFORP1; + + if (spawner->eflags & MFE_DRAWONLYFORP2) + dust->eflags |= MFE_DRAWONLYFORP2; + else + dust->eflags &= ~MFE_DRAWONLYFORP2; + + if (spawner->eflags & MFE_DRAWONLYFORP3) + dust->eflags |= MFE_DRAWONLYFORP3; + else + dust->eflags &= ~MFE_DRAWONLYFORP3; + + if (spawner->eflags & MFE_DRAWONLYFORP4) + dust->eflags |= MFE_DRAWONLYFORP4; + else + dust->eflags &= ~MFE_DRAWONLYFORP4; } } -static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, boolean bobombthrow) +static mobj_t *K_FindLastTrailMobj(player_t *player) +{ + mobj_t *trail; + + if (!player || !(trail = player->mo) || !player->mo->hnext || !player->mo->hnext->health) + return NULL; + + while (trail->hnext && !P_MobjWasRemoved(trail->hnext) && trail->hnext->health) + { + trail = trail->hnext; + } + + return trail; +} + +static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, boolean minethrow) { mobj_t *mo; INT32 dir, PROJSPEED; angle_t newangle; - fixed_t newx; - fixed_t newy; + fixed_t newx, newy, newz; mobj_t *throwmo; if (!player) @@ -1876,11 +2384,11 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map break; } - if (bobombthrow) + if (minethrow) { if (player->kartstuff[k_throwdir] == 1) dir = 2; - else if (player->kartstuff[k_throwdir] == -1) + else if (player->kartstuff[k_throwdir] == -1 && mapthing != MT_SINK) dir = -1; else dir = 1; @@ -1893,9 +2401,9 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map dir = defaultDir; } - if (missile) + if (missile) // Shootables { - if (mapthing == MT_FIREBALL) // Messy + if (mapthing == MT_BALLHOG) // Messy { if (dir == -1) { @@ -1916,7 +2424,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + 0x06000000, 0, PROJSPEED); } } - else // Shells + else { if (dir == -1) { @@ -1966,15 +2474,29 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map } else { - fixed_t dropradius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(mobjinfo[mapthing].radius, mobjinfo[mapthing].radius); + mobj_t *lasttrail = K_FindLastTrailMobj(player); - // Drop it directly behind you. - newangle = player->mo->angle; + player->kartstuff[k_bananadrag] = 0; // RESET timer, for multiple bananas - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, dropradius); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, dropradius); + if (lasttrail) + { + newx = lasttrail->x; + newy = lasttrail->y; + newz = lasttrail->z; + } + else + { + // Drop it directly behind you. + fixed_t dropradius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(mobjinfo[mapthing].radius, mobjinfo[mapthing].radius); - mo = P_SpawnMobj(newx, newy, player->mo->z, mapthing); + newangle = player->mo->angle; + + newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, dropradius); + newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, dropradius); + newz = player->mo->z; + } + + mo = P_SpawnMobj(newx, newy, newz, mapthing); if (P_MobjFlip(player->mo) < 0) mo->z = player->mo->z + player->mo->height - mo->height; @@ -2011,22 +2533,24 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map } } } + return mo; } -static void K_DoMagnet(player_t *player) +static void K_DoLightningShield(player_t *player) { S_StartSound(player->mo, sfx_s3k45); - player->kartstuff[k_magnettimer] = 35; + player->kartstuff[k_attractiontimer] = 35; P_NukeEnemies(player->mo, player->mo, RING_DIST/4); } -static void K_DoBooSteal(player_t *player) +static void K_DoHyudoroSteal(player_t *player) { INT32 i, numplayers = 0; INT32 playerswappable[MAXPLAYERS]; INT32 stealplayer = -1; // The player that's getting stolen from INT32 prandom = 0; + fixed_t sink = P_RandomChance(FRACUNIT/64); for (i = 0; i < MAXPLAYERS; i++) { @@ -2034,28 +2558,13 @@ static void K_DoBooSteal(player_t *player) && player != &players[i] && !players[i].exiting && !players[i].spectator // Player in-game // Can steal from this player - && ((G_RaceGametype() && players[i].kartstuff[k_position] < player->kartstuff[k_position]) - || (G_BattleGametype() && players[i].kartstuff[k_balloon] > 0)) + && (G_RaceGametype() //&& players[i].kartstuff[k_position] < player->kartstuff[k_position]) + || (G_BattleGametype() && players[i].kartstuff[k_bumper] > 0)) // Has an item - && (players[i].kartstuff[k_magnet] - || players[i].kartstuff[k_mushroom] - || players[i].kartstuff[k_megashroom] - || players[i].kartstuff[k_goldshroom] - || players[i].kartstuff[k_star] - || players[i].kartstuff[k_banana] & 2 - || players[i].kartstuff[k_triplebanana] & 8 - || players[i].kartstuff[k_fakeitem] & 2 - || players[i].kartstuff[k_greenshell] & 2 - || players[i].kartstuff[k_triplegreenshell] & 8 - || players[i].kartstuff[k_redshell] & 2 - || players[i].kartstuff[k_tripleredshell] & 8 - || players[i].kartstuff[k_bobomb] & 2 - || players[i].kartstuff[k_lightning] - || players[i].kartstuff[k_blueshell] - || players[i].kartstuff[k_fireflower] - || players[i].kartstuff[k_feather] & 1 - || players[i].kartstuff[k_boo])) // Stealing boos with boos? sounds like fun + && (players[i].kartstuff[k_itemtype] + && players[i].kartstuff[k_itemamount] + && !players[i].kartstuff[k_itemheld])) { playerswappable[numplayers] = i; numplayers++; @@ -2063,12 +2572,22 @@ static void K_DoBooSteal(player_t *player) } prandom = P_RandomFixed(); + S_StartSound(player->mo, sfx_s3k92); - if ((G_RaceGametype() && player->kartstuff[k_position] == 1) || numplayers == 0) // No-one can be stolen from? Get longer invisibility for nothing + if (sink) // BEHOLD THE KITCHEN SINK { - player->kartstuff[k_bootimer] = bootime; - player->kartstuff[k_bootaketimer] = boostealtime; - player->kartstuff[k_boo] = 0; + player->kartstuff[k_hyudorotimer] = hyudorotime; + player->kartstuff[k_stealingtimer] = stealtime; + + player->kartstuff[k_itemtype] = KITEM_KITCHENSINK; + player->kartstuff[k_itemamount] = 1; + player->kartstuff[k_itemheld] = 0; + return; + } + else if ((G_RaceGametype() && player->kartstuff[k_position] == 1) || numplayers == 0) // No-one can be stolen from? Oh well... + { + player->kartstuff[k_hyudorotimer] = hyudorotime; + player->kartstuff[k_stealingtimer] = stealtime; return; } else if (numplayers == 1) // With just 2 players, we just need to set the other player to be the one to steal from @@ -2082,110 +2601,29 @@ static void K_DoBooSteal(player_t *player) if (stealplayer > -1) // Now here's where we do the stealing, has to be done here because we still know the player we're stealing from { - player->kartstuff[k_bootimer] = bootime; - player->kartstuff[k_bootaketimer] = boostealtime; - player->kartstuff[k_boo] = 0; - players[stealplayer].kartstuff[k_boostolentimer] = boostealtime; + player->kartstuff[k_hyudorotimer] = hyudorotime; + player->kartstuff[k_stealingtimer] = stealtime; + players[stealplayer].kartstuff[k_stolentimer] = stealtime; - if (players[stealplayer].kartstuff[k_star]) - { - player->kartstuff[k_star] = players[stealplayer].kartstuff[k_star]; - players[stealplayer].kartstuff[k_star] = 0; - } - else if (players[stealplayer].kartstuff[k_mushroom]) - { - player->kartstuff[k_mushroom] = players[stealplayer].kartstuff[k_mushroom]; - players[stealplayer].kartstuff[k_mushroom] = 0; - } - else if (players[stealplayer].kartstuff[k_goldshroom]) - { - player->kartstuff[k_goldshroom] = players[stealplayer].kartstuff[k_goldshroom]; - players[stealplayer].kartstuff[k_goldshroom] = 0; - } - else if (players[stealplayer].kartstuff[k_megashroom]) - { - player->kartstuff[k_megashroom] = players[stealplayer].kartstuff[k_megashroom]; - players[stealplayer].kartstuff[k_megashroom] = 0; - } - else if (players[stealplayer].kartstuff[k_lightning]) - { - player->kartstuff[k_lightning] = players[stealplayer].kartstuff[k_lightning]; - players[stealplayer].kartstuff[k_lightning] = 0; - } - else if (players[stealplayer].kartstuff[k_blueshell]) - { - player->kartstuff[k_blueshell] = players[stealplayer].kartstuff[k_blueshell]; - players[stealplayer].kartstuff[k_blueshell] = 0; - } - else if (players[stealplayer].kartstuff[k_greenshell] & 2) - { - player->kartstuff[k_greenshell] |= 2; - players[stealplayer].kartstuff[k_greenshell] &= ~2; - } - else if (players[stealplayer].kartstuff[k_triplegreenshell] & 8) - { - player->kartstuff[k_triplegreenshell] |= 8; - players[stealplayer].kartstuff[k_triplegreenshell] &= ~8; - } - else if (players[stealplayer].kartstuff[k_redshell] & 2) - { - player->kartstuff[k_redshell] |= 2; - players[stealplayer].kartstuff[k_redshell] &= ~2; - } - else if (players[stealplayer].kartstuff[k_tripleredshell] & 8) - { - player->kartstuff[k_tripleredshell] |= 8; - players[stealplayer].kartstuff[k_tripleredshell] &= ~8; - } - else if (players[stealplayer].kartstuff[k_banana] & 2) - { - player->kartstuff[k_banana] |= 2; - players[stealplayer].kartstuff[k_banana] &= ~2; - } - else if (players[stealplayer].kartstuff[k_triplebanana] & 8) - { - player->kartstuff[k_triplebanana] |= 8; - players[stealplayer].kartstuff[k_triplebanana] &= ~8; - } - else if (players[stealplayer].kartstuff[k_fakeitem] & 2) - { - player->kartstuff[k_fakeitem] |= 2; - players[stealplayer].kartstuff[k_fakeitem] &= ~2; - } - else if (players[stealplayer].kartstuff[k_bobomb] & 2) - { - player->kartstuff[k_bobomb] |= 2; - players[stealplayer].kartstuff[k_bobomb] &= ~2; - } - else if (players[stealplayer].kartstuff[k_magnet]) - { - player->kartstuff[k_magnet] = players[stealplayer].kartstuff[k_magnet]; - players[stealplayer].kartstuff[k_magnet] = 0; - } - else if (players[stealplayer].kartstuff[k_fireflower]) - { - player->kartstuff[k_fireflower] = players[stealplayer].kartstuff[k_fireflower]; - players[stealplayer].kartstuff[k_fireflower] = 0; - } - else if (players[stealplayer].kartstuff[k_feather] & 1) - { - player->kartstuff[k_feather] |= 1; - players[stealplayer].kartstuff[k_feather] &= ~1; - } - else if (players[stealplayer].kartstuff[k_boo]) - { - player->kartstuff[k_boo] = players[stealplayer].kartstuff[k_boo]; - players[stealplayer].kartstuff[k_boo] = 0; - } + player->kartstuff[k_itemtype] = players[stealplayer].kartstuff[k_itemtype]; + player->kartstuff[k_itemamount] = players[stealplayer].kartstuff[k_itemamount]; + player->kartstuff[k_itemheld] = 0; + + players[stealplayer].kartstuff[k_itemtype] = KITEM_NONE; + players[stealplayer].kartstuff[k_itemamount] = 0; + players[stealplayer].kartstuff[k_itemheld] = 0; + + if (P_IsLocalPlayer(&players[stealplayer]) && !splitscreen) + S_StartSound(NULL, sfx_s3k92); } } -void K_DoMushroom(player_t *player, boolean doPFlag) +void K_DoSneaker(player_t *player, boolean doPFlag) { if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) - S_StartSound(player->mo, sfx_mush); + S_StartSound(player->mo, sfx_cdfm01); - player->kartstuff[k_mushroomtimer] = mushroomtime; + player->kartstuff[k_sneakertimer] = sneakertime; if (doPFlag) player->pflags |= PF_ATTACKDOWN; @@ -2193,54 +2631,45 @@ void K_DoMushroom(player_t *player, boolean doPFlag) K_PlayTauntSound(player->mo); } -static void K_DoLightning(player_t *player) +static void K_DoShrink(player_t *player) { - mobj_t *mo; - thinker_t *think; INT32 i; - S_StartSound(player->mo, sfx_bkpoof); // Sound the BANG! + + S_StartSound(player->mo, sfx_kc46); // Sound the BANG! player->pflags |= PF_ATTACKDOWN; for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i]) - P_FlashPal(&players[i], PAL_NUKE, 10); - } + /*if (playeringame[i]) + P_FlashPal(&players[i], PAL_NUKE, 10);*/ - for (think = thinkercap.next; think != &thinkercap; think = think->next) - { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - - mo = (mobj_t *)think; - - if (mo->player && !mo->player->spectator - && mo->player->kartstuff[k_position] < player->kartstuff[k_position]) - P_DamageMobj(mo, player->mo, player->mo, 64); - else - continue; + if (playeringame[i] && players[i].mo && !player->spectator + && players[i].kartstuff[k_position] < player->kartstuff[k_position]) + P_DamageMobj(players[i].mo, player->mo, player->mo, 64); } K_PlayTauntSound(player->mo); } -static void K_DoBlueShell(player_t *victim, player_t *source) +static void K_DoSPB(player_t *victim, player_t *source) { - INT32 i; + //INT32 i; S_StartSound(victim->mo, sfx_bkpoof); // Sound the BANG! - for (i = 0; i < MAXPLAYERS; i++) + /*for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) P_FlashPal(&players[i], PAL_NUKE, 10); - } + }*/ if (victim->mo && !victim->spectator) P_DamageMobj(victim->mo, source->mo, source->mo, 65); } -void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed) +void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute) { + fixed_t scale = mapheaderinfo[gamemap-1]->mobj_scale + abs(mo->scale - mapheaderinfo[gamemap-1]->mobj_scale); + if (mo->player && mo->player->spectator) return; @@ -2267,26 +2696,250 @@ void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed) thrust = 48< 72<player->kartstuff[k_mushroomtimer]) - thrust = FixedMul(thrust, 5*FRACUNIT/4); - else if (mo->player->kartstuff[k_startimer]) - thrust = FixedMul(thrust, 9*FRACUNIT/8); - mo->momz = FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), FixedMul(thrust, mo->scale)); + if (mo->player->kartstuff[k_pogospring] != 2) + { + if (mo->player->kartstuff[k_sneakertimer]) + thrust = FixedMul(thrust, 5*FRACUNIT/4); + else if (mo->player->kartstuff[k_invincibilitytimer]) + thrust = FixedMul(thrust, 9*FRACUNIT/8); + } } else { - thrust = P_AproxDistance(mo->momx,mo->momy); - if (thrust < 8< 16<momx, mo->momy)/2, 5*FRACUNIT/2); + if (thrust < 16<momz = FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), FixedMul(thrust, mo->scale)); + if (thrust > 32<momz = FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), FixedMul(thrust, scale)); } else - mo->momz = FixedMul(vertispeed, mo->scale); + mo->momz = FixedMul(vertispeed, scale); - S_StartSound(mo, sfx_boing); + if (!mute) + S_StartSound(mo, sfx_kc2f); +} + +void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source) +{ + if (banana->hnext) + { + K_KillBananaChain(banana->hnext, inflictor, source); + } + + if (banana->health) + { + if (banana->eflags & MFE_VERTICALFLIP) + banana->z -= banana->height; + else + banana->z += banana->height; + + S_StartSound(banana, banana->info->deathsound); + P_KillMobj(banana, inflictor, source); + + P_SetObjectMomZ(banana, 8*FRACUNIT, false); + if (inflictor) + P_InstaThrust(banana, R_PointToAngle2(inflictor->x, inflictor->y, banana->x, banana->y)+ANGLE_90, 16*FRACUNIT); + } +} + +void K_RepairOrbitChain(mobj_t *orbit) +{ + mobj_t *cachenext = orbit->hnext; + + // First, repair the chain + if (orbit->hnext && orbit->hnext->health && !P_MobjWasRemoved(orbit->hnext)) + { + P_SetTarget(&orbit->hnext->hprev, orbit->hprev); + P_SetTarget(&orbit->hnext, NULL); + } + + if (orbit->hprev && orbit->hprev->health && !P_MobjWasRemoved(orbit->hprev)) + { + P_SetTarget(&orbit->hprev->hnext, cachenext); + P_SetTarget(&orbit->hprev, NULL); + } + + // Then recount to make sure item amount is correct + if (orbit->target && orbit->target->player) + { + INT32 num = 0; + + mobj_t *cur = orbit->target->hnext; + mobj_t *prev = NULL; + + while (cur && !P_MobjWasRemoved(cur)) + { + prev = cur; + cur = cur->hnext; + if (++num > orbit->target->player->kartstuff[k_itemamount]) + P_RemoveMobj(prev); + else + prev->movedir = num; + } + + if (orbit->target->player->kartstuff[k_itemamount] != num) + orbit->target->player->kartstuff[k_itemamount] = num; + } +} + +static void K_MoveHeldObjects(player_t *player) +{ + if (!player->mo) + return; + + if (!player->mo->hnext) + { + player->kartstuff[k_bananadrag] = 0; + return; + } + + switch (player->mo->hnext->type) + { + case MT_ORBINAUT_SHIELD: // Kart orbit items + case MT_JAWZ_SHIELD: + { + mobj_t *cur = player->mo->hnext; + + player->kartstuff[k_bananadrag] = 0; // Just to make sure + + while (cur && !P_MobjWasRemoved(cur)) + { + const fixed_t radius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(cur->radius, cur->radius); // mobj's distance from its Target, or Radius. + fixed_t z; + + if (!cur->health) + { + cur = cur->hnext; + continue; + } + + cur->color = player->skincolor; + + cur->angle -= ANGLE_90; + cur->angle += FixedAngle(cur->info->speed); + + // If the player is on the ceiling, then flip your items as well. + if (player && player->mo->eflags & MFE_VERTICALFLIP) + cur->eflags |= MFE_VERTICALFLIP; + else + cur->eflags &= ~MFE_VERTICALFLIP; + + // Shrink your items if the player shrunk too. + P_SetScale(cur, (cur->destscale = player->mo->scale)); + + if (P_MobjFlip(cur) > 0) + z = player->mo->z; + else + z = player->mo->z + player->mo->height - cur->height; + + cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player + P_TeleportMove(cur, player->mo->x, player->mo->y, z); + cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), radius); + cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), radius); + cur->flags &= ~MF_NOCLIPTHING; + if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true)) + P_SlideMove(cur, true); + if (P_IsObjectOnGround(player->mo)) + { + if (P_MobjFlip(cur) > 0) + { + if (cur->floorz > player->mo->z - cur->height) + z = cur->floorz; + } + else + { + if (cur->ceilingz < player->mo->z + player->mo->height + cur->height) + z = cur->ceilingz - cur->height; + } + } + cur->z = z; + cur->momx = cur->momy = 0; + cur->angle += ANGLE_90; + + cur = cur->hnext; + } + } + break; + case MT_BANANA_SHIELD: // Kart trailing items + case MT_SSMINE_SHIELD: + case MT_FAKESHIELD: + { + mobj_t *cur = player->mo->hnext; + mobj_t *targ = player->mo; + + if (P_IsObjectOnGround(player->mo) && player->speed > 0) + { + player->kartstuff[k_bananadrag]++; + if (player->kartstuff[k_bananadrag] > TICRATE) + { + K_SpawnWipeoutTrail(player->mo, true); + if (leveltime % 6 == 0) + S_StartSound(player->mo, sfx_cdfm70); + } + } + + while (cur && !P_MobjWasRemoved(cur)) + { + const fixed_t radius = FixedHypot(targ->radius, targ->radius) + FixedHypot(cur->radius, cur->radius); + angle_t ang; + fixed_t targx; + fixed_t targy; + fixed_t targz; + fixed_t speed; + fixed_t dist = radius/2; + + if (!cur->health) + { + cur = cur->hnext; + continue; + } + + if (cur != player->mo->hnext) + { + targ = cur->hprev; + dist = radius/4; + } + + if (!targ || P_MobjWasRemoved(targ)) + continue; + + ang = targ->angle; + targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist); + targy = targ->y + P_ReturnThrustY(cur, ang + ANGLE_180, dist); + targz = targ->z; + speed = FixedMul(R_PointToDist2(cur->x, cur->y, targx, targy), 3*FRACUNIT/4); + if (P_IsObjectOnGround(targ)) + targz = cur->floorz; + + cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy); + + /*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE + && P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false))/2))) + { + if (leveltime & 1) + targz += 8*(2*FRACUNIT)/7; + else + targz -= 8*(2*FRACUNIT)/7; + }*/ + + if (speed > dist) + P_InstaThrust(cur, cur->angle, speed-dist); + + P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 7*FRACUNIT/8) - gravity, false); + + if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT) + P_TeleportMove(cur, targx, targy, cur->z); + + cur = cur->hnext; + } + } + break; + default: + break; + } } /** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c @@ -2301,7 +2954,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_UpdateOffroad(player); // setting players to use the star colormap and spawning afterimages - if (player->kartstuff[k_startimer]) + if (player->kartstuff[k_invincibilitytimer]) { mobj_t *ghost; player->mo->colorized = true; @@ -2309,36 +2962,59 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) ghost->fuse = 4; ghost->frame |= FF_FULLBRIGHT; } + else if (player->kartstuff[k_growshrinktimer] != 0) + { + if (player->kartstuff[k_growshrinktimer] % 5 == 0) + { + player->mo->colorized = true; + player->mo->color = (player->kartstuff[k_growshrinktimer] < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE); + } + else + { + player->mo->colorized = false; + player->mo->color = player->skincolor; + } + } else { player->mo->colorized = false; } - if (player->kartstuff[k_itemclose]) - player->kartstuff[k_itemclose]--; - - if (player->kartstuff[k_spinout]) - player->kartstuff[k_spinout]--; - if (player->kartstuff[k_spinouttimer]) - player->kartstuff[k_spinouttimer]--; - else if (!comeback) - player->kartstuff[k_comebacktimer] = comebacktime; - else if (player->kartstuff[k_comebacktimer]) { - player->kartstuff[k_comebacktimer]--; - if (player == &players[consoleplayer] && player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer] <= 0) - comebackshowninfo = true; // client has already seen the message + if ((P_IsObjectOnGround(player->mo) || player->kartstuff[k_spinouttype] == 1) + && (player->kartstuff[k_sneakertimer] == 0)) + { + player->kartstuff[k_spinouttimer]--; + if (player->kartstuff[k_wipeoutslow] > 1) + player->kartstuff[k_wipeoutslow]--; + if (player->kartstuff[k_spinouttimer] == 0) + player->kartstuff[k_spinouttype] = 0; // Reset type + } + } + else + { + if (player->kartstuff[k_wipeoutslow] == 1) + player->mo->friction = ORIG_FRICTION; + player->kartstuff[k_wipeoutslow] = 0; + if (!comeback) + player->kartstuff[k_comebacktimer] = comebacktime; + else if (player->kartstuff[k_comebacktimer]) + { + player->kartstuff[k_comebacktimer]--; + if (P_IsLocalPlayer(player) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer] <= 0) + comebackshowninfo = true; // client has already seen the message + } } - if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing()) + if (player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing()) player->powers[pw_flashing]--; - if (player->kartstuff[k_magnettimer]) - player->kartstuff[k_magnettimer]--; + if (player->kartstuff[k_attractiontimer]) + player->kartstuff[k_attractiontimer]--; - if (player->kartstuff[k_mushroomtimer]) - player->kartstuff[k_mushroomtimer]--; + if (player->kartstuff[k_sneakertimer]) + player->kartstuff[k_sneakertimer]--; if (player->kartstuff[k_floorboost]) player->kartstuff[k_floorboost]--; @@ -2346,8 +3022,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_driftboost]) player->kartstuff[k_driftboost]--; - if (player->kartstuff[k_startimer]) - player->kartstuff[k_startimer]--; + if (player->kartstuff[k_invincibilitytimer]) + player->kartstuff[k_invincibilitytimer]--; if (player->kartstuff[k_growshrinktimer] > 0) player->kartstuff[k_growshrinktimer]--; @@ -2357,44 +3033,45 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1) { + if (player->kartstuff[k_invincibilitytimer] == 0) + player->mo->color = player->skincolor; player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale; + if (cv_kartdebugshrink.value && !player->bot) + player->mo->destscale = 6*player->mo->destscale/8; P_RestoreMusic(player); } - if (player->kartstuff[k_bootaketimer] == 0 && player->kartstuff[k_boostolentimer] == 0 - && player->kartstuff[k_goldshroomtimer]) - player->kartstuff[k_goldshroomtimer]--; + if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0 + && player->kartstuff[k_rocketsneakertimer]) + player->kartstuff[k_rocketsneakertimer]--; - if (player->kartstuff[k_bootimer]) - player->kartstuff[k_bootimer]--; + if (player->kartstuff[k_hyudorotimer]) + player->kartstuff[k_hyudorotimer]--; - if (player->kartstuff[k_bootaketimer]) - player->kartstuff[k_bootaketimer]--; + if (player->kartstuff[k_sadtimer]) + player->kartstuff[k_sadtimer]--; - if (player->kartstuff[k_boostolentimer]) - player->kartstuff[k_boostolentimer]--; + if (player->kartstuff[k_stealingtimer]) + player->kartstuff[k_stealingtimer]--; + + if (player->kartstuff[k_stolentimer]) + player->kartstuff[k_stolentimer]--; if (player->kartstuff[k_squishedtimer]) player->kartstuff[k_squishedtimer]--; - if (player->kartstuff[k_laserwisptimer]) - player->kartstuff[k_laserwisptimer]--; - if (player->kartstuff[k_justbumped]) player->kartstuff[k_justbumped]--; if (player->kartstuff[k_deathsentence]) { if (player->kartstuff[k_deathsentence] == 1) - K_DoBlueShell(player, &players[blueshellplayer]); + K_DoSPB(player, &players[spbplayer]); player->kartstuff[k_deathsentence]--; } - if (player->kartstuff[k_poweritemtimer]) - player->kartstuff[k_poweritemtimer]--; - - if (player->kartstuff[k_lapanimation]) - player->kartstuff[k_lapanimation]--; + /*if (player->kartstuff[k_lapanimation]) + player->kartstuff[k_lapanimation]--;*/ if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer])) { @@ -2402,6 +3079,10 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { if (player->exiting < 6*TICRATE) player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; + else if (player->exiting == 6*TICRATE) + player->kartstuff[k_cardanimation] = 0; + else if (player->kartstuff[k_cardanimation] < 2*TICRATE) + player->kartstuff[k_cardanimation]++; } else { @@ -2416,6 +3097,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_cardanimation] < 0) player->kartstuff[k_cardanimation] = 0; } + else if (G_RaceGametype() && player->exiting) + { + if (player->kartstuff[k_cardanimation] < 2*TICRATE) + player->kartstuff[k_cardanimation]++; + } else player->kartstuff[k_cardanimation] = 0; @@ -2425,6 +3111,15 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_tauntvoices]) player->kartstuff[k_tauntvoices]--; + if (G_BattleGametype() && player->kartstuff[k_bumper] > 0) + player->kartstuff[k_wanted]++; + + if (P_IsObjectOnGround(player->mo)) + player->kartstuff[k_waterskip] = 0; + + if (player->kartstuff[k_instashield]) + player->kartstuff[k_instashield]--; + // ??? /* if (player->kartstuff[k_jmp] > 1 && onground) @@ -2439,56 +3134,55 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_comebacktimer]) player->kartstuff[k_comebackmode] = 0; - if (P_IsObjectOnGround(player->mo) && !(player->mo->momz) - && player->kartstuff[k_feather] & 2) - player->kartstuff[k_feather] &= ~2; + if (P_IsObjectOnGround(player->mo) && player->mo->momz <= 0 && player->kartstuff[k_pogospring]) + player->kartstuff[k_pogospring] = 0; if (cmd->buttons & BT_DRIFT) player->kartstuff[k_jmp] = 1; else player->kartstuff[k_jmp] = 0; - // Lakitu Checker - if (player->kartstuff[k_lakitu]) - K_LakituChecker(player); + // Respawn Checker + if (player->kartstuff[k_respawn]) + K_RespawnChecker(player); // Roulette Code - //K_KartItemRouletteByPosition(player, cmd); // Old, position-based - K_KartItemRouletteByDistance(player, cmd); // New, distance-based + K_KartItemRoulette(player, cmd); - // Stopping of the horrible star SFX - if (player->mo->health <= 0 || player->mo->player->kartstuff[k_startimer] <= 0 - || player->mo->player->kartstuff[k_growshrinktimer] > 0) // If you don't have invincibility (or mega is active too) + // Stopping of the horrible invincibility SFX + if (player->mo->health <= 0 || player->mo->player->kartstuff[k_invincibilitytimer] <= 0 + || player->mo->player->kartstuff[k_growshrinktimer] > 0) // If you don't have invincibility (or grow is active too) { - if (S_SoundPlaying(player->mo, sfx_star)) // But the sound is playing - S_StopSoundByID(player->mo, sfx_star); // Stop it + if (S_SoundPlaying(player->mo, sfx_kinvnc)) // But the sound is playing + S_StopSoundByID(player->mo, sfx_kinvnc); // Stop it } - // And the same for the mega mushroom SFX + // And the same for the grow SFX if (!(player->mo->health > 0 && player->mo->player->kartstuff[k_growshrinktimer] > 0)) // If you aren't big { - if (S_SoundPlaying(player->mo, sfx_mega)) // But the sound is playing - S_StopSoundByID(player->mo, sfx_mega); // Stop it + if (S_SoundPlaying(player->mo, sfx_kgrow)) // But the sound is playing + S_StopSoundByID(player->mo, sfx_kgrow); // Stop it } - // AAAAAAND handle the SMK star alarm - if (player->mo->health > 0 && (player->mo->player->kartstuff[k_startimer] > 0 + // AAAAAAND handle the invincibility alarm + if (player->mo->health > 0 && (player->mo->player->kartstuff[k_invincibilitytimer] > 0 || player->mo->player->kartstuff[k_growshrinktimer] > 0)) { - if (leveltime % 13 == 0 && cv_kartstarsfx.value && !P_IsLocalPlayer(player)) + if (leveltime % 13 == 0 && cv_kartinvinsfx.value && !P_IsLocalPlayer(player)) S_StartSound(player->mo, sfx_smkinv); } else if (S_SoundPlaying(player->mo, sfx_smkinv)) S_StopSoundByID(player->mo, sfx_smkinv); // Plays the music after the starting countdown. - if (P_IsLocalPlayer(player) && leveltime == 158) - S_ChangeMusic(mapmusname, mapmusflags, true); + if (P_IsLocalPlayer(player) && leveltime == (starttime + (TICRATE/2))) + S_ChangeMusicInternal(mapmusname, true); } void K_KartPlayerAfterThink(player_t *player) { - if (player->kartstuff[k_startimer]) + if (player->kartstuff[k_invincibilitytimer] + || (player->kartstuff[k_growshrinktimer] != 0 && player->kartstuff[k_growshrinktimer] % 5 == 4)) // 4 instead of 0 because this is afterthink! { player->mo->frame |= FF_FULLBRIGHT; } @@ -2497,6 +3191,9 @@ void K_KartPlayerAfterThink(player_t *player) if (!(player->mo->state->frame & FF_FULLBRIGHT)) player->mo->frame &= ~FF_FULLBRIGHT; } + + // Move held objects (Bananas, Orbinaut, etc) + K_MoveHeldObjects(player); } // Returns false if this player being placed here causes them to collide with any other player @@ -2570,23 +3267,24 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) turnvalue = FixedMul(turnvalue, adjustangle); // Weight has a small effect on turning - if (player->kartstuff[k_startimer] || player->kartstuff[k_mushroomtimer] || player->kartstuff[k_growshrinktimer] > 0) + if (player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_sneakertimer] || player->kartstuff[k_growshrinktimer] > 0) turnvalue = FixedMul(turnvalue, FixedDiv(5*FRACUNIT, 4*FRACUNIT)); return turnvalue; } +fixed_t K_GetKartDriftSparkValue(player_t *player) +{ + UINT8 kartspeed = (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) + ? 1 + : player->kartspeed; + return (26*4 + kartspeed*2 + (9 - player->kartweight))*8; +} + static void K_KartDrift(player_t *player, boolean onground) { - UINT8 kartspeed = player->kartspeed; - fixed_t dsone, dstwo; - - if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) - kartspeed = 1; - - // IF YOU CHANGE THESE: MAKE SURE YOU UPDATE THE SAME VALUES IN p_mobjc, "case MT_DRIFT:" - dsone = (26*4 + kartspeed*2 + (9 - player->kartweight))*8; - dstwo = dsone*2; + fixed_t dsone = K_GetKartDriftSparkValue(player); + fixed_t dstwo = dsone*2; // Drifting is actually straffing + automatic turning. // Holding the Jump button will enable drifting. @@ -2605,7 +3303,7 @@ static void K_KartDrift(player_t *player, boolean onground) && onground) { player->kartstuff[k_driftboost] = 20; - S_StartSound(player->mo, sfx_mush); + S_StartSound(player->mo, sfx_s23c); player->kartstuff[k_driftcharge] = 0; } else if ((player->kartstuff[k_drift] != -5 && player->kartstuff[k_drift] != 5) @@ -2614,7 +3312,7 @@ static void K_KartDrift(player_t *player, boolean onground) && onground) { player->kartstuff[k_driftboost] = 50; - S_StartSound(player->mo, sfx_mush); + S_StartSound(player->mo, sfx_s23c); player->kartstuff[k_driftcharge] = 0; } @@ -2653,8 +3351,7 @@ static void K_KartDrift(player_t *player, boolean onground) } // Incease/decrease the drift value to continue drifting in that direction - if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground - && player->kartstuff[k_drift] != 0) + if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground && player->kartstuff[k_drift] != 0) { fixed_t driftadditive = 24; @@ -2795,104 +3492,57 @@ static void K_KartUpdatePosition(player_t *player) } else if (G_BattleGametype()) { - if (player->exiting) - return; - if (players[i].kartstuff[k_balloon] == player->kartstuff[k_balloon] && players[i].score > player->score) - position++; - else if (players[i].kartstuff[k_balloon] > player->kartstuff[k_balloon]) - position++; + if (player->exiting) // End of match standings + { + if (players[i].marescore > player->marescore) // Only score matters + position++; + } + else + { + if (players[i].kartstuff[k_bumper] == player->kartstuff[k_bumper] && players[i].marescore > player->marescore) + position++; + else if (players[i].kartstuff[k_bumper] > player->kartstuff[k_bumper]) + position++; + } } } - if (leveltime < 4*TICRATE || oldposition == 0) + if (leveltime < starttime || oldposition == 0) oldposition = position; if (oldposition != position) // Changed places? - player->kartstuff[k_positiondelay] = 10; // and set up the timer. + player->kartstuff[k_positiondelay] = 10; // Position number growth player->kartstuff[k_position] = position; } -// -// K_CheckForHoldItem -// -static boolean K_CheckForHoldItem(player_t *player) -{ - if ( player->kartstuff[k_greenshell] == 1 - || player->kartstuff[k_redshell] == 1 - || player->kartstuff[k_banana] == 1 - || player->kartstuff[k_fakeitem] == 1 - || player->kartstuff[k_bobomb] == 1 - || player->kartstuff[k_triplegreenshell] & 1 - || player->kartstuff[k_triplegreenshell] & 2 - || player->kartstuff[k_triplegreenshell] & 4 - || player->kartstuff[k_tripleredshell] & 1 - || player->kartstuff[k_tripleredshell] & 2 - || player->kartstuff[k_tripleredshell] & 4 - || player->kartstuff[k_triplebanana] & 1 - || player->kartstuff[k_triplebanana] & 2 - || player->kartstuff[k_triplebanana] & 4 - ) return true; - return false; -} + // // K_StripItems // -static void K_StripItems(player_t *player) +void K_StripItems(player_t *player) { - if ( player->kartstuff[k_kitchensink] - || player->kartstuff[k_feather] & 1 - || player->kartstuff[k_lightning] - || player->kartstuff[k_tripleredshell] - || player->kartstuff[k_fireflower] - || player->kartstuff[k_blueshell] - || player->kartstuff[k_bobomb] - || player->kartstuff[k_triplegreenshell] - || player->kartstuff[k_redshell] - || player->kartstuff[k_greenshell] - || player->kartstuff[k_banana] - || player->kartstuff[k_fakeitem] & 2 - || player->kartstuff[k_triplebanana] - || player->kartstuff[k_star] - || player->kartstuff[k_goldshroom] - || player->kartstuff[k_megashroom] - || player->kartstuff[k_mushroom] - || player->kartstuff[k_boo] - || player->kartstuff[k_magnet] - || player->kartstuff[k_bootimer] - || player->kartstuff[k_bootaketimer] - || player->kartstuff[k_boostolentimer] - || player->kartstuff[k_goldshroomtimer] - || player->kartstuff[k_growshrinktimer] - || player->kartstuff[k_itemroulette] - ) player->kartstuff[k_itemclose] = 10; - player->kartstuff[k_kitchensink] = 0; - player->kartstuff[k_feather] = 0; - player->kartstuff[k_lightning] = 0; - player->kartstuff[k_tripleredshell] = 0; - player->kartstuff[k_fireflower] = 0; - player->kartstuff[k_blueshell] = 0; - player->kartstuff[k_bobomb] = 0; - player->kartstuff[k_triplegreenshell] = 0; - player->kartstuff[k_redshell] = 0; - player->kartstuff[k_greenshell] = 0; - player->kartstuff[k_banana] = 0; - player->kartstuff[k_fakeitem] = 0; - player->kartstuff[k_triplebanana] = 0; - player->kartstuff[k_star] = 0; - player->kartstuff[k_goldshroom] = 0; - player->kartstuff[k_megashroom] = 0; - player->kartstuff[k_mushroom] = 0; - player->kartstuff[k_boo] = 0; - player->kartstuff[k_magnet] = 0; + player->kartstuff[k_itemtype] = 0; + player->kartstuff[k_itemamount] = 0; + player->kartstuff[k_itemheld] = 0; + player->kartstuff[k_itemroulette] = 0; - player->kartstuff[k_bootimer] = 0; - player->kartstuff[k_bootaketimer] = 0; - player->kartstuff[k_boostolentimer] = 0; - player->kartstuff[k_goldshroomtimer] = 0; + player->kartstuff[k_roulettetype] = 0; + + player->kartstuff[k_rocketsneakertimer] = 0; + player->kartstuff[k_invincibilitytimer] = 0; player->kartstuff[k_growshrinktimer] = 0; - player->kartstuff[k_magnettimer] = 0; - player->kartstuff[k_startimer] = 0; + + player->kartstuff[k_eggmanheld] = 0; + + player->kartstuff[k_hyudorotimer] = 0; + player->kartstuff[k_stealingtimer] = 0; + player->kartstuff[k_stolentimer] = 0; + + player->kartstuff[k_attractiontimer] = 0; + + player->kartstuff[k_sadtimer] = 0; } + // // K_MoveKartPlayer // @@ -2900,15 +3550,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { ticcmd_t *cmd = &player->cmd; boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->pflags & PF_ATTACKDOWN)); - boolean HOLDING_ITEM = K_CheckForHoldItem(player); - boolean NO_BOO = (player->kartstuff[k_boostolentimer] == 0 && player->kartstuff[k_bootaketimer] == 0); + boolean HOLDING_ITEM = (player->kartstuff[k_itemheld] || player->kartstuff[k_eggmanheld]); + boolean NO_HYUDORO = (player->kartstuff[k_stolentimer] == 0 && player->kartstuff[k_stealingtimer] == 0); K_KartUpdatePosition(player); if (!player->exiting) { - if (player->kartstuff[k_oldposition] <= player->kartstuff[k_position]) // But first, if you lost a place, + if (player->kartstuff[k_oldposition] < player->kartstuff[k_position]) // But first, if you lost a place, + { player->kartstuff[k_oldposition] = player->kartstuff[k_position]; // then the other player taunts. + K_RegularVoiceTimers(player); // and you can't for a bit + } else if (player->kartstuff[k_oldposition] > player->kartstuff[k_position]) // Otherwise, { K_PlayOvertakeSound(player->mo); // Say "YOU'RE TOO SLOW!" @@ -2919,504 +3572,365 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->kartstuff[k_positiondelay]) player->kartstuff[k_positiondelay]--; - // Race Spectator - if (netgame && player->jointime < 1 - && G_RaceGametype() && countdown) - { - player->spectator = true; - player->powers[pw_nocontrol] = 5; - } - if ((player->pflags & PF_ATTACKDOWN) && !(cmd->buttons & BT_ATTACK)) player->pflags &= ~PF_ATTACKDOWN; else if (cmd->buttons & BT_ATTACK) player->pflags |= PF_ATTACKDOWN; - if (player && player->mo && player->mo->health > 0 && !player->spectator && !player->exiting && player->kartstuff[k_spinouttimer] == 0) + if (player && player->mo && player->mo->health > 0 && !player->spectator && !(player->exiting || mapreset) && player->kartstuff[k_spinouttimer] == 0) { - -// Magnet -// Boo -// Mushroom -// Triple Mushroom -// Mega Mushroom -// Gold Mushroom -// Star -// Triple Banana -// Fake Item -// Banana -// Green Shell -// Red Shell -// Triple Green Shell -// Bob-omb -// Blue Shell -// Fire Flower -// Triple Red Shell -// Lightning -// Feather - - // GoldenMushroom power - if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && player->kartstuff[k_goldshroom] == 1 - && player->kartstuff[k_goldshroomtimer] == 0 && NO_BOO) - { - K_DoMushroom(player, true); - player->kartstuff[k_goldshroomtimer] = itemtime; - player->kartstuff[k_goldshroom] = 0; - } - // GoldenMushroom power - else if (ATTACK_IS_DOWN && player->kartstuff[k_goldshroomtimer] > 1 && onground && NO_BOO) - { - K_DoMushroom(player, true); - player->kartstuff[k_goldshroomtimer] -= 5; - if (player->kartstuff[k_goldshroomtimer] < 1) - player->kartstuff[k_goldshroomtimer] = 1; - } - // TripleMushroom power - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_mushroom] == 4 && onground && NO_BOO) - { - K_DoMushroom(player, true); - player->kartstuff[k_mushroom] = 2; - } - // DoubleMushroom power - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_mushroom] == 2 && onground && NO_BOO) - { - K_DoMushroom(player, true); - player->kartstuff[k_mushroom] = 1; - } - // Mushroom power - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_mushroom] == 1 && onground && NO_BOO) - { - K_DoMushroom(player, true); - player->kartstuff[k_mushroom] = 0; - } - // Star power - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_star] == 1 && NO_BOO) - { - if (P_IsLocalPlayer(player) && !player->exiting) - S_ChangeMusicInternal("minvnc", true); - if (!cv_kartstarsfx.value && !P_IsLocalPlayer(player)) - S_StartSound(player->mo, sfx_star); - player->kartstuff[k_startimer] = itemtime; // Activate it - K_PlayTauntSound(player->mo); - player->kartstuff[k_star] = 0; - if (G_BattleGametype()) - player->kartstuff[k_poweritemtimer] = 10*TICRATE; - player->kartstuff[k_itemclose] = 10; - player->pflags |= PF_ATTACKDOWN; - } - // Green Shell - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_greenshell] & 2 && NO_BOO) - { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo; - player->kartstuff[k_greenshell] &= ~2; - player->kartstuff[k_greenshell] |= 1; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_GREENSHIELD); - mo->threshold = 10; - if (mo) - P_SetTarget(&mo->target, player->mo); - player->kartstuff[k_itemclose] = 10; - } - else if (!(cmd->buttons & BT_ATTACK) && player->kartstuff[k_greenshell] & 1) - { - player->kartstuff[k_greenshell] &= ~1; - - K_ThrowKartItem(player, true, MT_GREENITEM, 1, false); - K_PlayTauntSound(player->mo); - - } - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_fireflower] && NO_BOO) - { - player->kartstuff[k_fireflower] = 0; - - K_ThrowKartItem(player, true, MT_FIREBALL, 1, false); - S_StartSound(player->mo, sfx_mario7); - K_PlayTauntSound(player->mo); - - player->kartstuff[k_itemclose] = 10; - } - // Triple Green Shell - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_triplegreenshell] & 8 && NO_BOO) - { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo, *mo2, *mo3; - player->kartstuff[k_triplegreenshell] &= ~8; - player->kartstuff[k_triplegreenshell] |= 7; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - K_PlayTauntSound(player->mo); - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEGREENSHIELD1); - mo->threshold = 10; - P_SetTarget(&mo->target, player->mo); - mo->angle = 0; - mo2 = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEGREENSHIELD2); - mo2->threshold = 10; - P_SetTarget(&mo2->target, player->mo); - mo2->angle = ANGLE_120; - mo3 = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEGREENSHIELD3); - mo3->threshold = 10; - P_SetTarget(&mo3->target, player->mo); - mo3->angle = ANGLE_240; - player->kartstuff[k_itemclose] = 10; - } - else if (ATTACK_IS_DOWN && (player->kartstuff[k_triplegreenshell] & 1 || player->kartstuff[k_triplegreenshell] & 2 || player->kartstuff[k_triplegreenshell] & 4)) - { - K_ThrowKartItem(player, true, MT_GREENITEM, 1, false); - K_PlayTauntSound(player->mo); - player->pflags |= PF_ATTACKDOWN; - - if (player->kartstuff[k_triplegreenshell] & 4) - player->kartstuff[k_triplegreenshell] &= ~4; - else if (player->kartstuff[k_triplegreenshell] & 2) - player->kartstuff[k_triplegreenshell] &= ~2; - else if (player->kartstuff[k_triplegreenshell] & 1) - player->kartstuff[k_triplegreenshell] &= ~1; - - } - // Red Shell - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_redshell] & 2 && NO_BOO) - { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo; - player->kartstuff[k_redshell] &= ~2; - player->kartstuff[k_redshell] |= 1; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_REDSHIELD); - mo->threshold = 10; - if (mo) - P_SetTarget(&mo->target, player->mo); - player->kartstuff[k_itemclose] = 10; - } - else if (!(cmd->buttons & BT_ATTACK) && player->kartstuff[k_redshell] & 1 && (player->kartstuff[k_throwdir] == 1 || player->kartstuff[k_throwdir] == 0)) - { - player->kartstuff[k_redshell] &= ~1; - - K_ThrowKartItem(player, true, MT_REDITEM, 1, false); - K_PlayTauntSound(player->mo); - } - // Red Shell Dud - else if (!(cmd->buttons & BT_ATTACK) && player->kartstuff[k_redshell] & 1 && player->kartstuff[k_throwdir] == -1) - { - player->kartstuff[k_redshell] &= ~1; - - K_ThrowKartItem(player, true, MT_REDITEMDUD, -1, false); - K_PlayTauntSound(player->mo); - } - // Triple Red Shell - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_tripleredshell] & 8 && NO_BOO) - { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo, *mo2, *mo3; - player->kartstuff[k_tripleredshell] &= ~8; - player->kartstuff[k_tripleredshell] |= 7; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - K_PlayTauntSound(player->mo); - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEREDSHIELD1); - mo->threshold = 10; - P_SetTarget(&mo->target, player->mo); - mo->angle = 0; - mo2 = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEREDSHIELD2); - mo2->threshold = 10; - P_SetTarget(&mo2->target, player->mo); - mo2->angle = ANGLE_120; - mo3 = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEREDSHIELD3); - mo3->threshold = 10; - P_SetTarget(&mo3->target, player->mo); - mo3->angle = ANGLE_240; - player->kartstuff[k_itemclose] = 10; - } - else if (ATTACK_IS_DOWN && (player->kartstuff[k_tripleredshell] & 1 || player->kartstuff[k_tripleredshell] & 2 || player->kartstuff[k_tripleredshell] & 4) - && (player->kartstuff[k_throwdir] == 1 || player->kartstuff[k_throwdir] == 0)) - { - K_ThrowKartItem(player, true, MT_REDITEM, 1, false); - K_PlayTauntSound(player->mo); - player->pflags |= PF_ATTACKDOWN; - if (player->kartstuff[k_tripleredshell] & 4) - player->kartstuff[k_tripleredshell] &= ~4; - else if (player->kartstuff[k_tripleredshell] & 2) - player->kartstuff[k_tripleredshell] &= ~2; - else if (player->kartstuff[k_tripleredshell] & 1) - player->kartstuff[k_tripleredshell] &= ~1; - } - else if (ATTACK_IS_DOWN && (player->kartstuff[k_tripleredshell] & 1 || player->kartstuff[k_tripleredshell] & 2 || player->kartstuff[k_tripleredshell] & 4) - && player->kartstuff[k_throwdir] == -1) - { - K_ThrowKartItem(player, true, MT_REDITEMDUD, -1, false); - K_PlayTauntSound(player->mo); - player->pflags |= PF_ATTACKDOWN; - if (player->kartstuff[k_tripleredshell] & 4) - player->kartstuff[k_tripleredshell] &= ~4; - else if (player->kartstuff[k_tripleredshell] & 2) - player->kartstuff[k_tripleredshell] &= ~2; - else if (player->kartstuff[k_tripleredshell] & 1) - player->kartstuff[k_tripleredshell] &= ~1; - } - // Banana Peel - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_banana] & 2 && NO_BOO) - { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo; - player->kartstuff[k_banana] &= ~2; - player->kartstuff[k_banana] |= 1; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_BANANASHIELD); - mo->threshold = 10; - if (mo) - P_SetTarget(&mo->target, player->mo); - player->kartstuff[k_itemclose] = 10; - } - else if (!(cmd->buttons & BT_ATTACK) && player->kartstuff[k_banana] & 1) - { - K_ThrowKartItem(player, false, MT_BANANAITEM, -1, false); - K_PlayTauntSound(player->mo); - player->kartstuff[k_banana] &= ~1; - } - // Triple Banana Peel - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_triplebanana] & 8 && NO_BOO) - { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo, *mo2, *mo3; - K_PlayTauntSound(player->mo); - player->kartstuff[k_triplebanana] &= ~8; - player->kartstuff[k_triplebanana] |= 7; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEBANANASHIELD1); - mo->threshold = 10; - if (mo) { - P_SetTarget(&mo->target, player->mo); - mo->angle = 0; } - mo2 = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEBANANASHIELD2); - mo2->threshold = 10; - if (mo2) { - P_SetTarget(&mo2->target, player->mo); - mo2->angle = ANGLE_135; } - mo3 = P_SpawnMobj(newx, newy, player->mo->z, MT_TRIPLEBANANASHIELD3); - mo3->threshold = 10; - if (mo3) { - P_SetTarget(&mo3->target, player->mo); - mo3->angle = ANGLE_225; } - player->kartstuff[k_itemclose] = 10; - } - else if (ATTACK_IS_DOWN && (player->kartstuff[k_triplebanana] & 1 || player->kartstuff[k_triplebanana] & 2 || player->kartstuff[k_triplebanana] & 4)) - { - K_ThrowKartItem(player, false, MT_BANANAITEM, -1,false ); - K_PlayTauntSound(player->mo); - player->pflags |= PF_ATTACKDOWN; - if (player->kartstuff[k_triplebanana] & 4) - player->kartstuff[k_triplebanana] &= ~4; - else if (player->kartstuff[k_triplebanana] & 2) - player->kartstuff[k_triplebanana] &= ~2; - else if (player->kartstuff[k_triplebanana] & 1) - player->kartstuff[k_triplebanana] &= ~1; - } - // Fake Itembox - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_fakeitem] & 2 && NO_BOO) - { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo; - player->kartstuff[k_fakeitem] &= ~2; - player->kartstuff[k_fakeitem] |= 1; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_FAKESHIELD); - mo->scale = FRACUNIT/2; - mo->threshold = 10; - if (mo) - P_SetTarget(&mo->target, player->mo); - player->kartstuff[k_itemclose] = 10; - } - else if (!(cmd->buttons & BT_ATTACK) && player->kartstuff[k_fakeitem] & 1) + // First, the really specific, finicky items that function without the item being directly in your item slot. + // Eggman Monitor throwing + if (ATTACK_IS_DOWN && player->kartstuff[k_eggmanheld]) { K_ThrowKartItem(player, false, MT_FAKEITEM, -1, false); K_PlayTauntSound(player->mo); - player->kartstuff[k_fakeitem] &= ~1; + player->kartstuff[k_eggmanheld] = 0; } - // Bomb - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_bobomb] & 2 && NO_BOO) + // Rocket Sneaker + else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO + && player->kartstuff[k_rocketsneakertimer] > 1) { - angle_t newangle; - fixed_t newx; - fixed_t newy; - mobj_t *mo; - player->kartstuff[k_bobomb] &= ~2; - player->kartstuff[k_bobomb] |= 1; - player->pflags |= PF_ATTACKDOWN; - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - mo = P_SpawnMobj(newx, newy, player->mo->z, MT_BOMBSHIELD); - mo->threshold = 10; - if (mo) - P_SetTarget(&mo->target, player->mo); - player->kartstuff[k_itemclose] = 10; + K_DoSneaker(player, true); + player->kartstuff[k_rocketsneakertimer] -= 5; + if (player->kartstuff[k_rocketsneakertimer] < 1) + player->kartstuff[k_rocketsneakertimer] = 1; } - if (!(cmd->buttons & BT_ATTACK) && player->kartstuff[k_bobomb] & 1) + else { - K_ThrowKartItem(player, false, MT_BOMBITEM, 1, true); - K_PlayTauntSound(player->mo); - player->kartstuff[k_bobomb] &= ~1; - } - // Thunder - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_lightning] == 1 && NO_BOO) - { - K_DoLightning(player); - player->kartstuff[k_lightning] = 0; - player->kartstuff[k_itemclose] = 10; - } - // Blue Shell - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_blueshell] == 1 && NO_BOO) - { - UINT8 i; - UINT8 bestrank = 0; - fixed_t dist = 0; - - //K_DoLightning(player, true); - - for (i = 0; i < MAXPLAYERS; i++) + switch (player->kartstuff[k_itemtype]) { - fixed_t thisdist; - if (!playeringame[i] || players[i].spectator) - continue; - if (&players[i] == player) - continue; - if (!players[i].mo) - continue; - if (players[i].exiting) - continue; - thisdist = R_PointToDist2(player->mo->x, player->mo->y, players[i].mo->x, players[i].mo->y); - if (bestrank == 0 || players[i].kartstuff[k_position] < bestrank) - { - bestrank = players[i].kartstuff[k_position]; - dist = thisdist; - } + case KITEM_SNEAKER: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO) + { + K_DoSneaker(player, true); + player->kartstuff[k_itemamount]--; + } + break; + case KITEM_ROCKETSNEAKER: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO + && player->kartstuff[k_rocketsneakertimer] == 0) + { + K_DoSneaker(player, true); + player->kartstuff[k_rocketsneakertimer] = itemtime; + player->kartstuff[k_itemamount]--; + } + break; + case KITEM_INVINCIBILITY: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) // Doesn't hold your item slot hostage normally, so you're free to waste it if you have multiple + { + if (!player->kartstuff[k_invincibilitytimer]) + { + mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INVULNFLASH); + P_SetTarget(&overlay->target, player->mo); + overlay->destscale = player->mo->scale; + P_SetScale(overlay, player->mo->scale); + } + player->kartstuff[k_invincibilitytimer] = itemtime+(2*TICRATE); // 10 seconds + P_RestoreMusic(player); + if (!cv_kartinvinsfx.value && !P_IsLocalPlayer(player)) + S_StartSound(player->mo, sfx_kinvnc); + K_PlayTauntSound(player->mo); + player->kartstuff[k_itemamount]--; + player->pflags |= PF_ATTACKDOWN; + } + break; + case KITEM_BANANA: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + INT32 moloop; + mobj_t *mo; + mobj_t *prev = player->mo; + + //K_PlayTauntSound(player->mo); + player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ATTACKDOWN; + + for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) + { + mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BANANA_SHIELD); + mo->threshold = 10; + mo->movecount = player->kartstuff[k_itemamount]; + mo->lastlook = moloop+1; + P_SetTarget(&mo->target, player->mo); + P_SetTarget(&mo->hprev, prev); + P_SetTarget(&prev->hnext, mo); + prev = mo; + } + } + else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld]) // Banana x3 thrown + { + K_ThrowKartItem(player, false, MT_BANANA, -1, false); + K_PlayTauntSound(player->mo); + player->pflags |= PF_ATTACKDOWN; + player->kartstuff[k_itemamount]--; + if (!player->kartstuff[k_itemamount]) + player->kartstuff[k_itemheld] = 0; + } + break; + case KITEM_EGGMAN: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + mobj_t *mo; + player->kartstuff[k_itemamount]--; + player->kartstuff[k_eggmanheld] = 1; + player->pflags |= PF_ATTACKDOWN; + mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FAKESHIELD); + mo->threshold = 10; + mo->movecount = 1; + mo->lastlook = 1; + if (mo) + { + P_SetTarget(&mo->target, player->mo); + P_SetTarget(&player->mo->hnext, mo); + } + } + break; + case KITEM_ORBINAUT: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + angle_t newangle; + fixed_t newx; + fixed_t newy; + INT32 moloop; + mobj_t *mo = NULL; + mobj_t *prev = player->mo; + + //K_PlayTauntSound(player->mo); + player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ATTACKDOWN; + S_StartSound(player->mo, sfx_s3k3a); + + for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) + { + newangle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90; + newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 64*FRACUNIT); + newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 64*FRACUNIT); + mo = P_SpawnMobj(newx, newy, player->mo->z, MT_ORBINAUT_SHIELD); + mo->angle = newangle; + mo->threshold = 10; + mo->movecount = player->kartstuff[k_itemamount]; + mo->movedir = mo->lastlook = moloop+1; + mo->color = player->skincolor; + P_SetTarget(&mo->target, player->mo); + P_SetTarget(&mo->hprev, prev); + P_SetTarget(&prev->hnext, mo); + prev = mo; + } + } + else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld]) // Orbinaut x3 thrown + { + K_ThrowKartItem(player, true, MT_ORBINAUT, 1, false); + K_PlayTauntSound(player->mo); + player->pflags |= PF_ATTACKDOWN; + + player->kartstuff[k_itemamount]--; + if (!player->kartstuff[k_itemamount]) + player->kartstuff[k_itemheld] = 0; + } + break; + case KITEM_JAWZ: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + angle_t newangle; + fixed_t newx; + fixed_t newy; + INT32 moloop; + mobj_t *mo = NULL; + mobj_t *prev = player->mo; + + //K_PlayTauntSound(player->mo); + player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ATTACKDOWN; + S_StartSound(player->mo, sfx_s3k3a); + + for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) + { + newangle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90; + newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 64*FRACUNIT); + newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 64*FRACUNIT); + mo = P_SpawnMobj(newx, newy, player->mo->z, MT_JAWZ_SHIELD); + mo->angle = newangle; + mo->threshold = 10; + mo->movecount = player->kartstuff[k_itemamount]; + mo->movedir = mo->lastlook = moloop+1; + P_SetTarget(&mo->target, player->mo); + P_SetTarget(&mo->hprev, prev); + P_SetTarget(&prev->hnext, mo); + prev = mo; + } + } + else if (ATTACK_IS_DOWN && HOLDING_ITEM && player->kartstuff[k_itemheld]) // Jawz thrown + { + if (player->kartstuff[k_throwdir] == 1 || player->kartstuff[k_throwdir] == 0) + K_ThrowKartItem(player, true, MT_JAWZ, 1, false); + else if (player->kartstuff[k_throwdir] == -1) // Throwing backward gives you a dud that doesn't home in + K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, false); + K_PlayTauntSound(player->mo); + player->pflags |= PF_ATTACKDOWN; + + player->kartstuff[k_itemamount]--; + if (!player->kartstuff[k_itemamount]) + player->kartstuff[k_itemheld] = 0; + } + break; + case KITEM_MINE: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + mobj_t *mo; + player->kartstuff[k_itemheld] = 1; + player->pflags |= PF_ATTACKDOWN; + mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SSMINE_SHIELD); + mo->threshold = 10; + mo->movecount = 1; + mo->lastlook = 1; + if (mo) + { + P_SetTarget(&mo->target, player->mo); + P_SetTarget(&player->mo->hnext, mo); + } + } + else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld]) + { + K_ThrowKartItem(player, false, MT_SSMINE, 1, true); + K_PlayTauntSound(player->mo); + player->kartstuff[k_itemamount]--; + player->kartstuff[k_itemheld] = 0; + } + break; + case KITEM_BALLHOG: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + player->kartstuff[k_itemamount]--; + K_ThrowKartItem(player, true, MT_BALLHOG, 1, false); + S_StartSound(player->mo, sfx_mario7); + K_PlayTauntSound(player->mo); + } + break; + case KITEM_SPB: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + UINT8 ploop; + UINT8 bestrank = 0; + fixed_t dist = 0; + + for (ploop = 0; ploop < MAXPLAYERS; ploop++) + { + fixed_t thisdist; + if (!playeringame[ploop] || players[ploop].spectator) + continue; + if (&players[ploop] == player) + continue; + if (!players[ploop].mo) + continue; + if (players[ploop].exiting) + continue; + thisdist = R_PointToDist2(player->mo->x, player->mo->y, players[ploop].mo->x, players[ploop].mo->y); + if (bestrank == 0 || players[ploop].kartstuff[k_position] < bestrank) + { + bestrank = players[ploop].kartstuff[k_position]; + dist = thisdist; + } + } + + if (dist == 0) + spbincoming = 6*TICRATE; // If you couldn't find anyone, just set an abritary timer + else + spbincoming = (tic_t)max(1, FixedDiv(dist, 64*FRACUNIT)/FRACUNIT); + + spbplayer = player-players; + + player->pflags |= PF_ATTACKDOWN; + player->kartstuff[k_itemamount]--; + + K_PlayTauntSound(player->mo); + } + break; + case KITEM_GROW: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO + && player->kartstuff[k_growshrinktimer] <= 0) // Grow holds the item box hostage + { + K_PlayTauntSound(player->mo); + player->mo->scalespeed = FRACUNIT/TICRATE; + player->mo->destscale = 3*(mapheaderinfo[gamemap-1]->mobj_scale)/2; + if (cv_kartdebugshrink.value && !player->bot) + player->mo->destscale = 6*player->mo->destscale/8; + player->kartstuff[k_growshrinktimer] = itemtime+(4*TICRATE); // 12 seconds + P_RestoreMusic(player); + if (!cv_kartinvinsfx.value && !P_IsLocalPlayer(player)) + S_StartSound(player->mo, sfx_kgrow); + S_StartSound(player->mo, sfx_kc5a); + player->pflags |= PF_ATTACKDOWN; + player->kartstuff[k_itemamount]--; + } + break; + case KITEM_SHRINK: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + K_DoShrink(player); + player->kartstuff[k_itemamount]--; + } + break; + case KITEM_LIGHTNINGSHIELD: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + K_DoLightningShield(player); + player->pflags |= PF_ATTACKDOWN; + player->kartstuff[k_itemamount]--; + } + break; + case KITEM_HYUDORO: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + player->kartstuff[k_itemamount]--; + player->pflags |= PF_ATTACKDOWN; + K_DoHyudoroSteal(player); + } + break; + case KITEM_POGOSPRING: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO + && !player->kartstuff[k_pogospring]) + { + K_PlayTauntSound(player->mo); + K_DoPogoSpring(player->mo, 32<pflags |= PF_ATTACKDOWN; + player->kartstuff[k_pogospring] = 1; + player->kartstuff[k_itemamount]--; + } + break; + case KITEM_KITCHENSINK: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) + { + K_ThrowKartItem(player, false, MT_SINK, 1, true); + K_PlayTauntSound(player->mo); + player->kartstuff[k_itemamount]--; + player->kartstuff[k_itemheld] = 0; + } + break; + case KITEM_SAD: + if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO + && !player->kartstuff[k_sadtimer]) + { + player->kartstuff[k_sadtimer] = stealtime; + player->kartstuff[k_itemamount]--; + } + break; + default: + break; } - - if (dist == 0) - blueshellincoming = 6*TICRATE; // If you couldn't find anyone, just set an abritary timer - else - blueshellincoming = (tic_t)max(1, FixedDiv(dist, 64*FRACUNIT)/FRACUNIT); - - blueshellplayer = player-players; - player->pflags |= PF_ATTACKDOWN; - K_PlayTauntSound(player->mo); - player->kartstuff[k_blueshell] = 0; - player->kartstuff[k_itemclose] = 10; - } - // Mega Mushroom - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_megashroom] == 1 && NO_BOO) - { - if (P_IsLocalPlayer(player) && !player->exiting) - S_ChangeMusicInternal("mega", true); - if (!cv_kartstarsfx.value && !P_IsLocalPlayer(player)) - S_StartSound(player->mo, sfx_mega); - K_PlayTauntSound(player->mo); - player->kartstuff[k_growshrinktimer] = itemtime + TICRATE*2; - S_StartSound(player->mo, sfx_mario3); - player->pflags |= PF_ATTACKDOWN; - player->kartstuff[k_megashroom] = 0; - if (G_BattleGametype()) - player->kartstuff[k_poweritemtimer] = 10*TICRATE; - player->kartstuff[k_itemclose] = 10; - } - // Boo - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_boo] == 1 && NO_BOO) - { - K_DoBooSteal(player); - player->pflags |= PF_ATTACKDOWN; - player->kartstuff[k_boo] = 0; - } - // Magnet - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_magnet] == 1 && NO_BOO) - { - K_DoMagnet(player); - player->pflags |= PF_ATTACKDOWN; - player->kartstuff[k_magnet] = 0; - } - // Feather - else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_feather] & 1 && onground && NO_BOO) - { - K_PlayTauntSound(player->mo); - K_DoBouncePad(player->mo, 32<pflags |= PF_ATTACKDOWN; - player->kartstuff[k_feather] |= 2; - player->kartstuff[k_feather] &= ~1; - - player->kartstuff[k_itemclose] = 10; } - // Mushroom Boost - if (((player->kartstuff[k_mushroomtimer] > 0 && player->kartstuff[k_boosting] == 0) - || (player->kartstuff[k_mushroomtimer] > 0 && ATTACK_IS_DOWN && NO_BOO)) && onground) - { - player->kartstuff[k_boosting] = 1; - } - else if (player->kartstuff[k_mushroomtimer] == 0 && player->kartstuff[k_boosting] == 1) - player->kartstuff[k_boosting] = 0; + // No more! + if (!player->kartstuff[k_itemamount] && !player->kartstuff[k_itemheld]) + player->kartstuff[k_itemtype] = KITEM_NONE; - // Megashroom - Make the player grow! - if (player->kartstuff[k_growshrinktimer] > ((itemtime + TICRATE*2) - 25)) - { - if (leveltime & 2) - player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale)*3/2; - else - player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale); - } - else if (player->kartstuff[k_growshrinktimer] > 26 - && player->kartstuff[k_growshrinktimer] <= ((itemtime + TICRATE*2) - 25)) - player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale)*3/2; - // Megashroom - Back to normal... - else if (player->kartstuff[k_growshrinktimer] > 1 - && player->kartstuff[k_growshrinktimer] <= 26) - { - if (leveltime & 2) - player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale); - else - player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale)*3/2; - } - if (player->kartstuff[k_growshrinktimer] == 26) - S_StartSound(player->mo, sfx_mario8); + if (player->kartstuff[k_itemtype] == KITEM_SPB + || player->kartstuff[k_itemtype] == KITEM_SHRINK + || player->kartstuff[k_growshrinktimer] < 0 + || spbincoming) + indirectitemcooldown = 20*TICRATE; - if ((G_BattleGametype()) - && (player->kartstuff[k_star] || player->kartstuff[k_megashroom] - || player->kartstuff[k_startimer] || player->kartstuff[k_growshrinktimer] > 0)) - player->kartstuff[k_poweritemtimer] = 10*TICRATE; - - if (player->kartstuff[k_bootimer] > 0) + if (player->kartstuff[k_hyudorotimer] > 0) { if (splitscreen) { @@ -3425,7 +3939,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else player->mo->flags2 &= ~MF2_DONTDRAW; - if (player->kartstuff[k_bootimer] >= (1*TICRATE/2) && player->kartstuff[k_bootimer] <= bootime-(1*TICRATE/2)) + if (player->kartstuff[k_hyudorotimer] >= (1*TICRATE/2) && player->kartstuff[k_hyudorotimer] <= hyudorotime-(1*TICRATE/2)) { if (player == &players[secondarydisplayplayer]) player->mo->eflags |= MFE_DRAWONLYFORP2; @@ -3442,7 +3956,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else { if (player == &players[displayplayer] - || (player != &players[displayplayer] && (player->kartstuff[k_bootimer] < (1*TICRATE/2) || player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) + || (player != &players[displayplayer] && (player->kartstuff[k_hyudorotimer] < (1*TICRATE/2) || player->kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2)))) { if (leveltime & 1) player->mo->flags2 |= MF2_DONTDRAW; @@ -3453,62 +3967,23 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->flags2 |= MF2_DONTDRAW; } - player->powers[pw_flashing] = player->kartstuff[k_bootimer]; // We'll do this for now, let's people know about the invisible people through subtle hints + player->powers[pw_flashing] = player->kartstuff[k_hyudorotimer]; // We'll do this for now, let's people know about the invisible people through subtle hints } - else if (player->kartstuff[k_bootimer] == 0) + else if (player->kartstuff[k_hyudorotimer] == 0) { player->mo->flags2 &= ~MF2_DONTDRAW; player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); } - if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) // dead in match? you da bomb + if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb { K_StripItems(player); player->mo->flags2 |= MF2_SHADOW; - - if (!(player->mo->tracer)) - { - player->mo->tracer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_OVERLAY); - P_SetMobjState(player->mo->tracer, S_PLAYERBOMB); - } - - P_SetTarget(&player->mo->tracer->target, player->mo); - player->mo->tracer->color = player->mo->color; - - if (player->kartstuff[k_comebacktimer] > 0) - { - if (player->mo->tracer->state != &states[S_PLAYERBOMB]) - P_SetMobjState(player->mo->tracer, S_PLAYERBOMB); - - if (player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1)) - player->mo->tracer->flags2 &= ~MF2_DONTDRAW; - else - player->mo->tracer->flags2 |= MF2_DONTDRAW; - - player->powers[pw_flashing] = player->kartstuff[k_comebacktimer]; - } - else - { - if (player->kartstuff[k_comebackmode] == 0 - && player->mo->tracer->state != &states[S_PLAYERBOMB]) - P_SetMobjState(player->mo->tracer, S_PLAYERBOMB); - else if (player->kartstuff[k_comebackmode] == 1 - && player->mo->tracer->state != &states[S_PLAYERITEM]) - P_SetMobjState(player->mo->tracer, S_PLAYERITEM); - - if (player->powers[pw_flashing] && (leveltime & 1)) - player->mo->tracer->flags2 |= MF2_DONTDRAW; - else - player->mo->tracer->flags2 &= ~MF2_DONTDRAW; - } + player->powers[pw_flashing] = player->kartstuff[k_comebacktimer]; } - else if (G_RaceGametype() || player->kartstuff[k_balloon] > 0) + else if (G_RaceGametype() || player->kartstuff[k_bumper] > 0) { player->mo->flags2 &= ~MF2_SHADOW; - if (player->mo->tracer - && (player->mo->tracer->state == &states[S_PLAYERBOMB] - || player->mo->tracer->state == &states[S_PLAYERITEM])) - P_RemoveMobj(player->mo->tracer); } } @@ -3520,7 +3995,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->friction += 4608; if (player->speed > 0 && cmd->forwardmove < 0 && player->mo->friction == 59392) player->mo->friction += 1608; - if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) + if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) { player->mo->friction += 1228; @@ -3539,20 +4014,26 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->mo->movefactor < 32) player->mo->movefactor = 32; } + if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow]) + { + player->mo->friction -= FixedMul(1228, player->kartstuff[k_offroad]); + if (player->kartstuff[k_wipeoutslow] == 1) + player->mo->friction -= 4912; + } K_KartDrift(player, onground); // Quick Turning // You can't turn your kart when you're not moving. // So now it's time to burn some rubber! - if (player->speed < 2 && leveltime > 140 && cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE && cmd->driftturn != 0) + if (player->speed < 2 && leveltime > starttime && cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE && cmd->driftturn != 0) { if (leveltime % 20 == 0) S_StartSound(player->mo, sfx_mkslid); } // Squishing - // If a Mega Mushroom or a Thwomp crushes you, get flattened instead of being killed. + // If a Grow player or a sector crushes you, get flattened instead of being killed. if (player->kartstuff[k_squishedtimer] <= 0) { @@ -3565,51 +4046,192 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->momy = 0; } - // Play the stop light's sounds - if ((leveltime == (TICRATE-4)*2) || (leveltime == (TICRATE-2)*3)) - S_StartSound(NULL, sfx_lkt1); - if (leveltime == (TICRATE)*4) - S_StartSound(NULL, sfx_lkt2); + // Play the starting countdown sounds + if (player == &players[displayplayer]) // Don't play louder in splitscreen + { + if ((leveltime == starttime-(3*TICRATE)) || (leveltime == starttime-(2*TICRATE)) || (leveltime == starttime-TICRATE)) + S_StartSound(NULL, sfx_s3ka7); + if (leveltime == starttime) + { + S_StartSound(NULL, sfx_s3kad); + S_StopMusic(); // The GO! sound stops the level start ambience + } + } + // Start charging once you're given the opportunity. - if (leveltime >= 70 && leveltime <= 140 && cmd->buttons & BT_ACCELERATE) - player->kartstuff[k_boostcharge]++; - if (leveltime >= 70 && leveltime <= 140 && !(cmd->buttons & BT_ACCELERATE)) - player->kartstuff[k_boostcharge] = 0; + if (leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) + { + if (cmd->buttons & BT_ACCELERATE) + player->kartstuff[k_boostcharge]++; + else + player->kartstuff[k_boostcharge] = 0; + } + // Increase your size while charging your engine. - if (leveltime < 150) + if (leveltime < starttime+10) + { player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale) + (player->kartstuff[k_boostcharge]*131); + if (cv_kartdebugshrink.value && !player->bot) + player->mo->destscale = 6*player->mo->destscale/8; + } // Determine the outcome of your charge. - if (leveltime > 140 && player->kartstuff[k_boostcharge]) + if (leveltime > starttime && player->kartstuff[k_boostcharge]) { // Get an instant boost! if (player->kartstuff[k_boostcharge] >= 35 && player->kartstuff[k_boostcharge] <= 50) { + player->kartstuff[k_sneakertimer] = -((21*(player->kartstuff[k_boostcharge]*player->kartstuff[k_boostcharge]))/425)+131; // max time is 70, min time is 7; yay parabooolas if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) - S_StartSound(player->mo, sfx_sboost); - - player->kartstuff[k_mushroomtimer] = -((21*(player->kartstuff[k_boostcharge]*player->kartstuff[k_boostcharge]))/425)+131; // max time is 70, min time is 7; yay parabooolas + { + if (player->kartstuff[k_sneakertimer] >= 70) + S_StartSound(player->mo, sfx_s25f); // Special sound for the perfect start boost! + else if (player->kartstuff[k_sneakertimer] >= sneakertime) + S_StartSound(player->mo, sfx_cdfm01); // Sneaker boost sound for big boost + else + S_StartSound(player->mo, sfx_s23c); // Drift boost sound for small boost + } } // You overcharged your engine? Those things are expensive!!! else if (player->kartstuff[k_boostcharge] > 50) { player->powers[pw_nocontrol] = 40; - S_StartSound(player->mo, sfx_slip); + //S_StartSound(player->mo, sfx_kc34); + S_StartSound(player->mo, sfx_s3k83); + player->pflags |= PF_SKIDDOWN; // cheeky pflag reuse } player->kartstuff[k_boostcharge] = 0; } } -void K_CheckBalloons(void) +void K_CalculateBattleWanted(void) +{ + UINT8 numingame = 0, numwanted = 0; + SINT8 bestbumperplayer = -1, bestbumper = -1; + SINT8 camppos[MAXPLAYERS]; // who is the biggest camper + UINT8 ties = 0, nextcamppos = 0; + boolean setbumper = false; + UINT8 i, j; + + if (!G_BattleGametype()) + { + for (i = 0; i < 4; i++) + battlewanted[i] = -1; + return; + } + + wantedcalcdelay = wantedfrequency; + + for (i = 0; i < MAXPLAYERS; i++) + camppos[i] = -1; // initialize + + for (i = 0; i < MAXPLAYERS; i++) + { + UINT8 position = 1; + + if (!playeringame[i] || players[i].spectator) // Not playing + continue; + + if (players[i].exiting) // We're done, don't calculate. + return; + + if (players[i].kartstuff[k_bumper] <= 0) // Not alive, so don't do anything else + continue; + + numingame++; + + if (bestbumper == -1 || players[i].kartstuff[k_bumper] > bestbumper) + { + bestbumper = players[i].kartstuff[k_bumper]; + bestbumperplayer = i; + } + else if (players[i].kartstuff[k_bumper] == bestbumper) + bestbumperplayer = -1; // Tie, no one has best bumper. + + for (j = 0; j < MAXPLAYERS; j++) + { + if (!playeringame[j] || players[j].spectator) + continue; + if (players[j].kartstuff[k_bumper] <= 0) + continue; + if (j == i) + continue; + if (players[j].kartstuff[k_wanted] == players[i].kartstuff[k_wanted] && players[j].marescore > players[i].marescore) + position++; + else if (players[j].kartstuff[k_wanted] > players[i].kartstuff[k_wanted]) + position++; + } + + position--; // Make zero based + + while (camppos[position] != -1) // Port priority! + position++; + + camppos[position] = i; + } + + if (numingame <= 2) + numwanted = 0; + else + numwanted = min(4, 1 + ((numingame-2) / 4)); + + for (i = 0; i < 4; i++) + { + if (i+1 > numwanted) // Not enough players for this slot to be wanted! + battlewanted[i] = -1; + else if (bestbumperplayer != -1 && !setbumper) // If there's a player who has an untied bumper lead over everyone else, they are the first to be wanted. + { + battlewanted[i] = bestbumperplayer; + setbumper = true; // Don't set twice + } + else + { + // Don't accidentally set the same player, if the bestbumperplayer is also a huge camper. + while (bestbumperplayer != -1 && camppos[nextcamppos] != -1 + && bestbumperplayer == camppos[nextcamppos]) + nextcamppos++; + + // Do not add *any* more people if there's too many times that are tied with others. + // This could theoretically happen very easily if people don't hit each other for a while after the start of a match. + // (I will be sincerely impressed if more than 2 people tie after people start hitting each other though) + + if (camppos[nextcamppos] == -1 // Out of entries + || ties >= (numwanted-i)) // Already counted ties + { + battlewanted[i] = -1; + continue; + } + + if (ties < (numwanted-i)) + { + ties = 0; // Reset + for (j = 0; j < 2; j++) + { + if (camppos[nextcamppos+(j+1)] == -1) // Nothing beyond, cancel + break; + if (players[camppos[nextcamppos]].kartstuff[k_wanted] == players[camppos[nextcamppos+(j+1)]].kartstuff[k_wanted]) + ties++; + } + } + + if (ties < (numwanted-i)) // Is it still low enough after counting? + { + battlewanted[i] = camppos[nextcamppos]; + nextcamppos++; + } + else + battlewanted[i] = -1; + } + } +} + +void K_CheckBumpers(void) { UINT8 i; UINT8 numingame = 0; SINT8 winnernum = -1; - -#if 0 - return; // set to 1 to test comeback mechanics while alone -#endif + INT32 winnerscoreadd = 0; if (!multiplayer) return; @@ -3629,134 +4251,153 @@ void K_CheckBalloons(void) return; numingame++; + winnerscoreadd += players[i].marescore; - if (players[i].kartstuff[k_balloon] <= 0) // if you don't have any balloons, you're probably not a winner + if (players[i].kartstuff[k_bumper] <= 0) // if you don't have any bumpers, you're probably not a winner continue; else if (winnernum > -1) // TWO winners? that's dumb :V return; + winnernum = i; + winnerscoreadd -= players[i].marescore; } if (numingame <= 1) return; - if (playeringame[winnernum]) + if (winnernum > -1 && playeringame[winnernum]) { - players[winnernum].score += 1; - CONS_Printf(M_GetText("%s recieved a point for winning!\n"), player_names[winnernum]); + players[winnernum].marescore += winnerscoreadd; + CONS_Printf(M_GetText("%s recieved %d point%s for winning!\n"), player_names[winnernum], winnerscoreadd, (winnerscoreadd == 1 ? "" : "s")); } - for (i = 0; i < MAXPLAYERS; i++) + for (i = 0; i < MAXPLAYERS; i++) // This can't go in the earlier loop because winning adds points + K_KartUpdatePosition(&players[i]); + + for (i = 0; i < MAXPLAYERS; i++) // and it can't be merged with this loop because it needs to be all updated before exiting... multi-loops suck... P_DoPlayerExit(&players[i]); } +void K_CheckSpectateStatus(void) +{ + UINT8 respawnlist[MAXPLAYERS]; + UINT8 i, numingame = 0, numjoiners = 0; + + // Get the number of players in game, and the players to be de-spectated. + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (!players[i].spectator) + { + numingame++; + if (gamestate != GS_LEVEL) // Allow if you're not in a level + continue; + if (players[i].exiting) // DON'T allow if anyone's exiting + return; + if (numingame < 2 || leveltime < starttime || mapreset) // Allow if the match hasn't started yet + continue; + if (G_RaceGametype() && players[i].laps) // DON'T allow if the race is at 2 laps + return; + continue; + } + else if (!(players[i].pflags & PF_WANTSTOJOIN)) + continue; + + respawnlist[numjoiners++] = i; + } + + // literally zero point in going any further if nobody is joining + if (!numjoiners) + return; + + // Reset the match if you're in an empty server + if (!mapreset && gamestate == GS_LEVEL && leveltime >= starttime && (numingame < 2 && numingame+numjoiners >= 2)) + { + S_ChangeMusicInternal("chalng", false); // COME ON + mapreset = 3*TICRATE; // Even though only the server uses this for game logic, set for everyone for HUD in the future + } + + // Finally, we can de-spectate everyone! + for (i = 0; i < numjoiners; i++) + P_SpectatorJoinGame(&players[respawnlist[i]]); +} + //} //{ SRB2kart HUD Code -#define NUMLAKIFRAMES 13 #define NUMPOSNUMS 10 #define NUMPOSFRAMES 7 // White, three blues, three reds +#define NUMWINFRAMES 6 // Red, yellow, green, cyan, blue, purple //{ Patch Definitions static patch_t *kp_nodraw; -static patch_t *kp_itembg; + static patch_t *kp_timesticker; static patch_t *kp_timestickerwide; static patch_t *kp_lapsticker; static patch_t *kp_lapstickernarrow; static patch_t *kp_splitlapflag; -static patch_t *kp_balloonsticker; -static patch_t *kp_balloonstickerwide; +static patch_t *kp_bumpersticker; +static patch_t *kp_bumperstickerwide; static patch_t *kp_karmasticker; static patch_t *kp_splitkarmabomb; static patch_t *kp_timeoutsticker; -static patch_t *kp_lakitustart[NUMLAKIFRAMES]; -static patch_t *kp_lakitulaps[17]; + +static patch_t *kp_startcountdown[8]; +static patch_t *kp_racefinish[2]; + static patch_t *kp_positionnum[NUMPOSNUMS][NUMPOSFRAMES]; static patch_t *kp_winnernum[NUMPOSFRAMES]; + static patch_t *kp_facenull; static patch_t *kp_facefirst; static patch_t *kp_facesecond; static patch_t *kp_facethird; static patch_t *kp_facefourth; + +static patch_t *kp_rankbumper; +static patch_t *kp_ranknobumpers; + static patch_t *kp_battlewin; +static patch_t *kp_battlecool; static patch_t *kp_battlelose; static patch_t *kp_battlewait; static patch_t *kp_battleinfo; -static patch_t *kp_magnet; -static patch_t *kp_boo; -static patch_t *kp_boosteal; -static patch_t *kp_mushroom; -static patch_t *kp_doublemushroom; -static patch_t *kp_triplemushroom; -static patch_t *kp_megashroom; -static patch_t *kp_goldshroom; -static patch_t *kp_star; -static patch_t *kp_triplebanana; -static patch_t *kp_fakeitem; -static patch_t *kp_banana; -static patch_t *kp_greenshell; -static patch_t *kp_redshell; -static patch_t *kp_triplegreenshell; -static patch_t *kp_bobomb; -static patch_t *kp_blueshell; -static patch_t *kp_fireflower; -static patch_t *kp_tripleredshell; -static patch_t *kp_lightning; -static patch_t *kp_feather; -static patch_t *kp_kitchensink; -static patch_t *kp_itemused1; -static patch_t *kp_itemused2; -static patch_t *kp_itemused3; -static patch_t *kp_itemused4; -static patch_t *kp_itemused5; -static patch_t *kp_singlebananaicon; -static patch_t *kp_doublebananaicon; -static patch_t *kp_triplebananaicon; -static patch_t *kp_singlegreenshellicon; -static patch_t *kp_doublegreenshellicon; -static patch_t *kp_triplegreenshellicon; -static patch_t *kp_singleredshellicon; -static patch_t *kp_doubleredshellicon; -static patch_t *kp_tripleredshellicon; -static patch_t *kp_check; -static patch_t *kp_checkw; -static patch_t *kp_checkstar; -static patch_t *kp_checkstarw; -static patch_t *kp_checkmega; -static patch_t *kp_checkmegaw; -static patch_t *kp_rankballoon; -static patch_t *kp_ranknoballoons; -static patch_t *kp_bswarning[2]; -/* -static patch_t *kp_neonoitem; -static patch_t *kp_electroshield; -static patch_t *kp_skghost; -static patch_t *kp_skghoststeal; -static patch_t *kp_speedshoe; -static patch_t *kp_doublespeedshoe; -static patch_t *kp_triplespeedshoe; -static patch_t *kp_sizeupmonitor; -static patch_t *kp_rocketshoe; -static patch_t *kp_invincibility; -static patch_t *kp_neotriplebanana; -static patch_t *kp_eggmanmonitor; -static patch_t *kp_neobanana; -static patch_t *kp_orbinaut; -static patch_t *kp_jaws; -static patch_t *kp_tripleorbinaut; -static patch_t *kp_specialstagemine; -static patch_t *kp_deton; -static patch_t *kp_laserwisp; -static patch_t *kp_doublejaws; -static patch_t *kp_sizedownmonitor; -static patch_t *kp_neoitemused1; -static patch_t *kp_neoitemused2; -static patch_t *kp_neoitemused3; -static patch_t *kp_neoitemused4; -static patch_t *kp_neoitemused5; -*/ +static patch_t *kp_wanted; + +static patch_t *kp_itembg[4]; +static patch_t *kp_itemmulsticker[2]; +static patch_t *kp_itemx; + +static patch_t *kp_sneaker[2]; +static patch_t *kp_rocketsneaker[2]; +static patch_t *kp_invincibility[13]; +static patch_t *kp_banana[2]; +static patch_t *kp_eggman[2]; +static patch_t *kp_orbinaut[2]; +static patch_t *kp_jawz[2]; +static patch_t *kp_mine[2]; +static patch_t *kp_ballhog[2]; +static patch_t *kp_selfpropelledbomb[2]; +static patch_t *kp_grow[2]; +static patch_t *kp_shrink[2]; +static patch_t *kp_lightningshield[2]; +static patch_t *kp_hyudoro[2]; +static patch_t *kp_pogospring[2]; +static patch_t *kp_kitchensink[2]; +static patch_t *kp_sadface[2]; + +static patch_t *kp_check[6]; + +static patch_t *kp_spbwarning[2]; + +static patch_t *kp_fpview[3]; +static patch_t *kp_inputwheel[5]; + +static patch_t *kp_challenger[25]; void K_LoadKartHUDGraphics(void) { @@ -3765,8 +4406,6 @@ void K_LoadKartHUDGraphics(void) // Null Stuff kp_nodraw = W_CachePatchName("K_TRNULL", PU_HUDGFX); - kp_itembg = W_CachePatchName("K_ITNULL", PU_HUDGFX); - //kp_neonoitem = W_CachePatchName("KNITNULL", PU_HUDGFX); // Stickers kp_timesticker = W_CachePatchName("K_STTIME", PU_HUDGFX); @@ -3774,60 +4413,42 @@ void K_LoadKartHUDGraphics(void) kp_lapsticker = W_CachePatchName("K_STLAPS", PU_HUDGFX); kp_lapstickernarrow = W_CachePatchName("K_STLAPN", PU_HUDGFX); kp_splitlapflag = W_CachePatchName("K_SPTLAP", PU_HUDGFX); - kp_balloonsticker = W_CachePatchName("K_STBALN", PU_HUDGFX); - kp_balloonstickerwide = W_CachePatchName("K_STBALW", PU_HUDGFX); + kp_bumpersticker = W_CachePatchName("K_STBALN", PU_HUDGFX); + kp_bumperstickerwide = W_CachePatchName("K_STBALW", PU_HUDGFX); kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX); kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX); kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX); - // Lakitu Start-up Frames - kp_lakitustart[0] = W_CachePatchName("K_LAKISA", PU_HUDGFX); - kp_lakitustart[1] = W_CachePatchName("K_LAKISB", PU_HUDGFX); - kp_lakitustart[2] = W_CachePatchName("K_LAKISC", PU_HUDGFX); - kp_lakitustart[3] = W_CachePatchName("K_LAKISD", PU_HUDGFX); - kp_lakitustart[4] = W_CachePatchName("K_LAKISE", PU_HUDGFX); - kp_lakitustart[5] = W_CachePatchName("K_LAKISF", PU_HUDGFX); - kp_lakitustart[6] = W_CachePatchName("K_LAKISG", PU_HUDGFX); - kp_lakitustart[7] = W_CachePatchName("K_LAKISH", PU_HUDGFX); - kp_lakitustart[8] = W_CachePatchName("K_LAKISI", PU_HUDGFX); - kp_lakitustart[9] = W_CachePatchName("K_LAKISJ", PU_HUDGFX); - kp_lakitustart[10] = W_CachePatchName("K_LAKISK", PU_HUDGFX); - kp_lakitustart[11] = W_CachePatchName("K_LAKISL", PU_HUDGFX); - kp_lakitustart[12] = W_CachePatchName("K_LAKISM", PU_HUDGFX); + // Starting countdown + kp_startcountdown[0] = W_CachePatchName("K_CNT3A", PU_HUDGFX); + kp_startcountdown[1] = W_CachePatchName("K_CNT2A", PU_HUDGFX); + kp_startcountdown[2] = W_CachePatchName("K_CNT1A", PU_HUDGFX); + kp_startcountdown[3] = W_CachePatchName("K_CNTGOA", PU_HUDGFX); + kp_startcountdown[4] = W_CachePatchName("K_CNT3B", PU_HUDGFX); + kp_startcountdown[5] = W_CachePatchName("K_CNT2B", PU_HUDGFX); + kp_startcountdown[6] = W_CachePatchName("K_CNT1B", PU_HUDGFX); + kp_startcountdown[7] = W_CachePatchName("K_CNTGOB", PU_HUDGFX); - // Lakitu Lap Frames - kp_lakitulaps[0] = W_CachePatchName("K_LAKIL2", PU_HUDGFX); - kp_lakitulaps[1] = W_CachePatchName("K_LAKIL3", PU_HUDGFX); - kp_lakitulaps[2] = W_CachePatchName("K_LAKIL4", PU_HUDGFX); - kp_lakitulaps[3] = W_CachePatchName("K_LAKIL5", PU_HUDGFX); - kp_lakitulaps[4] = W_CachePatchName("K_LAKIL6", PU_HUDGFX); - kp_lakitulaps[5] = W_CachePatchName("K_LAKIL7", PU_HUDGFX); - kp_lakitulaps[6] = W_CachePatchName("K_LAKIL8", PU_HUDGFX); - kp_lakitulaps[7] = W_CachePatchName("K_LAKIL9", PU_HUDGFX); - kp_lakitulaps[8] = W_CachePatchName("K_LAKILF", PU_HUDGFX); - kp_lakitulaps[9] = W_CachePatchName("K_LAKIF1", PU_HUDGFX); - kp_lakitulaps[10] = W_CachePatchName("K_LAKIF2", PU_HUDGFX); - kp_lakitulaps[11] = W_CachePatchName("K_LAKIF3", PU_HUDGFX); - kp_lakitulaps[12] = W_CachePatchName("K_LAKIF4", PU_HUDGFX); - kp_lakitulaps[13] = W_CachePatchName("K_LAKIF5", PU_HUDGFX); - kp_lakitulaps[14] = W_CachePatchName("K_LAKIF6", PU_HUDGFX); - kp_lakitulaps[15] = W_CachePatchName("K_LAKIF7", PU_HUDGFX); - kp_lakitulaps[16] = W_CachePatchName("K_LAKIF8", PU_HUDGFX); + kp_racefinish[0] = W_CachePatchName("K_FINA", PU_HUDGFX); + kp_racefinish[1] = W_CachePatchName("K_FINB", PU_HUDGFX); // Position numbers + sprintf(buffer, "K_POSNxx"); for (i = 0; i < NUMPOSNUMS; i++) { + buffer[6] = '0'+i; for (j = 0; j < NUMPOSFRAMES; j++) { - //if (i > 4 && j < 4 && j != 0) continue; // We don't need blue numbers for ranks past 4th - sprintf(buffer, "K_POSN%d%d", i, j); + //sprintf(buffer, "K_POSN%d%d", i, j); + buffer[7] = '0'+j; kp_positionnum[i][j] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); } } - for (i = 0; i < NUMPOSFRAMES; i++) + sprintf(buffer, "K_POSNWx"); + for (i = 0; i < NUMWINFRAMES; i++) { - sprintf(buffer, "K_POSNW%d", i); + buffer[7] = '0'+i; kp_winnernum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); } @@ -3837,114 +4458,124 @@ void K_LoadKartHUDGraphics(void) kp_facethird = W_CachePatchName("K_PFACE3", PU_HUDGFX); kp_facefourth = W_CachePatchName("K_PFACE4", PU_HUDGFX); + // Extra ranking icons + kp_rankbumper = W_CachePatchName("K_BLNICO", PU_HUDGFX); + kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); + // Battle graphics kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); + kp_battlecool = W_CachePatchName("K_BCOOL", PU_HUDGFX); kp_battlelose = W_CachePatchName("K_BLOSE", PU_HUDGFX); kp_battlewait = W_CachePatchName("K_BWAIT", PU_HUDGFX); kp_battleinfo = W_CachePatchName("K_BINFO", PU_HUDGFX); + kp_wanted = W_CachePatchName("K_WANTED", PU_HUDGFX); // Kart Item Windows - kp_magnet = W_CachePatchName("K_ITMAGN", PU_HUDGFX); - kp_boo = W_CachePatchName("K_ITBOO1", PU_HUDGFX); - kp_boosteal = W_CachePatchName("K_ITBOO2", PU_HUDGFX); - kp_mushroom = W_CachePatchName("K_ITMUSH", PU_HUDGFX); - kp_doublemushroom = W_CachePatchName("K_ITDOUB", PU_HUDGFX); - kp_triplemushroom = W_CachePatchName("K_ITTRIP", PU_HUDGFX); - kp_megashroom = W_CachePatchName("K_ITMEGA", PU_HUDGFX); - kp_goldshroom = W_CachePatchName("K_ITGOLD", PU_HUDGFX); - kp_star = W_CachePatchName("K_ITSTAR", PU_HUDGFX); - kp_triplebanana = W_CachePatchName("K_ITTBAN", PU_HUDGFX); - kp_fakeitem = W_CachePatchName("K_ITFAKE", PU_HUDGFX); - kp_banana = W_CachePatchName("K_ITBANA", PU_HUDGFX); - kp_greenshell = W_CachePatchName("K_ITGREE", PU_HUDGFX); - kp_redshell = W_CachePatchName("K_ITREDS", PU_HUDGFX); - kp_triplegreenshell = W_CachePatchName("K_ITTGRE", PU_HUDGFX); - kp_bobomb = W_CachePatchName("K_ITBOBO", PU_HUDGFX); - kp_blueshell = W_CachePatchName("K_ITBLUE", PU_HUDGFX); - kp_fireflower = W_CachePatchName("K_ITFIRE", PU_HUDGFX); - kp_tripleredshell = W_CachePatchName("K_ITTRED", PU_HUDGFX); - kp_lightning = W_CachePatchName("K_ITLIGH", PU_HUDGFX); - kp_feather = W_CachePatchName("K_ITFETH", PU_HUDGFX); - kp_kitchensink = W_CachePatchName("K_ITSINK", PU_HUDGFX); + kp_itembg[0] = W_CachePatchName("K_ITBG", PU_HUDGFX); + kp_itembg[1] = W_CachePatchName("K_ITBGD", PU_HUDGFX); + kp_itemmulsticker[0] = W_CachePatchName("K_ITMUL", PU_HUDGFX); + kp_itemx = W_CachePatchName("K_ITX", PU_HUDGFX); - // Item-used - Closing the item window after an item is used - kp_itemused1 = W_CachePatchName("K_ITUSE1", PU_HUDGFX); - kp_itemused2 = W_CachePatchName("K_ITUSE2", PU_HUDGFX); - kp_itemused3 = W_CachePatchName("K_ITUSE3", PU_HUDGFX); - kp_itemused4 = W_CachePatchName("K_ITUSE4", PU_HUDGFX); - kp_itemused5 = W_CachePatchName("K_ITUSE5", PU_HUDGFX); + kp_sneaker[0] = W_CachePatchName("K_ITSHOE", PU_HUDGFX); + kp_rocketsneaker[0] = W_CachePatchName("K_ITRSHE", PU_HUDGFX); - // Triple-item HUD icons - kp_singlebananaicon = W_CachePatchName("K_TRBAN1", PU_HUDGFX); - kp_doublebananaicon = W_CachePatchName("K_TRBAN2", PU_HUDGFX); - kp_triplebananaicon = W_CachePatchName("K_TRBAN3", PU_HUDGFX); - kp_singlegreenshellicon = W_CachePatchName("K_TRGRE1", PU_HUDGFX); - kp_doublegreenshellicon = W_CachePatchName("K_TRGRE2", PU_HUDGFX); - kp_triplegreenshellicon = W_CachePatchName("K_TRGRE3", PU_HUDGFX); - kp_singleredshellicon = W_CachePatchName("K_TRRED1", PU_HUDGFX); - kp_doubleredshellicon = W_CachePatchName("K_TRRED2", PU_HUDGFX); - kp_tripleredshellicon = W_CachePatchName("K_TRRED3", PU_HUDGFX); + sprintf(buffer, "K_ITINVx"); + for (i = 0; i < 7; i++) + { + buffer[7] = '1'+i; + kp_invincibility[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } + kp_banana[0] = W_CachePatchName("K_ITBANA", PU_HUDGFX); + kp_eggman[0] = W_CachePatchName("K_ITEGGM", PU_HUDGFX); + kp_orbinaut[0] = W_CachePatchName("K_ITORBN", PU_HUDGFX); + kp_jawz[0] = W_CachePatchName("K_ITJAWZ", PU_HUDGFX); + kp_mine[0] = W_CachePatchName("K_ITMINE", PU_HUDGFX); + kp_ballhog[0] = W_CachePatchName("K_ITBHOG", PU_HUDGFX); + kp_selfpropelledbomb[0] = W_CachePatchName("K_ITSPB", PU_HUDGFX); + kp_grow[0] = W_CachePatchName("K_ITGROW", PU_HUDGFX); + kp_shrink[0] = W_CachePatchName("K_ITSHRK", PU_HUDGFX); + kp_lightningshield[0] = W_CachePatchName("K_ITLITS", PU_HUDGFX); + kp_hyudoro[0] = W_CachePatchName("K_ITHYUD", PU_HUDGFX); + kp_pogospring[0] = W_CachePatchName("K_ITPOGO", PU_HUDGFX); + kp_kitchensink[0] = W_CachePatchName("K_ITSINK", PU_HUDGFX); + kp_sadface[0] = W_CachePatchName("K_ITSAD", PU_HUDGFX); + + // Splitscreen + kp_itembg[2] = W_CachePatchName("K_ISBG", PU_HUDGFX); + kp_itembg[3] = W_CachePatchName("K_ISBGD", PU_HUDGFX); + kp_itemmulsticker[1] = W_CachePatchName("K_ISMUL", PU_HUDGFX); + + kp_sneaker[1] = W_CachePatchName("K_ISSHOE", PU_HUDGFX); + kp_rocketsneaker[1] = W_CachePatchName("K_ISRSHE", PU_HUDGFX); + sprintf(buffer, "K_ISINVx"); + for (i = 0; i < 6; i++) + { + buffer[7] = '1'+i; + kp_invincibility[i+7] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } + kp_banana[1] = W_CachePatchName("K_ISBANA", PU_HUDGFX); + kp_eggman[1] = W_CachePatchName("K_ISEGGM", PU_HUDGFX); + kp_orbinaut[1] = W_CachePatchName("K_ISORBN", PU_HUDGFX); + kp_jawz[1] = W_CachePatchName("K_ISJAWZ", PU_HUDGFX); + kp_mine[1] = W_CachePatchName("K_ISMINE", PU_HUDGFX); + kp_ballhog[1] = W_CachePatchName("K_ISBHOG", PU_HUDGFX); + kp_selfpropelledbomb[1] = W_CachePatchName("K_ISSPB", PU_HUDGFX); + kp_grow[1] = W_CachePatchName("K_ISGROW", PU_HUDGFX); + kp_shrink[1] = W_CachePatchName("K_ISSHRK", PU_HUDGFX); + kp_lightningshield[1] = W_CachePatchName("K_ISLITS", PU_HUDGFX); + kp_hyudoro[1] = W_CachePatchName("K_ISHYUD", PU_HUDGFX); + kp_pogospring[1] = W_CachePatchName("K_ISPOGO", PU_HUDGFX); + kp_kitchensink[1] = W_CachePatchName("K_ISSINK", PU_HUDGFX); + kp_sadface[1] = W_CachePatchName("K_ISSAD", PU_HUDGFX); // CHECK indicators - kp_check = W_CachePatchName("K_CHECK1", PU_HUDGFX); - kp_checkw = W_CachePatchName("K_CHECK2", PU_HUDGFX); - kp_checkstar = W_CachePatchName("K_CHECK3", PU_HUDGFX); - kp_checkstarw = W_CachePatchName("K_CHECK4", PU_HUDGFX); - kp_checkmega = W_CachePatchName("K_CHECK5", PU_HUDGFX); - kp_checkmegaw = W_CachePatchName("K_CHECK6", PU_HUDGFX); + sprintf(buffer, "K_CHECKx"); + for (i = 0; i < 6; i++) + { + buffer[7] = '1'+i; + kp_check[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } - // Extra ranking icons - kp_rankballoon = W_CachePatchName("K_BLNICO", PU_HUDGFX); - kp_ranknoballoons = W_CachePatchName("K_NOBLNS", PU_HUDGFX); + // SPB warning + kp_spbwarning[0] = W_CachePatchName("K_SPBW1", PU_HUDGFX); + kp_spbwarning[1] = W_CachePatchName("K_SPBW2", PU_HUDGFX); - // Blue Shell warning - kp_bswarning[0] = W_CachePatchName("K_BSWRN1", PU_HUDGFX); - kp_bswarning[1] = W_CachePatchName("K_BSWRN2", PU_HUDGFX); + // First person mode + kp_fpview[0] = W_CachePatchName("VIEWA0", PU_HUDGFX); + kp_fpview[1] = W_CachePatchName("VIEWB0D0", PU_HUDGFX); + kp_fpview[2] = W_CachePatchName("VIEWC0E0", PU_HUDGFX); - /* - // Neo-Kart item windows - kp_electroshield = W_CachePatchName("KNITELEC", PU_HUDGFX); - kp_skghost = W_CachePatchName("KTITSKG1", PU_HUDGFX); - kp_skghoststeal = W_CachePatchName("KTITSKG2", PU_HUDGFX); - kp_speedshoe = W_CachePatchName("KTITSPEE", PU_HUDGFX); - kp_triplespeedshoe = W_CachePatchName("KTITTSPE", PU_HUDGFX); - kp_sizeupmonitor = W_CachePatchName("KTITSUPM", PU_HUDGFX); - kp_rocketshoe = W_CachePatchName("KTITROCK", PU_HUDGFX); - kp_invincibility = W_CachePatchName("KTITINVI", PU_HUDGFX); - kp_neotriplebanana = W_CachePatchName("KTITTBAN", PU_HUDGFX); - kp_eggmanmonitor = W_CachePatchName("KTITEGGM", PU_HUDGFX); - kp_neobanana = W_CachePatchName("KTITBANA", PU_HUDGFX); - kp_orbinaut = W_CachePatchName("KTITORBI", PU_HUDGFX); - kp_jaws = W_CachePatchName("KTITJAWS", PU_HUDGFX); - kp_tripleorbinaut = W_CachePatchName("KTITTORB", PU_HUDGFX); - kp_specialstagemine = W_CachePatchName("KTITSPEC", PU_HUDGFX); - kp_deton = W_CachePatchName("KTITDETO", PU_HUDGFX); - kp_laserwisp = W_CachePatchName("KTITLASE", PU_HUDGFX); - kp_doublejaws = W_CachePatchName("KTITDJAW", PU_HUDGFX); - kp_sizedownmonitor = W_CachePatchName("KTITSDOW", PU_HUDGFX); + // Input UI Wheel + sprintf(buffer, "K_WHEELx"); + for (i = 0; i < 5; i++) + { + buffer[7] = '0'+i; + kp_inputwheel[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } - // Item-used - Closing the item window after an item is used (Neo-Kart) - kp_neoitemused1 = W_CachePatchName("KNITUSE1", PU_HUDGFX); - kp_neoitemused2 = W_CachePatchName("KNITUSE2", PU_HUDGFX); - kp_neoitemused3 = W_CachePatchName("KNITUSE3", PU_HUDGFX); - kp_neoitemused4 = W_CachePatchName("KNITUSE4", PU_HUDGFX); - kp_neoitemused5 = W_CachePatchName("KNITUSE5", PU_HUDGFX); - */ + // HERE COMES A NEW CHALLENGER + sprintf(buffer, "K_CHALxx"); + for (i = 0; i < 25; i++) + { + buffer[6] = '0'+((i+1)/10); + buffer[7] = '0'+((i+1)%10); + kp_challenger[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } } //} INT32 ITEM_X, ITEM_Y; // Item Window -INT32 TRIP_X, TRIP_Y; // Triple Item Icon INT32 TIME_X, TIME_Y; // Time Sticker INT32 LAPS_X, LAPS_Y; // Lap Sticker INT32 SPDM_X, SPDM_Y; // Speedometer INT32 POSI_X, POSI_Y; // Position Number INT32 FACE_X, FACE_Y; // Top-four Faces -INT32 LAKI_X, LAKI_Y; // Lakitu +INT32 STCD_X, STCD_Y; // Starting countdown INT32 CHEK_Y; // CHECK graphic INT32 MINI_X, MINI_Y; // Minimap -INT32 BSWR_X, BSWR_Y; // Blue Shell warning +INT32 SPBW_X, SPBW_Y; // SPB warning +INT32 WANT_X, WANT_Y; // Battle WANTED poster static void K_initKartHUD(void) { @@ -3984,65 +4615,74 @@ static void K_initKartHUD(void) // Single Screen (defaults) // Item Window - ITEM_X = BASEVIDWIDTH - 52; // 268 - ITEM_Y = 9; // 9 - // Triple Item Object - TRIP_X = 143; // 143 - TRIP_Y = BASEVIDHEIGHT- 34; // 166 + ITEM_X = 5; // 5 + ITEM_Y = 5; // 5 // Level Timer - TIME_X = 9; // 172 - TIME_Y = 9; // 9 + TIME_X = BASEVIDWIDTH - 148; // 172 + TIME_Y = 9; // 9 // Level Laps - LAPS_X = 9; // 9 - LAPS_Y = BASEVIDHEIGHT- 29; // 171 + LAPS_X = 9; // 9 + LAPS_Y = BASEVIDHEIGHT - 29; // 171 // Speedometer - SPDM_X = 9; // 9 - SPDM_Y = BASEVIDHEIGHT- 45; // 155 + SPDM_X = 9; // 9 + SPDM_Y = BASEVIDHEIGHT - 45; // 155 // Position Number - POSI_X = BASEVIDWIDTH - 9; // 268 - POSI_Y = BASEVIDHEIGHT- 9; // 138 + POSI_X = BASEVIDWIDTH - 9; // 268 + POSI_Y = BASEVIDHEIGHT - 9; // 138 // Top-Four Faces - FACE_X = 9; // 9 - FACE_Y = 92; // 92 - // Lakitu - LAKI_X = 136; // 138 - LAKI_Y = 58 - 200; // 58 + FACE_X = 9; // 9 + FACE_Y = 92; // 92 + // Starting countdown + STCD_X = BASEVIDWIDTH/2; // 9 + STCD_Y = BASEVIDHEIGHT/2; // 92 // CHECK graphic - CHEK_Y = BASEVIDHEIGHT; // 200 + CHEK_Y = BASEVIDHEIGHT; // 200 // Minimap - MINI_X = BASEVIDWIDTH - 50; // 270 - MINI_Y = BASEVIDHEIGHT/2; // 100 + MINI_X = BASEVIDWIDTH - 50; // 270 + MINI_Y = (BASEVIDHEIGHT/2)-16; // 84 // Blue Shell warning - BSWR_X = BASEVIDWIDTH/2; // 270 - BSWR_Y = BASEVIDHEIGHT- 24; // 176 + SPBW_X = BASEVIDWIDTH/2; // 270 + SPBW_Y = BASEVIDHEIGHT- 24; // 176 + // Battle WANTED poster + WANT_X = BASEVIDWIDTH - 55; // 270 + WANT_Y = BASEVIDHEIGHT- 71; // 176 if (splitscreen) // Splitscreen { - ITEM_X = 9; - ITEM_Y = 4; + ITEM_X = 5; + ITEM_Y = 3; LAPS_Y = (BASEVIDHEIGHT/2)-24; POSI_Y = (BASEVIDHEIGHT/2)- 2; + STCD_Y = BASEVIDHEIGHT/4; + MINI_Y = (BASEVIDHEIGHT/2); - BSWR_Y = (BASEVIDHEIGHT/2)-8; + SPBW_Y = (BASEVIDHEIGHT/2)-8; + + WANT_X = BASEVIDWIDTH-8; + WANT_Y = (BASEVIDHEIGHT/2)-12; if (splitscreen > 1) // 3P/4P Small Splitscreen { - ITEM_X = 0; - ITEM_Y = 0; + ITEM_X = -9; + ITEM_Y = -8; LAPS_X = 3; LAPS_Y = (BASEVIDHEIGHT/2)-13; POSI_X = (BASEVIDWIDTH/2)-3; + STCD_X = BASEVIDWIDTH/4; + MINI_X = (3*BASEVIDWIDTH/4); MINI_Y = (3*BASEVIDHEIGHT/4); - BSWR_X = BASEVIDWIDTH/4; + SPBW_X = BASEVIDWIDTH/4; + + WANT_X = (BASEVIDWIDTH/2)-8; if (splitscreen > 2) // 4P-only { @@ -4051,6 +4691,13 @@ static void K_initKartHUD(void) } } } + + if (timeinmap > 113) + hudtrans = cv_translucenthud.value; + else if (timeinmap > 105) + hudtrans = ((((INT32)timeinmap) - 105)*cv_translucenthud.value)/(113-105); + else + hudtrans = 0; } INT32 K_calcSplitFlags(INT32 snapflags) @@ -4091,333 +4738,261 @@ INT32 K_calcSplitFlags(INT32 snapflags) return (splitflags|snapflags); } -static void K_drawKartItemClose(void) -{ - // ITEM_X = BASEVIDWIDTH-50; // 270 - // ITEM_Y = 24; // 24 - - // Why write V_DrawScaledPatch calls over and over when they're all the same? - // Set to 'no draw' just in case. - patch_t *localpatch = kp_nodraw; - INT32 splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTORIGHT); - - if (splitscreen) - splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOLEFT); - - /*if () - switch (stplyr->kartstuff[k_itemclose]) - { - case 1: localpatch = kp_neoitemused5; break; - case 3: localpatch = kp_neoitemused4; break; - case 5: localpatch = kp_neoitemused3; break; - case 7: localpatch = kp_neoitemused2; break; - case 9: localpatch = kp_neoitemused1; break; - default: break; - } - else*/ - switch (stplyr->kartstuff[k_itemclose]) - { - case 1: localpatch = kp_itemused5; break; - case 3: localpatch = kp_itemused4; break; - case 5: localpatch = kp_itemused3; break; - case 7: localpatch = kp_itemused2; break; - case 9: localpatch = kp_itemused1; break; - default: break; - } - - if (localpatch != kp_nodraw) - V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); -} - -static void K_drawKartItemRoulette(void) +static void K_drawKartItem(void) { // ITEM_X = BASEVIDWIDTH-50; // 270 // ITEM_Y = 24; // 24 // Why write V_DrawScaledPatch calls over and over when they're all the same? // Set to 'no item' just in case. + const UINT8 offset = ((splitscreen > 1) ? 1 : 0); patch_t *localpatch = kp_nodraw; - patch_t *localbg = kp_itembg; - INT32 splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTORIGHT); + patch_t *localbg = ((splitscreen > 1) ? kp_itembg[2] : kp_itembg[0]); + patch_t *localinv = ((splitscreen > 1) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]); + INT32 splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOLEFT); - if (splitscreen) + if (stplyr->kartstuff[k_itemroulette]) { - splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOLEFT); - if (splitscreen > 1) - localbg = kp_itemused1; - } - - /*if () - switch(stplyr->kartstuff[k_itemroulette] % 53) + switch((stplyr->kartstuff[k_itemroulette] % (13*3)) / 3) { // Each case is handled in threes, to give three frames of in-game time to see the item on the roulette - // I'm also skipping by threes for the power order as to what item shows on the roulette - case 0: case 1: case 2: localpatch = kp_electroshield; break; // Electro-Shield - case 3: case 4: case 5: localpatch = kp_triplespeedshoe; break; // Triple Speed Shoe - case 6: case 7: case 8: localpatch = kp_invincibility; break; // Invincibility - case 9: case 10: case 11: localpatch = kp_neobanana; break; // Banana - case 12: case 13: case 14: localpatch = kp_tripleorbinaut; break; // 3x Orbinaut - case 15: case 16: case 17: localpatch = kp_laserwisp; break; // Laser Wisp - case 18: case 19: case 20: localpatch = kp_skghost; break; // S3K Ghost - case 21: case 22: case 23: localpatch = kp_sizeupmonitor; break; // Size-Up Monitor - case 24: case 25: case 26: localpatch = kp_neotriplebanana; break; // Triple Banana - case 27: case 28: case 29: localpatch = kp_orbinaut; break; // 1x Orbinaut - case 30: case 31: case 32: localpatch = kp_specialstagemine; break; // Specialstage Mines - case 33: case 34: case 35: localpatch = kp_doublejaws; break; // 2x Jaws - case 36: case 37: case 38: localpatch = kp_speedshoe; break; // Speed Shoe - case 39: case 40: case 41: localpatch = kp_rocketshoe; break; // Rocket Shoe - case 42: case 43: case 44: localpatch = kp_eggmanmonitor; break; // Eggman Monitor - case 45: case 46: case 47: localpatch = kp_jaws; break; // 1x Jaws - case 48: case 49: case 50: localpatch = kp_deton; break; // Deton - case 51: case 52: case 53: localpatch = kp_sizedownmonitor; break; // Size-Down Monitor + case 0: localpatch = kp_sneaker[offset]; break; // Sneaker + case 1: localpatch = kp_banana[offset]; break; // Banana + case 2: localpatch = kp_orbinaut[offset]; break; // Orbinaut + case 3: localpatch = kp_mine[offset]; break; // Mine + case 4: localpatch = kp_grow[offset]; break; // Grow + case 5: localpatch = kp_hyudoro[offset]; break; // Hyudoro + case 6: localpatch = kp_rocketsneaker[offset]; break; // Rocket Sneaker + case 7: localpatch = kp_jawz[offset]; break; // Jawz + case 8: localpatch = kp_selfpropelledbomb[offset]; break; // Self-Propelled Bomb + case 9: localpatch = kp_shrink[offset]; break; // Shrink + case 10: localpatch = localinv; break; // Invincibility + case 11: localpatch = kp_eggman[offset]; break; // Eggman Monitor + case 12: localpatch = kp_ballhog[offset]; break; // Ballhog + case 13: localpatch = kp_lightningshield[offset]; break; // Lightning Shield + //case 14: localpatch = kp_pogospring[offset]; break; // Pogo Spring + //case 15: localpatch = kp_kitchensink[offset]; break; // Kitchen Sink default: break; } - else*/ - switch(stplyr->kartstuff[k_itemroulette] % 53) - { - // Each case is handled in threes, to give three frames of in-game time to see the item on the roulette - // I'm also skipping by threes for the power order as to what item shows on the roulette - case 0: case 1: case 2: localpatch = kp_magnet; break; // Magnet - case 3: case 4: case 5: localpatch = kp_triplemushroom; break; // Triple Mushroom - case 6: case 7: case 8: localpatch = kp_star; break; // Star - case 9: case 10: case 11: localpatch = kp_banana; break; // Banana - case 12: case 13: case 14: localpatch = kp_triplegreenshell; break; // Triple Green Shell - case 15: case 16: case 17: localpatch = kp_fireflower; break; // Fire Flower - case 18: case 19: case 20: localpatch = kp_boo; break; // Boo - case 21: case 22: case 23: localpatch = kp_megashroom; break; // Mega Mushroom - case 24: case 25: case 26: localpatch = kp_triplebanana; break; // Triple Banana - case 27: case 28: case 29: localpatch = kp_greenshell; break; // Green Shell - case 30: case 31: case 32: localpatch = kp_bobomb; break; // Bob-omb - case 33: case 34: case 35: localpatch = kp_tripleredshell; break; // Triple Red Shell - case 36: case 37: case 38: localpatch = kp_mushroom; break; // Mushroom - case 39: case 40: case 41: localpatch = kp_goldshroom; break; // Gold Mushroom - case 42: case 43: case 44: localpatch = kp_fakeitem; break; // Fake Item - case 45: case 46: case 47: localpatch = kp_redshell; break; // Red Shell - case 48: case 49: case 50: localpatch = kp_blueshell; break; // Blue Shell - case 51: case 52: case 53: localpatch = kp_lightning; break; // Lightning - default: break; - } - - if (localpatch == kp_nodraw) - return; - - V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localbg); - V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); -} - -static void K_drawKartRetroItem(void) -{ - // ITEM_X = BASEVIDWIDTH-50; // 270 - // ITEM_Y = 24; // 24 - - // Why write V_DrawScaledPatch calls over and over when they're all the same? - // Set to 'no item' just in case. - patch_t *localpatch = kp_nodraw; - patch_t *localbg = kp_itembg; - INT32 X = ITEM_X; - INT32 splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTORIGHT); - - if (splitscreen) - { - splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOLEFT); - if (splitscreen > 1) - localbg = kp_itemused1; - } - - // I'm doing this a little weird and drawing mostly in reverse order - // The only actual reason is to make triple/double/single mushrooms line up this way in the code below - // This shouldn't have any actual baring over how it functions - // Boo is first, because we're drawing it on top of the player's current item - if ((stplyr->kartstuff[k_bootaketimer] > 0 || stplyr->kartstuff[k_boostolentimer] > 0) - && (leveltime & 2)) localpatch = kp_boosteal; - else if (stplyr->kartstuff[k_boostolentimer] > 0 && !(leveltime & 2)) localpatch = kp_nodraw; - else if (stplyr->kartstuff[k_kitchensink] == 1) localpatch = kp_kitchensink; - else if (stplyr->kartstuff[k_feather] & 1) localpatch = kp_feather; - else if (stplyr->kartstuff[k_lightning] == 1) localpatch = kp_lightning; - else if (stplyr->kartstuff[k_tripleredshell]) localpatch = kp_tripleredshell; // &8 - else if (stplyr->kartstuff[k_fireflower] == 1) localpatch = kp_fireflower; - else if (stplyr->kartstuff[k_blueshell] == 1) localpatch = kp_blueshell; - else if (stplyr->kartstuff[k_bobomb]) localpatch = kp_bobomb; // &2 - else if (stplyr->kartstuff[k_triplegreenshell]) localpatch = kp_triplegreenshell; // &8 - else if (stplyr->kartstuff[k_redshell]) localpatch = kp_redshell; // &2 - else if (stplyr->kartstuff[k_greenshell]) localpatch = kp_greenshell; // &2 - else if (stplyr->kartstuff[k_banana]) localpatch = kp_banana; // &2 - else if (stplyr->kartstuff[k_fakeitem] & 2) localpatch = kp_fakeitem; - else if (stplyr->kartstuff[k_triplebanana]) localpatch = kp_triplebanana; // &8 - else if (stplyr->kartstuff[k_star] == 1) localpatch = kp_star; - else if (stplyr->kartstuff[k_goldshroom] == 1 - || (stplyr->kartstuff[k_goldshroomtimer] > 1 && (leveltime & 1))) localpatch = kp_goldshroom; - else if (stplyr->kartstuff[k_goldshroomtimer] > 1 && !(leveltime & 1)) localpatch = kp_nodraw; - else if (stplyr->kartstuff[k_megashroom] == 1 - || (stplyr->kartstuff[k_growshrinktimer] > 1 && (leveltime & 1))) localpatch = kp_megashroom; - else if (stplyr->kartstuff[k_growshrinktimer] > 1 && !(leveltime & 1)) localpatch = kp_nodraw; - else if (stplyr->kartstuff[k_mushroom] & 4) localpatch = kp_triplemushroom; - else if (stplyr->kartstuff[k_mushroom] & 2) localpatch = kp_doublemushroom; - else if (stplyr->kartstuff[k_mushroom] == 1) localpatch = kp_mushroom; - else if (stplyr->kartstuff[k_boo] == 1) localpatch = kp_boo; - else if (stplyr->kartstuff[k_magnet] == 1) localpatch = kp_magnet; - - if (localpatch == kp_nodraw) - return; - - V_DrawScaledPatch(X, ITEM_Y, V_HUDTRANS|splitflags, localbg); - V_DrawScaledPatch(X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); -} - -/* -static void K_drawKartNeoItem(void) -{ - // ITEM_X = BASEVIDWIDTH-50; // 270 - // ITEM_Y = 24; // 24 - - // Why write V_DrawScaledPatch calls over and over when they're all the same? - // Set to 'no item' just in case. - patch_t *localpatch = kp_noitem; - - // I'm doing this a little weird and drawing mostly in reverse order - // The only actual reason is to make triple/double/single mushrooms line up this way in the code below - // This shouldn't have any actual baring over how it functions - // Boo is first, because we're drawing it on top of the player's current item - if ((stplyr->kartstuff[k_bootaketimer] > 0 - || stplyr->kartstuff[k_boostolentimer] > 0) && (leveltime & 2)) localpatch = kp_skghoststeal; - else if (stplyr->kartstuff[k_boostolentimer] > 0 && !(leveltime & 2)) localpatch = kp_neonoitem; - else if (stplyr->kartstuff[k_lightning] == 1) localpatch = kp_sizedownmonitor; - else if (stplyr->kartstuff[k_jaws] & 4) localpatch = kp_doublejaws; - else if (stplyr->kartstuff[k_laserwisp] == 1) localpatch = kp_laserwisp; - else if (stplyr->kartstuff[k_blueshell] == 1) localpatch = kp_deton; - else if (stplyr->kartstuff[k_bobomb] & 2) localpatch = kp_specialstagemine; - else if (stplyr->kartstuff[k_triplegreenshell] & 8) localpatch = kp_tripleorbinaut; - else if (stplyr->kartstuff[k_redshell] & 2) localpatch = kp_jaws; - else if (stplyr->kartstuff[k_greenshell] & 2) localpatch = kp_orbinaut; - else if (stplyr->kartstuff[k_banana] & 2) localpatch = kp_neobanana; - else if (stplyr->kartstuff[k_fakeitem] & 2) localpatch = kp_eggmanmonitor; - else if (stplyr->kartstuff[k_triplebanana] & 8) localpatch = kp_neotriplebanana; - else if (stplyr->kartstuff[k_star] == 1) localpatch = kp_invincibility; - else if (stplyr->kartstuff[k_goldshroom] == 1 - || (stplyr->kartstuff[k_goldshroomtimer] > 1 && (leveltime & 1))) localpatch = kp_rocketshoe; - else if (stplyr->kartstuff[k_goldshroomtimer] > 1 && !(leveltime & 1)) localpatch = kp_neonoitem; - else if (stplyr->kartstuff[k_megashroom] == 1 - || (stplyr->kartstuff[k_growshrinktimer] > 1 && (leveltime & 1))) localpatch = kp_sizeupmonitor; - else if (stplyr->kartstuff[k_growshrinktimer] > 1 && !(leveltime & 1)) localpatch = kp_neonoitem; - else if (stplyr->kartstuff[k_mushroom] & 4) localpatch = kp_triplespeedshoe; - else if (stplyr->kartstuff[k_mushroom] & 2) localpatch = kp_doublespeedshoe; - else if (stplyr->kartstuff[k_mushroom] == 1) localpatch = kp_speedshoe; - else if (stplyr->kartstuff[k_boo] & 8) localpatch = kp_skghost; - else if (stplyr->kartstuff[k_magnet] & 8) localpatch = kp_electroshield; - - V_DrawScaledPatch(ITEM_X, ITEM_Y, V_SNAPTORIGHT|V_HUDTRANSHALF, localpatch); -} -*/ - -/* -static void K_DrawKartTripleItem(void) -{ - // TRIP_X = 143; // 143 - // TRIP_Y = BASEVIDHEIGHT-34; // 166 - - // Why write V_DrawScaledPatch calls over and over when they're all the same? - // Set to 'no draw' just in case. - patch_t *localpatch = kp_nodraw; - INT32 thisitem; - - if () - { - thisitem = stplyr->kartstuff[k_triplebanana]; - if (thisitem & 1) localpatch = kp_singleneobananaicon; - else if (thisitem & 2) localpatch = kp_doubleneobananaicon; - else if (thisitem & 4) localpatch = kp_tripleneobananaicon; - - thisitem = stplyr->kartstuff[k_triplegreenshell]; - if (thisitem & 1) localpatch = kp_singleorbitauricon; - else if (thisitem & 2) localpatch = kp_doubleorbitauricon; - else if (thisitem & 4) localpatch = kp_tripleorbitauricon; - - thisitem = stplyr->kartstuff[k_jaws]; - if (thisitem & 1) localpatch = kp_singlejawsicon; - else if (thisitem & 2) localpatch = kp_doublejawsicon; } else { - thisitem = stplyr->kartstuff[k_triplebanana]; - if (thisitem & 4) localpatch = kp_triplebananaicon; - else if (thisitem & 2) localpatch = kp_doublebananaicon; - else if (thisitem & 1) localpatch = kp_singlebananaicon; + // I'm doing this a little weird and drawing mostly in reverse order + // The only actual reason is to make sneakers line up this way in the code below + // This shouldn't have any actual baring over how it functions + // Hyudoro is first, because we're drawing it on top of the player's current item + if (stplyr->kartstuff[k_stolentimer] > 0) + { + if (leveltime & 2) + localpatch = kp_hyudoro[offset]; + else if (!(leveltime & 2)) + localpatch = kp_nodraw; + } + else if ((stplyr->kartstuff[k_stealingtimer] > 0) && (leveltime & 2)) + { + localpatch = kp_hyudoro[offset]; + } + else if (stplyr->kartstuff[k_rocketsneakertimer] > 1) + { + if (leveltime & 1) + localpatch = kp_rocketsneaker[offset]; + else if (!(leveltime & 1)) + localpatch = kp_nodraw; + } + else if (stplyr->kartstuff[k_growshrinktimer] > 1) + { + if (leveltime & 1) + localpatch = kp_grow[offset]; + else if (!(leveltime & 1)) + localpatch = kp_nodraw; + } + else if (stplyr->kartstuff[k_sadtimer] > 0) + { + if (leveltime & 2) + localpatch = kp_sadface[offset]; + else if (!(leveltime & 2)) + localpatch = kp_nodraw; + } + else + { + if (!(stplyr->kartstuff[k_itemamount] || stplyr->kartstuff[k_itemheld])) + return; - thisitem = stplyr->kartstuff[k_triplegreenshell]; - if (thisitem & 4) localpatch = kp_triplegreenshellicon; - else if (thisitem & 2) localpatch = kp_doublegreenshellicon; - else if (thisitem & 1) localpatch = kp_singlegreenshellicon; - - thisitem = stplyr->kartstuff[k_tripleredshell]; - if (thisitem & 4) localpatch = kp_tripleredshellicon; - else if (thisitem & 2) localpatch = kp_doubleredshellicon; - else if (thisitem & 1) localpatch = kp_singleredshellicon; - - if (stplyr->kartstuff[k_banana] & 1) localpatch = kp_singlebananaicon; - if (stplyr->kartstuff[k_greenshell] & 1) localpatch = kp_singlegreenshellicon; - if (stplyr->kartstuff[k_redshell] & 1) localpatch = kp_singleredshellicon; + switch(stplyr->kartstuff[k_itemtype]) + { + case KITEM_SNEAKER: localpatch = kp_sneaker[offset]; break; + case KITEM_ROCKETSNEAKER: localpatch = kp_rocketsneaker[offset]; break; + case KITEM_INVINCIBILITY: localpatch = localinv; localbg = kp_itembg[offset+1]; break; + case KITEM_BANANA: localpatch = kp_banana[offset]; break; + case KITEM_EGGMAN: localpatch = kp_eggman[offset]; break; + case KITEM_ORBINAUT: localpatch = kp_orbinaut[offset]; break; + case KITEM_JAWZ: localpatch = kp_jawz[offset]; break; + case KITEM_MINE: localpatch = kp_mine[offset]; break; + case KITEM_BALLHOG: localpatch = kp_ballhog[offset]; break; + case KITEM_SPB: localpatch = kp_selfpropelledbomb[offset]; break; + case KITEM_GROW: localpatch = kp_grow[offset]; break; + case KITEM_SHRINK: localpatch = kp_shrink[offset]; break; + case KITEM_LIGHTNINGSHIELD: localpatch = kp_lightningshield[offset]; break; + case KITEM_HYUDORO: localpatch = kp_hyudoro[offset]; break; + case KITEM_POGOSPRING: localpatch = kp_pogospring[offset]; break; + case KITEM_KITCHENSINK: localpatch = kp_kitchensink[offset]; break; + case KITEM_SAD: localpatch = kp_sadface[offset]; break; + default: return; + } + } } - if (localpatch != kp_nodraw) - V_DrawScaledPatch(TRIP_X, TRIP_Y, V_SNAPTOBOTTOM, localpatch); + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localbg); + + // Then, the numbers: + if (stplyr->kartstuff[k_itemamount] > 1 && !stplyr->kartstuff[k_itemroulette]) + { + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, kp_itemmulsticker[offset]); + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); + if (splitscreen > 1) + V_DrawString(ITEM_X+24, ITEM_Y+31, V_ALLOWLOWERCASE|V_HUDTRANS|splitflags, va("x%d", stplyr->kartstuff[k_itemamount])); + else + { + V_DrawScaledPatch(ITEM_X+28, ITEM_Y+41, V_HUDTRANS|splitflags, kp_itemx); + V_DrawKartString(ITEM_X+38, ITEM_Y+36, V_HUDTRANS|splitflags, va("%d", stplyr->kartstuff[k_itemamount])); + } + } + else + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); } -*/ static void K_drawKartTimestamp(void) { // TIME_X = BASEVIDWIDTH-124; // 196 // TIME_Y = 6; // 6 - INT32 TIME_XB; - INT32 splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOLEFT); + INT32 TIME_XB, splitflags = V_HUDTRANS|K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTORIGHT); + tic_t drawtime = stplyr->realtime; - V_DrawScaledPatch(TIME_X, TIME_Y, V_HUDTRANS|splitflags, kp_timestickerwide); + if (cv_timelimit.value && timelimitintics > 0) + { + if (drawtime >= timelimitintics) + drawtime = 0; + else + drawtime = timelimitintics - drawtime; + } + + V_DrawScaledPatch(TIME_X, TIME_Y, splitflags, kp_timestickerwide); TIME_XB = TIME_X+33; - if (stplyr->realtime/(60*TICRATE) < 100) // 99:99:99 only + if (drawtime/(60*TICRATE) < 100) // 99:99:99 only { // zero minute - if (stplyr->realtime/(60*TICRATE) < 10) + if (drawtime/(60*TICRATE) < 10) { - V_DrawKartString(TIME_XB, TIME_Y+3, V_HUDTRANS|splitflags, va("0")); + V_DrawKartString(TIME_XB, TIME_Y+3, splitflags, va("0")); // minutes time 0 __ __ - V_DrawKartString(TIME_XB+12, TIME_Y+3, V_HUDTRANS|splitflags, va("%d", stplyr->realtime/(60*TICRATE))); + V_DrawKartString(TIME_XB+12, TIME_Y+3, splitflags, va("%d", drawtime/(60*TICRATE))); } // minutes time 0 __ __ else - V_DrawKartString(TIME_XB, TIME_Y+3, V_HUDTRANS|splitflags, va("%d", stplyr->realtime/(60*TICRATE))); + V_DrawKartString(TIME_XB, TIME_Y+3, splitflags, va("%d", drawtime/(60*TICRATE))); // apostrophe location _'__ __ - V_DrawKartString(TIME_XB+24, TIME_Y+3, V_HUDTRANS|splitflags, va("'")); + V_DrawKartString(TIME_XB+24, TIME_Y+3, splitflags, va("'")); // zero second _ 0_ __ - if ((stplyr->realtime/TICRATE % 60) < 10) + if ((drawtime/TICRATE % 60) < 10) { - V_DrawKartString(TIME_XB+36, TIME_Y+3, V_HUDTRANS|splitflags, va("0")); + V_DrawKartString(TIME_XB+36, TIME_Y+3, splitflags, va("0")); // seconds time _ _0 __ - V_DrawKartString(TIME_XB+48, TIME_Y+3, V_HUDTRANS|splitflags, va("%d", stplyr->realtime/TICRATE % 60)); + V_DrawKartString(TIME_XB+48, TIME_Y+3, splitflags, va("%d", drawtime/TICRATE % 60)); } // zero second _ 00 __ else - V_DrawKartString(TIME_XB+36, TIME_Y+3, V_HUDTRANS|splitflags, va("%d", stplyr->realtime/TICRATE % 60)); + V_DrawKartString(TIME_XB+36, TIME_Y+3, splitflags, va("%d", drawtime/TICRATE % 60)); // quotation mark location _ __"__ - V_DrawKartString(TIME_XB+60, TIME_Y+3, V_HUDTRANS|splitflags, va("\"")); + V_DrawKartString(TIME_XB+60, TIME_Y+3, splitflags, va("\"")); // zero tick _ __ 0_ - if (G_TicsToCentiseconds(stplyr->realtime) < 10) + if (G_TicsToCentiseconds(drawtime) < 10) { - V_DrawKartString(TIME_XB+72, TIME_Y+3, V_HUDTRANS|splitflags, va("0")); + V_DrawKartString(TIME_XB+72, TIME_Y+3, splitflags, va("0")); // tics _ __ _0 - V_DrawKartString(TIME_XB+84, TIME_Y+3, V_HUDTRANS|splitflags, va("%d", G_TicsToCentiseconds(stplyr->realtime))); + V_DrawKartString(TIME_XB+84, TIME_Y+3, splitflags, va("%d", G_TicsToCentiseconds(drawtime))); } // zero tick _ __ 00 - if (G_TicsToCentiseconds(stplyr->realtime) >= 10) - V_DrawKartString(TIME_XB+72, TIME_Y+3, V_HUDTRANS|splitflags, va("%d", G_TicsToCentiseconds(stplyr->realtime))); + if (G_TicsToCentiseconds(drawtime) >= 10) + V_DrawKartString(TIME_XB+72, TIME_Y+3, splitflags, va("%d", G_TicsToCentiseconds(drawtime))); + } + else if ((drawtime/TICRATE) & 1) + V_DrawKartString(TIME_XB, TIME_Y+3, splitflags, va("99'59\"99")); + + if (modeattacking) // emblem time! + { + INT32 workx = TIME_XB + 96, worky = TIME_Y+18; + SINT8 curemb = 0; + patch_t *emblempic[3] = {NULL, NULL, NULL}; + UINT8 *emblemcol[3] = {NULL, NULL, NULL}; + + emblem_t *emblem = M_GetLevelEmblems(gamemap); + while (emblem) + { + char targettext[9]; + + switch (emblem->type) + { + case ET_TIME: + { + static boolean canplaysound = true; + tic_t timetoreach = emblem->var; + + if (emblem->collected) + { + emblempic[curemb] = W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE); + emblemcol[curemb] = R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE); + if (++curemb == 3) + break; + goto bademblem; + } + + snprintf(targettext, 9, "%i:%02i.%02i", + G_TicsToMinutes(timetoreach, false), + G_TicsToSeconds(timetoreach), + G_TicsToCentiseconds(timetoreach)); + + if (stplyr->realtime > timetoreach) + { + splitflags = (splitflags &~ V_HUDTRANS)|V_HUDTRANSHALF; + if (canplaysound) + { + S_StartSound(NULL, sfx_s3k72); //sfx_s26d); -- you STOLE fizzy lifting drinks + canplaysound = false; + } + } + else if (!canplaysound) + canplaysound = true; + + targettext[8] = 0; + } + break; + default: + goto bademblem; + } + + V_DrawRightAlignedString(workx, worky, splitflags, targettext); + workx -= 69; // i SWEAR i wasn't aiming for this + V_DrawSmallScaledPatch(workx + 4, worky, splitflags, W_CachePatchName("NEEDIT", PU_CACHE)); + + break; + + bademblem: + emblem = M_GetLevelEmblems(-1); + } + + while (curemb--) + { + workx -= 16; + V_DrawSmallMappedPatch(workx + 4, worky, splitflags, emblempic[curemb], emblemcol[curemb]); + } } - else - V_DrawKartString(TIME_XB, TIME_Y+3, V_HUDTRANS|splitflags, va("99'59\"99")); } static void K_DrawKartPositionNum(INT32 num) @@ -4451,36 +5026,7 @@ static void K_DrawKartPositionNum(INT32 num) while (num) { if (stplyr->exiting && num == 1) // 1st place winner? You get rainbows!! - { - // Alternate frame every three frames - switch (leveltime % 21) - { - case 1: case 2: case 3: - localpatch = kp_winnernum[0]; - break; - case 4: case 5: case 6: - localpatch = kp_winnernum[1]; - break; - case 7: case 8: case 9: - localpatch = kp_winnernum[2]; - break; - case 10: case 11: case 12: - localpatch = kp_winnernum[3]; - break; - case 13: case 14: case 15: - localpatch = kp_winnernum[4]; - break; - case 16: case 17: case 18: - localpatch = kp_winnernum[5]; - break; - case 19: case 20: case 21: - localpatch = kp_winnernum[6]; - break; - default: - localpatch = kp_positionnum[1][0]; - break; - } - } + localpatch = kp_winnernum[(leveltime % (NUMWINFRAMES*3)) / 3]; else if (stplyr->laps+1 >= cv_numlaps.value || stplyr->exiting) // Check for the final lap, or won { // Alternate frame every three frames @@ -4519,7 +5065,7 @@ static void K_DrawKartPositionNum(INT32 num) } } -static void K_drawKartPositionFaces(void) +static boolean K_drawKartPositionFaces(void) { // FACE_X = 15; // 15 // FACE_Y = 72; // 72 @@ -4528,41 +5074,47 @@ static void K_drawKartPositionFaces(void) INT32 i, j, ranklines; boolean completed[MAXPLAYERS]; INT32 rankplayer[MAXPLAYERS]; - INT32 rankcolor[MAXPLAYERS]; - INT32 myplayer; - INT32 balloonx; + INT32 bumperx, numplayersingame = 0; UINT8 *colormap; patch_t *localpatch = kp_facenull; ranklines = 0; memset(completed, 0, sizeof (completed)); memset(rankplayer, 0, sizeof (rankplayer)); - memset(rankcolor, 0, sizeof (rankcolor)); - myplayer = demoplayback ? displayplayer : consoleplayer; for (i = 0; i < MAXPLAYERS; i++) + { rankplayer[i] = -1; - for (j = 0; j < MAXPLAYERS; j++) - { - if (!playeringame[j] || players[j].spectator || !players[j].mo) + if (!playeringame[i] || players[i].spectator || !players[i].mo) continue; + numplayersingame++; + } + + if (numplayersingame <= 1) + return true; + + for (j = 0; j < numplayersingame; j++) + { for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && completed[i] == false && players[i].mo && !players[i].spectator && (rankplayer[ranklines] < 0 || players[i].kartstuff[k_position] < players[rankplayer[ranklines]].kartstuff[k_position])) { rankplayer[ranklines] = i; - rankcolor[ranklines] = players[i].skincolor; } } - completed[rankplayer[ranklines]] = true; + i = rankplayer[ranklines]; + + completed[i] = true; + + if (ranklines == 4) + break; // Only draw the top 4 players + ranklines++; } - if (ranklines > 4) ranklines = 4; // Only draw the top 4 players - Y -= (9*ranklines); for (i = 0; i < ranklines; i++) @@ -4570,70 +5122,23 @@ static void K_drawKartPositionFaces(void) if (players[rankplayer[i]].spectator) continue; // Spectators are ignored if (!players[rankplayer[i]].mo) continue; - balloonx = FACE_X+18; + bumperx = FACE_X+18; - if (rankcolor[i] == 0) - { - colormap = colormaps; - if (rankplayer[i] != myplayer) - { - V_DrawSmallTranslucentPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin]); - if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_balloon] > 0) - { - for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) - { - V_DrawSmallTranslucentPatch(balloonx, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_rankballoon); - balloonx += 3; - } - } - } - else - { - V_DrawSmallScaledPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin]); - if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_balloon] > 0) - { - for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) - { - V_DrawSmallScaledPatch(balloonx, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_rankballoon); - balloonx += 3; - } - } - } - } - else + if (players[rankplayer[i]].mo->color) { colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE); if (players[rankplayer[i]].mo->colorized) - { - colormap = R_GetTranslationColormap(TC_STARMAN, players[rankplayer[i]].mo->color, GTC_CACHE); - } + colormap = R_GetTranslationColormap(TC_RAINBOW, players[rankplayer[i]].mo->color, GTC_CACHE); else - { colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE); - } - if (rankplayer[i] != myplayer) + V_DrawSmallMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); + if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_bumper] > 0) { - V_DrawSmallTranslucentMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); - if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_balloon] > 0) + for (j = 0; j < players[rankplayer[i]].kartstuff[k_bumper]; j++) { - for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) - { - V_DrawSmallTranslucentMappedPatch(balloonx, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_rankballoon, colormap); - balloonx += 3; - } - } - } - else - { - V_DrawSmallMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); - if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_balloon] > 0) - { - for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) - { - V_DrawSmallMappedPatch(balloonx, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_rankballoon, colormap); - balloonx += 3; - } + V_DrawSmallMappedPatch(bumperx, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_rankbumper, colormap); + bumperx += 3; } } } @@ -4648,23 +5153,15 @@ static void K_drawKartPositionFaces(void) default: break; } - if (rankplayer[i] != myplayer) - { - if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_balloon] <= 0) - V_DrawSmallTranslucentPatch(FACE_X-2, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_ranknoballoons); - else - V_DrawSmallTranslucentPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, localpatch); - } + if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_bumper] <= 0) + V_DrawSmallScaledPatch(FACE_X-2, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_ranknobumpers); else - { - if (G_BattleGametype() && players[rankplayer[i]].kartstuff[k_balloon] <= 0) - V_DrawSmallScaledPatch(FACE_X-2, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_ranknoballoons); - else - V_DrawSmallScaledPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, localpatch); - } + V_DrawSmallScaledPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, localpatch); Y += 18; } + + return false; } static void K_drawKartLaps(void) @@ -4696,74 +5193,74 @@ static void K_drawKartSpeedometer(void) fixed_t convSpeed; INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT); - if (cv_speedometer.value == 1) + if (cv_kartspeedometer.value == 1) // Kilometers { convSpeed = FixedDiv(FixedMul(stplyr->speed, 142371), mapheaderinfo[gamemap-1]->mobj_scale)/FRACUNIT; // 2.172409058 V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d km/h", convSpeed)); } - else if (cv_speedometer.value == 2) + else if (cv_kartspeedometer.value == 2) // Miles { convSpeed = FixedDiv(FixedMul(stplyr->speed, 88465), mapheaderinfo[gamemap-1]->mobj_scale)/FRACUNIT; // 1.349868774 V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d mph", convSpeed)); } - else if (cv_speedometer.value == 3) + else if (cv_kartspeedometer.value == 3) // Fracunits { convSpeed = FixedDiv(stplyr->speed, mapheaderinfo[gamemap-1]->mobj_scale)/FRACUNIT; V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d fu/t", convSpeed)); } } -static void K_drawKartBalloonsOrKarma(void) +static void K_drawKartBumpersOrKarma(void) { UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, 0); INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT); if (splitscreen > 1) { - if (stplyr->kartstuff[k_balloon] <= 0) + if (stplyr->kartstuff[k_bumper] <= 0) { V_DrawMappedPatch(LAPS_X, LAPS_Y-1, V_HUDTRANS|splitflags, kp_splitkarmabomb, colormap); V_DrawString(LAPS_X+13, LAPS_Y+1, V_HUDTRANS|splitflags, va("%d/3", stplyr->kartstuff[k_comebackpoints])); } else { - V_DrawMappedPatch(LAPS_X, LAPS_Y-1, V_HUDTRANS|splitflags, kp_rankballoon, colormap); - V_DrawString(LAPS_X+13, LAPS_Y+1, V_HUDTRANS|splitflags, va("%d/%d", stplyr->kartstuff[k_balloon], cv_kartballoons.value)); + V_DrawMappedPatch(LAPS_X, LAPS_Y-1, V_HUDTRANS|splitflags, kp_rankbumper, colormap); + V_DrawString(LAPS_X+13, LAPS_Y+1, V_HUDTRANS|splitflags, va("%d/%d", stplyr->kartstuff[k_bumper], cv_kartbumpers.value)); } } else { - if (stplyr->kartstuff[k_balloon] <= 0) + if (stplyr->kartstuff[k_bumper] <= 0) { V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|splitflags, kp_karmasticker, colormap); V_DrawKartString(LAPS_X+59, LAPS_Y+3, V_HUDTRANS|splitflags, va("%d/3", stplyr->kartstuff[k_comebackpoints])); } else { - if (stplyr->kartstuff[k_balloon] > 9 && cv_kartballoons.value > 9) - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|splitflags, kp_balloonstickerwide, colormap); + if (stplyr->kartstuff[k_bumper] > 9 && cv_kartbumpers.value > 9) + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|splitflags, kp_bumperstickerwide, colormap); else - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|splitflags, kp_balloonsticker, colormap); - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|splitflags, va("%d/%d", stplyr->kartstuff[k_balloon], cv_kartballoons.value)); + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|splitflags, kp_bumpersticker, colormap); + V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|splitflags, va("%d/%d", stplyr->kartstuff[k_bumper], cv_kartbumpers.value)); } } } -static void K_drawBlueShellWarning(void) +static void K_drawSPBWarning(void) { patch_t *localpatch = kp_nodraw; INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM); if (!(stplyr->kartstuff[k_deathsentence] > 0 - || (blueshellincoming > 0 && blueshellincoming < 2*TICRATE && stplyr->kartstuff[k_position] == 1))) + || (spbincoming > 0 && spbincoming < 2*TICRATE && stplyr->kartstuff[k_position] == 1))) return; if (leveltime % 8 > 3) - localpatch = kp_bswarning[1]; + localpatch = kp_spbwarning[1]; else - localpatch = kp_bswarning[0]; + localpatch = kp_spbwarning[0]; - V_DrawScaledPatch(BSWR_X, BSWR_Y, splitflags, localpatch); + V_DrawScaledPatch(SPBW_X, SPBW_Y, splitflags, localpatch); } fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my) @@ -4794,16 +5291,73 @@ fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my return x; } +static void K_drawKartWanted(void) +{ + UINT8 i, numwanted = 0; + UINT8 *colormap = NULL; + + if (splitscreen) // Can't fit the poster on screen, sadly + { + if (K_IsPlayerWanted(stplyr) && leveltime % 10 > 3) + V_DrawRightAlignedString(WANT_X, WANT_Y, K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS|V_REDMAP), "WANTED"); + return; + } + + for (i = 0; i < 4; i++) + { + if (battlewanted[i] == -1) + break; + numwanted++; + } + + if (numwanted <= 0) + return; + + if (battlewanted[0] != -1) + colormap = R_GetTranslationColormap(0, players[battlewanted[0]].skincolor, GTC_CACHE); + V_DrawFixedPatch(WANT_X< 1) + y += 17; + } + + if (players[battlewanted[i]].skincolor == 0) + V_DrawFixedPatch(x<skin], NULL); + else + { + colormap = R_GetTranslationColormap(TC_RAINBOW, p->skincolor, GTC_CACHE); + V_DrawFixedPatch(x<skin], colormap); + } + } +} + static void K_drawKartPlayerCheck(void) { INT32 i; UINT8 *colormap; INT32 x; - patch_t *localpatch; INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM); - if (!(stplyr->mo)) + if (!stplyr->mo || stplyr->spectator) return; if (stplyr->awayviewtics) @@ -4814,31 +5368,22 @@ static void K_drawKartPlayerCheck(void) for (i = 0; i < MAXPLAYERS; i++) { + UINT8 pnum = 0; + + if (&players[i] == stplyr) + continue; if (!playeringame[i] || players[i].spectator) continue; if (!players[i].mo) continue; - if (&players[i] == stplyr) - continue; - if ((players[i].kartstuff[k_startimer] <= 0) && (leveltime & 2)) - { - if (players[i].kartstuff[k_megashroom] || players[i].kartstuff[k_growshrinktimer] > 0) - localpatch = kp_checkmegaw; - else if (players[i].kartstuff[k_star] || players[i].kartstuff[k_startimer]) - localpatch = kp_checkstarw; - else - localpatch = kp_checkw; - } - else - { - if (players[i].kartstuff[k_megashroom] || players[i].kartstuff[k_growshrinktimer] > 0) - localpatch = kp_checkmega; - else if (players[i].kartstuff[k_star] || players[i].kartstuff[k_startimer]) - localpatch = kp_checkstar; - else - localpatch = kp_check; - } + if ((players[i].kartstuff[k_invincibilitytimer] <= 0) && (leveltime & 2)) + pnum++; // white frames + + if (players[i].kartstuff[k_itemtype] == KITEM_GROW || players[i].kartstuff[k_growshrinktimer] > 0) + pnum += 4; + else if (players[i].kartstuff[k_itemtype] == KITEM_INVINCIBILITY || players[i].kartstuff[k_invincibilitytimer]) + pnum += 2; x = K_FindCheckX(stplyr->mo->x, stplyr->mo->y, stplyr->mo->angle, players[i].mo->x, players[i].mo->y); if (x <= 320 && x >= 0) @@ -4849,7 +5394,7 @@ static void K_drawKartPlayerCheck(void) x = 306; colormap = R_GetTranslationColormap(TC_DEFAULT, players[i].mo->color, 0); - V_DrawMappedPatch(x, CHEK_Y, V_HUDTRANS|splitflags, localpatch, colormap); + V_DrawMappedPatch(x, CHEK_Y, V_HUDTRANS|splitflags, kp_check[pnum], colormap); } } } @@ -4883,7 +5428,7 @@ void K_ReloadSkinIconGraphics(void) K_LoadIconGraphics(skins[i].iconprefix, i); } -static void K_drawKartMinimapHead(player_t *player, INT32 x, INT32 y, INT32 flags, patch_t *AutomapPic) +static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, patch_t *AutomapPic) { // amnum xpos & ypos are the icon's speed around the HUD. // The number being divided by is for how fast it moves. @@ -4892,13 +5437,21 @@ static void K_drawKartMinimapHead(player_t *player, INT32 x, INT32 y, INT32 flag // am xpos & ypos are the icon's starting position. Withouht // it, they wouldn't 'spawn' on the top-right side of the HUD. - fixed_t amnumxpos; - fixed_t amnumypos; - INT32 amxpos; - INT32 amypos; + UINT8 skin = 0; + + fixed_t amnumxpos, amnumypos; + INT32 amxpos, amypos; node_t *bsp = &nodes[numnodes-1]; fixed_t maxx, minx, maxy, miny; + + fixed_t mapwidth, mapheight; + fixed_t xoffset, yoffset; + fixed_t xscale, yscale, zoom; + + if (mo->skin) + skin = ((skin_t*)mo->skin)-skins; + maxx = maxy = INT32_MAX; minx = miny = INT32_MIN; minx = bsp->bbox[0][BOXLEFT]; @@ -4924,43 +5477,43 @@ static void K_drawKartMinimapHead(player_t *player, INT32 x, INT32 y, INT32 flag miny >>= FRACBITS; maxy >>= FRACBITS; - fixed_t mapwidth = maxx - minx; - fixed_t mapheight = maxy - miny; + mapwidth = maxx - minx; + mapheight = maxy - miny; // These should always be small enough to be bitshift back right now - fixed_t xoffset = (minx + mapwidth/2)<width, mapwidth); - fixed_t yscale = FixedDiv(AutomapPic->height, mapheight); - fixed_t zoom = FixedMul(min(xscale, yscale), FRACUNIT-FRACUNIT/20); + xscale = FixedDiv(AutomapPic->width, mapwidth); + yscale = FixedDiv(AutomapPic->height, mapheight); + zoom = FixedMul(min(xscale, yscale), FRACUNIT-FRACUNIT/20); - amnumxpos = (FixedMul(player->mo->x, zoom) - FixedMul(xoffset, zoom)); - amnumypos = -(FixedMul(player->mo->y, zoom) - FixedMul(yoffset, zoom)); - - amxpos = amnumxpos + ((x + AutomapPic->width/2 - (iconprefix[player->skin]->width/2))<height/2 - (iconprefix[player->skin]->height/2))<x, zoom) - FixedMul(xoffset, zoom)); + amnumypos = -(FixedMul(mo->y, zoom) - FixedMul(yoffset, zoom)); if (mirrormode) + amnumxpos = -amnumxpos; + + amxpos = amnumxpos + ((x + AutomapPic->width/2 - (iconprefix[skin]->width/2))<height/2 - (iconprefix[skin]->height/2))<width/2 + (iconprefix[player->skin]->width/2))<width/2 + (iconprefix[skin]->width/2))<skincolor) // 'default' color - V_DrawSciencePatch(amxpos, amypos, flags, iconprefix[player->skin], FRACUNIT); + if (!mo->color) // 'default' color + V_DrawSciencePatch(amxpos, amypos, flags, iconprefix[skin], FRACUNIT); else { UINT8 *colormap; - if (player->mo->colorized) - { - colormap = R_GetTranslationColormap(TC_STARMAN, player->mo->color, 0); - } + if (mo->colorized) + colormap = R_GetTranslationColormap(TC_RAINBOW, mo->color, 0); else - { - colormap = R_GetTranslationColormap(player->skin, player->mo->color, 0); - } - V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, iconprefix[player->skin], colormap); + colormap = R_GetTranslationColormap(skin, mo->color, 0); + V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, iconprefix[skin], colormap); } } @@ -4970,8 +5523,8 @@ static void K_drawKartMinimap(void) patch_t *AutomapPic; INT32 i = 0; INT32 x, y; - const INT32 minimaptrans = ((10-cv_kartminimap.value)<width/2); y = MINI_Y - (AutomapPic->height/2); - if (splitscreen) - splitflags = 0; + if (timeinmap > 105) + { + minimaptrans = (splitscreen ? 10 : cv_kartminimap.value); + if (timeinmap <= 113) + minimaptrans = ((((INT32)timeinmap) - 105)*minimaptrans)/(113-105); + if (!minimaptrans) + return; + } + else + return; + + minimaptrans = ((10-minimaptrans)<width), y, splitflags|V_FLIP, AutomapPic); @@ -5012,37 +5576,104 @@ static void K_drawKartMinimap(void) x -= SHORT(AutomapPic->leftoffset); y -= SHORT(AutomapPic->topoffset); - // Player's tiny icons on the Automap. - for (i = 0; i < MAXPLAYERS; i++) + // Player's tiny icons on the Automap. (drawn opposite direction so player 1 is drawn last in splitscreen) + if (ghosts) { - if (i == displayplayer && !splitscreen) - continue; // Do displayplayer later - if (players[i].mo && !players[i].spectator) + demoghost *g = ghosts; + while (g) { - if (G_BattleGametype() && players[i].kartstuff[k_balloon] <= 0) + K_drawKartMinimapHead(g->mo, x, y, splitflags, AutomapPic); + g = g->next; + } + if (!stplyr->mo || stplyr->spectator) // do we need the latter..? + return; + dop1later = true; + } + else + { + for (i = MAXPLAYERS-1; i >= 0; i--) + { + if (!playeringame[i]) + continue; + if (!players[i].mo || players[i].spectator) continue; - if (players[i].kartstuff[k_bootimer] > 0) + if (!splitscreen && i == displayplayer) { - if ((players[i].kartstuff[k_bootimer] < 1*TICRATE/2 - || players[i].kartstuff[k_bootimer] > bootime-(1*TICRATE/2)) - && !(leveltime & 1)) - ; - else + dop1later = true; // Do displayplayer later + continue; + } + + if (G_BattleGametype() && players[i].kartstuff[k_bumper] <= 0) + continue; + if (players[i].kartstuff[k_hyudorotimer] > 0) + { + if (!((players[i].kartstuff[k_hyudorotimer] < 1*TICRATE/2 + || players[i].kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2)) + && !(leveltime & 1))) continue; } - K_drawKartMinimapHead(&players[i], x, y, splitflags, AutomapPic); + K_drawKartMinimapHead(players[i].mo, x, y, splitflags, AutomapPic); } } - if (splitscreen) - return; // Don't need this for splits + if (!dop1later) + return; // Don't need this splitflags &= ~V_HUDTRANSHALF; splitflags |= V_HUDTRANS; - if (stplyr->mo && !stplyr->spectator) - K_drawKartMinimapHead(stplyr, x, y, splitflags, AutomapPic); + K_drawKartMinimapHead(stplyr->mo, x, y, splitflags, AutomapPic); +} + +static void K_drawKartStartCountdown(void) +{ + INT32 pnum = 0, splitflags = K_calcSplitFlags(0); // 3 + + if (leveltime >= starttime-(2*TICRATE)) // 2 + pnum++; + if (leveltime >= starttime-TICRATE) // 1 + pnum++; + if (leveltime >= starttime) // GO! + pnum++; + if ((leveltime % (2*5)) / 5) // blink + pnum += 4; + + if (splitscreen) + V_DrawSmallScaledPatch(STCD_X - (SHORT(kp_startcountdown[pnum]->width)/4), STCD_Y - (SHORT(kp_startcountdown[pnum]->height)/4), splitflags, kp_startcountdown[pnum]); + else + V_DrawScaledPatch(STCD_X - (SHORT(kp_startcountdown[pnum]->width)/2), STCD_Y - (SHORT(kp_startcountdown[pnum]->height)/2), splitflags, kp_startcountdown[pnum]); +} + +static void K_drawKartFinish(void) +{ + INT32 pnum = 0, splitflags = K_calcSplitFlags(0); + + if (!stplyr->kartstuff[k_cardanimation] || stplyr->kartstuff[k_cardanimation] >= 2*TICRATE) + return; + + if ((stplyr->kartstuff[k_cardanimation] % (2*5)) / 5) // blink + pnum = 1; + + if (splitscreen > 1) + { + V_DrawTinyScaledPatch(STCD_X - (SHORT(kp_racefinish[pnum]->width)/8), STCD_Y - (SHORT(kp_racefinish[pnum]->height)/8), splitflags, kp_racefinish[pnum]); + return; + } + + { + INT32 scaleshift = (FRACBITS - splitscreen); // FRACUNIT or FRACUNIT/2 + INT32 x = ((vid.width<width)<kartstuff[k_cardanimation])*(xval > x ? xval : x))/TICRATE; + + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + x = -x; + + V_DrawFixedPatch(x + (STCD_X<width)<<(scaleshift-1)), + (STCD_Y<height)<<(scaleshift-1)), + (1<exiting) { if (stplyr == &players[displayplayer]) - V_DrawFadeScreen(); - if (stplyr->kartstuff[k_balloon]) - V_DrawFixedPatch(x<exiting < 6*TICRATE) + { + if (stplyr->kartstuff[k_position] == 1) + V_DrawFixedPatch(x<kartstuff[k_balloon] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback) + else if (stplyr->kartstuff[k_bumper] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback) { - INT32 t = stplyr->kartstuff[k_comebacktimer]/TICRATE; - INT32 txoff = 0; + UINT16 t = stplyr->kartstuff[k_comebacktimer]/(10*TICRATE); + INT32 txoff, adjust = (splitscreen > 1) ? 4 : 6; // normal string is 8, kart string is 12, half of that for ease INT32 ty = (BASEVIDHEIGHT/2)+66; - if (t == 0) - txoff = 8; - else + txoff = adjust; + + while (t) { - while (t) - { - txoff += 8; - t /= 10; - } + txoff += adjust; + t /= 10; } if (splitscreen) { - if (splitscreen > 2) + if (splitscreen > 1) ty = (BASEVIDHEIGHT/4)+33; if ((splitscreen == 1 && stplyr == &players[secondarydisplayplayer]) || (stplyr == &players[thirddisplayplayer] && splitscreen > 1) @@ -5119,7 +5752,7 @@ static void K_drawBattleFullscreen(void) ty += (BASEVIDHEIGHT/2); } else - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); if (!comebackshowninfo) V_DrawFixedPatch(x< 1) - V_DrawString(x-(txoff/2), ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); + V_DrawString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); else { V_DrawFixedPatch(x<kartstuff[k_comebacktimer]/TICRATE)); } } + + if (netgame && !stplyr->spectator && timeinmap > 113) // FREE PLAY? + { + UINT8 i; + + // check to see if there's anyone else at all + for (i = 0; i < MAXPLAYERS; i++) + { + if (i == displayplayer) + continue; + if (playeringame[i] && !stplyr->spectator) + return; + } + + K_drawKartFreePlay(leveltime); + } } -static void K_drawStartLakitu(void) +static void K_drawKartFirstPerson(void) { - patch_t *localpatch = kp_nodraw; + static INT32 pnum[4], turn[4], drift[4]; + INT32 pn = 0, tn = 0, dr = 0; + INT32 target = 0, splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM); + INT32 x = BASEVIDWIDTH/2, y = BASEVIDHEIGHT; + fixed_t scale; + UINT8 *colmap = NULL; + ticcmd_t *cmd = &stplyr->cmd; - fixed_t adjustY; - tic_t numFrames = 32; // Number of frames for the animation - fixed_t finalOffset = 206; // Number of pixels to offset the patch (This is actually 200, the 6 is a buffer for the parabola) + if (stplyr->spectator || !stplyr->mo || (stplyr->mo->flags2 & MF2_DONTDRAW)) + return; - if (leveltime < 52) localpatch = kp_lakitustart[0]; - if (leveltime >= 52 && leveltime < 56) localpatch = kp_lakitustart[1]; - if (leveltime >= 56 && leveltime < 60) localpatch = kp_lakitustart[2]; - if (leveltime >= 60 && leveltime < 64) localpatch = kp_lakitustart[3]; - if (leveltime >= 64 && leveltime < 91) localpatch = kp_lakitustart[4]; - if (leveltime >= 91 && leveltime < 95) localpatch = kp_lakitustart[5]; - if (leveltime >= 95 && leveltime < 99) localpatch = kp_lakitustart[6]; - if (leveltime >= 99 && leveltime < 103) localpatch = kp_lakitustart[7]; - if (leveltime >= 103 && leveltime < 130) localpatch = kp_lakitustart[8]; - if (leveltime >= 130 && leveltime < 134) localpatch = kp_lakitustart[9]; - if (leveltime >= 134 && leveltime < 138) localpatch = kp_lakitustart[10]; - if (leveltime >= 138 && leveltime < 142) localpatch = kp_lakitustart[11]; - if (leveltime >= 142 && leveltime < 178) localpatch = kp_lakitustart[12]; - - if (leveltime <= numFrames) - adjustY = (finalOffset - 1) - FixedMul((finalOffset), FRACUNIT / (leveltime + 3)); - else if (leveltime >= 146) - { - fixed_t templeveltime = leveltime - 145; - adjustY = (finalOffset - 1) - FixedMul((finalOffset), FRACUNIT / (numFrames + 3 - templeveltime)); - } + if (stplyr == &players[secondarydisplayplayer] && splitscreen) + { pn = pnum[1]; tn = turn[1]; dr = drift[1]; } + else if (stplyr == &players[thirddisplayplayer] && splitscreen > 1) + { pn = pnum[2]; tn = turn[2]; dr = drift[2]; } + else if (stplyr == &players[fourthdisplayplayer] && splitscreen > 2) + { pn = pnum[3]; tn = turn[3]; dr = drift[3]; } else - adjustY = 200; + { pn = pnum[0]; tn = turn[0]; dr = drift[0]; } + + if (splitscreen) + { + y >>= 1; + if (splitscreen > 1) + x >>= 1; + } + + { + if (stplyr->speed < FixedMul(stplyr->runspeed, stplyr->mo->scale) && (leveltime & 1) && !splitscreen) + y++; + // the following isn't EXPLICITLY right, it just gets the result we want, but i'm too lazy to look up the right way to do it + if (stplyr->mo->flags2 & MF2_SHADOW) + splitflags |= FF_TRANS80; + else if (stplyr->mo->frame & FF_TRANSMASK) + splitflags |= (stplyr->mo->frame & FF_TRANSMASK); + } + + if (cmd->driftturn > 400) // strong left turn + target = 2; + else if (cmd->driftturn < -400) // strong right turn + target = -2; + else if (cmd->driftturn > 0) // weak left turn + target = 1; + else if (cmd->driftturn < 0) // weak right turn + target = -1; + else // forward + target = 0; if (mirrormode) - V_DrawSmallScaledPatch(320-LAKI_X, LAKI_Y + adjustY, V_SNAPTOTOP|V_FLIP, localpatch); - else - V_DrawSmallScaledPatch(LAKI_X, LAKI_Y + adjustY, V_SNAPTOTOP, localpatch); -} + target = -target; -static void K_drawLapLakitu(void) -{ - patch_t *localpatch = kp_nodraw; + if (pn < target) + pn++; + else if (pn > target) + pn--; - fixed_t swoopTimer = 80 - stplyr->kartstuff[k_lapanimation]; // Starts at 80, goes down by 1 per frame - fixed_t adjustY; - fixed_t numFrames = 32; // Number of frames for the animation - fixed_t finalOffset = 206; // Number of pixels to offset the patch (This is actually 200, the 6 is a buffer for the parabola) - boolean finishLine = false; + if (pn < 0) + splitflags |= V_FLIP; // right turn - if (stplyr->laps < (UINT8)(cv_numlaps.value - 1)) + target = abs(pn); + if (target > 2) + target = 2; + + x <<= FRACBITS; + y <<= FRACBITS; + + if (tn != cmd->driftturn/50) + tn -= (tn - (cmd->driftturn/50))/8; + + if (dr != stplyr->kartstuff[k_drift]*16) + dr -= (dr - (stplyr->kartstuff[k_drift]*16))/8; + + if (splitscreen == 1) { - switch (stplyr->laps) + scale = (2*FRACUNIT)/3; + y += FRACUNIT/(vid.dupx < vid.dupy ? vid.dupx : vid.dupy); // correct a one-pixel gap on the screen view (not the basevid view) + } + else if (splitscreen) + scale = FRACUNIT/2; + else + scale = FRACUNIT; + + if (stplyr->mo) + { + fixed_t dsone = K_GetKartDriftSparkValue(stplyr); + fixed_t dstwo = dsone*2; + +#ifndef DONTLIKETOASTERSFPTWEAKS { - case 1: localpatch = kp_lakitulaps[0]; break; - case 2: localpatch = kp_lakitulaps[1]; break; - case 3: localpatch = kp_lakitulaps[2]; break; - case 4: localpatch = kp_lakitulaps[3]; break; - case 5: localpatch = kp_lakitulaps[4]; break; - case 6: localpatch = kp_lakitulaps[5]; break; - case 7: localpatch = kp_lakitulaps[6]; break; - case 8: localpatch = kp_lakitulaps[7]; break; - } - } - else if (stplyr->laps == (UINT8)(cv_numlaps.value - 1)) - localpatch = kp_lakitulaps[8]; - else - { - // Change flag frame every 4 frames - switch (leveltime % 32) - { - case 0: case 1: case 2: case 3: - localpatch = kp_lakitulaps[9]; break; - case 4: case 5: case 6: case 7: - localpatch = kp_lakitulaps[10]; break; - case 8: case 9: case 10: case 11: - localpatch = kp_lakitulaps[11]; break; - case 12: case 13: case 14: case 15: - localpatch = kp_lakitulaps[12]; break; - case 16: case 17: case 18: case 19: - localpatch = kp_lakitulaps[13]; break; - case 20: case 21: case 22: case 23: - localpatch = kp_lakitulaps[14]; break; - case 24: case 25: case 26: case 27: - localpatch = kp_lakitulaps[15]; break; - case 28: case 29: case 30: case 31: - localpatch = kp_lakitulaps[16]; break; - } - finishLine = true; - finalOffset = 226; - } + const angle_t ang = R_PointToAngle2(0, 0, stplyr->rmomx, stplyr->rmomy) - stplyr->frameangle; + // yes, the following is correct. no, you do not need to swap the x and y. + fixed_t xoffs = -P_ReturnThrustY(stplyr->mo, ang, (BASEVIDWIDTH<<(FRACBITS-2))/2); + fixed_t yoffs = -(P_ReturnThrustX(stplyr->mo, ang, 4*FRACUNIT) - 4*FRACUNIT); - if (swoopTimer <= numFrames) - adjustY = (finalOffset - 1) - FixedMul((finalOffset), FRACUNIT / (swoopTimer + 3)); - else if (swoopTimer >= 48) - { - fixed_t templeveltime = swoopTimer - 47; - adjustY = (finalOffset - 1) - FixedMul((finalOffset), FRACUNIT / (numFrames + 3 - templeveltime)); - } - else - { - if (finishLine) - adjustY = 220; + if (splitscreen) + xoffs = FixedMul(xoffs, scale); + + xoffs -= (tn)*scale; + xoffs -= (dr)*scale; + + if (stplyr->frameangle == stplyr->mo->angle) + { + const fixed_t mag = FixedDiv(stplyr->speed, 10*stplyr->mo->scale); + + if (mag < FRACUNIT) + { + xoffs = FixedMul(xoffs, mag); + if (!splitscreen) + yoffs = FixedMul(yoffs, mag); + } + } + + if (stplyr->mo->momz > 0) // TO-DO: Draw more of the kart so we can remove this if! + yoffs += stplyr->mo->momz/3; + + if (mirrormode) + x -= xoffs; + else + x += xoffs; + if (!splitscreen) + y += yoffs; + } + + // drift sparks! + if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dstwo)) + colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_TANGERINE, 0); + else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsone)) + colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, 0); else - adjustY = 200; +#endif + // invincibility/grow/shrink! + if (stplyr->mo->colorized && stplyr->mo->color) + colmap = R_GetTranslationColormap(TC_RAINBOW, stplyr->mo->color, 0); } - if (mirrormode) - V_DrawSmallScaledPatch(320-(LAKI_X+14+(swoopTimer/4)), LAKI_Y + adjustY, V_SNAPTOTOP|V_FLIP, localpatch); + V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap); + + if (stplyr == &players[secondarydisplayplayer] && splitscreen) + { pnum[1] = pn; turn[1] = tn; drift[1] = dr; } + else if (stplyr == &players[thirddisplayplayer] && splitscreen > 1) + { pnum[2] = pn; turn[2] = tn; drift[2] = dr; } + else if (stplyr == &players[fourthdisplayplayer] && splitscreen > 2) + { pnum[3] = pn; turn[3] = tn; drift[3] = dr; } else - V_DrawSmallScaledPatch(LAKI_X+14+(swoopTimer/4), LAKI_Y + adjustY, V_SNAPTOTOP, localpatch); + { pnum[0] = pn; turn[0] = tn; drift[0] = dr; } +} + +// doesn't need to ever support 4p +static void K_drawInput(void) +{ + static INT32 pn = 0; + INT32 target = 0, splitflags = (V_SNAPTOBOTTOM|V_SNAPTORIGHT); + INT32 x = BASEVIDWIDTH - 32, y = BASEVIDHEIGHT-24, offs, col; + const INT32 accent1 = splitflags|colortranslations[stplyr->skincolor][5]; + const INT32 accent2 = splitflags|colortranslations[stplyr->skincolor][9]; + ticcmd_t *cmd = &stplyr->cmd; + + if (timeinmap <= 105) + return; + + if (timeinmap < 113) + { + INT32 count = ((INT32)(timeinmap) - 105); + offs = 64; + while (count-- > 0) + offs >>= 1; + x += offs; + } + +#define BUTTW 8 +#define BUTTH 11 + +#define drawbutt(xoffs, butt, symb)\ + if (stplyr->cmd.buttons & butt)\ + {\ + offs = 2;\ + col = accent1;\ + }\ + else\ + {\ + offs = 0;\ + col = accent2;\ + V_DrawFill(x+(xoffs), y+BUTTH, BUTTW-1, 2, splitflags|31);\ + }\ + V_DrawFill(x+(xoffs), y+offs, BUTTW-1, BUTTH, col);\ + V_DrawFixedPatch((x+1+(xoffs))<driftturn) // no turn + target = 0; + else // turning of multiple strengths! + { + target = ((abs(cmd->driftturn) - 1)/125)+1; + if (target > 4) + target = 4; + if (cmd->driftturn < 0) + target = -target; + } + + if (pn != target) + { + if (abs(pn - target) == 1) + pn = target; + else if (pn < target) + pn += 2; + else //if (pn > target) + pn -= 2; + } + + if (pn < 0) + { + splitflags |= V_FLIP; // right turn + x--; + } + + target = abs(pn); + if (target > 4) + target = 4; + + if (!stplyr->skincolor) + V_DrawFixedPatch(x<skincolor, 0); + V_DrawFixedPatch(x<starpostnum) >= numstarposts) + V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Can finish)", stplyr->starpostnum, numstarposts)); + else + V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Skip: %d)", stplyr->starpostnum, numstarposts, (numstarposts/2 + stplyr->starpostnum))); + V_DrawString(8, 192, 0, va("Waypoint dist: Prev %d, Next %d", stplyr->kartstuff[k_prevcheck], stplyr->kartstuff[k_nextcheck])); +} + +void K_drawKartFreePlay(UINT32 flashtime) +{ + // no splitscreen support because it's not FREE PLAY if you have more than one player in-game + + if ((flashtime % TICRATE) < TICRATE/2) + return; + + V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy + LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY"); } void K_drawKartHUD(void) { + boolean isfreeplay = false; + // Define the X and Y for each drawn object // This is handled by console/menu values K_initKartHUD(); - if (splitscreen == 2) // Player 4 in 3P is basically the minimap :p + // Draw that fun first person HUD! Drawn ASAP so it looks more "real". + if ((stplyr == &players[displayplayer] && !camera.chase) + || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase) + || ((splitscreen > 1 && stplyr == &players[thirddisplayplayer]) && !camera3.chase) + || ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase)) + K_drawKartFirstPerson(); + + // Draw a white fade on level opening + if (leveltime < 15 && stplyr == &players[displayplayer]) + { + if (leveltime <= 5) + V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,120); // Pure white on first few frames, to hide SRB2's awful level load artifacts + else + V_DrawFadeScreen(120, 15-leveltime); // Then gradually fade out from there + } + + if (splitscreen == 2) // Player 4 in 3P is the minimap :p K_drawKartMinimap(); // Draw full screen stuff that turns off the rest of the HUD + if (mapreset) + { + K_drawChallengerScreen(); + return; + } + if ((G_BattleGametype()) && (stplyr->exiting - || (stplyr->kartstuff[k_balloon] <= 0 + || (stplyr->kartstuff[k_bumper] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback && stplyr->playerstate == PST_LIVE))) @@ -5268,39 +6105,19 @@ void K_drawKartHUD(void) return; } - // Draw Lakitu - // This is done first so that regardless of HUD layers, - // he'll appear to be in the 'real world' - if (!splitscreen) - { - if (leveltime < 178) - K_drawStartLakitu(); - - if (stplyr->kartstuff[k_lapanimation]) - K_drawLapLakitu(); - - // Draw the CHECK indicator before the other items too, so it's overlapped by everything else - if (cv_kartcheck.value) - K_drawKartPlayerCheck(); - } + // Draw the CHECK indicator before the other items, so it's overlapped by everything else + if (cv_kartcheck.value && !splitscreen && !players[displayplayer].exiting) + K_drawKartPlayerCheck(); if (splitscreen == 0 && cv_kartminimap.value) K_drawKartMinimap(); // 3P splitscreen is handled above - // If the item window is closing, draw it closing! - if (stplyr->kartstuff[k_itemclose]) - K_drawKartItemClose(); + // Draw the item window + K_drawKartItem(); - // If the item-roulette is going, draw that - // Otherwise, draw the item window normally (separated for retro/neo, to prevent this block from becoming a mess - if (stplyr->kartstuff[k_itemroulette]) - K_drawKartItemRoulette(); - // else if () - // K_drawKartNeoItem(); - else - K_drawKartRetroItem(); - - //K_DrawKartTripleItem(); + // Draw WANTED status + if (G_BattleGametype()) + K_drawKartWanted(); // If not splitscreen, draw... if (!splitscreen) @@ -5310,9 +6127,8 @@ void K_drawKartHUD(void) if (!modeattacking) { - // The little triple-item icons at the bottom // The top-four faces on the left - K_drawKartPositionFaces(); + isfreeplay = K_drawKartPositionFaces(); } } @@ -5330,21 +6146,55 @@ void K_drawKartHUD(void) K_drawKartSpeedometer(); } - if (!modeattacking) + if (isfreeplay) + ; + else if (!modeattacking) { // Draw the numerical position K_DrawKartPositionNum(stplyr->kartstuff[k_position]); } + else //if (!(demoplayback && hu_showscores)) + { + // Draw the input UI + K_drawInput(); + } // You're about to DIEEEEE - K_drawBlueShellWarning(); + K_drawSPBWarning(); } else if (G_BattleGametype()) // Battle-only { // Draw the hits left! - K_drawKartBalloonsOrKarma(); + K_drawKartBumpersOrKarma(); } } + + // Draw the countdowns after everything else. + if (leveltime >= starttime-(3*TICRATE) + && leveltime < starttime+TICRATE) + K_drawKartStartCountdown(); + else if (countdown && (!splitscreen || !stplyr->exiting)) + { + char *countstr = va("%d", countdown/TICRATE); + + if (splitscreen > 1) + V_DrawCenteredString(BASEVIDWIDTH/4, LAPS_Y+1, K_calcSplitFlags(0), countstr); + else + { + INT32 karlen = strlen(countstr)*6; // half of 12 + V_DrawKartString((BASEVIDWIDTH/2)-karlen, LAPS_Y+3, K_calcSplitFlags(0), countstr); + } + } + + if (stplyr->exiting && G_RaceGametype()) + K_drawKartFinish(); + + if (cv_kartdebugcheckpoint.value) + K_drawCheckpointDebugger(); + + // Draw FREE PLAY. + if (isfreeplay && !stplyr->spectator && timeinmap > 113) + K_drawKartFreePlay(leveltime); } //} diff --git a/src/k_kart.h b/src/k_kart.h index 694450d8..c0810a86 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -11,42 +11,54 @@ UINT8 colortranslations[MAXSKINCOLORS][16]; extern const char *KartColor_Names[MAXSKINCOLORS]; -void K_StarmanColormap(UINT8 *dest_colormap, UINT8 skincolor); +extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2]; +void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); UINT8 K_GetKartColorByName(const char *name); void K_RegisterKartStuff(void); boolean K_IsPlayerLosing(player_t *player); +boolean K_IsPlayerWanted(player_t *player); void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); -void K_LakituChecker(player_t *player); +void K_RespawnChecker(player_t *player); void K_KartMoveAnimation(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); -void K_SpinPlayer(player_t *player, mobj_t *source); +void K_DoInstashield(player_t *player); +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem); void K_SquishPlayer(player_t *player, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *source); -void K_StealBalloon(player_t *player, player_t *victim, boolean force); +void K_StealBumper(player_t *player, player_t *victim, boolean force); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); -void K_SpawnBobombExplosion(mobj_t *source, UINT8 color); +void K_SpawnMineExplosion(mobj_t *source, UINT8 color); void K_SpawnBoostTrail(player_t *player); +void K_SpawnSparkleTrail(mobj_t *mo); +void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent); void K_DriftDustHandling(mobj_t *spawner); -void K_DoMushroom(player_t *player, boolean doPFlag); -void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed); +void K_DoSneaker(player_t *player, boolean doPFlag); +void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute); +void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source); +void K_RepairOrbitChain(mobj_t *orbit); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); +fixed_t K_GetKartDriftSparkValue(player_t *player); +void K_StripItems(player_t *player); void K_MomentumToFacing(player_t *player); fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower); fixed_t K_GetKartAccel(player_t *player); UINT16 K_GetKartFlashing(void); fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove); void K_MoveKartPlayer(player_t *player, boolean onground); -void K_CheckBalloons(void); +void K_CalculateBattleWanted(void); +void K_CheckBumpers(void); +void K_CheckSpectateStatus(void); INT32 K_calcSplitFlags(INT32 snapflags); void K_LoadKartHUDGraphics(void); fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my); void K_drawKartHUD(void); +void K_drawKartFreePlay(UINT32 flashtime); void K_LoadIconGraphics(char *facestr, INT32 skinnum); void K_ReloadSkinIconGraphics(void); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 5cdd31f0..587f9514 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -628,6 +628,16 @@ static int lib_pCanRunOnWater(lua_State *L) return 1; } +static int lib_pSpawnShadowMobj(lua_State *L) +{ + mobj_t *caster = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + NOHUD + if (!caster) + return LUA_ErrInvalid(L, "mobj_t"); + P_SpawnShadowMobj(caster); + return 0; +} + // P_USER //////////// @@ -932,7 +942,7 @@ static int lib_pHomingAttack(lua_State *L) return 0; } -static int lib_pSuperReady(lua_State *L) +/*static int lib_pSuperReady(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); //HUDSAFE @@ -940,7 +950,7 @@ static int lib_pSuperReady(lua_State *L) return LUA_ErrInvalid(L, "player_t"); lua_pushboolean(L, P_SuperReady(player)); return 1; -} +}*/ static int lib_pDoJump(lua_State *L) { @@ -2038,6 +2048,26 @@ static int lib_kGetKartColorByName(lua_State *L) return 1; } +static int lib_kIsPlayerLosing(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + //HUDSAFE + if (!player) + return LUA_ErrInvalid(L, "player_t"); + K_IsPlayerLosing(player); + return 0; +} + +static int lib_kIsPlayerWanted(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + //HUDSAFE + if (!player) + return LUA_ErrInvalid(L, "player_t"); + K_IsPlayerWanted(player); + return 0; +} + static int lib_kKartBouncing(lua_State *L) { mobj_t *mobj1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -2053,16 +2083,28 @@ static int lib_kKartBouncing(lua_State *L) return 0; } +static int lib_kDoInstashield(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + K_DoInstashield(player); + return 0; +} + static int lib_kSpinPlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + INT32 type = (INT32)luaL_checkinteger(L, 3); + boolean trapitem = luaL_checkboolean(L, 4); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!source) return LUA_ErrInvalid(L, "mobj_t"); - K_SpinPlayer(player, source); + K_SpinPlayer(player, source, type, trapitem); return 0; } @@ -2092,7 +2134,7 @@ static int lib_kExplodePlayer(lua_State *L) return 0; } -static int lib_kStealBalloon(lua_State *L) +static int lib_kStealBumper(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); @@ -2102,7 +2144,7 @@ static int lib_kStealBalloon(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (!victim) return LUA_ErrInvalid(L, "player_t"); - K_StealBalloon(player, victim, force); + K_StealBumper(player, victim, force); return 0; } @@ -2125,7 +2167,7 @@ static int lib_kSpawnKartExplosion(lua_State *L) return 0; } -static int lib_kSpawnDriftTrail(lua_State *L) +static int lib_kSpawnBoostTrail(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD @@ -2135,6 +2177,27 @@ static int lib_kSpawnDriftTrail(lua_State *L) return 0; } +static int lib_kSpawnSparkleTrail(lua_State *L) +{ + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + NOHUD + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + K_SpawnSparkleTrail(mo); + return 0; +} + +static int lib_kSpawnWipeoutTrail(lua_State *L) +{ + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + boolean translucent = luaL_checkboolean(L, 2); + NOHUD + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + K_SpawnWipeoutTrail(mo, translucent); + return 0; +} + static int lib_kDriftDustHandling(lua_State *L) { mobj_t *spawner = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -2145,25 +2208,52 @@ static int lib_kDriftDustHandling(lua_State *L) return 0; } -static int lib_kDoMushroom(lua_State *L) +static int lib_kDoSneaker(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean doPFlag = luaL_checkboolean(L, 2); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); - K_DoMushroom(player, doPFlag); + K_DoSneaker(player, doPFlag); return 0; } -static int lib_kDoBouncePad(lua_State *L) +static int lib_kDoPogoSpring(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); fixed_t vertispeed = luaL_checkfixed(L, 2); + boolean mute = luaL_checkboolean(L, 3); NOHUD if (!mo) return LUA_ErrInvalid(L, "mobj_t"); - K_DoBouncePad(mo, vertispeed); + K_DoPogoSpring(mo, vertispeed, mute); + return 0; +} + +static int lib_kKillBananaChain(lua_State *L) +{ + mobj_t *banana = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + NOHUD + if (!banana) + return LUA_ErrInvalid(L, "mobj_t"); + if (!inflictor) + return LUA_ErrInvalid(L, "mobj_t"); + if (!source) + return LUA_ErrInvalid(L, "mobj_t"); + K_KillBananaChain(banana, inflictor, source); + return 0; +} + +static int lib_kRepairOrbitChain(lua_State *L) +{ + mobj_t *orbit = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + NOHUD + if (!orbit) + return LUA_ErrInvalid(L, "mobj_t"); + K_RepairOrbitChain(orbit); return 0; } @@ -2260,6 +2350,7 @@ static luaL_Reg lib[] = { {"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide}, {"P_CheckSolidLava",lib_pCheckSolidLava}, {"P_CanRunOnWater",lib_pCanRunOnWater}, + {"P_SpawnShadowMobj",lib_pSpawnShadowMobj}, // p_user {"P_GetPlayerHeight",lib_pGetPlayerHeight}, @@ -2290,7 +2381,7 @@ static luaL_Reg lib[] = { {"P_LookForEnemies",lib_pLookForEnemies}, {"P_NukeEnemies",lib_pNukeEnemies}, {"P_HomingAttack",lib_pHomingAttack}, - {"P_SuperReady",lib_pSuperReady}, + //{"P_SuperReady",lib_pSuperReady}, {"P_DoJump",lib_pDoJump}, {"P_SpawnThokMobj",lib_pSpawnThokMobj}, {"P_SpawnSpinMobj",lib_pSpawnSpinMobj}, @@ -2385,16 +2476,23 @@ static luaL_Reg lib[] = { // k_kart {"K_GetKartColorByName",lib_kGetKartColorByName}, + {"K_IsPlayerLosing",lib_kIsPlayerLosing}, + {"K_IsPlayerWanted",lib_kIsPlayerWanted}, {"K_KartBouncing",lib_kKartBouncing}, + {"K_DoInstashield",lib_kDoInstashield}, {"K_SpinPlayer",lib_kSpinPlayer}, {"K_SquishPlayer",lib_kSquishPlayer}, {"K_ExplodePlayer",lib_kExplodePlayer}, - {"K_StealBalloon",lib_kStealBalloon}, + {"K_StealBumper",lib_kStealBumper}, {"K_SpawnKartExplosion",lib_kSpawnKartExplosion}, - {"K_SpawnBoostTrail",lib_kSpawnDriftTrail}, + {"K_SpawnBoostTrail",lib_kSpawnBoostTrail}, + {"K_SpawnSparkleTrail",lib_kSpawnSparkleTrail}, + {"K_SpawnWipeoutTrail",lib_kSpawnWipeoutTrail}, {"K_DriftDustHandling",lib_kDriftDustHandling}, - {"K_DoMushroom",lib_kDoMushroom}, - {"K_DoBouncePad",lib_kDoBouncePad}, + {"K_DoSneaker",lib_kDoSneaker}, + {"K_DoPogoSpring",lib_kDoPogoSpring}, + {"K_KillBananaChain",lib_kKillBananaChain}, + {"K_RepairOrbitChain",lib_kRepairOrbitChain}, {"K_MomentumToFacing",lib_kMomentumToFacing}, {"K_GetKartSpeed",lib_kGetKartSpeed}, {"K_GetKartAccel",lib_kGetKartAccel}, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index f9428c8c..e8e9e173 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -424,6 +424,30 @@ static int libd_drawFill(lua_State *L) return 0; } +static int libd_fadeScreen(lua_State *L) +{ + UINT16 color = luaL_checkinteger(L, 1); + UINT8 strength = luaL_checkinteger(L, 2); + const UINT8 maxstrength = ((color & 0xFF00) ? 32 : 10); + + HUDONLY + + if (!strength) + return 0; + + if (strength > maxstrength) + return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength); + + if (strength == maxstrength) // Allow as a shortcut for drawfill... + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color)); + return 0; + } + + V_DrawFadeScreen(color, strength); + return 0; +} + static int libd_drawString(lua_State *L) { fixed_t x = luaL_checkinteger(L, 1); @@ -568,6 +592,7 @@ static luaL_Reg lib_draw[] = { {"drawNum", libd_drawNum}, {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, + {"fadeScreen", libd_fadeScreen}, {"drawString", libd_drawString}, {"stringWidth", libd_stringWidth}, {"getColormap", libd_getColormap}, diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 96d50b77..50a194c8 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -16,6 +16,7 @@ #include "tables.h" #include "p_local.h" #include "doomstat.h" // for ALL7EMERALDS +#include "k_kart.h" // KartColor_Opposite #include "lua_script.h" #include "lua_libs.h" @@ -191,8 +192,8 @@ static int lib_coloropposite(lua_State *L) UINT8 colornum = (UINT8)luaL_checkinteger(L, 1); if (colornum >= MAXSKINCOLORS) return luaL_error(L, "skincolor %d out of range (0 - %d).", colornum, MAXSKINCOLORS-1); - lua_pushinteger(L, Color_Opposite[colornum*2]); // push color - lua_pushinteger(L, Color_Opposite[colornum*2+1]); // push frame + lua_pushinteger(L, KartColor_Opposite[colornum*2]); // push color + lua_pushinteger(L, KartColor_Opposite[colornum*2+1]); // push frame return 2; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 2dbb58c8..814bb325 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -530,10 +530,22 @@ static int mobj_set(lua_State *L) case mobj_bprev: return UNIMPLEMENTED; case mobj_hnext: - mo->hnext = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hnext, NULL); + else + { + mobj_t *hnext = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hnext, hnext); + } break; case mobj_hprev: - mo->hprev = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hprev, NULL); + else + { + mobj_t *hprev = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hprev, hprev); + } break; case mobj_type: // yeah sure, we'll let you change the mobj's type. { diff --git a/src/lua_script.c b/src/lua_script.c index 7ed30367..ef94cf30 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -962,13 +962,16 @@ void LUA_Archive(void) ArchiveExtVars(&players[i], "player"); } - for (th = thinkercap.next; th != &thinkercap; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - { - // archive function will determine when to skip mobjs, - // and write mobjnum in otherwise. - ArchiveExtVars(th, "mobj"); - } + if (gamestate == GS_LEVEL) + { + for (th = thinkercap.next; th != &thinkercap; th = th->next) + if (th->function.acp1 == (actionf_p1)P_MobjThinker) + { + // archive function will determine when to skip mobjs, + // and write mobjnum in otherwise. + ArchiveExtVars(th, "mobj"); + } + } WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum. LUAh_NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode diff --git a/src/m_cheat.c b/src/m_cheat.c index fed76edd..ec602017 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1149,7 +1149,7 @@ void OP_ObjectplaceMovement(player_t *player) // make sure viewz follows player if in 1st person mode //player->deltaviewheight = 0; - player->viewheight = FixedMul(cv_viewheight.value << FRACBITS, player->mo->scale); + player->viewheight = FixedMul(32 << FRACBITS, player->mo->scale); if (player->mo->eflags & MFE_VERTICALFLIP) player->viewz = player->mo->z + player->mo->height - player->viewheight; else diff --git a/src/m_menu.c b/src/m_menu.c index 87982310..63eae220 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -241,6 +241,7 @@ menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef; // Single Player //static void M_LoadGame(INT32 choice); static void M_TimeAttack(INT32 choice); +static boolean M_QuitTimeAttackMenu(void); //static void M_NightsAttack(INT32 choice); static void M_Statistics(INT32 choice); static void M_HandleStaffReplay(INT32 choice); @@ -251,7 +252,7 @@ static void M_ModeAttackRetry(INT32 choice); static void M_ModeAttackEndGame(INT32 choice); static void M_SetGuestReplay(INT32 choice); static void M_ChoosePlayer(INT32 choice); -menu_t SP_GameStatsDef, SP_LevelStatsDef; +menu_t SP_LevelStatsDef; static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; //static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef; @@ -259,13 +260,8 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; #ifndef NONET static void M_StartServerMenu(INT32 choice); static void M_ConnectMenu(INT32 choice); -static void M_ConnectIPMenu(INT32 choice); #endif static void M_StartSplitServerMenu(INT32 choice); -#ifndef NOFOURPLAYER -static void M_Start3PServerMenu(INT32 choice); -static void M_Start4PServerMenu(INT32 choice); -#endif static void M_StartServer(INT32 choice); #ifndef NONET static void M_Refresh(INT32 choice); @@ -284,11 +280,9 @@ static void M_SetupMultiPlayer4(INT32 choice); // Controls menu_t OP_ControlsDef, /*OP_ControlListDef,*/ OP_MoveControlsDef; menu_t /*OP_MPControlsDef, OP_CameraControlsDef, OP_MiscControlsDef,*/ OP_CustomControlsDef, OP_SpectateControlsDef; -menu_t OP_P1ControlsDef, OP_P2ControlsDef; menu_t OP_MouseOptionsDef, OP_Mouse2OptionsDef; menu_t OP_Joystick1Def, OP_Joystick2Def; #ifndef NOFOURPLAYER -menu_t OP_P3ControlsDef, OP_P4ControlsDef; menu_t OP_Joystick3Def, OP_Joystick4Def; #endif static void M_VideoModeMenu(INT32 choice); @@ -313,14 +307,16 @@ menu_t OP_VideoOptionsDef, OP_VideoModeDef; menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; #endif menu_t OP_SoundOptionsDef; -static void M_ToggleSFX(void); -static void M_ToggleDigital(void); -static void M_ToggleMIDI(void); +static void M_ToggleSFX(INT32 choice); +static void M_ToggleDigital(INT32 choice); +//static void M_ToggleMIDI(INT32 choice); +static void M_RestartAudio(void); //Misc -menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef; +menu_t /*OP_DataOptionsDef,*/ OP_ScreenshotOptionsDef, OP_EraseDataDef; +menu_t OP_HUDOptionsDef; menu_t OP_GameOptionsDef, OP_ServerOptionsDef; -menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; +//menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; menu_t OP_MonitorToggleDef; static void M_ScreenshotOptions(INT32 choice); static void M_EraseData(INT32 choice); @@ -332,17 +328,18 @@ static void M_DrawSkyRoom(void); static void M_DrawChecklist(void); static void M_DrawEmblemHints(void); static void M_DrawPauseMenu(void); +static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); static void M_DrawServerMenu(void); -static void M_DrawLevelSelectMenu(void); static void M_DrawImageDef(void); static void M_DrawLoad(void); static void M_DrawLevelStats(void); -static void M_DrawGameStats(void); static void M_DrawTimeAttackMenu(void); //static void M_DrawNightsAttackMenu(void); static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawControl(void); +static void M_DrawVideoMenu(void); static void M_DrawVideoMode(void); +static void M_DrawHUDOptions(void); //static void M_DrawMonitorToggles(void); #ifdef HWRENDER static void M_OGL_DrawFogMenu(void); @@ -350,7 +347,7 @@ static void M_OGL_DrawColorMenu(void); #endif #ifndef NONET static void M_DrawConnectMenu(void); -static void M_DrawConnectIPMenu(void); +static void M_DrawMPMainMenu(void); static void M_DrawRoomMenu(void); #endif static void M_DrawJoystick(void); @@ -365,7 +362,6 @@ static boolean M_QuitMultiPlayerMenu(void); static void M_HandleSoundTest(INT32 choice); static void M_HandleImageDef(INT32 choice); static void M_HandleLoadSave(INT32 choice); -static void M_HandleGameStats(INT32 choice); static void M_HandleLevelStats(INT32 choice); #ifndef NONET static void M_HandleConnectIP(INT32 choice); @@ -388,7 +384,8 @@ static void Dummystaff_OnChange(void); static CV_PossibleValue_t map_cons_t[] = { {1,"MIN"}, - {NUMMAPS, "MAX"} + {NUMMAPS, "MAX"}, + {0, NULL} }; consvar_t cv_nextmap = {"nextmap", "1", CV_HIDEN|CV_CALL, map_cons_t, Nextmap_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -433,7 +430,7 @@ consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_ // autorecord demos for time attack static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -CV_PossibleValue_t ghost_cons_t[] = {{0, "Hide"}, {1, "Show"}, {2, "Show All"}, {0, NULL}}; +CV_PossibleValue_t ghost_cons_t[] = {{0, "Hide"}, {1, "Show Character"}, {2, "Show All"}, {0, NULL}}; CV_PossibleValue_t ghost2_cons_t[] = {{0, "Hide"}, {1, "Show"}, {0, NULL}}; consvar_t cv_ghost_besttime = {"ghost_besttime", "Show All", CV_SAVE, ghost_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -445,6 +442,12 @@ consvar_t cv_ghost_staff = {"ghost_staff", "Show", CV_SAVE, ghost2_cons_ //Console variables used solely in the menu system. //todo: add a way to use non-console variables in the menu // or make these consvars legitimate like color or skin. +#ifndef NOFOURPLAYER +static void Dummysplitplayers_OnChange(void); +static CV_PossibleValue_t dummysplitplayers_cons_t[] = {{2, "Two"}, {3, "Three"}, {4, "Four"}, {0, NULL}}; +static consvar_t cv_dummysplitplayers = {"dummysplitplayers", "Two", CV_HIDEN|CV_CALL, dummysplitplayers_cons_t, Dummysplitplayers_OnChange, 0, NULL, NULL, 0, 0, NULL}; +#endif + static CV_PossibleValue_t dummyteam_cons_t[] = {{0, "Spectator"}, {1, "Red"}, {2, "Blue"}, {0, NULL}}; static CV_PossibleValue_t dummyscramble_cons_t[] = {{0, "Random"}, {1, "Points"}, {0, NULL}}; static CV_PossibleValue_t ringlimit_cons_t[] = {{0, "MIN"}, {9999, "MAX"}, {0, NULL}}; @@ -478,7 +481,12 @@ static menuitem_t MainMenu[] = { {IT_SUBMENU|IT_STRING, NULL, "Extras", &SR_UnlockChecklistDef, 84}, {IT_CALL |IT_STRING, NULL, "1 Player", M_SinglePlayerMenu, 92}, +#ifdef NONET +M_StartSplitServerMenu + {IT_CALL |IT_STRING, NULL, "Splitscreen", M_StartSplitServerMenu,100}, +#else {IT_SUBMENU|IT_STRING, NULL, "Multiplayer", &MP_MainDef, 100}, +#endif {IT_CALL |IT_STRING, NULL, "Options", M_Options, 108}, {IT_CALL |IT_STRING, NULL, "Quit Game", M_QuitSRB2, 116}, }; @@ -514,21 +522,22 @@ typedef enum // --------------------- static menuitem_t MPauseMenu[] = { - {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, - {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24}, + {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, + {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24}, {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,40}, - {IT_CALL | IT_STRING, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen - {IT_CALL | IT_STRING, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen + {IT_CALL | IT_STRING, NULL, "P1 Setup...", M_SetupMultiPlayer, 48}, // splitscreen + {IT_CALL | IT_STRING, NULL, "P2 Setup...", M_SetupMultiPlayer2, 56}, // splitscreen #ifndef NOFOURPLAYER - {IT_CALL | IT_STRING, NULL, "Player 3 Setup", M_SetupMultiPlayer3, 64}, // splitscreen - {IT_CALL | IT_STRING, NULL, "Player 4 Setup", M_SetupMultiPlayer4, 72}, // splitscreen + {IT_CALL | IT_STRING, NULL, "P3 Setup...", M_SetupMultiPlayer3, 64}, // splitscreen + {IT_CALL | IT_STRING, NULL, "P4 Setup...", M_SetupMultiPlayer4, 72}, // splitscreen #endif {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48}, {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48}, + {IT_STRING | IT_CALL, NULL, "Cancel Join", M_ConfirmSpectate, 48}, {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48}, - {IT_CALL | IT_STRING, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone + {IT_CALL | IT_STRING, NULL, "Player Setup...", M_SetupMultiPlayer, 56}, // alone {IT_CALL | IT_STRING, NULL, "Options", M_Options, 64}, {IT_CALL | IT_STRING, NULL, "Return to Title", M_EndGame, 80}, @@ -549,6 +558,7 @@ typedef enum #endif mpause_spectate, mpause_entergame, + mpause_canceljoin, mpause_switchteam, mpause_psetup, mpause_options, @@ -606,9 +616,9 @@ static menuitem_t MISC_ChangeTeamMenu[] = static menuitem_t MISC_ChangeLevelMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 30}, - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 60}, - {IT_WHITESTRING|IT_CALL, NULL, "Change Level", M_ChangeLevel, 120}, + {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68}, + {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, + {IT_WHITESTRING|IT_CALL, NULL, "Change Level", M_ChangeLevel, 130}, }; static menuitem_t MISC_HelpMenu[] = @@ -682,9 +692,8 @@ static menuitem_t SR_MainMenu[] = static menuitem_t SR_LevelSelectMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 60}, - - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 120}, + {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 130}, }; static menuitem_t SR_UnlockChecklistMenu[] = @@ -729,29 +738,30 @@ static menuitem_t SP_LoadGameMenu[] = // Single Player Level Select static menuitem_t SP_LevelSelectMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 60}, - - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 120}, + {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 130}, }; // Single Player Time Attack static menuitem_t SP_TimeAttackMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 48}, - {IT_STRING|IT_CVAR, NULL, "Player", &cv_chooseskin, 58}, - {IT_STRING|IT_CVAR, NULL, "Color", &cv_playercolor, 68}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Name", &cv_playername, 0}, + {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 13}, + {IT_STRING|IT_CVAR, NULL, "Color", &cv_playercolor, 26}, + {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, - {IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100}, - {IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110}, - {IT_DISABLED, NULL, "Ghosts...", &SP_GhostDef, 120}, - {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseTimeAttack, 130}, + {IT_DISABLED, NULL, "Guest...", &SP_GuestReplayDef, 98}, + {IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 108}, + {IT_WHITESTRING|IT_SUBMENU, NULL, "Ghosts...", &SP_GhostDef, 118}, + {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseTimeAttack, 130}, }; enum { - talevel, + taname, taplayer, tacolor, + talevel, taguest, tareplay, @@ -761,14 +771,14 @@ enum static menuitem_t SP_ReplayMenu[] = { - {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 0}, - {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 8}, + {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 90}, + {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 98}, - {IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack,21}, - {IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack,29}, - {IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay,37}, + {IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack, 106}, + {IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack, 114}, + {IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay,122}, - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 50} + {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130} }; /*static menuitem_t SP_NightsReplayMenu[] = @@ -785,13 +795,13 @@ static menuitem_t SP_ReplayMenu[] = static menuitem_t SP_GuestReplayMenu[] = { - {IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 8}, - {IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay,16}, - {IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay,24}, + {IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 94}, + {IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay,102}, + {IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay,110}, - {IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay,37}, + {IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay,120}, - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 50} + {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130} }; /*static menuitem_t SP_NightsGuestReplayMenu[] = @@ -807,14 +817,13 @@ static menuitem_t SP_GuestReplayMenu[] = static menuitem_t SP_GhostMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Best Time", &cv_ghost_besttime, 0}, - {IT_STRING|IT_CVAR, NULL, "Best Lap", &cv_ghost_bestlap, 8}, - {IT_STRING|IT_CVAR, NULL, "Last", &cv_ghost_last, 16}, + {IT_STRING|IT_CVAR, NULL, "Best Time", &cv_ghost_besttime, 88}, + {IT_STRING|IT_CVAR, NULL, "Best Lap", &cv_ghost_bestlap, 96}, + {IT_STRING|IT_CVAR, NULL, "Last", &cv_ghost_last, 104}, + {IT_DISABLED, NULL, "Guest", &cv_ghost_guest, 112}, + {IT_DISABLED, NULL, "Staff Attack",&cv_ghost_staff, 120}, - {IT_STRING|IT_CVAR, NULL, "Guest", &cv_ghost_guest, 29}, - {IT_STRING|IT_CVAR, NULL, "Staff Attack",&cv_ghost_staff, 37}, - - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 50} + {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130} }; /*static menuitem_t SP_NightsGhostMenu[] = @@ -853,11 +862,6 @@ enum }; // Statistics -static menuitem_t SP_GameStatsMenu[] = -{ - {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleGameStats, '\0'}, // dummy menuitem for the control func -}; - static menuitem_t SP_LevelStatsMenu[] = { {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelStats, '\0'}, // dummy menuitem for the control func @@ -906,52 +910,77 @@ menuitem_t PlayerMenu[32] = // Multiplayer and all of its submenus // ----------------------------------- // Prefix: MP_ + +#ifndef NONET + static menuitem_t MP_MainMenu[] = { -#ifndef NONET - {IT_CALL | IT_STRING, NULL, "HOST GAME", M_StartServerMenu, 10}, - {IT_CALL | IT_STRING, NULL, "JOIN GAME (Search)", M_ConnectMenu, 30}, - {IT_CALL | IT_STRING, NULL, "JOIN GAME (Specify IP)", M_ConnectIPMenu, 40}, -#endif - - {IT_CALL | IT_STRING, NULL, "TWO PLAYER GAME", M_StartSplitServerMenu, 60}, - -#ifdef NOFOURPLAYER - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 1", M_SetupMultiPlayer, 80}, - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 2", M_SetupMultiPlayer2, 90}, -#else - {IT_CALL | IT_STRING, NULL, "THREE PLAYER GAME", M_Start3PServerMenu, 70}, - {IT_CALL | IT_STRING, NULL, "FOUR PLAYER GAME", M_Start4PServerMenu, 80}, - - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 1", M_SetupMultiPlayer, 100}, - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 2", M_SetupMultiPlayer2, 110}, - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 3", M_SetupMultiPlayer3, 120}, - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 4", M_SetupMultiPlayer4, 130}, -#endif + {IT_HEADER, NULL, "Host a game", NULL, 0}, + {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 10}, + {IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 18}, + {IT_HEADER, NULL, "Join a game", NULL, 32}, + {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenu, 42}, + {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 50}, + {IT_HEADER, NULL, "Player setup", NULL, 80}, + {IT_STRING|IT_CALL, NULL, "Name, character, color...", M_SetupMultiPlayer, 90}, }; +#endif + static menuitem_t MP_ServerMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 10}, + {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 10}, #ifndef NONET - {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30}, + {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30}, #endif - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 80}, + {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130}, }; -enum +// Separated splitscreen and normal servers. +static menuitem_t MP_SplitServerMenu[] = { - mp_server_gametype = 0, -#ifndef NONET - mp_server_room, - mp_server_name, + {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 10}, +#ifndef NOFOURPLAYER + {IT_STRING|IT_CVAR, NULL, "Number of players", &cv_dummysplitplayers, 20}, #endif - mp_server_level, - mp_server_start + {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, +#ifdef NOFOURPLAYER + {IT_STRING|IT_CALL, NULL, "P1 Setup...", M_SetupMultiPlayer, 108}, + {IT_STRING|IT_CALL, NULL, "P2 Setup... ", M_SetupMultiPlayer2, 118}, +#else + {IT_STRING|IT_CALL, NULL, "P1 Setup...", M_SetupMultiPlayer, 88}, + {IT_STRING|IT_CALL, NULL, "P2 Setup... ", M_SetupMultiPlayer2, 98}, + {IT_GRAYEDOUT, NULL, "P3 Setup...", M_SetupMultiPlayer3, 108}, + {IT_GRAYEDOUT, NULL, "P4 Setup... ", M_SetupMultiPlayer4, 118}, +#endif + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130}, +}; + +#ifndef NOFOURPLAYER +static void Dummysplitplayers_OnChange(void) +{ + UINT8 i = 2; // player 2 is the last unchanging setup + + while (i < 4) + { + if (i < cv_dummysplitplayers.value) + MP_SplitServerMenu[3+i].status = IT_STRING|IT_CALL; + else + MP_SplitServerMenu[3+i].status = IT_GRAYEDOUT; + i++; + } +} +#endif + +static menuitem_t MP_PlayerSetupMenu[] = +{ + {IT_KEYHANDLER | IT_STRING, NULL, "Name", M_HandleSetupMultiPlayer, 0}, + {IT_KEYHANDLER | IT_STRING, NULL, "Character", M_HandleSetupMultiPlayer, 16}, // Tails 01-18-2001 + {IT_KEYHANDLER | IT_STRING, NULL, "Color", M_HandleSetupMultiPlayer, 152}, }; #ifndef NONET @@ -1005,156 +1034,86 @@ static menuitem_t MP_RoomMenu[] = {IT_DISABLED, NULL, "", M_ChooseRoom, 153}, {IT_DISABLED, NULL, "", M_ChooseRoom, 162}, }; - -static menuitem_t MP_ConnectIPMenu[] = -{ - {IT_KEYHANDLER | IT_STRING, NULL, " IP Address:", M_HandleConnectIP, 0}, -}; #endif -// Separated splitscreen and normal servers. -static menuitem_t MP_SplitServerMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 10}, - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 80}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130}, -}; - -static menuitem_t MP_PlayerSetupMenu[] = -{ - {IT_KEYHANDLER | IT_STRING, NULL, "Name", M_HandleSetupMultiPlayer, 0}, - {IT_KEYHANDLER | IT_STRING, NULL, "Character", M_HandleSetupMultiPlayer, 16}, // Tails 01-18-2001 - {IT_KEYHANDLER | IT_STRING, NULL, "Color", M_HandleSetupMultiPlayer, 152}, -}; - // ------------------------------------ // Options and most (?) of its submenus // ------------------------------------ // Prefix: OP_ static menuitem_t OP_MainMenu[] = { - {IT_SUBMENU | IT_STRING, NULL, "Setup Controls...", &OP_ControlsDef, 10}, + {IT_SUBMENU|IT_STRING, NULL, "Control Setup...", &OP_ControlsDef, 10}, - {IT_SUBMENU | IT_STRING, NULL, "Video Options...", &OP_VideoOptionsDef, 30}, - {IT_SUBMENU | IT_STRING, NULL, "Sound Options...", &OP_SoundOptionsDef, 40}, - {IT_SUBMENU | IT_STRING, NULL, "Data Options...", &OP_DataOptionsDef, 50}, + {IT_SUBMENU|IT_STRING, NULL, "Video Options...", &OP_VideoOptionsDef, 30}, + {IT_SUBMENU|IT_STRING, NULL, "Sound Options...", &OP_SoundOptionsDef, 40}, - {IT_SUBMENU | IT_STRING, NULL, "Game Options...", &OP_GameOptionsDef, 70}, - {IT_SUBMENU | IT_STRING, NULL, "Server Options...", &OP_ServerOptionsDef, 80}, + {IT_SUBMENU|IT_STRING, NULL, "HUD Options...", &OP_HUDOptionsDef, 60}, + {IT_STRING|IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 70}, - {IT_CALL | IT_STRING, NULL, "Play Credits", M_Credits, 100}, - {IT_KEYHANDLER | IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 110}, + {IT_SUBMENU|IT_STRING, NULL, "Gameplay Options...", &OP_GameOptionsDef, 90}, + {IT_SUBMENU|IT_STRING, NULL, "Server Options...", &OP_ServerOptionsDef, 100}, + + {IT_CALL|IT_STRING, NULL, "Play Credits", M_Credits, 120}, + {IT_SUBMENU|IT_STRING, NULL, "Erase Data...", &OP_EraseDataDef, 130}, }; static menuitem_t OP_ControlsMenu[] = { - {IT_SUBMENU | IT_STRING, NULL, "Player 1 Controls...", &OP_P1ControlsDef, 10}, - {IT_SUBMENU | IT_STRING, NULL, "Player 2 Controls...", &OP_P2ControlsDef, 20}, + {IT_CALL | IT_STRING, NULL, "Player 1 Controls...", M_Setup1PControlsMenu, 10}, + {IT_CALL | IT_STRING, NULL, "Player 2 Controls...", M_Setup2PControlsMenu, 20}, #ifdef NOFOURPLAYER {IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 40}, #else - {IT_SUBMENU | IT_STRING, NULL, "Player 3 Controls...", &OP_P3ControlsDef, 30}, - {IT_SUBMENU | IT_STRING, NULL, "Player 4 Controls...", &OP_P4ControlsDef, 40}, + {IT_CALL | IT_STRING, NULL, "Player 3 Controls...", &M_Setup3PControlsMenu, 30}, + {IT_CALL | IT_STRING, NULL, "Player 4 Controls...", &M_Setup4PControlsMenu, 40}, {IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 60}, #endif }; -static menuitem_t OP_P1ControlsMenu[] = -{ - {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup1PControlsMenu, 10}, - //{IT_SUBMENU | IT_STRING, NULL, "Mouse Options...", &OP_MouseOptionsDef, 20}, - {IT_SUBMENU | IT_STRING, NULL, "Joystick Options...", &OP_Joystick1Def , 20}, - - {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam , 40}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair , 50}, - - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 80}, -}; - -static menuitem_t OP_P2ControlsMenu[] = -{ - {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup2PControlsMenu, 10}, - //{IT_SUBMENU | IT_STRING, NULL, "Second Mouse Options...", &OP_Mouse2OptionsDef, 20}, - {IT_SUBMENU | IT_STRING, NULL, "Second Joystick Options...", &OP_Joystick2Def , 20}, - - {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam2 , 40}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 50}, - - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 70}, -}; - -#ifndef NOFOURPLAYER -static menuitem_t OP_P3ControlsMenu[] = -{ - {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup3PControlsMenu, 10}, - {IT_SUBMENU | IT_STRING, NULL, "Third Joystick Options...", &OP_Joystick3Def , 20}, - - {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam3 , 40}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair3, 50}, - - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog3, 60}, -}; - -static menuitem_t OP_P4ControlsMenu[] = -{ - {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup4PControlsMenu, 10}, - {IT_SUBMENU | IT_STRING, NULL, "Fourth Joystick Options...", &OP_Joystick4Def , 20}, - - {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam4 , 40}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair4, 50}, - - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog4, 60}, -}; -#endif - -/*static menuitem_t OP_ControlListMenu[] = -{ - {IT_SUBMENU | IT_STRING, NULL, "Kart Controls...", &OP_MoveControlsDef, 10}, -// {IT_SUBMENU | IT_STRING, NULL, "Multiplayer Controls...", &OP_MPControlsDef, 20}, -// {IT_SUBMENU | IT_STRING, NULL, "Camera Controls...", &OP_CameraControlsDef, 20}, -// {IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 20}, -};*/ - static menuitem_t OP_MoveControlsMenu[] = { - {IT_CALL | IT_STRING2, NULL, "Aim Forward", M_ChangeControl, gc_aimforward }, - {IT_CALL | IT_STRING2, NULL, "Aim Backward", M_ChangeControl, gc_aimbackward}, - {IT_CALL | IT_STRING2, NULL, "Turn Left", M_ChangeControl, gc_turnleft }, - {IT_CALL | IT_STRING2, NULL, "Turn Right", M_ChangeControl, gc_turnright }, - {IT_CALL | IT_STRING2, NULL, "Accelerate", M_ChangeControl, gc_accelerate }, - {IT_CALL | IT_STRING2, NULL, "Drift", M_ChangeControl, gc_drift }, - {IT_CALL | IT_STRING2, NULL, "Brake", M_ChangeControl, gc_brake }, - {IT_CALL | IT_STRING2, NULL, "Use/Throw Item", M_ChangeControl, gc_fire }, - {IT_CALL | IT_STRING2, NULL, "Look Backward", M_ChangeControl, gc_lookback }, + {IT_CONTROL, NULL, "Accelerate", M_ChangeControl, gc_accelerate }, + {IT_CONTROL, NULL, "Turn Left", M_ChangeControl, gc_turnleft }, + {IT_CONTROL, NULL, "Turn Right", M_ChangeControl, gc_turnright }, + {IT_CONTROL, NULL, "Drift", M_ChangeControl, gc_drift }, + {IT_CONTROL, NULL, "Brake", M_ChangeControl, gc_brake }, + {IT_CONTROL, NULL, "Use/Throw Item", M_ChangeControl, gc_fire }, + {IT_CONTROL, NULL, "Aim Forward", M_ChangeControl, gc_aimforward }, + {IT_CONTROL, NULL, "Aim Backward", M_ChangeControl, gc_aimbackward}, + {IT_CONTROL, NULL, "Look Backward", M_ChangeControl, gc_lookback }, - {IT_CALL | IT_STRING2, NULL, "Talk key", M_ChangeControl, gc_talkkey }, - {IT_CALL | IT_STRING2, NULL, "Team-Talk key", M_ChangeControl, gc_teamkey }, - {IT_CALL | IT_STRING2, NULL, "Rankings/Scores", M_ChangeControl, gc_scores }, + {IT_SPACE, NULL, "", NULL, 76}, + {IT_CONTROL, NULL, "Talk key", M_ChangeControl, gc_talkkey }, + //{IT_CONTROL, NULL, "Team-Talk key", M_ChangeControl, gc_teamkey }, + {IT_CONTROL, NULL, "Rankings/Scores", M_ChangeControl, gc_scores }, + {IT_CONTROL, NULL, "Pause", M_ChangeControl, gc_pause }, + {IT_CONTROL, NULL, "Console", M_ChangeControl, gc_console }, - {IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause }, - {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, - - {IT_SUBMENU | IT_STRING, NULL, "Spectator Controls...", &OP_SpectateControlsDef, 112}, - {IT_SUBMENU | IT_STRING, NULL, "Custom Lua Actions...", &OP_CustomControlsDef, 120}, + {IT_SUBMENU | IT_STRING, NULL, "Gamepad Options...", &OP_Joystick1Def, 112}, + {IT_SUBMENU | IT_STRING, NULL, "Spectator Controls...", &OP_SpectateControlsDef, 120}, + {IT_SUBMENU | IT_STRING, NULL, "Custom Lua Actions...", &OP_CustomControlsDef, 128}, }; static menuitem_t OP_SpectateControlsMenu[] = { - {IT_CALL | IT_STRING2, NULL, "Spectate", M_ChangeControl, gc_spectate }, - {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup }, - {IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown }, - {IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview}, - {IT_CALL | IT_STRING2, NULL, "Reset Camera", M_ChangeControl, gc_camreset }, - {IT_CALL | IT_STRING2, NULL, "Toggle Chasecam", M_ChangeControl, gc_camtoggle }, + {IT_CONTROL, NULL, "Become Spectator", M_ChangeControl, gc_spectate }, + {IT_CONTROL, NULL, "Look Up", M_ChangeControl, gc_lookup }, + {IT_CONTROL, NULL, "Look Down", M_ChangeControl, gc_lookdown }, + {IT_CONTROL, NULL, "Center View", M_ChangeControl, gc_centerview}, + {IT_CONTROL, NULL, "Reset Camera", M_ChangeControl, gc_camreset }, + {IT_CONTROL, NULL, "Toggle Chasecam", M_ChangeControl, gc_camtoggle }, + + {IT_STRING | IT_CVAR, NULL, "Chasecam" , &cv_chasecam , 52}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 60}, }; static menuitem_t OP_CustomControlsMenu[] = { - {IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1}, - {IT_CALL | IT_STRING2, NULL, "Custom Action 2", M_ChangeControl, gc_custom2}, - {IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3}, + {IT_CONTROL, NULL, "Custom Action 1", M_ChangeControl, gc_custom1}, + {IT_CONTROL, NULL, "Custom Action 2", M_ChangeControl, gc_custom2}, + {IT_CONTROL, NULL, "Custom Action 3", M_ChangeControl, gc_custom3}, }; // Obsolete thanks to Kart @@ -1196,7 +1155,7 @@ static menuitem_t OP_MiscControlsMenu[] = static menuitem_t OP_Joystick1Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Joystick..." , M_Setup1PJoystickMenu, 10}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad..." , M_Setup1PJoystickMenu, 10}, {IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis , 30}, {IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis , 40}, {IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis , 50}, @@ -1208,7 +1167,7 @@ static menuitem_t OP_Joystick1Menu[] = static menuitem_t OP_Joystick2Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Joystick..." , M_Setup2PJoystickMenu, 10}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad..." , M_Setup2PJoystickMenu, 10}, {IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis2 , 30}, {IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis2 , 40}, {IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis2 , 50}, @@ -1221,7 +1180,7 @@ static menuitem_t OP_Joystick2Menu[] = #ifndef NOFOURPLAYER static menuitem_t OP_Joystick3Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Joystick..." , M_Setup3PJoystickMenu, 10}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad..." , M_Setup3PJoystickMenu, 10}, {IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis3 , 30}, {IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis3 , 40}, {IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis3 , 50}, @@ -1233,7 +1192,7 @@ static menuitem_t OP_Joystick3Menu[] = static menuitem_t OP_Joystick4Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Joystick..." , M_Setup4PJoystickMenu, 10}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad..." , M_Setup4PJoystickMenu, 10}, {IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis4 , 30}, {IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis4 , 40}, {IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis4 , 50}, @@ -1246,16 +1205,17 @@ static menuitem_t OP_Joystick4Menu[] = static menuitem_t OP_JoystickSetMenu[] = { - {IT_CALL | IT_NOTHING, "None", NULL, M_AssignJoystick, '0'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '1'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '2'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '3'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '4'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '5'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '6'}, + {IT_CALL | IT_NOTHING, "None", NULL, M_AssignJoystick, LINEHEIGHT+5}, + {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, (LINEHEIGHT*2)+5}, + {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, (LINEHEIGHT*3)+5}, + {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, (LINEHEIGHT*4)+5}, + {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, (LINEHEIGHT*5)+5}, + {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, (LINEHEIGHT*6)+5}, + {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, (LINEHEIGHT*7)+5}, + {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, (LINEHEIGHT*8)+5}, }; -static menuitem_t OP_MouseOptionsMenu[] = +/*static menuitem_t OP_MouseOptionsMenu[] = { {IT_STRING | IT_CVAR, NULL, "Use Mouse", &cv_usemouse, 10}, @@ -1281,30 +1241,28 @@ static menuitem_t OP_Mouse2OptionsMenu[] = NULL, "Mouse X Speed", &cv_mousesens2, 60}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse Y Speed", &cv_mouseysens2, 70}, -}; +};*/ static menuitem_t OP_VideoOptionsMenu[] = { - {IT_STRING | IT_CALL, NULL, "Video Modes...", M_VideoModeMenu, 10}, - + {IT_STRING | IT_CALL, NULL, "Set Resolution...", M_VideoModeMenu, 10}, #ifdef HWRENDER - {IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, + {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 20}, #endif - #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 30}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 30}, #endif - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Brightness", &cv_usegamma, 50}, - {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 60}, - {IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist", &cv_drawdist_nights, 70}, - {IT_STRING | IT_CVAR, NULL, "Precip Draw Dist", &cv_drawdist_precip, 80}, - {IT_STRING | IT_CVAR, NULL, "Precip Density", &cv_precipdensity, 90}, + NULL, "Gamma", &cv_usegamma, 50}, - {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 110}, - {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 120}, - {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 130}, + {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 70}, + //{IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist", &cv_drawdist_nights, 80}, + {IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 80}, + {IT_STRING | IT_CVAR, NULL, "Weather Density", &cv_precipdensity, 90}, + {IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 100}, + + {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 120}, + {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 130}, }; static menuitem_t OP_VideoModeMenu[] = @@ -1315,7 +1273,7 @@ static menuitem_t OP_VideoModeMenu[] = #ifdef HWRENDER static menuitem_t OP_OpenGLOptionsMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 10}, + {IT_STRING|IT_CVAR, NULL, "Field of View", &cv_grfov, 10}, {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 20}, {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 30}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,40}, @@ -1342,43 +1300,55 @@ static menuitem_t OP_OpenGLLightingMenu[] = static menuitem_t OP_OpenGLFogMenu[] = { {IT_STRING|IT_CVAR, NULL, "Fog", &cv_grfog, 10}, - {IT_STRING|IT_KEYHANDLER, NULL, "Fog color", M_HandleFogColor, 20}, - {IT_STRING|IT_CVAR, NULL, "Fog density", &cv_grfogdensity, 30}, + {IT_STRING|IT_KEYHANDLER, NULL, "Fog Color", M_HandleFogColor, 20}, + {IT_STRING|IT_CVAR, NULL, "Fog Density", &cv_grfogdensity, 30}, {IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40}, }; static menuitem_t OP_OpenGLColorMenu[] = { - {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "red", &cv_grgammared, 10}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "green", &cv_grgammagreen, 20}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "blue", &cv_grgammablue, 30}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Red", &cv_grgammared, 10}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Green", &cv_grgammagreen, 20}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Blue", &cv_grgammablue, 30}, }; #endif static menuitem_t OP_SoundOptionsMenu[] = { - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Sound Volume" , &cv_soundvolume, 10}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Music Volume" , &cv_digmusicvolume, 20}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "MIDI Volume" , &cv_midimusicvolume, 30}, -#ifdef PC_DOS - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "CD Volume" , &cd_volume, 40}, -#endif + {IT_KEYHANDLER|IT_STRING, NULL, "SFX", M_ToggleSFX, 10}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, + NULL, "SFX Volume", &cv_soundvolume, 18}, - {IT_STRING | IT_CALL, NULL, "Toggle SFX" , M_ToggleSFX, 50}, - {IT_STRING | IT_CALL, NULL, "Toggle Digital Music", M_ToggleDigital, 60}, - {IT_STRING | IT_CALL, NULL, "Toggle MIDI Music", M_ToggleMIDI, 70}, + {IT_KEYHANDLER|IT_STRING, NULL, "Music", M_ToggleDigital, 30}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, + NULL, "Music Volume", &cv_digmusicvolume, 38}, + +/* -- :nonnathisshit: + {IT_KEYHANDLER|IT_STRING, NULL, "MIDI", M_ToggleMIDI, 50}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, + NULL, "MIDI Volume", &cv_midimusicvolume, 58}, +#ifdef PC_DOS + {IT_STRING|IT_CVAR|IT_CV_SLIDER, + NULL, "CD Volume", &cd_volume, 40}, +#endif*/ + + {IT_STRING|IT_CALL, NULL, "Restart Audio System", M_RestartAudio, 50}, + + {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 70}, + {IT_STRING|IT_CVAR, NULL, "Surround Sound", &surround, 80}, + + {IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 100}, + {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 110}, + + {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 130}, }; -static menuitem_t OP_DataOptionsMenu[] = +/*static menuitem_t OP_DataOptionsMenu[] = { {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10}, {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", &OP_EraseDataDef, 30}, -}; +};*/ static menuitem_t OP_ScreenshotOptionsMenu[] = { @@ -1416,63 +1386,69 @@ enum static menuitem_t OP_EraseDataMenu[] = { {IT_STRING | IT_CALL, NULL, "Erase Record Data", M_EraseData, 10}, - {IT_STRING | IT_CALL, NULL, "Erase Secrets Data", M_EraseData, 20}, + {IT_STRING | IT_CALL, NULL, "Erase Unlockable Data", M_EraseData, 20}, {IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40}, }; +static menuitem_t OP_HUDOptionsMenu[] = +{ + {IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 10}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, + NULL, "HUD Visibility", &cv_translucenthud, 20}, + + {IT_STRING | IT_CVAR | IT_CV_SLIDER, + NULL, "Minimap Visibility", &cv_kartminimap, 40}, + {IT_STRING | IT_CVAR, NULL, "Speedometer Display", &cv_kartspeedometer, 50}, + {IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", &cv_kartcheck, 60}, + + {IT_STRING | IT_CVAR, NULL, "Console Color", &cons_backcolor, 80}, + {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 90}, + + {IT_STRING | IT_CVAR, NULL, "Menu Highlights", &cons_menuhighlight, 110}, +}; + static menuitem_t OP_GameOptionsMenu[] = { -#ifndef NONET - {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Master server", &cv_masterserver, 10}, -#endif - {IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 40}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "HUD Visibility", &cv_translucenthud, 50}, + {IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", &OP_MonitorToggleDef, 10}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Minimap Visibility", &cv_kartminimap, 62}, - {IT_STRING | IT_CVAR, NULL, "Speedometer Display", &cv_speedometer, 72}, - {IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", &cv_kartcheck, 82}, - {IT_STRING | IT_CVAR, NULL, "Star SFX", &cv_kartstarsfx, 92}, + {IT_STRING | IT_CVAR, NULL, "Game Speed", &cv_kartspeed, 30}, + {IT_STRING | IT_CVAR, NULL, "Frantic Items", &cv_kartfrantic, 40}, + {IT_STRING | IT_CVAR, NULL, "Mirror Mode", &cv_kartmirror, 50}, -#ifdef SEENAMES - {IT_STRING | IT_CVAR, NULL, "HUD Player Names", &cv_seenames, 104}, -#endif - {IT_STRING | IT_CVAR, NULL, "Log Hazard Damage", &cv_hazardlog, 114}, + {IT_STRING | IT_CVAR, NULL, "Number of Laps", &cv_basenumlaps, 70}, + {IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", &cv_countdowntime, 80}, - {IT_STRING | IT_CVAR, NULL, "Console Back Color", &cons_backcolor, 126}, - {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize,136}, - {IT_STRING | IT_CVAR, NULL, "Uppercase Console", &cv_allcaps, 146}, + //{IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 100}, + {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 100}, + {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 110}, - {IT_STRING | IT_CVAR, NULL, "Title Screen Demos", &cv_rollingdemos, 158}, + {IT_STRING | IT_CVAR, NULL, "Force Character #", &cv_forceskin, 130}, + {IT_STRING | IT_CVAR, NULL, "Restrict Character Changes", &cv_restrictskinchange, 140}, }; static menuitem_t OP_ServerOptionsMenu[] = { - {IT_STRING | IT_SUBMENU, NULL, "General netgame options...", &OP_NetgameOptionsDef, 10}, - {IT_STRING | IT_SUBMENU, NULL, "Gametype options...", &OP_GametypeOptionsDef, 20}, - {IT_STRING | IT_SUBMENU, NULL, "Random item toggles...", &OP_MonitorToggleDef, 30}, - #ifndef NONET {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Server name", &cv_servername, 50}, + NULL, "Server Name", &cv_servername, 10}, #endif - {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 80}, - {IT_STRING | IT_CVAR, NULL, "Voting Timer", &cv_votetime, 90}, - {IT_STRING | IT_CVAR, NULL, "Advance to next map", &cv_advancemap, 100}, + {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 40}, + {IT_STRING | IT_CVAR, NULL, "Voting Timer", &cv_votetime, 50}, + {IT_STRING | IT_CVAR, NULL, "Advance to Next Level", &cv_advancemap, 60}, #ifndef NONET - {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 120}, - {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 130}, - {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 140}, - {IT_STRING | IT_CVAR, NULL, "Attempts to Resynch", &cv_resynchattempts, 150}, + {IT_STRING | IT_CVAR, NULL, "Max Player Count", &cv_maxplayers, 80}, + {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 90}, + //{IT_STRING | IT_CVAR, NULL, "Join on Map Change", &cv_joinnextround, 100}, + + {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 100}, + {IT_STRING | IT_CVAR, NULL, "Attempts to Resynch", &cv_resynchattempts, 110}, #endif }; -static menuitem_t OP_NetgameOptionsMenu[] = +/*static menuitem_t OP_NetgameOptionsMenu[] = { {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 10}, {IT_STRING | IT_CVAR, NULL, "Point Limit", &cv_pointlimit, 18}, @@ -1480,18 +1456,18 @@ static menuitem_t OP_NetgameOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Frantic Items", &cv_kartfrantic, 34}, {IT_STRING | IT_CVAR, NULL, "Item Respawn", &cv_itemrespawn, 50}, - {IT_STRING | IT_CVAR, NULL, "Item Respawn time", &cv_itemrespawntime, 58}, + {IT_STRING | IT_CVAR, NULL, "Item Respawn Delay", &cv_itemrespawntime, 58}, - {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 74}, + {IT_STRING | IT_CVAR, NULL, "Player Respawn Delay", &cv_respawntime, 74}, {IT_STRING | IT_CVAR, NULL, "Force Skin #", &cv_forceskin, 90}, - {IT_STRING | IT_CVAR, NULL, "Restrict skin changes", &cv_restrictskinchange, 98}, + {IT_STRING | IT_CVAR, NULL, "Restrict Skin Changes", &cv_restrictskinchange, 98}, //{IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 114}, //{IT_STRING | IT_CVAR, NULL, "Scramble Teams on Map Change", &cv_scrambleonchange, 122}, -}; +};*/ -static menuitem_t OP_GametypeOptionsMenu[] = +/*static menuitem_t OP_GametypeOptionsMenu[] = { {IT_HEADER, NULL, "RACE", NULL, 2}, {IT_STRING | IT_CVAR, NULL, "Game Speed", &cv_kartspeed, 10}, @@ -1500,33 +1476,33 @@ static menuitem_t OP_GametypeOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Use Map Lap Counts", &cv_usemapnumlaps, 34}, {IT_HEADER, NULL, "BATTLE", NULL, 50}, - {IT_STRING | IT_CVAR, NULL, "Starting Balloons", &cv_kartballoons, 58}, + {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 58}, {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 66}, -}; +};*/ static menuitem_t OP_MonitorToggleMenu[] = { // Printing handled by drawing function // Instead of using this for dumb monitors, lets use the new item bools we have :V - {IT_STRING | IT_CVAR, NULL, "Mushrooms", &cv_mushroom, 10}, - {IT_STRING | IT_CVAR, NULL, "Triple Mushrooms", &cv_triplemushroom, 18}, - {IT_STRING | IT_CVAR, NULL, "Mega Mushrooms", &cv_megashroom, 26}, - {IT_STRING | IT_CVAR, NULL, "Golden Mushrooms", &cv_goldshroom, 34}, - {IT_STRING | IT_CVAR, NULL, "Stars", &cv_star, 42}, - {IT_STRING | IT_CVAR, NULL, "Bananas", &cv_banana, 50}, - {IT_STRING | IT_CVAR, NULL, "Triple Bananas", &cv_triplebanana, 58}, - {IT_STRING | IT_CVAR, NULL, "Fake Items", &cv_fakeitem, 66}, - {IT_STRING | IT_CVAR, NULL, "Green Shells", &cv_greenshell, 74}, - {IT_STRING | IT_CVAR, NULL, "Red Shells", &cv_redshell, 82}, - {IT_STRING | IT_CVAR, NULL, "Triple Green Shells", &cv_triplegreenshell, 90}, - {IT_STRING | IT_CVAR, NULL, "Triple Red Shells", &cv_tripleredshell, 98}, - {IT_STRING | IT_CVAR, NULL, "Bob-ombs", &cv_bobomb, 106}, - {IT_STRING | IT_CVAR, NULL, "Fire Flowers", &cv_fireflower, 114}, - {IT_STRING | IT_CVAR, NULL, "Magnets", &cv_magnet, 122}, - {IT_STRING | IT_CVAR, NULL, "Boos", &cv_boo, 130}, - {IT_STRING | IT_CVAR, NULL, "Lightning", &cv_lightning, 138}, - {IT_STRING | IT_CVAR, NULL, "Blue Lightning", &cv_blueshell, 146}, - {IT_STRING | IT_CVAR, NULL, "Feathers", &cv_feather, 154}, + {IT_STRING | IT_CVAR, NULL, "Sneakers", &cv_sneaker, 10}, + {IT_STRING | IT_CVAR, NULL, "Sneakers x3", &cv_triplesneaker, 18}, + {IT_STRING | IT_CVAR, NULL, "Rocket Sneakers", &cv_rocketsneaker, 26}, + {IT_STRING | IT_CVAR, NULL, "Invinciblity", &cv_invincibility, 34}, + {IT_STRING | IT_CVAR, NULL, "Bananas", &cv_banana, 42}, + {IT_STRING | IT_CVAR, NULL, "Bananas x3", &cv_triplebanana, 50}, + {IT_STRING | IT_CVAR, NULL, "Eggman Monitors", &cv_eggmanmonitor, 58}, + {IT_STRING | IT_CVAR, NULL, "Orbinauts", &cv_orbinaut, 66}, + {IT_STRING | IT_CVAR, NULL, "Orbinauts x3", &cv_tripleorbinaut, 74}, + {IT_STRING | IT_CVAR, NULL, "Jawz", &cv_jawz, 82}, + {IT_STRING | IT_CVAR, NULL, "Jawz x2", &cv_dualjawz, 90}, + {IT_STRING | IT_CVAR, NULL, "Mines", &cv_mine, 98}, + {IT_STRING | IT_CVAR, NULL, "Ballhogs", &cv_ballhog, 106}, + {IT_STRING | IT_CVAR, NULL, "Self-Propelled Bombs",&cv_selfpropelledbomb,114}, + {IT_STRING | IT_CVAR, NULL, "Grow", &cv_grow, 122}, + {IT_STRING | IT_CVAR, NULL, "Shrink", &cv_shrink, 130}, + {IT_STRING | IT_CVAR, NULL, "Lightning Shields", &cv_lightningshield, 138}, + {IT_STRING | IT_CVAR, NULL, "Hyudoros", &cv_hyudoro, 146}, + {IT_STRING | IT_CVAR, NULL, "Pogo Springs", &cv_pogospring, 154}, }; // ========================================================================== @@ -1546,6 +1522,73 @@ menu_t MISC_ChangeTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ChangeTeamMenu, &MPauseD menu_t MISC_ChangeLevelDef = MAPICONMENUSTYLE(NULL, MISC_ChangeLevelMenu, &MPauseDef); menu_t MISC_HelpDef = IMAGEDEF(MISC_HelpMenu); +// +// M_GetGametypeColor +// +// Pretty and consistent ^u^ +// See also G_GetGametypeColor. +// + +static INT32 highlightflags, recommendedflags, warningflags; + +inline static void M_GetGametypeColor(void) +{ + INT16 gt; + + warningflags = V_REDMAP; + recommendedflags = V_GREENMAP; + + if (cons_menuhighlight.value) + { + highlightflags = cons_menuhighlight.value; + if (highlightflags == V_REDMAP) + { + warningflags = V_ORANGEMAP; + return; + } + if (highlightflags == V_GREENMAP) + { + recommendedflags = V_SKYMAP; + return; + } + return; + } + + warningflags = V_REDMAP; + recommendedflags = V_GREENMAP; + + if (modeattacking // == ATTACKING_RECORD + || gamestate == GS_TIMEATTACK) + { + highlightflags = V_ORANGEMAP; + return; + } + + if (currentMenu->drawroutine == M_DrawServerMenu) + gt = cv_newgametype.value; + else if (!Playing()) + { + highlightflags = V_YELLOWMAP; + return; + } + else + gt = gametype; + + if (gt == GT_MATCH) + { + highlightflags = V_REDMAP; + warningflags = V_ORANGEMAP; + return; + } + if (gt == GT_RACE) + { + highlightflags = V_SKYMAP; + return; + } + + highlightflags = V_YELLOWMAP; // FALLBACK +} + // Sky Room menu_t SR_PandoraDef = { @@ -1569,17 +1612,9 @@ menu_t SR_MainDef = 0, NULL }; -menu_t SR_LevelSelectDef = -{ - 0, - sizeof (SR_LevelSelectMenu)/sizeof (menuitem_t), - &SR_MainDef, - SR_LevelSelectMenu, - M_DrawLevelSelectMenu, - 40, 40, - 0, - NULL -}; + +menu_t SR_LevelSelectDef = MAPICONMENUSTYLE(NULL, SR_LevelSelectMenu, &SR_MainDef); + menu_t SR_UnlockChecklistDef = { NULL, @@ -1618,17 +1653,6 @@ menu_t SP_LoadDef = }; menu_t SP_LevelSelectDef = MAPICONMENUSTYLE(NULL, SP_LevelSelectMenu, &SP_LoadDef); -menu_t SP_GameStatsDef = -{ - "M_STATS", - 1, - &SP_MainDef, - SP_GameStatsMenu, - M_DrawGameStats, - 280, 185, - 0, - NULL -}; menu_t SP_LevelStatsDef = { "M_STATS", @@ -1648,9 +1672,9 @@ static menu_t SP_TimeAttackDef = &MainDef, // Doesn't matter. SP_TimeAttackMenu, M_DrawTimeAttackMenu, - 32, 40, + 34, 40, 0, - NULL + M_QuitTimeAttackMenu }; static menu_t SP_ReplayDef = { @@ -1659,7 +1683,7 @@ static menu_t SP_ReplayDef = &SP_TimeAttackDef, SP_ReplayMenu, M_DrawTimeAttackMenu, - 32, 120, + 34, 40, 0, NULL }; @@ -1670,7 +1694,7 @@ static menu_t SP_GuestReplayDef = &SP_TimeAttackDef, SP_GuestReplayMenu, M_DrawTimeAttackMenu, - 32, 120, + 34, 40, 0, NULL }; @@ -1681,7 +1705,7 @@ static menu_t SP_GhostDef = &SP_TimeAttackDef, SP_GhostMenu, M_DrawTimeAttackMenu, - 32, 120, + 34, 40, 0, NULL }; @@ -1744,9 +1768,22 @@ menu_t SP_PlayerDef = NULL }; +#ifndef NONET // Multiplayer -menu_t MP_MainDef = DEFAULTMENUSTYLE("M_MULTI", MP_MainMenu, &MainDef, 60, 40); +menu_t MP_MainDef = +{ + "M_MULTI", + sizeof (MP_MainMenu)/sizeof (menuitem_t), + &MainDef, + MP_MainMenu, + M_DrawMPMainMenu, + 42, 50, + 0, + M_CancelConnect +}; menu_t MP_ServerDef = MAPICONMENUSTYLE("M_MULTI", MP_ServerMenu, &MP_MainDef); +#endif +menu_t MP_SplitServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef); #ifndef NONET menu_t MP_ConnectDef = { @@ -1759,17 +1796,6 @@ menu_t MP_ConnectDef = 0, M_CancelConnect }; -menu_t MP_ConnectIPDef = -{ - "M_MULTI", - sizeof (MP_ConnectIPMenu)/sizeof (menuitem_t), - &MP_MainDef, - MP_ConnectIPMenu, - M_DrawConnectIPMenu, - 27,40, - 0, - M_CancelConnect -}; menu_t MP_RoomDef = { "M_MULTI", @@ -1782,9 +1808,6 @@ menu_t MP_RoomDef = NULL }; #endif -menu_t MP_SplitServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef); -menu_t MP_3PServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef); -menu_t MP_4PServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef); menu_t MP_PlayerSetupDef = { NULL, //"M_SPLAYR" @@ -1792,7 +1815,7 @@ menu_t MP_PlayerSetupDef = &MP_MainDef, MP_PlayerSetupMenu, M_DrawSetupMultiPlayerMenu, - 32, 16, + 36, 14, 0, M_QuitMultiPlayerMenu }; @@ -1804,7 +1827,7 @@ menu_t OP_MainDef = sizeof (OP_MainMenu)/sizeof (menuitem_t), &MainDef, OP_MainMenu, - M_DrawSkyRoom, + M_DrawGenericMenu, 60, 30, 0, NULL @@ -1818,6 +1841,7 @@ menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlsDe //menu_t OP_MiscControlsDef = CONTROLMENUSTYLE(OP_MiscControlsMenu, &OP_ControlListDef); menu_t OP_CustomControlsDef = CONTROLMENUSTYLE(OP_CustomControlsMenu, &OP_MoveControlsDef); menu_t OP_SpectateControlsDef = CONTROLMENUSTYLE(OP_SpectateControlsMenu, &OP_MoveControlsDef); +/* menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_ControlsDef, 60, 30); menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 60, 30); #ifndef NOFOURPLAYER @@ -1826,11 +1850,12 @@ menu_t OP_P4ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P4ControlsMenu, &OP_Co #endif menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 60, 30); menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 60, 30); -menu_t OP_Joystick1Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 60, 30); -menu_t OP_Joystick2Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 60, 30); +*/ +menu_t OP_Joystick1Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick1Menu, &OP_MoveControlsDef, 60, 30); +menu_t OP_Joystick2Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick2Menu, &OP_MoveControlsDef, 60, 30); #ifndef NOFOURPLAYER -menu_t OP_Joystick3Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick3Menu, &OP_P3ControlsDef, 60, 30); -menu_t OP_Joystick4Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick4Menu, &OP_P4ControlsDef, 60, 30); +menu_t OP_Joystick3Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick3Menu, &OP_MoveControlsDef, 60, 30); +menu_t OP_Joystick4Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick4Menu, &OP_MoveControlsDef, 60, 30); #endif menu_t OP_JoystickSetDef = { @@ -1844,7 +1869,18 @@ menu_t OP_JoystickSetDef = NULL }; -menu_t OP_VideoOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_VideoOptionsMenu, &OP_MainDef, 60, 30); +menu_t OP_VideoOptionsDef = +{ + "M_VIDEO", + sizeof(OP_VideoOptionsMenu)/sizeof(menuitem_t), + &OP_MainDef, + OP_VideoOptionsMenu, + M_DrawVideoMenu, + 60, 30, + 0, + NULL +}; + menu_t OP_VideoModeDef = { "M_VIDEO", @@ -1856,13 +1892,37 @@ menu_t OP_VideoModeDef = 0, NULL }; -menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE("M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 60, 30); -menu_t OP_GameOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_GameOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30); -menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30); -menu_t OP_MonitorToggleDef = DEFAULTMENUSTYLE("M_SERVER", OP_MonitorToggleMenu, &OP_ServerOptionsDef, 30, 30); +menu_t OP_SoundOptionsDef = +{ + "M_SOUND", + sizeof (OP_SoundOptionsMenu)/sizeof (menuitem_t), + &OP_MainDef, + OP_SoundOptionsMenu, + M_DrawSkyRoom, + 60, 30, + 0, + NULL +}; + +menu_t OP_HUDOptionsDef = +{ + "M_HUD", + sizeof (OP_HUDOptionsMenu)/sizeof (menuitem_t), + &OP_MainDef, + OP_HUDOptionsMenu, + M_DrawHUDOptions, + 30, 30, + 0, + NULL +}; + +menu_t OP_GameOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_GameOptionsMenu, &OP_MainDef, 30, 30); +menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 24, 30); + +//menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30); +//menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30); +menu_t OP_MonitorToggleDef = DEFAULTMENUSTYLE("M_GAME", OP_MonitorToggleMenu, &OP_GameOptionsDef, 30, 30); /*menu_t OP_MonitorToggleDef = { "M_SERVER", @@ -1903,9 +1963,9 @@ menu_t OP_OpenGLColorDef = NULL }; #endif -menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); -menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_ScreenshotOptionsMenu, &OP_DataOptionsDef, 30, 30); -menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); +//menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); +menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_SCSHOT", OP_ScreenshotOptionsMenu, &OP_MainDef, 30, 30); +menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_MainDef, 60, 30); // ========================================================================== // CVAR ONCHANGE EVENTS GO HERE @@ -1920,8 +1980,6 @@ static INT32 M_GetFirstLevelInList(void); static void Nextmap_OnChange(void) { char *leveltitle; - char tabase[256]; - short i; UINT8 active; lumpnum_t l; @@ -1930,115 +1988,74 @@ static void Nextmap_OnChange(void) leveltitle = G_BuildMapTitle(cv_nextmap.value); cv_nextmap.string = cv_nextmap.zstring = leveltitle ? leveltitle : Z_StrDup(G_BuildMapName(cv_nextmap.value)); - /*if (currentMenu == &SP_NightsAttackDef) + if (currentMenu == &SP_TimeAttackDef) { - CV_StealthSetValue(&cv_dummymares, 0); - // Hide the record changing CVAR if only one mare is available. - if (!nightsrecords[cv_nextmap.value-1] || nightsrecords[cv_nextmap.value-1]->nummares < 2) - SP_NightsAttackMenu[narecords].status = IT_DISABLED; - else - SP_NightsAttackMenu[narecords].status = IT_STRING|IT_CVAR; + // see also p_setup.c's P_LoadRecordGhosts + const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + char *gpath = malloc(glen); + INT32 i; - CV_StealthSetValue(&cv_dummystaff, 0); + if (!gpath) + return; - // Do the replay things. - active = false; - SP_NightsAttackMenu[naguest].status = IT_DISABLED; - SP_NightsAttackMenu[nareplay].status = IT_DISABLED; - SP_NightsAttackMenu[naghost].status = IT_DISABLED; + sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); - // Check if file exists, if not, disable REPLAY option - sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); - for (i = 0; i < 5; i++) { - SP_NightsReplayMenu[i].status = IT_DISABLED; - SP_NightsGuestReplayMenu[i].status = IT_DISABLED; - } - if (FIL_FileExists(va("%s-score-best.lmp", tabase))) { - SP_NightsReplayMenu[0].status = IT_WHITESTRING|IT_CALL; - SP_NightsGuestReplayMenu[0].status = IT_WHITESTRING|IT_CALL; - active |= 3; - } - if (FIL_FileExists(va("%s-time-best.lmp", tabase))) { - SP_NightsReplayMenu[1].status = IT_WHITESTRING|IT_CALL; - SP_NightsGuestReplayMenu[1].status = IT_WHITESTRING|IT_CALL; - active |= 3; - } - if (FIL_FileExists(va("%s-last.lmp", tabase))) { - SP_NightsReplayMenu[2].status = IT_WHITESTRING|IT_CALL; - SP_NightsGuestReplayMenu[2].status = IT_WHITESTRING|IT_CALL; - active |= 3; - } - if (FIL_FileExists(va("%s-guest.lmp", tabase))) { - SP_NightsReplayMenu[3].status = IT_WHITESTRING|IT_CALL; - SP_NightsGuestReplayMenu[3].status = IT_WHITESTRING|IT_CALL; - active |= 3; - } - if ((l = W_CheckNumForName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) != LUMPERROR) { - SP_NightsReplayMenu[4].status = IT_WHITESTRING|IT_KEYHANDLER; - CV_StealthSetValue(&cv_dummystaff, 1); - active |= 1; - } - if (active) { - if (active & 1) - SP_NightsAttackMenu[nareplay].status = IT_WHITESTRING|IT_SUBMENU; - if (active & 2) - SP_NightsAttackMenu[naguest].status = IT_WHITESTRING|IT_SUBMENU; - SP_NightsAttackMenu[naghost].status = IT_WHITESTRING|IT_SUBMENU; - } - else if(itemOn == nareplay) // Reset lastOn so replay isn't still selected when not available. - { - currentMenu->lastOn = itemOn; - itemOn = nastart; - } - } - else*/ if (currentMenu == &SP_TimeAttackDef) - { CV_StealthSetValue(&cv_dummystaff, 0); active = false; SP_TimeAttackMenu[taguest].status = IT_DISABLED; SP_TimeAttackMenu[tareplay].status = IT_DISABLED; - SP_TimeAttackMenu[taghost].status = IT_DISABLED; + //SP_TimeAttackMenu[taghost].status = IT_DISABLED; // Check if file exists, if not, disable REPLAY option - sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string); - for (i = 0; i < 5; i++) { + for (i = 0; i < 4; i++) + { SP_ReplayMenu[i].status = IT_DISABLED; SP_GuestReplayMenu[i].status = IT_DISABLED; } - if (FIL_FileExists(va("%s-time-best.lmp", tabase))) { + SP_ReplayMenu[4].status = IT_DISABLED; + + SP_GhostMenu[3].status = IT_DISABLED; + SP_GhostMenu[4].status = IT_DISABLED; + + if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, cv_chooseskin.string))) { SP_ReplayMenu[0].status = IT_WHITESTRING|IT_CALL; SP_GuestReplayMenu[0].status = IT_WHITESTRING|IT_CALL; active |= 3; } - if (FIL_FileExists(va("%s-lap-best.lmp", tabase))) { + if (FIL_FileExists(va("%s-%s-lap-best.lmp", gpath, cv_chooseskin.string))) { SP_ReplayMenu[1].status = IT_WHITESTRING|IT_CALL; SP_GuestReplayMenu[1].status = IT_WHITESTRING|IT_CALL; active |= 3; } - if (FIL_FileExists(va("%s-last.lmp", tabase))) { + if (FIL_FileExists(va("%s-%s-last.lmp", gpath, cv_chooseskin.string))) { SP_ReplayMenu[2].status = IT_WHITESTRING|IT_CALL; SP_GuestReplayMenu[2].status = IT_WHITESTRING|IT_CALL; active |= 3; } - if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) { + + if (FIL_FileExists(va("%s-guest.lmp", gpath))) + { SP_ReplayMenu[3].status = IT_WHITESTRING|IT_CALL; SP_GuestReplayMenu[3].status = IT_WHITESTRING|IT_CALL; + SP_GhostMenu[3].status = IT_STRING|IT_CVAR; active |= 3; } - if ((l = W_CheckNumForName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) != LUMPERROR) { + if ((l = W_CheckNumForName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) != LUMPERROR) + { SP_ReplayMenu[4].status = IT_WHITESTRING|IT_KEYHANDLER; + SP_GhostMenu[4].status = IT_STRING|IT_CVAR; CV_StealthSetValue(&cv_dummystaff, 1); active |= 1; } + if (active) { if (active & 1) SP_TimeAttackMenu[tareplay].status = IT_WHITESTRING|IT_SUBMENU; if (active & 2) SP_TimeAttackMenu[taguest].status = IT_WHITESTRING|IT_SUBMENU; - SP_TimeAttackMenu[taghost].status = IT_WHITESTRING|IT_SUBMENU; } - else if(itemOn == tareplay) // Reset lastOn so replay isn't still selected when not available. + else if (itemOn == tareplay) // Reset lastOn so replay isn't still selected when not available. { currentMenu->lastOn = itemOn; itemOn = tastart; @@ -2046,6 +2063,8 @@ static void Nextmap_OnChange(void) if (mapheaderinfo[cv_nextmap.value-1] && mapheaderinfo[cv_nextmap.value-1]->forcecharacter[0] != '\0') CV_Set(&cv_chooseskin, mapheaderinfo[cv_nextmap.value-1]->forcecharacter); + + free(gpath); } } @@ -2130,8 +2149,8 @@ static void Newgametype_OnChange(void) } CV_SetValue(&cv_nextmap, M_FindFirstMap(value)); - CV_AddValue(&cv_nextmap, -1); - CV_AddValue(&cv_nextmap, 1); + //CV_AddValue(&cv_nextmap, -1); + //CV_AddValue(&cv_nextmap, 1); } } } @@ -2180,45 +2199,72 @@ static void M_ChangeCvar(INT32 choice) { consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction; + if (choice == -1) + { + if (cv == &cv_playercolor) + { + SINT8 skinno = R_SkinAvailable(cv_chooseskin.string); + if (skinno != -1) + CV_SetValue(cv,skins[skinno].prefcolor); + return; + } + CV_Set(cv,cv->defaultvalue); + return; + } + + choice = (choice<<1) - 1; + if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER) ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER) ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD)) { - CV_SetValue(cv,cv->value+(choice*2-1)); + CV_SetValue(cv,cv->value+choice); } else if (cv->flags & CV_FLOAT) { char s[20]; - sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice*2-1)*(1.0f/16.0f)); + sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f)); CV_Set(cv,s); } else - CV_AddValue(cv,choice*2-1); + CV_AddValue(cv,choice); } static boolean M_ChangeStringCvar(INT32 choice) { consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction; - char buf[255]; + char buf[MAXSTRINGLENGTH]; size_t len; + if (shiftdown && choice >= 32 && choice <= 127) + choice = shiftxform[choice]; + switch (choice) { case KEY_BACKSPACE: len = strlen(cv->string); if (len > 0) { + S_StartSound(NULL,sfx_menu1); // Tails M_Memcpy(buf, cv->string, len); buf[len-1] = 0; CV_Set(cv, buf); } return true; + case KEY_DEL: + if (cv->string[0]) + { + S_StartSound(NULL,sfx_menu1); // Tails + CV_Set(cv, ""); + } + return true; default: if (choice >= 32 && choice <= 127) { len = strlen(cv->string); if (len < MAXSTRINGLENGTH - 1) { + S_StartSound(NULL,sfx_menu1); // Tails M_Memcpy(buf, cv->string, len); buf[len++] = (char)choice; buf[len] = 0; @@ -2539,7 +2585,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef) + if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(0); } @@ -2549,7 +2595,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef) + if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(1); } @@ -2624,10 +2670,29 @@ boolean M_Responder(event_t *ev) G_ClearControlKeys(setupcontrols, currentMenu->menuitems[itemOn].alphaKey); return true; } + + if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS + || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) + { + consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction; + + if (cv == &cv_chooseskin + || cv == &cv_dummystaff + || cv == &cv_nextmap + || cv == &cv_newgametype) + return true; + + if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) + S_StartSound(NULL, sfx_menu1); + routine(-1); + return true; + } + // Why _does_ backspace go back anyway? - //currentMenu->lastOn = itemOn; - //if (currentMenu->prevMenu) - // M_SetupNextMenu(currentMenu->prevMenu); + // Sal: Because it supports gamepads better. And still makes sense for keyboard. + currentMenu->lastOn = itemOn; + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); return false; default: @@ -2651,10 +2716,13 @@ void M_Drawer(void) { // now that's more readable with a faded background (yeah like Quake...) if (!WipeInAction) - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); if (currentMenu->drawroutine) + { + M_GetGametypeColor(); currentMenu->drawroutine(); // call current menu Draw routine + } // Draw version down in corner // ... but only in the MAIN MENU. I'm a picky bastard. @@ -2682,9 +2750,9 @@ void M_Drawer(void) { M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2); if (gamestate == GS_LEVEL && (P_AutoPause() || paused)) - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused"); + V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), highlightflags, "Game Paused"); else - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost"); + V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), highlightflags, "Focus Lost"); } } @@ -2697,6 +2765,7 @@ void M_StartControlPanel(void) if (modeattacking && demoplayback) { G_CheckDemoStatus(); + S_ChangeMusicInternal("racent", true); return; } @@ -2778,6 +2847,7 @@ void M_StartControlPanel(void) #endif MPauseMenu[mpause_spectate].status = IT_DISABLED; MPauseMenu[mpause_entergame].status = IT_DISABLED; + MPauseMenu[mpause_canceljoin].status = IT_DISABLED; MPauseMenu[mpause_switchteam].status = IT_DISABLED; MPauseMenu[mpause_psetup].status = IT_DISABLED; // Reset these in case splitscreen messes things up @@ -2825,7 +2895,14 @@ void M_StartControlPanel(void) if (G_GametypeHasTeams()) MPauseMenu[mpause_switchteam].status = IT_STRING | IT_SUBMENU; else if (G_GametypeHasSpectators()) - MPauseMenu[((&players[consoleplayer] && players[consoleplayer].spectator) ? mpause_entergame : mpause_spectate)].status = IT_STRING | IT_CALL; + { + if (!players[consoleplayer].spectator) + MPauseMenu[mpause_spectate].status = IT_STRING | IT_CALL; + else if (players[consoleplayer].pflags & PF_WANTSTOJOIN) + MPauseMenu[mpause_canceljoin].status = IT_STRING | IT_CALL; + else + MPauseMenu[mpause_entergame].status = IT_STRING | IT_CALL; + } else // in this odd case, we still want something to be on the menu even if it's useless MPauseMenu[mpause_spectate].status = IT_GRAYEDOUT; } @@ -2934,6 +3011,9 @@ void M_Init(void) return; // Menu hacks +#ifndef NOFOURPLAYER + CV_RegisterVar(&cv_dummysplitplayers); +#endif CV_RegisterVar(&cv_dummyteam); CV_RegisterVar(&cv_dummyscramble); CV_RegisterVar(&cv_dummyrings); @@ -2946,26 +3026,26 @@ void M_Init(void) quitmsg[QUITMSG1] = M_GetText("What would Tails say if\nhe saw you quitting the game?\n\n(Press 'Y' to quit)"); quitmsg[QUITMSG2] = M_GetText("Hey!\nWhere do ya think you're goin'?\n\n(Press 'Y' to quit)"); quitmsg[QUITMSG3] = M_GetText("Forget your studies!\nPlay some more!\n\n(Press 'Y' to quit)"); - quitmsg[QUITMSG4] = M_GetText("You're trying to say you\nlike Sonic 2K6 better than\nthis, right?\n\n(Press 'Y' to quit)"); + quitmsg[QUITMSG4] = M_GetText("You're trying to say you\nlike Sonic R better than\nthis, aren't you?\n\n(Press 'Y' to quit)"); quitmsg[QUITMSG5] = M_GetText("Don't leave yet -- there's a\nsuper emerald around that corner!\n\n(Press 'Y' to quit)"); quitmsg[QUITMSG6] = M_GetText("You'd rather work than play?\n\n(Press 'Y' to quit)"); quitmsg[QUITMSG7] = M_GetText("Go ahead and leave. See if I care...\n*sniffle*\n\n(Press 'Y' to quit)"); quitmsg[QUIT2MSG] = M_GetText("If you leave now,\nEggman will take over the world!\n\n(Press 'Y' to quit)"); - quitmsg[QUIT2MSG1] = M_GetText("Don't quit!\nThere are animals\nto save!\n\n(Press 'Y' to quit)"); - quitmsg[QUIT2MSG2] = M_GetText("Aw c'mon, just bop\na few more robots!\n\n(Press 'Y' to quit)"); + quitmsg[QUIT2MSG1] = M_GetText("On your mark,\nget set,\nhit the 'N' key!\n\n(Press 'Y' to quit)"); + quitmsg[QUIT2MSG2] = M_GetText("Aw c'mon, just\na few more laps!\n\n(Press 'Y' to quit)"); quitmsg[QUIT2MSG3] = M_GetText("Did you get all those Chaos Emeralds?\n\n(Press 'Y' to quit)"); - quitmsg[QUIT2MSG4] = M_GetText("If you leave, I'll use\nmy spin attack on you!\n\n(Press 'Y' to quit)"); + quitmsg[QUIT2MSG4] = M_GetText("If you leave, I'll use\nmy Jawz on you!\n\n(Press 'Y' to quit)"); quitmsg[QUIT2MSG5] = M_GetText("Don't go!\nYou might find the hidden\nlevels!\n\n(Press 'Y' to quit)"); quitmsg[QUIT2MSG6] = M_GetText("Hit the 'N' key, Sonic!\nThe 'N' key!\n\n(Press 'Y' to quit)"); quitmsg[QUIT3MSG] = M_GetText("Are you really going to give up?\nWe certainly would never give you up.\n\n(Press 'Y' to quit)"); quitmsg[QUIT3MSG1] = M_GetText("Come on, just ONE more netgame!\n\n(Press 'Y' to quit)"); - quitmsg[QUIT3MSG2] = M_GetText("Press 'N' to unlock\nthe Ultimate Cheat!\n\n(Press 'Y' to quit)"); - quitmsg[QUIT3MSG3] = M_GetText("Why don't you go back and try\njumping on that house to\nsee what happens?\n\n(Press 'Y' to quit)"); + quitmsg[QUIT3MSG2] = M_GetText("Press 'N' to unlock\nthe Golden Kart!\n\n(Press 'Y' to quit)"); + quitmsg[QUIT3MSG3] = M_GetText("Couldn't handle\nthe banana meta?\n\n(Press 'Y' to quit)"); quitmsg[QUIT3MSG4] = M_GetText("Every time you press 'Y', an\nSRB2Kart Developer cries...\n\n(Press 'Y' to quit)"); - quitmsg[QUIT3MSG5] = M_GetText("You'll be back to play soon, though...\n......right?\n\n(Press 'Y' to quit)"); - quitmsg[QUIT3MSG6] = M_GetText("Aww, is Egg Rock Zone too\ndifficult for you?\n\n(Press 'Y' to quit)"); + quitmsg[QUIT3MSG5] = M_GetText("You'll be back to play soon, though...\n...right?\n\n(Press 'Y' to quit)"); + quitmsg[QUIT3MSG6] = M_GetText("Aww, is Eggman's Nightclub too\ndifficult for you?\n\n(Press 'Y' to quit)"); #ifdef HWRENDER // Permanently hide some options based on render mode @@ -3037,7 +3117,7 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv) } // A smaller 'Thermo', with range given as percents (0-100) -static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) +static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) { INT32 i; INT32 range; @@ -3045,16 +3125,31 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) for (i = 0; cv->PossibleValue[i+1].strvalue; i++); - range = ((cv->value - cv->PossibleValue[0].value) * 100 / - (cv->PossibleValue[i].value - cv->PossibleValue[0].value)); - - if (range < 0) - range = 0; - if (range > 100) - range = 100; - x = BASEVIDWIDTH - x - SLIDER_WIDTH; + if (ontop) + { + V_DrawCharacter(x - 16 - (skullAnimCounter/5), y, + '\x1C' | highlightflags, false); // left arrow + V_DrawCharacter(x+(SLIDER_RANGE*8) + 8 + (skullAnimCounter/5), y, + '\x1D' | highlightflags, false); // right arrow + } + + if ((range = atoi(cv->defaultvalue)) != cv->value) + { + range = ((range - cv->PossibleValue[0].value) * 100 / + (cv->PossibleValue[1].value - cv->PossibleValue[0].value)); + + if (range < 0) + range = 0; + if (range > 100) + range = 100; + + // draw the default + p = W_CachePatchName("M_SLIDEC", PU_CACHE); + V_DrawScaledPatch(x - 4 + (((SLIDER_RANGE)*8 + 4)*range)/100, y, 0, p); + } + V_DrawScaledPatch(x - 8, y, 0, W_CachePatchName("M_SLIDEL", PU_CACHE)); p = W_CachePatchName("M_SLIDEM", PU_CACHE); @@ -3064,9 +3159,17 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) p = W_CachePatchName("M_SLIDER", PU_CACHE); V_DrawScaledPatch(x+SLIDER_RANGE*8, y, 0, p); + range = ((cv->value - cv->PossibleValue[0].value) * 100 / + (cv->PossibleValue[1].value - cv->PossibleValue[0].value)); + + if (range < 0) + range = 0; + if (range > 100) + range = 100; + // draw the slider cursor p = W_CachePatchName("M_SLIDEC", PU_CACHE); - V_DrawMappedPatch(x + ((SLIDER_RANGE-1)*8*range)/100, y, 0, p, yellowmap); + V_DrawScaledPatch(x - 4 + (((SLIDER_RANGE)*8 + 4)*range)/100, y, 0, p); } // @@ -3226,7 +3329,7 @@ static void M_DrawMenuTitle(void) static void M_DrawGenericMenu(void) { - INT32 x, y, i, cursory = 0; + INT32 x, y, w, i, cursory = 0; // DRAW MENU x = currentMenu->x; @@ -3259,7 +3362,7 @@ static void M_DrawGenericMenu(void) /* FALLTHRU */ case IT_NOTHING: case IT_DYBIGSPACE: - y += LINEHEIGHT; + y = currentMenu->y+currentMenu->menuitems[i].alphaKey;//+= LINEHEIGHT; break; case IT_BIGSLIDER: M_DrawThermo(x, y, (consvar_t *)currentMenu->menuitems[i].itemaction); @@ -3275,7 +3378,7 @@ static void M_DrawGenericMenu(void) if ((currentMenu->menuitems[i].status & IT_DISPLAY)==IT_STRING) V_DrawString(x, y, 0, currentMenu->menuitems[i].text); else - V_DrawString(x, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + V_DrawString(x, y, highlightflags, currentMenu->menuitems[i].text); // Cvar specific handling switch (currentMenu->menuitems[i].status & IT_TYPE) @@ -3285,7 +3388,7 @@ static void M_DrawGenericMenu(void) switch (currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this case IT_CV_INVISSLIDER: // monitor toggles use this break; @@ -3298,8 +3401,16 @@ static void M_DrawGenericMenu(void) y += 16; break; default: - V_DrawString(BASEVIDWIDTH - x - V_StringWidth(cv->string, 0), y, - ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + w = V_StringWidth(cv->string, 0); + V_DrawString(BASEVIDWIDTH - x - w, y, + ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? warningflags : highlightflags), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - w - (skullAnimCounter/5), y, + '\x1C' | highlightflags, false); // left arrow + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | highlightflags, false); // right arrow + } break; } break; @@ -3337,7 +3448,7 @@ static void M_DrawGenericMenu(void) if (currentMenu->menuitems[i].alphaKey) y = currentMenu->y+currentMenu->menuitems[i].alphaKey; - V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + V_DrawString(x-16, y, highlightflags, currentMenu->menuitems[i].text); y += SMALLLINEHEIGHT; break; } @@ -3354,12 +3465,13 @@ static void M_DrawGenericMenu(void) { V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); - V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); + V_DrawString(currentMenu->x, cursory, highlightflags, currentMenu->menuitems[itemOn].text); } } static void M_DrawPauseMenu(void) { +#if 0 if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) { emblem_t *emblem_detail[3] = {NULL, NULL, NULL}; @@ -3374,16 +3486,16 @@ static void M_DrawPauseMenu(void) if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) { if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) - V_DrawString(40, 28, V_YELLOWMAP, va("%s %s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum)); + V_DrawString(40, 28, highlightflags, va("%s %s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum)); else - V_DrawString(40, 28, V_YELLOWMAP, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl)); + V_DrawString(40, 28, highlightflags, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl)); } else { if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) - V_DrawString(40, 28, V_YELLOWMAP, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); + V_DrawString(40, 28, highlightflags, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); else - V_DrawString(40, 28, V_YELLOWMAP, mapheaderinfo[gamemap-1]->lvlttl); + V_DrawString(40, 28, highlightflags, mapheaderinfo[gamemap-1]->lvlttl); } // Set up the detail boxes. @@ -3495,19 +3607,20 @@ static void M_DrawPauseMenu(void) { /*case ET_SCORE: case ET_NGRADE: - V_DrawString(56, 44 + (i*8), V_YELLOWMAP, "SCORE:"); + V_DrawString(56, 44 + (i*8), highlightflags, "SCORE:"); break;*/ case ET_TIME: //case ET_NTIME: - V_DrawString(56, 44 + (i*8), V_YELLOWMAP, "TIME:"); + V_DrawString(56, 44 + (i*8), highlightflags, "TIME:"); break; /*case ET_RINGS: - V_DrawString(56, 44 + (i*8), V_YELLOWMAP, "RINGS:"); + V_DrawString(56, 44 + (i*8), highlightflags, "RINGS:"); break;*/ } V_DrawRightAlignedString(284, 44 + (i*8), V_MONOSPACE, emblem_text[i]); } } +#endif M_DrawGenericMenu(); } @@ -3563,7 +3676,7 @@ static void M_DrawCenteredMenu(void) if ((currentMenu->menuitems[i].status & IT_DISPLAY)==IT_STRING) V_DrawCenteredString(x, y, 0, currentMenu->menuitems[i].text); else - V_DrawCenteredString(x, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + V_DrawCenteredString(x, y, highlightflags, currentMenu->menuitems[i].text); // Cvar specific handling switch(currentMenu->menuitems[i].status & IT_TYPE) @@ -3573,7 +3686,7 @@ static void M_DrawCenteredMenu(void) switch(currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this break; case IT_CV_STRING: @@ -3586,7 +3699,7 @@ static void M_DrawCenteredMenu(void) break; default: V_DrawString(BASEVIDWIDTH - x - V_StringWidth(cv->string, 0), y, - ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? warningflags : highlightflags), cv->string); break; } break; @@ -3626,7 +3739,7 @@ static void M_DrawCenteredMenu(void) { V_DrawScaledPatch(x - V_StringWidth(currentMenu->menuitems[itemOn].text, 0)/2 - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); - V_DrawCenteredString(x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); + V_DrawCenteredString(x, cursory, highlightflags, currentMenu->menuitems[itemOn].text); } } @@ -3672,14 +3785,15 @@ static void M_PatchSkinNameTable(void) { skins_cons_t[j].strvalue = NULL; skins_cons_t[j].value = 0; + break; } } - CV_SetValue(&cv_chooseskin, cv_chooseskin.value); // This causes crash sometimes?! + j = R_SkinAvailable(cv_skin.string); + if (j == -1) + j = 0; - CV_SetValue(&cv_chooseskin, 1); - CV_AddValue(&cv_chooseskin, -1); - CV_AddValue(&cv_chooseskin, 1); + CV_SetValue(&cv_chooseskin, j+1); // This causes crash sometimes?! return; } @@ -3713,7 +3827,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt) { case LLM_CREATESERVER: // Should the map be hidden? - if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU) + if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU && mapnum+1 != gamemap) return false; if (M_MapLocked(mapnum+1)) @@ -4106,11 +4220,11 @@ static void M_ConfirmSpectate(INT32 choice) static void M_ConfirmEnterGame(INT32 choice) { (void)choice; - if (!cv_allowteamchange.value) + /*if (!cv_allowteamchange.value) { M_StartMessage(M_GetText("The server is not allowing\nteam changes at this time.\nPress a key.\n"), NULL, MM_NOTHING); return; - } + }*/ M_ClearMenus(true); COM_ImmedExecute("changeteam playing"); } @@ -4160,13 +4274,12 @@ static void M_Options(INT32 choice) { (void)choice; - // if the player is not admin or server, disable server options - OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); + // if the player is not admin or server, disable gameplay & server options + OP_MainMenu[5].status = OP_MainMenu[6].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); - // if the player is playing _at all_, disable the erase data options - OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); - // SRB2Kart: Same with the "Play Credits" option - OP_MainMenu[6].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); + // if the player is playing _at all_, disable the erase data & credits options + OP_MainMenu[7].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); + OP_MainMenu[8].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_MainDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_MainDef); @@ -4307,14 +4420,15 @@ static char *M_GetConditionString(condition_t cond) case UC_EXTRAEMBLEM: return va("Get \"%s\" emblem", extraemblems[cond.requirement-1].name); default: - return ""; + return NULL; } } #define NUMCHECKLIST 23 static void M_DrawChecklist(void) { - INT32 i, line = 0, c, lastid; + UINT32 i, line = 0, c; + INT32 lastid; for (i = 0; i < MAXUNLOCKABLES; i++) { @@ -4323,7 +4437,7 @@ static void M_DrawChecklist(void) continue; ++line; - V_DrawString(8, (line*8), V_RETURN8|(unlockables[i].unlocked ? V_GREENMAP : V_REDMAP), unlockables[i].name); + V_DrawString(8, (line*8), V_RETURN8|(unlockables[i].unlocked ? recommendedflags : warningflags), unlockables[i].name); if (conditionSets[unlockables[i].conditionset - 1].numconditions) { @@ -4341,15 +4455,15 @@ static void M_DrawChecklist(void) ++line; - if (cond.id != lastid) + if (lastid == -1 || cond.id != (UINT32)lastid) { - V_DrawString(16, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), "*"); - V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), str); + V_DrawString(16, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? highlightflags : 0), "*"); + V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? highlightflags : 0), str); } else { - V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), "&"); - V_DrawString(48, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), str); + V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? highlightflags : 0), "&"); + V_DrawString(48, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? highlightflags : 0), str); } lastid = cond.id; @@ -4388,7 +4502,7 @@ static void M_DrawEmblemHints(void) if (emblem->collected) { - collected = V_GREENMAP; + collected = recommendedflags; V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); } @@ -4409,52 +4523,71 @@ static void M_DrawEmblemHints(void) break; } if (!j) - V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map."); + V_DrawCenteredString(160, 48, highlightflags, "No hidden emblems on this map."); M_DrawGenericMenu(); } -static void M_DrawLevelSelectMenu(void) -{ - M_DrawGenericMenu(); - - if (cv_nextmap.value) - { - lumpnum_t lumpnum; - patch_t *PictureOfLevel; - - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); - - if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); - else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - - V_DrawSmallScaledPatch(200, 110, 0, PictureOfLevel); - } -} - static void M_DrawSkyRoom(void) { INT32 i, y = 0; + INT32 lengthstring = 0; M_DrawGenericMenu(); + if (currentMenu == &OP_SoundOptionsDef) + { + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, + currentMenu->y+currentMenu->menuitems[0].alphaKey, + (nosound ? warningflags : highlightflags), + ((nosound || sound_disabled) ? "OFF" : "ON")); + + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, + currentMenu->y+currentMenu->menuitems[2].alphaKey, + (nodigimusic ? warningflags : highlightflags), + ((nodigimusic || digital_disabled) ? "OFF" : "ON")); + + /*V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, + currentMenu->y+currentMenu->menuitems[5].alphaKey, + (nomidimusic ? warningflags : highlightflags), + ((nomidimusic || music_disabled) ? "OFF" : "ON"));*/ + + if (itemOn == 0) + lengthstring = 8*((nosound || sound_disabled) ? 3 : 2); + else if (itemOn == 2) + lengthstring = 8*((nodigimusic || digital_disabled) ? 3 : 2); + /*else if (itemOn == 5) + lengthstring = 8*((nomidimusic || music_disabled) ? 3 : 2);*/ + } + for (i = 0; i < currentMenu->numitems; ++i) { - if (currentMenu->menuitems[i].status == (IT_STRING|IT_KEYHANDLER)) + if (currentMenu->menuitems[i].itemaction == M_HandleSoundTest) { y = currentMenu->menuitems[i].alphaKey; break; } } - if (!y) - return; - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y, V_YELLOWMAP, cv_soundtest.string); - if (cv_soundtest.value) - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y + 8, V_YELLOWMAP, S_sfx[cv_soundtest.value].name); + if (y) + { + y += currentMenu->y; + + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, y, highlightflags, cv_soundtest.string); + if (cv_soundtest.value) + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, y + 8, highlightflags, S_sfx[cv_soundtest.value].name); + + if (i == itemOn) + lengthstring = V_StringWidth(cv_soundtest.string, 0); + } + + if (lengthstring) + { + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x - 10 - lengthstring - (skullAnimCounter/5), currentMenu->y+currentMenu->menuitems[itemOn].alphaKey, + '\x1C' | highlightflags, false); // left arrow + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y+currentMenu->menuitems[itemOn].alphaKey, + '\x1D' | highlightflags, false); // right arrow + } } static void M_HandleSoundTest(INT32 choice) @@ -4701,7 +4834,7 @@ static void M_DrawLoadGameData(void) if (savegameinfo[saveSlotSelected].lives == -666) // savegame is bad { - V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "CORRUPT SAVE FILE"); + V_DrawCenteredString(ecks + 68, 144, warningflags, "CORRUPT SAVE FILE"); V_DrawCenteredString(ecks + 68, 156, 0, "THIS SAVE FILE"); V_DrawCenteredString(ecks + 68, 164, 0, "CAN NOT BE LOADED."); V_DrawCenteredString(ecks + 68, 172, 0, "DELETE USING BACKSPACE."); @@ -4722,11 +4855,11 @@ static void M_DrawLoadGameData(void) #ifdef SAVEGAMES_OTHERVERSIONS if (savegameinfo[saveSlotSelected].gamemap & 16384) - V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "OUTDATED SAVE FILE!"); + V_DrawCenteredString(ecks + 68, 144, warningflags, "OUTDATED SAVE FILE!"); #endif if (savegameinfo[saveSlotSelected].gamemap & 8192) - V_DrawString(ecks + 12, 160, V_GREENMAP, "CLEAR!"); + V_DrawString(ecks + 12, 160, recommendedflags, "CLEAR!"); else V_DrawString(ecks + 12, 160, 0, va("%s", savegameinfo[saveSlotSelected].levelname)); @@ -4782,9 +4915,9 @@ static void M_DrawLoad(void) if (savegameinfo[i%MAXSAVEGAMES].lives == -42) V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_TRANSLUCENT, "NO DATA"); else if (savegameinfo[i%MAXSAVEGAMES].lives == -666) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_REDMAP, "CORRUPT SAVE FILE"); + V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, warningflags, "CORRUPT SAVE FILE"); else if (savegameinfo[i%MAXSAVEGAMES].gamemap & 8192) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_GREENMAP, "CLEAR!"); + V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, recommendedflags, "CLEAR!"); else V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, 0, va("%s", savegameinfo[i%MAXSAVEGAMES].levelname)); @@ -5291,6 +5424,10 @@ static void M_ChoosePlayer(INT32 choice) // STATISTICS MENU // =============== +// =============== +// STATISTICS MENU +// =============== + static INT32 statsLocation; static INT32 statsMax; static INT16 statsMapList[NUMMAPS+1]; @@ -5309,7 +5446,7 @@ static void M_Statistics(INT32 choice) continue; if (!(mapheaderinfo[i]->typeoflevel & TOL_RACE) // TOL_SP - || (mapheaderinfo[i]->menuflags & LF2_HIDEINSTATS)) + || (mapheaderinfo[i]->menuflags & (LF2_HIDEINSTATS|LF2_HIDEINMENU))) continue; if (M_MapLocked(i+1)) // !mapvisited[i] @@ -5318,23 +5455,24 @@ static void M_Statistics(INT32 choice) statsMapList[j++] = i; } statsMapList[j] = -1; - statsMax = j - 13 + numextraemblems; + statsMax = j - 11 + numextraemblems; statsLocation = 0; if (statsMax < 0) statsMax = 0; - M_SetupNextMenu(&SP_GameStatsDef); + M_SetupNextMenu(&SP_LevelStatsDef); } static void M_DrawStatsMaps(int location) { - INT32 y = 76, i = -1; + INT32 y = 80, i = -1; INT16 mnum; extraemblem_t *exemblem; + boolean dotopname = true, dobottomarrow = (location < statsMax); - V_DrawString(20, y-12, 0, "LEVEL NAME"); - V_DrawString(248, y-12, 0, "EMBLEMS"); + if (location) + V_DrawString(10, y-(skullAnimCounter/5), highlightflags, "\x1A"); while (statsMapList[++i] != -1) { @@ -5343,43 +5481,60 @@ static void M_DrawStatsMaps(int location) --location; continue; } + else if (dotopname) + { + V_DrawString(20, y, highlightflags, "LEVEL NAME"); + V_DrawString(248, y, highlightflags, "EMBLEMS"); + y += 8; + dotopname = false; + } mnum = statsMapList[i]; M_DrawMapEmblems(mnum+1, 292, y); - if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) - { - if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) - V_DrawString(20, y, V_YELLOWMAP, va("%s %s %s", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->zonttl, mapheaderinfo[mnum]->actnum)); - else - V_DrawString(20, y, V_YELLOWMAP, va("%s %s", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->zonttl)); - } + if (mapheaderinfo[mnum]->levelflags & LF_NOZONE) + V_DrawString(20, y, 0, va("%s %s", + mapheaderinfo[mnum]->lvlttl, + mapheaderinfo[mnum]->actnum)); else - { - if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) - V_DrawString(20, y, V_YELLOWMAP, va("%s %s", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->actnum)); - else - V_DrawString(20, y, V_YELLOWMAP, mapheaderinfo[mnum]->lvlttl); - } + V_DrawString(20, y, 0, va("%s %s %s", + mapheaderinfo[mnum]->lvlttl, + (mapheaderinfo[mnum]->zonttl[0] ? mapheaderinfo[mnum]->zonttl : "ZONE"), + mapheaderinfo[mnum]->actnum)); y += 8; if (y >= BASEVIDHEIGHT-8) - return; + goto bottomarrow; } + if (dotopname && !location) + { + V_DrawString(20, y, highlightflags, "LEVEL NAME"); + V_DrawString(248, y, highlightflags, "EMBLEMS"); + y += 8; + } + else if (location) + --location; // Extra Emblems for (i = -2; i < numextraemblems; ++i) { + if (i == -1) + { + V_DrawString(20, y, highlightflags, "EXTRA EMBLEMS"); + if (location) + { + y += 8; + location++; + } + } if (location) { --location; continue; } - if (i == -1) - V_DrawString(20, y, V_GREENMAP, "EXTRA EMBLEMS"); - else if (i >= 0) + if (i >= 0) { exemblem = &extraemblems[i]; @@ -5389,23 +5544,64 @@ static void M_DrawStatsMaps(int location) else V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); - V_DrawString(20, y, V_YELLOWMAP, va("%s", exemblem->description)); + V_DrawString(20, y, 0, va("%s", exemblem->description)); } y += 8; if (y >= BASEVIDHEIGHT-8) - return; + goto bottomarrow; } +bottomarrow: + if (dobottomarrow) + V_DrawString(10, y-8 + (skullAnimCounter/5), highlightflags, "\x1B"); } static void M_DrawLevelStats(void) { - M_DrawMenuTitle(); - V_DrawCenteredString(BASEVIDWIDTH/2, 24, V_YELLOWMAP, "PAGE 2 OF 2"); + char beststr[40]; - V_DrawString(72, 48, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawScaledPatch(40, 48-4, 0, W_CachePatchName("EMBLICON", PU_STATIC)); + tic_t besttime = 0; + + INT32 i; + INT32 mapsunfinished = 0; + + M_DrawMenuTitle(); + + V_DrawString(20, 24, highlightflags, "Total Play Time:"); + V_DrawCenteredString(BASEVIDWIDTH/2, 32, 0, va("%i hours, %i minutes, %i seconds", + G_TicsToHours(totalplaytime), + G_TicsToMinutes(totalplaytime, false), + G_TicsToSeconds(totalplaytime))); + V_DrawString(20, 42, highlightflags, "Total Matches:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, 0, va("%i played", matchesplayed)); + + for (i = 0; i < NUMMAPS; i++) + { + if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) + continue; + + if (!mainrecords[i] || mainrecords[i]->time <= 0) + { + mapsunfinished++; + continue; + } + + besttime += mainrecords[i]->time; + } + + V_DrawString(20, 62, highlightflags, "Combined time records:"); + + sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime)); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 62, (mapsunfinished ? warningflags : 0), beststr); + + if (mapsunfinished) + V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, warningflags, va("(%d unfinished)", mapsunfinished)); + else + V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, recommendedflags, "(complete)"); + + V_DrawString(36, 70, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); + V_DrawSmallScaledPatch(20, 70, 0, W_CachePatchName("EMBLICON", PU_STATIC)); M_DrawStatsMaps(statsLocation); } @@ -5429,124 +5625,19 @@ static void M_HandleLevelStats(INT32 choice) --statsLocation; break; - case KEY_RIGHTARROW: + case KEY_PGDN: S_StartSound(NULL, sfx_menu1); - statsLocation += (statsLocation+15 >= statsMax) ? statsMax-statsLocation : 15; + statsLocation += (statsLocation+13 >= statsMax) ? statsMax-statsLocation : 13; break; - case KEY_LEFTARROW: + case KEY_PGUP: S_StartSound(NULL, sfx_menu1); - statsLocation -= (statsLocation < 15) ? statsLocation : 15; + statsLocation -= (statsLocation < 13) ? statsLocation : 13; break; case KEY_ESCAPE: exitmenu = true; break; - - case KEY_ENTER: - S_StartSound(NULL, sfx_menu1); - M_SetupNextMenu(&SP_GameStatsDef); - break; - } - if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } -} - -// Handle GAME statistics. -static void M_DrawGameStats(void) -{ - char beststr[40]; - - tic_t besttime = 0; - //UINT32 bestscore = 0; - //UINT32 bestrings = 0; - - INT32 i; - INT32 mapsunfinished = 0; //INT32 mapsunfinished[3] = {0, 0, 0}; - - M_DrawMenuTitle(); - V_DrawCenteredString(BASEVIDWIDTH/2, 24, V_YELLOWMAP, "PAGE 1 OF 2"); - - V_DrawString(32, 60, V_YELLOWMAP, "Total Play Time:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 70, 0, va("%i hours, %i minutes, %i seconds", - G_TicsToHours(totalplaytime), - G_TicsToMinutes(totalplaytime, false), - G_TicsToSeconds(totalplaytime))); - - V_DrawString(32, 90, V_YELLOWMAP, "Total Matches Played:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 100, 0, va("%i", matchesplayed)); - - for (i = 0; i < NUMMAPS; i++) - { - if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) - continue; - - if (!mainrecords[i]) - { - /*mapsunfinished[0]++; - mapsunfinished[1]++; - mapsunfinished[2]++;*/ - mapsunfinished++; - continue; - } - - /*if (mainrecords[i]->score > 0) - bestscore += mainrecords[i]->score; - else - mapsunfinished[0]++;*/ - - if (mainrecords[i]->time > 0) - besttime += mainrecords[i]->time; - else - mapsunfinished++; //mapsunfinished[1]++; - - /*if (mainrecords[i]->rings > 0) - bestrings += mainrecords[i]->rings; - else - mapsunfinished[2]++;*/ - - } - - V_DrawCenteredString(BASEVIDWIDTH/2, 120, 0, "* COMBINED RECORDS *"); - - /*sprintf(beststr, "%u", bestscore); - V_DrawString(32, 100, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 100, 0, beststr); - if (mapsunfinished[0]) - V_DrawRightAlignedString(BASEVIDWIDTH-32, 108, V_REDMAP, va("(%d unfinished)", mapsunfinished[0]));*/ - - sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime)); - V_DrawString(32, 140, V_YELLOWMAP, "TIME:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 140, 0, beststr); - if (mapsunfinished) - V_DrawRightAlignedString(BASEVIDWIDTH-32, 148, V_REDMAP, va("(%d unfinished)", mapsunfinished)); - - /*sprintf(beststr, "%u", bestrings); - V_DrawString(32, 140, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 140, 0, beststr); - if (mapsunfinished[2]) - V_DrawRightAlignedString(BASEVIDWIDTH-32, 148, V_REDMAP, va("(%d unfinished)", mapsunfinished[2]));*/ -} - -static void M_HandleGameStats(INT32 choice) -{ - boolean exitmenu = false; // exit to previous menu - - switch (choice) - { - case KEY_ESCAPE: - exitmenu = true; - break; - - case KEY_ENTER: - S_StartSound(NULL, sfx_menu1); - M_SetupNextMenu(&SP_LevelStatsDef); - break; } if (exitmenu) { @@ -5566,21 +5657,30 @@ void M_DrawTimeAttackMenu(void) { INT32 i, x, y, cursory = 0; UINT16 dispstatus; - patch_t *PictureOfLevel, *PictureOfUrFace; - lumpnum_t lumpnum; + patch_t *PictureOfUrFace; char beststr[40]; - S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback + //S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); M_DrawMenuTitle(); + if (currentMenu == &SP_TimeAttackDef) + M_DrawLevelSelectOnly(true, false); // draw menu (everything else goes on top of it) // Sadly we can't just use generic mode menus because we need some extra hacks x = currentMenu->x; y = currentMenu->y; + // Character face! + if (W_CheckNumForName(skins[cv_chooseskin.value-1].face) != LUMPERROR) + { + UINT8 *colormap = R_GetTranslationColormap(cv_chooseskin.value-1, cv_playercolor.value, 0); + PictureOfUrFace = W_CachePatchName(skins[cv_chooseskin.value-1].face, PU_CACHE); + V_DrawMappedPatch(BASEVIDWIDTH-x - SHORT(PictureOfUrFace->width), y, 0, PictureOfUrFace, colormap); + } + for (i = 0; i < currentMenu->numitems; ++i) { dispstatus = (currentMenu->menuitems[i].status & IT_DISPLAY); @@ -5591,67 +5691,55 @@ void M_DrawTimeAttackMenu(void) if (i == itemOn) cursory = y; - V_DrawString(x, y, (dispstatus == IT_WHITESTRING) ? V_YELLOWMAP : 0 , currentMenu->menuitems[i].text); + V_DrawString(x, y, (dispstatus == IT_WHITESTRING) ? highlightflags : 0 , currentMenu->menuitems[i].text); // Cvar specific handling if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_CVAR) { consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction; - INT32 soffset = 40; - - // hack to keep the menu from overlapping the player icon - if (currentMenu != &SP_TimeAttackDef) - soffset = 80; - - // Should see nothing but strings - if (cv == &cv_chooseskin) - V_DrawString(BASEVIDWIDTH - x - soffset - V_StringWidth(skins[cv_chooseskin.value-1].realname, 0), y, V_YELLOWMAP, skins[cv_chooseskin.value-1].realname); + if (currentMenu->menuitems[i].status & IT_CV_STRING) + { + M_DrawTextBox(x + 32, y - 8, MAXPLAYERNAME, 1); + V_DrawString(x + 40, y, V_ALLOWLOWERCASE, cv->string); + if (itemOn == i && skullAnimCounter < 4) // blink cursor + V_DrawCharacter(x + 40 + V_StringWidth(cv->string, V_ALLOWLOWERCASE), y, '_',false); + } else - V_DrawString(BASEVIDWIDTH - x - soffset - V_StringWidth(cv->string, 0), y, V_YELLOWMAP, cv->string); + { + const char *str = ((cv == &cv_chooseskin) ? skins[cv_chooseskin.value-1].realname : cv->string); + INT32 soffset = 40, strw = V_StringWidth(str, 0); + + // hack to keep the menu from overlapping the level icon + if (currentMenu != &SP_TimeAttackDef || cv == &cv_nextmap) + soffset = 0; + + // Should see nothing but strings + V_DrawString(BASEVIDWIDTH - x - soffset - strw, y, highlightflags, str); + + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - strw - (skullAnimCounter/5), y, + '\x1C' | highlightflags, false); // left arrow + V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, + '\x1D' | highlightflags, false); // right arrow + } + } } else if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_KEYHANDLER && cv_dummystaff.value) // bad hacky assumption: IT_KEYHANDLER is assumed to be staff ghost selector - { - V_DrawString(BASEVIDWIDTH - x - 80 - V_StringWidth(cv_dummystaff.string, 0), y, V_YELLOWMAP, cv_dummystaff.string); - } + V_DrawString(BASEVIDWIDTH - x - 80 - V_StringWidth(cv_dummystaff.string, 0), y, highlightflags, cv_dummystaff.string); } + x = currentMenu->x; + y = currentMenu->y; + // DRAW THE SKULL CURSOR - V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); - V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); - - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); - - if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); - else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - - V_DrawSmallScaledPatch(208, 32, 0, PictureOfLevel); - - // Character face! - if (W_CheckNumForName(skins[cv_chooseskin.value-1].face) != LUMPERROR) - { - UINT8 *colormap = R_GetTranslationColormap(cv_chooseskin.value-1, cv_playercolor.value, 0); - PictureOfUrFace = W_CachePatchName(skins[cv_chooseskin.value-1].face, PU_CACHE); - V_DrawMappedPatch(256,88,0,PictureOfUrFace, colormap); - } + V_DrawScaledPatch(x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + V_DrawString(x, cursory, highlightflags, currentMenu->menuitems[itemOn].text); // Level record list if (cv_nextmap.value) { emblem_t *em; - INT32 yHeight; - - V_DrawCenteredString(104, 32, 0, "* LEVEL RECORDS *"); - - /*if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->score) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); - - V_DrawString(104-72, 48, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(104+72, 48, V_ALLOWLOWERCASE, beststr);*/ if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) sprintf(beststr, "(none)"); @@ -5660,8 +5748,8 @@ void M_DrawTimeAttackMenu(void) G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); - V_DrawString(104-72, 53, V_YELLOWMAP, "BEST TIME:"); - V_DrawRightAlignedString(104+72, 53, V_ALLOWLOWERCASE, beststr); + V_DrawString(64, y+48, highlightflags, "BEST TIME:"); + V_DrawRightAlignedString(BASEVIDWIDTH - 64 - 24 - 8, y+48, V_ALLOWLOWERCASE, beststr); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->lap) sprintf(beststr, "(none)"); @@ -5670,8 +5758,8 @@ void M_DrawTimeAttackMenu(void) G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->lap), G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->lap)); - V_DrawString(104-72, 63, V_YELLOWMAP, "BEST LAP:"); - V_DrawRightAlignedString(104+72, 63, V_ALLOWLOWERCASE, beststr); + V_DrawString(64, y+56, highlightflags, "BEST LAP:"); + V_DrawRightAlignedString(BASEVIDWIDTH - 64 - 24 - 8, y+56, V_ALLOWLOWERCASE, beststr); // Draw record emblems. em = M_GetLevelEmblems(cv_nextmap.value); @@ -5679,41 +5767,49 @@ void M_DrawTimeAttackMenu(void) { switch (em->type) { - case ET_TIME: yHeight = 53; break; + case ET_TIME: break; default: goto skipThisOne; } if (em->collected) - V_DrawSmallMappedPatch(104+76, yHeight, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), + V_DrawMappedPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else - V_DrawSmallScaledPatch(104+76, yHeight, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawScaledPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName("NEEDIT", PU_CACHE)); skipThisOne: em = M_GetLevelEmblems(-1); } } - // ALWAYS DRAW level name, skin and color even when not on this menu! + // ALWAYS DRAW player name, level name, skin and color even when not on this menu! if (currentMenu != &SP_TimeAttackDef) { consvar_t *ncv; - x = SP_TimeAttackDef.x; - y = SP_TimeAttackDef.y; - - for (i = 0; i < 3; ++i) + for (i = 0; i < 4; ++i) { + y = currentMenu->y+SP_TimeAttackMenu[i].alphaKey; + V_DrawString(x, y, V_TRANSLUCENT, SP_TimeAttackMenu[i].text); ncv = (consvar_t *)SP_TimeAttackMenu[i].itemaction; - - V_DrawString(x, y + SP_TimeAttackMenu[i].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[i].text); - if (ncv == &cv_chooseskin) - V_DrawString(BASEVIDWIDTH - x - 40 - V_StringWidth(skins[cv_chooseskin.value-1].realname, 0), - y + SP_TimeAttackMenu[i].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, skins[cv_chooseskin.value-1].realname); + if (SP_TimeAttackMenu[i].status & IT_CV_STRING) + { + M_DrawTextBox(x + 32, y - 8, MAXPLAYERNAME, 1); + V_DrawString(x + 40, y, V_TRANSLUCENT|V_ALLOWLOWERCASE, ncv->string); + } else - V_DrawString(BASEVIDWIDTH - x - 40 - V_StringWidth(ncv->string, 0), - y + SP_TimeAttackMenu[i].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string); + { + const char *str = ((ncv == &cv_chooseskin) ? skins[cv_chooseskin.value-1].realname : ncv->string); + INT32 soffset = 40, strw = V_StringWidth(str, 0); + + // hack to keep the menu from overlapping the level icon + if (ncv == &cv_nextmap) + soffset = 0; + + // Should see nothing but strings + V_DrawString(BASEVIDWIDTH - x - soffset - strw, y, highlightflags|V_TRANSLUCENT, str); + } } } } @@ -5745,6 +5841,13 @@ static void M_TimeAttack(INT32 choice) S_ChangeMusicInternal("racent", true); } +static boolean M_QuitTimeAttackMenu(void) +{ + // you know what? always putting these in the buffer won't hurt anything. + COM_BufAddText(va("skin \"%s\"\n", cv_chooseskin.string)); + return true; +} + // Drawing function for Nights Attack /*void M_DrawNightsAttackMenu(void) { @@ -5763,7 +5866,7 @@ static void M_TimeAttack(INT32 choice) lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); + PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); else PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); @@ -5787,7 +5890,7 @@ static void M_TimeAttack(INT32 choice) { if (P_HasGrades(cv_nextmap.value, cv_dummymares.value)) { - V_DrawString(160-88, 112, V_YELLOWMAP, "BEST GRADE:"); + V_DrawString(160-88, 112, highlightflags, "BEST GRADE:"); V_DrawSmallScaledPatch(160 + 86 - (ngradeletters[bestgrade]->width/2), 112 + 8 - (ngradeletters[bestgrade]->height/2), 0, ngradeletters[bestgrade]); @@ -5798,7 +5901,7 @@ static void M_TimeAttack(INT32 choice) else sprintf(beststr, "%u", bestscore); - V_DrawString(160 - 88, 122, V_YELLOWMAP, "BEST SCORE:"); + V_DrawString(160 - 88, 122, highlightflags, "BEST SCORE:"); V_DrawRightAlignedString(160 + 88, 122, V_ALLOWLOWERCASE, beststr); if (besttime == UINT32_MAX) @@ -5808,7 +5911,7 @@ static void M_TimeAttack(INT32 choice) G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime)); - V_DrawString(160-88, 132, V_YELLOWMAP, "BEST TIME:"); + V_DrawString(160-88, 132, highlightflags, "BEST TIME:"); V_DrawRightAlignedString(160+88, 132, V_ALLOWLOWERCASE, beststr); if (cv_dummymares.value == 0) { @@ -5845,7 +5948,7 @@ static void M_TimeAttack(INT32 choice) ncv = (consvar_t *)SP_NightsAttackMenu[0].itemaction; V_DrawString(x, y + SP_NightsAttackMenu[0].alphaKey, V_TRANSLUCENT, SP_NightsAttackMenu[0].text); V_DrawString(BASEVIDWIDTH - x - V_StringWidth(ncv->string, 0), - y + SP_NightsAttackMenu[0].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string); + y + SP_NightsAttackMenu[0].alphaKey, highlightflags|V_TRANSLUCENT, ncv->string); } } }*/ @@ -6280,7 +6383,7 @@ static void M_DrawRoomMenu(void) // use generic drawer for cursor, items and title M_DrawGenericMenu(); - V_DrawString(currentMenu->x - 16, currentMenu->y, V_YELLOWMAP, M_GetText("Select a room")); + V_DrawString(currentMenu->x - 16, currentMenu->y, highlightflags, M_GetText("Select a room")); M_DrawTextBox(144, 24, 20, 20); @@ -6308,14 +6411,14 @@ static void M_DrawConnectMenu(void) // Room name if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, - V_YELLOWMAP, (itemOn == mp_connect_room) ? "" : ""); else V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, - V_YELLOWMAP, room_list[menuRoomIndex].name); + highlightflags, room_list[menuRoomIndex].name); // Page num V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_page].alphaKey, - V_YELLOWMAP, va("%u of %d", serverlistpage+1, numPages)); + highlightflags, va("%u of %d", serverlistpage+1, numPages)); // Horizontal line! V_DrawFill(1, currentMenu->y+40, 318, 1, 0); @@ -6327,7 +6430,7 @@ static void M_DrawConnectMenu(void) { INT32 slindex = i + serverlistpage * SERVERS_PER_PAGE; UINT32 globalflags = ((serverlist[slindex].info.numberofplayer >= serverlist[slindex].info.maxplayer) ? V_TRANSLUCENT : 0) - |((itemOn == FIRSTSERVERLINE+i) ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE; + |((itemOn == FIRSTSERVERLINE+i) ? highlightflags : 0)|V_ALLOWLOWERCASE; V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); @@ -6533,13 +6636,16 @@ static void M_ChooseRoom(INT32 choice) // // FindFirstMap // -// Finds the first map of a particular gametype +// Finds the first map of a particular gametype (or returns the current map) // Defaults to 1 if nothing found. // static INT32 M_FindFirstMap(INT32 gtype) { INT32 i; + if (mapheaderinfo[gamemap] && (mapheaderinfo[gamemap]->typeoflevel & gtype)) + return gamemap; + for (i = 0; i < NUMMAPS; i++) { if (mapheaderinfo[i] && (mapheaderinfo[i]->typeoflevel & gtype)) @@ -6553,15 +6659,16 @@ static void M_StartServer(INT32 choice) { UINT8 ssplayers = 0; - if (currentMenu == &MP_SplitServerDef) - ssplayers = 1; - else if (currentMenu == &MP_3PServerDef) - ssplayers = 2; - else if (currentMenu == &MP_4PServerDef) - ssplayers = 3; - (void)choice; - if (ssplayers < 2) + + if (currentMenu == &MP_SplitServerDef) + ssplayers = +#ifdef NOFOURPLAYER + 1; +#else + cv_dummysplitplayers.value-1; +#endif + else netgame = true; multiplayer = true; @@ -6596,44 +6703,185 @@ static void M_StartServer(INT32 choice) M_ClearMenus(true); } -static void M_DrawServerMenu(void) +static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) { lumpnum_t lumpnum; patch_t *PictureOfLevel; + INT32 x, y, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1; + // A 160x100 image of the level as entry MAPxxP + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); + + if (lumpnum != LUMPERROR) + PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); + else + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + + w = SHORT(PictureOfLevel->width)/2; + i = SHORT(PictureOfLevel->height)/2; + x = BASEVIDWIDTH/2 - w/2; + y = currentMenu->y + 130 + 8 - i; + + if (currentMenu->menuitems[itemOn].itemaction == &cv_nextmap && skullAnimCounter < 4) + trans = 120; + else + trans = G_GetGametypeColor(cv_newgametype.value); + + V_DrawFill(x-1, y-1, w+2, i+2, trans); // variable reuse... + + V_DrawSmallScaledPatch(x, y, 0, PictureOfLevel); + /*V_DrawDiag(x, y, 12, 31); + V_DrawDiag(x, y, 10, G_GetGametypeColor(cv_newgametype.value));*/ + + y += i/4; + i = cv_nextmap.value - 1; + trans = (leftfade ? V_TRANSLUCENT : 0); + +#define horizspac 2 + do + { + oldval = i; + do + { + i--; + if (i == -1) + i = NUMMAPS-1; + + if (i == oldval) + return; + + if(!mapheaderinfo[i]) + continue; // Don't allocate the header. That just makes memory usage skyrocket. + + } while (!M_CanShowLevelInList(i, cv_newgametype.value)); + + // A 160x100 image of the level as entry MAPxxP + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(i+1))); + + if (lumpnum != LUMPERROR) + PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); + else + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + + x -= horizspac + SHORT(PictureOfLevel->width)/4; + V_DrawTinyScaledPatch(x, y, trans, PictureOfLevel); + } while (x > horizspac-dupadjust); + + x = (BASEVIDWIDTH + w)/2 + horizspac; + i = cv_nextmap.value - 1; + trans = (rightfade ? V_TRANSLUCENT : 0); + + while (x < BASEVIDWIDTH+dupadjust-horizspac) + { + oldval = i; + do + { + i++; + if (i == NUMMAPS) + i = 0; + + if (i == oldval) + return; + + if(!mapheaderinfo[i]) + continue; // Don't allocate the header. That just makes memory usage skyrocket. + + } while (!M_CanShowLevelInList(i, cv_newgametype.value)); + + // A 160x100 image of the level as entry MAPxxP + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(i+1))); + + if (lumpnum != LUMPERROR) + PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); + else + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + + V_DrawTinyScaledPatch(x, y, trans, PictureOfLevel); + x += horizspac + SHORT(PictureOfLevel->width)/4; + } +#undef horizspac +} + +static void M_DrawServerMenu(void) +{ + M_DrawLevelSelectOnly((currentMenu == &MP_SplitServerDef), false); M_DrawGenericMenu(); #ifndef NONET // Room name if (currentMenu == &MP_ServerDef) { +#define mp_server_room 1 if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, - V_YELLOWMAP, (itemOn == mp_server_room) ? "" : ""); else V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, - V_YELLOWMAP, room_list[menuRoomIndex].name); + highlightflags, room_list[menuRoomIndex].name); +#undef mp_server_room } + else +#endif + if (currentMenu == &MP_SplitServerDef) + // character bar, ripped off the color bar :V + { +#define iconwidth 32 +#define spacingwidth 32 +#define incrwidth (iconwidth + spacingwidth) + UINT8 i = 0, pskin, pcol; + // player arrangement width, but there's also a chance i'm a furry, shhhhhh + const INT32 paw = iconwidth + +#ifndef NOFOURPLAYER + 3* +#endif + incrwidth; + INT32 x = BASEVIDWIDTH/2 - paw/2, y = currentMenu->y + 32, trans = 0; + patch_t *face; + + while (++i <= +#ifdef NOFOURPLAYER + 2 +#else + 4 +#endif + ) + { + switch (i) + { + default: + pskin = R_SkinAvailable(cv_skin.string); + pcol = cv_playercolor.value; + break; + case 2: + pskin = R_SkinAvailable(cv_skin2.string); + pcol = cv_playercolor2.value; + break; + case 3: + pskin = R_SkinAvailable(cv_skin3.string); + pcol = cv_playercolor3.value; + break; + case 4: + pskin = R_SkinAvailable(cv_skin4.string); + pcol = cv_playercolor4.value; + break; + } + + if (pskin >= MAXSKINS) + pskin = 0; + +#ifndef NOFOURPLAYER + if (!trans && i > cv_dummysplitplayers.value) + trans = V_TRANSLUCENT; #endif - // SRB2kart - // A 70x70 image of the level's gametype - /* - if (mapheaderinfo[cv_nextmap.value-1].typeoflevel & TOL_KART) - V_DrawSmallScaledPatch(BASEVIDWIDTH/2,130,0,W_CachePatchName("KART", PU_STATIC)); - else - V_DrawSmallScaledPatch(BASEVIDWIDTH/2,130,0,W_CachePatchName("SONR", PU_STATIC)); - */ - - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); - - if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); - else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - - V_DrawSmallScaledPatch((BASEVIDWIDTH*3/4)-(SHORT(PictureOfLevel->width)/4), ((BASEVIDHEIGHT*3/4)-(SHORT(PictureOfLevel->height)/4)+10), 0, PictureOfLevel); + face = W_CachePatchName(skins[pskin].face, PU_CACHE); + V_DrawFixedPatch(x<x; + INT32 y = currentMenu->y; + // use generic drawer for cursor, items and title M_DrawGenericMenu(); +#if MAXPLAYERS == 16 + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[1].alphaKey, + ((itemOn == 1) ? highlightflags : 0), "(2-16 players)"); +#else +Update the maxplayers label... +#endif + + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[2].alphaKey, + ((itemOn == 2) ? highlightflags : 0), +#ifdef NOFOURPLAYER + "(2 players)" +#else + "(2-4 players)" +#endif + ); + + y += MP_MainMenu[5].alphaKey; + + V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 239); + // draw name string - V_DrawString(128,40, V_MONOSPACE, setupm_ip); + V_DrawString(x+8,y+12, V_MONOSPACE, setupm_ip); // draw text cursor for name - if (itemOn == 0 && - skullAnimCounter < 4) //blink cursor - V_DrawCharacter(128+V_StringWidth(setupm_ip, V_MONOSPACE),40,'_',false); + if (itemOn == 5 + && skullAnimCounter < 4) //blink cursor + V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_MONOSPACE),y+12,'_',false); } // Tails 11-19-2002 @@ -6743,11 +6986,21 @@ static void M_ConnectIP(INT32 choice) // Tails 11-19-2002 static void M_HandleConnectIP(INT32 choice) { - size_t l; - boolean exitmenu = false; // exit to previous menu and send name change + size_t l; + boolean exitmenu = false; // exit to previous menu and send name change switch (choice) { + case KEY_DOWNARROW: + M_NextOpt(); + S_StartSound(NULL,sfx_menu1); // Tails + break; + + case KEY_UPARROW: + M_PrevOpt(); + S_StartSound(NULL,sfx_menu1); // Tails + break; + case KEY_ENTER: S_StartSound(NULL,sfx_menu1); // Tails M_ClearMenus(true); @@ -6759,29 +7012,41 @@ static void M_HandleConnectIP(INT32 choice) break; case KEY_BACKSPACE: - if ((l = strlen(setupm_ip))!=0 && itemOn == 0) + if ((l = strlen(setupm_ip)) != 0) { S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l-1] =0; + setupm_ip[l-1] = 0; + } + break; + + case KEY_DEL: + if (setupm_ip[0]) + { + S_StartSound(NULL,sfx_menu1); // Tails + setupm_ip[0] = 0; } break; default: l = strlen(setupm_ip); - if (l < 16-1 && (choice == 46 || (choice >= 48 && choice <= 57))) // Rudimentary number and period enforcing + if (l >= 16-1) + break; + + if (choice == 46 || (choice >= 48 && choice <= 57)) // Rudimentary number and period enforcing { S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l] =(char)choice; - setupm_ip[l+1] =0; + setupm_ip[l] = (char)choice; + setupm_ip[l+1] = 0; } - else if (l < 16-1 && choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too! + else if (choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too! { - XBOXSTATIC char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'}; + char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'}; choice = keypad_translation[choice - 199]; S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l] =(char)choice; - setupm_ip[l+1] =0; + setupm_ip[l] = (char)choice; + setupm_ip[l+1] = 0; } + break; } @@ -6825,6 +7090,7 @@ static void M_DrawSetupMultiPlayerMenu(void) UINT8 speed; UINT8 weight; UINT8 i; + const UINT8 *flashcol = V_GetStringColormap(highlightflags); mx = MP_PlayerSetupDef.x; my = MP_PlayerSetupDef.y; @@ -6836,21 +7102,37 @@ static void M_DrawSetupMultiPlayerMenu(void) M_DrawTextBox(mx + 32, my - 8, MAXPLAYERNAME, 1); V_DrawString(mx + 40, my, V_ALLOWLOWERCASE, setupm_name); + // draw text cursor for name + if (!itemOn && skullAnimCounter < 4) // blink cursor + V_DrawCharacter(mx + 40 + V_StringWidth(setupm_name, V_ALLOWLOWERCASE), my, '_',false); + // draw skin string - V_DrawString(mx + 80, my + 16, - ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|V_YELLOWMAP|V_ALLOWLOWERCASE, + st = V_StringWidth(skins[setupm_fakeskin].realname, 0); + V_DrawString(BASEVIDWIDTH - mx - st, my + 16, + ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|highlightflags|V_ALLOWLOWERCASE, skins[setupm_fakeskin].realname); + if (itemOn == 1) + { + V_DrawCharacter(BASEVIDWIDTH - mx - 10 - st - (skullAnimCounter/5), my + 16, + '\x1C' | highlightflags, false); // left arrow + V_DrawCharacter(BASEVIDWIDTH - mx + 2 + (skullAnimCounter/5), my + 16, + '\x1D' | highlightflags, false); // right arrow + } // draw the name of the color you have chosen // Just so people don't go thinking that "Default" is Green. - V_DrawString(mx + 48, my + 152, V_YELLOWMAP|V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart - - // draw text cursor for name - if (!itemOn && skullAnimCounter < 4) // blink cursor - V_DrawCharacter(mx + 40 + V_StringWidth(setupm_name, 0), my, '_',false); + st = V_StringWidth(KartColor_Names[setupm_fakecolor], 0); + V_DrawString(BASEVIDWIDTH - mx - st, my + 152, highlightflags|V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart + if (itemOn == 2) + { + V_DrawCharacter(BASEVIDWIDTH - mx - 10 - st - (skullAnimCounter/5), my + 152, + '\x1C' | highlightflags, false); // left arrow + V_DrawCharacter(BASEVIDWIDTH - mx + 2 + (skullAnimCounter/5), my + 152, + '\x1D' | highlightflags, false); // right arrow + } // SRB2Kart: draw the stat backer - V_DrawFixedPatch((mx+141)<= MAXSKINCOLORS) col -= MAXSKINCOLORS-1; x += w; @@ -6891,6 +7186,7 @@ static void M_DrawSetupMultiPlayerMenu(void) #undef indexwidth // character bar, ripped off the color bar :V + if (setupm_fakecolor) // inverse should never happen #define iconwidth 32 { const INT32 icons = 4; @@ -6959,45 +7255,23 @@ static void M_DrawSetupMultiPlayerMenu(void) flags |= V_FLIP; // This sprite is left/right flipped! // draw box around guy - V_DrawFill((mx+42)-(charw/2), my+66, charw, 84, 239); - - if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats - statdot = W_CachePatchName("K_SDOT2", PU_CACHE); - else - statdot = W_CachePatchName("K_SDOT1", PU_CACHE); - - speed = skins[setupm_fakeskin].kartspeed; - weight = skins[setupm_fakeskin].kartweight; + V_DrawFill(mx + 43 - (charw/2), my+65, charw, 84, 239); // draw player sprite - if (!setupm_fakecolor) // should never happen but hey, who knows - { - if (skins[setupm_fakeskin].flags & SF_HIRES) - { - V_DrawSciencePatch((mx+42)<lastOn = itemOn; // Unhide P1-only controls - OP_MoveControlsMenu[9].status = IT_CALL|IT_STRING2; // Talk - OP_MoveControlsMenu[10].status = IT_CALL|IT_STRING2; // Team talk - OP_MoveControlsMenu[11].status = IT_CALL|IT_STRING2; // Rankings - OP_MoveControlsMenu[12].status = IT_CALL|IT_STRING2; // Pause - OP_MoveControlsMenu[13].status = IT_CALL|IT_STRING2; // Console + OP_MoveControlsMenu[10].status = IT_CONTROL; // Talk + //OP_MoveControlsMenu[11].status = IT_CONTROL; // Team-talk + OP_MoveControlsMenu[11].status = IT_CONTROL; // Rankings + OP_MoveControlsMenu[12].status = IT_CONTROL; // Pause + OP_MoveControlsMenu[13].status = IT_CONTROL; // Console + OP_MoveControlsMenu[14].itemaction = &OP_Joystick1Def; // Gamepad + + // Set cvars + OP_SpectateControlsMenu[6].itemaction = &cv_chasecam; // Chasecam + OP_SpectateControlsMenu[7].itemaction = &cv_crosshair; // Crosshair - OP_MoveControlsDef.prevMenu = &OP_P1ControlsDef; M_SetupNextMenu(&OP_MoveControlsDef); } @@ -7408,19 +7706,22 @@ static void M_Setup2PControlsMenu(INT32 choice) { (void)choice; setupcontrols_secondaryplayer = true; - setupcontrols_thirdplayer = false; - setupcontrols_fourthplayer = false; + setupcontrols_thirdplayer = setupcontrols_fourthplayer = false; setupcontrols = gamecontrolbis; currentMenu->lastOn = itemOn; // Hide P1-only controls - OP_MoveControlsMenu[9].status = IT_GRAYEDOUT2; // Talk - OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; // Team talk + OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; // Talk + //OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; // Team-talk OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; // Rankings OP_MoveControlsMenu[12].status = IT_GRAYEDOUT2; // Pause OP_MoveControlsMenu[13].status = IT_GRAYEDOUT2; // Console + OP_MoveControlsMenu[14].itemaction = &OP_Joystick2Def; // Gamepad + + // Set cvars + OP_SpectateControlsMenu[6].itemaction = &cv_chasecam2; // Chasecam + OP_SpectateControlsMenu[7].itemaction = &cv_crosshair2; // Crosshair - OP_MoveControlsDef.prevMenu = &OP_P2ControlsDef; M_SetupNextMenu(&OP_MoveControlsDef); } @@ -7429,19 +7730,22 @@ static void M_Setup3PControlsMenu(INT32 choice) { (void)choice; setupcontrols_thirdplayer = true; - setupcontrols_secondaryplayer = false; - setupcontrols_fourthplayer = false; + setupcontrols_secondaryplayer = setupcontrols_fourthplayer = false; setupcontrols = gamecontrol3; currentMenu->lastOn = itemOn; // Hide P1-only controls - OP_MoveControlsMenu[9].status = IT_GRAYEDOUT2; // Talk - OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; // Team talk + OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; // Talk + //OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; // Team-talk OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; // Rankings OP_MoveControlsMenu[12].status = IT_GRAYEDOUT2; // Pause OP_MoveControlsMenu[13].status = IT_GRAYEDOUT2; // Console + OP_MoveControlsMenu[14].itemaction = &OP_Joystick3Def; // Gamepad + + // Set cvars + OP_SpectateControlsMenu[6].itemaction = &cv_chasecam3; // Chasecam + OP_SpectateControlsMenu[7].itemaction = &cv_crosshair3; // Crosshair - OP_MoveControlsDef.prevMenu = &OP_P3ControlsDef; M_SetupNextMenu(&OP_MoveControlsDef); } @@ -7449,19 +7753,22 @@ static void M_Setup4PControlsMenu(INT32 choice) { (void)choice; setupcontrols_fourthplayer = true; - setupcontrols_secondaryplayer = false; - setupcontrols_thirdplayer = false; + setupcontrols_secondaryplayer = setupcontrols_thirdplayer = false; setupcontrols = gamecontrol4; currentMenu->lastOn = itemOn; // Hide P1-only controls - OP_MoveControlsMenu[9].status = IT_GRAYEDOUT2; // Talk - OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; // Team talk + OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; // Talk + //OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; // Team-talk OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; // Rankings OP_MoveControlsMenu[12].status = IT_GRAYEDOUT2; // Pause OP_MoveControlsMenu[13].status = IT_GRAYEDOUT2; // Console + OP_MoveControlsMenu[14].itemaction = &OP_Joystick4Def; // Gamepad + + // Set cvars + OP_SpectateControlsMenu[6].itemaction = &cv_chasecam4; // Chasecam + OP_SpectateControlsMenu[7].itemaction = &cv_crosshair4; // Crosshair - OP_MoveControlsDef.prevMenu = &OP_P4ControlsDef; M_SetupNextMenu(&OP_MoveControlsDef); } #endif @@ -7470,7 +7777,7 @@ static void M_Setup4PControlsMenu(INT32 choice) static void M_DrawControl(void) { char tmp[50]; - INT32 i; + INT32 i, y; INT32 keys[2]; const char *ctrl; @@ -7478,18 +7785,25 @@ static void M_DrawControl(void) M_DrawGenericMenu(); if (setupcontrols_secondaryplayer) - ctrl = "SET CONTROLS FOR SECONDARY PLAYER"; + ctrl = "\x86""SET ""\x82""CONTROLS""\x86"" FOR ""\x82""SECONDARY PLAYER"; else if (setupcontrols_thirdplayer) - ctrl = "SET CONTROLS FOR THIRD PLAYER"; + ctrl = "\x86""SET ""\x82""CONTROLS""\x86"" FOR ""\x82""THIRD PLAYER"; else if (setupcontrols_fourthplayer) - ctrl = "SET CONTROLS FOR FOURTH PLAYER"; + ctrl = "\x86""SET ""\x82""CONTROLS""\x86"" FOR ""\x82""FOURTH PLAYER"; else - ctrl = "PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR"; + ctrl = "\x86""PRESS ""\x82""ENTER""\x86"" TO CHANGE, ""\x82""BACKSPACE""\x86"" TO CLEAR"; - M_CentreText(30, ctrl); + M_CentreText(28, ctrl); - for (i = 0;i < currentMenu->numitems;i++) + y = currentMenu->y; + + for (i = 0; i < currentMenu->numitems;i++) { + if (currentMenu->menuitems[i].status != IT_CONTROL) + { + y = currentMenu->y+currentMenu->menuitems[i].alphaKey; + continue; + } if (currentMenu->menuitems[i].status != IT_CONTROL) continue; @@ -7514,7 +7828,8 @@ static void M_DrawControl(void) } - V_DrawRightAlignedString(BASEVIDWIDTH-currentMenu->x, currentMenu->y + i*8, V_YELLOWMAP, tmp); + V_DrawRightAlignedString(BASEVIDWIDTH-currentMenu->x, y, highlightflags, tmp); + y += SMALLLINEHEIGHT; } } @@ -7614,85 +7929,189 @@ static void M_ChangeControl(INT32 choice) // ===== // Toggles sound systems in-game. -static void M_ToggleSFX(void) +static void M_ToggleSFX(INT32 choice) { + switch (choice) + { + case KEY_DOWNARROW: + S_StartSound(NULL, sfx_menu1); + itemOn++; + return; + + case KEY_UPARROW: + S_StartSound(NULL, sfx_menu1); + itemOn = currentMenu->numitems-1; + return; + + case KEY_ESCAPE: + currentMenu->lastOn = itemOn; + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ClearMenus(true); + return; + default: + break; + } + if (nosound) { nosound = false; I_StartupSound(); if (nosound) return; - S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); + S_Init(cv_soundvolume.value, cv_digmusicvolume.value);//, cv_midimusicvolume.value); + S_StartSound(NULL, sfx_strpst); + //M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); } else { if (sound_disabled) { sound_disabled = false; - M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); + S_StartSound(NULL, sfx_strpst); + //M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); } else { sound_disabled = true; S_StopSounds(); - M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING); + //M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING); } } } -static void M_ToggleDigital(void) +static void M_ToggleDigital(INT32 choice) { + switch (choice) + { + case KEY_DOWNARROW: + S_StartSound(NULL, sfx_menu1); + itemOn++; + return; + + case KEY_UPARROW: + S_StartSound(NULL, sfx_menu1); + itemOn--; + return; + + case KEY_ESCAPE: + currentMenu->lastOn = itemOn; + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ClearMenus(true); + return; + default: + break; + } + if (nodigimusic) { nodigimusic = false; I_InitDigMusic(); if (nodigimusic) return; - S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); + S_Init(cv_soundvolume.value, cv_digmusicvolume.value);//, cv_midimusicvolume.value); S_StopMusic(); - S_ChangeMusicInternal("lclear", false); - M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("titles", looptitle); + //M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); } else { if (digital_disabled) { digital_disabled = false; - M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("titles", looptitle); + //M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); } else { digital_disabled = true; S_StopMusic(); - M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING); + //M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING); } } } -static void M_ToggleMIDI(void) +/*static void M_ToggleMIDI(INT32 choice) { + switch (choice) + { + case KEY_DOWNARROW: + S_StartSound(NULL, sfx_menu1); + itemOn++; + return; + + case KEY_UPARROW: + S_StartSound(NULL, sfx_menu1); + itemOn--; + return; + + case KEY_ESCAPE: + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ClearMenus(true); + return; + default: + break; + } + if (nomidimusic) { nomidimusic = false; I_InitMIDIMusic(); if (nomidimusic) return; S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - S_ChangeMusicInternal("lclear", false); - M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("_clear", false); + //M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); } else { if (music_disabled) { music_disabled = false; - M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("_clear", false); + //M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); } else { music_disabled = true; S_StopMusic(); - M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING); + //M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING); } } +}*/ + +static void M_RestartAudio(void) +{ + S_StopMusic(); + I_ShutdownMusic(); + I_ShutdownSound(); + I_StartupSound(); + I_InitMusic(); + + I_SetSfxVolume(cv_soundvolume.value); + I_SetDigMusicVolume(cv_digmusicvolume.value); + //I_SetMIDIMusicVolume(cv_midimusicvolume.value); + + S_StartSound(NULL, sfx_strpst); + + if (Playing()) // Gotta make sure the player is in a level + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("titles", looptitle); } // =============== @@ -7785,6 +8204,15 @@ static void M_VideoModeMenu(INT32 choice) M_SetupNextMenu(&OP_VideoModeDef); } +static void M_DrawVideoMenu(void) +{ + + M_DrawGenericMenu(); + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + OP_VideoOptionsMenu[0].alphaKey, + (SCR_IsAspectCorrect(vid.width, vid.height) ? recommendedflags : highlightflags), + va("%dx%d", vid.width, vid.height)); +} + // Draw the video modes list, a-la-Quake static void M_DrawVideoMode(void) { @@ -7794,17 +8222,17 @@ static void M_DrawVideoMode(void) M_DrawMenuTitle(); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y, - V_YELLOWMAP, "Choose mode, reselect to change default"); + highlightflags, "Choose mode, reselect to change default"); row = 41; col = OP_VideoModeDef.y + 14; for (i = 0; i < vidm_nummodes; i++) { if (i == vidm_selected) - V_DrawString(row, col, V_YELLOWMAP, modedescs[i].desc); + V_DrawString(row, col, highlightflags, modedescs[i].desc); // Show multiples of 320x200 as green. else - V_DrawString(row, col, (modedescs[i].goodratio) ? V_GREENMAP : 0, modedescs[i].desc); + V_DrawString(row, col, (modedescs[i].goodratio) ? recommendedflags : 0, modedescs[i].desc); col += 8; if ((i % vidm_column_size) == (vidm_column_size-1)) @@ -7842,11 +8270,11 @@ static void M_DrawVideoMode(void) cv_scr_width.value, cv_scr_height.value)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138, - V_GREENMAP, "Green modes are recommended."); - V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 150, - V_YELLOWMAP, "Other modes may have visual errors."); + recommendedflags, "Marked modes are recommended."); + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 146, + highlightflags, "Other modes may have visual errors."); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 158, - V_YELLOWMAP, "Use at own risk."); + highlightflags, "Larger modes may have performance issues."); } // Draw the cursor for the VidMode menu @@ -7930,6 +8358,26 @@ static void M_HandleVideoMode(INT32 ch) } } +static void M_DrawHUDOptions(void) +{ + const char *str0 = ")"; + const char *str1 = " Warning highlight"; + const char *str2 = ","; + const char *str3 = "Good highlight"; + INT32 x = BASEVIDWIDTH - currentMenu->x + 2, y = currentMenu->y + 120; + INT32 w0 = V_StringWidth(str0, 0), w1 = V_StringWidth(str1, 0), w2 = V_StringWidth(str2, 0), w3 = V_StringWidth(str3, 0); + M_DrawGenericMenu(); + x -= w0; + V_DrawString(x, y, highlightflags, str0); + x -= w1; + V_DrawString(x, y, warningflags, str1); + x -= w2; + V_DrawString(x, y, highlightflags, str2); + x -= w3; + V_DrawString(x, y, recommendedflags, str3); + V_DrawRightAlignedString(x, y, highlightflags, "("); +} + // =============== // Monitor Toggles // =============== @@ -7957,16 +8405,16 @@ static void M_HandleVideoMode(INT32 ch) cv = (consvar_t *)currentMenu->menuitems[i].itemaction; y = currentMenu->y + currentMenu->menuitems[i].alphaKey; - M_DrawSlider(currentMenu->x + 20, y, cv); + M_DrawSlider(currentMenu->x + 20, y, cv, (i == itemOn)); if (!cv->value) - V_DrawRightAlignedString(312, y, V_OLDSPACING|((i == itemOn) ? V_YELLOWMAP : 0), "None"); + V_DrawRightAlignedString(312, y, V_OLDSPACING|((i == itemOn) ? highlightflags : 0), "None"); else - V_DrawRightAlignedString(312, y, V_OLDSPACING|((i == itemOn) ? V_YELLOWMAP : 0), va("%3d%%", (cv->value*100)/sum)); + V_DrawRightAlignedString(312, y, V_OLDSPACING|((i == itemOn) ? highlightflags : 0), va("%3d%%", (cv->value*100)/sum)); } if (cheating) - V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y, V_REDMAP, "* MODIFIED, CHEATS ENABLED *"); + V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y, warningflags, "* MODIFIED, CHEATS ENABLED *"); }*/ // ========= @@ -8041,7 +8489,7 @@ static void M_OGL_DrawFogMenu(void) my = currentMenu->y; M_DrawGenericMenu(); // use generic drawer for cursor, items and title V_DrawString(BASEVIDWIDTH - mx - V_StringWidth(cv_grfogcolor.string, 0), - my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, V_YELLOWMAP, cv_grfogcolor.string); + my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, highlightflags, cv_grfogcolor.string); // blink cursor on FOG_COLOR_ITEM if selected if (itemOn == FOG_COLOR_ITEM && skullAnimCounter < 4) V_DrawCharacter(BASEVIDWIDTH - mx, @@ -8059,7 +8507,7 @@ static void M_OGL_DrawColorMenu(void) my = currentMenu->y; M_DrawGenericMenu(); // use generic drawer for cursor, items and title V_DrawString(mx, my + currentMenu->menuitems[0].alphaKey - 10, - V_YELLOWMAP, "Gamma correction"); + highlightflags, "Gamma correction"); } //=================== diff --git a/src/m_menu.h b/src/m_menu.h index 4d6e2fac..51559489 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -267,7 +267,7 @@ void Screenshot_option_Onchange(void); prev,\ source,\ M_DrawServerMenu,\ - 27,40,\ + 24,40,\ 0,\ NULL\ } @@ -279,7 +279,7 @@ void Screenshot_option_Onchange(void); prev,\ source,\ M_DrawControl,\ - 24, 40,\ + 26, 40,\ 0,\ NULL\ } diff --git a/src/m_misc.c b/src/m_misc.c index 5727067c..766db72d 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -56,7 +56,9 @@ typedef off_t off64_t; #endif #endif -#if defined (_WIN32) +#if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3)) +#define PRIdS "u" +#elif defined (_WIN32) #define PRIdS "Iu" #elif defined (_PSP) || defined (_arch_dreamcast) || defined (DJGPP) || defined (_WII) || defined (_NDS) || defined (_PS3) #define PRIdS "u" diff --git a/src/p_enemy.c b/src/p_enemy.c index b8486683..a9333777 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -187,9 +187,11 @@ void A_RandomStateRange(mobj_t *actor); void A_DualAction(mobj_t *actor); void A_RemoteAction(mobj_t *actor); void A_ToggleFlameJet(mobj_t *actor); -void A_ItemPop(mobj_t *actor); // SRB2kart -void A_RedShellChase(mobj_t *actor); // SRB2kart -void A_BobombExplode(mobj_t *actor); // SRB2kart +void A_ItemPop(mobj_t *actor); // SRB2kart +void A_JawzChase(mobj_t *actor); // SRB2kart +void A_JawzExplode(mobj_t *actor); // SRB2kart +void A_MineExplode(mobj_t *actor); // SRB2kart +void A_BallhogExplode(mobj_t *actor); // SRB2kart void A_OrbitNights(mobj_t *actor); void A_GhostMe(mobj_t *actor); void A_SetObjectState(mobj_t *actor); @@ -849,7 +851,7 @@ void A_Look(mobj_t *actor) if (!P_LookForPlayers(actor, locvar1 & 65535, false , FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale))) return; - if (leveltime < 4*TICRATE) // SRB2kart - no looking before race starts + if (leveltime < starttime) // SRB2kart - no looking before race starts return; // go into chase state @@ -2549,7 +2551,7 @@ void A_MonitorPop(mobj_t *actor) mobj_t *remains; mobjtype_t explode; mobjtype_t item = 0; - mobjtype_t newbox; + //mobjtype_t newbox; #ifdef HAVE_BLUA if (LUA_CallAction("A_MonitorPop", actor)) @@ -2601,7 +2603,7 @@ void A_MonitorPop(mobj_t *actor) switch (actor->type) { - case MT_QUESTIONBOX: // Random! + /*case MT_QUESTIONBOX: // Random! { mobjtype_t spawnchance[256]; INT32 numchoices = 0, i = 0; @@ -2635,7 +2637,7 @@ for (i = cvar.value; i; --i) spawnchance[numchoices++] = type remains->flags2 &= ~MF2_AMBUSH; break; - } + }*/ default: item = actor->info->damage; break; @@ -3238,8 +3240,10 @@ void A_WaterShield(mobj_t *actor) P_SpawnShieldOrb(player); } + /* // SRB2kart - Can't drown. if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1) P_RestoreMusic(player); + */ player->powers[pw_underwater] = 0; @@ -3825,7 +3829,7 @@ void A_ThrownRing(mobj_t *actor) P_SetTarget(&actor->tracer, NULL); } - if (actor->tracer && (actor->tracer->health)) // SRB2kart - red shells always follow + if (actor->tracer && (actor->tracer->health)) // SRB2kart - jawz always follow //&& (actor->tracer->player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)// Already found someone to follow. { const INT32 temp = actor->threshold; @@ -3877,7 +3881,7 @@ void A_ThrownRing(mobj_t *actor) && actor->target->player->ctfteam == player->ctfteam) continue; - if (actor->target->player->kartstuff[k_position] < player->kartstuff[k_position]) // SRB2kart - Red Shells only go after people ahead of you + if (actor->target->player->kartstuff[k_position] < player->kartstuff[k_position]) // SRB2kart - Jawz only go after people ahead of you continue; } @@ -3920,8 +3924,8 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing) if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner. return true; - if (thing->player && (thing->player->kartstuff[k_bootimer] - || (G_BattleGametype() && thing->player && thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebacktimer]))) + if (thing->player && (thing->player->kartstuff[k_hyudorotimer] + || (G_BattleGametype() && thing->player && thing->player->kartstuff[k_bumper] <= 0 && thing->player->kartstuff[k_comebacktimer]))) return true; if ((gametype == GT_CTF || gametype == GT_TEAMMATCH) @@ -3990,15 +3994,19 @@ void A_SetSolidSteam(mobj_t *actor) #endif actor->flags &= ~MF_NOCLIP; actor->flags |= MF_SOLID; - if (P_RandomChance(FRACUNIT/8)) + + if (!(actor->flags2 & MF2_AMBUSH)) // Don't be so obnoxious. { - if (actor->info->deathsound) - S_StartSound(actor, actor->info->deathsound); // Hiss! - } - else - { - if (actor->info->painsound) - S_StartSound(actor, actor->info->painsound); + if (P_RandomChance(FRACUNIT/8)) + { + if (actor->info->deathsound) + S_StartSound(actor, actor->info->deathsound); // Hiss! + } + else + { + if (actor->info->painsound) + S_StartSound(actor, actor->info->painsound); + } } P_SetObjectMomZ (actor, 1, true); @@ -4042,8 +4050,8 @@ void A_SignPlayer(mobj_t *actor) return; // Set the sign to be an appropriate background color for this player's skincolor. - actor->color = Color_Opposite[actor->target->player->skincolor*2]; - actor->frame += Color_Opposite[actor->target->player->skincolor*2+1]; + actor->color = KartColor_Opposite[actor->target->player->skincolor*2]; + actor->frame += KartColor_Opposite[actor->target->player->skincolor*2+1]; // spawn an overlay of the player's face. ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); @@ -8085,7 +8093,7 @@ void A_ToggleFlameJet(mobj_t* actor) } } -//{ SRB2kart - A_ItemPop, A_RedShellChase and A_BobombExplode +//{ SRB2kart - A_ItemPop, A_JawzChase, A_JawzExplode, A_MineExplode, and A_BallhogExplode void A_ItemPop(mobj_t *actor) { mobj_t *remains; @@ -8143,7 +8151,7 @@ void A_ItemPop(mobj_t *actor) if (actor->info->deathsound) S_StartSound(remains, actor->info->deathsound); - if (!(G_BattleGametype() && actor->target->player->kartstuff[k_balloon] <= 0)) + if (!(G_BattleGametype() && actor->target->player->kartstuff[k_bumper] <= 0)) actor->target->player->kartstuff[k_itemroulette] = 1; remains->flags2 &= ~MF2_AMBUSH; @@ -8154,14 +8162,14 @@ void A_ItemPop(mobj_t *actor) P_RemoveMobj(actor); } -void A_RedShellChase(mobj_t *actor) +void A_JawzChase(mobj_t *actor) { INT32 c = 0; INT32 stop; player_t *player; #ifdef HAVE_BLUA - if (LUA_CallAction("A_RedShellChase", actor)) + if (LUA_CallAction("A_JawzChase", actor)) return; #endif @@ -8221,13 +8229,13 @@ void A_RedShellChase(mobj_t *actor) if (G_RaceGametype()) // Only in races, in match and CTF you should go after any nearby players { // USER TARGET - if (actor->target->player->kartstuff[k_position] != (player->kartstuff[k_position] + 1)) // Red Shells only go after the person directly ahead of you -Sryder + if (actor->target->player->kartstuff[k_position] != (player->kartstuff[k_position] + 1)) // Jawz only go after the person directly ahead of you -Sryder continue; } if (G_BattleGametype()) { - if (player->kartstuff[k_balloon] <= 0) + if (player->kartstuff[k_bumper] <= 0) continue; if (P_AproxDistance(P_AproxDistance(player->mo->x-actor->x, @@ -8239,7 +8247,7 @@ void A_RedShellChase(mobj_t *actor) if ((G_RaceGametype()) || (G_BattleGametype() // If in match etc. only home in when you get close enough, in race etc. home in all the time && P_AproxDistance(P_AproxDistance(player->mo->x-actor->x, player->mo->y-actor->y), player->mo->z-actor->z) < RING_DIST - && player->kartstuff[k_balloon] > 0)) + && player->kartstuff[k_bumper] > 0)) P_SetTarget(&actor->tracer, player->mo); return; @@ -8258,7 +8266,45 @@ void A_RedShellChase(mobj_t *actor) } -void A_BobombExplode(mobj_t *actor) +void A_JawzExplode(mobj_t *actor) +{ + INT32 shrapnel = 2; + mobj_t *truc; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_JawzExplode", actor)) + return; +#endif + + truc = P_SpawnMobj(actor->x, actor->y, actor->z, MT_BOOMEXPLODE); + truc->scale = actor->scale*2; + truc->color = SKINCOLOR_RED; + + while (shrapnel) + { + INT32 speed, speed2; + + truc = P_SpawnMobj(actor->x + P_RandomRange(-8, 8)*FRACUNIT, actor->y + P_RandomRange(-8, 8)*FRACUNIT, + actor->z + P_RandomRange(0, 8)*FRACUNIT, MT_BOOMPARTICLE); + truc->scale = actor->scale*2; + + speed = FixedMul(7*FRACUNIT, actor->scale)>>FRACBITS; + truc->momx = P_RandomRange(-speed, speed)*FRACUNIT; + truc->momy = P_RandomRange(-speed, speed)*FRACUNIT; + + speed = FixedMul(5*FRACUNIT, actor->scale)>>FRACBITS; + speed2 = FixedMul(15*FRACUNIT, actor->scale)>>FRACBITS; + truc->momz = P_RandomRange(speed, speed2)*FRACUNIT; + truc->tics = TICRATE*2; + truc->color = SKINCOLOR_RED; + + shrapnel--; + } + + return; +} + +void A_MineExplode(mobj_t *actor) { mobj_t *mo2; thinker_t *th; @@ -8266,7 +8312,7 @@ void A_BobombExplode(mobj_t *actor) INT32 locvar1 = var1; mobjtype_t type; #ifdef HAVE_BLUA - if (LUA_CallAction("A_BobombExplode", actor)) + if (LUA_CallAction("A_MineExplode", actor)) return; #endif @@ -8282,10 +8328,10 @@ void A_BobombExplode(mobj_t *actor) mo2 = (mobj_t *)th; - if (mo2 == actor || mo2->type == MT_BOMBEXPLOSIONSOUND) // Don't explode yourself! Endless loop! + if (mo2 == actor || mo2->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop! continue; - if (G_BattleGametype() && actor->target && actor->target->player && actor->target->player->kartstuff[k_balloon] <= 0 && mo2 == actor->target) + if (G_BattleGametype() && actor->target && actor->target->player && actor->target->player->kartstuff[k_bumper] <= 0 && mo2 == actor->target) continue; if (P_AproxDistance(P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > actor->info->painchance) @@ -8308,14 +8354,29 @@ void A_BobombExplode(mobj_t *actor) K_SpawnKartExplosion(actor->x, actor->y, actor->z, actor->info->painchance + 32*FRACUNIT, 32, type, d*(ANGLE_45/4), true, false, actor->target); // 32 <-> 64 if (actor->target && actor->target->player) - K_SpawnBobombExplosion(actor, actor->target->player->skincolor); + K_SpawnMineExplosion(actor, actor->target->player->skincolor); else - K_SpawnBobombExplosion(actor, SKINCOLOR_RED); + K_SpawnMineExplosion(actor, SKINCOLOR_RED); - P_SpawnMobj(actor->x, actor->y, actor->z, MT_BOMBEXPLOSIONSOUND); + P_SpawnMobj(actor->x, actor->y, actor->z, MT_MINEEXPLOSIONSOUND); return; } + +void A_BallhogExplode(mobj_t *actor) +{ + mobj_t *mo2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_BallhogExplode", actor)) + return; +#endif + + mo2 = P_SpawnMobj(actor->x, actor->y, actor->z, MT_BALLHOGBOOM); + P_SetScale(mo2, actor->scale*2); + mo2->destscale = mo2->scale; + S_StartSound(mo2, actor->info->deathsound); + return; +} //} // Function: A_OrbitNights diff --git a/src/p_floor.c b/src/p_floor.c index d143f6e9..ac8e60dc 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -237,7 +237,7 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus { case MT_GOOP: // Egg Slimer's goop objects case MT_SPINFIRE: // Elemental Shield flame balls - case MT_MUSHROOMTRAIL: + case MT_SNEAKERTRAIL: case MT_SPIKE: // Floor Spike // Is the object hang from the ceiling? // In that case, swap the planes used. diff --git a/src/p_inter.c b/src/p_inter.c index 6099e585..6ca5e6c2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -152,25 +152,21 @@ void P_ResetStarposts(void) // boolean P_CanPickupItem(player_t *player, boolean weapon) { - /*if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) // No balloons in Match + if (player->exiting || mapreset) + return false; + + /*if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) // No bumpers in Match return false;*/ if (weapon) { - if (player->kartstuff[k_bootaketimer] || player->kartstuff[k_boostolentimer] - || player->kartstuff[k_growshrinktimer] > 1 || player->kartstuff[k_goldshroomtimer]) // Item-specific timer going off + if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] + || player->kartstuff[k_growshrinktimer] != 0 || player->kartstuff[k_rocketsneakertimer]) // Item-specific timer going off return false; if (player->kartstuff[k_itemroulette] - || player->kartstuff[k_greenshell] || player->kartstuff[k_triplegreenshell] - || player->kartstuff[k_redshell] || player->kartstuff[k_tripleredshell] - || player->kartstuff[k_banana] || player->kartstuff[k_triplebanana] - || player->kartstuff[k_fakeitem] & 2 || player->kartstuff[k_magnet] - || player->kartstuff[k_bobomb] || player->kartstuff[k_blueshell] - || player->kartstuff[k_mushroom] || player->kartstuff[k_fireflower] - || player->kartstuff[k_star] || player->kartstuff[k_goldshroom] - || player->kartstuff[k_lightning] || player->kartstuff[k_megashroom] - || player->kartstuff[k_boo] || player->kartstuff[k_feather] & 1) // Item slot already taken up + || player->kartstuff[k_itemamount] + || player->kartstuff[k_itemheld]) // Item slot already taken up return false; } @@ -414,7 +410,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_CanPickupItem(player, true)) return; - if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) + if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) { if (player->kartstuff[k_comebackmode] == 1 || player->kartstuff[k_comebacktimer]) return; @@ -426,6 +422,67 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetTarget(&special->target, toucher); P_KillMobj(special, toucher, toucher); break; + case MT_KARMAHITBOX: + if (!special->target->player) + return; + if (player == special->target->player) + return; + if (player->kartstuff[k_bumper] <= 0) + return; + if (special->target->player->exiting || player->exiting) + return; + + if (special->target->player->kartstuff[k_comebacktimer] + || special->target->player->kartstuff[k_spinouttimer] + || special->target->player->kartstuff[k_squishedtimer]) + return; + + if (special->target->player->kartstuff[k_comebackmode] == 0) + { + if (player->kartstuff[k_growshrinktimer] || player->kartstuff[k_squishedtimer] + || player->kartstuff[k_hyudorotimer] || player->kartstuff[k_spinouttimer] + || player->kartstuff[k_invincibilitytimer] || player->powers[pw_flashing]) + return; + else + { + mobj_t *boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); + boom->scale = special->target->scale; + boom->destscale = special->target->scale; + boom->momz = 5*FRACUNIT; + if (special->target->color) + boom->color = special->target->color; + else + boom->color = SKINCOLOR_RED; + S_StartSound(boom, special->info->attacksound); + + special->target->player->kartstuff[k_comebackpoints] += 2 * (K_IsPlayerWanted(player) ? 2 : 1); + if (netgame && cv_hazardlog.value) + CONS_Printf(M_GetText("%s bombed %s!\n"), player_names[special->target->player-players], player_names[player-players]); + if (special->target->player->kartstuff[k_comebackpoints] >= 3) + K_StealBumper(special->target->player, player, true); + special->target->player->kartstuff[k_comebacktimer] = comebacktime; + + K_ExplodePlayer(player, special->target); + } + } + else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, true)) + { + mobj_t *poof = P_SpawnMobj(tmthing->x, tmthing->y, tmthing->z, MT_EXPLODE); + S_StartSound(poof, special->info->seesound); + + special->target->player->kartstuff[k_comebackmode] = 0; + special->target->player->kartstuff[k_comebackpoints]++; + + if (netgame && cv_hazardlog.value) + CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[special->target->player-players], player_names[player-players]); + if (special->target->player->kartstuff[k_comebackpoints] >= 3) + K_StealBumper(special->target->player, player, true); + special->target->player->kartstuff[k_comebacktimer] = comebacktime; + + player->kartstuff[k_itemroulette] = 1; + player->kartstuff[k_roulettetype] = 1; + } + return; // ***************************************** // // Rings, coins, spheres, weapon panels, etc // // ***************************************** // @@ -1490,12 +1547,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) || special->z > toucher->z + (toucher->height*2/3)) return; // Only go in the mouth + /* // SRB2kart - Can't drown. // Eaten by player! if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1) P_RestoreMusic(player); if (player->powers[pw_underwater] < underwatertics + 1) player->powers[pw_underwater] = underwatertics + 1; + */ /* if (!player->climbing) @@ -1612,7 +1671,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour str = M_GetText("%s%s's tagging hand %s %s.\n"); break; case MT_SPINFIRE: - case MT_MUSHROOMTRAIL: + case MT_SNEAKERTRAIL: str = M_GetText("%s%s's elemental fire trail %s %s.\n"); break; case MT_THROWNBOUNCE: @@ -1749,7 +1808,7 @@ void P_CheckTimeLimit(void) if (G_RaceGametype()) return; - if (leveltime < timelimitintics) + if (leveltime < (timelimitintics + starttime)) return; if (gameaction == ga_completed) @@ -1771,9 +1830,6 @@ void P_CheckTimeLimit(void) P_AddPlayerScore(&players[i], players[i].score); } } - - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); } //Optional tie-breaker for Match/CTF @@ -1787,6 +1843,8 @@ void P_CheckTimeLimit(void) //Figure out if we have enough participating players to care. for (i = 0; i < MAXPLAYERS; i++) { + if (players[i].exiting) + return; if (playeringame[i] && players[i].spectator) spectators++; } @@ -1815,7 +1873,7 @@ void P_CheckTimeLimit(void) { for (k = i; k < playercount; k++) { - if (players[playerarray[i-1]].score < players[playerarray[k]].score) + if (players[playerarray[i-1]].marescore < players[playerarray[k]].marescore) { tempplayer = playerarray[i-1]; playerarray[i-1] = playerarray[k]; @@ -1825,7 +1883,7 @@ void P_CheckTimeLimit(void) } //End the round if the top players aren't tied. - if (players[playerarray[0]].score == players[playerarray[1]].score) + if (players[playerarray[0]].marescore == players[playerarray[1]].marescore) return; } else @@ -1835,12 +1893,19 @@ void P_CheckTimeLimit(void) return; } } - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); } - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + if (players[i].exiting) + return; + P_DoPlayerExit(&players[i]); + } + + /*if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0);*/ } /** Checks if a player's score is over the pointlimit and the round should end. @@ -1863,7 +1928,7 @@ void P_CheckPointLimit(void) return; // pointlimit is nonzero, check if it's been reached by this player - if (G_GametypeHasTeams()) + /*if (G_GametypeHasTeams()) { // Just check both teams if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore) @@ -1872,18 +1937,27 @@ void P_CheckPointLimit(void) SendNetXCmd(XD_EXITLEVEL, NULL, 0); } } - else + else*/ { for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) continue; - if ((UINT32)cv_pointlimit.value <= players[i].score) + if ((UINT32)cv_pointlimit.value <= players[i].marescore) { - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); - return; + for (i = 0; i < MAXPLAYERS; i++) // AAAAA nested loop using the same iteration variable ;; + { + if (!playeringame[i] || players[i].spectator) + continue; + if (players[i].exiting) + return; + P_DoPlayerExit(&players[i]); + } + + /*if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0);*/ + return; // good thing we're leaving the function immediately instead of letting the loop get mangled! } } } @@ -1977,13 +2051,15 @@ void P_CheckSurvivors(void) // Checks whether or not to end a race netgame. boolean P_CheckRacers(void) { - INT32 i; + INT32 i, j, numplayersingame = 0; // Check if all the players in the race have finished. If so, end the level. for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator && !players[i].exiting && players[i].lives > 0) - break; + if (!playeringame[i] || players[i].spectator || players[i].exiting || !players[i].lives) + continue; + + break; } if (i == MAXPLAYERS) // finished @@ -1992,6 +2068,35 @@ boolean P_CheckRacers(void) return true; } + if (cv_karteliminatelast.value) + { + for (j = 0; j < MAXPLAYERS; j++) + { + if (!playeringame[j] || players[j].spectator) + continue; + numplayersingame++; + } + + if (numplayersingame > 1) // if there's more than one player in-game, this is safe to do + { + // check if we just got unlucky and there was only one guy who was a problem + for (j = i+1; j < MAXPLAYERS; j++) + { + if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives) + continue; + + break; + } + + if (j == MAXPLAYERS) // finish anyways, force a time over + { + P_DoTimeOver(&players[i]); + countdown = countdown2 = 0; + return true; + } + } + } + return false; } @@ -2011,43 +2116,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) //if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) // P_SetTarget(&target->tracer, inflictor); - // SRB2kart - // I wish I knew a better way to do this - if (target->target && target->target->player && target->target->player->mo) - { - if (target->type == MT_GREENSHIELD && target->target->player->kartstuff[k_greenshell] & 1) - target->target->player->kartstuff[k_greenshell] &= ~1; - else if (target->type == MT_REDSHIELD && target->target->player->kartstuff[k_redshell] & 1) - target->target->player->kartstuff[k_redshell] &= ~1; - else if (target->type == MT_BANANASHIELD && target->target->player->kartstuff[k_banana] & 1) - target->target->player->kartstuff[k_banana] &= ~1; - else if (target->type == MT_FAKESHIELD && target->target->player->kartstuff[k_fakeitem] & 1) - target->target->player->kartstuff[k_fakeitem] &= ~1; - else if (target->type == MT_BOMBSHIELD && target->target->player->kartstuff[k_bobomb] & 1) - target->target->player->kartstuff[k_bobomb] &= ~1; - else if (target->type == MT_TRIPLEGREENSHIELD1 && target->target->player->kartstuff[k_triplegreenshell] & 1) - target->target->player->kartstuff[k_triplegreenshell] &= ~1; - else if (target->type == MT_TRIPLEGREENSHIELD2 && target->target->player->kartstuff[k_triplegreenshell] & 2) - target->target->player->kartstuff[k_triplegreenshell] &= ~2; - else if (target->type == MT_TRIPLEGREENSHIELD3 && target->target->player->kartstuff[k_triplegreenshell] & 4) - target->target->player->kartstuff[k_triplegreenshell] &= ~4; - else if (target->type == MT_TRIPLEREDSHIELD1 && target->target->player->kartstuff[k_tripleredshell] & 1) - target->target->player->kartstuff[k_tripleredshell] &= ~1; - else if (target->type == MT_TRIPLEREDSHIELD2 && target->target->player->kartstuff[k_tripleredshell] & 2) - target->target->player->kartstuff[k_tripleredshell] &= ~2; - else if (target->type == MT_TRIPLEREDSHIELD3 && target->target->player->kartstuff[k_tripleredshell] & 4) - target->target->player->kartstuff[k_tripleredshell] &= ~4; - else if (target->type == MT_TRIPLEBANANASHIELD1 && target->target->player->kartstuff[k_triplebanana] & 1) - target->target->player->kartstuff[k_triplebanana] &= ~1; - else if (target->type == MT_TRIPLEBANANASHIELD2 && target->target->player->kartstuff[k_triplebanana] & 2) - target->target->player->kartstuff[k_triplebanana] &= ~2; - else if (target->type == MT_TRIPLEBANANASHIELD3 && target->target->player->kartstuff[k_triplebanana] & 4) - target->target->player->kartstuff[k_triplebanana] &= ~4; - /*else if (target->type == MT_BATTLEBALLOON && target->target->player->kartstuff[k_balloon] > target->threshold-1) - target->target->player->kartstuff[k_balloon] = target->threshold-1;*/ - } - // - if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6) sstimer = 6; // Just let P_Ticker take care of the rest. @@ -2056,14 +2124,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) // SRB2kart if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR) - && !(target->type == MT_GREENITEM || target->type == MT_GREENSHIELD - || target->type == MT_TRIPLEGREENSHIELD1 || target->type == MT_TRIPLEGREENSHIELD2 || target->type == MT_TRIPLEGREENSHIELD3 - || target->type == MT_REDITEM || target->type == MT_REDITEMDUD || target->type == MT_REDSHIELD - || target->type == MT_TRIPLEREDSHIELD1 || target->type == MT_TRIPLEREDSHIELD2 || target->type == MT_TRIPLEREDSHIELD3 - || target->type == MT_BANANAITEM || target->type == MT_BANANASHIELD - || target->type == MT_TRIPLEBANANASHIELD1 || target->type == MT_TRIPLEBANANASHIELD2 || target->type == MT_TRIPLEBANANASHIELD3 + && !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD + || target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD + || target->type == MT_BANANA || target->type == MT_BANANA_SHIELD || target->type == MT_FAKEITEM || target->type == MT_FAKESHIELD - || target->type == MT_FIREBALL)) // kart dead items + || target->type == MT_BALLHOG)) // kart dead items target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000 else target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields @@ -2082,6 +2147,46 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) return; #endif + // SRB2kart + // I wish I knew a better way to do this + if (target->target && target->target->player && target->target->player->mo) + { + if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_FAKESHIELD) + target->target->player->kartstuff[k_eggmanheld] = 0; + + if (target->target->player->kartstuff[k_itemheld]) + { + if ((target->type == MT_BANANA_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_BANANA) // trail items + || (target->type == MT_SSMINE_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_MINE)) + { + if (target->lastlook != 0 && target->lastlook < target->target->player->kartstuff[k_itemamount]) + { + if (target->target->hnext) + K_KillBananaChain(target->target->hnext, inflictor, source); + target->target->player->kartstuff[k_itemamount] = 0; + } + else + target->target->player->kartstuff[k_itemamount]--; + } + else if ((target->type == MT_ORBINAUT_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) // orbit items + || (target->type == MT_JAWZ_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_JAWZ)) + { + target->target->player->kartstuff[k_itemamount]--; + if (target->lastlook != 0) + { + K_RepairOrbitChain(target); + } + } + + if (target->target->player->kartstuff[k_itemamount] < 0) + target->target->player->kartstuff[k_itemamount] = 0; + + if (!target->target->player->kartstuff[k_itemamount]) + target->target->player->kartstuff[k_itemheld] = 0; + } + } + // + // Let EVERYONE know what happened to a player! 01-29-2002 Tails if (target->player && !target->player->spectator) { @@ -2197,7 +2302,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) { target->flags &= ~(MF_SOLID|MF_SHOOTABLE); // does not block P_UnsetThingPosition(target); - target->flags |= MF_NOBLOCKMAP; + target->flags |= MF_NOBLOCKMAP|MF_NOCLIPHEIGHT; P_SetThingPosition(target); if (!target->player->bot && !G_IsSpecialStage(gamemap) @@ -2272,9 +2377,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) } } else if (G_BattleGametype()) - { - K_CheckBalloons(); - } + K_CheckBumpers(); + + target->player->kartstuff[k_pogospring] = 0; } if (source && target && target->player && source->player) @@ -2773,14 +2878,22 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) if (G_BattleGametype()) { - if (player->kartstuff[k_balloon] > 0) + if (player->kartstuff[k_bumper] > 0) { - if (player->kartstuff[k_balloon] == 1) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); - player->kartstuff[k_balloon]--; + if (player->kartstuff[k_bumper] == 1) + { + mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! + P_SetTarget(&karmahitbox->target, player->mo); + karmahitbox->destscale = player->mo->scale; + P_SetScale(karmahitbox, player->mo->scale); + CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + } + player->kartstuff[k_bumper]--; + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); } - K_CheckBalloons(); + K_CheckBumpers(); } } @@ -2907,6 +3020,8 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) { + //const UINT8 scoremultiply = ((K_IsWantedPlayer(player) && !trapitem) : 2 ? 1); + if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) { P_DoPlayerPain(player, source, inflictor); @@ -2917,11 +3032,11 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN S_StartSound(player->mo, sfx_spkdth); } - if (source && source->player && !player->powers[pw_super]) //don't score points against super players + /*if (source && source->player && !player->powers[pw_super]) //don't score points against super players { // Award no points when players shoot each other when cv_friendlyfire is on. if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 1); + P_AddPlayerScore(source->player, scoremultiply); } if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) @@ -2931,9 +3046,9 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN { // Award no points when players shoot each other when cv_friendlyfire is on. if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 1); + P_AddPlayerScore(source->player, scoremultiply); } - } + }*/ // Ring loss sound plays despite hitting spikes P_PlayRinglossSound(player->mo); // Ringledingle! @@ -2964,7 +3079,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da #else static const boolean force = false; #endif - mobj_t *blueexplode; if (objectplacing) return false; @@ -3124,42 +3238,57 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da //{ SRB2kart - special damage sources - player->kartstuff[k_mushroomtimer] = 0; - - // Thunder + // Shrink if (damage == 64) { if (player == source->player) return false; // Don't flip out while super! - if (!player->kartstuff[k_startimer] && player->kartstuff[k_growshrinktimer] <= 0) + if (!player->kartstuff[k_invincibilitytimer] && player->kartstuff[k_growshrinktimer] <= 0) { - // Start slipping! - K_SpinPlayer(player, source); - // Start shrinking! + player->mo->scalespeed = FRACUNIT/TICRATE; player->mo->destscale = 6*(mapheaderinfo[gamemap-1]->mobj_scale)/8; - player->kartstuff[k_growshrinktimer] -= (100+20*(16-(player->kartstuff[k_position]))); + if (cv_kartdebugshrink.value && !player->bot) + player->mo->destscale = 6*player->mo->destscale/8; + + // Wipeout + K_SpinPlayer(player, source, 1, false); + damage = player->mo->health - 1; + P_RingDamage(player, inflictor, source, damage); + P_PlayerRingBurst(player, 5); + player->mo->momx = player->mo->momy = 0; + if (P_IsLocalPlayer(player)) + { + quake.intensity = 32*FRACUNIT; + quake.time = 5; + } + + K_StripItems(player); + player->kartstuff[k_growshrinktimer] -= (200+(40*(16-player->kartstuff[k_position]))); } - // Mega Mushroom? Let's take that away. + // Grow? Let's take that away. if (player->kartstuff[k_growshrinktimer] > 0) { player->kartstuff[k_growshrinktimer] = 2; } + player->kartstuff[k_sneakertimer] = 0; // Invincible or not, we still need this. - P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_LIGHTNING); + //P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_LIGHTNING); + S_StartSound(player->mo, sfx_kc59); return true; } - // Blue Thunder + // Self-Propelled Bomb if (damage == 65) { + mobj_t *spbexplode; if (player == source->player) return false; // Just need to do this now! Being thrown upwards is done by the explosion. - P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUELIGHTNING); - blueexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); - P_SetTarget(&blueexplode->target, source); + //P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUELIGHTNING); + spbexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); + P_SetTarget(&spbexplode->target, source); return true; } //} @@ -3185,23 +3314,25 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Instant-Death if (damage == 10000) P_KillPlayer(player, source, damage); - else if (player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing]) + else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing]) + { + K_DoInstashield(player); return false; + } else { - if (inflictor && (inflictor->type == MT_GREENITEM || inflictor->type == MT_GREENSHIELD - || inflictor->type == MT_REDITEM || inflictor->type == MT_REDSHIELD || inflictor->type == MT_REDITEMDUD + if (inflictor && (inflictor->type == MT_ORBINAUT || inflictor->type == MT_ORBINAUT_SHIELD + || inflictor->type == MT_JAWZ || inflictor->type == MT_JAWZ_SHIELD || inflictor->type == MT_JAWZ_DUD || inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD - || inflictor->type == MT_TRIPLEGREENSHIELD1 || inflictor->type == MT_TRIPLEGREENSHIELD2 || inflictor->type == MT_TRIPLEGREENSHIELD3 - || inflictor->type == MT_TRIPLEREDSHIELD1 || inflictor->type == MT_TRIPLEREDSHIELD2 || inflictor->type == MT_TRIPLEREDSHIELD3 || inflictor->player)) { - player->kartstuff[k_spinouttype] = 1; - K_SpinPlayer(player, source); + player->kartstuff[k_sneakertimer] = 0; + K_SpinPlayer(player, source, 1, (inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD)); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); P_PlayerRingBurst(player, 5); - player->mo->momx = player->mo->momy = 0; + if (inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD) + player->mo->momx = player->mo->momy = 0; if (P_IsLocalPlayer(player)) { quake.intensity = 32*FRACUNIT; @@ -3210,8 +3341,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else { - player->kartstuff[k_spinouttype] = -1; - K_SpinPlayer(player, source); + K_SpinPlayer(player, source, 0, false); } return true; } @@ -3362,22 +3492,25 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da break; } - target->reactiontime = 0; // we're awake now... - - if (source && source != target) + if (!P_MobjWasRemoved(target)) { - // if not intent on another player, - // chase after this one - P_SetTarget(&target->target, source); - if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) + target->reactiontime = 0; // we're awake now... + + if (source && source != target) { - if (player) + // if not intent on another player, + // chase after this one + P_SetTarget(&target->target, source); + if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); + if (player) + { + if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) + P_SetPlayerMobjState(target, target->info->seestate); + } + else + P_SetMobjState(target, target->info->seestate); } - else - P_SetMobjState(target, target->info->seestate); } } diff --git a/src/p_local.h b/src/p_local.h index 8a4bfa7b..3bf98bee 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -25,7 +25,7 @@ #define FLOATSPEED (FRACUNIT*4) -#define VIEWHEIGHTS "41" +//#define VIEWHEIGHTS "41" // Maximum player score. #define MAXSCORE 999999990 @@ -150,6 +150,7 @@ boolean P_InQuicksand(mobj_t *mo); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); +boolean P_EndingMusic(player_t *player); void P_SpawnShieldOrb(player_t *player); mobj_t *P_SpawnGhostMobj(mobj_t *mobj); void P_GivePlayerRings(player_t *player, INT32 num_rings); @@ -167,6 +168,7 @@ void P_ElementalFireTrail(player_t *player); void P_PlayerThink(player_t *player); void P_PlayerAfterThink(player_t *player); void P_DoPlayerExit(player_t *player); +void P_DoTimeOver(player_t *player); void P_NightserizePlayer(player_t *player, INT32 ptime); void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move); @@ -177,12 +179,13 @@ void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); boolean P_LookForEnemies(player_t *player); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user -boolean P_SuperReady(player_t *player); +//boolean P_SuperReady(player_t *player); void P_DoJump(player_t *player, boolean soundandstate); boolean P_AnalogMove(player_t *player); boolean P_TransferToNextMare(player_t *player); UINT8 P_FindLowestMare(void); UINT8 P_FindLowestLap(void); +UINT8 P_FindHighestLap(void); void P_FindEmerald(void); void P_TransferToAxis(player_t *player, INT32 axisnum); boolean P_PlayerMoving(INT32 pnum); @@ -191,9 +194,9 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type); void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range); void P_PlayLivesJingle(player_t *player); -#define P_PlayRinglossSound(s) S_StartSound(s, (mariomode) ? sfx_mario8 : sfx_altow1 + P_RandomKey(4)); -#define P_PlayDeathSound(s) S_StartSound(s, sfx_altdi1 + P_RandomKey(4)); -#define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); +void P_PlayRinglossSound(mobj_t *source); +void P_PlayDeathSound(mobj_t *source); +void P_PlayVictorySound(mobj_t *source); // @@ -209,7 +212,7 @@ void P_PlayLivesJingle(player_t *player); extern mapthing_t *itemrespawnque[ITEMQUESIZE]; extern tic_t itemrespawntime[ITEMQUESIZE]; extern size_t iquehead, iquetail; -extern consvar_t cv_gravity, cv_viewheight; +extern consvar_t cv_gravity/*, cv_viewheight*/; void P_RespawnSpecials(void); @@ -338,6 +341,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); void P_SlideMove(mobj_t *mo, boolean forceslide); +void P_BouncePlayerMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); boolean P_CheckSight(mobj_t *t1, mobj_t *t2); void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius); diff --git a/src/p_map.c b/src/p_map.c index ece49f26..52ab6154 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -116,6 +116,7 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) boolean P_DoSpring(mobj_t *spring, mobj_t *object) { //INT32 pflags; + const fixed_t scale = mapheaderinfo[gamemap-1]->mobj_scale + abs(object->scale - mapheaderinfo[gamemap-1]->mobj_scale); //max(mapheaderinfo[gamemap-1]->mobj_scale, object->scale) fixed_t offx, offy; fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; @@ -178,12 +179,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } if (vertispeed) - object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(object->scale, spring->scale))); + object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(scale, spring->scale))); if (horizspeed) { if (!object->player) - P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(object->scale, spring->scale)))); + P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(scale, spring->scale)))); else { fixed_t finalSpeed = horizspeed; @@ -192,7 +193,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (pSpeed > finalSpeed) finalSpeed = pSpeed; - P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed,FixedSqrt(FixedMul(object->scale, spring->scale)))); + P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed,FixedSqrt(FixedMul(scale, spring->scale)))); } } @@ -308,7 +309,17 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (spring->state != &states[S_STEAM1]) // Only when it bursts break; - object->momz = flipval*FixedMul(speed, FixedSqrt(FixedMul(spring->scale, object->scale))); // scale the speed with both objects' scales, just like with springs! + if (spring->spawnpoint && spring->spawnpoint->options & MTF_OBJECTSPECIAL) + { + if (object->eflags & MFE_SPRUNG) + break; + if (object->player) + object->player->kartstuff[k_pogospring] = 1; + K_DoPogoSpring(object, 0, true); + return; + } + else + object->momz = flipval*FixedMul(speed, FixedSqrt(FixedMul(spring->scale, object->scale))); // scale the speed with both objects' scales, just like with springs! /* // SRB2kart - don't need state change if (p) @@ -655,10 +666,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->type == MT_RANDOMITEM) return true; - if (tmthing->type == MT_GREENITEM || tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD || - tmthing->type == MT_GREENSHIELD || tmthing->type == MT_REDSHIELD || - tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3 || - tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3) + if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD + || tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD) { // see if it went over / under if (tmthing->z > thing->z + thing->height) @@ -672,23 +681,22 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->health <= 0 || thing->health <= 0) return true; - if (((tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3 - || tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3) - && (thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 - || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3)) + if ((tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD) && tmthing->lastlook + && (thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD) && thing->lastlook && (tmthing->target == thing->target)) // Don't hit each other if you have the same target return true; if (thing->player && thing->player->powers[pw_flashing] - && !(tmthing->type == MT_GREENITEM || tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD)) + && !(tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD)) return true; if (thing->type == MT_PLAYER) { // Player Damage P_DamageMobj(thing, tmthing, tmthing->target, 1); + K_KartBouncing(thing, tmthing, false, false); - if (tmthing->type == MT_GREENITEM || tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD) + if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD) S_StartSound(thing, sfx_shelit); // This Item Damage @@ -703,13 +711,10 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); } - else if (thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD - || thing->type == MT_GREENSHIELD || thing->type == MT_REDSHIELD - || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 - || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 - || thing->type == MT_BANANAITEM || thing->type == MT_BANANASHIELD - || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 - || thing->type == MT_FIREBALL) + else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD + || thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD + || thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD + || thing->type == MT_BALLHOG) { // Other Item Damage if (thing->eflags & MFE_VERTICALFLIP) @@ -739,9 +744,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } else if (thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD) { - if (tmthing->type == MT_GREENSHIELD || tmthing->type == MT_REDSHIELD - || tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3 - || tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3) + if (tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD) { // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -770,7 +773,7 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetObjectMomZ(thing, 8*FRACUNIT, false); P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); } - else if (thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM) + else if (thing->type == MT_SSMINE_SHIELD || thing->type == MT_SSMINE) { // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -787,12 +790,12 @@ static boolean PIT_CheckThing(mobj_t *thing) // Bomb death P_KillMobj(thing, tmthing, tmthing); } - else if (thing->flags & MF_SPRING && (tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD || tmthing->type == MT_GREENITEM)) + else if (thing->flags & MF_SPRING && (tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD || tmthing->type == MT_ORBINAUT)) P_DoSpring(thing, tmthing); return true; } - else if (tmthing->flags & MF_SPRING && (thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD || thing->type == MT_GREENITEM)) + else if (tmthing->flags & MF_SPRING && (thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD || thing->type == MT_ORBINAUT)) { // see if it went over / under if (tmthing->z > thing->z + thing->height) @@ -834,7 +837,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - else if (tmthing->type == MT_BOMBEXPLOSION) + else if (tmthing->type == MT_MINEEXPLOSION) { // see if it went over / under if (tmthing->z > thing->z + thing->height) @@ -850,17 +853,16 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_PLAYER && thing->player) { - if (tmthing->state == &states[S_BOMBEXPLOSION1]) + if (tmthing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(thing->player, tmthing->target); else - K_SpinPlayer(thing->player, tmthing->target); + K_SpinPlayer(thing->player, tmthing->target, 0, false); } return true; // This doesn't collide with anything, but we want it to effect the player anyway. } - else if (tmthing->type == MT_BANANASHIELD || tmthing->type == MT_BANANAITEM - || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3 - || tmthing->type == MT_FIREBALL) + else if (tmthing->type == MT_BANANA_SHIELD || tmthing->type == MT_BANANA + || tmthing->type == MT_BALLHOG) { // see if it went over / under if (tmthing->z > thing->z + thing->height) @@ -874,13 +876,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->health <= 0 || thing->health <= 0) return true; - if (((tmthing->type == MT_BANANASHIELD || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3) - && (thing->type == MT_BANANASHIELD || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3)) + if (((tmthing->type == MT_BANANA_SHIELD) && (thing->type == MT_BANANA_SHIELD)) && (tmthing->target == thing->target)) // Don't hit each other if you have the same target return true; - if (tmthing->type == MT_FIREBALL && thing->type == MT_FIREBALL) - return true; // Fireballs don't collide with eachother + if (tmthing->type == MT_BALLHOG && thing->type == MT_BALLHOG) + return true; // Ballhogs don't collide with eachother if (thing->player && thing->player->powers[pw_flashing]) return true; @@ -888,7 +889,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_PLAYER) { // Player Damage - K_SpinPlayer(thing->player, tmthing->target); + K_SpinPlayer(thing->player, tmthing->target, 0, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD)); // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -902,12 +903,10 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); } - else if (thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM - || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 - || thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD - || thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 - || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 - || thing->type == MT_FIREBALL) + else if (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD + || thing->type == MT_ORBINAUT || thing->type == MT_ORBINAUT_SHIELD + || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD || thing->type == MT_JAWZ_SHIELD + || thing->type == MT_BALLHOG) { // Other Item Damage if (thing->eflags & MFE_VERTICALFLIP) @@ -937,7 +936,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } else if (thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD) { - if (tmthing->type == MT_BANANASHIELD || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3) + if (tmthing->type == MT_BANANA_SHIELD) { // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -985,10 +984,10 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player && thing->player->powers[pw_flashing]) return true; - if (thing->type == MT_GREENITEM // When these items collide with the fake item, just the fake item is destroyed - || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD - || thing->type == MT_BOMBITEM - || thing->type == MT_BANANAITEM || thing->type == MT_FIREBALL) + if (thing->type == MT_ORBINAUT // When these items collide with the fake item, just the fake item is destroyed + || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD + || thing->type == MT_SSMINE + || thing->type == MT_BANANA || thing->type == MT_BALLHOG) { // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -1002,10 +1001,10 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); } - else if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 // When these items collide with the fake item, both of them are destroyed - || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 - || thing->type == MT_BOMBSHIELD - || thing->type == MT_BANANASHIELD || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 + else if (thing->type == MT_ORBINAUT_SHIELD // When these items collide with the fake item, both of them are destroyed + || thing->type == MT_JAWZ_SHIELD + || thing->type == MT_SSMINE_SHIELD + || thing->type == MT_BANANA_SHIELD || thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD) { // Other Item Damage @@ -1054,7 +1053,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - else if (tmthing->type == MT_BOMBSHIELD || tmthing->type == MT_BOMBITEM) + else if (tmthing->type == MT_SSMINE_SHIELD || tmthing->type == MT_SSMINE) { // see if it went over / under if (tmthing->z > thing->z + thing->height) @@ -1075,9 +1074,8 @@ static boolean PIT_CheckThing(mobj_t *thing) { P_KillMobj(tmthing, thing, thing); } - else if (thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD - || thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 - || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3) + else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD + || thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD) { P_KillMobj(tmthing, thing, thing); @@ -1097,16 +1095,13 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } else if (tmthing->type == MT_PLAYER && - (thing->type == MT_GREENSHIELD || thing->type == MT_GREENITEM - || thing->type == MT_REDSHIELD || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD - || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 - || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 + (thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_ORBINAUT + || thing->type == MT_JAWZ_SHIELD || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD || thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM - || thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM - || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 - || thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM - || thing->type == MT_BOMBEXPLOSION - || thing->type == MT_SINK || thing->type == MT_FIREBALL + || thing->type == MT_BANANA_SHIELD || thing->type == MT_BANANA + || thing->type == MT_SSMINE_SHIELD || thing->type == MT_SSMINE + || thing->type == MT_MINEEXPLOSION + || thing->type == MT_SINK || thing->type == MT_BALLHOG )) { // see if it went over / under @@ -1116,12 +1111,11 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // underneath if (tmthing->player && tmthing->player->powers[pw_flashing] - && !(thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD)) + && !(thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD)) return true; - if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 - || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 - || thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD + if (thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD + || thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD || thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM) { if ((thing->target == tmthing) && (thing->threshold > 0)) @@ -1133,7 +1127,10 @@ static boolean PIT_CheckThing(mobj_t *thing) // Player Damage P_DamageMobj(tmthing, thing, thing->target, 1); - if (thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD) + if (thing->type != MT_FAKESHIELD && thing->type != MT_FAKEITEM) + K_KartBouncing(tmthing, thing, false, false); + + if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD) S_StartSound(tmthing, sfx_shelit); // Other Item Damage @@ -1148,9 +1145,8 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetObjectMomZ(thing, 8*FRACUNIT, false); P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); } - else if (thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM - || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 - || thing->type == MT_FIREBALL) + else if (thing->type == MT_BANANA_SHIELD || thing->type == MT_BANANA + || thing->type == MT_BALLHOG) { if ((thing->target == tmthing) && (thing->threshold > 0)) return true; @@ -1159,7 +1155,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // Player Damage - K_SpinPlayer(tmthing->player, thing->target); + K_SpinPlayer(tmthing->player, thing->target, 0, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD)); // Other Item Damage if (thing->eflags & MFE_VERTICALFLIP) @@ -1173,7 +1169,7 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetObjectMomZ(thing, 8*FRACUNIT, false); P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); } - else if (thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM) + else if (thing->type == MT_SSMINE_SHIELD || thing->type == MT_SSMINE) { if ((thing->target == tmthing) && (thing->threshold > 0)) return true; @@ -1183,13 +1179,13 @@ static boolean PIT_CheckThing(mobj_t *thing) P_KillMobj(thing, tmthing, tmthing); } - else if (thing->type == MT_BOMBEXPLOSION && tmthing->player) + else if (thing->type == MT_MINEEXPLOSION && tmthing->player) { // Player Damage - if (thing->state == &states[S_BOMBEXPLOSION1]) + if (thing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(tmthing->player, thing->target); else - K_SpinPlayer(tmthing->player, thing->target); + K_SpinPlayer(tmthing->player, thing->target, 0, false); return true; } @@ -1543,21 +1539,15 @@ static boolean PIT_CheckThing(mobj_t *thing) && !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height)) { // SRB2kart - Squish! - if ((tmthing->player->kartstuff[k_growshrinktimer] > 0 && thing->player->kartstuff[k_growshrinktimer] <= 0) - || (tmthing->player->kartstuff[k_growshrinktimer] == 0 && thing->player->kartstuff[k_growshrinktimer] < 0)) - { + if (tmthing->scale > thing->scale + (FRACUNIT/8)) K_SquishPlayer(thing->player, tmthing); - } - else if ((thing->player->kartstuff[k_growshrinktimer] > 0 && tmthing->player->kartstuff[k_growshrinktimer] <= 0) - || (thing->player->kartstuff[k_growshrinktimer] == 0 && tmthing->player->kartstuff[k_growshrinktimer] < 0)) - { + else if (thing->scale > tmthing->scale + (FRACUNIT/8)) K_SquishPlayer(tmthing->player, thing); - } // SRB2kart - Starpower! - if (tmthing->player->kartstuff[k_startimer] && !thing->player->kartstuff[k_startimer]) + if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) P_DamageMobj(thing, tmthing, tmthing, 1); - else if (thing->player->kartstuff[k_startimer] && !tmthing->player->kartstuff[k_startimer]) + else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) P_DamageMobj(tmthing, thing, thing, 1); if (G_BattleGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) @@ -1649,107 +1639,32 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->player->kartstuff[k_growshrinktimer] || thing->player->kartstuff[k_squishedtimer] - || thing->player->kartstuff[k_bootimer] || thing->player->kartstuff[k_spinouttimer] - || thing->player->kartstuff[k_startimer] || thing->player->kartstuff[k_justbumped] - || (G_BattleGametype() && (thing->player->kartstuff[k_balloon] <= 0 - && (thing->player->kartstuff[k_comebacktimer]))) - || tmthing->player->kartstuff[k_growshrinktimer] || tmthing->player->kartstuff[k_squishedtimer] - || tmthing->player->kartstuff[k_bootimer] || tmthing->player->kartstuff[k_spinouttimer] - || tmthing->player->kartstuff[k_startimer] || tmthing->player->kartstuff[k_justbumped] - || (G_BattleGametype() && (tmthing->player->kartstuff[k_balloon] <= 0 - && (tmthing->player->kartstuff[k_comebacktimer])))) + if (thing->player->kartstuff[k_squishedtimer] || thing->player->kartstuff[k_hyudorotimer] + || thing->player->kartstuff[k_justbumped] || thing->scale > tmthing->scale + (FRACUNIT/8) + || (G_BattleGametype() && thing->player->kartstuff[k_bumper] <= 0) + || tmthing->player->kartstuff[k_squishedtimer] || tmthing->player->kartstuff[k_hyudorotimer] + || tmthing->player->kartstuff[k_justbumped] || tmthing->scale > thing->scale + (FRACUNIT/8) + || (G_BattleGametype() && tmthing->player->kartstuff[k_bumper] <= 0)) { return true; } - if (G_BattleGametype()) - { - if (thing->player->kartstuff[k_balloon] <= 0 || tmthing->player->kartstuff[k_balloon] <= 0) - { - if (thing->player->kartstuff[k_comebackmode] == 0 - && (tmthing->player->kartstuff[k_balloon] > 0 - && !tmthing->player->powers[pw_flashing])) - { - mobj_t *boom = P_SpawnMobj(thing->x, thing->y, thing->z, MT_BOOMPARTICLE); - boom->scale = thing->scale; - boom->destscale = thing->scale; - boom->momz = 5*FRACUNIT; - if (thing->player->skincolor) - boom->color = thing->player->skincolor; - else - boom->color = SKINCOLOR_RED; - S_StartSound(boom, sfx_s3k4e); - K_ExplodePlayer(tmthing->player, thing); - thing->player->kartstuff[k_comebacktimer] = comebacktime; - return true; - } - else if (tmthing->player->kartstuff[k_comebackmode] == 0 - && (thing->player->kartstuff[k_balloon] > 0 - && !thing->player->powers[pw_flashing])) - { - mobj_t *boom = P_SpawnMobj(tmthing->x, tmthing->y, tmthing->z, MT_BOOMPARTICLE); - boom->scale = tmthing->scale; - boom->destscale = tmthing->scale; - boom->momz = 5*FRACUNIT; - if (tmthing->player->skincolor) - boom->color = tmthing->player->skincolor; - else - boom->color = SKINCOLOR_RED; - S_StartSound(boom, sfx_s3k4e); - K_ExplodePlayer(thing->player, tmthing); - tmthing->player->kartstuff[k_comebacktimer] = comebacktime; - return true; - } - else if (thing->player->kartstuff[k_comebackmode] == 1 - && (tmthing->player->kartstuff[k_balloon] > 0 - && P_CanPickupItem(tmthing->player, true))) - { - thing->player->kartstuff[k_comebackmode] = 0; - thing->player->kartstuff[k_comebackpoints]++; - if (netgame && cv_hazardlog.value) - CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[thing->player-players], player_names[tmthing->player-players]); - tmthing->player->kartstuff[k_itemroulette] = 1; - tmthing->player->kartstuff[k_roulettetype] = 1; - if (thing->player->kartstuff[k_comebackpoints] >= 3) - K_StealBalloon(thing->player, tmthing->player, true); - thing->player->kartstuff[k_comebacktimer] = comebacktime; - return true; - } - else if (tmthing->player->kartstuff[k_comebackmode] == 1 - && (thing->player->kartstuff[k_balloon] > 0 - && P_CanPickupItem(thing->player, true))) - { - tmthing->player->kartstuff[k_comebackmode] = 0; - tmthing->player->kartstuff[k_comebackpoints]++; - if (netgame && cv_hazardlog.value) - CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[tmthing->player-players], player_names[thing->player-players]); - thing->player->kartstuff[k_itemroulette] = 1; - thing->player->kartstuff[k_roulettetype] = 1; - if (tmthing->player->kartstuff[k_comebackpoints] >= 3) - K_StealBalloon(tmthing->player, thing->player, true); - tmthing->player->kartstuff[k_comebacktimer] = comebacktime; - return true; - } - } - } - if (P_IsObjectOnGround(thing) && tmthing->momz < 0) { K_KartBouncing(tmthing, thing, true, false); - if (G_BattleGametype() && tmthing->player->kartstuff[k_feather] & 2) + if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring]) { - K_StealBalloon(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing); + K_StealBumper(tmthing->player, thing->player, false); + K_SpinPlayer(thing->player, tmthing, 0, false); } } else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) { K_KartBouncing(thing, tmthing, true, false); - if (G_BattleGametype() && thing->player->kartstuff[k_feather] & 2) + if (G_BattleGametype() && thing->player->kartstuff[k_pogospring]) { - K_StealBalloon(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing); + K_StealBumper(thing->player, tmthing->player, false); + K_SpinPlayer(tmthing->player, thing, 0, false); } } else @@ -1757,15 +1672,15 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype()) { - if (thing->player->kartstuff[k_mushroomtimer] && !(tmthing->player->kartstuff[k_mushroomtimer])) + if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer])) { - K_StealBalloon(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing); + K_StealBumper(thing->player, tmthing->player, false); + K_SpinPlayer(tmthing->player, thing, 0, false); } - else if (tmthing->player->kartstuff[k_mushroomtimer] && !(thing->player->kartstuff[k_mushroomtimer])) + else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer])) { - K_StealBalloon(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing); + K_StealBumper(tmthing->player, thing->player, false); + K_SpinPlayer(thing->player, tmthing, 0, false); } } @@ -2608,10 +2523,13 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) fixed_t tryx = thiscam->x; fixed_t tryy = thiscam->y; +#ifndef NOCLIPCAM if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP)) || (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP)) || (thiscam == &camera3 && (players[thirddisplayplayer].pflags & PF_NOCLIP)) - || (thiscam == &camera4 && (players[fourthdisplayplayer].pflags & PF_NOCLIP))) + || (thiscam == &camera4 && (players[fourthdisplayplayer].pflags & PF_NOCLIP)) + || (leveltime < introtime)) +#endif { // Noclipping player camera noclips too!! floatok = true; thiscam->floorz = thiscam->z; @@ -3229,11 +3147,11 @@ static void P_HitSlideLine(line_t *ld) } // -// P_HitBounceLine +// P_PlayerHitBounceLine // -// Adjusts the xmove / ymove so that the next move will bounce off the wall. +// HitBounceLine, for players // -static void P_HitBounceLine(line_t *ld) +static void P_PlayerHitBounceLine(line_t *ld) { INT32 side; angle_t lineangle; @@ -3256,6 +3174,47 @@ static void P_HitBounceLine(line_t *ld) tmymove += FixedMul(movelen, FINESINE(lineangle)); } +// +// P_HitBounceLine +// +// Adjusts the xmove / ymove so that the next move will bounce off the wall. +// +static void P_HitBounceLine(line_t *ld) +{ + angle_t lineangle, moveangle, deltaangle; + fixed_t movelen; + + if (ld->slopetype == ST_HORIZONTAL) + { + tmymove = -tmymove; + return; + } + + if (ld->slopetype == ST_VERTICAL) + { + tmxmove = -tmxmove; + return; + } + + lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy); + + if (lineangle >= ANGLE_180) + lineangle -= ANGLE_180; + + moveangle = R_PointToAngle2(0, 0, tmxmove, tmymove); + deltaangle = moveangle + 2*(lineangle - moveangle); + + lineangle >>= ANGLETOFINESHIFT; + deltaangle >>= ANGLETOFINESHIFT; + + movelen = P_AproxDistance(tmxmove, tmymove); + + tmxmove = FixedMul(movelen, FINECOSINE(deltaangle)); + tmymove = FixedMul(movelen, FINESINE(deltaangle)); + + deltaangle = R_PointToAngle2(0, 0, tmxmove, tmymove); +} + // // PTR_SlideCameraTraverse // @@ -3874,41 +3833,35 @@ stairstep: } // -// P_BounceMove +// P_BouncePlayerMove // -// The momx / momy move is bad, so try to bounce off a wall. +// Bounce move, for players. // -void P_BounceMove(mobj_t *mo) + +void P_BouncePlayerMove(mobj_t *mo) { fixed_t leadx, leady; fixed_t trailx, traily; - //fixed_t newx, newy; - //INT32 hitcount; fixed_t mmomx = 0, mmomy = 0; - if (mo->eflags & MFE_JUSTBOUNCEDWALL) + if (!mo->player) + return; + + if ((mo->eflags & MFE_JUSTBOUNCEDWALL) || (mo->player->spectator)) { P_SlideMove(mo, true); return; } slidemo = mo; - //hitcount = 0; -/*retry: - if (++hitcount == 3) - goto bounceback; // don't loop forever*/ + mmomx = mo->player->rmomx; + mmomy = mo->player->rmomy; - if (mo->player) + if (mo->player->kartstuff[k_drift] != 0) // SRB2kart { - mmomx = mo->player->rmomx; - mmomy = mo->player->rmomy; - - if (mo->player->kartstuff[k_drift] != 0) // SRB2kart - { - mo->player->kartstuff[k_drift] = 0; - mo->player->kartstuff[k_driftcharge] = 0; - } + mo->player->kartstuff[k_drift] = 0; + mo->player->kartstuff[k_driftcharge] = 0; } else { @@ -3945,8 +3898,107 @@ void P_BounceMove(mobj_t *mo) P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); + // Now continue along the wall. + // First calculate remainder. + bestslidefrac = FRACUNIT - bestslidefrac; + + if (bestslidefrac > FRACUNIT) + bestslidefrac = FRACUNIT; + + if (bestslidefrac <= 0) + return; + + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + + { + mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); + if (mo->eflags & MFE_VERTICALFLIP) + fx->eflags |= MFE_VERTICALFLIP; + else + fx->eflags &= ~MFE_VERTICALFLIP; + fx->scale = mo->scale; + + S_StartSound(mo, sfx_s3k49); + } + + P_PlayerHitBounceLine(bestslideline); + mo->eflags |= MFE_JUSTBOUNCEDWALL; + + mo->momx = tmxmove; + mo->momy = tmymove; + mo->player->cmomx = tmxmove; + mo->player->cmomy = tmymove; + + P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true); +} + +// +// P_BounceMove +// +// The momx / momy move is bad, so try to bounce off a wall. +// +void P_BounceMove(mobj_t *mo) +{ + fixed_t leadx, leady; + fixed_t trailx, traily; + fixed_t newx, newy; + INT32 hitcount; + fixed_t mmomx = 0, mmomy = 0; + + if (mo->eflags & MFE_JUSTBOUNCEDWALL) + { + P_SlideMove(mo, true); + return; + } + + if (mo->player) + { + P_BouncePlayerMove(mo); + return; + } + + slidemo = mo; + hitcount = 0; + +retry: + if (++hitcount == 3) + goto bounceback; // don't loop forever + + mmomx = mo->momx; + mmomy = mo->momy; + + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } + + bestslidefrac = FRACUNIT + 1; + + P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); + // move up to the wall - /*if (bestslidefrac == FRACUNIT + 1) + if (bestslidefrac == FRACUNIT + 1) { // the move must have hit the middle, so bounce straight back bounceback: @@ -3956,22 +4008,12 @@ bounceback: mo->momy *= -1; mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - - if (mo->player) - { - mo->player->cmomx *= -1; - mo->player->cmomy *= -1; - mo->player->cmomx = FixedMul(mo->player->cmomx, - (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - mo->player->cmomy = FixedMul(mo->player->cmomy, - (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - } } return; - }*/ + } // fudge a bit to make sure it doesn't hit - /*bestslidefrac -= 0x800; + bestslidefrac -= 0x800; if (bestslidefrac > 0) { newx = FixedMul(mmomx, bestslidefrac); @@ -3979,7 +4021,7 @@ bounceback: if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true)) goto bounceback; - }*/ + } // Now continue along the wall. // First calculate remainder. @@ -4011,34 +4053,15 @@ bounceback: { tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - if (mo->player) - { - mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); - if (mo->eflags & MFE_VERTICALFLIP) - fx->eflags |= MFE_VERTICALFLIP; - else - fx->eflags &= ~MFE_VERTICALFLIP; - fx->scale = mo->scale; - - S_StartSound(mo, sfx_s3k49); - } } - P_HitBounceLine(bestslideline); - mo->eflags |= MFE_JUSTBOUNCEDWALL; + P_HitBounceLine(bestslideline); // clip the moves mo->momx = tmxmove; mo->momy = tmymove; - if (mo->player) - { - mo->player->cmomx = tmxmove; - mo->player->cmomy = tmymove; - } - - /*if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) - goto retry;*/ - P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true); + if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) + goto retry; } // diff --git a/src/p_mobj.c b/src/p_mobj.c index 9619ccb6..9cf78ebf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -38,8 +38,8 @@ #include "k_kart.h" // protos. -static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; -consvar_t cv_viewheight = {"viewheight", VIEWHEIGHTS, 0, viewheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +//static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; +//consvar_t cv_viewheight = {"viewheight", VIEWHEIGHTS, 0, viewheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef WALLSPLATS consvar_t cv_splats = {"splats", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -1343,7 +1343,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) // || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4])))) // gravityadd = gravityadd/3; // less gravity while flying/gliding if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)) - gravityadd = 0; + return 0; if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be { @@ -1352,7 +1352,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) } if (wasflip == !(mo->eflags & MFE_VERTICALFLIP)) // note!! == ! is not equivalent to != here - turns numeric into bool this way P_PlayerFlip(mo); - if (mo->player->kartstuff[k_feather] & 2) + if (mo->player->kartstuff[k_pogospring]) gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2); } else @@ -1401,9 +1401,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_WATERDROP: gravityadd >>= 1; break; - case MT_BANANAITEM: + case MT_BANANA: case MT_FAKEITEM: - case MT_BOMBITEM: + case MT_SSMINE: + case MT_SINK: gravityadd = FixedMul(gravityadd, 5*FRACUNIT/2); default: break; @@ -1722,14 +1723,22 @@ void P_XYMovement(mobj_t *mo) if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) P_PushableCheckBustables(mo); - //{ SRB2kart - Fireball - if (mo->type == MT_FIREBALL) + //{ SRB2kart - Ballhogs + if (mo->type == MT_BALLHOG) { - mo->health--; - if (mo->health == 0) + if (mo->health) { - S_StartSound(mo, mo->info->deathsound); - P_SetMobjState(mo, mo->info->deathstate); + mo->health--; + if (mo->health == 0) + mo->destscale = 1; + } + else + { + if (mo->scale < mapheaderinfo[gamemap-1]->mobj_scale/16) + { + P_RemoveMobj(mo); + return; + } } } //} @@ -1742,8 +1751,8 @@ void P_XYMovement(mobj_t *mo) if (player->bot) B_MoveBlocked(player); } - //{ SRB2kart - Red Shell - if (mo->type == MT_REDITEM || mo->type == MT_REDITEMDUD) + //{ SRB2kart - Jawz + if (mo->type == MT_JAWZ || mo->type == MT_JAWZ_DUD) { if (mo->health == 1) { @@ -1760,9 +1769,11 @@ void P_XYMovement(mobj_t *mo) { P_BounceMove(mo); xmove = ymove = 0; - //S_StartSound(mo, mo->info->activesound); - //{ SRB2kart - Green Shell, Fireball - if (mo->type == MT_GREENITEM) + S_StartSound(mo, mo->info->activesound); + + //{ SRB2kart - Orbinaut, Ballhog + // Bump sparks + if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG) { mobj_t *fx; fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); @@ -1771,6 +1782,10 @@ void P_XYMovement(mobj_t *mo) else fx->eflags &= ~MFE_VERTICALFLIP; fx->scale = mo->scale; + } + + if (mo->type == MT_ORBINAUT) // Orbinaut speed decreasing + { if (mo->health > 1) { S_StartSound(mo, mo->info->attacksound); @@ -1787,10 +1802,6 @@ void P_XYMovement(mobj_t *mo) P_InstaThrust(mo, R_PointToAngle2(mo->x, mo->y, mo->x + xmove, mo->y + ymove)+ANGLE_90, 16*FRACUNIT); } } - if (mo->type == MT_FIREBALL) - S_StartSound(mo, mo->info->attacksound); - else - S_StartSound(mo, mo->info->activesound); //} // Bounce ring algorithm @@ -1861,7 +1872,7 @@ void P_XYMovement(mobj_t *mo) // draw damage on wall //SPLAT TEST ---------------------------------------------------------- #ifdef WALLSPLATS - if (blockingline && mo->type != MT_REDRING //&& mo->type != MT_FIREBALL + if (blockingline && mo->type != MT_REDRING && mo->type != MT_FIREBALL && !(mo->flags2 & (MF2_AUTOMATIC|MF2_RAILRING|MF2_BOUNCERING|MF2_EXPLOSION|MF2_SCATTER))) // set by last P_TryMove() that failed { @@ -1997,10 +2008,10 @@ void P_XYMovement(mobj_t *mo) #endif //{ SRB2kart stuff - if (mo->type == MT_GREENITEM || mo->type == MT_REDITEMDUD || mo->type == MT_REDITEM || mo->type == MT_FIREBALL) //(mo->type == MT_REDITEM && !mo->tracer)) + if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG) //(mo->type == MT_JAWZ && !mo->tracer)) return; - if (mo->player && mo->player->kartstuff[k_spinouttimer] && mo->player->speed <= mo->player->normalspeed/2) + if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= mo->player->normalspeed/2) return; //} @@ -2328,11 +2339,12 @@ static boolean P_ZMovement(mobj_t *mo) // SRB2kart stuff that should die in pits // Shouldn't stop moving along the Z if there's no speed though! case MT_FAKEITEM: - case MT_BANANAITEM: - case MT_GREENITEM: - case MT_REDITEM: - case MT_REDITEMDUD: - case MT_FIREBALL: + case MT_BANANA: + case MT_ORBINAUT: + case MT_JAWZ: + case MT_JAWZ_DUD: + case MT_BALLHOG: + case MT_SSMINE: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -2886,16 +2898,16 @@ static void P_PlayerZMovement(mobj_t *mo) // Cut momentum in half when you hit the ground and // aren't pressing any controls. if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy - && !(mo->player->pflags & PF_SPINNING) && !(mo->player->kartstuff[k_spinouttimer])) + && !(mo->player->kartstuff[k_spinouttimer])) { mo->momx = mo->momx/2; mo->momy = mo->momy/2; - } - if (mo->player->cmd.buttons & BT_BRAKE && !(mo->player->cmd.forwardmove)) // FURTHER slowdown if you're braking. - { - mo->momx = mo->momx/2; - mo->momy = mo->momy/2; + if (mo->player->cmd.buttons & BT_BRAKE && !(mo->player->cmd.forwardmove)) // FURTHER slowdown if you're braking. + { + mo->momx = mo->momx/2; + mo->momy = mo->momy/2; + } } } @@ -2907,7 +2919,7 @@ static void P_PlayerZMovement(mobj_t *mo) mo->tics = -1; } else if ((mo->player->pflags & PF_JUMPED || (mo->player->pflags & (PF_SPINNING|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN) - || mo->player->powers[pw_tailsfly]) && (mo->player->kartstuff[k_spinouttimer] == 0)) // SRB2kart + || mo->player->powers[pw_tailsfly]) && (mo->player->kartstuff[k_spinouttimer] == 0)) // SRB2kart { K_KartMoveAnimation(mo->player); } @@ -3372,17 +3384,30 @@ void P_MobjCheckWater(mobj_t *mobj) } // skipping stone! - if (p && (p->charability2 == CA2_SPINDASH) && p->speed/2 > abs(mobj->momz) - && ((p->pflags & (PF_SPINNING|PF_JUMPED)) == PF_SPINNING) + if (p && p->kartstuff[k_waterskip] < 2 + && ((p->speed/2 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water. + || (p->speed > K_GetKartSpeed(p,false)/4 && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more! && ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop) || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom))) { + const fixed_t min = 6<momx = mobj->momx/2; + mobj->momy = mobj->momy/2; mobj->momz = -mobj->momz/2; - if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz > FixedMul(6*FRACUNIT, mobj->scale)) - mobj->momz = FixedMul(6*FRACUNIT, mobj->scale); - else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz < FixedMul(-6*FRACUNIT, mobj->scale)) - mobj->momz = FixedMul(-6*FRACUNIT, mobj->scale); + if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz < FixedMul(min, mobj->scale)) + mobj->momz = FixedMul(min, mobj->scale); + else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz > FixedMul(-min, mobj->scale)) + mobj->momz = FixedMul(-min, mobj->scale); + + /*if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz > FixedMul(max, mobj->scale)) + mobj->momz = FixedMul(max, mobj->scale); + else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz < FixedMul(-max, mobj->scale)) + mobj->momz = FixedMul(-max, mobj->scale);*/ + + p->kartstuff[k_waterskip]++; } } @@ -3677,7 +3702,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled dummy.y = thiscam->y; dummy.z = thiscam->z; dummy.height = thiscam->height; - if (!resetcalled && !(player->pflags & PF_NOCLIP) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. + if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. P_ResetCamera(player, thiscam); else P_SlideCameraMove(thiscam); @@ -3698,7 +3723,8 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled // adjust height thiscam->z += thiscam->momz + player->mo->pmomz; - if (!itsatwodlevel && !(player->pflags & PF_NOCLIP)) +#ifndef NOCLIPCAM + if (!itsatwodlevel && !(player->pflags & PF_NOCLIP || leveltime < introtime)) { // clip movement if (thiscam->z <= thiscam->floorz) // hit the floor @@ -3738,6 +3764,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled } } } +#endif } if (itsatwodlevel @@ -6264,6 +6291,11 @@ void P_RunShadows(void) else mobj->flags2 &= ~MF2_DONTDRAW; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->eflags |= MFE_VERTICALFLIP; + else + mobj->eflags &= ~MFE_VERTICALFLIP; + if (mobj->target->eflags & MFE_DRAWONLYFORP1) // groooooaann... mobj->eflags |= MFE_DRAWONLYFORP1; else @@ -6289,12 +6321,13 @@ void P_RunShadows(void) P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); - if (mobj->floorz < mobj->z) + if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height)) + || (!(mobj->eflags & MFE_VERTICALFLIP) && (mobj->floorz < mobj->z))) { INT32 i; fixed_t prevz; - mobj->z = mobj->floorz; + mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : mobj->floorz); for (i = 0; i < MAXFFLOORS; i++) { @@ -6306,7 +6339,7 @@ void P_RunShadows(void) // Check new position to see if you should still be on that ledge P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->z); - mobj->z = mobj->floorz; + mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : mobj->floorz); if (mobj->z == prevz) break; @@ -6431,6 +6464,11 @@ void P_MobjThinker(mobj_t *mobj) P_SetTarget(&mobj->target, NULL); if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) P_SetTarget(&mobj->tracer, NULL); + // hnext/hprev changes suggested by toaster + if (mobj->hnext && P_MobjWasRemoved(mobj->hnext)) + P_SetTarget(&mobj->hnext, NULL); + if (mobj->hprev && P_MobjWasRemoved(mobj->hprev)) + P_SetTarget(&mobj->hprev, NULL); mobj->flags2 &= ~MF2_PUSHED; mobj->eflags &= ~(MFE_SPRUNG|MFE_JUSTBOUNCEDWALL); @@ -6577,16 +6615,11 @@ void P_MobjThinker(mobj_t *mobj) { if (mobj->target && mobj->target->player && mobj->target->player->mo && mobj->target->player->health > 0 && !mobj->target->player->spectator) { - UINT8 kartspeed = mobj->target->player->kartspeed; - fixed_t dsone, dstwo; - INT32 HEIGHT; + fixed_t HEIGHT; fixed_t radius; - if (G_BattleGametype() && mobj->target->player->kartstuff[k_balloon] <= 0) - kartspeed = 1; - - dsone = (26*4 + kartspeed*2 + (9 - mobj->target->player->kartweight))*8; - dstwo = dsone*2; + fixed_t dsone = K_GetKartDriftSparkValue(mobj->target->player); + fixed_t dstwo = dsone*2; if (mobj->target->player->kartstuff[k_driftcharge] < dsone) { @@ -6594,7 +6627,7 @@ void P_MobjThinker(mobj_t *mobj) return; } - if (mobj->target->player->kartstuff[k_bootimer] > 0) + if (mobj->target->player->kartstuff[k_hyudorotimer] > 0) { if (splitscreen) { @@ -6603,7 +6636,7 @@ void P_MobjThinker(mobj_t *mobj) else mobj->flags2 &= ~MF2_DONTDRAW; - if (mobj->target->player->kartstuff[k_bootimer] >= (1*TICRATE/2) && mobj->target->player->kartstuff[k_bootimer] <= bootime-(1*TICRATE/2)) + if (mobj->target->player->kartstuff[k_hyudorotimer] >= (1*TICRATE/2) && mobj->target->player->kartstuff[k_hyudorotimer] <= hyudorotime-(1*TICRATE/2)) { if (mobj->target->player == &players[secondarydisplayplayer]) mobj->eflags |= MFE_DRAWONLYFORP2; @@ -6621,7 +6654,7 @@ void P_MobjThinker(mobj_t *mobj) { if (mobj->target->player == &players[displayplayer] || (mobj->target->player != &players[displayplayer] - && (mobj->target->player->kartstuff[k_bootimer] < (1*TICRATE/2) || mobj->target->player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) + && (mobj->target->player->kartstuff[k_hyudorotimer] < (1*TICRATE/2) || mobj->target->player->kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2)))) { if (leveltime & 1) mobj->flags2 |= MF2_DONTDRAW; @@ -6632,7 +6665,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->flags2 |= MF2_DONTDRAW; } } - else if (mobj->target->player->kartstuff[k_bootimer] == 0) + else if (mobj->target->player->kartstuff[k_hyudorotimer] == 0) { mobj->flags2 &= ~MF2_DONTDRAW; mobj->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); @@ -6652,15 +6685,15 @@ void P_MobjThinker(mobj_t *mobj) mobj->angle = ANGLE_180 + mobj->target->player->frameangle; // If the player is on the ceiling, then flip - if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP) + if (mobj->target->eflags & MFE_VERTICALFLIP) { mobj->eflags |= MFE_VERTICALFLIP; - HEIGHT = mobj->target->height; + HEIGHT = (16<eflags &= ~MFE_VERTICALFLIP; - HEIGHT = mobj->target->height-mobj->target->height; + HEIGHT = 0; } // Shrink if the player shrunk too. @@ -6671,7 +6704,7 @@ void P_MobjThinker(mobj_t *mobj) const angle_t fa = mobj->angle>>ANGLETOFINESHIFT; mobj->x = mobj->target->x + FixedMul(finecosine[fa],radius); mobj->y = mobj->target->y + FixedMul(finesine[fa],radius); - mobj->z = mobj->target->z + HEIGHT; + mobj->z = mobj->target->z - HEIGHT; P_SetThingPosition(mobj); } } @@ -6682,109 +6715,49 @@ void P_MobjThinker(mobj_t *mobj) } break; } - case MT_GREENSHIELD: - case MT_REDSHIELD: - case MT_BANANASHIELD: - case MT_FAKESHIELD: - case MT_BOMBSHIELD: - case MT_TRIPLEGREENSHIELD1: - case MT_TRIPLEGREENSHIELD2: - case MT_TRIPLEGREENSHIELD3: - case MT_TRIPLEREDSHIELD1: - case MT_TRIPLEREDSHIELD2: - case MT_TRIPLEREDSHIELD3: - case MT_TRIPLEBANANASHIELD1: - case MT_TRIPLEBANANASHIELD2: - case MT_TRIPLEBANANASHIELD3: - if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo + case MT_ORBINAUT_SHIELD: // Kart orbit items + case MT_JAWZ_SHIELD: + if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->health > 0 && !mobj->target->player->spectator) { - fixed_t z; - const fixed_t radius = FixedHypot(mobj->target->radius, mobj->target->radius) + FixedHypot(mobj->radius, mobj->radius); // mobj's distance from its Target, or Radius. - - //mobj->angle += FixedAngle(12*FRACUNIT); // mobj's actual speed. - if (mobj->type == MT_TRIPLEGREENSHIELD1 || mobj->type == MT_TRIPLEGREENSHIELD2 || mobj->type == MT_TRIPLEGREENSHIELD3 - || mobj->type == MT_TRIPLEREDSHIELD1 || mobj->type == MT_TRIPLEREDSHIELD2 || mobj->type == MT_TRIPLEREDSHIELD3) - mobj->angle += FixedAngle(mobj->info->speed); - else if (mobj->type == MT_TRIPLEBANANASHIELD2) - mobj->angle = (mobj->target->angle + ANGLE_135); - else if (mobj->type == MT_TRIPLEBANANASHIELD3) - mobj->angle = (mobj->target->angle + ANGLE_225); - else - mobj->angle = (mobj->target->angle + ANGLE_180); - - // If the player is on the ceiling, then flip your items as well. - if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - } - else - { - mobj->eflags &= ~MFE_VERTICALFLIP; - } - - // Shrink your items if the player shrunk too. - if (mobj->target->player) - mobj->scale = mobj->target->scale; - - if (P_MobjFlip(mobj) > 0) - { - z = mobj->target->z; - } - else - { - z = mobj->target->z + mobj->target->height - mobj->height; - } - - mobj->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, z); - mobj->momx = FixedMul(FINECOSINE(mobj->angle>>ANGLETOFINESHIFT),radius); - mobj->momy = FixedMul(FINESINE(mobj->angle>>ANGLETOFINESHIFT), radius); - mobj->flags &= ~MF_NOCLIPTHING; - if (!P_TryMove(mobj, mobj->target->x + mobj->momx, mobj->target->y + mobj->momy, true)) - P_SlideMove(mobj, true); - if (P_IsObjectOnGround(mobj->target)) - { - if (P_MobjFlip(mobj) > 0) - { - if (mobj->floorz > mobj->target->z - mobj->height) - { - z = mobj->floorz; - } - } - else - { - if (mobj->ceilingz < mobj->target->z + mobj->target->height + mobj->height) - { - z = mobj->ceilingz - mobj->height; - } - } - } - mobj->z = z; - mobj->momx = mobj->momy = 0; - // Was this so hard? - if ((mobj->type == MT_GREENSHIELD && !(mobj->target->player->kartstuff[k_greenshell] & 1)) - || (mobj->type == MT_REDSHIELD && !(mobj->target->player->kartstuff[k_redshell] & 1)) - || (mobj->type == MT_BANANASHIELD && !(mobj->target->player->kartstuff[k_banana] & 1)) - || (mobj->type == MT_TRIPLEGREENSHIELD1 && !(mobj->target->player->kartstuff[k_triplegreenshell] & 1)) - || (mobj->type == MT_TRIPLEGREENSHIELD2 && !(mobj->target->player->kartstuff[k_triplegreenshell] & 2)) - || (mobj->type == MT_TRIPLEGREENSHIELD3 && !(mobj->target->player->kartstuff[k_triplegreenshell] & 4)) - || (mobj->type == MT_TRIPLEREDSHIELD1 && !(mobj->target->player->kartstuff[k_tripleredshell] & 1)) - || (mobj->type == MT_TRIPLEREDSHIELD2 && !(mobj->target->player->kartstuff[k_tripleredshell] & 2)) - || (mobj->type == MT_TRIPLEREDSHIELD3 && !(mobj->target->player->kartstuff[k_tripleredshell] & 4)) - || (mobj->type == MT_TRIPLEBANANASHIELD1 && !(mobj->target->player->kartstuff[k_triplebanana] & 1)) - || (mobj->type == MT_TRIPLEBANANASHIELD2 && !(mobj->target->player->kartstuff[k_triplebanana] & 2)) - || (mobj->type == MT_TRIPLEBANANASHIELD3 && !(mobj->target->player->kartstuff[k_triplebanana] & 4)) - || (mobj->type == MT_BOMBSHIELD && !(mobj->target->player->kartstuff[k_bobomb] & 1)) - || (mobj->type == MT_FAKESHIELD && !(mobj->target->player->kartstuff[k_fakeitem] & 1))) + if ((mobj->type == MT_ORBINAUT_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT) + || (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ) + || (mobj->movedir > 0 && ((UINT16)mobj->target->player->kartstuff[k_itemamount] < mobj->movedir)) + || (!mobj->target->player->kartstuff[k_itemheld])) { P_RemoveMobj(mobj); return; } } else if ((mobj->health > 0 - && (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator)) + && (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator)) + || (mobj->health <= 0 && mobj->z <= mobj->floorz) + || P_CheckDeathPitCollide(mobj)) // When in death state + { + P_RemoveMobj(mobj); + return; + } + break; + case MT_BANANA_SHIELD: // Kart trailing items + case MT_SSMINE_SHIELD: + case MT_FAKESHIELD: + if (mobj->health > 0 && mobj->target && mobj->target->player + && mobj->target->player->health > 0 && !mobj->target->player->spectator) + { + // Was this so hard? + if ((mobj->type == MT_BANANA_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_BANANA) + || (mobj->type == MT_SSMINE_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_MINE) + || (mobj->type == MT_FAKESHIELD && !mobj->target->player->kartstuff[k_eggmanheld]) + || (mobj->type != MT_FAKESHIELD && (!mobj->target->player->kartstuff[k_itemheld] + || (mobj->lastlook > 0 && mobj->target->player->kartstuff[k_itemamount] < mobj->lastlook)))) + { + P_RemoveMobj(mobj); + return; + } + } + else if ((mobj->health > 0 + && (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator)) || (mobj->health <= 0 && mobj->z <= mobj->floorz) || P_CheckDeathPitCollide(mobj)) // When in death state { @@ -6829,7 +6802,7 @@ void P_MobjThinker(mobj_t *mobj) } } break; - case MT_BATTLEBALLOON: + case MT_BATTLEBUMPER: if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->health > 0 && !mobj->target->player->spectator) { @@ -6842,10 +6815,10 @@ void P_MobjThinker(mobj_t *mobj) else ang = FixedAngle(mobj->info->speed); - if (mobj->target->player->kartstuff[k_balloon] <= 1) + if (mobj->target->player->kartstuff[k_bumper] <= 1) diff = 0; else - diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_balloon]); + diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_bumper]); ang = (ang*leveltime) + (diff * (mobj->threshold-1)); @@ -6893,16 +6866,16 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo && mobj->tracer->player->health > 0 && !mobj->tracer->player->spectator) // STOLEN - mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen balloons + mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen bumpers else mobj->color = mobj->target->color; // but do so if it belongs to you :B - if (mobj->target->player->kartstuff[k_balloon] < 2) - P_SetMobjState(mobj, S_BATTLEBALLOON3); - else if (mobj->target->player->kartstuff[k_balloon] < 3) - P_SetMobjState(mobj, S_BATTLEBALLOON2); + if (mobj->target->player->kartstuff[k_bumper] < 2) + P_SetMobjState(mobj, S_BATTLEBUMPER3); + else if (mobj->target->player->kartstuff[k_bumper] < 3) + P_SetMobjState(mobj, S_BATTLEBUMPER2); else - P_SetMobjState(mobj, S_BATTLEBALLOON1); + P_SetMobjState(mobj, S_BATTLEBUMPER1); // Shrink your items if the player shrunk too. mobj->scale = mobj->target->scale; @@ -6917,7 +6890,7 @@ void P_MobjThinker(mobj_t *mobj) } // Was this so hard? - if (mobj->target->player->kartstuff[k_balloon] <= mobj->threshold) + if (mobj->target->player->kartstuff[k_bumper] <= mobj->threshold) { P_RemoveMobj(mobj); return; @@ -6941,10 +6914,14 @@ void P_MobjThinker(mobj_t *mobj) fixed_t scale = mobj->target->scale; mobj->color = mobj->target->color; - if (!netgame || G_RaceGametype() + if (G_RaceGametype() || mobj->target->player == &players[displayplayer] - || mobj->target->player->kartstuff[k_balloon] <= 0 - || (mobj->target->player->mo->flags2 & MF2_DONTDRAW)) + || mobj->target->player->kartstuff[k_bumper] <= 0 + || (mobj->target->player->mo->flags2 & MF2_DONTDRAW) +#if 1 // Set to 0 to test without needing to host + || !netgame +#endif + ) mobj->flags2 |= MF2_DONTDRAW; else mobj->flags2 &= ~MF2_DONTDRAW; @@ -6965,42 +6942,149 @@ void P_MobjThinker(mobj_t *mobj) } P_SetThingPosition(mobj); - // Set it to use the correct states for its condition - if (mobj->target->player->kartstuff[k_itemroulette]) + scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, + players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); + if (scale > 16*FRACUNIT) + scale = 16*FRACUNIT; + mobj->destscale = scale; + + if (!mobj->tracer) { - if (mobj->state != &states[S_PLAYERARROW_ROULETTE]) // don't reset FF_ANIMATE - P_SetMobjState(mobj, S_PLAYERARROW_ROULETTE); + mobj->tracer = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + P_SetTarget(&mobj->tracer->target, mobj); + P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM); + P_SetScale(mobj->tracer, mobj->scale); } - else if (mobj->target->player->kartstuff[k_kitchensink]) P_SetMobjState(mobj, S_PLAYERARROW_KITCHENSINK); - else if (mobj->target->player->kartstuff[k_megashroom] == 1 - || (mobj->target->player->kartstuff[k_growshrinktimer] > 1 - && (leveltime & 1))) P_SetMobjState(mobj, S_PLAYERARROW_MEGASHROOM); - else if (mobj->target->player->kartstuff[k_growshrinktimer] > 1 - && !(leveltime & 1)) P_SetMobjState(mobj, S_PLAYERARROW_EMPTY); // S_INVISIBLE - else if (mobj->target->player->kartstuff[k_star] == 1) P_SetMobjState(mobj, S_PLAYERARROW_STAR); - else if (mobj->target->player->kartstuff[k_tripleredshell]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEREDSHELL); - else if (mobj->target->player->kartstuff[k_triplebanana]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEBANANA); - else if (mobj->target->player->kartstuff[k_triplegreenshell]) P_SetMobjState(mobj, S_PLAYERARROW_TRIPLEGREENSHELL); - else if (mobj->target->player->kartstuff[k_fireflower]) P_SetMobjState(mobj, S_PLAYERARROW_FIREFLOWER); - else if (mobj->target->player->kartstuff[k_bobomb]) P_SetMobjState(mobj, S_PLAYERARROW_BOBOMB); - else if (mobj->target->player->kartstuff[k_redshell]) P_SetMobjState(mobj, S_PLAYERARROW_REDSHELL); - else if (mobj->target->player->kartstuff[k_feather] & 1) P_SetMobjState(mobj, S_PLAYERARROW_FEATHER); - else if (mobj->target->player->kartstuff[k_boo] == 1) P_SetMobjState(mobj, S_PLAYERARROW_BOO); - else if (mobj->target->player->kartstuff[k_fakeitem] & 2) P_SetMobjState(mobj, S_PLAYERARROW_FAKEITEM); - else if (mobj->target->player->kartstuff[k_banana]) P_SetMobjState(mobj, S_PLAYERARROW_BANANA); - else if (mobj->target->player->kartstuff[k_greenshell]) P_SetMobjState(mobj, S_PLAYERARROW_GREENSHELL); - else if (mobj->target->player->kartstuff[k_mushroom]) P_SetMobjState(mobj, S_PLAYERARROW_MUSHROOM); - else if (mobj->target->player->kartstuff[k_mushroom] - && mobj->target->player->kartstuff[k_mushroomtimer] > 1 - && !(leveltime & 1)) P_SetMobjState(mobj, S_PLAYERARROW_EMPTY); // S_INVISIBLE - else P_SetMobjState(mobj, S_PLAYERARROW); // S_INVISIBLE + + if (!(mobj->flags2 & MF2_DONTDRAW)) + { + // Set it to use the correct states for its condition + if (mobj->target->player->kartstuff[k_itemroulette]) + { + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|(((mobj->target->player->kartstuff[k_itemroulette] % (13*3)) / 3) + 1); + } + else if (mobj->target->player->kartstuff[k_itemtype]) + { + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + + switch (mobj->target->player->kartstuff[k_itemtype]) + { + case KITEM_INVINCIBILITY: + mobj->tracer->sprite = SPR_ITMI; + mobj->tracer->frame = FF_FULLBRIGHT|((leveltime % (7*3)) / 3); + break; + case KITEM_SAD: + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT; + break; + default: + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemtype]); + break; + } + + if (mobj->target->player->kartstuff[k_growshrinktimer] > 0) + { + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|KITEM_GROW; + + if (leveltime & 1) + mobj->tracer->flags2 |= MF2_DONTDRAW; + else + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + } + else + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + } + else + { + P_SetMobjState(mobj, S_PLAYERARROW); + P_SetMobjState(mobj->tracer, S_INVISIBLE); + } + + mobj->tracer->destscale = scale; + + if (mobj->target->player->kartstuff[k_itemamount] > 1 + && mobj->target->player->kartstuff[k_itemamount] < 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V + { + mobj_t *number = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + mobj_t *numx = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + + P_SetTarget(&number->target, mobj); + P_SetMobjState(number, S_PLAYERARROW_NUMBER); + P_SetScale(number, mobj->scale); + number->destscale = scale; + number->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemamount]); + + P_SetTarget(&numx->target, mobj); + P_SetMobjState(numx, S_PLAYERARROW_X); + P_SetScale(numx, mobj->scale); + numx->destscale = scale; + } + + if (K_IsPlayerWanted(mobj->target->player) && mobj->movecount != 1) + { + mobj_t *wanted = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PLAYERWANTED); + P_SetTarget(&wanted->target, mobj->target); + P_SetTarget(&wanted->tracer, mobj); + P_SetScale(wanted, mobj->scale); + wanted->destscale = scale; + mobj->movecount = 1; + } + else if (!K_IsPlayerWanted(mobj->target->player)) + mobj->movecount = 0; + } + else + mobj->tracer->flags2 |= MF2_DONTDRAW; + } + else if (mobj->health > 0) + { + P_KillMobj(mobj, NULL, NULL); + return; + } + break; + case MT_PLAYERWANTED: + if (mobj->target && mobj->target->health && mobj->tracer + && mobj->target->player && !mobj->target->player->spectator + && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD + && players[displayplayer].mo && !players[displayplayer].spectator) + { + fixed_t scale = mobj->target->scale; + + if (!K_IsPlayerWanted(mobj->target->player)) + { + mobj->tracer->movecount = 0; + P_RemoveMobj(mobj); + return; + } + + if (mobj->tracer->flags2 & MF2_DONTDRAW) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + if (!(mobj->target->eflags & MFE_VERTICALFLIP)) + { + mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale)); + mobj->eflags &= ~MFE_VERTICALFLIP; + } + else + { + mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale)); + mobj->eflags |= MFE_VERTICALFLIP; + } + P_SetThingPosition(mobj); scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); if (scale > 16*FRACUNIT) - { scale = 16*FRACUNIT; - } mobj->destscale = scale; } else if (mobj->health > 0) @@ -7229,7 +7313,7 @@ void P_MobjThinker(mobj_t *mobj) P_PushableThinker(mobj); // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA //&& mobj->type != MT_FIREBALL + if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) { P_KillMobj(mobj, NULL, NULL); @@ -7366,19 +7450,26 @@ void P_MobjThinker(mobj_t *mobj) } } else // Apply gravity to fall downwards. + { P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + if (mobj->player) + mobj->player->frameangle -= ANGLE_22h; + } } break; //{ SRB2kart Items - Death States - case MT_GREENITEM: - case MT_REDITEM: - case MT_REDITEMDUD: - case MT_BANANAITEM: + case MT_ORBINAUT: + case MT_BANANA: case MT_FAKEITEM: if (mobj->z <= mobj->floorz) P_RemoveMobj(mobj); break; - case MT_BOMBITEM: + case MT_JAWZ: + case MT_JAWZ_DUD: + if (mobj->z <= mobj->floorz) + P_SetMobjState(mobj, mobj->info->xdeathstate); + break; + case MT_SSMINE: case MT_BLUEEXPLOSION: if (mobj->health > -100) { @@ -7388,7 +7479,7 @@ void P_MobjThinker(mobj_t *mobj) else P_RemoveMobj(mobj); break; - case MT_BOMBEXPLOSIONSOUND: + case MT_MINEEXPLOSIONSOUND: P_RemoveMobj(mobj); break; //} @@ -7876,7 +7967,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->threshold = 0; } break; - case MT_GREENITEM: + case MT_ORBINAUT: { sector_t *sec2; fixed_t finalspeed = mobj->info->speed; @@ -7888,7 +7979,7 @@ void P_MobjThinker(mobj_t *mobj) else if (gamespeed == 2) finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4); - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->x+mobj->momx, mobj->y+mobj->momy); + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); if (mobj->health <= 5) { INT32 i; @@ -7909,7 +8000,7 @@ void P_MobjThinker(mobj_t *mobj) if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoBouncePad(mobj, 0); + K_DoPogoSpring(mobj, 0, false); if (mobj->threshold > 0) mobj->threshold--; @@ -7918,7 +8009,7 @@ void P_MobjThinker(mobj_t *mobj) S_StartSound(mobj, mobj->info->activesound); break; } - case MT_REDITEM: + case MT_JAWZ: { sector_t *sec2; fixed_t topspeed = 64*FRACUNIT; @@ -7929,7 +8020,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->threshold > 0) mobj->threshold--; - if (leveltime % 7 == 0) + if (leveltime % TICRATE == 0) S_StartSound(mobj, mobj->info->activesound); if (gamespeed == 0) @@ -7968,7 +8059,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->friction = 0; } - P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), topspeed); + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + P_InstaThrust(mobj, mobj->angle, topspeed); if (mobj->tracer) mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); @@ -7981,33 +8073,33 @@ void P_MobjThinker(mobj_t *mobj) if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoBouncePad(mobj, 0); + K_DoPogoSpring(mobj, 0, false); break; } - case MT_REDITEMDUD: + case MT_JAWZ_DUD: { sector_t *sec2; P_SpawnGhostMobj(mobj); - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->x+mobj->momx, mobj->y+mobj->momy); + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); P_InstaThrust(mobj, mobj->angle, mobj->info->speed); sec2 = P_ThingOnSpecial3DFloor(mobj); if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoBouncePad(mobj, 0); + K_DoPogoSpring(mobj, 0, false); if (mobj->threshold > 0) mobj->threshold--; - if (leveltime % 7 == 0) + if (leveltime % TICRATE == 0) S_StartSound(mobj, mobj->info->activesound); break; } - case MT_BANANAITEM: + case MT_BANANA: case MT_FAKEITEM: if (mobj->momx || mobj->momy) P_SpawnGhostMobj(mobj); @@ -8020,13 +8112,14 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->threshold > 0) mobj->threshold--; break; - case MT_FIREBALL: - var1 = MT_FIRETRAIL; - A_SmokeTrailer(mobj); + case MT_BALLHOG: + P_SpawnGhostMobj(mobj)->fuse = 3; if (mobj->threshold > 0) mobj->threshold--; break; case MT_SINK: + if (mobj->momx || mobj->momy) + P_SpawnGhostMobj(mobj); if (mobj->z <= mobj->floorz) { S_StartSound(mobj, mobj->info->deathsound); @@ -8035,16 +8128,19 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->threshold > 0) mobj->threshold--; break; - case MT_BOMBITEM: + case MT_SSMINE: + if (mobj->target && mobj->target->player) + mobj->color = mobj->target->player->skincolor; + else + mobj->color = SKINCOLOR_RED; if (mobj->momx || mobj->momy) P_SpawnGhostMobj(mobj); if (P_IsObjectOnGround(mobj)) { + if (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2]) + P_SetMobjState(mobj, S_SSMINE_DEPLOY1); if (mobj->reactiontime >= mobj->info->reactiontime) { - if (mobj->state == &states[S_BOMBAIR]) - P_SetMobjState(mobj, S_BOMBITEM); - mobj->momx = mobj->momy = 0; S_StartSound(mobj, mobj->info->activesound); mobj->reactiontime--; @@ -8056,13 +8152,16 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->reactiontime) P_KillMobj(mobj, NULL, NULL); } + if ((mobj->state >= &states[S_SSMINE1] && mobj->state <= &states[S_SSMINE4]) + || (mobj->state >= &states[S_SSMINE_DEPLOY8] && mobj->state <= &states[S_SSMINE_DEPLOY13])) + A_GrenadeRing(mobj); if (mobj->threshold > 0) mobj->threshold--; break; case MT_BLUEEXPLOSION: mobj->health--; break; - case MT_BOMBEXPLOSION: + case MT_MINEEXPLOSION: if ((mobj->z < mobj->floorz - mobj->height) || (mobj->z > mobj->ceilingz + mobj->height)) { P_KillMobj(mobj, NULL, NULL); @@ -8085,11 +8184,111 @@ void P_MobjThinker(mobj_t *mobj) mobj->z += mobj->momz; P_SetThingPosition(mobj); return; - case MT_BOMBEXPLOSIONSOUND: + case MT_MINEEXPLOSIONSOUND: if (mobj->health == 100) S_StartSound(mobj, sfx_prloop); mobj->health--; break; + case MT_SPARKLETRAIL: + if (!mobj->target) + { + P_RemoveMobj(mobj); + return; + } + mobj->color = mobj->target->color; + mobj->colorized = mobj->target->colorized; + break; + case MT_INVULNFLASH: + if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_invincibilitytimer])) + { + P_RemoveMobj(mobj); + return; + } + P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + break; + case MT_INSTASHIELDB: + if (leveltime & 1) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + /* FALLTHRU */ + case MT_INSTASHIELDA: + if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield])) + { + P_RemoveMobj(mobj); + return; + } + P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + break; + case MT_KARMAHITBOX: + if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator + || (G_RaceGametype() || mobj->target->player->kartstuff[k_bumper])) + { + P_RemoveMobj(mobj); + return; + } + + P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + mobj->scalespeed = mobj->target->scalespeed; + mobj->destscale = mobj->target->destscale; + P_SetScale(mobj, mobj->target->scale); + mobj->color = mobj->target->color; + mobj->colorized = (mobj->target->player->kartstuff[k_comebackmode] == 1); + + if (mobj->target->player->kartstuff[k_comebacktimer] > 0) + { + if (mobj->state != &states[mobj->info->spawnstate]) + P_SetMobjState(mobj, mobj->info->spawnstate); + + if (mobj->target->player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1)) + mobj->flags2 &= ~MF2_DONTDRAW; + else + mobj->flags2 |= MF2_DONTDRAW; + } + else + { + if (mobj->target->player->kartstuff[k_comebackmode] == 0 + && mobj->state != &states[mobj->info->spawnstate]) + P_SetMobjState(mobj, mobj->info->spawnstate); + else if (mobj->target->player->kartstuff[k_comebackmode] == 1 + && mobj->state != &states[mobj->info->seestate]) + P_SetMobjState(mobj, mobj->info->seestate); + + if (mobj->target->player->powers[pw_flashing] && (leveltime & 1)) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + } + + // Now for the wheels + { + const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->target->scale); + mobj_t *cur = mobj->hnext; + + while (cur && !P_MobjWasRemoved(cur)) + { + fixed_t offx = rad; + fixed_t offy = rad; + + if (cur->lastlook == 1 || cur->lastlook == 3) + offx *= -1; + if (cur->lastlook == 2 || cur->lastlook == 3) + offy *= -1; + + P_TeleportMove(cur, mobj->x + offx, mobj->y + offy, mobj->z); + cur->scalespeed = mobj->target->scalespeed; + cur->destscale = mobj->target->destscale; + P_SetScale(cur, mobj->target->scale); + + if (mobj->flags2 & MF2_DONTDRAW) + cur->flags2 |= MF2_DONTDRAW; + else + cur->flags2 &= ~MF2_DONTDRAW; + + cur = cur->hnext; + } + } + break; //} case MT_TURRET: P_MobjCheckWater(mobj); @@ -8150,7 +8349,7 @@ void P_MobjThinker(mobj_t *mobj) #endif break; case MT_SPINFIRE: - case MT_MUSHROOMTRAIL: + case MT_SNEAKERTRAIL: if (mobj->eflags & MFE_VERTICALFLIP) mobj->z = mobj->ceilingz - mobj->height; else @@ -8161,7 +8360,7 @@ void P_MobjThinker(mobj_t *mobj) P_MobjCheckWater(mobj); // Extinguish fire objects in water - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA //&& mobj->type != MT_FIREBALL + if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) { P_KillMobj(mobj, NULL, NULL); @@ -8850,6 +9049,39 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BLUEBALL: nummaprings++; break; + case MT_KARMAHITBOX: // SRB2Kart + { + const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->scale); + mobj_t *cur, *prev = mobj; + INT32 i; + + for (i = 0; i < 4; i++) + { + fixed_t offx = rad; + fixed_t offy = rad; + + if (i == 1 || i == 3) + offx *= -1; + if (i == 2 || i == 3) + offy *= -1; + + cur = P_SpawnMobj(mobj->x + offx, mobj->y + offy, mobj->z, MT_KARMAWHEEL); + cur->destscale = mobj->scale; + P_SetScale(cur, mobj->scale); + + cur->lastlook = i; + + P_SetTarget(&cur->hprev, prev); + P_SetTarget(&prev->hnext, cur); + + prev = cur; + } + } + break; + case MT_BIGRING: + mobj->destscale = 3*FRACUNIT; + P_SetScale(mobj, 3*FRACUNIT); + break; default: break; } @@ -8857,18 +9089,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) switch (mobj->type) { case MT_PLAYER: - case MT_BIGMACE: case MT_SMALLMACE: + case MT_BIGMACE: case MT_SMALLMACE: case MT_FALLINGROCK: //case MT_RANDOMITEM: - case MT_BANANAITEM: case MT_BANANASHIELD: - case MT_TRIPLEBANANASHIELD1: case MT_TRIPLEBANANASHIELD2: case MT_TRIPLEBANANASHIELD3: - case MT_GREENITEM: case MT_GREENSHIELD: - case MT_TRIPLEGREENSHIELD1: case MT_TRIPLEGREENSHIELD2: case MT_TRIPLEGREENSHIELD3: - case MT_REDITEM: case MT_REDSHIELD: case MT_REDITEMDUD: - case MT_TRIPLEREDSHIELD1: case MT_TRIPLEREDSHIELD2: case MT_TRIPLEREDSHIELD3: - case MT_BATTLEBALLOON: case MT_FIREBALL: - case MT_FAKEITEM: case MT_FAKESHIELD: - case MT_BOMBITEM: case MT_BOMBSHIELD: + case MT_BATTLEBUMPER: + case MT_BANANA: case MT_BANANA_SHIELD: + //case MT_FAKEITEM: case MT_FAKESHIELD: + case MT_ORBINAUT: case MT_ORBINAUT_SHIELD: + case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: + case MT_SSMINE: case MT_SSMINE_SHIELD: + case MT_BALLHOG: case MT_SINK: P_SpawnShadowMobj(mobj); default: break; @@ -9125,6 +9355,18 @@ void P_RemoveMobj(mobj_t *mobj) iquetail = (iquetail+1)&(ITEMQUESIZE-1); } + if (mobj->type == MT_KARMAHITBOX) // Remove linked list objects for certain types + { + mobj_t *cur = mobj->hnext; + + while (cur && !P_MobjWasRemoved(cur)) + { + mobj_t *prev = cur; // Kind of a dumb var, but we need to set cur before we remove the mobj + cur = cur->hnext; + P_RemoveMobj(prev); + } + } + if (mobj->type == MT_OVERLAY) P_RemoveOverlay(mobj); @@ -9153,6 +9395,23 @@ void P_RemoveMobj(mobj_t *mobj) // Remove any references to other mobjs. P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL)); + // repair hnext chain + { + mobj_t *cachenext = mobj->hnext; + + if (mobj->hnext && !P_MobjWasRemoved(mobj->hnext)) + { + P_SetTarget(&mobj->hnext->hprev, mobj->hprev); + P_SetTarget(&mobj->hnext, NULL); + } + + if (mobj->hprev && !P_MobjWasRemoved(mobj->hprev)) + { + P_SetTarget(&mobj->hprev->hnext, cachenext); + P_SetTarget(&mobj->hprev, NULL); + } + } + // free block // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. if (mobj->flags & MF_NOTHINK && !mobj->thinker.next) @@ -9231,7 +9490,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj) } static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; -consvar_t cv_itemrespawntime = {"respawnitemtime", "1", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_itemrespawntime = {"respawnitemtime", "2", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_itemrespawn = {"respawnitem", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -9466,9 +9725,13 @@ void P_RespawnSpecials(void) { P_SpawnMapThing(box->spawnpoint); newmobj = box->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing + P_SpawnMobj(box->spawnpoint->mobj->x, box->spawnpoint->mobj->y, box->spawnpoint->mobj->z, MT_EXPLODE); // poof into existance } else + { newmobj = P_SpawnMobj(box->x, box->y, box->z, box->type); + P_SpawnMobj(newmobj->x, newmobj->y, newmobj->z, MT_EXPLODE); // poof into existance + } // Transfer flags2 (strongbox, objectflip) newmobj->flags2 = box->flags2; @@ -9577,25 +9840,33 @@ void P_RespawnSpecials(void) // void P_SpawnPlayer(INT32 playernum) { + UINT8 i, pcount = 0; player_t *p = &players[playernum]; mobj_t *mobj; - mobj_t *overheadarrow; if (p->playerstate == PST_REBORN) G_PlayerReborn(playernum); + for (i = 0; i < MAXPLAYERS; i++) + { + if (i == playernum) + continue; + if (!playeringame[i] || players[i].spectator) + continue; + pcount++; + } + // spawn as spectator determination if (!G_GametypeHasSpectators()) + p->spectator = false; + else if (netgame && p->jointime <= 1 && pcount) { - // Special case for (NiGHTS) special stages! - // if stage has already started, force players to become spectators until the next stage - /*if (multiplayer && netgame && G_IsSpecialStage(gamemap) && useNightsSS && leveltime > 0) - p->spectator = true; - else*/ - p->spectator = false; + p->spectator = true; + // Oni doesn't want this + /*if (pcount == 1 || leveltime < starttime) + p->pflags |= PF_WANTSTOJOIN; + p->jointime = 2;*/ } - else if (netgame && p->jointime < 1) - /*p->spectator = true*/; else if (multiplayer && !netgame) { // If you're in a team game and you don't have a team assigned yet... @@ -9661,65 +9932,59 @@ void P_SpawnPlayer(INT32 playernum) p->awayviewtics = 0; // set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't. + if (cv_kartdebugshrink.value && !p->bot) + mobj->destscale = 6*mobj->destscale/8; P_SetScale(mobj, mobj->destscale); P_FlashPal(p, 0, 0); // Resets // Spawn with a pity shield if necessary. //P_DoPityCheck(p); - overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW); - P_SetTarget(&overheadarrow->target, mobj); - overheadarrow->flags2 |= MF2_DONTDRAW; - P_SetScale(overheadarrow, mobj->destscale); - - if (G_BattleGametype()) + if (G_BattleGametype()) // SRB2kart { - /*INT32 i; - INT32 pcount = 0; + mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW); + P_SetTarget(&overheadarrow->target, mobj); + overheadarrow->flags2 |= MF2_DONTDRAW; + P_SetScale(overheadarrow, mobj->destscale); - for (i = 0; i < MAXPLAYERS; i++) + if (p->spectator && pcount > 1) // HEY! No being cheap... + p->kartstuff[k_bumper] = 0; + else if (p->kartstuff[k_bumper] > 0 || leveltime < 1 + || (p->jointime <= 1 && pcount <= 1)) { - if (!playeringame[i] || players[i].spectator || &players[i] == p) - continue; - if (players[i].jointime > 0) - continue; - pcount++; - }*/ + if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map? + p->kartstuff[k_bumper] = cv_kartbumpers.value; // Reset those bumpers! - if (p->kartstuff[k_balloon] > 0 || leveltime < 1/* || pcount <= 1*/) // srb2kart - { - INT32 i; - angle_t newangle; - angle_t diff; - fixed_t newx; - fixed_t newy; - mobj_t *mo; - - if (leveltime < 1 /*|| pcount <= 1*/) // Start of the map? - p->kartstuff[k_balloon] = cv_kartballoons.value; // Reset those balloons! - - if (p->kartstuff[k_balloon] <= 1) - diff = 0; - else - diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_balloon]); - - newangle = mobj->angle; - newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT); - newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT); - - for (i = 0; i < p->kartstuff[k_balloon]; i++) + if (p->kartstuff[k_bumper]) { - mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBALLOON); - mo->threshold = i; - P_SetTarget(&mo->target, mobj); - mo->angle = (diff * (i-1)); - mo->color = mobj->color; - if (mobj->flags2 & MF2_DONTDRAW) - mo->flags2 |= MF2_DONTDRAW; - else - mo->flags2 &= ~MF2_DONTDRAW; + INT32 i; + angle_t diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_bumper]); + angle_t newangle = mobj->angle; + fixed_t newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT); + fixed_t newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT); + mobj_t *mo; + + for (i = 0; i < p->kartstuff[k_bumper]; i++) + { + mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER); + mo->threshold = i; + P_SetTarget(&mo->target, mobj); + mo->angle = (diff * (i-1)); + mo->color = mobj->color; + if (mobj->flags2 & MF2_DONTDRAW) + mo->flags2 |= MF2_DONTDRAW; + else + mo->flags2 &= ~MF2_DONTDRAW; + } } } + else if (p->kartstuff[k_bumper] <= 0) + { + mobj_t *karmahitbox = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_KARMAHITBOX); // Player hitbox is too small!! + P_SetTarget(&karmahitbox->target, mobj); + karmahitbox->destscale = mobj->scale; + P_SetScale(karmahitbox, mobj->scale); + } } } @@ -9737,7 +10002,7 @@ void P_AfterPlayerSpawn(INT32 playernum) else if (playernum == fourthdisplayplayer) localangle4 = mobj->angle; - p->viewheight = cv_viewheight.value<viewheight = 32<mo->eflags & MFE_VERTICALFLIP) p->viewz = p->mo->z + p->mo->height - p->viewheight; @@ -9827,7 +10092,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) z = ceiling - mobjinfo[MT_PLAYER].height; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); - if (p->kartstuff[k_lakitu]) + if (p->kartstuff[k_respawn]) z -= 128*FRACUNIT; } else @@ -9835,7 +10100,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) z = floor; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); - if (p->kartstuff[k_lakitu]) + if (p->kartstuff[k_respawn]) z += 128*FRACUNIT; } @@ -9897,7 +10162,7 @@ void P_MovePlayerToStarpost(INT32 playernum) #endif sector->ceilingheight; - z = (p->starpostz + 128) << FRACBITS; // Lakitu spawns you off the ground + z = (p->starpostz + 128) << FRACBITS; // Respawn off the ground if (z < floor) z = floor; else if (z > ceiling - mobjinfo[MT_PLAYER].height) diff --git a/src/p_mobj.h b/src/p_mobj.h index 919a3d58..50645e4b 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -366,7 +366,7 @@ typedef struct mobj_s struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) #endif - boolean colorized; // Whether the mobj uses the starman colormap + boolean colorized; // Whether the mobj uses the rainbow colormap // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; @@ -450,7 +450,7 @@ boolean P_SupermanLook4Players(mobj_t *actor); void P_DestroyRobots(void); void P_SnowThinker(precipmobj_t *mobj); void P_RainThinker(precipmobj_t *mobj); -FUNCMATH void P_NullPrecipThinker(precipmobj_t *mobj); +void P_NullPrecipThinker(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj); void P_SetScale(mobj_t *mobj, fixed_t newscale); void P_XYMovement(mobj_t *mo); diff --git a/src/p_saveg.c b/src/p_saveg.c index 0fc69ad3..fdbe4033 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -436,7 +436,7 @@ static void P_NetUnArchivePlayers(void) if (flags & AWAYVIEW) players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p); - players[i].viewheight = cv_viewheight.value<next) + if (gamestate == GS_LEVEL) { - if (th->function.acp1 == (actionf_p1)P_MobjThinker) + for (th = thinkercap.next; th != &thinkercap; th = th->next) { - mobj = (mobj_t *)th; - if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) - continue; - mobj->mobjnum = i++; + if (th->function.acp1 == (actionf_p1)P_MobjThinker) + { + mobj = (mobj_t *)th; + if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) + continue; + mobj->mobjnum = i++; + } } } diff --git a/src/p_setup.c b/src/p_setup.c index bc29cc6c..f4c28663 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2197,11 +2197,15 @@ static void P_LevelInitStuff(void) for (i = 0; i < MAXPLAYERS; i++) { +#if 0 if ((netgame || multiplayer) && (gametype == GT_COMPETITION || players[i].lives <= 0)) { // In Co-Op, replenish a user's lives if they are depleted. players[i].lives = cv_startinglives.value; } +#else + players[i].lives = 1; +#endif players[i].realtime = countdown = countdown2 = 0; curlap = bestlap = 0; // SRB2Kart @@ -2426,6 +2430,7 @@ static void P_ForceCharacter(const char *forcecharskin) static void P_LoadRecordGhosts(void) { + // see also m_menu.c's Nextmap_OnChange const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char *gpath = malloc(glen); INT32 i; @@ -2559,11 +2564,6 @@ boolean P_SetupLevel(boolean skipprecip) CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer - - // Reset the palette - if (rendermode != render_none) - V_SetPaletteLump("PLAYPAL"); - // Initialize sector node list. P_Initsecnode(); @@ -2620,7 +2620,7 @@ boolean P_SetupLevel(boolean skipprecip) // Special stage fade to white // This is handled BEFORE sounds are stopped. - if (rendermode != render_none && G_IsSpecialStage(gamemap)) + /*if (rendermode != render_none && G_IsSpecialStage(gamemap)) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (3*TICRATE)/2; @@ -2647,7 +2647,7 @@ boolean P_SetupLevel(boolean skipprecip) } ranspecialwipe = 1; - } + }*/ // Make sure all sounds are stopped before Z_FreeTags. S_StopSounds(); @@ -2659,20 +2659,24 @@ boolean P_SetupLevel(boolean skipprecip) S_Start(); // SRB2 Kart - Yes this is weird, but we don't want the music to start until after the countdown is finished // but we do still need the mapmusname to be changed - if (leveltime < 158) - S_StopMusic(); + if (leveltime < (starttime + (TICRATE/2))) + S_ChangeMusicInternal("kstart", false); //S_StopMusic(); // Let's fade to black here // But only if we didn't do the special stage wipe if (rendermode != render_none && !ranspecialwipe) { F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 120); F_WipeEndScreen(); F_RunWipe(wipedefs[wipe_level_toblack], false); } + // Reset the palette now all fades have been done + if (rendermode != render_none) + V_SetPaletteLump(GetPalette()); // Set the level palette + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." /*if (rendermode != render_none) { @@ -2875,8 +2879,11 @@ boolean P_SetupLevel(boolean skipprecip) CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n")); } - else if (G_RaceGametype() && server && cv_usemapnumlaps.value) - CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps); + else if (G_RaceGametype() && server) + CV_StealthSetValue(&cv_numlaps, + ((netgame || multiplayer) && cv_basenumlaps.value) + ? cv_basenumlaps.value + : mapheaderinfo[gamemap - 1]->numlaps); // =========== // landing point for netgames. @@ -2990,22 +2997,27 @@ boolean P_SetupLevel(boolean skipprecip) else { if (G_BattleGametype()) + { gamespeed = 0; - else - gamespeed = cv_kartspeed.value; - - if (G_BattleGametype()) mirrormode = false; + } else - mirrormode = cv_kartmirror.value; - - franticitems = cv_kartfrantic.value; - comeback = cv_kartcomeback.value; + { + gamespeed = (UINT8)cv_kartspeed.value; + mirrormode = (boolean)cv_kartmirror.value; + } + franticitems = (boolean)cv_kartfrantic.value; + comeback = (boolean)cv_kartcomeback.value; } - lightningcooldown = 0; - blueshellincoming = 0; - blueshellplayer = 0; + for (i = 0; i < 4; i++) + battlewanted[i] = -1; + + wantedcalcdelay = wantedfrequency*2; + indirectitemcooldown = 0; + spbincoming = 0; + spbplayer = 0; + mapreset = 0; // clear special respawning que iquehead = iquetail = 0; @@ -3025,7 +3037,7 @@ boolean P_SetupLevel(boolean skipprecip) // Remove the loading shit from the screen if (rendermode != render_none) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 120); if (precache || dedicated) R_PrecacheLevel(); @@ -3143,7 +3155,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) } else if (name[1] == '_') { - CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + CONS_Debug(DBG_SETUP, "Music %.8s ignored\n", name); mreplaces++; } } @@ -3164,7 +3176,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) if (!devparm && sreplaces) CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces)); if (!devparm && mreplaces) - CONS_Printf(M_GetText("%s midi musics replaced\n"), sizeu1(mreplaces)); + CONS_Printf(M_GetText("%s midi musics ignored\n"), sizeu1(mreplaces)); if (!devparm && digmreplaces) CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces)); diff --git a/src/p_spec.c b/src/p_spec.c index 7883a2ca..4b186e9d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3753,22 +3753,46 @@ DoneSection2: // Process Section 3 switch (special) { - case 1: // SRB2kart: bounce pad + case 1: // SRB2kart: Spring Panel if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { + const fixed_t scale = mapheaderinfo[gamemap-1]->mobj_scale + abs(player->mo->scale - mapheaderinfo[gamemap-1]->mobj_scale); + const fixed_t minspeed = 24*scale; + if (player->mo->eflags & MFE_SPRUNG) break; - if (player->speed < K_GetKartSpeed(player, true)/4) // Push forward to prevent getting stuck - P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale)); + if (player->speed < minspeed) // Push forward to prevent getting stuck + P_InstaThrust(player->mo, player->mo->angle, minspeed); - player->kartstuff[k_feather] |= 2; - K_DoBouncePad(player->mo, 0); + player->kartstuff[k_pogospring] = 1; + K_DoPogoSpring(player->mo, 0, false); } break; case 2: // Wind/Current - case 3: // Unused (was "Ice/Sludge and Wind/Current") + break; + + case 3: // SRB2kart: Spring Panel (capped speed) + if (roversector || P_MobjReadyToTrigger(player->mo, sector)) + { + const fixed_t scale = mapheaderinfo[gamemap-1]->mobj_scale + abs(player->mo->scale - mapheaderinfo[gamemap-1]->mobj_scale); + const fixed_t minspeed = 24*scale; + const fixed_t maxspeed = 36*scale; + + if (player->mo->eflags & MFE_SPRUNG) + break; + + if (player->speed > maxspeed) // Prevent overshooting jumps + P_InstaThrust(player->mo, R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy), maxspeed); + else if (player->speed < minspeed) // Push forward to prevent getting stuck + P_InstaThrust(player->mo, player->mo->angle, minspeed); + + player->kartstuff[k_pogospring] = 2; + K_DoPogoSpring(player->mo, 0, false); + } + break; + case 4: // Conveyor Belt break; @@ -3969,22 +3993,21 @@ DoneSection2: // P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); break; - case 6: // SRB2kart 190117 - Mushroom Boost Panel + case 6: // SRB2kart 190117 - Sneaker Panel if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { if (!player->kartstuff[k_floorboost]) player->kartstuff[k_floorboost] = 3; else player->kartstuff[k_floorboost] = 2; - K_DoMushroom(player, false); + K_DoSneaker(player, false); } break; case 7: // SRB2kart 190117 - Oil Slick if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { - player->kartstuff[k_spinouttype] = -1; - K_SpinPlayer(player, NULL); + K_SpinPlayer(player, NULL, 0, false); } break; @@ -4151,7 +4174,7 @@ DoneSection2: if (player->starpostcount >= numstarposts/2) // srb2kart: must have touched *enough* starposts (was originally "(player->starpostnum == numstarposts)") { player->laps++; - player->kartstuff[k_lapanimation] = 80; + //player->kartstuff[k_lapanimation] = 80; if (player->pflags & PF_NIGHTSMODE) player->drillmeter += 48*20; @@ -4184,11 +4207,12 @@ DoneSection2: if (P_IsLocalPlayer(player)) { - if (player->laps < (UINT8)(cv_numlaps.value - 1)) - S_StartSound(NULL, sfx_mlap); - else if (player->laps == (UINT8)(cv_numlaps.value - 1)) - S_StartSound(NULL, sfx_mlap); + if (player->laps == (UINT8)(cv_numlaps.value - 1)) + S_StartSound(NULL, sfx_s3k68); + else if (player->laps < (UINT8)(cv_numlaps.value - 1)) + S_StartSound(NULL, sfx_s221); } + // //player->starpostangle = player->starposttime = player->starpostnum = 0; //player->starpostx = player->starposty = player->starpostz = 0; @@ -4207,26 +4231,10 @@ DoneSection2: if (player->laps >= (unsigned)cv_numlaps.value) { - if (P_IsLocalPlayer(player)) - { - // SRB2kart 200117 - if (splitscreen) - S_ChangeMusicInternal("karwin", true); - else - { - if (player->kartstuff[k_position] == 1) - S_ChangeMusicInternal("karwin", true); - else if (K_IsPlayerLosing(player)) - S_ChangeMusicInternal("karlos", true); - else - S_ChangeMusicInternal("karok", true); - } - } - - if (player->kartstuff[k_position] == 1) + if (!splitscreen && P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_s3k6a); + else if (player->kartstuff[k_position] == 1) S_StartSound(NULL, sfx_s253); - else if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_s24f); P_DoPlayerExit(player); } @@ -7222,8 +7230,8 @@ void T_Friction(friction_t *f) // friction works for all mobj's // (or at least MF_PUSHABLEs, which is all I care about anyway) if ((!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz) && (thing->player - && (thing->player->kartstuff[k_startimer] == 0 && thing->player->kartstuff[k_bootimer] == 0 - && thing->player->kartstuff[k_mushroomtimer] == 0 && thing->player->kartstuff[k_growshrinktimer] <= 0))) + && (thing->player->kartstuff[k_invincibilitytimer] == 0 && thing->player->kartstuff[k_hyudorotimer] == 0 + && thing->player->kartstuff[k_sneakertimer] == 0 && thing->player->kartstuff[k_growshrinktimer] <= 0))) { if (f->roverfriction) { @@ -7756,7 +7764,6 @@ void T_Pusher(pusher_t *p) thing->player->pflags |= PF_JUMPED; thing->player->pflags |= PF_SLIDING; - P_SetPlayerMobjState (thing, thing->info->painstate); // Whee! thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)); if (!demoplayback || P_AnalogMove(thing->player)) diff --git a/src/p_tick.c b/src/p_tick.c index 8235e8d5..b9aaccf7 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -677,12 +677,12 @@ void P_Ticker(boolean run) if (countdown2) countdown2--; - if (blueshellincoming && --blueshellincoming <= 0) + if (spbincoming && --spbincoming <= 0) { UINT8 best = 0; SINT8 hurtthisguy = -1; - blueshellincoming = 0; + spbincoming = 0; for (i = 0; i < MAXPLAYERS; i++) { @@ -703,11 +703,20 @@ void P_Ticker(boolean run) } if (hurtthisguy != -1) - players[hurtthisguy].kartstuff[k_deathsentence] = TICRATE+1; + { + players[hurtthisguy].kartstuff[k_deathsentence] = (2*TICRATE)+1; + S_StartSound(players[hurtthisguy].mo, sfx_kc57); + } } - if (lightningcooldown) - lightningcooldown--; + if (indirectitemcooldown) + indirectitemcooldown--; + + if (G_BattleGametype()) + { + if (wantedcalcdelay && --wantedcalcdelay <= 0) + K_CalculateBattleWanted(); + } if (quake.time) { @@ -731,6 +740,11 @@ void P_Ticker(boolean run) G_ConsGhostTic(); if (modeattacking) G_GhostTicker(); + + if (mapreset > 1 + && --mapreset <= 1 + && server) // Remember: server uses it for mapchange, but EVERYONE ticks down for the animation + D_MapChange(gamemap, gametype, ultimatemode, true, 0, false, false); } P_MapEnd(); diff --git a/src/p_user.c b/src/p_user.c index f5ab500f..86e404ac 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -218,7 +218,7 @@ void P_CalcHeight(player_t *player) //bob = FixedMul(player->bob/2, FINESINE(angle)); // move viewheight - player->viewheight = FixedMul(cv_viewheight.value << FRACBITS, mo->scale); // default eye view height + player->viewheight = FixedMul(32 << FRACBITS, mo->scale); // default eye view height /*if (player->playerstate == PST_LIVE) { @@ -406,6 +406,31 @@ UINT8 P_FindLowestLap(void) return lowest; } +// +// P_FindHighestLap +// +UINT8 P_FindHighestLap(void) +{ + INT32 i; + UINT8 highest = 0; + + if (!G_RaceGametype()) + return 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (players[i].laps > highest) + highest = players[i].laps; + } + + CONS_Debug(DBG_GAMELOGIC, "Highest laps found: %d\n", highest); + + return highest; +} + // // P_TransferToNextMare // @@ -636,9 +661,6 @@ static void P_DeNightserizePlayer(player_t *player) else if (player == &players[fourthdisplayplayer]) localaiming4 = 0; - // If you screwed up, kiss your score goodbye. - player->marescore = 0; - if (player->mo->tracer) P_RemoveMobj(player->mo->tracer); //P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); // SRB2kart @@ -765,8 +787,6 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) G_AddTempNightsRecords(players[i].marescore, leveltime - player->marebegunat, players[i].mare + 1);*/ // transfer scores anyway - players[i].lastmarescore = players[i].marescore; - players[i].marescore = 0; players[i].mo->health = players[i].health = 1; P_DoPlayerExit(&players[i]); @@ -788,8 +808,6 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) G_AddTempNightsRecords(player->marescore, leveltime - player->marebegunat, (UINT8)(oldmare + 1));*/ // Starting a new mare, transfer scores - player->lastmarescore = player->marescore; - player->marescore = 0; player->marebegunat = leveltime; player->mo->health = player->health = 1; @@ -834,15 +852,19 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) angle_t ang; fixed_t fallbackspeed; - if (player->mo->eflags & MFE_VERTICALFLIP) - player->mo->z--; - else - player->mo->z++; + if (inflictor && (inflictor->type != MT_PLAYER && inflictor->type != MT_ORBINAUT && inflictor->type != MT_ORBINAUT_SHIELD + && inflictor->type != MT_JAWZ && inflictor->type != MT_JAWZ_DUD && inflictor->type != MT_JAWZ_SHIELD)) + { + if (player->mo->eflags & MFE_VERTICALFLIP) + player->mo->z--; + else + player->mo->z++; - if (player->mo->eflags & MFE_UNDERWATER) - P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false); - else - P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); + if (player->mo->eflags & MFE_UNDERWATER) + P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false); + else + P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); + } if (inflictor) { @@ -1039,11 +1061,10 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // Adds to the player's score void P_AddPlayerScore(player_t *player, UINT32 amount) { - UINT32 oldscore; + //UINT32 oldscore; -#if 1 - return; // Nope, still don't need this for Battle even -#endif + if (!(G_BattleGametype())) + return; if (player->bot) player = &players[consoleplayer]; @@ -1051,73 +1072,20 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) if (player->exiting) // srb2kart return; - // NiGHTS does it different! - if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->typeoflevel & TOL_NIGHTS) - { - if ((netgame || multiplayer) && G_IsSpecialStage(gamemap)) - { // Pseudo-shared score for multiplayer special stages. - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) - { - oldscore = players[i].marescore; - - // Don't go above MAXSCORE. - if (players[i].marescore + amount < MAXSCORE) - players[i].marescore += amount; - else - players[i].marescore = MAXSCORE; - - // Continues are worthless in netgames. - // If that stops being the case uncomment this. -/* if (!ultimatemode && players[i].marescore > 50000 - && oldscore < 50000) - { - players[i].continues += 1; - players[i].gotcontinue = true; - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_flgcap); - } */ - } - } - else - { - oldscore = player->marescore; - - // Don't go above MAXSCORE. - if (player->marescore + amount < MAXSCORE) - player->marescore += amount; - else - player->marescore = MAXSCORE; - - if (!ultimatemode && !(netgame || multiplayer) && G_IsSpecialStage(gamemap) - && player->marescore >= 50000 && oldscore < 50000) - { - player->continues += 1; - player->gotcontinue = true; - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_flgcap); - } - } - - if (gametype == GT_COOP) - return; - } - - oldscore = player->score; + //oldscore = player->score; // Don't go above MAXSCORE. - if (player->score + amount < MAXSCORE) - player->score += amount; + if (player->marescore + amount < MAXSCORE) + player->marescore += amount; else - player->score = MAXSCORE; + player->marescore = MAXSCORE; // check for extra lives every 50000 pts - if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametype == GT_COMPETITION || gametype == GT_COOP)) + /*if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametype == GT_COMPETITION || gametype == GT_COOP)) { P_GivePlayerLives(player, (player->score/50000) - (oldscore/50000)); P_PlayLivesJingle(player); - } + }*/ // In team match, all awarded points are incremented to the team's running score. if (gametype == GT_TEAMMATCH) @@ -1150,6 +1118,84 @@ void P_PlayLivesJingle(player_t *player) } } +void P_PlayRinglossSound(mobj_t *source) +{ + sfxenum_t key = P_RandomKey(4); + if (cv_kartvoices.value) + S_StartSound(source, (mariomode) ? sfx_mario8 : sfx_altow1 + key); + else + S_StartSound(source, sfx_slip); +} + +void P_PlayDeathSound(mobj_t *source) +{ + sfxenum_t key = P_RandomKey(4); + if (cv_kartvoices.value) + S_StartSound(source, sfx_altdi1 + key); + else + S_StartSound(source, sfx_s3k35); +} + +void P_PlayVictorySound(mobj_t *source) +{ + sfxenum_t key = P_RandomKey(4); + if (cv_kartvoices.value) + S_StartSound(source, sfx_victr1 + key); +} + +// +// P_EndingMusic +// +// Consistently sets ending music! +// +boolean P_EndingMusic(player_t *player) +{ + char buffer[9]; + boolean looping = true; + + if (!P_IsLocalPlayer(player)) // Only applies to a local player + return false; + + // Event - Level Finish + if (splitscreen + && (players[displayplayer].exiting + || players[secondarydisplayplayer].exiting + || ((splitscreen < 2) && players[thirddisplayplayer].exiting) + || ((splitscreen < 3) && players[fourthdisplayplayer].exiting))) + { + sprintf(buffer, "k*ok"); + } + else if (player->pflags & PF_TIMEOVER) // || !player->lives) -- outta lives, outta time + { + sprintf(buffer, "k*lose"); + } + else if (player->exiting) + { + if (player->kartstuff[k_position] == 1) + sprintf(buffer, "k*win"); + else if (K_IsPlayerLosing(player)) + sprintf(buffer, "k*lose"); + else + sprintf(buffer, "k*ok"); + } + else + return false; + + S_SpeedMusic(1.0f); + + if (G_RaceGametype()) + buffer[1] = 'r'; + else if (G_BattleGametype()) + { + buffer[1] = 'b'; + looping = false; + } + + S_ChangeMusicInternal(buffer, looping); + + return true; +} + // // P_RestoreMusic // @@ -1160,43 +1206,37 @@ void P_RestoreMusic(player_t *player) if (!P_IsLocalPlayer(player)) // Only applies to a local player return; - if (player->powers[pw_extralife] > 1) + // Event - HERE COMES A NEW CHALLENGER + if (mapreset) + { + S_ChangeMusicInternal("chalng", false); //S_StopMusic(); return; + } + + // Event - Level Ending + if (P_EndingMusic(player)) + return; + S_SpeedMusic(1.0f); - // SRB2kart - We have some different powers than vanilla, some of which tweak the music. - if (splitscreen != 0 && G_RaceGametype() - && (players[consoleplayer].exiting - || players[secondarydisplayplayer].exiting - || players[thirddisplayplayer].exiting - || players[fourthdisplayplayer].exiting)) - S_ChangeMusicInternal("karwin", true); - else if (splitscreen == 0 && G_RaceGametype() && player->exiting) + // Event - Level Start + if (leveltime < (starttime + (TICRATE/2))) + S_ChangeMusicInternal("kstart", false); //S_StopMusic(); + else // see also where time overs are handled - search for "lives = 2" in this file { - if (player->kartstuff[k_position] == 1) - S_ChangeMusicInternal("karwin", true); - else if (K_IsPlayerLosing(player)) - S_ChangeMusicInternal("karlos", true); - else - S_ChangeMusicInternal("karok", true); - } - else - { - // Item - Mega Mushroom + // Item - Grow if (player->kartstuff[k_growshrinktimer] > 1 && player->playerstate == PST_LIVE) - S_ChangeMusicInternal("mega", true); - // Item - Star - else if (player->kartstuff[k_startimer] > 1 && player->playerstate == PST_LIVE) - S_ChangeMusicInternal("minvnc", false); - else if (leveltime > 157) + S_ChangeMusicInternal("kgrow", true); + // Item - Invincibility + else if (player->kartstuff[k_invincibilitytimer] > 1 && player->playerstate == PST_LIVE) + S_ChangeMusicInternal("kinvnc", true); + else { // Event - Final Lap if (G_RaceGametype() && player->laps >= (UINT8)(cv_numlaps.value - 1)) S_SpeedMusic(1.2f); S_ChangeMusic(mapmusname, mapmusflags, true); } - else - S_StopMusic(); } } @@ -1543,7 +1583,11 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->color = mobj->color; ghost->colorized = mobj->colorized; // Kart: they should also be colorized if their origin is - ghost->angle = mobj->angle; + if (mobj->player) + ghost->angle = mobj->player->frameangle; + else + ghost->angle = mobj->angle; + ghost->sprite = mobj->sprite; ghost->frame = mobj->frame; ghost->tics = -1; @@ -1671,7 +1715,7 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type) // Player exits the map via sector trigger void P_DoPlayerExit(player_t *player) { - if (player->exiting) + if (player->exiting || mapreset) return; if ((player == &players[consoleplayer] @@ -1689,8 +1733,7 @@ void P_DoPlayerExit(player_t *player) else if (!countdown) countdown = cv_countdowntime.value*TICRATE + 1; // Use cv_countdowntime - - if (circuitmap) + if (cv_kartvoices.value) { if (K_IsPlayerLosing(player)) S_StartSound(player->mo, sfx_klose); @@ -1698,34 +1741,23 @@ void P_DoPlayerExit(player_t *player) S_StartSound(player->mo, sfx_kwin); } - if (P_IsLocalPlayer(player) && cv_inttime.value > 0) - { - if (!splitscreen) - { - if (player->kartstuff[k_position] == 1) - S_ChangeMusicInternal("karwin", true); - else if (K_IsPlayerLosing(player)) - S_ChangeMusicInternal("karlos", true); - else - S_ChangeMusicInternal("karok", true); - } - else - S_ChangeMusicInternal("karok", true); - } - player->exiting = 3*TICRATE; + if (cv_inttime.value > 0) + P_EndingMusic(player); + // SRB2kart 120217 - if (!countdown2 && !(netgame || multiplayer)) - countdown2 = (66)*TICRATE + 1; // 6 seconds past the time over - else if (!countdown2) - countdown2 = (8 + cv_countdowntime.value)*TICRATE + 1; // 8 sec more than countdowntime -- 11 is too much + //if (!countdown2) + //countdown2 = countdown + 8*TICRATE; if (P_CheckRacers()) player->exiting = (14*TICRATE)/5 + 1; } - else if (G_BattleGametype()) - player->exiting = 8*TICRATE + 1; // Battle Mode exiting + else if (G_BattleGametype()) // Battle Mode exiting + { + player->exiting = 8*TICRATE + 1; + P_EndingMusic(player); + } else player->exiting = (14*TICRATE)/5 + 2; // Accidental death safeguard??? @@ -1741,7 +1773,6 @@ void P_DoPlayerExit(player_t *player) player->powers[pw_underwater] = 0; player->powers[pw_spacetime] = 0; player->kartstuff[k_cardanimation] = 0; // srb2kart: reset battle animation - P_RestoreMusic(player); /*if (playeringame[player-players] && netgame && !circuitmap) CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);*/ @@ -2164,6 +2195,7 @@ static void P_CheckQuicksand(player_t *player) // // Restores music from sneaker and life fanfares // +/* // SRB2kart - Can't drown. static void P_CheckSneakerAndLivesTimer(player_t *player) { if ((player->powers[pw_underwater] <= 11*TICRATE + 1) @@ -2176,12 +2208,14 @@ static void P_CheckSneakerAndLivesTimer(player_t *player) //if (player->powers[pw_sneakers] == 1) // SRB2kart // P_RestoreMusic(player); } +*/ // // P_CheckUnderwaterAndSpaceTimer // // Restores music from underwater and space warnings, and handles number generation // +/* // SRB2kart - Can't drown. static void P_CheckUnderwaterAndSpaceTimer(player_t *player) { fixed_t height; @@ -2290,7 +2324,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) player->powers[pw_spacetime] = 0; } -} +}*/ // // P_CheckInvincibilityTimer @@ -2299,20 +2333,20 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) // static void P_CheckInvincibilityTimer(player_t *player) { - if (!player->powers[pw_invulnerability] && !player->kartstuff[k_startimer]) + if (!player->powers[pw_invulnerability] && !player->kartstuff[k_invincibilitytimer]) return; //if (mariomode && !player->powers[pw_super]) // SRB2kart player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); - if (leveltime % (TICRATE/7) == 0) + /*if (leveltime % (TICRATE/7) == 0) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); sparkle->destscale = player->mo->scale; P_SetScale(sparkle, player->mo->scale); - } + }*/ // Resume normal music stuff. - if (player->powers[pw_invulnerability] == 1 || player->kartstuff[k_startimer] == 1) + if (player->powers[pw_invulnerability] == 1 || player->kartstuff[k_invincibilitytimer] == 1) { if (!player->powers[pw_super]) { @@ -2334,11 +2368,11 @@ static void P_CheckInvincibilityTimer(player_t *player) P_SpawnShieldOrb(player); } - if ((player->powers[pw_underwater] <= 11*TICRATE + 1) + /*if ((player->powers[pw_underwater] <= 11*TICRATE + 1) && (player->powers[pw_underwater] > 1)) return; // don't restore music if drowning music is playing - if (!player->powers[pw_super] || (mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) + if (!player->powers[pw_super] || (mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))*/ P_RestoreMusic(player); } } @@ -3562,10 +3596,10 @@ static void P_DoSuperStuff(player_t *player) return; // NiGHTS Super doesn't mix with normal super // Does player have all emeralds? If so, flag the "Ready For Super!" - if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50) + /*if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50) player->pflags |= PF_SUPERREADY; else - player->pflags &= ~PF_SUPERREADY; + player->pflags &= ~PF_SUPERREADY;*/ if (player->powers[pw_super]) { @@ -3691,7 +3725,7 @@ static void P_DoSuperStuff(player_t *player) // // Returns true if player is ready to turn super, duh // -boolean P_SuperReady(player_t *player) +/*boolean P_SuperReady(player_t *player) { if ((player->pflags & PF_SUPERREADY) && !player->powers[pw_super] && !player->powers[pw_tailsfly] && !(player->powers[pw_shield] & SH_NOSTACK) @@ -3702,7 +3736,7 @@ boolean P_SuperReady(player_t *player) return true; return false; -} +}*/ // // P_DoJump @@ -4015,7 +4049,6 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // SRB2kart - unused. // void P_DoJumpShield(player_t *player) { - return; // SRB2kart - Would be useful for feathers, but those are impossible to balance, so nuts to it. if (player->pflags & PF_THOKKED) return; @@ -4704,21 +4737,23 @@ static void P_3dMovement(player_t *player) cmd = &player->cmd; - if (player->exiting || player->pflags & PF_STASIS || player->kartstuff[k_spinouttimer]) // pw_introcam? + if ((player->exiting || mapreset) || player->pflags & PF_STASIS || player->kartstuff[k_spinouttimer]) // pw_introcam? { cmd->forwardmove = cmd->sidemove = 0; + if (player->kartstuff[k_sneakertimer]) + cmd->forwardmove = 50; if (player->pflags & PF_GLIDING) { if (!player->skidtime) player->pflags &= ~PF_GLIDING; - else if (player->exiting) + else if (player->exiting || mapreset) { player->pflags &= ~PF_GLIDING; P_SetPlayerMobjState(player->mo, S_KART_WALK1); // SRB2kart - was S_PLAY_RUN1 player->skidtime = 0; } } - if (player->pflags & PF_SPINNING && !player->exiting) + if (player->pflags & PF_SPINNING && !(player->exiting || mapreset)) { player->pflags &= ~PF_SPINNING; P_SetPlayerMobjState(player->mo, S_KART_STND1); // SRB2kart - was S_PLAY_STND @@ -4797,13 +4832,13 @@ static void P_3dMovement(player_t *player) cmd->forwardmove = 0; // Do not let the player control movement if not onground. - // SRB2Kart: feather and speed bumps are supposed to control like you're on the ground - onground = (P_IsObjectOnGround(player->mo) || (player->kartstuff[k_feather] & 2)); + // SRB2Kart: pogo spring and speed bumps are supposed to control like you're on the ground + onground = (P_IsObjectOnGround(player->mo) || (player->kartstuff[k_pogospring])); player->aiming = cmd->aiming<exiting || (P_PlayerInPain(player) && !onground))) + if (!((player->exiting || mapreset) || (P_PlayerInPain(player) && !onground))) { //movepushforward = cmd->forwardmove * (thrustfactor * acceleration); movepushforward = K_3dKartMovement(player, onground, cmd->forwardmove); @@ -4821,6 +4856,15 @@ static void P_3dMovement(player_t *player) if (cmd->buttons & BT_BRAKE && !cmd->forwardmove) // SRB2kart - braking isn't instant movepushforward /= 64; + if (cmd->forwardmove > 0) + player->kartstuff[k_brakestop] = 0; + else if (player->kartstuff[k_brakestop] < 6) // Don't start reversing with brakes until you've made a stop first + { + if (player->speed < 8*FRACUNIT) + player->kartstuff[k_brakestop]++; + movepushforward = 0; + } + #ifdef ESLOPE totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); @@ -4834,7 +4878,7 @@ static void P_3dMovement(player_t *player) } // Sideways movement - if (cmd->sidemove != 0 && !(player->exiting || (P_PlayerInPain(player)))) + if (cmd->sidemove != 0 && !((player->exiting || mapreset) || player->kartstuff[k_spinouttimer])) { if (cmd->sidemove > 0) movepushside = (cmd->sidemove * FRACUNIT/128) + FixedDiv(player->speed, K_GetKartSpeed(player, true)); @@ -4885,7 +4929,7 @@ static void P_3dMovement(player_t *player) if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed) { fixed_t tempmomx, tempmomy; - if (oldMagnitude > K_GetKartSpeed(player, true)) //topspeed) + if (oldMagnitude > K_GetKartSpeed(player, true) && onground) // SRB2Kart: onground check for air speed cap { if (newMagnitude > oldMagnitude) { @@ -6471,8 +6515,8 @@ static void P_MovePlayer(player_t *player) { player->pflags |= PF_FULLSTASIS; // If you're in stasis in tag, you don't drown. - if (player->powers[pw_underwater] <= 12*TICRATE + 1) - P_RestoreMusic(player); + /*if (player->powers[pw_underwater] <= 12*TICRATE + 1) + P_RestoreMusic(player);*/ player->powers[pw_underwater] = player->powers[pw_spacetime] = 0; } } @@ -6543,23 +6587,6 @@ static void P_MovePlayer(player_t *player) // MOVEMENT CODE // ////////////////////// - //{ SRB2kart slip net - - if (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] == 0) - { - K_SpinPlayer(player, NULL); // Here just for in-level oil spills now - } - // If you have one but not the other, we should get rid of the one we have - else if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_spinout] > 0) - player->kartstuff[k_spinout] = 0; - - // If somehow the power has gotten larger than the timer, it should be lowered back to it - if (player->kartstuff[k_spinouttimer] > player->kartstuff[k_spinout]) - player->kartstuff[k_spinouttimer] = player->kartstuff[k_spinout]; - - //} - - if (twodlevel || player->mo->flags2 & MF2_TWOD) // 2d-level, so special control applies. P_2dMovement(player); else @@ -6615,18 +6642,28 @@ static void P_MovePlayer(player_t *player) if (player->mo->state != &states[S_KART_SQUISH]) P_SetPlayerMobjState(player->mo, S_KART_SQUISH); } - else if (player->kartstuff[k_spinouttimer] > 0) + else if (player->kartstuff[k_spinouttimer] > 0 || player->pflags & PF_SLIDING) { if (player->mo->state != &states[S_KART_SPIN]) P_SetPlayerMobjState(player->mo, S_KART_SPIN); player->frameangle -= ANGLE_22h; } - else if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0) + else if (player->powers[pw_nocontrol] && player->pflags & PF_SKIDDOWN) + { + if (player->mo->state != &states[S_KART_SPIN]) + P_SetPlayerMobjState(player->mo, S_KART_SPIN); + + if (((player->powers[pw_nocontrol] + 5) % 20) < 10) + player->frameangle += ANGLE_11hh; + else + player->frameangle -= ANGLE_11hh; + } + else { K_KartMoveAnimation(player); - if (player->kartstuff[k_feather] & 2) + if (player->kartstuff[k_pogospring]) player->frameangle += ANGLE_22h; else player->frameangle = player->mo->angle; @@ -6922,9 +6959,15 @@ static void P_MovePlayer(player_t *player) //////////////////////////// // SRB2kart - Drifting smoke and fire - if (player->kartstuff[k_mushroomtimer] > 0 && onground && (leveltime & 1)) + if (player->kartstuff[k_sneakertimer] > 0 && onground && (leveltime & 1)) K_SpawnBoostTrail(player); + if (player->kartstuff[k_invincibilitytimer] > 0) + K_SpawnSparkleTrail(player->mo); + + if (player->kartstuff[k_wipeoutslow] > 1 && (leveltime & 1)) + K_SpawnWipeoutTrail(player->mo, false); + K_DriftDustHandling(player->mo); /* // SRB2kart - nadah @@ -7657,14 +7700,11 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) P_DamageMobj(mo, inflictor, source, 1); //{ SRB2kart - if (mo->type == MT_GREENITEM || mo->type == MT_REDITEM || mo->type == MT_REDITEMDUD - || mo->type == MT_GREENSHIELD || mo->type == MT_REDSHIELD - || mo->type == MT_TRIPLEGREENSHIELD1 || mo->type == MT_TRIPLEGREENSHIELD2 || mo->type == MT_TRIPLEGREENSHIELD3 - || mo->type == MT_TRIPLEREDSHIELD1 || mo->type == MT_TRIPLEREDSHIELD2 || mo->type == MT_TRIPLEREDSHIELD3 - || mo->type == MT_BANANAITEM || mo->type == MT_BANANASHIELD - || mo->type == MT_TRIPLEBANANASHIELD1 || mo->type == MT_TRIPLEBANANASHIELD2 || mo->type == MT_TRIPLEBANANASHIELD3 + if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ || mo->type == MT_JAWZ_DUD + || mo->type == MT_ORBINAUT_SHIELD || mo->type == MT_JAWZ_SHIELD + || mo->type == MT_BANANA || mo->type == MT_BANANA_SHIELD || mo->type == MT_FAKEITEM || mo->type == MT_FAKESHIELD - || mo->type == MT_FIREBALL) + || mo->type == MT_BALLHOG) { if (mo->eflags & MFE_VERTICALFLIP) mo->z -= mo->height; @@ -7682,7 +7722,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) continue; if (mo->type == MT_PLAYER) // Players wipe out in Kart - K_SpinPlayer(mo->player, source); + K_SpinPlayer(mo->player, source, 0, false); //} else P_DamageMobj(mo, inflictor, source, 1000); @@ -7852,44 +7892,34 @@ void P_FindEmerald(void) // static void P_DeathThink(player_t *player) { - ticcmd_t *cmd = &player->cmd; + //ticcmd_t *cmd = &player->cmd; //player->deltaviewheight = 0; if (player->deadtimer < INT32_MAX) player->deadtimer++; // continue logic - if (!(netgame || multiplayer) && player->lives <= 0) + /*if (!(netgame || multiplayer) && player->lives <= 0) { if (player->deadtimer > TICRATE && (cmd->buttons & BT_BRAKE || cmd->buttons & BT_ACCELERATE || cmd->buttons & BT_DRIFT) && player->continues > 0) G_UseContinue(); else if (player->deadtimer >= gameovertics) G_UseContinue(); // Even if we don't have one this handles ending the game - } + }*/ // Force respawn if idle for more than 30 seconds in shooter modes. - if (player->deadtimer > 30*TICRATE && !G_RaceGametype()) + /*if (player->deadtimer > 30*TICRATE && !G_RaceGametype()) player->playerstate = PST_REBORN; - else if (player->lives > 0 && !G_IsSpecialStage(gamemap) && leveltime >= 140) // Don't allow "click to respawn" in special stages! + else if (player->lives > 0 && !G_IsSpecialStage(gamemap)*/ + if (player->lives > 0 && leveltime >= starttime) // *could* you respawn? { - // SRB2kart-- But wait, why'd we add this? :eggthinking: - /*if (player->spectator) - { - CONS_Printf("%s entered the game.\n", player_names[player-players]); - player->spectator = false; - }*/ - - //player->kartstuff[k_lakitu] = 48; // See G_PlayerReborn in g_game.c - // SRB2kart - spawn automatically after 1 second - if (player->deadtimer > cv_respawntime.value*TICRATE) - player->playerstate = PST_REBORN; - - // Single player auto respawn - if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE) - player->playerstate = PST_REBORN; + if (player->deadtimer > ((netgame || multiplayer) + ? cv_respawntime.value*TICRATE + : TICRATE)) // don't let them change it in record attack + player->playerstate = PST_REBORN; } - else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE) + /*else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE) { // In a net/multiplayer game, and out of lives if (gametype == GT_COMPETITION) @@ -7925,13 +7955,11 @@ static void P_DeathThink(player_t *player) countdown2 = 1*TICRATE; skipstats = true; - /* // SRB2kart 010217 - Score doesn't need to be reset in Kart. for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) players[i].score = 0; } - */ //emeralds = 0; tokenbits = 0; @@ -7939,14 +7967,14 @@ static void P_DeathThink(player_t *player) token = 0; } } - } + }*/ // Keep time rolling - if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_TIMEOVER)) + if (!(countdown2 && !countdown) && !(player->exiting || mapreset) && !(player->pflags & PF_TIMEOVER)) { - if (leveltime >= 4*TICRATE) + if (leveltime >= starttime) { - player->realtime = leveltime - 4*TICRATE; + player->realtime = leveltime - starttime; if (player == &players[consoleplayer]) { if (player->spectator || !circuitmap) @@ -7963,8 +7991,12 @@ static void P_DeathThink(player_t *player) } } - if ((G_RaceGametype() || (gametype == GT_COOP && (multiplayer || netgame))) && (player->lives <= 0)) + /*if (G_RaceGametype() && (player->lives <= 0)) { + // to the lose music! + if (player->deadtimer == 4*TICRATE) + P_EndingMusic(player); + // stuff below isn't for kart // Return to level music if (netgame) { @@ -8001,7 +8033,7 @@ static void P_DeathThink(player_t *player) } } } - } + }*/ if (!player->mo) return; @@ -8106,9 +8138,9 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) x = player->mo->x - P_ReturnThrustX(player->mo, thiscam->angle, player->mo->radius); y = player->mo->y - P_ReturnThrustY(player->mo, thiscam->angle, player->mo->radius); if (player->mo->eflags & MFE_VERTICALFLIP) - z = player->mo->z + player->mo->height - (cv_viewheight.value<mo->z + player->mo->height - (32<mo->z + (cv_viewheight.value<mo->z + (32<x = x; @@ -8143,10 +8175,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall subsector_t *newsubsec; fixed_t f1, f2; - if (player->exiting) // SRB2Kart: Leave the camera behind while exiting, for dramatic effect! - return true; - - cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!! +#ifdef NOCLIPCAM + cameranoclip = true; // We like camera noclip! +#else + cameranoclip = ((player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) + || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) // Noclipping player camera noclips too!! + || (leveltime < introtime)); // Kart intro cam +#endif if (!(player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD)) { @@ -8188,6 +8223,11 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camrotate = cv_cam4_rotate.value; else camrotate = 0; + if (leveltime < introtime) // Whoooshy camera! + { + const INT32 introcam = (introtime - leveltime); + camrotate += introcam*5; + } thiscam->angle = focusangle + FixedAngle(camrotate*FRACUNIT); P_ResetCamera(player, thiscam); return true; @@ -8280,8 +8320,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall lookback = camspin4; } - // SRB2kart - Camera flipper - if (lookback) + if (leveltime < introtime) // Whoooshy camera! + { + const INT32 introcam = (introtime - leveltime); + camrotate += introcam*5; + camdist += (introcam * mapheaderinfo[gamemap-1]->mobj_scale)*3; + camheight += (introcam * mapheaderinfo[gamemap-1]->mobj_scale)*2; + } + else if (player->exiting) // SRB2Kart: Leave the camera behind while exiting, for dramatic effect! + camstill = true; + else if (lookback) // SRB2kart - Camera flipper { camrotate += 180; camspeed *= 2; @@ -8453,7 +8501,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } #endif // bad 2D camera code - pviewheight = FixedMul(cv_viewheight.value<scale); + pviewheight = FixedMul(32<scale); if (mo->eflags & MFE_VERTICALFLIP) z = mo->z + mo->height - pviewheight - camheight; @@ -8689,27 +8737,36 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } }*/ - if (twodlevel || (mo->flags2 & MF2_TWOD)) + if (player->exiting) { - thiscam->momx = x-thiscam->x; - thiscam->momy = y-thiscam->y; - thiscam->momz = z-thiscam->z; + thiscam->momx = 0; + thiscam->momy = 0; + thiscam->momz = 0; } else { - thiscam->momx = FixedMul(x - thiscam->x, camspeed); - thiscam->momy = FixedMul(y - thiscam->y, camspeed); - - if ((GETSECSPECIAL(thiscam->subsector->sector->special, 1) == 6 - && thiscam->z < thiscam->subsector->sector->floorheight + 256*FRACUNIT - && FixedMul(z - thiscam->z, camspeed) < 0) -#if 0 - || player->kartstuff[k_feather] & 2 // SRB2Kart: don't follow while bouncing, experimental -#endif - ) - thiscam->momz = 0; // Don't go down a death pit + if (twodlevel || (mo->flags2 & MF2_TWOD)) + { + thiscam->momx = x-thiscam->x; + thiscam->momy = y-thiscam->y; + thiscam->momz = z-thiscam->z; + } else - thiscam->momz = FixedMul(z - thiscam->z, camspeed); + { + thiscam->momx = FixedMul(x - thiscam->x, camspeed); + thiscam->momy = FixedMul(y - thiscam->y, camspeed); + + if ((GETSECSPECIAL(thiscam->subsector->sector->special, 1) == 6 + && thiscam->z < thiscam->subsector->sector->floorheight + 256*FRACUNIT + && FixedMul(z - thiscam->z, camspeed) < 0) +#if 0 + || player->kartstuff[k_pogospring] // SRB2Kart: don't follow while bouncing, experimental +#endif + ) + thiscam->momz = 0; // Don't go down a death pit + else + thiscam->momz = FixedMul(z - thiscam->z, camspeed); + } } // compute aming to look the viewed point @@ -8792,20 +8849,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall boolean P_SpectatorJoinGame(player_t *player) { - if (!G_GametypeHasSpectators() && G_IsSpecialStage(gamemap) && useNightsSS) // Special Stage spectators should NEVER be allowed to rejoin the game - { - if (P_IsLocalPlayer(player)) - CONS_Printf(M_GetText("You cannot enter the game while a special stage is in progress.\n")); - player->powers[pw_flashing] += 2*TICRATE; //to prevent message spam. - } - - else if (!cv_allowteamchange.value) + // Team changing isn't allowed. + if (!cv_allowteamchange.value) { if (P_IsLocalPlayer(player)) CONS_Printf(M_GetText("Server does not allow team change.\n")); - player->powers[pw_flashing] += 2*TICRATE; //to prevent message spam. + //player->powers[pw_flashing] = TICRATE + 1; //to prevent message spam. } - // Team changing in Team Match and CTF // Pressing fire assigns you to a team that needs players if allowed. // Partial code reproduction from p_tick.c autobalance code. @@ -8842,6 +8892,7 @@ boolean P_SpectatorJoinGame(player_t *player) player->mo = NULL; } player->spectator = false; + player->pflags &= ~PF_WANTSTOJOIN; player->ctfteam = changeto; player->playerstate = PST_REBORN; @@ -8859,43 +8910,21 @@ boolean P_SpectatorJoinGame(player_t *player) // Joining in game from firing. else { - // Exception for hide and seek. Don't join a game when you simply - // respawn in place and sit there for the rest of the round. - if (!(gametype == GT_HIDEANDSEEK && leveltime > (hidetime * TICRATE))) + if (player->mo) { - if (player->mo) - { - P_RemoveMobj(player->mo); - player->mo = NULL; - } - player->spectator = false; - player->playerstate = PST_REBORN; - - if (gametype == GT_TAG) - { - //Make joining players "it" after hidetime. - if (leveltime > (hidetime * TICRATE)) - { - CONS_Printf(M_GetText("%s is now IT!\n"), player_names[player-players]); // Tell everyone who is it! - player->pflags |= PF_TAGIT; - } - - P_CheckSurvivors(); - } - - //Reset away view - if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) - displayplayer = consoleplayer; - - CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); - return true; // no more player->mo, cannot continue. - } - else - { - if (P_IsLocalPlayer(player)) - CONS_Printf(M_GetText("You must wait until next round to enter the game.\n")); - player->powers[pw_flashing] += 2*TICRATE; //to prevent message spam. + P_RemoveMobj(player->mo); + player->mo = NULL; } + player->spectator = false; + player->pflags &= ~PF_WANTSTOJOIN; + player->playerstate = PST_REBORN; + + //Reset away view + if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) + displayplayer = consoleplayer; + + CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); + return true; // no more player->mo, cannot continue. } return false; } @@ -9037,6 +9066,36 @@ static void P_CalcPostImg(player_t *player) } }*/ +void P_DoTimeOver(player_t *player) +{ + if (netgame && player->health > 0) + CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]); + + player->pflags |= PF_TIMEOVER; + + if ((player == &players[consoleplayer] + || (splitscreen && player == &players[secondarydisplayplayer]) + || (splitscreen > 1 && player == &players[thirddisplayplayer]) + || (splitscreen > 2 && player == &players[fourthdisplayplayer])) + && !demoplayback) + legitimateexit = true; // SRB2kart: losing a race is still seeing it through to the end :p + + if (player->mo) + { + S_StopSound(player->mo); + P_DamageMobj(player->mo, NULL, NULL, 10000); + } + player->lives = 0; + + P_EndingMusic(player); + +#if 0 + // sal, when you do the f-zero explosion, this is how you make sure the map doesn't end before it's done ^u^ ~toast + if (!countdown2) + countdown2 = 5*TICRATE; +#endif +} + // // P_PlayerThink // @@ -9127,101 +9186,84 @@ void P_PlayerThink(player_t *player) I_Error("player %s is in PST_REBORN\n", sizeu1(playeri)); #endif - if (G_RaceGametype()) + if (!mapreset) { - INT32 i; - - // Check if all the players in the race have finished. If so, end the level. - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator) - { - if (!players[i].exiting && players[i].lives > 0) - break; - } - } - - if (i == MAXPLAYERS && player->exiting == 3*TICRATE) // finished - player->exiting = (14*TICRATE)/5 + 1; - - // If 10 seconds are left on the timer, - // begin the drown music for countdown! - /* - if (countdown == 11*TICRATE - 1) - { - if (P_IsLocalPlayer(player)) - S_ChangeMusicInternal("drown", false); - } - - // If you've hit the countdown and you haven't made - // it to the exit, you're a goner! - else */ - if (countdown == 1 && !player->exiting && !player->spectator && player->lives > 0) - { - if (netgame && player->health > 0) - CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]); - - player->pflags |= PF_TIMEOVER; - - if ((player == &players[consoleplayer] - || (splitscreen && player == &players[secondarydisplayplayer]) - || (splitscreen > 1 && player == &players[thirddisplayplayer]) - || (splitscreen > 2 && player == &players[fourthdisplayplayer])) - && !demoplayback) - legitimateexit = true; // SRB2kart: losing a race is still seeing it through to the end :p - - if (player->pflags & PF_NIGHTSMODE) - { - P_DeNightserizePlayer(player); - S_StartScreamSound(player->mo, sfx_s3k66); - } - - player->lives = 2; // Don't start the game over music! - P_DamageMobj(player->mo, NULL, NULL, 10000); - player->lives = 0; - - if (player->playerstate == PST_DEAD) - return; - } - } - - // If it is set, start subtracting - // Don't allow it to go back to 0 - if (player->exiting > 1 && (player->exiting < 3*TICRATE || !G_RaceGametype())) // SRB2kart - "&& player->exiting > 1" - player->exiting--; - - if (player->exiting && countdown2) - player->exiting = 99; // SRB2kart - - if (player->exiting == 2 || countdown2 == 2) - { - if (cv_playersforexit.value) // Count to be sure everyone's exited + if (G_RaceGametype()) { INT32 i; + // Check if all the players in the race have finished. If so, end the level. for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator || players[i].bot) - continue; - if (players[i].lives <= 0) - continue; - - if (!players[i].exiting || players[i].exiting > 3) - break; + if (playeringame[i] && !players[i].spectator) + { + if (!players[i].exiting && players[i].lives > 0) + break; + } } - if (i == MAXPLAYERS) + if (i == MAXPLAYERS && player->exiting == 3*TICRATE) // finished + player->exiting = (14*TICRATE)/5 + 1; + + // If 10 seconds are left on the timer, + // begin the drown music for countdown! + + // SRB2Kart: despite how perfect this is, it's disabled FOR A REASON + /*if (countdown == 11*TICRATE - 1) + { + if (P_IsLocalPlayer(player)) + S_ChangeMusicInternal("drown", false); + }*/ + + // If you've hit the countdown and you haven't made + // it to the exit, you're a goner! + else if (countdown == 1 && !player->exiting && !player->spectator && player->lives > 0) + { + P_DoTimeOver(player); + + if (player->playerstate == PST_DEAD) + return; + } + } + + // If it is set, start subtracting + // Don't allow it to go back to 0 + if (player->exiting > 1 && (player->exiting < 3*TICRATE || !G_RaceGametype())) // SRB2kart - "&& player->exiting > 1" + player->exiting--; + + if (player->exiting && countdown2) + player->exiting = 99; // SRB2kart + + if (player->exiting == 2 || countdown2 == 2) + { + if (cv_playersforexit.value) // Count to be sure everyone's exited + { + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator || players[i].bot) + continue; + if (players[i].lives <= 0) + continue; + + if (!players[i].exiting || players[i].exiting > 3) + break; + } + + if (i == MAXPLAYERS) + { + if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0); + } + else + player->exiting = 3; + } + else { if (server) SendNetXCmd(XD_EXITLEVEL, NULL, 0); } - else - player->exiting = 3; - } - else - { - if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); } } @@ -9259,18 +9301,22 @@ void P_PlayerThink(player_t *player) player->health = 1; } +#if 0 if ((netgame || multiplayer) && player->lives <= 0) { // In Co-Op, replenish a user's lives if they are depleted. // of course, this is just a cheap hack, meh... player->lives = cv_startinglives.value; } +#else + player->lives = 1; // SRB2Kart +#endif if (player == &players[displayplayer]) playerdeadview = false; // SRB2kart 010217 - if (leveltime < 4*TICRATE) + if (leveltime < starttime) player->powers[pw_nocontrol] = 2; /* if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) @@ -9284,9 +9330,9 @@ void P_PlayerThink(player_t *player) // Synchronizes the "real" amount of time spent in the level. if (!player->exiting) { - if (leveltime >= 4*TICRATE) + if (leveltime >= starttime) { - player->realtime = leveltime - 4*TICRATE; + player->realtime = leveltime - starttime; if (player == &players[consoleplayer]) { if (player->spectator || !circuitmap) @@ -9305,8 +9351,10 @@ void P_PlayerThink(player_t *player) if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) { - if (P_SpectatorJoinGame(player)) - return; // player->mo was removed. + player->pflags ^= PF_WANTSTOJOIN; + //player->powers[pw_flashing] = TICRATE + 1; + /*if (P_SpectatorJoinGame(player)) + return; // player->mo was removed.*/ } // Even if not NiGHTS, pull in nearby objects when walking around as John Q. Elliot. @@ -9393,16 +9441,16 @@ void P_PlayerThink(player_t *player) #endif //P_DoSuperStuff(player); - P_CheckSneakerAndLivesTimer(player); + //P_CheckSneakerAndLivesTimer(player); P_DoBubbleBreath(player); // Spawn Sonic's bubbles - P_CheckUnderwaterAndSpaceTimer(player); // Display the countdown drown numbers! + //P_CheckUnderwaterAndSpaceTimer(player); // Display the countdown drown numbers! P_CheckInvincibilityTimer(player); // Spawn Invincibility Sparkles P_DoPlayerHeadSigns(player); // Spawn Tag/CTF signs over player's head #if 1 // "Blur" a bit when you have speed shoes and are going fast enough if ((player->powers[pw_super] || player->powers[pw_sneakers] - || player->kartstuff[k_driftboost] || player->kartstuff[k_mushroomtimer]) && !player->kartstuff[k_startimer] // SRB2kart + || player->kartstuff[k_driftboost] || player->kartstuff[k_sneakertimer]) && !player->kartstuff[k_invincibilitytimer] // SRB2kart && (player->speed + abs(player->mo->momz)) > FixedMul(20*FRACUNIT,player->mo->scale)) { mobj_t *gmobj = P_SpawnGhostMobj(player->mo); @@ -9457,12 +9505,14 @@ void P_PlayerThink(player_t *player) if (player->powers[pw_invulnerability] && player->powers[pw_invulnerability] < UINT16_MAX) player->powers[pw_invulnerability]--; - if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) || player->powers[pw_flashing] < K_GetKartFlashing())) + if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) + || (player->spectator || player->powers[pw_flashing] < K_GetKartFlashing()))) player->powers[pw_flashing]--; if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter player->powers[pw_tailsfly]--; + /* // SRB2kart - Can't drown. if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)) { if (player->powers[pw_underwater] <= 12*TICRATE+1) @@ -9477,6 +9527,7 @@ void P_PlayerThink(player_t *player) player->powers[pw_spacetime] = 0; else if (player->powers[pw_spacetime] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer player->powers[pw_spacetime]--; + */ if (player->powers[pw_gravityboots] && player->powers[pw_gravityboots] < UINT16_MAX) player->powers[pw_gravityboots]--; @@ -9494,7 +9545,10 @@ void P_PlayerThink(player_t *player) player->powers[pw_nights_helper]--; if (player->powers[pw_nocontrol] & ((1<<15)-1) && player->powers[pw_nocontrol] < UINT16_MAX) - player->powers[pw_nocontrol]--; + { + if (!(--player->powers[pw_nocontrol])) + player->pflags &= ~PF_SKIDDOWN; + } else player->powers[pw_nocontrol] = 0; @@ -9542,21 +9596,17 @@ void P_PlayerThink(player_t *player) player->losstime--; // Flash player after being hit. - if (!(player->pflags & PF_NIGHTSMODE)) + if (!(player->pflags & PF_NIGHTSMODE + || player->kartstuff[k_hyudorotimer] // SRB2kart - fixes Hyudoro not flashing when it should. + || player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either. + || (G_BattleGametype() && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) + || leveltime < starttime)) // Level intro { - // SRB2kart - fixes boo not flashing when it should. Mega doesn't flash either. Flashing is local. - if ((player == &players[displayplayer] - || (splitscreen && player == &players[secondarydisplayplayer]) - || (splitscreen > 1 && player == &players[thirddisplayplayer]) - || (splitscreen > 2 && player == &players[fourthdisplayplayer])) - && player->kartstuff[k_bootimer] == 0 && player->kartstuff[k_growshrinktimer] <= 0 - && (player->kartstuff[k_comebacktimer] == 0 || (G_RaceGametype() || player->kartstuff[k_balloon] > 0))) - { - if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing() && (leveltime & 1)) - player->mo->flags2 |= MF2_DONTDRAW; - else - player->mo->flags2 &= ~MF2_DONTDRAW; - } + if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing() + && (leveltime & 1)) + player->mo->flags2 |= MF2_DONTDRAW; + else + player->mo->flags2 &= ~MF2_DONTDRAW; } else if (player->mo->tracer) { @@ -9938,7 +9988,7 @@ void P_PlayerAfterThink(player_t *player) { // defaults to make sure 1st person cam doesn't do anything weird on startup //player->deltaviewheight = 0; - player->viewheight = FixedMul(cv_viewheight.value << FRACBITS, player->mo->scale); + player->viewheight = FixedMul(32 << FRACBITS, player->mo->scale); if (player->mo->eflags & MFE_VERTICALFLIP) player->viewz = player->mo->z + player->mo->height - player->viewheight; else diff --git a/src/r_bsp.c b/src/r_bsp.c index 234d6ee0..56f159c2 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -855,7 +855,7 @@ static void R_AddPolyObjects(subsector_t *sub) drawseg_t *firstseg; -static void R_Subsector(size_t num, UINT8 ssplayer) +static void R_Subsector(size_t num, UINT8 viewnumber) { INT32 count, floorlightlevel, ceilinglightlevel, light; seg_t *line; @@ -1213,7 +1213,7 @@ static void R_Subsector(size_t num, UINT8 ssplayer) // Either you must pass the fake sector and handle validcount here, on the // real sector, or you must account for the lighting in some other way, // like passing it as an argument. - R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2, ssplayer); + R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2, viewnumber); firstseg = NULL; @@ -1419,7 +1419,7 @@ INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside) // // killough 5/2/98: reformatted, removed tail recursion -void R_RenderBSPNode(INT32 bspnum, UINT8 ssplayer) +void R_RenderBSPNode(INT32 bspnum, UINT8 viewnumber) { node_t *bsp; INT32 side; @@ -1430,7 +1430,7 @@ void R_RenderBSPNode(INT32 bspnum, UINT8 ssplayer) // Decide which side the view point is on. side = R_PointOnSide(viewx, viewy, bsp); // Recursively divide front space. - R_RenderBSPNode(bsp->children[side], ssplayer); + R_RenderBSPNode(bsp->children[side], viewnumber); // Possibly divide back space. @@ -1448,5 +1448,5 @@ void R_RenderBSPNode(INT32 bspnum, UINT8 ssplayer) portalcullsector = NULL; } - R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR, ssplayer); + R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR, viewnumber); } diff --git a/src/r_bsp.h b/src/r_bsp.h index db340221..f493a8a6 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -37,7 +37,7 @@ extern INT32 doorclosed; void R_ClearClipSegs(void); void R_PortalClearClipSegs(INT32 start, INT32 end); void R_ClearDrawSegs(void); -void R_RenderBSPNode(INT32 bspnum, UINT8 ssplayer); +void R_RenderBSPNode(INT32 bspnum, UINT8 viewnumber); void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); #ifdef POLYOBJECTS diff --git a/src/r_draw.c b/src/r_draw.c index 5560ffa0..60927434 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -135,7 +135,7 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define BOSS_TT_CACHE_INDEX (MAXSKINS + 1) #define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2) #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3) -#define STARMAN_TT_CACHE_INDEX (MAXSKINS + 4) +#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4) #define SKIN_RAMP_LENGTH 16 #define DEFAULT_STARTTRANSCOLOR 160 #define NUM_PALETTE_ENTRIES 256 @@ -155,7 +155,7 @@ const char *Color_Names[MAXSKINCOLORS] = "Black", // SKINCOLOR_BLACK "Cyan", // SKINCOLOR_CYAN "Teal", // SKINCOLOR_TEAL - "Steel_Blue",// SKINCOLOR_STEELBLUE + "Steel_Blue",// SKINCOLOR_STEEL "Blue", // SKINCOLOR_BLUE "Peach", // SKINCOLOR_PEACH "Tan", // SKINCOLOR_TAN @@ -175,7 +175,6 @@ const char *Color_Names[MAXSKINCOLORS] = "Yellow", // SKINCOLOR_YELLOW "Gold" // SKINCOLOR_GOLD }; -*/ const UINT8 Color_Opposite[MAXSKINCOLORS*2] = { @@ -186,7 +185,7 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] = SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK SKINCOLOR_NONE,8, // SKINCOLOR_CYAN SKINCOLOR_NONE,8, // SKINCOLOR_TEAL - SKINCOLOR_NONE,8, // SKINCOLOR_STEELBLUE + SKINCOLOR_NONE,8, // SKINCOLOR_STEEL SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE SKINCOLOR_NONE,8, // SKINCOLOR_PEACH SKINCOLOR_NONE,8, // SKINCOLOR_TAN @@ -206,6 +205,7 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] = SKINCOLOR_NONE,8, // SKINCOLOR_YELLOW SKINCOLOR_NONE,8 // SKINCOLOR_GOLD }; +*/ CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; @@ -257,7 +257,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U 0x18, // SKINCOLOR_BLACK 0xd0, // SKINCOLOR_CYAN 0xdc, // SKINCOLOR_TEAL - 0xc8, // SKINCOLOR_STEELBLUE + 0xc8, // SKINCOLOR_STEEL 0xe2, // SKINCOLOR_BLUE 0x40, // SKINCOLOR_PEACH 0x48, // SKINCOLOR_TAN @@ -339,7 +339,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U case SKINCOLOR_WHITE: case SKINCOLOR_BLACK: - case SKINCOLOR_STEELBLUE: + case SKINCOLOR_STEEL: case SKINCOLOR_PINK: case SKINCOLOR_LAVENDER: case SKINCOLOR_PURPLE: @@ -529,7 +529,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) else if (skinnum == TC_BOSS) skintableindex = BOSS_TT_CACHE_INDEX; else if (skinnum == TC_METALSONIC) skintableindex = METALSONIC_TT_CACHE_INDEX; else if (skinnum == TC_ALLWHITE) skintableindex = ALLWHITE_TT_CACHE_INDEX; - else if (skinnum == TC_STARMAN) skintableindex = STARMAN_TT_CACHE_INDEX; + else if (skinnum == TC_RAINBOW) skintableindex = RAINBOW_TT_CACHE_INDEX; else skintableindex = skinnum; if (flags & GTC_CACHE) diff --git a/src/r_draw.h b/src/r_draw.h index ae70cd8a..3199f0f6 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -107,7 +107,7 @@ extern lumpnum_t viewborderlump[8]; #define TC_BOSS -2 #define TC_METALSONIC -3 // For Metal Sonic battle #define TC_ALLWHITE -4 // For Cy-Brak-demon -#define TC_STARMAN -5 // For star power +#define TC_RAINBOW -5 // For invincibility power // Initialize color translation tables, for player rendering etc. void R_InitTranslationTables(void); diff --git a/src/r_main.c b/src/r_main.c index c516b87a..5990224c 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -170,7 +170,7 @@ consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_con consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // Okay, whoever said homremoval causes a performance hit should be shot. -consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_maxportals = {"maxportals", "2", CV_SAVE, maxportals_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -213,7 +213,6 @@ void SplitScreen_OnChange(void) } else { - INT32 i; secondarydisplayplayer = consoleplayer; thirddisplayplayer = consoleplayer; fourthdisplayplayer = consoleplayer; @@ -1335,28 +1334,43 @@ void R_RenderPlayerView(player_t *player) { portal_pair *portal; const boolean skybox = (skyboxmo[0] && cv_skybox.value); - UINT8 ssplayer; + UINT8 viewnumber; if (player == &players[secondarydisplayplayer] && splitscreen) - ssplayer = 2; + viewnumber = 1; else if (player == &players[thirddisplayplayer] && splitscreen > 1) - ssplayer = 3; + viewnumber = 2; else if (player == &players[fourthdisplayplayer] && splitscreen > 2) - ssplayer = 4; - else if (splitscreen) - ssplayer = 1; + viewnumber = 3; else - ssplayer = 0; + viewnumber = 0; - if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1 + // if this is display player 1 + if (cv_homremoval.value && player == &players[displayplayer]) { if (cv_homremoval.value == 1) V_DrawFill(0, 0, vid.width, vid.height, 31); // No HOM effect! else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. V_DrawFill(0, 0, vid.width, vid.height, 128+(timeinmap&15)); } + // Draw over the fourth screen so you don't have to stare at a HOM :V else if (splitscreen == 2 && player == &players[thirddisplayplayer]) - V_DrawFill(viewwidth, viewheight, viewwidth, viewheight, 31|V_NOSCALESTART); // Draw over the fourth screen so you don't have to stare at a HOM :V +#if 1 + { + // V_DrawPatchFill, but for the fourth screen only + patch_t *pat = W_CachePatchName("SRB2BACK", PU_CACHE); + INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); + INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; + + for (x = vid.width>>1; x < vid.width; x += pw) + { + for (y = vid.height>>1; y < vid.height; y += ph) + V_DrawScaledPatch(x, y, V_NOSCALESTART, pat); + } + } +#else + V_DrawFill(viewwidth, viewheight, viewwidth, viewheight, 31|V_NOSCALESTART); +#endif // load previous saved value of skyVisible for the player if (splitscreen > 2 && player == &players[fourthdisplayplayer]) @@ -1383,7 +1397,7 @@ void R_RenderPlayerView(player_t *player) R_ClearVisibleFloorSplats(); #endif - R_RenderBSPNode((INT32)numnodes - 1, ssplayer); + R_RenderBSPNode((INT32)numnodes - 1, viewnumber); R_ClipSprites(); R_DrawPlanes(); #ifdef FLOORSPLATS @@ -1416,7 +1430,7 @@ void R_RenderPlayerView(player_t *player) mytotal = 0; ProfZeroTimer(); #endif - R_RenderBSPNode((INT32)numnodes - 1, ssplayer); + R_RenderBSPNode((INT32)numnodes - 1, viewnumber); R_ClipSprites(); #ifdef TIMING RDMSR(0x10, &mycount); @@ -1441,7 +1455,7 @@ void R_RenderPlayerView(player_t *player) validcount++; - R_RenderBSPNode((INT32)numnodes - 1, ssplayer); + R_RenderBSPNode((INT32)numnodes - 1, viewnumber); R_ClipSprites(); //R_DrawPlanes(); //R_DrawMasked(); @@ -1548,7 +1562,7 @@ void R_RegisterEngineStuff(void) // Default viewheight is changeable, // initialized to standard viewheight - CV_RegisterVar(&cv_viewheight); + //CV_RegisterVar(&cv_viewheight); #ifdef HWRENDER // GL-specific Commands diff --git a/src/r_plane.c b/src/r_plane.c index 3ec97efb..92e0cacb 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -714,6 +714,7 @@ void R_DrawPlanes(void) if (dc_yl <= dc_yh) { angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; + dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); dc_x = x; dc_source = R_GetColumn(skytexture, diff --git a/src/r_plane.h b/src/r_plane.h index 16c8c12a..dff58669 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -87,7 +87,7 @@ extern lighttable_t **planezlight; extern fixed_t *yslope; extern fixed_t distscale[MAXVIDWIDTH]; -FUNCMATH void R_InitPlanes(void); +void R_InitPlanes(void); void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_ClearPlanes(void); diff --git a/src/r_segs.c b/src/r_segs.c index b997c2a8..025c920c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2674,22 +2674,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldbottomslope >>= 4; #endif - topstep = -FixedMul (rw_scalestep, worldtop); - topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); + if (linedef->special == 41) { // HORIZON LINES + topstep = bottomstep = 0; + topfrac = bottomfrac = (centeryfrac>>4); + topfrac++; // Prevent 1px HOM + } else { + topstep = -FixedMul (rw_scalestep, worldtop); + topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); - bottomstep = -FixedMul (rw_scalestep,worldbottom); - bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); + bottomstep = -FixedMul (rw_scalestep,worldbottom); + bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); #ifdef ESLOPE - if (frontsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); - topstep = (topfracend-topfrac)/(range); - } - if (frontsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); - bottomstep = (bottomfracend-bottomfrac)/(range); - } + if (frontsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); + topstep = (topfracend-topfrac)/(range); + } + if (frontsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); + bottomstep = (bottomfracend-bottomfrac)/(range); + } #endif + } dc_numlights = 0; diff --git a/src/r_splats.h b/src/r_splats.h index c0ba6881..24cfcd13 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -64,7 +64,7 @@ fixed_t P_SegLength(seg_t *seg); // call at P_SetupLevel() #if !(defined (WALLSPLATS) || defined (FLOORSPLATS)) -FUNCMATH void R_ClearLevelSplats(void); +void R_ClearLevelSplats(void); #else void R_ClearLevelSplats(void); #endif diff --git a/src/r_things.c b/src/r_things.c index 7309f452..ae935897 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -826,15 +826,12 @@ static void R_DrawVisSprite(vissprite_t *vis) { colfunc = transtransfunc; dc_transmap = vis->transmap; - if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> + if (vis->mobj->colorized) + dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); + else if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> { - if (vis->mobj->colorized) - dc_translation = R_GetTranslationColormap(TC_STARMAN, vis->mobj->color, GTC_CACHE); - else - { - size_t skinnum = (skin_t*)vis->mobj->skin-skins; - dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); - } + size_t skinnum = (skin_t*)vis->mobj->skin-skins; + dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); } else // Use the defaults dc_translation = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color, GTC_CACHE); @@ -850,15 +847,12 @@ static void R_DrawVisSprite(vissprite_t *vis) colfunc = transcolfunc; // New colormap stuff for skins Tails 06-07-2002 - if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! + if (vis->mobj->colorized) + dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); + else if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { - if (vis->mobj->colorized) - dc_translation = R_GetTranslationColormap(TC_STARMAN, vis->mobj->color, GTC_CACHE); - else - { - size_t skinnum = (skin_t*)vis->mobj->skin-skins; - dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); - } + size_t skinnum = (skin_t*)vis->mobj->skin-skins; + dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); } else // Use the defaults dc_translation = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color, GTC_CACHE); @@ -1676,7 +1670,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // R_AddSprites // During BSP traversal, this adds sprites by sector. // -void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 ssplayer) +void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber) { mobj_t *thing; precipmobj_t *precipthing; // Tails 08-25-2002 @@ -1722,19 +1716,19 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 ssplayer) if (splitscreen) { if (thing->eflags & MFE_DRAWONLYFORP1) - if (ssplayer != 1) + if (viewnumber != 0) continue; if (thing->eflags & MFE_DRAWONLYFORP2) - if (ssplayer != 2) + if (viewnumber != 1) continue; if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) - if (ssplayer != 3) + if (viewnumber != 2) continue; if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) - if (ssplayer != 4) + if (viewnumber != 3) continue; } @@ -1755,19 +1749,19 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 ssplayer) if (splitscreen) { if (thing->eflags & MFE_DRAWONLYFORP1) - if (ssplayer != 1) + if (viewnumber != 0) continue; if (thing->eflags & MFE_DRAWONLYFORP2) - if (ssplayer != 2) + if (viewnumber != 1) continue; if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) - if (ssplayer != 3) + if (viewnumber != 2) continue; if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) - if (ssplayer != 4) + if (viewnumber != 3) continue; } @@ -2502,9 +2496,9 @@ static void Sk_SetDefaultValue(skin_t *skin) strcpy(skin->realname, "Someone"); strcpy(skin->hudname, "???"); - strncpy(skin->charsel, "CHRSONIC", 8); - strncpy(skin->face, "MISSING", 8); - strncpy(skin->superface, "MISSING", 8); + strncpy(skin->charsel, "CHRSONIC", 9); + strncpy(skin->face, "MISSING", 9); + strncpy(skin->superface, "MISSING", 9); skin->starttranscolor = 160; skin->prefcolor = SKINCOLOR_GREEN; @@ -2536,7 +2530,7 @@ static void Sk_SetDefaultValue(skin_t *skin) for (i = 0; i < sfx_skinsoundslot0; i++) if (S_sfx[i].skinsound != -1) skin->soundsid[S_sfx[i].skinsound] = i; - strncpy(skin->iconprefix, "SONICICN", 8); + strncpy(skin->iconprefix, "SONICICN", 9); } // @@ -2569,9 +2563,9 @@ void R_InitSkins(void) strcpy(skin->realname, "Sonic"); strcpy(skin->hudname, "SONIC"); - strncpy(skin->charsel, "CHRSONIC", 8); - strncpy(skin->face, "LIVSONIC", 8); - strncpy(skin->superface, "LIVSUPER", 8); + strncpy(skin->charsel, "CHRSONIC", 9); + strncpy(skin->face, "LIVSONIC", 9); + strncpy(skin->superface, "LIVSUPER", 9); skin->prefcolor = SKINCOLOR_BLUE; skin->ability = CA_THOK; @@ -2591,7 +2585,7 @@ void R_InitSkins(void) skin->spritedef.numframes = sprites[SPR_PLAY].numframes; skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes; ST_LoadFaceGraphics(skin->face, skin->superface, 0); - strncpy(skin->iconprefix, "SONICICN", 8); + strncpy(skin->iconprefix, "SONICICN", 9); K_LoadIconGraphics(skin->iconprefix, 0); //MD2 for sonic doesn't want to load in Linux. diff --git a/src/r_things.h b/src/r_things.h index c7d4989c..a037b873 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -55,7 +55,7 @@ void R_DelSpriteDefs(UINT16 wadnum); #endif //SoM: 6/5/2000: Light sprites correctly! -void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 ssplayer); +void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber); void R_InitSprites(void); void R_ClearSprites(void); void R_ClipSprites(void); @@ -81,7 +81,7 @@ typedef struct char realname[SKINNAMESIZE+1]; // Display name for level completion. char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long) - char charsel[8], face[8], superface[8]; // Arbitrarily named patch lumps + char charsel[9], face[9], superface[9]; // Arbitrarily named patch lumps UINT8 ability; // ability definition UINT8 ability2; // secondary ability definition diff --git a/src/s_sound.c b/src/s_sound.c index 157c06ee..44e7e7ae 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -80,7 +80,7 @@ static consvar_t precachesound = {"precachesound", "Off", CV_SAVE, CV_OnOff, NUL // actual general (maximum) sound & music volume, saved into the config consvar_t cv_soundvolume = {"soundvolume", "31", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_digmusicvolume = {"digmusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +//consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // number of channels available #if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) consvar_t cv_numChannels = {"snd_channels", "8", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; @@ -88,7 +88,7 @@ consvar_t cv_numChannels = {"snd_channels", "8", CV_SAVE|CV_CALL, CV_Unsigned, S consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; #endif -static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #define S_MAX_VOLUME 127 @@ -846,7 +846,7 @@ void S_StopSound(void *origin) // static INT32 actualsfxvolume; // check for change through console static INT32 actualdigmusicvolume; -static INT32 actualmidimusicvolume; +//static INT32 actualmidimusicvolume; void S_UpdateSounds(void) { @@ -873,8 +873,8 @@ void S_UpdateSounds(void) S_SetSfxVolume (cv_soundvolume.value); if (actualdigmusicvolume != cv_digmusicvolume.value) S_SetDigMusicVolume (cv_digmusicvolume.value); - if (actualmidimusicvolume != cv_midimusicvolume.value) - S_SetMIDIMusicVolume (cv_midimusicvolume.value); + //if (actualmidimusicvolume != cv_midimusicvolume.value) + //S_SetMIDIMusicVolume (cv_midimusicvolume.value); // We're done now, if we're not in a level. if (gamestate != GS_LEVEL) @@ -1438,7 +1438,7 @@ void S_StartSoundName(void *mo, const char *soundname) /// ------------------------ #ifdef MUSICSLOT_COMPATIBILITY -const char *compat_special_music_slots[21] = +const char *compat_special_music_slots[16] = { "titles", // 1036 title screen "read_m", // 1037 intro @@ -1455,12 +1455,6 @@ const char *compat_special_music_slots[21] = "credit", // 1048 credits "racent", // 1049 Race Results "stjr", // 1050 Sonic Team Jr. Presents - // SRB2kart 040217 - "finlap", // 1051 Sonic Team Jr. Presents - "karwin", // 1052 Sonic Team Jr. Presents - "karok", // 1053 Sonic Team Jr. Presents - "karlos", // 1054 Sonic Team Jr. Presents - "mega", // 1055 Sonic Team Jr. Presents "" }; #endif @@ -1476,16 +1470,22 @@ static boolean mus_paused = 0; // whether songs are mus_paused static boolean S_MIDIMusic(const char *mname, boolean looping) { - lumpnum_t mlumpnum; + /*lumpnum_t mlumpnum; void *mdata; - INT32 mhandle; + INT32 mhandle;*/ - if (nomidimusic || music_disabled) + (void)looping; + + if (/*nomidimusic || */music_disabled) return false; // didn't search. if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR) return false; - mlumpnum = W_GetNumForName(va("d_%s", mname)); + + CONS_Alert(CONS_ERROR, "A MIDI Music lump %.6s was found,\nbut SRB2Kart does not support MIDI output.\nWe apologise for the inconvenience.\n", mname); + return false; + + /*mlumpnum = W_GetNumForName(va("d_%s", mname)); // load & register it mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC); @@ -1512,7 +1512,7 @@ static boolean S_MIDIMusic(const char *mname, boolean looping) music_lumpnum = mlumpnum; music_data = mdata; music_handle = mhandle; - return true; + return true;*/ } static boolean S_DigMusic(const char *mname, boolean looping) @@ -1601,7 +1601,7 @@ void S_SetDigMusicVolume(INT32 volume) I_SetDigMusicVolume(volume&31); } -void S_SetMIDIMusicVolume(INT32 volume) +/*void S_SetMIDIMusicVolume(INT32 volume) { if (volume < 0 || volume > 31) CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); @@ -1613,7 +1613,7 @@ void S_SetMIDIMusicVolume(INT32 volume) I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. #endif I_SetMIDIMusicVolume(volume&0x1f); -} +}*/ /// ------------------------ /// Init & Others @@ -1624,7 +1624,7 @@ void S_SetMIDIMusicVolume(INT32 volume) // Sets channels, SFX and music volume, // allocates channel buffer, sets S_sfx lookup. // -void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume) +void S_Init(INT32 sfxVolume, INT32 digMusicVolume) { INT32 i; @@ -1633,7 +1633,7 @@ void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume) S_SetSfxVolume(sfxVolume); S_SetDigMusicVolume(digMusicVolume); - S_SetMIDIMusicVolume(midiMusicVolume); + //S_SetMIDIMusicVolume(midiMusicVolume); SetChannelsNum(); diff --git a/src/s_sound.h b/src/s_sound.h index 708251a5..3561de80 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -23,8 +23,9 @@ #define PICKUP_SOUND 0x8000 extern consvar_t stereoreverse; -extern consvar_t cv_soundvolume, cv_digmusicvolume, cv_midimusicvolume; +extern consvar_t cv_soundvolume, cv_digmusicvolume;//, cv_midimusicvolume; extern consvar_t cv_numChannels; +extern consvar_t surround; #ifdef SNDSERV extern consvar_t sndserver_cmd, sndserver_arg; @@ -71,7 +72,7 @@ void S_RegisterSoundStuff(void); // Initializes sound stuff, including volume // Sets channels, SFX and music volume, allocates channel buffer, sets S_sfx lookup. // -void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume); +void S_Init(INT32 sfxVolume, INT32 digMusicVolume); // // Per level startup code. @@ -122,7 +123,7 @@ void S_UpdateSounds(void); FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2); void S_SetDigMusicVolume(INT32 volume); -void S_SetMIDIMusicVolume(INT32 volume); +//void S_SetMIDIMusicVolume(INT32 volume); void S_SetSfxVolume(INT32 volume); INT32 S_OriginPlaying(void *origin); @@ -142,7 +143,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #ifdef MUSICSLOT_COMPATIBILITY // For compatibility with code/scripts relying on older versions // This is a list of all the "special" slot names and their associated numbers -const char *compat_special_music_slots[21]; +const char *compat_special_music_slots[16]; #endif #endif diff --git a/src/screen.c b/src/screen.c index 2780edb6..61ac821f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -71,7 +71,7 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef DIRECTFULLSCREEN -static FUNCMATH void SCR_ChangeFullscreen (void); +static void SCR_ChangeFullscreen (void); #else static void SCR_ChangeFullscreen (void); #endif diff --git a/src/sdl/i_cdmus.c b/src/sdl/i_cdmus.c index 3105f512..5d086e73 100644 --- a/src/sdl/i_cdmus.c +++ b/src/sdl/i_cdmus.c @@ -12,19 +12,19 @@ consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NUL consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -FUNCMATH void I_InitCD(void){} +void I_InitCD(void){} -FUNCMATH void I_StopCD(void){} +void I_StopCD(void){} -FUNCMATH void I_PauseCD(void){} +void I_PauseCD(void){} -FUNCMATH void I_ResumeCD(void){} +void I_ResumeCD(void){} -FUNCMATH void I_ShutdownCD(void){} +void I_ShutdownCD(void){} -FUNCMATH void I_UpdateCD(void){} +void I_UpdateCD(void){} -FUNCMATH void I_PlayCD(UINT8 track, UINT8 looping) +void I_PlayCD(UINT8 track, UINT8 looping) { (void)track; (void)looping; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 3575afa8..05371282 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2552,28 +2552,28 @@ void I_StartupMouse2(void) // // I_Tactile // -FUNCMATH void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; (void)FFEffect; } -FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; (void)FFEffect; } -FUNCMATH void I_Tactile3(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile3(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; (void)FFEffect; } -FUNCMATH void I_Tactile4(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile4(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; @@ -2705,7 +2705,7 @@ tic_t I_GetTime (void) // //I_StartupTimer // -FUNCMATH void I_StartupTimer(void) +void I_StartupTimer(void) { #ifdef _WIN32 // for win2k time bug @@ -2805,11 +2805,11 @@ void I_WaitVBL(INT32 count) SDL_Delay(count); } -FUNCMATH void I_BeginRead(void) +void I_BeginRead(void) { } -FUNCMATH void I_EndRead(void) +void I_EndRead(void) { } @@ -3557,5 +3557,5 @@ const CPUInfoFlags *I_CPUInfo(void) } // note CPUAFFINITY code used to reside here -FUNCMATH void I_RegisterSysCommands(void) {} +void I_RegisterSysCommands(void) {} #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 0dd022a8..5e9392ad 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1014,7 +1014,6 @@ static inline boolean I_SkipFrame(void) if (!paused) return false; /* FALLTHRU */ - case GS_TIMEATTACK: case GS_WAITINGPLAYERS: return skip; // Skip odd frames default: diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 71832459..3126643c 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -124,7 +124,7 @@ void I_ShutdownSound(void) #endif } -FUNCMATH void I_UpdateSound(void) +void I_UpdateSound(void) { } @@ -462,7 +462,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len) } #endif -FUNCMATH void I_InitMusic(void) +void I_InitMusic(void) { } @@ -767,7 +767,7 @@ boolean I_SetSongTrack(int track) // MIDI Music // -FUNCMATH void I_InitMIDIMusic(void) +void I_InitMIDIMusic(void) { } diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index f44b60c8..ac9d4ffc 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1311,7 +1311,6 @@ static inline boolean I_SkipFrame(void) case GS_LEVEL: if (!paused) return false; - case GS_TIMEATTACK: case GS_WAITINGPLAYERS: return skip; // Skip odd frames default: diff --git a/src/sounds.c b/src/sounds.c index f5a7ee9b..60cbb676 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -147,7 +147,6 @@ sfxinfo_t S_sfx[NUMSFX] = {"drown", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"fizzle", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"gbeep", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Grenade beep - {"gclose", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"ghit" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"gloop", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"gspray", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -294,7 +293,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s1ba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s1bb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s1bc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s1bd", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s1bd", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Ballhog bounce {"s1be", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s1bf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s1c0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -316,7 +315,7 @@ sfxinfo_t S_sfx[NUMSFX] = // Sonic 2 sounds {"s220", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s221", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s221", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Lap sound {"s222", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s223", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s224", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -343,7 +342,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s239", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s23a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s23b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s23c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s23c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Drift boost {"s23d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s23e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s23f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -362,7 +361,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s24c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s24d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s24e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s24f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Normal finish + {"s24f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s250", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s251", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s252", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -378,7 +377,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s25c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s25d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s25e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s25f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s25f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Perfect start boost {"s260", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s261", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s262", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -405,7 +404,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k39", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k3a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3k3a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart item shield {"s3k3b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k3c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k3d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -416,7 +415,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Lightning Shield use {"s3k46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -451,9 +450,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Blue Spheres {"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart final lap {"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart finish {"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k6c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -493,11 +492,11 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3k92", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Hyudoro use {"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Orbinaut {"s3k97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k98", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k99", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -514,13 +513,13 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3ka4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3ka5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3ka6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3ka7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart 3,2,1 {"s3ka8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3ka9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kaa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart GO! {"s3kae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kaf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kb0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -543,7 +542,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kbel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kbfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kbfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3kc0s", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Jawz {"s3kc0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -557,12 +556,13 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kc5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3kc7s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3kc7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kc9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart respawn {"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -600,14 +600,14 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kdbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // 3D Blast sounds (the "missing" ones are direct copies of S3K's, no minor differences what-so-ever) - {"3db06", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"3db06", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Bumper stolen {"3db09", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"3db14", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"3db16", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Sonic CD sounds {"cdfm00", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"cdfm01", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"cdfm01", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Sneaker boost {"cdfm02", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm03", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm04", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -645,7 +645,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdfm36", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"cdfm39", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"cdfm39", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // SS Mine deployed {"cdfm40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -676,7 +676,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdfm67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"cdfm70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"cdfm70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Trail item dragging {"cdfm71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdfm73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -695,7 +695,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdpcm6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdpcm7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdpcm8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"cdpcm9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"cdpcm9", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // No damage taken // Knuckles Chaotix sounds {"kc2a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -703,7 +703,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc2c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc2d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc2e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"kc2f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Pogo Spring + {"kc2f", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Pogo Spring use {"kc30", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc31", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc32", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -726,7 +726,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"kc46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"kc46", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Shrink use {"kc47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Vote picked {"kc49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -743,10 +743,10 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"kc57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"kc57", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // SPB locked in {"kc58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"kc59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Shrink - {"kc5a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Grow + {"kc59", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Shrink + {"kc5a", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Grow {"kc5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"kc5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -777,8 +777,8 @@ sfxinfo_t S_sfx[NUMSFX] = {"mlap", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"sboost", true, 90, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"mush", false, 90, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"star", false, 140, 16, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mega", false, 140, 16, -1, NULL, 0, -1, -1, LUMPERROR}, + {"kinvnc", false, 140, 8, -1, NULL, 0, -1, -1, LUMPERROR}, + {"kgrow", false, 140, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"bomb", false, 110, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"bomb2", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"peel", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -804,8 +804,12 @@ sfxinfo_t S_sfx[NUMSFX] = {"shelit", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR}, {"vroom", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"boing", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"smkinv", false, 140, 16, -1, NULL, 0, -1, -1, LUMPERROR}, + {"smkinv", false, 140, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"screec", false, 52, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"yeeeah", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"noooo1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"noooo2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"hogbom", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // SRB2kart - Skin sounds {"kwin", false, 64, 0, -1, NULL, 0, SKSWIN, -1, LUMPERROR}, diff --git a/src/sounds.h b/src/sounds.h index 7954a5ef..0f8d5a3b 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -219,7 +219,6 @@ typedef enum sfx_drown, sfx_fizzle, sfx_gbeep, - sfx_gclose, sfx_ghit, sfx_gloop, sfx_gspray, @@ -629,7 +628,8 @@ typedef enum sfx_s3kc5l, sfx_s3kc6s, sfx_s3kc6l, - sfx_s3kc7, + sfx_s3kc7s, + sfx_s3kc7l, sfx_s3kc8s, sfx_s3kc8l, sfx_s3kc9s, @@ -849,8 +849,8 @@ typedef enum sfx_mlap, sfx_sboost, sfx_mush, - sfx_star, - sfx_mega, + sfx_kinvnc, + sfx_kgrow, sfx_bomb, sfx_bomb2, sfx_peel, @@ -878,6 +878,10 @@ typedef enum sfx_boing, sfx_smkinv, sfx_screec, + sfx_yeeeah, + sfx_noooo1, + sfx_noooo2, + sfx_hogbom, sfx_kwin, sfx_klose, diff --git a/src/st_stuff.c b/src/st_stuff.c index 33f7a275..7efbe6d2 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -229,7 +229,7 @@ void ST_doPaletteStuff(void) if (rendermode != render_none) { - V_SetPaletteLump(GetPalette()); // Reset the palette + //V_SetPaletteLump(GetPalette()); // Reset the palette -- is this needed? if (!splitscreen) V_SetPalette(palette); } @@ -755,63 +755,75 @@ static void ST_drawLevelTitle(void) char *zonttl = mapheaderinfo[gamemap-1]->zonttl; // SRB2kart char *actnum = mapheaderinfo[gamemap-1]->actnum; INT32 lvlttlxpos; - INT32 subttlxpos = BASEVIDWIDTH/2; INT32 ttlnumxpos; INT32 zonexpos; + INT32 dupcalc = (vid.width/vid.dupx); + UINT8 gtc = G_GetGametypeColor(gametype); + INT32 sub = 0; + INT32 bary = (splitscreen) + ? BASEVIDHEIGHT/2 + : 163; + INT32 lvlw; - INT32 lvlttly; - INT32 zoney; - - if (!(timeinmap > 2 && timeinmap-3 < 110)) + if (timeinmap > 113) return; - if (strlen(actnum) > 0) - lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)) - V_LevelNameWidth(actnum); - else - lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)); + lvlw = V_LevelNameWidth(lvlttl); - ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl); - if (strlen(zonttl) > 0) - zonexpos = ttlnumxpos - V_LevelNameWidth(zonttl); // SRB2kart + if (strlen(actnum) > 0) + lvlttlxpos = ((BASEVIDWIDTH/2) - (lvlw/2)) - V_LevelNameWidth(actnum); else - zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE")); + lvlttlxpos = ((BASEVIDWIDTH/2) - (lvlw/2)); + + zonexpos = ttlnumxpos = lvlttlxpos + lvlw; + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + { + if (zonttl[0]) + zonexpos -= V_LevelNameWidth(zonttl); // SRB2kart + else + zonexpos -= V_LevelNameWidth(M_GetText("ZONE")); + } if (lvlttlxpos < 0) lvlttlxpos = 0; - // There's no consistent algorithm that can accurately define the old positions - // so I just ended up resorting to a single switct statement to define them - switch (timeinmap-3) + if (timeinmap > 105) { - case 0: zoney = 200; lvlttly = 0; break; - case 1: zoney = 188; lvlttly = 12; break; - case 2: zoney = 176; lvlttly = 24; break; - case 3: zoney = 164; lvlttly = 36; break; - case 4: zoney = 152; lvlttly = 48; break; - case 5: zoney = 140; lvlttly = 60; break; - case 6: zoney = 128; lvlttly = 72; break; - case 105: zoney = 80; lvlttly = 104; break; - case 106: zoney = 56; lvlttly = 128; break; - case 107: zoney = 32; lvlttly = 152; break; - case 108: zoney = 8; lvlttly = 176; break; - case 109: zoney = 0; lvlttly = 200; break; - default: zoney = 104; lvlttly = 80; break; + INT32 count = (113 - (INT32)(timeinmap)); + sub = dupcalc; + while (count-- > 0) + sub >>= 1; + sub = -sub; } - if (strlen(actnum) > 0) - V_DrawLevelTitle(ttlnumxpos+12, zoney, 0, actnum); + { + dupcalc = (dupcalc - BASEVIDWIDTH)>>1; + V_DrawFill(sub - dupcalc, bary+9, ttlnumxpos+dupcalc + 1, 2, 31); + V_DrawDiag(sub + ttlnumxpos + 1, bary, 11, 31); + V_DrawFill(sub - dupcalc, bary, ttlnumxpos+dupcalc, 10, gtc); + V_DrawDiag(sub + ttlnumxpos, bary, 10, gtc); + if (subttl[0]) + V_DrawRightAlignedString(sub + zonexpos - 8, bary+1, V_ALLOWLOWERCASE, subttl); + else + V_DrawRightAlignedString(sub + zonexpos - 8, bary+1, V_ALLOWLOWERCASE, va("%s Mode", gametype_cons_t[gametype].strvalue)); + } - V_DrawLevelTitle(lvlttlxpos, lvlttly, 0, lvlttl); + ttlnumxpos += sub; + lvlttlxpos += sub; + zonexpos += sub; + + V_DrawLevelTitle(lvlttlxpos, bary-18, 0, lvlttl); if (strlen(zonttl) > 0) - V_DrawLevelTitle(zonexpos, zoney, 0, zonttl); + V_DrawLevelTitle(zonexpos, bary+6, 0, zonttl); else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) - V_DrawLevelTitle(zonexpos, zoney, 0, M_GetText("ZONE")); + V_DrawLevelTitle(zonexpos, bary+6, 0, M_GetText("ZONE")); - if (lvlttly+48 < 200) - V_DrawCenteredString(subttlxpos, lvlttly+48, V_ALLOWLOWERCASE, subttl); + if (actnum[0]) + V_DrawLevelTitle(ttlnumxpos+12, bary+6, 0, actnum); } +/* static void ST_drawFirstPersonHUD(void) { player_t *player = stplyr; @@ -913,11 +925,12 @@ static void ST_drawFirstPersonHUD(void) V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCY(60 - SHORT(p->topoffset)), V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p); } +*/ /* // [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold static skincolors_t linkColor[14] = -{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_STEELBLUE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, +{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_STEEL, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, SKINCOLOR_PURPLE, SKINCOLOR_SILVER, SKINCOLOR_SUPER4, SKINCOLOR_PINK, SKINCOLOR_RED, SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD}; @@ -967,7 +980,7 @@ static void ST_drawNightsRecords(void) V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); - ST_DrawNightsOverlayNum(BASEVIDWIDTH/2 + 48, STRINGY(160), aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_STEELBLUE); + ST_DrawNightsOverlayNum(BASEVIDWIDTH/2 + 48, STRINGY(160), aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_STEEL); // If new record, say so! if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1) <= stplyr->lastmarescore) @@ -1251,7 +1264,7 @@ static void ST_drawNiGHTSHUD(void) // SRB2kart - unused. #endif ) { - ST_DrawNightsOverlayNum(304, STRINGY(16), SPLITFLAGS(V_SNAPTOTOP)|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_STEELBLUE); + ST_DrawNightsOverlayNum(304, STRINGY(16), SPLITFLAGS(V_SNAPTOTOP)|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_STEEL); } if (!stplyr->exiting @@ -1488,13 +1501,13 @@ static void ST_drawMatchHUD(void) // SRB2kart - unused. static inline void ST_drawRaceHUD(void) { - if (leveltime > TICRATE && leveltime <= 2*TICRATE) + if (leveltime > starttime-(3*TICRATE) && leveltime <= starttime-(2*TICRATE)) V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race3->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race3); - else if (leveltime > 2*TICRATE && leveltime <= 3*TICRATE) + else if (leveltime > starttime-(2*TICRATE) && leveltime <= starttime-TICRATE) V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race2->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race2); - else if (leveltime > 3*TICRATE && leveltime <= 4*TICRATE) + else if (leveltime > starttime-TICRATE && leveltime <= starttime) V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race1->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race1); - else if (leveltime > 4*TICRATE && leveltime <= 5*TICRATE) + else if (leveltime > starttime && leveltime <= starttime+TICRATE) V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racego->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, racego); if (circuitmap) @@ -1815,7 +1828,7 @@ static void ST_overlayDrawer(void) */ // GAME OVER pic - if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) + /*if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) { patch_t *p; @@ -1825,23 +1838,12 @@ static void ST_overlayDrawer(void) p = sboover; V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)), 0, p); - } + }*/ if (!hu_showscores) // hide the following if TAB is held { // Countdown timer for Race Mode - if (countdown) - { - INT32 x = BASEVIDWIDTH/2; - INT32 y = BASEVIDHEIGHT-24; - if (splitscreen) - { - y = (BASEVIDHEIGHT/2)-12; - if (splitscreen > 1) - x = BASEVIDWIDTH/4; - } - V_DrawCenteredString(x, y, K_calcSplitFlags(0), va("%d", countdown/TICRATE)); - } + // ...moved to k_kart.c so we can take advantage of the LAPS_Y value K_drawKartHUD(); @@ -1897,18 +1899,18 @@ static void ST_overlayDrawer(void) strlcpy(name, player_names[stplyr-players], 13); // Show name of player being displayed - V_DrawCenteredString((BASEVIDWIDTH/6), BASEVIDHEIGHT-80, 0, M_GetText("Viewpoint:")); - V_DrawCenteredString((BASEVIDWIDTH/6), BASEVIDHEIGHT-64, V_ALLOWLOWERCASE, name); + V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-40, 0, M_GetText("Viewpoint:")); + V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_ALLOWLOWERCASE, name); } // This is where we draw all the fun cheese if you have the chasecam off! - if ((stplyr == &players[displayplayer] && !camera.chase) + /*if ((stplyr == &players[displayplayer] && !camera.chase) || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase) || ((splitscreen > 1 && stplyr == &players[thirddisplayplayer]) && !camera3.chase) || ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase)) { ST_drawFirstPersonHUD(); - } + }*/ } #ifdef HAVE_BLUA @@ -1917,16 +1919,16 @@ static void ST_overlayDrawer(void) #endif // draw level title Tails - if (*mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer)) + if (*mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer) && !mapreset) #ifdef HAVE_BLUA && LUA_HudEnabled(hud_stagetitle) #endif ) ST_drawLevelTitle(); - if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer) + if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer && !mapreset) { - if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) + /*if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) @@ -1934,15 +1936,15 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); } - /*else if (!G_RaceGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. + else if (!G_RaceGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); else V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); - }*/ - else if (stplyr->spectator + } + else*/ if (stplyr->spectator #ifdef HAVE_BLUA && LUA_HudEnabled(hud_textspectator) #endif @@ -1950,12 +1952,12 @@ static void ST_overlayDrawer(void) { // SRB2kart: changed positions & text V_DrawString(2, BASEVIDHEIGHT-50, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -")); - /*if (G_GametypeHasTeams()) - V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Item - Join Team")); - else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF|V_REDMAP, M_GetText("- CANNOT JOIN -")); - else*/ - V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Item - Enter Game")); + if (stplyr->pflags & PF_WANTSTOJOIN) + V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Item - Cancel Join")); + /*else if (G_GametypeHasTeams()) + V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Item - Join Team"));*/ + else + V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Item - Join Game")); V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("F12 - Change View")); V_DrawString(2, BASEVIDHEIGHT-20, V_HUDTRANSHALF, M_GetText("Accelerate - Float")); V_DrawString(2, BASEVIDHEIGHT-10, V_HUDTRANSHALF, M_GetText("Brake - Sink")); @@ -1968,7 +1970,7 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { #ifdef SEENAMES - if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) + if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo && !mapreset) { if (cv_seenames.value == 1) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF, player_names[seenplayer-players]); diff --git a/src/st_stuff.h b/src/st_stuff.h index 63bb89a1..d0528e0a 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -24,7 +24,7 @@ // // Called by main loop. -FUNCMATH void ST_Ticker(void); +void ST_Ticker(void); // Called by main loop. void ST_Drawer(void); diff --git a/src/v_video.c b/src/v_video.c index 44319dd7..8013ae82 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -41,7 +41,7 @@ UINT8 *screens[5]; static CV_PossibleValue_t gamma_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NULL}}; static void CV_usegamma_OnChange(void); -consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usegamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allcaps = {"allcaps", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -305,6 +305,7 @@ void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT3 static UINT8 hudplusalpha[11] = { 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0}; static UINT8 hudminusalpha[11] = { 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5}; +UINT8 hudtrans = 0; static const UINT8 *v_colormap = NULL; static const UINT8 *v_translevel = NULL; @@ -359,11 +360,11 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT))) { if (alphalevel == 13) - alphalevel = hudminusalpha[cv_translucenthud.value]; + alphalevel = hudminusalpha[hudtrans]; else if (alphalevel == 14) - alphalevel = 10 - cv_translucenthud.value; + alphalevel = 10 - hudtrans; /*else if (alphalevel == 15) - alphalevel = hudplusalpha[cv_translucenthud.value];*/ + alphalevel = hudplusalpha[hudtrans];*/ if (alphalevel >= 10) return; // invis @@ -418,7 +419,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t if (scrn & V_FLIP) { flip = true; - x -= FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<width) - SHORT(patch->leftoffset))<leftoffset)<>= FRACBITS; y >>= FRACBITS; - desttop += (y*vid.width) + x; // Center it if necessary if (!(scrn & V_SCALEPATCHMASK)) { + // if it's meant to cover the whole screen, black out the rest + // BAD, BAD, BAD, FUCK OFF, STOP, EW, AAAAAAA + // This does NOT account for transparent pixels + /*if (x == 0 && FixedMul(SHORT(patch->width)<>FRACBITS == BASEVIDWIDTH + && y == 0 && FixedMul(SHORT(patch->height)<>FRACBITS == BASEVIDHEIGHT) + { + column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[0])); + source = (const UINT8 *)(column) + 3; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + }*/ + if (vid.width != BASEVIDWIDTH * dupx) { // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, // so center this imaginary screen if ((scrn & (V_HORZSCREEN|V_SNAPTOLEFT)) == (V_HORZSCREEN|V_SNAPTOLEFT)) - desttop += (vid.width/2 - (BASEVIDWIDTH/2 * dupx)); + x += (vid.width/2 - (BASEVIDWIDTH/2 * dupx)); else if (scrn & V_SNAPTORIGHT) - desttop += (vid.width - (BASEVIDWIDTH * dupx)); + x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(scrn & V_SNAPTOLEFT)) - desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -475,15 +486,9 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t else if (!(scrn & V_SNAPTOTOP)) desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; } - // if it's meant to cover the whole screen, black out the rest - if (x == 0 && FixedMul(SHORT(patch->width)<>FRACBITS == BASEVIDWIDTH - && y == 0 && FixedMul(SHORT(patch->height)<>FRACBITS == BASEVIDHEIGHT) - { - column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[0])); - source = (const UINT8 *)(column) + 3; - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); - } } + + desttop += (y*vid.width) + x; } if (pscale != FRACUNIT) // scale width properly @@ -612,12 +617,14 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; } // if it's meant to cover the whole screen, black out the rest - if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT) + // BAD, BAD, BAD, FUCK OFF, STOP, EW, AAAAAAA + // This does NOT account for transparent pixels + /*if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT) { column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[0])); source = (const UINT8 *)(column) + 3; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); - } + }*/ } } @@ -837,7 +844,104 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) c &= 255; for (;(--h >= 0) && dest < deststop; dest += vid.width) - memset(dest, (UINT8)(c&255), w * vid.bpp); + memset(dest, c, w * vid.bpp); +} + +// +// Fills a triangle of pixels with a single color, NOTE: scaled to screen size +// +// ... +// .. <-- this shape only for now, i'm afraid +// . +// +void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c) +{ + UINT8 *dest; + const UINT8 *deststop; + INT32 w, h, wait = 0; + + if (rendermode == render_none) + return; + +#ifdef HWRENDER + if (rendermode != render_soft && !con_startup) + { + HWR_DrawDiag(x, y, wh, c); + return; + } +#endif + + if (!(c & V_NOSCALESTART)) + { + INT32 dupx = vid.dupx, dupy = vid.dupy; + + x *= dupx; + y *= dupy; + wh *= dupx; + + // Center it if necessary + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (c & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(c & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (c & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(c & V_SNAPTOTOP)) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (x >= vid.width || y >= vid.height) + return; // off the screen + + if (y < 0) + { + wh += y; + y = 0; + } + + w = h = wh; + + if (x < 0) + { + w += x; + x = 0; + } + + if (w <= 0 || h <= 0) + return; // zero width/height wouldn't draw anything + if (x + w > vid.width) + { + wait = w - (vid.width - x); + w = vid.width - x; + } + if (y + w > vid.height) + h = vid.height - y; + + if (h > w) + h = w; + + dest = screens[0] + y*vid.width + x; + deststop = screens[0] + vid.rowbytes * vid.height; + + c &= 255; + + for (;(--h >= 0) && dest < deststop; dest += vid.width) + { + memset(dest, c, w * vid.bpp); + if (wait) + wait--; + else + w--; + } } // THANK YOU MPC!!! @@ -1076,25 +1180,34 @@ void V_DrawPatchFill(patch_t *pat) // // Fade all the screen buffer, so that the menu is more readable, // especially now that we use the small hufont in the menus... +// If color is 0x00 to 0xFF, draw transtable (strength range 0-9). +// Else, use COLORMAP lump (strength range 0-31). +// IF YOU ARE NOT CAREFUL, THIS CAN AND WILL CRASH! +// I have kept the safety checks out of this function; +// the v.fadeScreen Lua interface handles those. // -void V_DrawFadeScreen(void) +void V_DrawFadeScreen(UINT16 color, UINT8 strength) { - const UINT8 *fadetable = (UINT8 *)colormaps + 16*256; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT8 *buf = screens[0]; - #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) - { - HWR_FadeScreenMenuBack(0x01010160, 0); // hack, 0 means full height - return; - } + if (rendermode != render_soft && rendermode != render_none) + { + HWR_FadeScreenMenuBack(color, strength); + return; + } #endif - // heavily simplified -- we don't need to know x or y - // position when we're doing a full screen fade - for (; buf < deststop; ++buf) - *buf = fadetable[*buf]; + { + const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index? + ? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade. + : ((UINT8 *)transtables + ((9-strength)<> V_CHARCOLORSHIFT) { @@ -1143,7 +1256,7 @@ static const UINT8 *V_GetStringColormap(INT32 colorflags) case 2: // 0x82, yellow return yellowmap; case 3: // 0x83, lgreen - return lgreenmap; + return greenmap; case 4: // 0x84, blue return bluemap; case 5: // 0x85, red @@ -1152,6 +1265,8 @@ static const UINT8 *V_GetStringColormap(INT32 colorflags) return graymap; case 7: // 0x87, orange return orangemap; + case 8: // 0x88, sky + return skymap; default: // reset return NULL; } @@ -1284,7 +1399,7 @@ char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) // void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; INT32 charflags = 0; const UINT8 *colormap = NULL; @@ -1300,7 +1415,11 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } charflags = (option & V_CHARCOLORMASK); @@ -1361,9 +1480,9 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) else w = SHORT(hu_font[c]->width) * dupx; - if (cx + w > scrwidth) + if (cx > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w; continue; @@ -1379,7 +1498,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) // SRB2kart void V_DrawKartString(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; INT32 charflags = 0; const UINT8 *colormap = NULL; @@ -1395,7 +1514,11 @@ void V_DrawKartString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } charflags = (option & V_CHARCOLORMASK); @@ -1456,9 +1579,9 @@ void V_DrawKartString(INT32 x, INT32 y, INT32 option, const char *string) else w = SHORT(kart_font[c]->width) * dupx; - if (cx + w > scrwidth) + if (cx > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w; continue; @@ -1490,7 +1613,7 @@ void V_DrawRightAlignedString(INT32 x, INT32 y, INT32 option, const char *string // void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; INT32 charflags = 0; const UINT8 *colormap = NULL; @@ -1506,7 +1629,11 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } charflags = (option & V_CHARCOLORMASK); @@ -1565,9 +1692,9 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) } else w = SHORT(hu_font[c]->width) * dupx / 2; - if (cx + w > scrwidth) + if (cx > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w; continue; @@ -1592,7 +1719,7 @@ void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *s // void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; const char *ch = string; INT32 charflags = 0; const UINT8 *colormap = NULL; @@ -1608,7 +1735,11 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } charflags = (option & V_CHARCOLORMASK); @@ -1665,9 +1796,9 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) else w = (SHORT(tny_font[c]->width) * dupx); - if (cx + w > scrwidth) + if (cx > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w; continue; @@ -1690,7 +1821,7 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) { fixed_t cx = x, cy = y; - INT32 w, c, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; + INT32 w, c, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; INT32 spacewidth = 4, charwidth = 0; @@ -1704,7 +1835,11 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } switch (option & V_SPACINGMASK) { @@ -1758,9 +1893,9 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) else w = SHORT(hu_font[c]->width) * dupx; - if ((cx>>FRACBITS) + w > scrwidth) + if ((cx>>FRACBITS) > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w<width) * dupx; - if ((cx>>FRACBITS) + w > scrwidth) + if ((cx>>FRACBITS) > scrwidth) break; V_DrawSciencePatch(cx, cy, option, cred_font[c], FRACUNIT); @@ -1896,7 +2031,7 @@ INT32 V_CreditStringWidth(const char *string) // void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; const char *ch = string; if (option & V_NOSCALESTART) @@ -1906,7 +2041,11 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } for (;;) { @@ -1928,11 +2067,10 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) } w = SHORT(lt_font[c]->width) * dupx; - if (cx + w > scrwidth) - break; - //left boundary check - if (cx < 0) + if (cx > scrwidth) + break; + if (cx + left < 0) //left boundary check { cx += w; continue; diff --git a/src/v_video.h b/src/v_video.h index ffa1038c..e118d5cf 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -43,6 +43,8 @@ const char *GetPalette(void); extern RGBA_t *pLocalPalette; +extern UINT8 hudtrans; + // Retrieve the ARGB value from a palette color index #define V_GetColor(color) (pLocalPalette[color&0xFF]) @@ -76,6 +78,7 @@ extern RGBA_t *pLocalPalette; #define V_REDMAP 0x00005000 #define V_GRAYMAP 0x00006000 #define V_ORANGEMAP 0x00007000 +#define V_SKYMAP 0x00008000 // use bits 17-20 for alpha transparency #define V_ALPHASHIFT 16 @@ -140,11 +143,13 @@ void V_DrawScaledPic (INT32 px1, INT32 py1, INT32 scrn, INT32 lumpnum); // fill a box with a single color void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); +// fill a triangle with a single color +void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c); // fill a box with a flat as a pattern void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); // fade down the screen buffer before drawing the menu over -void V_DrawFadeScreen(void); +void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); @@ -152,6 +157,7 @@ void V_DrawFadeConsBack(INT32 plines); void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); // draw a single character, but for the chat void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap); +const UINT8 *V_GetStringColormap(INT32 colorflags); void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string); diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index a9dd097b..30fada8e 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -323,7 +323,6 @@ static inline boolean I_SkipFrame(void) if (!paused) return false; /* FALLTHRU */ - case GS_TIMEATTACK: #ifndef CLIENT_LOADINGSCREEN case GS_WAITINGPLAYERS: #endif diff --git a/src/y_inter.c b/src/y_inter.c index cd56b346..29c81df0 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -36,9 +36,10 @@ #include "m_cond.h" // condition sets -#include "m_random.h" // P_RandomKey +#include "m_random.h" // M_RandomKey #include "g_input.h" // PLAYER1INPUTDOWN #include "k_kart.h" // colortranslations +#include "console.h" // cons_menuhighlight #ifdef HWRENDER #include "hardware/hw_main.h" @@ -59,7 +60,7 @@ typedef struct typedef union { - struct + /*struct { char passed1[21]; // KNUCKLES GOT / CRAWLA HONCHO char passed2[16]; // THROUGH THE ACT / PASSED THE ACT @@ -77,68 +78,22 @@ typedef union patch_t *ttlnum; // act number being displayed patch_t *ptotal; // TOTAL UINT8 gotlife; // Number of extra lives obtained - } coop; + } coop;*/ struct { - char passed1[29]; // KNUCKLES GOT / CRAWLA HONCHO - char passed2[17]; // A CHAOS EMERALD / GOT THEM ALL! - char passed3[15]; // CAN NOW BECOME - char passed4[SKINNAMESIZE+7]; // SUPER CRAWLA HONCHO - INT32 passedx1; - INT32 passedx2; - INT32 passedx3; - INT32 passedx4; - - y_bonus_t bonus; - patch_t *bonuspatch; - - patch_t *pscore; // SCORE - UINT32 score; // fake score - - // Continues - UINT8 continues; - patch_t *pcontinues; - INT32 *playerchar; // Continue HUD - UINT8 *playercolor; - - UINT8 gotlife; // Number of extra lives obtained - } spec; - - struct - { - UINT32 scores[MAXPLAYERS]; // Winner's score UINT8 *color[MAXPLAYERS]; // Winner's color # - boolean spectator[MAXPLAYERS]; // Spectator list INT32 *character[MAXPLAYERS]; // Winner's character # INT32 num[MAXPLAYERS]; // Winner's player # char *name[MAXPLAYERS]; // Winner's name - patch_t *result; // RESULT - patch_t *blueflag; - patch_t *redflag; // int_ctf uses this struct too. INT32 numplayers; // Number of players being displayed - char levelstring[40]; // holds levelnames up to 32 characters + char levelstring[62]; // holds levelnames up to 32 characters // SRB2kart - int increase[MAXPLAYERS]; //how much did the score increase by? - int time[MAXPLAYERS]; //Tournament Time + UINT8 increase[MAXPLAYERS]; //how much did the score increase by? + UINT32 val[MAXPLAYERS]; //Gametype-specific value + UINT8 pos[MAXPLAYERS]; // player positions. used for ties + boolean rankingsmode; // rankings mode } match; - - struct - { - UINT8 *color[MAXPLAYERS]; // Winner's color # - INT32 *character[MAXPLAYERS]; // Winner's character # - INT32 num[MAXPLAYERS]; // Winner's player # - char name[MAXPLAYERS][9]; // Winner's name - UINT32 times[MAXPLAYERS]; - UINT32 rings[MAXPLAYERS]; - UINT32 maxrings[MAXPLAYERS]; - UINT32 monitors[MAXPLAYERS]; - UINT32 scores[MAXPLAYERS]; - UINT32 points[MAXPLAYERS]; - INT32 numplayers; // Number of players being displayed - char levelstring[40]; // holds levelnames up to 32 characters - } competition; - } y_data; static y_data data; @@ -155,16 +110,10 @@ static INT32 timer; static INT32 intertic; static INT32 endtic = -1; +static INT32 sorttic = -1; intertype_t intertype = int_none; -//static void Y_AwardCoopBonuses(void); -//static void Y_AwardSpecialStageBonus(void); -static void Y_CalculateTournamentPoints(void); // SRB2kart - -static void Y_CalculateCompetitionWinners(void); -//static void Y_CalculateTimeRaceWinners(void); -static void Y_CalculateMatchWinners(void); static void Y_FollowIntermission(void); static void Y_UnloadData(void); @@ -172,7 +121,9 @@ static void Y_UnloadData(void); // Level images typedef struct { - char str[40]; + char str[62]; + UINT8 gtc; + const char *gts; patch_t *pic; } y_votelvlinfo; @@ -191,9 +142,10 @@ typedef struct UINT8 roffset; UINT8 rsynctime; UINT8 rendoff; + boolean loaded; } y_voteclient; -static y_votelvlinfo levelinfo[4]; +static y_votelvlinfo levelinfo[5]; static y_voteclient voteclient; static INT32 votetic; static INT32 voteendtic = -1; @@ -206,30 +158,112 @@ static patch_t *randomlvl = NULL; static void Y_UnloadVoteData(void); -// Stuff copy+pasted from st_stuff.c -static INT32 SCX(INT32 x) +// +// SRB2Kart - Y_CalculateMatchData and ancillary functions +// +static void Y_CompareRace(INT32 i) { - return FixedInt(FixedMul(x< data.match.val[data.match.numplayers]))) + return; + + data.match.val[data.match.numplayers] = val; + data.match.num[data.match.numplayers] = i; +} + +static void Y_CompareRank(INT32 i) +{ + if (!(data.match.val[data.match.numplayers] == UINT32_MAX || players[i].score > data.match.val[data.match.numplayers])) + return; + + data.match.val[data.match.numplayers] = players[i].score; + data.match.num[data.match.numplayers] = i; +} + +static void Y_CalculateMatchData(boolean rankingsmode, void (*comparison)(INT32)) +{ + INT32 i, j; + boolean completed[MAXPLAYERS]; + INT32 numplayersingame = 0; + + // Initialize variables + if ((data.match.rankingsmode = rankingsmode)) + sprintf(data.match.levelstring, "* Total Rankings *"); + + for (i = 0; i < MAXPLAYERS; i++) + { + data.match.val[i] = UINT32_MAX; + if (!rankingsmode) + data.match.increase[i] = UINT8_MAX; + + if (!playeringame[i] || players[i].spectator) + continue; + + numplayersingame++; + } + + memset(data.match.color, 0, sizeof (data.match.color)); + memset(data.match.character, 0, sizeof (data.match.character)); + memset(completed, 0, sizeof (completed)); + data.match.numplayers = 0; + + for (j = 0; j < numplayersingame; j++) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator || completed[i]) + continue; + + comparison(i); + } + + i = data.match.num[data.match.numplayers]; + + completed[i] = true; + + data.match.color[data.match.numplayers] = &players[i].skincolor; + data.match.character[data.match.numplayers] = &players[i].skin; + data.match.name[data.match.numplayers] = player_names[i]; + + if (data.match.numplayers && (data.match.val[data.match.numplayers] == data.match.val[data.match.numplayers-1])) + data.match.pos[data.match.numplayers] = data.match.pos[data.match.numplayers-1]; + else + data.match.pos[data.match.numplayers] = data.match.numplayers+1; + + if (!rankingsmode && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] != numplayersingame)) + { + data.match.increase[i] = numplayersingame - data.match.pos[data.match.numplayers]; + players[i].score += data.match.increase[i]; + } + + data.match.numplayers++; + } +} // // Y_IntermissionDrawer // -// Called by D_Display. Nothing is modified here; all it does is draw. +// Called by D_Display. Nothing is modified here; all it does is draw. (SRB2Kart: er, about that...) // Neat concept, huh? // void Y_IntermissionDrawer(void) { - // Bonus loops - INT32 i; + INT32 i, whiteplayer = MAXPLAYERS, x = 4, hilicol = V_YELLOWMAP; // fallback if (intertype == int_none || rendermode == render_none) return; @@ -260,8 +294,33 @@ void Y_IntermissionDrawer(void) else V_DrawPatchFill(bgtile); + if (usebuffer) // Fade everything out + V_DrawFadeScreen(0xFF00, 20); + + if (!splitscreen) + whiteplayer = demoplayback ? displayplayer : consoleplayer; + + if (cons_menuhighlight.value) + hilicol = cons_menuhighlight.value; + else if (modeattacking) + hilicol = V_ORANGEMAP; + else + hilicol = ((intertype == int_race) ? V_SKYMAP : V_REDMAP); + + if (sorttic != -1 && intertic > sorttic) + { + INT32 count = (intertic - sorttic); + + if (count < 8) + x -= ((count * vid.width) / (8 * vid.dupx)); + else if (count == 8) + goto dotimer; + else if (count < 16) + x += (((16 - count) * vid.width) / (8 * vid.dupx)); + } + // SRB2kart 290117 - compeltely replaced this block. - if (intertype == int_timeattack) + /*if (intertype == int_timeattack) { // draw time ST_DrawPatchFromHud(HUD_TIME, sbotime); @@ -279,13 +338,13 @@ void Y_IntermissionDrawer(void) ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds - /* // SRB2kart - pulled from old coop block, just in case we need it + // SRB2kart - pulled from old coop block, just in case we need it // we should show centiseconds on the intermission screen too, if the conditions are right. if (modeattacking || cv_timetic.value == 2) { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics - }*/ + } ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics @@ -301,58 +360,44 @@ void Y_IntermissionDrawer(void) //if (gottimebonus && endtic != -1) // V_DrawCenteredString(BASEVIDWIDTH/2, 172, V_YELLOWMAP, "TIME BONUS UNLOCKED!"); } - else if (intertype == int_race) + else*/ if (intertype == int_race || intertype == int_match) { - INT32 j = 0; - INT32 x = 4; INT32 y = 48; char name[MAXPLAYERNAME+1]; + const char *timeheader; - boolean completed[MAXPLAYERS]; - memset(completed, 0, sizeof (completed)); + if (data.match.rankingsmode) + timeheader = "RANK"; + else + timeheader = (intertype == int_race ? "TIME" : "SCORE"); // draw the level name - V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring); - V_DrawFill(4, 42, 312, 1, 0); + V_DrawCenteredString(-4 + x + BASEVIDWIDTH/2, 20, 0, data.match.levelstring); + V_DrawFill(x, 42, 312, 1, 0); if (data.match.numplayers > 8) { V_DrawFill(160, 32, 1, 152, 0); - V_DrawCenteredString(x+6+(BASEVIDWIDTH/2), 32, V_YELLOWMAP, "#"); - V_DrawString(x+36+(BASEVIDWIDTH/2), 32, V_YELLOWMAP, "NAME"); + V_DrawCenteredString(x+6+(BASEVIDWIDTH/2), 32, hilicol, "#"); + V_DrawString(x+36+(BASEVIDWIDTH/2), 32, hilicol, "NAME"); - V_DrawRightAlignedString(x+110, 32, V_YELLOWMAP, "TIME"); - - V_DrawRightAlignedString(x+152, 32, V_YELLOWMAP, "SCORE"); + V_DrawRightAlignedString(x+152, 32, hilicol, timeheader); } - V_DrawCenteredString(x+6, 32, V_YELLOWMAP, "#"); - V_DrawString(x+36, 32, V_YELLOWMAP, "NAME"); + V_DrawCenteredString(x+6, 32, hilicol, "#"); + V_DrawString(x+36, 32, hilicol, "NAME"); - if (data.match.numplayers > 8) - { - V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+110, 32, V_YELLOWMAP, "TIME"); - } - else - { - V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+62, 32, V_YELLOWMAP, "TIME"); - } - - V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 32, V_YELLOWMAP, "SCORE"); + V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 32, hilicol, timeheader); for (i = 0; i < data.match.numplayers; i++) { - char strtime[10]; - - if (data.match.spectator[i]) - continue; - - V_DrawCenteredString(x+6, y, 0, va("%d", j+1)); - j++; //We skip spectators, but not their number. - - if (playeringame[data.match.num[i]]) + if (data.match.num[i] != MAXPLAYERS && playeringame[data.match.num[i]] && !players[data.match.num[i]].spectator) { + char strtime[10]; + + V_DrawCenteredString(x+6, y, 0, va("%d", data.match.pos[i])); + if (data.match.color[i] == 0) V_DrawSmallScaledPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]]); else @@ -361,168 +406,75 @@ void Y_IntermissionDrawer(void) V_DrawSmallMappedPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]], colormap); } - if (data.match.numplayers > 8) - { + if (data.match.numplayers > 9) strlcpy(name, data.match.name[i], 6); - } else STRBUFCPY(name, data.match.name[i]); - V_DrawString(x+36, y, V_ALLOWLOWERCASE, name); + V_DrawString(x+36, y, + ((data.match.num[i] == whiteplayer) + ? hilicol|V_ALLOWLOWERCASE + : V_ALLOWLOWERCASE), + name); - snprintf(strtime, sizeof strtime, "%d", data.match.scores[i]-data.match.increase[i]); - - if (data.match.numplayers > 8) + if (data.match.rankingsmode) { - V_DrawRightAlignedString(x+152, y, V_YELLOWMAP, strtime); - } - else - { - V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, V_YELLOWMAP, strtime); - } + if (data.match.increase[data.match.num[i]] != UINT8_MAX) + { + if (data.match.increase[data.match.num[i]] > 9) + snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[data.match.num[i]]); + else + snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]); - if (data.match.increase[i] > 9) - snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[i]); - else - snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[i]); + if (data.match.numplayers > 8) + V_DrawRightAlignedString(x+120, y, 0, strtime); + else + V_DrawRightAlignedString(x+120+BASEVIDWIDTH/2, y, 0, strtime); - if (data.match.numplayers <= 8) // Only draw this with less than 8 players, otherwise we won't be able to fit the times in - { - V_DrawString(x+84+BASEVIDWIDTH/2, y, 0, strtime); - } - - snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.time[i], true), - G_TicsToSeconds(data.match.time[i]), G_TicsToCentiseconds(data.match.time[i])); - - strtime[sizeof strtime - 1] = '\0'; - - if (data.match.numplayers > 8) - { - V_DrawRightAlignedString(x+134, y, 0, strtime); - } - else - { - V_DrawRightAlignedString(x+80+BASEVIDWIDTH/2, y, 0, strtime); - } - - - completed[i] = true; - } - - y += 16; - - if (y > 160) - { - y = 48; - x += BASEVIDWIDTH/2; - } - } - } - else if (intertype == int_match) - { - INT32 j = 0; - INT32 x = 4; - INT32 y = 48; - char name[MAXPLAYERNAME+1]; - char strtime[10]; - - // draw the header - V_DrawScaledPatch(112, 2, 0, data.match.result); - - // draw the level name - V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring); - V_DrawFill(4, 42, 312, 1, 0); - - if (data.match.numplayers > 9) - { - V_DrawFill(160, 32, 1, 152, 0); - - if (intertype == int_race) - V_DrawRightAlignedString(x+152, 32, V_YELLOWMAP, "TIME"); - else - V_DrawRightAlignedString(x+152, 32, V_YELLOWMAP, "SCORE"); - - V_DrawCenteredString(x+(BASEVIDWIDTH/2)+6, 32, V_YELLOWMAP, "#"); - V_DrawString(x+(BASEVIDWIDTH/2)+36, 32, V_YELLOWMAP, "NAME"); - } - - V_DrawCenteredString(x+6, 32, V_YELLOWMAP, "#"); - V_DrawString(x+36, 32, V_YELLOWMAP, "NAME"); - - if (intertype == int_race) - V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 32, V_YELLOWMAP, "TIME"); - else - V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 32, V_YELLOWMAP, "SCORE"); - - for (i = 0; i < data.match.numplayers; i++) - { - if (data.match.spectator[i]) - continue; //Ignore spectators. - - V_DrawCenteredString(x+6, y, 0, va("%d", j+1)); - j++; //We skip spectators, but not their number. - - if (playeringame[data.match.num[i]]) - { - // Draw the back sprite, it looks ugly if we don't - V_DrawSmallScaledPatch(x+16, y-4, 0, livesback); - - if (data.match.color[i] == 0) - V_DrawSmallScaledPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]]); - else - { - UINT8 *colormap = R_GetTranslationColormap(*data.match.character[i], *data.match.color[i], GTC_CACHE); - V_DrawSmallMappedPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]], colormap); - } - - if (data.match.numplayers > 9) - { - if (intertype == int_race) - strlcpy(name, data.match.name[i], 8); + snprintf(strtime, sizeof strtime, "%d", data.match.val[i]-data.match.increase[data.match.num[i]]); + } else - strlcpy(name, data.match.name[i], 9); - } - else - STRBUFCPY(name, data.match.name[i]); + snprintf(strtime, sizeof strtime, "%d", data.match.val[i]); - V_DrawString(x+36, y, V_ALLOWLOWERCASE, name); - - if (data.match.numplayers > 9) - { - if (intertype == int_match) - V_DrawRightAlignedString(x+152, y, 0, va("%i", data.match.scores[i])); - else if (intertype == int_race) - { - if (players[data.match.num[i]].pflags & PF_TIMEOVER) - snprintf(strtime, sizeof strtime, "DNF"); - else - snprintf(strtime, sizeof strtime, - "%i:%02i.%02i", - G_TicsToMinutes(data.match.scores[i], true), - G_TicsToSeconds(data.match.scores[i]), G_TicsToCentiseconds(data.match.scores[i])); - - strtime[sizeof strtime - 1] = '\0'; + if (data.match.numplayers > 8) V_DrawRightAlignedString(x+152, y, 0, strtime); - } + else + V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, strtime); } else { - if (intertype == int_match) - V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, va("%u", data.match.scores[i])); - else if (intertype == int_race) + if (data.match.val[i] == (UINT32_MAX-1)) { - if (players[data.match.num[i]].pflags & PF_TIMEOVER) - snprintf(strtime, sizeof strtime, "DNF"); + if (data.match.numplayers > 8) + V_DrawRightAlignedThinString(x+152, y-1, 0, "NO CONTEST"); else - snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.scores[i], true), - G_TicsToSeconds(data.match.scores[i]), G_TicsToCentiseconds(data.match.scores[i])); + V_DrawRightAlignedThinString(x+152+BASEVIDWIDTH/2, y-1, 0, "NO CONTEST"); + } + else + { + if (intertype == int_race) + { + snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.val[i], true), + G_TicsToSeconds(data.match.val[i]), G_TicsToCentiseconds(data.match.val[i])); + strtime[sizeof strtime - 1] = '\0'; - strtime[sizeof strtime - 1] = '\0'; - - V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, strtime); + if (data.match.numplayers > 8) + V_DrawRightAlignedString(x+152, y, 0, strtime); + else + V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, strtime); + } + else + { + if (data.match.numplayers > 8) + V_DrawRightAlignedString(x+152, y, 0, va("%i", data.match.val[i])); + else + V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, va("%i", data.match.val[i])); + } } } } + else + data.match.num[i] = MAXPLAYERS; // this should be the only field setting in this function y += 16; @@ -533,171 +485,18 @@ void Y_IntermissionDrawer(void) } } } - else if (intertype == int_ctf || intertype == int_teammatch) - { - INT32 x = 4, y = 0; - INT32 redplayers = 0, blueplayers = 0; - char name[MAXPLAYERNAME+1]; - - // Show the team flags and the team score at the top instead of "RESULTS" - V_DrawSmallScaledPatch(128 - SHORT(data.match.blueflag->width)/4, 2, 0, data.match.blueflag); - V_DrawCenteredString(128, 16, 0, va("%u", bluescore)); - - V_DrawSmallScaledPatch(192 - SHORT(data.match.redflag->width)/4, 2, 0, data.match.redflag); - V_DrawCenteredString(192, 16, 0, va("%u", redscore)); - - // draw the level name - V_DrawCenteredString(BASEVIDWIDTH/2, 24, 0, data.match.levelstring); - V_DrawFill(4, 42, 312, 1, 0); - - //vert. line - V_DrawFill(160, 32, 1, 152, 0); - - //strings at the top of the list - V_DrawCenteredString(x+6, 32, V_YELLOWMAP, "#"); - V_DrawCenteredString(x+(BASEVIDWIDTH/2)+6, 32, V_YELLOWMAP, "#"); - - V_DrawString(x+36, 32, V_YELLOWMAP, "NAME"); - V_DrawString(x+(BASEVIDWIDTH/2)+36, 32, V_YELLOWMAP, "NAME"); - - V_DrawRightAlignedString(x+152, 32, V_YELLOWMAP, "SCORE"); - V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 32, V_YELLOWMAP, "SCORE"); - - for (i = 0; i < data.match.numplayers; i++) - { - if (playeringame[data.match.num[i]] && !(data.match.spectator[i])) - { - UINT8 *colormap = R_GetTranslationColormap(*data.match.character[i], *data.match.color[i], GTC_CACHE); - - if (*data.match.color[i] == SKINCOLOR_RED) //red - { - if (redplayers++ > 9) - continue; - x = 4 + (BASEVIDWIDTH/2); - y = (redplayers * 16) + 32; - V_DrawCenteredString(x+6, y, 0, va("%d", redplayers)); - } - else if (*data.match.color[i] == SKINCOLOR_BLUE) //blue - { - if (blueplayers++ > 9) - continue; - x = 4; - y = (blueplayers * 16) + 32; - V_DrawCenteredString(x+6, y, 0, va("%d", blueplayers)); - } - else - continue; - - // Draw the back sprite, it looks ugly if we don't - V_DrawSmallScaledPatch(x+16, y-4, 0, livesback); - - //color is ALWAYS going to be 6/7 here, no need to check if it's nonzero. - V_DrawSmallMappedPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]], colormap); - - strlcpy(name, data.match.name[i], 9); - - V_DrawString(x+36, y, V_ALLOWLOWERCASE, name); - - V_DrawRightAlignedString(x+152, y, 0, va("%u", data.match.scores[i])); - } - } - } - else if (intertype == int_classicrace) - { - INT32 x = 4; - INT32 y = 48; - UINT32 ptime, pring, pmaxring, pmonitor, pscore; - char sstrtime[10]; - - // draw the level name - V_DrawCenteredString(BASEVIDWIDTH/2, 8, 0, data.competition.levelstring); - V_DrawFill(4, 42, 312, 1, 0); - - V_DrawCenteredString(x+6, 32, V_YELLOWMAP, "#"); - V_DrawString(x+36, 32, V_YELLOWMAP, "NAME"); - // Time - V_DrawRightAlignedString(x+160, 32, V_YELLOWMAP, "TIME"); - - // Rings - V_DrawThinString(x+168, 31, V_YELLOWMAP, "RING"); - - // Total rings - V_DrawThinString(x+191, 22, V_YELLOWMAP, "TOTAL"); - V_DrawThinString(x+196, 31, V_YELLOWMAP, "RING"); - - // Monitors - V_DrawThinString(x+223, 22, V_YELLOWMAP, "ITEM"); - V_DrawThinString(x+229, 31, V_YELLOWMAP, "BOX"); - - // Score - V_DrawRightAlignedString(x+288, 32, V_YELLOWMAP, "SCORE"); - - // Points - V_DrawRightAlignedString(x+312, 32, V_YELLOWMAP, "PT"); - - for (i = 0; i < data.competition.numplayers; i++) - { - ptime = (data.competition.times[i] & ~0x80000000); - pring = (data.competition.rings[i] & ~0x80000000); - pmaxring = (data.competition.maxrings[i] & ~0x80000000); - pmonitor = (data.competition.monitors[i] & ~0x80000000); - pscore = (data.competition.scores[i] & ~0x80000000); - - V_DrawCenteredString(x+6, y, 0, va("%d", i+1)); - - if (playeringame[data.competition.num[i]]) - { - // Draw the back sprite, it looks ugly if we don't - V_DrawSmallScaledPatch(x+16, y-4, 0, livesback); - - if (data.competition.color[i] == 0) - V_DrawSmallScaledPatch(x+16, y-4, 0,faceprefix[*data.competition.character[i]]); - else - { - UINT8 *colormap = R_GetTranslationColormap(*data.competition.character[i], *data.competition.color[i], GTC_CACHE); - V_DrawSmallMappedPatch(x+16, y-4, 0,faceprefix[*data.competition.character[i]], colormap); - } - - // already constrained to 8 characters - V_DrawString(x+36, y, V_ALLOWLOWERCASE, data.competition.name[i]); - - if (players[data.competition.num[i]].pflags & PF_TIMEOVER) - snprintf(sstrtime, sizeof sstrtime, "Time Over"); - else if (players[data.competition.num[i]].lives <= 0) - snprintf(sstrtime, sizeof sstrtime, "Game Over"); - else - snprintf(sstrtime, sizeof sstrtime, "%i:%02i.%02i", G_TicsToMinutes(ptime, true), - G_TicsToSeconds(ptime), G_TicsToCentiseconds(ptime)); - - sstrtime[sizeof sstrtime - 1] = '\0'; - // Time - V_DrawRightAlignedThinString(x+160, y-1, ((data.competition.times[i] & 0x80000000) ? V_YELLOWMAP : 0), sstrtime); - // Rings - V_DrawRightAlignedThinString(x+188, y-1, V_MONOSPACE|((data.competition.rings[i] & 0x80000000) ? V_YELLOWMAP : 0), va("%u", pring)); - // Total rings - V_DrawRightAlignedThinString(x+216, y-1, V_MONOSPACE|((data.competition.maxrings[i] & 0x80000000) ? V_YELLOWMAP : 0), va("%u", pmaxring)); - // Monitors - V_DrawRightAlignedThinString(x+244, y-1, V_MONOSPACE|((data.competition.monitors[i] & 0x80000000) ? V_YELLOWMAP : 0), va("%u", pmonitor)); - // Score - V_DrawRightAlignedThinString(x+288, y-1, V_MONOSPACE|((data.competition.scores[i] & 0x80000000) ? V_YELLOWMAP : 0), va("%u", pscore)); - // Final Points - V_DrawRightAlignedString(x+312, y, V_YELLOWMAP, va("%d", data.competition.points[i])); - } - - y += 16; - - if (y > 176) - break; - } - } +dotimer: if (timer) - V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP, - va("start in %d seconds", timer/TICRATE)); + { + INT32 tickdown = (timer+1)/TICRATE; + V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, + va("%s in %d", cv_advancemap.string, tickdown)); + } // Make it obvious that scrambling is happening next round. if (cv_scrambleonchange.value && cv_teamscramble.value && (intertic/TICRATE % 2 == 0)) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, V_YELLOWMAP, M_GetText("Teams will be scrambled next round!")); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!")); } // @@ -744,188 +543,47 @@ void Y_Ticker(void) return; } - if (endtic != -1) - return; // tally is done + if (intertic < TICRATE || intertic & 1 || endtic != -1) + return; - /* // SRB2kart - if (intertype == int_coop) // coop or single player, normal level + if (intertype == int_race || intertype == int_match) { - INT32 i; - UINT32 oldscore = data.coop.score; - boolean skip = false; - boolean anybonuses = false; - - if (!intertic) // first time only - S_ChangeMusicInternal("lclear", false); // don't loop it - - if (intertic < TICRATE) // one second pause before tally begins - return; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].cmd.buttons & BT_BRAKE || players[i].cmd.buttons & BT_ACCELERATE)) - skip = true; - - // bonuses count down by 222 each tic - for (i = 0; i < 4; ++i) + if (netgame || multiplayer) { - if (!data.coop.bonuses[i].points) - continue; - - data.coop.bonuses[i].points -= 222; - data.coop.total += 222; - data.coop.score += 222; - if (data.coop.bonuses[i].points < 0 || skip == true) // too far? - { - data.coop.score += data.coop.bonuses[i].points; - data.coop.total += data.coop.bonuses[i].points; - data.coop.bonuses[i].points = 0; - } - if (data.coop.bonuses[i].points > 0) - anybonuses = true; - } - - if (!anybonuses) - { - endtic = intertic + 3*TICRATE; // 3 second pause after end of tally - S_StartSound(NULL, sfx_chchng); // cha-ching! - - // Update when done with tally - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) - { - if (M_UpdateUnlockablesAndExtraEmblems(false)) - S_StartSound(NULL, sfx_ncitem); - - G_SaveGameData(false); - } - } - else if (!(intertic & 1)) - S_StartSound(NULL, sfx_ptally); // tally sound effect - - if (data.coop.gotlife > 0 && (skip == true || data.coop.score % 50000 < oldscore % 50000)) // just passed a 50000 point mark - { - // lives are already added since tally is fake, but play the music - P_PlayLivesJingle(NULL); - --data.coop.gotlife; - } - } - else if (intertype == int_spec) // coop or single player, special stage - { - INT32 i; - UINT32 oldscore = data.spec.score; - boolean skip = false; - static INT32 tallydonetic = 0; - - if (!intertic) // first time only - { - S_ChangeMusicInternal("lclear", false); // don't loop it - tallydonetic = 0; - } - - if (intertic < TICRATE) // one second pause before tally begins - return; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].cmd.buttons & BT_BRAKE || players[i].cmd.buttons & BT_ACCELERATE)) - skip = true; - - if (tallydonetic != 0) - { - if (intertic > tallydonetic) - { - endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - S_StartSound(NULL, sfx_flgcap); // cha-ching! - } - return; - } - - // ring bonus counts down by 222 each tic - data.spec.bonus.points -= 222; - data.spec.score += 222; - if (data.spec.bonus.points < 0 || skip == true) // went too far - { - data.spec.score += data.spec.bonus.points; - data.spec.bonus.points = 0; - } - - if (!data.spec.bonus.points) - { - if (data.spec.continues & 0x80) // don't set endtic yet! - tallydonetic = intertic + (3*TICRATE)/2; - else // okay we're good. - endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - - S_StartSound(NULL, sfx_chchng); // cha-ching! - - // Update when done with tally - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) - { - if (M_UpdateUnlockablesAndExtraEmblems(false)) - S_StartSound(NULL, sfx_ncitem); - - G_SaveGameData(false); - } - } - else if (!(intertic & 1)) - S_StartSound(NULL, sfx_ptally); // tally sound effect - - if (data.spec.gotlife > 0 && (skip == true || data.spec.score % 50000 < oldscore % 50000)) // just passed a 50000 point mark - { - // lives are already added since tally is fake, but play the music - P_PlayLivesJingle(NULL); - --data.spec.gotlife; - } - } - */ - if (intertype == int_timeattack) - { - if (!intertic) - endtic = intertic + 10*TICRATE; // 10 second pause after end of tally - } - else if (intertype == int_race) - { - INT32 q=0,r=0; - - /* // SRB2kart - removed temporarily. - if (!intertic) { - if (!((music_playing == "karwin") // Mario Kart Win - || (music_playing == "karok") // Mario Kart Ok - || (music_playing == "karlos"))) // Mario Kart Lose - S_ChangeMusicInternal("racent", true); // Backup Plan - }*/ - - if (intertic < TICRATE || intertic % 8) - return; - - for (q = 0; q < data.match.numplayers; q++) - { - if (data.match.increase[q]) { - data.match.increase[q]--; - r++; - } - } - if (r) - S_StartSound(NULL, sfx_menu1); - else - if (modeattacking) - endtic = intertic + 10*TICRATE; // 10 second pause after end of tally + if (sorttic == -1) + sorttic = intertic + max((cv_inttime.value/2)-2, 2)*TICRATE; // 8 second pause after match results else - endtic = intertic + 3*TICRATE; // 3 second pause after end of tally - } - else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match - { - if (!intertic) // first time only - S_ChangeMusicInternal("racent", true); // loop it + { + if (!data.match.rankingsmode && (intertic >= sorttic + 8)) + Y_CalculateMatchData(true, Y_CompareRank); - // If a player has left or joined, recalculate scores. - if (data.match.numplayers != D_NumPlayers()) - Y_CalculateMatchWinners(); - } - else if (intertype == int_race || intertype == int_classicrace) // race - { - if (!intertic) // first time only - S_ChangeMusicInternal("racent", true); // loop it + if (data.match.rankingsmode && intertic > sorttic+(2*TICRATE)) + { + INT32 q=0,r=0; + boolean kaching = true; - // Don't bother recalcing for race. It doesn't make as much sense. + for (q = 0; q < data.match.numplayers; q++) + { + if (data.match.num[q] == MAXPLAYERS + || !data.match.increase[data.match.num[q]] + || data.match.increase[data.match.num[q]] == UINT8_MAX) + continue; + + data.match.increase[data.match.num[q]]--; + r++; + if (data.match.increase[data.match.num[q]]) + kaching = false; + } + + if (r) + S_StartSound(NULL, (kaching ? sfx_chchng : sfx_ptally)); + else + endtic = intertic + 3*TICRATE; // 3 second pause after end of tally + } + } + } + else + endtic = intertic + 8*TICRATE; // 8 second pause after end of tally } } @@ -1012,8 +670,6 @@ static void Y_UpdateRecordReplays(void) // void Y_StartIntermission(void) { - INT32 i; - intertic = -1; #ifdef PARANOIA @@ -1025,12 +681,6 @@ void Y_StartIntermission(void) { timer = 0; - /* - if (G_IsSpecialStage(gamemap)) - intertype = (maptol & TOL_NIGHTS) ? int_nightsspec : int_spec; - else - intertype = (maptol & TOL_NIGHTS) ? int_nights : int_coop; - */ /* // srb2kart: time attack tally is UGLY rn if (modeattacking) intertype = int_timeattack; @@ -1050,29 +700,10 @@ void Y_StartIntermission(void) timer = 1; } - /* // SRB2kart - if (gametype == GT_COOP) - { - // Nights intermission is single player only - // Don't add it here - if (G_IsSpecialStage(gamemap)) - intertype = int_spec; - else - intertype = int_coop; - } - else */ - if (gametype == GT_TEAMMATCH) - intertype = int_teammatch; - else if (gametype == GT_MATCH - || gametype == GT_TAG - || gametype == GT_HIDEANDSEEK) + if (gametype == GT_MATCH) intertype = int_match; - else if (gametype == GT_RACE) + else //if (gametype == GT_RACE) intertype = int_race; - else if (gametype == GT_COMPETITION) - intertype = int_classicrace; - else if (gametype == GT_CTF) - intertype = int_ctf; } // We couldn't display the intermission even if we wanted to. @@ -1085,284 +716,17 @@ void Y_StartIntermission(void) switch (intertype) { - case int_nights: - // Can't fail - //G_SetNightsRecords(); - - // Check records - { - UINT8 earnedEmblems = M_CheckLevelEmblems(); - if (earnedEmblems) - CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); - } - - // fall back into the coop intermission for now - intertype = int_timeattack; - /* FALLTHRU */ - case int_timeattack: // coop or single player, normal level // SRB2kart 230117 - replaced int_coop - { - // award time and ring bonuses - // Y_AwardCoopBonuses(); - - // setup time data - data.coop.tics = players[consoleplayer].realtime; - - if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback) - { - // Update visitation flags - mapvisited[gamemap-1] |= MV_BEATEN; - if (ALL7EMERALDS(emeralds)) - mapvisited[gamemap-1] |= MV_ALLEMERALDS; - /*if (ultimatemode) - mapvisited[gamemap-1] |= MV_ULTIMATE; - if (data.coop.gotperfbonus) - mapvisited[gamemap-1] |= MV_PERFECT;*/ - - if (modeattacking == ATTACKING_RECORD) - Y_UpdateRecordReplays(); - } - - for (i = 0; i < 4; ++i) - data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC); - data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC); - - // get act number - /*if (mapheaderinfo[prevmap]->actnum) - data.coop.ttlnum = W_CachePatchName(va("TTL%.2d", mapheaderinfo[prevmap]->actnum), - PU_STATIC); - else*/ - data.coop.ttlnum = W_CachePatchName("TTL01", PU_STATIC); - - // get background patches - widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); - bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); - - // grab an interscreen if appropriate - if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') - { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); - useinterpic = true; - usebuffer = false; - } - else - { - useinterpic = false; -#ifdef HWRENDER - if (rendermode == render_opengl) - usebuffer = true; // This needs to be here for OpenGL, otherwise usebuffer is never set to true for it, and thus there's no screenshot in the intermission -#endif - } - usetile = false; - - // set up the "got through act" message according to skin name - // too long so just show "YOU GOT THROUGH THE ACT" - if (strlen(skins[players[consoleplayer].skin].realname) > 13) - { - strcpy(data.coop.passed1, "YOU GOT"); - strcpy(data.coop.passed2, (strlen(mapheaderinfo[prevmap]->actnum) > 0) ? "THROUGH ACT" : "THROUGH THE ACT"); - } - // long enough that "X GOT" won't fit so use "X PASSED THE ACT" - else if (strlen(skins[players[consoleplayer].skin].realname) > 8) - { - strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname); - strcpy(data.coop.passed2, (strlen(mapheaderinfo[prevmap]->actnum) > 0) ? "PASSED ACT" : "PASSED THE ACT"); - } - // length is okay for normal use - else - { - snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s GOT", - skins[players[consoleplayer].skin].realname); - strcpy(data.coop.passed2, (strlen(mapheaderinfo[prevmap]->actnum) > 0) ? "THROUGH ACT" : "THROUGH THE ACT"); - } - - // set X positions - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - { - data.coop.passedx1 = 62 + (176 - V_LevelNameWidth(data.coop.passed1))/2; - data.coop.passedx2 = 62 + (176 - V_LevelNameWidth(data.coop.passed2))/2; - } - else - { - data.coop.passedx1 = (BASEVIDWIDTH - V_LevelNameWidth(data.coop.passed1))/2; - data.coop.passedx2 = (BASEVIDWIDTH - V_LevelNameWidth(data.coop.passed2))/2; - } - // The above value is not precalculated because it needs only be computed once - // at the start of intermission, and precalculating it would preclude mods - // changing the font to one of a slightly different width. - break; - } - - /* // SRB2kart 230117 - removed - case int_nightsspec: - if (modeattacking && stagefailed) - { - // Nuh-uh. Get out of here. - Y_EndIntermission(); - Y_FollowIntermission(); - break; - } - if (!stagefailed) - G_SetNightsRecords(); - - // Check records - { - UINT8 earnedEmblems = M_CheckLevelEmblems(); - if (earnedEmblems) - CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); - } - - // fall back into the special stage intermission for now - intertype = int_spec; - // FALLTHRU - case int_spec: // coop or single player, special stage - { - // Update visitation flags? - if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback) - { - if (!stagefailed) - mapvisited[gamemap-1] |= MV_BEATEN; - } - - // give out ring bonuses - Y_AwardSpecialStageBonus(); - - data.spec.bonuspatch = W_CachePatchName(data.spec.bonus.patch, PU_STATIC); - data.spec.pscore = W_CachePatchName("YB_SCORE", PU_STATIC); - data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_STATIC); - - // get background tile - bgtile = W_CachePatchName("SPECTILE", PU_STATIC); - - // grab an interscreen if appropriate - if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') - { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); - useinterpic = true; - } - else - useinterpic = false; - - // tile if using the default background - usetile = !useinterpic; - - // get special stage specific patches - if (!stagefailed && ALL7EMERALDS(emeralds)) - { - data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_STATIC); - data.spec.headx = 70; - data.spec.nowsuper = players[consoleplayer].skin - ? NULL : W_CachePatchName("NOWSUPER", PU_STATIC); - } - else - { - data.spec.cemerald = W_CachePatchName("CEMERALD", PU_STATIC); - data.spec.headx = 48; - data.spec.nowsuper = NULL; - } - - // Super form stuff (normally blank) - data.spec.passed3[0] = '\0'; - data.spec.passed4[0] = '\0'; - - // Super form stuff (normally blank) - data.spec.passed3[0] = '\0'; - data.spec.passed4[0] = '\0'; - - // set up the "got through act" message according to skin name - if (stagefailed) - { - strcpy(data.spec.passed2, "SPECIAL STAGE"); - data.spec.passed1[0] = '\0'; - } - else if (ALL7EMERALDS(emeralds)) - { - snprintf(data.spec.passed1, - sizeof data.spec.passed1, "%s", - skins[players[consoleplayer].skin].realname); - data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0'; - strcpy(data.spec.passed2, "GOT THEM ALL!"); - - if (skins[players[consoleplayer].skin].flags & SF_SUPER) - { - strcpy(data.spec.passed3, "CAN NOW BECOME"); - snprintf(data.spec.passed4, - sizeof data.spec.passed4, "SUPER %s", - skins[players[consoleplayer].skin].realname); - data.spec.passed4[sizeof data.spec.passed4 - 1] = '\0'; - } - } - else - { - if (strlen(skins[players[consoleplayer].skin].realname) <= SKINNAMESIZE-5) - { - snprintf(data.spec.passed1, - sizeof data.spec.passed1, "%s GOT", - skins[players[consoleplayer].skin].realname); - data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0'; - } - else - strcpy(data.spec.passed1, "YOU GOT"); - strcpy(data.spec.passed2, "A CHAOS EMERALD"); - } - data.spec.passedx1 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed1))/2; - data.spec.passedx2 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed2))/2; - data.spec.passedx3 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed3))/2; - data.spec.passedx4 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed4))/2; - break; - }*/ - case int_match: { // Calculate who won - Y_CalculateMatchWinners(); - - // set up the levelstring - if (strlen(mapheaderinfo[prevmap]->zonttl) > 0) - { - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "%.32s %.32s * %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s %.32s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl); - } - else - { - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "%.32s * %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s *", - mapheaderinfo[prevmap]->lvlttl); - } - - data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - - // get RESULT header - data.match.result = - W_CachePatchName("RESULT", PU_STATIC); - - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); - usetile = true; - useinterpic = false; + Y_CalculateMatchData(false, Y_CompareBattle); + S_ChangeMusicInternal("racent", true); // loop it break; } - case int_race: // (time-only race) { if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback) // remove this once we have a proper time attack screen { - // setup time data - data.coop.tics = players[consoleplayer].realtime; - // Update visitation flags mapvisited[gamemap-1] |= MV_BEATEN; if (ALL7EMERALDS(emeralds)) @@ -1377,107 +741,7 @@ void Y_StartIntermission(void) } // Calculate who won - Y_CalculateTournamentPoints(); - - // set up the levelstring - if (strlen(mapheaderinfo[prevmap]->zonttl) > 0) - { - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "%.32s %.32s * %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s %.32s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl); - } - else - { - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "%.32s * %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s *", - mapheaderinfo[prevmap]->lvlttl); - } - - data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - - // get RESULT header - //data.match.result = W_CachePatchName("RESULT", PU_STATIC); - - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); - usetile = true; - useinterpic = false; - break; - } - - case int_teammatch: - case int_ctf: - { - // Calculate who won - Y_CalculateMatchWinners(); - - // set up the levelstring - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "%.32s * %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s *", - mapheaderinfo[prevmap]->lvlttl); - - data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - - if (intertype == int_ctf) - { - data.match.redflag = rflagico; - data.match.blueflag = bflagico; - } - else // team match - { - data.match.redflag = rmatcico; - data.match.blueflag = bmatcico; - } - - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); - usetile = true; - useinterpic = false; - break; - } - - case int_classicrace: // classic (full race) - { - // find out who won - Y_CalculateCompetitionWinners(); - - // set up the levelstring - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.competition.levelstring, - sizeof data.competition.levelstring, - "%.32s * %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.competition.levelstring, - sizeof data.competition.levelstring, - "* %.32s *", - mapheaderinfo[prevmap]->lvlttl); - - data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0'; - - // get background tile - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); - usetile = true; - useinterpic = false; + Y_CalculateMatchData(false, Y_CompareRace); break; } @@ -1485,521 +749,42 @@ void Y_StartIntermission(void) default: break; } -} -// -// Y_CalculateMatchWinners -// -static void Y_CalculateMatchWinners(void) -{ - INT32 i, j; - boolean completed[MAXPLAYERS]; - - // Initialize variables - memset(data.match.scores, 0, sizeof (data.match.scores)); - memset(data.match.color, 0, sizeof (data.match.color)); - memset(data.match.character, 0, sizeof (data.match.character)); - memset(data.match.spectator, 0, sizeof (data.match.spectator)); - memset(completed, 0, sizeof (completed)); - data.match.numplayers = 0; - i = j = 0; - - for (j = 0; j < MAXPLAYERS; j++) + if (intertype == int_race || intertype == int_match) { - if (!playeringame[j]) - continue; - - for (i = 0; i < MAXPLAYERS; i++) + // set up the levelstring + if (strlen(mapheaderinfo[prevmap]->zonttl) > 0) { - if (!playeringame[i]) - continue; - - if (players[i].score >= data.match.scores[data.match.numplayers] && completed[i] == false) - { - data.match.scores[data.match.numplayers] = players[i].score; - data.match.color[data.match.numplayers] = &players[i].skincolor; - data.match.character[data.match.numplayers] = &players[i].skin; - data.match.name[data.match.numplayers] = player_names[i]; - data.match.spectator[data.match.numplayers] = players[i].spectator; - data.match.num[data.match.numplayers] = i; - } - } - completed[data.match.num[data.match.numplayers]] = true; - data.match.numplayers++; - } -} - -/* -// -// Y_CalculateTimeRaceWinners -// -static void Y_CalculateTimeRaceWinners(void) -{ - INT32 i, j; - boolean completed[MAXPLAYERS]; - - // Initialize variables - - for (i = 0; i < MAXPLAYERS; i++) - data.match.scores[i] = INT32_MAX; - - memset(data.match.color, 0, sizeof (data.match.color)); - memset(data.match.character, 0, sizeof (data.match.character)); - memset(data.match.spectator, 0, sizeof (data.match.spectator)); - memset(completed, 0, sizeof (completed)); - data.match.numplayers = 0; - i = j = 0; - - for (j = 0; j < MAXPLAYERS; j++) - { - if (!playeringame[j]) - continue; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (players[i].realtime <= data.match.scores[data.match.numplayers] && completed[i] == false) - { - data.match.scores[data.match.numplayers] = players[i].realtime; - data.match.color[data.match.numplayers] = &players[i].skincolor; - data.match.character[data.match.numplayers] = &players[i].skin; - data.match.name[data.match.numplayers] = player_names[i]; - data.match.num[data.match.numplayers] = i; - } - } - completed[data.match.num[data.match.numplayers]] = true; - data.match.numplayers++; - } -} -*/ - -// -// Y_CalculateCompetitionWinners -// -static void Y_CalculateCompetitionWinners(void) -{ - INT32 i, j; - boolean bestat[5]; - boolean completed[MAXPLAYERS]; - INT32 winner; // shortcut - - UINT32 points[MAXPLAYERS]; - UINT32 times[MAXPLAYERS]; - UINT32 rings[MAXPLAYERS]; - UINT32 maxrings[MAXPLAYERS]; - UINT32 monitors[MAXPLAYERS]; - UINT32 scores[MAXPLAYERS]; - - memset(data.competition.points, 0, sizeof (data.competition.points)); - memset(points, 0, sizeof (points)); - memset(completed, 0, sizeof (completed)); - - // Award points. - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - for (j = 0; j < 5; j++) - bestat[j] = true; - - times[i] = players[i].realtime; - rings[i] = (UINT32)max(players[i].health-1, 0); - maxrings[i] = (UINT32)players[i].totalring; - monitors[i] = (UINT32)players[i].numboxes; - scores[i] = (UINT32)min(players[i].score, 99999990); - - for (j = 0; j < MAXPLAYERS; j++) - { - if (!playeringame[j] || j == i) - continue; - - if (players[i].realtime <= players[j].realtime) - points[i]++; + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %.32s %.32s %s *", + mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl, mapheaderinfo[prevmap]->actnum); else - bestat[0] = false; - - if (max(players[i].health-1, 0) >= max(players[j].health-1, 0)) - points[i]++; - else - bestat[1] = false; - - if (players[i].totalring >= players[j].totalring) - points[i]++; - else - bestat[2] = false; - - if (players[i].numboxes >= players[j].numboxes) - points[i]++; - else - bestat[3] = false; - - if (players[i].score >= players[j].score) - points[i]++; - else - bestat[4] = false; + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %.32s %.32s *", + mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl); } - - // Highlight best scores - if (bestat[0]) - times[i] |= 0x80000000; - if (bestat[1]) - rings[i] |= 0x80000000; - if (bestat[2]) - maxrings[i] |= 0x80000000; - if (bestat[3]) - monitors[i] |= 0x80000000; - if (bestat[4]) - scores[i] |= 0x80000000; - } - - // Now we go through and set the data.competition struct properly - data.competition.numplayers = 0; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - winner = 0; - - for (j = 0; j < MAXPLAYERS; j++) - { - if (!playeringame[j]) - continue; - - if (points[j] >= data.competition.points[data.competition.numplayers] && completed[j] == false) - { - data.competition.points[data.competition.numplayers] = points[j]; - data.competition.num[data.competition.numplayers] = winner = j; - } - } - // We know this person won this spot, now let's set everything appropriately - data.competition.times[data.competition.numplayers] = times[winner]; - data.competition.rings[data.competition.numplayers] = rings[winner]; - data.competition.maxrings[data.competition.numplayers] = maxrings[winner]; - data.competition.monitors[data.competition.numplayers] = monitors[winner]; - data.competition.scores[data.competition.numplayers] = scores[winner]; - - snprintf(data.competition.name[data.competition.numplayers], 9, "%s", player_names[winner]); - data.competition.name[data.competition.numplayers][8] = '\0'; - - data.competition.color[data.competition.numplayers] = &players[winner].skincolor; - data.competition.character[data.competition.numplayers] = &players[winner].skin; - - completed[winner] = true; - data.competition.numplayers++; - } -} - -// ============ -// COOP BONUSES -// ============ - -// -// Y_SetNullBonus -// No bonus in this slot, but we need to set some things anyway. -// -static void Y_SetNullBonus(player_t *player, y_bonus_t *bstruct) -{ - (void)player; - memset(bstruct, 0, sizeof(y_bonus_t)); - strncpy(bstruct->patch, "MISSING", sizeof(bstruct->patch)); -} - -// -// Y_SetTimeBonus -// -static void Y_SetTimeBonus(player_t *player, y_bonus_t *bstruct) -{ - INT32 secs, bonus; - - strncpy(bstruct->patch, "YB_TIME", sizeof(bstruct->patch)); - bstruct->display = true; - - // calculate time bonus - secs = player->realtime / TICRATE; - if (secs < 30) /* :30 */ bonus = 100000; - else if (secs < 45) /* :45 */ bonus = 50000; - else if (secs < 60) /* 1:00 */ bonus = 10000; - else if (secs < 90) /* 1:30 */ bonus = 5000; - else if (secs < 120) /* 2:00 */ bonus = 4000; - else if (secs < 180) /* 3:00 */ bonus = 3000; - else if (secs < 240) /* 4:00 */ bonus = 2000; - else if (secs < 300) /* 5:00 */ bonus = 1000; - else if (secs < 360) /* 6:00 */ bonus = 500; - else if (secs < 420) /* 7:00 */ bonus = 400; - else if (secs < 480) /* 8:00 */ bonus = 300; - else if (secs < 540) /* 9:00 */ bonus = 200; - else if (secs < 600) /* 10:00 */ bonus = 100; - else /* TIME TAKEN: TOO LONG */ bonus = 0; - bstruct->points = bonus; -} - -// -// Y_SetRingBonus -// -static void Y_SetRingBonus(player_t *player, y_bonus_t *bstruct) -{ - strncpy(bstruct->patch, "YB_RING", sizeof(bstruct->patch)); - bstruct->display = true; - bstruct->points = max(0, (player->health-1) * 100); -} - -// -// Y_SetLinkBonus -// -/* -static void Y_SetLinkBonus(player_t *player, y_bonus_t *bstruct) // SRB2kart - unused. -{ - strncpy(bstruct->patch, "YB_LINK", sizeof(bstruct->patch)); - bstruct->display = true; - bstruct->points = max(0, (player->maxlink - 1) * 100); -} -*/ - -// -// Y_SetGuardBonus -// -static void Y_SetGuardBonus(player_t *player, y_bonus_t *bstruct) -{ - INT32 bonus; - strncpy(bstruct->patch, "YB_GUARD", sizeof(bstruct->patch)); - bstruct->display = true; - - if (player->timeshit == 0) bonus = 10000; - else if (player->timeshit == 1) bonus = 5000; - else if (player->timeshit == 2) bonus = 1000; - else if (player->timeshit == 3) bonus = 500; - else if (player->timeshit == 4) bonus = 100; - else bonus = 0; - bstruct->points = bonus; -} - -// -// Y_SetPerfectBonus -// -static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct) -{ - INT32 i; - - (void)player; - memset(bstruct, 0, sizeof(y_bonus_t)); - strncpy(bstruct->patch, "YB_PERFE", sizeof(bstruct->patch)); - - if (data.coop.gotperfbonus == -1) - { - INT32 sharedringtotal = 0; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) continue; - sharedringtotal += players[i].health - 1; - } - if (!sharedringtotal || sharedringtotal < nummaprings) - data.coop.gotperfbonus = 0; else - data.coop.gotperfbonus = 1; - } - if (!data.coop.gotperfbonus) - return; - - bstruct->display = true; - bstruct->points = 50000; -} - -// This list can be extended in the future with SOC/Lua, perhaps. -typedef void (*bonus_f)(player_t *, y_bonus_t *); -bonus_f bonuses_list[4][4] = { - { - Y_SetNullBonus, - Y_SetNullBonus, - Y_SetNullBonus, - Y_SetNullBonus, - }, - { - Y_SetNullBonus, - Y_SetTimeBonus, - Y_SetRingBonus, - Y_SetPerfectBonus, - }, - { - Y_SetNullBonus, - Y_SetGuardBonus, - Y_SetRingBonus, - Y_SetNullBonus, - }, - { - Y_SetNullBonus, - Y_SetGuardBonus, - Y_SetRingBonus, - Y_SetPerfectBonus, - }, -}; - - -/* // SRB2kart 230117 - Replaced with Y_CalculateTournamentPoints -// -// Y_AwardCoopBonuses -// -// Awards the time and ring bonuses. -// -static void Y_AwardCoopBonuses(void) -{ - INT32 i, j, bonusnum, oldscore, ptlives; - y_bonus_t localbonuses[4]; - - // set score/total first - data.coop.total = 0; - data.coop.score = players[consoleplayer].score; - data.coop.gotperfbonus = -1; - memset(data.coop.bonuses, 0, sizeof(data.coop.bonuses)); - memset(data.coop.bonuspatches, 0, sizeof(data.coop.bonuspatches)); - - for (i = 0; i < MAXPLAYERS; ++i) - { - if (!playeringame[i] || players[i].lives < 1) // not active or game over - bonusnum = 0; // all null - else - bonusnum = mapheaderinfo[prevmap]->bonustype + 1; // -1 is none - - oldscore = players[i].score; - - for (j = 0; j < 4; ++j) // Set bonuses { - (bonuses_list[bonusnum][j])(&players[i], &localbonuses[j]); - players[i].score += localbonuses[j].points; + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %.32s %s *", + mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); + else + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %.32s *", + mapheaderinfo[prevmap]->lvlttl); } - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; - if (ptlives) - P_GivePlayerLives(&players[i], ptlives); + data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - if (i == consoleplayer) - { - data.coop.gotlife = ptlives; - M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses)); - } - } - - // Just in case the perfect bonus wasn't checked. - if (data.coop.gotperfbonus < 0) - data.coop.gotperfbonus = 0; -} - -// -// Y_AwardSpecialStageBonus -// -// Gives a ring bonus only. -static void Y_AwardSpecialStageBonus(void) -{ - INT32 i, oldscore, ptlives; - y_bonus_t localbonus; - - data.spec.score = players[consoleplayer].score; - memset(&data.spec.bonus, 0, sizeof(data.spec.bonus)); - data.spec.bonuspatch = NULL; - - for (i = 0; i < MAXPLAYERS; i++) - { - oldscore = players[i].score; - - if (!playeringame[i] || players[i].lives < 1) // not active or game over - Y_SetNullBonus(&players[i], &localbonus); - else if (useNightsSS) // Link instead of Score - Y_SetLinkBonus(&players[i], &localbonus); - else - Y_SetRingBonus(&players[i], &localbonus); - players[i].score += localbonus.points; - - // grant extra lives right away since tally is faked - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; - if (ptlives) - P_GivePlayerLives(&players[i], ptlives); - - if (i == consoleplayer) - { - M_Memcpy(&data.spec.bonus, &localbonus, sizeof(data.spec.bonus)); - - data.spec.gotlife = ptlives; - - // Continues related - data.spec.continues = min(players[i].continues, 8); - if (players[i].gotcontinue) - data.spec.continues |= 0x80; - data.spec.playercolor = &players[i].skincolor; - data.spec.playerchar = &players[i].skin; - } - } -} -*/ - -// -// Y_CalculateTournamentPoints -// -static void Y_CalculateTournamentPoints(void) -{ - INT32 i, j; - boolean completed[MAXPLAYERS]; - INT32 numplayersingame = 0; - INT32 increase[MAXPLAYERS]; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - numplayersingame++; - } - - for (i = 0; i < numplayersingame; i++) - { - increase[i] = numplayersingame-i; - - if (increase[i] < 0) - increase[i] = 0; - } - - // Initialize variables - for (j = 0; j < MAXPLAYERS; j++) - data.match.scores[j] = INT32_MAX; - - memset(data.match.time, 0, sizeof (data.match.time)); - memset(data.match.color, 0, sizeof (data.match.color)); - memset(data.match.character, 0, sizeof (data.match.character)); - memset(data.match.spectator, 0, sizeof (data.match.spectator)); - memset(data.match.increase, 0, sizeof (data.match.increase)); - memset(completed, 0, sizeof (completed)); - data.match.numplayers = 0; - i = j = 0; - - for (j = 0; j < MAXPLAYERS; j++) - { - if (!playeringame[j]) - continue; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (players[i].realtime <= data.match.scores[data.match.numplayers] && completed[i] == false) - { - data.match.time[data.match.numplayers] = players[i].realtime; - data.match.scores[data.match.numplayers] = players[i].realtime; - data.match.color[data.match.numplayers] = &players[i].skincolor; - data.match.character[data.match.numplayers] = &players[i].skin; - data.match.name[data.match.numplayers] = player_names[i]; - data.match.spectator[data.match.numplayers] = players[i].spectator; - data.match.num[data.match.numplayers] = i; - } - } - completed[data.match.num[data.match.numplayers]] = true; - if (!(players[data.match.num[data.match.numplayers]].pflags & PF_TIMEOVER - || players[data.match.num[data.match.numplayers]].spectator)) - data.match.increase[data.match.numplayers] = increase[data.match.numplayers]; - players[data.match.num[data.match.numplayers]].score += data.match.increase[data.match.numplayers]; - data.match.scores[data.match.numplayers] = players[data.match.num[data.match.numplayers]].score; - - data.match.numplayers++; + //bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + usetile = useinterpic = false; + usebuffer = true; } } @@ -2013,6 +798,7 @@ void Y_EndIntermission(void) Y_UnloadData(); endtic = -1; + sorttic = -1; intertype = int_none; usebuffer = false; } @@ -2094,9 +880,8 @@ static void Y_UnloadData(void) UNLOAD(bgtile); UNLOAD(interpic); - switch (intertype) + /*switch (intertype) { - /* case int_coop: // unload the coop and single player patches UNLOAD(data.coop.ttlnum); @@ -2114,21 +899,14 @@ static void Y_UnloadData(void) UNLOAD(data.spec.pscore); UNLOAD(data.spec.pcontinues); break; - */ case int_match: case int_race: - UNLOAD(data.match.result); - break; - case int_ctf: - UNLOAD(data.match.blueflag); - UNLOAD(data.match.redflag); - break; default: //without this default, //int_none, int_tag, int_chaos, and int_classicrace //are not handled break; - } + }*/ } // SRB2Kart: Voting! @@ -2149,6 +927,9 @@ void Y_VoteDrawer(void) if (votetic >= voteendtic && voteendtic != -1) return; + if (!voteclient.loaded) + return; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) @@ -2185,9 +966,7 @@ void Y_VoteDrawer(void) { char str[40]; patch_t *pic; - UINT8 sizeadd = selected[i]; - UINT8 j; - UINT8 color; + UINT8 j, color; if (i == 3) { @@ -2203,19 +982,23 @@ void Y_VoteDrawer(void) if (selected[i]) { + UINT8 sizeadd = selected[i]; + for (j = 0; j <= splitscreen; j++) // another loop for drawing the selection backgrounds in the right order, grumble grumble.. { INT32 handy = y; + UINT8 p; UINT8 *colormap; patch_t *thiscurs; if (voteclient.playerinfo[j].selection != i) continue; - if (splitscreen == 0) + if (!splitscreen) { thiscurs = cursor; - color = colortranslations[players[consoleplayer].skincolor][7]; + p = consoleplayer; + color = levelinfo[i].gtc; colormap = NULL; } else @@ -2224,31 +1007,33 @@ void Y_VoteDrawer(void) { case 1: thiscurs = cursor2; - color = colortranslations[players[secondarydisplayplayer].skincolor][7]; - colormap = R_GetTranslationColormap(-1, players[secondarydisplayplayer].skincolor, GTC_CACHE); + p = secondarydisplayplayer; break; case 2: thiscurs = cursor3; - color = colortranslations[players[thirddisplayplayer].skincolor][7]; - colormap = R_GetTranslationColormap(-1, players[thirddisplayplayer].skincolor, GTC_CACHE); + p = thirddisplayplayer; break; case 3: thiscurs = cursor4; - color = colortranslations[players[fourthdisplayplayer].skincolor][7]; - colormap = R_GetTranslationColormap(-1, players[fourthdisplayplayer].skincolor, GTC_CACHE); + p = fourthdisplayplayer; break; default: thiscurs = cursor1; - color = colortranslations[players[consoleplayer].skincolor][7]; - colormap = R_GetTranslationColormap(-1, players[consoleplayer].skincolor, GTC_CACHE); + p = displayplayer; break; } + + color = colortranslations[players[p].skincolor][7]; + colormap = R_GetTranslationColormap(TC_DEFAULT, players[p].skincolor, GTC_CACHE); } + if (votes[p] != -1 || players[p].spectator) + continue; + handy += 6*(3-splitscreen) + (13*j); V_DrawMappedPatch(BASEVIDWIDTH-124, handy, V_SNAPTORIGHT, thiscurs, colormap); - if (votetic % 5 == 0) + if (votetic % 10 < 4) V_DrawFill(BASEVIDWIDTH-100-sizeadd, y-sizeadd, 80+(sizeadd*2), 50+(sizeadd*2), 120|V_SNAPTORIGHT); else V_DrawFill(BASEVIDWIDTH-100-sizeadd, y-sizeadd, 80+(sizeadd*2), 50+(sizeadd*2), color|V_SNAPTORIGHT); @@ -2258,11 +1043,26 @@ void Y_VoteDrawer(void) V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, V_SNAPTORIGHT, pic); V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 40+y, V_SNAPTORIGHT, str); + if (levelinfo[i].gts) + { + INT32 w = V_ThinStringWidth(levelinfo[i].gts, V_SNAPTORIGHT)+1; + V_DrawFill(BASEVIDWIDTH-100, y+10, w+1, 2, V_SNAPTORIGHT|31); + V_DrawFill(BASEVIDWIDTH-100, y, w, 11, V_SNAPTORIGHT|levelinfo[i].gtc); + V_DrawDiag(BASEVIDWIDTH-100+w+1, y, 12, V_SNAPTORIGHT|31); + V_DrawDiag(BASEVIDWIDTH-100+w, y, 11, V_SNAPTORIGHT|levelinfo[i].gtc); + V_DrawThinString(BASEVIDWIDTH-99, y+1, V_SNAPTORIGHT, levelinfo[i].gts); + } + y += 50; } else { V_DrawTinyScaledPatch(BASEVIDWIDTH-60, y, V_SNAPTORIGHT, pic); + if (levelinfo[i].gts) + { + V_DrawDiag(BASEVIDWIDTH-60, y, 8, V_SNAPTORIGHT|31); + V_DrawDiag(BASEVIDWIDTH-60, y, 6, V_SNAPTORIGHT|levelinfo[i].gtc); + } y += 25; } @@ -2281,7 +1081,7 @@ void Y_VoteDrawer(void) { patch_t *pic; - if (votes[i] == 3 && (i != pickedvote || voteendtic == -1)) + if (votes[i] >= 3 && (i != pickedvote || voteendtic == -1)) pic = randomlvl; else pic = levelinfo[votes[i]].pic; @@ -2289,13 +1089,18 @@ void Y_VoteDrawer(void) if (!timer && i == voteclient.ranim) { V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, cursor); - if (votetic % 4 > 1) + if (voteendtic != -1 && !(votetic % 4)) V_DrawFill(x-1, y-1, 42, 27, 120|V_SNAPTOLEFT); else - V_DrawFill(x-1, y-1, 42, 27, 103|V_SNAPTOLEFT); + V_DrawFill(x-1, y-1, 42, 27, levelinfo[votes[i]].gtc|V_SNAPTOLEFT); } V_DrawTinyScaledPatch(x, y, V_SNAPTOLEFT, pic); + if (levelinfo[votes[i]].gts) + { + V_DrawDiag(x, y, 8, V_SNAPTOLEFT|31); + V_DrawDiag(x, y, 6, V_SNAPTOLEFT|levelinfo[votes[i]].gtc); + } if (players[i].skincolor == 0) V_DrawSmallScaledPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[players[i].skin]); @@ -2316,8 +1121,45 @@ void Y_VoteDrawer(void) } if (timer) - V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP|V_SNAPTOBOTTOM, - va("Vote ends in %d seconds", timer/TICRATE)); + { + INT32 hilicol, tickdown = (timer+1)/TICRATE; + if (cons_menuhighlight.value) + hilicol = cons_menuhighlight.value; + else if (gametype == GT_RACE) + hilicol = V_SKYMAP; + else //if (gametype == GT_MATCH) + hilicol = V_REDMAP; + V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, + va("Vote ends in %d", tickdown)); + } +} + +// +// Y_VoteStop +// +// Vote screen's selection stops moving +// +SINT8 deferredlevel = 0; +static void Y_VoteStops(SINT8 pick, SINT8 level) +{ + nextmap = votelevels[level][0]; + + if (level == 4) + S_StartSound(NULL, sfx_noooo2); // gasp + else if (mapheaderinfo[nextmap] && (mapheaderinfo[nextmap]->menuflags & LF2_HIDEINMENU)) + S_StartSound(NULL, sfx_noooo1); // this is bad + else if (!splitscreen && pick == consoleplayer) + S_StartSound(NULL, sfx_yeeeah); // yeeeah! + else + S_StartSound(NULL, sfx_kc48); // just a cool sound + + if (gametype != votelevels[level][1]) + { + INT16 lastgametype = gametype; + gametype = votelevels[level][1]; + D_GameTypeChanged(lastgametype); + forceresetplayers = true; + } } // @@ -2336,8 +1178,11 @@ void Y_VoteTicker(void) if (votetic == voteendtic) { - Y_UnloadVoteData(); // Y_EndVote resets voteendtic too early apparently, causing the game to try to render patches that we just unloaded... - Y_FollowIntermission(); + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } return; } @@ -2378,14 +1223,17 @@ void Y_VoteTicker(void) if (numvotes < 1) // Whoops! Get outta here. { - Y_UnloadVoteData(); - Y_FollowIntermission(); + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } return; } voteclient.rtics--; - if (voteclient.rtics <= 0) + if (voteclient.rtics <= 0 && voteclient.loaded) { voteclient.roffset++; voteclient.rtics = min(20, (3*voteclient.roffset/4)+5); @@ -2399,17 +1247,25 @@ void Y_VoteTicker(void) { if (voteclient.rendoff == 0) { - if (tempvotes[((pickedvote + voteclient.roffset + 4) % numvotes)] == pickedvote - && voteclient.rsynctime % 51 == 0) // Song is 1.45 seconds long (sorry @ whoever wants to replace it in a music wad :V) + if (voteclient.rsynctime % 51 == 0) // Song is 1.45 seconds long (sorry @ whoever wants to replace it in a music wad :V) { - voteclient.rendoff = voteclient.roffset+4; - S_ChangeMusicInternal("voteeb", false); + for (i = 5; i >= 3; i--) // Find a suitable place to stop + { + if (tempvotes[((pickedvote + voteclient.roffset + i) % numvotes)] == pickedvote) + { + voteclient.rendoff = voteclient.roffset+i; + if (M_RandomChance(FRACUNIT/32)) // Let it cheat occasionally~ + voteclient.rendoff++; + S_ChangeMusicInternal("voteeb", false); + break; + } + } } } else if (voteclient.roffset >= voteclient.rendoff) { voteendtic = votetic + (3*TICRATE); - S_StartSound(NULL, sfx_kc48); + Y_VoteStops(pickedvote, deferredlevel); } } } @@ -2522,8 +1378,8 @@ void Y_StartVote(void) I_Error("voteendtic is dirty"); #endif - widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); - bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); + widebgpatch = W_CachePatchName(((gametype == GT_MATCH) ? "BATTLSCW" : "INTERSCW"), PU_STATIC); + bgpatch = W_CachePatchName(((gametype == GT_MATCH) ? "BATTLSCR" : "INTERSCR"), PU_STATIC); cursor = W_CachePatchName("M_CURSOR", PU_STATIC); cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC); cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC); @@ -2549,46 +1405,61 @@ void Y_StartVote(void) for (i = 0; i < MAXPLAYERS; i++) votes[i] = -1; - for (i = 0; i < 4; i++) + for (i = 0; i < 5; i++) { lumpnum_t lumpnum; // set up the str - if (strlen(mapheaderinfo[votelevels[i]]->zonttl) > 0) - { - if (strlen(mapheaderinfo[votelevels[i]]->actnum) > 0) - snprintf(levelinfo[i].str, - sizeof levelinfo[i].str, - "%.32s %.32s %s", - mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->zonttl, mapheaderinfo[votelevels[i]]->actnum); - else - snprintf(levelinfo[i].str, - sizeof levelinfo[i].str, - "%.32s %.32s", - mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->zonttl); - } + if (i == 4) + levelinfo[i].str[0] = '\0'; else { - if (strlen(mapheaderinfo[votelevels[i]]->actnum) > 0) - snprintf(levelinfo[i].str, - sizeof levelinfo[i].str, - "%.32s %s", - mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->actnum); + if (strlen(mapheaderinfo[votelevels[i][0]]->zonttl) > 0) + { + if (strlen(mapheaderinfo[votelevels[i][0]]->actnum) > 0) + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, + "%.32s %.32s %s", + mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->zonttl, mapheaderinfo[votelevels[i][0]]->actnum); + else + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, + "%.32s %.32s", + mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->zonttl); + } else - snprintf(levelinfo[i].str, - sizeof levelinfo[i].str, - "%.32s", - mapheaderinfo[votelevels[i]]->lvlttl); + { + if (strlen(mapheaderinfo[votelevels[i][0]]->actnum) > 0) + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, + "%.32s %s", + mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->actnum); + else + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, + "%.32s", + mapheaderinfo[votelevels[i][0]]->lvlttl); + } + + levelinfo[i].str[sizeof levelinfo[i].str - 1] = '\0'; } - levelinfo[i].str[sizeof levelinfo[i].str - 1] = '\0'; + // set up the gtc and gts + levelinfo[i].gtc = G_GetGametypeColor(votelevels[i][1]); + if (i == 2 && votelevels[i][1] != votelevels[0][1]) + levelinfo[i].gts = gametype_cons_t[votelevels[i][1]].strvalue; + else + levelinfo[i].gts = NULL; - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i]+1))); + // set up the pic + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1))); if (lumpnum != LUMPERROR) - levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i]+1)), PU_STATIC); + levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_STATIC); else levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); } + + voteclient.loaded = true; } // @@ -2608,6 +1479,8 @@ static void Y_UnloadVoteData(void) if (rendermode != render_soft) return; + voteclient.loaded = false; + UNLOAD(widebgpatch); UNLOAD(bgpatch); UNLOAD(cursor); @@ -2617,6 +1490,7 @@ static void Y_UnloadVoteData(void) UNLOAD(cursor4); UNLOAD(randomlvl); + UNLOAD(levelinfo[4].pic); UNLOAD(levelinfo[3].pic); UNLOAD(levelinfo[2].pic); UNLOAD(levelinfo[1].pic); @@ -2630,9 +1504,11 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) { if (pick == -1) // No other votes? We gotta get out of here, then! { - timer = 0; - Y_UnloadVoteData(); - Y_FollowIntermission(); + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } return; } @@ -2652,6 +1528,15 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) if (votes[i] == -1 || endtype > 1) // Don't need to go on continue; + if (level == 4) + { + votes[i] = 4; + continue; + } + + if (endtype == 2) + continue; + if (votecompare == -1) { votecompare = votes[i]; @@ -2661,24 +1546,26 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) endtype = 2; } - if (endtype == 0) // Might as well put this here, too. - { - timer = 0; - Y_UnloadVoteData(); - Y_FollowIntermission(); - return; - } - else if (endtype == 1) // Only one unique vote, so just end it immediately. + if (level == 4 || endtype == 1) // Only one unique vote, so just end it immediately. { voteendtic = votetic + (5*TICRATE); - S_StartSound(NULL, sfx_kc48); S_ChangeMusicInternal("voteeb", false); + Y_VoteStops(pick, level); + } + else if (endtype == 0) // Might as well put this here, too. + { + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } + return; } else S_ChangeMusicInternal("voteea", true); } + deferredlevel = level; pickedvote = pick; - nextmap = votelevels[level]; timer = 0; -} \ No newline at end of file +}