Merge branch 'snapify-hitlag' into 'master'

Snap da sentinel like hitlag

See merge request KartKrew/Kart!458
This commit is contained in:
James R 2021-11-28 00:29:29 +00:00
commit 17b3cd205e
18 changed files with 196 additions and 127 deletions

View file

@ -456,9 +456,6 @@ typedef struct player_s
UINT8 trickpanel; // Trick panel state
UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold
fixed_t trickmomx;
fixed_t trickmomy;
fixed_t trickmomz;
fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks.
UINT8 trickboostdecay; // used to know how long you've waited
UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god.

View file

@ -6845,6 +6845,7 @@ struct int_const_s const INT_CONST[] = {
{"TC_RAINBOW",TC_RAINBOW},
{"TC_BLINK",TC_BLINK},
{"TC_DASHMODE",TC_DASHMODE},
{"TC_HITLAG",TC_HITLAG},
// marathonmode flags
{"MA_INIT",MA_INIT},

View file

@ -3643,7 +3643,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
pslope_t *groundslope;
// hitlag vibrating
if (thing->hitlag > 0)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
@ -5062,7 +5062,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
return;
// hitlag vibrating
if (thing->hitlag > 0)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
@ -5401,7 +5401,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->mobj = thing;
//Hurdler: 25/04/2000: now support colormap in hardware mode
if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG))
{
vis->colormap = R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE);
}
else if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
{
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);

View file

