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 //=========
21 //Rogue Weapons
22 void Weapon_ChainFist (edict_t *ent);
23 void Weapon_Disintegrator (edict_t *ent);
24 void Weapon_ETF_Rifle (edict_t *ent);
25 void Weapon_Heatbeam (edict_t *ent);
26 void Weapon_Prox (edict_t *ent);
27 void Weapon_Tesla (edict_t *ent);
28 void Weapon_ProxLauncher (edict_t *ent);
29 //void Weapon_Nuke (edict_t *ent);
30 //Rogue Weapons
31 //=========
32 
33 gitem_armor_t jacketarmor_info	= { 25,  50, .30, .00, ARMOR_JACKET};
34 gitem_armor_t combatarmor_info	= { 50, 100, .60, .30, ARMOR_COMBAT};
35 gitem_armor_t bodyarmor_info	= {100, 200, .80, .60, ARMOR_BODY};
36 
37 int	jacket_armor_index;
38 int	combat_armor_index;
39 int	body_armor_index;
40 static int	power_screen_index;
41 static int	power_shield_index;
42 
43 #define HEALTH_IGNORE_MAX	1
44 #define HEALTH_TIMED		2
45 
46 void Use_Quad (edict_t *ent, gitem_t *item);
47 static int	quad_drop_timeout_hack;
48 
49 //======================================================================
50 
51 /*
52 ===============
53 GetItemByIndex
54 ===============
55 */
GetItemByIndex(int index)56 gitem_t	*GetItemByIndex (int index)
57 {
58 	if (index == 0 || index >= game.num_items)
59 		return NULL;
60 
61 	return &itemlist[index];
62 }
63 
64 
65 /*
66 ===============
67 FindItemByClassname
68 
69 ===============
70 */
FindItemByClassname(char * classname)71 gitem_t	*FindItemByClassname (char *classname)
72 {
73 	int		i;
74 	gitem_t	*it;
75 
76 	it = itemlist;
77 	for (i=0 ; i<game.num_items ; i++, it++)
78 	{
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 ===============
90 FindItem
91 
92 ===============
93 */
FindItem(char * pickup_name)94 gitem_t	*FindItem (char *pickup_name)
95 {
96 	int		i;
97 	gitem_t	*it;
98 
99 	it = itemlist;
100 	for (i=0 ; i<game.num_items ; i++, it++)
101 	{
102 		if (!it->pickup_name)
103 			continue;
104 		if (!Q_stricmp(it->pickup_name, pickup_name))
105 			return it;
106 	}
107 
108 	return NULL;
109 }
110 
111 //======================================================================
112 
DoRespawn(edict_t * ent)113 void DoRespawn (edict_t *ent)
114 {
115 	if (ent->team)
116 	{
117 		edict_t	*master;
118 		int	count;
119 		int choice;
120 
121 		master = ent->teammaster;
122 
123 		for (count = 0, ent = master; ent; ent = ent->chain, count++)
124 			;
125 
126 		choice = rand() % count;
127 
128 		for (count = 0, ent = master; count < choice; ent = ent->chain, count++)
129 			;
130 	}
131 
132 //=====
133 //ROGUE
134 	if(randomrespawn && randomrespawn->value)
135 	{
136 		edict_t *newEnt;
137 
138 		newEnt = DoRandomRespawn (ent);
139 
140 		// if we've changed entities, then do some sleight of hand.
141 		// otherwise, the old entity will respawn
142 		if(newEnt)
143 		{
144 			G_FreeEdict (ent);
145 			ent = newEnt;
146 		}
147 	}
148 //ROGUE
149 //=====
150 
151 	ent->svflags &= ~SVF_NOCLIENT;
152 	ent->solid = SOLID_TRIGGER;
153 	gi.linkentity (ent);
154 
155 	// send an effect
156 	ent->s.event = EV_ITEM_RESPAWN;
157 }
158 
SetRespawn(edict_t * ent,float delay)159 void SetRespawn (edict_t *ent, float delay)
160 {
161 	ent->flags |= FL_RESPAWN;
162 	ent->svflags |= SVF_NOCLIENT;
163 	ent->solid = SOLID_NOT;
164 	ent->nextthink = level.time + delay;
165 	ent->think = DoRespawn;
166 	gi.linkentity (ent);
167 }
168 
169 
170 //======================================================================
171 
Pickup_Powerup(edict_t * ent,edict_t * other)172 qboolean Pickup_Powerup (edict_t *ent, edict_t *other)
173 {
174 	int		quantity;
175 
176 	quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
177 	if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
178 		return false;
179 
180 	if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
181 		return false;
182 
183 	other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
184 
185 	if (deathmatch->value)
186 	{
187 		if (!(ent->spawnflags & DROPPED_ITEM) )
188 			SetRespawn (ent, ent->item->quantity);
189 		if (((int)dmflags->value & DF_INSTANT_ITEMS) || ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM)))
190 		{
191 			if ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM))
192 				quad_drop_timeout_hack = (ent->nextthink - level.time) / FRAMETIME;
193 //PGM
194 			if(ent->item->use)
195 				ent->item->use (other, ent->item);
196 			else
197 				gi.dprintf("Powerup has no use function!\n");
198 //PGM
199 		}
200 	}
201 
202 	return true;
203 }
204 
Drop_General(edict_t * ent,gitem_t * item)205 void Drop_General (edict_t *ent, gitem_t *item)
206 {
207 	Drop_Item (ent, item);
208 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
209 	ValidateSelectedItem (ent);
210 }
211 
212 
213 //======================================================================
214 
Pickup_Adrenaline(edict_t * ent,edict_t * other)215 qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other)
216 {
217 	if (!deathmatch->value)
218 		other->max_health += 1;
219 
220 	if (other->health < other->max_health)
221 		other->health = other->max_health;
222 
223 	if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
224 		SetRespawn (ent, ent->item->quantity);
225 
226 	return true;
227 }
228 
Pickup_AncientHead(edict_t * ent,edict_t * other)229 qboolean Pickup_AncientHead (edict_t *ent, edict_t *other)
230 {
231 	other->max_health += 2;
232 
233 	if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
234 		SetRespawn (ent, ent->item->quantity);
235 
236 	return true;
237 }
238 
Pickup_Bandolier(edict_t * ent,edict_t * other)239 qboolean Pickup_Bandolier (edict_t *ent, edict_t *other)
240 {
241 	gitem_t	*item;
242 	int		index;
243 
244 	if (other->client->pers.max_bullets < 250)
245 		other->client->pers.max_bullets = 250;
246 	if (other->client->pers.max_shells < 150)
247 		other->client->pers.max_shells = 150;
248 	if (other->client->pers.max_cells < 250)
249 		other->client->pers.max_cells = 250;
250 	if (other->client->pers.max_slugs < 75)
251 		other->client->pers.max_slugs = 75;
252 	//PMM
253 	if (other->client->pers.max_flechettes < 250)
254 		other->client->pers.max_flechettes = 250;
255 #ifndef KILL_DISRUPTOR
256 	if (other->client->pers.max_rounds < 150)
257 		other->client->pers.max_rounds = 150;
258 #endif
259 	//pmm
260 
261 	item = FindItem("Bullets");
262 	if (item)
263 	{
264 		index = ITEM_INDEX(item);
265 		other->client->pers.inventory[index] += item->quantity;
266 		if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
267 			other->client->pers.inventory[index] = other->client->pers.max_bullets;
268 	}
269 
270 	item = FindItem("Shells");
271 	if (item)
272 	{
273 		index = ITEM_INDEX(item);
274 		other->client->pers.inventory[index] += item->quantity;
275 		if (other->client->pers.inventory[index] > other->client->pers.max_shells)
276 			other->client->pers.inventory[index] = other->client->pers.max_shells;
277 	}
278 
279 	if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
280 		SetRespawn (ent, ent->item->quantity);
281 
282 	return true;
283 }
284 
Pickup_Pack(edict_t * ent,edict_t * other)285 qboolean Pickup_Pack (edict_t *ent, edict_t *other)
286 {
287 	gitem_t	*item;
288 	int		index;
289 
290 	if (other->client->pers.max_bullets < 300)
291 		other->client->pers.max_bullets = 300;
292 	if (other->client->pers.max_shells < 200)
293 		other->client->pers.max_shells = 200;
294 	if (other->client->pers.max_rockets < 100)
295 		other->client->pers.max_rockets = 100;
296 	if (other->client->pers.max_grenades < 100)
297 		other->client->pers.max_grenades = 100;
298 	if (other->client->pers.max_cells < 300)
299 		other->client->pers.max_cells = 300;
300 	if (other->client->pers.max_slugs < 100)
301 		other->client->pers.max_slugs = 100;
302 	//PMM
303 	if (other->client->pers.max_flechettes < 200)
304 		other->client->pers.max_flechettes = 200;
305 #ifndef KILL_DISRUPTOR
306 	if (other->client->pers.max_rounds < 200)
307 		other->client->pers.max_rounds = 200;
308 #endif
309 	//pmm
310 
311 	item = FindItem("Bullets");
312 	if (item)
313 	{
314 		index = ITEM_INDEX(item);
315 		other->client->pers.inventory[index] += item->quantity;
316 		if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
317 			other->client->pers.inventory[index] = other->client->pers.max_bullets;
318 	}
319 
320 	item = FindItem("Shells");
321 	if (item)
322 	{
323 		index = ITEM_INDEX(item);
324 		other->client->pers.inventory[index] += item->quantity;
325 		if (other->client->pers.inventory[index] > other->client->pers.max_shells)
326 			other->client->pers.inventory[index] = other->client->pers.max_shells;
327 	}
328 
329 	item = FindItem("Cells");
330 	if (item)
331 	{
332 		index = ITEM_INDEX(item);
333 		other->client->pers.inventory[index] += item->quantity;
334 		if (other->client->pers.inventory[index] > other->client->pers.max_cells)
335 			other->client->pers.inventory[index] = other->client->pers.max_cells;
336 	}
337 
338 	item = FindItem("Grenades");
339 	if (item)
340 	{
341 		index = ITEM_INDEX(item);
342 		other->client->pers.inventory[index] += item->quantity;
343 		if (other->client->pers.inventory[index] > other->client->pers.max_grenades)
344 			other->client->pers.inventory[index] = other->client->pers.max_grenades;
345 	}
346 
347 	item = FindItem("Rockets");
348 	if (item)
349 	{
350 		index = ITEM_INDEX(item);
351 		other->client->pers.inventory[index] += item->quantity;
352 		if (other->client->pers.inventory[index] > other->client->pers.max_rockets)
353 			other->client->pers.inventory[index] = other->client->pers.max_rockets;
354 	}
355 
356 	item = FindItem("Slugs");
357 	if (item)
358 	{
359 		index = ITEM_INDEX(item);
360 		other->client->pers.inventory[index] += item->quantity;
361 		if (other->client->pers.inventory[index] > other->client->pers.max_slugs)
362 			other->client->pers.inventory[index] = other->client->pers.max_slugs;
363 	}
364 //PMM
365 	item = FindItem("Flechettes");
366 	if (item)
367 	{
368 		index = ITEM_INDEX(item);
369 		other->client->pers.inventory[index] += item->quantity;
370 		if (other->client->pers.inventory[index] > other->client->pers.max_flechettes)
371 			other->client->pers.inventory[index] = other->client->pers.max_flechettes;
372 	}
373 #ifndef KILL_DISRUPTOR
374 	item = FindItem("Rounds");
375 	if (item)
376 	{
377 		index = ITEM_INDEX(item);
378 		other->client->pers.inventory[index] += item->quantity;
379 		if (other->client->pers.inventory[index] > other->client->pers.max_rounds)
380 			other->client->pers.inventory[index] = other->client->pers.max_rounds;
381 	}
382 #endif
383 //pmm
384 	if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
385 		SetRespawn (ent, ent->item->quantity);
386 
387 	return true;
388 }
389 // ================
390 // PMM
Pickup_Nuke(edict_t * ent,edict_t * other)391 qboolean Pickup_Nuke (edict_t *ent, edict_t *other)
392 {
393 	int		quantity;
394 
395 //	if (!deathmatch->value)
396 //		return;
397 	quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
398 //	if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
399 //		return false;
400 
401 	if (quantity >= 1)
402 		return false;
403 
404 	if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
405 		return false;
406 
407 	other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
408 
409 	if (deathmatch->value)
410 	{
411 		if (!(ent->spawnflags & DROPPED_ITEM) )
412 			SetRespawn (ent, ent->item->quantity);
413 	}
414 
415 	return true;
416 }
417 
418 // ================
419 // PGM
Use_IR(edict_t * ent,gitem_t * item)420 void Use_IR (edict_t *ent, gitem_t *item)
421 {
422 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
423 	ValidateSelectedItem (ent);
424 
425 	if (ent->client->ir_framenum > level.framenum)
426 		ent->client->ir_framenum += 600;
427 	else
428 		ent->client->ir_framenum = level.framenum + 600;
429 
430 	gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/ir_start.wav"), 1, ATTN_NORM, 0);
431 }
432 
Use_Double(edict_t * ent,gitem_t * item)433 void Use_Double (edict_t *ent, gitem_t *item)
434 {
435 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
436 	ValidateSelectedItem (ent);
437 
438 	if (ent->client->double_framenum > level.framenum)
439 		ent->client->double_framenum += 300;
440 	else
441 		ent->client->double_framenum = level.framenum + 300;
442 
443 	gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/ddamage1.wav"), 1, ATTN_NORM, 0);
444 }
445 
446 /*
447 void Use_Torch (edict_t *ent, gitem_t *item)
448 {
449 	ent->client->torch_framenum = level.framenum + 600;
450 }
451 */
452 
Use_Compass(edict_t * ent,gitem_t * item)453 void Use_Compass (edict_t *ent, gitem_t *item)
454 {
455 	int ang;
456 
457 	ang = (int)(ent->client->v_angle[1]);
458 	if(ang<0)
459 		ang += 360;
460 
461 	gi.cprintf(ent, PRINT_HIGH, "Origin: %0.0f,%0.0f,%0.0f    Dir: %d\n", ent->s.origin[0], ent->s.origin[1],
462 				ent->s.origin[2], ang);
463 }
464 
Use_Nuke(edict_t * ent,gitem_t * item)465 void Use_Nuke (edict_t *ent, gitem_t *item)
466 {
467 	vec3_t	forward, right, start;
468 	float	speed;
469 
470 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
471 	ValidateSelectedItem (ent);
472 
473 	AngleVectors (ent->client->v_angle, forward, right, NULL);
474 
475 	VectorCopy (ent->s.origin, start);
476 	speed = 100;
477 	fire_nuke (ent, start, forward, speed);
478 }
479 
Use_Doppleganger(edict_t * ent,gitem_t * item)480 void Use_Doppleganger (edict_t *ent, gitem_t *item)
481 {
482 	vec3_t		forward, right;
483 	vec3_t		createPt, spawnPt;
484 	vec3_t		ang;
485 
486 	VectorClear(ang);
487 	ang[YAW] = ent->client->v_angle[YAW];
488 	AngleVectors (ang, forward, right, NULL);
489 
490 	VectorMA(ent->s.origin, 48, forward, createPt);
491 
492 	if(!FindSpawnPoint(createPt, ent->mins, ent->maxs, spawnPt, 32))
493 		return;
494 
495 	if(!CheckGroundSpawnPoint(spawnPt, ent->mins, ent->maxs, 64, -1))
496 		return;
497 
498 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
499 	ValidateSelectedItem (ent);
500 
501 	SpawnGrow_Spawn (spawnPt, 0);
502 	fire_doppleganger (ent, spawnPt, forward);
503 }
504 
Pickup_Doppleganger(edict_t * ent,edict_t * other)505 qboolean Pickup_Doppleganger (edict_t *ent, edict_t *other)
506 {
507 	int		quantity;
508 
509 	if(!(deathmatch->value))		// item is DM only
510 		return false;
511 
512 	quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
513 	if (quantity >= 1)		// FIXME - apply max to dopplegangers
514 		return false;
515 
516 	other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
517 
518 	if (!(ent->spawnflags & DROPPED_ITEM) )
519 		SetRespawn (ent, ent->item->quantity);
520 
521 	return true;
522 }
523 
524 
Pickup_Sphere(edict_t * ent,edict_t * other)525 qboolean Pickup_Sphere (edict_t *ent, edict_t *other)
526 {
527 	int		quantity;
528 
529 	if(other->client && other->client->owned_sphere)
530 	{
531 //		gi.cprintf(other, PRINT_HIGH, "Only one sphere to a customer!\n");
532 		return false;
533 	}
534 
535 	quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
536 	if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
537 		return false;
538 
539 	if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
540 		return false;
541 
542 	other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
543 
544 	if (deathmatch->value)
545 	{
546 		if (!(ent->spawnflags & DROPPED_ITEM) )
547 			SetRespawn (ent, ent->item->quantity);
548 		if (((int)dmflags->value & DF_INSTANT_ITEMS))
549 		{
550 //PGM
551 			if(ent->item->use)
552 				ent->item->use (other, ent->item);
553 			else
554 				gi.dprintf("Powerup has no use function!\n");
555 //PGM
556 		}
557 	}
558 
559 	return true;
560 }
561 
Use_Defender(edict_t * ent,gitem_t * item)562 void Use_Defender (edict_t *ent, gitem_t *item)
563 {
564 	if(ent->client && ent->client->owned_sphere)
565 	{
566 		gi.cprintf(ent, PRINT_HIGH, "Only one sphere at a time!\n");
567 		return;
568 	}
569 
570 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
571 	ValidateSelectedItem (ent);
572 
573 	Defender_Launch (ent);
574 }
575 
Use_Hunter(edict_t * ent,gitem_t * item)576 void Use_Hunter (edict_t *ent, gitem_t *item)
577 {
578 	if(ent->client && ent->client->owned_sphere)
579 	{
580 		gi.cprintf(ent, PRINT_HIGH, "Only one sphere at a time!\n");
581 		return;
582 	}
583 
584 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
585 	ValidateSelectedItem (ent);
586 
587 	Hunter_Launch (ent);
588 }
589 
Use_Vengeance(edict_t * ent,gitem_t * item)590 void Use_Vengeance (edict_t *ent, gitem_t *item)
591 {
592 	if(ent->client && ent->client->owned_sphere)
593 	{
594 		gi.cprintf(ent, PRINT_HIGH, "Only one sphere at a time!\n");
595 		return;
596 	}
597 
598 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
599 	ValidateSelectedItem (ent);
600 
601 	Vengeance_Launch (ent);
602 }
603 
604 // PGM
605 // ================
606 
607 
608 //======================================================================
609 
Use_Quad(edict_t * ent,gitem_t * item)610 void Use_Quad (edict_t *ent, gitem_t *item)
611 {
612 	int		timeout;
613 
614 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
615 	ValidateSelectedItem (ent);
616 
617 	if (quad_drop_timeout_hack)
618 	{
619 		timeout = quad_drop_timeout_hack;
620 		quad_drop_timeout_hack = 0;
621 	}
622 	else
623 	{
624 		timeout = 300;
625 	}
626 
627 	if (ent->client->quad_framenum > level.framenum)
628 		ent->client->quad_framenum += timeout;
629 	else
630 		ent->client->quad_framenum = level.framenum + timeout;
631 
632 	gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
633 }
634 
635 //======================================================================
636 
Use_Breather(edict_t * ent,gitem_t * item)637 void Use_Breather (edict_t *ent, gitem_t *item)
638 {
639 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
640 	ValidateSelectedItem (ent);
641 
642 	if (ent->client->breather_framenum > level.framenum)
643 		ent->client->breather_framenum += 300;
644 	else
645 		ent->client->breather_framenum = level.framenum + 300;
646 
647 //	gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
648 }
649 
650 //======================================================================
651 
Use_Envirosuit(edict_t * ent,gitem_t * item)652 void Use_Envirosuit (edict_t *ent, gitem_t *item)
653 {
654 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
655 	ValidateSelectedItem (ent);
656 
657 	if (ent->client->enviro_framenum > level.framenum)
658 		ent->client->enviro_framenum += 300;
659 	else
660 		ent->client->enviro_framenum = level.framenum + 300;
661 
662 //	gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
663 }
664 
665 //======================================================================
666 
Use_Invulnerability(edict_t * ent,gitem_t * item)667 void	Use_Invulnerability (edict_t *ent, gitem_t *item)
668 {
669 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
670 	ValidateSelectedItem (ent);
671 
672 	if (ent->client->invincible_framenum > level.framenum)
673 		ent->client->invincible_framenum += 300;
674 	else
675 		ent->client->invincible_framenum = level.framenum + 300;
676 
677 	gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0);
678 }
679 
680 //======================================================================
681 
Use_Silencer(edict_t * ent,gitem_t * item)682 void	Use_Silencer (edict_t *ent, gitem_t *item)
683 {
684 	ent->client->pers.inventory[ITEM_INDEX(item)]--;
685 	ValidateSelectedItem (ent);
686 	ent->client->silencer_shots += 30;
687 
688 //	gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
689 }
690 
691 //======================================================================
692 
Pickup_Key(edict_t * ent,edict_t * other)693 qboolean Pickup_Key (edict_t *ent, edict_t *other)
694 {
695 	if (coop->value)
696 	{
697 		if (strcmp(ent->classname, "key_power_cube") == 0)
698 		{
699 			if (other->client->pers.power_cubes & ((ent->spawnflags & 0x0000ff00)>> 8))
700 				return false;
701 			other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
702 			other->client->pers.power_cubes |= ((ent->spawnflags & 0x0000ff00) >> 8);
703 		}
704 		else
705 		{
706 			if (other->client->pers.inventory[ITEM_INDEX(ent->item)])
707 				return false;
708 			other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1;
709 		}
710 		return true;
711 	}
712 	other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
713 	return true;
714 }
715 
716 //======================================================================
717 
Add_Ammo(edict_t * ent,gitem_t * item,int count)718 qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count)
719 {
720 	int			index;
721 	int			max;
722 
723 	if (!ent->client)
724 		return false;
725 
726 	if (item->tag == AMMO_BULLETS)
727 		max = ent->client->pers.max_bullets;
728 	else if (item->tag == AMMO_SHELLS)
729 		max = ent->client->pers.max_shells;
730 	else if (item->tag == AMMO_ROCKETS)
731 		max = ent->client->pers.max_rockets;
732 	else if (item->tag == AMMO_GRENADES)
733 		max = ent->client->pers.max_grenades;
734 	else if (item->tag == AMMO_CELLS)
735 		max = ent->client->pers.max_cells;
736 	else if (item->tag == AMMO_SLUGS)
737 		max = ent->client->pers.max_slugs;
738 // ROGUE
739 //	else if (item->tag == AMMO_MINES)
740 //		max = ent->client->pers.max_mines;
741 	else if (item->tag == AMMO_FLECHETTES)
742 		max = ent->client->pers.max_flechettes;
743 	else if (item->tag == AMMO_PROX)
744 		max = ent->client->pers.max_prox;
745 	else if (item->tag == AMMO_TESLA)
746 		max = ent->client->pers.max_tesla;
747 #ifndef KILL_DISRUPTOR
748 	else if (item->tag == AMMO_DISRUPTOR)
749 		max = ent->client->pers.max_rounds;
750 #endif
751 // ROGUE
752 	else
753 	{
754 		gi.dprintf("undefined ammo type\n");
755 		return false;
756 	}
757 
758 	index = ITEM_INDEX(item);
759 
760 	if (ent->client->pers.inventory[index] == max)
761 		return false;
762 
763 	ent->client->pers.inventory[index] += count;
764 
765 	if (ent->client->pers.inventory[index] > max)
766 		ent->client->pers.inventory[index] = max;
767 
768 	return true;
769 }
770 
Pickup_Ammo(edict_t * ent,edict_t * other)771 qboolean Pickup_Ammo (edict_t *ent, edict_t *other)
772 {
773 	int			oldcount;
774 	int			count;
775 	qboolean	weapon;
776 
777 	weapon = (ent->item->flags & IT_WEAPON);
778 	if ( (weapon) && ( (int)dmflags->value & DF_INFINITE_AMMO ) )
779 		count = 1000;
780 	else if (ent->count)
781 		count = ent->count;
782 	else
783 		count = ent->item->quantity;
784 
785 	oldcount = other->client->pers.inventory[ITEM_INDEX(ent->item)];
786 
787 	if (!Add_Ammo (other, ent->item, count))
788 		return false;
789 
790 	if (weapon && !oldcount)
791 	{
792 		// don't switch to tesla
793 		if (other->client->pers.weapon != ent->item
794 				&& ( !deathmatch->value || other->client->pers.weapon == FindItem("blaster"))
795 				&& (strcmp(ent->classname, "ammo_tesla")) )
796 
797 			other->client->newweapon = ent->item;
798 	}
799 
800 	if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && (deathmatch->value))
801 		SetRespawn (ent, 30);
802 	return true;
803 }
804 
Drop_Ammo(edict_t * ent,gitem_t * item)805 void Drop_Ammo (edict_t *ent, gitem_t *item)
806 {
807 	edict_t	*dropped;
808 	int		index;
809 
810 	index = ITEM_INDEX(item);
811 	dropped = Drop_Item (ent, item);
812 	if (ent->client->pers.inventory[index] >= item->quantity)
813 		dropped->count = item->quantity;
814 	else
815 		dropped->count = ent->client->pers.inventory[index];
816 
817 	if (ent->client->pers.weapon &&
818 		ent->client->pers.weapon->tag == AMMO_GRENADES &&
819 		item->tag == AMMO_GRENADES &&
820 		ent->client->pers.inventory[index] - dropped->count <= 0) {
821 		gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
822 		G_FreeEdict(dropped);
823 		return;
824 	}
825 
826 	ent->client->pers.inventory[index] -= dropped->count;
827 	ValidateSelectedItem (ent);
828 }
829 
830 
831 //======================================================================
832 
MegaHealth_think(edict_t * self)833 void MegaHealth_think (edict_t *self)
834 {
835 	if (self->owner->health > self->owner->max_health)
836 	{
837 		self->nextthink = level.time + 1;
838 		self->owner->health -= 1;
839 		return;
840 	}
841 
842 	if (!(self->spawnflags & DROPPED_ITEM) && (deathmatch->value))
843 		SetRespawn (self, 20);
844 	else
845 		G_FreeEdict (self);
846 }
847 
Pickup_Health(edict_t * ent,edict_t * other)848 qboolean Pickup_Health (edict_t *ent, edict_t *other)
849 {
850 	if (!(ent->style & HEALTH_IGNORE_MAX))
851 		if (other->health >= other->max_health)
852 			return false;
853 
854 	other->health += ent->count;
855 
856 	// PMM - health sound fix
857 	/*
858 	if (ent->count == 2)
859 		ent->item->pickup_sound = "items/s_health.wav";
860 	else if (ent->count == 10)
861 		ent->item->pickup_sound = "items/n_health.wav";
862 	else if (ent->count == 25)
863 		ent->item->pickup_sound = "items/l_health.wav";
864 	else // (ent->count == 100)
865 		ent->item->pickup_sound = "items/m_health.wav";
866 	*/
867 
868 	if (!(ent->style & HEALTH_IGNORE_MAX))
869 	{
870 		if (other->health > other->max_health)
871 			other->health = other->max_health;
872 	}
873 
874 	if (ent->style & HEALTH_TIMED)
875 	{
876 		ent->think = MegaHealth_think;
877 		ent->nextthink = level.time + 5;
878 		ent->owner = other;
879 		ent->flags |= FL_RESPAWN;
880 		ent->svflags |= SVF_NOCLIENT;
881 		ent->solid = SOLID_NOT;
882 	}
883 	else
884 	{
885 		if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
886 			SetRespawn (ent, 30);
887 	}
888 
889 	return true;
890 }
891 
892 //======================================================================
893 
ArmorIndex(edict_t * ent)894 int ArmorIndex (edict_t *ent)
895 {
896 	if (!ent->client)
897 		return 0;
898 
899 	if (ent->client->pers.inventory[jacket_armor_index] > 0)
900 		return jacket_armor_index;
901 
902 	if (ent->client->pers.inventory[combat_armor_index] > 0)
903 		return combat_armor_index;
904 
905 	if (ent->client->pers.inventory[body_armor_index] > 0)
906 		return body_armor_index;
907 
908 	return 0;
909 }
910 
Pickup_Armor(edict_t * ent,edict_t * other)911 qboolean Pickup_Armor (edict_t *ent, edict_t *other)
912 {
913 	int				old_armor_index;
914 	gitem_armor_t	*oldinfo;
915 	gitem_armor_t	*newinfo;
916 	int				newcount;
917 	float			salvage;
918 	int				salvagecount;
919 
920 	// get info on new armor
921 	newinfo = (gitem_armor_t *)ent->item->info;
922 
923 	old_armor_index = ArmorIndex (other);
924 
925 	// handle armor shards specially
926 	if (ent->item->tag == ARMOR_SHARD)
927 	{
928 		if (!old_armor_index)
929 			other->client->pers.inventory[jacket_armor_index] = 2;
930 		else
931 			other->client->pers.inventory[old_armor_index] += 2;
932 	}
933 
934 	// if player has no armor, just use it
935 	else if (!old_armor_index)
936 	{
937 		other->client->pers.inventory[ITEM_INDEX(ent->item)] = newinfo->base_count;
938 	}
939 
940 	// use the better armor
941 	else
942 	{
943 		// get info on old armor
944 		if (old_armor_index == jacket_armor_index)
945 			oldinfo = &jacketarmor_info;
946 		else if (old_armor_index == combat_armor_index)
947 			oldinfo = &combatarmor_info;
948 		else // (old_armor_index == body_armor_index)
949 			oldinfo = &bodyarmor_info;
950 
951 		if (newinfo->normal_protection > oldinfo->normal_protection)
952 		{
953 			// calc new armor values
954 			salvage = oldinfo->normal_protection / newinfo->normal_protection;
955 			salvagecount = salvage * other->client->pers.inventory[old_armor_index];
956 			newcount = newinfo->base_count + salvagecount;
957 			if (newcount > newinfo->max_count)
958 				newcount = newinfo->max_count;
959 
960 			// zero count of old armor so it goes away
961 			other->client->pers.inventory[old_armor_index] = 0;
962 
963 			// change armor to new item with computed value
964 			other->client->pers.inventory[ITEM_INDEX(ent->item)] = newcount;
965 		}
966 		else
967 		{
968 			// calc new armor values
969 			salvage = newinfo->normal_protection / oldinfo->normal_protection;
970 			salvagecount = salvage * newinfo->base_count;
971 			newcount = other->client->pers.inventory[old_armor_index] + salvagecount;
972 			if (newcount > oldinfo->max_count)
973 				newcount = oldinfo->max_count;
974 
975 			// if we're already maxed out then we don't need the new armor
976 			if (other->client->pers.inventory[old_armor_index] >= newcount)
977 				return false;
978 
979 			// update current armor value
980 			other->client->pers.inventory[old_armor_index] = newcount;
981 		}
982 	}
983 
984 	if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
985 		SetRespawn (ent, 20);
986 
987 	return true;
988 }
989 
990 //======================================================================
991 
PowerArmorType(edict_t * ent)992 int PowerArmorType (edict_t *ent)
993 {
994 	if (!ent->client)
995 		return POWER_ARMOR_NONE;
996 
997 	if (!(ent->flags & FL_POWER_ARMOR))
998 		return POWER_ARMOR_NONE;
999 
1000 	if (ent->client->pers.inventory[power_shield_index] > 0)
1001 		return POWER_ARMOR_SHIELD;
1002 
1003 	if (ent->client->pers.inventory[power_screen_index] > 0)
1004 		return POWER_ARMOR_SCREEN;
1005 
1006 	return POWER_ARMOR_NONE;
1007 }
1008 
Use_PowerArmor(edict_t * ent,gitem_t * item)1009 void Use_PowerArmor (edict_t *ent, gitem_t *item)
1010 {
1011 	int		index;
1012 
1013 	if (ent->flags & FL_POWER_ARMOR)
1014 	{
1015 		ent->flags &= ~FL_POWER_ARMOR;
1016 		gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
1017 	}
1018 	else
1019 	{
1020 		index = ITEM_INDEX(FindItem("cells"));
1021 		if (!ent->client->pers.inventory[index])
1022 		{
1023 			gi.cprintf (ent, PRINT_HIGH, "No cells for power armor.\n");
1024 			return;
1025 		}
1026 		ent->flags |= FL_POWER_ARMOR;
1027 		gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0);
1028 	}
1029 }
1030 
Pickup_PowerArmor(edict_t * ent,edict_t * other)1031 qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other)
1032 {
1033 	int		quantity;
1034 
1035 	quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
1036 
1037 	other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
1038 
1039 	if (deathmatch->value)
1040 	{
1041 		if (!(ent->spawnflags & DROPPED_ITEM) )
1042 			SetRespawn (ent, ent->item->quantity);
1043 		// auto-use for DM only if we didn't already have one
1044 		if (!quantity)
1045 			ent->item->use (other, ent->item);
1046 	}
1047 
1048 	return true;
1049 }
1050 
Drop_PowerArmor(edict_t * ent,gitem_t * item)1051 void Drop_PowerArmor (edict_t *ent, gitem_t *item)
1052 {
1053 	if ((ent->flags & FL_POWER_ARMOR) && (ent->client->pers.inventory[ITEM_INDEX(item)] == 1))
1054 		Use_PowerArmor (ent, item);
1055 	Drop_General (ent, item);
1056 }
1057 
1058 //======================================================================
1059 
1060 /*
1061 ===============
1062 Touch_Item
1063 ===============
1064 */
Touch_Item(edict_t * ent,edict_t * other,cplane_t * plane,csurface_t * surf)1065 void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
1066 {
1067 	qboolean	taken;
1068 
1069 	if (!other->client)
1070 		return;
1071 	if (other->health < 1)
1072 		return;		// dead people can't pickup
1073 	if (!ent->item->pickup)
1074 		return;		// not a grabbable item?
1075 
1076 	taken = ent->item->pickup(ent, other);
1077 
1078 	if (taken)
1079 	{
1080 		// flash the screen
1081 		other->client->bonus_alpha = 0.25;
1082 
1083 		// show icon and name on status bar
1084 		other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(ent->item->icon);
1085 		other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+ITEM_INDEX(ent->item);
1086 		other->client->pickup_msg_time = level.time + 3.0;
1087 
1088 		// change selected item
1089 		if (ent->item->use)
1090 			other->client->pers.selected_item = other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX(ent->item);
1091 
1092 		// PMM - health sound fix
1093 		if (ent->item->pickup == Pickup_Health)
1094 		{
1095 			if (ent->count == 2)
1096 				gi.sound(other, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0);
1097 			else if (ent->count == 10)
1098 				gi.sound(other, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0);
1099 			else if (ent->count == 25)
1100 				gi.sound(other, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0);
1101 			else // (ent->count == 100)
1102 				gi.sound(other, CHAN_ITEM, gi.soundindex("items/m_health.wav"), 1, ATTN_NORM, 0);
1103 		}
1104 		else if (ent->item->pickup_sound) // PGM - paranoia
1105 		{
1106 		//
1107 			gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0);
1108 		}
1109 	}
1110 
1111 	if (!(ent->spawnflags & ITEM_TARGETS_USED))
1112 	{
1113 		G_UseTargets (ent, other);
1114 		ent->spawnflags |= ITEM_TARGETS_USED;
1115 	}
1116 
1117 	if (!taken)
1118 		return;
1119 
1120 	if (!((coop->value) &&  (ent->item->flags & IT_STAY_COOP)) || (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)))
1121 	{
1122 		if (ent->flags & FL_RESPAWN)
1123 			ent->flags &= ~FL_RESPAWN;
1124 		else
1125 			G_FreeEdict (ent);
1126 	}
1127 }
1128 
1129 //======================================================================
1130 
drop_temp_touch(edict_t * ent,edict_t * other,cplane_t * plane,csurface_t * surf)1131 static void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
1132 {
1133 	if (other == ent->owner)
1134 		return;
1135 
1136 	Touch_Item (ent, other, plane, surf);
1137 }
1138 
drop_make_touchable(edict_t * ent)1139 static void drop_make_touchable (edict_t *ent)
1140 {
1141 	ent->touch = Touch_Item;
1142 	if (deathmatch->value)
1143 	{
1144 		ent->nextthink = level.time + 29;
1145 		ent->think = G_FreeEdict;
1146 	}
1147 }
1148 
Drop_Item(edict_t * ent,gitem_t * item)1149 edict_t *Drop_Item (edict_t *ent, gitem_t *item)
1150 {
1151 	edict_t	*dropped;
1152 	vec3_t	forward, right;
1153 	vec3_t	offset;
1154 
1155 	dropped = G_Spawn();
1156 
1157 	dropped->classname = item->classname;
1158 	dropped->item = item;
1159 	dropped->spawnflags = DROPPED_ITEM;
1160 	dropped->s.effects = item->world_model_flags;
1161 	dropped->s.renderfx = RF_GLOW | RF_IR_VISIBLE;		// PGM
1162 	VectorSet (dropped->mins, -15, -15, -15);
1163 	VectorSet (dropped->maxs, 15, 15, 15);
1164 	gi.setmodel (dropped, dropped->item->world_model);
1165 	dropped->solid = SOLID_TRIGGER;
1166 	dropped->movetype = MOVETYPE_TOSS;
1167 	dropped->touch = drop_temp_touch;
1168 	dropped->owner = ent;
1169 
1170 	if (ent->client)
1171 	{
1172 		trace_t	trace;
1173 
1174 		AngleVectors (ent->client->v_angle, forward, right, NULL);
1175 		VectorSet(offset, 24, 0, -16);
1176 		G_ProjectSource (ent->s.origin, offset, forward, right, dropped->s.origin);
1177 		trace = gi.trace (ent->s.origin, dropped->mins, dropped->maxs,
1178 			dropped->s.origin, ent, CONTENTS_SOLID);
1179 		VectorCopy (trace.endpos, dropped->s.origin);
1180 	}
1181 	else
1182 	{
1183 		AngleVectors (ent->s.angles, forward, right, NULL);
1184 		VectorCopy (ent->s.origin, dropped->s.origin);
1185 	}
1186 
1187 	VectorScale (forward, 100, dropped->velocity);
1188 	dropped->velocity[2] = 300;
1189 
1190 	dropped->think = drop_make_touchable;
1191 	dropped->nextthink = level.time + 1;
1192 
1193 	gi.linkentity (dropped);
1194 
1195 	return dropped;
1196 }
1197 
Use_Item(edict_t * ent,edict_t * other,edict_t * activator)1198 void Use_Item (edict_t *ent, edict_t *other, edict_t *activator)
1199 {
1200 	ent->svflags &= ~SVF_NOCLIENT;
1201 	ent->use = NULL;
1202 
1203 	if (ent->spawnflags & ITEM_NO_TOUCH)
1204 	{
1205 		ent->solid = SOLID_BBOX;
1206 		ent->touch = NULL;
1207 	}
1208 	else
1209 	{
1210 		ent->solid = SOLID_TRIGGER;
1211 		ent->touch = Touch_Item;
1212 	}
1213 
1214 	gi.linkentity (ent);
1215 }
1216 
1217 //======================================================================
1218 
1219 /*
1220 ================
1221 droptofloor
1222 ================
1223 */
droptofloor(edict_t * ent)1224 void droptofloor (edict_t *ent)
1225 {
1226 	trace_t		tr;
1227 	vec3_t		dest;
1228 	float		*v;
1229 
1230 	v = tv(-15,-15,-15);
1231 	VectorCopy (v, ent->mins);
1232 	v = tv(15,15,15);
1233 	VectorCopy (v, ent->maxs);
1234 
1235 	if (ent->model)
1236 		gi.setmodel (ent, ent->model);
1237 	else if (ent->item->world_model)	// PGM we shouldn't need this check, but paranoia...
1238 		gi.setmodel (ent, ent->item->world_model);
1239 	ent->solid = SOLID_TRIGGER;
1240 	ent->movetype = MOVETYPE_TOSS;
1241 	ent->touch = Touch_Item;
1242 
1243 	v = tv(0,0,-128);
1244 	VectorAdd (ent->s.origin, v, dest);
1245 
1246 	tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID);
1247 	if (tr.startsolid)
1248 	{
1249 		gi.dprintf ("droptofloor: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin));
1250 		G_FreeEdict (ent);
1251 		return;
1252 	}
1253 
1254 	VectorCopy (tr.endpos, ent->s.origin);
1255 
1256 	if (ent->team)
1257 	{
1258 		ent->flags &= ~FL_TEAMSLAVE;
1259 		ent->chain = ent->teamchain;
1260 		ent->teamchain = NULL;
1261 
1262 		ent->svflags |= SVF_NOCLIENT;
1263 		ent->solid = SOLID_NOT;
1264 		if (ent == ent->teammaster)
1265 		{
1266 			ent->nextthink = level.time + FRAMETIME;
1267 			ent->think = DoRespawn;
1268 		}
1269 	}
1270 
1271 	if (ent->spawnflags & ITEM_NO_TOUCH)
1272 	{
1273 		ent->solid = SOLID_BBOX;
1274 		ent->touch = NULL;
1275 		ent->s.effects &= ~EF_ROTATE;
1276 		ent->s.renderfx &= ~RF_GLOW;
1277 	}
1278 
1279 	if (ent->spawnflags & ITEM_TRIGGER_SPAWN)
1280 	{
1281 		ent->svflags |= SVF_NOCLIENT;
1282 		ent->solid = SOLID_NOT;
1283 		ent->use = Use_Item;
1284 	}
1285 
1286 	gi.linkentity (ent);
1287 }
1288 
1289 
1290 /*
1291 ===============
1292 PrecacheItem
1293 
1294 Precaches all data needed for a given item.
1295 This will be called for each item spawned in a level,
1296 and for each item in each client's inventory.
1297 ===============
1298 */
PrecacheItem(gitem_t * it)1299 void PrecacheItem (gitem_t *it)
1300 {
1301 	char	*s, *start;
1302 	char	data[MAX_QPATH];
1303 	int		len;
1304 	gitem_t	*ammo;
1305 
1306 	if (!it)
1307 		return;
1308 
1309 	if (it->pickup_sound)
1310 		gi.soundindex (it->pickup_sound);
1311 	if (it->world_model)
1312 		gi.modelindex (it->world_model);
1313 	if (it->view_model)
1314 		gi.modelindex (it->view_model);
1315 	if (it->icon)
1316 		gi.imageindex (it->icon);
1317 
1318 	// parse everything for its ammo
1319 	if (it->ammo && it->ammo[0])
1320 	{
1321 		ammo = FindItem (it->ammo);
1322 		if (ammo != it)
1323 			PrecacheItem (ammo);
1324 	}
1325 
1326 	// parse the space seperated precache string for other items
1327 	s = it->precaches;
1328 	if (!s || !s[0])
1329 		return;
1330 
1331 	while (*s)
1332 	{
1333 		start = s;
1334 		while (*s && *s != ' ')
1335 			s++;
1336 
1337 		len = s-start;
1338 		if (len >= MAX_QPATH || len < 5)
1339 			gi.error ("PrecacheItem: %s has bad precache string", it->classname);
1340 		memcpy (data, start, len);
1341 		data[len] = 0;
1342 		if (*s)
1343 			s++;
1344 
1345 		// determine type based on extension
1346 		if (!strcmp(data+len-3, "md2"))
1347 			gi.modelindex (data);
1348 		else if (!strcmp(data+len-3, "sp2"))
1349 			gi.modelindex (data);
1350 		else if (!strcmp(data+len-3, "wav"))
1351 			gi.soundindex (data);
1352 		if (!strcmp(data+len-3, "pcx"))
1353 			gi.imageindex (data);
1354 	}
1355 }
1356 
1357 
1358 //=================
1359 // Item_TriggeredSpawn - create the item marked for spawn creation
1360 //=================
Item_TriggeredSpawn(edict_t * self,edict_t * other,edict_t * activator)1361 void Item_TriggeredSpawn (edict_t *self, edict_t *other, edict_t *activator)
1362 {
1363 //	self->nextthink = level.time + 2 * FRAMETIME;    // items start after other solids
1364 //	self->think = droptofloor;
1365 	self->svflags &= ~SVF_NOCLIENT;
1366 	self->use = NULL;
1367 	if(strcmp(self->classname, "key_power_cube"))	// leave them be on key_power_cube..
1368 		self->spawnflags = 0;
1369 	droptofloor (self);
1370 }
1371 
1372 //=================
1373 // SetTriggeredSpawn - set up an item to spawn in later.
1374 //=================
SetTriggeredSpawn(edict_t * ent)1375 void SetTriggeredSpawn (edict_t *ent)
1376 {
1377 	// don't do anything on key_power_cubes.
1378 	if(!strcmp(ent->classname, "key_power_cube"))
1379 		return;
1380 
1381 	ent->think = NULL;
1382 	ent->nextthink = 0;
1383 	ent->use = Item_TriggeredSpawn;
1384 	ent->svflags |= SVF_NOCLIENT;
1385 	ent->solid = SOLID_NOT;
1386 }
1387 
1388 /*
1389 ============
1390 SpawnItem
1391 
1392 Sets the clipping size and plants the object on the floor.
1393 
1394 Items can't be immediately dropped to floor, because they might
1395 be on an entity that hasn't spawned yet.
1396 ============
1397 */
SpawnItem(edict_t * ent,gitem_t * item)1398 void SpawnItem (edict_t *ent, gitem_t *item)
1399 {
1400 #if KILL_DISRUPTOR
1401 	if ((!strcmp(ent->classname, "ammo_disruptor")) || (!strcmp(ent->classname, "weapon_disintegrator")))
1402 	{
1403 		G_FreeEdict (ent);
1404 		return;
1405 	}
1406 #endif
1407 
1408 // PGM - since the item may be freed by the following rules, go ahead
1409 //		 and move the precache until AFTER the following rules have been checked.
1410 //		 keep an eye on this.
1411 //	PrecacheItem (item);
1412 
1413 	if (ent->spawnflags > 1)		// PGM
1414 	{
1415 		if (strcmp(ent->classname, "key_power_cube") != 0)
1416 		{
1417 			ent->spawnflags = 0;
1418 			gi.dprintf("%s at %s has invalid spawnflags set\n", ent->classname, vtos(ent->s.origin));
1419 		}
1420 	}
1421 
1422 	// some items will be prevented in deathmatch
1423 	if (deathmatch->value)
1424 	{
1425 		if ( (int)dmflags->value & DF_NO_ARMOR )
1426 		{
1427 			if (item->pickup == Pickup_Armor || item->pickup == Pickup_PowerArmor)
1428 			{
1429 				G_FreeEdict (ent);
1430 				return;
1431 			}
1432 		}
1433 		if ( (int)dmflags->value & DF_NO_ITEMS )
1434 		{
1435 			if (item->pickup == Pickup_Powerup)
1436 			{
1437 				G_FreeEdict (ent);
1438 				return;
1439 			}
1440 			//=====
1441 			//ROGUE
1442 			if (item->pickup  == Pickup_Sphere)
1443 			{
1444 				G_FreeEdict (ent);
1445 				return;
1446 			}
1447 			if (item->pickup == Pickup_Doppleganger)
1448 			{
1449 				G_FreeEdict (ent);
1450 				return;
1451 			}
1452 			//ROGUE
1453 			//=====
1454 		}
1455 		if ( (int)dmflags->value & DF_NO_HEALTH )
1456 		{
1457 			if (item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline || item->pickup == Pickup_AncientHead)
1458 			{
1459 				G_FreeEdict (ent);
1460 				return;
1461 			}
1462 		}
1463 		if ( (int)dmflags->value & DF_INFINITE_AMMO )
1464 		{
1465 			if ( (item->flags == IT_AMMO) || (strcmp(ent->classname, "weapon_bfg") == 0) )
1466 			{
1467 				G_FreeEdict (ent);
1468 				return;
1469 			}
1470 		}
1471 
1472 //==========
1473 //ROGUE
1474 		if ( (int)dmflags->value & DF_NO_MINES )
1475 		{
1476 			if ( !strcmp(ent->classname, "ammo_prox") ||
1477 				 !strcmp(ent->classname, "ammo_tesla") )
1478 			{
1479 				G_FreeEdict (ent);
1480 				return;
1481 			}
1482 		}
1483 		if ( (int)dmflags->value & DF_NO_NUKES )
1484 		{
1485 			if ( !strcmp(ent->classname, "ammo_nuke") )
1486 			{
1487 				G_FreeEdict (ent);
1488 				return;
1489 			}
1490 		}
1491 		if ( (int)dmflags->value & DF_NO_SPHERES )
1492 		{
1493 			if (item->pickup  == Pickup_Sphere)
1494 			{
1495 				G_FreeEdict (ent);
1496 				return;
1497 			}
1498 		}
1499 //ROGUE
1500 //==========
1501 
1502 	}
1503 //==========
1504 //ROGUE
1505 // DM only items
1506 	if (!deathmatch->value)
1507 	{
1508 		if (item->pickup == Pickup_Doppleganger || item->pickup == Pickup_Nuke)
1509 		{
1510 			G_FreeEdict (ent);
1511 			return;
1512 		}
1513 		if ((item->use == Use_Vengeance) || (item->use == Use_Hunter))
1514 		{
1515 			G_FreeEdict (ent);
1516 			return;
1517 		}
1518 	}
1519 //ROGUE
1520 //==========
1521 
1522 //PGM
1523 	PrecacheItem (item);
1524 //PGM
1525 
1526 	if (coop->value && (strcmp(ent->classname, "key_power_cube") == 0))
1527 	{
1528 		ent->spawnflags |= (1 << (8 + level.power_cubes));
1529 		level.power_cubes++;
1530 	}
1531 
1532 	// don't let them drop items that stay in a coop game
1533 	if ((coop->value) && (item->flags & IT_STAY_COOP))
1534 	{
1535 		item->drop = NULL;
1536 	}
1537 
1538 	ent->item = item;
1539 	ent->nextthink = level.time + 2 * FRAMETIME;    // items start after other solids
1540 	ent->think = droptofloor;
1541 	ent->s.effects = item->world_model_flags;
1542 	ent->s.renderfx = RF_GLOW;
1543 	if (ent->model)
1544 		gi.modelindex (ent->model);
1545 
1546 	if (ent->spawnflags & 1)
1547 		SetTriggeredSpawn (ent);
1548 }
1549 
1550 //======================================================================
1551 
1552 gitem_t	itemlist[] =
1553 {
1554 	{
1555 		NULL
1556 	},	// leave index 0 alone
1557 
1558 	//
1559 	// ARMOR
1560 	//
1561 
1562 /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1563 */
1564 	{
1565 		"item_armor_body",
1566 		Pickup_Armor,
1567 		NULL,
1568 		NULL,
1569 		NULL,
1570 		"misc/ar1_pkup.wav",
1571 		"models/items/armor/body/tris.md2", EF_ROTATE,
1572 		NULL,
1573 /* icon */		"i_bodyarmor",
1574 /* pickup */	"Body Armor",
1575 /* width */		3,
1576 		0,
1577 		NULL,
1578 		IT_ARMOR,
1579 		0,
1580 		&bodyarmor_info,
1581 		ARMOR_BODY,
1582 /* precache */ ""
1583 	},
1584 
1585 /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1586 */
1587 	{
1588 		"item_armor_combat",
1589 		Pickup_Armor,
1590 		NULL,
1591 		NULL,
1592 		NULL,
1593 		"misc/ar1_pkup.wav",
1594 		"models/items/armor/combat/tris.md2", EF_ROTATE,
1595 		NULL,
1596 /* icon */		"i_combatarmor",
1597 /* pickup */	"Combat Armor",
1598 /* width */		3,
1599 		0,
1600 		NULL,
1601 		IT_ARMOR,
1602 		0,
1603 		&combatarmor_info,
1604 		ARMOR_COMBAT,
1605 /* precache */ ""
1606 	},
1607 
1608 /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1609 */
1610 	{
1611 		"item_armor_jacket",
1612 		Pickup_Armor,
1613 		NULL,
1614 		NULL,
1615 		NULL,
1616 		"misc/ar1_pkup.wav",
1617 		"models/items/armor/jacket/tris.md2", EF_ROTATE,
1618 		NULL,
1619 /* icon */		"i_jacketarmor",
1620 /* pickup */	"Jacket Armor",
1621 /* width */		3,
1622 		0,
1623 		NULL,
1624 		IT_ARMOR,
1625 		0,
1626 		&jacketarmor_info,
1627 		ARMOR_JACKET,
1628 /* precache */ ""
1629 	},
1630 
1631 /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1632 */
1633 	{
1634 		"item_armor_shard",
1635 		Pickup_Armor,
1636 		NULL,
1637 		NULL,
1638 		NULL,
1639 		"misc/ar2_pkup.wav",
1640 		"models/items/armor/shard/tris.md2", EF_ROTATE,
1641 		NULL,
1642 /* icon */		"i_jacketarmor",
1643 /* pickup */	"Armor Shard",
1644 /* width */		3,
1645 		0,
1646 		NULL,
1647 		IT_ARMOR,
1648 		0,
1649 		NULL,
1650 		ARMOR_SHARD,
1651 /* precache */ ""
1652 	},
1653 
1654 
1655 /*QUAKED item_power_screen (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1656 */
1657 	{
1658 		"item_power_screen",
1659 		Pickup_PowerArmor,
1660 		Use_PowerArmor,
1661 		Drop_PowerArmor,
1662 		NULL,
1663 		"misc/ar3_pkup.wav",
1664 		"models/items/armor/screen/tris.md2", EF_ROTATE,
1665 		NULL,
1666 /* icon */		"i_powerscreen",
1667 /* pickup */	"Power Screen",
1668 /* width */		0,
1669 		60,
1670 		NULL,
1671 		IT_ARMOR,
1672 		0,
1673 		NULL,
1674 		0,
1675 /* precache */ ""
1676 	},
1677 
1678 /*QUAKED item_power_shield (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1679 */
1680 	{
1681 		"item_power_shield",
1682 		Pickup_PowerArmor,
1683 		Use_PowerArmor,
1684 		Drop_PowerArmor,
1685 		NULL,
1686 		"misc/ar3_pkup.wav",
1687 		"models/items/armor/shield/tris.md2", EF_ROTATE,
1688 		NULL,
1689 /* icon */		"i_powershield",
1690 /* pickup */	"Power Shield",
1691 /* width */		0,
1692 		60,
1693 		NULL,
1694 		IT_ARMOR,
1695 		0,
1696 		NULL,
1697 		0,
1698 /* precache */ "misc/power2.wav misc/power1.wav"
1699 	},
1700 
1701 
1702 	//
1703 	// WEAPONS
1704 	//
1705 
1706 /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16)
1707 always owned, never in the world
1708 */
1709 	{
1710 		"weapon_blaster",
1711 		NULL,
1712 		Use_Weapon,
1713 		NULL,
1714 		Weapon_Blaster,
1715 		"misc/w_pkup.wav",
1716 		NULL, 0,
1717 		"models/weapons/v_blast/tris.md2",
1718 /* icon */		"w_blaster",
1719 /* pickup */	"Blaster",
1720 		0,
1721 		0,
1722 		NULL,
1723 		IT_WEAPON|IT_STAY_COOP,
1724 		WEAP_BLASTER,
1725 		NULL,
1726 		0,
1727 /* precache */ "weapons/blastf1a.wav misc/lasfly.wav"
1728 	},
1729 
1730 /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1731 */
1732 	{
1733 		"weapon_shotgun",
1734 		Pickup_Weapon,
1735 		Use_Weapon,
1736 		Drop_Weapon,
1737 		Weapon_Shotgun,
1738 		"misc/w_pkup.wav",
1739 		"models/weapons/g_shotg/tris.md2", EF_ROTATE,
1740 		"models/weapons/v_shotg/tris.md2",
1741 /* icon */		"w_shotgun",
1742 /* pickup */	"Shotgun",
1743 		0,
1744 		1,
1745 		"Shells",
1746 		IT_WEAPON|IT_STAY_COOP,
1747 		WEAP_SHOTGUN,
1748 		NULL,
1749 		0,
1750 /* precache */ "weapons/shotgf1b.wav weapons/shotgr1b.wav"
1751 	},
1752 
1753 /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1754 */
1755 	{
1756 		"weapon_supershotgun",
1757 		Pickup_Weapon,
1758 		Use_Weapon,
1759 		Drop_Weapon,
1760 		Weapon_SuperShotgun,
1761 		"misc/w_pkup.wav",
1762 		"models/weapons/g_shotg2/tris.md2", EF_ROTATE,
1763 		"models/weapons/v_shotg2/tris.md2",
1764 /* icon */		"w_sshotgun",
1765 /* pickup */	"Super Shotgun",
1766 		0,
1767 		2,
1768 		"Shells",
1769 		IT_WEAPON|IT_STAY_COOP,
1770 		WEAP_SUPERSHOTGUN,
1771 		NULL,
1772 		0,
1773 /* precache */ "weapons/sshotf1b.wav"
1774 	},
1775 
1776 /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1777 */
1778 	{
1779 		"weapon_machinegun",
1780 		Pickup_Weapon,
1781 		Use_Weapon,
1782 		Drop_Weapon,
1783 		Weapon_Machinegun,
1784 		"misc/w_pkup.wav",
1785 		"models/weapons/g_machn/tris.md2", EF_ROTATE,
1786 		"models/weapons/v_machn/tris.md2",
1787 /* icon */		"w_machinegun",
1788 /* pickup */	"Machinegun",
1789 		0,
1790 		1,
1791 		"Bullets",
1792 		IT_WEAPON|IT_STAY_COOP,
1793 		WEAP_MACHINEGUN,
1794 		NULL,
1795 		0,
1796 /* precache */ "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav"
1797 	},
1798 
1799 /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1800 */
1801 	{
1802 		"weapon_chaingun",
1803 		Pickup_Weapon,
1804 		Use_Weapon,
1805 		Drop_Weapon,
1806 		Weapon_Chaingun,
1807 		"misc/w_pkup.wav",
1808 		"models/weapons/g_chain/tris.md2", EF_ROTATE,
1809 		"models/weapons/v_chain/tris.md2",
1810 /* icon */		"w_chaingun",
1811 /* pickup */	"Chaingun",
1812 		0,
1813 		1,
1814 		"Bullets",
1815 		IT_WEAPON|IT_STAY_COOP,
1816 		WEAP_CHAINGUN,
1817 		NULL,
1818 		0,
1819 /* precache */ "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav"
1820 	},
1821 
1822 	// ROGUE
1823 /*QUAKED weapon_etf_rifle (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1824 */
1825 	{
1826 		"weapon_etf_rifle",									// classname
1827 		Pickup_Weapon,										// pickup function
1828 		Use_Weapon,											// use function
1829 		Drop_Weapon,										// drop function
1830 		Weapon_ETF_Rifle,									// weapon think function
1831 		"misc/w_pkup.wav",									// pick up sound
1832 		"models/weapons/g_etf_rifle/tris.md2", EF_ROTATE,		// world model, world model flags
1833 		"models/weapons/v_etf_rifle/tris.md2",					// view model
1834 		"w_etf_rifle",										// icon
1835 		"ETF Rifle",										// name printed when picked up
1836 		0,													// number of digits for statusbar
1837 		1,													// amount used / contained
1838 		"Flechettes",										// ammo type used
1839 		IT_WEAPON,											// inventory flags
1840 		WEAP_ETFRIFLE,										// visible weapon
1841 		NULL,												// info (void *)
1842 		0,													// tag
1843 		"weapons/nail1.wav models/proj/flechette/tris.md2",	// precaches
1844 	},
1845 
1846 	// rogue
1847 /*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1848 */
1849 	{
1850 		"ammo_grenades",
1851 		Pickup_Ammo,
1852 		Use_Weapon,
1853 		Drop_Ammo,
1854 		Weapon_Grenade,
1855 		"misc/am_pkup.wav",
1856 		"models/items/ammo/grenades/medium/tris.md2", 0,
1857 		"models/weapons/v_handgr/tris.md2",
1858 /* icon */		"a_grenades",
1859 /* pickup */	"Grenades",
1860 /* width */		3,
1861 		5,
1862 		"grenades",
1863 		IT_AMMO|IT_WEAPON,
1864 		WEAP_GRENADES,
1865 		NULL,
1866 		AMMO_GRENADES,
1867 /* precache */ "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav "
1868 	},
1869 
1870 /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1871 */
1872 	{
1873 		"weapon_grenadelauncher",
1874 		Pickup_Weapon,
1875 		Use_Weapon,
1876 		Drop_Weapon,
1877 		Weapon_GrenadeLauncher,
1878 		"misc/w_pkup.wav",
1879 		"models/weapons/g_launch/tris.md2", EF_ROTATE,
1880 		"models/weapons/v_launch/tris.md2",
1881 /* icon */		"w_glauncher",
1882 /* pickup */	"Grenade Launcher",
1883 		0,
1884 		1,
1885 		"Grenades",
1886 		IT_WEAPON|IT_STAY_COOP,
1887 		WEAP_GRENADELAUNCHER,
1888 		NULL,
1889 		0,
1890 /* precache */ "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav"
1891 	},
1892 
1893 	// ROGUE
1894 /*QUAKED weapon_proxlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1895 */
1896 	{
1897 		"weapon_proxlauncher",								// classname
1898 		Pickup_Weapon,										// pickup
1899 		Use_Weapon,											// use
1900 		Drop_Weapon,										// drop
1901 		Weapon_ProxLauncher,								// weapon think
1902 		"misc/w_pkup.wav",									// pick up sound
1903 		"models/weapons/g_plaunch/tris.md2", EF_ROTATE,		// world model, world model flags
1904 		"models/weapons/v_plaunch/tris.md2",				// view model
1905 		"w_proxlaunch",										// icon
1906 		"Prox Launcher",									// name printed when picked up
1907 		0,													// number of digits for statusbar
1908 		1,													// amount used
1909 		"Prox",												// ammo type used
1910 		IT_WEAPON,											// inventory flags
1911 		WEAP_PROXLAUNCH,									// visible weapon
1912 		NULL,												// info (void *)
1913 		AMMO_PROX,											// tag
1914 		"weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav weapons/proxwarn.wav weapons/proxopen.wav",
1915 	},
1916 	// rogue
1917 
1918 /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1919 */
1920 	{
1921 		"weapon_rocketlauncher",
1922 		Pickup_Weapon,
1923 		Use_Weapon,
1924 		Drop_Weapon,
1925 		Weapon_RocketLauncher,
1926 		"misc/w_pkup.wav",
1927 		"models/weapons/g_rocket/tris.md2", EF_ROTATE,
1928 		"models/weapons/v_rocket/tris.md2",
1929 /* icon */		"w_rlauncher",
1930 /* pickup */	"Rocket Launcher",
1931 		0,
1932 		1,
1933 		"Rockets",
1934 		IT_WEAPON|IT_STAY_COOP,
1935 		WEAP_ROCKETLAUNCHER,
1936 		NULL,
1937 		0,
1938 /* precache */ "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2"
1939 	},
1940 
1941 /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1942 */
1943 	{
1944 		"weapon_hyperblaster",
1945 		Pickup_Weapon,
1946 		Use_Weapon,
1947 		Drop_Weapon,
1948 		Weapon_HyperBlaster,
1949 		"misc/w_pkup.wav",
1950 		"models/weapons/g_hyperb/tris.md2", EF_ROTATE,
1951 		"models/weapons/v_hyperb/tris.md2",
1952 /* icon */		"w_hyperblaster",
1953 /* pickup */	"HyperBlaster",
1954 		0,
1955 		1,
1956 		"Cells",
1957 		IT_WEAPON|IT_STAY_COOP,
1958 		WEAP_HYPERBLASTER,
1959 		NULL,
1960 		0,
1961 /* precache */ "weapons/hyprbu1a.wav weapons/hyprbl1a.wav weapons/hyprbf1a.wav weapons/hyprbd1a.wav misc/lasfly.wav"
1962 	},
1963 
1964 	// ROGUE
1965 /*QUAKED weapon_plasmabeam (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1966 */
1967 	{
1968 		"weapon_plasmabeam",								// classname
1969 		Pickup_Weapon,										// pickup function
1970 		Use_Weapon,											// use function
1971 		Drop_Weapon,										// drop function
1972 		Weapon_Heatbeam,									// weapon think function
1973 		"misc/w_pkup.wav",									// pick up sound
1974 		"models/weapons/g_beamer/tris.md2", EF_ROTATE,		// world model, world model flags
1975 		"models/weapons/v_beamer/tris.md2",					// view model
1976 		"w_heatbeam",											// icon
1977 		"Plasma Beam",											// name printed when picked up
1978 		0,													// number of digits for statusbar
1979 		// FIXME - if this changes, change it in NoAmmoWeaponChange as well
1980 		2,													// amount used / contained
1981 		"Cells",											// ammo type used
1982 		IT_WEAPON,											// inventory flags
1983 		WEAP_PLASMA,										// visible weapon
1984 		NULL,												// info (void *)
1985 		0,													// tag
1986 		"models/weapons/v_beamer2/tris.md2 weapons/bfg__l1a.wav",		// precaches
1987 	},
1988 	//rogue
1989 /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1990 */
1991 	{
1992 		"weapon_railgun",
1993 		Pickup_Weapon,
1994 		Use_Weapon,
1995 		Drop_Weapon,
1996 		Weapon_Railgun,
1997 		"misc/w_pkup.wav",
1998 		"models/weapons/g_rail/tris.md2", EF_ROTATE,
1999 		"models/weapons/v_rail/tris.md2",
2000 /* icon */		"w_railgun",
2001 /* pickup */	"Railgun",
2002 		0,
2003 		1,
2004 		"Slugs",
2005 		IT_WEAPON|IT_STAY_COOP,
2006 		WEAP_RAILGUN,
2007 		NULL,
2008 		0,
2009 /* precache */ "weapons/rg_hum.wav"
2010 	},
2011 
2012 /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2013 */
2014 	{
2015 		"weapon_bfg",
2016 		Pickup_Weapon,
2017 		Use_Weapon,
2018 		Drop_Weapon,
2019 		Weapon_BFG,
2020 		"misc/w_pkup.wav",
2021 		"models/weapons/g_bfg/tris.md2", EF_ROTATE,
2022 		"models/weapons/v_bfg/tris.md2",
2023 /* icon */		"w_bfg",
2024 /* pickup */	"BFG10K",
2025 		0,
2026 		50,
2027 		"Cells",
2028 		IT_WEAPON|IT_STAY_COOP,
2029 		WEAP_BFG,
2030 		NULL,
2031 		0,
2032 /* 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"
2033 	},
2034 
2035 // =========================
2036 // ROGUE WEAPONS
2037 /*QUAKED weapon_chainfist (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2038 */
2039 	{
2040 		"weapon_chainfist",									// classname
2041 		Pickup_Weapon,										// pickup function
2042 		Use_Weapon,											// use function
2043 		Drop_Weapon,										// drop function
2044 		Weapon_ChainFist,									// weapon think function
2045 		"misc/w_pkup.wav",									// pick up sound
2046 		"models/weapons/g_chainf/tris.md2", EF_ROTATE,		// world model, world model flags
2047 		"models/weapons/v_chainf/tris.md2",					// view model
2048 		"w_chainfist",										// icon
2049 		"Chainfist",										// name printed when picked up
2050 		0,													// number of digits for statusbar
2051 		0,													// amount used / contained
2052 		NULL,												// ammo type used
2053 		IT_WEAPON | IT_MELEE,								// inventory flags
2054 		WEAP_CHAINFIST,										// visible weapon
2055 		NULL,												// info (void *)
2056 		1,													// tag
2057 		"weapons/sawidle.wav weapons/sawhit.wav",			// precaches
2058 	},
2059 
2060 /*QUAKED weapon_disintegrator (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2061 */
2062 	{
2063 		"weapon_disintegrator",								// classname
2064 		Pickup_Weapon,										// pickup function
2065 		Use_Weapon,											// use function
2066 		Drop_Weapon,										// drop function
2067 		Weapon_Disintegrator,								// weapon think function
2068 		"misc/w_pkup.wav",									// pick up sound
2069 		"models/weapons/g_dist/tris.md2", EF_ROTATE,		// world model, world model flags
2070 		"models/weapons/v_dist/tris.md2",					// view model
2071 		"w_disintegrator",									// icon
2072 		"Disruptor",										// name printed when picked up
2073 		0,													// number of digits for statusbar
2074 		1,													// amount used / contained
2075 		"Rounds",											// ammo type used
2076 #ifdef KILL_DISRUPTOR
2077 		IT_NOT_GIVEABLE,
2078 #else
2079 		IT_WEAPON,											// inventory flags
2080 #endif
2081 		WEAP_DISRUPTOR,										// visible weapon
2082 		NULL,												// info (void *)
2083 		1,													// tag
2084 		"models/items/spawngro/tris.md2 models/proj/disintegrator/tris.md2 weapons/disrupt.wav weapons/disint2.wav weapons/disrupthit.wav",	// precaches
2085 	},
2086 
2087 // ROGUE WEAPONS
2088 // =========================
2089 
2090 
2091 	//
2092 	// AMMO ITEMS
2093 	//
2094 
2095 /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2096 */
2097 	{
2098 		"ammo_shells",
2099 		Pickup_Ammo,
2100 		NULL,
2101 		Drop_Ammo,
2102 		NULL,
2103 		"misc/am_pkup.wav",
2104 		"models/items/ammo/shells/medium/tris.md2", 0,
2105 		NULL,
2106 /* icon */		"a_shells",
2107 /* pickup */	"Shells",
2108 /* width */		3,
2109 		10,
2110 		NULL,
2111 		IT_AMMO,
2112 		0,
2113 		NULL,
2114 		AMMO_SHELLS,
2115 /* precache */ ""
2116 	},
2117 
2118 /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2119 */
2120 	{
2121 		"ammo_bullets",
2122 		Pickup_Ammo,
2123 		NULL,
2124 		Drop_Ammo,
2125 		NULL,
2126 		"misc/am_pkup.wav",
2127 		"models/items/ammo/bullets/medium/tris.md2", 0,
2128 		NULL,
2129 /* icon */		"a_bullets",
2130 /* pickup */	"Bullets",
2131 /* width */		3,
2132 		50,
2133 		NULL,
2134 		IT_AMMO,
2135 		0,
2136 		NULL,
2137 		AMMO_BULLETS,
2138 /* precache */ ""
2139 	},
2140 
2141 /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2142 */
2143 	{
2144 		"ammo_cells",
2145 		Pickup_Ammo,
2146 		NULL,
2147 		Drop_Ammo,
2148 		NULL,
2149 		"misc/am_pkup.wav",
2150 		"models/items/ammo/cells/medium/tris.md2", 0,
2151 		NULL,
2152 /* icon */		"a_cells",
2153 /* pickup */	"Cells",
2154 /* width */		3,
2155 		50,
2156 		NULL,
2157 		IT_AMMO,
2158 		0,
2159 		NULL,
2160 		AMMO_CELLS,
2161 /* precache */ ""
2162 	},
2163 
2164 /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2165 */
2166 	{
2167 		"ammo_rockets",
2168 		Pickup_Ammo,
2169 		NULL,
2170 		Drop_Ammo,
2171 		NULL,
2172 		"misc/am_pkup.wav",
2173 		"models/items/ammo/rockets/medium/tris.md2", 0,
2174 		NULL,
2175 /* icon */		"a_rockets",
2176 /* pickup */	"Rockets",
2177 /* width */		3,
2178 		5,
2179 		NULL,
2180 		IT_AMMO,
2181 		0,
2182 		NULL,
2183 		AMMO_ROCKETS,
2184 /* precache */ ""
2185 	},
2186 
2187 /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2188 */
2189 	{
2190 		"ammo_slugs",
2191 		Pickup_Ammo,
2192 		NULL,
2193 		Drop_Ammo,
2194 		NULL,
2195 		"misc/am_pkup.wav",
2196 		"models/items/ammo/slugs/medium/tris.md2", 0,
2197 		NULL,
2198 /* icon */		"a_slugs",
2199 /* pickup */	"Slugs",
2200 /* width */		3,
2201 		10,
2202 		NULL,
2203 		IT_AMMO,
2204 		0,
2205 		NULL,
2206 		AMMO_SLUGS,
2207 /* precache */ ""
2208 	},
2209 
2210 // =======================================
2211 // ROGUE AMMO
2212 
2213 /*QUAKED ammo_flechettes (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2214 */
2215 	{
2216 		"ammo_flechettes",
2217 		Pickup_Ammo,
2218 		NULL,
2219 		Drop_Ammo,
2220 		NULL,
2221 		"misc/am_pkup.wav",
2222 		"models/ammo/am_flechette/tris.md2", 0,
2223 		NULL,
2224 		"a_flechettes",
2225 		"Flechettes",
2226 		3,
2227 		50,
2228 		NULL,
2229 		IT_AMMO,
2230 		0,
2231 		NULL,
2232 		AMMO_FLECHETTES
2233 	},
2234 /*QUAKED ammo_prox (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2235 */
2236 	{
2237 		"ammo_prox",										// Classname
2238 		Pickup_Ammo,										// pickup function
2239 		NULL,												// use function
2240 		Drop_Ammo,											// drop function
2241 		NULL,												// weapon think function
2242 		"misc/am_pkup.wav",									// pickup sound
2243 		"models/ammo/am_prox/tris.md2", 0,					// world model, world model flags
2244 		NULL,												// view model
2245 		"a_prox",											// icon
2246 		"Prox",												// Name printed when picked up
2247 		3,													// number of digits for status bar
2248 		5,													// amount contained
2249 		NULL,												// ammo type used
2250 		IT_AMMO,											// inventory flags
2251 		0,													// vwep index
2252 		NULL,												// info (void *)
2253 		AMMO_PROX,											// tag
2254 		"models/weapons/g_prox/tris.md2 weapons/proxwarn.wav"	// precaches
2255 	},
2256 
2257 /*QUAKED ammo_tesla (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2258 */
2259 	{
2260 		"ammo_tesla",
2261 		Pickup_Ammo,
2262 		Use_Weapon,						// PGM
2263 		Drop_Ammo,
2264 		Weapon_Tesla,					// PGM
2265 		"misc/am_pkup.wav",
2266 //		"models/weapons/g_tesla/tris.md2", 0,
2267 		"models/ammo/am_tesl/tris.md2", 0,
2268 		"models/weapons/v_tesla/tris.md2",
2269 		"a_tesla",
2270 		"Tesla",
2271 		3,
2272 		5,
2273 		"Tesla",												// PGM
2274 		IT_AMMO | IT_WEAPON,						// inventory flags
2275 		0,
2276 		NULL,										// info (void *)
2277 		AMMO_TESLA,									// tag
2278 		"models/weapons/v_tesla2/tris.md2 weapons/teslaopen.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav models/weapons/g_tesla/tris.md2"			// precache
2279 	},
2280 
2281 /*QUAKED ammo_nuke (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2282 */
2283 	{
2284 		"ammo_nuke",
2285 		Pickup_Nuke,
2286 		Use_Nuke,						// PMM
2287 		Drop_Ammo,
2288 		NULL,							// PMM
2289 		"misc/am_pkup.wav",
2290 		"models/weapons/g_nuke/tris.md2", EF_ROTATE,
2291 		NULL,
2292 /* icon */		"p_nuke",
2293 /* pickup */	"A-M Bomb",
2294 /* width */		3,
2295 		300, /* quantity (used for respawn time) */
2296 		"A-M Bomb",
2297 		IT_POWERUP,
2298 		0,
2299 		NULL,
2300 		0,
2301 		"weapons/nukewarn2.wav world/rumble.wav"
2302 	},
2303 
2304 /*QUAKED ammo_disruptor (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2305 */
2306 	{
2307 		"ammo_disruptor",
2308 		Pickup_Ammo,
2309 		NULL,
2310 		Drop_Ammo,
2311 		NULL,
2312 		"misc/am_pkup.wav",
2313 		"models/ammo/am_disr/tris.md2", 0,
2314 		NULL,
2315 		"a_disruptor",
2316 		"Rounds",		// FIXME
2317 		3,
2318 		15,
2319 		NULL,
2320 #ifdef KILL_DISRUPTOR
2321 		IT_NOT_GIVEABLE,
2322 #else
2323 		IT_AMMO,											// inventory flags
2324 #endif
2325 		0,
2326 		NULL,
2327 #ifdef KILL_DISRUPTOR
2328 		0,
2329 #else
2330 		AMMO_DISRUPTOR,
2331 #endif
2332 	},
2333 // ROGUE AMMO
2334 // =======================================
2335 
2336 	//
2337 	// POWERUP ITEMS
2338 	//
2339 /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2340 */
2341 	{
2342 		"item_quad",
2343 		Pickup_Powerup,
2344 		Use_Quad,
2345 		Drop_General,
2346 		NULL,
2347 		"items/pkup.wav",
2348 		"models/items/quaddama/tris.md2", EF_ROTATE,
2349 		NULL,
2350 /* icon */		"p_quad",
2351 /* pickup */	"Quad Damage",
2352 /* width */		2,
2353 		60,
2354 		NULL,
2355 		IT_POWERUP,
2356 		0,
2357 		NULL,
2358 		0,
2359 /* precache */ "items/damage.wav items/damage2.wav items/damage3.wav"
2360 	},
2361 
2362 /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2363 */
2364 	{
2365 		"item_invulnerability",
2366 		Pickup_Powerup,
2367 		Use_Invulnerability,
2368 		Drop_General,
2369 		NULL,
2370 		"items/pkup.wav",
2371 		"models/items/invulner/tris.md2", EF_ROTATE,
2372 		NULL,
2373 /* icon */		"p_invulnerability",
2374 /* pickup */	"Invulnerability",
2375 /* width */		2,
2376 		300,
2377 		NULL,
2378 		IT_POWERUP,
2379 		0,
2380 		NULL,
2381 		0,
2382 /* precache */ "items/protect.wav items/protect2.wav items/protect4.wav"
2383 	},
2384 
2385 /*QUAKED item_silencer (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2386 */
2387 	{
2388 		"item_silencer",
2389 		Pickup_Powerup,
2390 		Use_Silencer,
2391 		Drop_General,
2392 		NULL,
2393 		"items/pkup.wav",
2394 		"models/items/silencer/tris.md2", EF_ROTATE,
2395 		NULL,
2396 /* icon */		"p_silencer",
2397 /* pickup */	"Silencer",
2398 /* width */		2,
2399 		60,
2400 		NULL,
2401 		IT_POWERUP,
2402 		0,
2403 		NULL,
2404 		0,
2405 /* precache */ ""
2406 	},
2407 
2408 /*QUAKED item_breather (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2409 */
2410 	{
2411 		"item_breather",
2412 		Pickup_Powerup,
2413 		Use_Breather,
2414 		Drop_General,
2415 		NULL,
2416 		"items/pkup.wav",
2417 		"models/items/breather/tris.md2", EF_ROTATE,
2418 		NULL,
2419 /* icon */		"p_rebreather",
2420 /* pickup */	"Rebreather",
2421 /* width */		2,
2422 		60,
2423 		NULL,
2424 		IT_STAY_COOP|IT_POWERUP,
2425 		0,
2426 		NULL,
2427 		0,
2428 /* precache */ "items/airout.wav"
2429 	},
2430 
2431 /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2432 */
2433 	{
2434 		"item_enviro",
2435 		Pickup_Powerup,
2436 		Use_Envirosuit,
2437 		Drop_General,
2438 		NULL,
2439 		"items/pkup.wav",
2440 		"models/items/enviro/tris.md2", EF_ROTATE,
2441 		NULL,
2442 /* icon */		"p_envirosuit",
2443 /* pickup */	"Environment Suit",
2444 /* width */		2,
2445 		60,
2446 		NULL,
2447 		IT_STAY_COOP|IT_POWERUP,
2448 		0,
2449 		NULL,
2450 		0,
2451 /* precache */ "items/airout.wav"
2452 	},
2453 
2454 /*QUAKED item_ancient_head (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2455 Special item that gives +2 to maximum health
2456 */
2457 	{
2458 		"item_ancient_head",
2459 		Pickup_AncientHead,
2460 		NULL,
2461 		NULL,
2462 		NULL,
2463 		"items/pkup.wav",
2464 		"models/items/c_head/tris.md2", EF_ROTATE,
2465 		NULL,
2466 /* icon */		"i_fixme",
2467 /* pickup */	"Ancient Head",
2468 /* width */		2,
2469 		60,
2470 		NULL,
2471 		0,
2472 		0,
2473 		NULL,
2474 		0,
2475 /* precache */ ""
2476 	},
2477 
2478 /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2479 gives +1 to maximum health
2480 */
2481 	{
2482 		"item_adrenaline",
2483 		Pickup_Adrenaline,
2484 		NULL,
2485 		NULL,
2486 		NULL,
2487 		"items/pkup.wav",
2488 		"models/items/adrenal/tris.md2", EF_ROTATE,
2489 		NULL,
2490 /* icon */		"p_adrenaline",
2491 /* pickup */	"Adrenaline",
2492 /* width */		2,
2493 		60,
2494 		NULL,
2495 		0,
2496 		0,
2497 		NULL,
2498 		0,
2499 /* precache */ ""
2500 	},
2501 
2502 /*QUAKED item_bandolier (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2503 */
2504 	{
2505 		"item_bandolier",
2506 		Pickup_Bandolier,
2507 		NULL,
2508 		NULL,
2509 		NULL,
2510 		"items/pkup.wav",
2511 		"models/items/band/tris.md2", EF_ROTATE,
2512 		NULL,
2513 /* icon */		"p_bandolier",
2514 /* pickup */	"Bandolier",
2515 /* width */		2,
2516 		60,
2517 		NULL,
2518 		0,
2519 		0,
2520 		NULL,
2521 		0,
2522 /* precache */ ""
2523 	},
2524 
2525 /*QUAKED item_pack (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2526 */
2527 	{
2528 		"item_pack",
2529 		Pickup_Pack,
2530 		NULL,
2531 		NULL,
2532 		NULL,
2533 		"items/pkup.wav",
2534 		"models/items/pack/tris.md2", EF_ROTATE,
2535 		NULL,
2536 /* icon */		"i_pack",
2537 /* pickup */	"Ammo Pack",
2538 /* width */		2,
2539 		180,
2540 		NULL,
2541 		0,
2542 		0,
2543 		NULL,
2544 		0,
2545 /* precache */ ""
2546 	},
2547 
2548 // ======================================
2549 // PGM
2550 
2551 /*QUAKED item_ir_goggles (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2552 gives +1 to maximum health
2553 */
2554 	{
2555 		"item_ir_goggles",
2556 		Pickup_Powerup,
2557 		Use_IR,
2558 		Drop_General,
2559 		NULL,
2560 		"items/pkup.wav",
2561 		"models/items/goggles/tris.md2", EF_ROTATE,
2562 		NULL,
2563 /* icon */		"p_ir",
2564 /* pickup */	"IR Goggles",
2565 /* width */		2,
2566 		60,
2567 		NULL,
2568 		IT_POWERUP,
2569 		0,
2570 		NULL,
2571 		0,
2572 /* precache */ "misc/ir_start.wav"
2573 	},
2574 
2575 /*QUAKED item_double (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2576 */
2577 	{
2578 		"item_double",
2579 		Pickup_Powerup,
2580 		Use_Double,
2581 		Drop_General,
2582 		NULL,
2583 		"items/pkup.wav",
2584 		"models/items/ddamage/tris.md2", EF_ROTATE,
2585 		NULL,
2586 /* icon */		"p_double",
2587 /* pickup */	"Double Damage",
2588 /* width */		2,
2589 		60,
2590 		NULL,
2591 		IT_POWERUP,
2592 		0,
2593 		NULL,
2594 		0,
2595 /* precache */ "misc/ddamage1.wav misc/ddamage2.wav misc/ddamage3.wav"
2596 	},
2597 
2598 /*Q U A K E D item_torch (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2599 */
2600 /*
2601 	{
2602 		"item_torch",
2603 		Pickup_Powerup,
2604 		Use_Torch,
2605 		Drop_General,
2606 		NULL,
2607 		"items/pkup.wav",
2608 		"models/objects/fire/tris.md2", EF_ROTATE,
2609 		NULL,
2610 		"p_torch",
2611 		"torch",
2612 		2,
2613 		60,
2614 		NULL,
2615 		IT_POWERUP,
2616 		0,
2617 		NULL,
2618 		0,
2619 	},
2620 */
2621 
2622 /*QUAKED item_compass (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2623 */
2624 	{
2625 		"item_compass",
2626 		Pickup_Powerup,
2627 		Use_Compass,
2628 		NULL,
2629 		NULL,
2630 		"items/pkup.wav",
2631 		"models/objects/fire/tris.md2", EF_ROTATE,
2632 		NULL,
2633 /* icon */		"p_compass",
2634 /* pickup */	"compass",
2635 /* width */		2,
2636 		60,
2637 		NULL,
2638 		IT_POWERUP,
2639 		0,
2640 		NULL,
2641 		0,
2642 	},
2643 
2644 /*QUAKED item_sphere_vengeance (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2645 */
2646 	{
2647 		"item_sphere_vengeance",
2648 		Pickup_Sphere,
2649 		Use_Vengeance,
2650 		NULL,
2651 		NULL,
2652 		"items/pkup.wav",
2653 		"models/items/vengnce/tris.md2", EF_ROTATE,
2654 		NULL,
2655 /* icon */		"p_vengeance",
2656 /* pickup */	"vengeance sphere",
2657 /* width */		2,
2658 		60,
2659 		NULL,
2660 		IT_POWERUP,
2661 		0,
2662 		NULL,
2663 		0,
2664 		"spheres/v_idle.wav"		//precache
2665 	},
2666 
2667 /*QUAKED item_sphere_hunter (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2668 */
2669 	{
2670 		"item_sphere_hunter",
2671 		Pickup_Sphere,
2672 		Use_Hunter,
2673 		NULL,
2674 		NULL,
2675 		"items/pkup.wav",
2676 		"models/items/hunter/tris.md2", EF_ROTATE,
2677 		NULL,
2678 /* icon */		"p_hunter",
2679 /* pickup */	"hunter sphere",
2680 /* width */		2,
2681 		120,
2682 		NULL,
2683 		IT_POWERUP,
2684 		0,
2685 		NULL,
2686 		0,
2687 		"spheres/h_idle.wav spheres/h_active.wav spheres/h_lurk.wav"		//precache
2688 	},
2689 
2690 /*QUAKED item_sphere_defender (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2691 */
2692 	{
2693 		"item_sphere_defender",
2694 		Pickup_Sphere,
2695 		Use_Defender,
2696 		NULL,
2697 		NULL,
2698 		"items/pkup.wav",
2699 		"models/items/defender/tris.md2", EF_ROTATE,
2700 		NULL,
2701 /* icon */		"p_defender",
2702 /* pickup */	"defender sphere",
2703 /* width */		2,
2704 		60,													// respawn time
2705 		NULL,												// ammo type used
2706 		IT_POWERUP,											// inventory flags
2707 		0,
2708 		NULL,												// info (void *)
2709 		0,													// tag
2710 		"models/proj/laser2/tris.md2 models/items/shell/tris.md2 spheres/d_idle.wav"		// precache
2711 	},
2712 
2713 /*QUAKED item_doppleganger (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2714 */
2715 	{
2716 		"item_doppleganger",								// classname
2717 		Pickup_Doppleganger,								// pickup function
2718 		Use_Doppleganger,									// use function
2719 		Drop_General,										// drop function
2720 		NULL,												// weapon think function
2721 		"items/pkup.wav",									// pick up sound
2722 		"models/items/dopple/tris.md2",						// world model
2723 		EF_ROTATE,											// world model flags
2724 		NULL,												// view model
2725 		"p_doppleganger",									// icon
2726 		"Doppleganger",										// name printed when picked up
2727 		0,													// number of digits for statusbar
2728 		90,													// respawn time
2729 		NULL,												// ammo type used
2730 		IT_POWERUP,											// inventory flags
2731 		0,
2732 		NULL,												// info (void *)
2733 		0,													// tag
2734 		"models/objects/dopplebase/tris.md2 models/items/spawngro2/tris.md2 models/items/hunter/tris.md2 models/items/vengnce/tris.md2",		// precaches
2735 	},
2736 
2737 	{
2738 //		"dm_tag_token",										// classname
2739 		NULL,												// classname
2740 		Tag_PickupToken,									// pickup function
2741 		NULL,												// use function
2742 		NULL,												// drop function
2743 		NULL,												// weapon think function
2744 		"items/pkup.wav",									// pick up sound
2745 		"models/items/tagtoken/tris.md2",					// world model
2746 		EF_ROTATE | EF_TAGTRAIL,							// world model flags
2747 		NULL,												// view model
2748 		"i_tagtoken",										// icon
2749 		"Tag Token",										// name printed when picked up
2750 		0,													// number of digits for statusbar
2751 		0,													// amount used / contained
2752 		NULL,												// ammo type used
2753 		IT_POWERUP | IT_NOT_GIVEABLE,						// inventory flags
2754 		0,
2755 		NULL,												// info (void *)
2756 		1,													// tag
2757 		NULL,												// precaches
2758 	},
2759 
2760 // PGM
2761 // ======================================
2762 
2763 
2764 	//
2765 	// KEYS
2766 	//
2767 /*QUAKED key_data_cd (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2768 key for computer centers
2769 */
2770 	{
2771 		"key_data_cd",
2772 		Pickup_Key,
2773 		NULL,
2774 		Drop_General,
2775 		NULL,
2776 		"items/pkup.wav",
2777 		"models/items/keys/data_cd/tris.md2", EF_ROTATE,
2778 		NULL,
2779 		"k_datacd",
2780 		"Data CD",
2781 		2,
2782 		0,
2783 		NULL,
2784 		IT_STAY_COOP|IT_KEY,
2785 		0,
2786 		NULL,
2787 		0,
2788 /* precache */ ""
2789 	},
2790 
2791 /*QUAKED key_power_cube (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH
2792 warehouse circuits
2793 */
2794 	{
2795 		"key_power_cube",
2796 		Pickup_Key,
2797 		NULL,
2798 		Drop_General,
2799 		NULL,
2800 		"items/pkup.wav",
2801 		"models/items/keys/power/tris.md2", EF_ROTATE,
2802 		NULL,
2803 		"k_powercube",
2804 		"Power Cube",
2805 		2,
2806 		0,
2807 		NULL,
2808 		IT_STAY_COOP|IT_KEY,
2809 		0,
2810 		NULL,
2811 		0,
2812 /* precache */ ""
2813 	},
2814 
2815 /*QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2816 key for the entrance of jail3
2817 */
2818 	{
2819 		"key_pyramid",
2820 		Pickup_Key,
2821 		NULL,
2822 		Drop_General,
2823 		NULL,
2824 		"items/pkup.wav",
2825 		"models/items/keys/pyramid/tris.md2", EF_ROTATE,
2826 		NULL,
2827 		"k_pyramid",
2828 		"Pyramid Key",
2829 		2,
2830 		0,
2831 		NULL,
2832 		IT_STAY_COOP|IT_KEY,
2833 		0,
2834 		NULL,
2835 		0,
2836 /* precache */ ""
2837 	},
2838 
2839 /*QUAKED key_data_spinner (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2840 key for the city computer
2841 */
2842 	{
2843 		"key_data_spinner",
2844 		Pickup_Key,
2845 		NULL,
2846 		Drop_General,
2847 		NULL,
2848 		"items/pkup.wav",
2849 		"models/items/keys/spinner/tris.md2", EF_ROTATE,
2850 		NULL,
2851 		"k_dataspin",
2852 		"Data Spinner",
2853 		2,
2854 		0,
2855 		NULL,
2856 		IT_STAY_COOP|IT_KEY,
2857 		0,
2858 		NULL,
2859 		0,
2860 /* precache */ ""
2861 	},
2862 
2863 /*QUAKED key_pass (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2864 security pass for the security level
2865 */
2866 	{
2867 		"key_pass",
2868 		Pickup_Key,
2869 		NULL,
2870 		Drop_General,
2871 		NULL,
2872 		"items/pkup.wav",
2873 		"models/items/keys/pass/tris.md2", EF_ROTATE,
2874 		NULL,
2875 		"k_security",
2876 		"Security Pass",
2877 		2,
2878 		0,
2879 		NULL,
2880 		IT_STAY_COOP|IT_KEY,
2881 		0,
2882 		NULL,
2883 		0,
2884 /* precache */ ""
2885 	},
2886 
2887 /*QUAKED key_blue_key (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2888 normal door key - blue
2889 */
2890 	{
2891 		"key_blue_key",
2892 		Pickup_Key,
2893 		NULL,
2894 		Drop_General,
2895 		NULL,
2896 		"items/pkup.wav",
2897 		"models/items/keys/key/tris.md2", EF_ROTATE,
2898 		NULL,
2899 		"k_bluekey",
2900 		"Blue Key",
2901 		2,
2902 		0,
2903 		NULL,
2904 		IT_STAY_COOP|IT_KEY,
2905 		0,
2906 		NULL,
2907 		0,
2908 /* precache */ ""
2909 	},
2910 
2911 /*QUAKED key_red_key (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2912 normal door key - red
2913 */
2914 	{
2915 		"key_red_key",
2916 		Pickup_Key,
2917 		NULL,
2918 		Drop_General,
2919 		NULL,
2920 		"items/pkup.wav",
2921 		"models/items/keys/red_key/tris.md2", EF_ROTATE,
2922 		NULL,
2923 		"k_redkey",
2924 		"Red Key",
2925 		2,
2926 		0,
2927 		NULL,
2928 		IT_STAY_COOP|IT_KEY,
2929 		0,
2930 		NULL,
2931 		0,
2932 /* precache */ ""
2933 	},
2934 
2935 /*QUAKED key_commander_head (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2936 tank commander's head
2937 */
2938 	{
2939 		"key_commander_head",
2940 		Pickup_Key,
2941 		NULL,
2942 		Drop_General,
2943 		NULL,
2944 		"items/pkup.wav",
2945 		"models/monsters/commandr/head/tris.md2", EF_GIB,
2946 		NULL,
2947 /* icon */		"k_comhead",
2948 /* pickup */	"Commander's Head",
2949 /* width */		2,
2950 		0,
2951 		NULL,
2952 		IT_STAY_COOP|IT_KEY,
2953 		0,
2954 		NULL,
2955 		0,
2956 /* precache */ ""
2957 	},
2958 
2959 /*QUAKED key_airstrike_target (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2960 tank commander's head
2961 */
2962 	{
2963 		"key_airstrike_target",
2964 		Pickup_Key,
2965 		NULL,
2966 		Drop_General,
2967 		NULL,
2968 		"items/pkup.wav",
2969 		"models/items/keys/target/tris.md2", EF_ROTATE,
2970 		NULL,
2971 /* icon */		"i_airstrike",
2972 /* pickup */	"Airstrike Marker",
2973 /* width */		2,
2974 		0,
2975 		NULL,
2976 		IT_STAY_COOP|IT_KEY,
2977 		0,
2978 		NULL,
2979 		0,
2980 /* precache */ ""
2981 	},
2982 
2983 // ======================================
2984 // PGM
2985 
2986 /*QUAKED key_nuke_container (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2987 */
2988 	{
2989 		"key_nuke_container",								// classname
2990 		Pickup_Key,											// pickup function
2991 		NULL,												// use function
2992 		Drop_General,										// drop function
2993 		NULL,												// weapon think function
2994 		"items/pkup.wav",									// pick up sound
2995 		"models/weapons/g_nuke/tris.md2",					// world model
2996 		EF_ROTATE,											// world model flags
2997 		NULL,												// view model
2998 		"i_contain",										// icon
2999 		"Antimatter Pod",									// name printed when picked up
3000 		2,													// number of digits for statusbar
3001 		0,													// respawn time
3002 		NULL,												// ammo type used
3003 		IT_STAY_COOP|IT_KEY,								// inventory flags
3004 		0,
3005 		NULL,												// info (void *)
3006 		0,													// tag
3007 		NULL,												// precaches
3008 	},
3009 
3010 /*QUAKED key_nuke (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3011 */
3012 	{
3013 		"key_nuke",											// classname
3014 		Pickup_Key,											// pickup function
3015 		NULL,												// use function
3016 		Drop_General,										// drop function
3017 		NULL,												// weapon think function
3018 		"items/pkup.wav",									// pick up sound
3019 		"models/weapons/g_nuke/tris.md2",					// world model
3020 		EF_ROTATE,											// world model flags
3021 		NULL,												// view model
3022 		"i_nuke",											// icon
3023 		"Antimatter Bomb",									// name printed when picked up
3024 		2,													// number of digits for statusbar
3025 		0,													// respawn time
3026 		NULL,												// ammo type used
3027 		IT_STAY_COOP|IT_KEY,								// inventory flags
3028 		0,
3029 		NULL,												// info (void *)
3030 		0,													// tag
3031 		NULL,												// precaches
3032 	},
3033 
3034 // PGM
3035 // ======================================
3036 
3037 	{
3038 		NULL,
3039 		Pickup_Health,
3040 		NULL,
3041 		NULL,
3042 		NULL,
3043 		"items/pkup.wav",
3044 		NULL, 0,
3045 		NULL,
3046 /* icon */		"i_health",
3047 /* pickup */	"Health",
3048 /* width */		3,
3049 		0,
3050 		NULL,
3051 		0,
3052 		0,
3053 		NULL,
3054 		0,
3055 /* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav"  // PMM - health sound fix
3056 	},
3057 
3058 	// end of list marker
3059 	{NULL}
3060 };
3061 
3062 
3063 /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3064 */
SP_item_health(edict_t * self)3065 void SP_item_health (edict_t *self)
3066 {
3067 	if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3068 	{
3069 		G_FreeEdict (self);
3070 		return;
3071 	}
3072 
3073 	self->model = "models/items/healing/medium/tris.md2";
3074 	self->count = 10;
3075 	SpawnItem (self, FindItem ("Health"));
3076 	gi.soundindex ("items/n_health.wav");
3077 }
3078 
3079 /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3080 */
SP_item_health_small(edict_t * self)3081 void SP_item_health_small (edict_t *self)
3082 {
3083 	if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3084 	{
3085 		G_FreeEdict (self);
3086 		return;
3087 	}
3088 
3089 	self->model = "models/items/healing/stimpack/tris.md2";
3090 	self->count = 2;
3091 	SpawnItem (self, FindItem ("Health"));
3092 	self->style = HEALTH_IGNORE_MAX;
3093 	gi.soundindex ("items/s_health.wav");
3094 }
3095 
3096 /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3097 */
SP_item_health_large(edict_t * self)3098 void SP_item_health_large (edict_t *self)
3099 {
3100 	if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3101 	{
3102 		G_FreeEdict (self);
3103 		return;
3104 	}
3105 
3106 	self->model = "models/items/healing/large/tris.md2";
3107 	self->count = 25;
3108 	SpawnItem (self, FindItem ("Health"));
3109 	gi.soundindex ("items/l_health.wav");
3110 }
3111 
3112 /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3113 */
SP_item_health_mega(edict_t * self)3114 void SP_item_health_mega (edict_t *self)
3115 {
3116 	if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3117 	{
3118 		G_FreeEdict (self);
3119 		return;
3120 	}
3121 
3122 	self->model = "models/items/mega_h/tris.md2";
3123 	self->count = 100;
3124 	SpawnItem (self, FindItem ("Health"));
3125 	gi.soundindex ("items/m_health.wav");
3126 	self->style = HEALTH_IGNORE_MAX|HEALTH_TIMED;
3127 }
3128 
3129 
InitItems(void)3130 void InitItems (void)
3131 {
3132 	game.num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1;
3133 }
3134 
3135 
3136 
3137 /*
3138 ===============
3139 SetItemNames
3140 
3141 Called by worldspawn
3142 ===============
3143 */
SetItemNames(void)3144 void SetItemNames (void)
3145 {
3146 	int		i;
3147 	gitem_t	*it;
3148 
3149 	for (i=0 ; i<game.num_items ; i++)
3150 	{
3151 		it = &itemlist[i];
3152 		gi.configstring (CS_ITEMS+i, it->pickup_name);
3153 	}
3154 
3155 	jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor"));
3156 	combat_armor_index = ITEM_INDEX(FindItem("Combat Armor"));
3157 	body_armor_index   = ITEM_INDEX(FindItem("Body Armor"));
3158 	power_screen_index = ITEM_INDEX(FindItem("Power Screen"));
3159 	power_shield_index = ITEM_INDEX(FindItem("Power Shield"));
3160 }
3161 
3162 
3163 //===============
3164 //ROGUE
SP_xatrix_item(edict_t * self)3165 void SP_xatrix_item (edict_t *self)
3166 {
3167 	gitem_t	*item;
3168 	int		i;
3169 	char	*spawnClass;
3170 
3171 	if(!self->classname)
3172 		return;
3173 
3174 	if(!strcmp(self->classname, "ammo_magslug"))
3175 		spawnClass = "ammo_flechettes";
3176 	else if(!strcmp(self->classname, "ammo_trap"))
3177 		spawnClass = "weapon_proxlauncher";
3178 	else if(!strcmp(self->classname, "item_quadfire"))
3179 	{
3180 		float	chance;
3181 
3182 		chance = random();
3183 		if(chance < 0.2)
3184 			spawnClass = "item_sphere_hunter";
3185 		else if (chance < 0.6)
3186 			spawnClass = "item_sphere_vengeance";
3187 		else
3188 			spawnClass = "item_sphere_defender";
3189 	}
3190 	else if(!strcmp(self->classname, "weapon_boomer"))
3191 		spawnClass = "weapon_etf_rifle";
3192 	else if(!strcmp(self->classname, "weapon_phalanx"))
3193 		spawnClass = "weapon_plasmabeam";
3194 
3195 
3196 	// check item spawn functions
3197 	for (i=0,item=itemlist ; i<game.num_items ; i++,item++)
3198 	{
3199 		if (!item->classname)
3200 			continue;
3201 		if (!strcmp(item->classname, spawnClass))
3202 		{	// found it
3203 			SpawnItem (self, item);
3204 			return;
3205 		}
3206 	}
3207 }
3208 //ROGUE
3209 //===============
3210