Partial damage system overhaul: P_DamageMobj, P_KillMobj, P_HitDeathMessages and P_RingDamage now all take a "damagetype" variable that determines what type of damage was dealt. Does not replace the "damage" variable, we'll have to see if that is worth keeping another time?

Currently the main benefit of these changes is that a number of non-Object-related hazards/deaths no long rely on dummy MT_NULL objects or other hacks to tell the game how you were hurt/killed, yay

git-svn-id: https://code.orospakr.ca/svn/srb2/trunk@9039 6de4a73c-47e2-0310-b8c1-93d6ecd3f8cd
This commit is contained in:
MonsterIestyn 2015-02-13 16:15:58 +00:00 committed by Ronald Kinard
parent ff8c09922d
commit e83fa3dc43
13 changed files with 226 additions and 188 deletions

View File

@ -1911,7 +1911,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
}
if (players[suicideplayer].mo)
P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 10000);
P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 1, DMG_INSTAKILL);
}
/** Deals with an ::XD_RANDOMSEED message in a netgame.
@ -2442,7 +2442,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
if (players[playernum].mo)
{
if (!players[playernum].spectator)
P_DamageMobj(players[playernum].mo, NULL, NULL, 10000);
P_DamageMobj(players[playernum].mo, NULL, NULL, 1, DMG_INSTAKILL);
else
{
P_RemoveMobj(players[playernum].mo);

View File

@ -4134,7 +4134,7 @@ void G_ConsGhostTic(void)
if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
P_DamageMobj(mobj, players[0].mo, players[0].mo, 1);
P_DamageMobj(mobj, players[0].mo, players[0].mo, 1, 0);
}
}
}

View File

@ -1037,6 +1037,7 @@ static int lib_pDamageMobj(lua_State *L)
{
mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL;
INT32 damage;
UINT8 damagetype;
NOHUD
if (!target)
return LUA_ErrInvalid(L, "mobj_t");
@ -1045,13 +1046,15 @@ static int lib_pDamageMobj(lua_State *L)
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
damage = (INT32)luaL_optinteger(L, 4, 1);
lua_pushboolean(L, P_DamageMobj(target, inflictor, source, damage));
damagetype = (UINT8)luaL_optinteger(L, 5, 0);
lua_pushboolean(L, P_DamageMobj(target, inflictor, source, damage, damagetype));
return 1;
}
static int lib_pKillMobj(lua_State *L)
{
mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL;
UINT8 damagetype;
NOHUD
if (!target)
return LUA_ErrInvalid(L, "mobj_t");
@ -1059,7 +1062,8 @@ static int lib_pKillMobj(lua_State *L)
inflictor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
P_KillMobj(target, inflictor, source);
damagetype = (UINT8)luaL_optinteger(L, 4, 0);
P_KillMobj(target, inflictor, source, damagetype);
return 0;
}

View File

@ -372,7 +372,7 @@ void Command_Hurtme_f(void)
return;
}
P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1)));
P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1)), 0);
}
// Moves the NiGHTS player to another axis within the current mare

View File

@ -4813,7 +4813,7 @@ void A_UnidusBall(mobj_t *actor)
boolean skull = (actor->target->flags2 & MF2_SKULLFLY) == MF2_SKULLFLY;
if (actor->target->state == &states[actor->target->info->painstate])
{
P_KillMobj(actor, NULL, NULL);
P_KillMobj(actor, NULL, NULL, 0);
return;
}
switch(actor->extravalue2)
@ -5278,7 +5278,7 @@ void A_RingExplode(mobj_t *actor)
if (mo2->flags & MF_SHOOTABLE)
{
actor->flags2 |= MF2_DEBRIS;
P_DamageMobj(mo2, actor, actor->target, 1);
P_DamageMobj(mo2, actor, actor->target, 1, 0);
continue;
}
}
@ -6383,7 +6383,7 @@ void A_EggmanBox(mobj_t *actor)
return;
}
P_DamageMobj(actor->target, actor, actor, 1); // Ow!
P_DamageMobj(actor->target, actor, actor, 1, 0); // Ow!
}
// Function: A_TurretFire
@ -9368,9 +9368,9 @@ void A_RemoteDamage(mobj_t *actor)
if (locvar2 == 1) // Kill mobj!
{
if (target->player) // players die using P_DamageMobj instead for some reason
P_DamageMobj(target, source, source, 10000);
P_DamageMobj(target, source, source, 1, DMG_INSTAKILL);
else
P_KillMobj(target, source, source);
P_KillMobj(target, source, source, 0);
}
else if (locvar2 == 2) // Remove mobj!
{
@ -9380,7 +9380,7 @@ void A_RemoteDamage(mobj_t *actor)
P_RemoveMobj(target);
}
else // default: Damage mobj!
P_DamageMobj(target, source, source, 1);
P_DamageMobj(target, source, source, 1, 0);
}
// Function: A_HomingChase
@ -9615,7 +9615,7 @@ void A_VileAttack(mobj_t *actor)
return;
S_StartSound(actor, soundtoplay);
P_DamageMobj(actor->target, actor, actor, 1);
P_DamageMobj(actor->target, actor, actor, 1, 0);
//actor->target->momz = 1000*FRACUNIT/actor->target->info->mass; // How id did it
actor->target->momz += FixedMul(10*FRACUNIT, actor->scale)*P_MobjFlip(actor->target); // How we're doing it
if (explosionType != MT_NULL)
@ -9656,7 +9656,7 @@ void A_VileAttack(mobj_t *actor)
continue;
S_StartSound(actor, soundtoplay);
P_DamageMobj(players[i].mo, actor, actor, 1);
P_DamageMobj(players[i].mo, actor, actor, 1, 0);
//actor->target->momz = 1000*FRACUNIT/actor->target->info->mass; // How id did it
players[i].mo->momz += FixedMul(10*FRACUNIT, actor->scale)*P_MobjFlip(players[i].mo); // How we're doing it
if (explosionType != MT_NULL)

View File

@ -1215,9 +1215,7 @@ void T_SpikeSector(levelspecthink_t *spikes)
if (dothepain)
{
mobj_t *killer = P_SpawnMobj(thing->x, thing->y, thing->z, MT_NULL);
killer->threshold = 43; // Special flag that it was spikes which hurt you.
P_DamageMobj(thing, killer, killer, 1);
P_DamageMobj(thing, NULL, NULL, 1, DMG_SPIKE);
break;
}
}
@ -3125,7 +3123,7 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
thing->momz = FixedMul(6*FRACUNIT, thing->scale);
P_SetThingPosition(thing);
if (thing->flags & MF_SHOOTABLE)
P_DamageMobj(thing, puncher, puncher, 1);
P_DamageMobj(thing, puncher, puncher, 1, 0);
else if (thing->type == MT_RING || thing->type == MT_COIN)
{
thing->momz = FixedMul(3*FRACUNIT, thing->scale);

View File

@ -291,7 +291,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
if (special->type == MT_BLACKEGGMAN)
{
P_DamageMobj(toucher, special, special, 1); // ouch
P_DamageMobj(toucher, special, special, 1, 0); // ouch
return;
}
@ -303,7 +303,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
toucher->momz = -toucher->momz;
toucher->momx = -toucher->momx;
toucher->momy = -toucher->momy;
P_DamageMobj(special, toucher, toucher, 1);
P_DamageMobj(special, toucher, toucher, 1, 0);
}
else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP))
|| (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP)))
@ -313,10 +313,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
toucher->momz = -toucher->momz/2;
P_DamageMobj(special, toucher, toucher, 1);
P_DamageMobj(special, toucher, toucher, 1, 0);
}
else
P_DamageMobj(toucher, special, special, 1);
P_DamageMobj(toucher, special, special, 1, 0);
return;
}
@ -330,13 +330,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
&& toucher->z < special->z + special->height && toucher->z + toucher->height > special->z)
{
// Can only hit snapper from above
P_DamageMobj(toucher, special, special, 1);
P_DamageMobj(toucher, special, special, 1, 0);
}
else if (special->type == MT_SHARP
&& ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2)))
{
// Cannot hit sharp from above or when red and angry
P_DamageMobj(toucher, special, special, 1);
P_DamageMobj(toucher, special, special, 1, 0);
}
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
@ -345,7 +345,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (P_MobjFlip(toucher)*toucher->momz < 0)
toucher->momz = -toucher->momz;
P_DamageMobj(special, toucher, toucher, 1);
P_DamageMobj(special, toucher, toucher, 1, 0);
}
else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP))
|| (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP))) // Flame is bad at logic - JTE
@ -356,16 +356,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (P_MobjFlip(toucher)*toucher->momz < 0)
toucher->momz = -toucher->momz/2;
P_DamageMobj(special, toucher, toucher, 1);
P_DamageMobj(special, toucher, toucher, 1, 0);
}
else
P_DamageMobj(toucher, special, special, 1);
P_DamageMobj(toucher, special, special, 1, 0);
return;
}
else if (special->flags & MF_FIRE)
{
P_DamageMobj(toucher, special, special, 1);
P_DamageMobj(toucher, special, special, 1, DMG_FIRE);
return;
}
else
@ -743,7 +743,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (mo2->flags & MF_SHOOTABLE)
{
P_DamageMobj(mo2, toucher, toucher, 1);
P_DamageMobj(mo2, toucher, toucher, 1, 0);
continue;
}
@ -1351,7 +1351,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_SPECIALSPIKEBALL:
if (!(!useNightsSS && G_IsSpecialStage(gamemap))) // Only for old special stages
{
P_DamageMobj(toucher, special, special, 1);
P_DamageMobj(toucher, special, special, 1, 0);
return;
}
@ -1382,7 +1382,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// Goomba Stomp'd!
if (special->target->momz < 0)
{
P_DamageMobj(toucher, special, special->target, 1);
P_DamageMobj(toucher, special, special->target, 1, 0);
//special->target->momz = -special->target->momz;
special->target->momx = special->target->momy = 0;
special->target->momz = 0;
@ -1446,7 +1446,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings
P_KillMobj(special, NULL, toucher);
P_KillMobj(special, NULL, toucher, 0);
}
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
@ -1457,8 +1457,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
* \param player Affected player.
* \param inflictor The attack weapon used, can be NULL.
* \param source The attacker, can be NULL.
* \param damagetype The type of damage dealt to the player. If bit 7 (0x80) is set, this was an instant-kill.
*/
static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *source)
static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
{
const char *str = NULL;
boolean deathonly = false;
@ -1567,22 +1568,6 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
}
else switch (source->type)
{
case MT_NULL:
switch(source->threshold)
{
case 42:
deathonly = true;
str = M_GetText("%s drowned.\n");
break;
case 43:
str = M_GetText("%s was %s by spikes.\n");
break;
case 44:
deathonly = true;
str = M_GetText("%s was crushed.\n");
break;
}
break;
case MT_EGGMANICO:
case MT_EGGMANBOX:
str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n");
@ -1598,30 +1583,52 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
else
{
// null source, environment kills
// TERRIBLE HACK for hit damage because P_DoPlayerPain moves the player...
// I'll put it back, I promise!
player->mo->z -= player->mo->momz+1;
if (P_PlayerTouchingSectorSpecial(player, 1, 2))
str = M_GetText("%s was %s by chemical water.\n");
else if (P_PlayerTouchingSectorSpecial(player, 1, 3))
str = M_GetText("%s was %s by molten lava.\n");
else if (P_PlayerTouchingSectorSpecial(player, 1, 4))
str = M_GetText("%s was %s by electricity.\n");
else if (deadtarget)
switch (damagetype)
{
deathonly = true;
if (P_PlayerTouchingSectorSpecial(player, 1, 6)
|| P_PlayerTouchingSectorSpecial(player, 1, 7))
str = M_GetText("%s fell into a bottomless pit.\n");
else if (P_PlayerTouchingSectorSpecial(player, 1, 12))
str = M_GetText("%s asphyxiated in space.\n");
else
str = M_GetText("%s died.\n");
case DMG_WATER:
str = M_GetText("%s was %s by chemical water.\n");
break;
case DMG_FIRE:
str = M_GetText("%s was %s by molten lava.\n");
break;
case DMG_ELECTRIC:
str = M_GetText("%s was %s by electricity.\n");
break;
case DMG_SPIKE:
str = M_GetText("%s was %s by spikes.\n");
break;
case DMG_DROWNED:
deathonly = true;
str = M_GetText("%s drowned.\n");
break;
case DMG_CRUSHED:
deathonly = true;
str = M_GetText("%s was crushed.\n");
break;
case DMG_DEATHPIT:
if (deadtarget)
{
deathonly = true;
str = M_GetText("%s fell into a bottomless pit.\n");
}
break;
case DMG_SPACEDROWN:
if (deadtarget)
{
deathonly = true;
str = M_GetText("%s asphyxiated in space.\n");
}
break;
default:
if (deadtarget)
{
deathonly = true;
str = M_GetText("%s died.\n");
}
break;
}
if (!str)
str = M_GetText("%s was %s by an environmental hazard.\n");
player->mo->z += player->mo->momz+1;
}
if (!str) // Should not happen! Unless we missed catching something above.
@ -1799,10 +1806,11 @@ boolean P_CheckRacers(void)
* \param target The victim.
* \param inflictor The attack weapon. May be NULL (environmental damage).
* \param source The attacker. May be NULL.
* \param damagetype The type of damage dealt that killed the target. If bit 7 (0x80) was set, this was an instant-death.
* \todo Cleanup, refactor, split up.
* \sa P_DamageMobj
*/
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
{
mobjtype_t item;
mobj_t *mo;
@ -2126,15 +2134,19 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
case MT_PLAYER:
target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player)
target->momx = target->momy = target->momz = 0;
if (!(source && source->type == MT_NULL && source->threshold == 42)) // Don't jump up when drowning
P_SetObjectMomZ(target, 14*FRACUNIT, false);
if (source && source->type == MT_NULL && source->threshold == 42) // drowned
if (damagetype == DMG_DROWNED) // drowned
{
S_StartSound(target, sfx_drown);
else if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // Spikes
S_StartSound(target, sfx_spkdth);
// Don't jump up when drowning
}
else
P_PlayDeathSound(target);
{
P_SetObjectMomZ(target, 14*FRACUNIT, false);
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes
S_StartSound(target, sfx_spkdth);
else
P_PlayDeathSound(target);
}
break;
default:
break;
@ -2384,7 +2396,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
{
P_AddPlayerScore(source->player, 100); //award points to tagger.
P_HitDeathMessages(player, inflictor, source);
P_HitDeathMessages(player, inflictor, source, 0);
if (gametype == GT_TAG) //survivor
{
@ -2640,7 +2652,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
}
}
static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{
if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
{
@ -2648,7 +2660,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
S_StartSound(player->mo, sfx_spkdth);
}
@ -2677,21 +2689,21 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
/** Damages an object, which may or may not be a player.
* For melee attacks, source and inflictor are the same.
*
* \param target The object being damaged.
* \param inflictor The thing that caused the damage: creature, missile,
* gargoyle, and so forth. Can be NULL in the case of
* environmental damage, such as slime or crushing.
* \param source The creature or person responsible. For example, if a
* player is hit by a ring, the player who shot it. In some
* cases, the target will go after this object after
* receiving damage. This can be NULL.
* \param damage Amount of damage to be dealt. 10000 is instant death.
* \param target The object being damaged.
* \param inflictor The thing that caused the damage: creature, missile,
* gargoyle, and so forth. Can be NULL in the case of
* environmental damage, such as slime or crushing.
* \param source The creature or person responsible. For example, if a
* player is hit by a ring, the player who shot it. In some
* cases, the target will go after this object after
* receiving damage. This can be NULL.
* \param damage Amount of damage to be dealt.
* \param damagetype Type of damage to be dealt. If bit 7 (0x80) is set, this is an instant-kill.
* \return True if the target sustained damage, otherwise false.
* \todo Clean up this mess, split into multiple functions.
* \todo Get rid of the magic number 10000.
* \sa P_KillMobj
*/
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{
player_t *player;
#ifdef HAVE_BLUA
@ -2709,9 +2721,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Spectator handling
if (netgame)
{
if (damage == 42000 && target->player && target->player->spectator)
damage = 10000;
else if (target->player && target->player->spectator)
if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
return false;
if (source && source->player && source->player->spectator)
@ -2819,6 +2829,21 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS))
return false;
switch (damagetype)
{
case DMG_WATER:
case DMG_FIRE:
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
return false; // Invincible to water/fire damage
break;
case DMG_ELECTRIC:
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)
return false; // Invincible to electric damage
break;
default:
break;
}
}
if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling
@ -2840,12 +2865,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true;
}
if (!force && inflictor && (inflictor->flags & MF_FIRE))
if (!force && inflictor && inflictor->flags & MF_FIRE)
{
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
return false; // Invincible to fire objects
if (G_PlatformGametype() && source && source->player)
if (G_PlatformGametype() && inflictor && source && source->player)
return false; // Don't get hurt by fire generated from friends.
}
@ -2854,7 +2879,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
{
if ((gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) && cv_suddendeath.value
&& !player->powers[pw_flashing] && !player->powers[pw_invulnerability])
damage = 10000;
damagetype = DMG_INSTAKILL;
}
// Player hits another player
@ -2868,7 +2893,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// Instant-Death
if (damage == 10000)
if (damagetype & DMG_DEATHMASK)
P_KillPlayer(player, source, damage);
else if (metalrecording)
{
@ -2876,7 +2901,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
inflictor = source;
if (inflictor && inflictor->flags & MF_ENEMY)
{ // Metal Sonic destroy enemy !!
P_KillMobj(inflictor, NULL, target);
P_KillMobj(inflictor, NULL, target, damagetype);
return false;
}
else if (inflictor && inflictor->flags & MF_MISSILE)
@ -2915,7 +2940,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
else if (player->mo->health > 1) // No shield but have rings.
{
damage = player->mo->health - 1;
P_RingDamage(player, inflictor, source, damage);
P_RingDamage(player, inflictor, source, damage, damagetype);
}
else // No shield, no rings, no invincibility.
{
@ -2952,21 +2977,20 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
P_PlayerFlagBurst(player, false);
}
else if (damagetype & DMG_DEATHMASK)
player->health = 0;
else
{
player->health -= damage; // mirror mobj health here
if (damage < 10000)
{
target->player->powers[pw_flashing] = flashingtics;
if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
P_PlayerRingBurst(player, damage);
}
target->player->powers[pw_flashing] = flashingtics;
if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
P_PlayerRingBurst(player, damage);
}
if (player->health < 0)
player->health = 0;
P_HitDeathMessages(player, inflictor, source);
P_HitDeathMessages(player, inflictor, source, damagetype);
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
}
@ -2974,7 +2998,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Killing dead. Just for kicks.
// Require source and inflictor be player. Don't hurt for firing rings.
if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_Random() < 80)
P_DamageMobj(source, target, target, 1);
P_DamageMobj(source, target, target, 1, 0);
// do the damage
if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player))
@ -2983,6 +3007,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (target->health < 2)
target->health = 2;
}
else if (damagetype & DMG_DEATHMASK)
target->health = 0;
else
target->health -= damage;
@ -2991,7 +3017,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (target->health <= 0)
{
P_KillMobj(target, inflictor, source);
P_KillMobj(target, inflictor, source, damagetype);
return true;
}

