From c3627551b091d27819c242da204ed1e9dd8f15f0 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 30 Sep 2017 23:42:26 +0100 Subject: move all current new_flow_logic code to dedicated sub-directory --- new_flow_logic/abm_register.lua | 49 ++++++++++++ new_flow_logic/abms.lua | 123 ++++++++++++++++++++++++++++++ new_flow_logic/flowable_node_registry.lua | 59 ++++++++++++++ new_flow_logic/register_local_pipes.lua | 53 +++++++++++++ 4 files changed, 284 insertions(+) create mode 100644 new_flow_logic/abm_register.lua create mode 100644 new_flow_logic/abms.lua create mode 100644 new_flow_logic/flowable_node_registry.lua create mode 100644 new_flow_logic/register_local_pipes.lua (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua new file mode 100644 index 0000000..e7bed6a --- /dev/null +++ b/new_flow_logic/abm_register.lua @@ -0,0 +1,49 @@ +-- register new flow logic ABMs +-- written 2017 by thetaepsilon + + + +local register = {} +pipeworks.flowlogic.abmregister = register + + + +-- register a node name for the pressure balancing ABM. +-- currently this only exists as a per-node function to allow nodes to be registered outside pipeworks. +local register_abm_balance = function(nodename) + minetest.register_abm({ + nodenames = { nodename }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + pipeworks.flowlogic.balance_pressure(pos, node) + end + }) +end +register.balance = register_abm_balance + +-- register a node for the pump ABM. +-- maxpressure is the maximum pressure that this pump can drive. +local register_abm_input = function(nodename, maxpressure) + minetest.register_abm({ + nodenames = { nodename }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + pipeworks.flowlogic.run_pump_intake(pos, node) + end + }) +end +register.input = register_abm_input + +-- old spigot ABM code, not yet migrated +--[[ + minetest.register_abm({ + nodenames = { spigot_on, spigot_off }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + pipeworks.run_spigot_output(pos, node) + end + }) +]] diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua new file mode 100644 index 0000000..7360668 --- /dev/null +++ b/new_flow_logic/abms.lua @@ -0,0 +1,123 @@ +-- reimplementation of new_flow_logic branch: processing functions +-- written 2017 by thetaepsilon + + + +local flowlogic = {} +pipeworks.flowlogic = flowlogic + + + +-- 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. +local 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 +flowlogic.check_for_liquids_v2 = check_for_liquids_v2 + + + +local label_pressure = "pipeworks.water_pressure" +local label_haspressure = "pipeworks.is_pressure_node" +flowlogic.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 + + + +flowlogic.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 properties = pipeworks.flowables.inputs.list[node.name] + local maxpressure = properties.maxpressure + + local meta = minetest.get_meta(pos) + local currentpressure = meta:get_float(label_pressure) + + local intake_limit = maxpressure - currentpressure + local actual_intake = 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 + + + +flowlogic.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/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua new file mode 100644 index 0000000..def9649 --- /dev/null +++ b/new_flow_logic/flowable_node_registry.lua @@ -0,0 +1,59 @@ +-- registration code for nodes under new flow logic +-- written 2017 by thetaepsilon + +pipeworks.flowables = {} +pipeworks.flowables.list = {} +pipeworks.flowables.list.all = {} +-- pipeworks.flowables.list.nodenames = {} + +-- simple flowables - balance pressure in any direction +pipeworks.flowables.list.simple = {} +pipeworks.flowables.list.simple_nodenames = {} + +-- simple intakes - try to absorb any adjacent water nodes +pipeworks.flowables.inputs = {} +pipeworks.flowables.inputs.list = {} +pipeworks.flowables.inputs.nodenames = {} + +-- registration functions +pipeworks.flowables.register = {} +local register = pipeworks.flowables.register + +-- some sanity checking for passed args, as this could potentially be made an external API eventually +local checkexists = function(nodename) + if type(nodename) ~= "string" then error("pipeworks.flowables nodename must be a string!") end + return pipeworks.flowables.list.all[nodename] +end + +local insertbase = function(nodename) + if checkexists(nodename) then error("pipeworks.flowables duplicate registration!") end + pipeworks.flowables.list.all[nodename] = true + -- table.insert(pipeworks.flowables.list.nodenames, nodename) +end + +-- Register a node as a simple flowable. +-- Simple flowable nodes have no considerations for direction of flow; +-- A cluster of adjacent simple flowables will happily average out in any direction. +-- This does *not* register the ABM, as that is done in register_flow_logic.lua; +-- this is so that the new flow logic can remain optional during development. +register.simple = function(nodename) + insertbase(nodename) + pipeworks.flowables.list.simple[nodename] = true + table.insert(pipeworks.flowables.list.simple_nodenames, nodename) +end + +local checkbase = function(nodename) + if not checkexists(nodename) then error("pipeworks.flowables node doesn't exist as a flowable!") end +end + +-- Register a node as a simple intake. +-- See new_flow_logic for the details of this. +-- Expects node to be registered as a flowable (is present in flowables.list.all), +-- so that water can move out of it. +-- maxpressure is the maximum pipeline pressure that this node can drive. +-- possible WISHME here: technic-driven high-pressure pumps +register.intake_simple = function(nodename, maxpressure) + checkbase(nodename) + pipeworks.flowables.inputs.list[nodename] = { maxpressure=maxpressure } + table.insert(pipeworks.flowables.inputs.nodenames, nodename) +end diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua new file mode 100644 index 0000000..6fe8b7e --- /dev/null +++ b/new_flow_logic/register_local_pipes.lua @@ -0,0 +1,53 @@ +-- conditional registration of pipe nodes for the new pipe logic, depending on enable flags. +-- otherwise register_flow_logic.lua would be attempting to register ABMs for non-existant nodes. +-- 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 + + + +local pipes_full_nodenames = pipeworks.pipes_full_nodenames +local pipes_empty_nodenames = pipeworks.pipes_empty_nodenames + +local register = pipeworks.flowables.register +local abmregister = pipeworks.flowlogic.abmregister + + + +-- FIXME: DRY principle for names, move this to devices.lua? +-- FIXME: all devices still considered simple +local pump_on = "pipeworks:pump_on" +local pump_off = "pipeworks:pump_off" +local spigot_off = "pipeworks:spigot" +local spigot_on = "pipeworks:spigot_pouring" + +if pipeworks.enable_pipes then + for _, pipe in ipairs(pipes_full_nodenames) do + register.simple(pipe) + abmregister.balance(pipe) + end + for _, pipe in ipairs(pipes_empty_nodenames) do + register.simple(pipe) + abmregister.balance(pipe) + end + + if pipeworks.enable_pipe_devices then + register.simple(pump_off) + register.simple(pump_on) + register.simple(spigot_on) + register.simple(spigot_off) + abmregister.balance(pump_off) + abmregister.balance(pump_on) + abmregister.balance(spigot_on) + abmregister.balance(spigot_off) + + register.intake_simple(pump_on, thresholds.pump_pressure) + abmregister.input(pump_on, thresholds.pump_pressure) + end +end -- cgit v1.2.3 From 31741e33e20c2ed366f80c01c7d6b4a6a23e0d4c Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 00:00:33 +0100 Subject: new_flow_logic/abms.lua: run_pump_intake(): use passed-in maxpressure instead of table lookup, pass through in abm_register.lua --- new_flow_logic/abm_register.lua | 2 +- new_flow_logic/abms.lua | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index e7bed6a..505ca4b 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -30,7 +30,7 @@ local register_abm_input = function(nodename, maxpressure) interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - pipeworks.flowlogic.run_pump_intake(pos, node) + pipeworks.flowlogic.run_pump_intake(pos, node, maxpressure) end }) end diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 7360668..ece81c1 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -89,13 +89,10 @@ end -flowlogic.run_pump_intake = function(pos, node) +flowlogic.run_pump_intake = function(pos, node, maxpressure) -- 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 properties = pipeworks.flowables.inputs.list[node.name] - local maxpressure = properties.maxpressure - local meta = minetest.get_meta(pos) local currentpressure = meta:get_float(label_pressure) -- cgit v1.2.3 From ec9cf1df5019c915cf7f5776c90cca760670569f Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 00:13:43 +0100 Subject: new_flow_logic/flowable_node_registry.lua: integrate existing ABM registration from register_local_pipes.lua --- new_flow_logic/flowable_node_registry.lua | 11 +++++++++-- new_flow_logic/register_local_pipes.lua | 6 ------ 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index def9649..3cb2a67 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -1,6 +1,9 @@ -- registration code for nodes under new flow logic -- written 2017 by thetaepsilon +-- use for hooking up ABMs as nodes are registered +local abmregister = pipeworks.flowlogic.abmregister + pipeworks.flowables = {} pipeworks.flowables.list = {} pipeworks.flowables.list.all = {} @@ -34,12 +37,13 @@ end -- Register a node as a simple flowable. -- Simple flowable nodes have no considerations for direction of flow; -- A cluster of adjacent simple flowables will happily average out in any direction. --- This does *not* register the ABM, as that is done in register_flow_logic.lua; --- this is so that the new flow logic can remain optional during development. register.simple = function(nodename) insertbase(nodename) pipeworks.flowables.list.simple[nodename] = true table.insert(pipeworks.flowables.list.simple_nodenames, nodename) + if pipeworks.enable_new_flow_logic then + abmregister.balance(nodename) + end end local checkbase = function(nodename) @@ -56,4 +60,7 @@ register.intake_simple = function(nodename, maxpressure) checkbase(nodename) pipeworks.flowables.inputs.list[nodename] = { maxpressure=maxpressure } table.insert(pipeworks.flowables.inputs.nodenames, nodename) + if pipeworks.enable_new_flow_logic then + abmregister.input(nodename, maxpressure) + end end diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua index 6fe8b7e..62b787b 100644 --- a/new_flow_logic/register_local_pipes.lua +++ b/new_flow_logic/register_local_pipes.lua @@ -16,7 +16,6 @@ local pipes_full_nodenames = pipeworks.pipes_full_nodenames local pipes_empty_nodenames = pipeworks.pipes_empty_nodenames local register = pipeworks.flowables.register -local abmregister = pipeworks.flowlogic.abmregister @@ -42,12 +41,7 @@ if pipeworks.enable_pipes then register.simple(pump_on) register.simple(spigot_on) register.simple(spigot_off) - abmregister.balance(pump_off) - abmregister.balance(pump_on) - abmregister.balance(spigot_on) - abmregister.balance(spigot_off) register.intake_simple(pump_on, thresholds.pump_pressure) - abmregister.input(pump_on, thresholds.pump_pressure) end end -- cgit v1.2.3 From aee23d76426734892f1d7129c02c56b58cc813af Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 00:24:45 +0100 Subject: new_flow_logic/register_local_pipes.lua: remove old ABM note in header --- new_flow_logic/register_local_pipes.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua index 62b787b..989ff0c 100644 --- a/new_flow_logic/register_local_pipes.lua +++ b/new_flow_logic/register_local_pipes.lua @@ -1,5 +1,4 @@ --- conditional registration of pipe nodes for the new pipe logic, depending on enable flags. --- otherwise register_flow_logic.lua would be attempting to register ABMs for non-existant nodes. +-- registration of pipework's own pipes. -- written 2017 by thetaepsilon -- cgit v1.2.3 From 3486ee319ee4fafbf83c583dd9fedfaed92db7c4 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 00:44:14 +0100 Subject: abms.lua: refactor and generalise run_pump_intake() to allow passing custom intake functions --- new_flow_logic/abm_register.lua | 4 ++-- new_flow_logic/abms.lua | 20 ++++++++++---------- new_flow_logic/flowable_node_registry.lua | 3 +-- 3 files changed, 13 insertions(+), 14 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index 505ca4b..57c8a47 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -24,13 +24,13 @@ register.balance = register_abm_balance -- register a node for the pump ABM. -- maxpressure is the maximum pressure that this pump can drive. -local register_abm_input = function(nodename, maxpressure) +local register_abm_input = function(nodename, maxpressure, intakefn) minetest.register_abm({ nodenames = { nodename }, interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - pipeworks.flowlogic.run_pump_intake(pos, node, maxpressure) + pipeworks.flowlogic.run_input(pos, node, maxpressure, intakefn) end }) end diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index ece81c1..48dcb0b 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -31,12 +31,7 @@ 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. local 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 @@ -89,15 +84,20 @@ end -flowlogic.run_pump_intake = function(pos, node, maxpressure) - -- try to absorb nearby water nodes, but only up to limit. - -- NB: check_for_liquids_v2 handles zero or negative from the following subtraction +flowlogic.run_input = function(pos, node, maxpressure, intakefn) + -- intakefn allows a given input node to define it's own intake logic. + -- this function will calculate the maximum amount of water that can be taken in; + -- the intakefn will be given this and is expected to return the actual absorption amount. local meta = minetest.get_meta(pos) local currentpressure = meta:get_float(label_pressure) - local intake_limit = maxpressure - currentpressure - local actual_intake = check_for_liquids_v2(pos, intake_limit) + if intake_limit <= 0 then return end + + local actual_intake = intakefn(pos, intake_limit) + if actual_intake <= 0 then return end + if actual_intake >= intake_limit then actual_intake = intake_limit end + local newpressure = actual_intake + currentpressure -- debuglog("oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake.." newpressure "..newpressure) meta:set_float(label_pressure, newpressure) diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index 3cb2a67..1465561 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -51,7 +51,6 @@ local checkbase = function(nodename) end -- Register a node as a simple intake. --- See new_flow_logic for the details of this. -- Expects node to be registered as a flowable (is present in flowables.list.all), -- so that water can move out of it. -- maxpressure is the maximum pipeline pressure that this node can drive. @@ -61,6 +60,6 @@ register.intake_simple = function(nodename, maxpressure) pipeworks.flowables.inputs.list[nodename] = { maxpressure=maxpressure } table.insert(pipeworks.flowables.inputs.nodenames, nodename) if pipeworks.enable_new_flow_logic then - abmregister.input(nodename, maxpressure) + abmregister.input(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) end end -- cgit v1.2.3 From 4cf9c90bb9a2a1f3c1fc938b543198b4ebd885c3 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 12:25:03 +0100 Subject: new flow logic: register_local_pipes.lua: fix leftover calls to abmregister --- new_flow_logic/register_local_pipes.lua | 2 -- 1 file changed, 2 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua index 989ff0c..ca12244 100644 --- a/new_flow_logic/register_local_pipes.lua +++ b/new_flow_logic/register_local_pipes.lua @@ -28,11 +28,9 @@ local spigot_on = "pipeworks:spigot_pouring" if pipeworks.enable_pipes then for _, pipe in ipairs(pipes_full_nodenames) do register.simple(pipe) - abmregister.balance(pipe) end for _, pipe in ipairs(pipes_empty_nodenames) do register.simple(pipe) - abmregister.balance(pipe) end if pipeworks.enable_pipe_devices then -- cgit v1.2.3 From 463e7a206af8e2b98617b549e3bc6dc5eb181ffc Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 12:25:43 +0100 Subject: new flow logic: abms.lua: start splitting apart spigot code into generalised output ABM --- new_flow_logic/abms.lua | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 48dcb0b..640493a 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -4,6 +4,7 @@ local flowlogic = {} +flowlogic.helpers = {} pipeworks.flowlogic = flowlogic @@ -105,6 +106,43 @@ end +-- flowlogic output helper for spigots +-- tries to place a water block in the world beneath the spigot. +-- threshold checking is assumed to be handled by the node registration; +-- see register_local_pipes.lua for the pipeworks default spigot. +flowlogic.helpers.output_spigot = function(pos, node, currentpressure) + local taken = 0 + 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"}) + taken = taken + 1 + end + return taken +end + + + +flowlogic.run_output = function(pos, node, threshold, outputfn) + -- callback for output devices. + -- takes care of checking a minimum pressure value and updating the node metadata. + -- the outputfn is provided the current pressure and returns the pressure "taken". + -- as an example, using this with the above spigot function, + -- the spigot function tries to output a water source if it will fit in the world. + local meta = minetest.get_meta(pos) + -- sometimes I wonder if meta:get_* returning default values would ever be problematic. + -- though here it doesn't matter, an uninit'd node returns 0, which is fine for a new, empty node. + local currentpressure = meta:get_float(label_pressure) + if currentpressure > threshold then + local takenpressure = outputfn(pos, node, currentpressure) + local newpressure = currentpressure - takenpressure + if newpressure < 0 then currentpressure = 0 end + meta:set_float(label_pressure, newpressure) + end +end + + + flowlogic.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) -- cgit v1.2.3 From 15b41d14f3923ce3cea8418a792f83e7763d5b00 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 12:28:22 +0100 Subject: new flow logic: abm_register.lua: update doc comments for register_abm_input() --- new_flow_logic/abm_register.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index 57c8a47..793ea83 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -22,8 +22,9 @@ local register_abm_balance = function(nodename) end register.balance = register_abm_balance --- register a node for the pump ABM. --- maxpressure is the maximum pressure that this pump can drive. +-- register a node for the input ABM. +-- intakefn is run on the node to determine how much water can be taken (and update it's environment accordingly). +-- maxpressure is the maximum pressure that this input can drive, beyond which pressure will not be raised. local register_abm_input = function(nodename, maxpressure, intakefn) minetest.register_abm({ nodenames = { nodename }, -- cgit v1.2.3 From f3a94fcd248df35b4afb992941a58af4cc17f446 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 12:34:20 +0100 Subject: new flow logic: abm_register.lua: add register_abm_output routine --- new_flow_logic/abm_register.lua | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index 793ea83..c1b2d7d 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -6,7 +6,11 @@ local register = {} pipeworks.flowlogic.abmregister = register +local flowlogic = pipeworks.flowlogic +-- A possible DRY violation here... +-- DISCUSS: should it be possible later on to raise the the rate of ABMs, or lower the chance? +-- Currently all the intervals and chances are hardcoded below. -- register a node name for the pressure balancing ABM. -- currently this only exists as a per-node function to allow nodes to be registered outside pipeworks. @@ -16,7 +20,7 @@ local register_abm_balance = function(nodename) interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - pipeworks.flowlogic.balance_pressure(pos, node) + flowlogic.balance_pressure(pos, node) end }) end @@ -31,12 +35,28 @@ local register_abm_input = function(nodename, maxpressure, intakefn) interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - pipeworks.flowlogic.run_input(pos, node, maxpressure, intakefn) + flowlogic.run_input(pos, node, maxpressure, intakefn) end }) end register.input = register_abm_input +-- register a node for the output ABM. +-- threshold determines the minimum pressure, over which outputfn is called. +-- outputfn is then given the current pressure, and returns the pressure relieved by the output process. +-- outputfn is expected to update environment, nearby world etc. as appropriate for the node. +local register_abm_output = function(nodename, threshold, outputfn) + minetest.register_abm({ + nodenames = { nodename }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + flowlogic.run_output(pos, node, threshold, outputfn) + end + }) +end +register.output = register_abm_output + -- old spigot ABM code, not yet migrated --[[ minetest.register_abm({ -- cgit v1.2.3 From e615a1013b621daff64500fb74a6202fdca0093f Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 12:45:12 +0100 Subject: new flow logic: flowable_node_registry.lua: add output node registration --- new_flow_logic/flowable_node_registry.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index 1465561..f3548a4 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -18,6 +18,11 @@ pipeworks.flowables.inputs = {} pipeworks.flowables.inputs.list = {} pipeworks.flowables.inputs.nodenames = {} +-- outputs - takes pressure from pipes and update world to do something with it +pipeworks.flowables.outputs = {} +pipeworks.flowables.outputs.list = {} +-- not currently any nodenames arraylist for this one as it's not currently needed. + -- registration functions pipeworks.flowables.register = {} local register = pipeworks.flowables.register @@ -63,3 +68,20 @@ register.intake_simple = function(nodename, maxpressure) abmregister.input(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) end end + +-- Register a node as an output. +-- Expects node to already be a flowable. +-- threshold and outputfn are currently as documented for register_abm_output() in abm_register.lua. +register.output = function(nodename, threshold, outputfn) + checkbase(nodename) + pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } + if pipeworks.enable_new_flow_logic then + abmregister.output(nodename, maxpressure, outputfn) + end +end + +-- TODOs here: +-- The spigot's output behaviour (and possibly the fountain) could be abstracted out into a "simple output" of sorts, +-- which tries to place water nodes around it. +-- possibly this could be given a helper function to determine which faces a node should try, +-- to allow things like rotation or other param values determining "direction" to be respected. -- cgit v1.2.3 From 3a1edac06ce193179b58ffcd055b492839d30018 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 13:00:41 +0100 Subject: new flow logic: register_local_pipes.lua: make spigots work again --- new_flow_logic/flowable_node_registry.lua | 2 +- new_flow_logic/register_local_pipes.lua | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index f3548a4..f2ebdcb 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -76,7 +76,7 @@ register.output = function(nodename, threshold, outputfn) checkbase(nodename) pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } if pipeworks.enable_new_flow_logic then - abmregister.output(nodename, maxpressure, outputfn) + abmregister.output(nodename, threshold, outputfn) end end diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua index ca12244..b8cb7f0 100644 --- a/new_flow_logic/register_local_pipes.lua +++ b/new_flow_logic/register_local_pipes.lua @@ -8,6 +8,9 @@ local thresholds = {} -- limit on pump pressure - will not absorb more than can be taken thresholds.pump_pressure = 2 +-- activation threshold for spigot +-- should not be below 1, as spigot helper code indiscriminately places a water source node if run. +thresholds.spigot_min = 1 @@ -15,6 +18,7 @@ local pipes_full_nodenames = pipeworks.pipes_full_nodenames local pipes_empty_nodenames = pipeworks.pipes_empty_nodenames local register = pipeworks.flowables.register +local flowlogic = pipeworks.flowlogic @@ -40,5 +44,9 @@ if pipeworks.enable_pipes then register.simple(spigot_off) register.intake_simple(pump_on, thresholds.pump_pressure) + -- TODO: the code doesn't currently care if the spigot is the visually flowing node or not. + -- So some mechanism to register on/off states would be nice + register.output(spigot_off, thresholds.spigot_min, flowlogic.helpers.output_spigot) + register.output(spigot_on, thresholds.spigot_min, flowlogic.helpers.output_spigot) end end -- cgit v1.2.3 From f7b17197677ea3675eee6bc667370fe3e23ac099 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 15:18:00 +0100 Subject: new flow logic: node registry: split registration functions into seperate file to allow ABM code to inspect tables --- new_flow_logic/flowable_node_registry.lua | 73 +++-------------------- new_flow_logic/flowable_node_registry_install.lua | 70 ++++++++++++++++++++++ 2 files changed, 77 insertions(+), 66 deletions(-) create mode 100644 new_flow_logic/flowable_node_registry_install.lua (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index f2ebdcb..8fb925c 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -1,8 +1,12 @@ --- registration code for nodes under new flow logic +-- registry of flowable node behaviours in new flow logic -- written 2017 by thetaepsilon --- use for hooking up ABMs as nodes are registered -local abmregister = pipeworks.flowlogic.abmregister +-- the actual registration functions which edit these tables can be found in flowable_node_registry_install.lua +-- this is because the ABM code needs to inspect these tables, +-- but the registration code needs to reference said ABM code. +-- so those functions were split out to resolve a circular dependency. + + pipeworks.flowables = {} pipeworks.flowables.list = {} @@ -22,66 +26,3 @@ pipeworks.flowables.inputs.nodenames = {} pipeworks.flowables.outputs = {} pipeworks.flowables.outputs.list = {} -- not currently any nodenames arraylist for this one as it's not currently needed. - --- registration functions -pipeworks.flowables.register = {} -local register = pipeworks.flowables.register - --- some sanity checking for passed args, as this could potentially be made an external API eventually -local checkexists = function(nodename) - if type(nodename) ~= "string" then error("pipeworks.flowables nodename must be a string!") end - return pipeworks.flowables.list.all[nodename] -end - -local insertbase = function(nodename) - if checkexists(nodename) then error("pipeworks.flowables duplicate registration!") end - pipeworks.flowables.list.all[nodename] = true - -- table.insert(pipeworks.flowables.list.nodenames, nodename) -end - --- Register a node as a simple flowable. --- Simple flowable nodes have no considerations for direction of flow; --- A cluster of adjacent simple flowables will happily average out in any direction. -register.simple = function(nodename) - insertbase(nodename) - pipeworks.flowables.list.simple[nodename] = true - table.insert(pipeworks.flowables.list.simple_nodenames, nodename) - if pipeworks.enable_new_flow_logic then - abmregister.balance(nodename) - end -end - -local checkbase = function(nodename) - if not checkexists(nodename) then error("pipeworks.flowables node doesn't exist as a flowable!") end -end - --- Register a node as a simple intake. --- Expects node to be registered as a flowable (is present in flowables.list.all), --- so that water can move out of it. --- maxpressure is the maximum pipeline pressure that this node can drive. --- possible WISHME here: technic-driven high-pressure pumps -register.intake_simple = function(nodename, maxpressure) - checkbase(nodename) - pipeworks.flowables.inputs.list[nodename] = { maxpressure=maxpressure } - table.insert(pipeworks.flowables.inputs.nodenames, nodename) - if pipeworks.enable_new_flow_logic then - abmregister.input(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) - end -end - --- Register a node as an output. --- Expects node to already be a flowable. --- threshold and outputfn are currently as documented for register_abm_output() in abm_register.lua. -register.output = function(nodename, threshold, outputfn) - checkbase(nodename) - pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } - if pipeworks.enable_new_flow_logic then - abmregister.output(nodename, threshold, outputfn) - end -end - --- TODOs here: --- The spigot's output behaviour (and possibly the fountain) could be abstracted out into a "simple output" of sorts, --- which tries to place water nodes around it. --- possibly this could be given a helper function to determine which faces a node should try, --- to allow things like rotation or other param values determining "direction" to be respected. diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua new file mode 100644 index 0000000..06d69fd --- /dev/null +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -0,0 +1,70 @@ +-- flowable node registry: add entries and install ABMs if new flow logic is enabled +-- written 2017 by thetaepsilon + + + +-- use for hooking up ABMs as nodes are registered +local abmregister = pipeworks.flowlogic.abmregister + +-- registration functions +pipeworks.flowables.register = {} +local register = pipeworks.flowables.register + +-- some sanity checking for passed args, as this could potentially be made an external API eventually +local checkexists = function(nodename) + if type(nodename) ~= "string" then error("pipeworks.flowables nodename must be a string!") end + return pipeworks.flowables.list.all[nodename] +end + +local insertbase = function(nodename) + if checkexists(nodename) then error("pipeworks.flowables duplicate registration!") end + pipeworks.flowables.list.all[nodename] = true + -- table.insert(pipeworks.flowables.list.nodenames, nodename) +end + +-- Register a node as a simple flowable. +-- Simple flowable nodes have no considerations for direction of flow; +-- A cluster of adjacent simple flowables will happily average out in any direction. +register.simple = function(nodename) + insertbase(nodename) + pipeworks.flowables.list.simple[nodename] = true + table.insert(pipeworks.flowables.list.simple_nodenames, nodename) + if pipeworks.enable_new_flow_logic then + abmregister.balance(nodename) + end +end + +local checkbase = function(nodename) + if not checkexists(nodename) then error("pipeworks.flowables node doesn't exist as a flowable!") end +end + +-- Register a node as a simple intake. +-- Expects node to be registered as a flowable (is present in flowables.list.all), +-- so that water can move out of it. +-- maxpressure is the maximum pipeline pressure that this node can drive. +-- possible WISHME here: technic-driven high-pressure pumps +register.intake_simple = function(nodename, maxpressure) + checkbase(nodename) + pipeworks.flowables.inputs.list[nodename] = { maxpressure=maxpressure } + table.insert(pipeworks.flowables.inputs.nodenames, nodename) + if pipeworks.enable_new_flow_logic then + abmregister.input(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) + end +end + +-- Register a node as an output. +-- Expects node to already be a flowable. +-- threshold and outputfn are currently as documented for register_abm_output() in abm_register.lua. +register.output = function(nodename, threshold, outputfn) + checkbase(nodename) + pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } + if pipeworks.enable_new_flow_logic then + abmregister.output(nodename, threshold, outputfn) + end +end + +-- TODOs here: +-- The spigot's output behaviour (and possibly the fountain) could be abstracted out into a "simple output" of sorts, +-- which tries to place water nodes around it. +-- possibly this could be given a helper function to determine which faces a node should try, +-- to allow things like rotation or other param values determining "direction" to be respected. -- cgit v1.2.3 From d9b616c5f05b1c512988fd5eef5f91aba5bf12cf Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 15:47:21 +0100 Subject: new flow logic: node registry: add initial stub for flow directionality check --- new_flow_logic/flowable_node_registry.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index 8fb925c..b0634d0 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -26,3 +26,16 @@ pipeworks.flowables.inputs.nodenames = {} pipeworks.flowables.outputs = {} pipeworks.flowables.outputs.list = {} -- not currently any nodenames arraylist for this one as it's not currently needed. + + + +-- checks if a given node can flow in a given direction. +-- used to implement directional devices such as pumps, +-- which only visually connect in a certain direction. +-- node is the usual name + param structure. +-- direction is an x/y/z vector of the flow direction; +-- this function answers the question "can this node flow in this direction?" +pipeworks.flowables.flow_check = function(node, direction) + minetest.log("warning", "pipeworks.flowables.flow_check() stub!") + return true +end -- cgit v1.2.3 From f3cd1b61d771824ed9f42b32caa95ae08538bb64 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 16:17:35 +0100 Subject: new flow logic: flowable_node_registry_install.lua: add registration tracing --- new_flow_logic/flowable_node_registry_install.lua | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 06d69fd..f83f8ad 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -22,6 +22,12 @@ local insertbase = function(nodename) -- table.insert(pipeworks.flowables.list.nodenames, nodename) end +local regwarning = function(kind, nodename) + local tail = "" + if pipeworks.enable_new_flow_logic then tail = " but new_flow_logic not enabled" end + pipeworks.logger("[pipeworks] "..kind.." flow logic registry requested for "..nodename..tail) +end + -- Register a node as a simple flowable. -- Simple flowable nodes have no considerations for direction of flow; -- A cluster of adjacent simple flowables will happily average out in any direction. @@ -32,6 +38,7 @@ register.simple = function(nodename) if pipeworks.enable_new_flow_logic then abmregister.balance(nodename) end + regwarning("simple", nodename) end local checkbase = function(nodename) @@ -50,6 +57,7 @@ register.intake_simple = function(nodename, maxpressure) if pipeworks.enable_new_flow_logic then abmregister.input(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) end + regwarning("simple intake", nodename) end -- Register a node as an output. @@ -61,6 +69,7 @@ register.output = function(nodename, threshold, outputfn) if pipeworks.enable_new_flow_logic then abmregister.output(nodename, threshold, outputfn) end + regwarning("output node", nodename) end -- TODOs here: -- cgit v1.2.3 From 0fb0eab7235db267aece1cecee7c1d6a1a5b42a1 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 16:54:24 +0100 Subject: move pipe node registration for new flow logic closer to their definition in pipes.lua --- new_flow_logic/flowable_node_registry_install.lua | 4 ++-- new_flow_logic/register_local_pipes.lua | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index f83f8ad..ac305dc 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -24,8 +24,8 @@ end local regwarning = function(kind, nodename) local tail = "" - if pipeworks.enable_new_flow_logic then tail = " but new_flow_logic not enabled" end - pipeworks.logger("[pipeworks] "..kind.." flow logic registry requested for "..nodename..tail) + if not pipeworks.enable_new_flow_logic then tail = " but new_flow_logic not enabled" end + pipeworks.logger(kind.." flow logic registry requested for "..nodename..tail) end -- Register a node as a simple flowable. diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua index b8cb7f0..5128d47 100644 --- a/new_flow_logic/register_local_pipes.lua +++ b/new_flow_logic/register_local_pipes.lua @@ -30,12 +30,14 @@ local spigot_off = "pipeworks:spigot" local spigot_on = "pipeworks:spigot_pouring" if pipeworks.enable_pipes then + --[[ for _, pipe in ipairs(pipes_full_nodenames) do register.simple(pipe) end for _, pipe in ipairs(pipes_empty_nodenames) do register.simple(pipe) end + ]] if pipeworks.enable_pipe_devices then register.simple(pump_off) -- cgit v1.2.3 From e6b55028fc9b6a50ecd6c28c2af1ee94e041edcd Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 17:36:03 +0100 Subject: move pump flow logic registration to devices.lua --- new_flow_logic/register_local_pipes.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua index 5128d47..005a812 100644 --- a/new_flow_logic/register_local_pipes.lua +++ b/new_flow_logic/register_local_pipes.lua @@ -40,12 +40,12 @@ if pipeworks.enable_pipes then ]] if pipeworks.enable_pipe_devices then - register.simple(pump_off) - register.simple(pump_on) + --register.simple(pump_off) + --register.simple(pump_on) register.simple(spigot_on) register.simple(spigot_off) - register.intake_simple(pump_on, thresholds.pump_pressure) + --register.intake_simple(pump_on, thresholds.pump_pressure) -- TODO: the code doesn't currently care if the spigot is the visually flowing node or not. -- So some mechanism to register on/off states would be nice register.output(spigot_off, thresholds.spigot_min, flowlogic.helpers.output_spigot) -- cgit v1.2.3 From 13383770ef61d93899ad272586daeb0d8d3b4072 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 18:18:47 +0100 Subject: move spigot behaviour registration to devices.lua --- new_flow_logic/register_local_pipes.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua index 005a812..0de0056 100644 --- a/new_flow_logic/register_local_pipes.lua +++ b/new_flow_logic/register_local_pipes.lua @@ -42,13 +42,13 @@ if pipeworks.enable_pipes then if pipeworks.enable_pipe_devices then --register.simple(pump_off) --register.simple(pump_on) - register.simple(spigot_on) - register.simple(spigot_off) + --register.simple(spigot_on) + --register.simple(spigot_off) --register.intake_simple(pump_on, thresholds.pump_pressure) -- TODO: the code doesn't currently care if the spigot is the visually flowing node or not. -- So some mechanism to register on/off states would be nice - register.output(spigot_off, thresholds.spigot_min, flowlogic.helpers.output_spigot) - register.output(spigot_on, thresholds.spigot_min, flowlogic.helpers.output_spigot) + --register.output(spigot_off, thresholds.spigot_min, flowlogic.helpers.output_spigot) + --register.output(spigot_on, thresholds.spigot_min, flowlogic.helpers.output_spigot) end end -- cgit v1.2.3 From 396a4fdacdd6f80e3bba55cd6c26a2ae321179d1 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 18:23:58 +0100 Subject: remove register_local_pipes.lua as node registration has been moved to more appropriate files --- new_flow_logic/register_local_pipes.lua | 54 --------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 new_flow_logic/register_local_pipes.lua (limited to 'new_flow_logic') diff --git a/new_flow_logic/register_local_pipes.lua b/new_flow_logic/register_local_pipes.lua deleted file mode 100644 index 0de0056..0000000 --- a/new_flow_logic/register_local_pipes.lua +++ /dev/null @@ -1,54 +0,0 @@ --- registration of pipework's own pipes. --- 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 --- activation threshold for spigot --- should not be below 1, as spigot helper code indiscriminately places a water source node if run. -thresholds.spigot_min = 1 - - - -local pipes_full_nodenames = pipeworks.pipes_full_nodenames -local pipes_empty_nodenames = pipeworks.pipes_empty_nodenames - -local register = pipeworks.flowables.register -local flowlogic = pipeworks.flowlogic - - - --- FIXME: DRY principle for names, move this to devices.lua? --- FIXME: all devices still considered simple -local pump_on = "pipeworks:pump_on" -local pump_off = "pipeworks:pump_off" -local spigot_off = "pipeworks:spigot" -local spigot_on = "pipeworks:spigot_pouring" - -if pipeworks.enable_pipes then - --[[ - for _, pipe in ipairs(pipes_full_nodenames) do - register.simple(pipe) - end - for _, pipe in ipairs(pipes_empty_nodenames) do - register.simple(pipe) - end - ]] - - if pipeworks.enable_pipe_devices then - --register.simple(pump_off) - --register.simple(pump_on) - --register.simple(spigot_on) - --register.simple(spigot_off) - - --register.intake_simple(pump_on, thresholds.pump_pressure) - -- TODO: the code doesn't currently care if the spigot is the visually flowing node or not. - -- So some mechanism to register on/off states would be nice - --register.output(spigot_off, thresholds.spigot_min, flowlogic.helpers.output_spigot) - --register.output(spigot_on, thresholds.spigot_min, flowlogic.helpers.output_spigot) - end -end -- cgit v1.2.3 From 9abdeb3d626c702c044d6d621bdea6c43dbd6647 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 20:12:19 +0100 Subject: new flow logic: abms.lua: use flowable nodes registry to determine viable neighbours --- new_flow_logic/abms.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 640493a..66349e9 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -49,8 +49,9 @@ flowlogic.check_for_liquids_v2 = check_for_liquids_v2 +--local formatvec = function(vec) local sep="," return "("..tostring(vec.x)..sep..tostring(vec.y)..sep..tostring(vec.z)..")" end + local label_pressure = "pipeworks.water_pressure" -local label_haspressure = "pipeworks.is_pressure_node" flowlogic.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. @@ -60,16 +61,19 @@ flowlogic.balance_pressure = function(pos, node) -- 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 nodename = minetest.get_node(npos).name local neighbour = minetest.get_meta(npos) - local haspressure = (neighbour:get_int(label_haspressure) ~= 0) + -- for now, just check if it's in the simple table. + -- TODO: the "can flow from" logic in flowable_node_registry.lua + local haspressure = (pipeworks.flowables.list.simple[nodename]) if haspressure then + --pipeworks.logger("balance_pressure @ "..formatvec(pos).." "..nodename.." "..formatvec(npos).." added to neighbour set") local n = neighbour:get_float(label_pressure) table.insert(connections, neighbour) totalv = totalv + n -- cgit v1.2.3 From dc13ec619f7e49b0e75f845f8baa0559a8b11936 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 20:27:30 +0100 Subject: new flow logic: abms.lua: remove intake limit coercion causing water to be vanished --- new_flow_logic/abms.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 66349e9..afeb3b3 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -29,6 +29,8 @@ end +--local formatvec = function(vec) local sep="," return "("..tostring(vec.x)..sep..tostring(vec.y)..sep..tostring(vec.z)..")" 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. @@ -43,14 +45,13 @@ local check_for_liquids_v2 = function(pos, limit) total = total + 1 end end + --pipeworks.logger("check_for_liquids_v2@"..formatvec(pos).." total "..total) return total end flowlogic.check_for_liquids_v2 = check_for_liquids_v2 ---local formatvec = function(vec) local sep="," return "("..tostring(vec.x)..sep..tostring(vec.y)..sep..tostring(vec.z)..")" end - local label_pressure = "pipeworks.water_pressure" flowlogic.balance_pressure = function(pos, node) -- debuglog("balance_pressure() "..node.name.." at "..pos.x.." "..pos.y.." "..pos.z) @@ -100,8 +101,8 @@ flowlogic.run_input = function(pos, node, maxpressure, intakefn) if intake_limit <= 0 then return end local actual_intake = intakefn(pos, intake_limit) + --pipeworks.logger("run_input@"..formatvec(pos).." oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake) if actual_intake <= 0 then return end - if actual_intake >= intake_limit then actual_intake = intake_limit end local newpressure = actual_intake + currentpressure -- debuglog("oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake.." newpressure "..newpressure) -- cgit v1.2.3 From 667eeb7d095f12d5c7e560d161697878ea485433 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 21:04:07 +0100 Subject: new flow logic: abms.lua: generalise spigot output code to support arbitary neighbour lists --- new_flow_logic/abms.lua | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index afeb3b3..a07c390 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -111,19 +111,23 @@ end --- flowlogic output helper for spigots --- tries to place a water block in the world beneath the spigot. --- threshold checking is assumed to be handled by the node registration; --- see register_local_pipes.lua for the pipeworks default spigot. -flowlogic.helpers.output_spigot = function(pos, node, currentpressure) - local taken = 0 - 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"}) - taken = taken + 1 +-- flowlogic output helper implementation: +-- outputs water by trying to place water nodes nearby in the world. +-- neighbours is a list of node offsets to try placing water in. +-- this is a constructor function, returning another function which satisfies the output helper requirements. +flowlogic.helpers.make_neighbour_output = function(neighbours) + return function(pos, node, currentpressure) + local taken = 0 + for _, offset in pairs(neighbours) do + local npos = vector.add(pos, offset) + local name = minetest.get_node(npos).name + if (name == "air") or (name == "default:water_flowing") then + minetest.swap_node(npos, {name="default:water_source"}) + taken = taken + 1 + end + end + return taken end - return taken end @@ -145,19 +149,3 @@ flowlogic.run_output = function(pos, node, threshold, outputfn) meta:set_float(label_pressure, newpressure) end end - - - -flowlogic.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 -- cgit v1.2.3 From 8e53526b545e2dc0a05066fb18f064a394e20740 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 1 Oct 2017 21:20:30 +0100 Subject: new flow logic: abms.lua: rename neighbour output helper to better indicate lack of rotation support --- new_flow_logic/abms.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index a07c390..15adcef 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -115,7 +115,8 @@ end -- outputs water by trying to place water nodes nearby in the world. -- neighbours is a list of node offsets to try placing water in. -- this is a constructor function, returning another function which satisfies the output helper requirements. -flowlogic.helpers.make_neighbour_output = function(neighbours) +-- note that this does *not* take rotation into account. +flowlogic.helpers.make_neighbour_output_fixed = function(neighbours) return function(pos, node, currentpressure) local taken = 0 for _, offset in pairs(neighbours) do -- cgit v1.2.3 From 894ea5174fb8c3be9038698cb119b24acbec8cea Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Tue, 3 Oct 2017 20:38:56 +0100 Subject: move new flow logic flag to dedicated toggles table --- new_flow_logic/flowable_node_registry_install.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index ac305dc..defe877 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -24,7 +24,7 @@ end local regwarning = function(kind, nodename) local tail = "" - if not pipeworks.enable_new_flow_logic then tail = " but new_flow_logic not enabled" end + if not pipeworks.toggles.pressure_logic then tail = " but pressure logic not enabled" end pipeworks.logger(kind.." flow logic registry requested for "..nodename..tail) end @@ -35,7 +35,7 @@ register.simple = function(nodename) insertbase(nodename) pipeworks.flowables.list.simple[nodename] = true table.insert(pipeworks.flowables.list.simple_nodenames, nodename) - if pipeworks.enable_new_flow_logic then + if pipeworks.toggles.pressure_logic then abmregister.balance(nodename) end regwarning("simple", nodename) @@ -54,7 +54,7 @@ register.intake_simple = function(nodename, maxpressure) checkbase(nodename) pipeworks.flowables.inputs.list[nodename] = { maxpressure=maxpressure } table.insert(pipeworks.flowables.inputs.nodenames, nodename) - if pipeworks.enable_new_flow_logic then + if pipeworks.toggles.pressure_logic then abmregister.input(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) end regwarning("simple intake", nodename) @@ -66,7 +66,7 @@ end register.output = function(nodename, threshold, outputfn) checkbase(nodename) pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } - if pipeworks.enable_new_flow_logic then + if pipeworks.toggles.pressure_logic then abmregister.output(nodename, threshold, outputfn) end regwarning("output node", nodename) -- cgit v1.2.3 From 7eb5dc6aca664bbca5c81203f5d72d9abc39578c Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Wed, 4 Oct 2017 18:54:51 +0100 Subject: flowable_node_registry_install.lua: silence registration debugging by default --- new_flow_logic/flowable_node_registry_install.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index defe877..79f5997 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -25,7 +25,7 @@ end local regwarning = function(kind, nodename) local tail = "" if not pipeworks.toggles.pressure_logic then tail = " but pressure logic not enabled" end - pipeworks.logger(kind.." flow logic registry requested for "..nodename..tail) + --pipeworks.logger(kind.." flow logic registry requested for "..nodename..tail) end -- Register a node as a simple flowable. -- cgit v1.2.3 From 465e28cbd3e2d176a4ca0429711bc459fe37cf0d Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 12:16:36 +0100 Subject: devices.lua: factor out usage of flowlogic helper into dedicated registry function --- new_flow_logic/flowable_node_registry_install.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 79f5997..3d9ce0a 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -77,3 +77,7 @@ end -- which tries to place water nodes around it. -- possibly this could be given a helper function to determine which faces a node should try, -- to allow things like rotation or other param values determining "direction" to be respected. +register.output_simple = function(nodename, threshold, neighbours) + local outputfn = pipeworks.flowlogic.helpers.make_neighbour_output_fixed(neighbours) + register.output(nodename, threshold, outputfn) +end -- cgit v1.2.3 From 4f58a3039c55783978d5f85fbf59f06025884384 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 13:05:52 +0100 Subject: new flow logic: flowable_node_registry_install.lua: separate pressure threshold into upper and lower hysteresis values --- new_flow_logic/flowable_node_registry_install.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 3d9ce0a..7f414c4 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -62,12 +62,19 @@ end -- Register a node as an output. -- Expects node to already be a flowable. --- threshold and outputfn are currently as documented for register_abm_output() in abm_register.lua. -register.output = function(nodename, threshold, outputfn) +-- upper and lower thresholds have different meanings depending on whether finite liquid mode is in effect. +-- if not (the default unless auto-detected), +-- nodes above their upper threshold have their outputfn invoked (and pressure deducted), +-- nodes between upper and lower are left idle, +-- and nodes below lower have their cleanup fn invoked (to say remove water sources). +-- the upper and lower difference acts as a hysteresis to try and avoid "gaps" in the flow. +-- if finite mode is on, upper is ignored and lower is used to determine whether to run outputfn; +-- cleanupfn is ignored in this mode as finite mode assumes something causes water to move itself. +register.output = function(nodename, upper, lower, outputfn) checkbase(nodename) pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } if pipeworks.toggles.pressure_logic then - abmregister.output(nodename, threshold, outputfn) + abmregister.output(nodename, lower, outputfn) end regwarning("output node", nodename) end @@ -77,7 +84,8 @@ end -- which tries to place water nodes around it. -- possibly this could be given a helper function to determine which faces a node should try, -- to allow things like rotation or other param values determining "direction" to be respected. -register.output_simple = function(nodename, threshold, neighbours) +-- for meanings of upper and lower, see register.output() above. +register.output_simple = function(nodename, upper, lower, neighbours) local outputfn = pipeworks.flowlogic.helpers.make_neighbour_output_fixed(neighbours) - register.output(nodename, threshold, outputfn) + register.output(nodename, upper, lower, outputfn) end -- cgit v1.2.3 From 31a67cf4f98f0c9850998799956063401efceef5 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 13:15:42 +0100 Subject: new flow logic: flowable_node_registry_install.lua: add proper documentation for register.output_simple() --- new_flow_logic/flowable_node_registry_install.lua | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 7f414c4..650d1da 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -79,12 +79,17 @@ register.output = function(nodename, upper, lower, outputfn) regwarning("output node", nodename) end --- TODOs here: --- The spigot's output behaviour (and possibly the fountain) could be abstracted out into a "simple output" of sorts, --- which tries to place water nodes around it. --- possibly this could be given a helper function to determine which faces a node should try, --- to allow things like rotation or other param values determining "direction" to be respected. +-- register a simple output: +-- drains pressure by attempting to place water in nearby nodes, +-- which can be set by passing a list of offset vectors. +-- will attempt to drain as many whole nodes as there are positions in the offset list. -- for meanings of upper and lower, see register.output() above. +-- non-finite mode: +-- above upper pressure: places water sources as appropriate, keeps draining pressure. +-- below lower presssure: removes it's neighbour water sources. +-- finite mode: +-- same as for above pressure in non-finite mode, +-- but only drains pressure when water source nodes are actually placed. register.output_simple = function(nodename, upper, lower, neighbours) local outputfn = pipeworks.flowlogic.helpers.make_neighbour_output_fixed(neighbours) register.output(nodename, upper, lower, outputfn) -- cgit v1.2.3 From 6f90ee0875dd0f89f460b6ae75acac708a63cb4c Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 13:24:46 +0100 Subject: new flow logic: abms.lua: add companion cleaner helper for neighbour output --- new_flow_logic/abms.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 15adcef..7a720be 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -131,6 +131,21 @@ flowlogic.helpers.make_neighbour_output_fixed = function(neighbours) end end +-- complementary function to the above when using non-finite mode: +-- removes water sources from neighbor positions when the output is "off" due to lack of pressure. +flowlogic.helpers.make_neighbour_cleanup_fixed = function(neighbours) + return function(pos, node, currentpressure) + -- FIXME - this would indiscriminately take blocks while under-pressure, not just one time? + for _, offset in pairs(neighbours) do + local npos = vector.add(pos, offset) + local name = minetest.get_node(npos).name + if (name == "default:water_source") then + minetest.remove_node(pos) + end + end + end +end + flowlogic.run_output = function(pos, node, threshold, outputfn) -- cgit v1.2.3 From 1669cfd4510a2dbb2ca3c754b414ae8c976ceca1 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 15:42:00 +0100 Subject: new flow logic: flowable_node_registry_install.lua: add duplicate registration guard for register.output() --- new_flow_logic/flowable_node_registry_install.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 650d1da..07001ef 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -71,6 +71,9 @@ end -- if finite mode is on, upper is ignored and lower is used to determine whether to run outputfn; -- cleanupfn is ignored in this mode as finite mode assumes something causes water to move itself. register.output = function(nodename, upper, lower, outputfn) + if pipeworks.flowables.outputs.list[nodename] then + error("pipeworks.flowables.outputs duplicate registration!") + end checkbase(nodename) pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } if pipeworks.toggles.pressure_logic then -- cgit v1.2.3 From 34cfee8a2faaa9366b1a9ae5035eedee3620aa56 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 16:12:36 +0100 Subject: new flow logic: start adding replacement ABM logic --- new_flow_logic/abm_register.lua | 19 +++++++++++++++++++ new_flow_logic/flowable_node_registry_install.lua | 4 ++++ 2 files changed, 23 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index c1b2d7d..d8bb6cc 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -12,6 +12,25 @@ local flowlogic = pipeworks.flowlogic -- DISCUSS: should it be possible later on to raise the the rate of ABMs, or lower the chance? -- Currently all the intervals and chances are hardcoded below. + + +-- register node list for the main logic function. +-- see flowlogic.run() in abms.lua. +--[[ +local register_flowlogic_abm = function(nodename) + minetest.register_abm({ + nodenames = { nodename }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + flowlogic.run(pos, node) + end + }) +end +]] + + + -- register a node name for the pressure balancing ABM. -- currently this only exists as a per-node function to allow nodes to be registered outside pipeworks. local register_abm_balance = function(nodename) diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 07001ef..5ebae61 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -79,6 +79,10 @@ register.output = function(nodename, upper, lower, outputfn) if pipeworks.toggles.pressure_logic then abmregister.output(nodename, lower, outputfn) end + -- output ABM now part of main flow logic ABM to preserve ordering. + -- note that because outputs have to be a flowable first + -- (and the installation of the flow logic ABM is conditional), + -- registered output nodes for new_flow_logic is also still conditional on the enable flag. regwarning("output node", nodename) end -- cgit v1.2.3 From 608a9a69808ee58d05dc115b37af1d53b00f0241 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 17:14:50 +0100 Subject: new flow logic: abms.lua: wrap up pressure value accesses behind accessor object --- new_flow_logic/abms.lua | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 7a720be..9e5eb2d 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -53,6 +53,18 @@ flowlogic.check_for_liquids_v2 = check_for_liquids_v2 local label_pressure = "pipeworks.water_pressure" +local get_pressure_access = function(pos) + local metaref = minetest.get_meta(pos) + return { + get = function() + return metaref:get_float(label_pressure) + end, + set = function(v) + metaref:set_float(label_pressure, v) + end + } +end + flowlogic.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. @@ -60,22 +72,23 @@ flowlogic.balance_pressure = function(pos, node) -- 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) - local connections = { meta } + local pressure = get_pressure_access(pos) + local currentpressure = pressure.get() + -- pressure handles to average over + local connections = { pressure } 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 nodename = minetest.get_node(npos).name - local neighbour = minetest.get_meta(npos) -- for now, just check if it's in the simple table. -- TODO: the "can flow from" logic in flowable_node_registry.lua local haspressure = (pipeworks.flowables.list.simple[nodename]) if haspressure then + local neighbour = get_pressure_access(npos) --pipeworks.logger("balance_pressure @ "..formatvec(pos).." "..nodename.." "..formatvec(npos).." added to neighbour set") - local n = neighbour:get_float(label_pressure) + local n = neighbour.get() table.insert(connections, neighbour) totalv = totalv + n totalc = totalc + 1 @@ -83,8 +96,8 @@ flowlogic.balance_pressure = function(pos, node) end local average = totalv / totalc - for _, targetmeta in ipairs(connections) do - targetmeta:set_float(label_pressure, average) + for _, target in ipairs(connections) do + target.set(average) end end -- cgit v1.2.3 From 016f9de82f91b61a14ad1bc477ee18b501f77e39 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 17:33:42 +0100 Subject: new flow logic: abms.lua: refactor ABM logic into new master ABM, make balance_pressure() take current pressure and return new pressure --- new_flow_logic/abm_register.lua | 6 +++-- new_flow_logic/abms.lua | 31 +++++++++++++++++------ new_flow_logic/flowable_node_registry_install.lua | 2 +- 3 files changed, 28 insertions(+), 11 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index d8bb6cc..db6233f 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -16,7 +16,7 @@ local flowlogic = pipeworks.flowlogic -- register node list for the main logic function. -- see flowlogic.run() in abms.lua. ---[[ + local register_flowlogic_abm = function(nodename) minetest.register_abm({ nodenames = { nodename }, @@ -27,12 +27,13 @@ local register_flowlogic_abm = function(nodename) end }) end -]] +register.flowlogic = register_flowlogic_abm -- register a node name for the pressure balancing ABM. -- currently this only exists as a per-node function to allow nodes to be registered outside pipeworks. +--[[ local register_abm_balance = function(nodename) minetest.register_abm({ nodenames = { nodename }, @@ -44,6 +45,7 @@ local register_abm_balance = function(nodename) }) end register.balance = register_abm_balance +]] -- register a node for the input ABM. -- intakefn is run on the node to determine how much water can be taken (and update it's environment accordingly). diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 9e5eb2d..37b10bc 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -65,17 +65,30 @@ local get_pressure_access = function(pos) } end -flowlogic.balance_pressure = function(pos, node) + + +flowlogic.run = function(pos, node) + -- get the current pressure value. + local nodepressure = get_pressure_access(pos) + local currentpressure = nodepressure.get() + + -- balance pressure with neighbours + currentpressure = flowlogic.balance_pressure(pos, node, currentpressure) + + -- set the new pressure + nodepressure.set(currentpressure) +end + + + +flowlogic.balance_pressure = function(pos, node, currentpressure) -- 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? + -- check the pressure of all nearby flowable nodes, and average it out. - -- unconditionally include self in nodes to average over - local pressure = get_pressure_access(pos) - local currentpressure = pressure.get() -- pressure handles to average over - local connections = { pressure } + local connections = {} + -- unconditionally include self in nodes to average over. + -- result of averaging will be returned as new pressure for main flow logic callback local totalv = currentpressure local totalc = 1 @@ -99,6 +112,8 @@ flowlogic.balance_pressure = function(pos, node) for _, target in ipairs(connections) do target.set(average) end + + return average end diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 5ebae61..d195c63 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -36,7 +36,7 @@ register.simple = function(nodename) pipeworks.flowables.list.simple[nodename] = true table.insert(pipeworks.flowables.list.simple_nodenames, nodename) if pipeworks.toggles.pressure_logic then - abmregister.balance(nodename) + abmregister.flowlogic(nodename) end regwarning("simple", nodename) end -- cgit v1.2.3 From 65b3448796815718275ed3c16af4865e5e005454 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 17:55:14 +0100 Subject: new flow logic: abms.lua: refactor flowlogic.run_output() into a processing stage of flowlogic.run() --- new_flow_logic/abm_register.lua | 2 ++ new_flow_logic/abms.lua | 31 +++++++++++++++-------- new_flow_logic/flowable_node_registry_install.lua | 5 +--- 3 files changed, 24 insertions(+), 14 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index db6233f..1c7eede 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -66,6 +66,7 @@ register.input = register_abm_input -- threshold determines the minimum pressure, over which outputfn is called. -- outputfn is then given the current pressure, and returns the pressure relieved by the output process. -- outputfn is expected to update environment, nearby world etc. as appropriate for the node. +--[[ local register_abm_output = function(nodename, threshold, outputfn) minetest.register_abm({ nodenames = { nodename }, @@ -77,6 +78,7 @@ local register_abm_output = function(nodename, threshold, outputfn) }) end register.output = register_abm_output +]] -- old spigot ABM code, not yet migrated --[[ diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 37b10bc..671a69d 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -68,6 +68,7 @@ end flowlogic.run = function(pos, node) + local nodename = node.name -- get the current pressure value. local nodepressure = get_pressure_access(pos) local currentpressure = nodepressure.get() @@ -75,6 +76,18 @@ flowlogic.run = function(pos, node) -- balance pressure with neighbours currentpressure = flowlogic.balance_pressure(pos, node, currentpressure) + -- if node is an output: run output phase + local output = pipeworks.flowables.outputs.list[nodename] + if output then + currentpressure = flowlogic.run_output( + pos, + node, + currentpressure, + output.upper, + output.lower, + output.outputfn) + end + -- set the new pressure nodepressure.set(currentpressure) end @@ -176,20 +189,18 @@ end -flowlogic.run_output = function(pos, node, threshold, outputfn) - -- callback for output devices. - -- takes care of checking a minimum pressure value and updating the node metadata. +flowlogic.run_output = function(pos, node, currentpressure, upper, lower, outputfn) + -- processing step for water output devices. + -- takes care of checking a minimum pressure value and updating the resulting pressure level -- the outputfn is provided the current pressure and returns the pressure "taken". -- as an example, using this with the above spigot function, -- the spigot function tries to output a water source if it will fit in the world. - local meta = minetest.get_meta(pos) - -- sometimes I wonder if meta:get_* returning default values would ever be problematic. - -- though here it doesn't matter, an uninit'd node returns 0, which is fine for a new, empty node. - local currentpressure = meta:get_float(label_pressure) - if currentpressure > threshold then + local result = currentpressure + if currentpressure > lower then local takenpressure = outputfn(pos, node, currentpressure) local newpressure = currentpressure - takenpressure - if newpressure < 0 then currentpressure = 0 end - meta:set_float(label_pressure, newpressure) + if newpressure < 0 then newpressure = 0 end + result = newpressure end + return result end diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index d195c63..aed6fbd 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -75,10 +75,7 @@ register.output = function(nodename, upper, lower, outputfn) error("pipeworks.flowables.outputs duplicate registration!") end checkbase(nodename) - pipeworks.flowables.outputs.list[nodename] = { threshold=threshold, outputfn=outputfn } - if pipeworks.toggles.pressure_logic then - abmregister.output(nodename, lower, outputfn) - end + pipeworks.flowables.outputs.list[nodename] = { upper=upper, lower=lower, outputfn=outputfn } -- output ABM now part of main flow logic ABM to preserve ordering. -- note that because outputs have to be a flowable first -- (and the installation of the flow logic ABM is conditional), -- cgit v1.2.3 From be1a6d53aa94f812dc661b4b08c5d0e2ebf97623 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 18:07:55 +0100 Subject: new flow logic: flowable_node_registry_install.lua: factor out register.intake_simple into generic registration and helper wrapper --- new_flow_logic/flowable_node_registry_install.lua | 32 ++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index aed6fbd..35dbe97 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -45,21 +45,41 @@ local checkbase = function(nodename) if not checkexists(nodename) then error("pipeworks.flowables node doesn't exist as a flowable!") end end --- Register a node as a simple intake. +local duplicateerr = function(kind, nodename) error(kind.." duplicate registration for "..nodename) end + + + +-- Registers a node as a fluid intake. +-- intakefn is used to determine the water that can be taken in a node-specific way. -- Expects node to be registered as a flowable (is present in flowables.list.all), -- so that water can move out of it. --- maxpressure is the maximum pipeline pressure that this node can drive. +-- maxpressure is the maximum pipeline pressure that this node can drive; +-- if the input's node exceeds this the callback is not run. -- possible WISHME here: technic-driven high-pressure pumps -register.intake_simple = function(nodename, maxpressure) +register.intake = function(nodename, maxpressure, intakefn) + -- check for duplicate registration of this node + local list = pipeworks.flowables.inputs.list checkbase(nodename) - pipeworks.flowables.inputs.list[nodename] = { maxpressure=maxpressure } + if list[nodename] then duplicateerr("pipeworks.flowables.inputs", nodename) end + list[nodename] = { maxpressure=maxpressure, intakefn=intakefn } table.insert(pipeworks.flowables.inputs.nodenames, nodename) if pipeworks.toggles.pressure_logic then - abmregister.input(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) + abmregister.input(nodename, maxpressure, intakefn) end - regwarning("simple intake", nodename) + regwarning("intake", nodename) end + + +-- Register a node as a simple intake: +-- tries to absorb water source nodes from it's surroundings. +-- may exceed limit slightly due to needing to absorb whole nodes. +register.intake_simple = function(nodename, maxpressure) + register.intake(nodename, maxpressure, pipeworks.flowlogic.check_for_liquids_v2) +end + + + -- Register a node as an output. -- Expects node to already be a flowable. -- upper and lower thresholds have different meanings depending on whether finite liquid mode is in effect. -- cgit v1.2.3 From 9c770532e6e3cb1157e467015a97aef97a8a8893 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 19:19:09 +0100 Subject: new flow logic: abms.lua: refactor run_input to run as part of master run() ABM --- new_flow_logic/abm_register.lua | 2 ++ new_flow_logic/abms.lua | 31 +++++++++++++++++------ new_flow_logic/flowable_node_registry_install.lua | 4 --- 3 files changed, 25 insertions(+), 12 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index 1c7eede..dbd37e6 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -50,6 +50,7 @@ register.balance = register_abm_balance -- register a node for the input ABM. -- intakefn is run on the node to determine how much water can be taken (and update it's environment accordingly). -- maxpressure is the maximum pressure that this input can drive, beyond which pressure will not be raised. +--[[ local register_abm_input = function(nodename, maxpressure, intakefn) minetest.register_abm({ nodenames = { nodename }, @@ -61,6 +62,7 @@ local register_abm_input = function(nodename, maxpressure, intakefn) }) end register.input = register_abm_input +]] -- register a node for the output ABM. -- threshold determines the minimum pressure, over which outputfn is called. diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 671a69d..eb551d8 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -66,6 +66,14 @@ local get_pressure_access = function(pos) end +-- logging is unreliable when something is crashing... +local nilexplode = function(caller, label, value) + if value == nil then + error(caller..": "..label.." was nil") + end +end + + flowlogic.run = function(pos, node) local nodename = node.name @@ -73,6 +81,14 @@ flowlogic.run = function(pos, node) local nodepressure = get_pressure_access(pos) local currentpressure = nodepressure.get() + -- if node is an input: run intake phase + local inputdef = pipeworks.flowables.inputs.list[nodename] + if inputdef then + currentpressure = flowlogic.run_input(pos, node, currentpressure, inputdef) + --debuglog("post-intake currentpressure is "..currentpressure) + --nilexplode("run()", "currentpressure", currentpressure) + end + -- balance pressure with neighbours currentpressure = flowlogic.balance_pressure(pos, node, currentpressure) @@ -131,23 +147,22 @@ end -flowlogic.run_input = function(pos, node, maxpressure, intakefn) +flowlogic.run_input = function(pos, node, currentpressure, inputdef) -- intakefn allows a given input node to define it's own intake logic. -- this function will calculate the maximum amount of water that can be taken in; -- the intakefn will be given this and is expected to return the actual absorption amount. - local meta = minetest.get_meta(pos) - local currentpressure = meta:get_float(label_pressure) + local maxpressure = inputdef.maxpressure local intake_limit = maxpressure - currentpressure - if intake_limit <= 0 then return end + if intake_limit <= 0 then return currentpressure end - local actual_intake = intakefn(pos, intake_limit) + local actual_intake = inputdef.intakefn(pos, intake_limit) --pipeworks.logger("run_input@"..formatvec(pos).." oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake) - if actual_intake <= 0 then return end + if actual_intake <= 0 then return currentpressure end local newpressure = actual_intake + currentpressure - -- debuglog("oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake.." newpressure "..newpressure) - meta:set_float(label_pressure, newpressure) + --debuglog("run_input() end, oldpressure "..currentpressure.." intake_limit "..intake_limit.." actual_intake "..actual_intake.." newpressure "..newpressure) + return newpressure end diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 35dbe97..6da87dc 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -62,10 +62,6 @@ register.intake = function(nodename, maxpressure, intakefn) checkbase(nodename) if list[nodename] then duplicateerr("pipeworks.flowables.inputs", nodename) end list[nodename] = { maxpressure=maxpressure, intakefn=intakefn } - table.insert(pipeworks.flowables.inputs.nodenames, nodename) - if pipeworks.toggles.pressure_logic then - abmregister.input(nodename, maxpressure, intakefn) - end regwarning("intake", nodename) end -- cgit v1.2.3 From 91d057fcab8bf2caad295148201f1414e935def7 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 19:42:49 +0100 Subject: new flow logic: tear out old abm registration code --- new_flow_logic/abm_register.lua | 65 ----------------------------------------- 1 file changed, 65 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index dbd37e6..ac7b2e3 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -28,68 +28,3 @@ local register_flowlogic_abm = function(nodename) }) end register.flowlogic = register_flowlogic_abm - - - --- register a node name for the pressure balancing ABM. --- currently this only exists as a per-node function to allow nodes to be registered outside pipeworks. ---[[ -local register_abm_balance = function(nodename) - minetest.register_abm({ - nodenames = { nodename }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - flowlogic.balance_pressure(pos, node) - end - }) -end -register.balance = register_abm_balance -]] - --- register a node for the input ABM. --- intakefn is run on the node to determine how much water can be taken (and update it's environment accordingly). --- maxpressure is the maximum pressure that this input can drive, beyond which pressure will not be raised. ---[[ -local register_abm_input = function(nodename, maxpressure, intakefn) - minetest.register_abm({ - nodenames = { nodename }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - flowlogic.run_input(pos, node, maxpressure, intakefn) - end - }) -end -register.input = register_abm_input -]] - --- register a node for the output ABM. --- threshold determines the minimum pressure, over which outputfn is called. --- outputfn is then given the current pressure, and returns the pressure relieved by the output process. --- outputfn is expected to update environment, nearby world etc. as appropriate for the node. ---[[ -local register_abm_output = function(nodename, threshold, outputfn) - minetest.register_abm({ - nodenames = { nodename }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - flowlogic.run_output(pos, node, threshold, outputfn) - end - }) -end -register.output = register_abm_output -]] - --- old spigot ABM code, not yet migrated ---[[ - minetest.register_abm({ - nodenames = { spigot_on, spigot_off }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - pipeworks.run_spigot_output(pos, node) - end - }) -]] -- cgit v1.2.3 From 187e755aa5d7f4ddbc68cc2c4d8494051321a3cd Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 21:44:33 +0100 Subject: new flow logic: abms.lua: don't unpack outputdef variables in flowlogic.run(), leave to flowlogic.run_output() --- new_flow_logic/abms.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index eb551d8..6fee744 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -93,15 +93,13 @@ flowlogic.run = function(pos, node) currentpressure = flowlogic.balance_pressure(pos, node, currentpressure) -- if node is an output: run output phase - local output = pipeworks.flowables.outputs.list[nodename] - if output then + local outputdef = pipeworks.flowables.outputs.list[nodename] + if outputdef then currentpressure = flowlogic.run_output( pos, node, currentpressure, - output.upper, - output.lower, - output.outputfn) + outputdef) end -- set the new pressure @@ -204,15 +202,17 @@ end -flowlogic.run_output = function(pos, node, currentpressure, upper, lower, outputfn) +flowlogic.run_output = function(pos, node, currentpressure, outputdef) -- processing step for water output devices. -- takes care of checking a minimum pressure value and updating the resulting pressure level -- the outputfn is provided the current pressure and returns the pressure "taken". -- as an example, using this with the above spigot function, -- the spigot function tries to output a water source if it will fit in the world. + local upper = outputdef.upper + local lower = outputdef.lower local result = currentpressure if currentpressure > lower then - local takenpressure = outputfn(pos, node, currentpressure) + local takenpressure = outputdef.outputfn(pos, node, currentpressure) local newpressure = currentpressure - takenpressure if newpressure < 0 then newpressure = 0 end result = newpressure -- cgit v1.2.3 From 453a114cd022a4d7b0a028f9e4a9785e20e6e368 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 21:55:49 +0100 Subject: new flow logic: flowable_node_registry_install.lua: add cleanupfn argument to register.output() --- new_flow_logic/flowable_node_registry_install.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 6da87dc..0be9fc0 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -86,12 +86,17 @@ end -- the upper and lower difference acts as a hysteresis to try and avoid "gaps" in the flow. -- if finite mode is on, upper is ignored and lower is used to determine whether to run outputfn; -- cleanupfn is ignored in this mode as finite mode assumes something causes water to move itself. -register.output = function(nodename, upper, lower, outputfn) +register.output = function(nodename, upper, lower, outputfn, cleanupfn) if pipeworks.flowables.outputs.list[nodename] then error("pipeworks.flowables.outputs duplicate registration!") end checkbase(nodename) - pipeworks.flowables.outputs.list[nodename] = { upper=upper, lower=lower, outputfn=outputfn } + pipeworks.flowables.outputs.list[nodename] = { + upper=upper, + lower=lower, + outputfn=outputfn, + cleanupfn=cleanupfn, + } -- output ABM now part of main flow logic ABM to preserve ordering. -- note that because outputs have to be a flowable first -- (and the installation of the flow logic ABM is conditional), @@ -112,5 +117,6 @@ end -- but only drains pressure when water source nodes are actually placed. register.output_simple = function(nodename, upper, lower, neighbours) local outputfn = pipeworks.flowlogic.helpers.make_neighbour_output_fixed(neighbours) - register.output(nodename, upper, lower, outputfn) + local cleanupfn = pipeworks.flowlogic.helpers.make_neighbour_cleanup_fixed(neighbours) + register.output(nodename, upper, lower, outputfn, cleanupfn) end -- cgit v1.2.3 From bd32b4fca2ee77da1b4b017d3e90a4013d4393a8 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 22:03:53 +0100 Subject: new flow logic: abms.lua: pass finite mode flag to run_output() --- new_flow_logic/abms.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 6fee744..1605ea3 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -75,6 +75,7 @@ end +local finitemode = pipeworks.toggles.finite_water flowlogic.run = function(pos, node) local nodename = node.name -- get the current pressure value. @@ -99,7 +100,8 @@ flowlogic.run = function(pos, node) pos, node, currentpressure, - outputdef) + outputdef, + finitemode) end -- set the new pressure @@ -202,7 +204,7 @@ end -flowlogic.run_output = function(pos, node, currentpressure, outputdef) +flowlogic.run_output = function(pos, node, currentpressure, outputdef, finitemode) -- processing step for water output devices. -- takes care of checking a minimum pressure value and updating the resulting pressure level -- the outputfn is provided the current pressure and returns the pressure "taken". -- cgit v1.2.3 From 07e769d1b92661dc21bf85dee2f788f929fc444e Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 22:07:30 +0100 Subject: new flow logic: abms.lua: pass finite mod flag to output handler callbacks in flowlogic.run_output() --- new_flow_logic/abms.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 1605ea3..a4d5fc3 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -173,7 +173,7 @@ end -- this is a constructor function, returning another function which satisfies the output helper requirements. -- note that this does *not* take rotation into account. flowlogic.helpers.make_neighbour_output_fixed = function(neighbours) - return function(pos, node, currentpressure) + return function(pos, node, currentpressure, finitemode) local taken = 0 for _, offset in pairs(neighbours) do local npos = vector.add(pos, offset) @@ -214,7 +214,7 @@ flowlogic.run_output = function(pos, node, currentpressure, outputdef, finitemod local lower = outputdef.lower local result = currentpressure if currentpressure > lower then - local takenpressure = outputdef.outputfn(pos, node, currentpressure) + local takenpressure = outputdef.outputfn(pos, node, currentpressure, finitemode) local newpressure = currentpressure - takenpressure if newpressure < 0 then newpressure = 0 end result = newpressure -- cgit v1.2.3 From 9ab197af2f6e524be920857c0f152aef84546e37 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 22:21:54 +0100 Subject: new flow logic: abms.lua: implement non-finite mode behaviour for neighbour output helper --- new_flow_logic/abms.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index a4d5fc3..99ccbc6 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -178,9 +178,18 @@ flowlogic.helpers.make_neighbour_output_fixed = function(neighbours) for _, offset in pairs(neighbours) do local npos = vector.add(pos, offset) local name = minetest.get_node(npos).name - if (name == "air") or (name == "default:water_flowing") then + if currentpressure < 1 then break end + -- take pressure anyway in non-finite mode, even if node is water source already. + -- in non-finite mode, pressure has to be sustained to keep the sources there. + -- so in non-finite mode, placing water is dependent on the target node; + -- draining pressure is not. + local canplace = (name == "air") or (name == "default:water_flowing") + if canplace then minetest.swap_node(npos, {name="default:water_source"}) + end + if (not finitemode) or canplace then taken = taken + 1 + currentpressure = currentpressure - 1 end end return taken -- cgit v1.2.3 From d4346919bcb4d2e0c692448bc0a652d55c0fa2a9 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 22:29:17 +0100 Subject: new flow logic: abms.lua: pass initial pressure to run_output() to allow falling-level event detection --- new_flow_logic/abms.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 99ccbc6..babd14e 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -81,6 +81,7 @@ flowlogic.run = function(pos, node) -- get the current pressure value. local nodepressure = get_pressure_access(pos) local currentpressure = nodepressure.get() + local oldpressure = currentpressure -- if node is an input: run intake phase local inputdef = pipeworks.flowables.inputs.list[nodename] @@ -100,6 +101,7 @@ flowlogic.run = function(pos, node) pos, node, currentpressure, + oldpressure, outputdef, finitemode) end @@ -213,7 +215,7 @@ end -flowlogic.run_output = function(pos, node, currentpressure, outputdef, finitemode) +flowlogic.run_output = function(pos, node, currentpressure, oldpressure, outputdef, finitemode) -- processing step for water output devices. -- takes care of checking a minimum pressure value and updating the resulting pressure level -- the outputfn is provided the current pressure and returns the pressure "taken". -- cgit v1.2.3 From f94c93bb59fa151ee90932f53afb82ac6f3aae15 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sat, 7 Oct 2017 22:35:08 +0100 Subject: new flow logic: abms.lua: implement non-finite mode cleanupfn invocation in run_output() --- new_flow_logic/abms.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index babd14e..9197d17 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -224,11 +224,16 @@ flowlogic.run_output = function(pos, node, currentpressure, oldpressure, outputd local upper = outputdef.upper local lower = outputdef.lower local result = currentpressure - if currentpressure > lower then + local threshold = nil + if finitemode then threshold = lower else threshold = upper end + if currentpressure > threshold then local takenpressure = outputdef.outputfn(pos, node, currentpressure, finitemode) local newpressure = currentpressure - takenpressure if newpressure < 0 then newpressure = 0 end result = newpressure end + if (not finitemode) and (currentpressure < lower) and (oldpressure > lower) then + outputdef.cleanupfn(pos, node, currentpressure) + end return result end -- cgit v1.2.3 From 6a25e56336f98be7f91d328d6a75674450aa46a4 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 8 Oct 2017 11:32:08 +0100 Subject: new flow logic: algorithmic and value tuning for non-finite mode --- new_flow_logic/abms.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 9197d17..e83d50e 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -202,12 +202,13 @@ end -- removes water sources from neighbor positions when the output is "off" due to lack of pressure. flowlogic.helpers.make_neighbour_cleanup_fixed = function(neighbours) return function(pos, node, currentpressure) - -- FIXME - this would indiscriminately take blocks while under-pressure, not just one time? + --pipeworks.logger("neighbour_cleanup_fixed@"..formatvec(pos)) for _, offset in pairs(neighbours) do local npos = vector.add(pos, offset) local name = minetest.get_node(npos).name if (name == "default:water_source") then - minetest.remove_node(pos) + --pipeworks.logger("neighbour_cleanup_fixed removing "..formatvec(npos)) + minetest.remove_node(npos) end end end @@ -221,6 +222,7 @@ flowlogic.run_output = function(pos, node, currentpressure, oldpressure, outputd -- the outputfn is provided the current pressure and returns the pressure "taken". -- as an example, using this with the above spigot function, -- the spigot function tries to output a water source if it will fit in the world. + --pipeworks.logger("flowlogic.run_output() pos "..formatvec(pos).." old -> currentpressure "..tostring(oldpressure).." "..tostring(currentpressure).." finitemode "..tostring(finitemode)) local upper = outputdef.upper local lower = outputdef.lower local result = currentpressure @@ -232,7 +234,8 @@ flowlogic.run_output = function(pos, node, currentpressure, oldpressure, outputd if newpressure < 0 then newpressure = 0 end result = newpressure end - if (not finitemode) and (currentpressure < lower) and (oldpressure > lower) then + if (not finitemode) and (currentpressure < lower) and (oldpressure < lower) then + --pipeworks.logger("flowlogic.run_output() invoking cleanup currentpressure="..tostring(currentpressure)) outputdef.cleanupfn(pos, node, currentpressure) end return result -- cgit v1.2.3 From e98e4e268b5faf898a0b8f580d7da2b46ead05c4 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 8 Oct 2017 14:27:40 +0100 Subject: new flow logic: flowable node registry: add initial support for transition triggers --- new_flow_logic/flowable_node_registry.lua | 6 +++ new_flow_logic/flowable_node_registry_install.lua | 50 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index b0634d0..7651928 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -27,6 +27,12 @@ pipeworks.flowables.outputs = {} pipeworks.flowables.outputs.list = {} -- not currently any nodenames arraylist for this one as it's not currently needed. +-- nodes with registered node transitions +-- nodes will be switched depending on pressure level +pipeworks.flowables.transitions = {} +pipeworks.flowables.transitions.list = {} -- master list +pipeworks.flowables.transitions.simple = {} -- nodes that change based purely on pressure + -- checks if a given node can flow in a given direction. diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 0be9fc0..63151f0 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -120,3 +120,53 @@ register.output_simple = function(nodename, upper, lower, neighbours) local cleanupfn = pipeworks.flowlogic.helpers.make_neighbour_cleanup_fixed(neighbours) register.output(nodename, upper, lower, outputfn, cleanupfn) end + + + +-- common base checking for transition nodes +-- ensures the node has only been registered once as a transition. +local transition_list = pipeworks.flowables.transitions.list +local insert_transition_base = function(nodename) + checkbase(nodename) + if transition_list[nodename] then duplicateerr("base transition", nodename) end + transition_list[nodename] = true +end + + + +-- register a simple transition set. +-- expects a table with nodenames as keys and threshold pressures as values. +-- internally, the table is sorted by value, and when one of these nodes needs to transition, +-- the table is searched starting from the lowest (even if it's value is non-zero), +-- until a value is found which is higher than or equal to the current node pressure. +-- ex. nodeset = { ["mod:level_0"] = 0, ["mod:level_1"] = 1, --[[ ... ]] } +local simpleseterror = function(msg) + error("register.transition_simple_set(): "..msg) +end +local simple_transitions = pipeworks.flowables.transitions.simple + +register.transition_simple_set = function(nodeset) + local set = {} + for nodename, value in pairs(nodeset) do + if type(nodename) ~= "string" then simpleseterror("nodename key "..tostring(nodename).."was not a string!") end + if type(value) ~= "number" then simpleseterror("pressure value "..tostring(value).."was not a number!") end + insert_transition_base(nodename) + if simple_transitions[nodename] then duplicateerr("simple transition set", nodename) end + -- assigning set to table is done separately below + + table.insert(set, { nodename=nodename, threshold=value }) + end + + -- sort pressure values, smallest first + local smallest_first = function(a, b) + return a.value < b.value + end + table.sort(set, smallest_first) + + -- individual registration of each node, all sharing this set, + -- so each node in the set will transition to the correct target node. + for _, element in ipairs(set) do + --pipeworks.logger("register.transition_simple_set() after sort: nodename "..element.nodename.." value "..tostring(element.threshold)) + simple_transitions[element.nodename] = set + end +end -- cgit v1.2.3 From 32a24730f1ab8cd596ed2f4cf6eda1a58c877ecb Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 8 Oct 2017 15:07:12 +0100 Subject: new flow logic: change simple transition set logic to take list of key-value pairs, add set registration for flow sensor pipe --- new_flow_logic/flowable_node_registry_install.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index 63151f0..f019dc3 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -147,8 +147,11 @@ local simple_transitions = pipeworks.flowables.transitions.simple register.transition_simple_set = function(nodeset) local set = {} - for nodename, value in pairs(nodeset) do - if type(nodename) ~= "string" then simpleseterror("nodename key "..tostring(nodename).."was not a string!") end + for index, element in ipairs(nodeset) do + if type(element) ~= "table" then simpleseterror("element "..tostring(index).." in nodeset was not table!") end + local nodename = element[1] + local value = element[2] + if type(nodename) ~= "string" then simpleseterror("nodename "..tostring(nodename).."was not a string!") end if type(value) ~= "number" then simpleseterror("pressure value "..tostring(value).."was not a number!") end insert_transition_base(nodename) if simple_transitions[nodename] then duplicateerr("simple transition set", nodename) end @@ -159,7 +162,7 @@ register.transition_simple_set = function(nodeset) -- sort pressure values, smallest first local smallest_first = function(a, b) - return a.value < b.value + return a.threshold < b.threshold end table.sort(set, smallest_first) -- cgit v1.2.3 From eaf6c33bae0912e15ac190df203b9b250545052b Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 8 Oct 2017 16:19:51 +0100 Subject: new flow logic: abms.lua: implement node transitions --- new_flow_logic/abms.lua | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index e83d50e..6abdd42 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -29,7 +29,7 @@ end ---local formatvec = function(vec) local sep="," return "("..tostring(vec.x)..sep..tostring(vec.y)..sep..tostring(vec.z)..")" end +local formatvec = function(vec) local sep="," return "("..tostring(vec.x)..sep..tostring(vec.y)..sep..tostring(vec.z)..")" end -- new version of liquid check -- accepts a limit parameter to only delete water blocks that the receptacle can accept, @@ -106,6 +106,13 @@ flowlogic.run = function(pos, node) finitemode) end + -- if node has pressure transitions: determine new node + if pipeworks.flowables.transitions.list[nodename] then + local newnode = flowlogic.run_transition(node, currentpressure) + --pipeworks.logger("flowlogic.run()@"..formatvec(pos).." transition, new node name = "..dump(newnode).." pressure "..tostring(currentpressure)) + minetest.swap_node(pos, newnode) + end + -- set the new pressure nodepressure.set(currentpressure) end @@ -240,3 +247,45 @@ flowlogic.run_output = function(pos, node, currentpressure, oldpressure, outputd end return result end + + + +-- determine which node to switch to based on current pressure +flowlogic.run_transition = function(node, currentpressure) + local simplesetdef = pipeworks.flowables.transitions.simple[node.name] + local result = node + local found = false + + -- simple transition sets: assumes all nodes in the set share param values. + if simplesetdef then + -- assumes that the set has been checked to contain at least one element... + local nodename_prev = simplesetdef[1].nodename + local result_nodename = node.name + + for index, element in ipairs(simplesetdef) do + -- find the highest element that is below the current pressure. + local threshold = element.threshold + if threshold > currentpressure then + result_nodename = nodename_prev + found = true + break + end + nodename_prev = element.nodename + end + + -- use last element if no threshold is greater than current pressure + if not found then + result_nodename = nodename_prev + found = true + end + + -- preserve param1/param2 values + result = { name=result_nodename, param1=node.param1, param2=node.param2 } + end + + if not found then + pipeworks.logger("flowlogic.run_transition() BUG no transition definitions found! nodename="..nodename.." currentpressure="..tostring(currentpressure)) + end + + return result +end -- cgit v1.2.3 From c2553928f2e1063ca8011b0f9b024b819995cab5 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 8 Oct 2017 16:20:30 +0100 Subject: new flow logic: flowable_node_registry_install.lua: add set size checking guard --- new_flow_logic/flowable_node_registry_install.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'new_flow_logic') diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index f019dc3..e4a5744 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -147,6 +147,9 @@ local simple_transitions = pipeworks.flowables.transitions.simple register.transition_simple_set = function(nodeset) local set = {} + + local length = #nodeset + if length < 2 then simpleseterror("nodeset needs at least two elements!") end for index, element in ipairs(nodeset) do if type(element) ~= "table" then simpleseterror("element "..tostring(index).." in nodeset was not table!") end local nodename = element[1] -- cgit v1.2.3 From d5e3f1cf68a15d7e14cc44eb8e58e49dbb6aa087 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 8 Oct 2017 17:38:28 +0100 Subject: new flow logic: implement post-transition hook with mesecons support, add mesecons transition rules for flow sensor --- new_flow_logic/abms.lua | 24 +++++++++++++++++++++++ new_flow_logic/flowable_node_registry.lua | 1 + new_flow_logic/flowable_node_registry_install.lua | 12 +++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abms.lua b/new_flow_logic/abms.lua index 6abdd42..38ae4b6 100644 --- a/new_flow_logic/abms.lua +++ b/new_flow_logic/abms.lua @@ -111,6 +111,7 @@ flowlogic.run = function(pos, node) local newnode = flowlogic.run_transition(node, currentpressure) --pipeworks.logger("flowlogic.run()@"..formatvec(pos).." transition, new node name = "..dump(newnode).." pressure "..tostring(currentpressure)) minetest.swap_node(pos, newnode) + flowlogic.run_transition_post(pos, newnode) end -- set the new pressure @@ -289,3 +290,26 @@ flowlogic.run_transition = function(node, currentpressure) return result end + +-- post-update hook for run_transition +-- among other things, updates mesecons if present. +-- node here means the new node, returned from run_transition() above +flowlogic.run_transition_post = function(pos, node) + local mesecons_def = minetest.registered_nodes[node.name].mesecons + local mesecons_rules = pipeworks.flowables.transitions.mesecons[node.name] + if minetest.global_exists("mesecon") and (mesecons_def ~= nil) and mesecons_rules then + if type(mesecons_def) ~= "table" then + pipeworks.logger("flowlogic.run_transition_post() BUG mesecons def for "..node.name.."not a table: got "..tostring(mesecons_def)) + else + local receptor = mesecons_def.receptor + if receptor then + local state = receptor.state + if state == mesecon.state.on then + mesecon.receptor_on(pos, mesecons_rules) + elseif state == mesecon.state.off then + mesecon.receptor_off(pos, mesecons_rules) + end + end + end + end +end diff --git a/new_flow_logic/flowable_node_registry.lua b/new_flow_logic/flowable_node_registry.lua index 7651928..2523803 100644 --- a/new_flow_logic/flowable_node_registry.lua +++ b/new_flow_logic/flowable_node_registry.lua @@ -32,6 +32,7 @@ pipeworks.flowables.outputs.list = {} pipeworks.flowables.transitions = {} pipeworks.flowables.transitions.list = {} -- master list pipeworks.flowables.transitions.simple = {} -- nodes that change based purely on pressure +pipeworks.flowables.transitions.mesecons = {} -- table of mesecons rules to apply on transition diff --git a/new_flow_logic/flowable_node_registry_install.lua b/new_flow_logic/flowable_node_registry_install.lua index e4a5744..c8f6889 100644 --- a/new_flow_logic/flowable_node_registry_install.lua +++ b/new_flow_logic/flowable_node_registry_install.lua @@ -145,8 +145,9 @@ local simpleseterror = function(msg) end local simple_transitions = pipeworks.flowables.transitions.simple -register.transition_simple_set = function(nodeset) +register.transition_simple_set = function(nodeset, extras) local set = {} + if extras == nil then extras = {} end local length = #nodeset if length < 2 then simpleseterror("nodeset needs at least two elements!") end @@ -175,4 +176,13 @@ register.transition_simple_set = function(nodeset) --pipeworks.logger("register.transition_simple_set() after sort: nodename "..element.nodename.." value "..tostring(element.threshold)) simple_transitions[element.nodename] = set end + + -- handle extra options + -- if mesecons rules table was passed, set for each node + if extras.mesecons then + local mesecons_rules = pipeworks.flowables.transitions.mesecons + for _, element in ipairs(set) do + mesecons_rules[element.nodename] = extras.mesecons + end + end end -- cgit v1.2.3 From 72f793e2b3a7de1ed2946424eedc3fb2b0d3a1b4 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Sun, 8 Oct 2017 19:11:58 +0100 Subject: new flow logic: abm_register.lua: add extra safeguarding for conditional activation of new flow logic --- new_flow_logic/abm_register.lua | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'new_flow_logic') diff --git a/new_flow_logic/abm_register.lua b/new_flow_logic/abm_register.lua index ac7b2e3..1d038d6 100644 --- a/new_flow_logic/abm_register.lua +++ b/new_flow_logic/abm_register.lua @@ -1,30 +1,26 @@ -- register new flow logic ABMs -- written 2017 by thetaepsilon - - local register = {} pipeworks.flowlogic.abmregister = register local flowlogic = pipeworks.flowlogic --- A possible DRY violation here... --- DISCUSS: should it be possible later on to raise the the rate of ABMs, or lower the chance? --- Currently all the intervals and chances are hardcoded below. - - - -- register node list for the main logic function. -- see flowlogic.run() in abms.lua. local register_flowlogic_abm = function(nodename) - minetest.register_abm({ - nodenames = { nodename }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - flowlogic.run(pos, node) - end - }) + if pipeworks.toggles.pressure_logic then + minetest.register_abm({ + nodenames = { nodename }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + flowlogic.run(pos, node) + end + }) + else + minetest.log("warning", "pipeworks pressure_logic not enabled but register.flowlogic() requested") + end end register.flowlogic = register_flowlogic_abm -- cgit v1.2.3