From e81a5ee0cacdd17205114770501cd6d47ec3beb7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 18 Sep 2020 00:58:05 -0400 Subject: [PATCH 01/14] Spectator re-entry cooldown --- src/d_clisrv.c | 2 ++ src/d_clisrv.h | 1 + src/d_netcmd.c | 7 ++++++ src/d_player.h | 1 + src/g_game.c | 14 +++++++++++- src/k_kart.c | 52 +++++++++++++++++++++++++++++++++++++-------- src/lua_playerlib.c | 4 ++++ src/p_mobj.c | 10 +++++---- src/p_saveg.c | 2 ++ 9 files changed, 79 insertions(+), 14 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 88fdb35a..8a7bb772 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -644,6 +644,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->onconveyor = LONG(players[i].onconveyor); rsp->jointime = (tic_t)LONG(players[i].jointime); + rsp->spectatorreentry = (tic_t)LONG(players[i].spectatorreentry); rsp->splitscreenindex = players[i].splitscreenindex; @@ -767,6 +768,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].onconveyor = LONG(rsp->onconveyor); players[i].jointime = (tic_t)LONG(rsp->jointime); + players[i].spectatorreentry = (tic_t)LONG(rsp->spectatorreentry); players[i].splitscreenindex = rsp->splitscreenindex; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e94fd7e8..c341c4ae 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -282,6 +282,7 @@ typedef struct INT32 onconveyor; tic_t jointime; + tic_t spectatorreentry; UINT8 splitscreenindex; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4a90de33..7913a086 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -247,6 +247,9 @@ consvar_t cv_allowteamchange = {"allowteamchange", "Yes", CV_NETVAR, CV_YesNo, N static CV_PossibleValue_t ingamecap_cons_t[] = {{0, "MIN"}, {MAXPLAYERS-1, "MAX"}, {0, NULL}}; consvar_t cv_ingamecap = {"ingamecap", "0", CV_NETVAR, ingamecap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t spectatorreentry_cons_t[] = {{0, "MIN"}, {10*60, "MAX"}, {0, NULL}}; +consvar_t cv_spectatorreentry = {"spectatorreentry", "60", CV_NETVAR, spectatorreentry_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; @@ -679,6 +682,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_restrictskinchange); CV_RegisterVar(&cv_allowteamchange); CV_RegisterVar(&cv_ingamecap); + CV_RegisterVar(&cv_spectatorreentry); CV_RegisterVar(&cv_respawntime); CV_RegisterVar(&cv_killingdead); @@ -3703,12 +3707,15 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) // Clear player score and rings if a spectator. if (players[playernum].spectator) { + players[playernum].spectatorreentry = (cv_spectatorreentry.value * TICRATE); + 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; diff --git a/src/d_player.h b/src/d_player.h index 114674ff..52a1e48e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -520,6 +520,7 @@ typedef struct player_s UINT8 bot; tic_t jointime; // Timer when player joins game to change skin/color + tic_t spectatorreentry; UINT8 splitscreenindex; #ifdef HWRENDER diff --git a/src/g_game.c b/src/g_game.c index d9d7b7f1..94d14210 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2603,6 +2603,7 @@ void G_PlayerReborn(INT32 player) INT32 wanted; INT32 respawnflip; boolean songcredit = false; + tic_t spectatorreentry; score = players[player].score; marescore = players[player].marescore; @@ -2644,7 +2645,7 @@ void G_PlayerReborn(INT32 player) pity = players[player].pity; // SRB2kart - if (leveltime <= starttime) + if (leveltime <= starttime || spectator == true) { itemroulette = 0; roulettetype = 0; @@ -2655,6 +2656,14 @@ void G_PlayerReborn(INT32 player) comebackpoints = 0; wanted = 0; starpostwp = 0; + + starposttime = 0; + starpostx = 0; + starposty = 0; + starpostz = 0; + starpostnum = 0; + respawnflip = 0; + starpostangle = 0; } else { @@ -2685,6 +2694,8 @@ void G_PlayerReborn(INT32 player) wanted = players[player].kartstuff[k_wanted]; } + spectatorreentry = players[player].spectatorreentry; + p = &players[player]; memset(p, 0, sizeof (*p)); @@ -2737,6 +2748,7 @@ void G_PlayerReborn(INT32 player) p->kartstuff[k_wanted] = wanted; p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_starpostflip] = respawnflip; + p->spectatorreentry = spectatorreentry; // Don't do anything immediately p->pflags |= PF_USEDOWN; diff --git a/src/k_kart.c b/src/k_kart.c index e6afebc7..7fa062f4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6219,16 +6219,23 @@ void K_CheckSpectateStatus(void) { UINT8 respawnlist[MAXPLAYERS]; UINT8 i, j, numingame = 0, numjoiners = 0; + UINT8 previngame = 0; // Maintain spectate wait timer for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; + if (players[i].spectator && (players[i].pflags & PF_WANTSTOJOIN)) players[i].kartstuff[k_spectatewait]++; else players[i].kartstuff[k_spectatewait] = 0; + + if (gamestate != GS_LEVEL) + players[i].spectatorreentry = 0; + else if (players[i].spectatorreentry > 0) + players[i].spectatorreentry--; } // No one's allowed to join @@ -6244,22 +6251,38 @@ void K_CheckSpectateStatus(void) if (!players[i].spectator) { numingame++; - if (cv_ingamecap.value && numingame >= cv_ingamecap.value) // DON'T allow if you've hit the in-game player cap + + // DON'T allow if you've hit the in-game player cap + if (cv_ingamecap.value && numingame >= cv_ingamecap.value) return; - if (gamestate != GS_LEVEL) // Allow if you're not in a level + + // Allow if you're not in a level + if (gamestate != GS_LEVEL) continue; - if (players[i].exiting) // DON'T allow if anyone's exiting + + // DON'T allow if anyone's exiting + if (players[i].exiting) return; - if (numingame < 2 || leveltime < starttime || mapreset) // Allow if the match hasn't started yet + + // Allow if the match hasn't started yet + if (numingame < 2 || leveltime < starttime || mapreset) continue; - if (leveltime > (starttime + 20*TICRATE)) // DON'T allow if the match is 20 seconds in + + // DON'T allow if the match is 20 seconds in + if (leveltime > (starttime + 20*TICRATE)) return; - if (G_RaceGametype() && players[i].laps) // DON'T allow if the race is at 2 laps + + // DON'T allow if the race is on the second lap + if (G_RaceGametype() && players[i].laps) return; + continue; } else if (!(players[i].pflags & PF_WANTSTOJOIN)) + { + // This spectator does not want to join. continue; + } respawnlist[numjoiners++] = i; } @@ -6269,7 +6292,9 @@ void K_CheckSpectateStatus(void) return; // Organize by spectate wait timer +#if 0 if (cv_ingamecap.value) +#endif { UINT8 oldrespawnlist[MAXPLAYERS]; memcpy(oldrespawnlist, respawnlist, numjoiners); @@ -6293,16 +6318,25 @@ void K_CheckSpectateStatus(void) } } - // Finally, we can de-spectate everyone! + // Finally, we can de-spectate everyone in the list! + previngame = numingame; + for (i = 0; i < numjoiners; i++) { - if (cv_ingamecap.value && numingame+i >= cv_ingamecap.value) // Hit the in-game player cap while adding people? + // Hit the in-game player cap while adding people? Get out of here + if (cv_ingamecap.value > 0 && numingame >= cv_ingamecap.value) break; + + // This person has their reentry cooldown active. + if (players[i].spectatorreentry > 0 && numingame > 0) + continue; + P_SpectatorJoinGame(&players[respawnlist[i]]); + numingame++; } // Reset the match if you're in an empty server - if (!mapreset && gamestate == GS_LEVEL && leveltime >= starttime && (numingame < 2 && numingame+i >= 2)) // use previous i value + if (!mapreset && gamestate == GS_LEVEL && leveltime >= starttime && (previngame < 2 && numingame >= 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 diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 3aeeed73..663e625c 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -382,6 +382,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->bot); else if (fastcmp(field,"jointime")) lua_pushinteger(L, plr->jointime); + else if (fastcmp(field,"spectatorreentry") + lua_pushinteger(L, plr->spectatorreentry); else if (fastcmp(field,"splitscreenindex")) lua_pushinteger(L, plr->splitscreenindex); #ifdef HWRENDER @@ -646,6 +648,8 @@ static int player_set(lua_State *L) return NOSET; else if (fastcmp(field,"jointime")) plr->jointime = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"spectatorreentry")) + plr->spectatorreentry = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"splitscreenindex")) return NOSET; #ifdef HWRENDER diff --git a/src/p_mobj.c b/src/p_mobj.c index 506d7807..1cd7205e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10650,10 +10650,7 @@ void P_SpawnPlayer(INT32 playernum) else if (netgame && p->jointime <= 1 && pcount) { p->spectator = true; - // Oni doesn't want this - /*if (pcount == 1 || leveltime < starttime) - p->pflags |= PF_WANTSTOJOIN; - p->jointime = 2;*/ + p->spectatorreentry = (cv_spectatorreentry.value * TICRATE); } else if (multiplayer && !netgame) { @@ -10667,6 +10664,8 @@ void P_SpawnPlayer(INT32 playernum) // Spawn as a spectator, // yes even in splitscreen mode p->spectator = true; + p->spectatorreentry = (cv_spectatorreentry.value * TICRATE); + if (playernum&1) p->skincolor = skincolor_redteam; else p->skincolor = skincolor_blueteam; @@ -10686,7 +10685,10 @@ void P_SpawnPlayer(INT32 playernum) { // Fix stupid non spectator spectators. if (!p->spectator && !p->ctfteam) + { p->spectator = true; + p->spectatorreentry = (cv_spectatorreentry.value * TICRATE); + } // Fix team colors. // This code isn't being done right somewhere else. Oh well. diff --git a/src/p_saveg.c b/src/p_saveg.c index f587c6e6..178a844c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -246,6 +246,7 @@ static void P_NetArchivePlayers(void) WRITEINT32(save_p, players[i].onconveyor); WRITEUINT32(save_p, players[i].jointime); + WRITEUINT32(save_p, players[i].spectatorreentry); WRITEUINT8(save_p, players[i].splitscreenindex); @@ -411,6 +412,7 @@ static void P_NetUnArchivePlayers(void) players[i].onconveyor = READINT32(save_p); players[i].jointime = READUINT32(save_p); + players[i].spectatorreentry = READUINT32(save_p); players[i].splitscreenindex = READUINT8(save_p); From 7b6d527bd44c8c36863b2318099a31d238b58323 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 20 Sep 2020 17:03:14 -0400 Subject: [PATCH 02/14] Griefing timer Spectates/kicks players who aren't making progress, does it even faster if they're going backwards. --- src/d_clisrv.c | 6 ++++++ src/d_clisrv.h | 3 +++ src/d_netcmd.c | 4 ++++ src/d_netcmd.h | 1 + src/d_player.h | 3 +++ src/g_game.c | 8 ++++++++ src/lua_playerlib.c | 10 ++++++++- src/p_inter.c | 9 +++++++++ src/p_mobj.c | 2 ++ src/p_saveg.c | 6 ++++++ src/p_spec.c | 9 +++++++++ src/p_user.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8a7bb772..008ad906 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -646,6 +646,9 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->jointime = (tic_t)LONG(players[i].jointime); rsp->spectatorreentry = (tic_t)LONG(players[i].spectatorreentry); + rsp->grieftime = (tic_t)LONG(players[i].grieftime); + rsp->griefstrikes = players[i].griefstrikes; + rsp->splitscreenindex = players[i].splitscreenindex; rsp->hasmo = false; @@ -770,6 +773,9 @@ static void resynch_read_player(resynch_pak *rsp) players[i].jointime = (tic_t)LONG(rsp->jointime); players[i].spectatorreentry = (tic_t)LONG(rsp->spectatorreentry); + players[i].grieftime = (tic_t)LONG(rsp->grieftime); + players[i].griefstrikes = rsp->griefstrikes; + players[i].splitscreenindex = rsp->splitscreenindex; //We get a packet for each player in game. diff --git a/src/d_clisrv.h b/src/d_clisrv.h index c341c4ae..98aec37e 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -284,6 +284,9 @@ typedef struct tic_t jointime; tic_t spectatorreentry; + tic_t grieftime; + UINT8 griefstrikes; + UINT8 splitscreenindex; //player->mo stuff diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7913a086..cd8c2318 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -250,6 +250,9 @@ consvar_t cv_ingamecap = {"ingamecap", "0", CV_NETVAR, ingamecap_cons_t, NULL, 0 static CV_PossibleValue_t spectatorreentry_cons_t[] = {{0, "MIN"}, {10*60, "MAX"}, {0, NULL}}; consvar_t cv_spectatorreentry = {"spectatorreentry", "60", CV_NETVAR, spectatorreentry_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t antigrief_cons_t[] = {{20, "MIN"}, {60, "MAX"}, {0, "Off"}, {0, NULL}}; +consvar_t cv_antigrief = {"antigrief", "30", CV_NETVAR, antigrief_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; @@ -683,6 +686,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_allowteamchange); CV_RegisterVar(&cv_ingamecap); CV_RegisterVar(&cv_spectatorreentry); + CV_RegisterVar(&cv_antigrief); CV_RegisterVar(&cv_respawntime); CV_RegisterVar(&cv_killingdead); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 1e158808..1348af03 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -94,6 +94,7 @@ extern consvar_t cv_killingdead; extern consvar_t cv_pause; extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_ingamecap, cv_respawntime; +extern consvar_t cv_spectatorreentry, cv_antigrief; /*extern consvar_t cv_teleporters, cv_superring, cv_supersneakers, cv_invincibility; extern consvar_t cv_jumpshield, cv_watershield, cv_ringshield, cv_forceshield, cv_bombshield; diff --git a/src/d_player.h b/src/d_player.h index 52a1e48e..0f9358ed 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -522,6 +522,9 @@ typedef struct player_s tic_t jointime; // Timer when player joins game to change skin/color tic_t spectatorreentry; + tic_t grieftime; + UINT8 griefstrikes; + UINT8 splitscreenindex; #ifdef HWRENDER fixed_t fovadd; // adjust FOV for hw rendering diff --git a/src/g_game.c b/src/g_game.c index 94d14210..b6cc7b0c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2604,6 +2604,8 @@ void G_PlayerReborn(INT32 player) INT32 respawnflip; boolean songcredit = false; tic_t spectatorreentry; + tic_t grieftime; + UINT8 griefstrikes; score = players[player].score; marescore = players[player].marescore; @@ -2696,6 +2698,9 @@ void G_PlayerReborn(INT32 player) spectatorreentry = players[player].spectatorreentry; + grieftime = players[player].grieftime; + griefstrikes = players[player].griefstrikes; + p = &players[player]; memset(p, 0, sizeof (*p)); @@ -2748,7 +2753,10 @@ void G_PlayerReborn(INT32 player) p->kartstuff[k_wanted] = wanted; p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_starpostflip] = respawnflip; + p->spectatorreentry = spectatorreentry; + p->grieftime = grieftime; + p->griefstrikes = griefstrikes; // Don't do anything immediately p->pflags |= PF_USEDOWN; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 663e625c..26561a4d 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -382,8 +382,12 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->bot); else if (fastcmp(field,"jointime")) lua_pushinteger(L, plr->jointime); - else if (fastcmp(field,"spectatorreentry") + else if (fastcmp(field,"spectatorreentry")) lua_pushinteger(L, plr->spectatorreentry); + else if (fastcmp(field,"grieftime")) + lua_pushinteger(L, plr->grieftime); + else if (fastcmp(field,"griefstrikes")) + lua_pushinteger(L, plr->griefstrikes); else if (fastcmp(field,"splitscreenindex")) lua_pushinteger(L, plr->splitscreenindex); #ifdef HWRENDER @@ -650,6 +654,10 @@ static int player_set(lua_State *L) plr->jointime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"spectatorreentry")) plr->spectatorreentry = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"grieftime")) + plr->grieftime = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"griefstrikes")) + plr->griefstrikes = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"splitscreenindex")) return NOSET; #ifdef HWRENDER diff --git a/src/p_inter.c b/src/p_inter.c index abb12811..7f7c8861 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1454,7 +1454,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { // blatant reuse of a variable that's normally unused in circuit if (!player->tossdelay) + { S_StartSound(toucher, sfx_s26d); + + if (netgame && cv_antigrief.value) + { + player->grieftime += TICRATE; + } + } + player->tossdelay = 3; return; } @@ -1478,6 +1486,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->starpostangle = special->angle; player->starpostnum = special->health; player->kartstuff[k_starpostflip] = special->spawnpoint->options & MTF_OBJECTFLIP; // store flipping + player->grieftime = 0; //S_StartSound(toucher, special->info->painsound); return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1cd7205e..6b58e235 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10730,6 +10730,8 @@ void P_SpawnPlayer(INT32 playernum) // Spawn with a pity shield if necessary. //P_DoPityCheck(p); + p->grieftime = 0; + if (G_BattleGametype()) // SRB2kart { mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW); diff --git a/src/p_saveg.c b/src/p_saveg.c index 178a844c..3a29269b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -248,6 +248,9 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].jointime); WRITEUINT32(save_p, players[i].spectatorreentry); + WRITEUINT32(save_p, players[i].grieftime); + WRITEUINT8(save_p, players[i].griefstrikes); + WRITEUINT8(save_p, players[i].splitscreenindex); WRITEUINT16(save_p, flags); @@ -414,6 +417,9 @@ static void P_NetUnArchivePlayers(void) players[i].jointime = READUINT32(save_p); players[i].spectatorreentry = READUINT32(save_p); + players[i].grieftime = READUINT32(save_p); + players[i].griefstrikes = READUINT8(save_p); + players[i].splitscreenindex = READUINT8(save_p); flags = READUINT16(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index 04d69c9b..73f6938e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4316,12 +4316,21 @@ DoneSection2: nospectategrief = nump; thwompsactive = true; // Lap 2 effects + player->grieftime = 0; } else if (player->starpostnum) { // blatant reuse of a variable that's normally unused in circuit if (!player->tossdelay) + { S_StartSound(player->mo, sfx_s26d); + + if (netgame && cv_antigrief.value) + { + player->grieftime += TICRATE; + } + } + player->tossdelay = 3; } diff --git a/src/p_user.c b/src/p_user.c index cb6b7bd6..6b1e35d0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8489,6 +8489,55 @@ void P_PlayerThink(player_t *player) } } + if (netgame && cv_antigrief.value != 0) + { + if (!player->spectator && !player->exiting && !(player->pflags & PF_TIMEOVER)) + { + const tic_t griefval = cv_antigrief.value * TICRATE; + const UINT8 n = player - players; + + if (n != serverplayer && !IsPlayerAdmin(n)) + { + if (player->grieftime > griefval) + { + player->griefstrikes++; + player->grieftime = 0; + + if (server) + { + if (player->griefstrikes > 2) + { + // Send kick + XBOXSTATIC UINT8 buf[2]; + + buf[0] = n; + buf[1] = KICK_MSG_CON_FAIL; + SendNetXCmd(XD_KICK, &buf, 2); + } + else + { + // Send spectate + changeteam_union NetPacket; + UINT16 usvalue; + + NetPacket.value.l = NetPacket.value.b = 0; + NetPacket.packet.newteam = 0; + NetPacket.packet.playernum = n; + NetPacket.packet.verification = true; + + usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); + SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); + } + } + } + else + { + player->grieftime++; + } + } + } + } + if ((netgame || multiplayer) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) { player->pflags ^= PF_WANTSTOJOIN; From 73331776770b33eafec27de5542fdbec09b6869e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 3 Nov 2020 13:23:10 -0500 Subject: [PATCH 03/14] Remove strike for finishing normally --- src/p_user.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 6b1e35d0..440f00c9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1698,6 +1698,8 @@ void P_DoPlayerExit(player_t *player) if (P_IsLocalPlayer(player) && (!player->spectator && !demo.playback)) legitimateexit = true; + player->griefstrikes--; // Remove a strike for finishing a race normally + if (G_RaceGametype()) // If in Race Mode, allow { player->exiting = raceexittime+2; From 513652c9fadafb3860e32908f04176fc621375f5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 3 Nov 2020 13:23:41 -0500 Subject: [PATCH 04/14] Actually, let's avoid a future bruh moment --- src/p_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 440f00c9..7f022df0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1698,7 +1698,8 @@ void P_DoPlayerExit(player_t *player) if (P_IsLocalPlayer(player) && (!player->spectator && !demo.playback)) legitimateexit = true; - player->griefstrikes--; // Remove a strike for finishing a race normally + if (player->griefstrikes > 0) + player->griefstrikes--; // Remove a strike for finishing a race normally if (G_RaceGametype()) // If in Race Mode, allow { From 8726bb70ace38273f1113ffd2230ba49152a3fd5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 5 Nov 2020 16:15:09 -0500 Subject: [PATCH 05/14] Minor whitespace :p --- src/hu_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 1d0f8b4c..f209e222 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -759,7 +759,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) char *tempchar = NULL; // player is a spectator? - if (players[playernum].spectator) + if (players[playernum].spectator) { cstart = "\x86"; // grey name textcolor = "\x86"; From 83349b2473fc36132596d2524a9eb1ddb67e307a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 13 Apr 2021 02:06:57 -0400 Subject: [PATCH 06/14] Not while flashing --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index df5fb7be..12e12187 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8545,7 +8545,7 @@ void P_PlayerThink(player_t *player) } } } - else + else if (player->powers[pw_flashing] == 0) { player->grieftime++; } From d557b7f962374c955c7617032508134d52bada89 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 3 Dec 2021 20:41:57 +0000 Subject: [PATCH 07/14] Allow antigrief to be tested in dev builds (copy of internal commit) --- src/p_user.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 12e12187..e6ff7d96 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8511,7 +8511,11 @@ void P_PlayerThink(player_t *player) const tic_t griefval = cv_antigrief.value * TICRATE; const UINT8 n = player - players; - if (n != serverplayer && !IsPlayerAdmin(n)) + if (n != serverplayer +#ifndef DEVELOP + && !IsPlayerAdmin(n) +#endif + ) { if (player->grieftime > griefval) { From bac683085c54f76116da6ce56c10b7e6210d8e97 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 4 Dec 2021 15:59:24 +0000 Subject: [PATCH 08/14] Disable the "%s became a spectator" message if you haven't actually entered the game, to prevent an avenue for spam. --- src/d_netcmd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7fe1aa8d..2ca7e457 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3457,7 +3457,7 @@ static void Command_ServerTeamChange_f(void) static void Got_Teamchange(UINT8 **cp, INT32 playernum) { changeteam_union NetPacket; - boolean error = false; + boolean error = false, wasspectator = false; NetPacket.value.l = NetPacket.value.b = READINT16(*cp); if (!G_GametypeHasTeams() && !G_GametypeHasSpectators()) //Make sure you're in the right gametype. @@ -3601,6 +3601,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) else players[playernum].playerstate = PST_REBORN; } + else + wasspectator = true; players[playernum].pflags &= ~PF_WANTSTOJOIN; @@ -3685,7 +3687,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) else 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 == 0) + else if (NetPacket.packet.newteam == 0 && !wasspectator) HU_AddChatText(va("\x82*%s became a spectator.", player_names[playernum]), false); // "entered the game" text was moved to P_SpectatorJoinGame //reset view if you are changed, or viewing someone who was changed. From 19ac63bd6c6d843b0c82a5ee8b7ecced1b846cbf Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 8 Dec 2021 20:57:52 +0000 Subject: [PATCH 09/14] Fix for beocming a spectator while an SPB is on your trail having it continue to follow you around. Done here because it's related to spectators messing up other people's fun. --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index d41c4ffb..61b8e779 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8392,7 +8392,7 @@ void A_SPBChase(mobj_t *actor) if (actor->extravalue1 == 1) // MODE: TARGETING { - if (actor->tracer && actor->tracer->health) + if (actor->tracer && actor->tracer->health && !(actor->tracer->player && actor->tracer->player->spectator)) { fixed_t defspeed = wspeed; From d3986987298ea4009a283f1e4da9c71328a4cc4a Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 15 Dec 2021 17:28:31 +0000 Subject: [PATCH 10/14] Per Sal's request (slightly modified): * Do not allow any joining spectators if anybody got onto the last lap while not in FREE PLAY (this is the same condition as nospectategrief, for consistency). * Reset nospectategrief to 0 if there is literally nobody playing, to prevent a fully locked-out server. * This means it's not a problem to reset spectatorreentry even with the map command. * Change the default for spectatorreentry to 30 seconds, from 60. --- src/d_netcmd.c | 2 +- src/k_kart.c | 6 ++++++ src/p_setup.c | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 2ca7e457..d5e5d9f2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -248,7 +248,7 @@ static CV_PossibleValue_t ingamecap_cons_t[] = {{0, "MIN"}, {MAXPLAYERS-1, "MAX" consvar_t cv_ingamecap = {"ingamecap", "0", CV_NETVAR, ingamecap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t spectatorreentry_cons_t[] = {{0, "MIN"}, {10*60, "MAX"}, {0, NULL}}; -consvar_t cv_spectatorreentry = {"spectatorreentry", "60", CV_NETVAR, spectatorreentry_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_spectatorreentry = {"spectatorreentry", "30", CV_NETVAR, spectatorreentry_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t antigrief_cons_t[] = {{20, "MIN"}, {60, "MAX"}, {0, "Off"}, {0, NULL}}; consvar_t cv_antigrief = {"antigrief", "30", CV_NETVAR, antigrief_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/k_kart.c b/src/k_kart.c index 1c99a43e..a8b3374c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6339,6 +6339,12 @@ void K_CheckSpectateStatus(void) if (!numjoiners) return; + // 1.4: prevent last lap jerkitude + if (!numingame) // but allow empty netgames to recover + nospectategrief = 0; + if (nospectategrief > 1) + return; + // Organize by spectate wait timer #if 0 if (cv_ingamecap.value) diff --git a/src/p_setup.c b/src/p_setup.c index 5956a5f9..24241a7f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2396,6 +2396,8 @@ static void P_LevelInitStuff(void) players[i].exiting = 0; P_ResetPlayer(&players[i]); + players[i].spectatorreentry = 0; // SRB2Kart 1.4 + players[i].mo = NULL; // we must unset axis details too From 71d49bcc3b9c47a171a9e661130ac38be13f8e4b Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 15 Dec 2021 23:21:43 +0000 Subject: [PATCH 11/14] With Sal's feedback, make nospectategrief get set 20 seconds into the map, not on lap 3 --- src/k_kart.c | 21 +++++++++++---------- src/p_spec.c | 4 ---- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index a8b3374c..02a3c77e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6316,10 +6316,6 @@ void K_CheckSpectateStatus(void) if (numingame < 2 || leveltime < starttime || mapreset) continue; - // DON'T allow if the match is 20 seconds in - if (leveltime > (starttime + 20*TICRATE)) - return; - // DON'T allow if the race is on the second lap if (G_RaceGametype() && players[i].laps) return; @@ -6335,16 +6331,21 @@ void K_CheckSpectateStatus(void) respawnlist[numjoiners++] = i; } + // 1.4: prevent last lap jerkitude + if (gamestate == GS_LEVEL) + { + if (!numingame) // but allow empty netgames to recover + nospectategrief = 0; + else if (!nospectategrief && (leveltime > (starttime + 20*TICRATE))) + nospectategrief = numingame; + if (nospectategrief > 1) + return; + } + // literally zero point in going any further if nobody is joining if (!numjoiners) return; - // 1.4: prevent last lap jerkitude - if (!numingame) // but allow empty netgames to recover - nospectategrief = 0; - if (nospectategrief > 1) - return; - // Organize by spectate wait timer #if 0 if (cv_ingamecap.value) diff --git a/src/p_spec.c b/src/p_spec.c index 67d05f2d..4c457b91 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4311,10 +4311,6 @@ DoneSection2: // Play the starpost sound for 'consistency' // S_StartSound(player->mo, sfx_strpst); - // Figure out how many are playing on the last lap, to prevent spectate griefing - if (!nospectategrief && player->laps >= (UINT8)(cv_numlaps.value - 1)) - nospectategrief = nump; - thwompsactive = true; // Lap 2 effects player->grieftime = 0; } From fce57a102767aa3c71334c46effe613b4d472c66 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 29 Mar 2022 15:42:31 -0400 Subject: [PATCH 12/14] startedInFreePlay --- src/d_clisrv.c | 21 +++++++++++++++++++++ src/d_clisrv.h | 17 +++++++++-------- src/g_game.c | 3 +++ src/k_kart.c | 45 ++++++++++++++++++++++++++++++++++++--------- src/p_saveg.c | 2 ++ src/p_setup.c | 39 +++++++++++++++++++++++++++++++-------- src/p_tick.c | 5 +++++ src/p_user.c | 4 ++-- 8 files changed, 109 insertions(+), 27 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 925bf2e4..eb191757 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2972,6 +2972,23 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason) K_CheckBumpers(); else if (G_RaceGametype()) P_CheckRacers(); + + // Reset startedInFreePlay + { + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + break; + } + + if (i == MAXPLAYERS) + { + // Server was emptied, consider it FREE PLAY. + startedInFreePlay = true; + } + } } void CL_Reset(void) @@ -3412,6 +3429,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false); kickreason = KR_LEAVE; break; + case KICK_MSG_GRIEF: + HU_AddChatText(va("\x82*%s has been kicked (Automatic grief detection)", player_names[pnum]), false); + kickreason = KR_KICK; + break; case KICK_MSG_BANNED: HU_AddChatText(va("\x82*%s has been banned (Don't come back)", player_names[pnum]), false); kickreason = KR_BAN; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 7a8272b2..853af371 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -521,17 +521,18 @@ extern consvar_t cv_playbackspeed; #define KICK_MSG_TIMEOUT 4 #define KICK_MSG_BANNED 5 #define KICK_MSG_PING_HIGH 6 -#define KICK_MSG_CUSTOM_KICK 7 -#define KICK_MSG_CUSTOM_BAN 8 +#define KICK_MSG_GRIEF 7 +#define KICK_MSG_CUSTOM_KICK 8 +#define KICK_MSG_CUSTOM_BAN 9 typedef enum { - KR_KICK = 1, //Kicked by server - KR_PINGLIMIT = 2, //Broke Ping Limit - KR_SYNCH = 3, //Synch Failure - KR_TIMEOUT = 4, //Connection Timeout - KR_BAN = 5, //Banned by server - KR_LEAVE = 6, //Quit the game + KR_KICK = 1, //Kicked by server + KR_PINGLIMIT, //Broke Ping Limit + KR_SYNCH, //Synch Failure + KR_TIMEOUT, //Connection Timeout + KR_BAN, //Banned by server + KR_LEAVE, //Quit the game } kickreason_t; diff --git a/src/g_game.c b/src/g_game.c index 91bd11fa..c1034d59 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -275,6 +275,7 @@ tic_t mapreset; // Map reset delay when enough players have joined an empty game UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items +boolean startedInFreePlay; // Map was started in free play // 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? @@ -2482,7 +2483,9 @@ void G_Ticker(boolean 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--; diff --git a/src/k_kart.c b/src/k_kart.c index 02a3c77e..7b95d7a0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6316,6 +6316,10 @@ void K_CheckSpectateStatus(void) if (numingame < 2 || leveltime < starttime || mapreset) continue; + // DON'T allow if the match is 20 seconds in + if (leveltime > (starttime + 20*TICRATE)) + return; + // DON'T allow if the race is on the second lap if (G_RaceGametype() && players[i].laps) return; @@ -6331,15 +6335,11 @@ void K_CheckSpectateStatus(void) respawnlist[numjoiners++] = i; } - // 1.4: prevent last lap jerkitude - if (gamestate == GS_LEVEL) + // The map started as a legitimate race, but there's still the one player. + // Don't allow new joiners, as they're probably a ragespeccer. + if (G_RaceGametype() && startedInFreePlay == false && numingame == 1) { - if (!numingame) // but allow empty netgames to recover - nospectategrief = 0; - else if (!nospectategrief && (leveltime > (starttime + 20*TICRATE))) - nospectategrief = numingame; - if (nospectategrief > 1) - return; + return; } // literally zero point in going any further if nobody is joining @@ -6391,13 +6391,40 @@ void K_CheckSpectateStatus(void) } // Reset the match if you're in an empty server - if (!mapreset && gamestate == GS_LEVEL && leveltime >= starttime && (previngame < 2 && numingame >= 2)) + if (!mapreset && gamestate == GS_LEVEL && (previngame < 2 && numingame >= 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 } } +void K_UpdateSpectateGrief(void) +{ + UINT8 numingame = 0; + + if (nospectategrief) + { + return; + } + + if (leveltime <= (starttime + 20*TICRATE)) + { + return; + } + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + numingame++; + } + + nospectategrief = numingame; +} + //} //{ SRB2kart HUD Code diff --git a/src/p_saveg.c b/src/p_saveg.c index 3a29269b..11ee6630 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3278,6 +3278,7 @@ static void P_NetArchiveMisc(void) WRITEUINT8(save_p, nospectategrief); WRITEUINT8(save_p, thwompsactive); WRITESINT8(save_p, spbplace); + WRITEUINT8(save_p, startedInFreePlay); // Is it paused? if (paused) @@ -3387,6 +3388,7 @@ static inline boolean P_NetUnArchiveMisc(void) nospectategrief = READUINT8(save_p); thwompsactive = (boolean)READUINT8(save_p); spbplace = READSINT8(save_p); + startedInFreePlay = READUINT8(save_p); // Is it paused? if (READUINT8(save_p) == 0x2f) diff --git a/src/p_setup.c b/src/p_setup.c index 24241a7f..1868664d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3229,6 +3229,37 @@ boolean P_SetupLevel(boolean skipprecip) G_RecordDemo(buf); } + wantedcalcdelay = wantedfrequency*2; + indirectitemcooldown = 0; + hyubgone = 0; + mapreset = 0; + nospectategrief = 0; + thwompsactive = false; + spbplace = -1; + + startedInFreePlay = false; + { + UINT8 nump = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + nump++; + if (nump == 2) + { + break; + } + } + + if (nump <= 1) + { + startedInFreePlay = true; + } + } + // =========== // landing point for netgames. netgameskip: @@ -3301,14 +3332,6 @@ boolean P_SetupLevel(boolean skipprecip) CV_SetValue(&cv_analog, false); }*/ - wantedcalcdelay = wantedfrequency*2; - indirectitemcooldown = 0; - hyubgone = 0; - mapreset = 0; - nospectategrief = 0; - thwompsactive = false; - spbplace = -1; - // clear special respawning que iquehead = iquetail = 0; diff --git a/src/p_tick.c b/src/p_tick.c index 6a85027f..11adc9d8 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -735,6 +735,11 @@ void P_Ticker(boolean run) if (hyubgone > 0) hyubgone--; + if (G_RaceGametype()) + { + K_UpdateSpectateGrief(); + } + if (G_BattleGametype()) { if (wantedcalcdelay && --wantedcalcdelay <= 0) diff --git a/src/p_user.c b/src/p_user.c index e6ff7d96..a6f13990 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8504,7 +8504,7 @@ void P_PlayerThink(player_t *player) } } - if (netgame && cv_antigrief.value != 0) + if (netgame && cv_antigrief.value != 0 && G_RaceGametype()) { if (!player->spectator && !player->exiting && !(player->pflags & PF_TIMEOVER)) { @@ -8530,7 +8530,7 @@ void P_PlayerThink(player_t *player) XBOXSTATIC UINT8 buf[2]; buf[0] = n; - buf[1] = KICK_MSG_CON_FAIL; + buf[1] = KICK_MSG_GRIEF; SendNetXCmd(XD_KICK, &buf, 2); } else From a031998f5f48cf500df9c42536ad1bdf33bccb45 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 29 Mar 2022 15:46:02 -0400 Subject: [PATCH 13/14] Fix compile errors --- src/doomstat.h | 1 + src/k_kart.c | 1 + src/k_kart.h | 1 + 3 files changed, 3 insertions(+) diff --git a/src/doomstat.h b/src/doomstat.h index 232a5af8..ed6af452 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -477,6 +477,7 @@ extern tic_t mapreset; extern UINT8 nospectategrief; extern boolean thwompsactive; extern SINT8 spbplace; +extern boolean startedInFreePlay; extern boolean legitimateexit; extern boolean comebackshowninfo; diff --git a/src/k_kart.c b/src/k_kart.c index 7b95d7a0..615f1b74 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6401,6 +6401,7 @@ void K_CheckSpectateStatus(void) void K_UpdateSpectateGrief(void) { UINT8 numingame = 0; + INT32 i; if (nospectategrief) { diff --git a/src/k_kart.h b/src/k_kart.h index 79606540..b664f9c3 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -68,6 +68,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground); void K_CalculateBattleWanted(void); void K_CheckBumpers(void); void K_CheckSpectateStatus(void); +void K_UpdateSpectateGrief(void); // sound stuff for lua void K_PlayAttackTaunt(mobj_t *source); From 6c8938af6b5d2c0288557e24ad0e59ab800b2fa1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 29 Mar 2022 17:17:57 -0400 Subject: [PATCH 14/14] not on player join --- src/p_mobj.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 91b15a7a..6dfaefe5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10663,7 +10663,7 @@ void P_SpawnPlayer(INT32 playernum) else if (netgame && p->jointime <= 1 && pcount) { p->spectator = true; - p->spectatorreentry = (cv_spectatorreentry.value * TICRATE); + p->spectatorreentry = 0; //(cv_spectatorreentry.value * TICRATE); } else if (multiplayer && !netgame) { @@ -10677,7 +10677,7 @@ void P_SpawnPlayer(INT32 playernum) // Spawn as a spectator, // yes even in splitscreen mode p->spectator = true; - p->spectatorreentry = (cv_spectatorreentry.value * TICRATE); + p->spectatorreentry = 0; //(cv_spectatorreentry.value * TICRATE); if (playernum&1) p->skincolor = skincolor_redteam; else p->skincolor = skincolor_blueteam; @@ -10700,7 +10700,7 @@ void P_SpawnPlayer(INT32 playernum) if (!p->spectator && !p->ctfteam) { p->spectator = true; - p->spectatorreentry = (cv_spectatorreentry.value * TICRATE); + p->spectatorreentry = 0; //(cv_spectatorreentry.value * TICRATE); } // Fix team colors.