- Added mindist parameter to A_RadiusGive.

- Actors must be this far away to receive items. Mindist must be less than distance.
- Fixed RGF_OBJECTS not discriminating players and monsters from shootable or vulnerable actors.
This commit is contained in:
MajorCooke 2015-09-29 11:40:44 -05:00
parent 125afcf3de
commit 28622cecaf
2 changed files with 23 additions and 9 deletions

View file

@ -4880,17 +4880,19 @@ enum RadiusGiveFlags
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
{ {
ACTION_PARAM_START(6); ACTION_PARAM_START(7);
ACTION_PARAM_CLASS(item, 0); ACTION_PARAM_CLASS(item, 0);
ACTION_PARAM_FIXED(distance, 1); ACTION_PARAM_FIXED(distance, 1);
ACTION_PARAM_INT(flags, 2); ACTION_PARAM_INT(flags, 2);
ACTION_PARAM_INT(amount, 3); ACTION_PARAM_INT(amount, 3);
ACTION_PARAM_CLASS(filter, 4); ACTION_PARAM_CLASS(filter, 4);
ACTION_PARAM_NAME(species, 5); ACTION_PARAM_NAME(species, 5);
ACTION_PARAM_FIXED(mindist, 6);
// We need a valid item, valid targets, and a valid range // 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; return;
} }
@ -4899,9 +4901,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
amount = 1; amount = 1;
} }
FBlockThingsIterator it(FBoundingBox(self->x, self->y, distance)); FBlockThingsIterator it(FBoundingBox(self->x, self->y, distance));
double distsquared = double(distance) * double(distance);
AActor *thing; AActor *thing;
bool given = false;
while ((thing = it.Next())) while ((thing = it.Next()))
{ {
//[MC] Check for a filter, species, and the related exfilter/expecies/either flag(s). //[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 corpsePass = !!((flags & RGF_CORPSES) && thing->flags & MF_CORPSE);
bool killedPass = !!((flags & RGF_KILLED) && thing->flags6 & MF6_KILLED); bool killedPass = !!((flags & RGF_KILLED) && thing->flags6 & MF6_KILLED);
bool monsterPass = !!((flags & RGF_MONSTERS) && thing->flags3 & MF3_ISMONSTER); 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 playerPass = !!((flags & RGF_PLAYERS) && (thing->player != NULL) && (thing->player->mo == thing));
bool voodooPass = !!((flags & RGF_VOODOO) && (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. //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 (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass)
{ {
if (flags & RGF_CUBE) if (flags & RGF_CUBE)
{ // check if inside a cube { // check if inside a cube
if (fabs((double)thing->x - self->x) > (double)distance || double dx = fabs((double)(thing->x - self->x));
fabs((double)thing->y - self->y) > (double)distance || double dy = fabs((double)(thing->y - self->y));
fabs((double)(thing->z + thing->height / 2) - (self->z + self->height / 2)) > (double)distance) 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; continue;
} }
} }
else else
{ // check if inside a sphere { // check if inside a sphere
double distsquared = double(distance) * double(distance);
double minsquared = double(mindist) * double(mindist);
TVector3<double> tpos(thing->x, thing->y, thing->z + thing->height / 2); TVector3<double> tpos(thing->x, thing->y, thing->z + thing->height / 2);
TVector3<double> spos(self->x, self->y, self->z + self->height / 2); TVector3<double> 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; continue;
} }
@ -5005,10 +5014,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
{ {
gift->Destroy(); gift->Destroy();
} }
else
{
given = true;
} }
} }
} }
} }
ACTION_SET_RESULT(given);
}
//========================================================================== //==========================================================================

View file

@ -257,7 +257,7 @@ ACTOR Actor native //: Thinker
action native A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT); action native A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT);
action native A_GiveToTarget(class<Inventory> itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT); action native A_GiveToTarget(class<Inventory> itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT);
action native A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT); action native A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT);
action native A_RadiusGive(class<Inventory> itemtype, int distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None"); action native A_RadiusGive(class<Inventory> itemtype, int distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", int mindist = 0);
action native A_CountdownArg(int argnum, state targstate = ""); 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_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);
action native A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true); action native A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);