From 6a6ed9d8b3c33073845a81c53cac90b918871fa9 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Wed, 26 Nov 2025 13:13:15 -0500 Subject: [PATCH] start re-implementing airthrust from #158 --- src/d_netcmd.c | 41 +++++++++++++++++++++++++++-- src/d_netcmd.h | 3 +++ src/d_player.h | 7 ++--- src/k_hud.c | 2 ++ src/k_kart.c | 63 +++++++++++++++++++++++++++++++++++++++++---- src/lua_playerlib.c | 8 ++++++ src/p_inter.c | 1 + src/p_map.c | 12 +++++++++ src/p_mobj.h | 1 + src/p_saveg.c | 1 + src/p_setup.c | 5 ++++ 11 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d6ce95e28..759f460d0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -163,6 +163,7 @@ static void KartSlipdash_OnChange(void); static void KartSlopeBoost_OnChange(void); static void KartDrafting_OnChange(void); static void KartAirDrop_OnChange(void); +static void KartAirThrust_OnChange(void); static void KartItemLitter_OnChange(void); static void KartItemPush_OnChange(void); static void KartAntiBump_OnChange(void); @@ -553,6 +554,9 @@ consvar_t cv_kartdrafting_basedistance = CVAR_INIT ("kartdrafting_basedistance", consvar_t cv_kartairdrop = CVAR_INIT ("kartairdrop", "No", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartAirDrop_OnChange); +consvar_t cv_kartairthrust = CVAR_INIT ("kartairthrust", "Off", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_OnOff, KartAirThrust_OnChange); +consvar_t cv_kartairthrust_reductionrate = CVAR_INIT ("kartairthrust_reductionrate", "0.5", CV_NETVAR|CV_FLOAT, CV_Unsigned, NULL); + consvar_t cv_kartitemlitter = CVAR_INIT ("kartitemlitter", "On", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartItemLitter_OnChange); consvar_t cv_kartitempush = CVAR_INIT ("kartitempush", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartItemPush_OnChange); @@ -7661,11 +7665,44 @@ static void KartAirDrop_OnChange(void) if (leveltime < starttime) { airdropactive = false; - CONS_Printf(M_GetText("Drafting has been turned \"Off\".\n")); + CONS_Printf(M_GetText("Air Drop has been turned \"Off\".\n")); } else { - CONS_Printf(M_GetText("Drafting will be turned \"Off\" next round.\n")); + CONS_Printf(M_GetText("Air Drop will be turned \"Off\" next round.\n")); + } + } +} + +static void KartAirThrust_OnChange(void) +{ + if (K_CanChangeRules(false) == false) + { + return; + } + + if (!K_AirThrustActive() && cv_kartairthrust.value) + { + if (leveltime < starttime) + { + airthrustactive = true; + CONS_Printf(M_GetText("Air Thrust has been turned \"On\".\n")); + } + else + { + CONS_Printf(M_GetText("Air Thrust will be turned \"On\" Next Round.\n")); + } + } + else if (K_AirThrustActive() && !cv_kartairthrust.value) + { + if (leveltime < starttime) + { + airthrustactive = false; + CONS_Printf(M_GetText("Air Thrust has been turned \"Off\".\n")); + } + else + { + CONS_Printf(M_GetText("Air Thrust will be turned \"Off\" next round.\n")); } } } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7fca388e6..6d6668912 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -194,6 +194,9 @@ extern consvar_t cv_kartairsquish; extern consvar_t cv_kartairdrop; +extern consvar_t cv_kartairthrust; +extern consvar_t cv_kartairthrust_reductionrate; + extern consvar_t cv_kartitemlitter, cv_kartitempush; extern consvar_t cv_kartantibump; diff --git a/src/d_player.h b/src/d_player.h index 50ce06aa8..4e4f3ac16 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -562,9 +562,10 @@ struct player_t SINT8 driftlock; // Prevents you from using drift angle for x tics. Used for zipper fix. fixed_t driftcharge; // Charge your drift so you can release a burst of speed UINT8 driftboost; // (0 to 125) - Boost you get from drifting - tic_t driftsparkGrowTimer; - tic_t driftelapsed; // Elapsed time spent during a drift. - SINT8 driftlevel; // just for controller rumble for now + fixed_t airdriftspeed; // target velocity to reduce player velocity to while air trusting + tic_t driftsparkGrowTimer; // CLIENT ONLY - + tic_t driftelapsed; // CLIENT ONLY - Elapsed time spent during a drift. + SINT8 driftlevel; // CLIENT ONLY - handles controller rumble and air thrust power, cleared at the start of every tick. fixed_t spinoutrot; // When a player spins out, this value increments modulus 360. diff --git a/src/k_hud.c b/src/k_hud.c index 7fa5d321c..690b0ab79 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2346,10 +2346,12 @@ static void K_DrawServerMods(INT32 x, INT32 y) {"Slope Boost", 0, NULL, K_PurpleDriftActive() > 0, true}, {"Drafting", 0, NULL, K_DraftingActive() > 0, true}, {"Air Drop", 0, NULL, K_AirDropActive() > 0, true}, + {"Air Thrust", 0, NULL, K_AirThrustActive() > 0, true}, {"Bump Spark", 0, &cv_kartbumpspark, -1, true}, {"Bump Drift", 0, NULL, K_GetBumpSpark() > 0, true}, {"Bump Spark", 0, NULL, K_GetBumpSpark() > BUMPSPARK_NOCHARGE, true}, {"Bump Spring", 0, &cv_kartbumpspring, -1, true}, + //TODO: separate drawer that enumerates item changes? {"Alt. Invin.", 0, NULL, K_IsKartItemAlternate(KITEM_INVINCIBILITY), true} }; diff --git a/src/k_kart.c b/src/k_kart.c index 155d67d24..e9d9bb996 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -383,6 +383,9 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartslipdash); + CV_RegisterVar(&cv_kartairthrust); + CV_RegisterVar(&cv_kartairthrust_reductionrate); + CV_RegisterVar(&cv_kartslopeboost); CV_RegisterVar(&cv_kartaltshrinktime); @@ -8888,13 +8891,12 @@ static void K_KartDrift(player_t *player, boolean onground) // Drift Release (Moved here so you can't "chain" drifts) if (player->drift != -5 && player->drift != 5) { - if (driftstage && onground) + if (driftstage && (onground || K_IsAirThrustActive())) { UINT8 boost = 0; - if (!cv_kartdriftsounds.value || driftstage < 3) S_StartSound(player->mo, sfx_s23c); - + switch (driftstage) { case 1: @@ -8903,7 +8905,7 @@ static void K_KartDrift(player_t *player, boolean onground) case 2: boost = 50; if (cv_kartdriftsounds.value) - S_StartSound(player->mo, sfx_kc5b); + S_StartSound(player->mo, sfx_kc5b); break; case 3: boost = 80; @@ -8923,6 +8925,29 @@ static void K_KartDrift(player_t *player, boolean onground) } break; } + if (K_IsAirThrustActive() && !onground) // Air Thrust is enabled + { + // before thrust, set player's target speed to their speed before the air thrust + // after the air thrust player's momentum will be reduced back to this value + fixed_t airthrust = 0; + + player->airdriftspeed = max(K_GetKartSpeed(player), player->speed); + + if (driftstage == 1) + airthrust = FRACUNIT / 6; // ~15% boost + else if (driftstage == 2) + airthrust = FRACUNIT / 3; // ~33% boost + else if (driftstage == 3) + airthrust = FRACUNIT / 2; // 50% boost + else if (driftstage == 4) + airthrust = 3 * FRACUNIT / 4; // 75% boost + + // Give the player a forward boost + P_Thrust(player->mo, K_MomentumAngle(player->mo), FixedMul(player->speed, airthrust)); + + // Slash the player's vertical momentum. Gets stronger with higher drift charge, but is significantly weaker in water + player->mo->momz = FixedMul(player->mo->momz, FRACUNIT - FixedMul(airthrust, abs(P_GetMobjGravity(player->mo)))); + } if (player->driftboost < boost) player->driftboost = boost; @@ -8940,7 +8965,7 @@ static void K_KartDrift(player_t *player, boolean onground) player->karthud[khud_afterimagetime] = 10; } - if (onground) + if (onground || K_IsAirThrustActive()) player->driftcharge = 0; } @@ -9099,6 +9124,23 @@ static void K_KartDrift(player_t *player, boolean onground) player->pflags &= ~PF_BRAKEDRIFT; } +static void K_HandleAirDriftDrag(player_t *player) +{ + fixed_t difference; + if (player->mo && player->airdriftspeed > 0) + { + if (player->speed > player->airdriftspeed) + { + difference = player->speed - player->airdriftspeed; + P_Thrust(player->mo, K_MomentumAngle(player->mo), -min(difference, cv_kartairthrust_reductionrate.value)); + } + else // we're done doing drag (TODO: also stop applying drag after being bumped or hit or sprung etc.) + { + player->airdriftspeed = 0; + } + } +} + static void K_KartSlipdash(player_t *player, boolean onground) { boolean snaked = player->slipdashdir && player->aizdriftstrat && player->slipdashdir != player->aizdriftstrat; @@ -10722,6 +10764,17 @@ boolean K_AirDropActive(void) return false; } +boolean K_AirThrustActive(void) +{ + if (airthrustactive) + { + // Air Thrust is enabled! + return true; + } + + return false; +} + boolean K_ItemLitterActive(void) { if (itemlittering) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 4fd179536..83c1af831 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -281,6 +281,7 @@ enum player_e player_drift, player_driftcharge, player_driftboost, + player_airdriftspeed, player_boostcharge, player_slopeboost, player_prevslopeboost, @@ -497,6 +498,7 @@ static const char *const player_opt[] = { "drift", "driftcharge", "driftboost", + "airdriftspeed", "boostcharge", "slopeboost", "prevslopeboost", @@ -839,6 +841,9 @@ static int player_get(lua_State *L) case player_driftboost: lua_pushinteger(L, plr->driftboost); break; + case player_airdriftspeed: + lua_pushinteger(L, plr->airdriftspeed); + break; case player_boostcharge: lua_pushinteger(L, plr->boostcharge); break; @@ -1589,6 +1594,9 @@ static int player_set(lua_State *L) case player_driftboost: plr->driftboost = luaL_checkinteger(L, 3); break; + case player_airdriftspeed: + plr->airdriftspeed = luaL_checkinteger(L, 3); + break; case player_boostcharge: plr->boostcharge = luaL_checkinteger(L, 3); break; diff --git a/src/p_inter.c b/src/p_inter.c index bddd11064..1d8040fab 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2321,6 +2321,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } player->driftboost = 0; + player->airdriftspeed = 0; player->ringboost = 0; player->glanceDir = 0; player->pflags &= ~PF_GAINAX; diff --git a/src/p_map.c b/src/p_map.c index 2caaf1c07..1bcbbffbd 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -286,6 +286,9 @@ P_DoSpringEx finalSpeed = pSpeed; P_InstaThrust(object, finalAngle, FixedMul(finalSpeed,FixedSqrt(FixedMul(hscale, scaleVal)))); + + // clear air thrust target speed too + object->player->airdriftspeed = 0; } } } @@ -399,6 +402,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } } } + + // clear air thrust target speed too + object->player->airdriftspeed = 0; } return true; } @@ -467,6 +473,12 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) default: break; } + + if (object->player) + { + // clear air thrust target speed too + object->player->airdriftspeed = 0; + } } // diff --git a/src/p_mobj.h b/src/p_mobj.h index 000dd2613..e605bd65e 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -611,6 +611,7 @@ extern boolean purpledriftactive; extern boolean slopeboostactive; extern boolean draftingactive; extern boolean airdropactive; +extern boolean airthrustactive; extern boolean itemlittering; extern boolean itempushing; extern UINT8 bumpsparkactive; diff --git a/src/p_saveg.c b/src/p_saveg.c index 8b430dcc0..72a1444ee 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -590,6 +590,7 @@ static void P_NetSyncPlayers(savebuffer_t *save) SYNC(players[i].driftlock); SYNC(players[i].driftcharge); SYNC(players[i].driftboost); + SYNC(players[i].airdriftspeed); SYNC(players[i].aizdriftstrat); SYNC(players[i].aizdrifttilt); diff --git a/src/p_setup.c b/src/p_setup.c index 938f622e8..5a17badce 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -161,6 +161,7 @@ boolean purpledriftactive; boolean slopeboostactive; boolean draftingactive; boolean airdropactive; +boolean airthrustactive; boolean itemlittering; boolean itempushing; UINT8 bumpsparkactive; @@ -8169,6 +8170,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate) slopeboostactive = false; draftingactive = false; airdropactive = false; + airthrustactive = false; itemlittering = false; itempushing = false; bumpsparkactive = 0; @@ -8198,6 +8200,9 @@ static void P_InitLevelSettings(boolean reloadinggamestate) if (cv_kartairdrop.value) airdropactive = true; + if (cv_kartairthrust.value) + airthrustactive = true; + if (cv_kartitemlitter.value) itemlittering = true;