diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index dab68867b..9333a09d4 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4880,17 +4880,19 @@ enum RadiusGiveFlags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) { - ACTION_PARAM_START(6); + ACTION_PARAM_START(7); ACTION_PARAM_CLASS(item, 0); ACTION_PARAM_FIXED(distance, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_INT(amount, 3); ACTION_PARAM_CLASS(filter, 4); ACTION_PARAM_NAME(species, 5); + ACTION_PARAM_FIXED(mindist, 6); // We need a valid item, valid targets, and a valid range - if (item == NULL || (flags & RGF_MASK) == 0 || !flags || distance <= 0) + if (item == NULL || (flags & RGF_MASK) == 0 || !flags || distance <= 0 || mindist >= distance) { + ACTION_SET_RESULT(false); return; } @@ -4899,9 +4901,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) amount = 1; } FBlockThingsIterator it(FBoundingBox(self->x, self->y, distance)); - double distsquared = double(distance) * double(distance); AActor *thing; + bool given = false; while ((thing = it.Next())) { //[MC] Check for a filter, species, and the related exfilter/expecies/either flag(s). @@ -4946,7 +4948,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) bool corpsePass = !!((flags & RGF_CORPSES) && thing->flags & MF_CORPSE); bool killedPass = !!((flags & RGF_KILLED) && thing->flags6 & MF6_KILLED); bool monsterPass = !!((flags & RGF_MONSTERS) && thing->flags3 & MF3_ISMONSTER); - bool objectPass = !!((flags & RGF_OBJECTS) && ((thing->flags & MF_SHOOTABLE) || (thing->flags6 & MF6_VULNERABLE))); + bool objectPass = !!((flags & RGF_OBJECTS) && (thing->player == NULL) && (!(thing->flags3 & MF3_ISMONSTER)) + && ((thing->flags & MF_SHOOTABLE) || (thing->flags6 & MF6_VULNERABLE))); bool playerPass = !!((flags & RGF_PLAYERS) && (thing->player != NULL) && (thing->player->mo == thing)); bool voodooPass = !!((flags & RGF_VOODOO) && (thing->player != NULL) && (thing->player->mo != thing)); //Self calls priority over the rest of this. @@ -4969,20 +4972,26 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass) { + if (flags & RGF_CUBE) { // check if inside a cube - if (fabs((double)thing->x - self->x) > (double)distance || - fabs((double)thing->y - self->y) > (double)distance || - fabs((double)(thing->z + thing->height / 2) - (self->z + self->height / 2)) > (double)distance) + double dx = fabs((double)(thing->x - self->x)); + double dy = fabs((double)(thing->y - self->y)); + double dz = fabs((double)(thing->z + thing->height / 2) - (self->z + self->height / 2)); + double dist = (double)distance; + double min = (double)mindist; + if ((dx > dist || dy > dist || dz > dist) || (min && (dx < min && dy < min && dz < min))) { continue; } } else { // check if inside a sphere + double distsquared = double(distance) * double(distance); + double minsquared = double(mindist) * double(mindist); TVector3 tpos(thing->x, thing->y, thing->z + thing->height / 2); TVector3 spos(self->x, self->y, self->z + self->height / 2); - if ((tpos - spos).LengthSquared() > distsquared) + if ((tpos - spos).LengthSquared() > distsquared || (minsquared && ((tpos - spos).LengthSquared() < minsquared))) { continue; } @@ -5005,9 +5014,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) { gift->Destroy(); } + else + { + given = true; + } } } } + ACTION_SET_RESULT(given); } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 5877192ce..4832865c7 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -257,7 +257,7 @@ ACTOR Actor native //: Thinker action native A_JumpIfInTargetInventory(class itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT); action native A_GiveToTarget(class itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT); action native A_TakeFromTarget(class itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT); - action native A_RadiusGive(class itemtype, int distance, int flags, int amount = 0, class filter = "None", name species = "None"); + action native A_RadiusGive(class itemtype, int distance, int flags, int amount = 0, class filter = "None", name species = "None", int mindist = 0); action native A_CountdownArg(int argnum, state targstate = ""); action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true); action native A_CustomComboAttack(class missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);