mirror of
https://github.com/UberGames/RPG-X2.git
synced 2024-11-22 12:32:13 +00:00
287 lines
7.2 KiB
C
287 lines
7.2 KiB
C
|
#include "cg_local.h"
|
||
|
#include "fx_local.h"
|
||
|
|
||
|
|
||
|
/*
|
||
|
-------------------------
|
||
|
FX_Disruptor
|
||
|
-------------------------
|
||
|
*/
|
||
|
void DisruptorShards(vec3_t org)
|
||
|
{
|
||
|
vec3_t normal, end;
|
||
|
|
||
|
// Pick a random endpoint
|
||
|
VectorSet( normal, crandom(), crandom(), crandom() );
|
||
|
VectorNormalize( normal );
|
||
|
|
||
|
end[0] = org[0] + ( normal[0] * ( 48 + crandom() * 16 ));
|
||
|
end[1] = org[1] + ( normal[1] * ( 48 + crandom() * 16 ));
|
||
|
end[2] = org[2] + ( normal[2] * ( 64 + crandom() * 24 ));
|
||
|
|
||
|
// Draw a light shard, use a couple of different kinds so it doesn't look too homogeneous
|
||
|
if( rand() & 1 )
|
||
|
{
|
||
|
FX_AddLine( org, end, 1.0, random() * 0.5 + 0.5, 12.0, random() * 0.1 + 0.1, 0.0, 200 + random() * 350, cgs.media.orangeParticleShader );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
FX_AddLine( org, end, 1.0, random() * 0.5 + 0.5, 12.0, random() * 0.1 + 0.1, 0.0, 200 + random() * 350, cgs.media.yellowParticleShader );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
qboolean MakeDisruptorShard( localEntity_t *le )
|
||
|
{
|
||
|
DisruptorShards(le->refEntity.origin);
|
||
|
return(qtrue);
|
||
|
}
|
||
|
|
||
|
// Effect used when scav beams in--this wouldn't work well for a scav on the ground if they were to beam out
|
||
|
void FX_Disruptor( vec3_t org, float length )
|
||
|
{//FIXME: make it move with owner?
|
||
|
vec3_t org1, org2, normal={0,0,1};
|
||
|
int t;
|
||
|
|
||
|
VectorMA( org, 48, normal, org1 );
|
||
|
VectorMA( org, -48, normal, org2 );
|
||
|
|
||
|
// This is the core
|
||
|
FX_AddLine( org1, org2, 1.0, 0.1, 48.0, 1.0, 0.0, length, cgs.media.dkorangeParticleShader );
|
||
|
|
||
|
// Spawn a bunch to get the effect going
|
||
|
for (t=0; t < 12; t++ )
|
||
|
{
|
||
|
DisruptorShards( org);
|
||
|
}
|
||
|
|
||
|
// Keep spawning the light shards for a while.
|
||
|
FX_AddSpawner( org, normal, NULL, NULL, qfalse, 20, 10, length*0.75, MakeDisruptorShard, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void FX_EnergyGibs(vec3_t origin )
|
||
|
{
|
||
|
localEntity_t *le;
|
||
|
refEntity_t *re;
|
||
|
vec3_t dir;
|
||
|
int i, j, k;
|
||
|
int chunkModel=0;
|
||
|
float baseScale = 0.7f, dist;
|
||
|
int numChunks;
|
||
|
|
||
|
numChunks = irandom( 10, 15 );
|
||
|
|
||
|
VectorSubtract(cg.snap->ps.origin, origin, dir);
|
||
|
dist = VectorLength(dir);
|
||
|
if (dist > 512)
|
||
|
{
|
||
|
numChunks *= 512.0/dist; // 1/2 at 1024, 1/4 at 2048, etc.
|
||
|
}
|
||
|
|
||
|
for ( i = 0; i < numChunks; i++ )
|
||
|
{
|
||
|
chunkModel = cgs.media.chunkModels[MT_METAL][irandom(0,5)];
|
||
|
|
||
|
le = CG_AllocLocalEntity();
|
||
|
re = &le->refEntity;
|
||
|
|
||
|
le->leType = LE_FRAGMENT;
|
||
|
le->endTime = cg.time + 2000;
|
||
|
|
||
|
VectorCopy( origin, re->origin );
|
||
|
|
||
|
for ( j = 0; j < 3; j++ )
|
||
|
{
|
||
|
re->origin[j] += crandom() * 12;
|
||
|
}
|
||
|
VectorCopy( re->origin, le->pos.trBase );
|
||
|
|
||
|
//Velocity
|
||
|
VectorSet( dir, crandom(), crandom(), crandom() );
|
||
|
VectorScale( dir, flrandom( 300, 500 ), le->pos.trDelta );
|
||
|
|
||
|
//Angular Velocity
|
||
|
VectorSet( le->angles.trBase, crandom() * 360, crandom() * 360, crandom() * 360 );
|
||
|
VectorSet( le->angles.trDelta, crandom() * 90, crandom() * 90, crandom() * 90 );
|
||
|
|
||
|
AxisCopy( axisDefault, re->axis );
|
||
|
|
||
|
le->data.fragment.radius = flrandom(baseScale * 0.4f, baseScale * 0.8f );
|
||
|
|
||
|
re->nonNormalizedAxes = qtrue;
|
||
|
re->hModel = chunkModel;
|
||
|
re->renderfx |= RF_CAP_FRAMES;
|
||
|
re->customShader = cgs.media.quantumDisruptorShader;
|
||
|
re->shaderTime = cg.time/1000.0f;
|
||
|
|
||
|
le->pos.trType = TR_GRAVITY;
|
||
|
le->pos.trTime = cg.time;
|
||
|
le->angles.trType = TR_INTERPOLATE;
|
||
|
le->angles.trTime = cg.time;
|
||
|
le->bounceFactor = 0.2f + random() * 0.2f;
|
||
|
le->leFlags |= LEF_TUMBLE;
|
||
|
|
||
|
re->shaderRGBA[0] = re->shaderRGBA[1] = re->shaderRGBA[2] = re->shaderRGBA[3] = 255;
|
||
|
|
||
|
// Make sure that we have the desired start size set
|
||
|
for( k = 0; k < 3; k++)
|
||
|
{
|
||
|
VectorScale(le->refEntity.axis[k], le->data.fragment.radius, le->refEntity.axis[k]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void FX_ExplodeBits( vec3_t org)
|
||
|
{
|
||
|
float width, length;
|
||
|
vec3_t vel, pos;
|
||
|
int i;
|
||
|
|
||
|
FX_EnergyGibs(org);
|
||
|
|
||
|
for (i = 0; i < 32; i++)
|
||
|
{
|
||
|
VectorSet(vel, flrandom(-320,320), flrandom(-320,320), flrandom(-100,320));
|
||
|
VectorCopy(org, pos);
|
||
|
pos[2] += flrandom(-8, 8);
|
||
|
length = flrandom(10,20);
|
||
|
width = flrandom(2.0,4.0);
|
||
|
FX_AddTrail( pos, vel, qtrue, length, -length, width, -width,
|
||
|
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define Q_FLASH_SIZE 110
|
||
|
|
||
|
void FX_qFlash( centity_t* cent, vec3_t org, int timeIndex ) {
|
||
|
trace_t tr;
|
||
|
refEntity_t flare;
|
||
|
float frac;
|
||
|
|
||
|
if ( cg.predictedPlayerState.clientNum != cent->currentState.clientNum ) {
|
||
|
CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL,
|
||
|
cent->lerpOrigin, cg.predictedPlayerState.clientNum, CONTENTS_SOLID );
|
||
|
if ( tr.fraction != 1 ) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
memset( &flare, 0, sizeof( flare ) );
|
||
|
|
||
|
flare.reType = RT_SPRITE;
|
||
|
flare.shaderRGBA[0] = 0xff;
|
||
|
flare.shaderRGBA[1] = 0xff;
|
||
|
flare.shaderRGBA[2] = 0xff;
|
||
|
flare.shaderRGBA[3] = 0xff;
|
||
|
|
||
|
flare.data.sprite.rotation = 0;
|
||
|
flare.nonNormalizedAxes = qtrue; //needed for effective scaling
|
||
|
|
||
|
flare.customShader = cgs.media.qFlashSprite;
|
||
|
|
||
|
flare.renderfx |= RF_DEPTHHACK;
|
||
|
|
||
|
VectorCopy( org, flare.origin );
|
||
|
|
||
|
//find the basic ratio
|
||
|
frac = (float)(cg.time - timeIndex) / (float)( Q_FLASH_TIME );
|
||
|
//apply a sine function to it to make it less linear
|
||
|
//calculated using the fine graph prog @ http://math.umn.edu/~garrett/a08/Graph.html
|
||
|
frac = ( 0.65f * sin( 4.5f * frac - 0.6f ) + 0.35f );
|
||
|
|
||
|
frac = Com_Clamp( 0.0f, 1.0f, frac );
|
||
|
|
||
|
//CG_Printf( "%f\n", frac );
|
||
|
|
||
|
flare.data.sprite.radius = (float)Q_FLASH_SIZE * frac;
|
||
|
|
||
|
trap_R_AddRefEntityToScene( &flare );
|
||
|
}
|
||
|
|
||
|
#define PROBE_BEAM_LENGTH 32
|
||
|
//TiM - Beam FX for the Neutrino Probe weapon
|
||
|
void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
|
||
|
{
|
||
|
trace_t tr;
|
||
|
refEntity_t beam;
|
||
|
vec3_t end;
|
||
|
float scale;
|
||
|
|
||
|
memset( &beam, 0, sizeof( beam ) );
|
||
|
|
||
|
if ( alt_fire )
|
||
|
scale = flrandom(7.0f, 12.0f);
|
||
|
else
|
||
|
scale = Q_fabs( 12.0f * sin( cg.time * 0.1f ) );
|
||
|
|
||
|
VectorMA( origin, PROBE_BEAM_LENGTH, dir, end );
|
||
|
|
||
|
CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );
|
||
|
|
||
|
trap_R_AddLightToScene( origin, 20, 114.0f / 255, 164.0f / 255, 1.0f );
|
||
|
|
||
|
VectorCopy( origin, beam.origin);
|
||
|
VectorCopy( tr.endpos, beam.oldorigin );
|
||
|
beam.reType = RT_LINE;
|
||
|
beam.customShader = cgs.media.probeBeam;
|
||
|
beam.shaderRGBA[0] = 0xff;
|
||
|
beam.shaderRGBA[1] = 0xff;
|
||
|
beam.shaderRGBA[2] = 0xff;
|
||
|
beam.shaderRGBA[3] = 0xff;
|
||
|
AxisClear( beam.axis );
|
||
|
|
||
|
beam.data.line.width = scale*0.1;
|
||
|
beam.data.line.width2 = scale;
|
||
|
beam.data.line.stscale = 1.0;
|
||
|
trap_R_AddRefEntityToScene( &beam );
|
||
|
|
||
|
if ( tr.fraction != 1.0f )
|
||
|
{
|
||
|
float radius;
|
||
|
|
||
|
if ( alt_fire )
|
||
|
radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
|
||
|
else
|
||
|
radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));
|
||
|
|
||
|
if ( !radius )
|
||
|
return;
|
||
|
|
||
|
CG_ImpactMark( cgs.media.probeDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
|
||
|
trap_R_AddLightToScene( origin, radius*5, 114.0f / 255, 164.0f / 255, 1.0f );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define REGEN_BEAM_LENGTH 64
|
||
|
void FX_RegenBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
|
||
|
{
|
||
|
trace_t tr;
|
||
|
vec3_t end;
|
||
|
|
||
|
VectorMA( origin, REGEN_BEAM_LENGTH, dir, end );
|
||
|
|
||
|
CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );
|
||
|
|
||
|
trap_R_AddLightToScene( origin, 30, 235.0f / 255, 74.0f / 255, 102.0f / 255 );
|
||
|
|
||
|
if ( tr.fraction != 1.0f )
|
||
|
{
|
||
|
float radius;
|
||
|
|
||
|
if ( alt_fire )
|
||
|
radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
|
||
|
else
|
||
|
radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));
|
||
|
|
||
|
if ( !radius )
|
||
|
return;
|
||
|
|
||
|
CG_ImpactMark( cgs.media.regenDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
|
||
|
trap_R_AddLightToScene( origin, radius*5, 235.0f / 255, 74.0f / 255, 102.0f / 255 );
|
||
|
}
|
||
|
}
|