mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'neutral-explosion-hitlag' into 'master'
Add half hitlag to invulnerable players if they would normally take damage Closes #364 See merge request KartKrew/Kart!814
This commit is contained in:
commit
1662414e0e
11 changed files with 129 additions and 9 deletions
|
|
@ -466,6 +466,7 @@ struct player_t
|
|||
UINT16 spinouttimer; // Spin-out from a banana peel or oil slick (was "pw_bananacam")
|
||||
UINT8 spinouttype; // Determines the mode of spinout/wipeout, see kartspinoutflags_t
|
||||
UINT8 instashield; // Instashield no-damage animation timer
|
||||
INT32 invulnhitlag; // Numbers of tics of hitlag added this tic for "potential" damage -- not real damage
|
||||
UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out
|
||||
UINT8 justbumped; // Prevent players from endlessly bumping into each other
|
||||
UINT8 tumbleBounces;
|
||||
|
|
@ -615,7 +616,12 @@ struct player_t
|
|||
|
||||
INT16 lastsidehit, lastlinehit;
|
||||
|
||||
//UINT8 timeshit; // That's TIMES HIT, not TIME SHIT, you doofus! -- in memoriam
|
||||
// These track how many things tried to damage you, not
|
||||
// whether you actually took damage.
|
||||
UINT8 timeshit; // times hit this tic
|
||||
UINT8 timeshitprev; // times hit before
|
||||
// That's TIMES HIT, not TIME SHIT, you doofus! -- in memoriam
|
||||
// No longer in memoriam =P -jart
|
||||
|
||||
INT32 onconveyor; // You are on a conveyor belt if nonzero
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
|||
static mobj_t *grenade;
|
||||
static fixed_t explodedist;
|
||||
static boolean explodespin;
|
||||
static tic_t minehitlag;
|
||||
static INT32 minehitlag;
|
||||
|
||||
static inline boolean PIT_SSMineChecks(mobj_t *thing)
|
||||
{
|
||||
|
|
@ -272,6 +272,9 @@ void K_DoMineSearch(mobj_t *actor, fixed_t size)
|
|||
|
||||
static inline BlockItReturn_t PIT_SSMineExplode(mobj_t *thing)
|
||||
{
|
||||
const INT32 oldhitlag = thing->hitlag;
|
||||
INT32 lagadded;
|
||||
|
||||
if (grenade == NULL || P_MobjWasRemoved(grenade))
|
||||
return BMIT_ABORT; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot
|
||||
|
||||
|
|
@ -283,9 +286,13 @@ static inline BlockItReturn_t PIT_SSMineExplode(mobj_t *thing)
|
|||
if (PIT_SSMineChecks(thing) == true)
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE)))
|
||||
P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE));
|
||||
|
||||
lagadded = (thing->hitlag - oldhitlag);
|
||||
|
||||
if (lagadded > 0)
|
||||
{
|
||||
minehitlag = thing->hitlag;
|
||||
minehitlag = lagadded;
|
||||
}
|
||||
|
||||
return BMIT_CONTINUE;
|
||||
|
|
@ -392,6 +399,8 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
if (t2->player)
|
||||
{
|
||||
const INT32 oldhitlag = t2->hitlag;
|
||||
|
||||
if (t2->player->flashing)
|
||||
return true;
|
||||
|
||||
|
|
@ -403,6 +412,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
|||
{
|
||||
// Melt item
|
||||
S_StartSound(t2, sfx_s3k43);
|
||||
K_SetHitLagForObjects(t2, t1, 3, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -410,7 +420,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
|||
P_DamageMobj(t2, t1, t1->target, 1, DMG_TUMBLE);
|
||||
}
|
||||
|
||||
t1->reactiontime = t2->hitlag;
|
||||
t1->reactiontime = (t2->hitlag - oldhitlag);
|
||||
P_KillMobj(t1, t2, t2, DMG_NORMAL);
|
||||
}
|
||||
else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|
||||
|
|
|
|||
26
src/k_kart.c
26
src/k_kart.c
|
|
@ -7983,6 +7983,32 @@ void K_KartPlayerAfterThink(player_t *player)
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -232,6 +232,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->spinouttimer);
|
||||
else if (fastcmp(field,"instashield"))
|
||||
lua_pushinteger(L, plr->instashield);
|
||||
else if (fastcmp(field,"invulnhitlag"))
|
||||
lua_pushinteger(L, plr->invulnhitlag);
|
||||
else if (fastcmp(field,"wipeoutslow"))
|
||||
lua_pushinteger(L, plr->wipeoutslow);
|
||||
else if (fastcmp(field,"justbumped"))
|
||||
|
|
@ -472,6 +474,10 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->lastsidehit);
|
||||
else if (fastcmp(field,"lastlinehit"))
|
||||
lua_pushinteger(L, plr->lastlinehit);
|
||||
else if (fastcmp(field,"timeshit"))
|
||||
lua_pushinteger(L, plr->timeshit);
|
||||
else if (fastcmp(field,"timeshitprev"))
|
||||
lua_pushinteger(L, plr->timeshitprev);
|
||||
else if (fastcmp(field,"onconveyor"))
|
||||
lua_pushinteger(L, plr->onconveyor);
|
||||
else if (fastcmp(field,"awayviewmobj"))
|
||||
|
|
@ -604,6 +610,8 @@ static int player_set(lua_State *L)
|
|||
plr->spinouttimer = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"instashield"))
|
||||
plr->instashield = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"invulnhitlag"))
|
||||
plr->invulnhitlag = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"wipeoutslow"))
|
||||
plr->wipeoutslow = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"justbumped"))
|
||||
|
|
@ -830,6 +838,10 @@ static int player_set(lua_State *L)
|
|||
plr->lastsidehit = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"lastlinehit"))
|
||||
plr->lastlinehit = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"timeshit"))
|
||||
plr->timeshit = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"timeshitprev"))
|
||||
plr->timeshitprev = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"onconveyor"))
|
||||
plr->onconveyor = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"awayviewmobj"))
|
||||
|
|
|
|||
|
|
@ -2015,7 +2015,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
if (!(target->flags & MF_SHOOTABLE))
|
||||
return false; // shouldn't happen...
|
||||
|
||||
if (!(damagetype & DMG_DEATHMASK) && target->hitlag > 0 && inflictor == NULL)
|
||||
if (!(damagetype & DMG_DEATHMASK) && (target->eflags & MFE_PAUSED))
|
||||
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
|
||||
{
|
||||
{
|
||||
const INT32 oldtimeshit = player->timeshit;
|
||||
|
||||
player->timeshit++;
|
||||
|
||||
// overflow prevention
|
||||
if (player->timeshit < oldtimeshit)
|
||||
{
|
||||
player->timeshit = oldtimeshit;
|
||||
}
|
||||
}
|
||||
|
||||
if (player->pflags & PF_GODMODE)
|
||||
return false;
|
||||
|
||||
|
|
@ -2071,6 +2083,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
// If not, then spawn the instashield effect instead.
|
||||
if (!force)
|
||||
{
|
||||
boolean invincible = true;
|
||||
sfxenum_t sfx = sfx_None;
|
||||
|
||||
if (gametyperules & GTR_BUMPERS)
|
||||
{
|
||||
if (player->bumpers <= 0 && player->karmadelay)
|
||||
|
|
@ -2090,8 +2105,35 @@ 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)
|
||||
{
|
||||
sfx= sfx_invind;
|
||||
}
|
||||
else if (K_IsBigger(target, inflictor) == true)
|
||||
{
|
||||
sfx = sfx_grownd;
|
||||
}
|
||||
else if (player->hyudorotimer > 0)
|
||||
;
|
||||
else
|
||||
{
|
||||
invincible = false;
|
||||
}
|
||||
|
||||
if (invincible)
|
||||
{
|
||||
const INT32 oldhitlag = target->hitlag;
|
||||
|
||||
laglength = max(laglength / 2, 1);
|
||||
K_SetHitLagForObjects(target, inflictor, laglength, false);
|
||||
|
||||
player->invulnhitlag += (target->hitlag - oldhitlag);
|
||||
|
||||
if (player->timeshit > player->timeshitprev)
|
||||
{
|
||||
S_StartSound(target, sfx);
|
||||
}
|
||||
|
||||
// Full invulnerability
|
||||
K_DoInstashield(player);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -9665,6 +9665,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
// Don't run any thinker code while in hitlag
|
||||
if (mobj->hitlag > 0)
|
||||
{
|
||||
mobj->eflags |= MFE_PAUSED;
|
||||
mobj->hitlag--;
|
||||
|
||||
if (mobj->type == MT_DROPTARGET && mobj->reactiontime > 0 && mobj->hitlag == 2)
|
||||
|
|
@ -9684,7 +9685,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
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?
|
||||
P_SetTarget(&tm.floorthing, NULL);
|
||||
|
|
|
|||
|
|
@ -255,7 +255,8 @@ typedef enum
|
|||
MFE_DAMAGEHITLAG = 1<<13,
|
||||
// Slope physics sent you airborne
|
||||
MFE_SLOPELAUNCHED = 1<<14,
|
||||
// free: to and including 1<<15
|
||||
// Thinker is paused due to hitlag
|
||||
MFE_PAUSED = 1<<15,
|
||||
} mobjeflag_t;
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -190,6 +190,9 @@ static void P_NetArchivePlayers(void)
|
|||
|
||||
WRITEINT32(save_p, players[i].onconveyor);
|
||||
|
||||
WRITEUINT8(save_p, players[i].timeshit);
|
||||
WRITEUINT8(save_p, players[i].timeshitprev);
|
||||
|
||||
WRITEUINT32(save_p, players[i].jointime);
|
||||
|
||||
WRITEUINT8(save_p, players[i].splitscreenindex);
|
||||
|
|
@ -266,6 +269,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEUINT16(save_p, players[i].spinouttimer);
|
||||
WRITEUINT8(save_p, players[i].spinouttype);
|
||||
WRITEUINT8(save_p, players[i].instashield);
|
||||
WRITEINT32(save_p, players[i].invulnhitlag);
|
||||
WRITEUINT8(save_p, players[i].wipeoutslow);
|
||||
WRITEUINT8(save_p, players[i].justbumped);
|
||||
WRITEUINT8(save_p, players[i].tumbleBounces);
|
||||
|
|
@ -557,6 +561,9 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].lastsidehit = READINT16(save_p);
|
||||
players[i].lastlinehit = READINT16(save_p);
|
||||
|
||||
players[i].timeshit = READUINT8(save_p);
|
||||
players[i].timeshitprev = READUINT8(save_p);
|
||||
|
||||
players[i].onconveyor = READINT32(save_p);
|
||||
|
||||
players[i].jointime = READUINT32(save_p);
|
||||
|
|
@ -615,6 +622,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].spinouttimer = READUINT16(save_p);
|
||||
players[i].spinouttype = READUINT8(save_p);
|
||||
players[i].instashield = READUINT8(save_p);
|
||||
players[i].invulnhitlag = READINT32(save_p);
|
||||
players[i].wipeoutslow = READUINT8(save_p);
|
||||
players[i].justbumped = READUINT8(save_p);
|
||||
players[i].tumbleBounces = READUINT8(save_p);
|
||||
|
|
|
|||
|
|
@ -4341,6 +4341,12 @@ void P_PlayerAfterThink(player_t *player)
|
|||
// so a lag value of 1 is exactly attached to the 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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1148,6 +1148,10 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"pass15", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"pass16", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// SRB2Kart - Blocked damage
|
||||
{"grownd", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND
|
||||
{"invind", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND
|
||||
|
||||
// SRB2Kart - Engine sounds
|
||||
// Engine class A
|
||||
{"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
|
|||
|
|
@ -1212,6 +1212,10 @@ typedef enum
|
|||
sfx_pass15,
|
||||
sfx_pass16,
|
||||
|
||||
// Blocked damage SFX
|
||||
sfx_grownd,
|
||||
sfx_invind,
|
||||
|
||||
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
||||
// Engine class A - Low Speed, Low Weight
|
||||
sfx_krta00,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue