--[[ __ __ | | __ ____ ___.__. _______ __ ____ _____/ |_ | |/ // __ < | |/ __ \ \/ // __ \ / \ __\ | <\ ___/\___ \ ___/\ /\ ___/| | \ | |__|_ \\___ > ____|\___ >\_/ \___ >___| /__| \/ \/\/ \/ \/ \/ --]] 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) 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(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