Merge branch 'hitlag-retry' into 'master'

Hitlag

See merge request KartKrew/Kart!309
This commit is contained in:
Sal 2020-11-11 00:06:32 -05:00
commit 2332695988
15 changed files with 291 additions and 103 deletions

View file

@ -3617,9 +3617,9 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
{
const fixed_t thingxpos = thing->x + thing->sprxoff;
const fixed_t thingypos = thing->y + thing->spryoff;
const fixed_t thingzpos = thing->z + thing->sprzoff;
fixed_t thingxpos = thing->x + thing->sprxoff;
fixed_t thingypos = thing->y + thing->spryoff;
fixed_t thingzpos = thing->z + thing->sprzoff;
GLPatch_t *gpatch;
FOutVector shadowVerts[4];
@ -3637,6 +3637,21 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
fixed_t slopez;
pslope_t *groundslope;
// hitlag vibrating
if (thing->hitlag > 0)
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
if (leveltime & 1)
{
mul = -mul;
}
thingxpos += FixedMul(thing->momx, mul);
thingypos += FixedMul(thing->momy, mul);
thingzpos += FixedMul(thing->momz, mul);
}
groundz = R_GetShadowZ(thing, &groundslope);
floordiff = abs((flip < 0 ? thing->height : 0) + thingzpos - groundz);
@ -4867,9 +4882,9 @@ static void HWR_AddSprites(sector_t *sec)
// BP why not use xtoviexangle/viewangletox like in bsp ?....
static void HWR_ProjectSprite(mobj_t *thing)
{
const fixed_t thingxpos = thing->x + thing->sprxoff;
const fixed_t thingypos = thing->y + thing->spryoff;
const fixed_t thingzpos = thing->z + thing->sprzoff;
fixed_t thingxpos = thing->x + thing->sprxoff;
fixed_t thingypos = thing->y + thing->spryoff;
fixed_t thingzpos = thing->z + thing->sprzoff;
gl_vissprite_t *vis;
float tr_x, tr_y;
@ -4907,6 +4922,21 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (!thing)
return;
// hitlag vibrating
if (thing->hitlag > 0)
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
if (leveltime & 1)
{
mul = -mul;
}
thingxpos += FixedMul(thing->momx, mul);
thingypos += FixedMul(thing->momy, mul);
thingzpos += FixedMul(thing->momz, mul);
}
dispoffset = thing->info->dispoffset;
this_scale = FIXED_TO_FLOAT(thing->scale);

View file

@ -1340,9 +1340,9 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
// Look at HWR_ProjectSprite for more
{
const fixed_t thingxpos = spr->mobj->x + spr->mobj->sprxoff;
const fixed_t thingypos = spr->mobj->y + spr->mobj->spryoff;
const fixed_t thingzpos = spr->mobj->z + spr->mobj->sprzoff;
fixed_t thingxpos = spr->mobj->x + spr->mobj->sprxoff;
fixed_t thingypos = spr->mobj->y + spr->mobj->spryoff;
fixed_t thingzpos = spr->mobj->z + spr->mobj->sprzoff;
GLPatch_t *gpatch;
INT32 durs = spr->mobj->state->tics;
@ -1358,6 +1358,21 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
INT32 mod;
float finalscale;
// hitlag vibrating
if (spr->mobj->hitlag > 0)
{
fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 10);
if (leveltime & 1)
{
mul = -mul;
}
thingxpos += FixedMul(spr->mobj->momx, mul);
thingypos += FixedMul(spr->mobj->momy, mul);
thingzpos += FixedMul(spr->mobj->momz, mul);
}
// Apparently people don't like jump frames like that, so back it goes
//if (tics > durs)
//durs = tics;

View file

