mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- Added ALLOWPAIN flag.
Monsters with this flag can enter pain states, regardless of invulnerability or damage absorption. - Fixed: god2 cheat wasn't being considered for drowning and thrusting.
This commit is contained in:
parent
0ff65bb430
commit
2e085b2318
5 changed files with 77 additions and 18 deletions
|
@ -345,6 +345,7 @@ enum
|
||||||
MF7_BUDDHA = 0x00000040, // Behaves just like the buddha cheat.
|
MF7_BUDDHA = 0x00000040, // Behaves just like the buddha cheat.
|
||||||
MF7_FOILBUDDHA = 0x00000080, // Similar to FOILINVUL, foils buddha mode.
|
MF7_FOILBUDDHA = 0x00000080, // Similar to FOILINVUL, foils buddha mode.
|
||||||
MF7_DONTTHRUST = 0x00000100, // Thrusting functions do not take, and do not give thrust (damage) to actors with this flag.
|
MF7_DONTTHRUST = 0x00000100, // Thrusting functions do not take, and do not give thrust (damage) to actors with this flag.
|
||||||
|
MF7_ALLOWPAIN = 0x00000200, // Invulnerable or immune (via damagefactors) actors can still react to taking damage even if they don't.
|
||||||
|
|
||||||
// --- mobj.renderflags ---
|
// --- mobj.renderflags ---
|
||||||
|
|
||||||
|
|
|
@ -938,6 +938,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
FState * woundstate = NULL;
|
FState * woundstate = NULL;
|
||||||
PainChanceList * pc = NULL;
|
PainChanceList * pc = NULL;
|
||||||
bool justhit = false;
|
bool justhit = false;
|
||||||
|
bool plrDontThrust = false;
|
||||||
|
bool invulpain = false;
|
||||||
|
int fakeDamage = 0;
|
||||||
|
int holdDamage = 0;
|
||||||
|
|
||||||
if (target == NULL || !((target->flags & MF_SHOOTABLE) || (target->flags6 & MF6_VULNERABLE)))
|
if (target == NULL || !((target->flags & MF_SHOOTABLE) || (target->flags6 & MF6_VULNERABLE)))
|
||||||
{ // Shouldn't happen
|
{ // Shouldn't happen
|
||||||
|
@ -972,7 +976,14 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
if (inflictor == NULL || (!(inflictor->flags3 & MF3_FOILINVUL) && !(flags & DMG_FOILINVUL)))
|
if (inflictor == NULL || (!(inflictor->flags3 & MF3_FOILINVUL) && !(flags & DMG_FOILINVUL)))
|
||||||
{
|
{
|
||||||
return -1;
|
if (target->flags7 & MF7_ALLOWPAIN)
|
||||||
|
{
|
||||||
|
invulpain = true; //This returns -1 later.
|
||||||
|
fakeDamage = damage;
|
||||||
|
goto fakepain; //The label is above the massive pile of checks.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -980,11 +991,21 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
// Players are optionally excluded from getting thrust by damage.
|
// Players are optionally excluded from getting thrust by damage.
|
||||||
if (static_cast<APlayerPawn *>(target)->PlayerFlags & PPF_NOTHRUSTWHENINVUL)
|
if (static_cast<APlayerPawn *>(target)->PlayerFlags & PPF_NOTHRUSTWHENINVUL)
|
||||||
{
|
{
|
||||||
return -1;
|
if (target->flags7 & MF7_ALLOWPAIN)
|
||||||
|
plrDontThrust = 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if ((target->flags7 & MF7_ALLOWPAIN) && (damage < TELEFRAG_DAMAGE))
|
||||||
|
{
|
||||||
|
//Intentionally do not jump to fakepain because the damage hasn't been dished out yet.
|
||||||
|
//Once it's dished out, THEN we can disregard damage factors affecting pain chances.
|
||||||
|
fakeDamage = damage;
|
||||||
|
}
|
||||||
|
|
||||||
if (inflictor != NULL)
|
if (inflictor != NULL)
|
||||||
{
|
{
|
||||||
if (inflictor->flags5 & MF5_PIERCEARMOR)
|
if (inflictor->flags5 & MF5_PIERCEARMOR)
|
||||||
|
@ -1010,6 +1031,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
// Invulnerable, and won't wake up
|
// Invulnerable, and won't wake up
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
player = target->player;
|
player = target->player;
|
||||||
if (player && damage > 1 && damage < TELEFRAG_DAMAGE)
|
if (player && damage > 1 && damage < TELEFRAG_DAMAGE)
|
||||||
{
|
{
|
||||||
|
@ -1032,10 +1054,13 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (damage > 0)
|
||||||
|
damage = inflictor->DoSpecialDamage (target, damage, mod);
|
||||||
|
|
||||||
damage = inflictor->DoSpecialDamage (target, damage, mod);
|
|
||||||
if (damage == -1)
|
if (damage == -1)
|
||||||
{
|
{
|
||||||
|
if (target->flags7 & MF7_ALLOWPAIN) //Hold off ending the function before we can deal the pain chances.
|
||||||
|
goto fakepain;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1058,12 +1083,15 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
int olddam = damage;
|
int olddam = damage;
|
||||||
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
||||||
if (olddam != damage && damage <= 0)
|
if (((target->flags7 & MF7_ALLOWPAIN) && (fakeDamage <= 0)) || (olddam != damage && damage <= 0))
|
||||||
{ // Still allow FORCEPAIN
|
{ // Still allow FORCEPAIN and make sure we're still passing along fake damage to hit enemies for their pain states.
|
||||||
if (MustForcePain(target, inflictor))
|
if (MustForcePain(target, inflictor))
|
||||||
{
|
{
|
||||||
goto dopain;
|
goto dopain;
|
||||||
}
|
}
|
||||||
|
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||||
|
goto fakepain;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1081,19 +1109,25 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
goto dopain;
|
goto dopain;
|
||||||
}
|
}
|
||||||
|
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||||
|
goto fakepain;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (damage > 0)
|
||||||
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
||||||
}
|
}
|
||||||
if (damage == -1)
|
if (damage == -1)
|
||||||
{
|
{
|
||||||
|
if (target->flags7 & MF7_ALLOWPAIN)
|
||||||
|
goto fakepain;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Push the target unless the source's weapon's kickback is 0.
|
// Push the target unless the source's weapon's kickback is 0.
|
||||||
// (i.e. Gauntlets/Chainsaw)
|
// (i.e. Gauntlets/Chainsaw)
|
||||||
if (inflictor && inflictor != target // [RH] Not if hurting own self
|
if (!(plrDontThrust) && inflictor && inflictor != target // [RH] Not if hurting own self
|
||||||
&& !(target->flags & MF_NOCLIP)
|
&& !(target->flags & MF_NOCLIP)
|
||||||
&& !(inflictor->flags2 & MF2_NODMGTHRUST)
|
&& !(inflictor->flags2 & MF2_NODMGTHRUST)
|
||||||
&& !(flags & DMG_THRUSTLESS)
|
&& !(flags & DMG_THRUSTLESS)
|
||||||
|
@ -1134,11 +1168,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
fltthrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., fltthrust);
|
fltthrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., fltthrust);
|
||||||
}
|
}
|
||||||
|
|
||||||
thrust = FLOAT2FIXED(fltthrust);
|
thrust = FLOAT2FIXED(fltthrust);
|
||||||
|
// Don't apply ultra-small damage thrust.
|
||||||
// Don't apply ultra-small damage thrust
|
if (thrust < FRACUNIT / 100)
|
||||||
if (thrust < FRACUNIT/100) thrust = 0;
|
thrust = 0;
|
||||||
|
|
||||||
// make fall forwards sometimes
|
// make fall forwards sometimes
|
||||||
if ((damage < 40) && (damage > target->health)
|
if ((damage < 40) && (damage > target->health)
|
||||||
|
@ -1147,8 +1180,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
// [RH] But only if not too fast and not flying
|
// [RH] But only if not too fast and not flying
|
||||||
&& thrust < 10*FRACUNIT
|
&& thrust < 10*FRACUNIT
|
||||||
&& !(target->flags & MF_NOGRAVITY)
|
&& !(target->flags & MF_NOGRAVITY)
|
||||||
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL))
|
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL)))
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ang += ANG180;
|
ang += ANG180;
|
||||||
thrust *= 4;
|
thrust *= 4;
|
||||||
|
@ -1215,6 +1247,12 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
(player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE))
|
(player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE))
|
||||||
//Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2.
|
//Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2.
|
||||||
{ // player is invulnerable, so don't hurt him
|
{ // player is invulnerable, so don't hurt him
|
||||||
|
if (player->mo->flags7 & MF7_ALLOWPAIN)
|
||||||
|
{
|
||||||
|
invulpain = true;
|
||||||
|
fakeDamage = damage;
|
||||||
|
goto fakepain;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,7 +1270,8 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
// If MF6_FORCEPAIN is set, make the player enter the pain state.
|
// If MF6_FORCEPAIN is set, make the player enter the pain state.
|
||||||
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
|
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
|
||||||
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS))
|
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS) &&
|
||||||
|
(!(player->mo->flags2 & MF2_INVULNERABLE)))
|
||||||
{
|
{
|
||||||
goto dopain;
|
goto dopain;
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1335,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
damage = newdam;
|
damage = newdam;
|
||||||
if (damage <= 0)
|
if (damage <= 0)
|
||||||
{
|
{
|
||||||
return damage;
|
if (target->flags7 & MF7_ALLOWPAIN)
|
||||||
|
goto fakepain;
|
||||||
|
else
|
||||||
|
return damage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1383,6 +1425,12 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fakepain: //Needed so we can skip the rest of the above, but still obey the original rules.
|
||||||
|
if (target->flags7 & MF7_ALLOWPAIN && (fakeDamage != damage))
|
||||||
|
{
|
||||||
|
holdDamage = damage;
|
||||||
|
damage = fakeDamage;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(target->flags5 & MF5_NOPAIN) && (inflictor == NULL || !(inflictor->flags5 & MF5_PAINLESS)) &&
|
if (!(target->flags5 & MF5_NOPAIN) && (inflictor == NULL || !(inflictor->flags5 & MF5_PAINLESS)) &&
|
||||||
(target->player != NULL || !G_SkillProperty(SKILLP_NoPain)) && !(target->flags & MF_SKULLFLY))
|
(target->player != NULL || !G_SkillProperty(SKILLP_NoPain)) && !(target->flags & MF_SKULLFLY))
|
||||||
|
@ -1474,6 +1522,14 @@ dopain:
|
||||||
if (justhit && (target->target == source || !target->target || !target->IsFriend(target->target)))
|
if (justhit && (target->target == source || !target->target || !target->IsFriend(target->target)))
|
||||||
target->flags |= MF_JUSTHIT; // fight back!
|
target->flags |= MF_JUSTHIT; // fight back!
|
||||||
|
|
||||||
|
if (invulpain) //Note that this takes into account all the cheats a player has, in terms of invulnerability.
|
||||||
|
{
|
||||||
|
return -1; //NOW we return -1!
|
||||||
|
}
|
||||||
|
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||||
|
{
|
||||||
|
return holdDamage;
|
||||||
|
}
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5986,7 +5986,7 @@ bool AActor::IsHostile (AActor *other)
|
||||||
int AActor::DoSpecialDamage (AActor *target, int damage, FName damagetype)
|
int AActor::DoSpecialDamage (AActor *target, int damage, FName damagetype)
|
||||||
{
|
{
|
||||||
if (target->player && target->player->mo == target && damage < 1000 &&
|
if (target->player && target->player->mo == target && damage < 1000 &&
|
||||||
(target->player->cheats & CF_GODMODE))
|
(target->player->cheats & CF_GODMODE || target->player->cheats & CF_GODMODE2))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2588,7 +2588,8 @@ void P_PlayerThink (player_t *player)
|
||||||
{
|
{
|
||||||
if (player->mo->waterlevel < 3 ||
|
if (player->mo->waterlevel < 3 ||
|
||||||
(player->mo->flags2 & MF2_INVULNERABLE) ||
|
(player->mo->flags2 & MF2_INVULNERABLE) ||
|
||||||
(player->cheats & (CF_GODMODE | CF_NOCLIP2)))
|
(player->cheats & (CF_GODMODE | CF_NOCLIP2)) ||
|
||||||
|
(player->cheats & CF_GODMODE2))
|
||||||
{
|
{
|
||||||
player->mo->ResetAirSupply ();
|
player->mo->ResetAirSupply ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,6 +245,7 @@ static FFlagDef ActorFlags[]=
|
||||||
DEFINE_FLAG(MF7, BUDDHA, AActor, flags7),
|
DEFINE_FLAG(MF7, BUDDHA, AActor, flags7),
|
||||||
DEFINE_FLAG(MF7, FOILBUDDHA, AActor, flags7),
|
DEFINE_FLAG(MF7, FOILBUDDHA, AActor, flags7),
|
||||||
DEFINE_FLAG(MF7, DONTTHRUST, AActor, flags7),
|
DEFINE_FLAG(MF7, DONTTHRUST, AActor, flags7),
|
||||||
|
DEFINE_FLAG(MF7, ALLOWPAIN, AActor, flags7),
|
||||||
|
|
||||||
// Effect flags
|
// Effect flags
|
||||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||||
|
|
Loading…
Reference in a new issue