/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (Wolf ET Source Code).
Wolf ET Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Wolf ET Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wolf ET Source Code. If not, see .
In addition, the Wolf: ET 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 Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*
* name: cg_consolecmds.c
*
* desc: text commands typed in at the local console, or executed by a key binding
*
*/
#include "cg_local.h"
void CG_TargetCommand_f( void ) {
int targetNum;
char test[4];
targetNum = CG_CrosshairPlayer();
if ( !targetNum ) {
return;
}
trap_Argv( 1, test, 4 );
trap_SendConsoleCommand( va( "gc %i %i", targetNum, atoi( test ) ) );
}
/*
=============
CG_Viewpos_f
Debugging command to print the current position
=============
*/
static void CG_Viewpos_f( void ) {
CG_Printf( "(%i %i %i) : %i\n", (int)cg.refdef.vieworg[0],
(int)cg.refdef.vieworg[1], (int)cg.refdef.vieworg[2],
(int)cg.refdefViewAngles[YAW] );
}
void CG_LimboMenu_f( void ) {
if ( cg.showGameView ) {
CG_EventHandling( CGAME_EVENT_NONE, qfalse );
} else {
CG_EventHandling( CGAME_EVENT_GAMEVIEW, qfalse );
}
}
static void CG_StatsDown_f( void ) {
if ( !cg.demoPlayback ) {
int i = ( cg.mvTotalClients > 0 ) ? ( cg.mvCurrentActive->mvInfo & MV_PID ) : cg.snap->ps.clientNum;
if ( cg.mvTotalClients < 1 && cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
Pri( "You must be a player or following a player to use +stats\n" );
return;
}
if ( cgs.gamestats.show == SHOW_SHUTDOWN && cg.time < cgs.gamestats.fadeTime ) {
cgs.gamestats.fadeTime = 2 * cg.time + STATS_FADE_TIME - cgs.gamestats.fadeTime;
} else if ( cgs.gamestats.show != SHOW_ON ) {
cgs.gamestats.fadeTime = cg.time + STATS_FADE_TIME;
}
cgs.gamestats.show = SHOW_ON;
if ( cgs.gamestats.requestTime < cg.time ) {
cgs.gamestats.requestTime = cg.time + 2000;
trap_SendClientCommand( va( "sgstats %d", i ) );
}
}
}
static void CG_StatsUp_f( void ) {
if ( cgs.gamestats.show == SHOW_ON ) {
cgs.gamestats.show = SHOW_SHUTDOWN;
if ( cg.time < cgs.gamestats.fadeTime ) {
cgs.gamestats.fadeTime = 2 * cg.time + STATS_FADE_TIME - cgs.gamestats.fadeTime;
} else {
cgs.gamestats.fadeTime = cg.time + STATS_FADE_TIME;
}
}
}
void CG_topshotsDown_f( void ) {
if ( !cg.demoPlayback ) {
if ( cgs.topshots.show == SHOW_SHUTDOWN && cg.time < cgs.topshots.fadeTime ) {
cgs.topshots.fadeTime = 2 * cg.time + STATS_FADE_TIME - cgs.topshots.fadeTime;
} else if ( cgs.topshots.show != SHOW_ON ) {
cgs.topshots.fadeTime = cg.time + STATS_FADE_TIME;
}
cgs.topshots.show = SHOW_ON;
if ( cgs.topshots.requestTime < cg.time ) {
cgs.topshots.requestTime = cg.time + 2000;
trap_SendClientCommand( "stshots" );
}
}
}
void CG_topshotsUp_f( void ) {
if ( cgs.topshots.show == SHOW_ON ) {
cgs.topshots.show = SHOW_SHUTDOWN;
if ( cg.time < cgs.topshots.fadeTime ) {
cgs.topshots.fadeTime = 2 * cg.time + STATS_FADE_TIME - cgs.topshots.fadeTime;
} else {
cgs.topshots.fadeTime = cg.time + STATS_FADE_TIME;
}
}
}
void CG_ScoresDown_f( void ) {
if ( cg.scoresRequestTime + 2000 < cg.time ) {
// the scores are more than two seconds out of data,
// so request new ones
cg.scoresRequestTime = cg.time;
// OSP - we get periodic score updates if we are merging clients
if ( !cg.demoPlayback && cg.mvTotalClients < 1 ) {
trap_SendClientCommand( "score" );
}
// leave the current scores up if they were already
// displayed, but if this is the first hit, clear them out
if ( !cg.showScores ) {
cg.showScores = qtrue;
if ( !cg.demoPlayback && cg.mvTotalClients < 1 ) {
cg.numScores = 0;
}
}
} else {
// show the cached contents even if they just pressed if it
// is within two seconds
cg.showScores = qtrue;
}
}
void CG_ScoresUp_f( void ) {
if ( cg.showScores ) {
cg.showScores = qfalse;
cg.scoreFadeTime = cg.time;
}
}
static void CG_LoadHud_f( void ) {
// String_Init();
// Menu_Reset();
// CG_LoadMenus("ui/hud.txt");
}
static void CG_LoadWeapons_f( void ) {
int i;
for ( i = WP_KNIFE; i < WP_NUM_WEAPONS; i++ ) {
// DHM - Nerve :: Only register weapons we use in WolfMP
if ( BG_WeaponInWolfMP( i ) ) {
CG_RegisterWeapon( i, qtrue );
}
}
}
/*
static void CG_InventoryDown_f( void ) {
cg.showItems = qtrue;
}
static void CG_InventoryUp_f( void ) {
cg.showItems = qfalse;
cg.itemFadeTime = cg.time;
}
*/
static void CG_TellTarget_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_CrosshairPlayer();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
static void CG_TellAttacker_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_LastAttacker();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
/////////// cameras
#define MAX_CAMERAS 64 // matches define in splines.cpp
qboolean cameraInuse[MAX_CAMERAS];
int CG_LoadCamera( const char *name ) {
int i;
for ( i = 1; i < MAX_CAMERAS; i++ ) { // start at '1' since '0' is always taken by the cutscene camera
if ( !cameraInuse[i] ) {
if ( trap_loadCamera( i, name ) ) {
cameraInuse[i] = qtrue;
return i;
}
}
}
return -1;
}
void CG_FreeCamera( int camNum ) {
cameraInuse[camNum] = qfalse;
}
// @TEST. See if we can get an initial camera started at the first frame.
char g_initialCamera[256] = "";
qboolean g_initialCameraStartBlack = qfalse;
/*
==============
CG_SetInitialCamera
==============
*/
void CG_SetInitialCamera( const char *name, qboolean startBlack ) {
// Store this info to get reset after first snapshot inited
strcpy( g_initialCamera, name );
g_initialCameraStartBlack = startBlack;
}
/*
==============
CG_StartCamera
==============
*/
void CG_StartCamera( const char *name, qboolean startBlack ) {
char lname[MAX_QPATH];
//if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) // don't allow camera to start if you're dead
// return;
COM_StripExtension( name, lname ); //----(SA) added
strcat( lname, ".camera" );
if ( trap_loadCamera( CAM_PRIMARY, va( "cameras/%s", lname ) ) ) {
cg.cameraMode = qtrue; // camera on in cgame
if ( startBlack ) {
CG_Fade( 0, 0, 0, 255, cg.time, 0 ); // go black
}
trap_Cvar_Set( "cg_letterbox", "1" ); // go letterbox
//trap_SendClientCommand("startCamera"); // camera on in game
trap_startCamera( CAM_PRIMARY, cg.time ); // camera on in client
} else {
//----(SA) removed check for cams in main dir
cg.cameraMode = qfalse; // camera off in cgame
trap_SendClientCommand( "stopCamera" ); // camera off in game
trap_stopCamera( CAM_PRIMARY ); // camera off in client
CG_Fade( 0, 0, 0, 0, cg.time, 0 ); // ensure fadeup
trap_Cvar_Set( "cg_letterbox", "0" );
CG_Printf( "Unable to load camera %s\n",lname );
}
}
/*
==============
CG_StartInitialCamera
==============
*/
void CG_StartInitialCamera() {
// See if we've got a camera name
if ( g_initialCamera[0] != 0 ) {
// Start a camera with the initial data we stored.
CG_StartCamera( g_initialCamera, g_initialCameraStartBlack );
// Clear it now so we don't get re-entrance problems
g_initialCamera[0] = 0;
g_initialCameraStartBlack = qfalse;
} // if (g_initialCamera[0] != 0)...
}
/*
==============
CG_StopCamera
==============
*/
void CG_StopCamera( void ) {
cg.cameraMode = qfalse; // camera off in cgame
trap_SendClientCommand( "stopCamera" ); // camera off in game
trap_stopCamera( CAM_PRIMARY ); // camera off in client
trap_Cvar_Set( "cg_letterbox", "0" );
// fade back into world
CG_Fade( 0, 0, 0, 255, 0, 0 );
CG_Fade( 0, 0, 0, 0, cg.time + 500, 2000 );
}
static void CG_Fade_f( void ) {
int r, g, b, a;
float duration;
if ( trap_Argc() < 6 ) {
return;
}
r = atof( CG_Argv( 1 ) );
g = atof( CG_Argv( 2 ) );
b = atof( CG_Argv( 3 ) );
a = atof( CG_Argv( 4 ) );
duration = atof( CG_Argv( 5 ) ) * 1000;
CG_Fade( r, g, b, a, cg.time, duration );
}
void CG_QuickMessage_f( void ) {
if ( cgs.clientinfo[ cg.clientNum ].team == TEAM_SPECTATOR ) {
return;
}
CG_EventHandling( CGAME_EVENT_NONE, qfalse );
if ( cg_quickMessageAlt.integer ) {
trap_UI_Popup( UIMENU_WM_QUICKMESSAGEALT );
} else {
trap_UI_Popup( UIMENU_WM_QUICKMESSAGE );
}
}
void CG_QuickFireteamMessage_f( void ) {
if ( cgs.clientinfo[ cg.clientNum ].team == TEAM_SPECTATOR ) {
return;
}
CG_EventHandling( CGAME_EVENT_NONE, qfalse );
if ( cg_quickMessageAlt.integer ) {
trap_UI_Popup( UIMENU_WM_FTQUICKMESSAGEALT );
} else {
trap_UI_Popup( UIMENU_WM_FTQUICKMESSAGE );
}
}
void CG_QuickFireteamAdmin_f( void ) {
trap_UI_Popup( UIMENU_NONE );
if ( cg.showFireteamMenu ) {
if ( cgs.ftMenuMode == 1 ) {
CG_EventHandling( CGAME_EVENT_NONE, qfalse );
} else {
cgs.ftMenuMode = 1;
}
} else if ( cgs.clientinfo[ cg.clientNum ].team != TEAM_SPECTATOR ) {
CG_EventHandling( CGAME_EVENT_FIRETEAMMSG, qfalse );
cgs.ftMenuMode = 1;
}
}
static void CG_QuickFireteams_f( void ) {
if ( cg.showFireteamMenu ) {
if ( cgs.ftMenuMode == 0 ) {
CG_EventHandling( CGAME_EVENT_NONE, qfalse );
} else {
cgs.ftMenuMode = 0;
}
} else if ( CG_IsOnFireteam( cg.clientNum ) ) {
CG_EventHandling( CGAME_EVENT_FIRETEAMMSG, qfalse );
cgs.ftMenuMode = 0;
}
}
static void CG_FTSayPlayerClass_f( void ) {
int playerType;
const char *s;
playerType = cgs.clientinfo[ cg.clientNum ].cls;
if ( playerType == PC_MEDIC ) {
s = "IamMedic";
} else if ( playerType == PC_ENGINEER ) {
s = "IamEngineer";
} else if ( playerType == PC_FIELDOPS ) {
s = "IamFieldOps";
} else if ( playerType == PC_COVERTOPS ) {
s = "IamCovertOps";
} else {
s = "IamSoldier";
}
if ( cg.snap && ( cg.snap->ps.pm_type != PM_INTERMISSION ) ) {
if ( cgs.clientinfo[cg.clientNum].team == TEAM_SPECTATOR || cgs.clientinfo[cg.clientNum].team == TEAM_FREE ) {
CG_Printf( CG_TranslateString( "Can't team voice chat as a spectator.\n" ) );
return;
}
}
trap_SendConsoleCommand( va( "cmd vsay_buddy -1 %s %s\n", CG_BuildSelectedFirteamString(), s ) );
}
static void CG_SayPlayerClass_f( void ) {
int playerType;
const char *s;
playerType = cgs.clientinfo[ cg.clientNum ].cls;
if ( playerType == PC_MEDIC ) {
s = "IamMedic";
} else if ( playerType == PC_ENGINEER ) {
s = "IamEngineer";
} else if ( playerType == PC_FIELDOPS ) {
s = "IamFieldOps";
} else if ( playerType == PC_COVERTOPS ) {
s = "IamCovertOps";
} else {
s = "IamSoldier";
}
if ( cg.snap && ( cg.snap->ps.pm_type != PM_INTERMISSION ) ) {
if ( cgs.clientinfo[cg.clientNum].team == TEAM_SPECTATOR || cgs.clientinfo[cg.clientNum].team == TEAM_FREE ) {
CG_Printf( CG_TranslateString( "Can't team voice chat as a spectator.\n" ) );
return;
}
}
trap_SendConsoleCommand( va( "cmd vsay_team %s\n", s ) );
}
static void CG_VoiceChat_f( void ) {
char chatCmd[64];
if ( trap_Argc() != 2 ) {
return;
}
// NERVE - SMF - don't let spectators voice chat
// NOTE - This cg.snap will be the person you are following, but its just for intermission test
if ( cg.snap && ( cg.snap->ps.pm_type != PM_INTERMISSION ) ) {
if ( cgs.clientinfo[cg.clientNum].team == TEAM_SPECTATOR || cgs.clientinfo[cg.clientNum].team == TEAM_FREE ) {
CG_Printf( CG_TranslateString( "Can't voice chat as a spectator.\n" ) );
return;
}
}
trap_Argv( 1, chatCmd, 64 );
trap_SendConsoleCommand( va( "cmd vsay %s\n", chatCmd ) );
}
static void CG_TeamVoiceChat_f( void ) {
char chatCmd[64];
if ( trap_Argc() != 2 ) {
return;
}
// NERVE - SMF - don't let spectators voice chat
// NOTE - This cg.snap will be the person you are following, but its just for intermission test
if ( cg.snap && ( cg.snap->ps.pm_type != PM_INTERMISSION ) ) {
if ( cgs.clientinfo[cg.clientNum].team == TEAM_SPECTATOR || cgs.clientinfo[cg.clientNum].team == TEAM_FREE ) {
CG_Printf( CG_TranslateString( "Can't team voice chat as a spectator.\n" ) );
return;
}
}
trap_Argv( 1, chatCmd, 64 );
trap_SendConsoleCommand( va( "cmd vsay_team %s\n", chatCmd ) );
}
static void CG_BuddyVoiceChat_f( void ) {
char chatCmd[64];
if ( trap_Argc() != 2 ) {
return;
}
// NERVE - SMF - don't let spectators voice chat
// NOTE - This cg.snap will be the person you are following, but its just for intermission test
if ( cg.snap && ( cg.snap->ps.pm_type != PM_INTERMISSION ) ) {
if ( cgs.clientinfo[cg.clientNum].team == TEAM_SPECTATOR || cgs.clientinfo[cg.clientNum].team == TEAM_FREE ) {
CG_Printf( CG_TranslateString( "Can't buddy voice chat as a spectator.\n" ) );
return;
}
}
trap_Argv( 1, chatCmd, 64 );
trap_SendConsoleCommand( va( "cmd vsay_buddy -1 %s %s\n", CG_BuildSelectedFirteamString(), chatCmd ) );
}
// ydnar: say, team say, etc
static void CG_MessageMode_f( void ) {
char cmd[ 64 ];
if ( cgs.eventHandling != CGAME_EVENT_NONE ) {
return;
}
// get the actual command
trap_Argv( 0, cmd, 64 );
// team say
if ( !Q_stricmp( cmd, "messagemode2" ) ) {
trap_Cvar_Set( "cg_messageType", "2" );
}
// fireteam say
else if ( !Q_stricmp( cmd, "messagemode3" ) ) {
trap_Cvar_Set( "cg_messageType", "3" );
}
// (normal) say
else
{
trap_Cvar_Set( "cg_messageType", "1" );
}
// clear the chat text
trap_Cvar_Set( "cg_messageText", "" );
// open the menu
trap_UI_Popup( UIMENU_INGAME_MESSAGEMODE );
}
static void CG_MessageSend_f( void ) {
char messageText[ 256 ];
int messageType;
// get values
trap_Cvar_VariableStringBuffer( "cg_messageType", messageText, 256 );
messageType = atoi( messageText );
trap_Cvar_VariableStringBuffer( "cg_messageText", messageText, 256 );
// reset values
trap_Cvar_Set( "cg_messageText", "" );
trap_Cvar_Set( "cg_messageType", "" );
trap_Cvar_Set( "cg_messagePlayer", "" );
// don't send empty messages
if ( messageText[ 0 ] == '\0' ) {
return;
}
// team say
if ( messageType == 2 ) {
trap_SendConsoleCommand( va( "say_team \"%s\"\n", messageText ) );
// fireteam say
} else if ( messageType == 3 ) {
trap_SendConsoleCommand( va( "say_buddy \"%s\"\n", messageText ) );
// normal say
} else {
trap_SendConsoleCommand( va( "say \"%s\"\n", messageText ) );
}
}
static void CG_SetWeaponCrosshair_f( void ) {
char crosshair[64];
trap_Argv( 1, crosshair, 64 );
cg.newCrosshairIndex = atoi( crosshair ) + 1;
}
// -NERVE - SMF
static void CG_SelectBuddy_f( void ) {
int pos = atoi( CG_Argv( 1 ) );
int i;
clientInfo_t* ci;
// Gordon:
// 0 - 5 = select that person
// -1 = none
// -2 = all
switch ( pos ) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
if ( !CG_IsOnFireteam( cg.clientNum ) ) {
break; // Gordon: we aren't a leader, so dont allow selection
}
ci = CG_SortedFireTeamPlayerForPosition( pos, 6 );
if ( !ci ) {
break; // there was no-one in this position
}
ci->selected ^= qtrue;
break;
case - 1:
if ( !CG_IsOnFireteam( cg.clientNum ) ) {
break; // Gordon: we aren't a leader, so dont allow selection
}
for ( i = 0; i < 6; i++ ) {
ci = CG_SortedFireTeamPlayerForPosition( i, 6 );
if ( !ci ) {
break; // there was no-one in this position
}
ci->selected = qfalse;
}
break;
case - 2:
if ( !CG_IsOnFireteam( cg.clientNum ) ) {
break; // Gordon: we aren't a leader, so dont allow selection
}
for ( i = 0; i < 6; i++ ) {
ci = CG_SortedFireTeamPlayerForPosition( i, 6 );
if ( !ci ) {
break; // there was no-one in this position
}
ci->selected = qtrue;
}
break;
}
}
extern void CG_AdjustAutomapZoom( int zoomIn );
static void CG_AutomapZoomIn_f( void ) {
if ( !cgs.autoMapOff ) {
CG_AdjustAutomapZoom( qtrue );
}
}
static void CG_AutomapZoomOut_f( void ) {
if ( !cgs.autoMapOff ) {
CG_AdjustAutomapZoom( qfalse );
}
}
static void CG_AutomapExpandDown_f( void ) {
if ( !cgs.autoMapExpanded ) {
cgs.autoMapExpanded = qtrue;
if ( cg.time - cgs.autoMapExpandTime < 250.f ) {
cgs.autoMapExpandTime = cg.time - ( 250.f - ( cg.time - cgs.autoMapExpandTime ) );
} else {
cgs.autoMapExpandTime = cg.time;
}
}
}
static void CG_AutomapExpandUp_f( void ) {
if ( cgs.autoMapExpanded ) {
cgs.autoMapExpanded = qfalse;
if ( cg.time - cgs.autoMapExpandTime < 250.f ) {
cgs.autoMapExpandTime = cg.time - ( 250.f - ( cg.time - cgs.autoMapExpandTime ) );
} else {
cgs.autoMapExpandTime = cg.time;
}
}
}
static void CG_ToggleAutomap_f( void ) {
cgs.autoMapOff = !cgs.autoMapOff;
}
// OSP
const char *aMonths[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
void CG_currentTime_f( void ) {
qtime_t ct;
trap_RealTime( &ct );
CG_Printf( "[cgnotify]Current time: ^3%02d:%02d:%02d (%02d %s %d)\n", ct.tm_hour, ct.tm_min, ct.tm_sec, ct.tm_mday, aMonths[ct.tm_mon], 1900 + ct.tm_year );
}
// Dynamically names a demo and sets up the recording
void CG_autoRecord_f( void ) {
trap_SendConsoleCommand( va( "record %s\n", CG_generateFilename() ) );
}
// Dynamically names a screenshot[JPEG]
void CG_autoScreenShot_f( void ) {
trap_SendConsoleCommand( va( "screenshot%s %s\n", ( ( cg_useScreenshotJPEG.integer ) ? "JPEG" : "" ), CG_generateFilename() ) );
}
void CG_vstrDown_f( void ) {
// The engine also passes back the key code and time of the key press
if ( trap_Argc() == 5 ) {
trap_SendConsoleCommand( va( "vstr %s;", CG_Argv( 1 ) ) );
} else { CG_Printf( "[cgnotify]Usage: +vstr [down_vstr] [up_vstr]\n" );}
}
void CG_vstrUp_f( void ) {
// The engine also passes back the key code and time of the key press
if ( trap_Argc() == 5 ) {
trap_SendConsoleCommand( va( "vstr %s;", CG_Argv( 2 ) ) );
} else { CG_Printf( "[cgnotify]Usage: +vstr [down_vstr] [up_vstr]\n" );}
}
void CG_keyOn_f( void ) {
if ( !cg.demoPlayback ) {
CG_Printf( "[cgnotify]^3*** NOT PLAYING A DEMO!!\n" );
return;
}
if ( demo_infoWindow.integer > 0 ) {
CG_ShowHelp_On( &cg.demohelpWindow );
}
CG_EventHandling( CGAME_EVENT_DEMO, qtrue );
}
void CG_keyOff_f( void ) {
if ( !cg.demoPlayback ) {
return;
}
CG_EventHandling( CGAME_EVENT_NONE, qfalse );
}
void CG_dumpStats_f( void ) {
if ( cgs.dumpStatsTime < cg.time ) {
cgs.dumpStatsTime = cg.time + 2000;
trap_SendClientCommand( ( cg.mvTotalClients < 1 ) ? "weaponstats" : "statsall" );
}
}
void CG_wStatsDown_f( void ) {
int i = ( cg.mvTotalClients > 0 ) ? ( cg.mvCurrentActive->mvInfo & MV_PID ) : cg.snap->ps.clientNum;
if ( cg.mvTotalClients < 1 && cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
Pri( "You must be a player or following a player to use +wstats\n" );
return;
}
if ( cg.statsRequestTime < cg.time ) {
cg.statsRequestTime = cg.time + 500;
trap_SendClientCommand( va( "wstats %d", i ) );
}
cg.showStats = qtrue;
}
void CG_wStatsUp_f( void ) {
cg.showStats = qfalse;
CG_windowFree( cg.statsWindow );
cg.statsWindow = NULL;
}
void CG_toggleSpecHelp_f( void ) {
if ( cg.mvTotalClients > 0 && !cg.demoPlayback ) {
if ( cg.spechelpWindow != SHOW_ON && cg_specHelp.integer > 0 ) {
CG_ShowHelp_On( &cg.spechelpWindow );
} else if ( cg.spechelpWindow == SHOW_ON ) {
CG_ShowHelp_Off( &cg.spechelpWindow );
}
}
}
// -OSP
void CG_Obj_f( void ) {
// Gordon: short circuit this
}
static void CG_EditSpeakers_f( void ) {
if ( cg.editingSpeakers ) {
CG_DeActivateEditSoundMode();
} else {
const char *s = Info_ValueForKey( CG_ConfigString( CS_SYSTEMINFO ), "sv_cheats" );
if ( s[0] != '1' ) {
CG_Printf( "editSpeakers is cheat protected.\n" );
return;
}
CG_ActivateEditSoundMode();
}
}
static void CG_DumpSpeaker_f( void ) {
/* char sscrfilename[MAX_QPATH];
char soundfile[MAX_STRING_CHARS];
int i, wait, random;
char *extptr, *buffptr;
fileHandle_t f;
// Check for argument
if( trap_Argc() < 2 || trap_Argc() > 4 )
{
CG_Printf( "Usage: dumpspeaker ( | )\n" );
return;
}
wait = random = 0;
// parse the other parameters
for( i = 2; i < trap_Argc(); i++ ) {
char *valueptr = NULL;
trap_Argv( i, soundfile, sizeof(soundfile) );
for( buffptr = soundfile; *buffptr; buffptr++ ) {
if( *buffptr == '=' ) {
valueptr = buffptr + 1;
break;
}
}
Q_strncpyz( soundfile, soundfile, buffptr - soundfile + 1 );
if( !Q_stricmp( soundfile, "wait" ) )
wait = atoi( valueptr );
else if( !Q_stricmp( soundfile, "random" ) )
random = atoi( valueptr );
}
// parse soundfile
trap_Argv( 1, soundfile, sizeof(soundfile) );
// Open soundfile
Q_strncpyz( sscrfilename, cgs.mapname, sizeof(sscrfilename) );
extptr = sscrfilename + strlen( sscrfilename ) - 4;
if( extptr < sscrfilename || Q_stricmp( extptr, ".bsp" ) )
{
CG_Printf( "Unable to dump, unknown map name?\n" );
return;
}
Q_strncpyz( extptr, ".sscr", 5 );
trap_FS_FOpenFile( sscrfilename, &f, FS_APPEND_SYNC );
if( !f )
{
CG_Printf( "Failed to open '%s' for writing.\n", sscrfilename );
return;
}
// Build the entity definition
Com_sprintf( soundfile, sizeof(soundfile), "{\n\"classname\" \"target_speaker\"\n\"origin\" \"%i %i %i\"\n\"noise\" \"%s\"\n",
(int) cg.snap->ps.origin[0], (int) cg.snap->ps.origin[1], (int) cg.snap->ps.origin[2], soundfile );
if( wait ) {
Q_strcat( soundfile, sizeof(soundfile), va( "\"wait\" \"%i\"\n", wait ) );
}
if( random ) {
Q_strcat( soundfile, sizeof(soundfile), va( "\"random\" \"%i\"\n", random ) );
}
Q_strcat( soundfile, sizeof(soundfile), "}\n\n" );
// And write out/acknowledge
trap_FS_Write( soundfile, strlen( soundfile ), f );
trap_FS_FCloseFile( f );
CG_Printf( "Entity dumped to '%s' (%i %i %i).\n", sscrfilename,
(int) cg.snap->ps.origin[0], (int) cg.snap->ps.origin[1], (int) cg.snap->ps.origin[2] );*/
bg_speaker_t speaker;
trace_t tr;
vec3_t end;
if ( !cg.editingSpeakers ) {
CG_Printf( "Speaker Edit mode needs to be activated to dump speakers\n" );
return;
}
memset( &speaker, 0, sizeof( speaker ) );
speaker.volume = 127;
speaker.range = 1250;
VectorMA( cg.refdef_current->vieworg, 32, cg.refdef_current->viewaxis[0], end );
CG_Trace( &tr, cg.refdef_current->vieworg, NULL, NULL, end, -1, MASK_SOLID );
if ( tr.fraction < 1.f ) {
VectorCopy( tr.endpos, speaker.origin );
VectorMA( speaker.origin, -4, cg.refdef_current->viewaxis[0], speaker.origin );
} else {
VectorCopy( tr.endpos, speaker.origin );
}
if ( !BG_SS_StoreSpeaker( &speaker ) ) {
CG_Printf( S_COLOR_RED "ERROR: Failed to store speaker\n" );
}
}
static void CG_ModifySpeaker_f( void ) {
if ( cg.editingSpeakers ) {
CG_ModifyEditSpeaker();
}
}
static void CG_UndoSpeaker_f( void ) {
if ( cg.editingSpeakers ) {
CG_UndoEditSpeaker();
}
}
void CG_ForceTapOut_f( void ) {
trap_SendClientCommand( "forcetapout" );
}
static void CG_CPM_f( void ) {
CG_AddPMItem( PM_MESSAGE, CG_Argv( 1 ), cgs.media.voiceChatShader );
}
typedef struct {
char *cmd;
void ( *function )( void );
} consoleCommand_t;
static consoleCommand_t commands[] =
{
// { "obj", CG_Obj_f },
// { "setspawnpt", CG_Obj_f },
{ "testgun", CG_TestGun_f },
{ "testmodel", CG_TestModel_f },
{ "nextframe", CG_TestModelNextFrame_f },
{ "prevframe", CG_TestModelPrevFrame_f },
{ "nextskin", CG_TestModelNextSkin_f },
{ "prevskin", CG_TestModelPrevSkin_f },
{ "viewpos", CG_Viewpos_f },
{ "+scores", CG_ScoresDown_f },
{ "-scores", CG_ScoresUp_f },
{ "zoomin", CG_ZoomIn_f },
{ "zoomout", CG_ZoomOut_f },
{ "weaplastused", CG_LastWeaponUsed_f },
{ "weapnextinbank", CG_NextWeaponInBank_f },
{ "weapprevinbank", CG_PrevWeaponInBank_f },
{ "weapnext", CG_NextWeapon_f },
{ "weapprev", CG_PrevWeapon_f },
{ "weapalt", CG_AltWeapon_f },
{ "weapon", CG_Weapon_f },
{ "weaponbank", CG_WeaponBank_f },
{ "tell_target", CG_TellTarget_f },
{ "tell_attacker", CG_TellAttacker_f },
{ "tcmd", CG_TargetCommand_f },
{ "fade", CG_Fade_f }, // duffy
{ "loadhud", CG_LoadHud_f },
{ "loadweapons", CG_LoadWeapons_f },
{ "mp_QuickMessage", CG_QuickMessage_f },
{ "mp_fireteammsg", CG_QuickFireteams_f },
{ "mp_fireteamadmin", CG_QuickFireteamAdmin_f },
{ "wm_sayPlayerClass", CG_SayPlayerClass_f },
{ "wm_ftsayPlayerClass",CG_FTSayPlayerClass_f },
{ "VoiceChat", CG_VoiceChat_f },
{ "VoiceTeamChat", CG_TeamVoiceChat_f },
// ydnar: say, teamsay, etc
{ "messageMode", CG_MessageMode_f },
{ "messageMode2", CG_MessageMode_f },
{ "messageMode3", CG_MessageMode_f },
{ "messageSend", CG_MessageSend_f },
{ "SetWeaponCrosshair", CG_SetWeaponCrosshair_f },
// -NERVE - SMF
{ "VoiceFireTeamChat", CG_BuddyVoiceChat_f },
{ "openlimbomenu", CG_LimboMenu_f },
{ "+stats", CG_StatsDown_f },
{ "-stats", CG_StatsUp_f },
{ "+topshots", CG_topshotsDown_f },
{ "-topshots", CG_topshotsUp_f },
// OSP
{ "autoRecord", CG_autoRecord_f },
{ "autoScreenshot", CG_autoScreenShot_f },
{ "currentTime", CG_currentTime_f },
{ "keyoff", CG_keyOff_f },
{ "keyon", CG_keyOn_f },
#ifdef MV_SUPPORT
{ "mvactivate", CG_mvToggleAll_f },
{ "mvdel", CG_mvDelete_f },
{ "mvhide", CG_mvHideView_f },
{ "mvnew", CG_mvNew_f },
{ "mvshow", CG_mvShowView_f },
{ "mvswap", CG_mvSwapViews_f },
{ "mvtoggle", CG_mvToggleView_f },
{ "spechelp", CG_toggleSpecHelp_f },
#endif
{ "statsdump", CG_dumpStats_f },
{ "+vstr", CG_vstrDown_f },
{ "-vstr", CG_vstrUp_f },
// OSP
{ "selectbuddy", CG_SelectBuddy_f },
{ "MapZoomIn", CG_AutomapZoomIn_f },
{ "MapZoomOut", CG_AutomapZoomOut_f },
{ "+mapexpand", CG_AutomapExpandDown_f },
{ "-mapexpand", CG_AutomapExpandUp_f },
{ "generateTracemap", CG_GenerateTracemap },
// xkan, 11/27/2002, toggle automap on/off
{ "ToggleAutoMap", CG_ToggleAutomap_f },
{ "editSpeakers", CG_EditSpeakers_f },
{ "dumpSpeaker", CG_DumpSpeaker_f },
{ "modifySpeaker", CG_ModifySpeaker_f },
{ "undoSpeaker", CG_UndoSpeaker_f },
{ "cpm", CG_CPM_f },
{ "forcetapout", CG_ForceTapOut_f },
};
/*
=================
CG_ConsoleCommand
The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
qboolean CG_ConsoleCommand( void ) {
const char *cmd;
int i;
// Arnout - don't allow console commands until a snapshot is present
if ( !cg.snap ) {
return qfalse;
}
cmd = CG_Argv( 0 );
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
if ( !Q_stricmp( cmd, commands[i].cmd ) ) {
commands[i].function();
return qtrue;
}
}
return qfalse;
}
/*
=================
CG_InitConsoleCommands
Let the client system know about all of our commands
so it can perform tab completion
=================
*/
void CG_InitConsoleCommands( void ) {
int i;
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
trap_AddCommand( commands[i].cmd );
}
//
// the game server will interpret these commands, which will be automatically
// forwarded to the server after they are not recognized locally
//
trap_AddCommand( "kill" );
trap_AddCommand( "say" );
trap_AddCommand( "say_limbo" ); // NERVE - SMF
trap_AddCommand( "tell" );
trap_AddCommand( "listbotgoals" );
trap_AddCommand( "give" );
trap_AddCommand( "god" );
trap_AddCommand( "notarget" );
trap_AddCommand( "noclip" );
trap_AddCommand( "team" );
trap_AddCommand( "follow" );
trap_AddCommand( "addbot" );
trap_AddCommand( "setviewpos" );
trap_AddCommand( "callvote" );
trap_AddCommand( "vote" );
// Rafael
trap_AddCommand( "nofatigue" );
// NERVE - SMF
trap_AddCommand( "follownext" );
trap_AddCommand( "followprev" );
trap_AddCommand( "start_match" );
trap_AddCommand( "reset_match" );
trap_AddCommand( "swap_teams" );
// -NERVE - SMF
// OSP
trap_AddCommand( "?" );
trap_AddCommand( "bottomshots" );
trap_AddCommand( "commands" );
trap_AddCommand( "follow" );
trap_AddCommand( "lock" );
#ifdef MV_SUPPORT
trap_AddCommand( "mvadd" );
trap_AddCommand( "mvaxis" );
trap_AddCommand( "mvallies" );
trap_AddCommand( "mvall" );
trap_AddCommand( "mvnone" );
#endif
trap_AddCommand( "notready" );
trap_AddCommand( "pause" );
trap_AddCommand( "players" );
trap_AddCommand( "readyteam" );
trap_AddCommand( "ready" );
trap_AddCommand( "ref" );
trap_AddCommand( "say_teamnl" );
trap_AddCommand( "say_team" );
trap_AddCommand( "scores" );
trap_AddCommand( "specinvite" );
trap_AddCommand( "speclock" );
trap_AddCommand( "specunlock" );
trap_AddCommand( "statsall" );
trap_AddCommand( "statsdump" );
trap_AddCommand( "timein" );
trap_AddCommand( "timeout" );
trap_AddCommand( "topshots" );
trap_AddCommand( "unlock" );
trap_AddCommand( "unpause" );
trap_AddCommand( "unready" );
trap_AddCommand( "weaponstats" );
// OSP
trap_AddCommand( "fireteam" );
trap_AddCommand( "buddylist" );
trap_AddCommand( "showstats" );
trap_AddCommand( "ignore" );
trap_AddCommand( "unignore" );
trap_AddCommand( "addtt" );
trap_AddCommand( "selectbuddy" );
trap_AddCommand( "selectNextBuddy" ); // xkan 9/26/2002
trap_AddCommand( "loadgame" );
trap_AddCommand( "savegame" );
trap_AddCommand( "campaign" );
trap_AddCommand( "listcampaigns" );
trap_AddCommand( "setweapons" );
trap_AddCommand( "setclass" );
}