mirror of
https://github.com/UberGames/RPG-X2.git
synced 2024-11-28 23:22:00 +00:00
297 lines
8 KiB
C
297 lines
8 KiB
C
|
#include "cg_local.h"
|
||
|
#include "fx_local.h"
|
||
|
|
||
|
/*
|
||
|
-------------------------
|
||
|
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_DisruptorDischarge
|
||
|
|
||
|
Fun "crawling" electricity ( credit goes to Josh for this one )
|
||
|
-------------------------
|
||
|
*/
|
||
|
|
||
|
void FX_DisruptorDischarge( 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_DisruptorWeaponHitWall
|
||
|
|
||
|
Main fire impact
|
||
|
-------------------------
|
||
|
*/
|
||
|
|
||
|
#define NUM_DISCHARGES 6
|
||
|
#define DISCHARGE_DIST 8
|
||
|
#define DISCHARGE_SIDE_DIST 24
|
||
|
|
||
|
void FX_DisruptorWeaponHitWall( 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_DisruptorDischarge( 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)
|
||
|
{
|
||
|
sparks = (rand() & 1) + 1;
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|