Downloads containing chatbinds.mut

Downloads
Name Author Game Mode Rating
JJ2+ Only: ChatBindsFeatured Download juanpablo123 Mutator 9.5 Download file

File preview

  1. #pragma name "ChatBinds"
  2.  
  3. /*
  4.         ChatBinds mutator by Headshot / juanpablo123
  5.         A simple, yet powerful mutator that allows players to essentially "bind"
  6.         chat commands to their keys for fast access.
  7.  
  8.         Features three different binding modes: !bind, !bindtoggle, and !bindtoggle2.
  9.  
  10.         !bind: This binds a command to a specified key. Simplest option.
  11.         ex. !bind k !k
  12.  
  13.         !bindtoggle: Allows binding a chat command that requires an on/off
  14.         parameter.
  15.         ex. !bindtoggle p /spectate
  16.  
  17.         !bindtoggle2: Allows binding two off/on chat commands (in that order) that
  18.         toggle one option.
  19.         ex. !bindtoggle2 o /stop /start
  20.        
  21.         You are also able to bind, but not limited to, keys from F1 to F24
  22.         (does anyone even have such function keys that high?) or even the numpad keys.
  23.        
  24.         Your binds are saved, so they will work on any server that uses this mutator.
  25. */
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32. /*
  33.         source for key names from below:
  34.         https://docs.microsoft.com/es-es/windows/win32/inputdev/virtual-key-codes
  35. */
  36.  
  37. dictionary keyNames = {
  38.         {"backspace", 0x08},
  39.         {"tab", 0x09},
  40.         {"clear", 0x0c},
  41.         {"enter", 0x0d},
  42.         {"return", 0x0d},
  43.         {"shift", 0x10},
  44.         {"ctrl", 0x11},
  45.         {"control", 0x11},
  46.         {"alt", 0x12},
  47.         {"menu", 0x12},
  48.         {"pause", 0x13},
  49.         {"capslock", 0x14},
  50.         {"esc", 0x1b},
  51.         {"escape", 0x1b},
  52.         {"space", 0x20},
  53.         {"pgup", 0x21},
  54.         {"pageup", 0x21},
  55.         {"pgdn", 0x22},
  56.         {"pgdown", 0x22},
  57.         {"pagedown", 0x22},
  58.         {"end", 0x23},
  59.         {"home", 0x24},
  60.         {"left", 0x25},
  61.         {"up", 0x26},
  62.         {"right", 0x27},
  63.         {"down", 0x28},
  64.         {"select", 0x29},
  65.         {"printscreen", 0x2c},
  66.         {"prntscrn", 0x2c},
  67.         {"printscrn", 0x2c},
  68.         {"snapshot", 0x2c},
  69.         {"ins", 0x2d},
  70.         {"insert", 0x2d},
  71.         {"del", 0x2e},
  72.         {"delete", 0x2e},
  73.         {"1", 0x31},
  74.         {"2", 0x32},
  75.         {"3", 0x33},
  76.         {"4", 0x34},
  77.         {"5", 0x35},
  78.         {"6", 0x36},
  79.         {"7", 0x37},
  80.         {"8", 0x38},
  81.         {"9", 0x39},
  82.         {"0", 0x30},
  83.         {"a", 0x41},
  84.         {"b", 0x42},
  85.         {"c", 0x43},
  86.         {"d", 0x44},
  87.         {"e", 0x45},
  88.         {"f", 0x46},
  89.         {"g", 0x47},
  90.         {"h", 0x48},
  91.         {"i", 0x49},
  92.         {"j", 0x4a},
  93.         {"k", 0x4b},
  94.         {"l", 0x4c},
  95.         {"m", 0x4d},
  96.         {"n", 0x4e},
  97.         {"o", 0x4f},
  98.         {"p", 0x50},
  99.         {"q", 0x51},
  100.         {"r", 0x52},
  101.         {"s", 0x53},
  102.         {"t", 0x54},
  103.         {"u", 0x55},
  104.         {"v", 0x56},
  105.         {"w", 0x57},
  106.         {"x", 0x58},
  107.         {"y", 0x59},
  108.         {"z", 0x5a},
  109.         {"lmeta", 0x5b},
  110.         {"lwin", 0x5b},
  111.         {"rmeta", 0x5c},
  112.         {"rwin", 0x5c},
  113.         {"apps", 0x5d},
  114.         {"numpad0", 0x60},
  115.         {"numpad_0", 0x60},
  116.         {"numpad_ins", 0x60},
  117.         {"numpad_insert", 0x60},
  118.         {"numpad1", 0x61},
  119.         {"numpad_1", 0x61},
  120.         {"numpad_end", 0x61},
  121.         {"numpad2", 0x62},
  122.         {"numpad_2", 0x62},
  123.         {"numpad_dn", 0x62},
  124.         {"numpad_down", 0x62},
  125.         {"numpad3", 0x63},
  126.         {"numpad_3", 0x63},
  127.         {"numpad_pgdn", 0x63},
  128.         {"numpad_pagedn", 0x63},
  129.         {"numpad_pagedown", 0x63},
  130.         {"numpad4", 0x64},
  131.         {"numpad_4", 0x64},
  132.         {"numpad_left", 0x64},
  133.         {"numpad5", 0x65},
  134.         {"numpad_5", 0x65},
  135.         {"numpad6", 0x66},
  136.         {"numpad_6", 0x66},
  137.         {"numpad_right", 0x66},
  138.         {"numpad7", 0x67},
  139.         {"numpad_7", 0x67},
  140.         {"numpad_home", 0x67},
  141.         {"numpad8", 0x68},
  142.         {"numpad_8", 0x68},
  143.         {"numpad_up", 0x68},
  144.         {"numpad9", 0x69},
  145.         {"numpad_9", 0x69},
  146.         {"numpad_pgup", 0x69},
  147.         {"numpad_pageup", 0x69},
  148.         {"numpad_multiply", 0x6a},
  149.         {"numpad_asterisk", 0x6a},
  150.         {"numpad_add", 0x6b},
  151.         {"numpad_plus", 0x6b},
  152.         {"numpad_sub", 0x6d},
  153.         {"numpad_substract", 0x6d},
  154.         {"numpad_minus", 0x6d},
  155.         {"numpad_dot", 0x6e},
  156.         {"numpad_period", 0x6e},
  157.         {"numpad_decimal", 0x6e},
  158.         {"numpad_del", 0x6e},
  159.         {"numpad_delete", 0x6e},
  160.         {"numpad_divide", 0x6f},
  161.         {"numpad_div", 0x6f},
  162.         {"numpad_slash", 0x6f},
  163.         {"f1", 0x70},
  164.         {"f2", 0x71},
  165.         {"f3", 0x72},
  166.         {"f4", 0x73},
  167.         {"f5", 0x74},
  168.         {"f6", 0x75},
  169.         {"f7", 0x76},
  170.         {"f8", 0x77},
  171.         {"f9", 0x78},
  172.         {"f10", 0x79},
  173.         {"f11", 0x7a},
  174.         {"f12", 0x7b},
  175.         {"f13", 0x7c},
  176.         {"f14", 0x7d},
  177.         {"f15", 0x7e},
  178.         {"f16", 0x7f},
  179.         {"f17", 0x80},
  180.         {"f18", 0x81},
  181.         {"f19", 0x82},
  182.         {"f20", 0x83},
  183.         {"f21", 0x84},
  184.         {"f22", 0x85},
  185.         {"f23", 0x86},
  186.         {"f24", 0x87},
  187.         {"numlock", 0x90},
  188.         {"scroll", 0x91},
  189.         {"scrollock", 0x91},
  190.         {"scrolllock", 0x91},
  191.         {"scroll_lock", 0x91},
  192.         {"scrll", 0x91},
  193.         {"lshift", 0xa0},
  194.         {"rshift", 0xa1},
  195.         {"lctrl", 0xa2},
  196.         {"lcontrol", 0xa2},
  197.         {"rctrl", 0xa3},
  198.         {"rcontrol", 0xa3},
  199.         {"lmenu", 0xa4},
  200.         {"lalt", 0xa4},
  201.         {"rmenu", 0xa5},
  202.         {"ralt", 0xa5},
  203.         {"back", 0xa6},
  204.         {"browser_back", 0xa6},
  205.         {"forward", 0xa7},
  206.         {"browser_forward", 0xa7},
  207.         {"next", 0xa7},
  208.         {"browser_next", 0xa7},
  209.         {"refresh", 0xa8},
  210.         {"browser_refresh", 0xa8},
  211.         {"browser_stop", 0xa9},
  212.         {"search", 0xaa},
  213.         {"browser_search", 0xaa},
  214.         {"favorites", 0xab},
  215.         {"browser_favorites", 0xab},
  216.         {"browser_home", 0xac},
  217.         {"vol_mute", 0xad},
  218.         {"volume_mute", 0xad},
  219.         {"mute", 0xad},
  220.         {"vol_dn", 0xae},
  221.         {"volume_dn", 0xae},
  222.         {"vol_down", 0xae},
  223.         {"volume_down", 0xae},
  224.         {"vol_up", 0xaf},
  225.         {"volume_up", 0xaf},
  226.         {"media_next", 0xb0},
  227.         {"media_prev", 0xb1},
  228.         {"media_back", 0xb1},
  229.         {"media_stop", 0xb2},
  230.         {"media_playpause", 0xb3},
  231.         {"media_play_pause", 0xb3},
  232.         {"media_play", 0xb3},
  233.         {"media_pause", 0xb3},
  234.         {"launch_mail", 0xb4},
  235.         {"launch_media_select", 0xb5},
  236.         {"launch_app1", 0xb6},
  237.         {"launch_app2", 0xb7},
  238.         {"semicolon", 0xba},
  239.         {";", 0xba},
  240.         {":", 0xba},
  241.         {"plus", 0xbb},
  242.         {"+", 0xbb},
  243.         {"comma", 0xbc},
  244.         {",", 0xbc},
  245.         {"minus", 0xbd},
  246.         {"-", 0xbd},
  247.         {"period", 0xbe},
  248.         {"dot", 0xbe},
  249.         {".", 0xbe},
  250.         {"question", 0xbf},
  251.         {"?", 0xbf},
  252.         {"slash", 0xbf},
  253.         {"/", 0xbf},
  254.         {"tilde", 0xc0},
  255.         {"~", 0xc0},
  256.         {"grave_accent", 0xc0},
  257.         {"graveaccent", 0xc0},
  258.         {"grave", 0xc0},
  259.         {"`", 0xc0},
  260.         {"[", 0xdb},
  261.         {"{", 0xdb},
  262.         {"\\", 0xdc},
  263.         {"|", 0xdc},
  264.         {"}", 0xdd},
  265.         {"]", 0xdd},
  266.         {"\"", 0xde},
  267.         {"'", 0xde},
  268.         {"quote", 0xde}
  269. };
  270.  
  271. enum TOGGLETYPES
  272. {
  273.         TOGGLE_NONE,
  274.         TOGGLE_ON_OFF,
  275.         TOGGLE_TWO_CMDS,
  276.        
  277.         BIND_LENGTH=0xde+1
  278. };
  279.  
  280. array<string> binds(BIND_LENGTH, "");
  281. array<bool> pressed(BIND_LENGTH, false);
  282. array<array<int>> isToggle(BIND_LENGTH, array<int> = {TOGGLE_NONE, 0}); // {toggle type, on/off toggle itself}
  283. array<array<string>> toggleCmds(BIND_LENGTH, array<string> = {"", ""}); // for TOGGLE_TWO_CMDS, the two commands used for toggling something (ex. {"/stop", "/start"})
  284.  
  285. void onLevelBegin()
  286. {
  287.         jjSTREAM tutorial("chatbinds_tut.asdat");
  288.         jjSTREAM binds_file("my_chatbinds.asdat");
  289.  
  290.         if (tutorial.isEmpty())
  291.         {
  292.                 jjAlert("Welcome to ChatBinds!");
  293.                 jjAlert("To get started, use the !bind, !bindtoggle, !bindtoggle2 and !unbind commands.");
  294.                 tutorial.push(0);
  295.                 tutorial.save("chatbinds_tut.asdat");
  296.         }
  297.         if (binds_file.isEmpty()) return; // file doesn't exist or has nothing
  298.  
  299.         for (uint i=0x00; i<BIND_LENGTH; i++)
  300.         {
  301.                 string bind, togglecmd_1, togglecmd_2;
  302.                 bool has_togglecmds;
  303.                 int toggle;
  304.                 binds_file.pop(bind);
  305.                 binds_file.pop(toggle);
  306.                 binds_file.pop(has_togglecmds);
  307.                 if (has_togglecmds)
  308.                 {
  309.                         binds_file.pop(togglecmd_1);
  310.                         binds_file.pop(togglecmd_2);
  311.                 }
  312.                 binds[i] = bind;
  313.                 isToggle[i][0] = toggle;
  314.                 toggleCmds[i] = array<string> = {togglecmd_1, togglecmd_2};
  315.         }
  316. }
  317.  
  318. void saveBinds()
  319. {
  320.         jjSTREAM binds_file;
  321.  
  322.         for (uint i=0x00; i<BIND_LENGTH; i++)
  323.         {
  324.                 binds_file.push(binds[i]);
  325.                 binds_file.push(isToggle[i][0]);
  326.                 if (not toggleCmds[i][0].isEmpty())
  327.                 {
  328.                         binds_file.push(true);
  329.                         binds_file.push(toggleCmds[i][0]);
  330.                         binds_file.push(toggleCmds[i][1]);
  331.                 }
  332.                 else
  333.                         binds_file.push(false);
  334.         }
  335.        
  336.         binds_file.save("my_chatbinds.asdat");
  337. }
  338.  
  339. bool onLocalChat(string &in chatmsg, CHAT::Type chatType)
  340. {
  341.         array<string> cmdargs = chatmsg.split(" ");
  342.         string cmd = cmdargs[0];
  343.         cmdargs.removeAt(0);
  344.        
  345.         if (cmd == "!bind")
  346.         {
  347.                 if (cmdargs.isEmpty())
  348.                 {
  349.                         jjAlert("Usage: !bind <key> [chat message or command]");
  350.                         jjAlert("Leave out the second argument to display what command the key is bound to.");
  351.                         jjAlert("Example: ||!bind k !k ||||||or ||!bind k");
  352.                 }
  353.                 else
  354.                 {
  355.                         string key = cmdargs[0];
  356.                         if (keyNames.exists(key))
  357.                         {
  358.                                 uint keyInd = uint(keyNames[key]);
  359.                                 if (cmdargs.length() >= 2)
  360.                                 {
  361.                                         cmdargs.removeAt(0);
  362.                                         string cmd_bind = join(cmdargs, " ");
  363.  
  364.                                         binds[keyInd] = cmd_bind;
  365.                                         isToggle[keyInd] = array<int> = {TOGGLE_NONE, 0};
  366.                                         toggleCmds[keyInd] = array<string> = {"", ""};
  367.  
  368.                                         jjAlert("Bound key ||"+key+" ||||||to ||"+cmd_bind);
  369.                                         saveBinds();
  370.                                 }
  371.                                 else
  372.                                 {
  373.                                         if (not binds[keyInd].isEmpty() and isToggle[keyInd][0] == TOGGLE_ON_OFF)
  374.                                                 jjAlert("||"+key+" ||||||is bound to a toggle: ||"+binds[keyInd]+" on/off");
  375.                                         else if (not binds[keyInd].isEmpty())
  376.                                                 jjAlert("||"+key+" ||||||is bound to ||"+binds[keyInd]);
  377.                                         else if (not toggleCmds[keyInd][0].isEmpty())
  378.                                                 jjAlert("||"+key+" ||||||is bound to a toggle: ||"+toggleCmds[keyInd][0]+" ||||||and ||"+toggleCmds[keyInd][1]);
  379.                                         else
  380.                                                 jjAlert("||"+key+" ||||||is not bound");
  381.                                 }
  382.                         }
  383.                         else
  384.                                 jjAlert("|Invalid key '"+key+" '");
  385.                 }
  386.                 return true;
  387.         }
  388.        
  389.         else if (cmd == "!bindtoggle")
  390.         {
  391.                 if (cmdargs.isEmpty())
  392.                 {
  393.                         jjAlert("Usage: !bindtoggle <key> [chat message or command]");
  394.                         jjAlert("A special command to bind on/off commands to keys.");
  395.                         jjAlert("Example: !bind p /spectate");
  396.                 }
  397.                 else
  398.                 {
  399.                         string key = cmdargs[0];
  400.                         if (keyNames.exists(key))
  401.                         {
  402.                                 uint keyInd = uint(keyNames[key]);
  403.                                 if (cmdargs.length() >= 2)
  404.                                 {
  405.                                         cmdargs.removeAt(0);
  406.                                         string cmd_bind = join(cmdargs, " ");
  407.  
  408.                                         binds[keyInd] = cmd_bind;
  409.                                         isToggle[keyInd] = array<int> = {TOGGLE_ON_OFF, 0};
  410.                                         toggleCmds[keyInd] = array<string> = {"", ""};
  411.  
  412.                                         jjAlert("(Toggle) bound key ||"+key+" ||||||to ||"+cmd_bind+" on/off");
  413.                                         saveBinds();
  414.                                 }
  415.                                 else
  416.                                 {
  417.                                         if (not binds[keyInd].isEmpty() and isToggle[keyInd][0] == TOGGLE_ON_OFF)
  418.                                                 jjAlert("||"+key+" ||||||is bound to a toggle: ||"+binds[keyInd]+" on/off");
  419.                                         else if (not binds[keyInd].isEmpty())
  420.                                                 jjAlert("||"+key+" ||||||is bound to ||"+binds[keyInd]);
  421.                                         else if (not toggleCmds[keyInd][0].isEmpty())
  422.                                                 jjAlert("||"+key+" ||||||is bound to a toggle: ||"+toggleCmds[keyInd][0]+" ||||||and ||"+toggleCmds[keyInd][1]);
  423.                                         else
  424.                                                 jjAlert("||"+key+" ||||||is not bound");
  425.                                 }
  426.                         }
  427.                         else
  428.                                 jjAlert("|Invalid key '"+key+" '");
  429.                 }
  430.                 return true;
  431.         }
  432.        
  433.         else if (cmd == "!bindtoggle2")
  434.         {
  435.                 if (cmdargs.isEmpty())
  436.                 {
  437.                         jjAlert("Usage: !bindtoggle2 <key> <OFF command> <ON command>");
  438.                         jjAlert("Like !bindtoggle, but uses two commands to toggle something.");
  439.                         jjAlert("Example: !bind p /stop /start");
  440.                 }
  441.                 else
  442.                 {
  443.                         string key = cmdargs[0];
  444.                         if (keyNames.exists(key))
  445.                         {
  446.                                 uint keyInd = uint(keyNames[key]);
  447.                                 if (cmdargs.length() >= 3)
  448.                                 {
  449.                                         string on_cmd = cmdargs[1];
  450.                                         string off_cmd = cmdargs[2];
  451.  
  452.                                         isToggle[keyInd] = array<int> = {TOGGLE_TWO_CMDS, 0};
  453.                                         toggleCmds[keyInd] = array<string> = {on_cmd, off_cmd};
  454.  
  455.                                         jjAlert("(Toggle) bound key ||"+key+" ||||||to ||"+on_cmd+" - "+off_cmd);
  456.                                         saveBinds();
  457.                                 }
  458.                                 else if (cmdargs.length() == 2)
  459.                                         jjAlert("|Missing ON command argument");
  460.                                 else
  461.                                 {
  462.                                         if (not binds[keyInd].isEmpty() and isToggle[keyInd][0] == TOGGLE_ON_OFF)
  463.                                                 jjAlert("||"+key+" ||||||is bound to a toggle: ||"+binds[keyInd]+" on/off");
  464.                                         else if (not binds[keyInd].isEmpty())
  465.                                                 jjAlert("||"+key+" ||||||is bound to ||"+binds[keyInd]);
  466.                                         else if (not toggleCmds[keyInd][0].isEmpty())
  467.                                                 jjAlert("||"+key+" ||||||is bound to a toggle: ||"+toggleCmds[keyInd][0]+" ||||||and ||"+toggleCmds[keyInd][1]);
  468.                                         else
  469.                                                 jjAlert("||"+key+" ||||||is not bound");
  470.                                 }
  471.                         }
  472.                         else
  473.                                 jjAlert("|Invalid key '"+key+" '");
  474.                 }
  475.                 return true;
  476.         }
  477.        
  478.         else if (cmd == "!unbind")
  479.         {
  480.                 if (cmdargs.isEmpty())
  481.                 {
  482.                         jjAlert("Usage: !unbind <key>");
  483.                         jjAlert("Removes a chat bind from a key.");
  484.                         jjAlert("Example: !unbind p");
  485.                 }
  486.                 else
  487.                 {
  488.                         string key = cmdargs[0];
  489.                         if (keyNames.exists(key))
  490.                         {
  491.                                 uint keyInd = uint(keyNames[key]);
  492.                                
  493.                                 if (binds[keyInd].isEmpty() and toggleCmds[keyInd][0].isEmpty())
  494.                                         jjAlert("||"+key+" ||||||is not bound");
  495.                                 else
  496.                                 {
  497.                                         jjAlert("Unbound ||"+key);
  498.  
  499.                                         binds[keyInd] = "";
  500.                                         isToggle[keyInd] = array<int> = {0, 0};
  501.                                         toggleCmds[keyInd] = array<string> = {"", ""};
  502.  
  503.                                         saveBinds();
  504.                                 }
  505.                         }
  506.                         else
  507.                                 jjAlert("|Invalid key '"+key+" '");
  508.                 }
  509.                 return true;
  510.         }
  511.        
  512.         return false;
  513. }
  514.  
  515. void onPlayerInput(jjPLAYER@ player)
  516. {
  517.         for (uint i=0x00; i<BIND_LENGTH; i++)
  518.         {
  519.                 if (jjKey[i] and (not binds[i].isEmpty() or not toggleCmds[i][0].isEmpty()) and not pressed[i])
  520.                 {
  521.                         switch(isToggle[i][0])
  522.                         {
  523.                                 case TOGGLE_NONE:
  524.                                         jjChat(binds[i]);
  525.                                         break;
  526.                                
  527.                                 case TOGGLE_ON_OFF:
  528.                                         jjChat(binds[i]+" "+ ((isToggle[i][1] > 0) ? "off" : "on"));
  529.                                         break;
  530.                                
  531.                                 case TOGGLE_TWO_CMDS:
  532.                                         jjChat(toggleCmds[i][isToggle[i][1]]);
  533.                                         break;
  534.                         }
  535.  
  536.                         isToggle[i][1] = -isToggle[i][1]+1;
  537.                         pressed[i] = true;
  538.                 }
  539.                 else if (not jjKey[i] and pressed[i])
  540.                         pressed[i] = false;
  541.         }
  542. }