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