From afaa88a4604028d968041bcd708e4a42354a7ae7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 Sep 2014 08:48:36 +0200 Subject: [PATCH 1/3] - consolidated the common portion of the 6 different A_Damage* functions into a subfunction. --- src/thingdef/thingdef_codeptr.cpp | 335 ++++++++++-------------------- 1 file changed, 106 insertions(+), 229 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index c257a4f70..3893b3a1b 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3610,156 +3610,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) ACTION_JUMP(jump); } -enum DMSS -{ - DMSS_FOILINVUL = 1, - DMSS_AFFECTARMOR = 2, - DMSS_KILL = 4, -}; - -//=========================================================================== -// -// A_DamageMaster (int amount, str damagetype, int flags) -// Damages the master of this child by the specified amount. Negative values heal. -// -//=========================================================================== -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster) -{ - ACTION_PARAM_START(3); - ACTION_PARAM_INT(amount, 0); - ACTION_PARAM_NAME(DamageType, 1); - ACTION_PARAM_INT(flags, 2); - - - - if (self->master != NULL) - { - if ((amount > 0) || (flags & DMSS_KILL)) - { - if (!(self->master->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) - { - if (flags & DMSS_KILL) - { - P_DamageMobj(self->master, self, self, self->master->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); - } - if (flags & DMSS_AFFECTARMOR) - { - P_DamageMobj(self->master, self, self, amount, DamageType, DMG_FOILINVUL); - } - else - { - P_DamageMobj(self->master, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); - } - } - } - else if (amount < 0) - { - amount = -amount; - P_GiveBody(self->master, amount); - } - } -} - -//=========================================================================== -// -// A_DamageChildren (amount, str damagetype, int flags) -// Damages the children of this master by the specified amount. Negative values heal. -// -//=========================================================================== -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren) -{ - TThinkerIterator it; - AActor * mo; - - ACTION_PARAM_START(3); - ACTION_PARAM_INT(amount, 0); - ACTION_PARAM_NAME(DamageType, 1); - ACTION_PARAM_INT(flags, 2); - - while ( (mo = it.Next()) ) - { - if (mo->master == self) - { - if ((amount > 0) || (flags & DMSS_KILL)) //Bypass if kill flag is present; it won't matter. It intends to kill them. - { - if (!(mo->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) - { - if (flags & DMSS_KILL) - { - P_DamageMobj(mo, self, self, mo->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); - } - if (flags & DMSS_AFFECTARMOR) - { - P_DamageMobj(mo, self, self, amount, DamageType, DMG_FOILINVUL); - } - else - { - P_DamageMobj(mo, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); - } - } - } - else if (amount < 0) - { - amount = -amount; - P_GiveBody(mo, amount); - } - } - } -} - -// [KS] *** End of my modifications *** - -//=========================================================================== -// -// A_DamageSiblings (int amount, str damagetype, int flags) -// Damages the siblings of this master by the specified amount. Negative values heal. -// -//=========================================================================== -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) -{ - TThinkerIterator it; - AActor * mo; - - ACTION_PARAM_START(3); - ACTION_PARAM_INT(amount, 0); - ACTION_PARAM_NAME(DamageType, 1); - ACTION_PARAM_INT(flags, 2); - - if (self->master != NULL) - { - while ((mo = it.Next())) - { - if (mo->master == self->master && mo != self) - { - if ((amount > 0) || (flags & DMSS_KILL)) - { - if (!(mo->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) - { - if (flags & DMSS_KILL) - { - P_DamageMobj(mo, self, self, mo->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); - } - if (flags & DMSS_AFFECTARMOR) - { - P_DamageMobj(mo, self, self, amount, DamageType, DMG_FOILINVUL); - } - else - { - P_DamageMobj(mo, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); - } - } - else if (amount < 0) - { - amount = -amount; - P_GiveBody(mo, amount); - } - } - } - } - } -} - - //=========================================================================== // // Modified code pointer from Skulltag @@ -5131,8 +4981,51 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) //=========================================================================== // -// A_DamageSelf (int amount, str damagetype, int flags) -// Damages the calling actor by the specified amount. Negative values heal. +// Common A_Damage handler +// +// A_Damage* (int amount, str damagetype, int flags) +// Damages the specified actor by the specified amount. Negative values heal. +// +//=========================================================================== + +enum DMSS +{ + DMSS_FOILINVUL = 1, + DMSS_AFFECTARMOR = 2, + DMSS_KILL = 4, +}; + +static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags) +{ + if ((amount > 0) || (flags & DMSS_KILL)) + { + if (!(dmgtarget->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) + { + if (flags & DMSS_KILL) + { + P_DamageMobj(dmgtarget, self, self, dmgtarget->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); + } + if (flags & DMSS_AFFECTARMOR) + { + P_DamageMobj(dmgtarget, self, self, amount, DamageType, DMG_FOILINVUL); + } + else + { + //[MC] DMG_FOILINVUL is needed for making the damage occur on the actor. + P_DamageMobj(dmgtarget, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); + } + } + } + else if (amount < 0) + { + amount = -amount; + P_GiveBody(dmgtarget, amount); + } +} + +//=========================================================================== +// +// // //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSelf) @@ -5142,36 +5035,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSelf) ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); - if ((amount > 0) || (flags & DMSS_KILL)) - { - if (!(self->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) - { - if (flags & DMSS_KILL) - { - P_DamageMobj(self, self, self, self->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); - } - if (flags & DMSS_AFFECTARMOR) - { - P_DamageMobj(self, self, self, amount, DamageType, DMG_FOILINVUL); - } - else - { - //[MC] DMG_FOILINVUL is needed for making the damage occur on the actor. - P_DamageMobj(self, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); - } - } - } - else if (amount < 0) - { - amount = -amount; - P_GiveBody(self, amount); - } + DoDamage(self, self, amount, DamageType, flags); } //=========================================================================== // -// A_DamageTarget (int amount, str damagetype, int flags) -// Damages the target of the actor by the specified amount. Negative values heal. +// // //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTarget) @@ -5181,38 +5050,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTarget) ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); - if (self->target != NULL) - { - if ((amount > 0) || (flags & DMSS_KILL)) - { - if (!(self->target->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) - { - if (flags & DMSS_KILL) - { - P_DamageMobj(self->target, self, self, self->target->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); - } - if (flags & DMSS_AFFECTARMOR) - { - P_DamageMobj(self->target, self, self, amount, DamageType, DMG_FOILINVUL); - } - else - { - P_DamageMobj(self->target, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); - } - } - } - else if (amount < 0) - { - amount = -amount; - P_GiveBody(self->target, amount); - } - } + if (self->target != NULL) DoDamage(self->target, self, amount, DamageType, flags); } //=========================================================================== // -// A_DamageTracer (int amount, str damagetype, int flags) -// Damages the tracer of the actor by the specified amount. Negative values heal. +// // //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTracer) @@ -5222,31 +5065,65 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTracer) ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); - if (self->target != NULL) - { + if (self->tracer != NULL) DoDamage(self->tracer, self, amount, DamageType, flags); +} - if ((amount > 0) || (flags & DMSS_KILL)) +//=========================================================================== +// +// +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster) +{ + ACTION_PARAM_START(3); + ACTION_PARAM_INT(amount, 0); + ACTION_PARAM_NAME(DamageType, 1); + ACTION_PARAM_INT(flags, 2); + + if (self->master != NULL) DoDamage(self->master, self, amount, DamageType, flags); +} + +//=========================================================================== +// +// +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren) +{ + ACTION_PARAM_START(3); + ACTION_PARAM_INT(amount, 0); + ACTION_PARAM_NAME(DamageType, 1); + ACTION_PARAM_INT(flags, 2); + + TThinkerIterator it; + AActor * mo; + + while ( (mo = it.Next()) ) + { + if (mo->master == self) DoDamage(mo, self, amount, DamageType, flags); + } +} + +//=========================================================================== +// +// +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) +{ + ACTION_PARAM_START(3); + ACTION_PARAM_INT(amount, 0); + ACTION_PARAM_NAME(DamageType, 1); + ACTION_PARAM_INT(flags, 2); + + TThinkerIterator it; + AActor * mo; + + if (self->master != NULL) + { + while ((mo = it.Next())) { - if (!(self->tracer->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) - { - if (flags & DMSS_KILL) - { - P_DamageMobj(self->tracer, self, self, self->tracer->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); - } - if (flags & DMSS_AFFECTARMOR) - { - P_DamageMobj(self->tracer, self, self, amount, DamageType, DMG_FOILINVUL); - } - else - { - P_DamageMobj(self->tracer, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); - } - } - } - else if (amount < 0) - { - amount = -amount; - P_GiveBody(self->tracer, amount); + if (mo->master == self->master && mo != self) DoDamage(mo, self, amount, DamageType, flags); } } } From e025f4090221746fc35db4065a2d1455117d737b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 Sep 2014 08:54:18 +0200 Subject: [PATCH 2/3] - more redundancy removal: Consolidated the common part of the A_Kill* functions into a subfunction. --- src/thingdef/thingdef_codeptr.cpp | 267 +++++++++++------------------- 1 file changed, 96 insertions(+), 171 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 3893b3a1b..7c2653580 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2675,133 +2675,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIf) } -enum KILS -{ - KILS_FOILINVUL = 1 << 0, - KILS_KILLMISSILES = 1 << 1, - KILS_NOMONSTERS = 1 << 2, -}; - -//=========================================================================== -// -// A_KillMaster(damagetype, int flags) -// -//=========================================================================== -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillMaster) -{ - ACTION_PARAM_START(2); - ACTION_PARAM_NAME(damagetype, 0); - ACTION_PARAM_INT(flags, 1); - - if (self->master != NULL) - { - if ((self->master->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) - { - //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! - //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE - //since that's the whole point of it. - if ((!(self->master->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && !(self->master->flags5 & MF5_NODAMAGE)) - { - P_ExplodeMissile(self->master, NULL, NULL); - } - } - if (!(flags & KILS_NOMONSTERS)) - { - if (flags & KILS_FOILINVUL) - { - P_DamageMobj(self->master, self, self, self->master->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR | DMG_FOILINVUL); - } - else - { - P_DamageMobj(self->master, self, self, self->master->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR); - } - } - } -} - -//=========================================================================== -// -// A_KillChildren(damagetype, int flags) -// -//=========================================================================== -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillChildren) -{ - ACTION_PARAM_START(2); - ACTION_PARAM_NAME(damagetype, 0); - ACTION_PARAM_INT(flags, 1); - - TThinkerIterator it; - AActor *mo; - - while ( (mo = it.Next()) ) - { - if (mo->master == self) - { - if ((mo->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) - { - if ((!(mo->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && !(mo->flags5 & MF5_NODAMAGE)) - { - P_ExplodeMissile(mo, NULL, NULL); - } - } - if (!(flags & KILS_NOMONSTERS)) - { - if (flags & KILS_FOILINVUL) - { - P_DamageMobj(mo, self, self, mo->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR | DMG_FOILINVUL); - } - else - { - P_DamageMobj(mo, self, self, mo->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR); - } - } - } - } -} - -//=========================================================================== -// -// A_KillSiblings(damagetype, int flags) -// -//=========================================================================== -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings) -{ - ACTION_PARAM_START(2); - ACTION_PARAM_NAME(damagetype, 0); - ACTION_PARAM_INT(flags, 1); - - TThinkerIterator it; - AActor *mo; - - if (self->master != NULL) - { - while ( (mo = it.Next()) ) - { - if (mo->master == self->master && mo != self) - { - if ((mo->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) - { - if ((!(mo->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && !(mo->flags5 & MF5_NODAMAGE)) - { - P_ExplodeMissile(mo, NULL, NULL); - } - } - if (!(flags & KILS_NOMONSTERS)) - { - if (flags & KILS_FOILINVUL) - { - P_DamageMobj(mo, self, self, mo->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR | DMG_FOILINVUL); - } - else - { - P_DamageMobj(mo, self, self, mo->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR); - } - } - } - } - } -} - //=========================================================================== // // A_CountdownArg @@ -5128,6 +5001,46 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) } } + +//=========================================================================== +// +// A_Kill*(damagetype, int flags) +// +//=========================================================================== +enum KILS +{ + KILS_FOILINVUL = 1 << 0, + KILS_KILLMISSILES = 1 << 1, + KILS_NOMONSTERS = 1 << 2, +}; + +static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags) +{ + if ((killtarget->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) + { + //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! + //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE + //since that's the whole point of it. + if ((!(killtarget->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && !(killtarget->flags5 & MF5_NODAMAGE)) + { + P_ExplodeMissile(self->target, NULL, NULL); + } + } + if (!(flags & KILS_NOMONSTERS)) + { + if (flags & KILS_FOILINVUL) + { + P_DamageMobj(killtarget, self, self, killtarget->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR | DMG_FOILINVUL); + } + else + { + P_DamageMobj(killtarget, self, self, killtarget->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR); + } + } +} + + + //=========================================================================== // // A_KillTarget(damagetype, int flags) @@ -5139,30 +5052,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTarget) ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); - if (self->target != NULL) - { - if ((self->target->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) - { - //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! - //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE - //since that's the whole point of it. - if ((!(self->target->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && !(self->target->flags5 & MF5_NODAMAGE)) - { - P_ExplodeMissile(self->target, NULL, NULL); - } - } - if (!(flags & KILS_NOMONSTERS)) - { - if (flags & KILS_FOILINVUL) - { - P_DamageMobj(self->target, self, self, self->target->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR | DMG_FOILINVUL); - } - else - { - P_DamageMobj(self->target, self, self, self->target->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR); - } - } - } + if (self->target != NULL) DoKill(self->target, self, damagetype, flags); } //=========================================================================== @@ -5176,32 +5066,67 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTracer) ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); - if (self->tracer != NULL) + if (self->tracer != NULL) DoKill(self->tracer, self, damagetype, flags); +} + +//=========================================================================== +// +// A_KillMaster(damagetype, int flags) +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillMaster) +{ + ACTION_PARAM_START(2); + ACTION_PARAM_NAME(damagetype, 0); + ACTION_PARAM_INT(flags, 1); + + if (self->master != NULL) DoKill(self->master, self, damagetype, flags); +} + +//=========================================================================== +// +// A_KillChildren(damagetype, int flags) +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillChildren) +{ + ACTION_PARAM_START(2); + ACTION_PARAM_NAME(damagetype, 0); + ACTION_PARAM_INT(flags, 1); + + TThinkerIterator it; + AActor *mo; + + while ( (mo = it.Next()) ) { - if ((self->tracer->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) + if (mo->master == self) DoKill(mo, self, damagetype, flags); + } +} + +//=========================================================================== +// +// A_KillSiblings(damagetype, int flags) +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings) +{ + ACTION_PARAM_START(2); + ACTION_PARAM_NAME(damagetype, 0); + ACTION_PARAM_INT(flags, 1); + + TThinkerIterator it; + AActor *mo; + + if (self->master != NULL) + { + while ( (mo = it.Next()) ) { - //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! - //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE - //since that's the whole point of it. - if ((!(self->tracer->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && !(self->tracer->flags5 & MF5_NODAMAGE)) - { - P_ExplodeMissile(self->tracer, NULL, NULL); - } - } - if (!(flags & KILS_NOMONSTERS)) - { - if (flags & KILS_FOILINVUL) - { - P_DamageMobj(self->tracer, self, self, self->tracer->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR | DMG_FOILINVUL); - } - else - { - P_DamageMobj(self->tracer, self, self, self->tracer->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR); - } + if (mo->master == self->master && mo != self) DoKill(mo, self, damagetype, flags); } } } + //=========================================================================== // // A_RemoveTarget From 68c481945ad95098390b75153ea14b83e13c2cb7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 Sep 2014 09:36:38 +0200 Subject: [PATCH 3/3] - extended parameter list of A_BFGSpray. --- src/g_doom/a_doomweaps.cpp | 29 ++++++++++++++++++++++------- wadsrc/static/actors/actor.txt | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 424e691e7..38c823e18 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -546,6 +546,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG) P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindClass("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); } + // // A_BFGSpray // Spawn a BFG explosion on every monster in view @@ -559,14 +560,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) AActor *thingToHit; AActor *linetarget; - ACTION_PARAM_START(3); + ACTION_PARAM_START(7); ACTION_PARAM_CLASS(spraytype, 0); ACTION_PARAM_INT(numrays, 1); ACTION_PARAM_INT(damagecnt, 2); + ACTION_PARAM_ANGLE(angle, 3); + ACTION_PARAM_FIXED(distance, 4); + ACTION_PARAM_ANGLE(vrange, 5); + ACTION_PARAM_INT(defdamage, 6); if (spraytype == NULL) spraytype = PClass::FindClass("BFGExtra"); if (numrays <= 0) numrays = 40; if (damagecnt <= 0) damagecnt = 15; + if (angle == 0) angle = ANG90; + if (distance <= 0) distance = 16 * 64 * FRACUNIT; + if (vrange == 0) vrange = ANGLE_1 * 32; // [RH] Don't crash if no target if (!self->target) @@ -575,10 +583,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) // offset angles from its attack angle for (i = 0; i < numrays; i++) { - an = self->angle - ANG90/2 + ANG90/numrays*i; + an = self->angle - angle/2 + angle/numrays*i; // self->target is the originator (player) of the missile - P_AimLineAttack (self->target, an, 16*64*FRACUNIT, &linetarget, ANGLE_1*32); + P_AimLineAttack (self->target, an, distance, &linetarget, vrange); if (!linetarget) continue; @@ -589,10 +597,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) if (spray && (spray->flags5 & MF5_PUFFGETSOWNER)) spray->target = self->target; - - damage = 0; - for (j = 0; j < damagecnt; ++j) - damage += (pr_bfgspray() & 7) + 1; + if (defdamage == 0) + { + damage = 0; + for (j = 0; j < damagecnt; ++j) + damage += (pr_bfgspray() & 7) + 1; + } + else + { + // if this is used, damagecnt will be ignored + damage = defdamage; + } thingToHit = linetarget; int newdam = P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash), diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 52a0338fe..d404f23a2 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -70,7 +70,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); + action native A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float angle = 90, float distance = 16*64, float vrange = 32, int damage = 0); action native A_Pain(); action native A_NoBlocking(); action native A_XScream();