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