keyevent/init.lua
2019-05-26 09:45:56 +02:00

191 lines
3.9 KiB
Lua

--[[
__ __
| | __ ____ ___.__. _______ __ ____ _____/ |_
| |/ // __ < | |/ __ \ \/ // __ \ / \ __\
| <\ ___/\___ \ ___/\ /\ ___/| | \ |
|__|_ \\___ > ____|\___ >\_/ \___ >___| /__|
\/ \/\/ \/ \/ \/
--]]
local load_time_start = os.clock()
local modname = minetest.get_current_modname()
local meaning = {
[0] = "up", "down", "left",
"right", "jump", "aux1",
"sneak", "LMB", "RMB"
}
local function bits_to_table(bits)
if type(bits) ~= "number" then
return bits
end
local t = {}
for i = #meaning, 0, -1 do
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
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)
if diff_shall == 511 then
return true
end
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
keyevent = {}
local keyevents_bits = {}
function keyevent.register_on_keypress_bits(keys, func)
keys, func = handle_keys(keys, func)
keyevents_bits[keys] = func
end
local keyevents = {}
function keyevent.register_on_keypress(keys, func)
keys, func = handle_keys(keys, func)
keyevents[keys] = func
end
local function on_step(dtime, player, old_keys, keys, player_name)
if keys == old_keys then
return
end
local diff = look_differences(keys, old_keys)
for diff_shall, f in pairs(keyevents_bits) do
if is_different(diff_shall, diff) then
f(keys, old_keys, dtime, player_name)
end
end
local keys_t = bits_to_table(keys)
local old_keys_t = bits_to_table(old_keys)
for diff_shall, f in pairs(keyevents) do
if is_different(diff_shall, diff) then
f(keys_t, old_keys_t, dtime, player_name)
end
end
return keys
end
if INIT == "client" then
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
elseif INIT == "game" then
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)
local time = math.floor(tonumber(os.clock()-load_time_start)*100+0.5)/100
local msg = "["..modname.."] loaded after ca. "..time
if time > 0.05 then
print(msg)
else
minetest.log("info", msg)
end