distrubutor added

master
Joachim Stolberg 2017-09-08 21:59:48 +02:00
parent 20c09063cc
commit dd602335c4
17 changed files with 324 additions and 32 deletions

View File

@ -70,7 +70,7 @@ minetest.register_node("tubelib:button", {
end,
on_receive_fields = function(pos, formname, fields, player)
if tubelib.check_number(fields.number) then
if tubelib.check_numbers(fields.number) then
print(fields.number)
local meta = minetest.get_meta(pos)
meta:set_string("number", fields.number)
@ -80,7 +80,7 @@ minetest.register_node("tubelib:button", {
end,
on_rightclick = function(pos, node, clicker)
switch_on(pos, node, clicker:get_player_name())
switch_on(pos, node, nil)
end,
paramtype2 = "facedir",

View File

@ -44,9 +44,17 @@ function tubelib.get_server(dest_num)
end
-- Return true if number is known
function tubelib.check_number(number)
return Number2Pos[number] ~= nil
-- Return true if number(s) is/are known
function tubelib.check_numbers(numbers)
if numbers then
for _,num in ipairs(string.split(numbers, " ")) do
if Number2Pos[num] == nil then
return false
end
end
return true
end
return false
end
@ -55,6 +63,7 @@ end
-------------------------------------------------------------------
-- Add server node position to the tubelib data base
-- Function returns the assigned number for communication.
function tubelib.add_server_node(pos, name, placer)
local number = get_number(pos)
Number2Pos[number] = {
@ -76,22 +85,22 @@ end
-- Send function
-------------------------------------------------------------------
-- Send a command to all blocks referenced by 'destinations', a list of one or more numbers
-- separated by blanks. The command includes the topic string (e.g. "start") and
-- Send a command to all blocks referenced by 'numbers', a list of
-- one or more destination addressses separated by blanks.
-- The command is based on the topic string (e.g. "start") and
-- topic related payload.
-- The player_name is needed to check the protection rights. If player is unknown
-- use nil instead.
function tubelib.send_cmnd(destinations, player_name, topic, payload)
for _,num in ipairs(string.split(destinations, " ")) do
function tubelib.send_cmnd(numbers, player_name, topic, payload)
for _,num in ipairs(string.split(numbers, " ")) do
if Number2Pos[num] then
local data = Number2Pos[num]
if player_name == nil or not minetest.is_protected(data.pos, player_name) then
if tubelib.ReceiveFunction[data.name] then
return tubelib.ReceiveFunction[data.name](data.pos, topic, payload)
tubelib.ReceiveFunction[data.name](data.pos, topic, payload)
end
end
end
end
return false
end

283
distributor.lua Normal file
View File

@ -0,0 +1,283 @@
--[[
Tube Library
============
Copyright (C) 2017 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
History:
see init.lua
]]--
local function distributor_formspec(running)
return "size[8,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;gui_furnace_arrow_bg.png^[transformR270]"..
"button_exit[2,3;1,1;button;OK]"..
"checkbox[3,0;running1;On;"..dump(running[1]).."]"..
"checkbox[3,1;running2;On;"..dump(running[2]).."]"..
"checkbox[3,2;running3;On;"..dump(running[3]).."]"..
"checkbox[3,3;running4;On;"..dump(running[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;4,1;]"..
"list[context;green;4,1;4,1;]"..
"list[context;blue;4,2;4,1;]"..
"list[context;yellow;4,3;4,1;]"..
"list[current_player;main;0,4.5;8,4;]"..
"listring[context;src]"..
"listring[current_player;main]"
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "src" then
return stack:get_count()
else
return 1
end
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 filter_settings(meta)
local inv = meta:get_inventory()
local red = inv:get_list("red")
local green = inv:get_list("green")
local blue = inv:get_list("blue")
local yellow = inv:get_list("yellow")
local filter = {{},{},{},{}}
for idx,itemlist in ipairs({red, green, blue, yellow}) do
for _,items in ipairs(itemlist) do
if items:get_count() == 1 then
filter[idx][#filter[idx]+1] = items:get_name()
end
end
end
meta:set_string("filter", minetest.serialize(filter))
end
local function get_next_side(meta, item_name, filter)
local running = minetest.deserialize(meta:get_string("running"))
local side = meta:get_int("side") or 0
local num2asc = {"F", "L", "B", "R"}
meta:set_int("side", (side + 1) % 4)
local i, idx
for i = 1,4 do
idx = ((i + side) % 4) + 1
if running[idx] == true then
for _,name in ipairs(filter[idx]) do
if name == item_name then
print(meta:get_string("running"), idx, num2asc[idx])
return num2asc[idx]
end
end
end
end
for i = 1,4 do
idx = ((i + side) % 4) + 1
if running[idx] == true then
if #filter[idx] == 0 then
print(meta:get_string("running"), idx, num2asc[idx])
return num2asc[idx]
end
end
end
return nil
end
local function start_the_machine(pos)
local node = minetest.get_node(pos)
if node.name ~= "tubelib:distributor_active" then
node.name = "tubelib:distributor_active"
minetest.swap_node(pos, node)
end
minetest.get_node_timer(pos):start(2)
local meta = minetest.get_meta(pos)
local number = meta:get_string("number")
meta:set_string("infotext", "Tubelib Distributor "..number..": running")
end
local function stop_the_machine(pos)
local node = minetest.get_node(pos)
if node.name ~= "tubelib:distributor" then
node.name = "tubelib:distributor"
minetest.swap_node(pos, node)
minetest.get_node_timer(pos):stop()
end
local meta = minetest.get_meta(pos)
local number = meta:get_string("number")
meta:set_string("infotext", "Tubelib Distributor "..number..": stopped")
end
local function command_reception(pos, topic, payload)
if string.match(topic, "start") then
return start_the_machine(pos)
elseif string.match(topic, "stop") then
return stop_the_machine(pos)
else
return false
end
end
local function keep_running(pos, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local filter = minetest.deserialize(meta:get_string("filter"))
local item = tubelib.get_item(inv, "src")
local facedir = meta:get_int("facedir")
if item then
local side = get_next_side(meta, item:get_name(), filter)
print(side)
if side then
if tubelib.push_items(pos, facedir, side, item) then
return true
end
end
-- put item back to inventory
tubelib.put_item(inv, "src", item)
end
return true
end
local function on_receive_fields(pos, formname, fields, player)
local meta = minetest.get_meta(pos)
print(meta:get_string("running"))
local running = minetest.deserialize(meta:get_string("running"))
if fields.running1 ~= nil then
running[1] = fields.running1 == "true"
elseif fields.running2 ~= nil then
running[2] = fields.running2 == "true"
elseif fields.running3 ~= nil then
running[3] = fields.running3 == "true"
elseif fields.running4 ~= nil then
running[4] = fields.running4 == "true"
end
meta:set_string("running", minetest.serialize(running))
meta:set_string("formspec", distributor_formspec(running))
if fields.button ~= nil then
if running[1] or running[2] or running[3] or running[4] then
filter_settings(meta)
start_the_machine(pos)
else
stop_the_machine(pos)
end
end
end
minetest.register_node("tubelib:distributor", {
description = "Tubelib Distributor",
tiles = {
-- up, down, right, left, back, front
'tubelib_distributor.png',
'tubelib_distributor.png',
'tubelib_distributor_yellow.png',
'tubelib_distributor_green.png',
"tubelib_distributor_red.png",
"tubelib_distributor_blue.png",
},
after_place_node = function(pos, placer)
local number = tubelib.add_server_node(pos, "tubelib:distributor", placer)
local meta = minetest.get_meta(pos)
local facedir = minetest.dir_to_facedir(placer:get_look_dir(), false)
local running = {false,false,false,false}
meta:set_string("infotext", "Tubelib Distributor "..number..": stopped")
meta:set_string("formspec", distributor_formspec(running))
meta:set_string("running", minetest.serialize(running))
meta:set_string("number", number)
meta:set_int("facedir", facedir)
local inv = meta:get_inventory()
inv:set_size('src', 8)
inv:set_size('yellow', 4)
inv:set_size('green', 4)
inv:set_size('red', 4)
inv:set_size('blue', 4)
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)
end
end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
paramtype2 = "facedir",
groups = {cracky=1},
is_ground_content = false,
})
minetest.register_node("tubelib:distributor_active", {
description = "Tubelib Distributor",
tiles = {
-- up, down, right, left, back, front
{
image = "tubelib_distributor_active.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 2.0,
},
},
'tubelib_distributor.png',
'tubelib_distributor_yellow.png',
'tubelib_distributor_green.png',
"tubelib_distributor_red.png",
"tubelib_distributor_blue.png",
},
on_receive_fields = on_receive_fields,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
on_timer = keep_running,
paramtype2 = "facedir",
groups = {crumbly=0, not_in_creative_inventory=1},
is_ground_content = false,
})
local function get_items(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return tubelib.get_item(inv, "src")
end
local function put_items(pos, items)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return tubelib.put_item(inv, "src", items)
end
tubelib.register_receive_function("tubelib:distributor", command_reception)
tubelib.register_item_functions("tubelib:distributor", put_items, get_items)
tubelib.register_item_functions("tubelib:distributor_active", put_items, get_items)

View File

@ -89,10 +89,11 @@ end
-- Registration functions
-------------------------------------------------------------------
-- Register node name for tube push/pull calls
-- Register functions for tube pushing/pulling
-- Call this function only at load time!
function tubelib.register_node_name(name)
function tubelib.register_item_functions(name, push_clbk, pull_clbk)
tubelib.knownNodes[name] = true
tubelib.NodeTypes[name] = {push_clbk = push_clbk, pull_clbk = pull_clbk}
end
-------------------------------------------------------------------
@ -167,4 +168,4 @@ dofile(minetest.get_modpath("tubelib") .. "/command.lua")
dofile(minetest.get_modpath("tubelib") .. "/button.lua")
dofile(minetest.get_modpath("tubelib") .. "/lamp.lua")
dofile(minetest.get_modpath("tubelib") .. "/pusher.lua")
dofile(minetest.get_modpath("tubelib") .. "/distributor.lua")

View File

@ -16,23 +16,19 @@
local function switch_on(pos, node)
node.name = "tubelib:lamp_on"
minetest.swap_node(pos, node)
return true
end
local function switch_off(pos, node)
node.name = "tubelib:lamp"
minetest.swap_node(pos, node)
return true
end
local function command_reception(pos, topic, payload)
local node = minetest.get_node(pos)
if string.match(topic, "start") then
return switch_on(pos, node)
switch_on(pos, node)
elseif string.match(topic, "stop") then
return switch_off(pos, node)
else
return false
switch_off(pos, node)
end
end

View File

@ -160,5 +160,5 @@ minetest.register_node("tubelib:pusher_active", {
})
tubelib.register_receive_function("tubelib:pusher", command_reception)
tubelib.register_node_name("tubelib:pusher")
tubelib.register_node_name("tubelib:pusher_active")
tubelib.register_item_functions("tubelib:pusher", nil, nil)
tubelib.register_item_functions("tubelib:pusher_active", nil, nil)

BIN
textures/tubelib_blue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
textures/tubelib_green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

BIN
textures/tubelib_red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

BIN
textures/tubelib_yellow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

View File

@ -124,23 +124,26 @@ local function walk_to_peer(pos, pos1)
cnt = cnt + 1
node = minetest.get_node(pos1)
end
return pos, pos1
return cnt, pos, pos1
end
local function update_head_tubes(pos)
local node = minetest.get_node(pos)
if string.find(node.name, "tubelib:tube") then
local pos1, pos2 = nodetype_to_pos(nil, pos, node)
local peer1, dest1 = walk_to_peer(pos, pos1)
local peer2, dest2 = walk_to_peer(pos, pos2)
local cnt1, peer1, dest1 = walk_to_peer(pos, pos1)
local cnt2, peer2, dest2 = walk_to_peer(pos, pos2)
print(cnt1, cnt2)
minetest.get_meta(peer1):set_string("dest_pos", minetest.pos_to_string(dest2))
minetest.get_meta(peer2):set_string("dest_pos", minetest.pos_to_string(dest1))
minetest.get_meta(pos1):set_string("dest_pos", nil)
minetest.get_meta(pos2):set_string("dest_pos", nil)
if tubelib.debug then
minetest.get_meta(peer1):set_string("infotext", minetest.pos_to_string(dest2))
minetest.get_meta(peer2):set_string("infotext", minetest.pos_to_string(dest1))
minetest.get_meta(peer1):set_string("infotext", minetest.pos_to_string(dest2))
minetest.get_meta(peer2):set_string("infotext", minetest.pos_to_string(dest1))
if cnt1 < 1 then
minetest.get_meta(pos1):set_string("dest_pos", nil)
minetest.get_meta(pos1):set_string("infotext", nil)
end
if cnt2 < 1 then
minetest.get_meta(pos2):set_string("dest_pos", nil)
minetest.get_meta(pos2):set_string("infotext", nil)
end
end
@ -159,8 +162,8 @@ end
local function after_tube_removed(pos, node)
local pos1, pos2 = nodetype_to_pos(nil, pos, node)
local peer1, dest1 = walk_to_peer(pos, pos1)
local peer2, dest2 = walk_to_peer(pos, pos2)
local cnt1, peer1, dest1 = walk_to_peer(pos, pos1)
local cnt2, peer2, dest2 = walk_to_peer(pos, pos2)
minetest.get_meta(peer1):set_string("dest_pos", minetest.pos_to_string(pos))
minetest.get_meta(peer2):set_string("dest_pos", minetest.pos_to_string(pos))
minetest.get_meta(pos1):set_string("dest_pos", minetest.pos_to_string(dest1))