summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter-injector.lua201
-rwxr-xr-xinit.lua1
-rwxr-xr-xitem_transport.lua202
3 files changed, 202 insertions, 202 deletions
diff --git a/filter-injector.lua b/filter-injector.lua
new file mode 100644
index 0000000..599303f
--- /dev/null
+++ b/filter-injector.lua
@@ -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
diff --git a/init.lua b/init.lua
index 200bed3..98b2585 100755
--- a/init.lua
+++ b/init.lua
@@ -116,6 +116,7 @@ dofile(pipeworks.modpath.."/item_transport.lua")
dofile(pipeworks.modpath.."/flowing_logic.lua")
dofile(pipeworks.modpath.."/crafts.lua")
dofile(pipeworks.modpath.."/tubes.lua")
+dofile(pipeworks.modpath.."/filter-injector.lua")
dofile(pipeworks.modpath.."/trashcan.lua")
dofile(pipeworks.modpath.."/wielder.lua")
diff --git a/item_transport.lua b/item_transport.lua
index 8d5cc51..fb9f626 100755
--- a/item_transport.lua
+++ b/item_transport.lua
@@ -1,7 +1,3 @@
-local function delay(x)
- return (function() return x end)
-end
-
function pipeworks.tube_item(pos, item)
error("obsolete pipeworks.tube_item() called; change caller to use pipeworks.tube_inject_item() instead")
end
@@ -23,204 +19,6 @@ end
-- both optional w/ sensible defaults and fallback to normal allow_* function
-- 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}}
function pipeworks.notvel(tbl, vel)