2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 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.
24 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.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
32 #include "../Game_local.h"
41 float Cmd_GetFloatArg( const idCmdArgs &args, int &argNum ) {
44 value = args.Argv( argNum++ );
53 void Cmd_EntityList_f( const idCmdArgs &args ) {
60 if ( args.Argc() > 1 ) {
62 match.Replace( " ", "" );
70 gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" );
71 gameLocal.Printf( "--------------------------------------------------------------------\n" );
72 for( e = 0; e < MAX_GENTITIES; e++ ) {
73 check = gameLocal.entities[ e ];
79 if ( !check->name.Filter( match, true ) ) {
83 gameLocal.Printf( "%4i: %-20s %-20s %s\n", e,
84 check->GetEntityDefName(), check->GetClassname(), check->name.c_str() );
87 size += check->spawnArgs.Allocated();
90 gameLocal.Printf( "...%d entities\n...%d bytes of spawnargs\n", count, size );
95 Cmd_ActiveEntityList_f
98 void Cmd_ActiveEntityList_f( const idCmdArgs &args ) {
104 gameLocal.Printf( "%-4s %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" );
105 gameLocal.Printf( "--------------------------------------------------------------------\n" );
106 for( check = gameLocal.activeEntities.Next(); check != NULL; check = check->activeNode.Next() ) {
107 char dormant = check->fl.isDormant ? '-' : ' ';
108 gameLocal.Printf( "%4i:%c%-20s %-20s %s\n", check->entityNumber, dormant, check->GetEntityDefName(), check->GetClassname(), check->name.c_str() );
112 gameLocal.Printf( "...%d active entities\n", count );
120 void Cmd_ListSpawnArgs_f( const idCmdArgs &args ) {
124 ent = gameLocal.FindEntity( args.Argv( 1 ) );
126 gameLocal.Printf( "entity not found\n" );
130 for ( i = 0; i < ent->spawnArgs.GetNumKeyVals(); i++ ) {
131 const idKeyValue *kv = ent->spawnArgs.GetKeyVal( i );
132 gameLocal.Printf( "\"%s\" "S_COLOR_WHITE"\"%s\"\n", kv->GetKey().c_str(), kv->GetValue().c_str() );
141 void Cmd_ReloadScript_f( const idCmdArgs &args ) {
142 // shutdown the map because entities may point to script objects
143 gameLocal.MapShutdown();
145 // recompile the scripts
146 gameLocal.program.Startup( SCRIPT_DEFAULT );
148 // error out so that the user can rerun the scripts
149 gameLocal.Error( "Exiting map to reload scripts" );
157 void Cmd_Script_f( const idCmdArgs &args ) {
161 static int funccount = 0;
163 const function_t *func;
166 if ( !gameLocal.CheatsOk() ) {
170 sprintf( funcname, "ConsoleFunction_%d", funccount++ );
172 script = args.Args();
173 sprintf( text, "void %s() {%s;}\n", funcname.c_str(), script );
174 if ( gameLocal.program.CompileText( "console", text, true ) ) {
175 func = gameLocal.program.FindFunction( funcname );
177 // set all the entity names in case the user named one in the script that wasn't referenced in the default script
178 for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
179 gameLocal.program.SetEntity( ent->name, ent );
182 thread = new idThread( func );
192 Kills all the entities of the given class in a level.
195 void KillEntities( const idCmdArgs &args, const idTypeInfo &superClass ) {
201 if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
205 for( i = 1; i < args.Argc(); i++ ) {
206 name = args.Argv( i );
207 ignore.Append( name );
210 for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
211 if ( ent->IsType( superClass ) ) {
212 for( i = 0; i < ignore.Num(); i++ ) {
213 if ( ignore[ i ] == ent->name ) {
218 if ( i >= ignore.Num() ) {
219 ent->PostEventMS( &EV_Remove, 0 );
229 Kills all the monsters in a level.
232 void Cmd_KillMonsters_f( const idCmdArgs &args ) {
233 KillEntities( args, idAI::Type );
235 // kill any projectiles as well since they have pointers to the monster that created them
236 KillEntities( args, idProjectile::Type );
243 Kills all the moveables in a level.
246 void Cmd_KillMovables_f( const idCmdArgs &args ) {
247 if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
250 KillEntities( args, idMoveable::Type );
257 Kills all the ragdolls in a level.
260 void Cmd_KillRagdolls_f( const idCmdArgs &args ) {
261 if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
264 KillEntities( args, idAFEntity_Generic::Type );
265 KillEntities( args, idAFEntity_WithAttachedHead::Type );
272 Give items to a client
275 void Cmd_Give_f( const idCmdArgs &args ) {
281 player = gameLocal.GetLocalPlayer();
282 if ( !player || !gameLocal.CheatsOk() ) {
286 name = args.Argv( 1 );
288 if ( idStr::Icmp( name, "all" ) == 0 ) {
294 if ( give_all || ( idStr::Cmpn( name, "weapon", 6 ) == 0 ) ) {
295 if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) {
296 gameLocal.world->spawnArgs.SetBool( "no_Weapons", false );
297 for( i = 0; i < gameLocal.numClients; i++ ) {
298 if ( gameLocal.entities[ i ] ) {
299 gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, gameLocal.entities[ i ]->spawnArgs.GetString( "def_weapon1" ) );
305 if ( ( idStr::Cmpn( name, "weapon_", 7 ) == 0 ) || ( idStr::Cmpn( name, "item_", 5 ) == 0 ) || ( idStr::Cmpn( name, "ammo_", 5 ) == 0 ) ) {
306 player->GiveItem( name );
310 if ( give_all || idStr::Icmp( name, "health" ) == 0 ) {
311 player->health = player->inventory.maxHealth;
317 if ( give_all || idStr::Icmp( name, "weapons" ) == 0 ) {
318 player->inventory.weapons = BIT( MAX_WEAPONS ) - 1;
319 player->CacheWeapons();
326 if ( give_all || idStr::Icmp( name, "ammo" ) == 0 ) {
327 for ( i = 0 ; i < AMMO_NUMTYPES; i++ ) {
328 player->inventory.ammo[ i ] = player->inventory.MaxAmmoForAmmoClass( player, idWeapon::GetAmmoNameForNum( ( ammo_t )i ) );
335 if ( give_all || idStr::Icmp( name, "armor" ) == 0 ) {
336 player->inventory.armor = player->inventory.maxarmor;
342 if ( idStr::Icmp( name, "berserk" ) == 0 ) {
343 player->GivePowerUp( BERSERK, SEC2MS( 30.0f ) );
347 if ( idStr::Icmp( name, "invis" ) == 0 ) {
348 player->GivePowerUp( INVISIBILITY, SEC2MS( 30.0f ) );
352 if ( idStr::Icmp( name, "pda" ) == 0 ) {
353 player->GivePDA( args.Argv(2), NULL );
357 if ( idStr::Icmp( name, "video" ) == 0 ) {
358 player->GiveVideo( args.Argv(2), NULL );
362 if ( !give_all && !player->Give( args.Argv(1), args.Argv(2) ) ) {
363 gameLocal.Printf( "unknown item\n" );
371 Centers the players pitch
374 void Cmd_CenterView_f( const idCmdArgs &args ) {
378 player = gameLocal.GetLocalPlayer();
383 ang = player->viewAngles;
385 player->SetViewAngles( ang );
392 Sets client to godmode
397 void Cmd_God_f( const idCmdArgs &args ) {
401 player = gameLocal.GetLocalPlayer();
402 if ( !player || !gameLocal.CheatsOk() ) {
406 if ( player->godmode ) {
407 player->godmode = false;
408 msg = "godmode OFF\n";
410 player->godmode = true;
411 msg = "godmode ON\n";
414 gameLocal.Printf( "%s", msg );
421 Sets client to notarget
426 void Cmd_Notarget_f( const idCmdArgs &args ) {
430 player = gameLocal.GetLocalPlayer();
431 if ( !player || !gameLocal.CheatsOk() ) {
435 if ( player->fl.notarget ) {
436 player->fl.notarget = false;
437 msg = "notarget OFF\n";
439 player->fl.notarget = true;
440 msg = "notarget ON\n";
443 gameLocal.Printf( "%s", msg );
453 void Cmd_Noclip_f( const idCmdArgs &args ) {
457 player = gameLocal.GetLocalPlayer();
458 if ( !player || !gameLocal.CheatsOk() ) {
462 if ( player->noclip ) {
463 msg = "noclip OFF\n";
467 player->noclip = !player->noclip;
469 gameLocal.Printf( "%s", msg );
477 void Cmd_Kill_f( const idCmdArgs &args ) {
480 if ( gameLocal.isMultiplayer ) {
481 if ( gameLocal.isClient ) {
483 byte msgBuf[ MAX_GAME_MESSAGE_SIZE ];
484 outMsg.Init( msgBuf, sizeof( msgBuf ) );
485 outMsg.WriteByte( GAME_RELIABLE_MESSAGE_KILL );
486 networkSystem->ClientSendReliableMessage( outMsg );
488 player = gameLocal.GetClientByCmdArgs( args );
490 common->Printf( "kill <client nickname> or kill <client index>\n" );
493 player->Kill( false, false );
494 cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say killed client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
497 player = gameLocal.GetLocalPlayer();
501 player->Kill( false, false );
510 void Cmd_PlayerModel_f( const idCmdArgs &args ) {
516 player = gameLocal.GetLocalPlayer();
517 if ( !player || !gameLocal.CheatsOk() ) {
521 if ( args.Argc() < 2 ) {
522 gameLocal.Printf( "usage: playerModel <modelname>\n" );
526 name = args.Argv( 1 );
527 player->spawnArgs.Set( "model", name );
529 pos = player->GetPhysics()->GetOrigin();
530 ang = player->viewAngles;
531 player->SpawnToPoint( pos, ang );
539 static void Cmd_Say( bool team, const idCmdArgs &args ) {
542 const char *cmd = team ? "sayTeam" : "say" ;
544 if ( !gameLocal.isMultiplayer ) {
545 gameLocal.Printf( "%s can only be used in a multiplayer game\n", cmd );
549 if ( args.Argc() < 2 ) {
550 gameLocal.Printf( "usage: %s <text>\n", cmd );
555 if ( text.Length() == 0 ) {
559 if ( text[ text.Length() - 1 ] == '\n' ) {
560 text[ text.Length() - 1 ] = '\0';
566 // here we need to special case a listen server to use the real client name instead of "server"
567 // "server" will only appear on a dedicated server
568 if ( gameLocal.isClient || cvarSystem->GetCVarInteger( "net_serverDedicated" ) == 0 ) {
569 player = gameLocal.localClientNum >= 0 ? static_cast<idPlayer *>( gameLocal.entities[ gameLocal.localClientNum ] ) : NULL;
571 name = player->GetUserInfo()->GetString( "ui_name", "player" );
577 if ( gameLocal.isClient ) {
580 outMsg.Init( msgBuf, sizeof( msgBuf ) );
581 outMsg.WriteByte( team ? GAME_RELIABLE_MESSAGE_TCHAT : GAME_RELIABLE_MESSAGE_CHAT );
582 outMsg.WriteString( name );
583 outMsg.WriteString( text, -1, false );
584 networkSystem->ClientSendReliableMessage( outMsg );
586 gameLocal.mpGame.ProcessChatMessage( gameLocal.localClientNum, team, name, text, NULL );
595 static void Cmd_Say_f( const idCmdArgs &args ) {
596 Cmd_Say( false, args );
604 static void Cmd_SayTeam_f( const idCmdArgs &args ) {
605 Cmd_Say( true, args );
613 static void Cmd_AddChatLine_f( const idCmdArgs &args ) {
614 gameLocal.mpGame.AddChatLine( args.Argv( 1 ) );
622 static void Cmd_Kick_f( const idCmdArgs &args ) {
625 if ( !gameLocal.isMultiplayer ) {
626 gameLocal.Printf( "kick can only be used in a multiplayer game\n" );
630 if ( gameLocal.isClient ) {
631 gameLocal.Printf( "You have no such power. This is a server command\n" );
635 player = gameLocal.GetClientByCmdArgs( args );
637 gameLocal.Printf( "usage: kick <client nickname> or kick <client index>\n" );
640 cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say kicking out client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
641 cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "kick %d\n", player->entityNumber ) );
649 void Cmd_GetViewpos_f( const idCmdArgs &args ) {
654 player = gameLocal.GetLocalPlayer();
659 const renderView_t *view = player->GetRenderView();
661 gameLocal.Printf( "(%s) %.1f\n", view->vieworg.ToString(), view->viewaxis[0].ToYaw() );
663 player->GetViewPos( origin, axis );
664 gameLocal.Printf( "(%s) %.1f\n", origin.ToString(), axis[0].ToYaw() );
673 void Cmd_SetViewpos_f( const idCmdArgs &args ) {
679 player = gameLocal.GetLocalPlayer();
680 if ( !player || !gameLocal.CheatsOk() ) {
684 if ( ( args.Argc() != 4 ) && ( args.Argc() != 5 ) ) {
685 gameLocal.Printf( "usage: setviewpos <x> <y> <z> <yaw>\n" );
690 if ( args.Argc() == 5 ) {
691 angles.yaw = atof( args.Argv( 4 ) );
694 for ( i = 0 ; i < 3 ; i++ ) {
695 origin[i] = atof( args.Argv( i + 1 ) );
697 origin.z -= pm_normalviewheight.GetFloat() - 0.25f;
699 player->Teleport( origin, angles, NULL );
707 void Cmd_Teleport_f( const idCmdArgs &args ) {
713 player = gameLocal.GetLocalPlayer();
714 if ( !player || !gameLocal.CheatsOk() ) {
718 if ( args.Argc() != 2 ) {
719 gameLocal.Printf( "usage: teleport <name of entity to teleport to>\n" );
723 ent = gameLocal.FindEntity( args.Argv( 1 ) );
725 gameLocal.Printf( "entity not found\n" );
730 angles.yaw = ent->GetPhysics()->GetAxis()[ 0 ].ToYaw();
731 origin = ent->GetPhysics()->GetOrigin();
733 player->Teleport( origin, angles, ent );
741 void Cmd_Trigger_f( const idCmdArgs &args ) {
747 player = gameLocal.GetLocalPlayer();
748 if ( !player || !gameLocal.CheatsOk() ) {
752 if ( args.Argc() != 2 ) {
753 gameLocal.Printf( "usage: trigger <name of entity to trigger>\n" );
757 ent = gameLocal.FindEntity( args.Argv( 1 ) );
759 gameLocal.Printf( "entity not found\n" );
763 ent->Signal( SIG_TRIGGER );
764 ent->ProcessEvent( &EV_Activate, player );
773 void Cmd_Spawn_f( const idCmdArgs &args ) {
774 const char *key, *value;
781 player = gameLocal.GetLocalPlayer();
782 if ( !player || !gameLocal.CheatsOk( false ) ) {
786 if ( args.Argc() & 1 ) { // must always have an even number of arguments
787 gameLocal.Printf( "usage: spawn classname [key/value pairs]\n" );
791 yaw = player->viewAngles.yaw;
793 value = args.Argv( 1 );
794 dict.Set( "classname", value );
795 dict.Set( "angle", va( "%f", yaw + 180 ) );
797 org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 );
798 dict.Set( "origin", org.ToString() );
800 for( i = 2; i < args.Argc() - 1; i += 2 ) {
802 key = args.Argv( i );
803 value = args.Argv( i + 1 );
805 dict.Set( key, value );
808 gameLocal.SpawnEntityDef( dict );
815 Damages the specified entity
818 void Cmd_Damage_f( const idCmdArgs &args ) {
819 if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
822 if ( args.Argc() != 3 ) {
823 gameLocal.Printf( "usage: damage <name of entity to damage> <damage>\n" );
827 idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) );
829 gameLocal.Printf( "entity not found\n" );
833 ent->Damage( gameLocal.world, gameLocal.world, idVec3( 0, 0, 1 ), "damage_moverCrush", atoi( args.Argv( 2 ) ), INVALID_JOINT );
841 Removes the specified entity
844 void Cmd_Remove_f( const idCmdArgs &args ) {
845 if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
848 if ( args.Argc() != 2 ) {
849 gameLocal.Printf( "usage: remove <name of entity to remove>\n" );
853 idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) );
855 gameLocal.Printf( "entity not found\n" );
867 void Cmd_TestLight_f( const idCmdArgs &args ) {
870 const char *key, *value, *name;
874 player = gameLocal.GetLocalPlayer();
875 if ( !player || !gameLocal.CheatsOk( false ) ) {
879 renderView_t *rv = player->GetRenderView();
881 float fov = tan( idMath::M_DEG2RAD * rv->fov_x / 2 );
884 dict.SetMatrix( "rotation", mat3_default );
885 dict.SetVector( "origin", rv->vieworg );
886 dict.SetVector( "light_target", rv->viewaxis[0] );
887 dict.SetVector( "light_right", rv->viewaxis[1] * -fov );
888 dict.SetVector( "light_up", rv->viewaxis[2] * fov );
889 dict.SetVector( "light_start", rv->viewaxis[0] * 16 );
890 dict.SetVector( "light_end", rv->viewaxis[0] * 1000 );
892 if ( args.Argc() >= 2 ) {
893 value = args.Argv( 1 );
894 filename = args.Argv(1);
895 filename.DefaultFileExtension( ".tga" );
896 dict.Set( "texture", filename );
899 dict.Set( "classname", "light" );
900 for( i = 2; i < args.Argc() - 1; i += 2 ) {
902 key = args.Argv( i );
903 value = args.Argv( i + 1 );
905 dict.Set( key, value );
908 for ( i = 0; i < MAX_GENTITIES; i++ ) {
909 name = va( "spawned_light_%d", i ); // not just light_, or it might pick up a prelight shadow
910 if ( !gameLocal.FindEntity( name ) ) {
914 dict.Set( "name", name );
916 gameLocal.SpawnEntityDef( dict );
918 gameLocal.Printf( "Created new light\n");
926 void Cmd_TestPointLight_f( const idCmdArgs &args ) {
927 const char *key, *value, *name;
932 player = gameLocal.GetLocalPlayer();
933 if ( !player || !gameLocal.CheatsOk( false ) ) {
937 dict.SetVector("origin", player->GetRenderView()->vieworg);
939 if ( args.Argc() >= 2 ) {
940 value = args.Argv( 1 );
941 dict.Set("light", value);
943 dict.Set("light", "300");
946 dict.Set( "classname", "light" );
947 for( i = 2; i < args.Argc() - 1; i += 2 ) {
949 key = args.Argv( i );
950 value = args.Argv( i + 1 );
952 dict.Set( key, value );
955 for ( i = 0; i < MAX_GENTITIES; i++ ) {
956 name = va( "light_%d", i );
957 if ( !gameLocal.FindEntity( name ) ) {
961 dict.Set( "name", name );
963 gameLocal.SpawnEntityDef( dict );
965 gameLocal.Printf( "Created new point light\n");
973 void Cmd_PopLight_f( const idCmdArgs &args ) {
976 idMapFile *mapFile = gameLocal.GetLevelMap();
980 if ( !gameLocal.CheatsOk() ) {
984 bool removeFromMap = ( args.Argc() > 1 );
988 for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
989 if ( !ent->IsType( idLight::Type ) ) {
993 if ( gameLocal.spawnIds[ ent->entityNumber ] > last ) {
994 last = gameLocal.spawnIds[ ent->entityNumber ];
995 lastLight = static_cast<idLight*>( ent );
1000 // find map file entity
1001 mapEnt = mapFile->FindEntity( lastLight->name );
1003 if ( removeFromMap && mapEnt ) {
1004 mapFile->RemoveEntity( mapEnt );
1006 gameLocal.Printf( "Removing light %i\n", lastLight->GetLightDefHandle() );
1009 gameLocal.Printf( "No lights to clear.\n" );
1015 ====================
1017 ====================
1019 void Cmd_ClearLights_f( const idCmdArgs &args ) {
1023 idMapEntity *mapEnt;
1024 idMapFile *mapFile = gameLocal.GetLevelMap();
1026 bool removeFromMap = ( args.Argc() > 1 );
1028 gameLocal.Printf( "Clearing all lights.\n" );
1029 for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = next ) {
1030 next = ent->spawnNode.Next();
1031 if ( !ent->IsType( idLight::Type ) ) {
1035 light = static_cast<idLight*>( ent );
1036 mapEnt = mapFile->FindEntity( light->name );
1038 if ( removeFromMap && mapEnt ) {
1039 mapFile->RemoveEntity( mapEnt );
1051 void Cmd_TestFx_f( const idCmdArgs &args ) {
1057 player = gameLocal.GetLocalPlayer();
1058 if ( !player || !gameLocal.CheatsOk() ) {
1062 // delete the testModel if active
1063 if ( gameLocal.testFx ) {
1064 delete gameLocal.testFx;
1065 gameLocal.testFx = NULL;
1068 if ( args.Argc() < 2 ) {
1072 name = args.Argv( 1 );
1074 offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f;
1076 dict.Set( "origin", offset.ToString() );
1077 dict.Set( "test", "1");
1078 dict.Set( "fx", name );
1079 gameLocal.testFx = ( idEntityFx * )gameLocal.SpawnEntityType( idEntityFx::Type, &dict );
1082 #define MAX_DEBUGLINES 128
1092 gameDebugLine_t debugLines[MAX_DEBUGLINES];
1099 static void Cmd_AddDebugLine_f( const idCmdArgs &args ) {
1103 if ( !gameLocal.CheatsOk() ) {
1107 if ( args.Argc () < 7 ) {
1108 gameLocal.Printf( "usage: addline <x y z> <x y z> <color>\n" );
1111 for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1112 if ( !debugLines[i].used ) {
1116 if ( i >= MAX_DEBUGLINES ) {
1117 gameLocal.Printf( "no free debug lines\n" );
1120 value = args.Argv( 0 );
1121 if ( !idStr::Icmp( value, "addarrow" ) ) {
1122 debugLines[i].arrow = true;
1124 debugLines[i].arrow = false;
1126 debugLines[i].used = true;
1127 debugLines[i].blink = false;
1129 debugLines[i].start.x = Cmd_GetFloatArg( args, argNum );
1130 debugLines[i].start.y = Cmd_GetFloatArg( args, argNum );
1131 debugLines[i].start.z = Cmd_GetFloatArg( args, argNum );
1132 debugLines[i].end.x = Cmd_GetFloatArg( args, argNum );
1133 debugLines[i].end.y = Cmd_GetFloatArg( args, argNum );
1134 debugLines[i].end.z = Cmd_GetFloatArg( args, argNum );
1135 debugLines[i].color = Cmd_GetFloatArg( args, argNum );
1140 Cmd_RemoveDebugLine_f
1143 static void Cmd_RemoveDebugLine_f( const idCmdArgs &args ) {
1147 if ( !gameLocal.CheatsOk() ) {
1151 if ( args.Argc () < 2 ) {
1152 gameLocal.Printf( "usage: removeline <num>\n" );
1155 value = args.Argv( 1 );
1157 for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1158 if ( debugLines[i].used ) {
1164 if ( i >= MAX_DEBUGLINES ) {
1165 gameLocal.Printf( "line not found\n" );
1168 debugLines[i].used = false;
1173 Cmd_BlinkDebugLine_f
1176 static void Cmd_BlinkDebugLine_f( const idCmdArgs &args ) {
1180 if ( !gameLocal.CheatsOk() ) {
1184 if ( args.Argc () < 2 ) {
1185 gameLocal.Printf( "usage: blinkline <num>\n" );
1188 value = args.Argv( 1 );
1189 num = atoi( value );
1190 for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1191 if ( debugLines[i].used ) {
1197 if ( i >= MAX_DEBUGLINES ) {
1198 gameLocal.Printf( "line not found\n" );
1201 debugLines[i].blink = !debugLines[i].blink;
1209 static void PrintFloat( float f ) {
1212 for ( i = sprintf( buf, "%3.2f", f ); i < 7; i++ ) {
1216 gameLocal.Printf( buf );
1221 Cmd_ListDebugLines_f
1224 static void Cmd_ListDebugLines_f( const idCmdArgs &args ) {
1227 if ( !gameLocal.CheatsOk() ) {
1232 gameLocal.Printf( "line num: x1 y1 z1 x2 y2 z2 c b a\n" );
1233 for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1234 if ( debugLines[i].used ) {
1235 gameLocal.Printf( "line %3d: ", num );
1236 PrintFloat( debugLines[i].start.x );
1237 PrintFloat( debugLines[i].start.y );
1238 PrintFloat( debugLines[i].start.z );
1239 PrintFloat( debugLines[i].end.x );
1240 PrintFloat( debugLines[i].end.y );
1241 PrintFloat( debugLines[i].end.z );
1242 gameLocal.Printf( "%d %d %d\n", debugLines[i].color, debugLines[i].blink, debugLines[i].arrow );
1247 gameLocal.Printf( "no debug lines\n" );
1256 void D_DrawDebugLines( void ) {
1258 idVec3 forward, right, up, p1, p2;
1262 for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1263 if ( debugLines[i].used ) {
1264 if ( !debugLines[i].blink || (gameLocal.time & (1<<9)) ) {
1265 color = idVec4( debugLines[i].color&1, (debugLines[i].color>>1)&1, (debugLines[i].color>>2)&1, 1 );
1266 gameRenderWorld->DebugLine( color, debugLines[i].start, debugLines[i].end );
1268 if ( debugLines[i].arrow ) {
1269 // draw a nice arrow
1270 forward = debugLines[i].end - debugLines[i].start;
1271 l = forward.Normalize() * 0.2f;
1272 forward.NormalVectors( right, up);
1277 p1 = debugLines[i].end - l * forward + (l * 0.4f) * right;
1278 p2 = debugLines[i].end - l * forward - (l * 0.4f) * right;
1279 gameRenderWorld->DebugLine( color, debugLines[i].end, p1 );
1280 gameRenderWorld->DebugLine( color, debugLines[i].end, p2 );
1281 gameRenderWorld->DebugLine( color, p1, p2 );
1290 Cmd_ListCollisionModels_f
1293 static void Cmd_ListCollisionModels_f( const idCmdArgs &args ) {
1294 if ( !gameLocal.CheatsOk() ) {
1298 collisionModelManager->ListModels();
1303 Cmd_CollisionModelInfo_f
1306 static void Cmd_CollisionModelInfo_f( const idCmdArgs &args ) {
1309 if ( !gameLocal.CheatsOk() ) {
1313 if ( args.Argc () < 2 ) {
1314 gameLocal.Printf( "usage: collisionModelInfo <modelNum>\n"
1315 "use 'all' instead of the model number for accumulated info\n" );
1319 value = args.Argv( 1 );
1320 if ( !idStr::Icmp( value, "all" ) ) {
1321 collisionModelManager->ModelInfo( -1 );
1323 collisionModelManager->ModelInfo( atoi(value) );
1332 static void Cmd_ExportModels_f( const idCmdArgs &args ) {
1333 idModelExport exporter;
1336 // don't allow exporting models when cheats are disabled,
1337 // but if we're not in the game, it's ok
1338 if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
1342 if ( args.Argc() < 2 ) {
1343 exporter.ExportModels( "def", ".def" );
1345 name = args.Argv( 1 );
1346 name = "def/" + name;
1347 name.DefaultFileExtension( ".def" );
1348 exporter.ExportDefFile( name );
1354 Cmd_ReexportModels_f
1357 static void Cmd_ReexportModels_f( const idCmdArgs &args ) {
1358 idModelExport exporter;
1361 // don't allow exporting models when cheats are disabled,
1362 // but if we're not in the game, it's ok
1363 if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
1367 idAnimManager::forceExport = true;
1368 if ( args.Argc() < 2 ) {
1369 exporter.ExportModels( "def", ".def" );
1371 name = args.Argv( 1 );
1372 name = "def/" + name;
1373 name.DefaultFileExtension( ".def" );
1374 exporter.ExportDefFile( name );
1376 idAnimManager::forceExport = false;
1384 static void Cmd_ReloadAnims_f( const idCmdArgs &args ) {
1385 // don't allow reloading anims when cheats are disabled,
1386 // but if we're not in the game, it's ok
1387 if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
1391 animationLib.ReloadAnims();
1399 static void Cmd_ListAnims_f( const idCmdArgs &args ) {
1404 idAnimator * animator;
1405 const char * classname;
1406 const idDict * dict;
1409 if ( args.Argc() > 1 ) {
1410 idAnimator animator;
1412 classname = args.Argv( 1 );
1414 dict = gameLocal.FindEntityDefDict( classname, false );
1416 gameLocal.Printf( "Entitydef '%s' not found\n", classname );
1419 animator.SetModel( dict->GetString( "model" ) );
1421 gameLocal.Printf( "----------------\n" );
1422 num = animator.NumAnims();
1423 for( i = 0; i < num; i++ ) {
1424 gameLocal.Printf( "%s\n", animator.AnimFullName( i ) );
1426 gameLocal.Printf( "%d anims\n", num );
1428 animationLib.ListAnims();
1432 for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
1433 animator = ent->GetAnimator();
1435 alloced = animator->Allocated();
1441 gameLocal.Printf( "%d memory used in %d entity animators\n", size, num );
1450 static void Cmd_AASStats_f( const idCmdArgs &args ) {
1453 if ( !gameLocal.CheatsOk() ) {
1457 aasNum = aas_test.GetInteger();
1458 idAAS *aas = gameLocal.GetAAS( aasNum );
1460 gameLocal.Printf( "No aas #%d loaded\n", aasNum );
1471 static void Cmd_TestDamage_f( const idCmdArgs &args ) {
1473 const char *damageDefName;
1475 player = gameLocal.GetLocalPlayer();
1476 if ( !player || !gameLocal.CheatsOk() ) {
1480 if ( args.Argc() < 2 || args.Argc() > 3 ) {
1481 gameLocal.Printf( "usage: testDamage <damageDefName> [angle]\n" );
1485 damageDefName = args.Argv( 1 );
1488 if ( args.Argc() == 3 ) {
1489 float angle = atof( args.Argv( 2 ) );
1491 idMath::SinCos( DEG2RAD( angle ), dir[1], dir[0] );
1497 // give the player full health before and after
1498 // running the damage
1499 player->health = player->inventory.maxHealth;
1500 player->Damage( NULL, NULL, dir, damageDefName, 1.0f, INVALID_JOINT );
1501 player->health = player->inventory.maxHealth;
1509 static void Cmd_TestBoneFx_f( const idCmdArgs &args ) {
1511 const char *bone, *fx;
1513 player = gameLocal.GetLocalPlayer();
1514 if ( !player || !gameLocal.CheatsOk() ) {
1518 if ( args.Argc() < 3 || args.Argc() > 4 ) {
1519 gameLocal.Printf( "usage: testBoneFx <fxName> <boneName>\n" );
1523 fx = args.Argv( 1 );
1524 bone = args.Argv( 2 );
1526 player->StartFxOnBone( fx, bone );
1534 static void Cmd_TestDeath_f( const idCmdArgs &args ) {
1537 player = gameLocal.GetLocalPlayer();
1538 if ( !player || !gameLocal.CheatsOk() ) {
1543 idMath::SinCos( DEG2RAD( 45.0f ), dir[1], dir[0] );
1546 g_testDeath.SetBool( 1 );
1547 player->Damage( NULL, NULL, dir, "damage_triggerhurt_1000", 1.0f, INVALID_JOINT );
1548 if ( args.Argc() >= 2) {
1549 player->SpawnGibs( dir, "damage_triggerhurt_1000" );
1559 static void Cmd_WeaponSplat_f( const idCmdArgs &args ) {
1562 player = gameLocal.GetLocalPlayer();
1563 if ( !player || !gameLocal.CheatsOk() ) {
1567 player->weapon.GetEntity()->BloodSplat( 2.0f );
1575 static void Cmd_SaveSelected_f( const idCmdArgs &args ) {
1579 idMapEntity *mapEnt;
1580 idMapFile *mapFile = gameLocal.GetLevelMap();
1585 player = gameLocal.GetLocalPlayer();
1586 if ( !player || !gameLocal.CheatsOk() ) {
1590 s = player->dragEntity.GetSelected();
1592 gameLocal.Printf( "no entity selected, set g_dragShowSelection 1 to show the current selection\n" );
1596 if ( args.Argc() > 1 ) {
1597 mapName = args.Argv( 1 );
1598 mapName = "maps/" + mapName;
1601 mapName = mapFile->GetName();
1604 // find map file entity
1605 mapEnt = mapFile->FindEntity( s->name );
1606 // create new map file entity if there isn't one for this articulated figure
1608 mapEnt = new idMapEntity();
1609 mapFile->AddEntity( mapEnt );
1610 for ( i = 0; i < 9999; i++ ) {
1611 name = va( "%s_%d", s->GetEntityDefName(), i );
1612 if ( !gameLocal.FindEntity( name ) ) {
1617 mapEnt->epairs.Set( "classname", s->GetEntityDefName() );
1618 mapEnt->epairs.Set( "name", s->name );
1621 if ( s->IsType( idMoveable::Type ) ) {
1622 // save the moveable state
1623 mapEnt->epairs.Set( "origin", s->GetPhysics()->GetOrigin().ToString( 8 ) );
1624 mapEnt->epairs.Set( "rotation", s->GetPhysics()->GetAxis().ToString( 8 ) );
1626 else if ( s->IsType( idAFEntity_Generic::Type ) || s->IsType( idAFEntity_WithAttachedHead::Type ) ) {
1627 // save the articulated figure state
1629 static_cast<idAFEntity_Base *>(s)->SaveState( dict );
1630 mapEnt->epairs.Copy( dict );
1633 // write out the map file
1634 mapFile->Write( mapName, ".map" );
1639 Cmd_DeleteSelected_f
1642 static void Cmd_DeleteSelected_f( const idCmdArgs &args ) {
1645 player = gameLocal.GetLocalPlayer();
1646 if ( !player || !gameLocal.CheatsOk() ) {
1651 player->dragEntity.DeleteSelected();
1660 static void Cmd_SaveMoveables_f( const idCmdArgs &args ) {
1663 idMapEntity *mapEnt;
1664 idMapFile *mapFile = gameLocal.GetLevelMap();
1668 if ( !gameLocal.CheatsOk() ) {
1672 for( e = 0; e < MAX_GENTITIES; e++ ) {
1673 m = static_cast<idMoveable *>(gameLocal.entities[ e ]);
1675 if ( !m || !m->IsType( idMoveable::Type ) ) {
1679 if ( m->IsBound() ) {
1683 if ( !m->IsAtRest() ) {
1688 if ( e < MAX_GENTITIES ) {
1689 gameLocal.Warning( "map not saved because the moveable entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() );
1693 if ( args.Argc() > 1 ) {
1694 mapName = args.Argv( 1 );
1695 mapName = "maps/" + mapName;
1698 mapName = mapFile->GetName();
1701 for( e = 0; e < MAX_GENTITIES; e++ ) {
1702 m = static_cast<idMoveable *>(gameLocal.entities[ e ]);
1704 if ( !m || !m->IsType( idMoveable::Type ) ) {
1708 if ( m->IsBound() ) {
1712 // find map file entity
1713 mapEnt = mapFile->FindEntity( m->name );
1714 // create new map file entity if there isn't one for this articulated figure
1716 mapEnt = new idMapEntity();
1717 mapFile->AddEntity( mapEnt );
1718 for ( i = 0; i < 9999; i++ ) {
1719 name = va( "%s_%d", m->GetEntityDefName(), i );
1720 if ( !gameLocal.FindEntity( name ) ) {
1725 mapEnt->epairs.Set( "classname", m->GetEntityDefName() );
1726 mapEnt->epairs.Set( "name", m->name );
1728 // save the moveable state
1729 mapEnt->epairs.Set( "origin", m->GetPhysics()->GetOrigin().ToString( 8 ) );
1730 mapEnt->epairs.Set( "rotation", m->GetPhysics()->GetAxis().ToString( 8 ) );
1733 // write out the map file
1734 mapFile->Write( mapName, ".map" );
1742 static void Cmd_SaveRagdolls_f( const idCmdArgs &args ) {
1744 idAFEntity_Base *af;
1745 idMapEntity *mapEnt;
1746 idMapFile *mapFile = gameLocal.GetLevelMap();
1751 if ( !gameLocal.CheatsOk() ) {
1755 if ( args.Argc() > 1 ) {
1756 mapName = args.Argv( 1 );
1757 mapName = "maps/" + mapName;
1760 mapName = mapFile->GetName();
1763 for( e = 0; e < MAX_GENTITIES; e++ ) {
1764 af = static_cast<idAFEntity_Base *>(gameLocal.entities[ e ]);
1770 if ( !af->IsType( idAFEntity_WithAttachedHead::Type ) && !af->IsType( idAFEntity_Generic::Type ) ) {
1774 if ( af->IsBound() ) {
1778 if ( !af->IsAtRest() ) {
1779 gameLocal.Warning( "the articulated figure for entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() );
1783 af->SaveState( dict );
1785 // find map file entity
1786 mapEnt = mapFile->FindEntity( af->name );
1787 // create new map file entity if there isn't one for this articulated figure
1789 mapEnt = new idMapEntity();
1790 mapFile->AddEntity( mapEnt );
1791 for ( i = 0; i < 9999; i++ ) {
1792 name = va( "%s_%d", af->GetEntityDefName(), i );
1793 if ( !gameLocal.FindEntity( name ) ) {
1798 mapEnt->epairs.Set( "classname", af->GetEntityDefName() );
1799 mapEnt->epairs.Set( "name", af->name );
1801 // save the articulated figure state
1802 mapEnt->epairs.Copy( dict );
1805 // write out the map file
1806 mapFile->Write( mapName, ".map" );
1814 static void Cmd_BindRagdoll_f( const idCmdArgs &args ) {
1817 player = gameLocal.GetLocalPlayer();
1818 if ( !player || !gameLocal.CheatsOk() ) {
1823 player->dragEntity.BindSelected();
1832 static void Cmd_UnbindRagdoll_f( const idCmdArgs &args ) {
1835 player = gameLocal.GetLocalPlayer();
1836 if ( !player || !gameLocal.CheatsOk() ) {
1841 player->dragEntity.UnbindSelected();
1850 static void Cmd_GameError_f( const idCmdArgs &args ) {
1851 gameLocal.Error( "game error" );
1859 static void Cmd_SaveLights_f( const idCmdArgs &args ) {
1862 idMapEntity *mapEnt;
1863 idMapFile *mapFile = gameLocal.GetLevelMap();
1868 if ( !gameLocal.CheatsOk() ) {
1872 if ( args.Argc() > 1 ) {
1873 mapName = args.Argv( 1 );
1874 mapName = "maps/" + mapName;
1877 mapName = mapFile->GetName();
1880 for( e = 0; e < MAX_GENTITIES; e++ ) {
1881 light = static_cast<idLight*>(gameLocal.entities[ e ]);
1883 if ( !light || !light->IsType( idLight::Type ) ) {
1888 light->SaveState( &dict );
1890 // find map file entity
1891 mapEnt = mapFile->FindEntity( light->name );
1892 // create new map file entity if there isn't one for this light
1894 mapEnt = new idMapEntity();
1895 mapFile->AddEntity( mapEnt );
1896 for ( i = 0; i < 9999; i++ ) {
1897 name = va( "%s_%d", light->GetEntityDefName(), i );
1898 if ( !gameLocal.FindEntity( name ) ) {
1903 mapEnt->epairs.Set( "classname", light->GetEntityDefName() );
1904 mapEnt->epairs.Set( "name", light->name );
1906 // save the light state
1907 mapEnt->epairs.Copy( dict );
1910 // write out the map file
1911 mapFile->Write( mapName, ".map" );
1920 static void Cmd_SaveParticles_f( const idCmdArgs &args ) {
1923 idMapEntity *mapEnt;
1924 idMapFile *mapFile = gameLocal.GetLevelMap();
1926 idStr mapName, strModel;
1928 if ( !gameLocal.CheatsOk() ) {
1932 if ( args.Argc() > 1 ) {
1933 mapName = args.Argv( 1 );
1934 mapName = "maps/" + mapName;
1937 mapName = mapFile->GetName();
1940 for( e = 0; e < MAX_GENTITIES; e++ ) {
1942 ent = static_cast<idStaticEntity*> ( gameLocal.entities[ e ] );
1948 strModel = ent->spawnArgs.GetString( "model" );
1949 if ( strModel.Length() && strModel.Find( ".prt") > 0 ) {
1951 dict.Set( "model", ent->spawnArgs.GetString( "model" ) );
1952 dict.SetVector( "origin", ent->GetPhysics()->GetOrigin() );
1954 // find map file entity
1955 mapEnt = mapFile->FindEntity( ent->name );
1956 // create new map file entity if there isn't one for this entity
1960 // save the particle state
1961 mapEnt->epairs.Copy( dict );
1965 // write out the map file
1966 mapFile->Write( mapName, ".map" );
1975 static void Cmd_DisasmScript_f( const idCmdArgs &args ) {
1976 gameLocal.program.Disassemble();
1984 static void Cmd_TestSave_f( const idCmdArgs &args ) {
1987 f = fileSystem->OpenFileWrite( "test.sav" );
1988 gameLocal.SaveGame( f );
1989 fileSystem->CloseFile( f );
1994 Cmd_RecordViewNotes_f
1997 static void Cmd_RecordViewNotes_f( const idCmdArgs &args ) {
2002 if ( args.Argc() <= 3 ) {
2006 player = gameLocal.GetLocalPlayer();
2011 player->GetViewPos( origin, axis );
2013 // Argv(1) = filename for map (viewnotes/mapname/person)
2014 // Argv(2) = note number (person0001)
2015 // Argv(3) = comments
2017 idStr str = args.Argv(1);
2018 str.SetFileExtension( ".txt" );
2019 idFile *file = fileSystem->OpenFileAppend( str );
2021 file->WriteFloatString( "\"view\"\t( %s )\t( %s )\r\n", origin.ToString(), axis.ToString() );
2022 file->WriteFloatString( "\"comments\"\t\"%s: %s\"\r\n\r\n", args.Argv(2), args.Argv(3) );
2023 fileSystem->CloseFile( file );
2026 idStr viewComments = args.Argv(1);
2027 viewComments.StripLeading("viewnotes/");
2028 viewComments += " -- Loc: ";
2029 viewComments += origin.ToString();
2030 viewComments += "\n";
2031 viewComments += args.Argv(3);
2032 player->hud->SetStateString( "viewcomments", viewComments );
2033 player->hud->HandleNamedEvent( "showViewComments" );
2038 Cmd_CloseViewNotes_f
2041 static void Cmd_CloseViewNotes_f( const idCmdArgs &args ) {
2042 idPlayer *player = gameLocal.GetLocalPlayer();
2048 player->hud->SetStateString( "viewcomments", "" );
2049 player->hud->HandleNamedEvent( "hideViewComments" );
2057 static void Cmd_ShowViewNotes_f( const idCmdArgs &args ) {
2058 static idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT | LEXFL_NOFATALERRORS );
2064 player = gameLocal.GetLocalPlayer();
2070 if ( !parser.IsLoaded() ) {
2071 idStr str = "viewnotes/";
2072 str += gameLocal.GetMapName();
2073 str.StripFileExtension();
2075 if ( args.Argc() > 1 ) {
2076 str += args.Argv( 1 );
2080 str.SetFileExtension( ".txt" );
2081 if ( !parser.LoadFile( str ) ) {
2082 gameLocal.Printf( "No view notes for %s\n", gameLocal.GetMapName() );
2087 if ( parser.ExpectTokenString( "view" ) && parser.Parse1DMatrix( 3, origin.ToFloatPtr() ) &&
2088 parser.Parse1DMatrix( 9, axis.ToFloatPtr() ) && parser.ExpectTokenString( "comments" ) && parser.ReadToken( &token ) ) {
2089 player->hud->SetStateString( "viewcomments", token );
2090 player->hud->HandleNamedEvent( "showViewComments" );
2091 player->Teleport( origin, axis.ToAngles(), NULL );
2093 parser.FreeSource();
2094 player->hud->HandleNamedEvent( "hideViewComments" );
2103 helper function for Cmd_NextGUI_f. Checks the passed entity to determine if it
2104 has any valid gui surfaces.
2107 bool FindEntityGUIs( idEntity *ent, const modelSurface_t ** surfaces, int maxSurfs, int &guiSurfaces ) {
2108 renderEntity_t *renderEnt;
2109 idRenderModel *renderModel;
2110 const modelSurface_t *surf;
2111 const idMaterial *shader;
2114 assert( surfaces != NULL );
2115 assert( ent != NULL );
2117 memset( surfaces, 0x00, sizeof( modelSurface_t *) * maxSurfs );
2120 renderEnt = ent->GetRenderEntity();
2121 renderModel = renderEnt->hModel;
2122 if ( renderModel == NULL ) {
2126 for( i = 0; i < renderModel->NumSurfaces(); i++ ) {
2127 surf = renderModel->Surface( i );
2128 if ( surf == NULL ) {
2131 shader = surf->shader;
2132 if ( shader == NULL ) {
2135 if ( shader->GetEntityGui() > 0 ) {
2136 surfaces[ guiSurfaces++ ] = surf;
2140 return ( guiSurfaces != 0 );
2148 void Cmd_NextGUI_f( const idCmdArgs &args ) {
2155 renderEntity_t *renderEnt;
2157 srfTriangles_t *geom;
2161 const modelSurface_t *surfaces[ MAX_RENDERENTITY_GUI ];
2163 player = gameLocal.GetLocalPlayer();
2164 if ( !player || !gameLocal.CheatsOk() ) {
2168 if ( args.Argc() != 1 ) {
2169 gameLocal.Printf( "usage: nextgui\n" );
2173 // start at the last entity
2174 ent = gameLocal.lastGUIEnt.GetEntity();
2176 // see if we have any gui surfaces left to go to on the current entity.
2179 if ( ent == NULL ) {
2181 } else if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == true ) {
2182 if ( gameLocal.lastGUI >= guiSurfaces ) {
2186 // no actual gui surfaces on this ent, so skip it
2190 if ( newEnt == true ) {
2191 // go ahead and skip to the next entity with a gui...
2192 if ( ent == NULL ) {
2193 ent = gameLocal.spawnedEntities.Next();
2195 ent = ent->spawnNode.Next();
2198 for ( ; ent != NULL; ent = ent->spawnNode.Next() ) {
2199 if ( ent->spawnArgs.GetString( "gui", NULL ) != NULL ) {
2203 if ( ent->spawnArgs.GetString( "gui2", NULL ) != NULL ) {
2207 if ( ent->spawnArgs.GetString( "gui3", NULL ) != NULL ) {
2211 // try the next entity
2212 gameLocal.lastGUIEnt = ent;
2215 gameLocal.lastGUIEnt = ent;
2216 gameLocal.lastGUI = 0;
2219 gameLocal.Printf( "No more gui entities. Starting over...\n" );
2224 if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == false ) {
2225 gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces.\n", ent->name.c_str() );
2228 if ( guiSurfaces == 0 ) {
2229 gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces!\n", ent->name.c_str() );
2233 gameLocal.Printf( "Teleporting to gui entity \"%s\", gui #%d.\n" , ent->name.c_str (), gameLocal.lastGUI );
2235 renderEnt = ent->GetRenderEntity();
2236 surfIndex = gameLocal.lastGUI++;
2237 geom = surfaces[ surfIndex ]->geometry;
2238 if ( geom == NULL ) {
2239 gameLocal.Printf( "Entity \"%s\" has gui surface %d without geometry!\n", ent->name.c_str(), surfIndex );
2243 assert( geom->facePlanes != NULL );
2245 modelMatrix = idMat4( renderEnt->axis, renderEnt->origin );
2246 normal = geom->facePlanes[ 0 ].Normal() * renderEnt->axis;
2247 center = geom->bounds.GetCenter() * modelMatrix;
2249 origin = center + (normal * 32.0f);
2250 origin.z -= player->EyeHeight();
2252 angles = normal.ToAngles ();
2254 // make sure the player is in noclip
2255 player->noclip = true;
2256 player->Teleport( origin, angles, NULL );
2259 static void ArgCompletion_DefFile( const idCmdArgs &args, void(*callback)( const char *s ) ) {
2260 cmdSystem->ArgCompletion_FolderExtension( args, callback, "def/", true, ".def", NULL );
2266 outputs a string from the string table for the specified id
2269 void Cmd_TestId_f( const idCmdArgs &args ) {
2272 if ( args.Argc() == 1 ) {
2273 common->Printf( "usage: testid <string id>\n" );
2277 for ( i = 1; i < args.Argc(); i++ ) {
2278 id += args.Argv( i );
2280 if ( idStr::Cmpn( id, STRTABLE_ID, STRTABLE_ID_LENGTH ) != 0 ) {
2281 id = STRTABLE_ID + id;
2283 gameLocal.mpGame.AddChatLine( common->GetLanguageDict()->GetString( id ), "<nothing>", "<nothing>", "<nothing>" );
2288 idGameLocal::InitConsoleCommands
2290 Let the system know about all of our commands
2291 so it can perform tab completion
2294 void idGameLocal::InitConsoleCommands( void ) {
2295 cmdSystem->AddCommand( "listTypeInfo", ListTypeInfo_f, CMD_FL_GAME, "list type info" );
2296 cmdSystem->AddCommand( "writeGameState", WriteGameState_f, CMD_FL_GAME, "write game state" );
2297 cmdSystem->AddCommand( "testSaveGame", TestSaveGame_f, CMD_FL_GAME|CMD_FL_CHEAT, "test a save game for a level" );
2298 cmdSystem->AddCommand( "game_memory", idClass::DisplayInfo_f, CMD_FL_GAME, "displays game class info" );
2299 cmdSystem->AddCommand( "listClasses", idClass::ListClasses_f, CMD_FL_GAME, "lists game classes" );
2300 cmdSystem->AddCommand( "listThreads", idThread::ListThreads_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists script threads" );
2301 cmdSystem->AddCommand( "listEntities", Cmd_EntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists game entities" );
2302 cmdSystem->AddCommand( "listActiveEntities", Cmd_ActiveEntityList_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists active game entities" );
2303 cmdSystem->AddCommand( "listMonsters", idAI::List_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists monsters" );
2304 cmdSystem->AddCommand( "listSpawnArgs", Cmd_ListSpawnArgs_f, CMD_FL_GAME|CMD_FL_CHEAT, "list the spawn args of an entity", idGameLocal::ArgCompletion_EntityName );
2305 cmdSystem->AddCommand( "say", Cmd_Say_f, CMD_FL_GAME, "text chat" );
2306 cmdSystem->AddCommand( "sayTeam", Cmd_SayTeam_f, CMD_FL_GAME, "team text chat" );
2307 cmdSystem->AddCommand( "addChatLine", Cmd_AddChatLine_f, CMD_FL_GAME, "internal use - core to game chat lines" );
2308 cmdSystem->AddCommand( "gameKick", Cmd_Kick_f, CMD_FL_GAME, "same as kick, but recognizes player names" );
2309 cmdSystem->AddCommand( "give", Cmd_Give_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives one or more items" );
2310 cmdSystem->AddCommand( "centerview", Cmd_CenterView_f, CMD_FL_GAME, "centers the view" );
2311 cmdSystem->AddCommand( "god", Cmd_God_f, CMD_FL_GAME|CMD_FL_CHEAT, "enables god mode" );
2312 cmdSystem->AddCommand( "notarget", Cmd_Notarget_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables the player as a target" );
2313 cmdSystem->AddCommand( "noclip", Cmd_Noclip_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables collision detection for the player" );
2314 cmdSystem->AddCommand( "kill", Cmd_Kill_f, CMD_FL_GAME, "kills the player" );
2315 cmdSystem->AddCommand( "where", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" );
2316 cmdSystem->AddCommand( "getviewpos", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" );
2317 cmdSystem->AddCommand( "setviewpos", Cmd_SetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the current view position" );
2318 cmdSystem->AddCommand( "teleport", Cmd_Teleport_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleports the player to an entity location", idGameLocal::ArgCompletion_EntityName );
2319 cmdSystem->AddCommand( "trigger", Cmd_Trigger_f, CMD_FL_GAME|CMD_FL_CHEAT, "triggers an entity", idGameLocal::ArgCompletion_EntityName );
2320 cmdSystem->AddCommand( "spawn", Cmd_Spawn_f, CMD_FL_GAME|CMD_FL_CHEAT, "spawns a game entity", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
2321 cmdSystem->AddCommand( "damage", Cmd_Damage_f, CMD_FL_GAME|CMD_FL_CHEAT, "apply damage to an entity", idGameLocal::ArgCompletion_EntityName );
2322 cmdSystem->AddCommand( "remove", Cmd_Remove_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes an entity", idGameLocal::ArgCompletion_EntityName );
2323 cmdSystem->AddCommand( "killMonsters", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all monsters" );
2324 cmdSystem->AddCommand( "killMoveables", Cmd_KillMovables_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all moveables" );
2325 cmdSystem->AddCommand( "killRagdolls", Cmd_KillRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all ragdolls" );
2326 cmdSystem->AddCommand( "addline", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug line" );
2327 cmdSystem->AddCommand( "addarrow", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug arrow" );
2328 cmdSystem->AddCommand( "removeline", Cmd_RemoveDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes a debug line" );
2329 cmdSystem->AddCommand( "blinkline", Cmd_BlinkDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "blinks a debug line" );
2330 cmdSystem->AddCommand( "listLines", Cmd_ListDebugLines_f, CMD_FL_GAME|CMD_FL_CHEAT, "lists all debug lines" );
2331 cmdSystem->AddCommand( "playerModel", Cmd_PlayerModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the given model on the player", idCmdSystem::ArgCompletion_Decl<DECL_MODELDEF> );
2332 cmdSystem->AddCommand( "testFx", Cmd_TestFx_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an FX system", idCmdSystem::ArgCompletion_Decl<DECL_FX> );
2333 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> );
2334 cmdSystem->AddCommand( "testLight", Cmd_TestLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a light" );
2335 cmdSystem->AddCommand( "testPointLight", Cmd_TestPointLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a point light" );
2336 cmdSystem->AddCommand( "popLight", Cmd_PopLight_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes the last created light" );
2337 cmdSystem->AddCommand( "testDeath", Cmd_TestDeath_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests death" );
2338 cmdSystem->AddCommand( "testSave", Cmd_TestSave_f, CMD_FL_GAME|CMD_FL_CHEAT, "writes out a test savegame" );
2339 cmdSystem->AddCommand( "testModel", idTestModel::TestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a model", idTestModel::ArgCompletion_TestModel );
2340 cmdSystem->AddCommand( "testSkin", idTestModel::TestSkin_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a skin on an existing testModel", idCmdSystem::ArgCompletion_Decl<DECL_SKIN> );
2341 cmdSystem->AddCommand( "testShaderParm", idTestModel::TestShaderParm_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets a shaderParm on an existing testModel" );
2342 cmdSystem->AddCommand( "keepTestModel", idTestModel::KeepTestModel_f, CMD_FL_GAME|CMD_FL_CHEAT, "keeps the last test model in the game" );
2343 cmdSystem->AddCommand( "testAnim", idTestModel::TestAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests an animation", idTestModel::ArgCompletion_TestAnim );
2344 cmdSystem->AddCommand( "testParticleStopTime", idTestModel::TestParticleStopTime_f,CMD_FL_GAME|CMD_FL_CHEAT, "tests particle stop time on a test model" );
2345 cmdSystem->AddCommand( "nextAnim", idTestModel::TestModelNextAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation on test model" );
2346 cmdSystem->AddCommand( "prevAnim", idTestModel::TestModelPrevAnim_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation on test model" );
2347 cmdSystem->AddCommand( "nextFrame", idTestModel::TestModelNextFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows next animation frame on test model" );
2348 cmdSystem->AddCommand( "prevFrame", idTestModel::TestModelPrevFrame_f, CMD_FL_GAME|CMD_FL_CHEAT, "shows previous animation frame on test model" );
2349 cmdSystem->AddCommand( "testBlend", idTestModel::TestBlend_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests animation blending" );
2350 cmdSystem->AddCommand( "reloadScript", Cmd_ReloadScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads scripts" );
2351 cmdSystem->AddCommand( "script", Cmd_Script_f, CMD_FL_GAME|CMD_FL_CHEAT, "executes a line of script" );
2352 cmdSystem->AddCommand( "listCollisionModels", Cmd_ListCollisionModels_f, CMD_FL_GAME, "lists collision models" );
2353 cmdSystem->AddCommand( "collisionModelInfo", Cmd_CollisionModelInfo_f, CMD_FL_GAME, "shows collision model info" );
2354 cmdSystem->AddCommand( "reexportmodels", Cmd_ReexportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "reexports models", ArgCompletion_DefFile );
2355 cmdSystem->AddCommand( "reloadanims", Cmd_ReloadAnims_f, CMD_FL_GAME|CMD_FL_CHEAT, "reloads animations" );
2356 cmdSystem->AddCommand( "listAnims", Cmd_ListAnims_f, CMD_FL_GAME, "lists all animations" );
2357 cmdSystem->AddCommand( "aasStats", Cmd_AASStats_f, CMD_FL_GAME, "shows AAS stats" );
2358 cmdSystem->AddCommand( "testDamage", Cmd_TestDamage_f, CMD_FL_GAME|CMD_FL_CHEAT, "tests a damage def", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
2359 cmdSystem->AddCommand( "weaponSplat", Cmd_WeaponSplat_f, CMD_FL_GAME|CMD_FL_CHEAT, "projects a blood splat on the player weapon" );
2360 cmdSystem->AddCommand( "saveSelected", Cmd_SaveSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves the selected entity to the .map file" );
2361 cmdSystem->AddCommand( "deleteSelected", Cmd_DeleteSelected_f, CMD_FL_GAME|CMD_FL_CHEAT, "deletes selected entity" );
2362 cmdSystem->AddCommand( "saveMoveables", Cmd_SaveMoveables_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all moveables to the .map file" );
2363 cmdSystem->AddCommand( "saveRagdolls", Cmd_SaveRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "save all ragdoll poses to the .map file" );
2364 cmdSystem->AddCommand( "bindRagdoll", Cmd_BindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "binds ragdoll at the current drag position" );
2365 cmdSystem->AddCommand( "unbindRagdoll", Cmd_UnbindRagdoll_f, CMD_FL_GAME|CMD_FL_CHEAT, "unbinds the selected ragdoll" );
2366 cmdSystem->AddCommand( "saveLights", Cmd_SaveLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" );
2367 cmdSystem->AddCommand( "saveParticles", Cmd_SaveParticles_f, CMD_FL_GAME|CMD_FL_CHEAT, "saves all lights to the .map file" );
2368 cmdSystem->AddCommand( "clearLights", Cmd_ClearLights_f, CMD_FL_GAME|CMD_FL_CHEAT, "clears all lights" );
2369 cmdSystem->AddCommand( "gameError", Cmd_GameError_f, CMD_FL_GAME|CMD_FL_CHEAT, "causes a game error" );
2371 #ifndef ID_DEMO_BUILD
2372 cmdSystem->AddCommand( "disasmScript", Cmd_DisasmScript_f, CMD_FL_GAME|CMD_FL_CHEAT, "disassembles script" );
2373 cmdSystem->AddCommand( "recordViewNotes", Cmd_RecordViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "record the current view position with notes" );
2374 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" );
2375 cmdSystem->AddCommand( "closeViewNotes", Cmd_CloseViewNotes_f, CMD_FL_GAME|CMD_FL_CHEAT, "close the view showing any notes for this map" );
2376 cmdSystem->AddCommand( "exportmodels", Cmd_ExportModels_f, CMD_FL_GAME|CMD_FL_CHEAT, "exports models", ArgCompletion_DefFile );
2378 // multiplayer client commands ( replaces old impulses stuff )
2379 cmdSystem->AddCommand( "clientDropWeapon", idMultiplayerGame::DropWeapon_f, CMD_FL_GAME, "drop current weapon" );
2380 cmdSystem->AddCommand( "clientMessageMode", idMultiplayerGame::MessageMode_f, CMD_FL_GAME, "ingame gui message mode" );
2382 // cmdSystem->AddCommand( "clientVote", idMultiplayerGame::Vote_f, CMD_FL_GAME, "cast your vote: clientVote yes | no" );
2383 // cmdSystem->AddCommand( "clientCallVote", idMultiplayerGame::CallVote_f, CMD_FL_GAME, "call a vote: clientCallVote si_.. proposed_value" );
2384 cmdSystem->AddCommand( "clientVoiceChat", idMultiplayerGame::VoiceChat_f, CMD_FL_GAME, "voice chats: clientVoiceChat <sound shader>" );
2385 cmdSystem->AddCommand( "clientVoiceChatTeam", idMultiplayerGame::VoiceChatTeam_f, CMD_FL_GAME, "team voice chats: clientVoiceChat <sound shader>" );
2387 // multiplayer server commands
2388 cmdSystem->AddCommand( "serverMapRestart", idGameLocal::MapRestart_f, CMD_FL_GAME, "restart the current game" );
2389 cmdSystem->AddCommand( "serverForceReady", idMultiplayerGame::ForceReady_f,CMD_FL_GAME, "force all players ready" );
2390 cmdSystem->AddCommand( "serverNextMap", idGameLocal::NextMap_f, CMD_FL_GAME, "change to the next map" );
2393 // localization help commands
2394 cmdSystem->AddCommand( "nextGUI", Cmd_NextGUI_f, CMD_FL_GAME|CMD_FL_CHEAT, "teleport the player to the next func_static with a gui" );
2395 cmdSystem->AddCommand( "testid", Cmd_TestId_f, CMD_FL_GAME|CMD_FL_CHEAT, "output the string for the specified id." );
2400 idGameLocal::ShutdownConsoleCommands
2403 void idGameLocal::ShutdownConsoleCommands( void ) {
2404 cmdSystem->RemoveFlaggedCommands( CMD_FL_GAME );