00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "g_local.h"
00024
00025 #include "../../ui/menudef.h"
00026
00027
00028
00029
00030
00031
00032
00033 void DeathmatchScoreboardMessage( gentity_t *ent ) {
00034 char entry[1024];
00035 char string[1400];
00036 int stringlength;
00037 int i, j;
00038 gclient_t *cl;
00039 int numSorted, scoreFlags, accuracy, perfect;
00040
00041
00042 string[0] = 0;
00043 stringlength = 0;
00044 scoreFlags = 0;
00045
00046 numSorted = level.numConnectedClients;
00047
00048 for (i=0 ; i < numSorted ; i++) {
00049 int ping;
00050
00051 cl = &level.clients[level.sortedClients[i]];
00052
00053 if ( cl->pers.connected == CON_CONNECTING ) {
00054 ping = -1;
00055 } else {
00056 ping = cl->ps.ping < 999 ? cl->ps.ping : 999;
00057 }
00058
00059 if( cl->accuracy_shots ) {
00060 accuracy = cl->accuracy_hits * 100 / cl->accuracy_shots;
00061 }
00062 else {
00063 accuracy = 0;
00064 }
00065 perfect = ( cl->ps.persistant[PERS_RANK] == 0 && cl->ps.persistant[PERS_KILLED] == 0 ) ? 1 : 0;
00066
00067 Com_sprintf (entry, sizeof(entry),
00068 " %i %i %i %i %i %i %i %i %i %i %i %i %i %i", level.sortedClients[i],
00069 cl->ps.persistant[PERS_SCORE], ping, (level.time - cl->pers.enterTime)/60000,
00070 scoreFlags, g_entities[level.sortedClients[i]].s.powerups, accuracy,
00071 cl->ps.persistant[PERS_IMPRESSIVE_COUNT],
00072 cl->ps.persistant[PERS_EXCELLENT_COUNT],
00073 cl->ps.persistant[PERS_GAUNTLET_FRAG_COUNT],
00074 cl->ps.persistant[PERS_DEFEND_COUNT],
00075 cl->ps.persistant[PERS_ASSIST_COUNT],
00076 perfect,
00077 cl->ps.persistant[PERS_CAPTURES]);
00078 j = strlen(entry);
00079 if (stringlength + j > 1024)
00080 break;
00081 strcpy (string + stringlength, entry);
00082 stringlength += j;
00083 }
00084
00085 trap_SendServerCommand( ent-g_entities, va("scores %i %i %i%s", i,
00086 level.teamScores[TEAM_RED], level.teamScores[TEAM_BLUE],
00087 string ) );
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 void Cmd_Score_f( gentity_t *ent ) {
00099 DeathmatchScoreboardMessage( ent );
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 qboolean CheatsOk( gentity_t *ent ) {
00110 if ( !g_cheats.integer ) {
00111 trap_SendServerCommand( ent-g_entities, va("print \"Cheats are not enabled on this server.\n\""));
00112 return qfalse;
00113 }
00114 if ( ent->health <= 0 ) {
00115 trap_SendServerCommand( ent-g_entities, va("print \"You must be alive to use this command.\n\""));
00116 return qfalse;
00117 }
00118 return qtrue;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 char *ConcatArgs( int start ) {
00128 int i, c, tlen;
00129 static char line[MAX_STRING_CHARS];
00130 int len;
00131 char arg[MAX_STRING_CHARS];
00132
00133 len = 0;
00134 c = trap_Argc();
00135 for ( i = start ; i < c ; i++ ) {
00136 trap_Argv( i, arg, sizeof( arg ) );
00137 tlen = strlen( arg );
00138 if ( len + tlen >= MAX_STRING_CHARS - 1 ) {
00139 break;
00140 }
00141 memcpy( line + len, arg, tlen );
00142 len += tlen;
00143 if ( i != c - 1 ) {
00144 line[len] = ' ';
00145 len++;
00146 }
00147 }
00148
00149 line[len] = 0;
00150
00151 return line;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 void SanitizeString( char *in, char *out ) {
00162 while ( *in ) {
00163 if ( *in == 27 ) {
00164 in += 2;
00165 continue;
00166 }
00167 if ( *in < 32 ) {
00168 in++;
00169 continue;
00170 }
00171 *out++ = tolower( *in++ );
00172 }
00173
00174 *out = 0;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 int ClientNumberFromString( gentity_t *to, char *s ) {
00186 gclient_t *cl;
00187 int idnum;
00188 char s2[MAX_STRING_CHARS];
00189 char n2[MAX_STRING_CHARS];
00190
00191
00192 if (s[0] >= '0' && s[0] <= '9') {
00193 idnum = atoi( s );
00194 if ( idnum < 0 || idnum >= level.maxclients ) {
00195 trap_SendServerCommand( to-g_entities, va("print \"Bad client slot: %i\n\"", idnum));
00196 return -1;
00197 }
00198
00199 cl = &level.clients[idnum];
00200 if ( cl->pers.connected != CON_CONNECTED ) {
00201 trap_SendServerCommand( to-g_entities, va("print \"Client %i is not active\n\"", idnum));
00202 return -1;
00203 }
00204 return idnum;
00205 }
00206
00207
00208 SanitizeString( s, s2 );
00209 for ( idnum=0,cl=level.clients ; idnum < level.maxclients ; idnum++,cl++ ) {
00210 if ( cl->pers.connected != CON_CONNECTED ) {
00211 continue;
00212 }
00213 SanitizeString( cl->pers.netname, n2 );
00214 if ( !strcmp( n2, s2 ) ) {
00215 return idnum;
00216 }
00217 }
00218
00219 trap_SendServerCommand( to-g_entities, va("print \"User %s is not on the server\n\"", s));
00220 return -1;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 void Cmd_Give_f (gentity_t *ent)
00231 {
00232 char *name;
00233 gitem_t *it;
00234 int i;
00235 qboolean give_all;
00236 gentity_t *it_ent;
00237 trace_t trace;
00238
00239 if ( !CheatsOk( ent ) ) {
00240 return;
00241 }
00242
00243 name = ConcatArgs( 1 );
00244
00245 if (Q_stricmp(name, "all") == 0)
00246 give_all = qtrue;
00247 else
00248 give_all = qfalse;
00249
00250 if (give_all || Q_stricmp( name, "health") == 0)
00251 {
00252 ent->health = ent->client->ps.stats[STAT_MAX_HEALTH];
00253 if (!give_all)
00254 return;
00255 }
00256
00257 if (give_all || Q_stricmp(name, "weapons") == 0)
00258 {
00259 ent->client->ps.stats[STAT_WEAPONS] = (1 << WP_NUM_WEAPONS) - 1 -
00260 ( 1 << WP_GRAPPLING_HOOK ) - ( 1 << WP_NONE );
00261 if (!give_all)
00262 return;
00263 }
00264
00265 if (give_all || Q_stricmp(name, "ammo") == 0)
00266 {
00267 for ( i = 0 ; i < MAX_WEAPONS ; i++ ) {
00268 ent->client->ps.ammo[i] = 999;
00269 }
00270 if (!give_all)
00271 return;
00272 }
00273
00274 if (give_all || Q_stricmp(name, "armor") == 0)
00275 {
00276 ent->client->ps.stats[STAT_ARMOR] = 200;
00277
00278 if (!give_all)
00279 return;
00280 }
00281
00282 if (Q_stricmp(name, "excellent") == 0) {
00283 ent->client->ps.persistant[PERS_EXCELLENT_COUNT]++;
00284 return;
00285 }
00286 if (Q_stricmp(name, "impressive") == 0) {
00287 ent->client->ps.persistant[PERS_IMPRESSIVE_COUNT]++;
00288 return;
00289 }
00290 if (Q_stricmp(name, "gauntletaward") == 0) {
00291 ent->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT]++;
00292 return;
00293 }
00294 if (Q_stricmp(name, "defend") == 0) {
00295 ent->client->ps.persistant[PERS_DEFEND_COUNT]++;
00296 return;
00297 }
00298 if (Q_stricmp(name, "assist") == 0) {
00299 ent->client->ps.persistant[PERS_ASSIST_COUNT]++;
00300 return;
00301 }
00302
00303
00304 if ( !give_all ) {
00305 it = BG_FindItem (name);
00306 if (!it) {
00307 return;
00308 }
00309
00310 it_ent = G_Spawn();
00311 VectorCopy( ent->r.currentOrigin, it_ent->s.origin );
00312 it_ent->classname = it->classname;
00313 G_SpawnItem (it_ent, it);
00314 FinishSpawningItem(it_ent );
00315 memset( &trace, 0, sizeof( trace ) );
00316 Touch_Item (it_ent, ent, &trace);
00317 if (it_ent->inuse) {
00318 G_FreeEntity( it_ent );
00319 }
00320 }
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 void Cmd_God_f (gentity_t *ent)
00334 {
00335 char *msg;
00336
00337 if ( !CheatsOk( ent ) ) {
00338 return;
00339 }
00340
00341 ent->flags ^= FL_GODMODE;
00342 if (!(ent->flags & FL_GODMODE) )
00343 msg = "godmode OFF\n";
00344 else
00345 msg = "godmode ON\n";
00346
00347 trap_SendServerCommand( ent-g_entities, va("print \"%s\"", msg));
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 void Cmd_Notarget_f( gentity_t *ent ) {
00361 char *msg;
00362
00363 if ( !CheatsOk( ent ) ) {
00364 return;
00365 }
00366
00367 ent->flags ^= FL_NOTARGET;
00368 if (!(ent->flags & FL_NOTARGET) )
00369 msg = "notarget OFF\n";
00370 else
00371 msg = "notarget ON\n";
00372
00373 trap_SendServerCommand( ent-g_entities, va("print \"%s\"", msg));
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 void Cmd_Noclip_f( gentity_t *ent ) {
00385 char *msg;
00386
00387 if ( !CheatsOk( ent ) ) {
00388 return;
00389 }
00390
00391 if ( ent->client->noclip ) {
00392 msg = "noclip OFF\n";
00393 } else {
00394 msg = "noclip ON\n";
00395 }
00396 ent->client->noclip = !ent->client->noclip;
00397
00398 trap_SendServerCommand( ent-g_entities, va("print \"%s\"", msg));
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 void Cmd_LevelShot_f( gentity_t *ent ) {
00413 if ( !CheatsOk( ent ) ) {
00414 return;
00415 }
00416
00417
00418 if ( g_gametype.integer != 0 ) {
00419 trap_SendServerCommand( ent-g_entities,
00420 "print \"Must be in g_gametype 0 for levelshot\n\"" );
00421 return;
00422 }
00423
00424 BeginIntermission();
00425 trap_SendServerCommand( ent-g_entities, "clientLevelShot" );
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 void Cmd_TeamTask_f( gentity_t *ent ) {
00440 char userinfo[MAX_INFO_STRING];
00441 char arg[MAX_TOKEN_CHARS];
00442 int task;
00443 int client = ent->client - level.clients;
00444
00445 if ( trap_Argc() != 2 ) {
00446 return;
00447 }
00448 trap_Argv( 1, arg, sizeof( arg ) );
00449 task = atoi( arg );
00450
00451 trap_GetUserinfo(client, userinfo, sizeof(userinfo));
00452 Info_SetValueForKey(userinfo, "teamtask", va("%d", task));
00453 trap_SetUserinfo(client, userinfo);
00454 ClientUserinfoChanged(client);
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464 void Cmd_Kill_f( gentity_t *ent ) {
00465 if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
00466 return;
00467 }
00468 if (ent->health <= 0) {
00469 return;
00470 }
00471 ent->flags &= ~FL_GODMODE;
00472 ent->client->ps.stats[STAT_HEALTH] = ent->health = -999;
00473 player_die (ent, ent, ent, 100000, MOD_SUICIDE);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483 void BroadcastTeamChange( gclient_t *client, int oldTeam )
00484 {
00485 if ( client->sess.sessionTeam == TEAM_RED ) {
00486 trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the red team.\n\"",
00487 client->pers.netname) );
00488 } else if ( client->sess.sessionTeam == TEAM_BLUE ) {
00489 trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the blue team.\n\"",
00490 client->pers.netname));
00491 } else if ( client->sess.sessionTeam == TEAM_SPECTATOR && oldTeam != TEAM_SPECTATOR ) {
00492 trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the spectators.\n\"",
00493 client->pers.netname));
00494 } else if ( client->sess.sessionTeam == TEAM_FREE ) {
00495 trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the battle.\n\"",
00496 client->pers.netname));
00497 }
00498 }
00499
00500
00501
00502
00503
00504
00505 void SetTeam( gentity_t *ent, char *s ) {
00506 int team, oldTeam;
00507 gclient_t *client;
00508 int clientNum;
00509 spectatorState_t specState;
00510 int specClient;
00511 int teamLeader;
00512
00513
00514
00515
00516 client = ent->client;
00517
00518 clientNum = client - level.clients;
00519 specClient = 0;
00520 specState = SPECTATOR_NOT;
00521 if ( !Q_stricmp( s, "scoreboard" ) || !Q_stricmp( s, "score" ) ) {
00522 team = TEAM_SPECTATOR;
00523 specState = SPECTATOR_SCOREBOARD;
00524 } else if ( !Q_stricmp( s, "follow1" ) ) {
00525 team = TEAM_SPECTATOR;
00526 specState = SPECTATOR_FOLLOW;
00527 specClient = -1;
00528 } else if ( !Q_stricmp( s, "follow2" ) ) {
00529 team = TEAM_SPECTATOR;
00530 specState = SPECTATOR_FOLLOW;
00531 specClient = -2;
00532 } else if ( !Q_stricmp( s, "spectator" ) || !Q_stricmp( s, "s" ) ) {
00533 team = TEAM_SPECTATOR;
00534 specState = SPECTATOR_FREE;
00535 } else if ( g_gametype.integer >= GT_TEAM ) {
00536
00537 specState = SPECTATOR_NOT;
00538 if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) ) {
00539 team = TEAM_RED;
00540 } else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) ) {
00541 team = TEAM_BLUE;
00542 } else {
00543
00544 team = PickTeam( clientNum );
00545 }
00546
00547 if ( g_teamForceBalance.integer ) {
00548 int counts[TEAM_NUM_TEAMS];
00549
00550 counts[TEAM_BLUE] = TeamCount( ent->client->ps.clientNum, TEAM_BLUE );
00551 counts[TEAM_RED] = TeamCount( ent->client->ps.clientNum, TEAM_RED );
00552
00553
00554 if ( team == TEAM_RED && counts[TEAM_RED] - counts[TEAM_BLUE] > 1 ) {
00555 trap_SendServerCommand( ent->client->ps.clientNum,
00556 "cp \"Red team has too many players.\n\"" );
00557 return;
00558 }
00559 if ( team == TEAM_BLUE && counts[TEAM_BLUE] - counts[TEAM_RED] > 1 ) {
00560 trap_SendServerCommand( ent->client->ps.clientNum,
00561 "cp \"Blue team has too many players.\n\"" );
00562 return;
00563 }
00564
00565
00566 }
00567
00568 } else {
00569
00570 team = TEAM_FREE;
00571 }
00572
00573
00574 if ( (g_gametype.integer == GT_TOURNAMENT)
00575 && level.numNonSpectatorClients >= 2 ) {
00576 team = TEAM_SPECTATOR;
00577 } else if ( g_maxGameClients.integer > 0 &&
00578 level.numNonSpectatorClients >= g_maxGameClients.integer ) {
00579 team = TEAM_SPECTATOR;
00580 }
00581
00582
00583
00584
00585 oldTeam = client->sess.sessionTeam;
00586 if ( team == oldTeam && team != TEAM_SPECTATOR ) {
00587 return;
00588 }
00589
00590
00591
00592
00593
00594
00595 if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
00596 CopyToBodyQue(ent);
00597 }
00598
00599
00600 client->pers.teamState.state = TEAM_BEGIN;
00601 if ( oldTeam != TEAM_SPECTATOR ) {
00602
00603 ent->flags &= ~FL_GODMODE;
00604 ent->client->ps.stats[STAT_HEALTH] = ent->health = 0;
00605 player_die (ent, ent, ent, 100000, MOD_SUICIDE);
00606
00607 }
00608
00609 if ( team == TEAM_SPECTATOR ) {
00610 client->sess.spectatorTime = level.time;
00611 }
00612
00613 client->sess.sessionTeam = team;
00614 client->sess.spectatorState = specState;
00615 client->sess.spectatorClient = specClient;
00616
00617 client->sess.teamLeader = qfalse;
00618 if ( team == TEAM_RED || team == TEAM_BLUE ) {
00619 teamLeader = TeamLeader( team );
00620
00621 if ( teamLeader == -1 || ( !(g_entities[clientNum].r.svFlags & SVF_BOT) && (g_entities[teamLeader].r.svFlags & SVF_BOT) ) ) {
00622 SetLeader( team, clientNum );
00623 }
00624 }
00625
00626 if ( oldTeam == TEAM_RED || oldTeam == TEAM_BLUE ) {
00627 CheckTeamLeader( oldTeam );
00628 }
00629
00630 BroadcastTeamChange( client, oldTeam );
00631
00632
00633 ClientUserinfoChanged( clientNum );
00634
00635 ClientBegin( clientNum );
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 void StopFollowing( gentity_t *ent ) {
00647 ent->client->ps.persistant[ PERS_TEAM ] = TEAM_SPECTATOR;
00648 ent->client->sess.sessionTeam = TEAM_SPECTATOR;
00649 ent->client->sess.spectatorState = SPECTATOR_FREE;
00650 ent->client->ps.pm_flags &= ~PMF_FOLLOW;
00651 ent->r.svFlags &= ~SVF_BOT;
00652 ent->client->ps.clientNum = ent - g_entities;
00653 }
00654
00655
00656
00657
00658
00659
00660 void Cmd_Team_f( gentity_t *ent ) {
00661 int oldTeam;
00662 char s[MAX_TOKEN_CHARS];
00663
00664 if ( trap_Argc() != 2 ) {
00665 oldTeam = ent->client->sess.sessionTeam;
00666 switch ( oldTeam ) {
00667 case TEAM_BLUE:
00668 trap_SendServerCommand( ent-g_entities, "print \"Blue team\n\"" );
00669 break;
00670 case TEAM_RED:
00671 trap_SendServerCommand( ent-g_entities, "print \"Red team\n\"" );
00672 break;
00673 case TEAM_FREE:
00674 trap_SendServerCommand( ent-g_entities, "print \"Free team\n\"" );
00675 break;
00676 case TEAM_SPECTATOR:
00677 trap_SendServerCommand( ent-g_entities, "print \"Spectator team\n\"" );
00678 break;
00679 }
00680 return;
00681 }
00682
00683 if ( ent->client->switchTeamTime > level.time ) {
00684 trap_SendServerCommand( ent-g_entities, "print \"May not switch teams more than once per 5 seconds.\n\"" );
00685 return;
00686 }
00687
00688
00689 if ( (g_gametype.integer == GT_TOURNAMENT )
00690 && ent->client->sess.sessionTeam == TEAM_FREE ) {
00691 ent->client->sess.losses++;
00692 }
00693
00694 trap_Argv( 1, s, sizeof( s ) );
00695
00696 SetTeam( ent, s );
00697
00698 ent->client->switchTeamTime = level.time + 5000;
00699 }
00700
00701
00702
00703
00704
00705
00706
00707 void Cmd_Follow_f( gentity_t *ent ) {
00708 int i;
00709 char arg[MAX_TOKEN_CHARS];
00710
00711 if ( trap_Argc() != 2 ) {
00712 if ( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) {
00713 StopFollowing( ent );
00714 }
00715 return;
00716 }
00717
00718 trap_Argv( 1, arg, sizeof( arg ) );
00719 i = ClientNumberFromString( ent, arg );
00720 if ( i == -1 ) {
00721 return;
00722 }
00723
00724
00725 if ( &level.clients[ i ] == ent->client ) {
00726 return;
00727 }
00728
00729
00730 if ( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR ) {
00731 return;
00732 }
00733
00734
00735 if ( (g_gametype.integer == GT_TOURNAMENT )
00736 && ent->client->sess.sessionTeam == TEAM_FREE ) {
00737 ent->client->sess.losses++;
00738 }
00739
00740
00741 if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
00742 SetTeam( ent, "spectator" );
00743 }
00744
00745 ent->client->sess.spectatorState = SPECTATOR_FOLLOW;
00746 ent->client->sess.spectatorClient = i;
00747 }
00748
00749
00750
00751
00752
00753
00754 void Cmd_FollowCycle_f( gentity_t *ent, int dir ) {
00755 int clientnum;
00756 int original;
00757
00758
00759 if ( (g_gametype.integer == GT_TOURNAMENT )
00760 && ent->client->sess.sessionTeam == TEAM_FREE ) {
00761 ent->client->sess.losses++;
00762 }
00763
00764 if ( ent->client->sess.spectatorState == SPECTATOR_NOT ) {
00765 SetTeam( ent, "spectator" );
00766 }
00767
00768 if ( dir != 1 && dir != -1 ) {
00769 G_Error( "Cmd_FollowCycle_f: bad dir %i", dir );
00770 }
00771
00772 clientnum = ent->client->sess.spectatorClient;
00773 original = clientnum;
00774 do {
00775 clientnum += dir;
00776 if ( clientnum >= level.maxclients ) {
00777 clientnum = 0;
00778 }
00779 if ( clientnum < 0 ) {
00780 clientnum = level.maxclients - 1;
00781 }
00782
00783
00784 if ( level.clients[ clientnum ].pers.connected != CON_CONNECTED ) {
00785 continue;
00786 }
00787
00788
00789 if ( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) {
00790 continue;
00791 }
00792
00793
00794 ent->client->sess.spectatorClient = clientnum;
00795 ent->client->sess.spectatorState = SPECTATOR_FOLLOW;
00796 return;
00797 } while ( clientnum != original );
00798
00799
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809 static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message ) {
00810 if (!other) {
00811 return;
00812 }
00813 if (!other->inuse) {
00814 return;
00815 }
00816 if (!other->client) {
00817 return;
00818 }
00819 if ( other->client->pers.connected != CON_CONNECTED ) {
00820 return;
00821 }
00822 if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) {
00823 return;
00824 }
00825
00826 if ( (g_gametype.integer == GT_TOURNAMENT )
00827 && other->client->sess.sessionTeam == TEAM_FREE
00828 && ent->client->sess.sessionTeam != TEAM_FREE ) {
00829 return;
00830 }
00831
00832 trap_SendServerCommand( other-g_entities, va("%s \"%s%c%c%s\"",
00833 mode == SAY_TEAM ? "tchat" : "chat",
00834 name, Q_COLOR_ESCAPE, color, message));
00835 }
00836
00837 #define EC "\x19"
00838
00839 void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText ) {
00840 int j;
00841 gentity_t *other;
00842 int color;
00843 char name[64];
00844
00845 char text[MAX_SAY_TEXT];
00846 char location[64];
00847
00848 if ( g_gametype.integer < GT_TEAM && mode == SAY_TEAM ) {
00849 mode = SAY_ALL;
00850 }
00851
00852 switch ( mode ) {
00853 default:
00854 case SAY_ALL:
00855 G_LogPrintf( "say: %s: %s\n", ent->client->pers.netname, chatText );
00856 Com_sprintf (name, sizeof(name), "%s%c%c"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE );
00857 color = COLOR_GREEN;
00858 break;
00859 case SAY_TEAM:
00860 G_LogPrintf( "sayteam: %s: %s\n", ent->client->pers.netname, chatText );
00861 if (Team_GetLocationMsg(ent, location, sizeof(location)))
00862 Com_sprintf (name, sizeof(name), EC"(%s%c%c"EC") (%s)"EC": ",
00863 ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location);
00864 else
00865 Com_sprintf (name, sizeof(name), EC"(%s%c%c"EC")"EC": ",
00866 ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE );
00867 color = COLOR_CYAN;
00868 break;
00869 case SAY_TELL:
00870 if (target && g_gametype.integer >= GT_TEAM &&
00871 target->client->sess.sessionTeam == ent->client->sess.sessionTeam &&
00872 Team_GetLocationMsg(ent, location, sizeof(location)))
00873 Com_sprintf (name, sizeof(name), EC"[%s%c%c"EC"] (%s)"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location );
00874 else
00875 Com_sprintf (name, sizeof(name), EC"[%s%c%c"EC"]"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE );
00876 color = COLOR_MAGENTA;
00877 break;
00878 }
00879
00880 Q_strncpyz( text, chatText, sizeof(text) );
00881
00882 if ( target ) {
00883 G_SayTo( ent, target, mode, color, name, text );
00884 return;
00885 }
00886
00887
00888 if ( g_dedicated.integer ) {
00889 G_Printf( "%s%s\n", name, text);
00890 }
00891
00892
00893 for (j = 0; j < level.maxclients; j++) {
00894 other = &g_entities[j];
00895 G_SayTo( ent, other, mode, color, name, text );
00896 }
00897 }
00898
00899
00900
00901
00902
00903
00904
00905 static void Cmd_Say_f( gentity_t *ent, int mode, qboolean arg0 ) {
00906 char *p;
00907
00908 if ( trap_Argc () < 2 && !arg0 ) {
00909 return;
00910 }
00911
00912 if (arg0)
00913 {
00914 p = ConcatArgs( 0 );
00915 }
00916 else
00917 {
00918 p = ConcatArgs( 1 );
00919 }
00920
00921 G_Say( ent, NULL, mode, p );
00922 }
00923
00924
00925
00926
00927
00928
00929 static void Cmd_Tell_f( gentity_t *ent ) {
00930 int targetNum;
00931 gentity_t *target;
00932 char *p;
00933 char arg[MAX_TOKEN_CHARS];
00934
00935 if ( trap_Argc () < 2 ) {
00936 return;
00937 }
00938
00939 trap_Argv( 1, arg, sizeof( arg ) );
00940 targetNum = atoi( arg );
00941 if ( targetNum < 0 || targetNum >= level.maxclients ) {
00942 return;
00943 }
00944
00945 target = &g_entities[targetNum];
00946 if ( !target || !target->inuse || !target->client ) {
00947 return;
00948 }
00949
00950 p = ConcatArgs( 2 );
00951
00952 G_LogPrintf( "tell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, p );
00953 G_Say( ent, target, SAY_TELL, p );
00954
00955
00956 if ( ent != target && !(ent->r.svFlags & SVF_BOT)) {
00957 G_Say( ent, ent, SAY_TELL, p );
00958 }
00959 }
00960
00961
00962 static void G_VoiceTo( gentity_t *ent, gentity_t *other, int mode, const char *id, qboolean voiceonly ) {
00963 int color;
00964 char *cmd;
00965
00966 if (!other) {
00967 return;
00968 }
00969 if (!other->inuse) {
00970 return;
00971 }
00972 if (!other->client) {
00973 return;
00974 }
00975 if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) {
00976 return;
00977 }
00978
00979 if ( (g_gametype.integer == GT_TOURNAMENT )) {
00980 return;
00981 }
00982
00983 if (mode == SAY_TEAM) {
00984 color = COLOR_CYAN;
00985 cmd = "vtchat";
00986 }
00987 else if (mode == SAY_TELL) {
00988 color = COLOR_MAGENTA;
00989 cmd = "vtell";
00990 }
00991 else {
00992 color = COLOR_GREEN;
00993 cmd = "vchat";
00994 }
00995
00996 trap_SendServerCommand( other-g_entities, va("%s %d %d %d %s", cmd, voiceonly, ent->s.number, color, id));
00997 }
00998
00999 void G_Voice( gentity_t *ent, gentity_t *target, int mode, const char *id, qboolean voiceonly ) {
01000 int j;
01001 gentity_t *other;
01002
01003 if ( g_gametype.integer < GT_TEAM && mode == SAY_TEAM ) {
01004 mode = SAY_ALL;
01005 }
01006
01007 if ( target ) {
01008 G_VoiceTo( ent, target, mode, id, voiceonly );
01009 return;
01010 }
01011
01012
01013 if ( g_dedicated.integer ) {
01014 G_Printf( "voice: %s %s\n", ent->client->pers.netname, id);
01015 }
01016
01017
01018 for (j = 0; j < level.maxclients; j++) {
01019 other = &g_entities[j];
01020 G_VoiceTo( ent, other, mode, id, voiceonly );
01021 }
01022 }
01023
01024
01025
01026
01027
01028
01029 static void Cmd_Voice_f( gentity_t *ent, int mode, qboolean arg0, qboolean voiceonly ) {
01030 char *p;
01031
01032 if ( trap_Argc () < 2 && !arg0 ) {
01033 return;
01034 }
01035
01036 if (arg0)
01037 {
01038 p = ConcatArgs( 0 );
01039 }
01040 else
01041 {
01042 p = ConcatArgs( 1 );
01043 }
01044
01045 G_Voice( ent, NULL, mode, p, voiceonly );
01046 }
01047
01048
01049
01050
01051
01052
01053 static void Cmd_VoiceTell_f( gentity_t *ent, qboolean voiceonly ) {
01054 int targetNum;
01055 gentity_t *target;
01056 char *id;
01057 char arg[MAX_TOKEN_CHARS];
01058
01059 if ( trap_Argc () < 2 ) {
01060 return;
01061 }
01062
01063 trap_Argv( 1, arg, sizeof( arg ) );
01064 targetNum = atoi( arg );
01065 if ( targetNum < 0 || targetNum >= level.maxclients ) {
01066 return;
01067 }
01068
01069 target = &g_entities[targetNum];
01070 if ( !target || !target->inuse || !target->client ) {
01071 return;
01072 }
01073
01074 id = ConcatArgs( 2 );
01075
01076 G_LogPrintf( "vtell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, id );
01077 G_Voice( ent, target, SAY_TELL, id, voiceonly );
01078
01079
01080 if ( ent != target && !(ent->r.svFlags & SVF_BOT)) {
01081 G_Voice( ent, ent, SAY_TELL, id, voiceonly );
01082 }
01083 }
01084
01085
01086
01087
01088
01089
01090
01091 static void Cmd_VoiceTaunt_f( gentity_t *ent ) {
01092 gentity_t *who;
01093 int i;
01094
01095 if (!ent->client) {
01096 return;
01097 }
01098
01099
01100 if (ent->enemy && ent->enemy->client && ent->enemy->client->lastkilled_client == ent->s.number) {
01101
01102 if (!(ent->enemy->r.svFlags & SVF_BOT)) {
01103 G_Voice( ent, ent->enemy, SAY_TELL, VOICECHAT_DEATHINSULT, qfalse );
01104 }
01105 if (!(ent->r.svFlags & SVF_BOT)) {
01106 G_Voice( ent, ent, SAY_TELL, VOICECHAT_DEATHINSULT, qfalse );
01107 }
01108 ent->enemy = NULL;
01109 return;
01110 }
01111
01112 if (ent->client->lastkilled_client >= 0 && ent->client->lastkilled_client != ent->s.number) {
01113 who = g_entities + ent->client->lastkilled_client;
01114 if (who->client) {
01115
01116 if (who->client->lasthurt_mod == MOD_GAUNTLET) {
01117 if (!(who->r.svFlags & SVF_BOT)) {
01118 G_Voice( ent, who, SAY_TELL, VOICECHAT_KILLGAUNTLET, qfalse );
01119 }
01120 if (!(ent->r.svFlags & SVF_BOT)) {
01121 G_Voice( ent, ent, SAY_TELL, VOICECHAT_KILLGAUNTLET, qfalse );
01122 }
01123 } else {
01124 if (!(who->r.svFlags & SVF_BOT)) {
01125 G_Voice( ent, who, SAY_TELL, VOICECHAT_KILLINSULT, qfalse );
01126 }
01127 if (!(ent->r.svFlags & SVF_BOT)) {
01128 G_Voice( ent, ent, SAY_TELL, VOICECHAT_KILLINSULT, qfalse );
01129 }
01130 }
01131 ent->client->lastkilled_client = -1;
01132 return;
01133 }
01134 }
01135
01136 if (g_gametype.integer >= GT_TEAM) {
01137
01138 for(i = 0; i < MAX_CLIENTS; i++) {
01139 who = g_entities + i;
01140 if (who->client && who != ent && who->client->sess.sessionTeam == ent->client->sess.sessionTeam) {
01141 if (who->client->rewardTime > level.time) {
01142 if (!(who->r.svFlags & SVF_BOT)) {
01143 G_Voice( ent, who, SAY_TELL, VOICECHAT_PRAISE, qfalse );
01144 }
01145 if (!(ent->r.svFlags & SVF_BOT)) {
01146 G_Voice( ent, ent, SAY_TELL, VOICECHAT_PRAISE, qfalse );
01147 }
01148 return;
01149 }
01150 }
01151 }
01152 }
01153
01154
01155 G_Voice( ent, NULL, SAY_ALL, VOICECHAT_TAUNT, qfalse );
01156 }
01157
01158
01159
01160 static char *gc_orders[] = {
01161 "hold your position",
01162 "hold this position",
01163 "come here",
01164 "cover me",
01165 "guard location",
01166 "search and destroy",
01167 "report"
01168 };
01169
01170 void Cmd_GameCommand_f( gentity_t *ent ) {
01171 int player;
01172 int order;
01173 char str[MAX_TOKEN_CHARS];
01174
01175 trap_Argv( 1, str, sizeof( str ) );
01176 player = atoi( str );
01177 trap_Argv( 2, str, sizeof( str ) );
01178 order = atoi( str );
01179
01180 if ( player < 0 || player >= MAX_CLIENTS ) {
01181 return;
01182 }
01183 if ( order < 0 || order > sizeof(gc_orders)/sizeof(char *) ) {
01184 return;
01185 }
01186 G_Say( ent, &g_entities[player], SAY_TELL, gc_orders[order] );
01187 G_Say( ent, ent, SAY_TELL, gc_orders[order] );
01188 }
01189
01190
01191
01192
01193
01194
01195 void Cmd_Where_f( gentity_t *ent ) {
01196 trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", vtos( ent->s.origin ) ) );
01197 }
01198
01199 static const char *gameNames[] = {
01200 "Free For All",
01201 "Tournament",
01202 "Single Player",
01203 "Team Deathmatch",
01204 "Capture the Flag",
01205 "One Flag CTF",
01206 "Overload",
01207 "Harvester"
01208 };
01209
01210
01211
01212
01213
01214
01215 void Cmd_CallVote_f( gentity_t *ent ) {
01216 int i;
01217 char arg1[MAX_STRING_TOKENS];
01218 char arg2[MAX_STRING_TOKENS];
01219
01220 if ( !g_allowVote.integer ) {
01221 trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here.\n\"" );
01222 return;
01223 }
01224
01225 if ( level.voteTime ) {
01226 trap_SendServerCommand( ent-g_entities, "print \"A vote is already in progress.\n\"" );
01227 return;
01228 }
01229 if ( ent->client->pers.voteCount >= MAX_VOTE_COUNT ) {
01230 trap_SendServerCommand( ent-g_entities, "print \"You have called the maximum number of votes.\n\"" );
01231 return;
01232 }
01233 if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
01234 trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator.\n\"" );
01235 return;
01236 }
01237
01238
01239 trap_Argv( 1, arg1, sizeof( arg1 ) );
01240 trap_Argv( 2, arg2, sizeof( arg2 ) );
01241
01242 if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) {
01243 trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
01244 return;
01245 }
01246
01247 if ( !Q_stricmp( arg1, "map_restart" ) ) {
01248 } else if ( !Q_stricmp( arg1, "nextmap" ) ) {
01249 } else if ( !Q_stricmp( arg1, "map" ) ) {
01250 } else if ( !Q_stricmp( arg1, "g_gametype" ) ) {
01251 } else if ( !Q_stricmp( arg1, "kick" ) ) {
01252 } else if ( !Q_stricmp( arg1, "clientkick" ) ) {
01253 } else if ( !Q_stricmp( arg1, "g_doWarmup" ) ) {
01254 } else if ( !Q_stricmp( arg1, "timelimit" ) ) {
01255 } else if ( !Q_stricmp( arg1, "fraglimit" ) ) {
01256 } else {
01257 trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
01258 trap_SendServerCommand( ent-g_entities, "print \"Vote commands are: map_restart, nextmap, map <mapname>, g_gametype <n>, kick <player>, clientkick <clientnum>, g_doWarmup, timelimit <time>, fraglimit <frags>.\n\"" );
01259 return;
01260 }
01261
01262
01263 if ( level.voteExecuteTime ) {
01264 level.voteExecuteTime = 0;
01265 trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.voteString ) );
01266 }
01267
01268
01269 if ( !Q_stricmp( arg1, "g_gametype" ) ) {
01270 i = atoi( arg2 );
01271 if( i == GT_SINGLE_PLAYER || i < GT_FFA || i >= GT_MAX_GAME_TYPE) {
01272 trap_SendServerCommand( ent-g_entities, "print \"Invalid gametype.\n\"" );
01273 return;
01274 }
01275
01276 Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
01277 Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s %s", arg1, gameNames[i] );
01278 } else if ( !Q_stricmp( arg1, "map" ) ) {
01279
01280
01281 char s[MAX_STRING_CHARS];
01282
01283 trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) );
01284 if (*s) {
01285 Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s; set nextmap \"%s\"", arg1, arg2, s );
01286 } else {
01287 Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
01288 }
01289 Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
01290 } else if ( !Q_stricmp( arg1, "nextmap" ) ) {
01291 char s[MAX_STRING_CHARS];
01292
01293 trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) );
01294 if (!*s) {
01295 trap_SendServerCommand( ent-g_entities, "print \"nextmap not set.\n\"" );
01296 return;
01297 }
01298 Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap");
01299 Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
01300 } else {
01301 Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 );
01302 Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
01303 }
01304
01305 trap_SendServerCommand( -1, va("print \"%s called a vote.\n\"", ent->client->pers.netname ) );
01306
01307
01308 level.voteTime = level.time;
01309 level.voteYes = 1;
01310 level.voteNo = 0;
01311
01312 for ( i = 0 ; i < level.maxclients ; i++ ) {
01313 level.clients[i].ps.eFlags &= ~EF_VOTED;
01314 }
01315 ent->client->ps.eFlags |= EF_VOTED;
01316
01317 trap_SetConfigstring( CS_VOTE_TIME, va("%i", level.voteTime ) );
01318 trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString );
01319 trap_SetConfigstring( CS_VOTE_YES, va("%i", level.voteYes ) );
01320 trap_SetConfigstring( CS_VOTE_NO, va("%i", level.voteNo ) );
01321 }
01322
01323
01324
01325
01326
01327
01328 void Cmd_Vote_f( gentity_t *ent ) {
01329 char msg[64];
01330
01331 if ( !level.voteTime ) {
01332 trap_SendServerCommand( ent-g_entities, "print \"No vote in progress.\n\"" );
01333 return;
01334 }
01335 if ( ent->client->ps.eFlags & EF_VOTED ) {
01336 trap_SendServerCommand( ent-g_entities, "print \"Vote already cast.\n\"" );
01337 return;
01338 }
01339 if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
01340 trap_SendServerCommand( ent-g_entities, "print \"Not allowed to vote as spectator.\n\"" );
01341 return;
01342 }
01343
01344 trap_SendServerCommand( ent-g_entities, "print \"Vote cast.\n\"" );
01345
01346 ent->client->ps.eFlags |= EF_VOTED;
01347
01348 trap_Argv( 1, msg, sizeof( msg ) );
01349
01350 if ( msg[0] == 'y' || msg[1] == 'Y' || msg[1] == '1' ) {
01351 level.voteYes++;
01352 trap_SetConfigstring( CS_VOTE_YES, va("%i", level.voteYes ) );
01353 } else {
01354 level.voteNo++;
01355 trap_SetConfigstring( CS_VOTE_NO, va("%i", level.voteNo ) );
01356 }
01357
01358
01359
01360 }
01361
01362
01363
01364
01365
01366
01367 void Cmd_CallTeamVote_f( gentity_t *ent ) {
01368 int i, team, cs_offset;
01369 char arg1[MAX_STRING_TOKENS];
01370 char arg2[MAX_STRING_TOKENS];
01371
01372 team = ent->client->sess.sessionTeam;
01373 if ( team == TEAM_RED )
01374 cs_offset = 0;
01375 else if ( team == TEAM_BLUE )
01376 cs_offset = 1;
01377 else
01378 return;
01379
01380 if ( !g_allowVote.integer ) {
01381 trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here.\n\"" );
01382 return;
01383 }
01384
01385 if ( level.teamVoteTime[cs_offset] ) {
01386 trap_SendServerCommand( ent-g_entities, "print \"A team vote is already in progress.\n\"" );
01387 return;
01388 }
01389 if ( ent->client->pers.teamVoteCount >= MAX_VOTE_COUNT ) {
01390 trap_SendServerCommand( ent-g_entities, "print \"You have called the maximum number of team votes.\n\"" );
01391 return;
01392 }
01393 if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
01394 trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator.\n\"" );
01395 return;
01396 }
01397
01398
01399 trap_Argv( 1, arg1, sizeof( arg1 ) );
01400 arg2[0] = '\0';
01401 for ( i = 2; i < trap_Argc(); i++ ) {
01402 if (i > 2)
01403 strcat(arg2, " ");
01404 trap_Argv( i, &arg2[strlen(arg2)], sizeof( arg2 ) - strlen(arg2) );
01405 }
01406
01407 if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) {
01408 trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
01409 return;
01410 }
01411
01412 if ( !Q_stricmp( arg1, "leader" ) ) {
01413 char netname[MAX_NETNAME], leader[MAX_NETNAME];
01414
01415 if ( !arg2[0] ) {
01416 i = ent->client->ps.clientNum;
01417 }
01418 else {
01419
01420 for (i = 0; i < 3; i++) {
01421 if ( !arg2[i] || arg2[i] < '0' || arg2[i] > '9' )
01422 break;
01423 }
01424 if ( i >= 3 || !arg2[i]) {
01425 i = atoi( arg2 );
01426 if ( i < 0 || i >= level.maxclients ) {
01427 trap_SendServerCommand( ent-g_entities, va("print \"Bad client slot: %i\n\"", i) );
01428 return;
01429 }
01430
01431 if ( !g_entities[i].inuse ) {
01432 trap_SendServerCommand( ent-g_entities, va("print \"Client %i is not active\n\"", i) );
01433 return;
01434 }
01435 }
01436 else {
01437 Q_strncpyz(leader, arg2, sizeof(leader));
01438 Q_CleanStr(leader);
01439 for ( i = 0 ; i < level.maxclients ; i++ ) {
01440 if ( level.clients[i].pers.connected == CON_DISCONNECTED )
01441 continue;
01442 if (level.clients[i].sess.sessionTeam != team)
01443 continue;
01444 Q_strncpyz(netname, level.clients[i].pers.netname, sizeof(netname));
01445 Q_CleanStr(netname);
01446 if ( !Q_stricmp(netname, leader) ) {
01447 break;
01448 }
01449 }
01450 if ( i >= level.maxclients ) {
01451 trap_SendServerCommand( ent-g_entities, va("print \"%s is not a valid player on your team.\n\"", arg2) );
01452 return;
01453 }
01454 }
01455 }
01456 Com_sprintf(arg2, sizeof(arg2), "%d", i);
01457 } else {
01458 trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
01459 trap_SendServerCommand( ent-g_entities, "print \"Team vote commands are: leader <player>.\n\"" );
01460 return;
01461 }
01462
01463 Com_sprintf( level.teamVoteString[cs_offset], sizeof( level.teamVoteString[cs_offset] ), "%s %s", arg1, arg2 );
01464
01465 for ( i = 0 ; i < level.maxclients ; i++ ) {
01466 if ( level.clients[i].pers.connected == CON_DISCONNECTED )
01467 continue;
01468 if (level.clients[i].sess.sessionTeam == team)
01469 trap_SendServerCommand( i, va("print \"%s called a team vote.\n\"", ent->client->pers.netname ) );
01470 }
01471
01472
01473 level.teamVoteTime[cs_offset] = level.time;
01474 level.teamVoteYes[cs_offset] = 1;
01475 level.teamVoteNo[cs_offset] = 0;
01476
01477 for ( i = 0 ; i < level.maxclients ; i++ ) {
01478 if (level.clients[i].sess.sessionTeam == team)
01479 level.clients[i].ps.eFlags &= ~EF_TEAMVOTED;
01480 }
01481 ent->client->ps.eFlags |= EF_TEAMVOTED;
01482
01483 trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, va("%i", level.teamVoteTime[cs_offset] ) );
01484 trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, level.teamVoteString[cs_offset] );
01485 trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, va("%i", level.teamVoteYes[cs_offset] ) );
01486 trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va("%i", level.teamVoteNo[cs_offset] ) );
01487 }
01488
01489
01490
01491
01492
01493
01494 void Cmd_TeamVote_f( gentity_t *ent ) {
01495 int team, cs_offset;
01496 char msg[64];
01497
01498 team = ent->client->sess.sessionTeam;
01499 if ( team == TEAM_RED )
01500 cs_offset = 0;
01501 else if ( team == TEAM_BLUE )
01502 cs_offset = 1;
01503 else
01504 return;
01505
01506 if ( !level.teamVoteTime[cs_offset] ) {
01507 trap_SendServerCommand( ent-g_entities, "print \"No team vote in progress.\n\"" );
01508 return;
01509 }
01510 if ( ent->client->ps.eFlags & EF_TEAMVOTED ) {
01511 trap_SendServerCommand( ent-g_entities, "print \"Team vote already cast.\n\"" );
01512 return;
01513 }
01514 if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
01515 trap_SendServerCommand( ent-g_entities, "print \"Not allowed to vote as spectator.\n\"" );
01516 return;
01517 }
01518
01519 trap_SendServerCommand( ent-g_entities, "print \"Team vote cast.\n\"" );
01520
01521 ent->client->ps.eFlags |= EF_TEAMVOTED;
01522
01523 trap_Argv( 1, msg, sizeof( msg ) );
01524
01525 if ( msg[0] == 'y' || msg[1] == 'Y' || msg[1] == '1' ) {
01526 level.teamVoteYes[cs_offset]++;
01527 trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, va("%i", level.teamVoteYes[cs_offset] ) );
01528 } else {
01529 level.teamVoteNo[cs_offset]++;
01530 trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va("%i", level.teamVoteNo[cs_offset] ) );
01531 }
01532
01533
01534
01535 }
01536
01537
01538
01539
01540
01541
01542
01543 void Cmd_SetViewpos_f( gentity_t *ent ) {
01544 vec3_t origin, angles;
01545 char buffer[MAX_TOKEN_CHARS];
01546 int i;
01547
01548 if ( !g_cheats.integer ) {
01549 trap_SendServerCommand( ent-g_entities, va("print \"Cheats are not enabled on this server.\n\""));
01550 return;
01551 }
01552 if ( trap_Argc() != 5 ) {
01553 trap_SendServerCommand( ent-g_entities, va("print \"usage: setviewpos x y z yaw\n\""));
01554 return;
01555 }
01556
01557 VectorClear( angles );
01558 for ( i = 0 ; i < 3 ; i++ ) {
01559 trap_Argv( i + 1, buffer, sizeof( buffer ) );
01560 origin[i] = atof( buffer );
01561 }
01562
01563 trap_Argv( 4, buffer, sizeof( buffer ) );
01564 angles[YAW] = atof( buffer );
01565
01566 TeleportPlayer( ent, origin, angles );
01567 }
01568
01569
01570
01571
01572
01573
01574
01575
01576 void Cmd_Stats_f( gentity_t *ent ) {
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591 }
01592
01593
01594
01595
01596
01597
01598 void ClientCommand( int clientNum ) {
01599 gentity_t *ent;
01600 char cmd[MAX_TOKEN_CHARS];
01601
01602 ent = g_entities + clientNum;
01603 if ( !ent->client ) {
01604 return;
01605 }
01606
01607
01608 trap_Argv( 0, cmd, sizeof( cmd ) );
01609
01610 if (Q_stricmp (cmd, "say") == 0) {
01611 Cmd_Say_f (ent, SAY_ALL, qfalse);
01612 return;
01613 }
01614 if (Q_stricmp (cmd, "say_team") == 0) {
01615 Cmd_Say_f (ent, SAY_TEAM, qfalse);
01616 return;
01617 }
01618 if (Q_stricmp (cmd, "tell") == 0) {
01619 Cmd_Tell_f ( ent );
01620 return;
01621 }
01622 if (Q_stricmp (cmd, "vsay") == 0) {
01623 Cmd_Voice_f (ent, SAY_ALL, qfalse, qfalse);
01624 return;
01625 }
01626 if (Q_stricmp (cmd, "vsay_team") == 0) {
01627 Cmd_Voice_f (ent, SAY_TEAM, qfalse, qfalse);
01628 return;
01629 }
01630 if (Q_stricmp (cmd, "vtell") == 0) {
01631 Cmd_VoiceTell_f ( ent, qfalse );
01632 return;
01633 }
01634 if (Q_stricmp (cmd, "vosay") == 0) {
01635 Cmd_Voice_f (ent, SAY_ALL, qfalse, qtrue);
01636 return;
01637 }
01638 if (Q_stricmp (cmd, "vosay_team") == 0) {
01639 Cmd_Voice_f (ent, SAY_TEAM, qfalse, qtrue);
01640 return;
01641 }
01642 if (Q_stricmp (cmd, "votell") == 0) {
01643 Cmd_VoiceTell_f ( ent, qtrue );
01644 return;
01645 }
01646 if (Q_stricmp (cmd, "vtaunt") == 0) {
01647 Cmd_VoiceTaunt_f ( ent );
01648 return;
01649 }
01650 if (Q_stricmp (cmd, "score") == 0) {
01651 Cmd_Score_f (ent);
01652 return;
01653 }
01654
01655
01656 if (level.intermissiontime) {
01657 Cmd_Say_f (ent, qfalse, qtrue);
01658 return;
01659 }
01660
01661 if (Q_stricmp (cmd, "give") == 0)
01662 Cmd_Give_f (ent);
01663 else if (Q_stricmp (cmd, "god") == 0)
01664 Cmd_God_f (ent);
01665 else if (Q_stricmp (cmd, "notarget") == 0)
01666 Cmd_Notarget_f (ent);
01667 else if (Q_stricmp (cmd, "noclip") == 0)
01668 Cmd_Noclip_f (ent);
01669 else if (Q_stricmp (cmd, "kill") == 0)
01670 Cmd_Kill_f (ent);
01671 else if (Q_stricmp (cmd, "teamtask") == 0)
01672 Cmd_TeamTask_f (ent);
01673 else if (Q_stricmp (cmd, "levelshot") == 0)
01674 Cmd_LevelShot_f (ent);
01675 else if (Q_stricmp (cmd, "follow") == 0)
01676 Cmd_Follow_f (ent);
01677 else if (Q_stricmp (cmd, "follownext") == 0)
01678 Cmd_FollowCycle_f (ent, 1);
01679 else if (Q_stricmp (cmd, "followprev") == 0)
01680 Cmd_FollowCycle_f (ent, -1);
01681 else if (Q_stricmp (cmd, "team") == 0)
01682 Cmd_Team_f (ent);
01683 else if (Q_stricmp (cmd, "where") == 0)
01684 Cmd_Where_f (ent);
01685 else if (Q_stricmp (cmd, "callvote") == 0)
01686 Cmd_CallVote_f (ent);
01687 else if (Q_stricmp (cmd, "vote") == 0)
01688 Cmd_Vote_f (ent);
01689 else if (Q_stricmp (cmd, "callteamvote") == 0)
01690 Cmd_CallTeamVote_f (ent);
01691 else if (Q_stricmp (cmd, "teamvote") == 0)
01692 Cmd_TeamVote_f (ent);
01693 else if (Q_stricmp (cmd, "gc") == 0)
01694 Cmd_GameCommand_f( ent );
01695 else if (Q_stricmp (cmd, "setviewpos") == 0)
01696 Cmd_SetViewpos_f( ent );
01697 else if (Q_stricmp (cmd, "stats") == 0)
01698 Cmd_Stats_f( ent );
01699 else
01700 trap_SendServerCommand( clientNum, va("print \"unknown cmd %s\n\"", cmd ) );
01701 }