Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

g_items.c (46311B)


      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 }