mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-15 01:11:25 +00:00
a39565b783
... not quite content with where the project files lie but it is ok for now. ... compiling works fine so far (only tested mingw32 right now)
293 lines
7.1 KiB
C
293 lines
7.1 KiB
C
|
|
#include "cg_local.h"
|
|
#include "fx_local.h"
|
|
|
|
/*
|
|
-------------------------
|
|
SPTransporterLensFlares
|
|
|
|
TiM: Judging from the title,
|
|
you just KNOW it's mine ;)
|
|
|
|
Anyway, the point of this
|
|
function is to render 4
|
|
sprites and then scale + move
|
|
them in a way reminisicant
|
|
of ST: Voyager's transporter FX.
|
|
|
|
I wrote this instead of using the
|
|
already made FX spawning functions
|
|
because they don't let u track an origin.
|
|
To stop the particle
|
|
from rendering within the character, I'm going to
|
|
use the DEPTHHACK renderflag, the flag
|
|
originally used for the weapon models
|
|
in first-person mode. :)
|
|
|
|
Planned timing:
|
|
|
|
0 - 500 : Flare spawns, and scales up to it's main size (width parameter)
|
|
500 - 1500 : Flare moves up the height/2 of model (height parameter)
|
|
1500 - 2000 : Flare scales down and disappears ( width * 1.0 - (timeScale) )
|
|
-------------------------
|
|
*/
|
|
|
|
void FX_SPTransporterLensFlares( centity_t* cent, vec3_t headVector, int startTime ) {
|
|
refEntity_t flare;
|
|
trace_t tr;
|
|
int i;
|
|
int direction = 1;
|
|
int timeOffset = 0; //250 - time between first and second flares appearing;
|
|
float ratio;
|
|
float dlightRatio;
|
|
|
|
vec3_t origin, tempOrigin;
|
|
int width;
|
|
int height;
|
|
|
|
//Hrmm... we have a glitch lol. Since DEPTHHACK is on, the flare will be drawn
|
|
//from ANYWHERE IN THE LEVEL! O_o
|
|
//So.... uh, we'll do a trace between ourselves and the entity this is attached
|
|
//to, and if they can't see each other, screw it. :P
|
|
if ( cg.predictedPlayerState.clientNum != cent->currentState.clientNum ) {
|
|
CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL,
|
|
cent->lerpOrigin, cg.predictedPlayerState.clientNum, CONTENTS_SOLID );
|
|
if ( tr.fraction != 1 ) {
|
|
return;
|
|
}
|
|
}
|
|
/*else {
|
|
Com_Printf( "Origin: { %f, %f, %f }\n", cent->lerpOrigin[0], cent->lerpOrigin[1], cent->lerpOrigin[2] );
|
|
Com_Printf( "HeadVector: { %f, %f, %f }\n", headVector[0], headVector[1], headVector[2] );
|
|
return;
|
|
}*/
|
|
|
|
//calculate the necessary data we need to place the origin in the direct center of the model
|
|
|
|
memset( &flare, 0, sizeof( flare ) );
|
|
|
|
//Bah. I thought lerpOrigin was at the base of the feet. Turns out it's at the knees O_o
|
|
//This little hack should help that
|
|
VectorCopy( cent->lerpOrigin, tempOrigin );
|
|
tempOrigin[2] -= 24;
|
|
|
|
//If the distance means we're not lying down
|
|
if ( ( headVector[2] - tempOrigin[2] ) > 8 ) {
|
|
//find the average between our lerp origin and headVector to find the center
|
|
//VectorAdd( headVector, tempOrigin, origin );
|
|
//VectorScale( origin, 0.5, origin );
|
|
VectorAverage( headVector, tempOrigin, origin );
|
|
|
|
width = 30;
|
|
height = (headVector[2] - tempOrigin[2]) / 2;
|
|
}
|
|
else {
|
|
width = 30;
|
|
height = 4;
|
|
|
|
VectorCopy( cent->lerpOrigin, origin);
|
|
}
|
|
|
|
flare.reType = RT_SPRITE;
|
|
flare.shaderRGBA[0] = 0xff;
|
|
flare.shaderRGBA[1] = 0xff;
|
|
flare.shaderRGBA[2] = 0xff;
|
|
flare.shaderRGBA[3] = 0xff;
|
|
|
|
flare.data.sprite.rotation = 0;
|
|
flare.nonNormalizedAxes = qtrue; //needed for effective scaling
|
|
|
|
flare.renderfx |= RF_DEPTHHACK; //DEPTHHACK renders the element over everything else. Useful in this lens flare simulation case :)
|
|
|
|
//loop 4 times = 4 flares. :)
|
|
for (i = 0; i < 4; i++ ) {
|
|
VectorClear( flare.origin );
|
|
VectorCopy( origin, flare.origin);
|
|
|
|
//the first two flares are the main ones
|
|
if ( i < 2 ) {
|
|
flare.customShader = cgs.media.transport1Shader; //1
|
|
timeOffset = startTime;
|
|
}
|
|
else { // the second two spawn a little later
|
|
flare.customShader = cgs.media.transport2Shader;
|
|
timeOffset = startTime + 650; //750
|
|
}
|
|
|
|
//the second flare each round goes down instead of up
|
|
if ( i % 2 == 0)
|
|
direction = 1;
|
|
else
|
|
direction = -1;
|
|
|
|
//===========================
|
|
|
|
if ( cg.time > timeOffset + 2000 ) {
|
|
continue;
|
|
}
|
|
|
|
//Phase 1: flares get bigger
|
|
if ( cg.time < timeOffset + 500 ) {
|
|
ratio = ((float)(cg.time - timeOffset) * 0.002);
|
|
if (ratio < 0 )
|
|
ratio = 0.0f;
|
|
else if (ratio > 1 )
|
|
ratio = 1.0f;
|
|
|
|
flare.data.sprite.radius = (float)width * ratio;
|
|
/*if ( i ==0 )
|
|
Com_Printf( "Phase 1 Radius: %f\n", flare.data.sprite.radius );*/
|
|
}
|
|
//Phase 2: flares move up/down character
|
|
if ( ( cg.time < timeOffset + 1500 ) && ( cg.time >= timeOffset + 500 ) ) {
|
|
ratio = ( (float)(cg.time - (timeOffset + 500) ) * 0.001 );
|
|
if (ratio < 0 )
|
|
ratio = 0.0f;
|
|
else if (ratio > 1 )
|
|
ratio = 1.0f;
|
|
|
|
flare.data.sprite.radius = (float)width;
|
|
flare.origin[2] += (float)direction * (float)height * ratio;
|
|
/*if (i == 0 )
|
|
Com_Printf( "Phase 2 Location: %f\n", flare.origin[2] );*/
|
|
}
|
|
//Phase 3: flares get smaller
|
|
if ( ( cg.time < timeOffset + 2000 ) && ( cg.time >= timeOffset + 1500 ) ) {
|
|
ratio = 1.0f - (float)(cg.time - ( timeOffset + 1500 ) ) * 0,002;
|
|
if (ratio < 0 )
|
|
ratio = 0.0f;
|
|
else if (ratio > 1 )
|
|
ratio = 1.0f;
|
|
|
|
flare.origin[2] += ((float)height * (float)direction);
|
|
flare.data.sprite.radius = (float)width * ratio;
|
|
/*if ( i == 0 )
|
|
Com_Printf( "Phase 3 Radius: %f\n", flare.data.sprite.radius );*/
|
|
}
|
|
|
|
trap_R_AddRefEntityToScene( &flare );
|
|
}
|
|
|
|
//dynamic light calculation
|
|
if ( cg.time < ( startTime + 2000 ) ) {
|
|
dlightRatio = (float)( cg.time - startTime ) * 0,0005;
|
|
}
|
|
else {
|
|
dlightRatio = 1.0f - (float)( cg.time - ( startTime + 2000 ) ) * 0,0005;
|
|
}
|
|
|
|
//dynamic light FX
|
|
trap_R_AddLightToScene( origin, 80.0f * dlightRatio, 0.345, 0.624, 0.835 );
|
|
}
|
|
|
|
/*
|
|
-------------------------
|
|
TransporterParticle
|
|
-------------------------
|
|
*/
|
|
|
|
qboolean TransporterParticle( localEntity_t *le)
|
|
{
|
|
vec3_t org, velocity = { 0, 0, 68 };
|
|
vec3_t accel = { 0, 0, -12 };
|
|
float scale, dscale;
|
|
qhandle_t shader;
|
|
|
|
VectorCopy( le->refEntity.origin, org );
|
|
org[2] += 0;//38;
|
|
|
|
shader = ( le->data.spawner.dir[0] == 0 ) ? cgs.media.trans1Shader : cgs.media.trans2Shader;
|
|
scale = ( le->data.spawner.dir[0] == 0 ) ? 2.0 : 4.0;
|
|
dscale = ( le->data.spawner.dir[0] == 0 ) ? 4.0 : 24.0;
|
|
|
|
le->data.spawner.dir[0]++;
|
|
|
|
FX_AddSprite( org,
|
|
velocity,
|
|
qfalse,
|
|
scale,
|
|
dscale,
|
|
1.0f,
|
|
0.0f,
|
|
0,
|
|
0.0f,
|
|
450.0f,
|
|
shader );
|
|
|
|
VectorScale( velocity, -1, velocity );
|
|
VectorScale( accel, -1, accel );
|
|
|
|
FX_AddSprite( org,
|
|
velocity,
|
|
qfalse,
|
|
scale,
|
|
dscale,
|
|
1.0f,
|
|
0.0f,
|
|
0,
|
|
0.0f,
|
|
450.0f,
|
|
shader );
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
-------------------------
|
|
TransporterPad
|
|
-------------------------
|
|
*/
|
|
|
|
qboolean TransporterPad( localEntity_t *le)
|
|
{
|
|
vec3_t org;
|
|
vec3_t up = {0,0,1};
|
|
float scale, dscale;
|
|
qhandle_t shader;
|
|
|
|
VectorCopy( le->refEntity.origin, org );
|
|
org[2] -= 3;
|
|
|
|
shader = cgs.media.trans1Shader;
|
|
scale = 20.0;
|
|
dscale = 2.0;
|
|
|
|
FX_AddQuad( org,
|
|
up,
|
|
scale,
|
|
dscale,
|
|
1.0f,
|
|
0.0f,
|
|
0,
|
|
950.0f,
|
|
shader );
|
|
return qtrue;
|
|
}
|
|
|
|
/*
|
|
-------------------------
|
|
FX_Transporter
|
|
-------------------------
|
|
*/
|
|
|
|
void FX_Transporter( vec3_t origin )
|
|
{
|
|
vec3_t up = {0,0,1};
|
|
|
|
FX_AddSpawner( origin, up, NULL, NULL, qfalse, 0, 0, 200, TransporterParticle, 0 );
|
|
// trap_S_StartSound( origin, NULL, CHAN_AUTO, cgs.media.teleInSound );
|
|
}
|
|
|
|
/*
|
|
-------------------------
|
|
FX_TransporterPad
|
|
-------------------------
|
|
*/
|
|
|
|
void FX_TransporterPad( vec3_t origin )
|
|
{
|
|
vec3_t up = {0,0,1};
|
|
|
|
FX_AddSpawner( origin, up, NULL, NULL, qfalse, 1000, 0, 0, TransporterPad, 0 );
|
|
}
|
|
|