From: Samual Date: Tue, 13 Dec 2011 09:15:18 +0000 (-0500) Subject: Also move all of the other game command files from other programs into their respecti... X-Git-Tag: xonotic-v0.6.0~188^2~28^2~152 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=9c26f61b3d9a3341032455833f6b03228ac94077;p=xonotic%2Fxonotic-data.pk3dir.git Also move all of the other game command files from other programs into their respective command/ folder --- diff --git a/qcsrc/client/command/cl_cmd.qc b/qcsrc/client/command/cl_cmd.qc new file mode 100644 index 000000000..a15626a71 --- /dev/null +++ b/qcsrc/client/command/cl_cmd.qc @@ -0,0 +1,471 @@ +// ============================================== +// CSQC client commands code, written by Samual +// Last updated: November 26th, 2011 +// ============================================== + + /* + if(cmd == "mv_download") { + Cmd_MapVote_MapDownload(argc); + } + else if(cmd == "scoreboard_columns_set") { + Cmd_HUD_SetFields(argc); + } + else if(cmd == "scoreboard_columns_help") { + Cmd_HUD_Help(argc); + } + else if(cmd == "spawn") { + s = argv(1); + e = spawn(); + precache_model(s); + setmodel(e, s); + setorigin(e, view_origin); + e.angles = view_angles; + e.draw = DrawDebugModel; + e.classname = "debugmodel"; + } + else if(cmd == "vyes") + { + if(uid2name_dialog) + { + 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) + vote_prev = 0; + localcmd("setreport cl_allow_uid2name 1\n"); + vote_change = -9999; + uid2name_dialog = 0; + } + else + { + localcmd("cmd vote yes\n"); + } + } + else if(cmd == "vno") + { + if(uid2name_dialog) + { + vote_active = 0; + vote_prev = 0; + localcmd("setreport cl_allow_uid2name 0\n"); + vote_change = -9999; + uid2name_dialog = 0; + } + else + { + localcmd("cmd vote no\n"); + } + } + */ + + +#define GC_REQUEST_COMMAND 1 +#define GC_REQUEST_USAGE 2 + +void Cmd_HUD_SetFields(float); +void Cmd_HUD_Help(float); + +.vector view_ofs; +entity debug_shotorg; + + +// ============================ +// Misc. Supporting Functions +// ============================ + +float cvar_clientsettemp(string tmp_cvar, string value) +{ + entity e; + + for(e = world; (e = find(e, classname, "saved_cvar_value")); ) + if(e.netname == tmp_cvar) + goto saved; + + // creating a new entity to keep track of this cvar + e = spawn(); + e.classname = "saved_cvar_value"; + e.netname = strzone(tmp_cvar); + e.message = strzone(cvar_string(tmp_cvar)); + return TRUE; + + // an entity for this cvar already exists, update the value + :saved + cvar_set(tmp_cvar, value); + return FALSE; +} + +float cvar_clientsettemp_restore() +{ + float i; + entity e; + + for(e = world; (e = find(e, classname, "saved_cvar_value")); ) + { cvar_set(e.netname, e.message); ++i; } + + return i; +} + +void DrawDebugModel() +{ + if(time - floor(time) > 0.5) + { + PolyDrawModel(self); + self.drawmask = 0; + } + else + { + self.renderflags = 0; + self.drawmask = MASK_NORMAL; + } +} + + +// ======================= +// Command Sub-Functions +// ======================= + +void GameCommand_blurtest(float request) +{ + // Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now... + // Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command. + + #ifdef BLURTEST + switch(request) + { + case GC_REQUEST_COMMAND: + { + blurtest_time0 = time; + blurtest_time1 = time + stof(argv(1)); + blurtest_radius = stof(argv(2)); + blurtest_power = stof(argv(3)); + print("Enabled blurtest\n"); + return; + } + + default: + case GC_REQUEST_USAGE: + { + print("\nUsage:^3 cl_cmd blurtest\n"); + print(" No arguments required.\n"); + return; + } + } + #else + if(request) + { + print("Blurtest is not enabled on this client.\n"); + return; + } + #endif +} + +void GameCommand_hud(float request, float argc) // TODO: Add aliases in commands.cfg +{ + switch(request) + { + case GC_REQUEST_COMMAND: + { + switch(argv(1)) + { + case "configure": + { + cvar_set("_hud_configure", ftos(!autocvar__hud_configure)); + return; + } + + case "save": + { + if(argv(2)) + { + HUD_Panel_ExportCfg(argv(2)); + return; + } + else + { + break; // go to usage, we're missing the paramater needed here. + } + } + + case "radar": + { + if(argv(2)) + hud_panel_radar_maximized = (stof(argv(2)) != 0); + else + hud_panel_radar_maximized = !hud_panel_radar_maximized; + + return; + } + + case "scoreboard_columns_set": + { + Cmd_HUD_SetFields(argc); // todo update this function + + return; + } + + case "scoreboard_columns_help": + { + Cmd_HUD_Help(argc); // todo update this function + + return; + } + } + return; + } + + default: + print("Incorrect parameters for ^2hud^7\n"); + case GC_REQUEST_USAGE: + { + print("\nUsage:^3 cl_cmd hud action [configname | radartoggle]\n"); + print(" Where 'action' is the command to complete,\n"); + print(" 'configname' is the name to save to for \"save\" action,\n"); + print(" and 'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action.\n"); + print(" Full list of commands here: \"configure, save, radar.\"\n"); + return; + } + } +} + +void GameCommand_sendcvar(float request, float argc) +{ + switch(request) + { + case GC_REQUEST_COMMAND: + { + // W_FixWeaponOrder will trash argv, so save what we need. + string thiscvar = strzone(argv(1)); + string s = cvar_string(thiscvar); + + if(thiscvar == "cl_weaponpriority") + s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1); + else if(substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18) + s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0); + + localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n"); + strunzone(thiscvar); + + return; + } + + default: + case GC_REQUEST_USAGE: + { + print("\nUsage:^3 cl_cmd sendcvar \n"); + print(" Where 'cvar' is the cvar plus arguments to send to the server.\n"); + return; + } + } +} + +/* use this when creating a new command, making sure to place it in alphabetical order. +void GameCommand_(float request) +{ + switch(request) + { + case GC_REQUEST_COMMAND: + { + + return; + } + + default: + case GC_REQUEST_USAGE: + { + print("\nUsage:^3 cl_cmd \n"); + print(" No arguments required.\n"); + return; + } + } +} +*/ + + +// ================================== +// Macro system for client commands +// ================================== + +// Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;) +#define CLIENT_COMMANDS(request,arguments) \ + CLIENT_COMMAND("blurtest", GameCommand_blurtest(request), "Feature for testing blur postprocessing") \ + CLIENT_COMMAND("hud", GameCommand_hud(request, arguments), "Commands regarding/controlling the HUD system") \ + CLIENT_COMMAND("sendcvar", GameCommand_sendcvar(request, arguments), "Send a cvar to the server (like weaponpriority)") \ + /* nothing */ + +void GameCommand_macro_help() +{ + #define CLIENT_COMMAND(name,function,description) \ + { print(" ^2", name, "^7: ", description, "\n"); } + + CLIENT_COMMANDS(0, 0) + #undef CLIENT_COMMAND + + return; +} + +float GameCommand_macro_command(float argc) +{ + #define CLIENT_COMMAND(name,function,description) \ + { if(name == strtolower(argv(0))) { function; return TRUE; } } + + CLIENT_COMMANDS(GC_REQUEST_COMMAND, argc) + #undef CLIENT_COMMAND + + return FALSE; +} + +float GameCommand_macro_usage(float argc) +{ + #define CLIENT_COMMAND(name,function,description) \ + { if(name == strtolower(argv(1))) { function; return TRUE; } } + + CLIENT_COMMANDS(GC_REQUEST_USAGE, argc) + #undef CLIENT_COMMAND + + return FALSE; +} + + +// ========================================= +// Main Function Called By Engine (cl_cmd) +// ========================================= +// If this function exists, client code handles gamecommand instead of the engine code. + +void GameCommand(string command) +{ + float argc = tokenize_console(command); + + if(strtolower(argv(0)) == "help") + { + if(argc == 1) + { + print("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are:\n"); + GameCommand_macro_help(); + GameCommand_Generic("help"); + print("For help about specific commands, type cl_cmd help COMMAND\n"); + return; + } + else if(GameCommand_macro_usage(argc)) // Instead of trying to call a command, we're going to see detailed information about it + { + return; + } + } + else if(GameCommand_Generic(command)) + { + return; // handled by common/gamecommand.qc + } + else if(GameCommand_macro_command(argc)) // continue as usual and scan for normal commands + { + return; // handled by one of the above GameCommand_* functions + } + + // nothing above caught the command, must be invalid + print("Unknown client command", ((command != "") ? strcat(" \"", command, "\"") : ""), ". For a list of supported commands, try cl_cmd help.\n"); + + return; +} + + +// =================================== +// Macro system for console commands +// =================================== + +// These functions are here specifically to add special + - commands to the game, and are not really normal commands. +// Please add client commands to the function above this, as this is only for special reasons. +#define CONSOLE_COMMANDS_NORMAL \ + CONSOLE_COMMAND("+showscores", { scoreboard_showscores = TRUE; }) \ + CONSOLE_COMMAND("-showscores", { scoreboard_showscores = FALSE; }) \ + CONSOLE_COMMAND("+showaccuracy", { scoreboard_showaccuracy = TRUE; }) \ + CONSOLE_COMMAND("-showaccuracy", { scoreboard_showaccuracy = FALSE; }) \ + /* nothing */ + +#define CONSOLE_COMMANDS_MOVEMENT \ + CONSOLE_COMMAND("+forward", { ++camera_direction_x; }) \ + CONSOLE_COMMAND("-forward", { --camera_direction_x; }) \ + CONSOLE_COMMAND("+back", { --camera_direction_x; }) \ + CONSOLE_COMMAND("-back", { ++camera_direction_x; }) \ + CONSOLE_COMMAND("+moveup", { ++camera_direction_z; }) \ + CONSOLE_COMMAND("-moveup", { --camera_direction_z; }) \ + CONSOLE_COMMAND("+movedown", { --camera_direction_z; }) \ + CONSOLE_COMMAND("-movedown", { ++camera_direction_z; }) \ + CONSOLE_COMMAND("+moveright", { --camera_direction_y; }) \ + CONSOLE_COMMAND("-moveright", { ++camera_direction_y; }) \ + CONSOLE_COMMAND("+moveleft", { ++camera_direction_y; }) \ + CONSOLE_COMMAND("-moveleft", { --camera_direction_y; }) \ + CONSOLE_COMMAND("+roll_right", { ++camera_roll; }) \ + CONSOLE_COMMAND("-roll_right", { --camera_roll; }) \ + CONSOLE_COMMAND("+roll_left", { --camera_roll; }) \ + CONSOLE_COMMAND("-roll_left", { ++camera_roll; }) \ + /* nothing */ + +void ConsoleCommand_macro_init() +{ + // first init normal commands + #define CONSOLE_COMMAND(name,execution) \ + { registercommand(name); } + + CONSOLE_COMMANDS_NORMAL + #undef CONSOLE_COMMAND + + // then init movement commands + #ifndef CAMERATEST + if(isdemo()) + { + #endif + #define CONSOLE_COMMAND(name,execution) \ + { registercommand(name); } + + CONSOLE_COMMANDS_MOVEMENT + #undef CONSOLE_COMMAND + #ifndef CAMERATEST + } + #endif + + return; +} + +float ConsoleCommand_macro_normal(float argc) +{ + #define CONSOLE_COMMAND(name,execution) \ + { if(name == strtolower(argv(0))) { { execution } return TRUE; } } + + CONSOLE_COMMANDS_NORMAL + #undef CONSOLE_COMMAND + + return FALSE; +} + +float ConsoleCommand_macro_movement(float argc) +{ + if(camera_active) + { + #define CONSOLE_COMMAND(name,execution) \ + { if(name == strtolower(argv(0))) { { execution } return TRUE; } } + + CONSOLE_COMMANDS_MOVEMENT + #undef CONSOLE_COMMAND + } + + return FALSE; +} + + +// ====================================================== +// Main Function Called By Engine (registered commands) +// ====================================================== +// Used to parse commands in the console that have been registered with the "registercommand" function + +float CSQC_ConsoleCommand(string command) +{ + float argc = tokenize_console(command); + + if(ConsoleCommand_macro_normal(argc)) + { + return TRUE; + } + else if(ConsoleCommand_macro_movement(argc)) + { + return TRUE; + } + + // Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it. + + return FALSE; +} \ No newline at end of file diff --git a/qcsrc/client/gamecommand.qc b/qcsrc/client/gamecommand.qc deleted file mode 100644 index a15626a71..000000000 --- a/qcsrc/client/gamecommand.qc +++ /dev/null @@ -1,471 +0,0 @@ -// ============================================== -// CSQC client commands code, written by Samual -// Last updated: November 26th, 2011 -// ============================================== - - /* - if(cmd == "mv_download") { - Cmd_MapVote_MapDownload(argc); - } - else if(cmd == "scoreboard_columns_set") { - Cmd_HUD_SetFields(argc); - } - else if(cmd == "scoreboard_columns_help") { - Cmd_HUD_Help(argc); - } - else if(cmd == "spawn") { - s = argv(1); - e = spawn(); - precache_model(s); - setmodel(e, s); - setorigin(e, view_origin); - e.angles = view_angles; - e.draw = DrawDebugModel; - e.classname = "debugmodel"; - } - else if(cmd == "vyes") - { - if(uid2name_dialog) - { - 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) - vote_prev = 0; - localcmd("setreport cl_allow_uid2name 1\n"); - vote_change = -9999; - uid2name_dialog = 0; - } - else - { - localcmd("cmd vote yes\n"); - } - } - else if(cmd == "vno") - { - if(uid2name_dialog) - { - vote_active = 0; - vote_prev = 0; - localcmd("setreport cl_allow_uid2name 0\n"); - vote_change = -9999; - uid2name_dialog = 0; - } - else - { - localcmd("cmd vote no\n"); - } - } - */ - - -#define GC_REQUEST_COMMAND 1 -#define GC_REQUEST_USAGE 2 - -void Cmd_HUD_SetFields(float); -void Cmd_HUD_Help(float); - -.vector view_ofs; -entity debug_shotorg; - - -// ============================ -// Misc. Supporting Functions -// ============================ - -float cvar_clientsettemp(string tmp_cvar, string value) -{ - entity e; - - for(e = world; (e = find(e, classname, "saved_cvar_value")); ) - if(e.netname == tmp_cvar) - goto saved; - - // creating a new entity to keep track of this cvar - e = spawn(); - e.classname = "saved_cvar_value"; - e.netname = strzone(tmp_cvar); - e.message = strzone(cvar_string(tmp_cvar)); - return TRUE; - - // an entity for this cvar already exists, update the value - :saved - cvar_set(tmp_cvar, value); - return FALSE; -} - -float cvar_clientsettemp_restore() -{ - float i; - entity e; - - for(e = world; (e = find(e, classname, "saved_cvar_value")); ) - { cvar_set(e.netname, e.message); ++i; } - - return i; -} - -void DrawDebugModel() -{ - if(time - floor(time) > 0.5) - { - PolyDrawModel(self); - self.drawmask = 0; - } - else - { - self.renderflags = 0; - self.drawmask = MASK_NORMAL; - } -} - - -// ======================= -// Command Sub-Functions -// ======================= - -void GameCommand_blurtest(float request) -{ - // Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now... - // Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command. - - #ifdef BLURTEST - switch(request) - { - case GC_REQUEST_COMMAND: - { - blurtest_time0 = time; - blurtest_time1 = time + stof(argv(1)); - blurtest_radius = stof(argv(2)); - blurtest_power = stof(argv(3)); - print("Enabled blurtest\n"); - return; - } - - default: - case GC_REQUEST_USAGE: - { - print("\nUsage:^3 cl_cmd blurtest\n"); - print(" No arguments required.\n"); - return; - } - } - #else - if(request) - { - print("Blurtest is not enabled on this client.\n"); - return; - } - #endif -} - -void GameCommand_hud(float request, float argc) // TODO: Add aliases in commands.cfg -{ - switch(request) - { - case GC_REQUEST_COMMAND: - { - switch(argv(1)) - { - case "configure": - { - cvar_set("_hud_configure", ftos(!autocvar__hud_configure)); - return; - } - - case "save": - { - if(argv(2)) - { - HUD_Panel_ExportCfg(argv(2)); - return; - } - else - { - break; // go to usage, we're missing the paramater needed here. - } - } - - case "radar": - { - if(argv(2)) - hud_panel_radar_maximized = (stof(argv(2)) != 0); - else - hud_panel_radar_maximized = !hud_panel_radar_maximized; - - return; - } - - case "scoreboard_columns_set": - { - Cmd_HUD_SetFields(argc); // todo update this function - - return; - } - - case "scoreboard_columns_help": - { - Cmd_HUD_Help(argc); // todo update this function - - return; - } - } - return; - } - - default: - print("Incorrect parameters for ^2hud^7\n"); - case GC_REQUEST_USAGE: - { - print("\nUsage:^3 cl_cmd hud action [configname | radartoggle]\n"); - print(" Where 'action' is the command to complete,\n"); - print(" 'configname' is the name to save to for \"save\" action,\n"); - print(" and 'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action.\n"); - print(" Full list of commands here: \"configure, save, radar.\"\n"); - return; - } - } -} - -void GameCommand_sendcvar(float request, float argc) -{ - switch(request) - { - case GC_REQUEST_COMMAND: - { - // W_FixWeaponOrder will trash argv, so save what we need. - string thiscvar = strzone(argv(1)); - string s = cvar_string(thiscvar); - - if(thiscvar == "cl_weaponpriority") - s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1); - else if(substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18) - s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0); - - localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n"); - strunzone(thiscvar); - - return; - } - - default: - case GC_REQUEST_USAGE: - { - print("\nUsage:^3 cl_cmd sendcvar \n"); - print(" Where 'cvar' is the cvar plus arguments to send to the server.\n"); - return; - } - } -} - -/* use this when creating a new command, making sure to place it in alphabetical order. -void GameCommand_(float request) -{ - switch(request) - { - case GC_REQUEST_COMMAND: - { - - return; - } - - default: - case GC_REQUEST_USAGE: - { - print("\nUsage:^3 cl_cmd \n"); - print(" No arguments required.\n"); - return; - } - } -} -*/ - - -// ================================== -// Macro system for client commands -// ================================== - -// Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;) -#define CLIENT_COMMANDS(request,arguments) \ - CLIENT_COMMAND("blurtest", GameCommand_blurtest(request), "Feature for testing blur postprocessing") \ - CLIENT_COMMAND("hud", GameCommand_hud(request, arguments), "Commands regarding/controlling the HUD system") \ - CLIENT_COMMAND("sendcvar", GameCommand_sendcvar(request, arguments), "Send a cvar to the server (like weaponpriority)") \ - /* nothing */ - -void GameCommand_macro_help() -{ - #define CLIENT_COMMAND(name,function,description) \ - { print(" ^2", name, "^7: ", description, "\n"); } - - CLIENT_COMMANDS(0, 0) - #undef CLIENT_COMMAND - - return; -} - -float GameCommand_macro_command(float argc) -{ - #define CLIENT_COMMAND(name,function,description) \ - { if(name == strtolower(argv(0))) { function; return TRUE; } } - - CLIENT_COMMANDS(GC_REQUEST_COMMAND, argc) - #undef CLIENT_COMMAND - - return FALSE; -} - -float GameCommand_macro_usage(float argc) -{ - #define CLIENT_COMMAND(name,function,description) \ - { if(name == strtolower(argv(1))) { function; return TRUE; } } - - CLIENT_COMMANDS(GC_REQUEST_USAGE, argc) - #undef CLIENT_COMMAND - - return FALSE; -} - - -// ========================================= -// Main Function Called By Engine (cl_cmd) -// ========================================= -// If this function exists, client code handles gamecommand instead of the engine code. - -void GameCommand(string command) -{ - float argc = tokenize_console(command); - - if(strtolower(argv(0)) == "help") - { - if(argc == 1) - { - print("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are:\n"); - GameCommand_macro_help(); - GameCommand_Generic("help"); - print("For help about specific commands, type cl_cmd help COMMAND\n"); - return; - } - else if(GameCommand_macro_usage(argc)) // Instead of trying to call a command, we're going to see detailed information about it - { - return; - } - } - else if(GameCommand_Generic(command)) - { - return; // handled by common/gamecommand.qc - } - else if(GameCommand_macro_command(argc)) // continue as usual and scan for normal commands - { - return; // handled by one of the above GameCommand_* functions - } - - // nothing above caught the command, must be invalid - print("Unknown client command", ((command != "") ? strcat(" \"", command, "\"") : ""), ". For a list of supported commands, try cl_cmd help.\n"); - - return; -} - - -// =================================== -// Macro system for console commands -// =================================== - -// These functions are here specifically to add special + - commands to the game, and are not really normal commands. -// Please add client commands to the function above this, as this is only for special reasons. -#define CONSOLE_COMMANDS_NORMAL \ - CONSOLE_COMMAND("+showscores", { scoreboard_showscores = TRUE; }) \ - CONSOLE_COMMAND("-showscores", { scoreboard_showscores = FALSE; }) \ - CONSOLE_COMMAND("+showaccuracy", { scoreboard_showaccuracy = TRUE; }) \ - CONSOLE_COMMAND("-showaccuracy", { scoreboard_showaccuracy = FALSE; }) \ - /* nothing */ - -#define CONSOLE_COMMANDS_MOVEMENT \ - CONSOLE_COMMAND("+forward", { ++camera_direction_x; }) \ - CONSOLE_COMMAND("-forward", { --camera_direction_x; }) \ - CONSOLE_COMMAND("+back", { --camera_direction_x; }) \ - CONSOLE_COMMAND("-back", { ++camera_direction_x; }) \ - CONSOLE_COMMAND("+moveup", { ++camera_direction_z; }) \ - CONSOLE_COMMAND("-moveup", { --camera_direction_z; }) \ - CONSOLE_COMMAND("+movedown", { --camera_direction_z; }) \ - CONSOLE_COMMAND("-movedown", { ++camera_direction_z; }) \ - CONSOLE_COMMAND("+moveright", { --camera_direction_y; }) \ - CONSOLE_COMMAND("-moveright", { ++camera_direction_y; }) \ - CONSOLE_COMMAND("+moveleft", { ++camera_direction_y; }) \ - CONSOLE_COMMAND("-moveleft", { --camera_direction_y; }) \ - CONSOLE_COMMAND("+roll_right", { ++camera_roll; }) \ - CONSOLE_COMMAND("-roll_right", { --camera_roll; }) \ - CONSOLE_COMMAND("+roll_left", { --camera_roll; }) \ - CONSOLE_COMMAND("-roll_left", { ++camera_roll; }) \ - /* nothing */ - -void ConsoleCommand_macro_init() -{ - // first init normal commands - #define CONSOLE_COMMAND(name,execution) \ - { registercommand(name); } - - CONSOLE_COMMANDS_NORMAL - #undef CONSOLE_COMMAND - - // then init movement commands - #ifndef CAMERATEST - if(isdemo()) - { - #endif - #define CONSOLE_COMMAND(name,execution) \ - { registercommand(name); } - - CONSOLE_COMMANDS_MOVEMENT - #undef CONSOLE_COMMAND - #ifndef CAMERATEST - } - #endif - - return; -} - -float ConsoleCommand_macro_normal(float argc) -{ - #define CONSOLE_COMMAND(name,execution) \ - { if(name == strtolower(argv(0))) { { execution } return TRUE; } } - - CONSOLE_COMMANDS_NORMAL - #undef CONSOLE_COMMAND - - return FALSE; -} - -float ConsoleCommand_macro_movement(float argc) -{ - if(camera_active) - { - #define CONSOLE_COMMAND(name,execution) \ - { if(name == strtolower(argv(0))) { { execution } return TRUE; } } - - CONSOLE_COMMANDS_MOVEMENT - #undef CONSOLE_COMMAND - } - - return FALSE; -} - - -// ====================================================== -// Main Function Called By Engine (registered commands) -// ====================================================== -// Used to parse commands in the console that have been registered with the "registercommand" function - -float CSQC_ConsoleCommand(string command) -{ - float argc = tokenize_console(command); - - if(ConsoleCommand_macro_normal(argc)) - { - return TRUE; - } - else if(ConsoleCommand_macro_movement(argc)) - { - return TRUE; - } - - // Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it. - - return FALSE; -} \ No newline at end of file diff --git a/qcsrc/common/command/generic.qc b/qcsrc/common/command/generic.qc new file mode 100644 index 000000000..9595ed5c2 --- /dev/null +++ b/qcsrc/common/command/generic.qc @@ -0,0 +1,853 @@ +#define MAX_RPN_STACK 16 +float rpn_db; +float rpn_error; +float rpn_sp; +string rpn_stack[MAX_RPN_STACK]; +string rpn_pop() { + if(rpn_sp > 0) { + --rpn_sp; + return rpn_stack[rpn_sp]; + } else { + print("rpn: stack underflow\n"); + rpn_error = TRUE; + return ""; + } +} +void rpn_push(string s) { + if(rpn_sp < MAX_RPN_STACK) { + rpn_stack[rpn_sp] = s; + ++rpn_sp; + } else { + print("rpn: stack overflow\n"); + rpn_error = TRUE; + } +} +string rpn_get() { + if(rpn_sp > 0) { + return rpn_stack[rpn_sp - 1]; + } else { + print("rpn: empty stack\n"); + rpn_error = TRUE; + return ""; + } +} +void rpn_set(string s) { + if(rpn_sp > 0) { + rpn_stack[rpn_sp - 1] = s; + } else { + print("rpn: empty stack\n"); + rpn_error = TRUE; + } +} +float rpn_getf() { return stof(rpn_get()); } +float rpn_popf() { return stof(rpn_pop()); } +void rpn_pushf(float f) { return rpn_push(ftos(f)); } +void rpn_setf(float f) { return rpn_set(ftos(f)); } + +#define NUM_MARKUPS 41 +float markup_init; +string markup_from[NUM_MARKUPS]; +string markup_to[NUM_MARKUPS]; +void GameCommand_MarkupInit() +{ + float i; + if (markup_init) + return; + markup_init = 1; + i = 0; + markup_from[i] = "&alien"; markup_to[i] = "\x12"; ++i; + markup_from[i] = "&:-)"; markup_to[i] = "\x13"; ++i; + markup_from[i] = "&:-("; markup_to[i] = "\x14"; ++i; + markup_from[i] = "&x-P"; markup_to[i] = "\x15"; ++i; + markup_from[i] = "&:-/"; markup_to[i] = "\x16"; ++i; + markup_from[i] = "&:-D"; markup_to[i] = "\x17"; ++i; + markup_from[i] = "&<<"; markup_to[i] = "\x18"; ++i; + markup_from[i] = "&>>"; markup_to[i] = "\x19"; ++i; + markup_from[i] = "&dot"; markup_to[i] = "\x1a"; ++i; + markup_from[i] = "&^_"; markup_to[i] = "\x1b"; ++i; + markup_from[i] = "&ysplat"; markup_to[i] = "\x1c"; ++i; + markup_from[i] = "&-]"; markup_to[i] = "\x1d"; ++i; + markup_from[i] = "&--"; markup_to[i] = "\x1e"; ++i; + markup_from[i] = "&[-"; markup_to[i] = "\x1f"; ++i; + markup_from[i] = "&s<"; markup_to[i] = "\x2c"; ++i; + markup_from[i] = "&s>"; markup_to[i] = "\x2e"; ++i; + markup_from[i] = "&<-"; markup_to[i] = "\x7f"; ++i; + markup_from[i] = "&[="; markup_to[i] = "\x80"; ++i; + markup_from[i] = "&=="; markup_to[i] = "\x81"; ++i; + markup_from[i] = "&=]"; markup_to[i] = "\x82"; ++i; + markup_from[i] = "&r!"; markup_to[i] = "\x84"; ++i; + markup_from[i] = "&|o|"; markup_to[i] = "\x85"; ++i; + markup_from[i] = "&|u|"; markup_to[i] = "\x86"; ++i; + markup_from[i] = "&|i|"; markup_to[i] = "\x87"; ++i; + markup_from[i] = "&|c|"; markup_to[i] = "\x88"; ++i; + markup_from[i] = "&[c]"; markup_to[i] = "\x89"; ++i; + markup_from[i] = "&[n]"; markup_to[i] = "\x8a"; ++i; + markup_from[i] = "&[]"; markup_to[i] = "\x8b"; ++i; + markup_from[i] = "&r?"; markup_to[i] = "\x8c"; ++i; + markup_from[i] = "&|>"; markup_to[i] = "\x8d"; ++i; + markup_from[i] = "&splat0"; markup_to[i] = "\x8e"; ++i; + markup_from[i] = "&splat1"; markup_to[i] = "\x8f"; ++i; + markup_from[i] = "&[["; markup_to[i] = "\x90"; ++i; + markup_from[i] = "&]]"; markup_to[i] = "\x91"; ++i; + markup_from[i] = "&splat2"; markup_to[i] = "\x9a"; ++i; + markup_from[i] = "&)("; markup_to[i] = "\x9b"; ++i; + markup_from[i] = "&splat3"; markup_to[i] = "\x9c"; ++i; + markup_from[i] = "&(."; markup_to[i] = "\x9d"; ++i; + markup_from[i] = "&.."; markup_to[i] = "\x9e"; ++i; + markup_from[i] = "&.)"; markup_to[i] = "\x9f"; ++i; + markup_from[i] = "&<|"; markup_to[i] = "\xff"; ++i; +} + +string GameCommand_Markup(string s2) +{ + float red, ccase, i, j; + string s, s3; + + GameCommand_MarkupInit(); + + s = ""; + + red = 0; + ccase = 0; + for(i = 0; i < strlen(s2); ++i) + { + for(j = 0; j < NUM_MARKUPS; ++j) + { + s3 = substring(s2, i, strlen(markup_from[j])); + if (s3 == markup_from[j]) + { + s = strcat(s, markup_to[j]); + i += strlen(markup_from[j]) - 1; + break; + } + } + + if(j == NUM_MARKUPS) + { + if(substring(s2, i, 2) == "&&") + { + s = strcat(s, strconv(ccase, red, red, "&")); + ++i; + } + else if(substring(s2, i, 2) == "&d") + { + red = 2; + ccase = 0; + ++i; + } + else if(substring(s2, i, 2) == "&a") + { + red = 2; + ccase = 2; + ++i; + } + else if(substring(s2, i, 2) == "&n") + { + red = 0; + ccase = 0; + ++i; + } + else + s = strcat(s, strconv(ccase, red, red, substring(s2, i, 1))); + } + } + + return s; +} + +float GameCommand_Generic(string command) +{ + float argc; + float i, j, f, n; + vector rgb; + string s, s2, c; + argc = tokenize_console(command); + if(argv(0) == "help") + { + print(" rpn EXPRESSION... - a RPN calculator.\n"); + print(" Operator description (x: string, s: set, f: float):\n"); + print(" x pop -----------------------------> : removes the top\n"); + print(" x dup -----------------------------> x x : duplicates the top\n"); + print(" x x exch --------------------------> x x : swap the top two\n"); + print(" /cvarname load --------------------> x : loads a cvar\n"); + print(" /cvarname x def -------------------> : writes to a cvar\n"); + print(" f f add|sub|mul|div|mod|max|min ---> f : adds/... two numbers\n"); + print(" f f eq|ne|gt|ge|lt|le -------------> f : compares two numbers\n"); + print(" f neg|abs|sgn|rand|floor|ceil------> f : negates/... a number\n"); + print(" f f f bound -----------------------> f : bounds the middle number\n"); + print(" f1 f2 b when ----------------------> f : f1 if b, f2 otherwise\n"); + print(" s s union|intersection|difference -> s : set operations\n"); + print(" s shuffle -------------------------> s : randomly arrange elements\n"); + print(" /key /value put -------------------> : set a database key\n"); + print(" /key get --------------------------> s : get a database value\n"); + print(" x dbpush --------------------------> : pushes the top onto the database\n"); + print(" dbpop|dbget -----------------------> x : removes/reads DB's top\n"); + print(" dblen|dbat ------------------------> f : gets the DB's size/cursor pos\n"); + print(" dbclr -----------------------------> : clear the DB\n"); + print(" s dbsave|dbload--------------------> : save/load the DB to/from a file\n"); + print(" x dbins ---------------------------> : moves the top into the DB\n"); + print(" dbext|dbread ----------------------> x : extract/get from the DB's cursor\n"); + print(" f dbmov|dbgoto --------------------> : move or set the DB's cursor\n"); + print(" s localtime -----------------------> s : formats the current local time\n"); + print(" s gmtime --------------------------> s : formats the current UTC time\n"); + print(" time ------------------------------> f : seconds since VM start\n"); + print(" s /MD4 digest ---------------------> s : MD4 digest\n"); + print(" s /SHA256 digest ------------------> s : SHA256 digest\n"); + print(" s /formatstring sprintf1s ---------> s : sprintf with 1 string (pad, cut)\n"); + print(" Set operations operate on 'such''strings'.\n"); + print(" Unknown tokens insert their cvar value.\n"); + print(" maplist add map\n"); + print(" maplist remove map\n"); + print(" maplist shuffle\n"); + print(" maplist cleanup\n"); + print(" maplist maplist\n"); + print(" maplist lsmaps\n"); + print(" maplist lsnewmaps\n"); + print(" addtolist variable addedvalue\n"); + print(" records\n"); + print(" rankings (map argument optional)\n"); + return TRUE; + } + + if(argv(0) == "maplist") + { + if(argv(1) == "add" && argc == 3) + { + if (!fexists(strcat("maps/", argv(2), ".bsp"))) + { + print("maplist: ERROR: ", argv(2), " does not exist!\n"); + return TRUE; + } + if(cvar_string("g_maplist") == "") + cvar_set("g_maplist", argv(2)); + else + cvar_set("g_maplist", strcat(argv(2), " ", cvar_string("g_maplist"))); + return TRUE; + } + else if(argv(1) == "remove" && argc == 3) + { + s = argv(2); + n = tokenizebyseparator(cvar_string("g_maplist"), " "); + s2 = ""; + for(i = 0; i < n; ++i) + if(argv(i) != s) + s2 = strcat(s2, " ", argv(i)); + s2 = substring(s2, 1, strlen(s2) - 1); + cvar_set("g_maplist", s2); + return TRUE; + } + else if(argv(1) == "shuffle" && argc == 2) + { + cvar_set("g_maplist", shufflewords(cvar_string("g_maplist"))); + return TRUE; + } + else if(argv(1) == "cleanup") + { + MapInfo_Enumerate(); + MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); + n = tokenizebyseparator(cvar_string("g_maplist"), " "); + s2 = ""; + for(i = 0; i < n; ++i) + if(MapInfo_CheckMap(argv(i))) + s2 = strcat(s2, " ", argv(i)); + s2 = substring(s2, 1, strlen(s2) - 1); + cvar_set("g_maplist", s2); + return TRUE; + } + else if(argv(1) == "maplist") { + print(maplist_reply); + return TRUE; + } + else if(argv(1) == "lsmaps") { + print(lsmaps_reply); + return TRUE; + } + else if(argv(1) == "lsnewmaps") { + print(lsnewmaps_reply); + return TRUE; + } + } + else if(argc >= 3 && argv(0) == "red") + { + s = substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2)); + localcmd(strcat(argv(1), " ", GameCommand_Markup(s))); + return TRUE; + } + else if(argc >= 3 && crc16(0, argv(0)) == 38566 && crc16(0, strcat(argv(0), argv(0), argv(0))) == 59830) + { + // other test case + s = strconv(2, 0, 0, substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2))); + + n = floor(random() * 6 + 2); + + s2 = ""; + for(i = 0; i < n; ++i) + { + s2 = strcat(s2, "AH"); + } + + if(random() < 0.1) + s2 = strcat(substring(s2, 1, strlen(s2) - 1), "A"); + + if(s == "") + s = s2; + else + if(random() < 0.8) + s = strcat(s, " ", s2); + else + s = strcat(s2, " ", s); + + s2 = substring(s, strlen(s) - 2, 2); + if(s2 == "AH" || s2 == "AY") + s = strcat(s, "))"); + else + s = strcat(s, " ))"); + + if(random() < 0.1) + s = substring(s, 0, strlen(s) - 1); + + if(random() < 0.1) + s = strconv(1, 0, 0, s); + + localcmd(strcat(argv(1), " ", s)); + + return TRUE; + } + else if(argc >= 3 && crc16(0, argv(0)) == 3826 && crc16(0, strcat(argv(0), argv(0), argv(0))) == 55790) + { + // test case for terencehill's color codes + s = strdecolorize(substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2))); + s2 = ""; + + n = strlen(s); + j = ((6 * max(1, floor(strlen(s)/32 + random() * 2 - 1))) / n) * (1 - 2 * (random() > 0.5)); + f = random() * 6; + + for(i = 0; i < n; ++i) + { + c = substring(s, i, 1); + + if(c == ";") + c = ":"; + else if(c == "^") + { + c = "^^"; + if(substring(s, i+1, 1) == "^") + ++i; + } + + if(c != " ") + { + rgb = hsl_to_rgb('1 0 0' * (j * i + f) + '0 1 .5'); + c = strcat(rgb_to_hexcolor(rgb), c); + } + s2 = strcat(s2, c); + } + + localcmd(strcat(argv(1), " ", s2)); + + return TRUE; + } + else if(argv(0) == "rpn") + { + if(!rpn_db) + { + rpn_db = db_create(); + db_put(rpn_db, "stack.pointer", "0"); + db_put(rpn_db, "stack.pos", "-1"); + } + if(argc >= 2) + { + float rpnpos; + string rpncmd; + float f2, f3; + rpn_sp = 0; + rpn_error = FALSE; + for(rpnpos = 1; rpnpos < argc; ++rpnpos) + { + rpncmd = argv(rpnpos); + f = strlen(rpncmd); + if(rpncmd == "") { + } else if(stof(substring(rpncmd, 0, 1)) > 0) { + rpn_push(rpncmd); + } else if(substring(rpncmd, 0, 1) == "0") { + rpn_push(rpncmd); + } else if(f >= 2 && substring(rpncmd, 0, 1) == "+") { + rpn_push(rpncmd); + } else if(f >= 2 && substring(rpncmd, 0, 1) == "-") { + rpn_push(rpncmd); + } else if(f >= 2 && substring(rpncmd, 0, 1) == "/") { + rpn_push(substring(rpncmd, 1, strlen(rpncmd) - 1)); + } else if(rpncmd == "clear") { + rpn_sp = 0; + } else if(rpncmd == "def" || rpncmd == "=") { + s = rpn_pop(); + s2 = rpn_pop(); + + if(s2 != "") + { +#ifdef MENUQC + registercvar(s2, "", 0); +#else + registercvar(s2, ""); +#endif + if(!rpn_error) // don't change cvars if a stack error had happened! + cvar_set(s2, s); + } + else + { + print("rpn: empty cvar name for 'def'\n"); + rpn_error = TRUE; + } + } else if(rpncmd == "defs" || rpncmd == "@") { + s = ""; + i = rpn_popf(); + j = (i == 0); + while(rpn_sp > 1 && (j || i > 0)) + { + s = strcat("/", rpn_pop(), " ", s); + --i; + } + s2 = rpn_pop(); + if(s2 != "") + { +#ifdef MENUQC + registercvar(s2, "", 0); +#else + registercvar(s2, ""); +#endif + if(!rpn_error) // don't change cvars if a stack error had happened! + cvar_set(s2, s); + } + else + { + print("rpn: empty cvar name for 'defs'\n"); + rpn_error = TRUE; + } + } else if(rpncmd == "load") { + rpn_set(cvar_string(rpn_get())); + } else if(rpncmd == "exch") { + s = rpn_pop(); + s2 = rpn_get(); + rpn_set(s); + rpn_push(s2); + } else if(rpncmd == "dup") { + rpn_push(rpn_get()); + } else if(rpncmd == "pop") { + rpn_pop(); + } else if(rpncmd == "add" || rpncmd == "+") { + f = rpn_popf(); + rpn_setf(rpn_getf() + f); + } else if(rpncmd == "sub" || rpncmd == "-") { + f = rpn_popf(); + rpn_setf(rpn_getf() - f); + } else if(rpncmd == "mul" || rpncmd == "*") { + f = rpn_popf(); + rpn_setf(rpn_getf() * f); + } else if(rpncmd == "div" || rpncmd == "/") { + f = rpn_popf(); + rpn_setf(rpn_getf() / f); + } else if(rpncmd == "mod" || rpncmd == "%") { + f = rpn_popf(); + f2 = rpn_getf(); + rpn_setf(f2 - f * floor(f2 / f)); + } else if(rpncmd == "abs") { + rpn_setf(fabs(rpn_getf())); + } else if(rpncmd == "sgn") { + f = rpn_getf(); + if(f < 0) + rpn_set("-1"); + else if(f > 0) + rpn_set("1"); + else + rpn_set("0"); + } else if(rpncmd == "neg" || rpncmd == "~") { + rpn_setf(-rpn_getf()); + } else if(rpncmd == "floor" || rpncmd == "f") { + rpn_setf(floor(rpn_getf())); + } else if(rpncmd == "ceil" || rpncmd == "c") { + rpn_setf(ceil(rpn_getf())); + } else if(rpncmd == "max") { + f = rpn_popf(); + f2 = rpn_getf(); + rpn_setf(max(f2, f)); + } else if(rpncmd == "min") { + f = rpn_popf(); + f2 = rpn_getf(); + rpn_setf(min(f2, f)); + } else if(rpncmd == "bound") { + f = rpn_popf(); + f2 = rpn_popf(); + f3 = rpn_getf(); + rpn_setf(bound(f3, f2, f)); + } else if(rpncmd == "when") { + f = rpn_popf(); + f2 = rpn_popf(); + f3 = rpn_getf(); + if(f) + rpn_setf(f3); + else + rpn_setf(f2); + } else if(rpncmd == ">" || rpncmd == "gt") { + f = rpn_popf(); + rpn_setf(rpn_getf() > f); + } else if(rpncmd == "<" || rpncmd == "lt") { + f = rpn_popf(); + rpn_setf(rpn_getf() < f); + } else if(rpncmd == "==" || rpncmd == "eq") { + f = rpn_popf(); + rpn_setf(rpn_getf() == f); + } else if(rpncmd == ">=" || rpncmd == "ge") { + f = rpn_popf(); + rpn_setf(rpn_getf() >= f); + } else if(rpncmd == "<=" || rpncmd == "le") { + f = rpn_popf(); + rpn_setf(rpn_getf() <= f); + } else if(rpncmd == "!=" || rpncmd == "ne") { + f = rpn_popf(); + rpn_setf(rpn_getf() != f); + } else if(rpncmd == "rand") { + rpn_setf(ceil(random() * rpn_getf()) - 1); + } else if(rpncmd == "crc16") { + rpn_setf(crc16(FALSE, rpn_get())); + } else if(rpncmd == "put") { + s2 = rpn_pop(); + if (!rpn_error) + { + s = rpn_pop(); + if (!rpn_error) + db_put(rpn_db, s, s2); + } + } else if(rpncmd == "get") { + s = rpn_pop(); + if (!rpn_error) + rpn_push(db_get(rpn_db, s)); + } else if(rpncmd == "dbpush") { + s = rpn_pop(); + if(!rpn_error) + { + i = stof(db_get(rpn_db, "stack.pointer")); + db_put(rpn_db, "stack.pointer", ftos(i+1)); + db_put(rpn_db, strcat("stack.", ftos(i)), s); + } + if(!i) + db_put(rpn_db, "stack.pos", "0"); + } else if(rpncmd == "dbpop") { + i = stof(db_get(rpn_db, "stack.pointer")); + if(i) + { + s = ftos(i-1); + db_put(rpn_db, "stack.pointer", s); + rpn_push(db_get(rpn_db, strcat("stack.", s))); + j = stof(db_get(rpn_db, "stack.pos")); + if(j >= i) + db_put(rpn_db, "stack.pos", ftos(i-2)); + } else { + rpn_error = 1; + print("rpn: database underflow\n"); + } + } else if(rpncmd == "dbget") { + + i = stof(db_get(rpn_db, "stack.pointer")); + if(i) + { + rpn_push(db_get(rpn_db, strcat("stack.", ftos(i-1)))); + } else { + rpn_error = 1; + print("rpn: database empty\n"); + } + } else if(rpncmd == "dblen") { + rpn_push(db_get(rpn_db, "stack.pointer")); + } else if(rpncmd == "dbclr") { + db_close(rpn_db); + rpn_db = db_create(); + db_put(rpn_db, "stack.pointer", "0"); + db_put(rpn_db, "stack.pos", "-1"); + } else if(rpncmd == "dbsave") { + s = rpn_pop(); + if(!rpn_error) + db_save(rpn_db, s); + } else if(rpncmd == "dbload") { + s = rpn_pop(); + if(!rpn_error) + { + db_close(rpn_db); + rpn_db = db_load(s); + } + } else if(rpncmd == "dbins") { + s = rpn_pop(); + if(!rpn_error) + //if(rpn_sp > 0) + { + j = stof(db_get(rpn_db, "stack.pointer")); + i = stof(db_get(rpn_db, "stack.pos")); + + if(i < 0) + { + i = 0; + db_put(rpn_db, "stack.pos", "0"); + } + + db_put(rpn_db, "stack.pointer", ftos(j+1)); + for(--j; j >= i; --j) + { + db_put(rpn_db, strcat("stack.", ftos(j+1)), + db_get(rpn_db, (strcat("stack.", ftos(j)))) + ); + } + db_put(rpn_db, strcat("stack.", ftos(i)), s); + } + } else if(rpncmd == "dbext") { + j = stof(db_get(rpn_db, "stack.pointer")); + i = stof(db_get(rpn_db, "stack.pos")); + if(!j) + { + rpn_error = TRUE; + print("rpn: empty database\n"); + } else { + --j; + rpn_push(db_get(rpn_db, strcat("stack.", ftos(i)))); + db_put(rpn_db, "stack.pointer", ftos(j)); + if(i == j) + { + db_put(rpn_db, "stack.pos", ftos(j-1)); + } else { + while(i < j) + { + db_put(rpn_db, strcat("stack.", ftos(i)), + db_get(rpn_db, (strcat("stack.", ftos(i+1)))) + ); + ++i; + } + } + } + } else if(rpncmd == "dbread") { + s = db_get(rpn_db, "stack.pos"); + if(stof(s) >= 0) + { + rpn_push(db_get(rpn_db, strcat("stack.", s))); + } else { + rpn_error = 1; + print("rpn: empty database\n"); + } + } else if(rpncmd == "dbat") { + rpn_push(db_get(rpn_db, "stack.pos")); + } else if(rpncmd == "dbmov") { + j = stof(db_get(rpn_db, "stack.pointer")); + i = stof(db_get(rpn_db, "stack.pos")); + i += rpn_popf(); + if(!rpn_error) + { + if(i < 0 || i >= j) + { + print("rpn: database cursor out of bounds\n"); + rpn_error = TRUE; + } + if(!rpn_error) + { + db_put(rpn_db, "stack.pos", ftos(i)); + } + } + } else if(rpncmd == "dbgoto") { + s = rpn_pop(); + j = stof(db_get(rpn_db, "stack.pointer")); + if(!j) + { + rpn_error = TRUE; + print("rpn: empty database, cannot move cursor\n"); + } + if(!rpn_error) + { + if(s == "end") + i = stof(db_get(rpn_db, "stack.pointer"))-1; + else if(s == "beg") + i = 0; + else + i = stof(s); + + j = stof(db_get(rpn_db, "stack.pointer")); + if(i < 0 || i >= j) + { + print("rpn: database cursor destination out of bounds\n"); + rpn_error = TRUE; + } + if(!rpn_error) + { + db_put(rpn_db, "stack.pos", ftos(i)); + } + } + } else if(rpncmd == "union") { + // s s2 union + s2 = rpn_pop(); + s = rpn_get(); + f = tokenize_console(s); + f2 = tokenize_console(strcat(s, " ", s2)); + // tokens 0..(f-1) represent s + // tokens f..f2 represent s2 + // UNION: add all tokens to s that are in s2 but not in s + s = ""; + for(i = 0; i < f; ++i) + s = strcat(s, " ", argv(i)); + for(i = f; i < f2; ++i) { + for(j = 0; j < f; ++j) + if(argv(i) == argv(j)) + goto skip_union; + s = strcat(s, " ", argv(i)); +:skip_union + } + if(substring(s, 0, 1) == " ") + s = substring(s, 1, 99999); + rpn_set(s); + tokenize_console(command); + } else if(rpncmd == "intersection") { + // s s2 intersection + s2 = rpn_pop(); + s = rpn_get(); + f = tokenize_console(s); + f2 = tokenize_console(strcat(s, " ", s2)); + // tokens 0..(f-1) represent s + // tokens f..f2 represent s2 + // INTERSECTION: keep only the tokens from s that are also in s2 + s = ""; + for(i = 0; i < f; ++i) { + for(j = f; j < f2; ++j) + if(argv(i) == argv(j)) + { + s = strcat(s, " ", argv(i)); + break; + } + } + if(substring(s, 0, 1) == " ") + s = substring(s, 1, 99999); + rpn_set(s); + tokenize_console(command); + } else if(rpncmd == "difference") { + // s s2 difference + s2 = rpn_pop(); + s = rpn_get(); + f = tokenize_console(s); + f2 = tokenize_console(strcat(s, " ", s2)); + // tokens 0..(f-1) represent s + // tokens f..f2 represent s2 + // DIFFERENCE: keep only the tokens from s that are not in s2 + s = ""; + for(i = 0; i < f; ++i) { + for(j = f; j < f2; ++j) + if(argv(i) == argv(j)) + goto skip_difference; + s = strcat(s, " ", argv(i)); +:skip_difference + } + if(substring(s, 0, 1) == " ") + s = substring(s, 1, 99999); + rpn_set(s); + tokenize_console(command); + } else if(rpncmd == "shuffle") { + // s shuffle + s = rpn_get(); + f = tokenize_console(s); + + for(i = 0; i < f - 1; ++i) { + // move a random item from i..f-1 to position i + s = ""; + f2 = floor(random() * (f - i) + i); + for(j = 0; j < i; ++j) + s = strcat(s, " ", argv(j)); + s = strcat(s, " ", argv(f2)); + for(j = i; j < f; ++j) + if(j != f2) + s = strcat(s, " ", argv(j)); + f = tokenize_console(s); + } + + if(substring(s, 0, 1) == " ") + s = substring(s, 1, 99999); + rpn_set(s); + tokenize_console(command); + } else if(rpncmd == "fexists_assert") { + s = rpn_pop(); + if(!rpn_error) + { + if (!fexists(s)) + { + print("rpn: ERROR: ", s, " does not exist!\n"); + rpn_error = TRUE; + } + } + } else if(rpncmd == "fexists") { + s = rpn_get(); + if(!rpn_error) + { + if (fexists(s)) + rpn_setf(1); + else + rpn_setf(0); + } + } else if(rpncmd == "localtime") { + rpn_set(strftime(TRUE, rpn_get())); + } else if(rpncmd == "gmtime") { + rpn_set(strftime(FALSE, rpn_get())); + } else if(rpncmd == "time") { + rpn_pushf(time); + } else if(rpncmd == "digest") { + s = rpn_pop(); + rpn_set(digest_hex(s, rpn_get())); + } else if(rpncmd == "sprintf1s") { + s = rpn_pop(); + rpn_set(sprintf(s, rpn_get())); + } else { + rpn_push(cvar_string(rpncmd)); + } + if(rpn_error) + break; + } + while(rpn_sp > 0) + { + s = rpn_pop(); + print("rpn: still on stack: ", s, "\n"); + } + return TRUE; + } + } else if(argv(0) == "addtolist") { + if(argc >= 2) + { + s = argv(1); + s2 = argv(2); + if(cvar_string(s) == "") + cvar_set(s, s2); + else { + n = tokenizebyseparator(cvar_string(s), " "); + for(i = 0; i < n; ++i) + if(argv(i) == s2) + return TRUE; // already in list + cvar_set(s, strcat(s2, " ", cvar_string(s))); + } + } + return TRUE; + } + else if(argv(0) == "records") { + print(records_reply); + return TRUE; + } + else if(argv(0) == "ladder") { + print(ladder_reply); + return TRUE; + } + else if(argv(0) == "rankings") { + print(rankings_reply); + return TRUE; +#ifdef MENUQC + } else if(argv(0) == "cp") { + if(argc >= 2) + { + s = argv(1); + for(i = 2; i < argc; ++i) + s = strcat(s, " ", argv(i)); + centerprint(unescape(s)); + } + return TRUE; +#endif + } + + return FALSE; +} diff --git a/qcsrc/common/gamecommand.qc b/qcsrc/common/gamecommand.qc deleted file mode 100644 index 9595ed5c2..000000000 --- a/qcsrc/common/gamecommand.qc +++ /dev/null @@ -1,853 +0,0 @@ -#define MAX_RPN_STACK 16 -float rpn_db; -float rpn_error; -float rpn_sp; -string rpn_stack[MAX_RPN_STACK]; -string rpn_pop() { - if(rpn_sp > 0) { - --rpn_sp; - return rpn_stack[rpn_sp]; - } else { - print("rpn: stack underflow\n"); - rpn_error = TRUE; - return ""; - } -} -void rpn_push(string s) { - if(rpn_sp < MAX_RPN_STACK) { - rpn_stack[rpn_sp] = s; - ++rpn_sp; - } else { - print("rpn: stack overflow\n"); - rpn_error = TRUE; - } -} -string rpn_get() { - if(rpn_sp > 0) { - return rpn_stack[rpn_sp - 1]; - } else { - print("rpn: empty stack\n"); - rpn_error = TRUE; - return ""; - } -} -void rpn_set(string s) { - if(rpn_sp > 0) { - rpn_stack[rpn_sp - 1] = s; - } else { - print("rpn: empty stack\n"); - rpn_error = TRUE; - } -} -float rpn_getf() { return stof(rpn_get()); } -float rpn_popf() { return stof(rpn_pop()); } -void rpn_pushf(float f) { return rpn_push(ftos(f)); } -void rpn_setf(float f) { return rpn_set(ftos(f)); } - -#define NUM_MARKUPS 41 -float markup_init; -string markup_from[NUM_MARKUPS]; -string markup_to[NUM_MARKUPS]; -void GameCommand_MarkupInit() -{ - float i; - if (markup_init) - return; - markup_init = 1; - i = 0; - markup_from[i] = "&alien"; markup_to[i] = "\x12"; ++i; - markup_from[i] = "&:-)"; markup_to[i] = "\x13"; ++i; - markup_from[i] = "&:-("; markup_to[i] = "\x14"; ++i; - markup_from[i] = "&x-P"; markup_to[i] = "\x15"; ++i; - markup_from[i] = "&:-/"; markup_to[i] = "\x16"; ++i; - markup_from[i] = "&:-D"; markup_to[i] = "\x17"; ++i; - markup_from[i] = "&<<"; markup_to[i] = "\x18"; ++i; - markup_from[i] = "&>>"; markup_to[i] = "\x19"; ++i; - markup_from[i] = "&dot"; markup_to[i] = "\x1a"; ++i; - markup_from[i] = "&^_"; markup_to[i] = "\x1b"; ++i; - markup_from[i] = "&ysplat"; markup_to[i] = "\x1c"; ++i; - markup_from[i] = "&-]"; markup_to[i] = "\x1d"; ++i; - markup_from[i] = "&--"; markup_to[i] = "\x1e"; ++i; - markup_from[i] = "&[-"; markup_to[i] = "\x1f"; ++i; - markup_from[i] = "&s<"; markup_to[i] = "\x2c"; ++i; - markup_from[i] = "&s>"; markup_to[i] = "\x2e"; ++i; - markup_from[i] = "&<-"; markup_to[i] = "\x7f"; ++i; - markup_from[i] = "&[="; markup_to[i] = "\x80"; ++i; - markup_from[i] = "&=="; markup_to[i] = "\x81"; ++i; - markup_from[i] = "&=]"; markup_to[i] = "\x82"; ++i; - markup_from[i] = "&r!"; markup_to[i] = "\x84"; ++i; - markup_from[i] = "&|o|"; markup_to[i] = "\x85"; ++i; - markup_from[i] = "&|u|"; markup_to[i] = "\x86"; ++i; - markup_from[i] = "&|i|"; markup_to[i] = "\x87"; ++i; - markup_from[i] = "&|c|"; markup_to[i] = "\x88"; ++i; - markup_from[i] = "&[c]"; markup_to[i] = "\x89"; ++i; - markup_from[i] = "&[n]"; markup_to[i] = "\x8a"; ++i; - markup_from[i] = "&[]"; markup_to[i] = "\x8b"; ++i; - markup_from[i] = "&r?"; markup_to[i] = "\x8c"; ++i; - markup_from[i] = "&|>"; markup_to[i] = "\x8d"; ++i; - markup_from[i] = "&splat0"; markup_to[i] = "\x8e"; ++i; - markup_from[i] = "&splat1"; markup_to[i] = "\x8f"; ++i; - markup_from[i] = "&[["; markup_to[i] = "\x90"; ++i; - markup_from[i] = "&]]"; markup_to[i] = "\x91"; ++i; - markup_from[i] = "&splat2"; markup_to[i] = "\x9a"; ++i; - markup_from[i] = "&)("; markup_to[i] = "\x9b"; ++i; - markup_from[i] = "&splat3"; markup_to[i] = "\x9c"; ++i; - markup_from[i] = "&(."; markup_to[i] = "\x9d"; ++i; - markup_from[i] = "&.."; markup_to[i] = "\x9e"; ++i; - markup_from[i] = "&.)"; markup_to[i] = "\x9f"; ++i; - markup_from[i] = "&<|"; markup_to[i] = "\xff"; ++i; -} - -string GameCommand_Markup(string s2) -{ - float red, ccase, i, j; - string s, s3; - - GameCommand_MarkupInit(); - - s = ""; - - red = 0; - ccase = 0; - for(i = 0; i < strlen(s2); ++i) - { - for(j = 0; j < NUM_MARKUPS; ++j) - { - s3 = substring(s2, i, strlen(markup_from[j])); - if (s3 == markup_from[j]) - { - s = strcat(s, markup_to[j]); - i += strlen(markup_from[j]) - 1; - break; - } - } - - if(j == NUM_MARKUPS) - { - if(substring(s2, i, 2) == "&&") - { - s = strcat(s, strconv(ccase, red, red, "&")); - ++i; - } - else if(substring(s2, i, 2) == "&d") - { - red = 2; - ccase = 0; - ++i; - } - else if(substring(s2, i, 2) == "&a") - { - red = 2; - ccase = 2; - ++i; - } - else if(substring(s2, i, 2) == "&n") - { - red = 0; - ccase = 0; - ++i; - } - else - s = strcat(s, strconv(ccase, red, red, substring(s2, i, 1))); - } - } - - return s; -} - -float GameCommand_Generic(string command) -{ - float argc; - float i, j, f, n; - vector rgb; - string s, s2, c; - argc = tokenize_console(command); - if(argv(0) == "help") - { - print(" rpn EXPRESSION... - a RPN calculator.\n"); - print(" Operator description (x: string, s: set, f: float):\n"); - print(" x pop -----------------------------> : removes the top\n"); - print(" x dup -----------------------------> x x : duplicates the top\n"); - print(" x x exch --------------------------> x x : swap the top two\n"); - print(" /cvarname load --------------------> x : loads a cvar\n"); - print(" /cvarname x def -------------------> : writes to a cvar\n"); - print(" f f add|sub|mul|div|mod|max|min ---> f : adds/... two numbers\n"); - print(" f f eq|ne|gt|ge|lt|le -------------> f : compares two numbers\n"); - print(" f neg|abs|sgn|rand|floor|ceil------> f : negates/... a number\n"); - print(" f f f bound -----------------------> f : bounds the middle number\n"); - print(" f1 f2 b when ----------------------> f : f1 if b, f2 otherwise\n"); - print(" s s union|intersection|difference -> s : set operations\n"); - print(" s shuffle -------------------------> s : randomly arrange elements\n"); - print(" /key /value put -------------------> : set a database key\n"); - print(" /key get --------------------------> s : get a database value\n"); - print(" x dbpush --------------------------> : pushes the top onto the database\n"); - print(" dbpop|dbget -----------------------> x : removes/reads DB's top\n"); - print(" dblen|dbat ------------------------> f : gets the DB's size/cursor pos\n"); - print(" dbclr -----------------------------> : clear the DB\n"); - print(" s dbsave|dbload--------------------> : save/load the DB to/from a file\n"); - print(" x dbins ---------------------------> : moves the top into the DB\n"); - print(" dbext|dbread ----------------------> x : extract/get from the DB's cursor\n"); - print(" f dbmov|dbgoto --------------------> : move or set the DB's cursor\n"); - print(" s localtime -----------------------> s : formats the current local time\n"); - print(" s gmtime --------------------------> s : formats the current UTC time\n"); - print(" time ------------------------------> f : seconds since VM start\n"); - print(" s /MD4 digest ---------------------> s : MD4 digest\n"); - print(" s /SHA256 digest ------------------> s : SHA256 digest\n"); - print(" s /formatstring sprintf1s ---------> s : sprintf with 1 string (pad, cut)\n"); - print(" Set operations operate on 'such''strings'.\n"); - print(" Unknown tokens insert their cvar value.\n"); - print(" maplist add map\n"); - print(" maplist remove map\n"); - print(" maplist shuffle\n"); - print(" maplist cleanup\n"); - print(" maplist maplist\n"); - print(" maplist lsmaps\n"); - print(" maplist lsnewmaps\n"); - print(" addtolist variable addedvalue\n"); - print(" records\n"); - print(" rankings (map argument optional)\n"); - return TRUE; - } - - if(argv(0) == "maplist") - { - if(argv(1) == "add" && argc == 3) - { - if (!fexists(strcat("maps/", argv(2), ".bsp"))) - { - print("maplist: ERROR: ", argv(2), " does not exist!\n"); - return TRUE; - } - if(cvar_string("g_maplist") == "") - cvar_set("g_maplist", argv(2)); - else - cvar_set("g_maplist", strcat(argv(2), " ", cvar_string("g_maplist"))); - return TRUE; - } - else if(argv(1) == "remove" && argc == 3) - { - s = argv(2); - n = tokenizebyseparator(cvar_string("g_maplist"), " "); - s2 = ""; - for(i = 0; i < n; ++i) - if(argv(i) != s) - s2 = strcat(s2, " ", argv(i)); - s2 = substring(s2, 1, strlen(s2) - 1); - cvar_set("g_maplist", s2); - return TRUE; - } - else if(argv(1) == "shuffle" && argc == 2) - { - cvar_set("g_maplist", shufflewords(cvar_string("g_maplist"))); - return TRUE; - } - else if(argv(1) == "cleanup") - { - MapInfo_Enumerate(); - MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); - n = tokenizebyseparator(cvar_string("g_maplist"), " "); - s2 = ""; - for(i = 0; i < n; ++i) - if(MapInfo_CheckMap(argv(i))) - s2 = strcat(s2, " ", argv(i)); - s2 = substring(s2, 1, strlen(s2) - 1); - cvar_set("g_maplist", s2); - return TRUE; - } - else if(argv(1) == "maplist") { - print(maplist_reply); - return TRUE; - } - else if(argv(1) == "lsmaps") { - print(lsmaps_reply); - return TRUE; - } - else if(argv(1) == "lsnewmaps") { - print(lsnewmaps_reply); - return TRUE; - } - } - else if(argc >= 3 && argv(0) == "red") - { - s = substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2)); - localcmd(strcat(argv(1), " ", GameCommand_Markup(s))); - return TRUE; - } - else if(argc >= 3 && crc16(0, argv(0)) == 38566 && crc16(0, strcat(argv(0), argv(0), argv(0))) == 59830) - { - // other test case - s = strconv(2, 0, 0, substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2))); - - n = floor(random() * 6 + 2); - - s2 = ""; - for(i = 0; i < n; ++i) - { - s2 = strcat(s2, "AH"); - } - - if(random() < 0.1) - s2 = strcat(substring(s2, 1, strlen(s2) - 1), "A"); - - if(s == "") - s = s2; - else - if(random() < 0.8) - s = strcat(s, " ", s2); - else - s = strcat(s2, " ", s); - - s2 = substring(s, strlen(s) - 2, 2); - if(s2 == "AH" || s2 == "AY") - s = strcat(s, "))"); - else - s = strcat(s, " ))"); - - if(random() < 0.1) - s = substring(s, 0, strlen(s) - 1); - - if(random() < 0.1) - s = strconv(1, 0, 0, s); - - localcmd(strcat(argv(1), " ", s)); - - return TRUE; - } - else if(argc >= 3 && crc16(0, argv(0)) == 3826 && crc16(0, strcat(argv(0), argv(0), argv(0))) == 55790) - { - // test case for terencehill's color codes - s = strdecolorize(substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2))); - s2 = ""; - - n = strlen(s); - j = ((6 * max(1, floor(strlen(s)/32 + random() * 2 - 1))) / n) * (1 - 2 * (random() > 0.5)); - f = random() * 6; - - for(i = 0; i < n; ++i) - { - c = substring(s, i, 1); - - if(c == ";") - c = ":"; - else if(c == "^") - { - c = "^^"; - if(substring(s, i+1, 1) == "^") - ++i; - } - - if(c != " ") - { - rgb = hsl_to_rgb('1 0 0' * (j * i + f) + '0 1 .5'); - c = strcat(rgb_to_hexcolor(rgb), c); - } - s2 = strcat(s2, c); - } - - localcmd(strcat(argv(1), " ", s2)); - - return TRUE; - } - else if(argv(0) == "rpn") - { - if(!rpn_db) - { - rpn_db = db_create(); - db_put(rpn_db, "stack.pointer", "0"); - db_put(rpn_db, "stack.pos", "-1"); - } - if(argc >= 2) - { - float rpnpos; - string rpncmd; - float f2, f3; - rpn_sp = 0; - rpn_error = FALSE; - for(rpnpos = 1; rpnpos < argc; ++rpnpos) - { - rpncmd = argv(rpnpos); - f = strlen(rpncmd); - if(rpncmd == "") { - } else if(stof(substring(rpncmd, 0, 1)) > 0) { - rpn_push(rpncmd); - } else if(substring(rpncmd, 0, 1) == "0") { - rpn_push(rpncmd); - } else if(f >= 2 && substring(rpncmd, 0, 1) == "+") { - rpn_push(rpncmd); - } else if(f >= 2 && substring(rpncmd, 0, 1) == "-") { - rpn_push(rpncmd); - } else if(f >= 2 && substring(rpncmd, 0, 1) == "/") { - rpn_push(substring(rpncmd, 1, strlen(rpncmd) - 1)); - } else if(rpncmd == "clear") { - rpn_sp = 0; - } else if(rpncmd == "def" || rpncmd == "=") { - s = rpn_pop(); - s2 = rpn_pop(); - - if(s2 != "") - { -#ifdef MENUQC - registercvar(s2, "", 0); -#else - registercvar(s2, ""); -#endif - if(!rpn_error) // don't change cvars if a stack error had happened! - cvar_set(s2, s); - } - else - { - print("rpn: empty cvar name for 'def'\n"); - rpn_error = TRUE; - } - } else if(rpncmd == "defs" || rpncmd == "@") { - s = ""; - i = rpn_popf(); - j = (i == 0); - while(rpn_sp > 1 && (j || i > 0)) - { - s = strcat("/", rpn_pop(), " ", s); - --i; - } - s2 = rpn_pop(); - if(s2 != "") - { -#ifdef MENUQC - registercvar(s2, "", 0); -#else - registercvar(s2, ""); -#endif - if(!rpn_error) // don't change cvars if a stack error had happened! - cvar_set(s2, s); - } - else - { - print("rpn: empty cvar name for 'defs'\n"); - rpn_error = TRUE; - } - } else if(rpncmd == "load") { - rpn_set(cvar_string(rpn_get())); - } else if(rpncmd == "exch") { - s = rpn_pop(); - s2 = rpn_get(); - rpn_set(s); - rpn_push(s2); - } else if(rpncmd == "dup") { - rpn_push(rpn_get()); - } else if(rpncmd == "pop") { - rpn_pop(); - } else if(rpncmd == "add" || rpncmd == "+") { - f = rpn_popf(); - rpn_setf(rpn_getf() + f); - } else if(rpncmd == "sub" || rpncmd == "-") { - f = rpn_popf(); - rpn_setf(rpn_getf() - f); - } else if(rpncmd == "mul" || rpncmd == "*") { - f = rpn_popf(); - rpn_setf(rpn_getf() * f); - } else if(rpncmd == "div" || rpncmd == "/") { - f = rpn_popf(); - rpn_setf(rpn_getf() / f); - } else if(rpncmd == "mod" || rpncmd == "%") { - f = rpn_popf(); - f2 = rpn_getf(); - rpn_setf(f2 - f * floor(f2 / f)); - } else if(rpncmd == "abs") { - rpn_setf(fabs(rpn_getf())); - } else if(rpncmd == "sgn") { - f = rpn_getf(); - if(f < 0) - rpn_set("-1"); - else if(f > 0) - rpn_set("1"); - else - rpn_set("0"); - } else if(rpncmd == "neg" || rpncmd == "~") { - rpn_setf(-rpn_getf()); - } else if(rpncmd == "floor" || rpncmd == "f") { - rpn_setf(floor(rpn_getf())); - } else if(rpncmd == "ceil" || rpncmd == "c") { - rpn_setf(ceil(rpn_getf())); - } else if(rpncmd == "max") { - f = rpn_popf(); - f2 = rpn_getf(); - rpn_setf(max(f2, f)); - } else if(rpncmd == "min") { - f = rpn_popf(); - f2 = rpn_getf(); - rpn_setf(min(f2, f)); - } else if(rpncmd == "bound") { - f = rpn_popf(); - f2 = rpn_popf(); - f3 = rpn_getf(); - rpn_setf(bound(f3, f2, f)); - } else if(rpncmd == "when") { - f = rpn_popf(); - f2 = rpn_popf(); - f3 = rpn_getf(); - if(f) - rpn_setf(f3); - else - rpn_setf(f2); - } else if(rpncmd == ">" || rpncmd == "gt") { - f = rpn_popf(); - rpn_setf(rpn_getf() > f); - } else if(rpncmd == "<" || rpncmd == "lt") { - f = rpn_popf(); - rpn_setf(rpn_getf() < f); - } else if(rpncmd == "==" || rpncmd == "eq") { - f = rpn_popf(); - rpn_setf(rpn_getf() == f); - } else if(rpncmd == ">=" || rpncmd == "ge") { - f = rpn_popf(); - rpn_setf(rpn_getf() >= f); - } else if(rpncmd == "<=" || rpncmd == "le") { - f = rpn_popf(); - rpn_setf(rpn_getf() <= f); - } else if(rpncmd == "!=" || rpncmd == "ne") { - f = rpn_popf(); - rpn_setf(rpn_getf() != f); - } else if(rpncmd == "rand") { - rpn_setf(ceil(random() * rpn_getf()) - 1); - } else if(rpncmd == "crc16") { - rpn_setf(crc16(FALSE, rpn_get())); - } else if(rpncmd == "put") { - s2 = rpn_pop(); - if (!rpn_error) - { - s = rpn_pop(); - if (!rpn_error) - db_put(rpn_db, s, s2); - } - } else if(rpncmd == "get") { - s = rpn_pop(); - if (!rpn_error) - rpn_push(db_get(rpn_db, s)); - } else if(rpncmd == "dbpush") { - s = rpn_pop(); - if(!rpn_error) - { - i = stof(db_get(rpn_db, "stack.pointer")); - db_put(rpn_db, "stack.pointer", ftos(i+1)); - db_put(rpn_db, strcat("stack.", ftos(i)), s); - } - if(!i) - db_put(rpn_db, "stack.pos", "0"); - } else if(rpncmd == "dbpop") { - i = stof(db_get(rpn_db, "stack.pointer")); - if(i) - { - s = ftos(i-1); - db_put(rpn_db, "stack.pointer", s); - rpn_push(db_get(rpn_db, strcat("stack.", s))); - j = stof(db_get(rpn_db, "stack.pos")); - if(j >= i) - db_put(rpn_db, "stack.pos", ftos(i-2)); - } else { - rpn_error = 1; - print("rpn: database underflow\n"); - } - } else if(rpncmd == "dbget") { - - i = stof(db_get(rpn_db, "stack.pointer")); - if(i) - { - rpn_push(db_get(rpn_db, strcat("stack.", ftos(i-1)))); - } else { - rpn_error = 1; - print("rpn: database empty\n"); - } - } else if(rpncmd == "dblen") { - rpn_push(db_get(rpn_db, "stack.pointer")); - } else if(rpncmd == "dbclr") { - db_close(rpn_db); - rpn_db = db_create(); - db_put(rpn_db, "stack.pointer", "0"); - db_put(rpn_db, "stack.pos", "-1"); - } else if(rpncmd == "dbsave") { - s = rpn_pop(); - if(!rpn_error) - db_save(rpn_db, s); - } else if(rpncmd == "dbload") { - s = rpn_pop(); - if(!rpn_error) - { - db_close(rpn_db); - rpn_db = db_load(s); - } - } else if(rpncmd == "dbins") { - s = rpn_pop(); - if(!rpn_error) - //if(rpn_sp > 0) - { - j = stof(db_get(rpn_db, "stack.pointer")); - i = stof(db_get(rpn_db, "stack.pos")); - - if(i < 0) - { - i = 0; - db_put(rpn_db, "stack.pos", "0"); - } - - db_put(rpn_db, "stack.pointer", ftos(j+1)); - for(--j; j >= i; --j) - { - db_put(rpn_db, strcat("stack.", ftos(j+1)), - db_get(rpn_db, (strcat("stack.", ftos(j)))) - ); - } - db_put(rpn_db, strcat("stack.", ftos(i)), s); - } - } else if(rpncmd == "dbext") { - j = stof(db_get(rpn_db, "stack.pointer")); - i = stof(db_get(rpn_db, "stack.pos")); - if(!j) - { - rpn_error = TRUE; - print("rpn: empty database\n"); - } else { - --j; - rpn_push(db_get(rpn_db, strcat("stack.", ftos(i)))); - db_put(rpn_db, "stack.pointer", ftos(j)); - if(i == j) - { - db_put(rpn_db, "stack.pos", ftos(j-1)); - } else { - while(i < j) - { - db_put(rpn_db, strcat("stack.", ftos(i)), - db_get(rpn_db, (strcat("stack.", ftos(i+1)))) - ); - ++i; - } - } - } - } else if(rpncmd == "dbread") { - s = db_get(rpn_db, "stack.pos"); - if(stof(s) >= 0) - { - rpn_push(db_get(rpn_db, strcat("stack.", s))); - } else { - rpn_error = 1; - print("rpn: empty database\n"); - } - } else if(rpncmd == "dbat") { - rpn_push(db_get(rpn_db, "stack.pos")); - } else if(rpncmd == "dbmov") { - j = stof(db_get(rpn_db, "stack.pointer")); - i = stof(db_get(rpn_db, "stack.pos")); - i += rpn_popf(); - if(!rpn_error) - { - if(i < 0 || i >= j) - { - print("rpn: database cursor out of bounds\n"); - rpn_error = TRUE; - } - if(!rpn_error) - { - db_put(rpn_db, "stack.pos", ftos(i)); - } - } - } else if(rpncmd == "dbgoto") { - s = rpn_pop(); - j = stof(db_get(rpn_db, "stack.pointer")); - if(!j) - { - rpn_error = TRUE; - print("rpn: empty database, cannot move cursor\n"); - } - if(!rpn_error) - { - if(s == "end") - i = stof(db_get(rpn_db, "stack.pointer"))-1; - else if(s == "beg") - i = 0; - else - i = stof(s); - - j = stof(db_get(rpn_db, "stack.pointer")); - if(i < 0 || i >= j) - { - print("rpn: database cursor destination out of bounds\n"); - rpn_error = TRUE; - } - if(!rpn_error) - { - db_put(rpn_db, "stack.pos", ftos(i)); - } - } - } else if(rpncmd == "union") { - // s s2 union - s2 = rpn_pop(); - s = rpn_get(); - f = tokenize_console(s); - f2 = tokenize_console(strcat(s, " ", s2)); - // tokens 0..(f-1) represent s - // tokens f..f2 represent s2 - // UNION: add all tokens to s that are in s2 but not in s - s = ""; - for(i = 0; i < f; ++i) - s = strcat(s, " ", argv(i)); - for(i = f; i < f2; ++i) { - for(j = 0; j < f; ++j) - if(argv(i) == argv(j)) - goto skip_union; - s = strcat(s, " ", argv(i)); -:skip_union - } - if(substring(s, 0, 1) == " ") - s = substring(s, 1, 99999); - rpn_set(s); - tokenize_console(command); - } else if(rpncmd == "intersection") { - // s s2 intersection - s2 = rpn_pop(); - s = rpn_get(); - f = tokenize_console(s); - f2 = tokenize_console(strcat(s, " ", s2)); - // tokens 0..(f-1) represent s - // tokens f..f2 represent s2 - // INTERSECTION: keep only the tokens from s that are also in s2 - s = ""; - for(i = 0; i < f; ++i) { - for(j = f; j < f2; ++j) - if(argv(i) == argv(j)) - { - s = strcat(s, " ", argv(i)); - break; - } - } - if(substring(s, 0, 1) == " ") - s = substring(s, 1, 99999); - rpn_set(s); - tokenize_console(command); - } else if(rpncmd == "difference") { - // s s2 difference - s2 = rpn_pop(); - s = rpn_get(); - f = tokenize_console(s); - f2 = tokenize_console(strcat(s, " ", s2)); - // tokens 0..(f-1) represent s - // tokens f..f2 represent s2 - // DIFFERENCE: keep only the tokens from s that are not in s2 - s = ""; - for(i = 0; i < f; ++i) { - for(j = f; j < f2; ++j) - if(argv(i) == argv(j)) - goto skip_difference; - s = strcat(s, " ", argv(i)); -:skip_difference - } - if(substring(s, 0, 1) == " ") - s = substring(s, 1, 99999); - rpn_set(s); - tokenize_console(command); - } else if(rpncmd == "shuffle") { - // s shuffle - s = rpn_get(); - f = tokenize_console(s); - - for(i = 0; i < f - 1; ++i) { - // move a random item from i..f-1 to position i - s = ""; - f2 = floor(random() * (f - i) + i); - for(j = 0; j < i; ++j) - s = strcat(s, " ", argv(j)); - s = strcat(s, " ", argv(f2)); - for(j = i; j < f; ++j) - if(j != f2) - s = strcat(s, " ", argv(j)); - f = tokenize_console(s); - } - - if(substring(s, 0, 1) == " ") - s = substring(s, 1, 99999); - rpn_set(s); - tokenize_console(command); - } else if(rpncmd == "fexists_assert") { - s = rpn_pop(); - if(!rpn_error) - { - if (!fexists(s)) - { - print("rpn: ERROR: ", s, " does not exist!\n"); - rpn_error = TRUE; - } - } - } else if(rpncmd == "fexists") { - s = rpn_get(); - if(!rpn_error) - { - if (fexists(s)) - rpn_setf(1); - else - rpn_setf(0); - } - } else if(rpncmd == "localtime") { - rpn_set(strftime(TRUE, rpn_get())); - } else if(rpncmd == "gmtime") { - rpn_set(strftime(FALSE, rpn_get())); - } else if(rpncmd == "time") { - rpn_pushf(time); - } else if(rpncmd == "digest") { - s = rpn_pop(); - rpn_set(digest_hex(s, rpn_get())); - } else if(rpncmd == "sprintf1s") { - s = rpn_pop(); - rpn_set(sprintf(s, rpn_get())); - } else { - rpn_push(cvar_string(rpncmd)); - } - if(rpn_error) - break; - } - while(rpn_sp > 0) - { - s = rpn_pop(); - print("rpn: still on stack: ", s, "\n"); - } - return TRUE; - } - } else if(argv(0) == "addtolist") { - if(argc >= 2) - { - s = argv(1); - s2 = argv(2); - if(cvar_string(s) == "") - cvar_set(s, s2); - else { - n = tokenizebyseparator(cvar_string(s), " "); - for(i = 0; i < n; ++i) - if(argv(i) == s2) - return TRUE; // already in list - cvar_set(s, strcat(s2, " ", cvar_string(s))); - } - } - return TRUE; - } - else if(argv(0) == "records") { - print(records_reply); - return TRUE; - } - else if(argv(0) == "ladder") { - print(ladder_reply); - return TRUE; - } - else if(argv(0) == "rankings") { - print(rankings_reply); - return TRUE; -#ifdef MENUQC - } else if(argv(0) == "cp") { - if(argc >= 2) - { - s = argv(1); - for(i = 2; i < argc; ++i) - s = strcat(s, " ", argv(i)); - centerprint(unescape(s)); - } - return TRUE; -#endif - } - - return FALSE; -} diff --git a/qcsrc/menu/command/menu_cmd.qc b/qcsrc/menu/command/menu_cmd.qc new file mode 100644 index 000000000..ea2e4034e --- /dev/null +++ b/qcsrc/menu/command/menu_cmd.qc @@ -0,0 +1,193 @@ +void GameCommand_Init() +{ + // make gg call menu QC theCommands + localcmd("alias qc_cmd \"menu_cmd $*\"\n"); +} + +string _dumptree_space; +void _dumptree_open(entity pass, entity me) +{ + string s; + s = me.toString(me); + if(s == "") + s = me.classname; + else + s = strcat(me.classname, ": ", s); + print(_dumptree_space, etos(me), " (", s, ")"); + if(me.firstChild) + { + print(" {\n"); + _dumptree_space = strcat(_dumptree_space, " "); + } + else + print("\n"); +} +void _dumptree_close(entity pass, entity me) +{ + if(me.firstChild) + { + _dumptree_space = substring(_dumptree_space, 0, strlen(_dumptree_space) - 2); + print(_dumptree_space, "}\n"); + } +} + +float curl_uri_get_pos; +float curl_uri_get_exec[URI_GET_CURL_END - URI_GET_CURL + 1]; +string curl_uri_get_cvar[URI_GET_CURL_END - URI_GET_CURL + 1]; +void Curl_URI_Get_Callback(float id, float status, string data) +{ + float i; + float do_exec; + string do_cvar; + i = id - URI_GET_CURL; + do_exec = curl_uri_get_exec[i]; + do_cvar = curl_uri_get_cvar[i]; + if(status != 0) + { + print(sprintf(_("error: status is %d\n"), status)); + if(do_cvar) + strunzone(do_cvar); + return; + } + if(do_exec) + localcmd(data); + if(do_cvar) + { + cvar_set(do_cvar, data); + strunzone(do_cvar); + } + if(!do_exec && !do_cvar) + print(data); +} + +void GameCommand(string theCommand) +{ + float argc; + argc = tokenize_console(theCommand); + + if(argv(0) == "help" || argc == 0) + { + print(_("Usage: menu_cmd command..., where possible commands are:\n")); + print(_(" sync - reloads all cvars on the current menu page\n")); + print(_(" directmenu ITEM - select a menu item as main item\n")); + GameCommand_Generic("help"); + return; + } + + if(GameCommand_Generic(theCommand)) + return; + + if(argv(0) == "sync") + { + m_sync(); + return; + } + + if(argv(0) == "directmenu") if(argc == 2) + { + // switch to a menu item + if(!isdemo()) // don't allow this command in demos + m_goto(argv(1)); + return; + } + + if(argv(0) == "directpanelhudmenu") + { + // switch to a menu item + m_goto(strcat("HUD", argv(1))); + return; + } + + if(argv(0) == "skinselect") + { + m_goto_skin_selector(); + return; + } + + if(argv(0) == "languageselect") + { + m_goto_language_selector(); + return; + } + + if(argv(0) == "videosettings") + { + m_goto_video_settings(); + return; + } + + if(argv(0) == "dumptree") + { + _dumptree_space = ""; + depthfirst(main, parent, firstChild, nextSibling, _dumptree_open, _dumptree_close, NULL); + return; + } + + if(argv(0) == "curl") + { + float do_exec; + string do_cvar; + float key; + float i, j; + string url; + float buf; + float r; + + do_exec = FALSE; + do_cvar = string_null; + key = -1; + + for(i = 1; i+1 < argc; ++i) + { + if(argv(i) == "--cvar" && i+2 < argc) + { + ++i; + do_cvar = strzone(argv(i)); + continue; + } + if(argv(i) == "--exec") + { + do_exec = TRUE; + continue; + } + if(argv(i) == "--key" && i+2 < argc) + { + ++i; + key = stof(argv(i)); + continue; + } + break; + } + + // now, argv(i) is the URL + // following args may be POST parameters + url = argv(i); + ++i; + buf = buf_create(); + j = 0; + for(; i+1 < argc; i += 2) + bufstr_set(buf, ++j, sprintf("%s=%s", uri_escape(argv(i)), uri_escape(argv(i+1)))); + if(i < argc) + bufstr_set(buf, ++j, sprintf("submit=%s", uri_escape(argv(i)))); + + if(j == 0) // no args: GET + r = crypto_uri_postbuf(url, URI_GET_CURL + curl_uri_get_pos, string_null, string_null, -1, key); + else // with args: POST + r = crypto_uri_postbuf(url, URI_GET_CURL + curl_uri_get_pos, "application/x-www-form-urlencoded", "&", buf, key); + + if(r) + { + curl_uri_get_exec[curl_uri_get_pos] = do_exec; + curl_uri_get_cvar[curl_uri_get_pos] = do_cvar; + curl_uri_get_pos = mod(curl_uri_get_pos + 1, URI_GET_CURL_END - URI_GET_CURL + 1); + } + else + print(_("error creating curl handle\n")); + + buf_del(buf); + + return; + } + + print(_("Invalid command. For a list of supported commands, try menu_cmd help.\n")); +} diff --git a/qcsrc/menu/command/menu_cmd.qh b/qcsrc/menu/command/menu_cmd.qh new file mode 100644 index 000000000..33eb05371 --- /dev/null +++ b/qcsrc/menu/command/menu_cmd.qh @@ -0,0 +1,2 @@ +void GameCommand_Init(); +void GameCommand(string command); diff --git a/qcsrc/menu/gamecommand.qc b/qcsrc/menu/gamecommand.qc deleted file mode 100644 index ea2e4034e..000000000 --- a/qcsrc/menu/gamecommand.qc +++ /dev/null @@ -1,193 +0,0 @@ -void GameCommand_Init() -{ - // make gg call menu QC theCommands - localcmd("alias qc_cmd \"menu_cmd $*\"\n"); -} - -string _dumptree_space; -void _dumptree_open(entity pass, entity me) -{ - string s; - s = me.toString(me); - if(s == "") - s = me.classname; - else - s = strcat(me.classname, ": ", s); - print(_dumptree_space, etos(me), " (", s, ")"); - if(me.firstChild) - { - print(" {\n"); - _dumptree_space = strcat(_dumptree_space, " "); - } - else - print("\n"); -} -void _dumptree_close(entity pass, entity me) -{ - if(me.firstChild) - { - _dumptree_space = substring(_dumptree_space, 0, strlen(_dumptree_space) - 2); - print(_dumptree_space, "}\n"); - } -} - -float curl_uri_get_pos; -float curl_uri_get_exec[URI_GET_CURL_END - URI_GET_CURL + 1]; -string curl_uri_get_cvar[URI_GET_CURL_END - URI_GET_CURL + 1]; -void Curl_URI_Get_Callback(float id, float status, string data) -{ - float i; - float do_exec; - string do_cvar; - i = id - URI_GET_CURL; - do_exec = curl_uri_get_exec[i]; - do_cvar = curl_uri_get_cvar[i]; - if(status != 0) - { - print(sprintf(_("error: status is %d\n"), status)); - if(do_cvar) - strunzone(do_cvar); - return; - } - if(do_exec) - localcmd(data); - if(do_cvar) - { - cvar_set(do_cvar, data); - strunzone(do_cvar); - } - if(!do_exec && !do_cvar) - print(data); -} - -void GameCommand(string theCommand) -{ - float argc; - argc = tokenize_console(theCommand); - - if(argv(0) == "help" || argc == 0) - { - print(_("Usage: menu_cmd command..., where possible commands are:\n")); - print(_(" sync - reloads all cvars on the current menu page\n")); - print(_(" directmenu ITEM - select a menu item as main item\n")); - GameCommand_Generic("help"); - return; - } - - if(GameCommand_Generic(theCommand)) - return; - - if(argv(0) == "sync") - { - m_sync(); - return; - } - - if(argv(0) == "directmenu") if(argc == 2) - { - // switch to a menu item - if(!isdemo()) // don't allow this command in demos - m_goto(argv(1)); - return; - } - - if(argv(0) == "directpanelhudmenu") - { - // switch to a menu item - m_goto(strcat("HUD", argv(1))); - return; - } - - if(argv(0) == "skinselect") - { - m_goto_skin_selector(); - return; - } - - if(argv(0) == "languageselect") - { - m_goto_language_selector(); - return; - } - - if(argv(0) == "videosettings") - { - m_goto_video_settings(); - return; - } - - if(argv(0) == "dumptree") - { - _dumptree_space = ""; - depthfirst(main, parent, firstChild, nextSibling, _dumptree_open, _dumptree_close, NULL); - return; - } - - if(argv(0) == "curl") - { - float do_exec; - string do_cvar; - float key; - float i, j; - string url; - float buf; - float r; - - do_exec = FALSE; - do_cvar = string_null; - key = -1; - - for(i = 1; i+1 < argc; ++i) - { - if(argv(i) == "--cvar" && i+2 < argc) - { - ++i; - do_cvar = strzone(argv(i)); - continue; - } - if(argv(i) == "--exec") - { - do_exec = TRUE; - continue; - } - if(argv(i) == "--key" && i+2 < argc) - { - ++i; - key = stof(argv(i)); - continue; - } - break; - } - - // now, argv(i) is the URL - // following args may be POST parameters - url = argv(i); - ++i; - buf = buf_create(); - j = 0; - for(; i+1 < argc; i += 2) - bufstr_set(buf, ++j, sprintf("%s=%s", uri_escape(argv(i)), uri_escape(argv(i+1)))); - if(i < argc) - bufstr_set(buf, ++j, sprintf("submit=%s", uri_escape(argv(i)))); - - if(j == 0) // no args: GET - r = crypto_uri_postbuf(url, URI_GET_CURL + curl_uri_get_pos, string_null, string_null, -1, key); - else // with args: POST - r = crypto_uri_postbuf(url, URI_GET_CURL + curl_uri_get_pos, "application/x-www-form-urlencoded", "&", buf, key); - - if(r) - { - curl_uri_get_exec[curl_uri_get_pos] = do_exec; - curl_uri_get_cvar[curl_uri_get_pos] = do_cvar; - curl_uri_get_pos = mod(curl_uri_get_pos + 1, URI_GET_CURL_END - URI_GET_CURL + 1); - } - else - print(_("error creating curl handle\n")); - - buf_del(buf); - - return; - } - - print(_("Invalid command. For a list of supported commands, try menu_cmd help.\n")); -} diff --git a/qcsrc/menu/gamecommand.qh b/qcsrc/menu/gamecommand.qh deleted file mode 100644 index 33eb05371..000000000 --- a/qcsrc/menu/gamecommand.qh +++ /dev/null @@ -1,2 +0,0 @@ -void GameCommand_Init(); -void GameCommand(string command);