277 lines
6.8 KiB
C
277 lines
6.8 KiB
C
#include "cg_local.h"
|
|
#include "fx_local.h"
|
|
|
|
|
|
#define SCAV_SPIN 0.3
|
|
|
|
void FX_ScavengerProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
|
|
{
|
|
vec3_t forward;
|
|
qboolean fired_from_NPC = qfalse; // Always
|
|
|
|
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0 )
|
|
forward[2] = 1;
|
|
|
|
// The effect you'd see from first person looks horrible from third person..or when shot by an NPC,
|
|
// so we'll just tone down the effect so it's not so horrible. :)
|
|
if ( fired_from_NPC )
|
|
{
|
|
// Energy glow
|
|
FX_AddSprite( cent->lerpOrigin,
|
|
NULL, qfalse,
|
|
8.0f + random() * 8.0f, 0.0f,
|
|
0.7f, 0.0f,
|
|
random()*360, 0.0f,
|
|
1.0f,
|
|
cgs.media.tetrionFlareShader );
|
|
|
|
// Spinning projectile core
|
|
FX_AddSprite( cent->lerpOrigin,
|
|
NULL, qfalse,
|
|
8.0f + random() * 10.0f, 0.0f,
|
|
1.0f, 0.0f,
|
|
cg.time * SCAV_SPIN, 0.0f,
|
|
1.0f,
|
|
cgs.media.redFlareShader );
|
|
|
|
// leave a cool tail
|
|
FX_AddTrail( cent->lerpOrigin,
|
|
forward, qfalse,
|
|
16, 0,
|
|
1.0f, 0.0f,
|
|
0.8f, 0.0f,
|
|
0,
|
|
1,
|
|
cgs.media.tetrionTrail2Shader );
|
|
}
|
|
else
|
|
{
|
|
// Energy glow
|
|
FX_AddSprite( cent->lerpOrigin,
|
|
NULL, qfalse,
|
|
16.0f + random() * 16.0f, 0.0f,
|
|
0.5f, 0.0f,
|
|
random()*360, 0.0f,
|
|
1.0f,
|
|
cgs.media.tetrionFlareShader );
|
|
|
|
// Spinning projectile
|
|
FX_AddSprite( cent->lerpOrigin,
|
|
NULL, qfalse,
|
|
4.0f + random() * 10.0f, 0.0f,
|
|
0.6f, 0.0f,
|
|
cg.time * SCAV_SPIN, 0.0f,
|
|
1.0f,
|
|
cgs.media.redFlareShader );
|
|
|
|
// leave a cool tail
|
|
FX_AddTrail( cent->lerpOrigin,
|
|
forward, qfalse,
|
|
64, 0,
|
|
1.4f, 0.0f,
|
|
0.6f, 0.0f,
|
|
0,
|
|
1,
|
|
cgs.media.tetrionTrail2Shader );
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
-------------------------
|
|
FX_ScavengerAltFireThink
|
|
-------------------------
|
|
*/
|
|
#define SCAV_TRAIL_SPACING 12
|
|
|
|
void FX_ScavengerAltFireThink( centity_t *cent, const struct weaponInfo_s *weapon )
|
|
{
|
|
vec3_t diff;
|
|
float len;
|
|
|
|
// Make a trail that's reasonably consistent and not so much based on frame rate.
|
|
if (cent->thinkFlag)
|
|
{
|
|
VectorSubtract( cent->lerpOrigin, cent->beamEnd, diff );
|
|
}
|
|
else
|
|
{
|
|
VectorSubtract( cent->lerpOrigin, cent->currentState.origin2, diff );
|
|
}
|
|
|
|
len = VectorNormalize( diff );
|
|
|
|
if ( len > SCAV_TRAIL_SPACING )
|
|
{
|
|
vec3_t origin;
|
|
int i;
|
|
float scale;
|
|
|
|
for ( i = 0 ; i < len; i += SCAV_TRAIL_SPACING )
|
|
{
|
|
// Calc the right spot along the trail
|
|
VectorMA( cent->lerpOrigin, -i, diff, origin );
|
|
scale = 18.0f + (random()*5.0f);
|
|
FX_AddSprite( origin,
|
|
NULL, qfalse,
|
|
scale, -8.75,
|
|
0.4f, 0.0f,
|
|
random() * 360, 0.0f,
|
|
250.0f,
|
|
cgs.media.scavengerAltShader );
|
|
}
|
|
|
|
// Stash the current position
|
|
VectorCopy( cent->lerpOrigin, cent->beamEnd);
|
|
cent->thinkFlag = 1;
|
|
}
|
|
|
|
// Glowing bit
|
|
FX_AddSprite( cent->lerpOrigin,
|
|
NULL, qfalse,
|
|
24.0f + ( random() * 16.0f ), 0.0f,
|
|
1.0f, 0.0f,
|
|
0, 0.0f,
|
|
1.0f,
|
|
cgs.media.tetrionFlareShader );
|
|
}
|
|
|
|
|
|
/*
|
|
-------------------------
|
|
FX_ScavengerWeaponHitWall
|
|
-------------------------
|
|
*/
|
|
void FX_ScavengerWeaponHitWall( vec3_t origin, vec3_t normal, qboolean fired_by_NPC )
|
|
{
|
|
weaponInfo_t *weaponInfo = &cg_weapons[WP_SCAVENGER_RIFLE];
|
|
|
|
// Tone down when shot by an NPC
|
|
// FIXME: is this really a good idea?
|
|
if ( fired_by_NPC )
|
|
{
|
|
// Expanding shock ring
|
|
FX_AddQuad( origin, normal,
|
|
0.5f, 6.4f,
|
|
0.8, 0.0,
|
|
random() * 360.0f,
|
|
200,
|
|
cgs.media.redRingShader );
|
|
|
|
// Impact core
|
|
FX_AddQuad( origin, normal,
|
|
12.0f + ( random() * 8.0f ), 3.2f,
|
|
0.6f, 0.0f,
|
|
cg.time * SCAV_SPIN,
|
|
100,
|
|
cgs.media.redFlareShader );
|
|
}
|
|
else
|
|
{
|
|
// Expanding shock ring
|
|
FX_AddQuad( origin, normal,
|
|
8.0f, 12.8f,
|
|
1.0, 0.0,
|
|
random() * 360.0f,
|
|
200,
|
|
cgs.media.redRingShader );
|
|
|
|
// Impact core
|
|
FX_AddQuad( origin, normal,
|
|
24.0f + ( random() * 16.0f ), 6.4f,
|
|
0.8f, 0.0f,
|
|
cg.time * SCAV_SPIN,
|
|
100,
|
|
cgs.media.redFlareShader );
|
|
}
|
|
|
|
//Sound
|
|
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
|
|
|
|
CG_ImpactMark( cgs.media.scavMarkShader, origin, normal, random()*360, 1,1,1,0.2, qfalse, random() + 5.5f, qfalse );
|
|
}
|
|
|
|
|
|
/*
|
|
-------------------------
|
|
FX_ScavengerWeaponHitPlayer
|
|
-------------------------
|
|
*/
|
|
void FX_ScavengerWeaponHitPlayer( vec3_t origin, vec3_t normal, qboolean fired_by_NPC )
|
|
{
|
|
if ( fired_by_NPC )
|
|
{
|
|
// Smaller expanding shock ring
|
|
FX_AddQuad( origin, normal,
|
|
0.5f, 32.0f,
|
|
0.8, 0.0,
|
|
random() * 360.0f,
|
|
125,
|
|
cgs.media.redRingShader );
|
|
}
|
|
else
|
|
{
|
|
// Expanding shock ring
|
|
FX_AddQuad( origin, normal,
|
|
1.0f, 64.0f,
|
|
0.8, 0.0,
|
|
random() * 360.0f,
|
|
125,
|
|
cgs.media.redRingShader );
|
|
}
|
|
|
|
//Sound
|
|
// cgi_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cg_weapons[WP_SCAVENGER_RIFLE].missileHitSound );
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
-------------------------
|
|
FX_Scavenger_Alt_Explode
|
|
-------------------------
|
|
*/
|
|
void FX_ScavengerAltExplode( vec3_t origin, vec3_t dir )
|
|
{
|
|
// FXCylinder *fx2;
|
|
localEntity_t *le;
|
|
vec3_t direction, org;
|
|
int i;
|
|
weaponInfo_t *weaponInfo = &cg_weapons[WP_SCAVENGER_RIFLE];
|
|
|
|
//Orient the explosions to face the camera
|
|
VectorSubtract( cg.refdef.vieworg, origin, direction );
|
|
VectorNormalize( direction );
|
|
|
|
VectorMA( origin, 12, direction, org );
|
|
// Add an explosion and tag a light to it
|
|
le = CG_MakeExplosion2( org, direction, cgs.media.explosionModel, 5, cgs.media.scavExplosionSlowShader, 675, qfalse, 1.0f + (random()*0.5f), LEF_NONE);
|
|
le->light = 150;
|
|
le->refEntity.renderfx |= RF_NOSHADOW;
|
|
VectorSet( le->lightColor, 1.0f, 0.6f, 0.6f );
|
|
|
|
VectorSet( org, (org[0] + crandom() * 8), (org[1] + crandom() * 8), (org[2] + crandom() * 8) );
|
|
CG_MakeExplosion2( org, direction, cgs.media.explosionModel, 5, cgs.media.scavExplosionFastShader, 375, qfalse, 0.7f + (random()*0.5f), LEF_NONE);
|
|
|
|
//Sound
|
|
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->altHitSound );
|
|
|
|
CG_ImpactMark( cgs.media.compressionMarkShader, origin, dir, random()*360, 1,1,1,0.2, qfalse,
|
|
random() * 6 + 20, qfalse );
|
|
|
|
// Always orient horizontally
|
|
VectorSet ( direction, 0,0,1 );
|
|
|
|
le = FX_AddCylinder( origin, direction, 4, 0, 20, 210, 14, 140, 1.0, 0.0, 600, cgs.media.redRing2Shader, 1.5 );
|
|
le->refEntity.data.cylinder.wrap = qtrue;
|
|
le->refEntity.data.cylinder.stscale = 6;
|
|
|
|
for (i = 0; i < 6; i++)
|
|
{
|
|
vec3_t velocity;
|
|
|
|
FXE_Spray( dir, 300, 175, 0.8f, velocity);
|
|
FX_AddTrail( origin, velocity, qtrue, 12.0f, -12.0f,
|
|
2, -2, 1.0f, 1.0f, 0.2f, 1000.0f, cgs.media.tetrionTrail2Shader);
|
|
}
|
|
}
|