diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 814320fce..e63cafe33 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -617,6 +617,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); rsp->driftInput = players[i].driftInput; + rsp->airFailsafe = players[i].airFailsafe; rsp->trickpanel = (UINT8)players[i].trickpanel; rsp->trickdelay = (boolean)players[i].trickdelay; @@ -779,6 +780,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); players[i].driftInput = (boolean)rsp->driftInput; + players[i].airFailsafe = (boolean)rsp->airFailsafe; players[i].trickpanel = (UINT8)rsp->trickpanel; players[i].trickdelay = (boolean)rsp->trickdelay; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index f5e21d2e3..82baf6581 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -281,6 +281,7 @@ typedef struct INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; boolean driftInput; + boolean airFailsafe; UINT8 trickpanel; boolean trickdelay; fixed_t trickmomx; diff --git a/src/d_player.h b/src/d_player.h index fc98e93bd..95fd8adea 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -525,6 +525,7 @@ typedef struct player_s respawnvars_t respawn; // Respawn info tic_t airtime; // Keep track of how long you've been in the air boolean driftInput; // Whenever or not try drifting. + boolean airFailsafe; // Whenever or not try the air boost UINT8 trickpanel; // Trick panel state boolean trickdelay; // Prevent tricks until control stick is neutral diff --git a/src/k_kart.c b/src/k_kart.c index eb7f10720..4ef73a2b6 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6984,6 +6984,7 @@ INT32 K_GetKartDriftSparkValue(player_t *player) Stage 1: red sparks Stage 2: blue sparks Stage 3: big large rainbow sparks +Stage 0: air failsafe */ void K_SpawnDriftBoostExplosion(player_t *player, int stage) { @@ -7014,6 +7015,11 @@ void K_SpawnDriftBoostExplosion(player_t *player, int stage) S_StartSound(player->mo, sfx_kc5b); S_StartSound(player->mo, sfx_s3kc4l); break; + + case 0: + overlay->color = SKINCOLOR_SILVER; + overlay->fuse = 16; + break; } overlay->extravalue1 = stage; @@ -7586,6 +7592,39 @@ static void K_KartSpindash(player_t *player) } } +static void K_AirFailsafe(player_t *player) +{ + const fixed_t maxSpeed = 6*player->mo->scale; + const fixed_t thrustSpeed = 6*player->mo->scale; // 10*player->mo->scale + + ticcmd_t *cmd = &player->cmd; + + if (player->speed > maxSpeed // Above the max speed that you're allowed to use this technique. + || player->respawn.state != RESPAWNST_NONE) // Respawning, you don't need this AND drop dash :V + { + player->airFailsafe = false; + return; + } + + if ((cmd->buttons & BT_ACCELERATE) || K_GetForwardMove(player) != 0) + { + // Queue up later + player->airFailsafe = true; + return; + } + + if (player->airFailsafe == true) + { + // Push the player forward + P_Thrust(player->mo, K_MomentumAngle(player->mo), thrustSpeed); + + S_StartSound(player->mo, sfx_s23c); + K_SpawnDriftBoostExplosion(player, 0); + + player->airFailsafe = false; + } +} + // // K_AdjustPlayerFriction // @@ -8459,9 +8498,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } } - K_KartDrift(player, P_IsObjectOnGround(player->mo)); // Not using onground, since we don't want this affected by spring pads + K_KartDrift(player, onground); K_KartSpindash(player); + if (onground == false) + { + K_AirFailsafe(player); + } + else + { + player->airFailsafe = false; + } + // Play the starting countdown sounds if (player == &players[g_localplayers[0]]) // Don't play louder in splitscreen { diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index a8e0e5810..61c6e85b1 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -220,6 +220,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->airtime); else if (fastcmp(field,"driftInput")) lua_pushboolean(L, plr->driftInput); + else if (fastcmp(field,"airFailsafe")) + lua_pushboolean(L, plr->airFailsafe); else if (fastcmp(field,"tumbleBounces")) lua_pushinteger(L, plr->tumbleBounces); else if (fastcmp(field,"tumbleHeight")) @@ -533,6 +535,8 @@ static int player_set(lua_State *L) plr->airtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"driftInput")) plr->driftInput = luaL_checkboolean(L, 3); + else if (fastcmp(field,"airFailsafe")) + plr->airFailsafe = luaL_checkboolean(L, 3); else if (fastcmp(field,"tumbleBounces")) plr->tumbleBounces = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"tumbleHeight")) diff --git a/src/p_mobj.c b/src/p_mobj.c index 438b88099..96a10458f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6748,6 +6748,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->fuse == 16)/* to red*/ K_SpawnDriftBoostClip(mobj->target->player); break; + + case 0:/* air failsafe boost */ + mobj->color = SKINCOLOR_SILVER; // force white + break; } { diff --git a/src/p_saveg.c b/src/p_saveg.c index 0eff1e1d3..e24e3d2f7 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -258,6 +258,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].airtime); WRITEUINT8(save_p, players[i].driftInput); + WRITEUINT8(save_p, players[i].airFailsafe); WRITEUINT8(save_p, players[i].trickpanel); WRITEUINT8(save_p, players[i].trickdelay); @@ -463,6 +464,7 @@ static void P_NetUnArchivePlayers(void) players[i].airtime = READUINT32(save_p); players[i].driftInput = (boolean)READUINT8(save_p); + players[i].airFailsafe = (boolean)READUINT8(save_p); players[i].trickpanel = READUINT8(save_p); players[i].trickdelay = READUINT8(save_p);