1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8 
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.
13 
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.
18 
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/>.
21 
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.
23 
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.
25 
26 ===========================================================================
27 */
28 
29 #include "sys/platform.h"
30 #include "idlib/LangDict.h"
31 #include "framework/async/NetworkSystem.h"
32 #include "framework/FileSystem.h"
33 
34 #include "gamesys/TypeInfo.h"
35 #include "gamesys/SysCvar.h"
36 #include "script/Script_Thread.h"
37 #include "ai/AI.h"
38 #include "anim/Anim_Testmodel.h"
39 #include "Entity.h"
40 #include "Moveable.h"
41 #include "WorldSpawn.h"
42 #include "Fx.h"
43 #include "Misc.h"
44 
45 #include "SysCmds.h"
46 
47 /*
48 ==================
49 Cmd_GetFloatArg
50 ==================
51 */
Cmd_GetFloatArg(const idCmdArgs & args,int & argNum)52 float Cmd_GetFloatArg( const idCmdArgs &args, int &argNum ) {
53 	const char *value;
54 
55 	value = args.Argv( argNum++ );
56 	return atof( value );
57 }
58 
59 /*
60 ===================
61 Cmd_EntityList_f
62 ===================
63 */
Cmd_EntityList_f(const idCmdArgs & args)64 void Cmd_EntityList_f( const idCmdArgs &args ) {
65 	int			e;
66 	idEntity	*check;
67 	int			count;
68 	size_t		size;
69 	idStr		match;
70 
71 	if ( args.Argc() > 1 ) {
72 		match = args.Args();
73 		match.Replace( " ", "" );
74 	} else {
75 		match = "";
76 	}
77 
78 	count = 0;
79 	size = 0;
80 
81 	gameLocal.Printf( "%-4s  %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" );
82 	gameLocal.Printf( "--------------------------------------------------------------------\n" );
83 	for( e = 0; e < MAX_GENTITIES; e++ ) {
84 		check = gameLocal.entities[ e ];
85 
86 		if ( !check ) {
87 			continue;
88 		}
89 
90 		if ( !check->name.Filter( match, true ) ) {
91 			continue;
92 		}
93 
94 		gameLocal.Printf( "%4i: %-20s %-20s %s\n", e,
95 			check->GetEntityDefName(), check->GetClassname(), check->name.c_str() );
96 
97 		count++;
98 		size += check->spawnArgs.Allocated();
99 	}
100 
101 	gameLocal.Printf( "...%d entities\n...%zd bytes of spawnargs\n", count, size );
102 }
103 
104 /*
105 ===================
106 Cmd_ActiveEntityList_f
107 ===================
108 */
Cmd_ActiveEntityList_f(const idCmdArgs & args)109 void Cmd_ActiveEntityList_f( const idCmdArgs &args ) {
110 	idEntity	*check;
111 	int			count;
112 
113 	count = 0;
114 
115 	gameLocal.Printf( "%-4s  %-20s %-20s %s\n", " Num", "EntityDef", "Class", "Name" );
116 	gameLocal.Printf( "--------------------------------------------------------------------\n" );
117 	for( check = gameLocal.activeEntities.Next(); check != NULL; check = check->activeNode.Next() ) {
118 		char	dormant = check->fl.isDormant ? '-' : ' ';
119 		gameLocal.Printf( "%4i:%c%-20s %-20s %s\n", check->entityNumber, dormant, check->GetEntityDefName(), check->GetClassname(), check->name.c_str() );
120 		count++;
121 	}
122 
123 	gameLocal.Printf( "...%d active entities\n", count );
124 }
125 
126 /*
127 ===================
128 Cmd_ListSpawnArgs_f
129 ===================
130 */
Cmd_ListSpawnArgs_f(const idCmdArgs & args)131 void Cmd_ListSpawnArgs_f( const idCmdArgs &args ) {
132 	int i;
133 	idEntity *ent;
134 
135 	ent = gameLocal.FindEntity( args.Argv( 1 ) );
136 	if ( !ent ) {
137 		gameLocal.Printf( "entity not found\n" );
138 		return;
139 	}
140 
141 	for ( i = 0; i < ent->spawnArgs.GetNumKeyVals(); i++ ) {
142 		const idKeyValue *kv = ent->spawnArgs.GetKeyVal( i );
143 		gameLocal.Printf( "\"%s\"  " S_COLOR_WHITE "\"%s\"\n", kv->GetKey().c_str(), kv->GetValue().c_str() );
144 	}
145 }
146 
147 /*
148 ===================
149 Cmd_ReloadScript_f
150 ===================
151 */
Cmd_ReloadScript_f(const idCmdArgs & args)152 void Cmd_ReloadScript_f( const idCmdArgs &args ) {
153 	// shutdown the map because entities may point to script objects
154 	gameLocal.MapShutdown();
155 
156 	// recompile the scripts
157 	gameLocal.program.Startup( SCRIPT_DEFAULT );
158 
159 	// error out so that the user can rerun the scripts
160 	gameLocal.Error( "Exiting map to reload scripts" );
161 }
162 
163 /*
164 ===================
165 Cmd_Script_f
166 ===================
167 */
Cmd_Script_f(const idCmdArgs & args)168 void Cmd_Script_f( const idCmdArgs &args ) {
169 	const char *	script;
170 	idStr			text;
171 	idStr			funcname;
172 	static int		funccount = 0;
173 	idThread *		thread;
174 	const function_t *func;
175 	idEntity		*ent;
176 
177 	if ( !gameLocal.CheatsOk() ) {
178 		return;
179 	}
180 
181 	sprintf( funcname, "ConsoleFunction_%d", funccount++ );
182 
183 	script = args.Args();
184 	sprintf( text, "void %s() {%s;}\n", funcname.c_str(), script );
185 	if ( gameLocal.program.CompileText( "console", text, true ) ) {
186 		func = gameLocal.program.FindFunction( funcname );
187 		if ( func ) {
188 			// set all the entity names in case the user named one in the script that wasn't referenced in the default script
189 			for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
190 				gameLocal.program.SetEntity( ent->name, ent );
191 			}
192 
193 			thread = new idThread( func );
194 			thread->Start();
195 		}
196 	}
197 }
198 
199 /*
200 ==================
201 KillEntities
202 
203 Kills all the entities of the given class in a level.
204 ==================
205 */
KillEntities(const idCmdArgs & args,const idTypeInfo & superClass)206 void KillEntities( const idCmdArgs &args, const idTypeInfo &superClass ) {
207 	idEntity	*ent;
208 	idStrList	ignore;
209 	const char *name;
210 	int			i;
211 
212 	if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
213 		return;
214 	}
215 
216 	for( i = 1; i < args.Argc(); i++ ) {
217 		name = args.Argv( i );
218 		ignore.Append( name );
219 	}
220 
221 	for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
222 		if ( ent->IsType( superClass ) ) {
223 			for( i = 0; i < ignore.Num(); i++ ) {
224 				if ( ignore[ i ] == ent->name ) {
225 					break;
226 				}
227 			}
228 
229 			if ( i >= ignore.Num() ) {
230 				ent->PostEventMS( &EV_Remove, 0 );
231 			}
232 		}
233 	}
234 }
235 
236 /*
237 ==================
238 Cmd_KillMonsters_f
239 
240 Kills all the monsters in a level.
241 ==================
242 */
Cmd_KillMonsters_f(const idCmdArgs & args)243 void Cmd_KillMonsters_f( const idCmdArgs &args ) {
244 	KillEntities( args, idAI::Type );
245 
246 	// kill any projectiles as well since they have pointers to the monster that created them
247 	KillEntities( args, idProjectile::Type );
248 }
249 
250 /*
251 ==================
252 Cmd_KillMovables_f
253 
254 Kills all the moveables in a level.
255 ==================
256 */
Cmd_KillMovables_f(const idCmdArgs & args)257 void Cmd_KillMovables_f( const idCmdArgs &args ) {
258 	if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
259 		return;
260 	}
261 	KillEntities( args, idMoveable::Type );
262 }
263 
264 /*
265 ==================
266 Cmd_KillRagdolls_f
267 
268 Kills all the ragdolls in a level.
269 ==================
270 */
Cmd_KillRagdolls_f(const idCmdArgs & args)271 void Cmd_KillRagdolls_f( const idCmdArgs &args ) {
272 	if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
273 		return;
274 	}
275 	KillEntities( args, idAFEntity_Generic::Type );
276 	KillEntities( args, idAFEntity_WithAttachedHead::Type );
277 }
278 
279 /*
280 ==================
281 Cmd_Give_f
282 
283 Give items to a client
284 ==================
285 */
Cmd_Give_f(const idCmdArgs & args)286 void Cmd_Give_f( const idCmdArgs &args ) {
287 	const char *name;
288 	int			i;
289 	bool		give_all;
290 	idPlayer	*player;
291 
292 	player = gameLocal.GetLocalPlayer();
293 	if ( !player || !gameLocal.CheatsOk() ) {
294 		return;
295 	}
296 
297 	name = args.Argv( 1 );
298 
299 	if ( idStr::Icmp( name, "all" ) == 0 ) {
300 		give_all = true;
301 	} else {
302 		give_all = false;
303 	}
304 
305 	if ( give_all || ( idStr::Cmpn( name, "weapon", 6 ) == 0 ) ) {
306 		if ( gameLocal.world->spawnArgs.GetBool( "no_Weapons" ) ) {
307 			gameLocal.world->spawnArgs.SetBool( "no_Weapons", false );
308 			for( i = 0; i < gameLocal.numClients; i++ ) {
309 				if ( gameLocal.entities[ i ] ) {
310 					gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, gameLocal.entities[ i ]->spawnArgs.GetString( "def_weapon1" ) );
311 				}
312 			}
313 		}
314 	}
315 
316 	if ( ( idStr::Cmpn( name, "weapon_", 7 ) == 0 ) || ( idStr::Cmpn( name, "item_", 5 ) == 0 ) || ( idStr::Cmpn( name, "ammo_", 5 ) == 0 ) ) {
317 		player->GiveItem( name );
318 		return;
319 	}
320 
321 	if ( give_all || idStr::Icmp( name, "health" ) == 0 )	{
322 		player->health = player->inventory.maxHealth;
323 		if ( !give_all ) {
324 			return;
325 		}
326 	}
327 
328 	if ( give_all || idStr::Icmp( name, "weapons" ) == 0 ) {
329 		player->inventory.weapons = BIT( MAX_WEAPONS ) - 1;
330 		player->CacheWeapons();
331 
332 		if ( !give_all ) {
333 			return;
334 		}
335 	}
336 
337 	if ( give_all || idStr::Icmp( name, "ammo" ) == 0 ) {
338 		for ( i = 0 ; i < AMMO_NUMTYPES; i++ ) {
339 			player->inventory.ammo[ i ] = player->inventory.MaxAmmoForAmmoClass( player, idWeapon::GetAmmoNameForNum( ( ammo_t )i ) );
340 		}
341 		if ( !give_all ) {
342 			return;
343 		}
344 	}
345 
346 	if ( give_all || idStr::Icmp( name, "armor" ) == 0 ) {
347 		player->inventory.armor = player->inventory.maxarmor;
348 		if ( !give_all ) {
349 			return;
350 		}
351 	}
352 
353 	if ( idStr::Icmp( name, "berserk" ) == 0 ) {
354 		player->GivePowerUp( BERSERK, SEC2MS( 30.0f ) );
355 		return;
356 	}
357 
358 	if ( idStr::Icmp( name, "invis" ) == 0 ) {
359 		player->GivePowerUp( INVISIBILITY, SEC2MS( 30.0f ) );
360 		return;
361 	}
362 
363 	if ( idStr::Icmp( name, "pda" ) == 0 ) {
364 		player->GivePDA( args.Argv(2), NULL );
365 		return;
366 	}
367 
368 	if ( idStr::Icmp( name, "video" ) == 0 ) {
369 		player->GiveVideo( args.Argv(2), NULL );
370 		return;
371 	}
372 
373 	if ( !give_all && !player->Give( args.Argv(1), args.Argv(2) ) ) {
374 		gameLocal.Printf( "unknown item\n" );
375 	}
376 }
377 
378 /*
379 ==================
380 Cmd_CenterView_f
381 
382 Centers the players pitch
383 ==================
384 */
Cmd_CenterView_f(const idCmdArgs & args)385 void Cmd_CenterView_f( const idCmdArgs &args ) {
386 	idPlayer	*player;
387 	idAngles	ang;
388 
389 	player = gameLocal.GetLocalPlayer();
390 	if ( !player ) {
391 		return;
392 	}
393 
394 	ang = player->viewAngles;
395 	ang.pitch = 0.0f;
396 	player->SetViewAngles( ang );
397 }
398 
399 /*
400 ==================
401 Cmd_God_f
402 
403 Sets client to godmode
404 
405 argv(0) god
406 ==================
407 */
Cmd_God_f(const idCmdArgs & args)408 void Cmd_God_f( const idCmdArgs &args ) {
409 	const char	*msg;
410 	idPlayer	*player;
411 
412 	player = gameLocal.GetLocalPlayer();
413 	if ( !player || !gameLocal.CheatsOk() ) {
414 		return;
415 	}
416 
417 	if ( player->godmode ) {
418 		player->godmode = false;
419 		msg = "godmode OFF\n";
420 	} else {
421 		player->godmode = true;
422 		msg = "godmode ON\n";
423 	}
424 
425 	gameLocal.Printf( "%s", msg );
426 }
427 
428 /*
429 ==================
430 Cmd_Notarget_f
431 
432 Sets client to notarget
433 
434 argv(0) notarget
435 ==================
436 */
Cmd_Notarget_f(const idCmdArgs & args)437 void Cmd_Notarget_f( const idCmdArgs &args ) {
438 	const char	*msg;
439 	idPlayer	*player;
440 
441 	player = gameLocal.GetLocalPlayer();
442 	if ( !player || !gameLocal.CheatsOk() ) {
443 		return;
444 	}
445 
446 	if ( player->fl.notarget ) {
447 		player->fl.notarget = false;
448 		msg = "notarget OFF\n";
449 	} else {
450 		player->fl.notarget = true;
451 		msg = "notarget ON\n";
452 	}
453 
454 	gameLocal.Printf( "%s", msg );
455 }
456 
457 /*
458 ==================
459 Cmd_Noclip_f
460 
461 argv(0) noclip
462 ==================
463 */
Cmd_Noclip_f(const idCmdArgs & args)464 void Cmd_Noclip_f( const idCmdArgs &args ) {
465 	const char	*msg;
466 	idPlayer	*player;
467 
468 	player = gameLocal.GetLocalPlayer();
469 	if ( !player || !gameLocal.CheatsOk() ) {
470 		return;
471 	}
472 
473 	if ( player->noclip ) {
474 		msg = "noclip OFF\n";
475 	} else {
476 		msg = "noclip ON\n";
477 	}
478 	player->noclip = !player->noclip;
479 
480 	gameLocal.Printf( "%s", msg );
481 }
482 
483 /*
484 =================
485 Cmd_Kill_f
486 =================
487 */
Cmd_Kill_f(const idCmdArgs & args)488 void Cmd_Kill_f( const idCmdArgs &args ) {
489 	idPlayer	*player;
490 
491 	if ( gameLocal.isMultiplayer ) {
492 		if ( gameLocal.isClient ) {
493 			idBitMsg	outMsg;
494 			byte		msgBuf[ MAX_GAME_MESSAGE_SIZE ];
495 			outMsg.Init( msgBuf, sizeof( msgBuf ) );
496 			outMsg.WriteByte( GAME_RELIABLE_MESSAGE_KILL );
497 			networkSystem->ClientSendReliableMessage( outMsg );
498 		} else {
499 			player = gameLocal.GetClientByCmdArgs( args );
500 			if ( !player ) {
501 				common->Printf( "kill <client nickname> or kill <client index>\n" );
502 				return;
503 			}
504 			player->Kill( false, false );
505 			cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say killed client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
506 		}
507 	} else {
508 		player = gameLocal.GetLocalPlayer();
509 		if ( !player ) {
510 			return;
511 		}
512 		player->Kill( false, false );
513 	}
514 }
515 
516 /*
517 =================
518 Cmd_PlayerModel_f
519 =================
520 */
Cmd_PlayerModel_f(const idCmdArgs & args)521 void Cmd_PlayerModel_f( const idCmdArgs &args ) {
522 	idPlayer	*player;
523 	const char *name;
524 	idVec3		pos;
525 	idAngles	ang;
526 
527 	player = gameLocal.GetLocalPlayer();
528 	if ( !player || !gameLocal.CheatsOk() ) {
529 		return;
530 	}
531 
532 	if ( args.Argc() < 2 ) {
533 		gameLocal.Printf( "usage: playerModel <modelname>\n" );
534 		return;
535 	}
536 
537 	name = args.Argv( 1 );
538 	player->spawnArgs.Set( "model", name );
539 
540 	pos = player->GetPhysics()->GetOrigin();
541 	ang = player->viewAngles;
542 	player->SpawnToPoint( pos, ang );
543 }
544 
545 /*
546 ==================
547 Cmd_Say
548 ==================
549 */
Cmd_Say(bool team,const idCmdArgs & args)550 static void Cmd_Say( bool team, const idCmdArgs &args ) {
551 	const char *name;
552 	idStr text;
553 	const char *cmd = team ? "sayTeam" : "say" ;
554 
555 	if ( !gameLocal.isMultiplayer ) {
556 		gameLocal.Printf( "%s can only be used in a multiplayer game\n", cmd );
557 		return;
558 	}
559 
560 	if ( args.Argc() < 2 ) {
561 		gameLocal.Printf( "usage: %s <text>\n", cmd );
562 		return;
563 	}
564 
565 	text = args.Args();
566 	if ( text.Length() == 0 ) {
567 		return;
568 	}
569 
570 	if ( text[ text.Length() - 1 ] == '\n' ) {
571 		text[ text.Length() - 1 ] = '\0';
572 	}
573 	name = "player";
574 
575 	idPlayer *	player;
576 
577 	// here we need to special case a listen server to use the real client name instead of "server"
578 	// "server" will only appear on a dedicated server
579 	if ( gameLocal.isClient || cvarSystem->GetCVarInteger( "net_serverDedicated" ) == 0 ) {
580 		player = gameLocal.localClientNum >= 0 ? static_cast<idPlayer *>( gameLocal.entities[ gameLocal.localClientNum ] ) : NULL;
581 		if ( player ) {
582 			name = player->GetUserInfo()->GetString( "ui_name", "player" );
583 		}
584 	} else {
585 		name = "server";
586 	}
587 
588 	if ( gameLocal.isClient ) {
589 		idBitMsg	outMsg;
590 		byte		msgBuf[ 256 ];
591 		outMsg.Init( msgBuf, sizeof( msgBuf ) );
592 		outMsg.WriteByte( team ? GAME_RELIABLE_MESSAGE_TCHAT : GAME_RELIABLE_MESSAGE_CHAT );
593 		outMsg.WriteString( name );
594 		outMsg.WriteString( text, -1, false );
595 		networkSystem->ClientSendReliableMessage( outMsg );
596 	} else {
597 		gameLocal.mpGame.ProcessChatMessage( gameLocal.localClientNum, team, name, text, NULL );
598 	}
599 }
600 
601 /*
602 ==================
603 Cmd_Say_f
604 ==================
605 */
Cmd_Say_f(const idCmdArgs & args)606 static void Cmd_Say_f( const idCmdArgs &args ) {
607 	Cmd_Say( false, args );
608 }
609 
610 /*
611 ==================
612 Cmd_SayTeam_f
613 ==================
614 */
Cmd_SayTeam_f(const idCmdArgs & args)615 static void Cmd_SayTeam_f( const idCmdArgs &args ) {
616 	Cmd_Say( true, args );
617 }
618 
619 /*
620 ==================
621 Cmd_AddChatLine_f
622 ==================
623 */
Cmd_AddChatLine_f(const idCmdArgs & args)624 static void Cmd_AddChatLine_f( const idCmdArgs &args ) {
625 	gameLocal.mpGame.AddChatLine( args.Argv( 1 ) );
626 }
627 
628 /*
629 ==================
630 Cmd_Kick_f
631 ==================
632 */
Cmd_Kick_f(const idCmdArgs & args)633 static void Cmd_Kick_f( const idCmdArgs &args ) {
634 	idPlayer *player;
635 
636 	if ( !gameLocal.isMultiplayer ) {
637 		gameLocal.Printf( "kick can only be used in a multiplayer game\n" );
638 		return;
639 	}
640 
641 	if ( gameLocal.isClient ) {
642 		gameLocal.Printf( "You have no such power. This is a server command\n" );
643 		return;
644 	}
645 
646 	player = gameLocal.GetClientByCmdArgs( args );
647 	if ( !player ) {
648 		gameLocal.Printf( "usage: kick <client nickname> or kick <client index>\n" );
649 		return;
650 	}
651 	cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say kicking out client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
652 	cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "kick %d\n", player->entityNumber ) );
653 }
654 
655 /*
656 ==================
657 Cmd_GetViewpos_f
658 ==================
659 */
Cmd_GetViewpos_f(const idCmdArgs & args)660 void Cmd_GetViewpos_f( const idCmdArgs &args ) {
661 	idPlayer	*player;
662 	idVec3		origin;
663 	idMat3		axis;
664 
665 	player = gameLocal.GetLocalPlayer();
666 	if ( !player ) {
667 		return;
668 	}
669 
670 	const renderView_t *view = player->GetRenderView();
671 	if ( view ) {
672 		gameLocal.Printf( "(%s) %.1f\n", view->vieworg.ToString(), view->viewaxis[0].ToYaw() );
673 	} else {
674 		player->GetViewPos( origin, axis );
675 		gameLocal.Printf( "(%s) %.1f\n", origin.ToString(), axis[0].ToYaw() );
676 	}
677 }
678 
679 /*
680 =================
681 Cmd_SetViewpos_f
682 =================
683 */
Cmd_SetViewpos_f(const idCmdArgs & args)684 void Cmd_SetViewpos_f( const idCmdArgs &args ) {
685 	idVec3		origin;
686 	idAngles	angles;
687 	int			i;
688 	idPlayer	*player;
689 
690 	player = gameLocal.GetLocalPlayer();
691 	if ( !player || !gameLocal.CheatsOk() ) {
692 		return;
693 	}
694 
695 	if ( ( args.Argc() != 4 ) && ( args.Argc() != 5 ) ) {
696 		gameLocal.Printf( "usage: setviewpos <x> <y> <z> <yaw>\n" );
697 		return;
698 	}
699 
700 	angles.Zero();
701 	if ( args.Argc() == 5 ) {
702 		angles.yaw = atof( args.Argv( 4 ) );
703 	}
704 
705 	for ( i = 0 ; i < 3 ; i++ ) {
706 		origin[i] = atof( args.Argv( i + 1 ) );
707 	}
708 	origin.z -= pm_normalviewheight.GetFloat() - 0.25f;
709 
710 	player->Teleport( origin, angles, NULL );
711 }
712 
713 /*
714 =================
715 Cmd_Teleport_f
716 =================
717 */
Cmd_Teleport_f(const idCmdArgs & args)718 void Cmd_Teleport_f( const idCmdArgs &args ) {
719 	idVec3		origin;
720 	idAngles	angles;
721 	idPlayer	*player;
722 	idEntity	*ent;
723 
724 	player = gameLocal.GetLocalPlayer();
725 	if ( !player || !gameLocal.CheatsOk() ) {
726 		return;
727 	}
728 
729 	if ( args.Argc() != 2 ) {
730 		gameLocal.Printf( "usage: teleport <name of entity to teleport to>\n" );
731 		return;
732 	}
733 
734 	ent = gameLocal.FindEntity( args.Argv( 1 ) );
735 	if ( !ent ) {
736 		gameLocal.Printf( "entity not found\n" );
737 		return;
738 	}
739 
740 	angles.Zero();
741 	angles.yaw = ent->GetPhysics()->GetAxis()[ 0 ].ToYaw();
742 	origin = ent->GetPhysics()->GetOrigin();
743 
744 	player->Teleport( origin, angles, ent );
745 }
746 
747 /*
748 =================
749 Cmd_Trigger_f
750 =================
751 */
Cmd_Trigger_f(const idCmdArgs & args)752 void Cmd_Trigger_f( const idCmdArgs &args ) {
753 	idVec3		origin;
754 	idAngles	angles;
755 	idPlayer	*player;
756 	idEntity	*ent;
757 
758 	player = gameLocal.GetLocalPlayer();
759 	if ( !player || !gameLocal.CheatsOk() ) {
760 		return;
761 	}
762 
763 	if ( args.Argc() != 2 ) {
764 		gameLocal.Printf( "usage: trigger <name of entity to trigger>\n" );
765 		return;
766 	}
767 
768 	ent = gameLocal.FindEntity( args.Argv( 1 ) );
769 	if ( !ent ) {
770 		gameLocal.Printf( "entity not found\n" );
771 		return;
772 	}
773 
774 	ent->Signal( SIG_TRIGGER );
775 	ent->ProcessEvent( &EV_Activate, player );
776 	ent->TriggerGuis();
777 }
778 
779 /*
780 ===================
781 Cmd_Spawn_f
782 ===================
783 */
Cmd_Spawn_f(const idCmdArgs & args)784 void Cmd_Spawn_f( const idCmdArgs &args ) {
785 	const char *key, *value;
786 	int			i;
787 	float		yaw;
788 	idVec3		org;
789 	idPlayer	*player;
790 	idDict		dict;
791 
792 	player = gameLocal.GetLocalPlayer();
793 	if ( !player || !gameLocal.CheatsOk( false ) ) {
794 		return;
795 	}
796 
797 	if ( args.Argc() & 1 ) {	// must always have an even number of arguments
798 		gameLocal.Printf( "usage: spawn classname [key/value pairs]\n" );
799 		return;
800 	}
801 
802 	yaw = player->viewAngles.yaw;
803 
804 	value = args.Argv( 1 );
805 	dict.Set( "classname", value );
806 	dict.Set( "angle", va( "%f", yaw + 180 ) );
807 
808 	org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 );
809 	dict.Set( "origin", org.ToString() );
810 
811 	for( i = 2; i < args.Argc() - 1; i += 2 ) {
812 
813 		key = args.Argv( i );
814 		value = args.Argv( i + 1 );
815 
816 		dict.Set( key, value );
817 	}
818 
819 	gameLocal.SpawnEntityDef( dict );
820 }
821 
822 /*
823 ==================
824 Cmd_Damage_f
825 
826 Damages the specified entity
827 ==================
828 */
Cmd_Damage_f(const idCmdArgs & args)829 void Cmd_Damage_f( const idCmdArgs &args ) {
830 	if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
831 		return;
832 	}
833 	if ( args.Argc() != 3 ) {
834 		gameLocal.Printf( "usage: damage <name of entity to damage> <damage>\n" );
835 		return;
836 	}
837 
838 	idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) );
839 	if ( !ent ) {
840 		gameLocal.Printf( "entity not found\n" );
841 		return;
842 	}
843 
844 	ent->Damage( gameLocal.world, gameLocal.world, idVec3( 0, 0, 1 ), "damage_moverCrush", atoi( args.Argv( 2 ) ), INVALID_JOINT );
845 }
846 
847 
848 /*
849 ==================
850 Cmd_Remove_f
851 
852 Removes the specified entity
853 ==================
854 */
Cmd_Remove_f(const idCmdArgs & args)855 void Cmd_Remove_f( const idCmdArgs &args ) {
856 	if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
857 		return;
858 	}
859 	if ( args.Argc() != 2 ) {
860 		gameLocal.Printf( "usage: remove <name of entity to remove>\n" );
861 		return;
862 	}
863 
864 	idEntity *ent = gameLocal.FindEntity( args.Argv( 1 ) );
865 	if ( !ent ) {
866 		gameLocal.Printf( "entity not found\n" );
867 		return;
868 	}
869 
870 	delete ent;
871 }
872 
873 /*
874 ===================
875 Cmd_TestLight_f
876 ===================
877 */
Cmd_TestLight_f(const idCmdArgs & args)878 void Cmd_TestLight_f( const idCmdArgs &args ) {
879 	int			i;
880 	idStr		filename;
881 	const char *key, *value, *name;
882 	idPlayer *	player;
883 	idDict		dict;
884 
885 	player = gameLocal.GetLocalPlayer();
886 	if ( !player || !gameLocal.CheatsOk( false ) ) {
887 		return;
888 	}
889 
890 	renderView_t	*rv = player->GetRenderView();
891 
892 	float fov = tan( idMath::M_DEG2RAD * rv->fov_x / 2 );
893 
894 
895 	dict.SetMatrix( "rotation", mat3_default );
896 	dict.SetVector( "origin", rv->vieworg );
897 	dict.SetVector( "light_target", rv->viewaxis[0] );
898 	dict.SetVector( "light_right", rv->viewaxis[1] * -fov );
899 	dict.SetVector( "light_up", rv->viewaxis[2] * fov );
900 	dict.SetVector( "light_start", rv->viewaxis[0] * 16 );
901 	dict.SetVector( "light_end", rv->viewaxis[0] * 1000 );
902 
903 	if ( args.Argc() >= 2 ) {
904 		value = args.Argv( 1 );
905 		filename = args.Argv(1);
906 		filename.DefaultFileExtension( ".tga" );
907 		dict.Set( "texture", filename );
908 	}
909 
910 	dict.Set( "classname", "light" );
911 	for( i = 2; i < args.Argc() - 1; i += 2 ) {
912 
913 		key = args.Argv( i );
914 		value = args.Argv( i + 1 );
915 
916 		dict.Set( key, value );
917 	}
918 
919 	for ( i = 0; i < MAX_GENTITIES; i++ ) {
920 		name = va( "spawned_light_%d", i );		// not just light_, or it might pick up a prelight shadow
921 		if ( !gameLocal.FindEntity( name ) ) {
922 			break;
923 		}
924 	}
925 	dict.Set( "name", name );
926 
927 	gameLocal.SpawnEntityDef( dict );
928 
929 	gameLocal.Printf( "Created new light\n");
930 }
931 
932 /*
933 ===================
934 Cmd_TestPointLight_f
935 ===================
936 */
Cmd_TestPointLight_f(const idCmdArgs & args)937 void Cmd_TestPointLight_f( const idCmdArgs &args ) {
938 	const char *key, *value, *name;
939 	int			i;
940 	idPlayer	*player;
941 	idDict		dict;
942 
943 	player = gameLocal.GetLocalPlayer();
944 	if ( !player || !gameLocal.CheatsOk( false ) ) {
945 		return;
946 	}
947 
948 	dict.SetVector("origin", player->GetRenderView()->vieworg);
949 
950 	if ( args.Argc() >= 2 ) {
951 		value = args.Argv( 1 );
952 		dict.Set("light", value);
953 	} else {
954 		dict.Set("light", "300");
955 	}
956 
957 	dict.Set( "classname", "light" );
958 	for( i = 2; i < args.Argc() - 1; i += 2 ) {
959 
960 		key = args.Argv( i );
961 		value = args.Argv( i + 1 );
962 
963 		dict.Set( key, value );
964 	}
965 
966 	for ( i = 0; i < MAX_GENTITIES; i++ ) {
967 		name = va( "light_%d", i );
968 		if ( !gameLocal.FindEntity( name ) ) {
969 			break;
970 		}
971 	}
972 	dict.Set( "name", name );
973 
974 	gameLocal.SpawnEntityDef( dict );
975 
976 	gameLocal.Printf( "Created new point light\n");
977 }
978 
979 /*
980 ==================
981 Cmd_PopLight_f
982 ==================
983 */
Cmd_PopLight_f(const idCmdArgs & args)984 void Cmd_PopLight_f( const idCmdArgs &args ) {
985 	idEntity	*ent;
986 	idMapEntity *mapEnt;
987 	idMapFile	*mapFile = gameLocal.GetLevelMap();
988 	idLight		*lastLight;
989 	int			last;
990 
991 	if ( !gameLocal.CheatsOk() ) {
992 		return;
993 	}
994 
995 	bool removeFromMap = ( args.Argc() > 1 );
996 
997 	lastLight = NULL;
998 	last = -1;
999 	for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
1000 		if ( !ent->IsType( idLight::Type ) ) {
1001 			continue;
1002 		}
1003 
1004 		if ( gameLocal.spawnIds[ ent->entityNumber ] > last ) {
1005 			last = gameLocal.spawnIds[ ent->entityNumber ];
1006 			lastLight = static_cast<idLight*>( ent );
1007 		}
1008 	}
1009 
1010 	if ( lastLight ) {
1011 		// find map file entity
1012 		mapEnt = mapFile->FindEntity( lastLight->name );
1013 
1014 		if ( removeFromMap && mapEnt ) {
1015 			mapFile->RemoveEntity( mapEnt );
1016 		}
1017 		gameLocal.Printf( "Removing light %i\n", lastLight->GetLightDefHandle() );
1018 		delete lastLight;
1019 	} else {
1020 		gameLocal.Printf( "No lights to clear.\n" );
1021 	}
1022 
1023 }
1024 
1025 /*
1026 ====================
1027 Cmd_ClearLights_f
1028 ====================
1029 */
Cmd_ClearLights_f(const idCmdArgs & args)1030 void Cmd_ClearLights_f( const idCmdArgs &args ) {
1031 	idEntity *ent;
1032 	idEntity *next;
1033 	idLight *light;
1034 	idMapEntity *mapEnt;
1035 	idMapFile *mapFile = gameLocal.GetLevelMap();
1036 
1037 	bool removeFromMap = ( args.Argc() > 1 );
1038 
1039 	gameLocal.Printf( "Clearing all lights.\n" );
1040 	for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = next ) {
1041 		next = ent->spawnNode.Next();
1042 		if ( !ent->IsType( idLight::Type ) ) {
1043 			continue;
1044 		}
1045 
1046 		light = static_cast<idLight*>( ent );
1047 		mapEnt = mapFile->FindEntity( light->name );
1048 
1049 		if ( removeFromMap && mapEnt ) {
1050 			mapFile->RemoveEntity( mapEnt );
1051 		}
1052 
1053 		delete light;
1054 	}
1055 }
1056 
1057 /*
1058 ==================
1059 Cmd_TestFx_f
1060 ==================
1061 */
Cmd_TestFx_f(const idCmdArgs & args)1062 void Cmd_TestFx_f( const idCmdArgs &args ) {
1063 	idVec3		offset;
1064 	const char *name;
1065 	idPlayer *	player;
1066 	idDict		dict;
1067 
1068 	player = gameLocal.GetLocalPlayer();
1069 	if ( !player || !gameLocal.CheatsOk() ) {
1070 		return;
1071 	}
1072 
1073 	// delete the testModel if active
1074 	if ( gameLocal.testFx ) {
1075 		delete gameLocal.testFx;
1076 		gameLocal.testFx = NULL;
1077 	}
1078 
1079 	if ( args.Argc() < 2 ) {
1080 		return;
1081 	}
1082 
1083 	name = args.Argv( 1 );
1084 
1085 	offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f;
1086 
1087 	dict.Set( "origin", offset.ToString() );
1088 	dict.Set( "test", "1");
1089 	dict.Set( "fx", name );
1090 	gameLocal.testFx = ( idEntityFx * )gameLocal.SpawnEntityType( idEntityFx::Type, &dict );
1091 }
1092 
1093 #define MAX_DEBUGLINES	128
1094 
1095 typedef struct {
1096 	bool used;
1097 	idVec3 start, end;
1098 	int color;
1099 	bool blink;
1100 	bool arrow;
1101 } gameDebugLine_t;
1102 
1103 gameDebugLine_t debugLines[MAX_DEBUGLINES];
1104 
1105 /*
1106 ==================
1107 Cmd_AddDebugLine_f
1108 ==================
1109 */
Cmd_AddDebugLine_f(const idCmdArgs & args)1110 static void Cmd_AddDebugLine_f( const idCmdArgs &args ) {
1111 	int i, argNum;
1112 	const char *value;
1113 
1114 	if ( !gameLocal.CheatsOk() ) {
1115 		return;
1116 	}
1117 
1118 	if ( args.Argc () < 7 ) {
1119 		gameLocal.Printf( "usage: addline <x y z> <x y z> <color>\n" );
1120 		return;
1121 	}
1122 	for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1123 		if ( !debugLines[i].used ) {
1124 			break;
1125 		}
1126 	}
1127 	if ( i >= MAX_DEBUGLINES ) {
1128 		gameLocal.Printf( "no free debug lines\n" );
1129 		return;
1130 	}
1131 	value = args.Argv( 0 );
1132 	if ( !idStr::Icmp( value, "addarrow" ) ) {
1133 		debugLines[i].arrow = true;
1134 	} else {
1135 		debugLines[i].arrow = false;
1136 	}
1137 	debugLines[i].used = true;
1138 	debugLines[i].blink = false;
1139 	argNum = 1;
1140 	debugLines[i].start.x = Cmd_GetFloatArg( args, argNum );
1141 	debugLines[i].start.y = Cmd_GetFloatArg( args, argNum );
1142 	debugLines[i].start.z = Cmd_GetFloatArg( args, argNum );
1143 	debugLines[i].end.x = Cmd_GetFloatArg( args, argNum );
1144 	debugLines[i].end.y = Cmd_GetFloatArg( args, argNum );
1145 	debugLines[i].end.z = Cmd_GetFloatArg( args, argNum );
1146 	debugLines[i].color = Cmd_GetFloatArg( args, argNum );
1147 }
1148 
1149 /*
1150 ==================
1151 Cmd_RemoveDebugLine_f
1152 ==================
1153 */
Cmd_RemoveDebugLine_f(const idCmdArgs & args)1154 static void Cmd_RemoveDebugLine_f( const idCmdArgs &args ) {
1155 	int i, num;
1156 	const char *value;
1157 
1158 	if ( !gameLocal.CheatsOk() ) {
1159 		return;
1160 	}
1161 
1162 	if ( args.Argc () < 2 ) {
1163 		gameLocal.Printf( "usage: removeline <num>\n" );
1164 		return;
1165 	}
1166 	value = args.Argv( 1 );
1167 	num = atoi(value);
1168 	for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1169 		if ( debugLines[i].used ) {
1170 			if ( --num < 0 ) {
1171 				break;
1172 			}
1173 		}
1174 	}
1175 	if ( i >= MAX_DEBUGLINES ) {
1176 		gameLocal.Printf( "line not found\n" );
1177 		return;
1178 	}
1179 	debugLines[i].used = false;
1180 }
1181 
1182 /*
1183 ==================
1184 Cmd_BlinkDebugLine_f
1185 ==================
1186 */
Cmd_BlinkDebugLine_f(const idCmdArgs & args)1187 static void Cmd_BlinkDebugLine_f( const idCmdArgs &args ) {
1188 	int i, num;
1189 	const char *value;
1190 
1191 	if ( !gameLocal.CheatsOk() ) {
1192 		return;
1193 	}
1194 
1195 	if ( args.Argc () < 2 ) {
1196 		gameLocal.Printf( "usage: blinkline <num>\n" );
1197 		return;
1198 	}
1199 	value = args.Argv( 1 );
1200 	num = atoi( value );
1201 	for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1202 		if ( debugLines[i].used ) {
1203 			if ( --num < 0 ) {
1204 				break;
1205 			}
1206 		}
1207 	}
1208 	if ( i >= MAX_DEBUGLINES ) {
1209 		gameLocal.Printf( "line not found\n" );
1210 		return;
1211 	}
1212 	debugLines[i].blink = !debugLines[i].blink;
1213 }
1214 
1215 /*
1216 ==================
1217 PrintFloat
1218 ==================
1219 */
PrintFloat(float f)1220 static void PrintFloat( float f ) {
1221 	char buf[128];
1222 	int i;
1223 
1224 	for ( i = sprintf( buf, "%3.2f", f ); i < 7; i++ ) {
1225 		buf[i] = ' ';
1226 	}
1227 	buf[i] = '\0';
1228 	gameLocal.Printf( buf );
1229 }
1230 
1231 /*
1232 ==================
1233 Cmd_ListDebugLines_f
1234 ==================
1235 */
Cmd_ListDebugLines_f(const idCmdArgs & args)1236 static void Cmd_ListDebugLines_f( const idCmdArgs &args ) {
1237 	int i, num;
1238 
1239 	if ( !gameLocal.CheatsOk() ) {
1240 		return;
1241 	}
1242 
1243 	num = 0;
1244 	gameLocal.Printf( "line num: x1     y1     z1     x2     y2     z2     c  b  a\n" );
1245 	for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1246 		if ( debugLines[i].used ) {
1247 			gameLocal.Printf( "line %3d: ", num );
1248 			PrintFloat( debugLines[i].start.x );
1249 			PrintFloat( debugLines[i].start.y );
1250 			PrintFloat( debugLines[i].start.z );
1251 			PrintFloat( debugLines[i].end.x );
1252 			PrintFloat( debugLines[i].end.y );
1253 			PrintFloat( debugLines[i].end.z );
1254 			gameLocal.Printf( "%d  %d  %d\n", debugLines[i].color, debugLines[i].blink, debugLines[i].arrow );
1255 			num++;
1256 		}
1257 	}
1258 	if ( !num ) {
1259 		gameLocal.Printf( "no debug lines\n" );
1260 	}
1261 }
1262 
1263 /*
1264 ==================
1265 D_DrawDebugLines
1266 ==================
1267 */
D_DrawDebugLines(void)1268 void D_DrawDebugLines( void ) {
1269 	int i;
1270 	idVec3 forward, right, up, p1, p2;
1271 	idVec4 color;
1272 	float l;
1273 
1274 	for ( i = 0; i < MAX_DEBUGLINES; i++ ) {
1275 		if ( debugLines[i].used ) {
1276 			if ( !debugLines[i].blink || (gameLocal.time & (1<<9)) ) {
1277 				color = idVec4( debugLines[i].color&1, (debugLines[i].color>>1)&1, (debugLines[i].color>>2)&1, 1 );
1278 				gameRenderWorld->DebugLine( color, debugLines[i].start, debugLines[i].end );
1279 				//
1280 				if ( debugLines[i].arrow ) {
1281 					// draw a nice arrow
1282 					forward = debugLines[i].end - debugLines[i].start;
1283 					l = forward.Normalize() * 0.2f;
1284 					forward.NormalVectors( right, up);
1285 
1286 					if ( l > 3.0f ) {
1287 						l = 3.0f;
1288 					}
1289 					p1 = debugLines[i].end - l * forward + (l * 0.4f) * right;
1290 					p2 = debugLines[i].end - l * forward - (l * 0.4f) * right;
1291 					gameRenderWorld->DebugLine( color, debugLines[i].end, p1 );
1292 					gameRenderWorld->DebugLine( color, debugLines[i].end, p2 );
1293 					gameRenderWorld->DebugLine( color, p1, p2 );
1294 				}
1295 			}
1296 		}
1297 	}
1298 }
1299 
1300 /*
1301 ==================
1302 Cmd_ListCollisionModels_f
1303 ==================
1304 */
Cmd_ListCollisionModels_f(const idCmdArgs & args)1305 static void Cmd_ListCollisionModels_f( const idCmdArgs &args ) {
1306 	if ( !gameLocal.CheatsOk() ) {
1307 		return;
1308 	}
1309 
1310 	collisionModelManager->ListModels();
1311 }
1312 
1313 /*
1314 ==================
1315 Cmd_CollisionModelInfo_f
1316 ==================
1317 */
Cmd_CollisionModelInfo_f(const idCmdArgs & args)1318 static void Cmd_CollisionModelInfo_f( const idCmdArgs &args ) {
1319 	const char *value;
1320 
1321 	if ( !gameLocal.CheatsOk() ) {
1322 		return;
1323 	}
1324 
1325 	if ( args.Argc () < 2 ) {
1326 		gameLocal.Printf( "usage: collisionModelInfo <modelNum>\n"
1327 					"use 'all' instead of the model number for accumulated info\n" );
1328 		return;
1329 	}
1330 
1331 	value = args.Argv( 1 );
1332 	if ( !idStr::Icmp( value, "all" ) ) {
1333 		collisionModelManager->ModelInfo( -1 );
1334 	} else {
1335 		collisionModelManager->ModelInfo( atoi(value) );
1336 	}
1337 }
1338 
1339 /*
1340 ==================
1341 Cmd_ExportModels_f
1342 ==================
1343 */
Cmd_ExportModels_f(const idCmdArgs & args)1344 static void Cmd_ExportModels_f( const idCmdArgs &args ) {
1345 	idModelExport	exporter;
1346 	idStr			name;
1347 
1348 	// don't allow exporting models when cheats are disabled,
1349 	// but if we're not in the game, it's ok
1350 	if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
1351 		return;
1352 	}
1353 
1354 	if ( args.Argc() < 2 ) {
1355 		exporter.ExportModels( "def", ".def" );
1356 	} else {
1357 		name = args.Argv( 1 );
1358 		name = "def/" + name;
1359 		name.DefaultFileExtension( ".def" );
1360 		exporter.ExportDefFile( name );
1361 	}
1362 }
1363 
1364 /*
1365 ==================
1366 Cmd_ReexportModels_f
1367 ==================
1368 */
Cmd_ReexportModels_f(const idCmdArgs & args)1369 static void Cmd_ReexportModels_f( const idCmdArgs &args ) {
1370 	idModelExport	exporter;
1371 	idStr			name;
1372 
1373 	// don't allow exporting models when cheats are disabled,
1374 	// but if we're not in the game, it's ok
1375 	if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
1376 		return;
1377 	}
1378 
1379 	idAnimManager::forceExport = true;
1380 	if ( args.Argc() < 2 ) {
1381 		exporter.ExportModels( "def", ".def" );
1382 	} else {
1383 		name = args.Argv( 1 );
1384 		name = "def/" + name;
1385 		name.DefaultFileExtension( ".def" );
1386 		exporter.ExportDefFile( name );
1387 	}
1388 	idAnimManager::forceExport = false;
1389 }
1390 
1391 /*
1392 ==================
1393 Cmd_ReloadAnims_f
1394 ==================
1395 */
Cmd_ReloadAnims_f(const idCmdArgs & args)1396 static void Cmd_ReloadAnims_f( const idCmdArgs &args ) {
1397 	// don't allow reloading anims when cheats are disabled,
1398 	// but if we're not in the game, it's ok
1399 	if ( gameLocal.GetLocalPlayer() && !gameLocal.CheatsOk( false ) ) {
1400 		return;
1401 	}
1402 
1403 	animationLib.ReloadAnims();
1404 }
1405 
1406 /*
1407 ==================
1408 Cmd_ListAnims_f
1409 ==================
1410 */
Cmd_ListAnims_f(const idCmdArgs & args)1411 static void Cmd_ListAnims_f( const idCmdArgs &args ) {
1412 	idEntity *		ent;
1413 	int				num;
1414 	size_t			size;
1415 	size_t			alloced;
1416 	idAnimator *	animator;
1417 	const char *	classname;
1418 	const idDict *	dict;
1419 	int				i;
1420 
1421 	if ( args.Argc() > 1 ) {
1422 		idAnimator animator;
1423 
1424 		classname = args.Argv( 1 );
1425 
1426 		dict = gameLocal.FindEntityDefDict( classname, false );
1427 		if ( !dict ) {
1428 			gameLocal.Printf( "Entitydef '%s' not found\n", classname );
1429 			return;
1430 		}
1431 		animator.SetModel( dict->GetString( "model" ) );
1432 
1433 		gameLocal.Printf( "----------------\n" );
1434 		num = animator.NumAnims();
1435 		for( i = 0; i < num; i++ ) {
1436 			gameLocal.Printf( "%s\n", animator.AnimFullName( i ) );
1437 		}
1438 		gameLocal.Printf( "%d anims\n", num );
1439 	} else {
1440 		animationLib.ListAnims();
1441 
1442 		size = 0;
1443 		num = 0;
1444 		for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
1445 			animator = ent->GetAnimator();
1446 			if ( animator ) {
1447 				alloced = animator->Allocated();
1448 				size += alloced;
1449 				num++;
1450 			}
1451 		}
1452 
1453 		gameLocal.Printf( "%zd memory used in %d entity animators\n", size, num );
1454 	}
1455 }
1456 
1457 /*
1458 ==================
1459 Cmd_AASStats_f
1460 ==================
1461 */
Cmd_AASStats_f(const idCmdArgs & args)1462 static void Cmd_AASStats_f( const idCmdArgs &args ) {
1463 	int aasNum;
1464 
1465 	if ( !gameLocal.CheatsOk() ) {
1466 		return;
1467 	}
1468 
1469 	aasNum = aas_test.GetInteger();
1470 	idAAS *aas = gameLocal.GetAAS( aasNum );
1471 	if ( !aas ) {
1472 		gameLocal.Printf( "No aas #%d loaded\n", aasNum );
1473 	} else {
1474 		aas->Stats();
1475 	}
1476 }
1477 
1478 /*
1479 ==================
1480 Cmd_TestDamage_f
1481 ==================
1482 */
Cmd_TestDamage_f(const idCmdArgs & args)1483 static void Cmd_TestDamage_f( const idCmdArgs &args ) {
1484 	idPlayer *player;
1485 	const char *damageDefName;
1486 
1487 	player = gameLocal.GetLocalPlayer();
1488 	if ( !player || !gameLocal.CheatsOk() ) {
1489 		return;
1490 	}
1491 
1492 	if ( args.Argc() < 2 || args.Argc() > 3 ) {
1493 		gameLocal.Printf( "usage: testDamage <damageDefName> [angle]\n" );
1494 		return;
1495 	}
1496 
1497 	damageDefName = args.Argv( 1 );
1498 
1499 	idVec3	dir;
1500 	if ( args.Argc() == 3 ) {
1501 		float angle = atof( args.Argv( 2 ) );
1502 
1503 		idMath::SinCos( DEG2RAD( angle ), dir[1], dir[0] );
1504 		dir[2] = 0;
1505 	} else {
1506 		dir.Zero();
1507 	}
1508 
1509 	// give the player full health before and after
1510 	// running the damage
1511 	player->health = player->inventory.maxHealth;
1512 	player->Damage( NULL, NULL, dir, damageDefName, 1.0f, INVALID_JOINT );
1513 	player->health = player->inventory.maxHealth;
1514 }
1515 
1516 /*
1517 ==================
1518 Cmd_TestBoneFx_f
1519 ==================
1520 */
Cmd_TestBoneFx_f(const idCmdArgs & args)1521 static void Cmd_TestBoneFx_f( const idCmdArgs &args ) {
1522 	idPlayer *player;
1523 	const char *bone, *fx;
1524 
1525 	player = gameLocal.GetLocalPlayer();
1526 	if ( !player || !gameLocal.CheatsOk() ) {
1527 		return;
1528 	}
1529 
1530 	if ( args.Argc() < 3 || args.Argc() > 4 ) {
1531 		gameLocal.Printf( "usage: testBoneFx <fxName> <boneName>\n" );
1532 		return;
1533 	}
1534 
1535 	fx = args.Argv( 1 );
1536 	bone = args.Argv( 2 );
1537 
1538 	player->StartFxOnBone( fx, bone );
1539 }
1540 
1541 /*
1542 ==================
1543 Cmd_TestDamage_f
1544 ==================
1545 */
Cmd_TestDeath_f(const idCmdArgs & args)1546 static void Cmd_TestDeath_f( const idCmdArgs &args ) {
1547 	idPlayer *player;
1548 
1549 	player = gameLocal.GetLocalPlayer();
1550 	if ( !player || !gameLocal.CheatsOk() ) {
1551 		return;
1552 	}
1553 
1554 	idVec3 dir;
1555 	idMath::SinCos( DEG2RAD( 45.0f ), dir[1], dir[0] );
1556 	dir[2] = 0;
1557 
1558 	g_testDeath.SetBool( 1 );
1559 	player->Damage( NULL, NULL, dir, "damage_triggerhurt_1000", 1.0f, INVALID_JOINT );
1560 	if ( args.Argc() >= 2) {
1561 		player->SpawnGibs( dir, "damage_triggerhurt_1000" );
1562 	}
1563 
1564 }
1565 
1566 /*
1567 ==================
1568 Cmd_WeaponSplat_f
1569 ==================
1570 */
Cmd_WeaponSplat_f(const idCmdArgs & args)1571 static void Cmd_WeaponSplat_f( const idCmdArgs &args ) {
1572 	idPlayer *player;
1573 
1574 	player = gameLocal.GetLocalPlayer();
1575 	if ( !player || !gameLocal.CheatsOk() ) {
1576 		return;
1577 	}
1578 
1579 	player->weapon.GetEntity()->BloodSplat( 2.0f );
1580 }
1581 
1582 /*
1583 ==================
1584 Cmd_SaveSelected_f
1585 ==================
1586 */
Cmd_SaveSelected_f(const idCmdArgs & args)1587 static void Cmd_SaveSelected_f( const idCmdArgs &args ) {
1588 	int i;
1589 	idPlayer *player;
1590 	idEntity *s;
1591 	idMapEntity *mapEnt;
1592 	idMapFile *mapFile = gameLocal.GetLevelMap();
1593 	idDict dict;
1594 	idStr mapName;
1595 	const char *name;
1596 
1597 	player = gameLocal.GetLocalPlayer();
1598 	if ( !player || !gameLocal.CheatsOk() ) {
1599 		return;
1600 	}
1601 
1602 	s = player->dragEntity.GetSelected();
1603 	if ( !s ) {
1604 		gameLocal.Printf( "no entity selected, set g_dragShowSelection 1 to show the current selection\n" );
1605 		return;
1606 	}
1607 
1608 	if ( args.Argc() > 1 ) {
1609 		mapName = args.Argv( 1 );
1610 		mapName = "maps/" + mapName;
1611 	}
1612 	else {
1613 		mapName = mapFile->GetName();
1614 	}
1615 
1616 	// find map file entity
1617 	mapEnt = mapFile->FindEntity( s->name );
1618 	// create new map file entity if there isn't one for this articulated figure
1619 	if ( !mapEnt ) {
1620 		mapEnt = new idMapEntity();
1621 		mapFile->AddEntity( mapEnt );
1622 		for ( i = 0; i < 9999; i++ ) {
1623 			name = va( "%s_%d", s->GetEntityDefName(), i );
1624 			if ( !gameLocal.FindEntity( name ) ) {
1625 				break;
1626 			}
1627 		}
1628 		s->name = name;
1629 		mapEnt->epairs.Set( "classname", s->GetEntityDefName() );
1630 		mapEnt->epairs.Set( "name", s->name );
1631 	}
1632 
1633 	if ( s->IsType( idMoveable::Type ) ) {
1634 		// save the moveable state
1635 		mapEnt->epairs.Set( "origin", s->GetPhysics()->GetOrigin().ToString( 8 ) );
1636 		mapEnt->epairs.Set( "rotation", s->GetPhysics()->GetAxis().ToString( 8 ) );
1637 	}
1638 	else if ( s->IsType( idAFEntity_Generic::Type ) || s->IsType( idAFEntity_WithAttachedHead::Type ) ) {
1639 		// save the articulated figure state
1640 		dict.Clear();
1641 		static_cast<idAFEntity_Base *>(s)->SaveState( dict );
1642 		mapEnt->epairs.Copy( dict );
1643 	}
1644 
1645 	// write out the map file
1646 	mapFile->Write( mapName, ".map" );
1647 }
1648 
1649 /*
1650 ==================
1651 Cmd_DeleteSelected_f
1652 ==================
1653 */
Cmd_DeleteSelected_f(const idCmdArgs & args)1654 static void Cmd_DeleteSelected_f( const idCmdArgs &args ) {
1655 	idPlayer *player;
1656 
1657 	player = gameLocal.GetLocalPlayer();
1658 	if ( !player || !gameLocal.CheatsOk() ) {
1659 		return;
1660 	}
1661 
1662 	if ( player ) {
1663 		player->dragEntity.DeleteSelected();
1664 	}
1665 }
1666 
1667 /*
1668 ==================
1669 Cmd_SaveMoveables_f
1670 ==================
1671 */
Cmd_SaveMoveables_f(const idCmdArgs & args)1672 static void Cmd_SaveMoveables_f( const idCmdArgs &args ) {
1673 	int e, i;
1674 	idMoveable *m;
1675 	idMapEntity *mapEnt;
1676 	idMapFile *mapFile = gameLocal.GetLevelMap();
1677 	idStr mapName;
1678 	const char *name;
1679 
1680 	if ( !gameLocal.CheatsOk() ) {
1681 		return;
1682 	}
1683 
1684 	for( e = 0; e < MAX_GENTITIES; e++ ) {
1685 		m = static_cast<idMoveable *>(gameLocal.entities[ e ]);
1686 
1687 		if ( !m || !m->IsType( idMoveable::Type ) ) {
1688 			continue;
1689 		}
1690 
1691 		if ( m->IsBound() ) {
1692 			continue;
1693 		}
1694 
1695 		if ( !m->IsAtRest() ) {
1696 			break;
1697 		}
1698 	}
1699 
1700 	if ( e < MAX_GENTITIES ) {
1701 		gameLocal.Warning( "map not saved because the moveable entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() );
1702 		return;
1703 	}
1704 
1705 	if ( args.Argc() > 1 ) {
1706 		mapName = args.Argv( 1 );
1707 		mapName = "maps/" + mapName;
1708 	}
1709 	else {
1710 		mapName = mapFile->GetName();
1711 	}
1712 
1713 	for( e = 0; e < MAX_GENTITIES; e++ ) {
1714 		m = static_cast<idMoveable *>(gameLocal.entities[ e ]);
1715 
1716 		if ( !m || !m->IsType( idMoveable::Type ) ) {
1717 			continue;
1718 		}
1719 
1720 		if ( m->IsBound() ) {
1721 			continue;
1722 		}
1723 
1724 		// find map file entity
1725 		mapEnt = mapFile->FindEntity( m->name );
1726 		// create new map file entity if there isn't one for this articulated figure
1727 		if ( !mapEnt ) {
1728 			mapEnt = new idMapEntity();
1729 			mapFile->AddEntity( mapEnt );
1730 			for ( i = 0; i < 9999; i++ ) {
1731 				name = va( "%s_%d", m->GetEntityDefName(), i );
1732 				if ( !gameLocal.FindEntity( name ) ) {
1733 					break;
1734 				}
1735 			}
1736 			m->name = name;
1737 			mapEnt->epairs.Set( "classname", m->GetEntityDefName() );
1738 			mapEnt->epairs.Set( "name", m->name );
1739 		}
1740 		// save the moveable state
1741 		mapEnt->epairs.Set( "origin", m->GetPhysics()->GetOrigin().ToString( 8 ) );
1742 		mapEnt->epairs.Set( "rotation", m->GetPhysics()->GetAxis().ToString( 8 ) );
1743 	}
1744 
1745 	// write out the map file
1746 	mapFile->Write( mapName, ".map" );
1747 }
1748 
1749 /*
1750 ==================
1751 Cmd_SaveRagdolls_f
1752 ==================
1753 */
Cmd_SaveRagdolls_f(const idCmdArgs & args)1754 static void Cmd_SaveRagdolls_f( const idCmdArgs &args ) {
1755 	int e, i;
1756 	idAFEntity_Base *af;
1757 	idMapEntity *mapEnt;
1758 	idMapFile *mapFile = gameLocal.GetLevelMap();
1759 	idDict dict;
1760 	idStr mapName;
1761 	const char *name;
1762 
1763 	if ( !gameLocal.CheatsOk() ) {
1764 		return;
1765 	}
1766 
1767 	if ( args.Argc() > 1 ) {
1768 		mapName = args.Argv( 1 );
1769 		mapName = "maps/" + mapName;
1770 	}
1771 	else {
1772 		mapName = mapFile->GetName();
1773 	}
1774 
1775 	for( e = 0; e < MAX_GENTITIES; e++ ) {
1776 		af = static_cast<idAFEntity_Base *>(gameLocal.entities[ e ]);
1777 
1778 		if ( !af ) {
1779 			continue;
1780 		}
1781 
1782 		if ( !af->IsType( idAFEntity_WithAttachedHead::Type ) && !af->IsType( idAFEntity_Generic::Type ) ) {
1783 			continue;
1784 		}
1785 
1786 		if ( af->IsBound() ) {
1787 			continue;
1788 		}
1789 
1790 		if ( !af->IsAtRest() ) {
1791 			gameLocal.Warning( "the articulated figure for entity %s is not at rest", gameLocal.entities[ e ]->name.c_str() );
1792 		}
1793 
1794 		dict.Clear();
1795 		af->SaveState( dict );
1796 
1797 		// find map file entity
1798 		mapEnt = mapFile->FindEntity( af->name );
1799 		// create new map file entity if there isn't one for this articulated figure
1800 		if ( !mapEnt ) {
1801 			mapEnt = new idMapEntity();
1802 			mapFile->AddEntity( mapEnt );
1803 			for ( i = 0; i < 9999; i++ ) {
1804 				name = va( "%s_%d", af->GetEntityDefName(), i );
1805 				if ( !gameLocal.FindEntity( name ) ) {
1806 					break;
1807 				}
1808 			}
1809 			af->name = name;
1810 			mapEnt->epairs.Set( "classname", af->GetEntityDefName() );
1811 			mapEnt->epairs.Set( "name", af->name );
1812 		}
1813 		// save the articulated figure state
1814 		mapEnt->epairs.Copy( dict );
1815 	}
1816 
1817 	// write out the map file
1818 	mapFile->Write( mapName, ".map" );
1819 }
1820 
1821 /*
1822 ==================
1823 Cmd_BindRagdoll_f
1824 ==================
1825 */
Cmd_BindRagdoll_f(const idCmdArgs & args)1826 static void Cmd_BindRagdoll_f( const idCmdArgs &args ) {
1827 	idPlayer *player;
1828 
1829 	player = gameLocal.GetLocalPlayer();
1830 	if ( !player || !gameLocal.CheatsOk() ) {
1831 		return;
1832 	}
1833 
1834 	if ( player ) {
1835 		player->dragEntity.BindSelected();
1836 	}
1837 }
1838 
1839 /*
1840 ==================
1841 Cmd_UnbindRagdoll_f
1842 ==================
1843 */
Cmd_UnbindRagdoll_f(const idCmdArgs & args)1844 static void Cmd_UnbindRagdoll_f( const idCmdArgs &args ) {
1845 	idPlayer *player;
1846 
1847 	player = gameLocal.GetLocalPlayer();
1848 	if ( !player || !gameLocal.CheatsOk() ) {
1849 		return;
1850 	}
1851 
1852 	if ( player ) {
1853 		player->dragEntity.UnbindSelected();
1854 	}
1855 }
1856 
1857 /*
1858 ==================
1859 Cmd_GameError_f
1860 ==================
1861 */
Cmd_GameError_f(const idCmdArgs & args)1862 static void Cmd_GameError_f( const idCmdArgs &args ) {
1863 	gameLocal.Error( "game error" );
1864 }
1865 
1866 /*
1867 ==================
1868 Cmd_SaveLights_f
1869 ==================
1870 */
Cmd_SaveLights_f(const idCmdArgs & args)1871 static void Cmd_SaveLights_f( const idCmdArgs &args ) {
1872 	int e, i;
1873 	idLight *light;
1874 	idMapEntity *mapEnt;
1875 	idMapFile *mapFile = gameLocal.GetLevelMap();
1876 	idDict dict;
1877 	idStr mapName;
1878 	const char *name;
1879 
1880 	if ( !gameLocal.CheatsOk() ) {
1881 		return;
1882 	}
1883 
1884 	if ( args.Argc() > 1 ) {
1885 		mapName = args.Argv( 1 );
1886 		mapName = "maps/" + mapName;
1887 	}
1888 	else {
1889 		mapName = mapFile->GetName();
1890 	}
1891 
1892 	for( e = 0; e < MAX_GENTITIES; e++ ) {
1893 		light = static_cast<idLight*>(gameLocal.entities[ e ]);
1894 
1895 		if ( !light || !light->IsType( idLight::Type ) ) {
1896 			continue;
1897 		}
1898 
1899 		dict.Clear();
1900 		light->SaveState( &dict );
1901 
1902 		// find map file entity
1903 		mapEnt = mapFile->FindEntity( light->name );
1904 		// create new map file entity if there isn't one for this light
1905 		if ( !mapEnt ) {
1906 			mapEnt = new idMapEntity();
1907 			mapFile->AddEntity( mapEnt );
1908 			for ( i = 0; i < 9999; i++ ) {
1909 				name = va( "%s_%d", light->GetEntityDefName(), i );
1910 				if ( !gameLocal.FindEntity( name ) ) {
1911 					break;
1912 				}
1913 			}
1914 			light->name = name;
1915 			mapEnt->epairs.Set( "classname", light->GetEntityDefName() );
1916 			mapEnt->epairs.Set( "name", light->name );
1917 		}
1918 		// save the light state
1919 		mapEnt->epairs.Copy( dict );
1920 	}
1921 
1922 	// write out the map file
1923 	mapFile->Write( mapName, ".map" );
1924 }
1925 
1926 
1927 /*
1928 ==================
1929 Cmd_SaveParticles_f
1930 ==================
1931 */
Cmd_SaveParticles_f(const idCmdArgs & args)1932 static void Cmd_SaveParticles_f( const idCmdArgs &args ) {
1933 	int e;
1934 	idEntity *ent;
1935 	idMapEntity *mapEnt;
1936 	idMapFile *mapFile = gameLocal.GetLevelMap();
1937 	idDict dict;
1938 	idStr mapName, strModel;
1939 
1940 	if ( !gameLocal.CheatsOk() ) {
1941 		return;
1942 	}
1943 
1944 	if ( args.Argc() > 1 ) {
1945 		mapName = args.Argv( 1 );
1946 		mapName = "maps/" + mapName;
1947 	}
1948 	else {
1949 		mapName = mapFile->GetName();
1950 	}
1951 
1952 	for( e = 0; e < MAX_GENTITIES; e++ ) {
1953 
1954 		ent = static_cast<idStaticEntity*> ( gameLocal.entities[ e ] );
1955 
1956 		if ( !ent ) {
1957 			continue;
1958 		}
1959 
1960 		strModel = ent->spawnArgs.GetString( "model" );
1961 		if ( strModel.Length() && strModel.Find( ".prt") > 0 ) {
1962 			dict.Clear();
1963 			dict.Set( "model", ent->spawnArgs.GetString( "model" ) );
1964 			dict.SetVector( "origin", ent->GetPhysics()->GetOrigin() );
1965 
1966 			// find map file entity
1967 			mapEnt = mapFile->FindEntity( ent->name );
1968 			// create new map file entity if there isn't one for this entity
1969 			if ( !mapEnt ) {
1970 				continue;
1971 			}
1972 			// save the particle state
1973 			mapEnt->epairs.Copy( dict );
1974 		}
1975 	}
1976 
1977 	// write out the map file
1978 	mapFile->Write( mapName, ".map" );
1979 }
1980 
1981 
1982 /*
1983 ==================
1984 Cmd_DisasmScript_f
1985 ==================
1986 */
Cmd_DisasmScript_f(const idCmdArgs & args)1987 static void Cmd_DisasmScript_f( const idCmdArgs &args ) {
1988 	gameLocal.program.Disassemble();
1989 }
1990 
1991 /*
1992 ==================
1993 Cmd_TestSave_f
1994 ==================
1995 */
Cmd_TestSave_f(const idCmdArgs & args)1996 static void Cmd_TestSave_f( const idCmdArgs &args ) {
1997 	idFile *f;
1998 
1999 	f = fileSystem->OpenFileWrite( "test.sav" );
2000 	gameLocal.SaveGame( f );
2001 	fileSystem->CloseFile( f );
2002 }
2003 
2004 /*
2005 ==================
2006 Cmd_RecordViewNotes_f
2007 ==================
2008 */
Cmd_RecordViewNotes_f(const idCmdArgs & args)2009 static void Cmd_RecordViewNotes_f( const idCmdArgs &args ) {
2010 	idPlayer *player;
2011 	idVec3 origin;
2012 	idMat3 axis;
2013 
2014 	if ( args.Argc() <= 3 ) {
2015 		return;
2016 	}
2017 
2018 	player = gameLocal.GetLocalPlayer();
2019 	if ( !player ) {
2020 		return;
2021 	}
2022 
2023 	player->GetViewPos( origin, axis );
2024 
2025 	// Argv(1) = filename for map (viewnotes/mapname/person)
2026 	// Argv(2) = note number (person0001)
2027 	// Argv(3) = comments
2028 
2029 	idStr str = args.Argv(1);
2030 	str.SetFileExtension( ".txt" );
2031 	idFile *file = fileSystem->OpenFileAppend( str );
2032 	if ( file ) {
2033 		file->WriteFloatString( "\"view\"\t( %s )\t( %s )\r\n", origin.ToString(), axis.ToString() );
2034 		file->WriteFloatString( "\"comments\"\t\"%s: %s\"\r\n\r\n", args.Argv(2), args.Argv(3) );
2035 		fileSystem->CloseFile( file );
2036 	}
2037 
2038 	idStr viewComments = args.Argv(1);
2039 	viewComments.StripLeading("viewnotes/");
2040 	viewComments += " -- Loc: ";
2041 	viewComments += origin.ToString();
2042 	viewComments += "\n";
2043 	viewComments += args.Argv(3);
2044 	player->hud->SetStateString( "viewcomments", viewComments );
2045 	player->hud->HandleNamedEvent( "showViewComments" );
2046 }
2047 
2048 /*
2049 ==================
2050 Cmd_CloseViewNotes_f
2051 ==================
2052 */
Cmd_CloseViewNotes_f(const idCmdArgs & args)2053 static void Cmd_CloseViewNotes_f( const idCmdArgs &args ) {
2054 	idPlayer *player = gameLocal.GetLocalPlayer();
2055 
2056 	if ( !player ) {
2057 		return;
2058 	}
2059 
2060 	player->hud->SetStateString( "viewcomments", "" );
2061 	player->hud->HandleNamedEvent( "hideViewComments" );
2062 }
2063 
2064 /*
2065 ==================
2066 Cmd_ShowViewNotes_f
2067 ==================
2068 */
Cmd_ShowViewNotes_f(const idCmdArgs & args)2069 static void Cmd_ShowViewNotes_f( const idCmdArgs &args ) {
2070 	static idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT | LEXFL_NOFATALERRORS );
2071 	idToken	token;
2072 	idPlayer *player;
2073 	idVec3 origin;
2074 	idMat3 axis;
2075 
2076 	player = gameLocal.GetLocalPlayer();
2077 
2078 	if ( !player ) {
2079 		return;
2080 	}
2081 
2082 	if ( !parser.IsLoaded() ) {
2083 		idStr str = "viewnotes/";
2084 		str += gameLocal.GetMapName();
2085 		str.StripFileExtension();
2086 		str += "/";
2087 		if ( args.Argc() > 1 ) {
2088 			str += args.Argv( 1 );
2089 		} else {
2090 			str += "comments";
2091 		}
2092 		str.SetFileExtension( ".txt" );
2093 		if ( !parser.LoadFile( str ) ) {
2094 			gameLocal.Printf( "No view notes for %s\n", gameLocal.GetMapName() );
2095 			return;
2096 		}
2097 	}
2098 
2099 	if ( parser.ExpectTokenString( "view" ) && parser.Parse1DMatrix( 3, origin.ToFloatPtr() ) &&
2100 		parser.Parse1DMatrix( 9, axis.ToFloatPtr() ) && parser.ExpectTokenString( "comments" ) && parser.ReadToken( &token ) ) {
2101 		player->hud->SetStateString( "viewcomments", token );
2102 		player->hud->HandleNamedEvent( "showViewComments" );
2103 		player->Teleport( origin, axis.ToAngles(), NULL );
2104 	} else {
2105 		parser.FreeSource();
2106 		player->hud->HandleNamedEvent( "hideViewComments" );
2107 		return;
2108 	}
2109 }
2110 
2111 /*
2112 =================
2113 FindEntityGUIs
2114 
2115 helper function for Cmd_NextGUI_f.  Checks the passed entity to determine if it
2116 has any valid gui surfaces.
2117 =================
2118 */
FindEntityGUIs(idEntity * ent,const modelSurface_t ** surfaces,int maxSurfs,int & guiSurfaces)2119 bool FindEntityGUIs( idEntity *ent, const modelSurface_t ** surfaces,  int maxSurfs, int &guiSurfaces ) {
2120 	renderEntity_t			*renderEnt;
2121 	idRenderModel			*renderModel;
2122 	const modelSurface_t	*surf;
2123 	const idMaterial		*shader;
2124 	int						i;
2125 
2126 	assert( surfaces != NULL );
2127 	assert( ent != NULL );
2128 
2129 	memset( surfaces, 0x00, sizeof( modelSurface_t *) * maxSurfs );
2130 	guiSurfaces = 0;
2131 
2132 	renderEnt  = ent->GetRenderEntity();
2133 	renderModel = renderEnt->hModel;
2134 	if ( renderModel == NULL ) {
2135 		return false;
2136 	}
2137 
2138 	for( i = 0; i < renderModel->NumSurfaces(); i++ ) {
2139 		surf = renderModel->Surface( i );
2140 		if ( surf == NULL ) {
2141 			continue;
2142 		}
2143 		shader = surf->shader;
2144 		if ( shader == NULL ) {
2145 			continue;
2146 		}
2147 		if ( shader->GetEntityGui() > 0 ) {
2148 			surfaces[ guiSurfaces++ ] = surf;
2149 		}
2150 	}
2151 
2152 	return ( guiSurfaces != 0 );
2153 }
2154 
2155 /*
2156 =================
2157 Cmd_NextGUI_f
2158 =================
2159 */
Cmd_NextGUI_f(const idCmdArgs & args)2160 void Cmd_NextGUI_f( const idCmdArgs &args ) {
2161 	idVec3					origin;
2162 	idAngles				angles;
2163 	idPlayer				*player;
2164 	idEntity				*ent;
2165 	int						guiSurfaces;
2166 	bool					newEnt;
2167 	renderEntity_t			*renderEnt;
2168 	int						surfIndex;
2169 	srfTriangles_t			*geom;
2170 	idMat4					modelMatrix;
2171 	idVec3					normal;
2172 	idVec3					center;
2173 	const modelSurface_t	*surfaces[ MAX_RENDERENTITY_GUI ];
2174 
2175 	player = gameLocal.GetLocalPlayer();
2176 	if ( !player || !gameLocal.CheatsOk() ) {
2177 		return;
2178 	}
2179 
2180 	if ( args.Argc() != 1 ) {
2181 		gameLocal.Printf( "usage: nextgui\n" );
2182 		return;
2183 	}
2184 
2185 	// start at the last entity
2186 	ent = gameLocal.lastGUIEnt.GetEntity();
2187 
2188 	// see if we have any gui surfaces left to go to on the current entity.
2189 	guiSurfaces = 0;
2190 	newEnt = false;
2191 	if ( ent == NULL ) {
2192 		newEnt = true;
2193 	} else if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == true ) {
2194 		if ( gameLocal.lastGUI >= guiSurfaces ) {
2195 			newEnt = true;
2196 		}
2197 	} else {
2198 		// no actual gui surfaces on this ent, so skip it
2199 		newEnt = true;
2200 	}
2201 
2202 	if ( newEnt == true ) {
2203 		// go ahead and skip to the next entity with a gui...
2204 		if ( ent == NULL ) {
2205 			ent = gameLocal.spawnedEntities.Next();
2206 		} else {
2207 			ent = ent->spawnNode.Next();
2208 		}
2209 
2210 		for ( ; ent != NULL; ent = ent->spawnNode.Next() ) {
2211 			if ( ent->spawnArgs.GetString( "gui", NULL ) != NULL ) {
2212 				break;
2213 			}
2214 
2215 			if ( ent->spawnArgs.GetString( "gui2", NULL ) != NULL ) {
2216 				break;
2217 			}
2218 
2219 			if ( ent->spawnArgs.GetString( "gui3", NULL ) != NULL ) {
2220 				break;
2221 			}
2222 
2223 			// try the next entity
2224 			gameLocal.lastGUIEnt = ent;
2225 		}
2226 
2227 		gameLocal.lastGUIEnt = ent;
2228 		gameLocal.lastGUI = 0;
2229 
2230 		if ( !ent ) {
2231 			gameLocal.Printf( "No more gui entities. Starting over...\n" );
2232 			return;
2233 		}
2234 	}
2235 
2236 	if ( FindEntityGUIs( ent, surfaces, MAX_RENDERENTITY_GUI, guiSurfaces ) == false ) {
2237 		gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces.\n", ent->name.c_str() );
2238 	}
2239 
2240 	if ( guiSurfaces == 0 ) {
2241 		gameLocal.Printf( "Entity \"%s\" has gui properties but no gui surfaces!\n", ent->name.c_str() );
2242 		return;
2243 	}
2244 
2245 	gameLocal.Printf( "Teleporting to gui entity \"%s\", gui #%d.\n" , ent->name.c_str (), gameLocal.lastGUI );
2246 
2247 	renderEnt = ent->GetRenderEntity();
2248 	surfIndex = gameLocal.lastGUI++;
2249 	geom = surfaces[ surfIndex ]->geometry;
2250 	if ( geom == NULL ) {
2251 		gameLocal.Printf( "Entity \"%s\" has gui surface %d without geometry!\n", ent->name.c_str(), surfIndex );
2252 		return;
2253 	}
2254 
2255 	assert( geom->facePlanes != NULL );
2256 
2257 	modelMatrix = idMat4( renderEnt->axis, renderEnt->origin );
2258 	normal = geom->facePlanes[ 0 ].Normal() * renderEnt->axis;
2259 	center = geom->bounds.GetCenter() * modelMatrix;
2260 
2261 	origin = center + (normal * 32.0f);
2262 	origin.z -= player->EyeHeight();
2263 	normal *= -1.0f;
2264 	angles = normal.ToAngles ();
2265 
2266 	//	make sure the player is in noclip
2267 	player->noclip = true;
2268 	player->Teleport( origin, angles, NULL );
2269 }
2270 
ArgCompletion_DefFile(const idCmdArgs & args,void (* callback)(const char * s))2271 static void ArgCompletion_DefFile( const idCmdArgs &args, void(*callback)( const char *s ) ) {
2272 	cmdSystem->ArgCompletion_FolderExtension( args, callback, "def/", true, ".def", NULL );
2273 }
2274 
2275 /*
2276 ===============
2277 Cmd_TestId_f
2278 outputs a string from the string table for the specified id
2279 ===============
2280 */
Cmd_TestId_f(const idCmdArgs & args)2281 void Cmd_TestId_f( const idCmdArgs &args ) {
2282 	idStr	id;
2283 	int		i;
2284 	if ( args.Argc() == 1 ) {
2285 		common->Printf( "usage: testid <string id>\n" );
2286 		return;
2287 	}
2288 
2289 	for ( i = 1; i < args.Argc(); i++ ) {
2290 		id += args.Argv( i );
2291 	}
2292 	if ( idStr::Cmpn( id, STRTABLE_ID, STRTABLE_ID_LENGTH ) != 0 ) {
2293 		id = STRTABLE_ID + id;
2294 	}
2295 	gameLocal.mpGame.AddChatLine( common->GetLanguageDict()->GetString( id ), "<nothing>", "<nothing>", "<nothing>" );
2296 }
2297 
2298 /*
2299 =================
2300 idGameLocal::InitConsoleCommands
2301 
2302 Let the system know about all of our commands
2303 so it can perform tab completion
2304 =================
2305 */
InitConsoleCommands(void)2306 void idGameLocal::InitConsoleCommands( void ) {
2307 	cmdSystem->AddCommand( "listTypeInfo",			ListTypeInfo_f,				CMD_FL_GAME,				"list type info" );
2308 	cmdSystem->AddCommand( "writeGameState",		WriteGameState_f,			CMD_FL_GAME,				"write game state" );
2309 	cmdSystem->AddCommand( "testSaveGame",			TestSaveGame_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"test a save game for a level" );
2310 	cmdSystem->AddCommand( "game_memory",			idClass::DisplayInfo_f,		CMD_FL_GAME,				"displays game class info" );
2311 	cmdSystem->AddCommand( "listClasses",			idClass::ListClasses_f,		CMD_FL_GAME,				"lists game classes" );
2312 	cmdSystem->AddCommand( "listThreads",			idThread::ListThreads_f,	CMD_FL_GAME|CMD_FL_CHEAT,	"lists script threads" );
2313 	cmdSystem->AddCommand( "listEntities",			Cmd_EntityList_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"lists game entities" );
2314 	cmdSystem->AddCommand( "listActiveEntities",	Cmd_ActiveEntityList_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"lists active game entities" );
2315 	cmdSystem->AddCommand( "listMonsters",			idAI::List_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"lists monsters" );
2316 	cmdSystem->AddCommand( "listSpawnArgs",			Cmd_ListSpawnArgs_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"list the spawn args of an entity", idGameLocal::ArgCompletion_EntityName );
2317 	cmdSystem->AddCommand( "say",					Cmd_Say_f,					CMD_FL_GAME,				"text chat" );
2318 	cmdSystem->AddCommand( "sayTeam",				Cmd_SayTeam_f,				CMD_FL_GAME,				"team text chat" );
2319 	cmdSystem->AddCommand( "addChatLine",			Cmd_AddChatLine_f,			CMD_FL_GAME,				"internal use - core to game chat lines" );
2320 	cmdSystem->AddCommand( "gameKick",				Cmd_Kick_f,					CMD_FL_GAME,				"same as kick, but recognizes player names" );
2321 	cmdSystem->AddCommand( "give",					Cmd_Give_f,					CMD_FL_GAME|CMD_FL_CHEAT,	"gives one or more items" );
2322 	cmdSystem->AddCommand( "centerview",			Cmd_CenterView_f,			CMD_FL_GAME,				"centers the view" );
2323 	cmdSystem->AddCommand( "god",					Cmd_God_f,					CMD_FL_GAME|CMD_FL_CHEAT,	"enables god mode" );
2324 	cmdSystem->AddCommand( "notarget",				Cmd_Notarget_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"disables the player as a target" );
2325 	cmdSystem->AddCommand( "noclip",				Cmd_Noclip_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"disables collision detection for the player" );
2326 	cmdSystem->AddCommand( "kill",					Cmd_Kill_f,					CMD_FL_GAME,				"kills the player" );
2327 	cmdSystem->AddCommand( "where",					Cmd_GetViewpos_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"prints the current view position" );
2328 	cmdSystem->AddCommand( "getviewpos",			Cmd_GetViewpos_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"prints the current view position" );
2329 	cmdSystem->AddCommand( "setviewpos",			Cmd_SetViewpos_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"sets the current view position" );
2330 	cmdSystem->AddCommand( "teleport",				Cmd_Teleport_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"teleports the player to an entity location", idGameLocal::ArgCompletion_EntityName );
2331 	cmdSystem->AddCommand( "trigger",				Cmd_Trigger_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"triggers an entity", idGameLocal::ArgCompletion_EntityName );
2332 	cmdSystem->AddCommand( "spawn",					Cmd_Spawn_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"spawns a game entity", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
2333 	cmdSystem->AddCommand( "damage",				Cmd_Damage_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"apply damage to an entity", idGameLocal::ArgCompletion_EntityName );
2334 	cmdSystem->AddCommand( "remove",				Cmd_Remove_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"removes an entity", idGameLocal::ArgCompletion_EntityName );
2335 	cmdSystem->AddCommand( "killMonsters",			Cmd_KillMonsters_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"removes all monsters" );
2336 	cmdSystem->AddCommand( "killMoveables",			Cmd_KillMovables_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"removes all moveables" );
2337 	cmdSystem->AddCommand( "killRagdolls",			Cmd_KillRagdolls_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"removes all ragdolls" );
2338 	cmdSystem->AddCommand( "addline",				Cmd_AddDebugLine_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"adds a debug line" );
2339 	cmdSystem->AddCommand( "addarrow",				Cmd_AddDebugLine_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"adds a debug arrow" );
2340 	cmdSystem->AddCommand( "removeline",			Cmd_RemoveDebugLine_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"removes a debug line" );
2341 	cmdSystem->AddCommand( "blinkline",				Cmd_BlinkDebugLine_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"blinks a debug line" );
2342 	cmdSystem->AddCommand( "listLines",				Cmd_ListDebugLines_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"lists all debug lines" );
2343 	cmdSystem->AddCommand( "playerModel",			Cmd_PlayerModel_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"sets the given model on the player", idCmdSystem::ArgCompletion_Decl<DECL_MODELDEF> );
2344 	cmdSystem->AddCommand( "testFx",				Cmd_TestFx_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"tests an FX system", idCmdSystem::ArgCompletion_Decl<DECL_FX> );
2345 	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> );
2346 	cmdSystem->AddCommand( "testLight",				Cmd_TestLight_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"tests a light" );
2347 	cmdSystem->AddCommand( "testPointLight",		Cmd_TestPointLight_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"tests a point light" );
2348 	cmdSystem->AddCommand( "popLight",				Cmd_PopLight_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"removes the last created light" );
2349 	cmdSystem->AddCommand( "testDeath",				Cmd_TestDeath_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"tests death" );
2350 	cmdSystem->AddCommand( "testSave",				Cmd_TestSave_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"writes out a test savegame" );
2351 	cmdSystem->AddCommand( "testModel",				idTestModel::TestModel_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"tests a model", idTestModel::ArgCompletion_TestModel );
2352 	cmdSystem->AddCommand( "testSkin",				idTestModel::TestSkin_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"tests a skin on an existing testModel", idCmdSystem::ArgCompletion_Decl<DECL_SKIN> );
2353 	cmdSystem->AddCommand( "testShaderParm",		idTestModel::TestShaderParm_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"sets a shaderParm on an existing testModel" );
2354 	cmdSystem->AddCommand( "keepTestModel",			idTestModel::KeepTestModel_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"keeps the last test model in the game" );
2355 	cmdSystem->AddCommand( "testAnim",				idTestModel::TestAnim_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"tests an animation", idTestModel::ArgCompletion_TestAnim );
2356 	cmdSystem->AddCommand( "testParticleStopTime",	idTestModel::TestParticleStopTime_f,CMD_FL_GAME|CMD_FL_CHEAT,	"tests particle stop time on a test model" );
2357 	cmdSystem->AddCommand( "nextAnim",				idTestModel::TestModelNextAnim_f,	CMD_FL_GAME|CMD_FL_CHEAT,	"shows next animation on test model" );
2358 	cmdSystem->AddCommand( "prevAnim",				idTestModel::TestModelPrevAnim_f,	CMD_FL_GAME|CMD_FL_CHEAT,	"shows previous animation on test model" );
2359 	cmdSystem->AddCommand( "nextFrame",				idTestModel::TestModelNextFrame_f,	CMD_FL_GAME|CMD_FL_CHEAT,	"shows next animation frame on test model" );
2360 	cmdSystem->AddCommand( "prevFrame",				idTestModel::TestModelPrevFrame_f,	CMD_FL_GAME|CMD_FL_CHEAT,	"shows previous animation frame on test model" );
2361 	cmdSystem->AddCommand( "testBlend",				idTestModel::TestBlend_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"tests animation blending" );
2362 	cmdSystem->AddCommand( "reloadScript",			Cmd_ReloadScript_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"reloads scripts" );
2363 	cmdSystem->AddCommand( "script",				Cmd_Script_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"executes a line of script" );
2364 	cmdSystem->AddCommand( "listCollisionModels",	Cmd_ListCollisionModels_f,	CMD_FL_GAME,				"lists collision models" );
2365 	cmdSystem->AddCommand( "collisionModelInfo",	Cmd_CollisionModelInfo_f,	CMD_FL_GAME,				"shows collision model info" );
2366 	cmdSystem->AddCommand( "reexportmodels",		Cmd_ReexportModels_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"reexports models", ArgCompletion_DefFile );
2367 	cmdSystem->AddCommand( "reloadanims",			Cmd_ReloadAnims_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"reloads animations" );
2368 	cmdSystem->AddCommand( "listAnims",				Cmd_ListAnims_f,			CMD_FL_GAME,				"lists all animations" );
2369 	cmdSystem->AddCommand( "aasStats",				Cmd_AASStats_f,				CMD_FL_GAME,				"shows AAS stats" );
2370 	cmdSystem->AddCommand( "testDamage",			Cmd_TestDamage_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"tests a damage def", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
2371 	cmdSystem->AddCommand( "weaponSplat",			Cmd_WeaponSplat_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"projects a blood splat on the player weapon" );
2372 	cmdSystem->AddCommand( "saveSelected",			Cmd_SaveSelected_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"saves the selected entity to the .map file" );
2373 	cmdSystem->AddCommand( "deleteSelected",		Cmd_DeleteSelected_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"deletes selected entity" );
2374 	cmdSystem->AddCommand( "saveMoveables",			Cmd_SaveMoveables_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"save all moveables to the .map file" );
2375 	cmdSystem->AddCommand( "saveRagdolls",			Cmd_SaveRagdolls_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"save all ragdoll poses to the .map file" );
2376 	cmdSystem->AddCommand( "bindRagdoll",			Cmd_BindRagdoll_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"binds ragdoll at the current drag position" );
2377 	cmdSystem->AddCommand( "unbindRagdoll",			Cmd_UnbindRagdoll_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"unbinds the selected ragdoll" );
2378 	cmdSystem->AddCommand( "saveLights",			Cmd_SaveLights_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"saves all lights to the .map file" );
2379 	cmdSystem->AddCommand( "saveParticles",			Cmd_SaveParticles_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"saves all lights to the .map file" );
2380 	cmdSystem->AddCommand( "clearLights",			Cmd_ClearLights_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"clears all lights" );
2381 	cmdSystem->AddCommand( "gameError",				Cmd_GameError_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"causes a game error" );
2382 
2383 	cmdSystem->AddCommand( "disasmScript",			Cmd_DisasmScript_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"disassembles script" );
2384 	cmdSystem->AddCommand( "recordViewNotes",		Cmd_RecordViewNotes_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"record the current view position with notes" );
2385 	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" );
2386 	cmdSystem->AddCommand( "closeViewNotes",		Cmd_CloseViewNotes_f,		CMD_FL_GAME|CMD_FL_CHEAT,	"close the view showing any notes for this map" );
2387 	cmdSystem->AddCommand( "exportmodels",			Cmd_ExportModels_f,			CMD_FL_GAME|CMD_FL_CHEAT,	"exports models", ArgCompletion_DefFile );
2388 
2389 	// multiplayer client commands ( replaces old impulses stuff )
2390 	cmdSystem->AddCommand( "clientDropWeapon",		idMultiplayerGame::DropWeapon_f, CMD_FL_GAME,			"drop current weapon" );
2391 	cmdSystem->AddCommand( "clientMessageMode",		idMultiplayerGame::MessageMode_f, CMD_FL_GAME,			"ingame gui message mode" );
2392 	// FIXME: implement
2393 //	cmdSystem->AddCommand( "clientVote",			idMultiplayerGame::Vote_f,	CMD_FL_GAME,				"cast your vote: clientVote yes | no" );
2394 //	cmdSystem->AddCommand( "clientCallVote",		idMultiplayerGame::CallVote_f,	CMD_FL_GAME,			"call a vote: clientCallVote si_.. proposed_value" );
2395 	cmdSystem->AddCommand( "clientVoiceChat",		idMultiplayerGame::VoiceChat_f,	CMD_FL_GAME,			"voice chats: clientVoiceChat <sound shader>" );
2396 	cmdSystem->AddCommand( "clientVoiceChatTeam",	idMultiplayerGame::VoiceChatTeam_f,	CMD_FL_GAME,		"team voice chats: clientVoiceChat <sound shader>" );
2397 
2398 	// multiplayer server commands
2399 	cmdSystem->AddCommand( "serverMapRestart",		idGameLocal::MapRestart_f,	CMD_FL_GAME,				"restart the current game" );
2400 	cmdSystem->AddCommand( "serverForceReady",	idMultiplayerGame::ForceReady_f,CMD_FL_GAME,				"force all players ready" );
2401 	cmdSystem->AddCommand( "serverNextMap",			idGameLocal::NextMap_f,		CMD_FL_GAME,				"change to the next map" );
2402 
2403 	// localization help commands
2404 	cmdSystem->AddCommand( "nextGUI",				Cmd_NextGUI_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"teleport the player to the next func_static with a gui" );
2405 	cmdSystem->AddCommand( "testid",				Cmd_TestId_f,				CMD_FL_GAME|CMD_FL_CHEAT,	"output the string for the specified id." );
2406 }
2407 
2408 /*
2409 =================
2410 idGameLocal::ShutdownConsoleCommands
2411 =================
2412 */
ShutdownConsoleCommands(void)2413 void idGameLocal::ShutdownConsoleCommands( void ) {
2414 	cmdSystem->RemoveFlaggedCommands( CMD_FL_GAME );
2415 }
2416