2001-12-31 16:16:59 +00:00
//-----------------------------------------------------------------------------
//
// $Id$
//
//-----------------------------------------------------------------------------
//
2001-12-31 16:28:42 +00:00
// $Log$
2006-04-14 18:16:31 +00:00
// Revision 1.21 2006/04/14 18:16:31 makro
// no message
//
2004-01-26 21:26:09 +00:00
// Revision 1.20 2004/01/26 21:26:08 makro
// no message
//
2003-07-30 16:05:47 +00:00
// Revision 1.19 2003/07/30 16:05:46 makro
// no message
//
2003-03-29 18:53:41 +00:00
// Revision 1.18 2003/03/29 18:53:41 jbravo
// Fixed ammo bug when dropping bandolier. Added color to more errormessages
//
2002-12-02 19:52:05 +00:00
// Revision 1.17 2002/12/02 19:52:05 niceass
// water pressure & shell ejection stuff
//
2002-08-25 23:20:18 +00:00
// Revision 1.16 2002/08/25 23:20:18 niceass
// steam looks/acts better
//
2002-08-22 07:06:37 +00:00
// Revision 1.15 2002/08/22 07:06:37 niceass
// small change to particle reflection
//
2002-08-21 03:53:09 +00:00
// Revision 1.14 2002/08/21 03:53:09 niceass
// enhanced particle system that allows particle reflection
//
2002-08-21 03:45:36 +00:00
// Revision 1.13 2002/08/21 03:45:36 niceass
// enhanced particle system that supports bouncing
//
2002-06-16 20:06:15 +00:00
// Revision 1.12 2002/06/16 20:06:13 jbravo
// Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap"
//
2002-06-09 05:16:58 +00:00
// Revision 1.11 2002/06/09 05:15:12 niceass
// pressure change
//
2002-06-06 01:54:26 +00:00
// Revision 1.10 2002/06/06 01:53:26 niceass
// pressure change
//
2002-05-26 05:14:14 +00:00
// Revision 1.9 2002/05/26 05:14:05 niceass
// pressure stuff
//
2002-04-29 06:13:31 +00:00
// Revision 1.8 2002/04/29 06:13:31 niceass
// small particle stuff
//
2002-04-23 06:06:19 +00:00
// Revision 1.7 2002/04/23 06:06:19 niceass
// pressure particles
//
2002-01-11 19:48:33 +00:00
// Revision 1.6 2002/01/11 19:48:29 jbravo
// Formatted the source in non DOS format.
//
2001-12-31 16:28:42 +00:00
// Revision 1.5 2001/12/31 16:28:41 jbravo
// I made a Booboo with the Log tag.
//
2001-12-31 16:16:59 +00:00
//
//-----------------------------------------------------------------------------
2001-05-06 20:50:27 +00:00
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_marks.c -- wall marks
# include "cg_local.h"
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
MARK POLYS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
markPoly_t cg_activeMarkPolys ; // double linked list
markPoly_t * cg_freeMarkPolys ; // single linked list
markPoly_t cg_markPolys [ MAX_MARK_POLYS ] ;
static int markTotal ;
2001-05-06 20:50:27 +00:00
/*
= = = = = = = = = = = = = = = = = = =
CG_InitMarkPolys
This is called at startup and for tournement restarts
= = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_InitMarkPolys ( void )
{
int i ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
memset ( cg_markPolys , 0 , sizeof ( cg_markPolys ) ) ;
2001-05-06 20:50:27 +00:00
cg_activeMarkPolys . nextMark = & cg_activeMarkPolys ;
cg_activeMarkPolys . prevMark = & cg_activeMarkPolys ;
cg_freeMarkPolys = cg_markPolys ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < MAX_MARK_POLYS - 1 ; i + + ) {
cg_markPolys [ i ] . nextMark = & cg_markPolys [ i + 1 ] ;
2001-05-06 20:50:27 +00:00
}
}
/*
= = = = = = = = = = = = = = = = = =
CG_FreeMarkPoly
= = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_FreeMarkPoly ( markPoly_t * le )
{
if ( ! le - > prevMark ) {
CG_Error ( " CG_FreeLocalEntity: not active " ) ;
2001-05-06 20:50:27 +00:00
}
// remove from the doubly linked active list
le - > prevMark - > nextMark = le - > nextMark ;
le - > nextMark - > prevMark = le - > prevMark ;
// the free list is only singly linked
le - > nextMark = cg_freeMarkPolys ;
cg_freeMarkPolys = le ;
}
/*
= = = = = = = = = = = = = = = = = = =
CG_AllocMark
Will allways succeed , even if it requires freeing an old active mark
= = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
markPoly_t * CG_AllocMark ( void )
{
markPoly_t * le ;
2001-05-06 20:50:27 +00:00
int time ;
2002-06-16 20:06:15 +00:00
if ( ! cg_freeMarkPolys ) {
2001-05-06 20:50:27 +00:00
// no free entities, so free the one at the end of the chain
// remove the oldest active entity
time = cg_activeMarkPolys . prevMark - > time ;
while ( cg_activeMarkPolys . prevMark & & time = = cg_activeMarkPolys . prevMark - > time ) {
2002-06-16 20:06:15 +00:00
CG_FreeMarkPoly ( cg_activeMarkPolys . prevMark ) ;
2001-05-06 20:50:27 +00:00
}
}
le = cg_freeMarkPolys ;
cg_freeMarkPolys = cg_freeMarkPolys - > nextMark ;
2002-06-16 20:06:15 +00:00
memset ( le , 0 , sizeof ( * le ) ) ;
2001-05-06 20:50:27 +00:00
// link into the active list
le - > nextMark = cg_activeMarkPolys . nextMark ;
le - > prevMark = & cg_activeMarkPolys ;
cg_activeMarkPolys . nextMark - > prevMark = le ;
cg_activeMarkPolys . nextMark = le ;
return le ;
}
/*
= = = = = = = = = = = = = = = = =
CG_ImpactMark
origin should be a point within a unit of the plane
dir should be the plane normal
temporary marks will not be stored or randomly oriented , but immediately
passed to the renderer .
= = = = = = = = = = = = = = = = =
*/
# define MAX_MARK_FRAGMENTS 128
# define MAX_MARK_POINTS 384
2002-06-16 20:06:15 +00:00
void CG_ImpactMark ( qhandle_t markShader , const vec3_t origin , const vec3_t dir ,
float orientation , float red , float green , float blue , float alpha ,
qboolean alphaFade , float radius , qboolean temporary )
{
vec3_t axis [ 3 ] ;
float texCoordScale ;
vec3_t originalPoints [ 4 ] ;
byte colors [ 4 ] ;
int i , j ;
int numFragments ;
markFragment_t markFragments [ MAX_MARK_FRAGMENTS ] , * mf ;
vec3_t markPoints [ MAX_MARK_POINTS ] ;
vec3_t projection ;
if ( ! cg_addMarks . integer ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
if ( radius < = 0 ) {
CG_Error ( " CG_ImpactMark called with <= 0 radius " ) ;
2001-05-06 20:50:27 +00:00
}
//if ( markTotal >= MAX_MARK_POLYS ) {
2002-06-16 20:06:15 +00:00
// return;
2001-05-06 20:50:27 +00:00
//}
// create the texture axis
2002-06-16 20:06:15 +00:00
VectorNormalize2 ( dir , axis [ 0 ] ) ;
PerpendicularVector ( axis [ 1 ] , axis [ 0 ] ) ;
RotatePointAroundVector ( axis [ 2 ] , axis [ 0 ] , axis [ 1 ] , orientation ) ;
CrossProduct ( axis [ 0 ] , axis [ 2 ] , axis [ 1 ] ) ;
2001-05-06 20:50:27 +00:00
texCoordScale = 0.5 * 1.0 / radius ;
// create the full polygon
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < 3 ; i + + ) {
2001-05-06 20:50:27 +00:00
originalPoints [ 0 ] [ i ] = origin [ i ] - radius * axis [ 1 ] [ i ] - radius * axis [ 2 ] [ i ] ;
originalPoints [ 1 ] [ i ] = origin [ i ] + radius * axis [ 1 ] [ i ] - radius * axis [ 2 ] [ i ] ;
originalPoints [ 2 ] [ i ] = origin [ i ] + radius * axis [ 1 ] [ i ] + radius * axis [ 2 ] [ i ] ;
originalPoints [ 3 ] [ i ] = origin [ i ] - radius * axis [ 1 ] [ i ] + radius * axis [ 2 ] [ i ] ;
}
// get the fragments
2002-06-16 20:06:15 +00:00
VectorScale ( dir , - 20 , projection ) ;
numFragments = trap_CM_MarkFragments ( 4 , ( void * ) originalPoints ,
projection , MAX_MARK_POINTS , markPoints [ 0 ] ,
MAX_MARK_FRAGMENTS , markFragments ) ;
2001-05-06 20:50:27 +00:00
colors [ 0 ] = red * 255 ;
colors [ 1 ] = green * 255 ;
colors [ 2 ] = blue * 255 ;
colors [ 3 ] = alpha * 255 ;
2002-06-16 20:06:15 +00:00
for ( i = 0 , mf = markFragments ; i < numFragments ; i + + , mf + + ) {
polyVert_t * v ;
polyVert_t verts [ MAX_VERTS_ON_POLY ] ;
markPoly_t * mark ;
2001-05-06 20:50:27 +00:00
// we have an upper limit on the complexity of polygons
// that we store persistantly
2002-06-16 20:06:15 +00:00
if ( mf - > numPoints > MAX_VERTS_ON_POLY ) {
2001-05-06 20:50:27 +00:00
mf - > numPoints = MAX_VERTS_ON_POLY ;
}
2002-06-16 20:06:15 +00:00
for ( j = 0 , v = verts ; j < mf - > numPoints ; j + + , v + + ) {
vec3_t delta ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
VectorCopy ( markPoints [ mf - > firstPoint + j ] , v - > xyz ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
VectorSubtract ( v - > xyz , origin , delta ) ;
v - > st [ 0 ] = 0.5 + DotProduct ( delta , axis [ 1 ] ) * texCoordScale ;
v - > st [ 1 ] = 0.5 + DotProduct ( delta , axis [ 2 ] ) * texCoordScale ;
* ( int * ) v - > modulate = * ( int * ) colors ;
2001-05-06 20:50:27 +00:00
}
// if it is a temporary (shadow) mark, add it immediately and forget about it
2002-06-16 20:06:15 +00:00
if ( temporary ) {
trap_R_AddPolyToScene ( markShader , mf - > numPoints , verts ) ;
2001-05-06 20:50:27 +00:00
continue ;
}
// otherwise save it persistantly
mark = CG_AllocMark ( ) ;
mark - > time = cg . time ;
mark - > alphaFade = alphaFade ;
mark - > markShader = markShader ;
mark - > poly . numVerts = mf - > numPoints ;
mark - > color [ 0 ] = red ;
mark - > color [ 1 ] = green ;
mark - > color [ 2 ] = blue ;
mark - > color [ 3 ] = alpha ;
2002-06-16 20:06:15 +00:00
memcpy ( mark - > verts , verts , mf - > numPoints * sizeof ( verts [ 0 ] ) ) ;
2001-05-06 20:50:27 +00:00
markTotal + + ;
}
}
/*
= = = = = = = = = = = = = = =
CG_AddMarks
= = = = = = = = = = = = = = =
*/
# define MARK_TOTAL_TIME 10000
# define MARK_FADE_TIME 1000
2002-06-16 20:06:15 +00:00
void CG_AddMarks ( void )
{
int j ;
markPoly_t * mp , * next ;
int t ;
int fade ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( ! cg_addMarks . integer ) {
2001-05-06 20:50:27 +00:00
return ;
}
mp = cg_activeMarkPolys . nextMark ;
2002-06-16 20:06:15 +00:00
for ( ; mp ! = & cg_activeMarkPolys ; mp = next ) {
2001-05-06 20:50:27 +00:00
// grab next now, so if the local entity is freed we
// still have it
next = mp - > nextMark ;
// see if it is time to completely remove it
2002-06-16 20:06:15 +00:00
if ( cg . time > mp - > time + MARK_TOTAL_TIME ) {
CG_FreeMarkPoly ( mp ) ;
2001-05-06 20:50:27 +00:00
continue ;
}
// fade out the energy bursts
2002-06-16 20:06:15 +00:00
if ( mp - > markShader = = cgs . media . energyMarkShader ) {
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
fade = 450 - 450 * ( ( cg . time - mp - > time ) / 3000.0 ) ;
if ( fade < 255 ) {
if ( fade < 0 ) {
2001-05-06 20:50:27 +00:00
fade = 0 ;
}
2002-06-16 20:06:15 +00:00
if ( mp - > verts [ 0 ] . modulate [ 0 ] ! = 0 ) {
for ( j = 0 ; j < mp - > poly . numVerts ; j + + ) {
2001-05-06 20:50:27 +00:00
mp - > verts [ j ] . modulate [ 0 ] = mp - > color [ 0 ] * fade ;
mp - > verts [ j ] . modulate [ 1 ] = mp - > color [ 1 ] * fade ;
mp - > verts [ j ] . modulate [ 2 ] = mp - > color [ 2 ] * fade ;
}
}
}
}
// fade all marks out with time
t = mp - > time + MARK_TOTAL_TIME - cg . time ;
2002-06-16 20:06:15 +00:00
if ( t < MARK_FADE_TIME ) {
2001-05-06 20:50:27 +00:00
fade = 255 * t / MARK_FADE_TIME ;
2002-06-16 20:06:15 +00:00
if ( mp - > alphaFade ) {
for ( j = 0 ; j < mp - > poly . numVerts ; j + + ) {
2001-05-06 20:50:27 +00:00
mp - > verts [ j ] . modulate [ 3 ] = fade ;
}
} else {
2002-06-16 20:06:15 +00:00
for ( j = 0 ; j < mp - > poly . numVerts ; j + + ) {
2001-05-06 20:50:27 +00:00
mp - > verts [ j ] . modulate [ 0 ] = mp - > color [ 0 ] * fade ;
mp - > verts [ j ] . modulate [ 1 ] = mp - > color [ 1 ] * fade ;
mp - > verts [ j ] . modulate [ 2 ] = mp - > color [ 2 ] * fade ;
}
}
}
2002-06-16 20:06:15 +00:00
trap_R_AddPolyToScene ( mp - > markShader , mp - > poly . numVerts , mp - > verts ) ;
2001-05-06 20:50:27 +00:00
}
}
2001-08-01 21:07:48 +00:00
// cg_particles.c
# define BLOODRED 2
# define EMISIVEFADE 3
# define GREY75 4
2002-04-23 06:06:19 +00:00
# define LIGHT_BLUE_WATER 5
# define DARK_BLUE_WATER 6
2003-07-30 16:05:47 +00:00
//Makro - added
# define GRASS 7
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
typedef struct particle_s {
struct particle_s * next ;
float time ;
float endtime ;
vec3_t org ;
vec3_t vel ;
vec3_t accel ;
int color ;
float colorvel ;
float alpha ;
float alphavel ;
int type ;
qhandle_t pshader ;
float height ;
float width ;
float endheight ;
float endwidth ;
float start ;
float end ;
float startfade ;
qboolean rotate ;
int snum ;
qboolean link ;
2001-08-01 21:07:48 +00:00
// Ridah
2002-06-16 20:06:15 +00:00
int shaderAnim ;
int roll ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
int accumroll ;
2001-08-01 21:07:48 +00:00
2002-08-21 03:45:36 +00:00
// reflection stuff
float reflectdistance ;
vec3_t reflectnormal ;
float mtime ;
2002-08-21 03:53:09 +00:00
float epsilon ;
2001-08-01 21:07:48 +00:00
} cparticle_t ;
2002-06-16 20:06:15 +00:00
typedef enum {
2001-08-01 21:07:48 +00:00
P_NONE ,
P_WEATHER ,
P_FLAT ,
P_SMOKE ,
P_ROTATE ,
P_WEATHER_TURBULENT ,
2002-06-16 20:06:15 +00:00
P_ANIM , // Ridah
2001-08-01 21:07:48 +00:00
P_BAT ,
P_BLEED ,
P_FLAT_SCALEUP ,
P_FLAT_SCALEUP_FADE ,
P_WEATHER_FLURRY ,
P_SMOKE_IMPACT ,
P_BUBBLE ,
P_BUBBLE_TURBULENT ,
P_SPRITE
} particle_type_t ;
# define MAX_SHADER_ANIMS 32
# define MAX_SHADER_ANIM_FRAMES 64
static char * shaderAnimNames [ MAX_SHADER_ANIMS ] = {
" explode1 " ,
NULL
} ;
static qhandle_t shaderAnims [ MAX_SHADER_ANIMS ] [ MAX_SHADER_ANIM_FRAMES ] ;
2002-06-16 20:06:15 +00:00
static int shaderAnimCounts [ MAX_SHADER_ANIMS ] = {
2001-08-01 21:07:48 +00:00
23
} ;
2002-06-16 20:06:15 +00:00
static float shaderAnimSTRatio [ MAX_SHADER_ANIMS ] = {
2001-08-01 21:07:48 +00:00
1.0f
} ;
2002-06-16 20:06:15 +00:00
static int numShaderAnims ;
2001-08-01 21:07:48 +00:00
// done.
# define PARTICLE_GRAVITY 40
2002-04-23 06:06:19 +00:00
# define MAX_PARTICLES 1536 // NiceAss: 1024 upped to 1536
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
cparticle_t * active_particles , * free_particles ;
cparticle_t particles [ MAX_PARTICLES ] ;
int cl_numparticles = MAX_PARTICLES ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
qboolean initparticles = qfalse ;
vec3_t pvforward , pvright , pvup ;
vec3_t rforward , rright , rup ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
float oldtime ;
2001-08-01 21:07:48 +00:00
/*
= = = = = = = = = = = = = = =
CL_ClearParticles
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_ClearParticles ( void )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
int i ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
memset ( particles , 0 , sizeof ( particles ) ) ;
2001-08-01 21:07:48 +00:00
free_particles = & particles [ 0 ] ;
active_particles = NULL ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < cl_numparticles ; i + + ) {
particles [ i ] . next = & particles [ i + 1 ] ;
2001-08-01 21:07:48 +00:00
particles [ i ] . type = 0 ;
}
2002-06-16 20:06:15 +00:00
particles [ cl_numparticles - 1 ] . next = NULL ;
2001-08-01 21:07:48 +00:00
oldtime = cg . time ;
// Ridah, init the shaderAnims
2002-06-16 20:06:15 +00:00
for ( i = 0 ; shaderAnimNames [ i ] ; i + + ) {
2001-08-01 21:07:48 +00:00
int j ;
2002-06-16 20:06:15 +00:00
for ( j = 0 ; j < shaderAnimCounts [ i ] ; j + + ) {
shaderAnims [ i ] [ j ] = trap_R_RegisterShader ( va ( " %s%i " , shaderAnimNames [ i ] , j + 1 ) ) ;
2001-08-01 21:07:48 +00:00
}
}
numShaderAnims = i ;
// done.
initparticles = qtrue ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CG_AddParticleToScene
= = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_AddParticleToScene ( cparticle_t * p , vec3_t org , float alpha )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
vec3_t point ;
polyVert_t verts [ 4 ] ;
float width ;
float height ;
float time , time2 ;
float ratio ;
float invratio ;
vec3_t color ;
polyVert_t TRIverts [ 3 ] ;
vec3_t rright2 , rup2 ;
if ( p - > type = = P_WEATHER | | p - > type = = P_WEATHER_TURBULENT | | p - > type = = P_WEATHER_FLURRY | | p - > type = = P_BUBBLE | | p - > type = = P_BUBBLE_TURBULENT ) { // create a front facing polygon
if ( p - > type ! = P_WEATHER_FLURRY ) {
if ( p - > type = = P_BUBBLE | | p - > type = = P_BUBBLE_TURBULENT ) {
if ( org [ 2 ] > p - > end ) {
p - > time = cg . time ;
VectorCopy ( org , p - > org ) ; // Ridah, fixes rare snow flakes that flicker on the ground
p - > org [ 2 ] = ( p - > start + crandom ( ) * 4 ) ;
if ( p - > type = = P_BUBBLE_TURBULENT ) {
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = crandom ( ) * 4 ;
p - > vel [ 1 ] = crandom ( ) * 4 ;
}
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
} else {
if ( org [ 2 ] < p - > end ) {
p - > time = cg . time ;
VectorCopy ( org , p - > org ) ; // Ridah, fixes rare snow flakes that flicker on the ground
while ( p - > org [ 2 ] < p - > end ) {
p - > org [ 2 ] + = ( p - > start - p - > end ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
if ( p - > type = = P_WEATHER_TURBULENT ) {
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = crandom ( ) * 16 ;
p - > vel [ 1 ] = crandom ( ) * 16 ;
}
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
}
}
// Rafael snow pvs check
if ( ! p - > link )
return ;
p - > alpha = 1 ;
}
// Ridah, had to do this or MAX_POLYS is being exceeded in village1.bsp
2002-06-16 20:06:15 +00:00
if ( Distance ( cg . snap - > ps . origin , org ) > 1024 ) {
2001-08-01 21:07:48 +00:00
return ;
}
// done.
2002-06-16 20:06:15 +00:00
if ( p - > type = = P_BUBBLE | | p - > type = = P_BUBBLE_TURBULENT ) {
VectorMA ( org , - p - > height , pvup , point ) ;
VectorMA ( point , - p - > width , pvright , point ) ;
VectorCopy ( point , verts [ 0 ] . xyz ) ;
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 0 ;
verts [ 0 ] . modulate [ 0 ] = 255 ;
verts [ 0 ] . modulate [ 1 ] = 255 ;
verts [ 0 ] . modulate [ 2 ] = 255 ;
verts [ 0 ] . modulate [ 3 ] = 255 * p - > alpha ;
VectorMA ( org , - p - > height , pvup , point ) ;
VectorMA ( point , p - > width , pvright , point ) ;
VectorCopy ( point , verts [ 1 ] . xyz ) ;
verts [ 1 ] . st [ 0 ] = 0 ;
verts [ 1 ] . st [ 1 ] = 1 ;
verts [ 1 ] . modulate [ 0 ] = 255 ;
verts [ 1 ] . modulate [ 1 ] = 255 ;
verts [ 1 ] . modulate [ 2 ] = 255 ;
verts [ 1 ] . modulate [ 3 ] = 255 * p - > alpha ;
VectorMA ( org , p - > height , pvup , point ) ;
VectorMA ( point , p - > width , pvright , point ) ;
VectorCopy ( point , verts [ 2 ] . xyz ) ;
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 255 ;
verts [ 2 ] . modulate [ 1 ] = 255 ;
verts [ 2 ] . modulate [ 2 ] = 255 ;
verts [ 2 ] . modulate [ 3 ] = 255 * p - > alpha ;
VectorMA ( org , p - > height , pvup , point ) ;
VectorMA ( point , - p - > width , pvright , point ) ;
VectorCopy ( point , verts [ 3 ] . xyz ) ;
verts [ 3 ] . st [ 0 ] = 1 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 255 ;
verts [ 3 ] . modulate [ 1 ] = 255 ;
verts [ 3 ] . modulate [ 2 ] = 255 ;
verts [ 3 ] . modulate [ 3 ] = 255 * p - > alpha ;
} else {
VectorMA ( org , - p - > height , pvup , point ) ;
VectorMA ( point , - p - > width , pvright , point ) ;
VectorCopy ( point , TRIverts [ 0 ] . xyz ) ;
2001-08-01 21:07:48 +00:00
TRIverts [ 0 ] . st [ 0 ] = 1 ;
TRIverts [ 0 ] . st [ 1 ] = 0 ;
TRIverts [ 0 ] . modulate [ 0 ] = 255 ;
TRIverts [ 0 ] . modulate [ 1 ] = 255 ;
TRIverts [ 0 ] . modulate [ 2 ] = 255 ;
2002-06-16 20:06:15 +00:00
TRIverts [ 0 ] . modulate [ 3 ] = 255 * p - > alpha ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
VectorMA ( org , p - > height , pvup , point ) ;
VectorMA ( point , - p - > width , pvright , point ) ;
VectorCopy ( point , TRIverts [ 1 ] . xyz ) ;
2001-08-01 21:07:48 +00:00
TRIverts [ 1 ] . st [ 0 ] = 0 ;
TRIverts [ 1 ] . st [ 1 ] = 0 ;
TRIverts [ 1 ] . modulate [ 0 ] = 255 ;
TRIverts [ 1 ] . modulate [ 1 ] = 255 ;
TRIverts [ 1 ] . modulate [ 2 ] = 255 ;
2002-06-16 20:06:15 +00:00
TRIverts [ 1 ] . modulate [ 3 ] = 255 * p - > alpha ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
VectorMA ( org , p - > height , pvup , point ) ;
VectorMA ( point , p - > width , pvright , point ) ;
VectorCopy ( point , TRIverts [ 2 ] . xyz ) ;
2001-08-01 21:07:48 +00:00
TRIverts [ 2 ] . st [ 0 ] = 0 ;
TRIverts [ 2 ] . st [ 1 ] = 1 ;
TRIverts [ 2 ] . modulate [ 0 ] = 255 ;
TRIverts [ 2 ] . modulate [ 1 ] = 255 ;
TRIverts [ 2 ] . modulate [ 2 ] = 255 ;
2002-06-16 20:06:15 +00:00
TRIverts [ 2 ] . modulate [ 3 ] = 255 * p - > alpha ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
} else if ( p - > type = = P_SPRITE ) {
vec3_t rr , ru ;
vec3_t rotate_ang ;
VectorSet ( color , 1.0 , 1.0 , 0.5 ) ;
2001-08-01 21:07:48 +00:00
time = cg . time - p - > time ;
time2 = p - > endtime - p - > time ;
ratio = time / time2 ;
2002-06-16 20:06:15 +00:00
width = p - > width + ( ratio * ( p - > endwidth - p - > width ) ) ;
height = p - > height + ( ratio * ( p - > endheight - p - > height ) ) ;
2001-08-01 21:07:48 +00:00
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
vectoangles ( cg . refdef . viewaxis [ 0 ] , rotate_ang ) ;
2001-08-01 21:07:48 +00:00
rotate_ang [ ROLL ] + = p - > roll ;
2002-06-16 20:06:15 +00:00
AngleVectors ( rotate_ang , NULL , rr , ru ) ;
2001-08-01 21:07:48 +00:00
}
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( org , - height , ru , point ) ;
VectorMA ( point , - width , rr , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( org , - height , pvup , point ) ;
VectorMA ( point , - width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 0 ] . xyz ) ;
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 0 ;
verts [ 0 ] . modulate [ 0 ] = 255 ;
verts [ 0 ] . modulate [ 1 ] = 255 ;
verts [ 0 ] . modulate [ 2 ] = 255 ;
2001-08-01 21:07:48 +00:00
verts [ 0 ] . modulate [ 3 ] = 255 ;
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * height , ru , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * height , pvup , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 1 ] . xyz ) ;
verts [ 1 ] . st [ 0 ] = 0 ;
verts [ 1 ] . st [ 1 ] = 1 ;
verts [ 1 ] . modulate [ 0 ] = 255 ;
verts [ 1 ] . modulate [ 1 ] = 255 ;
verts [ 1 ] . modulate [ 2 ] = 255 ;
verts [ 1 ] . modulate [ 3 ] = 255 ;
2001-08-01 21:07:48 +00:00
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * width , rr , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 2 ] . xyz ) ;
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 255 ;
verts [ 2 ] . modulate [ 1 ] = 255 ;
verts [ 2 ] . modulate [ 2 ] = 255 ;
verts [ 2 ] . modulate [ 3 ] = 255 ;
2001-08-01 21:07:48 +00:00
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( point , - 2 * height , ru , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( point , - 2 * height , pvup , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 3 ] . xyz ) ;
verts [ 3 ] . st [ 0 ] = 1 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 255 ;
verts [ 3 ] . modulate [ 1 ] = 255 ;
verts [ 3 ] . modulate [ 2 ] = 255 ;
verts [ 3 ] . modulate [ 3 ] = 255 ;
} else if ( p - > type = = P_SMOKE | | p - > type = = P_SMOKE_IMPACT ) { // create a front rotating facing polygon
if ( p - > type = = P_SMOKE_IMPACT & & Distance ( cg . snap - > ps . origin , org ) > 1024 ) {
2001-08-01 21:07:48 +00:00
return ;
}
if ( p - > color = = BLOODRED )
2002-06-16 20:06:15 +00:00
VectorSet ( color , 0.22f , 0.0f , 0.0f ) ;
2002-04-23 06:06:19 +00:00
else if ( p - > color = = LIGHT_BLUE_WATER )
2002-06-16 20:06:15 +00:00
VectorSet ( color , 0.8f , 0.8f , 1.0f ) ;
2002-04-23 06:06:19 +00:00
else if ( p - > color = = DARK_BLUE_WATER )
2002-06-16 20:06:15 +00:00
VectorSet ( color , 0.6f , 0.8f , 1.0f ) ;
2003-07-30 16:05:47 +00:00
//Makro - added
else if ( p - > color = = GRASS )
VectorSet ( color , 0.4f , 0.5f , 0.4f ) ;
2002-06-16 20:06:15 +00:00
else if ( p - > color = = GREY75 ) {
float len ;
float greyit ;
float val ;
len = Distance ( cg . snap - > ps . origin , org ) ;
2001-08-01 21:07:48 +00:00
if ( ! len )
len = 1 ;
2002-06-16 20:06:15 +00:00
val = 4096 / len ;
2001-08-01 21:07:48 +00:00
greyit = 0.25 * val ;
if ( greyit > 0.5 )
greyit = 0.5 ;
2002-06-16 20:06:15 +00:00
VectorSet ( color , greyit , greyit , greyit ) ;
} else
VectorSet ( color , 1.0 , 1.0 , 1.0 ) ;
2001-08-01 21:07:48 +00:00
time = cg . time - p - > time ;
time2 = p - > endtime - p - > time ;
ratio = time / time2 ;
2002-06-16 20:06:15 +00:00
if ( cg . time > p - > startfade ) {
invratio = 1 - ( ( cg . time - p - > startfade ) / ( p - > endtime - p - > startfade ) ) ;
if ( p - > color = = EMISIVEFADE ) {
2001-08-01 21:07:48 +00:00
float fval ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
fval = ( invratio * invratio ) ;
if ( fval < 0 )
fval = 0 ;
2002-06-16 20:06:15 +00:00
VectorSet ( color , fval , fval , fval ) ;
2001-08-01 21:07:48 +00:00
}
invratio * = p - > alpha ;
2002-06-16 20:06:15 +00:00
} else
2001-08-01 21:07:48 +00:00
invratio = 1 * p - > alpha ;
2002-06-16 20:06:15 +00:00
if ( cgs . glconfig . hardwareType = = GLHW_RAGEPRO )
2001-08-01 21:07:48 +00:00
invratio = 1 ;
if ( invratio > 1 )
invratio = 1 ;
2002-06-16 20:06:15 +00:00
width = p - > width + ( ratio * ( p - > endwidth - p - > width ) ) ;
height = p - > height + ( ratio * ( p - > endheight - p - > height ) ) ;
if ( p - > type ! = P_SMOKE_IMPACT ) {
2001-08-01 21:07:48 +00:00
vec3_t temp ;
2002-06-16 20:06:15 +00:00
vectoangles ( rforward , temp ) ;
2001-08-01 21:07:48 +00:00
p - > accumroll + = p - > roll ;
temp [ ROLL ] + = p - > accumroll * 0.1 ;
2002-06-16 20:06:15 +00:00
AngleVectors ( temp , NULL , rright2 , rup2 ) ;
} else {
VectorCopy ( rright , rright2 ) ;
VectorCopy ( rup , rup2 ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
if ( p - > rotate ) {
VectorMA ( org , - height , rup2 , point ) ;
VectorMA ( point , - width , rright2 , point ) ;
} else {
VectorMA ( org , - p - > height , pvup , point ) ;
VectorMA ( point , - p - > width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 0 ] . xyz ) ;
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 0 ;
verts [ 0 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 0 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 0 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 0 ] . modulate [ 3 ] = 255 * invratio ;
if ( p - > rotate ) {
VectorMA ( org , - height , rup2 , point ) ;
VectorMA ( point , width , rright2 , point ) ;
} else {
VectorMA ( org , - p - > height , pvup , point ) ;
VectorMA ( point , p - > width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 1 ] . xyz ) ;
verts [ 1 ] . st [ 0 ] = 0 ;
verts [ 1 ] . st [ 1 ] = 1 ;
verts [ 1 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 1 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 1 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 1 ] . modulate [ 3 ] = 255 * invratio ;
if ( p - > rotate ) {
VectorMA ( org , height , rup2 , point ) ;
VectorMA ( point , width , rright2 , point ) ;
} else {
VectorMA ( org , p - > height , pvup , point ) ;
VectorMA ( point , p - > width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 2 ] . xyz ) ;
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 2 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 2 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 2 ] . modulate [ 3 ] = 255 * invratio ;
if ( p - > rotate ) {
VectorMA ( org , height , rup2 , point ) ;
VectorMA ( point , - width , rright2 , point ) ;
} else {
VectorMA ( org , p - > height , pvup , point ) ;
VectorMA ( point , - p - > width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 3 ] . xyz ) ;
verts [ 3 ] . st [ 0 ] = 1 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 3 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 3 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 3 ] . modulate [ 3 ] = 255 * invratio ;
} else if ( p - > type = = P_BLEED ) {
vec3_t rr , ru ;
vec3_t rotate_ang ;
float alpha ;
2001-08-01 21:07:48 +00:00
alpha = p - > alpha ;
2002-06-16 20:06:15 +00:00
if ( cgs . glconfig . hardwareType = = GLHW_RAGEPRO )
2001-08-01 21:07:48 +00:00
alpha = 1 ;
2002-06-16 20:06:15 +00:00
if ( p - > roll ) {
vectoangles ( cg . refdef . viewaxis [ 0 ] , rotate_ang ) ;
2001-08-01 21:07:48 +00:00
rotate_ang [ ROLL ] + = p - > roll ;
2002-06-16 20:06:15 +00:00
AngleVectors ( rotate_ang , NULL , rr , ru ) ;
} else {
VectorCopy ( pvup , ru ) ;
VectorCopy ( pvright , rr ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorMA ( org , - p - > height , ru , point ) ;
VectorMA ( point , - p - > width , rr , point ) ;
VectorCopy ( point , verts [ 0 ] . xyz ) ;
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 0 ;
verts [ 0 ] . modulate [ 0 ] = 111 ;
verts [ 0 ] . modulate [ 1 ] = 19 ;
verts [ 0 ] . modulate [ 2 ] = 9 ;
verts [ 0 ] . modulate [ 3 ] = 255 * alpha ;
VectorMA ( org , - p - > height , ru , point ) ;
VectorMA ( point , p - > width , rr , point ) ;
VectorCopy ( point , verts [ 1 ] . xyz ) ;
verts [ 1 ] . st [ 0 ] = 0 ;
verts [ 1 ] . st [ 1 ] = 1 ;
verts [ 1 ] . modulate [ 0 ] = 111 ;
verts [ 1 ] . modulate [ 1 ] = 19 ;
verts [ 1 ] . modulate [ 2 ] = 9 ;
verts [ 1 ] . modulate [ 3 ] = 255 * alpha ;
VectorMA ( org , p - > height , ru , point ) ;
VectorMA ( point , p - > width , rr , point ) ;
VectorCopy ( point , verts [ 2 ] . xyz ) ;
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 111 ;
verts [ 2 ] . modulate [ 1 ] = 19 ;
verts [ 2 ] . modulate [ 2 ] = 9 ;
verts [ 2 ] . modulate [ 3 ] = 255 * alpha ;
VectorMA ( org , p - > height , ru , point ) ;
VectorMA ( point , - p - > width , rr , point ) ;
VectorCopy ( point , verts [ 3 ] . xyz ) ;
verts [ 3 ] . st [ 0 ] = 1 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 111 ;
verts [ 3 ] . modulate [ 1 ] = 19 ;
verts [ 3 ] . modulate [ 2 ] = 9 ;
verts [ 3 ] . modulate [ 3 ] = 255 * alpha ;
} else if ( p - > type = = P_FLAT_SCALEUP ) {
2001-08-01 21:07:48 +00:00
float width , height ;
float sinR , cosR ;
if ( p - > color = = BLOODRED )
2002-06-16 20:06:15 +00:00
VectorSet ( color , 1 , 1 , 1 ) ;
2002-04-23 06:06:19 +00:00
else if ( p - > color = = LIGHT_BLUE_WATER )
2002-06-16 20:06:15 +00:00
VectorSet ( color , 0.8f , 0.8f , 1.0f ) ;
2002-04-23 06:06:19 +00:00
else if ( p - > color = = DARK_BLUE_WATER )
2002-06-16 20:06:15 +00:00
VectorSet ( color , 0.6f , 0.8f , 1.0f ) ;
2001-08-01 21:07:48 +00:00
else
2002-06-16 20:06:15 +00:00
VectorSet ( color , 0.5 , 0.5 , 0.5 ) ;
2001-08-01 21:07:48 +00:00
time = cg . time - p - > time ;
time2 = p - > endtime - p - > time ;
ratio = time / time2 ;
2002-06-16 20:06:15 +00:00
width = p - > width + ( ratio * ( p - > endwidth - p - > width ) ) ;
height = p - > height + ( ratio * ( p - > endheight - p - > height ) ) ;
2001-08-01 21:07:48 +00:00
if ( width > p - > endwidth )
width = p - > endwidth ;
if ( height > p - > endheight )
height = p - > endheight ;
sinR = height * sin ( DEG2RAD ( p - > roll ) ) * sqrt ( 2 ) ;
cosR = width * cos ( DEG2RAD ( p - > roll ) ) * sqrt ( 2 ) ;
2002-06-16 20:06:15 +00:00
VectorCopy ( org , verts [ 0 ] . xyz ) ;
2001-08-01 21:07:48 +00:00
verts [ 0 ] . xyz [ 0 ] - = sinR ;
verts [ 0 ] . xyz [ 1 ] - = cosR ;
2002-06-16 20:06:15 +00:00
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 0 ;
verts [ 0 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 0 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 0 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 0 ] . modulate [ 3 ] = 255 ;
VectorCopy ( org , verts [ 1 ] . xyz ) ;
verts [ 1 ] . xyz [ 0 ] - = cosR ;
verts [ 1 ] . xyz [ 1 ] + = sinR ;
verts [ 1 ] . st [ 0 ] = 0 ;
verts [ 1 ] . st [ 1 ] = 1 ;
verts [ 1 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 1 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 1 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 1 ] . modulate [ 3 ] = 255 ;
VectorCopy ( org , verts [ 2 ] . xyz ) ;
verts [ 2 ] . xyz [ 0 ] + = sinR ;
verts [ 2 ] . xyz [ 1 ] + = cosR ;
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 2 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 2 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 2 ] . modulate [ 3 ] = 255 ;
VectorCopy ( org , verts [ 3 ] . xyz ) ;
verts [ 3 ] . xyz [ 0 ] + = cosR ;
verts [ 3 ] . xyz [ 1 ] - = sinR ;
verts [ 3 ] . st [ 0 ] = 1 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 255 * color [ 0 ] ;
verts [ 3 ] . modulate [ 1 ] = 255 * color [ 1 ] ;
verts [ 3 ] . modulate [ 2 ] = 255 * color [ 2 ] ;
verts [ 3 ] . modulate [ 3 ] = 255 ;
} else if ( p - > type = = P_FLAT ) {
VectorCopy ( org , verts [ 0 ] . xyz ) ;
verts [ 0 ] . xyz [ 0 ] - = p - > height ;
verts [ 0 ] . xyz [ 1 ] - = p - > width ;
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 0 ;
verts [ 0 ] . modulate [ 0 ] = 255 ;
verts [ 0 ] . modulate [ 1 ] = 255 ;
verts [ 0 ] . modulate [ 2 ] = 255 ;
verts [ 0 ] . modulate [ 3 ] = 255 ;
VectorCopy ( org , verts [ 1 ] . xyz ) ;
verts [ 1 ] . xyz [ 0 ] - = p - > height ;
verts [ 1 ] . xyz [ 1 ] + = p - > width ;
verts [ 1 ] . st [ 0 ] = 0 ;
verts [ 1 ] . st [ 1 ] = 1 ;
verts [ 1 ] . modulate [ 0 ] = 255 ;
verts [ 1 ] . modulate [ 1 ] = 255 ;
verts [ 1 ] . modulate [ 2 ] = 255 ;
verts [ 1 ] . modulate [ 3 ] = 255 ;
VectorCopy ( org , verts [ 2 ] . xyz ) ;
verts [ 2 ] . xyz [ 0 ] + = p - > height ;
verts [ 2 ] . xyz [ 1 ] + = p - > width ;
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 255 ;
verts [ 2 ] . modulate [ 1 ] = 255 ;
verts [ 2 ] . modulate [ 2 ] = 255 ;
verts [ 2 ] . modulate [ 3 ] = 255 ;
VectorCopy ( org , verts [ 3 ] . xyz ) ;
verts [ 3 ] . xyz [ 0 ] + = p - > height ;
verts [ 3 ] . xyz [ 1 ] - = p - > width ;
verts [ 3 ] . st [ 0 ] = 1 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 255 ;
verts [ 3 ] . modulate [ 1 ] = 255 ;
verts [ 3 ] . modulate [ 2 ] = 255 ;
verts [ 3 ] . modulate [ 3 ] = 255 ;
2001-08-01 21:07:48 +00:00
}
// Ridah
else if ( p - > type = = P_ANIM ) {
2002-06-16 20:06:15 +00:00
vec3_t rr , ru ;
vec3_t rotate_ang ;
2001-08-01 21:07:48 +00:00
int i , j ;
time = cg . time - p - > time ;
time2 = p - > endtime - p - > time ;
ratio = time / time2 ;
if ( ratio > = 1.0f ) {
ratio = 0.9999f ;
}
2002-06-16 20:06:15 +00:00
width = p - > width + ( ratio * ( p - > endwidth - p - > width ) ) ;
height = p - > height + ( ratio * ( p - > endheight - p - > height ) ) ;
2001-08-01 21:07:48 +00:00
// if we are "inside" this sprite, don't draw
2002-06-16 20:06:15 +00:00
if ( Distance ( cg . snap - > ps . origin , org ) < width / 1.5 ) {
2001-08-01 21:07:48 +00:00
return ;
}
i = p - > shaderAnim ;
2002-06-16 20:06:15 +00:00
j = ( int ) floor ( ratio * shaderAnimCounts [ p - > shaderAnim ] ) ;
2001-08-01 21:07:48 +00:00
p - > pshader = shaderAnims [ i ] [ j ] ;
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
vectoangles ( cg . refdef . viewaxis [ 0 ] , rotate_ang ) ;
2001-08-01 21:07:48 +00:00
rotate_ang [ ROLL ] + = p - > roll ;
2002-06-16 20:06:15 +00:00
AngleVectors ( rotate_ang , NULL , rr , ru ) ;
2001-08-01 21:07:48 +00:00
}
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( org , - height , ru , point ) ;
VectorMA ( point , - width , rr , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( org , - height , pvup , point ) ;
VectorMA ( point , - width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 0 ] . xyz ) ;
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 0 ;
verts [ 0 ] . modulate [ 0 ] = 255 ;
verts [ 0 ] . modulate [ 1 ] = 255 ;
verts [ 0 ] . modulate [ 2 ] = 255 ;
2001-08-01 21:07:48 +00:00
verts [ 0 ] . modulate [ 3 ] = 255 ;
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * height , ru , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * height , pvup , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 1 ] . xyz ) ;
verts [ 1 ] . st [ 0 ] = 0 ;
verts [ 1 ] . st [ 1 ] = 1 ;
verts [ 1 ] . modulate [ 0 ] = 255 ;
verts [ 1 ] . modulate [ 1 ] = 255 ;
verts [ 1 ] . modulate [ 2 ] = 255 ;
verts [ 1 ] . modulate [ 3 ] = 255 ;
2001-08-01 21:07:48 +00:00
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * width , rr , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( point , 2 * width , pvright , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 2 ] . xyz ) ;
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 255 ;
verts [ 2 ] . modulate [ 1 ] = 255 ;
verts [ 2 ] . modulate [ 2 ] = 255 ;
verts [ 2 ] . modulate [ 3 ] = 255 ;
2001-08-01 21:07:48 +00:00
if ( p - > roll ) {
2002-06-16 20:06:15 +00:00
VectorMA ( point , - 2 * height , ru , point ) ;
2001-08-01 21:07:48 +00:00
} else {
2002-06-16 20:06:15 +00:00
VectorMA ( point , - 2 * height , pvup , point ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( point , verts [ 3 ] . xyz ) ;
verts [ 3 ] . st [ 0 ] = 1 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 255 ;
verts [ 3 ] . modulate [ 1 ] = 255 ;
verts [ 3 ] . modulate [ 2 ] = 255 ;
verts [ 3 ] . modulate [ 3 ] = 255 ;
2001-08-01 21:07:48 +00:00
}
// done.
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
if ( ! p - > pshader ) {
// (SA) temp commented out for DM
2002-06-16 20:06:15 +00:00
// CG_Printf ("CG_AddParticleToScene type %d p->pshader == ZERO\n", p->type);
2001-08-01 21:07:48 +00:00
return ;
}
if ( p - > type = = P_WEATHER | | p - > type = = P_WEATHER_TURBULENT | | p - > type = = P_WEATHER_FLURRY )
2002-06-16 20:06:15 +00:00
trap_R_AddPolyToScene ( p - > pshader , 3 , TRIverts ) ;
2001-08-01 21:07:48 +00:00
else
2002-06-16 20:06:15 +00:00
trap_R_AddPolyToScene ( p - > pshader , 4 , verts ) ;
2001-08-01 21:07:48 +00:00
}
// Ridah, made this static so it doesn't interfere with other files
static float roll = 0.0 ;
/*
= = = = = = = = = = = = = = =
CG_AddParticles
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_AddParticles ( void )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p , * next ;
float alpha ;
2002-08-21 03:45:36 +00:00
float time , time2 , mtime , mtime2 ;
2002-06-16 20:06:15 +00:00
vec3_t org ;
2012-01-13 21:27:15 +00:00
// int color;
2002-06-16 20:06:15 +00:00
cparticle_t * active , * tail ;
2012-01-13 21:27:15 +00:00
// int type;
2002-06-16 20:06:15 +00:00
vec3_t rotate_ang ;
2002-08-21 03:45:36 +00:00
trace_t tr ;
vec3_t dist , end ;
2001-08-01 21:07:48 +00:00
if ( ! initparticles )
2002-06-16 20:06:15 +00:00
CG_ClearParticles ( ) ;
VectorCopy ( cg . refdef . viewaxis [ 0 ] , pvforward ) ;
VectorCopy ( cg . refdef . viewaxis [ 1 ] , pvright ) ;
VectorCopy ( cg . refdef . viewaxis [ 2 ] , pvup ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
vectoangles ( cg . refdef . viewaxis [ 0 ] , rotate_ang ) ;
roll + = ( ( cg . time - oldtime ) * 0.1 ) ;
rotate_ang [ ROLL ] + = ( roll * 0.9 ) ;
AngleVectors ( rotate_ang , rforward , rright , rup ) ;
2001-08-01 21:07:48 +00:00
oldtime = cg . time ;
active = NULL ;
tail = NULL ;
2002-06-16 20:06:15 +00:00
for ( p = active_particles ; p ; p = next ) {
2001-08-01 21:07:48 +00:00
next = p - > next ;
2002-06-16 20:06:15 +00:00
time = ( cg . time - p - > time ) * 0.001 ;
2002-08-21 03:45:36 +00:00
mtime = ( cg . time - p - > mtime ) * 0.001 ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
alpha = p - > alpha + time * p - > alphavel ;
if ( alpha < = 0 ) { // faded out
2001-08-01 21:07:48 +00:00
p - > next = free_particles ;
free_particles = p ;
p - > type = 0 ;
p - > color = 0 ;
p - > alpha = 0 ;
continue ;
}
2002-06-16 20:06:15 +00:00
if ( p - > type = = P_SMOKE | | p - > type = = P_ANIM | | p - > type = = P_BLEED | | p - > type = = P_SMOKE_IMPACT ) {
if ( cg . time > p - > endtime ) {
2001-08-01 21:07:48 +00:00
p - > next = free_particles ;
free_particles = p ;
p - > type = 0 ;
p - > color = 0 ;
p - > alpha = 0 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
continue ;
}
}
2002-06-16 20:06:15 +00:00
if ( p - > type = = P_WEATHER_FLURRY ) {
if ( cg . time > p - > endtime ) {
2001-08-01 21:07:48 +00:00
p - > next = free_particles ;
free_particles = p ;
p - > type = 0 ;
p - > color = 0 ;
p - > alpha = 0 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
continue ;
}
}
2002-06-16 20:06:15 +00:00
if ( p - > type = = P_FLAT_SCALEUP_FADE ) {
if ( cg . time > p - > endtime ) {
2001-08-01 21:07:48 +00:00
p - > next = free_particles ;
free_particles = p ;
p - > type = 0 ;
p - > color = 0 ;
p - > alpha = 0 ;
continue ;
}
}
if ( ( p - > type = = P_BAT | | p - > type = = P_SPRITE ) & & p - > endtime < 0 ) {
// temporary sprite
2002-06-16 20:06:15 +00:00
CG_AddParticleToScene ( p , p - > org , alpha ) ;
2001-08-01 21:07:48 +00:00
p - > next = free_particles ;
free_particles = p ;
p - > type = 0 ;
p - > color = 0 ;
p - > alpha = 0 ;
continue ;
}
p - > next = NULL ;
if ( ! tail )
active = tail = p ;
2002-06-16 20:06:15 +00:00
else {
2001-08-01 21:07:48 +00:00
tail - > next = p ;
tail = p ;
}
if ( alpha > 1.0 )
alpha = 1 ;
2012-01-13 21:27:15 +00:00
// color = p->color;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
time2 = time * time ;
2002-08-21 03:45:36 +00:00
mtime2 = mtime * mtime ;
2001-08-01 21:07:48 +00:00
2002-08-21 03:45:36 +00:00
if ( p - > mtime ) {
org [ 0 ] = p - > org [ 0 ] + p - > vel [ 0 ] * mtime + p - > accel [ 0 ] * mtime2 ;
org [ 1 ] = p - > org [ 1 ] + p - > vel [ 1 ] * mtime + p - > accel [ 1 ] * mtime2 ;
org [ 2 ] = p - > org [ 2 ] + p - > vel [ 2 ] * mtime + p - > accel [ 2 ] * mtime2 ;
}
else {
org [ 0 ] = p - > org [ 0 ] + p - > vel [ 0 ] * time + p - > accel [ 0 ] * time2 ;
org [ 1 ] = p - > org [ 1 ] + p - > vel [ 1 ] * time + p - > accel [ 1 ] * time2 ;
org [ 2 ] = p - > org [ 2 ] + p - > vel [ 2 ] * time + p - > accel [ 2 ] * time2 ;
}
2001-08-01 21:07:48 +00:00
2012-01-13 21:27:15 +00:00
// type = p->type;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
CG_AddParticleToScene ( p , org , alpha ) ;
2002-08-21 03:45:36 +00:00
VectorSubtract ( org , p - > org , dist ) ;
2002-08-21 03:53:09 +00:00
// reflection stuff
2002-08-25 23:20:18 +00:00
if ( VectorLength ( dist ) > p - > reflectdistance - 5 & & p - > reflectdistance ) {
2002-08-21 03:45:36 +00:00
float length ;
2002-08-25 23:20:18 +00:00
length = VectorLength ( p - > vel ) * 0.75f ;
2002-08-21 03:45:36 +00:00
// reflection stuff
p - > vel [ 0 ] + = ( rand ( ) % 200 ) - 100 ;
p - > vel [ 1 ] + = ( rand ( ) % 200 ) - 100 ;
p - > vel [ 2 ] + = ( rand ( ) % 200 ) - 100 ;
VectorNormalize ( p - > vel ) ;
VectorScale ( p - > vel , length , p - > vel ) ;
2002-08-21 03:53:09 +00:00
PM_ClipVelocity ( p - > vel , p - > reflectnormal , p - > vel , p - > epsilon ) ;
2002-08-21 03:45:36 +00:00
VectorCopy ( org , p - > org ) ;
VectorMA ( org , 300 , p - > vel , end ) ;
CG_Trace ( & tr , org , NULL , NULL , end , 0 , MASK_SOLID ) ;
VectorSubtract ( org , tr . endpos , dist ) ;
p - > reflectdistance = VectorLength ( dist ) ;
VectorCopy ( tr . plane . normal , p - > reflectnormal ) ;
p - > mtime = cg . time ;
}
2001-08-01 21:07:48 +00:00
}
active_particles = active ;
}
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_AddParticles
= = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_ParticleSnowFlurry ( qhandle_t pshader , centity_t * cent )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
qboolean turb = qtrue ;
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_ParticleSnowFlurry pshader == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > color = 0 ;
p - > alpha = 0.90f ;
p - > alphavel = 0 ;
p - > start = cent - > currentState . origin2 [ 0 ] ;
p - > end = cent - > currentState . origin2 [ 1 ] ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > endtime = cg . time + cent - > currentState . time ;
p - > startfade = cg . time + cent - > currentState . time2 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > pshader = pshader ;
2002-06-16 20:06:15 +00:00
if ( rand ( ) % 100 > 90 ) {
2001-08-01 21:07:48 +00:00
p - > height = 32 ;
p - > width = 32 ;
p - > alpha = 0.10f ;
2002-06-16 20:06:15 +00:00
} else {
2001-08-01 21:07:48 +00:00
p - > height = 1 ;
p - > width = 1 ;
}
p - > vel [ 2 ] = - 20 ;
p - > type = P_WEATHER_FLURRY ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
if ( turb )
p - > vel [ 2 ] = - 10 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
VectorCopy ( cent - > currentState . origin , p - > org ) ;
p - > org [ 0 ] = p - > org [ 0 ] ;
p - > org [ 1 ] = p - > org [ 1 ] ;
p - > org [ 2 ] = p - > org [ 2 ] ;
p - > vel [ 0 ] = p - > vel [ 1 ] = 0 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > accel [ 0 ] = p - > accel [ 1 ] = p - > accel [ 2 ] = 0 ;
p - > vel [ 0 ] + = cent - > currentState . angles [ 0 ] * 32 + ( crandom ( ) * 16 ) ;
p - > vel [ 1 ] + = cent - > currentState . angles [ 1 ] * 32 + ( crandom ( ) * 16 ) ;
p - > vel [ 2 ] + = cent - > currentState . angles [ 2 ] ;
2002-06-16 20:06:15 +00:00
if ( turb ) {
p - > accel [ 0 ] = crandom ( ) * 16 ;
p - > accel [ 1 ] = crandom ( ) * 16 ;
2001-08-01 21:07:48 +00:00
}
}
2002-06-16 20:06:15 +00:00
void CG_ParticleSnow ( qhandle_t pshader , vec3_t origin , vec3_t origin2 , int turb , float range , int snum )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_ParticleSnow pshader == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > color = 0 ;
p - > alpha = 0.40f ;
p - > alphavel = 0 ;
p - > start = origin [ 2 ] ;
p - > end = origin2 [ 2 ] ;
p - > pshader = pshader ;
p - > height = 1 ;
p - > width = 1 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > vel [ 2 ] = - 50 ;
2002-06-16 20:06:15 +00:00
if ( turb ) {
2001-08-01 21:07:48 +00:00
p - > type = P_WEATHER_TURBULENT ;
p - > vel [ 2 ] = - 50 * 1.3 ;
2002-06-16 20:06:15 +00:00
} else {
2001-08-01 21:07:48 +00:00
p - > type = P_WEATHER ;
}
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
VectorCopy ( origin , p - > org ) ;
2002-06-16 20:06:15 +00:00
p - > org [ 0 ] = p - > org [ 0 ] + ( crandom ( ) * range ) ;
p - > org [ 1 ] = p - > org [ 1 ] + ( crandom ( ) * range ) ;
p - > org [ 2 ] = p - > org [ 2 ] + ( crandom ( ) * ( p - > start - p - > end ) ) ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = p - > vel [ 1 ] = 0 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > accel [ 0 ] = p - > accel [ 1 ] = p - > accel [ 2 ] = 0 ;
2002-06-16 20:06:15 +00:00
if ( turb ) {
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = crandom ( ) * 16 ;
p - > vel [ 1 ] = crandom ( ) * 16 ;
}
// Rafael snow pvs check
p - > snum = snum ;
p - > link = qtrue ;
}
2002-06-16 20:06:15 +00:00
void CG_ParticleBubble ( qhandle_t pshader , vec3_t origin , vec3_t origin2 , int turb , float range , int snum )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
float randsize ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_ParticleSnow pshader == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > color = 0 ;
p - > alpha = 0.40f ;
p - > alphavel = 0 ;
p - > start = origin [ 2 ] ;
p - > end = origin2 [ 2 ] ;
p - > pshader = pshader ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
randsize = 1 + ( crandom ( ) * 0.5 ) ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > height = randsize ;
p - > width = randsize ;
2002-06-16 20:06:15 +00:00
p - > vel [ 2 ] = 50 + ( crandom ( ) * 10 ) ;
if ( turb ) {
2001-08-01 21:07:48 +00:00
p - > type = P_BUBBLE_TURBULENT ;
p - > vel [ 2 ] = 50 * 1.3 ;
2002-06-16 20:06:15 +00:00
} else {
2001-08-01 21:07:48 +00:00
p - > type = P_BUBBLE ;
}
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
VectorCopy ( origin , p - > org ) ;
2002-06-16 20:06:15 +00:00
p - > org [ 0 ] = p - > org [ 0 ] + ( crandom ( ) * range ) ;
p - > org [ 1 ] = p - > org [ 1 ] + ( crandom ( ) * range ) ;
p - > org [ 2 ] = p - > org [ 2 ] + ( crandom ( ) * ( p - > start - p - > end ) ) ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = p - > vel [ 1 ] = 0 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > accel [ 0 ] = p - > accel [ 1 ] = p - > accel [ 2 ] = 0 ;
2002-06-16 20:06:15 +00:00
if ( turb ) {
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = crandom ( ) * 4 ;
p - > vel [ 1 ] = crandom ( ) * 4 ;
}
// Rafael snow pvs check
p - > snum = snum ;
p - > link = qtrue ;
}
2002-06-16 20:06:15 +00:00
void CG_ParticleSmoke ( qhandle_t pshader , centity_t * cent )
2001-08-01 21:07:48 +00:00
{
// using cent->density = enttime
2002-06-16 20:06:15 +00:00
// cent->frame = startfade
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_ParticleSmoke == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > endtime = cg . time + cent - > currentState . time ;
p - > startfade = cg . time + cent - > currentState . time2 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > color = 0 ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
p - > start = cent - > currentState . origin [ 2 ] ;
p - > end = cent - > currentState . origin2 [ 2 ] ;
p - > pshader = pshader ;
p - > rotate = qfalse ;
p - > height = 8 ;
p - > width = 8 ;
p - > endheight = 32 ;
p - > endwidth = 32 ;
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
VectorCopy ( cent - > currentState . origin , p - > org ) ;
p - > vel [ 0 ] = p - > vel [ 1 ] = 0 ;
p - > accel [ 0 ] = p - > accel [ 1 ] = p - > accel [ 2 ] = 0 ;
p - > vel [ 2 ] = 5 ;
2002-06-16 20:06:15 +00:00
if ( cent - > currentState . frame = = 1 ) // reverse gravity
2001-08-01 21:07:48 +00:00
p - > vel [ 2 ] * = - 1 ;
p - > roll = 8 + ( crandom ( ) * 4 ) ;
}
2002-06-16 20:06:15 +00:00
void CG_ParticleBulletDebris ( vec3_t org , vec3_t vel , int duration )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > endtime = cg . time + duration ;
2002-06-16 20:06:15 +00:00
p - > startfade = cg . time + duration / 2 ;
2001-08-01 21:07:48 +00:00
p - > color = EMISIVEFADE ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
2001-08-30 09:42:25 +00:00
/*
2002-06-16 20:06:15 +00:00
p - > height = 0.5 ;
p - > width = 0.5 ;
p - > endheight = 0.5 ;
p - > endwidth = 0.5 ;
*/
2001-08-01 21:07:48 +00:00
p - > pshader = cgs . media . tracerShader ;
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
VectorCopy ( org , p - > org ) ;
p - > vel [ 0 ] = vel [ 0 ] ;
p - > vel [ 1 ] = vel [ 1 ] ;
p - > vel [ 2 ] = vel [ 2 ] ;
p - > accel [ 0 ] = p - > accel [ 1 ] = p - > accel [ 2 ] = 0 ;
p - > accel [ 2 ] = - 60 ;
p - > vel [ 2 ] + = - 20 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_ParticleExplosion
= = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_ParticleExplosion ( char * animStr , vec3_t origin , vec3_t vel , int duration , int sizeStart , int sizeEnd )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
int anim ;
2002-06-16 20:06:15 +00:00
if ( animStr < ( char * ) 10 )
CG_Error ( " CG_ParticleExplosion: animStr is probably an index rather than a string " ) ;
2001-08-01 21:07:48 +00:00
// find the animation string
2002-06-16 20:06:15 +00:00
for ( anim = 0 ; shaderAnimNames [ anim ] ; anim + + ) {
if ( ! Q_stricmp ( animStr , shaderAnimNames [ anim ] ) )
2001-08-01 21:07:48 +00:00
break ;
}
if ( ! shaderAnimNames [ anim ] ) {
CG_Error ( " CG_ParticleExplosion: unknown animation string: %s \n " , animStr ) ;
return ;
}
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > alpha = 0.5 ;
p - > alphavel = 0 ;
if ( duration < 0 ) {
duration * = - 1 ;
p - > roll = 0 ;
} else {
2002-06-16 20:06:15 +00:00
p - > roll = crandom ( ) * 179 ;
2001-08-01 21:07:48 +00:00
}
p - > shaderAnim = anim ;
p - > width = sizeStart ;
2002-06-16 20:06:15 +00:00
p - > height = sizeStart * shaderAnimSTRatio [ anim ] ; // for sprites that are stretch in either direction
2001-08-01 21:07:48 +00:00
p - > endheight = sizeEnd ;
2002-06-16 20:06:15 +00:00
p - > endwidth = sizeEnd * shaderAnimSTRatio [ anim ] ;
2001-08-01 21:07:48 +00:00
p - > endtime = cg . time + duration ;
p - > type = P_ANIM ;
2002-06-16 20:06:15 +00:00
VectorCopy ( origin , p - > org ) ;
VectorCopy ( vel , p - > vel ) ;
VectorClear ( p - > accel ) ;
2001-08-01 21:07:48 +00:00
}
// Rafael Shrapnel
2002-06-16 20:06:15 +00:00
void CG_AddParticleShrapnel ( localEntity_t * le )
2001-08-01 21:07:48 +00:00
{
return ;
}
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
// done.
2002-06-16 20:06:15 +00:00
int CG_NewParticleArea ( int num )
2001-08-01 21:07:48 +00:00
{
// const char *str;
char * str ;
char * token ;
int type ;
vec3_t origin , origin2 ;
2002-06-16 20:06:15 +00:00
int i ;
2001-08-01 21:07:48 +00:00
float range = 0 ;
int turb ;
2002-06-16 20:06:15 +00:00
int numparticles ;
int snum ;
str = ( char * ) CG_ConfigString ( num ) ;
2001-08-01 21:07:48 +00:00
if ( ! str [ 0 ] )
return ( 0 ) ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
// returns type 128 64 or 32
2002-06-16 20:06:15 +00:00
token = COM_Parse ( & str ) ;
type = atoi ( token ) ;
2001-08-01 21:07:48 +00:00
if ( type = = 1 )
range = 128 ;
else if ( type = = 2 )
range = 64 ;
else if ( type = = 3 )
range = 32 ;
else if ( type = = 0 )
range = 256 ;
else if ( type = = 4 )
range = 8 ;
else if ( type = = 5 )
range = 16 ;
else if ( type = = 6 )
range = 32 ;
else if ( type = = 7 )
range = 64 ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < 3 ; i + + ) {
token = COM_Parse ( & str ) ;
origin [ i ] = atof ( token ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < 3 ; i + + ) {
token = COM_Parse ( & str ) ;
origin2 [ i ] = atof ( token ) ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
token = COM_Parse ( & str ) ;
numparticles = atoi ( token ) ;
token = COM_Parse ( & str ) ;
turb = atoi ( token ) ;
token = COM_Parse ( & str ) ;
snum = atoi ( token ) ;
for ( i = 0 ; i < numparticles ; i + + ) {
2001-08-01 21:07:48 +00:00
if ( type > = 4 )
2002-06-16 20:06:15 +00:00
CG_ParticleBubble ( cgs . media . waterBubbleShader , origin , origin2 , turb , range , snum ) ;
2001-08-01 21:07:48 +00:00
else
2002-06-16 20:06:15 +00:00
CG_ParticleSnow ( cgs . media . waterBubbleShader , origin , origin2 , turb , range , snum ) ;
2001-08-01 21:07:48 +00:00
}
return ( 1 ) ;
}
2002-06-16 20:06:15 +00:00
void CG_SnowLink ( centity_t * cent , qboolean particleOn )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p , * next ;
2001-08-01 21:07:48 +00:00
int id ;
id = cent - > currentState . frame ;
2002-06-16 20:06:15 +00:00
for ( p = active_particles ; p ; p = next ) {
2001-08-01 21:07:48 +00:00
next = p - > next ;
2002-06-16 20:06:15 +00:00
if ( p - > type = = P_WEATHER | | p - > type = = P_WEATHER_TURBULENT ) {
if ( p - > snum = = id ) {
2001-08-01 21:07:48 +00:00
if ( particleOn )
p - > link = qtrue ;
else
p - > link = qfalse ;
}
}
}
}
2002-06-16 20:06:15 +00:00
void CG_ParticleImpactSmokePuff ( qhandle_t pshader , vec3_t origin )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_ParticleImpactSmokePuff pshader == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > alpha = 0.25 ;
p - > alphavel = 0 ;
2002-06-16 20:06:15 +00:00
p - > roll = crandom ( ) * 179 ;
2001-08-01 21:07:48 +00:00
p - > pshader = pshader ;
p - > endtime = cg . time + 1000 ;
p - > startfade = cg . time + 100 ;
2002-06-16 20:06:15 +00:00
p - > width = rand ( ) % 4 + 8 ;
p - > height = rand ( ) % 4 + 8 ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
p - > endheight = p - > height * 2 ;
2001-08-01 21:07:48 +00:00
p - > endwidth = p - > width * 2 ;
p - > endtime = cg . time + 500 ;
p - > type = P_SMOKE_IMPACT ;
2002-06-16 20:06:15 +00:00
VectorCopy ( origin , p - > org ) ;
2001-08-01 21:07:48 +00:00
VectorSet ( p - > vel , 0 , 0 , 20 ) ;
VectorSet ( p - > accel , 0 , 0 , 20 ) ;
p - > rotate = qtrue ;
}
2002-06-16 20:06:15 +00:00
void CG_Particle_Bleed ( qhandle_t pshader , vec3_t start , vec3_t dir , int fleshEntityNum , int duration )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_Particle_Bleed pshader == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
p - > roll = 0 ;
p - > pshader = pshader ;
p - > endtime = cg . time + duration ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
if ( fleshEntityNum )
p - > startfade = cg . time ;
else
p - > startfade = cg . time + 100 ;
p - > width = 4 ;
p - > height = 4 ;
2002-06-16 20:06:15 +00:00
p - > endheight = 4 + rand ( ) % 3 ;
2001-08-01 21:07:48 +00:00
p - > endwidth = p - > endheight ;
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
VectorCopy ( start , p - > org ) ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = 0 ;
p - > vel [ 1 ] = 0 ;
p - > vel [ 2 ] = - 20 ;
2002-06-16 20:06:15 +00:00
VectorClear ( p - > accel ) ;
2001-08-01 21:07:48 +00:00
p - > rotate = qfalse ;
2002-06-16 20:06:15 +00:00
p - > roll = rand ( ) % 179 ;
2001-08-01 21:07:48 +00:00
p - > color = BLOODRED ;
p - > alpha = 0.75 ;
}
2002-06-16 20:06:15 +00:00
void CG_Particle_OilParticle ( qhandle_t pshader , centity_t * cent )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
int time ;
int time2 ;
float ratio ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
float duration = 1500 ;
2001-08-01 21:07:48 +00:00
time = cg . time ;
time2 = cg . time + cent - > currentState . time ;
2002-06-16 20:06:15 +00:00
ratio = ( float ) 1 - ( ( float ) time / ( float ) time2 ) ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_Particle_OilParticle == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
p - > roll = 0 ;
p - > pshader = pshader ;
p - > endtime = cg . time + duration ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > startfade = p - > endtime ;
p - > width = 1 ;
p - > height = 3 ;
p - > endheight = 3 ;
p - > endwidth = 1 ;
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
VectorCopy ( cent - > currentState . origin , p - > org ) ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = ( cent - > currentState . origin2 [ 0 ] * ( 16 * ratio ) ) ;
p - > vel [ 1 ] = ( cent - > currentState . origin2 [ 1 ] * ( 16 * ratio ) ) ;
p - > vel [ 2 ] = ( cent - > currentState . origin2 [ 2 ] ) ;
p - > snum = 1.0f ;
2002-06-16 20:06:15 +00:00
VectorClear ( p - > accel ) ;
2001-08-01 21:07:48 +00:00
p - > accel [ 2 ] = - 20 ;
p - > rotate = qfalse ;
2002-06-16 20:06:15 +00:00
p - > roll = rand ( ) % 179 ;
2001-08-01 21:07:48 +00:00
p - > alpha = 0.75 ;
}
2002-06-16 20:06:15 +00:00
void CG_Particle_OilSlick ( qhandle_t pshader , centity_t * cent )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_Particle_OilSlick == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
if ( cent - > currentState . angles2 [ 2 ] )
p - > endtime = cg . time + cent - > currentState . angles2 [ 2 ] ;
else
p - > endtime = cg . time + 60000 ;
p - > startfade = p - > endtime ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
p - > roll = 0 ;
p - > pshader = pshader ;
2002-06-16 20:06:15 +00:00
if ( cent - > currentState . angles2 [ 0 ] | | cent - > currentState . angles2 [ 1 ] ) {
2001-08-01 21:07:48 +00:00
p - > width = cent - > currentState . angles2 [ 0 ] ;
p - > height = cent - > currentState . angles2 [ 0 ] ;
p - > endheight = cent - > currentState . angles2 [ 1 ] ;
p - > endwidth = cent - > currentState . angles2 [ 1 ] ;
2002-06-16 20:06:15 +00:00
} else {
2001-08-01 21:07:48 +00:00
p - > width = 8 ;
p - > height = 8 ;
p - > endheight = 16 ;
p - > endwidth = 16 ;
}
p - > type = P_FLAT_SCALEUP ;
p - > snum = 1.0 ;
2002-06-16 20:06:15 +00:00
VectorCopy ( cent - > currentState . origin , p - > org ) ;
p - > org [ 2 ] + = 0.55 + ( crandom ( ) * 0.5 ) ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = 0 ;
p - > vel [ 1 ] = 0 ;
p - > vel [ 2 ] = 0 ;
2002-06-16 20:06:15 +00:00
VectorClear ( p - > accel ) ;
2001-08-01 21:07:48 +00:00
p - > rotate = qfalse ;
2002-06-16 20:06:15 +00:00
p - > roll = rand ( ) % 179 ;
2001-08-01 21:07:48 +00:00
p - > alpha = 0.75 ;
}
2002-06-16 20:06:15 +00:00
void CG_OilSlickRemove ( centity_t * cent )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p , * next ;
int id ;
2001-08-01 21:07:48 +00:00
id = 1.0f ;
if ( ! id )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_OilSlickRevove NULL id \n " ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
for ( p = active_particles ; p ; p = next ) {
2001-08-01 21:07:48 +00:00
next = p - > next ;
2002-06-16 20:06:15 +00:00
if ( p - > type = = P_FLAT_SCALEUP ) {
if ( p - > snum = = id ) {
2001-08-01 21:07:48 +00:00
p - > endtime = cg . time + 100 ;
p - > startfade = p - > endtime ;
p - > type = P_FLAT_SCALEUP_FADE ;
}
}
}
}
2002-06-16 20:06:15 +00:00
qboolean ValidBloodPool ( vec3_t start )
2001-08-01 21:07:48 +00:00
{
# define EXTRUDE_DIST 0.5
2002-06-16 20:06:15 +00:00
vec3_t angles ;
vec3_t right , up ;
vec3_t this_pos , x_pos , center_pos , end_pos ;
float x , y ;
float fwidth , fheight ;
trace_t trace ;
vec3_t normal ;
2001-08-01 21:07:48 +00:00
fwidth = 16 ;
fheight = 16 ;
2002-06-16 20:06:15 +00:00
VectorSet ( normal , 0 , 0 , 1 ) ;
vectoangles ( normal , angles ) ;
AngleVectors ( angles , NULL , right , up ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
VectorMA ( start , EXTRUDE_DIST , normal , center_pos ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
for ( x = - fwidth / 2 ; x < fwidth ; x + = fwidth ) {
VectorMA ( center_pos , x , right , x_pos ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
for ( y = - fheight / 2 ; y < fheight ; y + = fheight ) {
VectorMA ( x_pos , y , up , this_pos ) ;
VectorMA ( this_pos , - EXTRUDE_DIST * 2 , normal , end_pos ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
CG_Trace ( & trace , this_pos , NULL , NULL , end_pos , - 1 , CONTENTS_SOLID ) ;
2001-08-01 21:07:48 +00:00
2012-12-12 20:46:23 +00:00
if ( trace . entityNum < ( MAX_GENTITIES - 1 ) ) // may only land on world
2001-08-01 21:07:48 +00:00
return qfalse ;
if ( ! ( ! trace . startsolid & & trace . fraction < 1 ) )
return qfalse ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
}
}
return qtrue ;
}
2002-06-16 20:06:15 +00:00
void CG_BloodPool ( localEntity_t * le , qhandle_t pshader , trace_t * tr )
{
cparticle_t * p ;
qboolean legit ;
vec3_t start ;
float rndSize ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_BloodPool pshader == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
2002-06-16 20:06:15 +00:00
VectorCopy ( tr - > endpos , start ) ;
legit = ValidBloodPool ( start ) ;
if ( ! legit )
2001-08-01 21:07:48 +00:00
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > endtime = cg . time + 3000 ;
p - > startfade = p - > endtime ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
p - > roll = 0 ;
p - > pshader = pshader ;
2002-06-16 20:06:15 +00:00
rndSize = 0.4 + random ( ) * 0.6 ;
p - > width = 8 * rndSize ;
p - > height = 8 * rndSize ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
p - > endheight = 16 * rndSize ;
p - > endwidth = 16 * rndSize ;
2001-08-01 21:07:48 +00:00
p - > type = P_FLAT_SCALEUP ;
2002-06-16 20:06:15 +00:00
VectorCopy ( start , p - > org ) ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = 0 ;
p - > vel [ 1 ] = 0 ;
p - > vel [ 2 ] = 0 ;
2002-06-16 20:06:15 +00:00
VectorClear ( p - > accel ) ;
2001-08-01 21:07:48 +00:00
p - > rotate = qfalse ;
2002-06-16 20:06:15 +00:00
p - > roll = rand ( ) % 179 ;
2001-08-01 21:07:48 +00:00
p - > alpha = 0.75 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > color = BLOODRED ;
}
# define NORMALSIZE 16
# define LARGESIZE 32
2002-06-16 20:06:15 +00:00
void CG_ParticleBloodCloud ( centity_t * cent , vec3_t origin , vec3_t dir )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
float length ;
float dist ;
float crittersize ;
vec3_t angles , forward ;
vec3_t point ;
cparticle_t * p ;
int i ;
2001-08-01 21:07:48 +00:00
dist = 0 ;
2002-06-16 20:06:15 +00:00
length = VectorLength ( dir ) ;
vectoangles ( dir , angles ) ;
AngleVectors ( angles , forward , NULL , NULL ) ;
2001-08-01 21:07:48 +00:00
crittersize = LARGESIZE ;
if ( length )
dist = length / crittersize ;
if ( dist < 1 )
dist = 1 ;
2002-06-16 20:06:15 +00:00
VectorCopy ( origin , point ) ;
for ( i = 0 ; i < dist ; i + + ) {
VectorMA ( point , crittersize , forward , point ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
p - > roll = 0 ;
p - > pshader = cgs . media . smokePuffShader ;
p - > endtime = cg . time + 350 + ( crandom ( ) * 100 ) ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > startfade = cg . time ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > width = LARGESIZE ;
p - > height = LARGESIZE ;
p - > endheight = LARGESIZE ;
p - > endwidth = LARGESIZE ;
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
VectorCopy ( origin , p - > org ) ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] = 0 ;
p - > vel [ 1 ] = 0 ;
p - > vel [ 2 ] = - 1 ;
2002-06-16 20:06:15 +00:00
VectorClear ( p - > accel ) ;
2001-08-01 21:07:48 +00:00
p - > rotate = qfalse ;
2002-06-16 20:06:15 +00:00
p - > roll = rand ( ) % 179 ;
2001-08-01 21:07:48 +00:00
p - > color = BLOODRED ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > alpha = 0.75 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
}
}
2001-08-30 09:42:25 +00:00
// Elder: modified to suit our impact marks
2002-06-16 20:06:15 +00:00
void CG_ParticleSparks ( vec3_t org , vec3_t vel , int duration , float x , float y , float speed , float scale )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
2006-04-14 18:16:31 +00:00
{
CG_Printf ( S_COLOR_RED " No particles left for sparks!!! \n " ) ;
2001-08-01 21:07:48 +00:00
return ;
2006-04-14 18:16:31 +00:00
}
2001-08-01 21:07:48 +00:00
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > endtime = cg . time + duration ;
2002-06-16 20:06:15 +00:00
p - > startfade = cg . time + duration / 2 ;
2001-08-01 21:07:48 +00:00
p - > color = EMISIVEFADE ;
p - > alpha = 0.4f ;
p - > alphavel = 0 ;
2001-08-30 09:42:25 +00:00
/*
2002-06-16 20:06:15 +00:00
// Elder: old settings
p - > height = 0.5 ;
p - > width = 0.5 ;
p - > endheight = 0.5 ;
p - > endwidth = 0.5 ;
*/
2001-08-30 09:42:25 +00:00
p - > height = 1.5 * scale ;
p - > width = 1.5 * scale ;
p - > endheight = 0.75 * scale ;
p - > endwidth = 0.75 * scale ;
2001-08-01 21:07:48 +00:00
p - > pshader = cgs . media . tracerShader ;
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
VectorCopy ( org , p - > org ) ;
p - > org [ 0 ] + = ( crandom ( ) * x ) ;
p - > org [ 1 ] + = ( crandom ( ) * y ) ;
p - > vel [ 0 ] = vel [ 0 ] ;
p - > vel [ 1 ] = vel [ 1 ] ;
p - > vel [ 2 ] = vel [ 2 ] ;
2001-08-30 09:42:25 +00:00
// Elder: old settings
//p->accel[0] = p->accel[1] = p->accel[2] = 0;
p - > accel [ 0 ] = p - > accel [ 1 ] = 0 ;
p - > accel [ 2 ] = - PARTICLE_GRAVITY * 4 ;
2001-08-01 21:07:48 +00:00
p - > vel [ 0 ] + = ( crandom ( ) * 4 ) ;
p - > vel [ 1 ] + = ( crandom ( ) * 4 ) ;
2002-06-16 20:06:15 +00:00
p - > vel [ 2 ] + = ( 20 + ( crandom ( ) * 10 ) ) * speed ;
p - > accel [ 0 ] = crandom ( ) * 4 ;
p - > accel [ 1 ] = crandom ( ) * 4 ;
2001-08-01 21:07:48 +00:00
}
2003-07-30 16:05:47 +00:00
//Makro - snow
void CG_ParticleHitSnow ( vec3_t org , vec3_t vel , int duration , float x , float y , float speed , float scale )
{
cparticle_t * p ;
if ( ! free_particles )
2006-04-14 18:16:31 +00:00
{
CG_Printf ( S_COLOR_RED " No particles left for sparks!!! \n " ) ;
2003-07-30 16:05:47 +00:00
return ;
2006-04-14 18:16:31 +00:00
}
2003-07-30 16:05:47 +00:00
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > endtime = cg . time + duration ;
2004-01-26 21:26:09 +00:00
p - > startfade = cg . time + duration * 0.75 ;
2003-07-30 16:05:47 +00:00
2004-01-26 21:26:09 +00:00
//p->color = GREY75;
p - > color = 0 ;
p - > alpha = 0.8f ;
p - > alphavel = p - > alpha / ( ( p - > endtime - p - > startfade ) * .001f ) ;
2003-07-30 16:05:47 +00:00
p - > height = 4 ;
p - > width = 4 ;
2004-01-26 21:26:09 +00:00
p - > endheight = 16 ;
p - > endwidth = 16 ;
2003-07-30 16:05:47 +00:00
2004-01-26 21:26:09 +00:00
p - > pshader = cgs . media . snowImpactShader ;
2003-07-30 16:05:47 +00:00
p - > type = P_SMOKE ;
VectorCopy ( org , p - > org ) ;
p - > org [ 0 ] + = ( crandom ( ) * x ) ;
p - > org [ 1 ] + = ( crandom ( ) * y ) ;
p - > vel [ 0 ] = vel [ 0 ] ;
p - > vel [ 1 ] = vel [ 1 ] ;
p - > vel [ 2 ] = vel [ 2 ] ;
2004-01-26 21:26:09 +00:00
p - > accel [ 0 ] = crandom ( ) * 4 ;
p - > accel [ 1 ] = crandom ( ) * 4 ;
2003-07-30 16:05:47 +00:00
p - > accel [ 2 ] = - PARTICLE_GRAVITY * 4 ;
2004-01-26 21:26:09 +00:00
p - > vel [ 0 ] + = ( crandom ( ) * 8 ) ;
p - > vel [ 1 ] + = ( crandom ( ) * 8 ) ;
2003-07-30 16:05:47 +00:00
//p->vel[2] += (20 + (crandom() * 10)) * speed;
}
//Makro - grass
void CG_ParticleHitGrass ( vec3_t org , vec3_t vel , int duration , float x , float y , float speed , float scale )
{
cparticle_t * p ;
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > endtime = cg . time + duration ;
p - > startfade = cg . time + duration * 0.75 ;
p - > color = GRASS ;
p - > alpha = 0.5f ;
p - > alphavel = 0 ;
p - > height = 4 ;
p - > width = 4 ;
p - > endheight = 8 ;
p - > endwidth = 8 ;
p - > pshader = cgs . media . smokePuffShader ;
p - > type = P_SMOKE ;
VectorCopy ( org , p - > org ) ;
p - > org [ 0 ] + = ( crandom ( ) * x ) ;
p - > org [ 1 ] + = ( crandom ( ) * y ) ;
p - > vel [ 0 ] = vel [ 0 ] ;
p - > vel [ 1 ] = vel [ 1 ] ;
p - > vel [ 2 ] = vel [ 2 ] ;
p - > accel [ 0 ] = crandom ( ) * 6 ;
p - > accel [ 1 ] = crandom ( ) * 6 ;
p - > accel [ 2 ] = - PARTICLE_GRAVITY * 4 ;
p - > vel [ 0 ] + = ( crandom ( ) * 12 ) ;
p - > vel [ 1 ] + = ( crandom ( ) * 12 ) ;
//p->vel[2] += (20 + (crandom() * 10)) * speed;
}
2004-01-26 21:26:09 +00:00
//Makro - wall
void CG_ParticleHitWall ( vec3_t org , vec3_t vel , int duration , float x , float y , float speed , float scale )
{
cparticle_t * p ;
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > endtime = cg . time + duration ;
p - > startfade = cg . time + duration * 0.85 ;
p - > color = 0 ;
p - > alpha = 1.0f ;
p - > alphavel = 0 ;
p - > roll = rand ( ) % 179 ;
p - > height = 3 ;
p - > width = 3 ;
p - > endheight = 2 ;
p - > endwidth = 2 ;
p - > pshader = cgs . media . particleImpactShader ;
p - > type = P_SMOKE ;
VectorCopy ( org , p - > org ) ;
p - > org [ 0 ] + = ( crandom ( ) * x ) ;
p - > org [ 1 ] + = ( crandom ( ) * y ) ;
p - > vel [ 0 ] = vel [ 0 ] ;
p - > vel [ 1 ] = vel [ 1 ] ;
p - > vel [ 2 ] = vel [ 2 ] ;
p - > accel [ 0 ] = crandom ( ) * 6 ;
p - > accel [ 1 ] = crandom ( ) * 6 ;
p - > accel [ 2 ] = - PARTICLE_GRAVITY * 4 ;
p - > vel [ 0 ] + = ( crandom ( ) * 24 ) ;
p - > vel [ 1 ] + = ( crandom ( ) * 24 ) ;
p - > vel [ 2 ] + = ( crandom ( ) * 24 ) ;
}
2002-06-16 20:06:15 +00:00
void CG_ParticleDust ( centity_t * cent , vec3_t origin , vec3_t dir )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
float length ;
float dist ;
float crittersize ;
vec3_t angles , forward ;
vec3_t point ;
cparticle_t * p ;
int i ;
2001-08-01 21:07:48 +00:00
dist = 0 ;
2002-06-16 20:06:15 +00:00
VectorNegate ( dir , dir ) ;
length = VectorLength ( dir ) ;
vectoangles ( dir , angles ) ;
AngleVectors ( angles , forward , NULL , NULL ) ;
2001-08-01 21:07:48 +00:00
crittersize = LARGESIZE ;
if ( length )
dist = length / crittersize ;
if ( dist < 1 )
dist = 1 ;
2002-06-16 20:06:15 +00:00
VectorCopy ( origin , point ) ;
for ( i = 0 ; i < dist ; i + + ) {
VectorMA ( point , crittersize , forward , point ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > alpha = 5.0 ;
p - > alphavel = 0 ;
p - > roll = 0 ;
p - > pshader = cgs . media . smokePuffShader ;
// RF, stay around for long enough to expand and dissipate naturally
if ( length )
p - > endtime = cg . time + 4500 + ( crandom ( ) * 3500 ) ;
else
p - > endtime = cg . time + 750 + ( crandom ( ) * 500 ) ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > startfade = cg . time ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
p - > width = LARGESIZE ;
p - > height = LARGESIZE ;
// RF, expand while falling
2002-06-16 20:06:15 +00:00
p - > endheight = LARGESIZE * 3.0 ;
p - > endwidth = LARGESIZE * 3.0 ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
if ( ! length ) {
2001-08-01 21:07:48 +00:00
p - > width * = 0.2f ;
p - > height * = 0.2f ;
p - > endheight = NORMALSIZE ;
p - > endwidth = NORMALSIZE ;
}
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
VectorCopy ( point , p - > org ) ;
p - > vel [ 0 ] = crandom ( ) * 6 ;
p - > vel [ 1 ] = crandom ( ) * 6 ;
p - > vel [ 2 ] = random ( ) * 20 ;
2001-08-01 21:07:48 +00:00
// RF, add some gravity/randomness
2002-06-16 20:06:15 +00:00
p - > accel [ 0 ] = crandom ( ) * 3 ;
p - > accel [ 1 ] = crandom ( ) * 3 ;
p - > accel [ 2 ] = - PARTICLE_GRAVITY * 0.4 ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
VectorClear ( p - > accel ) ;
2001-08-01 21:07:48 +00:00
p - > rotate = qfalse ;
2002-06-16 20:06:15 +00:00
p - > roll = rand ( ) % 179 ;
2001-08-01 21:07:48 +00:00
p - > alpha = 0.75 ;
2002-06-16 20:06:15 +00:00
2001-08-01 21:07:48 +00:00
}
}
2002-06-16 20:06:15 +00:00
void CG_ParticleMisc ( qhandle_t pshader , vec3_t origin , int size , int duration , float alpha )
2001-08-01 21:07:48 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2001-08-01 21:07:48 +00:00
if ( ! pshader )
2003-03-29 18:53:41 +00:00
CG_Printf ( " ^1CG_ParticleImpactSmokePuff pshader == ZERO! \n " ) ;
2001-08-01 21:07:48 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > alpha = 1.0 ;
p - > alphavel = 0 ;
2002-06-16 20:06:15 +00:00
p - > roll = rand ( ) % 179 ;
2001-08-01 21:07:48 +00:00
p - > pshader = pshader ;
if ( duration > 0 )
p - > endtime = cg . time + duration ;
else
p - > endtime = duration ;
p - > startfade = cg . time ;
p - > width = size ;
p - > height = size ;
p - > endheight = size ;
p - > endwidth = size ;
p - > type = P_SPRITE ;
2002-06-16 20:06:15 +00:00
VectorCopy ( origin , p - > org ) ;
2001-08-01 21:07:48 +00:00
p - > rotate = qfalse ;
}
2002-06-16 20:06:15 +00:00
void CG_ParticleAir ( vec3_t org , vec3_t vel , int duration , float alpha , float speed , float scale )
2002-04-23 06:06:19 +00:00
{
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2002-04-23 06:06:19 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
2002-08-21 03:45:36 +00:00
p - > mtime = cg . time ;
2002-06-16 20:06:15 +00:00
2002-04-23 06:06:19 +00:00
p - > endtime = cg . time + duration ;
2002-06-16 20:06:15 +00:00
p - > startfade = cg . time + duration / 1.5 ;
if ( rand ( ) % 2 )
2002-04-23 06:06:19 +00:00
p - > color = DARK_BLUE_WATER ;
else
p - > color = LIGHT_BLUE_WATER ;
2002-06-09 05:16:58 +00:00
p - > alpha = alpha ;
2002-04-23 06:06:19 +00:00
p - > alphavel = p - > alpha / ( ( p - > endtime - p - > startfade ) * .0001f ) ;
p - > height = 1.0 * scale ;
p - > width = 1.0 * scale ;
p - > endheight = 1.0 * scale ;
p - > endwidth = 1.0 * scale ;
2002-06-16 20:06:15 +00:00
2002-06-09 05:16:58 +00:00
p - > pshader = cgs . media . waterBubbleShader ;
2002-04-23 06:06:19 +00:00
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
2002-04-23 06:06:19 +00:00
VectorCopy ( org , p - > org ) ;
2002-05-26 05:14:14 +00:00
p - > vel [ 0 ] = vel [ 0 ] * speed ;
p - > vel [ 1 ] = vel [ 1 ] * speed ;
p - > vel [ 2 ] = vel [ 2 ] * speed ;
2002-04-23 06:06:19 +00:00
p - > accel [ 0 ] = p - > accel [ 1 ] = 0 ;
2002-06-09 05:16:58 +00:00
p - > accel [ 2 ] = PARTICLE_GRAVITY * 8 ;
2002-04-23 06:06:19 +00:00
2002-06-09 05:16:58 +00:00
p - > vel [ 0 ] + = ( crandom ( ) * 40 ) ;
p - > vel [ 1 ] + = ( crandom ( ) * 40 ) ;
2002-06-16 20:06:15 +00:00
p - > vel [ 2 ] + = ( 20 + ( crandom ( ) * 40 ) ) * speed ;
2002-04-23 06:06:19 +00:00
}
2002-06-16 20:06:15 +00:00
void CG_ParticleSteam ( vec3_t org , vec3_t vel , int duration , float alpha , float speed , float scale , int Shader )
2002-04-23 06:06:19 +00:00
{
2002-08-21 03:45:36 +00:00
trace_t tr ;
vec3_t end , dist ;
2002-06-16 20:06:15 +00:00
cparticle_t * p ;
2002-04-23 06:06:19 +00:00
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
2002-08-21 03:45:36 +00:00
p - > mtime = cg . time ;
2002-08-22 07:06:37 +00:00
p - > epsilon = 1.1f ;
2002-06-16 20:06:15 +00:00
2002-04-23 06:06:19 +00:00
p - > endtime = cg . time + duration ;
p - > startfade = cg . time ;
2002-06-16 20:06:15 +00:00
2002-04-23 06:06:19 +00:00
p - > alpha = alpha * 0.5f ;
p - > alphavel = p - > alpha / ( ( p - > endtime - p - > startfade ) * .0001f ) ;
2002-06-16 20:06:15 +00:00
p - > width = LARGESIZE * 0.06f ;
p - > height = LARGESIZE * 0.06f ;
p - > endheight = LARGESIZE * 0.70f ;
p - > endwidth = LARGESIZE * 0.70f ;
2002-04-23 06:06:19 +00:00
p - > rotate = qtrue ;
2002-08-25 23:20:18 +00:00
p - > roll = crandom ( ) * 20 ;
2002-04-23 06:06:19 +00:00
2002-05-26 05:14:14 +00:00
p - > pshader = Shader ;
2002-04-29 06:13:31 +00:00
2002-04-23 06:06:19 +00:00
p - > type = P_SMOKE ;
2002-06-16 20:06:15 +00:00
2002-04-23 06:06:19 +00:00
VectorCopy ( org , p - > org ) ;
2002-06-16 20:06:15 +00:00
p - > vel [ 0 ] = vel [ 0 ] * speed ;
p - > vel [ 1 ] = vel [ 1 ] * speed ;
p - > vel [ 2 ] = vel [ 2 ] * speed ;
2002-04-23 06:06:19 +00:00
p - > vel [ 0 ] + = ( crandom ( ) * 12 ) ;
p - > vel [ 1 ] + = ( crandom ( ) * 12 ) ;
p - > vel [ 2 ] + = ( crandom ( ) * 12 ) ;
2002-08-21 03:45:36 +00:00
// reflection stuff
VectorMA ( org , 300 , p - > vel , end ) ;
CG_Trace ( & tr , org , NULL , NULL , end , 0 , MASK_SOLID ) ;
VectorSubtract ( org , tr . endpos , dist ) ;
p - > reflectdistance = VectorLength ( dist ) ;
VectorCopy ( tr . plane . normal , p - > reflectnormal ) ;
2002-04-23 06:06:19 +00:00
}
2002-12-02 19:52:05 +00:00
void CG_ParticleWater ( vec3_t org , vec3_t vel , int duration , float alpha , float speed , float scale )
{
cparticle_t * p ;
if ( ! free_particles )
return ;
p = free_particles ;
free_particles = p - > next ;
p - > next = active_particles ;
active_particles = p ;
p - > time = cg . time ;
p - > mtime = cg . time ;
p - > endtime = cg . time + duration ;
p - > startfade = cg . time + duration / 1.5 ;
if ( rand ( ) % 2 )
p - > color = DARK_BLUE_WATER ;
else
p - > color = LIGHT_BLUE_WATER ;
p - > alpha = alpha ;
p - > alphavel = p - > alpha / ( ( p - > endtime - p - > startfade ) * .0001f ) ;
p - > height = scale ;
p - > width = scale ;
p - > endheight = scale ;
p - > endwidth = scale ;
p - > pshader = cgs . media . smokePuffShader ;
p - > type = P_SMOKE ;
VectorCopy ( org , p - > org ) ;
p - > vel [ 0 ] = vel [ 0 ] * speed ;
p - > vel [ 1 ] = vel [ 1 ] * speed ;
p - > vel [ 2 ] = vel [ 2 ] * speed ;
p - > accel [ 0 ] = p - > accel [ 1 ] = 0 ;
p - > accel [ 2 ] = - PARTICLE_GRAVITY * 8 ;
p - > vel [ 0 ] + = ( crandom ( ) * 40 ) ;
p - > vel [ 1 ] + = ( crandom ( ) * 40 ) ;
p - > vel [ 2 ] + = ( 20 + ( crandom ( ) * 40 ) ) * speed ;
}