mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'misc-battle-fixes-chapter-69' into 'bumpers-ARE-health'
Bug fixes and general improvements to Battle: The Final Season Part 1 See merge request KartKrew/Kart!1028
This commit is contained in:
commit
4297591b87
18 changed files with 209 additions and 118 deletions
|
|
@ -3370,7 +3370,7 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
|
||||||
if (!P_IsObjectOnGround(players[respawnplayer].mo))
|
if (!P_IsObjectOnGround(players[respawnplayer].mo))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
K_DoIngameRespawn(&players[respawnplayer]);
|
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 1, DMG_DEATHPIT);
|
||||||
demo_extradata[playernum] |= DXD_RESPAWN;
|
demo_extradata[playernum] |= DXD_RESPAWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -490,7 +490,7 @@ struct player_t
|
||||||
UINT16 spinouttimer; // Spin-out from a banana peel or oil slick (was "pw_bananacam")
|
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 spinouttype; // Determines the mode of spinout/wipeout, see kartspinoutflags_t
|
||||||
UINT8 instashield; // Instashield no-damage animation timer
|
UINT8 instashield; // Instashield no-damage animation timer
|
||||||
INT32 invulnhitlag; // Numbers of tics of hitlag added this tic for "potential" damage -- not real damage
|
INT32 nullHitlag; // Numbers of tics of hitlag that will ultimately be ignored by subtracting from hitlag
|
||||||
UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out
|
UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out
|
||||||
UINT8 justbumped; // Prevent players from endlessly bumping into each other
|
UINT8 justbumped; // Prevent players from endlessly bumping into each other
|
||||||
UINT8 tumbleBounces;
|
UINT8 tumbleBounces;
|
||||||
|
|
@ -641,8 +641,10 @@ struct player_t
|
||||||
|
|
||||||
INT16 lastsidehit, lastlinehit;
|
INT16 lastsidehit, lastlinehit;
|
||||||
|
|
||||||
// These track how many things tried to damage you, not
|
// TimesHit tracks how many times something tried to
|
||||||
// whether you actually took damage.
|
// damage you or how many times you tried to damage
|
||||||
|
// something else. It does not track whether damage was
|
||||||
|
// actually dealt.
|
||||||
UINT8 timeshit; // times hit this tic
|
UINT8 timeshit; // times hit this tic
|
||||||
UINT8 timeshitprev; // times hit before
|
UINT8 timeshitprev; // times hit before
|
||||||
// That's TIMES HIT, not TIME SHIT, you doofus! -- in memoriam
|
// That's TIMES HIT, not TIME SHIT, you doofus! -- in memoriam
|
||||||
|
|
|
||||||
|
|
@ -5730,7 +5730,7 @@ const char *const MOBJFLAG2_LIST[] = {
|
||||||
"JUSTATTACKED", // can be pushed by other moving mobjs
|
"JUSTATTACKED", // can be pushed by other moving mobjs
|
||||||
"FIRING", // turret fire
|
"FIRING", // turret fire
|
||||||
"SUPERFIRE", // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
|
"SUPERFIRE", // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
|
||||||
"\x01", // free: 1<<20 (name un-matchable)
|
"ALREADYHIT", // This object was already damaged THIS tic, resets even during hitlag
|
||||||
"STRONGBOX", // Flag used for "strong" random monitors.
|
"STRONGBOX", // Flag used for "strong" random monitors.
|
||||||
"OBJECTFLIP", // Flag for objects that always have flipped gravity.
|
"OBJECTFLIP", // Flag for objects that always have flipped gravity.
|
||||||
"SKULLFLY", // Special handling: skull in flight.
|
"SKULLFLY", // Special handling: skull in flight.
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ void G_ReadDemoExtraData(void)
|
||||||
if (players[p].mo)
|
if (players[p].mo)
|
||||||
{
|
{
|
||||||
// Is this how this should work..?
|
// Is this how this should work..?
|
||||||
K_DoIngameRespawn(&players[p]);
|
P_DamageMobj(players[p].mo, NULL, NULL, 1, DMG_DEATHPIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (extradata & DXD_WEAPONPREF)
|
if (extradata & DXD_WEAPONPREF)
|
||||||
|
|
|
||||||
|
|
@ -23907,7 +23907,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
16, // mass
|
16, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_SOLID|MF_NOCLIP|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
MF_SOLID|MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ UINT8 numtargets = 0; // Capsules busted
|
||||||
INT32 K_StartingBumperCount(void)
|
INT32 K_StartingBumperCount(void)
|
||||||
{
|
{
|
||||||
if (battlecapsules)
|
if (battlecapsules)
|
||||||
return 1; // always 1 hit in Break the Capsules
|
return 0; // always 1 hit in Break the Capsules
|
||||||
|
|
||||||
return cv_kartbumpers.value;
|
return cv_kartbumpers.value;
|
||||||
}
|
}
|
||||||
|
|
@ -95,8 +95,6 @@ void K_CheckBumpers(void)
|
||||||
UINT8 nobumpers = 0;
|
UINT8 nobumpers = 0;
|
||||||
UINT8 eliminated = 0;
|
UINT8 eliminated = 0;
|
||||||
|
|
||||||
const boolean singleplayer = (battlecapsules || bossinfo.valid);
|
|
||||||
|
|
||||||
if (!(gametyperules & GTR_BUMPERS))
|
if (!(gametyperules & GTR_BUMPERS))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -124,7 +122,7 @@ void K_CheckBumpers(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (singleplayer
|
if (K_Cooperative()
|
||||||
? nobumpers > 0 && nobumpers >= numingame
|
? nobumpers > 0 && nobumpers >= numingame
|
||||||
: eliminated >= numingame - 1)
|
: eliminated >= numingame - 1)
|
||||||
{
|
{
|
||||||
|
|
@ -135,7 +133,7 @@ void K_CheckBumpers(void)
|
||||||
if (players[i].spectator)
|
if (players[i].spectator)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (singleplayer)
|
if (K_Cooperative())
|
||||||
players[i].pflags |= PF_NOCONTEST;
|
players[i].pflags |= PF_NOCONTEST;
|
||||||
|
|
||||||
P_DoPlayerExit(&players[i]);
|
P_DoPlayerExit(&players[i]);
|
||||||
|
|
@ -170,7 +168,7 @@ void K_CheckEmeralds(player_t *player)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
player->roundscore++; // lol
|
player->roundscore = 100; // lmao
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -179,11 +177,6 @@ void K_CheckEmeralds(player_t *player)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (&players[i] == player)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
P_DoPlayerExit(&players[i]);
|
P_DoPlayerExit(&players[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -319,6 +312,21 @@ static inline boolean IsOnInterval(tic_t interval)
|
||||||
return ((leveltime - starttime) % interval) == 0;
|
return ((leveltime - starttime) % interval) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT32 CountEmeraldsSpawned(const mobj_t *mo)
|
||||||
|
{
|
||||||
|
switch (mo->type)
|
||||||
|
{
|
||||||
|
case MT_EMERALD:
|
||||||
|
return mo->extravalue1;
|
||||||
|
|
||||||
|
case MT_MONITOR:
|
||||||
|
return Obj_MonitorGetEmerald(mo);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void K_RunPaperItemSpawners(void)
|
void K_RunPaperItemSpawners(void)
|
||||||
{
|
{
|
||||||
const boolean overtime = (battleovertime.enabled >= 10*TICRATE);
|
const boolean overtime = (battleovertime.enabled >= 10*TICRATE);
|
||||||
|
|
@ -382,10 +390,7 @@ void K_RunPaperItemSpawners(void)
|
||||||
|
|
||||||
mo = (mobj_t *)th;
|
mo = (mobj_t *)th;
|
||||||
|
|
||||||
if (mo->type == MT_EMERALD)
|
emeraldsSpawned |= CountEmeraldsSpawned(mo);
|
||||||
{
|
|
||||||
emeraldsSpawned |= mo->extravalue1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canmakeemeralds)
|
if (canmakeemeralds)
|
||||||
|
|
@ -444,15 +449,7 @@ void K_RunPaperItemSpawners(void)
|
||||||
|
|
||||||
mo = (mobj_t *)th;
|
mo = (mobj_t *)th;
|
||||||
|
|
||||||
if (mo->type == MT_EMERALD)
|
emeraldsSpawned |= CountEmeraldsSpawned(mo);
|
||||||
{
|
|
||||||
emeraldsSpawned |= mo->extravalue1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mo->type == MT_MONITOR)
|
|
||||||
{
|
|
||||||
emeraldsSpawned |= Obj_MonitorGetEmerald(mo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mo->type != MT_PAPERITEMSPOT)
|
if (mo->type != MT_PAPERITEMSPOT)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -827,10 +824,10 @@ UINT8 K_Bumpers(player_t *player)
|
||||||
return UINT8_MAX;
|
return UINT8_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
return player->mo->health;
|
return (player->mo->health - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 K_BumpersToHealth(UINT8 bumpers)
|
INT32 K_BumpersToHealth(UINT8 bumpers)
|
||||||
{
|
{
|
||||||
return bumpers;
|
return (bumpers + 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
boolean damageitem = false;
|
boolean damageitem = false;
|
||||||
|
|
||||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -133,9 +130,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Push fakes out of other item boxes
|
// Push fakes out of other item boxes
|
||||||
if (t2->type == MT_RANDOMITEM || t2->type == MT_EGGMANITEM)
|
if (t2->type == MT_RANDOMITEM || t2->type == MT_EGGMANITEM)
|
||||||
{
|
{
|
||||||
|
|
@ -313,6 +307,10 @@ tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin)
|
||||||
// Set this flag to ensure that the inital action won't be triggered twice.
|
// Set this flag to ensure that the inital action won't be triggered twice.
|
||||||
actor->flags2 |= MF2_DEBRIS;
|
actor->flags2 |= MF2_DEBRIS;
|
||||||
|
|
||||||
|
// Set this flag to ensure the hitbox timer doesn't get extended with every player hit
|
||||||
|
actor->flags |= MF_NOHITLAGFORME;
|
||||||
|
actor->hitlag = 0; // same deal
|
||||||
|
|
||||||
if (!spin)
|
if (!spin)
|
||||||
{
|
{
|
||||||
if (minehitlag == 0)
|
if (minehitlag == 0)
|
||||||
|
|
@ -330,9 +328,6 @@ tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin)
|
||||||
|
|
||||||
boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -384,9 +379,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -465,9 +457,6 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
mobj_t *draggeddroptarget = (t1->type == MT_DROPTARGET_SHIELD) ? t1->target : NULL;
|
mobj_t *draggeddroptarget = (t1->type == MT_DROPTARGET_SHIELD) ? t1->target : NULL;
|
||||||
|
|
||||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (((t1->target == t2) || (t1->target == t2->target)) && ((t1->threshold > 0 && t2->type == MT_PLAYER) || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
if (((t1->target == t2) || (t1->target == t2->target)) && ((t1->threshold > 0 && t2->type == MT_PLAYER) || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -678,6 +667,17 @@ void K_LightningShieldAttack(mobj_t *actor, fixed_t size)
|
||||||
|
|
||||||
boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
|
boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
|
if (t1->type == MT_PLAYER)
|
||||||
|
{
|
||||||
|
// Bubble Shield already has a hitbox, and it gets
|
||||||
|
// teleported every tic so the Bubble itself will
|
||||||
|
// always make contact with other objects.
|
||||||
|
//
|
||||||
|
// Therefore, we don't need a second, smaller hitbox
|
||||||
|
// on the player. It'll just cause unwanted hitlag.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (t2->type == MT_PLAYER)
|
if (t2->type == MT_PLAYER)
|
||||||
{
|
{
|
||||||
// Counter desyncs
|
// Counter desyncs
|
||||||
|
|
@ -697,8 +697,13 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Player Damage
|
// Player Damage
|
||||||
P_DamageMobj(t2, ((t1->type == MT_BUBBLESHIELD) ? t1->target : t1), t1, 1, DMG_NORMAL|DMG_WOMBO);
|
P_DamageMobj(t2, t1->target, t1, 1, DMG_NORMAL|DMG_WOMBO);
|
||||||
S_StartSound(t1, sfx_s3k44);
|
|
||||||
|
if (t2->player->timeshit > t2->player->timeshitprev)
|
||||||
|
{
|
||||||
|
// Don't play from t1 else it gets cut out... for some reason.
|
||||||
|
S_StartSound(t2, sfx_s3k44);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -728,9 +733,6 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
|
boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
||||||
23
src/k_hud.c
23
src/k_hud.c
|
|
@ -2025,7 +2025,7 @@ static boolean K_drawKartPositionFaces(void)
|
||||||
if (i == strank)
|
if (i == strank)
|
||||||
V_DrawScaledPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facehighlight[(leveltime / 4) % 8]);
|
V_DrawScaledPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facehighlight[(leveltime / 4) % 8]);
|
||||||
|
|
||||||
if ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].mo->health <= 0)
|
if ((gametyperules & GTR_BUMPERS) && (players[rankplayer[i]].pflags & PF_ELIMINATED))
|
||||||
V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers);
|
V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2358,7 +2358,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
|
||||||
if (tab[i].num == whiteplayer)
|
if (tab[i].num == whiteplayer)
|
||||||
V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]);
|
V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]);
|
||||||
|
|
||||||
if ((gametyperules & GTR_BUMPERS) && players[tab[i].num].mo->health <= 0)
|
if ((gametyperules & GTR_BUMPERS) && (players[tab[i].num].pflags & PF_ELIMINATED))
|
||||||
V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers);
|
V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -3640,6 +3640,10 @@ static void K_drawKartMinimap(void)
|
||||||
if (!players[i].mo || players[i].spectator || !players[i].mo->skin || players[i].exiting)
|
if (!players[i].mo || players[i].spectator || !players[i].mo->skin || players[i].exiting)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// This player is out of the game!
|
||||||
|
if ((gametyperules & GTR_BUMPERS) && (players[i].pflags & PF_ELIMINATED))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (i == displayplayers[0] || i == displayplayers[1] || i == displayplayers[2] || i == displayplayers[3])
|
if (i == displayplayers[0] || i == displayplayers[1] || i == displayplayers[2] || i == displayplayers[3])
|
||||||
{
|
{
|
||||||
// Draw display players on top of everything else
|
// Draw display players on top of everything else
|
||||||
|
|
@ -3647,10 +3651,6 @@ static void K_drawKartMinimap(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we know it's not a display player, handle non-local player exceptions.
|
|
||||||
if ((gametyperules & GTR_BUMPERS) && players[i].mo->health <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (players[i].hyudorotimer > 0)
|
if (players[i].hyudorotimer > 0)
|
||||||
{
|
{
|
||||||
if (!((players[i].hyudorotimer < TICRATE/2
|
if (!((players[i].hyudorotimer < TICRATE/2
|
||||||
|
|
@ -3862,19 +3862,22 @@ static void K_drawKartFinish(boolean finish)
|
||||||
|
|
||||||
//else -- 1/2p, scrolling FINISH
|
//else -- 1/2p, scrolling FINISH
|
||||||
{
|
{
|
||||||
INT32 x, xval, ox, interpx;
|
INT32 x, xval, ox, interpx, pwidth;
|
||||||
|
|
||||||
x = ((vid.width<<FRACBITS)/vid.dupx);
|
x = ((vid.width<<FRACBITS)/vid.dupx);
|
||||||
xval = (SHORT(kptodraw[pnum]->width)<<FRACBITS);
|
xval = (SHORT(kptodraw[pnum]->width)<<FRACBITS);
|
||||||
x = ((TICRATE - timer)*(xval > x ? xval : x))/TICRATE;
|
|
||||||
ox = ((TICRATE - (timer - 1))*(xval > x ? xval : x))/TICRATE;
|
pwidth = max(xval, x);
|
||||||
|
|
||||||
|
x = ((TICRATE - timer) * pwidth) / TICRATE;
|
||||||
|
ox = ((TICRATE - (timer - 1)) * pwidth) / TICRATE;
|
||||||
|
|
||||||
interpx = R_InterpolateFixed(ox, x);
|
interpx = R_InterpolateFixed(ox, x);
|
||||||
|
|
||||||
if (r_splitscreen && stplyr == &players[displayplayers[1]])
|
if (r_splitscreen && stplyr == &players[displayplayers[1]])
|
||||||
interpx = -interpx;
|
interpx = -interpx;
|
||||||
|
|
||||||
V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (xval>>1),
|
V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (pwidth / 2),
|
||||||
(STCD_Y<<FRACBITS) - (SHORT(kptodraw[pnum]->height)<<(FRACBITS-1)),
|
(STCD_Y<<FRACBITS) - (SHORT(kptodraw[pnum]->height)<<(FRACBITS-1)),
|
||||||
FRACUNIT,
|
FRACUNIT,
|
||||||
splitflags, kptodraw[pnum], NULL);
|
splitflags, kptodraw[pnum], NULL);
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
#include "core/static_vec.hpp"
|
#include "core/static_vec.hpp"
|
||||||
|
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_hud.h"
|
#include "k_hud.h"
|
||||||
|
#include "k_kart.h"
|
||||||
#include "k_objects.h"
|
#include "k_objects.h"
|
||||||
#include "m_fixed.h"
|
#include "m_fixed.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
|
@ -314,7 +314,7 @@ bool is_player_tracking_target(player_t *player = stplyr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battlecapsules || bossinfo.valid)
|
if (K_Cooperative())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -338,6 +338,23 @@ bool is_player_tracking_target(player_t *player = stplyr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->emeralds != 0 && K_IsPlayerWanted(stplyr))
|
||||||
|
{
|
||||||
|
// The player who is about to win because of emeralds
|
||||||
|
// gets a TARGET on them
|
||||||
|
if (K_NumEmeralds(player) == 6) // 6 out of 7
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WANTED player sees TARGETs on players holding
|
||||||
|
// emeralds
|
||||||
|
if (K_IsPlayerWanted(stplyr))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return K_IsPlayerWanted(player);
|
return K_IsPlayerWanted(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
39
src/k_kart.c
39
src/k_kart.c
|
|
@ -8290,30 +8290,14 @@ void K_KartPlayerAfterThink(player_t *player)
|
||||||
K_LookForRings(player->mo);
|
K_LookForRings(player->mo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->invulnhitlag > 0)
|
if (player->nullHitlag > 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))
|
if (!P_MobjWasRemoved(player->mo))
|
||||||
{
|
{
|
||||||
player->mo->hitlag -= player->invulnhitlag;
|
player->mo->hitlag -= player->nullHitlag;
|
||||||
player->mo->eflags &= ~(MFE_DAMAGEHITLAG);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
player->invulnhitlag = 0;
|
player->nullHitlag = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -11577,7 +11561,7 @@ UINT32 K_PointLimitForGametype(void)
|
||||||
return cv_pointlimit.value;
|
return cv_pointlimit.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battlecapsules || bossinfo.valid)
|
if (K_Cooperative())
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -11601,4 +11585,19 @@ UINT32 K_PointLimitForGametype(void)
|
||||||
return ptsCap;
|
return ptsCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean K_Cooperative(void)
|
||||||
|
{
|
||||||
|
if (battlecapsules)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bossinfo.valid)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,8 @@ void K_EggmanTransfer(player_t *source, player_t *victim);
|
||||||
tic_t K_TimeLimitForGametype(void);
|
tic_t K_TimeLimitForGametype(void);
|
||||||
UINT32 K_PointLimitForGametype(void);
|
UINT32 K_PointLimitForGametype(void);
|
||||||
|
|
||||||
|
boolean K_Cooperative(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -232,8 +232,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->spinouttimer);
|
lua_pushinteger(L, plr->spinouttimer);
|
||||||
else if (fastcmp(field,"instashield"))
|
else if (fastcmp(field,"instashield"))
|
||||||
lua_pushinteger(L, plr->instashield);
|
lua_pushinteger(L, plr->instashield);
|
||||||
else if (fastcmp(field,"invulnhitlag"))
|
else if (fastcmp(field,"nullHitlag"))
|
||||||
lua_pushinteger(L, plr->invulnhitlag);
|
lua_pushinteger(L, plr->nullHitlag);
|
||||||
else if (fastcmp(field,"wipeoutslow"))
|
else if (fastcmp(field,"wipeoutslow"))
|
||||||
lua_pushinteger(L, plr->wipeoutslow);
|
lua_pushinteger(L, plr->wipeoutslow);
|
||||||
else if (fastcmp(field,"justbumped"))
|
else if (fastcmp(field,"justbumped"))
|
||||||
|
|
@ -614,8 +614,8 @@ static int player_set(lua_State *L)
|
||||||
plr->spinouttimer = luaL_checkinteger(L, 3);
|
plr->spinouttimer = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"instashield"))
|
else if (fastcmp(field,"instashield"))
|
||||||
plr->instashield = luaL_checkinteger(L, 3);
|
plr->instashield = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"invulnhitlag"))
|
else if (fastcmp(field,"nullHitlag"))
|
||||||
plr->invulnhitlag = luaL_checkinteger(L, 3);
|
plr->nullHitlag = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"wipeoutslow"))
|
else if (fastcmp(field,"wipeoutslow"))
|
||||||
plr->wipeoutslow = luaL_checkinteger(L, 3);
|
plr->wipeoutslow = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"justbumped"))
|
else if (fastcmp(field,"justbumped"))
|
||||||
|
|
|
||||||
|
|
@ -167,12 +167,6 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
||||||
boolean tumbleitem = false;
|
boolean tumbleitem = false;
|
||||||
boolean sprung = false;
|
boolean sprung = false;
|
||||||
|
|
||||||
if ((orbinaut_selfdelay(t1) > 0 && t2->hitlag > 0)
|
|
||||||
|| (orbinaut_selfdelay(t2) > 0 && t1->hitlag > 0))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t1->health <= 0 || t2->health <= 0)
|
if (t1->health <= 0 || t2->health <= 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
101
src/p_inter.c
101
src/p_inter.c
|
|
@ -1382,7 +1382,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
P_PlayDeathSound(target);
|
P_PlayDeathSound(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battlecapsules || bossinfo.valid)
|
if (K_Cooperative())
|
||||||
{
|
{
|
||||||
target->player->pflags |= (PF_NOCONTEST|PF_ELIMINATED);
|
target->player->pflags |= (PF_NOCONTEST|PF_ELIMINATED);
|
||||||
}
|
}
|
||||||
|
|
@ -2003,6 +2003,43 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AddTimesHit(player_t *player)
|
||||||
|
{
|
||||||
|
const INT32 oldtimeshit = player->timeshit;
|
||||||
|
|
||||||
|
player->timeshit++;
|
||||||
|
|
||||||
|
// overflow prevention
|
||||||
|
if (player->timeshit < oldtimeshit)
|
||||||
|
{
|
||||||
|
player->timeshit = oldtimeshit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddNullHitlag(player_t *player, tic_t oldHitlag)
|
||||||
|
{
|
||||||
|
if (player == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
player->nullHitlag += (player->mo->hitlag - oldHitlag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Damages an object, which may or may not be a player.
|
/** Damages an object, which may or may not be a player.
|
||||||
* For melee attacks, source and inflictor are the same.
|
* For melee attacks, source and inflictor are the same.
|
||||||
*
|
*
|
||||||
|
|
@ -2023,6 +2060,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
||||||
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||||
{
|
{
|
||||||
player_t *player;
|
player_t *player;
|
||||||
|
player_t *playerInflictor;
|
||||||
boolean force = false;
|
boolean force = false;
|
||||||
|
|
||||||
INT32 laglength = 6;
|
INT32 laglength = 6;
|
||||||
|
|
@ -2080,9 +2118,6 @@ 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->eflags & MFE_PAUSED))
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target->flags2 & MF2_SKULLFLY)
|
if (target->flags2 & MF2_SKULLFLY)
|
||||||
|
|
@ -2101,20 +2136,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
}
|
}
|
||||||
|
|
||||||
player = target->player;
|
player = target->player;
|
||||||
|
playerInflictor = inflictor ? inflictor->player : NULL;
|
||||||
|
|
||||||
|
if (playerInflictor)
|
||||||
|
{
|
||||||
|
AddTimesHit(playerInflictor);
|
||||||
|
}
|
||||||
|
|
||||||
if (player) // Player is the target
|
if (player) // Player is the target
|
||||||
{
|
{
|
||||||
{
|
AddTimesHit(player);
|
||||||
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;
|
||||||
|
|
@ -2179,12 +2210,32 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
|
|
||||||
if (invincible && type != DMG_STUMBLE)
|
if (invincible && type != DMG_STUMBLE)
|
||||||
{
|
{
|
||||||
const INT32 oldhitlag = target->hitlag;
|
const INT32 oldHitlag = target->hitlag;
|
||||||
|
const INT32 oldHitlagInflictor = inflictor ? inflictor->hitlag : 0;
|
||||||
|
|
||||||
|
// Damage during hitlag should be a no-op
|
||||||
|
// for invincibility states because there
|
||||||
|
// are no flashing tics. If the damage is
|
||||||
|
// from a constant source, a deadlock
|
||||||
|
// would occur.
|
||||||
|
|
||||||
|
if (target->eflags & MFE_PAUSED)
|
||||||
|
{
|
||||||
|
player->timeshit--; // doesn't count
|
||||||
|
|
||||||
|
if (playerInflictor)
|
||||||
|
{
|
||||||
|
playerInflictor->timeshit--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
laglength = max(laglength / 2, 1);
|
laglength = max(laglength / 2, 1);
|
||||||
K_SetHitLagForObjects(target, inflictor, laglength, false);
|
K_SetHitLagForObjects(target, inflictor, laglength, false);
|
||||||
|
|
||||||
player->invulnhitlag += (target->hitlag - oldhitlag);
|
AddNullHitlag(player, oldHitlag);
|
||||||
|
AddNullHitlag(playerInflictor, oldHitlagInflictor);
|
||||||
|
|
||||||
if (player->timeshit > player->timeshitprev)
|
if (player->timeshit > player->timeshitprev)
|
||||||
{
|
{
|
||||||
|
|
@ -2214,6 +2265,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
allowcombo = false;
|
allowcombo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allowcombo == false && (target->eflags & MFE_PAUSED))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// DMG_EXPLODE excluded from flashtic checks to prevent dodging eggbox/SPB with weak spinout
|
// DMG_EXPLODE excluded from flashtic checks to prevent dodging eggbox/SPB with weak spinout
|
||||||
if ((target->hitlag == 0 || allowcombo == false) && player->flashing > 0 && type != DMG_EXPLODE && type != DMG_STUMBLE)
|
if ((target->hitlag == 0 || allowcombo == false) && player->flashing > 0 && type != DMG_EXPLODE && type != DMG_STUMBLE)
|
||||||
{
|
{
|
||||||
|
|
@ -2221,6 +2277,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
K_DoInstashield(player);
|
K_DoInstashield(player);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (target->flags2 & MF2_ALREADYHIT) // do not deal extra damage in the same tic
|
||||||
|
{
|
||||||
|
K_SetHitLagForObjects(target, inflictor, laglength, true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2263,7 +2324,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
|
|
||||||
K_TryHurtSoundExchange(target, source);
|
K_TryHurtSoundExchange(target, source);
|
||||||
|
|
||||||
|
if (K_Cooperative() == false)
|
||||||
|
{
|
||||||
K_BattleAwardHit(source->player, player, inflictor, damage);
|
K_BattleAwardHit(source->player, player, inflictor, damage);
|
||||||
|
}
|
||||||
|
|
||||||
K_TakeBumpersFromPlayer(source->player, player, damage);
|
K_TakeBumpersFromPlayer(source->player, player, damage);
|
||||||
|
|
||||||
if (damagetype & DMG_STEAL)
|
if (damagetype & DMG_STEAL)
|
||||||
|
|
@ -2397,6 +2462,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
|
|
||||||
K_SetHitLagForObjects(target, inflictor, laglength, true);
|
K_SetHitLagForObjects(target, inflictor, laglength, true);
|
||||||
|
|
||||||
|
target->flags2 |= MF2_ALREADYHIT;
|
||||||
|
|
||||||
if (target->health <= 0)
|
if (target->health <= 0)
|
||||||
{
|
{
|
||||||
P_KillMobj(target, inflictor, source, damagetype);
|
P_KillMobj(target, inflictor, source, damagetype);
|
||||||
|
|
|
||||||
|
|
@ -956,6 +956,8 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
|| tm.thing->type == MT_BANANA || tm.thing->type == MT_EGGMANITEM || tm.thing->type == MT_BALLHOG
|
|| tm.thing->type == MT_BANANA || tm.thing->type == MT_EGGMANITEM || tm.thing->type == MT_BALLHOG
|
||||||
|| tm.thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || tm.thing->type == MT_SINK
|
|| tm.thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || tm.thing->type == MT_SINK
|
||||||
|| tm.thing->type == MT_GARDENTOP
|
|| tm.thing->type == MT_GARDENTOP
|
||||||
|
|| tm.thing->type == MT_MONITOR
|
||||||
|
|| tm.thing->type == MT_BATTLECAPSULE
|
||||||
|| (tm.thing->type == MT_PLAYER)))
|
|| (tm.thing->type == MT_PLAYER)))
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
|
|
@ -971,6 +973,8 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
||||||
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|
||||||
|| thing->type == MT_SSMINE || thing->type == MT_LANDMINE || thing->type == MT_SINK
|
|| thing->type == MT_SSMINE || thing->type == MT_LANDMINE || thing->type == MT_SINK
|
||||||
|| thing->type == MT_GARDENTOP
|
|| thing->type == MT_GARDENTOP
|
||||||
|
|| thing->type == MT_MONITOR
|
||||||
|
|| thing->type == MT_BATTLECAPSULE
|
||||||
|| (thing->type == MT_PLAYER)))
|
|| (thing->type == MT_PLAYER)))
|
||||||
{
|
{
|
||||||
// see if it went over / under
|
// see if it went over / under
|
||||||
|
|
|
||||||
|
|
@ -8246,7 +8246,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
desty = mobj->target->y;
|
desty = mobj->target->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mobj->flags &= ~(MF_NOCLIPTHING);
|
||||||
P_MoveOrigin(mobj, destx, desty, mobj->target->z);
|
P_MoveOrigin(mobj, destx, desty, mobj->target->z);
|
||||||
|
mobj->flags |= MF_NOCLIPTHING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MT_FLAMESHIELD:
|
case MT_FLAMESHIELD:
|
||||||
|
|
@ -9842,8 +9844,10 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<<mobj->spawnpoint->args[0])))
|
if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<<mobj->spawnpoint->args[0])))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mobj->flags2 &= ~(MF2_ALREADYHIT);
|
||||||
|
|
||||||
// Don't run any thinker code while in hitlag
|
// Don't run any thinker code while in hitlag
|
||||||
if (mobj->hitlag > 0)
|
if ((mobj->player ? mobj->hitlag - mobj->player->nullHitlag : mobj->hitlag) > 0)
|
||||||
{
|
{
|
||||||
mobj->eflags |= MFE_PAUSED;
|
mobj->eflags |= MFE_PAUSED;
|
||||||
mobj->hitlag--;
|
mobj->hitlag--;
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ typedef enum
|
||||||
MF2_JUSTATTACKED = 1<<16, // can be pushed by other moving mobjs
|
MF2_JUSTATTACKED = 1<<16, // can be pushed by other moving mobjs
|
||||||
MF2_FIRING = 1<<17, // turret fire
|
MF2_FIRING = 1<<17, // turret fire
|
||||||
MF2_SUPERFIRE = 1<<18, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
|
MF2_SUPERFIRE = 1<<18, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
|
||||||
// free: 1<<19
|
MF2_ALREADYHIT = 1<<19, // This object was already damaged THIS tic, resets even during hitlag
|
||||||
MF2_STRONGBOX = 1<<20, // Flag used for "strong" random monitors.
|
MF2_STRONGBOX = 1<<20, // Flag used for "strong" random monitors.
|
||||||
MF2_OBJECTFLIP = 1<<21, // Flag for objects that always have flipped gravity.
|
MF2_OBJECTFLIP = 1<<21, // Flag for objects that always have flipped gravity.
|
||||||
MF2_SKULLFLY = 1<<22, // Special handling: skull in flight.
|
MF2_SKULLFLY = 1<<22, // Special handling: skull in flight.
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
WRITEUINT16(save->p, players[i].spinouttimer);
|
WRITEUINT16(save->p, players[i].spinouttimer);
|
||||||
WRITEUINT8(save->p, players[i].spinouttype);
|
WRITEUINT8(save->p, players[i].spinouttype);
|
||||||
WRITEUINT8(save->p, players[i].instashield);
|
WRITEUINT8(save->p, players[i].instashield);
|
||||||
WRITEINT32(save->p, players[i].invulnhitlag);
|
WRITEINT32(save->p, players[i].nullHitlag);
|
||||||
WRITEUINT8(save->p, players[i].wipeoutslow);
|
WRITEUINT8(save->p, players[i].wipeoutslow);
|
||||||
WRITEUINT8(save->p, players[i].justbumped);
|
WRITEUINT8(save->p, players[i].justbumped);
|
||||||
WRITEUINT8(save->p, players[i].tumbleBounces);
|
WRITEUINT8(save->p, players[i].tumbleBounces);
|
||||||
|
|
@ -651,7 +651,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
players[i].spinouttimer = READUINT16(save->p);
|
players[i].spinouttimer = READUINT16(save->p);
|
||||||
players[i].spinouttype = READUINT8(save->p);
|
players[i].spinouttype = READUINT8(save->p);
|
||||||
players[i].instashield = READUINT8(save->p);
|
players[i].instashield = READUINT8(save->p);
|
||||||
players[i].invulnhitlag = READINT32(save->p);
|
players[i].nullHitlag = READINT32(save->p);
|
||||||
players[i].wipeoutslow = READUINT8(save->p);
|
players[i].wipeoutslow = READUINT8(save->p);
|
||||||
players[i].justbumped = READUINT8(save->p);
|
players[i].justbumped = READUINT8(save->p);
|
||||||
players[i].tumbleBounces = READUINT8(save->p);
|
players[i].tumbleBounces = READUINT8(save->p);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue