]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/gamecommand.qc
ANOTHER bug fixed
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / gamecommand.qc
1 // ==============================================
2 //  CSQC client commands code, written by Samual
3 //  Last updated: November 8th, 2011
4 // ==============================================
5
6         /*
7         if(cmd == "mv_download") {
8                 Cmd_MapVote_MapDownload(argc);
9         }
10         else if(cmd == "settemp") {
11                 cvar_clientsettemp(argv(1), argv(2));
12         }
13         else if(cmd == "scoreboard_columns_set") {
14                 Cmd_HUD_SetFields(argc);
15         }
16         else if(cmd == "scoreboard_columns_help") {
17                 Cmd_HUD_Help(argc);
18         }
19         else if(cmd == "spawn") {
20                 s = argv(1);
21                 e = spawn();
22                 precache_model(s);
23                 setmodel(e, s);
24                 setorigin(e, view_origin);
25                 e.angles = view_angles;
26                 e.draw = DrawDebugModel;
27                 e.classname = "debugmodel";
28         }
29     else if(cmd == "vyes")
30     {
31         if(uid2name_dialog)
32         {
33             vote_active = 0; // force the panel to disappear right as we have selected the value (to prevent it from fading out in the normal vote panel pos)
34             vote_prev = 0;
35             localcmd("setreport cl_allow_uid2name 1\n");
36             vote_change = -9999;
37                         uid2name_dialog = 0;
38         }
39         else
40         {
41             localcmd("cmd vote yes\n");
42         }
43     }
44     else if(cmd == "vno")
45     {
46         if(uid2name_dialog)
47         {
48             vote_active = 0;
49             vote_prev = 0;
50             localcmd("setreport cl_allow_uid2name 0\n");
51             vote_change = -9999;
52                         uid2name_dialog = 0;
53         }
54         else
55         {
56             localcmd("cmd vote no\n");
57         }
58     }
59         */
60
61
62 #define GC_REQUEST_COMMAND 1
63 #define GC_REQUEST_USAGE 2
64
65 void Cmd_HUD_SetFields(float);
66 void Cmd_HUD_Help(float);
67
68 .vector view_ofs;
69 entity debug_shotorg;
70
71
72 // ============================
73 //  Misc. Supporting Functions
74 // ============================
75
76 float cvar_clientsettemp(string tmp_cvar, string value)
77 {
78         entity e;
79         
80         for(e = world; (e = find(e, classname, "saved_cvar_value")); )
81                 if(e.netname == tmp_cvar)
82                         goto saved;
83                         
84         // creating a new entity to keep track of this cvar
85         e = spawn();
86         e.classname = "saved_cvar_value";
87         e.netname = strzone(tmp_cvar);
88         e.message = strzone(cvar_string(tmp_cvar));
89         return TRUE;
90         
91         // an entity for this cvar already exists, update the value
92         :saved
93         cvar_set(tmp_cvar, value);
94         return FALSE;
95 }
96
97 float cvar_clientsettemp_restore()
98 {
99         float i;
100         entity e;
101         
102         for(e = world; (e = find(e, classname, "saved_cvar_value")); )
103                 { cvar_set(e.netname, e.message); ++i; } 
104                 
105         return i;
106 }
107 void DrawDebugModel()
108 {
109         if(time - floor(time) > 0.5)
110         {
111                 PolyDrawModel(self);
112                 self.drawmask = 0;
113         }
114         else
115         {
116                 self.renderflags = 0;
117                 self.drawmask = MASK_NORMAL;
118         }
119 }
120
121
122 // =======================
123 //  Command Sub-Functions
124 // =======================
125
126 void GameCommand_blurtest(float request)
127 {
128         // Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now...
129         // Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command.
130         
131         #ifdef BLURTEST
132         switch(request)
133         {
134                 case GC_REQUEST_COMMAND:
135                 {
136                         blurtest_time0 = time;
137                         blurtest_time1 = time + stof(argv(1));
138                         blurtest_radius = stof(argv(2));
139                         blurtest_power = stof(argv(3));
140                         print("Enabled blurtest\n");
141                         return; 
142                 }
143                         
144                 default:
145                 case GC_REQUEST_USAGE:
146                 {
147                         print("\nUsage:^3 cl_cmd blurtest\n");
148                         print("  No arguments required.\n");
149                         return;
150                 }
151         }
152         #else
153         if(request)
154         {
155                 print("Blurtest is not enabled on this client.\n");
156                 return;
157         }
158         #endif
159 }
160
161 void GameCommand_hud(float request, float argc) // TODO: Add aliases in commands.cfg
162 {
163         switch(request)
164         {
165                 case GC_REQUEST_COMMAND:
166                 {
167                         switch(argv(1))
168                         {
169                                 case "configure":
170                                 {
171                                         cvar_set("_hud_configure", ftos(!autocvar__hud_configure));
172                                         return;
173                                 }
174                                 
175                                 case "save":
176                                 {
177                                         if(argv(2))
178                                         {
179                                                 HUD_Panel_ExportCfg(argv(2));
180                                                 return;
181                                         }
182                                         else
183                                         {
184                                                 break; // go to usage, we're missing the paramater needed here.
185                                         }
186                                 }
187                                 
188                                 case "radar":
189                                 {
190                                         if(argv(2))
191                                                 hud_panel_radar_maximized = (stof(argv(2)) != 0);
192                                         else
193                                                 hud_panel_radar_maximized = !hud_panel_radar_maximized;
194                                         
195                                         return;
196                                 }
197                         }
198                         return; 
199                 }
200                         
201                 default:
202                         print("Incorrect parameters for ^2hud^7\n");
203                 case GC_REQUEST_USAGE:
204                 {
205                         print("\nUsage:^3 cl_cmd hud action [configname | radartoggle]\n");
206                         print("  Where 'action' is the command to complete,\n");
207                         print("  'configname' is the name to save to for \"save\" action,\n");
208                         print("  and 'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action.\n");
209                         print("  Full list of commands here: \"configure, save, radar.\"\n");
210                         return;
211                 }
212         }
213 }
214
215 void GameCommand_sendcvar(float request, float argc)
216 {
217         switch(request)
218         {
219                 case GC_REQUEST_COMMAND:
220                 {
221                         // W_FixWeaponOrder will trash argv, so save what we need.
222                         string thiscvar = strzone(argv(1));
223                         string s = cvar_string(thiscvar);
224                         
225                         if(thiscvar == "cl_weaponpriority")
226                                 s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1);
227                         else if(substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18)
228                                 s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0);
229                                 
230                         localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n");
231                         strunzone(thiscvar);
232                         
233                         return; 
234                 }
235                         
236                 default:
237                 case GC_REQUEST_USAGE:
238                 {
239                         print("\nUsage:^3 cl_cmd sendcvar <cvar>\n");
240                         print("  Where 'cvar' is the cvar plus arguments to send to the server.\n");
241                         return;
242                 }
243         }
244 }
245
246 void GameCommand_settemp(float request, float argc)
247 {
248         switch(request)
249         {
250                 case GC_REQUEST_COMMAND:
251                 {
252                         
253                         return; 
254                 }
255                         
256                 default:
257                 case GC_REQUEST_USAGE:
258                 {
259                         print("\nUsage:^3 cl_cmd \n");
260                         print("  No arguments required.\n");
261                         return;
262                 }
263         }
264 }
265
266 /* use this when creating a new command, making sure to place it in alphabetical order.
267 void GameCommand_(float request)
268 {
269         switch(request)
270         {
271                 case GC_REQUEST_COMMAND:
272                 {
273                         
274                         return; 
275                 }
276                         
277                 default:
278                 case GC_REQUEST_USAGE:
279                 {
280                         print("\nUsage:^3 cl_cmd \n");
281                         print("  No arguments required.\n");
282                         return;
283                 }
284         }
285 }
286 */
287
288
289 // ==================================
290 //  Macro system for client commands
291 // ==================================
292
293 // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
294 #define CLIENT_COMMANDS(request,arguments) \
295         CLIENT_COMMAND("blurtest", GameCommand_blurtest(request), "Feature for testing blur postprocessing") \
296         CLIENT_COMMAND("hud", GameCommand_hud(request, arguments), "Commands regarding/controlling the HUD system") \
297         CLIENT_COMMAND("sendcvar", GameCommand_sendcvar(request, arguments), "Send a cvar to the server (like weaponpriority)") \
298         CLIENT_COMMAND("settemp", GameCommand_settemp(request, arguments), "Temporarily set a value to a cvar which will be cleared next match") \
299         /* nothing */
300         
301 void GameCommand_macro_help()
302 {
303         #define CLIENT_COMMAND(name,function,description) \
304                 { print("  ^2", name, "^7: ", description, "\n"); }
305                 
306         CLIENT_COMMANDS(0, 0)
307         #undef CLIENT_COMMAND
308         
309         return;
310 }
311
312 float GameCommand_macro_command(float argc)
313 {
314         #define CLIENT_COMMAND(name,function,description) \
315                 { if(name == strtolower(argv(0))) { function; return TRUE; } }
316                 
317         CLIENT_COMMANDS(GC_REQUEST_COMMAND, argc)
318         #undef CLIENT_COMMAND
319         
320         return FALSE;
321 }
322
323 float GameCommand_macro_usage(float argc)
324 {
325         #define CLIENT_COMMAND(name,function,description) \
326                 { if(name == strtolower(argv(1))) { function; return TRUE; } }
327                 
328         CLIENT_COMMANDS(GC_REQUEST_USAGE, argc)
329         #undef CLIENT_COMMAND
330         
331         return FALSE;
332 }
333
334
335 // =========================================
336 //  Main Function Called By Engine (cl_cmd)
337 // =========================================
338 // If this function exists, client code handles gamecommand instead of the engine code.
339
340 void GameCommand(string command)
341 {
342         float argc = tokenize_console(command);
343
344         if(strtolower(argv(0)) == "help") 
345         {
346                 if(argc == 1) 
347                 {
348                         print("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are:\n");
349                         GameCommand_macro_help();
350                         GameCommand_Generic("help");
351                         print("For help about specific commands, type cl_cmd help COMMAND\n");
352                         return;
353                 } 
354                 else if(GameCommand_macro_usage(argc)) // Instead of trying to call a command, we're going to see detailed information about it
355                 {
356                         return;
357                 }
358         } 
359         else if(GameCommand_Generic(command)) 
360         {
361                 return; // handled by common/gamecommand.qc
362         }
363         else if(GameCommand_macro_command(argc)) // continue as usual and scan for normal commands
364         {
365                 return; // handled by one of the above GameCommand_* functions
366         }
367         
368         // nothing above caught the command, must be invalid
369         print("Unknown client command", ((command != "") ? strcat(" \"", command, "\"") : ""), ". For a list of supported commands, try cl_cmd help.\n");
370         
371         return;
372 }
373
374
375 // ===================================
376 //  Macro system for console commands
377 // ===================================
378
379 // These functions are here specifically to add special + - commands to the game, and are not really normal commands.
380 // Please add client commands to the function above this, as this is only for special reasons.
381 #define CONSOLE_COMMANDS_NORMAL \
382         CONSOLE_COMMAND("+showscores", { scoreboard_showscores = TRUE; }) \
383         CONSOLE_COMMAND("-showscores", { scoreboard_showscores = FALSE; }) \
384         CONSOLE_COMMAND("+showaccuracy", { scoreboard_showaccuracy = TRUE; }) \
385         CONSOLE_COMMAND("-showaccuracy", { scoreboard_showaccuracy = FALSE; }) \
386         /* nothing */
387         
388 #define CONSOLE_COMMANDS_MOVEMENT \
389         CONSOLE_COMMAND("+forward", { ++camera_direction_x; }) \
390         CONSOLE_COMMAND("-forward", { --camera_direction_x; }) \
391         CONSOLE_COMMAND("+back", { --camera_direction_x; }) \
392         CONSOLE_COMMAND("-back", { ++camera_direction_x; }) \
393         CONSOLE_COMMAND("+moveup", { ++camera_direction_z; }) \
394         CONSOLE_COMMAND("-moveup", { --camera_direction_z; }) \
395         CONSOLE_COMMAND("+movedown", { --camera_direction_z; }) \
396         CONSOLE_COMMAND("-movedown", { ++camera_direction_z; }) \
397         CONSOLE_COMMAND("+moveright", { --camera_direction_y; }) \
398         CONSOLE_COMMAND("-moveright", { ++camera_direction_y; }) \
399         CONSOLE_COMMAND("+moveleft", { ++camera_direction_y; }) \
400         CONSOLE_COMMAND("-moveleft", { --camera_direction_y; }) \
401         CONSOLE_COMMAND("+roll_right", { ++camera_roll; }) \
402         CONSOLE_COMMAND("-roll_right", { --camera_roll; }) \
403         CONSOLE_COMMAND("+roll_left", { --camera_roll; }) \
404         CONSOLE_COMMAND("-roll_left", { ++camera_roll; }) \
405         /* nothing */
406
407 void ConsoleCommand_macro_init()
408 {
409         // first init normal commands
410         #define CONSOLE_COMMAND(name,execution) \
411                 { registercmd(name); }
412
413         CONSOLE_COMMANDS_NORMAL
414         #undef CONSOLE_COMMAND
415         
416         // then init movement commands
417         #ifndef CAMERATEST
418         if(isdemo())
419         {
420         #endif
421                 #define CONSOLE_COMMAND(name,execution) \
422                         { registercmd(name); }
423
424                 CONSOLE_COMMANDS_MOVEMENT
425                 #undef CONSOLE_COMMAND
426         #ifndef CAMERATEST
427         }
428         #endif
429         
430         return;
431 }
432
433 float ConsoleCommand_macro_normal(float argc)
434 {
435         #define CONSOLE_COMMAND(name,execution) \
436                 { if(name == strtolower(argv(0))) { { execution } return TRUE; } }
437                 
438         CONSOLE_COMMANDS_NORMAL
439         #undef CONSOLE_COMMAND
440         
441         return FALSE;
442 }
443
444 float ConsoleCommand_macro_movement(float argc)
445 {
446         if(camera_active)
447         {
448                 #define CONSOLE_COMMAND(name,execution) \
449                         { if(name == strtolower(argv(0))) { { execution } return TRUE; } }
450
451                 CONSOLE_COMMANDS_MOVEMENT
452                 #undef CONSOLE_COMMAND
453         }
454         
455         return FALSE;
456 }
457
458
459 // ======================================================
460 //  Main Function Called By Engine (registered commands)
461 // ======================================================
462 // Used to parse commands in the console that have been registered with the "registercmd" function
463
464 float CSQC_ConsoleCommand(string command)
465 {
466         float argc = tokenize_console(command);
467
468         if(ConsoleCommand_macro_normal(argc))
469         {
470                 return TRUE;
471         }
472         else if(ConsoleCommand_macro_movement(argc))
473         {
474                 return TRUE;
475         }
476         
477         // Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it.
478
479         return FALSE;
480 }