cl_newfx.c 24 KB

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