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