|
|
1.1.1.4 ! root 1: /* ! 2: Copyright (C) 1997-2001 Id Software, Inc. ! 3: ! 4: This program is free software; you can redistribute it and/or ! 5: modify it under the terms of the GNU General Public License ! 6: as published by the Free Software Foundation; either version 2 ! 7: of the License, or (at your option) any later version. ! 8: ! 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: ! 13: See the GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with this program; if not, write to the Free Software ! 17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! 18: ! 19: */ 1.1 root 20: #include "g_local.h" 21: 22: 23: qboolean Pickup_Weapon (edict_t *ent, edict_t *other); 24: void Use_Weapon (edict_t *ent, gitem_t *inv); 25: void Drop_Weapon (edict_t *ent, gitem_t *inv); 26: 27: void Weapon_Blaster (edict_t *ent); 28: void Weapon_Shotgun (edict_t *ent); 29: void Weapon_SuperShotgun (edict_t *ent); 30: void Weapon_Machinegun (edict_t *ent); 31: void Weapon_Chaingun (edict_t *ent); 32: void Weapon_HyperBlaster (edict_t *ent); 33: void Weapon_RocketLauncher (edict_t *ent); 34: void Weapon_Grenade (edict_t *ent); 35: void Weapon_GrenadeLauncher (edict_t *ent); 36: void Weapon_Railgun (edict_t *ent); 37: void Weapon_BFG (edict_t *ent); 38: 39: gitem_armor_t jacketarmor_info = { 25, 50, .30, .00, ARMOR_JACKET}; 40: gitem_armor_t combatarmor_info = { 50, 100, .60, .30, ARMOR_COMBAT}; 41: gitem_armor_t bodyarmor_info = {100, 200, .80, .60, ARMOR_BODY}; 42: 43: static int jacket_armor_index; 44: static int combat_armor_index; 45: static int body_armor_index; 46: static int power_screen_index; 47: static int power_shield_index; 48: 49: #define HEALTH_IGNORE_MAX 1 50: #define HEALTH_TIMED 2 51: 52: void Use_Quad (edict_t *ent, gitem_t *item); 53: static int quad_drop_timeout_hack; 54: 55: //====================================================================== 56: 57: /* 58: =============== 59: GetItemByIndex 60: =============== 61: */ 62: gitem_t *GetItemByIndex (int index) 63: { 64: if (index == 0 || index >= game.num_items) 65: return NULL; 66: 67: return &itemlist[index]; 68: } 69: 70: 71: /* 72: =============== 73: FindItemByClassname 74: 75: =============== 76: */ 77: gitem_t *FindItemByClassname (char *classname) 78: { 79: int i; 80: gitem_t *it; 81: 82: it = itemlist; 83: for (i=0 ; i<game.num_items ; i++, it++) 84: { 85: if (!it->classname) 86: continue; 87: if (!Q_stricmp(it->classname, classname)) 88: return it; 89: } 90: 91: return NULL; 92: } 93: 94: /* 95: =============== 96: FindItem 97: 98: =============== 99: */ 100: gitem_t *FindItem (char *pickup_name) 101: { 102: int i; 103: gitem_t *it; 104: 105: it = itemlist; 106: for (i=0 ; i<game.num_items ; i++, it++) 107: { 108: if (!it->pickup_name) 109: continue; 110: if (!Q_stricmp(it->pickup_name, pickup_name)) 111: return it; 112: } 113: 114: return NULL; 115: } 116: 117: //====================================================================== 118: 119: void DoRespawn (edict_t *ent) 120: { 121: if (ent->team) 122: { 123: edict_t *master; 124: int count; 125: int choice; 126: 127: master = ent->teammaster; 128: 129: for (count = 0, ent = master; ent; ent = ent->chain, count++) 130: ; 131: 132: choice = rand() % count; 133: 134: for (count = 0, ent = master; count < choice; ent = ent->chain, count++) 135: ; 136: } 137: 138: ent->svflags &= ~SVF_NOCLIENT; 139: ent->solid = SOLID_TRIGGER; 140: gi.linkentity (ent); 141: 142: // send an effect 143: ent->s.event = EV_ITEM_RESPAWN; 144: } 145: 146: void SetRespawn (edict_t *ent, float delay) 147: { 148: ent->flags |= FL_RESPAWN; 149: ent->svflags |= SVF_NOCLIENT; 150: ent->solid = SOLID_NOT; 151: ent->nextthink = level.time + delay; 152: ent->think = DoRespawn; 153: gi.linkentity (ent); 154: } 155: 156: 157: //====================================================================== 158: 159: qboolean Pickup_Powerup (edict_t *ent, edict_t *other) 160: { 161: int quantity; 162: 163: quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)]; 164: if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1)) 165: return false; 166: 167: if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0)) 168: return false; 169: 170: other->client->pers.inventory[ITEM_INDEX(ent->item)]++; 171: 172: if (deathmatch->value) 173: { 174: if (!(ent->spawnflags & DROPPED_ITEM) ) 175: SetRespawn (ent, ent->item->quantity); 176: if (((int)dmflags->value & DF_INSTANT_ITEMS) || ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM))) 177: { 178: if ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM)) 179: quad_drop_timeout_hack = (ent->nextthink - level.time) / FRAMETIME; 180: ent->item->use (other, ent->item); 181: } 182: } 183: 184: return true; 185: } 186: 187: void Drop_General (edict_t *ent, gitem_t *item) 188: { 189: Drop_Item (ent, item); 190: ent->client->pers.inventory[ITEM_INDEX(item)]--; 191: ValidateSelectedItem (ent); 192: } 193: 194: 195: //====================================================================== 196: 197: qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other) 198: { 199: if (!deathmatch->value) 200: other->max_health += 1; 201: 202: if (other->health < other->max_health) 203: other->health = other->max_health; 204: 205: if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) 206: SetRespawn (ent, ent->item->quantity); 207: 208: return true; 209: } 210: 211: qboolean Pickup_AncientHead (edict_t *ent, edict_t *other) 212: { 213: other->max_health += 2; 214: 215: if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) 216: SetRespawn (ent, ent->item->quantity); 217: 218: return true; 219: } 220: 221: qboolean Pickup_Bandolier (edict_t *ent, edict_t *other) 222: { 223: gitem_t *item; 224: int index; 225: 226: if (other->client->pers.max_bullets < 250) 227: other->client->pers.max_bullets = 250; 228: if (other->client->pers.max_shells < 150) 229: other->client->pers.max_shells = 150; 230: if (other->client->pers.max_cells < 250) 231: other->client->pers.max_cells = 250; 232: if (other->client->pers.max_slugs < 75) 233: other->client->pers.max_slugs = 75; 234: 235: item = FindItem("Bullets"); 236: if (item) 237: { 238: index = ITEM_INDEX(item); 239: other->client->pers.inventory[index] += item->quantity; 240: if (other->client->pers.inventory[index] > other->client->pers.max_bullets) 241: other->client->pers.inventory[index] = other->client->pers.max_bullets; 242: } 243: 244: item = FindItem("Shells"); 245: if (item) 246: { 247: index = ITEM_INDEX(item); 248: other->client->pers.inventory[index] += item->quantity; 249: if (other->client->pers.inventory[index] > other->client->pers.max_shells) 250: other->client->pers.inventory[index] = other->client->pers.max_shells; 251: } 252: 253: if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) 254: SetRespawn (ent, ent->item->quantity); 255: 256: return true; 257: } 258: 259: qboolean Pickup_Pack (edict_t *ent, edict_t *other) 260: { 261: gitem_t *item; 262: int index; 263: 264: if (other->client->pers.max_bullets < 300) 265: other->client->pers.max_bullets = 300; 266: if (other->client->pers.max_shells < 200) 267: other->client->pers.max_shells = 200; 268: if (other->client->pers.max_rockets < 100) 269: other->client->pers.max_rockets = 100; 270: if (other->client->pers.max_grenades < 100) 271: other->client->pers.max_grenades = 100; 272: if (other->client->pers.max_cells < 300) 273: other->client->pers.max_cells = 300; 274: if (other->client->pers.max_slugs < 100) 275: other->client->pers.max_slugs = 100; 276: 277: item = FindItem("Bullets"); 278: if (item) 279: { 280: index = ITEM_INDEX(item); 281: other->client->pers.inventory[index] += item->quantity; 282: if (other->client->pers.inventory[index] > other->client->pers.max_bullets) 283: other->client->pers.inventory[index] = other->client->pers.max_bullets; 284: } 285: 286: item = FindItem("Shells"); 287: if (item) 288: { 289: index = ITEM_INDEX(item); 290: other->client->pers.inventory[index] += item->quantity; 291: if (other->client->pers.inventory[index] > other->client->pers.max_shells) 292: other->client->pers.inventory[index] = other->client->pers.max_shells; 293: } 294: 295: item = FindItem("Cells"); 296: if (item) 297: { 298: index = ITEM_INDEX(item); 299: other->client->pers.inventory[index] += item->quantity; 300: if (other->client->pers.inventory[index] > other->client->pers.max_cells) 301: other->client->pers.inventory[index] = other->client->pers.max_cells; 302: } 303: 304: item = FindItem("Grenades"); 305: if (item) 306: { 307: index = ITEM_INDEX(item); 308: other->client->pers.inventory[index] += item->quantity; 309: if (other->client->pers.inventory[index] > other->client->pers.max_grenades) 310: other->client->pers.inventory[index] = other->client->pers.max_grenades; 311: } 312: 313: item = FindItem("Rockets"); 314: if (item) 315: { 316: index = ITEM_INDEX(item); 317: other->client->pers.inventory[index] += item->quantity; 318: if (other->client->pers.inventory[index] > other->client->pers.max_rockets) 319: other->client->pers.inventory[index] = other->client->pers.max_rockets; 320: } 321: 322: item = FindItem("Slugs"); 323: if (item) 324: { 325: index = ITEM_INDEX(item); 326: other->client->pers.inventory[index] += item->quantity; 327: if (other->client->pers.inventory[index] > other->client->pers.max_slugs) 328: other->client->pers.inventory[index] = other->client->pers.max_slugs; 329: } 330: 331: if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) 332: SetRespawn (ent, ent->item->quantity); 333: 334: return true; 335: } 336: 337: //====================================================================== 338: 339: void Use_Quad (edict_t *ent, gitem_t *item) 340: { 341: int timeout; 342: 343: ent->client->pers.inventory[ITEM_INDEX(item)]--; 344: ValidateSelectedItem (ent); 345: 346: if (quad_drop_timeout_hack) 347: { 348: timeout = quad_drop_timeout_hack; 349: quad_drop_timeout_hack = 0; 350: } 351: else 352: { 353: timeout = 300; 354: } 355: 356: if (ent->client->quad_framenum > level.framenum) 357: ent->client->quad_framenum += timeout; 358: else 359: ent->client->quad_framenum = level.framenum + timeout; 360: 361: gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0); 362: } 363: 364: //====================================================================== 365: 366: void Use_Breather (edict_t *ent, gitem_t *item) 367: { 368: ent->client->pers.inventory[ITEM_INDEX(item)]--; 369: ValidateSelectedItem (ent); 370: 371: if (ent->client->breather_framenum > level.framenum) 372: ent->client->breather_framenum += 300; 373: else 374: ent->client->breather_framenum = level.framenum + 300; 375: 376: // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0); 377: } 378: 379: //====================================================================== 380: 381: void Use_Envirosuit (edict_t *ent, gitem_t *item) 382: { 383: ent->client->pers.inventory[ITEM_INDEX(item)]--; 384: ValidateSelectedItem (ent); 385: 386: if (ent->client->enviro_framenum > level.framenum) 387: ent->client->enviro_framenum += 300; 388: else 389: ent->client->enviro_framenum = level.framenum + 300; 390: 391: // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0); 392: } 393: 394: //====================================================================== 395: 396: void Use_Invulnerability (edict_t *ent, gitem_t *item) 397: { 398: ent->client->pers.inventory[ITEM_INDEX(item)]--; 399: ValidateSelectedItem (ent); 400: 401: if (ent->client->invincible_framenum > level.framenum) 402: ent->client->invincible_framenum += 300; 403: else 404: ent->client->invincible_framenum = level.framenum + 300; 405: 406: gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0); 407: } 408: 409: //====================================================================== 410: 411: void Use_Silencer (edict_t *ent, gitem_t *item) 412: { 413: ent->client->pers.inventory[ITEM_INDEX(item)]--; 414: ValidateSelectedItem (ent); 415: ent->client->silencer_shots += 30; 416: 417: // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0); 418: } 419: 420: //====================================================================== 421: 422: qboolean Pickup_Key (edict_t *ent, edict_t *other) 423: { 424: if (coop->value) 425: { 426: if (strcmp(ent->classname, "key_power_cube") == 0) 427: { 428: if (other->client->pers.power_cubes & ((ent->spawnflags & 0x0000ff00)>> 8)) 429: return false; 430: other->client->pers.inventory[ITEM_INDEX(ent->item)]++; 431: other->client->pers.power_cubes |= ((ent->spawnflags & 0x0000ff00) >> 8); 432: } 433: else 434: { 435: if (other->client->pers.inventory[ITEM_INDEX(ent->item)]) 436: return false; 437: other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1; 438: } 439: return true; 440: } 441: other->client->pers.inventory[ITEM_INDEX(ent->item)]++; 442: return true; 443: } 444: 445: //====================================================================== 446: 447: qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count) 448: { 449: int index; 450: int max; 451: 452: if (!ent->client) 453: return false; 454: 455: if (item->tag == AMMO_BULLETS) 456: max = ent->client->pers.max_bullets; 457: else if (item->tag == AMMO_SHELLS) 458: max = ent->client->pers.max_shells; 459: else if (item->tag == AMMO_ROCKETS) 460: max = ent->client->pers.max_rockets; 461: else if (item->tag == AMMO_GRENADES) 462: max = ent->client->pers.max_grenades; 463: else if (item->tag == AMMO_CELLS) 464: max = ent->client->pers.max_cells; 465: else if (item->tag == AMMO_SLUGS) 466: max = ent->client->pers.max_slugs; 467: else 468: return false; 469: 470: index = ITEM_INDEX(item); 471: 472: if (ent->client->pers.inventory[index] == max) 473: return false; 474: 475: ent->client->pers.inventory[index] += count; 476: 477: if (ent->client->pers.inventory[index] > max) 478: ent->client->pers.inventory[index] = max; 479: 480: return true; 481: } 482: 483: qboolean Pickup_Ammo (edict_t *ent, edict_t *other) 484: { 485: int oldcount; 486: int count; 487: qboolean weapon; 488: 489: weapon = (ent->item->flags & IT_WEAPON); 490: if ( (weapon) && ( (int)dmflags->value & DF_INFINITE_AMMO ) ) 491: count = 1000; 492: else if (ent->count) 493: count = ent->count; 494: else 495: count = ent->item->quantity; 496: 497: oldcount = other->client->pers.inventory[ITEM_INDEX(ent->item)]; 498: 499: if (!Add_Ammo (other, ent->item, count)) 500: return false; 501: 502: if (weapon && !oldcount) 503: { 504: if (other->client->pers.weapon != ent->item && ( !deathmatch->value || other->client->pers.weapon == FindItem("blaster") ) ) 505: other->client->newweapon = ent->item; 506: } 507: 508: if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && (deathmatch->value)) 509: SetRespawn (ent, 30); 510: return true; 511: } 512: 513: void Drop_Ammo (edict_t *ent, gitem_t *item) 514: { 515: edict_t *dropped; 516: int index; 517: 518: index = ITEM_INDEX(item); 519: dropped = Drop_Item (ent, item); 520: if (ent->client->pers.inventory[index] >= item->quantity) 521: dropped->count = item->quantity; 522: else 523: dropped->count = ent->client->pers.inventory[index]; 1.1.1.2 root 524: 525: if (ent->client->pers.weapon && 526: ent->client->pers.weapon->tag == AMMO_GRENADES && 527: item->tag == AMMO_GRENADES && 528: ent->client->pers.inventory[index] - dropped->count <= 0) { 529: gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n"); 530: G_FreeEdict(dropped); 531: return; 532: } 533: 1.1 root 534: ent->client->pers.inventory[index] -= dropped->count; 535: ValidateSelectedItem (ent); 536: } 537: 538: 539: //====================================================================== 540: 541: void MegaHealth_think (edict_t *self) 542: { 543: if (self->owner->health > self->owner->max_health) 544: { 545: self->nextthink = level.time + 1; 546: self->owner->health -= 1; 547: return; 548: } 549: 550: if (!(self->spawnflags & DROPPED_ITEM) && (deathmatch->value)) 551: SetRespawn (self, 20); 552: else 553: G_FreeEdict (self); 554: } 555: 556: qboolean Pickup_Health (edict_t *ent, edict_t *other) 557: { 558: if (!(ent->style & HEALTH_IGNORE_MAX)) 559: if (other->health >= other->max_health) 560: return false; 561: 562: other->health += ent->count; 563: 564: if (!(ent->style & HEALTH_IGNORE_MAX)) 565: { 566: if (other->health > other->max_health) 567: other->health = other->max_health; 568: } 569: 570: if (ent->style & HEALTH_TIMED) 571: { 572: ent->think = MegaHealth_think; 573: ent->nextthink = level.time + 5; 574: ent->owner = other; 575: ent->flags |= FL_RESPAWN; 576: ent->svflags |= SVF_NOCLIENT; 577: ent->solid = SOLID_NOT; 578: } 579: else 580: { 581: if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) 582: SetRespawn (ent, 30); 583: } 584: 585: return true; 586: } 587: 588: //====================================================================== 589: 590: int ArmorIndex (edict_t *ent) 591: { 592: if (!ent->client) 593: return 0; 594: 595: if (ent->client->pers.inventory[jacket_armor_index] > 0) 596: return jacket_armor_index; 597: 598: if (ent->client->pers.inventory[combat_armor_index] > 0) 599: return combat_armor_index; 600: 601: if (ent->client->pers.inventory[body_armor_index] > 0) 602: return body_armor_index; 603: 604: return 0; 605: } 606: 607: qboolean Pickup_Armor (edict_t *ent, edict_t *other) 608: { 609: int old_armor_index; 610: gitem_armor_t *oldinfo; 611: gitem_armor_t *newinfo; 612: int newcount; 613: float salvage; 614: int salvagecount; 615: 616: // get info on new armor 617: newinfo = (gitem_armor_t *)ent->item->info; 618: 619: old_armor_index = ArmorIndex (other); 620: 621: // handle armor shards specially 622: if (ent->item->tag == ARMOR_SHARD) 623: { 624: if (!old_armor_index) 625: other->client->pers.inventory[jacket_armor_index] = 2; 626: else 627: other->client->pers.inventory[old_armor_index] += 2; 628: } 629: 630: // if player has no armor, just use it 631: else if (!old_armor_index) 632: { 633: other->client->pers.inventory[ITEM_INDEX(ent->item)] = newinfo->base_count; 634: } 635: 636: // use the better armor 637: else 638: { 639: // get info on old armor 640: if (old_armor_index == jacket_armor_index) 641: oldinfo = &jacketarmor_info; 642: else if (old_armor_index == combat_armor_index) 643: oldinfo = &combatarmor_info; 644: else // (old_armor_index == body_armor_index) 645: oldinfo = &bodyarmor_info; 646: 647: if (newinfo->normal_protection > oldinfo->normal_protection) 648: { 649: // calc new armor values 650: salvage = oldinfo->normal_protection / newinfo->normal_protection; 651: salvagecount = salvage * other->client->pers.inventory[old_armor_index]; 652: newcount = newinfo->base_count + salvagecount; 653: if (newcount > newinfo->max_count) 654: newcount = newinfo->max_count; 655: 656: // zero count of old armor so it goes away 657: other->client->pers.inventory[old_armor_index] = 0; 658: 659: // change armor to new item with computed value 660: other->client->pers.inventory[ITEM_INDEX(ent->item)] = newcount; 661: } 662: else 663: { 664: // calc new armor values 665: salvage = newinfo->normal_protection / oldinfo->normal_protection; 666: salvagecount = salvage * newinfo->base_count; 667: newcount = other->client->pers.inventory[old_armor_index] + salvagecount; 668: if (newcount > oldinfo->max_count) 669: newcount = oldinfo->max_count; 670: 671: // if we're already maxed out then we don't need the new armor 672: if (other->client->pers.inventory[old_armor_index] >= newcount) 673: return false; 674: 675: // update current armor value 676: other->client->pers.inventory[old_armor_index] = newcount; 677: } 678: } 679: 680: if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) 681: SetRespawn (ent, 20); 682: 683: return true; 684: } 685: 686: //====================================================================== 687: 688: int PowerArmorType (edict_t *ent) 689: { 690: if (!ent->client) 691: return POWER_ARMOR_NONE; 692: 693: if (!(ent->flags & FL_POWER_ARMOR)) 694: return POWER_ARMOR_NONE; 695: 696: if (ent->client->pers.inventory[power_shield_index] > 0) 697: return POWER_ARMOR_SHIELD; 698: 699: if (ent->client->pers.inventory[power_screen_index] > 0) 700: return POWER_ARMOR_SCREEN; 701: 702: return POWER_ARMOR_NONE; 703: } 704: 705: void Use_PowerArmor (edict_t *ent, gitem_t *item) 706: { 707: int index; 708: 709: if (ent->flags & FL_POWER_ARMOR) 710: { 711: ent->flags &= ~FL_POWER_ARMOR; 712: gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0); 713: } 714: else 715: { 716: index = ITEM_INDEX(FindItem("cells")); 717: if (!ent->client->pers.inventory[index]) 718: { 719: gi.cprintf (ent, PRINT_HIGH, "No cells for power armor.\n"); 720: return; 721: } 722: ent->flags |= FL_POWER_ARMOR; 723: gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0); 724: } 725: } 726: 727: qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other) 728: { 729: int quantity; 730: 731: quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)]; 732: 733: other->client->pers.inventory[ITEM_INDEX(ent->item)]++; 734: 735: if (deathmatch->value) 736: { 737: if (!(ent->spawnflags & DROPPED_ITEM) ) 738: SetRespawn (ent, ent->item->quantity); 739: // auto-use for DM only if we didn't already have one 740: if (!quantity) 741: ent->item->use (other, ent->item); 742: } 743: 744: return true; 745: } 746: 747: void Drop_PowerArmor (edict_t *ent, gitem_t *item) 748: { 749: if ((ent->flags & FL_POWER_ARMOR) && (ent->client->pers.inventory[ITEM_INDEX(item)] == 1)) 750: Use_PowerArmor (ent, item); 751: Drop_General (ent, item); 752: } 753: 754: //====================================================================== 755: 756: /* 757: =============== 758: Touch_Item 759: =============== 760: */ 761: void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) 762: { 763: qboolean taken; 764: 765: if (!other->client) 766: return; 767: if (other->health < 1) 768: return; // dead people can't pickup 769: if (!ent->item->pickup) 770: return; // not a grabbable item? 771: 772: taken = ent->item->pickup(ent, other); 773: 774: if (taken) 775: { 776: // flash the screen 777: other->client->bonus_alpha = 0.25; 778: 779: // show icon and name on status bar 780: other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(ent->item->icon); 781: other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+ITEM_INDEX(ent->item); 782: other->client->pickup_msg_time = level.time + 3.0; 783: 784: // change selected item 785: if (ent->item->use) 786: other->client->pers.selected_item = other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX(ent->item); 787: 1.1.1.3 root 788: if (ent->item->pickup == Pickup_Health) 789: { 790: if (ent->count == 2) 791: gi.sound(other, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0); 792: else if (ent->count == 10) 793: gi.sound(other, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0); 794: else if (ent->count == 25) 795: gi.sound(other, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0); 796: else // (ent->count == 100) 797: gi.sound(other, CHAN_ITEM, gi.soundindex("items/m_health.wav"), 1, ATTN_NORM, 0); 798: } 799: else if (ent->item->pickup_sound) 800: { 801: gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0); 802: } 1.1 root 803: } 804: 805: if (!(ent->spawnflags & ITEM_TARGETS_USED)) 806: { 807: G_UseTargets (ent, other); 808: ent->spawnflags |= ITEM_TARGETS_USED; 809: } 810: 811: if (!taken) 812: return; 813: 814: if (!((coop->value) && (ent->item->flags & IT_STAY_COOP)) || (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM))) 815: { 816: if (ent->flags & FL_RESPAWN) 817: ent->flags &= ~FL_RESPAWN; 818: else 819: G_FreeEdict (ent); 820: } 821: } 822: 823: //====================================================================== 824: 825: static void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) 826: { 827: if (other == ent->owner) 828: return; 829: 830: Touch_Item (ent, other, plane, surf); 831: } 832: 833: static void drop_make_touchable (edict_t *ent) 834: { 835: ent->touch = Touch_Item; 836: if (deathmatch->value) 837: { 838: ent->nextthink = level.time + 29; 839: ent->think = G_FreeEdict; 840: } 841: } 842: 843: edict_t *Drop_Item (edict_t *ent, gitem_t *item) 844: { 845: edict_t *dropped; 846: vec3_t forward, right; 847: vec3_t offset; 848: 849: dropped = G_Spawn(); 850: 851: dropped->classname = item->classname; 852: dropped->item = item; 853: dropped->spawnflags = DROPPED_ITEM; 854: dropped->s.effects = item->world_model_flags; 855: dropped->s.renderfx = RF_GLOW; 856: VectorSet (dropped->mins, -15, -15, -15); 857: VectorSet (dropped->maxs, 15, 15, 15); 858: gi.setmodel (dropped, dropped->item->world_model); 859: dropped->solid = SOLID_TRIGGER; 860: dropped->movetype = MOVETYPE_TOSS; 861: dropped->touch = drop_temp_touch; 862: dropped->owner = ent; 863: 864: if (ent->client) 865: { 866: trace_t trace; 867: 868: AngleVectors (ent->client->v_angle, forward, right, NULL); 869: VectorSet(offset, 24, 0, -16); 870: G_ProjectSource (ent->s.origin, offset, forward, right, dropped->s.origin); 871: trace = gi.trace (ent->s.origin, dropped->mins, dropped->maxs, 872: dropped->s.origin, ent, CONTENTS_SOLID); 873: VectorCopy (trace.endpos, dropped->s.origin); 874: } 875: else 876: { 877: AngleVectors (ent->s.angles, forward, right, NULL); 878: VectorCopy (ent->s.origin, dropped->s.origin); 879: } 880: 881: VectorScale (forward, 100, dropped->velocity); 882: dropped->velocity[2] = 300; 883: 884: dropped->think = drop_make_touchable; 885: dropped->nextthink = level.time + 1; 886: 887: gi.linkentity (dropped); 888: 889: return dropped; 890: } 891: 892: void Use_Item (edict_t *ent, edict_t *other, edict_t *activator) 893: { 894: ent->svflags &= ~SVF_NOCLIENT; 895: ent->use = NULL; 896: 897: if (ent->spawnflags & ITEM_NO_TOUCH) 898: { 899: ent->solid = SOLID_BBOX; 900: ent->touch = NULL; 901: } 902: else 903: { 904: ent->solid = SOLID_TRIGGER; 905: ent->touch = Touch_Item; 906: } 907: 908: gi.linkentity (ent); 909: } 910: 911: //====================================================================== 912: 913: /* 914: ================ 915: droptofloor 916: ================ 917: */ 918: void droptofloor (edict_t *ent) 919: { 920: trace_t tr; 921: vec3_t dest; 922: float *v; 923: 924: v = tv(-15,-15,-15); 925: VectorCopy (v, ent->mins); 926: v = tv(15,15,15); 927: VectorCopy (v, ent->maxs); 928: 929: if (ent->model) 930: gi.setmodel (ent, ent->model); 931: else 932: gi.setmodel (ent, ent->item->world_model); 933: ent->solid = SOLID_TRIGGER; 934: ent->movetype = MOVETYPE_TOSS; 935: ent->touch = Touch_Item; 936: 937: v = tv(0,0,-128); 938: VectorAdd (ent->s.origin, v, dest); 939: 940: tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); 941: if (tr.startsolid) 942: { 943: gi.dprintf ("droptofloor: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin)); 944: G_FreeEdict (ent); 945: return; 946: } 947: 948: VectorCopy (tr.endpos, ent->s.origin); 949: 950: if (ent->team) 951: { 952: ent->flags &= ~FL_TEAMSLAVE; 953: ent->chain = ent->teamchain; 954: ent->teamchain = NULL; 955: 956: ent->svflags |= SVF_NOCLIENT; 957: ent->solid = SOLID_NOT; 958: if (ent == ent->teammaster) 959: { 960: ent->nextthink = level.time + FRAMETIME; 961: ent->think = DoRespawn; 962: } 963: } 964: 965: if (ent->spawnflags & ITEM_NO_TOUCH) 966: { 967: ent->solid = SOLID_BBOX; 968: ent->touch = NULL; 969: ent->s.effects &= ~EF_ROTATE; 970: ent->s.renderfx &= ~RF_GLOW; 971: } 972: 973: if (ent->spawnflags & ITEM_TRIGGER_SPAWN) 974: { 975: ent->svflags |= SVF_NOCLIENT; 976: ent->solid = SOLID_NOT; 977: ent->use = Use_Item; 978: } 979: 980: gi.linkentity (ent); 981: } 982: 983: 984: /* 985: =============== 986: PrecacheItem 987: 988: Precaches all data needed for a given item. 989: This will be called for each item spawned in a level, 990: and for each item in each client's inventory. 991: =============== 992: */ 993: void PrecacheItem (gitem_t *it) 994: { 995: char *s, *start; 996: char data[MAX_QPATH]; 997: int len; 998: gitem_t *ammo; 999: 1000: if (!it) 1001: return; 1002: 1003: if (it->pickup_sound) 1004: gi.soundindex (it->pickup_sound); 1005: if (it->world_model) 1006: gi.modelindex (it->world_model); 1007: if (it->view_model) 1008: gi.modelindex (it->view_model); 1009: if (it->icon) 1010: gi.imageindex (it->icon); 1011: 1012: // parse everything for its ammo 1013: if (it->ammo && it->ammo[0]) 1014: { 1015: ammo = FindItem (it->ammo); 1016: if (ammo != it) 1017: PrecacheItem (ammo); 1018: } 1019: 1020: // parse the space seperated precache string for other items 1021: s = it->precaches; 1022: if (!s || !s[0]) 1023: return; 1024: 1025: while (*s) 1026: { 1027: start = s; 1028: while (*s && *s != ' ') 1029: s++; 1030: 1031: len = s-start; 1032: if (len >= MAX_QPATH || len < 5) 1033: gi.error ("PrecacheItem: %s has bad precache string", it->classname); 1034: memcpy (data, start, len); 1035: data[len] = 0; 1036: if (*s) 1037: s++; 1038: 1039: // determine type based on extension 1040: if (!strcmp(data+len-3, "md2")) 1041: gi.modelindex (data); 1042: else if (!strcmp(data+len-3, "sp2")) 1043: gi.modelindex (data); 1044: else if (!strcmp(data+len-3, "wav")) 1045: gi.soundindex (data); 1046: if (!strcmp(data+len-3, "pcx")) 1047: gi.imageindex (data); 1048: } 1049: } 1050: 1051: /* 1052: ============ 1053: SpawnItem 1054: 1055: Sets the clipping size and plants the object on the floor. 1056: 1057: Items can't be immediately dropped to floor, because they might 1058: be on an entity that hasn't spawned yet. 1059: ============ 1060: */ 1061: void SpawnItem (edict_t *ent, gitem_t *item) 1062: { 1063: PrecacheItem (item); 1064: 1065: if (ent->spawnflags) 1066: { 1067: if (strcmp(ent->classname, "key_power_cube") != 0) 1068: { 1069: ent->spawnflags = 0; 1070: gi.dprintf("%s at %s has invalid spawnflags set\n", ent->classname, vtos(ent->s.origin)); 1071: } 1072: } 1073: 1074: // some items will be prevented in deathmatch 1075: if (deathmatch->value) 1076: { 1077: if ( (int)dmflags->value & DF_NO_ARMOR ) 1078: { 1079: if (item->pickup == Pickup_Armor || item->pickup == Pickup_PowerArmor) 1080: { 1081: G_FreeEdict (ent); 1082: return; 1083: } 1084: } 1085: if ( (int)dmflags->value & DF_NO_ITEMS ) 1086: { 1087: if (item->pickup == Pickup_Powerup) 1088: { 1089: G_FreeEdict (ent); 1090: return; 1091: } 1092: } 1093: if ( (int)dmflags->value & DF_NO_HEALTH ) 1094: { 1095: if (item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline || item->pickup == Pickup_AncientHead) 1096: { 1097: G_FreeEdict (ent); 1098: return; 1099: } 1100: } 1101: if ( (int)dmflags->value & DF_INFINITE_AMMO ) 1102: { 1103: if ( (item->flags == IT_AMMO) || (strcmp(ent->classname, "weapon_bfg") == 0) ) 1104: { 1105: G_FreeEdict (ent); 1106: return; 1107: } 1108: } 1109: } 1110: 1111: if (coop->value && (strcmp(ent->classname, "key_power_cube") == 0)) 1112: { 1113: ent->spawnflags |= (1 << (8 + level.power_cubes)); 1114: level.power_cubes++; 1115: } 1116: 1117: // don't let them drop items that stay in a coop game 1118: if ((coop->value) && (item->flags & IT_STAY_COOP)) 1119: { 1120: item->drop = NULL; 1121: } 1122: 1123: ent->item = item; 1124: ent->nextthink = level.time + 2 * FRAMETIME; // items start after other solids 1125: ent->think = droptofloor; 1126: ent->s.effects = item->world_model_flags; 1127: ent->s.renderfx = RF_GLOW; 1128: if (ent->model) 1129: gi.modelindex (ent->model); 1130: } 1131: 1132: //====================================================================== 1133: 1134: gitem_t itemlist[] = 1135: { 1136: { 1137: NULL 1138: }, // leave index 0 alone 1139: 1140: // 1141: // ARMOR 1142: // 1143: 1144: /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) 1145: */ 1146: { 1147: "item_armor_body", 1148: Pickup_Armor, 1149: NULL, 1150: NULL, 1151: NULL, 1152: "misc/ar1_pkup.wav", 1153: "models/items/armor/body/tris.md2", EF_ROTATE, 1154: NULL, 1155: /* icon */ "i_bodyarmor", 1156: /* pickup */ "Body Armor", 1157: /* width */ 3, 1158: 0, 1159: NULL, 1160: IT_ARMOR, 1.1.1.2 root 1161: 0, 1.1 root 1162: &bodyarmor_info, 1163: ARMOR_BODY, 1164: /* precache */ "" 1165: }, 1166: 1167: /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) 1168: */ 1169: { 1170: "item_armor_combat", 1171: Pickup_Armor, 1172: NULL, 1173: NULL, 1174: NULL, 1175: "misc/ar1_pkup.wav", 1176: "models/items/armor/combat/tris.md2", EF_ROTATE, 1177: NULL, 1178: /* icon */ "i_combatarmor", 1179: /* pickup */ "Combat Armor", 1180: /* width */ 3, 1181: 0, 1182: NULL, 1183: IT_ARMOR, 1.1.1.2 root 1184: 0, 1.1 root 1185: &combatarmor_info, 1186: ARMOR_COMBAT, 1187: /* precache */ "" 1188: }, 1189: 1190: /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16) 1191: */ 1192: { 1193: "item_armor_jacket", 1194: Pickup_Armor, 1195: NULL, 1196: NULL, 1197: NULL, 1198: "misc/ar1_pkup.wav", 1199: "models/items/armor/jacket/tris.md2", EF_ROTATE, 1200: NULL, 1201: /* icon */ "i_jacketarmor", 1202: /* pickup */ "Jacket Armor", 1203: /* width */ 3, 1204: 0, 1205: NULL, 1206: IT_ARMOR, 1.1.1.2 root 1207: 0, 1.1 root 1208: &jacketarmor_info, 1209: ARMOR_JACKET, 1210: /* precache */ "" 1211: }, 1212: 1213: /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) 1214: */ 1215: { 1216: "item_armor_shard", 1217: Pickup_Armor, 1218: NULL, 1219: NULL, 1220: NULL, 1221: "misc/ar2_pkup.wav", 1222: "models/items/armor/shard/tris.md2", EF_ROTATE, 1223: NULL, 1224: /* icon */ "i_jacketarmor", 1225: /* pickup */ "Armor Shard", 1226: /* width */ 3, 1227: 0, 1228: NULL, 1229: IT_ARMOR, 1.1.1.2 root 1230: 0, 1.1 root 1231: NULL, 1232: ARMOR_SHARD, 1233: /* precache */ "" 1234: }, 1235: 1236: 1237: /*QUAKED item_power_screen (.3 .3 1) (-16 -16 -16) (16 16 16) 1238: */ 1239: { 1240: "item_power_screen", 1241: Pickup_PowerArmor, 1242: Use_PowerArmor, 1243: Drop_PowerArmor, 1244: NULL, 1245: "misc/ar3_pkup.wav", 1246: "models/items/armor/screen/tris.md2", EF_ROTATE, 1247: NULL, 1248: /* icon */ "i_powerscreen", 1249: /* pickup */ "Power Screen", 1250: /* width */ 0, 1251: 60, 1252: NULL, 1253: IT_ARMOR, 1.1.1.2 root 1254: 0, 1.1 root 1255: NULL, 1256: 0, 1257: /* precache */ "" 1258: }, 1259: 1260: /*QUAKED item_power_shield (.3 .3 1) (-16 -16 -16) (16 16 16) 1261: */ 1262: { 1263: "item_power_shield", 1264: Pickup_PowerArmor, 1265: Use_PowerArmor, 1266: Drop_PowerArmor, 1267: NULL, 1268: "misc/ar3_pkup.wav", 1269: "models/items/armor/shield/tris.md2", EF_ROTATE, 1270: NULL, 1271: /* icon */ "i_powershield", 1272: /* pickup */ "Power Shield", 1273: /* width */ 0, 1274: 60, 1275: NULL, 1276: IT_ARMOR, 1.1.1.2 root 1277: 0, 1.1 root 1278: NULL, 1279: 0, 1280: /* precache */ "misc/power2.wav misc/power1.wav" 1281: }, 1282: 1283: 1284: // 1285: // WEAPONS 1286: // 1287: 1288: /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16) 1289: always owned, never in the world 1290: */ 1291: { 1292: "weapon_blaster", 1293: NULL, 1294: Use_Weapon, 1295: NULL, 1296: Weapon_Blaster, 1297: "misc/w_pkup.wav", 1298: NULL, 0, 1299: "models/weapons/v_blast/tris.md2", 1300: /* icon */ "w_blaster", 1301: /* pickup */ "Blaster", 1302: 0, 1303: 0, 1304: NULL, 1305: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1306: WEAP_BLASTER, 1.1 root 1307: NULL, 1308: 0, 1309: /* precache */ "weapons/blastf1a.wav misc/lasfly.wav" 1310: }, 1311: 1312: /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) 1313: */ 1314: { 1315: "weapon_shotgun", 1316: Pickup_Weapon, 1317: Use_Weapon, 1318: Drop_Weapon, 1319: Weapon_Shotgun, 1320: "misc/w_pkup.wav", 1321: "models/weapons/g_shotg/tris.md2", EF_ROTATE, 1322: "models/weapons/v_shotg/tris.md2", 1323: /* icon */ "w_shotgun", 1324: /* pickup */ "Shotgun", 1325: 0, 1326: 1, 1327: "Shells", 1328: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1329: WEAP_SHOTGUN, 1.1 root 1330: NULL, 1331: 0, 1332: /* precache */ "weapons/shotgf1b.wav weapons/shotgr1b.wav" 1333: }, 1334: 1335: /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16) 1336: */ 1337: { 1338: "weapon_supershotgun", 1339: Pickup_Weapon, 1340: Use_Weapon, 1341: Drop_Weapon, 1342: Weapon_SuperShotgun, 1343: "misc/w_pkup.wav", 1344: "models/weapons/g_shotg2/tris.md2", EF_ROTATE, 1345: "models/weapons/v_shotg2/tris.md2", 1346: /* icon */ "w_sshotgun", 1347: /* pickup */ "Super Shotgun", 1348: 0, 1349: 2, 1350: "Shells", 1351: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1352: WEAP_SUPERSHOTGUN, 1.1 root 1353: NULL, 1354: 0, 1355: /* precache */ "weapons/sshotf1b.wav" 1356: }, 1357: 1358: /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16) 1359: */ 1360: { 1361: "weapon_machinegun", 1362: Pickup_Weapon, 1363: Use_Weapon, 1364: Drop_Weapon, 1365: Weapon_Machinegun, 1366: "misc/w_pkup.wav", 1367: "models/weapons/g_machn/tris.md2", EF_ROTATE, 1368: "models/weapons/v_machn/tris.md2", 1369: /* icon */ "w_machinegun", 1370: /* pickup */ "Machinegun", 1371: 0, 1372: 1, 1373: "Bullets", 1374: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1375: WEAP_MACHINEGUN, 1.1 root 1376: NULL, 1377: 0, 1378: /* precache */ "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav" 1379: }, 1380: 1381: /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) 1382: */ 1383: { 1384: "weapon_chaingun", 1385: Pickup_Weapon, 1386: Use_Weapon, 1387: Drop_Weapon, 1388: Weapon_Chaingun, 1389: "misc/w_pkup.wav", 1390: "models/weapons/g_chain/tris.md2", EF_ROTATE, 1391: "models/weapons/v_chain/tris.md2", 1392: /* icon */ "w_chaingun", 1393: /* pickup */ "Chaingun", 1394: 0, 1395: 1, 1396: "Bullets", 1397: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1398: WEAP_CHAINGUN, 1.1 root 1399: NULL, 1400: 0, 1401: /* precache */ "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav" 1402: }, 1403: 1404: /*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16) 1405: */ 1406: { 1407: "ammo_grenades", 1408: Pickup_Ammo, 1409: Use_Weapon, 1410: Drop_Ammo, 1411: Weapon_Grenade, 1412: "misc/am_pkup.wav", 1413: "models/items/ammo/grenades/medium/tris.md2", 0, 1414: "models/weapons/v_handgr/tris.md2", 1415: /* icon */ "a_grenades", 1416: /* pickup */ "Grenades", 1417: /* width */ 3, 1418: 5, 1419: "grenades", 1420: IT_AMMO|IT_WEAPON, 1.1.1.2 root 1421: WEAP_GRENADES, 1.1 root 1422: NULL, 1423: AMMO_GRENADES, 1424: /* precache */ "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav " 1425: }, 1426: 1427: /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) 1428: */ 1429: { 1430: "weapon_grenadelauncher", 1431: Pickup_Weapon, 1432: Use_Weapon, 1433: Drop_Weapon, 1434: Weapon_GrenadeLauncher, 1435: "misc/w_pkup.wav", 1436: "models/weapons/g_launch/tris.md2", EF_ROTATE, 1437: "models/weapons/v_launch/tris.md2", 1438: /* icon */ "w_glauncher", 1439: /* pickup */ "Grenade Launcher", 1440: 0, 1441: 1, 1442: "Grenades", 1443: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1444: WEAP_GRENADELAUNCHER, 1.1 root 1445: NULL, 1446: 0, 1447: /* precache */ "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav" 1448: }, 1449: 1450: /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) 1451: */ 1452: { 1453: "weapon_rocketlauncher", 1454: Pickup_Weapon, 1455: Use_Weapon, 1456: Drop_Weapon, 1457: Weapon_RocketLauncher, 1458: "misc/w_pkup.wav", 1459: "models/weapons/g_rocket/tris.md2", EF_ROTATE, 1460: "models/weapons/v_rocket/tris.md2", 1461: /* icon */ "w_rlauncher", 1462: /* pickup */ "Rocket Launcher", 1463: 0, 1464: 1, 1465: "Rockets", 1466: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1467: WEAP_ROCKETLAUNCHER, 1.1 root 1468: NULL, 1469: 0, 1470: /* precache */ "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2" 1471: }, 1472: 1473: /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16) 1474: */ 1475: { 1476: "weapon_hyperblaster", 1477: Pickup_Weapon, 1478: Use_Weapon, 1479: Drop_Weapon, 1480: Weapon_HyperBlaster, 1481: "misc/w_pkup.wav", 1482: "models/weapons/g_hyperb/tris.md2", EF_ROTATE, 1483: "models/weapons/v_hyperb/tris.md2", 1484: /* icon */ "w_hyperblaster", 1485: /* pickup */ "HyperBlaster", 1486: 0, 1487: 1, 1488: "Cells", 1489: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1490: WEAP_HYPERBLASTER, 1.1 root 1491: NULL, 1492: 0, 1493: /* precache */ "weapons/hyprbu1a.wav weapons/hyprbl1a.wav weapons/hyprbf1a.wav weapons/hyprbd1a.wav misc/lasfly.wav" 1494: }, 1495: 1496: /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) 1497: */ 1498: { 1499: "weapon_railgun", 1500: Pickup_Weapon, 1501: Use_Weapon, 1502: Drop_Weapon, 1503: Weapon_Railgun, 1504: "misc/w_pkup.wav", 1505: "models/weapons/g_rail/tris.md2", EF_ROTATE, 1506: "models/weapons/v_rail/tris.md2", 1507: /* icon */ "w_railgun", 1508: /* pickup */ "Railgun", 1509: 0, 1510: 1, 1511: "Slugs", 1512: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1513: WEAP_RAILGUN, 1.1 root 1514: NULL, 1515: 0, 1516: /* precache */ "weapons/rg_hum.wav" 1517: }, 1518: 1519: /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) 1520: */ 1521: { 1522: "weapon_bfg", 1523: Pickup_Weapon, 1524: Use_Weapon, 1525: Drop_Weapon, 1526: Weapon_BFG, 1527: "misc/w_pkup.wav", 1528: "models/weapons/g_bfg/tris.md2", EF_ROTATE, 1529: "models/weapons/v_bfg/tris.md2", 1530: /* icon */ "w_bfg", 1531: /* pickup */ "BFG10K", 1532: 0, 1533: 50, 1534: "Cells", 1535: IT_WEAPON|IT_STAY_COOP, 1.1.1.2 root 1536: WEAP_BFG, 1.1 root 1537: NULL, 1538: 0, 1539: /* precache */ "sprites/s_bfg1.sp2 sprites/s_bfg2.sp2 sprites/s_bfg3.sp2 weapons/bfg__f1y.wav weapons/bfg__l1a.wav weapons/bfg__x1b.wav weapons/bfg_hum.wav" 1540: }, 1541: 1542: // 1543: // AMMO ITEMS 1544: // 1545: 1546: /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) 1547: */ 1548: { 1549: "ammo_shells", 1550: Pickup_Ammo, 1551: NULL, 1552: Drop_Ammo, 1553: NULL, 1554: "misc/am_pkup.wav", 1555: "models/items/ammo/shells/medium/tris.md2", 0, 1556: NULL, 1557: /* icon */ "a_shells", 1558: /* pickup */ "Shells", 1559: /* width */ 3, 1560: 10, 1561: NULL, 1562: IT_AMMO, 1.1.1.2 root 1563: 0, 1.1 root 1564: NULL, 1565: AMMO_SHELLS, 1566: /* precache */ "" 1567: }, 1568: 1569: /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) 1570: */ 1571: { 1572: "ammo_bullets", 1573: Pickup_Ammo, 1574: NULL, 1575: Drop_Ammo, 1576: NULL, 1577: "misc/am_pkup.wav", 1578: "models/items/ammo/bullets/medium/tris.md2", 0, 1579: NULL, 1580: /* icon */ "a_bullets", 1581: /* pickup */ "Bullets", 1582: /* width */ 3, 1583: 50, 1584: NULL, 1585: IT_AMMO, 1.1.1.2 root 1586: 0, 1.1 root 1587: NULL, 1588: AMMO_BULLETS, 1589: /* precache */ "" 1590: }, 1591: 1592: /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) 1593: */ 1594: { 1595: "ammo_cells", 1596: Pickup_Ammo, 1597: NULL, 1598: Drop_Ammo, 1599: NULL, 1600: "misc/am_pkup.wav", 1601: "models/items/ammo/cells/medium/tris.md2", 0, 1602: NULL, 1603: /* icon */ "a_cells", 1604: /* pickup */ "Cells", 1605: /* width */ 3, 1606: 50, 1607: NULL, 1608: IT_AMMO, 1.1.1.2 root 1609: 0, 1.1 root 1610: NULL, 1611: AMMO_CELLS, 1612: /* precache */ "" 1613: }, 1614: 1615: /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) 1616: */ 1617: { 1618: "ammo_rockets", 1619: Pickup_Ammo, 1620: NULL, 1621: Drop_Ammo, 1622: NULL, 1623: "misc/am_pkup.wav", 1624: "models/items/ammo/rockets/medium/tris.md2", 0, 1625: NULL, 1626: /* icon */ "a_rockets", 1627: /* pickup */ "Rockets", 1628: /* width */ 3, 1629: 5, 1630: NULL, 1631: IT_AMMO, 1.1.1.2 root 1632: 0, 1.1 root 1633: NULL, 1634: AMMO_ROCKETS, 1635: /* precache */ "" 1636: }, 1637: 1638: /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) 1639: */ 1640: { 1641: "ammo_slugs", 1642: Pickup_Ammo, 1643: NULL, 1644: Drop_Ammo, 1645: NULL, 1646: "misc/am_pkup.wav", 1647: "models/items/ammo/slugs/medium/tris.md2", 0, 1648: NULL, 1649: /* icon */ "a_slugs", 1650: /* pickup */ "Slugs", 1651: /* width */ 3, 1652: 10, 1653: NULL, 1654: IT_AMMO, 1.1.1.2 root 1655: 0, 1.1 root 1656: NULL, 1657: AMMO_SLUGS, 1658: /* precache */ "" 1659: }, 1660: 1661: 1662: // 1663: // POWERUP ITEMS 1664: // 1665: /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) 1666: */ 1667: { 1668: "item_quad", 1669: Pickup_Powerup, 1670: Use_Quad, 1671: Drop_General, 1672: NULL, 1673: "items/pkup.wav", 1674: "models/items/quaddama/tris.md2", EF_ROTATE, 1675: NULL, 1676: /* icon */ "p_quad", 1677: /* pickup */ "Quad Damage", 1678: /* width */ 2, 1679: 60, 1680: NULL, 1681: IT_POWERUP, 1.1.1.2 root 1682: 0, 1.1 root 1683: NULL, 1684: 0, 1685: /* precache */ "items/damage.wav items/damage2.wav items/damage3.wav" 1686: }, 1687: 1688: /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) 1689: */ 1690: { 1691: "item_invulnerability", 1692: Pickup_Powerup, 1693: Use_Invulnerability, 1694: Drop_General, 1695: NULL, 1696: "items/pkup.wav", 1697: "models/items/invulner/tris.md2", EF_ROTATE, 1698: NULL, 1699: /* icon */ "p_invulnerability", 1700: /* pickup */ "Invulnerability", 1701: /* width */ 2, 1702: 300, 1703: NULL, 1704: IT_POWERUP, 1.1.1.2 root 1705: 0, 1.1 root 1706: NULL, 1707: 0, 1708: /* precache */ "items/protect.wav items/protect2.wav items/protect4.wav" 1709: }, 1710: 1711: /*QUAKED item_silencer (.3 .3 1) (-16 -16 -16) (16 16 16) 1712: */ 1713: { 1714: "item_silencer", 1715: Pickup_Powerup, 1716: Use_Silencer, 1717: Drop_General, 1718: NULL, 1719: "items/pkup.wav", 1720: "models/items/silencer/tris.md2", EF_ROTATE, 1721: NULL, 1722: /* icon */ "p_silencer", 1723: /* pickup */ "Silencer", 1724: /* width */ 2, 1725: 60, 1726: NULL, 1727: IT_POWERUP, 1.1.1.2 root 1728: 0, 1.1 root 1729: NULL, 1730: 0, 1731: /* precache */ "" 1732: }, 1733: 1734: /*QUAKED item_breather (.3 .3 1) (-16 -16 -16) (16 16 16) 1735: */ 1736: { 1737: "item_breather", 1738: Pickup_Powerup, 1739: Use_Breather, 1740: Drop_General, 1741: NULL, 1742: "items/pkup.wav", 1743: "models/items/breather/tris.md2", EF_ROTATE, 1744: NULL, 1745: /* icon */ "p_rebreather", 1746: /* pickup */ "Rebreather", 1747: /* width */ 2, 1748: 60, 1749: NULL, 1750: IT_STAY_COOP|IT_POWERUP, 1.1.1.2 root 1751: 0, 1.1 root 1752: NULL, 1753: 0, 1754: /* precache */ "items/airout.wav" 1755: }, 1756: 1757: /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16) 1758: */ 1759: { 1760: "item_enviro", 1761: Pickup_Powerup, 1762: Use_Envirosuit, 1763: Drop_General, 1764: NULL, 1765: "items/pkup.wav", 1766: "models/items/enviro/tris.md2", EF_ROTATE, 1767: NULL, 1768: /* icon */ "p_envirosuit", 1769: /* pickup */ "Environment Suit", 1770: /* width */ 2, 1771: 60, 1772: NULL, 1773: IT_STAY_COOP|IT_POWERUP, 1.1.1.2 root 1774: 0, 1.1 root 1775: NULL, 1776: 0, 1777: /* precache */ "items/airout.wav" 1778: }, 1779: 1780: /*QUAKED item_ancient_head (.3 .3 1) (-16 -16 -16) (16 16 16) 1781: Special item that gives +2 to maximum health 1782: */ 1783: { 1784: "item_ancient_head", 1785: Pickup_AncientHead, 1786: NULL, 1787: NULL, 1788: NULL, 1789: "items/pkup.wav", 1790: "models/items/c_head/tris.md2", EF_ROTATE, 1791: NULL, 1792: /* icon */ "i_fixme", 1793: /* pickup */ "Ancient Head", 1794: /* width */ 2, 1795: 60, 1796: NULL, 1797: 0, 1.1.1.2 root 1798: 0, 1.1 root 1799: NULL, 1800: 0, 1801: /* precache */ "" 1802: }, 1803: 1804: /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16) 1805: gives +1 to maximum health 1806: */ 1807: { 1808: "item_adrenaline", 1809: Pickup_Adrenaline, 1810: NULL, 1811: NULL, 1812: NULL, 1813: "items/pkup.wav", 1814: "models/items/adrenal/tris.md2", EF_ROTATE, 1815: NULL, 1816: /* icon */ "p_adrenaline", 1817: /* pickup */ "Adrenaline", 1818: /* width */ 2, 1819: 60, 1820: NULL, 1821: 0, 1.1.1.2 root 1822: 0, 1.1 root 1823: NULL, 1824: 0, 1825: /* precache */ "" 1826: }, 1827: 1828: /*QUAKED item_bandolier (.3 .3 1) (-16 -16 -16) (16 16 16) 1829: */ 1830: { 1831: "item_bandolier", 1832: Pickup_Bandolier, 1833: NULL, 1834: NULL, 1835: NULL, 1836: "items/pkup.wav", 1837: "models/items/band/tris.md2", EF_ROTATE, 1838: NULL, 1839: /* icon */ "p_bandolier", 1840: /* pickup */ "Bandolier", 1841: /* width */ 2, 1842: 60, 1843: NULL, 1844: 0, 1.1.1.2 root 1845: 0, 1.1 root 1846: NULL, 1847: 0, 1848: /* precache */ "" 1849: }, 1850: 1851: /*QUAKED item_pack (.3 .3 1) (-16 -16 -16) (16 16 16) 1852: */ 1853: { 1854: "item_pack", 1855: Pickup_Pack, 1856: NULL, 1857: NULL, 1858: NULL, 1859: "items/pkup.wav", 1860: "models/items/pack/tris.md2", EF_ROTATE, 1861: NULL, 1862: /* icon */ "i_pack", 1863: /* pickup */ "Ammo Pack", 1864: /* width */ 2, 1865: 180, 1866: NULL, 1867: 0, 1.1.1.2 root 1868: 0, 1.1 root 1869: NULL, 1870: 0, 1871: /* precache */ "" 1872: }, 1873: 1874: // 1875: // KEYS 1876: // 1877: /*QUAKED key_data_cd (0 .5 .8) (-16 -16 -16) (16 16 16) 1878: key for computer centers 1879: */ 1880: { 1881: "key_data_cd", 1882: Pickup_Key, 1883: NULL, 1884: Drop_General, 1885: NULL, 1886: "items/pkup.wav", 1887: "models/items/keys/data_cd/tris.md2", EF_ROTATE, 1888: NULL, 1889: "k_datacd", 1890: "Data CD", 1891: 2, 1892: 0, 1893: NULL, 1894: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 1895: 0, 1.1 root 1896: NULL, 1897: 0, 1898: /* precache */ "" 1899: }, 1900: 1901: /*QUAKED key_power_cube (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH 1902: warehouse circuits 1903: */ 1904: { 1905: "key_power_cube", 1906: Pickup_Key, 1907: NULL, 1908: Drop_General, 1909: NULL, 1910: "items/pkup.wav", 1911: "models/items/keys/power/tris.md2", EF_ROTATE, 1912: NULL, 1913: "k_powercube", 1914: "Power Cube", 1915: 2, 1916: 0, 1917: NULL, 1918: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 1919: 0, 1.1 root 1920: NULL, 1921: 0, 1922: /* precache */ "" 1923: }, 1924: 1925: /*QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16) 1926: key for the entrance of jail3 1927: */ 1928: { 1929: "key_pyramid", 1930: Pickup_Key, 1931: NULL, 1932: Drop_General, 1933: NULL, 1934: "items/pkup.wav", 1935: "models/items/keys/pyramid/tris.md2", EF_ROTATE, 1936: NULL, 1937: "k_pyramid", 1938: "Pyramid Key", 1939: 2, 1940: 0, 1941: NULL, 1942: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 1943: 0, 1.1 root 1944: NULL, 1945: 0, 1946: /* precache */ "" 1947: }, 1948: 1949: /*QUAKED key_data_spinner (0 .5 .8) (-16 -16 -16) (16 16 16) 1950: key for the city computer 1951: */ 1952: { 1953: "key_data_spinner", 1954: Pickup_Key, 1955: NULL, 1956: Drop_General, 1957: NULL, 1958: "items/pkup.wav", 1959: "models/items/keys/spinner/tris.md2", EF_ROTATE, 1960: NULL, 1961: "k_dataspin", 1962: "Data Spinner", 1963: 2, 1964: 0, 1965: NULL, 1966: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 1967: 0, 1.1 root 1968: NULL, 1969: 0, 1970: /* precache */ "" 1971: }, 1972: 1973: /*QUAKED key_pass (0 .5 .8) (-16 -16 -16) (16 16 16) 1974: security pass for the security level 1975: */ 1976: { 1977: "key_pass", 1978: Pickup_Key, 1979: NULL, 1980: Drop_General, 1981: NULL, 1982: "items/pkup.wav", 1983: "models/items/keys/pass/tris.md2", EF_ROTATE, 1984: NULL, 1985: "k_security", 1986: "Security Pass", 1987: 2, 1988: 0, 1989: NULL, 1990: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 1991: 0, 1.1 root 1992: NULL, 1993: 0, 1994: /* precache */ "" 1995: }, 1996: 1997: /*QUAKED key_blue_key (0 .5 .8) (-16 -16 -16) (16 16 16) 1998: normal door key - blue 1999: */ 2000: { 2001: "key_blue_key", 2002: Pickup_Key, 2003: NULL, 2004: Drop_General, 2005: NULL, 2006: "items/pkup.wav", 2007: "models/items/keys/key/tris.md2", EF_ROTATE, 2008: NULL, 2009: "k_bluekey", 2010: "Blue Key", 2011: 2, 2012: 0, 2013: NULL, 2014: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 2015: 0, 1.1 root 2016: NULL, 2017: 0, 2018: /* precache */ "" 2019: }, 2020: 2021: /*QUAKED key_red_key (0 .5 .8) (-16 -16 -16) (16 16 16) 2022: normal door key - red 2023: */ 2024: { 2025: "key_red_key", 2026: Pickup_Key, 2027: NULL, 2028: Drop_General, 2029: NULL, 2030: "items/pkup.wav", 2031: "models/items/keys/red_key/tris.md2", EF_ROTATE, 2032: NULL, 2033: "k_redkey", 2034: "Red Key", 2035: 2, 2036: 0, 2037: NULL, 2038: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 2039: 0, 1.1 root 2040: NULL, 2041: 0, 2042: /* precache */ "" 2043: }, 2044: 2045: /*QUAKED key_commander_head (0 .5 .8) (-16 -16 -16) (16 16 16) 2046: tank commander's head 2047: */ 2048: { 2049: "key_commander_head", 2050: Pickup_Key, 2051: NULL, 2052: Drop_General, 2053: NULL, 2054: "items/pkup.wav", 2055: "models/monsters/commandr/head/tris.md2", EF_GIB, 2056: NULL, 2057: /* icon */ "k_comhead", 2058: /* pickup */ "Commander's Head", 2059: /* width */ 2, 2060: 0, 2061: NULL, 2062: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 2063: 0, 1.1 root 2064: NULL, 2065: 0, 2066: /* precache */ "" 2067: }, 2068: 2069: /*QUAKED key_airstrike_target (0 .5 .8) (-16 -16 -16) (16 16 16) 2070: tank commander's head 2071: */ 2072: { 2073: "key_airstrike_target", 2074: Pickup_Key, 2075: NULL, 2076: Drop_General, 2077: NULL, 2078: "items/pkup.wav", 2079: "models/items/keys/target/tris.md2", EF_ROTATE, 2080: NULL, 2081: /* icon */ "i_airstrike", 2082: /* pickup */ "Airstrike Marker", 2083: /* width */ 2, 2084: 0, 2085: NULL, 2086: IT_STAY_COOP|IT_KEY, 1.1.1.2 root 2087: 0, 1.1 root 2088: NULL, 2089: 0, 2090: /* precache */ "" 2091: }, 2092: 2093: { 2094: NULL, 2095: Pickup_Health, 2096: NULL, 2097: NULL, 2098: NULL, 2099: "items/pkup.wav", 2100: NULL, 0, 2101: NULL, 2102: /* icon */ "i_health", 2103: /* pickup */ "Health", 2104: /* width */ 3, 2105: 0, 2106: NULL, 2107: 0, 1.1.1.2 root 2108: 0, 1.1 root 2109: NULL, 2110: 0, 1.1.1.3 root 2111: /* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav" 1.1 root 2112: }, 2113: 2114: // end of list marker 2115: {NULL} 2116: }; 2117: 2118: 2119: /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16) 2120: */ 2121: void SP_item_health (edict_t *self) 2122: { 2123: if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) 2124: { 2125: G_FreeEdict (self); 2126: return; 2127: } 2128: 2129: self->model = "models/items/healing/medium/tris.md2"; 2130: self->count = 10; 2131: SpawnItem (self, FindItem ("Health")); 2132: gi.soundindex ("items/n_health.wav"); 2133: } 2134: 2135: /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) 2136: */ 2137: void SP_item_health_small (edict_t *self) 2138: { 2139: if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) 2140: { 2141: G_FreeEdict (self); 2142: return; 2143: } 2144: 2145: self->model = "models/items/healing/stimpack/tris.md2"; 2146: self->count = 2; 2147: SpawnItem (self, FindItem ("Health")); 2148: self->style = HEALTH_IGNORE_MAX; 2149: gi.soundindex ("items/s_health.wav"); 2150: } 2151: 2152: /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) 2153: */ 2154: void SP_item_health_large (edict_t *self) 2155: { 2156: if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) 2157: { 2158: G_FreeEdict (self); 2159: return; 2160: } 2161: 2162: self->model = "models/items/healing/large/tris.md2"; 2163: self->count = 25; 2164: SpawnItem (self, FindItem ("Health")); 2165: gi.soundindex ("items/l_health.wav"); 2166: } 2167: 2168: /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) 2169: */ 2170: void SP_item_health_mega (edict_t *self) 2171: { 2172: if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) 2173: { 2174: G_FreeEdict (self); 2175: return; 2176: } 2177: 2178: self->model = "models/items/mega_h/tris.md2"; 2179: self->count = 100; 2180: SpawnItem (self, FindItem ("Health")); 2181: gi.soundindex ("items/m_health.wav"); 2182: self->style = HEALTH_IGNORE_MAX|HEALTH_TIMED; 2183: } 2184: 2185: 2186: void InitItems (void) 2187: { 2188: game.num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1; 2189: } 2190: 2191: 2192: 2193: /* 2194: =============== 2195: SetItemNames 2196: 2197: Called by worldspawn 2198: =============== 2199: */ 2200: void SetItemNames (void) 2201: { 2202: int i; 2203: gitem_t *it; 2204: 2205: for (i=0 ; i<game.num_items ; i++) 2206: { 2207: it = &itemlist[i]; 2208: gi.configstring (CS_ITEMS+i, it->pickup_name); 2209: } 2210: 2211: jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor")); 2212: combat_armor_index = ITEM_INDEX(FindItem("Combat Armor")); 2213: body_armor_index = ITEM_INDEX(FindItem("Body Armor")); 2214: power_screen_index = ITEM_INDEX(FindItem("Power Screen")); 2215: power_shield_index = ITEM_INDEX(FindItem("Power Shield")); 2216: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.