From 4ccb9b22c81d49367375571ecdbf0f77cdf100a2 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 29 Feb 2024 03:28:49 -0800 Subject: [PATCH 1/2] Ring Shooter: add a 2 second cooldown after respawning before you can touch a Ring Shooter This does not prevent you from using the respawn button to summon a Ring Shooter. - Ring Shooter only tracks the last player who touched it, to prevent that player from reusing it - If another player touches the Ring Shooter, it loses track of the original user - Near a Block Lightsnake waypoint, this would enter an endless loop where both players are able to touch the Ring Shooter and use it to respawn, placing them right above the Ring Shooter (and the cycle repeats) --- src/d_player.h | 1 + src/k_kart.c | 3 +++ src/k_respawn.c | 3 +++ src/p_inter.c | 5 ++++- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index e164e1afe..a9e486825 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -952,6 +952,7 @@ struct player_t UINT16 infinitether; // Generic infinitether time, used for infinitether leniency. UINT8 finalfailsafe; // When you can't Ringshooter, force respawn as a last ditch effort! + UINT8 freeRingShooterCooldown; // Can't use a free Ring Shooter again too soon after respawning. UINT8 lastsafelap; UINT8 lastsafecheatcheck; diff --git a/src/k_kart.c b/src/k_kart.c index 6084a259d..4cb21e27c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8738,6 +8738,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->finalfailsafe = 0; } + if (player->freeRingShooterCooldown && !player->mo->hitlag) + player->freeRingShooterCooldown--; + if (player->superring) { player->nextringaward++; diff --git a/src/k_respawn.c b/src/k_respawn.c index f72cb61e2..3cd82d1d0 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -885,6 +885,9 @@ static void K_HandleDropDash(player_t *player) player->respawn.state = RESPAWNST_NONE; player->mo->flags &= ~(MF_NOCLIPTHING); + + // Don't touch another Ring Shooter (still lets you summon a Ring Shooter yourself) + player->freeRingShooterCooldown = 2*TICRATE; } } diff --git a/src/p_inter.c b/src/p_inter.c index f0f953715..11e32dbff 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -915,7 +915,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_RINGSHOOTER: - Obj_PlayerUsedRingShooter(special, player); + if (player->freeRingShooterCooldown) + player->pflags |= PF_CASTSHADOW; // you can't use this right now! + else + Obj_PlayerUsedRingShooter(special, player); return; case MT_SUPER_FLICKY: From 3402c3af647cc2d62e9d100f1898a1dee8050479 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 29 Feb 2024 03:36:04 -0800 Subject: [PATCH 2/2] Polyobjects: add po_movecount member to mobj_t instead of using lastlook - Polyobject carrying set lastlook on mobjs for internal tracking - lastlook is used by some objects to track their own state - Ring Shooter uses lastlook to remember which player summoned it - A Ring Shooter spawned right next to a polyobject would become buggy; If its owner player pressed the respawn button again before the Ring Shooter despawned, that player would be teleported back to the Ring Shooter instead of spawning a new Ring Shooter (which would be the correct behavior) --- src/p_mobj.h | 2 ++ src/p_polyobj.c | 16 ++++------------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/p_mobj.h b/src/p_mobj.h index 1e429aa26..1002bac46 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -447,6 +447,8 @@ struct mobj_t mobj_t *owner; + INT32 po_movecount; // Polyobject carrying (NOT savegame, NOT Lua) + // WARNING: New fields must be added separately to savegame and Lua. }; diff --git a/src/p_polyobj.c b/src/p_polyobj.c index a27b2d847..021b8520e 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -879,14 +879,10 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) for (; mo; mo = mo->bnext) { - // lastlook is used by the SPB to determine targets, do not let it affect it - if (mo->type == MT_SPB) + if (mo->po_movecount == pomovecount) continue; - if (mo->lastlook == pomovecount) - continue; - - mo->lastlook = pomovecount; + mo->po_movecount = pomovecount; // Don't scroll objects that aren't affected by gravity if (mo->flags & MF_NOGRAVITY) @@ -1115,14 +1111,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, for (; mo; mo = mo->bnext) { - // lastlook is used by the SPB to determine targets, do not let it affect it - if (mo->type == MT_SPB) + if (mo->po_movecount == pomovecount) continue; - if (mo->lastlook == pomovecount) - continue; - - mo->lastlook = pomovecount; + mo->po_movecount = pomovecount; // Don't scroll objects that aren't affected by gravity if (mo->flags & MF_NOGRAVITY)