250 lines
6.3 KiB
C
250 lines
6.3 KiB
C
#include "cg_local.h"
|
|
#include "fx_local.h"
|
|
|
|
|
|
|
|
//
|
|
// detpack
|
|
//
|
|
|
|
#define NUM_RING_SHADERS 6
|
|
|
|
qboolean DetpackAftereffect(localEntity_t *le)
|
|
{
|
|
localEntity_t *cyl = NULL;
|
|
qhandle_t shader = cgs.media.phaserShader;
|
|
qhandle_t slowRingShaders[NUM_RING_SHADERS];
|
|
float percentLife = 1.0 - (le->endTime - cg.time)*le->lifeRate;
|
|
float alpha = 0.6 - (0.6*percentLife*percentLife);
|
|
// data for shell
|
|
float shellLife = percentLife + .2;
|
|
float height1 = 20 + (percentLife * 150);
|
|
float height2 =(50*percentLife);
|
|
float scale1 = 40 + (percentLife * 1500);
|
|
float scale2 = 20 + (percentLife * 1200);
|
|
// data for flat energy rings
|
|
float ringLife = percentLife + .5;
|
|
float scale3 = 200 + (percentLife * 3400);
|
|
float scale4 = 100 + (percentLife * 3000);
|
|
float scale5 = 20 + (percentLife * 1000);
|
|
float scale6 = 10 + (percentLife * 200);
|
|
float ringAlpha = 0.6 - (0.6*ringLife*ringLife);
|
|
vec3_t up = {0,0,1},origin1;
|
|
|
|
|
|
slowRingShaders[0] = cgs.media.testDetpackRingShader1;
|
|
slowRingShaders[1] = cgs.media.testDetpackRingShader2;
|
|
slowRingShaders[2] = cgs.media.testDetpackRingShader3;
|
|
slowRingShaders[3] = cgs.media.testDetpackRingShader4;
|
|
slowRingShaders[4] = cgs.media.testDetpackRingShader5;
|
|
slowRingShaders[5] = cgs.media.testDetpackRingShader6;
|
|
|
|
// slower, inner ring
|
|
VectorCopy(le->refEntity.origin, origin1);
|
|
if (NUM_RING_SHADERS == le->data.spawner.data1)
|
|
{
|
|
le->data.spawner.data1 = 0;
|
|
}
|
|
else if (le->data.spawner.data1 < 0)
|
|
{
|
|
le->data.spawner.data1 = 0;
|
|
}
|
|
shader = slowRingShaders[le->data.spawner.data1++];
|
|
// fast, outer ring
|
|
cyl = FX_AddCylinder( origin1,
|
|
up,
|
|
0.1,// height,
|
|
0,// dheight,
|
|
scale5,// scale,
|
|
0,// dscale,
|
|
scale6,// scale2,
|
|
0,// dscale2,
|
|
ringAlpha,// startalpha,
|
|
0.0,// endalpha,
|
|
500,// killTime,
|
|
shader,
|
|
15);// bias );
|
|
cyl->leFlags |= LEF_ONE_FRAME;
|
|
|
|
if (shellLife <= 1.0f)
|
|
{
|
|
origin1[2] += height2;
|
|
shader = cgs.media.phaserShader;
|
|
cyl = FX_AddCylinder( origin1,
|
|
up,
|
|
height1,// height,
|
|
0,// dheight,
|
|
scale1,// scale,
|
|
0,// dscale,
|
|
scale2,// scale2,
|
|
0,// dscale2,
|
|
alpha,// startalpha,
|
|
0.0,// endalpha,
|
|
500,// killTime,
|
|
shader,
|
|
15);// bias );
|
|
cyl->leFlags |= LEF_ONE_FRAME;
|
|
|
|
cyl = FX_AddCylinder( le->refEntity.origin,
|
|
up,
|
|
height2, // height,
|
|
0, // dheight,
|
|
scale1, // scale,
|
|
0, // dscale,
|
|
scale1, // scale2,
|
|
0, // dscale2,
|
|
alpha, // startalpha,
|
|
0.0, // endalpha,
|
|
500, // killTime,
|
|
shader,
|
|
15); // bias );
|
|
cyl->leFlags |= LEF_ONE_FRAME;
|
|
}
|
|
// flat energy wave thingy
|
|
if (ringLife <= 1.0f)
|
|
{
|
|
shader = cgs.media.testDetpackShader3;
|
|
VectorCopy(le->refEntity.origin, origin1);
|
|
// fast, outer ring
|
|
|
|
cyl = FX_AddCylinder( origin1,
|
|
up,
|
|
0.1,// height,
|
|
0,// dheight,
|
|
scale3,// scale,
|
|
0,// dscale,
|
|
scale4,// scale2,
|
|
0,// dscale2,
|
|
ringAlpha,// startalpha,
|
|
0.0,// endalpha,
|
|
500,// killTime,
|
|
shader,
|
|
15);// bias );
|
|
cyl->leFlags |= LEF_ONE_FRAME;
|
|
}
|
|
return qtrue;
|
|
}
|
|
|
|
|
|
void FX_Detpack(vec3_t origin)
|
|
{
|
|
localEntity_t *le;
|
|
vec3_t direction, org, vel, norm = {0,0,1};
|
|
int i;
|
|
|
|
VectorCopy( norm, direction);
|
|
|
|
// Add an explosion and tag a light to it
|
|
le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, (qhandle_t)NULL, 250, qfalse, 100.0f, LEF_FADE_RGB);
|
|
le->light = 300;
|
|
le->refEntity.renderfx |= RF_NOSHADOW;
|
|
|
|
VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );
|
|
|
|
// Ground ring
|
|
// FX_AddQuad( origin, norm, 5, 150, 1.0, 0.0, random() * 360, 600, cgs.media.bigShockShader );
|
|
// Flare
|
|
VectorMA( origin, 12, direction, org );
|
|
FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 500, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );
|
|
|
|
for (i = 0; i < 12; i++)
|
|
{
|
|
float width, length;
|
|
FXE_Spray( norm, 470, 325, 0.5f, vel);
|
|
length = 50.0 + random() * 12;
|
|
width = 1.5 + random() * 2;
|
|
FX_AddTrail( origin, vel, qtrue, length, -length, width, -width,
|
|
1.0f, 1.0f, 0.5f, 1000.0f, cgs.media.orangeTrailShader);
|
|
}
|
|
|
|
// trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.detpackExplodeSound );
|
|
|
|
// Smoke and impact
|
|
CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse,
|
|
random() * 16 + 48, qfalse );
|
|
|
|
// mondo explosion shock wave cloud thing
|
|
le = FX_AddSpawner( origin, norm, NULL, NULL, qfalse, 0,
|
|
0, 1500, DetpackAftereffect, 10 );
|
|
le->data.spawner.data1 = 0;
|
|
|
|
// shake absolutely _everyone_
|
|
CG_ExplosionEffects(origin, 5.0f, 8092);
|
|
}
|
|
|
|
|
|
//
|
|
// portable shield
|
|
//
|
|
|
|
|
|
void FX_DrawPortableShield(centity_t *cent)
|
|
{
|
|
int xaxis, height, posWidth, negWidth, team;
|
|
vec3_t start, end, normal;
|
|
float halfHeight;
|
|
localEntity_t *le;
|
|
qhandle_t shader;
|
|
|
|
if (cent->currentState.eFlags & EF_NODRAW)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// decode the data stored in time2
|
|
xaxis = ((cent->currentState.time2 >> 24) & 1);
|
|
height = ((cent->currentState.time2 >> 16) & 255);
|
|
posWidth = ((cent->currentState.time2 >> 8) & 255);
|
|
negWidth = (cent->currentState.time2 & 255);
|
|
|
|
team = (cent->currentState.otherEntityNum2);
|
|
halfHeight = (float)height * .5;
|
|
|
|
VectorCopy(cent->lerpOrigin, start);
|
|
VectorCopy(cent->lerpOrigin, end);
|
|
start[2] += halfHeight;
|
|
end[2] += halfHeight;
|
|
|
|
VectorClear(normal);
|
|
if (xaxis) // drawing along x-axis
|
|
{
|
|
start[0] -= negWidth;
|
|
end[0] += posWidth;
|
|
normal[1] = 1;
|
|
}
|
|
else
|
|
{
|
|
start[1] -= negWidth;
|
|
end[1] += posWidth;
|
|
normal[0] = 1;
|
|
}
|
|
// draw a rectangle o' shieldness
|
|
|
|
if (team == TEAM_RED)
|
|
{
|
|
if (cent->currentState.eFlags & EF_ITEMPLACEHOLDER)
|
|
{ // Damaged.
|
|
shader = cgs.media.shieldDamageShaderRed;
|
|
}
|
|
else
|
|
{
|
|
shader = cgs.media.shieldActivateShaderRed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (cent->currentState.eFlags & EF_ITEMPLACEHOLDER)
|
|
{ // Damaged.
|
|
shader = cgs.media.shieldDamageShaderBlue;
|
|
}
|
|
else
|
|
{
|
|
shader = cgs.media.shieldActivateShaderBlue;
|
|
}
|
|
}
|
|
|
|
le = FX_AddOrientedLine(start, end, normal, 1.0f, height, 0.0f, 1.0f, 1.0f, 50.0, shader);
|
|
// le->leFlags |= LEF_ONE_FRAME;
|
|
}
|
|
|
|
|