//----------------------------------------------------------------------------- // // $Id$ // //----------------------------------------------------------------------------- // // $Log$ // Revision 1.58 2007/02/03 15:02:21 jbravo // Renamed RQ3 to Reaction, Dropped loading of various baseq3 media, disabled the follow command, fixed grenades killing teammates and some cleanups // // Revision 1.57 2004/01/26 21:26:08 makro // no message // // Revision 1.56 2003/09/20 19:38:16 makro // Lens flares, what else ? // // Revision 1.55 2003/04/09 02:00:43 jbravo // Fixed team none in DM and some final cleanups for the 3.0 release // // Revision 1.54 2002/10/26 00:37:18 jbravo // New multiple item code and added PB support to the UI // // Revision 1.53 2002/06/23 23:32:29 jbravo // Fixed logging of clients IP addresses. // // Revision 1.52 2002/06/16 20:06:13 jbravo // Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap" // // Revision 1.51 2002/06/16 19:12:51 jbravo // Removed the MISSIONPACK ifdefs and missionpack only code. // // Revision 1.50 2002/06/02 22:23:57 makro // no message // // Revision 1.49 2002/05/12 19:15:47 jbravo // Added playerlist, did some cleanup on votes. // // Revision 1.48 2002/05/12 16:10:19 jbravo // Added unignore // // Revision 1.47 2002/05/12 12:14:14 slicer // Added Referee command for captains // // Revision 1.46 2002/05/10 04:06:27 jbravo // Added Ignore // // Revision 1.45 2002/04/28 11:01:21 slicer // Added "teammodel" command for Matchmode // // Revision 1.44 2002/04/26 03:39:34 jbravo // added tkok, fixed players always leaving zcam modes when player thats // beeing tracked dies // // Revision 1.43 2002/04/07 12:49:53 slicer // Added 'teamname' command for MM, and tweaked the cvar system. // // Revision 1.42 2002/04/03 09:26:47 jbravo // New FF system. Warns and then finally kickbans teamwounders and // teamkillers // // Revision 1.41 2002/03/31 23:41:45 jbravo // Added the use command // // Revision 1.40 2002/03/31 17:41:03 makro // Changed IR vision to be more like AQ2 // // Revision 1.39 2002/03/31 13:52:48 jbravo // More cleanups // // Revision 1.38 2002/03/30 21:51:42 jbravo // Removed all those ifdefs for zcam. // // Revision 1.37 2002/03/30 02:29:43 jbravo // Lots of spectator code updates. Removed debugshit, added some color. // // Revision 1.36 2002/03/24 22:51:30 niceass // scoreboard toggle changes // // Revision 1.35 2002/03/19 06:00:14 niceass // tab scoreboard quicky change to q2 way // // Revision 1.34 2002/03/18 19:19:08 slicer // Fixed bandage bugs ( i hope ) // // Revision 1.33 2002/03/17 13:41:28 jbravo // Added a debug cmd to print out stuff when bugs occor // // Revision 1.32 2002/03/14 02:24:39 jbravo // Adding radio :) // // Revision 1.31 2002/03/13 18:41:18 slicer // Adjusted some of elder's unzoom code for the new sniper system ( server side ) // // Revision 1.30 2002/03/07 00:03:00 assimon // Added some trap_AddComand for ref cvars // // Revision 1.29 2002/02/28 05:41:54 blaze // weapons stats on client side // // Revision 1.28 2002/02/10 08:17:08 niceass // many changes to scoreboard (deaths/second mode) // // Revision 1.27 2002/02/09 00:10:12 jbravo // Fixed spectator follow and free and updated zcam to 1.04 and added the // missing zcam files. // // Revision 1.26 2002/02/08 05:59:09 niceass // scoreboard timer thing added // // Revision 1.25 2002/02/03 21:24:12 slicer // More Matchmode code // // Revision 1.23 2002/01/11 20:20:57 jbravo // Adding TP to main branch // // Revision 1.22 2002/01/11 19:48:29 jbravo // Formatted the source in non DOS format. // // Revision 1.21 2001/12/31 16:28:41 jbravo // I made a Booboo with the Log tag. // // //----------------------------------------------------------------------------- // Copyright (C) 1999-2000 Id Software, Inc. // // cg_consolecmds.c -- 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 == -1 ) { return; } trap_Argv(1, test, 4); trap_SendClientCommand( va( "gc %i %i", targetNum, atoi( test ) ) ); } /* ================= CG_DropWeapon_f JBravo: not used. Elder: reset local zoom, then proceed with server action ================= */ /* static void CG_DropWeapon_f (void) { if ( !cg.snap ) { //CG_Printf("No snapshot: normally exiting\n"); return; } // if we are going into the intermission, don't do anything if ( cg.intermissionStarted ) { return; } ///Elder: spectator? if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) { return; } // if ((cg.snap->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) if(cg.snap->ps.weaponstate == WEAPON_BANDAGING) { CG_Printf("You are too busy bandaging!\n"); return; } //Slicer: Done Server Side // CG_RQ3_Zoom1x(); trap_SendClientCommand("dropweapon"); } */ /* ================= CG_DropItem_f JBravo: not used. Elder: Do any client pre-processing here for drop item ================= */ /* static void CG_DropItem_f (void) { if ( !cg.snap ) { //CG_Printf("No snapshot: normally exiting\n"); return; } // if we are going into the intermission, don't do anything if ( cg.intermissionStarted ) { return; } ///Elder: spectator? if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) { return; } trap_SendClientCommand("dropitem"); } */ /* ================= CG_Bandage_f Elder: check cases that are possible before sending the client command to reduce bandwidth use slightly ================= */ static void CG_Bandage_f(void) { if (!cg.snap) { return; } // if we are going into the intermission, don't do anything if (cg.intermissionStarted) { return; } //Elder: spectator? if (cg.snap->ps.pm_flags & PMF_FOLLOW) { return; } //Elder: prevent "bandaging" when dead hehe if (cg.snap->ps.stats[STAT_HEALTH] < 0) { CG_AddMessage("It's a bit too late to bandage yourself...\n"); return; } // if ( (cg.snap->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) { if (cg.snap->ps.weaponstate == WEAPON_BANDAGING) { CG_AddMessage("You are already bandaging!\n"); return; } //Elder: don't allow bandaging when in the middle of bursts if (cg.snap->ps.stats[STAT_BURST] > 0) return; //Elder: added to prevent bandaging while reloading or firing //Moved below "already-bandaging" case and removed message //if ( cg.snap->ps.weaponTime > 0 || cg.snap->ps.weaponstate == WEAPON_COCKED) { //CG_Printf("You are too busy with your weapon!\n"); //return; //} if (cg.snap->ps.weaponTime > 0 || cg.snap->ps.stats[STAT_RELOADTIME] > 0) return; //Slicer: Done Server Side /* if ( (cg.snap->ps.stats[STAT_RQ3] & RQ3_BANDAGE_NEED) == RQ3_BANDAGE_NEED) { CG_RQ3_Zoom1x(); } */ trap_SendClientCommand("bandage"); } /* ================= CG_SizeUp_f Keybinding command ================= */ static void CG_SizeUp_f(void) { trap_Cvar_Set("cg_viewsize", va("%i", (int) (cg_viewsize.integer + 10))); } /* ================= CG_SizeDown_f Keybinding command ================= */ static void CG_SizeDown_f(void) { trap_Cvar_Set("cg_viewsize", va("%i", (int) (cg_viewsize.integer - 10))); } /* ============= CG_Viewpos_f Debugging command to print the current position ============= */ static void CG_Viewpos_f(void) { CG_Printf("(%i %i %i) : %.2f %.2f\n", (int) cg.refdef.vieworg[0], (int) cg.refdef.vieworg[1], (int) cg.refdef.vieworg[2], cg.refdefViewAngles[PITCH], cg.refdefViewAngles[YAW]); } /* ============= CG_PlayerOrigin_f Debugging command to print player's origin ============= */ static void CG_PlayerOrigin_f(void) { CG_Printf("(%i %i %i)\n", (int) cg.snap->ps.origin[0], (int) cg.snap->ps.origin[1], (int) cg.snap->ps.origin[2]); } static void CG_ScoresDown_f( void ) { if ( cg.time - cg.scoreFadeTime < 500 && !cg.showScores) cg.scoreTPMode = (cg.scoreTPMode == 0) ? 1 : 0; // Toggle if ( cg.time - cg.scoreFadeTime >= 500 && !cg.showScores) cg.scoreTPMode = 0; if ( !cg.showScores ) cg.scoreStartTime = cg.time; if ( cg.scoresRequestTime + 2000 < cg.time ) { // the scores are more than two seconds out of date, // so request new ones cg.scoresRequestTime = cg.time; 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; cg.numScores = 0; } } else { // show the cached contents even if they just pressed if it // is within two seconds cg.showScores = qtrue; } } static void CG_ScoresUp_f( void ) { if ( cg.showScores ) { cg.showScores = qfalse; cg.scoreFadeTime = cg.time; } } static void CG_Scores_f(void) { if (cgs.gametype >= GT_TEAM) { if (cg.showScores && cg.scoreTPMode == 1) { cg.showScores = qfalse; cg.scoreFadeTime = 0; //cg.time; cg.scoreTPMode = 0; return; } if (cg.scoreTPMode == 0 && cg.showScores) { cg.scoreTPMode = 1; return; } } else { if (cg.showScores) { cg.showScores = qfalse; cg.scoreFadeTime = 0; //cg.time; return; } } if (cg.scoresRequestTime + 2000 < cg.time) { // the scores are more than two seconds out of data, // so request new ones cg.scoresRequestTime = cg.time; 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; cg.scoreStartTime = cg.time; cg.numScores = 0; } } else { // show the cached contents even if they just pressed if it // is within two seconds cg.showScores = qtrue; cg.scoreStartTime = cg.time; } } /* ================================= CG_WeaponStatsUp_f Turns on the players weapon stats ================================= */ static void CG_WeaponStatsUp_f(void) { if (cg.wstatsRequestTime + 2000 < cg.time) { // the stats are more than two seconds out of data, // so request new ones cg.wstatsRequestTime = cg.time; trap_SendClientCommand("wstats"); } if (!cg.showWStats) { cg.wstatsStartTime = cg.time; cg.showWStats = qtrue; } } /* ================================= CG_WeaponStatsDown_f Turns off the players weapon stats ================================= */ static void CG_WeaponStatsDown_f(void) { if (cg.showWStats) { cg.showWStats = qfalse; } } 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); } static void CG_VoiceTellTarget_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, "vtell %i %s", clientNum, message); trap_SendClientCommand(command); } static void CG_VoiceTellAttacker_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, "vtell %i %s", clientNum, message); trap_SendClientCommand(command); } /* ================== CG_StartOrbit_f ================== */ static void CG_StartOrbit_f(void) { char var[MAX_TOKEN_CHARS]; trap_Cvar_VariableStringBuffer("developer", var, sizeof(var)); if (!atoi(var)) { return; } if (cg_cameraOrbit.value != 0) { trap_Cvar_Set("cg_cameraOrbit", "0"); trap_Cvar_Set("cg_thirdPerson", "0"); } else { trap_Cvar_Set("cg_cameraOrbit", "5"); trap_Cvar_Set("cg_thirdPerson", "1"); trap_Cvar_Set("cg_thirdPersonAngle", "0"); trap_Cvar_Set("cg_thirdPersonRange", "100"); } } /* static void CG_Camera_f( void ) { char name[1024]; trap_Argv( 1, name, sizeof(name)); if (trap_loadCamera(name)) { cg.cameraMode = qtrue; trap_startCamera(cg.time); } else { CG_Printf ("Unable to load camera %s\n",name); } } */ /* ================== CG_Say_f JBravo: not used. Elder: Pre-validate say command to avoid text flooding ================== */ /* static void CG_Say_f ( void ) { if (cg.time - cg.sayTime > 2000) cg.sayCount = 0; if (cg.sayCount == 0) cg.sayTime = cg.time; cg.sayCount++; // CG_Printf("sayCount: %i sayTime: %i\n", cg.sayCount, cg.sayTime); if (cg.sayCount > 4 && cg.time - cg.sayTime < 2000) { CG_Printf("Cannot send messages.\n"); return; } trap_SendClientCommand("say"); } */ /* ================== CG_SayTeam_f JBravo: Not used. Elder: Pre-validate say_team command to avoid text flooding ================== */ /* static void CG_SayTeam_f ( void ) { if (cg.time - cg.sayTime > 2000) cg.sayCount = 0; if (cg.sayCount == 0) cg.sayTime = cg.time; cg.sayCount++; // CG_Printf("sayCount: %i sayTime: %i\n", cg.sayCount, cg.sayTime); if (cg.sayCount > 4 && cg.time - cg.sayTime < 2000) { CG_Printf("Cannot send messages.\n"); return; } trap_SendClientCommand("say_team"); } */ /* ==================================== CG_IRVision_f Elder: Attempt to turn on IR Vision Makro: Made it so that the player can use this even if he doesn't have a bandolier ==================================== */ static void CG_IRVision_f(void) { const char *status = "enabled"; cg.rq3_irvision = !(cg.rq3_irvision); if (!(cg.rq3_irvision)) { status = "disabled"; } if (cg.snap->ps.stats[STAT_HOLDABLE_ITEM] & (1 << HI_BANDOLIER)) { CG_AddMessage(va("IR vision %s.\n", status)); } else { CG_AddMessage(va("IR vision will be %s next time you get a bandolier.\n", status)); } trap_S_StartLocalSound(cgs.media.weapToggleSound, CHAN_ITEM); } //Makro - added static void CG_ReloadModel_f(void) { int i = atoi(CG_Argv(1)), j = atoi(CG_Argv(2)); if (i == 0) { CG_ReplaceModels(); CG_RegisterWeapon(j); } } typedef struct { char *cmd; void (*function) (void); } consoleCommand_t; static consoleCommand_t commands[] = { {"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}, {"playerorigin", CG_PlayerOrigin_f}, {"+scores", CG_ScoresDown_f }, { "-scores", CG_ScoresUp_f }, {"scores", CG_Scores_f}, /* { "+zoom", CG_ZoomDown_f }, // hawkins not needed in Reaction { "-zoom", CG_ZoomUp_f },*/ //Blaze: Weapon stats {"+wstats", CG_WeaponStatsUp_f}, {"-wstats", CG_WeaponStatsDown_f}, {"sizeup", CG_SizeUp_f}, {"sizedown", CG_SizeDown_f}, {"weapnext", CG_NextWeapon_f}, {"weapprev", CG_PrevWeapon_f}, {"weapon", CG_Weapon_f}, // Elder: it's for RQ3 and Q3A // JBravo: adding the drop command and unregistering the other two // { "dropitem", CG_DropItem_f }, // { "dropweapon", CG_DropWeapon_f }, // Elder: added to reset zoom then goto server {"bandage", CG_Bandage_f}, // Elder: added to reset zoom then goto server {"specialweapon", CG_SpecialWeapon_f}, // Elder: select special weapon {"tell_target", CG_TellTarget_f}, {"tell_attacker", CG_TellAttacker_f}, {"vtell_target", CG_VoiceTellTarget_f}, {"vtell_attacker", CG_VoiceTellAttacker_f}, {"tcmd", CG_TargetCommand_f}, {"startOrbit", CG_StartOrbit_f}, //{ "camera", CG_Camera_f }, {"loaddeferred", CG_LoadDeferredPlayers}, {"irvision", CG_IRVision_f}, {"reloadmodel", CG_ReloadModel_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; cmd = CG_Argv(0); for ( i = 0 ; i < ARRAY_LEN( commands ) ; 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 < ARRAY_LEN( commands ) ; 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_team"); trap_AddCommand("tell"); trap_AddCommand("vsay"); trap_AddCommand("vsay_team"); trap_AddCommand("vtell"); trap_AddCommand("vtaunt"); trap_AddCommand("vosay"); trap_AddCommand("vosay_team"); trap_AddCommand("votell"); trap_AddCommand("give"); trap_AddCommand("god"); trap_AddCommand("notarget"); trap_AddCommand("noclip"); trap_AddCommand ("where"); trap_AddCommand("team"); // JBravo: no thanks. // trap_AddCommand("follow"); // trap_AddCommand ("follownext"); // trap_AddCommand ("followprev"); trap_AddCommand("levelshot"); trap_AddCommand("addbot"); trap_AddCommand("setviewpos"); trap_AddCommand("callvote"); trap_AddCommand("vote"); trap_AddCommand("callteamvote"); trap_AddCommand("teamvote"); trap_AddCommand("stats"); trap_AddCommand("teamtask"); //Makro - fixed spelling //trap_AddCommand ("loaddefered"); // spelled wrong, but not changing for demo trap_AddCommand("loaddeferred"); trap_AddCommand("opendoor"); trap_AddCommand("bandage"); //trap_AddCommand ("drop"); // XRAY FMJ weap drop cmd - Elder: not used //Elder: added to give drop weapon auto-complete // JBravo: no need for tab completion for those two // trap_AddCommand ("dropweapon"); // trap_AddCommand ("dropitem"); //Blaze: to get weapon stats trap_AddCommand("playerstats"); //Elder: try this trap_AddCommand("weapon"); trap_AddCommand("specialweapon"); //trap_AddCommand ("messagemode"); //trap_AddCommand ("messagemode2"); trap_AddCommand("playerorigin"); trap_AddCommand("irvision"); // JBravo: adding choose and drop commands. trap_AddCommand("choose"); trap_AddCommand("use"); trap_AddCommand("drop"); trap_AddCommand("unzoom"); // JBravo: for zcam trap_AddCommand("camera"); // JBravo: for radio trap_AddCommand("radio"); trap_AddCommand("radiogender"); trap_AddCommand("radio_power"); // JBravo: tkok trap_AddCommand("tkok"); trap_AddCommand("playerlist"); // JBravo: ignore trap_AddCommand("ignorenum"); trap_AddCommand("unignorenum"); trap_AddCommand("ignore"); trap_AddCommand("unignore"); trap_AddCommand("clearignorelist"); // Slicer: Matchmode trap_AddCommand("captain"); trap_AddCommand("ready"); trap_AddCommand("sub"); trap_AddCommand("teamname"); trap_AddCommand("teammodel"); trap_AddCommand("referee"); // aasimon: refeere mm trap_AddCommand("reflogin"); trap_AddCommand("ref"); trap_AddCommand("refresign"); // trap_AddCommand("debugshit"); }