items.qc 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687
  1. /*
  2. items.qc
  3. item functions
  4. Copyright (C) 1996-1997 Id Software, Inc.
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. See the GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to:
  15. Free Software Foundation, Inc.
  16. 59 Temple Place - Suite 330
  17. Boston, MA 02111-1307, USA
  18. */
  19. void() W_SetCurrentAmmo;
  20. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  21. BE .8 .3 .4 IN COLOR */
  22. void() SUB_regen =
  23. {
  24. self.model = self.mdl; // restore original model
  25. self.solid = SOLID_TRIGGER; // allow it to be touched again
  26. sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound
  27. setorigin (self, self.origin);
  28. };
  29. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  30. prints a warning message when spawned
  31. */
  32. void() noclass =
  33. {
  34. dprint ("noclass spawned at");
  35. dprint (vtos(self.origin));
  36. dprint ("\n");
  37. remove (self);
  38. };
  39. void() q_touch;
  40. void() q_touch =
  41. {
  42. local entity stemp;
  43. local float best;
  44. local string s;
  45. if (other.classname != "player")
  46. return;
  47. if (other.health <= 0)
  48. return;
  49. self.mdl = self.model;
  50. sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  51. stuffcmd (other, "bf\n");
  52. self.solid = SOLID_NOT;
  53. other.items = other.items | IT_QUAD;
  54. self.model = string_null;
  55. if (deathmatch == 4)
  56. {
  57. other.armortype = 0;
  58. other.armorvalue = 0 * 0.01;
  59. other.ammo_cells = 0;
  60. }
  61. // do the apropriate action
  62. other.super_time = 1;
  63. other.super_damage_finished = self.cnt;
  64. s=ftos(rint(other.super_damage_finished - time));
  65. bprint (PRINT_LOW, other.netname);
  66. if (deathmatch == 4)
  67. bprint (PRINT_LOW, " recovered an OctaPower with ");
  68. else
  69. bprint (PRINT_LOW, " recovered a Quad with ");
  70. bprint (PRINT_LOW, s);
  71. bprint (PRINT_LOW, " seconds remaining!\n");
  72. activator = other;
  73. SUB_UseTargets(); // fire all targets / killtargets
  74. };
  75. void(float timeleft) DropQuad =
  76. {
  77. local entity item;
  78. item = spawn();
  79. item.origin = self.origin;
  80. item.velocity_z = 300;
  81. item.velocity_x = -100 + (random() * 200);
  82. item.velocity_y = -100 + (random() * 200);
  83. item.flags = FL_ITEM;
  84. item.solid = SOLID_TRIGGER;
  85. item.movetype = MOVETYPE_TOSS;
  86. item.noise = "items/damage.wav";
  87. setmodel (item, "progs/quaddama.mdl");
  88. setsize (item, '-16 -16 -24', '16 16 32');
  89. item.cnt = time + timeleft;
  90. item.touch = q_touch;
  91. item.nextthink = time + timeleft; // remove it with the time left on it
  92. item.think = SUB_Remove;
  93. };
  94. void() r_touch;
  95. void() r_touch =
  96. {
  97. local entity stemp;
  98. local float best;
  99. local string s;
  100. if (other.classname != "player")
  101. return;
  102. if (other.health <= 0)
  103. return;
  104. self.mdl = self.model;
  105. sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  106. stuffcmd (other, "bf\n");
  107. self.solid = SOLID_NOT;
  108. other.items = other.items | IT_INVISIBILITY;
  109. self.model = string_null;
  110. // do the apropriate action
  111. other.invisible_time = 1;
  112. other.invisible_finished = self.cnt;
  113. s=ftos(rint(other.invisible_finished - time));
  114. bprint (PRINT_LOW, other.netname);
  115. bprint (PRINT_LOW, " recovered a Ring with ");
  116. bprint (PRINT_LOW, s);
  117. bprint (PRINT_LOW, " seconds remaining!\n");
  118. activator = other;
  119. SUB_UseTargets(); // fire all targets / killtargets
  120. };
  121. void(float timeleft) DropRing =
  122. {
  123. local entity item;
  124. item = spawn();
  125. item.origin = self.origin;
  126. item.velocity_z = 300;
  127. item.velocity_x = -100 + (random() * 200);
  128. item.velocity_y = -100 + (random() * 200);
  129. item.flags = FL_ITEM;
  130. item.solid = SOLID_TRIGGER;
  131. item.movetype = MOVETYPE_TOSS;
  132. item.noise = "items/inv1.wav";
  133. setmodel (item, "progs/invisibl.mdl");
  134. setsize (item, '-16 -16 -24', '16 16 32');
  135. item.cnt = time + timeleft;
  136. item.touch = r_touch;
  137. item.nextthink = time + timeleft; // remove after 30 seconds
  138. item.think = SUB_Remove;
  139. };
  140. /*
  141. ============
  142. PlaceItem
  143. plants the object on the floor
  144. ============
  145. */
  146. void() PlaceItem =
  147. {
  148. local float oldz;
  149. self.mdl = self.model; // so it can be restored on respawn
  150. self.flags = FL_ITEM; // make extra wide
  151. self.solid = SOLID_TRIGGER;
  152. self.movetype = MOVETYPE_TOSS;
  153. self.velocity = '0 0 0';
  154. self.origin_z = self.origin_z + 6;
  155. oldz = self.origin_z;
  156. if (!droptofloor())
  157. {
  158. dprint ("Bonus item fell out of level at ");
  159. dprint (vtos(self.origin));
  160. dprint ("\n");
  161. remove(self);
  162. return;
  163. }
  164. };
  165. /*
  166. ============
  167. StartItem
  168. Sets the clipping size and plants the object on the floor
  169. ============
  170. */
  171. void() StartItem =
  172. {
  173. self.nextthink = time + 0.2; // items start after other solids
  174. self.think = PlaceItem;
  175. };
  176. /*
  177. =========================================================================
  178. HEALTH BOX
  179. =========================================================================
  180. */
  181. //
  182. // T_Heal: add health to an entity, limiting health to max_health
  183. // "ignore" will ignore max_health limit
  184. //
  185. float (entity e, float healamount, float ignore) T_Heal =
  186. {
  187. if (e.health <= 0)
  188. return 0;
  189. if ((!ignore) && (e.health >= other.max_health))
  190. return 0;
  191. healamount = ceil(healamount);
  192. e.health = e.health + healamount;
  193. if ((!ignore) && (e.health >= other.max_health))
  194. e.health = other.max_health;
  195. if (e.health > 250)
  196. e.health = 250;
  197. return 1;
  198. };
  199. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  200. Health box. Normally gives 25 points.
  201. Rotten box heals 5-10 points,
  202. megahealth will add 100 health, then
  203. rot you down to your maximum health limit,
  204. one point per second.
  205. */
  206. float H_ROTTEN = 1;
  207. float H_MEGA = 2;
  208. .float healamount, healtype;
  209. void() health_touch;
  210. void() item_megahealth_rot;
  211. void() item_health =
  212. {
  213. self.touch = health_touch;
  214. if (self.spawnflags & H_ROTTEN)
  215. {
  216. precache_model("maps/b_bh10.bsp");
  217. precache_sound("items/r_item1.wav");
  218. setmodel(self, "maps/b_bh10.bsp");
  219. self.noise = "items/r_item1.wav";
  220. self.healamount = 15;
  221. self.healtype = 0;
  222. }
  223. else
  224. if (self.spawnflags & H_MEGA)
  225. {
  226. precache_model("maps/b_bh100.bsp");
  227. precache_sound("items/r_item2.wav");
  228. setmodel(self, "maps/b_bh100.bsp");
  229. self.noise = "items/r_item2.wav";
  230. self.healamount = 100;
  231. self.healtype = 2;
  232. }
  233. else
  234. {
  235. precache_model("maps/b_bh25.bsp");
  236. precache_sound("items/health1.wav");
  237. setmodel(self, "maps/b_bh25.bsp");
  238. self.noise = "items/health1.wav";
  239. self.healamount = 25;
  240. self.healtype = 1;
  241. }
  242. setsize (self, '0 0 0', '32 32 56');
  243. StartItem ();
  244. };
  245. void() health_touch =
  246. {
  247. local float amount;
  248. local string s;
  249. if (deathmatch == 4)
  250. if (other.invincible_time > 0)
  251. return;
  252. if (other.classname != "player")
  253. return;
  254. if (self.healtype == 2) // Megahealth? Ignore max_health...
  255. {
  256. if (other.health >= 250)
  257. return;
  258. if (!T_Heal(other, self.healamount, 1))
  259. return;
  260. }
  261. else
  262. {
  263. if (!T_Heal(other, self.healamount, 0))
  264. return;
  265. }
  266. sprint(other, PRINT_LOW, "You receive ");
  267. s = ftos(self.healamount);
  268. sprint(other, PRINT_LOW, s);
  269. sprint(other, PRINT_LOW, " health\n");
  270. // health touch sound
  271. sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  272. stuffcmd (other, "bf\n");
  273. self.model = string_null;
  274. self.solid = SOLID_NOT;
  275. // Megahealth = rot down the player's super health
  276. if (self.healtype == 2)
  277. {
  278. other.items = other.items | IT_SUPERHEALTH;
  279. if (deathmatch != 4)
  280. {
  281. self.nextthink = time + 5;
  282. self.think = item_megahealth_rot;
  283. }
  284. self.owner = other;
  285. }
  286. else
  287. {
  288. if (deathmatch != 2) // deathmatch 2 is the silly old rules
  289. {
  290. self.nextthink = time + 20;
  291. self.think = SUB_regen;
  292. }
  293. }
  294. activator = other;
  295. SUB_UseTargets(); // fire all targets / killtargets
  296. };
  297. void() item_megahealth_rot =
  298. {
  299. other = self.owner;
  300. if (other.health > other.max_health)
  301. {
  302. other.health = other.health - 1;
  303. self.nextthink = time + 1;
  304. return;
  305. }
  306. // it is possible for a player to die and respawn between rots, so don't
  307. // just blindly subtract the flag off
  308. other.items = other.items - (other.items & IT_SUPERHEALTH);
  309. if (deathmatch != 2) // deathmatch 2 is silly old rules
  310. {
  311. self.nextthink = time + 20;
  312. self.think = SUB_regen;
  313. }
  314. };
  315. /*
  316. ===============================================================================
  317. ARMOR
  318. ===============================================================================
  319. */
  320. void() armor_touch;
  321. void() armor_touch =
  322. {
  323. local float type, value, bit;
  324. if (other.health <= 0)
  325. return;
  326. if (other.classname != "player")
  327. return;
  328. if (deathmatch == 4)
  329. if (other.invincible_time > 0)
  330. return;
  331. if (self.classname == "item_armor1")
  332. {
  333. type = 0.3;
  334. value = 100;
  335. bit = IT_ARMOR1;
  336. }
  337. if (self.classname == "item_armor2")
  338. {
  339. type = 0.6;
  340. value = 150;
  341. bit = IT_ARMOR2;
  342. }
  343. if (self.classname == "item_armorInv")
  344. {
  345. type = 0.8;
  346. value = 200;
  347. bit = IT_ARMOR3;
  348. }
  349. if (other.armortype*other.armorvalue >= type*value)
  350. return;
  351. other.armortype = type;
  352. other.armorvalue = value;
  353. other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  354. self.solid = SOLID_NOT;
  355. self.model = string_null;
  356. if (deathmatch != 2)
  357. self.nextthink = time + 20;
  358. self.think = SUB_regen;
  359. sprint(other, PRINT_LOW, "You got armor\n");
  360. // armor touch sound
  361. sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  362. stuffcmd (other, "bf\n");
  363. activator = other;
  364. SUB_UseTargets(); // fire all targets / killtargets
  365. };
  366. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  367. */
  368. void() item_armor1 =
  369. {
  370. self.touch = armor_touch;
  371. precache_model ("progs/armor.mdl");
  372. setmodel (self, "progs/armor.mdl");
  373. self.skin = 0;
  374. setsize (self, '-16 -16 0', '16 16 56');
  375. StartItem ();
  376. };
  377. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  378. */
  379. void() item_armor2 =
  380. {
  381. self.touch = armor_touch;
  382. precache_model ("progs/armor.mdl");
  383. setmodel (self, "progs/armor.mdl");
  384. self.skin = 1;
  385. setsize (self, '-16 -16 0', '16 16 56');
  386. StartItem ();
  387. };
  388. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  389. */
  390. void() item_armorInv =
  391. {
  392. self.touch = armor_touch;
  393. precache_model ("progs/armor.mdl");
  394. setmodel (self, "progs/armor.mdl");
  395. self.skin = 2;
  396. setsize (self, '-16 -16 0', '16 16 56');
  397. StartItem ();
  398. };
  399. /*
  400. ===============================================================================
  401. WEAPONS
  402. ===============================================================================
  403. */
  404. void() bound_other_ammo =
  405. {
  406. if (other.ammo_shells > 100)
  407. other.ammo_shells = 100;
  408. if (other.ammo_nails > 200)
  409. other.ammo_nails = 200;
  410. if (other.ammo_rockets > 100)
  411. other.ammo_rockets = 100;
  412. if (other.ammo_cells > 100)
  413. other.ammo_cells = 100;
  414. };
  415. float(float w) RankForWeapon =
  416. {
  417. if (w == IT_LIGHTNING)
  418. return 1;
  419. if (w == IT_ROCKET_LAUNCHER)
  420. return 2;
  421. if (w == IT_SUPER_NAILGUN)
  422. return 3;
  423. if (w == IT_GRENADE_LAUNCHER)
  424. return 4;
  425. if (w == IT_SUPER_SHOTGUN)
  426. return 5;
  427. if (w == IT_NAILGUN)
  428. return 6;
  429. return 7;
  430. };
  431. float (float w) WeaponCode =
  432. {
  433. if (w == IT_SUPER_SHOTGUN)
  434. return 3;
  435. if (w == IT_NAILGUN)
  436. return 4;
  437. if (w == IT_SUPER_NAILGUN)
  438. return 5;
  439. if (w == IT_GRENADE_LAUNCHER)
  440. return 6;
  441. if (w == IT_ROCKET_LAUNCHER)
  442. return 7;
  443. if (w == IT_LIGHTNING)
  444. return 8;
  445. return 1;
  446. };
  447. /*
  448. =============
  449. Deathmatch_Weapon
  450. Deathmatch weapon change rules for picking up a weapon
  451. .float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  452. =============
  453. */
  454. void(float old, float new) Deathmatch_Weapon =
  455. {
  456. local float or, nr;
  457. // change self.weapon if desired
  458. or = RankForWeapon (self.weapon);
  459. nr = RankForWeapon (new);
  460. if ( nr < or )
  461. self.weapon = new;
  462. };
  463. /*
  464. =============
  465. weapon_touch
  466. =============
  467. */
  468. float() W_BestWeapon;
  469. void() weapon_touch =
  470. {
  471. local float hadammo, best, new, old;
  472. local entity stemp;
  473. local float leave;
  474. // For client weapon_switch
  475. local float w_switch;
  476. if (!(other.flags & FL_CLIENT))
  477. return;
  478. if ((stof(infokey(other,"w_switch"))) == 0)
  479. w_switch = 8;
  480. else
  481. w_switch = stof(infokey(other,"w_switch"));
  482. // if the player was using his best weapon, change up to the new one if better
  483. stemp = self;
  484. self = other;
  485. best = W_BestWeapon();
  486. self = stemp;
  487. if (deathmatch == 2 || deathmatch == 3 || deathmatch == 5)
  488. leave = 1;
  489. else
  490. leave = 0;
  491. if (self.classname == "weapon_nailgun")
  492. {
  493. if (leave && (other.items & IT_NAILGUN) )
  494. return;
  495. hadammo = other.ammo_nails;
  496. new = IT_NAILGUN;
  497. other.ammo_nails = other.ammo_nails + 30;
  498. }
  499. else if (self.classname == "weapon_supernailgun")
  500. {
  501. if (leave && (other.items & IT_SUPER_NAILGUN) )
  502. return;
  503. hadammo = other.ammo_rockets;
  504. new = IT_SUPER_NAILGUN;
  505. other.ammo_nails = other.ammo_nails + 30;
  506. }
  507. else if (self.classname == "weapon_supershotgun")
  508. {
  509. if (leave && (other.items & IT_SUPER_SHOTGUN) )
  510. return;
  511. hadammo = other.ammo_rockets;
  512. new = IT_SUPER_SHOTGUN;
  513. other.ammo_shells = other.ammo_shells + 5;
  514. }
  515. else if (self.classname == "weapon_rocketlauncher")
  516. {
  517. if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  518. return;
  519. hadammo = other.ammo_rockets;
  520. new = IT_ROCKET_LAUNCHER;
  521. other.ammo_rockets = other.ammo_rockets + 5;
  522. }
  523. else if (self.classname == "weapon_grenadelauncher")
  524. {
  525. if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  526. return;
  527. hadammo = other.ammo_rockets;
  528. new = IT_GRENADE_LAUNCHER;
  529. other.ammo_rockets = other.ammo_rockets + 5;
  530. }
  531. else if (self.classname == "weapon_lightning")
  532. {
  533. if (leave && (other.items & IT_LIGHTNING))
  534. return;
  535. hadammo = other.ammo_rockets;
  536. new = IT_LIGHTNING;
  537. other.ammo_cells = other.ammo_cells + 15;
  538. }
  539. else
  540. objerror ("weapon_touch: unknown classname");
  541. sprint (other, PRINT_LOW, "You got the ");
  542. sprint (other, PRINT_LOW, self.netname);
  543. sprint (other, PRINT_LOW, "\n");
  544. // weapon touch sound
  545. sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  546. stuffcmd (other, "bf\n");
  547. bound_other_ammo ();
  548. // change to the weapon
  549. old = other.items;
  550. other.items = other.items | new;
  551. stemp = self;
  552. self = other;
  553. if ( WeaponCode(new) <= w_switch )
  554. {
  555. if (self.flags & FL_INWATER)
  556. {
  557. if (new != IT_LIGHTNING)
  558. {
  559. Deathmatch_Weapon (old, new);
  560. }
  561. }
  562. else
  563. {
  564. Deathmatch_Weapon (old, new);
  565. }
  566. }
  567. W_SetCurrentAmmo();
  568. self = stemp;
  569. if (leave)
  570. return;
  571. if (deathmatch!=3 || deathmatch !=5)
  572. {
  573. // remove it in single player, or setup for respawning in deathmatch
  574. self.model = string_null;
  575. self.solid = SOLID_NOT;
  576. if (deathmatch != 2)
  577. self.nextthink = time + 30;
  578. self.think = SUB_regen;
  579. }
  580. activator = other;
  581. SUB_UseTargets(); // fire all targets / killtargets
  582. };
  583. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  584. */
  585. void() weapon_supershotgun =
  586. {
  587. if (deathmatch <= 3)
  588. {
  589. precache_model ("progs/g_shot.mdl");
  590. setmodel (self, "progs/g_shot.mdl");
  591. self.weapon = IT_SUPER_SHOTGUN;
  592. self.netname = "Double-barrelled Shotgun";
  593. self.touch = weapon_touch;
  594. setsize (self, '-16 -16 0', '16 16 56');
  595. StartItem ();
  596. }
  597. };
  598. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  599. */
  600. void() weapon_nailgun =
  601. {
  602. if (deathmatch <= 3)
  603. {
  604. precache_model ("progs/g_nail.mdl");
  605. setmodel (self, "progs/g_nail.mdl");
  606. self.weapon = IT_NAILGUN;
  607. self.netname = "nailgun";
  608. self.touch = weapon_touch;
  609. setsize (self, '-16 -16 0', '16 16 56');
  610. StartItem ();
  611. }
  612. };
  613. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  614. */
  615. void() weapon_supernailgun =
  616. {
  617. if (deathmatch <= 3)
  618. {
  619. precache_model ("progs/g_nail2.mdl");
  620. setmodel (self, "progs/g_nail2.mdl");
  621. self.weapon = IT_SUPER_NAILGUN;
  622. self.netname = "Super Nailgun";
  623. self.touch = weapon_touch;
  624. setsize (self, '-16 -16 0', '16 16 56');
  625. StartItem ();
  626. }
  627. };
  628. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  629. */
  630. void() weapon_grenadelauncher =
  631. {
  632. if (deathmatch <= 3)
  633. {
  634. precache_model ("progs/g_rock.mdl");
  635. setmodel (self, "progs/g_rock.mdl");
  636. self.weapon = 3;
  637. self.netname = "Grenade Launcher";
  638. self.touch = weapon_touch;
  639. setsize (self, '-16 -16 0', '16 16 56');
  640. StartItem ();
  641. }
  642. };
  643. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  644. */
  645. void() weapon_rocketlauncher =
  646. {
  647. if (deathmatch <= 3)
  648. {
  649. precache_model ("progs/g_rock2.mdl");
  650. setmodel (self, "progs/g_rock2.mdl");
  651. self.weapon = 3;
  652. self.netname = "Rocket Launcher";
  653. self.touch = weapon_touch;
  654. setsize (self, '-16 -16 0', '16 16 56');
  655. StartItem ();
  656. }
  657. };
  658. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  659. */
  660. void() weapon_lightning =
  661. {
  662. if (deathmatch <= 3)
  663. {
  664. precache_model ("progs/g_light.mdl");
  665. setmodel (self, "progs/g_light.mdl");
  666. self.weapon = 3;
  667. self.netname = "Thunderbolt";
  668. self.touch = weapon_touch;
  669. setsize (self, '-16 -16 0', '16 16 56');
  670. StartItem ();
  671. }
  672. };
  673. /*
  674. ===============================================================================
  675. AMMO
  676. ===============================================================================
  677. */
  678. void() ammo_touch =
  679. {
  680. local entity stemp;
  681. local float best;
  682. if (other.classname != "player")
  683. return;
  684. if (other.health <= 0)
  685. return;
  686. // if the player was using his best weapon, change up to the new one if better
  687. stemp = self;
  688. self = other;
  689. best = W_BestWeapon();
  690. self = stemp;
  691. // shotgun
  692. if (self.weapon == 1)
  693. {
  694. if (other.ammo_shells >= 100)
  695. return;
  696. other.ammo_shells = other.ammo_shells + self.aflag;
  697. }
  698. // spikes
  699. if (self.weapon == 2)
  700. {
  701. if (other.ammo_nails >= 200)
  702. return;
  703. other.ammo_nails = other.ammo_nails + self.aflag;
  704. }
  705. // rockets
  706. if (self.weapon == 3)
  707. {
  708. if (other.ammo_rockets >= 100)
  709. return;
  710. other.ammo_rockets = other.ammo_rockets + self.aflag;
  711. }
  712. // cells
  713. if (self.weapon == 4)
  714. {
  715. if (other.ammo_cells >= 100)
  716. return;
  717. other.ammo_cells = other.ammo_cells + self.aflag;
  718. }
  719. bound_other_ammo ();
  720. sprint (other, PRINT_LOW, "You got the ");
  721. sprint (other, PRINT_LOW, self.netname);
  722. sprint (other, PRINT_LOW, "\n");
  723. // ammo touch sound
  724. sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  725. stuffcmd (other, "bf\n");
  726. // change to a better weapon if appropriate
  727. if ( other.weapon == best )
  728. {
  729. stemp = self;
  730. self = other;
  731. self.weapon = W_BestWeapon();
  732. W_SetCurrentAmmo ();
  733. self = stemp;
  734. }
  735. // if changed current ammo, update it
  736. stemp = self;
  737. self = other;
  738. W_SetCurrentAmmo();
  739. self = stemp;
  740. // remove it in single player, or setup for respawning in deathmatch
  741. self.model = string_null;
  742. self.solid = SOLID_NOT;
  743. if (deathmatch != 2)
  744. self.nextthink = time + 30;
  745. // Xian -- If playing in DM 3.0 mode, halve the time ammo respawns
  746. if (deathmatch == 3 || deathmatch == 5)
  747. self.nextthink = time + 15;
  748. self.think = SUB_regen;
  749. activator = other;
  750. SUB_UseTargets(); // fire all targets / killtargets
  751. };
  752. float WEAPON_BIG2 = 1;
  753. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  754. */
  755. void() item_shells =
  756. {
  757. if (deathmatch == 4)
  758. return;
  759. self.touch = ammo_touch;
  760. if (self.spawnflags & WEAPON_BIG2)
  761. {
  762. precache_model ("maps/b_shell1.bsp");
  763. setmodel (self, "maps/b_shell1.bsp");
  764. self.aflag = 40;
  765. }
  766. else
  767. {
  768. precache_model ("maps/b_shell0.bsp");
  769. setmodel (self, "maps/b_shell0.bsp");
  770. self.aflag = 20;
  771. }
  772. self.weapon = 1;
  773. self.netname = "shells";
  774. setsize (self, '0 0 0', '32 32 56');
  775. StartItem ();
  776. };
  777. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  778. */
  779. void() item_spikes =
  780. {
  781. if (deathmatch == 4)
  782. return;
  783. self.touch = ammo_touch;
  784. if (self.spawnflags & WEAPON_BIG2)
  785. {
  786. precache_model ("maps/b_nail1.bsp");
  787. setmodel (self, "maps/b_nail1.bsp");
  788. self.aflag = 50;
  789. }
  790. else
  791. {
  792. precache_model ("maps/b_nail0.bsp");
  793. setmodel (self, "maps/b_nail0.bsp");
  794. self.aflag = 25;
  795. }
  796. self.weapon = 2;
  797. self.netname = "nails";
  798. setsize (self, '0 0 0', '32 32 56');
  799. StartItem ();
  800. };
  801. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  802. */
  803. void() item_rockets =
  804. {
  805. if (deathmatch == 4)
  806. return;
  807. self.touch = ammo_touch;
  808. if (self.spawnflags & WEAPON_BIG2)
  809. {
  810. precache_model ("maps/b_rock1.bsp");
  811. setmodel (self, "maps/b_rock1.bsp");
  812. self.aflag = 10;
  813. }
  814. else
  815. {
  816. precache_model ("maps/b_rock0.bsp");
  817. setmodel (self, "maps/b_rock0.bsp");
  818. self.aflag = 5;
  819. }
  820. self.weapon = 3;
  821. self.netname = "rockets";
  822. setsize (self, '0 0 0', '32 32 56');
  823. StartItem ();
  824. };
  825. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  826. */
  827. void() item_cells =
  828. {
  829. if (deathmatch == 4)
  830. return;
  831. self.touch = ammo_touch;
  832. if (self.spawnflags & WEAPON_BIG2)
  833. {
  834. precache_model ("maps/b_batt1.bsp");
  835. setmodel (self, "maps/b_batt1.bsp");
  836. self.aflag = 12;
  837. }
  838. else
  839. {
  840. precache_model ("maps/b_batt0.bsp");
  841. setmodel (self, "maps/b_batt0.bsp");
  842. self.aflag = 6;
  843. }
  844. self.weapon = 4;
  845. self.netname = "cells";
  846. setsize (self, '0 0 0', '32 32 56');
  847. StartItem ();
  848. };
  849. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  850. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  851. */
  852. float WEAPON_SHOTGUN = 1;
  853. float WEAPON_ROCKET = 2;
  854. float WEAPON_SPIKES = 4;
  855. float WEAPON_BIG = 8;
  856. void() item_weapon =
  857. {
  858. self.touch = ammo_touch;
  859. if (self.spawnflags & WEAPON_SHOTGUN)
  860. {
  861. if (self.spawnflags & WEAPON_BIG)
  862. {
  863. precache_model ("maps/b_shell1.bsp");
  864. setmodel (self, "maps/b_shell1.bsp");
  865. self.aflag = 40;
  866. }
  867. else
  868. {
  869. precache_model ("maps/b_shell0.bsp");
  870. setmodel (self, "maps/b_shell0.bsp");
  871. self.aflag = 20;
  872. }
  873. self.weapon = 1;
  874. self.netname = "shells";
  875. }
  876. if (self.spawnflags & WEAPON_SPIKES)
  877. {
  878. if (self.spawnflags & WEAPON_BIG)
  879. {
  880. precache_model ("maps/b_nail1.bsp");
  881. setmodel (self, "maps/b_nail1.bsp");
  882. self.aflag = 40;
  883. }
  884. else
  885. {
  886. precache_model ("maps/b_nail0.bsp");
  887. setmodel (self, "maps/b_nail0.bsp");
  888. self.aflag = 20;
  889. }
  890. self.weapon = 2;
  891. self.netname = "spikes";
  892. }
  893. if (self.spawnflags & WEAPON_ROCKET)
  894. {
  895. if (self.spawnflags & WEAPON_BIG)
  896. {
  897. precache_model ("maps/b_rock1.bsp");
  898. setmodel (self, "maps/b_rock1.bsp");
  899. self.aflag = 10;
  900. }
  901. else
  902. {
  903. precache_model ("maps/b_rock0.bsp");
  904. setmodel (self, "maps/b_rock0.bsp");
  905. self.aflag = 5;
  906. }
  907. self.weapon = 3;
  908. self.netname = "rockets";
  909. }
  910. setsize (self, '0 0 0', '32 32 56');
  911. StartItem ();
  912. };
  913. /*
  914. ===============================================================================
  915. KEYS
  916. ===============================================================================
  917. */
  918. void() key_touch =
  919. {
  920. local entity stemp;
  921. local float best;
  922. if (other.classname != "player")
  923. return;
  924. if (other.health <= 0)
  925. return;
  926. if (other.items & self.items)
  927. return;
  928. sprint (other, PRINT_LOW, "You got the ");
  929. sprint (other, PRINT_LOW, self.netname);
  930. sprint (other,PRINT_LOW, "\n");
  931. sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  932. stuffcmd (other, "bf\n");
  933. other.items = other.items | self.items;
  934. self.solid = SOLID_NOT;
  935. self.model = string_null;
  936. activator = other;
  937. SUB_UseTargets(); // fire all targets / killtargets
  938. };
  939. void() key_setsounds =
  940. {
  941. if (world.worldtype == 0)
  942. {
  943. precache_sound ("misc/medkey.wav");
  944. self.noise = "misc/medkey.wav";
  945. }
  946. if (world.worldtype == 1)
  947. {
  948. precache_sound ("misc/runekey.wav");
  949. self.noise = "misc/runekey.wav";
  950. }
  951. if (world.worldtype == 2)
  952. {
  953. precache_sound2 ("misc/basekey.wav");
  954. self.noise = "misc/basekey.wav";
  955. }
  956. };
  957. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  958. SILVER key
  959. In order for keys to work
  960. you MUST set your maps
  961. worldtype to one of the
  962. following:
  963. 0: medieval
  964. 1: metal
  965. 2: base
  966. */
  967. void() item_key1 =
  968. {
  969. if (world.worldtype == 0)
  970. {
  971. precache_model ("progs/w_s_key.mdl");
  972. setmodel (self, "progs/w_s_key.mdl");
  973. self.netname = "silver key";
  974. }
  975. else if (world.worldtype == 1)
  976. {
  977. precache_model ("progs/m_s_key.mdl");
  978. setmodel (self, "progs/m_s_key.mdl");
  979. self.netname = "silver runekey";
  980. }
  981. else if (world.worldtype == 2)
  982. {
  983. precache_model2 ("progs/b_s_key.mdl");
  984. setmodel (self, "progs/b_s_key.mdl");
  985. self.netname = "silver keycard";
  986. }
  987. key_setsounds();
  988. self.touch = key_touch;
  989. self.items = IT_KEY1;
  990. setsize (self, '-16 -16 -24', '16 16 32');
  991. StartItem ();
  992. };
  993. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  994. GOLD key
  995. In order for keys to work
  996. you MUST set your maps
  997. worldtype to one of the
  998. following:
  999. 0: medieval
  1000. 1: metal
  1001. 2: base
  1002. */
  1003. void() item_key2 =
  1004. {
  1005. if (world.worldtype == 0)
  1006. {
  1007. precache_model ("progs/w_g_key.mdl");
  1008. setmodel (self, "progs/w_g_key.mdl");
  1009. self.netname = "gold key";
  1010. }
  1011. if (world.worldtype == 1)
  1012. {
  1013. precache_model ("progs/m_g_key.mdl");
  1014. setmodel (self, "progs/m_g_key.mdl");
  1015. self.netname = "gold runekey";
  1016. }
  1017. if (world.worldtype == 2)
  1018. {
  1019. precache_model2 ("progs/b_g_key.mdl");
  1020. setmodel (self, "progs/b_g_key.mdl");
  1021. self.netname = "gold keycard";
  1022. }
  1023. key_setsounds();
  1024. self.touch = key_touch;
  1025. self.items = IT_KEY2;
  1026. setsize (self, '-16 -16 -24', '16 16 32');
  1027. StartItem ();
  1028. };
  1029. /*
  1030. ===============================================================================
  1031. END OF LEVEL RUNES
  1032. ===============================================================================
  1033. */
  1034. void() sigil_touch =
  1035. {
  1036. local entity stemp;
  1037. local float best;
  1038. if (other.classname != "player")
  1039. return;
  1040. if (other.health <= 0)
  1041. return;
  1042. centerprint (other, "You got the rune!");
  1043. sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1044. stuffcmd (other, "bf\n");
  1045. self.solid = SOLID_NOT;
  1046. self.model = string_null;
  1047. serverflags = serverflags | (self.spawnflags & 15);
  1048. self.classname = ""; // so rune doors won't find it
  1049. activator = other;
  1050. SUB_UseTargets(); // fire all targets / killtargets
  1051. };
  1052. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1053. End of level sigil, pick up to end episode and return to jrstart.
  1054. */
  1055. void() item_sigil =
  1056. {
  1057. if (!self.spawnflags)
  1058. objerror ("no spawnflags");
  1059. precache_sound ("misc/runekey.wav");
  1060. self.noise = "misc/runekey.wav";
  1061. if (self.spawnflags & 1)
  1062. {
  1063. precache_model ("progs/end1.mdl");
  1064. setmodel (self, "progs/end1.mdl");
  1065. }
  1066. if (self.spawnflags & 2)
  1067. {
  1068. precache_model2 ("progs/end2.mdl");
  1069. setmodel (self, "progs/end2.mdl");
  1070. }
  1071. if (self.spawnflags & 4)
  1072. {
  1073. precache_model2 ("progs/end3.mdl");
  1074. setmodel (self, "progs/end3.mdl");
  1075. }
  1076. if (self.spawnflags & 8)
  1077. {
  1078. precache_model2 ("progs/end4.mdl");
  1079. setmodel (self, "progs/end4.mdl");
  1080. }
  1081. self.touch = sigil_touch;
  1082. setsize (self, '-16 -16 -24', '16 16 32');
  1083. StartItem ();
  1084. };
  1085. /*
  1086. ===============================================================================
  1087. POWERUPS
  1088. ===============================================================================
  1089. */
  1090. void() powerup_touch;
  1091. void() powerup_touch =
  1092. {
  1093. local entity stemp;
  1094. local float best;
  1095. if (other.classname != "player")
  1096. return;
  1097. if (other.health <= 0)
  1098. return;
  1099. sprint (other, PRINT_LOW, "You got the ");
  1100. sprint (other,PRINT_LOW, self.netname);
  1101. sprint (other,PRINT_LOW, "\n");
  1102. self.mdl = self.model;
  1103. if ((self.classname == "item_artifact_invulnerability") ||
  1104. (self.classname == "item_artifact_invisibility"))
  1105. self.nextthink = time + 60*5;
  1106. else
  1107. self.nextthink = time + 60;
  1108. self.think = SUB_regen;
  1109. sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1110. stuffcmd (other, "bf\n");
  1111. self.solid = SOLID_NOT;
  1112. other.items = other.items | self.items;
  1113. self.model = string_null;
  1114. // do the apropriate action
  1115. if (self.classname == "item_artifact_envirosuit")
  1116. {
  1117. other.rad_time = 1;
  1118. other.radsuit_finished = time + 30;
  1119. }
  1120. if (self.classname == "item_artifact_invulnerability")
  1121. {
  1122. other.invincible_time = 1;
  1123. other.invincible_finished = time + 30;
  1124. }
  1125. if (self.classname == "item_artifact_invisibility")
  1126. {
  1127. other.invisible_time = 1;
  1128. other.invisible_finished = time + 30;
  1129. }
  1130. if (self.classname == "item_artifact_super_damage")
  1131. {
  1132. if (deathmatch == 4)
  1133. {
  1134. other.armortype = 0;
  1135. other.armorvalue = 0 * 0.01;
  1136. other.ammo_cells = 0;
  1137. }
  1138. other.super_time = 1;
  1139. other.super_damage_finished = time + 30;
  1140. }
  1141. activator = other;
  1142. SUB_UseTargets(); // fire all targets / killtargets
  1143. };
  1144. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1145. Player is invulnerable for 30 seconds
  1146. */
  1147. void() item_artifact_invulnerability =
  1148. {
  1149. self.touch = powerup_touch;
  1150. precache_model ("progs/invulner.mdl");
  1151. precache_sound ("items/protect.wav");
  1152. precache_sound ("items/protect2.wav");
  1153. precache_sound ("items/protect3.wav");
  1154. self.noise = "items/protect.wav";
  1155. setmodel (self, "progs/invulner.mdl");
  1156. self.netname = "Pentagram of Protection";
  1157. self.effects = self.effects | EF_RED;
  1158. self.items = IT_INVULNERABILITY;
  1159. setsize (self, '-16 -16 -24', '16 16 32');
  1160. StartItem ();
  1161. };
  1162. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1163. Player takes no damage from water or slime for 30 seconds
  1164. */
  1165. void() item_artifact_envirosuit =
  1166. {
  1167. self.touch = powerup_touch;
  1168. precache_model ("progs/suit.mdl");
  1169. precache_sound ("items/suit.wav");
  1170. precache_sound ("items/suit2.wav");
  1171. self.noise = "items/suit.wav";
  1172. setmodel (self, "progs/suit.mdl");
  1173. self.netname = "Biosuit";
  1174. self.items = IT_SUIT;
  1175. setsize (self, '-16 -16 -24', '16 16 32');
  1176. StartItem ();
  1177. };
  1178. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1179. Player is invisible for 30 seconds
  1180. */
  1181. void() item_artifact_invisibility =
  1182. {
  1183. self.touch = powerup_touch;
  1184. precache_model ("progs/invisibl.mdl");
  1185. precache_sound ("items/inv1.wav");
  1186. precache_sound ("items/inv2.wav");
  1187. precache_sound ("items/inv3.wav");
  1188. self.noise = "items/inv1.wav";
  1189. setmodel (self, "progs/invisibl.mdl");
  1190. self.netname = "Ring of Shadows";
  1191. self.items = IT_INVISIBILITY;
  1192. setsize (self, '-16 -16 -24', '16 16 32');
  1193. StartItem ();
  1194. };
  1195. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1196. The next attack from the player will do 4x damage
  1197. */
  1198. void() item_artifact_super_damage =
  1199. {
  1200. self.touch = powerup_touch;
  1201. precache_model ("progs/quaddama.mdl");
  1202. precache_sound ("items/damage.wav");
  1203. precache_sound ("items/damage2.wav");
  1204. precache_sound ("items/damage3.wav");
  1205. self.noise = "items/damage.wav";
  1206. setmodel (self, "progs/quaddama.mdl");
  1207. if (deathmatch == 4)
  1208. self.netname = "OctaPower";
  1209. else
  1210. self.netname = "Quad Damage";
  1211. self.items = IT_QUAD;
  1212. self.effects = self.effects | EF_BLUE;
  1213. setsize (self, '-16 -16 -24', '16 16 32');
  1214. StartItem ();
  1215. };
  1216. /*
  1217. ===============================================================================
  1218. PLAYER BACKPACKS
  1219. ===============================================================================
  1220. */
  1221. void() BackpackTouch =
  1222. {
  1223. local string s;
  1224. local float best, old, new;
  1225. local entity stemp;
  1226. local float acount;
  1227. local float b_switch;
  1228. if (deathmatch == 4)
  1229. if (other.invincible_time > 0)
  1230. return;
  1231. if ((stof(infokey(other,"b_switch"))) == 0)
  1232. b_switch = 8;
  1233. else
  1234. b_switch = stof(infokey(other,"b_switch"));
  1235. if (other.classname != "player")
  1236. return;
  1237. if (other.health <= 0)
  1238. return;
  1239. acount = 0;
  1240. sprint (other, PRINT_LOW, "You get ");
  1241. if (deathmatch == 4)
  1242. {
  1243. other.health = other.health + 10;
  1244. sprint (other, PRINT_LOW, "10 additional health\n");
  1245. if ((other.health > 250) && (other.health < 300))
  1246. sound (other, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  1247. else
  1248. sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1249. stuffcmd (other, "bf\n");
  1250. remove(self);
  1251. if (other.health >299)
  1252. {
  1253. if (other.invincible_time != 1)
  1254. {
  1255. other.invincible_time = 1;
  1256. other.invincible_finished = time + 30;
  1257. other.items = other.items | IT_INVULNERABILITY;
  1258. other.super_time = 1;
  1259. other.super_damage_finished = time + 30;
  1260. other.items = other.items | IT_QUAD;
  1261. other.ammo_cells = 0;
  1262. sound (other, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
  1263. stuffcmd (other, "bf\n");
  1264. bprint (PRINT_HIGH, other.netname);
  1265. bprint (PRINT_HIGH, " attains bonus powers!!!\n");
  1266. }
  1267. }
  1268. self = other;
  1269. return;
  1270. }
  1271. if (self.items)
  1272. if ((other.items & self.items) == 0)
  1273. {
  1274. acount = 1;
  1275. sprint (other, PRINT_LOW, "the ");
  1276. sprint (other, PRINT_LOW, self.netname);
  1277. }
  1278. // if the player was using his best weapon, change up to the new one if better
  1279. stemp = self;
  1280. self = other;
  1281. best = W_BestWeapon();
  1282. self = stemp;
  1283. // change weapons
  1284. other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1285. other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1286. other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1287. other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1288. new = self.items;
  1289. if (!new)
  1290. new = other.weapon;
  1291. old = other.items;
  1292. other.items = other.items | self.items;
  1293. bound_other_ammo ();
  1294. if (self.ammo_shells)
  1295. {
  1296. if (acount)
  1297. sprint(other, PRINT_LOW, ", ");
  1298. acount = 1;
  1299. s = ftos(self.ammo_shells);
  1300. sprint (other, PRINT_LOW, s);
  1301. sprint (other, PRINT_LOW, " shells");
  1302. }
  1303. if (self.ammo_nails)
  1304. {
  1305. if (acount)
  1306. sprint(other, PRINT_LOW, ", ");
  1307. acount = 1;
  1308. s = ftos(self.ammo_nails);
  1309. sprint (other, PRINT_LOW, s);
  1310. sprint (other, PRINT_LOW, " nails");
  1311. }
  1312. if (self.ammo_rockets)
  1313. {
  1314. if (acount)
  1315. sprint(other, PRINT_LOW, ", ");
  1316. acount = 1;
  1317. s = ftos(self.ammo_rockets);
  1318. sprint (other, PRINT_LOW, s);
  1319. sprint (other, PRINT_LOW, " rockets");
  1320. }
  1321. if (self.ammo_cells)
  1322. {
  1323. if (acount)
  1324. sprint(other, PRINT_LOW, ", ");
  1325. acount = 1;
  1326. s = ftos(self.ammo_cells);
  1327. sprint (other, PRINT_LOW, s);
  1328. sprint (other,PRINT_LOW, " cells");
  1329. }
  1330. if ( (deathmatch==3 || deathmatch == 5) & ( (WeaponCode(new)==6) || (WeaponCode(new)==7) ) & (other.ammo_rockets < 5) )
  1331. other.ammo_rockets = 5;
  1332. sprint (other, PRINT_LOW, "\n");
  1333. // backpack touch sound
  1334. sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1335. stuffcmd (other, "bf\n");
  1336. remove(self);
  1337. self = other;
  1338. // change to the weapon
  1339. if ( WeaponCode(new) <= b_switch )
  1340. {
  1341. if (self.flags & FL_INWATER)
  1342. {
  1343. if (new != IT_LIGHTNING)
  1344. {
  1345. Deathmatch_Weapon (old, new);
  1346. }
  1347. }
  1348. else
  1349. {
  1350. Deathmatch_Weapon (old, new);
  1351. }
  1352. }
  1353. W_SetCurrentAmmo ();
  1354. };
  1355. /*
  1356. ===============
  1357. DropBackpack
  1358. ===============
  1359. */
  1360. void() DropBackpack =
  1361. {
  1362. local entity item;
  1363. if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1364. return; // nothing in it
  1365. item = spawn();
  1366. item.origin = self.origin - '0 0 24';
  1367. item.items = self.weapon;
  1368. if (item.items == IT_AXE)
  1369. item.netname = "Axe";
  1370. else if (item.items == IT_SHOTGUN)
  1371. item.netname = "Shotgun";
  1372. else if (item.items == IT_SUPER_SHOTGUN)
  1373. item.netname = "Double-barrelled Shotgun";
  1374. else if (item.items == IT_NAILGUN)
  1375. item.netname = "Nailgun";
  1376. else if (item.items == IT_SUPER_NAILGUN)
  1377. item.netname = "Super Nailgun";
  1378. else if (item.items == IT_GRENADE_LAUNCHER)
  1379. item.netname = "Grenade Launcher";
  1380. else if (item.items == IT_ROCKET_LAUNCHER)
  1381. item.netname = "Rocket Launcher";
  1382. else if (item.items == IT_LIGHTNING)
  1383. item.netname = "Thunderbolt";
  1384. else
  1385. item.netname = "";
  1386. item.ammo_shells = self.ammo_shells;
  1387. item.ammo_nails = self.ammo_nails;
  1388. item.ammo_rockets = self.ammo_rockets;
  1389. item.ammo_cells = self.ammo_cells;
  1390. item.velocity_z = 300;
  1391. item.velocity_x = -100 + (random() * 200);
  1392. item.velocity_y = -100 + (random() * 200);
  1393. item.flags = FL_ITEM;
  1394. item.solid = SOLID_TRIGGER;
  1395. item.movetype = MOVETYPE_TOSS;
  1396. setmodel (item, "progs/backpack.mdl");
  1397. setsize (item, '-16 -16 0', '16 16 56');
  1398. item.touch = BackpackTouch;
  1399. item.nextthink = time + 120; // remove after 2 minutes
  1400. item.think = SUB_Remove;
  1401. };