mirror of
https://github.com/UberGames/RPG-X2.git
synced 2024-11-24 21:32:36 +00:00
357 lines
9.1 KiB
C
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 );
|
|
}
|
|
}
|