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