|
|
1.1.1.2 ! root 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: */ 1.1 root 20: // cl_newfx.c -- MORE entity effects parsing and management 21: 22: #include "client.h" 23: 24: extern cparticle_t *active_particles, *free_particles; 25: extern cparticle_t particles[MAX_PARTICLES]; 26: extern int cl_numparticles; 27: extern cvar_t *vid_ref; 28: 29: extern void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up); 30: 31: 32: /* 33: ====== 34: vectoangles2 - this is duplicated in the game DLL, but I need it here. 35: ====== 36: */ 37: void vectoangles2 (vec3_t value1, vec3_t angles) 38: { 39: float forward; 40: float yaw, pitch; 41: 42: if (value1[1] == 0 && value1[0] == 0) 43: { 44: yaw = 0; 45: if (value1[2] > 0) 46: pitch = 90; 47: else 48: pitch = 270; 49: } 50: else 51: { 52: // PMM - fixed to correct for pitch of 0 53: if (value1[0]) 54: yaw = (atan2(value1[1], value1[0]) * 180 / M_PI); 55: else if (value1[1] > 0) 56: yaw = 90; 57: else 58: yaw = 270; 59: 60: if (yaw < 0) 61: yaw += 360; 62: 63: forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); 64: pitch = (atan2(value1[2], forward) * 180 / M_PI); 65: if (pitch < 0) 66: pitch += 360; 67: } 68: 69: angles[PITCH] = -pitch; 70: angles[YAW] = yaw; 71: angles[ROLL] = 0; 72: } 73: 74: //============= 75: //============= 76: void CL_Flashlight (int ent, vec3_t pos) 77: { 78: cdlight_t *dl; 79: 80: dl = CL_AllocDlight (ent); 81: VectorCopy (pos, dl->origin); 82: dl->radius = 400; 83: dl->minlight = 250; 84: dl->die = cl.time + 100; 85: dl->color[0] = 1; 86: dl->color[1] = 1; 87: dl->color[2] = 1; 88: } 89: 90: /* 91: ====== 92: CL_ColorFlash - flash of light 93: ====== 94: */ 95: void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float b) 96: { 97: cdlight_t *dl; 98: 99: if((vidref_val == VIDREF_SOFT) && ((r < 0) || (g<0) || (b<0))) 100: { 101: intensity = -intensity; 102: r = -r; 103: g = -g; 104: b = -b; 105: } 106: 107: dl = CL_AllocDlight (ent); 108: VectorCopy (pos, dl->origin); 109: dl->radius = intensity; 110: dl->minlight = 250; 111: dl->die = cl.time + 100; 112: dl->color[0] = r; 113: dl->color[1] = g; 114: dl->color[2] = b; 115: } 116: 117: 118: /* 119: ====== 120: CL_DebugTrail 121: ====== 122: */ 123: void CL_DebugTrail (vec3_t start, vec3_t end) 124: { 125: vec3_t move; 126: vec3_t vec; 127: float len; 128: // int j; 129: cparticle_t *p; 130: float dec; 131: vec3_t right, up; 132: // int i; 133: // float d, c, s; 134: // vec3_t dir; 135: 136: VectorCopy (start, move); 137: VectorSubtract (end, start, vec); 138: len = VectorNormalize (vec); 139: 140: MakeNormalVectors (vec, right, up); 141: 142: // VectorScale(vec, RT2_SKIP, vec); 143: 144: // dec = 1.0; 145: // dec = 0.75; 146: dec = 3; 147: VectorScale (vec, dec, vec); 148: VectorCopy (start, move); 149: 150: while (len > 0) 151: { 152: len -= dec; 153: 154: if (!free_particles) 155: return; 156: p = free_particles; 157: free_particles = p->next; 158: p->next = active_particles; 159: active_particles = p; 160: 161: p->time = cl.time; 162: VectorClear (p->accel); 163: VectorClear (p->vel); 164: p->alpha = 1.0; 165: p->alphavel = -0.1; 166: // p->alphavel = 0; 167: p->color = 0x74 + (rand()&7); 168: VectorCopy (move, p->org); 169: /* 170: for (j=0 ; j<3 ; j++) 171: { 172: p->org[j] = move[j] + crand()*2; 173: p->vel[j] = crand()*3; 174: p->accel[j] = 0; 175: } 176: */ 177: VectorAdd (move, vec, move); 178: } 179: 180: } 181: 182: /* 183: =============== 184: CL_SmokeTrail 185: =============== 186: */ 187: void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing) 188: { 189: vec3_t move; 190: vec3_t vec; 191: float len; 192: int j; 193: cparticle_t *p; 194: 195: VectorCopy (start, move); 196: VectorSubtract (end, start, vec); 197: len = VectorNormalize (vec); 198: 199: VectorScale (vec, spacing, vec); 200: 201: // FIXME: this is a really silly way to have a loop 202: while (len > 0) 203: { 204: len -= spacing; 205: 206: if (!free_particles) 207: return; 208: p = free_particles; 209: free_particles = p->next; 210: p->next = active_particles; 211: active_particles = p; 212: VectorClear (p->accel); 213: 214: p->time = cl.time; 215: 216: p->alpha = 1.0; 217: p->alphavel = -1.0 / (1+frand()*0.5); 218: p->color = colorStart + (rand() % colorRun); 219: for (j=0 ; j<3 ; j++) 220: { 221: p->org[j] = move[j] + crand()*3; 222: p->accel[j] = 0; 223: } 224: p->vel[2] = 20 + crand()*5; 225: 226: VectorAdd (move, vec, move); 227: } 228: } 229: 230: void CL_ForceWall (vec3_t start, vec3_t end, int color) 231: { 232: vec3_t move; 233: vec3_t vec; 234: float len; 235: int j; 236: cparticle_t *p; 237: 238: VectorCopy (start, move); 239: VectorSubtract (end, start, vec); 240: len = VectorNormalize (vec); 241: 242: VectorScale (vec, 4, vec); 243: 244: // FIXME: this is a really silly way to have a loop 245: while (len > 0) 246: { 247: len -= 4; 248: 249: if (!free_particles) 250: return; 251: 252: if (frand() > 0.3) 253: { 254: p = free_particles; 255: free_particles = p->next; 256: p->next = active_particles; 257: active_particles = p; 258: VectorClear (p->accel); 259: 260: p->time = cl.time; 261: 262: p->alpha = 1.0; 263: p->alphavel = -1.0 / (3.0+frand()*0.5); 264: p->color = color; 265: for (j=0 ; j<3 ; j++) 266: { 267: p->org[j] = move[j] + crand()*3; 268: p->accel[j] = 0; 269: } 270: p->vel[0] = 0; 271: p->vel[1] = 0; 272: p->vel[2] = -40 - (crand()*10); 273: } 274: 275: VectorAdd (move, vec, move); 276: } 277: } 278: 279: void CL_FlameEffects (centity_t *ent, vec3_t origin) 280: { 281: int n, count; 282: int j; 283: cparticle_t *p; 284: 285: count = rand() & 0xF; 286: 287: for(n=0;n<count;n++) 288: { 289: if (!free_particles) 290: return; 291: 292: p = free_particles; 293: free_particles = p->next; 294: p->next = active_particles; 295: active_particles = p; 296: 297: VectorClear (p->accel); 298: p->time = cl.time; 299: 300: p->alpha = 1.0; 301: p->alphavel = -1.0 / (1+frand()*0.2); 302: p->color = 226 + (rand() % 4); 303: for (j=0 ; j<3 ; j++) 304: { 305: p->org[j] = origin[j] + crand()*5; 306: p->vel[j] = crand()*5; 307: } 308: p->vel[2] = crand() * -10; 309: p->accel[2] = -PARTICLE_GRAVITY; 310: } 311: 312: count = rand() & 0x7; 313: 314: for(n=0;n<count;n++) 315: { 316: if (!free_particles) 317: return; 318: p = free_particles; 319: free_particles = p->next; 320: p->next = active_particles; 321: active_particles = p; 322: VectorClear (p->accel); 323: 324: p->time = cl.time; 325: 326: p->alpha = 1.0; 327: p->alphavel = -1.0 / (1+frand()*0.5); 328: p->color = 0 + (rand() % 4); 329: for (j=0 ; j<3 ; j++) 330: { 331: p->org[j] = origin[j] + crand()*3; 332: } 333: p->vel[2] = 20 + crand()*5; 334: } 335: 336: } 337: 338: 339: /* 340: =============== 341: CL_GenericParticleEffect 342: =============== 343: */ 344: void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel) 345: { 346: int i, j; 347: cparticle_t *p; 348: float d; 349: 350: for (i=0 ; i<count ; i++) 351: { 352: if (!free_particles) 353: return; 354: p = free_particles; 355: free_particles = p->next; 356: p->next = active_particles; 357: active_particles = p; 358: 359: p->time = cl.time; 360: if (numcolors > 1) 361: p->color = color + (rand() & numcolors); 362: else 363: p->color = color; 364: 365: d = rand() & dirspread; 366: for (j=0 ; j<3 ; j++) 367: { 368: p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; 369: p->vel[j] = crand()*20; 370: } 371: 372: p->accel[0] = p->accel[1] = 0; 373: p->accel[2] = -PARTICLE_GRAVITY; 374: // VectorCopy (accel, p->accel); 375: p->alpha = 1.0; 376: 377: p->alphavel = -1.0 / (0.5 + frand()*alphavel); 378: // p->alphavel = alphavel; 379: } 380: } 381: 382: /* 383: =============== 384: CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns) 385: 386: =============== 387: */ 388: void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist) 389: { 390: vec3_t move; 391: vec3_t vec; 392: float len; 393: int i, j; 394: cparticle_t *p; 395: float dec; 396: 397: VectorCopy (start, move); 398: VectorSubtract (end, start, vec); 399: len = VectorNormalize (vec); 400: 401: dec = dist; 402: VectorScale (vec, dec, vec); 403: 404: for (i=0 ; i<len ; i+=dec) 405: { 406: if (!free_particles) 407: return; 408: 409: p = free_particles; 410: free_particles = p->next; 411: p->next = active_particles; 412: active_particles = p; 413: 414: VectorClear (p->accel); 415: p->time = cl.time; 416: 417: p->alpha = 1.0; 418: p->alphavel = -1.0 / (1+frand()*0.1); 419: p->color = 4 + (rand()&7); 420: for (j=0 ; j<3 ; j++) 421: { 422: p->org[j] = move[j] + crand()*2; 423: p->vel[j] = crand()*10; 424: } 425: p->org[2] -= 4; 426: // p->vel[2] += 6; 427: p->vel[2] += 20; 428: 429: VectorAdd (move, vec, move); 430: } 431: } 432: 433: //#define CORKSCREW 1 434: //#define DOUBLE_SCREW 1 435: #define RINGS 1 436: //#define SPRAY 1 437: 438: #ifdef CORKSCREW 439: void CL_Heatbeam (vec3_t start, vec3_t end) 440: { 441: vec3_t move; 442: vec3_t vec; 443: float len; 444: int j,k; 445: cparticle_t *p; 446: vec3_t right, up; 447: int i; 448: float d, c, s; 449: vec3_t dir; 450: float ltime; 451: float step = 5.0; 452: 453: VectorCopy (start, move); 454: VectorSubtract (end, start, vec); 455: len = VectorNormalize (vec); 456: 457: // MakeNormalVectors (vec, right, up); 458: VectorCopy (cl.v_right, right); 459: VectorCopy (cl.v_up, up); 460: VectorMA (move, -1, right, move); 461: VectorMA (move, -1, up, move); 462: 463: VectorScale (vec, step, vec); 464: ltime = (float) cl.time/1000.0; 465: 466: // for (i=0 ; i<len ; i++) 467: for (i=0 ; i<len ; i+=step) 468: { 469: d = i * 0.1 - fmod(ltime,16.0)*M_PI; 470: c = cos(d)/1.75; 471: s = sin(d)/1.75; 472: #ifdef DOUBLE_SCREW 473: for (k=-1; k<2; k+=2) 474: { 475: #else 476: k=1; 477: #endif 478: if (!free_particles) 479: return; 480: 481: p = free_particles; 482: free_particles = p->next; 483: p->next = active_particles; 484: active_particles = p; 485: 486: p->time = cl.time; 487: VectorClear (p->accel); 488: 489: p->alpha = 0.5; 490: // p->alphavel = -1.0 / (1+frand()*0.2); 491: // only last one frame! 492: p->alphavel = INSTANT_PARTICLE; 493: // p->color = 0x74 + (rand()&7); 494: // p->color = 223 - (rand()&7); 495: p->color = 223; 496: // p->color = 240; 497: 498: // trim it so it looks like it's starting at the origin 499: if (i < 10) 500: { 501: VectorScale (right, c*(i/10.0)*k, dir); 502: VectorMA (dir, s*(i/10.0)*k, up, dir); 503: } 504: else 505: { 506: VectorScale (right, c*k, dir); 507: VectorMA (dir, s*k, up, dir); 508: } 509: 510: for (j=0 ; j<3 ; j++) 511: { 512: p->org[j] = move[j] + dir[j]*3; 513: // p->vel[j] = dir[j]*6; 514: p->vel[j] = 0; 515: } 516: #ifdef DOUBLE_SCREW 517: } 518: #endif 519: VectorAdd (move, vec, move); 520: } 521: } 522: #endif 523: #ifdef RINGS 524: //void CL_Heatbeam (vec3_t start, vec3_t end) 525: void CL_Heatbeam (vec3_t start, vec3_t forward) 526: { 527: vec3_t move; 528: vec3_t vec; 529: float len; 530: int j; 531: cparticle_t *p; 532: vec3_t right, up; 533: int i; 534: float c, s; 535: vec3_t dir; 536: float ltime; 537: float step = 32.0, rstep; 538: float start_pt; 539: float rot; 540: float variance; 541: vec3_t end; 542: 543: VectorMA (start, 4096, forward, end); 544: 545: VectorCopy (start, move); 546: VectorSubtract (end, start, vec); 547: len = VectorNormalize (vec); 548: 549: // FIXME - pmm - these might end up using old values? 550: // MakeNormalVectors (vec, right, up); 551: VectorCopy (cl.v_right, right); 552: VectorCopy (cl.v_up, up); 553: if (vidref_val == VIDREF_GL) 554: { // GL mode 555: VectorMA (move, -0.5, right, move); 556: VectorMA (move, -0.5, up, move); 557: } 558: // otherwise assume SOFT 559: 560: ltime = (float) cl.time/1000.0; 561: start_pt = fmod(ltime*96.0,step); 562: VectorMA (move, start_pt, vec, move); 563: 564: VectorScale (vec, step, vec); 565: 566: // Com_Printf ("%f\n", ltime); 567: rstep = M_PI/10.0; 568: for (i=start_pt ; i<len ; i+=step) 569: { 570: if (i>step*5) // don't bother after the 5th ring 571: break; 572: 573: for (rot = 0; rot < M_PI*2; rot += rstep) 574: { 575: 576: if (!free_particles) 577: return; 578: 579: p = free_particles; 580: free_particles = p->next; 581: p->next = active_particles; 582: active_particles = p; 583: 584: p->time = cl.time; 585: VectorClear (p->accel); 586: // rot+= fmod(ltime, 12.0)*M_PI; 587: // c = cos(rot)/2.0; 588: // s = sin(rot)/2.0; 589: // variance = 0.4 + ((float)rand()/(float)RAND_MAX) *0.2; 590: variance = 0.5; 591: c = cos(rot)*variance; 592: s = sin(rot)*variance; 593: 594: // trim it so it looks like it's starting at the origin 595: if (i < 10) 596: { 597: VectorScale (right, c*(i/10.0), dir); 598: VectorMA (dir, s*(i/10.0), up, dir); 599: } 600: else 601: { 602: VectorScale (right, c, dir); 603: VectorMA (dir, s, up, dir); 604: } 605: 606: p->alpha = 0.5; 607: // p->alphavel = -1.0 / (1+frand()*0.2); 608: p->alphavel = -1000.0; 609: // p->color = 0x74 + (rand()&7); 610: p->color = 223 - (rand()&7); 611: for (j=0 ; j<3 ; j++) 612: { 613: p->org[j] = move[j] + dir[j]*3; 614: // p->vel[j] = dir[j]*6; 615: p->vel[j] = 0; 616: } 617: } 618: VectorAdd (move, vec, move); 619: } 620: } 621: #endif 622: #ifdef SPRAY 623: void CL_Heatbeam (vec3_t start, vec3_t end) 624: { 625: vec3_t move; 626: vec3_t vec; 627: float len; 628: int j; 629: cparticle_t *p; 630: vec3_t forward, right, up; 631: int i; 632: float d, c, s; 633: vec3_t dir; 634: float ltime; 635: float step = 32.0, rstep; 636: float start_pt; 637: float rot; 638: 639: VectorCopy (start, move); 640: VectorSubtract (end, start, vec); 641: len = VectorNormalize (vec); 642: 643: // MakeNormalVectors (vec, right, up); 644: VectorCopy (cl.v_forward, forward); 645: VectorCopy (cl.v_right, right); 646: VectorCopy (cl.v_up, up); 647: VectorMA (move, -0.5, right, move); 648: VectorMA (move, -0.5, up, move); 649: 650: for (i=0; i<8; i++) 651: { 652: if (!free_particles) 653: return; 654: 655: p = free_particles; 656: free_particles = p->next; 657: p->next = active_particles; 658: active_particles = p; 659: 660: p->time = cl.time; 661: VectorClear (p->accel); 662: 663: d = crand()*M_PI; 664: c = cos(d)*30; 665: s = sin(d)*30; 666: 667: p->alpha = 1.0; 668: p->alphavel = -5.0 / (1+frand()); 669: p->color = 223 - (rand()&7); 670: 671: for (j=0 ; j<3 ; j++) 672: { 673: p->org[j] = move[j]; 674: } 675: VectorScale (vec, 450, p->vel); 676: VectorMA (p->vel, c, right, p->vel); 677: VectorMA (p->vel, s, up, p->vel); 678: } 679: /* 680: 681: ltime = (float) cl.time/1000.0; 682: start_pt = fmod(ltime*16.0,step); 683: VectorMA (move, start_pt, vec, move); 684: 685: VectorScale (vec, step, vec); 686: 687: // Com_Printf ("%f\n", ltime); 688: rstep = M_PI/12.0; 689: for (i=start_pt ; i<len ; i+=step) 690: { 691: if (i>step*5) // don't bother after the 5th ring 692: break; 693: 694: for (rot = 0; rot < M_PI*2; rot += rstep) 695: { 696: if (!free_particles) 697: return; 698: 699: p = free_particles; 700: free_particles = p->next; 701: p->next = active_particles; 702: active_particles = p; 703: 704: p->time = cl.time; 705: VectorClear (p->accel); 706: // rot+= fmod(ltime, 12.0)*M_PI; 707: // c = cos(rot)/2.0; 708: // s = sin(rot)/2.0; 709: c = cos(rot)/1.5; 710: s = sin(rot)/1.5; 711: 712: // trim it so it looks like it's starting at the origin 713: if (i < 10) 714: { 715: VectorScale (right, c*(i/10.0), dir); 716: VectorMA (dir, s*(i/10.0), up, dir); 717: } 718: else 719: { 720: VectorScale (right, c, dir); 721: VectorMA (dir, s, up, dir); 722: } 723: 724: p->alpha = 0.5; 725: // p->alphavel = -1.0 / (1+frand()*0.2); 726: p->alphavel = -1000.0; 727: // p->color = 0x74 + (rand()&7); 728: p->color = 223 - (rand()&7); 729: for (j=0 ; j<3 ; j++) 730: { 731: p->org[j] = move[j] + dir[j]*3; 732: // p->vel[j] = dir[j]*6; 733: p->vel[j] = 0; 734: } 735: } 736: VectorAdd (move, vec, move); 737: } 738: */ 739: } 740: #endif 741: 742: /* 743: =============== 744: CL_ParticleSteamEffect 745: 746: Puffs with velocity along direction, with some randomness thrown in 747: =============== 748: */ 749: void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude) 750: { 751: int i, j; 752: cparticle_t *p; 753: float d; 754: vec3_t r, u; 755: 756: // vectoangles2 (dir, angle_dir); 757: // AngleVectors (angle_dir, f, r, u); 758: 759: MakeNormalVectors (dir, r, u); 760: 761: for (i=0 ; i<count ; i++) 762: { 763: if (!free_particles) 764: return; 765: p = free_particles; 766: free_particles = p->next; 767: p->next = active_particles; 768: active_particles = p; 769: 770: p->time = cl.time; 771: p->color = color + (rand()&7); 772: 773: for (j=0 ; j<3 ; j++) 774: { 775: p->org[j] = org[j] + magnitude*0.1*crand(); 776: // p->vel[j] = dir[j]*magnitude; 777: } 778: VectorScale (dir, magnitude, p->vel); 779: d = crand()*magnitude/3; 780: VectorMA (p->vel, d, r, p->vel); 781: d = crand()*magnitude/3; 782: VectorMA (p->vel, d, u, p->vel); 783: 784: p->accel[0] = p->accel[1] = 0; 785: p->accel[2] = -PARTICLE_GRAVITY/2; 786: p->alpha = 1.0; 787: 788: p->alphavel = -1.0 / (0.5 + frand()*0.3); 789: } 790: } 791: 792: void CL_ParticleSteamEffect2 (cl_sustain_t *self) 793: //vec3_t org, vec3_t dir, int color, int count, int magnitude) 794: { 795: int i, j; 796: cparticle_t *p; 797: float d; 798: vec3_t r, u; 799: vec3_t dir; 800: 801: // vectoangles2 (dir, angle_dir); 802: // AngleVectors (angle_dir, f, r, u); 803: 804: VectorCopy (self->dir, dir); 805: MakeNormalVectors (dir, r, u); 806: 807: for (i=0 ; i<self->count ; i++) 808: { 809: if (!free_particles) 810: return; 811: p = free_particles; 812: free_particles = p->next; 813: p->next = active_particles; 814: active_particles = p; 815: 816: p->time = cl.time; 817: p->color = self->color + (rand()&7); 818: 819: for (j=0 ; j<3 ; j++) 820: { 821: p->org[j] = self->org[j] + self->magnitude*0.1*crand(); 822: // p->vel[j] = dir[j]*magnitude; 823: } 824: VectorScale (dir, self->magnitude, p->vel); 825: d = crand()*self->magnitude/3; 826: VectorMA (p->vel, d, r, p->vel); 827: d = crand()*self->magnitude/3; 828: VectorMA (p->vel, d, u, p->vel); 829: 830: p->accel[0] = p->accel[1] = 0; 831: p->accel[2] = -PARTICLE_GRAVITY/2; 832: p->alpha = 1.0; 833: 834: p->alphavel = -1.0 / (0.5 + frand()*0.3); 835: } 836: self->nextthink += self->thinkinterval; 837: } 838: 839: /* 840: =============== 841: CL_TrackerTrail 842: =============== 843: */ 844: void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor) 845: { 846: vec3_t move; 847: vec3_t vec; 848: vec3_t forward,right,up,angle_dir; 849: float len; 850: int j; 851: cparticle_t *p; 852: int dec; 853: float dist; 854: 855: VectorCopy (start, move); 856: VectorSubtract (end, start, vec); 857: len = VectorNormalize (vec); 858: 859: VectorCopy(vec, forward); 860: vectoangles2 (forward, angle_dir); 861: AngleVectors (angle_dir, forward, right, up); 862: 863: dec = 3; 864: VectorScale (vec, 3, vec); 865: 866: // FIXME: this is a really silly way to have a loop 867: while (len > 0) 868: { 869: len -= dec; 870: 871: if (!free_particles) 872: return; 873: p = free_particles; 874: free_particles = p->next; 875: p->next = active_particles; 876: active_particles = p; 877: VectorClear (p->accel); 878: 879: p->time = cl.time; 880: 881: p->alpha = 1.0; 882: p->alphavel = -2.0; 883: p->color = particleColor; 884: dist = DotProduct(move, forward); 885: VectorMA(move, 8 * cos(dist), up, p->org); 886: for (j=0 ; j<3 ; j++) 887: { 888: // p->org[j] = move[j] + crand(); 889: p->vel[j] = 0; 890: p->accel[j] = 0; 891: } 892: p->vel[2] = 5; 893: 894: VectorAdd (move, vec, move); 895: } 896: } 897: 898: void CL_Tracker_Shell(vec3_t origin) 899: { 900: vec3_t dir; 901: int i; 902: cparticle_t *p; 903: 904: for(i=0;i<300;i++) 905: { 906: if (!free_particles) 907: return; 908: p = free_particles; 909: free_particles = p->next; 910: p->next = active_particles; 911: active_particles = p; 912: VectorClear (p->accel); 913: 914: p->time = cl.time; 915: 916: p->alpha = 1.0; 917: p->alphavel = INSTANT_PARTICLE; 918: p->color = 0; 919: 920: dir[0] = crand(); 921: dir[1] = crand(); 922: dir[2] = crand(); 923: VectorNormalize(dir); 924: 925: VectorMA(origin, 40, dir, p->org); 926: } 927: } 928: 929: void CL_MonsterPlasma_Shell(vec3_t origin) 930: { 931: vec3_t dir; 932: int i; 933: cparticle_t *p; 934: 935: for(i=0;i<40;i++) 936: { 937: if (!free_particles) 938: return; 939: p = free_particles; 940: free_particles = p->next; 941: p->next = active_particles; 942: active_particles = p; 943: VectorClear (p->accel); 944: 945: p->time = cl.time; 946: 947: p->alpha = 1.0; 948: p->alphavel = INSTANT_PARTICLE; 949: p->color = 0xe0; 950: 951: dir[0] = crand(); 952: dir[1] = crand(); 953: dir[2] = crand(); 954: VectorNormalize(dir); 955: 956: VectorMA(origin, 10, dir, p->org); 957: // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org); 958: } 959: } 960: 961: void CL_Widowbeamout (cl_sustain_t *self) 962: { 963: vec3_t dir; 964: int i; 965: cparticle_t *p; 966: static int colortable[4] = {2*8,13*8,21*8,18*8}; 967: float ratio; 968: 969: ratio = 1.0 - (((float)self->endtime - (float)cl.time)/2100.0); 970: 971: for(i=0;i<300;i++) 972: { 973: if (!free_particles) 974: return; 975: p = free_particles; 976: free_particles = p->next; 977: p->next = active_particles; 978: active_particles = p; 979: VectorClear (p->accel); 980: 981: p->time = cl.time; 982: 983: p->alpha = 1.0; 984: p->alphavel = INSTANT_PARTICLE; 985: p->color = colortable[rand()&3]; 986: 987: dir[0] = crand(); 988: dir[1] = crand(); 989: dir[2] = crand(); 990: VectorNormalize(dir); 991: 992: VectorMA(self->org, (45.0 * ratio), dir, p->org); 993: // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org); 994: } 995: } 996: 997: void CL_Nukeblast (cl_sustain_t *self) 998: { 999: vec3_t dir; 1000: int i; 1001: cparticle_t *p; 1002: static int colortable[4] = {110, 112, 114, 116}; 1003: float ratio; 1004: 1005: ratio = 1.0 - (((float)self->endtime - (float)cl.time)/1000.0); 1006: 1007: for(i=0;i<700;i++) 1008: { 1009: if (!free_particles) 1010: return; 1011: p = free_particles; 1012: free_particles = p->next; 1013: p->next = active_particles; 1014: active_particles = p; 1015: VectorClear (p->accel); 1016: 1017: p->time = cl.time; 1018: 1019: p->alpha = 1.0; 1020: p->alphavel = INSTANT_PARTICLE; 1021: p->color = colortable[rand()&3]; 1022: 1023: dir[0] = crand(); 1024: dir[1] = crand(); 1025: dir[2] = crand(); 1026: VectorNormalize(dir); 1027: 1028: VectorMA(self->org, (200.0 * ratio), dir, p->org); 1029: // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org); 1030: } 1031: } 1032: 1033: void CL_WidowSplash (vec3_t org) 1034: { 1035: static int colortable[4] = {2*8,13*8,21*8,18*8}; 1036: int i; 1037: cparticle_t *p; 1038: vec3_t dir; 1039: 1040: for (i=0 ; i<256 ; i++) 1041: { 1042: if (!free_particles) 1043: return; 1044: p = free_particles; 1045: free_particles = p->next; 1046: p->next = active_particles; 1047: active_particles = p; 1048: 1049: p->time = cl.time; 1050: p->color = colortable[rand()&3]; 1051: 1052: dir[0] = crand(); 1053: dir[1] = crand(); 1054: dir[2] = crand(); 1055: VectorNormalize(dir); 1056: VectorMA(org, 45.0, dir, p->org); 1057: VectorMA(vec3_origin, 40.0, dir, p->vel); 1058: 1059: p->accel[0] = p->accel[1] = 0; 1060: p->alpha = 1.0; 1061: 1062: p->alphavel = -0.8 / (0.5 + frand()*0.3); 1063: } 1064: 1065: } 1066: 1067: void CL_Tracker_Explode(vec3_t origin) 1068: { 1069: vec3_t dir, backdir; 1070: int i; 1071: cparticle_t *p; 1072: 1073: for(i=0;i<300;i++) 1074: { 1075: if (!free_particles) 1076: return; 1077: p = free_particles; 1078: free_particles = p->next; 1079: p->next = active_particles; 1080: active_particles = p; 1081: VectorClear (p->accel); 1082: 1083: p->time = cl.time; 1084: 1085: p->alpha = 1.0; 1086: p->alphavel = -1.0; 1087: p->color = 0; 1088: 1089: dir[0] = crand(); 1090: dir[1] = crand(); 1091: dir[2] = crand(); 1092: VectorNormalize(dir); 1093: VectorScale(dir, -1, backdir); 1094: 1095: VectorMA(origin, 64, dir, p->org); 1096: VectorScale(backdir, 64, p->vel); 1097: } 1098: 1099: } 1100: 1101: /* 1102: =============== 1103: CL_TagTrail 1104: 1105: =============== 1106: */ 1107: void CL_TagTrail (vec3_t start, vec3_t end, float color) 1108: { 1109: vec3_t move; 1110: vec3_t vec; 1111: float len; 1112: int j; 1113: cparticle_t *p; 1114: int dec; 1115: 1116: VectorCopy (start, move); 1117: VectorSubtract (end, start, vec); 1118: len = VectorNormalize (vec); 1119: 1120: dec = 5; 1121: VectorScale (vec, 5, vec); 1122: 1123: while (len >= 0) 1124: { 1125: len -= dec; 1126: 1127: if (!free_particles) 1128: return; 1129: p = free_particles; 1130: free_particles = p->next; 1131: p->next = active_particles; 1132: active_particles = p; 1133: VectorClear (p->accel); 1134: 1135: p->time = cl.time; 1136: 1137: p->alpha = 1.0; 1138: p->alphavel = -1.0 / (0.8+frand()*0.2); 1139: p->color = color; 1140: for (j=0 ; j<3 ; j++) 1141: { 1142: p->org[j] = move[j] + crand()*16; 1143: p->vel[j] = crand()*5; 1144: p->accel[j] = 0; 1145: } 1146: 1147: VectorAdd (move, vec, move); 1148: } 1149: } 1150: 1151: /* 1152: =============== 1153: CL_ColorExplosionParticles 1154: =============== 1155: */ 1156: void CL_ColorExplosionParticles (vec3_t org, int color, int run) 1157: { 1158: int i, j; 1159: cparticle_t *p; 1160: 1161: for (i=0 ; i<128 ; i++) 1162: { 1163: if (!free_particles) 1164: return; 1165: p = free_particles; 1166: free_particles = p->next; 1167: p->next = active_particles; 1168: active_particles = p; 1169: 1170: p->time = cl.time; 1171: p->color = color + (rand() % run); 1172: 1173: for (j=0 ; j<3 ; j++) 1174: { 1175: p->org[j] = org[j] + ((rand()%32)-16); 1176: p->vel[j] = (rand()%256)-128; 1177: } 1178: 1179: p->accel[0] = p->accel[1] = 0; 1180: p->accel[2] = -PARTICLE_GRAVITY; 1181: p->alpha = 1.0; 1182: 1183: p->alphavel = -0.4 / (0.6 + frand()*0.2); 1184: } 1185: } 1186: 1187: /* 1188: =============== 1189: CL_ParticleSmokeEffect - like the steam effect, but unaffected by gravity 1190: =============== 1191: */ 1192: void CL_ParticleSmokeEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude) 1193: { 1194: int i, j; 1195: cparticle_t *p; 1196: float d; 1197: vec3_t r, u; 1198: 1199: MakeNormalVectors (dir, r, u); 1200: 1201: for (i=0 ; i<count ; i++) 1202: { 1203: if (!free_particles) 1204: return; 1205: p = free_particles; 1206: free_particles = p->next; 1207: p->next = active_particles; 1208: active_particles = p; 1209: 1210: p->time = cl.time; 1211: p->color = color + (rand()&7); 1212: 1213: for (j=0 ; j<3 ; j++) 1214: { 1215: p->org[j] = org[j] + magnitude*0.1*crand(); 1216: // p->vel[j] = dir[j]*magnitude; 1217: } 1218: VectorScale (dir, magnitude, p->vel); 1219: d = crand()*magnitude/3; 1220: VectorMA (p->vel, d, r, p->vel); 1221: d = crand()*magnitude/3; 1222: VectorMA (p->vel, d, u, p->vel); 1223: 1224: p->accel[0] = p->accel[1] = p->accel[2] = 0; 1225: p->alpha = 1.0; 1226: 1227: p->alphavel = -1.0 / (0.5 + frand()*0.3); 1228: } 1229: } 1230: 1231: /* 1232: =============== 1233: CL_BlasterParticles2 1234: 1235: Wall impact puffs (Green) 1236: =============== 1237: */ 1238: void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color) 1239: { 1240: int i, j; 1241: cparticle_t *p; 1242: float d; 1243: int count; 1244: 1245: count = 40; 1246: for (i=0 ; i<count ; i++) 1247: { 1248: if (!free_particles) 1249: return; 1250: p = free_particles; 1251: free_particles = p->next; 1252: p->next = active_particles; 1253: active_particles = p; 1254: 1255: p->time = cl.time; 1256: p->color = color + (rand()&7); 1257: 1258: d = rand()&15; 1259: for (j=0 ; j<3 ; j++) 1260: { 1261: p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j]; 1262: p->vel[j] = dir[j] * 30 + crand()*40; 1263: } 1264: 1265: p->accel[0] = p->accel[1] = 0; 1266: p->accel[2] = -PARTICLE_GRAVITY; 1267: p->alpha = 1.0; 1268: 1269: p->alphavel = -1.0 / (0.5 + frand()*0.3); 1270: } 1271: } 1272: 1273: /* 1274: =============== 1275: CL_BlasterTrail2 1276: 1277: Green! 1278: =============== 1279: */ 1280: void CL_BlasterTrail2 (vec3_t start, vec3_t end) 1281: { 1282: vec3_t move; 1283: vec3_t vec; 1284: float len; 1285: int j; 1286: cparticle_t *p; 1287: int dec; 1288: 1289: VectorCopy (start, move); 1290: VectorSubtract (end, start, vec); 1291: len = VectorNormalize (vec); 1292: 1293: dec = 5; 1294: VectorScale (vec, 5, vec); 1295: 1296: // FIXME: this is a really silly way to have a loop 1297: while (len > 0) 1298: { 1299: len -= dec; 1300: 1301: if (!free_particles) 1302: return; 1303: p = free_particles; 1304: free_particles = p->next; 1305: p->next = active_particles; 1306: active_particles = p; 1307: VectorClear (p->accel); 1308: 1309: p->time = cl.time; 1310: 1311: p->alpha = 1.0; 1312: p->alphavel = -1.0 / (0.3+frand()*0.2); 1313: p->color = 0xd0; 1314: for (j=0 ; j<3 ; j++) 1315: { 1316: p->org[j] = move[j] + crand(); 1317: p->vel[j] = crand()*5; 1318: p->accel[j] = 0; 1319: } 1320: 1321: VectorAdd (move, vec, move); 1322: } 1323: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.