diff --git a/src/dehacked.c b/src/dehacked.c index a467543e9..8f4bd5083 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9317,6 +9317,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_WATERTRAILUNDERLAY7", "S_WATERTRAILUNDERLAY8", + "S_SPINDASHDUST", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -10397,6 +10399,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_WATERTRAIL", "MT_WATERTRAILUNDERLAY", + "MT_SPINDASHDUST", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/info.c b/src/info.c index 5677e4270..91cb1cb59 100644 --- a/src/info.c +++ b/src/info.c @@ -730,6 +730,8 @@ char sprnames[NUMSPRITES + 1][5] = "DBCL", // Drift boost clip "DBNC", // Drift boost clip's sparks "DBST", // Drift boost plume + + "SDDS", // Spindash dust }; char spr2names[NUMPLAYERSPRITES][5] = @@ -5026,6 +5028,8 @@ state_t states[NUMSTATES] = {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|14, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY7 {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|15, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY8 + {SPR_SDDS, FF_ANIMATE, 9, {NULL}, 9, 1, S_NULL}, // S_SPINDASHDUST + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -28675,6 +28679,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SPINDASHDUST + -1, // doomednum + S_SPINDASHDUST, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 12*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index e7d53cb5b..b8e2908e2 100644 --- a/src/info.h +++ b/src/info.h @@ -1002,6 +1002,8 @@ typedef enum sprite SPR_DBNC, // Drift boost clip's sparks SPR_DBST, // Drift boost plume + SPR_SDDS, // Spindash dust + SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMSPRITES @@ -5177,6 +5179,8 @@ typedef enum state S_WATERTRAILUNDERLAY7, S_WATERTRAILUNDERLAY8, + S_SPINDASHDUST, + #ifdef SEENAMES S_NAMECHECK, #endif @@ -6277,6 +6281,8 @@ typedef enum mobj_type MT_WATERTRAIL, MT_WATERTRAILUNDERLAY, + MT_SPINDASHDUST, + #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/k_kart.c b/src/k_kart.c index 8a3597f1f..1197706ae 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2044,7 +2044,7 @@ static fixed_t K_FlameShieldDashVar(INT32 val) return (3*FRACUNIT/4) + (((val * FRACUNIT) / TICRATE) / 2); } -tic_t K_GetSpindashChargeTime(player_t *player) +INT16 K_GetSpindashChargeTime(player_t *player) { // more charge time for higher speed // Tails = 2s, Mighty = 3s, Fang = 4s, Metal = 4s @@ -6788,9 +6788,43 @@ boolean K_PlayerEBrake(player_t *player) && player->powers[pw_nocontrol] == 0; } +static void K_KartSpindashDust(mobj_t *parent) +{ + fixed_t rad = FixedHypot(parent->radius, parent->radius); + INT32 i; + + for (i = 0; i < 2; i++) + { + + fixed_t hmomentum = P_RandomRange(6, 12) * parent->scale; + fixed_t vmomentum = P_RandomRange(2, 6) * parent->scale; + + angle_t ang = parent->player->drawangle + ANGLE_180; + SINT8 flip = 1; + + mobj_t *dust; + + if (i & 1) + ang -= ANGLE_45; + else + ang += ANGLE_45; + + dust = P_SpawnMobjFromMobj(parent, + FixedMul(rad, FINECOSINE(ang >> ANGLETOFINESHIFT)), + FixedMul(rad, FINESINE(ang >> ANGLETOFINESHIFT)), + 0, MT_SPINDASHDUST + ); + flip = P_MobjFlip(dust); + + dust->momx = FixedMul(hmomentum, FINECOSINE(ang >> ANGLETOFINESHIFT)); + dust->momy = FixedMul(hmomentum, FINESINE(ang >> ANGLETOFINESHIFT)); + dust->momz = vmomentum * flip; + } +} + static void K_KartSpindash(player_t *player) { - const tic_t MAXCHARGETIME = K_GetSpindashChargeTime(player); + const INT16 MAXCHARGETIME = K_GetSpindashChargeTime(player); ticcmd_t *cmd = &player->cmd; if (player->kartstuff[k_spindash] > 0 && (cmd->buttons & (BT_DRIFT|BT_BRAKE)) != (BT_DRIFT|BT_BRAKE)) @@ -6817,6 +6851,11 @@ static void K_KartSpindash(player_t *player) S_StartSound(player->mo, sfx_s23c); } + if (player->kartstuff[k_spindashboost] > (TICRATE/2)) + { + K_KartSpindashDust(player->mo); + } + if (K_PlayerEBrake(player) == false) { player->kartstuff[k_spindash] = 0; @@ -6831,24 +6870,36 @@ static void K_KartSpindash(player_t *player) if ((cmd->buttons & (BT_DRIFT|BT_BRAKE)) == (BT_DRIFT|BT_BRAKE)) { INT16 chargetime = MAXCHARGETIME - ++player->kartstuff[k_spindash]; + boolean spawnOldEffect = true; + + if (chargetime <= (MAXCHARGETIME / 2)) + { + K_KartSpindashDust(player->mo); + spawnOldEffect = false; + } + if (chargetime > 0) { UINT16 soundcharge = 0; UINT8 add = 0; + while ((soundcharge += ++add) < chargetime); + if (soundcharge == chargetime) { - K_SpawnDashDustRelease(player); + if (spawnOldEffect == true) + K_SpawnDashDustRelease(player); S_StartSound(player->mo, sfx_s3kab); } } else if (chargetime < -TICRATE) + { P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + } else { if (player->kartstuff[k_spindash] % 4 == 0) { - K_SpawnDashDustRelease(player); K_FlameDashLeftoverSmoke(player->mo); } } diff --git a/src/k_kart.h b/src/k_kart.h index 2c1236368..6fcf7690d 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -77,7 +77,7 @@ void K_StripItems(player_t *player); void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); boolean K_ApplyOffroad(player_t *player); -tic_t K_GetSpindashChargeTime(player_t *player); +INT16 K_GetSpindashChargeTime(player_t *player); fixed_t K_GetSpindashChargeSpeed(player_t *player); fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);