2011-06-01 12:20:56 +00:00
|
|
|
#include "cg_local.h"
|
|
|
|
#include "fx_local.h"
|
|
|
|
|
|
|
|
void FX_StasisDischarge( vec3_t origin, vec3_t normal, int count, float dist_out, float dist_side );
|
|
|
|
|
|
|
|
#define FX_STASIS_ALT_RIGHT_OFS 0.10
|
|
|
|
#define FX_STASIS_ALT_UP_OFS 0.02
|
|
|
|
#define FX_STASIS_ALT_MUZZLE_OFS 1
|
|
|
|
#define FX_MAXRANGE_STASIS 4096
|
|
|
|
|
|
|
|
/*
|
|
|
|
-------------------------
|
|
|
|
FX_StasisShot
|
|
|
|
|
|
|
|
Alt-fire, beam that shrinks to its impact point
|
|
|
|
-------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*void FX_SmallStasisBeam(centity_t *cent, vec3_t start, vec3_t dir)
|
|
|
|
{
|
|
|
|
vec3_t end, org, vel = { 0,0,-4};
|
|
|
|
trace_t tr;
|
|
|
|
float r;
|
|
|
|
int i, ct, t;
|
|
|
|
|
|
|
|
VectorMA(start, FX_MAXRANGE_STASIS, dir, end);
|
|
|
|
CG_Trace(&tr, start, NULL, NULL, end, cent->currentState.number, MASK_SHOT);
|
|
|
|
|
|
|
|
// Beam
|
|
|
|
// FX_AddLine( start, tr.endpos, 1.0f, 3.0f, 4.0f, 0.8f, 0.0f, 400.0f, cgs.media.stasisAltShader);
|
|
|
|
|
|
|
|
// Do a quick LOD for number of decay particles
|
|
|
|
ct = tr.fraction * (FX_MAXRANGE_STASIS * 0.02);
|
|
|
|
if ( ct < 12 )
|
|
|
|
ct = 12;
|
|
|
|
else if ( ct > 24 )
|
|
|
|
ct = 24;
|
|
|
|
|
|
|
|
for ( i = 0; i < ct; i++ )
|
|
|
|
{
|
|
|
|
r = random() * tr.fraction * (FX_MAXRANGE_STASIS * 0.5);
|
|
|
|
VectorMA( start, r, dir, org );
|
|
|
|
|
|
|
|
for ( t = 0; t < 3; t++ )
|
|
|
|
org[t] += crandom();
|
|
|
|
|
|
|
|
if ( rand() & 1 )
|
|
|
|
FX_AddSprite( org, vel, qfalse, random() + 1.5, -3, 1.0, 1.0, 0.0, 0.0, 500, cgs.media.blueParticleShader);
|
|
|
|
else
|
|
|
|
FX_AddSprite( org, vel, qfalse, random() + 1.5, -3, 1.0, 1.0, 0.0, 0.0, 500, cgs.media.purpleParticleShader);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Impact graphic if needed.
|
|
|
|
if (cg_entities[tr.entityNum].currentState.eType == ET_PLAYER)
|
|
|
|
{ // Hit an entity.
|
|
|
|
// Expanding rings
|
|
|
|
// FX_AddSprite( tr.endpos, NULL, qfalse, 1, 60, 0.8, 0.2, random() * 360, 0, 400, cgs.media.stasisRingShader );
|
|
|
|
// Impact effect
|
|
|
|
// FX_AddSprite( tr.endpos, NULL, qfalse, 7, 25, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
|
|
|
|
FX_AddSprite( tr.endpos, NULL, qfalse, 5, 18, 1.0, 0.0, random() * 360, 0, 420, cgs.media.ltblueParticleShader );
|
|
|
|
}
|
|
|
|
else if (!(tr.surfaceFlags & SURF_NOIMPACT) )
|
|
|
|
{
|
|
|
|
// Move me away from the wall a bit so that I don't z-buffer into it
|
|
|
|
VectorMA( tr.endpos, 1.5, tr.plane.normal, end);
|
|
|
|
|
|
|
|
// Expanding rings
|
|
|
|
// FX_AddQuad( end, tr.plane.normal, 1, 12, 0.8, 0.2, random() * 360, 400, cgs.media.stasisRingShader );
|
|
|
|
// FX_AddQuad( end, tr.plane.normal, 1, 30, 0.8, 0.2, random() * 360, 300, cgs.media.stasisRingShader );
|
|
|
|
// Impact effect
|
|
|
|
FX_AddQuad( end, tr.plane.normal, 4, 16, 1.0, 0.0, random() * 360, 500, cgs.media.blueParticleShader );
|
|
|
|
FX_AddQuad( end, tr.plane.normal, 3, 12, 1.0, 0.0, random() * 360, 420, cgs.media.ltblueParticleShader );
|
|
|
|
|
|
|
|
CG_ImpactMark( cgs.media.scavMarkShader, end, tr.plane.normal, random()*360, 1,1,1,0.6, qfalse,
|
|
|
|
5 + random() * 2, qfalse );
|
|
|
|
}
|
|
|
|
|
|
|
|
FX_AddSprite( tr.endpos, NULL, qfalse, flrandom(40,60), -50, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
|
|
|
|
|
|
|
|
// Pass the end position back to the calling function (yes, I know).
|
|
|
|
VectorCopy(tr.endpos, dir);
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
// kef -- fixme. the altfire stuff really wants to use some endcap stuff and some other flags
|
|
|
|
/*void FX_StasisShot( centity_t *cent, vec3_t end, vec3_t start )
|
|
|
|
{
|
|
|
|
trace_t tr;
|
|
|
|
vec3_t fwd, newdir, org, vel = { 0,0,-4}, newstart, end2;
|
|
|
|
int i, t, ct;
|
|
|
|
float len, r;
|
|
|
|
vec3_t fwd2, right, up;
|
|
|
|
int bolt1, bolt2;
|
|
|
|
vec3_t bolt1vec, bolt2vec;
|
|
|
|
centity_t *traceEnt = NULL;
|
|
|
|
int clientNum = -1;
|
|
|
|
|
|
|
|
// Choose which bolt will have the electricity accent.
|
|
|
|
bolt1 = irandom(0,2);
|
|
|
|
bolt2 = irandom(0,4);
|
|
|
|
|
|
|
|
VectorSubtract( end, start, fwd );
|
|
|
|
len = VectorNormalize( fwd );
|
|
|
|
|
|
|
|
// Beam
|
|
|
|
// FX_AddLine( end, start, 1.0f, 4.0f, 6.0f, 0.8f, 0.0f, 500.0f, cgs.media.stasisAltShader);
|
|
|
|
|
|
|
|
// Do a quick LOD for number of decay particles
|
|
|
|
ct = len * 0.03;
|
|
|
|
if ( ct < 16 )
|
|
|
|
ct = 16;
|
|
|
|
else if ( ct > 32 )
|
|
|
|
ct = 32;
|
|
|
|
|
|
|
|
for ( i = 0; i < ct; i++ )
|
|
|
|
{
|
|
|
|
r = random() * len * 0.5;
|
|
|
|
VectorMA( start, r, fwd, org );
|
|
|
|
|
|
|
|
for ( t = 0; t < 3; t++ )
|
|
|
|
org[t] += crandom();
|
|
|
|
|
|
|
|
if ( rand() & 1 )
|
|
|
|
FX_AddSprite( org, vel, qfalse, random() + 2, -4, 1.0, 1.0, 0.0, 0.0, 600, cgs.media.blueParticleShader);
|
|
|
|
else
|
|
|
|
FX_AddSprite( org, vel, qfalse, random() + 2, -4, 1.0, 1.0, 0.0, 0.0, 600, cgs.media.purpleParticleShader);
|
|
|
|
}
|
|
|
|
VectorMA(start, FX_MAXRANGE_STASIS, fwd, end2);
|
|
|
|
CG_Trace(&tr, start, NULL, NULL, end2, cent->currentState.number, MASK_SHOT);
|
|
|
|
if (!( tr.surfaceFlags & SURF_NOIMPACT ))
|
|
|
|
{
|
|
|
|
traceEnt = &cg_entities[tr.entityNum];
|
|
|
|
clientNum = traceEnt->currentState.clientNum;
|
|
|
|
if ( (tr.entityNum != ENTITYNUM_WORLD) && (clientNum >= 0 || clientNum < MAX_CLIENTS) )
|
|
|
|
{
|
|
|
|
// hit a player
|
|
|
|
FX_StasisShotImpact(tr.endpos, tr.plane.normal);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// hit the world
|
|
|
|
FX_StasisShotMiss(tr.endpos, tr.plane.normal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// cap the impact end of the main beam to hide the nasty end of the line
|
|
|
|
FX_AddSprite( tr.endpos, NULL, qfalse, flrandom(40,60), -50, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
|
|
|
|
|
|
|
|
if (bolt1==0)
|
|
|
|
{
|
|
|
|
VectorCopy(end, bolt1vec);
|
|
|
|
}
|
|
|
|
else if (bolt2==0)
|
|
|
|
{
|
|
|
|
VectorCopy(end, bolt2vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
AngleVectors(cent->currentState.angles, fwd2, right, up);
|
|
|
|
|
|
|
|
// CrossProduct(fwd, up, right);
|
|
|
|
// VectorNormalize(right); // "right" is scaled by the sin of the angle between fwd & up... Ditch that.
|
|
|
|
// CrossProduct(right, fwd, up); // Change the "fake up" (0,0,1) to a "real up" (perpendicular to the forward vector).
|
|
|
|
// VectorNormalize(up); // If I cared about how the vertical variance looked when pointing up or down, I'd normalize this.
|
|
|
|
|
|
|
|
// Fire a shot up and to the right.
|
|
|
|
VectorMA(fwd, FX_STASIS_ALT_RIGHT_OFS, right, newdir);
|
|
|
|
VectorMA(newdir, FX_STASIS_ALT_UP_OFS, up, newdir);
|
|
|
|
VectorMA(start, FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
|
|
|
|
FX_SmallStasisBeam(cent, newstart, newdir);
|
|
|
|
|
|
|
|
if (bolt1==1)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt1vec);
|
|
|
|
}
|
|
|
|
else if (bolt2==1)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt2vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fire a shot up and to the left.
|
|
|
|
VectorMA(fwd, -FX_STASIS_ALT_RIGHT_OFS, right, newdir);
|
|
|
|
VectorMA(newdir, FX_STASIS_ALT_UP_OFS, up, newdir);
|
|
|
|
VectorMA(start, -FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
|
|
|
|
FX_SmallStasisBeam(cent, newstart, newdir);
|
|
|
|
|
|
|
|
if (bolt1==2)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt1vec);
|
|
|
|
}
|
|
|
|
else if (bolt2==2)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt2vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fire a shot a bit down and to the right.
|
|
|
|
VectorMA(fwd, 2.0*FX_STASIS_ALT_RIGHT_OFS, right, newdir);
|
|
|
|
VectorMA(newdir, -0.5*FX_STASIS_ALT_UP_OFS, up, newdir);
|
|
|
|
VectorMA(start, 2.0*FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
|
|
|
|
FX_SmallStasisBeam(cent, newstart, newdir);
|
|
|
|
|
|
|
|
if (bolt1==3)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt1vec);
|
|
|
|
}
|
|
|
|
else if (bolt2==3)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt2vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fire a shot up and to the left.
|
|
|
|
VectorMA(fwd, -2.0*FX_STASIS_ALT_RIGHT_OFS, right, newdir);
|
|
|
|
VectorMA(newdir, -0.5*FX_STASIS_ALT_UP_OFS, up, newdir);
|
|
|
|
VectorMA(start, -2.0*FX_STASIS_ALT_MUZZLE_OFS, right, newstart);
|
|
|
|
FX_SmallStasisBeam(cent, newstart, newdir);
|
|
|
|
|
|
|
|
if (bolt1==4)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt1vec);
|
|
|
|
}
|
|
|
|
else if (bolt2==4)
|
|
|
|
{
|
|
|
|
VectorCopy(newdir, bolt2vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Put a big gigant-mo sprite at the muzzle end so people can't see the crappy edges of the line
|
|
|
|
FX_AddSprite( start, NULL, qfalse, random()*3 + 15, -20, 1.0, 0.5, 0.0, 0.0, 600, cgs.media.blueParticleShader);
|
|
|
|
|
|
|
|
// Do an electrical arc to one of the impact points.
|
|
|
|
FX_AddElectricity( start, bolt1vec, 0.2f, 15.0, -15.0, 1.0, 0.5, 100, cgs.media.dnBoltShader, 0.1 );
|
|
|
|
|
|
|
|
if (bolt1!=bolt2)
|
|
|
|
{
|
|
|
|
// ALSO do an electrical arc to another point.
|
|
|
|
FX_AddElectricity( bolt1vec, bolt2vec, 0.2f, 15.0, -15.0, 1.0, 0.5, flrandom(100,200), cgs.media.dnBoltShader, 0.5 );
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
-------------------------
|
|
|
|
FX_StasisShotImpact
|
|
|
|
|
|
|
|
Alt-fire, impact effect
|
|
|
|
-------------------------
|
|
|
|
*/
|
|
|
|
/*void FX_StasisShotImpact( vec3_t end, vec3_t dir )
|
|
|
|
{
|
|
|
|
vec3_t org;
|
|
|
|
|
|
|
|
// Move me away from the wall a bit so that I don't z-buffer into it
|
|
|
|
VectorMA( end, 1.5, dir, org );
|
|
|
|
|
|
|
|
// Expanding rings
|
|
|
|
// FX_AddQuad( org, dir, 1, 80, 0.8, 0.2, random() * 360, 400, cgs.media.stasisRingShader );
|
|
|
|
// Impact effect
|
|
|
|
FX_AddQuad( org, dir, 7, 35, 1.0, 0.0, random() * 360, 500, cgs.media.blueParticleShader );
|
|
|
|
FX_AddQuad( org, dir, 5, 25, 1.0, 0.0, random() * 360, 420, cgs.media.ltblueParticleShader );
|
|
|
|
|
|
|
|
// CG_ImpactMark( cgs.media.scavMarkShader, org, dir, random()*360, 1,1,1,0.6, qfalse,
|
|
|
|
// 8 + random() * 2, qfalse );
|
|
|
|
|
|
|
|
// FX_StasisDischarge( org, dir, irandom( 2,4 ), 24 + random() * 12, 64 + random() * 48 );
|
|
|
|
}*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
-------------------------
|
|
|
|
FX_StasisShotMiss
|
|
|
|
|
|
|
|
Alt-fire, miss effect
|
|
|
|
-------------------------
|
|
|
|
*/
|
|
|
|
/*void FX_StasisShotMiss( vec3_t end, vec3_t dir )
|
|
|
|
{
|
|
|
|
vec3_t org;
|
|
|
|
|
|
|
|
// Move me away from the wall a bit so that I don't z-buffer into it
|
|
|
|
VectorMA( end, 0.5, dir, org );
|
|
|
|
|
|
|
|
// Expanding rings
|
|
|
|
// FX_AddQuad( org, dir, 1, 16, 0.8, 0.2, random() * 360, 400, cgs.media.stasisRingShader );
|
|
|
|
// FX_AddQuad( org, dir, 1, 40, 0.8, 0.2, random() * 360, 300, cgs.media.stasisRingShader );
|
|
|
|
// Impact effect
|
|
|
|
FX_AddQuad( org, dir, 5, 25, 1.0, 0.0, random() * 360, 500, cgs.media.blueParticleShader );
|
|
|
|
FX_AddQuad( org, dir, 4, 17, 1.0, 0.0, random() * 360, 420, cgs.media.ltblueParticleShader );
|
|
|
|
|
|
|
|
CG_ImpactMark( cgs.media.scavMarkShader, org, dir, random()*360, 1,1,1,0.6, qfalse,
|
|
|
|
6 + random() * 2, qfalse );
|
|
|
|
|
|
|
|
FX_AddSprite( end, NULL, qfalse, flrandom(40,60), -50, 1.0, 0.0, random() * 360, 0, 500, cgs.media.blueParticleShader );
|
|
|
|
|
|
|
|
// FX_StasisDischarge( org, dir, irandom( 2,4 ), 24 + random() * 12, 64 + random() * 48 );
|
|
|
|
}*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
-------------------------
|
|
|
|
FX_StasisProjectileThink
|
|
|
|
|
|
|
|
Main fire, with crazy bits swirling around main projectile
|
|
|
|
Hehe used to :D -TiM
|
|
|
|
-------------------------
|
|
|
|
*/
|
|
|
|
//unused
|
|
|
|
/*void FX_StasisProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
|
|
|
|
{
|
|
|
|
int size = 0;
|
|
|
|
vec3_t forward;
|
|
|
|
//vec3_t right, up;
|
|
|
|
//float radius, temp;
|
|
|
|
vec3_t org;
|
|
|
|
|
|
|
|
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0 )
|
|
|
|
forward[2] = 1;
|
|
|
|
|
|
|
|
VectorCopy( cent->lerpOrigin, org );
|
|
|
|
|
|
|
|
// org[0] -=32;
|
|
|
|
|
|
|
|
//FX_AddTrail(
|
|
|
|
|
|
|
|
FX_AddTrail( org, forward, qfalse, 64, 0, 30.4f, 0.0f, 0.6f, 0.0f, 0, 1, cgs.media.disruptorBolt );
|
|
|
|
|
|
|
|
FX_AddSprite( cent->lerpOrigin, NULL, qfalse, 25.0f, 0.0f, 0.7f, 0.0f, 1.0f, 0.0f, 1.0f, cgs.media.disruptorStreak );
|
|
|
|
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
-------------------------
|
|
|
|
FX_OrientedBolt
|
|
|
|
|
|
|
|
Creates new bolts for a while
|
|
|
|
-------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
void FX_OrientedBolt( vec3_t start, vec3_t end, vec3_t dir )
|
|
|
|
{
|
|
|
|
vec3_t mid;
|
|
|
|
|
|
|
|
VectorSubtract( end, start, mid );
|
|
|
|
VectorScale( mid, 0.1f + (random() * 0.8), mid );
|
|
|
|
VectorAdd( start, mid, mid );
|
|
|
|
VectorMA(mid, 3.0f + (random() * 10.0f), dir, mid );
|
|
|
|
|
|
|
|
//FX_AddElectricity( mid, start, 0.5, 0.75 + random() * 0.75, 0.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.bolt2Shader, DEFAULT_DEVIATION);
|
|
|
|
//FX_AddElectricity( mid, end, 0.5, 0.75 + random() * 0.75, 1.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.bolt2Shader, DEFAULT_DEVIATION);
|
|
|
|
|
|
|
|
FX_AddElectricity( mid, start, 0.5, 0.75 + random() * 0.75, 0.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.borgLightningShaders[2], DEFAULT_DEVIATION);
|
|
|
|
FX_AddElectricity( mid, end, 0.5, 0.75 + random() * 0.75, 1.0, 1.0, 0.5, 300.0f + random() * 300, cgs.media.borgLightningShaders[3], DEFAULT_DEVIATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
-------------------------
|
|
|
|
FX_StasisDischarge
|
|
|
|
|
|
|
|
Fun "crawling" electricity ( credit goes to Josh for this one )
|
|
|
|
-------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
void FX_StasisDischarge( vec3_t origin, vec3_t normal, int count, float dist_out, float dist_side )
|
|
|
|
{
|
|
|
|
trace_t trace;
|
|
|
|
vec3_t org, dir, dest;
|
|
|
|
vec3_t vr;
|
|
|
|
int i;
|
|
|
|
int discharge = dist_side;
|
|
|
|
|
|
|
|
vectoangles( normal, dir );
|
|
|
|
dir[ROLL] += random() * 360;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
//Move out a set distance
|
|
|
|
VectorMA( origin, dist_out, normal, org );
|
|
|
|
|
|
|
|
//Even out the hits
|
|
|
|
dir[ROLL] += (360 / count) + (rand() & 31);
|
|
|
|
AngleVectors( dir, NULL, vr, NULL );
|
|
|
|
|
|
|
|
//Move to the side in a random direction
|
|
|
|
discharge += (int)( crandom() * 8.0f );
|
|
|
|
VectorMA( org, discharge, vr, org );
|
|
|
|
|
|
|
|
//Trace back to find a surface
|
|
|
|
VectorMA( org, -dist_out * 3, normal, dest );
|
|
|
|
|
|
|
|
CG_Trace( &trace, org, NULL, NULL, dest, 0, MASK_SHOT );
|
|
|
|
|
|
|
|
//No surface found, start over
|
|
|
|
if (trace.fraction == 1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
//Connect the two points with bolts
|
|
|
|
FX_OrientedBolt( origin, trace.endpos, normal );
|
|
|
|
|
|
|
|
//TiM : Aww screw it. Add a lens flare. ^_^
|
|
|
|
CG_InitLensFlare( trace.endpos,
|
|
|
|
10, 10,
|
|
|
|
colorTable[CT_GREEN], 1.2, 2.0, 1600, 500,
|
|
|
|
colorTable[CT_GREEN], 1600, 500, 100, 5, qtrue,
|
|
|
|
0, 0, qfalse, qtrue,
|
|
|
|
qfalse, 1.0, cg.time, 0, 0, 300.0f + random() * 300);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
-------------------------
|
|
|
|
FX_StasisWeaponHitWall
|
|
|
|
|
|
|
|
Main fire impact
|
|
|
|
-------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define NUM_DISCHARGES 6
|
|
|
|
#define DISCHARGE_DIST 8
|
|
|
|
#define DISCHARGE_SIDE_DIST 24
|
|
|
|
|
|
|
|
void FX_StasisWeaponHitWall( vec3_t origin, vec3_t dir, int size )
|
|
|
|
{
|
|
|
|
vec3_t vel, /*accel,*/ hitpos, direction, org;
|
|
|
|
//int i, t;
|
|
|
|
weaponInfo_t *weaponInfo = &cg_weapons[WP_DISRUPTOR];
|
|
|
|
|
|
|
|
CG_InitLensFlare( origin,
|
|
|
|
375, 375,
|
|
|
|
colorTable[CT_GREEN], 1.2, 2.0, 1600, 200,
|
|
|
|
colorTable[CT_GREEN], 1600, 200, 800, 20, qtrue,
|
|
|
|
0, 0, qfalse, qtrue,
|
|
|
|
qfalse, 1.0, cg.time, 0, 0, 200);
|
|
|
|
|
|
|
|
// Generate "crawling" electricity // eh, don't it doesn't look that great.
|
|
|
|
FX_StasisDischarge( origin, dir, NUM_DISCHARGES, DISCHARGE_DIST, DISCHARGE_SIDE_DIST );
|
|
|
|
|
|
|
|
VectorMA(origin, size, dir, hitpos);
|
|
|
|
|
|
|
|
// Set an oriented residual glow effect
|
|
|
|
FX_AddQuad( hitpos, dir, size * size * 15.0f, -150.0f,
|
|
|
|
1.0f, 0.0f, 0, 300, cgs.media.greenParticleShader );
|
|
|
|
|
|
|
|
CG_ImpactMark( cgs.media.scavMarkShader, origin, dir, random()*360, 1,1,1,0.6, qfalse,
|
|
|
|
size * 12 + 1, qfalse );
|
|
|
|
|
|
|
|
FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
|
|
|
|
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleShader );
|
|
|
|
|
|
|
|
/* FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f,
|
|
|
|
1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleStreakShader ); */
|
|
|
|
|
|
|
|
FX_AddSprite( hitpos, NULL, qfalse, size * size * 25.0f, -150.0f,
|
|
|
|
1.0f, 0.0f, 0.0f, 0, 400, cgs.media.greenParticleStreakShader );
|
|
|
|
|
|
|
|
VectorSubtract( cg.refdef.vieworg, origin, direction );
|
|
|
|
VectorNormalize( direction );
|
|
|
|
|
|
|
|
VectorMA( origin, 12, direction, org );
|
|
|
|
VectorMA( org, 8, dir, direction );
|
|
|
|
VectorSet(vel, 0, 0, 32 ); //8
|
|
|
|
|
|
|
|
FX_AddSprite( origin,
|
|
|
|
vel, qfalse,
|
|
|
|
random() * 4 + 2, 12,
|
|
|
|
0.6 + random() * 0.4, 0.0,
|
|
|
|
random() * 180,
|
|
|
|
0.0,
|
|
|
|
random() * 200 + 1200, //300
|
|
|
|
cgs.media.steamShader );
|
|
|
|
|
|
|
|
//FX_AddSprite(
|
|
|
|
|
|
|
|
// Only play the impact sound and throw off the purple particles when it's the main projectile
|
|
|
|
/* if ( size < 3 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
for ( i = 0; i < 4; i++ )
|
|
|
|
{
|
|
|
|
for ( t = 0; t < 3; t++ )
|
|
|
|
vel[t] = ( dir[t] + crandom() * 0.9 ) * ( random() * 100 + 250 );
|
|
|
|
|
|
|
|
VectorScale( vel, -2.2, accel );
|
|
|
|
FX_AddSprite( hitpos, vel, qfalse, random() * 8 + 8, 0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.purpleParticleShader );
|
|
|
|
|
|
|
|
}*/
|
|
|
|
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound );
|
|
|
|
}
|
|
|
|
|
|
|
|
void FX_DisruptorBeamFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
|
|
|
|
{
|
|
|
|
refEntity_t beam;
|
|
|
|
sfxHandle_t sfx;
|
|
|
|
float size;
|
|
|
|
vec3_t velocity;
|
|
|
|
int sparks;
|
|
|
|
vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};
|
|
|
|
|
|
|
|
//vec3_t rgb3 = { 1.0, 1.0, 1.0 };
|
|
|
|
|
|
|
|
sfx = 0;
|
|
|
|
|
|
|
|
// Draw beam first.
|
|
|
|
memset( &beam, 0, sizeof( beam ) );
|
|
|
|
|
|
|
|
VectorCopy( startpos, beam.origin);
|
|
|
|
VectorCopy( endpos, beam.oldorigin );
|
|
|
|
beam.reType = RT_LINE;
|
|
|
|
if (empty)
|
|
|
|
{
|
|
|
|
beam.customShader = cgs.media.phaserEmptyShader;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
beam.customShader = cgs.media.disruptorBeam;
|
|
|
|
}
|
|
|
|
AxisClear( beam.axis );
|
|
|
|
beam.shaderRGBA[0] = 0xff;
|
|
|
|
beam.shaderRGBA[1] = 0xff;
|
|
|
|
beam.shaderRGBA[2] = 0xff;
|
|
|
|
beam.shaderRGBA[3] = 0xff;
|
|
|
|
if (empty)
|
|
|
|
{
|
|
|
|
beam.data.line.width = 1.0f + ( crandom() * 0.6f );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
beam.data.line.width = 1.5f + ( crandom() * 0.6f );
|
|
|
|
}
|
|
|
|
beam.data.line.stscale = 5.0;
|
|
|
|
trap_R_AddRefEntityToScene( &beam );
|
|
|
|
|
|
|
|
// Now draw the hit graphic
|
|
|
|
|
|
|
|
// no explosion at LG impact, it is added with the beam
|
|
|
|
|
|
|
|
if ( sfx )
|
|
|
|
{
|
|
|
|
Com_Printf("playing %s\n", "phaser sound");
|
|
|
|
trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// impact mark
|
|
|
|
//
|
|
|
|
if (impact)
|
|
|
|
{
|
|
|
|
if (!empty)
|
|
|
|
{ // normal.
|
|
|
|
CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse,
|
|
|
|
random() + 1, qfalse );
|
|
|
|
|
|
|
|
//VectorCopy( endpos, phaserFlare.worldCoord );
|
|
|
|
|
|
|
|
/*CG_InitLensFlare( endpos,
|
|
|
|
80,
|
|
|
|
80,
|
|
|
|
rgb,
|
|
|
|
1.2,
|
|
|
|
1.5,
|
|
|
|
1600,
|
|
|
|
200,
|
|
|
|
colorTable[CT_BLACK],
|
|
|
|
1600,
|
|
|
|
200,
|
|
|
|
80,
|
|
|
|
5,
|
|
|
|
qfalse,
|
|
|
|
5,
|
|
|
|
40,
|
|
|
|
qfalse,
|
|
|
|
qfalse,
|
|
|
|
qfalse,
|
|
|
|
1.0,
|
|
|
|
1.0,
|
|
|
|
200.0,
|
|
|
|
200.0,
|
|
|
|
200.0 );*/
|
|
|
|
|
|
|
|
//CG_InitLensFlare( endpos,
|
|
|
|
// 30, 30,
|
|
|
|
// rgb, 1.2, 2.0, 1600, 200,
|
|
|
|
// colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse,
|
|
|
|
// 0, 0, qfalse, qtrue,
|
|
|
|
// qfalse, 1.0, cg.time, 0, 0, 50);
|
|
|
|
|
|
|
|
//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
|
|
|
|
//CG_DrawLensFlare( &phaserFlare );
|
|
|
|
//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
|
|
|
|
|
|
|
|
//FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
|
|
|
|
//eh... looked bad :P
|
|
|
|
|
|
|
|
FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200,
|
|
|
|
cgs.media.sunnyFlareShader );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Wuss hit when empty.
|
|
|
|
FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200,
|
|
|
|
cgs.media.sunnyFlareShader );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// "Fun" sparks... Not when empty.
|
|
|
|
if ( spark && !empty)
|
|
|
|
{
|
2011-06-09 10:27:51 +00:00
|
|
|
sparks = (rand() & 1) + 1;
|
2011-06-01 12:20:56 +00:00
|
|
|
for(;sparks>0;sparks--)
|
|
|
|
{
|
|
|
|
size = 0.2f + (random() * 0.4);
|
|
|
|
FXE_Spray( normal, 200, 75, 0.8f, velocity);
|
|
|
|
if (rand() & LEF_USE_COLLISION)
|
|
|
|
{ // This spark bounces.
|
|
|
|
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
|
|
|
|
size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
|
|
|
|
size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|