mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 22:33:17 +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_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_ALLOWPAIN = 0x00000200, // Invulnerable or immune (via damagefactors) actors can still react to taking damage even if they don't.
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
||||
|
|
|
@ -938,6 +938,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
FState * woundstate = NULL;
|
||||
PainChanceList * pc = NULL;
|
||||
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)))
|
||||
{ // 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)))
|
||||
{
|
||||
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
|
||||
|
@ -980,11 +991,21 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
// Players are optionally excluded from getting thrust by damage.
|
||||
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->flags5 & MF5_PIERCEARMOR)
|
||||
|
@ -1010,6 +1031,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
// Invulnerable, and won't wake up
|
||||
return -1;
|
||||
}
|
||||
|
||||
player = target->player;
|
||||
if (player && damage > 1 && damage < TELEFRAG_DAMAGE)
|
||||
{
|
||||
|
@ -1032,10 +1054,13 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
if (damage > 0)
|
||||
damage = inflictor->DoSpecialDamage (target, damage, mod);
|
||||
|
||||
damage = inflictor->DoSpecialDamage (target, damage, mod);
|
||||
if (damage == -1)
|
||||
{
|
||||
if (target->flags7 & MF7_ALLOWPAIN) //Hold off ending the function before we can deal the pain chances.
|
||||
goto fakepain;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1058,12 +1083,15 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
int olddam = damage;
|
||||
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
||||
if (olddam != damage && damage <= 0)
|
||||
{ // Still allow FORCEPAIN
|
||||
if (((target->flags7 & MF7_ALLOWPAIN) && (fakeDamage <= 0)) || (olddam != damage && damage <= 0))
|
||||
{ // Still allow FORCEPAIN and make sure we're still passing along fake damage to hit enemies for their pain states.
|
||||
if (MustForcePain(target, inflictor))
|
||||
{
|
||||
goto dopain;
|
||||
}
|
||||
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||
goto fakepain;
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1081,19 +1109,25 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
goto dopain;
|
||||
}
|
||||
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||
goto fakepain;
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
||||
if (damage > 0)
|
||||
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
||||
}
|
||||
if (damage == -1)
|
||||
{
|
||||
if (target->flags7 & MF7_ALLOWPAIN)
|
||||
goto fakepain;
|
||||
|
||||
return -1;
|
||||
}
|
||||
// Push the target unless the source's weapon's kickback is 0.
|
||||
// (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)
|
||||
&& !(inflictor->flags2 & MF2_NODMGTHRUST)
|
||||
&& !(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);
|
||||
}
|
||||
|
||||
thrust = FLOAT2FIXED(fltthrust);
|
||||
|
||||
// Don't apply ultra-small damage thrust
|
||||
if (thrust < FRACUNIT/100) thrust = 0;
|
||||
// Don't apply ultra-small damage thrust.
|
||||
if (thrust < FRACUNIT / 100)
|
||||
thrust = 0;
|
||||
|
||||
// make fall forwards sometimes
|
||||
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
|
||||
&& thrust < 10*FRACUNIT
|
||||
&& !(target->flags & MF_NOGRAVITY)
|
||||
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL))
|
||||
)
|
||||
&& (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL)))
|
||||
{
|
||||
ang += ANG180;
|
||||
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))
|
||||
//Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2.
|
||||
{ // player is invulnerable, so don't hurt him
|
||||
if (player->mo->flags7 & MF7_ALLOWPAIN)
|
||||
{
|
||||
invulpain = true;
|
||||
fakeDamage = damage;
|
||||
goto fakepain;
|
||||
}
|
||||
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 (!(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;
|
||||
}
|
||||
|
@ -1296,7 +1335,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
damage = newdam;
|
||||
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)) &&
|
||||
(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)))
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -5986,7 +5986,7 @@ bool AActor::IsHostile (AActor *other)
|
|||
int AActor::DoSpecialDamage (AActor *target, int damage, FName damagetype)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -2588,7 +2588,8 @@ void P_PlayerThink (player_t *player)
|
|||
{
|
||||
if (player->mo->waterlevel < 3 ||
|
||||
(player->mo->flags2 & MF2_INVULNERABLE) ||
|
||||
(player->cheats & (CF_GODMODE | CF_NOCLIP2)))
|
||||
(player->cheats & (CF_GODMODE | CF_NOCLIP2)) ||
|
||||
(player->cheats & CF_GODMODE2))
|
||||
{
|
||||
player->mo->ResetAirSupply ();
|
||||
}
|
||||
|
|
|
@ -245,6 +245,7 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_FLAG(MF7, BUDDHA, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, FOILBUDDHA, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, DONTTHRUST, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, ALLOWPAIN, AActor, flags7),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
|
Loading…
Reference in a new issue