weapons.qc 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759
  1. /* Copyright (C) 1996-2022 id Software LLC
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13. See file, 'COPYING', for details.
  14. */
  15. /*
  16. */
  17. float lavaGunFired;
  18. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  19. void () player_run;
  20. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  21. void(vector org, vector vel, float damage) SpawnBlood;
  22. void() SuperDamageSound;
  23. // called by worldspawn
  24. void() W_Precache =
  25. {
  26. precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
  27. precache_sound ("weapons/rocket1i.wav"); // spike gun
  28. precache_sound ("weapons/sgun1.wav");
  29. precache_sound ("weapons/guncock.wav"); // player shotgun
  30. precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
  31. precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
  32. precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
  33. precache_sound ("weapons/spike2.wav"); // super spikes
  34. precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
  35. precache_sound ("weapons/grenade.wav"); // grenade launcher
  36. precache_sound ("weapons/bounce.wav"); // grenade bounce
  37. precache_sound ("weapons/shotgn2.wav"); // super shotgun
  38. //ZOID--
  39. // grapple
  40. precache_sound("weapons/chain1.wav");
  41. // precache_sound("weapons/chain2.wav");
  42. // precache_sound("weapons/chain3.wav");
  43. // precache_sound("weapons/bounce2.wav");
  44. // precache_sound("blob/land1.wav");
  45. precache_sound("pendulum/hit.wav");
  46. //--ZOID
  47. precache_sound ("lavagun/snail.wav"); // lava nail gun cooldown
  48. };
  49. float() crandom =
  50. {
  51. return 2*(random() - 0.5);
  52. };
  53. /*
  54. ================
  55. W_FireAxe
  56. ================
  57. */
  58. void() W_FireAxe =
  59. {
  60. local vector source;
  61. local vector org;
  62. makevectors (self.v_angle);
  63. source = self.origin + '0 0 16';
  64. traceline (source, source + v_forward*64, FALSE, self);
  65. if (trace_fraction == 1.0)
  66. return;
  67. org = trace_endpos - v_forward*4;
  68. if (trace_ent.takedamage)
  69. {
  70. trace_ent.axhitme = 1;
  71. SpawnBlood (org, '0 0 0', 20);
  72. T_Damage (trace_ent, self, self, 20);
  73. }
  74. else
  75. { // hit wall
  76. sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  77. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  78. WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  79. WriteCoord (MSG_BROADCAST, org_x);
  80. WriteCoord (MSG_BROADCAST, org_y);
  81. WriteCoord (MSG_BROADCAST, org_z);
  82. }
  83. };
  84. //============================================================================
  85. vector() wall_velocity =
  86. {
  87. local vector vel;
  88. vel = normalize (self.velocity);
  89. vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  90. vel = vel + 2*trace_plane_normal;
  91. vel = vel * 200;
  92. return vel;
  93. };
  94. /*
  95. ================
  96. SpawnMeatSpray
  97. ================
  98. */
  99. void(vector org, vector vel) SpawnMeatSpray =
  100. {
  101. local entity missile, mpuff;
  102. local vector org;
  103. missile = spawn ();
  104. missile.owner = self;
  105. missile.movetype = MOVETYPE_BOUNCE;
  106. missile.solid = SOLID_NOT;
  107. makevectors (self.angles);
  108. missile.velocity = vel;
  109. missile.velocity_z = missile.velocity_z + 250 + 50*random();
  110. missile.avelocity = '3000 1000 2000';
  111. // set missile duration
  112. missile.nextthink = time + 1;
  113. missile.think = SUB_Remove;
  114. setmodel (missile, "progs/zom_gib.mdl");
  115. setsize (missile, '0 0 0', '0 0 0');
  116. setorigin (missile, org);
  117. };
  118. /*
  119. ================
  120. SpawnBlood
  121. ================
  122. */
  123. void(vector org, vector vel, float damage) SpawnBlood =
  124. {
  125. particle (org, vel*0.1, 73, damage*2);
  126. };
  127. /*
  128. ================
  129. spawn_touchblood
  130. ================
  131. */
  132. void(float damage) spawn_touchblood =
  133. {
  134. local vector vel;
  135. vel = wall_velocity () * 0.2;
  136. SpawnBlood (self.origin + vel*0.01, vel, damage);
  137. };
  138. /*
  139. ================
  140. SpawnChunk
  141. ================
  142. */
  143. void(vector org, vector vel) SpawnChunk =
  144. {
  145. particle (org, vel*0.02, 0, 10);
  146. };
  147. /*
  148. ==============================================================================
  149. MULTI-DAMAGE
  150. Collects multiple small damages into a single damage
  151. ==============================================================================
  152. */
  153. entity multi_ent;
  154. float multi_damage;
  155. void() ClearMultiDamage =
  156. {
  157. multi_ent = world;
  158. multi_damage = 0;
  159. };
  160. void() ApplyMultiDamage =
  161. {
  162. if (!multi_ent)
  163. return;
  164. T_Damage (multi_ent, self, self, multi_damage);
  165. };
  166. void(entity hit, float damage) AddMultiDamage =
  167. {
  168. if (!hit)
  169. return;
  170. if (hit != multi_ent)
  171. {
  172. ApplyMultiDamage ();
  173. multi_damage = damage;
  174. multi_ent = hit;
  175. }
  176. else
  177. multi_damage = multi_damage + damage;
  178. };
  179. /*
  180. ==============================================================================
  181. BULLETS
  182. ==============================================================================
  183. */
  184. /*
  185. ================
  186. TraceAttack
  187. ================
  188. */
  189. void(float damage, vector dir) TraceAttack =
  190. {
  191. local vector vel, org;
  192. vel = normalize(dir + v_up*crandom() + v_right*crandom());
  193. vel = vel + 2*trace_plane_normal;
  194. vel = vel * 200;
  195. org = trace_endpos - dir*4;
  196. if (trace_ent.takedamage)
  197. {
  198. SpawnBlood (org, vel*0.2, damage);
  199. AddMultiDamage (trace_ent, damage);
  200. }
  201. else
  202. {
  203. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  204. WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  205. WriteCoord (MSG_BROADCAST, org_x);
  206. WriteCoord (MSG_BROADCAST, org_y);
  207. WriteCoord (MSG_BROADCAST, org_z);
  208. }
  209. };
  210. /*
  211. ================
  212. FireBullets
  213. Used by shotgun, super shotgun, and enemy soldier firing
  214. Go to the trouble of combining multiple pellets into a single damage call.
  215. ================
  216. */
  217. void(float shotcount, vector dir, vector spread) FireBullets =
  218. {
  219. local vector direction;
  220. local vector src;
  221. makevectors(self.v_angle);
  222. src = self.origin + v_forward*10;
  223. src_z = self.absmin_z + self.size_z * 0.7;
  224. ClearMultiDamage ();
  225. while (shotcount > 0)
  226. {
  227. direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  228. traceline (src, src + direction*2048, FALSE, self);
  229. if (trace_fraction != 1.0)
  230. TraceAttack (4, direction);
  231. shotcount = shotcount - 1;
  232. }
  233. ApplyMultiDamage ();
  234. };
  235. /*
  236. ================
  237. W_FireShotgun
  238. ================
  239. */
  240. void() W_FireShotgun =
  241. {
  242. local vector dir;
  243. sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
  244. self.punchangle_x = -2;
  245. self.currentammo = self.ammo_shells1 = self.ammo_shells1 - 1;
  246. UpdateAmmoCounts(self);
  247. dir = aim (self, 100000);
  248. FireBullets (6, dir, '0.04 0.04 0');
  249. };
  250. /*
  251. ================
  252. W_FireSuperShotgun
  253. ================
  254. */
  255. void() W_FireSuperShotgun =
  256. {
  257. local vector dir;
  258. if (self.currentammo == 1)
  259. {
  260. W_FireShotgun ();
  261. return;
  262. }
  263. sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
  264. self.punchangle_x = -4;
  265. self.currentammo = self.ammo_shells1 = self.ammo_shells1 - 2;
  266. UpdateAmmoCounts(self);
  267. dir = aim (self, 100000);
  268. FireBullets (14, dir, '0.14 0.08 0');
  269. };
  270. /*
  271. ==============================================================================
  272. ROCKETS
  273. ==============================================================================
  274. */
  275. void() s_explode1 = [0, s_explode2] {};
  276. void() s_explode2 = [1, s_explode3] {};
  277. void() s_explode3 = [2, s_explode4] {};
  278. void() s_explode4 = [3, s_explode5] {};
  279. void() s_explode5 = [4, s_explode6] {};
  280. void() s_explode6 = [5, SUB_Remove] {};
  281. void() BecomeExplosion =
  282. {
  283. self.movetype = MOVETYPE_NONE;
  284. self.velocity = '0 0 0';
  285. self.touch = SUB_Null;
  286. setmodel (self, "progs/s_explod.spr");
  287. self.solid = SOLID_NOT;
  288. s_explode1 ();
  289. };
  290. void() T_MissileTouch =
  291. {
  292. local float damg;
  293. if (other == self.owner)
  294. return; // don't explode on owner
  295. if (pointcontents(self.origin) == CONTENT_SKY)
  296. {
  297. remove(self);
  298. return;
  299. }
  300. damg = 100 + random()*20;
  301. if (other.health)
  302. {
  303. if (other.classname == "monster_shambler")
  304. damg = damg * 0.5; // mostly immune
  305. T_Damage (other, self, self.owner, damg );
  306. }
  307. // don't do radius damage to the other, because all the damage
  308. // was done in the impact
  309. T_RadiusDamage (self, self.owner, 120, other);
  310. // sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  311. self.origin = self.origin - 8*normalize(self.velocity);
  312. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  313. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  314. WriteCoord (MSG_BROADCAST, self.origin_x);
  315. WriteCoord (MSG_BROADCAST, self.origin_y);
  316. WriteCoord (MSG_BROADCAST, self.origin_z);
  317. BecomeExplosion ();
  318. };
  319. /*
  320. ================
  321. W_FireRocket
  322. ================
  323. */
  324. void() W_FireRocket =
  325. {
  326. local entity missile, mpuff;
  327. self.currentammo = self.ammo_rockets1 = self.ammo_rockets1 - 1;
  328. UpdateAmmoCounts(self);
  329. sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  330. self.punchangle_x = -2;
  331. missile = spawn ();
  332. missile.owner = self;
  333. missile.movetype = MOVETYPE_FLYMISSILE;
  334. missile.solid = SOLID_BBOX;
  335. missile.classname = "missile";
  336. // set missile speed
  337. makevectors (self.v_angle);
  338. missile.velocity = aim(self, 1000);
  339. missile.velocity = missile.velocity * 1000;
  340. missile.angles = vectoangles(missile.velocity);
  341. missile.touch = T_MissileTouch;
  342. // set missile duration
  343. missile.nextthink = time + 5;
  344. missile.think = SUB_Remove;
  345. setmodel (missile, "progs/missile.mdl");
  346. setsize (missile, '0 0 0', '0 0 0');
  347. setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  348. };
  349. /*
  350. ===============================================================================
  351. LIGHTNING
  352. ===============================================================================
  353. */
  354. /*
  355. =================
  356. LightningDamage
  357. =================
  358. */
  359. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  360. {
  361. local entity e1, e2;
  362. local vector f;
  363. f = p2 - p1;
  364. normalize (f);
  365. f_x = 0 - f_y;
  366. f_y = f_x;
  367. f_z = 0;
  368. f = f*16;
  369. e1 = e2 = world;
  370. traceline (p1, p2, FALSE, self);
  371. if (trace_ent.takedamage)
  372. {
  373. particle (trace_endpos, '0 0 100', 225, damage*4);
  374. T_Damage (trace_ent, from, from, damage);
  375. if (self.classname == "player")
  376. {
  377. if (other.classname == "player")
  378. trace_ent.velocity_z = trace_ent.velocity_z + 400;
  379. }
  380. }
  381. e1 = trace_ent;
  382. traceline (p1 + f, p2 + f, FALSE, self);
  383. if (trace_ent != e1 && trace_ent.takedamage)
  384. {
  385. particle (trace_endpos, '0 0 100', 225, damage*4);
  386. T_Damage (trace_ent, from, from, damage);
  387. }
  388. e2 = trace_ent;
  389. traceline (p1 - f, p2 - f, FALSE, self);
  390. if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  391. {
  392. particle (trace_endpos, '0 0 100', 225, damage*4);
  393. T_Damage (trace_ent, from, from, damage);
  394. }
  395. };
  396. void() W_FireLightning =
  397. {
  398. local vector org;
  399. local float cells;
  400. if (self.ammo_cells1 < 1)
  401. {
  402. self.weapon = W_BestWeapon ();
  403. W_SetCurrentAmmo ();
  404. return;
  405. }
  406. // explode if under water
  407. if (self.waterlevel > 1)
  408. {
  409. cells = self.ammo_cells1;
  410. self.ammo_cells1 = 0;
  411. W_SetCurrentAmmo ();
  412. T_RadiusDamage (self, self, 35*cells, world);
  413. return;
  414. }
  415. if (self.t_width < time)
  416. {
  417. sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  418. self.t_width = time + 0.6;
  419. }
  420. self.punchangle_x = -2;
  421. self.currentammo = self.ammo_cells1 = self.ammo_cells1 - 1;
  422. UpdateAmmoCounts(self);
  423. org = self.origin + '0 0 16';
  424. makevectors (self.v_angle);
  425. traceline (org, org + v_forward*600, TRUE, self);
  426. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  427. WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  428. WriteEntity (MSG_BROADCAST, self);
  429. WriteCoord (MSG_BROADCAST, org_x);
  430. WriteCoord (MSG_BROADCAST, org_y);
  431. WriteCoord (MSG_BROADCAST, org_z);
  432. WriteCoord (MSG_BROADCAST, trace_endpos_x);
  433. WriteCoord (MSG_BROADCAST, trace_endpos_y);
  434. WriteCoord (MSG_BROADCAST, trace_endpos_z);
  435. LightningDamage (self.origin + '0 0 16', trace_endpos + v_forward*4, self, 30);
  436. };
  437. //=============================================================================
  438. void() GrenadeExplode =
  439. {
  440. T_RadiusDamage (self, self.owner, 120, world);
  441. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  442. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  443. WriteCoord (MSG_BROADCAST, self.origin_x);
  444. WriteCoord (MSG_BROADCAST, self.origin_y);
  445. WriteCoord (MSG_BROADCAST, self.origin_z);
  446. BecomeExplosion ();
  447. };
  448. void() GrenadeTouch =
  449. {
  450. if (other == self.owner)
  451. return; // don't explode on owner
  452. if (other.takedamage == DAMAGE_AIM)
  453. {
  454. GrenadeExplode();
  455. return;
  456. }
  457. sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
  458. if (self.velocity == '0 0 0')
  459. self.avelocity = '0 0 0';
  460. };
  461. /*
  462. ================
  463. W_FireGrenade
  464. ================
  465. */
  466. void() W_FireGrenade =
  467. {
  468. local entity missile, mpuff;
  469. self.currentammo = self.ammo_rockets1 = self.ammo_rockets1 - 1;
  470. UpdateAmmoCounts(self);
  471. sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  472. self.punchangle_x = -2;
  473. missile = spawn ();
  474. missile.owner = self;
  475. missile.movetype = MOVETYPE_BOUNCE;
  476. missile.solid = SOLID_BBOX;
  477. missile.classname = "grenade";
  478. // set missile speed
  479. makevectors (self.v_angle);
  480. if (self.v_angle_x)
  481. missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  482. else
  483. {
  484. missile.velocity = aim(self, 10000);
  485. missile.velocity = missile.velocity * 600;
  486. missile.velocity_z = 200;
  487. }
  488. missile.avelocity = '300 300 300';
  489. missile.angles = vectoangles(missile.velocity);
  490. missile.touch = GrenadeTouch;
  491. // set missile duration
  492. missile.nextthink = time + 2.5;
  493. missile.think = GrenadeExplode;
  494. setmodel (missile, "progs/grenade.mdl");
  495. setsize (missile, '0 0 0', '0 0 0');
  496. setorigin (missile, self.origin);
  497. };
  498. //=============================================================================
  499. void() spike_touch;
  500. void() superspike_touch;
  501. void() lavaspike_touch;
  502. void() superlavaspike_touch;
  503. /*
  504. ===============
  505. launch_spike
  506. Used for both the player and the ogre
  507. ===============
  508. */
  509. void(vector org, vector dir) launch_spike =
  510. {
  511. newmis = spawn ();
  512. newmis.owner = self;
  513. newmis.movetype = MOVETYPE_FLYMISSILE;
  514. newmis.solid = SOLID_BBOX;
  515. newmis.angles = vectoangles(dir);
  516. newmis.touch = spike_touch;
  517. newmis.classname = "spike";
  518. newmis.think = SUB_Remove;
  519. newmis.nextthink = time + 6;
  520. setmodel (newmis, "progs/spike.mdl");
  521. setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  522. setorigin (newmis, org);
  523. newmis.velocity = dir * 1000;
  524. };
  525. void() W_FireSuperSpikes =
  526. {
  527. local vector dir;
  528. local entity old;
  529. sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  530. self.attack_finished = time + 0.2;
  531. self.currentammo = self.ammo_nails1 = self.ammo_nails1 - 2;
  532. UpdateAmmoCounts(self);
  533. dir = aim (self, 1000);
  534. launch_spike (self.origin + '0 0 16', dir);
  535. newmis.touch = superspike_touch;
  536. setmodel (newmis, "progs/s_spike.mdl");
  537. setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  538. self.punchangle_x = -2;
  539. };
  540. void(float ox) W_FireSpikes =
  541. {
  542. local vector dir;
  543. local entity old;
  544. makevectors (self.v_angle);
  545. if (self.ammo_nails1 >= 2 && self.weapon == IT_SUPER_NAILGUN)
  546. {
  547. W_FireSuperSpikes ();
  548. return;
  549. }
  550. if (self.ammo_nails1 < 1)
  551. {
  552. self.weapon = W_BestWeapon ();
  553. W_SetCurrentAmmo ();
  554. return;
  555. }
  556. sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  557. self.attack_finished = time + 0.2;
  558. self.currentammo = self.ammo_nails1 = self.ammo_nails1 - 1;
  559. UpdateAmmoCounts(self);
  560. dir = aim (self, 1000);
  561. launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  562. self.punchangle_x = -2;
  563. };
  564. .float hit_z;
  565. void() spike_touch =
  566. {
  567. local float rand;
  568. if (other == self.owner)
  569. return;
  570. if (other.solid == SOLID_TRIGGER)
  571. return; // trigger field, do nothing
  572. if (pointcontents(self.origin) == CONTENT_SKY)
  573. {
  574. remove(self);
  575. return;
  576. }
  577. // hit something that bleeds
  578. if (other.takedamage)
  579. {
  580. spawn_touchblood (9);
  581. T_Damage (other, self, self.owner, 9);
  582. }
  583. else
  584. {
  585. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  586. if (self.classname == "wizspike")
  587. WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  588. else if (self.classname == "knightspike")
  589. WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  590. else
  591. WriteByte (MSG_BROADCAST, TE_SPIKE);
  592. WriteCoord (MSG_BROADCAST, self.origin_x);
  593. WriteCoord (MSG_BROADCAST, self.origin_y);
  594. WriteCoord (MSG_BROADCAST, self.origin_z);
  595. }
  596. remove(self);
  597. };
  598. void() superspike_touch =
  599. {
  600. local float rand;
  601. if (other == self.owner)
  602. return;
  603. if (other.solid == SOLID_TRIGGER)
  604. return; // trigger field, do nothing
  605. if (pointcontents(self.origin) == CONTENT_SKY)
  606. {
  607. remove(self);
  608. return;
  609. }
  610. // hit something that bleeds
  611. if (other.takedamage)
  612. {
  613. spawn_touchblood (18);
  614. T_Damage (other, self, self.owner, 18);
  615. }
  616. else
  617. {
  618. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  619. WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  620. WriteCoord (MSG_BROADCAST, self.origin_x);
  621. WriteCoord (MSG_BROADCAST, self.origin_y);
  622. WriteCoord (MSG_BROADCAST, self.origin_z);
  623. }
  624. remove(self);
  625. };
  626. /*
  627. ===============================================================================
  628. PLAYER WEAPON USE
  629. ===============================================================================
  630. */
  631. void() W_SetCurrentAmmo =
  632. {
  633. player_run (); // get out of any weapon firing states
  634. self.items = self.items -
  635. ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));
  636. self.items2 = self.items2 -
  637. (self.items2 & (IT2_LAVA_NAILS|IT2_PLASMA_AMMO|IT2_MULTI_ROCKETS));
  638. if (self.weapon == IT_AXE)
  639. {
  640. self.currentammo = 0;
  641. self.weaponmodel = "progs/v_axe.mdl";
  642. self.weaponframe = 0;
  643. }
  644. //ZOID--
  645. else if (self.weapon == IT_GRAPPLE)
  646. {
  647. self.currentammo = 0;
  648. self.weaponmodel = "progs/v_grpple.mdl";
  649. self.weaponframe = 0;
  650. }
  651. //--ZOID
  652. else if (self.weapon == IT_SHOTGUN)
  653. {
  654. self.currentammo = self.ammo_shells1;
  655. self.weaponmodel = "progs/v_shot.mdl";
  656. self.weaponframe = 0;
  657. self.items = self.items | IT_SHELLS;
  658. }
  659. else if (self.weapon == IT_SUPER_SHOTGUN)
  660. {
  661. self.currentammo = self.ammo_shells1;
  662. self.weaponmodel = "progs/v_shot2.mdl";
  663. self.weaponframe = 0;
  664. self.items = self.items | IT_SHELLS;
  665. }
  666. else if (self.weapon == IT_LAVA_NAILGUN)
  667. {
  668. self.currentammo = self.ammo_lava_nails;
  669. self.weaponmodel = "progs/v_lava.mdl";
  670. self.weaponframe = 0;
  671. self.items2 = self.items2 | IT2_LAVA_NAILS;
  672. }
  673. else if (self.weapon == IT_LAVA_SUPER_NAILGUN)
  674. {
  675. self.currentammo = self.ammo_lava_nails;
  676. self.weaponmodel = "progs/v_lava2.mdl";
  677. self.weaponframe = 0;
  678. self.items2 = self.items2 | IT2_LAVA_NAILS;
  679. }
  680. else if (self.weapon == IT_MULTI_GRENADE)
  681. {
  682. self.currentammo = self.ammo_multi_rockets;
  683. self.weaponmodel = "progs/v_multi.mdl";
  684. self.weaponframe = 0;
  685. self.items2 = self.items2 | IT2_MULTI_ROCKETS;
  686. }
  687. else if (self.weapon == IT_MULTI_ROCKET)
  688. {
  689. self.currentammo = self.ammo_multi_rockets;
  690. self.weaponmodel = "progs/v_multi2.mdl";
  691. self.weaponframe = 0;
  692. self.items2 = self.items2 | IT2_MULTI_ROCKETS;
  693. }
  694. else if (self.weapon == IT_PLASMA_GUN)
  695. {
  696. self.currentammo = self.ammo_plasma;
  697. self.weaponmodel = "progs/v_plasma.mdl";
  698. self.weaponframe = 0;
  699. self.items2 = self.items2 | IT2_PLASMA_AMMO;
  700. }
  701. else if (self.weapon == IT_NAILGUN)
  702. {
  703. self.currentammo = self.ammo_nails1;
  704. self.weaponmodel = "progs/v_nail.mdl";
  705. self.weaponframe = 0;
  706. self.items = self.items | IT_NAILS;
  707. }
  708. else if (self.weapon == IT_SUPER_NAILGUN)
  709. {
  710. self.currentammo = self.ammo_nails1;
  711. self.weaponmodel = "progs/v_nail2.mdl";
  712. self.weaponframe = 0;
  713. self.items = self.items | IT_NAILS;
  714. }
  715. else if (self.weapon == IT_GRENADE_LAUNCHER)
  716. {
  717. self.currentammo = self.ammo_rockets1;
  718. self.weaponmodel = "progs/v_rock.mdl";
  719. self.weaponframe = 0;
  720. self.items = self.items | IT_ROCKETS;
  721. }
  722. else if (self.weapon == IT_ROCKET_LAUNCHER)
  723. {
  724. self.currentammo = self.ammo_rockets1;
  725. self.weaponmodel = "progs/v_rock2.mdl";
  726. self.weaponframe = 0;
  727. self.items = self.items | IT_ROCKETS;
  728. }
  729. else if (self.weapon == IT_LIGHTNING)
  730. {
  731. self.currentammo = self.ammo_cells1;
  732. self.weaponmodel = "progs/v_light.mdl";
  733. self.weaponframe = 0;
  734. self.items = self.items | IT_CELLS;
  735. }
  736. else
  737. {
  738. self.currentammo = 0;
  739. self.weaponmodel = "";
  740. self.weaponframe = 0;
  741. }
  742. UpdateAmmoCounts(self);
  743. };
  744. float() W_BestWeapon =
  745. {
  746. local float it;
  747. it = self.items;
  748. // pgm - fix for sandy. will not change to plasma gun
  749. // if(self.waterlevel <= 1 && self.ammo_plasma >= 1 && (it & IT_PLASMA_GUN))
  750. // return IT_PLASMA_GUN;
  751. // else
  752. if(self.waterlevel<=1 && self.ammo_cells1>=1 && (it & IT_LIGHTNING))
  753. return IT_LIGHTNING;
  754. else if(self.ammo_lava_nails >= 2 && (it & IT_LAVA_SUPER_NAILGUN) )
  755. return IT_LAVA_SUPER_NAILGUN;
  756. else if(self.ammo_nails1 >= 2 && (it & IT_SUPER_NAILGUN) )
  757. return IT_SUPER_NAILGUN;
  758. else if(self.ammo_lava_nails >= 1 && (it & IT_LAVA_NAILGUN) )
  759. return IT_LAVA_NAILGUN;
  760. else if(self.ammo_nails1 >= 1 && (it & IT_NAILGUN) )
  761. return IT_NAILGUN;
  762. else if(self.ammo_shells1 >= 2 && (it & IT_SUPER_SHOTGUN) )
  763. return IT_SUPER_SHOTGUN;
  764. else if(self.ammo_shells1 >= 1 && (it & IT_SHOTGUN) )
  765. return IT_SHOTGUN;
  766. return IT_AXE;
  767. };
  768. float(entity playerEnt, float old, float new) W_WantsToChangeWeapon =
  769. {
  770. float playerFlags = CheckPlayerEXFlags(playerEnt);
  771. if((playerFlags & PEF_CHANGENEVER) != 0)
  772. {
  773. return 0;
  774. }
  775. if(((playerFlags & PEF_CHANGEONLYNEW) != 0) && old == new)
  776. {
  777. return 0;
  778. }
  779. return 1;
  780. };
  781. float() W_CheckNoAmmo =
  782. {
  783. if (self.currentammo > 0)
  784. return TRUE;
  785. //ZOID--
  786. if (self.weapon == IT_AXE || self.weapon == IT_GRAPPLE)
  787. return TRUE;
  788. //--ZOID
  789. self.weapon = W_BestWeapon ();
  790. W_SetCurrentAmmo ();
  791. // drop the weapon down
  792. return FALSE;
  793. };
  794. /*
  795. ============
  796. W_Attack
  797. An attack impulse can be triggered now
  798. ============
  799. */
  800. void() player_axe1;
  801. void() player_axeb1;
  802. void() player_axec1;
  803. void() player_axed1;
  804. void() player_shot1;
  805. void() player_nail1;
  806. void() player_light1;
  807. void() player_rocket1;
  808. void() player_lava_nail1;
  809. //ZOID--
  810. void() player_grapple1;
  811. void() player_grapple3;
  812. //--ZOID
  813. void() W_FireMultiGrenade;
  814. void() W_FireMultiRocket;
  815. void() W_Attack =
  816. {
  817. local float r;
  818. if (!W_CheckNoAmmo ())
  819. return;
  820. makevectors (self.v_angle); // calculate forward angle for velocity
  821. self.show_hostile = time + 1; // wake monsters up
  822. // ZOID--
  823. RuneApplyBlackNoise(self); // make rune noise
  824. //--ZOID
  825. if (self.weapon == IT_AXE)
  826. {
  827. sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  828. r = random();
  829. if (r < 0.25)
  830. player_axe1 ();
  831. else if (r<0.5)
  832. player_axeb1 ();
  833. else if (r<0.75)
  834. player_axec1 ();
  835. else
  836. player_axed1 ();
  837. self.attack_finished = time + RuneApplyHell(0.5, self);
  838. }
  839. //ZOID--
  840. else if (self.weapon == IT_GRAPPLE)
  841. {
  842. if (!self.hook_out)
  843. player_grapple1();
  844. else
  845. player_grapple3();
  846. self.attack_finished = time + 0.1;
  847. }
  848. //--ZOID
  849. else if (self.weapon == IT_SHOTGUN)
  850. {
  851. player_shot1 ();
  852. W_FireShotgun ();
  853. self.attack_finished = time + RuneApplyHell(0.5, self);
  854. }
  855. else if (self.weapon == IT_SUPER_SHOTGUN)
  856. {
  857. player_shot1 ();
  858. W_FireSuperShotgun ();
  859. self.attack_finished = time + RuneApplyHell(0.7, self);
  860. }
  861. else if (self.weapon == IT_LAVA_NAILGUN)
  862. {
  863. lavaGunFired = 1;
  864. player_lava_nail1 ();
  865. }
  866. else if (self.weapon == IT_LAVA_SUPER_NAILGUN)
  867. {
  868. lavaGunFired = 1;
  869. player_lava_nail1 ();
  870. }
  871. else if (self.weapon == IT_MULTI_GRENADE)
  872. {
  873. player_rocket1();
  874. W_FireMultiGrenade();
  875. self.attack_finished = time + RuneApplyHell(0.6, self);
  876. }
  877. else if (self.weapon == IT_MULTI_ROCKET)
  878. {
  879. player_rocket1();
  880. W_FireMultiRocket();
  881. self.attack_finished = time + RuneApplyHell(0.8, self);
  882. }
  883. else if (self.weapon == IT_PLASMA_GUN)
  884. {
  885. // player_light1 determines choice of W_FireLightning
  886. // or W_FirePlasma, but same lighting and frames...
  887. self.attack_finished = time + RuneApplyHell(1.0, self);
  888. player_light1 ();
  889. }
  890. else if (self.weapon == IT_NAILGUN)
  891. {
  892. player_nail1 ();
  893. }
  894. else if (self.weapon == IT_SUPER_NAILGUN)
  895. {
  896. player_nail1 ();
  897. }
  898. else if (self.weapon == IT_GRENADE_LAUNCHER)
  899. {
  900. player_rocket1();
  901. W_FireGrenade();
  902. self.attack_finished = time + RuneApplyHell(0.6, self);
  903. }
  904. else if (self.weapon == IT_ROCKET_LAUNCHER)
  905. {
  906. player_rocket1();
  907. W_FireRocket();
  908. self.attack_finished = time + RuneApplyHell(0.8, self);
  909. }
  910. else if (self.weapon == IT_LIGHTNING)
  911. {
  912. player_light1();
  913. self.attack_finished = time + 0.1;
  914. sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  915. }
  916. };
  917. /*
  918. ============
  919. W_ChangeWeapon
  920. ============
  921. */
  922. void() W_ChangeWeapon =
  923. {
  924. local float it, am, fl;
  925. EnableComboWeapons ( self );
  926. UpdateAmmoCounts ( self );
  927. it = self.items;
  928. am = 0;
  929. if (self.impulse == 1)
  930. {
  931. //ZOID--
  932. if (self.weapon == IT_AXE && deathmatch && teamplay >= TEAM_CTF)
  933. fl = IT_GRAPPLE;
  934. else
  935. fl = IT_AXE;
  936. }
  937. else if (self.impulse == 22)
  938. {
  939. if(deathmatch && teamplay >= TEAM_CTF) //pgm optimization
  940. fl = IT_GRAPPLE;
  941. }
  942. //--ZOID
  943. else if (self.impulse == 2)
  944. {
  945. fl = IT_SHOTGUN;
  946. if (self.ammo_shells1 < 1)
  947. am = 1;
  948. }
  949. else if (self.impulse == 3)
  950. {
  951. fl = IT_SUPER_SHOTGUN;
  952. if (self.ammo_shells1 < 2)
  953. am = 1;
  954. }
  955. else if (self.impulse == 4)
  956. {
  957. if ((self.items & IT_LAVA_NAILGUN) &&
  958. (self.weapon == IT_NAILGUN || self.ammo_nails1 < 1))
  959. {
  960. fl = IT_LAVA_NAILGUN;
  961. if (self.ammo_lava_nails < 1)
  962. am = 1;
  963. }
  964. else
  965. {
  966. fl = IT_NAILGUN;
  967. if (self.ammo_nails1 < 1)
  968. am = 1;
  969. }
  970. }
  971. else if (self.impulse == 5)
  972. {
  973. if ((self.items & IT_LAVA_SUPER_NAILGUN) &&
  974. (self.weapon == IT_SUPER_NAILGUN || self.ammo_nails1 < 2))
  975. {
  976. fl = IT_LAVA_SUPER_NAILGUN;
  977. if (self.ammo_lava_nails < 2)
  978. am = 1;
  979. }
  980. else
  981. {
  982. fl = IT_SUPER_NAILGUN;
  983. if (self.ammo_nails1 < 2)
  984. am = 1;
  985. }
  986. }
  987. else if (self.impulse == 6)
  988. {
  989. if ((self.items & IT_MULTI_GRENADE) &&
  990. (self.weapon == IT_GRENADE_LAUNCHER || self.ammo_rockets1 < 1))
  991. {
  992. fl = IT_MULTI_GRENADE;
  993. if (self.ammo_multi_rockets < 1)
  994. am = 1;
  995. }
  996. else
  997. {
  998. fl = IT_GRENADE_LAUNCHER;
  999. if (self.ammo_rockets1 < 1)
  1000. am = 1;
  1001. }
  1002. }
  1003. else if (self.impulse == 7)
  1004. {
  1005. if ((self.items & IT_MULTI_ROCKET) &&
  1006. (self.weapon == IT_ROCKET_LAUNCHER || self.ammo_rockets1 < 1))
  1007. {
  1008. fl = IT_MULTI_ROCKET;
  1009. if (self.ammo_multi_rockets < 1)
  1010. am = 1;
  1011. }
  1012. else
  1013. {
  1014. fl = IT_ROCKET_LAUNCHER;
  1015. if (self.ammo_rockets1 < 1)
  1016. am = 1;
  1017. }
  1018. }
  1019. else if (self.impulse == 8)
  1020. {
  1021. if ((self.items & IT_PLASMA_GUN) &&
  1022. (self.weapon == IT_LIGHTNING || self.ammo_cells1 < 1))
  1023. {
  1024. fl = IT_PLASMA_GUN;
  1025. if (self.ammo_plasma < 1)
  1026. am = 1;
  1027. }
  1028. else
  1029. {
  1030. fl = IT_LIGHTNING;
  1031. if (self.ammo_cells1 < 1)
  1032. am = 1;
  1033. }
  1034. }
  1035. else if (self.impulse == 60)
  1036. {
  1037. fl = IT_LAVA_NAILGUN;
  1038. if (self.ammo_lava_nails < 1)
  1039. am = 1;
  1040. }
  1041. else if (self.impulse == 61)
  1042. {
  1043. fl = IT_LAVA_SUPER_NAILGUN;
  1044. if (self.ammo_lava_nails < 1)
  1045. am = 1;
  1046. }
  1047. else if (self.impulse == 62)
  1048. {
  1049. fl = IT_MULTI_GRENADE;
  1050. if (self.ammo_multi_rockets < 1)
  1051. am = 1;
  1052. }
  1053. else if (self.impulse == 63)
  1054. {
  1055. fl = IT_MULTI_ROCKET;
  1056. if (self.ammo_multi_rockets < 1)
  1057. am = 1;
  1058. }
  1059. else if (self.impulse == 64)
  1060. {
  1061. fl = IT_PLASMA_GUN;
  1062. if (self.ammo_plasma < 1)
  1063. am = 1;
  1064. }
  1065. else if (self.impulse == 65)
  1066. {
  1067. fl = IT_NAILGUN;
  1068. if (self.ammo_nails < 1)
  1069. am = 1;
  1070. }
  1071. else if (self.impulse == 66)
  1072. {
  1073. fl = IT_SUPER_NAILGUN;
  1074. if (self.ammo_nails < 2)
  1075. am = 1;
  1076. }
  1077. else if (self.impulse == 67)
  1078. {
  1079. fl = IT_GRENADE_LAUNCHER;
  1080. if (self.ammo_rockets < 1)
  1081. am = 1;
  1082. }
  1083. else if (self.impulse == 68)
  1084. {
  1085. fl = IT_ROCKET_LAUNCHER;
  1086. if (self.ammo_rockets < 1)
  1087. am = 1;
  1088. }
  1089. self.impulse = 0;
  1090. if (!(self.items & fl))
  1091. { // don't have the weapon or the ammo
  1092. sprint (self, "$qc_no_weapon");
  1093. return;
  1094. }
  1095. if (am)
  1096. { // don't have the ammo
  1097. sprint (self, "$qc_not_enough_ammo");
  1098. return;
  1099. }
  1100. if (self.weapon != fl)
  1101. {
  1102. if (self.weapon == IT_LAVA_NAILGUN ||
  1103. self.weapon == IT_LAVA_SUPER_NAILGUN)
  1104. {
  1105. if (fl == IT_NAILGUN || fl == IT_SUPER_NAILGUN)
  1106. sprint (self, "$qc_normal_nails");
  1107. }
  1108. else if (self.weapon == IT_MULTI_GRENADE)
  1109. {
  1110. if (fl == IT_GRENADE_LAUNCHER)
  1111. sprint (self, "$qc_normal_grenades");
  1112. }
  1113. else if (self.weapon == IT_MULTI_ROCKET)
  1114. {
  1115. if (fl == IT_ROCKET_LAUNCHER)
  1116. sprint (self, "$qc_normal_rockets");
  1117. }
  1118. else if (self.weapon == IT_PLASMA_GUN)
  1119. {
  1120. if (fl == IT_LIGHTNING)
  1121. sprint (self, "$qc_lightning_gun");
  1122. }
  1123. else if (fl == IT_LAVA_NAILGUN || fl == IT_LAVA_SUPER_NAILGUN)
  1124. {
  1125. sprint (self, "$qc_lava_nails");
  1126. }
  1127. else if(fl == IT_MULTI_GRENADE)
  1128. {
  1129. sprint (self, "$qc_multi_gl");
  1130. }
  1131. else if(fl == IT_MULTI_ROCKET)
  1132. {
  1133. sprint (self, "$qc_multi_rl");
  1134. }
  1135. else if(fl == IT_PLASMA_GUN)
  1136. {
  1137. sprint (self, "$qc_plasma_gun");
  1138. }
  1139. }
  1140. //
  1141. // set weapon, set ammo
  1142. //
  1143. self.weapon = fl;
  1144. W_SetCurrentAmmo ();
  1145. };
  1146. /*
  1147. ============
  1148. CheatCommand
  1149. ============
  1150. */
  1151. void() CheatCommand =
  1152. {
  1153. if ( ( deathmatch || coop ) && cheats_allowed == 0 ) { // mal: allow impulse 9 IF cheats allowed
  1154. return;
  1155. }
  1156. self.ammo_rockets1 = 100;
  1157. self.ammo_nails1 = 200;
  1158. self.ammo_shells1 = 100;
  1159. self.items = self.items |
  1160. IT_AXE |
  1161. IT_SHOTGUN |
  1162. IT_SUPER_SHOTGUN |
  1163. IT_NAILGUN |
  1164. IT_SUPER_NAILGUN |
  1165. IT_GRENADE_LAUNCHER |
  1166. IT_ROCKET_LAUNCHER |
  1167. IT_LAVA_NAILGUN |
  1168. IT_LAVA_SUPER_NAILGUN |
  1169. IT_MULTI_GRENADE |
  1170. IT_MULTI_ROCKET |
  1171. IT_PLASMA_GUN |
  1172. IT_LIGHTNING;
  1173. self.items = self.items | IT_KEY1 | IT_KEY2;
  1174. self.ammo_lava_nails = 200;
  1175. self.ammo_multi_rockets = 100;
  1176. self.ammo_plasma = 100;
  1177. self.ammo_cells1 = 200;
  1178. self.weapon = IT_ROCKET_LAUNCHER;
  1179. self.impulse = 0;
  1180. W_SetCurrentAmmo ();
  1181. };
  1182. /*
  1183. ============
  1184. CycleWeaponCommand
  1185. Go to the next weapon with ammo
  1186. ============
  1187. */
  1188. void() CycleWeaponCommand =
  1189. {
  1190. local float it, am;
  1191. EnableComboWeapons ( self );
  1192. UpdateAmmoCounts ( self );
  1193. it = self.items;
  1194. self.impulse = 0;
  1195. while (1)
  1196. {
  1197. am = 0;
  1198. if (self.weapon == IT_PLASMA_GUN)
  1199. {
  1200. self.weapon = IT_AXE;
  1201. }
  1202. else if (self.weapon == IT_AXE)
  1203. {
  1204. //ZOID--
  1205. if (deathmatch && teamplay >= TEAM_CTF)
  1206. self.weapon = IT_GRAPPLE;
  1207. else
  1208. {
  1209. self.weapon = IT_SHOTGUN;
  1210. if (self.ammo_shells1 < 1)
  1211. am = 1;
  1212. }
  1213. //--ZOID
  1214. }
  1215. else if (self.weapon == IT_GRAPPLE)
  1216. {
  1217. self.weapon = IT_SHOTGUN;
  1218. if (self.ammo_shells1 < 1)
  1219. am = 1;
  1220. }
  1221. //--ZOID
  1222. else if (self.weapon == IT_SHOTGUN)
  1223. {
  1224. self.weapon = IT_SUPER_SHOTGUN;
  1225. if (self.ammo_shells1 < 2)
  1226. am = 1;
  1227. }
  1228. else if (self.weapon == IT_SUPER_SHOTGUN)
  1229. {
  1230. self.weapon = IT_NAILGUN;
  1231. if (self.ammo_nails1 < 1)
  1232. am = 1;
  1233. }
  1234. else if (self.weapon == IT_NAILGUN)
  1235. {
  1236. self.weapon = IT_LAVA_NAILGUN;
  1237. if (self.ammo_lava_nails < 1)
  1238. am = 1;
  1239. }
  1240. else if (self.weapon == IT_LAVA_NAILGUN)
  1241. {
  1242. self.weapon = IT_SUPER_NAILGUN;
  1243. if (self.ammo_nails1 < 2)
  1244. am = 1;
  1245. }
  1246. else if (self.weapon == IT_SUPER_NAILGUN)
  1247. {
  1248. self.weapon = IT_LAVA_SUPER_NAILGUN;
  1249. if (self.ammo_lava_nails < 2)
  1250. am = 1;
  1251. }
  1252. else if (self.weapon == IT_LAVA_SUPER_NAILGUN)
  1253. {
  1254. self.weapon = IT_GRENADE_LAUNCHER;
  1255. if (self.ammo_rockets1 < 1)
  1256. am = 1;
  1257. }
  1258. else if (self.weapon == IT_GRENADE_LAUNCHER)
  1259. {
  1260. self.weapon = IT_MULTI_GRENADE;
  1261. if (self.ammo_multi_rockets < 1)
  1262. am = 1;
  1263. }
  1264. else if (self.weapon == IT_MULTI_GRENADE)
  1265. {
  1266. self.weapon = IT_ROCKET_LAUNCHER;
  1267. if (self.ammo_rockets1 < 1)
  1268. am = 1;
  1269. }
  1270. else if (self.weapon == IT_ROCKET_LAUNCHER)
  1271. {
  1272. self.weapon = IT_MULTI_ROCKET;
  1273. if (self.ammo_multi_rockets < 1)
  1274. am = 1;
  1275. }
  1276. else if (self.weapon == IT_MULTI_ROCKET)
  1277. {
  1278. self.weapon = IT_LIGHTNING;
  1279. if (self.ammo_cells1 < 1)
  1280. am = 1;
  1281. }
  1282. else if (self.weapon == IT_LIGHTNING)
  1283. {
  1284. self.weapon = IT_PLASMA_GUN;
  1285. if (self.ammo_plasma < 1)
  1286. am = 1;
  1287. }
  1288. if ( (it & self.weapon) && am == 0)
  1289. {
  1290. W_SetCurrentAmmo ();
  1291. return;
  1292. }
  1293. }
  1294. };
  1295. /*
  1296. ============
  1297. CycleWeaponReverseCommand
  1298. Go to the prev weapon with ammo
  1299. ============
  1300. */
  1301. void() CycleWeaponReverseCommand =
  1302. {
  1303. local float it, am;
  1304. EnableComboWeapons ( self );
  1305. UpdateAmmoCounts ( self );
  1306. it = self.items;
  1307. self.impulse = 0;
  1308. while (1)
  1309. {
  1310. am = 0;
  1311. if (self.weapon == IT_PLASMA_GUN)
  1312. {
  1313. self.weapon = IT_LIGHTNING;
  1314. if (self.ammo_cells1 < 1)
  1315. am = 1;
  1316. }
  1317. else if (self.weapon == IT_LIGHTNING)
  1318. {
  1319. self.weapon = IT_MULTI_ROCKET;
  1320. if (self.ammo_multi_rockets < 1)
  1321. am = 1;
  1322. }
  1323. else if (self.weapon == IT_MULTI_ROCKET)
  1324. {
  1325. self.weapon = IT_ROCKET_LAUNCHER;
  1326. if (self.ammo_rockets1 < 1)
  1327. am = 1;
  1328. }
  1329. else if (self.weapon == IT_ROCKET_LAUNCHER)
  1330. {
  1331. self.weapon = IT_MULTI_GRENADE;
  1332. if (self.ammo_multi_rockets < 1)
  1333. am = 1;
  1334. }
  1335. else if (self.weapon == IT_MULTI_GRENADE)
  1336. {
  1337. self.weapon = IT_GRENADE_LAUNCHER;
  1338. if (self.ammo_rockets1 < 1)
  1339. am = 1;
  1340. }
  1341. else if (self.weapon == IT_GRENADE_LAUNCHER)
  1342. {
  1343. self.weapon = IT_LAVA_SUPER_NAILGUN;
  1344. if (self.ammo_lava_nails < 2)
  1345. am = 1;
  1346. }
  1347. else if (self.weapon == IT_LAVA_SUPER_NAILGUN)
  1348. {
  1349. self.weapon = IT_SUPER_NAILGUN;
  1350. if (self.ammo_nails1 < 2)
  1351. am = 1;
  1352. }
  1353. else if (self.weapon == IT_SUPER_NAILGUN)
  1354. {
  1355. self.weapon = IT_LAVA_NAILGUN;
  1356. if (self.ammo_lava_nails < 2)
  1357. am = 1;
  1358. }
  1359. else if (self.weapon == IT_LAVA_NAILGUN)
  1360. {
  1361. self.weapon = IT_NAILGUN;
  1362. if (self.ammo_nails1 < 1)
  1363. am = 1;
  1364. }
  1365. else if (self.weapon == IT_NAILGUN)
  1366. {
  1367. self.weapon = IT_SUPER_SHOTGUN;
  1368. if (self.ammo_shells1 < 2)
  1369. am = 1;
  1370. }
  1371. else if (self.weapon == IT_SUPER_SHOTGUN)
  1372. {
  1373. self.weapon = IT_SHOTGUN;
  1374. if (self.ammo_shells1 < 1)
  1375. am = 1;
  1376. }
  1377. else if (self.weapon == IT_SHOTGUN)
  1378. {
  1379. //PGM
  1380. if (deathmatch && teamplay >= TEAM_CTF)
  1381. self.weapon = IT_GRAPPLE;
  1382. else
  1383. self.weapon = IT_AXE;
  1384. //PGM
  1385. }
  1386. //ZOID--
  1387. else if (self.weapon == IT_GRAPPLE)
  1388. {
  1389. self.weapon = IT_AXE;
  1390. }
  1391. //--ZOID
  1392. else if (self.weapon == IT_AXE)
  1393. {
  1394. self.weapon = IT_PLASMA_GUN;
  1395. if (self.ammo_plasma < 1)
  1396. am = 1;
  1397. }
  1398. if ( (it & self.weapon) && am == 0)
  1399. {
  1400. W_SetCurrentAmmo ();
  1401. return;
  1402. }
  1403. }
  1404. };
  1405. /*
  1406. ============
  1407. ServerflagsCommand
  1408. Just for development
  1409. ============
  1410. */
  1411. void() ServerflagsCommand =
  1412. {
  1413. serverflags = serverflags * 2 + 1;
  1414. };
  1415. void() QuadCheat =
  1416. {
  1417. if (deathmatch || coop)
  1418. return;
  1419. self.super_time = 1;
  1420. self.super_damage_finished = time + 30;
  1421. self.items = self.items | IT_QUAD;
  1422. dprint ("$qc_quad_cheat");
  1423. };
  1424. /*
  1425. ============
  1426. ImpulseCommands
  1427. ============
  1428. */
  1429. void() ImpulseCommands =
  1430. {
  1431. local entity takeThisOut;
  1432. if (self.impulse >= 1 && self.impulse <= 8)
  1433. W_ChangeWeapon ();
  1434. else if (self.impulse >= 60 && self.impulse <= 68)
  1435. W_ChangeWeapon ();
  1436. else if (self.impulse == 9)
  1437. CheatCommand ();
  1438. else if (self.impulse == 10)
  1439. CycleWeaponCommand ();
  1440. else if (self.impulse == 11)
  1441. ServerflagsCommand ();
  1442. else if (self.impulse == 12)
  1443. CycleWeaponReverseCommand ();
  1444. //ZOID--
  1445. //teamplay stuff
  1446. else if (self.impulse == 20)
  1447. TossBackpack();
  1448. else if (self.impulse == 21)
  1449. TossWeapon();
  1450. else if (self.impulse == 22)
  1451. {
  1452. if (deathmatch && teamplay >= TEAM_CTF)
  1453. W_ChangeWeapon();
  1454. }
  1455. else if (self.impulse == 23)
  1456. TeamFlagStatusReport();
  1457. //--ZOID
  1458. else if (self.impulse == 255)
  1459. QuadCheat ();
  1460. self.impulse = 0;
  1461. };
  1462. /*
  1463. ============
  1464. W_WeaponFrame
  1465. Called every frame so impulse events can be handled as well as possible
  1466. ============
  1467. */
  1468. void() W_WeaponFrame =
  1469. {
  1470. if (time < self.attack_finished)
  1471. return;
  1472. if (lavaGunFired)
  1473. {
  1474. if (self.weapon == IT_LAVA_NAILGUN ||
  1475. self.weapon == IT_LAVA_SUPER_NAILGUN)
  1476. {
  1477. sound (self, CHAN_WEAPON, "lavagun/snail.wav", 1, ATTN_NORM);
  1478. }
  1479. lavaGunFired = 0;
  1480. }
  1481. if (self.impulse)
  1482. ImpulseCommands ();
  1483. // check for attack
  1484. if (self.button0)
  1485. {
  1486. SuperDamageSound ();
  1487. W_Attack ();
  1488. }
  1489. };
  1490. /*
  1491. ========
  1492. SuperDamageSound
  1493. Plays sound if needed
  1494. ========
  1495. */
  1496. void() SuperDamageSound =
  1497. {
  1498. if (self.super_damage_finished > time)
  1499. {
  1500. if (self.super_sound < time)
  1501. {
  1502. self.super_sound = time + 1;
  1503. sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  1504. }
  1505. }
  1506. return;
  1507. };