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