View File

@ -342,12 +342,29 @@ typedef struct BasicFF_s
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
} BasicFF_t;
/* Damage/death types, for P_DamageMobj and related */
//// Damage types
//#define DMG_NORMAL 0 (unneeded?)
#define DMG_WATER 1
#define DMG_FIRE 2
#define DMG_ELECTRIC 3
#define DMG_SPIKE 4
//#define DMG_SPECIALSTAGE 5
//// Death types - cannot be combined with damage types
#define DMG_INSTAKILL 0x80
#define DMG_DROWNED 0x80+1
#define DMG_SPACEDROWN 0x80+2
#define DMG_DEATHPIT 0x80+3
#define DMG_CRUSHED 0x80+4
#define DMG_SPECTATOR 0x80+5
#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period);
void P_ForceConstant(const BasicFF_t *FFInfo);
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End);
void P_RemoveShield(player_t *player);
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage);
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source);
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c
void P_PlayerWeaponPanelBurst(player_t *player);
void P_PlayerWeaponAmmoBurst(player_t *player);

View File

@ -426,12 +426,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
S_StartSound(tmthing, thing->info->deathsound);
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
P_KillMobj(thing, tmthing, tmthing);
P_KillMobj(thing, tmthing, tmthing, 0);
}
else
{
thing->health = 0;
P_KillMobj(thing, tmthing, tmthing);
P_KillMobj(thing, tmthing, tmthing, 0);
}
return true;
}
@ -483,7 +483,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
else
thing->z = tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale);
if (thing->flags & MF_SHOOTABLE)
P_DamageMobj(thing, tmthing, tmthing, 1);
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
return true;
}
@ -495,7 +495,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z + thing->height < tmthing->z)
return true; // underneath
if (tmthing->player && tmthing->flags & MF_SHOOTABLE)
P_DamageMobj(tmthing, thing, thing, 1);
{
UINT8 damagetype = 0;
if (thing->flags & MF_FIRE) // BURN!
damagetype = DMG_FIRE;
P_DamageMobj(tmthing, thing, thing, 1, damagetype);
}
return true;
}
else if (tmthing->flags & MF_PAIN)
@ -506,7 +511,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (thing->player && thing->flags & MF_SHOOTABLE)
P_DamageMobj(thing, tmthing, tmthing, 1);
{
UINT8 damagetype = 0;
if (tmthing->flags & MF_FIRE) // BURN!
damagetype = DMG_FIRE;
P_DamageMobj(thing, tmthing, tmthing, 1, damagetype);
}
return true;
}
@ -627,7 +637,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return false;
else // hit shield from behind, shield is destroyed!
{
P_KillMobj(thing, tmthing, tmthing);
P_KillMobj(thing, tmthing, tmthing, 0);
return false;
}
}
@ -636,7 +646,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
// damage / explode
if (tmthing->flags & MF_ENEMY) // An actual ENEMY! (Like the deton, for example)
P_DamageMobj(thing, tmthing, tmthing, 1);
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player
&& (thing->player->pflags & PF_JUMPED)
&& !thing->player->powers[pw_flashing]
@ -672,7 +682,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
P_SetThingPosition(tmthing);
}
else
P_DamageMobj(thing, tmthing, tmthing->target, 1);
P_DamageMobj(thing, tmthing, tmthing->target, 1, 0);
// don't traverse any more
@ -786,11 +796,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale)
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz)
P_DamageMobj(thing, tmthing, tmthing, 1);
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
}
else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale)
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz)
P_DamageMobj(thing, tmthing, tmthing, 1);
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
}
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
{
@ -798,11 +808,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale))
P_DamageMobj(tmthing, thing, thing, 1);
P_DamageMobj(tmthing, thing, thing, 1, 0);
}
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale))
P_DamageMobj(tmthing, thing, thing, 1);
P_DamageMobj(tmthing, thing, thing, 1, 0);
}
if (thing->flags & MF_PUSHABLE)
@ -832,10 +842,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super])
&& !thing->player->powers[pw_super])
P_DamageMobj(thing, tmthing, tmthing, 1);
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
else if ((thing->player->powers[pw_invulnerability] || thing->player->powers[pw_super])
&& !tmthing->player->powers[pw_super])
P_DamageMobj(tmthing, thing, thing, 1);
P_DamageMobj(tmthing, thing, thing, 1, 0);
}
// If players are using touch tag, seekers damage hiders.
@ -843,9 +853,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
((thing->player->pflags & PF_TAGIT) != (tmthing->player->pflags & PF_TAGIT)))
{
if ((tmthing->player->pflags & PF_TAGIT) && !(thing->player->pflags & PF_TAGIT))
P_DamageMobj(thing, tmthing, tmthing, 1);
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
else if ((thing->player->pflags & PF_TAGIT) && !(tmthing->player->pflags & PF_TAGIT))
P_DamageMobj(tmthing, thing, tmthing, 1);
P_DamageMobj(tmthing, thing, tmthing, 1, 0);
}
}
@ -883,7 +893,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
// Objects kill you if it falls from above.
if (thing != tmthing->target)
P_DamageMobj(thing, tmthing, tmthing->target, 10000);
P_DamageMobj(thing, tmthing, tmthing->target, 1, DMG_INSTAKILL);
tmthing->momz = -tmthing->momz/2; // Bounce, just for fun!
// The tmthing->target allows the pusher of the object
@ -917,7 +927,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
P_DamageMobj(thing, tmthing, tmthing, 1); // break the monitor
P_DamageMobj(thing, tmthing, tmthing, 1, 0); // break the monitor
// Going down? Then bounce back up.
if ((P_MobjWasRemoved(thing) // Monitor was removed
|| !thing->health) // or otherwise popped
@ -3007,7 +3017,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
if (P_CheckSight(thing, bombspot))
{ // must be in direct path
P_DamageMobj(thing, bombspot, bombsource, 1); // Tails 01-11-2001
P_DamageMobj(thing, bombspot, bombsource, 1, 0); // Tails 01-11-2001
}
return true;
@ -3140,22 +3150,15 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
{
// Crush the object
if (netgame && thing->player && thing->player->spectator)
P_DamageMobj(thing, NULL, NULL, 42000); // Respawn crushed spectators
P_DamageMobj(thing, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
{
if (!killer)
{
//Nobody is responsible for crushing the object, so give a generic crush message
killer = P_SpawnMobj(thing->x, thing->y, thing->z, MT_NULL);
killer->threshold = 44; // Special flag for crushing
}
P_DamageMobj(thing, killer, killer, 10000);
}
P_DamageMobj(thing, killer, killer, 1, DMG_CRUSHED);
return true;
}
}
if (realcrush && crushchange)
P_DamageMobj(thing, NULL, NULL, 1);
P_DamageMobj(thing, NULL, NULL, 1, 0);
// keep checking (crush other things)
return true;

View File

@ -712,7 +712,7 @@ void P_ExplodeMissile(mobj_t *mo)
S_StartSound(explodemo, sfx_cybdth);
// Hack: Release an animal.
P_DamageMobj(mo, NULL, NULL, 10000);
P_DamageMobj(mo, NULL, NULL, 1, DMG_INSTAKILL);
}
mo->flags &= ~MF_MISSILE;
@ -1744,7 +1744,7 @@ static boolean P_ZMovement(mobj_t *mo)
// Kill enemies and bosses that fall into death pits.
if (mo->health)
{
P_KillMobj(mo, NULL, NULL);
P_KillMobj(mo, NULL, NULL, 0);
return false;
}
}
@ -2800,7 +2800,7 @@ void P_DestroyRobots(void)
continue;
// Found a target enemy
P_KillMobj(mo, players[consoleplayer].mo, players[consoleplayer].mo);
P_KillMobj(mo, players[consoleplayer].mo, players[consoleplayer].mo, 0);
}
}
@ -3481,7 +3481,7 @@ static void P_Boss3Thinker(mobj_t *mobj)
continue;
if (players[i].mo->eflags & MFE_UNDERWATER)
P_DamageMobj(players[i].mo, mobj, mobj, 1);
P_DamageMobj(players[i].mo, mobj, mobj, 1, 0);
}
// Make the water flash
@ -3822,7 +3822,7 @@ static void P_Boss4PopSpikeballs(mobj_t *mobj)
P_SetTarget(&base->tracer, NULL);
for (seg = base; seg; seg = seg->hnext)
if (seg->health)
P_KillMobj(seg, NULL, NULL);
P_KillMobj(seg, NULL, NULL, 0);
base = next;
}
}
@ -4122,7 +4122,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
{
INT32 i;
P_KillMobj(mobj, NULL, NULL);
P_KillMobj(mobj, NULL, NULL, 0);
// It was a team effort
for (i = 0; i < MAXPLAYERS; i++)
@ -4173,7 +4173,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
&& players[i].mo->z < mobj->z + mobj->height + 128*FRACUNIT) // You can't be in the vicinity, either...
{
// Punch him!
P_DamageMobj(players[i].mo, mobj, mobj, 1);
P_DamageMobj(players[i].mo, mobj, mobj, 1, 0);
mobj->state->nextstate = mobj->info->spawnstate;
// Laugh
@ -4396,7 +4396,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
if (players[i].mo->z < mobj->z - 64*FRACUNIT)
continue;
P_DamageMobj(players[i].mo, mobj, mobj, 1);
P_DamageMobj(players[i].mo, mobj, mobj, 1, 0);
// Laugh
S_StartSound(0, sfx_bewar1 + P_RandomKey(4));
@ -5818,7 +5818,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL
&& (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
{
P_KillMobj(mobj, NULL, NULL);
P_KillMobj(mobj, NULL, NULL, 0);
return;
}
}
@ -6450,7 +6450,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL
&& (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
{
P_KillMobj(mobj, NULL, NULL);
P_KillMobj(mobj, NULL, NULL, 0);
return;
}
break;
@ -6699,7 +6699,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health
&& P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz
{
P_KillMobj(mobj, NULL, NULL);
P_KillMobj(mobj, NULL, NULL, DMG_DEATHPIT);
return;
}
@ -6713,7 +6713,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
&& !(mobj->flags & MF_NOCLIPHEIGHT)
&& mobj->health > 0)
{
P_KillMobj(mobj, NULL, NULL);
P_KillMobj(mobj, NULL, NULL, DMG_CRUSHED);
return;
}
}

