mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
-Added: CAUSEPAIN. Actors which deal damage (even if 0) while having this flag can cause other actors to trigger pain chances.
-Fixed: ALLOWPAIN should not trigger pain states if the damage is 0, but still allow for infighting to occur. -Fixed: an unneeded logic call was processing damage modification when it was 0 to begin with.
This commit is contained in:
parent
e0eca1e0f5
commit
b54b18c8c5
4 changed files with 36 additions and 25 deletions
|
@ -346,6 +346,7 @@ enum
|
|||
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.
|
||||
MF7_CAUSEPAIN = 0x00000400, // Damage sources with this flag can cause similar effects like ALLOWPAIN.
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
||||
|
|
|
@ -970,13 +970,13 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
if ((target->flags2 & MF2_INVULNERABLE) && damage < TELEFRAG_DAMAGE && !(flags & DMG_FORCED))
|
||||
if ((target->flags2 & MF2_INVULNERABLE) && (damage < TELEFRAG_DAMAGE) && (!(flags & DMG_FORCED)))
|
||||
{ // actor is invulnerable
|
||||
if (target->player == NULL)
|
||||
{
|
||||
if (inflictor == NULL || (!(inflictor->flags3 & MF3_FOILINVUL) && !(flags & DMG_FOILINVUL)))
|
||||
{
|
||||
if (target->flags7 & MF7_ALLOWPAIN)
|
||||
if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN))
|
||||
{
|
||||
invulpain = true; //This returns -1 later.
|
||||
fakeDamage = damage;
|
||||
|
@ -991,7 +991,7 @@ 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)
|
||||
{
|
||||
if (target->flags7 & MF7_ALLOWPAIN)
|
||||
if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN))
|
||||
plrDontThrust = 1;
|
||||
else
|
||||
return -1;
|
||||
|
@ -999,7 +999,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
}
|
||||
|
||||
}
|
||||
if ((target->flags7 & MF7_ALLOWPAIN) && (damage < TELEFRAG_DAMAGE))
|
||||
if (((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN)) && (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.
|
||||
|
@ -1059,7 +1059,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
|
||||
if (damage == -1)
|
||||
{
|
||||
if (target->flags7 & MF7_ALLOWPAIN) //Hold off ending the function before we can deal the pain chances.
|
||||
if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN)) //Hold off ending the function before we can deal the pain chances.
|
||||
goto fakepain;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1089,7 +1089,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
goto dopain;
|
||||
}
|
||||
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||
else if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN))
|
||||
goto fakepain;
|
||||
|
||||
return -1;
|
||||
|
@ -1099,7 +1099,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
if (!(flags & DMG_NO_FACTOR))
|
||||
{
|
||||
damage = FixedMul(damage, target->DamageFactor);
|
||||
if (damage >= 0)
|
||||
if (damage > 0)
|
||||
{
|
||||
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->ActorInfo->DamageFactors);
|
||||
}
|
||||
|
@ -1109,7 +1109,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
goto dopain;
|
||||
}
|
||||
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||
else if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN))
|
||||
goto fakepain;
|
||||
|
||||
return -1;
|
||||
|
@ -1120,7 +1120,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
}
|
||||
if (damage == -1)
|
||||
{
|
||||
if (target->flags7 & MF7_ALLOWPAIN)
|
||||
if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN))
|
||||
goto fakepain;
|
||||
|
||||
return -1;
|
||||
|
@ -1243,12 +1243,16 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
// check the real player, not a voodoo doll here for invulnerability effects
|
||||
if ((damage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) ||
|
||||
(player->cheats & CF_GODMODE))) ||
|
||||
(player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE))
|
||||
(player->cheats & CF_GODMODE))) ||
|
||||
(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)
|
||||
{
|
||||
|
||||
if (((!(player->cheats & CF_GODMODE)) && (!(player->cheats & CF_GODMODE2)) && (!(player->mo->flags5 & MF5_NOPAIN))) &&
|
||||
(((player->mo->flags7 & MF7_ALLOWPAIN) || (player->mo->flags5 & MF5_NODAMAGE)) || (inflictor->flags7 & MF7_CAUSEPAIN)))
|
||||
//Make sure no godmodes and NOPAIN flags are found first.
|
||||
//Then, check to see if the player has NODAMAGE or ALLOWPAIN, or inflictor has CAUSEPAIN.
|
||||
{
|
||||
invulpain = true;
|
||||
fakeDamage = damage;
|
||||
goto fakepain;
|
||||
|
@ -1270,8 +1274,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) &&
|
||||
(!(player->mo->flags2 & MF2_INVULNERABLE)))
|
||||
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS)
|
||||
&& (!(player->mo->flags2 & MF2_INVULNERABLE)) && (!(player->cheats & CF_GODMODE)) && (!(player->cheats & CF_GODMODE2)))
|
||||
{
|
||||
goto dopain;
|
||||
}
|
||||
|
@ -1302,7 +1306,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
// telefrag him right? ;) (Unfortunately the damage is "absorbed" by armor,
|
||||
// but telefragging should still do enough damage to kill the player)
|
||||
// Ignore players that are already dead.
|
||||
if (((player->cheats & CF_BUDDHA2) || ((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA) && damage < TELEFRAG_DAMAGE)) && player->playerstate != PST_DEAD)
|
||||
if ((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (damage < TELEFRAG_DAMAGE)) && (player->playerstate != PST_DEAD))
|
||||
{
|
||||
// If this is a voodoo doll we need to handle the real player as well.
|
||||
player->mo->health = target->health = player->health = 1;
|
||||
|
@ -1335,7 +1339,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
damage = newdam;
|
||||
if (damage <= 0)
|
||||
{
|
||||
if (target->flags7 & MF7_ALLOWPAIN)
|
||||
if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN))
|
||||
goto fakepain;
|
||||
else
|
||||
return damage;
|
||||
|
@ -1426,10 +1430,14 @@ 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))
|
||||
|
||||
//CAUSEPAIN can always attempt to trigger the chances of pain.
|
||||
//ALLOWPAIN can do the same, only if the (unfiltered aka fake) damage is greater than 0.
|
||||
if ((((target->flags7 & MF7_ALLOWPAIN) && (fakeDamage > 0))
|
||||
|| (inflictor->flags7 & MF7_CAUSEPAIN)) && (fakeDamage != damage))
|
||||
{
|
||||
holdDamage = damage;
|
||||
damage = fakeDamage;
|
||||
holdDamage = damage; //Store the modified damage away after factors are taken into account.
|
||||
damage = fakeDamage; //Retrieve the original damage.
|
||||
}
|
||||
|
||||
if (!(target->flags5 & MF5_NOPAIN) && (inflictor == NULL || !(inflictor->flags5 & MF5_PAINLESS)) &&
|
||||
|
@ -1446,8 +1454,8 @@ fakepain: //Needed so we can skip the rest of the above, but still obey the orig
|
|||
}
|
||||
}
|
||||
|
||||
if ((damage >= target->PainThreshold && pr_damagemobj() < painchance) ||
|
||||
(inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN)))
|
||||
if ((((damage >= target->PainThreshold)) && (pr_damagemobj() < painchance))
|
||||
|| (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN)))
|
||||
{
|
||||
dopain:
|
||||
if (mod == NAME_Electric)
|
||||
|
@ -1484,6 +1492,7 @@ dopain:
|
|||
}
|
||||
}
|
||||
}
|
||||
//ALLOWPAIN and CAUSEPAIN can still trigger infighting, even if no pain state is worked out.
|
||||
target->reactiontime = 0; // we're awake now...
|
||||
if (source)
|
||||
{
|
||||
|
@ -1526,9 +1535,9 @@ dopain:
|
|||
{
|
||||
return -1; //NOW we return -1!
|
||||
}
|
||||
else if (target->flags7 & MF7_ALLOWPAIN)
|
||||
else if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN))
|
||||
{
|
||||
return holdDamage;
|
||||
return holdDamage; //This is the calculated damage after all is said and done.
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
|
|
|
@ -3695,7 +3695,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
|
|||
// [GZ] If MF6_FORCEPAIN is set, we need to call P_DamageMobj even if damage is 0!
|
||||
// Note: The puff may not yet be spawned here so we must check the class defaults, not the actor.
|
||||
int newdam = damage;
|
||||
if (damage || (puffDefaults != NULL && puffDefaults->flags6 & MF6_FORCEPAIN))
|
||||
if (damage || (puffDefaults != NULL && ((puffDefaults->flags6 & MF6_FORCEPAIN) || (puffDefaults->flags7 & MF7_CAUSEPAIN))))
|
||||
{
|
||||
int dmgflags = DMG_INFLICTOR_IS_PUFF | pflag;
|
||||
// Allow MF5_PIERCEARMOR on a weapon as well.
|
||||
|
|
|
@ -246,6 +246,7 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_FLAG(MF7, FOILBUDDHA, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, DONTTHRUST, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, ALLOWPAIN, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, CAUSEPAIN, AActor, flags7),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
|
Loading…
Reference in a new issue