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