Skip to content

Commit 8d34ff9

Browse files
fix #15 and #62 (process split stacks) (#154)
* fix #15 fixes #15 * fix luacheck stuff * I mean here * crash fix + allow arbitrary-count extraction * crash fix * wrong place * missed an end
1 parent 999b43b commit 8d34ff9

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

filter-injector.lua

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
117117
}
118118

119119
-- make sure there's something appropriate to inject the item into
120-
local todir = pipeworks.facedir_to_right_dir(filtnode.param2)
121-
local topos = vector.add(filtpos, todir)
120+
local topos = vector.add(filtpos, dir)
122121
local tonode = minetest.get_node(topos)
123122
local todef = minetest.registered_nodes[tonode.name]
124123

@@ -258,6 +257,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
258257
if fromtube.before_filter then fromtube.before_filter(frompos) end
259258

260259
local function grabAndFire(frominvname, filterfor)
260+
if (exmatch_mode ~= 0) and not filterfor.count then return false end
261261
local sposes = {}
262262
if not frominvname or not frominv:get_list(frominvname) then return end
263263
for spos,stack in ipairs(frominv:get_list(frominvname)) do
@@ -314,6 +314,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
314314
return a < b
315315
end)
316316
end
317+
local taken = 0
317318
for _, spos in ipairs(sposes) do
318319
local stack = frominv:get_stack(frominvname, spos)
319320
local doRemove = stack:get_count()
@@ -332,39 +333,53 @@ local function punch_filter(data, filtpos, filtnode, msg)
332333
filtmeta:set_int("slotseq_index", nextpos)
333334
set_filter_infotext(data, filtmeta)
334335
end
335-
local item
336336
local count
337337
if data.stackwise then
338338
count = math.min(stack:get_count(), doRemove)
339-
if filterfor.count and (filterfor.count > 1 or data.digiline) then
340-
if exmatch_mode ~= 0 and filterfor.count > count then
341-
return false -- not enough, fail
342-
else
343-
-- limit quantity to filter amount
344-
count = math.min(filterfor.count, count)
345-
end
346-
end
339+
taken = taken + count
347340
else
348-
count = 1
341+
taken = 1
342+
break
349343
end
350-
if fromtube.remove_items then
351-
-- it could be the entire stack...
352-
item = fromtube.remove_items(frompos, fromnode, stack, dir, count, frominvname, spos)
353-
else
354-
item = stack:take_item(count)
355-
frominv:set_stack(frominvname, spos, stack)
356-
if fromdef.on_metadata_inventory_take then
357-
fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakeplayer)
358-
end
344+
end
345+
end
346+
local item
347+
if taken == 0 then return false end
348+
if (exmatch_mode ~= 0) and (filterfor.count > taken) then return false end
349+
if filterfor.count then taken = math.min(taken, filterfor.count) end
350+
local real_taken = 0
351+
if fromtube.remove_items then
352+
for i, spos in ipairs(sposes) do
353+
-- it could be the entire stack...
354+
item = fromtube.remove_items(frompos, fromnode, frominv:get_stack(frominvname, spos), dir, taken, frominvname, spos)
355+
local count = math.min(taken, item:get_count())
356+
taken = taken - count
357+
real_taken = real_taken + count
358+
if taken == 0 then break end
359+
if not filterfor.count then break end
360+
end
361+
else
362+
for i, spos in ipairs(sposes) do
363+
-- it could be the entire stack...
364+
local stack = frominv:get_stack(frominvname, spos)
365+
local count = math.min(taken, stack:get_count())
366+
item = stack:take_item(taken)
367+
frominv:set_stack(frominvname, spos, stack)
368+
if fromdef.on_metadata_inventory_take then
369+
fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakeplayer)
359370
end
360-
local pos = vector.add(frompos, vector.multiply(dir, 1.4))
361-
local start_pos = vector.add(frompos, dir)
362-
pipeworks.tube_inject_item(pos, start_pos, dir, item,
363-
fakeplayer:get_player_name(), item_tags)
364-
return true -- only fire one item, please
371+
taken = taken - count
372+
real_taken = real_taken + count
373+
if taken == 0 then break end
374+
if not filterfor.count then break end
365375
end
366376
end
367-
return false
377+
local pos = vector.add(frompos, vector.multiply(dir, 1.4))
378+
local start_pos = vector.add(frompos, dir)
379+
item:set_count(real_taken)
380+
pipeworks.tube_inject_item(pos, start_pos, dir, item,
381+
fakeplayer:get_player_name(), item_tags)
382+
return true -- only fire one item, please
368383
end
369384

370385
for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do

0 commit comments

Comments
 (0)