1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324 |
- /*
- Copyright (C) 1997-2001 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- // cl_newfx.c -- MORE entity effects parsing and management
- #include "client.h"
- extern cparticle_t *active_particles, *free_particles;
- extern cparticle_t particles[MAX_PARTICLES];
- extern int cl_numparticles;
- extern cvar_t *vid_ref;
- extern void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up);
- /*
- ======
- vectoangles2 - this is duplicated in the game DLL, but I need it here.
- ======
- */
- void vectoangles2 (vec3_t value1, vec3_t angles)
- {
- float forward;
- float yaw, pitch;
-
- if (value1[1] == 0 && value1[0] == 0)
- {
- yaw = 0;
- if (value1[2] > 0)
- pitch = 90;
- else
- pitch = 270;
- }
- else
- {
- // PMM - fixed to correct for pitch of 0
- if (value1[0])
- yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
- else if (value1[1] > 0)
- yaw = 90;
- else
- yaw = 270;
- if (yaw < 0)
- yaw += 360;
- forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
- pitch = (atan2(value1[2], forward) * 180 / M_PI);
- if (pitch < 0)
- pitch += 360;
- }
- angles[PITCH] = -pitch;
- angles[YAW] = yaw;
- angles[ROLL] = 0;
- }
- //=============
- //=============
- void CL_Flashlight (int ent, vec3_t pos)
- {
- cdlight_t *dl;
- dl = CL_AllocDlight (ent);
- VectorCopy (pos, dl->origin);
- dl->radius = 400;
- dl->minlight = 250;
- dl->die = cl.time + 100;
- dl->color[0] = 1;
- dl->color[1] = 1;
- dl->color[2] = 1;
- }
- /*
- ======
- CL_ColorFlash - flash of light
- ======
- */
- void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float b)
- {
- cdlight_t *dl;
- if((vidref_val == VIDREF_SOFT) && ((r < 0) || (g<0) || (b<0)))
- {
- intensity = -intensity;
- r = -r;
- g = -g;
- b = -b;
- }
- dl = CL_AllocDlight (ent);
- VectorCopy (pos, dl->origin);
- dl->radius = intensity;
- dl->minlight = 250;
- dl->die = cl.time + 100;
- dl->color[0] = r;
- dl->color[1] = g;
- dl->color[2] = b;
- }
- /*
- ======
- CL_DebugTrail
- ======
- */
- void CL_DebugTrail (vec3_t start, vec3_t end)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- // int j;
- cparticle_t *p;
- float dec;
- vec3_t right, up;
- // int i;
- // float d, c, s;
- // vec3_t dir;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- MakeNormalVectors (vec, right, up);
- // VectorScale(vec, RT2_SKIP, vec);
- // dec = 1.0;
- // dec = 0.75;
- dec = 3;
- VectorScale (vec, dec, vec);
- VectorCopy (start, move);
- while (len > 0)
- {
- len -= dec;
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- VectorClear (p->accel);
- VectorClear (p->vel);
- p->alpha = 1.0;
- p->alphavel = -0.1;
- // p->alphavel = 0;
- p->color = 0x74 + (rand()&7);
- VectorCopy (move, p->org);
- /*
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + crand()*2;
- p->vel[j] = crand()*3;
- p->accel[j] = 0;
- }
- */
- VectorAdd (move, vec, move);
- }
- }
- /*
- ===============
- CL_SmokeTrail
- ===============
- */
- void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int j;
- cparticle_t *p;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- VectorScale (vec, spacing, vec);
- // FIXME: this is a really silly way to have a loop
- while (len > 0)
- {
- len -= spacing;
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (1+frand()*0.5);
- p->color = colorStart + (rand() % colorRun);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + crand()*3;
- p->accel[j] = 0;
- }
- p->vel[2] = 20 + crand()*5;
- VectorAdd (move, vec, move);
- }
- }
- void CL_ForceWall (vec3_t start, vec3_t end, int color)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int j;
- cparticle_t *p;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- VectorScale (vec, 4, vec);
- // FIXME: this is a really silly way to have a loop
- while (len > 0)
- {
- len -= 4;
- if (!free_particles)
- return;
-
- if (frand() > 0.3)
- {
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (3.0+frand()*0.5);
- p->color = color;
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + crand()*3;
- p->accel[j] = 0;
- }
- p->vel[0] = 0;
- p->vel[1] = 0;
- p->vel[2] = -40 - (crand()*10);
- }
- VectorAdd (move, vec, move);
- }
- }
- void CL_FlameEffects (centity_t *ent, vec3_t origin)
- {
- int n, count;
- int j;
- cparticle_t *p;
- count = rand() & 0xF;
- for(n=0;n<count;n++)
- {
- if (!free_particles)
- return;
-
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
-
- VectorClear (p->accel);
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (1+frand()*0.2);
- p->color = 226 + (rand() % 4);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = origin[j] + crand()*5;
- p->vel[j] = crand()*5;
- }
- p->vel[2] = crand() * -10;
- p->accel[2] = -PARTICLE_GRAVITY;
- }
- count = rand() & 0x7;
- for(n=0;n<count;n++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (1+frand()*0.5);
- p->color = 0 + (rand() % 4);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = origin[j] + crand()*3;
- }
- p->vel[2] = 20 + crand()*5;
- }
- }
- /*
- ===============
- CL_GenericParticleEffect
- ===============
- */
- void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel)
- {
- int i, j;
- cparticle_t *p;
- float d;
- for (i=0 ; i<count ; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- if (numcolors > 1)
- p->color = color + (rand() & numcolors);
- else
- p->color = color;
- d = rand() & dirspread;
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
- p->vel[j] = crand()*20;
- }
- p->accel[0] = p->accel[1] = 0;
- p->accel[2] = -PARTICLE_GRAVITY;
- // VectorCopy (accel, p->accel);
- p->alpha = 1.0;
- p->alphavel = -1.0 / (0.5 + frand()*alphavel);
- // p->alphavel = alphavel;
- }
- }
- /*
- ===============
- CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns)
- ===============
- */
- void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int i, j;
- cparticle_t *p;
- float dec;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- dec = dist;
- VectorScale (vec, dec, vec);
- for (i=0 ; i<len ; i+=dec)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (1+frand()*0.1);
- p->color = 4 + (rand()&7);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + crand()*2;
- p->vel[j] = crand()*10;
- }
- p->org[2] -= 4;
- // p->vel[2] += 6;
- p->vel[2] += 20;
- VectorAdd (move, vec, move);
- }
- }
- //#define CORKSCREW 1
- //#define DOUBLE_SCREW 1
- #define RINGS 1
- //#define SPRAY 1
- #ifdef CORKSCREW
- void CL_Heatbeam (vec3_t start, vec3_t end)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int j,k;
- cparticle_t *p;
- vec3_t right, up;
- int i;
- float d, c, s;
- vec3_t dir;
- float ltime;
- float step = 5.0;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- // MakeNormalVectors (vec, right, up);
- VectorCopy (cl.v_right, right);
- VectorCopy (cl.v_up, up);
- VectorMA (move, -1, right, move);
- VectorMA (move, -1, up, move);
- VectorScale (vec, step, vec);
- ltime = (float) cl.time/1000.0;
- // for (i=0 ; i<len ; i++)
- for (i=0 ; i<len ; i+=step)
- {
- d = i * 0.1 - fmod(ltime,16.0)*M_PI;
- c = cos(d)/1.75;
- s = sin(d)/1.75;
- #ifdef DOUBLE_SCREW
- for (k=-1; k<2; k+=2)
- {
- #else
- k=1;
- #endif
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
-
- p->time = cl.time;
- VectorClear (p->accel);
- p->alpha = 0.5;
- // p->alphavel = -1.0 / (1+frand()*0.2);
- // only last one frame!
- p->alphavel = INSTANT_PARTICLE;
- // p->color = 0x74 + (rand()&7);
- // p->color = 223 - (rand()&7);
- p->color = 223;
- // p->color = 240;
- // trim it so it looks like it's starting at the origin
- if (i < 10)
- {
- VectorScale (right, c*(i/10.0)*k, dir);
- VectorMA (dir, s*(i/10.0)*k, up, dir);
- }
- else
- {
- VectorScale (right, c*k, dir);
- VectorMA (dir, s*k, up, dir);
- }
-
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + dir[j]*3;
- // p->vel[j] = dir[j]*6;
- p->vel[j] = 0;
- }
- #ifdef DOUBLE_SCREW
- }
- #endif
- VectorAdd (move, vec, move);
- }
- }
- #endif
- #ifdef RINGS
- //void CL_Heatbeam (vec3_t start, vec3_t end)
- void CL_Heatbeam (vec3_t start, vec3_t forward)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int j;
- cparticle_t *p;
- vec3_t right, up;
- int i;
- float c, s;
- vec3_t dir;
- float ltime;
- float step = 32.0, rstep;
- float start_pt;
- float rot;
- float variance;
- vec3_t end;
- VectorMA (start, 4096, forward, end);
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- // FIXME - pmm - these might end up using old values?
- // MakeNormalVectors (vec, right, up);
- VectorCopy (cl.v_right, right);
- VectorCopy (cl.v_up, up);
- if (vidref_val == VIDREF_GL)
- { // GL mode
- VectorMA (move, -0.5, right, move);
- VectorMA (move, -0.5, up, move);
- }
- // otherwise assume SOFT
- ltime = (float) cl.time/1000.0;
- start_pt = fmod(ltime*96.0,step);
- VectorMA (move, start_pt, vec, move);
- VectorScale (vec, step, vec);
- // Com_Printf ("%f\n", ltime);
- rstep = M_PI/10.0;
- for (i=start_pt ; i<len ; i+=step)
- {
- if (i>step*5) // don't bother after the 5th ring
- break;
- for (rot = 0; rot < M_PI*2; rot += rstep)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
-
- p->time = cl.time;
- VectorClear (p->accel);
- // rot+= fmod(ltime, 12.0)*M_PI;
- // c = cos(rot)/2.0;
- // s = sin(rot)/2.0;
- // variance = 0.4 + ((float)rand()/(float)RAND_MAX) *0.2;
- variance = 0.5;
- c = cos(rot)*variance;
- s = sin(rot)*variance;
-
- // trim it so it looks like it's starting at the origin
- if (i < 10)
- {
- VectorScale (right, c*(i/10.0), dir);
- VectorMA (dir, s*(i/10.0), up, dir);
- }
- else
- {
- VectorScale (right, c, dir);
- VectorMA (dir, s, up, dir);
- }
-
- p->alpha = 0.5;
- // p->alphavel = -1.0 / (1+frand()*0.2);
- p->alphavel = -1000.0;
- // p->color = 0x74 + (rand()&7);
- p->color = 223 - (rand()&7);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + dir[j]*3;
- // p->vel[j] = dir[j]*6;
- p->vel[j] = 0;
- }
- }
- VectorAdd (move, vec, move);
- }
- }
- #endif
- #ifdef SPRAY
- void CL_Heatbeam (vec3_t start, vec3_t end)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int j;
- cparticle_t *p;
- vec3_t forward, right, up;
- int i;
- float d, c, s;
- vec3_t dir;
- float ltime;
- float step = 32.0, rstep;
- float start_pt;
- float rot;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- // MakeNormalVectors (vec, right, up);
- VectorCopy (cl.v_forward, forward);
- VectorCopy (cl.v_right, right);
- VectorCopy (cl.v_up, up);
- VectorMA (move, -0.5, right, move);
- VectorMA (move, -0.5, up, move);
- for (i=0; i<8; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
-
- p->time = cl.time;
- VectorClear (p->accel);
-
- d = crand()*M_PI;
- c = cos(d)*30;
- s = sin(d)*30;
- p->alpha = 1.0;
- p->alphavel = -5.0 / (1+frand());
- p->color = 223 - (rand()&7);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j];
- }
- VectorScale (vec, 450, p->vel);
- VectorMA (p->vel, c, right, p->vel);
- VectorMA (p->vel, s, up, p->vel);
- }
- /*
- ltime = (float) cl.time/1000.0;
- start_pt = fmod(ltime*16.0,step);
- VectorMA (move, start_pt, vec, move);
- VectorScale (vec, step, vec);
- // Com_Printf ("%f\n", ltime);
- rstep = M_PI/12.0;
- for (i=start_pt ; i<len ; i+=step)
- {
- if (i>step*5) // don't bother after the 5th ring
- break;
- for (rot = 0; rot < M_PI*2; rot += rstep)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
-
- p->time = cl.time;
- VectorClear (p->accel);
- // rot+= fmod(ltime, 12.0)*M_PI;
- // c = cos(rot)/2.0;
- // s = sin(rot)/2.0;
- c = cos(rot)/1.5;
- s = sin(rot)/1.5;
-
- // trim it so it looks like it's starting at the origin
- if (i < 10)
- {
- VectorScale (right, c*(i/10.0), dir);
- VectorMA (dir, s*(i/10.0), up, dir);
- }
- else
- {
- VectorScale (right, c, dir);
- VectorMA (dir, s, up, dir);
- }
-
- p->alpha = 0.5;
- // p->alphavel = -1.0 / (1+frand()*0.2);
- p->alphavel = -1000.0;
- // p->color = 0x74 + (rand()&7);
- p->color = 223 - (rand()&7);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + dir[j]*3;
- // p->vel[j] = dir[j]*6;
- p->vel[j] = 0;
- }
- }
- VectorAdd (move, vec, move);
- }
- */
- }
- #endif
- /*
- ===============
- CL_ParticleSteamEffect
- Puffs with velocity along direction, with some randomness thrown in
- ===============
- */
- void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude)
- {
- int i, j;
- cparticle_t *p;
- float d;
- vec3_t r, u;
- // vectoangles2 (dir, angle_dir);
- // AngleVectors (angle_dir, f, r, u);
- MakeNormalVectors (dir, r, u);
- for (i=0 ; i<count ; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- p->color = color + (rand()&7);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = org[j] + magnitude*0.1*crand();
- // p->vel[j] = dir[j]*magnitude;
- }
- VectorScale (dir, magnitude, p->vel);
- d = crand()*magnitude/3;
- VectorMA (p->vel, d, r, p->vel);
- d = crand()*magnitude/3;
- VectorMA (p->vel, d, u, p->vel);
- p->accel[0] = p->accel[1] = 0;
- p->accel[2] = -PARTICLE_GRAVITY/2;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (0.5 + frand()*0.3);
- }
- }
- void CL_ParticleSteamEffect2 (cl_sustain_t *self)
- //vec3_t org, vec3_t dir, int color, int count, int magnitude)
- {
- int i, j;
- cparticle_t *p;
- float d;
- vec3_t r, u;
- vec3_t dir;
- // vectoangles2 (dir, angle_dir);
- // AngleVectors (angle_dir, f, r, u);
- VectorCopy (self->dir, dir);
- MakeNormalVectors (dir, r, u);
- for (i=0 ; i<self->count ; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- p->color = self->color + (rand()&7);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = self->org[j] + self->magnitude*0.1*crand();
- // p->vel[j] = dir[j]*magnitude;
- }
- VectorScale (dir, self->magnitude, p->vel);
- d = crand()*self->magnitude/3;
- VectorMA (p->vel, d, r, p->vel);
- d = crand()*self->magnitude/3;
- VectorMA (p->vel, d, u, p->vel);
- p->accel[0] = p->accel[1] = 0;
- p->accel[2] = -PARTICLE_GRAVITY/2;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (0.5 + frand()*0.3);
- }
- self->nextthink += self->thinkinterval;
- }
- /*
- ===============
- CL_TrackerTrail
- ===============
- */
- void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor)
- {
- vec3_t move;
- vec3_t vec;
- vec3_t forward,right,up,angle_dir;
- float len;
- int j;
- cparticle_t *p;
- int dec;
- float dist;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- VectorCopy(vec, forward);
- vectoangles2 (forward, angle_dir);
- AngleVectors (angle_dir, forward, right, up);
- dec = 3;
- VectorScale (vec, 3, vec);
- // FIXME: this is a really silly way to have a loop
- while (len > 0)
- {
- len -= dec;
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -2.0;
- p->color = particleColor;
- dist = DotProduct(move, forward);
- VectorMA(move, 8 * cos(dist), up, p->org);
- for (j=0 ; j<3 ; j++)
- {
- // p->org[j] = move[j] + crand();
- p->vel[j] = 0;
- p->accel[j] = 0;
- }
- p->vel[2] = 5;
- VectorAdd (move, vec, move);
- }
- }
- void CL_Tracker_Shell(vec3_t origin)
- {
- vec3_t dir;
- int i;
- cparticle_t *p;
- for(i=0;i<300;i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = INSTANT_PARTICLE;
- p->color = 0;
- dir[0] = crand();
- dir[1] = crand();
- dir[2] = crand();
- VectorNormalize(dir);
-
- VectorMA(origin, 40, dir, p->org);
- }
- }
- void CL_MonsterPlasma_Shell(vec3_t origin)
- {
- vec3_t dir;
- int i;
- cparticle_t *p;
- for(i=0;i<40;i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = INSTANT_PARTICLE;
- p->color = 0xe0;
- dir[0] = crand();
- dir[1] = crand();
- dir[2] = crand();
- VectorNormalize(dir);
-
- VectorMA(origin, 10, dir, p->org);
- // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
- }
- }
- void CL_Widowbeamout (cl_sustain_t *self)
- {
- vec3_t dir;
- int i;
- cparticle_t *p;
- static int colortable[4] = {2*8,13*8,21*8,18*8};
- float ratio;
- ratio = 1.0 - (((float)self->endtime - (float)cl.time)/2100.0);
- for(i=0;i<300;i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = INSTANT_PARTICLE;
- p->color = colortable[rand()&3];
- dir[0] = crand();
- dir[1] = crand();
- dir[2] = crand();
- VectorNormalize(dir);
-
- VectorMA(self->org, (45.0 * ratio), dir, p->org);
- // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
- }
- }
- void CL_Nukeblast (cl_sustain_t *self)
- {
- vec3_t dir;
- int i;
- cparticle_t *p;
- static int colortable[4] = {110, 112, 114, 116};
- float ratio;
- ratio = 1.0 - (((float)self->endtime - (float)cl.time)/1000.0);
- for(i=0;i<700;i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = INSTANT_PARTICLE;
- p->color = colortable[rand()&3];
- dir[0] = crand();
- dir[1] = crand();
- dir[2] = crand();
- VectorNormalize(dir);
-
- VectorMA(self->org, (200.0 * ratio), dir, p->org);
- // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
- }
- }
- void CL_WidowSplash (vec3_t org)
- {
- static int colortable[4] = {2*8,13*8,21*8,18*8};
- int i;
- cparticle_t *p;
- vec3_t dir;
- for (i=0 ; i<256 ; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- p->color = colortable[rand()&3];
- dir[0] = crand();
- dir[1] = crand();
- dir[2] = crand();
- VectorNormalize(dir);
- VectorMA(org, 45.0, dir, p->org);
- VectorMA(vec3_origin, 40.0, dir, p->vel);
- p->accel[0] = p->accel[1] = 0;
- p->alpha = 1.0;
- p->alphavel = -0.8 / (0.5 + frand()*0.3);
- }
- }
- void CL_Tracker_Explode(vec3_t origin)
- {
- vec3_t dir, backdir;
- int i;
- cparticle_t *p;
- for(i=0;i<300;i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0;
- p->color = 0;
- dir[0] = crand();
- dir[1] = crand();
- dir[2] = crand();
- VectorNormalize(dir);
- VectorScale(dir, -1, backdir);
-
- VectorMA(origin, 64, dir, p->org);
- VectorScale(backdir, 64, p->vel);
- }
-
- }
- /*
- ===============
- CL_TagTrail
- ===============
- */
- void CL_TagTrail (vec3_t start, vec3_t end, float color)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int j;
- cparticle_t *p;
- int dec;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- dec = 5;
- VectorScale (vec, 5, vec);
- while (len >= 0)
- {
- len -= dec;
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (0.8+frand()*0.2);
- p->color = color;
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + crand()*16;
- p->vel[j] = crand()*5;
- p->accel[j] = 0;
- }
- VectorAdd (move, vec, move);
- }
- }
- /*
- ===============
- CL_ColorExplosionParticles
- ===============
- */
- void CL_ColorExplosionParticles (vec3_t org, int color, int run)
- {
- int i, j;
- cparticle_t *p;
- for (i=0 ; i<128 ; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- p->color = color + (rand() % run);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = org[j] + ((rand()%32)-16);
- p->vel[j] = (rand()%256)-128;
- }
- p->accel[0] = p->accel[1] = 0;
- p->accel[2] = -PARTICLE_GRAVITY;
- p->alpha = 1.0;
- p->alphavel = -0.4 / (0.6 + frand()*0.2);
- }
- }
- /*
- ===============
- CL_ParticleSmokeEffect - like the steam effect, but unaffected by gravity
- ===============
- */
- void CL_ParticleSmokeEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude)
- {
- int i, j;
- cparticle_t *p;
- float d;
- vec3_t r, u;
- MakeNormalVectors (dir, r, u);
- for (i=0 ; i<count ; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- p->color = color + (rand()&7);
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = org[j] + magnitude*0.1*crand();
- // p->vel[j] = dir[j]*magnitude;
- }
- VectorScale (dir, magnitude, p->vel);
- d = crand()*magnitude/3;
- VectorMA (p->vel, d, r, p->vel);
- d = crand()*magnitude/3;
- VectorMA (p->vel, d, u, p->vel);
- p->accel[0] = p->accel[1] = p->accel[2] = 0;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (0.5 + frand()*0.3);
- }
- }
- /*
- ===============
- CL_BlasterParticles2
- Wall impact puffs (Green)
- ===============
- */
- void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color)
- {
- int i, j;
- cparticle_t *p;
- float d;
- int count;
- count = 40;
- for (i=0 ; i<count ; i++)
- {
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- p->time = cl.time;
- p->color = color + (rand()&7);
- d = rand()&15;
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
- p->vel[j] = dir[j] * 30 + crand()*40;
- }
- p->accel[0] = p->accel[1] = 0;
- p->accel[2] = -PARTICLE_GRAVITY;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (0.5 + frand()*0.3);
- }
- }
- /*
- ===============
- CL_BlasterTrail2
- Green!
- ===============
- */
- void CL_BlasterTrail2 (vec3_t start, vec3_t end)
- {
- vec3_t move;
- vec3_t vec;
- float len;
- int j;
- cparticle_t *p;
- int dec;
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
- dec = 5;
- VectorScale (vec, 5, vec);
- // FIXME: this is a really silly way to have a loop
- while (len > 0)
- {
- len -= dec;
- if (!free_particles)
- return;
- p = free_particles;
- free_particles = p->next;
- p->next = active_particles;
- active_particles = p;
- VectorClear (p->accel);
-
- p->time = cl.time;
- p->alpha = 1.0;
- p->alphavel = -1.0 / (0.3+frand()*0.2);
- p->color = 0xd0;
- for (j=0 ; j<3 ; j++)
- {
- p->org[j] = move[j] + crand();
- p->vel[j] = crand()*5;
- p->accel[j] = 0;
- }
- VectorAdd (move, vec, move);
- }
- }
|