diff options
author | thetaepsilon-gamedev <thetaepsilon-gamedev@noreply.users.github.com> | 2017-09-30 23:42:26 +0100 |
---|---|---|
committer | thetaepsilon-gamedev <thetaepsilon-gamedev@noreply.users.github.com> | 2017-09-30 23:42:26 +0100 |
commit | c3627551b091d27819c242da204ed1e9dd8f15f0 (patch) | |
tree | fb51d5e91b5a6357327266b00f466881b9be1f60 /new_flow_logic | |
parent | d69941a0ae763d6681ede2185ad88e25b11fead5 (diff) | |
download | pipeworks-c3627551b091d27819c242da204ed1e9dd8f15f0.tar pipeworks-c3627551b091d27819c242da204ed1e9dd8f15f0.tar.gz pipeworks-c3627551b091d27819c242da204ed1e9dd8f15f0.tar.bz2 pipeworks-c3627551b091d27819c242da204ed1e9dd8f15f0.tar.xz pipeworks-c3627551b091d27819c242da204ed1e9dd8f15f0.zip |
move all current new_flow_logic code to dedicated sub-directory
Diffstat (limited to 'new_flow_logic')
-rw-r--r-- | new_flow_logic/abm_register.lua | 49 | ||||
-rw-r--r-- | new_flow_logic/abms.lua | 123 | ||||
-rw-r--r-- | new_flow_logic/flowable_node_registry.lua | 59 | ||||
-rw-r--r-- | new_flow_logic/register_local_pipes.lua | 53 |
4 files changed, 284 insertions, 0 deletions
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 |