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