- fixed: The newly added checks for printing weapon obituaries failed if the weapon used a puff with a special damage type. To handle this, P_DamageMobj will now pass the damage flags to AActor::Die and from there to ClientObituary so that P_LineAttack - which is a better place to decide this - can flag an attack as coming from a player weapon.

- fixed: The same rules that are used for deciding if a weapon attack took place should be used when checking the PIERCEARMOR flag in P_LineAttack: It should be ignored if the attack doesn't originate from the weapon.

SVN r3649 (trunk)
This commit is contained in:
Christoph Oelckers 2012-05-13 07:54:44 +00:00
parent 3e41382d63
commit 3a24790056
12 changed files with 35 additions and 27 deletions

View file

@ -599,7 +599,7 @@ public:
virtual void Tick (); virtual void Tick ();
// Called when actor dies // Called when actor dies
virtual void Die (AActor *source, AActor *inflictor); virtual void Die (AActor *source, AActor *inflictor, int dmgflags = 0);
// Perform some special damage action. Returns the amount of damage to do. // Perform some special damage action. Returns the amount of damage to do.
// Returning -1 signals the damage routine to exit immediately // Returning -1 signals the damage routine to exit immediately

View file

@ -118,7 +118,7 @@ public:
}; };
void BeginPlay (); void BeginPlay ();
void Die (AActor *source, AActor *inflictor); void Die (AActor *source, AActor *inflictor, int dmgflags);
int crouchsprite; int crouchsprite;
int MaxHealth; int MaxHealth;

View file

@ -67,7 +67,7 @@ public:
const PClass *StopBall; const PClass *StopBall;
void Serialize (FArchive &arc); void Serialize (FArchive &arc);
void Die (AActor *source, AActor *inflictor); void Die (AActor *source, AActor *inflictor, int dmgflags);
}; };
IMPLEMENT_CLASS (AHeresiarch) IMPLEMENT_CLASS (AHeresiarch)
@ -78,13 +78,13 @@ void AHeresiarch::Serialize (FArchive &arc)
arc << StopBall; arc << StopBall;
} }
void AHeresiarch::Die (AActor *source, AActor *inflictor) void AHeresiarch::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
// The heresiarch just executes a script instead of a special upon death // The heresiarch just executes a script instead of a special upon death
int script = special; int script = special;
special = 0; special = 0;
Super::Die (source, inflictor); Super::Die (source, inflictor, dmgflags);
if (script != 0) if (script != 0)
{ {

View file

@ -83,9 +83,9 @@ void AMinotaurFriend::Serialize (FArchive &arc)
arc << StartTime; arc << StartTime;
} }
void AMinotaurFriend::Die (AActor *source, AActor *inflictor) void AMinotaurFriend::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
Super::Die (source, inflictor); Super::Die (source, inflictor, dmgflags);
if (tracer && tracer->health > 0 && tracer->player) if (tracer && tracer->health > 0 && tracer->player)
{ {

View file

@ -20,7 +20,7 @@ class AMinotaurFriend : public AMinotaur
public: public:
int StartTime; int StartTime;
void Die (AActor *source, AActor *inflictor); void Die (AActor *source, AActor *inflictor, int dmgflags);
bool OkayToSwitchTarget (AActor *other); bool OkayToSwitchTarget (AActor *other);
void BeginPlay (); void BeginPlay ();
void Serialize (FArchive &arc); void Serialize (FArchive &arc);

View file

@ -580,7 +580,7 @@ void AMorphedMonster::Destroy ()
Super::Destroy (); Super::Destroy ();
} }
void AMorphedMonster::Die (AActor *source, AActor *inflictor) void AMorphedMonster::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
// Dead things don't unmorph // Dead things don't unmorph
// flags3 |= MF3_STAYMORPHED; // flags3 |= MF3_STAYMORPHED;
@ -588,11 +588,11 @@ void AMorphedMonster::Die (AActor *source, AActor *inflictor)
// But they can now, so that line above has been // But they can now, so that line above has been
// moved into P_MorphedDeath() and is now set by // moved into P_MorphedDeath() and is now set by
// that function if and only if it is needed. // that function if and only if it is needed.
Super::Die (source, inflictor); Super::Die (source, inflictor, dmgflags);
if (UnmorphedMe != NULL && (UnmorphedMe->flags & MF_UNMORPHED)) if (UnmorphedMe != NULL && (UnmorphedMe->flags & MF_UNMORPHED))
{ {
UnmorphedMe->health = health; UnmorphedMe->health = health;
UnmorphedMe->Die (source, inflictor); UnmorphedMe->Die (source, inflictor, dmgflags);
} }
} }

