mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 22:11:43 +00:00
Merge branch 'master' into scripting
Conflicts: src/thingdef/thingdef_codeptr.cpp
This commit is contained in:
commit
36974431ba
11 changed files with 6363 additions and 6285 deletions
|
@ -149,7 +149,8 @@ void cht_DoCheat (player_t *player, int cheat)
|
||||||
case CHT_FLY:
|
case CHT_FLY:
|
||||||
if (player->mo != NULL)
|
if (player->mo != NULL)
|
||||||
{
|
{
|
||||||
if ((player->mo->flags7 ^= MF7_FLYCHEAT) != 0)
|
player->mo->flags7 ^= MF7_FLYCHEAT;
|
||||||
|
if (player->mo->flags7 & MF7_FLYCHEAT)
|
||||||
{
|
{
|
||||||
player->mo->flags |= MF_NOGRAVITY;
|
player->mo->flags |= MF_NOGRAVITY;
|
||||||
player->mo->flags2 |= MF2_FLY;
|
player->mo->flags2 |= MF2_FLY;
|
||||||
|
|
|
@ -137,7 +137,7 @@ inline SDWORD ModDiv (SDWORD num, SDWORD den, SDWORD *dmval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define FLOAT2FIXED(f) xs_Fix<16>::ToFix(f)
|
#define FLOAT2FIXED(f) ((fixed_t)xs_Fix<16>::ToFix(f))
|
||||||
#define FIXED2FLOAT(f) ((f) / float(65536))
|
#define FIXED2FLOAT(f) ((f) / float(65536))
|
||||||
#define FIXED2DBL(f) ((f) / double(65536))
|
#define FIXED2DBL(f) ((f) / double(65536))
|
||||||
|
|
||||||
|
|
|
@ -3594,7 +3594,7 @@ int DoGetMasterTID (AActor *self)
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AActor *SingleActorFromTID (int tid, AActor *defactor)
|
AActor *SingleActorFromTID (int tid, AActor *defactor)
|
||||||
{
|
{
|
||||||
if (tid == 0)
|
if (tid == 0)
|
||||||
{
|
{
|
||||||
|
@ -4421,6 +4421,8 @@ enum EACSFunctions
|
||||||
ACSF_ChangeActorRoll,
|
ACSF_ChangeActorRoll,
|
||||||
ACSF_GetActorRoll,
|
ACSF_GetActorRoll,
|
||||||
ACSF_QuakeEx,
|
ACSF_QuakeEx,
|
||||||
|
ACSF_Warp, // 92
|
||||||
|
|
||||||
/* Zandronum's - these must be skipped when we reach 99!
|
/* Zandronum's - these must be skipped when we reach 99!
|
||||||
-100:ResetMap(0),
|
-100:ResetMap(0),
|
||||||
-101 : PlayerIsSpectator(1),
|
-101 : PlayerIsSpectator(1),
|
||||||
|
@ -5841,6 +5843,45 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
actor = SingleActorFromTID(args[0], activator);
|
actor = SingleActorFromTID(args[0], activator);
|
||||||
return actor != NULL? actor->roll >> 16 : 0;
|
return actor != NULL? actor->roll >> 16 : 0;
|
||||||
|
|
||||||
|
// [ZK] A_Warp in ACS
|
||||||
|
case ACSF_Warp:
|
||||||
|
{
|
||||||
|
int tid_dest = args[0];
|
||||||
|
fixed_t xofs = args[1];
|
||||||
|
fixed_t yofs = args[2];
|
||||||
|
fixed_t zofs = args[3];
|
||||||
|
angle_t angle = args[4];
|
||||||
|
int flags = args[5];
|
||||||
|
const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : "";
|
||||||
|
bool exact = argCount > 7 ? !!args[7] : false;
|
||||||
|
|
||||||
|
FState *state = argCount > 6 ? activator->GetClass()->FindStateByString(statename, exact) : 0;
|
||||||
|
|
||||||
|
AActor *reference;
|
||||||
|
if((flags & WARPF_USEPTR) && tid_dest != AAPTR_DEFAULT)
|
||||||
|
{
|
||||||
|
reference = COPY_AAPTR(activator, tid_dest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reference = SingleActorFromTID(tid_dest, activator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is no actor to warp to, fail.
|
||||||
|
if (!reference)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags))
|
||||||
|
{
|
||||||
|
if (state && argCount > 6)
|
||||||
|
{
|
||||||
|
activator->SetState(state);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -586,7 +586,7 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_DrawRailTrail(AActor *source, const TVector3<double> &start, const TVector3<double> &end, int color1, int color2, double maxdiff, int flags, const PClassActor *spawnclass, angle_t angle, int duration, double sparsity, double drift, int SpiralOffset)
|
void P_DrawRailTrail(AActor *source, const TVector3<double> &start, const TVector3<double> &end, int color1, int color2, double maxdiff_d, int flags, PClassActor *spawnclass, angle_t angle, int duration, double sparsity, double drift, int SpiralOffset)
|
||||||
{
|
{
|
||||||
double length, lengthsquared;
|
double length, lengthsquared;
|
||||||
int steps, i;
|
int steps, i;
|
||||||
|
|
|
@ -88,7 +88,7 @@ void P_RunEffects (void);
|
||||||
|
|
||||||
void P_RunEffect (AActor *actor, int effects);
|
void P_RunEffect (AActor *actor, int effects);
|
||||||
|
|
||||||
void P_DrawRailTrail(AActor *source, const TVector3<double> &start, const TVector3<double> &end, int color1, int color2, double maxdiff = 0, int flags = 0, const PClassActor *spawnclass = NULL, angle_t angle = 0, int duration = 35, double sparsity = 1.0, double drift = 1.0, int SpiralOffset = 270);
|
void P_DrawRailTrail(AActor *source, const TVector3<double> &start, const TVector3<double> &end, int color1, int color2, double maxdiff = 0, int flags = 0, PClassActor *spawnclass = NULL, angle_t angle = 0, int duration = 35, double sparsity = 1.0, double drift = 1.0, int SpiralOffset = 270);
|
||||||
void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int kind);
|
void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int kind);
|
||||||
void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind);
|
void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind);
|
||||||
void P_DisconnectEffect (AActor *actor);
|
void P_DisconnectEffect (AActor *actor);
|
||||||
|
|
|
@ -180,6 +180,31 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser);
|
||||||
bool P_Thing_CanRaise(AActor *thing);
|
bool P_Thing_CanRaise(AActor *thing);
|
||||||
PClassActor *P_GetSpawnableType(int spawnnum);
|
PClassActor *P_GetSpawnableType(int spawnnum);
|
||||||
void InitSpawnablesFromMapinfo();
|
void InitSpawnablesFromMapinfo();
|
||||||
|
int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags);
|
||||||
|
|
||||||
|
enum WARPF
|
||||||
|
{
|
||||||
|
WARPF_ABSOLUTEOFFSET = 0x1,
|
||||||
|
WARPF_ABSOLUTEANGLE = 0x2,
|
||||||
|
WARPF_USECALLERANGLE = 0x4,
|
||||||
|
|
||||||
|
WARPF_NOCHECKPOSITION = 0x8,
|
||||||
|
|
||||||
|
WARPF_INTERPOLATE = 0x10,
|
||||||
|
WARPF_WARPINTERPOLATION = 0x20,
|
||||||
|
WARPF_COPYINTERPOLATION = 0x40,
|
||||||
|
|
||||||
|
WARPF_STOP = 0x80,
|
||||||
|
WARPF_TOFLOOR = 0x100,
|
||||||
|
WARPF_TESTONLY = 0x200,
|
||||||
|
WARPF_ABSOLUTEPOSITION = 0x400,
|
||||||
|
WARPF_BOB = 0x800,
|
||||||
|
WARPF_MOVEPTR = 0x1000,
|
||||||
|
WARPF_USEPTR = 0x2000,
|
||||||
|
WARPF_USETID = 0x2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_MAPUTL
|
// P_MAPUTL
|
||||||
|
@ -479,7 +504,7 @@ void P_TraceBleed (int damage, AActor *target); // random direction version
|
||||||
bool P_HitFloor (AActor *thing);
|
bool P_HitFloor (AActor *thing);
|
||||||
bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true);
|
bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true);
|
||||||
void P_CheckSplash(AActor *self, fixed_t distance);
|
void P_CheckSplash(AActor *self, fixed_t distance);
|
||||||
void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, const PClassActor *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, const PClassActor *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun
|
void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, PClassActor *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, PClassActor *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun
|
||||||
|
|
||||||
enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags
|
enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags
|
||||||
{
|
{
|
||||||
|
|
|
@ -4150,7 +4150,7 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, int color1, int color2, double maxdiff, int railflags, const PClassActor *puffclass, angle_t angleoffset, angle_t pitchoffset, fixed_t distance, int duration, double sparsity, double drift, const PClassActor *spawnclass, int SpiralOffset)
|
void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, int color1, int color2, double maxdiff, int railflags, PClassActor *puffclass, angle_t angleoffset, angle_t pitchoffset, fixed_t distance, int duration, double sparsity, double drift, PClassActor *spawnclass, int SpiralOffset)
|
||||||
{
|
{
|
||||||
fixed_t vx, vy, vz;
|
fixed_t vx, vy, vz;
|
||||||
angle_t angle, pitch;
|
angle_t angle, pitch;
|
||||||
|
|
127
src/p_things.cpp
127
src/p_things.cpp
|
@ -678,3 +678,130 @@ void InitSpawnablesFromMapinfo()
|
||||||
InitClassMap(SpawnableThings, SpawnablesFromMapinfo);
|
InitClassMap(SpawnableThings, SpawnablesFromMapinfo);
|
||||||
InitClassMap(StrifeTypes, ConversationIDsFromMapinfo);
|
InitClassMap(StrifeTypes, ConversationIDsFromMapinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags)
|
||||||
|
{
|
||||||
|
if (flags & WARPF_MOVEPTR)
|
||||||
|
{
|
||||||
|
AActor *temp = reference;
|
||||||
|
reference = caller;
|
||||||
|
caller = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed_t oldx = caller->x;
|
||||||
|
fixed_t oldy = caller->y;
|
||||||
|
fixed_t oldz = caller->z;
|
||||||
|
|
||||||
|
if (!(flags & WARPF_ABSOLUTEANGLE))
|
||||||
|
{
|
||||||
|
angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle;
|
||||||
|
}
|
||||||
|
if (!(flags & WARPF_ABSOLUTEPOSITION))
|
||||||
|
{
|
||||||
|
if (!(flags & WARPF_ABSOLUTEOFFSET))
|
||||||
|
{
|
||||||
|
angle_t fineangle = angle >> ANGLETOFINESHIFT;
|
||||||
|
fixed_t xofs1 = xofs;
|
||||||
|
|
||||||
|
// (borrowed from A_SpawnItemEx, assumed workable)
|
||||||
|
// in relative mode negative y values mean 'left' and positive ones mean 'right'
|
||||||
|
// This is the inverse orientation of the absolute mode!
|
||||||
|
|
||||||
|
xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]);
|
||||||
|
yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & WARPF_TOFLOOR)
|
||||||
|
{
|
||||||
|
// set correct xy
|
||||||
|
|
||||||
|
caller->SetOrigin(
|
||||||
|
reference->x + xofs,
|
||||||
|
reference->y + yofs,
|
||||||
|
reference->z);
|
||||||
|
|
||||||
|
// now the caller's floorz should be appropriate for the assigned xy-position
|
||||||
|
// assigning position again with
|
||||||
|
|
||||||
|
if (zofs)
|
||||||
|
{
|
||||||
|
// extra unlink, link and environment calculation
|
||||||
|
caller->SetOrigin(
|
||||||
|
caller->x,
|
||||||
|
caller->y,
|
||||||
|
caller->floorz + zofs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if there is no offset, there should be no ill effect from moving down to the already defined floor
|
||||||
|
|
||||||
|
// A_Teleport does the same thing anyway
|
||||||
|
caller->z = caller->floorz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
caller->SetOrigin(
|
||||||
|
reference->x + xofs,
|
||||||
|
reference->y + yofs,
|
||||||
|
reference->z + zofs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's.
|
||||||
|
{
|
||||||
|
if (flags & WARPF_TOFLOOR)
|
||||||
|
{
|
||||||
|
caller->SetOrigin(xofs, yofs, caller->floorz + zofs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
caller->SetOrigin(xofs, yofs, zofs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & WARPF_NOCHECKPOSITION) || P_TestMobjLocation(caller))
|
||||||
|
{
|
||||||
|
if (flags & WARPF_TESTONLY)
|
||||||
|
{
|
||||||
|
caller->SetOrigin(oldx, oldy, oldz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
caller->angle = angle;
|
||||||
|
|
||||||
|
if (flags & WARPF_STOP)
|
||||||
|
{
|
||||||
|
caller->velx = 0;
|
||||||
|
caller->vely = 0;
|
||||||
|
caller->velz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & WARPF_WARPINTERPOLATION)
|
||||||
|
{
|
||||||
|
caller->PrevX += caller->x - oldx;
|
||||||
|
caller->PrevY += caller->y - oldy;
|
||||||
|
caller->PrevZ += caller->z - oldz;
|
||||||
|
}
|
||||||
|
else if (flags & WARPF_COPYINTERPOLATION)
|
||||||
|
{
|
||||||
|
caller->PrevX = caller->x + reference->PrevX - reference->x;
|
||||||
|
caller->PrevY = caller->y + reference->PrevY - reference->y;
|
||||||
|
caller->PrevZ = caller->z + reference->PrevZ - reference->z;
|
||||||
|
}
|
||||||
|
else if (!(flags & WARPF_INTERPOLATE))
|
||||||
|
{
|
||||||
|
caller->PrevX = caller->x;
|
||||||
|
caller->PrevY = caller->y;
|
||||||
|
caller->PrevZ = caller->z;
|
||||||
|
}
|
||||||
|
if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB))
|
||||||
|
{
|
||||||
|
caller->z += reference->GetBobOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
caller->SetOrigin(oldx, oldy, oldz);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -73,6 +73,8 @@
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
|
|
||||||
|
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||||
|
|
||||||
|
|
||||||
static FRandom pr_camissile ("CustomActorfire");
|
static FRandom pr_camissile ("CustomActorfire");
|
||||||
static FRandom pr_camelee ("CustomMelee");
|
static FRandom pr_camelee ("CustomMelee");
|
||||||
|
@ -4382,7 +4384,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTBOOL was_moving = self->velx | self->vely | self->velz;
|
INTBOOL was_moving = ref->velx | ref->vely | ref->velz;
|
||||||
|
|
||||||
ref->velx = FixedMul(ref->velx, scale);
|
ref->velx = FixedMul(ref->velx, scale);
|
||||||
ref->vely = FixedMul(ref->vely, scale);
|
ref->vely = FixedMul(ref->vely, scale);
|
||||||
|
@ -4445,7 +4447,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeVelocity)
|
||||||
|
|
||||||
if (was_moving)
|
if (was_moving)
|
||||||
{
|
{
|
||||||
CheckStopped(self);
|
CheckStopped(ref);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5009,26 +5011,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
enum WARPF
|
|
||||||
{
|
|
||||||
WARPF_ABSOLUTEOFFSET = 0x1,
|
|
||||||
WARPF_ABSOLUTEANGLE = 0x2,
|
|
||||||
WARPF_USECALLERANGLE = 0x4,
|
|
||||||
|
|
||||||
WARPF_NOCHECKPOSITION = 0x8,
|
|
||||||
|
|
||||||
WARPF_INTERPOLATE = 0x10,
|
|
||||||
WARPF_WARPINTERPOLATION = 0x20,
|
|
||||||
WARPF_COPYINTERPOLATION = 0x40,
|
|
||||||
|
|
||||||
WARPF_STOP = 0x80,
|
|
||||||
WARPF_TOFLOOR = 0x100,
|
|
||||||
WARPF_TESTONLY = 0x200,
|
|
||||||
WARPF_ABSOLUTEPOSITION = 0x400,
|
|
||||||
WARPF_BOB = 0x800,
|
|
||||||
WARPF_MOVEPTR = 0x1000,
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp)
|
||||||
{
|
{
|
||||||
PARAM_ACTION_PROLOGUE;
|
PARAM_ACTION_PROLOGUE;
|
||||||
|
@ -5040,7 +5022,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp)
|
||||||
PARAM_INT_OPT(flags) { flags = 0; }
|
PARAM_INT_OPT(flags) { flags = 0; }
|
||||||
PARAM_STATE_OPT(success_state) { success_state = NULL; }
|
PARAM_STATE_OPT(success_state) { success_state = NULL; }
|
||||||
|
|
||||||
AActor *reference = COPY_AAPTR(self, destination_selector);
|
|
||||||
|
AActor *reference;
|
||||||
|
|
||||||
|
if ((flags & WARPF_USETID))
|
||||||
|
{
|
||||||
|
reference = SingleActorFromTID(destination_selector, self);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reference = COPY_AAPTR(self, destination_selector);
|
||||||
|
}
|
||||||
|
|
||||||
//If there is no actor to warp to, fail.
|
//If there is no actor to warp to, fail.
|
||||||
if (!reference)
|
if (!reference)
|
||||||
|
@ -5049,130 +5041,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp)
|
||||||
return numret;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
AActor *caller = self;
|
if (P_Thing_Warp(self, reference, xofs, yofs, zofs, angle, flags))
|
||||||
|
|
||||||
if (flags & WARPF_MOVEPTR)
|
|
||||||
{
|
{
|
||||||
AActor *temp = reference;
|
|
||||||
reference = caller;
|
|
||||||
caller = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
fixed_t oldx = caller->x;
|
|
||||||
fixed_t oldy = caller->y;
|
|
||||||
fixed_t oldz = caller->z;
|
|
||||||
|
|
||||||
if (!(flags & WARPF_ABSOLUTEANGLE))
|
|
||||||
{
|
|
||||||
angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flags & WARPF_ABSOLUTEPOSITION))
|
|
||||||
{
|
|
||||||
if (!(flags & WARPF_ABSOLUTEOFFSET))
|
|
||||||
{
|
|
||||||
angle_t fineangle = angle >> ANGLETOFINESHIFT;
|
|
||||||
fixed_t xofs1 = xofs;
|
|
||||||
|
|
||||||
// (borrowed from A_SpawnItemEx, assumed workable)
|
|
||||||
// in relative mode negative y values mean 'left' and positive ones mean 'right'
|
|
||||||
// This is the inverse orientation of the absolute mode!
|
|
||||||
|
|
||||||
xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]);
|
|
||||||
yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & WARPF_TOFLOOR)
|
|
||||||
{
|
|
||||||
// set correct xy
|
|
||||||
|
|
||||||
caller->SetOrigin(
|
|
||||||
reference->x + xofs,
|
|
||||||
reference->y + yofs,
|
|
||||||
reference->z);
|
|
||||||
|
|
||||||
// now the caller's floorz should be appropriate for the assigned xy-position
|
|
||||||
// assigning position again with
|
|
||||||
|
|
||||||
if (zofs)
|
|
||||||
{
|
|
||||||
// extra unlink, link and environment calculation
|
|
||||||
caller->SetOrigin(
|
|
||||||
caller->x,
|
|
||||||
caller->y,
|
|
||||||
caller->floorz + zofs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if there is no offset, there should be no ill effect from moving down to the
|
|
||||||
// already identified floor
|
|
||||||
|
|
||||||
// A_Teleport does the same thing anyway
|
|
||||||
caller->z = caller->floorz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
caller->SetOrigin(
|
|
||||||
reference->x + xofs,
|
|
||||||
reference->y + yofs,
|
|
||||||
reference->z + zofs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //[MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's.
|
|
||||||
{
|
|
||||||
if (flags & WARPF_TOFLOOR)
|
|
||||||
{
|
|
||||||
caller->SetOrigin(xofs, yofs, caller->floorz + zofs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
caller->SetOrigin(xofs, yofs, zofs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((flags & WARPF_NOCHECKPOSITION) || P_TestMobjLocation(caller))
|
|
||||||
{
|
|
||||||
if (flags & WARPF_TESTONLY)
|
|
||||||
{
|
|
||||||
caller->SetOrigin(oldx, oldy, oldz);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
caller->angle = angle;
|
|
||||||
|
|
||||||
if (flags & WARPF_STOP)
|
|
||||||
{
|
|
||||||
caller->velx = 0;
|
|
||||||
caller->vely = 0;
|
|
||||||
caller->velz = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & WARPF_WARPINTERPOLATION)
|
|
||||||
{
|
|
||||||
caller->PrevX += caller->x - oldx;
|
|
||||||
caller->PrevY += caller->y - oldy;
|
|
||||||
caller->PrevZ += caller->z - oldz;
|
|
||||||
}
|
|
||||||
else if (flags & WARPF_COPYINTERPOLATION)
|
|
||||||
{
|
|
||||||
caller->PrevX = caller->x + reference->PrevX - reference->x;
|
|
||||||
caller->PrevY = caller->y + reference->PrevY - reference->y;
|
|
||||||
caller->PrevZ = caller->z + reference->PrevZ - reference->z;
|
|
||||||
}
|
|
||||||
else if (!(flags & WARPF_INTERPOLATE))
|
|
||||||
{
|
|
||||||
caller->PrevX = caller->x;
|
|
||||||
caller->PrevY = caller->y;
|
|
||||||
caller->PrevZ = caller->z;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB))
|
|
||||||
{
|
|
||||||
caller->z += reference->GetBobOffset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (success_state)
|
if (success_state)
|
||||||
{
|
{
|
||||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||||
|
@ -5185,7 +5055,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
caller->SetOrigin(oldx, oldy, oldz);
|
|
||||||
ACTION_SET_RESULT(false);
|
ACTION_SET_RESULT(false);
|
||||||
}
|
}
|
||||||
return numret;
|
return numret;
|
||||||
|
@ -5296,12 +5165,26 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedTerminate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool DoCheckSpecies(AActor *mo, FName filterSpecies, bool exclude)
|
||||||
|
{
|
||||||
|
FName actorSpecies = mo->GetSpecies();
|
||||||
|
if (filterSpecies == NAME_None) return true;
|
||||||
|
return exclude ? (actorSpecies != filterSpecies) : (actorSpecies == filterSpecies);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DoCheckClass(AActor *mo, PClassActor *filterClass, bool exclude)
|
||||||
|
{
|
||||||
|
const PClass *actorClass = mo->GetClass();
|
||||||
|
if (filterClass == NULL) return true;
|
||||||
|
return exclude ? (actorClass != filterClass) : (actorClass == filterClass);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// A_RadiusGive
|
// A_RadiusGive(item, distance, flags, amount, filter, species)
|
||||||
//
|
//
|
||||||
// Uses code roughly similar to A_Explode (but without all the compatibility
|
// Uses code roughly similar to A_Explode (but without all the compatibility
|
||||||
// baggage and damage computation code to give an item to all eligible mobjs
|
// baggage and damage computation code) to give an item to all eligible mobjs
|
||||||
// in range.
|
// in range.
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -5320,6 +5203,12 @@ enum RadiusGiveFlags
|
||||||
RGF_CUBE = 1 << 9,
|
RGF_CUBE = 1 << 9,
|
||||||
RGF_NOSIGHT = 1 << 10,
|
RGF_NOSIGHT = 1 << 10,
|
||||||
RGF_MISSILES = 1 << 11,
|
RGF_MISSILES = 1 << 11,
|
||||||
|
RGF_INCLUSIVE = 1 << 12,
|
||||||
|
RGF_ITEMS = 1 << 13,
|
||||||
|
RGF_KILLED = 1 << 14,
|
||||||
|
RGF_EXFILTER = 1 << 15,
|
||||||
|
RGF_EXSPECIES = 1 << 16,
|
||||||
|
RGF_EITHER = 1 << 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
|
||||||
|
@ -5329,12 +5218,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
|
||||||
PARAM_FIXED (distance);
|
PARAM_FIXED (distance);
|
||||||
PARAM_INT (flags);
|
PARAM_INT (flags);
|
||||||
PARAM_INT_OPT (amount) { amount = 0; }
|
PARAM_INT_OPT (amount) { amount = 0; }
|
||||||
|
PARAM_CLASS_OPT (filter, AActor) { filter = NULL; }
|
||||||
|
PARAM_NAME_OPT (species) { species = NAME_None; }
|
||||||
|
|
||||||
// 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 || distance <= 0)
|
if (item == NULL || (flags & RGF_MASK) == 0 || !flags || distance <= 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amount == 0)
|
if (amount == 0)
|
||||||
{
|
{
|
||||||
amount = 1;
|
amount = 1;
|
||||||
|
@ -5345,73 +5237,71 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
|
||||||
AActor *thing;
|
AActor *thing;
|
||||||
while ((thing = it.Next()))
|
while ((thing = it.Next()))
|
||||||
{
|
{
|
||||||
// Don't give to inventory items
|
//[MC] Check for a filter, species, and the related exfilter/expecies/either flag(s).
|
||||||
if (thing->flags & MF_SPECIAL)
|
bool filterpass = DoCheckClass(thing, filter, !!(flags & RGF_EXFILTER)),
|
||||||
{
|
speciespass = DoCheckSpecies(thing, species, !!(flags & RGF_EXSPECIES));
|
||||||
continue;
|
|
||||||
}
|
if ((flags & RGF_EITHER) ? (!(filterpass || speciespass)) : (!(filterpass && speciespass)))
|
||||||
// Avoid giving to self unless requested
|
|
||||||
if (thing == self && !(flags & RGF_GIVESELF))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Avoiding special pointers if requested
|
|
||||||
if (((thing == self->target) && (flags & RGF_NOTARGET)) ||
|
|
||||||
((thing == self->tracer) && (flags & RGF_NOTRACER)) ||
|
|
||||||
((thing == self->master) && (flags & RGF_NOMASTER)))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Don't give to dead thing unless requested
|
|
||||||
if (thing->flags & MF_CORPSE)
|
|
||||||
{
|
|
||||||
if (!(flags & RGF_CORPSES))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (thing->health <= 0 || thing->flags6 & MF6_KILLED)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Players, monsters, and other shootable objects
|
|
||||||
if (thing->player)
|
|
||||||
{
|
|
||||||
if ((thing->player->mo == thing) && !(flags & RGF_PLAYERS))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((thing->player->mo != thing) && !(flags & RGF_VOODOO))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (thing->flags3 & MF3_ISMONSTER)
|
|
||||||
{
|
|
||||||
if (!(flags & RGF_MONSTERS))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (thing->flags & MF_SHOOTABLE || thing->flags6 & MF6_VULNERABLE)
|
|
||||||
{
|
|
||||||
if (!(flags & RGF_OBJECTS))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (thing->flags & MF_MISSILE)
|
|
||||||
{
|
|
||||||
if (!(flags & RGF_MISSILES))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
if (thing != self) //Don't let filter and species obstruct RGF_GIVESELF.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thing == self)
|
||||||
|
{
|
||||||
|
if (!(flags & RGF_GIVESELF))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check for target, master, and tracer flagging.
|
||||||
|
bool targetPass = true;
|
||||||
|
bool masterPass = true;
|
||||||
|
bool tracerPass = true;
|
||||||
|
bool ptrPass = false;
|
||||||
|
if ((thing != self) && (flags & (RGF_NOTARGET | RGF_NOMASTER | RGF_NOTRACER)))
|
||||||
|
{
|
||||||
|
if ((thing == self->target) && (flags & RGF_NOTARGET))
|
||||||
|
targetPass = false;
|
||||||
|
if ((thing == self->master) && (flags & RGF_NOMASTER))
|
||||||
|
masterPass = false;
|
||||||
|
if ((thing == self->tracer) && (flags & RGF_NOTRACER))
|
||||||
|
tracerPass = false;
|
||||||
|
|
||||||
|
ptrPass = (flags & RGF_INCLUSIVE) ? (targetPass || masterPass || tracerPass) : (targetPass && masterPass && tracerPass);
|
||||||
|
|
||||||
|
//We should not care about what the actor is here. It's safe to abort this actor.
|
||||||
|
if (!ptrPass)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Next, actor flag checking.
|
||||||
|
bool selfPass = !!((flags & RGF_GIVESELF) && thing == self);
|
||||||
|
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 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.
|
||||||
|
if (!selfPass)
|
||||||
|
{
|
||||||
|
//If it's specifically a monster/object/player/voodoo... Can be either or...
|
||||||
|
if (monsterPass || objectPass || playerPass || voodooPass)
|
||||||
|
{
|
||||||
|
//...and is dead, without desire to give to the dead...
|
||||||
|
if (((thing->health <= 0) && !(corpsePass || killedPass)))
|
||||||
|
{
|
||||||
|
//Skip!
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool itemPass = !!((flags & RGF_ITEMS) && thing->IsKindOf(RUNTIME_CLASS(AInventory)));
|
||||||
|
bool missilePass = !!((flags & RGF_MISSILES) && thing->flags & MF_MISSILE);
|
||||||
|
|
||||||
|
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 ||
|
if (fabs((double)thing->x - self->x) > (double)distance ||
|
||||||
|
@ -5432,8 +5322,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & RGF_NOSIGHT) || P_CheckSight(thing, self, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
|
if ((flags & RGF_NOSIGHT) || P_CheckSight(thing, self, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
|
||||||
{ // OK to give; target is in direct path, or the
|
{ // OK to give; target is in direct path, or the monster doesn't care about it being in line of sight.
|
||||||
// monster doesn't care about it being in line of sight.
|
|
||||||
AInventory *gift = static_cast<AInventory *>(Spawn(item, 0, 0, 0, NO_REPLACE));
|
AInventory *gift = static_cast<AInventory *>(Spawn(item, 0, 0, 0, NO_REPLACE));
|
||||||
if (gift->IsKindOf(RUNTIME_CLASS(AHealth)))
|
if (gift->IsKindOf(RUNTIME_CLASS(AHealth)))
|
||||||
{
|
{
|
||||||
|
@ -5451,9 +5340,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// A_SetTics
|
// A_SetTics
|
||||||
|
@ -5534,20 +5425,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DoCheckSpecies(AActor *mo, FName filterSpecies, bool exclude)
|
|
||||||
{
|
|
||||||
FName actorSpecies = mo->GetSpecies();
|
|
||||||
if (filterSpecies == NAME_None) return true;
|
|
||||||
return exclude ? (actorSpecies != filterSpecies) : (actorSpecies == filterSpecies);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool DoCheckClass(AActor *mo, PClassActor *filterClass, bool exclude)
|
|
||||||
{
|
|
||||||
const PClass *actorClass = mo->GetClass();
|
|
||||||
if (filterClass == NULL) return true;
|
|
||||||
return exclude ? (actorClass != filterClass) : (actorClass == filterClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Common A_Damage handler
|
// Common A_Damage handler
|
||||||
|
|
|
@ -225,7 +225,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);
|
action native A_RadiusGive(class<Inventory> itemtype, int distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None");
|
||||||
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);
|
||||||
|
|
|
@ -224,6 +224,12 @@ enum
|
||||||
RGF_CUBE = 1 << 9,
|
RGF_CUBE = 1 << 9,
|
||||||
RGF_NOSIGHT = 1 << 10,
|
RGF_NOSIGHT = 1 << 10,
|
||||||
RGF_MISSILES = 1 << 11,
|
RGF_MISSILES = 1 << 11,
|
||||||
|
RGF_INCLUSIVE = 1 << 12,
|
||||||
|
RGF_ITEMS = 1 << 13,
|
||||||
|
RGF_KILLED = 1 << 14,
|
||||||
|
RGF_EXFILTER = 1 << 15,
|
||||||
|
RGF_EXSPECIES = 1 << 16,
|
||||||
|
RGF_EITHER = 1 << 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Activation flags
|
// Activation flags
|
||||||
|
@ -351,6 +357,7 @@ Const Int WAPRF_ABSOLUTEPOSITION = 0x400;
|
||||||
Const Int WARPF_ABSOLUTEPOSITION = 0x400;
|
Const Int WARPF_ABSOLUTEPOSITION = 0x400;
|
||||||
Const Int WARPF_BOB = 0x800;
|
Const Int WARPF_BOB = 0x800;
|
||||||
Const Int WARPF_MOVEPTR = 0x1000;
|
Const Int WARPF_MOVEPTR = 0x1000;
|
||||||
|
Const Int WARPF_USETID = 0x2000;
|
||||||
|
|
||||||
// flags for A_SetPitch/SetAngle/SetRoll
|
// flags for A_SetPitch/SetAngle/SetRoll
|
||||||
const int SPF_FORCECLAMP = 1;
|
const int SPF_FORCECLAMP = 1;
|
||||||
|
|
Loading…
Reference in a new issue