@ -819,7 +819,12 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
while (size--)
{
if (skinnum == TC_BOSS)
if (skinnum == TC_HITLAG)
{
cur->s.red = cur->s.green = cur->s.blue = K_HitlagColorValue(*image);
cur->s.alpha = image->s.alpha;
}
else if (skinnum == TC_BOSS)
{
// Turn everything below a certain threshold white
if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127)
@ -1367,7 +1372,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
float finalscale;
// hitlag vibrating
if (spr->mobj->hitlag > 0)
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 10);
@ -1486,7 +1491,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
{
INT32 skinnum = TC_DEFAULT;
if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
{
skinnum = TC_HITLAG;
}
else if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
{
if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized)
skinnum = TC_ALLWHITE;

View file

@ -90,6 +90,59 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor)
}
}
/*--------------------------------------------------
UINT8 K_HitlagColorValue(RGBA_t color)
See header file for description.
--------------------------------------------------*/
UINT8 K_HitlagColorValue(RGBA_t color)
{
// Outputs a raw brightness value (makes OGL support easier)
INT32 output = K_ColorRelativeLuminance(color.s.red, color.s.green, color.s.blue);
// Invert the color
output = 255 - output;
// Increase the contrast
output = ((output-128) * 2) + 128;
// Make sure to cap it.
if (output > 255)
{
output = 255;
}
else if (output < 0)
{
output = 0;
}
return output;
}
/*--------------------------------------------------
void K_HitlagColormap(UINT8 *dest_colormap)
See header file for description.
--------------------------------------------------*/
void K_HitlagColormap(UINT8 *dest_colormap)
{
RGBA_t color;
UINT8 v, offset;
INT32 i;
// for every colour in the palette, invert, greyscale, and increase the contrast.
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
{
color = V_GetColor(i);
v = K_HitlagColorValue(color);
// Convert raw brightness value to an offset from the greyscale palette line
offset = (255 - v) / 8;
dest_colormap[i] = offset; // Starts from 0, add it if greyscale moves.
}
}
/*--------------------------------------------------
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color)
@ -100,13 +153,18 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color)
INT32 i;
INT32 starttranscolor;
// Handle a couple of simple special cases
if (skinnum == TC_BOSS
if (skinnum == TC_HITLAG)
{
K_HitlagColormap(dest_colormap);
return;
}
else if (skinnum == TC_BOSS
|| skinnum == TC_ALLWHITE
|| skinnum == TC_METALSONIC
|| skinnum == TC_BLINK
|| color == SKINCOLOR_NONE)
{
// Handle a couple of simple special cases
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
{
if (skinnum == TC_ALLWHITE)

View file

@ -66,6 +66,35 @@ UINT16 K_RainbowColor(tic_t time);
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
/*--------------------------------------------------
UINT8 K_HitlagColorValue(RGBA_t color);
Gets the new replacement brightness value for the hitlag effect.
Input Arguments:-
color - Input color we intend to replace.
Return:-
0 to 255 brightness value.
--------------------------------------------------*/
UINT8 K_HitlagColorValue(RGBA_t color);
/*--------------------------------------------------
void K_HitlagColormap(UINT8 *dest_colormap);
Generates a inverted hi-contrast greyscale colormap,
for the hitlag effect.
Input Arguments:-
dest_colormap - Colormap to populate.
Return:-
None
--------------------------------------------------*/
void K_HitlagColormap(UINT8 *dest_colormap);
/*--------------------------------------------------
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color);

View file

@ -3743,7 +3743,7 @@ static void K_drawKartFirstPerson(void)
fixed_t yoffs = -P_ReturnThrustX(stplyr->mo, ang, 4*FRACUNIT);
// hitlag vibrating
if (stplyr->mo->hitlag > 0)
if (stplyr->mo->hitlag > 0 && (stplyr->mo->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = stplyr->mo->hitlag * (FRACUNIT / 10);
if (r_splitscreen && mul > FRACUNIT)

View file

@ -3021,74 +3021,66 @@ angle_t K_MomentumAngle(mobj_t *mo)
}
}
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics)
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage)
{
boolean mo1valid = (mo1 && !P_MobjWasRemoved(mo1));
boolean mo2valid = (mo2 && !P_MobjWasRemoved(mo2));
if (mo == NULL || P_MobjWasRemoved(mo))
{
return;
}
INT32 tics1 = tics;
INT32 tics2 = tics;
mo->hitlag += tics;
mo->hitlag = min(mo->hitlag, MAXHITLAGTICS);
if (fromDamage == true)
{
// Dunno if this should flat-out &~ the flag out too.
// Decided it probably just just keep it since it's "adding" hitlag.
mo->eflags |= MFE_DAMAGEHITLAG;
}
}
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage)
{
INT32 finalTics = tics;
if (tics <= 0)
{
return;
}
if (mo1valid == true && mo2valid == true)
if ((mo1 && !P_MobjWasRemoved(mo1)) == true && (mo2 && !P_MobjWasRemoved(mo2)) == true)
{
const INT32 mintics = tics;
const fixed_t ticaddfactor = mapobjectscale * 8;
const fixed_t speedTicFactor = (mapobjectscale * 8);
const INT32 angleTicFactor = ANGLE_22h;
const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz);
const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz);
const fixed_t speeddiff = mo2speed - mo1speed;
const fixed_t speedDiff = abs(mo2speed - mo1speed);
const fixed_t scalediff = mo2->scale - mo1->scale;
const fixed_t scaleDiff = abs(mo2->scale - mo1->scale);
const angle_t mo1angle = K_MomentumAngle(mo1);
const angle_t mo2angle = K_MomentumAngle(mo2);
angle_t mo1angle = K_MomentumAngle(mo1);
angle_t mo2angle = K_MomentumAngle(mo2);
INT32 angleDiff = 0;
angle_t anglediff = mo1angle - mo2angle;
fixed_t anglemul = FRACUNIT;
if (anglediff > ANGLE_180)
if (mo1speed > 0 && mo2speed > 0)
{
anglediff = InvAngle(anglediff);
// If either object is completely not moving, their speed doesn't matter.
angleDiff = AngleDelta(mo1angle, mo2angle);
}
anglemul = FRACUNIT + (AngleFixed(anglediff) / 180); // x1.0 at 0, x1.5 at 90, x2.0 at 180
// Add extra "damage" based on what was happening to the objects on impact.
finalTics += (FixedMul(speedDiff, FRACUNIT + scaleDiff) / speedTicFactor) + (angleDiff / angleTicFactor);
/*
CONS_Printf("anglemul: %f\n", FIXED_TO_FLOAT(anglemul));
CONS_Printf("speeddiff: %f\n", FIXED_TO_FLOAT(speeddiff));
CONS_Printf("scalediff: %f\n", FIXED_TO_FLOAT(scalediff));
*/
tics1 += FixedMul(speeddiff, FixedMul(anglemul, FRACUNIT + scalediff)) / ticaddfactor;
tics2 += FixedMul(-speeddiff, FixedMul(anglemul, FRACUNIT - scalediff)) / ticaddfactor;
if (tics1 < mintics)
// This shouldn't happen anymore, but just in case something funky happens.
if (finalTics < tics)
{
tics1 = mintics;
}
if (tics2 < mintics)
{
tics2 = mintics;
finalTics = tics;
}
}
//CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2);
if (mo1valid == true)
{
mo1->hitlag = max(tics1, mo1->hitlag);
}
if (mo2valid == true)
{
mo2->hitlag = max(tics2, mo2->hitlag);
}
K_AddHitLag(mo1, finalTics, fromDamage);
K_AddHitLag(mo2, finalTics, fromDamage);
}
void K_DoInstashield(player_t *player)
@ -5121,7 +5113,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
thrust = FixedMul(thrust, 9*FRACUNIT/8);
}
mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = mo->player->tricktime = 0; // Reset post-hitlag momentums and timer
mo->player->tricktime = 0; // Reset post-hitlag timer
// Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25)
mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0)*125/100;
//CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT);
@ -9209,29 +9201,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (cmd->turning > 0)
{
P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2));
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 2;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (cmd->turning < 0)
{
P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2));
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 3;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (player->throwdir == 1)
@ -9242,15 +9226,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3));
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 2;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (player->throwdir == -1)
@ -9272,30 +9252,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
//CONS_Printf("decay: %d\n", player->trickboostdecay);
P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative);
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 4;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
}
}
// After hitlag, we will get here and will be able to apply the desired momentums!
else if (player->trickmomx || player->trickmomy || player->trickmomz)
{
player->mo->momx = player->trickmomx;
player->mo->momy = player->trickmomy;
player->mo->momz = player->trickmomz;
player->trickmomx = player->trickmomy = player->trickmomz = 0;
}
else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed!
{
//CONS_Printf("apply boost\n");

View file

@ -19,6 +19,7 @@ Make sure this matches the actual number of states
*/
#define KART_NUMINVSPARKLESANIM 12
#define MAXHITLAGTICS 18 //12
player_t *K_GetItemBoxPlayer(mobj_t *mobj);
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
@ -55,7 +56,8 @@ void K_KartPlayerHUDUpdate(player_t *player);
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
void K_KartPlayerAfterThink(player_t *player);
angle_t K_MomentumAngle(mobj_t *mo);
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics);
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage);
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage);
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);