View file

@ -170,7 +170,7 @@ class AMorphedMonster : public AActor
public: public:
void Tick (); void Tick ();
void Serialize (FArchive &arc); void Serialize (FArchive &arc);
void Die (AActor *source, AActor *inflictor); void Die (AActor *source, AActor *inflictor, int dmgflags);
void Destroy (); void Destroy ();
TObjPtr<AActor> UnmorphedMe; TObjPtr<AActor> UnmorphedMe;

View file

@ -524,14 +524,14 @@ class APowerCoupling : public AActor
{ {
DECLARE_CLASS (APowerCoupling, AActor) DECLARE_CLASS (APowerCoupling, AActor)
public: public:
void Die (AActor *source, AActor *inflictor); void Die (AActor *source, AActor *inflictor, int dmgflags);
}; };
IMPLEMENT_CLASS (APowerCoupling) IMPLEMENT_CLASS (APowerCoupling)
void APowerCoupling::Die (AActor *source, AActor *inflictor) void APowerCoupling::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
Super::Die (source, inflictor); Super::Die (source, inflictor, dmgflags);
int i; int i;

View file

@ -176,7 +176,7 @@ void SexMessage (const char *from, char *to, int gender, const char *victim, con
// [RH] // [RH]
// ClientObituary: Show a message when a player dies // ClientObituary: Show a message when a player dies
// //
void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker) void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgflags)
{ {
FName mod; FName mod;
const char *message; const char *message;
@ -284,7 +284,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker)
{ {
message = inflictor->GetClass()->Meta.GetMetaString (AMETA_Obituary); message = inflictor->GetClass()->Meta.GetMetaString (AMETA_Obituary);
} }
if (message == NULL && (mod == NAME_Melee || mod == NAME_Hitscan) && attacker->player->ReadyWeapon != NULL) if (message == NULL && (dmgflags & DMG_PLAYERATTACK) && attacker->player->ReadyWeapon != NULL)
{ {
message = attacker->player->ReadyWeapon->GetClass()->Meta.GetMetaString (AMETA_Obituary); message = attacker->player->ReadyWeapon->GetClass()->Meta.GetMetaString (AMETA_Obituary);
} }
@ -328,7 +328,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker)
// //
EXTERN_CVAR (Int, fraglimit) EXTERN_CVAR (Int, fraglimit)
void AActor::Die (AActor *source, AActor *inflictor) void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
// Handle possible unmorph on death // Handle possible unmorph on death
bool wasgibbed = (health < GibHealth()); bool wasgibbed = (health < GibHealth());
@ -348,7 +348,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
realthis->health = realgibhealth -1; // if morphed was gibbed, so must original be (where allowed) realthis->health = realgibhealth -1; // if morphed was gibbed, so must original be (where allowed)
} }
} }
realthis->Die(source, inflictor); realthis->Die(source, inflictor, dmgflags);
} }
return; return;
} }
@ -592,7 +592,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
if (player) if (player)
{ {
// [RH] Death messages // [RH] Death messages
ClientObituary (this, inflictor, source); ClientObituary (this, inflictor, source, dmgflags);
// Death script execution, care of Skull Tag // Death script execution, care of Skull Tag
FBehavior::StaticStartTypedScripts (SCRIPT_Death, this, true); FBehavior::StaticStartTypedScripts (SCRIPT_Death, this, true);
@ -1290,7 +1290,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
source = source->tracer; source = source->tracer;
} }
} }
target->Die (source, inflictor); target->Die (source, inflictor, flags);
return; return;
} }

