2017-06-02 17:15:49 +02:00
|
|
|
|
2019-05-31 13:47:17 +02:00
|
|
|
-- helpers:
|
|
|
|
|
2017-06-03 12:05:32 +02:00
|
|
|
local meaning = {
|
|
|
|
[0] = "up", "down", "left",
|
|
|
|
"right", "jump", "aux1",
|
|
|
|
"sneak", "LMB", "RMB"
|
|
|
|
}
|
2017-06-02 17:15:49 +02:00
|
|
|
|
|
|
|
local function bits_to_table(bits)
|
|
|
|
if type(bits) ~= "number" then
|
|
|
|
return bits
|
|
|
|
end
|
|
|
|
local t = {}
|
2017-06-03 12:05:32 +02:00
|
|
|
for i = #meaning, 0, -1 do
|
2017-06-02 17:15:49 +02:00
|
|
|
local n = 2^i
|
|
|
|
if bits >= n then
|
|
|
|
bits = bits - n
|
|
|
|
t[meaning[i]] = true
|
|
|
|
else
|
|
|
|
t[meaning[i]] = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
|
2017-06-03 12:05:32 +02:00
|
|
|
local function table_to_bits(t)
|
|
|
|
if type(t) ~= "table" then
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
local bits = 0
|
|
|
|
for i = 0, #meaning do
|
|
|
|
if t[meaning[i]] then
|
|
|
|
bits = bits + 2^i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return bits
|
|
|
|
end
|
|
|
|
|
|
|
|
local function make_true(t)
|
|
|
|
local out = {}
|
|
|
|
for i = 1, #t do
|
|
|
|
out[t[i]] = true
|
|
|
|
end
|
|
|
|
for i = 0, #meaning do
|
|
|
|
out[meaning[i]] = out[meaning[i]] or false
|
|
|
|
end
|
|
|
|
return out
|
|
|
|
end
|
|
|
|
|
|
|
|
local function look_differences(bitsa, bitsb)
|
|
|
|
if not bitsb then
|
|
|
|
return 511
|
|
|
|
end
|
|
|
|
local diff = 0
|
|
|
|
for i = #meaning, 0, -1 do
|
|
|
|
local n = 2^i
|
|
|
|
local a = bitsa - n >= 0
|
|
|
|
local b = bitsb - n >= 0
|
|
|
|
if a ~= b then
|
|
|
|
diff = diff + n
|
|
|
|
end
|
|
|
|
bitsa = bitsa - ((a and n) or 0)
|
|
|
|
bitsb = bitsb - ((b and n) or 0)
|
|
|
|
end
|
|
|
|
return diff
|
|
|
|
end
|
|
|
|
|
|
|
|
local function is_different(diff_shall, diff_is)
|
2017-06-03 12:09:59 +02:00
|
|
|
if diff_shall == 511 then
|
|
|
|
return true
|
|
|
|
end
|
2017-06-03 12:05:32 +02:00
|
|
|
for i = #meaning, 0, -1 do
|
|
|
|
local n = 2^i
|
|
|
|
local a = diff_shall - n >= 0
|
|
|
|
local b = diff_is - n >= 0
|
|
|
|
if a and b then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
diff_shall = diff_shall - ((a and n) or 0)
|
|
|
|
diff_is = diff_is - ((b and n) or 0)
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local function handle_keys(keys, func)
|
|
|
|
local keyst = type(keys)
|
|
|
|
if keyst == "function" then
|
|
|
|
func = keys
|
|
|
|
keys = 511
|
|
|
|
elseif keyst == "string" then
|
|
|
|
for i = 0, #meaning do
|
|
|
|
if keys == meaning[i] then
|
|
|
|
keys = 2^i
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif keyst == "table" then
|
|
|
|
keys = table_to_bits((#keys >= 1 and make_true(keys)) or keys)
|
|
|
|
elseif keyst ~= "number" then
|
|
|
|
keys = 511
|
|
|
|
end
|
|
|
|
return keys, func
|
|
|
|
end
|
|
|
|
|
2019-05-31 13:47:17 +02:00
|
|
|
local function add_func_to_callback_origins(func)
|
|
|
|
-- this is taken from minetest/builtin/game/register.lua
|
|
|
|
minetest.callback_origins[func] = {
|
|
|
|
mod = core.get_current_modname() or "??",
|
|
|
|
name = debug.getinfo(1, "n").name or "??"
|
|
|
|
}
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- global functions:
|
|
|
|
|
2017-06-03 12:05:32 +02:00
|
|
|
keyevent = {}
|
2019-05-31 13:47:17 +02:00
|
|
|
|
2017-06-03 12:05:32 +02:00
|
|
|
local keyevents_bits = {}
|
|
|
|
function keyevent.register_on_keypress_bits(keys, func)
|
|
|
|
keys, func = handle_keys(keys, func)
|
2019-05-31 13:47:17 +02:00
|
|
|
add_func_to_callback_origins(func)
|
|
|
|
if not keyevents_bits[keys] then
|
|
|
|
keyevents_bits[keys] = {func}
|
|
|
|
return
|
|
|
|
end
|
|
|
|
keyevents_bits[keys][#keyevents_bits[keys] + 1] = func
|
2017-06-03 12:05:32 +02:00
|
|
|
end
|
2019-05-31 13:47:17 +02:00
|
|
|
|
2017-06-03 12:05:32 +02:00
|
|
|
local keyevents = {}
|
2019-05-26 09:45:56 +02:00
|
|
|
function keyevent.register_on_keypress(keys, func)
|
2017-06-03 12:05:32 +02:00
|
|
|
keys, func = handle_keys(keys, func)
|
2019-05-31 13:47:17 +02:00
|
|
|
add_func_to_callback_origins(func)
|
|
|
|
if not keyevents[keys] then
|
|
|
|
keyevents[keys] = {func}
|
|
|
|
return
|
|
|
|
end
|
|
|
|
keyevents[keys][#keyevents[keys] + 1] = func
|
2017-06-03 12:05:32 +02:00
|
|
|
end
|
2019-05-31 13:47:17 +02:00
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- use minetest registration fuctions:
|
2017-06-03 12:05:32 +02:00
|
|
|
|
2017-06-02 17:15:49 +02:00
|
|
|
local function on_step(dtime, player, old_keys, keys, player_name)
|
|
|
|
if keys == old_keys then
|
|
|
|
return
|
|
|
|
end
|
2017-06-03 12:05:32 +02:00
|
|
|
local diff = look_differences(keys, old_keys)
|
2019-05-31 13:47:17 +02:00
|
|
|
for diff_shall, fs in pairs(keyevents_bits) do
|
2017-06-03 12:05:32 +02:00
|
|
|
if is_different(diff_shall, diff) then
|
2019-05-31 13:47:17 +02:00
|
|
|
minetest.run_callbacks(fs, -1, keys, old_keys, dtime, player_name)
|
2017-06-03 12:05:32 +02:00
|
|
|
end
|
2017-06-02 17:15:49 +02:00
|
|
|
end
|
|
|
|
local keys_t = bits_to_table(keys)
|
|
|
|
local old_keys_t = bits_to_table(old_keys)
|
2019-05-31 13:47:17 +02:00
|
|
|
for diff_shall, fs in pairs(keyevents) do
|
2017-06-03 12:05:32 +02:00
|
|
|
if is_different(diff_shall, diff) then
|
2019-05-31 13:47:17 +02:00
|
|
|
minetest.run_callbacks(fs, -1, keys_t, old_keys_t, dtime, player_name)
|
2017-06-03 12:05:32 +02:00
|
|
|
end
|
2017-06-02 17:15:49 +02:00
|
|
|
end
|
|
|
|
return keys
|
|
|
|
end
|
|
|
|
|
2019-05-31 13:47:17 +02:00
|
|
|
if INIT == "client" then -- csm
|
2017-06-02 17:15:49 +02:00
|
|
|
local localplayer
|
|
|
|
minetest.register_on_connect(function()
|
|
|
|
localplayer = minetest.localplayer
|
|
|
|
end)
|
|
|
|
|
|
|
|
local keys
|
|
|
|
local f = on_step
|
|
|
|
function on_step(dtime)
|
|
|
|
if not localplayer then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
keys = f(dtime, localplayer, keys, localplayer:get_key_pressed()) or keys
|
|
|
|
end
|
|
|
|
|
2019-05-31 13:47:17 +02:00
|
|
|
elseif INIT == "game" then -- ssm
|
2017-06-02 17:15:49 +02:00
|
|
|
local keys = {}
|
|
|
|
local f = on_step
|
|
|
|
function on_step(dtime)
|
|
|
|
local players = minetest.get_connected_players()
|
|
|
|
for i = 1, #players do
|
|
|
|
local player_name = players[i]:get_player_name()
|
|
|
|
keys[player_name] = f(dtime, players[i], keys[player_name],
|
|
|
|
players[i]:get_player_control_bits(), player_name) or
|
|
|
|
keys[player_name]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
else
|
|
|
|
function on_step()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
minetest.register_globalstep(on_step)
|