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