From d659cb38b32640656071c4cd2eddcbd97af36bf3 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Mon, 18 Dec 2017 22:07:53 +0000 Subject: item_transport.lua: read extra multimode parameter from go_next callback --- item_transport.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'item_transport.lua') diff --git a/item_transport.lua b/item_transport.lua index 551db07..8a92bdb 100644 --- a/item_transport.lua +++ b/item_transport.lua @@ -277,7 +277,7 @@ luaentity.register_entity("pipeworks:tubed_item", { end if moved then - local found_next, new_velocity = go_next(self.start_pos, velocity, stack, self.owner) -- todo: color + local found_next, new_velocity, multimode = go_next(self.start_pos, velocity, stack, self.owner) -- todo: color local rev_vel = vector.multiply(velocity, -1) local rev_dir = vector.direction(self.start_pos,vector.add(self.start_pos,rev_vel)) local rev_node = minetest.get_node(vector.round(vector.add(self.start_pos,rev_dir))) -- cgit v1.2.3 From 28a3ba44d165cce068491b90233a58f3cea4d1c2 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Mon, 18 Dec 2017 22:38:24 +0000 Subject: item_transport.lua: initial support in item luaentity for multiple outputs and trajectories from go_next() --- item_transport.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'item_transport.lua') diff --git a/item_transport.lua b/item_transport.lua index 8a92bdb..64e4624 100644 --- a/item_transport.lua +++ b/item_transport.lua @@ -197,6 +197,12 @@ minetest.register_entity("pipeworks:color_entity", { on_activate = luaentity.on_activate, }) +-- see below for usage: +-- determine if go_next returned a multi-mode set. +local is_multimode = function(v) + return (type(v) == "table") and (v.__multimode) +end + luaentity.register_entity("pipeworks:tubed_item", { itemstring = '', item_entity = nil, @@ -297,6 +303,15 @@ luaentity.register_entity("pipeworks:tubed_item", { self:setpos(vector.subtract(self.start_pos, vector.multiply(vel, moved_by - 1))) self:setvelocity(velocity) end + elseif is_multimode(multimode) then + -- create new stacks according to returned data. + local s = self.start_pos + for _, split in ipairs(multimode) do + pipeworks.tube_inject_item(s, s, split.velocity, split.itemstack, self.owner) + end + -- remove ourself now the splits are sent + self:remove() + return end if new_velocity and not vector.equals(velocity, new_velocity) then -- cgit v1.2.3 From 56362cdd2acd8e855ceb79b46ce0b62f205776da Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Mon, 18 Dec 2017 23:07:40 +0000 Subject: item_transport.lua: factor out tube overload code into separate function --- item_transport.lua | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'item_transport.lua') diff --git a/item_transport.lua b/item_transport.lua index 64e4624..cf9e5c4 100644 --- a/item_transport.lua +++ b/item_transport.lua @@ -50,6 +50,26 @@ minetest.register_globalstep(function(dtime) end end) + + +-- tube overload mechanism: +-- when the tube's item count (tracked in the above tube_item_count table) +-- exceeds the limit configured per tube, replace it with a broken one. +local crunch_tube = function(pos, cnode, cmeta) + if enable_max_limit then + local h = minetest.hash_node_position(pos) + local itemcount = tube_item_count[h] or 0 + if itemcount > max_tube_limit then + cmeta:set_string("the_tube_was", minetest.serialize(cnode)) + print("[Pipeworks] Warning - a tube at "..minetest.pos_to_string(pos).." broke due to too many items ("..itemcount..")") + minetest.swap_node(pos, {name = "pipeworks:broken_tube_1"}) + pipeworks.scan_for_tube_objects(pos) + end + end +end + + + local function go_next(pos, velocity, stack, owner) local next_positions = {} local max_priority = 0 @@ -96,16 +116,7 @@ local function go_next(pos, velocity, stack, owner) end end - if enable_max_limit then - local h = minetest.hash_node_position(pos) - local itemcount = tube_item_count[h] or 0 - if itemcount > max_tube_limit then - cmeta:set_string("the_tube_was", minetest.serialize(cnode)) - print("[Pipeworks] Warning - a tube at "..minetest.pos_to_string(pos).." broke due to too many items ("..itemcount..")") - minetest.swap_node(pos, {name = "pipeworks:broken_tube_1"}) - pipeworks.scan_for_tube_objects(pos) - end - end + crunch_tube(pos, cnode, cmeta) if not next_positions[1] then return false, nil -- cgit v1.2.3 From 755dd262086da5469489d74c919e6870870eca57 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Tue, 19 Dec 2017 18:17:22 +0000 Subject: item_transport.lua: move tube limit checking before can_go() callback in go_next() --- item_transport.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'item_transport.lua') diff --git a/item_transport.lua b/item_transport.lua index cf9e5c4..154b6db 100644 --- a/item_transport.lua +++ b/item_transport.lua @@ -89,6 +89,9 @@ local function go_next(pos, velocity, stack, owner) speed = 1 end vel.speed = speed + + crunch_tube(pos, cnode, cmeta) + if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack) else @@ -116,8 +119,6 @@ local function go_next(pos, velocity, stack, owner) end end - crunch_tube(pos, cnode, cmeta) - if not next_positions[1] then return false, nil end -- cgit v1.2.3 From 97522b6a244a34be9e384c151618ab8db74aea46 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Tue, 19 Dec 2017 18:38:02 +0000 Subject: item_transport.lua: update return statements in go_next() to include multimode parameter --- item_transport.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'item_transport.lua') diff --git a/item_transport.lua b/item_transport.lua index 154b6db..d0b0e63 100644 --- a/item_transport.lua +++ b/item_transport.lua @@ -70,6 +70,15 @@ end +-- function called by the on_step callback of the pipeworks tube luaentity. +-- the routine is passed the current node position, velocity, itemstack, +-- and owner name. +-- returns three values: +-- * a boolean "found destination" status; +-- * a new velocity vector that the tubed item should use, or nil if not found; +-- * a "multi-mode" data table (or nil if N/A) where a stack was split apart. +-- if this is not nil, the luaentity spawns new tubed items for each new fragment stack, +-- then deletes itself (i.e. the original item stack). local function go_next(pos, velocity, stack, owner) local next_positions = {} local max_priority = 0 @@ -120,7 +129,7 @@ local function go_next(pos, velocity, stack, owner) end if not next_positions[1] then - return false, nil + return false, nil, nil end local n = (cmeta:get_int("tubedir") % (#next_positions)) + 1 @@ -128,9 +137,11 @@ local function go_next(pos, velocity, stack, owner) cmeta:set_int("tubedir", n) end local new_velocity = vector.multiply(next_positions[n].vect, vel.speed) - return true, new_velocity + return true, new_velocity, nil end + + minetest.register_entity("pipeworks:tubed_item", { initial_properties = { hp_max = 1, -- cgit v1.2.3 From fb91ba53f1af1d5d618f7610cdd04e3895ebd6c6 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Tue, 19 Dec 2017 22:53:18 +0000 Subject: item_transport.lua: read cycle direction at start of go_next() in preparation for refactoring --- item_transport.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'item_transport.lua') diff --git a/item_transport.lua b/item_transport.lua index d0b0e63..72f6d7d 100644 --- a/item_transport.lua +++ b/item_transport.lua @@ -100,6 +100,11 @@ local function go_next(pos, velocity, stack, owner) vel.speed = speed crunch_tube(pos, cnode, cmeta) + -- cycling of outputs: + -- an integer counter is kept in each pipe's metadata, + -- which allows tracking which output was previously chosen. + -- note reliance on get_int returning 0 for uninitialised. + local cycledir = cmeta:get_int("tubedir") if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack) @@ -132,7 +137,9 @@ local function go_next(pos, velocity, stack, owner) return false, nil, nil end - local n = (cmeta:get_int("tubedir") % (#next_positions)) + 1 + local n = (cycledir % (#next_positions)) + 1 + -- if not using output cycling, + -- don't update the field so it stays the same for the next item. if pipeworks.enable_cyclic_mode then cmeta:set_int("tubedir", n) end -- cgit v1.2.3 From a2e183c6f3d76e809bbc2d6b596e7e000f06ee66 Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Tue, 19 Dec 2017 23:15:44 +0000 Subject: item_transport.lua: split out determination of next position in go_next() into separate function --- item_transport.lua | 95 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 35 deletions(-) (limited to 'item_transport.lua') diff --git a/item_transport.lua b/item_transport.lua index 72f6d7d..7219f7e 100644 --- a/item_transport.lua +++ b/item_transport.lua @@ -70,47 +70,24 @@ end --- function called by the on_step callback of the pipeworks tube luaentity. --- the routine is passed the current node position, velocity, itemstack, --- and owner name. --- returns three values: --- * a boolean "found destination" status; --- * a new velocity vector that the tubed item should use, or nil if not found; --- * a "multi-mode" data table (or nil if N/A) where a stack was split apart. --- if this is not nil, the luaentity spawns new tubed items for each new fragment stack, --- then deletes itself (i.e. the original item stack). -local function go_next(pos, velocity, stack, owner) +-- compatibility behaviour for the existing can_go() callbacks, +-- which can only specify a list of possible positions. +local function go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner) local next_positions = {} local max_priority = 0 - local cnode = minetest.get_node(pos) - local cmeta = minetest.get_meta(pos) local can_go - local speed = math.abs(velocity.x + velocity.y + velocity.z) - if speed == 0 then - speed = 1 - end - local vel = {x = velocity.x/speed, y = velocity.y/speed, z = velocity.z/speed,speed=speed} - if speed >= 4.1 then - speed = 4 - elseif speed >= 1.1 then - speed = speed - 0.1 - else - speed = 1 - end - vel.speed = speed - - crunch_tube(pos, cnode, cmeta) - -- cycling of outputs: - -- an integer counter is kept in each pipe's metadata, - -- which allows tracking which output was previously chosen. - -- note reliance on get_int returning 0 for uninitialised. - local cycledir = cmeta:get_int("tubedir") if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack) else can_go = pipeworks.notvel(adjlist, vel) end + -- can_go() is expected to return an array-like table of candidate offsets. + -- for each one, look at the node at that offset and determine if it can accept the item. + -- also note the prioritisation: + -- if any tube is found with a greater priority than previously discovered, + -- then the valid positions are reset and and subsequent positions under this are skipped. + -- this has the effect of allowing only equal priorities to co-exist. for _, vect in ipairs(can_go) do local npos = vector.add(pos, vect) pipeworks.load_position(npos) @@ -133,18 +110,66 @@ local function go_next(pos, velocity, stack, owner) end end + -- indicate not found if no valid rules were picked up, + -- and don't change the counter. if not next_positions[1] then - return false, nil, nil + return cycledir, false, nil, nil end + -- otherwise rotate to the next output direction and return that local n = (cycledir % (#next_positions)) + 1 + local new_velocity = vector.multiply(next_positions[n].vect, vel.speed) + return n, true, new_velocity, nil +end + + + + +-- function called by the on_step callback of the pipeworks tube luaentity. +-- the routine is passed the current node position, velocity, itemstack, +-- and owner name. +-- returns three values: +-- * a boolean "found destination" status; +-- * a new velocity vector that the tubed item should use, or nil if not found; +-- * a "multi-mode" data table (or nil if N/A) where a stack was split apart. +-- if this is not nil, the luaentity spawns new tubed items for each new fragment stack, +-- then deletes itself (i.e. the original item stack). +local function go_next(pos, velocity, stack, owner) + local cnode = minetest.get_node(pos) + local cmeta = minetest.get_meta(pos) + local speed = math.abs(velocity.x + velocity.y + velocity.z) + if speed == 0 then + speed = 1 + end + local vel = {x = velocity.x/speed, y = velocity.y/speed, z = velocity.z/speed,speed=speed} + if speed >= 4.1 then + speed = 4 + elseif speed >= 1.1 then + speed = speed - 0.1 + else + speed = 1 + end + vel.speed = speed + + crunch_tube(pos, cnode, cmeta) + -- cycling of outputs: + -- an integer counter is kept in each pipe's metadata, + -- which allows tracking which output was previously chosen. + -- note reliance on get_int returning 0 for uninitialised. + local cycledir = cmeta:get_int("tubedir") + + -- pulled out and factored out into go_next_compat() above. + -- n is the new value of the cycle counter. + -- XXX: this probably needs cleaning up after being split out, + -- seven args is a bit too many + local n, found, new_velocity, multimode = go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner) + -- if not using output cycling, -- don't update the field so it stays the same for the next item. if pipeworks.enable_cyclic_mode then cmeta:set_int("tubedir", n) end - local new_velocity = vector.multiply(next_positions[n].vect, vel.speed) - return true, new_velocity, nil + return found, new_velocity, multimode end -- cgit v1.2.3