]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/command/cl_cmd.qc
Merge branch 'master' into terencehill/quickmenu
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / command / cl_cmd.qc
1 // ==============================================
2 //  CSQC client commands code, written by Samual
3 //  Last updated: December 28th, 2011
4 // ==============================================
5
6 void DrawDebugModel()
7 {
8         if(time - floor(time) > 0.5)
9         {
10                 PolyDrawModel(self);
11                 self.drawmask = 0;
12         }
13         else
14         {
15                 self.renderflags = 0;
16                 self.drawmask = MASK_NORMAL;
17         }
18 }
19
20
21 // =======================
22 //  Command Sub-Functions
23 // =======================
24
25 void LocalCommand_blurtest(float request)
26 {
27         // Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now...
28         // Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command.
29         
30         #ifdef BLURTEST
31         switch(request)
32         {
33                 case CMD_REQUEST_COMMAND:
34                 {
35                         blurtest_time0 = time;
36                         blurtest_time1 = time + stof(argv(1));
37                         blurtest_radius = stof(argv(2));
38                         blurtest_power = stof(argv(3));
39                         print("Enabled blurtest\n");
40                         return; 
41                 }
42                         
43                 default:
44                 case CMD_REQUEST_USAGE:
45                 {
46                         print("\nUsage:^3 cl_cmd blurtest\n");
47                         print("  No arguments required.\n");
48                         return;
49                 }
50         }
51         #else
52         if(request)
53         {
54                 print("Blurtest is not enabled on this client.\n");
55                 return;
56         }
57         #endif
58 }
59
60 void LocalCommand_debugmodel(float request, float argc)
61 {
62         switch(request)
63         {
64                 case CMD_REQUEST_COMMAND:
65                 {
66                         string modelname = argv(1);
67                         entity debugmodel_entity;
68                         
69                         debugmodel_entity = spawn();
70                         precache_model(modelname);
71                         setmodel(debugmodel_entity, modelname);
72                         setorigin(debugmodel_entity, view_origin);
73                         debugmodel_entity.angles = view_angles;
74                         debugmodel_entity.draw = DrawDebugModel;
75                         debugmodel_entity.classname = "debugmodel";
76                         
77                         return; 
78                 }
79                         
80                 default:
81                 case CMD_REQUEST_USAGE:
82                 {
83                         print("\nUsage:^3 cl_cmd debugmodel model\n");
84                         print("  Where 'model' is a string of the model name to use for the debug model.\n");
85                         return;
86                 }
87         }
88 }
89
90 void LocalCommand_handlevote(float request, float argc)
91 {
92         switch(request)
93         {
94                 case CMD_REQUEST_COMMAND:
95                 {
96                         float vote_selection;
97                         string vote_string;
98                         
99                         if(InterpretBoolean(argv(1)))
100                         {
101                                 vote_selection = 2; 
102                                 vote_string = "yes";
103                         }
104                         else
105                         {
106                                 vote_selection = 1; 
107                                 vote_string = "no"; 
108                         }
109                         
110                         if(vote_selection)
111                         {
112                                 if(uid2name_dialog) // handled by "uid2name" option
113                                 {
114                                         vote_active = 0;
115                                         vote_prev = 0;
116                                         vote_change = -9999;
117                                         localcmd(strcat("setreport cl_allow_uid2name ", ftos(vote_selection - 1), "\n"));
118                                         uid2name_dialog = 0;
119                                 }
120                                 else { localcmd(strcat("cmd vote ", vote_string, "\n")); }
121                                 
122                                 return;
123                         }
124                 }
125                         
126                 default:
127                         print("Incorrect parameters for ^2handlevote^7\n");
128                 case CMD_REQUEST_USAGE:
129                 {
130                         print("\nUsage:^3 cl_cmd handlevote vote\n");
131                         print("  Where 'vote' is the selection for either the current poll or uid2name.\n");
132                         return;
133                 }
134         }
135 }
136
137 void LocalCommand_hud(float request, float argc)
138 {
139         switch(request)
140         {
141                 case CMD_REQUEST_COMMAND:
142                 {
143                         switch(argv(1))
144                         {
145                                 case "configure":
146                                 {
147                                         cvar_set("_hud_configure", ftos(!autocvar__hud_configure));
148                                         return;
149                                 }
150
151                                 case "quickmenu":
152                                 {
153                                         if(argc == 2 && HUD_QuickMenu_IsOpened())
154                                                 HUD_QuickMenu_Close();
155                                         else
156                                                 if (HUD_QuickMenu_Buffer_Init())
157                                                         HUD_QuickMenu_Open("", 0);
158                                         return;
159                                 }
160
161                                 case "save":
162                                 {
163                                         if(argv(2))
164                                         {
165                                                 HUD_Panel_ExportCfg(argv(2));
166                                                 return;
167                                         }
168                                         else
169                                         {
170                                                 break; // go to usage, we're missing the paramater needed here.
171                                         }
172                                 }
173
174                                 case "scoreboard_columns_set":
175                                 {
176                                         Cmd_HUD_SetFields(argc);
177                                         return;
178                                 }
179
180                                 case "scoreboard_columns_help":
181                                 {
182                                         Cmd_HUD_Help();
183                                         return;
184                                 }
185
186                                 case "radar":
187                                 {
188                                         hud_panel_radar_maximized = (argv(2) ? InterpretBoolean(argv(2)) : !hud_panel_radar_maximized);
189                                         return;
190                                 }
191                         }
192                 }
193
194                 default:
195                         print("Incorrect parameters for ^2hud^7\n");
196                 case CMD_REQUEST_USAGE:
197                 {
198                         print("\nUsage:^3 cl_cmd hud action [configname | radartoggle | layout]\n");
199                         print("  Where 'action' is the command to complete,\n");
200                         print("  'configname' is the name to save to for \"save\" action,\n");
201                         print("  'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action,\n");
202                         print("  and 'layout' is how to organize the scoreboard columns for the set action.\n");
203                         print("  Full list of commands here: \"configure, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"\n");
204                         return;
205                 }
206         }
207 }
208
209 void LocalCommand_localprint(float request, float argc)
210 {
211         switch(request)
212         {
213                 case CMD_REQUEST_COMMAND:
214                 {
215                         if(argv(1))
216                         {
217                                 centerprint_hud(argv(1));
218                                 return; 
219                         }
220                 }
221                         
222                 default:
223                         print("Incorrect parameters for ^2localprint^7\n");
224                 case CMD_REQUEST_USAGE:
225                 {
226                         print("\nUsage:^3 cl_cmd localprint \"message\"\n");
227                         print("  'message' is the centerprint message to send to yourself.\n");
228                         return;
229                 }
230         }
231 }
232
233 void LocalCommand_mv_download(float request, float argc)
234 {
235         switch(request)
236         {
237                 case CMD_REQUEST_COMMAND:
238                 {
239                         if(argv(1))
240                         {
241                                 Cmd_MapVote_MapDownload(argc);
242                                 return; 
243                         }
244                 }
245                         
246                 default:
247                         print("Incorrect parameters for ^2mv_download^7\n");
248                 case CMD_REQUEST_USAGE:
249                 {
250                         print("\nUsage:^3 cl_cmd mv_download mapid\n");
251                         print("  Where 'mapid' is the id number of the map to request an image of on the map vote selection menu.\n");
252                         return;
253                 }
254         }
255 }
256
257 void LocalCommand_sendcvar(float request, float argc)
258 {
259         switch(request)
260         {
261                 case CMD_REQUEST_COMMAND:
262                 {
263                         if(argv(1))
264                         {
265                                 // W_FixWeaponOrder will trash argv, so save what we need.
266                                 string thiscvar = strzone(argv(1));
267                                 string s = cvar_string(thiscvar);
268                                 
269                                 if(thiscvar == "cl_weaponpriority")
270                                         s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1);
271                                 else if(substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18)
272                                         s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0);
273                                         
274                                 localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n");
275                                 strunzone(thiscvar);
276                                 return; 
277                         }
278                 }
279                         
280                 default:
281                         print("Incorrect parameters for ^2sendcvar^7\n");
282                 case CMD_REQUEST_USAGE:
283                 {
284                         print("\nUsage:^3 cl_cmd sendcvar <cvar>\n");
285                         print("  Where 'cvar' is the cvar plus arguments to send to the server.\n");
286                         return;
287                 }
288         }
289 }
290
291 /* use this when creating a new command, making sure to place it in alphabetical order... also,
292 ** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
293 void LocalCommand_(float request)
294 {
295         switch(request)
296         {
297                 case CMD_REQUEST_COMMAND:
298                 {
299                         
300                         return; 
301                 }
302                         
303                 default:
304                 case CMD_REQUEST_USAGE:
305                 {
306                         print("\nUsage:^3 cl_cmd \n");
307                         print("  No arguments required.\n");
308                         return;
309                 }
310         }
311 }
312 */
313
314
315 // ==================================
316 //  Macro system for client commands
317 // ==================================
318
319 // Normally do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
320 // but for 0.5 compat, we need vyes and vno here as they were replaced... REMOVE THEM AFTER 0.6 RELEASE!!!!
321 #define CLIENT_COMMANDS(request,arguments) \
322         CLIENT_COMMAND("blurtest", LocalCommand_blurtest(request), "Feature for testing blur postprocessing") \
323         CLIENT_COMMAND("debugmodel", LocalCommand_debugmodel(request, arguments), "Spawn a debug model manually") \
324         CLIENT_COMMAND("handlevote", LocalCommand_handlevote(request, arguments), "System to handle selecting a vote or option") \
325         CLIENT_COMMAND("hud", LocalCommand_hud(request, arguments), "Commands regarding/controlling the HUD system") \
326         CLIENT_COMMAND("localprint", LocalCommand_localprint(request, arguments), "Create your own centerprint sent to yourself") \
327         CLIENT_COMMAND("mv_download", LocalCommand_mv_download(request, arguments), "Retrieve mapshot picture from the server") \
328         CLIENT_COMMAND("sendcvar", LocalCommand_sendcvar(request, arguments), "Send a cvar to the server (like weaponpriority)") \
329         CLIENT_COMMAND("vyes", LocalCommand_handlevote(request, tokenize_console("handlevote yes")), "") \
330         CLIENT_COMMAND("vno", LocalCommand_handlevote(request, tokenize_console("handlevote no")), "") \
331         /* nothing */
332         
333 void LocalCommand_macro_help()
334 {
335         #define CLIENT_COMMAND(name,function,description) \
336                 { if(strtolower(description) != "") { print("  ^2", name, "^7: ", description, "\n"); } }
337                 
338         CLIENT_COMMANDS(0, 0)
339         #undef CLIENT_COMMAND
340         
341         return;
342 }
343
344 float LocalCommand_macro_command(float argc)
345 {
346         #define CLIENT_COMMAND(name,function,description) \
347                 { if(name == strtolower(argv(0))) { function; return TRUE; } }
348                 
349         CLIENT_COMMANDS(CMD_REQUEST_COMMAND, argc)
350         #undef CLIENT_COMMAND
351         
352         return FALSE;
353 }
354
355 float LocalCommand_macro_usage(float argc)
356 {
357         #define CLIENT_COMMAND(name,function,description) \
358                 { if(name == strtolower(argv(1))) { function; return TRUE; } }
359                 
360         CLIENT_COMMANDS(CMD_REQUEST_USAGE, argc)
361         #undef CLIENT_COMMAND
362         
363         return FALSE;
364 }
365
366 void LocalCommand_macro_write_aliases(float fh)
367 {
368         #define CLIENT_COMMAND(name,function,description) \
369                 { if(strtolower(description) != "") { CMD_Write_Alias("qc_cmd_cl", name, description); } }
370                 
371         CLIENT_COMMANDS(0, 0)
372         #undef CLIENT_COMMAND
373         
374         return;
375 }
376
377
378 // =========================================
379 //  Main Function Called By Engine (cl_cmd)
380 // =========================================
381 // If this function exists, client code handles gamecommand instead of the engine code.
382
383 void GameCommand(string command)
384 {
385         float argc = tokenize_console(command);
386
387         // Guide for working with argc arguments by example:
388         // argc:   1    - 2      - 3     - 4
389         // argv:   0    - 1      - 2     - 3 
390         // cmd     vote - master - login - password
391
392         if(strtolower(argv(0)) == "help") 
393         {
394                 if(argc == 1) 
395                 {
396                         print("\nClient console commands:\n");
397                         LocalCommand_macro_help();
398
399                         print("\nGeneric commands shared by all programs:\n");
400                         GenericCommand_macro_help();
401                         
402                         print("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are listed above.\n");
403                         print("For help about a specific command, type cl_cmd help COMMAND\n");
404                         
405                         return;
406                 } 
407                 else if(GenericCommand_macro_usage(argc)) // Instead of trying to call a command, we're going to see detailed information about it
408                 {
409                         return;
410                 }
411                 else if(LocalCommand_macro_usage(argc)) // now try for normal commands too
412                 {
413                         return;
414                 }
415         } 
416         else if(GenericCommand(command)) 
417         {
418                 return; // handled by common/command/generic.qc
419         }
420         else if(LocalCommand_macro_command(argc)) // continue as usual and scan for normal commands
421         {
422                 return; // handled by one of the above LocalCommand_* functions
423         }
424         
425         // nothing above caught the command, must be invalid
426         print(((command != "") ? strcat("Unknown client command \"", command, "\"") : "No command provided"), ". For a list of supported commands, try cl_cmd help.\n");
427         
428         return;
429 }
430
431
432 // ===================================
433 //  Macro system for console commands
434 // ===================================
435
436 // These functions are here specifically to add special + - commands to the game, and are not really normal commands.
437 // Please add client commands to the function above this, as this is only for special reasons.
438 #define CONSOLE_COMMANDS_NORMAL \
439         CONSOLE_COMMAND("+showscores", { scoreboard_showscores = TRUE; }) \
440         CONSOLE_COMMAND("-showscores", { scoreboard_showscores = FALSE; }) \
441         CONSOLE_COMMAND("+showaccuracy", { scoreboard_showaccuracy = TRUE; }) \
442         CONSOLE_COMMAND("-showaccuracy", { scoreboard_showaccuracy = FALSE; }) \
443         /* nothing */
444         
445 #define CONSOLE_COMMANDS_MOVEMENT \
446         CONSOLE_COMMAND("+forward", { ++camera_direction_x; }) \
447         CONSOLE_COMMAND("-forward", { --camera_direction_x; }) \
448         CONSOLE_COMMAND("+back", { --camera_direction_x; }) \
449         CONSOLE_COMMAND("-back", { ++camera_direction_x; }) \
450         CONSOLE_COMMAND("+moveup", { ++camera_direction_z; }) \
451         CONSOLE_COMMAND("-moveup", { --camera_direction_z; }) \
452         CONSOLE_COMMAND("+movedown", { --camera_direction_z; }) \
453         CONSOLE_COMMAND("-movedown", { ++camera_direction_z; }) \
454         CONSOLE_COMMAND("+moveright", { --camera_direction_y; }) \
455         CONSOLE_COMMAND("-moveright", { ++camera_direction_y; }) \
456         CONSOLE_COMMAND("+moveleft", { ++camera_direction_y; }) \
457         CONSOLE_COMMAND("-moveleft", { --camera_direction_y; }) \
458         CONSOLE_COMMAND("+roll_right", { ++camera_roll; }) \
459         CONSOLE_COMMAND("-roll_right", { --camera_roll; }) \
460         CONSOLE_COMMAND("+roll_left", { --camera_roll; }) \
461         CONSOLE_COMMAND("-roll_left", { ++camera_roll; }) \
462         /* nothing */
463
464 void ConsoleCommand_macro_init()
465 {
466         // first init normal commands
467         #define CONSOLE_COMMAND(name,execution) \
468                 { registercommand(name); }
469
470         CONSOLE_COMMANDS_NORMAL
471         #undef CONSOLE_COMMAND
472         
473         // then init movement commands
474         #ifndef CAMERATEST
475         if(isdemo())
476         {
477         #endif
478                 #define CONSOLE_COMMAND(name,execution) \
479                         { registercommand(name); }
480
481                 CONSOLE_COMMANDS_MOVEMENT
482                 #undef CONSOLE_COMMAND
483         #ifndef CAMERATEST
484         }
485         #endif
486         
487         return;
488 }
489
490 float ConsoleCommand_macro_normal(float argc)
491 {
492         #define CONSOLE_COMMAND(name,execution) \
493                 { if(name == strtolower(argv(0))) { { execution } return TRUE; } }
494                 
495         CONSOLE_COMMANDS_NORMAL
496         #undef CONSOLE_COMMAND
497         
498         return FALSE;
499 }
500
501 float ConsoleCommand_macro_movement(float argc)
502 {
503         if(camera_active)
504         {
505                 #define CONSOLE_COMMAND(name,execution) \
506                         { if(name == strtolower(argv(0))) { { execution } return TRUE; } }
507
508                 CONSOLE_COMMANDS_MOVEMENT
509                 #undef CONSOLE_COMMAND
510         }
511         
512         return FALSE;
513 }
514
515
516 // ======================================================
517 //  Main Function Called By Engine (registered commands)
518 // ======================================================
519 // Used to parse commands in the console that have been registered with the "registercommand" function
520
521 float CSQC_ConsoleCommand(string command)
522 {
523         float argc = tokenize_console(command);
524
525         if(ConsoleCommand_macro_normal(argc))
526         {
527                 return TRUE;
528         }
529         else if(ConsoleCommand_macro_movement(argc))
530         {
531                 return TRUE;
532         }
533         
534         // Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it.
535
536         return FALSE;
537 }