- Added A_CheckBlock(state block, int flags, int ptr).

- Performs a jump if an actor or a line is in the way.
- Can be used without a jump state if the desire is only to have a pointer change.
- CBF_NOLINES disables jumping if a line is involved.
- CBF_SET* flags set the target, master or tracer to whoever is blocking, for the actor calling the function.
- CBF_SETONPTR causes the pointer changing flags to apply to the pointed actor instead of itself.
This commit is contained in:
MajorCooke 2015-10-04 16:00:40 -05:00
parent 125afcf3de
commit 154e023800
3 changed files with 74 additions and 1 deletions

View file

@ -5846,3 +5846,64 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRipMax)
self->RipLevelMax = max;
}
/*===========================================================================
A_CheckBlock
(state block, int flags, int ptr)
Checks if something is blocking the actor('s pointer) 'ptr'.
The SET pointer flags only affect the caller, not the pointer.
===========================================================================*/
enum CBF
{
CBF_NOLINES = 1 << 0, //Don't check actors.
CBF_SETTARGET = 1 << 1, //Sets the caller/pointer's target to the actor blocking it. Actors only.
CBF_SETMASTER = 1 << 2, //^ but with master.
CBF_SETTRACER = 1 << 3, //^ but with tracer.
CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self.
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock)
{
ACTION_PARAM_START(3);
ACTION_PARAM_STATE(block, 0);
ACTION_PARAM_INT(flags, 1);
ACTION_PARAM_INT(ptr, 2);
AActor *mobj = COPY_AAPTR(self, ptr);
ACTION_SET_RESULT(false);
//Needs at least one state jump to work.
if (!mobj)
{
return;
}
bool blockTest = P_TestMobjLocation(mobj);
//Nothing to block it so skip the rest.
if (blockTest) return;
if (mobj->BlockingMobj)
{
AActor *setter = (flags & CBF_SETONPTR) ? mobj : self;
if (setter)
{
if (flags & CBF_SETTARGET) setter->target = mobj->BlockingMobj;
if (flags & CBF_SETMASTER) setter->master = mobj->BlockingMobj;
if (flags & CBF_SETTRACER) setter->tracer = mobj->BlockingMobj;
}
}
//[MC] If modders don't want jumping, but just getting the pointer, only abort at
//this point. I.e. A_CheckBlock("",CBF_SETTRACER) is like having CBF_NOLINES.
//It gets the mobj blocking, if any, and doesn't jump at all.
if (!block)
return;
//[MC] Easiest way to tell if an actor is blocking it, use the pointers.
if (!blockTest && (mobj->BlockingMobj || (!(flags & CBF_NOLINES) && mobj->BlockingLine != NULL)))
{
ACTION_JUMP(block);
}
}

View file

@ -336,7 +336,7 @@ ACTOR Actor native //: Thinker
action native A_SetRipperLevel(int level);
action native A_SetRipMin(int min);
action native A_SetRipMax(int max);
action native A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT);
action native A_CheckSightOrRange(float distance, state label, bool two_dimension = false);
action native A_CheckRange(float distance, state label, bool two_dimension = false);

View file

@ -482,5 +482,17 @@ enum
QF_WAVE = 1 << 5,
};
// Flags for A_CheckBlock
// These flags only affect the calling actor('s pointer), not the ones being searched.
enum
{
CBF_NOLINES = 1 << 0, //Don't check actors.
CBF_SETTARGET = 1 << 1, //Sets the caller/pointer's target to the actor blocking it. Actors only.
CBF_SETMASTER = 1 << 2, //^ but with master.
CBF_SETTRACER = 1 << 3, //^ but with tracer.
CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self.
};
// This is only here to provide one global variable for testing.
native int testglobalvar;