@@ -117,8 +117,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
117
117
}
118
118
119
119
-- 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 )
122
121
local tonode = minetest .get_node (topos )
123
122
local todef = minetest .registered_nodes [tonode .name ]
124
123
@@ -258,6 +257,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
258
257
if fromtube .before_filter then fromtube .before_filter (frompos ) end
259
258
260
259
local function grabAndFire (frominvname , filterfor )
260
+ if (exmatch_mode ~= 0 ) and not filterfor .count then return false end
261
261
local sposes = {}
262
262
if not frominvname or not frominv :get_list (frominvname ) then return end
263
263
for spos ,stack in ipairs (frominv :get_list (frominvname )) do
@@ -314,6 +314,7 @@ local function punch_filter(data, filtpos, filtnode, msg)
314
314
return a < b
315
315
end )
316
316
end
317
+ local taken = 0
317
318
for _ , spos in ipairs (sposes ) do
318
319
local stack = frominv :get_stack (frominvname , spos )
319
320
local doRemove = stack :get_count ()
@@ -332,39 +333,53 @@ local function punch_filter(data, filtpos, filtnode, msg)
332
333
filtmeta :set_int (" slotseq_index" , nextpos )
333
334
set_filter_infotext (data , filtmeta )
334
335
end
335
- local item
336
336
local count
337
337
if data .stackwise then
338
338
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
347
340
else
348
- count = 1
341
+ taken = 1
342
+ break
349
343
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 )
359
370
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
365
375
end
366
376
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
368
383
end
369
384
370
385
for _ , frominvname in ipairs (type (fromtube .input_inventory ) == " table" and fromtube .input_inventory or {fromtube .input_inventory }) do
0 commit comments