- 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 ();
// 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.
// Returning -1 signals the damage routine to exit immediately

View File

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

View File

@ -67,7 +67,7 @@ public:
const PClass *StopBall;
void Serialize (FArchive &arc);
void Die (AActor *source, AActor *inflictor);
void Die (AActor *source, AActor *inflictor, int dmgflags);
};
IMPLEMENT_CLASS (AHeresiarch)
@ -78,13 +78,13 @@ void AHeresiarch::Serialize (FArchive &arc)
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
int script = special;
special = 0;
Super::Die (source, inflictor);
Super::Die (source, inflictor, dmgflags);
if (script != 0)
{

View File

@ -83,9 +83,9 @@ void AMinotaurFriend::Serialize (FArchive &arc)
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)
{

View File

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

View File

@ -580,7 +580,7 @@ void AMorphedMonster::Destroy ()
Super::Destroy ();
}
void AMorphedMonster::Die (AActor *source, AActor *inflictor)
void AMorphedMonster::Die (AActor *source, AActor *inflictor, int dmgflags)
{
// Dead things don't unmorph
// flags3 |= MF3_STAYMORPHED;
@ -588,11 +588,11 @@ void AMorphedMonster::Die (AActor *source, AActor *inflictor)
// But they can now, so that line above has been
// moved into P_MorphedDeath() and is now set by
// 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))
{
UnmorphedMe->health = health;
UnmorphedMe->Die (source, inflictor);
UnmorphedMe->Die (source, inflictor, dmgflags);
}
}

View File

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

View File

@ -524,14 +524,14 @@ class APowerCoupling : public AActor
{
DECLARE_CLASS (APowerCoupling, AActor)
public:
void Die (AActor *source, AActor *inflictor);
void Die (AActor *source, AActor *inflictor, int dmgflags);
};
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;

View File

@ -176,7 +176,7 @@ void SexMessage (const char *from, char *to, int gender, const char *victim, con
// [RH]
// 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;
const char *message;
@ -284,7 +284,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker)
{
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);
}
@ -328,7 +328,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker)
//
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
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->Die(source, inflictor);
realthis->Die(source, inflictor, dmgflags);
}
return;
}
@ -592,7 +592,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
if (player)
{
// [RH] Death messages
ClientObituary (this, inflictor, source);
ClientObituary (this, inflictor, source, dmgflags);
// Death script execution, care of Skull Tag
FBehavior::StaticStartTypedScripts (SCRIPT_Death, this, true);
@ -1290,7 +1290,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
source = source->tracer;
}
}
target->Die (source, inflictor);
target->Die (source, inflictor, flags);
return;
}

View File

@ -531,6 +531,7 @@ enum EDmgFlags
DMG_THRUSTLESS = 4,
DMG_FORCED = 8,
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;
AActor *puff = NULL;
int flags = ismeleeattack? PF_MELEERANGE : 0;
int pflag = 0;
if (victim != NULL)
{
@ -3462,6 +3463,12 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
if (t1->player != NULL)
{
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
{
@ -3476,7 +3483,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
(t1->player->ReadyWeapon->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.
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.
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.
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)
{
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)
{ // Make the real player die, too
player->mo->Die (source, inflictor);
player->mo->Die (source, inflictor, dmgflags);
}
else
{