diff --git a/src/k_kart.c b/src/k_kart.c index f019eef50..26c7c4811 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3422,10 +3422,13 @@ static angle_t K_TumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll) return slope; } -#define STEEP_VAL (FixedAngle(40*FRACUNIT)) -void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) +#define STEEP_VAL ANG60 +#define STEEP_VAL_AIR ANG30 + ANG10 + +boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir) { + angle_t steepVal = ANGLE_MAX; fixed_t gravityadjust; angle_t oldSlope, newSlope; angle_t slopeDelta; @@ -3436,25 +3439,41 @@ void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) if (player->tumbleBounces) { // Already tumbling. - return; + return false; + } + + if ((player->mo->pitch == oldPitch) + && (player->mo->roll == oldRoll)) + { + // No change. + return false; + } + + if (fromAir == true) + { + steepVal = STEEP_VAL_AIR; + } + else + { + steepVal = STEEP_VAL; } oldSlope = K_TumbleSlope(player->mo, oldPitch, oldRoll); - if (oldSlope <= STEEP_VAL) + if (oldSlope <= steepVal) { // Transferring from flat ground to a steep slope // is a free action. (The other way around isn't, though.) - return; + return false; } newSlope = K_TumbleSlope(player->mo, player->mo->pitch, player->mo->roll); slopeDelta = AngleDelta(oldSlope, newSlope); - if (slopeDelta <= STEEP_VAL) + if (slopeDelta <= steepVal) { // Needs to be VERY steep before we'll punish this. - return; + return false; } // Oh jeez, you landed on your side. @@ -3488,6 +3507,7 @@ void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) // Reset slope. player->mo->pitch = player->mo->roll = 0; + return true; } static boolean K_LastTumbleBounceCondition(player_t *player) @@ -3525,6 +3545,7 @@ static void K_HandleTumbleBounce(player_t *player) player->tumbleHeight = 10; player->pflags |= PF_TUMBLELASTBOUNCE; player->mo->rollangle = 0; // p_user.c will stop rotating the player automatically + player->mo->pitch = player->mo->roll = 0; // Prevent Kodachrome Void infinite } } diff --git a/src/k_kart.h b/src/k_kart.h index 605e0f410..8881729ad 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -70,7 +70,7 @@ void K_DoInstashield(player_t *player); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); -void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll); +boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir); INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); diff --git a/src/p_map.c b/src/p_map.c index 996d1c2db..67f15102e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2480,7 +2480,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t oldy = tryy; fixed_t radius = thing->radius; fixed_t thingtop; - fixed_t startingonground = P_IsObjectOnGround(thing); + boolean startingonground = P_IsObjectOnGround(thing); fixed_t stairjank = 0; pslope_t *oldslope = thing->standingslope; floatok = false; @@ -2673,7 +2673,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->standingslope = tmfloorslope; P_SetPitchRollFromSlope(thing, thing->standingslope); - if (thing->momz == 0 && thing->player) + if (thing->player) { P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll); } @@ -2696,7 +2696,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->standingslope = tmceilingslope; P_SetPitchRollFromSlope(thing, thing->standingslope); - if (thing->momz == 0 && thing->player) + if (thing->player) { P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 428880478..42652afdc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1514,12 +1514,18 @@ void P_XYMovement(mobj_t *mo) } // adjust various things based on slope - if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { - if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing! + if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) + { + if (!P_IsObjectOnGround(mo)) + { + // We fell off at some point? Do the twisty thing! P_SlopeLaunch(mo); xmove = mo->momx; ymove = mo->momy; - } else { // Still on the ground. + } + else + { + // Still on the ground. slopemom.x = xmove; slopemom.y = ymove; slopemom.z = 0; @@ -1748,9 +1754,13 @@ void P_XYMovement(mobj_t *mo) if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; return; - if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT)) { // Check to see if we ran off + if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT)) + { + // Check to see if we ran off - if (oldslope != mo->standingslope) { // First, compare different slopes + if (oldslope != mo->standingslope) + { + // First, compare different slopes angle_t oldangle, newangle; angle_t moveangle = K_MomentumAngle(mo); @@ -1762,7 +1772,9 @@ void P_XYMovement(mobj_t *mo) newangle = 0; // Now compare the Zs of the different quantizations - if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later + if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) + { + // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; P_SetPitchRollFromSlope(mo, mo->standingslope); P_SlopeLaunch(mo); @@ -1776,12 +1788,17 @@ void P_XYMovement(mobj_t *mo) FIXED_TO_FLOAT(AngleFixed(oldangle-newangle)) );*/ // Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway - } else if (predictedz-mo->z > abs(slopemom.z/2) - && !(mo->standingslope->flags & SL_NOPHYSICS)) { // Now check if we were supposed to stick to this slope + } + else if (predictedz-mo->z > abs(slopemom.z/2) + && !(mo->standingslope->flags & SL_NOPHYSICS)) + { + // Now check if we were supposed to stick to this slope //CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2)); P_SlopeLaunch(mo); } - } else if (moved && mo->standingslope && predictedz) { + } + else if (moved && mo->standingslope && predictedz) + { angle_t moveangle = K_MomentumAngle(mo); angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); @@ -1789,7 +1806,8 @@ void P_XYMovement(mobj_t *mo) FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), FIXED_TO_FLOAT(predictedz) );*/ - if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) { + if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) + { mo->momz = P_MobjFlip(mo)*FRACUNIT/2; mo->z = predictedz + P_MobjFlip(mo); mo->standingslope = NULL; diff --git a/src/p_user.c b/src/p_user.c index af0aff8b1..9eba0531e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1324,14 +1324,23 @@ boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, an clipmomz = !(P_CheckDeathPitCollide(player->mo)); - if (fromAir == true && clipmomz == true) + if (clipmomz == true) { - K_SpawnSplashForMobj(player->mo, abs(player->mo->momz)); - } + if (fromAir == true) + { + K_SpawnSplashForMobj(player->mo, abs(player->mo->momz)); + } - if (player->mo->health) - { - K_CheckSlopeTumble(player, oldPitch, oldRoll); + if (player->mo->health) + { + boolean air = fromAir; + + if (P_IsObjectOnGround(player->mo) && (player->mo->eflags & MFE_JUSTHITFLOOR)) + air = true; + + if (K_CheckSlopeTumble(player, oldPitch, oldRoll, air)) + return false; + } } return clipmomz;