@ -30,7 +30,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
if (t2->player)
{
if (t2->player->powers[pw_flashing]
if ((t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
&& !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD))
return true;
@ -58,11 +58,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|| t2->type == MT_BALLHOG)
{
// Other Item Damage
if (t2->eflags & MFE_VERTICALFLIP)
t2->z -= t2->height;
else
t2->z += t2->height;
S_StartSound(t2, t2->info->deathsound);
P_KillMobj(t2, t1, t1, DMG_NORMAL);
@ -94,11 +89,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
if (damageitem)
{
// This Item Damage
if (t1->eflags & MFE_VERTICALFLIP)
t1->z -= t1->height;
else
t1->z += t1->height;
S_StartSound(t1, t1->info->deathsound);
P_KillMobj(t1, t2, t2, DMG_NORMAL);
@ -133,7 +123,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
if (t2->player)
{
if (t2->player->powers[pw_flashing])
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
return true;
// Banana snipe!
@ -147,7 +137,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
}
else
{
// Player Damage
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
}
@ -159,11 +148,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|| t2->type == MT_BALLHOG)
{
// Other Item Damage
if (t2->eflags & MFE_VERTICALFLIP)
t2->z -= t2->height;
else
t2->z += t2->height;
S_StartSound(t2, t2->info->deathsound);
P_KillMobj(t2, t1, t1, DMG_NORMAL);
@ -184,11 +168,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
if (damageitem)
{
// This Item Damage
if (t1->eflags & MFE_VERTICALFLIP)
t1->z -= t1->height;
else
t1->z += t1->height;
S_StartSound(t1, t1->info->deathsound);
P_KillMobj(t1, t2, t2, DMG_NORMAL);
@ -283,15 +262,19 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
if (t2->player)
{
if (t2->player->powers[pw_flashing])
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
return true;
// Bomb punting
if ((t1->state >= &states[S_SSMINE1] && t1->state <= &states[S_SSMINE4])
|| (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_DEPLOY13]))
{
P_KillMobj(t1, t2, t2, DMG_NORMAL);
}
else
{
K_PuntMine(t1, t2);
}
}
else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD
|| t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD)
@ -300,11 +283,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
P_KillMobj(t1, t2, t2, DMG_NORMAL);
// Other Item Damage
if (t2->eflags & MFE_VERTICALFLIP)
t2->z -= t2->height;
else
t2->z += t2->height;
S_StartSound(t2, t2->info->deathsound);
P_KillMobj(t2, t1, t1, DMG_NORMAL);
@ -326,10 +304,17 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2)
{
if (t2->player)
{
if (t2->player->powers[pw_flashing])
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
return true;
P_DamageMobj(t2, t1, t1->target, 1, (t1->state == &states[S_MINEEXPLOSION1]) ? DMG_EXPLODE : DMG_NORMAL);
if (t1->state == &states[S_MINEEXPLOSION1])
{
P_DamageMobj(t2, t1, t1->target, 1, DMG_EXPLODE);
}
else
{
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
}
}
else if (t2->flags & MF_SHOOTABLE)
{
@ -347,14 +332,16 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
if (t2->player)
{
if (t2->player->powers[pw_flashing])
if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0)
return true;
S_StartSound(NULL, sfx_bsnipe); // let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[t2->player-players]));
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[t2->player-players]);
P_DamageMobj(t2, t1, t1->target, 1, DMG_INSTAKILL);
P_KillMobj(t1, t2, t2, DMG_NORMAL);
}

View file

@ -1457,8 +1457,8 @@ static void K_UpdateDraft(player_t *player)
continue;
#ifndef EASYDRAFTTEST
yourangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
theirangle = R_PointToAngle2(0, 0, players[i].mo->momx, players[i].mo->momy);
yourangle = K_MomentumAngle(player->mo);
theirangle = K_MomentumAngle(players[i].mo);
diff = R_PointToAngle2(player->mo->x, player->mo->y, players[i].mo->x, players[i].mo->y) - yourangle;
if (diff > ANGLE_180)
@ -2015,7 +2015,7 @@ void K_PlayPowerGloatSound(mobj_t *source)
void K_MomentumToFacing(player_t *player)
{
angle_t dangle = player->mo->angle - R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
angle_t dangle = player->mo->angle - K_MomentumAngle(player->mo);
if (dangle > ANGLE_180)
dangle = InvAngle(dangle);
@ -2362,6 +2362,83 @@ fixed_t K_3dKartMovement(player_t *player)
return finalspeed;
}
angle_t K_MomentumAngle(mobj_t *mo)
{
if (mo->momx || mo->momy)
{
return R_PointToAngle2(0, 0, mo->momx, mo->momy);
}
else
{
return mo->angle; // default to facing angle, rather than 0
}
}
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics)
{
boolean mo1valid = (mo1 && !P_MobjWasRemoved(mo1));
boolean mo2valid = (mo2 && !P_MobjWasRemoved(mo2));
INT32 tics1 = tics;
INT32 tics2 = tics;
if (mo1valid == true && mo2valid == true)
{
const fixed_t ticaddfactor = mapobjectscale * 8;
const INT32 mintics = tics;
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 scalediff = mo2->scale - mo1->scale;
const angle_t mo1angle = K_MomentumAngle(mo1);
const angle_t mo2angle = K_MomentumAngle(mo2);
angle_t anglediff = mo1angle - mo2angle;
fixed_t anglemul = FRACUNIT;
if (anglediff > ANGLE_180)
{
anglediff = InvAngle(anglediff);
}
anglemul = FRACUNIT + (AngleFixed(anglediff) / 180); // x1.0 at 0, x1.5 at 90, x2.0 at 180
/*
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)
{
tics1 = mintics;
}
if (tics2 < mintics)
{
tics2 = mintics;
}
}
//CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2);
if (mo1valid == true)
{
mo1->hitlag += tics1;
}
if (mo2valid == true)
{
mo2->hitlag += tics2;
}
}
void K_DoInstashield(player_t *player)
{
mobj_t *layera;
@ -2738,7 +2815,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
if (!bombflashtimer && P_CheckSight(p->mo, source))
{
bombflashtimer = TICRATE*2;
P_FlashPal(p, 1, 1);
P_FlashPal(p, PAL_WHITE, 1);
}
break; // we can break right now because quakes are global to all split players somehow.
}
@ -3131,7 +3208,7 @@ static void K_SpawnAIZDust(player_t *player)
if (player->speed <= K_GetKartSpeed(player, false))
return;
travelangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
travelangle = K_MomentumAngle(player->mo);
//S_StartSound(player->mo, sfx_s3k47);
{
@ -3175,7 +3252,7 @@ void K_SpawnBoostTrail(player_t *player)
if (player->kartstuff[k_drift] != 0)
travelangle = player->mo->angle;
else
travelangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
travelangle = K_MomentumAngle(player->mo);
for (i = 0; i < 2; i++)
{
@ -3267,7 +3344,7 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
mo->z, MT_WIPEOUTTRAIL);
P_SetTarget(&dust->target, mo);
dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy);
dust->angle = K_MomentumAngle(mo);
dust->destscale = mo->scale;
P_SetScale(dust, mo->scale);
K_FlipFromObject(dust, mo);
@ -3400,7 +3477,7 @@ void K_DriftDustHandling(mobj_t *spawner)
if (P_AproxDistance(spawner->momx, spawner->momy) < 5*spawner->scale)
return;
anglediff = abs((signed)(spawner->angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy)));
anglediff = abs((signed)(spawner->angle - K_MomentumAngle(spawner)));
}
if (anglediff > ANGLE_180)
@ -3702,7 +3779,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
void K_PuntMine(mobj_t *thismine, mobj_t *punter)
{
angle_t fa = R_PointToAngle2(0, 0, punter->momx, punter->momy) >> ANGLETOFINESHIFT;
angle_t fa = K_MomentumAngle(punter) >> ANGLETOFINESHIFT;
fixed_t z = 30*mapobjectscale + punter->momz;
fixed_t spd;
mobj_t *mine;
@ -3739,6 +3816,9 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter)
if (!mine || P_MobjWasRemoved(mine))
return;
if (mine->threshold > 0 || mine->hitlag > 0)
return;
spd = (82 + ((gamespeed-1) * 14))*mapobjectscale; // Avg Speed is 41 in Normal
mine->flags |= MF_NOCLIPTHING;
@ -3748,6 +3828,8 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter)
mine->extravalue1 = 0;
mine->reactiontime = mine->info->reactiontime;
K_SetHitLagForObjects(punter, mine, 5);
mine->momx = punter->momx + FixedMul(FINECOSINE(fa), spd);
mine->momy = punter->momy + FixedMul(FINESINE(fa), spd);
mine->momz = P_MobjFlip(mine) * z;
@ -5372,7 +5454,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
MT_FASTLINE);
P_SetTarget(&fast->target, player->mo);
fast->angle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
fast->angle = K_MomentumAngle(player->mo);
fast->momx = 3*player->mo->momx/4;
fast->momy = 3*player->mo->momy/4;
fast->momz = 3*player->mo->momz/4;
@ -5913,18 +5995,12 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
{
boolean finishlinehack = false;
angle_t playerangle = player->mo->angle;
angle_t momangle = player->mo->angle;
angle_t momangle = K_MomentumAngle(player->mo);
angle_t angletowaypoint =
R_PointToAngle2(player->mo->x, player->mo->y, waypoint->mobj->x, waypoint->mobj->y);
angle_t angledelta = ANGLE_MAX;
angle_t momdelta = ANGLE_MAX;
if (player->mo->momx != 0 || player->mo->momy != 0)
{
// Defaults to facing angle if you're not moving.
momangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
}
angledelta = playerangle - angletowaypoint;
if (angledelta > ANGLE_180)
{
@ -6425,7 +6501,7 @@ static void K_KartDrift(player_t *player, boolean onground)
{
if (player->kartstuff[k_driftcharge] < 0 || player->kartstuff[k_driftcharge] >= dsone)
{
angle_t pushdir = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
angle_t pushdir = K_MomentumAngle(player->mo);
S_StartSound(player->mo, sfx_s23c);
//K_SpawnDashDustRelease(player);
@ -6863,7 +6939,7 @@ static void K_KartSpindash(player_t *player)
mobj_t *grease;
grease = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_TIREGREASE);
P_SetTarget(&grease->target, player->mo);
grease->angle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
grease->angle = K_MomentumAngle(player->mo);
grease->extravalue1 = i;
}
}
@ -7528,7 +7604,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (!onground)
{
P_Thrust(
player->mo, R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy),
player->mo, K_MomentumAngle(player->mo),
FixedMul(player->mo->scale, K_GetKartGameSpeedScalar(gamespeed))
);
}

View file

@ -39,6 +39,8 @@ void K_KartMoveAnimation(player_t *player);
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_DoInstashield(player_t *player);
void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted);
void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source);

View file

@ -95,7 +95,8 @@ enum mobj_e {
mobj_whiteshadow,
mobj_sprxoff,
mobj_spryoff,
mobj_sprzoff
mobj_sprzoff,
mobj_hitlag
};
static const char *const mobj_opt[] = {
@ -170,6 +171,7 @@ static const char *const mobj_opt[] = {
"sprxoff",
"spryoff",
"sprzoff",
"hitlag",
NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
@ -430,6 +432,9 @@ static int mobj_get(lua_State *L)
case mobj_sprzoff:
lua_pushfixed(L, mo->sprzoff);
break;
case mobj_hitlag:
lua_pushinteger(L, mo->hitlag);
break;
default: // extra custom variables in Lua memory
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));
@ -787,6 +792,9 @@ static int mobj_set(lua_State *L)
case mobj_sprzoff:
mo->sprzoff = luaL_checkfixed(L, 3);
break;
case mobj_hitlag:
mo->hitlag = luaL_checkinteger(L, 3);
break;
default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));

View file

@ -4457,6 +4457,9 @@ void A_GrenadeRing(mobj_t *actor)
if (actor->flags2 & MF2_DEBRIS)
return;
if (actor->hitlag > 0)
return;
if (actor->state == &states[S_SSMINE_DEPLOY8])
explodedist = (3*explodedist)/2;
@ -4524,6 +4527,9 @@ void A_SSMineExplode(mobj_t *actor)
if (actor->flags2 & MF2_DEBRIS)
return;
if (actor->hitlag > 0)
return;
type = (mobjtype_t)locvar1;
// Use blockmap to check for nearby shootables
@ -8757,7 +8763,7 @@ void A_JawzChase(mobj_t *actor)
if (!actor->tracer)
{
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
actor->angle = K_MomentumAngle(actor);
}
P_Thrust(actor, actor->angle, thrustamount);
@ -8887,7 +8893,7 @@ static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir)
if (mo->eflags & MFE_VERTICALFLIP)
sz = mo->ceilingz;
travelangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
travelangle = K_MomentumAngle(mo);
if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*64)
{
newx = mo->x + P_ReturnThrustX(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale));
@ -8917,7 +8923,7 @@ static void SpawnSPBSpeedLines(mobj_t *actor)
MT_FASTLINE);
P_SetTarget(&fast->target, actor);
fast->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
fast->angle = K_MomentumAngle(actor);
fast->color = SKINCOLOR_RED;
fast->colorized = true;
K_MatchGenericExtraFlags(fast, actor);

View file

@ -1075,6 +1075,8 @@ 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);
// SRB2kart
// I wish I knew a better way to do this
if (target->target && target->target->player && target->target->player->mo)
@ -1646,8 +1648,10 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
return true;
}
static boolean P_KillPlayer(player_t *player, UINT8 type)
static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 type)
{
(void)source;
if (player->exiting)
{
player->mo->destscale = 1;
@ -1668,6 +1672,8 @@ static boolean P_KillPlayer(player_t *player, UINT8 type)
break;
}
K_SetHitLagForObjects(player->mo, inflictor, 15);
player->pflags &= ~PF_SLIDING;
player->powers[pw_carry] = CR_NONE;
@ -1753,6 +1759,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
player_t *player;
boolean force = false;
INT32 laglength = 10;
if (objectplacing)
return false;
@ -1760,13 +1768,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// Spectator handling
if (multiplayer)
{
if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
return false;
if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
return false;
if (source && source->player && source->player->spectator)
return false;
if (source && source->player && source->player->spectator)
return false;
if (((damagetype & DMG_TYPEMASK) == DMG_STING)
|| ((inflictor && !P_MobjWasRemoved(inflictor)) && inflictor->type == MT_BANANA && inflictor->health <= 1))
{
laglength = 5;
}
// Everything above here can't be forced.
@ -1830,7 +1841,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Instant-Death
if ((damagetype & DMG_DEATHMASK))
{
if (!P_KillPlayer(player, damagetype))
if (!P_KillPlayer(player, inflictor, source, damagetype))
return false;
}
else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
@ -1941,6 +1952,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
}
player->kartstuff[k_instashield] = 15;
K_SetHitLagForObjects(target, inflictor, laglength);
return true;
}
}
@ -1962,12 +1974,16 @@ 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);
if (target->health <= 0)
{
P_KillMobj(target, inflictor, source, damagetype);
return true;
}
//K_SetHitLagForObjects(target, inflictor, laglength);
if (player)
P_ResetPlayer(target->player);
else

View file

@ -357,7 +357,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
mobj_t *grease;
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
P_SetTarget(&grease->target, object);
grease->angle = R_PointToAngle2(0, 0, object->momx, object->momy);
grease->angle = K_MomentumAngle(object);
grease->extravalue1 = i;
}
}
@ -1217,19 +1217,31 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)
{
if (tmthing->scale > thing->scale + (mapobjectscale/8)) // SRB2kart - Handle squishes first!
{
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SQUISH);
}
else if (thing->scale > tmthing->scale + (mapobjectscale/8))
{
P_DamageMobj(tmthing, thing, thing, 1, DMG_SQUISH);
}
else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility!
{
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT);
}
else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer])
{
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT);
}
else if ((tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)
&& !(thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield!
{
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT);
}
else if ((thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)
&& !(tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD))
{
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT);
}
}
}
@ -2472,6 +2484,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (radius < mapobjectscale)
radius = mapobjectscale;
if (thing->hitlag > 0)
{
// Do not move during hitlag
return false;
}
do {
if (thing->flags & MF_NOCLIP) {
tryx = x;

View file

@ -1620,8 +1620,10 @@ void P_XYMovement(mobj_t *mo)
relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy);
else // Give it for free, I guess.
relation = ANGLE_90;
transfermomz = FixedMul(transfermomz,
abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK)));
if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch!
{
mo->momz = transfermomz;
@ -1696,7 +1698,7 @@ void P_XYMovement(mobj_t *mo)
if (oldslope != mo->standingslope) { // First, compare different slopes
angle_t oldangle, newangle;
angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
angle_t moveangle = K_MomentumAngle(mo);
oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT));
@ -1728,7 +1730,7 @@ void P_XYMovement(mobj_t *mo)
P_SlopeLaunch(mo);
}
} else if (moved && mo->standingslope && predictedz) {
angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
angle_t moveangle = K_MomentumAngle(mo);
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
/*CONS_Printf("flat to angle %f - predicted z of %f\n",
@ -4881,8 +4883,6 @@ static boolean P_ParticleGenSceneryThink(mobj_t *mobj)
mobj->angle += mobj->movedir;
}
mobj->angle += (angle_t)mobj->movecount;
}
return true;
@ -6142,7 +6142,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
frictionsafety = FRACUNIT;
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
mobj->angle = K_MomentumAngle(mobj);
if (mobj->health <= 5)
{
INT32 i;
@ -6244,7 +6244,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety);
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
mobj->angle = K_MomentumAngle(mobj);
P_Thrust(mobj, mobj->angle, thrustamount);
if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true))
@ -6407,7 +6407,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
//mobj->angle = mobj->target->angle;
{
angle_t angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
angle_t angle = K_MomentumAngle(mobj->target);
fixed_t nudge;
mobj->angle = angle;
@ -6675,7 +6675,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
{
const angle_t off = FixedAngle(40*FRACUNIT);
angle_t ang = mobj->target->angle;
angle_t ang = K_MomentumAngle(mobj->target);
fixed_t z;
UINT8 trans = (mobj->target->player->kartstuff[k_tiregrease] * (NUMTRANSMAPS+1)) / greasetics;
@ -6688,9 +6688,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->eflags & MFE_VERTICALFLIP)
z += mobj->target->height;
if (mobj->target->momx || mobj->target->momy)
ang = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
if (mobj->extravalue1)
ang = (signed)(ang - off);
else
@ -6985,10 +6982,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
P_TeleportMove(mobj, destx, desty, mobj->target->z);
if (mobj->target->momx || mobj->target->momy)
mobj->angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
else
mobj->angle = mobj->target->angle;
mobj->angle = K_MomentumAngle(mobj->target);
if (underlayst != S_NULL)
{
@ -7865,7 +7859,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->momx = (23*mobj->momx)/24;
mobj->momy = (23*mobj->momy)/24;
mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy);
mobj->angle = K_MomentumAngle(mobj);
if ((mobj->z - mobj->floorz) < (24*mobj->scale) && (leveltime % 3 != 0))
{
@ -8419,6 +8413,13 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
P_SetTarget(&mobj->hprev, NULL);
// Don't run any thinker code while in hitlag
if (mobj->hitlag > 0)
{
mobj->hitlag--;
return;
}
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL);
tmfloorthing = tmhitthing = NULL;
@ -9020,6 +9021,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->colorized = false;
mobj->hitlag = 0;
// Set shadowscale here, before spawn hook so that Lua can change it
P_DefaultMobjShadowScale(mobj);

View file

@ -420,6 +420,8 @@ typedef struct mobj_s
fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision
INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls
// WARNING: New fields must be added separately to savegame and Lua.
} mobj_t;

View file

@ -1369,9 +1369,10 @@ typedef enum
MD2_ROLLANGLE = 1<<14,
MD2_SHADOWSCALE = 1<<15,
MD2_DRAWFLAGS = 1<<16,
MD2_WAYPOINTCAP = 1<<17,
MD2_KITEMCAP = 1<<18,
MD2_ITNEXT = 1<<19,
MD2_HITLAG = 1<<17,
MD2_WAYPOINTCAP = 1<<18,
MD2_KITEMCAP = 1<<19,
MD2_ITNEXT = 1<<20,
} mobj_diff2_t;
typedef enum
@ -1586,6 +1587,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SHADOWSCALE;
if (mobj->drawflags)
diff2 |= MD2_DRAWFLAGS;
if (mobj->hitlag)
diff2 |= MD2_HITLAG;
if (mobj == waypointcap)
diff2 |= MD2_WAYPOINTCAP;
if (mobj == kitemcap)
@ -1750,6 +1753,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT16(save_p, df);
}
if (diff2 & MD2_HITLAG)
WRITEINT32(save_p, mobj->hitlag);
WRITEUINT32(save_p, mobj->mobjnum);
}
@ -2814,6 +2819,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
}
if (diff2 & MD2_DRAWFLAGS)
mobj->drawflags = READUINT16(save_p);
if (diff2 & MD2_HITLAG)
mobj->hitlag = READINT32(save_p);
if (diff & MD_REDFLAG)
{

View file

@ -4602,8 +4602,7 @@ DoneSection2:
{
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
angle_t pushangle = K_MomentumAngle(player->mo);
if (player->mo->eflags & MFE_SPRUNG)
break;
@ -4625,8 +4624,7 @@ DoneSection2:
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
const fixed_t maxspeed = 28*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
angle_t pushangle = K_MomentumAngle(player->mo);
if (player->mo->eflags & MFE_SPRUNG)
break;
@ -4673,7 +4671,7 @@ DoneSection2:
}
lineangle = K_ReflectAngle(
R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy), lineangle,
K_MomentumAngle(player->mo), lineangle,
playerspeed, linespeed
);

View file

@ -2271,7 +2271,7 @@ void P_MovePlayer(player_t *player)
if (trailScale > 0)
{
const angle_t forwardangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
const angle_t forwardangle = K_MomentumAngle(player->mo);
const fixed_t playerVisualRadius = player->mo->radius + 8*FRACUNIT;
const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1;
const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames);
@ -4071,7 +4071,7 @@ static void P_HandleFollower(player_t *player)
player->follower->drawflags |= MFD_DONTDRAW;
if (player->speed && (player->follower->momx || player->follower->momy))
player->follower->angle = R_PointToAngle2(0, 0, player->follower->momx, player->follower->momy);
player->follower->angle = K_MomentumAngle(player->follower);
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
// Make sure the follower itself is also moving however, otherwise we'll be facing angle 0
@ -4217,6 +4217,11 @@ void P_PlayerThink(player_t *player)
}
#endif
if (player->mo->hitlag > 0)
{
return;
}
if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj))
{
P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid

View file

@ -1403,9 +1403,9 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
//
static void R_ProjectSprite(mobj_t *thing)
{
const fixed_t thingxpos = thing->x + thing->sprxoff;
const fixed_t thingypos = thing->y + thing->spryoff;
const fixed_t thingzpos = thing->z + thing->sprzoff;
fixed_t thingxpos = thing->x + thing->sprxoff;
fixed_t thingypos = thing->y + thing->spryoff;
fixed_t thingzpos = thing->z + thing->sprzoff;
mobj_t *oldthing = thing;
@ -1464,6 +1464,21 @@ static void R_ProjectSprite(mobj_t *thing)
INT32 rollangle = 0;
#endif
// hitlag vibrating
if (thing->hitlag > 0)
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
if (leveltime & 1)
{
mul = -mul;
}
thingxpos += FixedMul(thing->momx, mul);
thingypos += FixedMul(thing->momy, mul);
thingzpos += FixedMul(thing->momz, mul);
}
// transform the origin point
tr_x = thingxpos - viewx;
tr_y = thingypos - viewy;