/* 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. */ // // cg_partgloom.c // #include "cg_local.h" /* ============================================================================= GLOOM SPECIFIC PARTICLE EFFECTS ============================================================================= */ /* =============== CG_GloomBlobTip =============== */ void CG_GloomBlobTip (vec3_t start, vec3_t end) { vec3_t move, vec, tmpstart, tmpend; float len, dec, rnum, rnum2; // I AM LAME ASS -- HEAR MY ROAR! Vec3Copy (start, tmpstart); Vec3Copy (end, tmpend); tmpstart[2] += 12; tmpend[2] += 12; // I AM LAME ASS -- HEAR MY ROAR! // bubbles CG_BubbleEffect (tmpstart); Vec3Copy (tmpstart, move); Vec3Subtract (tmpstart, tmpend, vec); len = VectorNormalizeFastf (vec); dec = 2; Vec3Scale (vec, dec, vec); for (; len>0 ; Vec3Add (move, vec, move)) { len -= dec; rnum = (rand () % 2) ? 100 + (frand () * 30) : (frand () * 30); rnum2 = (frand () * 40); CG_SpawnParticle ( move[0] + crand (), move[1] + crand (), move[2] + crand (), 0, 0, 0, 0, 0, 0, 0, 0, 0, rnum, 200 + rnum2, rnum, rnum, 200 + rnum2, rnum, 0.9f, -15, 3.5f + (frand () * 4), 3.5f + (frand () * 2.5f), PT_FLAREGLOW, PF_SCALED|PF_ALPHACOLOR, 0, qFalse, PART_STYLE_QUAD, 0); } } /* =============== CG_GloomDroneEffect =============== */ void CG_GloomDroneEffect (vec3_t org, vec3_t dir) { float i, d; float rnum, rnum2; // Decal for (i=0 ; i<2 ; i++) { rnum = 10 + (frand () * 30); rnum2 = (frand () * 40); CG_SpawnDecal ( org[0], org[1], org[2], dir[0], dir[1], dir[2], 200 * i, 215 + (rnum * (1 - i)), 200 * i, 200 * i, 215 + (rnum2 * (1 - i)), 200 * i, 1.0f, 1.0f, 12 + crand () - (4.5f * i), DT_DRONE_SPIT_GLOW, DF_ALPHACOLOR, 0, qFalse, 0, frand () * 360); } // Particles for (i=0 ; i<40 ; i++) { d = 2 + (frand () * 22); rnum = 20 + (frand () * 30); rnum2 = (frand () * 40) + (rand () % 2 * 30); if (rand () % 2) { rnum += 90 + (frand () * 10); rnum2 += 40 + (frand () * 10); } CG_SpawnParticle ( org[0] + (crand () * 4) + d*dir[0], org[1] + (crand () * 4) + d*dir[1], org[2] + (crand () * 4) + d*dir[2], 0, 0, 0, crand () * 20, crand () * 20, crand () * 20, 0, 0, -40, rnum, 150 + rnum2, rnum, rnum, 150 + rnum2, rnum, 1.0f, -1.0f / (0.5f + (frand () * 0.3f)), 7 + crand (), 3 + crand (), PT_FLAREGLOW, PF_SCALED|PF_GRAVITY|PF_ALPHACOLOR|PF_NOCLOSECULL, pBounceThink, qTrue, PART_STYLE_QUAD, 0); } } /* =============== CG_GloomEmberTrail =============== */ void CG_GloomEmberTrail (vec3_t start, vec3_t end) { float rnum, rnum2; float dec, len; vec3_t move, vec; Vec3Copy (start, move); Vec3Subtract (end, start, vec); len = VectorNormalizeFastf (vec); dec = 14; Vec3Scale (vec, dec, vec); for (; len>0 ; Vec3Add (move, vec, move)) { len -= dec; // Explosion anim CG_SpawnParticle ( move[0] + (crand () * 2), move[1] + (crand () * 2), move[2] + (crand () * 2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 245, 255, 245, 245, 255, 1.0f, -3.5f + (crand () * 0.1f), 10 + (crand () * 5), 70 + (crand () * 10), PT_EXPLO1 + (rand () % 6), PF_ALPHACOLOR, 0, qFalse, PART_STYLE_QUAD, crand () * 12); // Smoke rnum = 60 + (frand () * 50); rnum2 = 70 + (frand () * 50); CG_SpawnParticle ( start[0] + (crand () * 4), start[1] + (crand () * 4), start[2] + (crand () * 4), 0, 0, 0, crand () * 2, crand () * 2, crand () * 2, crand () * 2, crand () * 2, crand () + (rand () % 4), rnum, rnum, rnum, rnum2, rnum2, rnum2, 0.8f, -1.0f / (0.125f + (cg_particleSmokeLinger->floatVal * 0.1f) + (crand () * 0.1f)), 20 + (crand () * 5), 60 + (crand () * 10), pRandSmoke (), PF_SHADE, NULL, 0, PART_STYLE_QUAD, frand () * 361); } } /* =============== CG_GloomFlareTrail =============== */ void CG_GloomFlareTrail (vec3_t start, vec3_t end) { vec3_t move, vec; float len, dec; float rnum, rnum2; // Tip CG_FlareEffect (start, PT_FLAREGLOW, 0, 25, 25, 0x0f, 0x0f, 0.66f + (frand () * 0.1f), PART_INSTANT); // core CG_FlareEffect (start, PT_FLAREGLOW, 0, 30, 30, 0xd0, 0xd0, 0.66f + (frand () * 0.1f), PART_INSTANT); // outer // Following blur Vec3Copy (start, move); Vec3Subtract (end, start, vec); len = VectorNormalizeFastf (vec); dec = 8; Vec3Scale (vec, dec, vec); for (; len>0 ; Vec3Add (move, vec, move)) { len -= dec; // Smoke if (!(rand () & 3)) { rnum = 60 + (frand () * 50); rnum2 = 70 + (frand () * 50); CG_SpawnParticle ( start[0] + (crand () * 2), start[1] + (crand () * 2), start[2] + (crand () * 2), 0, 0, 0, crand () * 3, crand () * 3, crand () * 3, 0, 0, 5, rnum, rnum, rnum, rnum2, rnum2, rnum2, 0.3f + (frand () * 0.1f), -1.0f / (1.5f + (cg_particleSmokeLinger->floatVal * 0.5f) + (crand () * 0.2f)), 10 + (crand () * 5), 30 + (crand () * 5), pRandSmoke (), PF_SHADE, pSmokeThink, qTrue, PART_STYLE_QUAD, frand () * 360); } // Glowing trail CG_FlareEffect (move, PT_FLAREGLOW, 0, 20, 15, 0xd0, 0xd0, 0.5f + (frand () * 0.1f), -2.25); // outer } } /* =============== CG_GloomGasEffect =============== */ void CG_GloomGasEffect (vec3_t origin) { float rnum, rnum2; if (rand () & 3) return; rnum = (float)(rand () % 61); rnum2 = (float)(rand () % 61); CG_SpawnParticle ( origin[0] + (crand () * 2), origin[1] + (crand () * 2), origin[2] + (crand () * 2), 0, 0, 0, 0, 0, 0, 0, 0, (frand () * 3), 70 + rnum, 100 + rnum, 70 + rnum, 70 + rnum2, 110 + rnum2, 70 + rnum2, 0.35f, -1.0f / (5.1f + (frand () * 0.2f)), 30 + (frand () * 10), 300 + (crand () * 50), pRandSmoke (), PF_SHADE, pSmokeThink, qTrue, PART_STYLE_QUAD, frand () * 360); } /* =============== CG_GloomRepairEffect =============== */ void CG_GloomRepairEffect (vec3_t org, vec3_t dir, int count) { int i, rnum, rnum2; float d; for (i=0 ; i<2 ; i++) { // Glow marks rnum = (rand () % 5); rnum2 = (rand () % 5); CG_SpawnDecal ( org[0], org[1], org[2], dir[0], dir[1], dir[2], palRed (0xe0 + rnum), palGreen (0xe0 + rnum), palBlue (0xe0 + rnum), palRed (0xe0 + rnum2), palGreen (0xe0 + rnum2), palBlue (0xe0 + rnum2), 1.0f, 0, 3 + (frand () * 0.5f), DT_ENGYREPAIR_GLOWMARK, DF_USE_BURNLIFE|DF_ALPHACOLOR, 0, qFalse, 0, frand () * 360); } // Burn mark rnum = (rand () % 5); CG_SpawnDecal ( org[0], org[1], org[2], dir[0], dir[1], dir[2], (255-palRed(0xe0+rnum))*0.5f+128, (255-palGreen(0xe0+rnum))*0.5f+128, (255-palBlue(0xe0+rnum))*0.5f+128, 0, 0, 0, 0.9f + (crand () * 0.1f), 0.8f, 2 + (frand () * 0.5f), DT_ENGYREPAIR_BURNMARK, DF_ALPHACOLOR, 0, qFalse, 0, frand () * 360); // Dots for (i=0 ; iintVal) cgi.R_AddLight (start, 175 + (frand () * 25), 0.1f, 0, 0.9f + (frand () * 0.1f)); else if (inWater) cgi.R_AddLight (start, 175 + (frand () * 25), 0.8f + (frand () * 0.2f), 0.7f + (frand () * 0.2f), 0.5f); else cgi.R_AddLight (start, 175 + (frand () * 25), 0.9f + (frand () * 0.1f), 0.8f + (frand () * 0.1f), 0); } if (glm_bluestingfire->intVal) { tipimage = trailimage = PT_BLUEFIRE; } else { tipimage = (inWater) ? PT_BLUEFIRE : pRandFire (); trailimage = pRandFire (); } waterScale = (inWater || glm_bluestingfire->intVal) ? 100.0f : 0.0f; if (rand () & 1) { // Tip CG_SpawnParticle ( start[0] + (crand () * 2), start[1] + (crand () * 2), start[2] + (crand () * 2), 0, 0, 0, crand () * 2, crand () * 2, crand () * 2, 0, 0, 0, 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20), 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20), 0.6f + (crand () * 0.1f), -0.3f / (0.05f + (frand () * 0.1f)), size + (crand () * 2), (size * 0.25f) + (crand () * 3), tipimage, PF_SCALED|PF_ALPHACOLOR, pFireThink, qTrue, PART_STYLE_QUAD, frand () * 360); } else { // Parts that spiral away CG_SpawnParticle ( start[0] + (crand () * 2), start[1] + (crand () * 2), start[2] + (crand () * 2), 0, 0, 0, crand () * 80, crand () * 80, crand () * 80, 0, 0, 0, 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20), 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20), 0.6f + (crand () * 0.1f), -0.3f / (0.05f + (frand () * 0.1f)), (size * 0.6f) + (crand () * 2), (size * 1.2f) + (crand () * 2), tipimage, PF_SCALED|PF_ALPHACOLOR, pFireThink, qTrue, PART_STYLE_QUAD, frand () * 360); } // Fire for (; len>0 ; Vec3Add (move, vec, move)) { len -= dec; CG_SpawnParticle ( move[0] + (crand () * 8), move[1] + (crand () * 8), move[2] + (crand () * 8), 0, 0, 0, crand () * 2, crand () * 2, crand () * 2, 0, 0, 0, 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20) - waterScale, 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20) - waterScale, 0.6f + (frand () * 0.2f), -0.25f / (0.05f + (frand () * 0.1f)), (size * 0.8f) + (crand () * 2), 2 + crand (), trailimage, PF_SCALED|PF_ALPHACOLOR, pFireThink, qTrue, PART_STYLE_QUAD, frand () * 360); } }