diff --git a/src/d_player.h b/src/d_player.h index 0c3501227..f9ccf8a6c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -828,6 +828,8 @@ struct player_t UINT8 numsneakers; // Number of stacked sneaker effects UINT16 panelsneakertimer; UINT8 numpanelsneakers; + UINT16 weaksneakertimer; + UINT8 numweaksneakers; UINT8 floorboost; // (0 to 3) - Prevents Sneaker sounds for a brief duration when triggered by a floor panel INT16 growshrinktimer; // > 0 = Big, < 0 = small diff --git a/src/k_collide.cpp b/src/k_collide.cpp index 77cf778c8..d42be35d0 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -973,6 +973,7 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim) attackerPlayer->spindashboost = 0; attackerPlayer->sneakertimer = 0; attackerPlayer->panelsneakertimer = 0; + attackerPlayer->weaksneakertimer = 0; attackerPlayer->instaWhipCharge = 0; attackerPlayer->flashing = 0; @@ -1211,7 +1212,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) { auto shouldSteal = [](mobj_t *t1, mobj_t *t2) { - return ((t1->player->sneakertimer > 0 || t1->player->panelsneakertimer > 0) + return ((t1->player->sneakertimer > 0 || t1->player->panelsneakertimer > 0 || t1->player->weaksneakertimer > 0) && !P_PlayerInPain(t1->player) && (t1->player->flashing == 0)); }; diff --git a/src/k_kart.c b/src/k_kart.c index 8ce6ba3f8..8c742d069 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3012,7 +3012,7 @@ void K_MomentumToFacing(player_t *player) boolean K_ApplyOffroad(const player_t *player) { - if (player->invincibilitytimer || player->hyudorotimer || player->sneakertimer || player->panelsneakertimer) + if (player->invincibilitytimer || player->hyudorotimer || player->sneakertimer || player->panelsneakertimer|| player->weaksneakertimer) return false; if (K_IsRidingFloatingTop(player)) return false; @@ -3021,7 +3021,7 @@ boolean K_ApplyOffroad(const player_t *player) boolean K_SlopeResistance(const player_t *player) { - if (player->invincibilitytimer || player->sneakertimer || player->panelsneakertimer || player->tiregrease || player->flamedash) + if (player->invincibilitytimer || player->sneakertimer || player->panelsneakertimer || player->weaksneakertimer || player->tiregrease || player->flamedash) return true; if (player->curshield == KSHIELD_TOP) return true; @@ -3162,6 +3162,7 @@ boolean K_WaterRun(mobj_t *mobj) if (mobj->player->invincibilitytimer || mobj->player->sneakertimer || mobj->player->panelsneakertimer + || mobj->player->weaksneakertimer || mobj->player->tiregrease || mobj->player->flamedash || mobj->player->speed > minspeed) @@ -3526,19 +3527,29 @@ static void K_GetKartBoostPower(player_t *player) UINT8 i; for (i = 0; i < player->numsneakers; i++) { - ADDBOOST(FRACUNIT, 8*FRACUNIT, HANDLESCALING+HANDLESCALING/3); // + 100% top speed, + 800% acceleration, +50% handling + ADDBOOST(FRACUNIT, 8*FRACUNIT, HANDLESCALING+HANDLESCALING/3); // + 100% top speed, + 800% acceleration, +50%(???) handling } } - if (player->panelsneakertimer) // Sneaker + if (player->panelsneakertimer) // Sneaker panel { UINT8 i; for (i = 0; i < player->numpanelsneakers; i++) { - ADDBOOST(FRACUNIT/2, 8*FRACUNIT, HANDLESCALING); // + 50% top speed, + 800% acceleration, +50% handling + ADDBOOST(FRACUNIT/2, 8*FRACUNIT, HANDLESCALING); // + 50% top speed, + 800% acceleration, +50%(???) handling } } + if (player->weaksneakertimer) // Rocket sneaker boost + { + UINT8 i; + for (i = 0; i < player->numweaksneakers; i++) + { + ADDBOOST((FRACUNIT*85)/100, 8*FRACUNIT, HANDLESCALING+HANDLESCALING/3); // + 85% top speed, + 800% acceleration, +50%(???) handling + } + } + //NOTE: The various sneaker booth strengths are also defined in K_DoSneaker()! + if (player->invincibilitytimer) // Invincibility { // S-Monitor: no extra % @@ -4002,7 +4013,7 @@ SINT8 K_GetForwardMove(const player_t *player) return 0; } - if (player->sneakertimer || player->panelsneakertimer || player->spindashboost + if (player->sneakertimer || player->panelsneakertimer || player->weaksneakertimer || player->spindashboost || (((gametyperules & (GTR_ROLLINGSTART|GTR_CIRCUIT)) == (GTR_ROLLINGSTART|GTR_CIRCUIT)) && (leveltime < TICRATE/2))) { return MAXPLMOVE; @@ -5065,7 +5076,7 @@ static boolean K_IsLosingWavedash(player_t *player) if (!K_Sliptiding(player) && player->wavedash < MIN_WAVEDASH_CHARGE) return true; if (!K_Sliptiding(player) && player->drift == 0 - && P_IsObjectOnGround(player->mo) && player->sneakertimer == 0 && player->panelsneakertimer == 0 + && P_IsObjectOnGround(player->mo) && player->sneakertimer == 0 && player->panelsneakertimer == 0 && player->weaksneakertimer == 0 && player->driftboost == 0) return true; return false; @@ -7204,8 +7215,14 @@ void K_DoSneaker(player_t *player, INT32 type) fixed_t intendedboost = FRACUNIT/2; - // If you've already got an item sneaker type boost, panel sneakers will instead turn into item sneaker boosts - if (player->numsneakers && type == 0) + // If you've already got an rocket sneaker type boost, panel sneakers will instead turn into rocket sneaker boosts + if (player->numweaksneakers && type == 0) + { + type = 2; + } + + // If you've already got an item sneaker type boost, other sneakers will instead turn into item sneaker boosts + if (player->numsneakers && type != 1) { type = 1; } @@ -7216,10 +7233,13 @@ void K_DoSneaker(player_t *player, INT32 type) intendedboost = FRACUNIT/2; break; case 1: // Single item sneaker - case 2: // Rocket sneaker + intendedboost = 100*FRACUNIT/100; + break; + case 2: // Rocket sneaker (aka. weaksneaker) intendedboost = 85*FRACUNIT/100; break; } + //NOTE: The various sneaker booth strengths are also defined in K_GetKartBoostPower()! if (player->roundconditions.touched_sneakerpanel == false && !(player->exiting || (player->pflags & PF_NOCONTEST)) @@ -7235,7 +7255,7 @@ void K_DoSneaker(player_t *player, INT32 type) const sfxenum_t smallsfx = sfx_cdfm40; sfxenum_t sfx = normalsfx; - if (player->numsneakers || player->numpanelsneakers) + if (player->numsneakers || player->numpanelsneakers || player->numweaksneakers) { // Use a less annoying sound when stacking sneakers. sfx = smallsfx; @@ -7251,17 +7271,19 @@ void K_DoSneaker(player_t *player, INT32 type) switch (type) { - case 0: + case 0: // Panel sneaker player->numpanelsneakers++; break; - case 1: - case 2: + case 1: // Single item sneaker player->numsneakers++; break; + case 2: // Rocket sneaker (aka. weaksneaker) + player->numweaksneakers++; + break; } } - if (player->sneakertimer == 0 && player->panelsneakertimer == 0) + if (player->sneakertimer == 0 && player->panelsneakertimer == 0 && player->weaksneakertimer == 0) { if (type == 2) { @@ -7293,16 +7315,16 @@ void K_DoSneaker(player_t *player, INT32 type) switch (type) { - case 0: + case 0: // Panel sneaker player->panelsneakertimer = sneakertime; player->overshield += 1; break; - case 1: + case 1: // Single item sneaker player->sneakertimer = sneakertime; player->overshield += TICRATE/2; break; - case 2: - player->sneakertimer = 3*sneakertime/4; + case 2: // Rocket sneaker (aka. weaksneaker) + player->weaksneakertimer = 3*sneakertime/4; player->overshield += TICRATE/2; break; } @@ -7438,7 +7460,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) } } - if (mo->player->sneakertimer || mo->player->panelsneakertimer || mo->player->invincibilitytimer) + if (mo->player->sneakertimer || mo->player->panelsneakertimer || mo->player->weaksneakertimer || mo->player->invincibilitytimer) { thrust = FixedMul(thrust, (3*FRACUNIT)/2); } @@ -9198,7 +9220,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->speed > 0) { // Speed lines - if (player->sneakertimer || player->panelsneakertimer || player->ringboost + if (player->sneakertimer || player->panelsneakertimer || player->weaksneakertimer || player->ringboost || player->driftboost || player->startboost || player->eggmanexplode || player->trickboost || player->gateBoost || player->wavedashboost) @@ -9439,7 +9461,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (((P_IsObjectOnGround(player->mo) || ( player->spinouttype & KSPIN_AIRTIMER )) && (!player->sneakertimer) - && (!player->panelsneakertimer)) + && (!player->panelsneakertimer) + && (!player->weaksneakertimer)) || (player->respawn.state != RESPAWNST_NONE && player->spinouttimer > 1 && (leveltime & 1))) @@ -9635,6 +9658,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } + if (player->weaksneakertimer) + { + player->weaksneakertimer--; + + if (player->weaksneakertimer <= 0) + { + player->numweaksneakers = 0; + } + } + if (player->trickboost) player->trickboost--; @@ -9654,7 +9687,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->counterdash) player->counterdash--; - if ((player->sneakertimer || player->panelsneakertimer) && player->wipeoutslow > 0 && player->wipeoutslow < wipeoutslowtime+1) + if ((player->sneakertimer || player->panelsneakertimer || player->weaksneakertimer) && player->wipeoutslow > 0 && player->wipeoutslow < wipeoutslowtime+1) player->wipeoutslow = wipeoutslowtime+1; if (player->floorboost > 0) @@ -9958,6 +9991,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->tiregrease = 0; player->sneakertimer = 0; player->panelsneakertimer = 0; + player->weaksneakertimer = 0; player->spindashboost = 0; player->flashing = TICRATE/2; player->ringboost = 0; diff --git a/src/objects/crate.cpp b/src/objects/crate.cpp index bfea4d900..224880d14 100644 --- a/src/objects/crate.cpp +++ b/src/objects/crate.cpp @@ -110,7 +110,7 @@ struct Side : Graphic struct Toucher : Mobj { - bool boosting() const { return player && (player->sneakertimer || player->panelsneakertimer || K_PlayerCanPunt(player)); } + bool boosting() const { return player && (player->sneakertimer || player->panelsneakertimer || player->weaksneakertimer || K_PlayerCanPunt(player)); } }; struct AnyBox : Graphic diff --git a/src/objects/rocks.cpp b/src/objects/rocks.cpp index 8bf400838..1ed75110d 100644 --- a/src/objects/rocks.cpp +++ b/src/objects/rocks.cpp @@ -96,7 +96,7 @@ private: { const player_t* p = toucher->player; - if (p->sneakertimer || p->panelsneakertimer || p->invincibilitytimer || p->growshrinktimer > 0 || p->hyudorotimer) + if (p->sneakertimer || p->panelsneakertimer || p->weaksneakertimer || p->invincibilitytimer || p->growshrinktimer > 0 || p->hyudorotimer) { return; } diff --git a/src/objects/ufo.c b/src/objects/ufo.c index f753874c3..8bdce7962 100644 --- a/src/objects/ufo.c +++ b/src/objects/ufo.c @@ -895,7 +895,7 @@ static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType) { // Players deal damage relative to how many sneakers they used. targetdamaging = UFOD_BOOST; - ret = 15 * max(1, inflictor->player->numsneakers + inflictor->player->numpanelsneakers); + ret = 15 * max(1, inflictor->player->numsneakers + inflictor->player->numpanelsneakers + inflictor->player->numweaksneakers); break; } case MT_SPECIAL_UFO: @@ -1056,6 +1056,8 @@ void Obj_PlayerUFOCollide(mobj_t *ufo, mobj_t *other) other->player->numsneakers = 0; other->player->panelsneakertimer = 0; other->player->numpanelsneakers = 0; + other->player->weaksneakertimer = 0; + other->player->numweaksneakers = 0; // Copied from Obj_OrbinautThrown const ffloor_t *rover = P_IsObjectFlipped(other) ? other->ceilingrover : other->floorrover; diff --git a/src/p_inter.c b/src/p_inter.c index c7b370f04..0a74ab9c4 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3288,6 +3288,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player->sneakertimer = player->numsneakers = 0; player->panelsneakertimer = player->numpanelsneakers = 0; + player->weaksneakertimer = player->numweaksneakers = 0; player->driftboost = player->strongdriftboost = 0; player->gateBoost = 0; player->fastfall = 0; diff --git a/src/p_mobj.c b/src/p_mobj.c index 98d377637..cfa0b4e0d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7989,7 +7989,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (p) { - UINT16 timer = max(p->sneakertimer, p->panelsneakertimer); + UINT16 timer = max(max(p->sneakertimer, p->panelsneakertimer), p->weaksneakertimer); if (timer > mobj->movecount) P_SetMobjState(mobj, S_BOOSTFLAME); mobj->movecount = timer; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 7fc84d0f8..c971ad20e 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -550,6 +550,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].numsneakers); WRITEUINT16(save->p, players[i].panelsneakertimer); WRITEUINT8(save->p, players[i].numpanelsneakers); + WRITEUINT16(save->p, players[i].weaksneakertimer); + WRITEUINT8(save->p, players[i].numweaksneakers); WRITEUINT8(save->p, players[i].floorboost); @@ -1196,6 +1198,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].numsneakers = READUINT8(save->p); players[i].panelsneakertimer = READUINT16(save->p); players[i].numpanelsneakers = READUINT8(save->p); + players[i].numweaksneakers = READUINT8(save->p); players[i].floorboost = READUINT8(save->p); players[i].growshrinktimer = READINT16(save->p); diff --git a/src/p_tick.c b/src/p_tick.c index 29cf6d62c..0ae7e3de7 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -599,9 +599,9 @@ static inline void P_DeviceRumbleTick(void) { low = high = 65536 / 2; } - else if (player->sneakertimer > (sneakertime-(TICRATE/2)) || player->panelsneakertimer > (sneakertime-(TICRATE/2))) + else if (player->sneakertimer > (sneakertime-(TICRATE/2)) || player->panelsneakertimer > (sneakertime-(TICRATE/2)) || player->weaksneakertimer > (sneakertime-(TICRATE/2))) { - low = high = 65536 / (3+player->numsneakers+player->numpanelsneakers); + low = high = 65536 / (3+player->numsneakers+player->numpanelsneakers+player->numweaksneakers); } else if (((player->boostpower < FRACUNIT) || (player->stairjank > 8)) && P_IsObjectOnGround(player->mo) && player->speed != 0) diff --git a/src/p_user.c b/src/p_user.c index 3b7119c30..5895b6cbc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2618,7 +2618,7 @@ void P_MovePlayer(player_t *player) //////////////////////////// // SRB2kart - Drifting smoke and fire - if ((player->sneakertimer || player->panelsneakertimer || player->flamedash) + if ((player->sneakertimer || player->panelsneakertimer || player->weaksneakertimer || player->flamedash) && onground && (leveltime & 1)) K_SpawnBoostTrail(player);