mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
- Added the following flags, all affixed with CPXF_:
- NODISTANCE: Disables distance checking. - CHECKSIGHT: The qualifying actor must be in sight in order to count. - SET<TARGET/MASTER/TRACER>: Gets the first qualifying actor and sets the calling actor's specified pointer to it. - SETONPTR: If the function is being aimed at another actor other than the caller, sets that actor's pointers instead. Requires a SET* flag to work. - FARTHEST: The actor farthest from the checking actor is set as the pointer. Requires a SET* flag to work. - CLOSEST: The closest qualifying actor is set as the pointer. Requires a SET* flag to work.
This commit is contained in:
parent
efaaccc030
commit
ccc694bbcd
2 changed files with 82 additions and 9 deletions
|
@ -5908,6 +5908,14 @@ enum CPXFflags
|
||||||
CPXF_COUNTDEAD = 1 << 3,
|
CPXF_COUNTDEAD = 1 << 3,
|
||||||
CPXF_DEADONLY = 1 << 4,
|
CPXF_DEADONLY = 1 << 4,
|
||||||
CPXF_EXACT = 1 << 5,
|
CPXF_EXACT = 1 << 5,
|
||||||
|
CPXF_SETTARGET = 1 << 6,
|
||||||
|
CPXF_SETMASTER = 1 << 7,
|
||||||
|
CPXF_SETTRACER = 1 << 8,
|
||||||
|
CPXF_FARTHEST = 1 << 9,
|
||||||
|
CPXF_CLOSEST = 1 << 10,
|
||||||
|
CPXF_SETONPTR = 1 << 11,
|
||||||
|
CPXF_NODISTANCE = 1 << 12,
|
||||||
|
CPXF_CHECKSIGHT = 1 << 13,
|
||||||
};
|
};
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity)
|
||||||
{
|
{
|
||||||
|
@ -5920,17 +5928,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity)
|
||||||
ACTION_PARAM_INT(ptr, 5);
|
ACTION_PARAM_INT(ptr, 5);
|
||||||
|
|
||||||
ACTION_SET_RESULT(false); //No inventory chain results please.
|
ACTION_SET_RESULT(false); //No inventory chain results please.
|
||||||
|
|
||||||
|
if (!jump)
|
||||||
|
{
|
||||||
|
if (!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
AActor *ref = COPY_AAPTR(self, ptr);
|
AActor *ref = COPY_AAPTR(self, ptr);
|
||||||
|
|
||||||
//We need these to check out.
|
//We need these to check out.
|
||||||
if (!ref || !jump || !classname || distance <= 0)
|
if (!ref || !classname || ((distance <= 0) && !(flags & CPXF_NODISTANCE)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
const double distsquared = (double)distance * (double)distance;
|
||||||
|
double closer, farther = 0, current = closer = distsquared;
|
||||||
|
const bool ptrWillChange = !!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER));
|
||||||
|
const bool ptrDistPref = !!(flags & (CPXF_CLOSEST | CPXF_FARTHEST));
|
||||||
|
|
||||||
|
|
||||||
TThinkerIterator<AActor> it;
|
TThinkerIterator<AActor> it;
|
||||||
AActor * mo;
|
AActor *mo, *dist = NULL;
|
||||||
|
|
||||||
//[MC] Process of elimination, I think, will get through this as quickly and
|
//[MC] Process of elimination, I think, will get through this as quickly and
|
||||||
//efficiently as possible.
|
//efficiently as possible.
|
||||||
|
@ -5949,12 +5968,37 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity)
|
||||||
else if (classname != mo->GetClass())
|
else if (classname != mo->GetClass())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//Make sure it's in range and respect the desire for Z or not.
|
//[MC]Make sure it's in range and respect the desire for Z or not. The function forces it to use
|
||||||
if (P_AproxDistance(ref->x - mo->x, ref->y - mo->y) < distance &&
|
//Z later for ensuring CLOSEST and FARTHEST flags are respected perfectly.
|
||||||
((flags & CPXF_NOZ) ||
|
//Ripped from sphere checking in A_RadiusGive (along with a number of things).
|
||||||
((ref->z > mo->z && ref->z - (mo->z + mo->height) < distance) ||
|
|
||||||
(ref->z <= mo->z && mo->z - (ref->z + ref->height) < distance))))
|
TVector3<double> spos(ref->x, ref->y, ((flags & CPXF_NOZ) ? 0 : (ref->z + ref->height / 2)));
|
||||||
|
TVector3<double> tpos(mo->x, mo->y, ((flags & CPXF_NOZ) ? 0 : (mo->z + mo->height / 2)));
|
||||||
|
if ((flags & CPXF_NODISTANCE) || (tpos - spos).LengthSquared() <= distsquared)
|
||||||
{
|
{
|
||||||
|
if ((flags & CPXF_CHECKSIGHT) && !(P_CheckSight(mo, ref, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ptrWillChange && ptrDistPref)
|
||||||
|
{
|
||||||
|
spos.Z = ref->z + ref->height / 2; //This one cannot have NOZ checking.
|
||||||
|
tpos.Z = mo->z + mo->height / 2;
|
||||||
|
current = (tpos - spos).LengthSquared();
|
||||||
|
|
||||||
|
if ((flags & CPXF_CLOSEST) && ((current < closer) || !closer))
|
||||||
|
{
|
||||||
|
dist = mo;
|
||||||
|
closer = current; //This actor's closer. Set the new standard.
|
||||||
|
}
|
||||||
|
else if ((flags & CPXF_FARTHEST) && (current > farther))
|
||||||
|
{
|
||||||
|
dist = mo;
|
||||||
|
farther = current;
|
||||||
|
}
|
||||||
|
else if (!dist)
|
||||||
|
dist = mo; //Just get the last one and call it quits if there's nothing selected.
|
||||||
|
}
|
||||||
|
|
||||||
if (mo->flags6 & MF6_KILLED)
|
if (mo->flags6 & MF6_KILLED)
|
||||||
{
|
{
|
||||||
if (!(flags & (CPXF_COUNTDEAD | CPXF_DEADONLY)))
|
if (!(flags & (CPXF_COUNTDEAD | CPXF_DEADONLY)))
|
||||||
|
@ -5972,17 +6016,38 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity)
|
||||||
if (counter > count)
|
if (counter > count)
|
||||||
{
|
{
|
||||||
result = (flags & (CPXF_LESSOREQUAL | CPXF_EXACT)) ? false : true;
|
result = (flags & (CPXF_LESSOREQUAL | CPXF_EXACT)) ? false : true;
|
||||||
break;
|
|
||||||
|
//However, if we have one SET* flag and either the closest or farthest flags, keep the funcion going.
|
||||||
|
if (ptrWillChange && ptrDistPref)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ptrWillChange && dist != NULL)
|
||||||
|
{
|
||||||
|
if (flags & CPXF_SETONPTR)
|
||||||
|
{
|
||||||
|
if (flags & CPXF_SETTARGET) ref->target = dist;
|
||||||
|
if (flags & CPXF_SETMASTER) ref->master = dist;
|
||||||
|
if (flags & CPXF_SETTRACER) ref->tracer = dist;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flags & CPXF_SETTARGET) self->target = dist;
|
||||||
|
if (flags & CPXF_SETMASTER) self->master = dist;
|
||||||
|
if (flags & CPXF_SETTRACER) self->tracer = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (counter == count)
|
if (counter == count)
|
||||||
result = true;
|
result = true;
|
||||||
else if (counter < count)
|
else if (counter < count)
|
||||||
result = !!((flags & CPXF_LESSOREQUAL) && !(flags & CPXF_EXACT));
|
result = !!((flags & CPXF_LESSOREQUAL) && !(flags & CPXF_EXACT));
|
||||||
|
|
||||||
|
if (!jump) return;
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
|
|
@ -497,6 +497,14 @@ enum
|
||||||
CPXF_COUNTDEAD = 1 << 3,
|
CPXF_COUNTDEAD = 1 << 3,
|
||||||
CPXF_DEADONLY = 1 << 4,
|
CPXF_DEADONLY = 1 << 4,
|
||||||
CPXF_EXACT = 1 << 5,
|
CPXF_EXACT = 1 << 5,
|
||||||
|
CPXF_SETTARGET = 1 << 6,
|
||||||
|
CPXF_SETMASTER = 1 << 7,
|
||||||
|
CPXF_SETTRACER = 1 << 8,
|
||||||
|
CPXF_FARTHEST = 1 << 9,
|
||||||
|
CPXF_CLOSEST = 1 << 10,
|
||||||
|
CPXF_SETONPTR = 1 << 11,
|
||||||
|
CPXF_NODISTANCE = 1 << 12,
|
||||||
|
CPXF_CHECKSIGHT = 1 << 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flags for A_CheckBlock
|
// Flags for A_CheckBlock
|
||||||
|
|
Loading…
Reference in a new issue