View file

@ -356,12 +356,6 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->trickpanel);
else if (fastcmp(field,"tricktime"))
lua_pushinteger(L, plr->tricktime);
else if (fastcmp(field,"trickmomx"))
lua_pushfixed(L, plr->trickmomx);
else if (fastcmp(field,"trickmomy"))
lua_pushfixed(L, plr->trickmomy);
else if (fastcmp(field,"trickmomz"))
lua_pushfixed(L, plr->trickmomz);
else if (fastcmp(field,"trickboostpower"))
lua_pushfixed(L, plr->trickboostpower);
else if (fastcmp(field,"trickboostdecay"))
@ -707,12 +701,6 @@ static int player_set(lua_State *L)
plr->trickpanel = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tricktime"))
plr->tricktime = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickmomx"))
plr->trickmomx = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickmomy"))
plr->trickmomy = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickmomz"))
plr->trickmomz = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickboostpower"))
plr->trickboostpower = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickboostdecay"))

View file

@ -968,7 +968,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
return;
//K_SetHitLagForObjects(target, inflictor, 15);
//K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true);
// SRB2kart
// I wish I knew a better way to do this
@ -1255,6 +1255,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
kart->angle = target->angle;
kart->color = target->color;
kart->hitlag = target->hitlag;
kart->eflags |= MFE_DAMAGEHITLAG;
P_SetObjectMomZ(kart, 6*FRACUNIT, false);
kart->extravalue1 = target->player->kartweight;
}
@ -1745,7 +1746,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
}
K_DropEmeraldsFromPlayer(player, player->emeralds);
K_SetHitLagForObjects(player->mo, inflictor, 15);
K_SetHitLagForObjects(player->mo, inflictor, MAXHITLAGTICS, true);
player->carry = CR_NONE;
@ -1805,7 +1806,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
player_t *player;
boolean force = false;
INT32 laglength = 10;
INT32 laglength = 6;
INT32 kinvextend = 0;
if (objectplacing)
@ -1824,7 +1825,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (((damagetype & DMG_TYPEMASK) == DMG_STING)
|| ((inflictor && !P_MobjWasRemoved(inflictor)) && inflictor->type == MT_BANANA && inflictor->health <= 1))
{
laglength = 5;
laglength = 2;
}
// Everything above here can't be forced.
@ -2062,7 +2063,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
}
player->instashield = 15;
K_SetHitLagForObjects(target, inflictor, laglength);
K_SetHitLagForObjects(target, inflictor, laglength, true);
return true;
}
}
@ -2084,7 +2085,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (source && source->player && target)
G_GhostAddHit((INT32) (source->player - players), target);
K_SetHitLagForObjects(target, inflictor, laglength);
K_SetHitLagForObjects(target, inflictor, laglength, true);
if (target->health <= 0)
{
@ -2092,7 +2093,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true;
}
//K_SetHitLagForObjects(target, inflictor, laglength);
//K_SetHitLagForObjects(target, inflictor, laglength, true);
if (player)
P_ResetPlayer(target->player);

