split bfg self-damage code into its own function, A_RadiusDamageSelf

This commit is contained in:
Xaser Acheron 2016-06-13 19:38:00 -05:00 committed by Christoph Oelckers
parent 481ef7a5b5
commit de0301a704
4 changed files with 72 additions and 34 deletions

View file

@ -653,7 +653,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
PARAM_ANGLE_OPT (vrange) { vrange = 0.; }
PARAM_INT_OPT (defdamage) { defdamage = 0; }
PARAM_INT_OPT (flags) { flags = 0; }
PARAM_FLOAT_OPT (damrad) { damrad = 0; }
int i;
int j;
@ -661,7 +660,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
DAngle an;
FTranslatedLineTarget t;
AActor *originator;
double origdist;
if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra");
if (numrays <= 0) numrays = 40;
@ -674,37 +672,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
if (!self->target)
return 0;
// [XA] If damrad is set, check the originator and hurt them if too close.
// adapted from SMMU's BFG11K code with fraggle's blessing.
origdist = self->Distance2D(self->target);
if (origdist < damrad)
{
// [XA] Decrease damage with distance. This uses SMMU's formula
// and is included mainly for emulation's sake. For more
// customization, seek out A_Explode rather than this.
damage = 0;
for (j = 0; j < (damrad / 2) - (origdist / 2); ++j)
damage += (pr_bfgspray() & 7) + 1;
// [XA] flash n' damage -- some slight copypasta here, but it works.
AActor *spray = Spawn(spraytype, self->target->PosPlusZ(self->target->Height / 4), ALLOW_REPLACE);
int dmgFlags = 0;
FName dmgType = NAME_BFGSplash;
if (spray != NULL)
{
// [XA] skip the species check since we've already decided to damage oneself.
if (spray->flags5 & MF5_PUFFGETSOWNER) spray->target = self->target;
if (spray->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL;
if (spray->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA;
dmgType = spray->DamageType;
}
int selfdam = P_DamageMobj(self->target, self, self->target, damage, dmgType, dmgFlags);
P_TraceBleed(selfdam > 0 ? selfdam : damage, self->target, self);
}
// [XA] Set the originator of the rays to the projectile (self) if
// the new flag is set, else set it to the player (self->target)
originator = (flags & BFGF_MISSILEORIGIN) ? self : self->target;

View file

@ -95,6 +95,7 @@ static FRandom pr_spawnitemex ("SpawnItemEx");
static FRandom pr_burst ("Burst");
static FRandom pr_monsterrefire ("MonsterRefire");
static FRandom pr_teleport("A_Teleport");
static FRandom pr_bfgselfdamage("BFGSelfDamage");
//==========================================================================
//
@ -1334,6 +1335,72 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust)
return 0;
}
//==========================================================================
//
// A_RadiusDamageSelf
//
//==========================================================================
enum
{
RDSF_BFGDAMAGE = 1,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusDamageSelf)
{
PARAM_ACTION_PROLOGUE;
PARAM_INT_OPT(damage) { damage = 128; }
PARAM_FLOAT_OPT(distance) { distance = 128; }
PARAM_INT_OPT(flags) { flags = 0; }
PARAM_CLASS_OPT(flashtype, AActor) { flashtype = NULL; }
int i;
int damageSteps;
int actualDamage;
double actualDistance;
actualDistance = self->Distance3D(self->target);
if (actualDistance < distance)
{
// [XA] Decrease damage with distance. Use the BFG damage
// calculation formula if the flag is set (essentially
// a generalization of SMMU's BFG11K behavior, used
// with fraggle's blessing.)
damageSteps = damage - int(damage * actualDistance / distance);
if (flags & RDSF_BFGDAMAGE)
{
actualDamage = 0;
for (i = 0; i < damageSteps; ++i)
actualDamage += (pr_bfgselfdamage() & 7) + 1;
}
else
{
actualDamage = damageSteps;
}
// optional "flash" effect -- spawn an actor on
// the player to indicate bad things happened.
AActor *flash = NULL;
if(flashtype != NULL)
flash = Spawn(flashtype, self->target->PosPlusZ(self->target->Height / 4), ALLOW_REPLACE);
int dmgFlags = 0;
FName dmgType = NAME_BFGSplash;
if (flash != NULL)
{
if (flash->flags5 & MF5_PUFFGETSOWNER) flash->target = self->target;
if (flash->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL;
if (flash->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA;
dmgType = flash->DamageType;
}
int newdam = P_DamageMobj(self->target, self, self->target, actualDamage, dmgType, dmgFlags);
P_TraceBleed(newdam > 0 ? newdam : actualDamage, self->target, self);
}
return 0;
}
//==========================================================================
//
// Execute a line special / script

View file

@ -56,7 +56,7 @@ ACTOR Actor native //: Thinker
// End of MBF redundant functions.
action native A_MonsterRail();
action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0, float damrad = 0);
action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0);
action native A_Pain();
action native A_NoBlocking();
action native A_XScream();
@ -247,6 +247,7 @@ ACTOR Actor native //: Thinker
native void A_Burst(class<Actor> chunktype);
action native A_Blast(int flags = 0, float strength = 255, float radius = 255, float speed = 20, class<Actor> blasteffect = "BlastEffect", sound blastsound = "BlastRadius");
action native A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0);
action native A_RadiusDamageSelf(int damage = 128, float distance = 128, int flags = 0, class<Actor> flashtype = "None");
action native A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff");
action native A_Stop();
action native A_Respawn(int flags = 1);

View file

@ -184,6 +184,9 @@ const int RTF_NOIMPACTDAMAGE = 2;
const int RTF_NOTMISSILE = 4;
const int RTF_THRUSTZ = 16;
// Flags for A_RadiusDamageSelf
const int RDSF_BFGDAMAGE = 1;
// Flags for A_Blast
const int BF_USEAMMO = 1;
const int BF_DONTWARN = 2;