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