local vmf = get_mod("VMF") local keyboard_buton_name = Keyboard.button_name local mouse_buton_name = Mouse.button_name vmf.keys = { keyboard = { [8] = {"Backspace", "backspace", keyboard_buton_name(8)}, [9] = {"Tab", "tab", keyboard_buton_name(9)}, [13] = {"Enter", "enter", keyboard_buton_name(13)}, [20] = {"Caps Lock", "caps lock", keyboard_buton_name(20)}, [32] = {"Space", "space", keyboard_buton_name(32)}, [33] = {"Page Up", "page up", keyboard_buton_name(33)}, [34] = {"Page Down", "page down", keyboard_buton_name(34)}, [35] = {"End", "end", keyboard_buton_name(35)}, [36] = {"Home", "home", keyboard_buton_name(36)}, [37] = {"Left", "left", keyboard_buton_name(37)}, [38] = {"Up", "up", keyboard_buton_name(38)}, [39] = {"Right", "right", keyboard_buton_name(39)}, [40] = {"Down", "down", keyboard_buton_name(40)}, [45] = {"Insert", "insert", keyboard_buton_name(45)}, [46] = {"Delete", "delete", keyboard_buton_name(46)}, [48] = {"0", "0", keyboard_buton_name(48)}, [49] = {"1", "1", keyboard_buton_name(49)}, [50] = {"2", "2", keyboard_buton_name(50)}, [51] = {"3", "3", keyboard_buton_name(51)}, [52] = {"4", "4", keyboard_buton_name(52)}, [53] = {"5", "5", keyboard_buton_name(53)}, [54] = {"6", "6", keyboard_buton_name(54)}, [55] = {"7", "7", keyboard_buton_name(55)}, [56] = {"8", "8", keyboard_buton_name(56)}, [57] = {"9", "9", keyboard_buton_name(57)}, [65] = {"A", "a", keyboard_buton_name(65)}, [66] = {"B", "b", keyboard_buton_name(66)}, [67] = {"C", "c", keyboard_buton_name(67)}, [68] = {"D", "d", keyboard_buton_name(68)}, [69] = {"E", "e", keyboard_buton_name(69)}, [70] = {"F", "f", keyboard_buton_name(70)}, [71] = {"G", "g", keyboard_buton_name(71)}, [72] = {"H", "h", keyboard_buton_name(72)}, [73] = {"I", "i", keyboard_buton_name(73)}, [74] = {"J", "j", keyboard_buton_name(74)}, [75] = {"K", "k", keyboard_buton_name(75)}, [76] = {"L", "l", keyboard_buton_name(76)}, [77] = {"M", "m", keyboard_buton_name(77)}, [78] = {"N", "n", keyboard_buton_name(78)}, [79] = {"O", "o", keyboard_buton_name(79)}, [80] = {"P", "p", keyboard_buton_name(80)}, [81] = {"Q", "q", keyboard_buton_name(81)}, [82] = {"R", "r", keyboard_buton_name(82)}, [83] = {"S", "s", keyboard_buton_name(83)}, [84] = {"T", "t", keyboard_buton_name(84)}, [85] = {"U", "u", keyboard_buton_name(85)}, [86] = {"V", "v", keyboard_buton_name(86)}, [87] = {"W", "w", keyboard_buton_name(87)}, [88] = {"X", "x", keyboard_buton_name(88)}, [89] = {"Y", "y", keyboard_buton_name(89)}, [90] = {"Z", "z", keyboard_buton_name(90)}, [91] = {"Win", "win", keyboard_buton_name(91)}, [92] = {"RWin", "right win", keyboard_buton_name(92)}, [96] = {"Num 0", "numpad 0", keyboard_buton_name(96)}, [97] = {"Num 1", "numpad 1", keyboard_buton_name(97)}, [98] = {"Num 2", "numpad 2", keyboard_buton_name(98)}, [99] = {"Num 3", "numpad 3", keyboard_buton_name(99)}, [100] = {"Num 4", "numpad 4", keyboard_buton_name(100)}, [101] = {"Num 5", "numpad 5", keyboard_buton_name(101)}, [102] = {"Num 6", "numpad 6", keyboard_buton_name(102)}, [103] = {"Num 7", "numpad 7", keyboard_buton_name(103)}, [104] = {"Num 8", "numpad 8", keyboard_buton_name(104)}, [105] = {"Num 9", "numpad 9", keyboard_buton_name(105)}, [106] = {"Num *", "numpad *", keyboard_buton_name(106)}, [107] = {"Num +", "numpad +", keyboard_buton_name(107)}, [109] = {"Num -", "numpad -", keyboard_buton_name(109)}, [110] = {"Num .", "numpad .", keyboard_buton_name(110)}, [111] = {"Num /", "numpad /", keyboard_buton_name(111)}, [112] = {"F1", "f1", keyboard_buton_name(112)}, [113] = {"F2", "f2", keyboard_buton_name(113)}, [114] = {"F3", "f3", keyboard_buton_name(114)}, [115] = {"F4", "f4", keyboard_buton_name(115)}, [116] = {"F5", "f5", keyboard_buton_name(116)}, [117] = {"F6", "f6", keyboard_buton_name(117)}, [118] = {"F7", "f7", keyboard_buton_name(118)}, [119] = {"F8", "f8", keyboard_buton_name(119)}, [120] = {"F9", "f9", keyboard_buton_name(120)}, [121] = {"F10", "f10", keyboard_buton_name(121)}, [122] = {"F11", "f11", keyboard_buton_name(122)}, [123] = {"F12", "f12", keyboard_buton_name(123)}, [144] = {"Num Lock", "num lock", keyboard_buton_name(144)}, [145] = {"Scroll Lock", "scroll lock", keyboard_buton_name(145)}, [166] = {"Browser Back", "browser back", keyboard_buton_name(166)}, [167] = {"Browser Forward", "browser forward", keyboard_buton_name(167)}, [168] = {"Browser Refresh", "browser refresh", keyboard_buton_name(168)}, [169] = {"Browser Stop", "browser stop", keyboard_buton_name(169)}, [170] = {"Browser Search", "browser search", keyboard_buton_name(170)}, [171] = {"Browser Favorites", "browser favorites", keyboard_buton_name(171)}, [172] = {"Browser Home", "browser home", keyboard_buton_name(172)}, [173] = {"Volume Mute", "volume mute", keyboard_buton_name(173)}, [174] = {"Volume Down", "volume down", keyboard_buton_name(174)}, [175] = {"Volume Up", "volume up", keyboard_buton_name(175)}, [176] = {"Next Track", "next track", keyboard_buton_name(176)}, [177] = {"Previous Track", "previous track", keyboard_buton_name(177)}, [178] = {"Stop", "stop", keyboard_buton_name(178)}, [179] = {"Play/Pause", "play pause", keyboard_buton_name(179)}, [180] = {"Mail", "mail", keyboard_buton_name(180)}, [181] = {"Media", "media", keyboard_buton_name(181)}, [182] = {"Start Application 1", "start app 1", keyboard_buton_name(182)}, [183] = {"Start Application 2", "start app 2", keyboard_buton_name(183)}, [186] = {";", ";", keyboard_buton_name(186)}, [187] = {"=", "=", keyboard_buton_name(187)}, [188] = {",", ",", keyboard_buton_name(188)}, [189] = {"-", "-", keyboard_buton_name(189)}, [190] = {".", ".", keyboard_buton_name(190)}, [191] = {"/", "/", keyboard_buton_name(191)}, [192] = {"`", "`", keyboard_buton_name(192)}, [219] = {"[", "[", keyboard_buton_name(219)}, [220] = {"\\", "\\", keyboard_buton_name(220)}, [221] = {"]", "]", keyboard_buton_name(221)}, [222] = {"'", "'", keyboard_buton_name(222)}, --?[226] = {"\", "oem_102 (> <)", keyboard_buton_name(226)}, [256] = {"Num Enter", "numpad enter", keyboard_buton_name(256)} }, mouse = { [0] = {"Mouse Left", "mouse left", mouse_buton_name(0)}, [1] = {"Mouse Right", "mouse right", mouse_buton_name(1)}, [2] = {"Mouse Middle", "mouse middle", mouse_buton_name(2)}, [3] = {"Mouse Extra 1", "mouse extra 1", mouse_buton_name(3)}, [4] = {"Mouse Extra 2", "mouse extra 2", mouse_buton_name(4)}, [10] = {"Mouse Wheel Up", "mouse wheel up", mouse_buton_name(10)}, [11] = {"Mouse Wheel Down", "mouse wheel down", mouse_buton_name(11)}, [12] = {"Mouse Wheel Left", "mouse wheel left", mouse_buton_name(12)}, [13] = {"Mouse Wheel Right", "mouse wheel right", mouse_buton_name(13)} },--[[ -- will work on this if it will be needed gamepad = { [0] = {"", "d_up", gamepad_buton_name(0)}, [1] = {"", "d_down", gamepad_buton_name(1)}, [2] = {"", "d_left", gamepad_buton_name(2)}, [3] = {"", "d_right", gamepad_buton_name(3)}, [4] = {"", "start", gamepad_buton_name(4)}, [5] = {"", "back", gamepad_buton_name(5)}, [6] = {"", "left_thumb", gamepad_buton_name(6)}, [7] = {"", "right_thumb", gamepad_buton_name(7)}, [8] = {"", "left_shoulder", gamepad_buton_name(8)}, [9] = {"", "right_shoulder", gamepad_buton_name(9)}, [10] = {"", "left_trigger", gamepad_buton_name(10)}, [11] = {"", "right_trigger", gamepad_buton_name(11)}, [12] = {"", "a", gamepad_buton_name(12)}, [13] = {"", "b", gamepad_buton_name(13)}, [14] = {"", "x", gamepad_buton_name(14)}, [15] = {"", "y", gamepad_buton_name(15)}, }]] } vmf.readable_key_names = {} for _, controller_keys in pairs(vmf.keys) do for _, key_info in pairs(controller_keys) do vmf.readable_key_names[key_info[2]] = key_info[1] end end vmf.readable_key_names["ctrl"] = "Ctrl" vmf.readable_key_names["alt"] = "Alt" vmf.readable_key_names["shift"] = "Shift" VMFModsKeyMap = { win32 = { ["ctrl"] = {"keyboard", "left ctrl", "held"}, ["alt"] = {"keyboard", "left alt", "held"}, ["shift"] = {"keyboard", "left shift", "held"} } } for _, key_info in pairs(vmf.keys.keyboard) do VMFModsKeyMap.win32[key_info[2]] = {"keyboard", key_info[3], "held"} end for i = 0, 4 do local key_info = vmf.keys.mouse[i] VMFModsKeyMap.win32[key_info[2]] = {"mouse", key_info[3], "held"} end for i = 10, 13 do local key_info = vmf.keys.mouse[i] VMFModsKeyMap.win32[key_info[2]] = {"mouse", key_info[3], "pressed"} end -- ["mod_name"]["setting_name"] = {"action_name", {"primary_key", "2nd_key", "3rd_key", "4th_key"}} local raw_keybinds = {} -- ["primary_key"] = {{"mod_name", "action_name", "2nd_key", "3rd_key", "4th_key"}, {}, {}, ...} local optimized_keybinds = {} local function apply_keybinds() optimized_keybinds = {} for mod_name, mod_keybinds in pairs(raw_keybinds) do for setting_name, keybind in pairs(mod_keybinds) do local action_name = keybind[1] local primary_key = keybind[2][1] local special_key1 = keybind[2][2] local special_key2 = keybind[2][3] local special_key3 = keybind[2][4] local special_keys = {} if special_key1 then special_keys[special_key1] = true end if special_key2 then special_keys[special_key2] = true end if special_key3 then special_keys[special_key3] = true end optimized_keybinds[primary_key] = optimized_keybinds[primary_key] or {} table.insert(optimized_keybinds[primary_key], {mod_name, action_name, special_keys["ctrl"], special_keys["alt"], special_keys["shift"]}) end end end -- use it directly only for dedugging purposes, otherwise use keybind widget -- setting_name [string] - keybind identifyer for certain mod -- action_name [string] - name of some mod.function which will be called when keybind is pressed -- keys [table] = {"primary_key", "2nd_key" [optional], "3rd_key" [optional], "4th_key" [optional]} -- 2, 3, 4 keys can contain words "ctrl", "alt", "shift" (lowercase) VMFMod.keybind = function (self, setting_name, action_name, keys) if keys[1] then local mod_keybinds = raw_keybinds[self._name] or {} mod_keybinds[setting_name] = {action_name, keys} raw_keybinds[self._name] = mod_keybinds else local mod_keybinds = raw_keybinds[self._name] if mod_keybinds and mod_keybinds[setting_name] then mod_keybinds[setting_name] = nil end end if vmf.keybind_input_service then apply_keybinds() end end vmf.initialize_keybinds = function() Managers.input.create_input_service(Managers.input, "VMFMods", "VMFModsKeyMap") Managers.input.map_device_to_service(Managers.input, "VMFMods", "keyboard") Managers.input.map_device_to_service(Managers.input, "VMFMods", "mouse") vmf.keybind_input_service = Managers.input:get_service("VMFMods") apply_keybinds() end vmf.check_pressed_keybinds = function() local input_service = vmf.keybind_input_service if input_service then -- don't check for the pressed keybindings until player will release already pressed keybind if vmf.activated_pressed_key then if input_service:get(vmf.activated_pressed_key) then return else vmf.activated_pressed_key = nil end end local key_has_active_keybind = false for key, key_bindings in pairs(optimized_keybinds) do if input_service:get(key) then for _, binding_info in ipairs(key_bindings) do if (not binding_info[3] and not input_service:get("ctrl") or binding_info[3] and input_service:get("ctrl")) and (not binding_info[4] and not input_service:get("alt") or binding_info[4] and input_service:get("alt")) and (not binding_info[5] and not input_service:get("shift") or binding_info[5] and input_service:get("shift")) then --@TODO: also check for suspending, and perhaps add "toggle" event local action_exists, action_function = pcall(function() return get_mod(binding_info[1])[binding_info[2]] end) if action_exists then local success, error_message = pcall(action_function) if not success then get_mod(binding_info[1]):echo("ERROR(keybindings) in function '" .. tostring(binding_info[2]) .. "': " .. tostring(error_message), true) end else get_mod(binding_info[1]):echo("ERROR(keybindings): function '" .. tostring(binding_info[2]) .. "' wasn't found.", true) end key_has_active_keybind = true vmf.activated_pressed_key = key end end -- return here because some other mods can have the same keybind which also need to be executed if key_has_active_keybind then return end end end end end vmf.delete_keybinds = function() VMFModsKeyMap = {} end