51b5aa8b94
Avoid calling get_player_name too much
119 lines
3.1 KiB
Lua
119 lines
3.1 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local math, minetest, nodecore, pairs, table, type, unpack
|
|
= math, minetest, nodecore, pairs, table, type, unpack
|
|
local math_floor, table_insert
|
|
= math.floor, table.insert
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
local steps = {}
|
|
nodecore.registered_playersteps = steps
|
|
|
|
local counters = {}
|
|
function nodecore.register_playerstep(def)
|
|
local label = def.label
|
|
if not label then
|
|
label = minetest.get_current_modname()
|
|
local i = (counters[label] or 0) + 1
|
|
counters[label] = i
|
|
label = label .. ":" .. i
|
|
end
|
|
|
|
local prio = def.priority or 0
|
|
def.priority = prio
|
|
local min = 1
|
|
local max = #steps + 1
|
|
while max > min do
|
|
local try = math_floor((min + max) / 2)
|
|
local oldp = steps[try].priority
|
|
if (prio < oldp) or (prio == oldp and label > steps[try].label) then
|
|
min = try + 1
|
|
else
|
|
max = try
|
|
end
|
|
end
|
|
|
|
table_insert(steps, min, def)
|
|
end
|
|
|
|
local function clone(x)
|
|
if type(x) == "table" then
|
|
local t = {}
|
|
for k, v in pairs(x) do t[k] = clone(v) end
|
|
return t
|
|
end
|
|
return x
|
|
end
|
|
|
|
local mismatch = nodecore.prop_mismatch
|
|
|
|
local function setdelta(cur, old)
|
|
if not cur then return end
|
|
if not old then return cur end
|
|
local set
|
|
for k, v in pairs(cur) do
|
|
if mismatch(v, old[k]) then
|
|
set = set or {}
|
|
set[k] = v
|
|
end
|
|
end
|
|
return set
|
|
end
|
|
|
|
local cache = {}
|
|
local function step_player(player, dtime)
|
|
local pname = player:get_player_name()
|
|
local data = cache[pname] or {pname = pname}
|
|
data.physics = player:get_physics_override()
|
|
local orig_phys = clone(data.physics)
|
|
data.properties = player:get_properties()
|
|
local orig_props = clone(data.properties)
|
|
do
|
|
local b, t, x, c = player:get_sky()
|
|
local s = player:get_sky_color()
|
|
data.sky = {
|
|
base_color = b,
|
|
type = t,
|
|
textures = x,
|
|
clouds = c,
|
|
sky_color = s
|
|
}
|
|
end
|
|
local orig_sky = clone(data.sky)
|
|
data.daynight = player:get_day_night_ratio()
|
|
local orig_daynight = clone(data.daynight)
|
|
data.animation = {player:get_animation()}
|
|
local orig_anim = clone(data.animation)
|
|
data.hud_flags = player:hud_get_flags()
|
|
local orig_hud = clone(data.hud_flags)
|
|
data.control = player:get_player_control()
|
|
for _, def in pairs(steps) do
|
|
def.action(player, data, dtime)
|
|
end
|
|
local phys = setdelta(data.physics, orig_phys)
|
|
if phys then player:set_physics_override(phys) end
|
|
local props = setdelta(data.properties, orig_props)
|
|
if props then player:set_properties(props) end
|
|
if mismatch(data.animation, orig_anim) then
|
|
player:set_animation(unpack(data.animation))
|
|
end
|
|
if mismatch(data.sky, orig_sky) then player:set_sky(data.sky) end
|
|
if mismatch(data.daynight, orig_daynight) then
|
|
player:override_day_night_ratio(data.daynight)
|
|
end
|
|
local hud = setdelta(data.hud_flags, orig_hud)
|
|
if hud then player:hud_set_flags(hud) end
|
|
cache[pname] = data
|
|
end
|
|
|
|
nodecore.register_globalstep("player steps", function(dtime)
|
|
for _, player in pairs(minetest.get_connected_players()) do
|
|
step_player(player, dtime)
|
|
end
|
|
end)
|
|
minetest.register_on_joinplayer(function(player)
|
|
step_player(player, 0)
|
|
end)
|
|
minetest.register_on_leaveplayer(function(player)
|
|
cache[player:get_player_name()] = nil
|
|
end)
|