diff options
Diffstat (limited to 'src/jake2/client/CL_newfx.java')
-rw-r--r-- | src/jake2/client/CL_newfx.java | 2000 |
1 files changed, 991 insertions, 1009 deletions
diff --git a/src/jake2/client/CL_newfx.java b/src/jake2/client/CL_newfx.java index 5346226..690cd57 100644 --- a/src/jake2/client/CL_newfx.java +++ b/src/jake2/client/CL_newfx.java @@ -2,1028 +2,1010 @@ * CL_newfx.java * Copyright (C) 2004 * - * $Id: CL_newfx.java,v 1.3 2004-07-08 20:24:29 hzi Exp $ + * $Id: CL_newfx.java,v 1.4 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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. -*/ + */ // Created on 31.01.2004 by RST. - package jake2.client; +import jake2.Defines; import jake2.Globals; - +import jake2.client.CL_fx.cdlight_t; +import jake2.util.Lib; +import jake2.util.Math3D; /** * CL_newfx */ -public class CL_newfx extends CL_fx { - - - - static void Flashlight(int ent, float[] 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 - ====== - */ - static void ColorFlash(float[] 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 - ====== - */ - static void DebugTrail(float[] start, float[] end) { - float[] move = new float[3]; - float[] vec = new float[3]; - - float len; - // int j; - cparticle_t p; - float dec; - float[] right = new float[3]; - float[] up = new float[3]; - // int i; - // float d, c, s; - // float[] 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 == null) - 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.0f; - p.alphavel = -0.1f; - // 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 - =============== - */ - static void SmokeTrail(float[] start, float[] end, int colorStart, int colorRun, int spacing) { - float[] move = new float[3]; - float[] vec = new float[3]; - 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 == null) - 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.0f; - p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.5f); - 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); - } - } - - static void ForceWall(float[] start, float[] end, int color) { - float[] move = new float[3]; - float[] vec = new float[3]; - ; - 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 == null) - return; - - if (Globals.rnd.nextFloat() > 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.0f; - p.alphavel = -1.0f / (3.0f + Globals.rnd.nextFloat() * 0.5f); - 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); - } - } - -// static void FlameEffects(centity_t ent, float[] origin) { -// int n, count; -// int j; -// cparticle_t p; -// -// count = rand() & 0xF; -// -// for (n = 0; n < count; n++) { -// if (free_particles == null) -// 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.0f; -// p.alphavel = -1.0f / (1 + frand() * 0.2f); -// 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 == null) -// 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.0f; -// p.alphavel = -1.0f / (1 + frand() * 0.5f); -// 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 - =============== - */ - static void GenericParticleEffect(float[] org, float[] 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 == null) - 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.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * alphavel); - // p.alphavel = alphavel; - } - } - - /* - =============== - CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns) - - =============== - */ - static void BubbleTrail2 (float[] start, float[] end, int dist) - { - float[] move = new float[3]; - float[] vec = new float[3];; - 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 == null) - 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.0f; - p.alphavel = -1.0f / (1+Globals.rnd.nextFloat()*0.1f); - 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); - } - } - - static void Heatbeam(float[] start, float[] forward) { - float[] move = new float[3]; - float[] vec = new float[3]; - float len; - int j; - cparticle_t p; - float[] right = new float[3]; - float[] up = new float[3]; - int i; - float c, s; - float[] dir = new float[3]; - float ltime; - float step = 32.0f, rstep; - float start_pt; - float rot; - float variance; - float[] end = new float[3]; - - 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.5f, right, move); - VectorMA(move, -0.5f, up, move); - } - // otherwise assume SOFT - - ltime = (float)cl.time / 1000.0f; - start_pt = ltime * 96.0f % step; - VectorMA(move, start_pt, vec, move); - - VectorScale(vec, step, vec); - - // Com_Printf ("%f\n", ltime); - rstep = (float) (Math.PI / 10.0); - float M_PI2 = (float) (Math.PI * 2.0); - for (i = (int)start_pt; i < len; i += step) { - if (i > step * 5) // don't bother after the 5th ring - break; - - for (rot = 0; rot < M_PI2; rot += rstep) { - - if (free_particles == null) - 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.5f; - c = (float) (Math.cos(rot) * variance); - s = (float) (Math.sin(rot) * variance); - - // trim it so it looks like it's starting at the origin - if (i < 10) { - VectorScale(right, c * (i / 10.0f), dir); - VectorMA(dir, s * (i / 10.0f), up, dir); - } else { - VectorScale(right, c, dir); - VectorMA(dir, s, up, dir); - } - - p.alpha = 0.5f; - // p.alphavel = -1.0 / (1+frand()*0.2); - p.alphavel = -1000.0f; - // 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); - } - } - - /* - =============== - CL_ParticleSteamEffect - - Puffs with velocity along direction, with some randomness thrown in - =============== - */ - static void ParticleSteamEffect(float[] org, float[] dir, int color, int count, int magnitude) { - int i, j; - cparticle_t p; - float d; - float[] r = new float[3]; - float[] u = new float[3]; - - // vectoangles2 (dir, angle_dir); - // AngleVectors (angle_dir, f, r, u); - - MakeNormalVectors(dir, r, u); - - for (i = 0; i < count; i++) { - if (free_particles == null) - 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.1f * 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.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - } - - static void ParticleSteamEffect2(cl_sustain_t self) - // float[] org, float[] dir, int color, int count, int magnitude) - { - int i, j; - cparticle_t p; - float d; - float[] r = new float[3]; - float[] u = new float[3]; - float[] dir = new float[3]; - - // 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 == null) - 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.1f * 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.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - self.nextthink += self.thinkinterval; - } - - /* - =============== - CL_TrackerTrail - =============== - */ - static void TrackerTrail(float[] start, float[] end, int particleColor) { - float[] move = new float[3]; - float[] vec = new float[3]; - float[] forward = new float[3]; - float[] right = new float[3]; - float[] up = new float[3]; - float[] angle_dir = new float[3]; - float len; - cparticle_t p; - int dec; - float dist; - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - VectorCopy(vec, forward); - vectoangles(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 == null) - 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.0f; - p.alphavel = -2.0f; - p.color = particleColor; - dist = DotProduct(move, forward); - VectorMA(move, (float)(8 * Math.cos(dist)), up, p.org); - for (int j=0 ; j<3 ; j++) { - p.vel[j] = 0; - p.accel[j] = 0; - } - p.vel[2] = 5; - - VectorAdd (move, vec, move); - } - } - - static void Tracker_Shell(float[] origin) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - for(i=0;i<300;i++) { - if (free_particles == null) - 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.0f; - p.alphavel = INSTANT_PARTICLE; - p.color = 0; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - - VectorMA(origin, 40, dir, p.org); - } - } - - static void MonsterPlasma_Shell(float[] origin) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - for (i = 0; i < 40; i++) { - if (free_particles == null) - 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.0f; - 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); - } - } - - private static int[] wb_colortable = {2*8,13*8,21*8,18*8}; - static void Widowbeamout(cl_sustain_t self) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - float ratio; - - ratio = 1.0f - (((float)self.endtime - (float)cl.time) / 2100.0f); - - for (i = 0; i < 300; i++) { - if (free_particles == null) - 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.0f; - p.alphavel = INSTANT_PARTICLE; - p.color = wb_colortable[rand() & 3]; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - - VectorMA(self.org, (45.0f * ratio), dir, p.org); - // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p.org); - } - } - - private static int[] nb_colortable = {110, 112, 114, 116}; - static void Nukeblast(cl_sustain_t self) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - float ratio; - - ratio = 1.0f - (((float)self.endtime - (float)cl.time) / 1000.0f); - - for (i = 0; i < 700; i++) { - if (free_particles == null) - 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.0f; - p.alphavel = INSTANT_PARTICLE; - p.color = nb_colortable[rand() & 3]; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - - VectorMA(self.org, (200.0f * ratio), dir, p.org); - // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p.org); - } - } - - private static int[] ws_colortable = {2*8,13*8,21*8,18*8}; - static void WidowSplash(float[] org) { - int i; - cparticle_t p; - float[] dir = new float[3]; - - for (i = 0; i < 256; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - p.color = ws_colortable[rand() & 3]; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - VectorMA(org, 45.0f, dir, p.org); - VectorMA(vec3_origin, 40.0f, dir, p.vel); - - p.accel[0] = p.accel[1] = 0; - p.alpha = 1.0f; - - p.alphavel = -0.8f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - - } - - static void Tracker_Explode(float[] origin) { - float[] dir = new float[3]; - float[] backdir = new float[3]; - int i; - cparticle_t p; - - for (i = 0; i < 300; i++) { - if (free_particles == null) - 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.0f; - p.alphavel = -1.0f; - 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 - - =============== - */ - static void TagTrail(float[] start, float[] end, float color) { - float[] move = new float[3]; - float[] vec = new float[3]; - 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 == null) - 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.0f; - p.alphavel = -1.0f / (0.8f + Globals.rnd.nextFloat() * 0.2f); - 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 - =============== - */ - static void ColorExplosionParticles(float[] org, int color, int run) { - int i, j; - cparticle_t p; - - for (i = 0; i < 128; i++) { - if (free_particles == null) - 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.0f; - - p.alphavel = -0.4f / (0.6f + Globals.rnd.nextFloat() * 0.2f); - } - } - - /* - =============== - CL_ParticleSmokeEffect - like the steam effect, but unaffected by gravity - =============== - */ - static void ParticleSmokeEffect (float[] org, float[] dir, int color, int count, int magnitude) - { - int i, j; - cparticle_t p; - float d; - float[] r = new float[3]; - float[] u = new float[3]; - - MakeNormalVectors (dir, r, u); - - for (i=0 ; i<count ; i++) - { - if (free_particles == null) - 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.1f*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.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat()*0.3f); - } - } - - /* - =============== - CL_BlasterParticles2 - - Wall impact puffs (Green) - =============== - */ - static void BlasterParticles2(float[] org, float[] dir, long color) { - int i, j; - cparticle_t p; - float d; - int count; - - count = 40; - for (i = 0; i < count; i++) { - if (free_particles == null) - 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.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - } - - /* - =============== - CL_BlasterTrail2 - - Green! - =============== - */ - static void BlasterTrail2(float[] start, float[] end) { - float[] move = new float[3]; - float[] vec = new float[3]; - 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 == null) - 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.0f; - p.alphavel = -1.0f / (0.3f + Globals.rnd.nextFloat() * 0.2f); - 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); - } - } - -} +public class CL_newfx { + + static void Flashlight(int ent, float[] pos) { + CL_fx.cdlight_t dl; + + dl = CL_fx.AllocDlight(ent); + Math3D.VectorCopy(pos, dl.origin); + dl.radius = 400; + dl.minlight = 250; + dl.die = Globals.cl.time + 100; + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 1; + } + + /* + * ====== CL_ColorFlash - flash of light ====== + */ + static void ColorFlash(float[] pos, int ent, int intensity, float r, + float g, float b) { + CL_fx.cdlight_t dl; + + if ((Globals.vidref_val == Defines.VIDREF_SOFT) + && ((r < 0) || (g < 0) || (b < 0))) { + intensity = -intensity; + r = -r; + g = -g; + b = -b; + } + + dl = CL_fx.AllocDlight(ent); + Math3D.VectorCopy(pos, dl.origin); + dl.radius = intensity; + dl.minlight = 250; + dl.die = Globals.cl.time + 100; + dl.color[0] = r; + dl.color[1] = g; + dl.color[2] = b; + } + + /* + * ====== CL_DebugTrail ====== + */ + static void DebugTrail(float[] start, float[] end) { + float[] move = new float[3]; + float[] vec = new float[3]; + + float len; + // int j; + cparticle_t p; + float dec; + float[] right = new float[3]; + float[] up = new float[3]; + // int i; + // float d, c, s; + // float[] dir; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.MakeNormalVectors(vec, right, up); + + // VectorScale(vec, RT2_SKIP, vec); + + // dec = 1.0; + // dec = 0.75; + dec = 3; + Math3D.VectorScale(vec, dec, vec); + Math3D.VectorCopy(start, move); + + while (len > 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + Math3D.VectorClear(p.accel); + Math3D.VectorClear(p.vel); + p.alpha = 1.0f; + p.alphavel = -0.1f; + // p.alphavel = 0; + p.color = 0x74 + (Lib.rand() & 7); + Math3D.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; } + */ + Math3D.VectorAdd(move, vec, move); + } + + } + + /* + * =============== CL_SmokeTrail =============== + */ + static void SmokeTrail(float[] start, float[] end, int colorStart, + int colorRun, int spacing) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.VectorScale(vec, spacing, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= spacing; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.5f); + p.color = colorStart + (Lib.rand() % colorRun); + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 3; + p.accel[j] = 0; + } + p.vel[2] = 20 + Lib.crand() * 5; + + Math3D.VectorAdd(move, vec, move); + } + } + + static void ForceWall(float[] start, float[] end, int color) { + float[] move = new float[3]; + float[] vec = new float[3]; + ; + float len; + int j; + cparticle_t p; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.VectorScale(vec, 4, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= 4; + + if (CL_fx.free_particles == null) + return; + + if (Globals.rnd.nextFloat() > 0.3) { + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (3.0f + Globals.rnd.nextFloat() * 0.5f); + p.color = color; + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 3; + p.accel[j] = 0; + } + p.vel[0] = 0; + p.vel[1] = 0; + p.vel[2] = -40 - (Lib.crand() * 10); + } + + Math3D.VectorAdd(move, vec, move); + } + } + + // static void FlameEffects(centity_t ent, float[] origin) { + // int n, count; + // int j; + // cparticle_t p; + // + // count = rand() & 0xF; + // + // for (n = 0; n < count; n++) { + // if (free_particles == null) + // 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.0f; + // p.alphavel = -1.0f / (1 + frand() * 0.2f); + // 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 == null) + // 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.0f; + // p.alphavel = -1.0f / (1 + frand() * 0.5f); + // 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 =============== + */ + static void GenericParticleEffect(float[] org, float[] 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 (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + if (numcolors > 1) + p.color = color + (Lib.rand() & numcolors); + else + p.color = color; + + d = Lib.rand() & dirspread; + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = Lib.crand() * 20; + } + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY; + // VectorCopy (accel, p.accel); + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * alphavel); + // p.alphavel = alphavel; + } + } + + /* + * =============== CL_BubbleTrail2 (lets you control the # of bubbles by + * setting the distance between the spawns) + * + * =============== + */ + static void BubbleTrail2(float[] start, float[] end, int dist) { + float[] move = new float[3]; + float[] vec = new float[3]; + ; + float len; + int i, j; + cparticle_t p; + float dec; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + dec = dist; + Math3D.VectorScale(vec, dec, vec); + + for (i = 0; i < len; i += dec) { + if (CL_fx.free_particles == null) + return; + + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + Math3D.VectorClear(p.accel); + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.1f); + p.color = 4 + (Lib.rand() & 7); + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 2; + p.vel[j] = Lib.crand() * 10; + } + p.org[2] -= 4; + // p.vel[2] += 6; + p.vel[2] += 20; + + Math3D.VectorAdd(move, vec, move); + } + } + + static void Heatbeam(float[] start, float[] forward) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + float[] right = new float[3]; + float[] up = new float[3]; + int i; + float c, s; + float[] dir = new float[3]; + float ltime; + float step = 32.0f, rstep; + float start_pt; + float rot; + float variance; + float[] end = new float[3]; + + Math3D.VectorMA(start, 4096, forward, end); + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + // FIXME - pmm - these might end up using old values? + // MakeNormalVectors (vec, right, up); + Math3D.VectorCopy(Globals.cl.v_right, right); + Math3D.VectorCopy(Globals.cl.v_up, up); + if (Globals.vidref_val == Defines.VIDREF_GL) { // GL mode + Math3D.VectorMA(move, -0.5f, right, move); + Math3D.VectorMA(move, -0.5f, up, move); + } + // otherwise assume SOFT + + ltime = (float) Globals.cl.time / 1000.0f; + start_pt = ltime * 96.0f % step; + Math3D.VectorMA(move, start_pt, vec, move); + + Math3D.VectorScale(vec, step, vec); + + // Com_Printf ("%f\n", ltime); + rstep = (float) (Math.PI / 10.0); + float M_PI2 = (float) (Math.PI * 2.0); + for (i = (int) start_pt; i < len; i += step) { + if (i > step * 5) // don't bother after the 5th ring + break; + + for (rot = 0; rot < M_PI2; rot += rstep) { + + if (CL_fx.free_particles == null) + return; + + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + Math3D.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.5f; + c = (float) (Math.cos(rot) * variance); + s = (float) (Math.sin(rot) * variance); + + // trim it so it looks like it's starting at the origin + if (i < 10) { + Math3D.VectorScale(right, c * (i / 10.0f), dir); + Math3D.VectorMA(dir, s * (i / 10.0f), up, dir); + } else { + Math3D.VectorScale(right, c, dir); + Math3D.VectorMA(dir, s, up, dir); + } + + p.alpha = 0.5f; + // p.alphavel = -1.0 / (1+frand()*0.2); + p.alphavel = -1000.0f; + // p.color = 0x74 + (rand()&7); + p.color = 223 - (Lib.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; + } + } + Math3D.VectorAdd(move, vec, move); + } + } + + /* + * =============== CL_ParticleSteamEffect + * + * Puffs with velocity along direction, with some randomness thrown in + * =============== + */ + static void ParticleSteamEffect(float[] org, float[] dir, int color, + int count, int magnitude) { + int i, j; + cparticle_t p; + float d; + float[] r = new float[3]; + float[] u = new float[3]; + + // vectoangles2 (dir, angle_dir); + // AngleVectors (angle_dir, f, r, u); + + Math3D.MakeNormalVectors(dir, r, u); + + for (i = 0; i < count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() & 7); + + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + magnitude * 0.1f * Lib.crand(); + // p.vel[j] = dir[j]*magnitude; + } + Math3D.VectorScale(dir, magnitude, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, r, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, u, p.vel); + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY / 2; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + } + + static void ParticleSteamEffect2(cl_sustain_t self) + // float[] org, float[] dir, int color, int count, int magnitude) + { + int i, j; + cparticle_t p; + float d; + float[] r = new float[3]; + float[] u = new float[3]; + float[] dir = new float[3]; + + // vectoangles2 (dir, angle_dir); + // AngleVectors (angle_dir, f, r, u); + + Math3D.VectorCopy(self.dir, dir); + Math3D.MakeNormalVectors(dir, r, u); + + for (i = 0; i < self.count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = self.color + (Lib.rand() & 7); + + for (j = 0; j < 3; j++) { + p.org[j] = self.org[j] + self.magnitude * 0.1f * Lib.crand(); + // p.vel[j] = dir[j]*magnitude; + } + Math3D.VectorScale(dir, self.magnitude, p.vel); + d = Lib.crand() * self.magnitude / 3; + Math3D.VectorMA(p.vel, d, r, p.vel); + d = Lib.crand() * self.magnitude / 3; + Math3D.VectorMA(p.vel, d, u, p.vel); + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY / 2; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + self.nextthink += self.thinkinterval; + } + + /* + * =============== CL_TrackerTrail =============== + */ + static void TrackerTrail(float[] start, float[] end, int particleColor) { + float[] move = new float[3]; + float[] vec = new float[3]; + float[] forward = new float[3]; + float[] right = new float[3]; + float[] up = new float[3]; + float[] angle_dir = new float[3]; + float len; + cparticle_t p; + int dec; + float dist; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.VectorCopy(vec, forward); + Math3D.vectoangles(forward, angle_dir); + Math3D.AngleVectors(angle_dir, forward, right, up); + + dec = 3; + Math3D.VectorScale(vec, 3, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -2.0f; + p.color = particleColor; + dist = Math3D.DotProduct(move, forward); + Math3D.VectorMA(move, (float) (8 * Math.cos(dist)), up, p.org); + for (int j = 0; j < 3; j++) { + p.vel[j] = 0; + p.accel[j] = 0; + } + p.vel[2] = 5; + + Math3D.VectorAdd(move, vec, move); + } + } + + static void Tracker_Shell(float[] origin) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + for (i = 0; i < 300; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = 0; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(origin, 40, dir, p.org); + } + } + + static void MonsterPlasma_Shell(float[] origin) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + for (i = 0; i < 40; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = 0xe0; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(origin, 10, dir, p.org); + // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), + // dir, p.org); + } + } + + private static int[] wb_colortable = { 2 * 8, 13 * 8, 21 * 8, 18 * 8 }; + + static void Widowbeamout(cl_sustain_t self) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + float ratio; + + ratio = 1.0f - (((float) self.endtime - (float) Globals.cl.time) / 2100.0f); + + for (i = 0; i < 300; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = wb_colortable[Lib.rand() & 3]; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(self.org, (45.0f * ratio), dir, p.org); + // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), + // dir, p.org); + } + } + + private static int[] nb_colortable = { 110, 112, 114, 116 }; + + static void Nukeblast(cl_sustain_t self) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + float ratio; + + ratio = 1.0f - (((float) self.endtime - (float) Globals.cl.time) / 1000.0f); + + for (i = 0; i < 700; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = nb_colortable[Lib.rand() & 3]; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(self.org, (200.0f * ratio), dir, p.org); + // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), + // dir, p.org); + } + } + + private static int[] ws_colortable = { 2 * 8, 13 * 8, 21 * 8, 18 * 8 }; + + static void WidowSplash(float[] org) { + int i; + cparticle_t p; + float[] dir = new float[3]; + + for (i = 0; i < 256; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = ws_colortable[Lib.rand() & 3]; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + Math3D.VectorMA(org, 45.0f, dir, p.org); + Math3D.VectorMA(Globals.vec3_origin, 40.0f, dir, p.vel); + + p.accel[0] = p.accel[1] = 0; + p.alpha = 1.0f; + + p.alphavel = -0.8f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + + } + + static void Tracker_Explode(float[] origin) { + float[] dir = new float[3]; + float[] backdir = new float[3]; + int i; + cparticle_t p; + + for (i = 0; i < 300; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f; + p.color = 0; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + Math3D.VectorScale(dir, -1, backdir); + + Math3D.VectorMA(origin, 64, dir, p.org); + Math3D.VectorScale(backdir, 64, p.vel); + } + + } + + /* + * =============== CL_TagTrail + * + * =============== + */ + static void TagTrail(float[] start, float[] end, float color) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + int dec; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + dec = 5; + Math3D.VectorScale(vec, 5, vec); + + while (len >= 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (0.8f + Globals.rnd.nextFloat() * 0.2f); + p.color = color; + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 16; + p.vel[j] = Lib.crand() * 5; + p.accel[j] = 0; + } + + Math3D.VectorAdd(move, vec, move); + } + } + + /* + * =============== CL_ColorExplosionParticles =============== + */ + static void ColorExplosionParticles(float[] org, int color, int run) { + int i, j; + cparticle_t p; + + for (i = 0; i < 128; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() % run); + + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + ((Lib.rand() % 32) - 16); + p.vel[j] = (Lib.rand() % 256) - 128; + } + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY; + p.alpha = 1.0f; + + p.alphavel = -0.4f / (0.6f + Globals.rnd.nextFloat() * 0.2f); + } + } + + /* + * =============== CL_ParticleSmokeEffect - like the steam effect, but + * unaffected by gravity =============== + */ + static void ParticleSmokeEffect(float[] org, float[] dir, int color, + int count, int magnitude) { + int i, j; + cparticle_t p; + float d; + float[] r = new float[3]; + float[] u = new float[3]; + + Math3D.MakeNormalVectors(dir, r, u); + + for (i = 0; i < count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() & 7); + + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + magnitude * 0.1f * Lib.crand(); + // p.vel[j] = dir[j]*magnitude; + } + Math3D.VectorScale(dir, magnitude, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, r, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, u, p.vel); + + p.accel[0] = p.accel[1] = p.accel[2] = 0; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + } + + /* + * =============== CL_BlasterParticles2 + * + * Wall impact puffs (Green) =============== + */ + static void BlasterParticles2(float[] org, float[] dir, long color) { + int i, j; + cparticle_t p; + float d; + int count; + + count = 40; + for (i = 0; i < count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() & 7); + + d = Lib.rand() & 15; + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = dir[j] * 30 + Lib.crand() * 40; + } + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + } + + /* + * =============== CL_BlasterTrail2 + * + * Green! =============== + */ + static void BlasterTrail2(float[] start, float[] end) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + int dec; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + dec = 5; + Math3D.VectorScale(vec, 5, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (0.3f + Globals.rnd.nextFloat() * 0.2f); + p.color = 0xd0; + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand(); + p.vel[j] = Lib.crand() * 5; + p.accel[j] = 0; + } + + Math3D.VectorAdd(move, vec, move); + } + } +}
\ No newline at end of file |