diff options
Diffstat (limited to 'mesecons')
-rw-r--r-- | mesecons/actionqueue.lua | 23 | ||||
-rw-r--r-- | mesecons/init.lua | 8 | ||||
-rw-r--r-- | mesecons/internal.lua | 89 | ||||
-rw-r--r-- | mesecons/services.lua | 2 | ||||
-rw-r--r-- | mesecons/settings.lua | 30 | ||||
-rw-r--r-- | mesecons/util.lua | 88 | ||||
-rw-r--r-- | mesecons/wires.lua | 6 |
7 files changed, 157 insertions, 89 deletions
diff --git a/mesecons/actionqueue.lua b/mesecons/actionqueue.lua index fa4079f..e300ea7 100644 --- a/mesecons/actionqueue.lua +++ b/mesecons/actionqueue.lua @@ -23,7 +23,7 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior -- Otherwise, add the action to the queue if overwritecheck then -- check if old action has to be overwritten / removed: for i, ac in ipairs(mesecon.queue.actions) do - if(mesecon.cmpPos(pos, ac.pos) + if(vector.equals(pos, ac.pos) and mesecon.cmpAny(overwritecheck, ac.owcheck)) then toremove = i break @@ -94,25 +94,8 @@ end -- Store and read the ActionQueue to / from a file -- so that upcoming actions are remembered when the game -- is restarted - -local wpath = minetest.get_worldpath() -local function file2table(filename) - local f = io.open(filename, "r") - if f==nil then return {} end - local t = f:read("*all") - f:close() - if t=="" or t==nil then return {} end - return minetest.deserialize(t) -end - -local function table2file(filename, table) - local f = io.open(filename, "w") - f:write(minetest.serialize(table)) - f:close() -end - -mesecon.queue.actions = file2table(wpath.."/mesecon_actionqueue") +mesecon.queue.actions = mesecon.file2table("mesecon_actionqueue") minetest.register_on_shutdown(function() - mesecon.queue.actions = table2file(wpath.."/mesecon_actionqueue", mesecon.queue.actions) + mesecon.table2file("mesecon_actionqueue", mesecon.queue.actions) end) diff --git a/mesecons/init.lua b/mesecons/init.lua index 8645f03..3ab4f4a 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -74,7 +74,7 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) -- if area (any of the rule targets) is not loaded, keep trying and call this again later for _, rule in ipairs(mesecon.flattenrules(rules)) do - local np = mesecon.addPosRule(pos, rule) + local np = vector.add(pos, rule) -- if area is not loaded, keep trying if minetest.get_node_or_nil(np) == nil then mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) @@ -84,7 +84,7 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) -- execute action for _, rule in ipairs(mesecon.flattenrules(rules)) do - local np = mesecon.addPosRule(pos, rule) + local np = vector.add(pos, rule) local rulenames = mesecon.rules_link_rule_all(pos, rule) for _, rulename in ipairs(rulenames) do mesecon.turnon(np, rulename) @@ -101,7 +101,7 @@ mesecon.queue:add_function("receptor_off", function (pos, rules) -- if area (any of the rule targets) is not loaded, keep trying and call this again later for _, rule in ipairs(mesecon.flattenrules(rules)) do - local np = mesecon.addPosRule(pos, rule) + local np = vector.add(pos, rule) if minetest.get_node_or_nil(np) == nil then mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) return @@ -109,7 +109,7 @@ mesecon.queue:add_function("receptor_off", function (pos, rules) end for _, rule in ipairs(mesecon.flattenrules(rules)) do - local np = mesecon.addPosRule(pos, rule) + local np = vector.add(pos, rule) local rulenames = mesecon.rules_link_rule_all(pos, rule) for _, rulename in ipairs(rulenames) do if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then diff --git a/mesecons/internal.lua b/mesecons/internal.lua index 741abf1..d479852 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -77,6 +77,8 @@ function mesecon.get_conductor(nodename) end function mesecon.get_any_outputrules (node) + if not node then return nil end + if mesecon.is_conductor(node.name) then return mesecon.conductor_get_rules(node) elseif mesecon.is_receptor(node.name) then @@ -85,6 +87,8 @@ function mesecon.get_any_outputrules (node) end function mesecon.get_any_inputrules (node) + if not node then return nil end + if mesecon.is_conductor(node.name) then return mesecon.conductor_get_rules(node) elseif mesecon.is_effector(node.name) then @@ -182,7 +186,9 @@ end -- Activation: mesecon.queue:add_function("activate", function (pos, rulename) - local node = minetest.get_node(pos) + local node = mesecon.get_node_force(pos) + if not node then return end + local effector = mesecon.get_effector(node.name) if effector and effector.action_on then @@ -203,7 +209,9 @@ end -- Deactivation mesecon.queue:add_function("deactivate", function (pos, rulename) - local node = minetest.get_node(pos) + local node = mesecon.get_node_force(pos) + if not node then return end + local effector = mesecon.get_effector(node.name) if effector and effector.action_off then @@ -224,7 +232,9 @@ end -- Change mesecon.queue:add_function("change", function (pos, rulename, changetype) - local node = minetest.get_node(pos) + local node = mesecon.get_node_force(pos) + if not node then return end + local effector = mesecon.get_effector(node.name) if effector and effector.action_change then @@ -249,6 +259,8 @@ end -- Conductors function mesecon.is_conductor_on(node, rulename) + if not node then return false end + local conductor = mesecon.get_conductor(node.name) if conductor then if conductor.state then @@ -263,10 +275,13 @@ function mesecon.is_conductor_on(node, rulename) return mesecon.get_bit(binstate, bit) end end + return false end function mesecon.is_conductor_off(node, rulename) + if not node then return false end + local conductor = mesecon.get_conductor(node.name) if conductor then if conductor.state then @@ -281,6 +296,7 @@ function mesecon.is_conductor_off(node, rulename) return not mesecon.get_bit(binstate, bit) end end + return false end @@ -340,16 +356,16 @@ end -- some more general high-level stuff function mesecon.is_power_on(pos, rulename) - local node = minetest.get_node(pos) - if mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name) then + local node = mesecon.get_node_force(pos) + if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then return true end return false end function mesecon.is_power_off(pos, rulename) - local node = minetest.get_node(pos) - if mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name) then + local node = mesecon.get_node_force(pos) + if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then return true end return false @@ -361,7 +377,7 @@ function mesecon.turnon(pos, link) local depth = 1 while frontiers[depth] do local f = frontiers[depth] - local node = minetest.get_node_or_nil(f.pos) + local node = mesecon.get_node_force(f.pos) -- area not loaded, postpone action if not node then @@ -374,10 +390,10 @@ function mesecon.turnon(pos, link) -- call turnon on neighbors: normal rules for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do - local np = mesecon.addPosRule(f.pos, r) + local np = vector.add(f.pos, r) -- area not loaded, postpone action - if not minetest.get_node_or_nil(np) then + if not mesecon.get_node_force(np) then mesecon.queue:add_action(np, "turnon", {rulename}, nil, true) else @@ -407,7 +423,7 @@ function mesecon.turnoff(pos, link) local depth = 1 while frontiers[depth] do local f = frontiers[depth] - local node = minetest.get_node_or_nil(f.pos) + local node = mesecon.get_node_force(f.pos) -- area not loaded, postpone action if not node then @@ -420,10 +436,10 @@ function mesecon.turnoff(pos, link) -- call turnoff on neighbors: normal rules for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do - local np = mesecon.addPosRule(f.pos, r) + local np = vector.add(f.pos, r) -- area not loaded, postpone action - if not minetest.get_node_or_nil(np) then + if not mesecon.get_node_force(np) then mesecon.queue:add_action(np, "turnoff", {rulename}, nil, true) else @@ -449,7 +465,8 @@ end) function mesecon.connected_to_receptor(pos, link) - local node = minetest.get_node(pos) + local node = mesecon.get_node_force(pos) + if not node then return false end -- Check if conductors around are connected local rules = mesecon.get_any_inputrules(node) @@ -458,7 +475,7 @@ function mesecon.connected_to_receptor(pos, link) for _, rule in ipairs(mesecon.rule2meta(link, rules)) do local links = mesecon.rules_link_rule_all_inverted(pos, rule) for _, l in ipairs(links) do - local np = mesecon.addPosRule(pos, l) + local np = vector.add(pos, l) if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then return true end @@ -476,7 +493,7 @@ function mesecon.find_receptor_on(pos, link) local depth = 1 while frontiers[depth] do local f = frontiers[depth] - local node = minetest.get_node_or_nil(f.pos) + local node = mesecon.get_node_force(f.pos) if not node then return false end if mesecon.is_receptor_on(node.name) then return true end @@ -485,7 +502,7 @@ function mesecon.find_receptor_on(pos, link) -- call turnoff on neighbors: normal rules for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do - local np = mesecon.addPosRule(f.pos, r) + local np = vector.add(f.pos, r) local links = mesecon.rules_link_rule_all_inverted(f.pos, r) for _, l in ipairs(links) do @@ -503,8 +520,9 @@ function mesecon.find_receptor_on(pos, link) end function mesecon.rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule - local outputnode = minetest.get_node(output) - local inputnode = minetest.get_node(input) + local outputnode = mesecon.get_node_force(output) + local inputnode = mesecon.get_node_force(input) + local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode) local inputrules = mesecon.get_any_inputrules (inputnode) if not outputrules or not inputrules then @@ -513,21 +531,22 @@ function mesecon.rules_link(output, input, dug_outputrules) --output/input are p for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do -- Check if output sends to input - if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then + if vector.equals(vector.add(output, outputrule), input) then for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do -- Check if input accepts from output - if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then + if vector.equals(vector.add(input, inputrule), output) then return true, inputrule end end end end + return false end function mesecon.rules_link_rule_all(output, rule) - local input = mesecon.addPosRule(output, rule) - local inputnode = minetest.get_node(input) + local input = vector.add(output, rule) + local inputnode = mesecon.get_node_force(input) local inputrules = mesecon.get_any_inputrules (inputnode) if not inputrules then return {} @@ -536,17 +555,18 @@ function mesecon.rules_link_rule_all(output, rule) for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do -- Check if input accepts from output - if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then + if vector.equals(vector.add(input, inputrule), output) then table.insert(rules, inputrule) end end + return rules end function mesecon.rules_link_rule_all_inverted(input, rule) --local irule = mesecon.invertRule(rule) - local output = mesecon.addPosRule(input, rule) - local outputnode = minetest.get_node(output) + local output = vector.add(input, rule) + local outputnode = mesecon.get_node_force(output) local outputrules = mesecon.get_any_outputrules (outputnode) if not outputrules then return {} @@ -554,7 +574,7 @@ function mesecon.rules_link_rule_all_inverted(input, rule) local rules = {} for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do - if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then + if vector.equals(vector.add(output, outputrule), input) then table.insert(rules, mesecon.invertRule(outputrule)) end end @@ -566,7 +586,7 @@ function mesecon.rules_link_anydir(pos1, pos2) end function mesecon.is_powered(pos, rule) - local node = minetest.get_node(pos) + local node = mesecon.get_node_force(pos) local rules = mesecon.get_any_inputrules(node) if not rules then return false end @@ -577,10 +597,11 @@ function mesecon.is_powered(pos, rule) for _, rule in ipairs(mesecon.flattenrules(rules)) do local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) for _, rname in ipairs(rulenames) do - local np = mesecon.addPosRule(pos, rname) - local nn = minetest.get_node(np) - if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) - or mesecon.is_receptor_on (nn.name)) then + local np = vector.add(pos, rname) + local nn = mesecon.get_node_force(np) + + if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname)) + or mesecon.is_receptor_on(nn.name)) then table.insert(sourcepos, np) end end @@ -588,8 +609,8 @@ function mesecon.is_powered(pos, rule) else local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) for _, rname in ipairs(rulenames) do - local np = mesecon.addPosRule(pos, rname) - local nn = minetest.get_node(np) + local np = vector.add(pos, rname) + local nn = mesecon.get_node_force(np) if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) or mesecon.is_receptor_on (nn.name)) then table.insert(sourcepos, np) diff --git a/mesecons/services.lua b/mesecons/services.lua index 215fb31..5d0f81e 100644 --- a/mesecons/services.lua +++ b/mesecons/services.lua @@ -16,7 +16,7 @@ mesecon.on_placenode = function (pos, node) -- also call receptor_on if itself is powered already, so that neighboring -- conductors will be activated (when pushing an on-conductor with a piston) for _, s in ipairs(sources) do - local rule = {x = pos.x - s.x, y = pos.y - s.y, z = pos.z - s.z} + local rule = vector.subtract(pos, s) mesecon.turnon(pos, rule) end --mesecon.receptor_on (pos, mesecon.conductor_get_rules(node)) diff --git a/mesecons/settings.lua b/mesecons/settings.lua index 50240c3..1ebbfde 100644 --- a/mesecons/settings.lua +++ b/mesecons/settings.lua @@ -1,15 +1,15 @@ --- SETTINGS
-function mesecon.setting(setting, default)
- if type(default) == "boolean" then
- local read = minetest.setting_getbool("mesecon."..setting)
- if read == nil then
- return default
- else
- return read
- end
- elseif type(default) == "string" then
- return minetest.setting_get("mesecon."..setting) or default
- elseif type(default) == "number" then
- return tonumber(minetest.setting_get("mesecon."..setting) or default)
- end
-end
+-- SETTINGS +function mesecon.setting(setting, default) + if type(default) == "boolean" then + local read = minetest.setting_getbool("mesecon."..setting) + if read == nil then + return default + else + return read + end + elseif type(default) == "string" then + return minetest.setting_get("mesecon."..setting) or default + elseif type(default) == "number" then + return tonumber(minetest.setting_get("mesecon."..setting) or default) + end +end diff --git a/mesecons/util.lua b/mesecons/util.lua index dd33f1c..3827dce 100644 --- a/mesecons/util.lua +++ b/mesecons/util.lua @@ -2,7 +2,7 @@ function mesecon.move_node(pos, newpos) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos):to_table() minetest.remove_node(pos) - minetest.add_node(newpos, node) + minetest.set_node(newpos, node) minetest.get_meta(pos):from_table(meta) end @@ -50,7 +50,7 @@ function mesecon.rule2bit(findrule, allrules) end for m,metarule in ipairs( allrules) do for _, rule in ipairs(metarule ) do - if mesecon.cmpPos(findrule, rule) then + if vector.equals(findrule, rule) then return m end end @@ -69,7 +69,7 @@ function mesecon.rule2metaindex(findrule, allrules) for m, metarule in ipairs( allrules) do for _, rule in ipairs(metarule ) do - if mesecon.cmpPos(findrule, rule) then + if vector.equals(findrule, rule) then return m end end @@ -133,15 +133,7 @@ function mesecon.set_bit(binary,bit,value) end function mesecon.invertRule(r) - return {x = -r.x, y = -r.y, z = -r.z} -end - -function mesecon.addPosRule(p, r) - return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z} -end - -function mesecon.cmpPos(p1, p2) - return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z) + return vector.multiply(r, -1) end function mesecon.tablecopy(table) -- deep table copy @@ -209,3 +201,75 @@ function mesecon.flipstate(pos, node) return newstate end + +-- File writing / reading utilities +local wpath = minetest.get_worldpath() +function mesecon.file2table(filename) + local f = io.open(wpath..DIR_DELIM..filename, "r") + if f == nil then return {} end + local t = f:read("*all") + f:close() + if t == "" or t == nil then return {} end + return minetest.deserialize(t) +end + +function mesecon.table2file(filename, table) + local f = io.open(wpath..DIR_DELIM..filename, "w") + f:write(minetest.serialize(table)) + f:close() +end + +-- Forceloading: Force server to load area if node is nil +local BLOCKSIZE = 16 + +-- convert node position --> block hash +local function hash_blockpos(pos) + return minetest.hash_node_position({ + x = math.floor(pos.x/BLOCKSIZE), + y = math.floor(pos.y/BLOCKSIZE), + z = math.floor(pos.z/BLOCKSIZE) + }) +end + +-- convert block hash --> node position +local function unhash_blockpos(hash) + return vector.multiply(minetest.get_position_from_hash(hash), BLOCKSIZE) +end + +mesecon.forceloaded_blocks = {} + +-- get node and force-load area +function mesecon.get_node_force(pos) + local hash = hash_blockpos(pos) + + if mesecon.forceloaded_blocks[hash] == nil then + -- if no more forceload spaces are available, try again next time + if minetest.forceload_block(pos) then + mesecon.forceloaded_blocks[hash] = 0 + end + else + mesecon.forceloaded_blocks[hash] = 0 + end + + return minetest.get_node_or_nil(pos) +end + +minetest.register_globalstep(function (dtime) + for hash, time in pairs(mesecon.forceloaded_blocks) do + -- unload forceloaded blocks after 10 minutes without usage + if (time > mesecon.setting("forceload_timeout", 600)) then + minetest.forceload_free_block(unhash_blockpos(hash)) + mesecon.forceloaded_blocks[hash] = nil + else + mesecon.forceloaded_blocks[hash] = time + dtime + end + end +end) + +-- Store and read the forceloaded blocks to / from a file +-- so that those blocks are remembered when the game +-- is restarted +mesecon.forceloaded_blocks = mesecon.file2table("mesecon_forceloaded") +minetest.register_on_shutdown(function() + mesecon.table2file("mesecon_forceloaded", mesecon.forceloaded_blocks) +end) diff --git a/mesecons/wires.lua b/mesecons/wires.lua index 18ae8f5..d77904e 100644 --- a/mesecons/wires.lua +++ b/mesecons/wires.lua @@ -22,7 +22,7 @@ local wire_getconnect = function (from_pos, self_pos) end for _, r in ipairs(mesecon.flattenrules(rules)) do - if (mesecon.cmpPos(mesecon.addPosRule(self_pos, r), from_pos)) then + if (vector.equals(vector.add(self_pos, r), from_pos)) then return true end end @@ -35,7 +35,7 @@ local wire_updateconnect = function (pos) local connections = {} for _, r in ipairs(mesecon.rules.default) do - if wire_getconnect(pos, mesecon.addPosRule(pos, r)) then + if wire_getconnect(pos, vector.add(pos, r)) then table.insert(connections, r) end end @@ -83,7 +83,7 @@ local update_on_place_dig = function (pos, node) if (not rules) then return end for _, r in ipairs(mesecon.flattenrules(rules)) do - local np = mesecon.addPosRule(pos, r) + local np = vector.add(pos, r) if minetest.registered_nodes[minetest.get_node(np).name] and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then wire_updateconnect(np) |