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