From de0301a7049c226c654c4c039ab000cddfdf7f7b Mon Sep 17 00:00:00 2001 From: Xaser Acheron Date: Mon, 13 Jun 2016 19:38:00 -0500 Subject: [PATCH] split bfg self-damage code into its own function, A_RadiusDamageSelf --- src/g_doom/a_doomweaps.cpp | 33 --------------- src/thingdef/thingdef_codeptr.cpp | 67 ++++++++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 3 +- wadsrc/static/actors/constants.txt | 3 ++ 4 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index f985e6ed5..5bba7bbf1 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -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; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index e2bda69d0..000f8385c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -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 diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 103d8be5b..220e9e5e8 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -56,7 +56,7 @@ ACTOR Actor native //: Thinker // End of MBF redundant functions. action native A_MonsterRail(); - action native A_BFGSpray(class 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 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 chunktype); action native A_Blast(int flags = 0, float strength = 255, float radius = 255, float speed = 20, class 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 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 pufftype = "BulletPuff"); action native A_Stop(); action native A_Respawn(int flags = 1); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 813e56195..c43a3b2aa 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -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;