-- 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