/* * CL_fx.java * Copyright (C) 2004 * * $Id: CL_fx.java,v 1.1 2004-07-07 19:58:36 hzi Exp $ */ /* 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. */ package jake2.client; import jake2.game.M_Flash; import jake2.game.entity_state_t; import jake2.qcommon.Com; import jake2.qcommon.MSG; /** * CL_fx */ public class CL_fx extends CL_tent { static final float INSTANT_PARTICLE = -10000.0f; static class cdlight_t { int key; // so entities can reuse same entry float[] color = { 0, 0, 0 }; float[] origin = { 0, 0, 0 }; float radius; float die; // stop lighting after this time float decay; // drop this each second float minlight; // don't add when contributing less void clear() { radius = decay = die = minlight = color[0] = color[1] = color[2] = origin[0] = origin[1] = origin[2] = key = 0; } } static float[][] avelocities = new float[NUMVERTEXNORMALS][3]; /* ============================================================== LIGHT STYLE MANAGEMENT ============================================================== */ static class clightstyle_t { int length; float[] value = new float[3]; float[] map = new float[MAX_QPATH]; void clear() { value[0] = value[1] = value[2] = length = 0; for (int i = 0; i < map.length; i++) map[i] = 0.0f; } } static clightstyle_t[] cl_lightstyle = new clightstyle_t[MAX_LIGHTSTYLES]; static { for(int i=0; i= MAX_QPATH) Com.Error(ERR_DROP, "svc_lightstyle length=" + j); cl_lightstyle[i].length = j; for (k = 0; k < j; k++) cl_lightstyle[i].map[k] = (float) (s.charAt(k) - 'a') / (float) ('m' - 'a'); } /* ================ CL_AddLightStyles ================ */ static void AddLightStyles() { int i; clightstyle_t[] ls; ls = cl_lightstyle; for (i = 0; i < ls.length; i++) V.AddLightStyle(i, ls[i].value[0], ls[i].value[1], ls[i].value[2]); } /* ============================================================== DLIGHT MANAGEMENT ============================================================== */ static cdlight_t[] cl_dlights = new cdlight_t[MAX_DLIGHTS]; static { for (int i = 0; i < cl_dlights.length; i++) cl_dlights[i] = new cdlight_t(); } /* ================ CL_ClearDlights ================ */ static void ClearDlights() { // memset (cl_dlights, 0, sizeof(cl_dlights)); for (int i = 0; i < cl_dlights.length; i++) { cl_dlights[i].clear(); } } /* =============== CL_AllocDlight =============== */ static cdlight_t AllocDlight(int key) { int i; cdlight_t[] dl; // first look for an exact key match if (key != 0) { dl = cl_dlights; for (i = 0; i < MAX_DLIGHTS; i++) { if (dl[i].key == key) { //memset (dl, 0, sizeof(*dl)); dl[i].clear(); dl[i].key = key; return dl[i]; } } } // then look for anything else dl = cl_dlights; for (i = 0; i < MAX_DLIGHTS; i++) { if (dl[i].die < cl.time) { //memset (dl, 0, sizeof(*dl)); dl[i].clear(); dl[i].key = key; return dl[i]; } } //dl = &cl_dlights[0]; //memset (dl, 0, sizeof(*dl)); dl[0].clear(); dl[0].key = key; return dl[0]; } /* =============== CL_NewDlight =============== */ static void NewDlight(int key, float x, float y, float z, float radius, float time) { cdlight_t dl; dl = CL.AllocDlight(key); dl.origin[0] = x; dl.origin[1] = y; dl.origin[2] = z; dl.radius = radius; dl.die = cl.time + time; } /* =============== CL_RunDLights =============== */ static void RunDLights() { int i; cdlight_t[] dl; dl = cl_dlights; for (i = 0; i < MAX_DLIGHTS; i++) { if (dl[i].radius == 0.0f) continue; if (dl[i].die < cl.time) { dl[i].radius = 0; return; } dl[i].radius -= cls.frametime * dl[i].decay; if (dl[i].radius < 0) dl[i].radius = 0; } } /* ============== CL_ParseMuzzleFlash ============== */ static void ParseMuzzleFlash() { float[] fv = new float[3]; float[] rv = new float[3]; cdlight_t dl; int i, weapon; centity_t pl; int silenced; float volume; String soundname; i = MSG.ReadShort(net_message); if (i < 1 || i >= MAX_EDICTS) Com.Error(ERR_DROP, "CL_ParseMuzzleFlash: bad entity"); weapon = MSG.ReadByte(net_message); silenced = weapon & MZ_SILENCED; weapon &= ~MZ_SILENCED; pl = cl_entities[i]; dl = CL.AllocDlight(i); VectorCopy(pl.current.origin, dl.origin); AngleVectors(pl.current.angles, fv, rv, null); VectorMA(dl.origin, 18, fv, dl.origin); VectorMA(dl.origin, 16, rv, dl.origin); if (silenced != 0) dl.radius = 100 + (rand() & 31); else dl.radius = 200 + (rand() & 31); dl.minlight = 32; dl.die = cl.time; // + 0.1; if (silenced != 0) volume = 0.2f; else volume = 1; switch (weapon) { case MZ_BLASTER : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_BLUEHYPERBLASTER : dl.color[0] = 0; dl.color[1] = 0; dl.color[2] = 1; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_HYPERBLASTER : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_MACHINEGUN : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); soundname = "weapons/machgf" + ((rand() % 5) + 1) + "b.wav"; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); break; case MZ_SHOTGUN : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0); S.StartSound(null, i, CHAN_AUTO, S.RegisterSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1f); break; case MZ_SSHOTGUN : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0); break; case MZ_CHAINGUN1 : dl.radius = 200 + (rand() & 31); dl.color[0] = 1; dl.color[1] = 0.25f; dl.color[2] = 0; //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); soundname = "weapons/machgf" + ((rand() % 5) + 1) + "b.wav"; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); break; case MZ_CHAINGUN2 : dl.radius = 225 + (rand() & 31); dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0; dl.die = cl.time + 0.1f; // long delay //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); soundname = "weapons/machgf" + ((rand() % 5) + 1) + "b.wav"; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); soundname = "weapons/machgf" + ((rand() % 5) + 1) + "b.wav"; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0.05f); break; case MZ_CHAINGUN3 : dl.radius = 250 + (rand() & 31); dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; dl.die = cl.time + 0.1f; // long delay //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); soundname = "weapons/machgf" + ((rand() % 5) + 1) + "b.wav"; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); soundname = "weapons/machgf" + ((rand() % 5) + 1) + "b.wav"; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0.033f); //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); soundname = "weapons/machgf" + ((rand() % 5) + 1) + "b.wav"; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0.066f); break; case MZ_RAILGUN : dl.color[0] = 0.5f; dl.color[1] = 0.5f; dl.color[2] = 1.0f; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_ROCKET : dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0.2f; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0); S.StartSound(null, i, CHAN_AUTO, S.RegisterSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1f); break; case MZ_GRENADE : dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0); S.StartSound(null, i, CHAN_AUTO, S.RegisterSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1f); break; case MZ_BFG : dl.color[0] = 0; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0); break; case MZ_LOGIN : dl.color[0] = 0; dl.color[1] = 1; dl.color[2] = 0; dl.die = cl.time + 1.0f; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); CL.LogoutEffect(pl.current.origin, weapon); break; case MZ_LOGOUT : dl.color[0] = 1; dl.color[1] = 0; dl.color[2] = 0; dl.die = cl.time + 1.0f; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); CL.LogoutEffect(pl.current.origin, weapon); break; case MZ_RESPAWN : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; dl.die = cl.time + 1.0f; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); CL.LogoutEffect(pl.current.origin, weapon); break; // RAFAEL case MZ_PHALANX : dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0.5f; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/plasshot.wav"), volume, ATTN_NORM, 0); break; // RAFAEL case MZ_IONRIPPER : dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0.5f; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/rippfire.wav"), volume, ATTN_NORM, 0); break; // ====================== // PGM case MZ_ETF_RIFLE : dl.color[0] = 0.9f; dl.color[1] = 0.7f; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/nail1.wav"), volume, ATTN_NORM, 0); break; case MZ_SHOTGUN2 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/shotg2.wav"), volume, ATTN_NORM, 0); break; case MZ_HEATBEAM : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; dl.die = cl.time + 100; // S.StartSound (null, i, CHAN_WEAPON, S.RegisterSound("weapons/bfg__l1a.wav"), volume, ATTN_NORM, 0); break; case MZ_BLASTER2 : dl.color[0] = 0; dl.color[1] = 1; dl.color[2] = 0; // FIXME - different sound for blaster2 ?? S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0); break; case MZ_TRACKER : // negative flashes handled the same in gl/soft until CL_AddDLights dl.color[0] = -1; dl.color[1] = -1; dl.color[2] = -1; S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/disint2.wav"), volume, ATTN_NORM, 0); break; case MZ_NUKE1 : dl.color[0] = 1; dl.color[1] = 0; dl.color[2] = 0; dl.die = cl.time + 100; break; case MZ_NUKE2 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; dl.die = cl.time + 100; break; case MZ_NUKE4 : dl.color[0] = 0; dl.color[1] = 0; dl.color[2] = 1; dl.die = cl.time + 100; break; case MZ_NUKE8 : dl.color[0] = 0; dl.color[1] = 1; dl.color[2] = 1; dl.die = cl.time + 100; break; // PGM // ====================== } } /* ============== CL_ParseMuzzleFlash2 ============== */ static void ParseMuzzleFlash2() { int ent; float[] origin = new float[3]; int flash_number; cdlight_t dl; float[] forward = new float[3]; float[] right = new float[3]; String soundname; ent = MSG.ReadShort(net_message); if (ent < 1 || ent >= MAX_EDICTS) Com.Error(ERR_DROP, "CL_ParseMuzzleFlash2: bad entity"); flash_number = MSG.ReadByte(net_message); // locate the origin AngleVectors(cl_entities[ent].current.angles, forward, right, null); origin[0] = cl_entities[ent].current.origin[0] + forward[0] * M_Flash.monster_flash_offset[flash_number][0] + right[0] * M_Flash.monster_flash_offset[flash_number][1]; origin[1] = cl_entities[ent].current.origin[1] + forward[1] * M_Flash.monster_flash_offset[flash_number][0] + right[1] * M_Flash.monster_flash_offset[flash_number][1]; origin[2] = cl_entities[ent].current.origin[2] + forward[2] * M_Flash.monster_flash_offset[flash_number][0] + right[2] * M_Flash.monster_flash_offset[flash_number][1] + M_Flash.monster_flash_offset[flash_number][2]; dl = CL.AllocDlight(ent); VectorCopy(origin, dl.origin); dl.radius = 200 + (rand() & 31); dl.minlight = 32; dl.die = cl.time; // + 0.1; switch (flash_number) { case MZ2_INFANTRY_MACHINEGUN_1 : case MZ2_INFANTRY_MACHINEGUN_2 : case MZ2_INFANTRY_MACHINEGUN_3 : case MZ2_INFANTRY_MACHINEGUN_4 : case MZ2_INFANTRY_MACHINEGUN_5 : case MZ2_INFANTRY_MACHINEGUN_6 : case MZ2_INFANTRY_MACHINEGUN_7 : case MZ2_INFANTRY_MACHINEGUN_8 : case MZ2_INFANTRY_MACHINEGUN_9 : case MZ2_INFANTRY_MACHINEGUN_10 : case MZ2_INFANTRY_MACHINEGUN_11 : case MZ2_INFANTRY_MACHINEGUN_12 : case MZ2_INFANTRY_MACHINEGUN_13 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0); break; case MZ2_SOLDIER_MACHINEGUN_1 : case MZ2_SOLDIER_MACHINEGUN_2 : case MZ2_SOLDIER_MACHINEGUN_3 : case MZ2_SOLDIER_MACHINEGUN_4 : case MZ2_SOLDIER_MACHINEGUN_5 : case MZ2_SOLDIER_MACHINEGUN_6 : case MZ2_SOLDIER_MACHINEGUN_7 : case MZ2_SOLDIER_MACHINEGUN_8 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("soldier/solatck3.wav"), 1, ATTN_NORM, 0); break; case MZ2_GUNNER_MACHINEGUN_1 : case MZ2_GUNNER_MACHINEGUN_2 : case MZ2_GUNNER_MACHINEGUN_3 : case MZ2_GUNNER_MACHINEGUN_4 : case MZ2_GUNNER_MACHINEGUN_5 : case MZ2_GUNNER_MACHINEGUN_6 : case MZ2_GUNNER_MACHINEGUN_7 : case MZ2_GUNNER_MACHINEGUN_8 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("gunner/gunatck2.wav"), 1, ATTN_NORM, 0); break; case MZ2_ACTOR_MACHINEGUN_1 : case MZ2_SUPERTANK_MACHINEGUN_1 : case MZ2_SUPERTANK_MACHINEGUN_2 : case MZ2_SUPERTANK_MACHINEGUN_3 : case MZ2_SUPERTANK_MACHINEGUN_4 : case MZ2_SUPERTANK_MACHINEGUN_5 : case MZ2_SUPERTANK_MACHINEGUN_6 : case MZ2_TURRET_MACHINEGUN : // PGM dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0); break; case MZ2_BOSS2_MACHINEGUN_L1 : case MZ2_BOSS2_MACHINEGUN_L2 : case MZ2_BOSS2_MACHINEGUN_L3 : case MZ2_BOSS2_MACHINEGUN_L4 : case MZ2_BOSS2_MACHINEGUN_L5 : case MZ2_CARRIER_MACHINEGUN_L1 : // PMM case MZ2_CARRIER_MACHINEGUN_L2 : // PMM dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, ATTN_NONE, 0); break; case MZ2_SOLDIER_BLASTER_1 : case MZ2_SOLDIER_BLASTER_2 : case MZ2_SOLDIER_BLASTER_3 : case MZ2_SOLDIER_BLASTER_4 : case MZ2_SOLDIER_BLASTER_5 : case MZ2_SOLDIER_BLASTER_6 : case MZ2_SOLDIER_BLASTER_7 : case MZ2_SOLDIER_BLASTER_8 : case MZ2_TURRET_BLASTER : // PGM dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("soldier/solatck2.wav"), 1, ATTN_NORM, 0); break; case MZ2_FLYER_BLASTER_1 : case MZ2_FLYER_BLASTER_2 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("flyer/flyatck3.wav"), 1, ATTN_NORM, 0); break; case MZ2_MEDIC_BLASTER_1 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("medic/medatck1.wav"), 1, ATTN_NORM, 0); break; case MZ2_HOVER_BLASTER_1 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("hover/hovatck1.wav"), 1, ATTN_NORM, 0); break; case MZ2_FLOAT_BLASTER_1 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("floater/fltatck1.wav"), 1, ATTN_NORM, 0); break; case MZ2_SOLDIER_SHOTGUN_1 : case MZ2_SOLDIER_SHOTGUN_2 : case MZ2_SOLDIER_SHOTGUN_3 : case MZ2_SOLDIER_SHOTGUN_4 : case MZ2_SOLDIER_SHOTGUN_5 : case MZ2_SOLDIER_SHOTGUN_6 : case MZ2_SOLDIER_SHOTGUN_7 : case MZ2_SOLDIER_SHOTGUN_8 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.SmokeAndFlash(origin); S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("soldier/solatck1.wav"), 1, ATTN_NORM, 0); break; case MZ2_TANK_BLASTER_1 : case MZ2_TANK_BLASTER_2 : case MZ2_TANK_BLASTER_3 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0); break; case MZ2_TANK_MACHINEGUN_1 : case MZ2_TANK_MACHINEGUN_2 : case MZ2_TANK_MACHINEGUN_3 : case MZ2_TANK_MACHINEGUN_4 : case MZ2_TANK_MACHINEGUN_5 : case MZ2_TANK_MACHINEGUN_6 : case MZ2_TANK_MACHINEGUN_7 : case MZ2_TANK_MACHINEGUN_8 : case MZ2_TANK_MACHINEGUN_9 : case MZ2_TANK_MACHINEGUN_10 : case MZ2_TANK_MACHINEGUN_11 : case MZ2_TANK_MACHINEGUN_12 : case MZ2_TANK_MACHINEGUN_13 : case MZ2_TANK_MACHINEGUN_14 : case MZ2_TANK_MACHINEGUN_15 : case MZ2_TANK_MACHINEGUN_16 : case MZ2_TANK_MACHINEGUN_17 : case MZ2_TANK_MACHINEGUN_18 : case MZ2_TANK_MACHINEGUN_19 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); //Com_sprintf(soundname, sizeof(soundname), "tank/tnkatk2%c.wav", 'a' + rand() % 5); soundname = "tank/tnkatk2" + (char) ('a' + rand() % 5) + ".wav"; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound(soundname), 1, ATTN_NORM, 0); break; case MZ2_CHICK_ROCKET_1 : case MZ2_TURRET_ROCKET : // PGM dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0.2f; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("chick/chkatck2.wav"), 1, ATTN_NORM, 0); break; case MZ2_TANK_ROCKET_1 : case MZ2_TANK_ROCKET_2 : case MZ2_TANK_ROCKET_3 : dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0.2f; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/tnkatck1.wav"), 1, ATTN_NORM, 0); break; case MZ2_SUPERTANK_ROCKET_1 : case MZ2_SUPERTANK_ROCKET_2 : case MZ2_SUPERTANK_ROCKET_3 : case MZ2_BOSS2_ROCKET_1 : case MZ2_BOSS2_ROCKET_2 : case MZ2_BOSS2_ROCKET_3 : case MZ2_BOSS2_ROCKET_4 : case MZ2_CARRIER_ROCKET_1 : // case MZ2_CARRIER_ROCKET_2: // case MZ2_CARRIER_ROCKET_3: // case MZ2_CARRIER_ROCKET_4: dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0.2f; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/rocket.wav"), 1, ATTN_NORM, 0); break; case MZ2_GUNNER_GRENADE_1 : case MZ2_GUNNER_GRENADE_2 : case MZ2_GUNNER_GRENADE_3 : case MZ2_GUNNER_GRENADE_4 : dl.color[0] = 1; dl.color[1] = 0.5f; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("gunner/gunatck3.wav"), 1, ATTN_NORM, 0); break; case MZ2_GLADIATOR_RAILGUN_1 : // PMM case MZ2_CARRIER_RAILGUN : case MZ2_WIDOW_RAIL : // pmm dl.color[0] = 0.5f; dl.color[1] = 0.5f; dl.color[2] = 1.0f; break; // --- Xian's shit starts --- case MZ2_MAKRON_BFG : dl.color[0] = 0.5f; dl.color[1] = 1; dl.color[2] = 0.5f; //S.StartSound (null, ent, CHAN_WEAPON, S.RegisterSound("makron/bfg_fire.wav"), 1, ATTN_NORM, 0); break; case MZ2_MAKRON_BLASTER_1 : case MZ2_MAKRON_BLASTER_2 : case MZ2_MAKRON_BLASTER_3 : case MZ2_MAKRON_BLASTER_4 : case MZ2_MAKRON_BLASTER_5 : case MZ2_MAKRON_BLASTER_6 : case MZ2_MAKRON_BLASTER_7 : case MZ2_MAKRON_BLASTER_8 : case MZ2_MAKRON_BLASTER_9 : case MZ2_MAKRON_BLASTER_10 : case MZ2_MAKRON_BLASTER_11 : case MZ2_MAKRON_BLASTER_12 : case MZ2_MAKRON_BLASTER_13 : case MZ2_MAKRON_BLASTER_14 : case MZ2_MAKRON_BLASTER_15 : case MZ2_MAKRON_BLASTER_16 : case MZ2_MAKRON_BLASTER_17 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("makron/blaster.wav"), 1, ATTN_NORM, 0); break; case MZ2_JORG_MACHINEGUN_L1 : case MZ2_JORG_MACHINEGUN_L2 : case MZ2_JORG_MACHINEGUN_L3 : case MZ2_JORG_MACHINEGUN_L4 : case MZ2_JORG_MACHINEGUN_L5 : case MZ2_JORG_MACHINEGUN_L6 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("boss3/xfire.wav"), 1, ATTN_NORM, 0); break; case MZ2_JORG_MACHINEGUN_R1 : case MZ2_JORG_MACHINEGUN_R2 : case MZ2_JORG_MACHINEGUN_R3 : case MZ2_JORG_MACHINEGUN_R4 : case MZ2_JORG_MACHINEGUN_R5 : case MZ2_JORG_MACHINEGUN_R6 : dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); break; case MZ2_JORG_BFG_1 : dl.color[0] = 0.5f; dl.color[1] = 1; dl.color[2] = 0.5f; break; case MZ2_BOSS2_MACHINEGUN_R1 : case MZ2_BOSS2_MACHINEGUN_R2 : case MZ2_BOSS2_MACHINEGUN_R3 : case MZ2_BOSS2_MACHINEGUN_R4 : case MZ2_BOSS2_MACHINEGUN_R5 : case MZ2_CARRIER_MACHINEGUN_R1 : // PMM case MZ2_CARRIER_MACHINEGUN_R2 : // PMM dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; CL.ParticleEffect(origin, vec3_origin, 0, 40); CL.SmokeAndFlash(origin); break; // ====== // ROGUE case MZ2_STALKER_BLASTER : case MZ2_DAEDALUS_BLASTER : case MZ2_MEDIC_BLASTER_2 : case MZ2_WIDOW_BLASTER : case MZ2_WIDOW_BLASTER_SWEEP1 : case MZ2_WIDOW_BLASTER_SWEEP2 : case MZ2_WIDOW_BLASTER_SWEEP3 : case MZ2_WIDOW_BLASTER_SWEEP4 : case MZ2_WIDOW_BLASTER_SWEEP5 : case MZ2_WIDOW_BLASTER_SWEEP6 : case MZ2_WIDOW_BLASTER_SWEEP7 : case MZ2_WIDOW_BLASTER_SWEEP8 : case MZ2_WIDOW_BLASTER_SWEEP9 : case MZ2_WIDOW_BLASTER_100 : case MZ2_WIDOW_BLASTER_90 : case MZ2_WIDOW_BLASTER_80 : case MZ2_WIDOW_BLASTER_70 : case MZ2_WIDOW_BLASTER_60 : case MZ2_WIDOW_BLASTER_50 : case MZ2_WIDOW_BLASTER_40 : case MZ2_WIDOW_BLASTER_30 : case MZ2_WIDOW_BLASTER_20 : case MZ2_WIDOW_BLASTER_10 : case MZ2_WIDOW_BLASTER_0 : case MZ2_WIDOW_BLASTER_10L : case MZ2_WIDOW_BLASTER_20L : case MZ2_WIDOW_BLASTER_30L : case MZ2_WIDOW_BLASTER_40L : case MZ2_WIDOW_BLASTER_50L : case MZ2_WIDOW_BLASTER_60L : case MZ2_WIDOW_BLASTER_70L : case MZ2_WIDOW_RUN_1 : case MZ2_WIDOW_RUN_2 : case MZ2_WIDOW_RUN_3 : case MZ2_WIDOW_RUN_4 : case MZ2_WIDOW_RUN_5 : case MZ2_WIDOW_RUN_6 : case MZ2_WIDOW_RUN_7 : case MZ2_WIDOW_RUN_8 : dl.color[0] = 0; dl.color[1] = 1; dl.color[2] = 0; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0); break; case MZ2_WIDOW_DISRUPTOR : dl.color[0] = -1; dl.color[1] = -1; dl.color[2] = -1; S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("weapons/disint2.wav"), 1, ATTN_NORM, 0); break; case MZ2_WIDOW_PLASMABEAM : case MZ2_WIDOW2_BEAMER_1 : case MZ2_WIDOW2_BEAMER_2 : case MZ2_WIDOW2_BEAMER_3 : case MZ2_WIDOW2_BEAMER_4 : case MZ2_WIDOW2_BEAMER_5 : case MZ2_WIDOW2_BEAM_SWEEP_1 : case MZ2_WIDOW2_BEAM_SWEEP_2 : case MZ2_WIDOW2_BEAM_SWEEP_3 : case MZ2_WIDOW2_BEAM_SWEEP_4 : case MZ2_WIDOW2_BEAM_SWEEP_5 : case MZ2_WIDOW2_BEAM_SWEEP_6 : case MZ2_WIDOW2_BEAM_SWEEP_7 : case MZ2_WIDOW2_BEAM_SWEEP_8 : case MZ2_WIDOW2_BEAM_SWEEP_9 : case MZ2_WIDOW2_BEAM_SWEEP_10 : case MZ2_WIDOW2_BEAM_SWEEP_11 : dl.radius = 300 + (rand() & 100); dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 0; dl.die = cl.time + 200; break; // ROGUE // ====== // --- Xian's shit ends --- } } /* =============== CL_AddDLights =============== */ static void AddDLights() { int i; cdlight_t[] dl; dl = cl_dlights; // ===== // PGM if (vidref_val == VIDREF_GL) { for (i = 0; i < MAX_DLIGHTS; i++) { if (dl[i].radius == 0.0f) continue; V.AddLight(dl[i].origin, dl[i].radius, dl[i].color[0], dl[i].color[1], dl[i].color[2]); } } else { for (i = 0; i < MAX_DLIGHTS; i++) { if (dl[i].radius == 0.0f) continue; // negative light in software. only black allowed if ((dl[i].color[0] < 0) || (dl[i].color[1] < 0) || (dl[i].color[2] < 0)) { dl[i].radius = - (dl[i].radius); dl[i].color[0] = 1; dl[i].color[1] = 1; dl[i].color[2] = 1; } V.AddLight(dl[i].origin, dl[i].radius, dl[i].color[0], dl[i].color[1], dl[i].color[2]); } } // PGM // ===== } /* ============================================================== PARTICLE MANAGEMENT ============================================================== */ static final int PARTICLE_GRAVITY = 40; static cparticle_t active_particles, free_particles; static cparticle_t[] particles = new cparticle_t[MAX_PARTICLES]; static { for (int i = 0; i < particles.length; i++) particles[i] = new cparticle_t(); } static int cl_numparticles = MAX_PARTICLES; /* =============== CL_ClearParticles =============== */ static void ClearParticles() { int i; free_particles = particles[0]; active_particles = null; for (i=0 ; i 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 + frand() * 0.2f); p.color = 0xe0; 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); } } /* =============== CL_QuadTrail =============== */ static void QuadTrail(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); 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 + frand() * 0.2f); p.color = 115; 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_FlagTrail =============== */ static void FlagTrail(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 + frand() * 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_DiminishingTrail =============== */ static void DiminishingTrail(float[] start, float[] end, centity_t old, int flags) { float[] move = new float[3]; float[] vec = new float[3]; float len; int j; cparticle_t p; float dec; float orgscale; float velscale; VectorCopy(start, move); VectorSubtract(end, start, vec); len = VectorNormalize(vec); dec = 0.5f; VectorScale(vec, dec, vec); if (old.trailcount > 900) { orgscale = 4; velscale = 15; } else if (old.trailcount > 800) { orgscale = 2; velscale = 10; } else { orgscale = 1; velscale = 5; } while (len > 0) { len -= dec; if (free_particles == null) return; // drop less particles as it flies if ((rand() & 1023) < old.trailcount) { p = free_particles; free_particles = p.next; p.next = active_particles; active_particles = p; VectorClear(p.accel); p.time = cl.time; if ((flags & EF_GIB) != 0) { p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + frand() * 0.4f); p.color = 0xe8 + (rand() & 7); for (j = 0; j < 3; j++) { p.org[j] = move[j] + crand() * orgscale; p.vel[j] = crand() * velscale; p.accel[j] = 0; } p.vel[2] -= PARTICLE_GRAVITY; } else if ((flags & EF_GREENGIB) != 0) { p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + frand() * 0.4f); p.color = 0xdb + (rand() & 7); for (j = 0; j < 3; j++) { p.org[j] = move[j] + crand() * orgscale; p.vel[j] = crand() * velscale; p.accel[j] = 0; } p.vel[2] -= PARTICLE_GRAVITY; } else { p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + frand() * 0.2f); p.color = 4 + (rand() & 7); for (j = 0; j < 3; j++) { p.org[j] = move[j] + crand() * orgscale; p.vel[j] = crand() * velscale; } p.accel[2] = 20; } } old.trailcount -= 5; if (old.trailcount < 100) old.trailcount = 100; VectorAdd(move, vec, move); } } /* =============== CL_RocketTrail =============== */ static void RocketTrail(float[] start, float[] end, centity_t old) { float[] move = new float[3]; float[] vec = new float[3]; float len; int j; cparticle_t p; float dec; // smoke CL.DiminishingTrail(start, end, old, EF_ROCKET); // fire VectorCopy(start, move); VectorSubtract(end, start, vec); len = VectorNormalize(vec); dec = 1; VectorScale(vec, dec, vec); while (len > 0) { len -= dec; if (free_particles == null) return; if ((rand() & 7) == 0) { 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.0f + frand() * 0.2f); p.color = 0xdc + (rand() & 3); for (j = 0; j < 3; j++) { p.org[j] = move[j] + crand() * 5; p.vel[j] = crand() * 20; } p.accel[2] = -PARTICLE_GRAVITY; } VectorAdd(move, vec, move); } } /* =============== CL_RailTrail =============== */ static void RailTrail(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 = new float[3]; byte clr = 0x74; VectorCopy(start, move); VectorSubtract(end, start, vec); len = VectorNormalize(vec); MakeNormalVectors(vec, right, up); for (i = 0; i < len; i++) { 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); d = i * 0.1f; c = (float)Math.cos(d); s = (float)Math.sin(d); VectorScale(right, c, dir); VectorMA(dir, s, up, dir); p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + frand() * 0.2f); p.color = clr + (rand() & 7); for (j = 0; j < 3; j++) { p.org[j] = move[j] + dir[j] * 3; p.vel[j] = dir[j] * 6; } VectorAdd(move, vec, move); } dec = 0.75f; 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); p.alpha = 1.0f; p.alphavel = -1.0f / (0.6f + frand() * 0.2f); p.color = 0x0 + rand() & 15; for (j = 0; j < 3; j++) { p.org[j] = move[j] + crand() * 3; p.vel[j] = crand() * 3; p.accel[j] = 0; } VectorAdd(move, vec, move); } } // RAFAEL /* =============== CL_IonripperTrail =============== */ static void IonripperTrail(float[] start, float[] ent) { float[] move = new float[3]; float[] vec = new float[3]; float len; int j; cparticle_t p; int dec; int left = 0; VectorCopy(start, move); VectorSubtract(ent, 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 = 0.5f; p.alphavel = -1.0f / (0.3f + frand() * 0.2f); p.color = 0xe4 + (rand() & 3); for (j = 0; j < 3; j++) { p.org[j] = move[j]; p.accel[j] = 0; } if (left != 0) { left = 0; p.vel[0] = 10; } else { left = 1; p.vel[0] = -10; } p.vel[1] = 0; p.vel[2] = 0; VectorAdd(move, vec, move); } } /* =============== CL_BubbleTrail =============== */ static void BubbleTrail(float[] start, float[] end) { 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 = 32; 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.0f + frand() * 0.2f); p.color = 4 + (rand() & 7); for (j = 0; j < 3; j++) { p.org[j] = move[j] + crand() * 2; p.vel[j] = crand() * 5; } p.vel[2] += 6; VectorAdd(move, vec, move); } } /* =============== CL_FlyParticles =============== */ private static final int BEAMLENGTH = 16; static void FlyParticles (float [] origin, int count) { int i; cparticle_t p; float angle; float sr, sp, sy, cr, cp, cy; float [] forward= new float[3]; float dist = 64; float ltime; if (count > NUMVERTEXNORMALS) count = NUMVERTEXNORMALS; if (avelocities[0][0] == 0.0f) { for (i=0 ; i 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 + frand() * 0.2f); p.color = 0xe0; for (j = 0; j < 3; j++) { p.org[j] = move[j] + crand(); p.vel[j] = crand() * 15; p.accel[j] = 0; } p.accel[2] = PARTICLE_GRAVITY; VectorAdd(move, vec, move); } int i, k; //cparticle_t p; float vel; float[] dir = new float[3]; float[] org = new float[3]; ent.origin[2] += 14; VectorCopy(ent.origin, org); for (i = -2; i <= 2; i += 4) for (j = -2; j <= 2; j += 4) for (k = -2; k <= 4; k += 4) { 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 = 0xe0 + (rand() & 3); p.alpha = 1.0f; p.alphavel = -1.0f / (0.3f + (rand() & 7) * 0.02f); p.org[0] = org[0] + i + ((rand() & 23) * crand()); p.org[1] = org[1] + j + ((rand() & 23) * crand()); p.org[2] = org[2] + k + ((rand() & 23) * crand()); dir[0] = j * 8; dir[1] = i * 8; dir[2] = k * 8; VectorNormalize(dir); vel = 50 + rand() & 63; VectorScale(dir, vel, p.vel); p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY; } } /* =============== CL_BFGExplosionParticles =============== */ // FIXME combined with CL_ExplosionParticles static void BFGExplosionParticles(float[] org) { int i, j; cparticle_t p; 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 = 0xd0 + (rand() & 7); for (j = 0; j < 3; j++) { p.org[j] = org[j] + ((rand() % 32) - 16); p.vel[j] = (rand() % 384) - 192; } p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY; p.alpha = 1.0f; p.alphavel = -0.8f / (0.5f + frand() * 0.3f); } } /* =============== CL_TeleportParticles =============== */ static void TeleportParticles(float[] org) { int i, j, k; cparticle_t p; float vel; float[] dir = new float[3]; for (i = -16; i <= 16; i += 4) for (j = -16; j <= 16; j += 4) for (k = -16; k <= 32; k += 4) { 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 = 7 + (rand() & 7); p.alpha = 1.0f; p.alphavel = -1.0f / (0.3f + (rand() & 7) * 0.02f); p.org[0] = org[0] + i + (rand() & 3); p.org[1] = org[1] + j + (rand() & 3); p.org[2] = org[2] + k + (rand() & 3); dir[0] = j * 8; dir[1] = i * 8; dir[2] = k * 8; VectorNormalize(dir); vel = 50 + (rand() & 63); VectorScale(dir, vel, p.vel); p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY; } } /* =============== CL_AddParticles =============== */ static void AddParticles() { cparticle_t p, next; float alpha; float time = 0.0f; float time2; float[] org = new float[3]; int color; cparticle_t active, tail; active = null; tail = null; for (p = active_particles; p != null; p = next) { next = p.next; // PMM - added INSTANT_PARTICLE handling for heat beam if (p.alphavel != INSTANT_PARTICLE) { time = (cl.time - p.time) * 0.001f; alpha = p.alpha + time * p.alphavel; if (alpha <= 0) { // faded out p.next = free_particles; free_particles = p; continue; } } else { alpha = p.alpha; } p.next = null; if (tail == null) active = tail = p; else { tail.next = p; tail = p; } if (alpha > 1.0) alpha = 1; color = (int)p.color; time2 = time * time; 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; V.AddParticle(org, color, alpha); // PMM if (p.alphavel == INSTANT_PARTICLE) { p.alphavel = 0.0f; p.alpha = 0.0f; } } active_particles = active; } /* ============== CL_EntityEvent An entity has just been parsed that has an event value the female events are there for backwards compatability ============== */ static void EntityEvent(entity_state_t ent) { switch (ent.event) { case EV_ITEM_RESPAWN : S.StartSound(null, ent.number, CHAN_WEAPON, S.RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0); CL.ItemRespawnParticles(ent.origin); break; case EV_PLAYER_TELEPORT : S.StartSound(null, ent.number, CHAN_WEAPON, S.RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0); CL.TeleportParticles(ent.origin); break; case EV_FOOTSTEP : if (cl_footsteps.value != 0.0f) S.StartSound(null, ent.number, CHAN_BODY, cl_sfx_footsteps[rand() & 3], 1, ATTN_NORM, 0); break; case EV_FALLSHORT : S.StartSound(null, ent.number, CHAN_AUTO, S.RegisterSound("player/land1.wav"), 1, ATTN_NORM, 0); break; case EV_FALL : S.StartSound(null, ent.number, CHAN_AUTO, S.RegisterSound("*fall2.wav"), 1, ATTN_NORM, 0); break; case EV_FALLFAR : S.StartSound(null, ent.number, CHAN_AUTO, S.RegisterSound("*fall1.wav"), 1, ATTN_NORM, 0); break; } } /* ============== CL_ClearEffects ============== */ static void ClearEffects() { CL.ClearParticles(); CL.ClearDlights(); CL.ClearLightStyles(); } }