added : an Read/Writable item.tag for tubed item stack

This commit is contained in:
Guill4um gamer 2021-04-18 14:13:13 +00:00 committed by CalebJ
parent c4994b62d4
commit fb8a1a5262
4 changed files with 73 additions and 13 deletions

View File

@ -20,6 +20,7 @@ local function set_filter_formspec(data, meta)
formspec = "size[8,2.7]"..
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
"label[1.4,0.444;]".. -- use to display error with tag using regex so dont modify coordinates without modifying the regex
"field[0.3,1.5;8.0,1;channel;Channel;${channel}]"..
fs_helpers.cycling_button(meta, "button[0,2;4,1", "slotseq_mode",
{"Sequence slots by Priority",
@ -55,7 +56,7 @@ local function set_filter_formspec(data, meta)
end
-- todo SOON: this function has *way too many* parameters
local function grabAndFire(data,slotseq_mode,exmatch_mode,filtmeta,frominv,frominvname,frompos,fromnode,filterfor,fromtube,fromdef,dir,fakePlayer,all,digiline)
local function grabAndFire(data,slotseq_mode,exmatch_mode,filtmeta,frominv,frominvname,frompos,fromnode,filterfor,fromtube,fromdef,dir,fakePlayer,all,digiline,tag)
local sposes = {}
if not frominvname or not frominv:get_list(frominvname) then return end
for spos,stack in ipairs(frominv:get_list(frominvname)) do
@ -201,7 +202,7 @@ local function grabAndFire(data,slotseq_mode,exmatch_mode,filtmeta,frominv,fromi
end
local pos = vector.add(frompos, vector.multiply(dir, 1.4))
local start_pos = vector.add(frompos, dir)
local item1 = pipeworks.tube_inject_item(pos, start_pos, dir, item, fakePlayer:get_player_name())
local item1 = pipeworks.tube_inject_item(pos, start_pos, dir, item, fakePlayer:get_player_name(),tag)
return true-- only fire one item, please
end
@ -262,6 +263,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
local slotseq_mode
local exact_match
local tag
local filters = {}
if data.digiline then
@ -281,6 +283,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
local t_msg = type(msg)
if t_msg == "table" then
tag = msg.tag
local slotseq = msg.slotseq
local t_slotseq = type(slotseq)
if t_slotseq == "number" and slotseq >= 0 and slotseq <= 2 then
@ -378,7 +381,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do
local done = false
for _, filterfor in ipairs(filters) do
if grabAndFire(data, slotseq_mode, exact_match, filtmeta, frominv, frominvname, frompos, fromnode, filterfor, fromtube, fromdef, dir, fakePlayer, data.stackwise, data.digiline) then
if grabAndFire(data, slotseq_mode, exact_match, filtmeta, frominv, frominvname, frompos, fromnode, filterfor, fromtube, fromdef, dir, fakePlayer, data.stackwise, data.digiline,tag) then
done = true
break
end
@ -489,6 +492,19 @@ for _, data in ipairs({
local setchan = meta:get_string("channel")
if setchan ~= channel then return end
if msg.tag ~= nil then -- check tag size
local tagstring = minetest.serialize(msg.tag)
local tagsize_max = tonumber(core.settings:get("pipeworks_tag_max_size")) or 100
if (#tagstring > tagsize_max) then
local errmsg = "Warning: lua_tube 'event.item.tag' memory overflow.\r"..tagsize_max.." bytes available, "
..#tagstring.." required. 'event.item.tag set to 'nil'"
msg.tag = nil
print(errmsg)
-- show message on digiline filter injector formspec.
local formspec_meta = meta:get_string("formspec")
meta:set_string("formspec", string.gsub(formspec_meta, "label.1.4,0.444;.", "label[1.4,0.444;"..errmsg.."]"))
end
end
punch_filter(data, pos, node, msg)
end,
},

View File

@ -7,10 +7,12 @@ function pipeworks.tube_item(pos, item)
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
end
function pipeworks.tube_inject_item(pos, start_pos, velocity, item, owner)
function pipeworks.tube_inject_item(pos, start_pos, velocity, item, owner,tag)
-- Take item in any format
local stack = ItemStack(item)
local obj = luaentity.add_entity(pos, "pipeworks:tubed_item")
obj.tag.value = tag
obj:set_item(stack:to_string())
obj.start_pos = vector.new(start_pos)
obj:set_velocity(velocity)
@ -72,13 +74,13 @@ end
-- 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 function go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner,tag)
local next_positions = {}
local max_priority = 0
local can_go
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)
can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack,tag)
else
can_go = pipeworks.notvel(adjlist, vel)
end
@ -134,7 +136,7 @@ end
-- * 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 function go_next(pos, velocity, stack, owner,tag)
local cnode = minetest.get_node(pos)
local cmeta = minetest.get_meta(pos)
local speed = math.abs(velocity.x + velocity.y + velocity.z)
@ -162,7 +164,7 @@ local function go_next(pos, velocity, stack, owner)
-- 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)
local n, found, new_velocity, multimode = go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner,tag)
-- if not using output cycling,
-- don't update the field so it stays the same for the next item.
@ -260,7 +262,8 @@ end
luaentity.register_entity("pipeworks:tubed_item", {
itemstring = '',
item_entity = nil,
tag={value=""}, -- writable/readable tag in injector with digiline and in lua tube (a table is use , to update value by ref in functions)
item_entity = nil,
color_entity = nil,
color = nil,
start_pos = nil,
@ -338,7 +341,7 @@ luaentity.register_entity("pipeworks:tubed_item", {
end
if moved then
local found_next, new_velocity, multimode = 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,self.tag) -- 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)))
@ -364,7 +367,7 @@ luaentity.register_entity("pipeworks:tubed_item", {
-- 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)
pipeworks.tube_inject_item(s, s, split.velocity, split.itemstack, self.owner,self.tag)
end
-- remove ourself now the splits are sent
self:remove()

View File

@ -718,6 +718,31 @@ for white = 0, 1 do
}
}
local function show_tag_warning(pos,errmsg)
local meta = minetest.get_meta(pos)
local code = minetest.formspec_escape(meta:get_string("code") or "")
errmsg = minetest.formspec_escape(tostring(errmsg or ""))
meta:set_string("formspec", "size[12,10]"..
"background[-0.2,-0.25;12.4,10.75;jeija_luac_background.png]"..
"textarea[0.2,0.2;12.2,9.5;code;;"..code.."]"..
"image_button[4.75,8.75;2.5,1;jeija_luac_runbutton.png;program;]"..
"image_button_exit[11.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
"label[0.1,8.3;"..errmsg.."]")
end
local function check_tag(pos,tag)
if tag == nil then return true end
local tagstring = minetest.serialize(tag)
local tagsize_max = tonumber(core.settings:get("pipeworks_tag_max_size")) or 100
if (#tagstring > tagsize_max) then
local errmsg = "Warning: lua_tube 'event.item.tag' memory overflow. "..tagsize_max.." bytes available, "
..#tagstring.." required. 'event.item.tag set to 'nil'"
print(errmsg)
show_tag_warning(pos,errmsg)
return false
end
return true
end
minetest.register_node(node_name, {
description = "Lua controlled Tube",
drawtype = "nodebox",
@ -753,7 +778,7 @@ for white = 0, 1 do
tube = {
connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1},
priority = 50,
can_go = function(pos, node, velocity, stack)
can_go = function(pos, node, velocity, stack,tag)
local src = {name = nil}
-- add color of the incoming tube explicitly; referring to rules, in case they change later
for color, rule in pairs(rules) do
@ -762,13 +787,26 @@ for white = 0, 1 do
break
end
end
-- add a writtable/readable tag on itemstack
local stack_table = stack:to_table()
stack_table.tag = tag.value -- coz meta can't be accessed in lua controller
local succ, msg = run(pos, {
type = "item",
pin = src,
itemstring = stack:to_string(),
item = stack:to_table(),
item = stack_table,
velocity = velocity,
})
if check_tag(pos,stack_table.tag) then
tag.value = stack_table.tag
else
tag.value = nil
end
stack_table = nil
if not succ or type(msg) ~= "string" then
return go_back(velocity)
end

View File

@ -75,3 +75,6 @@ pipeworks_drop_on_routing_fail (Drop On Routing Fail) bool false
#Delete item on clearobject.
pipeworks_delete_item_on_clearobject (Delete Item On Clearobject) bool true
#max size for tag on tubed item stack
pipeworks_tag_max_size (Max Size for tubed item Read/Writable tag ) int 100 0 65535