mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 04:21:47 +00:00
Merge branch 'antigrief-returns' into 'master'
[Antigrief pt1] Spectator re-entry timer See merge request KartKrew/Kart!1168
This commit is contained in:
commit
a08a23101c
14 changed files with 335 additions and 67 deletions
|
|
@ -3189,16 +3189,6 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
pnum = READUINT8(*p);
|
pnum = READUINT8(*p);
|
||||||
msg = READUINT8(*p);
|
msg = READUINT8(*p);
|
||||||
|
|
||||||
if (pnum == serverplayer && IsPlayerAdmin(playernum))
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n"));
|
|
||||||
|
|
||||||
if (server)
|
|
||||||
COM_BufAddText("quit\n");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg == KICK_MSG_CUSTOM_BAN || msg == KICK_MSG_CUSTOM_KICK)
|
if (msg == KICK_MSG_CUSTOM_BAN || msg == KICK_MSG_CUSTOM_KICK)
|
||||||
{
|
{
|
||||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||||
|
|
@ -3264,6 +3254,12 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (playernode[pnum] == servernode)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Ignoring kick attempt from %s on node %d (it's the server)\n"), player_names[playernum], servernode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//CONS_Printf("\x82%s ", player_names[pnum]);
|
//CONS_Printf("\x82%s ", player_names[pnum]);
|
||||||
|
|
||||||
// Save bans here. Used to be split between here and the actual command, depending on
|
// Save bans here. Used to be split between here and the actual command, depending on
|
||||||
|
|
@ -3373,6 +3369,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false);
|
HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false);
|
||||||
kickreason = KR_LEAVE;
|
kickreason = KR_LEAVE;
|
||||||
break;
|
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:
|
case KICK_MSG_BANNED:
|
||||||
HU_AddChatText(va("\x82*%s has been banned (No reason given)", player_names[pnum]), false);
|
HU_AddChatText(va("\x82*%s has been banned (No reason given)", player_names[pnum]), false);
|
||||||
kickreason = KR_BAN;
|
kickreason = KR_BAN;
|
||||||
|
|
@ -3418,8 +3418,12 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
M_StartMessage(M_GetText("Server closed connection\n(Synch failure)\nPress (B)\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("Server closed connection\n(Synch failure)\nPress (B)\n"), NULL, MM_NOTHING);
|
||||||
else if (msg == KICK_MSG_PING_HIGH)
|
else if (msg == KICK_MSG_PING_HIGH)
|
||||||
M_StartMessage(M_GetText("Server closed connection\n(Broke delay limit)\nPress (B)\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("Server closed connection\n(Broke delay limit)\nPress (B)\n"), NULL, MM_NOTHING);
|
||||||
|
else if (msg == KICK_MSG_TIMEOUT) // this one will probably never be seen?
|
||||||
|
M_StartMessage(M_GetText("Connection timed out\n\nPress (B)\n"), NULL, MM_NOTHING);
|
||||||
else if (msg == KICK_MSG_BANNED)
|
else if (msg == KICK_MSG_BANNED)
|
||||||
M_StartMessage(M_GetText("You have been banned by the server\n\nPress (B)\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("You have been banned by the server\n\nPress (B)\n"), NULL, MM_NOTHING);
|
||||||
|
else if (msg == KICK_MSG_CUSTOM_KICK)
|
||||||
|
M_StartMessage(M_GetText("You have been kicked\n(Automatic grief detection)\nPress (B)\n"), NULL, MM_NOTHING);
|
||||||
else if (msg == KICK_MSG_CUSTOM_KICK)
|
else if (msg == KICK_MSG_CUSTOM_KICK)
|
||||||
M_StartMessage(va(M_GetText("You have been kicked\n(%s)\nPress (B)\n"), reason), NULL, MM_NOTHING);
|
M_StartMessage(va(M_GetText("You have been kicked\n(%s)\nPress (B)\n"), reason), NULL, MM_NOTHING);
|
||||||
else if (msg == KICK_MSG_CUSTOM_BAN)
|
else if (msg == KICK_MSG_CUSTOM_BAN)
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,7 @@ typedef enum
|
||||||
KICK_MSG_CUSTOM_BAN, // Ban message w/ custom reason
|
KICK_MSG_CUSTOM_BAN, // Ban message w/ custom reason
|
||||||
KICK_MSG_TIMEOUT, // Player's connection timed out
|
KICK_MSG_TIMEOUT, // Player's connection timed out
|
||||||
KICK_MSG_PING_HIGH, // Player hit the ping limit
|
KICK_MSG_PING_HIGH, // Player hit the ping limit
|
||||||
|
KICK_MSG_GRIEF, // Player was detected by antigrief
|
||||||
KICK_MSG_CON_FAIL, // Player failed to resync game state
|
KICK_MSG_CON_FAIL, // Player failed to resync game state
|
||||||
KICK_MSG_SIGFAIL, // Player failed signature check
|
KICK_MSG_SIGFAIL, // Player failed signature check
|
||||||
KICK_MSG__MAX // Number of unique messages
|
KICK_MSG__MAX // Number of unique messages
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,13 @@ consvar_t cv_allowteamchange = CVAR_INIT ("allowteamchange", "Yes", CV_NETVAR, C
|
||||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{1, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t maxplayers_cons_t[] = {{1, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_NETVAR, maxplayers_cons_t, NULL);
|
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_NETVAR, maxplayers_cons_t, NULL);
|
||||||
|
|
||||||
|
static CV_PossibleValue_t spectatorreentry_cons_t[] = {{0, "MIN"}, {10*60, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_spectatorreentry = CVAR_INIT ("spectatorreentry", "30", CV_NETVAR, spectatorreentry_cons_t, NULL);
|
||||||
|
consvar_t cv_duelspectatorreentry = CVAR_INIT ("duelspectatorreentry", "180", CV_NETVAR, spectatorreentry_cons_t, NULL);
|
||||||
|
|
||||||
|
static CV_PossibleValue_t antigrief_cons_t[] = {{10, "MIN"}, {180, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||||
|
consvar_t cv_antigrief = CVAR_INIT ("antigrief", "30", CV_NETVAR, antigrief_cons_t, NULL);
|
||||||
|
|
||||||
consvar_t cv_startinglives = CVAR_INIT ("startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL);
|
consvar_t cv_startinglives = CVAR_INIT ("startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL);
|
||||||
|
|
||||||
static CV_PossibleValue_t respawntime_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "Off"}, {0, NULL}};
|
static CV_PossibleValue_t respawntime_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||||
|
|
@ -788,6 +795,9 @@ void D_RegisterServerCommands(void)
|
||||||
CV_RegisterVar(&cv_restrictskinchange);
|
CV_RegisterVar(&cv_restrictskinchange);
|
||||||
CV_RegisterVar(&cv_allowteamchange);
|
CV_RegisterVar(&cv_allowteamchange);
|
||||||
CV_RegisterVar(&cv_maxplayers);
|
CV_RegisterVar(&cv_maxplayers);
|
||||||
|
CV_RegisterVar(&cv_spectatorreentry);
|
||||||
|
CV_RegisterVar(&cv_duelspectatorreentry);
|
||||||
|
CV_RegisterVar(&cv_antigrief);
|
||||||
CV_RegisterVar(&cv_respawntime);
|
CV_RegisterVar(&cv_respawntime);
|
||||||
|
|
||||||
// d_clisrv
|
// d_clisrv
|
||||||
|
|
@ -1594,6 +1604,35 @@ static void FinalisePlaystateChange(INT32 playernum)
|
||||||
// Clear player score and rings if a spectator.
|
// Clear player score and rings if a spectator.
|
||||||
if (players[playernum].spectator)
|
if (players[playernum].spectator)
|
||||||
{
|
{
|
||||||
|
// To attempt to discourage rage-spectators, we delay any rejoining.
|
||||||
|
// If you're engaging in a DUEL and quit early, in addition to the
|
||||||
|
// indignity of losing your PWR, you get a special extra-long delay.
|
||||||
|
if (netgame)
|
||||||
|
{
|
||||||
|
UINT8 pcount = 0;
|
||||||
|
|
||||||
|
if (cv_duelspectatorreentry.value > cv_spectatorreentry.value)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i] || players[i].spectator)
|
||||||
|
continue;
|
||||||
|
if (++pcount < 2)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
players[playernum].spectatorReentry =
|
||||||
|
(pcount == 1)
|
||||||
|
? (cv_duelspectatorreentry.value * TICRATE)
|
||||||
|
: (cv_spectatorreentry.value * TICRATE);
|
||||||
|
|
||||||
|
//CONS_Printf("player %u got re-entry of %u\n", playernum, players[playernum].spectatorReentry);
|
||||||
|
}
|
||||||
|
|
||||||
if (gametyperules & GTR_POINTLIMIT) // SRB2kart
|
if (gametyperules & GTR_POINTLIMIT) // SRB2kart
|
||||||
{
|
{
|
||||||
players[playernum].roundscore = 0;
|
players[playernum].roundscore = 0;
|
||||||
|
|
@ -3864,7 +3903,7 @@ static void Command_ServerTeamChange_f(void)
|
||||||
static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
changeteam_union NetPacket;
|
changeteam_union NetPacket;
|
||||||
boolean error = false;
|
boolean error = false, wasspectator = false;
|
||||||
NetPacket.value.l = NetPacket.value.b = READINT16(*cp);
|
NetPacket.value.l = NetPacket.value.b = READINT16(*cp);
|
||||||
|
|
||||||
if (!G_GametypeHasTeams() && !G_GametypeHasSpectators()) //Make sure you're in the right gametype.
|
if (!G_GametypeHasTeams() && !G_GametypeHasSpectators()) //Make sure you're in the right gametype.
|
||||||
|
|
@ -3935,7 +3974,9 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
//Safety first!
|
//Safety first!
|
||||||
// (not respawning spectators here...)
|
// (not respawning spectators here...)
|
||||||
if (!players[playernum].spectator && gamestate == GS_LEVEL)
|
wasspectator = (players[playernum].spectator == true);
|
||||||
|
|
||||||
|
if (!wasspectator && gamestate == GS_LEVEL)
|
||||||
{
|
{
|
||||||
if (players[playernum].mo)
|
if (players[playernum].mo)
|
||||||
{
|
{
|
||||||
|
|
@ -3996,7 +4037,7 @@ 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');
|
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
|
HU_AddChatText(va("\x82*%s became a spectator.", player_names[playernum]), false); // "entered the game" text was moved to P_SpectatorJoinGame
|
||||||
|
|
||||||
/*if (G_GametypeHasTeams())
|
/*if (G_GametypeHasTeams())
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ extern consvar_t cv_mute;
|
||||||
extern consvar_t cv_pause;
|
extern consvar_t cv_pause;
|
||||||
|
|
||||||
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_maxplayers, cv_respawntime;
|
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_maxplayers, cv_respawntime;
|
||||||
|
extern consvar_t cv_spectatorreentry, cv_duelspectatorreentry, cv_antigrief;
|
||||||
|
|
||||||
// SRB2kart items
|
// SRB2kart items
|
||||||
extern consvar_t cv_items[NUMKARTRESULTS-1];
|
extern consvar_t cv_items[NUMKARTRESULTS-1];
|
||||||
|
|
|
||||||
|
|
@ -504,6 +504,7 @@ struct player_t
|
||||||
UINT8 oldposition; // Used for taunting when you pass someone
|
UINT8 oldposition; // Used for taunting when you pass someone
|
||||||
UINT8 positiondelay; // Used for position number, so it can grow when passing
|
UINT8 positiondelay; // Used for position number, so it can grow when passing
|
||||||
UINT32 distancetofinish;
|
UINT32 distancetofinish;
|
||||||
|
UINT32 distancetofinishprev;
|
||||||
waypoint_t *currentwaypoint;
|
waypoint_t *currentwaypoint;
|
||||||
waypoint_t *nextwaypoint;
|
waypoint_t *nextwaypoint;
|
||||||
respawnvars_t respawn; // Respawn info
|
respawnvars_t respawn; // Respawn info
|
||||||
|
|
@ -691,6 +692,11 @@ struct player_t
|
||||||
|
|
||||||
tic_t jointime; // Timer when player joins game to change skin/color
|
tic_t jointime; // Timer when player joins game to change skin/color
|
||||||
|
|
||||||
|
tic_t spectatorReentry;
|
||||||
|
|
||||||
|
UINT32 griefValue;
|
||||||
|
UINT8 griefStrikes;
|
||||||
|
|
||||||
UINT8 typing_timer; // Counts down while keystrokes are not emitted
|
UINT8 typing_timer; // Counts down while keystrokes are not emitted
|
||||||
UINT8 typing_duration; // How long since resumed timer
|
UINT8 typing_duration; // How long since resumed timer
|
||||||
|
|
||||||
|
|
|
||||||
14
src/g_game.c
14
src/g_game.c
|
|
@ -2476,6 +2476,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
|
|
||||||
tic_t jointime;
|
tic_t jointime;
|
||||||
|
|
||||||
|
tic_t spectatorReentry;
|
||||||
|
|
||||||
|
UINT32 griefValue;
|
||||||
|
UINT8 griefStrikes;
|
||||||
|
|
||||||
UINT8 splitscreenindex;
|
UINT8 splitscreenindex;
|
||||||
boolean spectator;
|
boolean spectator;
|
||||||
boolean bot;
|
boolean bot;
|
||||||
|
|
@ -2654,6 +2659,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
saveroundconditions = true;
|
saveroundconditions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spectatorReentry = (betweenmaps ? 0 : players[player].spectatorReentry);
|
||||||
|
|
||||||
|
griefValue = players[player].griefValue;
|
||||||
|
griefStrikes = players[player].griefStrikes;
|
||||||
|
|
||||||
if (!betweenmaps)
|
if (!betweenmaps)
|
||||||
{
|
{
|
||||||
follower = players[player].follower;
|
follower = players[player].follower;
|
||||||
|
|
@ -2734,6 +2744,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
p->botvars.rubberband = FRACUNIT;
|
p->botvars.rubberband = FRACUNIT;
|
||||||
p->botvars.controller = UINT16_MAX;
|
p->botvars.controller = UINT16_MAX;
|
||||||
|
|
||||||
|
p->spectatorReentry = spectatorReentry;
|
||||||
|
p->griefValue = griefValue;
|
||||||
|
p->griefStrikes = griefStrikes;
|
||||||
|
|
||||||
memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette));
|
memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette));
|
||||||
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5116,6 +5116,11 @@ static void K_DrawWaypointDebugger(void)
|
||||||
if (stplyr != &players[displayplayers[0]]) // only for p1
|
if (stplyr != &players[displayplayers[0]]) // only for p1
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (netgame)
|
||||||
|
{
|
||||||
|
V_DrawString(8, 146, 0, va("Online griefing: [%u, %u]", stplyr->griefValue/TICRATE, stplyr->griefStrikes));
|
||||||
|
}
|
||||||
|
|
||||||
V_DrawString(8, 156, 0, va("Current Waypoint ID: %d", K_GetWaypointID(stplyr->currentwaypoint)));
|
V_DrawString(8, 156, 0, va("Current Waypoint ID: %d", K_GetWaypointID(stplyr->currentwaypoint)));
|
||||||
V_DrawString(8, 166, 0, va("Next Waypoint ID: %d", K_GetWaypointID(stplyr->nextwaypoint)));
|
V_DrawString(8, 166, 0, va("Next Waypoint ID: %d", K_GetWaypointID(stplyr->nextwaypoint)));
|
||||||
V_DrawString(8, 176, 0, va("Finishline Distance: %d", stplyr->distancetofinish));
|
V_DrawString(8, 176, 0, va("Finishline Distance: %d", stplyr->distancetofinish));
|
||||||
|
|
|
||||||
93
src/k_kart.c
93
src/k_kart.c
|
|
@ -8578,6 +8578,9 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
player->nextwaypoint = nextwaypoint;
|
player->nextwaypoint = nextwaypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update prev value (used for grief prevention code)
|
||||||
|
player->distancetofinishprev = player->distancetofinish;
|
||||||
|
|
||||||
// nextwaypoint is now the waypoint that is in front of us
|
// nextwaypoint is now the waypoint that is in front of us
|
||||||
if ((player->exiting && !(player->pflags & PF_NOCONTEST)) || player->spectator)
|
if ((player->exiting && !(player->pflags & PF_NOCONTEST)) || player->spectator)
|
||||||
{
|
{
|
||||||
|
|
@ -11384,17 +11387,45 @@ void K_CheckSpectateStatus(void)
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (!playeringame[i])
|
if (!playeringame[i])
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
if (players[i].spectator && (players[i].pflags & PF_WANTSTOJOIN))
|
}
|
||||||
players[i].spectatewait++;
|
|
||||||
else
|
if (!players[i].spectator)
|
||||||
|
{
|
||||||
|
numingame++;
|
||||||
players[i].spectatewait = 0;
|
players[i].spectatewait = 0;
|
||||||
|
players[i].spectatorReentry = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((players[i].pflags & PF_WANTSTOJOIN))
|
||||||
|
{
|
||||||
|
players[i].spectatewait++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
players[i].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
|
// No one's allowed to join
|
||||||
if (!cv_allowteamchange.value)
|
if (!cv_allowteamchange.value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// DON'T allow if you've hit the in-game player cap
|
||||||
|
if (cv_maxplayers.value && numingame >= cv_maxplayers.value)
|
||||||
|
return;
|
||||||
|
|
||||||
// Get the number of players in game, and the players to be de-spectated.
|
// Get the number of players in game, and the players to be de-spectated.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -11403,33 +11434,56 @@ void K_CheckSpectateStatus(void)
|
||||||
|
|
||||||
if (!players[i].spectator)
|
if (!players[i].spectator)
|
||||||
{
|
{
|
||||||
numingame++;
|
// Allow if you're not in a level
|
||||||
if (cv_maxplayers.value && numingame >= cv_maxplayers.value) // DON'T allow if you've hit the in-game player cap
|
if (gamestate != GS_LEVEL)
|
||||||
return;
|
|
||||||
if (gamestate != GS_LEVEL) // Allow if you're not in a level
|
|
||||||
continue;
|
continue;
|
||||||
if (players[i].exiting) // DON'T allow if anyone's exiting
|
|
||||||
|
// DON'T allow if anyone's exiting
|
||||||
|
if (players[i].exiting)
|
||||||
return;
|
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;
|
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;
|
return;
|
||||||
if ((gametyperules & GTR_CIRCUIT) && players[i].laps >= 2) // DON'T allow if the race is at 2 laps
|
|
||||||
|
// DON'T allow if the race is at 2 laps
|
||||||
|
if ((gametyperules & GTR_CIRCUIT) && players[i].laps >= 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (players[i].bot || !(players[i].pflags & PF_WANTSTOJOIN))
|
|
||||||
|
if (players[i].bot)
|
||||||
|
{
|
||||||
|
// Spectating bots are controlled by other mechanisms.
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(players[i].pflags & PF_WANTSTOJOIN))
|
||||||
|
{
|
||||||
|
// This spectator does not want to join.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netgame && numingame > 0 && players[i].spectatorReentry > 0)
|
||||||
|
{
|
||||||
|
// This person has their reentry cooldown active.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
respawnlist[numjoiners++] = i;
|
respawnlist[numjoiners++] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// literally zero point in going any further if nobody is joining
|
// Literally zero point in going any further if nobody is joining.
|
||||||
if (!numjoiners)
|
if (!numjoiners)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Organize by spectate wait timer
|
// Organize by spectate wait timer (if there's more than one to sort)
|
||||||
if (cv_maxplayers.value)
|
if (cv_maxplayers.value && numjoiners > 1)
|
||||||
{
|
{
|
||||||
UINT8 oldrespawnlist[MAXPLAYERS];
|
UINT8 oldrespawnlist[MAXPLAYERS];
|
||||||
memcpy(oldrespawnlist, respawnlist, numjoiners);
|
memcpy(oldrespawnlist, respawnlist, numjoiners);
|
||||||
|
|
@ -11456,15 +11510,18 @@ void K_CheckSpectateStatus(void)
|
||||||
// Finally, we can de-spectate everyone!
|
// Finally, we can de-spectate everyone!
|
||||||
for (i = 0; i < numjoiners; i++)
|
for (i = 0; i < numjoiners; i++)
|
||||||
{
|
{
|
||||||
if (cv_maxplayers.value && numingame+i >= cv_maxplayers.value) // Hit the in-game player cap while adding people?
|
|
||||||
break;
|
|
||||||
//CONS_Printf("player %s is joining on tic %d\n", player_names[respawnlist[i]], leveltime);
|
//CONS_Printf("player %s is joining on tic %d\n", player_names[respawnlist[i]], leveltime);
|
||||||
|
|
||||||
P_SpectatorJoinGame(&players[respawnlist[i]]);
|
P_SpectatorJoinGame(&players[respawnlist[i]]);
|
||||||
|
|
||||||
|
// Hit the in-game player cap while adding people?
|
||||||
|
if (cv_maxplayers.value && numingame+i >= cv_maxplayers.value)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the match when 2P joins 1P, DUEL mode
|
// Reset the match when 2P joins 1P, DUEL mode
|
||||||
// Reset the match when 3P joins 1P and 2P, DUEL mode must be disabled
|
// Reset the match when 3P joins 1P and 2P, DUEL mode must be disabled
|
||||||
if (!mapreset && gamestate == GS_LEVEL && (numingame < 3 && numingame+i >= 2)) // use previous i value
|
if (i > 0 && !mapreset && gamestate == GS_LEVEL && (numingame < 3 && numingame+i >= 2))
|
||||||
{
|
{
|
||||||
S_ChangeMusicInternal("chalng", false); // COME ON
|
S_ChangeMusicInternal("chalng", false); // COME ON
|
||||||
mapreset = 3*TICRATE; // Even though only the server uses this for game logic, set for everyone for HUD
|
mapreset = 3*TICRATE; // Even though only the server uses this for game logic, set for everyone for HUD
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->positiondelay);
|
lua_pushinteger(L, plr->positiondelay);
|
||||||
else if (fastcmp(field,"distancetofinish"))
|
else if (fastcmp(field,"distancetofinish"))
|
||||||
lua_pushinteger(L, plr->distancetofinish);
|
lua_pushinteger(L, plr->distancetofinish);
|
||||||
|
else if (fastcmp(field,"distancetofinishprev"))
|
||||||
|
lua_pushinteger(L, plr->distancetofinishprev);
|
||||||
else if (fastcmp(field,"airtime"))
|
else if (fastcmp(field,"airtime"))
|
||||||
lua_pushinteger(L, plr->airtime);
|
lua_pushinteger(L, plr->airtime);
|
||||||
else if (fastcmp(field,"flashing"))
|
else if (fastcmp(field,"flashing"))
|
||||||
|
|
@ -500,6 +502,12 @@ static int player_get(lua_State *L)
|
||||||
lua_pushboolean(L, plr->bot);
|
lua_pushboolean(L, plr->bot);
|
||||||
else if (fastcmp(field,"jointime"))
|
else if (fastcmp(field,"jointime"))
|
||||||
lua_pushinteger(L, plr->jointime);
|
lua_pushinteger(L, plr->jointime);
|
||||||
|
else if (fastcmp(field,"spectatorReentry"))
|
||||||
|
lua_pushinteger(L, plr->spectatorReentry);
|
||||||
|
else if (fastcmp(field,"griefValue"))
|
||||||
|
lua_pushinteger(L, plr->griefValue);
|
||||||
|
else if (fastcmp(field,"griefStrikes"))
|
||||||
|
lua_pushinteger(L, plr->griefStrikes);
|
||||||
else if (fastcmp(field,"splitscreenindex"))
|
else if (fastcmp(field,"splitscreenindex"))
|
||||||
lua_pushinteger(L, plr->splitscreenindex);
|
lua_pushinteger(L, plr->splitscreenindex);
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
|
@ -611,6 +619,8 @@ static int player_set(lua_State *L)
|
||||||
plr->positiondelay = luaL_checkinteger(L, 3);
|
plr->positiondelay = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"distancetofinish"))
|
else if (fastcmp(field,"distancetofinish"))
|
||||||
return NOSET;
|
return NOSET;
|
||||||
|
else if (fastcmp(field,"distancetofinishprev"))
|
||||||
|
return NOSET;
|
||||||
else if (fastcmp(field,"airtime"))
|
else if (fastcmp(field,"airtime"))
|
||||||
plr->airtime = luaL_checkinteger(L, 3);
|
plr->airtime = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"flashing"))
|
else if (fastcmp(field,"flashing"))
|
||||||
|
|
@ -880,6 +890,12 @@ static int player_set(lua_State *L)
|
||||||
return NOSET;
|
return NOSET;
|
||||||
else if (fastcmp(field,"jointime"))
|
else if (fastcmp(field,"jointime"))
|
||||||
return NOSET;
|
return NOSET;
|
||||||
|
else if (fastcmp(field,"spectatorReentry"))
|
||||||
|
plr->spectatorReentry = (UINT32)luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"griefValue"))
|
||||||
|
plr->griefValue = (UINT32)luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"griefStrikes"))
|
||||||
|
plr->griefStrikes = (UINT8)luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"splitscreenindex"))
|
else if (fastcmp(field,"splitscreenindex"))
|
||||||
return NOSET;
|
return NOSET;
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,7 @@ void P_PlayerThink(player_t *player);
|
||||||
void P_PlayerAfterThink(player_t *player);
|
void P_PlayerAfterThink(player_t *player);
|
||||||
void P_DoPlayerExit(player_t *player);
|
void P_DoPlayerExit(player_t *player);
|
||||||
void P_DoTimeOver(player_t *player);
|
void P_DoTimeOver(player_t *player);
|
||||||
|
void P_CheckRaceGriefing(player_t *player, boolean dopunishment);
|
||||||
|
|
||||||
void P_ResetPlayerCheats(void);
|
void P_ResetPlayerCheats(void);
|
||||||
|
|
||||||
|
|
|
||||||
12
src/p_mobj.c
12
src/p_mobj.c
|
|
@ -11682,12 +11682,7 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
else if (netgame && p->jointime <= 1 && pcount)
|
else if (netgame && p->jointime <= 1 && pcount)
|
||||||
{
|
{
|
||||||
p->spectator = true;
|
p->spectator = true;
|
||||||
|
p->spectatorReentry = 0;
|
||||||
#if 0
|
|
||||||
if (pcount == 1 || leveltime < starttime)
|
|
||||||
p->pflags |= PF_WANTSTOJOIN;
|
|
||||||
p->jointime = 2;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (multiplayer && !netgame)
|
else if (multiplayer && !netgame)
|
||||||
{
|
{
|
||||||
|
|
@ -11701,6 +11696,7 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
// Spawn as a spectator,
|
// Spawn as a spectator,
|
||||||
// yes even in splitscreen mode
|
// yes even in splitscreen mode
|
||||||
p->spectator = true;
|
p->spectator = true;
|
||||||
|
|
||||||
if (playernum&1) p->skincolor = skincolor_redteam;
|
if (playernum&1) p->skincolor = skincolor_redteam;
|
||||||
else p->skincolor = skincolor_blueteam;
|
else p->skincolor = skincolor_blueteam;
|
||||||
|
|
||||||
|
|
@ -11722,7 +11718,9 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
{
|
{
|
||||||
// Fix stupid non spectator spectators.
|
// Fix stupid non spectator spectators.
|
||||||
if (!p->spectator && !p->ctfteam)
|
if (!p->spectator && !p->ctfteam)
|
||||||
|
{
|
||||||
p->spectator = true;
|
p->spectator = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Fix team colors.
|
// Fix team colors.
|
||||||
// This code isn't being done right somewhere else. Oh well.
|
// This code isn't being done right somewhere else. Oh well.
|
||||||
|
|
@ -11776,6 +11774,8 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
P_SetScale(mobj, mobj->destscale);
|
P_SetScale(mobj, mobj->destscale);
|
||||||
P_FlashPal(p, 0, 0); // Resets
|
P_FlashPal(p, 0, 0); // Resets
|
||||||
|
|
||||||
|
p->griefValue = 0;
|
||||||
|
|
||||||
K_InitStumbleIndicator(p);
|
K_InitStumbleIndicator(p);
|
||||||
|
|
||||||
K_InitSliptideZipIndicator(p);
|
K_InitSliptideZipIndicator(p);
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,10 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
|
|
||||||
WRITEUINT32(save->p, players[i].jointime);
|
WRITEUINT32(save->p, players[i].jointime);
|
||||||
|
|
||||||
|
WRITEUINT32(save->p, players[i].spectatorReentry);
|
||||||
|
WRITEUINT32(save->p, players[i].griefValue);
|
||||||
|
WRITEUINT8(save->p, players[i].griefStrikes);
|
||||||
|
|
||||||
WRITEUINT8(save->p, players[i].splitscreenindex);
|
WRITEUINT8(save->p, players[i].splitscreenindex);
|
||||||
|
|
||||||
if (players[i].awayview.mobj)
|
if (players[i].awayview.mobj)
|
||||||
|
|
@ -272,6 +276,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
WRITEUINT8(save->p, players[i].oldposition);
|
WRITEUINT8(save->p, players[i].oldposition);
|
||||||
WRITEUINT8(save->p, players[i].positiondelay);
|
WRITEUINT8(save->p, players[i].positiondelay);
|
||||||
WRITEUINT32(save->p, players[i].distancetofinish);
|
WRITEUINT32(save->p, players[i].distancetofinish);
|
||||||
|
WRITEUINT32(save->p, players[i].distancetofinishprev);
|
||||||
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].currentwaypoint));
|
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].currentwaypoint));
|
||||||
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
|
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
|
||||||
WRITEUINT32(save->p, players[i].airtime);
|
WRITEUINT32(save->p, players[i].airtime);
|
||||||
|
|
@ -598,6 +603,10 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
|
|
||||||
players[i].jointime = READUINT32(save->p);
|
players[i].jointime = READUINT32(save->p);
|
||||||
|
|
||||||
|
players[i].spectatorReentry = READUINT32(save->p);
|
||||||
|
players[i].griefValue = READUINT32(save->p);
|
||||||
|
players[i].griefStrikes = READUINT8(save->p);
|
||||||
|
|
||||||
players[i].splitscreenindex = READUINT8(save->p);
|
players[i].splitscreenindex = READUINT8(save->p);
|
||||||
|
|
||||||
flags = READUINT16(save->p);
|
flags = READUINT16(save->p);
|
||||||
|
|
@ -649,6 +658,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
players[i].oldposition = READUINT8(save->p);
|
players[i].oldposition = READUINT8(save->p);
|
||||||
players[i].positiondelay = READUINT8(save->p);
|
players[i].positiondelay = READUINT8(save->p);
|
||||||
players[i].distancetofinish = READUINT32(save->p);
|
players[i].distancetofinish = READUINT32(save->p);
|
||||||
|
players[i].distancetofinishprev = READUINT32(save->p);
|
||||||
players[i].currentwaypoint = (waypoint_t *)(size_t)READUINT32(save->p);
|
players[i].currentwaypoint = (waypoint_t *)(size_t)READUINT32(save->p);
|
||||||
players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save->p);
|
players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save->p);
|
||||||
players[i].airtime = READUINT32(save->p);
|
players[i].airtime = READUINT32(save->p);
|
||||||
|
|
|
||||||
91
src/p_tick.c
91
src/p_tick.c
|
|
@ -617,6 +617,37 @@ static inline void P_DoTeamStuff(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void P_DeviceRumbleTick(void)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
for (i = 0; i <= splitscreen; i++)
|
||||||
|
{
|
||||||
|
player_t *player = &players[g_localplayers[i]];
|
||||||
|
UINT16 low = 0;
|
||||||
|
UINT16 high = 0;
|
||||||
|
|
||||||
|
if (player->mo == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((player->mo->eflags & MFE_DAMAGEHITLAG) && player->mo->hitlag)
|
||||||
|
{
|
||||||
|
low = high = 65536 / 2;
|
||||||
|
}
|
||||||
|
else if (player->sneakertimer > (sneakertime-(TICRATE/2)))
|
||||||
|
{
|
||||||
|
low = high = 65536 / (3+player->numsneakers);
|
||||||
|
}
|
||||||
|
else if (((player->boostpower < FRACUNIT) || (player->stairjank > 8))
|
||||||
|
&& P_IsObjectOnGround(player->mo))
|
||||||
|
{
|
||||||
|
low = high = 65536 / 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_PlayerDeviceRumble(i, low, high);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void P_RunChaseCameras(void)
|
void P_RunChaseCameras(void)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
@ -750,7 +781,7 @@ void P_Ticker(boolean run)
|
||||||
// Run any "after all the other thinkers" stuff
|
// Run any "after all the other thinkers" stuff
|
||||||
{
|
{
|
||||||
player_t *finishingPlayers[MAXPLAYERS];
|
player_t *finishingPlayers[MAXPLAYERS];
|
||||||
UINT8 numFinishingPlayers = 0;
|
UINT8 numingame = 0, numFinishingPlayers = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -758,6 +789,11 @@ void P_Ticker(boolean run)
|
||||||
{
|
{
|
||||||
P_PlayerAfterThink(&players[i]);
|
P_PlayerAfterThink(&players[i]);
|
||||||
|
|
||||||
|
if (players[i].spectator == true)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
numingame++;
|
||||||
|
|
||||||
// Check for the number of ties for first place after every player has thunk run for this tic
|
// Check for the number of ties for first place after every player has thunk run for this tic
|
||||||
if (players[i].exiting == 1 && players[i].position == 1 &&
|
if (players[i].exiting == 1 && players[i].position == 1 &&
|
||||||
(players[i].pflags & (PF_HITFINISHLINE|PF_NOCONTEST)) == PF_HITFINISHLINE)
|
(players[i].pflags & (PF_HITFINISHLINE|PF_NOCONTEST)) == PF_HITFINISHLINE)
|
||||||
|
|
@ -767,37 +803,32 @@ void P_Ticker(boolean run)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply rumble to player if local to machine and not in demo playback
|
if ((netgame) // Antigrief is supposed to apply?
|
||||||
|
&& !(K_Cooperative() || timelimitintics > 0 || g_pointlimit > 0) // There are rules that will punish a griefing player
|
||||||
|
&& (gametyperules & GTR_CIRCUIT) && (leveltime > starttime) && K_GetNumWaypoints()) // The following only detects race griefing
|
||||||
|
{
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
||||||
|
{
|
||||||
|
if (players[i].spectator == true)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (players[i].exiting || (players[i].pflags & PF_NOCONTEST))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (players[i].bot == true)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
P_CheckRaceGriefing(&players[i], (numingame > 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply rumble to local players
|
||||||
if (!demo.playback)
|
if (!demo.playback)
|
||||||
{
|
{
|
||||||
for (i = 0; i <= splitscreen; i++)
|
P_DeviceRumbleTick();
|
||||||
{
|
|
||||||
player_t *player = &players[g_localplayers[i]];
|
|
||||||
UINT16 low = 0;
|
|
||||||
UINT16 high = 0;
|
|
||||||
|
|
||||||
if (player->mo == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((player->mo->eflags & MFE_DAMAGEHITLAG) && player->mo->hitlag)
|
|
||||||
{
|
|
||||||
low = 65536 / 2;
|
|
||||||
high = 65536 / 2;
|
|
||||||
}
|
|
||||||
else if (player->sneakertimer > (sneakertime-(TICRATE/2)))
|
|
||||||
{
|
|
||||||
low = 65536 / (3+player->numsneakers);
|
|
||||||
high = 65536 / (3+player->numsneakers);
|
|
||||||
}
|
|
||||||
else if (((player->boostpower < FRACUNIT) || (player->stairjank > 8))
|
|
||||||
&& P_IsObjectOnGround(player->mo))
|
|
||||||
{
|
|
||||||
low = 65536 / 32;
|
|
||||||
high = 65536 / 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_PlayerDeviceRumble(i, low, high);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numFinishingPlayers > 1)
|
if (numFinishingPlayers > 1)
|
||||||
|
|
|
||||||
81
src/p_user.c
81
src/p_user.c
|
|
@ -4586,6 +4586,87 @@ void P_PlayerAfterThink(player_t *player)
|
||||||
player->mo->pmomz = 0;
|
player->mo->pmomz = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void P_CheckRaceGriefing(player_t *player, boolean dopunishment)
|
||||||
|
{
|
||||||
|
const UINT32 griefMax = cv_antigrief.value * TICRATE;
|
||||||
|
const UINT8 n = player - players;
|
||||||
|
|
||||||
|
const fixed_t requireDist = (12*player->mo->scale) / FRACUNIT;
|
||||||
|
INT32 progress = player->distancetofinishprev - player->distancetofinish;
|
||||||
|
boolean exceptions = (
|
||||||
|
player->flashing != 0
|
||||||
|
|| player->mo->hitlag != 0
|
||||||
|
|| player->airtime > 3*TICRATE/2
|
||||||
|
|| (player->justbumped > 0 && player->justbumped < bumptime-1)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Don't punish if the cvar is turned off,
|
||||||
|
// otherwise NOBODY would be able to play!
|
||||||
|
if (griefMax == 0)
|
||||||
|
{
|
||||||
|
dopunishment = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exceptions && (progress < requireDist))
|
||||||
|
{
|
||||||
|
// If antigrief is disabled, we don't want the
|
||||||
|
// player getting into a hole so deep no amount
|
||||||
|
// of good behaviour could ever make up for it.
|
||||||
|
if (player->griefValue < griefMax)
|
||||||
|
{
|
||||||
|
// Making no progress, start counting against you.
|
||||||
|
player->griefValue++;
|
||||||
|
if (progress < -requireDist && player->griefValue < griefMax)
|
||||||
|
{
|
||||||
|
// Making NEGATIVE progress? Start counting even harder.
|
||||||
|
player->griefValue++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (player->griefValue > 0)
|
||||||
|
{
|
||||||
|
// Playing normally.
|
||||||
|
player->griefValue--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dopunishment && player->griefValue >= griefMax)
|
||||||
|
{
|
||||||
|
if (player->griefStrikes < 3)
|
||||||
|
{
|
||||||
|
player->griefStrikes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
player->griefValue = 0;
|
||||||
|
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
if (player->griefStrikes == 3 && playernode[n] != servernode
|
||||||
|
#ifndef DEVELOP
|
||||||
|
&& !IsPlayerAdmin(n)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Send kick
|
||||||
|
SendKick(n, KICK_MSG_GRIEF);
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void P_SetPlayerAngle(player_t *player, angle_t angle)
|
void P_SetPlayerAngle(player_t *player, angle_t angle)
|
||||||
{
|
{
|
||||||
P_ForceLocalAngle(player, angle);
|
P_ForceLocalAngle(player, angle);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue