mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-10 15:21:34 +00:00
a39565b783
... not quite content with where the project files lie but it is ok for now. ... compiling works fine so far (only tested mingw32 right now)
1170 lines
27 KiB
C
1170 lines
27 KiB
C
// FX Library
|
|
|
|
#include "cg_local.h"
|
|
|
|
void FXE_Spray (vec3_t direction, float speed, float variation, float cone, vec3_t velocity)
|
|
{
|
|
vec3_t dir;
|
|
int i;
|
|
|
|
//Randomize the direction
|
|
for (i = 0; i < 3; i ++ )
|
|
{
|
|
dir[i] = direction[i] + (cone * crandom());
|
|
}
|
|
|
|
VectorNormalize(dir);
|
|
|
|
//set the speed
|
|
VectorScale( dir, speed + (variation * crandom()), velocity);
|
|
}
|
|
|
|
|
|
|
|
localEntity_t *FX_AddLine(vec3_t start, vec3_t end, float stScale, float scale, float dscale, float startalpha, float endalpha, float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddLine: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_LINE;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
le->data.line.width = scale;
|
|
le->data.line.dwidth = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
|
|
le->refEntity.data.line.stscale = stScale;
|
|
le->refEntity.data.line.width = scale;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( start, le->refEntity.origin);
|
|
VectorCopy ( end, le->refEntity.oldorigin );
|
|
|
|
AxisClear(le->refEntity.axis);
|
|
le->refEntity.shaderRGBA[0] = 0xff;
|
|
le->refEntity.shaderRGBA[1] = 0xff;
|
|
le->refEntity.shaderRGBA[2] = 0xff;
|
|
le->refEntity.shaderRGBA[3] = 0xff;
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = 1.0;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
|
|
localEntity_t *FX_AddLine2(vec3_t start, vec3_t end, float stScale, float width1, float dwidth1, float width2, float dwidth2,
|
|
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddLine2: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_LINE2;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
le->data.line2.width = width1;
|
|
le->data.line2.dwidth = dwidth1;
|
|
le->data.line2.width2 = width2;
|
|
le->data.line2.dwidth2 = dwidth2;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorCopy(startRGB, le->data.line2.startRGB);
|
|
VectorSubtract(endRGB, startRGB, le->data.line2.dRGB);
|
|
|
|
le->refEntity.data.line.stscale = stScale;
|
|
le->refEntity.data.line.width = width1;
|
|
le->refEntity.data.line.width2 = width2;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( start, le->refEntity.origin);
|
|
VectorCopy ( end, le->refEntity.oldorigin );
|
|
|
|
AxisClear(le->refEntity.axis);
|
|
le->refEntity.shaderRGBA[0] = 0xff;
|
|
le->refEntity.shaderRGBA[1] = 0xff;
|
|
le->refEntity.shaderRGBA[2] = 0xff;
|
|
le->refEntity.shaderRGBA[3] = 0xff;
|
|
|
|
le->color[0] = startRGB[0];
|
|
le->color[1] = startRGB[1];
|
|
le->color[2] = startRGB[2];
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
|
|
localEntity_t *FX_AddLine3(vec3_t start, vec3_t end, float stScale, float scale, float dscale,
|
|
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddLine2: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_LINE2;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
le->data.line.width = scale;
|
|
le->data.line.dwidth = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorCopy(startRGB, le->data.line2.startRGB);
|
|
VectorSubtract(endRGB, startRGB, le->data.line2.dRGB);
|
|
|
|
le->refEntity.data.line.stscale = stScale;
|
|
le->refEntity.data.line.width = scale;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( start, le->refEntity.origin);
|
|
VectorCopy ( end, le->refEntity.oldorigin );
|
|
|
|
AxisClear(le->refEntity.axis);
|
|
le->refEntity.shaderRGBA[0] = 0xff;
|
|
le->refEntity.shaderRGBA[1] = 0xff;
|
|
le->refEntity.shaderRGBA[2] = 0xff;
|
|
le->refEntity.shaderRGBA[3] = 0xff;
|
|
|
|
le->color[0] = startRGB[0];
|
|
le->color[1] = startRGB[1];
|
|
le->color[2] = startRGB[2];
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
|
|
localEntity_t *FX_AddOrientedLine(vec3_t start, vec3_t end, vec3_t normal, float stScale, float scale,
|
|
float dscale, float startalpha, float endalpha, float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddLine: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_OLINE;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
le->data.line.width = scale;
|
|
le->data.line.dwidth = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
|
|
le->refEntity.data.line.stscale = stScale;
|
|
le->refEntity.data.line.width = scale;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( start, le->refEntity.origin);
|
|
VectorCopy ( end, le->refEntity.oldorigin );
|
|
|
|
AxisClear(le->refEntity.axis);
|
|
VectorCopy( normal, le->refEntity.axis[0] );
|
|
RotateAroundDirection( le->refEntity.axis, 0); // le->refEntity.data.sprite.rotation ); This is roll in quad land
|
|
|
|
le->refEntity.shaderRGBA[0] = 0xff;
|
|
le->refEntity.shaderRGBA[1] = 0xff;
|
|
le->refEntity.shaderRGBA[2] = 0xff;
|
|
le->refEntity.shaderRGBA[3] = 0xff;
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = 1.0;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
|
|
localEntity_t *FX_AddTrail( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
|
|
float scale, float dscale, float startalpha, float endalpha,
|
|
float elasticity, float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddTrail: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_TRAIL;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.trail.width = scale;
|
|
le->data.trail.dwidth = dscale;
|
|
le->data.trail.length = length;
|
|
le->data.trail.dlength = dlength;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorSet(le->data.trail.startRGB, 1, 1, 1);
|
|
VectorSet(le->data.trail.dRGB, 0, 0, 0);
|
|
|
|
le->refEntity.data.line.stscale = 1.0;
|
|
le->refEntity.data.line.width = scale;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
// kef -- extrapolate oldorigin based on length of trail and origin?
|
|
if (velocity)
|
|
{
|
|
vec3_t vel;
|
|
VectorNormalize2(velocity, vel);
|
|
VectorMA(origin, -length, vel, le->refEntity.oldorigin);
|
|
}
|
|
else
|
|
{
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
}
|
|
|
|
AxisClear(le->refEntity.axis);
|
|
le->refEntity.shaderRGBA[0] = 0xff;
|
|
le->refEntity.shaderRGBA[1] = 0xff;
|
|
le->refEntity.shaderRGBA[2] = 0xff;
|
|
le->refEntity.shaderRGBA[3] = 0xff*startalpha;
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = 1.0;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
if (velocity)
|
|
{
|
|
le->leFlags |= LEF_MOVE;
|
|
VectorCopy (origin, le->pos.trBase);
|
|
VectorCopy (velocity, le->pos.trDelta);
|
|
if (gravity)
|
|
le->pos.trType = TR_GRAVITY;
|
|
else
|
|
le->pos.trType = TR_LINEAR;
|
|
le->pos.trTime = cg.time;
|
|
le->pos.trDuration = killTime;
|
|
|
|
if (elasticity > 0)
|
|
{
|
|
le->leFlags |= LEF_USE_COLLISION;
|
|
le->bounceFactor = elasticity;
|
|
}
|
|
}
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
|
|
localEntity_t *FX_AddTrail2( vec3_t origin, vec3_t velocity, qboolean gravity, float length, float dlength,
|
|
float scale, float dscale, float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB,
|
|
float elasticity, float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddTrail: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_TRAIL;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.trail.width = scale;
|
|
le->data.trail.dwidth = dscale;
|
|
le->data.trail.length = length;
|
|
le->data.trail.dlength = dlength;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorCopy(startRGB, le->data.trail.startRGB);
|
|
VectorSubtract(endRGB, startRGB, le->data.trail.dRGB);
|
|
|
|
le->refEntity.data.line.stscale = 1.0;
|
|
le->refEntity.data.line.width = scale;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
// kef -- extrapolate oldorigin based on length of trail and origin?
|
|
if (velocity)
|
|
{
|
|
vec3_t vel;
|
|
VectorNormalize2(velocity, vel);
|
|
VectorMA(origin, -length, vel, le->refEntity.oldorigin);
|
|
}
|
|
else
|
|
{
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
}
|
|
|
|
AxisClear(le->refEntity.axis);
|
|
le->refEntity.shaderRGBA[0] = 0xff*startRGB[0];
|
|
le->refEntity.shaderRGBA[1] = 0xff*startRGB[1];
|
|
le->refEntity.shaderRGBA[2] = 0xff*startRGB[2];
|
|
le->refEntity.shaderRGBA[3] = 0xff*startalpha;
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = 1.0;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
if (velocity)
|
|
{
|
|
le->leFlags |= LEF_MOVE;
|
|
VectorCopy (origin, le->pos.trBase);
|
|
VectorCopy (velocity, le->pos.trDelta);
|
|
if (gravity)
|
|
le->pos.trType = TR_GRAVITY;
|
|
else
|
|
le->pos.trType = TR_LINEAR;
|
|
le->pos.trTime = cg.time;
|
|
le->pos.trDuration = killTime;
|
|
|
|
if (elasticity > 0)
|
|
{
|
|
le->leFlags |= LEF_USE_COLLISION;
|
|
le->bounceFactor = elasticity;
|
|
}
|
|
}
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
/*
|
|
===============
|
|
FX_AddSprite
|
|
|
|
Adds a view oriented sprite to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddSprite(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
|
|
float startalpha, float endalpha, float roll, float elasticity,
|
|
float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddSprite: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
// Glow mark
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_VIEWSPRITE;
|
|
le->refEntity.data.sprite.rotation = roll;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.sprite.radius = scale;
|
|
le->data.sprite.dradius = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorSet(le->data.sprite.startRGB, 1, 1, 1);
|
|
VectorSet(le->data.sprite.dRGB, 0, 0, 0);
|
|
|
|
// le->refEntity.hModel = 0;
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
if (velocity)
|
|
{
|
|
le->leFlags |= LEF_MOVE;
|
|
VectorCopy (origin, le->pos.trBase);
|
|
VectorCopy (velocity, le->pos.trDelta);
|
|
if (gravity)
|
|
le->pos.trType = TR_GRAVITY;
|
|
else
|
|
le->pos.trType = TR_LINEAR;
|
|
le->pos.trTime = cg.time;
|
|
le->pos.trDuration = killTime;
|
|
|
|
if (elasticity > 0)
|
|
{
|
|
le->leFlags |= LEF_USE_COLLISION;
|
|
le->bounceFactor = elasticity;
|
|
}
|
|
}
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
/*
|
|
===============
|
|
FX_AddSprite2
|
|
|
|
Adds a view oriented sprite to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddSprite2(vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
|
|
float startalpha, float endalpha, vec3_t startRGB, vec3_t endRGB, float roll, float elasticity,
|
|
float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddSprite: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
// Glow mark
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_VIEWSPRITE;
|
|
le->refEntity.data.sprite.rotation = roll;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.sprite.radius = scale;
|
|
le->data.sprite.dradius = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorCopy(startRGB, le->data.sprite.startRGB);
|
|
VectorSubtract(endRGB, startRGB, le->data.sprite.dRGB);
|
|
|
|
// le->refEntity.hModel = 0;
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
|
|
le->color[0] = startRGB[0];
|
|
le->color[1] = startRGB[1];
|
|
le->color[2] = startRGB[2];
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
if (velocity)
|
|
{
|
|
le->leFlags |= LEF_MOVE;
|
|
VectorCopy (origin, le->pos.trBase);
|
|
VectorCopy (velocity, le->pos.trDelta);
|
|
if (gravity)
|
|
le->pos.trType = TR_GRAVITY;
|
|
else
|
|
le->pos.trType = TR_LINEAR;
|
|
le->pos.trTime = cg.time;
|
|
le->pos.trDuration = killTime;
|
|
|
|
if (elasticity > 0)
|
|
{
|
|
le->leFlags |= LEF_USE_COLLISION;
|
|
le->bounceFactor = elasticity;
|
|
}
|
|
}
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
/*
|
|
===============
|
|
FX_AddSprite3
|
|
|
|
Adds a view oriented sprite to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddSprite3(vec3_t origin, vec3_t velocity, vec3_t acceleration, float scale, float dscale,
|
|
float startalpha, float endalpha, float roll, float elasticity,
|
|
float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddSprite: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
// Glow mark
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_VIEWSPRITE;
|
|
le->refEntity.data.sprite.rotation = roll;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.sprite.radius = scale;
|
|
le->data.sprite.dradius = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorSet(le->data.sprite.startRGB, 1, 1, 1);
|
|
VectorSet(le->data.sprite.dRGB, 0, 0, 0);
|
|
|
|
// le->refEntity.hModel = 0;
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
if (velocity)
|
|
{
|
|
le->leFlags |= LEF_MOVE;
|
|
VectorCopy (origin, le->pos.trBase);
|
|
VectorCopy (velocity, le->pos.trDelta);
|
|
if (acceleration) //how do i make this accellerate in the given direction?... lol, bee-fountain on forge3 now ^^
|
|
le->pos.trType = TR_GRAVITY;
|
|
else
|
|
le->pos.trType = TR_LINEAR;
|
|
le->pos.trTime = cg.time;
|
|
le->pos.trDuration = killTime;
|
|
|
|
if (elasticity > 0)
|
|
{
|
|
le->leFlags |= LEF_USE_COLLISION;
|
|
le->bounceFactor = elasticity;
|
|
}
|
|
}
|
|
|
|
return(le);
|
|
}
|
|
|
|
/*
|
|
===============
|
|
FX_AddBezier
|
|
|
|
Adds a Bezier curve to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddBezier(vec3_t start, vec3_t end, vec3_t cpoint1, vec3_t cpoint2, vec3_t cpointvel1, vec3_t cpointvel2,
|
|
vec3_t cpointacc1, vec3_t cpointacc2, float width, float killTime, qhandle_t shader)
|
|
{
|
|
localEntity_t *le = CG_AllocLocalEntity();
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddBezier: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
// just testing beziers
|
|
le->leType = LE_BEZIER;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
le->data.line.width = width;
|
|
|
|
le->alpha = 1.0;
|
|
le->dalpha = -1.0;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( start, le->refEntity.origin);
|
|
VectorCopy ( end, le->refEntity.oldorigin );
|
|
|
|
AxisClear(le->refEntity.axis);
|
|
le->refEntity.shaderRGBA[0] = 0xff;
|
|
le->refEntity.shaderRGBA[1] = 0xff;
|
|
le->refEntity.shaderRGBA[2] = 0xff;
|
|
le->refEntity.shaderRGBA[3] = 0xff;
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = 1.0;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
if (cpoint1)
|
|
{
|
|
VectorCopy(cpoint1, le->data.line.control1);
|
|
}
|
|
if (cpoint2)
|
|
{
|
|
VectorCopy(cpoint2, le->data.line.control2);
|
|
}
|
|
if (cpointvel1)
|
|
{
|
|
VectorCopy(cpointvel1, le->data.line.control1_velocity);
|
|
}
|
|
if (cpointvel2)
|
|
{
|
|
VectorCopy(cpointvel2, le->data.line.control2_velocity);
|
|
}
|
|
if (cpointacc1)
|
|
{
|
|
VectorCopy(cpointacc1, le->data.line.control1_acceleration);
|
|
}
|
|
if (cpointacc2)
|
|
{
|
|
VectorCopy(cpointacc2, le->data.line.control2_acceleration);
|
|
}
|
|
|
|
return le;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
FX_AddQuad
|
|
|
|
Adds a quad to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddQuad( vec3_t origin, vec3_t normal, float scale, float dscale,
|
|
float startalpha, float endalpha, float roll, float killTime, qhandle_t shader )
|
|
{
|
|
localEntity_t *le = CG_AllocLocalEntity();
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddQuad: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le->leType = LE_QUAD;
|
|
le->refEntity.data.sprite.rotation = roll;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.sprite.radius = scale;
|
|
le->data.sprite.dradius = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
VectorSet(le->data.sprite.startRGB, 1, 1, 1);
|
|
VectorSet(le->data.sprite.dRGB, 0, 0, 0);
|
|
|
|
// le->refEntity.hModel = 0;
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
|
|
VectorCopy( normal, le->refEntity.axis[0] );
|
|
RotateAroundDirection( le->refEntity.axis, le->refEntity.data.sprite.rotation );
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
===============
|
|
FX_AddQuad2
|
|
|
|
Adds a quad to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddQuad2( vec3_t origin, vec3_t normal, float scale, float dscale, float startalpha, float endalpha,
|
|
vec3_t startRGB, vec3_t endRGB, float roll, float killTime, qhandle_t shader )
|
|
{
|
|
localEntity_t *le = CG_AllocLocalEntity();
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddQuad: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le->leType = LE_QUAD;
|
|
le->refEntity.data.sprite.rotation = roll;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.sprite.radius = scale;
|
|
le->data.sprite.dradius = dscale;
|
|
VectorCopy(startRGB, le->data.sprite.startRGB);
|
|
VectorSubtract(endRGB, startRGB, le->data.sprite.dRGB);
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
|
|
// le->refEntity.hModel = 0;
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
|
|
VectorCopy( normal, le->refEntity.axis[0] );
|
|
RotateAroundDirection( le->refEntity.axis, le->refEntity.data.sprite.rotation );
|
|
|
|
le->color[0] = startRGB[0];
|
|
le->color[1] = startRGB[1];
|
|
le->color[2] = startRGB[2];
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
===============
|
|
FX_AddCylinder
|
|
|
|
Adds a cylinder to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
//NOTENOTE: The reigning king of parameters!
|
|
#define DEFAULT_ST_SCALE 1.0f
|
|
|
|
localEntity_t *FX_AddCylinder( vec3_t start,
|
|
vec3_t normal,
|
|
float height,
|
|
float dheight,
|
|
float scale,
|
|
float dscale,
|
|
float scale2,
|
|
float dscale2,
|
|
float startalpha,
|
|
float endalpha,
|
|
float killTime,
|
|
qhandle_t shader,
|
|
float bias )
|
|
{
|
|
localEntity_t *le = CG_AllocLocalEntity();
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddCylinder: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le->leType = LE_CYLINDER;
|
|
le->refEntity.data.cylinder.height = height;
|
|
le->refEntity.data.cylinder.width = scale;
|
|
le->refEntity.data.cylinder.width2 = scale2;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.cylinder.height = height;
|
|
le->data.cylinder.dheight = dheight;
|
|
le->data.cylinder.width = scale;
|
|
le->data.cylinder.dwidth = dscale;
|
|
le->data.cylinder.width2 = scale2;
|
|
le->data.cylinder.dwidth2 = dscale2;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
le->refEntity.data.cylinder.bias = bias;
|
|
le->refEntity.data.cylinder.stscale = 1.0;
|
|
le->refEntity.data.cylinder.wrap = qtrue;
|
|
|
|
// set origin
|
|
VectorCopy ( start, le->refEntity.origin);
|
|
VectorCopy ( start, le->refEntity.oldorigin );
|
|
|
|
VectorCopy( normal, le->refEntity.axis[0] );
|
|
RotateAroundDirection( le->refEntity.axis, 0);
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
/*
|
|
===============
|
|
FX_AddCylinder2
|
|
|
|
Adds a cylinder to the FX wrapper render list
|
|
Overloaded for RGB
|
|
===============
|
|
*/
|
|
|
|
//NOTENOTE: The reigning king of parameters!
|
|
#define DEFAULT_ST_SCALE 1.0f
|
|
|
|
localEntity_t *FX_AddCylinder2( vec3_t start,
|
|
vec3_t normal,
|
|
float height,
|
|
float dheight,
|
|
float scale,
|
|
float dscale,
|
|
float scale2,
|
|
float dscale2,
|
|
float startalpha,
|
|
float endalpha,
|
|
vec3_t startRGB,
|
|
vec3_t endRGB,
|
|
float killTime,
|
|
qhandle_t shader,
|
|
float bias )
|
|
{
|
|
localEntity_t *le = CG_AllocLocalEntity();
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddCylinder: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le->leType = LE_CYLINDER;
|
|
le->refEntity.data.cylinder.height = height;
|
|
le->refEntity.data.cylinder.width = scale;
|
|
le->refEntity.data.cylinder.width2 = scale2;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.cylinder.height = height;
|
|
le->data.cylinder.dheight = dheight;
|
|
le->data.cylinder.width = scale;
|
|
le->data.cylinder.dwidth = dscale;
|
|
le->data.cylinder.width2 = scale2;
|
|
le->data.cylinder.dwidth2 = dscale2;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
le->refEntity.data.cylinder.bias = bias;
|
|
le->refEntity.data.cylinder.stscale = 1.0;
|
|
le->refEntity.data.cylinder.wrap = qtrue;
|
|
|
|
// set origin
|
|
VectorCopy ( start, le->refEntity.origin);
|
|
VectorCopy ( start, le->refEntity.oldorigin );
|
|
|
|
VectorCopy( normal, le->refEntity.axis[0] );
|
|
RotateAroundDirection( le->refEntity.axis, 0);
|
|
|
|
le->color[0] = startRGB[0];
|
|
le->color[1] = startRGB[1];
|
|
le->color[2] = startRGB[2];
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
return(le);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
===============
|
|
FX_AddElectricity
|
|
|
|
Adds a electricity bolt to the scene
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddElectricity( vec3_t origin, vec3_t origin2, float stScale, float scale, float dscale,
|
|
float startalpha, float endalpha, float killTime, qhandle_t shader, float deviation )
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddElectricity: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_ELECTRICITY;
|
|
|
|
// set origin
|
|
VectorCopy (origin, le->refEntity.origin);
|
|
VectorCopy (origin2, le->refEntity.oldorigin );
|
|
|
|
le->refEntity.data.electricity.stscale = stScale;
|
|
le->refEntity.data.electricity.deviation = deviation;
|
|
le->data.electricity.width = scale;
|
|
le->data.electricity.dwidth = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->refEntity.customShader = shader;
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = startalpha;
|
|
|
|
return(le);
|
|
}
|
|
/*
|
|
===============
|
|
FX_AddParticle
|
|
|
|
Adds a particle (basically, a sprite with an optional think function) to the FX wrapper render list
|
|
===============
|
|
*/
|
|
|
|
localEntity_t *FX_AddParticle( vec3_t origin, vec3_t velocity, qboolean gravity, float scale, float dscale,
|
|
float startalpha, float endalpha, float roll, float elasticity,
|
|
float killTime, qhandle_t shader, qboolean (*thinkFn)(localEntity_t *le) )
|
|
{
|
|
localEntity_t *le;
|
|
|
|
#ifdef _DEBUG
|
|
if (!shader)
|
|
{
|
|
Com_Printf("FX_AddParticle: NULL shader\n");
|
|
}
|
|
#endif
|
|
|
|
// Glow mark
|
|
|
|
le = CG_AllocLocalEntity();
|
|
le->leType = LE_PARTICLE;
|
|
le->refEntity.data.sprite.rotation = roll;
|
|
|
|
le->startTime = cg.time;
|
|
le->endTime = le->startTime + killTime;
|
|
|
|
le->data.particle.radius = scale;
|
|
le->data.particle.dradius = dscale;
|
|
|
|
le->alpha = startalpha;
|
|
le->dalpha = endalpha - startalpha;
|
|
|
|
// le->refEntity.hModel = 0;
|
|
le->refEntity.customShader = shader;
|
|
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = startalpha;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
// wacky think function stuff
|
|
le->data.particle.thinkFn = thinkFn;
|
|
|
|
if (velocity)
|
|
{
|
|
le->leFlags |= LEF_MOVE;
|
|
VectorCopy (origin, le->pos.trBase);
|
|
VectorCopy (velocity, le->pos.trDelta);
|
|
if (gravity)
|
|
le->pos.trType = TR_GRAVITY;
|
|
else
|
|
le->pos.trType = TR_LINEAR;
|
|
le->pos.trTime = cg.time;
|
|
le->pos.trDuration = killTime;
|
|
|
|
if (elasticity > 0)
|
|
{
|
|
le->leFlags |= LEF_USE_COLLISION;
|
|
le->bounceFactor = elasticity;
|
|
}
|
|
}
|
|
|
|
return(le);
|
|
}
|
|
|
|
/*
|
|
===============
|
|
FX_AddSpawner
|
|
|
|
Adds a spawner -- basically, a local entity with a think function. Spawners don't have any rendered entities
|
|
associated with them inherently, but the spawner's think fn probably generates them.
|
|
===============
|
|
*/
|
|
localEntity_t *FX_AddSpawner( vec3_t origin, vec3_t dir, vec3_t velocity, vec3_t user, qboolean gravity, int delay,
|
|
float variance, float killTime, qboolean (*thinkFn)(localEntity_t *le), int radius )
|
|
{
|
|
localEntity_t *le = NULL;
|
|
|
|
if (NULL == thinkFn)
|
|
{
|
|
// a spawner with no think fn is silly. and useless.
|
|
return NULL;
|
|
}
|
|
le = CG_AllocLocalEntity();
|
|
|
|
le->leType = LE_SPAWNER;
|
|
|
|
le->data.spawner.data1 = radius;
|
|
le->data.spawner.delay = delay;
|
|
le->data.spawner.nextthink = cg.time + delay;
|
|
le->startTime = cg.time;
|
|
// if we want the spawner to hang around forever, we use a killtime of 0 and the think fn keeps adjusting it.
|
|
//thing is, we still need it to not get culled right here, so give it an arbitrary endTime somewhere in the future.
|
|
if (0 == killTime)
|
|
{
|
|
le->endTime = le->startTime + 10000;
|
|
le->data.spawner.dontDie = qtrue;
|
|
}
|
|
else
|
|
{
|
|
le->endTime = le->startTime + killTime;
|
|
}
|
|
|
|
le->data.spawner.variance = variance;
|
|
if(dir)
|
|
VectorCopy(dir, le->data.spawner.dir);
|
|
// set origin
|
|
VectorCopy ( origin, le->refEntity.origin);
|
|
VectorCopy ( origin, le->refEntity.oldorigin );
|
|
|
|
// maybe employ the user variable here, like in singleplayer? or in the think fn?
|
|
le->color[0] = 1.0;
|
|
le->color[1] = 1.0;
|
|
le->color[2] = 1.0;
|
|
le->color[3] = 1.0;
|
|
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
|
|
|
|
// wacky think function stuff
|
|
le->data.spawner.thinkFn = thinkFn;
|
|
|
|
if (velocity)
|
|
{
|
|
le->leFlags |= LEF_MOVE;
|
|
VectorCopy (origin, le->pos.trBase);
|
|
if(velocity)
|
|
VectorCopy (velocity, le->pos.trDelta);
|
|
if (gravity)
|
|
le->pos.trType = TR_GRAVITY;
|
|
else
|
|
le->pos.trType = TR_LINEAR;
|
|
le->pos.trTime = cg.time;
|
|
// we better not ever have a spawner with a velocity that we expect to last forever, so just plain
|
|
//assigning killTime here _should_ be ok
|
|
le->pos.trDuration = killTime;
|
|
|
|
// if (elasticity > 0)
|
|
// {
|
|
// le->leFlags |= LEF_USE_COLLISION;
|
|
// le->bounceFactor = elasticity;
|
|
// }
|
|
}
|
|
|
|
return (le);
|
|
}
|
|
|
|
// provide the center of the circle, a normal out from it (normalized, please), and the radius.
|
|
//out will then become a random position on the radius of the circle.
|
|
void fxRandCircumferencePos(vec3_t center, vec3_t normal, float radius, vec3_t out)
|
|
{
|
|
float rnd = flrandom(0, 2*M_PI);
|
|
float s = sin(rnd);
|
|
float c = cos(rnd);
|
|
vec3_t vTemp, radialX, radialY;
|
|
|
|
vTemp[0]=0.57735;
|
|
vTemp[1]=0.57735;
|
|
vTemp[2]=0.57735;
|
|
CrossProduct(normal, vTemp, radialX);
|
|
CrossProduct(normal, radialX, radialY);
|
|
VectorScale(radialX, radius, radialX);
|
|
VectorScale(radialY, radius, radialY);
|
|
VectorMA(center, s, radialX, out);
|
|
VectorMA(out, c, radialY, out);
|
|
}
|