Merge branch 'tumble-slope-fuck' into 'master'

Stumble + Smooth Landing

See merge request KartKrew/Kart!571
This commit is contained in:
Sal 2022-09-21 14:13:17 +00:00
commit cb85e23422
12 changed files with 487 additions and 41 deletions

View file

@ -590,6 +590,8 @@ typedef struct player_s
UINT8 shrinkLaserDelay;
mobj_t *stumbleIndicator;
#ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering
#endif

View file

@ -3837,6 +3837,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_TRIPWIREBOOST_BLAST_TOP",
"S_TRIPWIREBOOST_BLAST_BOTTOM",
"S_SMOOTHLANDING",
// DEZ respawn laser
"S_DEZLASER",
"S_DEZLASER_TRAIL1",
@ -5383,6 +5385,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_TRIPWIREBOOST",
"MT_SMOOTHLANDING",
"MT_DEZLASER",
"MT_WAYPOINT",

View file

@ -588,6 +588,7 @@ char sprnames[NUMSPRITES + 1][5] =
"BEXB", // Battle Bumper Explosion: Blast
"TWBS", // Tripwire Boost
"TWBT", // Tripwire BLASTER
"SMLD", // Smooth landing
"DEZL", // DEZ Laser respawn
// Additional Kart Objects
@ -4397,6 +4398,8 @@ state_t states[NUMSTATES] =
{SPR_TWBT, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 6, 2, S_NULL}, // S_TRIPWIREBOOST_BLAST_TOP
{SPR_TWBT, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|FF_VERTICALFLIP|FF_HORIZONTALFLIP, -1, {NULL}, 6, 2, S_NULL}, // S_TRIPWIREBOOST_BLAST_BOTTOM
{SPR_SMLD, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_SMOOTHLANDING
{SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER
{SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1
{SPR_DEZL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL3}, // S_DEZLASER_TRAIL2
@ -24470,6 +24473,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_SMOOTHLANDING
-1, // doomednum
S_SMOOTHLANDING, // 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
8*FRACUNIT, // radius
16*FRACUNIT, // height
-1, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_DEZLASER
-1, // doomednum
S_DEZLASER, // spawnstate

View file

@ -1136,6 +1136,7 @@ typedef enum sprite
SPR_BEXB, // Battle Bumper Explosion: Blast
SPR_TWBS, // Tripwire Boost
SPR_TWBT, // Tripwire BLASTER
SPR_SMLD, // Smooth landing
SPR_DEZL, // DEZ Laser respawn
// Additional Kart Objects
@ -4833,6 +4834,8 @@ typedef enum state
S_TRIPWIREBOOST_BLAST_TOP,
S_TRIPWIREBOOST_BLAST_BOTTOM,
S_SMOOTHLANDING,
// DEZ Laser respawn
S_DEZLASER,
S_DEZLASER_TRAIL1,
@ -6416,6 +6419,8 @@ typedef enum mobj_type
MT_TRIPWIREBOOST,
MT_SMOOTHLANDING,
MT_DEZLASER,
MT_WAYPOINT,

View file

@ -952,6 +952,55 @@ static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController)
}
}
/*--------------------------------------------------
static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle)
Calculates a new destination angle while in the air,
to be able to successfully smooth land.
Input Arguments:-
player - Bot player to check.
destangle - Previous destination angle.
Return:-
New destination angle.
--------------------------------------------------*/
static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle)
{
angle_t newAngle = destangle;
boolean air = !P_IsObjectOnGround(player->mo);
angle_t steepVal = air ? STUMBLE_STEEP_VAL_AIR : STUMBLE_STEEP_VAL;
angle_t slopeSteep = max(AngleDelta(player->mo->pitch, 0), AngleDelta(player->mo->roll, 0));
if (slopeSteep > steepVal)
{
fixed_t pitchMul = -FINESINE(destangle >> ANGLETOFINESHIFT);
fixed_t rollMul = FINECOSINE(destangle >> ANGLETOFINESHIFT);
angle_t testAngles[2];
angle_t testDeltas[2];
UINT8 i;
testAngles[0] = R_PointToAngle2(0, 0, rollMul, pitchMul);
testAngles[1] = R_PointToAngle2(0, 0, -rollMul, -pitchMul);
for (i = 0; i < 2; i++)
{
testDeltas[i] = AngleDelta(testAngles[i], destangle);
}
if (testDeltas[1] < testDeltas[0])
{
return testAngles[1];
}
else
{
return testAngles[0];
}
}
return newAngle;
}
/*--------------------------------------------------
static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *predict)
@ -975,6 +1024,8 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
I_Assert(predict != NULL);
destangle = K_BotSmoothLanding(player, destangle);
moveangle = player->mo->angle;
anglediff = AngleDeltaSigned(moveangle, destangle);
@ -1105,6 +1156,8 @@ static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t
}
}
destangle = K_BotSmoothLanding(player, destangle);
// Calculate turn direction first.
moveangle = player->mo->angle;
angle = (moveangle - destangle);

View file

@ -19,6 +19,7 @@
#include "p_setup.h"
#include "r_draw.h"
#include "r_local.h"
#include "r_things.c"
#include "s_sound.h"
#include "st_stuff.h"
#include "v_video.h"
@ -3797,6 +3798,234 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
P_StartQuake(64<<FRACBITS, 10);
}
angle_t K_StumbleSlope(angle_t angle, angle_t pitch, angle_t roll)
{
fixed_t pitchMul = -FINESINE(angle >> ANGLETOFINESHIFT);
fixed_t rollMul = FINECOSINE(angle >> ANGLETOFINESHIFT);
angle_t slope = FixedMul(pitch, pitchMul) + FixedMul(roll, rollMul);
if (slope > ANGLE_180)
{
slope = InvAngle(slope);
}
return slope;
}
boolean K_CheckStumble(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;
// If you don't land upright on a slope, then you tumble,
// kinda like Kirby Air Ride
if (player->tumbleBounces)
{
// Already tumbling.
return false;
}
if ((player->mo->pitch == oldPitch)
&& (player->mo->roll == oldRoll))
{
// No change.
return false;
}
if (fromAir == true)
{
steepVal = STUMBLE_STEEP_VAL_AIR;
}
else
{
steepVal = STUMBLE_STEEP_VAL;
}
oldSlope = K_StumbleSlope(player->mo->angle, oldPitch, oldRoll);
if (oldSlope <= steepVal)
{
// Transferring from flat ground to a steep slope
// is a free action. (The other way around isn't, though.)
return false;
}
newSlope = K_StumbleSlope(player->mo->angle, player->mo->pitch, player->mo->roll);
slopeDelta = AngleDelta(oldSlope, newSlope);
if (slopeDelta <= steepVal)
{
// Needs to be VERY steep before we'll punish this.
return false;
}
// Oh jeez, you landed on your side.
// You get to tumble.
P_ResetPlayer(player);
#if 0
// Single, medium bounce
player->tumbleBounces = TUMBLEBOUNCES;
player->tumbleHeight = 30;
#else
// Two small bounces
player->tumbleBounces = TUMBLEBOUNCES-1;
player->tumbleHeight = 20;
#endif
player->pflags &= ~PF_TUMBLESOUND;
S_StartSound(player->mo, sfx_s3k9b);
gravityadjust = P_GetMobjGravity(player->mo)/2; // so we'll halve it for our calculations.
if (player->mo->eflags & MFE_UNDERWATER)
gravityadjust /= 2; // halve "gravity" underwater
// and then modulate momz like that...
player->mo->momz = -gravityadjust * player->tumbleHeight;
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
if (P_IsDisplayPlayer(player))
P_StartQuake(64<<FRACBITS, 10);
// Reset slope.
player->mo->pitch = player->mo->roll = 0;
return true;
}
void K_InitStumbleIndicator(player_t *player)
{
mobj_t *new = NULL;
if (player == NULL)
{
return;
}
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
{
return;
}
if (player->stumbleIndicator != NULL && P_MobjWasRemoved(player->stumbleIndicator) == false)
{
P_RemoveMobj(player->stumbleIndicator);
}
new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SMOOTHLANDING);
P_SetTarget(&player->stumbleIndicator, new);
P_SetTarget(&new->target, player->mo);
}
void K_UpdateStumbleIndicator(player_t *player)
{
const angle_t fudge = ANG15;
mobj_t *mobj = NULL;
boolean air = false;
angle_t steepVal = STUMBLE_STEEP_VAL;
angle_t slopeSteep = 0;
angle_t steepRange = ANGLE_90;
INT32 delta = 0;
INT32 trans = 0;
if (player == NULL)
{
return;
}
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
{
return;
}
if (player->stumbleIndicator == NULL || P_MobjWasRemoved(player->stumbleIndicator) == true)
{
K_InitStumbleIndicator(player);
return;
}
mobj = player->stumbleIndicator;
P_MoveOrigin(mobj, player->mo->x, player->mo->y, player->mo->z + (player->mo->height / 2));
air = !P_IsObjectOnGround(player->mo);
steepVal = (air ? STUMBLE_STEEP_VAL_AIR : STUMBLE_STEEP_VAL) - fudge;
slopeSteep = max(AngleDelta(player->mo->pitch, 0), AngleDelta(player->mo->roll, 0));
delta = 0;
if (slopeSteep > steepVal)
{
angle_t testAngles[2];
INT32 testDeltas[2];
UINT8 i;
testAngles[0] = R_PointToAngle2(0, 0, player->mo->pitch, player->mo->roll);
testAngles[1] = R_PointToAngle2(0, 0, -player->mo->pitch, -player->mo->roll);
for (i = 0; i < 2; i++)
{
testDeltas[i] = AngleDeltaSigned(player->mo->angle, testAngles[i]);
}
if (abs(testDeltas[1]) < abs(testDeltas[0]))
{
delta = testDeltas[1];
}
else
{
delta = testDeltas[0];
}
}
if (delta < 0)
{
mobj->renderflags |= RF_HORIZONTALFLIP;
}
else
{
mobj->renderflags &= ~RF_HORIZONTALFLIP;
}
steepRange = ANGLE_90 - steepVal;
delta = max(0, abs(delta) - ((signed)steepVal));
trans = ((FixedDiv(AngleFixed(delta), AngleFixed(steepRange)) * (NUMTRANSMAPS - 2)) + (FRACUNIT/2)) / FRACUNIT;
if (trans < 0)
{
trans = 0;
}
if (trans > (NUMTRANSMAPS - 2))
{
trans = (NUMTRANSMAPS - 2);
}
// invert
trans = (NUMTRANSMAPS - 2) - trans;
mobj->renderflags |= RF_DONTDRAW;
if (trans < (NUMTRANSMAPS - 2))
{
mobj->renderflags &= ~(RF_TRANSMASK | K_GetPlayerDontDrawFlag(player));
if (trans != 0)
{
mobj->renderflags |= (trans << RF_TRANSSHIFT);
}
}
}
static boolean K_LastTumbleBounceCondition(player_t *player)
{
return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60);
@ -3831,6 +4060,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
}
}
@ -7899,6 +8129,8 @@ void K_KartPlayerAfterThink(player_t *player)
{
K_KartResetPlayerColor(player);
K_UpdateStumbleIndicator(player);
// Move held objects (Bananas, Orbinaut, etc)
K_MoveHeldObjects(player);
@ -9340,31 +9572,7 @@ static void K_KartSpindash(player_t *player)
}
else if (player->fastfall != 0)
{
// Handle fastfall bounce.
const fixed_t maxBounce = player->mo->scale * 10;
const fixed_t minBounce = player->mo->scale;
fixed_t bounce = 2 * abs(player->fastfall) / 3;
if (bounce > maxBounce)
{
bounce = maxBounce;
}
else
{
// Lose speed on bad bounce.
player->mo->momx /= 2;
player->mo->momy /= 2;
if (bounce < minBounce)
{
bounce = minBounce;
}
}
S_StartSound(player->mo, sfx_ffbonc);
player->mo->momz = bounce * P_MobjFlip(player->mo);
player->fastfall = 0;
// Still handling fast-fall bounce.
return;
}
@ -9431,6 +9639,41 @@ static void K_KartSpindash(player_t *player)
#undef SPINDASHTHRUSTTIME
boolean K_FastFallBounce(player_t *player)
{
// Handle fastfall bounce.
if (player->fastfall != 0)
{
const fixed_t maxBounce = player->mo->scale * 10;
const fixed_t minBounce = player->mo->scale;
fixed_t bounce = 2 * abs(player->fastfall) / 3;
if (bounce > maxBounce)
{
bounce = maxBounce;
}
else
{
// Lose speed on bad bounce.
player->mo->momx /= 2;
player->mo->momy /= 2;
if (bounce < minBounce)
{
bounce = minBounce;
}
}
S_StartSound(player->mo, sfx_ffbonc);
player->mo->momz = bounce * P_MobjFlip(player->mo);
player->fastfall = 0;
return true;
}
return false;
}
static void K_AirFailsafe(player_t *player)
{
const fixed_t maxSpeed = 6*player->mo->scale;

View file

@ -28,6 +28,9 @@ Make sure this matches the actual number of states
#define GROW_PHYSICS_SCALE (3*FRACUNIT/2)
#define SHRINK_PHYSICS_SCALE (3*FRACUNIT/4)
#define STUMBLE_STEEP_VAL ANG60
#define STUMBLE_STEEP_VAL_AIR (ANG30 + ANG10)
player_t *K_GetItemBoxPlayer(mobj_t *mobj);
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
@ -75,6 +78,10 @@ void K_RemoveGrowShrink(player_t *player);
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_TumbleInterrupt(player_t *player);
angle_t K_StumbleSlope(angle_t angle, angle_t pitch, angle_t roll);
boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir);
void K_InitStumbleIndicator(player_t *player);
void K_UpdateStumbleIndicator(player_t *player);
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);
@ -142,6 +149,7 @@ fixed_t K_GetNewSpeed(player_t *player);
fixed_t K_3dKartMovement(player_t *player);
boolean K_PlayerEBrake(player_t *player);
SINT8 K_Sliptiding(player_t *player);
boolean K_FastFallBounce(player_t *player);
void K_AdjustPlayerFriction(player_t *player);
void K_MoveKartPlayer(player_t *player, boolean onground);
void K_CheckSpectateStatus(void);

View file

@ -172,7 +172,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart
#define P_IsObjectFlipped(o) ((o)->eflags & MFE_VERTICALFLIP)
boolean P_InQuicksand(mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player, boolean fromAir);
boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, angle_t oldRoll);
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
void P_RestoreMusic(player_t *player);

View file

@ -2801,12 +2801,15 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->momz <= 0)
{
angle_t oldPitch = thing->pitch;
angle_t oldRoll = thing->roll;
thing->standingslope = tmfloorslope;
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
if (thing->player)
{
P_PlayerHitFloor(thing->player, true);
P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll);
}
}
}
@ -2821,12 +2824,15 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->momz >= 0)
{
angle_t oldPitch = thing->pitch;
angle_t oldRoll = thing->roll;
thing->standingslope = tmceilingslope;
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
if (thing->player)
{
P_PlayerHitFloor(thing->player, true);
P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll);
}
}
}
@ -3117,7 +3123,7 @@ static boolean P_ThingHeightClip(mobj_t *thing)
}
if ((P_MobjFlip(thing)*(thing->z - oldz) > 0 || hitfloor) && thing->player)
P_PlayerHitFloor(thing->player, !onfloor);
P_PlayerHitFloor(thing->player, !onfloor, thing->pitch, thing->roll);
// debug: be sure it falls to the floor
thing->eflags &= ~MFE_ONGROUND;

View file

@ -1534,12 +1534,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;
@ -1771,7 +1777,9 @@ 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)
{
@ -2727,6 +2735,7 @@ static boolean P_PlayerPolyObjectZMovement(mobj_t *mo)
void P_PlayerZMovement(mobj_t *mo)
{
boolean onground;
angle_t oldPitch, oldRoll;
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
@ -2734,6 +2743,9 @@ void P_PlayerZMovement(mobj_t *mo)
if (!mo->player)
return;
oldPitch = mo->pitch;
oldRoll = mo->roll;
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
@ -2810,7 +2822,7 @@ void P_PlayerZMovement(mobj_t *mo)
mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement.
mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack
clipmomz = P_PlayerHitFloor(mo->player, true);
clipmomz = P_PlayerHitFloor(mo->player, true, oldPitch, oldRoll);
P_PlayerPolyObjectZMovement(mo);
if (clipmomz)
@ -2846,6 +2858,47 @@ void P_PlayerZMovement(mobj_t *mo)
mo->eflags &= ~MFE_JUSTHITFLOOR;
P_CheckGravity(mo, true);
}
// Even out pitch & roll slowly over time when respawning.
if (mo->player->respawn.state != RESPAWNST_NONE)
{
const angle_t speed = ANG2; //FixedMul(ANG2, abs(mo->momz) / 8);
angle_t dest = 0;
INT32 pitchDelta = AngleDeltaSigned(mo->pitch, 0);
INT32 rollDelta = AngleDeltaSigned(mo->roll, 0);
if (abs(pitchDelta) <= speed && dest == 0)
{
mo->pitch = 0;
}
else if (abs(pitchDelta) > dest)
{
if (pitchDelta > 0)
{
mo->pitch -= speed;
}
else
{
mo->pitch += speed;
}
}
if (abs(rollDelta) <= speed && dest == 0)
{
mo->roll = 0;
}
else if (abs(rollDelta) > dest)
{
if (rollDelta > 0)
{
mo->roll -= speed;
}
else
{
mo->roll += speed;
}
}
}
}
if (((mo->eflags & MFE_VERTICALFLIP && mo->z < mo->floorz) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height > mo->ceilingz))
@ -11333,6 +11386,8 @@ void P_SpawnPlayer(INT32 playernum)
P_SetScale(mobj, mobj->destscale);
P_FlashPal(p, 0, 0); // Resets
K_InitStumbleIndicator(p);
if (gametyperules & GTR_BUMPERS)
{
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW);

View file

@ -64,6 +64,7 @@ typedef enum
SKYBOXVIEW = 0x08,
SKYBOXCENTER = 0x10,
HOVERHYUDORO = 0x20,
STUMBLE = 0x40,
} player_saveflags;
static inline void P_ArchivePlayer(void)
@ -202,6 +203,9 @@ static void P_NetArchivePlayers(void)
if (players[i].hoverhyudoro)
flags |= HOVERHYUDORO;
if (players[i].stumbleIndicator)
flags |= STUMBLE;
WRITEUINT16(save_p, flags);
if (flags & SKYBOXVIEW)
@ -219,6 +223,9 @@ static void P_NetArchivePlayers(void)
if (flags & HOVERHYUDORO)
WRITEUINT32(save_p, players[i].hoverhyudoro->mobjnum);
if (flags & STUMBLE)
WRITEUINT32(save_p, players[i].stumbleIndicator->mobjnum);
WRITEUINT32(save_p, (UINT32)players[i].followitem);
WRITEUINT32(save_p, players[i].charflags);
@ -509,6 +516,9 @@ static void P_NetUnArchivePlayers(void)
if (flags & HOVERHYUDORO)
players[i].hoverhyudoro = (mobj_t *)(size_t)READUINT32(save_p);
if (flags & STUMBLE)
players[i].stumbleIndicator = (mobj_t *)(size_t)READUINT32(save_p);
players[i].followitem = (mobjtype_t)READUINT32(save_p);
//SetPlayerSkinByNum(i, players[i].skin);
@ -4289,6 +4299,13 @@ static void P_RelinkPointers(void)
if (!P_SetTarget(&mobj->player->hoverhyudoro, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "hoverhyudoro not found on %d\n", mobj->type);
}
if (mobj->player->stumbleIndicator)
{
temp = (UINT32)(size_t)mobj->player->stumbleIndicator;
mobj->player->stumbleIndicator = NULL;
if (!P_SetTarget(&mobj->player->stumbleIndicator, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "stumbleIndicator not found on %d\n", mobj->type);
}
}
}
}

View file

@ -1339,7 +1339,7 @@ void P_DoPlayerExit(player_t *player)
//
// Handles player hitting floor surface.
// Returns whether to clip momz.
boolean P_PlayerHitFloor(player_t *player, boolean fromAir)
boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, angle_t oldRoll)
{
boolean clipmomz;
@ -1347,9 +1347,32 @@ boolean P_PlayerHitFloor(player_t *player, boolean fromAir)
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 > 0)
{
boolean air = fromAir;
if (P_IsObjectOnGround(player->mo) && (player->mo->eflags & MFE_JUSTHITFLOOR))
{
air = true;
}
if (K_CheckStumble(player, oldPitch, oldRoll, air) == true)
{
return false;
}
if (air == false && K_FastFallBounce(player) == true)
{
return false;
}
}
}
return clipmomz;
@ -1662,7 +1685,7 @@ static void P_CheckQuicksand(player_t *player)
player->mo->z = ceilingheight - player->mo->height;
if (player->mo->momz <= 0)
P_PlayerHitFloor(player, false);
P_PlayerHitFloor(player, false, player->mo->roll, player->mo->pitch);
}
else
{
@ -1674,7 +1697,7 @@ static void P_CheckQuicksand(player_t *player)
player->mo->z = floorheight;
if (player->mo->momz >= 0)
P_PlayerHitFloor(player, false);
P_PlayerHitFloor(player, false, player->mo->roll, player->mo->pitch);
}
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;