1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 //
21 // cg_partgloom.c
22 //
23
24 #include "cg_local.h"
25
26 /*
27 =============================================================================
28
29 GLOOM SPECIFIC PARTICLE EFFECTS
30
31 =============================================================================
32 */
33
34 /*
35 ===============
36 CG_GloomBlobTip
37 ===============
38 */
CG_GloomBlobTip(vec3_t start,vec3_t end)39 void CG_GloomBlobTip (vec3_t start, vec3_t end)
40 {
41 vec3_t move, vec, tmpstart, tmpend;
42 float len, dec, rnum, rnum2;
43
44 // I AM LAME ASS -- HEAR MY ROAR!
45 Vec3Copy (start, tmpstart);
46 Vec3Copy (end, tmpend);
47 tmpstart[2] += 12;
48 tmpend[2] += 12;
49 // I AM LAME ASS -- HEAR MY ROAR!
50
51 // bubbles
52 CG_BubbleEffect (tmpstart);
53
54 Vec3Copy (tmpstart, move);
55 Vec3Subtract (tmpstart, tmpend, vec);
56 len = VectorNormalizeFastf (vec);
57
58 dec = 2;
59 Vec3Scale (vec, dec, vec);
60
61 for (; len>0 ; Vec3Add (move, vec, move)) {
62 len -= dec;
63
64 rnum = (rand () % 2) ? 100 + (frand () * 30) : (frand () * 30);
65 rnum2 = (frand () * 40);
66 CG_SpawnParticle (
67 move[0] + crand (), move[1] + crand (), move[2] + crand (),
68 0, 0, 0,
69 0, 0, 0,
70 0, 0, 0,
71 rnum, 200 + rnum2, rnum,
72 rnum, 200 + rnum2, rnum,
73 0.9f, -15,
74 3.5f + (frand () * 4), 3.5f + (frand () * 2.5f),
75 PT_FLAREGLOW, PF_SCALED|PF_ALPHACOLOR,
76 0, qFalse,
77 PART_STYLE_QUAD,
78 0);
79 }
80 }
81
82
83 /*
84 ===============
85 CG_GloomDroneEffect
86 ===============
87 */
CG_GloomDroneEffect(vec3_t org,vec3_t dir)88 void CG_GloomDroneEffect (vec3_t org, vec3_t dir)
89 {
90 float i, d;
91 float rnum, rnum2;
92
93 // Decal
94 for (i=0 ; i<2 ; i++) {
95 rnum = 10 + (frand () * 30);
96 rnum2 = (frand () * 40);
97 CG_SpawnDecal (
98 org[0], org[1], org[2],
99 dir[0], dir[1], dir[2],
100 200 * i, 215 + (rnum * (1 - i)), 200 * i,
101 200 * i, 215 + (rnum2 * (1 - i)), 200 * i,
102 1.0f, 1.0f,
103 12 + crand () - (4.5f * i),
104 DT_DRONE_SPIT_GLOW, DF_ALPHACOLOR,
105 0, qFalse,
106 0, frand () * 360);
107 }
108
109 // Particles
110 for (i=0 ; i<40 ; i++) {
111 d = 2 + (frand () * 22);
112 rnum = 20 + (frand () * 30);
113 rnum2 = (frand () * 40) + (rand () % 2 * 30);
114
115 if (rand () % 2) {
116 rnum += 90 + (frand () * 10);
117 rnum2 += 40 + (frand () * 10);
118 }
119
120 CG_SpawnParticle (
121 org[0] + (crand () * 4) + d*dir[0], org[1] + (crand () * 4) + d*dir[1], org[2] + (crand () * 4) + d*dir[2],
122 0, 0, 0,
123 crand () * 20, crand () * 20, crand () * 20,
124 0, 0, -40,
125 rnum, 150 + rnum2, rnum,
126 rnum, 150 + rnum2, rnum,
127 1.0f, -1.0f / (0.5f + (frand () * 0.3f)),
128 7 + crand (), 3 + crand (),
129 PT_FLAREGLOW, PF_SCALED|PF_GRAVITY|PF_ALPHACOLOR|PF_NOCLOSECULL,
130 pBounceThink, qTrue,
131 PART_STYLE_QUAD,
132 0);
133 }
134 }
135
136
137 /*
138 ===============
139 CG_GloomEmberTrail
140 ===============
141 */
CG_GloomEmberTrail(vec3_t start,vec3_t end)142 void CG_GloomEmberTrail (vec3_t start, vec3_t end)
143 {
144 float rnum, rnum2;
145 float dec, len;
146 vec3_t move, vec;
147
148 Vec3Copy (start, move);
149 Vec3Subtract (end, start, vec);
150 len = VectorNormalizeFastf (vec);
151
152 dec = 14;
153 Vec3Scale (vec, dec, vec);
154
155 for (; len>0 ; Vec3Add (move, vec, move)) {
156 len -= dec;
157
158 // Explosion anim
159 CG_SpawnParticle (
160 move[0] + (crand () * 2), move[1] + (crand () * 2), move[2] + (crand () * 2),
161 0, 0, 0,
162 0, 0, 0,
163 0, 0, 0,
164 245, 245, 255,
165 245, 245, 255,
166 1.0f, -3.5f + (crand () * 0.1f),
167 10 + (crand () * 5), 70 + (crand () * 10),
168 PT_EXPLO1 + (rand () % 6), PF_ALPHACOLOR,
169 0, qFalse,
170 PART_STYLE_QUAD,
171 crand () * 12);
172
173 // Smoke
174 rnum = 60 + (frand () * 50);
175 rnum2 = 70 + (frand () * 50);
176 CG_SpawnParticle (
177 start[0] + (crand () * 4), start[1] + (crand () * 4), start[2] + (crand () * 4),
178 0, 0, 0,
179 crand () * 2, crand () * 2, crand () * 2,
180 crand () * 2, crand () * 2, crand () + (rand () % 4),
181 rnum, rnum, rnum,
182 rnum2, rnum2, rnum2,
183 0.8f, -1.0f / (0.125f + (cg_particleSmokeLinger->floatVal * 0.1f) + (crand () * 0.1f)),
184 20 + (crand () * 5), 60 + (crand () * 10),
185 pRandSmoke (), PF_SHADE,
186 NULL, 0,
187 PART_STYLE_QUAD,
188 frand () * 361);
189 }
190 }
191
192
193 /*
194 ===============
195 CG_GloomFlareTrail
196 ===============
197 */
CG_GloomFlareTrail(vec3_t start,vec3_t end)198 void CG_GloomFlareTrail (vec3_t start, vec3_t end)
199 {
200 vec3_t move, vec;
201 float len, dec;
202 float rnum, rnum2;
203
204 // Tip
205 CG_FlareEffect (start, PT_FLAREGLOW, 0, 25, 25, 0x0f, 0x0f, 0.66f + (frand () * 0.1f), PART_INSTANT); // core
206 CG_FlareEffect (start, PT_FLAREGLOW, 0, 30, 30, 0xd0, 0xd0, 0.66f + (frand () * 0.1f), PART_INSTANT); // outer
207
208 // Following blur
209 Vec3Copy (start, move);
210 Vec3Subtract (end, start, vec);
211 len = VectorNormalizeFastf (vec);
212
213 dec = 8;
214 Vec3Scale (vec, dec, vec);
215
216 for (; len>0 ; Vec3Add (move, vec, move)) {
217 len -= dec;
218
219 // Smoke
220 if (!(rand () & 3)) {
221 rnum = 60 + (frand () * 50);
222 rnum2 = 70 + (frand () * 50);
223 CG_SpawnParticle (
224 start[0] + (crand () * 2), start[1] + (crand () * 2), start[2] + (crand () * 2),
225 0, 0, 0,
226 crand () * 3, crand () * 3, crand () * 3,
227 0, 0, 5,
228 rnum, rnum, rnum,
229 rnum2, rnum2, rnum2,
230 0.3f + (frand () * 0.1f), -1.0f / (1.5f + (cg_particleSmokeLinger->floatVal * 0.5f) + (crand () * 0.2f)),
231 10 + (crand () * 5), 30 + (crand () * 5),
232 pRandSmoke (), PF_SHADE,
233 pSmokeThink, qTrue,
234 PART_STYLE_QUAD,
235 frand () * 360);
236 }
237
238 // Glowing trail
239 CG_FlareEffect (move, PT_FLAREGLOW, 0, 20, 15, 0xd0, 0xd0, 0.5f + (frand () * 0.1f), -2.25); // outer
240 }
241 }
242
243
244 /*
245 ===============
246 CG_GloomGasEffect
247 ===============
248 */
CG_GloomGasEffect(vec3_t origin)249 void CG_GloomGasEffect (vec3_t origin)
250 {
251 float rnum, rnum2;
252
253 if (rand () & 3)
254 return;
255
256 rnum = (float)(rand () % 61);
257 rnum2 = (float)(rand () % 61);
258 CG_SpawnParticle (
259 origin[0] + (crand () * 2), origin[1] + (crand () * 2), origin[2] + (crand () * 2),
260 0, 0, 0,
261 0, 0, 0,
262 0, 0, (frand () * 3),
263 70 + rnum, 100 + rnum, 70 + rnum,
264 70 + rnum2, 110 + rnum2, 70 + rnum2,
265 0.35f, -1.0f / (5.1f + (frand () * 0.2f)),
266 30 + (frand () * 10), 300 + (crand () * 50),
267 pRandSmoke (), PF_SHADE,
268 pSmokeThink, qTrue,
269 PART_STYLE_QUAD,
270 frand () * 360);
271 }
272
273
274 /*
275 ===============
276 CG_GloomRepairEffect
277 ===============
278 */
CG_GloomRepairEffect(vec3_t org,vec3_t dir,int count)279 void CG_GloomRepairEffect (vec3_t org, vec3_t dir, int count)
280 {
281 int i, rnum, rnum2;
282 float d;
283
284 for (i=0 ; i<2 ; i++) {
285 // Glow marks
286 rnum = (rand () % 5);
287 rnum2 = (rand () % 5);
288 CG_SpawnDecal (
289 org[0], org[1], org[2],
290 dir[0], dir[1], dir[2],
291 palRed (0xe0 + rnum), palGreen (0xe0 + rnum), palBlue (0xe0 + rnum),
292 palRed (0xe0 + rnum2), palGreen (0xe0 + rnum2), palBlue (0xe0 + rnum2),
293 1.0f, 0,
294 3 + (frand () * 0.5f),
295 DT_ENGYREPAIR_GLOWMARK, DF_USE_BURNLIFE|DF_ALPHACOLOR,
296 0, qFalse,
297 0, frand () * 360);
298 }
299
300 // Burn mark
301 rnum = (rand () % 5);
302 CG_SpawnDecal (
303 org[0], org[1], org[2],
304 dir[0], dir[1], dir[2],
305 (255-palRed(0xe0+rnum))*0.5f+128, (255-palGreen(0xe0+rnum))*0.5f+128, (255-palBlue(0xe0+rnum))*0.5f+128,
306 0, 0, 0,
307 0.9f + (crand () * 0.1f), 0.8f,
308 2 + (frand () * 0.5f),
309 DT_ENGYREPAIR_BURNMARK, DF_ALPHACOLOR,
310 0, qFalse,
311 0, frand () * 360);
312
313 // Dots
314 for (i=0 ; i<count*2.0f ; i++) {
315 d = (frand () * 5) + 2;
316 rnum = (rand () % 5);
317 CG_SpawnParticle (
318 org[0] + (crand () * 4) + d*dir[0], org[1] + (crand () * 4) + d*dir[1], org[2] + (crand () * 4) + d*dir[2],
319 0, 0, 0,
320 crand () * 18, crand () * 18, crand () * 18,
321 0, 0, 40,
322 palRed (0xe0 + rnum), palGreen (0xe0 + rnum), palBlue (0xe0 + rnum),
323 palRed (0xe0 + rnum), palGreen (0xe0 + rnum), palBlue (0xe0 + rnum),
324 1.0f, -1.0f / (0.5f + (frand () * 0.3f)),
325 6 + (frand () * -5.75f), 0.5f + (crand () * 0.45f),
326 PT_ENGYREPAIR_DOT, PF_SCALED|PF_GRAVITY|PF_ALPHACOLOR|PF_NOCLOSECULL,
327 pBounceThink, qTrue,
328 PART_STYLE_QUAD,
329 0);
330 }
331 }
332
333
334 /*
335 ===============
336 CG_GloomStingerFire
337 ===============
338 */
CG_GloomStingerFire(vec3_t start,vec3_t end,float size,qBool light)339 void CG_GloomStingerFire (vec3_t start, vec3_t end, float size, qBool light)
340 {
341 vec3_t move, vec;
342 float len, dec, waterScale;
343 qBool inWater = qFalse;
344 int tipimage, trailimage;
345
346 if (cgi.CM_PointContents (start, 0) & MASK_WATER)
347 inWater = qTrue;
348
349 Vec3Copy (start, move);
350 Vec3Subtract (end, start, vec);
351 len = VectorNormalizeFastf (vec);
352
353 dec = 30;
354 Vec3Scale (vec, dec, vec);
355
356 if (light) {
357 if (glm_bluestingfire->intVal)
358 cgi.R_AddLight (start, 175 + (frand () * 25), 0.1f, 0, 0.9f + (frand () * 0.1f));
359 else if (inWater)
360 cgi.R_AddLight (start, 175 + (frand () * 25), 0.8f + (frand () * 0.2f), 0.7f + (frand () * 0.2f), 0.5f);
361 else
362 cgi.R_AddLight (start, 175 + (frand () * 25), 0.9f + (frand () * 0.1f), 0.8f + (frand () * 0.1f), 0);
363 }
364
365 if (glm_bluestingfire->intVal) {
366 tipimage = trailimage = PT_BLUEFIRE;
367 }
368 else {
369 tipimage = (inWater) ? PT_BLUEFIRE : pRandFire ();
370 trailimage = pRandFire ();
371 }
372
373 waterScale = (inWater || glm_bluestingfire->intVal) ? 100.0f : 0.0f;
374 if (rand () & 1) {
375 // Tip
376 CG_SpawnParticle (
377 start[0] + (crand () * 2), start[1] + (crand () * 2), start[2] + (crand () * 2),
378 0, 0, 0,
379 crand () * 2, crand () * 2, crand () * 2,
380 0, 0, 0,
381 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20),
382 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20),
383 0.6f + (crand () * 0.1f), -0.3f / (0.05f + (frand () * 0.1f)),
384 size + (crand () * 2), (size * 0.25f) + (crand () * 3),
385 tipimage, PF_SCALED|PF_ALPHACOLOR,
386 pFireThink, qTrue,
387 PART_STYLE_QUAD,
388 frand () * 360);
389 }
390 else {
391 // Parts that spiral away
392 CG_SpawnParticle (
393 start[0] + (crand () * 2), start[1] + (crand () * 2), start[2] + (crand () * 2),
394 0, 0, 0,
395 crand () * 80, crand () * 80, crand () * 80,
396 0, 0, 0,
397 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20),
398 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20),
399 0.6f + (crand () * 0.1f), -0.3f / (0.05f + (frand () * 0.1f)),
400 (size * 0.6f) + (crand () * 2), (size * 1.2f) + (crand () * 2),
401 tipimage, PF_SCALED|PF_ALPHACOLOR,
402 pFireThink, qTrue,
403 PART_STYLE_QUAD,
404 frand () * 360);
405 }
406
407 // Fire
408 for (; len>0 ; Vec3Add (move, vec, move)) {
409 len -= dec;
410
411 CG_SpawnParticle (
412 move[0] + (crand () * 8), move[1] + (crand () * 8), move[2] + (crand () * 8),
413 0, 0, 0,
414 crand () * 2, crand () * 2, crand () * 2,
415 0, 0, 0,
416 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20) - waterScale,
417 235 + (frand () * 20) - waterScale, 230 + (frand () * 20) - waterScale, 220 + (frand () * 20) - waterScale,
418 0.6f + (frand () * 0.2f), -0.25f / (0.05f + (frand () * 0.1f)),
419 (size * 0.8f) + (crand () * 2), 2 + crand (),
420 trailimage, PF_SCALED|PF_ALPHACOLOR,
421 pFireThink, qTrue,
422 PART_STYLE_QUAD,
423 frand () * 360);
424 }
425 }
426