yl_api_nodestages/internal.lua
2024-07-04 14:43:14 +02:00

210 lines
6.4 KiB
Lua

-- The functions and variables in this file are only for use in the mod itself.
-- Those that do real work should be local and wrapped in public functions
local function log(text)
local logmessage = yl_api_nodestages.t("log_prefix",
yl_api_nodestages.modname, text)
if yl_api_nodestages.settings.debug then
minetest.log("action", logmessage)
end
return logmessage
end
function yl_api_nodestages.log(text) return log(text) end
local function remove_timer(pos)
local t = minetest.get_node_timer(pos)
t:stop()
end
function yl_api_nodestages.remove_timer(pos) return remove_timer(pos) end
function yl_api_nodestages.on_destruct(pos) return remove_timer(pos) end
local function on_construct(pos)
local node = minetest.get_node(pos)
local nodename = node.name
local stage = minetest.registered_nodes[nodename]._stage
local duration = stage.duration or 0
local node_definition = minetest.registered_nodes[nodename]
-- node functions
if ((minetest.registered_nodes[nodename] == nil) or
-- Only add a nodetimer if the node does not yet have one
(minetest.registered_nodes[nodename].on_timer)) then
node_definition.on_timer = function(tpos, elapsed)
yl_api_nodestages.on_timer(tpos, elapsed, stage.duration)
end
end
if (duration > 0) then
local current_duration = duration
local t = minetest.get_node_timer(pos)
t:start(current_duration)
end
end
function yl_api_nodestages.on_construct(pos) return on_construct(pos) end
local function get_target_nodename(node, pos, next_stages)
local sum = 0
for _, stage_chance in pairs(next_stages) do sum = sum + stage_chance[2] end
local dice = math.random(sum)
for _, stage_chance in pairs(next_stages) do
dice = dice - stage_chance[2]
if dice <= 0 then
if (minetest.registered_nodes[stage_chance[1]] == nil) then
minetest.log("warning",
yl_api_nodestages.t(
"target_nodestage_does_not_exist",
dump(stage_chance[1]), dump(node.name),
dump(pos)))
return nil
elseif ((type(stage_chance[3]) == "function") and (stage_chance[3](pos) == false) ) then
return node.name
else
return stage_chance[1]
end
end
end
-- should never return this
return yl_api_nodestages.error
end
local function on_timer(pos, elapsed)
local t1 = core.get_us_time()
numz = numz +1
local node = minetest.get_node(pos)
local stage = minetest.registered_nodes[node.name]._stage
local target_nodename
local timer = 0
local duration
if (stage == nil) or (stage.next_stages == nil) then
yl_api_nodestages.remove_timer(pos)
bucket = bucket + (core.get_us_time() - t1)
return
end
repeat
duration = stage.duration
timer = timer + duration
target_nodename = get_target_nodename(node, pos, stage.next_stages)
if (target_nodename == yl_api_nodestages.error) then
-- Thing kaputt, stop it.
minetest.log("error", yl_api_nodestages.t("undefined_state_abort"))
yl_api_nodestages.remove_timer(pos)
bucket = bucket + (core.get_us_time() - t1)
return
end
if (target_nodename == nil) then
-- Fallback to last known target_nodename
target_nodename = stage.stage_name
break
else
-- Last stage most often does not have a _stage
stage = minetest.registered_nodes[target_nodename] and
minetest.registered_nodes[target_nodename]._stage or nil
end
until ((timer >= elapsed) or (stage == nil) or (stage.duration == 0))
--[[
if (node.name == target_nodename) then
bucket = bucket + (core.get_us_time() - t1)
return true
end
]]--
minetest.set_node(pos, {name = target_nodename})
local remaining = timer - elapsed
if (stage and stage.duration and (remaining > 0)) then
local nodetimer = minetest.get_node_timer(pos)
nodetimer:set(stage.duration, remaining)
end
bucket = bucket + (core.get_us_time() - t1)
end
function yl_api_nodestages.on_timer(pos, elapsed) return on_timer(pos, elapsed) end
-- Validation
--
function get_valid_copy_of_stage(stage)
if (type(stage) ~= "table") then
return false, t("stage_not_table")
end
local stage = table.copy(stage)
if (yl_api_nodestages.is_valid_stage(stage) == false) then
return false, t("stage_not_valid")
end
local nodename = stage.stage_name
local overwrite = stage.overwrite
if (((overwrite == false) or (overwrite == nil)) and
(minetest.registered_nodes[nodename] ~= nil)) then
-- No overwrite, but item exists
return false, yl_api_nodestages.t("error_item_exists", dump(nodename))
end
return true, stage
end
function yl_api_nodestages.get_valid_copy_of_stage(stage)
return get_valid_copy_of_stage(stage)
end
local function is_valid_stage(stage)
return true -- TODO: Implement validation
end
function yl_api_nodestages.is_valid(stages)
local good, bad, total = 0,0,0
local reasons = {}
for _, stage in ipairs(stage) do
total = total + 1
local success, message = is_valid_stage(stage)
if (success == true) then
good = good + 1
else
bad = bad + 1
table.insert(reasons, message)
end
end
if (bad == 0) then
minetest.log("action",
"[MOD] yl_api_nodestages : bad = " .. tostring(bad) ..
", good = " .. tostring(good) .. ", total = " ..
tostring(total))
return true, good, bad, total, reasons
else
minetest.log("warning",
"[MOD] yl_api_nodestages : bad = " .. tostring(bad) ..
", good = " .. tostring(good) .. ", total = " ..
tostring(total))
return false, good, bad, total, reasons
end
end
function yl_api_nodestages.validate_all_stages()
local stages = {}
for _, def in pairs(minetest.registered_nodes) do
local stage = def._stage
table.insert(stages, stage)
end
return yl_api_nodestages.is_valid(stages)
end