From ecbcc5addb1b402aec171894a0464adda7feb07f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Mar 2024 19:16:48 -0800 Subject: [PATCH 1/8] Make automatic respawn (from lap cheat prevention) more lenient - When potential lap cheating is detected, start a 10 second timer (previously 1 second) - After 3 seconds, tell the player they can respawn with the Y button - You don't need to hold the Y button, just tap it - After 10 seconds, automatically respawns the player --- src/d_player.h | 2 +- src/k_kart.c | 10 +++++++--- src/k_kart.h | 5 +++++ src/p_saveg.c | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 4630224dc..8eba8f205 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -671,7 +671,7 @@ struct player_t mobj_t *ringShooter; // DEZ respawner object tic_t airtime; // Used to track just air time, but has evolved over time into a general "karted" timer. Rename this variable? tic_t lastairtime; - UINT8 bigwaypointgap; // timer counts down if finish line distance gap is too big to update waypoint + UINT16 bigwaypointgap; // timer counts down if finish line distance gap is too big to update waypoint UINT8 startboost; // (0 to 125) - Boost you get from start of race UINT8 dropdashboost; // Boost you get when holding A while respawning diff --git a/src/k_kart.c b/src/k_kart.c index a68293cf4..a7904a182 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8777,6 +8777,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->bigwaypointgap--; if (!player->bigwaypointgap) K_DoIngameRespawn(player); + else if (player->bigwaypointgap == AUTORESPAWN_THRESHOLD) + K_AddMessageForPlayer(player, "Press \xAE to respawn", true, false); } if (player->tripwireUnstuck && !player->mo->hitlag) @@ -8797,7 +8799,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->respawn.state == RESPAWNST_NONE && (player->cmd.buttons & BT_RESPAWN) == BT_RESPAWN) { player->finalfailsafe++; // Decremented by ringshooter to "freeze" this timer - if (player->finalfailsafe >= 4*TICRATE) + // Part-way through the auto-respawn timer, you can tap Ring Shooter to respawn early + if (player->finalfailsafe >= 4*TICRATE || + (player->bigwaypointgap && player->bigwaypointgap < AUTORESPAWN_THRESHOLD)) { K_DoIngameRespawn(player); player->finalfailsafe = 0; @@ -10000,14 +10004,14 @@ static void K_UpdatePlayerWaypoints(player_t *const player) // Start the auto respawn timer when the distance jumps. if (!player->bigwaypointgap) { - player->bigwaypointgap = 35; + player->bigwaypointgap = AUTORESPAWN_TIME; } } } else { // Reset the auto respawn timer if distance changes are back to normal. - if (player->bigwaypointgap == 1) + if (player->bigwaypointgap <= AUTORESPAWN_THRESHOLD + 1) { player->bigwaypointgap = 0; } diff --git a/src/k_kart.h b/src/k_kart.h index 17ab9640f..3224e1256 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -70,6 +70,11 @@ Make sure this matches the actual number of states // Delay the wavedash visuals until we're reasonably sure that it's a deliberate turn. #define HIDEWAVEDASHCHARGE (60) +// Auto-respawn timer for when lap cheating or out of bounds +// is detected. +#define AUTORESPAWN_TIME (10*TICRATE) +#define AUTORESPAWN_THRESHOLD (7*TICRATE) + angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); boolean K_IsDuelItem(mobjtype_t type); diff --git a/src/p_saveg.c b/src/p_saveg.c index e95837d97..b89ee4412 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -418,7 +418,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save->p, players[i].airtime); WRITEUINT32(save->p, players[i].lastairtime); - WRITEUINT8(save->p, players[i].bigwaypointgap); + WRITEUINT16(save->p, players[i].bigwaypointgap); WRITEUINT8(save->p, players[i].startboost); WRITEUINT8(save->p, players[i].dropdashboost); @@ -1006,7 +1006,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save->p); players[i].airtime = READUINT32(save->p); players[i].lastairtime = READUINT32(save->p); - players[i].bigwaypointgap = READUINT8(save->p); + players[i].bigwaypointgap = READUINT16(save->p); players[i].startboost = READUINT8(save->p); players[i].dropdashboost = READUINT8(save->p); From b5f318b405934ec9ce5554a72d8a9fa6b7f3ba5c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Mar 2024 21:28:21 -0800 Subject: [PATCH 2/8] Freeze auto-respawn while player is in damage state - Still let the respawn prompt appear --- src/k_kart.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index a7904a182..cb8ea9f0c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8772,7 +8772,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_DoIngameRespawn(player); } - if (player->bigwaypointgap) + // Don't tick down while in damage state. + // There may be some maps where the timer activates for + // a moment during normal play, but would quickly correct + // itself when the player drives forward. + // If the player is in a damage state, they may not be + // able to move in time. + // Always let the respawn prompt appear. + if (player->bigwaypointgap && (player->bigwaypointgap > AUTORESPAWN_THRESHOLD || !P_PlayerInPain(player))) { player->bigwaypointgap--; if (!player->bigwaypointgap) From 1015d6964b50df13201ab5f54fd4126efacb0af1 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 5 Mar 2024 05:33:33 -0800 Subject: [PATCH 3/8] Add PF_TRUSTWAYPOINTS player flag, disable lap cheat prevention next time finish line distance is calculated --- src/d_player.h | 3 ++- src/deh_tables.c | 2 +- src/k_kart.c | 9 ++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 8eba8f205..f78a07e38 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -104,8 +104,9 @@ typedef enum PF_RINGLOCK = 1<<13, // Prevent picking up rings while SPB is locked on PF_ANALOGSTICK = 1<<14, // This player is using an analog joystick + PF_TRUSTWAYPOINTS = 1<<15, // Do not activate lap cheat prevention next time finish line distance is updated - //15-17 free, was previously itemflags stuff + //16-17 free, was previously itemflags stuff PF_DRIFTINPUT = 1<<18, // Drifting! PF_GETSPARKS = 1<<19, // Can get sparks diff --git a/src/deh_tables.c b/src/deh_tables.c index 7a80db60b..5bd5700f9 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4016,7 +4016,7 @@ const char *const PLAYERFLAG_LIST[] = { "RINGLOCK", // Prevent picking up rings while SPB is locked on "ANALOGSTICK", // This player is using an analog joystick - "\x01", // Free + "TRUSTWAYPOINTS", // Do not activate lap cheat prevention next time finish line distance is updated "\x01", // Free "\x01", // Free diff --git a/src/k_kart.c b/src/k_kart.c index cb8ea9f0c..abfcbd203 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9987,10 +9987,11 @@ static void K_UpdatePlayerWaypoints(player_t *const player) player->distancetofinishprev = player->distancetofinish; K_UpdateDistanceFromFinishLine(player); - // Respawning should be a full reset. - // So should touching the first waypoint ever. UINT32 delta = u32_delta(player->distancetofinish, player->distancetofinishprev); - if (player->respawn.state == RESPAWNST_NONE && delta > distance_threshold && old_currentwaypoint != NULL) + if (delta > distance_threshold && + player->respawn.state == RESPAWNST_NONE && // Respawning should be a full reset. + old_currentwaypoint != NULL && // So should touching the first waypoint ever. + !(player->pflags & PF_TRUSTWAYPOINTS)) // Special exception. { extern consvar_t cv_debuglapcheat; #define debug_args "Player %s: waypoint ID %d too far away (%u > %u)\n", \ @@ -10036,6 +10037,8 @@ static void K_UpdatePlayerWaypoints(player_t *const player) player->lastsafelap = player->laps; player->lastsafecheatcheck = player->cheatchecknum; } + + player->pflags &= ~PF_TRUSTWAYPOINTS; // clear special exception } INT32 K_GetKartRingPower(const player_t *player, boolean boosted) From 2a79eed0d2c29d7ef5c0a0627c8da9b322b38d79 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 5 Mar 2024 05:34:44 -0800 Subject: [PATCH 4/8] Disable lap cheat prevention while on lap 0 (POSITION room) --- src/k_kart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/k_kart.c b/src/k_kart.c index abfcbd203..3804235c5 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9991,6 +9991,7 @@ static void K_UpdatePlayerWaypoints(player_t *const player) if (delta > distance_threshold && player->respawn.state == RESPAWNST_NONE && // 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. { extern consvar_t cv_debuglapcheat; From 46291135a03369a68aa481485fe41ef5e4de321f Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 5 Mar 2024 05:35:20 -0800 Subject: [PATCH 5/8] Disable lap cheat prevention when starting lap 1 (first lap from POSITION room) --- src/p_spec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index c4ca508ed..c67f4f9e2 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2015,6 +2015,13 @@ static void K_HandleLapIncrement(player_t *player) SetRandomFakePlayerSkin(player, true); } + // Always trust waypoints entering the first lap. + // This accounts for special POSITION room setups. + // debuglapcheat can be used to expose errors that would be hidden by this exception. + extern consvar_t cv_debuglapcheat; + if (!cv_debuglapcheat.value && player->laps == 1) + player->pflags |= PF_TRUSTWAYPOINTS; + K_UpdateAllPlayerPositions(); // P_DoPlayerExit calls this } From a32bb486e2614672d226bc434b12612897cc2b61 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 5 Mar 2024 05:35:33 -0800 Subject: [PATCH 6/8] Disable lap cheat prevention when teleporting with console commands --- src/d_netcmd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 47d272caf..2e2a1bc9a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -6078,6 +6078,9 @@ static void Got_Cheat(const UINT8 **cp, INT32 playernum) } P_MapEnd(); + player->pflags |= PF_TRUSTWAYPOINTS; + player->bigwaypointgap = 0; + S_StartSound(player->mo, sfx_mixup); } From 5eeb45228cd31692266ec5974330b691222b36b8 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 6 Mar 2024 18:28:33 -0800 Subject: [PATCH 7/8] DEVELOP: add debugtraversemax cvar to improve sight check consistency --- src/cvars.cpp | 6 ++++++ src/doomdef.h | 3 +++ src/doomtype.h | 1 + src/p_sight.c | 6 +++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/cvars.cpp b/src/cvars.cpp index 495305827..7d6aad888 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -834,6 +834,12 @@ consvar_t cv_restrictskinchange = OnlineCheat("restrictskinchange", "Yes").yes_n consvar_t cv_spbtest = OnlineCheat("spbtest", "Off").on_off().description("SPB can never target a player"); consvar_t cv_showgremlins = OnlineCheat("showgremlins", "No").yes_no().description("Show line collision errors"); consvar_t cv_timescale = OnlineCheat(cvlist_timer)("timescale", "1.0").floating_point().min_max(FRACUNIT/20, 20*FRACUNIT).description("Overclock or slow down the game"); + +#ifdef DEVELOP + // change the default value in doomdef.h (so it affects release builds too) + consvar_t cv_debugtraversemax = OnlineCheat("debugtraversemax", TOSTR2(TRAVERSE_MAX)).min_max(0, 255).description("Improve line-of-sight detection (waypoints) but may slow down the game"); +#endif + consvar_t cv_ufo_follow = OnlineCheat("ufo_follow", "0").min_max(0, MAXPLAYERS).description("Make UFO Catcher folow this player"); consvar_t cv_ufo_health = OnlineCheat("ufo_health", "-1").min_max(-1, 100).description("Override UFO Catcher health -- applied at spawn or when value is changed"); diff --git a/src/doomdef.h b/src/doomdef.h index bdaeb556a..5f1cf9488 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -724,6 +724,9 @@ extern int #undef UPDATE_ALERT #endif +// p_sight.c +#define TRAVERSE_MAX 2 + /// Other karma comeback modes //#define OTHERKARMAMODES diff --git a/src/doomtype.h b/src/doomtype.h index d8db69c2b..49e2d11d8 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -360,6 +360,7 @@ typedef UINT32 tic_t; #endif #define TOSTR(x) #x +#define TOSTR2(x) TOSTR(x) // expand x first /* preprocessor dumb and needs second macro to expand input */ #define WSTRING2(s) L ## s diff --git a/src/p_sight.c b/src/p_sight.c index c145ffbfd..37b485c25 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -52,7 +52,11 @@ typedef struct static INT32 sightcounts[2]; -#define TRAVERSE_MAX (2) +#ifdef DEVELOP +extern consvar_t cv_debugtraversemax; +#undef TRAVERSE_MAX +#define TRAVERSE_MAX (cv_debugtraversemax.value) +#endif // // P_DivlineSide From 1a330dd471817b675126c08099d3b1167bded1cc Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 6 Mar 2024 18:32:33 -0800 Subject: [PATCH 8/8] Raise TRAVERSEMAX 2 -> 8 - Improves nextwaypoint searching on a problem spot in Endless Mine - I think the sight checking fail state can trigger too quickly, so this makes it more lenient? (I'm sorry, I don't really understand it myself.) --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index 5f1cf9488..2f854c2d4 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -725,7 +725,7 @@ extern int #endif // p_sight.c -#define TRAVERSE_MAX 2 +#define TRAVERSE_MAX 8 /// Other karma comeback modes //#define OTHERKARMAMODES