1 /*
2  * cl_effect.c -- Client side effects.
3  * $Id: cl_effect.c 5843 2017-04-07 14:55:31Z sezero $
4  *
5  * Copyright (C) 1996-1997  Id Software, Inc.
6  * Copyright (C) 1997-1998  Raven Software Corp.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23 
24 // HEADER FILES ------------------------------------------------------------
25 
26 #include "quakedef.h"
27 
28 // MACROS ------------------------------------------------------------------
29 
30 // TYPES -------------------------------------------------------------------
31 
32 #define MAX_EFFECT_ENTITIES		256
33 
34 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
35 
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
37 
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
39 
40 static int NewEffectEntity (void);
41 static void FreeEffectEntity (int idx);
42 
43 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
44 
45 // PUBLIC DATA DEFINITIONS -------------------------------------------------
46 
47 // PRIVATE DATA DEFINITIONS ------------------------------------------------
48 
49 static entity_t	EffectEntities[MAX_EFFECT_ENTITIES];
50 static qboolean	EntityUsed[MAX_EFFECT_ENTITIES];
51 static int	EffectEntityCount;
52 
53 // CODE --------------------------------------------------------------------
54 
55 
56 //==========================================================================
57 //
58 // CL_InitTEnts
59 //
60 //==========================================================================
61 
CL_InitEffects(void)62 void CL_InitEffects (void)
63 {
64 }
65 
CL_ClearEffects(void)66 void CL_ClearEffects (void)
67 {
68 	memset(cl.Effects, 0, sizeof(cl.Effects));
69 	memset(EntityUsed, 0, sizeof(EntityUsed));
70 	EffectEntityCount = 0;
71 }
72 
CL_FreeEffect(int idx)73 static void CL_FreeEffect (int idx)
74 {
75 	int		i;
76 
77 	switch (cl.Effects[idx].type)
78 	{
79 	case CE_RAIN:
80 		break;
81 
82 	case CE_SNOW:
83 		break;
84 
85 	case CE_FOUNTAIN:
86 		break;
87 
88 	case CE_QUAKE:
89 		break;
90 
91 	case CE_WHITE_SMOKE:
92 	case CE_GREEN_SMOKE:
93 	case CE_GREY_SMOKE:
94 	case CE_RED_SMOKE:
95 	case CE_SLOW_WHITE_SMOKE:
96 	case CE_TELESMK1:
97 	case CE_TELESMK2:
98 	case CE_GHOST:
99 	case CE_REDCLOUD:
100 	case CE_ACID_MUZZFL:
101 	case CE_FLAMESTREAM:
102 	case CE_FLAMEWALL:
103 	case CE_FLAMEWALL2:
104 	case CE_ONFIRE:
105 		FreeEffectEntity(cl.Effects[idx].ef.Smoke.entity_index);
106 		break;
107 
108 	/* Just go through animation and then remove */
109 	case CE_SM_WHITE_FLASH:
110 	case CE_YELLOWRED_FLASH:
111 	case CE_BLUESPARK:
112 	case CE_YELLOWSPARK:
113 	case CE_SM_CIRCLE_EXP:
114 	case CE_BG_CIRCLE_EXP:
115 	case CE_SM_EXPLOSION:
116 	case CE_LG_EXPLOSION:
117 	case CE_FLOOR_EXPLOSION:
118 	case CE_FLOOR_EXPLOSION3:
119 	case CE_BLUE_EXPLOSION:
120 	case CE_REDSPARK:
121 	case CE_GREENSPARK:
122 	case CE_ICEHIT:
123 	case CE_MEDUSA_HIT:
124 	case CE_MEZZO_REFLECT:
125 	case CE_FLOOR_EXPLOSION2:
126 	case CE_XBOW_EXPLOSION:
127 	case CE_NEW_EXPLOSION:
128 	case CE_MAGIC_MISSILE_EXPLOSION:
129 	case CE_BONE_EXPLOSION:
130 	case CE_BLDRN_EXPL:
131 	case CE_BRN_BOUNCE:
132 	case CE_LSHOCK:
133 	case CE_ACID_HIT:
134 	case CE_ACID_SPLAT:
135 	case CE_ACID_EXPL:
136 	case CE_LBALL_EXPL:
137 	case CE_FBOOM:
138 	case CE_BOMB:
139 	case CE_FIREWALL_SMALL:
140 	case CE_FIREWALL_MEDIUM:
141 	case CE_FIREWALL_LARGE:
142 		FreeEffectEntity(cl.Effects[idx].ef.Smoke.entity_index);
143 		break;
144 
145 	/* Go forward then backward through animation then remove */
146 	case CE_WHITE_FLASH:
147 	case CE_BLUE_FLASH:
148 	case CE_SM_BLUE_FLASH:
149 	case CE_RED_FLASH:
150 		FreeEffectEntity(cl.Effects[idx].ef.Flash.entity_index);
151 		break;
152 
153 	case CE_RIDER_DEATH:
154 		break;
155 
156 	case CE_GRAVITYWELL:
157 		break;
158 
159 	case CE_TELEPORTERPUFFS:
160 		for (i = 0 ; i < 8 ; ++i)
161 			FreeEffectEntity(cl.Effects[idx].ef.Teleporter.entity_index[i]);
162 		break;
163 
164 	case CE_TELEPORTERBODY:
165 		FreeEffectEntity(cl.Effects[idx].ef.Teleporter.entity_index[0]);
166 		break;
167 
168 	case CE_BONESHARD:
169 	case CE_BONESHRAPNEL:
170 		FreeEffectEntity(cl.Effects[idx].ef.Missile.entity_index);
171 		break;
172 
173 	case CE_CHUNK:
174 	//	Con_Printf("Freeing a chunk here\n");
175 		for (i = 0 ; i < cl.Effects[idx].ef.Chunk.numChunks ; i++)
176 		{
177 			if (cl.Effects[idx].ef.Chunk.entity_index[i] != -1)
178 				FreeEffectEntity(cl.Effects[idx].ef.Chunk.entity_index[i]);
179 		}
180 		break;
181 	}
182 
183 	memset(&cl.Effects[idx], 0, sizeof(struct EffectT));
184 }
185 
186 //==========================================================================
187 //
188 // CL_ParseEffect
189 //
190 //==========================================================================
191 
192 // All changes need to be in SV_SendEffect(), SV_ParseEffect(),
193 // SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect()
CL_ParseEffect(void)194 void CL_ParseEffect (void)
195 {
196 	int		i, idx;
197 	qboolean	ImmediateFree;
198 	entity_t	*ent;
199 	int		dir;
200 	float		angleval, sinval, cosval;
201 	float		skinnum;
202 	float		final;
203 
204 	ImmediateFree = false;
205 
206 	idx = MSG_ReadByte();
207 	if (cl.Effects[idx].type)
208 		CL_FreeEffect(idx);
209 
210 	memset(&cl.Effects[idx], 0, sizeof(struct EffectT));
211 
212 	cl.Effects[idx].type = MSG_ReadByte();
213 
214 	switch (cl.Effects[idx].type)
215 	{
216 	case CE_RAIN:
217 		cl.Effects[idx].ef.Rain.min_org[0] = MSG_ReadCoord();
218 		cl.Effects[idx].ef.Rain.min_org[1] = MSG_ReadCoord();
219 		cl.Effects[idx].ef.Rain.min_org[2] = MSG_ReadCoord();
220 		cl.Effects[idx].ef.Rain.max_org[0] = MSG_ReadCoord();
221 		cl.Effects[idx].ef.Rain.max_org[1] = MSG_ReadCoord();
222 		cl.Effects[idx].ef.Rain.max_org[2] = MSG_ReadCoord();
223 		cl.Effects[idx].ef.Rain.e_size[0] = MSG_ReadCoord();
224 		cl.Effects[idx].ef.Rain.e_size[1] = MSG_ReadCoord();
225 		cl.Effects[idx].ef.Rain.e_size[2] = MSG_ReadCoord();
226 		cl.Effects[idx].ef.Rain.dir[0] = MSG_ReadCoord();
227 		cl.Effects[idx].ef.Rain.dir[1] = MSG_ReadCoord();
228 		cl.Effects[idx].ef.Rain.dir[2] = MSG_ReadCoord();
229 		cl.Effects[idx].ef.Rain.color = MSG_ReadShort();
230 		cl.Effects[idx].ef.Rain.count = MSG_ReadShort();
231 		cl.Effects[idx].ef.Rain.wait = MSG_ReadFloat();
232 		break;
233 
234 	case CE_SNOW:
235 		cl.Effects[idx].ef.Rain.min_org[0] = MSG_ReadCoord();
236 		cl.Effects[idx].ef.Rain.min_org[1] = MSG_ReadCoord();
237 		cl.Effects[idx].ef.Rain.min_org[2] = MSG_ReadCoord();
238 		cl.Effects[idx].ef.Rain.max_org[0] = MSG_ReadCoord();
239 		cl.Effects[idx].ef.Rain.max_org[1] = MSG_ReadCoord();
240 		cl.Effects[idx].ef.Rain.max_org[2] = MSG_ReadCoord();
241 		cl.Effects[idx].ef.Rain.flags = MSG_ReadByte();
242 		cl.Effects[idx].ef.Rain.dir[0] = MSG_ReadCoord();
243 		cl.Effects[idx].ef.Rain.dir[1] = MSG_ReadCoord();
244 		cl.Effects[idx].ef.Rain.dir[2] = MSG_ReadCoord();
245 		cl.Effects[idx].ef.Rain.count = MSG_ReadByte();
246 		//cl.Effects[idx].ef.Rain.veer = MSG_ReadShort();
247 		break;
248 
249 	case CE_FOUNTAIN:
250 		cl.Effects[idx].ef.Fountain.pos[0] = MSG_ReadCoord ();
251 		cl.Effects[idx].ef.Fountain.pos[1] = MSG_ReadCoord ();
252 		cl.Effects[idx].ef.Fountain.pos[2] = MSG_ReadCoord ();
253 		cl.Effects[idx].ef.Fountain.angle[0] = MSG_ReadAngle ();
254 		cl.Effects[idx].ef.Fountain.angle[1] = MSG_ReadAngle ();
255 		cl.Effects[idx].ef.Fountain.angle[2] = MSG_ReadAngle ();
256 		cl.Effects[idx].ef.Fountain.movedir[0] = MSG_ReadCoord ();
257 		cl.Effects[idx].ef.Fountain.movedir[1] = MSG_ReadCoord ();
258 		cl.Effects[idx].ef.Fountain.movedir[2] = MSG_ReadCoord ();
259 		cl.Effects[idx].ef.Fountain.color = MSG_ReadShort ();
260 		cl.Effects[idx].ef.Fountain.cnt = MSG_ReadByte ();
261 		AngleVectors (cl.Effects[idx].ef.Fountain.angle,
262 				cl.Effects[idx].ef.Fountain.vforward,
263 				cl.Effects[idx].ef.Fountain.vright,
264 				cl.Effects[idx].ef.Fountain.vup);
265 		break;
266 
267 	case CE_QUAKE:
268 		cl.Effects[idx].ef.Quake.origin[0] = MSG_ReadCoord ();
269 		cl.Effects[idx].ef.Quake.origin[1] = MSG_ReadCoord ();
270 		cl.Effects[idx].ef.Quake.origin[2] = MSG_ReadCoord ();
271 		cl.Effects[idx].ef.Quake.radius = MSG_ReadFloat ();
272 		break;
273 
274 	case CE_WHITE_SMOKE:
275 	case CE_GREEN_SMOKE:
276 	case CE_GREY_SMOKE:
277 	case CE_RED_SMOKE:
278 	case CE_SLOW_WHITE_SMOKE:
279 	case CE_TELESMK1:
280 	case CE_TELESMK2:
281 	case CE_GHOST:
282 	case CE_REDCLOUD:
283 	case CE_ACID_MUZZFL:
284 	case CE_FLAMESTREAM:
285 	case CE_FLAMEWALL:
286 	case CE_FLAMEWALL2:
287 	case CE_ONFIRE:
288 		cl.Effects[idx].ef.Smoke.origin[0] = MSG_ReadCoord ();
289 		cl.Effects[idx].ef.Smoke.origin[1] = MSG_ReadCoord ();
290 		cl.Effects[idx].ef.Smoke.origin[2] = MSG_ReadCoord ();
291 
292 		cl.Effects[idx].ef.Smoke.velocity[0] = MSG_ReadFloat ();
293 		cl.Effects[idx].ef.Smoke.velocity[1] = MSG_ReadFloat ();
294 		cl.Effects[idx].ef.Smoke.velocity[2] = MSG_ReadFloat ();
295 
296 		cl.Effects[idx].ef.Smoke.framelength = MSG_ReadFloat ();
297 		/* smoke frame is a mission pack thing only. */
298 		if (cl_protocol > PROTOCOL_RAVEN_111)
299 			cl.Effects[idx].ef.Smoke.frame = MSG_ReadFloat ();
300 
301 		if ((cl.Effects[idx].ef.Smoke.entity_index = NewEffectEntity()) != -1)
302 		{
303 			ent = &EffectEntities[cl.Effects[idx].ef.Smoke.entity_index];
304 			VectorCopy(cl.Effects[idx].ef.Smoke.origin, ent->origin);
305 
306 			if ((cl.Effects[idx].type == CE_WHITE_SMOKE) ||
307 					(cl.Effects[idx].type == CE_SLOW_WHITE_SMOKE))
308 				ent->model = Mod_ForName("models/whtsmk1.spr", true);
309 			else if (cl.Effects[idx].type == CE_GREEN_SMOKE)
310 				ent->model = Mod_ForName("models/grnsmk1.spr", true);
311 			else if (cl.Effects[idx].type == CE_GREY_SMOKE)
312 				ent->model = Mod_ForName("models/grysmk1.spr", true);
313 			else if (cl.Effects[idx].type == CE_RED_SMOKE)
314 				ent->model = Mod_ForName("models/redsmk1.spr", true);
315 			else if (cl.Effects[idx].type == CE_TELESMK1)
316 				ent->model = Mod_ForName("models/telesmk1.spr", true);
317 			else if (cl.Effects[idx].type == CE_TELESMK2)
318 				ent->model = Mod_ForName("models/telesmk2.spr", true);
319 			else if (cl.Effects[idx].type == CE_REDCLOUD)
320 				ent->model = Mod_ForName("models/rcloud.spr", true);
321 			else if (cl.Effects[idx].type == CE_FLAMESTREAM)
322 				ent->model = Mod_ForName("models/flamestr.spr", true);
323 			else if (cl.Effects[idx].type == CE_ACID_MUZZFL)
324 			{
325 				ent->model = Mod_ForName("models/muzzle1.spr", true);
326 				ent->drawflags = DRF_TRANSLUCENT | MLS_ABSLIGHT;
327 				ent->abslight = 51;
328 			}
329 			else if (cl.Effects[idx].type == CE_FLAMEWALL)
330 				ent->model = Mod_ForName("models/firewal1.spr", true);
331 			else if (cl.Effects[idx].type == CE_FLAMEWALL2)
332 				ent->model = Mod_ForName("models/firewal2.spr", true);
333 			else if (cl.Effects[idx].type == CE_ONFIRE)
334 			{
335 				float	rdm = rand() & 3;
336 
337 				if (rdm < 1)
338 					ent->model = Mod_ForName("models/firewal1.spr", true);
339 				else if (rdm < 2)
340 					ent->model = Mod_ForName("models/firewal2.spr", true);
341 				else
342 					ent->model = Mod_ForName("models/firewal3.spr", true);
343 
344 				ent->drawflags = DRF_TRANSLUCENT;
345 				ent->abslight = 255;
346 				ent->frame = cl.Effects[idx].ef.Smoke.frame;
347 			}
348 
349 			if (cl.Effects[idx].type != CE_REDCLOUD &&
350 					cl.Effects[idx].type != CE_ACID_MUZZFL &&
351 					cl.Effects[idx].type != CE_FLAMEWALL)
352 				ent->drawflags = DRF_TRANSLUCENT;
353 
354 			if (cl.Effects[idx].type == CE_FLAMESTREAM)
355 			{
356 				ent->drawflags = DRF_TRANSLUCENT | MLS_ABSLIGHT;
357 				ent->abslight = 255;
358 				ent->frame = cl.Effects[idx].ef.Smoke.frame;
359 			}
360 
361 			if (cl.Effects[idx].type == CE_GHOST)
362 			{
363 				ent->model = Mod_ForName("models/ghost.spr", true);
364 				ent->drawflags = DRF_TRANSLUCENT | MLS_ABSLIGHT;
365 				ent->abslight = 127;
366 			}
367 		}
368 		else
369 			ImmediateFree = true;
370 		break;
371 
372 	case CE_SM_WHITE_FLASH:
373 	case CE_YELLOWRED_FLASH:
374 	case CE_BLUESPARK:
375 	case CE_YELLOWSPARK:
376 	case CE_SM_CIRCLE_EXP:
377 	case CE_BG_CIRCLE_EXP:
378 	case CE_SM_EXPLOSION:
379 	case CE_LG_EXPLOSION:
380 	case CE_FLOOR_EXPLOSION:
381 	case CE_FLOOR_EXPLOSION3:
382 	case CE_BLUE_EXPLOSION:
383 	case CE_REDSPARK:
384 	case CE_GREENSPARK:
385 	case CE_ICEHIT:
386 	case CE_MEDUSA_HIT:
387 	case CE_MEZZO_REFLECT:
388 	case CE_FLOOR_EXPLOSION2:
389 	case CE_XBOW_EXPLOSION:
390 	case CE_NEW_EXPLOSION:
391 	case CE_MAGIC_MISSILE_EXPLOSION:
392 	case CE_BONE_EXPLOSION:
393 	case CE_BLDRN_EXPL:
394 	case CE_BRN_BOUNCE:
395 	case CE_LSHOCK:
396 	case CE_ACID_HIT:
397 	case CE_ACID_SPLAT:
398 	case CE_ACID_EXPL:
399 	case CE_LBALL_EXPL:
400 	case CE_FBOOM:
401 	case CE_BOMB:
402 	case CE_FIREWALL_SMALL:
403 	case CE_FIREWALL_MEDIUM:
404 	case CE_FIREWALL_LARGE:
405 		cl.Effects[idx].ef.Smoke.origin[0] = MSG_ReadCoord ();
406 		cl.Effects[idx].ef.Smoke.origin[1] = MSG_ReadCoord ();
407 		cl.Effects[idx].ef.Smoke.origin[2] = MSG_ReadCoord ();
408 		if ((cl.Effects[idx].ef.Smoke.entity_index = NewEffectEntity()) != -1)
409 		{
410 			ent = &EffectEntities[cl.Effects[idx].ef.Smoke.entity_index];
411 			VectorCopy(cl.Effects[idx].ef.Smoke.origin, ent->origin);
412 
413 			if (cl.Effects[idx].type == CE_BLUESPARK)
414 				ent->model = Mod_ForName("models/bspark.spr", true);
415 			else if (cl.Effects[idx].type == CE_YELLOWSPARK)
416 				ent->model = Mod_ForName("models/spark.spr", true);
417 			else if (cl.Effects[idx].type == CE_SM_CIRCLE_EXP)
418 				ent->model = Mod_ForName("models/fcircle.spr", true);
419 			else if (cl.Effects[idx].type == CE_BG_CIRCLE_EXP)
420 				ent->model = Mod_ForName("models/xplod29.spr", true);
421 			else if (cl.Effects[idx].type == CE_SM_WHITE_FLASH)
422 				ent->model = Mod_ForName("models/sm_white.spr", true);
423 			else if (cl.Effects[idx].type == CE_YELLOWRED_FLASH)
424 			{
425 				ent->model = Mod_ForName("models/yr_flsh.spr", true);
426 				ent->drawflags = DRF_TRANSLUCENT;
427 			}
428 			else if (cl.Effects[idx].type == CE_SM_EXPLOSION)
429 				ent->model = Mod_ForName("models/sm_expld.spr", true);
430 			else if (cl.Effects[idx].type == CE_LG_EXPLOSION)
431 				ent->model = Mod_ForName("models/bg_expld.spr", true);
432 			else if (cl.Effects[idx].type == CE_FLOOR_EXPLOSION)
433 				ent->model = Mod_ForName("models/fl_expld.spr", true);
434 			else if (cl.Effects[idx].type == CE_FLOOR_EXPLOSION3)
435 				ent->model = Mod_ForName("models/biggy.spr", true);
436 			else if (cl.Effects[idx].type == CE_BLUE_EXPLOSION)
437 				ent->model = Mod_ForName("models/xpspblue.spr", true);
438 			else if (cl.Effects[idx].type == CE_REDSPARK)
439 				ent->model = Mod_ForName("models/rspark.spr", true);
440 			else if (cl.Effects[idx].type == CE_GREENSPARK)
441 				ent->model = Mod_ForName("models/gspark.spr", true);
442 			else if (cl.Effects[idx].type == CE_ICEHIT)
443 				ent->model = Mod_ForName("models/icehit.spr", true);
444 			else if (cl.Effects[idx].type == CE_MEDUSA_HIT)
445 				ent->model = Mod_ForName("models/medhit.spr", true);
446 			else if (cl.Effects[idx].type == CE_MEZZO_REFLECT)
447 				ent->model = Mod_ForName("models/mezzoref.spr", true);
448 			else if (cl.Effects[idx].type == CE_FLOOR_EXPLOSION2)
449 				ent->model = Mod_ForName("models/flrexpl2.spr", true);
450 			else if (cl.Effects[idx].type == CE_XBOW_EXPLOSION)
451 				ent->model = Mod_ForName("models/xbowexpl.spr", true);
452 			else if (cl.Effects[idx].type == CE_NEW_EXPLOSION)
453 				ent->model = Mod_ForName("models/gen_expl.spr", true);
454 			else if (cl.Effects[idx].type == CE_MAGIC_MISSILE_EXPLOSION)
455 				ent->model = Mod_ForName("models/mm_expld.spr", true);
456 			else if (cl.Effects[idx].type == CE_BONE_EXPLOSION)
457 				ent->model = Mod_ForName("models/bonexpld.spr", true);
458 			else if (cl.Effects[idx].type == CE_BLDRN_EXPL)
459 				ent->model = Mod_ForName("models/xplsn_1.spr", true);
460 			else if (cl.Effects[idx].type == CE_ACID_HIT)
461 				ent->model = Mod_ForName("models/axplsn_2.spr", true);
462 			else if (cl.Effects[idx].type == CE_ACID_SPLAT)
463 				ent->model = Mod_ForName("models/axplsn_1.spr", true);
464 			else if (cl.Effects[idx].type == CE_ACID_EXPL)
465 			{
466 				ent->model = Mod_ForName("models/axplsn_5.spr", true);
467 				ent->drawflags = MLS_ABSLIGHT;
468 				ent->abslight = 255;
469 			}
470 			else if (cl.Effects[idx].type == CE_FBOOM)
471 				ent->model = Mod_ForName("models/fboom.spr", true);
472 			else if (cl.Effects[idx].type == CE_BOMB)
473 				ent->model = Mod_ForName("models/pow.spr", true);
474 			else if (cl.Effects[idx].type == CE_LBALL_EXPL)
475 				ent->model = Mod_ForName("models/Bluexp3.spr", true);
476 			else if (cl.Effects[idx].type == CE_FIREWALL_SMALL)
477 				ent->model = Mod_ForName("models/firewal1.spr", true);
478 			else if (cl.Effects[idx].type == CE_FIREWALL_MEDIUM)
479 				ent->model = Mod_ForName("models/firewal5.spr", true);
480 			else if (cl.Effects[idx].type == CE_FIREWALL_LARGE)
481 				ent->model = Mod_ForName("models/firewal4.spr", true);
482 			else if (cl.Effects[idx].type == CE_BRN_BOUNCE)
483 				ent->model = Mod_ForName("models/spark.spr", true);
484 			else if (cl.Effects[idx].type == CE_LSHOCK)
485 			{
486 				ent->model = Mod_ForName("models/vorpshok.mdl", true);
487 				ent->drawflags = MLS_TORCH;
488 				ent->angles[2] = 90;
489 				ent->scale = 255;
490 			}
491 		}
492 		else
493 		{
494 			ImmediateFree = true;
495 		}
496 		break;
497 
498 	case CE_WHITE_FLASH:
499 	case CE_BLUE_FLASH:
500 	case CE_SM_BLUE_FLASH:
501 	case CE_RED_FLASH:
502 		cl.Effects[idx].ef.Flash.origin[0] = MSG_ReadCoord ();
503 		cl.Effects[idx].ef.Flash.origin[1] = MSG_ReadCoord ();
504 		cl.Effects[idx].ef.Flash.origin[2] = MSG_ReadCoord ();
505 		cl.Effects[idx].ef.Flash.reverse = 0;
506 		if ((cl.Effects[idx].ef.Flash.entity_index = NewEffectEntity()) != -1)
507 		{
508 			ent = &EffectEntities[cl.Effects[idx].ef.Flash.entity_index];
509 			VectorCopy(cl.Effects[idx].ef.Flash.origin, ent->origin);
510 
511 			if (cl.Effects[idx].type == CE_WHITE_FLASH)
512 				ent->model = Mod_ForName("models/gryspt.spr", true);
513 			else if (cl.Effects[idx].type == CE_BLUE_FLASH)
514 				ent->model = Mod_ForName("models/bluflash.spr", true);
515 			else if (cl.Effects[idx].type == CE_SM_BLUE_FLASH)
516 				ent->model = Mod_ForName("models/sm_blue.spr", true);
517 			else if (cl.Effects[idx].type == CE_RED_FLASH)
518 				ent->model = Mod_ForName("models/redspt.spr", true);
519 
520 			ent->drawflags = DRF_TRANSLUCENT;
521 		}
522 		else
523 		{
524 			ImmediateFree = true;
525 		}
526 		break;
527 
528 	case CE_RIDER_DEATH:
529 		cl.Effects[idx].ef.RD.origin[0] = MSG_ReadCoord ();
530 		cl.Effects[idx].ef.RD.origin[1] = MSG_ReadCoord ();
531 		cl.Effects[idx].ef.RD.origin[2] = MSG_ReadCoord ();
532 		break;
533 
534 	case CE_GRAVITYWELL:
535 		cl.Effects[idx].ef.RD.origin[0] = MSG_ReadCoord ();
536 		cl.Effects[idx].ef.RD.origin[1] = MSG_ReadCoord ();
537 		cl.Effects[idx].ef.RD.origin[2] = MSG_ReadCoord ();
538 		cl.Effects[idx].ef.RD.color = MSG_ReadShort ();
539 		cl.Effects[idx].ef.RD.lifetime = MSG_ReadFloat ();
540 		break;
541 
542 	case CE_TELEPORTERPUFFS:
543 		cl.Effects[idx].ef.Teleporter.origin[0] = MSG_ReadCoord ();
544 		cl.Effects[idx].ef.Teleporter.origin[1] = MSG_ReadCoord ();
545 		cl.Effects[idx].ef.Teleporter.origin[2] = MSG_ReadCoord ();
546 
547 		cl.Effects[idx].ef.Teleporter.framelength = .05;
548 		dir = 0;
549 		for (i = 0 ; i < 8 ; ++i)
550 		{
551 			if ((cl.Effects[idx].ef.Teleporter.entity_index[i] = NewEffectEntity()) != -1)
552 			{
553 				ent = &EffectEntities[cl.Effects[idx].ef.Teleporter.entity_index[i]];
554 				VectorCopy(cl.Effects[idx].ef.Teleporter.origin, ent->origin);
555 
556 				angleval = dir * M_PI*2 / 360;
557 
558 				sinval = sin(angleval);
559 				cosval = cos(angleval);
560 
561 				cl.Effects[idx].ef.Teleporter.velocity[i][0] = 10*cosval;
562 				cl.Effects[idx].ef.Teleporter.velocity[i][1] = 10*sinval;
563 				cl.Effects[idx].ef.Teleporter.velocity[i][2] = 0;
564 				dir += 45;
565 
566 				ent->model = Mod_ForName("models/telesmk2.spr", true);
567 				ent->drawflags = DRF_TRANSLUCENT;
568 			}
569 		}
570 		break;
571 
572 	case CE_TELEPORTERBODY:
573 		cl.Effects[idx].ef.Teleporter.origin[0] = MSG_ReadCoord ();
574 		cl.Effects[idx].ef.Teleporter.origin[1] = MSG_ReadCoord ();
575 		cl.Effects[idx].ef.Teleporter.origin[2] = MSG_ReadCoord ();
576 
577 		cl.Effects[idx].ef.Teleporter.velocity[0][0] = MSG_ReadFloat ();
578 		cl.Effects[idx].ef.Teleporter.velocity[0][1] = MSG_ReadFloat ();
579 		cl.Effects[idx].ef.Teleporter.velocity[0][2] = MSG_ReadFloat ();
580 
581 		skinnum = MSG_ReadFloat ();
582 
583 		cl.Effects[idx].ef.Teleporter.framelength = .05;
584 		dir = 0;
585 		if ((cl.Effects[idx].ef.Teleporter.entity_index[0] = NewEffectEntity()) != -1)
586 		{
587 			ent = &EffectEntities[cl.Effects[idx].ef.Teleporter.entity_index[0]];
588 			VectorCopy(cl.Effects[idx].ef.Teleporter.origin, ent->origin);
589 
590 			ent->model = Mod_ForName("models/teleport.mdl", true);
591 			ent->drawflags = SCALE_TYPE_XYONLY | DRF_TRANSLUCENT;
592 			ent->scale = 100;
593 			ent->skinnum = skinnum;
594 		}
595 		break;
596 
597 	case CE_BONESHARD:
598 	case CE_BONESHRAPNEL:
599 		cl.Effects[idx].ef.Missile.origin[0] = MSG_ReadCoord ();
600 		cl.Effects[idx].ef.Missile.origin[1] = MSG_ReadCoord ();
601 		cl.Effects[idx].ef.Missile.origin[2] = MSG_ReadCoord ();
602 
603 		cl.Effects[idx].ef.Missile.velocity[0] = MSG_ReadFloat ();
604 		cl.Effects[idx].ef.Missile.velocity[1] = MSG_ReadFloat ();
605 		cl.Effects[idx].ef.Missile.velocity[2] = MSG_ReadFloat ();
606 
607 		cl.Effects[idx].ef.Missile.angle[0] = MSG_ReadFloat ();
608 		cl.Effects[idx].ef.Missile.angle[1] = MSG_ReadFloat ();
609 		cl.Effects[idx].ef.Missile.angle[2] = MSG_ReadFloat ();
610 
611 		cl.Effects[idx].ef.Missile.avelocity[0] = MSG_ReadFloat ();
612 		cl.Effects[idx].ef.Missile.avelocity[1] = MSG_ReadFloat ();
613 		cl.Effects[idx].ef.Missile.avelocity[2] = MSG_ReadFloat ();
614 
615 		if ((cl.Effects[idx].ef.Missile.entity_index = NewEffectEntity()) != -1)
616 		{
617 			ent = &EffectEntities[cl.Effects[idx].ef.Missile.entity_index];
618 			VectorCopy(cl.Effects[idx].ef.Missile.origin, ent->origin);
619 			if (cl.Effects[idx].type == CE_BONESHARD)
620 				ent->model = Mod_ForName("models/boneshot.mdl", true);
621 			else if (cl.Effects[idx].type == CE_BONESHRAPNEL)
622 				ent->model = Mod_ForName("models/boneshrd.mdl", true);
623 		}
624 		else
625 			ImmediateFree = true;
626 		break;
627 
628 	case CE_CHUNK:
629 		cl.Effects[idx].ef.Chunk.origin[0] = MSG_ReadCoord ();
630 		cl.Effects[idx].ef.Chunk.origin[1] = MSG_ReadCoord ();
631 		cl.Effects[idx].ef.Chunk.origin[2] = MSG_ReadCoord ();
632 
633 		cl.Effects[idx].ef.Chunk.type = MSG_ReadByte ();
634 
635 		cl.Effects[idx].ef.Chunk.srcVel[0] = MSG_ReadCoord ();
636 		cl.Effects[idx].ef.Chunk.srcVel[1] = MSG_ReadCoord ();
637 		cl.Effects[idx].ef.Chunk.srcVel[2] = MSG_ReadCoord ();
638 
639 		cl.Effects[idx].ef.Chunk.numChunks = MSG_ReadByte ();
640 
641 		cl.Effects[idx].ef.Chunk.time_amount = 4.0;
642 
643 		cl.Effects[idx].ef.Chunk.aveScale =
644 					30 + 100 * (cl.Effects[idx].ef.Chunk.numChunks / 40.0);
645 
646 		if (cl.Effects[idx].ef.Chunk.numChunks > 16)
647 			cl.Effects[idx].ef.Chunk.numChunks = 16;
648 
649 		for (i = 0 ; i < cl.Effects[idx].ef.Chunk.numChunks ; i++)
650 		{
651 			if ((cl.Effects[idx].ef.Chunk.entity_index[i] = NewEffectEntity()) != -1)
652 			{
653 				ent = &EffectEntities[cl.Effects[idx].ef.Chunk.entity_index[i]];
654 				VectorCopy(cl.Effects[idx].ef.Chunk.origin, ent->origin);
655 
656 				VectorCopy(cl.Effects[idx].ef.Chunk.srcVel,
657 							cl.Effects[idx].ef.Chunk.velocity[i]);
658 				VectorScale(cl.Effects[idx].ef.Chunk.velocity[i],
659 							.80 + ((rand() % 4) / 10.0),
660 							cl.Effects[idx].ef.Chunk.velocity[i]);
661 				/* temp modify them... */
662 				cl.Effects[idx].ef.Chunk.velocity[i][0] += (rand() % 140) - 70;
663 				cl.Effects[idx].ef.Chunk.velocity[i][1] += (rand() % 140) - 70;
664 				cl.Effects[idx].ef.Chunk.velocity[i][2] += (rand() % 140) - 70;
665 
666 				/* are these in degrees or radians? */
667 				ent->angles[0] = rand() % 360;
668 				ent->angles[1] = rand() % 360;
669 				ent->angles[2] = rand() % 360;
670 
671 				ent->scale = cl.Effects[idx].ef.Chunk.aveScale + (rand() % 40);
672 
673 				/* make this overcomplicated */
674 				final = (rand() % 100) * .01;
675 				if ((cl.Effects[idx].ef.Chunk.type == THINGTYPE_GLASS) ||
676 					(cl.Effects[idx].ef.Chunk.type == THINGTYPE_REDGLASS) ||
677 					(cl.Effects[idx].ef.Chunk.type == THINGTYPE_CLEARGLASS) ||
678 					(cl.Effects[idx].ef.Chunk.type == THINGTYPE_WEBS))
679 				{
680 					if (final < 0.20)
681 						ent->model = Mod_ForName ("models/shard1.mdl", true);
682 					else if (final < 0.40)
683 						ent->model = Mod_ForName ("models/shard2.mdl", true);
684 					else if (final < 0.60)
685 						ent->model = Mod_ForName ("models/shard3.mdl", true);
686 					else if (final < 0.80)
687 						ent->model = Mod_ForName ("models/shard4.mdl", true);
688 					else
689 						ent->model = Mod_ForName ("models/shard5.mdl", true);
690 
691 					if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_CLEARGLASS)
692 					{
693 						ent->skinnum = 1;
694 						ent->drawflags |= DRF_TRANSLUCENT;
695 					}
696 					else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_REDGLASS)
697 					{
698 						ent->skinnum = 2;
699 					}
700 					else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_WEBS)
701 					{
702 						ent->skinnum = 3;
703 						ent->drawflags |= DRF_TRANSLUCENT;
704 					}
705 				}
706 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_WOOD)
707 				{
708 					if (final < 0.25)
709 						ent->model = Mod_ForName ("models/splnter1.mdl", true);
710 					else if (final < 0.50)
711 						ent->model = Mod_ForName ("models/splnter2.mdl", true);
712 					else if (final < 0.75)
713 						ent->model = Mod_ForName ("models/splnter3.mdl", true);
714 					else
715 						ent->model = Mod_ForName ("models/splnter4.mdl", true);
716 				}
717 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_METAL)
718 				{
719 					if (final < 0.25)
720 						ent->model = Mod_ForName ("models/metlchk1.mdl", true);
721 					else if (final < 0.50)
722 						ent->model = Mod_ForName ("models/metlchk2.mdl", true);
723 					else if (final < 0.75)
724 						ent->model = Mod_ForName ("models/metlchk3.mdl", true);
725 					else
726 						ent->model = Mod_ForName ("models/metlchk4.mdl", true);
727 				}
728 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_FLESH)
729 				{
730 					if (final < 0.33)
731 						ent->model = Mod_ForName ("models/flesh1.mdl", true);
732 					else if (final < 0.66)
733 						ent->model = Mod_ForName ("models/flesh2.mdl", true);
734 					else
735 						ent->model = Mod_ForName ("models/flesh3.mdl", true);
736 				}
737 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_BROWNSTONE)
738 				{
739 					if (final < 0.25)
740 						ent->model = Mod_ForName ("models/schunk1.mdl", true);
741 					else if (final < 0.50)
742 						ent->model = Mod_ForName ("models/schunk2.mdl", true);
743 					else if (final < 0.75)
744 						ent->model = Mod_ForName ("models/schunk3.mdl", true);
745 					else
746 						ent->model = Mod_ForName ("models/schunk4.mdl", true);
747 					ent->skinnum = 1;
748 				}
749 				else if ((cl.Effects[idx].ef.Chunk.type == THINGTYPE_CLAY) ||
750 						(cl.Effects[idx].ef.Chunk.type == THINGTYPE_BONE))
751 				{
752 					if (final < 0.25)
753 						ent->model = Mod_ForName ("models/clshard1.mdl", true);
754 					else if (final < 0.50)
755 						ent->model = Mod_ForName ("models/clshard2.mdl", true);
756 					else if (final < 0.75)
757 						ent->model = Mod_ForName ("models/clshard3.mdl", true);
758 					else
759 						ent->model = Mod_ForName ("models/clshard4.mdl", true);
760 					if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_BONE)
761 					{
762 						ent->skinnum = 1;	/* bone skin is second */
763 					}
764 				}
765 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_LEAVES)
766 				{
767 					if (final < 0.33)
768 						ent->model = Mod_ForName ("models/leafchk1.mdl", true);
769 					else if (final < 0.66)
770 						ent->model = Mod_ForName ("models/leafchk2.mdl", true);
771 					else
772 						ent->model = Mod_ForName ("models/leafchk3.mdl", true);
773 				}
774 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_HAY)
775 				{
776 					if (final < 0.33)
777 						ent->model = Mod_ForName ("models/hay1.mdl", true);
778 					else if (final < 0.66)
779 						ent->model = Mod_ForName ("models/hay2.mdl", true);
780 					else
781 						ent->model = Mod_ForName ("models/hay3.mdl", true);
782 				}
783 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_CLOTH)
784 				{
785 					if (final < 0.33)
786 						ent->model = Mod_ForName ("models/clthchk1.mdl", true);
787 					else if (final < 0.66)
788 						ent->model = Mod_ForName ("models/clthchk2.mdl", true);
789 					else
790 						ent->model = Mod_ForName ("models/clthchk3.mdl", true);
791 				}
792 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_WOOD_LEAF)
793 				{
794 					if (final < 0.14)
795 						ent->model = Mod_ForName ("models/splnter1.mdl", true);
796 					else if (final < 0.28)
797 						ent->model = Mod_ForName ("models/leafchk1.mdl", true);
798 					else if (final < 0.42)
799 						ent->model = Mod_ForName ("models/splnter2.mdl", true);
800 					else if (final < 0.56)
801 						ent->model = Mod_ForName ("models/leafchk2.mdl", true);
802 					else if (final < 0.70)
803 						ent->model = Mod_ForName ("models/splnter3.mdl", true);
804 					else if (final < 0.84)
805 						ent->model = Mod_ForName ("models/leafchk3.mdl", true);
806 					else
807 						ent->model = Mod_ForName ("models/splnter4.mdl", true);
808 				}
809 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_WOOD_METAL)
810 				{
811 					if (final < 0.125)
812 						ent->model = Mod_ForName ("models/splnter1.mdl", true);
813 					else if (final < 0.25)
814 						ent->model = Mod_ForName ("models/metlchk1.mdl", true);
815 					else if (final < 0.375)
816 						ent->model = Mod_ForName ("models/splnter2.mdl", true);
817 					else if (final < 0.50)
818 						ent->model = Mod_ForName ("models/metlchk2.mdl", true);
819 					else if (final < 0.625)
820 						ent->model = Mod_ForName ("models/splnter3.mdl", true);
821 					else if (final < 0.75)
822 						ent->model = Mod_ForName ("models/metlchk3.mdl", true);
823 					else if (final < 0.875)
824 						ent->model = Mod_ForName ("models/splnter4.mdl", true);
825 					else
826 						ent->model = Mod_ForName ("models/metlchk4.mdl", true);
827 				}
828 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_WOOD_STONE)
829 				{
830 					if (final < 0.125)
831 						ent->model = Mod_ForName ("models/splnter1.mdl", true);
832 					else if (final < 0.25)
833 						ent->model = Mod_ForName ("models/schunk1.mdl", true);
834 					else if (final < 0.375)
835 						ent->model = Mod_ForName ("models/splnter2.mdl", true);
836 					else if (final < 0.50)
837 						ent->model = Mod_ForName ("models/schunk2.mdl", true);
838 					else if (final < 0.625)
839 						ent->model = Mod_ForName ("models/splnter3.mdl", true);
840 					else if (final < 0.75)
841 						ent->model = Mod_ForName ("models/schunk3.mdl", true);
842 					else if (final < 0.875)
843 						ent->model = Mod_ForName ("models/splnter4.mdl", true);
844 					else
845 						ent->model = Mod_ForName ("models/schunk4.mdl", true);
846 				}
847 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_METAL_STONE)
848 				{
849 					if (final < 0.125)
850 						ent->model = Mod_ForName ("models/metlchk1.mdl", true);
851 					else if (final < 0.25)
852 						ent->model = Mod_ForName ("models/schunk1.mdl", true);
853 					else if (final < 0.375)
854 						ent->model = Mod_ForName ("models/metlchk2.mdl", true);
855 					else if (final < 0.50)
856 						ent->model = Mod_ForName ("models/schunk2.mdl", true);
857 					else if (final < 0.625)
858 						ent->model = Mod_ForName ("models/metlchk3.mdl", true);
859 					else if (final < 0.75)
860 						ent->model = Mod_ForName ("models/schunk3.mdl", true);
861 					else if (final < 0.875)
862 						ent->model = Mod_ForName ("models/metlchk4.mdl", true);
863 					else
864 						ent->model = Mod_ForName ("models/schunk4.mdl", true);
865 				}
866 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_METAL_CLOTH)
867 				{
868 					if (final < 0.14)
869 						ent->model = Mod_ForName ("models/metlchk1.mdl", true);
870 					else if (final < 0.28)
871 						ent->model = Mod_ForName ("models/clthchk1.mdl", true);
872 					else if (final < 0.42)
873 						ent->model = Mod_ForName ("models/metlchk2.mdl", true);
874 					else if (final < 0.56)
875 						ent->model = Mod_ForName ("models/clthchk2.mdl", true);
876 					else if (final < 0.70)
877 						ent->model = Mod_ForName ("models/metlchk3.mdl", true);
878 					else if (final < 0.84)
879 						ent->model = Mod_ForName ("models/clthchk3.mdl", true);
880 					else
881 						ent->model = Mod_ForName ("models/metlchk4.mdl", true);
882 				}
883 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_ICE)
884 				{
885 					ent->model = Mod_ForName("models/shard.mdl", true);
886 					ent->skinnum = 0;
887 					ent->frame = rand() % 2;
888 					ent->drawflags |= DRF_TRANSLUCENT|MLS_ABSLIGHT;
889 					ent->abslight = 127;
890 				}
891 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_METEOR)
892 				{
893 					ent->model = Mod_ForName("models/tempmetr.mdl", true);
894 					ent->skinnum = 0;
895 				}
896 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_ACID)
897 				{	/* no spinning if possible... */
898 					ent->model = Mod_ForName("models/sucwp2p.mdl", true);
899 					ent->skinnum = 0;
900 				}
901 				else if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_GREENFLESH)
902 				{	/* spider guts */
903 					if (final < 0.33)
904 						ent->model = Mod_ForName ("models/sflesh1.mdl", true);
905 					else if (final < 0.66)
906 						ent->model = Mod_ForName ("models/sflesh2.mdl", true);
907 					else
908 						ent->model = Mod_ForName ("models/sflesh3.mdl", true);
909 
910 					ent->skinnum = 0;
911 				}
912 				else// if (cl.Effects[idx].ef.Chunk.type == THINGTYPE_GREYSTONE)
913 				{
914 					if (final < 0.25)
915 						ent->model = Mod_ForName ("models/schunk1.mdl", true);
916 					else if (final < 0.50)
917 						ent->model = Mod_ForName ("models/schunk2.mdl", true);
918 					else if (final < 0.75)
919 						ent->model = Mod_ForName ("models/schunk3.mdl", true);
920 					else
921 						ent->model = Mod_ForName ("models/schunk4.mdl", true);
922 					ent->skinnum = 0;
923 				}
924 			}
925 		}
926 
927 		for (i = 0 ; i < 3 ; i++)
928 		{
929 			cl.Effects[idx].ef.Chunk.avel[i][0] = (rand() % 850) - 425;
930 			cl.Effects[idx].ef.Chunk.avel[i][1] = (rand() % 850) - 425;
931 			cl.Effects[idx].ef.Chunk.avel[i][2] = (rand() % 850) - 425;
932 		}
933 
934 		break;
935 
936 	default:
937 		Host_Error ("%s: bad type", __thisfunc__);
938 	}
939 
940 	if (ImmediateFree)
941 	{
942 		cl.Effects[idx].type = CE_NONE;
943 	}
944 }
945 
CL_EndEffect(void)946 void CL_EndEffect (void)
947 {
948 	int		idx;
949 
950 	idx = MSG_ReadByte();
951 
952 	CL_FreeEffect(idx);
953 }
954 
CL_LinkEntity(entity_t * ent)955 static void CL_LinkEntity (entity_t *ent)
956 {
957 	if (cl_numvisedicts < MAX_VISEDICTS)
958 	{
959 		cl_visedicts[cl_numvisedicts++] = ent;
960 	}
961 }
962 
CL_UpdateEffects(void)963 void CL_UpdateEffects (void)
964 {
965 	int		i;
966 	int		idx, cur_frame;
967 	vec3_t		mymin, mymax;
968 	float		frametime;
969 //	edict_t		test;
970 //	trace_t		trace;
971 	vec3_t		org, org2, alldir, snow_org;
972 	int		x_dir, y_dir;
973 	entity_t	*ent;
974 	float		distance, smoketime;
975 
976 	if (cls.state == ca_disconnected)
977 		return;
978 
979 	frametime = cl.time - cl.oldtime;
980 	if (!frametime)
981 		return;
982 //	Con_Printf("Here at %f\n",cl.time);
983 
984 	for (idx = 0 ; idx < MAX_EFFECTS ; idx++)
985 	{
986 		if (!cl.Effects[idx].type)
987 			continue;
988 
989 		switch (cl.Effects[idx].type)
990 		{
991 		case CE_RAIN:
992 			org[0] = cl.Effects[idx].ef.Rain.min_org[0];
993 			org[1] = cl.Effects[idx].ef.Rain.min_org[1];
994 			org[2] = cl.Effects[idx].ef.Rain.max_org[2];
995 
996 			org2[0] = cl.Effects[idx].ef.Rain.e_size[0];
997 			org2[1] = cl.Effects[idx].ef.Rain.e_size[1];
998 			org2[2] = cl.Effects[idx].ef.Rain.e_size[2];
999 
1000 			x_dir = cl.Effects[idx].ef.Rain.dir[0];
1001 			y_dir = cl.Effects[idx].ef.Rain.dir[1];
1002 
1003 			cl.Effects[idx].ef.Rain.next_time += frametime;
1004 			if (cl.Effects[idx].ef.Rain.next_time >= cl.Effects[idx].ef.Rain.wait)
1005 			{
1006 				R_RainEffect(org, org2, x_dir, y_dir, cl.Effects[idx].ef.Rain.color,
1007 								cl.Effects[idx].ef.Rain.count);
1008 				cl.Effects[idx].ef.Rain.next_time = 0;
1009 			}
1010 			break;
1011 
1012 		case CE_SNOW:
1013 			VectorCopy(cl.Effects[idx].ef.Rain.min_org, org);
1014 			VectorCopy(cl.Effects[idx].ef.Rain.max_org, org2);
1015 			VectorCopy(cl.Effects[idx].ef.Rain.dir, alldir);
1016 
1017 			VectorAdd(org, org2, snow_org);
1018 
1019 			snow_org[0] *= 0.5;
1020 			snow_org[1] *= 0.5;
1021 			snow_org[2] *= 0.5;
1022 
1023 			snow_org[2] = r_origin[2];
1024 
1025 			VectorSubtract(snow_org, r_origin, snow_org);
1026 
1027 			distance = VectorNormalize(snow_org);
1028 
1029 			cl.Effects[idx].ef.Rain.next_time += frametime;
1030 			/* jfm:  fixme, check distance to player first */
1031 			if (cl.Effects[idx].ef.Rain.next_time >= 0.10 && distance < 1024)
1032 			{
1033 				R_SnowEffect(org, org2, cl.Effects[idx].ef.Rain.flags, alldir,
1034 								cl.Effects[idx].ef.Rain.count);
1035 
1036 				cl.Effects[idx].ef.Rain.next_time = 0;
1037 			}
1038 			break;
1039 
1040 		case CE_FOUNTAIN:
1041 			mymin[0] = (-3 * cl.Effects[idx].ef.Fountain.vright[0] * cl.Effects[idx].ef.Fountain.movedir[0]) +
1042 				   (-3 * cl.Effects[idx].ef.Fountain.vforward[0] * cl.Effects[idx].ef.Fountain.movedir[1]) +
1043 				   (2 * cl.Effects[idx].ef.Fountain.vup[0] * cl.Effects[idx].ef.Fountain.movedir[2]);
1044 			mymin[1] = (-3 * cl.Effects[idx].ef.Fountain.vright[1] * cl.Effects[idx].ef.Fountain.movedir[0]) +
1045 				   (-3 * cl.Effects[idx].ef.Fountain.vforward[1] * cl.Effects[idx].ef.Fountain.movedir[1]) +
1046 				   (2 * cl.Effects[idx].ef.Fountain.vup[1] * cl.Effects[idx].ef.Fountain.movedir[2]);
1047 			mymin[2] = (-3 * cl.Effects[idx].ef.Fountain.vright[2] * cl.Effects[idx].ef.Fountain.movedir[0]) +
1048 				   (-3 * cl.Effects[idx].ef.Fountain.vforward[2] * cl.Effects[idx].ef.Fountain.movedir[1]) +
1049 				   (2 * cl.Effects[idx].ef.Fountain.vup[2] * cl.Effects[idx].ef.Fountain.movedir[2]);
1050 			mymin[0] *= 15;
1051 			mymin[1] *= 15;
1052 			mymin[2] *= 15;
1053 
1054 			mymax[0] = (3 * cl.Effects[idx].ef.Fountain.vright[0] * cl.Effects[idx].ef.Fountain.movedir[0]) +
1055 				   (3 * cl.Effects[idx].ef.Fountain.vforward[0] * cl.Effects[idx].ef.Fountain.movedir[1]) +
1056 				   (10 * cl.Effects[idx].ef.Fountain.vup[0] * cl.Effects[idx].ef.Fountain.movedir[2]);
1057 			mymax[1] = (3 * cl.Effects[idx].ef.Fountain.vright[1] * cl.Effects[idx].ef.Fountain.movedir[0]) +
1058 				   (3 * cl.Effects[idx].ef.Fountain.vforward[1] * cl.Effects[idx].ef.Fountain.movedir[1]) +
1059 				   (10 * cl.Effects[idx].ef.Fountain.vup[1] * cl.Effects[idx].ef.Fountain.movedir[2]);
1060 			mymax[2] = (3 * cl.Effects[idx].ef.Fountain.vright[2] * cl.Effects[idx].ef.Fountain.movedir[0]) +
1061 				   (3 * cl.Effects[idx].ef.Fountain.vforward[2] * cl.Effects[idx].ef.Fountain.movedir[1]) +
1062 				   (10 * cl.Effects[idx].ef.Fountain.vup[2] * cl.Effects[idx].ef.Fountain.movedir[2]);
1063 			mymax[0] *= 15;
1064 			mymax[1] *= 15;
1065 			mymax[2] *= 15;
1066 
1067 			R_RunParticleEffect2 (cl.Effects[idx].ef.Fountain.pos, mymin, mymax,
1068 						cl.Effects[idx].ef.Fountain.color, pt_fastgrav,
1069 						cl.Effects[idx].ef.Fountain.cnt);
1070 
1071 			/*
1072 			memset(&test, 0, sizeof(test));
1073 			trace = SV_Move (cl.Effects[idx].ef.Fountain.pos, mymin, mymax, mymin,
1074 										false, &test);
1075 			Con_Printf("Fraction is %f\n", trace.fraction);
1076 			*/
1077 			break;
1078 
1079 		case CE_QUAKE:
1080 			R_RunQuakeEffect (cl.Effects[idx].ef.Quake.origin,
1081 						cl.Effects[idx].ef.Quake.radius);
1082 			break;
1083 
1084 		case CE_WHITE_SMOKE:
1085 		case CE_GREEN_SMOKE:
1086 		case CE_GREY_SMOKE:
1087 		case CE_RED_SMOKE:
1088 		case CE_SLOW_WHITE_SMOKE:
1089 		case CE_TELESMK1:
1090 		case CE_TELESMK2:
1091 		case CE_GHOST:
1092 		case CE_REDCLOUD:
1093 		case CE_FLAMESTREAM:
1094 		case CE_ACID_MUZZFL:
1095 		case CE_FLAMEWALL:
1096 		case CE_FLAMEWALL2:
1097 		case CE_ONFIRE:
1098 			cl.Effects[idx].ef.Smoke.time_amount += frametime;
1099 			ent = &EffectEntities[cl.Effects[idx].ef.Smoke.entity_index];
1100 
1101 			smoketime = cl.Effects[idx].ef.Smoke.framelength;
1102 			if (!smoketime)
1103 				smoketime = HX_FRAME_TIME;
1104 
1105 			ent->origin[0] += (frametime/smoketime) * cl.Effects[idx].ef.Smoke.velocity[0];
1106 			ent->origin[1] += (frametime/smoketime) * cl.Effects[idx].ef.Smoke.velocity[1];
1107 			ent->origin[2] += (frametime/smoketime) * cl.Effects[idx].ef.Smoke.velocity[2];
1108 
1109 			while (cl.Effects[idx].ef.Smoke.time_amount >= smoketime)
1110 			{
1111 				ent->frame++;
1112 				cl.Effects[idx].ef.Smoke.time_amount -= smoketime;
1113 			}
1114 
1115 			if (ent->frame >= ent->model->numframes)
1116 			{
1117 				CL_FreeEffect(idx);
1118 			}
1119 			else
1120 			{
1121 				CL_LinkEntity(ent);
1122 			}
1123 
1124 			break;
1125 
1126 		/* Just go through animation and then remove */
1127 		case CE_SM_WHITE_FLASH:
1128 		case CE_YELLOWRED_FLASH:
1129 		case CE_BLUESPARK:
1130 		case CE_YELLOWSPARK:
1131 		case CE_SM_CIRCLE_EXP:
1132 		case CE_BG_CIRCLE_EXP:
1133 		case CE_SM_EXPLOSION:
1134 		case CE_LG_EXPLOSION:
1135 		case CE_FLOOR_EXPLOSION:
1136 		case CE_FLOOR_EXPLOSION3:
1137 		case CE_BLUE_EXPLOSION:
1138 		case CE_REDSPARK:
1139 		case CE_GREENSPARK:
1140 		case CE_ICEHIT:
1141 		case CE_MEDUSA_HIT:
1142 		case CE_MEZZO_REFLECT:
1143 		case CE_FLOOR_EXPLOSION2:
1144 		case CE_XBOW_EXPLOSION:
1145 		case CE_NEW_EXPLOSION:
1146 		case CE_MAGIC_MISSILE_EXPLOSION:
1147 		case CE_BONE_EXPLOSION:
1148 		case CE_BLDRN_EXPL:
1149 		case CE_BRN_BOUNCE:
1150 		case CE_ACID_HIT:
1151 		case CE_ACID_SPLAT:
1152 		case CE_ACID_EXPL:
1153 		case CE_LBALL_EXPL:
1154 		case CE_FBOOM:
1155 		case CE_BOMB:
1156 		case CE_FIREWALL_SMALL:
1157 		case CE_FIREWALL_MEDIUM:
1158 		case CE_FIREWALL_LARGE:
1159 			cl.Effects[idx].ef.Smoke.time_amount += frametime;
1160 			ent = &EffectEntities[cl.Effects[idx].ef.Smoke.entity_index];
1161 
1162 			if (cl.Effects[idx].type != CE_BG_CIRCLE_EXP)
1163 			{
1164 				while (cl.Effects[idx].ef.Smoke.time_amount >= HX_FRAME_TIME)
1165 				{
1166 					ent->frame++;
1167 					cl.Effects[idx].ef.Smoke.time_amount -= HX_FRAME_TIME;
1168 				}
1169 			}
1170 			else
1171 			{
1172 				while (cl.Effects[idx].ef.Smoke.time_amount >= HX_FRAME_TIME * 2)
1173 				{
1174 					ent->frame++;
1175 					cl.Effects[idx].ef.Smoke.time_amount -= HX_FRAME_TIME * 2;
1176 				}
1177 			}
1178 			if (ent->frame >= ent->model->numframes)
1179 			{
1180 				CL_FreeEffect(idx);
1181 			}
1182 			else
1183 			{
1184 				CL_LinkEntity(ent);
1185 			}
1186 			break;
1187 
1188 		case CE_LSHOCK:
1189 			ent = &EffectEntities[cl.Effects[idx].ef.Smoke.entity_index];
1190 			if (ent->skinnum == 0)
1191 				ent->skinnum = 1;
1192 			else if (ent->skinnum == 1)
1193 				ent->skinnum = 0;
1194 			ent->scale -= 10;
1195 			if (ent->scale <= 10)
1196 			{
1197 				CL_FreeEffect(idx);
1198 			}
1199 			else
1200 			{
1201 				CL_LinkEntity(ent);
1202 			}
1203 			break;
1204 
1205 		/* Go forward then backward through animation then remove */
1206 		case CE_WHITE_FLASH:
1207 		case CE_BLUE_FLASH:
1208 		case CE_SM_BLUE_FLASH:
1209 		case CE_RED_FLASH:
1210 			cl.Effects[idx].ef.Flash.time_amount += frametime;
1211 			ent = &EffectEntities[cl.Effects[idx].ef.Flash.entity_index];
1212 
1213 			while (cl.Effects[idx].ef.Flash.time_amount >= HX_FRAME_TIME)
1214 			{
1215 				if (!cl.Effects[idx].ef.Flash.reverse)
1216 				{
1217 					if (ent->frame >= ent->model->numframes-1)
1218 					{
1219 					/* Ran through forward animation */
1220 						cl.Effects[idx].ef.Flash.reverse = 1;
1221 						ent->frame--;
1222 					}
1223 					else
1224 						ent->frame++;
1225 				}
1226 				else
1227 				{
1228 					ent->frame--;
1229 				}
1230 
1231 				cl.Effects[idx].ef.Flash.time_amount -= HX_FRAME_TIME;
1232 			}
1233 
1234 			if ((ent->frame <= 0) && (cl.Effects[idx].ef.Flash.reverse))
1235 			{
1236 				CL_FreeEffect(idx);
1237 			}
1238 			else
1239 			{
1240 				CL_LinkEntity(ent);
1241 			}
1242 			break;
1243 
1244 		case CE_RIDER_DEATH:
1245 			cl.Effects[idx].ef.RD.time_amount += frametime;
1246 			if (cl.Effects[idx].ef.RD.time_amount >= 1)
1247 			{
1248 				cl.Effects[idx].ef.RD.stage++;
1249 				cl.Effects[idx].ef.RD.time_amount -= 1;
1250 			}
1251 
1252 			VectorCopy(cl.Effects[idx].ef.RD.origin, org);
1253 			org[0] += sin(cl.Effects[idx].ef.RD.time_amount * 2 * M_PI) * 30;
1254 			org[1] += cos(cl.Effects[idx].ef.RD.time_amount * 2 * M_PI) * 30;
1255 
1256 			if (cl.Effects[idx].ef.RD.stage <= 6)
1257 			{
1258 			//	RiderParticle(cl.Effects[idx].ef.RD.stage + 1, cl.Effects[idx].ef.RD.origin);
1259 				RiderParticle(cl.Effects[idx].ef.RD.stage + 1, org);
1260 			}
1261 			else
1262 			{
1263 				/* To set the rider's origin point for the particles */
1264 				RiderParticle(0, org);
1265 				if (cl.Effects[idx].ef.RD.stage == 7)
1266 				{
1267 					cl.cshifts[CSHIFT_BONUS].destcolor[0] = 255;
1268 					cl.cshifts[CSHIFT_BONUS].destcolor[1] = 255;
1269 					cl.cshifts[CSHIFT_BONUS].destcolor[2] = 255;
1270 					cl.cshifts[CSHIFT_BONUS].percent = 256;
1271 				}
1272 				else if (cl.Effects[idx].ef.RD.stage > 13)
1273 				{
1274 				//	cl.Effects[idx].ef.RD.stage = 0;
1275 					CL_FreeEffect(idx);
1276 				}
1277 			}
1278 			break;
1279 
1280 		case CE_GRAVITYWELL:
1281 			cl.Effects[idx].ef.RD.time_amount += frametime*2;
1282 			if (cl.Effects[idx].ef.RD.time_amount >= 1)
1283 				cl.Effects[idx].ef.RD.time_amount -= 1;
1284 
1285 			VectorCopy(cl.Effects[idx].ef.RD.origin, org);
1286 			org[0] += sin(cl.Effects[idx].ef.RD.time_amount * 2 * M_PI) * 30;
1287 			org[1] += cos(cl.Effects[idx].ef.RD.time_amount * 2 * M_PI) * 30;
1288 
1289 			if (cl.Effects[idx].ef.RD.lifetime < cl.time)
1290 			{
1291 				CL_FreeEffect(idx);
1292 			}
1293 			else
1294 			{
1295 				GravityWellParticle(rand() % 8, org, cl.Effects[idx].ef.RD.color);
1296 			}
1297 
1298 			break;
1299 
1300 		case CE_TELEPORTERPUFFS:
1301 			cl.Effects[idx].ef.Teleporter.time_amount += frametime;
1302 			smoketime = cl.Effects[idx].ef.Teleporter.framelength;
1303 
1304 			ent = &EffectEntities[cl.Effects[idx].ef.Teleporter.entity_index[0]];
1305 			while (cl.Effects[idx].ef.Teleporter.time_amount >= HX_FRAME_TIME)
1306 			{
1307 				ent->frame++;
1308 				cl.Effects[idx].ef.Teleporter.time_amount -= HX_FRAME_TIME;
1309 			}
1310 			cur_frame = ent->frame;
1311 
1312 			if (cur_frame >= ent->model->numframes)
1313 			{
1314 				CL_FreeEffect(idx);
1315 				break;
1316 			}
1317 
1318 			for (i = 0 ; i < 8 ; ++i)
1319 			{
1320 				ent = &EffectEntities[cl.Effects[idx].ef.Teleporter.entity_index[i]];
1321 
1322 				ent->origin[0] += (frametime/smoketime) * cl.Effects[idx].ef.Teleporter.velocity[i][0];
1323 				ent->origin[1] += (frametime/smoketime) * cl.Effects[idx].ef.Teleporter.velocity[i][1];
1324 				ent->origin[2] += (frametime/smoketime) * cl.Effects[idx].ef.Teleporter.velocity[i][2];
1325 				ent->frame = cur_frame;
1326 
1327 				CL_LinkEntity(ent);
1328 			}
1329 			break;
1330 
1331 		case CE_TELEPORTERBODY:
1332 			cl.Effects[idx].ef.Teleporter.time_amount += frametime;
1333 			smoketime = cl.Effects[idx].ef.Teleporter.framelength;
1334 
1335 			ent = &EffectEntities[cl.Effects[idx].ef.Teleporter.entity_index[0]];
1336 			while (cl.Effects[idx].ef.Teleporter.time_amount >= HX_FRAME_TIME)
1337 			{
1338 				ent->scale -= 15;
1339 				cl.Effects[idx].ef.Teleporter.time_amount -= HX_FRAME_TIME;
1340 			}
1341 
1342 			ent = &EffectEntities[cl.Effects[idx].ef.Teleporter.entity_index[0]];
1343 			ent->angles[1] += 45;
1344 
1345 			if (ent->scale <= 10)
1346 			{
1347 				CL_FreeEffect(idx);
1348 			}
1349 			else
1350 			{
1351 				CL_LinkEntity(ent);
1352 			}
1353 			break;
1354 
1355 		case CE_BONESHARD:
1356 		case CE_BONESHRAPNEL:
1357 			cl.Effects[idx].ef.Missile.time_amount += frametime;
1358 			ent = &EffectEntities[cl.Effects[idx].ef.Missile.entity_index];
1359 
1360 		//	ent->angles[0] = cl.Effects[idx].ef.Missile.angle[0];
1361 		//	ent->angles[1] = cl.Effects[idx].ef.Missile.angle[1];
1362 		//	ent->angles[2] = cl.Effects[idx].ef.Missile.angle[2];
1363 
1364 			ent->angles[0] += frametime * cl.Effects[idx].ef.Missile.avelocity[0];
1365 			ent->angles[1] += frametime * cl.Effects[idx].ef.Missile.avelocity[1];
1366 			ent->angles[2] += frametime * cl.Effects[idx].ef.Missile.avelocity[2];
1367 
1368 			ent->origin[0] += frametime * cl.Effects[idx].ef.Missile.velocity[0];
1369 			ent->origin[1] += frametime * cl.Effects[idx].ef.Missile.velocity[1];
1370 			ent->origin[2] += frametime * cl.Effects[idx].ef.Missile.velocity[2];
1371 
1372 			CL_LinkEntity(ent);
1373 			break;
1374 
1375 		case CE_CHUNK:
1376 			cl.Effects[idx].ef.Chunk.time_amount -= frametime;
1377 			if (cl.Effects[idx].ef.Chunk.time_amount < 0)
1378 			{
1379 				CL_FreeEffect(idx);
1380 			}
1381 			else
1382 			{
1383 				for (i = 0 ; i < cl.Effects[idx].ef.Chunk.numChunks ; i++)
1384 				{
1385 					vec3_t		oldorg;
1386 					mleaf_t		*l;
1387 					int		moving = 1;
1388 
1389 					ent = &EffectEntities[cl.Effects[idx].ef.Chunk.entity_index[i]];
1390 
1391 					VectorCopy(ent->origin, oldorg);
1392 
1393 					ent->origin[0] += frametime * cl.Effects[idx].ef.Chunk.velocity[i][0];
1394 					ent->origin[1] += frametime * cl.Effects[idx].ef.Chunk.velocity[i][1];
1395 					ent->origin[2] += frametime * cl.Effects[idx].ef.Chunk.velocity[i][2];
1396 
1397 					l = Mod_PointInLeaf (ent->origin, cl.worldmodel);
1398 					if (l->contents != CONTENTS_EMPTY) //|| in_solid == true
1399 					{	/* bouncing prolly won't work... */
1400 						VectorCopy(oldorg, ent->origin);
1401 
1402 						cl.Effects[idx].ef.Chunk.velocity[i][0] = 0;
1403 						cl.Effects[idx].ef.Chunk.velocity[i][1] = 0;
1404 						cl.Effects[idx].ef.Chunk.velocity[i][2] = 0;
1405 
1406 						moving = 0;
1407 					}
1408 					else
1409 					{
1410 						ent->angles[0] += frametime * cl.Effects[idx].ef.Chunk.avel[i%3][0];
1411 						ent->angles[1] += frametime * cl.Effects[idx].ef.Chunk.avel[i%3][1];
1412 						ent->angles[2] += frametime * cl.Effects[idx].ef.Chunk.avel[i%3][2];
1413 					}
1414 
1415 					if (cl.Effects[idx].ef.Chunk.time_amount < frametime * 3)
1416 					{	/* chunk leaves in 3 frames */
1417 						ent->scale *= .7;
1418 					}
1419 
1420 					CL_LinkEntity(ent);
1421 
1422 					cl.Effects[idx].ef.Chunk.velocity[i][2] -= frametime * 500; /* apply gravity */
1423 
1424 					switch (cl.Effects[idx].ef.Chunk.type)
1425 					{
1426 					case THINGTYPE_GREYSTONE:
1427 						break;
1428 					case THINGTYPE_WOOD:
1429 						break;
1430 					case THINGTYPE_METAL:
1431 						break;
1432 					case THINGTYPE_FLESH:
1433 						if (moving)
1434 							R_RocketTrail (oldorg, ent->origin, 17);
1435 						break;
1436 					case THINGTYPE_FIRE:
1437 						break;
1438 					case THINGTYPE_CLAY:
1439 					case THINGTYPE_BONE:
1440 						break;
1441 					case THINGTYPE_LEAVES:
1442 						break;
1443 					case THINGTYPE_HAY:
1444 						break;
1445 					case THINGTYPE_BROWNSTONE:
1446 						break;
1447 					case THINGTYPE_CLOTH:
1448 						break;
1449 					case THINGTYPE_WOOD_LEAF:
1450 						break;
1451 					case THINGTYPE_WOOD_METAL:
1452 						break;
1453 					case THINGTYPE_WOOD_STONE:
1454 						break;
1455 					case THINGTYPE_METAL_STONE:
1456 						break;
1457 					case THINGTYPE_METAL_CLOTH:
1458 						break;
1459 					case THINGTYPE_WEBS:
1460 						break;
1461 					case THINGTYPE_GLASS:
1462 						break;
1463 					case THINGTYPE_ICE:
1464 						if (moving)
1465 							R_RocketTrail (oldorg, ent->origin, rt_ice);
1466 						break;
1467 					case THINGTYPE_CLEARGLASS:
1468 						break;
1469 					case THINGTYPE_REDGLASS:
1470 						break;
1471 					case THINGTYPE_ACID:
1472 						if (moving)
1473 							R_RocketTrail (oldorg, ent->origin, rt_acidball);
1474 						break;
1475 					case THINGTYPE_METEOR:
1476 						R_RocketTrail (oldorg, ent->origin, 1);
1477 						break;
1478 					case THINGTYPE_GREENFLESH:
1479 						if (moving)
1480 							R_RocketTrail (oldorg, ent->origin, rt_acidball);
1481 						break;
1482 					}
1483 				}
1484 			}
1485 			break;
1486 		}
1487 	}
1488 }
1489 
1490 //==========================================================================
1491 //
1492 // NewEffectEntity
1493 //
1494 //==========================================================================
1495 
NewEffectEntity(void)1496 static int NewEffectEntity (void)
1497 {
1498 	entity_t	*ent;
1499 	int		counter;
1500 
1501 	if (cl_numvisedicts == MAX_VISEDICTS)
1502 		return -1;
1503 
1504 	if (EffectEntityCount == MAX_EFFECT_ENTITIES)
1505 		return -1;
1506 
1507 	for (counter = 0 ; counter < MAX_EFFECT_ENTITIES ; counter++)
1508 	{
1509 		if (!EntityUsed[counter])
1510 			break;
1511 	}
1512 
1513 	EntityUsed[counter] = true;
1514 	EffectEntityCount++;
1515 	ent = &EffectEntities[counter];
1516 	memset(ent, 0, sizeof(*ent));
1517 	ent->colormap = vid.colormap;
1518 
1519 	return counter;
1520 }
1521 
FreeEffectEntity(int idx)1522 static void FreeEffectEntity (int idx)
1523 {
1524 	EntityUsed[idx] = false;
1525 	EffectEntityCount--;
1526 }
1527 
1528