mirror of
https://github.com/dhewm/dhewm3-sdk.git
synced 2024-11-22 04:31:15 +00:00
afebd7e1e5
Don't include the lazy precompiled.h everywhere, only what's required for the compilation unit. platform.h needs to be included instead to provide all essential defines and types. All includes use the relative path to the neo or the game specific root. Move all idlib related includes from idlib/Lib.h to precompiled.h. precompiled.h still exists for the MFC stuff in tools/. Add some missing header guards.
2417 lines
62 KiB
C++
2417 lines
62 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "sys/platform.h"
|
|
#include "idlib/LangDict.h"
|
|
#include "framework/async/NetworkSystem.h"
|
|
#include "framework/FileSystem.h"
|
|
|
|
#include "gamesys/TypeInfo.h"
|
|
#include "gamesys/SysCvar.h"
|
|
#include "script/Script_Thread.h"
|
|
#include "ai/AI.h"
|
|
#include "anim/Anim_Testmodel.h"
|
|
#include "Entity.h"
|
|
#include "Moveable.h"
|
|
#include "WorldSpawn.h"
|
|
#include "Fx.h"
|
|
#include "Misc.h"
|
|
|
|
#include "SysCmds.h"
|
|
|
|
/*
|
|
==================
|
|
Cmd_GetFloatArg
|
|
==================
|
|
*/
|
|
float Cmd_GetFloatArg( const idCmdArgs &args, int &argNum ) {
|
|
const char *value;
|
|
|
|
value = args.Argv( argNum++ );
|
|
return atof( value );
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_EntityList_f
|
|
===================
|
|
*/
|
|
void Cmd_EntityList_f( const idCmdArgs &args ) {
|
|
int e;
|
|
idEntity *check;
|
|
int count;
|
|
size_t size;
|
|
idStr match;
|
|
|
|
if ( args.Argc() > 1 ) {
|
|
match = args.Args();
|
|
match.Replace( " ", "" );
|
|
} else {
|
|
match = "";
|
|
}
|
|
|
|
count = 0;
|
|
size = 0;
|
|
|
|
gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" );
|
|
gameLocal.Printf( "--------------------------------------------------------------------\n" );
|
|
for( e = 0; e < MAX_GENTITIES; e++ ) {
|
|
check = gameLocal.entities[ e ];
|
|
|
|
if ( !check ) {
|
|
continue;
|
|
}
|
|
|
|
if ( !check->name.Filter( match, true ) ) {
|
|
continue;
|
|
}
|
|
|
|
gameLocal.Printf( "%4i: %-20s %-20s %s\n", e,
|
|
check->GetEntityDefName(), check->GetClassname(), check->name.c_str() );
|
|
|
|
count++;
|
|
size += check->spawnArgs.Allocated();
|
|
}
|
|
|
|
gameLocal.Printf( "...%d entities\n...%zd bytes of spawnargs\n", count, size );
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_ActiveEntityList_f
|
|
===================
|
|
*/
|
|
void Cmd_ActiveEntityList_f( const idCmdArgs &args ) {
|
|
idEntity *check;
|
|
int count;
|
|
|
|
count = 0;
|
|
|
|
gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" );
|
|
gameLocal.Printf( "--------------------------------------------------------------------\n" );
|
|
for( check = gameLocal.activeEntities.Next(); check != NULL; check = check->activeNode.Next() ) {
|
|
char dormant = check->fl.isDormant ? '-' : ' ';
|
|
gameLocal.Printf( "%4i:%c%-20s %-20s %s\n", check->entityNumber, dormant, check->GetEntityDefName(), check->GetClassname(), check->name.c_str() );
|
|
count++;
|
|
}
|
|
|
|
gameLocal.Printf( "...%d active entities\n", count );
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_ListSpawnArgs_f
|
|
===================
|
|
*/
|
|
void Cmd_ListSpawnArgs_f( const idCmdArgs &args ) {
|
|
int i;
|
|
idEntity *ent;
|
|
|
|
ent = gameLocal.FindEntity( args.Argv( 1 ) );
|
|
if ( !ent ) {
|
|
gameLocal.Printf( "entity not found\n" );
|
|
return;
|
|
}
|
|
|
|
for ( i = 0; i < ent->spawnArgs.GetNumKeyVals(); i++ ) {
|
|
const idKeyValue *kv = ent->spawnArgs.GetKeyVal( i );
|
|
gameLocal.Printf( "\"%s\" "S_COLOR_WHITE"\"%s\"\n", kv->GetKey().c_str(), kv->GetValue().c_str() );
|
|
}
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_ReloadScript_f
|
|
===================
|
|
*/
|
|
void Cmd_ReloadScript_f( const idCmdArgs &args ) {
|
|
// shutdown the map because entities may point to script objects
|
|
gameLocal.MapShutdown();
|
|
|
|
// recompile the scripts
|
|
gameLocal.program.Startup( SCRIPT_DEFAULT );
|
|
|
|
// error out so that the user can rerun the scripts
|
|
gameLocal.Error( "Exiting map to reload scripts" );
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_Script_f
|
|
===================
|
|
*/
|
|
void Cmd_Script_f( const idCmdArgs &args ) {
|
|
const char * script;
|
|
idStr text;
|
|
idStr funcname;
|
|
static int funccount = 0;
|
|
idThread * thread;
|
|
const function_t *func;
|
|
idEntity *ent;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
sprintf( funcname, "ConsoleFunction_%d", funccount++ );
|
|
|
|
script = args.Args();
|
|
sprintf( text, "void %s() {%s;}\n", funcname.c_str(), script );
|
|
if ( gameLocal.program.CompileText( "console", text, true ) ) {
|
|
func = gameLocal.program.FindFunction( funcname );
|
|
if ( func ) {
|
|
// set all the entity names in case the user named one in the script that wasn't referenced in the default script
|
|
for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
|
|
gameLocal.program.SetEntity( ent->name, ent );
|
|
}
|
|
|
|
thread = new idThread( func );
|
|
thread->Start();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
KillEntities
|
|
|
|
Kills all the entities of the given class in a level.
|
|
==================
|
|
*/
|
|
void KillEntities( const idCmdArgs &args, const idTypeInfo &superClass ) {
|
|
idEntity *ent;
|
|
idStrList ignore;
|
|
const char *name;
|
|
int i;
|
|
|
|
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
|
|
for( i = 1; i < args.Argc(); i++ ) {
|
|
name = args.Argv( i );
|
|
ignore.Append( name );
|
|
}
|
|
|
|
for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
|
|
if ( ent->IsType( superClass ) ) {
|
|
for( i = 0; i < ignore.Num(); i++ ) {
|
|
if ( ignore[ i ] == ent->name ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( i >= ignore.Num() ) {
|
|
ent->PostEventMS( &EV_Remove, 0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_KillMonsters_f
|
|
|
|
Kills all the monsters in a level.
|
|
==================
|
|
*/
|
|
void Cmd_KillMonsters_f( const idCmdArgs &args ) {
|
|
KillEntities( args, idAI::Type );
|
|
|
|
// kill any projectiles as well since they have pointers to the monster that created them
|
|
KillEntities( args, idProjectile::Type );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_KillMovables_f
|
|
|
|
Kills all the moveables in a level.
|
|
==================
|
|
*/
|
|
void Cmd_KillMovables_f( const idCmdArgs &args ) {
|
|
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
KillEntities( args, idMoveable::Type );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_KillRagdolls_f
|
|
|
|
Kills all the ragdolls in a level.
|
|
==================
|
|
*/
|
|
void Cmd_KillRagdolls_f( const idCmdArgs &args ) {
|
|
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
KillEntities( args, idAFEntity_Generic::Type );
|
|
KillEntities( args, idAFEntity_WithAttachedHead::Type );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_Give_f
|
|
|
|
Give items to a client
|
|
==================
|
|
*/
|
|
void Cmd_Give_f( const idCmdArgs &args ) {
|
|
const char *name;
|
|
int i;
|
|
bool give_all;
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
name = args.Argv( 1 );
|
|
|
|
if ( idStr::Icmp( name, "all" ) == 0 ) {
|
|
give_all = true;
|
|
} else {
|
|
give_all = false;
|
|
}
|
|
|
|
if ( give_all || ( idStr::Cmpn( name, "weapon", 6 ) == 0 ) ) {
|
|
if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) {
|
|
gameLocal.world->spawnArgs.SetBool( "no_Weapons", false );
|
|
for( i = 0; i < gameLocal.numClients; i++ ) {
|
|
if ( gameLocal.entities[ i ] ) {
|
|
gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, gameLocal.entities[ i ]->spawnArgs.GetString( "def_weapon1" ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ( idStr::Cmpn( name, "weapon_", 7 ) == 0 ) || ( idStr::Cmpn( name, "item_", 5 ) == 0 ) || ( idStr::Cmpn( name, "ammo_", 5 ) == 0 ) ) {
|
|
player->GiveItem( name );
|
|
return;
|
|
}
|
|
|
|
if ( give_all || idStr::Icmp( name, "health" ) == 0 ) {
|
|
player->health = player->inventory.maxHealth;
|
|
if ( !give_all ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( give_all || idStr::Icmp( name, "weapons" ) == 0 ) {
|
|
player->inventory.weapons = BIT( MAX_WEAPONS ) - 1;
|
|
player->CacheWeapons();
|
|
|
|
if ( !give_all ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( give_all || idStr::Icmp( name, "ammo" ) == 0 ) {
|
|
for ( i = 0 ; i < AMMO_NUMTYPES; i++ ) {
|
|
player->inventory.ammo[ i ] = player->inventory.MaxAmmoForAmmoClass( player, idWeapon::GetAmmoNameForNum( ( ammo_t )i ) );
|
|
}
|
|
if ( !give_all ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( give_all || idStr::Icmp( name, "armor" ) == 0 ) {
|
|
player->inventory.armor = player->inventory.maxarmor;
|
|
if ( !give_all ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( idStr::Icmp( name, "berserk" ) == 0 ) {
|
|
player->GivePowerUp( BERSERK, SEC2MS( 30.0f ) );
|
|
return;
|
|
}
|
|
|
|
if ( idStr::Icmp( name, "invis" ) == 0 ) {
|
|
player->GivePowerUp( INVISIBILITY, SEC2MS( 30.0f ) );
|
|
return;
|
|
}
|
|
|
|
if ( idStr::Icmp( name, "pda" ) == 0 ) {
|
|
player->GivePDA( args.Argv(2), NULL );
|
|
return;
|
|
}
|
|
|
|
if ( idStr::Icmp( name, "video" ) == 0 ) {
|
|
player->GiveVideo( args.Argv(2), NULL );
|
|
return;
|
|
}
|
|
|
|
if ( !give_all && !player->Give( args.Argv(1), args.Argv(2) ) ) {
|
|
gameLocal.Printf( "unknown item\n" );
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_CenterView_f
|
|
|
|
Centers the players pitch
|
|
==================
|
|
*/
|
|
void Cmd_CenterView_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
idAngles ang;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player ) {
|
|
return;
|
|
}
|
|
|
|
ang = player->viewAngles;
|
|
ang.pitch = 0.0f;
|
|
player->SetViewAngles( ang );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_God_f
|
|
|
|
Sets client to godmode
|
|
|
|
argv(0) god
|
|
==================
|
|
*/
|
|
void Cmd_God_f( const idCmdArgs &args ) {
|
|
const char *msg;
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( player->godmode ) {
|
|
player->godmode = false;
|
|
msg = "godmode OFF\n";
|
|
} else {
|
|
player->godmode = true;
|
|
msg = "godmode ON\n";
|
|
}
|
|
|
|
gameLocal.Printf( "%s", msg );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_Notarget_f
|
|
|
|
Sets client to notarget
|
|
|
|
argv(0) notarget
|
|
==================
|
|
*/
|
|
void Cmd_Notarget_f( const idCmdArgs &args ) {
|
|
const char *msg;
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( player->fl.notarget ) {
|
|
player->fl.notarget = false;
|
|
msg = "notarget OFF\n";
|
|
} else {
|
|
player->fl.notarget = true;
|
|
msg = "notarget ON\n";
|
|
}
|
|
|
|
gameLocal.Printf( "%s", msg );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_Noclip_f
|
|
|
|
argv(0) noclip
|
|
==================
|
|
*/
|
|
void Cmd_Noclip_f( const idCmdArgs &args ) {
|
|
const char *msg;
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( player->noclip ) {
|
|
msg = "noclip OFF\n";
|
|
} else {
|
|
msg = "noclip ON\n";
|
|
}
|
|
player->noclip = !player->noclip;
|
|
|
|
gameLocal.Printf( "%s", msg );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Cmd_Kill_f
|
|
=================
|
|
*/
|
|
void Cmd_Kill_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
|
|
if ( gameLocal.isMultiplayer ) {
|
|
if ( gameLocal.isClient ) {
|
|
idBitMsg outMsg;
|
|
byte msgBuf[ MAX_GAME_MESSAGE_SIZE ];
|
|
outMsg.Init( msgBuf, sizeof( msgBuf ) );
|
|
outMsg.WriteByte( GAME_RELIABLE_MESSAGE_KILL );
|
|
networkSystem->ClientSendReliableMessage( outMsg );
|
|
} else {
|
|
player = gameLocal.GetClientByCmdArgs( args );
|
|
if ( !player ) {
|
|
common->Printf( "kill <client nickname> or kill <client index>\n" );
|
|
return;
|
|
}
|
|
player->Kill( false, false );
|
|
cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say killed client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
|
|
}
|
|
} else {
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player ) {
|
|
return;
|
|
}
|
|
player->Kill( false, false );
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Cmd_PlayerModel_f
|
|
=================
|
|
*/
|
|
void Cmd_PlayerModel_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
const char *name;
|
|
idVec3 pos;
|
|
idAngles ang;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() < 2 ) {
|
|
gameLocal.Printf( "usage: playerModel <modelname>\n" );
|
|
return;
|
|
}
|
|
|
|
name = args.Argv( 1 );
|
|
player->spawnArgs.Set( "model", name );
|
|
|
|
pos = player->GetPhysics()->GetOrigin();
|
|
ang = player->viewAngles;
|
|
player->SpawnToPoint( pos, ang );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_Say
|
|
==================
|
|
*/
|
|
static void Cmd_Say( bool team, const idCmdArgs &args ) {
|
|
const char *name;
|
|
idStr text;
|
|
const char *cmd = team ? "sayTeam" : "say" ;
|
|
|
|
if ( !gameLocal.isMultiplayer ) {
|
|
gameLocal.Printf( "%s can only be used in a multiplayer game\n", cmd );
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() < 2 ) {
|
|
gameLocal.Printf( "usage: %s <text>\n", cmd );
|
|
return;
|
|
}
|
|
|
|
text = args.Args();
|
|
if ( text.Length() == 0 ) {
|
|
return;
|
|
}
|
|
|
|
if ( text[ text.Length() - 1 ] == '\n' ) {
|
|
text[ text.Length() - 1 ] = '\0';
|
|
}
|
|
name = "player";
|
|
|
|
idPlayer * player;
|
|
|
|
// here we need to special case a listen server to use the real client name instead of "server"
|
|
// "server" will only appear on a dedicated server
|
|
if ( gameLocal.isClient || cvarSystem->GetCVarInteger( "net_serverDedicated" ) == 0 ) {
|
|
player = gameLocal.localClientNum >= 0 ? static_cast<idPlayer *>( gameLocal.entities[ gameLocal.localClientNum ] ) : NULL;
|
|
if ( player ) {
|
|
name = player->GetUserInfo()->GetString( "ui_name", "player" );
|
|
}
|
|
} else {
|
|
name = "server";
|
|
}
|
|
|
|
if ( gameLocal.isClient ) {
|
|
idBitMsg outMsg;
|
|
byte msgBuf[ 256 ];
|
|
outMsg.Init( msgBuf, sizeof( msgBuf ) );
|
|
outMsg.WriteByte( team ? GAME_RELIABLE_MESSAGE_TCHAT : GAME_RELIABLE_MESSAGE_CHAT );
|
|
outMsg.WriteString( name );
|
|
outMsg.WriteString( text, -1, false );
|
|
networkSystem->ClientSendReliableMessage( outMsg );
|
|
} else {
|
|
gameLocal.mpGame.ProcessChatMessage( gameLocal.localClientNum, team, name, text, NULL );
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_Say_f
|
|
==================
|
|
*/
|
|
static void Cmd_Say_f( const idCmdArgs &args ) {
|
|
Cmd_Say( false, args );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_SayTeam_f
|
|
==================
|
|
*/
|
|
static void Cmd_SayTeam_f( const idCmdArgs &args ) {
|
|
Cmd_Say( true, args );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_AddChatLine_f
|
|
==================
|
|
*/
|
|
static void Cmd_AddChatLine_f( const idCmdArgs &args ) {
|
|
gameLocal.mpGame.AddChatLine( args.Argv( 1 ) );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_Kick_f
|
|
==================
|
|
*/
|
|
static void Cmd_Kick_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
|
|
if ( !gameLocal.isMultiplayer ) {
|
|
gameLocal.Printf( "kick can only be used in a multiplayer game\n" );
|
|
return;
|
|
}
|
|
|
|
if ( gameLocal.isClient ) {
|
|
gameLocal.Printf( "You have no such power. This is a server command\n" );
|
|
return;
|
|
}
|
|
|
|
player = gameLocal.GetClientByCmdArgs( args );
|
|
if ( !player ) {
|
|
gameLocal.Printf( "usage: kick <client nickname> or kick <client index>\n" );
|
|
return;
|
|
}
|
|
cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say kicking out client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
|
|
cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "kick %d\n", player->entityNumber ) );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_GetViewpos_f
|
|
==================
|
|
*/
|
|
void Cmd_GetViewpos_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
idVec3 origin;
|
|
idMat3 axis;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player ) {
|
|
return;
|
|
}
|
|
|
|
const renderView_t *view = player->GetRenderView();
|
|
if ( view ) {
|
|
gameLocal.Printf( "(%s) %.1f\n", view->vieworg.ToString(), view->viewaxis[0].ToYaw() );
|
|
} else {
|
|
player->GetViewPos( origin, axis );
|
|
gameLocal.Printf( "(%s) %.1f\n", origin.ToString(), axis[0].ToYaw() );
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Cmd_SetViewpos_f
|
|
=================
|
|
*/
|
|
void Cmd_SetViewpos_f( const idCmdArgs &args ) {
|
|
idVec3 origin;
|
|
idAngles angles;
|
|
int i;
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( ( args.Argc() != 4 ) && ( args.Argc() != 5 ) ) {
|
|
gameLocal.Printf( "usage: setviewpos <x> <y> <z> <yaw>\n" );
|
|
return;
|
|
}
|
|
|
|
angles.Zero();
|
|
if ( args.Argc() == 5 ) {
|
|
angles.yaw = atof( args.Argv( 4 ) );
|
|
}
|
|
|
|
for ( i = 0 ; i < 3 ; i++ ) {
|
|
origin[i] = atof( args.Argv( i + 1 ) );
|
|
}
|
|
origin.z -= pm_normalviewheight.GetFloat() - 0.25f;
|
|
|
|
player->Teleport( origin, angles, NULL );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Cmd_Teleport_f
|
|
=================
|
|
*/
|
|
void Cmd_Teleport_f( const idCmdArgs &args ) {
|
|
idVec3 origin;
|
|
idAngles angles;
|
|
idPlayer *player;
|
|
idEntity *ent;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() != 2 ) {
|
|
gameLocal.Printf( "usage: teleport <name of entity to teleport to>\n" );
|
|
return;
|
|
}
|
|
|
|
ent = gameLocal.FindEntity( args.Argv( 1 ) );
|
|
if ( !ent ) {
|
|
gameLocal.Printf( "entity not found\n" );
|
|
return;
|
|
}
|
|
|
|
angles.Zero();
|
|
angles.yaw = ent->GetPhysics()->GetAxis()[ 0 ].ToYaw();
|
|
origin = ent->GetPhysics()->GetOrigin();
|
|
|
|
player->Teleport( origin, angles, ent );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Cmd_Trigger_f
|
|
=================
|
|
*/
|
|
void Cmd_Trigger_f( const idCmdArgs &args ) {
|
|
idVec3 origin;
|
|
idAngles angles;
|
|
idPlayer *player;
|
|
idEntity *ent;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() != 2 ) {
|
|
gameLocal.Printf( "usage: trigger <name of entity to trigger>\n" );
|
|
return;
|
|
}
|
|
|
|
ent = gameLocal.FindEntity( args.Argv( 1 ) );
|
|
if ( !ent ) {
|
|
gameLocal.Printf( "entity not found\n" );
|
|
return;
|
|
}
|
|
|
|
ent->Signal( SIG_TRIGGER );
|
|
ent->ProcessEvent( &EV_Activate, player );
|
|
ent->TriggerGuis();
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_Spawn_f
|
|
===================
|
|
*/
|
|
void Cmd_Spawn_f( const idCmdArgs &args ) {
|
|
const char *key, *value;
|
|
int i;
|
|
float yaw;
|
|
idVec3 org;
|
|
idPlayer *player;
|
|
idDict dict;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() & 1 ) { // must always have an even number of arguments
|
|
gameLocal.Printf( "usage: spawn classname [key/value pairs]\n" );
|
|
return;
|
|
}
|
|
|
|
yaw = player->viewAngles.yaw;
|
|
|
|
value = args.Argv( 1 );
|
|
dict.Set( "classname", value );
|
|
dict.Set( "angle", va( "%f", yaw + 180 ) );
|
|
|
|
org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 );
|
|
dict.Set( "origin", org.ToString() );
|
|
|
|
for( i = 2; i < args.Argc() - 1; i += 2 ) {
|
|
|
|
key = args.Argv( i );
|
|
value = args.Argv( i + 1 );
|
|
|
|
dict.Set( key, value );
|
|
}
|
|
|
|
gameLocal.SpawnEntityDef( dict );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_Damage_f
|
|
|
|
Damages the specified entity
|
|
==================
|
|
*/
|
|
void Cmd_Damage_f( const idCmdArgs &args ) {
|
|
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
if ( args.Argc() != 3 ) {
|
|
gameLocal.Printf( "usage: damage <name of entity to damage> <damage>\n" );
|
|
return;
|
|
}
|
|
|
|
idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) );
|
|
if ( !ent ) {
|
|
gameLocal.Printf( "entity not found\n" );
|
|
return;
|
|
}
|
|
|
|
ent->Damage( gameLocal.world, gameLocal.world, idVec3( 0, 0, 1 ), "damage_moverCrush", atoi( args.Argv( 2 ) ), INVALID_JOINT );
|
|
}
|
|
|
|
|
|
/*
|
|
==================
|
|
Cmd_Remove_f
|
|
|
|
Removes the specified entity
|
|
==================
|
|
*/
|
|
void Cmd_Remove_f( const idCmdArgs &args ) {
|
|
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
if ( args.Argc() != 2 ) {
|
|
gameLocal.Printf( "usage: remove <name of entity to remove>\n" );
|
|
return;
|
|
}
|
|
|
|
idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) );
|
|
if ( !ent ) {
|
|
gameLocal.Printf( "entity not found\n" );
|
|
return;
|
|
}
|
|
|
|
delete ent;
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_TestLight_f
|
|
===================
|
|
*/
|
|
void Cmd_TestLight_f( const idCmdArgs &args ) {
|
|
int i;
|
|
idStr filename;
|
|
const char *key, *value, *name;
|
|
idPlayer * player;
|
|
idDict dict;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
|
|
renderView_t *rv = player->GetRenderView();
|
|
|
|
float fov = tan( idMath::M_DEG2RAD * rv->fov_x / 2 );
|
|
|
|
|
|
dict.SetMatrix( "rotation", mat3_default );
|
|
dict.SetVector( "origin", rv->vieworg );
|
|
dict.SetVector( "light_target", rv->viewaxis[0] );
|
|
dict.SetVector( "light_right", rv->viewaxis[1] * -fov );
|
|
dict.SetVector( "light_up", rv->viewaxis[2] * fov );
|
|
dict.SetVector( "light_start", rv->viewaxis[0] * 16 );
|
|
dict.SetVector( "light_end", rv->viewaxis[0] * 1000 );
|
|
|
|
if ( args.Argc() >= 2 ) {
|
|
value = args.Argv( 1 );
|
|
filename = args.Argv(1);
|
|
filename.DefaultFileExtension( ".tga" );
|
|
dict.Set( "texture", filename );
|
|
}
|
|
|
|
dict.Set( "classname", "light" );
|
|
for( i = 2; i < args.Argc() - 1; i += 2 ) {
|
|
|
|
key = args.Argv( i );
|
|
value = args.Argv( i + 1 );
|
|
|
|
dict.Set( key, value );
|
|
}
|
|
|
|
for ( i = 0; i < MAX_GENTITIES; i++ ) {
|
|
name = va( "spawned_light_%d", i ); // not just light_, or it might pick up a prelight shadow
|
|
if ( !gameLocal.FindEntity( name ) ) {
|
|
break;
|
|
}
|
|
}
|
|
dict.Set( "name", name );
|
|
|
|
gameLocal.SpawnEntityDef( dict );
|
|
|
|
gameLocal.Printf( "Created new light\n");
|
|
}
|
|
|
|
/*
|
|
===================
|
|
Cmd_TestPointLight_f
|
|
===================
|
|
*/
|
|
void Cmd_TestPointLight_f( const idCmdArgs &args ) {
|
|
const char *key, *value, *name;
|
|
int i;
|
|
idPlayer *player;
|
|
idDict dict;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
|
|
dict.SetVector("origin", player->GetRenderView()->vieworg);
|
|
|
|
if ( args.Argc() >= 2 ) {
|
|
value = args.Argv( 1 );
|
|
dict.Set("light", value);
|
|
} else {
|
|
dict.Set("light", "300");
|
|
}
|
|
|
|
dict.Set( "classname", "light" );
|
|
for( i = 2; i < args.Argc() - 1; i += 2 ) {
|
|
|
|
key = args.Argv( i );
|
|
value = args.Argv( i + 1 );
|
|
|
|
dict.Set( key, value );
|
|
}
|
|
|
|
for ( i = 0; i < MAX_GENTITIES; i++ ) {
|
|
name = va( "light_%d", i );
|
|
if ( !gameLocal.FindEntity( name ) ) {
|
|
break;
|
|
}
|
|
}
|
|
dict.Set( "name", name );
|
|
|
|
gameLocal.SpawnEntityDef( dict );
|
|
|
|
gameLocal.Printf( "Created new point light\n");
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_PopLight_f
|
|
==================
|
|
*/
|
|
void Cmd_PopLight_f( const idCmdArgs &args ) {
|
|
idEntity *ent;
|
|
idMapEntity *mapEnt;
|
|
idMapFile *mapFile = gameLocal.GetLevelMap();
|
|
idLight *lastLight;
|
|
int last;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
bool removeFromMap = ( args.Argc() > 1 );
|
|
|
|
lastLight = NULL;
|
|
last = -1;
|
|
for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
|
|
if ( !ent->IsType( idLight::Type ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( gameLocal.spawnIds[ ent->entityNumber ] > last ) {
|
|
last = gameLocal.spawnIds[ ent->entityNumber ];
|
|
lastLight = static_cast<idLight*>( ent );
|
|
}
|
|
}
|
|
|
|
if ( lastLight ) {
|
|
// find map file entity
|
|
mapEnt = mapFile->FindEntity( lastLight->name );
|
|
|
|
if ( removeFromMap && mapEnt ) {
|
|
mapFile->RemoveEntity( mapEnt );
|
|
}
|
|
gameLocal.Printf( "Removing light %i\n", lastLight->GetLightDefHandle() );
|
|
delete lastLight;
|
|
} else {
|
|
gameLocal.Printf( "No lights to clear.\n" );
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
====================
|
|
Cmd_ClearLights_f
|
|
====================
|
|
*/
|
|
void Cmd_ClearLights_f( const idCmdArgs &args ) {
|
|
idEntity *ent;
|
|
idEntity *next;
|
|
idLight *light;
|
|
idMapEntity *mapEnt;
|
|
idMapFile *mapFile = gameLocal.GetLevelMap();
|
|
|
|
bool removeFromMap = ( args.Argc() > 1 );
|
|
|
|
gameLocal.Printf( "Clearing all lights.\n" );
|
|
for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = next ) {
|
|
next = ent->spawnNode.Next();
|
|
if ( !ent->IsType( idLight::Type ) ) {
|
|
continue;
|
|
}
|
|
|
|
light = static_cast<idLight*>( ent );
|
|
mapEnt = mapFile->FindEntity( light->name );
|
|
|
|
if ( removeFromMap && mapEnt ) {
|
|
mapFile->RemoveEntity( mapEnt );
|
|
}
|
|
|
|
delete light;
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_TestFx_f
|
|
==================
|
|
*/
|
|
void Cmd_TestFx_f( const idCmdArgs &args ) {
|
|
idVec3 offset;
|
|
const char *name;
|
|
idPlayer * player;
|
|
idDict dict;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
// delete the testModel if active
|
|
if ( gameLocal.testFx ) {
|
|
delete gameLocal.testFx;
|
|
gameLocal.testFx = NULL;
|
|
}
|
|
|
|
if ( args.Argc() < 2 ) {
|
|
return;
|
|
}
|
|
|
|
name = args.Argv( 1 );
|
|
|
|
offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f;
|
|
|
|
dict.Set( "origin", offset.ToString() );
|
|
dict.Set( "test", "1");
|
|
dict.Set( "fx", name );
|
|
gameLocal.testFx = ( idEntityFx * )gameLocal.SpawnEntityType( idEntityFx::Type, &dict );
|
|
}
|
|
|
|
#define MAX_DEBUGLINES 128
|
|
|
|
typedef struct {
|
|
bool used;
|
|
idVec3 start, end;
|
|
int color;
|
|
bool blink;
|
|
bool arrow;
|
|
} gameDebugLine_t;
|
|
|
|
gameDebugLine_t debugLines[MAX_DEBUGLINES];
|
|
|
|
/*
|
|
==================
|
|
Cmd_AddDebugLine_f
|
|
==================
|
|
*/
|
|
static void Cmd_AddDebugLine_f( const idCmdArgs &args ) {
|
|
int i, argNum;
|
|
const char *value;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc () < 7 ) {
|
|
gameLocal.Printf( "usage: addline <x y z> <x y z> <color>\n" );
|
|
return;
|
|
}
|
|
for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
|
|
if ( !debugLines[i].used ) {
|
|
break;
|
|
}
|
|
}
|
|
if ( i >= MAX_DEBUGLINES ) {
|
|
gameLocal.Printf( "no free debug lines\n" );
|
|
return;
|
|
}
|
|
value = args.Argv( 0 );
|
|
if ( !idStr::Icmp( value, "addarrow" ) ) {
|
|
debugLines[i].arrow = true;
|
|
} else {
|
|
debugLines[i].arrow = false;
|
|
}
|
|
debugLines[i].used = true;
|
|
debugLines[i].blink = false;
|
|
argNum = 1;
|
|
debugLines[i].start.x = Cmd_GetFloatArg( args, argNum );
|
|
debugLines[i].start.y = Cmd_GetFloatArg( args, argNum );
|
|
debugLines[i].start.z = Cmd_GetFloatArg( args, argNum );
|
|
debugLines[i].end.x = Cmd_GetFloatArg( args, argNum );
|
|
debugLines[i].end.y = Cmd_GetFloatArg( args, argNum );
|
|
debugLines[i].end.z = Cmd_GetFloatArg( args, argNum );
|
|
debugLines[i].color = Cmd_GetFloatArg( args, argNum );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_RemoveDebugLine_f
|
|
==================
|
|
*/
|
|
static void Cmd_RemoveDebugLine_f( const idCmdArgs &args ) {
|
|
int i, num;
|
|
const char *value;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc () < 2 ) {
|
|
gameLocal.Printf( "usage: removeline <num>\n" );
|
|
return;
|
|
}
|
|
value = args.Argv( 1 );
|
|
num = atoi(value);
|
|
for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
|
|
if ( debugLines[i].used ) {
|
|
if ( --num < 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ( i >= MAX_DEBUGLINES ) {
|
|
gameLocal.Printf( "line not found\n" );
|
|
return;
|
|
}
|
|
debugLines[i].used = false;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_BlinkDebugLine_f
|
|
==================
|
|
*/
|
|
static void Cmd_BlinkDebugLine_f( const idCmdArgs &args ) {
|
|
int i, num;
|
|
const char *value;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc () < 2 ) {
|
|
gameLocal.Printf( "usage: blinkline <num>\n" );
|
|
return;
|
|
}
|
|
value = args.Argv( 1 );
|
|
num = atoi( value );
|
|
for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
|
|
if ( debugLines[i].used ) {
|
|
if ( --num < 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ( i >= MAX_DEBUGLINES ) {
|
|
gameLocal.Printf( "line not found\n" );
|
|
return;
|
|
}
|
|
debugLines[i].blink = !debugLines[i].blink;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
PrintFloat
|
|
==================
|
|
*/
|
|
static void PrintFloat( float f ) {
|
|
char buf[128];
|
|
int i;
|
|
|
|
for ( i = sprintf( buf, "%3.2f", f ); i < 7; i++ ) {
|
|
buf[i] = ' ';
|
|
}
|
|
buf[i] = '\0';
|
|
gameLocal.Printf( buf );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_ListDebugLines_f
|
|
==================
|
|
*/
|
|
static void Cmd_ListDebugLines_f( const idCmdArgs &args ) {
|
|
int i, num;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
num = 0;
|
|
gameLocal.Printf( "line num: x1 y1 z1 x2 y2 z2 c b a\n" );
|
|
for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
|
|
if ( debugLines[i].used ) {
|
|
gameLocal.Printf( "line %3d: ", num );
|
|
PrintFloat( debugLines[i].start.x );
|
|
PrintFloat( debugLines[i].start.y );
|
|
PrintFloat( debugLines[i].start.z );
|
|
PrintFloat( debugLines[i].end.x );
|
|
PrintFloat( debugLines[i].end.y );
|
|
PrintFloat( debugLines[i].end.z );
|
|
gameLocal.Printf( "%d %d %d\n", debugLines[i].color, debugLines[i].blink, debugLines[i].arrow );
|
|
num++;
|
|
}
|
|
}
|
|
if ( !num ) {
|
|
gameLocal.Printf( "no debug lines\n" );
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
D_DrawDebugLines
|
|
==================
|
|
*/
|
|
void D_DrawDebugLines( void ) {
|
|
int i;
|
|
idVec3 forward, right, up, p1, p2;
|
|
idVec4 color;
|
|
float l;
|
|
|
|
for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
|
|
if ( debugLines[i].used ) {
|
|
if ( !debugLines[i].blink || (gameLocal.time & (1<<9)) ) {
|
|
color = idVec4( debugLines[i].color&1, (debugLines[i].color>>1)&1, (debugLines[i].color>>2)&1, 1 );
|
|
gameRenderWorld->DebugLine( color, debugLines[i].start, debugLines[i].end );
|
|
//
|
|
if ( debugLines[i].arrow ) {
|
|
// draw a nice arrow
|
|
forward = debugLines[i].end - debugLines[i].start;
|
|
l = forward.Normalize() * 0.2f;
|
|
forward.NormalVectors( right, up);
|
|
|
|
if ( l > 3.0f ) {
|
|
l = 3.0f;
|
|
}
|
|
p1 = debugLines[i].end - l * forward + (l * 0.4f) * right;
|
|
p2 = debugLines[i].end - l * forward - (l * 0.4f) * right;
|
|
gameRenderWorld->DebugLine( color, debugLines[i].end, p1 );
|
|
gameRenderWorld->DebugLine( color, debugLines[i].end, p2 );
|
|
gameRenderWorld->DebugLine( color, p1, p2 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_ListCollisionModels_f
|
|
==================
|
|
*/
|
|
static void Cmd_ListCollisionModels_f( const idCmdArgs &args ) {
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
collisionModelManager->ListModels();
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_CollisionModelInfo_f
|
|
==================
|
|
*/
|
|
static void Cmd_CollisionModelInfo_f( const idCmdArgs &args ) {
|
|
const char *value;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc () < 2 ) {
|
|
gameLocal.Printf( "usage: collisionModelInfo <modelNum>\n"
|
|
"use 'all' instead of the model number for accumulated info\n" );
|
|
return;
|
|
}
|
|
|
|
value = args.Argv( 1 );
|
|
if ( !idStr::Icmp( value, "all" ) ) {
|
|
collisionModelManager->ModelInfo( -1 );
|
|
} else {
|
|
collisionModelManager->ModelInfo( atoi(value) );
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_ExportModels_f
|
|
==================
|
|
*/
|
|
static void Cmd_ExportModels_f( const idCmdArgs &args ) {
|
|
idModelExport exporter;
|
|
idStr name;
|
|
|
|
// don't allow exporting models when cheats are disabled,
|
|
// but if we're not in the game, it's ok
|
|
if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() < 2 ) {
|
|
exporter.ExportModels( "def", ".def" );
|
|
} else {
|
|
name = args.Argv( 1 );
|
|
name = "def/" + name;
|
|
name.DefaultFileExtension( ".def" );
|
|
exporter.ExportDefFile( name );
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_ReexportModels_f
|
|
==================
|
|
*/
|
|
static void Cmd_ReexportModels_f( const idCmdArgs &args ) {
|
|
idModelExport exporter;
|
|
idStr name;
|
|
|
|
// don't allow exporting models when cheats are disabled,
|
|
// but if we're not in the game, it's ok
|
|
if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
|
|
idAnimManager::forceExport = true;
|
|
if ( args.Argc() < 2 ) {
|
|
exporter.ExportModels( "def", ".def" );
|
|
} else {
|
|
name = args.Argv( 1 );
|
|
name = "def/" + name;
|
|
name.DefaultFileExtension( ".def" );
|
|
exporter.ExportDefFile( name );
|
|
}
|
|
idAnimManager::forceExport = false;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_ReloadAnims_f
|
|
==================
|
|
*/
|
|
static void Cmd_ReloadAnims_f( const idCmdArgs &args ) {
|
|
// don't allow reloading anims when cheats are disabled,
|
|
// but if we're not in the game, it's ok
|
|
if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
|
|
return;
|
|
}
|
|
|
|
animationLib.ReloadAnims();
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_ListAnims_f
|
|
==================
|
|
*/
|
|
static void Cmd_ListAnims_f( const idCmdArgs &args ) {
|
|
idEntity * ent;
|
|
int num;
|
|
size_t size;
|
|
size_t alloced;
|
|
idAnimator * animator;
|
|
const char * classname;
|
|
const idDict * dict;
|
|
int i;
|
|
|
|
if ( args.Argc() > 1 ) {
|
|
idAnimator animator;
|
|
|
|
classname = args.Argv( 1 );
|
|
|
|
dict = gameLocal.FindEntityDefDict( classname, false );
|
|
if ( !dict ) {
|
|
gameLocal.Printf( "Entitydef '%s' not found\n", classname );
|
|
return;
|
|
}
|
|
animator.SetModel( dict->GetString( "model" ) );
|
|
|
|
gameLocal.Printf( "----------------\n" );
|
|
num = animator.NumAnims();
|
|
for( i = 0; i < num; i++ ) {
|
|
gameLocal.Printf( "%s\n", animator.AnimFullName( i ) );
|
|
}
|
|
gameLocal.Printf( "%d anims\n", num );
|
|
} else {
|
|
animationLib.ListAnims();
|
|
|
|
size = 0;
|
|
num = 0;
|
|
for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
|
|
animator = ent->GetAnimator();
|
|
if ( animator ) {
|
|
alloced = animator->Allocated();
|
|
size += alloced;
|
|
num++;
|
|
}
|
|
}
|
|
|
|
gameLocal.Printf( "%zd memory used in %d entity animators\n", size, num );
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_AASStats_f
|
|
==================
|
|
*/
|
|
static void Cmd_AASStats_f( const idCmdArgs &args ) {
|
|
int aasNum;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
aasNum = aas_test.GetInteger();
|
|
idAAS *aas = gameLocal.GetAAS( aasNum );
|
|
if ( !aas ) {
|
|
gameLocal.Printf( "No aas #%d loaded\n", aasNum );
|
|
} else {
|
|
aas->Stats();
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_TestDamage_f
|
|
==================
|
|
*/
|
|
static void Cmd_TestDamage_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
const char *damageDefName;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() < 2 || args.Argc() > 3 ) {
|
|
gameLocal.Printf( "usage: testDamage <damageDefName> [angle]\n" );
|
|
return;
|
|
}
|
|
|
|
damageDefName = args.Argv( 1 );
|
|
|
|
idVec3 dir;
|
|
if ( args.Argc() == 3 ) {
|
|
float angle = atof( args.Argv( 2 ) );
|
|
|
|
idMath::SinCos( DEG2RAD( angle ), dir[1], dir[0] );
|
|
dir[2] = 0;
|
|
} else {
|
|
dir.Zero();
|
|
}
|
|
|
|
// give the player full health before and after
|
|
// running the damage
|
|
player->health = player->inventory.maxHealth;
|
|
player->Damage( NULL, NULL, dir, damageDefName, 1.0f, INVALID_JOINT );
|
|
player->health = player->inventory.maxHealth;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_TestBoneFx_f
|
|
==================
|
|
*/
|
|
static void Cmd_TestBoneFx_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
const char *bone, *fx;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() < 3 || args.Argc() > 4 ) {
|
|
gameLocal.Printf( "usage: testBoneFx <fxName> <boneName>\n" );
|
|
return;
|
|
}
|
|
|
|
fx = args.Argv( 1 );
|
|
bone = args.Argv( 2 );
|
|
|
|
player->StartFxOnBone( fx, bone );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_TestDamage_f
|
|
==================
|
|
*/
|
|
static void Cmd_TestDeath_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
idVec3 dir;
|
|
idMath::SinCos( DEG2RAD( 45.0f ), dir[1], dir[0] );
|
|
dir[2] = 0;
|
|
|
|
g_testDeath.SetBool( 1 );
|
|
player->Damage( NULL, NULL, dir, "damage_triggerhurt_1000", 1.0f, INVALID_JOINT );
|
|
if ( args.Argc() >= 2) {
|
|
player->SpawnGibs( dir, "damage_triggerhurt_1000" );
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_WeaponSplat_f
|
|
==================
|
|
*/
|
|
static void Cmd_WeaponSplat_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
player->weapon.GetEntity()->BloodSplat( 2.0f );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_SaveSelected_f
|
|
==================
|
|
*/
|
|
static void Cmd_SaveSelected_f( const idCmdArgs &args ) {
|
|
int i;
|
|
idPlayer *player;
|
|
idEntity *s;
|
|
idMapEntity *mapEnt;
|
|
idMapFile *mapFile = gameLocal.GetLevelMap();
|
|
idDict dict;
|
|
idStr mapName;
|
|
const char *name;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
s = player->dragEntity.GetSelected();
|
|
if ( !s ) {
|
|
gameLocal.Printf( "no entity selected, set g_dragShowSelection 1 to show the current selection\n" );
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() > 1 ) {
|
|
mapName = args.Argv( 1 );
|
|
mapName = "maps/" + mapName;
|
|
}
|
|
else {
|
|
mapName = mapFile->GetName();
|
|
}
|
|
|
|
// find map file entity
|
|
mapEnt = mapFile->FindEntity( s->name );
|
|
// create new map file entity if there isn't one for this articulated figure
|
|
if ( !mapEnt ) {
|
|
mapEnt = new idMapEntity();
|
|
mapFile->AddEntity( mapEnt );
|
|
for ( i = 0; i < 9999; i++ ) {
|
|
name = va( "%s_%d", s->GetEntityDefName(), i );
|
|
if ( !gameLocal.FindEntity( name ) ) {
|
|
break;
|
|
}
|
|
}
|
|
s->name = name;
|
|
mapEnt->epairs.Set( "classname", s->GetEntityDefName() );
|
|
mapEnt->epairs.Set( "name", s->name );
|
|
}
|
|
|
|
if ( s->IsType( idMoveable::Type ) ) {
|
|
// save the moveable state
|
|
mapEnt->epairs.Set( "origin", s->GetPhysics()->GetOrigin().ToString( 8 ) );
|
|
mapEnt->epairs.Set( "rotation", s->GetPhysics()->GetAxis().ToString( 8 ) );
|
|
}
|
|
else if ( s->IsType( idAFEntity_Generic::Type ) || s->IsType( idAFEntity_WithAttachedHead::Type ) ) {
|
|
// save the articulated figure state
|
|
dict.Clear();
|
|
static_cast<idAFEntity_Base *>(s)->SaveState( dict );
|
|
mapEnt->epairs.Copy( dict );
|
|
}
|
|
|
|
// write out the map file
|
|
mapFile->Write( mapName, ".map" );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_DeleteSelected_f
|
|
==================
|
|
*/
|
|
static void Cmd_DeleteSelected_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( player ) {
|
|
player->dragEntity.DeleteSelected();
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_SaveMoveables_f
|
|
==================
|
|
*/
|
|
static void Cmd_SaveMoveables_f( const idCmdArgs &args ) {
|
|
int e, i;
|
|
idMoveable *m;
|
|
idMapEntity *mapEnt;
|
|
idMapFile *mapFile = gameLocal.GetLevelMap();
|
|
idStr mapName;
|
|
const char *name;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
for( e = 0; e < MAX_GENTITIES; e++ ) {
|
|
m = static_cast<idMoveable *>(gameLocal.entities[ e ]);
|
|
|
|
if ( !m || !m->IsType( idMoveable::Type ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( m->IsBound() ) {
|
|
continue;
|
|
}
|
|
|
|
if ( !m->IsAtRest() ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( e < MAX_GENTITIES ) {
|
|
gameLocal.Warning( "map not saved because the moveable entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() );
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() > 1 ) {
|
|
mapName = args.Argv( 1 );
|
|
mapName = "maps/" + mapName;
|
|
}
|
|
else {
|
|
mapName = mapFile->GetName();
|
|
}
|
|
|
|
for( e = 0; e < MAX_GENTITIES; e++ ) {
|
|
m = static_cast<idMoveable *>(gameLocal.entities[ e ]);
|
|
|
|
if ( !m || !m->IsType( idMoveable::Type ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( m->IsBound() ) {
|
|
continue;
|
|
}
|
|
|
|
// find map file entity
|
|
mapEnt = mapFile->FindEntity( m->name );
|
|
// create new map file entity if there isn't one for this articulated figure
|
|
if ( !mapEnt ) {
|
|
mapEnt = new idMapEntity();
|
|
mapFile->AddEntity( mapEnt );
|
|
for ( i = 0; i < 9999; i++ ) {
|
|
name = va( "%s_%d", m->GetEntityDefName(), i );
|
|
if ( !gameLocal.FindEntity( name ) ) {
|
|
break;
|
|
}
|
|
}
|
|
m->name = name;
|
|
mapEnt->epairs.Set( "classname", m->GetEntityDefName() );
|
|
mapEnt->epairs.Set( "name", m->name );
|
|
}
|
|
// save the moveable state
|
|
mapEnt->epairs.Set( "origin", m->GetPhysics()->GetOrigin().ToString( 8 ) );
|
|
mapEnt->epairs.Set( "rotation", m->GetPhysics()->GetAxis().ToString( 8 ) );
|
|
}
|
|
|
|
// write out the map file
|
|
mapFile->Write( mapName, ".map" );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_SaveRagdolls_f
|
|
==================
|
|
*/
|
|
static void Cmd_SaveRagdolls_f( const idCmdArgs &args ) {
|
|
int e, i;
|
|
idAFEntity_Base *af;
|
|
idMapEntity *mapEnt;
|
|
idMapFile *mapFile = gameLocal.GetLevelMap();
|
|
idDict dict;
|
|
idStr mapName;
|
|
const char *name;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() > 1 ) {
|
|
mapName = args.Argv( 1 );
|
|
mapName = "maps/" + mapName;
|
|
}
|
|
else {
|
|
mapName = mapFile->GetName();
|
|
}
|
|
|
|
for( e = 0; e < MAX_GENTITIES; e++ ) {
|
|
af = static_cast<idAFEntity_Base *>(gameLocal.entities[ e ]);
|
|
|
|
if ( !af ) {
|
|
continue;
|
|
}
|
|
|
|
if ( !af->IsType( idAFEntity_WithAttachedHead::Type ) && !af->IsType( idAFEntity_Generic::Type ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( af->IsBound() ) {
|
|
continue;
|
|
}
|
|
|
|
if ( !af->IsAtRest() ) {
|
|
gameLocal.Warning( "the articulated figure for entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() );
|
|
}
|
|
|
|
dict.Clear();
|
|
af->SaveState( dict );
|
|
|
|
// find map file entity
|
|
mapEnt = mapFile->FindEntity( af->name );
|
|
// create new map file entity if there isn't one for this articulated figure
|
|
if ( !mapEnt ) {
|
|
mapEnt = new idMapEntity();
|
|
mapFile->AddEntity( mapEnt );
|
|
for ( i = 0; i < 9999; i++ ) {
|
|
name = va( "%s_%d", af->GetEntityDefName(), i );
|
|
if ( !gameLocal.FindEntity( name ) ) {
|
|
break;
|
|
}
|
|
}
|
|
af->name = name;
|
|
mapEnt->epairs.Set( "classname", af->GetEntityDefName() );
|
|
mapEnt->epairs.Set( "name", af->name );
|
|
}
|
|
// save the articulated figure state
|
|
mapEnt->epairs.Copy( dict );
|
|
}
|
|
|
|
// write out the map file
|
|
mapFile->Write( mapName, ".map" );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_BindRagdoll_f
|
|
==================
|
|
*/
|
|
static void Cmd_BindRagdoll_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( player ) {
|
|
player->dragEntity.BindSelected();
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_UnbindRagdoll_f
|
|
==================
|
|
*/
|
|
static void Cmd_UnbindRagdoll_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( player ) {
|
|
player->dragEntity.UnbindSelected();
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_GameError_f
|
|
==================
|
|
*/
|
|
static void Cmd_GameError_f( const idCmdArgs &args ) {
|
|
gameLocal.Error( "game error" );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_SaveLights_f
|
|
==================
|
|
*/
|
|
static void Cmd_SaveLights_f( const idCmdArgs &args ) {
|
|
int e, i;
|
|
idLight *light;
|
|
idMapEntity *mapEnt;
|
|
idMapFile *mapFile = gameLocal.GetLevelMap();
|
|
idDict dict;
|
|
idStr mapName;
|
|
const char *name;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() > 1 ) {
|
|
mapName = args.Argv( 1 );
|
|
mapName = "maps/" + mapName;
|
|
}
|
|
else {
|
|
mapName = mapFile->GetName();
|
|
}
|
|
|
|
for( e = 0; e < MAX_GENTITIES; e++ ) {
|
|
light = static_cast<idLight*>(gameLocal.entities[ e ]);
|
|
|
|
if ( !light || !light->IsType( idLight::Type ) ) {
|
|
continue;
|
|
}
|
|
|
|
dict.Clear();
|
|
light->SaveState( &dict );
|
|
|
|
// find map file entity
|
|
mapEnt = mapFile->FindEntity( light->name );
|
|
// create new map file entity if there isn't one for this light
|
|
if ( !mapEnt ) {
|
|
mapEnt = new idMapEntity();
|
|
mapFile->AddEntity( mapEnt );
|
|
for ( i = 0; i < 9999; i++ ) {
|
|
name = va( "%s_%d", light->GetEntityDefName(), i );
|
|
if ( !gameLocal.FindEntity( name ) ) {
|
|
break;
|
|
}
|
|
}
|
|
light->name = name;
|
|
mapEnt->epairs.Set( "classname", light->GetEntityDefName() );
|
|
mapEnt->epairs.Set( "name", light->name );
|
|
}
|
|
// save the light state
|
|
mapEnt->epairs.Copy( dict );
|
|
}
|
|
|
|
// write out the map file
|
|
mapFile->Write( mapName, ".map" );
|
|
}
|
|
|
|
|
|
/*
|
|
==================
|
|
Cmd_SaveParticles_f
|
|
==================
|
|
*/
|
|
static void Cmd_SaveParticles_f( const idCmdArgs &args ) {
|
|
int e;
|
|
idEntity *ent;
|
|
idMapEntity *mapEnt;
|
|
idMapFile *mapFile = gameLocal.GetLevelMap();
|
|
idDict dict;
|
|
idStr mapName, strModel;
|
|
|
|
if ( !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() > 1 ) {
|
|
mapName = args.Argv( 1 );
|
|
mapName = "maps/" + mapName;
|
|
}
|
|
else {
|
|
mapName = mapFile->GetName();
|
|
}
|
|
|
|
for( e = 0; e < MAX_GENTITIES; e++ ) {
|
|
|
|
ent = static_cast<idStaticEntity*> ( gameLocal.entities[ e ] );
|
|
|
|
if ( !ent ) {
|
|
continue;
|
|
}
|
|
|
|
strModel = ent->spawnArgs.GetString( "model" );
|
|
if ( strModel.Length() && strModel.Find( ".prt") > 0 ) {
|
|
dict.Clear();
|
|
dict.Set( "model", ent->spawnArgs.GetString( "model" ) );
|
|
dict.SetVector( "origin", ent->GetPhysics()->GetOrigin() );
|
|
|
|
// find map file entity
|
|
mapEnt = mapFile->FindEntity( ent->name );
|
|
// create new map file entity if there isn't one for this entity
|
|
if ( !mapEnt ) {
|
|
continue;
|
|
}
|
|
// save the particle state
|
|
mapEnt->epairs.Copy( dict );
|
|
}
|
|
}
|
|
|
|
// write out the map file
|
|
mapFile->Write( mapName, ".map" );
|
|
}
|
|
|
|
|
|
/*
|
|
==================
|
|
Cmd_DisasmScript_f
|
|
==================
|
|
*/
|
|
static void Cmd_DisasmScript_f( const idCmdArgs &args ) {
|
|
gameLocal.program.Disassemble();
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_TestSave_f
|
|
==================
|
|
*/
|
|
static void Cmd_TestSave_f( const idCmdArgs &args ) {
|
|
idFile *f;
|
|
|
|
f = fileSystem->OpenFileWrite( "test.sav" );
|
|
gameLocal.SaveGame( f );
|
|
fileSystem->CloseFile( f );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_RecordViewNotes_f
|
|
==================
|
|
*/
|
|
static void Cmd_RecordViewNotes_f( const idCmdArgs &args ) {
|
|
idPlayer *player;
|
|
idVec3 origin;
|
|
idMat3 axis;
|
|
|
|
if ( args.Argc() <= 3 ) {
|
|
return;
|
|
}
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player ) {
|
|
return;
|
|
}
|
|
|
|
player->GetViewPos( origin, axis );
|
|
|
|
// Argv(1) = filename for map (viewnotes/mapname/person)
|
|
// Argv(2) = note number (person0001)
|
|
// Argv(3) = comments
|
|
|
|
idStr str = args.Argv(1);
|
|
str.SetFileExtension( ".txt" );
|
|
idFile *file = fileSystem->OpenFileAppend( str );
|
|
if ( file ) {
|
|
file->WriteFloatString( "\"view\"\t( %s )\t( %s )\r\n", origin.ToString(), axis.ToString() );
|
|
file->WriteFloatString( "\"comments\"\t\"%s: %s\"\r\n\r\n", args.Argv(2), args.Argv(3) );
|
|
fileSystem->CloseFile( file );
|
|
}
|
|
|
|
idStr viewComments = args.Argv(1);
|
|
viewComments.StripLeading("viewnotes/");
|
|
viewComments += " -- Loc: ";
|
|
viewComments += origin.ToString();
|
|
viewComments += "\n";
|
|
viewComments += args.Argv(3);
|
|
player->hud->SetStateString( "viewcomments", viewComments );
|
|
player->hud->HandleNamedEvent( "showViewComments" );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_CloseViewNotes_f
|
|
==================
|
|
*/
|
|
static void Cmd_CloseViewNotes_f( const idCmdArgs &args ) {
|
|
idPlayer *player = gameLocal.GetLocalPlayer();
|
|
|
|
if ( !player ) {
|
|
return;
|
|
}
|
|
|
|
player->hud->SetStateString( "viewcomments", "" );
|
|
player->hud->HandleNamedEvent( "hideViewComments" );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
Cmd_ShowViewNotes_f
|
|
==================
|
|
*/
|
|
static void Cmd_ShowViewNotes_f( const idCmdArgs &args ) {
|
|
static idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT | LEXFL_NOFATALERRORS );
|
|
idToken token;
|
|
idPlayer *player;
|
|
idVec3 origin;
|
|
idMat3 axis;
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
|
|
if ( !player ) {
|
|
return;
|
|
}
|
|
|
|
if ( !parser.IsLoaded() ) {
|
|
idStr str = "viewnotes/";
|
|
str += gameLocal.GetMapName();
|
|
str.StripFileExtension();
|
|
str += "/";
|
|
if ( args.Argc() > 1 ) {
|
|
str += args.Argv( 1 );
|
|
} else {
|
|
str += "comments";
|
|
}
|
|
str.SetFileExtension( ".txt" );
|
|
if ( !parser.LoadFile( str ) ) {
|
|
gameLocal.Printf( "No view notes for %s\n", gameLocal.GetMapName() );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( parser.ExpectTokenString( "view" ) && parser.Parse1DMatrix( 3, origin.ToFloatPtr() ) &&
|
|
parser.Parse1DMatrix( 9, axis.ToFloatPtr() ) && parser.ExpectTokenString( "comments" ) && parser.ReadToken( &token ) ) {
|
|
player->hud->SetStateString( "viewcomments", token );
|
|
player->hud->HandleNamedEvent( "showViewComments" );
|
|
player->Teleport( origin, axis.ToAngles(), NULL );
|
|
} else {
|
|
parser.FreeSource();
|
|
player->hud->HandleNamedEvent( "hideViewComments" );
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
FindEntityGUIs
|
|
|
|
helper function for Cmd_NextGUI_f. Checks the passed entity to determine if it
|
|
has any valid gui surfaces.
|
|
=================
|
|
*/
|
|
bool FindEntityGUIs( idEntity *ent, const modelSurface_t ** surfaces, int maxSurfs, int &guiSurfaces ) {
|
|
renderEntity_t *renderEnt;
|
|
idRenderModel *renderModel;
|
|
const modelSurface_t *surf;
|
|
const idMaterial *shader;
|
|
int i;
|
|
|
|
assert( surfaces != NULL );
|
|
assert( ent != NULL );
|
|
|
|
memset( surfaces, 0x00, sizeof( modelSurface_t *) * maxSurfs );
|
|
guiSurfaces = 0;
|
|
|
|
renderEnt = ent->GetRenderEntity();
|
|
renderModel = renderEnt->hModel;
|
|
if ( renderModel == NULL ) {
|
|
return false;
|
|
}
|
|
|
|
for( i = 0; i < renderModel->NumSurfaces(); i++ ) {
|
|
surf = renderModel->Surface( i );
|
|
if ( surf == NULL ) {
|
|
continue;
|
|
}
|
|
shader = surf->shader;
|
|
if ( shader == NULL ) {
|
|
continue;
|
|
}
|
|
if ( shader->GetEntityGui() > 0 ) {
|
|
surfaces[ guiSurfaces++ ] = surf;
|
|
}
|
|
}
|
|
|
|
return ( guiSurfaces != 0 );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
Cmd_NextGUI_f
|
|
=================
|
|
*/
|
|
void Cmd_NextGUI_f( const idCmdArgs &args ) {
|
|
idVec3 origin;
|
|
idAngles angles;
|
|
idPlayer *player;
|
|
idEntity *ent;
|
|
int guiSurfaces;
|
|
bool newEnt;
|
|
renderEntity_t *renderEnt;
|
|
int surfIndex;
|
|
srfTriangles_t *geom;
|
|
idMat4 modelMatrix;
|
|
idVec3 normal;
|
|
idVec3 center;
|
|
const modelSurface_t *surfaces[ MAX_RENDERENTITY_GUI ];
|
|
|
|
player = gameLocal.GetLocalPlayer();
|
|
if ( !player || !gameLocal.CheatsOk() ) {
|
|
return;
|
|
}
|
|
|
|
if ( args.Argc() != 1 ) {
|
|
gameLocal.Printf( "usage: nextgui\n" );
|
|
return;
|
|
}
|
|
|
|
// start at the last entity
|
|
ent = gameLocal.lastGUIEnt.GetEntity();
|
|
|
|
// see if we have any gui surfaces left to go to on the current entity.
|
|
guiSurfaces = 0;
|
|
newEnt = false;
|
|
if ( ent == NULL ) {
|
|
newEnt = true;
|
|
} else if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == true ) {
|
|
if ( gameLocal.lastGUI >= guiSurfaces ) {
|
|
newEnt = true;
|
|
}
|
|
} else {
|
|
// no actual gui surfaces on this ent, so skip it
|
|
newEnt = true;
|
|
}
|
|
|
|
if ( newEnt == true ) {
|
|
// go ahead and skip to the next entity with a gui...
|
|
if ( ent == NULL ) {
|
|
ent = gameLocal.spawnedEntities.Next();
|
|
} else {
|
|
ent = ent->spawnNode.Next();
|
|
}
|
|
|
|
for ( ; ent != NULL; ent = ent->spawnNode.Next() ) {
|
|
if ( ent->spawnArgs.GetString( "gui", NULL ) != NULL ) {
|
|
break;
|
|
}
|
|
|
|
if ( ent->spawnArgs.GetString( "gui2", NULL ) != NULL ) {
|
|
break;
|
|
}
|
|
|
|
if ( ent->spawnArgs.GetString( "gui3", NULL ) != NULL ) {
|
|
break;
|
|
}
|
|
|
|
// try the next entity
|
|
gameLocal.lastGUIEnt = ent;
|
|
}
|
|
|
|
gameLocal.lastGUIEnt = ent;
|
|
gameLocal.lastGUI = 0;
|
|
|
|
if ( !ent ) {
|
|
gameLocal.Printf( "No more gui entities. Starting over...\n" );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == false ) {
|
|
gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces.\n", ent->name.c_str() );
|
|
}
|
|
|
|
if ( guiSurfaces == 0 ) {
|
|
gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces!\n", ent->name.c_str() );
|
|
return;
|
|
}
|
|
|
|
gameLocal.Printf( "Teleporting to gui entity \"%s\", gui #%d.\n" , ent->name.c_str (), gameLocal.lastGUI );
|
|
|
|
renderEnt = ent->GetRenderEntity();
|
|
surfIndex = gameLocal.lastGUI++;
|
|
geom = surfaces[ surfIndex ]->geometry;
|
|
if ( geom == NULL ) {
|
|
gameLocal.Printf( "Entity \"%s\" has gui surface %d without geometry!\n", ent->name.c_str(), surfIndex );
|
|
return;
|
|
}
|
|
|
|
assert( geom->facePlanes != NULL );
|
|
|
|
modelMatrix = idMat4( renderEnt->axis, renderEnt->origin );
|
|
normal = geom->facePlanes[ 0 ].Normal() * renderEnt->axis;
|
|
center = geom->bounds.GetCenter() * modelMatrix;
|
|
|
|
origin = center + (normal * 32.0f);
|
|
origin.z -= player->EyeHeight();
|
|
normal *= -1.0f;
|
|
angles = normal.ToAngles ();
|
|
|
|
// make sure the player is in noclip
|
|
player->noclip = true;
|
|
player->Teleport( origin, angles, NULL );
|
|
}
|
|
|
|
static void ArgCompletion_DefFile( const idCmdArgs &args, void(*callback)( const char *s ) ) {
|
|
cmdSystem->ArgCompletion_FolderExtension( args, callback, "def/", true, ".def", NULL );
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Cmd_TestId_f
|
|
outputs a string from the string table for the specified id
|
|
===============
|
|
*/
|
|
void Cmd_TestId_f( const idCmdArgs &args ) {
|
|
idStr id;
|
|
int i;
|
|
if ( args.Argc() == 1 ) {
|
|
common->Printf( "usage: testid <string id>\n" );
|
|
return;
|
|
}
|
|
|
|
for ( i = 1; i < args.Argc(); i++ ) {
|
|
id += args.Argv( i );
|
|
}
|
|
if ( idStr::Cmpn( id, STRTABLE_ID, STRTABLE_ID_LENGTH ) != 0 ) {
|
|
id = STRTABLE_ID + id;
|
|
}
|
|
gameLocal.mpGame.AddChatLine( common->GetLanguageDict()->GetString( id ), "<nothing>", "<nothing>", "<nothing>" );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idGameLocal::InitConsoleCommands
|
|
|
|
Let the system know about all of our commands
|
|
so it can perform tab completion
|
|
=================
|
|
*/
|
|
void idGameLocal::InitConsoleCommands( void ) {
|
|
cmdSystem->AddCommand( "listTypeInfo", ListTypeInfo_f, CMD_FL_GAME, "list type info" );
|
|
cmdSystem->AddCommand( "writeGameState", WriteGameState_f, CMD_FL_GAME, "write game state" );
|
|
cmdSystem->AddCommand( "testSaveGame", TestSaveGame_f, CMD_FL_GAME|CMD_FL_CHEAT, "test a save game for a level" );
|
|
cmdSystem->AddCommand( "game_memory", idClass::DisplayInfo_f, CMD_FL_GAME, "displays game class info" );
|
|
cmdSystem->AddCommand( "listClasses", idClass::ListClasses_f, CMD_FL_GAME, "lists game classes" );
|
|
cmdSystem->AddCommand( "listThreads", idThread::ListThreads_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists script threads" );
|
|
cmdSystem->AddCommand( "listEntities", Cmd_EntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists game entities" );
|
|
cmdSystem->AddCommand( "listActiveEntities", Cmd_ActiveEntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists active game entities" );
|
|
cmdSystem->AddCommand( "listMonsters", idAI::List_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists monsters" );
|
|
cmdSystem->AddCommand( "listSpawnArgs", Cmd_ListSpawnArgs_f, CMD_FL_GAME|CMD_FL_CHEAT, "list the spawn args of an entity", idGameLocal::ArgCompletion_EntityName );
|
|
cmdSystem->AddCommand( "say", Cmd_Say_f, CMD_FL_GAME, "text chat" );
|
|
cmdSystem->AddCommand( "sayTeam", Cmd_SayTeam_f, CMD_FL_GAME, "team text chat" );
|
|
cmdSystem->AddCommand( "addChatLine", Cmd_AddChatLine_f, CMD_FL_GAME, "internal use - core to game chat lines" );
|
|
cmdSystem->AddCommand( "gameKick", Cmd_Kick_f, CMD_FL_GAME, "same as kick, but recognizes player names" );
|
|
cmdSystem->AddCommand( "give", Cmd_Give_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives one or more items" );
|
|
cmdSystem->AddCommand( "centerview", Cmd_CenterView_f, CMD_FL_GAME, "centers the view" );
|
|
cmdSystem->AddCommand( "god", Cmd_God_f, CMD_FL_GAME|CMD_FL_CHEAT, "enables god mode" );
|
|
cmdSystem->AddCommand( "notarget", Cmd_Notarget_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables the player as a target" );
|
|
cmdSystem->AddCommand( "noclip", Cmd_Noclip_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables collision detection for the player" );
|
|
cmdSystem->AddCommand( "kill", Cmd_Kill_f, CMD_FL_GAME, "kills the player" );
|
|
cmdSystem->AddCommand( "where", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" );
|
|
cmdSystem->AddCommand( "getviewpos", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" );
|
|
cmdSystem->AddCommand( "setviewpos", Cmd_SetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the current view position" );
|
|
cmdSystem->AddCommand( "teleport", Cmd_Teleport_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleports the player to an entity location", idGameLocal::ArgCompletion_EntityName );
|
|
cmdSystem->AddCommand( "trigger", Cmd_Trigger_f, CMD_FL_GAME|CMD_FL_CHEAT, "triggers an entity", idGameLocal::ArgCompletion_EntityName );
|
|
cmdSystem->AddCommand( "spawn", Cmd_Spawn_f, CMD_FL_GAME|CMD_FL_CHEAT, "spawns a game entity", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
|
|
cmdSystem->AddCommand( "damage", Cmd_Damage_f, CMD_FL_GAME|CMD_FL_CHEAT, "apply damage to an entity", idGameLocal::ArgCompletion_EntityName );
|
|
cmdSystem->AddCommand( "remove", Cmd_Remove_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes an entity", idGameLocal::ArgCompletion_EntityName );
|
|
cmdSystem->AddCommand( "killMonsters", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all monsters" );
|
|
cmdSystem->AddCommand( "killMoveables", Cmd_KillMovables_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all moveables" );
|
|
cmdSystem->AddCommand( "killRagdolls", Cmd_KillRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all ragdolls" );
|
|
cmdSystem->AddCommand( "addline", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug line" );
|
|
cmdSystem->AddCommand( "addarrow", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug arrow" );
|
|
cmdSystem->AddCommand( "removeline", Cmd_RemoveDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes a debug line" );
|
|
cmdSystem->AddCommand( "blinkline", Cmd_BlinkDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "blinks a debug line" );
|
|
cmdSystem->AddCommand( "listLines", Cmd_ListDebugLines_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists all debug lines" );
|
|
cmdSystem->AddCommand( "playerModel", Cmd_PlayerModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the given model on the player", idCmdSystem::ArgCompletion_Decl<DECL_MODELDEF> );
|
|
cmdSystem->AddCommand( "testFx", Cmd_TestFx_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an FX system", idCmdSystem::ArgCompletion_Decl<DECL_FX> );
|
|
cmdSystem->AddCommand( "testBoneFx", Cmd_TestBoneFx_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an FX system bound to a joint", idCmdSystem::ArgCompletion_Decl<DECL_FX> );
|
|
cmdSystem->AddCommand( "testLight", Cmd_TestLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a light" );
|
|
cmdSystem->AddCommand( "testPointLight", Cmd_TestPointLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a point light" );
|
|
cmdSystem->AddCommand( "popLight", Cmd_PopLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes the last created light" );
|
|
cmdSystem->AddCommand( "testDeath", Cmd_TestDeath_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests death" );
|
|
cmdSystem->AddCommand( "testSave", Cmd_TestSave_f, CMD_FL_GAME|CMD_FL_CHEAT, "writes out a test savegame" );
|
|
cmdSystem->AddCommand( "testModel", idTestModel::TestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a model", idTestModel::ArgCompletion_TestModel );
|
|
cmdSystem->AddCommand( "testSkin", idTestModel::TestSkin_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a skin on an existing testModel", idCmdSystem::ArgCompletion_Decl<DECL_SKIN> );
|
|
cmdSystem->AddCommand( "testShaderParm", idTestModel::TestShaderParm_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets a shaderParm on an existing testModel" );
|
|
cmdSystem->AddCommand( "keepTestModel", idTestModel::KeepTestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "keeps the last test model in the game" );
|
|
cmdSystem->AddCommand( "testAnim", idTestModel::TestAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an animation", idTestModel::ArgCompletion_TestAnim );
|
|
cmdSystem->AddCommand( "testParticleStopTime", idTestModel::TestParticleStopTime_f,CMD_FL_GAME|CMD_FL_CHEAT, "tests particle stop time on a test model" );
|
|
cmdSystem->AddCommand( "nextAnim", idTestModel::TestModelNextAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation on test model" );
|
|
cmdSystem->AddCommand( "prevAnim", idTestModel::TestModelPrevAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation on test model" );
|
|
cmdSystem->AddCommand( "nextFrame", idTestModel::TestModelNextFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation frame on test model" );
|
|
cmdSystem->AddCommand( "prevFrame", idTestModel::TestModelPrevFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation frame on test model" );
|
|
cmdSystem->AddCommand( "testBlend", idTestModel::TestBlend_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests animation blending" );
|
|
cmdSystem->AddCommand( "reloadScript", Cmd_ReloadScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads scripts" );
|
|
cmdSystem->AddCommand( "script", Cmd_Script_f, CMD_FL_GAME|CMD_FL_CHEAT, "executes a line of script" );
|
|
cmdSystem->AddCommand( "listCollisionModels", Cmd_ListCollisionModels_f, CMD_FL_GAME, "lists collision models" );
|
|
cmdSystem->AddCommand( "collisionModelInfo", Cmd_CollisionModelInfo_f, CMD_FL_GAME, "shows collision model info" );
|
|
cmdSystem->AddCommand( "reexportmodels", Cmd_ReexportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "reexports models", ArgCompletion_DefFile );
|
|
cmdSystem->AddCommand( "reloadanims", Cmd_ReloadAnims_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads animations" );
|
|
cmdSystem->AddCommand( "listAnims", Cmd_ListAnims_f, CMD_FL_GAME, "lists all animations" );
|
|
cmdSystem->AddCommand( "aasStats", Cmd_AASStats_f, CMD_FL_GAME, "shows AAS stats" );
|
|
cmdSystem->AddCommand( "testDamage", Cmd_TestDamage_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a damage def", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
|
|
cmdSystem->AddCommand( "weaponSplat", Cmd_WeaponSplat_f, CMD_FL_GAME|CMD_FL_CHEAT, "projects a blood splat on the player weapon" );
|
|
cmdSystem->AddCommand( "saveSelected", Cmd_SaveSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves the selected entity to the .map file" );
|
|
cmdSystem->AddCommand( "deleteSelected", Cmd_DeleteSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "deletes selected entity" );
|
|
cmdSystem->AddCommand( "saveMoveables", Cmd_SaveMoveables_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all moveables to the .map file" );
|
|
cmdSystem->AddCommand( "saveRagdolls", Cmd_SaveRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all ragdoll poses to the .map file" );
|
|
cmdSystem->AddCommand( "bindRagdoll", Cmd_BindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "binds ragdoll at the current drag position" );
|
|
cmdSystem->AddCommand( "unbindRagdoll", Cmd_UnbindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "unbinds the selected ragdoll" );
|
|
cmdSystem->AddCommand( "saveLights", Cmd_SaveLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" );
|
|
cmdSystem->AddCommand( "saveParticles", Cmd_SaveParticles_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" );
|
|
cmdSystem->AddCommand( "clearLights", Cmd_ClearLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "clears all lights" );
|
|
cmdSystem->AddCommand( "gameError", Cmd_GameError_f, CMD_FL_GAME|CMD_FL_CHEAT, "causes a game error" );
|
|
|
|
#ifndef ID_DEMO_BUILD
|
|
cmdSystem->AddCommand( "disasmScript", Cmd_DisasmScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "disassembles script" );
|
|
cmdSystem->AddCommand( "recordViewNotes", Cmd_RecordViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "record the current view position with notes" );
|
|
cmdSystem->AddCommand( "showViewNotes", Cmd_ShowViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "show any view notes for the current map, successive calls will cycle to the next note" );
|
|
cmdSystem->AddCommand( "closeViewNotes", Cmd_CloseViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "close the view showing any notes for this map" );
|
|
cmdSystem->AddCommand( "exportmodels", Cmd_ExportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "exports models", ArgCompletion_DefFile );
|
|
|
|
// multiplayer client commands ( replaces old impulses stuff )
|
|
cmdSystem->AddCommand( "clientDropWeapon", idMultiplayerGame::DropWeapon_f, CMD_FL_GAME, "drop current weapon" );
|
|
cmdSystem->AddCommand( "clientMessageMode", idMultiplayerGame::MessageMode_f, CMD_FL_GAME, "ingame gui message mode" );
|
|
// FIXME: implement
|
|
// cmdSystem->AddCommand( "clientVote", idMultiplayerGame::Vote_f, CMD_FL_GAME, "cast your vote: clientVote yes | no" );
|
|
// cmdSystem->AddCommand( "clientCallVote", idMultiplayerGame::CallVote_f, CMD_FL_GAME, "call a vote: clientCallVote si_.. proposed_value" );
|
|
cmdSystem->AddCommand( "clientVoiceChat", idMultiplayerGame::VoiceChat_f, CMD_FL_GAME, "voice chats: clientVoiceChat <sound shader>" );
|
|
cmdSystem->AddCommand( "clientVoiceChatTeam", idMultiplayerGame::VoiceChatTeam_f, CMD_FL_GAME, "team voice chats: clientVoiceChat <sound shader>" );
|
|
|
|
// multiplayer server commands
|
|
cmdSystem->AddCommand( "serverMapRestart", idGameLocal::MapRestart_f, CMD_FL_GAME, "restart the current game" );
|
|
cmdSystem->AddCommand( "serverForceReady", idMultiplayerGame::ForceReady_f,CMD_FL_GAME, "force all players ready" );
|
|
cmdSystem->AddCommand( "serverNextMap", idGameLocal::NextMap_f, CMD_FL_GAME, "change to the next map" );
|
|
#endif
|
|
|
|
// localization help commands
|
|
cmdSystem->AddCommand( "nextGUI", Cmd_NextGUI_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleport the player to the next func_static with a gui" );
|
|
cmdSystem->AddCommand( "testid", Cmd_TestId_f, CMD_FL_GAME|CMD_FL_CHEAT, "output the string for the specified id." );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idGameLocal::ShutdownConsoleCommands
|
|
=================
|
|
*/
|
|
void idGameLocal::ShutdownConsoleCommands( void ) {
|
|
cmdSystem->RemoveFlaggedCommands( CMD_FL_GAME );
|
|
}
|