From 9ee69ec1db2f03eee9a9d811ca19d1abfd9a0bde Mon Sep 17 00:00:00 2001 From: Lach Date: Thu, 19 Jun 2025 21:46:56 +1000 Subject: [PATCH 01/10] Track player Flybot767 spawns using a mobj pointer instead of a flag in the stunned timer --- src/d_player.h | 1 + src/k_kart.c | 14 ++++---------- src/k_objects.h | 1 + src/lua_playerlib.c | 9 +++++++++ src/objects/flybot767.c | 28 +++++++++++++++++++++++++++- src/p_inter.c | 3 ++- src/p_mobj.c | 5 +++++ src/p_saveg.cpp | 18 ++++++++++++++++-- 8 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 16339b32a..d8500b557 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -741,6 +741,7 @@ struct player_t UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu UINT16 stunned; // Number of tics during which rings cannot be picked up UINT8 stunnedCombo; // Number of hits sustained while stunned, reduces consecutive stun penalties + mobj_t *flybot; // One Flybot767 circling the player while stunned UINT8 justDI; // Turn-lockout timer to briefly prevent unintended turning after DI, resets when actionable or no input boolean flipDI; // Bananas flip the DI direction. Was a bug, but it made bananas much more interesting. diff --git a/src/k_kart.c b/src/k_kart.c index 5ac1ba0ad..493776254 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9738,23 +9738,17 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) && P_IsObjectOnGround(player->mo) ) { - // MEGA FUCKING HACK BECAUSE P_SAVEG MOBJS ARE FULL - // Would updating player_saveflags to 32 bits have any negative consequences? - // For now, player->stunned 16th bit is a flag to determine whether the flybots were spawned - // timer counts down at triple speed while spindashing - player->stunned = (player->stunned & 0x8000) | max(0, (player->stunned & 0x7FFF) - (player->spindash ? 3 : 1)); + player->stunned = max(0, player->stunned - (player->spindash ? 3 : 1)); - // when timer reaches 0, reset the flag and stun combo counter - if ((player->stunned & 0x7FFF) == 0) + // when timer reaches 0, reset the stun combo counter + if (player->stunned == 0) { - player->stunned = 0; player->stunnedCombo = 0; } // otherwise if the flybots aren't spawned, spawn them now! - else if ((player->stunned & 0x8000) == 0) + else if (P_MobjWasRemoved(player->flybot)) { - player->stunned |= 0x8000; Obj_SpawnFlybotsForPlayer(player); } } diff --git a/src/k_objects.h b/src/k_objects.h index f5c36da12..060e43144 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -440,6 +440,7 @@ void Obj_DestroyedKartParticleLanding(mobj_t *part); void Obj_SpawnFlybotsForPlayer(player_t *player); void Obj_FlybotThink(mobj_t *flybot); void Obj_FlybotDeath(mobj_t *flybot); +void Obj_FlybotRemoved(mobj_t *flybot); /* Pulley */ void Obj_PulleyThink(mobj_t *root); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 1a7d199c0..b6ebacae1 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -264,6 +264,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->stunned); else if (fastcmp(field,"stunnedcombo")) lua_pushinteger(L, plr->stunnedCombo); + else if (fastcmp(field,"flybot")) + LUA_PushUserdata(L, plr->flybot, META_MOBJ); else if (fastcmp(field,"justdi")) lua_pushinteger(L, plr->justDI); else if (fastcmp(field,"flipdi")) @@ -898,6 +900,13 @@ static int player_set(lua_State *L) plr->stunned = luaL_checkinteger(L, 3); else if (fastcmp(field,"stunnedcombo")) plr->stunnedCombo = luaL_checkinteger(L, 3); + else if (fastcmp(field,"flybot")) + { + mobj_t *mo = NULL; + if (!lua_isnil(L, 3)) + mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&plr->flybot, mo); + } else if (fastcmp(field,"justdi")) plr->justDI = luaL_checkinteger(L, 3); else if (fastcmp(field,"flipdi")) diff --git a/src/objects/flybot767.c b/src/objects/flybot767.c index 790276387..edf59cd57 100644 --- a/src/objects/flybot767.c +++ b/src/objects/flybot767.c @@ -43,6 +43,7 @@ void Obj_SpawnFlybotsForPlayer(player_t *player) { UINT8 i; mobj_t *mo = player->mo; + mobj_t *hprev = mo; fixed_t radius = mo->radius; for (i = 0; i < FLYBOT_QUANTITY; i++) @@ -61,6 +62,17 @@ void Obj_SpawnFlybotsForPlayer(player_t *player) flybot->movedir = flybot->old_angle = flybot->angle = angle + ANGLE_90; flybot->old_z = SetFlybotZ(flybot); flybot->renderflags |= (i * RF_DONTDRAW); + + if (hprev->player) + { + P_SetTarget(&player->flybot, flybot); + } + else + { + P_SetTarget(&hprev->hnext, flybot); + P_SetTarget(&flybot->hprev, hprev); + } + hprev = flybot; } } @@ -80,7 +92,7 @@ void Obj_FlybotThink(mobj_t *flybot) if (mo->player) { - if (((stunned = mo->player->stunned & 0x7FFF) == 0) || (mo->player->playerstate == PST_DEAD)) + if (((stunned = mo->player->stunned) == 0) || (mo->player->playerstate == PST_DEAD)) { P_KillMobj(flybot, NULL, NULL, 0); return; @@ -120,6 +132,11 @@ void Obj_FlybotDeath(mobj_t *flybot) if (!P_MobjWasRemoved(mo)) { + if (mo->player && (flybot == mo->player->flybot)) + { + P_SetTarget(&mo->player->flybot, NULL); + } + mom.x = mo->momx; mom.y = mo->momy; mom.z = mo->momz; @@ -140,3 +157,12 @@ void Obj_FlybotDeath(mobj_t *flybot) angle += ANGLE_90; } } + +void Obj_FlybotRemoved(mobj_t *flybot) +{ + mobj_t *mo = flybot->target; + if (!P_MobjWasRemoved(mo) && mo->player && (flybot == mo->player->flybot)) + { + P_SetTarget(&mo->player->flybot, NULL); + } +} diff --git a/src/p_inter.c b/src/p_inter.c index 04a05ce4c..dea1597d0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3504,7 +3504,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { player->stunnedCombo++; } - player->stunned = (player->stunned & 0x8000) | min(0x7FFF, (player->stunned & 0x7FFF) + stunTics); + stunTics = min(player->stunned + stunTics, UINT16_MAX); + player->stunned = stunTics; #undef MIN_STUNTICS #undef MAX_STUNTICS diff --git a/src/p_mobj.c b/src/p_mobj.c index da3e08bc6..fe7b5f0fc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11855,6 +11855,11 @@ void P_RemoveMobj(mobj_t *mobj) Obj_UnlinkRocks(mobj); break; } + case MT_FLYBOT767: + { + Obj_FlybotRemoved(mobj); + break; + } default: { break; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 98e544cd4..1bbfb36c5 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -72,8 +72,7 @@ static savebuffer_t *current_savebuffer; #define ARCHIVEBLOCK_WAYPOINTS 0x7F46498F #define ARCHIVEBLOCK_RNG 0x7FAAB5BD -// Note: This cannot be bigger -// than an UINT16 (for now) +// Note: This cannot have more than 32 entries typedef enum { AWAYVIEW = 0x0001, @@ -93,6 +92,7 @@ typedef enum BARRIER = 0x4000, BALLHOGRETICULE = 0x8000, STONESHOE = 0x10000, + FLYBOT = 0x20000, } player_saveflags; static inline void P_ArchivePlayer(savebuffer_t *save) @@ -368,6 +368,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (players[i].stoneShoe) flags |= STONESHOE; + if (players[i].flybot) + flags |= FLYBOT; + WRITEUINT32(save->p, flags); if (flags & SKYBOXVIEW) @@ -418,6 +421,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) if (flags & STONESHOE) WRITEUINT32(save->p, players[i].stoneShoe->mobjnum); + if (flags & FLYBOT) + WRITEUINT32(save->p, players[i].flybot->mobjnum); + WRITEUINT32(save->p, (UINT32)players[i].followitem); WRITEUINT32(save->p, players[i].charflags); @@ -1073,6 +1079,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) if (flags & STONESHOE) players[i].stoneShoe = (mobj_t *)(size_t)READUINT32(save->p); + if (flags & FLYBOT) + players[i].flybot = (mobj_t *)(size_t)READUINT32(save->p); + players[i].followitem = (mobjtype_t)READUINT32(save->p); //SetPlayerSkinByNum(i, players[i].skin); @@ -6232,6 +6241,11 @@ static void P_RelinkPointers(void) if (!RelinkMobj(&players[i].stoneShoe)) CONS_Debug(DBG_GAMELOGIC, "stoneShoe not found on player %d\n", i); } + if (players[i].flybot) + { + if (!RelinkMobj(&players[i].flybot)) + CONS_Debug(DBG_GAMELOGIC, "flybot not found on player %d\n", i); + } } } From 2c11aa36c32ae8b4fbe0a4b9c702369b6eddf9ed Mon Sep 17 00:00:00 2001 From: Lach Date: Thu, 19 Jun 2025 22:13:23 +1000 Subject: [PATCH 02/10] Move stunned timer calculations from P_DamageMobj into K_ApplyStun --- src/k_kart.c | 26 ++++++++++++++++++++++++++ src/k_kart.h | 2 ++ src/p_inter.c | 22 +--------------------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 493776254..4b3445f2b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -16307,4 +16307,30 @@ fixed_t K_TeamComebackMultiplier(player_t *player) return multiplier; } +void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) +{ + #define BASE_STUN_TICS_MIN (4 * TICRATE) + #define BASE_STUN_TICS_MAX (10 * TICRATE) + UINT16 stunTics = 0; + + stunTics = Easing_Linear((player->kartweight - 1) * FRACUNIT / 8, BASE_STUN_TICS_MAX, BASE_STUN_TICS_MIN); + stunTics >>= player->stunnedCombo; // consecutive hits add half as much stun as the previous hit + + // 1/3 base stun values in battle + if (gametyperules & GTR_SPHERES) + { + stunTics /= 3; + } + + if (player->stunnedCombo < UINT8_MAX) + { + player->stunnedCombo++; + } + stunTics = min(player->stunned + stunTics, UINT16_MAX); + player->stunned = stunTics; + + #undef BASE_STUN_TICS_MIN + #undef BASE_STUN_TICS_MAX +} + //} diff --git a/src/k_kart.h b/src/k_kart.h index 9d9f3fdf8..a31e886d3 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -340,6 +340,8 @@ boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2, boolean allowHostile); fixed_t K_TeamComebackMultiplier(player_t *player); +void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/p_inter.c b/src/p_inter.c index dea1597d0..aaf0c7f0b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3041,7 +3041,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da UINT8 type = (damagetype & DMG_TYPEMASK); const boolean hardhit = (type == DMG_EXPLODE || type == DMG_KARMA || type == DMG_TUMBLE); // This damage type can do evil stuff like ALWAYS combo INT16 ringburst = 5; - UINT16 stunTics = 0; // Check if the player is allowed to be damaged! // If not, then spawn the instashield effect instead. @@ -3488,26 +3487,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } // Apply stun! - // Feel free to move these calculations higher up if different damage sources should apply variable stun in future - #define MIN_STUNTICS (4 * TICRATE) - #define MAX_STUNTICS (10 * TICRATE) - stunTics = Easing_Linear((player->kartweight - 1) * FRACUNIT / 8, MAX_STUNTICS, MIN_STUNTICS); - stunTics >>= player->stunnedCombo; // consecutive hits add half as much stun as the previous hit - - // 1/3 base stun values in battle - if (gametyperules & GTR_SPHERES) - { - stunTics /= 3; - } - - if (player->stunnedCombo < UINT8_MAX) - { - player->stunnedCombo++; - } - stunTics = min(player->stunned + stunTics, UINT16_MAX); - player->stunned = stunTics; - #undef MIN_STUNTICS - #undef MAX_STUNTICS + K_ApplyStun(player, inflictor, source, damage, damagetype); K_DefensiveOverdrive(target->player); } From f24a5db5d20118eaa1e92028c8861c2383a4d962 Mon Sep 17 00:00:00 2001 From: Lach Date: Thu, 19 Jun 2025 22:14:41 +1000 Subject: [PATCH 03/10] Don't apply any stunned tics on ring sting --- src/p_inter.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index aaf0c7f0b..730b53664 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3487,7 +3487,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } // Apply stun! - K_ApplyStun(player, inflictor, source, damage, damagetype); + if (damagetype != DMG_STING) + { + K_ApplyStun(player, inflictor, source, damage, damagetype); + } K_DefensiveOverdrive(target->player); } From da6d7ec6b134241d08227973103450c1ac8d3f4f Mon Sep 17 00:00:00 2001 From: Lach Date: Thu, 19 Jun 2025 22:24:23 +1000 Subject: [PATCH 04/10] Reduce stunned tics in games with more than 8 players --- src/k_kart.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 4b3445f2b..df60e23ac 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -16311,12 +16311,30 @@ void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 dama { #define BASE_STUN_TICS_MIN (4 * TICRATE) #define BASE_STUN_TICS_MAX (10 * TICRATE) - UINT16 stunTics = 0; + INT32 stunTics = 0; + UINT8 numPlayers = 0; + UINT8 i; + // calculate the number of players playing + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + numPlayers++; + } + } + + // calculate base stun tics stunTics = Easing_Linear((player->kartweight - 1) * FRACUNIT / 8, BASE_STUN_TICS_MAX, BASE_STUN_TICS_MIN); stunTics >>= player->stunnedCombo; // consecutive hits add half as much stun as the previous hit - // 1/3 base stun values in battle + // reduce stun in games with more than 8 players + if (numPlayers > 8) + { + stunTics -= 17 * (numPlayers - 8); + } + + // 1/3 stun values in battle if (gametyperules & GTR_SPHERES) { stunTics /= 3; @@ -16326,7 +16344,7 @@ void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 dama { player->stunnedCombo++; } - stunTics = min(player->stunned + stunTics, UINT16_MAX); + stunTics = min(max(player->stunned + stunTics, 0), UINT16_MAX); player->stunned = stunTics; #undef BASE_STUN_TICS_MIN From fceaad44ab8683e2f8d27892e772c1b1b54ca678 Mon Sep 17 00:00:00 2001 From: eebrozgi Date: Thu, 19 Jun 2025 15:49:46 +0300 Subject: [PATCH 05/10] Spindash to spin Flybots faster btw ring sting change doesn't work yet, somehow --- src/objects/flybot767.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/objects/flybot767.c b/src/objects/flybot767.c index edf59cd57..c9bd6014b 100644 --- a/src/objects/flybot767.c +++ b/src/objects/flybot767.c @@ -97,6 +97,13 @@ void Obj_FlybotThink(mobj_t *flybot) P_KillMobj(flybot, NULL, NULL, 0); return; } + + // If player is spindashing, spin faster to hint that stun is going down faster + else if (mo->player->spindash) + { + speed *= 2; + //flybot->movedir += FLYBOT_BOB_FREQUENCY; + } } flybot->frame = flybot->frame & ~FF_TRANSMASK; From d58414b4405a835ab42f9b4f80718e70567ffe04 Mon Sep 17 00:00:00 2001 From: Lach Date: Thu, 19 Jun 2025 22:54:19 +1000 Subject: [PATCH 06/10] Don't apply any stunned tics on ring sting (but for real this time) --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 730b53664..ca9183cc8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3487,7 +3487,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } // Apply stun! - if (damagetype != DMG_STING) + if (type != DMG_STING) { K_ApplyStun(player, inflictor, source, damage, damagetype); } From fceb325bd4879c48255dcfd52dbd3f55142607f4 Mon Sep 17 00:00:00 2001 From: Lach Date: Fri, 20 Jun 2025 20:40:29 +1000 Subject: [PATCH 07/10] Remove stacked stunned tics --- src/d_player.h | 1 - src/k_kart.c | 17 +++-------------- src/lua_playerlib.c | 4 ---- src/p_saveg.cpp | 2 -- 4 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index d8500b557..a5219c816 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -740,7 +740,6 @@ struct player_t UINT8 tumbleBounces; UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu UINT16 stunned; // Number of tics during which rings cannot be picked up - UINT8 stunnedCombo; // Number of hits sustained while stunned, reduces consecutive stun penalties mobj_t *flybot; // One Flybot767 circling the player while stunned UINT8 justDI; // Turn-lockout timer to briefly prevent unintended turning after DI, resets when actionable or no input boolean flipDI; // Bananas flip the DI direction. Was a bug, but it made bananas much more interesting. diff --git a/src/k_kart.c b/src/k_kart.c index df60e23ac..37452e6be 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9741,13 +9741,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // timer counts down at triple speed while spindashing player->stunned = max(0, player->stunned - (player->spindash ? 3 : 1)); - // when timer reaches 0, reset the stun combo counter - if (player->stunned == 0) - { - player->stunnedCombo = 0; - } - // otherwise if the flybots aren't spawned, spawn them now! - else if (P_MobjWasRemoved(player->flybot)) + // if the flybots aren't spawned, spawn them now! + if (player->stunned != 0 && P_MobjWasRemoved(player->flybot)) { Obj_SpawnFlybotsForPlayer(player); } @@ -16326,7 +16321,6 @@ void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 dama // calculate base stun tics stunTics = Easing_Linear((player->kartweight - 1) * FRACUNIT / 8, BASE_STUN_TICS_MAX, BASE_STUN_TICS_MIN); - stunTics >>= player->stunnedCombo; // consecutive hits add half as much stun as the previous hit // reduce stun in games with more than 8 players if (numPlayers > 8) @@ -16340,12 +16334,7 @@ void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 dama stunTics /= 3; } - if (player->stunnedCombo < UINT8_MAX) - { - player->stunnedCombo++; - } - stunTics = min(max(player->stunned + stunTics, 0), UINT16_MAX); - player->stunned = stunTics; + player->stunned = max(stunTics, 0); #undef BASE_STUN_TICS_MIN #undef BASE_STUN_TICS_MAX diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index b6ebacae1..6dcbc527f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -262,8 +262,6 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->tumbleHeight); else if (fastcmp(field,"stunned")) lua_pushinteger(L, plr->stunned); - else if (fastcmp(field,"stunnedcombo")) - lua_pushinteger(L, plr->stunnedCombo); else if (fastcmp(field,"flybot")) LUA_PushUserdata(L, plr->flybot, META_MOBJ); else if (fastcmp(field,"justdi")) @@ -898,8 +896,6 @@ static int player_set(lua_State *L) plr->tumbleHeight = luaL_checkinteger(L, 3); else if (fastcmp(field,"stunned")) plr->stunned = luaL_checkinteger(L, 3); - else if (fastcmp(field,"stunnedcombo")) - plr->stunnedCombo = luaL_checkinteger(L, 3); else if (fastcmp(field,"flybot")) { mobj_t *mo = NULL; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 1bbfb36c5..9908c3bba 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -470,7 +470,6 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].tumbleBounces); WRITEUINT16(save->p, players[i].tumbleHeight); WRITEUINT16(save->p, players[i].stunned); - WRITEUINT8(save->p, players[i].stunnedCombo); WRITEUINT8(save->p, players[i].justDI); WRITEUINT8(save->p, players[i].flipDI); @@ -1129,7 +1128,6 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].tumbleBounces = READUINT8(save->p); players[i].tumbleHeight = READUINT16(save->p); players[i].stunned = READUINT16(save->p); - players[i].stunnedCombo = READUINT8(save->p); players[i].justDI = READUINT8(save->p); players[i].flipDI = (boolean)READUINT8(save->p); From 546bb52e3b25f969dd1d2367dec4378711712d0a Mon Sep 17 00:00:00 2001 From: Lach Date: Fri, 20 Jun 2025 20:57:31 +1000 Subject: [PATCH 08/10] Reduce stunned tics for damage caused by non-players --- src/k_kart.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 37452e6be..6a83abda4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -16334,6 +16334,22 @@ void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 dama stunTics /= 3; } + if (source && source->player) + { + // hits scored by players apply full stun + ; + } + else if (inflictor && (P_IsKartItem(inflictor->type) || P_IsKartFieldItem(inflictor->type))) + { + // items not thrown by a player apply half stun + stunTics /= 2; + } + else + { + // all other hazards apply 1/4 stun + stunTics /= 4; + } + player->stunned = max(stunTics, 0); #undef BASE_STUN_TICS_MIN From 51abee48cd2d1c64ad0b24610e0863c5dd7bdcef Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Wed, 25 Jun 2025 14:23:32 -0400 Subject: [PATCH 09/10] Reduce stun based on distance to leader --- src/k_kart.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6a83abda4..794f193b4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -16302,10 +16302,12 @@ fixed_t K_TeamComebackMultiplier(player_t *player) return multiplier; } -void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) +void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, ATTRUNUSED INT32 damage, ATTRUNUSED UINT8 damagetype) { #define BASE_STUN_TICS_MIN (4 * TICRATE) #define BASE_STUN_TICS_MAX (10 * TICRATE) + #define MAX_STUN_REDUCTION (FRACUNIT/2) + #define STUN_REDUCTION_DISTANCE (20000) INT32 stunTics = 0; UINT8 numPlayers = 0; UINT8 i; @@ -16350,10 +16352,20 @@ void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 dama stunTics /= 4; } + UINT32 dist = K_GetItemRouletteDistance(player, D_NumPlayersInRace()); + if (dist > STUN_REDUCTION_DISTANCE) + dist = STUN_REDUCTION_DISTANCE; + + fixed_t distfactor = FixedDiv(dist, STUN_REDUCTION_DISTANCE); // 0-1 as you approach STUN_REDUCTION_DISTANCE + fixed_t stunfactor = Easing_Linear(distfactor, FRACUNIT, MAX_STUN_REDUCTION); + stunTics = FixedMul(stunTics*FRACUNIT, stunfactor)/FRACUNIT; + player->stunned = max(stunTics, 0); #undef BASE_STUN_TICS_MIN #undef BASE_STUN_TICS_MAX + #undef MAX_STUN_REDUCTION + #undef STUN_REDUCTION_DISTANCE } //} From 82c0aa400b42edfcddd1c97b2f506386ea840385 Mon Sep 17 00:00:00 2001 From: VelocitOni Date: Wed, 25 Jun 2025 18:52:44 -0400 Subject: [PATCH 10/10] 16P Stun Nerf + Flybots bob faster Above 8P, stun timer nerf nerfed from 17t->6t; flybots don't just orbit faster, they bob faster too. --- src/k_kart.c | 2 +- src/objects/flybot767.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 794f193b4..4a05d3f82 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -16327,7 +16327,7 @@ void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, ATTRUNUSED // reduce stun in games with more than 8 players if (numPlayers > 8) { - stunTics -= 17 * (numPlayers - 8); + stunTics -= 6 * (numPlayers - 8); } // 1/3 stun values in battle diff --git a/src/objects/flybot767.c b/src/objects/flybot767.c index c9bd6014b..32293aeec 100644 --- a/src/objects/flybot767.c +++ b/src/objects/flybot767.c @@ -102,7 +102,7 @@ void Obj_FlybotThink(mobj_t *flybot) else if (mo->player->spindash) { speed *= 2; - //flybot->movedir += FLYBOT_BOB_FREQUENCY; + flybot->movedir += FLYBOT_BOB_FREQUENCY*2; } }