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
23
ClientTeam(edict_t * ent)24 char *ClientTeam (edict_t *ent)
25 {
26 char *p;
27 static char value[512];
28
29 value[0] = 0;
30
31 if (!ent->client)
32 return value;
33
34 strcpy(value, Info_ValueForKey (ent->client->pers.userinfo, "skin"));
35 p = strchr(value, '/');
36 if (!p)
37 return value;
38
39 if ((int)(dmflags->value) & DF_MODELTEAMS)
40 {
41 *p = 0;
42 return value;
43 }
44
45 // if ((int)(dmflags->value) & DF_SKINTEAMS)
46 return ++p;
47 }
48
OnSameTeam(edict_t * ent1,edict_t * ent2)49 qboolean OnSameTeam (edict_t *ent1, edict_t *ent2)
50 {
51 char ent1Team [512];
52 char ent2Team [512];
53
54 if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
55 return false;
56
57 strcpy (ent1Team, ClientTeam (ent1));
58 strcpy (ent2Team, ClientTeam (ent2));
59
60 if (strcmp(ent1Team, ent2Team) == 0)
61 return true;
62 return false;
63 }
64
65
SelectNextItem(edict_t * ent,int itflags)66 void SelectNextItem (edict_t *ent, int itflags)
67 {
68 gclient_t *cl;
69 int i, index;
70 gitem_t *it;
71
72 cl = ent->client;
73
74 //ZOID
75 if (cl->menu) {
76 PMenu_Next(ent);
77 return;
78 } else if (cl->chase_target) {
79 ChaseNext(ent);
80 return;
81 }
82 //ZOID
83
84 // scan for the next valid one
85 for (i=1 ; i<=MAX_ITEMS ; i++)
86 {
87 index = (cl->pers.selected_item + i)%MAX_ITEMS;
88 if (!cl->pers.inventory[index])
89 continue;
90 it = &itemlist[index];
91 if (!it->use)
92 continue;
93 if (!(it->flags & itflags))
94 continue;
95
96 cl->pers.selected_item = index;
97 return;
98 }
99
100 cl->pers.selected_item = -1;
101 }
102
SelectPrevItem(edict_t * ent,int itflags)103 void SelectPrevItem (edict_t *ent, int itflags)
104 {
105 gclient_t *cl;
106 int i, index;
107 gitem_t *it;
108
109 cl = ent->client;
110
111 //ZOID
112 if (cl->menu) {
113 PMenu_Prev(ent);
114 return;
115 } else if (cl->chase_target) {
116 ChasePrev(ent);
117 return;
118 }
119 //ZOID
120
121 // scan for the next valid one
122 for (i=1 ; i<=MAX_ITEMS ; i++)
123 {
124 index = (cl->pers.selected_item + MAX_ITEMS - i)%MAX_ITEMS;
125 if (!cl->pers.inventory[index])
126 continue;
127 it = &itemlist[index];
128 if (!it->use)
129 continue;
130 if (!(it->flags & itflags))
131 continue;
132
133 cl->pers.selected_item = index;
134 return;
135 }
136
137 cl->pers.selected_item = -1;
138 }
139
ValidateSelectedItem(edict_t * ent)140 void ValidateSelectedItem (edict_t *ent)
141 {
142 gclient_t *cl;
143
144 cl = ent->client;
145
146 if (cl->pers.inventory[cl->pers.selected_item])
147 return; // valid
148
149 SelectNextItem (ent, -1);
150 }
151
152
153 //=================================================================================
154
155 /*
156 ==================
157 Cmd_Give_f
158
159 Give items to a client
160 ==================
161 */
Cmd_Give_f(edict_t * ent)162 void Cmd_Give_f (edict_t *ent)
163 {
164 char *name;
165 gitem_t *it;
166 int index;
167 int i;
168 qboolean give_all;
169 edict_t *it_ent;
170
171 if (deathmatch->value && !sv_cheats->value)
172 {
173 gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
174 return;
175 }
176
177 name = gi.args();
178
179 if (Q_stricmp(name, "all") == 0)
180 give_all = true;
181 else
182 give_all = false;
183
184 if (give_all || Q_stricmp(gi.argv(1), "health") == 0)
185 {
186 if (gi.argc() == 3)
187 ent->health = atoi(gi.argv(2));
188 else
189 ent->health = ent->max_health;
190 if (!give_all)
191 return;
192 }
193
194 if (give_all || Q_stricmp(name, "weapons") == 0)
195 {
196 for (i=0 ; i<game.num_items ; i++)
197 {
198 it = itemlist + i;
199 if (!it->pickup)
200 continue;
201 if (!(it->flags & IT_WEAPON))
202 continue;
203 ent->client->pers.inventory[i] += 1;
204 }
205 if (!give_all)
206 return;
207 }
208
209 if (give_all || Q_stricmp(name, "ammo") == 0)
210 {
211 for (i=0 ; i<game.num_items ; i++)
212 {
213 it = itemlist + i;
214 if (!it->pickup)
215 continue;
216 if (!(it->flags & IT_AMMO))
217 continue;
218 Add_Ammo (ent, it, 1000);
219 }
220 if (!give_all)
221 return;
222 }
223
224 if (give_all || Q_stricmp(name, "armor") == 0)
225 {
226 gitem_armor_t *info;
227
228 it = FindItem("Jacket Armor");
229 ent->client->pers.inventory[ITEM_INDEX(it)] = 0;
230
231 it = FindItem("Combat Armor");
232 ent->client->pers.inventory[ITEM_INDEX(it)] = 0;
233
234 it = FindItem("Body Armor");
235 info = (gitem_armor_t *)it->info;
236 ent->client->pers.inventory[ITEM_INDEX(it)] = info->max_count;
237
238 if (!give_all)
239 return;
240 }
241
242 if (give_all || Q_stricmp(name, "Power Shield") == 0)
243 {
244 it = FindItem("Power Shield");
245 it_ent = G_Spawn();
246 it_ent->classname = it->classname;
247 SpawnItem (it_ent, it);
248 Touch_Item (it_ent, ent, NULL, NULL);
249 if (it_ent->inuse)
250 G_FreeEdict(it_ent);
251
252 if (!give_all)
253 return;
254 }
255
256 if (give_all)
257 {
258 for (i=0 ; i<game.num_items ; i++)
259 {
260 it = itemlist + i;
261 if (!it->pickup)
262 continue;
263 if (it->flags & (IT_ARMOR|IT_WEAPON|IT_AMMO))
264 continue;
265 ent->client->pers.inventory[i] = 1;
266 }
267 return;
268 }
269
270 it = FindItem (name);
271 if (!it)
272 {
273 name = gi.argv(1);
274 it = FindItem (name);
275 if (!it)
276 {
277 gi.cprintf (ent, PRINT_HIGH, "unknown item\n");
278 return;
279 }
280 }
281
282 if (!it->pickup)
283 {
284 gi.cprintf (ent, PRINT_HIGH, "non-pickup item\n");
285 return;
286 }
287
288 index = ITEM_INDEX(it);
289
290 if (it->flags & IT_AMMO)
291 {
292 if (gi.argc() == 3)
293 ent->client->pers.inventory[index] = atoi(gi.argv(2));
294 else
295 ent->client->pers.inventory[index] += it->quantity;
296 }
297 else
298 {
299 it_ent = G_Spawn();
300 it_ent->classname = it->classname;
301 SpawnItem (it_ent, it);
302 Touch_Item (it_ent, ent, NULL, NULL);
303 if (it_ent->inuse)
304 G_FreeEdict(it_ent);
305 }
306 }
307
308
309 /*
310 ==================
311 Cmd_God_f
312
313 Sets client to godmode
314
315 argv(0) god
316 ==================
317 */
Cmd_God_f(edict_t * ent)318 void Cmd_God_f (edict_t *ent)
319 {
320 char *msg;
321
322 if (deathmatch->value && !sv_cheats->value)
323 {
324 gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
325 return;
326 }
327
328 ent->flags ^= FL_GODMODE;
329 if (!(ent->flags & FL_GODMODE) )
330 msg = "godmode OFF\n";
331 else
332 msg = "godmode ON\n";
333
334 gi.cprintf (ent, PRINT_HIGH, msg);
335 }
336
337
338 /*
339 ==================
340 Cmd_Notarget_f
341
342 Sets client to notarget
343
344 argv(0) notarget
345 ==================
346 */
Cmd_Notarget_f(edict_t * ent)347 void Cmd_Notarget_f (edict_t *ent)
348 {
349 char *msg;
350
351 if (deathmatch->value && !sv_cheats->value)
352 {
353 gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
354 return;
355 }
356
357 ent->flags ^= FL_NOTARGET;
358 if (!(ent->flags & FL_NOTARGET) )
359 msg = "notarget OFF\n";
360 else
361 msg = "notarget ON\n";
362
363 gi.cprintf (ent, PRINT_HIGH, msg);
364 }
365
366
367 /*
368 ==================
369 Cmd_Noclip_f
370
371 argv(0) noclip
372 ==================
373 */
Cmd_Noclip_f(edict_t * ent)374 void Cmd_Noclip_f (edict_t *ent)
375 {
376 char *msg;
377
378 if (deathmatch->value && !sv_cheats->value)
379 {
380 gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
381 return;
382 }
383
384 if (ent->movetype == MOVETYPE_NOCLIP)
385 {
386 ent->movetype = MOVETYPE_WALK;
387 msg = "noclip OFF\n";
388 }
389 else
390 {
391 ent->movetype = MOVETYPE_NOCLIP;
392 msg = "noclip ON\n";
393 }
394
395 gi.cprintf (ent, PRINT_HIGH, msg);
396 }
397
398
399 /*
400 ==================
401 Cmd_Use_f
402
403 Use an inventory item
404 ==================
405 */
Cmd_Use_f(edict_t * ent)406 void Cmd_Use_f (edict_t *ent)
407 {
408 int index;
409 gitem_t *it;
410 char *s;
411
412 s = gi.args();
413 it = FindItem (s);
414 if (!it)
415 {
416 gi.cprintf (ent, PRINT_HIGH, "unknown item: %s\n", s);
417 return;
418 }
419 if (!it->use)
420 {
421 gi.cprintf (ent, PRINT_HIGH, "Item is not usable.\n");
422 return;
423 }
424 index = ITEM_INDEX(it);
425 if (!ent->client->pers.inventory[index])
426 {
427 gi.cprintf (ent, PRINT_HIGH, "Out of item: %s\n", s);
428 return;
429 }
430
431 it->use (ent, it);
432 }
433
434
435 /*
436 ==================
437 Cmd_Drop_f
438
439 Drop an inventory item
440 ==================
441 */
Cmd_Drop_f(edict_t * ent)442 void Cmd_Drop_f (edict_t *ent)
443 {
444 int index;
445 gitem_t *it;
446 char *s;
447
448 //ZOID--special case for tech powerups
449 if (Q_stricmp(gi.args(), "tech") == 0 && (it = CTFWhat_Tech(ent)) != NULL) {
450 it->drop (ent, it);
451 return;
452 }
453 //ZOID
454
455 s = gi.args();
456 it = FindItem (s);
457 if (!it)
458 {
459 gi.cprintf (ent, PRINT_HIGH, "unknown item: %s\n", s);
460 return;
461 }
462 if (!it->drop)
463 {
464 gi.cprintf (ent, PRINT_HIGH, "Item is not dropable.\n");
465 return;
466 }
467 index = ITEM_INDEX(it);
468 if (!ent->client->pers.inventory[index])
469 {
470 gi.cprintf (ent, PRINT_HIGH, "Out of item: %s\n", s);
471 return;
472 }
473
474 it->drop (ent, it);
475 }
476
477
478 /*
479 =================
480 Cmd_Inven_f
481 =================
482 */
Cmd_Inven_f(edict_t * ent)483 void Cmd_Inven_f (edict_t *ent)
484 {
485 int i;
486 gclient_t *cl;
487
488 cl = ent->client;
489
490 cl->showscores = false;
491 cl->showhelp = false;
492
493 //ZOID
494 if (ent->client->menu) {
495 PMenu_Close(ent);
496 ent->client->update_chase = true;
497 return;
498 }
499 //ZOID
500
501 if (cl->showinventory)
502 {
503 cl->showinventory = false;
504 return;
505 }
506
507 //ZOID
508 if (ctf->value && cl->resp.ctf_team == CTF_NOTEAM) {
509 CTFOpenJoinMenu(ent);
510 return;
511 }
512 //ZOID
513
514 cl->showinventory = true;
515
516 gi.WriteByte (svc_inventory);
517 for (i=0 ; i<MAX_ITEMS ; i++)
518 {
519 gi.WriteShort (cl->pers.inventory[i]);
520 }
521 gi.unicast (ent, true);
522 }
523
524 /*
525 =================
526 Cmd_InvUse_f
527 =================
528 */
Cmd_InvUse_f(edict_t * ent)529 void Cmd_InvUse_f (edict_t *ent)
530 {
531 gitem_t *it;
532
533 //ZOID
534 if (ent->client->menu) {
535 PMenu_Select(ent);
536 return;
537 }
538 //ZOID
539
540 ValidateSelectedItem (ent);
541
542 if (ent->client->pers.selected_item == -1)
543 {
544 gi.cprintf (ent, PRINT_HIGH, "No item to use.\n");
545 return;
546 }
547
548 it = &itemlist[ent->client->pers.selected_item];
549 if (!it->use)
550 {
551 gi.cprintf (ent, PRINT_HIGH, "Item is not usable.\n");
552 return;
553 }
554 it->use (ent, it);
555 }
556
557 //ZOID
558 /*
559 =================
560 Cmd_LastWeap_f
561 =================
562 */
Cmd_LastWeap_f(edict_t * ent)563 void Cmd_LastWeap_f (edict_t *ent)
564 {
565 gclient_t *cl;
566
567 cl = ent->client;
568
569 if (!cl->pers.weapon || !cl->pers.lastweapon)
570 return;
571
572 cl->pers.lastweapon->use (ent, cl->pers.lastweapon);
573 }
574 //ZOID
575
576 /*
577 =================
578 Cmd_WeapPrev_f
579 =================
580 */
Cmd_WeapPrev_f(edict_t * ent)581 void Cmd_WeapPrev_f (edict_t *ent)
582 {
583 gclient_t *cl;
584 int i, index;
585 gitem_t *it;
586 int selected_weapon;
587
588 cl = ent->client;
589
590 if (!cl->pers.weapon)
591 return;
592
593 selected_weapon = ITEM_INDEX(cl->pers.weapon);
594
595 // scan for the next valid one
596 for (i=1 ; i<=MAX_ITEMS ; i++)
597 {
598 index = (selected_weapon + i)%MAX_ITEMS;
599 if (!cl->pers.inventory[index])
600 continue;
601 it = &itemlist[index];
602 if (!it->use)
603 continue;
604 if (! (it->flags & IT_WEAPON) )
605 continue;
606 it->use (ent, it);
607 if (cl->pers.weapon == it)
608 return; // successful
609 }
610 }
611
612 /*
613 =================
614 Cmd_WeapNext_f
615 =================
616 */
Cmd_WeapNext_f(edict_t * ent)617 void Cmd_WeapNext_f (edict_t *ent)
618 {
619 gclient_t *cl;
620 int i, index;
621 gitem_t *it;
622 int selected_weapon;
623
624 cl = ent->client;
625
626 if (!cl->pers.weapon)
627 return;
628
629 selected_weapon = ITEM_INDEX(cl->pers.weapon);
630
631 // scan for the next valid one
632 for (i=1 ; i<=MAX_ITEMS ; i++)
633 {
634 index = (selected_weapon + MAX_ITEMS - i)%MAX_ITEMS;
635 if (!cl->pers.inventory[index])
636 continue;
637 it = &itemlist[index];
638 if (!it->use)
639 continue;
640 if (! (it->flags & IT_WEAPON) )
641 continue;
642 it->use (ent, it);
643 if (cl->pers.weapon == it)
644 return; // successful
645 }
646 }
647
648 /*
649 =================
650 Cmd_WeapLast_f
651 =================
652 */
Cmd_WeapLast_f(edict_t * ent)653 void Cmd_WeapLast_f (edict_t *ent)
654 {
655 gclient_t *cl;
656 int index;
657 gitem_t *it;
658
659 cl = ent->client;
660
661 if (!cl->pers.weapon || !cl->pers.lastweapon)
662 return;
663
664 index = ITEM_INDEX(cl->pers.lastweapon);
665 if (!cl->pers.inventory[index])
666 return;
667 it = &itemlist[index];
668 if (!it->use)
669 return;
670 if (! (it->flags & IT_WEAPON) )
671 return;
672 it->use (ent, it);
673 }
674
675 /*
676 =================
677 Cmd_InvDrop_f
678 =================
679 */
Cmd_InvDrop_f(edict_t * ent)680 void Cmd_InvDrop_f (edict_t *ent)
681 {
682 gitem_t *it;
683
684 ValidateSelectedItem (ent);
685
686 if (ent->client->pers.selected_item == -1)
687 {
688 gi.cprintf (ent, PRINT_HIGH, "No item to drop.\n");
689 return;
690 }
691
692 it = &itemlist[ent->client->pers.selected_item];
693 if (!it->drop)
694 {
695 gi.cprintf (ent, PRINT_HIGH, "Item is not dropable.\n");
696 return;
697 }
698 it->drop (ent, it);
699 }
700
701 /*
702 =================
703 Cmd_Kill_f
704 =================
705 */
Cmd_Kill_f(edict_t * ent)706 void Cmd_Kill_f (edict_t *ent)
707 {
708 //ZOID
709 if (ent->solid == SOLID_NOT)
710 return;
711 //ZOID
712
713 if((level.time - ent->client->respawn_time) < 5)
714 return;
715 ent->flags &= ~FL_GODMODE;
716 ent->health = 0;
717 meansOfDeath = MOD_SUICIDE;
718 player_die (ent, ent, ent, 100000, vec3_origin);
719 }
720
721 /*
722 =================
723 Cmd_PutAway_f
724 =================
725 */
Cmd_PutAway_f(edict_t * ent)726 void Cmd_PutAway_f (edict_t *ent)
727 {
728 ent->client->showscores = false;
729 ent->client->showhelp = false;
730 ent->client->showinventory = false;
731 //ZOID
732 if (ent->client->menu)
733 PMenu_Close(ent);
734 ent->client->update_chase = true;
735 //ZOID
736 }
737
738
PlayerSort(void const * a,void const * b)739 int PlayerSort (void const *a, void const *b)
740 {
741 int anum, bnum;
742
743 anum = *(int *)a;
744 bnum = *(int *)b;
745
746 anum = game.clients[anum].ps.stats[STAT_FRAGS];
747 bnum = game.clients[bnum].ps.stats[STAT_FRAGS];
748
749 if (anum < bnum)
750 return -1;
751 if (anum > bnum)
752 return 1;
753 return 0;
754 }
755
756 /*
757 =================
758 Cmd_Players_f
759 =================
760 */
Cmd_Players_f(edict_t * ent)761 void Cmd_Players_f (edict_t *ent)
762 {
763 int i;
764 int count;
765 char small[64];
766 char large[1280];
767 int index[256];
768
769 count = 0;
770 for (i = 0 ; i < maxclients->value ; i++)
771 if (game.clients[i].pers.connected)
772 {
773 index[count] = i;
774 count++;
775 }
776
777 // sort by frags
778 qsort (index, count, sizeof(index[0]), PlayerSort);
779
780 // print information
781 large[0] = 0;
782
783 for (i = 0 ; i < count ; i++)
784 {
785 Com_sprintf (small, sizeof(small), "%3i %s\n",
786 game.clients[index[i]].ps.stats[STAT_FRAGS],
787 game.clients[index[i]].pers.netname);
788 if (strlen (small) + strlen(large) > sizeof(large) - 100 )
789 { // can't print all of them in one packet
790 strcat (large, "...\n");
791 break;
792 }
793 strcat (large, small);
794 }
795
796 gi.cprintf (ent, PRINT_HIGH, "%s\n%i players\n", large, count);
797 }
798
799 /*
800 =================
801 Cmd_Wave_f
802 =================
803 */
Cmd_Wave_f(edict_t * ent)804 void Cmd_Wave_f (edict_t *ent)
805 {
806 int i;
807
808 i = atoi (gi.argv(1));
809
810 // can't wave when ducked
811 if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
812 return;
813
814 if (ent->client->anim_priority > ANIM_WAVE)
815 return;
816
817 ent->client->anim_priority = ANIM_WAVE;
818
819 switch (i)
820 {
821 case 0:
822 gi.cprintf (ent, PRINT_HIGH, "flipoff\n");
823 ent->s.frame = FRAME_flip01-1;
824 ent->client->anim_end = FRAME_flip12;
825 break;
826 case 1:
827 gi.cprintf (ent, PRINT_HIGH, "salute\n");
828 ent->s.frame = FRAME_salute01-1;
829 ent->client->anim_end = FRAME_salute11;
830 break;
831 case 2:
832 gi.cprintf (ent, PRINT_HIGH, "taunt\n");
833 ent->s.frame = FRAME_taunt01-1;
834 ent->client->anim_end = FRAME_taunt17;
835 break;
836 case 3:
837 gi.cprintf (ent, PRINT_HIGH, "wave\n");
838 ent->s.frame = FRAME_wave01-1;
839 ent->client->anim_end = FRAME_wave11;
840 break;
841 case 4:
842 default:
843 gi.cprintf (ent, PRINT_HIGH, "point\n");
844 ent->s.frame = FRAME_point01-1;
845 ent->client->anim_end = FRAME_point12;
846 break;
847 }
848 }
849
CheckFlood(edict_t * ent)850 qboolean CheckFlood(edict_t *ent)
851 {
852 int i;
853 gclient_t *cl;
854
855 if (flood_msgs->value) {
856 cl = ent->client;
857
858 if (level.time < cl->flood_locktill) {
859 gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n",
860 (int)(cl->flood_locktill - level.time));
861 return true;
862 }
863 i = cl->flood_whenhead - flood_msgs->value + 1;
864 if (i < 0)
865 i = (sizeof(cl->flood_when)/sizeof(cl->flood_when[0])) + i;
866 if (cl->flood_when[i] &&
867 level.time - cl->flood_when[i] < flood_persecond->value) {
868 cl->flood_locktill = level.time + flood_waitdelay->value;
869 gi.cprintf(ent, PRINT_CHAT, "Flood protection: You can't talk for %d seconds.\n",
870 (int)flood_waitdelay->value);
871 return true;
872 }
873 cl->flood_whenhead = (cl->flood_whenhead + 1) %
874 (sizeof(cl->flood_when)/sizeof(cl->flood_when[0]));
875 cl->flood_when[cl->flood_whenhead] = level.time;
876 }
877 return false;
878 }
879
880 /*
881 ==================
882 Cmd_Say_f
883 ==================
884 */
Cmd_Say_f(edict_t * ent,qboolean team,qboolean arg0)885 void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
886 {
887 int j;
888 edict_t *other;
889 char *p;
890 char text[2048];
891
892 if (gi.argc () < 2 && !arg0)
893 return;
894
895 if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
896 team = false;
897
898 if (team)
899 Com_sprintf (text, sizeof(text), "(%s): ", ent->client->pers.netname);
900 else
901 Com_sprintf (text, sizeof(text), "%s: ", ent->client->pers.netname);
902
903 if (arg0)
904 {
905 strcat (text, gi.argv(0));
906 strcat (text, " ");
907 strcat (text, gi.args());
908 }
909 else
910 {
911 p = gi.args();
912
913 if (*p == '"')
914 {
915 p++;
916 p[strlen(p)-1] = 0;
917 }
918 strcat(text, p);
919 }
920
921 // don't let text be too long for malicious reasons
922 if (strlen(text) > 150)
923 text[150] = 0;
924
925 strcat(text, "\n");
926
927 if (CheckFlood(ent))
928 return;
929
930 if (dedicated->value)
931 gi.cprintf(NULL, PRINT_CHAT, "%s", text);
932
933 for (j = 1; j <= game.maxclients; j++)
934 {
935 other = &g_edicts[j];
936 if (!other->inuse)
937 continue;
938 if (!other->client)
939 continue;
940 if (team)
941 {
942 if (!OnSameTeam(ent, other))
943 continue;
944 }
945 gi.cprintf(other, PRINT_CHAT, "%s", text);
946 }
947 }
948
949 /*
950 =================
951 ClientCommand
952 =================
953 */
ClientCommand(edict_t * ent)954 void ClientCommand (edict_t *ent)
955 {
956 char *cmd;
957
958 if (!ent->client)
959 return; // not fully in game yet
960
961 cmd = gi.argv(0);
962
963 if (Q_stricmp (cmd, "players") == 0)
964 {
965 Cmd_Players_f (ent);
966 return;
967 }
968 if (Q_stricmp (cmd, "say") == 0)
969 {
970 Cmd_Say_f (ent, false, false);
971 return;
972 }
973 if (Q_stricmp (cmd, "say_team") == 0 || Q_stricmp (cmd, "steam") == 0)
974 {
975 CTFSay_Team(ent, gi.args());
976 return;
977 }
978 if (Q_stricmp (cmd, "score") == 0)
979 {
980 Cmd_Score_f (ent);
981 return;
982 }
983 if (Q_stricmp (cmd, "help") == 0)
984 {
985 Cmd_Help_f (ent);
986 return;
987 }
988
989 if (level.intermissiontime)
990 return;
991
992 if (Q_stricmp (cmd, "use") == 0)
993 Cmd_Use_f (ent);
994 else if (Q_stricmp (cmd, "drop") == 0)
995 Cmd_Drop_f (ent);
996 else if (Q_stricmp (cmd, "give") == 0)
997 Cmd_Give_f (ent);
998 else if (Q_stricmp (cmd, "god") == 0)
999 Cmd_God_f (ent);
1000 else if (Q_stricmp (cmd, "notarget") == 0)
1001 Cmd_Notarget_f (ent);
1002 else if (Q_stricmp (cmd, "noclip") == 0)
1003 Cmd_Noclip_f (ent);
1004 else if (Q_stricmp (cmd, "inven") == 0)
1005 Cmd_Inven_f (ent);
1006 else if (Q_stricmp (cmd, "invnext") == 0)
1007 SelectNextItem (ent, -1);
1008 else if (Q_stricmp (cmd, "invprev") == 0)
1009 SelectPrevItem (ent, -1);
1010 else if (Q_stricmp (cmd, "invnextw") == 0)
1011 SelectNextItem (ent, IT_WEAPON);
1012 else if (Q_stricmp (cmd, "invprevw") == 0)
1013 SelectPrevItem (ent, IT_WEAPON);
1014 else if (Q_stricmp (cmd, "invnextp") == 0)
1015 SelectNextItem (ent, IT_POWERUP);
1016 else if (Q_stricmp (cmd, "invprevp") == 0)
1017 SelectPrevItem (ent, IT_POWERUP);
1018 else if (Q_stricmp (cmd, "invuse") == 0)
1019 Cmd_InvUse_f (ent);
1020 else if (Q_stricmp (cmd, "invdrop") == 0)
1021 Cmd_InvDrop_f (ent);
1022 else if (Q_stricmp (cmd, "weapprev") == 0)
1023 Cmd_WeapPrev_f (ent);
1024 else if (Q_stricmp (cmd, "weapnext") == 0)
1025 Cmd_WeapNext_f (ent);
1026 else if (Q_stricmp (cmd, "weaplast") == 0)
1027 Cmd_WeapLast_f (ent);
1028 else if (Q_stricmp (cmd, "kill") == 0)
1029 Cmd_Kill_f (ent);
1030 else if (Q_stricmp (cmd, "putaway") == 0)
1031 Cmd_PutAway_f (ent);
1032 else if (Q_stricmp (cmd, "wave") == 0)
1033 Cmd_Wave_f (ent);
1034 //ZOID
1035 else if (Q_stricmp (cmd, "team") == 0)
1036 {
1037 CTFTeam_f (ent);
1038 } else if (Q_stricmp(cmd, "id") == 0) {
1039 CTFID_f (ent);
1040 } else if (Q_stricmp(cmd, "yes") == 0) {
1041 CTFVoteYes(ent);
1042 } else if (Q_stricmp(cmd, "no") == 0) {
1043 CTFVoteNo(ent);
1044 } else if (Q_stricmp(cmd, "ready") == 0) {
1045 CTFReady(ent);
1046 } else if (Q_stricmp(cmd, "notready") == 0) {
1047 CTFNotReady(ent);
1048 } else if (Q_stricmp(cmd, "ghost") == 0) {
1049 CTFGhost(ent);
1050 } else if (Q_stricmp(cmd, "admin") == 0) {
1051 CTFAdmin(ent);
1052 } else if (Q_stricmp(cmd, "stats") == 0) {
1053 CTFStats(ent);
1054 } else if (Q_stricmp(cmd, "warp") == 0) {
1055 CTFWarp(ent);
1056 } else if (Q_stricmp(cmd, "boot") == 0) {
1057 CTFBoot(ent);
1058 } else if (Q_stricmp(cmd, "playerlist") == 0) {
1059 CTFPlayerList(ent);
1060 } else if (Q_stricmp(cmd, "observer") == 0) {
1061 CTFObserver(ent);
1062 }
1063 //ZOID
1064 else // anything that doesn't match a command will be a chat
1065 Cmd_Say_f (ent, false, true);
1066 }
1067