Port basic lap anticheat for new waypoints from RR
This commit is contained in:
parent
58e243a20c
commit
bda7d26a0f
15 changed files with 145 additions and 13 deletions
|
|
@ -469,6 +469,7 @@ consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off",
|
|||
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
|
||||
consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
|
||||
consvar_t cv_kartdebuglap = CVAR_INIT ("kartdebuglap", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
|
||||
consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ extern consvar_t cv_votetime;
|
|||
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;
|
||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
|
||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebuglap,cv_kartdebugbotpredict;
|
||||
|
||||
extern consvar_t cv_itemfinder;
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ typedef enum
|
|||
PF_UPDATEMYRESPAWN = 1<<19,
|
||||
|
||||
PF_FLIPCAM = 1<<20,
|
||||
//free = 1<<21,
|
||||
PF_TRUSTWAYPOINTS = 1<<21, // Do not activate lap cheat prevention next time finish line distance is updated
|
||||
|
||||
PF_HITFINISHLINE = 1<<22, // Already hit the finish line this tic
|
||||
PF_WRONGWAY = 1<<23, // Moving the wrong way with respect to waypoints?
|
||||
|
|
@ -548,6 +548,7 @@ struct player_t
|
|||
UINT32 distancetofinishprev;
|
||||
waypoint_t *currentwaypoint;
|
||||
waypoint_t *nextwaypoint;
|
||||
UINT16 bigwaypointgap;
|
||||
tic_t airtime; // Keep track of how long you've been in the air
|
||||
UINT8 startboost; // (0 to 125) - Boost you get from start of race or respawn drop dash
|
||||
|
||||
|
|
@ -657,6 +658,9 @@ struct player_t
|
|||
|
||||
UINT16 breathTimer; // Holding your breath underwater
|
||||
|
||||
UINT8 lastsafelap;
|
||||
UINT8 lastsafestarpost;
|
||||
|
||||
//
|
||||
|
||||
SINT8 lives;
|
||||
|
|
|
|||
|
|
@ -1408,6 +1408,8 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
mapheaderinfo[num]->encorepal = (UINT16)i;
|
||||
else if (fastcmp(word, "NUMLAPS"))
|
||||
mapheaderinfo[num]->numlaps = (UINT8)i;
|
||||
else if (fastcmp(word, "LAPSPERSECTION"))
|
||||
mapheaderinfo[num]->lapspersection = max((UINT8)i, 1u);
|
||||
else if (fastcmp(word, "UNLOCKABLE"))
|
||||
{
|
||||
if (i >= 0 && i <= MAXUNLOCKABLES) // 0 for no unlock required, anything else requires something
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ const char *const PLAYERFLAG_LIST[] = {
|
|||
"UPDATEMYRESPAWN",
|
||||
|
||||
"FLIPCAM",
|
||||
"\x01",
|
||||
"TRUSTWAYPOINTS",
|
||||
|
||||
"HITFINISHLINE", // Already hit the finish line this tic
|
||||
"WRONGWAY", // Moving the wrong way with respect to waypoints?
|
||||
|
|
|
|||
|
|
@ -413,6 +413,7 @@ struct mapheader_t
|
|||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden.
|
||||
UINT8 lapspersection; ///< Number of laps per section in hybrid section-circuit maps.
|
||||
fixed_t gravity; ///< Map-wide gravity.
|
||||
|
||||
// Music information
|
||||
|
|
|
|||
13
src/g_game.c
13
src/g_game.c
|
|
@ -2359,6 +2359,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
UINT16 nocontrol;
|
||||
INT32 kickstartaccel;
|
||||
boolean enteredGame;
|
||||
UINT8 lastsafelap;
|
||||
UINT8 lastsafestarpost;
|
||||
UINT16 bigwaypointgap;
|
||||
|
||||
score = players[player].score;
|
||||
lives = players[player].lives;
|
||||
|
|
@ -2412,6 +2415,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
wanted = 0;
|
||||
rings = 10;
|
||||
kickstartaccel = 0;
|
||||
lastsafelap = 0;
|
||||
lastsafestarpost = 0;
|
||||
bigwaypointgap = 0;
|
||||
nocontrol = 0;
|
||||
laps = 0;
|
||||
latestlap = 0;
|
||||
|
|
@ -2479,6 +2485,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
prevcheck = players[player].nextcheck;
|
||||
|
||||
pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_LOSTLIFE|PF_FLIPCAM));
|
||||
|
||||
lastsafelap = players[player].lastsafelap;
|
||||
lastsafestarpost = players[player].lastsafestarpost;
|
||||
bigwaypointgap = players[player].bigwaypointgap;
|
||||
}
|
||||
|
||||
if (!betweenmaps)
|
||||
|
|
@ -2513,6 +2523,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->splitscreenindex = splitscreenindex;
|
||||
p->spectator = spectator;
|
||||
p->angleturn = playerangleturn;
|
||||
p->lastsafelap = lastsafelap;
|
||||
p->lastsafestarpost = lastsafestarpost;
|
||||
p->bigwaypointgap = bigwaypointgap;
|
||||
|
||||
// save player config truth reborn
|
||||
p->skincolor = skincolor;
|
||||
|
|
|
|||
|
|
@ -4299,6 +4299,11 @@ static void K_DrawWaypointDebugger(void)
|
|||
if (stplyr != &players[displayplayers[0]]) // only for p1
|
||||
return;
|
||||
|
||||
if (stplyr->bigwaypointgap)
|
||||
{
|
||||
V_DrawString(8, 146, 0, va("Auto Respawn Timer: %d", stplyr->bigwaypointgap));
|
||||
}
|
||||
|
||||
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, 176, 0, va("Finishline Distance: %d", stplyr->distancetofinish));
|
||||
|
|
|
|||
81
src/k_kart.c
81
src/k_kart.c
|
|
@ -238,6 +238,7 @@ void K_RegisterKartStuff(void)
|
|||
CV_RegisterVar(&cv_kartdebugdistribution);
|
||||
CV_RegisterVar(&cv_kartdebughuddrop);
|
||||
CV_RegisterVar(&cv_kartdebugwaypoints);
|
||||
CV_RegisterVar(&cv_kartdebuglap);
|
||||
CV_RegisterVar(&cv_kartdebugbotpredict);
|
||||
|
||||
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
||||
|
|
@ -7025,6 +7026,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
if (player->checkskip)
|
||||
player->checkskip--;
|
||||
|
||||
if (player->bigwaypointgap && (player->bigwaypointgap > AUTORESPAWN_THRESHOLD || !P_PlayerInPain(player)))
|
||||
{
|
||||
player->bigwaypointgap--;
|
||||
if (!player->bigwaypointgap)
|
||||
P_KillMobj(player->mo, NULL, NULL, DMG_INSTAKILL);
|
||||
else if (player->bigwaypointgap == AUTORESPAWN_THRESHOLD)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s26d);
|
||||
CONS_Printf("You are going the wrong way! You will automatically respawn in 7 seconds.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (player->growshrinktimer != 0)
|
||||
{
|
||||
if (player->growshrinktimer > 0)
|
||||
|
|
@ -8134,7 +8147,7 @@ static void K_UpdateDistanceFromFinishLine(player_t *player)
|
|||
const mapheader_t *mapheader = mapheaderinfo[gamemap - 1];
|
||||
if ((mapheader->levelflags & LF_SECTIONRACE) == 0U)
|
||||
{
|
||||
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps);
|
||||
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps) / mapheader->lapspersection;
|
||||
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
||||
}
|
||||
}
|
||||
|
|
@ -8183,24 +8196,59 @@ static void K_UpdatePlayerWaypoints(player_t *const player)
|
|||
boolean updaterespawn = K_SetPlayerNextWaypoint(player);
|
||||
|
||||
// Update prev value (used for grief prevention code)
|
||||
K_UpdateDistanceFromFinishLine(player);
|
||||
player->distancetofinishprev = player->distancetofinish;
|
||||
K_UpdateDistanceFromFinishLine(player);
|
||||
|
||||
// Respawning should be a full reset.
|
||||
UINT32 delta = u32_delta(player->distancetofinish, player->distancetofinishprev);
|
||||
if (!player->respawn && delta > distance_threshold)
|
||||
if (delta > distance_threshold &&
|
||||
!player->respawn && // Respawning should be a full reset.
|
||||
old_currentwaypoint != NULL && // So should touching the first waypoint ever.
|
||||
player->laps != 0 && // POSITION rooms may have unorthodox waypoints to guide bots.
|
||||
!(player->pflags & PF_TRUSTWAYPOINTS)) // Special exception.
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %s: waypoint ID %d too far away (%u > %u)\n",
|
||||
sizeu1(player - players), K_GetWaypointID(player->nextwaypoint), delta, distance_threshold);
|
||||
#define debug_args "Player %s: waypoint ID %d too far away (%u > %u)\n", \
|
||||
sizeu1(player - players), K_GetWaypointID(player->nextwaypoint), delta, distance_threshold
|
||||
if (cv_kartdebuglap.value)
|
||||
CONS_Printf(debug_args);
|
||||
else
|
||||
CONS_Debug(DBG_GAMELOGIC, debug_args);
|
||||
#undef debug_args
|
||||
|
||||
// Distance jump is too great, keep the old waypoints and recalculate distance.
|
||||
player->currentwaypoint = old_currentwaypoint;
|
||||
player->nextwaypoint = old_nextwaypoint;
|
||||
player->distancetofinish = player->distancetofinishprev;
|
||||
if (!cv_kartdebuglap.value)
|
||||
{
|
||||
// Distance jump is too great, keep the old waypoints and old distance.
|
||||
player->currentwaypoint = old_currentwaypoint;
|
||||
player->nextwaypoint = old_nextwaypoint;
|
||||
player->distancetofinish = player->distancetofinishprev;
|
||||
|
||||
// Start the auto respawn timer when the distance jumps.
|
||||
if (!player->bigwaypointgap)
|
||||
{
|
||||
player->bigwaypointgap = AUTORESPAWN_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset the auto respawn timer if distance changes are back to normal.
|
||||
if (player->bigwaypointgap && player->bigwaypointgap <= AUTORESPAWN_THRESHOLD + 1)
|
||||
{
|
||||
player->bigwaypointgap = 0;
|
||||
|
||||
// While the player was in the "bigwaypointgap" state, laps did not change from crossing finish lines.
|
||||
// So reset the lap back to normal, in case they were able to get behind the line.
|
||||
player->laps = player->lastsafelap;
|
||||
if (numbosswaypoints == 0)
|
||||
{
|
||||
player->starpostnum = player->lastsafestarpost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Respawn point should only be updated when we're going to a nextwaypoint
|
||||
if ((updaterespawn) &&
|
||||
(player->bigwaypointgap == 0) &&
|
||||
(!player->respawn) &&
|
||||
(player->nextwaypoint != old_nextwaypoint) &&
|
||||
(K_GetWaypointIsSpawnpoint(player->nextwaypoint)) &&
|
||||
|
|
@ -8209,6 +8257,9 @@ static void K_UpdatePlayerWaypoints(player_t *const player)
|
|||
if (!(player->pflags & PF_WRONGWAY))
|
||||
player->grieftime = 0;
|
||||
|
||||
player->lastsafelap = player->laps;
|
||||
player->lastsafestarpost = player->starpostnum;
|
||||
|
||||
// Check if respawn is safe. If not then goto next spawnpoint and respawn there.
|
||||
if (K_SafeRespawnPosition(player->mo))
|
||||
{
|
||||
|
|
@ -8244,6 +8295,8 @@ static void K_UpdatePlayerWaypoints(player_t *const player)
|
|||
K_FudgeRespawn(player, player->nextwaypoint);
|
||||
}
|
||||
}
|
||||
|
||||
player->pflags &= ~PF_TRUSTWAYPOINTS; // clear special exception
|
||||
}
|
||||
|
||||
INT32 K_GetKartRingPower(player_t *player, boolean boosted)
|
||||
|
|
@ -8819,6 +8872,16 @@ void K_UpdateAllPlayerPositions(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (player->respawn > 0 && player->lastsafelap != player->laps)
|
||||
{
|
||||
player->laps = player->lastsafelap;
|
||||
|
||||
if (numbosswaypoints == 0)
|
||||
{
|
||||
player->starpostnum = player->lastsafestarpost;
|
||||
}
|
||||
}
|
||||
|
||||
K_UpdatePlayerWaypoints(player);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ Make sure this matches the actual number of states
|
|||
#define GROW_SCALE ((3*FRACUNIT)/2)
|
||||
#define SHRINK_SCALE ((6*FRACUNIT)/8)
|
||||
|
||||
#define AUTORESPAWN_TIME (10 * TICRATE)
|
||||
#define AUTORESPAWN_THRESHOLD (7 * TICRATE)
|
||||
|
||||
// Used for respawning checks.
|
||||
|
||||
typedef struct respawnresult_s
|
||||
|
|
|
|||
|
|
@ -2609,6 +2609,8 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->palette);
|
||||
else if (fastcmp(field,"numlaps"))
|
||||
lua_pushinteger(L, header->numlaps);
|
||||
else if (fastcmp(field,"lapspersection"))
|
||||
lua_pushinteger(L, header->lapspersection);
|
||||
else if (fastcmp(field,"unlockrequired"))
|
||||
lua_pushinteger(L, header->unlockrequired);
|
||||
else if (fastcmp(field,"levelselect"))
|
||||
|
|
|
|||
|
|
@ -388,6 +388,12 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->confirmVictimDelay);
|
||||
else if (fastcmp(field,"glanceDir"))
|
||||
lua_pushinteger(L, plr->glanceDir);
|
||||
else if (fastcmp(field,"breathTimer"))
|
||||
lua_pushinteger(L, plr->breathTimer);
|
||||
else if (fastcmp(field,"lastsafelap"))
|
||||
lua_pushinteger(L, plr->lastsafelap);
|
||||
else if (fastcmp(field,"laststarpost"))
|
||||
lua_pushinteger(L, plr->lastsafestarpost);
|
||||
else if (fastcmp(field,"roundscore"))
|
||||
plr->roundscore = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"marescore"))
|
||||
|
|
@ -799,6 +805,12 @@ static int player_set(lua_State *L)
|
|||
plr->confirmVictimDelay = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"glanceDir"))
|
||||
plr->glanceDir = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"breathTimer"))
|
||||
plr->breathTimer = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"lastsafelap"))
|
||||
plr->lastsafelap = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"lastsafestarpost"))
|
||||
plr->lastsafestarpost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"roundscore"))
|
||||
lua_pushinteger(L, plr->roundscore);
|
||||
else if (fastcmp(field,"marescore"))
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
WRITEUINT32(save->p, players[i].distancetofinishprev);
|
||||
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].currentwaypoint));
|
||||
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
|
||||
WRITEUINT16(save->p, players[i].bigwaypointgap);
|
||||
WRITEUINT32(save->p, players[i].airtime);
|
||||
WRITEUINT8(save->p, players[i].startboost);
|
||||
|
||||
|
|
@ -348,6 +349,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
|
||||
WRITEUINT16(save->p, players[i].breathTimer);
|
||||
|
||||
WRITEUINT8(save->p, players[i].lastsafelap);
|
||||
WRITEUINT8(save->p, players[i].lastsafestarpost);
|
||||
|
||||
WRITEUINT8(save->p, players[i].typing_timer);
|
||||
WRITEUINT8(save->p, players[i].typing_duration);
|
||||
|
||||
|
|
@ -552,7 +556,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].distancetofinish = READUINT32(save->p);
|
||||
players[i].distancetofinishprev = 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].bigwaypointgap = READUINT16(save->p);
|
||||
players[i].airtime = READUINT32(save->p);
|
||||
players[i].startboost = READUINT8(save->p);
|
||||
|
||||
|
|
@ -655,6 +661,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
|
||||
players[i].breathTimer = READUINT16(save->p);
|
||||
|
||||
players[i].lastsafelap = READUINT8(save->p);
|
||||
players[i].lastsafestarpost = READUINT8(save->p);
|
||||
|
||||
players[i].typing_timer = READUINT8(save->p);
|
||||
players[i].typing_duration = READUINT8(save->p);
|
||||
|
||||
|
|
|
|||
|
|
@ -427,6 +427,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
|
|||
mapheaderinfo[num]->palette = UINT16_MAX;
|
||||
mapheaderinfo[num]->encorepal = UINT16_MAX;
|
||||
mapheaderinfo[num]->numlaps = NUMLAPS_DEFAULT;
|
||||
mapheaderinfo[num]->lapspersection = 1;
|
||||
mapheaderinfo[num]->unlockrequired = -1;
|
||||
mapheaderinfo[num]->levelselect = 0;
|
||||
mapheaderinfo[num]->levelflags = 0;
|
||||
|
|
|
|||
18
src/p_spec.c
18
src/p_spec.c
|
|
@ -1970,11 +1970,23 @@ void P_SwitchWeather(preciptype_t newWeather)
|
|||
P_SpawnPrecipitation();
|
||||
}
|
||||
|
||||
static boolean K_IgnoreFinishLine(player_t *player)
|
||||
{
|
||||
// If potential lap cheating has been detected, do not
|
||||
// interact with the finish line at all.
|
||||
if (player->bigwaypointgap)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Passed over the finish line forwards
|
||||
static void K_HandleLapIncrement(player_t *player)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
if (K_IgnoreFinishLine(player))
|
||||
return;
|
||||
if (((numbosswaypoints > 0) ? (player->starpostnum >= (numstarposts - (numstarposts/2))) : (player->starpostnum == numstarposts)) || (player->laps == 0))
|
||||
{
|
||||
size_t i = 0;
|
||||
|
|
@ -1992,6 +2004,9 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
|
||||
player->starposttime = player->realtime;
|
||||
player->starpostnum = 0;
|
||||
player->lastsafestarpost = 0;
|
||||
player->laps++;
|
||||
|
||||
|
||||
if (mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||
{
|
||||
|
|
@ -2010,7 +2025,8 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
player->starpostangle = player->starpostx = player->starposty = player->starpostz = player->starpostflip = 0;
|
||||
}
|
||||
|
||||
player->laps++;
|
||||
if (!cv_kartdebuglap.value && player->laps == 1)
|
||||
player->pflags |= PF_TRUSTWAYPOINTS;
|
||||
K_UpdateAllPlayerPositions();
|
||||
|
||||
// Set up lap animation vars
|
||||
|
|
|
|||
Loading…
Reference in a new issue