controls/init.lua

120 lines
4.2 KiB
Lua

controls = {
--util values
modpath = minetest.get_modpath("controls"),
testsmode = minetest.settings:get_bool("controls_enable_tests", false),
--location to store callbacks
registered_on_press = {},
registered_on_hold = {},
registered_on_release = {},
--store player control data
players = {},
}
--api functions
function controls.register_on_press(callback)
table.insert(controls.registered_on_press, callback)
end
function controls.register_on_hold(callback)
table.insert(controls.registered_on_hold, callback)
end
function controls.register_on_release(callback)
table.insert(controls.registered_on_release, callback)
end
--set up key store on join
minetest.register_on_joinplayer(function(player, _)
local pname = player:get_player_name()
local controls_names = player:get_player_control()
--note: could hardcode this, but this is more future proof in case minetest adds more controls
controls.players[pname] = {}
for key, _ in pairs(controls_names) do
--[[
in theory the control value is false when they join, but hard coding just in case
consider changing this to named key table instead of numeric for better readability???
]]
controls.players[pname][key] = {false}
end
end)
--discard when leaving
minetest.register_on_leaveplayer(function(player, _)
local pname = player:get_player_name()
controls.players[pname] = nil
end)
--event loop
minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do
local pname = player:get_player_name()
local pcontrols = player:get_player_control()
if not controls.players[pname] then break end --safety check
--consider using minetest.get_us_time() instead of os.clock()? would need to convert to seconds however
for key, key_status in pairs(pcontrols) do
if key_status and not controls.players[pname][key][1] then
for _, callback in pairs(controls.registered_on_press) do
callback(player, key)
end
controls.players[pname][key] = {true, minetest.get_us_time()}
elseif key_status and controls.players[pname][key][1] then
for _, callback in pairs(controls.registered_on_hold) do
callback(player, key, (minetest.get_us_time() - controls.players[pname][key][2]) / 1e6)
end
elseif not key_status and controls.players[pname][key][1] then
for _, callback in pairs(controls.registered_on_release) do
callback(player, key, (minetest.get_us_time() - controls.players[pname][key][2]) / 1e6)
end
controls.players[pname][key] = {false}
end
end
end
end)
--special keys
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_nodes) do
local old_node_drop = def.on_drop
local on_drop = function(itemstack, dropper, ...)
for _, callback in pairs(controls.registered_on_press) do
callback(dropper, "_drop")
end
return old_node_drop(itemstack, dropper, unpack({...}))
end
minetest.override_item(name, {
on_drop = on_drop
})
end
local old_reg_node = minetest.register_node
function minetest.register_node(name, def)
if def.on_drop then
local old_node_drop = def.on_drop
def.on_drop = function(itemstack, dropper, ...)
for _, callback in pairs(controls.registered_on_press) do
callback(dropper, "_drop")
end
return old_node_drop(itemstack, dropper, unpack({...}))
end
else
def.on_drop = function(itemstack, dropper, ...)
for _, callback in pairs(controls.registered_on_press) do
callback(dropper, "_drop")
end
return minetest.item_drop(itemstack, dropper, unpack({...}))
end
end
old_reg_node(name, def)
end
end)
--tests
if(controls.testsmode) then
dofile(controls.modpath .. "/test.lua")
end