Add half hitlag to invincible players if they would've been damaged

This commit is contained in:
James R 2022-12-16 23:49:05 -08:00
parent b73bbd3712
commit ba2a7744d1
6 changed files with 57 additions and 3 deletions

View file

@ -403,6 +403,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
{ {
// Melt item // Melt item
S_StartSound(t2, sfx_s3k43); S_StartSound(t2, sfx_s3k43);
K_SetHitLagForObjects(t2, t1, 3, false);
} }
else else
{ {

View file

@ -7983,6 +7983,32 @@ void K_KartPlayerAfterThink(player_t *player)
{ {
K_LookForRings(player->mo); K_LookForRings(player->mo);
} }
if (player->invulnhitlag > 0)
{
// Hitlag from what would normally be damage but the
// player was invulnerable.
//
// If we're constantly getting hit the same number of
// times, we're probably standing on a damage floor.
//
// Checking if we're hit more than before ensures
// that:
//
// 1) repeating damage doesn't count
// 2) new damage sources still count
if (player->timeshit <= player->timeshitprev)
{
if (!P_MobjWasRemoved(player->mo))
{
player->mo->hitlag -= player->invulnhitlag;
player->mo->eflags &= ~(MFE_DAMAGEHITLAG);
}
}
player->invulnhitlag = 0;
}
} }
/*-------------------------------------------------- /*--------------------------------------------------

View file

@ -2015,7 +2015,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!(target->flags & MF_SHOOTABLE)) if (!(target->flags & MF_SHOOTABLE))
return false; // shouldn't happen... return false; // shouldn't happen...
if (!(damagetype & DMG_DEATHMASK) && target->hitlag > 0 && inflictor == NULL) if (!(damagetype & DMG_DEATHMASK) && (target->eflags & MFE_PAUSED))
return false; return false;
} }
@ -2038,6 +2038,18 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player) // Player is the target if (player) // Player is the target
{ {
{
const INT32 oldtimeshit = player->timeshit;
player->timeshit++;
// overflow prevention
if (player->timeshit < oldtimeshit)
{
player->timeshit = oldtimeshit;
}
}
if (player->pflags & PF_GODMODE) if (player->pflags & PF_GODMODE)
return false; return false;
@ -2092,6 +2104,13 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player->invincibilitytimer > 0 || K_IsBigger(target, inflictor) == true || player->hyudorotimer > 0) if (player->invincibilitytimer > 0 || K_IsBigger(target, inflictor) == true || player->hyudorotimer > 0)
{ {
const INT32 oldhitlag = target->hitlag;
laglength = max(laglength / 2, 1);
K_SetHitLagForObjects(target, inflictor, laglength, false);
player->invulnhitlag += (target->hitlag - oldhitlag);
// Full invulnerability // Full invulnerability
K_DoInstashield(player); K_DoInstashield(player);
return false; return false;

View file

@ -9665,6 +9665,7 @@ void P_MobjThinker(mobj_t *mobj)
// Don't run any thinker code while in hitlag // Don't run any thinker code while in hitlag
if (mobj->hitlag > 0) if (mobj->hitlag > 0)
{ {
mobj->eflags |= MFE_PAUSED;
mobj->hitlag--; mobj->hitlag--;
if (mobj->type == MT_DROPTARGET && mobj->reactiontime > 0 && mobj->hitlag == 2) if (mobj->type == MT_DROPTARGET && mobj->reactiontime > 0 && mobj->hitlag == 2)
@ -9684,7 +9685,7 @@ void P_MobjThinker(mobj_t *mobj)
return; return;
} }
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG|MFE_SLOPELAUNCHED); mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG|MFE_SLOPELAUNCHED|MFE_PAUSED);
// sal: what the hell? is there any reason this isn't done, like, literally ANYWHERE else? // sal: what the hell? is there any reason this isn't done, like, literally ANYWHERE else?
P_SetTarget(&tm.floorthing, NULL); P_SetTarget(&tm.floorthing, NULL);

View file

@ -255,7 +255,8 @@ typedef enum
MFE_DAMAGEHITLAG = 1<<13, MFE_DAMAGEHITLAG = 1<<13,
// Slope physics sent you airborne // Slope physics sent you airborne
MFE_SLOPELAUNCHED = 1<<14, MFE_SLOPELAUNCHED = 1<<14,
// free: to and including 1<<15 // Thinker is paused due to hitlag
MFE_PAUSED = 1<<15,
} mobjeflag_t; } mobjeflag_t;
// //

View file

@ -4341,6 +4341,12 @@ void P_PlayerAfterThink(player_t *player)
// so a lag value of 1 is exactly attached to the player. // so a lag value of 1 is exactly attached to the player.
K_HandleFollower(player); K_HandleFollower(player);
if (P_MobjWasRemoved(player->mo) || (player->mo->eflags & MFE_PAUSED) == 0)
{
player->timeshitprev = player->timeshit;
player->timeshit = 0;
}
if (K_PlayerUsesBotMovement(player)) if (K_PlayerUsesBotMovement(player))
{ {