1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 #include "g_local.h"
21 #include "m_player.h"
22 #include "scanner.h"
23 #include "defense_laser.h"
24
25 // C14 Start of New Code
trimicons(int * icons)26 void trimicons(int *icons)
27 {
28 if (icons[6] == icons[5]) {
29 icons[6] = -1;
30 icons[4] = -1;
31 icons[7] = -1;
32 icons[3] = -1;
33 icons[8] = -1;
34 icons[2] = -1;
35 icons[9] = -1;
36 icons[1] = -1;
37 icons[10] = -1;
38 icons[0] = -1;
39 }
40 else if (icons[4] == icons[6]) {
41 icons[4] = -1;
42 icons[7] = -1;
43 icons[3] = -1;
44 icons[8] = -1;
45 icons[2] = -1;
46 icons[9] = -1;
47 icons[1] = -1;
48 icons[10] = -1;
49 icons[0] = -1;
50 }
51 else if (icons[7] == icons[4]) {
52 icons[7] = -1;
53 icons[3] = -1;
54 icons[8] = -1;
55 icons[2] = -1;
56 icons[9] = -1;
57 icons[1] = -1;
58 icons[10] = -1;
59 icons[0] = -1;
60 }
61 else if (icons[3] == icons[7]) {
62 icons[3] = -1;
63 icons[8] = -1;
64 icons[2] = -1;
65 icons[9] = -1;
66 icons[1] = -1;
67 icons[10] = -1;
68 icons[0] = -1;
69 }
70 else if (icons[8] == icons[3]) {
71 icons[8] = -1;
72 icons[2] = -1;
73 icons[9] = -1;
74 icons[1] = -1;
75 icons[10] = -1;
76 icons[0] = -1;
77 }
78 else if (icons[2] == icons[8]) {
79 icons[2] = -1;
80 icons[9] = -1;
81 icons[1] = -1;
82 icons[10] = -1;
83 icons[0] = -1;
84 }
85 else if (icons[9] == icons[2]) {
86 icons[9] = -1;
87 icons[1] = -1;
88 icons[10] = -1;
89 icons[0] = -1;
90 }
91 else if (icons[1] == icons[9]) {
92 icons[1] = -1;
93 icons[10] = -1;
94 icons[0] = -1;
95 }
96 else if (icons[10] == icons[1]) {
97 icons[10] = -1;
98 icons[0] = -1;
99 }
100 else if (icons[0] == icons[10]) {
101 icons[0] = -1;
102 }
103
104 }
105
c14_SetFastIcons(edict_t * ent,int itemtype)106 void c14_SetFastIcons(edict_t *ent, int itemtype)
107 {
108 gclient_t *cl;
109 int i, index;
110 gitem_t *it;
111 int icons[11];
112 int iconindex;
113
114 cl = ent->client;
115
116 icons[5] = cl->pers.selected_item;
117 for (iconindex = 6; iconindex < 11; iconindex++) {
118 icons[iconindex] = -1;
119 for (i = 1; i <= MAX_ITEMS; i++) {
120 index = (icons[iconindex-1] + i) % MAX_ITEMS;
121 if (!cl->pers.inventory[index])
122 continue;
123 it = &itemlist[index];
124 if (!it->use)
125 continue;
126 if (!(it->flags & itemtype))
127 continue;
128 icons[iconindex] = index;
129 break;
130 }
131 }
132
133 for (iconindex = 4; iconindex >= 0; iconindex--) {
134 icons[iconindex] = -1;
135 for (i = 1; i <= MAX_ITEMS; i++) {
136 index = (icons[iconindex+1] + MAX_ITEMS - i) % MAX_ITEMS;
137 if (!cl->pers.inventory[index])
138 continue;
139 it = &itemlist[index];
140 if (!it->use)
141 continue;
142 if (!(it->flags & itemtype))
143 continue;
144 icons[iconindex] = index;
145 break;
146 }
147 }
148
149 trimicons(icons);
150
151 for (i = 0; i < 11; i++) {
152 if (icons[i] == -1)
153 ent->client->ps.stats[STAT_FAST_PREV5 + i] = 0;
154 else
155 ent->client->ps.stats[STAT_FAST_PREV5 + i] =
156 gi.imageindex((&itemlist[icons[i]])->icon);
157 }
158
159 ent->client->fs_frame = level.framenum + 10;
160 ent->client->ps.stats[STAT_FAST_NAME] = CS_ITEMS + icons[5];
161 return;
162 }
163
c14_SetFastWIcons(edict_t * ent)164 void c14_SetFastWIcons(edict_t *ent)
165 {
166 gclient_t *cl;
167 int i, index;
168 gitem_t *it;
169 int icons[11];
170 int iconindex;
171
172 cl = ent->client;
173
174 if (!cl->newweapon)
175 return;
176
177 icons[5] = ITEM_INDEX(cl->newweapon);
178 for (iconindex = 6; iconindex < 11; iconindex++) {
179 icons[iconindex] = -1;
180 for (i = 1; i <= MAX_ITEMS; i++) {
181 index = (icons[iconindex-1] + i) % MAX_ITEMS;
182 if (!cl->pers.inventory[index])
183 continue;
184 it = &itemlist[index];
185 if (!it->use)
186 continue;
187 if (!(it->flags & IT_WEAPON))
188 continue;
189 icons[iconindex] = index;
190 break;
191 }
192 }
193
194 for (iconindex = 4; iconindex >= 0; iconindex--) {
195 icons[iconindex] = -1;
196 for (i = 1; i <= MAX_ITEMS; i++) {
197 index = (icons[iconindex+1] + MAX_ITEMS - i) % MAX_ITEMS;
198 if (!cl->pers.inventory[index])
199 continue;
200 it = &itemlist[index];
201 if (!it->use)
202 continue;
203 if (!(it->flags & IT_WEAPON))
204 continue;
205 icons[iconindex] = index;
206 break;
207 }
208 }
209
210 trimicons(icons);
211
212 for (i = 0; i < 11; i++) {
213 if (icons[i] == -1)
214 ent->client->ps.stats[STAT_FAST_PREV5 + i] = 0;
215 else
216 ent->client->ps.stats[STAT_FAST_PREV5 + i] =
217 gi.imageindex((&itemlist[icons[i]])->icon);
218 }
219
220 ent->client->fs_frame = level.framenum + 10;
221 ent->client->ps.stats[STAT_FAST_NAME] = CS_ITEMS + icons[5];
222 return;
223 }
224
225 // C14 End of New Code
226
227 int LIGHTS=0;
228
ClientTeam(edict_t * ent)229 char *ClientTeam (edict_t *ent)
230
231
232 {
233 char *p;
234 static char value[512];
235
236 value[0] = 0;
237
238 if (!ent->client)
239 return value;
240
241 strcpy(value, Info_ValueForKey (ent->client->pers.userinfo, "skin"));
242 p = strchr(value, '/');
243 if (!p)
244 return value;
245
246 if ((int)(dmflags->value) & DF_MODELTEAMS)
247 {
248 *p = 0;
249 return value;
250 }
251
252 // if ((int)(dmflags->value) & DF_SKINTEAMS)
253 return ++p;
254 }
255
OnSameTeam(edict_t * ent1,edict_t * ent2)256 qboolean OnSameTeam (edict_t *ent1, edict_t *ent2)
257 {
258 char ent1Team [512];
259 char ent2Team [512];
260
261 if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
262 return false;
263
264 strcpy (ent1Team, ClientTeam (ent1));
265 strcpy (ent2Team, ClientTeam (ent2));
266
267 if (strcmp(ent1Team, ent2Team) == 0)
268 return true;
269 return false;
270 }
271
272
SelectNextItem(edict_t * ent,int itflags)273 void SelectNextItem (edict_t *ent, int itflags)
274 {
275 gclient_t *cl;
276 int i, index;
277 gitem_t *it;
278
279 cl = ent->client;
280
281 if (cl->chase_target) {
282 ChaseNext(ent);
283 return;
284 }
285
286 // scan for the next valid one
287 for (i=1 ; i<=MAX_ITEMS ; i++)
288 {
289 index = (cl->pers.selected_item + i)%MAX_ITEMS;
290 if (!cl->pers.inventory[index])
291 continue;
292 it = &itemlist[index];
293 if (!it->use)
294 continue;
295 if (!(it->flags & itflags))
296 continue;
297
298 cl->pers.selected_item = index;
299 c14_SetFastIcons(ent, itflags); // C14 Add this line
300 return;
301 }
302
303 cl->pers.selected_item = -1;
304 }
305
SelectPrevItem(edict_t * ent,int itflags)306 void SelectPrevItem (edict_t *ent, int itflags)
307 {
308 gclient_t *cl;
309 int i, index;
310 gitem_t *it;
311
312 cl = ent->client;
313
314 if (cl->chase_target) {
315 ChasePrev(ent);
316 return;
317 }
318
319 // scan for the next valid one
320 for (i=1 ; i<=MAX_ITEMS ; i++)
321 {
322 index = (cl->pers.selected_item + MAX_ITEMS - i)%MAX_ITEMS;
323 if (!cl->pers.inventory[index])
324 continue;
325 it = &itemlist[index];
326 if (!it->use)
327 continue;
328 if (!(it->flags & itflags))
329 continue;
330
331 cl->pers.selected_item = index;
332 c14_SetFastIcons(ent, itflags); // C14 Add this line
333 return;
334 }
335
336 cl->pers.selected_item = -1;
337 }
338
ValidateSelectedItem(edict_t * ent)339 void ValidateSelectedItem (edict_t *ent)
340 {
341 gclient_t *cl;
342
343 cl = ent->client;
344
345 if (cl->pers.inventory[cl->pers.selected_item])
346 return; // valid
347
348 SelectNextItem (ent, -1);
349 }
350
351
352 //=================================================================================
353
354 /*
355 ==================
356 Cmd_Give_f
357
358 Give items to a client
359 ==================
360 */
Cmd_Give_f(edict_t * ent)361 void Cmd_Give_f (edict_t *ent)
362 {
363 char *name;
364 gitem_t *it;
365 int index;
366 int i;
367 qboolean give_all;
368 edict_t *it_ent;
369
370 if ((deathmatch->value || coop->value) && !sv_cheats->value)
371 {
372 #ifdef WITH_ACEBOT
373 safe_cprintf
374 #else
375 gi.cprintf
376 #endif
377 (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
378 return;
379 }
380
381 name = gi.args();
382
383 if (Q_stricmp(name, "all") == 0)
384 give_all = true;
385 else
386 give_all = false;
387
388 if (give_all || Q_stricmp(gi.argv(1), "health") == 0)
389 {
390 if (gi.argc() == 3)
391 ent->health = atoi(gi.argv(2));
392 else
393 ent->health = ent->max_health;
394 if (!give_all)
395 return;
396 }
397
398 if (give_all || Q_stricmp(name, "weapons") == 0)
399 {
400 for (i=0 ; i<game.num_items ; i++)
401 {
402 it = itemlist + i;
403 if (!it->pickup)
404 continue;
405 if (!(it->flags & IT_WEAPON))
406 continue;
407 ent->client->pers.inventory[i] += 1;
408 }
409 if (!give_all)
410 return;
411 }
412
413 if (give_all || Q_stricmp(name, "ammo") == 0)
414 {
415 for (i=0 ; i<game.num_items ; i++)
416 {
417 it = itemlist + i;
418 if (!it->pickup)
419 continue;
420 if (!(it->flags & IT_AMMO))
421 continue;
422 Add_Ammo (ent, it, 1000);
423 }
424 if (!give_all)
425 return;
426 }
427
428 if (give_all || Q_stricmp(name, "armor") == 0)
429 {
430 gitem_armor_t *info;
431
432 it = FindItem("Jacket Armor");
433 ent->client->pers.inventory[ITEM_INDEX(it)] = 0;
434
435 it = FindItem("Combat Armor");
436 ent->client->pers.inventory[ITEM_INDEX(it)] = 0;
437
438 it = FindItem("Body Armor");
439 info = (gitem_armor_t *)it->info;
440 ent->client->pers.inventory[ITEM_INDEX(it)] = info->max_count;
441
442 if (!give_all)
443 return;
444 }
445
446 if (give_all || Q_stricmp(name, "Power Shield") == 0)
447 {
448 it = FindItem("Power Shield");
449 it_ent = G_Spawn();
450 it_ent->classname = it->classname;
451 SpawnItem (it_ent, it);
452 Touch_Item (it_ent, ent, NULL, NULL);
453 if (it_ent->inuse)
454 G_FreeEdict(it_ent);
455
456 if (!give_all)
457 return;
458 }
459
460 if (give_all)
461 {
462 for (i=0 ; i<game.num_items ; i++)
463 {
464 it = itemlist + i;
465 if (!it->pickup)
466 continue;
467 if (it->flags & (IT_ARMOR|IT_WEAPON|IT_AMMO))
468 continue;
469 ent->client->pers.inventory[i] = 1;
470 }
471 return;
472 }
473
474 it = FindItem (name);
475 if (!it)
476 {
477 name = gi.argv(1);
478 it = FindItem (name);
479 if (!it)
480 {
481 #ifdef WITH_ACEBOT
482 safe_cprintf
483 #else
484 gi.cprintf
485 #endif
486
487 (ent, PRINT_HIGH, "unknown item\n");
488 return;
489 }
490 }
491
492 if (!it->pickup)
493 {
494 #ifdef WITH_ACEBOT
495 safe_cprintf
496 #else
497 gi.cprintf
498 #endif
499 (ent, PRINT_HIGH, "non-pickup item\n");
500 return;
501 }
502
503 index = ITEM_INDEX(it);
504
505 if (it->flags & IT_AMMO)
506 {
507 if (gi.argc() == 3)
508 ent->client->pers.inventory[index] = atoi(gi.argv(2));
509 else
510 ent->client->pers.inventory[index] += it->quantity;
511 }
512 else
513 {
514 it_ent = G_Spawn();
515 it_ent->classname = it->classname;
516 SpawnItem (it_ent, it);
517 Touch_Item (it_ent, ent, NULL, NULL);
518 if (it_ent->inuse)
519 G_FreeEdict(it_ent);
520 }
521 }
522
523
524 /*
525 ==================
526 Cmd_God_f
527
528 Sets client to godmode
529
530 argv(0) god
531 ==================
532 */
Cmd_God_f(edict_t * ent)533 void Cmd_God_f (edict_t *ent)
534 {
535 char *msg;
536
537 if ((deathmatch->value || coop->value) && !sv_cheats->value)
538 {
539 #ifdef WITH_ACEBOT
540 safe_cprintf
541 #else
542 gi.cprintf
543 #endif
544 (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
545 return;
546 }
547
548 ent->flags ^= FL_GODMODE;
549 if (!(ent->flags & FL_GODMODE) )
550 msg = "godmode OFF\n";
551 else
552 msg = "godmode ON\n";
553
554 #ifdef WITH_ACEBOT
555 safe_cprintf
556 #else
557 gi.cprintf
558 #endif
559 (ent, PRINT_HIGH, msg);
560 }
561
562
563 /*
564 ==================
565 Cmd_Notarget_f
566
567 Sets client to notarget
568
569 argv(0) notarget
570 ==================
571 */
Cmd_Notarget_f(edict_t * ent)572 void Cmd_Notarget_f (edict_t *ent)
573 {
574 char *msg;
575
576 if ((deathmatch->value || coop->value) && !sv_cheats->value)
577 {
578 #ifdef WITH_ACEBOT
579 safe_cprintf
580 #else
581 gi.cprintf
582 #endif
583 (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
584 return;
585 }
586
587 ent->flags ^= FL_NOTARGET;
588 if (!(ent->flags & FL_NOTARGET) )
589 msg = "notarget OFF\n";
590 else
591 msg = "notarget ON\n";
592
593 #ifdef WITH_ACEBOT
594 safe_cprintf
595 #else
596 gi.cprintf
597 #endif
598 (ent, PRINT_HIGH, msg);
599 }
600
601
602 /*
603 ==================
604 Cmd_Noclip_f
605
606 argv(0) noclip
607 ==================
608 */
Cmd_Noclip_f(edict_t * ent)609 void Cmd_Noclip_f (edict_t *ent)
610 {
611 char *msg;
612
613 if ((deathmatch->value || coop->value) && !sv_cheats->value)
614 {
615 #ifdef WITH_ACEBOT
616 safe_cprintf
617 #else
618 gi.cprintf
619 #endif
620 (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
621 return;
622 }
623
624 if (ent->movetype == MOVETYPE_NOCLIP)
625 {
626 ent->movetype = MOVETYPE_WALK;
627 msg = "noclip OFF\n";
628 }
629 else
630 {
631 ent->movetype = MOVETYPE_NOCLIP;
632 msg = "noclip ON\n";
633 }
634
635 #ifdef WITH_ACEBOT
636 safe_cprintf
637 #else
638 gi.cprintf
639 #endif
640 (ent, PRINT_HIGH, msg);
641 }
642
643
644 /*
645 ==================
646 Cmd_Use_f
647
648 Use an inventory item
649 ==================
650 */
Cmd_Use_f(edict_t * ent)651 void Cmd_Use_f (edict_t *ent)
652 {
653 int index;
654 gitem_t *it;
655 char *s;
656
657 s = gi.args();
658 it = FindItem (s);
659 if (!it)
660 {
661 #ifdef WITH_ACEBOT
662 safe_cprintf
663 #else
664 gi.cprintf
665 #endif
666 (ent, PRINT_HIGH, "unknown item: %s\n", s);
667 return;
668 }
669 if (!it->use)
670 {
671 #ifdef WITH_ACEBOT
672 safe_cprintf
673 #else
674 gi.cprintf
675 #endif
676 (ent, PRINT_HIGH, "Item is not usable.\n");
677 return;
678 }
679 index = ITEM_INDEX(it);
680 if (!ent->client->pers.inventory[index])
681 {
682 #ifdef WITH_ACEBOT
683 safe_cprintf
684 #else
685 gi.cprintf
686 #endif
687 (ent, PRINT_HIGH, "Out of item: %s\n", s);
688 return;
689 }
690 else if (!Q_strcasecmp(s, ent->client->pers.weapon->pickup_name))
691 {
692 if (!Q_strcasecmp(s, "machinegun"))
693 {
694 if (ent->client->resp.firemode == 0)
695 {
696 ent->client->resp.firemode = 1;
697 #ifdef WITH_ACEBOT
698 safe_cprintf
699 #else
700 gi.cprintf
701 #endif
702 (ent, PRINT_HIGH, "3 Round Burst\n");
703 }
704 else if (ent->client->resp.firemode == 1)
705 {
706 ent->client->resp.firemode = 2;
707 #ifdef WITH_ACEBOT
708 safe_cprintf
709 #else
710 gi.cprintf
711 #endif
712 (ent, PRINT_HIGH, "Single Shot\n");
713 }
714 else
715 {
716 ent->client->selectfire_count=0;
717 ent->client->resp.firemode = 0;
718 #ifdef WITH_ACEBOT
719 safe_cprintf
720 #else
721 gi.cprintf
722 #endif
723 (ent, PRINT_HIGH, "Automatic\n");
724 }
725 }
726 }
727 else if (!Q_strcasecmp(s, "machinegun"))
728 {
729 ent->client->resp.firemode = 0;
730 }
731 it->use (ent, it);
732 }
733
734
735 /*
736 ==================
737 Cmd_Drop_f
738
739 Drop an inventory item
740 ==================
741 */
Cmd_Drop_f(edict_t * ent)742 void Cmd_Drop_f (edict_t *ent)
743 {
744 int index;
745 gitem_t *it;
746 char *s;
747
748 s = gi.args();
749 it = FindItem (s);
750 if (!it)
751 {
752 #ifdef WITH_ACEBOT
753 safe_cprintf
754 #else
755 gi.cprintf
756 #endif
757 (ent, PRINT_HIGH, "unknown item: %s\n", s);
758 return;
759 }
760 if (!it->drop)
761 {
762 #ifdef WITH_ACEBOT
763 safe_cprintf
764 #else
765 gi.cprintf
766 #endif
767 (ent, PRINT_HIGH, "Item is not dropable.\n");
768 return;
769 }
770 index = ITEM_INDEX(it);
771 if (!ent->client->pers.inventory[index])
772 {
773 #ifdef WITH_ACEBOT
774 safe_cprintf
775 #else
776 gi.cprintf
777 #endif
778 (ent, PRINT_HIGH, "Out of item: %s\n", s);
779 return;
780 }
781
782 it->drop (ent, it);
783 }
784
785
786 /*
787 =================
788 Cmd_Inven_f
789 =================
790 */
Cmd_Inven_f(edict_t * ent)791 void Cmd_Inven_f (edict_t *ent)
792 {
793 int i;
794 gclient_t *cl;
795
796 cl = ent->client;
797
798 cl->showscores = false;
799 cl->showhelp = false;
800
801 if (cl->showinventory)
802 {
803 cl->showinventory = false;
804 return;
805 }
806
807 cl->showinventory = true;
808
809 gi.WriteByte (svc_inventory);
810 for (i=0 ; i<MAX_ITEMS ; i++)
811 {
812 gi.WriteShort (cl->pers.inventory[i]);
813 }
814 gi.unicast (ent, true);
815 if (cl->pers.scanner_active & 1)
816 cl->pers.scanner_active = 2;
817 }
818
819 /*
820 =================
821 Cmd_InvUse_f
822 =================
823 */
Cmd_InvUse_f(edict_t * ent)824 void Cmd_InvUse_f (edict_t *ent)
825 {
826 gitem_t *it;
827
828 ValidateSelectedItem (ent);
829
830 if (ent->client->pers.selected_item == -1)
831 {
832 #ifdef WITH_ACEBOT
833 safe_cprintf
834 #else
835 gi.cprintf
836 #endif
837 (ent, PRINT_HIGH, "No item to use.\n");
838 return;
839 }
840
841 it = &itemlist[ent->client->pers.selected_item];
842 if (!it->use)
843 {
844 #ifdef WITH_ACEBOT
845 safe_cprintf
846 #else
847 gi.cprintf
848 #endif
849 (ent, PRINT_HIGH, "Item is not usable.\n");
850 return;
851 }
852 it->use (ent, it);
853 }
854
855 /*
856 =================
857 Cmd_WeapPrev_f
858 =================
859 */
Cmd_WeapPrev_f(edict_t * ent)860 void Cmd_WeapPrev_f (edict_t *ent)
861 {
862 gclient_t *cl;
863 int i, index;
864 gitem_t *it;
865 int selected_weapon;
866
867 cl = ent->client;
868
869 if (!cl->pers.weapon)
870 return;
871
872 selected_weapon = ITEM_INDEX(cl->pers.weapon);
873
874 // scan for the next valid one
875 for (i=1 ; i<=MAX_ITEMS ; i++)
876 {
877 index = (selected_weapon + i)%MAX_ITEMS;
878 if (!cl->pers.inventory[index])
879 continue;
880 it = &itemlist[index];
881 if (!it->use)
882 continue;
883 if (! (it->flags & IT_WEAPON) )
884 continue;
885 it->use (ent, it);
886 // if (cl->pers.weapon == it) // C14 Remove This Line
887 // return; // successful // C14 Remove This Line
888 // C14 Start of New Code
889 if (cl->newweapon == it) {
890 c14_SetFastWIcons(ent);
891 return; // successful
892 }
893 // C14 End of New Code
894 }
895 }
896
897 /*
898 =================
899 Cmd_WeapNext_f
900 =================
901 */
Cmd_WeapNext_f(edict_t * ent)902 void Cmd_WeapNext_f (edict_t *ent)
903 {
904 gclient_t *cl;
905 int i, index;
906 gitem_t *it;
907 int selected_weapon;
908
909 cl = ent->client;
910
911 if (!cl->pers.weapon)
912 return;
913
914 selected_weapon = ITEM_INDEX(cl->pers.weapon);
915
916 // scan for the next valid one
917 for (i=1 ; i<=MAX_ITEMS ; i++)
918 {
919 index = (selected_weapon + MAX_ITEMS - i)%MAX_ITEMS;
920 if (!cl->pers.inventory[index])
921 continue;
922 it = &itemlist[index];
923 if (!it->use)
924 continue;
925 if (! (it->flags & IT_WEAPON) )
926 continue;
927 it->use (ent, it);
928 // if (cl->pers.weapon == it)
929 // return; // successful
930 // C14 Start of New Code
931 if (cl->newweapon == it) {
932 c14_SetFastWIcons(ent);
933 return; // successful
934 }
935 // C14 End of New Code
936 }
937 }
938
939 /*
940 =================
941 Cmd_WeapLast_f
942 =================
943 */
Cmd_WeapLast_f(edict_t * ent)944 void Cmd_WeapLast_f (edict_t *ent)
945 {
946 gclient_t *cl;
947 int index;
948 gitem_t *it;
949
950 cl = ent->client;
951
952 if (!cl->pers.weapon || !cl->pers.lastweapon)
953 return;
954
955 index = ITEM_INDEX(cl->pers.lastweapon);
956 if (!cl->pers.inventory[index])
957 return;
958 it = &itemlist[index];
959 if (!it->use)
960 return;
961 if (! (it->flags & IT_WEAPON) )
962 return;
963 it->use (ent, it);
964 // C14 Start of New Code
965 if (cl->newweapon == it) {
966 c14_SetFastWIcons(ent);
967 return; // successful
968 }
969 // C14 End of New Code
970 }
971
972 /*
973 =================
974 Cmd_InvDrop_f
975 =================
976 */
Cmd_InvDrop_f(edict_t * ent)977 void Cmd_InvDrop_f (edict_t *ent)
978 {
979 gitem_t *it;
980
981 ValidateSelectedItem (ent);
982
983 if (ent->client->pers.selected_item == -1)
984 {
985 #ifdef WITH_ACEBOT
986 safe_cprintf
987 #else
988 gi.cprintf
989 #endif
990 (ent, PRINT_HIGH, "No item to drop.\n");
991 return;
992 }
993
994 it = &itemlist[ent->client->pers.selected_item];
995 if (!it->drop)
996 {
997 #ifdef WITH_ACEBOT
998 safe_cprintf
999 #else
1000 gi.cprintf
1001 #endif
1002 (ent, PRINT_HIGH, "Item is not dropable.\n");
1003 return;
1004 }
1005 it->drop (ent, it);
1006 }
1007
1008 /*
1009 =================
1010 Cmd_Kill_f
1011 =================
1012 */
Cmd_Kill_f(edict_t * ent)1013 void Cmd_Kill_f (edict_t *ent)
1014 {
1015 if((level.time - ent->client->respawn_time) < 5 ||
1016 (ent->client->resp.spectator))
1017 return;
1018 ent->flags &= ~FL_GODMODE;
1019 ent->health = 0;
1020 meansOfDeath = MOD_SUICIDE;
1021 player_die (ent, ent, ent, 100000, vec3_origin);
1022 }
1023
1024 /*
1025 =================
1026 Cmd_PutAway_f
1027 =================
1028 */
Cmd_PutAway_f(edict_t * ent)1029 void Cmd_PutAway_f (edict_t *ent)
1030 {
1031 ent->client->showscores = false;
1032 ent->client->showhelp = false;
1033 ent->client->showinventory = false;
1034 }
1035
1036
PlayerSort(void const * a,void const * b)1037 int PlayerSort (void const *a, void const *b)
1038 {
1039 int anum, bnum;
1040
1041 anum = *(int *)a;
1042 bnum = *(int *)b;
1043
1044 anum = game.clients[anum].ps.stats[STAT_FRAGS];
1045 bnum = game.clients[bnum].ps.stats[STAT_FRAGS];
1046
1047 if (anum < bnum)
1048 return -1;
1049 if (anum > bnum)
1050 return 1;
1051 return 0;
1052 }
1053
1054 /*
1055 =================
1056 Cmd_Players_f
1057 =================
1058 */
Cmd_Players_f(edict_t * ent)1059 void Cmd_Players_f (edict_t *ent)
1060 {
1061 int i;
1062 int count;
1063 char small[64];
1064 char large[1280];
1065 int index[256];
1066
1067 count = 0;
1068 for (i = 0 ; i < maxclients->value ; i++)
1069 if (game.clients[i].pers.connected)
1070 {
1071 index[count] = i;
1072 count++;
1073 }
1074
1075 // sort by frags
1076 qsort (index, count, sizeof(index[0]), PlayerSort);
1077
1078 // print information
1079 large[0] = 0;
1080
1081 for (i = 0 ; i < count ; i++)
1082 {
1083 Com_sprintf (small, sizeof(small), "%3i %s\n",
1084 game.clients[index[i]].ps.stats[STAT_FRAGS],
1085 game.clients[index[i]].pers.netname);
1086 if (strlen (small) + strlen(large) > sizeof(large) - 100 )
1087 { // can't print all of them in one packet
1088 strcat (large, "...\n");
1089 break;
1090 }
1091 strcat (large, small);
1092 }
1093
1094 #ifdef WITH_ACEBOT
1095 safe_cprintf
1096 #else
1097 gi.cprintf
1098 #endif
1099 (ent, PRINT_HIGH, "%s\n%i players\n", large, count);
1100 }
1101
1102 /*
1103 =================
1104 Cmd_Wave_f
1105 =================
1106 */
Cmd_Wave_f(edict_t * ent)1107 void Cmd_Wave_f (edict_t *ent)
1108 {
1109 int i;
1110
1111 i = atoi (gi.argv(1));
1112
1113 // can't wave when ducked
1114 if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
1115 return;
1116
1117 if (ent->client->anim_priority > ANIM_WAVE)
1118 return;
1119
1120 ent->client->anim_priority = ANIM_WAVE;
1121
1122 switch (i)
1123 {
1124 case 0:
1125 #ifdef WITH_ACEBOT
1126 safe_cprintf
1127 #else
1128 gi.cprintf
1129 #endif
1130 (ent, PRINT_HIGH, "flipoff\n");
1131 ent->s.frame = FRAME_flip01-1;
1132 ent->client->anim_end = FRAME_flip12;
1133 break;
1134 case 1:
1135 #ifdef WITH_ACEBOT
1136 safe_cprintf
1137 #else
1138 gi.cprintf
1139 #endif
1140 (ent, PRINT_HIGH, "salute\n");
1141 ent->s.frame = FRAME_salute01-1;
1142 ent->client->anim_end = FRAME_salute11;
1143 break;
1144 case 2:
1145 #ifdef WITH_ACEBOT
1146 safe_cprintf
1147 #else
1148 gi.cprintf
1149 #endif
1150 (ent, PRINT_HIGH, "taunt\n");
1151 ent->s.frame = FRAME_taunt01-1;
1152 ent->client->anim_end = FRAME_taunt17;
1153 break;
1154 case 3:
1155 #ifdef WITH_ACEBOT
1156 safe_cprintf
1157 #else
1158 gi.cprintf
1159 #endif
1160 (ent, PRINT_HIGH, "wave\n");
1161 ent->s.frame = FRAME_wave01-1;
1162 ent->client->anim_end = FRAME_wave11;
1163 break;
1164 case 4:
1165 default:
1166 #ifdef WITH_ACEBOT
1167 safe_cprintf
1168 #else
1169 gi.cprintf
1170 #endif
1171 (ent, PRINT_HIGH, "point\n");
1172 ent->s.frame = FRAME_point01-1;
1173 ent->client->anim_end = FRAME_point12;
1174 break;
1175 }
1176 }
1177
1178 /*
1179 ==================
1180 Cmd_Say_f
1181 ==================
1182 */
Cmd_Say_f(edict_t * ent,qboolean team,qboolean arg0)1183 void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
1184 {
1185 int i, j;
1186 edict_t *other;
1187 char *p;
1188 char text[2048];
1189 gclient_t *cl;
1190
1191 if (gi.argc () < 2 && !arg0)
1192 return;
1193
1194 if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
1195 team = false;
1196
1197 if (team)
1198 Com_sprintf (text, sizeof(text), "(%s): ", ent->client->pers.netname);
1199 else
1200 Com_sprintf (text, sizeof(text), "%s: ", ent->client->pers.netname);
1201
1202 if (arg0)
1203 {
1204 strcat (text, gi.argv(0));
1205 strcat (text, " ");
1206 strcat (text, gi.args());
1207 }
1208 else
1209 {
1210 p = gi.args();
1211
1212 if (*p == '"')
1213 {
1214 p++;
1215 p[strlen(p)-1] = 0;
1216 }
1217 strcat(text, p);
1218 }
1219
1220 // don't let text be too long for malicious reasons
1221 if (strlen(text) > 150)
1222 text[150] = 0;
1223
1224 strcat(text, "\n");
1225
1226 if (flood_msgs->value) {
1227 cl = ent->client;
1228
1229 if (level.time < cl->flood_locktill) {
1230 #ifdef WITH_ACEBOT
1231 safe_cprintf
1232 #else
1233 gi.cprintf
1234 #endif
1235 (ent, PRINT_HIGH, "You can't talk for %d more seconds\n",
1236 (int)(cl->flood_locktill - level.time));
1237 return;
1238 }
1239 i = cl->flood_whenhead - flood_msgs->value + 1;
1240 if (i < 0)
1241 i = (sizeof(cl->flood_when)/sizeof(cl->flood_when[0])) + i;
1242 if (cl->flood_when[i] &&
1243 level.time - cl->flood_when[i] < flood_persecond->value) {
1244 cl->flood_locktill = level.time + flood_waitdelay->value;
1245 #ifdef WITH_ACEBOT
1246 safe_cprintf
1247 #else
1248 gi.cprintf
1249 #endif
1250 (ent, PRINT_CHAT, "Flood protection: You can't talk for %d seconds.\n",
1251 (int)flood_waitdelay->value);
1252 return;
1253 }
1254 cl->flood_whenhead = (cl->flood_whenhead + 1) %
1255 (sizeof(cl->flood_when)/sizeof(cl->flood_when[0]));
1256 cl->flood_when[cl->flood_whenhead] = level.time;
1257 }
1258
1259 if (dedicated->value)
1260 #ifdef WITH_ACEBOT
1261 safe_cprintf
1262 #else
1263 gi.cprintf
1264 #endif
1265 (NULL, PRINT_CHAT, "%s", text);
1266
1267 for (j = 1; j <= game.maxclients; j++)
1268 {
1269 other = &g_edicts[j];
1270 if (!other->inuse)
1271 continue;
1272 if (!other->client)
1273 continue;
1274 if (team)
1275 {
1276 if (!OnSameTeam(ent, other))
1277 continue;
1278 }
1279 #ifdef WITH_ACEBOT
1280 safe_cprintf
1281 #else
1282 gi.cprintf
1283 #endif
1284 (other, PRINT_CHAT, "%s", text);
1285 }
1286 }
1287
Cmd_PlayerList_f(edict_t * ent)1288 void Cmd_PlayerList_f(edict_t *ent)
1289 {
1290 int i;
1291 char st[80];
1292 char text[1400];
1293 edict_t *e2;
1294
1295 // connect time, ping, score, name
1296 *text = 0;
1297 for (i = 0, e2 = g_edicts + 1; i < maxclients->value; i++, e2++) {
1298 if (!e2->inuse)
1299 continue;
1300
1301 Com_sprintf(st, sizeof(st), "%02d:%02d %4d %3d %s%s\n",
1302 (level.framenum - e2->client->resp.enterframe) / 600,
1303 ((level.framenum - e2->client->resp.enterframe) % 600)/10,
1304 e2->client->ping,
1305 e2->client->resp.score,
1306 e2->client->pers.netname,
1307 e2->client->resp.spectator ? " (spectator)" : "");
1308 if (strlen(text) + strlen(st) > sizeof(text) - 50) {
1309 sprintf(text+strlen(text), "And more...\n");
1310 #ifdef WITH_ACEBOT
1311 safe_cprintf
1312 #else
1313 gi.cprintf
1314 #endif
1315 (ent, PRINT_HIGH, "%s", text);
1316 return;
1317 }
1318 strcat(text, st);
1319 }
1320 #ifdef WITH_ACEBOT
1321 safe_cprintf
1322 #else
1323 gi.cprintf
1324 #endif
1325 (ent, PRINT_HIGH, "%s", text);
1326 }
1327
Cmd_Infrared_f(edict_t * ent)1328 void Cmd_Infrared_f (edict_t *ent) // PSY: IR Goggles
1329 {
1330 if (ent->client->goggles) // we're on
1331 {
1332 ent->client->goggles = 0;
1333 ent->client->ps.rdflags &= ~RDF_IRGOGGLES;
1334 }
1335 else // we're off
1336 {
1337 ent->client->goggles = 1;
1338 ent->client->ps.rdflags |= RDF_IRGOGGLES;
1339 }
1340 }
1341
1342 /*
1343 =================
1344 Cmd_Thrust_f
1345
1346 MUCE:
1347 To set jetpack on or off
1348 =================
1349 */
Cmd_Thrust_f(edict_t * ent)1350 void Cmd_Thrust_f (edict_t *ent)
1351 {
1352 char *string;
1353
1354 string=gi.args();
1355
1356 if (Q_stricmp ( string, "on") == 0)
1357 {
1358 ent->client->thrusting=1;
1359 ent->client->next_thrust_sound=0;
1360 }
1361 else
1362 {
1363 ent->client->thrusting=0;
1364 }
1365 }
1366
1367 //Begin code
1368 /*
1369 =================
1370 Cmd_id_f
1371 New function to print player name and dist
1372 By Reven
1373 =================
1374 */
Cmd_id_f(edict_t * ent)1375 void Cmd_id_f (edict_t *ent)
1376 {
1377 int j;
1378 char stats[500];
1379 vec3_t start, forward, end;
1380 trace_t tr;
1381 j = sprintf(stats, " NAME RANGE\n\n");
1382
1383 VectorCopy(ent->s.origin, start);
1384 start[2] += ent->viewheight;
1385 AngleVectors(ent->client->v_angle, forward, NULL, NULL);
1386 VectorMA(start, 8192, forward, end);
1387 tr = gi.trace(start, NULL, NULL, end, ent,
1388 MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA);
1389 if (tr.ent->client)
1390 {
1391 j += sprintf(stats + j, "%16s %i\n",
1392 tr.ent->client->pers.netname, (int)(tr.fraction * 512));
1393 #ifdef WITH_ACEBOT
1394 safe_centerprintf
1395 #else
1396 gi.centerprintf
1397 #endif
1398 (ent, "%s", stats);
1399 }
1400
1401 }
1402
1403 /*
1404 =================
1405 ClientCommand
1406 =================
1407 */
ClientCommand(edict_t * ent)1408 void ClientCommand (edict_t *ent)
1409 {
1410 char *cmd;
1411
1412 if (!ent->client)
1413 return; // not fully in game yet
1414 #ifdef WITH_ACEBOT
1415 // ACEBOT_ADD
1416 if(ACECM_Commands(ent))
1417 return;
1418 // ACEBOT_END
1419 #endif
1420 cmd = gi.argv(0);
1421
1422 if (Q_stricmp (cmd, "players") == 0)
1423 {
1424 Cmd_Players_f (ent);
1425 return;
1426 }
1427 if (Q_stricmp (cmd, "say") == 0)
1428 {
1429 Cmd_Say_f (ent, false, false);
1430 return;
1431 }
1432 if (Q_stricmp (cmd, "say_team") == 0)
1433 {
1434 Cmd_Say_f (ent, true, false);
1435 return;
1436 }
1437 if (Q_stricmp (cmd, "score") == 0)
1438 {
1439 Cmd_Score_f (ent);
1440 return;
1441 }
1442 if (Q_stricmp (cmd, "help") == 0)
1443 {
1444 Cmd_Help_f (ent);
1445 return;
1446 }
1447
1448 if (level.intermissiontime)
1449 return;
1450
1451 if (Q_stricmp (cmd, "use") == 0)
1452 Cmd_Use_f (ent);
1453 else if (Q_stricmp (cmd, "drop") == 0)
1454 Cmd_Drop_f (ent);
1455 else if (Q_stricmp (cmd, "give") == 0)
1456 Cmd_Give_f (ent);
1457 else if (Q_stricmp (cmd, "god") == 0)
1458 Cmd_God_f (ent);
1459 else if (Q_stricmp (cmd, "notarget") == 0)
1460 Cmd_Notarget_f (ent);
1461 else if (Q_stricmp (cmd, "noclip") == 0)
1462 Cmd_Noclip_f (ent);
1463 else if (Q_stricmp (cmd, "inven") == 0)
1464 Cmd_Inven_f (ent);
1465 else if (Q_stricmp (cmd, "invnext") == 0)
1466 SelectNextItem (ent, -1);
1467 else if (Q_stricmp (cmd, "invprev") == 0)
1468 SelectPrevItem (ent, -1);
1469 else if (Q_stricmp (cmd, "invnextw") == 0)
1470 SelectNextItem (ent, IT_WEAPON);
1471 else if (Q_stricmp (cmd, "invprevw") == 0)
1472 SelectPrevItem (ent, IT_WEAPON);
1473 else if (Q_stricmp (cmd, "invnextp") == 0)
1474 SelectNextItem (ent, IT_POWERUP);
1475 else if (Q_stricmp (cmd, "invprevp") == 0)
1476 SelectPrevItem (ent, IT_POWERUP);
1477 else if (Q_stricmp (cmd, "invuse") == 0)
1478 Cmd_InvUse_f (ent);
1479 else if (Q_stricmp (cmd, "invdrop") == 0)
1480 Cmd_InvDrop_f (ent);
1481 else if (Q_stricmp (cmd, "weapprev") == 0)
1482 Cmd_WeapPrev_f (ent);
1483 else if (Q_stricmp (cmd, "weapnext") == 0)
1484 Cmd_WeapNext_f (ent);
1485 else if (Q_stricmp (cmd, "weaplast") == 0)
1486 Cmd_WeapLast_f (ent);
1487 else if (Q_stricmp (cmd, "kill") == 0)
1488 Cmd_Kill_f (ent);
1489 else if (Q_stricmp (cmd, "putaway") == 0)
1490 Cmd_PutAway_f (ent);
1491 else if (Q_stricmp (cmd, "wave") == 0)
1492 Cmd_Wave_f (ent);
1493 else if (Q_stricmp(cmd, "playerlist") == 0)
1494 Cmd_PlayerList_f(ent);
1495 else if (Q_stricmp (cmd, "scanner") == 0)
1496 Toggle_Scanner (ent);
1497 else if (Q_stricmp (cmd, "defense_laser") == 0)
1498 PlaceLaser (ent);
1499 else if (Q_stricmp (cmd, "decoy") == 0)
1500 SP_Decoy (ent);
1501 else if (Q_stricmp(cmd, "thrust") == 0 )
1502 Cmd_Thrust_f (ent);
1503 else if (Q_stricmp (cmd, "id") == 0)
1504 Cmd_id_f (ent);
1505 else if (Q_stricmp (cmd, "chasecam") == 0)
1506 Cmd_Chasecam_Toggle (ent);
1507 else if (Q_stricmp (cmd, "camzoomout") == 0)
1508 Cmd_Chasecam_Zoom(ent, "out");
1509 else if (Q_stricmp (cmd, "camzoomin") == 0)
1510 Cmd_Chasecam_Zoom(ent, "in");
1511 else if (Q_stricmp (cmd, "camviewlock") == 0)
1512 Cmd_Chasecam_Viewlock(ent);
1513 else if (Q_stricmp (cmd, "camreset") == 0){
1514 if (ent->client->chasetoggle != 3 && ent->client->chasetoggle != 0){
1515 ent->client->chasecam->chaseAngle = 0;
1516 }
1517 }
1518 else if (Q_stricmp (cmd, "flashlight") == 0)
1519 FL_make (ent);
1520 else if (Q_stricmp (cmd, "laser") == 0)
1521 SP_LaserSight (ent);
1522 else if(Q_stricmp (cmd, "sorpresa") == 0)
1523 {
1524 if (LIGHTS)
1525 {
1526 // 0 normal
1527 gi.configstring(CS_LIGHTS+0, "m");
1528
1529 // 1 FLICKER (first variety)
1530 gi.configstring(CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo");
1531
1532 // 2 SLOW STRONG PULSE
1533 gi.configstring(CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
1534
1535 // 3 CANDLE (first variety)
1536 gi.configstring(CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
1537
1538 // 4 FAST STROBE
1539 gi.configstring(CS_LIGHTS+4, "mamamamamama");
1540
1541 // 5 GENTLE PULSE 1
1542 gi.configstring(CS_LIGHTS+5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
1543
1544 // 6 FLICKER (second variety)
1545 gi.configstring(CS_LIGHTS+6, "nmonqnmomnmomomno");
1546
1547 // 7 CANDLE (second variety)
1548 gi.configstring(CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm");
1549
1550 // 8 CANDLE (third variety)
1551 gi.configstring(CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
1552
1553 // 9 SLOW STROBE (fourth variety)
1554 gi.configstring(CS_LIGHTS+9, "aaaaaaaazzzzzzzz");
1555
1556 // 10 FLUORESCENT FLICKER
1557 gi.configstring(CS_LIGHTS+10, "mmamammmmammamamaaamammma");
1558
1559 // 11 SLOW PULSE NOT FADE TO BLACK
1560 gi.configstring(CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
1561
1562 //JR 3/26/98
1563 //12 Wierd flashing
1564 gi.configstring(CS_LIGHTS+12, "ahsbexcbkxerswaibldcwersxa");
1565 LIGHTS =0;
1566 }
1567 else
1568 {
1569 // 0 normal
1570 gi.configstring(CS_LIGHTS+0, "a");
1571
1572 // 1 FLICKER (first variety)
1573 gi.configstring(CS_LIGHTS+1, "a");
1574
1575 // 2 SLOW STRONG PULSE
1576 gi.configstring(CS_LIGHTS+2, "a");
1577
1578 // 3 CANDLE (first variety)
1579 gi.configstring(CS_LIGHTS+3, "a");
1580
1581 // 4 FAST STROBE
1582 gi.configstring(CS_LIGHTS+4, "a");
1583
1584 // 5 GENTLE PULSE 1
1585 gi.configstring(CS_LIGHTS+5,"a");
1586
1587 // 6 FLICKER (second variety)
1588 gi.configstring(CS_LIGHTS+6, "a");
1589
1590 // 7 CANDLE (second variety)
1591 gi.configstring(CS_LIGHTS+7, "a");
1592
1593 // 8 CANDLE (third variety)
1594 gi.configstring(CS_LIGHTS+8, "a");
1595
1596 // 9 SLOW STROBE (fourth variety)
1597 gi.configstring(CS_LIGHTS+9, "a");
1598
1599 // 10 FLUORESCENT FLICKER
1600 gi.configstring(CS_LIGHTS+10, "a");
1601
1602 // 11 SLOW PULSE NOT FADE TO BLACK
1603 gi.configstring(CS_LIGHTS+11, "a");
1604
1605 //JR 3/26/98
1606 //12 Wierd flashing
1607 gi.configstring(CS_LIGHTS+12, "a");
1608 LIGHTS = 1;
1609 }
1610 }
1611 else // anything that doesn't match a command will be a chat
1612 Cmd_Say_f (ent, false, true);
1613 }
1614