mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-31 10:15:34 +00:00
181 lines
5.9 KiB
Lua
181 lines
5.9 KiB
Lua
local core = require('openmw.core')
|
|
local input = require('openmw.input')
|
|
local util = require('openmw.util')
|
|
local async = require('openmw.async')
|
|
local storage = require('openmw.storage')
|
|
local ui = require('openmw.ui')
|
|
|
|
local I = require('openmw.interfaces')
|
|
|
|
local actionPressHandlers = {}
|
|
local function onActionPress(id, handler)
|
|
actionPressHandlers[id] = actionPressHandlers[id] or {}
|
|
table.insert(actionPressHandlers[id], handler)
|
|
end
|
|
|
|
local function bindHold(key, actionId)
|
|
input.bindAction(key, async:callback(function()
|
|
return input.isActionPressed(actionId)
|
|
end), {})
|
|
end
|
|
|
|
local function bindMovement(key, actionId, axisId, direction)
|
|
input.bindAction(key, async:callback(function()
|
|
local actionActive = input.isActionPressed(actionId)
|
|
local axisActive = input.getAxisValue(axisId) * direction > 0
|
|
return (actionActive or axisActive) and 1 or 0
|
|
end), {})
|
|
end
|
|
|
|
local function bindTrigger(key, actionid)
|
|
onActionPress(actionid, function()
|
|
input.activateTrigger(key)
|
|
end)
|
|
end
|
|
|
|
bindTrigger('AlwaysRun', input.ACTION.AlwaysRun)
|
|
bindTrigger('ToggleSneak', input.ACTION.Sneak)
|
|
bindTrigger('ToggleWeapon', input.ACTION.ToggleWeapon)
|
|
bindTrigger('ToggleSpell', input.ACTION.ToggleSpell)
|
|
bindTrigger('Jump', input.ACTION.Jump)
|
|
bindTrigger('AutoMove', input.ACTION.AutoMove)
|
|
bindTrigger('Inventory', input.ACTION.Inventory)
|
|
bindTrigger('Journal', input.ACTION.Journal)
|
|
bindTrigger('QuickKeysMenu', input.ACTION.QuickKeysMenu)
|
|
|
|
bindHold('TogglePOV', input.ACTION.TogglePOV)
|
|
bindHold('Sneak', input.ACTION.Sneak)
|
|
|
|
bindHold('Run', input.ACTION.Run)
|
|
input.bindAction('Run', async:callback(function(_, value)
|
|
local controllerInput = util.vector2(
|
|
input.getAxisValue(input.CONTROLLER_AXIS.MoveForwardBackward),
|
|
input.getAxisValue(input.CONTROLLER_AXIS.MoveLeftRight)
|
|
):length2()
|
|
return value or controllerInput > 0.25
|
|
end), {})
|
|
|
|
input.bindAction('Use', async:callback(function()
|
|
-- The value "0.6" shouldn't exceed the triggering threshold in BindingsManager::actionValueChanged.
|
|
-- TODO: Move more logic from BindingsManager to Lua and consider to make this threshold configurable.
|
|
return input.isActionPressed(input.ACTION.Use) or input.getAxisValue(input.CONTROLLER_AXIS.TriggerRight) >= 0.6
|
|
end), {})
|
|
|
|
bindMovement('MoveBackward', input.ACTION.MoveBackward, input.CONTROLLER_AXIS.MoveForwardBackward, 1)
|
|
bindMovement('MoveForward', input.ACTION.MoveForward, input.CONTROLLER_AXIS.MoveForwardBackward, -1)
|
|
bindMovement('MoveRight', input.ACTION.MoveRight, input.CONTROLLER_AXIS.MoveLeftRight, 1)
|
|
bindMovement('MoveLeft', input.ACTION.MoveLeft, input.CONTROLLER_AXIS.MoveLeftRight, -1)
|
|
|
|
do
|
|
local zoomInOut = 0
|
|
onActionPress(input.ACTION.ZoomIn, function()
|
|
zoomInOut = zoomInOut + 1
|
|
end)
|
|
onActionPress(input.ACTION.ZoomOut, function()
|
|
zoomInOut = zoomInOut - 1
|
|
end)
|
|
input.bindAction('Zoom3rdPerson', async:callback(function(dt, _, togglePOV)
|
|
local Zoom3rdPerson = zoomInOut * 10
|
|
if togglePOV then
|
|
local triggerLeft = input.getAxisValue(input.CONTROLLER_AXIS.TriggerLeft)
|
|
local triggerRight = input.getAxisValue(input.CONTROLLER_AXIS.TriggerRight)
|
|
local controllerZoom = (triggerRight - triggerLeft) * 100 * dt
|
|
Zoom3rdPerson = Zoom3rdPerson + controllerZoom
|
|
end
|
|
zoomInOut = 0
|
|
return Zoom3rdPerson
|
|
end), { 'TogglePOV' })
|
|
end
|
|
|
|
local bindingSection = storage.playerSection('OMWInputBindings')
|
|
|
|
local keyboardPresses = {}
|
|
local keybordHolds = {}
|
|
local boundActions = {}
|
|
|
|
local function bindAction(action)
|
|
if boundActions[action] then return end
|
|
boundActions[action] = true
|
|
input.bindAction(action, async:callback(function()
|
|
if keybordHolds[action] then
|
|
for _, binding in pairs(keybordHolds[action]) do
|
|
if input.isKeyPressed(binding.code) then return true end
|
|
end
|
|
end
|
|
return false
|
|
end), {})
|
|
end
|
|
|
|
local function registerBinding(binding, id)
|
|
if not input.actions[binding.key] and not input.triggers[binding.key] then
|
|
print(string.format('Skipping binding for unknown action or trigger: "%s"', binding.key))
|
|
return
|
|
end
|
|
if binding.type == 'keyboardPress' then
|
|
local bindings = keyboardPresses[binding.code] or {}
|
|
bindings[id] = binding
|
|
keyboardPresses[binding.code] = bindings
|
|
elseif binding.type == 'keyboardHold' then
|
|
local bindings = keybordHolds[binding.key] or {}
|
|
bindings[id] = binding
|
|
keybordHolds[binding.key] = bindings
|
|
bindAction(binding.key)
|
|
else
|
|
error('Unknown binding type "' .. binding.type .. '"')
|
|
end
|
|
end
|
|
|
|
function clearBinding(id)
|
|
for _, boundTriggers in pairs(keyboardPresses) do
|
|
boundTriggers[id] = nil
|
|
end
|
|
for _, boundKeys in pairs(keybordHolds) do
|
|
boundKeys[id] = nil
|
|
end
|
|
end
|
|
|
|
bindingSection:subscribe(async:callback(function(_, id)
|
|
if not id then return end
|
|
local binding = bindingSection:get(id)
|
|
clearBinding(id)
|
|
if binding ~= nil then
|
|
registerBinding(binding, id)
|
|
end
|
|
return id
|
|
end))
|
|
|
|
|
|
local initiated = false
|
|
|
|
local function init()
|
|
for id, binding in pairs(bindingSection:asTable()) do
|
|
registerBinding(binding, id)
|
|
end
|
|
end
|
|
|
|
return {
|
|
engineHandlers = {
|
|
onFrame = function()
|
|
if not initiated then
|
|
initiated = true
|
|
init()
|
|
end
|
|
end,
|
|
onInputAction = function(id)
|
|
if not actionPressHandlers[id] then
|
|
return
|
|
end
|
|
for _, handler in ipairs(actionPressHandlers[id]) do
|
|
handler()
|
|
end
|
|
end,
|
|
onKeyPress = function(e)
|
|
local bindings = keyboardPresses[e.code]
|
|
if bindings then
|
|
for _, binding in pairs(bindings) do
|
|
input.activateTrigger(binding.key)
|
|
end
|
|
end
|
|
end,
|
|
}
|
|
}
|