forked from mtcontrib/pipeworks
split the filter-injector specific code out of the generic item_transport
This commit is contained in:
parent
1e50644487
commit
009b9e9276
201
filter-injector.lua
Normal file
201
filter-injector.lua
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
local function delay(x)
|
||||||
|
return (function() return x end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_filter_infotext(data, meta)
|
||||||
|
local infotext = data.wise_desc.." Filter-Injector"
|
||||||
|
if meta:get_int("slotseq_mode") == 2 then
|
||||||
|
infotext = infotext .. " (slot #"..meta:get_int("slotseq_index").." next)"
|
||||||
|
end
|
||||||
|
meta:set_string("infotext", infotext)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_filter_formspec(data, meta)
|
||||||
|
local itemname = data.wise_desc.." Filter-Injector"
|
||||||
|
local formspec = "size[8,8.5]"..
|
||||||
|
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
|
||||||
|
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
|
||||||
|
"label[0,1;Prefer item types:]"..
|
||||||
|
"list[current_name;main;0,1.5;8,2;]"..
|
||||||
|
fs_helpers.cycling_button(meta, "button[0,3.5;4,1", "slotseq_mode",
|
||||||
|
{"Sequence slots by Priority",
|
||||||
|
"Sequence slots Randomly",
|
||||||
|
"Sequence slots by Rotation"})..
|
||||||
|
"list[current_player;main;0,4.5;8,4;]"
|
||||||
|
meta:set_string("formspec", formspec)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- todo SOON: this function has *way too many* parameters
|
||||||
|
local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompos,fromnode,filtername,fromtube,fromdef,dir,fakePlayer,all)
|
||||||
|
local sposes = {}
|
||||||
|
for spos,stack in ipairs(frominv:get_list(frominvname)) do
|
||||||
|
local matches
|
||||||
|
if filtername == "" then
|
||||||
|
matches = stack:get_name() ~= ""
|
||||||
|
else
|
||||||
|
matches = stack:get_name() == filtername
|
||||||
|
end
|
||||||
|
if matches then table.insert(sposes, spos) end
|
||||||
|
end
|
||||||
|
if #sposes == 0 then return false end
|
||||||
|
if slotseq_mode == 1 then
|
||||||
|
for i = #sposes, 2, -1 do
|
||||||
|
local j = math.random(i)
|
||||||
|
local t = sposes[j]
|
||||||
|
sposes[j] = sposes[i]
|
||||||
|
sposes[i] = t
|
||||||
|
end
|
||||||
|
elseif slotseq_mode == 2 then
|
||||||
|
local headpos = filtmeta:get_int("slotseq_index")
|
||||||
|
table.sort(sposes, function (a, b)
|
||||||
|
if a >= headpos then
|
||||||
|
if b < headpos then return true end
|
||||||
|
else
|
||||||
|
if b >= headpos then return false end
|
||||||
|
end
|
||||||
|
return a < b
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
for _, spos in ipairs(sposes) do
|
||||||
|
local stack = frominv:get_stack(frominvname, spos)
|
||||||
|
local doRemove = stack:get_count()
|
||||||
|
if fromtube.can_remove then
|
||||||
|
doRemove = fromtube.can_remove(frompos, fromnode, stack, dir)
|
||||||
|
elseif fromdef.allow_metadata_inventory_take then
|
||||||
|
doRemove = fromdef.allow_metadata_inventory_take(frompos, frominvname,spos, stack, fakePlayer)
|
||||||
|
end
|
||||||
|
-- stupid lack of continue statements grumble
|
||||||
|
if doRemove > 0 then
|
||||||
|
if slotseq_mode == 2 then
|
||||||
|
local nextpos = spos + 1
|
||||||
|
if nextpos > frominv:get_size(frominvname) then
|
||||||
|
nextpos = 1
|
||||||
|
end
|
||||||
|
filtmeta:set_int("slotseq_index", nextpos)
|
||||||
|
set_filter_infotext(data, filtmeta)
|
||||||
|
end
|
||||||
|
local item
|
||||||
|
local count
|
||||||
|
if all then
|
||||||
|
count = math.min(stack:get_count(), doRemove)
|
||||||
|
else
|
||||||
|
count = 1
|
||||||
|
end
|
||||||
|
if fromtube.remove_items then
|
||||||
|
-- it could be the entire stack...
|
||||||
|
item = fromtube.remove_items(frompos, fromnode, stack, dir, count)
|
||||||
|
else
|
||||||
|
item = stack:take_item(count)
|
||||||
|
frominv:set_stack(frominvname, spos, stack)
|
||||||
|
if fromdef.on_metadata_inventory_take then
|
||||||
|
fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakePlayer)
|
||||||
|
end
|
||||||
|
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)
|
||||||
|
return true-- only fire one item, please
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function punch_filter(data, filtpos, filtnode)
|
||||||
|
local filtmeta = minetest.get_meta(filtpos)
|
||||||
|
local filtinv = filtmeta:get_inventory()
|
||||||
|
local owner = filtmeta:get_string("owner")
|
||||||
|
local fakePlayer = {
|
||||||
|
get_player_name = delay(owner),
|
||||||
|
} -- TODO: use a mechanism as the wielder one
|
||||||
|
local dir = minetest.facedir_to_right_dir(filtnode.param2)
|
||||||
|
local frompos = vector.subtract(filtpos, dir)
|
||||||
|
local fromnode = minetest.get_node(frompos)
|
||||||
|
if not fromnode then return end
|
||||||
|
local fromdef = minetest.registered_nodes[fromnode.name]
|
||||||
|
if not fromdef then return end
|
||||||
|
local fromtube = fromdef.tube
|
||||||
|
if not (fromtube and fromtube.input_inventory) then return end
|
||||||
|
local filters = {}
|
||||||
|
for _, filterstack in ipairs(filtinv:get_list("main")) do
|
||||||
|
local filtername = filterstack:get_name()
|
||||||
|
if filtername ~= "" then table.insert(filters, filtername) end
|
||||||
|
end
|
||||||
|
if #filters == 0 then table.insert(filters, "") end
|
||||||
|
local slotseq_mode = filtmeta:get_int("slotseq_mode")
|
||||||
|
local frommeta = minetest.get_meta(frompos)
|
||||||
|
local frominv = frommeta:get_inventory()
|
||||||
|
if fromtube.before_filter then fromtube.before_filter(frompos) end
|
||||||
|
for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do
|
||||||
|
local done = false
|
||||||
|
for _, filtername in ipairs(filters) do
|
||||||
|
if grabAndFire(data, slotseq_mode, filtmeta, frominv, frominvname, frompos, fromnode, filtername, fromtube, fromdef, dir, fakePlayer, data.stackwise) then
|
||||||
|
done = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if done then break end
|
||||||
|
end
|
||||||
|
if fromtube.after_filter then fromtube.after_filter(frompos) end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, data in ipairs({
|
||||||
|
{
|
||||||
|
name = "filter",
|
||||||
|
wise_desc = "Itemwise",
|
||||||
|
stackwise = false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "mese_filter",
|
||||||
|
wise_desc = "Stackwise",
|
||||||
|
stackwise = true,
|
||||||
|
},
|
||||||
|
}) do
|
||||||
|
minetest.register_node("pipeworks:"..data.name, {
|
||||||
|
description = data.wise_desc.." Filter-Injector",
|
||||||
|
tiles = {
|
||||||
|
"pipeworks_"..data.name.."_top.png",
|
||||||
|
"pipeworks_"..data.name.."_top.png",
|
||||||
|
"pipeworks_"..data.name.."_output.png",
|
||||||
|
"pipeworks_"..data.name.."_input.png",
|
||||||
|
"pipeworks_"..data.name.."_side.png",
|
||||||
|
"pipeworks_"..data.name.."_top.png",
|
||||||
|
},
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2},
|
||||||
|
legacy_facedir_simple = true,
|
||||||
|
sounds = default.node_sound_wood_defaults(),
|
||||||
|
on_construct = function(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
set_filter_formspec(data, meta)
|
||||||
|
set_filter_infotext(data, meta)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
inv:set_size("main", 8*2)
|
||||||
|
end,
|
||||||
|
after_place_node = function (pos, placer)
|
||||||
|
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||||
|
end,
|
||||||
|
on_receive_fields = function(pos, formname, fields, sender)
|
||||||
|
fs_helpers.on_receive_fields(pos, fields)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
meta:set_int("slotseq_index", 1)
|
||||||
|
set_filter_formspec(data, meta)
|
||||||
|
set_filter_infotext(data, meta)
|
||||||
|
end,
|
||||||
|
can_dig = function(pos, player)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
return inv:is_empty("main")
|
||||||
|
end,
|
||||||
|
mesecons = {
|
||||||
|
effector = {
|
||||||
|
action_on = function(pos, node)
|
||||||
|
punch_filter(data, pos, node)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tube = {connect_sides = {right = 1}},
|
||||||
|
on_punch = function (pos, node, puncher)
|
||||||
|
punch_filter(data, pos, node)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
1
init.lua
1
init.lua
@ -116,6 +116,7 @@ dofile(pipeworks.modpath.."/item_transport.lua")
|
|||||||
dofile(pipeworks.modpath.."/flowing_logic.lua")
|
dofile(pipeworks.modpath.."/flowing_logic.lua")
|
||||||
dofile(pipeworks.modpath.."/crafts.lua")
|
dofile(pipeworks.modpath.."/crafts.lua")
|
||||||
dofile(pipeworks.modpath.."/tubes.lua")
|
dofile(pipeworks.modpath.."/tubes.lua")
|
||||||
|
dofile(pipeworks.modpath.."/filter-injector.lua")
|
||||||
dofile(pipeworks.modpath.."/trashcan.lua")
|
dofile(pipeworks.modpath.."/trashcan.lua")
|
||||||
dofile(pipeworks.modpath.."/wielder.lua")
|
dofile(pipeworks.modpath.."/wielder.lua")
|
||||||
|
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
local function delay(x)
|
|
||||||
return (function() return x end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pipeworks.tube_item(pos, item)
|
function pipeworks.tube_item(pos, item)
|
||||||
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
|
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
|
||||||
end
|
end
|
||||||
@ -23,204 +19,6 @@ end
|
|||||||
-- both optional w/ sensible defaults and fallback to normal allow_* function
|
-- both optional w/ sensible defaults and fallback to normal allow_* function
|
||||||
-- XXX: possibly change insert_object to insert_item
|
-- XXX: possibly change insert_object to insert_item
|
||||||
|
|
||||||
local function set_filter_infotext(data, meta)
|
|
||||||
local infotext = data.wise_desc.." Filter-Injector"
|
|
||||||
if meta:get_int("slotseq_mode") == 2 then
|
|
||||||
infotext = infotext .. " (slot #"..meta:get_int("slotseq_index").." next)"
|
|
||||||
end
|
|
||||||
meta:set_string("infotext", infotext)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function set_filter_formspec(data, meta)
|
|
||||||
local itemname = data.wise_desc.." Filter-Injector"
|
|
||||||
local formspec = "size[8,8.5]"..
|
|
||||||
"item_image[0,0;1,1;pipeworks:"..data.name.."]"..
|
|
||||||
"label[1,0;"..minetest.formspec_escape(itemname).."]"..
|
|
||||||
"label[0,1;Prefer item types:]"..
|
|
||||||
"list[current_name;main;0,1.5;8,2;]"..
|
|
||||||
fs_helpers.cycling_button(meta, "button[0,3.5;4,1", "slotseq_mode",
|
|
||||||
{"Sequence slots by Priority",
|
|
||||||
"Sequence slots Randomly",
|
|
||||||
"Sequence slots by Rotation"})..
|
|
||||||
"list[current_player;main;0,4.5;8,4;]"
|
|
||||||
meta:set_string("formspec", formspec)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- todo SOON: this function has *way too many* parameters
|
|
||||||
local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompos,fromnode,filtername,fromtube,fromdef,dir,fakePlayer,all)
|
|
||||||
local sposes = {}
|
|
||||||
for spos,stack in ipairs(frominv:get_list(frominvname)) do
|
|
||||||
local matches
|
|
||||||
if filtername == "" then
|
|
||||||
matches = stack:get_name() ~= ""
|
|
||||||
else
|
|
||||||
matches = stack:get_name() == filtername
|
|
||||||
end
|
|
||||||
if matches then table.insert(sposes, spos) end
|
|
||||||
end
|
|
||||||
if #sposes == 0 then return false end
|
|
||||||
if slotseq_mode == 1 then
|
|
||||||
for i = #sposes, 2, -1 do
|
|
||||||
local j = math.random(i)
|
|
||||||
local t = sposes[j]
|
|
||||||
sposes[j] = sposes[i]
|
|
||||||
sposes[i] = t
|
|
||||||
end
|
|
||||||
elseif slotseq_mode == 2 then
|
|
||||||
local headpos = filtmeta:get_int("slotseq_index")
|
|
||||||
table.sort(sposes, function (a, b)
|
|
||||||
if a >= headpos then
|
|
||||||
if b < headpos then return true end
|
|
||||||
else
|
|
||||||
if b >= headpos then return false end
|
|
||||||
end
|
|
||||||
return a < b
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
for _, spos in ipairs(sposes) do
|
|
||||||
local stack = frominv:get_stack(frominvname, spos)
|
|
||||||
local doRemove = stack:get_count()
|
|
||||||
if fromtube.can_remove then
|
|
||||||
doRemove = fromtube.can_remove(frompos, fromnode, stack, dir)
|
|
||||||
elseif fromdef.allow_metadata_inventory_take then
|
|
||||||
doRemove = fromdef.allow_metadata_inventory_take(frompos, frominvname,spos, stack, fakePlayer)
|
|
||||||
end
|
|
||||||
-- stupid lack of continue statements grumble
|
|
||||||
if doRemove > 0 then
|
|
||||||
if slotseq_mode == 2 then
|
|
||||||
local nextpos = spos + 1
|
|
||||||
if nextpos > frominv:get_size(frominvname) then
|
|
||||||
nextpos = 1
|
|
||||||
end
|
|
||||||
filtmeta:set_int("slotseq_index", nextpos)
|
|
||||||
set_filter_infotext(data, filtmeta)
|
|
||||||
end
|
|
||||||
local item
|
|
||||||
local count
|
|
||||||
if all then
|
|
||||||
count = math.min(stack:get_count(), doRemove)
|
|
||||||
else
|
|
||||||
count = 1
|
|
||||||
end
|
|
||||||
if fromtube.remove_items then
|
|
||||||
-- it could be the entire stack...
|
|
||||||
item = fromtube.remove_items(frompos, fromnode, stack, dir, count)
|
|
||||||
else
|
|
||||||
item = stack:take_item(count)
|
|
||||||
frominv:set_stack(frominvname, spos, stack)
|
|
||||||
if fromdef.on_metadata_inventory_take then
|
|
||||||
fromdef.on_metadata_inventory_take(frompos, frominvname, spos, item, fakePlayer)
|
|
||||||
end
|
|
||||||
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)
|
|
||||||
return true-- only fire one item, please
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local function punch_filter(data, filtpos, filtnode)
|
|
||||||
local filtmeta = minetest.get_meta(filtpos)
|
|
||||||
local filtinv = filtmeta:get_inventory()
|
|
||||||
local owner = filtmeta:get_string("owner")
|
|
||||||
local fakePlayer = {
|
|
||||||
get_player_name = delay(owner),
|
|
||||||
} -- TODO: use a mechanism as the wielder one
|
|
||||||
local dir = minetest.facedir_to_right_dir(filtnode.param2)
|
|
||||||
local frompos = vector.subtract(filtpos, dir)
|
|
||||||
local fromnode = minetest.get_node(frompos)
|
|
||||||
if not fromnode then return end
|
|
||||||
local fromdef = minetest.registered_nodes[fromnode.name]
|
|
||||||
if not fromdef then return end
|
|
||||||
local fromtube = fromdef.tube
|
|
||||||
if not (fromtube and fromtube.input_inventory) then return end
|
|
||||||
local filters = {}
|
|
||||||
for _, filterstack in ipairs(filtinv:get_list("main")) do
|
|
||||||
local filtername = filterstack:get_name()
|
|
||||||
if filtername ~= "" then table.insert(filters, filtername) end
|
|
||||||
end
|
|
||||||
if #filters == 0 then table.insert(filters, "") end
|
|
||||||
local slotseq_mode = filtmeta:get_int("slotseq_mode")
|
|
||||||
local frommeta = minetest.get_meta(frompos)
|
|
||||||
local frominv = frommeta:get_inventory()
|
|
||||||
if fromtube.before_filter then fromtube.before_filter(frompos) end
|
|
||||||
for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do
|
|
||||||
local done = false
|
|
||||||
for _, filtername in ipairs(filters) do
|
|
||||||
if grabAndFire(data, slotseq_mode, filtmeta, frominv, frominvname, frompos, fromnode, filtername, fromtube, fromdef, dir, fakePlayer, data.stackwise) then
|
|
||||||
done = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if done then break end
|
|
||||||
end
|
|
||||||
if fromtube.after_filter then fromtube.after_filter(frompos) end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, data in ipairs({
|
|
||||||
{
|
|
||||||
name = "filter",
|
|
||||||
wise_desc = "Itemwise",
|
|
||||||
stackwise = false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "mese_filter",
|
|
||||||
wise_desc = "Stackwise",
|
|
||||||
stackwise = true,
|
|
||||||
},
|
|
||||||
}) do
|
|
||||||
minetest.register_node("pipeworks:"..data.name, {
|
|
||||||
description = data.wise_desc.." Filter-Injector",
|
|
||||||
tiles = {
|
|
||||||
"pipeworks_"..data.name.."_top.png",
|
|
||||||
"pipeworks_"..data.name.."_top.png",
|
|
||||||
"pipeworks_"..data.name.."_output.png",
|
|
||||||
"pipeworks_"..data.name.."_input.png",
|
|
||||||
"pipeworks_"..data.name.."_side.png",
|
|
||||||
"pipeworks_"..data.name.."_top.png",
|
|
||||||
},
|
|
||||||
paramtype2 = "facedir",
|
|
||||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, mesecon = 2},
|
|
||||||
legacy_facedir_simple = true,
|
|
||||||
sounds = default.node_sound_wood_defaults(),
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
set_filter_formspec(data, meta)
|
|
||||||
set_filter_infotext(data, meta)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
inv:set_size("main", 8*2)
|
|
||||||
end,
|
|
||||||
after_place_node = function (pos, placer)
|
|
||||||
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
|
||||||
end,
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
|
||||||
fs_helpers.on_receive_fields(pos, fields)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_int("slotseq_index", 1)
|
|
||||||
set_filter_formspec(data, meta)
|
|
||||||
set_filter_infotext(data, meta)
|
|
||||||
end,
|
|
||||||
can_dig = function(pos, player)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:is_empty("main")
|
|
||||||
end,
|
|
||||||
mesecons = {
|
|
||||||
effector = {
|
|
||||||
action_on = function(pos, node)
|
|
||||||
punch_filter(data, pos, node)
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tube = {connect_sides = {right = 1}},
|
|
||||||
on_punch = function (pos, node, puncher)
|
|
||||||
punch_filter(data, pos, node)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local adjlist={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=0,y=1,z=0},{x=0,y=-1,z=0},{x=1,y=0,z=0},{x=-1,y=0,z=0}}
|
local adjlist={{x=0,y=0,z=1},{x=0,y=0,z=-1},{x=0,y=1,z=0},{x=0,y=-1,z=0},{x=1,y=0,z=0},{x=-1,y=0,z=0}}
|
||||||
|
|
||||||
function pipeworks.notvel(tbl, vel)
|
function pipeworks.notvel(tbl, vel)
|
||||||
|
Loading…
Reference in New Issue
Block a user