g_cmds.c

Go to the documentation of this file.
00001 
00006 /*
00007 All original material Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 Original file from Quake 2 v3.21: quake2-2.31/game/g_cmds.c
00010 Copyright (C) 1997-2001 Id Software, Inc.
00011 
00012 This program is free software; you can redistribute it and/or
00013 modify it under the terms of the GNU General Public License
00014 as published by the Free Software Foundation; either version 2
00015 of the License, or (at your option) any later version.
00016 
00017 This program is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00020 
00021 See the GNU General Public License for more details.
00022 
00023 You should have received a copy of the GNU General Public License
00024 along with this program; if not, write to the Free Software
00025 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     /* print information */
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         /* can't print all of them in one packet */
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     /* default is to kill all teams */
00139     int teamToKill = -1;
00140     edict_t *ent = NULL;
00141 
00142     /* with a parameter we will be able to kill a specific team */
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             /* die */
00151             ent->HP = 0;
00152             G_ActorDieOrStun(ent, NULL);
00153         }
00154 
00155     /* check for win conditions */
00156     G_MatchEndCheck();
00157 }
00158 
00162 static void G_StunTeam_f (void)
00163 {
00164     /* default is to kill all teams */
00165     int teamToKill = -1;
00166     edict_t *ent = NULL;
00167 
00168     /* with a parameter we will be able to kill a specific team */
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             /* stun */
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     /* check for win conditions */
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     /* With a parameter we will be able to get the info for a specific team */
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; /* didn't find any */
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;                 /* not fully in game yet */
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         /* anything that doesn't match a command will be a chat */
00424         G_Say_f(player, qtrue, qfalse);
00425 }

Generated by  doxygen 1.6.2