View File

@ -3472,19 +3472,19 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
{
case 1: // Damage (Generic)
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, 1);
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
break;
case 2: // Damage (Water)
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
P_DamageMobj(player->mo, NULL, NULL, 1);
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE))
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_WATER);
break;
case 3: // Damage (Fire)
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
P_DamageMobj(player->mo, NULL, NULL, 1);
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_FIRE);
break;
case 4: // Damage (Electrical)
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT)
P_DamageMobj(player->mo, NULL, NULL, 1);
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC);
break;
case 5: // Spikes
// Don't do anything. In Soviet Russia, spikes find you.
@ -3492,10 +3492,10 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
case 6: // Death Pit (Camera Mod)
case 7: // Death Pit (No Camera Mod)
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, 10000);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT);
break;
case 8: // Instant Kill
P_DamageMobj(player->mo, NULL, NULL, 10000);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
break;
case 9: // Ring Drainer (Floor Touch)
case 10: // Ring Drainer (No Floor Touch)
@ -3599,7 +3599,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
mo2 = (mobj_t *)th;
if (mo2->type == MT_EGGTRAP)
P_KillMobj(mo2, NULL, player->mo);
P_KillMobj(mo2, NULL, player->mo, 0);
}
// clear the special so you can't push the button twice.
@ -5355,9 +5355,9 @@ void T_LaserFlash(laserthink_t *flash)
continue;
if (thing->flags & MF_SHOOTABLE)
P_DamageMobj(thing, NULL, NULL, 1);
P_DamageMobj(thing, NULL, NULL, 1, 0);
else if (thing->type == MT_EGGSHIELD)
P_KillMobj(thing, NULL, NULL);
P_KillMobj(thing, NULL, NULL, 0);
}
}

