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