mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- added FDARI's latest actor pointer submission.
SVN r3222 (trunk)
This commit is contained in:
parent
0991d45838
commit
f69181f851
7 changed files with 366 additions and 150 deletions
118
src/actorptrselect.h
Normal file
118
src/actorptrselect.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
#pragma once
|
||||
|
||||
#include "p_pspr.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Standard pointer acquisition functions
|
||||
//
|
||||
// Use COPY_AAPTR(pointer_owner, AActor *assigntovariable, AAPTR selector)
|
||||
// Use COPY_AAPTR_NOT_NULL to return from a function if the pointer is NULL
|
||||
//
|
||||
// Possible effective results at run-time
|
||||
// assigntovariable = NULL (or a RETURN statement is issued)
|
||||
// P_BulletSlope(pointer_owner, &temporary), assigntovariable = temporary
|
||||
// assigntovariable = pointer_owner->target or ...->master or ...->tracer
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
||||
// Pointer selectors (enum)
|
||||
|
||||
enum AAPTR
|
||||
{
|
||||
AAPTR_DEFAULT = 0,
|
||||
AAPTR_NULL = 0x1,
|
||||
AAPTR_TARGET = 0x2,
|
||||
AAPTR_MASTER = 0x4,
|
||||
AAPTR_TRACER = 0x8,
|
||||
|
||||
AAPTR_PLAYER_GETTARGET = 0x10,
|
||||
AAPTR_PLAYER_GETCONVERSATION = 0x20,
|
||||
|
||||
AAPTR_PLAYER1 = 0x40,
|
||||
AAPTR_PLAYER2 = 0x80,
|
||||
AAPTR_PLAYER3 = 0x100,
|
||||
AAPTR_PLAYER4 = 0x200,
|
||||
AAPTR_PLAYER5 = 0x400,
|
||||
AAPTR_PLAYER6 = 0x800,
|
||||
AAPTR_PLAYER7 = 0x1000,
|
||||
AAPTR_PLAYER8 = 0x2000,
|
||||
|
||||
AAPTR_FRIENDPLAYER = 0x4000,
|
||||
|
||||
AAPTR_PLAYER_SELECTORS =
|
||||
AAPTR_PLAYER_GETTARGET|AAPTR_PLAYER_GETCONVERSATION,
|
||||
|
||||
AAPTR_GENERAL_SELECTORS =
|
||||
AAPTR_TARGET|AAPTR_MASTER|AAPTR_TRACER|AAPTR_FRIENDPLAYER,
|
||||
|
||||
AAPTR_STATIC_SELECTORS =
|
||||
AAPTR_PLAYER1|AAPTR_PLAYER2|AAPTR_PLAYER3|AAPTR_PLAYER4|
|
||||
AAPTR_PLAYER5|AAPTR_PLAYER6|AAPTR_PLAYER7|AAPTR_PLAYER8|
|
||||
AAPTR_NULL
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
PROCESS_AAPTR
|
||||
|
||||
Result overview in order of priority:
|
||||
|
||||
1. Caller is player and a player specific selector is specified: Player specific selector is used.
|
||||
2. Caller is non-null and a general actor selector is specified: General actor selector is used.
|
||||
3. A static actor selector is specified: Static actor selector is used.
|
||||
4. The origin actor is used.
|
||||
|
||||
Only one selector of each type can be used.
|
||||
*/
|
||||
|
||||
#define AAPTR_RESOLVE_PLAYERNUM(playernum) (playeringame[playernum] ? players[playernum].mo : NULL)
|
||||
|
||||
static AActor *PROCESS_AAPTR(AActor *origin, int selector)
|
||||
{
|
||||
if (origin)
|
||||
{
|
||||
if (origin->player)
|
||||
{
|
||||
switch (selector & AAPTR_PLAYER_SELECTORS)
|
||||
{
|
||||
case AAPTR_PLAYER_GETTARGET:
|
||||
{
|
||||
AActor *gettarget = NULL;
|
||||
P_BulletSlope(origin, &gettarget);
|
||||
return gettarget;
|
||||
}
|
||||
case AAPTR_PLAYER_GETCONVERSATION:
|
||||
return origin->player->ConversationNPC;
|
||||
}
|
||||
}
|
||||
|
||||
switch (selector & AAPTR_GENERAL_SELECTORS)
|
||||
{
|
||||
case AAPTR_TARGET: return origin->target;
|
||||
case AAPTR_MASTER: return origin->master;
|
||||
case AAPTR_TRACER: return origin->tracer;
|
||||
case AAPTR_FRIENDPLAYER:
|
||||
return origin->FriendPlayer ? AAPTR_RESOLVE_PLAYERNUM(origin->FriendPlayer - 1) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (selector & AAPTR_STATIC_SELECTORS)
|
||||
{
|
||||
case AAPTR_PLAYER1: return AAPTR_RESOLVE_PLAYERNUM(0);
|
||||
case AAPTR_PLAYER2: return AAPTR_RESOLVE_PLAYERNUM(1);
|
||||
case AAPTR_PLAYER3: return AAPTR_RESOLVE_PLAYERNUM(2);
|
||||
case AAPTR_PLAYER4: return AAPTR_RESOLVE_PLAYERNUM(3);
|
||||
case AAPTR_PLAYER5: return AAPTR_RESOLVE_PLAYERNUM(4);
|
||||
case AAPTR_PLAYER6: return AAPTR_RESOLVE_PLAYERNUM(5);
|
||||
case AAPTR_PLAYER7: return AAPTR_RESOLVE_PLAYERNUM(6);
|
||||
case AAPTR_PLAYER8: return AAPTR_RESOLVE_PLAYERNUM(7);
|
||||
case AAPTR_NULL: return NULL;
|
||||
}
|
||||
|
||||
return origin;
|
||||
}
|
||||
|
||||
#define COPY_AAPTR_NOT_NULL(source, destination, selector) { destination = PROCESS_AAPTR(source, selector); if (!destination) return; }
|
||||
#define COPY_AAPTR(source, destination, selector) { destination = PROCESS_AAPTR(source, selector); }
|
|
@ -26,6 +26,7 @@ struct FFlagDef
|
|||
|
||||
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2);
|
||||
void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int index);
|
||||
bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index);
|
||||
const char *GetFlagName(int flagnum, int flagoffset);
|
||||
|
||||
#define FLAG_NAME(flagnum, flagvar) GetFlagName(flagnum, myoffsetof(AActor, flagvar))
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "doomstat.h"
|
||||
#include "v_palette.h"
|
||||
#include "g_shared/a_specialspot.h"
|
||||
#include "actorptrselect.h"
|
||||
|
||||
|
||||
static FRandom pr_camissile ("CustomActorfire");
|
||||
|
@ -159,15 +160,14 @@ inline static bool isMissile(AActor * self, bool precise=true)
|
|||
//==========================================================================
|
||||
|
||||
|
||||
enum AAPTR
|
||||
{
|
||||
AAPTR_DEFAULT = 0,
|
||||
AAPTR_NULL = 0x1,
|
||||
AAPTR_TARGET = 0x2,
|
||||
AAPTR_MASTER = 0x4,
|
||||
AAPTR_TRACER = 0x8
|
||||
enum PTROP
|
||||
{
|
||||
PTROP_UNSAFETARGET = 1,
|
||||
PTROP_UNSAFEMASTER = 2,
|
||||
PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER
|
||||
};
|
||||
|
||||
|
||||
// [FDARI] Exported logic for guarding against loops in Target (for missiles) and Master (for all) chains.
|
||||
// It is called from multiple locations.
|
||||
// The code may be in need of optimisation.
|
||||
|
@ -186,8 +186,8 @@ void VerifyTargetChain(AActor *self, bool preciseMissileCheck=true)
|
|||
AActor *compare = self;
|
||||
// every new actor must prove not to be the first actor in the chain, or any subsequent actor
|
||||
// any actor up to and including "origin" has only appeared once
|
||||
do
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (compare == next)
|
||||
{
|
||||
// if any of the actors from self to (inclusive) origin match the next actor,
|
||||
|
@ -197,7 +197,7 @@ void VerifyTargetChain(AActor *self, bool preciseMissileCheck=true)
|
|||
}
|
||||
if (compare == origin) break; // when "compare" = origin, we know that the next actor is, and should be "next"
|
||||
compare = compare->target;
|
||||
} while (true); // we're never leaving the loop here
|
||||
}
|
||||
|
||||
origin = next;
|
||||
next = next->target;
|
||||
|
@ -214,7 +214,7 @@ void VerifyMasterChain(AActor *self)
|
|||
while (next) // We always care (See "VerifyTargetChain")
|
||||
{
|
||||
AActor *compare = self;
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
if (compare == next)
|
||||
{
|
||||
|
@ -223,21 +223,13 @@ void VerifyMasterChain(AActor *self)
|
|||
}
|
||||
if (compare == origin) break;
|
||||
compare = compare->master;
|
||||
} while (true); // we're never leaving the loop here
|
||||
}
|
||||
|
||||
origin = next;
|
||||
next = next->master;
|
||||
}
|
||||
}
|
||||
|
||||
enum PTROP
|
||||
{
|
||||
PTROP_UNSAFETARGET = 1,
|
||||
PTROP_UNSAFEMASTER = 2,
|
||||
PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_RearrangePointers
|
||||
|
@ -341,35 +333,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_TransferPointer)
|
|||
|
||||
// Exchange pointers with actors to whom you have pointers (or with yourself, if you must)
|
||||
|
||||
switch (ptr_source) // pick an actor to provide a pointer
|
||||
{
|
||||
case AAPTR_DEFAULT: source = self; break;
|
||||
case AAPTR_TARGET: source = self->target; break;
|
||||
case AAPTR_MASTER: source = self->master; break;
|
||||
case AAPTR_TRACER: source = self->tracer; break;
|
||||
default: return;
|
||||
}
|
||||
COPY_AAPTR(self, source, ptr_source);
|
||||
COPY_AAPTR_NOT_NULL(self, recepient, ptr_recepient); // pick an actor to store the provided pointer value
|
||||
|
||||
if (!source) return; // you must pick somebody. MAYBE we should make a null assignment instead of just returning.
|
||||
|
||||
switch (ptr_recepient) // pick an actor to store the provided pointer value
|
||||
{
|
||||
case AAPTR_DEFAULT: recepient = self; break;
|
||||
case AAPTR_TARGET: recepient = self->target; break;
|
||||
case AAPTR_MASTER: recepient = self->master; break;
|
||||
case AAPTR_TRACER: recepient = self->tracer; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (!recepient) return; // you must pick somebody. No way we can even make a null assignment here.
|
||||
|
||||
switch (ptr_sourcefield) // convert source from dataprovider to data
|
||||
{
|
||||
case AAPTR_TARGET: source = source->target; break; // now we don't care where the data comes from anymore
|
||||
case AAPTR_MASTER: source = source->master; break; // so we reassign source; it now holds the data itself
|
||||
case AAPTR_TRACER: source = source->tracer; break;
|
||||
default: source = NULL;
|
||||
}
|
||||
// convert source from dataprovider to data
|
||||
|
||||
COPY_AAPTR(source, source, ptr_sourcefield);
|
||||
|
||||
if (source == recepient) source = NULL; // The recepient should not acquire a pointer to itself; will write NULL
|
||||
|
||||
|
@ -409,16 +378,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CopyFriendliness)
|
|||
if (self->player) return;
|
||||
|
||||
AActor *source;
|
||||
|
||||
switch (ptr_source)
|
||||
{
|
||||
case AAPTR_TARGET: source = self->target; break;
|
||||
case AAPTR_MASTER: source = self->master; break;
|
||||
case AAPTR_TRACER: source = self->tracer; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (source) self->CopyFriendliness(source, false, false); // Overriding default behaviour: No modification of health
|
||||
COPY_AAPTR_NOT_NULL(self, source, ptr_source);
|
||||
self->CopyFriendliness(source, false, false); // No change in current target or health
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -812,14 +773,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfMasterCloser)
|
|||
//==========================================================================
|
||||
void DoJumpIfInventory(AActor * owner, DECLARE_PARAMINFO)
|
||||
{
|
||||
ACTION_PARAM_START(3);
|
||||
ACTION_PARAM_START(4);
|
||||
ACTION_PARAM_CLASS(Type, 0);
|
||||
ACTION_PARAM_INT(ItemAmount, 1);
|
||||
ACTION_PARAM_STATE(JumpOffset, 2);
|
||||
ACTION_PARAM_INT(setowner, 3);
|
||||
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
|
||||
if (!Type || owner == NULL) return;
|
||||
if (!Type) return;
|
||||
COPY_AAPTR_NOT_NULL(owner, owner, setowner); // returns if owner ends up being NULL
|
||||
|
||||
AInventory *Item = owner->FindInventory(Type);
|
||||
|
||||
|
@ -1669,31 +1632,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
|
|||
|
||||
static void DoGiveInventory(AActor * receiver, DECLARE_PARAMINFO)
|
||||
{
|
||||
ACTION_PARAM_START(3); // param count up
|
||||
ACTION_PARAM_START(3);
|
||||
ACTION_PARAM_CLASS(mi, 0);
|
||||
ACTION_PARAM_INT(amount, 1);
|
||||
|
||||
// [FDARI] Modified code: Allow any pointer to be used for receiver
|
||||
ACTION_PARAM_INT(setreceiver, 2);
|
||||
|
||||
switch (setreceiver)
|
||||
{
|
||||
case AAPTR_TARGET:
|
||||
if (receiver->target) { receiver = receiver->target; break; }
|
||||
return;
|
||||
case AAPTR_MASTER:
|
||||
if (receiver->master) { receiver = receiver->master; break; }
|
||||
return;
|
||||
case AAPTR_TRACER:
|
||||
if (receiver->tracer) { receiver = receiver->tracer; break; }
|
||||
return;
|
||||
}
|
||||
|
||||
// FDARI: End of modified code
|
||||
COPY_AAPTR_NOT_NULL(receiver, receiver, setreceiver);
|
||||
|
||||
bool res=true;
|
||||
if (receiver == NULL) return;
|
||||
|
||||
|
||||
if (amount==0) amount=1;
|
||||
if (mi)
|
||||
{
|
||||
|
@ -1743,30 +1690,14 @@ enum
|
|||
|
||||
void DoTakeInventory(AActor * receiver, DECLARE_PARAMINFO)
|
||||
{
|
||||
ACTION_PARAM_START(4); // param count up
|
||||
ACTION_PARAM_START(4);
|
||||
ACTION_PARAM_CLASS(item, 0);
|
||||
ACTION_PARAM_INT(amount, 1);
|
||||
ACTION_PARAM_INT(flags, 2);
|
||||
|
||||
// [FDARI] Modified code: Allow any pointer to be used for receiver
|
||||
ACTION_PARAM_INT(setreceiver, 3);
|
||||
|
||||
switch (setreceiver)
|
||||
{
|
||||
case AAPTR_TARGET:
|
||||
if (receiver->target) { receiver = receiver->target; break; }
|
||||
return;
|
||||
case AAPTR_MASTER:
|
||||
if (receiver->master) { receiver = receiver->master; break; }
|
||||
return;
|
||||
case AAPTR_TRACER:
|
||||
if (receiver->tracer) { receiver = receiver->tracer; break; }
|
||||
return;
|
||||
}
|
||||
|
||||
// FDARI: End of modified code
|
||||
|
||||
if (item == NULL || receiver == NULL) return;
|
||||
if (!item) return;
|
||||
COPY_AAPTR_NOT_NULL(receiver, receiver, setreceiver);
|
||||
|
||||
bool res = false;
|
||||
|
||||
|
@ -2917,6 +2848,10 @@ enum JLOS_flags
|
|||
JLOSF_CLOSENOJUMP=16,
|
||||
JLOSF_DEADNOJUMP=32,
|
||||
JLOSF_CHECKMASTER=64,
|
||||
JLOSF_TARGETLOS=128,
|
||||
JLOSF_FLIPFOV=256,
|
||||
JLOSF_ALLYNOJUMP=512,
|
||||
JLOSF_COMBATANTONLY=1024
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
|
||||
|
@ -2929,10 +2864,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
|
|||
ACTION_PARAM_FIXED(dist_close, 4);
|
||||
|
||||
angle_t an;
|
||||
AActor *target;
|
||||
AActor *target, *viewport;
|
||||
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
|
||||
bool doCheckSight;
|
||||
|
||||
if (!self->player)
|
||||
{
|
||||
if (flags & JLOSF_CHECKMASTER)
|
||||
|
@ -2952,66 +2889,88 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
|
|||
}
|
||||
|
||||
if (!target) return; // [KS] Let's not call P_CheckSight unnecessarily in this case.
|
||||
|
||||
|
||||
if ((flags & JLOSF_DEADNOJUMP) && (target->health <= 0)) return;
|
||||
|
||||
fixed_t distance = P_AproxDistance(target->x - self->x, target->y - self->y);
|
||||
distance = P_AproxDistance(distance, target->z - self->z);
|
||||
|
||||
if (dist_max && (distance > dist_max)) return;
|
||||
|
||||
bool doCheckSight = !(flags & JLOSF_NOSIGHT);
|
||||
|
||||
if (dist_close && (distance < dist_close))
|
||||
{
|
||||
if (flags & JLOSF_CLOSENOJUMP)
|
||||
return;
|
||||
|
||||
if (flags & JLOSF_CLOSENOFOV)
|
||||
fov = 0;
|
||||
|
||||
if (flags & JLOSF_CLOSENOSIGHT)
|
||||
doCheckSight = false;
|
||||
}
|
||||
|
||||
if (doCheckSight && !P_CheckSight (self, target, SF_IGNOREVISIBILITY))
|
||||
return;
|
||||
|
||||
if (fov && (fov < ANGLE_MAX))
|
||||
{
|
||||
an = R_PointToAngle2 (self->x,
|
||||
self->y,
|
||||
target->x,
|
||||
target->y)
|
||||
- self->angle;
|
||||
|
||||
if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2)))
|
||||
{
|
||||
|
||||
return; // [KS] Outside of FOV - return
|
||||
}
|
||||
|
||||
}
|
||||
doCheckSight = !(flags & JLOSF_NOSIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Does the player aim at something that can be shot?
|
||||
P_BulletSlope(self, &target);
|
||||
|
||||
|
||||
if (!target) return;
|
||||
|
||||
fixed_t distance = P_AproxDistance(target->x - self->x, target->y - self->y);
|
||||
distance = P_AproxDistance(distance, target->z - self->z);
|
||||
|
||||
if (dist_max && (distance > dist_max)) return;
|
||||
|
||||
if (dist_close && (distance < dist_close))
|
||||
switch (flags & (JLOSF_TARGETLOS|JLOSF_FLIPFOV))
|
||||
{
|
||||
if (flags & JLOSF_CLOSENOJUMP)
|
||||
return;
|
||||
case JLOSF_TARGETLOS|JLOSF_FLIPFOV:
|
||||
// target makes sight check, player makes fov check; player has verified fov
|
||||
fov = 0;
|
||||
// fall-through
|
||||
case JLOSF_TARGETLOS:
|
||||
doCheckSight = !(flags & JLOSF_NOSIGHT); // The target is responsible for sight check and fov
|
||||
break;
|
||||
default:
|
||||
// player has verified sight and fov
|
||||
fov = 0;
|
||||
// fall-through
|
||||
case JLOSF_FLIPFOV: // Player has verified sight, but target must verify fov
|
||||
doCheckSight = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// [FDARI] If target is not a combatant, don't jump
|
||||
if ( (flags & JLOSF_COMBATANTONLY) && (!target->player) && !(target->flags3 & MF3_ISMONSTER)) return;
|
||||
|
||||
// [FDARI] If actors share team, don't jump
|
||||
if ((flags & JLOSF_ALLYNOJUMP) && self->IsFriend(target)) return;
|
||||
|
||||
fixed_t distance = P_AproxDistance(target->x - self->x, target->y - self->y);
|
||||
distance = P_AproxDistance(distance, target->z - self->z);
|
||||
|
||||
if (dist_max && (distance > dist_max)) return;
|
||||
|
||||
if (dist_close && (distance < dist_close))
|
||||
{
|
||||
if (flags & JLOSF_CLOSENOJUMP)
|
||||
return;
|
||||
|
||||
if (flags & JLOSF_CLOSENOFOV)
|
||||
fov = 0;
|
||||
|
||||
if (flags & JLOSF_CLOSENOSIGHT)
|
||||
doCheckSight = false;
|
||||
}
|
||||
|
||||
if (flags & JLOSF_TARGETLOS) { viewport = target; target = self; }
|
||||
else { viewport = self; }
|
||||
|
||||
if (doCheckSight && !P_CheckSight (viewport, target, SF_IGNOREVISIBILITY))
|
||||
return;
|
||||
|
||||
if (flags & JLOSF_FLIPFOV)
|
||||
{
|
||||
if (viewport == self) { viewport = target; target = self; }
|
||||
else { target = viewport; viewport = self; }
|
||||
}
|
||||
|
||||
if (fov && (fov < ANGLE_MAX))
|
||||
{
|
||||
an = R_PointToAngle2 (viewport->x,
|
||||
viewport->y,
|
||||
target->x,
|
||||
target->y)
|
||||
- viewport->angle;
|
||||
|
||||
if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2)))
|
||||
{
|
||||
|
||||
return; // [KS] Outside of FOV - return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ACTION_JUMP(jump);
|
||||
}
|
||||
|
||||
|
@ -3352,6 +3311,60 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_CheckFlag
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFlag)
|
||||
{
|
||||
ACTION_PARAM_START(3);
|
||||
ACTION_PARAM_STRING(flagname, 0);
|
||||
ACTION_PARAM_STATE(jumpto, 1);
|
||||
ACTION_PARAM_INT(checkpointer, 2);
|
||||
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
|
||||
AActor *owner;
|
||||
|
||||
COPY_AAPTR_NOT_NULL(self, owner, checkpointer);
|
||||
|
||||
const char *dot = strchr (flagname, '.');
|
||||
FFlagDef *fd;
|
||||
const PClass *cls = owner->GetClass();
|
||||
|
||||
if (dot != NULL)
|
||||
{
|
||||
FString part1(flagname, dot-flagname);
|
||||
fd = FindFlag (cls, part1, dot+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = FindFlag (cls, flagname, NULL);
|
||||
}
|
||||
|
||||
if (fd != NULL)
|
||||
{
|
||||
if (fd->structoffset == -1)
|
||||
{
|
||||
if (CheckDeprecatedFlags(owner, cls->ActorInfo, fd->flagbit)) {
|
||||
ACTION_JUMP(jumpto);
|
||||
}
|
||||
}
|
||||
else if ( fd->flagbit & *(DWORD*)(((char*)owner) + fd->structoffset))
|
||||
{
|
||||
ACTION_JUMP(jumpto);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Unknown flag '%s' in '%s'\n", flagname, cls->TypeName.GetChars());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_RemoveMaster
|
||||
|
|
|
@ -159,6 +159,67 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CheckDeprecatedFlags
|
||||
//
|
||||
// Checks properties related to deprecated flags, and returns true only
|
||||
// if the relevant properties are configured exactly as they would have
|
||||
// been by setting the flag in HandleDeprecatedFlags.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index)
|
||||
{
|
||||
// A deprecated flag is false if
|
||||
// a) it hasn't been added here
|
||||
// b) any property of the actor differs from what it would be after setting the flag using HandleDeprecatedFlags
|
||||
|
||||
// Deprecated flags are normally replaced by something more flexible, which means a multitude of related configurations
|
||||
// will report "false".
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case DEPF_FIREDAMAGE:
|
||||
return actor->DamageType == NAME_Fire;
|
||||
case DEPF_ICEDAMAGE:
|
||||
return actor->DamageType == NAME_Ice;
|
||||
case DEPF_LOWGRAVITY:
|
||||
return actor->gravity == FRACUNIT/8;
|
||||
case DEPF_SHORTMISSILERANGE:
|
||||
return actor->maxtargetrange == 896*FRACUNIT;
|
||||
case DEPF_LONGMELEERANGE:
|
||||
return actor->meleethreshold == 196*FRACUNIT;
|
||||
case DEPF_QUARTERGRAVITY:
|
||||
return actor->gravity == FRACUNIT/4;
|
||||
case DEPF_FIRERESIST:
|
||||
if (info->DamageFactors)
|
||||
{
|
||||
fixed_t *df = info->DamageFactors->CheckKey(NAME_Fire);
|
||||
return df && (*df) == FRACUNIT / 2;
|
||||
}
|
||||
return false;
|
||||
|
||||
case DEPF_HERETICBOUNCE:
|
||||
return (actor->BounceFlags & (BOUNCE_TypeMask|BOUNCE_UseSeeSound)) == BOUNCE_HereticCompat;
|
||||
|
||||
case DEPF_HEXENBOUNCE:
|
||||
return (actor->BounceFlags & (BOUNCE_TypeMask|BOUNCE_UseSeeSound)) == BOUNCE_HexenCompat;
|
||||
|
||||
case DEPF_DOOMBOUNCE:
|
||||
return (actor->BounceFlags & (BOUNCE_TypeMask|BOUNCE_UseSeeSound)) == BOUNCE_DoomCompat;
|
||||
|
||||
case DEPF_PICKUPFLASH:
|
||||
return static_cast<AInventory*>(actor)->PickupFlash == PClass::FindClass("PickupFlash");
|
||||
// A pure name lookup may or may not be more efficient, but I know no static identifier for PickupFlash.
|
||||
|
||||
case DEPF_INTERHUBSTRIP:
|
||||
return !(static_cast<AInventory*>(actor)->InterHubAmount);
|
||||
}
|
||||
|
||||
return false; // Any entirely unknown flag is not set
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -197,7 +197,7 @@ ACTOR Actor native //: Thinker
|
|||
action native A_JumpIfCloser(float distance, state label);
|
||||
action native A_JumpIfTracerCloser(float distance, state label);
|
||||
action native A_JumpIfMasterCloser(float distance, state label);
|
||||
action native A_JumpIfInventory(class<Inventory> itemtype, int itemamount, state label);
|
||||
action native A_JumpIfInventory(class<Inventory> itemtype, int itemamount, state label, int owner = AAPTR_DEFAULT);
|
||||
action native A_JumpIfArmorType(string Type, state label, int amount = 1);
|
||||
action native A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT);
|
||||
action native A_TakeInventory(class<Inventory> itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT);
|
||||
|
@ -219,6 +219,7 @@ ACTOR Actor native //: Thinker
|
|||
action native A_DropInventory(class<Inventory> itemtype);
|
||||
action native A_SetBlend(color color1, float alpha, int tics, color color2 = "");
|
||||
action native A_ChangeFlag(string flagname, bool value);
|
||||
action native A_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT);
|
||||
action native A_JumpIf(bool expression, state label);
|
||||
action native A_RemoveMaster();
|
||||
action native A_RemoveChildren(bool removeall = false);
|
||||
|
@ -238,9 +239,9 @@ ACTOR Actor native //: Thinker
|
|||
action native A_Weave(int xspeed, int yspeed, float xdist, float ydist);
|
||||
|
||||
action native A_Recoil(float xyvel);
|
||||
action native A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label);
|
||||
action native A_GiveToTarget(class<Inventory> itemtype, int amount = 0);
|
||||
action native A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0);
|
||||
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_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT);
|
||||
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<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
|
||||
|
|
|
@ -75,6 +75,10 @@ const int JLOSF_CLOSENOSIGHT = 8;
|
|||
const int JLOSF_CLOSENOJUMP = 16;
|
||||
const int JLOSF_DEADNOJUMP = 32;
|
||||
const int JLOSF_CHECKMASTER = 64;
|
||||
const int JLOSF_TARGETLOS = 128;
|
||||
const int JLOSF_FLIPFOV = 256;
|
||||
const int JLOSF_ALLYNOJUMP = 512;
|
||||
const int JLOSF_COMBATANTONLY = 1024;
|
||||
|
||||
// Flags for A_ChangeVelocity
|
||||
const int CVF_RELATIVE = 1;
|
||||
|
@ -217,6 +221,20 @@ Const Int AAPTR_TARGET = 2;
|
|||
Const Int AAPTR_MASTER = 4;
|
||||
Const Int AAPTR_TRACER = 8;
|
||||
|
||||
Const Int AAPTR_PLAYER_GETTARGET = 16;
|
||||
Const Int AAPTR_PLAYER_GETCONVERSATION = 32;
|
||||
|
||||
Const Int AAPTR_PLAYER1 = 64;
|
||||
Const Int AAPTR_PLAYER2 = 128;
|
||||
Const Int AAPTR_PLAYER3 = 256;
|
||||
Const Int AAPTR_PLAYER4 = 512;
|
||||
Const Int AAPTR_PLAYER5 = 1024;
|
||||
Const Int AAPTR_PLAYER6 = 2048;
|
||||
Const Int AAPTR_PLAYER7 = 4096;
|
||||
Const Int AAPTR_PLAYER8 = 8192;
|
||||
|
||||
Const Int AAPTR_FRIENDPLAYER = 16384;
|
||||
|
||||
// Pointer operation flags
|
||||
|
||||
Const Int PTROP_UNSAFETARGET = 1;
|
||||
|
|
|
@ -1089,6 +1089,10 @@
|
|||
RelativePath=".\src\actor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\actorptrselect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\am_map.h"
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue