Add BindAid

This commit is contained in:
dhert
2023-03-10 20:49:42 -06:00
parent a24dabe5b7
commit 299af7eaf4
14 changed files with 1808 additions and 0 deletions

View File

@@ -0,0 +1,322 @@
local keyman = require("KeybindManager")
local conf = require("BindAidConfig")
------------------------------------------
-- ModKey Overrides -- Client
--- All of the override functions ModKey Supports
------------------------------------------
local overrides = {}
-- We want the LAST references to all of this
overrides.onStart = function()
-- Don't do this if disabled
if not conf.Local.keyinputOptimize then return end
------------------------------------------
-- ISHotbar
---- "All hotbar keys"
------------------------------------------
local _ISHotbar_onKeyStartPressed = ISHotbar.onKeyStartPressed
local _ISHotbar_onKeyPressed = ISHotbar.onKeyPressed
local _ISHotbar_onKeyKeepPressed = ISHotbar.onKeyKeepPressed
Events.OnKeyStartPressed.Remove(_ISHotbar_onKeyStartPressed)
Events.OnKeyKeepPressed.Remove(_ISHotbar_onKeyKeepPressed)
Events.OnKeyPressed.Remove(_ISHotbar_onKeyPressed)
-- we need to get all of the keys that start with "Hotbar"
local hotbars = {}
for _,v in ipairs(keyBinding) do
if luautils.stringStarts(v.value, "Hotbar ") then
hotbars[#hotbars+1] = v.value
end
end
for _,v in ipairs(hotbars) do
keyman.addKeyEvents(v, {
["OnKeyStartPressed"] = _ISHotbar_onKeyStartPressed,
["OnKeyKeepPressed"] = _ISHotbar_onKeyKeepPressed,
["OnKeyPressed"] = _ISHotbar_onKeyPressed
})
end
hotbars = nil
------------------------------------------
-- ISVehicleMenu
---- "VehicleMechanics"
---- "StartVehicleEngine"
---- "VehicleHeater"
---- "VehicleHorn"
---- "VehicleSwitchSeat"
------------------------------------------
local _ISVehicleMenu_onKeyPressed = ISVehicleMenu.onKeyPressed
local _ISVehicleMenu_onKeyStartPressed = ISVehicleMenu.onKeyStartPressed
Events.OnKeyPressed.Remove(_ISVehicleMenu_onKeyPressed)
Events.OnKeyStartPressed.Remove(_ISVehicleMenu_onKeyStartPressed)
keyman.addKeyEvents("VehicleMechanics", {
["OnKeyPressed"] = _ISVehicleMenu_onKeyPressed
})
keyman.addKeyEvents("StartVehicleEngine", {
["OnKeyPressed"] = _ISVehicleMenu_onKeyPressed
})
keyman.addKeyEvents("VehicleHeater", {
["OnKeyPressed"] = _ISVehicleMenu_onKeyPressed
})
keyman.addKeyEvents("VehicleHorn", {
["OnKeyPressed"] = _ISVehicleMenu_onKeyPressed,
["OnKeyStartPressed"] = _ISVehicleMenu_onKeyStartPressed
})
keyman.addKeyEvents("VehicleSwitchSeat", {
["OnKeyStartPressed"] = _ISVehicleMenu_onKeyStartPressed
})
------------------------------------------
-- ISWorldMap
---- "Map"
------------------------------------------
local _ISWorldMap_onKeyStartPressed = ISWorldMap.onKeyStartPressed
local _ISWorldMap_onKeyKeepPressed = ISWorldMap.onKeyKeepPressed
local _ISWorldMap_onKeyReleased = ISWorldMap.onKeyReleased
Events.OnKeyStartPressed.Remove(_ISWorldMap_onKeyStartPressed)
Events.OnKeyKeepPressed.Remove(_ISWorldMap_onKeyKeepPressed)
Events.OnKeyPressed.Remove(_ISWorldMap_onKeyReleased)
keyman.addKeyEvents("Map", {
["OnKeyStartPressed"] = _ISWorldMap_onKeyStartPressed,
["OnKeyKeepPressed"] = _ISWorldMap_onKeyKeepPressed,
["OnKeyPressed"] = _ISWorldMap_onKeyReleased
})
------------------------------------------
-- ISLightSourceRadialMenu
---- "Equip/Turn On/Off Light Source"
------------------------------------------
local _ISLightSourceRadialMenu_onKeyPressed = ISLightSourceRadialMenu.onKeyPressed
local _ISLightSourceRadialMenu_onKeyRepeat = ISLightSourceRadialMenu.onKeyRepeat
local _ISLightSourceRadialMenu_onKeyReleased = ISLightSourceRadialMenu.onKeyReleased
Events.OnKeyStartPressed.Remove(_ISLightSourceRadialMenu_onKeyPressed)
Events.OnKeyKeepPressed.Remove(_ISLightSourceRadialMenu_onKeyRepeat)
Events.OnKeyPressed.Remove(_ISLightSourceRadialMenu_onKeyReleased)
keyman.addKeyEvents("Equip/Turn On/Off Light Source", {
["OnKeyStartPressed"] = _ISLightSourceRadialMenu_onKeyPressed,
["OnKeyKeepPressed"] = _ISLightSourceRadialMenu_onKeyRepeat,
["OnKeyPressed"] = _ISLightSourceRadialMenu_onKeyReleased
})
------------------------------------------
-- ISInventoryPage
---- "Toggle Inventory"
------------------------------------------
local _ISInventoryPage_onKeyPressed = ISInventoryPage.onKeyPressed
Events.OnKeyPressed.Remove(_ISInventoryPage_onKeyPressed)
keyman.addKeyEvents("Toggle Inventory", {
["OnKeyPressed"] = _ISInventoryPage_onKeyPressed
})
------------------------------------------
-- ISFPS
---- "Display FPS"
------------------------------------------
local _ISFPS_onKeyPressed = ISFPS.onKeyPressed
Events.OnKeyPressed.Remove(_ISFPS_onKeyPressed)
keyman.addKeyEvents("Display FPS", {
["OnKeyPressed"] = _ISFPS_onKeyPressed
})
------------------------------------------
-- ISUIHandler
---- "VehicleRadialMenu"
---- "Toggle UI"
---- "Show Ping"
------------------------------------------
local _ISUIHandler_onKeyStartPressed = ISUIHandler.onKeyStartPressed
local _ISUIHandler_onKeyPressed = ISUIHandler.onKeyPressed
Events.OnKeyStartPressed.Remove(_ISUIHandler_onKeyStartPressed)
Events.OnKeyPressed.Remove(_ISUIHandler_onKeyPressed)
keyman.addKeyEvents("Toggle UI", {
["OnKeyStartPressed"] = _ISUIHandler_onKeyStartPressed,
["OnKeyPressed"] = _ISUIHandler_onKeyPressed
})
keyman.addKeyEvents("VehicleRadialMenu", {
["OnKeyStartPressed"] = _ISUIHandler_onKeyStartPressed,
["OnKeyPressed"] = _ISUIHandler_onKeyPressed
})
------------------------------------------
-- ISCraftingUI
---- "Crafting UI"
------------------------------------------
local _ISCraftingUI_onPressKey = ISCraftingUI.onPressKey
Events.OnCustomUIKey.Remove(_ISCraftingUI_onPressKey)
keyman.addKeyEvents("Crafting UI", {
["OnCustomUIKey"] = _ISCraftingUI_onPressKey
})
------------------------------------------
-- ISSafetyUI
---- "Toggle Safety"
------------------------------------------
local _ISSafetyUI_onKeyPressed = ISSafetyUI.onKeyPressed
Events.OnKeyPressed.Remove(_ISSafetyUI_onKeyPressed)
if isClient() and getServerOptions():getBoolean("SafetySystem") then
keyman.addKeyEvents("Toggle Safety", {
["OnKeyPressed"] = _ISSafetyUI_onKeyPressed
})
end
------------------------------------------
-- ISFirearmRadialMenu
---- "ReloadWeapon"
------------------------------------------
local _ISFirearmRadialMenu_onKeyPressed = ISFirearmRadialMenu.onKeyPressed
local _ISFirearmRadialMenu_onKeyRepeat = ISFirearmRadialMenu.onKeyRepeat
local _ISFirearmRadialMenu_onKeyReleased = ISFirearmRadialMenu.onKeyReleased
Events.OnKeyStartPressed.Remove(_ISFirearmRadialMenu_onKeyPressed)
Events.OnKeyKeepPressed.Remove(_ISFirearmRadialMenu_onKeyRepeat)
Events.OnKeyPressed.Remove(_ISFirearmRadialMenu_onKeyReleased)
keyman.addKeyEvents("ReloadWeapon", {
["OnKeyStartPressed"] = _ISFirearmRadialMenu_onKeyPressed,
["OnKeyKeepPressed"] = _ISFirearmRadialMenu_onKeyRepeat,
["OnKeyPressed"] = _ISFirearmRadialMenu_onKeyReleased
})
------------------------------------------
-- ISMoveableInfoWindow
---- "Toggle Moveable Panel Mode"
------------------------------------------
local _ISMoveableInfoWindow_moveablePanelModeKey = ISMoveableInfoWindow.moveablePanelModeKey
Events.OnKeyPressed.Remove(_ISMoveableInfoWindow_moveablePanelModeKey)
keyman.addKeyEvents("Toggle Moveable Panel Mode", {
["OnKeyPressed"] = _ISMoveableInfoWindow_moveablePanelModeKey
})
------------------------------------------
-- ISEmoteRadialMenu
---- "Emote"
---- "Shout"
------------------------------------------
local _ISEmoteRadialMenu_onKeyReleased = ISEmoteRadialMenu.onKeyReleased
local _ISEmoteRadialMenu_onKeyPressed = ISEmoteRadialMenu.onKeyPressed
local _ISEmoteRadialMenu_onKeyRepeat = ISEmoteRadialMenu.onKeyRepeat
Events.OnKeyStartPressed.Remove(_ISEmoteRadialMenu_onKeyPressed)
Events.OnKeyKeepPressed.Remove(_ISEmoteRadialMenu_onKeyRepeat)
Events.OnKeyPressed.Remove(_ISEmoteRadialMenu_onKeyReleased)
keyman.addKeyEvents("Emote", {
["OnKeyStartPressed"] = _ISEmoteRadialMenu_onKeyPressed,
["OnKeyKeepPressed"] = _ISEmoteRadialMenu_onKeyRepeat,
["OnKeyPressed"] = _ISEmoteRadialMenu_onKeyReleased
})
keyman.addKeyEvents("Shout", {
["OnKeyStartPressed"] = _ISEmoteRadialMenu_onKeyPressed,
["OnKeyKeepPressed"] = _ISEmoteRadialMenu_onKeyRepeat,
["OnKeyPressed"] = _ISEmoteRadialMenu_onKeyReleased
})
------------------------------------------
-- ISSearchManager
---- "Toggle Search Mode"
------------------------------------------
local _ISSearchManager_handleKeyPressed = ISSearchManager.handleKeyPressed
Events.OnKeyPressed.Remove(_ISSearchManager_handleKeyPressed)
keyman.addKeyEvents("Toggle Search Mode", {
["OnKeyPressed"] = _ISSearchManager_handleKeyPressed
})
------------------------------------------
-- ISChat
---- "Toggle chat"
---- "Alt toggle chat"
------------------------------------------
local _ISChat_onToggleChatBox = ISChat.onToggleChatBox
--local _ISChat_onKeyKeepPressed = ISChat.onKeyKeepPressed
Events.OnKeyPressed.Remove(_ISChat_onToggleChatBox)
keyman.addKeyEvents("Toggle chat", {
["OnKeyPressed"] = _ISChat_onToggleChatBox
})
keyman.addKeyEvents("Alt toggle chat", {
["OnKeyPressed"] = _ISChat_onToggleChatBox
})
keyman.addKeyEvents("Switch chat stream", {
["OnKeyPressed"] = _ISChat_onToggleChatBox
})
------------------------------------------
-- Escape!
---- "Main Menu"
------------------------------------------
local _ToggleEscapeMenu = ToggleEscapeMenu
Events.OnKeyPressed.Remove(_ToggleEscapeMenu)
keyman.addKeyEvents("Main Menu", {
["OnKeyPressed"] = _ToggleEscapeMenu
})
------------------------------------------
-- SpeedControlsHandler
---- "Pause"
---- "Normal Speed"
---- "Fast Forward x1"
---- "Fast Forward x2"
---- "Fast Forward x3"
------------------------------------------
local _SpeedControlsHandler_onKeyPressed = SpeedControlsHandler.onKeyPressed
Events.OnKeyPressed.Remove(_SpeedControlsHandler_onKeyPressed)
if not isClient() then
keyman.addKeyEvents("Pause", {
["OnKeyPressed"] = _SpeedControlsHandler_onKeyPressed
})
keyman.addKeyEvents("Normal Speed", {
["OnKeyPressed"] = _SpeedControlsHandler_onKeyPressed
})
keyman.addKeyEvents("Fast Forward x1", {
["OnKeyPressed"] = _SpeedControlsHandler_onKeyPressed
})
keyman.addKeyEvents("Fast Forward x2", {
["OnKeyPressed"] = _SpeedControlsHandler_onKeyPressed
})
keyman.addKeyEvents("Fast Forward x3", {
["OnKeyPressed"] = _SpeedControlsHandler_onKeyPressed
})
end
------------------------------------------
-- SurvivalGuideManager
---- "Toggle Survival Guide"
------------------------------------------
local _SurvivalGuideManager_onKeyPressed = SurvivalGuideManager.onKeyPressed
Events.OnKeyPressed.Remove(_SurvivalGuideManager_onKeyPressed)
keyman.addKeyEvents("Toggle Survival Guide", {
["OnKeyPressed"] = _SurvivalGuideManager_onKeyPressed
})
end
return overrides

View File

@@ -0,0 +1,260 @@
local conf = require('BindAidConfig')
local mouse = {
curMouseX = 0,
curMouseY = 0,
prevMouseX = 0,
prevMouseY = 0,
hideDelta = 1,
hiding = false,
shouldHide = true,
hideDelay = 10, -- seconds
mouseButtons = 3,
buttonState = {},
buttonData = {}
}
mouse._onTickMouseHide = function()
-- Get our position
mouse.curMouseX = mouse.getX()
mouse.curMouseY = mouse.getY()
-- if our position is the same as last frame
---- Since we want this to work on everthing; we have to check this manually
if (mouse.curMouseX == mouse.prevMouseX and mouse.curMouseY == mouse.prevMouseY) then
-- if we are already hiding, do
if mouse.hiding then
mouse.setCursorVisible(false)
else
-- otherwise, increment
mouse.hideDelta = mouse.hideDelta + 1
-- We changed hideDelay on start to be in seconds
if mouse.hideDelta >= mouse.hideDelay then
mouse.hiding = true
end
end
else
-- Reset
mouse.hiding = false
mouse.hideDelta = 1
mouse.prevMouseX = mouse.curMouseX
mouse.prevMouseY = mouse.curMouseY
end
end
mouse.buttonEvents = {
["OnMouseMiddleDown"] = {},
["OnMouse4Down"] = {},
["OnMouse5Down"] = {},
["OnMouse6Down"] = {},
["OnMouse7Down"] = {},
["OnMouse8Down"] = {},
["OnMouse9Down"] = {},
["OnMouse10Down"] = {},
["OnMouse11Down"] = {},
["OnMouse12Down"] = {},
["OnMouseMiddleHold"] = {},
["OnMouse4Hold"] = {},
["OnMouse5Hold"] = {},
["OnMouse6Hold"] = {},
["OnMouse7Hold"] = {},
["OnMouse8Hold"] = {},
["OnMouse9Hold"] = {},
["OnMouse10Hold"] = {},
["OnMouse11Hold"] = {},
["OnMouse12Hold"] = {},
["OnMouseMiddleUp"] = {},
["OnMouse4Up"] = {},
["OnMouse5Up"] = {},
["OnMouse6Up"] = {},
["OnMouse7Up"] = {},
["OnMouse8Up"] = {},
["OnMouse9Up"] = {},
["OnMouse10Up"] = {},
["OnMouse11Up"] = {},
["OnMouse12Up"] = {},
}
local _mouseDownEvents = {
-- 0
false, --1
"OnMouseMiddleDown",
"OnMouse4Down",
"OnMouse5Down",
"OnMouse6Down",
"OnMouse7Down",
"OnMouse8Down",
"OnMouse9Down",
"OnMouse10Down",
"OnMouse11Down",
"OnMouse12Down"
}
local _mouseHoldEvents = {
-- 0
false, --1
"OnMouseMiddleHold",
"OnMouse4Hold",
"OnMouse5Hold",
"OnMouse6Hold",
"OnMouse7Hold",
"OnMouse8Hold",
"OnMouse9Hold",
"OnMouse10Hold",
"OnMouse11Hold",
"OnMouse12Hold"
}
local _mouseUpEvents = {
-- 0
false, --1
"OnMouseMiddleUp",
"OnMouse4Up",
"OnMouse5Up",
"OnMouse6Up",
"OnMouse7Up",
"OnMouse8Up",
"OnMouse9Up",
"OnMouse10Up",
"OnMouse11Up",
"OnMouse12Up"
}
local addTo = function(key, data, input)
local o = data[key] or {}
o[#o+1] = input
data[key] = o
return data
end
mouse.Add = function(data)
for i,v in pairs(data) do
mouse.buttonEvents = addTo(i, mouse.buttonEvents, v)
end
end
local _event -- cache
local mouseEvent = function(button, go)
_event = mouse.buttonData[button]
if not _event then return end
if _event.press then
if go then
_event = mouse.buttonEvents[_mouseHoldEvents[button]]
for i=1, #_event do
_event[i](mouse.getX(), mouse.getY())
end
else
_event.press = false
_event = mouse.buttonEvents[_mouseUpEvents[button]]
for i=1, #_event do
_event[i](mouse.getX(), mouse.getY())
end
end
else
if go then
_event.press = true
_event = mouse.buttonEvents[_mouseDownEvents[button]]
for i=1, #_event do
_event[i](mouse.getX(), mouse.getY())
end
end
end
end
local mouseEmulate = function(button, go)
_event = mouse.buttonData[button]
if not _event then return end
if _event.press then
if go then
-- hold
triggerEvent("OnKeyKeepPressed", _event.key)
else
-- up
triggerEvent("OnKeyPressed", _event.key)
_event.press = false
end
else
if go then
-- down
triggerEvent("OnKeyStartPressed", _event.key)
_event.press = true
end
end
end
local mouseBoth = function(button, go)
_event = mouse.buttonData[button]
if not _event then return end
if _event.press then
if go then
-- hold
triggerEvent("OnKeyKeepPressed", _event.key)
_event = mouse.buttonEvents[_mouseHoldEvents[button]]
for i=1, #_event do
_event[i](mouse.getX(), mouse.getY())
end
else
-- up
triggerEvent("OnKeyPressed", _event.key)
_event.press = false
_event = mouse.buttonEvents[_mouseUpEvents[button]]
for i=1, #_event do
_event[i](mouse.getX(), mouse.getY())
end
end
else
if go then
-- down
triggerEvent("OnKeyStartPressed", _event.key)
_event.press = true
_event = mouse.buttonEvents[_mouseDownEvents[button]]
for i=1, #_event do
_event[i](mouse.getX(), mouse.getY())
end
end
end
end
mouse.buildButtonData = function()
mouse.buttonData = {}
local buttons = { false, } -- 1
for _,v in ipairs(keyBinding) do
if luautils.stringStarts(v.value, "Bindaid_MouseKey") then
buttons[#buttons+1] = getCore():getKey(v.value)
end
end
for i=2, mouse.mouseButtons do
local key = (buttons[i] and buttons[i] ~= 0 and buttons[i]) or nil
mouse.buttonData[i] = {
func = (key and conf.Conf.emulateAndEvent and mouseBoth) or (key and mouseEmulate) or mouseEvent,
key = key
}
end
end
mouse._onClickButtonHandler = function()
for i=2, mouse.mouseButtons do
mouse.buttonData[i].func(i, mouse.isButtonDown(i))
end
end
mouse._onStart = function()
mouse.buildButtonData()
if conf.Local.mouseButtonSupport then
Events.OnTick.Add(mouse._onClickButtonHandler)
end
end
mouse._onBoot = function()
-- Since these are static functions, let's cache them
mouse.getX = Mouse.getX
mouse.getY = Mouse.getY
mouse.setCursorVisible = Mouse.setCursorVisible
mouse.isButtonDown = Mouse.isButtonDown
mouse.isButtonDownUICheck = Mouse.isButtonDownUICheck
end
return mouse

View File

@@ -0,0 +1,25 @@
-- These fixes are included in other mods, so this prevents from multiple runnings
if not Exterminator then
Exterminator = {}
end
if not Exterminator.onEnterFromGame then
-- Protects Against a Known Options Bug
-- Thanks Burryaga!
Exterminator.onEnterFromGame = MainScreen.onEnterFromGame
function MainScreen:onEnterFromGame()
Exterminator.onEnterFromGame(self)
-- Guarantee that when you ENTER the options menu, the game does not think you've already changed your damn options.
MainOptions.instance.gameOptions.changed = false
end
end
if not Exterminator.MainOptions_apply then
-- Adds an event when Game Options are changed
LuaEventManager.AddEvent("OnSettingsApply")
Exterminator.MainOptions_apply = MainOptions.apply
function MainOptions:apply(closeAfter)
Exterminator.MainOptions_apply(self, closeAfter)
triggerEvent("OnSettingsApply")
end
end

View File

@@ -0,0 +1,83 @@
------------------------------------------
-- BindAid Overrides -- Server
--- All of the override functions BindAid Supports
------------------------------------------
if not (isClient() or not isServer()) then return end
local keyman = require('KeybindManager')
local conf = require("BindAidConfig")
local overrides = {}
-- We want the LAST references to all of this
overrides.onStart = function()
-- Don't do this if disabled
if not conf.Local.keyinputOptimize then return end
------------------------------------------
-- ItemBindingHandler
---- "Equip/Turn On/Off Light Source"
---- "ToggleVehicleHeadlights"
------- This one is not actually an Event, but is called by ISLightSourceRadialMenu
------- This is here to catch the headlights mostly
------------------------------------------
-- local _ItemBindingHandler_onKeyPressed = ItemBindingHandler.onKeyPressed
-- ItemBindingHandler.onKeyPressed = function(key)
-- if not keyman.isModKeyDown() then
-- _ItemBindingHandler_onKeyPressed(key)
-- end
-- end
------------------------------------------
-- xpUpdate
---- "Toggle Skill Panel"
---- "Toggle Health Panel"
---- "Toggle Info Panel"
---- "Toggle Clothing Protection Panel"
------------------------------------------
local _xpUpdate_displayCharacterInfo = xpUpdate.displayCharacterInfo
Events.OnKeyPressed.Remove(_xpUpdate_displayCharacterInfo)
keyman.addKeyEvents("Toggle Skill Panel", {
["OnKeyPressed"] = _xpUpdate_displayCharacterInfo
})
keyman.addKeyEvents("Toggle Health Panel", {
["OnKeyPressed"] = _xpUpdate_displayCharacterInfo
})
keyman.addKeyEvents("Toggle Info Panel", {
["OnKeyPressed"] = _xpUpdate_displayCharacterInfo
})
keyman.addKeyEvents("Toggle Clothing Protection Panel", {
["OnKeyPressed"] = _xpUpdate_displayCharacterInfo
})
------------------------------------------
-- ISMoveableCursor
---- "Run"
---- "Interact"
---- "Toggle mode"
------------------------------------------
local _ISMoveableCursor_exitCursorKey = ISMoveableCursor.exitCursorKey
local _ISMoveableCursor_changeModeKey = ISMoveableCursor.changeModeKey
Events.OnKeyPressed.Remove(_ISMoveableCursor_exitCursorKey)
Events.OnKeyKeepPressed.Remove(_ISMoveableCursor_exitCursorKey)
keyman.addKeyEvents("Run", {
["OnKeyPressed"] = _ISMoveableCursor_exitCursorKey,
["OnKeyKeepPressed"] = _ISMoveableCursor_exitCursorKey,
})
keyman.addKeyEvents("Interact", {
["OnKeyPressed"] = _ISMoveableCursor_exitCursorKey,
["OnKeyKeepPressed"] = _ISMoveableCursor_exitCursorKey,
})
Events.OnKeyPressed.Remove(_ISMoveableCursor_changeModeKey)
keyman.addKeyEvents("Toggle mode", {
["OnKeyPressed"] = _ISMoveableCursor_changeModeKey
})
end
return overrides

View File

@@ -0,0 +1,84 @@
-- Only load in Single Player or if a Multiplayer client
if not (isClient() or not isServer()) then return end
local conf = require('BindAidConfig')
local keyman = require('KeybindManager')
local mouse -- client, loaded onBoot
local localOverrides -- client, loaded onStart
local serverOverrides -- server, loaded onStart
local autoHideTimes = {
1,2,5,10,30,60
}
local onBoot = function()
mouse = require('Mouse')
-- Added to Sync the options
conf.OnApplyOptions = function()
mouse.hideDelay = (autoHideTimes[conf.Local.autohideMouseTime] or 5) * getPerformance():getFramerate()
mouse.mouseButtons = conf.Local.mouseButtonCount + 1
Events.OnTickEvenPaused.Remove(mouse._onTickMouseHide)
Events.OnFETick.Remove(mouse._onTickMouseHide)
if conf.Local.autohideMouse then
-- Do the game and the Pause
Events.OnTickEvenPaused.Add(mouse._onTickMouseHide)
-- Do the Main Menu
Events.OnFETick.Add(mouse._onTickMouseHide)
end
end
conf._onBoot()
mouse._onBoot()
keyman._onBoot()
keyman.addKeybind("[Bindaid]", 'Bindaid_Modkey', Keyboard.KEY_LCONTROL)
if conf.Local.mouseButtonSupport then
for i=2, mouse.mouseButtons do
keyman.addKeybind("[Bindaid]", 'Bindaid_MouseKey_' .. tostring(i), 0)
end
end
end
local onSettings = function()
if conf.Local.keyinputOptimize then
keyman.buildKeymap()
end
if conf.Local.mouseButtonSupport then
mouse.buildButtonData()
end
end
-- The postStart is the last OnGameStart function that is called
---- Will run all of the other `starts` for keys to get the latest key events
local postStart = function()
localOverrides.onStart()
if serverOverrides then serverOverrides.onStart() end
keyman._onStart()
mouse._onStart()
end
local onStart = function()
localOverrides = require('ClientKeys')
serverOverrides = require('ServerKeys')
Events.OnSettingsApply.Add(onSettings)
-- Add the postStart function to the OnGameStart stack now
---- This ENSURES that it is last. :)
Events.OnGameStart.Add(postStart)
end
local function BindAid()
print(getText("UI_Init_Bindaid"))
Events.OnGameBoot.Add(onBoot)
Events.OnGameStart.Add(onStart)
end
BindAid()

View File

@@ -0,0 +1,309 @@
-- Configuration Manager
---- Made by dhert, use this however you want. :)
-- NOTE: GIVE THIS FILE A UNIQUE SANDNAME IN YOUR MOD TO NOT OVERWRITE OTHER USES OF THIS SCRIPT!
---------------------
-- Edit the "options_data" array for your settings using Mod Options syntax.
--- Comment out the OPTIONS table in full to disable ModOptions support
--- Do not change the OPTIONS, options_data, mod_id, mod_shortname, and mod_fullname variable names, but fill them in with your own values
--- The options OnApplyMainMenu and OnApplyInGame will be added/overwritten later, do not use them.
local OPTIONS = {
options_data = {
autohideMouse = {
name = "UI_ModOptions_Bindaid_autohideMouse",
default = true,
},
autohideMouseTime = {
"1", "2", "5", "10", "30", "60",
name = "UI_ModOptions_Bindaid_autohideMouseTime",
default = 4,
},
mouseButtonSupport = {
name = "UI_ModOptions_Bindaid_mouseButtonSupport",
default = true,
},
mouseButtonCount = {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
name = "UI_ModOptions_Bindaid_mouseButtonCount",
default = 3
},
emulateAndEvent = {
name = "UI_ModOptions_Bindaid_emulateAndEvent",
default = false,
},
keyinputOptimize = {
name = "UI_ModOptions_Bindaid_keyinputOptimize",
default = true,
},
},
mod_id = "BindAid",
mod_shortname = "BindAid",
mod_fullname = getText("UI_optionscreen_binding_Bindaid")
}
-- Controls whether ModOptions will overwrite Sandbox Options with the same name by default.
--- To allow Server Owners to control this, keep this as "TRUE" add the IgnoreLocalOptions option to your Sandbox Namespace (see above)
local OVERWRITE = true
-- Set the name of your SandboxVariable Namespace.
--- The "Namespace" is the group of Sandbox Variables for your mod: "SanboxVars.Namespace.Variable"
--- You build Sanbox Variables as: "option Namespace.Variable"
---- If you have only one Namespace:
----- local SANDNAME = "Namespace"
---- If you have more than one, then build a table:
----- local SANDNAME = {"One", "Two", "etc"}
----- Comment out to disable Sandbox Support
--local SANDNAME = "Bindaid"
---------------------
-- Additional Documentation
---------------------
-- This module can be used as a cache for your Sandbox Options and ModOptions
--- Simply modify the variables above to setup your mod's Config cache.
--- This can be placed anywhere; client, server, or shared
--- Include this in your mod and use as:
---- local config = require('YourConfigManagerFileNameName') -- no .lua at the end
---- Can use this as:
----- if config.Get("Option") then
----- -- do something
----- end
----
---- You also have access to the raw data using:
---- config.Conf["Option"] OR config.Conf.Option
---
--- Defined ModOptions are made available in the config.Conf table.
---- ModOptions that have the same name as a Sandbox options will overwrite.
----- In your Sandbox namespace, add the option 'IgnoreLocalOptions' to allow server owners to force sync options
----- Example:
------ option Namespace.IgnoreLocalOptions
------ {
------ type = boolean, default = false,
------ page = Namespace,
------ translation = Namespace_IgnoreLocalOptions,
------ }
----- Alternatively, set the OVERWRITE option to false to only sync ModOptions and not overwrite Sandbox options
---------------------
----------- Don't edit below here, unless you know what you're doing. :)
---------------------
local Conf = {
-- This is our main object for configuration; read from this.
Conf = {},
-- This is the user's configuration, only defined if Mod Options exists. Used internally, not intended to be used but left here; already synced with Conf.
Local = nil,
-- A function that can be defined to run when Sandbox Settings are read
OnSandboxConfig = nil,
-- A function that can be defined to run when settings are applied. Called ANY time that Mod Options are changed
OnApplyOptions = nil,
-- A function that can be defined to run when settings are applied in game
OnApplyOptionsInGame = nil
}
-- Print the available Configuration
--- Useful for debugging
Conf.Print = function()
for i,v in pairs(Conf.Conf) do
print(" " .. tostring(i) .. " = " .. tostring(v))
end
end
-- Sync Sandbox Configuration from given Namespace
local syncSandboxConfig = function(nmspce)
local vars = SandboxVars[nmspce]
if not vars then
print("Unable to find namespace: " .. nmspce)
return false
end
for i,v in pairs(vars) do
Conf.Conf[i] = v
end
end
-- Sync Sandbox Configuration from Multiple Namespaces
local syncSandboxConfigMulti = function(nmspces)
for _,n in ipairs(nmspces) do
syncSandboxConfig(n)
end
end
-- Syncs Sandbox and available ModOptions
Conf.SyncConfig = function()
-- Reset our conf object
Conf.Conf = {}
if SANDNAME then
if type(SANDNAME) == "string" then
syncSandboxConfig(SANDNAME)
else
syncSandboxConfigMulti(SANDNAME)
end
end
if not Conf.Conf.IgnoreLocalOptions and Conf.Local and OVERWRITE then
-- Sync our Local configuration into our Conf data, overriding any Sandbox Options
for i,v in pairs(Conf.Local) do
Conf.Conf[i] = v
end
elseif Conf.Local then
-- only sync options that do not exist
for i, v in pairs(Conf.Local) do
if Conf.Conf[i] == nil then
Conf.Conf[i] = v
end
end
end
end
-- Get configuration value from given `key`
-- Returns default, nil if no default given
--- @param key string
--- @param default number|boolean|string -- optional
--- @return number|boolean|string|nil
Conf.Get = function(key, default)
return (Conf.Conf[key] == nil and default) or Conf.Conf[key]
end
-- Apply Mod Options in general, run the OnApplyOptions function if available
---- ALWAYS called when ModOptions are changed
local function applyModOptions(data)
Conf.Local = {}
for i,v in pairs(data.settings.options) do
Conf.Local[i] = v
end
if Conf.OnApplyOptions then
Conf.OnApplyOptions(Conf.Local)
end
end
-- Apply Mod Options in game, run the OnApplyOptionsInGame function if available
local function applyModOptionsGame(data)
applyModOptions(data)
Conf.SyncConfig()
if Conf.OnApplyOptionsInGame then
Conf.OnApplyOptionsInGame(Conf.Conf)
end
end
-- Function that handles ModOptions
local modOptions = function()
-- Add our apply event functions to the settings
for i,_ in pairs(OPTIONS.options_data) do
if not OPTIONS.options_data[i].tooltip then
local name = OPTIONS.options_data[i].name
if name then
name = name .. "_tooltip"
local tt = getText(name)
if tt ~= name then -- getText returns the same string if no translation exists, so just check for that
OPTIONS.options_data[i].tooltip = tt
end
end
end
OPTIONS.options_data[i].OnApplyMainMenu = applyModOptions
OPTIONS.options_data[i].OnApplyInGame = applyModOptionsGame
end
-- Load our stuff
ModOptions:getInstance(OPTIONS)
ModOptions:loadFile()
applyModOptions({settings = OPTIONS})
-- Build our Configuration
Events.OnInitGlobalModData.Add(function()
applyModOptionsGame({settings = OPTIONS})
end)
end
-- Add support for loading the ModOptions config file, even if ModOptions is not currently active
local forceModOptionsConfig = function()
-- Set our defaults
local config = {}
for i,v in pairs(OPTIONS.options_data) do
config[i] = v.default
end
-- Read and apply configuration from the local ini file
local function Load()
local file = getFileReader("mods_options.ini", false)
local line = ""
local found = false
if file then
while true do
line = file:readLine()
if not line then
break
end
line = line:trim()
if line ~= "" then
local next = false
local k = line:match('^%[([^%[%]]+)%]$')
if k and k == OPTIONS.mod_id then
found = true
next = true
elseif k and k ~= OPTIONS.mod_id then
if found then break end -- we found the next one, so we're done
end
if found and not next then
local i, v = line:match('^([%w|_]+)%s-=%s-(.+)$')
if(i and v)then
v = v:trim()
i = i:trim()
if(tonumber(v))then
v = tonumber(v)
elseif(v:lower() == 'true')then
v = true
elseif(v:lower() == 'false')then
v = false
else -- we only want the above
v = nil
end
config = config or {}
-- if we failed to read from config, then keep the default
config[i] = (v == nil and config[i]) or v
end
end
end
end
file:close()
end
end
Load()
if isDebugEnabled() then
print("Force Loading Mod Options")
for i,v in pairs(config) do
print(" Loaded: " .. i .. " = " .. tostring(v))
end
end
-- add condition to not do this?
Conf.Local = config
Conf.SyncConfig()
if Conf.OnApplyOptions then
Conf.OnApplyOptions(Conf.Local)
end
end
Conf._onBoot = function()
-- Runs on the local client, or in singleplayer
if isClient() or not isServer() then
-- Add ModOptions if installed, sync Sandbox and ModOptions
if OPTIONS and ModOptions and ModOptions.getInstance then
modOptions()
else
-- No ModOptions? That's fine, just sync our defined Mod Options and Sandbox options anyways
Events.OnInitGlobalModData.Add(forceModOptionsConfig)
end
else
-- If its a server, just sync our Sandbox config
Events.OnInitGlobalModData.Add(Conf.SyncConfig)
end
end
return Conf

View File

@@ -0,0 +1,234 @@
-- Only load in Single Player or if a Multiplayer client
if not (isClient() or not isServer()) then return end
-- Storage module for defining keybinds used in the game.
local keyman = {
-- -- keys = {
-- [key] = {
-- ["OnKeyPressed"] = {}
-- ["OnKeyStartPressed"] = {},
-- },
-- }
keys = {},
-- Functions, indexed by their keybinds
funcs = {},
addKeys = {}
}
local conf
local addTo = function(key, data, input)
local o = data[key] or {}
o[#o+1] = input
data[key] = o
return data
end
-- Add a function to the map by event
--- @param keyName string
--- @param events table
---- events should be a table of functions, indexed by event | { ["event"]=function, ["event"]=function }
---- valid events are "OnKeyStartPressed", "OnModKeyStartPressed", "OnKeyKeepPressed", "OnModKeyKeepPressed", "OnKeyPressed", "OnModKeyPressed"
keyman.addKeyEvents = function(keyName, events)
keyman.funcs = addTo(keyName, keyman.funcs, events)
end
-- Add a function to the map by event
--- @param section string
--- @param keyName string
--- @param default integer
--- @param events table
---- events should be a table of functions, indexed by event | { ["event"]=function, ["event"]=function }
---- valid events are "OnKeyStartPressed", "OnModKeyStartPressed", "OnKeyKeepPressed", "OnModKeyKeepPressed", "OnKeyPressed", "OnModKeyPressed"
keyman.addKeybind = function(section, keyName, default, events)
keyman.addKeys = addTo(section, keyman.addKeys, {value=keyName, key=default or 0})
if events then
keyman.addKeyEvents(keyName, events)
end
end
local isMKdown = false
-- Returns if the Modkey is down
--- @return boolean
keyman.isModkeyDown = function()
return isMKdown
end
-- Prints keys in the `funcs` table, pre-cache
--- Used for Debug
keyman.PrintFuncs = function()
print("Functions: ")
for i,v in pairs(keyman.funcs) do
print("Key: " .. i)
for j,k in ipairs(v) do
print(" Index: " .. tostring(j))
for name,func in pairs(k) do
print(" Has Event: " .. name .. " | Function: " .. tostring(func))
end
end
end
end
-- Prints keys in the `keys` table, the cache
--- Used for Debug, only available in game
keyman.PrintKeys = function()
print("Keys: ")
for i,v in pairs(keyman.keys) do
print("Key: " .. i)
for j,event in pairs(v) do
print(" Event: " .. tostring(j) .. " | Total: " .. tostring(event and #event))
for index,func in ipairs(event) do
print(" Index: " .. index .. " | Function: " .. tostring(func))
end
end
end
end
local handleInput = function(key, mevent, event)
local temp = keyman.keys[key] and (keyman.keys[key][mevent] or keyman.keys[key][event])
if not temp then return end
for i=1, #temp do
temp[i](key)
end
end
local _onKeyPressed = function(key)
handleInput(key, (isMKdown and "OnModKeyPressed"), "OnKeyPressed")
end
local _onKeyStartPressed = function(key)
handleInput(key, (isMKdown and "OnModKeyStartPressed"), "OnKeyStartPressed")
end
local _onKeyKeepPressed = function(key)
handleInput(key, (isMKdown and "OnModKeyKeepPressed"), "OnKeyKeepPressed")
end
local _onCustomUIKey = function(key)
handleInput(key, (isMKdown and "OnCustomUIModKey"), "OnCustomUIKey")
end
-- Check if our given function has been already added to the current key/event
---- this could be better, but most of the time this should be a relatively small check
local checkIfExists = function(obj, data)
if not obj then return false end
for _,v in ipairs(obj) do
if v == data then
return true
end
end
return false
end
keyman.buildKeymap = function()
keyman.keys = {}
for i,v in pairs(keyman.funcs) do
-- get the key for the bind we have stored
local key = getCore():getKey(i)
-- check if we didn't get a key for some reason...
if key then
-- get the index for this key in our object
local obj = keyman.keys[key] or {}
for _,k in ipairs(v) do
for event, func in pairs(k) do
if not checkIfExists(obj[event], func) then
obj = addTo(event, obj, func)
end
end
end
-- reassign
keyman.keys[key] = obj
end
end
--keyman.PrintKeys()
end
local _isKeyDown = isKeyDown
local function modkey(key)
isMKdown = _isKeyDown(key)
end
-- this is for when we disable the event, need to prevent those modkeys from being added; they're not events
local modkeyevents = {
["OnModKeyPressed"] = true,
["OnModKeyStartPressed"] = true,
["OnModKeyKeepPressed"] = true,
["OnCustomUIModKey"] = true,
}
-- Build our Keymap and setup our events
keyman._onStart = function()
keyman.addKeyEvents('Bindaid_Modkey', {
["OnKeyStartPressed"] = modkey,
["OnKeyPressed"] = modkey,
})
if conf.Local.keyinputOptimize then
keyman.buildKeymap()
Events.OnKeyPressed.Add(_onKeyPressed)
Events.OnKeyStartPressed.Add(_onKeyStartPressed)
Events.OnKeyKeepPressed.Add(_onKeyKeepPressed)
Events.OnCustomUIKey.Add(_onCustomUIKey)
else
-- If the keyinput optimizer is disabled, this will only contain functions added by other mods
---- Add those keys to the event stack
for _,v in pairs(keyman.funcs) do
for _,k in ipairs(v) do
for event, func in pairs(k) do
-- skip modkey events
if not modkeyevents[event] then
Events[event].Add(func)
end
end
end
end
end
end
local postBoot = function()
conf = require('BindAidConfig')
local keys = {}
local headers = {}
local index
-- index the current keyBinding variable
for _,v in ipairs(keyBinding) do
if luautils.stringStarts(v.value, "[") then
index = v.value
keys[index] = {}
headers[#headers+1] = v.value
else
keys[index][#keys[index]+1] = v
end
end
-- Add our functions to the appropriate section
for section,binds in pairs(keyman.addKeys) do
--print("Section: " .. tostring(section))
if not keys[section] then
headers[#headers+1] = section
keys[section] = {}
end
for _,k in ipairs(binds) do
--print(" Key: " .. tostring(k.value) .. " = " .. tostring(k.key))
keys[section][#keys[section]+1] = k
end
end
-- re-add our bindings back into the keyBinding variable
keyBinding = {}
for _,v in ipairs(headers) do
--print("Index: " .. tostring(i) .. " | Header: " .. v)
keyBinding[#keyBinding+1] = {value = v, key = nil} -- header
for _,k in ipairs(keys[v]) do
--print(" Value: " .. k.value .. " | Key: " .. k.key)
keyBinding[#keyBinding+1] = {value = k.value, key = k.key} -- let's make a deep copy
end
end
end
keyman._onBoot = function()
Events.OnGameBoot.Add(postBoot)
end
return keyman

View File

@@ -0,0 +1,34 @@
UI_EN = {
UI_Init_Bindaid = "Hello: BindAid!",
UI_optionscreen_binding_Bindaid = "BindAid",
UI_optionscreen_binding_Bindaid_Modkey = "Modifier Key",
UI_optionscreen_binding_Bindaid_MouseKey_2 = "Middle Mouse Button",
UI_optionscreen_binding_Bindaid_MouseKey_3 = "Mouse Button 3",
UI_optionscreen_binding_Bindaid_MouseKey_4 = "Mouse Button 4",
UI_optionscreen_binding_Bindaid_MouseKey_5 = "Mouse Button 5",
UI_optionscreen_binding_Bindaid_MouseKey_6 = "Mouse Button 6",
UI_optionscreen_binding_Bindaid_MouseKey_7 = "Mouse Button 7",
UI_optionscreen_binding_Bindaid_MouseKey_8 = "Mouse Button 8",
UI_optionscreen_binding_Bindaid_MouseKey_9 = "Mouse Button 9",
UI_optionscreen_binding_Bindaid_MouseKey_10 ="Mouse Button 10",
UI_optionscreen_binding_Bindaid_MouseKey_11 ="Mouse Button 11",
UI_optionscreen_binding_Bindaid_MouseKey_12 ="Mouse Button 12",
UI_ModOptions_Bindaid_autohideMouse = "AutoHide Mouse",
UI_ModOptions_Bindaid_autohideMouse_tooltip = "Hide the mouse after it has not been moved.",
UI_ModOptions_Bindaid_autohideMouseTime = "AutoHide Mouse Delay",
UI_ModOptions_Bindaid_UI_ModOptions_Bindaid_autohideMouseTime_tooltip = "AutoHide the Mouse after this many Seconds",
UI_ModOptions_Bindaid_mouseButtonSupport = "Enable Additional Mouse Button Support",
UI_ModOptions_Bindaid_mouseButtonSupport_tooltip = "NOTE: You MUST restart the game if this is changed.",
UI_ModOptions_Bindaid_mouseButtonCount = "Additional Mouse Buttons",
UI_ModOptions_Bindaid_mouseButtonCount_tooltip = "Number of additional Mouse Buttons to support. <LINE> NOTE: You MUST restart the game if this is changed.",
UI_ModOptions_Bindaid_emulateAndEvent = "Run Mouse and Emulated Events",
UI_ModOptions_Bindaid_emulateAndEvent_tooltip = "When a Mouse Button is pressed, run both the Mouse Event functions and the Emulated Key if set. If disabled, only the assigned Emulated Key is performed. If no Emulated Key, then Mouse Events are used.",
UI_ModOptions_Bindaid_keyinputOptimize = "Enable Keyboard Input Optimization",
UI_ModOptions_Bindaid_keyinputOptimize_tooltip = "Enables the Keyboard Input Optimization, please read the Mod's Description for full information on this. <LINE> If you receive any issues with input, please disable this. <LINE> NOTE: You MUST restart the game if this is changed while in-game.",
}

View File

@@ -0,0 +1,11 @@
name=BindAid
id=BindAid
authors=dhert
description=
description=Optimizes keyboard input, adds native mousebutton emulation, and more!
pzversion=41
tags=Interface;Framework;Misc
poster=poster.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB