From 3e827c23b9a9df72f55150ac38214444edd697f3 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Wed, 27 Sep 2017 17:49:49 +0100 Subject: [PATCH] flowing_logic.lua: separate out new logic into seperate file --- flowing_logic.lua | 118 ------------------------------------------- new_flow_logic.lua | 121 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 118 deletions(-) create mode 100644 new_flow_logic.lua diff --git a/flowing_logic.lua b/flowing_logic.lua index 50a4c99..632baa6 100644 --- a/flowing_logic.lua +++ b/flowing_logic.lua @@ -132,121 +132,3 @@ pipeworks.fountainhead_check = function(pos, node) end end end - - - --- global values and thresholds for water behaviour --- TODO: add some way of setting this per-world -local thresholds = {} --- limit on pump pressure - will not absorb more than can be taken -thresholds.pump_pressure = 2 - - - --- borrowed from above: might be useable to replace the above coords tables -local make_coords_offsets = function(pos, include_base) - local coords = { - {x=pos.x,y=pos.y-1,z=pos.z}, - {x=pos.x,y=pos.y+1,z=pos.z}, - {x=pos.x-1,y=pos.y,z=pos.z}, - {x=pos.x+1,y=pos.y,z=pos.z}, - {x=pos.x,y=pos.y,z=pos.z-1}, - {x=pos.x,y=pos.y,z=pos.z+1}, - } - if include_base then table.insert(coords, pos) end - return coords -end - - - --- local debuglog = function(msg) print("## "..msg) end - - - --- new version of liquid check --- accepts a limit parameter to only delete water blocks that the receptacle can accept, --- and returns it so that the receptacle can update it's pressure values. --- this should ensure that water blocks aren't vanished from existance. --- will take care of zero or negative-valued limits. -pipeworks.check_for_liquids_v2 = function(pos, limit) - if not limit then - limit = 6 - end - local coords = make_coords_offsets(pos, false) - local total = 0 - for index, tpos in ipairs(coords) do - if total >= limit then break end - local name = minetest.get_node(tpos).name - if name == "default:water_source" then - minetest.remove_node(tpos) - total = total + 1 - end - end - return total -end - - - -local label_pressure = "pipeworks.water_pressure" -local label_haspressure = "pipeworks.is_pressure_node" -pipeworks.balance_pressure = function(pos, node) - -- debuglog("balance_pressure() "..node.name.." at "..pos.x.." "..pos.y.." "..pos.z) - -- check the pressure of all nearby nodes, and average it out. - -- for the moment, only balance neighbour nodes if it already has a pressure value. - -- XXX: maybe this could be used to add fluid behaviour to other mod's nodes too? - - -- unconditionally include self in nodes to average over - local meta = minetest.get_meta(pos) - local currentpressure = meta:get_float(label_pressure) - meta:set_int(label_haspressure, 1) - local connections = { meta } - local totalv = currentpressure - local totalc = 1 - - -- then handle neighbours, but if not a pressure node don't consider them at all - for _, npos in ipairs(make_coords_offsets(pos, false)) do - local neighbour = minetest.get_meta(npos) - local haspressure = (neighbour:get_int(label_haspressure) ~= 0) - if haspressure then - local n = neighbour:get_float(label_pressure) - table.insert(connections, neighbour) - totalv = totalv + n - totalc = totalc + 1 - end - end - - local average = totalv / totalc - for _, targetmeta in ipairs(connections) do - targetmeta:set_float(label_pressure, average) - end -end - - - -pipeworks.run_pump_intake = function(pos, node) - -- try to absorb nearby water nodes, but only up to limit. - -- NB: check_for_liquids_v2 handles zero or negative from the following subtraction - local meta = minetest.get_meta(pos) - local currentpressure = meta:get_float(label_pressure) - local intake_limit = thresholds.pump_pressure - currentpressure - local actual_intake = pipeworks.check_for_liquids_v2(pos, intake_limit) - local newpressure = actual_intake + currentpressure - -- debuglog("oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake.." newpressure "..newpressure) - meta:set_float(label_pressure, newpressure) -end - - - -pipeworks.run_spigot_output = function(pos, node) - -- try to output a water source node if there's enough pressure and space below. - local meta = minetest.get_meta(pos) - local currentpressure = meta:get_float(label_pressure) - if currentpressure > 1 then - local below = {x=pos.x, y=pos.y-1, z=pos.z} - local name = minetest.get_node(below).name - if (name == "air") or (name == "default:water_flowing") then - minetest.set_node(below, {name="default:water_source"}) - meta:set_float(label_pressure, currentpressure - 1) - end - end -end diff --git a/new_flow_logic.lua b/new_flow_logic.lua new file mode 100644 index 0000000..3fd1bb6 --- /dev/null +++ b/new_flow_logic.lua @@ -0,0 +1,121 @@ +-- reimplementation of new_flow_logic branch: processing functions +-- written 2017 by thetaepsilon + + + +-- global values and thresholds for water behaviour +-- TODO: add some way of setting this per-world +local thresholds = {} +-- limit on pump pressure - will not absorb more than can be taken +thresholds.pump_pressure = 2 + + + +-- borrowed from above: might be useable to replace the above coords tables +local make_coords_offsets = function(pos, include_base) + local coords = { + {x=pos.x,y=pos.y-1,z=pos.z}, + {x=pos.x,y=pos.y+1,z=pos.z}, + {x=pos.x-1,y=pos.y,z=pos.z}, + {x=pos.x+1,y=pos.y,z=pos.z}, + {x=pos.x,y=pos.y,z=pos.z-1}, + {x=pos.x,y=pos.y,z=pos.z+1}, + } + if include_base then table.insert(coords, pos) end + return coords +end + + + +-- local debuglog = function(msg) print("## "..msg) end + + + +-- new version of liquid check +-- accepts a limit parameter to only delete water blocks that the receptacle can accept, +-- and returns it so that the receptacle can update it's pressure values. +-- this should ensure that water blocks aren't vanished from existance. +-- will take care of zero or negative-valued limits. +pipeworks.check_for_liquids_v2 = function(pos, limit) + if not limit then + limit = 6 + end + local coords = make_coords_offsets(pos, false) + local total = 0 + for index, tpos in ipairs(coords) do + if total >= limit then break end + local name = minetest.get_node(tpos).name + if name == "default:water_source" then + minetest.remove_node(tpos) + total = total + 1 + end + end + return total +end + + + + +local label_pressure = "pipeworks.water_pressure" +local label_haspressure = "pipeworks.is_pressure_node" +pipeworks.balance_pressure = function(pos, node) + -- debuglog("balance_pressure() "..node.name.." at "..pos.x.." "..pos.y.." "..pos.z) + -- check the pressure of all nearby nodes, and average it out. + -- for the moment, only balance neighbour nodes if it already has a pressure value. + -- XXX: maybe this could be used to add fluid behaviour to other mod's nodes too? + + -- unconditionally include self in nodes to average over + local meta = minetest.get_meta(pos) + local currentpressure = meta:get_float(label_pressure) + meta:set_int(label_haspressure, 1) + local connections = { meta } + local totalv = currentpressure + local totalc = 1 + + -- then handle neighbours, but if not a pressure node don't consider them at all + for _, npos in ipairs(make_coords_offsets(pos, false)) do + local neighbour = minetest.get_meta(npos) + local haspressure = (neighbour:get_int(label_haspressure) ~= 0) + if haspressure then + local n = neighbour:get_float(label_pressure) + table.insert(connections, neighbour) + totalv = totalv + n + totalc = totalc + 1 + end + end + + local average = totalv / totalc + for _, targetmeta in ipairs(connections) do + targetmeta:set_float(label_pressure, average) + end +end + + + +pipeworks.run_pump_intake = function(pos, node) + -- try to absorb nearby water nodes, but only up to limit. + -- NB: check_for_liquids_v2 handles zero or negative from the following subtraction + local meta = minetest.get_meta(pos) + local currentpressure = meta:get_float(label_pressure) + local intake_limit = thresholds.pump_pressure - currentpressure + local actual_intake = pipeworks.check_for_liquids_v2(pos, intake_limit) + local newpressure = actual_intake + currentpressure + -- debuglog("oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake.." newpressure "..newpressure) + meta:set_float(label_pressure, newpressure) +end + + + +pipeworks.run_spigot_output = function(pos, node) + -- try to output a water source node if there's enough pressure and space below. + local meta = minetest.get_meta(pos) + local currentpressure = meta:get_float(label_pressure) + if currentpressure > 1 then + local below = {x=pos.x, y=pos.y-1, z=pos.z} + local name = minetest.get_node(below).name + if (name == "air") or (name == "default:water_flowing") then + minetest.set_node(below, {name="default:water_source"}) + meta:set_float(label_pressure, currentpressure - 1) + end + end +end