mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- Added SpawnDecal ACS function:
int SpawnDecal(int tid, str decalname, int flags, fixed angle, int zoffset, int distance) Traces a line from tid's actor until hitting a wall, then creates a decal there. Returns the number of decals spawned. * tid = Which actor(s) to start the trace at. * decalname = Which decal to spawn. * flags = * SDF_ABSANGLE = Angle parameter is an absolute angle. Otherwise, it's relative to the origin actor's angle. * SDF_PERMANENT = Decal ignores cl_maxdecals. Otherwise, it will eventually disappear. * angle = Direction in which to search for a wall. Defaults to 0.0. * zoffset = Offset from the middle of the origin actor for the Z height of the decal. Defaults to 0. * distance = Maximum distance to search for a wall. Defaults to 64. SVN r4330 (trunk)
This commit is contained in:
parent
5a00f4b59a
commit
e32e44209e
3 changed files with 97 additions and 23 deletions
|
@ -755,6 +755,48 @@ CCMD (spray)
|
||||||
Net_WriteString (argv[1]);
|
Net_WriteString (argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, fixed_t x, fixed_t y, fixed_t z, angle_t angle, fixed_t tracedist, bool permanent)
|
||||||
|
{
|
||||||
|
if (tpl == NULL || (tpl = tpl->GetDecal()) == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FTraceResults trace;
|
||||||
|
DBaseDecal *decal;
|
||||||
|
side_t *wall;
|
||||||
|
|
||||||
|
angle >>= ANGLETOFINESHIFT;
|
||||||
|
|
||||||
|
Trace(x, y, z, sec,
|
||||||
|
finecosine[angle], finesine[angle], 0,
|
||||||
|
tracedist, 0, 0, NULL, trace, TRACE_NoSky);
|
||||||
|
|
||||||
|
if (trace.HitType == TRACE_HitWall)
|
||||||
|
{
|
||||||
|
if (permanent)
|
||||||
|
{
|
||||||
|
decal = new DBaseDecal(trace.Z);
|
||||||
|
wall = trace.Line->sidedef[trace.Side];
|
||||||
|
decal->StickToWall(wall, trace.X, trace.Y, trace.ffloor);
|
||||||
|
tpl->ApplyToDecal(decal, wall);
|
||||||
|
// Spread decal to nearby walls if it does not all fit on this one
|
||||||
|
if (cl_spreaddecals)
|
||||||
|
{
|
||||||
|
decal->Spread(tpl, wall, trace.X, trace.Y, trace.Z, trace.ffloor);
|
||||||
|
}
|
||||||
|
return decal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DImpactDecal::StaticCreate(tpl,
|
||||||
|
trace.X, trace.Y, trace.Z,
|
||||||
|
trace.Line->sidedef[trace.Side], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
class ADecal : public AActor
|
class ADecal : public AActor
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (ADecal, AActor);
|
DECLARE_CLASS (ADecal, AActor);
|
||||||
|
@ -767,9 +809,6 @@ IMPLEMENT_CLASS (ADecal)
|
||||||
void ADecal::BeginPlay ()
|
void ADecal::BeginPlay ()
|
||||||
{
|
{
|
||||||
const FDecalTemplate *tpl;
|
const FDecalTemplate *tpl;
|
||||||
FTraceResults trace;
|
|
||||||
DBaseDecal *decal;
|
|
||||||
side_t *wall;
|
|
||||||
|
|
||||||
Super::BeginPlay ();
|
Super::BeginPlay ();
|
||||||
|
|
||||||
|
@ -781,31 +820,13 @@ void ADecal::BeginPlay ()
|
||||||
if (!tpl->PicNum.Exists())
|
if (!tpl->PicNum.Exists())
|
||||||
{
|
{
|
||||||
Printf("Decal actor at (%d,%d) does not have a valid texture\n", x>>FRACBITS, y>>FRACBITS);
|
Printf("Decal actor at (%d,%d) does not have a valid texture\n", x>>FRACBITS, y>>FRACBITS);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Look for a wall within 64 units behind the actor. If none can be
|
// Look for a wall within 64 units behind the actor. If none can be
|
||||||
// found, then no decal is created, and this actor is destroyed
|
// found, then no decal is created, and this actor is destroyed
|
||||||
// without effectively doing anything.
|
// without effectively doing anything.
|
||||||
Trace (x, y, z, Sector,
|
if (NULL == ShootDecal(tpl, this, Sector, x, y, z, angle + ANGLE_180, 64*FRACUNIT, true))
|
||||||
finecosine[(angle+ANGLE_180)>>ANGLETOFINESHIFT],
|
|
||||||
finesine[(angle+ANGLE_180)>>ANGLETOFINESHIFT], 0,
|
|
||||||
64*FRACUNIT, 0, 0, NULL, trace, TRACE_NoSky);
|
|
||||||
|
|
||||||
if (trace.HitType == TRACE_HitWall)
|
|
||||||
{
|
|
||||||
decal = new DBaseDecal (this);
|
|
||||||
wall = trace.Line->sidedef[trace.Side];
|
|
||||||
decal->StickToWall (wall, trace.X, trace.Y, trace.ffloor);
|
|
||||||
tpl->ApplyToDecal (decal, wall);
|
|
||||||
// Spread decal to nearby walls if it does not all fit on this one
|
|
||||||
if (cl_spreaddecals)
|
|
||||||
{
|
|
||||||
decal->Spread (tpl, wall, trace.X, trace.Y, z, trace.ffloor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
DPrintf ("Could not find a wall to stick decal to at (%d,%d)\n", x>>FRACBITS, y>>FRACBITS);
|
DPrintf ("Could not find a wall to stick decal to at (%d,%d)\n", x>>FRACBITS, y>>FRACBITS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,8 @@ struct vertex_t;
|
||||||
struct side_t;
|
struct side_t;
|
||||||
struct F3DFloor;
|
struct F3DFloor;
|
||||||
|
|
||||||
extern void P_SpawnDirt (AActor *actor, fixed_t radius);
|
void P_SpawnDirt (AActor *actor, fixed_t radius);
|
||||||
|
class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, fixed_t x, fixed_t y, fixed_t z, angle_t angle, fixed_t tracedist, bool permanent);
|
||||||
|
|
||||||
class DBaseDecal : public DThinker
|
class DBaseDecal : public DThinker
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
#include "po_man.h"
|
#include "po_man.h"
|
||||||
#include "actorptrselect.h"
|
#include "actorptrselect.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "decallib.h"
|
||||||
|
|
||||||
#include "g_shared/a_pickups.h"
|
#include "g_shared/a_pickups.h"
|
||||||
|
|
||||||
|
@ -111,6 +112,10 @@ FRandom pr_acs ("ACS");
|
||||||
#define NOT_FLOOR 8
|
#define NOT_FLOOR 8
|
||||||
#define NOT_CEILING 16
|
#define NOT_CEILING 16
|
||||||
|
|
||||||
|
// SpawnDecal flags
|
||||||
|
#define SDF_ABSANGLE 1
|
||||||
|
#define SDF_PERMANENT 2
|
||||||
|
|
||||||
struct CallReturn
|
struct CallReturn
|
||||||
{
|
{
|
||||||
CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, unsigned int runaway)
|
CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, unsigned int runaway)
|
||||||
|
@ -4192,6 +4197,7 @@ enum EACSFunctions
|
||||||
ACSF_GetWeapon,
|
ACSF_GetWeapon,
|
||||||
ACSF_SoundVolume,
|
ACSF_SoundVolume,
|
||||||
ACSF_PlayActorSound,
|
ACSF_PlayActorSound,
|
||||||
|
ACSF_SpawnDecal,
|
||||||
|
|
||||||
// ZDaemon
|
// ZDaemon
|
||||||
ACSF_GetTeamScore = 19620, // (int team)
|
ACSF_GetTeamScore = 19620, // (int team)
|
||||||
|
@ -4440,6 +4446,17 @@ static int SetCVar(AActor *activator, const char *cvarname, int value, bool is_s
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, angle_t angle, fixed_t zofs, fixed_t distance)
|
||||||
|
{
|
||||||
|
if (!(flags & SDF_ABSANGLE))
|
||||||
|
{
|
||||||
|
angle += actor->angle;
|
||||||
|
}
|
||||||
|
return NULL != ShootDecal(tpl, actor, actor->Sector, actor->x, actor->y,
|
||||||
|
actor->z + (actor->height>>1) - actor->floorclip + actor->GetBobOffset() + zofs,
|
||||||
|
angle, distance, !!(flags & SDF_PERMANENT));
|
||||||
|
}
|
||||||
|
|
||||||
int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth)
|
int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth)
|
||||||
{
|
{
|
||||||
AActor *actor;
|
AActor *actor;
|
||||||
|
@ -5141,6 +5158,41 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
return GlobalACSStrings.AddString(activator->player->ReadyWeapon->GetClass()->TypeName.GetChars(), stack, stackdepth);
|
return GlobalACSStrings.AddString(activator->player->ReadyWeapon->GetClass()->TypeName.GetChars(), stack, stackdepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ACSF_SpawnDecal:
|
||||||
|
// int SpawnDecal(int tid, str decalname, int flags, fixed angle, int zoffset, int distance)
|
||||||
|
// Returns number of decals spawned (not including spreading)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
const FDecalTemplate *tpl = DecalLibrary.GetDecalByName(FBehavior::StaticLookupString(args[1]));
|
||||||
|
if (tpl != NULL)
|
||||||
|
{
|
||||||
|
int flags = (argCount > 2) ? args[2] : 0;
|
||||||
|
angle_t angle = (argCount > 3) ? (args[3] << FRACBITS) : 0;
|
||||||
|
fixed_t zoffset = (argCount > 4) ? (args[4] << FRACBITS) : 0;
|
||||||
|
fixed_t distance = (argCount > 5) ? (args[5] << FRACBITS) : 64*FRACUNIT;
|
||||||
|
|
||||||
|
if (args[0] == 0)
|
||||||
|
{
|
||||||
|
if (activator != NULL)
|
||||||
|
{
|
||||||
|
count += DoSpawnDecal(activator, tpl, flags, angle, zoffset, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FActorIterator it(args[0]);
|
||||||
|
AActor *actor;
|
||||||
|
|
||||||
|
while ((actor = it.Next()) != NULL)
|
||||||
|
{
|
||||||
|
count += DoSpawnDecal(actor, tpl, flags, angle, zoffset, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue