/* ** c_cmds.cpp ** Miscellaneous console commands. ** **--------------------------------------------------------------------------- ** Copyright 1998-2006 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** 3. The name of the author may not be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** ** It might be a good idea to move these into files that they are more ** closely related to, but right now, I am too lazy to do that. */ #include #include #include #include #ifdef _WIN32 #include #else #include #endif #include "version.h" #include "c_console.h" #include "c_dispatch.h" #include "i_system.h" #include "doomstat.h" #include "gstrings.h" #include "s_sound.h" #include "g_game.h" #include "g_level.h" #include "w_wad.h" #include "g_level.h" #include "gi.h" #include "r_defs.h" #include "d_player.h" #include "r_main.h" #include "templates.h" #include "p_local.h" #include "r_sky.h" #include "p_setup.h" extern FILE *Logfile; extern bool insave; CVAR (Bool, sv_cheats, false, CVAR_SERVERINFO | CVAR_LATCH) CCMD (toggleconsole) { C_ToggleConsole(); } bool CheckCheatmode () { if (((gameskill == sk_nightmare) || netgame || deathmatch) && (!sv_cheats)) { Printf ("sv_cheats must be true to enable this command.\n"); return true; } else { return false; } } CCMD (quit) { if (!insave) exit (0); } CCMD (exit) { if (!insave) exit (0); } /* ================== Cmd_God Sets client to godmode argv(0) god ================== */ CCMD (god) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_GOD); } CCMD (iddqd) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_IDDQD); } CCMD (notarget) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_NOTARGET); } CCMD (fly) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_FLY); } /* ================== Cmd_Noclip argv(0) noclip ================== */ CCMD (noclip) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_NOCLIP); } CCMD (powerup) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_POWER); } CCMD (morphme) { if (CheckCheatmode ()) return; if (argv.argc() == 1) { Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_MORPH); } else { Net_WriteByte (DEM_MORPHEX); Net_WriteString (argv[1]); } } CCMD (anubis) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_ANUBIS); } // [GRB] CCMD (resurrect) { if (CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_RESSURECT); } EXTERN_CVAR (Bool, chasedemo) CCMD (chase) { if (demoplayback) { int i; if (chasedemo) { chasedemo = false; for (i = 0; i < MAXPLAYERS; i++) players[i].cheats &= ~CF_CHASECAM; } else { chasedemo = true; for (i = 0; i < MAXPLAYERS; i++) players[i].cheats |= CF_CHASECAM; } R_ResetViewInterpolation (); } else { if (deathmatch && CheckCheatmode ()) return; Net_WriteByte (DEM_GENERICCHEAT); Net_WriteByte (CHT_CHASECAM); } } CCMD (idclev) { if (CheckCheatmode () || netgame) return; if ((argv.argc() > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1]) { int epsd, map; char buf[2]; char *mapname; buf[0] = argv[1][0] - '0'; buf[1] = argv[1][1] - '0'; if (gameinfo.flags & GI_MAPxx) { epsd = 1; map = buf[0]*10 + buf[1]; } else { epsd = buf[0]; map = buf[1]; } // Catch invalid maps. mapname = CalcMapName (epsd, map); MapData * mapd = P_OpenMapData(mapname); if (mapd == NULL) return; // So be it. delete mapd; Printf ("%s\n", GStrings("STSTR_CLEV")); G_DeferedInitNew (mapname); players[0].health = 0; // Force reset } } CCMD (hxvisit) { if (CheckCheatmode ()) return; if ((argv.argc() > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1]) { char mapname[9]; sprintf (mapname, "&wt@%c%c", argv[1][0], argv[1][1]); if (CheckWarpTransMap (mapname, false)) { // Just because it's in MAPINFO doesn't mean it's in the wad. MapData * map = P_OpenMapData(mapname); if (map != NULL) { // So be it. delete map; Printf ("%s\n", GStrings("STSTR_CLEV")); G_DeferedInitNew (mapname); return; } } Printf ("No such map found\n"); } } CCMD (changemap) { if (who == NULL) { Printf ("Use the map command when not in a game.\n"); return; } if (who->player - players != Net_Arbitrator && multiplayer) { Printf ("Only player %d can change the map.\n", Net_Arbitrator+1); return; } if (argv.argc() > 1) { MapData * map = P_OpenMapData(argv[1]); if (map == NULL) { Printf ("No map %s\n", argv[1]); } else { delete map; if (argv.argc() > 2) { Net_WriteByte (DEM_CHANGEMAP2); Net_WriteByte (atoi(argv[2])); } else { Net_WriteByte (DEM_CHANGEMAP); } Net_WriteString (argv[1]); } } else { Printf ("Usage: changemap [position]\n"); } } CCMD (give) { if (CheckCheatmode () || argv.argc() < 2) return; Net_WriteByte (DEM_GIVECHEAT); Net_WriteString (argv[1]); if (argv.argc() > 2) Net_WriteWord (clamp (atoi (argv[2]), 1, 32767)); else Net_WriteWord (0); } CCMD (gameversion) { Printf ("%s : " __DATE__ "\n", DOTVERSIONSTR); } CCMD (print) { if (argv.argc() != 2) { Printf ("print : Print a string from the string table\n"); return; } const char *str = GStrings[argv[1]]; if (str == NULL) { Printf ("%s unknown\n", argv[1]); } else { Printf ("%s\n", str); } } CCMD (exec) { if (argv.argc() < 2) return; for (int i = 1; i < argv.argc(); ++i) { switch (C_ExecFile (argv[i], gamestate == GS_STARTUP)) { case 1: Printf ("Could not open \"%s\"\n", argv[1]); break; case 2: Printf ("Error parsing \"%s\"\n", argv[1]); break; default: break; } } } CCMD (logfile) { char *timestr = myasctime (); if (Logfile) { Printf ("Log stopped: %s\n", timestr); fclose (Logfile); Logfile = NULL; } if (argv.argc() >= 2) { if ( (Logfile = fopen (argv[1], "w")) ) { Printf ("Log started: %s\n", timestr); } else { Printf ("Could not start log\n"); } } } CCMD (puke) { int argc = argv.argc(); if (argc < 2 || argc > 5) { Printf (" puke