cg_consolecmds.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. //
  19. // cg_consolecmds.c -- text commands typed in at the local console, or
  20. // executed by a key binding
  21. #include "cg_local.h"
  22. #include "../ui/ui_shared.h"
  23. #ifdef MISSIONPACK
  24. extern menuDef_t *menuScoreboard;
  25. #endif
  26. void CG_TargetCommand_f( void ) {
  27. int targetNum;
  28. char test[4];
  29. targetNum = CG_CrosshairPlayer();
  30. if (!targetNum ) {
  31. return;
  32. }
  33. trap_Argv( 1, test, 4 );
  34. trap_SendConsoleCommand( va( "gc %i %i", targetNum, atoi( test ) ) );
  35. }
  36. /*
  37. =================
  38. CG_SizeUp_f
  39. Keybinding command
  40. =================
  41. */
  42. static void CG_SizeUp_f (void) {
  43. trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer+10)));
  44. }
  45. /*
  46. =================
  47. CG_SizeDown_f
  48. Keybinding command
  49. =================
  50. */
  51. static void CG_SizeDown_f (void) {
  52. trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer-10)));
  53. }
  54. /*
  55. =============
  56. CG_Viewpos_f
  57. Debugging command to print the current position
  58. =============
  59. */
  60. static void CG_Viewpos_f (void) {
  61. CG_Printf ("(%i %i %i) : %i\n", (int)cg.refdef.vieworg[0],
  62. (int)cg.refdef.vieworg[1], (int)cg.refdef.vieworg[2],
  63. (int)cg.refdefViewAngles[YAW]);
  64. }
  65. static void CG_ScoresDown_f( void ) {
  66. #ifdef MISSIONPACK
  67. CG_BuildSpectatorString();
  68. #endif
  69. if ( cg.scoresRequestTime + 2000 < cg.time ) {
  70. // the scores are more than two seconds out of data,
  71. // so request new ones
  72. cg.scoresRequestTime = cg.time;
  73. trap_SendClientCommand( "score" );
  74. // leave the current scores up if they were already
  75. // displayed, but if this is the first hit, clear them out
  76. if ( !cg.showScores ) {
  77. cg.showScores = qtrue;
  78. cg.numScores = 0;
  79. }
  80. } else {
  81. // show the cached contents even if they just pressed if it
  82. // is within two seconds
  83. cg.showScores = qtrue;
  84. }
  85. }
  86. static void CG_ScoresUp_f( void ) {
  87. if ( cg.showScores ) {
  88. cg.showScores = qfalse;
  89. cg.scoreFadeTime = cg.time;
  90. }
  91. }
  92. #ifdef MISSIONPACK
  93. extern menuDef_t *menuScoreboard;
  94. void Menu_Reset(); // FIXME: add to right include file
  95. static void CG_LoadHud_f( void) {
  96. char buff[1024];
  97. const char *hudSet;
  98. memset(buff, 0, sizeof(buff));
  99. String_Init();
  100. Menu_Reset();
  101. trap_Cvar_VariableStringBuffer("cg_hudFiles", buff, sizeof(buff));
  102. hudSet = buff;
  103. if (hudSet[0] == '\0') {
  104. hudSet = "ui/hud.txt";
  105. }
  106. CG_LoadMenus(hudSet);
  107. menuScoreboard = NULL;
  108. }
  109. static void CG_scrollScoresDown_f( void) {
  110. if (menuScoreboard && cg.scoreBoardShowing) {
  111. Menu_ScrollFeeder(menuScoreboard, FEEDER_SCOREBOARD, qtrue);
  112. Menu_ScrollFeeder(menuScoreboard, FEEDER_REDTEAM_LIST, qtrue);
  113. Menu_ScrollFeeder(menuScoreboard, FEEDER_BLUETEAM_LIST, qtrue);
  114. }
  115. }
  116. static void CG_scrollScoresUp_f( void) {
  117. if (menuScoreboard && cg.scoreBoardShowing) {
  118. Menu_ScrollFeeder(menuScoreboard, FEEDER_SCOREBOARD, qfalse);
  119. Menu_ScrollFeeder(menuScoreboard, FEEDER_REDTEAM_LIST, qfalse);
  120. Menu_ScrollFeeder(menuScoreboard, FEEDER_BLUETEAM_LIST, qfalse);
  121. }
  122. }
  123. static void CG_spWin_f( void) {
  124. trap_Cvar_Set("cg_cameraOrbit", "2");
  125. trap_Cvar_Set("cg_cameraOrbitDelay", "35");
  126. trap_Cvar_Set("cg_thirdPerson", "1");
  127. trap_Cvar_Set("cg_thirdPersonAngle", "0");
  128. trap_Cvar_Set("cg_thirdPersonRange", "100");
  129. CG_AddBufferedSound(cgs.media.winnerSound);
  130. //trap_S_StartLocalSound(cgs.media.winnerSound, CHAN_ANNOUNCER);
  131. CG_CenterPrint("YOU WIN!", SCREEN_HEIGHT * .30, 0);
  132. }
  133. static void CG_spLose_f( void) {
  134. trap_Cvar_Set("cg_cameraOrbit", "2");
  135. trap_Cvar_Set("cg_cameraOrbitDelay", "35");
  136. trap_Cvar_Set("cg_thirdPerson", "1");
  137. trap_Cvar_Set("cg_thirdPersonAngle", "0");
  138. trap_Cvar_Set("cg_thirdPersonRange", "100");
  139. CG_AddBufferedSound(cgs.media.loserSound);
  140. //trap_S_StartLocalSound(cgs.media.loserSound, CHAN_ANNOUNCER);
  141. CG_CenterPrint("YOU LOSE...", SCREEN_HEIGHT * .30, 0);
  142. }
  143. #endif
  144. static void CG_TellTarget_f( void ) {
  145. int clientNum;
  146. char command[128];
  147. char message[128];
  148. clientNum = CG_CrosshairPlayer();
  149. if ( clientNum == -1 ) {
  150. return;
  151. }
  152. trap_Args( message, 128 );
  153. Com_sprintf( command, 128, "tell %i %s", clientNum, message );
  154. trap_SendClientCommand( command );
  155. }
  156. static void CG_TellAttacker_f( void ) {
  157. int clientNum;
  158. char command[128];
  159. char message[128];
  160. clientNum = CG_LastAttacker();
  161. if ( clientNum == -1 ) {
  162. return;
  163. }
  164. trap_Args( message, 128 );
  165. Com_sprintf( command, 128, "tell %i %s", clientNum, message );
  166. trap_SendClientCommand( command );
  167. }
  168. static void CG_VoiceTellTarget_f( void ) {
  169. int clientNum;
  170. char command[128];
  171. char message[128];
  172. clientNum = CG_CrosshairPlayer();
  173. if ( clientNum == -1 ) {
  174. return;
  175. }
  176. trap_Args( message, 128 );
  177. Com_sprintf( command, 128, "vtell %i %s", clientNum, message );
  178. trap_SendClientCommand( command );
  179. }
  180. static void CG_VoiceTellAttacker_f( void ) {
  181. int clientNum;
  182. char command[128];
  183. char message[128];
  184. clientNum = CG_LastAttacker();
  185. if ( clientNum == -1 ) {
  186. return;
  187. }
  188. trap_Args( message, 128 );
  189. Com_sprintf( command, 128, "vtell %i %s", clientNum, message );
  190. trap_SendClientCommand( command );
  191. }
  192. #ifdef MISSIONPACK
  193. static void CG_NextTeamMember_f( void ) {
  194. CG_SelectNextPlayer();
  195. }
  196. static void CG_PrevTeamMember_f( void ) {
  197. CG_SelectPrevPlayer();
  198. }
  199. // ASS U ME's enumeration order as far as task specific orders, OFFENSE is zero, CAMP is last
  200. //
  201. static void CG_NextOrder_f( void ) {
  202. clientInfo_t *ci = cgs.clientinfo + cg.snap->ps.clientNum;
  203. if (ci) {
  204. if (!ci->teamLeader && sortedTeamPlayers[cg_currentSelectedPlayer.integer] != cg.snap->ps.clientNum) {
  205. return;
  206. }
  207. }
  208. if (cgs.currentOrder < TEAMTASK_CAMP) {
  209. cgs.currentOrder++;
  210. if (cgs.currentOrder == TEAMTASK_RETRIEVE) {
  211. if (!CG_OtherTeamHasFlag()) {
  212. cgs.currentOrder++;
  213. }
  214. }
  215. if (cgs.currentOrder == TEAMTASK_ESCORT) {
  216. if (!CG_YourTeamHasFlag()) {
  217. cgs.currentOrder++;
  218. }
  219. }
  220. } else {
  221. cgs.currentOrder = TEAMTASK_OFFENSE;
  222. }
  223. cgs.orderPending = qtrue;
  224. cgs.orderTime = cg.time + 3000;
  225. }
  226. static void CG_ConfirmOrder_f (void ) {
  227. trap_SendConsoleCommand(va("cmd vtell %d %s\n", cgs.acceptLeader, VOICECHAT_YES));
  228. trap_SendConsoleCommand("+button5; wait; -button5");
  229. if (cg.time < cgs.acceptOrderTime) {
  230. trap_SendClientCommand(va("teamtask %d\n", cgs.acceptTask));
  231. cgs.acceptOrderTime = 0;
  232. }
  233. }
  234. static void CG_DenyOrder_f (void ) {
  235. trap_SendConsoleCommand(va("cmd vtell %d %s\n", cgs.acceptLeader, VOICECHAT_NO));
  236. trap_SendConsoleCommand("+button6; wait; -button6");
  237. if (cg.time < cgs.acceptOrderTime) {
  238. cgs.acceptOrderTime = 0;
  239. }
  240. }
  241. static void CG_TaskOffense_f (void ) {
  242. if (cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF) {
  243. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONGETFLAG));
  244. } else {
  245. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONOFFENSE));
  246. }
  247. trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_OFFENSE));
  248. }
  249. static void CG_TaskDefense_f (void ) {
  250. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONDEFENSE));
  251. trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_DEFENSE));
  252. }
  253. static void CG_TaskPatrol_f (void ) {
  254. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONPATROL));
  255. trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_PATROL));
  256. }
  257. static void CG_TaskCamp_f (void ) {
  258. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONCAMPING));
  259. trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_CAMP));
  260. }
  261. static void CG_TaskFollow_f (void ) {
  262. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONFOLLOW));
  263. trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_FOLLOW));
  264. }
  265. static void CG_TaskRetrieve_f (void ) {
  266. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONRETURNFLAG));
  267. trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_RETRIEVE));
  268. }
  269. static void CG_TaskEscort_f (void ) {
  270. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONFOLLOWCARRIER));
  271. trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_ESCORT));
  272. }
  273. static void CG_TaskOwnFlag_f (void ) {
  274. trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_IHAVEFLAG));
  275. }
  276. static void CG_TauntKillInsult_f (void ) {
  277. trap_SendConsoleCommand("cmd vsay kill_insult\n");
  278. }
  279. static void CG_TauntPraise_f (void ) {
  280. trap_SendConsoleCommand("cmd vsay praise\n");
  281. }
  282. static void CG_TauntTaunt_f (void ) {
  283. trap_SendConsoleCommand("cmd vtaunt\n");
  284. }
  285. static void CG_TauntDeathInsult_f (void ) {
  286. trap_SendConsoleCommand("cmd vsay death_insult\n");
  287. }
  288. static void CG_TauntGauntlet_f (void ) {
  289. trap_SendConsoleCommand("cmd vsay kill_guantlet\n");
  290. }
  291. static void CG_TaskSuicide_f (void ) {
  292. int clientNum;
  293. char command[128];
  294. clientNum = CG_CrosshairPlayer();
  295. if ( clientNum == -1 ) {
  296. return;
  297. }
  298. Com_sprintf( command, 128, "tell %i suicide", clientNum );
  299. trap_SendClientCommand( command );
  300. }
  301. /*
  302. ==================
  303. CG_TeamMenu_f
  304. ==================
  305. */
  306. /*
  307. static void CG_TeamMenu_f( void ) {
  308. if (trap_Key_GetCatcher() & KEYCATCH_CGAME) {
  309. CG_EventHandling(CGAME_EVENT_NONE);
  310. trap_Key_SetCatcher(0);
  311. } else {
  312. CG_EventHandling(CGAME_EVENT_TEAMMENU);
  313. //trap_Key_SetCatcher(KEYCATCH_CGAME);
  314. }
  315. }
  316. */
  317. /*
  318. ==================
  319. CG_EditHud_f
  320. ==================
  321. */
  322. /*
  323. static void CG_EditHud_f( void ) {
  324. //cls.keyCatchers ^= KEYCATCH_CGAME;
  325. //VM_Call (cgvm, CG_EVENT_HANDLING, (cls.keyCatchers & KEYCATCH_CGAME) ? CGAME_EVENT_EDITHUD : CGAME_EVENT_NONE);
  326. }
  327. */
  328. #endif
  329. /*
  330. ==================
  331. CG_StartOrbit_f
  332. ==================
  333. */
  334. static void CG_StartOrbit_f( void ) {
  335. char var[MAX_TOKEN_CHARS];
  336. trap_Cvar_VariableStringBuffer( "developer", var, sizeof( var ) );
  337. if ( !atoi(var) ) {
  338. return;
  339. }
  340. if (cg_cameraOrbit.value != 0) {
  341. trap_Cvar_Set ("cg_cameraOrbit", "0");
  342. trap_Cvar_Set("cg_thirdPerson", "0");
  343. } else {
  344. trap_Cvar_Set("cg_cameraOrbit", "5");
  345. trap_Cvar_Set("cg_thirdPerson", "1");
  346. trap_Cvar_Set("cg_thirdPersonAngle", "0");
  347. trap_Cvar_Set("cg_thirdPersonRange", "100");
  348. }
  349. }
  350. /*
  351. static void CG_Camera_f( void ) {
  352. char name[1024];
  353. trap_Argv( 1, name, sizeof(name));
  354. if (trap_loadCamera(name)) {
  355. cg.cameraMode = qtrue;
  356. trap_startCamera(cg.time);
  357. } else {
  358. CG_Printf ("Unable to load camera %s\n",name);
  359. }
  360. }
  361. */
  362. typedef struct {
  363. char *cmd;
  364. void (*function)(void);
  365. } consoleCommand_t;
  366. static consoleCommand_t commands[] = {
  367. { "testgun", CG_TestGun_f },
  368. { "testmodel", CG_TestModel_f },
  369. { "nextframe", CG_TestModelNextFrame_f },
  370. { "prevframe", CG_TestModelPrevFrame_f },
  371. { "nextskin", CG_TestModelNextSkin_f },
  372. { "prevskin", CG_TestModelPrevSkin_f },
  373. { "viewpos", CG_Viewpos_f },
  374. { "+scores", CG_ScoresDown_f },
  375. { "-scores", CG_ScoresUp_f },
  376. { "+zoom", CG_ZoomDown_f },
  377. { "-zoom", CG_ZoomUp_f },
  378. { "sizeup", CG_SizeUp_f },
  379. { "sizedown", CG_SizeDown_f },
  380. { "weapnext", CG_NextWeapon_f },
  381. { "weapprev", CG_PrevWeapon_f },
  382. { "weapon", CG_Weapon_f },
  383. { "tell_target", CG_TellTarget_f },
  384. { "tell_attacker", CG_TellAttacker_f },
  385. { "vtell_target", CG_VoiceTellTarget_f },
  386. { "vtell_attacker", CG_VoiceTellAttacker_f },
  387. { "tcmd", CG_TargetCommand_f },
  388. #ifdef MISSIONPACK
  389. { "loadhud", CG_LoadHud_f },
  390. { "nextTeamMember", CG_NextTeamMember_f },
  391. { "prevTeamMember", CG_PrevTeamMember_f },
  392. { "nextOrder", CG_NextOrder_f },
  393. { "confirmOrder", CG_ConfirmOrder_f },
  394. { "denyOrder", CG_DenyOrder_f },
  395. { "taskOffense", CG_TaskOffense_f },
  396. { "taskDefense", CG_TaskDefense_f },
  397. { "taskPatrol", CG_TaskPatrol_f },
  398. { "taskCamp", CG_TaskCamp_f },
  399. { "taskFollow", CG_TaskFollow_f },
  400. { "taskRetrieve", CG_TaskRetrieve_f },
  401. { "taskEscort", CG_TaskEscort_f },
  402. { "taskSuicide", CG_TaskSuicide_f },
  403. { "taskOwnFlag", CG_TaskOwnFlag_f },
  404. { "tauntKillInsult", CG_TauntKillInsult_f },
  405. { "tauntPraise", CG_TauntPraise_f },
  406. { "tauntTaunt", CG_TauntTaunt_f },
  407. { "tauntDeathInsult", CG_TauntDeathInsult_f },
  408. { "tauntGauntlet", CG_TauntGauntlet_f },
  409. { "spWin", CG_spWin_f },
  410. { "spLose", CG_spLose_f },
  411. { "scoresDown", CG_scrollScoresDown_f },
  412. { "scoresUp", CG_scrollScoresUp_f },
  413. #endif
  414. { "startOrbit", CG_StartOrbit_f },
  415. //{ "camera", CG_Camera_f },
  416. { "loaddeferred", CG_LoadDeferredPlayers }
  417. };
  418. /*
  419. =================
  420. CG_ConsoleCommand
  421. The string has been tokenized and can be retrieved with
  422. Cmd_Argc() / Cmd_Argv()
  423. =================
  424. */
  425. qboolean CG_ConsoleCommand( void ) {
  426. const char *cmd;
  427. int i;
  428. cmd = CG_Argv(0);
  429. for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
  430. if ( !Q_stricmp( cmd, commands[i].cmd ) ) {
  431. commands[i].function();
  432. return qtrue;
  433. }
  434. }
  435. return qfalse;
  436. }
  437. /*
  438. =================
  439. CG_InitConsoleCommands
  440. Let the client system know about all of our commands
  441. so it can perform tab completion
  442. =================
  443. */
  444. void CG_InitConsoleCommands( void ) {
  445. int i;
  446. for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
  447. trap_AddCommand( commands[i].cmd );
  448. }
  449. //
  450. // the game server will interpret these commands, which will be automatically
  451. // forwarded to the server after they are not recognized locally
  452. //
  453. trap_AddCommand ("kill");
  454. trap_AddCommand ("say");
  455. trap_AddCommand ("say_team");
  456. trap_AddCommand ("tell");
  457. trap_AddCommand ("vsay");
  458. trap_AddCommand ("vsay_team");
  459. trap_AddCommand ("vtell");
  460. trap_AddCommand ("vtaunt");
  461. trap_AddCommand ("vosay");
  462. trap_AddCommand ("vosay_team");
  463. trap_AddCommand ("votell");
  464. trap_AddCommand ("give");
  465. trap_AddCommand ("god");
  466. trap_AddCommand ("notarget");
  467. trap_AddCommand ("noclip");
  468. trap_AddCommand ("team");
  469. trap_AddCommand ("follow");
  470. trap_AddCommand ("levelshot");
  471. trap_AddCommand ("addbot");
  472. trap_AddCommand ("setviewpos");
  473. trap_AddCommand ("callvote");
  474. trap_AddCommand ("vote");
  475. trap_AddCommand ("callteamvote");
  476. trap_AddCommand ("teamvote");
  477. trap_AddCommand ("stats");
  478. trap_AddCommand ("teamtask");
  479. trap_AddCommand ("loaddefered"); // spelled wrong, but not changing for demo
  480. }