diff --git a/src/k_kart.c b/src/k_kart.c index 1517d595e..9ad06d42f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4510,6 +4510,42 @@ void K_DriftDustHandling(mobj_t *spawner) } } +void K_Squish(mobj_t *mo) +{ + const fixed_t maxstretch = 4*FRACUNIT; + const fixed_t factor = 3 * mo->height / 2; + const fixed_t threshold = factor / 6; + + const fixed_t old3dspeed = abs(mo->lastmomz); + const fixed_t new3dspeed = abs(mo->momz); + + const fixed_t delta = abs(old3dspeed - new3dspeed); + + if (delta > threshold) + { + mo->spritexscale = + FRACUNIT + FixedDiv(delta, factor); + + if (mo->spritexscale > maxstretch) + mo->spritexscale = maxstretch; + + if (abs(new3dspeed) > abs(old3dspeed)) + { + mo->spritexscale = + FixedDiv(FRACUNIT, mo->spritexscale); + } + } + else + { + mo->spritexscale -= + (mo->spritexscale - FRACUNIT) + / (mo->spritexscale < FRACUNIT ? 8 : 2); + } + + mo->spriteyscale = + FixedDiv(FRACUNIT, mo->spritexscale); +} + static mobj_t *K_FindLastTrailMobj(player_t *player) { mobj_t *trail; diff --git a/src/k_kart.h b/src/k_kart.h index b8e74539b..9a07fe609 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -76,6 +76,7 @@ void K_SpawnSparkleTrail(mobj_t *mo); void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad); void K_SpawnDraftDust(mobj_t *mo); void K_DriftDustHandling(mobj_t *spawner); +void K_Squish(mobj_t *mo); mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow); void K_PuntMine(mobj_t *mine, mobj_t *punter); void K_DoSneaker(player_t *player, INT32 type); diff --git a/src/p_mobj.c b/src/p_mobj.c index 27c23ea92..c2ec5d1db 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3511,6 +3511,16 @@ static void P_CheckFloatbobPlatforms(mobj_t *mobj) } } +static void P_SquishThink(mobj_t *mobj) +{ + if (!(mobj->eflags & MFE_SLOPELAUNCHED)) + { + K_Squish(mobj); + } + + mobj->lastmomz = mobj->momz; +} + static void P_PlayerMobjThinker(mobj_t *mobj) { I_Assert(mobj != NULL); @@ -3576,6 +3586,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj) mobj->eflags &= ~MFE_JUSTHITFLOOR; } + P_SquishThink(mobj); + animonly: P_CyclePlayerMobjState(mobj); } @@ -8626,7 +8638,7 @@ void P_MobjThinker(mobj_t *mobj) return; } - mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG); + mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG|MFE_SLOPELAUNCHED); tmfloorthing = tmhitthing = NULL; @@ -8815,6 +8827,8 @@ void P_MobjThinker(mobj_t *mobj) P_ButteredSlope(mobj); } + P_SquishThink(mobj); + if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health && P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz { diff --git a/src/p_mobj.h b/src/p_mobj.h index 3247c14d7..3c7ab4367 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -249,6 +249,8 @@ typedef enum MFE_JUSTBOUNCEDWALL = 1<<12, // SRB2Kart: In damage hitlag (displays different visual efx) MFE_DAMAGEHITLAG = 1<<13, + // Slope physics sent you airborne + MFE_SLOPELAUNCHED = 1<<14, // free: to and including 1<<15 } mobjeflag_t; @@ -361,6 +363,7 @@ typedef struct mobj_s fixed_t friction; fixed_t movefactor; + fixed_t lastmomz; INT32 fuse; // Does something in P_MobjThinker on reaching 0. fixed_t watertop; // top of the water FOF the mobj is in diff --git a/src/p_saveg.c b/src/p_saveg.c index ce1093061..83625026d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1534,7 +1534,8 @@ typedef enum MD2_HITLAG = 1<<24, MD2_WAYPOINTCAP = 1<<25, MD2_KITEMCAP = 1<<26, - MD2_ITNEXT = 1<<27 + MD2_ITNEXT = 1<<27, + MD2_LASTMOMZ = 1<<28, } mobj_diff2_t; typedef enum @@ -1775,6 +1776,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_KITEMCAP; if (mobj->itnext) diff2 |= MD2_ITNEXT; + if (mobj->lastmomz) + diff2 |= MD2_LASTMOMZ; if (diff2 != 0) diff |= MD_MORE; @@ -1968,6 +1971,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) { WRITEINT32(save_p, mobj->hitlag); } + if (diff2 & MD2_LASTMOMZ) + { + WRITEINT32(save_p, mobj->lastmomz); + } WRITEUINT32(save_p, mobj->mobjnum); } @@ -3062,6 +3069,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) { mobj->hitlag = READINT32(save_p); } + if (diff2 & MD2_LASTMOMZ) + { + mobj->lastmomz = READINT32(save_p); + } if (diff & MD_REDFLAG) { diff --git a/src/p_slopes.c b/src/p_slopes.c index d1e8f5f54..1bde8f4ee 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -844,6 +844,8 @@ void P_SlopeLaunch(mobj_t *mo) mo->momy = slopemom.y; mo->momz = slopemom.z; #endif + + mo->eflags |= MFE_SLOPELAUNCHED; } //CONS_Printf("Launched off of slope.\n");