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