Skip to content

Commit 6c66a2f

Browse files
slavazSlava ZankoBuckarooBanzayOgelGames
authored
Tags support (#107)
Signed-off-by: Slava Zanko <[email protected]> Co-authored-by: Slava Zanko <[email protected]> Co-authored-by: BuckarooBanzay <[email protected]> Co-authored-by: OgelGames <[email protected]>
1 parent 8724c28 commit 6c66a2f

22 files changed

+266
-18
lines changed

crafts.lua

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,26 @@ if pipeworks.enable_mese_tube then
223223
})
224224
end
225225

226+
if pipeworks.enable_item_tags and pipeworks.enable_tag_tube then
227+
minetest.register_craft( {
228+
output = "pipeworks:tag_tube_000000 2",
229+
recipe = {
230+
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" },
231+
{ materials.book, materials.mese_crystal, materials.book },
232+
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }
233+
},
234+
})
235+
236+
minetest.register_craft( {
237+
type = "shapeless",
238+
output = "pipeworks:tag_tube_000000",
239+
recipe = {
240+
"pipeworks:mese_tube_000000",
241+
materials.book,
242+
},
243+
})
244+
end
245+
226246
if pipeworks.enable_sand_tube then
227247
minetest.register_craft( {
228248
output = "pipeworks:sand_tube_1 2",

default_settings.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ local prefix = "pipeworks_"
44

55
local settings = {
66
enable_pipes = true,
7+
enable_item_tags = true,
8+
enable_tag_tube = true,
79
enable_lowpoly = false,
810
enable_autocrafter = true,
911
enable_deployer = true,

filter-injector.lua

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,29 @@ local function set_filter_formspec(data, meta)
1414

1515
local formspec
1616
if data.digiline then
17+
local form_height = 3
18+
if pipeworks.enable_item_tags then
19+
form_height = 4
20+
end
1721
formspec =
18-
"size[8.5,3]"..
22+
("size[8.5,%f]"):format(form_height) ..
1923
"item_image[0.2,0;1,1;pipeworks:"..data.name.."]"..
2024
"label[1.2,0.2;"..minetest.formspec_escape(itemname).."]"..
2125
"field[0.5,1.6;4.6,1;channel;"..S("Channel")..";${channel}]"..
2226
"button[4.8,1.3;1.5,1;set_channel;"..S("Set").."]"..
23-
fs_helpers.cycling_button(meta, "button[0.2,2.3;4.05,1", "slotseq_mode",
27+
fs_helpers.cycling_button(meta, ("button[0.2,%f;4.05,1"):format(form_height - 0.7), "slotseq_mode",
2428
{S("Sequence slots by Priority"),
2529
S("Sequence slots Randomly"),
2630
S("Sequence slots by Rotation")})..
27-
fs_helpers.cycling_button(meta, "button[4.25,2.3;4.05,1", "exmatch_mode",
31+
fs_helpers.cycling_button(meta, ("button[4.25,%f;4.05,1"):format(form_height - 0.7), "exmatch_mode",
2832
{S("Exact match - off"),
2933
S("Exact match - on")})..
30-
"button_exit[6.3,1.3;2,1;close;"..S("Close").."]"
34+
("button_exit[6.3,%f;2,1;close;" .. S("Close") .. "]"):format(form_height - 1.7)
35+
if pipeworks.enable_item_tags then
36+
formspec = formspec ..
37+
("field[0.5,%f;4.6,1;item_tags;"):format(form_height - 1.4) .. S("Item Tags") .. ";${item_tags}]" ..
38+
("button[4.8,%f;1.5,1;set_item_tags;"):format(form_height - 1.7) .. S("Set") .. "]"
39+
end
3140
else
3241
local exmatch_button = ""
3342
if data.stackwise then
@@ -62,6 +71,11 @@ local function set_filter_formspec(data, meta)
6271
exmatch_button..
6372
pipeworks.fs_helpers.get_inv(6)..
6473
"listring[]"
74+
if pipeworks.enable_item_tags then
75+
formspec = formspec ..
76+
"field[5.8,0.5;3,0.8;item_tags;" .. S("Item Tags") .. ";${item_tags}]" ..
77+
"button[9,0.3;1,1.1;set_item_tags;" .. S("Set") .. "]"
78+
end
6579
end
6680
meta:set_string("formspec", formspec)
6781
end
@@ -123,6 +137,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
123137
local slotseq_mode
124138
local exmatch_mode
125139

140+
local item_tags = pipeworks.sanitize_tags(filtmeta:get_string("item_tags"))
126141
local filters = {}
127142
if data.digiline then
128143
local function add_filter(name, group, count, wear, metadata)
@@ -186,6 +201,12 @@ local function punch_filter(data, filtpos, filtnode, msg)
186201
set_filter_formspec(data, filtmeta)
187202
end
188203

204+
if type(msg.tags) == "table" then
205+
item_tags = pipeworks.sanitize_tags(msg.tags)
206+
elseif type(msg.tag) == "string" then
207+
item_tags = pipeworks.sanitize_tags({msg.tag})
208+
end
209+
189210
if msg.nofire then
190211
return
191212
end
@@ -339,7 +360,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
339360
local pos = vector.add(frompos, vector.multiply(dir, 1.4))
340361
local start_pos = vector.add(frompos, dir)
341362
pipeworks.tube_inject_item(pos, start_pos, dir, item,
342-
fakePlayer:get_player_name())
363+
fakePlayer:get_player_name(), item_tags)
343364
return true -- only fire one item, please
344365
end
345366
end
@@ -457,6 +478,10 @@ for _, data in ipairs({
457478
end
458479

459480
local meta = minetest.get_meta(pos)
481+
if pipeworks.enable_item_tags and fields.item_tags and (fields.key_enter_field == "item_tags" or fields.set_item_tags) then
482+
local tags = pipeworks.sanitize_tags(fields.item_tags)
483+
meta:set_string("item_tags", table.concat(tags, ","))
484+
end
460485
--meta:set_int("slotseq_index", 1)
461486
set_filter_formspec(data, meta)
462487
set_filter_infotext(data, meta)
@@ -478,6 +503,10 @@ for _, data in ipairs({
478503
fs_helpers.on_receive_fields(pos, fields)
479504
local meta = minetest.get_meta(pos)
480505
meta:set_int("slotseq_index", 1)
506+
if pipeworks.enable_item_tags and fields.item_tags and (fields.key_enter_field == "item_tags" or fields.set_item_tags) then
507+
local tags = pipeworks.sanitize_tags(fields.item_tags)
508+
meta:set_string("item_tags", table.concat(tags, ","))
509+
end
481510
set_filter_formspec(data, meta)
482511
set_filter_infotext(data, meta)
483512
end

init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ dofile(pipeworks.modpath.."/tubes/sorting.lua")
6767
dofile(pipeworks.modpath.."/tubes/signal.lua")
6868
dofile(pipeworks.modpath.."/tubes/embedded_tube.lua")
6969
dofile(pipeworks.modpath.."/tubes/pane_embedded_tube.lua")
70+
dofile(pipeworks.modpath.."/tubes/tags.lua")
7071

7172
if pipeworks.enable_teleport_tube then
7273
dofile(pipeworks.modpath.."/tubes/teleport.lua")

item_transport.lua

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,44 @@ local enable_max_limit = minetest.settings:get_bool("pipeworks_enable_items_per_
33
local max_tube_limit = tonumber(minetest.settings:get("pipeworks_max_items_per_tube")) or 30
44
if enable_max_limit == nil then enable_max_limit = true end
55

6+
if pipeworks.enable_item_tags then
7+
local max_tag_length = tonumber(minetest.settings:get("pipeworks_max_item_tag_length")) or 32
8+
local max_tags = tonumber(minetest.settings:get("pipeworks_max_item_tags")) or 16
9+
10+
function pipeworks.sanitize_tags(tags)
11+
if type(tags) == "string" then
12+
tags = tags:split(",")
13+
end
14+
local sanitized = {}
15+
for i, tag in ipairs(tags) do
16+
if type(tag) == "string" then
17+
tag = tag:gsub("[%s,]", "") -- Remove whitespace and commas
18+
tag = tag:gsub("%$%b%{%}", "") -- Remove special ${key} values
19+
if tag ~= "" then
20+
table.insert(sanitized, tag:sub(1, max_tag_length))
21+
end
22+
end
23+
if #sanitized >= max_tags then
24+
break
25+
end
26+
end
27+
return sanitized
28+
end
29+
end
30+
631
function pipeworks.tube_item(pos, item)
732
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
833
end
934

10-
function pipeworks.tube_inject_item(pos, start_pos, velocity, item, owner)
35+
function pipeworks.tube_inject_item(pos, start_pos, velocity, item, owner, tags)
1136
-- Take item in any format
1237
local stack = ItemStack(item)
1338
local obj = luaentity.add_entity(pos, "pipeworks:tubed_item")
1439
obj:set_item(stack:to_string())
1540
obj.start_pos = vector.new(start_pos)
1641
obj:set_velocity(velocity)
1742
obj.owner = owner
43+
obj.tags = tags
1844
--obj:set_color("red") -- todo: this is test-only code
1945
return obj
2046
end
@@ -79,13 +105,14 @@ end
79105

80106
-- compatibility behaviour for the existing can_go() callbacks,
81107
-- which can only specify a list of possible positions.
82-
local function go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner)
108+
local function go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner, tags)
83109
local next_positions = {}
84110
local max_priority = 0
85111
local can_go
86112

87-
if minetest.registered_nodes[cnode.name] and minetest.registered_nodes[cnode.name].tube and minetest.registered_nodes[cnode.name].tube.can_go then
88-
can_go = minetest.registered_nodes[cnode.name].tube.can_go(pos, cnode, vel, stack)
113+
local def = minetest.registered_nodes[cnode.name]
114+
if def and def.tube and def.tube.can_go then
115+
can_go = def.tube.can_go(pos, cnode, vel, stack, tags)
89116
else
90117
local adjlist_string = minetest.get_meta(pos):get_string("adjlist")
91118
local adjlist = minetest.deserialize(adjlist_string) or default_adjlist -- backward compat: if not found, use old behavior: all directions
@@ -144,7 +171,7 @@ end
144171
-- * a "multi-mode" data table (or nil if N/A) where a stack was split apart.
145172
-- if this is not nil, the luaentity spawns new tubed items for each new fragment stack,
146173
-- then deletes itself (i.e. the original item stack).
147-
local function go_next(pos, velocity, stack, owner)
174+
local function go_next(pos, velocity, stack, owner, tags)
148175
local cnode = minetest.get_node(pos)
149176
local cmeta = minetest.get_meta(pos)
150177
local speed = math.abs(velocity.x + velocity.y + velocity.z)
@@ -172,7 +199,7 @@ local function go_next(pos, velocity, stack, owner)
172199
-- n is the new value of the cycle counter.
173200
-- XXX: this probably needs cleaning up after being split out,
174201
-- seven args is a bit too many
175-
local n, found, new_velocity, multimode = go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner)
202+
local n, found, new_velocity, multimode = go_next_compat(pos, cnode, cmeta, cycledir, vel, stack, owner, tags)
176203

177204
-- if not using output cycling,
178205
-- don't update the field so it stays the same for the next item.
@@ -276,6 +303,7 @@ luaentity.register_entity("pipeworks:tubed_item", {
276303
color_entity = nil,
277304
color = nil,
278305
start_pos = nil,
306+
tags = nil,
279307

280308
set_item = function(self, item)
281309
local itemstring = ItemStack(item):to_string() -- Accept any input format
@@ -337,8 +365,9 @@ luaentity.register_entity("pipeworks:tubed_item", {
337365
local node = minetest.get_node(self.start_pos)
338366
if minetest.get_item_group(node.name, "tubedevice_receiver") == 1 then
339367
local leftover
340-
if minetest.registered_nodes[node.name].tube and minetest.registered_nodes[node.name].tube.insert_object then
341-
leftover = minetest.registered_nodes[node.name].tube.insert_object(self.start_pos, node, stack, vel, self.owner)
368+
local def = minetest.registered_nodes[node.name]
369+
if def.tube and def.tube.insert_object then
370+
leftover = def.tube.insert_object(self.start_pos, node, stack, vel, self.owner)
342371
else
343372
leftover = stack
344373
end
@@ -353,7 +382,14 @@ luaentity.register_entity("pipeworks:tubed_item", {
353382
return
354383
end
355384

356-
local found_next, new_velocity, multimode = go_next(self.start_pos, velocity, stack, self.owner) -- todo: color
385+
local tags
386+
if pipeworks.enable_item_tags then
387+
tags = self.tags or {}
388+
end
389+
local found_next, new_velocity, multimode = go_next(self.start_pos, velocity, stack, self.owner, tags) -- todo: color
390+
if pipeworks.enable_item_tags then
391+
self.tags = #tags > 0 and pipeworks.sanitize_tags(tags) or nil
392+
end
357393
local rev_vel = vector.multiply(velocity, -1)
358394
local rev_dir = vector.direction(self.start_pos,vector.add(self.start_pos,rev_vel))
359395
local rev_node = minetest.get_node(vector.round(vector.add(self.start_pos,rev_dir)))

textures/pipeworks_tag_tube_end.png

875 Bytes
Loading

textures/pipeworks_tag_tube_inv.png

496 Bytes
Loading
768 Bytes
Loading
744 Bytes
Loading
743 Bytes
Loading
747 Bytes
Loading
769 Bytes
Loading
753 Bytes
Loading
864 Bytes
Loading
865 Bytes
Loading
863 Bytes
Loading
864 Bytes
Loading
871 Bytes
Loading
860 Bytes
Loading

textures/pipeworks_tag_tube_short.png

457 Bytes
Loading

tubes/lua.lua

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ for white = 0, 1 do
945945
tube = {
946946
connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1},
947947
priority = 50,
948-
can_go = function(pos, node, velocity, stack)
948+
can_go = function(pos, node, velocity, stack, tags)
949949
local src = {name = nil}
950950
-- add color of the incoming tube explicitly; referring to rules, in case they change later
951951
for _, rule in pairs(rules) do
@@ -960,12 +960,33 @@ for white = 0, 1 do
960960
itemstring = stack:to_string(),
961961
item = stack:to_table(),
962962
velocity = velocity,
963+
tags = table.copy(tags),
964+
side = src.name,
963965
})
964-
if not succ or type(msg) ~= "string" then
966+
if not succ then
965967
return go_back(velocity)
966968
end
967-
local r = rules[msg]
968-
return r and {r} or go_back(velocity)
969+
if type(msg) == "string" then
970+
local side = rules[msg]
971+
return side and {side} or go_back(velocity)
972+
elseif type(msg) == "table" then
973+
if pipeworks.enable_item_tags then
974+
local new_tags
975+
if type(msg.tags) == "table" then
976+
new_tags = msg.tags
977+
elseif type(msg.tag) == "string" then
978+
new_tags = {msg.tag}
979+
end
980+
if new_tags then
981+
for i=1, math.max(#tags, #new_tags) do
982+
tags[i] = new_tags[i]
983+
end
984+
end
985+
end
986+
local side = rules[msg.side]
987+
return side and {side} or go_back(velocity)
988+
end
989+
return go_back(velocity)
969990
end,
970991
},
971992
after_place_node = pipeworks.after_place,

0 commit comments

Comments
 (0)