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