From f2bbcbefa25a86ff7c888fc01548e043fcdcde27 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 14 Mar 2019 19:43:58 -0400 Subject: [PATCH] Drafting --- src/d_player.h | 2 + src/dehacked.c | 5 +++ src/info.c | 3 ++ src/info.h | 2 + src/k_kart.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+) diff --git a/src/d_player.h b/src/d_player.h index 914714935..52d85b18f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -306,6 +306,8 @@ typedef enum k_boostpower, // Base boost value, for offroad k_speedboost, // Boost value smoothing for max speed k_accelboost, // Boost value smoothing for acceleration + k_draftpower, // Drafting power (from 0 to FRACUNIT), doubles your top speed & acceleration at max + k_draftleeway, // Leniency timer before removing draft power k_boostcam, // Camera push forward on boost k_destboostcam, // Ditto k_timeovercam, // Camera timer for leaving behind or not diff --git a/src/dehacked.c b/src/dehacked.c index acd8761b7..48fc60b69 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7152,6 +7152,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_OPAQUESMOKE4", "S_OPAQUESMOKE5", + // Chaotix draft band + "S_DRAFTBAND", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -8375,6 +8378,8 @@ static const char *const KARTSTUFF_LIST[] = { "BOOSTPOWER", "SPEEDBOOST", "ACCELBOOST", + "DRAFTPOWER", + "DRAFTLEEWAY", "BOOSTCAM", "DESTBOOSTCAM", "TIMEOVERCAM", diff --git a/src/info.c b/src/info.c index f297fb0aa..c2fab68f6 100644 --- a/src/info.c +++ b/src/info.c @@ -3401,6 +3401,9 @@ state_t states[NUMSTATES] = {SPR_SMOK, 3, 7, {NULL}, 0, 0, S_OPAQUESMOKE5}, // S_OPAQUESMOKE4 {SPR_SMOK, 4, 8, {NULL}, 0, 0, S_NULL}, // S_OPAQUESMOKE5 + // Chaotix draft band + {SPR_FWRK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_DRAFTBAND + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif diff --git a/src/info.h b/src/info.h index 0e23a07c5..c38d9d9cc 100644 --- a/src/info.h +++ b/src/info.h @@ -4058,6 +4058,8 @@ typedef enum state S_OPAQUESMOKE4, S_OPAQUESMOKE5, + S_DRAFTBAND, + #ifdef SEENAMES S_NAMECHECK, #endif diff --git a/src/k_kart.c b/src/k_kart.c index 0b90b1ec4..1d617f6b4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1541,6 +1541,117 @@ static void K_UpdateOffroad(player_t *player) player->kartstuff[k_offroad] = 0; } +/** \brief Updates the player's drafting values once per frame + + \param player player object passed from K_KartPlayerThink + + \return void +*/ +static void K_UpdateDraft(player_t *player) +{ + fixed_t topspd = K_GetKartSpeed(player, false); + fixed_t draftdistance; + UINT8 i; + + // Not enough speed to draft. + if (player->speed < 20*mapobjectscale) + return; + + // Distance you have to be to draft. If you're still accelerating, then this distance is lessened. + // This distance biases toward low weight! (min weight is 2368 units, max weight is 832 units) + draftdistance = (832 + ((9 - player->kartweight) * 192)) * mapobjectscale; + if (player->speed < topspd) + draftdistance = FixedDiv(FixedMul(player->speed, draftdistance), topspd); + + // Let's hunt for players to draft off of! + for (i = 0; i < MAXPLAYERS; i++) + { + fixed_t dist; + angle_t yourangle, theirangle, diff; + + if (!playeringame[i] || players[i].spectator || !players[i].mo) + continue; + + // Don't draft on yourself :V + if (&players[i] == player) + continue; + + // Not enough speed to draft off of. + if (players[i].speed < 20*mapobjectscale) + continue; + + dist = P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x, players[i].mo->y - player->mo->y), players[i].mo->z - player->mo->z); + + // Not close enough to draft. + if (dist > draftdistance) + continue; + + yourangle = R_PointToAngle2(0,0,player->mo->momx,player->mo->momy); + theirangle = R_PointToAngle2(0,0,players[i].mo->momx,players[i].mo->momy); + + diff = yourangle - theirangle; + if (diff > ANGLE_180) + diff = InvAngle(diff); + + // Not moving in the same direction. + if (diff > ANGLE_90) + continue; + + player->kartstuff[k_draftleeway] = TICRATE/2; + + // Draft power is used later in K_GetKartBoostPower, ranging from 0 for normal speed and FRACUNIT for max draft speed. + // How much this increments every tic biases toward acceleration! (min speed is 6.25% per tic, max speed is 0.25% per tic) + if (player->kartstuff[k_draftpower] < FRACUNIT) + player->kartstuff[k_draftpower] += (FRACUNIT/400) + ((9 - player->kartspeed) * ((3*FRACUNIT) / 400)); + + if (player->kartstuff[k_draftpower] > FRACUNIT) + player->kartstuff[k_draftpower] = FRACUNIT; + + // Spawn in the visual! + if (leveltime & 1) + { + const fixed_t spacing = 256; + UINT8 amt = (dist / mapobjectscale) / spacing; + UINT8 offset = ((leveltime / 3) % 3); + fixed_t stepx, stepy, stepz; + fixed_t curx, cury, curz; + + stepx = (players[i].mo->x - player->mo->x) / amt; + stepy = (players[i].mo->y - player->mo->y) / amt; + stepz = ((players[i].mo->z + (players[i].mo->height / 2)) - (player->mo->z + (player->mo->height / 2))) / amt; + + curx = player->mo->x + stepx; + cury = player->mo->y + stepy; + curz = player->mo->z + stepz; + + while (amt > 0) + { + if (offset == 0) + { + mobj_t *band = P_SpawnMobj(curx, cury, curz + (24*mapobjectscale), MT_THOK); + P_SetMobjState(band, S_DRAFTBAND); + band->color = player->skincolor; + } + + curx += stepx; + cury += stepy; + curz += stepz; + + offset = (offset+1) % 3; + amt--; + } + } + + return; // Finished doing our draft. + } + + // No one to draft off of? Then you can knock that off. + if (player->kartstuff[k_draftleeway]) // Prevent small disruptions from stopping your draft. + player->kartstuff[k_draftleeway]--; + else if (player->kartstuff[k_draftpower]) // Remove draft speed boost. + player->kartstuff[k_draftpower] = 0; +} + void K_KartPainEnergyFling(player_t *player) { static const UINT8 numfling = 5; @@ -2033,6 +2144,13 @@ static void K_GetKartBoostPower(player_t *player) // don't average them anymore, this would make a small boost and a high boost less useful // just take the highest we want instead + // Drafting bonuses + if (player->kartstuff[k_draftpower] > 0) + { + speedboost += player->kartstuff[k_draftpower]; + accelboost += player->kartstuff[k_draftpower]; + } + player->kartstuff[k_boostpower] = boostpower; // value smoothing @@ -4662,6 +4780,7 @@ void K_KartPlayerHUDUpdate(player_t *player) void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { K_UpdateOffroad(player); + K_UpdateDraft(player); K_UpdateEngineSounds(player, cmd); // Thanks, VAda! K_GetKartBoostPower(player);