View File

@ -662,7 +662,7 @@ void P_Ticker(boolean run)
if (!players[i].mo)
continue;
P_DamageMobj(players[i].mo, NULL, NULL, 10000);
P_DamageMobj(players[i].mo, NULL, NULL, 1, DMG_INSTAKILL);
}
}

View File

@ -632,7 +632,7 @@ static void P_DeNightserizePlayer(player_t *player)
continue;
if (mo2->flags & MF_AMBUSH)
P_DamageMobj(player->mo, NULL, NULL, 10000);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
break;
}
@ -1998,21 +1998,15 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
// Underwater timer runs out
else if (player->powers[pw_underwater] == 1)
{
mobj_t *killer;
if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true);
killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL);
killer->threshold = 42; // Special flag that it was drowning which killed you.
P_DamageMobj(player->mo, killer, killer, 10000);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED);
}
else if (player->powers[pw_spacetime] == 1)
{
if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true);
P_DamageMobj(player->mo, NULL, NULL, 10000);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN);
}
if (numbermobj)
@ -6016,7 +6010,7 @@ static void P_NiGHTSMovement(player_t *player)
if (player->powers[pw_flashing] == 1)
player->powers[pw_flashing] = 3;
else
P_DamageMobj(player->mo, NULL, NULL, 1);
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
}
if (movingangle >= ANGLE_90 && movingangle <= ANGLE_180)
@ -6378,7 +6372,7 @@ static void P_MovePlayer(player_t *player)
players[i].exiting = (14*TICRATE)/5 + 1;
}
else if (player->health > 1)
P_DamageMobj(player->mo, NULL, NULL, 1);
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
player->pflags &= ~PF_NIGHTSFALL;
}
}
@ -6906,13 +6900,9 @@ static void P_MovePlayer(player_t *player)
else if (player->mo->ceilingz - player->mo->floorz < player->mo->height)
{
if ((netgame || multiplayer) && player->spectator)
P_DamageMobj(player->mo, NULL, NULL, 42000); // Respawn crushed spectators
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
{
mobj_t *killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL);
killer->threshold = 44; // Special flag that it was crushing which killed you.
P_DamageMobj(player->mo, killer, killer, 10000);
}
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED);
if (player->playerstate == PST_DEAD)
return;
@ -7343,7 +7333,7 @@ static void P_NukeAllPlayers(player_t *player)
if (mo == player->mo)
continue;
P_DamageMobj(mo, player->mo, player->mo, 1);
P_DamageMobj(mo, player->mo, player->mo, 1, 0);
}
CONS_Printf(M_GetText("%s caused a world of pain.\n"), player_names[player-players]);
@ -7401,12 +7391,12 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
mo->flags |= MF_SPECIAL|MF_SHOOTABLE;
if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield!
P_KillMobj(mo->tracer, inflictor, source);
P_KillMobj(mo->tracer, inflictor, source, 0);
if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players!
P_DamageMobj(mo, inflictor, source, 1);
P_DamageMobj(mo, inflictor, source, 1, 0);
else
P_DamageMobj(mo, inflictor, source, 1000);
P_DamageMobj(mo, inflictor, source, 1000, 0);
}
}
@ -8679,7 +8669,7 @@ void P_PlayerThink(player_t *player)
}
player->lives = 2; // Don't start the game over music!
P_DamageMobj(player->mo, NULL, NULL, 10000);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
player->lives = 0;
if (player->playerstate == PST_DEAD)