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