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 //=========
21 //Rogue Weapons
22 void Weapon_ChainFist (edict_t *ent);
23 void Weapon_Disintegrator (edict_t *ent);
24 void Weapon_ETF_Rifle (edict_t *ent);
25 void Weapon_Heatbeam (edict_t *ent);
26 void Weapon_Prox (edict_t *ent);
27 void Weapon_Tesla (edict_t *ent);
28 void Weapon_ProxLauncher (edict_t *ent);
29 //void Weapon_Nuke (edict_t *ent);
30 //Rogue Weapons
31 //=========
32
33 gitem_armor_t jacketarmor_info = { 25, 50, .30, .00, ARMOR_JACKET};
34 gitem_armor_t combatarmor_info = { 50, 100, .60, .30, ARMOR_COMBAT};
35 gitem_armor_t bodyarmor_info = {100, 200, .80, .60, ARMOR_BODY};
36
37 int jacket_armor_index;
38 int combat_armor_index;
39 int body_armor_index;
40 static int power_screen_index;
41 static int power_shield_index;
42
43 #define HEALTH_IGNORE_MAX 1
44 #define HEALTH_TIMED 2
45
46 void Use_Quad (edict_t *ent, gitem_t *item);
47 static int quad_drop_timeout_hack;
48
49 //======================================================================
50
51 /*
52 ===============
53 GetItemByIndex
54 ===============
55 */
GetItemByIndex(int index)56 gitem_t *GetItemByIndex (int index)
57 {
58 if (index == 0 || index >= game.num_items)
59 return NULL;
60
61 return &itemlist[index];
62 }
63
64
65 /*
66 ===============
67 FindItemByClassname
68
69 ===============
70 */
FindItemByClassname(char * classname)71 gitem_t *FindItemByClassname (char *classname)
72 {
73 int i;
74 gitem_t *it;
75
76 it = itemlist;
77 for (i=0 ; i<game.num_items ; i++, it++)
78 {
79 if (!it->classname)
80 continue;
81 if (!Q_stricmp(it->classname, classname))
82 return it;
83 }
84
85 return NULL;
86 }
87
88 /*
89 ===============
90 FindItem
91
92 ===============
93 */
FindItem(char * pickup_name)94 gitem_t *FindItem (char *pickup_name)
95 {
96 int i;
97 gitem_t *it;
98
99 it = itemlist;
100 for (i=0 ; i<game.num_items ; i++, it++)
101 {
102 if (!it->pickup_name)
103 continue;
104 if (!Q_stricmp(it->pickup_name, pickup_name))
105 return it;
106 }
107
108 return NULL;
109 }
110
111 //======================================================================
112
DoRespawn(edict_t * ent)113 void DoRespawn (edict_t *ent)
114 {
115 if (ent->team)
116 {
117 edict_t *master;
118 int count;
119 int choice;
120
121 master = ent->teammaster;
122
123 for (count = 0, ent = master; ent; ent = ent->chain, count++)
124 ;
125
126 choice = rand() % count;
127
128 for (count = 0, ent = master; count < choice; ent = ent->chain, count++)
129 ;
130 }
131
132 //=====
133 //ROGUE
134 if(randomrespawn && randomrespawn->value)
135 {
136 edict_t *newEnt;
137
138 newEnt = DoRandomRespawn (ent);
139
140 // if we've changed entities, then do some sleight of hand.
141 // otherwise, the old entity will respawn
142 if(newEnt)
143 {
144 G_FreeEdict (ent);
145 ent = newEnt;
146 }
147 }
148 //ROGUE
149 //=====
150
151 ent->svflags &= ~SVF_NOCLIENT;
152 ent->solid = SOLID_TRIGGER;
153 gi.linkentity (ent);
154
155 // send an effect
156 ent->s.event = EV_ITEM_RESPAWN;
157 }
158
SetRespawn(edict_t * ent,float delay)159 void SetRespawn (edict_t *ent, float delay)
160 {
161 ent->flags |= FL_RESPAWN;
162 ent->svflags |= SVF_NOCLIENT;
163 ent->solid = SOLID_NOT;
164 ent->nextthink = level.time + delay;
165 ent->think = DoRespawn;
166 gi.linkentity (ent);
167 }
168
169
170 //======================================================================
171
Pickup_Powerup(edict_t * ent,edict_t * other)172 qboolean Pickup_Powerup (edict_t *ent, edict_t *other)
173 {
174 int quantity;
175
176 quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
177 if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
178 return false;
179
180 if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
181 return false;
182
183 other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
184
185 if (deathmatch->value)
186 {
187 if (!(ent->spawnflags & DROPPED_ITEM) )
188 SetRespawn (ent, ent->item->quantity);
189 if (((int)dmflags->value & DF_INSTANT_ITEMS) || ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM)))
190 {
191 if ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM))
192 quad_drop_timeout_hack = (ent->nextthink - level.time) / FRAMETIME;
193 //PGM
194 if(ent->item->use)
195 ent->item->use (other, ent->item);
196 else
197 gi.dprintf("Powerup has no use function!\n");
198 //PGM
199 }
200 }
201
202 return true;
203 }
204
Drop_General(edict_t * ent,gitem_t * item)205 void Drop_General (edict_t *ent, gitem_t *item)
206 {
207 Drop_Item (ent, item);
208 ent->client->pers.inventory[ITEM_INDEX(item)]--;
209 ValidateSelectedItem (ent);
210 }
211
212
213 //======================================================================
214
Pickup_Adrenaline(edict_t * ent,edict_t * other)215 qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other)
216 {
217 if (!deathmatch->value)
218 other->max_health += 1;
219
220 if (other->health < other->max_health)
221 other->health = other->max_health;
222
223 if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
224 SetRespawn (ent, ent->item->quantity);
225
226 return true;
227 }
228
Pickup_AncientHead(edict_t * ent,edict_t * other)229 qboolean Pickup_AncientHead (edict_t *ent, edict_t *other)
230 {
231 other->max_health += 2;
232
233 if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
234 SetRespawn (ent, ent->item->quantity);
235
236 return true;
237 }
238
Pickup_Bandolier(edict_t * ent,edict_t * other)239 qboolean Pickup_Bandolier (edict_t *ent, edict_t *other)
240 {
241 gitem_t *item;
242 int index;
243
244 if (other->client->pers.max_bullets < 250)
245 other->client->pers.max_bullets = 250;
246 if (other->client->pers.max_shells < 150)
247 other->client->pers.max_shells = 150;
248 if (other->client->pers.max_cells < 250)
249 other->client->pers.max_cells = 250;
250 if (other->client->pers.max_slugs < 75)
251 other->client->pers.max_slugs = 75;
252 //PMM
253 if (other->client->pers.max_flechettes < 250)
254 other->client->pers.max_flechettes = 250;
255 #ifndef KILL_DISRUPTOR
256 if (other->client->pers.max_rounds < 150)
257 other->client->pers.max_rounds = 150;
258 #endif
259 //pmm
260
261 item = FindItem("Bullets");
262 if (item)
263 {
264 index = ITEM_INDEX(item);
265 other->client->pers.inventory[index] += item->quantity;
266 if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
267 other->client->pers.inventory[index] = other->client->pers.max_bullets;
268 }
269
270 item = FindItem("Shells");
271 if (item)
272 {
273 index = ITEM_INDEX(item);
274 other->client->pers.inventory[index] += item->quantity;
275 if (other->client->pers.inventory[index] > other->client->pers.max_shells)
276 other->client->pers.inventory[index] = other->client->pers.max_shells;
277 }
278
279 if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
280 SetRespawn (ent, ent->item->quantity);
281
282 return true;
283 }
284
Pickup_Pack(edict_t * ent,edict_t * other)285 qboolean Pickup_Pack (edict_t *ent, edict_t *other)
286 {
287 gitem_t *item;
288 int index;
289
290 if (other->client->pers.max_bullets < 300)
291 other->client->pers.max_bullets = 300;
292 if (other->client->pers.max_shells < 200)
293 other->client->pers.max_shells = 200;
294 if (other->client->pers.max_rockets < 100)
295 other->client->pers.max_rockets = 100;
296 if (other->client->pers.max_grenades < 100)
297 other->client->pers.max_grenades = 100;
298 if (other->client->pers.max_cells < 300)
299 other->client->pers.max_cells = 300;
300 if (other->client->pers.max_slugs < 100)
301 other->client->pers.max_slugs = 100;
302 //PMM
303 if (other->client->pers.max_flechettes < 200)
304 other->client->pers.max_flechettes = 200;
305 #ifndef KILL_DISRUPTOR
306 if (other->client->pers.max_rounds < 200)
307 other->client->pers.max_rounds = 200;
308 #endif
309 //pmm
310
311 item = FindItem("Bullets");
312 if (item)
313 {
314 index = ITEM_INDEX(item);
315 other->client->pers.inventory[index] += item->quantity;
316 if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
317 other->client->pers.inventory[index] = other->client->pers.max_bullets;
318 }
319
320 item = FindItem("Shells");
321 if (item)
322 {
323 index = ITEM_INDEX(item);
324 other->client->pers.inventory[index] += item->quantity;
325 if (other->client->pers.inventory[index] > other->client->pers.max_shells)
326 other->client->pers.inventory[index] = other->client->pers.max_shells;
327 }
328
329 item = FindItem("Cells");
330 if (item)
331 {
332 index = ITEM_INDEX(item);
333 other->client->pers.inventory[index] += item->quantity;
334 if (other->client->pers.inventory[index] > other->client->pers.max_cells)
335 other->client->pers.inventory[index] = other->client->pers.max_cells;
336 }
337
338 item = FindItem("Grenades");
339 if (item)
340 {
341 index = ITEM_INDEX(item);
342 other->client->pers.inventory[index] += item->quantity;
343 if (other->client->pers.inventory[index] > other->client->pers.max_grenades)
344 other->client->pers.inventory[index] = other->client->pers.max_grenades;
345 }
346
347 item = FindItem("Rockets");
348 if (item)
349 {
350 index = ITEM_INDEX(item);
351 other->client->pers.inventory[index] += item->quantity;
352 if (other->client->pers.inventory[index] > other->client->pers.max_rockets)
353 other->client->pers.inventory[index] = other->client->pers.max_rockets;
354 }
355
356 item = FindItem("Slugs");
357 if (item)
358 {
359 index = ITEM_INDEX(item);
360 other->client->pers.inventory[index] += item->quantity;
361 if (other->client->pers.inventory[index] > other->client->pers.max_slugs)
362 other->client->pers.inventory[index] = other->client->pers.max_slugs;
363 }
364 //PMM
365 item = FindItem("Flechettes");
366 if (item)
367 {
368 index = ITEM_INDEX(item);
369 other->client->pers.inventory[index] += item->quantity;
370 if (other->client->pers.inventory[index] > other->client->pers.max_flechettes)
371 other->client->pers.inventory[index] = other->client->pers.max_flechettes;
372 }
373 #ifndef KILL_DISRUPTOR
374 item = FindItem("Rounds");
375 if (item)
376 {
377 index = ITEM_INDEX(item);
378 other->client->pers.inventory[index] += item->quantity;
379 if (other->client->pers.inventory[index] > other->client->pers.max_rounds)
380 other->client->pers.inventory[index] = other->client->pers.max_rounds;
381 }
382 #endif
383 //pmm
384 if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
385 SetRespawn (ent, ent->item->quantity);
386
387 return true;
388 }
389 // ================
390 // PMM
Pickup_Nuke(edict_t * ent,edict_t * other)391 qboolean Pickup_Nuke (edict_t *ent, edict_t *other)
392 {
393 int quantity;
394
395 // if (!deathmatch->value)
396 // return;
397 quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
398 // if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
399 // return false;
400
401 if (quantity >= 1)
402 return false;
403
404 if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
405 return false;
406
407 other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
408
409 if (deathmatch->value)
410 {
411 if (!(ent->spawnflags & DROPPED_ITEM) )
412 SetRespawn (ent, ent->item->quantity);
413 }
414
415 return true;
416 }
417
418 // ================
419 // PGM
Use_IR(edict_t * ent,gitem_t * item)420 void Use_IR (edict_t *ent, gitem_t *item)
421 {
422 ent->client->pers.inventory[ITEM_INDEX(item)]--;
423 ValidateSelectedItem (ent);
424
425 if (ent->client->ir_framenum > level.framenum)
426 ent->client->ir_framenum += 600;
427 else
428 ent->client->ir_framenum = level.framenum + 600;
429
430 gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/ir_start.wav"), 1, ATTN_NORM, 0);
431 }
432
Use_Double(edict_t * ent,gitem_t * item)433 void Use_Double (edict_t *ent, gitem_t *item)
434 {
435 ent->client->pers.inventory[ITEM_INDEX(item)]--;
436 ValidateSelectedItem (ent);
437
438 if (ent->client->double_framenum > level.framenum)
439 ent->client->double_framenum += 300;
440 else
441 ent->client->double_framenum = level.framenum + 300;
442
443 gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/ddamage1.wav"), 1, ATTN_NORM, 0);
444 }
445
446 /*
447 void Use_Torch (edict_t *ent, gitem_t *item)
448 {
449 ent->client->torch_framenum = level.framenum + 600;
450 }
451 */
452
Use_Compass(edict_t * ent,gitem_t * item)453 void Use_Compass (edict_t *ent, gitem_t *item)
454 {
455 int ang;
456
457 ang = (int)(ent->client->v_angle[1]);
458 if(ang<0)
459 ang += 360;
460
461 gi.cprintf(ent, PRINT_HIGH, "Origin: %0.0f,%0.0f,%0.0f Dir: %d\n", ent->s.origin[0], ent->s.origin[1],
462 ent->s.origin[2], ang);
463 }
464
Use_Nuke(edict_t * ent,gitem_t * item)465 void Use_Nuke (edict_t *ent, gitem_t *item)
466 {
467 vec3_t forward, right, start;
468 float speed;
469
470 ent->client->pers.inventory[ITEM_INDEX(item)]--;
471 ValidateSelectedItem (ent);
472
473 AngleVectors (ent->client->v_angle, forward, right, NULL);
474
475 VectorCopy (ent->s.origin, start);
476 speed = 100;
477 fire_nuke (ent, start, forward, speed);
478 }
479
Use_Doppleganger(edict_t * ent,gitem_t * item)480 void Use_Doppleganger (edict_t *ent, gitem_t *item)
481 {
482 vec3_t forward, right;
483 vec3_t createPt, spawnPt;
484 vec3_t ang;
485
486 VectorClear(ang);
487 ang[YAW] = ent->client->v_angle[YAW];
488 AngleVectors (ang, forward, right, NULL);
489
490 VectorMA(ent->s.origin, 48, forward, createPt);
491
492 if(!FindSpawnPoint(createPt, ent->mins, ent->maxs, spawnPt, 32))
493 return;
494
495 if(!CheckGroundSpawnPoint(spawnPt, ent->mins, ent->maxs, 64, -1))
496 return;
497
498 ent->client->pers.inventory[ITEM_INDEX(item)]--;
499 ValidateSelectedItem (ent);
500
501 SpawnGrow_Spawn (spawnPt, 0);
502 fire_doppleganger (ent, spawnPt, forward);
503 }
504
Pickup_Doppleganger(edict_t * ent,edict_t * other)505 qboolean Pickup_Doppleganger (edict_t *ent, edict_t *other)
506 {
507 int quantity;
508
509 if(!(deathmatch->value)) // item is DM only
510 return false;
511
512 quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
513 if (quantity >= 1) // FIXME - apply max to dopplegangers
514 return false;
515
516 other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
517
518 if (!(ent->spawnflags & DROPPED_ITEM) )
519 SetRespawn (ent, ent->item->quantity);
520
521 return true;
522 }
523
524
Pickup_Sphere(edict_t * ent,edict_t * other)525 qboolean Pickup_Sphere (edict_t *ent, edict_t *other)
526 {
527 int quantity;
528
529 if(other->client && other->client->owned_sphere)
530 {
531 // gi.cprintf(other, PRINT_HIGH, "Only one sphere to a customer!\n");
532 return false;
533 }
534
535 quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
536 if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
537 return false;
538
539 if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
540 return false;
541
542 other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
543
544 if (deathmatch->value)
545 {
546 if (!(ent->spawnflags & DROPPED_ITEM) )
547 SetRespawn (ent, ent->item->quantity);
548 if (((int)dmflags->value & DF_INSTANT_ITEMS))
549 {
550 //PGM
551 if(ent->item->use)
552 ent->item->use (other, ent->item);
553 else
554 gi.dprintf("Powerup has no use function!\n");
555 //PGM
556 }
557 }
558
559 return true;
560 }
561
Use_Defender(edict_t * ent,gitem_t * item)562 void Use_Defender (edict_t *ent, gitem_t *item)
563 {
564 if(ent->client && ent->client->owned_sphere)
565 {
566 gi.cprintf(ent, PRINT_HIGH, "Only one sphere at a time!\n");
567 return;
568 }
569
570 ent->client->pers.inventory[ITEM_INDEX(item)]--;
571 ValidateSelectedItem (ent);
572
573 Defender_Launch (ent);
574 }
575
Use_Hunter(edict_t * ent,gitem_t * item)576 void Use_Hunter (edict_t *ent, gitem_t *item)
577 {
578 if(ent->client && ent->client->owned_sphere)
579 {
580 gi.cprintf(ent, PRINT_HIGH, "Only one sphere at a time!\n");
581 return;
582 }
583
584 ent->client->pers.inventory[ITEM_INDEX(item)]--;
585 ValidateSelectedItem (ent);
586
587 Hunter_Launch (ent);
588 }
589
Use_Vengeance(edict_t * ent,gitem_t * item)590 void Use_Vengeance (edict_t *ent, gitem_t *item)
591 {
592 if(ent->client && ent->client->owned_sphere)
593 {
594 gi.cprintf(ent, PRINT_HIGH, "Only one sphere at a time!\n");
595 return;
596 }
597
598 ent->client->pers.inventory[ITEM_INDEX(item)]--;
599 ValidateSelectedItem (ent);
600
601 Vengeance_Launch (ent);
602 }
603
604 // PGM
605 // ================
606
607
608 //======================================================================
609
Use_Quad(edict_t * ent,gitem_t * item)610 void Use_Quad (edict_t *ent, gitem_t *item)
611 {
612 int timeout;
613
614 ent->client->pers.inventory[ITEM_INDEX(item)]--;
615 ValidateSelectedItem (ent);
616
617 if (quad_drop_timeout_hack)
618 {
619 timeout = quad_drop_timeout_hack;
620 quad_drop_timeout_hack = 0;
621 }
622 else
623 {
624 timeout = 300;
625 }
626
627 if (ent->client->quad_framenum > level.framenum)
628 ent->client->quad_framenum += timeout;
629 else
630 ent->client->quad_framenum = level.framenum + timeout;
631
632 gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
633 }
634
635 //======================================================================
636
Use_Breather(edict_t * ent,gitem_t * item)637 void Use_Breather (edict_t *ent, gitem_t *item)
638 {
639 ent->client->pers.inventory[ITEM_INDEX(item)]--;
640 ValidateSelectedItem (ent);
641
642 if (ent->client->breather_framenum > level.framenum)
643 ent->client->breather_framenum += 300;
644 else
645 ent->client->breather_framenum = level.framenum + 300;
646
647 // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
648 }
649
650 //======================================================================
651
Use_Envirosuit(edict_t * ent,gitem_t * item)652 void Use_Envirosuit (edict_t *ent, gitem_t *item)
653 {
654 ent->client->pers.inventory[ITEM_INDEX(item)]--;
655 ValidateSelectedItem (ent);
656
657 if (ent->client->enviro_framenum > level.framenum)
658 ent->client->enviro_framenum += 300;
659 else
660 ent->client->enviro_framenum = level.framenum + 300;
661
662 // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
663 }
664
665 //======================================================================
666
Use_Invulnerability(edict_t * ent,gitem_t * item)667 void Use_Invulnerability (edict_t *ent, gitem_t *item)
668 {
669 ent->client->pers.inventory[ITEM_INDEX(item)]--;
670 ValidateSelectedItem (ent);
671
672 if (ent->client->invincible_framenum > level.framenum)
673 ent->client->invincible_framenum += 300;
674 else
675 ent->client->invincible_framenum = level.framenum + 300;
676
677 gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0);
678 }
679
680 //======================================================================
681
Use_Silencer(edict_t * ent,gitem_t * item)682 void Use_Silencer (edict_t *ent, gitem_t *item)
683 {
684 ent->client->pers.inventory[ITEM_INDEX(item)]--;
685 ValidateSelectedItem (ent);
686 ent->client->silencer_shots += 30;
687
688 // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
689 }
690
691 //======================================================================
692
Pickup_Key(edict_t * ent,edict_t * other)693 qboolean Pickup_Key (edict_t *ent, edict_t *other)
694 {
695 if (coop->value)
696 {
697 if (strcmp(ent->classname, "key_power_cube") == 0)
698 {
699 if (other->client->pers.power_cubes & ((ent->spawnflags & 0x0000ff00)>> 8))
700 return false;
701 other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
702 other->client->pers.power_cubes |= ((ent->spawnflags & 0x0000ff00) >> 8);
703 }
704 else
705 {
706 if (other->client->pers.inventory[ITEM_INDEX(ent->item)])
707 return false;
708 other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1;
709 }
710 return true;
711 }
712 other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
713 return true;
714 }
715
716 //======================================================================
717
Add_Ammo(edict_t * ent,gitem_t * item,int count)718 qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count)
719 {
720 int index;
721 int max;
722
723 if (!ent->client)
724 return false;
725
726 if (item->tag == AMMO_BULLETS)
727 max = ent->client->pers.max_bullets;
728 else if (item->tag == AMMO_SHELLS)
729 max = ent->client->pers.max_shells;
730 else if (item->tag == AMMO_ROCKETS)
731 max = ent->client->pers.max_rockets;
732 else if (item->tag == AMMO_GRENADES)
733 max = ent->client->pers.max_grenades;
734 else if (item->tag == AMMO_CELLS)
735 max = ent->client->pers.max_cells;
736 else if (item->tag == AMMO_SLUGS)
737 max = ent->client->pers.max_slugs;
738 // ROGUE
739 // else if (item->tag == AMMO_MINES)
740 // max = ent->client->pers.max_mines;
741 else if (item->tag == AMMO_FLECHETTES)
742 max = ent->client->pers.max_flechettes;
743 else if (item->tag == AMMO_PROX)
744 max = ent->client->pers.max_prox;
745 else if (item->tag == AMMO_TESLA)
746 max = ent->client->pers.max_tesla;
747 #ifndef KILL_DISRUPTOR
748 else if (item->tag == AMMO_DISRUPTOR)
749 max = ent->client->pers.max_rounds;
750 #endif
751 // ROGUE
752 else
753 {
754 gi.dprintf("undefined ammo type\n");
755 return false;
756 }
757
758 index = ITEM_INDEX(item);
759
760 if (ent->client->pers.inventory[index] == max)
761 return false;
762
763 ent->client->pers.inventory[index] += count;
764
765 if (ent->client->pers.inventory[index] > max)
766 ent->client->pers.inventory[index] = max;
767
768 return true;
769 }
770
Pickup_Ammo(edict_t * ent,edict_t * other)771 qboolean Pickup_Ammo (edict_t *ent, edict_t *other)
772 {
773 int oldcount;
774 int count;
775 qboolean weapon;
776
777 weapon = (ent->item->flags & IT_WEAPON);
778 if ( (weapon) && ( (int)dmflags->value & DF_INFINITE_AMMO ) )
779 count = 1000;
780 else if (ent->count)
781 count = ent->count;
782 else
783 count = ent->item->quantity;
784
785 oldcount = other->client->pers.inventory[ITEM_INDEX(ent->item)];
786
787 if (!Add_Ammo (other, ent->item, count))
788 return false;
789
790 if (weapon && !oldcount)
791 {
792 // don't switch to tesla
793 if (other->client->pers.weapon != ent->item
794 && ( !deathmatch->value || other->client->pers.weapon == FindItem("blaster"))
795 && (strcmp(ent->classname, "ammo_tesla")) )
796
797 other->client->newweapon = ent->item;
798 }
799
800 if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && (deathmatch->value))
801 SetRespawn (ent, 30);
802 return true;
803 }
804
Drop_Ammo(edict_t * ent,gitem_t * item)805 void Drop_Ammo (edict_t *ent, gitem_t *item)
806 {
807 edict_t *dropped;
808 int index;
809
810 index = ITEM_INDEX(item);
811 dropped = Drop_Item (ent, item);
812 if (ent->client->pers.inventory[index] >= item->quantity)
813 dropped->count = item->quantity;
814 else
815 dropped->count = ent->client->pers.inventory[index];
816
817 if (ent->client->pers.weapon &&
818 ent->client->pers.weapon->tag == AMMO_GRENADES &&
819 item->tag == AMMO_GRENADES &&
820 ent->client->pers.inventory[index] - dropped->count <= 0) {
821 gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
822 G_FreeEdict(dropped);
823 return;
824 }
825
826 ent->client->pers.inventory[index] -= dropped->count;
827 ValidateSelectedItem (ent);
828 }
829
830
831 //======================================================================
832
MegaHealth_think(edict_t * self)833 void MegaHealth_think (edict_t *self)
834 {
835 if (self->owner->health > self->owner->max_health)
836 {
837 self->nextthink = level.time + 1;
838 self->owner->health -= 1;
839 return;
840 }
841
842 if (!(self->spawnflags & DROPPED_ITEM) && (deathmatch->value))
843 SetRespawn (self, 20);
844 else
845 G_FreeEdict (self);
846 }
847
Pickup_Health(edict_t * ent,edict_t * other)848 qboolean Pickup_Health (edict_t *ent, edict_t *other)
849 {
850 if (!(ent->style & HEALTH_IGNORE_MAX))
851 if (other->health >= other->max_health)
852 return false;
853
854 other->health += ent->count;
855
856 // PMM - health sound fix
857 /*
858 if (ent->count == 2)
859 ent->item->pickup_sound = "items/s_health.wav";
860 else if (ent->count == 10)
861 ent->item->pickup_sound = "items/n_health.wav";
862 else if (ent->count == 25)
863 ent->item->pickup_sound = "items/l_health.wav";
864 else // (ent->count == 100)
865 ent->item->pickup_sound = "items/m_health.wav";
866 */
867
868 if (!(ent->style & HEALTH_IGNORE_MAX))
869 {
870 if (other->health > other->max_health)
871 other->health = other->max_health;
872 }
873
874 if (ent->style & HEALTH_TIMED)
875 {
876 ent->think = MegaHealth_think;
877 ent->nextthink = level.time + 5;
878 ent->owner = other;
879 ent->flags |= FL_RESPAWN;
880 ent->svflags |= SVF_NOCLIENT;
881 ent->solid = SOLID_NOT;
882 }
883 else
884 {
885 if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
886 SetRespawn (ent, 30);
887 }
888
889 return true;
890 }
891
892 //======================================================================
893
ArmorIndex(edict_t * ent)894 int ArmorIndex (edict_t *ent)
895 {
896 if (!ent->client)
897 return 0;
898
899 if (ent->client->pers.inventory[jacket_armor_index] > 0)
900 return jacket_armor_index;
901
902 if (ent->client->pers.inventory[combat_armor_index] > 0)
903 return combat_armor_index;
904
905 if (ent->client->pers.inventory[body_armor_index] > 0)
906 return body_armor_index;
907
908 return 0;
909 }
910
Pickup_Armor(edict_t * ent,edict_t * other)911 qboolean Pickup_Armor (edict_t *ent, edict_t *other)
912 {
913 int old_armor_index;
914 gitem_armor_t *oldinfo;
915 gitem_armor_t *newinfo;
916 int newcount;
917 float salvage;
918 int salvagecount;
919
920 // get info on new armor
921 newinfo = (gitem_armor_t *)ent->item->info;
922
923 old_armor_index = ArmorIndex (other);
924
925 // handle armor shards specially
926 if (ent->item->tag == ARMOR_SHARD)
927 {
928 if (!old_armor_index)
929 other->client->pers.inventory[jacket_armor_index] = 2;
930 else
931 other->client->pers.inventory[old_armor_index] += 2;
932 }
933
934 // if player has no armor, just use it
935 else if (!old_armor_index)
936 {
937 other->client->pers.inventory[ITEM_INDEX(ent->item)] = newinfo->base_count;
938 }
939
940 // use the better armor
941 else
942 {
943 // get info on old armor
944 if (old_armor_index == jacket_armor_index)
945 oldinfo = &jacketarmor_info;
946 else if (old_armor_index == combat_armor_index)
947 oldinfo = &combatarmor_info;
948 else // (old_armor_index == body_armor_index)
949 oldinfo = &bodyarmor_info;
950
951 if (newinfo->normal_protection > oldinfo->normal_protection)
952 {
953 // calc new armor values
954 salvage = oldinfo->normal_protection / newinfo->normal_protection;
955 salvagecount = salvage * other->client->pers.inventory[old_armor_index];
956 newcount = newinfo->base_count + salvagecount;
957 if (newcount > newinfo->max_count)
958 newcount = newinfo->max_count;
959
960 // zero count of old armor so it goes away
961 other->client->pers.inventory[old_armor_index] = 0;
962
963 // change armor to new item with computed value
964 other->client->pers.inventory[ITEM_INDEX(ent->item)] = newcount;
965 }
966 else
967 {
968 // calc new armor values
969 salvage = newinfo->normal_protection / oldinfo->normal_protection;
970 salvagecount = salvage * newinfo->base_count;
971 newcount = other->client->pers.inventory[old_armor_index] + salvagecount;
972 if (newcount > oldinfo->max_count)
973 newcount = oldinfo->max_count;
974
975 // if we're already maxed out then we don't need the new armor
976 if (other->client->pers.inventory[old_armor_index] >= newcount)
977 return false;
978
979 // update current armor value
980 other->client->pers.inventory[old_armor_index] = newcount;
981 }
982 }
983
984 if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
985 SetRespawn (ent, 20);
986
987 return true;
988 }
989
990 //======================================================================
991
PowerArmorType(edict_t * ent)992 int PowerArmorType (edict_t *ent)
993 {
994 if (!ent->client)
995 return POWER_ARMOR_NONE;
996
997 if (!(ent->flags & FL_POWER_ARMOR))
998 return POWER_ARMOR_NONE;
999
1000 if (ent->client->pers.inventory[power_shield_index] > 0)
1001 return POWER_ARMOR_SHIELD;
1002
1003 if (ent->client->pers.inventory[power_screen_index] > 0)
1004 return POWER_ARMOR_SCREEN;
1005
1006 return POWER_ARMOR_NONE;
1007 }
1008
Use_PowerArmor(edict_t * ent,gitem_t * item)1009 void Use_PowerArmor (edict_t *ent, gitem_t *item)
1010 {
1011 int index;
1012
1013 if (ent->flags & FL_POWER_ARMOR)
1014 {
1015 ent->flags &= ~FL_POWER_ARMOR;
1016 gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
1017 }
1018 else
1019 {
1020 index = ITEM_INDEX(FindItem("cells"));
1021 if (!ent->client->pers.inventory[index])
1022 {
1023 gi.cprintf (ent, PRINT_HIGH, "No cells for power armor.\n");
1024 return;
1025 }
1026 ent->flags |= FL_POWER_ARMOR;
1027 gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0);
1028 }
1029 }
1030
Pickup_PowerArmor(edict_t * ent,edict_t * other)1031 qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other)
1032 {
1033 int quantity;
1034
1035 quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
1036
1037 other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
1038
1039 if (deathmatch->value)
1040 {
1041 if (!(ent->spawnflags & DROPPED_ITEM) )
1042 SetRespawn (ent, ent->item->quantity);
1043 // auto-use for DM only if we didn't already have one
1044 if (!quantity)
1045 ent->item->use (other, ent->item);
1046 }
1047
1048 return true;
1049 }
1050
Drop_PowerArmor(edict_t * ent,gitem_t * item)1051 void Drop_PowerArmor (edict_t *ent, gitem_t *item)
1052 {
1053 if ((ent->flags & FL_POWER_ARMOR) && (ent->client->pers.inventory[ITEM_INDEX(item)] == 1))
1054 Use_PowerArmor (ent, item);
1055 Drop_General (ent, item);
1056 }
1057
1058 //======================================================================
1059
1060 /*
1061 ===============
1062 Touch_Item
1063 ===============
1064 */
Touch_Item(edict_t * ent,edict_t * other,cplane_t * plane,csurface_t * surf)1065 void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
1066 {
1067 qboolean taken;
1068
1069 if (!other->client)
1070 return;
1071 if (other->health < 1)
1072 return; // dead people can't pickup
1073 if (!ent->item->pickup)
1074 return; // not a grabbable item?
1075
1076 taken = ent->item->pickup(ent, other);
1077
1078 if (taken)
1079 {
1080 // flash the screen
1081 other->client->bonus_alpha = 0.25;
1082
1083 // show icon and name on status bar
1084 other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(ent->item->icon);
1085 other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+ITEM_INDEX(ent->item);
1086 other->client->pickup_msg_time = level.time + 3.0;
1087
1088 // change selected item
1089 if (ent->item->use)
1090 other->client->pers.selected_item = other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX(ent->item);
1091
1092 // PMM - health sound fix
1093 if (ent->item->pickup == Pickup_Health)
1094 {
1095 if (ent->count == 2)
1096 gi.sound(other, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0);
1097 else if (ent->count == 10)
1098 gi.sound(other, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0);
1099 else if (ent->count == 25)
1100 gi.sound(other, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0);
1101 else // (ent->count == 100)
1102 gi.sound(other, CHAN_ITEM, gi.soundindex("items/m_health.wav"), 1, ATTN_NORM, 0);
1103 }
1104 else if (ent->item->pickup_sound) // PGM - paranoia
1105 {
1106 //
1107 gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0);
1108 }
1109 }
1110
1111 if (!(ent->spawnflags & ITEM_TARGETS_USED))
1112 {
1113 G_UseTargets (ent, other);
1114 ent->spawnflags |= ITEM_TARGETS_USED;
1115 }
1116
1117 if (!taken)
1118 return;
1119
1120 if (!((coop->value) && (ent->item->flags & IT_STAY_COOP)) || (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)))
1121 {
1122 if (ent->flags & FL_RESPAWN)
1123 ent->flags &= ~FL_RESPAWN;
1124 else
1125 G_FreeEdict (ent);
1126 }
1127 }
1128
1129 //======================================================================
1130
drop_temp_touch(edict_t * ent,edict_t * other,cplane_t * plane,csurface_t * surf)1131 static void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
1132 {
1133 if (other == ent->owner)
1134 return;
1135
1136 Touch_Item (ent, other, plane, surf);
1137 }
1138
drop_make_touchable(edict_t * ent)1139 static void drop_make_touchable (edict_t *ent)
1140 {
1141 ent->touch = Touch_Item;
1142 if (deathmatch->value)
1143 {
1144 ent->nextthink = level.time + 29;
1145 ent->think = G_FreeEdict;
1146 }
1147 }
1148
Drop_Item(edict_t * ent,gitem_t * item)1149 edict_t *Drop_Item (edict_t *ent, gitem_t *item)
1150 {
1151 edict_t *dropped;
1152 vec3_t forward, right;
1153 vec3_t offset;
1154
1155 dropped = G_Spawn();
1156
1157 dropped->classname = item->classname;
1158 dropped->item = item;
1159 dropped->spawnflags = DROPPED_ITEM;
1160 dropped->s.effects = item->world_model_flags;
1161 dropped->s.renderfx = RF_GLOW | RF_IR_VISIBLE; // PGM
1162 VectorSet (dropped->mins, -15, -15, -15);
1163 VectorSet (dropped->maxs, 15, 15, 15);
1164 gi.setmodel (dropped, dropped->item->world_model);
1165 dropped->solid = SOLID_TRIGGER;
1166 dropped->movetype = MOVETYPE_TOSS;
1167 dropped->touch = drop_temp_touch;
1168 dropped->owner = ent;
1169
1170 if (ent->client)
1171 {
1172 trace_t trace;
1173
1174 AngleVectors (ent->client->v_angle, forward, right, NULL);
1175 VectorSet(offset, 24, 0, -16);
1176 G_ProjectSource (ent->s.origin, offset, forward, right, dropped->s.origin);
1177 trace = gi.trace (ent->s.origin, dropped->mins, dropped->maxs,
1178 dropped->s.origin, ent, CONTENTS_SOLID);
1179 VectorCopy (trace.endpos, dropped->s.origin);
1180 }
1181 else
1182 {
1183 AngleVectors (ent->s.angles, forward, right, NULL);
1184 VectorCopy (ent->s.origin, dropped->s.origin);
1185 }
1186
1187 VectorScale (forward, 100, dropped->velocity);
1188 dropped->velocity[2] = 300;
1189
1190 dropped->think = drop_make_touchable;
1191 dropped->nextthink = level.time + 1;
1192
1193 gi.linkentity (dropped);
1194
1195 return dropped;
1196 }
1197
Use_Item(edict_t * ent,edict_t * other,edict_t * activator)1198 void Use_Item (edict_t *ent, edict_t *other, edict_t *activator)
1199 {
1200 ent->svflags &= ~SVF_NOCLIENT;
1201 ent->use = NULL;
1202
1203 if (ent->spawnflags & ITEM_NO_TOUCH)
1204 {
1205 ent->solid = SOLID_BBOX;
1206 ent->touch = NULL;
1207 }
1208 else
1209 {
1210 ent->solid = SOLID_TRIGGER;
1211 ent->touch = Touch_Item;
1212 }
1213
1214 gi.linkentity (ent);
1215 }
1216
1217 //======================================================================
1218
1219 /*
1220 ================
1221 droptofloor
1222 ================
1223 */
droptofloor(edict_t * ent)1224 void droptofloor (edict_t *ent)
1225 {
1226 trace_t tr;
1227 vec3_t dest;
1228 float *v;
1229
1230 v = tv(-15,-15,-15);
1231 VectorCopy (v, ent->mins);
1232 v = tv(15,15,15);
1233 VectorCopy (v, ent->maxs);
1234
1235 if (ent->model)
1236 gi.setmodel (ent, ent->model);
1237 else if (ent->item->world_model) // PGM we shouldn't need this check, but paranoia...
1238 gi.setmodel (ent, ent->item->world_model);
1239 ent->solid = SOLID_TRIGGER;
1240 ent->movetype = MOVETYPE_TOSS;
1241 ent->touch = Touch_Item;
1242
1243 v = tv(0,0,-128);
1244 VectorAdd (ent->s.origin, v, dest);
1245
1246 tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID);
1247 if (tr.startsolid)
1248 {
1249 gi.dprintf ("droptofloor: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin));
1250 G_FreeEdict (ent);
1251 return;
1252 }
1253
1254 VectorCopy (tr.endpos, ent->s.origin);
1255
1256 if (ent->team)
1257 {
1258 ent->flags &= ~FL_TEAMSLAVE;
1259 ent->chain = ent->teamchain;
1260 ent->teamchain = NULL;
1261
1262 ent->svflags |= SVF_NOCLIENT;
1263 ent->solid = SOLID_NOT;
1264 if (ent == ent->teammaster)
1265 {
1266 ent->nextthink = level.time + FRAMETIME;
1267 ent->think = DoRespawn;
1268 }
1269 }
1270
1271 if (ent->spawnflags & ITEM_NO_TOUCH)
1272 {
1273 ent->solid = SOLID_BBOX;
1274 ent->touch = NULL;
1275 ent->s.effects &= ~EF_ROTATE;
1276 ent->s.renderfx &= ~RF_GLOW;
1277 }
1278
1279 if (ent->spawnflags & ITEM_TRIGGER_SPAWN)
1280 {
1281 ent->svflags |= SVF_NOCLIENT;
1282 ent->solid = SOLID_NOT;
1283 ent->use = Use_Item;
1284 }
1285
1286 gi.linkentity (ent);
1287 }
1288
1289
1290 /*
1291 ===============
1292 PrecacheItem
1293
1294 Precaches all data needed for a given item.
1295 This will be called for each item spawned in a level,
1296 and for each item in each client's inventory.
1297 ===============
1298 */
PrecacheItem(gitem_t * it)1299 void PrecacheItem (gitem_t *it)
1300 {
1301 char *s, *start;
1302 char data[MAX_QPATH];
1303 int len;
1304 gitem_t *ammo;
1305
1306 if (!it)
1307 return;
1308
1309 if (it->pickup_sound)
1310 gi.soundindex (it->pickup_sound);
1311 if (it->world_model)
1312 gi.modelindex (it->world_model);
1313 if (it->view_model)
1314 gi.modelindex (it->view_model);
1315 if (it->icon)
1316 gi.imageindex (it->icon);
1317
1318 // parse everything for its ammo
1319 if (it->ammo && it->ammo[0])
1320 {
1321 ammo = FindItem (it->ammo);
1322 if (ammo != it)
1323 PrecacheItem (ammo);
1324 }
1325
1326 // parse the space seperated precache string for other items
1327 s = it->precaches;
1328 if (!s || !s[0])
1329 return;
1330
1331 while (*s)
1332 {
1333 start = s;
1334 while (*s && *s != ' ')
1335 s++;
1336
1337 len = s-start;
1338 if (len >= MAX_QPATH || len < 5)
1339 gi.error ("PrecacheItem: %s has bad precache string", it->classname);
1340 memcpy (data, start, len);
1341 data[len] = 0;
1342 if (*s)
1343 s++;
1344
1345 // determine type based on extension
1346 if (!strcmp(data+len-3, "md2"))
1347 gi.modelindex (data);
1348 else if (!strcmp(data+len-3, "sp2"))
1349 gi.modelindex (data);
1350 else if (!strcmp(data+len-3, "wav"))
1351 gi.soundindex (data);
1352 if (!strcmp(data+len-3, "pcx"))
1353 gi.imageindex (data);
1354 }
1355 }
1356
1357
1358 //=================
1359 // Item_TriggeredSpawn - create the item marked for spawn creation
1360 //=================
Item_TriggeredSpawn(edict_t * self,edict_t * other,edict_t * activator)1361 void Item_TriggeredSpawn (edict_t *self, edict_t *other, edict_t *activator)
1362 {
1363 // self->nextthink = level.time + 2 * FRAMETIME; // items start after other solids
1364 // self->think = droptofloor;
1365 self->svflags &= ~SVF_NOCLIENT;
1366 self->use = NULL;
1367 if(strcmp(self->classname, "key_power_cube")) // leave them be on key_power_cube..
1368 self->spawnflags = 0;
1369 droptofloor (self);
1370 }
1371
1372 //=================
1373 // SetTriggeredSpawn - set up an item to spawn in later.
1374 //=================
SetTriggeredSpawn(edict_t * ent)1375 void SetTriggeredSpawn (edict_t *ent)
1376 {
1377 // don't do anything on key_power_cubes.
1378 if(!strcmp(ent->classname, "key_power_cube"))
1379 return;
1380
1381 ent->think = NULL;
1382 ent->nextthink = 0;
1383 ent->use = Item_TriggeredSpawn;
1384 ent->svflags |= SVF_NOCLIENT;
1385 ent->solid = SOLID_NOT;
1386 }
1387
1388 /*
1389 ============
1390 SpawnItem
1391
1392 Sets the clipping size and plants the object on the floor.
1393
1394 Items can't be immediately dropped to floor, because they might
1395 be on an entity that hasn't spawned yet.
1396 ============
1397 */
SpawnItem(edict_t * ent,gitem_t * item)1398 void SpawnItem (edict_t *ent, gitem_t *item)
1399 {
1400 #if KILL_DISRUPTOR
1401 if ((!strcmp(ent->classname, "ammo_disruptor")) || (!strcmp(ent->classname, "weapon_disintegrator")))
1402 {
1403 G_FreeEdict (ent);
1404 return;
1405 }
1406 #endif
1407
1408 // PGM - since the item may be freed by the following rules, go ahead
1409 // and move the precache until AFTER the following rules have been checked.
1410 // keep an eye on this.
1411 // PrecacheItem (item);
1412
1413 if (ent->spawnflags > 1) // PGM
1414 {
1415 if (strcmp(ent->classname, "key_power_cube") != 0)
1416 {
1417 ent->spawnflags = 0;
1418 gi.dprintf("%s at %s has invalid spawnflags set\n", ent->classname, vtos(ent->s.origin));
1419 }
1420 }
1421
1422 // some items will be prevented in deathmatch
1423 if (deathmatch->value)
1424 {
1425 if ( (int)dmflags->value & DF_NO_ARMOR )
1426 {
1427 if (item->pickup == Pickup_Armor || item->pickup == Pickup_PowerArmor)
1428 {
1429 G_FreeEdict (ent);
1430 return;
1431 }
1432 }
1433 if ( (int)dmflags->value & DF_NO_ITEMS )
1434 {
1435 if (item->pickup == Pickup_Powerup)
1436 {
1437 G_FreeEdict (ent);
1438 return;
1439 }
1440 //=====
1441 //ROGUE
1442 if (item->pickup == Pickup_Sphere)
1443 {
1444 G_FreeEdict (ent);
1445 return;
1446 }
1447 if (item->pickup == Pickup_Doppleganger)
1448 {
1449 G_FreeEdict (ent);
1450 return;
1451 }
1452 //ROGUE
1453 //=====
1454 }
1455 if ( (int)dmflags->value & DF_NO_HEALTH )
1456 {
1457 if (item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline || item->pickup == Pickup_AncientHead)
1458 {
1459 G_FreeEdict (ent);
1460 return;
1461 }
1462 }
1463 if ( (int)dmflags->value & DF_INFINITE_AMMO )
1464 {
1465 if ( (item->flags == IT_AMMO) || (strcmp(ent->classname, "weapon_bfg") == 0) )
1466 {
1467 G_FreeEdict (ent);
1468 return;
1469 }
1470 }
1471
1472 //==========
1473 //ROGUE
1474 if ( (int)dmflags->value & DF_NO_MINES )
1475 {
1476 if ( !strcmp(ent->classname, "ammo_prox") ||
1477 !strcmp(ent->classname, "ammo_tesla") )
1478 {
1479 G_FreeEdict (ent);
1480 return;
1481 }
1482 }
1483 if ( (int)dmflags->value & DF_NO_NUKES )
1484 {
1485 if ( !strcmp(ent->classname, "ammo_nuke") )
1486 {
1487 G_FreeEdict (ent);
1488 return;
1489 }
1490 }
1491 if ( (int)dmflags->value & DF_NO_SPHERES )
1492 {
1493 if (item->pickup == Pickup_Sphere)
1494 {
1495 G_FreeEdict (ent);
1496 return;
1497 }
1498 }
1499 //ROGUE
1500 //==========
1501
1502 }
1503 //==========
1504 //ROGUE
1505 // DM only items
1506 if (!deathmatch->value)
1507 {
1508 if (item->pickup == Pickup_Doppleganger || item->pickup == Pickup_Nuke)
1509 {
1510 G_FreeEdict (ent);
1511 return;
1512 }
1513 if ((item->use == Use_Vengeance) || (item->use == Use_Hunter))
1514 {
1515 G_FreeEdict (ent);
1516 return;
1517 }
1518 }
1519 //ROGUE
1520 //==========
1521
1522 //PGM
1523 PrecacheItem (item);
1524 //PGM
1525
1526 if (coop->value && (strcmp(ent->classname, "key_power_cube") == 0))
1527 {
1528 ent->spawnflags |= (1 << (8 + level.power_cubes));
1529 level.power_cubes++;
1530 }
1531
1532 // don't let them drop items that stay in a coop game
1533 if ((coop->value) && (item->flags & IT_STAY_COOP))
1534 {
1535 item->drop = NULL;
1536 }
1537
1538 ent->item = item;
1539 ent->nextthink = level.time + 2 * FRAMETIME; // items start after other solids
1540 ent->think = droptofloor;
1541 ent->s.effects = item->world_model_flags;
1542 ent->s.renderfx = RF_GLOW;
1543 if (ent->model)
1544 gi.modelindex (ent->model);
1545
1546 if (ent->spawnflags & 1)
1547 SetTriggeredSpawn (ent);
1548 }
1549
1550 //======================================================================
1551
1552 gitem_t itemlist[] =
1553 {
1554 {
1555 NULL
1556 }, // leave index 0 alone
1557
1558 //
1559 // ARMOR
1560 //
1561
1562 /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1563 */
1564 {
1565 "item_armor_body",
1566 Pickup_Armor,
1567 NULL,
1568 NULL,
1569 NULL,
1570 "misc/ar1_pkup.wav",
1571 "models/items/armor/body/tris.md2", EF_ROTATE,
1572 NULL,
1573 /* icon */ "i_bodyarmor",
1574 /* pickup */ "Body Armor",
1575 /* width */ 3,
1576 0,
1577 NULL,
1578 IT_ARMOR,
1579 0,
1580 &bodyarmor_info,
1581 ARMOR_BODY,
1582 /* precache */ ""
1583 },
1584
1585 /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1586 */
1587 {
1588 "item_armor_combat",
1589 Pickup_Armor,
1590 NULL,
1591 NULL,
1592 NULL,
1593 "misc/ar1_pkup.wav",
1594 "models/items/armor/combat/tris.md2", EF_ROTATE,
1595 NULL,
1596 /* icon */ "i_combatarmor",
1597 /* pickup */ "Combat Armor",
1598 /* width */ 3,
1599 0,
1600 NULL,
1601 IT_ARMOR,
1602 0,
1603 &combatarmor_info,
1604 ARMOR_COMBAT,
1605 /* precache */ ""
1606 },
1607
1608 /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1609 */
1610 {
1611 "item_armor_jacket",
1612 Pickup_Armor,
1613 NULL,
1614 NULL,
1615 NULL,
1616 "misc/ar1_pkup.wav",
1617 "models/items/armor/jacket/tris.md2", EF_ROTATE,
1618 NULL,
1619 /* icon */ "i_jacketarmor",
1620 /* pickup */ "Jacket Armor",
1621 /* width */ 3,
1622 0,
1623 NULL,
1624 IT_ARMOR,
1625 0,
1626 &jacketarmor_info,
1627 ARMOR_JACKET,
1628 /* precache */ ""
1629 },
1630
1631 /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1632 */
1633 {
1634 "item_armor_shard",
1635 Pickup_Armor,
1636 NULL,
1637 NULL,
1638 NULL,
1639 "misc/ar2_pkup.wav",
1640 "models/items/armor/shard/tris.md2", EF_ROTATE,
1641 NULL,
1642 /* icon */ "i_jacketarmor",
1643 /* pickup */ "Armor Shard",
1644 /* width */ 3,
1645 0,
1646 NULL,
1647 IT_ARMOR,
1648 0,
1649 NULL,
1650 ARMOR_SHARD,
1651 /* precache */ ""
1652 },
1653
1654
1655 /*QUAKED item_power_screen (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1656 */
1657 {
1658 "item_power_screen",
1659 Pickup_PowerArmor,
1660 Use_PowerArmor,
1661 Drop_PowerArmor,
1662 NULL,
1663 "misc/ar3_pkup.wav",
1664 "models/items/armor/screen/tris.md2", EF_ROTATE,
1665 NULL,
1666 /* icon */ "i_powerscreen",
1667 /* pickup */ "Power Screen",
1668 /* width */ 0,
1669 60,
1670 NULL,
1671 IT_ARMOR,
1672 0,
1673 NULL,
1674 0,
1675 /* precache */ ""
1676 },
1677
1678 /*QUAKED item_power_shield (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1679 */
1680 {
1681 "item_power_shield",
1682 Pickup_PowerArmor,
1683 Use_PowerArmor,
1684 Drop_PowerArmor,
1685 NULL,
1686 "misc/ar3_pkup.wav",
1687 "models/items/armor/shield/tris.md2", EF_ROTATE,
1688 NULL,
1689 /* icon */ "i_powershield",
1690 /* pickup */ "Power Shield",
1691 /* width */ 0,
1692 60,
1693 NULL,
1694 IT_ARMOR,
1695 0,
1696 NULL,
1697 0,
1698 /* precache */ "misc/power2.wav misc/power1.wav"
1699 },
1700
1701
1702 //
1703 // WEAPONS
1704 //
1705
1706 /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16)
1707 always owned, never in the world
1708 */
1709 {
1710 "weapon_blaster",
1711 NULL,
1712 Use_Weapon,
1713 NULL,
1714 Weapon_Blaster,
1715 "misc/w_pkup.wav",
1716 NULL, 0,
1717 "models/weapons/v_blast/tris.md2",
1718 /* icon */ "w_blaster",
1719 /* pickup */ "Blaster",
1720 0,
1721 0,
1722 NULL,
1723 IT_WEAPON|IT_STAY_COOP,
1724 WEAP_BLASTER,
1725 NULL,
1726 0,
1727 /* precache */ "weapons/blastf1a.wav misc/lasfly.wav"
1728 },
1729
1730 /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1731 */
1732 {
1733 "weapon_shotgun",
1734 Pickup_Weapon,
1735 Use_Weapon,
1736 Drop_Weapon,
1737 Weapon_Shotgun,
1738 "misc/w_pkup.wav",
1739 "models/weapons/g_shotg/tris.md2", EF_ROTATE,
1740 "models/weapons/v_shotg/tris.md2",
1741 /* icon */ "w_shotgun",
1742 /* pickup */ "Shotgun",
1743 0,
1744 1,
1745 "Shells",
1746 IT_WEAPON|IT_STAY_COOP,
1747 WEAP_SHOTGUN,
1748 NULL,
1749 0,
1750 /* precache */ "weapons/shotgf1b.wav weapons/shotgr1b.wav"
1751 },
1752
1753 /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1754 */
1755 {
1756 "weapon_supershotgun",
1757 Pickup_Weapon,
1758 Use_Weapon,
1759 Drop_Weapon,
1760 Weapon_SuperShotgun,
1761 "misc/w_pkup.wav",
1762 "models/weapons/g_shotg2/tris.md2", EF_ROTATE,
1763 "models/weapons/v_shotg2/tris.md2",
1764 /* icon */ "w_sshotgun",
1765 /* pickup */ "Super Shotgun",
1766 0,
1767 2,
1768 "Shells",
1769 IT_WEAPON|IT_STAY_COOP,
1770 WEAP_SUPERSHOTGUN,
1771 NULL,
1772 0,
1773 /* precache */ "weapons/sshotf1b.wav"
1774 },
1775
1776 /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1777 */
1778 {
1779 "weapon_machinegun",
1780 Pickup_Weapon,
1781 Use_Weapon,
1782 Drop_Weapon,
1783 Weapon_Machinegun,
1784 "misc/w_pkup.wav",
1785 "models/weapons/g_machn/tris.md2", EF_ROTATE,
1786 "models/weapons/v_machn/tris.md2",
1787 /* icon */ "w_machinegun",
1788 /* pickup */ "Machinegun",
1789 0,
1790 1,
1791 "Bullets",
1792 IT_WEAPON|IT_STAY_COOP,
1793 WEAP_MACHINEGUN,
1794 NULL,
1795 0,
1796 /* precache */ "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav"
1797 },
1798
1799 /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1800 */
1801 {
1802 "weapon_chaingun",
1803 Pickup_Weapon,
1804 Use_Weapon,
1805 Drop_Weapon,
1806 Weapon_Chaingun,
1807 "misc/w_pkup.wav",
1808 "models/weapons/g_chain/tris.md2", EF_ROTATE,
1809 "models/weapons/v_chain/tris.md2",
1810 /* icon */ "w_chaingun",
1811 /* pickup */ "Chaingun",
1812 0,
1813 1,
1814 "Bullets",
1815 IT_WEAPON|IT_STAY_COOP,
1816 WEAP_CHAINGUN,
1817 NULL,
1818 0,
1819 /* precache */ "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav"
1820 },
1821
1822 // ROGUE
1823 /*QUAKED weapon_etf_rifle (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1824 */
1825 {
1826 "weapon_etf_rifle", // classname
1827 Pickup_Weapon, // pickup function
1828 Use_Weapon, // use function
1829 Drop_Weapon, // drop function
1830 Weapon_ETF_Rifle, // weapon think function
1831 "misc/w_pkup.wav", // pick up sound
1832 "models/weapons/g_etf_rifle/tris.md2", EF_ROTATE, // world model, world model flags
1833 "models/weapons/v_etf_rifle/tris.md2", // view model
1834 "w_etf_rifle", // icon
1835 "ETF Rifle", // name printed when picked up
1836 0, // number of digits for statusbar
1837 1, // amount used / contained
1838 "Flechettes", // ammo type used
1839 IT_WEAPON, // inventory flags
1840 WEAP_ETFRIFLE, // visible weapon
1841 NULL, // info (void *)
1842 0, // tag
1843 "weapons/nail1.wav models/proj/flechette/tris.md2", // precaches
1844 },
1845
1846 // rogue
1847 /*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1848 */
1849 {
1850 "ammo_grenades",
1851 Pickup_Ammo,
1852 Use_Weapon,
1853 Drop_Ammo,
1854 Weapon_Grenade,
1855 "misc/am_pkup.wav",
1856 "models/items/ammo/grenades/medium/tris.md2", 0,
1857 "models/weapons/v_handgr/tris.md2",
1858 /* icon */ "a_grenades",
1859 /* pickup */ "Grenades",
1860 /* width */ 3,
1861 5,
1862 "grenades",
1863 IT_AMMO|IT_WEAPON,
1864 WEAP_GRENADES,
1865 NULL,
1866 AMMO_GRENADES,
1867 /* precache */ "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav "
1868 },
1869
1870 /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1871 */
1872 {
1873 "weapon_grenadelauncher",
1874 Pickup_Weapon,
1875 Use_Weapon,
1876 Drop_Weapon,
1877 Weapon_GrenadeLauncher,
1878 "misc/w_pkup.wav",
1879 "models/weapons/g_launch/tris.md2", EF_ROTATE,
1880 "models/weapons/v_launch/tris.md2",
1881 /* icon */ "w_glauncher",
1882 /* pickup */ "Grenade Launcher",
1883 0,
1884 1,
1885 "Grenades",
1886 IT_WEAPON|IT_STAY_COOP,
1887 WEAP_GRENADELAUNCHER,
1888 NULL,
1889 0,
1890 /* precache */ "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav"
1891 },
1892
1893 // ROGUE
1894 /*QUAKED weapon_proxlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1895 */
1896 {
1897 "weapon_proxlauncher", // classname
1898 Pickup_Weapon, // pickup
1899 Use_Weapon, // use
1900 Drop_Weapon, // drop
1901 Weapon_ProxLauncher, // weapon think
1902 "misc/w_pkup.wav", // pick up sound
1903 "models/weapons/g_plaunch/tris.md2", EF_ROTATE, // world model, world model flags
1904 "models/weapons/v_plaunch/tris.md2", // view model
1905 "w_proxlaunch", // icon
1906 "Prox Launcher", // name printed when picked up
1907 0, // number of digits for statusbar
1908 1, // amount used
1909 "Prox", // ammo type used
1910 IT_WEAPON, // inventory flags
1911 WEAP_PROXLAUNCH, // visible weapon
1912 NULL, // info (void *)
1913 AMMO_PROX, // tag
1914 "weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav weapons/proxwarn.wav weapons/proxopen.wav",
1915 },
1916 // rogue
1917
1918 /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1919 */
1920 {
1921 "weapon_rocketlauncher",
1922 Pickup_Weapon,
1923 Use_Weapon,
1924 Drop_Weapon,
1925 Weapon_RocketLauncher,
1926 "misc/w_pkup.wav",
1927 "models/weapons/g_rocket/tris.md2", EF_ROTATE,
1928 "models/weapons/v_rocket/tris.md2",
1929 /* icon */ "w_rlauncher",
1930 /* pickup */ "Rocket Launcher",
1931 0,
1932 1,
1933 "Rockets",
1934 IT_WEAPON|IT_STAY_COOP,
1935 WEAP_ROCKETLAUNCHER,
1936 NULL,
1937 0,
1938 /* precache */ "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2"
1939 },
1940
1941 /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1942 */
1943 {
1944 "weapon_hyperblaster",
1945 Pickup_Weapon,
1946 Use_Weapon,
1947 Drop_Weapon,
1948 Weapon_HyperBlaster,
1949 "misc/w_pkup.wav",
1950 "models/weapons/g_hyperb/tris.md2", EF_ROTATE,
1951 "models/weapons/v_hyperb/tris.md2",
1952 /* icon */ "w_hyperblaster",
1953 /* pickup */ "HyperBlaster",
1954 0,
1955 1,
1956 "Cells",
1957 IT_WEAPON|IT_STAY_COOP,
1958 WEAP_HYPERBLASTER,
1959 NULL,
1960 0,
1961 /* precache */ "weapons/hyprbu1a.wav weapons/hyprbl1a.wav weapons/hyprbf1a.wav weapons/hyprbd1a.wav misc/lasfly.wav"
1962 },
1963
1964 // ROGUE
1965 /*QUAKED weapon_plasmabeam (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1966 */
1967 {
1968 "weapon_plasmabeam", // classname
1969 Pickup_Weapon, // pickup function
1970 Use_Weapon, // use function
1971 Drop_Weapon, // drop function
1972 Weapon_Heatbeam, // weapon think function
1973 "misc/w_pkup.wav", // pick up sound
1974 "models/weapons/g_beamer/tris.md2", EF_ROTATE, // world model, world model flags
1975 "models/weapons/v_beamer/tris.md2", // view model
1976 "w_heatbeam", // icon
1977 "Plasma Beam", // name printed when picked up
1978 0, // number of digits for statusbar
1979 // FIXME - if this changes, change it in NoAmmoWeaponChange as well
1980 2, // amount used / contained
1981 "Cells", // ammo type used
1982 IT_WEAPON, // inventory flags
1983 WEAP_PLASMA, // visible weapon
1984 NULL, // info (void *)
1985 0, // tag
1986 "models/weapons/v_beamer2/tris.md2 weapons/bfg__l1a.wav", // precaches
1987 },
1988 //rogue
1989 /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
1990 */
1991 {
1992 "weapon_railgun",
1993 Pickup_Weapon,
1994 Use_Weapon,
1995 Drop_Weapon,
1996 Weapon_Railgun,
1997 "misc/w_pkup.wav",
1998 "models/weapons/g_rail/tris.md2", EF_ROTATE,
1999 "models/weapons/v_rail/tris.md2",
2000 /* icon */ "w_railgun",
2001 /* pickup */ "Railgun",
2002 0,
2003 1,
2004 "Slugs",
2005 IT_WEAPON|IT_STAY_COOP,
2006 WEAP_RAILGUN,
2007 NULL,
2008 0,
2009 /* precache */ "weapons/rg_hum.wav"
2010 },
2011
2012 /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2013 */
2014 {
2015 "weapon_bfg",
2016 Pickup_Weapon,
2017 Use_Weapon,
2018 Drop_Weapon,
2019 Weapon_BFG,
2020 "misc/w_pkup.wav",
2021 "models/weapons/g_bfg/tris.md2", EF_ROTATE,
2022 "models/weapons/v_bfg/tris.md2",
2023 /* icon */ "w_bfg",
2024 /* pickup */ "BFG10K",
2025 0,
2026 50,
2027 "Cells",
2028 IT_WEAPON|IT_STAY_COOP,
2029 WEAP_BFG,
2030 NULL,
2031 0,
2032 /* 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"
2033 },
2034
2035 // =========================
2036 // ROGUE WEAPONS
2037 /*QUAKED weapon_chainfist (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2038 */
2039 {
2040 "weapon_chainfist", // classname
2041 Pickup_Weapon, // pickup function
2042 Use_Weapon, // use function
2043 Drop_Weapon, // drop function
2044 Weapon_ChainFist, // weapon think function
2045 "misc/w_pkup.wav", // pick up sound
2046 "models/weapons/g_chainf/tris.md2", EF_ROTATE, // world model, world model flags
2047 "models/weapons/v_chainf/tris.md2", // view model
2048 "w_chainfist", // icon
2049 "Chainfist", // name printed when picked up
2050 0, // number of digits for statusbar
2051 0, // amount used / contained
2052 NULL, // ammo type used
2053 IT_WEAPON | IT_MELEE, // inventory flags
2054 WEAP_CHAINFIST, // visible weapon
2055 NULL, // info (void *)
2056 1, // tag
2057 "weapons/sawidle.wav weapons/sawhit.wav", // precaches
2058 },
2059
2060 /*QUAKED weapon_disintegrator (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2061 */
2062 {
2063 "weapon_disintegrator", // classname
2064 Pickup_Weapon, // pickup function
2065 Use_Weapon, // use function
2066 Drop_Weapon, // drop function
2067 Weapon_Disintegrator, // weapon think function
2068 "misc/w_pkup.wav", // pick up sound
2069 "models/weapons/g_dist/tris.md2", EF_ROTATE, // world model, world model flags
2070 "models/weapons/v_dist/tris.md2", // view model
2071 "w_disintegrator", // icon
2072 "Disruptor", // name printed when picked up
2073 0, // number of digits for statusbar
2074 1, // amount used / contained
2075 "Rounds", // ammo type used
2076 #ifdef KILL_DISRUPTOR
2077 IT_NOT_GIVEABLE,
2078 #else
2079 IT_WEAPON, // inventory flags
2080 #endif
2081 WEAP_DISRUPTOR, // visible weapon
2082 NULL, // info (void *)
2083 1, // tag
2084 "models/items/spawngro/tris.md2 models/proj/disintegrator/tris.md2 weapons/disrupt.wav weapons/disint2.wav weapons/disrupthit.wav", // precaches
2085 },
2086
2087 // ROGUE WEAPONS
2088 // =========================
2089
2090
2091 //
2092 // AMMO ITEMS
2093 //
2094
2095 /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2096 */
2097 {
2098 "ammo_shells",
2099 Pickup_Ammo,
2100 NULL,
2101 Drop_Ammo,
2102 NULL,
2103 "misc/am_pkup.wav",
2104 "models/items/ammo/shells/medium/tris.md2", 0,
2105 NULL,
2106 /* icon */ "a_shells",
2107 /* pickup */ "Shells",
2108 /* width */ 3,
2109 10,
2110 NULL,
2111 IT_AMMO,
2112 0,
2113 NULL,
2114 AMMO_SHELLS,
2115 /* precache */ ""
2116 },
2117
2118 /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2119 */
2120 {
2121 "ammo_bullets",
2122 Pickup_Ammo,
2123 NULL,
2124 Drop_Ammo,
2125 NULL,
2126 "misc/am_pkup.wav",
2127 "models/items/ammo/bullets/medium/tris.md2", 0,
2128 NULL,
2129 /* icon */ "a_bullets",
2130 /* pickup */ "Bullets",
2131 /* width */ 3,
2132 50,
2133 NULL,
2134 IT_AMMO,
2135 0,
2136 NULL,
2137 AMMO_BULLETS,
2138 /* precache */ ""
2139 },
2140
2141 /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2142 */
2143 {
2144 "ammo_cells",
2145 Pickup_Ammo,
2146 NULL,
2147 Drop_Ammo,
2148 NULL,
2149 "misc/am_pkup.wav",
2150 "models/items/ammo/cells/medium/tris.md2", 0,
2151 NULL,
2152 /* icon */ "a_cells",
2153 /* pickup */ "Cells",
2154 /* width */ 3,
2155 50,
2156 NULL,
2157 IT_AMMO,
2158 0,
2159 NULL,
2160 AMMO_CELLS,
2161 /* precache */ ""
2162 },
2163
2164 /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2165 */
2166 {
2167 "ammo_rockets",
2168 Pickup_Ammo,
2169 NULL,
2170 Drop_Ammo,
2171 NULL,
2172 "misc/am_pkup.wav",
2173 "models/items/ammo/rockets/medium/tris.md2", 0,
2174 NULL,
2175 /* icon */ "a_rockets",
2176 /* pickup */ "Rockets",
2177 /* width */ 3,
2178 5,
2179 NULL,
2180 IT_AMMO,
2181 0,
2182 NULL,
2183 AMMO_ROCKETS,
2184 /* precache */ ""
2185 },
2186
2187 /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2188 */
2189 {
2190 "ammo_slugs",
2191 Pickup_Ammo,
2192 NULL,
2193 Drop_Ammo,
2194 NULL,
2195 "misc/am_pkup.wav",
2196 "models/items/ammo/slugs/medium/tris.md2", 0,
2197 NULL,
2198 /* icon */ "a_slugs",
2199 /* pickup */ "Slugs",
2200 /* width */ 3,
2201 10,
2202 NULL,
2203 IT_AMMO,
2204 0,
2205 NULL,
2206 AMMO_SLUGS,
2207 /* precache */ ""
2208 },
2209
2210 // =======================================
2211 // ROGUE AMMO
2212
2213 /*QUAKED ammo_flechettes (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2214 */
2215 {
2216 "ammo_flechettes",
2217 Pickup_Ammo,
2218 NULL,
2219 Drop_Ammo,
2220 NULL,
2221 "misc/am_pkup.wav",
2222 "models/ammo/am_flechette/tris.md2", 0,
2223 NULL,
2224 "a_flechettes",
2225 "Flechettes",
2226 3,
2227 50,
2228 NULL,
2229 IT_AMMO,
2230 0,
2231 NULL,
2232 AMMO_FLECHETTES
2233 },
2234 /*QUAKED ammo_prox (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2235 */
2236 {
2237 "ammo_prox", // Classname
2238 Pickup_Ammo, // pickup function
2239 NULL, // use function
2240 Drop_Ammo, // drop function
2241 NULL, // weapon think function
2242 "misc/am_pkup.wav", // pickup sound
2243 "models/ammo/am_prox/tris.md2", 0, // world model, world model flags
2244 NULL, // view model
2245 "a_prox", // icon
2246 "Prox", // Name printed when picked up
2247 3, // number of digits for status bar
2248 5, // amount contained
2249 NULL, // ammo type used
2250 IT_AMMO, // inventory flags
2251 0, // vwep index
2252 NULL, // info (void *)
2253 AMMO_PROX, // tag
2254 "models/weapons/g_prox/tris.md2 weapons/proxwarn.wav" // precaches
2255 },
2256
2257 /*QUAKED ammo_tesla (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2258 */
2259 {
2260 "ammo_tesla",
2261 Pickup_Ammo,
2262 Use_Weapon, // PGM
2263 Drop_Ammo,
2264 Weapon_Tesla, // PGM
2265 "misc/am_pkup.wav",
2266 // "models/weapons/g_tesla/tris.md2", 0,
2267 "models/ammo/am_tesl/tris.md2", 0,
2268 "models/weapons/v_tesla/tris.md2",
2269 "a_tesla",
2270 "Tesla",
2271 3,
2272 5,
2273 "Tesla", // PGM
2274 IT_AMMO | IT_WEAPON, // inventory flags
2275 0,
2276 NULL, // info (void *)
2277 AMMO_TESLA, // tag
2278 "models/weapons/v_tesla2/tris.md2 weapons/teslaopen.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav models/weapons/g_tesla/tris.md2" // precache
2279 },
2280
2281 /*QUAKED ammo_nuke (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2282 */
2283 {
2284 "ammo_nuke",
2285 Pickup_Nuke,
2286 Use_Nuke, // PMM
2287 Drop_Ammo,
2288 NULL, // PMM
2289 "misc/am_pkup.wav",
2290 "models/weapons/g_nuke/tris.md2", EF_ROTATE,
2291 NULL,
2292 /* icon */ "p_nuke",
2293 /* pickup */ "A-M Bomb",
2294 /* width */ 3,
2295 300, /* quantity (used for respawn time) */
2296 "A-M Bomb",
2297 IT_POWERUP,
2298 0,
2299 NULL,
2300 0,
2301 "weapons/nukewarn2.wav world/rumble.wav"
2302 },
2303
2304 /*QUAKED ammo_disruptor (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2305 */
2306 {
2307 "ammo_disruptor",
2308 Pickup_Ammo,
2309 NULL,
2310 Drop_Ammo,
2311 NULL,
2312 "misc/am_pkup.wav",
2313 "models/ammo/am_disr/tris.md2", 0,
2314 NULL,
2315 "a_disruptor",
2316 "Rounds", // FIXME
2317 3,
2318 15,
2319 NULL,
2320 #ifdef KILL_DISRUPTOR
2321 IT_NOT_GIVEABLE,
2322 #else
2323 IT_AMMO, // inventory flags
2324 #endif
2325 0,
2326 NULL,
2327 #ifdef KILL_DISRUPTOR
2328 0,
2329 #else
2330 AMMO_DISRUPTOR,
2331 #endif
2332 },
2333 // ROGUE AMMO
2334 // =======================================
2335
2336 //
2337 // POWERUP ITEMS
2338 //
2339 /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2340 */
2341 {
2342 "item_quad",
2343 Pickup_Powerup,
2344 Use_Quad,
2345 Drop_General,
2346 NULL,
2347 "items/pkup.wav",
2348 "models/items/quaddama/tris.md2", EF_ROTATE,
2349 NULL,
2350 /* icon */ "p_quad",
2351 /* pickup */ "Quad Damage",
2352 /* width */ 2,
2353 60,
2354 NULL,
2355 IT_POWERUP,
2356 0,
2357 NULL,
2358 0,
2359 /* precache */ "items/damage.wav items/damage2.wav items/damage3.wav"
2360 },
2361
2362 /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2363 */
2364 {
2365 "item_invulnerability",
2366 Pickup_Powerup,
2367 Use_Invulnerability,
2368 Drop_General,
2369 NULL,
2370 "items/pkup.wav",
2371 "models/items/invulner/tris.md2", EF_ROTATE,
2372 NULL,
2373 /* icon */ "p_invulnerability",
2374 /* pickup */ "Invulnerability",
2375 /* width */ 2,
2376 300,
2377 NULL,
2378 IT_POWERUP,
2379 0,
2380 NULL,
2381 0,
2382 /* precache */ "items/protect.wav items/protect2.wav items/protect4.wav"
2383 },
2384
2385 /*QUAKED item_silencer (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2386 */
2387 {
2388 "item_silencer",
2389 Pickup_Powerup,
2390 Use_Silencer,
2391 Drop_General,
2392 NULL,
2393 "items/pkup.wav",
2394 "models/items/silencer/tris.md2", EF_ROTATE,
2395 NULL,
2396 /* icon */ "p_silencer",
2397 /* pickup */ "Silencer",
2398 /* width */ 2,
2399 60,
2400 NULL,
2401 IT_POWERUP,
2402 0,
2403 NULL,
2404 0,
2405 /* precache */ ""
2406 },
2407
2408 /*QUAKED item_breather (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2409 */
2410 {
2411 "item_breather",
2412 Pickup_Powerup,
2413 Use_Breather,
2414 Drop_General,
2415 NULL,
2416 "items/pkup.wav",
2417 "models/items/breather/tris.md2", EF_ROTATE,
2418 NULL,
2419 /* icon */ "p_rebreather",
2420 /* pickup */ "Rebreather",
2421 /* width */ 2,
2422 60,
2423 NULL,
2424 IT_STAY_COOP|IT_POWERUP,
2425 0,
2426 NULL,
2427 0,
2428 /* precache */ "items/airout.wav"
2429 },
2430
2431 /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2432 */
2433 {
2434 "item_enviro",
2435 Pickup_Powerup,
2436 Use_Envirosuit,
2437 Drop_General,
2438 NULL,
2439 "items/pkup.wav",
2440 "models/items/enviro/tris.md2", EF_ROTATE,
2441 NULL,
2442 /* icon */ "p_envirosuit",
2443 /* pickup */ "Environment Suit",
2444 /* width */ 2,
2445 60,
2446 NULL,
2447 IT_STAY_COOP|IT_POWERUP,
2448 0,
2449 NULL,
2450 0,
2451 /* precache */ "items/airout.wav"
2452 },
2453
2454 /*QUAKED item_ancient_head (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2455 Special item that gives +2 to maximum health
2456 */
2457 {
2458 "item_ancient_head",
2459 Pickup_AncientHead,
2460 NULL,
2461 NULL,
2462 NULL,
2463 "items/pkup.wav",
2464 "models/items/c_head/tris.md2", EF_ROTATE,
2465 NULL,
2466 /* icon */ "i_fixme",
2467 /* pickup */ "Ancient Head",
2468 /* width */ 2,
2469 60,
2470 NULL,
2471 0,
2472 0,
2473 NULL,
2474 0,
2475 /* precache */ ""
2476 },
2477
2478 /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2479 gives +1 to maximum health
2480 */
2481 {
2482 "item_adrenaline",
2483 Pickup_Adrenaline,
2484 NULL,
2485 NULL,
2486 NULL,
2487 "items/pkup.wav",
2488 "models/items/adrenal/tris.md2", EF_ROTATE,
2489 NULL,
2490 /* icon */ "p_adrenaline",
2491 /* pickup */ "Adrenaline",
2492 /* width */ 2,
2493 60,
2494 NULL,
2495 0,
2496 0,
2497 NULL,
2498 0,
2499 /* precache */ ""
2500 },
2501
2502 /*QUAKED item_bandolier (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2503 */
2504 {
2505 "item_bandolier",
2506 Pickup_Bandolier,
2507 NULL,
2508 NULL,
2509 NULL,
2510 "items/pkup.wav",
2511 "models/items/band/tris.md2", EF_ROTATE,
2512 NULL,
2513 /* icon */ "p_bandolier",
2514 /* pickup */ "Bandolier",
2515 /* width */ 2,
2516 60,
2517 NULL,
2518 0,
2519 0,
2520 NULL,
2521 0,
2522 /* precache */ ""
2523 },
2524
2525 /*QUAKED item_pack (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2526 */
2527 {
2528 "item_pack",
2529 Pickup_Pack,
2530 NULL,
2531 NULL,
2532 NULL,
2533 "items/pkup.wav",
2534 "models/items/pack/tris.md2", EF_ROTATE,
2535 NULL,
2536 /* icon */ "i_pack",
2537 /* pickup */ "Ammo Pack",
2538 /* width */ 2,
2539 180,
2540 NULL,
2541 0,
2542 0,
2543 NULL,
2544 0,
2545 /* precache */ ""
2546 },
2547
2548 // ======================================
2549 // PGM
2550
2551 /*QUAKED item_ir_goggles (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2552 gives +1 to maximum health
2553 */
2554 {
2555 "item_ir_goggles",
2556 Pickup_Powerup,
2557 Use_IR,
2558 Drop_General,
2559 NULL,
2560 "items/pkup.wav",
2561 "models/items/goggles/tris.md2", EF_ROTATE,
2562 NULL,
2563 /* icon */ "p_ir",
2564 /* pickup */ "IR Goggles",
2565 /* width */ 2,
2566 60,
2567 NULL,
2568 IT_POWERUP,
2569 0,
2570 NULL,
2571 0,
2572 /* precache */ "misc/ir_start.wav"
2573 },
2574
2575 /*QUAKED item_double (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2576 */
2577 {
2578 "item_double",
2579 Pickup_Powerup,
2580 Use_Double,
2581 Drop_General,
2582 NULL,
2583 "items/pkup.wav",
2584 "models/items/ddamage/tris.md2", EF_ROTATE,
2585 NULL,
2586 /* icon */ "p_double",
2587 /* pickup */ "Double Damage",
2588 /* width */ 2,
2589 60,
2590 NULL,
2591 IT_POWERUP,
2592 0,
2593 NULL,
2594 0,
2595 /* precache */ "misc/ddamage1.wav misc/ddamage2.wav misc/ddamage3.wav"
2596 },
2597
2598 /*Q U A K E D item_torch (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2599 */
2600 /*
2601 {
2602 "item_torch",
2603 Pickup_Powerup,
2604 Use_Torch,
2605 Drop_General,
2606 NULL,
2607 "items/pkup.wav",
2608 "models/objects/fire/tris.md2", EF_ROTATE,
2609 NULL,
2610 "p_torch",
2611 "torch",
2612 2,
2613 60,
2614 NULL,
2615 IT_POWERUP,
2616 0,
2617 NULL,
2618 0,
2619 },
2620 */
2621
2622 /*QUAKED item_compass (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2623 */
2624 {
2625 "item_compass",
2626 Pickup_Powerup,
2627 Use_Compass,
2628 NULL,
2629 NULL,
2630 "items/pkup.wav",
2631 "models/objects/fire/tris.md2", EF_ROTATE,
2632 NULL,
2633 /* icon */ "p_compass",
2634 /* pickup */ "compass",
2635 /* width */ 2,
2636 60,
2637 NULL,
2638 IT_POWERUP,
2639 0,
2640 NULL,
2641 0,
2642 },
2643
2644 /*QUAKED item_sphere_vengeance (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2645 */
2646 {
2647 "item_sphere_vengeance",
2648 Pickup_Sphere,
2649 Use_Vengeance,
2650 NULL,
2651 NULL,
2652 "items/pkup.wav",
2653 "models/items/vengnce/tris.md2", EF_ROTATE,
2654 NULL,
2655 /* icon */ "p_vengeance",
2656 /* pickup */ "vengeance sphere",
2657 /* width */ 2,
2658 60,
2659 NULL,
2660 IT_POWERUP,
2661 0,
2662 NULL,
2663 0,
2664 "spheres/v_idle.wav" //precache
2665 },
2666
2667 /*QUAKED item_sphere_hunter (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2668 */
2669 {
2670 "item_sphere_hunter",
2671 Pickup_Sphere,
2672 Use_Hunter,
2673 NULL,
2674 NULL,
2675 "items/pkup.wav",
2676 "models/items/hunter/tris.md2", EF_ROTATE,
2677 NULL,
2678 /* icon */ "p_hunter",
2679 /* pickup */ "hunter sphere",
2680 /* width */ 2,
2681 120,
2682 NULL,
2683 IT_POWERUP,
2684 0,
2685 NULL,
2686 0,
2687 "spheres/h_idle.wav spheres/h_active.wav spheres/h_lurk.wav" //precache
2688 },
2689
2690 /*QUAKED item_sphere_defender (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2691 */
2692 {
2693 "item_sphere_defender",
2694 Pickup_Sphere,
2695 Use_Defender,
2696 NULL,
2697 NULL,
2698 "items/pkup.wav",
2699 "models/items/defender/tris.md2", EF_ROTATE,
2700 NULL,
2701 /* icon */ "p_defender",
2702 /* pickup */ "defender sphere",
2703 /* width */ 2,
2704 60, // respawn time
2705 NULL, // ammo type used
2706 IT_POWERUP, // inventory flags
2707 0,
2708 NULL, // info (void *)
2709 0, // tag
2710 "models/proj/laser2/tris.md2 models/items/shell/tris.md2 spheres/d_idle.wav" // precache
2711 },
2712
2713 /*QUAKED item_doppleganger (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2714 */
2715 {
2716 "item_doppleganger", // classname
2717 Pickup_Doppleganger, // pickup function
2718 Use_Doppleganger, // use function
2719 Drop_General, // drop function
2720 NULL, // weapon think function
2721 "items/pkup.wav", // pick up sound
2722 "models/items/dopple/tris.md2", // world model
2723 EF_ROTATE, // world model flags
2724 NULL, // view model
2725 "p_doppleganger", // icon
2726 "Doppleganger", // name printed when picked up
2727 0, // number of digits for statusbar
2728 90, // respawn time
2729 NULL, // ammo type used
2730 IT_POWERUP, // inventory flags
2731 0,
2732 NULL, // info (void *)
2733 0, // tag
2734 "models/objects/dopplebase/tris.md2 models/items/spawngro2/tris.md2 models/items/hunter/tris.md2 models/items/vengnce/tris.md2", // precaches
2735 },
2736
2737 {
2738 // "dm_tag_token", // classname
2739 NULL, // classname
2740 Tag_PickupToken, // pickup function
2741 NULL, // use function
2742 NULL, // drop function
2743 NULL, // weapon think function
2744 "items/pkup.wav", // pick up sound
2745 "models/items/tagtoken/tris.md2", // world model
2746 EF_ROTATE | EF_TAGTRAIL, // world model flags
2747 NULL, // view model
2748 "i_tagtoken", // icon
2749 "Tag Token", // name printed when picked up
2750 0, // number of digits for statusbar
2751 0, // amount used / contained
2752 NULL, // ammo type used
2753 IT_POWERUP | IT_NOT_GIVEABLE, // inventory flags
2754 0,
2755 NULL, // info (void *)
2756 1, // tag
2757 NULL, // precaches
2758 },
2759
2760 // PGM
2761 // ======================================
2762
2763
2764 //
2765 // KEYS
2766 //
2767 /*QUAKED key_data_cd (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2768 key for computer centers
2769 */
2770 {
2771 "key_data_cd",
2772 Pickup_Key,
2773 NULL,
2774 Drop_General,
2775 NULL,
2776 "items/pkup.wav",
2777 "models/items/keys/data_cd/tris.md2", EF_ROTATE,
2778 NULL,
2779 "k_datacd",
2780 "Data CD",
2781 2,
2782 0,
2783 NULL,
2784 IT_STAY_COOP|IT_KEY,
2785 0,
2786 NULL,
2787 0,
2788 /* precache */ ""
2789 },
2790
2791 /*QUAKED key_power_cube (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH
2792 warehouse circuits
2793 */
2794 {
2795 "key_power_cube",
2796 Pickup_Key,
2797 NULL,
2798 Drop_General,
2799 NULL,
2800 "items/pkup.wav",
2801 "models/items/keys/power/tris.md2", EF_ROTATE,
2802 NULL,
2803 "k_powercube",
2804 "Power Cube",
2805 2,
2806 0,
2807 NULL,
2808 IT_STAY_COOP|IT_KEY,
2809 0,
2810 NULL,
2811 0,
2812 /* precache */ ""
2813 },
2814
2815 /*QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2816 key for the entrance of jail3
2817 */
2818 {
2819 "key_pyramid",
2820 Pickup_Key,
2821 NULL,
2822 Drop_General,
2823 NULL,
2824 "items/pkup.wav",
2825 "models/items/keys/pyramid/tris.md2", EF_ROTATE,
2826 NULL,
2827 "k_pyramid",
2828 "Pyramid Key",
2829 2,
2830 0,
2831 NULL,
2832 IT_STAY_COOP|IT_KEY,
2833 0,
2834 NULL,
2835 0,
2836 /* precache */ ""
2837 },
2838
2839 /*QUAKED key_data_spinner (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2840 key for the city computer
2841 */
2842 {
2843 "key_data_spinner",
2844 Pickup_Key,
2845 NULL,
2846 Drop_General,
2847 NULL,
2848 "items/pkup.wav",
2849 "models/items/keys/spinner/tris.md2", EF_ROTATE,
2850 NULL,
2851 "k_dataspin",
2852 "Data Spinner",
2853 2,
2854 0,
2855 NULL,
2856 IT_STAY_COOP|IT_KEY,
2857 0,
2858 NULL,
2859 0,
2860 /* precache */ ""
2861 },
2862
2863 /*QUAKED key_pass (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2864 security pass for the security level
2865 */
2866 {
2867 "key_pass",
2868 Pickup_Key,
2869 NULL,
2870 Drop_General,
2871 NULL,
2872 "items/pkup.wav",
2873 "models/items/keys/pass/tris.md2", EF_ROTATE,
2874 NULL,
2875 "k_security",
2876 "Security Pass",
2877 2,
2878 0,
2879 NULL,
2880 IT_STAY_COOP|IT_KEY,
2881 0,
2882 NULL,
2883 0,
2884 /* precache */ ""
2885 },
2886
2887 /*QUAKED key_blue_key (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2888 normal door key - blue
2889 */
2890 {
2891 "key_blue_key",
2892 Pickup_Key,
2893 NULL,
2894 Drop_General,
2895 NULL,
2896 "items/pkup.wav",
2897 "models/items/keys/key/tris.md2", EF_ROTATE,
2898 NULL,
2899 "k_bluekey",
2900 "Blue Key",
2901 2,
2902 0,
2903 NULL,
2904 IT_STAY_COOP|IT_KEY,
2905 0,
2906 NULL,
2907 0,
2908 /* precache */ ""
2909 },
2910
2911 /*QUAKED key_red_key (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2912 normal door key - red
2913 */
2914 {
2915 "key_red_key",
2916 Pickup_Key,
2917 NULL,
2918 Drop_General,
2919 NULL,
2920 "items/pkup.wav",
2921 "models/items/keys/red_key/tris.md2", EF_ROTATE,
2922 NULL,
2923 "k_redkey",
2924 "Red Key",
2925 2,
2926 0,
2927 NULL,
2928 IT_STAY_COOP|IT_KEY,
2929 0,
2930 NULL,
2931 0,
2932 /* precache */ ""
2933 },
2934
2935 /*QUAKED key_commander_head (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2936 tank commander's head
2937 */
2938 {
2939 "key_commander_head",
2940 Pickup_Key,
2941 NULL,
2942 Drop_General,
2943 NULL,
2944 "items/pkup.wav",
2945 "models/monsters/commandr/head/tris.md2", EF_GIB,
2946 NULL,
2947 /* icon */ "k_comhead",
2948 /* pickup */ "Commander's Head",
2949 /* width */ 2,
2950 0,
2951 NULL,
2952 IT_STAY_COOP|IT_KEY,
2953 0,
2954 NULL,
2955 0,
2956 /* precache */ ""
2957 },
2958
2959 /*QUAKED key_airstrike_target (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2960 tank commander's head
2961 */
2962 {
2963 "key_airstrike_target",
2964 Pickup_Key,
2965 NULL,
2966 Drop_General,
2967 NULL,
2968 "items/pkup.wav",
2969 "models/items/keys/target/tris.md2", EF_ROTATE,
2970 NULL,
2971 /* icon */ "i_airstrike",
2972 /* pickup */ "Airstrike Marker",
2973 /* width */ 2,
2974 0,
2975 NULL,
2976 IT_STAY_COOP|IT_KEY,
2977 0,
2978 NULL,
2979 0,
2980 /* precache */ ""
2981 },
2982
2983 // ======================================
2984 // PGM
2985
2986 /*QUAKED key_nuke_container (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
2987 */
2988 {
2989 "key_nuke_container", // classname
2990 Pickup_Key, // pickup function
2991 NULL, // use function
2992 Drop_General, // drop function
2993 NULL, // weapon think function
2994 "items/pkup.wav", // pick up sound
2995 "models/weapons/g_nuke/tris.md2", // world model
2996 EF_ROTATE, // world model flags
2997 NULL, // view model
2998 "i_contain", // icon
2999 "Antimatter Pod", // name printed when picked up
3000 2, // number of digits for statusbar
3001 0, // respawn time
3002 NULL, // ammo type used
3003 IT_STAY_COOP|IT_KEY, // inventory flags
3004 0,
3005 NULL, // info (void *)
3006 0, // tag
3007 NULL, // precaches
3008 },
3009
3010 /*QUAKED key_nuke (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3011 */
3012 {
3013 "key_nuke", // classname
3014 Pickup_Key, // pickup function
3015 NULL, // use function
3016 Drop_General, // drop function
3017 NULL, // weapon think function
3018 "items/pkup.wav", // pick up sound
3019 "models/weapons/g_nuke/tris.md2", // world model
3020 EF_ROTATE, // world model flags
3021 NULL, // view model
3022 "i_nuke", // icon
3023 "Antimatter Bomb", // name printed when picked up
3024 2, // number of digits for statusbar
3025 0, // respawn time
3026 NULL, // ammo type used
3027 IT_STAY_COOP|IT_KEY, // inventory flags
3028 0,
3029 NULL, // info (void *)
3030 0, // tag
3031 NULL, // precaches
3032 },
3033
3034 // PGM
3035 // ======================================
3036
3037 {
3038 NULL,
3039 Pickup_Health,
3040 NULL,
3041 NULL,
3042 NULL,
3043 "items/pkup.wav",
3044 NULL, 0,
3045 NULL,
3046 /* icon */ "i_health",
3047 /* pickup */ "Health",
3048 /* width */ 3,
3049 0,
3050 NULL,
3051 0,
3052 0,
3053 NULL,
3054 0,
3055 /* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav" // PMM - health sound fix
3056 },
3057
3058 // end of list marker
3059 {NULL}
3060 };
3061
3062
3063 /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3064 */
SP_item_health(edict_t * self)3065 void SP_item_health (edict_t *self)
3066 {
3067 if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3068 {
3069 G_FreeEdict (self);
3070 return;
3071 }
3072
3073 self->model = "models/items/healing/medium/tris.md2";
3074 self->count = 10;
3075 SpawnItem (self, FindItem ("Health"));
3076 gi.soundindex ("items/n_health.wav");
3077 }
3078
3079 /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3080 */
SP_item_health_small(edict_t * self)3081 void SP_item_health_small (edict_t *self)
3082 {
3083 if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3084 {
3085 G_FreeEdict (self);
3086 return;
3087 }
3088
3089 self->model = "models/items/healing/stimpack/tris.md2";
3090 self->count = 2;
3091 SpawnItem (self, FindItem ("Health"));
3092 self->style = HEALTH_IGNORE_MAX;
3093 gi.soundindex ("items/s_health.wav");
3094 }
3095
3096 /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3097 */
SP_item_health_large(edict_t * self)3098 void SP_item_health_large (edict_t *self)
3099 {
3100 if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3101 {
3102 G_FreeEdict (self);
3103 return;
3104 }
3105
3106 self->model = "models/items/healing/large/tris.md2";
3107 self->count = 25;
3108 SpawnItem (self, FindItem ("Health"));
3109 gi.soundindex ("items/l_health.wav");
3110 }
3111
3112 /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
3113 */
SP_item_health_mega(edict_t * self)3114 void SP_item_health_mega (edict_t *self)
3115 {
3116 if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
3117 {
3118 G_FreeEdict (self);
3119 return;
3120 }
3121
3122 self->model = "models/items/mega_h/tris.md2";
3123 self->count = 100;
3124 SpawnItem (self, FindItem ("Health"));
3125 gi.soundindex ("items/m_health.wav");
3126 self->style = HEALTH_IGNORE_MAX|HEALTH_TIMED;
3127 }
3128
3129
InitItems(void)3130 void InitItems (void)
3131 {
3132 game.num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1;
3133 }
3134
3135
3136
3137 /*
3138 ===============
3139 SetItemNames
3140
3141 Called by worldspawn
3142 ===============
3143 */
SetItemNames(void)3144 void SetItemNames (void)
3145 {
3146 int i;
3147 gitem_t *it;
3148
3149 for (i=0 ; i<game.num_items ; i++)
3150 {
3151 it = &itemlist[i];
3152 gi.configstring (CS_ITEMS+i, it->pickup_name);
3153 }
3154
3155 jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor"));
3156 combat_armor_index = ITEM_INDEX(FindItem("Combat Armor"));
3157 body_armor_index = ITEM_INDEX(FindItem("Body Armor"));
3158 power_screen_index = ITEM_INDEX(FindItem("Power Screen"));
3159 power_shield_index = ITEM_INDEX(FindItem("Power Shield"));
3160 }
3161
3162
3163 //===============
3164 //ROGUE
SP_xatrix_item(edict_t * self)3165 void SP_xatrix_item (edict_t *self)
3166 {
3167 gitem_t *item;
3168 int i;
3169 char *spawnClass;
3170
3171 if(!self->classname)
3172 return;
3173
3174 if(!strcmp(self->classname, "ammo_magslug"))
3175 spawnClass = "ammo_flechettes";
3176 else if(!strcmp(self->classname, "ammo_trap"))
3177 spawnClass = "weapon_proxlauncher";
3178 else if(!strcmp(self->classname, "item_quadfire"))
3179 {
3180 float chance;
3181
3182 chance = random();
3183 if(chance < 0.2)
3184 spawnClass = "item_sphere_hunter";
3185 else if (chance < 0.6)
3186 spawnClass = "item_sphere_vengeance";
3187 else
3188 spawnClass = "item_sphere_defender";
3189 }
3190 else if(!strcmp(self->classname, "weapon_boomer"))
3191 spawnClass = "weapon_etf_rifle";
3192 else if(!strcmp(self->classname, "weapon_phalanx"))
3193 spawnClass = "weapon_plasmabeam";
3194
3195
3196 // check item spawn functions
3197 for (i=0,item=itemlist ; i<game.num_items ; i++,item++)
3198 {
3199 if (!item->classname)
3200 continue;
3201 if (!strcmp(item->classname, spawnClass))
3202 { // found it
3203 SpawnItem (self, item);
3204 return;
3205 }
3206 }
3207 }
3208 //ROGUE
3209 //===============
3210