cl_fx.c (49451B)
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 // cl_fx.c -- entity effects parsing and management 21 22 #include "client.h" 23 24 void CL_LogoutEffect (vec3_t org, int type); 25 void CL_ItemRespawnParticles (vec3_t org); 26 27 static vec3_t avelocities [NUMVERTEXNORMALS]; 28 29 extern struct model_s *cl_mod_smoke; 30 extern struct model_s *cl_mod_flash; 31 32 /* 33 ============================================================== 34 35 LIGHT STYLE MANAGEMENT 36 37 ============================================================== 38 */ 39 40 typedef struct 41 { 42 int length; 43 float value[3]; 44 float map[MAX_QPATH]; 45 } clightstyle_t; 46 47 clightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; 48 int lastofs; 49 50 /* 51 ================ 52 CL_ClearLightStyles 53 ================ 54 */ 55 void CL_ClearLightStyles (void) 56 { 57 memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); 58 lastofs = -1; 59 } 60 61 /* 62 ================ 63 CL_RunLightStyles 64 ================ 65 */ 66 void CL_RunLightStyles (void) 67 { 68 int ofs; 69 int i; 70 clightstyle_t *ls; 71 72 ofs = cl.time / 100; 73 if (ofs == lastofs) 74 return; 75 lastofs = ofs; 76 77 for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++) 78 { 79 if (!ls->length) 80 { 81 ls->value[0] = ls->value[1] = ls->value[2] = 1.0; 82 continue; 83 } 84 if (ls->length == 1) 85 ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0]; 86 else 87 ls->value[0] = ls->value[1] = ls->value[2] = ls->map[ofs%ls->length]; 88 } 89 } 90 91 92 void CL_SetLightstyle (int i) 93 { 94 char *s; 95 int j, k; 96 97 s = cl.configstrings[i+CS_LIGHTS]; 98 99 j = strlen (s); 100 if (j >= MAX_QPATH) 101 Com_Error (ERR_DROP, "svc_lightstyle length=%i", j); 102 103 cl_lightstyle[i].length = j; 104 105 for (k=0 ; k<j ; k++) 106 cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a'); 107 } 108 109 /* 110 ================ 111 CL_AddLightStyles 112 ================ 113 */ 114 void CL_AddLightStyles (void) 115 { 116 int i; 117 clightstyle_t *ls; 118 119 for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++) 120 V_AddLightStyle (i, ls->value[0], ls->value[1], ls->value[2]); 121 } 122 123 /* 124 ============================================================== 125 126 DLIGHT MANAGEMENT 127 128 ============================================================== 129 */ 130 131 cdlight_t cl_dlights[MAX_DLIGHTS]; 132 133 /* 134 ================ 135 CL_ClearDlights 136 ================ 137 */ 138 void CL_ClearDlights (void) 139 { 140 memset (cl_dlights, 0, sizeof(cl_dlights)); 141 } 142 143 /* 144 =============== 145 CL_AllocDlight 146 147 =============== 148 */ 149 cdlight_t *CL_AllocDlight (int key) 150 { 151 int i; 152 cdlight_t *dl; 153 154 // first look for an exact key match 155 if (key) 156 { 157 dl = cl_dlights; 158 for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) 159 { 160 if (dl->key == key) 161 { 162 memset (dl, 0, sizeof(*dl)); 163 dl->key = key; 164 return dl; 165 } 166 } 167 } 168 169 // then look for anything else 170 dl = cl_dlights; 171 for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) 172 { 173 if (dl->die < cl.time) 174 { 175 memset (dl, 0, sizeof(*dl)); 176 dl->key = key; 177 return dl; 178 } 179 } 180 181 dl = &cl_dlights[0]; 182 memset (dl, 0, sizeof(*dl)); 183 dl->key = key; 184 return dl; 185 } 186 187 /* 188 =============== 189 CL_NewDlight 190 =============== 191 */ 192 void CL_NewDlight (int key, float x, float y, float z, float radius, float time) 193 { 194 cdlight_t *dl; 195 196 dl = CL_AllocDlight (key); 197 dl->origin[0] = x; 198 dl->origin[1] = y; 199 dl->origin[2] = z; 200 dl->radius = radius; 201 dl->die = cl.time + time; 202 } 203 204 205 /* 206 =============== 207 CL_RunDLights 208 209 =============== 210 */ 211 void CL_RunDLights (void) 212 { 213 int i; 214 cdlight_t *dl; 215 216 dl = cl_dlights; 217 for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) 218 { 219 if (!dl->radius) 220 continue; 221 222 if (dl->die < cl.time) 223 { 224 dl->radius = 0; 225 return; 226 } 227 dl->radius -= cls.frametime*dl->decay; 228 if (dl->radius < 0) 229 dl->radius = 0; 230 } 231 } 232 233 /* 234 ============== 235 CL_ParseMuzzleFlash 236 ============== 237 */ 238 void CL_ParseMuzzleFlash (void) 239 { 240 vec3_t fv, rv; 241 cdlight_t *dl; 242 int i, weapon; 243 centity_t *pl; 244 int silenced; 245 float volume; 246 char soundname[64]; 247 248 i = MSG_ReadShort (&net_message); 249 if (i < 1 || i >= MAX_EDICTS) 250 Com_Error (ERR_DROP, "CL_ParseMuzzleFlash: bad entity"); 251 252 weapon = MSG_ReadByte (&net_message); 253 silenced = weapon & MZ_SILENCED; 254 weapon &= ~MZ_SILENCED; 255 256 pl = &cl_entities[i]; 257 258 dl = CL_AllocDlight (i); 259 VectorCopy (pl->current.origin, dl->origin); 260 AngleVectors (pl->current.angles, fv, rv, NULL); 261 VectorMA (dl->origin, 18, fv, dl->origin); 262 VectorMA (dl->origin, 16, rv, dl->origin); 263 if (silenced) 264 dl->radius = 100 + (rand()&31); 265 else 266 dl->radius = 200 + (rand()&31); 267 dl->minlight = 32; 268 dl->die = cl.time; // + 0.1; 269 270 if (silenced) 271 volume = 0.2; 272 else 273 volume = 1; 274 275 switch (weapon) 276 { 277 case MZ_BLASTER: 278 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 279 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0); 280 break; 281 case MZ_BLUEHYPERBLASTER: 282 dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1; 283 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0); 284 break; 285 case MZ_HYPERBLASTER: 286 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 287 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0); 288 break; 289 case MZ_MACHINEGUN: 290 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 291 Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); 292 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); 293 break; 294 case MZ_SHOTGUN: 295 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 296 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0); 297 S_StartSound (NULL, i, CHAN_AUTO, S_RegisterSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1); 298 break; 299 case MZ_SSHOTGUN: 300 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 301 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0); 302 break; 303 case MZ_CHAINGUN1: 304 dl->radius = 200 + (rand()&31); 305 dl->color[0] = 1;dl->color[1] = 0.25;dl->color[2] = 0; 306 Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); 307 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); 308 break; 309 case MZ_CHAINGUN2: 310 dl->radius = 225 + (rand()&31); 311 dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0; 312 dl->die = cl.time + 0.1; // long delay 313 Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); 314 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); 315 Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); 316 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.05); 317 break; 318 case MZ_CHAINGUN3: 319 dl->radius = 250 + (rand()&31); 320 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 321 dl->die = cl.time + 0.1; // long delay 322 Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); 323 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0); 324 Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); 325 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.033); 326 Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); 327 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.066); 328 break; 329 case MZ_RAILGUN: 330 dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0; 331 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0); 332 break; 333 case MZ_ROCKET: 334 dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2; 335 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0); 336 S_StartSound (NULL, i, CHAN_AUTO, S_RegisterSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1); 337 break; 338 case MZ_GRENADE: 339 dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0; 340 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0); 341 S_StartSound (NULL, i, CHAN_AUTO, S_RegisterSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1); 342 break; 343 case MZ_BFG: 344 dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0; 345 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0); 346 break; 347 348 case MZ_LOGIN: 349 dl->color[0] = 0;dl->color[1] = 1; dl->color[2] = 0; 350 dl->die = cl.time + 1.0; 351 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); 352 CL_LogoutEffect (pl->current.origin, weapon); 353 break; 354 case MZ_LOGOUT: 355 dl->color[0] = 1;dl->color[1] = 0; dl->color[2] = 0; 356 dl->die = cl.time + 1.0; 357 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); 358 CL_LogoutEffect (pl->current.origin, weapon); 359 break; 360 case MZ_RESPAWN: 361 dl->color[0] = 1;dl->color[1] = 1; dl->color[2] = 0; 362 dl->die = cl.time + 1.0; 363 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); 364 CL_LogoutEffect (pl->current.origin, weapon); 365 break; 366 // RAFAEL 367 case MZ_PHALANX: 368 dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5; 369 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/plasshot.wav"), volume, ATTN_NORM, 0); 370 break; 371 // RAFAEL 372 case MZ_IONRIPPER: 373 dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5; 374 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rippfire.wav"), volume, ATTN_NORM, 0); 375 break; 376 377 // ====================== 378 // PGM 379 case MZ_ETF_RIFLE: 380 dl->color[0] = 0.9;dl->color[1] = 0.7;dl->color[2] = 0; 381 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/nail1.wav"), volume, ATTN_NORM, 0); 382 break; 383 case MZ_SHOTGUN2: 384 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 385 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotg2.wav"), volume, ATTN_NORM, 0); 386 break; 387 case MZ_HEATBEAM: 388 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 389 dl->die = cl.time + 100; 390 // S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__l1a.wav"), volume, ATTN_NORM, 0); 391 break; 392 case MZ_BLASTER2: 393 dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0; 394 // FIXME - different sound for blaster2 ?? 395 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0); 396 break; 397 case MZ_TRACKER: 398 // negative flashes handled the same in gl/soft until CL_AddDLights 399 dl->color[0] = -1;dl->color[1] = -1;dl->color[2] = -1; 400 S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/disint2.wav"), volume, ATTN_NORM, 0); 401 break; 402 case MZ_NUKE1: 403 dl->color[0] = 1;dl->color[1] = 0;dl->color[2] = 0; 404 dl->die = cl.time + 100; 405 break; 406 case MZ_NUKE2: 407 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 408 dl->die = cl.time + 100; 409 break; 410 case MZ_NUKE4: 411 dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1; 412 dl->die = cl.time + 100; 413 break; 414 case MZ_NUKE8: 415 dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 1; 416 dl->die = cl.time + 100; 417 break; 418 // PGM 419 // ====================== 420 } 421 } 422 423 424 /* 425 ============== 426 CL_ParseMuzzleFlash2 427 ============== 428 */ 429 void CL_ParseMuzzleFlash2 (void) 430 { 431 int ent; 432 vec3_t origin; 433 int flash_number; 434 cdlight_t *dl; 435 vec3_t forward, right; 436 char soundname[64]; 437 438 ent = MSG_ReadShort (&net_message); 439 if (ent < 1 || ent >= MAX_EDICTS) 440 Com_Error (ERR_DROP, "CL_ParseMuzzleFlash2: bad entity"); 441 442 flash_number = MSG_ReadByte (&net_message); 443 444 // locate the origin 445 AngleVectors (cl_entities[ent].current.angles, forward, right, NULL); 446 origin[0] = cl_entities[ent].current.origin[0] + forward[0] * monster_flash_offset[flash_number][0] + right[0] * monster_flash_offset[flash_number][1]; 447 origin[1] = cl_entities[ent].current.origin[1] + forward[1] * monster_flash_offset[flash_number][0] + right[1] * monster_flash_offset[flash_number][1]; 448 origin[2] = cl_entities[ent].current.origin[2] + forward[2] * monster_flash_offset[flash_number][0] + right[2] * monster_flash_offset[flash_number][1] + monster_flash_offset[flash_number][2]; 449 450 dl = CL_AllocDlight (ent); 451 VectorCopy (origin, dl->origin); 452 dl->radius = 200 + (rand()&31); 453 dl->minlight = 32; 454 dl->die = cl.time; // + 0.1; 455 456 switch (flash_number) 457 { 458 case MZ2_INFANTRY_MACHINEGUN_1: 459 case MZ2_INFANTRY_MACHINEGUN_2: 460 case MZ2_INFANTRY_MACHINEGUN_3: 461 case MZ2_INFANTRY_MACHINEGUN_4: 462 case MZ2_INFANTRY_MACHINEGUN_5: 463 case MZ2_INFANTRY_MACHINEGUN_6: 464 case MZ2_INFANTRY_MACHINEGUN_7: 465 case MZ2_INFANTRY_MACHINEGUN_8: 466 case MZ2_INFANTRY_MACHINEGUN_9: 467 case MZ2_INFANTRY_MACHINEGUN_10: 468 case MZ2_INFANTRY_MACHINEGUN_11: 469 case MZ2_INFANTRY_MACHINEGUN_12: 470 case MZ2_INFANTRY_MACHINEGUN_13: 471 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 472 CL_ParticleEffect (origin, vec3_origin, 0, 40); 473 CL_SmokeAndFlash(origin); 474 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0); 475 break; 476 477 case MZ2_SOLDIER_MACHINEGUN_1: 478 case MZ2_SOLDIER_MACHINEGUN_2: 479 case MZ2_SOLDIER_MACHINEGUN_3: 480 case MZ2_SOLDIER_MACHINEGUN_4: 481 case MZ2_SOLDIER_MACHINEGUN_5: 482 case MZ2_SOLDIER_MACHINEGUN_6: 483 case MZ2_SOLDIER_MACHINEGUN_7: 484 case MZ2_SOLDIER_MACHINEGUN_8: 485 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 486 CL_ParticleEffect (origin, vec3_origin, 0, 40); 487 CL_SmokeAndFlash(origin); 488 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck3.wav"), 1, ATTN_NORM, 0); 489 break; 490 491 case MZ2_GUNNER_MACHINEGUN_1: 492 case MZ2_GUNNER_MACHINEGUN_2: 493 case MZ2_GUNNER_MACHINEGUN_3: 494 case MZ2_GUNNER_MACHINEGUN_4: 495 case MZ2_GUNNER_MACHINEGUN_5: 496 case MZ2_GUNNER_MACHINEGUN_6: 497 case MZ2_GUNNER_MACHINEGUN_7: 498 case MZ2_GUNNER_MACHINEGUN_8: 499 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 500 CL_ParticleEffect (origin, vec3_origin, 0, 40); 501 CL_SmokeAndFlash(origin); 502 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("gunner/gunatck2.wav"), 1, ATTN_NORM, 0); 503 break; 504 505 case MZ2_ACTOR_MACHINEGUN_1: 506 case MZ2_SUPERTANK_MACHINEGUN_1: 507 case MZ2_SUPERTANK_MACHINEGUN_2: 508 case MZ2_SUPERTANK_MACHINEGUN_3: 509 case MZ2_SUPERTANK_MACHINEGUN_4: 510 case MZ2_SUPERTANK_MACHINEGUN_5: 511 case MZ2_SUPERTANK_MACHINEGUN_6: 512 case MZ2_TURRET_MACHINEGUN: // PGM 513 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 514 515 CL_ParticleEffect (origin, vec3_origin, 0, 40); 516 CL_SmokeAndFlash(origin); 517 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0); 518 break; 519 520 case MZ2_BOSS2_MACHINEGUN_L1: 521 case MZ2_BOSS2_MACHINEGUN_L2: 522 case MZ2_BOSS2_MACHINEGUN_L3: 523 case MZ2_BOSS2_MACHINEGUN_L4: 524 case MZ2_BOSS2_MACHINEGUN_L5: 525 case MZ2_CARRIER_MACHINEGUN_L1: // PMM 526 case MZ2_CARRIER_MACHINEGUN_L2: // PMM 527 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 528 529 CL_ParticleEffect (origin, vec3_origin, 0, 40); 530 CL_SmokeAndFlash(origin); 531 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NONE, 0); 532 break; 533 534 case MZ2_SOLDIER_BLASTER_1: 535 case MZ2_SOLDIER_BLASTER_2: 536 case MZ2_SOLDIER_BLASTER_3: 537 case MZ2_SOLDIER_BLASTER_4: 538 case MZ2_SOLDIER_BLASTER_5: 539 case MZ2_SOLDIER_BLASTER_6: 540 case MZ2_SOLDIER_BLASTER_7: 541 case MZ2_SOLDIER_BLASTER_8: 542 case MZ2_TURRET_BLASTER: // PGM 543 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 544 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck2.wav"), 1, ATTN_NORM, 0); 545 break; 546 547 case MZ2_FLYER_BLASTER_1: 548 case MZ2_FLYER_BLASTER_2: 549 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 550 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("flyer/flyatck3.wav"), 1, ATTN_NORM, 0); 551 break; 552 553 case MZ2_MEDIC_BLASTER_1: 554 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 555 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("medic/medatck1.wav"), 1, ATTN_NORM, 0); 556 break; 557 558 case MZ2_HOVER_BLASTER_1: 559 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 560 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("hover/hovatck1.wav"), 1, ATTN_NORM, 0); 561 break; 562 563 case MZ2_FLOAT_BLASTER_1: 564 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 565 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("floater/fltatck1.wav"), 1, ATTN_NORM, 0); 566 break; 567 568 case MZ2_SOLDIER_SHOTGUN_1: 569 case MZ2_SOLDIER_SHOTGUN_2: 570 case MZ2_SOLDIER_SHOTGUN_3: 571 case MZ2_SOLDIER_SHOTGUN_4: 572 case MZ2_SOLDIER_SHOTGUN_5: 573 case MZ2_SOLDIER_SHOTGUN_6: 574 case MZ2_SOLDIER_SHOTGUN_7: 575 case MZ2_SOLDIER_SHOTGUN_8: 576 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 577 CL_SmokeAndFlash(origin); 578 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck1.wav"), 1, ATTN_NORM, 0); 579 break; 580 581 case MZ2_TANK_BLASTER_1: 582 case MZ2_TANK_BLASTER_2: 583 case MZ2_TANK_BLASTER_3: 584 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 585 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0); 586 break; 587 588 case MZ2_TANK_MACHINEGUN_1: 589 case MZ2_TANK_MACHINEGUN_2: 590 case MZ2_TANK_MACHINEGUN_3: 591 case MZ2_TANK_MACHINEGUN_4: 592 case MZ2_TANK_MACHINEGUN_5: 593 case MZ2_TANK_MACHINEGUN_6: 594 case MZ2_TANK_MACHINEGUN_7: 595 case MZ2_TANK_MACHINEGUN_8: 596 case MZ2_TANK_MACHINEGUN_9: 597 case MZ2_TANK_MACHINEGUN_10: 598 case MZ2_TANK_MACHINEGUN_11: 599 case MZ2_TANK_MACHINEGUN_12: 600 case MZ2_TANK_MACHINEGUN_13: 601 case MZ2_TANK_MACHINEGUN_14: 602 case MZ2_TANK_MACHINEGUN_15: 603 case MZ2_TANK_MACHINEGUN_16: 604 case MZ2_TANK_MACHINEGUN_17: 605 case MZ2_TANK_MACHINEGUN_18: 606 case MZ2_TANK_MACHINEGUN_19: 607 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 608 CL_ParticleEffect (origin, vec3_origin, 0, 40); 609 CL_SmokeAndFlash(origin); 610 Com_sprintf(soundname, sizeof(soundname), "tank/tnkatk2%c.wav", 'a' + rand() % 5); 611 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound(soundname), 1, ATTN_NORM, 0); 612 break; 613 614 case MZ2_CHICK_ROCKET_1: 615 case MZ2_TURRET_ROCKET: // PGM 616 dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2; 617 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("chick/chkatck2.wav"), 1, ATTN_NORM, 0); 618 break; 619 620 case MZ2_TANK_ROCKET_1: 621 case MZ2_TANK_ROCKET_2: 622 case MZ2_TANK_ROCKET_3: 623 dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2; 624 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck1.wav"), 1, ATTN_NORM, 0); 625 break; 626 627 case MZ2_SUPERTANK_ROCKET_1: 628 case MZ2_SUPERTANK_ROCKET_2: 629 case MZ2_SUPERTANK_ROCKET_3: 630 case MZ2_BOSS2_ROCKET_1: 631 case MZ2_BOSS2_ROCKET_2: 632 case MZ2_BOSS2_ROCKET_3: 633 case MZ2_BOSS2_ROCKET_4: 634 case MZ2_CARRIER_ROCKET_1: 635 // case MZ2_CARRIER_ROCKET_2: 636 // case MZ2_CARRIER_ROCKET_3: 637 // case MZ2_CARRIER_ROCKET_4: 638 dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2; 639 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/rocket.wav"), 1, ATTN_NORM, 0); 640 break; 641 642 case MZ2_GUNNER_GRENADE_1: 643 case MZ2_GUNNER_GRENADE_2: 644 case MZ2_GUNNER_GRENADE_3: 645 case MZ2_GUNNER_GRENADE_4: 646 dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0; 647 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("gunner/gunatck3.wav"), 1, ATTN_NORM, 0); 648 break; 649 650 case MZ2_GLADIATOR_RAILGUN_1: 651 // PMM 652 case MZ2_CARRIER_RAILGUN: 653 case MZ2_WIDOW_RAIL: 654 // pmm 655 dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0; 656 break; 657 658 // --- Xian's shit starts --- 659 case MZ2_MAKRON_BFG: 660 dl->color[0] = 0.5;dl->color[1] = 1 ;dl->color[2] = 0.5; 661 //S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("makron/bfg_fire.wav"), 1, ATTN_NORM, 0); 662 break; 663 664 case MZ2_MAKRON_BLASTER_1: 665 case MZ2_MAKRON_BLASTER_2: 666 case MZ2_MAKRON_BLASTER_3: 667 case MZ2_MAKRON_BLASTER_4: 668 case MZ2_MAKRON_BLASTER_5: 669 case MZ2_MAKRON_BLASTER_6: 670 case MZ2_MAKRON_BLASTER_7: 671 case MZ2_MAKRON_BLASTER_8: 672 case MZ2_MAKRON_BLASTER_9: 673 case MZ2_MAKRON_BLASTER_10: 674 case MZ2_MAKRON_BLASTER_11: 675 case MZ2_MAKRON_BLASTER_12: 676 case MZ2_MAKRON_BLASTER_13: 677 case MZ2_MAKRON_BLASTER_14: 678 case MZ2_MAKRON_BLASTER_15: 679 case MZ2_MAKRON_BLASTER_16: 680 case MZ2_MAKRON_BLASTER_17: 681 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 682 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("makron/blaster.wav"), 1, ATTN_NORM, 0); 683 break; 684 685 case MZ2_JORG_MACHINEGUN_L1: 686 case MZ2_JORG_MACHINEGUN_L2: 687 case MZ2_JORG_MACHINEGUN_L3: 688 case MZ2_JORG_MACHINEGUN_L4: 689 case MZ2_JORG_MACHINEGUN_L5: 690 case MZ2_JORG_MACHINEGUN_L6: 691 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 692 CL_ParticleEffect (origin, vec3_origin, 0, 40); 693 CL_SmokeAndFlash(origin); 694 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("boss3/xfire.wav"), 1, ATTN_NORM, 0); 695 break; 696 697 case MZ2_JORG_MACHINEGUN_R1: 698 case MZ2_JORG_MACHINEGUN_R2: 699 case MZ2_JORG_MACHINEGUN_R3: 700 case MZ2_JORG_MACHINEGUN_R4: 701 case MZ2_JORG_MACHINEGUN_R5: 702 case MZ2_JORG_MACHINEGUN_R6: 703 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 704 CL_ParticleEffect (origin, vec3_origin, 0, 40); 705 CL_SmokeAndFlash(origin); 706 break; 707 708 case MZ2_JORG_BFG_1: 709 dl->color[0] = 0.5;dl->color[1] = 1 ;dl->color[2] = 0.5; 710 break; 711 712 case MZ2_BOSS2_MACHINEGUN_R1: 713 case MZ2_BOSS2_MACHINEGUN_R2: 714 case MZ2_BOSS2_MACHINEGUN_R3: 715 case MZ2_BOSS2_MACHINEGUN_R4: 716 case MZ2_BOSS2_MACHINEGUN_R5: 717 case MZ2_CARRIER_MACHINEGUN_R1: // PMM 718 case MZ2_CARRIER_MACHINEGUN_R2: // PMM 719 720 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 721 722 CL_ParticleEffect (origin, vec3_origin, 0, 40); 723 CL_SmokeAndFlash(origin); 724 break; 725 726 // ====== 727 // ROGUE 728 case MZ2_STALKER_BLASTER: 729 case MZ2_DAEDALUS_BLASTER: 730 case MZ2_MEDIC_BLASTER_2: 731 case MZ2_WIDOW_BLASTER: 732 case MZ2_WIDOW_BLASTER_SWEEP1: 733 case MZ2_WIDOW_BLASTER_SWEEP2: 734 case MZ2_WIDOW_BLASTER_SWEEP3: 735 case MZ2_WIDOW_BLASTER_SWEEP4: 736 case MZ2_WIDOW_BLASTER_SWEEP5: 737 case MZ2_WIDOW_BLASTER_SWEEP6: 738 case MZ2_WIDOW_BLASTER_SWEEP7: 739 case MZ2_WIDOW_BLASTER_SWEEP8: 740 case MZ2_WIDOW_BLASTER_SWEEP9: 741 case MZ2_WIDOW_BLASTER_100: 742 case MZ2_WIDOW_BLASTER_90: 743 case MZ2_WIDOW_BLASTER_80: 744 case MZ2_WIDOW_BLASTER_70: 745 case MZ2_WIDOW_BLASTER_60: 746 case MZ2_WIDOW_BLASTER_50: 747 case MZ2_WIDOW_BLASTER_40: 748 case MZ2_WIDOW_BLASTER_30: 749 case MZ2_WIDOW_BLASTER_20: 750 case MZ2_WIDOW_BLASTER_10: 751 case MZ2_WIDOW_BLASTER_0: 752 case MZ2_WIDOW_BLASTER_10L: 753 case MZ2_WIDOW_BLASTER_20L: 754 case MZ2_WIDOW_BLASTER_30L: 755 case MZ2_WIDOW_BLASTER_40L: 756 case MZ2_WIDOW_BLASTER_50L: 757 case MZ2_WIDOW_BLASTER_60L: 758 case MZ2_WIDOW_BLASTER_70L: 759 case MZ2_WIDOW_RUN_1: 760 case MZ2_WIDOW_RUN_2: 761 case MZ2_WIDOW_RUN_3: 762 case MZ2_WIDOW_RUN_4: 763 case MZ2_WIDOW_RUN_5: 764 case MZ2_WIDOW_RUN_6: 765 case MZ2_WIDOW_RUN_7: 766 case MZ2_WIDOW_RUN_8: 767 dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0; 768 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0); 769 break; 770 771 case MZ2_WIDOW_DISRUPTOR: 772 dl->color[0] = -1;dl->color[1] = -1;dl->color[2] = -1; 773 S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("weapons/disint2.wav"), 1, ATTN_NORM, 0); 774 break; 775 776 case MZ2_WIDOW_PLASMABEAM: 777 case MZ2_WIDOW2_BEAMER_1: 778 case MZ2_WIDOW2_BEAMER_2: 779 case MZ2_WIDOW2_BEAMER_3: 780 case MZ2_WIDOW2_BEAMER_4: 781 case MZ2_WIDOW2_BEAMER_5: 782 case MZ2_WIDOW2_BEAM_SWEEP_1: 783 case MZ2_WIDOW2_BEAM_SWEEP_2: 784 case MZ2_WIDOW2_BEAM_SWEEP_3: 785 case MZ2_WIDOW2_BEAM_SWEEP_4: 786 case MZ2_WIDOW2_BEAM_SWEEP_5: 787 case MZ2_WIDOW2_BEAM_SWEEP_6: 788 case MZ2_WIDOW2_BEAM_SWEEP_7: 789 case MZ2_WIDOW2_BEAM_SWEEP_8: 790 case MZ2_WIDOW2_BEAM_SWEEP_9: 791 case MZ2_WIDOW2_BEAM_SWEEP_10: 792 case MZ2_WIDOW2_BEAM_SWEEP_11: 793 dl->radius = 300 + (rand()&100); 794 dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0; 795 dl->die = cl.time + 200; 796 break; 797 // ROGUE 798 // ====== 799 800 // --- Xian's shit ends --- 801 802 } 803 } 804 805 806 /* 807 =============== 808 CL_AddDLights 809 810 =============== 811 */ 812 void CL_AddDLights (void) 813 { 814 int i; 815 cdlight_t *dl; 816 817 dl = cl_dlights; 818 819 //===== 820 //PGM 821 if(vidref_val == VIDREF_GL) 822 { 823 for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) 824 { 825 if (!dl->radius) 826 continue; 827 V_AddLight (dl->origin, dl->radius, 828 dl->color[0], dl->color[1], dl->color[2]); 829 } 830 } 831 else 832 { 833 for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) 834 { 835 if (!dl->radius) 836 continue; 837 838 // negative light in software. only black allowed 839 if ((dl->color[0] < 0) || (dl->color[1] < 0) || (dl->color[2] < 0)) 840 { 841 dl->radius = -(dl->radius); 842 dl->color[0] = 1; 843 dl->color[1] = 1; 844 dl->color[2] = 1; 845 } 846 V_AddLight (dl->origin, dl->radius, 847 dl->color[0], dl->color[1], dl->color[2]); 848 } 849 } 850 //PGM 851 //===== 852 } 853 854 855 856 /* 857 ============================================================== 858 859 PARTICLE MANAGEMENT 860 861 ============================================================== 862 */ 863 864 /* 865 // THIS HAS BEEN RELOCATED TO CLIENT.H 866 typedef struct particle_s 867 { 868 struct particle_s *next; 869 870 float time; 871 872 vec3_t org; 873 vec3_t vel; 874 vec3_t accel; 875 float color; 876 float colorvel; 877 float alpha; 878 float alphavel; 879 } cparticle_t; 880 881 882 #define PARTICLE_GRAVITY 40 883 */ 884 885 cparticle_t *active_particles, *free_particles; 886 887 cparticle_t particles[MAX_PARTICLES]; 888 int cl_numparticles = MAX_PARTICLES; 889 890 891 /* 892 =============== 893 CL_ClearParticles 894 =============== 895 */ 896 void CL_ClearParticles (void) 897 { 898 int i; 899 900 free_particles = &particles[0]; 901 active_particles = NULL; 902 903 for (i=0 ;i<cl_numparticles ; i++) 904 particles[i].next = &particles[i+1]; 905 particles[cl_numparticles-1].next = NULL; 906 } 907 908 909 /* 910 =============== 911 CL_ParticleEffect 912 913 Wall impact puffs 914 =============== 915 */ 916 void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count) 917 { 918 int i, j; 919 cparticle_t *p; 920 float d; 921 922 for (i=0 ; i<count ; i++) 923 { 924 if (!free_particles) 925 return; 926 p = free_particles; 927 free_particles = p->next; 928 p->next = active_particles; 929 active_particles = p; 930 931 p->time = cl.time; 932 p->color = color + (rand()&7); 933 934 d = rand()&31; 935 for (j=0 ; j<3 ; j++) 936 { 937 p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; 938 p->vel[j] = crand()*20; 939 } 940 941 p->accel[0] = p->accel[1] = 0; 942 p->accel[2] = -PARTICLE_GRAVITY; 943 p->alpha = 1.0; 944 945 p->alphavel = -1.0 / (0.5 + frand()*0.3); 946 } 947 } 948 949 950 /* 951 =============== 952 CL_ParticleEffect2 953 =============== 954 */ 955 void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count) 956 { 957 int i, j; 958 cparticle_t *p; 959 float d; 960 961 for (i=0 ; i<count ; i++) 962 { 963 if (!free_particles) 964 return; 965 p = free_particles; 966 free_particles = p->next; 967 p->next = active_particles; 968 active_particles = p; 969 970 p->time = cl.time; 971 p->color = color; 972 973 d = rand()&7; 974 for (j=0 ; j<3 ; j++) 975 { 976 p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; 977 p->vel[j] = crand()*20; 978 } 979 980 p->accel[0] = p->accel[1] = 0; 981 p->accel[2] = -PARTICLE_GRAVITY; 982 p->alpha = 1.0; 983 984 p->alphavel = -1.0 / (0.5 + frand()*0.3); 985 } 986 } 987 988 989 // RAFAEL 990 /* 991 =============== 992 CL_ParticleEffect3 993 =============== 994 */ 995 void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count) 996 { 997 int i, j; 998 cparticle_t *p; 999 float d; 1000 1001 for (i=0 ; i<count ; i++) 1002 { 1003 if (!free_particles) 1004 return; 1005 p = free_particles; 1006 free_particles = p->next; 1007 p->next = active_particles; 1008 active_particles = p; 1009 1010 p->time = cl.time; 1011 p->color = color; 1012 1013 d = rand()&7; 1014 for (j=0 ; j<3 ; j++) 1015 { 1016 p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; 1017 p->vel[j] = crand()*20; 1018 } 1019 1020 p->accel[0] = p->accel[1] = 0; 1021 p->accel[2] = PARTICLE_GRAVITY; 1022 p->alpha = 1.0; 1023 1024 p->alphavel = -1.0 / (0.5 + frand()*0.3); 1025 } 1026 } 1027 1028 /* 1029 =============== 1030 CL_TeleporterParticles 1031 =============== 1032 */ 1033 void CL_TeleporterParticles (entity_state_t *ent) 1034 { 1035 int i, j; 1036 cparticle_t *p; 1037 1038 for (i=0 ; i<8 ; i++) 1039 { 1040 if (!free_particles) 1041 return; 1042 p = free_particles; 1043 free_particles = p->next; 1044 p->next = active_particles; 1045 active_particles = p; 1046 1047 p->time = cl.time; 1048 p->color = 0xdb; 1049 1050 for (j=0 ; j<2 ; j++) 1051 { 1052 p->org[j] = ent->origin[j] - 16 + (rand()&31); 1053 p->vel[j] = crand()*14; 1054 } 1055 1056 p->org[2] = ent->origin[2] - 8 + (rand()&7); 1057 p->vel[2] = 80 + (rand()&7); 1058 1059 p->accel[0] = p->accel[1] = 0; 1060 p->accel[2] = -PARTICLE_GRAVITY; 1061 p->alpha = 1.0; 1062 1063 p->alphavel = -0.5; 1064 } 1065 } 1066 1067 1068 /* 1069 =============== 1070 CL_LogoutEffect 1071 1072 =============== 1073 */ 1074 void CL_LogoutEffect (vec3_t org, int type) 1075 { 1076 int i, j; 1077 cparticle_t *p; 1078 1079 for (i=0 ; i<500 ; i++) 1080 { 1081 if (!free_particles) 1082 return; 1083 p = free_particles; 1084 free_particles = p->next; 1085 p->next = active_particles; 1086 active_particles = p; 1087 1088 p->time = cl.time; 1089 1090 if (type == MZ_LOGIN) 1091 p->color = 0xd0 + (rand()&7); // green 1092 else if (type == MZ_LOGOUT) 1093 p->color = 0x40 + (rand()&7); // red 1094 else 1095 p->color = 0xe0 + (rand()&7); // yellow 1096 1097 p->org[0] = org[0] - 16 + frand()*32; 1098 p->org[1] = org[1] - 16 + frand()*32; 1099 p->org[2] = org[2] - 24 + frand()*56; 1100 1101 for (j=0 ; j<3 ; j++) 1102 p->vel[j] = crand()*20; 1103 1104 p->accel[0] = p->accel[1] = 0; 1105 p->accel[2] = -PARTICLE_GRAVITY; 1106 p->alpha = 1.0; 1107 1108 p->alphavel = -1.0 / (1.0 + frand()*0.3); 1109 } 1110 } 1111 1112 1113 /* 1114 =============== 1115 CL_ItemRespawnParticles 1116 1117 =============== 1118 */ 1119 void CL_ItemRespawnParticles (vec3_t org) 1120 { 1121 int i, j; 1122 cparticle_t *p; 1123 1124 for (i=0 ; i<64 ; i++) 1125 { 1126 if (!free_particles) 1127 return; 1128 p = free_particles; 1129 free_particles = p->next; 1130 p->next = active_particles; 1131 active_particles = p; 1132 1133 p->time = cl.time; 1134 1135 p->color = 0xd4 + (rand()&3); // green 1136 1137 p->org[0] = org[0] + crand()*8; 1138 p->org[1] = org[1] + crand()*8; 1139 p->org[2] = org[2] + crand()*8; 1140 1141 for (j=0 ; j<3 ; j++) 1142 p->vel[j] = crand()*8; 1143 1144 p->accel[0] = p->accel[1] = 0; 1145 p->accel[2] = -PARTICLE_GRAVITY*0.2; 1146 p->alpha = 1.0; 1147 1148 p->alphavel = -1.0 / (1.0 + frand()*0.3); 1149 } 1150 } 1151 1152 1153 /* 1154 =============== 1155 CL_ExplosionParticles 1156 =============== 1157 */ 1158 void CL_ExplosionParticles (vec3_t org) 1159 { 1160 int i, j; 1161 cparticle_t *p; 1162 1163 for (i=0 ; i<256 ; i++) 1164 { 1165 if (!free_particles) 1166 return; 1167 p = free_particles; 1168 free_particles = p->next; 1169 p->next = active_particles; 1170 active_particles = p; 1171 1172 p->time = cl.time; 1173 p->color = 0xe0 + (rand()&7); 1174 1175 for (j=0 ; j<3 ; j++) 1176 { 1177 p->org[j] = org[j] + ((rand()%32)-16); 1178 p->vel[j] = (rand()%384)-192; 1179 } 1180 1181 p->accel[0] = p->accel[1] = 0; 1182 p->accel[2] = -PARTICLE_GRAVITY; 1183 p->alpha = 1.0; 1184 1185 p->alphavel = -0.8 / (0.5 + frand()*0.3); 1186 } 1187 } 1188 1189 1190 /* 1191 =============== 1192 CL_BigTeleportParticles 1193 =============== 1194 */ 1195 void CL_BigTeleportParticles (vec3_t org) 1196 { 1197 int i; 1198 cparticle_t *p; 1199 float angle, dist; 1200 static int colortable[4] = {2*8,13*8,21*8,18*8}; 1201 1202 for (i=0 ; i<4096 ; i++) 1203 { 1204 if (!free_particles) 1205 return; 1206 p = free_particles; 1207 free_particles = p->next; 1208 p->next = active_particles; 1209 active_particles = p; 1210 1211 p->time = cl.time; 1212 1213 p->color = colortable[rand()&3]; 1214 1215 angle = M_PI*2*(rand()&1023)/1023.0; 1216 dist = rand()&31; 1217 p->org[0] = org[0] + cos(angle)*dist; 1218 p->vel[0] = cos(angle)*(70+(rand()&63)); 1219 p->accel[0] = -cos(angle)*100; 1220 1221 p->org[1] = org[1] + sin(angle)*dist; 1222 p->vel[1] = sin(angle)*(70+(rand()&63)); 1223 p->accel[1] = -sin(angle)*100; 1224 1225 p->org[2] = org[2] + 8 + (rand()%90); 1226 p->vel[2] = -100 + (rand()&31); 1227 p->accel[2] = PARTICLE_GRAVITY*4; 1228 p->alpha = 1.0; 1229 1230 p->alphavel = -0.3 / (0.5 + frand()*0.3); 1231 } 1232 } 1233 1234 1235 /* 1236 =============== 1237 CL_BlasterParticles 1238 1239 Wall impact puffs 1240 =============== 1241 */ 1242 void CL_BlasterParticles (vec3_t org, vec3_t dir) 1243 { 1244 int i, j; 1245 cparticle_t *p; 1246 float d; 1247 int count; 1248 1249 count = 40; 1250 for (i=0 ; i<count ; i++) 1251 { 1252 if (!free_particles) 1253 return; 1254 p = free_particles; 1255 free_particles = p->next; 1256 p->next = active_particles; 1257 active_particles = p; 1258 1259 p->time = cl.time; 1260 p->color = 0xe0 + (rand()&7); 1261 1262 d = rand()&15; 1263 for (j=0 ; j<3 ; j++) 1264 { 1265 p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; 1266 p->vel[j] = dir[j] * 30 + crand()*40; 1267 } 1268 1269 p->accel[0] = p->accel[1] = 0; 1270 p->accel[2] = -PARTICLE_GRAVITY; 1271 p->alpha = 1.0; 1272 1273 p->alphavel = -1.0 / (0.5 + frand()*0.3); 1274 } 1275 } 1276 1277 1278 /* 1279 =============== 1280 CL_BlasterTrail 1281 1282 =============== 1283 */ 1284 void CL_BlasterTrail (vec3_t start, vec3_t end) 1285 { 1286 vec3_t move; 1287 vec3_t vec; 1288 float len; 1289 int j; 1290 cparticle_t *p; 1291 int dec; 1292 1293 VectorCopy (start, move); 1294 VectorSubtract (end, start, vec); 1295 len = VectorNormalize (vec); 1296 1297 dec = 5; 1298 VectorScale (vec, 5, vec); 1299 1300 // FIXME: this is a really silly way to have a loop 1301 while (len > 0) 1302 { 1303 len -= dec; 1304 1305 if (!free_particles) 1306 return; 1307 p = free_particles; 1308 free_particles = p->next; 1309 p->next = active_particles; 1310 active_particles = p; 1311 VectorClear (p->accel); 1312 1313 p->time = cl.time; 1314 1315 p->alpha = 1.0; 1316 p->alphavel = -1.0 / (0.3+frand()*0.2); 1317 p->color = 0xe0; 1318 for (j=0 ; j<3 ; j++) 1319 { 1320 p->org[j] = move[j] + crand(); 1321 p->vel[j] = crand()*5; 1322 p->accel[j] = 0; 1323 } 1324 1325 VectorAdd (move, vec, move); 1326 } 1327 } 1328 1329 /* 1330 =============== 1331 CL_QuadTrail 1332 1333 =============== 1334 */ 1335 void CL_QuadTrail (vec3_t start, vec3_t end) 1336 { 1337 vec3_t move; 1338 vec3_t vec; 1339 float len; 1340 int j; 1341 cparticle_t *p; 1342 int dec; 1343 1344 VectorCopy (start, move); 1345 VectorSubtract (end, start, vec); 1346 len = VectorNormalize (vec); 1347 1348 dec = 5; 1349 VectorScale (vec, 5, vec); 1350 1351 while (len > 0) 1352 { 1353 len -= dec; 1354 1355 if (!free_particles) 1356 return; 1357 p = free_particles; 1358 free_particles = p->next; 1359 p->next = active_particles; 1360 active_particles = p; 1361 VectorClear (p->accel); 1362 1363 p->time = cl.time; 1364 1365 p->alpha = 1.0; 1366 p->alphavel = -1.0 / (0.8+frand()*0.2); 1367 p->color = 115; 1368 for (j=0 ; j<3 ; j++) 1369 { 1370 p->org[j] = move[j] + crand()*16; 1371 p->vel[j] = crand()*5; 1372 p->accel[j] = 0; 1373 } 1374 1375 VectorAdd (move, vec, move); 1376 } 1377 } 1378 1379 /* 1380 =============== 1381 CL_FlagTrail 1382 1383 =============== 1384 */ 1385 void CL_FlagTrail (vec3_t start, vec3_t end, float color) 1386 { 1387 vec3_t move; 1388 vec3_t vec; 1389 float len; 1390 int j; 1391 cparticle_t *p; 1392 int dec; 1393 1394 VectorCopy (start, move); 1395 VectorSubtract (end, start, vec); 1396 len = VectorNormalize (vec); 1397 1398 dec = 5; 1399 VectorScale (vec, 5, vec); 1400 1401 while (len > 0) 1402 { 1403 len -= dec; 1404 1405 if (!free_particles) 1406 return; 1407 p = free_particles; 1408 free_particles = p->next; 1409 p->next = active_particles; 1410 active_particles = p; 1411 VectorClear (p->accel); 1412 1413 p->time = cl.time; 1414 1415 p->alpha = 1.0; 1416 p->alphavel = -1.0 / (0.8+frand()*0.2); 1417 p->color = color; 1418 for (j=0 ; j<3 ; j++) 1419 { 1420 p->org[j] = move[j] + crand()*16; 1421 p->vel[j] = crand()*5; 1422 p->accel[j] = 0; 1423 } 1424 1425 VectorAdd (move, vec, move); 1426 } 1427 } 1428 1429 /* 1430 =============== 1431 CL_DiminishingTrail 1432 1433 =============== 1434 */ 1435 void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags) 1436 { 1437 vec3_t move; 1438 vec3_t vec; 1439 float len; 1440 int j; 1441 cparticle_t *p; 1442 float dec; 1443 float orgscale; 1444 float velscale; 1445 1446 VectorCopy (start, move); 1447 VectorSubtract (end, start, vec); 1448 len = VectorNormalize (vec); 1449 1450 dec = 0.5; 1451 VectorScale (vec, dec, vec); 1452 1453 if (old->trailcount > 900) 1454 { 1455 orgscale = 4; 1456 velscale = 15; 1457 } 1458 else if (old->trailcount > 800) 1459 { 1460 orgscale = 2; 1461 velscale = 10; 1462 } 1463 else 1464 { 1465 orgscale = 1; 1466 velscale = 5; 1467 } 1468 1469 while (len > 0) 1470 { 1471 len -= dec; 1472 1473 if (!free_particles) 1474 return; 1475 1476 // drop less particles as it flies 1477 if ((rand()&1023) < old->trailcount) 1478 { 1479 p = free_particles; 1480 free_particles = p->next; 1481 p->next = active_particles; 1482 active_particles = p; 1483 VectorClear (p->accel); 1484 1485 p->time = cl.time; 1486 1487 if (flags & EF_GIB) 1488 { 1489 p->alpha = 1.0; 1490 p->alphavel = -1.0 / (1+frand()*0.4); 1491 p->color = 0xe8 + (rand()&7); 1492 for (j=0 ; j<3 ; j++) 1493 { 1494 p->org[j] = move[j] + crand()*orgscale; 1495 p->vel[j] = crand()*velscale; 1496 p->accel[j] = 0; 1497 } 1498 p->vel[2] -= PARTICLE_GRAVITY; 1499 } 1500 else if (flags & EF_GREENGIB) 1501 { 1502 p->alpha = 1.0; 1503 p->alphavel = -1.0 / (1+frand()*0.4); 1504 p->color = 0xdb + (rand()&7); 1505 for (j=0; j< 3; j++) 1506 { 1507 p->org[j] = move[j] + crand()*orgscale; 1508 p->vel[j] = crand()*velscale; 1509 p->accel[j] = 0; 1510 } 1511 p->vel[2] -= PARTICLE_GRAVITY; 1512 } 1513 else 1514 { 1515 p->alpha = 1.0; 1516 p->alphavel = -1.0 / (1+frand()*0.2); 1517 p->color = 4 + (rand()&7); 1518 for (j=0 ; j<3 ; j++) 1519 { 1520 p->org[j] = move[j] + crand()*orgscale; 1521 p->vel[j] = crand()*velscale; 1522 } 1523 p->accel[2] = 20; 1524 } 1525 } 1526 1527 old->trailcount -= 5; 1528 if (old->trailcount < 100) 1529 old->trailcount = 100; 1530 VectorAdd (move, vec, move); 1531 } 1532 } 1533 1534 void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up) 1535 { 1536 float d; 1537 1538 // this rotate and negat guarantees a vector 1539 // not colinear with the original 1540 right[1] = -forward[0]; 1541 right[2] = forward[1]; 1542 right[0] = forward[2]; 1543 1544 d = DotProduct (right, forward); 1545 VectorMA (right, -d, forward, right); 1546 VectorNormalize (right); 1547 CrossProduct (right, forward, up); 1548 } 1549 1550 /* 1551 =============== 1552 CL_RocketTrail 1553 1554 =============== 1555 */ 1556 void CL_RocketTrail (vec3_t start, vec3_t end, centity_t *old) 1557 { 1558 vec3_t move; 1559 vec3_t vec; 1560 float len; 1561 int j; 1562 cparticle_t *p; 1563 float dec; 1564 1565 // smoke 1566 CL_DiminishingTrail (start, end, old, EF_ROCKET); 1567 1568 // fire 1569 VectorCopy (start, move); 1570 VectorSubtract (end, start, vec); 1571 len = VectorNormalize (vec); 1572 1573 dec = 1; 1574 VectorScale (vec, dec, vec); 1575 1576 while (len > 0) 1577 { 1578 len -= dec; 1579 1580 if (!free_particles) 1581 return; 1582 1583 if ( (rand()&7) == 0) 1584 { 1585 p = free_particles; 1586 free_particles = p->next; 1587 p->next = active_particles; 1588 active_particles = p; 1589 1590 VectorClear (p->accel); 1591 p->time = cl.time; 1592 1593 p->alpha = 1.0; 1594 p->alphavel = -1.0 / (1+frand()*0.2); 1595 p->color = 0xdc + (rand()&3); 1596 for (j=0 ; j<3 ; j++) 1597 { 1598 p->org[j] = move[j] + crand()*5; 1599 p->vel[j] = crand()*20; 1600 } 1601 p->accel[2] = -PARTICLE_GRAVITY; 1602 } 1603 VectorAdd (move, vec, move); 1604 } 1605 } 1606 1607 /* 1608 =============== 1609 CL_RailTrail 1610 1611 =============== 1612 */ 1613 void CL_RailTrail (vec3_t start, vec3_t end) 1614 { 1615 vec3_t move; 1616 vec3_t vec; 1617 float len; 1618 int j; 1619 cparticle_t *p; 1620 float dec; 1621 vec3_t right, up; 1622 int i; 1623 float d, c, s; 1624 vec3_t dir; 1625 byte clr = 0x74; 1626 1627 VectorCopy (start, move); 1628 VectorSubtract (end, start, vec); 1629 len = VectorNormalize (vec); 1630 1631 MakeNormalVectors (vec, right, up); 1632 1633 for (i=0 ; i<len ; i++) 1634 { 1635 if (!free_particles) 1636 return; 1637 1638 p = free_particles; 1639 free_particles = p->next; 1640 p->next = active_particles; 1641 active_particles = p; 1642 1643 p->time = cl.time; 1644 VectorClear (p->accel); 1645 1646 d = i * 0.1; 1647 c = cos(d); 1648 s = sin(d); 1649 1650 VectorScale (right, c, dir); 1651 VectorMA (dir, s, up, dir); 1652 1653 p->alpha = 1.0; 1654 p->alphavel = -1.0 / (1+frand()*0.2); 1655 p->color = clr + (rand()&7); 1656 for (j=0 ; j<3 ; j++) 1657 { 1658 p->org[j] = move[j] + dir[j]*3; 1659 p->vel[j] = dir[j]*6; 1660 } 1661 1662 VectorAdd (move, vec, move); 1663 } 1664 1665 dec = 0.75; 1666 VectorScale (vec, dec, vec); 1667 VectorCopy (start, move); 1668 1669 while (len > 0) 1670 { 1671 len -= dec; 1672 1673 if (!free_particles) 1674 return; 1675 p = free_particles; 1676 free_particles = p->next; 1677 p->next = active_particles; 1678 active_particles = p; 1679 1680 p->time = cl.time; 1681 VectorClear (p->accel); 1682 1683 p->alpha = 1.0; 1684 p->alphavel = -1.0 / (0.6+frand()*0.2); 1685 p->color = 0x0 + rand()&15; 1686 1687 for (j=0 ; j<3 ; j++) 1688 { 1689 p->org[j] = move[j] + crand()*3; 1690 p->vel[j] = crand()*3; 1691 p->accel[j] = 0; 1692 } 1693 1694 VectorAdd (move, vec, move); 1695 } 1696 } 1697 1698 // RAFAEL 1699 /* 1700 =============== 1701 CL_IonripperTrail 1702 =============== 1703 */ 1704 void CL_IonripperTrail (vec3_t start, vec3_t ent) 1705 { 1706 vec3_t move; 1707 vec3_t vec; 1708 float len; 1709 int j; 1710 cparticle_t *p; 1711 int dec; 1712 int left = 0; 1713 1714 VectorCopy (start, move); 1715 VectorSubtract (ent, start, vec); 1716 len = VectorNormalize (vec); 1717 1718 dec = 5; 1719 VectorScale (vec, 5, vec); 1720 1721 while (len > 0) 1722 { 1723 len -= dec; 1724 1725 if (!free_particles) 1726 return; 1727 p = free_particles; 1728 free_particles = p->next; 1729 p->next = active_particles; 1730 active_particles = p; 1731 VectorClear (p->accel); 1732 1733 p->time = cl.time; 1734 p->alpha = 0.5; 1735 p->alphavel = -1.0 / (0.3 + frand() * 0.2); 1736 p->color = 0xe4 + (rand()&3); 1737 1738 for (j=0; j<3; j++) 1739 { 1740 p->org[j] = move[j]; 1741 p->accel[j] = 0; 1742 } 1743 if (left) 1744 { 1745 left = 0; 1746 p->vel[0] = 10; 1747 } 1748 else 1749 { 1750 left = 1; 1751 p->vel[0] = -10; 1752 } 1753 1754 p->vel[1] = 0; 1755 p->vel[2] = 0; 1756 1757 VectorAdd (move, vec, move); 1758 } 1759 } 1760 1761 1762 /* 1763 =============== 1764 CL_BubbleTrail 1765 1766 =============== 1767 */ 1768 void CL_BubbleTrail (vec3_t start, vec3_t end) 1769 { 1770 vec3_t move; 1771 vec3_t vec; 1772 float len; 1773 int i, j; 1774 cparticle_t *p; 1775 float dec; 1776 1777 VectorCopy (start, move); 1778 VectorSubtract (end, start, vec); 1779 len = VectorNormalize (vec); 1780 1781 dec = 32; 1782 VectorScale (vec, dec, vec); 1783 1784 for (i=0 ; i<len ; i+=dec) 1785 { 1786 if (!free_particles) 1787 return; 1788 1789 p = free_particles; 1790 free_particles = p->next; 1791 p->next = active_particles; 1792 active_particles = p; 1793 1794 VectorClear (p->accel); 1795 p->time = cl.time; 1796 1797 p->alpha = 1.0; 1798 p->alphavel = -1.0 / (1+frand()*0.2); 1799 p->color = 4 + (rand()&7); 1800 for (j=0 ; j<3 ; j++) 1801 { 1802 p->org[j] = move[j] + crand()*2; 1803 p->vel[j] = crand()*5; 1804 } 1805 p->vel[2] += 6; 1806 1807 VectorAdd (move, vec, move); 1808 } 1809 } 1810 1811 1812 /* 1813 =============== 1814 CL_FlyParticles 1815 =============== 1816 */ 1817 1818 #define BEAMLENGTH 16 1819 void CL_FlyParticles (vec3_t origin, int count) 1820 { 1821 int i; 1822 cparticle_t *p; 1823 float angle; 1824 float sr, sp, sy, cr, cp, cy; 1825 vec3_t forward; 1826 float dist = 64; 1827 float ltime; 1828 1829 1830 if (count > NUMVERTEXNORMALS) 1831 count = NUMVERTEXNORMALS; 1832 1833 if (!avelocities[0][0]) 1834 { 1835 for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++) 1836 avelocities[0][i] = (rand()&255) * 0.01; 1837 } 1838 1839 1840 ltime = (float)cl.time / 1000.0; 1841 for (i=0 ; i<count ; i+=2) 1842 { 1843 angle = ltime * avelocities[i][0]; 1844 sy = sin(angle); 1845 cy = cos(angle); 1846 angle = ltime * avelocities[i][1]; 1847 sp = sin(angle); 1848 cp = cos(angle); 1849 angle = ltime * avelocities[i][2]; 1850 sr = sin(angle); 1851 cr = cos(angle); 1852 1853 forward[0] = cp*cy; 1854 forward[1] = cp*sy; 1855 forward[2] = -sp; 1856 1857 if (!free_particles) 1858 return; 1859 p = free_particles; 1860 free_particles = p->next; 1861 p->next = active_particles; 1862 active_particles = p; 1863 1864 p->time = cl.time; 1865 1866 dist = sin(ltime + i)*64; 1867 p->org[0] = origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH; 1868 p->org[1] = origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH; 1869 p->org[2] = origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH; 1870 1871 VectorClear (p->vel); 1872 VectorClear (p->accel); 1873 1874 p->color = 0; 1875 p->colorvel = 0; 1876 1877 p->alpha = 1; 1878 p->alphavel = -100; 1879 } 1880 } 1881 1882 void CL_FlyEffect (centity_t *ent, vec3_t origin) 1883 { 1884 int n; 1885 int count; 1886 int starttime; 1887 1888 if (ent->fly_stoptime < cl.time) 1889 { 1890 starttime = cl.time; 1891 ent->fly_stoptime = cl.time + 60000; 1892 } 1893 else 1894 { 1895 starttime = ent->fly_stoptime - 60000; 1896 } 1897 1898 n = cl.time - starttime; 1899 if (n < 20000) 1900 count = n * 162 / 20000.0; 1901 else 1902 { 1903 n = ent->fly_stoptime - cl.time; 1904 if (n < 20000) 1905 count = n * 162 / 20000.0; 1906 else 1907 count = 162; 1908 } 1909 1910 CL_FlyParticles (origin, count); 1911 } 1912 1913 1914 /* 1915 =============== 1916 CL_BfgParticles 1917 =============== 1918 */ 1919 1920 #define BEAMLENGTH 16 1921 void CL_BfgParticles (entity_t *ent) 1922 { 1923 int i; 1924 cparticle_t *p; 1925 float angle; 1926 float sr, sp, sy, cr, cp, cy; 1927 vec3_t forward; 1928 float dist = 64; 1929 vec3_t v; 1930 float ltime; 1931 1932 if (!avelocities[0][0]) 1933 { 1934 for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++) 1935 avelocities[0][i] = (rand()&255) * 0.01; 1936 } 1937 1938 1939 ltime = (float)cl.time / 1000.0; 1940 for (i=0 ; i<NUMVERTEXNORMALS ; i++) 1941 { 1942 angle = ltime * avelocities[i][0]; 1943 sy = sin(angle); 1944 cy = cos(angle); 1945 angle = ltime * avelocities[i][1]; 1946 sp = sin(angle); 1947 cp = cos(angle); 1948 angle = ltime * avelocities[i][2]; 1949 sr = sin(angle); 1950 cr = cos(angle); 1951 1952 forward[0] = cp*cy; 1953 forward[1] = cp*sy; 1954 forward[2] = -sp; 1955 1956 if (!free_particles) 1957 return; 1958 p = free_particles; 1959 free_particles = p->next; 1960 p->next = active_particles; 1961 active_particles = p; 1962 1963 p->time = cl.time; 1964 1965 dist = sin(ltime + i)*64; 1966 p->org[0] = ent->origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH; 1967 p->org[1] = ent->origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH; 1968 p->org[2] = ent->origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH; 1969 1970 VectorClear (p->vel); 1971 VectorClear (p->accel); 1972 1973 VectorSubtract (p->org, ent->origin, v); 1974 dist = VectorLength(v) / 90.0; 1975 p->color = floor (0xd0 + dist * 7); 1976 p->colorvel = 0; 1977 1978 p->alpha = 1.0 - dist; 1979 p->alphavel = -100; 1980 } 1981 } 1982 1983 1984 /* 1985 =============== 1986 CL_TrapParticles 1987 =============== 1988 */ 1989 // RAFAEL 1990 void CL_TrapParticles (entity_t *ent) 1991 { 1992 vec3_t move; 1993 vec3_t vec; 1994 vec3_t start, end; 1995 float len; 1996 int j; 1997 cparticle_t *p; 1998 int dec; 1999 2000 ent->origin[2]-=14; 2001 VectorCopy (ent->origin, start); 2002 VectorCopy (ent->origin, end); 2003 end[2]+=64; 2004 2005 VectorCopy (start, move); 2006 VectorSubtract (end, start, vec); 2007 len = VectorNormalize (vec); 2008 2009 dec = 5; 2010 VectorScale (vec, 5, vec); 2011 2012 // FIXME: this is a really silly way to have a loop 2013 while (len > 0) 2014 { 2015 len -= dec; 2016 2017 if (!free_particles) 2018 return; 2019 p = free_particles; 2020 free_particles = p->next; 2021 p->next = active_particles; 2022 active_particles = p; 2023 VectorClear (p->accel); 2024 2025 p->time = cl.time; 2026 2027 p->alpha = 1.0; 2028 p->alphavel = -1.0 / (0.3+frand()*0.2); 2029 p->color = 0xe0; 2030 for (j=0 ; j<3 ; j++) 2031 { 2032 p->org[j] = move[j] + crand(); 2033 p->vel[j] = crand()*15; 2034 p->accel[j] = 0; 2035 } 2036 p->accel[2] = PARTICLE_GRAVITY; 2037 2038 VectorAdd (move, vec, move); 2039 } 2040 2041 { 2042 2043 2044 int i, j, k; 2045 cparticle_t *p; 2046 float vel; 2047 vec3_t dir; 2048 vec3_t org; 2049 2050 2051 ent->origin[2]+=14; 2052 VectorCopy (ent->origin, org); 2053 2054 2055 for (i=-2 ; i<=2 ; i+=4) 2056 for (j=-2 ; j<=2 ; j+=4) 2057 for (k=-2 ; k<=4 ; k+=4) 2058 { 2059 if (!free_particles) 2060 return; 2061 p = free_particles; 2062 free_particles = p->next; 2063 p->next = active_particles; 2064 active_particles = p; 2065 2066 p->time = cl.time; 2067 p->color = 0xe0 + (rand()&3); 2068 2069 p->alpha = 1.0; 2070 p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02); 2071 2072 p->org[0] = org[0] + i + ((rand()&23) * crand()); 2073 p->org[1] = org[1] + j + ((rand()&23) * crand()); 2074 p->org[2] = org[2] + k + ((rand()&23) * crand()); 2075 2076 dir[0] = j * 8; 2077 dir[1] = i * 8; 2078 dir[2] = k * 8; 2079 2080 VectorNormalize (dir); 2081 vel = 50 + rand()&63; 2082 VectorScale (dir, vel, p->vel); 2083 2084 p->accel[0] = p->accel[1] = 0; 2085 p->accel[2] = -PARTICLE_GRAVITY; 2086 } 2087 } 2088 } 2089 2090 2091 /* 2092 =============== 2093 CL_BFGExplosionParticles 2094 =============== 2095 */ 2096 //FIXME combined with CL_ExplosionParticles 2097 void CL_BFGExplosionParticles (vec3_t org) 2098 { 2099 int i, j; 2100 cparticle_t *p; 2101 2102 for (i=0 ; i<256 ; i++) 2103 { 2104 if (!free_particles) 2105 return; 2106 p = free_particles; 2107 free_particles = p->next; 2108 p->next = active_particles; 2109 active_particles = p; 2110 2111 p->time = cl.time; 2112 p->color = 0xd0 + (rand()&7); 2113 2114 for (j=0 ; j<3 ; j++) 2115 { 2116 p->org[j] = org[j] + ((rand()%32)-16); 2117 p->vel[j] = (rand()%384)-192; 2118 } 2119 2120 p->accel[0] = p->accel[1] = 0; 2121 p->accel[2] = -PARTICLE_GRAVITY; 2122 p->alpha = 1.0; 2123 2124 p->alphavel = -0.8 / (0.5 + frand()*0.3); 2125 } 2126 } 2127 2128 2129 /* 2130 =============== 2131 CL_TeleportParticles 2132 2133 =============== 2134 */ 2135 void CL_TeleportParticles (vec3_t org) 2136 { 2137 int i, j, k; 2138 cparticle_t *p; 2139 float vel; 2140 vec3_t dir; 2141 2142 for (i=-16 ; i<=16 ; i+=4) 2143 for (j=-16 ; j<=16 ; j+=4) 2144 for (k=-16 ; k<=32 ; k+=4) 2145 { 2146 if (!free_particles) 2147 return; 2148 p = free_particles; 2149 free_particles = p->next; 2150 p->next = active_particles; 2151 active_particles = p; 2152 2153 p->time = cl.time; 2154 p->color = 7 + (rand()&7); 2155 2156 p->alpha = 1.0; 2157 p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02); 2158 2159 p->org[0] = org[0] + i + (rand()&3); 2160 p->org[1] = org[1] + j + (rand()&3); 2161 p->org[2] = org[2] + k + (rand()&3); 2162 2163 dir[0] = j*8; 2164 dir[1] = i*8; 2165 dir[2] = k*8; 2166 2167 VectorNormalize (dir); 2168 vel = 50 + (rand()&63); 2169 VectorScale (dir, vel, p->vel); 2170 2171 p->accel[0] = p->accel[1] = 0; 2172 p->accel[2] = -PARTICLE_GRAVITY; 2173 } 2174 } 2175 2176 2177 /* 2178 =============== 2179 CL_AddParticles 2180 =============== 2181 */ 2182 void CL_AddParticles (void) 2183 { 2184 cparticle_t *p, *next; 2185 float alpha; 2186 float time, time2; 2187 vec3_t org; 2188 int color; 2189 cparticle_t *active, *tail; 2190 2191 active = NULL; 2192 tail = NULL; 2193 2194 for (p=active_particles ; p ; p=next) 2195 { 2196 next = p->next; 2197 2198 // PMM - added INSTANT_PARTICLE handling for heat beam 2199 if (p->alphavel != INSTANT_PARTICLE) 2200 { 2201 time = (cl.time - p->time)*0.001; 2202 alpha = p->alpha + time*p->alphavel; 2203 if (alpha <= 0) 2204 { // faded out 2205 p->next = free_particles; 2206 free_particles = p; 2207 continue; 2208 } 2209 } 2210 else 2211 { 2212 alpha = p->alpha; 2213 } 2214 2215 p->next = NULL; 2216 if (!tail) 2217 active = tail = p; 2218 else 2219 { 2220 tail->next = p; 2221 tail = p; 2222 } 2223 2224 if (alpha > 1.0) 2225 alpha = 1; 2226 color = p->color; 2227 2228 time2 = time*time; 2229 2230 org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2; 2231 org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2; 2232 org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2; 2233 2234 V_AddParticle (org, color, alpha); 2235 // PMM 2236 if (p->alphavel == INSTANT_PARTICLE) 2237 { 2238 p->alphavel = 0.0; 2239 p->alpha = 0.0; 2240 } 2241 } 2242 2243 active_particles = active; 2244 } 2245 2246 2247 /* 2248 ============== 2249 CL_EntityEvent 2250 2251 An entity has just been parsed that has an event value 2252 2253 the female events are there for backwards compatability 2254 ============== 2255 */ 2256 extern struct sfx_s *cl_sfx_footsteps[4]; 2257 2258 void CL_EntityEvent (entity_state_t *ent) 2259 { 2260 switch (ent->event) 2261 { 2262 case EV_ITEM_RESPAWN: 2263 S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0); 2264 CL_ItemRespawnParticles (ent->origin); 2265 break; 2266 case EV_PLAYER_TELEPORT: 2267 S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0); 2268 CL_TeleportParticles (ent->origin); 2269 break; 2270 case EV_FOOTSTEP: 2271 if (cl_footsteps->value) 2272 S_StartSound (NULL, ent->number, CHAN_BODY, cl_sfx_footsteps[rand()&3], 1, ATTN_NORM, 0); 2273 break; 2274 case EV_FALLSHORT: 2275 S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("player/land1.wav"), 1, ATTN_NORM, 0); 2276 break; 2277 case EV_FALL: 2278 S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall2.wav"), 1, ATTN_NORM, 0); 2279 break; 2280 case EV_FALLFAR: 2281 S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall1.wav"), 1, ATTN_NORM, 0); 2282 break; 2283 } 2284 } 2285 2286 2287 /* 2288 ============== 2289 CL_ClearEffects 2290 2291 ============== 2292 */ 2293 void CL_ClearEffects (void) 2294 { 2295 CL_ClearParticles (); 2296 CL_ClearDlights (); 2297 CL_ClearLightStyles (); 2298 }