- Update scripting branch to trunk.
SVN r3758 (scripting)
This commit is contained in:
commit
562cf04db2
614 changed files with 63691 additions and 31256 deletions
238
src/p_effect.cpp
238
src/p_effect.cpp
|
|
@ -36,15 +36,16 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
#include "doomstat.h"
|
||||
#include "i_system.h"
|
||||
#include "c_cvars.h"
|
||||
#include "actor.h"
|
||||
#include "m_argv.h"
|
||||
#include "p_effect.h"
|
||||
#include "p_local.h"
|
||||
#include "g_level.h"
|
||||
#include "v_video.h"
|
||||
#include "m_random.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_things.h"
|
||||
#include "s_sound.h"
|
||||
#include "templates.h"
|
||||
#include "gi.h"
|
||||
|
|
@ -55,9 +56,19 @@ CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
|
|||
CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);
|
||||
CVAR (Int, r_rail_spiralsparsity, 1, CVAR_ARCHIVE);
|
||||
CVAR (Int, r_rail_trailsparsity, 1, CVAR_ARCHIVE);
|
||||
CVAR (Bool, r_particles, true, 0);
|
||||
|
||||
FRandom pr_railtrail("RailTrail");
|
||||
|
||||
#define FADEFROMTTL(a) (255/(a))
|
||||
|
||||
// [RH] particle globals
|
||||
WORD NumParticles;
|
||||
WORD ActiveParticles;
|
||||
WORD InactiveParticles;
|
||||
particle_t *Particles;
|
||||
TArray<WORD> ParticlesInSubsec;
|
||||
|
||||
static int grey1, grey2, grey3, grey4, red, green, blue, yellow, black,
|
||||
red1, green1, blue1, yellow1, purple, purple1, white,
|
||||
rblue1, rblue2, rblue3, rblue4, orange, yorange, dred, grey5,
|
||||
|
|
@ -93,22 +104,147 @@ static const struct ColorList {
|
|||
{&dred, 80, 0, 0 },
|
||||
{&maroon1, 154, 49, 49 },
|
||||
{&maroon2, 125, 24, 24 },
|
||||
{NULL}
|
||||
{NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
inline particle_t *NewParticle (void)
|
||||
{
|
||||
particle_t *result = NULL;
|
||||
if (InactiveParticles != NO_PARTICLE)
|
||||
{
|
||||
result = Particles + InactiveParticles;
|
||||
InactiveParticles = result->tnext;
|
||||
result->tnext = ActiveParticles;
|
||||
ActiveParticles = WORD(result - Particles);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// [RH] Particle functions
|
||||
//
|
||||
void P_InitParticles ();
|
||||
void P_DeinitParticles ();
|
||||
|
||||
// [BC] Allow the maximum number of particles to be specified by a cvar (so people
|
||||
// with lots of nice hardware can have lots of particles!).
|
||||
CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE )
|
||||
{
|
||||
if ( self == 0 )
|
||||
self = 4000;
|
||||
else if ( self < 100 )
|
||||
self = 100;
|
||||
|
||||
if ( gamestate != GS_STARTUP )
|
||||
{
|
||||
P_DeinitParticles( );
|
||||
P_InitParticles( );
|
||||
}
|
||||
}
|
||||
|
||||
void P_InitParticles ()
|
||||
{
|
||||
const char *i;
|
||||
|
||||
if ((i = Args->CheckValue ("-numparticles")))
|
||||
NumParticles = atoi (i);
|
||||
// [BC] Use r_maxparticles now.
|
||||
else
|
||||
NumParticles = r_maxparticles;
|
||||
|
||||
// This should be good, but eh...
|
||||
NumParticles = clamp<WORD>(NumParticles, 100, 65535);
|
||||
|
||||
P_DeinitParticles();
|
||||
Particles = new particle_t[NumParticles];
|
||||
P_ClearParticles ();
|
||||
atterm (P_DeinitParticles);
|
||||
}
|
||||
|
||||
void P_DeinitParticles()
|
||||
{
|
||||
if (Particles != NULL)
|
||||
{
|
||||
delete[] Particles;
|
||||
Particles = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void P_ClearParticles ()
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (Particles, 0, NumParticles * sizeof(particle_t));
|
||||
ActiveParticles = NO_PARTICLE;
|
||||
InactiveParticles = 0;
|
||||
for (i = 0; i < NumParticles-1; i++)
|
||||
Particles[i].tnext = i + 1;
|
||||
Particles[i].tnext = NO_PARTICLE;
|
||||
}
|
||||
|
||||
// Group particles by subsectors. Because particles are always
|
||||
// in motion, there is little benefit to caching this information
|
||||
// from one frame to the next.
|
||||
|
||||
void P_FindParticleSubsectors ()
|
||||
{
|
||||
if (ParticlesInSubsec.Size() < (size_t)numsubsectors)
|
||||
{
|
||||
ParticlesInSubsec.Reserve (numsubsectors - ParticlesInSubsec.Size());
|
||||
}
|
||||
|
||||
clearbufshort (&ParticlesInSubsec[0], numsubsectors, NO_PARTICLE);
|
||||
|
||||
if (!r_particles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (WORD i = ActiveParticles; i != NO_PARTICLE; i = Particles[i].tnext)
|
||||
{
|
||||
subsector_t *ssec = R_PointInSubsector (Particles[i].x, Particles[i].y);
|
||||
int ssnum = int(ssec-subsectors);
|
||||
Particles[i].subsector = ssec;
|
||||
Particles[i].snext = ParticlesInSubsec[ssnum];
|
||||
ParticlesInSubsec[ssnum] = i;
|
||||
}
|
||||
}
|
||||
|
||||
static TMap<int, int> ColorSaver;
|
||||
|
||||
static uint32 ParticleColor(int rgb)
|
||||
{
|
||||
int *val;
|
||||
int stuff;
|
||||
|
||||
val = ColorSaver.CheckKey(rgb);
|
||||
if (val != NULL)
|
||||
{
|
||||
return *val;
|
||||
}
|
||||
stuff = rgb | (ColorMatcher.Pick(RPART(rgb), GPART(rgb), BPART(rgb)) << 24);
|
||||
ColorSaver[rgb] = stuff;
|
||||
return stuff;
|
||||
}
|
||||
|
||||
static uint32 ParticleColor(int r, int g, int b)
|
||||
{
|
||||
return ParticleColor(MAKERGB(r, g, b));
|
||||
}
|
||||
|
||||
void P_InitEffects ()
|
||||
{
|
||||
const struct ColorList *color = Colors;
|
||||
|
||||
P_InitParticles();
|
||||
while (color->color)
|
||||
{
|
||||
*(color->color) = ColorMatcher.Pick (color->r, color->g, color->b);
|
||||
*(color->color) = ParticleColor(color->r, color->g, color->b);
|
||||
color++;
|
||||
}
|
||||
|
||||
int kind = gameinfo.defaultbloodparticlecolor;
|
||||
blood1 = ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind));
|
||||
blood2 = ColorMatcher.Pick(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3);
|
||||
blood1 = ParticleColor(kind);
|
||||
blood2 = ParticleColor(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -175,11 +311,16 @@ void P_RunEffects ()
|
|||
}
|
||||
|
||||
//
|
||||
// AddParticle
|
||||
// JitterParticle
|
||||
//
|
||||
// Creates a particle with "jitter"
|
||||
//
|
||||
particle_t *JitterParticle (int ttl)
|
||||
{
|
||||
return JitterParticle (ttl, 1.0);
|
||||
}
|
||||
// [XA] Added "drift speed" multiplier setting for enhanced railgun stuffs.
|
||||
particle_t *JitterParticle (int ttl, double drift)
|
||||
{
|
||||
particle_t *particle = NewParticle ();
|
||||
|
||||
|
|
@ -189,10 +330,10 @@ particle_t *JitterParticle (int ttl)
|
|||
|
||||
// Set initial velocities
|
||||
for (i = 3; i; i--, val++)
|
||||
*val = (FRACUNIT/4096) * (M_Random () - 128);
|
||||
*val = (int)((FRACUNIT/4096) * (M_Random () - 128) * drift);
|
||||
// Set initial accelerations
|
||||
for (i = 3; i; i--, val++)
|
||||
*val = (FRACUNIT/16384) * (M_Random () - 128);
|
||||
*val = (int)((FRACUNIT/16384) * (M_Random () - 128) * drift);
|
||||
|
||||
particle->trans = 255; // fully opaque
|
||||
particle->ttl = ttl;
|
||||
|
|
@ -407,8 +548,8 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i
|
|||
color2 = grey1;
|
||||
break;
|
||||
default: // colorized blood
|
||||
color1 = ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind));
|
||||
color2 = ColorMatcher.Pick(RPART(kind)>>1, GPART(kind)>>1, BPART(kind)>>1);
|
||||
color1 = ParticleColor(kind);
|
||||
color2 = ParticleColor(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -445,21 +586,24 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i
|
|||
}
|
||||
}
|
||||
|
||||
void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end, int color1, int color2, float maxdiff, bool silent)
|
||||
void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end, int color1, int color2, double maxdiff_d, int flags, PClassActor *spawnclass, angle_t angle, int duration, double sparsity, double drift)
|
||||
{
|
||||
double length, lengthsquared;
|
||||
int steps, i;
|
||||
FAngle deg;
|
||||
FVector3 step, dir, pos, extend;
|
||||
bool fullbright;
|
||||
float maxdiff = (float)maxdiff_d;
|
||||
|
||||
dir = end - start;
|
||||
lengthsquared = dir | dir;
|
||||
length = sqrt(lengthsquared);
|
||||
steps = int(length / 3);
|
||||
steps = xs_FloorToInt(length / 3);
|
||||
fullbright = !!(flags & RAF_FULLBRIGHT);
|
||||
|
||||
if (steps)
|
||||
{
|
||||
if (!silent)
|
||||
if (!(flags & RAF_SILENT))
|
||||
{
|
||||
FSoundID sound;
|
||||
|
||||
|
|
@ -485,7 +629,7 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
|
|||
{
|
||||
|
||||
// Only consider sound in 2D (for now, anyway)
|
||||
// [BB] You have to devide by lengthsquared here, not multiply with it.
|
||||
// [BB] You have to divide by lengthsquared here, not multiply with it.
|
||||
|
||||
r = ((start.Y - FIXED2FLOAT(mo->y)) * (-dir.Y) - (start.X - FIXED2FLOAT(mo->x)) * (dir.X)) / lengthsquared;
|
||||
r = clamp<double>(r, 0., 1.);
|
||||
|
|
@ -528,12 +672,12 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
|
|||
step = dir * 3;
|
||||
|
||||
// Create the outer spiral.
|
||||
if (color1 != -1 && (!r_rail_smartspiral || color2 == -1) && r_rail_spiralsparsity > 0)
|
||||
if (color1 != -1 && (!r_rail_smartspiral || color2 == -1) && r_rail_spiralsparsity > 0 && (spawnclass == NULL))
|
||||
{
|
||||
FVector3 spiral_step = step * r_rail_spiralsparsity;
|
||||
int spiral_steps = steps * r_rail_spiralsparsity;
|
||||
FVector3 spiral_step = step * r_rail_spiralsparsity * sparsity;
|
||||
int spiral_steps = (int)(steps * r_rail_spiralsparsity / sparsity);
|
||||
|
||||
color1 = color1 == 0 ? -1 : ColorMatcher.Pick(RPART(color1), GPART(color1), BPART(color1));
|
||||
color1 = color1 == 0 ? -1 : ParticleColor(color1);
|
||||
pos = start;
|
||||
deg = FAngle(270);
|
||||
for (i = spiral_steps; i; i--)
|
||||
|
|
@ -544,15 +688,18 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
|
|||
if (!p)
|
||||
return;
|
||||
|
||||
int spiralduration = (duration == 0) ? 35 : duration;
|
||||
|
||||
p->trans = 255;
|
||||
p->ttl = 35;
|
||||
p->fade = FADEFROMTTL(35);
|
||||
p->ttl = duration;
|
||||
p->fade = FADEFROMTTL(spiralduration);
|
||||
p->size = 3;
|
||||
p->bright = fullbright;
|
||||
|
||||
tempvec = FMatrix3x3(dir, deg) * extend;
|
||||
p->velx = FLOAT2FIXED(tempvec.X)>>4;
|
||||
p->vely = FLOAT2FIXED(tempvec.Y)>>4;
|
||||
p->velz = FLOAT2FIXED(tempvec.Z)>>4;
|
||||
p->velx = FLOAT2FIXED(tempvec.X * drift)>>4;
|
||||
p->vely = FLOAT2FIXED(tempvec.Y * drift)>>4;
|
||||
p->velz = FLOAT2FIXED(tempvec.Z * drift)>>4;
|
||||
tempvec += pos;
|
||||
p->x = FLOAT2FIXED(tempvec.X);
|
||||
p->y = FLOAT2FIXED(tempvec.Y);
|
||||
|
|
@ -581,18 +728,20 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
|
|||
}
|
||||
|
||||
// Create the inner trail.
|
||||
if (color2 != -1 && r_rail_trailsparsity > 0)
|
||||
if (color2 != -1 && r_rail_trailsparsity > 0 && spawnclass == NULL)
|
||||
{
|
||||
FVector3 trail_step = step * r_rail_trailsparsity;
|
||||
int trail_steps = steps * r_rail_trailsparsity;
|
||||
FVector3 trail_step = step * r_rail_trailsparsity * sparsity;
|
||||
int trail_steps = xs_FloorToInt(steps * r_rail_trailsparsity / sparsity);
|
||||
|
||||
color2 = color2 == 0 ? -1 : ColorMatcher.Pick(RPART(color2), GPART(color2), BPART(color2));
|
||||
color2 = color2 == 0 ? -1 : ParticleColor(color2);
|
||||
FVector3 diff(0, 0, 0);
|
||||
|
||||
pos = start;
|
||||
for (i = trail_steps; i; i--)
|
||||
{
|
||||
particle_t *p = JitterParticle (33);
|
||||
// [XA] inner trail uses a different default duration (33).
|
||||
int innerduration = (duration == 0) ? 33 : duration;
|
||||
particle_t *p = JitterParticle (innerduration, drift);
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
|
@ -618,6 +767,8 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
|
|||
p->accz -= FRACUNIT/4096;
|
||||
pos += trail_step;
|
||||
|
||||
p->bright = fullbright;
|
||||
|
||||
if (color2 == -1)
|
||||
{
|
||||
int rand = M_Random();
|
||||
|
|
@ -635,6 +786,37 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
|
|||
}
|
||||
}
|
||||
}
|
||||
// create actors
|
||||
if (spawnclass != NULL)
|
||||
{
|
||||
if (sparsity < 1)
|
||||
sparsity = 32;
|
||||
|
||||
FVector3 trail_step = (step / 3) * sparsity;
|
||||
int trail_steps = (int)((steps * 3) / sparsity);
|
||||
FVector3 diff(0, 0, 0);
|
||||
|
||||
pos = start;
|
||||
for (i = trail_steps; i; i--)
|
||||
{
|
||||
if (maxdiff > 0)
|
||||
{
|
||||
int rnd = pr_railtrail();
|
||||
if (rnd & 1)
|
||||
diff.X = clamp<float> (diff.X + ((rnd & 8) ? 1 : -1), -maxdiff, maxdiff);
|
||||
if (rnd & 2)
|
||||
diff.Y = clamp<float> (diff.Y + ((rnd & 16) ? 1 : -1), -maxdiff, maxdiff);
|
||||
if (rnd & 4)
|
||||
diff.Z = clamp<float> (diff.Z + ((rnd & 32) ? 1 : -1), -maxdiff, maxdiff);
|
||||
}
|
||||
FVector3 postmp = pos + diff;
|
||||
|
||||
AActor *thing = Spawn (spawnclass, FLOAT2FIXED(postmp.X), FLOAT2FIXED(postmp.Y), FLOAT2FIXED(postmp.Z), ALLOW_REPLACE);
|
||||
if (thing)
|
||||
thing->angle = angle;
|
||||
pos += trail_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void P_DisconnectEffect (AActor *actor)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue