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