00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "g_local.h"
00030 #include "../shared/parse.h"
00031
00032 static void G_Players_f (const player_t *player)
00033 {
00034 int i;
00035 int count = 0;
00036 char smallBuf[64];
00037 char largeBuf[1280];
00038
00039
00040 largeBuf[0] = 0;
00041
00042 for (i = 0; i < game.sv_maxplayersperteam; i++) {
00043 const player_t *p = &game.players[i];
00044 if (!p->inuse)
00045 continue;
00046
00047 Com_sprintf(smallBuf, sizeof(smallBuf), "(%i) Team %i %s status: %s\n", p->num,
00048 p->pers.team, p->pers.netname, (p->roundDone ? "waiting" : "playing"));
00049
00050
00051 if (strlen(smallBuf) + strlen(largeBuf) > sizeof(largeBuf) - 100) {
00052 Q_strcat(largeBuf, "...\n", sizeof(largeBuf));
00053 break;
00054 }
00055 Q_strcat(largeBuf, smallBuf, sizeof(largeBuf));
00056 count++;
00057 }
00058
00059 G_ClientPrintf(player, PRINT_CONSOLE, "%s\n%i players\n", largeBuf, count);
00060 }
00061
00065 static qboolean G_CheckFlood (player_t *player)
00066 {
00067 int i;
00068
00069 if (flood_msgs->integer) {
00070 if (level.time < player->pers.flood_locktill) {
00071 G_ClientPrintf(player, PRINT_CHAT, _("You can't talk for %d more seconds\n"), (int)(player->pers.flood_locktill - level.time));
00072 return qtrue;
00073 }
00074 i = player->pers.flood_whenhead - flood_msgs->value + 1;
00075 if (i < 0)
00076 i = (sizeof(player->pers.flood_when)/sizeof(player->pers.flood_when[0])) + i;
00077 if (player->pers.flood_when[i] && level.time - player->pers.flood_when[i] < flood_persecond->value) {
00078 player->pers.flood_locktill = level.time + flood_waitdelay->value;
00079 G_ClientPrintf(player, PRINT_CHAT, _("Flood protection: You can't talk for %d seconds.\n"), flood_waitdelay->integer);
00080 return qtrue;
00081 }
00082 player->pers.flood_whenhead = (player->pers.flood_whenhead + 1) %
00083 (sizeof(player->pers.flood_when)/sizeof(player->pers.flood_when[0]));
00084 player->pers.flood_when[player->pers.flood_whenhead] = level.time;
00085 }
00086 return qfalse;
00087 }
00088
00089 static void G_Say_f (player_t *player, qboolean arg0, qboolean team)
00090 {
00091 int j;
00092 char text[256];
00093
00094 if (gi.Cmd_Argc() < 2 && !arg0)
00095 return;
00096
00097 if (G_CheckFlood(player))
00098 return;
00099
00100 if (!team)
00101 Com_sprintf(text, sizeof(text), "%s: ", player->pers.netname);
00102 else
00103 Com_sprintf(text, sizeof(text), "^B%s (team): ", player->pers.netname);
00104
00105 if (arg0) {
00106 Q_strcat(text, gi.Cmd_Argv(0), sizeof(text));
00107 Q_strcat(text, " ", sizeof(text));
00108 Q_strcat(text, gi.Cmd_Args(), sizeof(text));
00109 } else {
00110 const char *p = gi.Cmd_Args();
00111 const char *token = Com_Parse(&p);
00112
00113 Q_strcat(text, token, sizeof(text));
00114 }
00115
00116 Q_strcat(text, "\n", sizeof(text));
00117
00118 if (sv_dedicated->integer)
00119 gi.DPrintf("%s", text);
00120
00121 for (j = 0; j < game.sv_maxplayersperteam; j++) {
00122 if (!game.players[j].inuse)
00123 continue;
00124 if (team && game.players[j].pers.team != player->pers.team)
00125 continue;
00126 G_ClientPrintf(&game.players[j], PRINT_CHAT, "%s", text);
00127 }
00128 }
00129
00130 #ifdef DEBUG
00131
00136 static void G_KillTeam_f (void)
00137 {
00138
00139 int teamToKill = -1;
00140 edict_t *ent = NULL;
00141
00142
00143 if (gi.Cmd_Argc() == 2)
00144 teamToKill = atoi(gi.Cmd_Argv(1));
00145
00146 Com_DPrintf(DEBUG_GAME, "G_KillTeam: kill team %i\n", teamToKill);
00147
00148 if (teamToKill >= 0)
00149 while ((ent = G_EdictsGetNextLivingActorOfTeam(ent, teamToKill))) {
00150
00151 ent->HP = 0;
00152 G_ActorDieOrStun(ent, NULL);
00153 }
00154
00155
00156 G_MatchEndCheck();
00157 }
00158
00162 static void G_StunTeam_f (void)
00163 {
00164
00165 int teamToKill = -1;
00166 edict_t *ent = NULL;
00167
00168
00169 if (gi.Cmd_Argc() == 2)
00170 teamToKill = atoi(gi.Cmd_Argv(1));
00171
00172 if (teamToKill >= 0) {
00173 while ((ent = G_EdictsGetNextLivingActorOfTeam(ent, teamToKill))) {
00174
00175 G_ActorDieOrStun(ent, NULL);
00176
00177 if (teamToKill == TEAM_ALIEN)
00178 level.num_stuns[TEAM_PHALANX][TEAM_ALIEN]++;
00179 else
00180 level.num_stuns[TEAM_ALIEN][teamToKill]++;
00181 }
00182 }
00183
00184
00185 G_MatchEndCheck();
00186 }
00187
00192 static void G_ListMissionScore_f (void)
00193 {
00194 int team = -1;
00195 edict_t *ent = NULL;
00196 int i, j;
00197
00198
00199 if (gi.Cmd_Argc() == 2) {
00200 team = atoi(gi.Cmd_Argv(1));
00201 } else {
00202 gi.DPrintf("Usage: %s <teamnumber>\n", gi.Cmd_Argv(0));
00203 return;
00204 }
00205
00206 while ((ent = G_EdictsGetNextLivingActor(ent))) {
00207 if (team >= 0 && ent->team != team)
00208 continue;
00209
00210 assert(ent->chr.scoreMission);
00211
00212 gi.DPrintf("Soldier: %s\n", ent->chr.name);
00213
00214
00215 gi.DPrintf(" Move: Normal=%i Crouched=%i\n", ent->chr.scoreMission->movedNormal, ent->chr.scoreMission->movedCrouched);
00216
00217 gi.DPrintf(" Kills:");
00218 for (i = 0; i < KILLED_NUM_TYPES; i++) {
00219 gi.DPrintf(" %i", ent->chr.scoreMission->kills[i]);
00220 }
00221 gi.DPrintf("\n");
00222
00223 gi.DPrintf(" Stuns:");
00224 for (i = 0; i < KILLED_NUM_TYPES; i++) {
00225 gi.DPrintf(" %i", ent->chr.scoreMission->stuns[i]);
00226 }
00227 gi.DPrintf("\n");
00228
00229
00230 gi.DPrintf(" Fired:");
00231 for (i = 0; i < SKILL_NUM_TYPES; i++) {
00232 gi.DPrintf(" %i", ent->chr.scoreMission->fired[i]);
00233 }
00234 gi.DPrintf("\n");
00235
00236 gi.DPrintf(" Hits:\n");
00237 for (i = 0; i < SKILL_NUM_TYPES; i++) {
00238 gi.DPrintf(" Skill%i: ",i);
00239 for (j = 0; j < KILLED_NUM_TYPES; j++) {
00240 gi.DPrintf(" %i", ent->chr.scoreMission->hits[i][j]);
00241 }
00242 gi.DPrintf("\n");
00243 }
00244
00245
00246 gi.DPrintf(" Fired Splash:");
00247 for (i = 0; i < SKILL_NUM_TYPES; i++) {
00248 gi.DPrintf(" %i", ent->chr.scoreMission->firedSplash[i]);
00249 }
00250 gi.DPrintf("\n");
00251
00252 gi.DPrintf(" Hits Splash:\n");
00253 for (i = 0; i < SKILL_NUM_TYPES; i++) {
00254 gi.DPrintf(" Skill%i: ",i);
00255 for (j = 0; j < KILLED_NUM_TYPES; j++) {
00256 gi.DPrintf(" %i", ent->chr.scoreMission->hitsSplash[i][j]);
00257 }
00258 gi.DPrintf("\n");
00259 }
00260
00261 gi.DPrintf(" Splash Damage:\n");
00262 for (i = 0; i < SKILL_NUM_TYPES; i++) {
00263 gi.DPrintf(" Skill%i: ",i);
00264 for (j = 0; j < KILLED_NUM_TYPES; j++) {
00265 gi.DPrintf(" %i", ent->chr.scoreMission->hitsSplashDamage[i][j]);
00266 }
00267 gi.DPrintf("\n");
00268 }
00269
00270
00271 gi.DPrintf(" Kills per skill:");
00272 for (i = 0; i < SKILL_NUM_TYPES; i++) {
00273 gi.DPrintf(" %i", ent->chr.scoreMission->skillKills[i]);
00274 }
00275 gi.DPrintf("\n");
00276
00277
00278 gi.DPrintf(" Heal (received): %i\n", ent->chr.scoreMission->heal);
00279 }
00280 }
00281
00285 void G_InvList_f (const player_t *player)
00286 {
00287 edict_t *ent = NULL;
00288
00289 gi.DPrintf("Print inventory for '%s'\n", player->pers.netname);
00290 while ((ent = G_EdictsGetNextLivingActorOfTeam(ent, player->pers.team))) {
00291 containerIndex_t container;
00292 gi.DPrintf("actor: '%s'\n", ent->chr.name);
00293
00294 for (container = 0; container < gi.csi->numIDs; container++) {
00295 const invList_t *ic = CONTAINER(ent, container);
00296 Com_Printf("Container: %i\n", container);
00297 while (ic) {
00298 Com_Printf(".. item.t: %i, item.m: %i, item.a: %i, x: %i, y: %i\n",
00299 (ic->item.t ? ic->item.t->idx : NONE), (ic->item.m ? ic->item.m->idx : NONE),
00300 ic->item.a, ic->x, ic->y);
00301 if (ic->item.t)
00302 Com_Printf(".... weapon: %s\n", ic->item.t->id);
00303 if (ic->item.m)
00304 Com_Printf(".... ammo: %s (%i)\n", ic->item.m->id, ic->item.a);
00305 ic = ic->next;
00306 }
00307 }
00308 }
00309 }
00310
00311 static void G_TouchEdict_f (void)
00312 {
00313 edict_t *e, *ent;
00314 int i;
00315
00316 if (gi.Cmd_Argc() < 2) {
00317 gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0));
00318 return;
00319 }
00320
00321 i = atoi(gi.Cmd_Argv(1));
00322 if (!G_EdictsIsValidNum(i))
00323 return;
00324
00325 e = G_EdictsGetByNum(i);
00326 if (!e->touch) {
00327 gi.DPrintf("No touch function for entity %s\n", e->classname);
00328 return;
00329 }
00330
00331 ent = G_EdictsGetNextLivingActor(NULL);
00332 if (!ent)
00333 return;
00334
00335 gi.DPrintf("Call touch function for %s\n", e->classname);
00336 e->touch(e, ent);
00337 }
00338
00339 static void G_UseEdict_f (void)
00340 {
00341 edict_t *e;
00342 int i;
00343
00344 if (gi.Cmd_Argc() < 2) {
00345 gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0));
00346 return;
00347 }
00348
00349 i = atoi(gi.Cmd_Argv(1));
00350 if (!G_EdictsIsValidNum(i)) {
00351 gi.DPrintf("No entity with number %i\n", i);
00352 return;
00353 }
00354
00355 e = G_EdictsGetByNum(i);
00356 if (!e->use) {
00357 gi.DPrintf("No use function for entity %s\n", e->classname);
00358 return;
00359 }
00360
00361 gi.DPrintf("Call use function for %s\n", e->classname);
00362 e->use(e, NULL);
00363 }
00364
00365 static void G_DestroyEdict_f (void)
00366 {
00367 edict_t *e;
00368 int i;
00369
00370 if (gi.Cmd_Argc() < 2) {
00371 gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0));
00372 return;
00373 }
00374
00375 i = atoi(gi.Cmd_Argv(1));
00376 if (!G_EdictsIsValidNum(i))
00377 return;
00378
00379 e = G_EdictsGetByNum(i);
00380 if (!e->destroy) {
00381 gi.DPrintf("No destroy function for entity %s\n", e->classname);
00382 return;
00383 }
00384
00385 gi.DPrintf("Call destroy function for %s\n", e->classname);
00386 e->destroy(e);
00387 }
00388
00389 #endif
00390
00391 void G_ClientCommand (player_t * player)
00392 {
00393 const char *cmd;
00394
00395 if (!player->inuse)
00396 return;
00397
00398 cmd = gi.Cmd_Argv(0);
00399
00400 if (Q_strcasecmp(cmd, "players") == 0)
00401 G_Players_f(player);
00402 else if (Q_strcasecmp(cmd, "say") == 0)
00403 G_Say_f(player, qfalse, qfalse);
00404 else if (Q_strcasecmp(cmd, "say_team") == 0)
00405 G_Say_f(player, qfalse, qtrue);
00406 #ifdef DEBUG
00407 else if (Q_strcasecmp(cmd, "debug_actorinvlist") == 0)
00408 G_InvList_f(player);
00409 else if (Q_strcasecmp(cmd, "debug_killteam") == 0)
00410 G_KillTeam_f();
00411 else if (Q_strcasecmp(cmd, "debug_stunteam") == 0)
00412 G_StunTeam_f();
00413 else if (Q_strcasecmp(cmd, "debug_listscore") == 0)
00414 G_ListMissionScore_f();
00415 else if (Q_strcasecmp(cmd, "debug_edicttouch") == 0)
00416 G_TouchEdict_f();
00417 else if (Q_strcasecmp(cmd, "debug_edictuse") == 0)
00418 G_UseEdict_f();
00419 else if (Q_strcasecmp(cmd, "debug_edictdestroy") == 0)
00420 G_DestroyEdict_f();
00421 #endif
00422 else
00423
00424 G_Say_f(player, qtrue, qfalse);
00425 }