Some improvements on the robot (still WIP)
First draft of tubelib_addons3 (still WIP)
@ -14,6 +14,15 @@
|
||||
|
||||
]]--
|
||||
|
||||
-- constrict value to the given range
|
||||
local function range(val, min, max)
|
||||
val = tonumber(val)
|
||||
if val < min then return min end
|
||||
if val > max then return max end
|
||||
return val
|
||||
end
|
||||
|
||||
|
||||
|
||||
sl_robot.register_action("get_ms_time", {
|
||||
cmnd = function(self)
|
||||
@ -25,7 +34,7 @@ sl_robot.register_action("get_ms_time", {
|
||||
|
||||
sl_robot.register_action("forward", {
|
||||
cmnd = function(self, steps)
|
||||
steps = math.min(tonumber(steps or 1), 100)
|
||||
steps = range(steps, 1, 100)
|
||||
local idx = 1
|
||||
while idx <= steps do
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
@ -49,7 +58,7 @@ sl_robot.register_action("forward", {
|
||||
|
||||
sl_robot.register_action("backward", {
|
||||
cmnd = function(self, steps)
|
||||
steps = math.min(tonumber(steps or 1), 100)
|
||||
steps = range(steps, 1, 100)
|
||||
local idx = 1
|
||||
while idx <= steps do
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
@ -140,8 +149,8 @@ sl_robot.register_action("down", {
|
||||
|
||||
sl_robot.register_action("take", {
|
||||
cmnd = function(self, num, slot)
|
||||
num = math.min(tonumber(num or 1), 99)
|
||||
slot = math.min(tonumber(slot or 1), 8)
|
||||
num = range(num, 1, 99)
|
||||
slot = range(slot, 1, 8)
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
local robot_pos = minetest.string_to_pos(meta:get_string("robot_pos"))
|
||||
local robot_param2 = meta:get_int("robot_param2")
|
||||
@ -159,8 +168,8 @@ sl_robot.register_action("take", {
|
||||
|
||||
sl_robot.register_action("add", {
|
||||
cmnd = function(self, num, slot)
|
||||
num = math.min(tonumber(num or 1), 99)
|
||||
slot = math.min(tonumber(slot or 1), 8)
|
||||
num = range(num, 1, 99)
|
||||
slot = range(slot, 1, 8)
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
local robot_pos = minetest.string_to_pos(meta:get_string("robot_pos"))
|
||||
local robot_param2 = meta:get_int("robot_param2")
|
||||
@ -177,7 +186,7 @@ sl_robot.register_action("add", {
|
||||
|
||||
sl_robot.register_action("place", {
|
||||
cmnd = function(self, slot, dir)
|
||||
slot = math.min(tonumber(slot or 1), 8)
|
||||
slot = range(slot, 1, 8)
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
local robot_pos = minetest.string_to_pos(meta:get_string("robot_pos"))
|
||||
local robot_param2 = meta:get_int("robot_param2")
|
||||
@ -193,7 +202,7 @@ sl_robot.register_action("place", {
|
||||
|
||||
sl_robot.register_action("dig", {
|
||||
cmnd = function(self, slot, dir)
|
||||
slot = math.min(tonumber(slot or 1), 8)
|
||||
slot = range(slot, 1, 8)
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
local robot_pos = minetest.string_to_pos(meta:get_string("robot_pos"))
|
||||
local robot_param2 = meta:get_int("robot_param2")
|
||||
@ -215,17 +224,3 @@ sl_robot.register_action("stop", {
|
||||
end,
|
||||
help = "tbd"
|
||||
})
|
||||
|
||||
--sl_robot.register_action("run", {
|
||||
-- cmnd = function(self, sCmd, reverse)
|
||||
-- slot = math.min(tonumber(slot or 1), 8)
|
||||
-- local meta = minetest.get_meta(self.meta.pos)
|
||||
-- local robot_pos = minetest.string_to_pos(meta:get_string("robot_pos"))
|
||||
-- local robot_param2 = meta:get_int("robot_param2")
|
||||
|
||||
-- for cmnd in sCmd:gmatch("%w+") do
|
||||
-- if cmnd:byte()
|
||||
-- end
|
||||
-- end,
|
||||
-- help = " "
|
||||
--})
|
||||
|
@ -16,3 +16,4 @@ sl_robot = {}
|
||||
dofile(minetest.get_modpath("sl_robot") .. "/robot.lua")
|
||||
dofile(minetest.get_modpath("sl_robot") .. "/base.lua")
|
||||
dofile(minetest.get_modpath("sl_robot") .. "/commands.lua")
|
||||
dofile(minetest.get_modpath("sl_robot") .. "/run_cmnd.lua")
|
||||
|
@ -23,40 +23,38 @@ local Face2Dir = {[0]=
|
||||
|
||||
|
||||
local Inventories = {
|
||||
["default:chest"] = {take = "main", add = "main", fuel = "main"},
|
||||
["default:chest_locked"] = {take = "main", add = "main", fuel = "main"},
|
||||
["default:chest_locked"] = {take = "main", add = "main", fuel = "main"},
|
||||
["default:furnace"] = {take = "dst", add = "src", fuel = "fuel"},
|
||||
["default:furnace_active"] = {take = "dst", add = "src", fuel = "fuel"},
|
||||
["tubelib:distributor"] = {take = "src", add = "src", fuel = "src"},
|
||||
["gravelsieve:sieve"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["gravelsieve:auto_sieve0"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["gravelsieve:auto_sieve1"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["gravelsieve:auto_sieve2"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["gravelsieve:auto_sieve3"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["tubelib_addons1:autocrafter"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["tubelib_addons1:autocrafter_active"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["tubelib_addons1:chest"] = {take = "main", add = "main", fuel = "main"},
|
||||
["tubelib_addons1:fermenter"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["tubelib_addons1:reformer"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["tubelib_addons1:funnel"] = {take = "main", add = "main", fuel = "main"},
|
||||
["tubelib_addons1:grinder"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["tubelib_addons1:grinder_active"] = {take = "dst", add = "src", fuel = "src"},
|
||||
["tubelib_addons1:harvester_base"] = {take = "main", add = "main", fuel = "fuel"},
|
||||
["tubelib_addons1:quarry"] = {take = "main", add = "main", fuel = "fuel"},
|
||||
["tubelib_addons1:quarry_active"] = {take = "main", add = "main", fuel = "fuel"},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
-- [""] = {take = "", add = "", fuel = ""},
|
||||
["tubelib:distributor"] = {take = "src", add = "src"},
|
||||
["tubelib_addons1:harvester_base"] = {take = "main", add = "fuel"},
|
||||
["tubelib_addons1:quarry"] = {take = "main", add = "fuel"},
|
||||
["tubelib_addons1:quarry_active"] = {take = "main", add = "fuel"},
|
||||
-- [""] = {take = "", add = ""},
|
||||
-- [""] = {take = "", add = ""},
|
||||
-- [""] = {take = "", add = ""},
|
||||
}
|
||||
|
||||
local function inv_list_add(inv, name)
|
||||
if Inventories[name] then
|
||||
return inv:get_list(Inventories[name].add)
|
||||
elseif inv:get_list("src") then
|
||||
return inv:get_list("src")
|
||||
elseif inv:get_list("main") then
|
||||
return inv:get_list("main")
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function inv_list_take(inv, name)
|
||||
if Inventories[name] then
|
||||
return inv:get_list(Inventories[name].take)
|
||||
elseif inv:get_list("dst") then
|
||||
return inv:get_list("dst")
|
||||
elseif inv:get_list("main") then
|
||||
return inv:get_list("main")
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
-- return the largest stack
|
||||
local function peek(src_list)
|
||||
local max_val = 0
|
||||
@ -264,19 +262,13 @@ function sl_robot.robot_take(base_pos, robot_pos, param2, owner, num, slot)
|
||||
return
|
||||
end
|
||||
local node = minetest.get_node_or_nil(pos1) or read_node_with_vm(pos1)
|
||||
if Inventories[node.name] then
|
||||
local listname = Inventories[node.name].take
|
||||
local src_inv = minetest.get_inventory({type="node", pos=pos1})
|
||||
if src_inv:is_empty(listname) then
|
||||
return
|
||||
end
|
||||
local src_list = src_inv:get_list(listname)
|
||||
local dst_inv = minetest.get_inventory({type="node", pos=base_pos})
|
||||
local dst_list = dst_inv:get_list("main")
|
||||
if take_num_items(src_list, num, dst_list[slot]) then
|
||||
src_inv:set_list(listname, src_list)
|
||||
dst_inv:set_list("main", dst_list)
|
||||
end
|
||||
local src_inv = minetest.get_inventory({type="node", pos=pos1})
|
||||
local src_list = inv_list_take(src_inv, node.name)
|
||||
local dst_inv = minetest.get_inventory({type="node", pos=base_pos})
|
||||
local dst_list = dst_inv:get_list("main")
|
||||
if src_list and take_num_items(src_list, num, dst_list[slot]) then
|
||||
src_inv:set_list(listname, src_list)
|
||||
dst_inv:set_list("main", dst_list)
|
||||
end
|
||||
end
|
||||
|
||||
@ -286,12 +278,11 @@ function sl_robot.robot_add(base_pos, robot_pos, param2, owner, num, slot)
|
||||
return
|
||||
end
|
||||
local node = minetest.get_node_or_nil(pos1) or read_node_with_vm(pos1)
|
||||
if Inventories[node.name] then
|
||||
local listname = Inventories[node.name].take
|
||||
local dst_inv = minetest.get_inventory({type="node", pos=pos1})
|
||||
local dst_list = dst_inv:get_list(listname)
|
||||
local src_inv = minetest.get_inventory({type="node", pos=base_pos})
|
||||
local src_list = src_inv:get_list("main")
|
||||
local dst_inv = minetest.get_inventory({type="node", pos=pos1})
|
||||
local dst_list = inv_list_add(dst_inv, node.name)
|
||||
local src_inv = minetest.get_inventory({type="node", pos=base_pos})
|
||||
local src_list = src_inv:get_list("main")
|
||||
if dst_list then
|
||||
local taken = src_list[slot]:take_item(num)
|
||||
if dst_inv:room_for_item(listname, taken) then
|
||||
dst_inv:add_item(listname, taken)
|
||||
|
122
sl_robot/run_cmnd.lua
Normal file
@ -0,0 +1,122 @@
|
||||
--[[
|
||||
|
||||
sl_robot
|
||||
========
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
run_cmnd.lua:
|
||||
|
||||
Register the run command
|
||||
|
||||
]]--
|
||||
|
||||
local function Reverse(arr)
|
||||
local i, j = 1, #arr
|
||||
|
||||
while i < j do
|
||||
arr[i], arr[j] = arr[j], arr[i]
|
||||
|
||||
i = i + 1
|
||||
j = j - 1
|
||||
end
|
||||
end
|
||||
|
||||
local switch = {
|
||||
f = function(cmnd)
|
||||
local num = (cmnd:byte(2) or 0x31) - 0x30
|
||||
print("forward("..num..")")
|
||||
end,
|
||||
b = function(cmnd)
|
||||
local num = (cmnd:byte(2) or 0x31) - 0x30
|
||||
print("backward("..num..")")
|
||||
end,
|
||||
l = function(cmnd, reverse)
|
||||
if reverse then
|
||||
print("right()")
|
||||
else
|
||||
print("left()")
|
||||
end
|
||||
end,
|
||||
r = function(cmnd, reverse)
|
||||
if reverse then
|
||||
print("left()")
|
||||
else
|
||||
print("right()")
|
||||
end
|
||||
end,
|
||||
u = function(cmnd)
|
||||
print("up()")
|
||||
end,
|
||||
d = function(cmnd)
|
||||
print("down()")
|
||||
end,
|
||||
t = function(cmnd)
|
||||
local num, slot
|
||||
if cmnd:sub(2,2) == "s" then
|
||||
num = 99
|
||||
slot = (cmnd:byte(3) or 0x31) - 0x30
|
||||
else
|
||||
num = 1
|
||||
slot = (cmnd:byte(2) or 0x31) - 0x30
|
||||
end
|
||||
print("take("..num..","..slot..")")
|
||||
end,
|
||||
a = function(cmnd)
|
||||
local num, slot
|
||||
if cmnd:sub(2,2) == "s" then
|
||||
num = 99
|
||||
slot = (cmnd:byte(3) or 0x31) - 0x30
|
||||
else
|
||||
num = 1
|
||||
slot = (cmnd:byte(2) or 0x31) - 0x30
|
||||
end
|
||||
print("add("..num..","..slot..")")
|
||||
end,
|
||||
p = function(cmnd)
|
||||
local num, slot
|
||||
if cmnd:sub(2,2) == "u" then
|
||||
slot = (cmnd:byte(3) or 0x31) - 0x30
|
||||
print("place("..slot..",U)")
|
||||
elseif cmnd:sub(2,2) == "d" then
|
||||
slot = (cmnd:byte(3) or 0x31) - 0x30
|
||||
print("place("..slot..",D)")
|
||||
else
|
||||
slot = (cmnd:byte(2) or 0x31) - 0x30
|
||||
print("place("..slot..")")
|
||||
end
|
||||
end,
|
||||
e = function(cmnd)
|
||||
print(cmnd.." is a invalid command")
|
||||
end,
|
||||
}
|
||||
|
||||
local function run(task, reverse)
|
||||
task = task:gsub("\n", " ")
|
||||
task = task:gsub("\t", " ")
|
||||
local cmnds = task:split(" ")
|
||||
if reverse then
|
||||
Reverse(cmnds)
|
||||
end
|
||||
for i,cmnd in ipairs(cmnds) do
|
||||
(switch[cmnd:sub(1,1)] or switch["e"])(cmnd, reverse)
|
||||
end
|
||||
end
|
||||
|
||||
sl_robot.register_action("run", {
|
||||
cmnd = function(self, sCmndList, reverse)
|
||||
sCmndList = sCmndList:gsub("\n", " ")
|
||||
sCmndList = sCmndList:gsub("\t", " ")
|
||||
local cmnds = sCmndList:split(" ")
|
||||
if reverse then
|
||||
Reverse(cmnds)
|
||||
end
|
||||
for i,cmnd in ipairs(cmnds) do
|
||||
(switch[cmnd:sub(1,1)] or switch["e"])(cmnd, reverse)
|
||||
end
|
||||
end,
|
||||
help = " "
|
||||
})
|
@ -19,4 +19,4 @@ dofile(minetest.get_modpath("tubelib_addons1") .. '/fermenter.lua')
|
||||
dofile(minetest.get_modpath("tubelib_addons1") .. '/reformer.lua')
|
||||
dofile(minetest.get_modpath("tubelib_addons1") .. '/funnel.lua')
|
||||
dofile(minetest.get_modpath("tubelib_addons1") .. "/pusher_fast.lua")
|
||||
dofile(minetest.get_modpath("tubelib_addons1") .. '/chest.lua')
|
||||
dofile(minetest.get_modpath("tubelib_addons1") .. '/chest.lua')
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 119 B |
Before Width: | Height: | Size: 423 B After Width: | Height: | Size: 400 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
137
tubelib_addons3/chest.lua
Normal file
@ -0,0 +1,137 @@
|
||||
--[[
|
||||
|
||||
Tubelib Addons 3
|
||||
================
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
chest.lua
|
||||
|
||||
A high performance chest
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
minetest.log("action", player:get_player_name().." moves "..stack:get_name()..
|
||||
" to chest at "..minetest.pos_to_string(pos))
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
minetest.log("action", player:get_player_name().." takes "..stack:get_name()..
|
||||
" from chest at "..minetest.pos_to_string(pos))
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function get_stack(meta, list)
|
||||
local inv = meta:get_inventory()
|
||||
local item = tubelib.get_item(meta, list)
|
||||
if item and inv:contains_item(list, item) then
|
||||
-- try to remove a complete stack
|
||||
item:set_count(98)
|
||||
local taken = inv:remove_item(list, item)
|
||||
-- add the already removed
|
||||
taken:set_count(taken:get_count() + 1)
|
||||
return taken
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
|
||||
local function formspec()
|
||||
return "size[12,10]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[context;main;0,0;12,6;]"..
|
||||
"list[current_player;main;2,6.3;8,4;]"..
|
||||
"listring[context;main]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
minetest.register_node("tubelib_addons3:chest", {
|
||||
description = "HighPerf Chest",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'tubelib_addons3_chest_bottom.png',
|
||||
'tubelib_addons3_chest_bottom.png',
|
||||
"tubelib_addons3_chest_side.png",
|
||||
"tubelib_addons3_chest_side.png",
|
||||
"tubelib_addons3_chest_side.png",
|
||||
"tubelib_addons3_chest_front.png",
|
||||
},
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('main', 72)
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", formspec())
|
||||
meta:set_string("infotext", "HighPerf Chest")
|
||||
end,
|
||||
|
||||
can_dig = function(pos,player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return false
|
||||
end
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main")
|
||||
end,
|
||||
|
||||
on_dig = function(pos, node, puncher, pointed_thing)
|
||||
minetest.node_dig(pos, node, puncher, pointed_thing)
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "tubelib_addons3:chest",
|
||||
recipe = {
|
||||
{"", "default:steel_ingot", ""},
|
||||
{"tubelib_addons1:chest", "default:gold_ingot", "tubelib_addons1:chest"},
|
||||
{"", "default:tin_ingot", ""},
|
||||
}
|
||||
})
|
||||
|
||||
tubelib.register_node("tubelib_addons3:chest", {}, {
|
||||
on_pull_item = function(pos, side)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return get_stack(meta, "main")
|
||||
end,
|
||||
on_push_item = function(pos, side, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
tubelib.put_item(meta, "main", item)
|
||||
end,
|
||||
on_unpull_item = function(pos, side, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return tubelib.put_item(meta, "main", item)
|
||||
end,
|
||||
|
||||
on_recv_message = function(pos, topic, payload)
|
||||
return "unsupported"
|
||||
end,
|
||||
})
|
3
tubelib_addons3/depends.txt
Normal file
@ -0,0 +1,3 @@
|
||||
tubelib
|
||||
tubelib_addons1
|
||||
default
|
2
tubelib_addons3/description.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Tubelib Extension with High Performance nodes
|
||||
|
491
tubelib_addons3/distributor.lua
Normal file
@ -0,0 +1,491 @@
|
||||
--[[
|
||||
|
||||
Tubelib Addons 3
|
||||
================
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
distributor.lua:
|
||||
|
||||
A high performance distributor
|
||||
]]--
|
||||
|
||||
local NUM_FILTER_ELEM = 6
|
||||
local NUM_FILTER_SLOTS = 4
|
||||
local TICKS_TO_SLEEP = 5
|
||||
local CYCLE_TIME = 2
|
||||
local STOP_STATE = 0
|
||||
local STANDBY_STATE = -1
|
||||
|
||||
-- Get one item-stack from the given ItemList, specified by stack number (1..n).
|
||||
-- Returns nil if ItemList is empty.
|
||||
local function get_this_stack(meta, listname, number)
|
||||
if meta == nil or meta.get_inventory == nil then return nil end
|
||||
local inv = meta:get_inventory()
|
||||
if inv:is_empty(listname) then
|
||||
return nil
|
||||
end
|
||||
|
||||
local items = inv:get_stack(listname, number)
|
||||
if items:get_count() > 0 then
|
||||
return inv:remove_item(listname, items)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Return a key/value table with all items and the corresponding stack numbers
|
||||
local function invlist_content_as_kvlist(list)
|
||||
local res = {}
|
||||
for idx,items in ipairs(list) do
|
||||
local name = items:get_name()
|
||||
if name ~= "" then
|
||||
res[name] = idx
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
-- Return the total number of list entries
|
||||
local function invlist_num_entries(list)
|
||||
local res = 0
|
||||
for _,items in ipairs(list) do
|
||||
local name = items:get_name()
|
||||
if name ~= "" then
|
||||
res = res + items:get_count()
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
-- Return a flat table with all items
|
||||
local function invlist_entries_as_list(list)
|
||||
local res = {}
|
||||
for _,items in ipairs(list) do
|
||||
local name = items:get_name()
|
||||
local count = items:get_count()
|
||||
if name ~= "" then
|
||||
for i = 1,count do
|
||||
res[#res+1] = name
|
||||
end
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
local function AddToTbl(kvTbl, new_items)
|
||||
for _, l in ipairs(new_items) do
|
||||
kvTbl[l] = true
|
||||
end
|
||||
return kvTbl
|
||||
end
|
||||
|
||||
|
||||
local function distributor_formspec(state, filter)
|
||||
return "size[10,8.5]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[context;src;0,0;2,4;]"..
|
||||
"image[2,1.5;1,1;tubelib_gui_arrow.png]"..
|
||||
"image_button[2,3;1,1;".. tubelib.state_button(state) ..";button;]"..
|
||||
"checkbox[3,0;filter1;On;"..dump(filter[1]).."]"..
|
||||
"checkbox[3,1;filter2;On;"..dump(filter[2]).."]"..
|
||||
"checkbox[3,2;filter3;On;"..dump(filter[3]).."]"..
|
||||
"checkbox[3,3;filter4;On;"..dump(filter[4]).."]"..
|
||||
"image[3.6,0;0.3,1;tubelib_red.png]"..
|
||||
"image[3.6,1;0.3,1;tubelib_green.png]"..
|
||||
"image[3.6,2;0.3,1;tubelib_blue.png]"..
|
||||
"image[3.6,3;0.3,1;tubelib_yellow.png]"..
|
||||
"list[context;red;4,0;6,1;]"..
|
||||
"list[context;green;4,1;6,1;]"..
|
||||
"list[context;blue;4,2;6,1;]"..
|
||||
"list[context;yellow;4,3;6,1;]"..
|
||||
"list[current_player;main;1,4.5;8,4;]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local list = inv:get_list(listname)
|
||||
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
if listname == "src" then
|
||||
return stack:get_count()
|
||||
elseif invlist_num_entries(list) < NUM_FILTER_ELEM then
|
||||
return 1
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local stack = inv:get_stack(from_list, from_index)
|
||||
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
|
||||
end
|
||||
|
||||
local SlotColors = {"red", "green", "blue", "yellow"}
|
||||
local Num2Ascii = {"B", "L", "F", "R"} -- color to side translation
|
||||
local FilterCache = {} -- local cache for filter settings
|
||||
|
||||
local function filter_settings(pos)
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
|
||||
local kvFilterItemNames = {} -- {<item:name> = true,...}
|
||||
local kvSide2ItemNames = {} -- {"F" = {<item:name>,...},...}
|
||||
|
||||
-- collect all filter settings
|
||||
for idx,slot in ipairs(SlotColors) do
|
||||
local side = Num2Ascii[idx]
|
||||
if filter[idx] == true then
|
||||
local list = inv:get_list(slot)
|
||||
local filter = invlist_entries_as_list(list)
|
||||
AddToTbl(kvFilterItemNames, filter)
|
||||
kvSide2ItemNames[side] = filter
|
||||
end
|
||||
end
|
||||
|
||||
FilterCache[hash] = {
|
||||
kvFilterItemNames = kvFilterItemNames,
|
||||
kvSide2ItemNames = kvSide2ItemNames
|
||||
}
|
||||
end
|
||||
|
||||
local function start_the_machine(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
meta:set_int("running", TICKS_TO_SLEEP)
|
||||
node.name = "tubelib_addons3:distributor_active"
|
||||
minetest.swap_node(pos, node)
|
||||
meta:set_string("infotext", "HighPerf Distributor "..number..": running")
|
||||
local filter = minetest.deserialize(meta:get_string("filter"))
|
||||
meta:set_string("formspec", distributor_formspec(tubelib.RUNNING, filter))
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
return false
|
||||
end
|
||||
|
||||
local function stop_the_machine(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
meta:set_int("running", STOP_STATE)
|
||||
node.name = "tubelib_addons3:distributor"
|
||||
minetest.swap_node(pos, node)
|
||||
meta:set_string("infotext", "HighPerf Distributor "..number..": stopped")
|
||||
local filter = minetest.deserialize(meta:get_string("filter"))
|
||||
meta:set_string("formspec", distributor_formspec(tubelib.STOPPED, filter))
|
||||
minetest.get_node_timer(pos):stop()
|
||||
return false
|
||||
end
|
||||
|
||||
local function goto_sleep(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
meta:set_int("running", STANDBY_STATE)
|
||||
node.name = "tubelib_addons3:distributor"
|
||||
minetest.swap_node(pos, node)
|
||||
meta:set_string("infotext", "HighPerf Distributor "..number..": standby")
|
||||
local filter = minetest.deserialize(meta:get_string("filter"))
|
||||
meta:set_string("formspec", distributor_formspec(tubelib.STANDBY, filter))
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME * TICKS_TO_SLEEP)
|
||||
return false
|
||||
end
|
||||
|
||||
-- move items to the output slots
|
||||
local function keep_running(pos, elapsed)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local running = meta:get_int("running") - 1
|
||||
local player_name = meta:get_string("player_name")
|
||||
--print("running", running)
|
||||
local slot_idx = meta:get_int("slot_idx") or 1
|
||||
meta:set_int("slot_idx", (slot_idx + 1) % NUM_FILTER_SLOTS)
|
||||
local side = Num2Ascii[slot_idx+1]
|
||||
local listname = SlotColors[slot_idx+1]
|
||||
local inv = meta:get_inventory()
|
||||
local list = inv:get_list("src")
|
||||
local kvSrc = invlist_content_as_kvlist(list)
|
||||
local counter = minetest.deserialize(meta:get_string("item_counter")) or
|
||||
{red=0, green=0, blue=0, yellow=0}
|
||||
|
||||
-- calculate the filter settings only once
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
if FilterCache[hash] == nil then
|
||||
filter_settings(pos)
|
||||
end
|
||||
|
||||
-- read data from Cache
|
||||
-- all filter items as key/value {<item:name> = true,...}
|
||||
local kvFilterItemNames = FilterCache[hash].kvFilterItemNames
|
||||
-- filter items of one slot as list {<item:name>,...}
|
||||
local names = FilterCache[hash].kvSide2ItemNames[side]
|
||||
|
||||
if names == nil then
|
||||
-- this slot is empty
|
||||
return true
|
||||
end
|
||||
|
||||
local busy = false
|
||||
-- move items from configured filters to the output
|
||||
if next(names) then
|
||||
for _,name in ipairs(names) do
|
||||
if kvSrc[name] then
|
||||
local item = get_this_stack(meta, "src", kvSrc[name])
|
||||
if item then
|
||||
if not tubelib.push_items(pos, side, item, player_name) then
|
||||
tubelib.put_item(meta, "src", item)
|
||||
else
|
||||
counter[listname] = counter[listname] + 1
|
||||
busy = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- move additional items from unconfigured filters to the output
|
||||
if next(names) == nil then
|
||||
for name,_ in pairs(kvSrc) do
|
||||
if kvFilterItemNames[name] == nil then -- not in the filter so far?
|
||||
local item = get_this_stack(meta, "src", kvSrc[name])
|
||||
if item then
|
||||
if not tubelib.push_items(pos, side, item, player_name) then
|
||||
tubelib.put_item(meta, "src", item)
|
||||
else
|
||||
counter[listname] = counter[listname] + 1
|
||||
busy = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if busy == true then
|
||||
if running <= 0 then
|
||||
return start_the_machine(pos)
|
||||
else
|
||||
running = TICKS_TO_SLEEP
|
||||
end
|
||||
else
|
||||
if running <= 0 then
|
||||
return goto_sleep(pos)
|
||||
end
|
||||
end
|
||||
|
||||
meta:set_string("item_counter", minetest.serialize(counter))
|
||||
meta:set_int("running", running)
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local running = meta:get_int("running")
|
||||
local filter = minetest.deserialize(meta:get_string("filter"))
|
||||
if fields.filter1 ~= nil then
|
||||
filter[1] = fields.filter1 == "true"
|
||||
elseif fields.filter2 ~= nil then
|
||||
filter[2] = fields.filter2 == "true"
|
||||
elseif fields.filter3 ~= nil then
|
||||
filter[3] = fields.filter3 == "true"
|
||||
elseif fields.filter4 ~= nil then
|
||||
filter[4] = fields.filter4 == "true"
|
||||
end
|
||||
meta:set_string("filter", minetest.serialize(filter))
|
||||
|
||||
filter_settings(pos)
|
||||
|
||||
if fields.button ~= nil then
|
||||
if running > STOP_STATE then
|
||||
stop_the_machine(pos)
|
||||
else
|
||||
start_the_machine(pos)
|
||||
end
|
||||
else
|
||||
meta:set_string("formspec", distributor_formspec(tubelib.state(running), filter))
|
||||
end
|
||||
end
|
||||
|
||||
-- tubelib command to turn on/off filter channels
|
||||
local function change_filter_settings(pos, slot, val)
|
||||
local slots = {["red"] = 1, ["green"] = 2, ["blue"] = 3, ["yellow"] = 4}
|
||||
local meta = minetest.get_meta(pos)
|
||||
local filter = minetest.deserialize(meta:get_string("filter"))
|
||||
local num = slots[slot] or 1
|
||||
if num >= 1 and num <= 4 then
|
||||
filter[num] = val == "on"
|
||||
end
|
||||
meta:set_string("filter", minetest.serialize(filter))
|
||||
|
||||
filter_settings(pos)
|
||||
|
||||
local running = meta:get_int("running")
|
||||
meta:set_string("formspec", distributor_formspec(tubelib.state(running), filter))
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_node("tubelib_addons3:distributor", {
|
||||
description = "HighPerf Distributor",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'tubelib_distributor.png^tubelib_addons3_node_frame.png',
|
||||
'tubelib_distributor.png^tubelib_addons3_node_frame.png',
|
||||
'tubelib_distributor_yellow.png^tubelib_addons3_node_frame.png',
|
||||
'tubelib_distributor_green.png^tubelib_addons3_node_frame.png',
|
||||
"tubelib_distributor_red.png^tubelib_addons3_node_frame.png",
|
||||
"tubelib_distributor_blue.png^tubelib_addons3_node_frame.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local number = tubelib.add_node(pos, "tubelib_addons3:distributor")
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("player_name", placer:get_player_name())
|
||||
|
||||
local filter = {false,false,false,false}
|
||||
meta:set_string("formspec", distributor_formspec(tubelib.STOPPED, filter))
|
||||
meta:set_string("filter", minetest.serialize(filter))
|
||||
meta:set_string("number", number)
|
||||
meta:set_string("infotext", "HighPerf Distributor "..number..": stopped")
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('src', 8)
|
||||
inv:set_size('yellow', 6)
|
||||
inv:set_size('green', 6)
|
||||
inv:set_size('red', 6)
|
||||
inv:set_size('blue', 6)
|
||||
meta:set_string("item_counter", minetest.serialize({red=0, green=0, blue=0, yellow=0}))
|
||||
end,
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
|
||||
on_dig = function(pos, node, puncher, pointed_thing)
|
||||
if minetest.is_protected(pos, puncher:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if inv:is_empty("src") then
|
||||
minetest.node_dig(pos, node, puncher, pointed_thing)
|
||||
tubelib.remove_node(pos)
|
||||
end
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
||||
|
||||
on_timer = keep_running,
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("tubelib_addons3:distributor_active", {
|
||||
description = "HighPerf Distributor",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
{
|
||||
image = "tubelib_addons3_distributor_active.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
'tubelib_distributor.png^tubelib_addons3_node_frame.png',
|
||||
'tubelib_distributor_yellow.png^tubelib_addons3_node_frame.png',
|
||||
'tubelib_distributor_green.png^tubelib_addons3_node_frame.png',
|
||||
"tubelib_distributor_red.png^tubelib_addons3_node_frame.png",
|
||||
"tubelib_distributor_blue.png^tubelib_addons3_node_frame.png",
|
||||
},
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
||||
|
||||
on_timer = keep_running,
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {crumbly=0, not_in_creative_inventory=1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "tubelib_addons3:distributor",
|
||||
recipe = {
|
||||
{"", "default:steel_ingot", ""},
|
||||
{"default:gold_ingot", "tubelib:distributor", "default:tin_ingot"},
|
||||
{"", "default:steel_ingot", ""},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
tubelib.register_node("tubelib_addons3:distributor", {"tubelib_addons3:distributor_active"}, {
|
||||
on_pull_item = function(pos, side)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return tubelib.get_item(meta, "src")
|
||||
end,
|
||||
on_push_item = function(pos, side, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return tubelib.put_item(meta, "src", item)
|
||||
end,
|
||||
on_unpull_item = function(pos, side, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return tubelib.put_item(meta, "src", item)
|
||||
end,
|
||||
on_recv_message = function(pos, topic, payload)
|
||||
if topic == "on" then
|
||||
return start_the_machine(pos)
|
||||
elseif topic == "off" then
|
||||
return stop_the_machine(pos)
|
||||
elseif topic == "state" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local running = meta:get_int("running")
|
||||
return tubelib.statestring(running)
|
||||
elseif topic == "filter" then
|
||||
return change_filter_settings(pos, payload.slot, payload.val)
|
||||
elseif topic == "counter" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
return minetest.deserialize(meta:get_string("item_counter")) or
|
||||
{red=0, green=0, blue=0, yellow=0}
|
||||
elseif topic == "clear_counter" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("item_counter", minetest.serialize({red=0, green=0, blue=0, yellow=0}))
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
})
|
15
tubelib_addons3/init.lua
Normal file
@ -0,0 +1,15 @@
|
||||
--[[
|
||||
|
||||
Tubelib Addons 3
|
||||
================
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
]]--
|
||||
|
||||
dofile(minetest.get_modpath("tubelib_addons3") .. '/pushing_chest.lua')
|
||||
dofile(minetest.get_modpath("tubelib_addons3") .. '/chest.lua')
|
||||
dofile(minetest.get_modpath("tubelib_addons3") .. '/distributor.lua')
|
1
tubelib_addons3/mod.conf
Normal file
@ -0,0 +1 @@
|
||||
name=tubelib_addons3
|
203
tubelib_addons3/pushing_chest.lua
Normal file
@ -0,0 +1,203 @@
|
||||
--[[
|
||||
|
||||
Tubelib Addons 3
|
||||
================
|
||||
|
||||
Copyright (C) 2017-2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
pushing_chest.lua
|
||||
|
||||
A high performance pushing chest
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
local Cache = {}
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
Cache[minetest.get_meta(pos):get_string("number")] = nil
|
||||
minetest.log("action", player:get_player_name().." moves "..stack:get_name()..
|
||||
" to chest at "..minetest.pos_to_string(pos))
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
Cache[minetest.get_meta(pos):get_string("number")] = nil
|
||||
minetest.log("action", player:get_player_name().." takes "..stack:get_name()..
|
||||
" from chest at "..minetest.pos_to_string(pos))
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
Cache[minetest.get_meta(pos):get_string("number")] = nil
|
||||
return count
|
||||
end
|
||||
|
||||
local function configured(pos, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local number = meta:get_string("number")
|
||||
if not Cache[number] then
|
||||
Cache[number] = {}
|
||||
for _,items in ipairs(inv:get_list("main")) do
|
||||
Cache[number][items:get_name()] = true
|
||||
end
|
||||
end
|
||||
return Cache[number][item:get_name()] == true
|
||||
end
|
||||
|
||||
local function shift_items(pos, elapsed)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("shift") then
|
||||
local number = meta:get_string("number")
|
||||
local player_name = meta:get_string("player_name")
|
||||
local offs = meta:get_int("offs")
|
||||
meta:set_int("offs", offs + 1)
|
||||
for i = 0,7 do
|
||||
local idx = ((i + offs) % 8) + 1
|
||||
local stack = inv:get_stack("shift", idx)
|
||||
if stack:get_count() > 0 then
|
||||
if tubelib.push_items(pos, "R", stack, player_name) then
|
||||
inv:set_stack("shift", idx, nil)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function formspec()
|
||||
return "size[9,9.2]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[context;shift;0.5,0;8,1;]"..
|
||||
"list[context;main;0.5,1.2;8,4;]"..
|
||||
"image[0.5,0;1,1;tubelib_gui_arrow.png]"..
|
||||
"image[7.5,0;1,1;tubelib_gui_arrow.png]"..
|
||||
"list[current_player;main;0.5,5.5;8,4;]"..
|
||||
"image[0.5,1.2;1,1;tubelib_gui_arrow.png^[transformR270]"..
|
||||
"listring[context;main]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
minetest.register_node("tubelib_addons3:pushing_chest", {
|
||||
description = "HighPerf Pushing Chest",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
{
|
||||
image = "tubelib_addons3_pushing_chest.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
'tubelib_addons3_chest_bottom.png',
|
||||
"tubelib_addons3_chest_out.png",
|
||||
"tubelib_addons3_chest_side.png",
|
||||
"tubelib_addons3_chest_side.png",
|
||||
"tubelib_addons3_chest_front.png",
|
||||
},
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('main', 32)
|
||||
inv:set_size('shift', 8)
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = tubelib.add_node(pos, "tubelib_addons3:pushing_chest")
|
||||
meta:set_string("player_name", placer:get_player_name())
|
||||
meta:set_string("number", number)
|
||||
meta:set_string("formspec", formspec())
|
||||
meta:set_string("infotext", "HighPerf Pushing Chest "..number)
|
||||
minetest.get_node_timer(pos):start(2)
|
||||
end,
|
||||
|
||||
can_dig = function(pos,player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return false
|
||||
end
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main") and inv:is_empty("shift")
|
||||
end,
|
||||
|
||||
on_dig = function(pos, node, puncher, pointed_thing)
|
||||
minetest.node_dig(pos, node, puncher, pointed_thing)
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
||||
|
||||
on_timer = shift_items,
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "tubelib_addons3:pushing_chest",
|
||||
recipe = {
|
||||
{ "", "default:tin_ingot", ""},
|
||||
{"default:chest", "default:gold_ingot", "tubelib:distributor"},
|
||||
{"", "default:steel_ingot", ""},
|
||||
}
|
||||
})
|
||||
|
||||
tubelib.register_node("tubelib_addons3:pushing_chest", {}, {
|
||||
on_pull_item = function(pos, side)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local item = tubelib.get_item(meta, "main")
|
||||
-- check if one remaining item is left
|
||||
if meta:get_inventory():contains_item("main", item) then
|
||||
return item
|
||||
else
|
||||
-- don't remove the last item (recipe)
|
||||
tubelib.put_item(meta, "main", item)
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
on_push_item = function(pos, side, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if configured(pos, item) then
|
||||
return tubelib.put_item(meta, "main", item)
|
||||
else
|
||||
return tubelib.put_item(meta, "shift", item)
|
||||
end
|
||||
end,
|
||||
on_unpull_item = function(pos, side, item)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return tubelib.put_item(meta, "main", item)
|
||||
end,
|
||||
|
||||
on_recv_message = function(pos, topic, payload)
|
||||
return "unsupported"
|
||||
end,
|
||||
})
|
BIN
tubelib_addons3/textures/tubelib_addons3_chest_bottom.png
Normal file
After Width: | Height: | Size: 752 B |
BIN
tubelib_addons3/textures/tubelib_addons3_chest_front.png
Normal file
After Width: | Height: | Size: 737 B |
BIN
tubelib_addons3/textures/tubelib_addons3_chest_out.png
Normal file
After Width: | Height: | Size: 585 B |
BIN
tubelib_addons3/textures/tubelib_addons3_chest_side.png
Normal file
After Width: | Height: | Size: 485 B |
BIN
tubelib_addons3/textures/tubelib_addons3_distributor_active.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
tubelib_addons3/textures/tubelib_addons3_node_frame.png
Normal file
After Width: | Height: | Size: 962 B |
BIN
tubelib_addons3/textures/tubelib_addons3_pushing_chest.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
tubelib_addons3/textures/tubelib_addons3_stack_chest_front.png
Normal file
After Width: | Height: | Size: 500 B |
BIN
tubelib_addons3/textures/tubelib_addons3_stack_chest_side.png
Normal file
After Width: | Height: | Size: 484 B |