mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- Added DavidPH's A_Teleport submission but removed the now redundant GetSpotWithMinDistance functions.
SVN r2451 (trunk)
This commit is contained in:
parent
f430881a54
commit
bc47f7133b
6 changed files with 100 additions and 6 deletions
|
@ -139,7 +139,7 @@ void P_DSparilTeleport (AActor *actor)
|
|||
DSpotState *state = DSpotState::GetSpotState();
|
||||
if (state == NULL) return;
|
||||
|
||||
spot = state->GetSpotWithMinDistance(PClass::FindClass("BossSpot"), actor->x, actor->y, 128*FRACUNIT);
|
||||
spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->x, actor->y, 128*FRACUNIT, 0);
|
||||
if (spot == NULL) return;
|
||||
|
||||
prevX = actor->x;
|
||||
|
|
|
@ -147,14 +147,20 @@ struct FSpotList
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
ASpecialSpot *GetSpotWithMinDistance(fixed_t x, fixed_t y, fixed_t distance)
|
||||
ASpecialSpot *GetSpotWithMinMaxDistance(fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist)
|
||||
{
|
||||
if (Spots.Size() == 0) return NULL;
|
||||
int i = pr_spot() % Spots.Size();
|
||||
int initial = i;
|
||||
|
||||
while (P_AproxDistance(Spots[i]->x - x, Spots[i]->y - y) < distance)
|
||||
fixed_t distance;
|
||||
|
||||
while (true)
|
||||
{
|
||||
distance = P_AproxDistance(Spots[i]->x - x, Spots[i]->y - y);
|
||||
|
||||
if ((distance >= mindist) && ((maxdist == 0) || (distance <= maxdist))) break;
|
||||
|
||||
i = (i+1) % Spots.Size();
|
||||
if (i == initial) return NULL;
|
||||
}
|
||||
|
@ -329,10 +335,10 @@ ASpecialSpot *DSpotState::GetNextInList(const PClass *type, int skipcounter)
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
ASpecialSpot *DSpotState::GetSpotWithMinDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t distance)
|
||||
ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist)
|
||||
{
|
||||
FSpotList *list = FindSpotList(type);
|
||||
if (list != NULL) return list->GetSpotWithMinDistance(x, y, distance);
|
||||
if (list != NULL) return list->GetSpotWithMinMaxDistance(x, y, mindist, maxdist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
bool RemoveSpot(ASpecialSpot *spot);
|
||||
void Serialize(FArchive &arc);
|
||||
ASpecialSpot *GetNextInList(const PClass *type, int skipcounter);
|
||||
ASpecialSpot *GetSpotWithMinDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t distance);
|
||||
ASpecialSpot *GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist);
|
||||
ASpecialSpot *GetRandomSpot(const PClass *type, bool onlyonce = false);
|
||||
};
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "v_font.h"
|
||||
#include "doomstat.h"
|
||||
#include "v_palette.h"
|
||||
#include "g_shared/a_specialspot.h"
|
||||
|
||||
|
||||
static FRandom pr_camissile ("CustomActorfire");
|
||||
|
@ -81,6 +82,7 @@ static FRandom pr_spawndebris ("SpawnDebris");
|
|||
static FRandom pr_spawnitemex ("SpawnItemEx");
|
||||
static FRandom pr_burst ("Burst");
|
||||
static FRandom pr_monsterrefire ("MonsterRefire");
|
||||
static FRandom pr_teleport("Teleport");
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -3194,6 +3196,87 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray)
|
|||
((int *)(reinterpret_cast<BYTE *>(self) + var->offset))[pos] = value;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_Teleport(optional state teleportstate, optional class targettype,
|
||||
// optional class fogtype, optional int flags, optional fixed mindist,
|
||||
// optional fixed maxdist)
|
||||
//
|
||||
// Attempts to teleport to a targettype at least mindist away and at most
|
||||
// maxdist away (0 means unlimited). If successful, spawn a fogtype at old
|
||||
// location and place calling actor in teleportstate.
|
||||
//
|
||||
//===========================================================================
|
||||
enum T_Flags
|
||||
{
|
||||
TF_TELEFRAG = 1, // Allow telefrag in order to teleport.
|
||||
TF_RANDOMDECIDE = 2, // Randomly fail based on health. (A_Srcr2Decide)
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
|
||||
{
|
||||
ACTION_PARAM_START(6);
|
||||
ACTION_PARAM_STATE(TeleportState, 0);
|
||||
ACTION_PARAM_CLASS(TargetType, 1);
|
||||
ACTION_PARAM_CLASS(FogType, 2);
|
||||
ACTION_PARAM_INT(Flags, 3);
|
||||
ACTION_PARAM_FIXED(MinDist, 4);
|
||||
ACTION_PARAM_FIXED(MaxDist, 5);
|
||||
|
||||
// Randomly choose not to teleport like A_Srcr2Decide.
|
||||
if (Flags & TF_RANDOMDECIDE)
|
||||
{
|
||||
static const int chance[] =
|
||||
{
|
||||
192, 120, 120, 120, 64, 64, 32, 16, 0
|
||||
};
|
||||
|
||||
unsigned int chanceindex = self->health / ((self->SpawnHealth()/8 == 0) ? 1 : self->SpawnHealth()/8);
|
||||
|
||||
if (chanceindex >= countof(chance))
|
||||
{
|
||||
chanceindex = countof(chance) - 1;
|
||||
}
|
||||
|
||||
if (pr_teleport() >= chance[chanceindex]) return;
|
||||
}
|
||||
|
||||
if (TeleportState == NULL)
|
||||
{
|
||||
// Default to Teleport.
|
||||
TeleportState = self->FindState("Teleport");
|
||||
// If still nothing, then return.
|
||||
if (!TeleportState) return;
|
||||
}
|
||||
|
||||
DSpotState *state = DSpotState::GetSpotState();
|
||||
if (state == NULL) return;
|
||||
|
||||
if (!TargetType) TargetType = PClass::FindClass("BossSpot");
|
||||
|
||||
AActor * spot = state->GetSpotWithMinMaxDistance(TargetType, self->x, self->y, MinDist, MaxDist);
|
||||
if (spot == NULL) return;
|
||||
|
||||
fixed_t prevX = self->x;
|
||||
fixed_t prevY = self->y;
|
||||
fixed_t prevZ = self->z;
|
||||
if (P_TeleportMove (self, spot->x, spot->y, spot->z, Flags & TF_TELEFRAG))
|
||||
{
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
|
||||
if (FogType)
|
||||
{
|
||||
Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE);
|
||||
}
|
||||
|
||||
ACTION_JUMP(TeleportState);
|
||||
|
||||
self->z = self->floorz;
|
||||
self->angle = spot->angle;
|
||||
self->velx = self->vely = self->velz = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_Turn
|
||||
|
|
|
@ -224,6 +224,7 @@ ACTOR Actor native //: Thinker
|
|||
action native A_CheckCeiling(state label);
|
||||
action native A_PlayerSkinCheck(state label);
|
||||
action native A_BasicAttack(int meleedamage, sound meleesound, class<actor> missiletype, float missileheight);
|
||||
action native A_Teleport(state teleportstate = "", class<SpecialSpot> targettype = "BossSpot", class<Actor> fogtype = "TeleportFog", int flags = 0, float mindist = 128, float maxdist = 0);
|
||||
action native A_ThrowGrenade(class<Actor> itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true);
|
||||
action native A_Weave(int xspeed, int yspeed, float xdist, float ydist);
|
||||
|
||||
|
|
|
@ -95,6 +95,10 @@ const int CPF_USEAMMO = 1;
|
|||
const int CPF_DAGGER = 2;
|
||||
const int CPF_PULLIN = 4;
|
||||
|
||||
// Flags for A_Teleport
|
||||
const int TF_TELEFRAG = 1;
|
||||
const int TF_RANDOMDECIDE = 2;
|
||||
|
||||
// Activation flags
|
||||
enum
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue