Polish player corpse physics

- Flung a little higher into the air
- Takes momentum of whatever killed the player
- Bounces off walls
- Bounces off the floor once
- After bouncing off the floor once, corpse noclips
  through walls and floors
This commit is contained in:
James R 2024-01-21 20:02:17 -08:00
parent 255552d141
commit 6b27a656e8
3 changed files with 31 additions and 5 deletions

View file

@ -1764,7 +1764,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->flags &= ~(MF_SOLID|MF_SHOOTABLE); // does not block
P_UnsetThingPosition(target);
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
target->flags |= MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOGRAVITY;
P_SetThingPosition(target);
target->standingslope = NULL;
target->terrain = NULL;
@ -1967,6 +1967,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
case MT_PLAYER:
if (damagetype != DMG_SPECTATOR)
{
fixed_t flingSpeed = FixedHypot(target->momx, target->momy);
angle_t flingAngle;
mobj_t *kart;
@ -2019,8 +2020,18 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
// so make sure that this draws at the correct angle.
target->rollangle = 0;
P_InstaThrust(target, flingAngle, 14 * target->scale);
P_SetObjectMomZ(target, 14*FRACUNIT, false);
fixed_t inflictorSpeed = 0;
if (!P_MobjWasRemoved(inflictor))
{
inflictorSpeed = FixedHypot(inflictor->momx, inflictor->momy);
if (inflictorSpeed > flingSpeed)
{
flingSpeed = inflictorSpeed;
}
}
P_InstaThrust(target, flingAngle, max(flingSpeed, 14 * target->scale));
P_SetObjectMomZ(target, 20*FRACUNIT, false);
P_PlayDeathSound(target);
}

View file

@ -4140,7 +4140,12 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result)
);
}
if (mo->eflags & MFE_JUSTBOUNCEDWALL) // Stronger push-out
if (mo->health <= 0)
{
tmxmove = mo->momx;
tmymove = mo->momy;
}
else if (mo->eflags & MFE_JUSTBOUNCEDWALL) // Stronger push-out
{
tmxmove = mmomx;
tmymove = mmomy;
@ -4177,6 +4182,11 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result)
mo->player->cmomx = tmxmove;
mo->player->cmomy = tmymove;
if (mo->health <= 0)
{
mo->momz = 16 * mapobjectscale;
}
if (!bestslideline || !P_IsLineTripWire(bestslideline))
{
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true, NULL))

View file

@ -1969,7 +1969,7 @@ void P_XYMovement(mobj_t *mo)
return;
//}
if (((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz))
if (((!(mo->eflags & MFE_VERTICALFLIP) && (mo->momz > 0 || mo->z > mo->floorz)) || (mo->eflags & MFE_VERTICALFLIP && (mo->momz < 0 || mo->z+mo->height < mo->ceilingz)))
&& !(player && player->carry == CR_SLIDING))
return; // no friction when airborne
@ -2501,6 +2501,11 @@ boolean P_ZMovement(mobj_t *mo)
mom.x = mom.y = 0;
mom.z = -mom.z/2;
}
else if (mo->type == MT_PLAYER) // only DEAD players
{
mom.z = -mom.z;
mo->flags |= MF_NOCLIP | MF_NOCLIPHEIGHT; // fall through floor next time
}
else if (mo->flags & MF_MISSILE)
{
if (!(mo->flags & MF_NOCLIP))