weapons.qc 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332
  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. //JIM
  18. void( vector pos ) placebullethole;
  19. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  20. void () player_run;
  21. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  22. void(vector org, vector vel, float damage) SpawnBlood;
  23. void() SuperDamageSound;
  24. //MED 10/18/96
  25. void(float damage) spawn_touchblood;
  26. /*
  27. ================
  28. HIPNOTIC WEAPONS
  29. ================
  30. */
  31. void() HIP_LaserTouch =
  32. {
  33. local vector org;
  34. local vector spot1,spot2;
  35. local vector oldvel;
  36. local float mag;
  37. local float r;
  38. self.owner = world;
  39. self.cnt = self.cnt + 1;
  40. if (pointcontents(self.origin) == CONTENT_SKY)
  41. {
  42. remove(self);
  43. return;
  44. }
  45. oldvel = normalize(self.old_velocity);
  46. spot1 = self.origin - (16*oldvel);
  47. spot2 = self.origin + (16*oldvel);
  48. traceline (spot1, spot2, FALSE, self); // see through other monsters
  49. self.origin = trace_endpos;
  50. org = self.origin;
  51. if (other.health)
  52. {
  53. if (self.lastvictim == other)
  54. {
  55. self.dmg = self.dmg / 2;
  56. }
  57. spawn_touchblood (self.dmg);
  58. T_Damage (other, self, self.lastvictim, self.dmg);
  59. }
  60. else if ((self.cnt == 3) || (random()<0.15))
  61. {
  62. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  63. WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  64. WriteCoord (MSG_BROADCAST, org_x);
  65. WriteCoord (MSG_BROADCAST, org_y);
  66. WriteCoord (MSG_BROADCAST, org_z);
  67. }
  68. else
  69. {
  70. // self.dmg = 0.66 * self.dmg;
  71. self.dmg = 0.9 * self.dmg;
  72. // self.speed = 0.95 * self.speed;
  73. self.velocity = oldvel+(2*trace_plane_normal);
  74. self.velocity = normalize(self.velocity);
  75. self.velocity = self.speed * self.velocity;
  76. self.old_velocity = self.velocity;
  77. if (self.flags & FL_ONGROUND)
  78. self.flags = self.flags - FL_ONGROUND;
  79. r = random();
  80. sound (self, CHAN_WEAPON, "hipweap/laserric.wav", 1, ATTN_STATIC);
  81. /*
  82. if (r<0.33)
  83. sound (self, CHAN_WEAPON, "weapons/ric1.wav", 1, ATTN_STATIC);
  84. else if (r<0.66)
  85. sound (self, CHAN_WEAPON, "weapons/ric2.wav", 1, ATTN_STATIC);
  86. else
  87. sound (self, CHAN_WEAPON, "weapons/ric3.wav", 1, ATTN_STATIC);
  88. */
  89. return;
  90. }
  91. sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
  92. remove(self);
  93. };
  94. void() HIP_LaserThink =
  95. {
  96. local float delta;
  97. if (time>self.attack_finished)
  98. {
  99. remove(self);
  100. return;
  101. }
  102. if (self.flags & FL_ONGROUND)
  103. self.flags = self.flags - FL_ONGROUND;
  104. self.velocity = self.old_velocity;
  105. self.angles = vectoangles(self.velocity);
  106. self.nextthink = time+0.1;
  107. };
  108. void(vector org, vector vec, float light) HIP_LaunchLaser =
  109. {
  110. // sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
  111. sound (self ,CHAN_WEAPON, "hipweap/laserg.wav", 1, ATTN_NORM);
  112. vec = normalize(vec);
  113. newmis = spawn();
  114. newmis.owner = self;
  115. newmis.classname = "hiplaser";
  116. newmis.lastvictim = self;
  117. newmis.movetype = MOVETYPE_FLYMISSILE;
  118. newmis.solid = SOLID_BBOX;
  119. if (light)
  120. newmis.effects = EF_DIMLIGHT;
  121. setmodel (newmis, "progs/lasrspik.mdl");
  122. setsize (newmis, '0 0 0', '0 0 0');
  123. setorigin (newmis, org);
  124. newmis.speed = 1000;
  125. newmis.dmg = 18;
  126. newmis.velocity = vec * newmis.speed;
  127. newmis.old_velocity = newmis.velocity;
  128. newmis.angles = vectoangles(newmis.velocity);
  129. newmis.avelocity = '0 0 400';
  130. newmis.nextthink = time;
  131. newmis.attack_finished = time + 5;
  132. newmis.think = HIP_LaserThink;
  133. newmis.touch = HIP_LaserTouch;
  134. newmis.count = 0;
  135. };
  136. /*
  137. =================
  138. HIP_FireLaser
  139. =================
  140. */
  141. void(float stat) HIP_FireLaser =
  142. {
  143. local vector org;
  144. local vector dir;
  145. local vector out;
  146. local float ofs;
  147. local float aofs;
  148. if (!self.button0)
  149. {
  150. player_run ();
  151. return;
  152. }
  153. if (self.ammo_cells < 1)
  154. {
  155. self.weapon = W_BestWeapon ();
  156. W_SetCurrentAmmo ();
  157. return;
  158. }
  159. SuperDamageSound();
  160. self.effects = self.effects | EF_MUZZLEFLASH;
  161. makevectors (self.v_angle);
  162. ofs = 6;
  163. out = v_forward;
  164. out_z = 0;
  165. out = normalize(out);
  166. org = self.origin + ((12-ofs) * v_up) + (12*out);
  167. // org = self.origin + (1*v_forward);
  168. dir = aim (self, 1000);
  169. aofs = ofs * 0.707;
  170. if (stat == 0)
  171. {
  172. self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  173. org = org + (aofs*v_right);
  174. org = org - (aofs*v_up);
  175. HIP_LaunchLaser(org, dir, 0);
  176. org = org - (2*aofs*v_right);
  177. HIP_LaunchLaser(org, dir, 0);
  178. }
  179. else if (stat == 1)
  180. {
  181. self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  182. org = org + (ofs*v_up);
  183. if (random()<0.1)
  184. {
  185. HIP_LaunchLaser(org, dir, 1);
  186. newmis.dmg = 25;
  187. }
  188. else
  189. HIP_LaunchLaser(org, dir, 0);
  190. }
  191. self.punchangle_x = -1;
  192. };
  193. /*
  194. =================
  195. HIP_HammerDamage
  196. =================
  197. */
  198. void(vector p1, vector p2, entity from, float damage) HIP_HammerDamage =
  199. {
  200. local entity e1, e2;
  201. local vector f;
  202. f = p2 - p1;
  203. normalize (f);
  204. f_x = 0 - f_y;
  205. f_y = f_x;
  206. f_z = 0;
  207. f = f*16;
  208. e1 = e2 = world;
  209. traceline (p1, p2, FALSE, self);
  210. //JIM
  211. if (trace_ent.takedamage && !trace_ent.wetsuit_finished )
  212. {
  213. particle (trace_endpos, '0 0 100', 225, damage*4);
  214. T_Damage (trace_ent, from, from, damage);
  215. if (self.classname == "player")
  216. {
  217. if (other.classname == "player")
  218. trace_ent.velocity_z = trace_ent.velocity_z + 400;
  219. }
  220. }
  221. e1 = trace_ent;
  222. traceline (p1 + f, p2 + f, FALSE, self);
  223. //JIM
  224. if (trace_ent != e1 && trace_ent.takedamage &&
  225. !trace_ent.wetsuit_finished )
  226. {
  227. particle (trace_endpos, '0 0 100', 225, damage*4);
  228. T_Damage (trace_ent, from, from, damage);
  229. }
  230. e2 = trace_ent;
  231. traceline (p1 - f, p2 - f, FALSE, self);
  232. //JIM
  233. if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage &&
  234. !trace_ent.wetsuit_finished )
  235. {
  236. particle (trace_endpos, '0 0 100', 225, damage*4);
  237. T_Damage (trace_ent, from, from, damage);
  238. }
  239. };
  240. /*
  241. void() HIP_DiversionLightningThink =
  242. {
  243. local vector org,end;
  244. if (time > self.delay)
  245. {
  246. remove(self);
  247. return;
  248. }
  249. makevectors(self.v_angle);
  250. org = self.origin;
  251. end = org + v_forward*200;
  252. // end = end + (((200*random()) - 100) * v_up);
  253. end = end + (((400*random()) - 200) * v_right);
  254. traceline (org, end, TRUE, self);
  255. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  256. WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  257. WriteEntity (MSG_BROADCAST, self);
  258. WriteCoord (MSG_BROADCAST, org_x);
  259. WriteCoord (MSG_BROADCAST, org_y);
  260. WriteCoord (MSG_BROADCAST, org_z);
  261. WriteCoord (MSG_BROADCAST, trace_endpos_x);
  262. WriteCoord (MSG_BROADCAST, trace_endpos_y);
  263. WriteCoord (MSG_BROADCAST, trace_endpos_z);
  264. self.nextthink = time + 0.1;
  265. };
  266. */
  267. //void(entity prev, entity owner, float dst) HIP_SpawnMjolnirLightning;
  268. void() HIP_LightningThink =
  269. {
  270. local vector org;
  271. local vector dst;
  272. local entity head;
  273. local entity selected;
  274. local float cur_dist;
  275. local float head_dist;
  276. local vector vec;
  277. local float dot;
  278. local float oldstate;
  279. local float dam;
  280. if (time > self.delay)
  281. {
  282. if (self.enemy != world)
  283. self.enemy.struck_by_mjolnir = 0;
  284. remove(self);
  285. return;
  286. }
  287. oldstate = self.state;
  288. if (self.state==0)
  289. {
  290. // look in our immediate vicinity
  291. self.enemy = world;
  292. selected = world;
  293. cur_dist = self.distance;
  294. head = findradius(self.owner.origin, self.distance);
  295. while(head)
  296. {
  297. if(!(head.flags & FL_NOTARGET) && ((head.flags & FL_MONSTER) || (head.flags & FL_CLIENT)))
  298. {
  299. // if (visible(head) && (head!=self.owner.owner) && (head.health>0))
  300. if ((visible(head)) && (head!=self.owner.owner) && (head.health>0))
  301. {
  302. head_dist = vlen(head.origin - self.lastvictim.origin);
  303. if ((head_dist<cur_dist) && (head.struck_by_mjolnir==0))
  304. {
  305. selected = head;
  306. cur_dist = head_dist;
  307. }
  308. }
  309. }
  310. head = head.chain;
  311. }
  312. if (selected != world)
  313. {
  314. self.state = 1;
  315. self.enemy = selected;
  316. self.enemy.struck_by_mjolnir = 1;
  317. }
  318. else
  319. {
  320. local vector org,end;
  321. makevectors(self.v_angle);
  322. org = self.owner.origin;
  323. end = org + v_forward*200;
  324. end = end + (((400*random()) - 200) * v_right);
  325. traceline (org, end, TRUE, self);
  326. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  327. WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  328. WriteEntity (MSG_BROADCAST, self);
  329. WriteCoord (MSG_BROADCAST, org_x);
  330. WriteCoord (MSG_BROADCAST, org_y);
  331. WriteCoord (MSG_BROADCAST, org_z);
  332. WriteCoord (MSG_BROADCAST, trace_endpos_x);
  333. WriteCoord (MSG_BROADCAST, trace_endpos_y);
  334. WriteCoord (MSG_BROADCAST, trace_endpos_z);
  335. self.nextthink = time + 0.1;
  336. // self.think = HIP_DiversionLightningThink;
  337. // self.nextthink = time;
  338. // self.delay = time + 0.30;
  339. // self.origin = self.owner.origin;
  340. // self.think();
  341. return;
  342. }
  343. }
  344. org = self.lastvictim.origin;
  345. dst = self.enemy.absmin + 0.25*(self.enemy.absmax-self.enemy.absmin);
  346. dst = dst + (random()*0.5*(self.enemy.absmax-self.enemy.absmin));
  347. traceline (org, dst, TRUE, self.owner.owner);
  348. if (trace_fraction != 1.0 || self.enemy.health<=0)
  349. {
  350. self.enemy.struck_by_mjolnir = 0;
  351. self.state = 0;
  352. self.nextthink = time + 0.1;
  353. return;
  354. }
  355. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  356. WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  357. WriteEntity (MSG_BROADCAST, self);
  358. WriteCoord (MSG_BROADCAST, org_x);
  359. WriteCoord (MSG_BROADCAST, org_y);
  360. WriteCoord (MSG_BROADCAST, org_z);
  361. WriteCoord (MSG_BROADCAST, trace_endpos_x);
  362. WriteCoord (MSG_BROADCAST, trace_endpos_y);
  363. WriteCoord (MSG_BROADCAST, trace_endpos_z);
  364. vec = normalize(self.enemy.origin - self.owner.origin);
  365. dot = vec * self.owner.movedir;
  366. head = self;
  367. self = self.owner.owner;
  368. if (oldstate==0)
  369. dam = 80;
  370. else
  371. dam = 30;
  372. if (dot>0.3)
  373. HIP_HammerDamage (org, trace_endpos, self, dam);
  374. else
  375. HIP_HammerDamage (org, trace_endpos, self, dam*0.5);
  376. self = head;
  377. self.nextthink = time + 0.2;
  378. };
  379. void(entity prev, entity own, float dst) HIP_SpawnMjolnirLightning =
  380. {
  381. local entity light;
  382. // spawn actual lightning
  383. light = spawn();
  384. light.delay = time + 0.8;
  385. light.state = 0;
  386. light.lastvictim = prev;
  387. light.distance = dst;
  388. light.owner = own;
  389. light.v_angle = self.angles;
  390. light.v_angle_x = 0;
  391. light.v_angle_z = 0;
  392. light.origin = own.origin;
  393. light.think = HIP_LightningThink;
  394. light.nextthink = time;
  395. };
  396. void() HIP_SpawnMjolnirBase =
  397. {
  398. local entity light;
  399. // spawn lightning base
  400. light = spawn();
  401. // light.origin = self.origin - '0 0 24' + (32*v_forward);
  402. light.origin = trace_endpos;
  403. light.flags = 0;
  404. light.owner = self;
  405. light.struck_by_mjolnir = 1;
  406. light.think = SUB_Remove;
  407. light.nextthink = time + 1;
  408. sound (light, CHAN_AUTO, "hipweap/mjolslap.wav", 1, ATTN_NORM);
  409. sound (light, CHAN_WEAPON, "hipweap/mjolhit.wav", 1, ATTN_NORM);
  410. makevectors(self.v_angle);
  411. light.movedir = v_forward;
  412. HIP_SpawnMjolnirLightning( light, light, 350 );
  413. HIP_SpawnMjolnirLightning( light, light, 350 );
  414. HIP_SpawnMjolnirLightning( light, light, 350 );
  415. HIP_SpawnMjolnirLightning( light, light, 350 );
  416. };
  417. void() HIP_FireMjolnirLightning =
  418. {
  419. local vector org;
  420. local float cells;
  421. // explode if under water
  422. if (self.waterlevel > 1)
  423. {
  424. cells = self.ammo_cells;
  425. self.ammo_cells = 0;
  426. discharged = 1;
  427. T_RadiusDamage (self, self, 35*cells, world);
  428. discharged = 0;
  429. W_SetCurrentAmmo ();
  430. return;
  431. }
  432. // if (self.t_width < time)
  433. // {
  434. // sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  435. // self.t_width = time + 0.6;
  436. // }
  437. // self.punchangle_x = 12;
  438. self.currentammo = self.ammo_cells = self.ammo_cells - 15;
  439. HIP_SpawnMjolnirBase();
  440. };
  441. void() HIP_FireMjolnir =
  442. {
  443. local vector org;
  444. local float cells;
  445. local float damage;
  446. local vector source;
  447. local vector ang;
  448. self.attack_finished = time + 0.4;
  449. source = self.origin + '0 0 16';
  450. // ang = self.angles;
  451. // ang_x = 0;
  452. // ang_y = 0;
  453. makevectors(self.v_angle);
  454. traceline (source, source + v_forward*32, FALSE, self);
  455. if (trace_fraction == 1.0 && (self.ammo_cells >= 15))
  456. {
  457. source = source + v_forward*32;
  458. traceline (source , source - v_up*50, FALSE, self);
  459. // dprint("fraction = ");
  460. // dprint(ftos(trace_fraction));
  461. // dprint("\n");
  462. if (trace_fraction > 0.3 && trace_fraction< 1.0)
  463. {
  464. HIP_FireMjolnirLightning();
  465. self.attack_finished = time + 1.5;
  466. return;
  467. }
  468. }
  469. org = trace_endpos - v_forward*4;
  470. if (trace_ent.takedamage)
  471. {
  472. damage = 50;
  473. if (trace_ent.classname == "monster_zombie")
  474. damage = 70;
  475. trace_ent.axhitme = 1;
  476. SpawnBlood (org, v_forward, damage);
  477. T_Damage (trace_ent, self, self, damage);
  478. }
  479. else
  480. { // hit wall
  481. if (trace_fraction != 1.0)
  482. {
  483. // sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  484. sound (self, CHAN_WEAPON, "hipweap/mjoltink.wav", 1, ATTN_NORM);
  485. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  486. WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  487. WriteCoord (MSG_BROADCAST, org_x);
  488. WriteCoord (MSG_BROADCAST, org_y);
  489. WriteCoord (MSG_BROADCAST, org_z);
  490. }
  491. else
  492. {
  493. sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
  494. }
  495. }
  496. self.attack_finished = time + 0.4;
  497. };
  498. // called by worldspawn
  499. void() W_Precache =
  500. {
  501. precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
  502. precache_sound ("weapons/rocket1i.wav"); // spike gun
  503. precache_sound ("weapons/sgun1.wav");
  504. precache_sound ("weapons/guncock.wav"); // player shotgun
  505. precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
  506. precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
  507. precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
  508. precache_sound ("weapons/spike2.wav"); // super spikes
  509. precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
  510. precache_sound ("weapons/grenade.wav"); // grenade launcher
  511. precache_sound ("weapons/bounce.wav"); // grenade bounce
  512. precache_sound ("weapons/shotgn2.wav"); // super shotgun
  513. //MED
  514. precache_sound ("enforcer/enfstop.wav"); // laser cannon
  515. //MED 11/06/96
  516. precache_sound ("knight/sword1.wav"); // laser cannon
  517. precache_sound ("hipweap/laserg.wav"); // laser cannon
  518. precache_sound ("hipweap/laserric.wav"); // laser cannon ricochet
  519. precache_sound ("hipweap/proxwarn.wav"); // proximity bomb
  520. precache_sound ("hipweap/proxbomb.wav"); // proximity bomb
  521. //MED 11/19/96
  522. precache_sound ("hipweap/mjolhit.wav"); // mjolnir
  523. precache_sound ("hipweap/mjolslap.wav"); // mjolnir
  524. precache_sound ("hipweap/mjoltink.wav"); // mjolnir
  525. };
  526. float() crandom =
  527. {
  528. return 2*(random() - 0.5);
  529. };
  530. /*
  531. ================
  532. W_FireAxe
  533. ================
  534. */
  535. void() W_FireAxe =
  536. {
  537. local vector source;
  538. local vector org;
  539. makevectors (self.v_angle);
  540. source = self.origin + '0 0 16';
  541. traceline (source, source + v_forward*64, FALSE, self);
  542. if (trace_fraction == 1.0)
  543. return;
  544. org = trace_endpos - v_forward*4;
  545. if (trace_ent.takedamage)
  546. {
  547. trace_ent.axhitme = 1;
  548. SpawnBlood (org, '0 0 0', 20);
  549. T_Damage (trace_ent, self, self, 20);
  550. }
  551. else
  552. { // hit wall
  553. sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  554. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  555. WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  556. WriteCoord (MSG_BROADCAST, org_x);
  557. WriteCoord (MSG_BROADCAST, org_y);
  558. WriteCoord (MSG_BROADCAST, org_z);
  559. }
  560. };
  561. //============================================================================
  562. vector() wall_velocity =
  563. {
  564. local vector vel;
  565. vel = normalize (self.velocity);
  566. vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  567. vel = vel + 2*trace_plane_normal;
  568. vel = vel * 200;
  569. return vel;
  570. };
  571. /*
  572. ================
  573. SpawnMeatSpray
  574. ================
  575. */
  576. void(vector org, vector vel) SpawnMeatSpray =
  577. {
  578. local entity missile, mpuff;
  579. local vector org;
  580. missile = spawn ();
  581. missile.owner = self;
  582. missile.movetype = MOVETYPE_BOUNCE;
  583. missile.solid = SOLID_NOT;
  584. makevectors (self.angles);
  585. missile.velocity = vel;
  586. missile.velocity_z = missile.velocity_z + 250 + 50*random();
  587. missile.avelocity = '3000 1000 2000';
  588. // set missile duration
  589. missile.nextthink = time + 1;
  590. missile.think = SUB_Remove;
  591. setmodel (missile, "progs/zom_gib.mdl");
  592. setsize (missile, '0 0 0', '0 0 0');
  593. setorigin (missile, org);
  594. };
  595. /*
  596. ================
  597. SpawnBlood
  598. ================
  599. */
  600. void(vector org, vector vel, float damage) SpawnBlood =
  601. {
  602. particle (org, vel*0.1, 73, damage*2);
  603. };
  604. /*
  605. ================
  606. spawn_touchblood
  607. ================
  608. */
  609. void(float damage) spawn_touchblood =
  610. {
  611. local vector vel;
  612. vel = wall_velocity () * 0.2;
  613. SpawnBlood (self.origin + vel*0.01, vel, damage);
  614. };
  615. /*
  616. ================
  617. SpawnChunk
  618. ================
  619. */
  620. void(vector org, vector vel) SpawnChunk =
  621. {
  622. particle (org, vel*0.02, 0, 10);
  623. };
  624. /*
  625. ==============================================================================
  626. MULTI-DAMAGE
  627. Collects multiple small damages into a single damage
  628. ==============================================================================
  629. */
  630. entity multi_ent;
  631. float multi_damage;
  632. void() ClearMultiDamage =
  633. {
  634. multi_ent = world;
  635. multi_damage = 0;
  636. };
  637. void() ApplyMultiDamage =
  638. {
  639. if (!multi_ent)
  640. return;
  641. T_Damage (multi_ent, self, self, multi_damage);
  642. };
  643. void(entity hit, float damage) AddMultiDamage =
  644. {
  645. if (!hit)
  646. return;
  647. if (hit != multi_ent)
  648. {
  649. ApplyMultiDamage ();
  650. multi_damage = damage;
  651. multi_ent = hit;
  652. }
  653. else
  654. multi_damage = multi_damage + damage;
  655. };
  656. /*
  657. ==============================================================================
  658. BULLETS
  659. ==============================================================================
  660. */
  661. /*
  662. ================
  663. TraceAttack
  664. ================
  665. */
  666. void(float damage, vector dir) TraceAttack =
  667. {
  668. local vector vel, org;
  669. vel = normalize(dir + v_up*crandom() + v_right*crandom());
  670. vel = vel + 2*trace_plane_normal;
  671. vel = vel * 200;
  672. org = trace_endpos - dir*4;
  673. if (trace_ent.takedamage)
  674. {
  675. SpawnBlood (org, vel*0.2, damage);
  676. AddMultiDamage (trace_ent, damage);
  677. }
  678. else
  679. {
  680. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  681. WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  682. WriteCoord (MSG_BROADCAST, org_x);
  683. WriteCoord (MSG_BROADCAST, org_y);
  684. WriteCoord (MSG_BROADCAST, org_z);
  685. }
  686. };
  687. /*
  688. ================
  689. FireBullets
  690. Used by shotgun, super shotgun, and enemy soldier firing
  691. Go to the trouble of combining multiple pellets into a single damage call.
  692. ================
  693. */
  694. void(float shotcount, vector dir, vector spread) FireBullets =
  695. {
  696. local vector direction;
  697. local vector src;
  698. //JIM
  699. local float bullet;
  700. bullet = 0;
  701. makevectors(self.v_angle);
  702. src = self.origin + v_forward*10;
  703. src_z = self.absmin_z + self.size_z * 0.7;
  704. ClearMultiDamage ();
  705. while (shotcount > 0)
  706. {
  707. direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  708. traceline (src, src + direction*2048, FALSE, self);
  709. if (trace_fraction != 1.0)
  710. //JIM
  711. {
  712. TraceAttack (4, direction);
  713. if ( ( !bullet ) && ( trace_ent == world ) )
  714. {
  715. placebullethole( trace_endpos );
  716. bullet = 1;
  717. }
  718. }
  719. shotcount = shotcount - 1;
  720. }
  721. ApplyMultiDamage ();
  722. };
  723. /*
  724. ================
  725. W_FireShotgun
  726. ================
  727. */
  728. void() W_FireShotgun =
  729. {
  730. local vector dir;
  731. sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
  732. self.punchangle_x = -2;
  733. self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  734. dir = aim (self, 100000);
  735. FireBullets (6, dir, '0.04 0.04 0');
  736. };
  737. /*
  738. ================
  739. W_FireSuperShotgun
  740. ================
  741. */
  742. void() W_FireSuperShotgun =
  743. {
  744. local vector dir;
  745. if (self.currentammo == 1)
  746. {
  747. W_FireShotgun ();
  748. return;
  749. }
  750. sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
  751. self.punchangle_x = -4;
  752. self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  753. dir = aim (self, 100000);
  754. FireBullets (14, dir, '0.14 0.08 0');
  755. };
  756. /*
  757. ==============================================================================
  758. ROCKETS
  759. ==============================================================================
  760. */
  761. void() s_explode1 = [0, s_explode2] {};
  762. void() s_explode2 = [1, s_explode3] {};
  763. void() s_explode3 = [2, s_explode4] {};
  764. void() s_explode4 = [3, s_explode5] {};
  765. void() s_explode5 = [4, s_explode6] {};
  766. void() s_explode6 = [5, SUB_Remove] {};
  767. void() BecomeExplosion =
  768. {
  769. self.movetype = MOVETYPE_NONE;
  770. self.velocity = '0 0 0';
  771. self.touch = SUB_Null;
  772. setmodel (self, "progs/s_explod.spr");
  773. self.solid = SOLID_NOT;
  774. s_explode1 ();
  775. };
  776. void() T_MissileTouch =
  777. {
  778. local float damg;
  779. if (other == self.owner)
  780. return; // don't explode on owner
  781. if (pointcontents(self.origin) == CONTENT_SKY)
  782. {
  783. remove(self);
  784. return;
  785. }
  786. damg = 100 + random()*20;
  787. if (other.health)
  788. {
  789. if (other.classname == "monster_shambler")
  790. damg = damg * 0.5; // mostly immune
  791. T_Damage (other, self, self.owner, damg );
  792. }
  793. // don't do radius damage to the other, because all the damage
  794. // was done in the impact
  795. T_RadiusDamage (self, self.owner, 120, other);
  796. // sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  797. self.origin = self.origin - 8*normalize(self.velocity);
  798. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  799. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  800. WriteCoord (MSG_BROADCAST, self.origin_x);
  801. WriteCoord (MSG_BROADCAST, self.origin_y);
  802. WriteCoord (MSG_BROADCAST, self.origin_z);
  803. BecomeExplosion ();
  804. };
  805. /*
  806. ================
  807. W_FireRocket
  808. ================
  809. */
  810. void() W_FireRocket =
  811. {
  812. local entity missile, mpuff;
  813. self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  814. sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  815. self.punchangle_x = -2;
  816. missile = spawn ();
  817. missile.owner = self;
  818. missile.movetype = MOVETYPE_FLYMISSILE;
  819. missile.solid = SOLID_BBOX;
  820. missile.classname = "missile";
  821. // set missile speed
  822. makevectors (self.v_angle);
  823. missile.velocity = aim(self, 1000);
  824. missile.velocity = missile.velocity * 1000;
  825. missile.angles = vectoangles(missile.velocity);
  826. missile.touch = T_MissileTouch;
  827. // set missile duration
  828. missile.nextthink = time + 5;
  829. missile.think = SUB_Remove;
  830. setmodel (missile, "progs/missile.mdl");
  831. setsize (missile, '0 0 0', '0 0 0');
  832. setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  833. //MED 11/09/96
  834. newmis = missile;
  835. };
  836. /*
  837. ===============================================================================
  838. LIGHTNING
  839. ===============================================================================
  840. */
  841. /*
  842. =================
  843. LightningDamage
  844. =================
  845. */
  846. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  847. {
  848. local entity e1, e2;
  849. local vector f;
  850. f = p2 - p1;
  851. normalize (f);
  852. f_x = 0 - f_y;
  853. f_y = f_x;
  854. f_z = 0;
  855. f = f*16;
  856. e1 = e2 = world;
  857. traceline (p1, p2, FALSE, self);
  858. //JIM
  859. if (trace_ent.takedamage && !trace_ent.wetsuit_finished )
  860. {
  861. particle (trace_endpos, '0 0 100', 225, damage*4);
  862. T_Damage (trace_ent, from, from, damage);
  863. if (self.classname == "player")
  864. {
  865. if (other.classname == "player")
  866. trace_ent.velocity_z = trace_ent.velocity_z + 400;
  867. }
  868. }
  869. e1 = trace_ent;
  870. traceline (p1 + f, p2 + f, FALSE, self);
  871. //JIM
  872. if (trace_ent != e1 && trace_ent.takedamage &&
  873. !trace_ent.wetsuit_finished )
  874. {
  875. particle (trace_endpos, '0 0 100', 225, damage*4);
  876. T_Damage (trace_ent, from, from, damage);
  877. }
  878. e2 = trace_ent;
  879. traceline (p1 - f, p2 - f, FALSE, self);
  880. //JIM
  881. if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage &&
  882. !trace_ent.wetsuit_finished )
  883. {
  884. particle (trace_endpos, '0 0 100', 225, damage*4);
  885. T_Damage (trace_ent, from, from, damage);
  886. }
  887. };
  888. void() W_FireLightning =
  889. {
  890. local vector org;
  891. local float cells;
  892. if (self.ammo_cells < 1)
  893. {
  894. self.weapon = W_BestWeapon ();
  895. W_SetCurrentAmmo ();
  896. return;
  897. }
  898. // explode if under water
  899. if (self.waterlevel > 1)
  900. {
  901. cells = self.ammo_cells;
  902. self.ammo_cells = 0;
  903. //MED 01/05/97 added discharge flag
  904. discharged = 1;
  905. T_RadiusDamage (self, self, 35*cells, world);
  906. discharged = 0;
  907. W_SetCurrentAmmo ();
  908. return;
  909. }
  910. if (self.t_width < time)
  911. {
  912. sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  913. self.t_width = time + 0.6;
  914. }
  915. self.punchangle_x = -2;
  916. self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  917. org = self.origin + '0 0 16';
  918. traceline (org, org + v_forward*600, TRUE, self);
  919. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  920. WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  921. WriteEntity (MSG_BROADCAST, self);
  922. WriteCoord (MSG_BROADCAST, org_x);
  923. WriteCoord (MSG_BROADCAST, org_y);
  924. WriteCoord (MSG_BROADCAST, org_z);
  925. WriteCoord (MSG_BROADCAST, trace_endpos_x);
  926. WriteCoord (MSG_BROADCAST, trace_endpos_y);
  927. WriteCoord (MSG_BROADCAST, trace_endpos_z);
  928. LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  929. };
  930. //=============================================================================
  931. void() GrenadeExplode =
  932. {
  933. T_RadiusDamage (self, self.owner, 120, world);
  934. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  935. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  936. WriteCoord (MSG_BROADCAST, self.origin_x);
  937. WriteCoord (MSG_BROADCAST, self.origin_y);
  938. WriteCoord (MSG_BROADCAST, self.origin_z);
  939. BecomeExplosion ();
  940. };
  941. void() GrenadeTouch =
  942. {
  943. if (other == self.owner)
  944. return; // don't explode on owner
  945. if (other.takedamage == DAMAGE_AIM)
  946. {
  947. GrenadeExplode();
  948. return;
  949. }
  950. sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
  951. if (self.velocity == '0 0 0')
  952. self.avelocity = '0 0 0';
  953. };
  954. /*
  955. ================
  956. W_FireGrenade
  957. ================
  958. */
  959. void() W_FireGrenade =
  960. {
  961. local entity missile, mpuff;
  962. self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  963. sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  964. self.punchangle_x = -2;
  965. missile = spawn ();
  966. missile.owner = self;
  967. missile.movetype = MOVETYPE_BOUNCE;
  968. missile.solid = SOLID_BBOX;
  969. missile.classname = "grenade";
  970. // set missile speed
  971. makevectors (self.v_angle);
  972. if (self.v_angle_x)
  973. missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  974. else
  975. {
  976. missile.velocity = aim(self, 10000);
  977. missile.velocity = missile.velocity * 600;
  978. missile.velocity_z = 200;
  979. }
  980. missile.avelocity = '300 300 300';
  981. missile.angles = vectoangles(missile.velocity);
  982. missile.touch = GrenadeTouch;
  983. // set missile duration
  984. missile.nextthink = time + 2.5;
  985. missile.think = GrenadeExplode;
  986. setmodel (missile, "progs/grenade.mdl");
  987. setsize (missile, '0 0 0', '0 0 0');
  988. setorigin (missile, self.origin);
  989. };
  990. void() ProximityExplode =
  991. {
  992. T_RadiusDamage (self, self.owner, 95, world);
  993. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  994. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  995. WriteCoord (MSG_BROADCAST, self.origin_x);
  996. WriteCoord (MSG_BROADCAST, self.origin_y);
  997. WriteCoord (MSG_BROADCAST, self.origin_z);
  998. BecomeExplosion ();
  999. };
  1000. //MED 10/31/96
  1001. float NumProximityGrenades;
  1002. /*
  1003. ================
  1004. ProximityGrenadeExplode
  1005. ================
  1006. */
  1007. void() ProximityGrenadeExplode =
  1008. {
  1009. self.takedamage = DAMAGE_NO;
  1010. NumProximityGrenades = NumProximityGrenades - 1;
  1011. self.deathtype = "exploding";
  1012. self.nextthink = time + 0.1;
  1013. self.owner = self.lastvictim;
  1014. self.think = ProximityExplode;
  1015. };
  1016. /*
  1017. ================
  1018. ProximityGrenadeTouch
  1019. ================
  1020. */
  1021. void() ProximityGrenadeTouch =
  1022. {
  1023. if (other == self)
  1024. return;
  1025. if (other.classname == self.classname)
  1026. return;
  1027. self.movetype = MOVETYPE_TOSS;
  1028. if (self.state == 1)
  1029. return;
  1030. if (vlen(other.velocity) > 0)
  1031. {
  1032. ProximityGrenadeExplode();
  1033. self.think();
  1034. return;
  1035. }
  1036. if (other.takedamage == DAMAGE_AIM)
  1037. {
  1038. ProximityGrenadeExplode();
  1039. self.think();
  1040. return;
  1041. }
  1042. sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
  1043. self.movetype = MOVETYPE_NONE;
  1044. setsize (self, '-8 -8 -8', '8 8 8');
  1045. self.state = 1;
  1046. self.spawnmaster = other;
  1047. };
  1048. /*
  1049. ================
  1050. ProximityBomb
  1051. ================
  1052. */
  1053. void() ProximityBomb =
  1054. {
  1055. local entity head;
  1056. local float blowup;
  1057. if ((time > self.delay) || (NumProximityGrenades > 15) || (vlen(self.spawnmaster.velocity)>0) )
  1058. {
  1059. ProximityGrenadeExplode();
  1060. self.think();
  1061. return;
  1062. }
  1063. self.owner = world;
  1064. self.takedamage = DAMAGE_YES;
  1065. head = findradius(self.origin, 140);
  1066. blowup = 0;
  1067. while (head)
  1068. {
  1069. if ((head != self) && (head.health > 0) && (head.flags & (FL_CLIENT|FL_MONSTER)) && (head.classname!=self.classname))
  1070. blowup = 1;
  1071. if ((head.classname == self.classname) && (head.state==0))
  1072. blowup = 1;
  1073. traceline(self.origin,head.origin,TRUE,self);
  1074. if (trace_fraction != 1.0)
  1075. blowup = 0;
  1076. if (blowup==1)
  1077. {
  1078. sound (self, CHAN_WEAPON, "hipweap/proxwarn.wav", 1, ATTN_NORM);
  1079. ProximityGrenadeExplode();
  1080. self.nextthink = time + 0.5;
  1081. return;
  1082. }
  1083. head = head.chain;
  1084. }
  1085. self.nextthink = time + 0.25;
  1086. };
  1087. /*
  1088. ================
  1089. W_FireProximityGrenade
  1090. ================
  1091. */
  1092. void() W_FireProximityGrenade =
  1093. {
  1094. local entity missile, mpuff;
  1095. NumProximityGrenades = NumProximityGrenades + 1;
  1096. self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1097. sound (self, CHAN_WEAPON, "hipweap/proxbomb.wav", 1, ATTN_NORM);
  1098. self.punchangle_x = -2;
  1099. missile = spawn ();
  1100. missile.owner = self;
  1101. missile.lastvictim = self;
  1102. missile.movetype = MOVETYPE_TOSS;
  1103. missile.solid = SOLID_BBOX;
  1104. missile.classname = "proximity_grenade";
  1105. missile.takedamage = DAMAGE_NO;
  1106. missile.health = 5;
  1107. missile.state = 0;
  1108. // set missile speed
  1109. makevectors (self.v_angle);
  1110. if (self.v_angle_x)
  1111. missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  1112. else
  1113. {
  1114. missile.velocity = aim(self, 10000);
  1115. missile.velocity = missile.velocity * 600;
  1116. missile.velocity_z = 200;
  1117. }
  1118. missile.avelocity = '100 600 100';
  1119. missile.angles = vectoangles(missile.velocity);
  1120. missile.touch = ProximityGrenadeTouch;
  1121. // set missile duration
  1122. missile.nextthink = time + 2;
  1123. missile.delay = time + 15 + (10*random());
  1124. missile.think = ProximityBomb;
  1125. missile.th_die = ProximityGrenadeExplode;
  1126. setmodel (missile, "progs/proxbomb.mdl");
  1127. setorigin (missile, self.origin);
  1128. setsize (missile, '-1 -1 -1', '1 1 1');
  1129. };
  1130. //=============================================================================
  1131. void() spike_touch;
  1132. void() superspike_touch;
  1133. /*
  1134. ===============
  1135. launch_spike
  1136. Used for both the player and the ogre
  1137. ===============
  1138. */
  1139. void(vector org, vector dir) launch_spike =
  1140. {
  1141. newmis = spawn ();
  1142. newmis.owner = self;
  1143. newmis.movetype = MOVETYPE_FLYMISSILE;
  1144. newmis.solid = SOLID_BBOX;
  1145. newmis.angles = vectoangles(dir);
  1146. newmis.touch = spike_touch;
  1147. newmis.classname = "spike";
  1148. newmis.think = SUB_Remove;
  1149. newmis.nextthink = time + 6;
  1150. setmodel (newmis, "progs/spike.mdl");
  1151. setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  1152. setorigin (newmis, org);
  1153. newmis.velocity = dir * 1000;
  1154. };
  1155. void() W_FireSuperSpikes =
  1156. {
  1157. local vector dir;
  1158. local entity old;
  1159. sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  1160. self.attack_finished = time + 0.2;
  1161. self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  1162. dir = aim (self, 1000);
  1163. launch_spike (self.origin + '0 0 16', dir);
  1164. newmis.touch = superspike_touch;
  1165. setmodel (newmis, "progs/s_spike.mdl");
  1166. setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  1167. self.punchangle_x = -2;
  1168. };
  1169. void(float ox) W_FireSpikes =
  1170. {
  1171. local vector dir;
  1172. local entity old;
  1173. makevectors (self.v_angle);
  1174. if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  1175. {
  1176. W_FireSuperSpikes ();
  1177. return;
  1178. }
  1179. if (self.ammo_nails < 1)
  1180. {
  1181. self.weapon = W_BestWeapon ();
  1182. W_SetCurrentAmmo ();
  1183. return;
  1184. }
  1185. sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1186. self.attack_finished = time + 0.2;
  1187. self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  1188. dir = aim (self, 1000);
  1189. launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  1190. self.punchangle_x = -2;
  1191. };
  1192. .float hit_z;
  1193. void() spike_touch =
  1194. {
  1195. local float rand;
  1196. if (other == self.owner)
  1197. return;
  1198. if (other.solid == SOLID_TRIGGER)
  1199. return; // trigger field, do nothing
  1200. if (pointcontents(self.origin) == CONTENT_SKY)
  1201. {
  1202. remove(self);
  1203. return;
  1204. }
  1205. // hit something that bleeds
  1206. if (other.takedamage)
  1207. {
  1208. spawn_touchblood (9);
  1209. T_Damage (other, self, self.owner, 9);
  1210. }
  1211. else
  1212. {
  1213. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1214. if (self.classname == "wizspike")
  1215. WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  1216. else if (self.classname == "knightspike")
  1217. WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  1218. else
  1219. WriteByte (MSG_BROADCAST, TE_SPIKE);
  1220. WriteCoord (MSG_BROADCAST, self.origin_x);
  1221. WriteCoord (MSG_BROADCAST, self.origin_y);
  1222. WriteCoord (MSG_BROADCAST, self.origin_z);
  1223. }
  1224. remove(self);
  1225. };
  1226. void() superspike_touch =
  1227. {
  1228. local float rand;
  1229. if (other == self.owner)
  1230. return;
  1231. if (other.solid == SOLID_TRIGGER)
  1232. return; // trigger field, do nothing
  1233. if (pointcontents(self.origin) == CONTENT_SKY)
  1234. {
  1235. remove(self);
  1236. return;
  1237. }
  1238. // hit something that bleeds
  1239. if (other.takedamage)
  1240. {
  1241. spawn_touchblood (18);
  1242. T_Damage (other, self, self.owner, 18);
  1243. }
  1244. else
  1245. {
  1246. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1247. WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  1248. WriteCoord (MSG_BROADCAST, self.origin_x);
  1249. WriteCoord (MSG_BROADCAST, self.origin_y);
  1250. WriteCoord (MSG_BROADCAST, self.origin_z);
  1251. }
  1252. remove(self);
  1253. };
  1254. /*
  1255. ===============================================================================
  1256. PLAYER WEAPON USE
  1257. ===============================================================================
  1258. */
  1259. //MED 10/18/96 added HIPWEAPONS
  1260. void() W_SetCurrentAmmo =
  1261. {
  1262. player_run (); // get out of any weapon firing states
  1263. self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  1264. if (self.weapon == IT_AXE)
  1265. {
  1266. self.currentammo = 0;
  1267. self.weaponmodel = "progs/v_axe.mdl";
  1268. self.weaponframe = 0;
  1269. }
  1270. else if (self.weapon == IT_SHOTGUN)
  1271. {
  1272. self.currentammo = self.ammo_shells;
  1273. self.weaponmodel = "progs/v_shot.mdl";
  1274. self.weaponframe = 0;
  1275. self.items = self.items | IT_SHELLS;
  1276. }
  1277. else if (self.weapon == IT_SUPER_SHOTGUN)
  1278. {
  1279. self.currentammo = self.ammo_shells;
  1280. self.weaponmodel = "progs/v_shot2.mdl";
  1281. self.weaponframe = 0;
  1282. self.items = self.items | IT_SHELLS;
  1283. }
  1284. else if (self.weapon == IT_NAILGUN)
  1285. {
  1286. self.currentammo = self.ammo_nails;
  1287. self.weaponmodel = "progs/v_nail.mdl";
  1288. self.weaponframe = 0;
  1289. self.items = self.items | IT_NAILS;
  1290. }
  1291. else if (self.weapon == IT_SUPER_NAILGUN)
  1292. {
  1293. self.currentammo = self.ammo_nails;
  1294. self.weaponmodel = "progs/v_nail2.mdl";
  1295. self.weaponframe = 0;
  1296. self.items = self.items | IT_NAILS;
  1297. }
  1298. //MED
  1299. else if (self.weapon == IT_LASER_CANNON)
  1300. {
  1301. self.currentammo = self.ammo_cells;
  1302. self.weaponmodel = "progs/v_laserg.mdl";
  1303. self.weaponframe = 0;
  1304. self.items = self.items | IT_CELLS;
  1305. }
  1306. else if (self.weapon == IT_GRENADE_LAUNCHER)
  1307. {
  1308. self.currentammo = self.ammo_rockets;
  1309. self.weaponmodel = "progs/v_rock.mdl";
  1310. self.weaponframe = 0;
  1311. self.items = self.items | IT_ROCKETS;
  1312. }
  1313. else if (self.weapon == IT_ROCKET_LAUNCHER)
  1314. {
  1315. self.currentammo = self.ammo_rockets;
  1316. self.weaponmodel = "progs/v_rock2.mdl";
  1317. self.weaponframe = 0;
  1318. self.items = self.items | IT_ROCKETS;
  1319. }
  1320. else if (self.weapon == IT_LIGHTNING)
  1321. {
  1322. self.currentammo = self.ammo_cells;
  1323. self.weaponmodel = "progs/v_light.mdl";
  1324. self.weaponframe = 0;
  1325. self.items = self.items | IT_CELLS;
  1326. }
  1327. //MED
  1328. else if (self.weapon == IT_MJOLNIR)
  1329. {
  1330. self.currentammo = self.ammo_cells;
  1331. self.weaponmodel = "progs/v_hammer.mdl";
  1332. self.weaponframe = 0;
  1333. self.items = self.items | IT_CELLS;
  1334. }
  1335. //MED
  1336. else if (self.weapon == IT_PROXIMITY_GUN)
  1337. {
  1338. self.currentammo = self.ammo_rockets;
  1339. self.weaponmodel = "progs/v_prox.mdl";
  1340. self.weaponframe = 0;
  1341. self.items = self.items | IT_ROCKETS;
  1342. }
  1343. else
  1344. {
  1345. self.currentammo = 0;
  1346. self.weaponmodel = "";
  1347. self.weaponframe = 0;
  1348. }
  1349. };
  1350. float() W_BestWeapon =
  1351. {
  1352. local float it;
  1353. it = self.items;
  1354. if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  1355. return IT_LIGHTNING;
  1356. //MED
  1357. else if(self.ammo_cells >= 1 && (it & IT_LASER_CANNON) )
  1358. return IT_LASER_CANNON;
  1359. else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1360. return IT_SUPER_NAILGUN;
  1361. else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1362. return IT_SUPER_SHOTGUN;
  1363. else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1364. return IT_NAILGUN;
  1365. else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  1366. return IT_SHOTGUN;
  1367. //MED
  1368. else if( it & IT_MJOLNIR )
  1369. return IT_MJOLNIR;
  1370. /*
  1371. if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  1372. return IT_ROCKET_LAUNCHER;
  1373. else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) )
  1374. return IT_GRENADE_LAUNCHER;
  1375. */
  1376. return IT_AXE;
  1377. };
  1378. float(entity playerEnt, float old, float new) W_WantsToChangeWeapon =
  1379. {
  1380. float playerFlags = CheckPlayerEXFlags(playerEnt);
  1381. if((playerFlags & PEF_CHANGENEVER) != 0)
  1382. {
  1383. return 0;
  1384. }
  1385. if(((playerFlags & PEF_CHANGEONLYNEW) != 0) && old == new)
  1386. {
  1387. return 0;
  1388. }
  1389. return 1;
  1390. };
  1391. float() W_CheckNoAmmo =
  1392. {
  1393. if (self.currentammo > 0)
  1394. return TRUE;
  1395. if (self.weapon == IT_AXE)
  1396. return TRUE;
  1397. //MED
  1398. if (self.weapon == IT_MJOLNIR)
  1399. {
  1400. return TRUE;
  1401. }
  1402. self.weapon = W_BestWeapon ();
  1403. W_SetCurrentAmmo ();
  1404. // drop the weapon down
  1405. return FALSE;
  1406. };
  1407. /*
  1408. ============
  1409. W_Attack
  1410. An attack impulse can be triggered now
  1411. ============
  1412. */
  1413. void() player_axe1;
  1414. void() player_axeb1;
  1415. void() player_axec1;
  1416. void() player_axed1;
  1417. void() player_shot1;
  1418. void() player_nail1;
  1419. void() player_light1;
  1420. void() player_rocket1;
  1421. //MED
  1422. void() player_laser1;
  1423. void() player_hammer1;
  1424. void() player_mjolnir1;
  1425. void() W_Attack =
  1426. {
  1427. local float r;
  1428. if (!W_CheckNoAmmo ())
  1429. return;
  1430. makevectors (self.v_angle); // calculate forward angle for velocity
  1431. self.show_hostile = time + 1; // wake monsters up
  1432. if (self.weapon == IT_AXE)
  1433. {
  1434. sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  1435. r = random();
  1436. if (r < 0.25)
  1437. player_axe1 ();
  1438. else if (r<0.5)
  1439. player_axeb1 ();
  1440. else if (r<0.75)
  1441. player_axec1 ();
  1442. else
  1443. player_axed1 ();
  1444. self.attack_finished = time + 0.5;
  1445. }
  1446. else if (self.weapon == IT_SHOTGUN)
  1447. {
  1448. player_shot1 ();
  1449. W_FireShotgun ();
  1450. self.attack_finished = time + 0.5;
  1451. }
  1452. else if (self.weapon == IT_SUPER_SHOTGUN)
  1453. {
  1454. player_shot1 ();
  1455. W_FireSuperShotgun ();
  1456. self.attack_finished = time + 0.7;
  1457. }
  1458. else if (self.weapon == IT_NAILGUN)
  1459. {
  1460. player_nail1 ();
  1461. }
  1462. else if (self.weapon == IT_SUPER_NAILGUN)
  1463. {
  1464. player_nail1 ();
  1465. }
  1466. else if (self.weapon == IT_GRENADE_LAUNCHER)
  1467. {
  1468. player_rocket1();
  1469. W_FireGrenade();
  1470. self.attack_finished = time + 0.6;
  1471. }
  1472. else if (self.weapon == IT_ROCKET_LAUNCHER)
  1473. {
  1474. player_rocket1();
  1475. W_FireRocket();
  1476. self.attack_finished = time + 0.8;
  1477. }
  1478. else if (self.weapon == IT_LIGHTNING)
  1479. {
  1480. player_light1();
  1481. self.attack_finished = time + 0.1;
  1482. sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1483. }
  1484. //MED
  1485. else if (self.weapon == IT_LASER_CANNON)
  1486. {
  1487. player_laser1();
  1488. }
  1489. //MED
  1490. else if (self.weapon == IT_MJOLNIR)
  1491. {
  1492. if (self.ammo_cells < 30)
  1493. player_hammer1();
  1494. else
  1495. player_mjolnir1();
  1496. self.attack_finished = time + 0.8;
  1497. }
  1498. //MED
  1499. else if (self.weapon == IT_PROXIMITY_GUN)
  1500. {
  1501. player_rocket1();
  1502. W_FireProximityGrenade();
  1503. self.attack_finished = time + 0.6;
  1504. }
  1505. };
  1506. /*
  1507. ============
  1508. W_ChangeWeapon
  1509. ============
  1510. */
  1511. //MED 10/18/96 added hipweapons
  1512. void() W_ChangeWeapon =
  1513. {
  1514. local float it, am, fl;
  1515. local float oldimpulse;
  1516. it = self.items;
  1517. am = 0;
  1518. //MED
  1519. if (self.impulse == 1)
  1520. {
  1521. fl = IT_AXE;
  1522. }
  1523. else if (self.impulse == 2)
  1524. {
  1525. fl = IT_SHOTGUN;
  1526. if (self.ammo_shells < 1)
  1527. am = 1;
  1528. }
  1529. else if (self.impulse == 3)
  1530. {
  1531. fl = IT_SUPER_SHOTGUN;
  1532. if (self.ammo_shells < 2)
  1533. am = 1;
  1534. }
  1535. else if (self.impulse == 4)
  1536. {
  1537. fl = IT_NAILGUN;
  1538. if (self.ammo_nails < 1)
  1539. am = 1;
  1540. }
  1541. //MED
  1542. else if (self.impulse == 5)
  1543. {
  1544. fl = IT_SUPER_NAILGUN;
  1545. if (self.ammo_nails < 2)
  1546. am = 1;
  1547. }
  1548. //MED
  1549. else if (self.impulse == 6)
  1550. {
  1551. if (self.weapon == IT_GRENADE_LAUNCHER)
  1552. {
  1553. fl = IT_PROXIMITY_GUN;
  1554. }
  1555. else
  1556. {
  1557. fl = IT_GRENADE_LAUNCHER;
  1558. }
  1559. if (self.ammo_rockets < 1)
  1560. am = 1;
  1561. }
  1562. else if (self.impulse == 7)
  1563. {
  1564. fl = IT_ROCKET_LAUNCHER;
  1565. if (self.ammo_rockets < 1)
  1566. am = 1;
  1567. }
  1568. //MED
  1569. else if (self.impulse == 8)
  1570. {
  1571. fl = IT_LIGHTNING;
  1572. if (self.ammo_cells < 1)
  1573. am = 1;
  1574. }
  1575. else if (self.impulse == 225)
  1576. {
  1577. fl = IT_LASER_CANNON;
  1578. if (self.ammo_cells < 1)
  1579. am = 1;
  1580. }
  1581. else if (self.impulse == 226)
  1582. {
  1583. fl = IT_MJOLNIR;
  1584. }
  1585. else if (self.impulse == 227)
  1586. {
  1587. fl = IT_PROXIMITY_GUN;
  1588. if (self.ammo_rockets < 1)
  1589. am = 1;
  1590. }
  1591. else if (self.impulse == 228)
  1592. {
  1593. fl = IT_GRENADE_LAUNCHER;
  1594. if (self.ammo_rockets < 1)
  1595. am = 1;
  1596. }
  1597. //MED
  1598. oldimpulse = self.impulse;
  1599. self.impulse = 0;
  1600. if (!(self.items & fl))
  1601. {
  1602. //MED
  1603. if (fl == IT_GRENADE_LAUNCHER)
  1604. {
  1605. fl = IT_PROXIMITY_GUN;
  1606. if (!(self.items & fl))
  1607. {
  1608. sprint (self, "$qc_no_weapon");
  1609. return;
  1610. }
  1611. if (self.ammo_rockets < 1)
  1612. am = 1;
  1613. else
  1614. am = 0;
  1615. }
  1616. else
  1617. {
  1618. sprint (self, "$qc_no_weapon");
  1619. return;
  1620. }
  1621. }
  1622. if (am)
  1623. { // don't have the ammo
  1624. sprint (self, "$qc_not_enough_ammo");
  1625. return;
  1626. }
  1627. //
  1628. // set weapon, set ammo
  1629. //
  1630. self.weapon = fl;
  1631. W_SetCurrentAmmo ();
  1632. };
  1633. /*
  1634. ============
  1635. CheatCommand
  1636. ============
  1637. */
  1638. void() CheatCommand =
  1639. {
  1640. if ( ( deathmatch || coop ) && cheats_allowed == 0 ) { // mal: allow impulse 9 IF cheats allowed
  1641. return;
  1642. }
  1643. self.ammo_rockets = 100;
  1644. self.ammo_nails = 200;
  1645. self.ammo_shells = 100;
  1646. self.items = self.items |
  1647. IT_AXE |
  1648. IT_SHOTGUN |
  1649. IT_SUPER_SHOTGUN |
  1650. IT_NAILGUN |
  1651. IT_SUPER_NAILGUN |
  1652. IT_GRENADE_LAUNCHER |
  1653. IT_ROCKET_LAUNCHER |
  1654. IT_KEY1 | IT_KEY2;
  1655. self.ammo_cells = 200;
  1656. self.items = self.items | IT_LIGHTNING;
  1657. //MED
  1658. self.items = self.items | IT_LASER_CANNON;
  1659. self.items = self.items | IT_MJOLNIR;
  1660. self.items = self.items | IT_PROXIMITY_GUN;
  1661. self.weapon = IT_ROCKET_LAUNCHER;
  1662. self.impulse = 0;
  1663. W_SetCurrentAmmo ();
  1664. };
  1665. /*
  1666. ============
  1667. CycleWeaponCommand
  1668. Go to the next weapon with ammo
  1669. ============
  1670. */
  1671. void() CycleWeaponCommand =
  1672. {
  1673. local float it, am;
  1674. it = self.items;
  1675. self.impulse = 0;
  1676. while (1)
  1677. {
  1678. am = 0;
  1679. //MED
  1680. if (self.weapon == IT_MJOLNIR)
  1681. {
  1682. self.weapon = IT_AXE;
  1683. }
  1684. else if (self.weapon == IT_AXE)
  1685. {
  1686. self.weapon = IT_SHOTGUN;
  1687. if (self.ammo_shells < 1)
  1688. am = 1;
  1689. }
  1690. else if (self.weapon == IT_SHOTGUN)
  1691. {
  1692. self.weapon = IT_SUPER_SHOTGUN;
  1693. if (self.ammo_shells < 2)
  1694. am = 1;
  1695. }
  1696. else if (self.weapon == IT_SUPER_SHOTGUN)
  1697. {
  1698. self.weapon = IT_NAILGUN;
  1699. if (self.ammo_nails < 1)
  1700. am = 1;
  1701. }
  1702. else if (self.weapon == IT_NAILGUN)
  1703. {
  1704. self.weapon = IT_SUPER_NAILGUN;
  1705. if (self.ammo_nails < 2)
  1706. am = 1;
  1707. }
  1708. else if (self.weapon == IT_SUPER_NAILGUN)
  1709. {
  1710. self.weapon = IT_GRENADE_LAUNCHER;
  1711. if (self.ammo_rockets < 1)
  1712. am = 1;
  1713. }
  1714. //MED
  1715. else if (self.weapon == IT_GRENADE_LAUNCHER)
  1716. {
  1717. self.weapon = IT_PROXIMITY_GUN;
  1718. if (self.ammo_rockets < 1)
  1719. am = 1;
  1720. }
  1721. //MED
  1722. else if (self.weapon == IT_PROXIMITY_GUN)
  1723. {
  1724. self.weapon = IT_ROCKET_LAUNCHER;
  1725. if (self.ammo_rockets < 1)
  1726. am = 1;
  1727. }
  1728. else if (self.weapon == IT_ROCKET_LAUNCHER)
  1729. {
  1730. self.weapon = IT_LIGHTNING;
  1731. if (self.ammo_cells < 1)
  1732. am = 1;
  1733. }
  1734. else if (self.weapon == IT_LIGHTNING)
  1735. {
  1736. self.weapon = IT_LASER_CANNON;
  1737. if (self.ammo_cells < 1)
  1738. am = 1;
  1739. }
  1740. else if (self.weapon == IT_LASER_CANNON)
  1741. {
  1742. self.weapon = IT_MJOLNIR;
  1743. }
  1744. if ( (self.items & self.weapon) && am == 0)
  1745. {
  1746. W_SetCurrentAmmo ();
  1747. return;
  1748. }
  1749. }
  1750. };
  1751. /*
  1752. ============
  1753. CycleWeaponReverseCommand
  1754. Go to the prev weapon with ammo
  1755. ============
  1756. */
  1757. void() CycleWeaponReverseCommand =
  1758. {
  1759. local float it, am;
  1760. it = self.items;
  1761. self.impulse = 0;
  1762. while (1)
  1763. {
  1764. am = 0;
  1765. //MED
  1766. if (self.weapon == IT_MJOLNIR)
  1767. {
  1768. self.weapon = IT_LASER_CANNON;
  1769. if (self.ammo_cells < 1)
  1770. am = 1;
  1771. }
  1772. //MED
  1773. else if (self.weapon == IT_LASER_CANNON)
  1774. {
  1775. self.weapon = IT_LIGHTNING;
  1776. if (self.ammo_cells < 1)
  1777. am = 1;
  1778. }
  1779. else if (self.weapon == IT_LIGHTNING)
  1780. {
  1781. self.weapon = IT_ROCKET_LAUNCHER;
  1782. if (self.ammo_rockets < 1)
  1783. am = 1;
  1784. }
  1785. else if (self.weapon == IT_ROCKET_LAUNCHER)
  1786. {
  1787. self.weapon = IT_PROXIMITY_GUN;
  1788. if (self.ammo_rockets < 1)
  1789. am = 1;
  1790. }
  1791. else if (self.weapon == IT_PROXIMITY_GUN)
  1792. {
  1793. self.weapon = IT_GRENADE_LAUNCHER;
  1794. if (self.ammo_rockets < 1)
  1795. am = 1;
  1796. }
  1797. else if (self.weapon == IT_GRENADE_LAUNCHER)
  1798. {
  1799. self.weapon = IT_SUPER_NAILGUN;
  1800. if (self.ammo_nails < 2)
  1801. am = 1;
  1802. }
  1803. else if (self.weapon == IT_SUPER_NAILGUN)
  1804. {
  1805. self.weapon = IT_NAILGUN;
  1806. if (self.ammo_nails < 1)
  1807. am = 1;
  1808. }
  1809. else if (self.weapon == IT_NAILGUN)
  1810. {
  1811. self.weapon = IT_SUPER_SHOTGUN;
  1812. if (self.ammo_shells < 2)
  1813. am = 1;
  1814. }
  1815. else if (self.weapon == IT_SUPER_SHOTGUN)
  1816. {
  1817. self.weapon = IT_SHOTGUN;
  1818. if (self.ammo_shells < 1)
  1819. am = 1;
  1820. }
  1821. else if (self.weapon == IT_SHOTGUN)
  1822. {
  1823. self.weapon = IT_AXE;
  1824. }
  1825. else if (self.weapon == IT_AXE)
  1826. {
  1827. self.weapon = IT_MJOLNIR;
  1828. }
  1829. if ( (it & self.weapon) && am == 0)
  1830. {
  1831. W_SetCurrentAmmo ();
  1832. return;
  1833. }
  1834. }
  1835. };
  1836. /*
  1837. ============
  1838. ServerflagsCommand
  1839. Just for development
  1840. ============
  1841. */
  1842. void() ServerflagsCommand =
  1843. {
  1844. serverflags = serverflags * 2 + 1;
  1845. };
  1846. void() QuadCheat =
  1847. {
  1848. if (deathmatch || coop)
  1849. return;
  1850. self.super_time = 1;
  1851. self.super_damage_finished = time + 30;
  1852. self.items = self.items | IT_QUAD;
  1853. bprint ("$qc_quad_cheat");
  1854. };
  1855. //MED
  1856. void() WetsuitCheat =
  1857. {
  1858. if (deathmatch || coop)
  1859. return;
  1860. self.items2 = self.items2 | HIP_IT_WETSUIT;
  1861. self.wetsuit_time = 1;
  1862. self.wetsuit_finished = time + 30;
  1863. bprint( "$qc_wetsuit_cheat" );
  1864. };
  1865. //MED
  1866. void() EmpathyShieldsCheat =
  1867. {
  1868. if (deathmatch || coop)
  1869. return;
  1870. self.items2 = self.items2 | HIP_IT_EMPATHY_SHIELDS;
  1871. self.empathy_time = 1;
  1872. self.empathy_finished = time + 30;
  1873. bprint( "$qc_empathy_cheat" );
  1874. };
  1875. void() DumpEntities =
  1876. {
  1877. local entity head;
  1878. local float i;
  1879. i = 1;
  1880. head = nextent(world);
  1881. while (head!=world)
  1882. {
  1883. dprint(ftos(i));
  1884. dprint(" ");
  1885. dprint(head.classname);
  1886. dprint("\n");
  1887. head = nextent(head);
  1888. i = i + 1;
  1889. }
  1890. };
  1891. void() DumpLiveEntities =
  1892. {
  1893. local entity head;
  1894. local float i;
  1895. i = 1;
  1896. head = nextent(world);
  1897. while (head!=world)
  1898. {
  1899. if (head.health > 0)
  1900. {
  1901. dprint(ftos(i));
  1902. dprint(" ");
  1903. dprint(head.classname);
  1904. dprint(" ");
  1905. dprint(vtos(head.origin));
  1906. dprint("\n");
  1907. dprint("--------------------\n");
  1908. }
  1909. head = nextent(head);
  1910. i = i + 1;
  1911. }
  1912. };
  1913. void() Genocide =
  1914. {
  1915. local entity head;
  1916. if (deathmatch || coop)
  1917. return;
  1918. bprint("$qc_genocide_cheat");
  1919. head = nextent(world);
  1920. while (head!=world)
  1921. {
  1922. if ((head.health > 0) && (head.flags & FL_MONSTER))
  1923. {
  1924. T_Damage(head,world,world,head.health+10);
  1925. }
  1926. head = nextent(head);
  1927. }
  1928. };
  1929. float dump_coord;
  1930. void () ToggleDump =
  1931. {
  1932. dump_coord = 1 - dump_coord;
  1933. if (dump_coord == 1)
  1934. bprint("$qc_dump_player_loc");
  1935. };
  1936. void () DumpCoordinates =
  1937. {
  1938. local entity pl;
  1939. pl = checkclient();
  1940. if (pl)
  1941. {
  1942. bprint("Player: ");
  1943. bprint(vtos(pl.origin));
  1944. bprint("\n");
  1945. }
  1946. };
  1947. /*
  1948. ============
  1949. ImpulseCommands
  1950. ============
  1951. */
  1952. void() ImpulseCommands =
  1953. {
  1954. if (self.impulse >= 1 && self.impulse <= 8)
  1955. W_ChangeWeapon ();
  1956. if (self.impulse >= 225 && self.impulse <= 228)
  1957. W_ChangeWeapon ();
  1958. if (self.impulse == 9)
  1959. CheatCommand ();
  1960. if (self.impulse == 10)
  1961. CycleWeaponCommand ();
  1962. if (self.impulse == 11)
  1963. ServerflagsCommand ();
  1964. if (self.impulse == 12)
  1965. CycleWeaponReverseCommand ();
  1966. //JIM
  1967. if ( self.impulse == 200 )
  1968. WetsuitCheat();
  1969. //MED
  1970. if ( self.impulse == 201 )
  1971. EmpathyShieldsCheat();
  1972. if ( self.impulse == 205 )
  1973. Genocide();
  1974. if ( self.impulse == 206 )
  1975. ToggleDump();
  1976. if ( self.impulse == 202 )
  1977. DumpEntities();
  1978. if ( self.impulse == 203 )
  1979. DumpLiveEntities();
  1980. if (self.impulse == 255)
  1981. QuadCheat ();
  1982. if (dump_coord == 1)
  1983. DumpCoordinates();
  1984. self.impulse = 0;
  1985. };
  1986. /*
  1987. ============
  1988. W_WeaponFrame
  1989. Called every frame so impulse events can be handled as well as possible
  1990. ============
  1991. */
  1992. void() W_WeaponFrame =
  1993. {
  1994. if (time < self.attack_finished)
  1995. return;
  1996. ImpulseCommands ();
  1997. // check for attack
  1998. if (self.button0)
  1999. {
  2000. SuperDamageSound ();
  2001. W_Attack ();
  2002. }
  2003. };
  2004. /*
  2005. ========
  2006. SuperDamageSound
  2007. Plays sound if needed
  2008. ========
  2009. */
  2010. void() SuperDamageSound =
  2011. {
  2012. if (self.super_damage_finished > time)
  2013. {
  2014. if (self.super_sound < time)
  2015. {
  2016. self.super_sound = time + 1;
  2017. sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  2018. }
  2019. }
  2020. return;
  2021. };