rpg-x2/cgame/fx_phaser.c
2011-06-09 12:27:51 +02:00

357 lines
9.1 KiB
C

//Phaser
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
FX_PhaserFire
-------------------------
*/
lensFlare_t phaserFlare = { {0.0,0.0,0.0},
20,
20,
{1.0, 0.7, 0.13},
1.2,
1.5,
20,
300,
{0.0, 0.0, 0.0},
20,
300,
80,
5,
qfalse,
5,
40,
qfalse,
qfalse,
qtrue,
1.0,
1.0,
1.0,
1.0,
1.0,
qtrue };
void FX_PhaserFire( 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.phaserShader;
}
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 = 2.0f + ( 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);
}
}
}
}
/*
-------------------------
FX_PhaserAltFire
-------------------------
*/
#define PHASER_ALT_CONE_LEN 256
void FX_PhaserAltFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
float scale = flrandom(13.0f, 17.0f), scale2 = flrandom(2.0f, 6.0f);
vec3_t vel, diff, end2;
int i = 0, sparks = 0;
refEntity_t beam;
vec3_t rgb = { 1,0.6,0.5}, rgb2={1,0.3,0};
float len;
int color;
VectorSubtract(end, start, diff);
len = VectorNormalize(diff);
color = 0xff * flrandom(0.75, 1.0);
if (empty)
{ // More faint and shaky line.
scale *= flrandom(0.25,0.75);
}
if (len > PHASER_ALT_CONE_LEN)
{ // Draw beam in two parts...
// Draw main beam first.
VectorMA(start, PHASER_ALT_CONE_LEN, diff, end2);
// Draw starting cone
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end2, beam.oldorigin );
beam.reType = RT_LINE2;
if (empty)
{
beam.customShader = cgs.media.phaserAltEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserAltShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// Draw big thick normal beam for the rest.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( end2, beam.oldorigin);
VectorCopy( end, beam.origin );
beam.reType = RT_LINE;
if (empty)
{
beam.customShader = cgs.media.phaserAltEmptyShader;
}
else
{
beam.customShader = cgs.media.phaserAltShader;
}
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// Draw beam core, all one bit.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = color*0.75f;
beam.shaderRGBA[1] = 0xff*0.5f;
beam.shaderRGBA[2] = 0xff*0.5f;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale2*0.2;
beam.data.line.width2 = scale2;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
}
else
{ // Draw beam in two parts...
// Draw beam first.
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserAltShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff;
beam.shaderRGBA[1] = 0xff*0.3;
beam.shaderRGBA[2] = 0;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale*0.1;
beam.data.line.width2 = scale;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
// just one beam is never enough
memset( &beam, 0, sizeof( beam ) );
VectorCopy( start, beam.origin);
VectorCopy( end, beam.oldorigin );
beam.reType = RT_LINE2;
beam.customShader = cgs.media.phaserShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = color*0.75f;
beam.shaderRGBA[1] = 0xff*0.5f;
beam.shaderRGBA[2] = 0xff*0.5f;
beam.shaderRGBA[3] = 0xff;
beam.data.line.width = scale2*0.2;
beam.data.line.width2 = scale2;
beam.data.line.stscale = 1.0;
trap_R_AddRefEntityToScene( &beam );
}
// Phaser beam
// FX_AddLine( start, end, 1.0f, scale, 0.0f, 0.9f, 0.9f, 2, cgs.media.phaserShader );
// FX_AddLine( start, end, 1.0f, scale * 0.5f, 0.0f, 0.8f, 0.8f, 2, cgs.media.phaserShader );
// Per frame impact mark
FX_AddQuad( end, normal, random() * 1.5 + 1.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.sparkShader );
FX_AddQuad( end, normal, random() * 5 + 2.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.yellowParticleShader );
// Multi frame impacts--never do this when it hits a player because it will just look stupid
if ( impact )
{
FX_AddQuad2( end, normal, random() * 2.0 + 5.0f, 2.5f, 0.6f, 0.0f, rgb, rgb2, 0.0f, 500 + random() * 200,
cgs.media.sunnyFlareShader );
CG_ImpactMark( cgs.media.scavMarkShader, end, normal, random()*360, 1,1,1,0.1, qfalse,
random() + 6.0, qfalse );
}
// "Fun" sparks
if ( spark )
{
// kef -- fixme. dunno what the deal is with this velocity vector
VectorClear(vel);
sparks = (rand() & 3) + 1;
// Set random starting pos...
end2[0] = flrandom(-1.0, 1.0) + end[0];
end2[1] = flrandom(-1.0, 1.0) + end[1];
end2[2] = flrandom(-1.0, 1.0) + end[2];
for( i = 0; i < sparks; i++ )
{
scale = 0.5f + (random() * 0.5);
FXE_Spray( normal, 200, 75, 0.8f, /*1024*/vel);
FX_AddTrail2( end2, vel, qfalse,
8.0f, -8.0f,
scale, -scale, 0.5f, 0.0f, rgb, rgb2, 0.4f, 500.0f, cgs.media.sparkShader );
}
VectorMA(end, -8, diff, end2);
// Add a hit sprite over everything...
memset( &beam, 0, sizeof( beam ) );
VectorCopy( end2, beam.origin);
beam.reType = RT_SPRITE;
beam.customShader = cgs.media.sunnyFlareShader;
AxisClear( beam.axis );
beam.shaderRGBA[0] = 0xff*1.0f;
beam.shaderRGBA[1] = 0xff*0.9f;
beam.shaderRGBA[2] = 0xff*0.8f;
beam.shaderRGBA[3] = 0xff;
beam.data.sprite.radius = random()*2.0 + 9.0;
trap_R_AddRefEntityToScene( &beam );
}
}