File: game\g_items.c

    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 */
   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];
  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 
  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 
  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                 }
  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,
 1161                 0,
 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,
 1184                 0,
 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,
 1207                 0,
 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,
 1230                 0,
 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,
 1254                 0,
 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,
 1277                 0,
 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,
 1306                 WEAP_BLASTER,
 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,
 1329                 WEAP_SHOTGUN,
 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,
 1352                 WEAP_SUPERSHOTGUN,
 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,
 1375                 WEAP_MACHINEGUN,
 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,
 1398                 WEAP_CHAINGUN,
 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,
 1421                 WEAP_GRENADES,
 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,
 1444                 WEAP_GRENADELAUNCHER,
 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,
 1467                 WEAP_ROCKETLAUNCHER,
 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,
 1490                 WEAP_HYPERBLASTER,
 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,
 1513                 WEAP_RAILGUN,
 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,
 1536                 WEAP_BFG,
 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,
 1563                 0,
 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,
 1586                 0,
 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,
 1609                 0,
 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,
 1632                 0,
 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,
 1655                 0,
 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,
 1682                 0,
 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,
 1705                 0,
 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,
 1728                 0,
 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,
 1751                 0,
 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,
 1774                 0,
 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,
 1798                 0,
 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,
 1822                 0,
 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,
 1845                 0,
 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,
 1868                 0,
 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,
 1895                 0,
 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,
 1919                 0,
 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,
 1943                 0,
 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,
 1967                 0,
 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,
 1991                 0,
 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,
 2015                 0,
 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,
 2039                 0,
 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,
 2063                 0,
 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,
 2087                 0,
 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,
 2108                 0,
 2109                 NULL,
 2110                 0,
 2111 /* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav"
 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 }
 2217