View file

@ -479,6 +479,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|| (thing->player && thing->player->spectator))
return true;
// Ignore the collision if BOTH things are in hitlag.
if (thing->hitlag > 0 && tmthing->hitlag > 0)
return true;
if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING)))
return true;
@ -2402,11 +2406,13 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (radius < mapobjectscale)
radius = mapobjectscale;
#if 0
if (thing->hitlag > 0)
{
// Do not move during hitlag
return false;
}
#endif
do {
if (thing->flags & MF_NOCLIP) {

View file

@ -8616,7 +8616,7 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL);
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG);
tmfloorthing = tmhitthing = NULL;

View file

@ -247,6 +247,8 @@ typedef enum
MFE_TRACERANGLE = 1<<11,
// SRB2Kart: The mobj just hit & bounced off a wall, this is cleared on next frame
MFE_JUSTBOUNCEDWALL = 1<<12,
// SRB2Kart: In damage hitlag (displays different visual efx)
MFE_DAMAGEHITLAG = 1<<13,
// free: to and including 1<<15
} mobjeflag_t;

View file

@ -306,9 +306,6 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].trickpanel);
WRITEUINT8(save_p, players[i].tricktime);
WRITEUINT32(save_p, players[i].trickmomx);
WRITEUINT32(save_p, players[i].trickmomy);
WRITEUINT32(save_p, players[i].trickmomz);
WRITEUINT32(save_p, players[i].trickboostpower);
WRITEUINT8(save_p, players[i].trickboostdecay);
WRITEUINT8(save_p, players[i].trickboost);
@ -564,9 +561,6 @@ static void P_NetUnArchivePlayers(void)
players[i].trickpanel = READUINT8(save_p);
players[i].tricktime = READUINT8(save_p);
players[i].trickmomx = READUINT32(save_p);
players[i].trickmomy = READUINT32(save_p);
players[i].trickmomz = READUINT32(save_p);
players[i].trickboostpower = READUINT32(save_p);
players[i].trickboostdecay = READUINT8(save_p);
players[i].trickboost = READUINT8(save_p);
@ -1969,7 +1963,9 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, slope->normal.z);
}
if (diff2 & MD2_HITLAG)
{
WRITEINT32(save_p, mobj->hitlag);
}
WRITEUINT32(save_p, mobj->mobjnum);
}
@ -3061,7 +3057,9 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
slope->normal.z = READFIXED(save_p);
}
if (diff2 & MD2_HITLAG)
{
mobj->hitlag = READINT32(save_p);
}
if (diff & MD_REDFLAG)
{

View file

@ -141,7 +141,9 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6)
#define TT_CACHE_SIZE (MAXSKINS + 7)
#define HITLAG_TT_CACHE_INDEX (MAXSKINS + 7)
#define TT_CACHE_SIZE (MAXSKINS + 8)
#define SKIN_RAMP_LENGTH 16
#define DEFAULT_STARTTRANSCOLOR 96
#define NUM_PALETTE_ENTRIES 256
@ -160,6 +162,7 @@ static INT32 SkinToCacheIndex(INT32 skinnum)
case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX;
case TC_BLINK: return BLINK_TT_CACHE_INDEX;
case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX;
case TC_HITLAG: return HITLAG_TT_CACHE_INDEX;
default: break;
}
@ -177,6 +180,7 @@ static INT32 CacheIndexToSkin(INT32 ttc)
case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW;
case BLINK_TT_CACHE_INDEX: return TC_BLINK;
case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE;
case HITLAG_TT_CACHE_INDEX: return TC_HITLAG;
default: break;
}

View file

@ -119,6 +119,7 @@ enum
TC_RAINBOW, // For single colour
TC_BLINK, // For item blinking, according to kart
TC_DASHMODE, // For Metal Sonic's dashmode
TC_HITLAG, // Damage hitlag effect
TC_DEFAULT
};

View file

@ -737,7 +737,11 @@ boolean R_SpriteIsFlashing(vissprite_t *vis)
UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
{
if (R_SpriteIsFlashing(vis)) // Bosses "flash"
if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG))
{
return R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE);
}
else if (R_SpriteIsFlashing(vis)) // Bosses "flash"
{
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
return R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
@ -1432,7 +1436,7 @@ static void R_ProjectSprite(mobj_t *thing)
#endif
// hitlag vibrating
if (thing->hitlag > 0)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);