View file

@ -531,6 +531,7 @@ enum EDmgFlags
DMG_THRUSTLESS = 4, DMG_THRUSTLESS = 4,
DMG_FORCED = 8, DMG_FORCED = 8,
DMG_NO_FACTOR = 16, DMG_NO_FACTOR = 16,
DMG_PLAYERATTACK = 32,
}; };

View file

@ -3445,6 +3445,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
bool killPuff = false; bool killPuff = false;
AActor *puff = NULL; AActor *puff = NULL;
int flags = ismeleeattack? PF_MELEERANGE : 0; int flags = ismeleeattack? PF_MELEERANGE : 0;
int pflag = 0;
if (victim != NULL) if (victim != NULL)
{ {
@ -3462,6 +3463,12 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
if (t1->player != NULL) if (t1->player != NULL)
{ {
shootz += FixedMul (t1->player->mo->AttackZOffset, t1->player->crouchfactor); shootz += FixedMul (t1->player->mo->AttackZOffset, t1->player->crouchfactor);
if (damageType == NAME_Melee || damageType == NAME_Hitscan)
{
// this is coming from a weapon attack function which needs to transfer information to the obituary code,
// We need to preserve this info from the damage type because the actual damage type can get overridden by the puff
pflag = DMG_PLAYERATTACK;
}
} }
else else
{ {
@ -3476,7 +3483,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
(t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) || (t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) ||
(puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST)); (puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST));
// if the puff uses a non-standard damage type this will override default and melee damage type. // if the puff uses a non-standard damage type this will override default, hitscan and melee damage type.
// All other explicitly passed damage types (currenty only MDK) will be preserved. // All other explicitly passed damage types (currenty only MDK) will be preserved.
if ((damageType == NAME_None || damageType == NAME_Melee || damageType == NAME_Hitscan) && puffDefaults->DamageType != NAME_None) if ((damageType == NAME_None || damageType == NAME_Melee || damageType == NAME_Hitscan) && puffDefaults->DamageType != NAME_None)
{ {
@ -3627,9 +3634,9 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
// Note: The puff may not yet be spawned here so we must check the class defaults, not the actor. // Note: The puff may not yet be spawned here so we must check the class defaults, not the actor.
if (damage || (puffDefaults->flags6 & MF6_FORCEPAIN)) if (damage || (puffDefaults->flags6 & MF6_FORCEPAIN))
{ {
int dmgflags = DMG_INFLICTOR_IS_PUFF; int dmgflags = DMG_INFLICTOR_IS_PUFF | pflag;
// Allow MF5_PIERCEARMOR on a weapon as well. // Allow MF5_PIERCEARMOR on a weapon as well.
if (t1->player != NULL && t1->player->ReadyWeapon != NULL && if (t1->player != NULL && (dmgflags & DMG_PLAYERATTACK) && t1->player->ReadyWeapon != NULL &&
t1->player->ReadyWeapon->flags5 & MF5_PIERCEARMOR) t1->player->ReadyWeapon->flags5 & MF5_PIERCEARMOR)
{ {
dmgflags |= DMG_NO_ARMOR; dmgflags |= DMG_NO_ARMOR;

View file

@ -1205,15 +1205,15 @@ void APlayerPawn::ActivateMorphWeapon ()
// //
//=========================================================================== //===========================================================================
void APlayerPawn::Die (AActor *source, AActor *inflictor) void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
Super::Die (source, inflictor); Super::Die (source, inflictor, dmgflags);
if (player != NULL && player->mo == this) player->bonuscount = 0; if (player != NULL && player->mo == this) player->bonuscount = 0;
if (player != NULL && player->mo != this) if (player != NULL && player->mo != this)
{ // Make the real player die, too { // Make the real player die, too
player->mo->Die (source, inflictor); player->mo->Die (source, inflictor, dmgflags);
} }
else else
{ {