- fixed: Draining health from a victim must check for damage reduction before awarding the health to the player. This affected Heretic's gauntlets, A_Saw and A_CustomPunch.

- added a DONTDRAIN flag that prevents the above attacks from draining any health at all.
This commit is contained in:
Christoph Oelckers 2013-06-24 16:42:43 +02:00
parent c4ad09fe90
commit 394f21f71e
8 changed files with 27 additions and 15 deletions

View file

@ -265,7 +265,7 @@ enum
// --- mobj.flags5 ---
/* = 0x00000001, */
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
/* = 0x00000002, */
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
/* = 0x00000008, */

View file

@ -115,6 +115,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
angle_t slope;
player_t *player;
AActor *linetarget;
int actualdamage;
ACTION_PARAM_START(9);
ACTION_PARAM_SOUND(fullsound, 0);
@ -151,7 +152,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
return;
}
P_LineAttack (self, angle, Range, slope, damage, NAME_Melee, pufftype, false, &linetarget);
P_LineAttack (self, angle, Range, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage);
if (!linetarget)
{
@ -180,8 +181,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
}
}
if (LifeSteal)
P_GiveBody (self, (damage * LifeSteal) >> FRACBITS);
if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS);
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);

View file

@ -240,6 +240,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
player_t *player;
const PClass *pufftype;
AActor *linetarget;
int actualdamage = 0;
if (NULL == (player = self->player))
{
@ -273,7 +274,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
pufftype = PClass::FindClass("GauntletPuff1");
}
slope = P_AimLineAttack (self, angle, dist, &linetarget);
P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &linetarget);
P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage);
if (!linetarget)
{
if (pr_gatk() > 64)
@ -298,7 +299,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
}
if (power)
{
P_GiveBody (self, damage>>1);
if (!(linetarget->flags5 & MF5_DONTDRAIN)) P_GiveBody (self, actualdamage>>1);
S_Sound (self, CHAN_AUTO, "weapons/gauntletspowhit", 1, ATTN_NORM);
}
else

View file

@ -1262,7 +1262,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
// If the damaging player has the power of drain, give the player 50% of the damage
// done in health.
if ( source && source->player && source->player->cheats & CF_DRAIN)
if ( source && source->player && source->player->cheats & CF_DRAIN && !(target->flags5 & MF5_DONTDRAIN))
{
if (!target->player || target->player != source->player)
{

View file

@ -460,8 +460,8 @@ enum // P_LineAttack flags
LAF_NORANDOMPUFFZ = 2
};
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL);
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL);
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL);
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL);
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version

View file

@ -3496,7 +3496,7 @@ static ETraceStatus CheckForSpectral (FTraceResults &res, void *userdata)
//==========================================================================
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
int pitch, int damage, FName damageType, const PClass *pufftype, int flags, AActor **victim)
int pitch, int damage, FName damageType, const PClass *pufftype, int flags, AActor **victim, int *actualdamage)
{
fixed_t vx, vy, vz, shootz;
FTraceResults trace;
@ -3514,6 +3514,10 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
{
*victim = NULL;
}
if (actualdamage != NULL)
{
*actualdamage = 0;
}
angle >>= ANGLETOFINESHIFT;
pitch = (angle_t)(pitch) >> ANGLETOFINESHIFT;
@ -3684,6 +3688,10 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
killPuff = true;
}
newdam = P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags);
if (actualdamage != NULL)
{
*actualdamage = newdam;
}
}
if (!(puffDefaults != NULL && puffDefaults->flags3&MF3_BLOODLESSIMPACT))
{
@ -3741,7 +3749,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
}
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
int pitch, int damage, FName damageType, FName pufftype, int flags, AActor **victim)
int pitch, int damage, FName damageType, FName pufftype, int flags, AActor **victim, int *actualdamage)
{
const PClass * type = PClass::FindClass(pufftype);
if (victim != NULL)
@ -3754,7 +3762,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
}
else
{
return P_LineAttack(t1, angle, distance, pitch, damage, damageType, type, flags, victim);
return P_LineAttack(t1, angle, distance, pitch, damage, damageType, type, flags, victim, actualdamage);
}
return NULL;
}

View file

@ -1388,6 +1388,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
angle_t angle;
int pitch;
AActor * linetarget;
int actualdamage;
if (!norandom) Damage *= (pr_cwpunch()%8+1);
@ -1404,13 +1405,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff);
int puffFlags = LAF_ISMELEEATTACK | (flags & CPF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
P_LineAttack (self, angle, Range, pitch, Damage, NAME_Melee, PuffType, puffFlags, &linetarget);
P_LineAttack (self, angle, Range, pitch, Damage, NAME_Melee, PuffType, puffFlags, &linetarget, &actualdamage);
// turn to face target
if (linetarget)
{
if (LifeSteal)
P_GiveBody (self, (Damage * LifeSteal) >> FRACBITS);
if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS);
if (weapon != NULL)
{

View file

@ -182,6 +182,7 @@ static FFlagDef ActorFlags[]=
DEFINE_FLAG(MF4, NOSKIN, AActor, flags4),
DEFINE_FLAG(MF4, BOSSDEATH, AActor, flags4),
DEFINE_FLAG(MF5, DONTDRAIN, AActor, flags5),
DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5),
DEFINE_FLAG(MF5, COUNTSECRET, AActor, flags5),
DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5),