]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/command/cl_cmd.qc
Merge branch 'master' of git://de.git.xonotic.org/xonotic/xonotic-data.pk3dir
[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 "save":
152                                 {
153                                         if(argv(2))
154                                         {
155                                                 HUD_Panel_ExportCfg(argv(2));
156                                                 return;
157                                         }
158                                         else
159                                         {
160                                                 break; // go to usage, we're missing the paramater needed here.
161                                         }
162                                 }
163                                 
164                                 case "scoreboard_columns_set":
165                                 {
166                                         Cmd_HUD_SetFields(argc); 
167                                         return;
168                                 }
169
170                                 case "scoreboard_columns_help":
171                                 {
172                                         Cmd_HUD_Help();
173                                         return;
174                                 }
175                                 
176                                 case "radar":
177                                 {
178                                         hud_panel_radar_maximized = (argv(2) ? InterpretBoolean(argv(2)) : !hud_panel_radar_maximized);
179                                         return;
180                                 }
181                         }
182                 }
183                         
184                 default:
185                         print("Incorrect parameters for ^2hud^7\n");
186                 case CMD_REQUEST_USAGE:
187                 {
188                         print("\nUsage:^3 cl_cmd hud action [configname | radartoggle | layout]\n");
189                         print("  Where 'action' is the command to complete,\n");
190                         print("  'configname' is the name to save to for \"save\" action,\n");
191                         print("  'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action,\n");
192                         print("  and 'layout' is how to organize the scoreboard columns for the set action.\n");
193                         print("  Full list of commands here: \"configure, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"\n");
194                         return;
195                 }
196         }
197 }
198
199 void LocalCommand_localprint(float request, float argc)
200 {
201         switch(request)
202         {
203                 case CMD_REQUEST_COMMAND:
204                 {
205                         if(argv(1))
206                         {
207                                 centerprint_hud(argv(1));
208                                 return; 
209                         }
210                 }
211                         
212                 default:
213                         print("Incorrect parameters for ^2localprint^7\n");
214                 case CMD_REQUEST_USAGE:
215                 {
216                         print("\nUsage:^3 cl_cmd localprint \"message\"\n");
217                         print("  'message' is the centerprint message to send to yourself.\n");
218                         return;
219                 }
220         }
221 }
222
223 void LocalCommand_mv_download(float request, float argc)
224 {
225         switch(request)
226         {
227                 case CMD_REQUEST_COMMAND:
228                 {
229                         if(argv(1))
230                         {
231                                 Cmd_MapVote_MapDownload(argc);
232                                 return; 
233                         }
234                 }
235                         
236                 default:
237                         print("Incorrect parameters for ^2mv_download^7\n");
238                 case CMD_REQUEST_USAGE:
239                 {
240                         print("\nUsage:^3 cl_cmd mv_download mapid\n");
241                         print("  Where 'mapid' is the id number of the map to request an image of on the map vote selection menu.\n");
242                         return;
243                 }
244         }
245 }
246
247 void LocalCommand_sendcvar(float request, float argc)
248 {
249         switch(request)
250         {
251                 case CMD_REQUEST_COMMAND:
252                 {
253                         if(argv(1))
254                         {
255                                 // W_FixWeaponOrder will trash argv, so save what we need.
256                                 string thiscvar = strzone(argv(1));
257                                 string s = cvar_string(thiscvar);
258                                 
259                                 if(thiscvar == "cl_weaponpriority")
260                                         s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1);
261                                 else if(substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18)
262                                         s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0);
263                                         
264                                 localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n");
265                                 strunzone(thiscvar);
266                                 return; 
267                         }
268                 }
269                         
270                 default:
271                         print("Incorrect parameters for ^2sendcvar^7\n");
272                 case CMD_REQUEST_USAGE:
273                 {
274                         print("\nUsage:^3 cl_cmd sendcvar <cvar>\n");
275                         print("  Where 'cvar' is the cvar plus arguments to send to the server.\n");
276                         return;
277                 }
278         }
279 }
280
281 /* use this when creating a new command, making sure to place it in alphabetical order... also,
282 ** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
283 void LocalCommand_(float request)
284 {
285         switch(request)
286         {
287                 case CMD_REQUEST_COMMAND:
288                 {
289                         
290                         return; 
291                 }
292                         
293                 default:
294                 case CMD_REQUEST_USAGE:
295                 {
296                         print("\nUsage:^3 cl_cmd \n");
297                         print("  No arguments required.\n");
298                         return;
299                 }
300         }
301 }
302 */
303
304
305 // ==================================
306 //  Macro system for client commands
307 // ==================================
308
309 // Normally do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
310 // but for 0.5 compat, we need vyes and vno here as they were replaced... REMOVE THEM AFTER 0.6 RELEASE!!!!
311 #define CLIENT_COMMANDS(request,arguments) \
312         CLIENT_COMMAND("blurtest", LocalCommand_blurtest(request), "Feature for testing blur postprocessing") \
313         CLIENT_COMMAND("debugmodel", LocalCommand_debugmodel(request, arguments), "Spawn a debug model manually") \
314         CLIENT_COMMAND("handlevote", LocalCommand_handlevote(request, arguments), "System to handle selecting a vote or option") \
315         CLIENT_COMMAND("hud", LocalCommand_hud(request, arguments), "Commands regarding/controlling the HUD system") \
316         CLIENT_COMMAND("localprint", LocalCommand_localprint(request, arguments), "Create your own centerprint sent to yourself") \
317         CLIENT_COMMAND("mv_download", LocalCommand_mv_download(request, arguments), "Retrieve mapshot picture from the server") \
318         CLIENT_COMMAND("sendcvar", LocalCommand_sendcvar(request, arguments), "Send a cvar to the server (like weaponpriority)") \
319         CLIENT_COMMAND("vyes", LocalCommand_handlevote(request, tokenize_console("handlevote yes")), "") \
320         CLIENT_COMMAND("vno", LocalCommand_handlevote(request, tokenize_console("handlevote no")), "") \
321         /* nothing */
322         
323 void LocalCommand_macro_help()
324 {
325         #define CLIENT_COMMAND(name,function,description) \
326                 { if(strtolower(description) != "") { print("  ^2", name, "^7: ", description, "\n"); } }
327                 
328         CLIENT_COMMANDS(0, 0)
329         #undef CLIENT_COMMAND
330         
331         return;
332 }
333
334 float LocalCommand_macro_command(float argc)
335 {
336         #define CLIENT_COMMAND(name,function,description) \
337                 { if(name == strtolower(argv(0))) { function; return TRUE; } }
338                 
339         CLIENT_COMMANDS(CMD_REQUEST_COMMAND, argc)
340         #undef CLIENT_COMMAND
341         
342         return FALSE;
343 }
344
345 float LocalCommand_macro_usage(float argc)
346 {
347         #define CLIENT_COMMAND(name,function,description) \
348                 { if(name == strtolower(argv(1))) { function; return TRUE; } }
349                 
350         CLIENT_COMMANDS(CMD_REQUEST_USAGE, argc)
351         #undef CLIENT_COMMAND
352         
353         return FALSE;
354 }
355
356 void LocalCommand_macro_write_aliases(float fh)
357 {
358         #define CLIENT_COMMAND(name,function,description) \
359                 { if(strtolower(description) != "") { CMD_Write_Alias("qc_cmd_cl", name, description); } }
360                 
361         CLIENT_COMMANDS(0, 0)
362         #undef CLIENT_COMMAND
363         
364         return;
365 }
366
367
368 // =========================================
369 //  Main Function Called By Engine (cl_cmd)
370 // =========================================
371 // If this function exists, client code handles gamecommand instead of the engine code.
372
373 void GameCommand(string command)
374 {
375         float argc = tokenize_console(command);
376
377         // Guide for working with argc arguments by example:
378         // argc:   1    - 2      - 3     - 4
379         // argv:   0    - 1      - 2     - 3 
380         // cmd     vote - master - login - password
381
382         if(strtolower(argv(0)) == "help") 
383         {
384                 if(argc == 1) 
385                 {
386                         print("\nClient console commands:\n");
387                         LocalCommand_macro_help();
388
389                         print("\nGeneric commands shared by all programs:\n");
390                         GenericCommand_macro_help();
391                         
392                         print("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are listed above.\n");
393                         print("For help about a specific command, type cl_cmd help COMMAND\n");
394                         
395                         return;
396                 } 
397                 else if(GenericCommand_macro_usage(argc)) // Instead of trying to call a command, we're going to see detailed information about it
398                 {
399                         return;
400                 }
401                 else if(LocalCommand_macro_usage(argc)) // now try for normal commands too
402                 {
403                         return;
404                 }
405         } 
406         else if(GenericCommand(command)) 
407         {
408                 return; // handled by common/command/generic.qc
409         }
410         else if(LocalCommand_macro_command(argc)) // continue as usual and scan for normal commands
411         {
412                 return; // handled by one of the above LocalCommand_* functions
413         }
414         
415         // nothing above caught the command, must be invalid
416         print(((command != "") ? strcat("Unknown client command \"", command, "\"") : "No command provided"), ". For a list of supported commands, try cl_cmd help.\n");
417         
418         return;
419 }
420
421
422 // ===================================
423 //  Macro system for console commands
424 // ===================================
425
426 // These functions are here specifically to add special + - commands to the game, and are not really normal commands.
427 // Please add client commands to the function above this, as this is only for special reasons.
428 #define CONSOLE_COMMANDS_NORMAL \
429         CONSOLE_COMMAND("+showscores", { scoreboard_showscores = TRUE; }) \
430         CONSOLE_COMMAND("-showscores", { scoreboard_showscores = FALSE; }) \
431         CONSOLE_COMMAND("+showaccuracy", { scoreboard_showaccuracy = TRUE; }) \
432         CONSOLE_COMMAND("-showaccuracy", { scoreboard_showaccuracy = FALSE; }) \
433         /* nothing */
434         
435 #define CONSOLE_COMMANDS_MOVEMENT \
436         CONSOLE_COMMAND("+forward", { ++camera_direction_x; }) \
437         CONSOLE_COMMAND("-forward", { --camera_direction_x; }) \
438         CONSOLE_COMMAND("+back", { --camera_direction_x; }) \
439         CONSOLE_COMMAND("-back", { ++camera_direction_x; }) \
440         CONSOLE_COMMAND("+moveup", { ++camera_direction_z; }) \
441         CONSOLE_COMMAND("-moveup", { --camera_direction_z; }) \
442         CONSOLE_COMMAND("+movedown", { --camera_direction_z; }) \
443         CONSOLE_COMMAND("-movedown", { ++camera_direction_z; }) \
444         CONSOLE_COMMAND("+moveright", { --camera_direction_y; }) \
445         CONSOLE_COMMAND("-moveright", { ++camera_direction_y; }) \
446         CONSOLE_COMMAND("+moveleft", { ++camera_direction_y; }) \
447         CONSOLE_COMMAND("-moveleft", { --camera_direction_y; }) \
448         CONSOLE_COMMAND("+roll_right", { ++camera_roll; }) \
449         CONSOLE_COMMAND("-roll_right", { --camera_roll; }) \
450         CONSOLE_COMMAND("+roll_left", { --camera_roll; }) \
451         CONSOLE_COMMAND("-roll_left", { ++camera_roll; }) \
452         /* nothing */
453
454 void ConsoleCommand_macro_init()
455 {
456         // first init normal commands
457         #define CONSOLE_COMMAND(name,execution) \
458                 { registercommand(name); }
459
460         CONSOLE_COMMANDS_NORMAL
461         #undef CONSOLE_COMMAND
462         
463         // then init movement commands
464         #ifndef CAMERATEST
465         if(isdemo())
466         {
467         #endif
468                 #define CONSOLE_COMMAND(name,execution) \
469                         { registercommand(name); }
470
471                 CONSOLE_COMMANDS_MOVEMENT
472                 #undef CONSOLE_COMMAND
473         #ifndef CAMERATEST
474         }
475         #endif
476         
477         return;
478 }
479
480 float ConsoleCommand_macro_normal(float argc)
481 {
482         #define CONSOLE_COMMAND(name,execution) \
483                 { if(name == strtolower(argv(0))) { { execution } return TRUE; } }
484                 
485         CONSOLE_COMMANDS_NORMAL
486         #undef CONSOLE_COMMAND
487         
488         return FALSE;
489 }
490
491 float ConsoleCommand_macro_movement(float argc)
492 {
493         if(camera_active)
494         {
495                 #define CONSOLE_COMMAND(name,execution) \
496                         { if(name == strtolower(argv(0))) { { execution } return TRUE; } }
497
498                 CONSOLE_COMMANDS_MOVEMENT
499                 #undef CONSOLE_COMMAND
500         }
501         
502         return FALSE;
503 }
504
505
506 // ======================================================
507 //  Main Function Called By Engine (registered commands)
508 // ======================================================
509 // Used to parse commands in the console that have been registered with the "registercommand" function
510
511 float CSQC_ConsoleCommand(string command)
512 {
513         float argc = tokenize_console(command);
514
515         if(ConsoleCommand_macro_normal(argc))
516         {
517                 return TRUE;
518         }
519         else if(ConsoleCommand_macro_movement(argc))
520         {
521                 return TRUE;
522         }
523         
524         // Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it.
525
526         return FALSE;
527 }