Add files via upload
This commit is contained in:
3
change.log
Normal file
3
change.log
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
v 0.1.0
|
||||||
|
* initial release
|
536
collector.lua
Normal file
536
collector.lua
Normal file
@@ -0,0 +1,536 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local collect_interval = 0.5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function send_collect_message (pos, name, count)
|
||||||
|
if utils.digilines_supported then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if channel:len () > 0 then
|
||||||
|
utils.digilines_receptor_send (pos,
|
||||||
|
digiline.rules.default,
|
||||||
|
channel,
|
||||||
|
{ action = "collect",
|
||||||
|
name = name,
|
||||||
|
count = count })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function filter_item (pos, item)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv:is_empty ("filter") then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local slots = inv:get_size ("filter")
|
||||||
|
for i = 1, slots do
|
||||||
|
local stack = inv:get_stack ("filter", i)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () and
|
||||||
|
stack:get_name () == item then
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function get_form_spec (is_off)
|
||||||
|
return
|
||||||
|
"formspec_version[3]\n"..
|
||||||
|
"size[11.75,13.75;true]\n"..
|
||||||
|
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
|
||||||
|
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
|
||||||
|
"button[8.25,1.0;2.5,0.8;"..((is_off and "start;Start") or "stop;Stop").."]\n"..
|
||||||
|
"list[context;filter;8.5,2.5;2,4;]\n"..
|
||||||
|
"list[context;main;1.0,2.5;4,4;]\n"..
|
||||||
|
"list[current_player;main;1.0,8.0;8,4;]\n"..
|
||||||
|
"listring[]"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function start_collector (pos)
|
||||||
|
local node = minetest.get_node (pos)
|
||||||
|
|
||||||
|
if node then
|
||||||
|
if node.name == "lwcomponents:collector" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:collector_on"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):start (collect_interval)
|
||||||
|
|
||||||
|
meta:set_string ("formspec", get_form_spec (false))
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif node.name == "lwcomponents:collector_locked" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:collector_locked_on"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):start (collect_interval)
|
||||||
|
|
||||||
|
meta:set_string ("formspec", get_form_spec (false))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function stop_collector (pos)
|
||||||
|
local node = minetest.get_node (pos)
|
||||||
|
|
||||||
|
if node then
|
||||||
|
if node.name == "lwcomponents:collector_on" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:collector"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):stop ()
|
||||||
|
|
||||||
|
meta:set_string ("formspec", get_form_spec (true))
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif node.name == "lwcomponents:collector_locked_on" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:collector_locked"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):stop ()
|
||||||
|
|
||||||
|
meta:set_string ("formspec", get_form_spec (true))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_destruct (pos)
|
||||||
|
minetest.get_node_timer (pos):stop ()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
local is_off = itemstack and (itemstack:get_name () == "lwcomponents:collector" or
|
||||||
|
itemstack:get_name () == "lwcomponents:collector_locked")
|
||||||
|
|
||||||
|
meta:set_string ("inventory", "{ main = { }, filter = { } }")
|
||||||
|
meta:set_string ("formspec", get_form_spec (is_off))
|
||||||
|
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
inv:set_size ("main", 16)
|
||||||
|
inv:set_width ("main", 4)
|
||||||
|
inv:set_size ("filter", 8)
|
||||||
|
inv:set_width ("filter", 2)
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
|
||||||
|
after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
|
||||||
|
if placer and placer:is_player () then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
meta:set_string ("owner", placer:get_player_name ())
|
||||||
|
meta:set_string ("infotext", "Collector (owned by "..placer:get_player_name ()..")")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_receive_fields (pos, formname, fields, sender)
|
||||||
|
if not utils.can_interact_with_node (pos, sender) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.setchannel then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("channel", fields.channel)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif fields.start then
|
||||||
|
start_collector (pos)
|
||||||
|
|
||||||
|
elseif fields.stop then
|
||||||
|
stop_collector (pos)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function can_dig (pos, player)
|
||||||
|
if not utils.can_interact_with_node (pos, player) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
if not inv:is_empty ("main") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if not inv:is_empty ("filter") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_blast (pos, intensity)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
if intensity >= 1.0 then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
if math.floor (math.random (0, 5)) == 3 then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
else
|
||||||
|
utils.on_destroy (stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
slots = inv:get_size ("filter")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("filter", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
if math.floor (math.random (0, 5)) == 3 then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
else
|
||||||
|
utils.on_destroy (stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
on_destruct (pos)
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
|
||||||
|
else -- intensity < 1.0
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
slots = inv:get_size ("filter")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("filter", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local node = minetest.get_node_or_nil (pos)
|
||||||
|
if node then
|
||||||
|
local items = minetest.get_node_drops (node, nil)
|
||||||
|
|
||||||
|
if items and #items > 0 then
|
||||||
|
local stack = ItemStack (items[1])
|
||||||
|
|
||||||
|
if stack then
|
||||||
|
preserve_metadata (pos, node, meta, { stack })
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
on_destruct (pos)
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
|
||||||
|
if not utils.can_interact_with_node (pos, clicker) then
|
||||||
|
if clicker and clicker:is_player () then
|
||||||
|
local owner = "<unknown>"
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
owner = meta:get_string ("owner")
|
||||||
|
end
|
||||||
|
|
||||||
|
local spec =
|
||||||
|
"formspec_version[3]"..
|
||||||
|
"size[8.0,4.0,false]"..
|
||||||
|
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
|
||||||
|
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
|
||||||
|
|
||||||
|
minetest.show_formspec (clicker:get_player_name (),
|
||||||
|
"lwcomponents:component_privately_owned",
|
||||||
|
spec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_timer (pos, elapsed)
|
||||||
|
local list = minetest.get_objects_inside_radius (pos, 2)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
for i = 1, #list do
|
||||||
|
if list[i].get_luaentity and list[i]:get_luaentity () and
|
||||||
|
list[i]:get_luaentity ().name and
|
||||||
|
list[i]:get_luaentity ().name == "__builtin:item" then
|
||||||
|
|
||||||
|
local stack = utils.item_pickup (list[i]:get_luaentity (), false)
|
||||||
|
|
||||||
|
if stack and inv:room_for_item ("main", stack) and
|
||||||
|
filter_item (pos, stack:get_name ()) then
|
||||||
|
|
||||||
|
local name = stack:get_name ()
|
||||||
|
local count = stack:get_count ()
|
||||||
|
|
||||||
|
inv:add_item ("main", stack)
|
||||||
|
utils.item_pickup (list[i]:get_luaentity ())
|
||||||
|
|
||||||
|
send_collect_message (pos, name, count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function digilines_support ()
|
||||||
|
if utils.digilines_supported then
|
||||||
|
return
|
||||||
|
{
|
||||||
|
wire =
|
||||||
|
{
|
||||||
|
rules = digiline.rules.default,
|
||||||
|
},
|
||||||
|
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
action = function (pos, node, channel, msg)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local this_channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if this_channel == channel then
|
||||||
|
local m = { }
|
||||||
|
for w in string.gmatch(msg, "[^%s]+") do
|
||||||
|
m[#m + 1] = w
|
||||||
|
end
|
||||||
|
|
||||||
|
if m[1] == "start" then
|
||||||
|
start_collector (pos)
|
||||||
|
|
||||||
|
elseif m[1] == "stop" then
|
||||||
|
stop_collector (pos)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:collector", {
|
||||||
|
description = S("Collector"),
|
||||||
|
tiles = { "lwcollector.png", "lwcollector.png", "lwcollector.png",
|
||||||
|
"lwcollector.png", "lwcollector.png", "lwcollector.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:collector",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:collector_locked", {
|
||||||
|
description = S("Collector (locked)"),
|
||||||
|
tiles = { "lwcollector.png", "lwcollector.png", "lwcollector.png",
|
||||||
|
"lwcollector.png", "lwcollector.png", "lwcollector.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:collector_locked",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node_locked,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:collector_on", {
|
||||||
|
description = S("Collector"),
|
||||||
|
tiles = { "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png",
|
||||||
|
"lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3, not_in_creative_inventory = 1 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:collector",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:collector_locked_on", {
|
||||||
|
description = S("Collector (locked)"),
|
||||||
|
tiles = { "lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png",
|
||||||
|
"lwcollector_on.png", "lwcollector_on.png", "lwcollector_on.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3, not_in_creative_inventory = 1 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:collector_locked",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node_locked,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end -- utils.digilines_supported
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
141
crafting.lua
Normal file
141
crafting.lua
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported or utils.mesecon_supported then
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:dropper",
|
||||||
|
recipe = {
|
||||||
|
{ "default:stone", "default:chest" },
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:dropper_locked",
|
||||||
|
recipe = {
|
||||||
|
{ "default:stone", "default:chest_locked" },
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:dispenser",
|
||||||
|
recipe = {
|
||||||
|
{ "default:chest", "default:stone" },
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:dispenser_locked",
|
||||||
|
recipe = {
|
||||||
|
{ "default:chest_locked", "default:stone" },
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:detector",
|
||||||
|
recipe = {
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
{ "default:stone", "default:chest" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:detector_locked",
|
||||||
|
recipe = {
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
{ "default:stone", "default:chest_locked" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
end -- utils.digilines_supported or utils.mesecon_supported
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported then
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:collector",
|
||||||
|
recipe = {
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
{ "default:chest", "default:stone" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft( {
|
||||||
|
output = "lwcomponents:collector_locked",
|
||||||
|
recipe = {
|
||||||
|
{ "default:copper_ingot", "default:steel_ingot" },
|
||||||
|
{ "default:chest_locked", "default:stone" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
end -- utils.digilines_supported
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.mesecon_supported and mesecon.mvps_push then
|
||||||
|
|
||||||
|
minetest.register_craft ({
|
||||||
|
output = "lwcomponents:movefloor",
|
||||||
|
recipe = {
|
||||||
|
{ "default:stick", "default:stick", "default:stick" },
|
||||||
|
{ "default:stick", "default:steel_ingot", "default:stick" },
|
||||||
|
{ "default:stick", "default:stick", "default:stick" },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
end -- utils.mesecon_supported and mesecon.mvps_push
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported and utils.mesecon_supported then
|
||||||
|
|
||||||
|
minetest.register_craft ({
|
||||||
|
output = "lwcomponents:digiswitch 2",
|
||||||
|
recipe = {
|
||||||
|
{ "default:stone", "default:stone" },
|
||||||
|
{ "default:copper_ingot", "default:mese_crystal_fragment" },
|
||||||
|
{ "default:stick", "default:stick" },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
end -- utils.digilines_supported and utils.mesecon_supported
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then
|
||||||
|
|
||||||
|
minetest.register_craft ({
|
||||||
|
output = "lwcomputers:solid_conductor_off 3",
|
||||||
|
recipe = {
|
||||||
|
{ "default:mese_crystal_fragment", "group:wood", ""},
|
||||||
|
{ "group:wood", "group:wood", "dye:white" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft ({
|
||||||
|
output = "lwcomputers:solid_horizontal_conductor_off 3",
|
||||||
|
recipe = {
|
||||||
|
{ "group:wood", "group:wood", ""},
|
||||||
|
{ "default:mese_crystal_fragment", "group:wood", "dye:white" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
end -- utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
6
depends.txt
Normal file
6
depends.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
default
|
||||||
|
lwdrops?
|
||||||
|
mesecons?
|
||||||
|
digilines?
|
||||||
|
unifieddyes?
|
||||||
|
intllib?
|
1
description.txt
Normal file
1
description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Various components for mesecons and digilines.
|
782
detector.lua
Normal file
782
detector.lua
Normal file
@@ -0,0 +1,782 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported or utils.mesecon_supported then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local detect_interval = 0.5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function mesecons_on (pos)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
if meta:get_int ("power_on") == 0 then
|
||||||
|
utils.mesecon_receptor_on (pos, utils.mesecon_default_rules)
|
||||||
|
meta:set_int ("power_on", 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function mesecons_off (pos)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
if meta:get_int ("power_on") ~= 0 then
|
||||||
|
utils.mesecon_receptor_off (pos, utils.mesecon_default_rules)
|
||||||
|
meta:set_int ("power_on", 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function to_relative_coords (pos, testpos)
|
||||||
|
local base = { x = testpos.x - pos.x,
|
||||||
|
y = testpos.y - pos.y,
|
||||||
|
z = testpos.z - pos.z }
|
||||||
|
local node = minetest.get_node (pos)
|
||||||
|
|
||||||
|
if node then
|
||||||
|
if node.param2 == 3 then -- +x
|
||||||
|
return { x = (base.z * -1), y = base.y, z = base.x }
|
||||||
|
elseif node.param2 == 0 then -- -z
|
||||||
|
return { x = (base.x * -1), y = base.y, z = (base.z * -1) }
|
||||||
|
elseif node.param2 == 1 then -- -x
|
||||||
|
return { x = base.z, y = base.y, z = (base.x * -1) }
|
||||||
|
elseif node.param2 == 2 then -- +z
|
||||||
|
return { x = base.x, y = base.y, z = base.z }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return { x = 0, y = 0, z = 0 }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function send_detect_message (pos, item_type, name, label, item_pos, count)
|
||||||
|
if utils.digilines_supported then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if channel:len () > 0 then
|
||||||
|
utils.digilines_receptor_send (pos,
|
||||||
|
digiline.rules.default,
|
||||||
|
channel,
|
||||||
|
{ action = "detect",
|
||||||
|
type = item_type,
|
||||||
|
name = name,
|
||||||
|
label = label,
|
||||||
|
pos = to_relative_coords (pos, item_pos),
|
||||||
|
count = count })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function filter_item (pos, mode, testpos)
|
||||||
|
local base = { x = math.floor (testpos.x - pos.x + 0.5),
|
||||||
|
y = math.floor (testpos.y - pos.y + 0.5),
|
||||||
|
z = math.floor (testpos.z - pos.z + 0.5) }
|
||||||
|
|
||||||
|
if base.x == 0 and base.y == 0 and base.z == 0 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if mode == 1 then
|
||||||
|
-- all
|
||||||
|
return true
|
||||||
|
|
||||||
|
elseif mode == 2 then
|
||||||
|
-- forward
|
||||||
|
local node = minetest.get_node (pos)
|
||||||
|
|
||||||
|
if node then
|
||||||
|
if node.param2 == 0 then
|
||||||
|
-- -z
|
||||||
|
return (base.x == 0 and base.y == 0 and base.z < 0)
|
||||||
|
elseif node.param2 == 1 then
|
||||||
|
-- -x
|
||||||
|
return (base.x < 0 and base.y == 0 and base.z == 0)
|
||||||
|
elseif node.param2 == 2 then
|
||||||
|
-- +z
|
||||||
|
return (base.x == 0 and base.y == 0 and base.z > 0)
|
||||||
|
elseif node.param2 == 3 then
|
||||||
|
-- +x
|
||||||
|
return (base.x > 0 and base.y == 0 and base.z == 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif mode == 3 then
|
||||||
|
-- up
|
||||||
|
return (base.x == 0 and base.z == 0 and base.y > 0)
|
||||||
|
|
||||||
|
elseif mode == 4 then
|
||||||
|
-- down
|
||||||
|
return (base.x == 0 and base.z == 0 and base.y < 0)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function detect (pos)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
local detected = false
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local radius = meta:get_int ("radius")
|
||||||
|
local mode = meta:get_int ("mode")
|
||||||
|
local object = minetest.get_objects_inside_radius (pos, radius + 0.5)
|
||||||
|
|
||||||
|
for i = 1, #object do
|
||||||
|
if object[i]:is_player () then
|
||||||
|
|
||||||
|
-- player
|
||||||
|
if meta:get_string ("players") == "true" and
|
||||||
|
filter_item (pos, mode, object[i]:get_pos ()) then
|
||||||
|
|
||||||
|
send_detect_message (pos,
|
||||||
|
"player",
|
||||||
|
object[i]:get_player_name (),
|
||||||
|
object[i]:get_player_name (),
|
||||||
|
object[i]:get_pos (),
|
||||||
|
1)
|
||||||
|
|
||||||
|
detected = true
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif object[i].get_luaentity and object[i]:get_luaentity () and
|
||||||
|
object[i]:get_luaentity ().name and
|
||||||
|
object[i]:get_luaentity ().name == "__builtin:item" then
|
||||||
|
|
||||||
|
-- drop
|
||||||
|
if meta:get_string ("drops") == "true" and
|
||||||
|
filter_item (pos, mode, object[i]:get_pos ()) then
|
||||||
|
|
||||||
|
local stack = ItemStack (object[i]:get_luaentity ().itemstring or "")
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
send_detect_message (pos,
|
||||||
|
"drop",
|
||||||
|
stack:get_name (),
|
||||||
|
stack:get_name (),
|
||||||
|
object[i]:get_pos (),
|
||||||
|
stack:get_count ())
|
||||||
|
|
||||||
|
detected = true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif object[i].get_pos and object[i]:get_pos () then
|
||||||
|
|
||||||
|
-- entity
|
||||||
|
if meta:get_string ("entities") == "true" and
|
||||||
|
filter_item (pos, mode, object[i]:get_pos ()) then
|
||||||
|
|
||||||
|
local name = object[i]:get_nametag_attributes ()
|
||||||
|
local label = ""
|
||||||
|
|
||||||
|
if type (name) == "table" then
|
||||||
|
label = tostring (name.text or "")
|
||||||
|
end
|
||||||
|
|
||||||
|
name = (object[i].get_luaentity and
|
||||||
|
object[i]:get_luaentity () and
|
||||||
|
object[i]:get_luaentity ().name) or ""
|
||||||
|
|
||||||
|
send_detect_message (pos,
|
||||||
|
"entity",
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
object[i]:get_pos (),
|
||||||
|
1)
|
||||||
|
|
||||||
|
detected = true
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if meta:get_string ("nodes") == "true" then
|
||||||
|
for y = (pos.y - radius), (pos.y + radius) do
|
||||||
|
for x = (pos.x - radius), (pos.x + radius) do
|
||||||
|
for z = (pos.z - radius), (pos.z + radius) do
|
||||||
|
local testpos = { x = x, y = y, z = z }
|
||||||
|
local node = minetest.get_node (testpos)
|
||||||
|
|
||||||
|
if node and node.name ~= "air" and node.name ~= "ignore" and
|
||||||
|
filter_item (pos, mode, testpos) then
|
||||||
|
|
||||||
|
send_detect_message (pos,
|
||||||
|
"node",
|
||||||
|
node.name,
|
||||||
|
node.name,
|
||||||
|
testpos,
|
||||||
|
1)
|
||||||
|
|
||||||
|
detected = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if detected then
|
||||||
|
mesecons_on (pos)
|
||||||
|
else
|
||||||
|
mesecons_off (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function get_form_spec (is_off, radius, entities, players, drops, nodes, mode)
|
||||||
|
return
|
||||||
|
"formspec_version[3]\n"..
|
||||||
|
"size[11.75,9.0;true]\n"..
|
||||||
|
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
|
||||||
|
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
|
||||||
|
"button[8.25,1.0;2.5,0.8;"..((is_off and "start;Start") or "stop;Stop").."]\n"..
|
||||||
|
"field[1.0,2.5;4.0,0.8;radius;Radius;"..tostring (radius).."]\n"..
|
||||||
|
"button[5.5,2.5;2.0,0.8;setradius;Set]\n"..
|
||||||
|
"checkbox[1.0,4.4;entities;Entities;"..entities.."]\n"..
|
||||||
|
"checkbox[1.0,5.4;players;Players;"..players.."]\n"..
|
||||||
|
"checkbox[1.0,6.4;drops;Drops;"..drops.."]\n"..
|
||||||
|
"checkbox[1.0,7.4;nodes;Nodes;"..nodes.."]\n"..
|
||||||
|
"textlist[4.875,4.0;5.875,4.0;mode;All,Forward,Up,Down;"..tostring (mode)..";false]"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function update_form_spec (pos)
|
||||||
|
local node = minetest.get_node (pos)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if node and meta then
|
||||||
|
local is_off = node.name == "lwcomponents:detector" or
|
||||||
|
node.name == "lwcomponents:detector_locked"
|
||||||
|
|
||||||
|
meta:set_string ("formspec",
|
||||||
|
get_form_spec (is_off,
|
||||||
|
meta:get_int ("radius"),
|
||||||
|
meta:get_string ("entities"),
|
||||||
|
meta:get_string ("players"),
|
||||||
|
meta:get_string ("drops"),
|
||||||
|
meta:get_string ("nodes"),
|
||||||
|
meta:get_int ("mode")))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function start_detector (pos)
|
||||||
|
local node = minetest.get_node (pos)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if node and meta then
|
||||||
|
if node.name == "lwcomponents:detector" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:detector_on"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):start (detect_interval)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif node.name == "lwcomponents:detector_locked" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:detector_locked_on"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):start (detect_interval)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function stop_detector (pos)
|
||||||
|
local node = minetest.get_node (pos)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if node and meta then
|
||||||
|
if node.name == "lwcomponents:detector_on" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:detector"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):stop ()
|
||||||
|
mesecons_off (pos)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif node.name == "lwcomponents:detector_locked_on" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
node.name = "lwcomponents:detector_locked"
|
||||||
|
|
||||||
|
minetest.swap_node (pos, node)
|
||||||
|
minetest.get_node_timer (pos):stop ()
|
||||||
|
mesecons_off (pos)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_destruct (pos)
|
||||||
|
minetest.get_node_timer (pos):stop ()
|
||||||
|
|
||||||
|
mesecons_off (pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
local is_off = itemstack and (itemstack:get_name () == "lwcomponents:detector" or
|
||||||
|
itemstack:get_name () == "lwcomponents:detector_locked")
|
||||||
|
|
||||||
|
meta:set_string ("inventory", "{ main = { }, filter = { } }")
|
||||||
|
meta:set_string ("formspec", get_form_spec (is_off, 1, 0, 0, 0, 0, 1))
|
||||||
|
|
||||||
|
meta:set_string ("entities", "false")
|
||||||
|
meta:set_string ("players", "false")
|
||||||
|
meta:set_string ("drops", "false")
|
||||||
|
meta:set_string ("nodes", "false")
|
||||||
|
meta:set_int ("mode", 1)
|
||||||
|
meta:set_int ("radius", 1)
|
||||||
|
meta:set_int ("power_on", 0)
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
|
||||||
|
after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
|
||||||
|
if placer and placer:is_player () then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
meta:set_string ("owner", placer:get_player_name ())
|
||||||
|
meta:set_string ("infotext", "Detector (owned by "..placer:get_player_name ()..")")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_receive_fields (pos, formname, fields, sender)
|
||||||
|
if not utils.can_interact_with_node (pos, sender) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.setchannel then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("channel", fields.channel)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.setradius then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local radius = math.min (math.max (tonumber (fields.radius) or 1, 1), 5)
|
||||||
|
|
||||||
|
meta:set_int ("radius", radius)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.start then
|
||||||
|
start_detector (pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.stop then
|
||||||
|
stop_detector (pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.entities ~= nil then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("entities", fields.entities)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.players ~= nil then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("players", fields.players)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.drops ~= nil then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("drops", fields.drops)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.nodes ~= nil then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("nodes", fields.nodes)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.mode then
|
||||||
|
local event = minetest.explode_textlist_event (fields.mode)
|
||||||
|
|
||||||
|
if event.type == "CHG" then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_int ("mode", event.index)
|
||||||
|
update_form_spec (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function can_dig (pos, player)
|
||||||
|
if not utils.can_interact_with_node (pos, player) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_blast (pos, intensity)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
if intensity >= 1.0 then
|
||||||
|
on_destruct (pos)
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
|
||||||
|
else -- intensity < 1.0
|
||||||
|
local node = minetest.get_node_or_nil (pos)
|
||||||
|
if node then
|
||||||
|
local items = minetest.get_node_drops (node, nil)
|
||||||
|
|
||||||
|
if items and #items > 0 then
|
||||||
|
local stack = ItemStack (items[1])
|
||||||
|
|
||||||
|
if stack then
|
||||||
|
preserve_metadata (pos, node, meta, { stack })
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
on_destruct (pos)
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_timer (pos, elapsed)
|
||||||
|
detect (pos)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
|
||||||
|
if not utils.can_interact_with_node (pos, clicker) then
|
||||||
|
if clicker and clicker:is_player () then
|
||||||
|
local owner = "<unknown>"
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
owner = meta:get_string ("owner")
|
||||||
|
end
|
||||||
|
|
||||||
|
local spec =
|
||||||
|
"formspec_version[3]"..
|
||||||
|
"size[8.0,4.0,false]"..
|
||||||
|
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
|
||||||
|
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
|
||||||
|
|
||||||
|
minetest.show_formspec (clicker:get_player_name (),
|
||||||
|
"lwcomponents:component_privately_owned",
|
||||||
|
spec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function digilines_support ()
|
||||||
|
if utils.digilines_supported then
|
||||||
|
return
|
||||||
|
{
|
||||||
|
wire =
|
||||||
|
{
|
||||||
|
rules = digiline.rules.default,
|
||||||
|
},
|
||||||
|
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
action = function (pos, node, channel, msg)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local this_channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if this_channel == channel then
|
||||||
|
local m = { }
|
||||||
|
for w in string.gmatch(msg, "[^%s]+") do
|
||||||
|
m[#m + 1] = w
|
||||||
|
end
|
||||||
|
|
||||||
|
if m[1] == "start" then
|
||||||
|
start_detector (pos)
|
||||||
|
|
||||||
|
elseif m[1] == "stop" then
|
||||||
|
stop_detector (pos)
|
||||||
|
|
||||||
|
elseif m[1] == "radius" then
|
||||||
|
local radius = math.min (math.max (tonumber (m[2] or 1) or 1, 1), 5)
|
||||||
|
|
||||||
|
meta:set_int ("radius", radius)
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
elseif m[1] == "entities" then
|
||||||
|
meta:set_string ("entities", ((m[2] == "true") and "true") or "false")
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
elseif m[1] == "players" then
|
||||||
|
meta:set_string ("players", ((m[2] == "true") and "true") or "false")
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
elseif m[1] == "drops" then
|
||||||
|
meta:set_string ("drops", ((m[2] == "true") and "true") or "false")
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
elseif m[1] == "nodes" then
|
||||||
|
meta:set_string ("nodes", ((m[2] == "true") and "true") or "false")
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
|
||||||
|
elseif m[1] == "mode" then
|
||||||
|
if m[2] == "all" then
|
||||||
|
meta:set_int ("mode", 1)
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
elseif m[2] == "forward" then
|
||||||
|
meta:set_int ("mode", 2)
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
elseif m[2] == "up" then
|
||||||
|
meta:set_int ("mode", 3)
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
elseif m[2] == "down" then
|
||||||
|
meta:set_int ("mode", 4)
|
||||||
|
update_form_spec (pos)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function mesecon_support ()
|
||||||
|
if utils.mesecon_supported then
|
||||||
|
return
|
||||||
|
{
|
||||||
|
receptor =
|
||||||
|
{
|
||||||
|
state = utils.mesecon_state_off,
|
||||||
|
rules = utils.mesecon_default_rules
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:detector", {
|
||||||
|
description = S("Detector"),
|
||||||
|
tiles = { "lwdetector_face.png", "lwdetector_face.png", "lwdetector.png",
|
||||||
|
"lwdetector.png", "lwdetector.png", "lwdetector_face.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:detector",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
can_dig = can_dig,
|
||||||
|
after_place_node = after_place_node,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:detector_locked", {
|
||||||
|
description = S("Detector (locked)"),
|
||||||
|
tiles = { "lwdetector_face.png", "lwdetector_face.png", "lwdetector.png",
|
||||||
|
"lwdetector.png", "lwdetector.png", "lwdetector_face.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:detector_locked",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
can_dig = can_dig,
|
||||||
|
after_place_node = after_place_node_locked,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:detector_on", {
|
||||||
|
description = S("Detector"),
|
||||||
|
tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png",
|
||||||
|
"lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3, not_in_creative_inventory = 1 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:detector",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
can_dig = can_dig,
|
||||||
|
after_place_node = after_place_node,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:detector_locked_on", {
|
||||||
|
description = S("Detector (locked)"),
|
||||||
|
tiles = { "lwdetector_face_on.png", "lwdetector_face_on.png", "lwdetector.png",
|
||||||
|
"lwdetector.png", "lwdetector.png", "lwdetector_face_on.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3, not_in_creative_inventory = 1 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
drop = "lwcomponents:detector_locked",
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
can_dig = can_dig,
|
||||||
|
after_place_node = after_place_node_locked,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_timer = on_timer,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end -- utils.digilines_supported or utils.mesecon_supported
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
188
digiswitch.lua
Normal file
188
digiswitch.lua
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported and utils.mesecon_supported then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function get_mesecon_rule_for_side (side)
|
||||||
|
local base = nil
|
||||||
|
|
||||||
|
if side == "white" then
|
||||||
|
return { { x = 0, y = 1, z = 0 } }
|
||||||
|
elseif side == "black" then
|
||||||
|
return { { x = 0, y = -1, z = 0 } } -- down doesn't work
|
||||||
|
elseif side == "red" then
|
||||||
|
return { { x = -1, y = 0, z = 0 } }
|
||||||
|
elseif side == "green" then
|
||||||
|
return { { x = 1, y = 0, z = 0 } }
|
||||||
|
elseif side == "blue" then
|
||||||
|
return { { x = 0, y = 0, z = -1 } }
|
||||||
|
elseif side == "yellow" then
|
||||||
|
return { { x = 0, y = 0, z = 1 } }
|
||||||
|
elseif side == "switch" then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return
|
||||||
|
{
|
||||||
|
{ x = 1, y = 0, z = 0 },
|
||||||
|
{ x = -1, y = 0, z = 0 },
|
||||||
|
{ x = 0, y = 0, z = 1 },
|
||||||
|
{ x = 0, y = 0, z = -1 },
|
||||||
|
{ x = 0, y = 1, z = 0 },
|
||||||
|
{ x = 0, y = -1, z = 0 }, -- down doesn't work
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function digilines_support ()
|
||||||
|
return
|
||||||
|
{
|
||||||
|
wire =
|
||||||
|
{
|
||||||
|
rules =
|
||||||
|
{
|
||||||
|
{ x = 0, y = 0, z = -1 },
|
||||||
|
{ x = 1, y = 0, z = 0 },
|
||||||
|
{ x = -1, y = 0, z = 0 },
|
||||||
|
{ x = 0, y = 0, z = 1 },
|
||||||
|
{ x = 1, y = 1, z = 0 },
|
||||||
|
{ x = 1, y = -1, z = 0 },
|
||||||
|
{ x = -1, y = 1, z = 0 },
|
||||||
|
{ x = -1, y = -1, z = 0 },
|
||||||
|
{ x = 0, y = 1, z = 1 },
|
||||||
|
{ x = 0, y = -1, z = 1 },
|
||||||
|
{ x = 0, y = 1, z = -1 },
|
||||||
|
{ x = 0, y = -1, z = -1 },
|
||||||
|
{ x = 0, y = 1, z = 0 },
|
||||||
|
{ x = 0, y = -1, z = 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
action = function (pos, node, channel, msg)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local mychannel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if mychannel == channel then
|
||||||
|
if type (msg) == "string" then
|
||||||
|
local words = { }
|
||||||
|
|
||||||
|
for word in string.gmatch (msg, "%S+") do
|
||||||
|
words[#words + 1] = word
|
||||||
|
end
|
||||||
|
|
||||||
|
if words[1] == "on" then
|
||||||
|
utils.mesecon_receptor_on (pos, get_mesecon_rule_for_side (words[2]))
|
||||||
|
elseif words[1] == "off" then
|
||||||
|
utils.mesecon_receptor_off (pos, get_mesecon_rule_for_side (words[2]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function mesecon_support ()
|
||||||
|
return
|
||||||
|
{
|
||||||
|
receptor =
|
||||||
|
{
|
||||||
|
state = mesecon.state.off,
|
||||||
|
rules =
|
||||||
|
{
|
||||||
|
{ x = 1, y = 0, z = 0 },
|
||||||
|
{ x = -1, y = 0, z = 0 },
|
||||||
|
{ x = 0, y = 0, z = 1 },
|
||||||
|
{ x = 0, y = 0, z = -1 },
|
||||||
|
{ x = 0, y = 1, z = 0 },
|
||||||
|
{ x = 0, y = -1, z = 0 }, -- down doesn't work
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_construct (pos)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("channel", "")
|
||||||
|
|
||||||
|
local formspec =
|
||||||
|
"formspec_version[3]\n"..
|
||||||
|
"size[6.0,4.0]\n"..
|
||||||
|
"field[1.0,0.8;4.0,1.0;channel;Channel;]\n"..
|
||||||
|
"button_exit[2.0,2.5;2.0,1.0;set;Set]\n"
|
||||||
|
|
||||||
|
meta:set_string ("formspec", formspec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_destruct (pos)
|
||||||
|
utils.mesecon_receptor_off (pos, get_mesecon_rule_for_side ())
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_receive_fields (pos, formname, fields, sender)
|
||||||
|
if fields.channel then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("channel", fields.channel or "")
|
||||||
|
|
||||||
|
local formspec =
|
||||||
|
"formspec_version[3]\n"..
|
||||||
|
"size[6.0,4.0]\n"..
|
||||||
|
"field[1.0,0.8;4.0,1.0;channel;Channel;"..minetest.formspec_escape (meta:get_string ("channel")).."]\n"..
|
||||||
|
"button_exit[2.0,2.5;2.0,1.0;set;Set]\n"
|
||||||
|
|
||||||
|
meta:set_string ("formspec", formspec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node ("lwcomponents:digiswitch", {
|
||||||
|
description = S("Digilines Switch"),
|
||||||
|
tiles = { "lwdigiswitch_white.png", "lwdigiswitch_black.png",
|
||||||
|
"lwdigiswitch_green.png", "lwdigiswitch_red.png",
|
||||||
|
"lwdigiswitch_yellow.png", "lwdigiswitch_blue.png" },
|
||||||
|
sunlight_propagates = false,
|
||||||
|
drawtype = "normal",
|
||||||
|
node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groups = { cracky = 2, oddly_breakable_by_hand = 2 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
on_construct = on_construct,
|
||||||
|
on_destruct = on_destruct,
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end -- utils.digilines_supported and utils.mesecon_supported
|
429
dispenser.lua
Normal file
429
dispenser.lua
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported or utils.mesecon_supported then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function dispense_pos (pos, node)
|
||||||
|
if node.param2 == 0 then
|
||||||
|
return { x = pos.x, y = pos.y, z = pos.z - 1 }
|
||||||
|
elseif node.param2 == 1 then
|
||||||
|
return { x = pos.x - 1, y = pos.y, z = pos.z }
|
||||||
|
elseif node.param2 == 2 then
|
||||||
|
return { x = pos.x, y = pos.y, z = pos.z + 1 }
|
||||||
|
elseif node.param2 == 3 then
|
||||||
|
return { x = pos.x + 1, y = pos.y, z = pos.z }
|
||||||
|
else
|
||||||
|
return { x = pos.x, y = pos.y, z = pos.z }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function dispense_velocity (node)
|
||||||
|
local force = 25 --math.random (30 , 35)
|
||||||
|
local tilt = (math.random (1 , 2001) - 1001) / 1000
|
||||||
|
local sway = (math.random (1 , 4001) - 2001) / 1000
|
||||||
|
|
||||||
|
if node.param2 == 0 then
|
||||||
|
return { x = sway, y = tilt, z = -force }
|
||||||
|
elseif node.param2 == 1 then
|
||||||
|
return { x = -force, y = tilt, z = sway }
|
||||||
|
elseif node.param2 == 2 then
|
||||||
|
return { x = sway, y = tilt, z = force }
|
||||||
|
elseif node.param2 == 3 then
|
||||||
|
return { x = force, y = tilt, z = sway }
|
||||||
|
else
|
||||||
|
return { x = 0, y = 0, z = 0 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function send_dispense_message (pos, slot, name)
|
||||||
|
if utils.digilines_supported then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if channel:len () > 0 then
|
||||||
|
utils.digilines_receptor_send (pos,
|
||||||
|
digiline.rules.default,
|
||||||
|
channel,
|
||||||
|
{ action = "dispense",
|
||||||
|
name = name,
|
||||||
|
slot = slot })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- slot:
|
||||||
|
-- nil - next item, no dispense if empty
|
||||||
|
-- number - 1 item from slot, no dispense if empty
|
||||||
|
-- string - name of item to dispense, no dispense if none
|
||||||
|
local function dispense_item (pos, node, slot)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
if not slot then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for i = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", i)
|
||||||
|
|
||||||
|
if not stack:is_empty () and stack:get_count () > 0 then
|
||||||
|
slot = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif type (slot) == "string" then
|
||||||
|
local name = slot
|
||||||
|
slot = nil
|
||||||
|
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for i = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", i)
|
||||||
|
|
||||||
|
if not stack:is_empty () and stack:get_count () > 0 then
|
||||||
|
if name == stack:get_name () then
|
||||||
|
slot = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
slot = tonumber (slot)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if slot then
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if not stack:is_empty () and stack:get_count () > 0 then
|
||||||
|
local name = stack:get_name ()
|
||||||
|
local item = ItemStack (stack)
|
||||||
|
|
||||||
|
if item then
|
||||||
|
item:set_count (1)
|
||||||
|
|
||||||
|
local obj = minetest.add_item (dispense_pos (pos, node), item)
|
||||||
|
|
||||||
|
if obj then
|
||||||
|
obj:set_velocity (dispense_velocity (node))
|
||||||
|
|
||||||
|
stack:set_count (stack:get_count () - 1)
|
||||||
|
inv:set_stack ("main", slot, stack)
|
||||||
|
|
||||||
|
send_dispense_message (pos, slot, name)
|
||||||
|
|
||||||
|
return true, slot, name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
local spec =
|
||||||
|
"formspec_version[3]\n"..
|
||||||
|
"size[11.75,13.75;true]\n"..
|
||||||
|
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
|
||||||
|
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
|
||||||
|
"list[context;main;3.5,2.5;4,4;]\n"..
|
||||||
|
"list[current_player;main;1.0,8.0;8,4;]\n"..
|
||||||
|
"listring[]"
|
||||||
|
|
||||||
|
meta:set_string ("inventory", "{ main = { } }")
|
||||||
|
meta:set_string ("formspec", spec)
|
||||||
|
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
inv:set_size ("main", 16)
|
||||||
|
inv:set_width ("main", 4)
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
|
||||||
|
after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
|
||||||
|
if placer and placer:is_player () then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
meta:set_string ("owner", placer:get_player_name ())
|
||||||
|
meta:set_string ("infotext", "Dispenser (owned by "..placer:get_player_name ()..")")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_receive_fields (pos, formname, fields, sender)
|
||||||
|
if not utils.can_interact_with_node (pos, sender) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.setchannel then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("channel", fields.channel)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function can_dig (pos, player)
|
||||||
|
if not utils.can_interact_with_node (pos, player) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
if not inv:is_empty ("main") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_blast (pos, intensity)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
if intensity >= 1.0 then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
if math.floor (math.random (0, 5)) == 3 then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
else
|
||||||
|
utils.on_destroy (stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
|
||||||
|
else -- intensity < 1.0
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local node = minetest.get_node_or_nil (pos)
|
||||||
|
if node then
|
||||||
|
local items = minetest.get_node_drops (node, nil)
|
||||||
|
|
||||||
|
if items and #items > 0 then
|
||||||
|
local stack = ItemStack (items[1])
|
||||||
|
|
||||||
|
if stack then
|
||||||
|
preserve_metadata (pos, node, meta, { stack })
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
|
||||||
|
if not utils.can_interact_with_node (pos, clicker) then
|
||||||
|
if clicker and clicker:is_player () then
|
||||||
|
local owner = "<unknown>"
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
owner = meta:get_string ("owner")
|
||||||
|
end
|
||||||
|
|
||||||
|
local spec =
|
||||||
|
"formspec_version[3]"..
|
||||||
|
"size[8.0,4.0,false]"..
|
||||||
|
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
|
||||||
|
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
|
||||||
|
|
||||||
|
minetest.show_formspec (clicker:get_player_name (),
|
||||||
|
"lwcomponents:component_privately_owned",
|
||||||
|
spec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function digilines_support ()
|
||||||
|
if utils.digilines_supported then
|
||||||
|
return
|
||||||
|
{
|
||||||
|
wire =
|
||||||
|
{
|
||||||
|
rules = digiline.rules.default,
|
||||||
|
},
|
||||||
|
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
action = function (pos, node, channel, msg)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local this_channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if this_channel == channel then
|
||||||
|
local m = { }
|
||||||
|
for w in string.gmatch(msg, "[^%s]+") do
|
||||||
|
m[#m + 1] = w
|
||||||
|
end
|
||||||
|
|
||||||
|
if m[1] == "dispense" then
|
||||||
|
if m[2] and tonumber (m[2]) then
|
||||||
|
m[2] = tonumber (m[2])
|
||||||
|
end
|
||||||
|
|
||||||
|
dispense_item (pos, node, m[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function mesecon_support ()
|
||||||
|
if utils.mesecon_supported then
|
||||||
|
return
|
||||||
|
{
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
rules = utils.mesecon_flat_rules,
|
||||||
|
|
||||||
|
action_on = function (pos, node)
|
||||||
|
dispense_item (pos, node)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:dispenser", {
|
||||||
|
description = S("Dispenser"),
|
||||||
|
tiles = { "lwdispenser.png", "lwdispenser.png", "lwdispenser.png",
|
||||||
|
"lwdispenser.png", "lwdispenser.png", "lwdispenser_face.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:dispenser_locked", {
|
||||||
|
description = S("Dispenser (locked)"),
|
||||||
|
tiles = { "lwdispenser.png", "lwdispenser.png", "lwdispenser.png",
|
||||||
|
"lwdispenser.png", "lwdispenser.png", "lwdispenser_face.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node_locked,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end -- utils.digilines_supported or utils.mesecon_supported
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
405
dropper.lua
Normal file
405
dropper.lua
Normal file
@@ -0,0 +1,405 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.digilines_supported or utils.mesecon_supported then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function drop_pos (pos, node)
|
||||||
|
if node.param2 == 0 then
|
||||||
|
return { x = pos.x, y = pos.y, z = pos.z - 1 }
|
||||||
|
elseif node.param2 == 1 then
|
||||||
|
return { x = pos.x - 1, y = pos.y, z = pos.z }
|
||||||
|
elseif node.param2 == 2 then
|
||||||
|
return { x = pos.x, y = pos.y, z = pos.z + 1 }
|
||||||
|
elseif node.param2 == 3 then
|
||||||
|
return { x = pos.x + 1, y = pos.y, z = pos.z }
|
||||||
|
else
|
||||||
|
return { x = pos.x, y = pos.y, z = pos.z }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function send_drop_message (pos, slot, name)
|
||||||
|
if utils.digilines_supported then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if channel:len () > 0 then
|
||||||
|
utils.digilines_receptor_send (pos,
|
||||||
|
digiline.rules.default,
|
||||||
|
channel,
|
||||||
|
{ action = "drop",
|
||||||
|
name = name,
|
||||||
|
slot = slot })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- slot:
|
||||||
|
-- nil - next item, no drop if empty
|
||||||
|
-- number - 1 item from slot, no drop if empty
|
||||||
|
-- string - name of item to drop, no drop if none
|
||||||
|
local function drop_item (pos, node, slot)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
if not slot then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for i = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", i)
|
||||||
|
|
||||||
|
if not stack:is_empty () and stack:get_count () > 0 then
|
||||||
|
slot = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif type (slot) == "string" then
|
||||||
|
local name = slot
|
||||||
|
slot = nil
|
||||||
|
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for i = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", i)
|
||||||
|
|
||||||
|
if not stack:is_empty () and stack:get_count () > 0 then
|
||||||
|
if name == stack:get_name () then
|
||||||
|
slot = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
slot = tonumber (slot)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if slot then
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if not stack:is_empty () and stack:get_count () > 0 then
|
||||||
|
local name = stack:get_name ()
|
||||||
|
local item = ItemStack (stack)
|
||||||
|
|
||||||
|
if item then
|
||||||
|
item:set_count (1)
|
||||||
|
|
||||||
|
stack:set_count (stack:get_count () - 1)
|
||||||
|
inv:set_stack ("main", slot, stack)
|
||||||
|
|
||||||
|
utils.item_drop (item, nil, drop_pos (pos, node))
|
||||||
|
|
||||||
|
send_drop_message (pos, slot, name)
|
||||||
|
|
||||||
|
return true, slot, name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
local spec =
|
||||||
|
"formspec_version[3]\n"..
|
||||||
|
"size[11.75,13.75;true]\n"..
|
||||||
|
"field[1.0,1.0;4.0,0.8;channel;Channel;${channel}]\n"..
|
||||||
|
"button[5.5,1.0;2.0,0.8;setchannel;Set]\n"..
|
||||||
|
"list[context;main;3.5,2.5;4,4;]\n"..
|
||||||
|
"list[current_player;main;1.0,8.0;8,4;]\n"..
|
||||||
|
"listring[]"
|
||||||
|
|
||||||
|
meta:set_string ("inventory", "{ main = { } }")
|
||||||
|
meta:set_string ("formspec", spec)
|
||||||
|
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
inv:set_size ("main", 16)
|
||||||
|
inv:set_width ("main", 4)
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function after_place_node_locked (pos, placer, itemstack, pointed_thing)
|
||||||
|
after_place_node (pos, placer, itemstack, pointed_thing)
|
||||||
|
|
||||||
|
if placer and placer:is_player () then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
meta:set_string ("owner", placer:get_player_name ())
|
||||||
|
meta:set_string ("infotext", "Dropper (owned by "..placer:get_player_name ()..")")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If return true no item is taken from itemstack
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_receive_fields (pos, formname, fields, sender)
|
||||||
|
if not utils.can_interact_with_node (pos, sender) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.setchannel then
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
meta:set_string ("channel", fields.channel)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function can_dig (pos, player)
|
||||||
|
if not utils.can_interact_with_node (pos, player) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
if not inv:is_empty ("main") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_blast (pos, intensity)
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
if intensity >= 1.0 then
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
if math.floor (math.random (0, 5)) == 3 then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
else
|
||||||
|
utils.on_destroy (stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
|
||||||
|
else -- intensity < 1.0
|
||||||
|
local inv = meta:get_inventory ()
|
||||||
|
|
||||||
|
if inv then
|
||||||
|
local slots = inv:get_size ("main")
|
||||||
|
|
||||||
|
for slot = 1, slots do
|
||||||
|
local stack = inv:get_stack ("main", slot)
|
||||||
|
|
||||||
|
if stack and not stack:is_empty () then
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local node = minetest.get_node_or_nil (pos)
|
||||||
|
if node then
|
||||||
|
local items = minetest.get_node_drops (node, nil)
|
||||||
|
|
||||||
|
if items and #items > 0 then
|
||||||
|
local stack = ItemStack (items[1])
|
||||||
|
|
||||||
|
if stack then
|
||||||
|
preserve_metadata (pos, node, meta, { stack })
|
||||||
|
utils.item_drop (stack, nil, pos)
|
||||||
|
minetest.remove_node (pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_rightclick (pos, node, clicker, itemstack, pointed_thing)
|
||||||
|
if not utils.can_interact_with_node (pos, clicker) then
|
||||||
|
if clicker and clicker:is_player () then
|
||||||
|
local owner = "<unknown>"
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
owner = meta:get_string ("owner")
|
||||||
|
end
|
||||||
|
|
||||||
|
local spec =
|
||||||
|
"formspec_version[3]"..
|
||||||
|
"size[8.0,4.0,false]"..
|
||||||
|
"label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]"..
|
||||||
|
"button_exit[3.0,2.0;2.0,1.0;close;Close]"
|
||||||
|
|
||||||
|
minetest.show_formspec (clicker:get_player_name (),
|
||||||
|
"lwcomponents:component_privately_owned",
|
||||||
|
spec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function digilines_support ()
|
||||||
|
if utils.digilines_supported then
|
||||||
|
return
|
||||||
|
{
|
||||||
|
wire =
|
||||||
|
{
|
||||||
|
rules = digiline.rules.default,
|
||||||
|
},
|
||||||
|
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
action = function (pos, node, channel, msg)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
if meta then
|
||||||
|
local this_channel = meta:get_string ("channel")
|
||||||
|
|
||||||
|
if this_channel == channel then
|
||||||
|
local m = { }
|
||||||
|
for w in string.gmatch(msg, "[^%s]+") do
|
||||||
|
m[#m + 1] = w
|
||||||
|
end
|
||||||
|
|
||||||
|
if m[1] == "drop" then
|
||||||
|
if m[2] and tonumber (m[2]) then
|
||||||
|
m[2] = tonumber (m[2])
|
||||||
|
end
|
||||||
|
|
||||||
|
drop_item (pos, node, m[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function mesecon_support ()
|
||||||
|
if utils.mesecon_supported then
|
||||||
|
return
|
||||||
|
{
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
rules = utils.mesecon_flat_rules,
|
||||||
|
|
||||||
|
action_on = function (pos, node)
|
||||||
|
drop_item (pos, node)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:dropper", {
|
||||||
|
description = S("Dropper"),
|
||||||
|
tiles = { "lwdropper.png", "lwdropper.png", "lwdropper.png",
|
||||||
|
"lwdropper.png", "lwdropper.png", "lwdropper_face.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:dropper_locked", {
|
||||||
|
description = S("Dropper (locked)"),
|
||||||
|
tiles = { "lwdropper.png", "lwdropper.png", "lwdropper.png",
|
||||||
|
"lwdropper.png", "lwdropper.png", "lwdropper_face.png"},
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = { cracky = 3 },
|
||||||
|
sounds = default.node_sound_stone_defaults (),
|
||||||
|
paramtype = "light",
|
||||||
|
param1 = 0,
|
||||||
|
paramtype2 = "facedir",
|
||||||
|
param2 = 1,
|
||||||
|
floodable = false,
|
||||||
|
_digistuff_channelcopier_fieldname = "channel",
|
||||||
|
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
digiline = digilines_support (),
|
||||||
|
|
||||||
|
on_receive_fields = on_receive_fields,
|
||||||
|
after_place_node = after_place_node_locked,
|
||||||
|
can_dig = can_dig,
|
||||||
|
on_blast = on_blast,
|
||||||
|
on_rightclick = on_rightclick
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end -- utils.digilines_supported or utils.mesecon_supported
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
88
extras.lua
Normal file
88
extras.lua
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local touchscreen = minetest.registered_nodes["digistuff:touchscreen"]
|
||||||
|
if touchscreen then
|
||||||
|
local touchblock = table.copy (touchscreen)
|
||||||
|
|
||||||
|
touchblock.description = S("LWComponents Touchscreen")
|
||||||
|
|
||||||
|
touchblock.node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
touchblock.selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
touchblock.collision_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minetest.register_node ("lwcomponents:touchscreen", touchblock)
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "lwcomponents:touchscreen",
|
||||||
|
recipe = {
|
||||||
|
{"mesecons_luacontroller:luacontroller0000","default:glass","default:glass"},
|
||||||
|
{"default:glass","digilines:lcd","default:glass"},
|
||||||
|
{"default:glass","default:glass","default:stone"}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local panel = minetest.registered_nodes["digistuff:panel"]
|
||||||
|
if panel then
|
||||||
|
local panelblock = table.copy (panel)
|
||||||
|
|
||||||
|
panelblock.description = S("LWComponents Control Panel")
|
||||||
|
|
||||||
|
panelblock.node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panelblock.selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panelblock.collision_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{ -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minetest.register_node ("lwcomponents:panel", panelblock)
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "lwcomponents:panel",
|
||||||
|
recipe = {
|
||||||
|
{"","digistuff:button",""},
|
||||||
|
{"digistuff:button","digilines:lcd","digistuff:button"},
|
||||||
|
{"","digistuff:button","default:stone"}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
31
init.lua
Normal file
31
init.lua
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
local version = "0.1.0"
|
||||||
|
local mod_storage = minetest.get_mod_storage ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lwcomponents = { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function lwcomponents.version ()
|
||||||
|
return version
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local utils = { }
|
||||||
|
local modpath = minetest.get_modpath ("lwcomponents")
|
||||||
|
|
||||||
|
loadfile (modpath.."/utils.lua") (utils, mod_storage)
|
||||||
|
loadfile (modpath.."/dropper.lua") (utils)
|
||||||
|
loadfile (modpath.."/collector.lua") (utils)
|
||||||
|
loadfile (modpath.."/dispenser.lua") (utils)
|
||||||
|
loadfile (modpath.."/detector.lua") (utils)
|
||||||
|
loadfile (modpath.."/extras.lua") (utils)
|
||||||
|
loadfile (modpath.."/digiswitch.lua") (utils)
|
||||||
|
loadfile (modpath.."/movefloor.lua") (utils)
|
||||||
|
loadfile (modpath.."/solid_conductor.lua") (utils)
|
||||||
|
loadfile (modpath.."/crafting.lua") (utils)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
38
license.txt
Normal file
38
license.txt
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
Source code license
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
GNU Lesser General Public License, version 2.1
|
||||||
|
Copyright (C) 2021 loosewheel
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under the terms
|
||||||
|
of the GNU Lesser General Public License as published by the Free Software Foundation;
|
||||||
|
either version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details:
|
||||||
|
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
|
||||||
|
|
||||||
|
|
||||||
|
Media license
|
||||||
|
-------------
|
||||||
|
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||||
|
|
||||||
|
You are free to:
|
||||||
|
Share — copy and redistribute the material in any medium or format.
|
||||||
|
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||||
|
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||||
|
|
||||||
|
Under the following terms:
|
||||||
|
|
||||||
|
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||||
|
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||||
|
that suggests the licensor endorses you or your use.
|
||||||
|
|
||||||
|
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||||
|
your contributions under the same license as the original.
|
||||||
|
|
||||||
|
No additional restrictions — You may not apply legal terms or technological measures that
|
||||||
|
legally restrict others from doing anything the license permits.
|
||||||
|
|
||||||
|
See http://creativecommons.org/licenses/by-sa/3.0/
|
6
mod.conf
Normal file
6
mod.conf
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
author = loosewheel
|
||||||
|
description = Various components for mesecons and digilines.
|
||||||
|
title = LWComponents
|
||||||
|
name = lwcomponents
|
||||||
|
depends = default
|
||||||
|
optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib
|
199
movefloor.lua
Normal file
199
movefloor.lua
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.mesecon_supported and mesecon.mvps_push then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local mesecon_rules =
|
||||||
|
{
|
||||||
|
{ x = 1, y = 1, z = 0 },
|
||||||
|
{ x = -1, y = 1, z = 0 },
|
||||||
|
{ x = 0, y = 1, z = 1 },
|
||||||
|
{ x = 0, y = 1, z = -1 },
|
||||||
|
{ x = 1, y = -1, z = 0 },
|
||||||
|
{ x = -1, y = -1, z = 0 },
|
||||||
|
{ x = 0, y = -1, z = 1 },
|
||||||
|
{ x = 0, y = -1, z = -1 },
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- use mesecons movestone settings
|
||||||
|
local timer_interval = 1 / mesecon.setting ("movestone_speed", 3)
|
||||||
|
local max_push = 3
|
||||||
|
local max_pull = 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- helper functions:
|
||||||
|
local function get_movefloor_direction (rulename)
|
||||||
|
if rulename.y > 0 then
|
||||||
|
return { x = 0, y = 1, z = 0 }
|
||||||
|
elseif rulename.y < 0 then
|
||||||
|
return { x = 0, y = -1, z = 0 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function add_movefloor_list (pos, list)
|
||||||
|
for i = 1, #list do
|
||||||
|
if list[i].x == pos.x and
|
||||||
|
list[i].y == pos.y and
|
||||||
|
list[i].z == pos.z then
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
list[#list + 1] = { x = pos.x, y = pos.y, z = pos.z }
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function find_adjoining_movefloor (pos, list)
|
||||||
|
local tpos =
|
||||||
|
{
|
||||||
|
{ x = pos.x + 1, y = pos.y, z = pos.z },
|
||||||
|
{ x = pos.x - 1, y = pos.y, z = pos.z },
|
||||||
|
{ x = pos.x, y = pos.y, z = pos.z + 1 },
|
||||||
|
{ x = pos.x, y = pos.y, z = pos.z - 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 1, #tpos do
|
||||||
|
local node = minetest.get_node (tpos[i])
|
||||||
|
if node and node.name == "lwcomponents:movefloor" then
|
||||||
|
if add_movefloor_list (tpos[i], list) then
|
||||||
|
find_adjoining_movefloor (tpos[i], list)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- copied from mesecons movestone
|
||||||
|
local function movefloor_move (pos, node, rulename, is_sticky)
|
||||||
|
local direction = get_movefloor_direction (rulename)
|
||||||
|
local play_sound = false
|
||||||
|
|
||||||
|
local list =
|
||||||
|
{
|
||||||
|
{ x = pos.x, y = pos.y, z = pos.z }
|
||||||
|
}
|
||||||
|
|
||||||
|
find_adjoining_movefloor (pos, list)
|
||||||
|
|
||||||
|
for i = 1, #list do
|
||||||
|
local frontpos = vector.add (list[i], direction)
|
||||||
|
local meta = minetest.get_meta (list[i])
|
||||||
|
local owner = meta:get_string ("owner")
|
||||||
|
local continue = true
|
||||||
|
|
||||||
|
-- ### Step 1: Push nodes in front ###
|
||||||
|
local success, stack, oldstack = mesecon.mvps_push (frontpos, direction, max_push, owner)
|
||||||
|
if not success then
|
||||||
|
if stack == "protected" then
|
||||||
|
meta:set_string ("infotext", "Can't move: protected area on the way")
|
||||||
|
else
|
||||||
|
minetest.get_node_timer (list[i]):start (timer_interval)
|
||||||
|
continue = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if continue then
|
||||||
|
mesecon.mvps_move_objects (frontpos, direction, oldstack)
|
||||||
|
|
||||||
|
-- ### Step 2: Move the movestone ###
|
||||||
|
minetest.set_node (frontpos, node)
|
||||||
|
local meta2 = minetest.get_meta (frontpos)
|
||||||
|
meta2:set_string ("owner", owner)
|
||||||
|
minetest.remove_node (list[i])
|
||||||
|
mesecon.on_dignode (list[i], node)
|
||||||
|
mesecon.on_placenode (frontpos, node)
|
||||||
|
minetest.get_node_timer (frontpos):start (timer_interval)
|
||||||
|
play_sound = true
|
||||||
|
|
||||||
|
-- ### Step 3: If sticky, pull stack behind ###
|
||||||
|
if is_sticky and direction.y < 0 then
|
||||||
|
local backpos = vector.subtract (list[i], direction)
|
||||||
|
success, stack, oldstack = mesecon.mvps_pull_all (backpos, direction, max_pull, owner)
|
||||||
|
if success then
|
||||||
|
mesecon.mvps_move_objects (backpos, vector.multiply (direction, -1), oldstack, -1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ### Step 4: Let things fall ###
|
||||||
|
minetest.check_for_falling (vector.add (list[i], { x = 0, y = 1, z = 0 }))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if play_sound then
|
||||||
|
minetest.sound_play("movestone", { pos = list[i], max_hear_distance = 20, gain = 0.5 }, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function on_timer (pos, elapsed)
|
||||||
|
local sourcepos = mesecon.is_powered (pos)
|
||||||
|
|
||||||
|
if not sourcepos then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local rulename = vector.subtract (sourcepos[1], pos)
|
||||||
|
|
||||||
|
mesecon.activate (pos, minetest.get_node (pos), rulename, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function mesecon_support ()
|
||||||
|
return
|
||||||
|
{
|
||||||
|
effector =
|
||||||
|
{
|
||||||
|
rules = table.copy (mesecon_rules),
|
||||||
|
|
||||||
|
action_on = function (pos, node, rulename)
|
||||||
|
-- do something to turn the effector on
|
||||||
|
|
||||||
|
if rulename and not minetest.get_node_timer (pos):is_started () then
|
||||||
|
movefloor_move (pos, node, rulename, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_node("lwcomponents:movefloor", {
|
||||||
|
description = S("Moving Floor"),
|
||||||
|
tiles = { "lwmovefloortop.png", "lwmovefloortop.png",
|
||||||
|
"lwmovefloorside.png", "lwmovefloorside.png",
|
||||||
|
"lwmovefloorside.png", "lwmovefloorside.png" },
|
||||||
|
sunlight_propagates = false,
|
||||||
|
drawtype = "normal",
|
||||||
|
node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groups = { cracky = 2 },
|
||||||
|
sounds = default.node_sound_wood_defaults (),
|
||||||
|
mesecons = mesecon_support (),
|
||||||
|
|
||||||
|
on_timer = on_timer,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
330
readme.txt
Normal file
330
readme.txt
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
LWComponents
|
||||||
|
by loosewheel
|
||||||
|
|
||||||
|
|
||||||
|
Licence
|
||||||
|
=======
|
||||||
|
Code licence:
|
||||||
|
LGPL 2.1
|
||||||
|
|
||||||
|
Media licence
|
||||||
|
CC BY-SA 3.0
|
||||||
|
|
||||||
|
|
||||||
|
Version
|
||||||
|
=======
|
||||||
|
0.1.0
|
||||||
|
|
||||||
|
|
||||||
|
Minetest Version
|
||||||
|
================
|
||||||
|
This mod was developed on version 5.4.0
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
============
|
||||||
|
default
|
||||||
|
|
||||||
|
|
||||||
|
Optional Dependencies
|
||||||
|
=====================
|
||||||
|
lwdrops
|
||||||
|
mesecons
|
||||||
|
digilines
|
||||||
|
unifieddyes
|
||||||
|
intllib
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
Copy the 'lwcomponents' folder to your mods folder.
|
||||||
|
|
||||||
|
|
||||||
|
Bug Report
|
||||||
|
==========
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
===========
|
||||||
|
Various components for mesecons and digilines.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dropper
|
||||||
|
-------
|
||||||
|
* This block is only available if digilines and/or mesecons are loaded.
|
||||||
|
|
||||||
|
Contains an inventory and drops an item on command. Also acts as a
|
||||||
|
digilines conductor.
|
||||||
|
|
||||||
|
UI
|
||||||
|
|
||||||
|
Channel - digilines channel of dropper.
|
||||||
|
Top 16 slot inventory - storage of items to drop.
|
||||||
|
Bottom 32 slot inventory - player's inventory.
|
||||||
|
|
||||||
|
Mesecons
|
||||||
|
Drops the next item when power is turned on.
|
||||||
|
|
||||||
|
Digilines messages
|
||||||
|
|
||||||
|
"drop"
|
||||||
|
Drops the next item. No drop if dropper is empty.
|
||||||
|
|
||||||
|
"drop <slot>"
|
||||||
|
Drops 1 item from the given slot (1 to 16). No drop if slot is empty.
|
||||||
|
eg. "drop 7"
|
||||||
|
|
||||||
|
"drop <itemname>"
|
||||||
|
Drops 1 item of the given name. No drop if dropper does not contain the
|
||||||
|
item.
|
||||||
|
eg. "drop default:stone"
|
||||||
|
|
||||||
|
When an item is dropped a digilines message is sent with the dropper's
|
||||||
|
channel. The message is a table with the following keys:
|
||||||
|
{
|
||||||
|
action = "drop",
|
||||||
|
name = "<itemname>", -- name of dropped item
|
||||||
|
slot = <slot> -- slot number the item was taken from (1 to 16).
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dispenser
|
||||||
|
---------
|
||||||
|
* This block is only available if digilines and/or mesecons are loaded.
|
||||||
|
|
||||||
|
Contains an inventory and dispenses (with velocity) an item on command.
|
||||||
|
Also acts as a digilines conductor.
|
||||||
|
|
||||||
|
UI
|
||||||
|
|
||||||
|
Channel - digilines channel of dispenser.
|
||||||
|
Top 16 slot inventory - storage of items to dispense.
|
||||||
|
Bottom 32 slot inventory - player's inventory.
|
||||||
|
|
||||||
|
Mesecons
|
||||||
|
Dispenses the next item when power is turned on.
|
||||||
|
|
||||||
|
Digilines messages
|
||||||
|
|
||||||
|
"dispense"
|
||||||
|
Dispenses the next item. No dispense if dispenser is empty.
|
||||||
|
|
||||||
|
"dispense <slot>"
|
||||||
|
Dispenses 1 item from the given slot (1 to 16). No dispense if slot is
|
||||||
|
empty.
|
||||||
|
eg. "dispense 7"
|
||||||
|
|
||||||
|
"dispense <itemname>"
|
||||||
|
Dispenses 1 item of the given name. No dispense if dispenser does not
|
||||||
|
contain the item.
|
||||||
|
eg. "dispense default:stone"
|
||||||
|
|
||||||
|
When an item is dropped a digilines message is sent with the dropper's
|
||||||
|
channel. The message is a table with the following keys:
|
||||||
|
{
|
||||||
|
action = "dispense",
|
||||||
|
name = "<itemname>", -- name of dropped item
|
||||||
|
slot = <slot> -- slot number the item was taken from (1 to 16).
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Collector
|
||||||
|
---------
|
||||||
|
* This block is only available if digilines is loaded.
|
||||||
|
|
||||||
|
Picks up dropped items in adjacent block, with optional filtering. Also
|
||||||
|
acts as a digilines conductor.
|
||||||
|
|
||||||
|
UI
|
||||||
|
|
||||||
|
Channel - digilines channel of collector.
|
||||||
|
Left 16 slot inventory - storage of picked up items.
|
||||||
|
Right 8 slot inventory - Filter list. Place what items should be picked
|
||||||
|
up in this list. Leave empty to pick up all.
|
||||||
|
Bottom 32 slot inventory - player's inventory.
|
||||||
|
|
||||||
|
Digilines messages
|
||||||
|
|
||||||
|
"start"
|
||||||
|
Start the collector.
|
||||||
|
|
||||||
|
"stop"
|
||||||
|
Stop the collector.
|
||||||
|
|
||||||
|
When items are picked up a digilines message is sent with the collector's
|
||||||
|
channel. The message is a table with the following keys:
|
||||||
|
{
|
||||||
|
action = "collect",
|
||||||
|
name = "<itemname>", -- name of picked up items.
|
||||||
|
count = <count> -- number of the item picked up.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Detector
|
||||||
|
--------
|
||||||
|
* This block is only available if digilines and/or mesecons are loaded.
|
||||||
|
|
||||||
|
Detects items or entities within a given radius. Also acts as a
|
||||||
|
digilines conductor.
|
||||||
|
|
||||||
|
UI
|
||||||
|
|
||||||
|
Channel - digilines channel of detector.
|
||||||
|
Radius - block distance from detector to detect.
|
||||||
|
Entities - if checked detects entities.
|
||||||
|
Players - if checked detects players.
|
||||||
|
Drops - if checked detects drops.
|
||||||
|
Nodes - if checked detects nodes.
|
||||||
|
|
||||||
|
mode:
|
||||||
|
All - detects to radius in all directions, including diagonal.
|
||||||
|
Forward - detects to radius directly in front of the detector (one block high).
|
||||||
|
Up - detects to radius directly above the detector (one block wide).
|
||||||
|
Down - detects to radius directly below the detector (one block wide).
|
||||||
|
|
||||||
|
Mesecons
|
||||||
|
Mesecons power is turned on when something is detected, and turned off
|
||||||
|
when nothing is detected.
|
||||||
|
|
||||||
|
Digilines messages
|
||||||
|
|
||||||
|
"start"
|
||||||
|
Start the detector.
|
||||||
|
|
||||||
|
"stop"
|
||||||
|
Stop the detector.
|
||||||
|
|
||||||
|
"radius <n>"
|
||||||
|
Set radius of the detector. <n> should be a number from 1 to 5, and is
|
||||||
|
trimmed to this range.
|
||||||
|
|
||||||
|
"entities <true|false>"
|
||||||
|
Set detection of entities on or off.
|
||||||
|
|
||||||
|
"players <true|false>"
|
||||||
|
Set detection of players on or off.
|
||||||
|
|
||||||
|
"drops <true|false>"
|
||||||
|
Set detection of drops on or off.
|
||||||
|
|
||||||
|
"nodes <true|false>"
|
||||||
|
Set detection of nodes on or off.
|
||||||
|
|
||||||
|
"mode all"
|
||||||
|
"mode forward"
|
||||||
|
"mode up"
|
||||||
|
"mode down"
|
||||||
|
Set the detector's mode.
|
||||||
|
|
||||||
|
When items or entities are detected a digilines message is sent with the
|
||||||
|
detector's channel. A message is sent for each found item/entity. The
|
||||||
|
message is a table with the following keys:
|
||||||
|
{
|
||||||
|
action = "detect",
|
||||||
|
type = "<type>", -- will be "entity", "player", "drop" or "node"
|
||||||
|
name = "<name>",
|
||||||
|
label = "<label>",
|
||||||
|
pos = { x = n, y = n, z = n },
|
||||||
|
count = <count>
|
||||||
|
}
|
||||||
|
|
||||||
|
type
|
||||||
|
Will be "entity", "player", "drop" or "node".
|
||||||
|
|
||||||
|
name
|
||||||
|
For "entity" the registered entity name.
|
||||||
|
For "player" the player's name.
|
||||||
|
For "drop" the registered item name.
|
||||||
|
For "node" the registered item name.
|
||||||
|
|
||||||
|
label
|
||||||
|
For "entity" the name tag text.
|
||||||
|
For "player" the player's name.
|
||||||
|
For "drop" the registered item name.
|
||||||
|
For "node" the registered item name.
|
||||||
|
|
||||||
|
pos
|
||||||
|
The relative position of the detected item/entity from the detector,
|
||||||
|
facing the direction of the detector.
|
||||||
|
+x = right
|
||||||
|
-x = left
|
||||||
|
+z = forward
|
||||||
|
-z = behind
|
||||||
|
+y = above
|
||||||
|
-y = below
|
||||||
|
|
||||||
|
count
|
||||||
|
The count of items for a "drop", or 1 for everything else.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DigiSwitch
|
||||||
|
----------
|
||||||
|
* This block is only available if both digilines and mesecons are loaded.
|
||||||
|
|
||||||
|
Digiswitches act as both a digilines message target and a digilines cable,
|
||||||
|
as well as a mesecons power source. They can be placed beside each other
|
||||||
|
to form a bank, horizontally or vertically.
|
||||||
|
|
||||||
|
Right click the digiswitch to give it a channel.
|
||||||
|
|
||||||
|
Mesecon power can be delivered at 6 sides of the digiswitch, the adjacent
|
||||||
|
4 in the (x, z), above and below. Around the connector on these sides are a
|
||||||
|
colored border indicating the side. The sides are named "red", "green",
|
||||||
|
"blue", "yellow", "white" and "black".
|
||||||
|
|
||||||
|
The digilines message sent to the digiswitch dictates the action, "on" or
|
||||||
|
"off". The action can be followed with the side to act upon, separated by
|
||||||
|
a space. eg. "on white". If a side is stated only that side is acted upon.
|
||||||
|
If the side is omitted (or is invalid) all 6 sides are acted upon. If the
|
||||||
|
side name "switch" is give the power is supplied the same as a mesecons
|
||||||
|
switch (all horizontal sides, one below, this height and one above).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MoveFloor
|
||||||
|
---------
|
||||||
|
* This block is only available if mesecons and mesecons_mvps is loaded.
|
||||||
|
|
||||||
|
The MoveFloor block responds to a mesecons power source in the 4 horizontal
|
||||||
|
directions. If the power source is one higher the MoveFloor moves up to
|
||||||
|
that height. If the power source is one lower the MoveFloor moves down to
|
||||||
|
that height. Powering an adjacent block has no effect. The power source
|
||||||
|
should be turned off before another move or the MoveFloor will oscillate.
|
||||||
|
|
||||||
|
Any horizontally adjoining MoveFloor acts as a single block (only one
|
||||||
|
needs to be powered).
|
||||||
|
|
||||||
|
The MoveFloor will move up to 3 blocks stacked on it.
|
||||||
|
|
||||||
|
If using a DigiSwitch as the power source use the side name "switch" or
|
||||||
|
the MoveFloor will not move.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Solid Color Conductors
|
||||||
|
----------------------
|
||||||
|
* These blocks are only defined if mesecons, digilines, and unifieddyes are
|
||||||
|
loaded.
|
||||||
|
|
||||||
|
Provides 2 blocks that can be colored the same as Solid Color Block (with
|
||||||
|
the air brush) and is both a mesecons and digilines conductor.
|
||||||
|
|
||||||
|
The Solid Color Conductor block conducts in the 'default' directions and
|
||||||
|
the Solid Color Horizontal Conductor only conducts horizontally.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The following are also defined as variants of the original mod item, if
|
||||||
|
the relevant mod is loaded.
|
||||||
|
+ lwcomponents:touchscreen - digistuff:touchscreen as full sized node.
|
||||||
|
+ lwcomponents:panel - digistuff:panel as full sized node.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
142
solid_conductor.lua
Normal file
142
solid_conductor.lua
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
local utils = ...
|
||||||
|
local S = utils.S
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mesecon.register_node (":lwcomponents:solid_conductor",
|
||||||
|
{
|
||||||
|
description = S("Solid Color Conductor"),
|
||||||
|
tiles = { "lwsolid_conductor.png" },
|
||||||
|
is_ground_content = false,
|
||||||
|
sounds = ( default and default.node_sound_wood_defaults() ),
|
||||||
|
paramtype2 = "color",
|
||||||
|
palette = "unifieddyes_palette_extended.png",
|
||||||
|
on_rotate = false,
|
||||||
|
drop = "lwcomponents:solid_conductor_off",
|
||||||
|
digiline = { wire = { rules = mesecon.rules.default } },
|
||||||
|
on_construct = unifieddyes.on_construct,
|
||||||
|
on_dig = unifieddyes.on_dig,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tiles = { "lwsolid_conductor.png" },
|
||||||
|
mesecons =
|
||||||
|
{
|
||||||
|
conductor =
|
||||||
|
{
|
||||||
|
rules = mesecon.rules.default,
|
||||||
|
state = mesecon.state.off,
|
||||||
|
onstate = "lwcomponents:solid_conductor_on",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groups = {
|
||||||
|
dig_immediate = 2,
|
||||||
|
ud_param2_colorable = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tiles = { "lwsolid_conductor.png" },
|
||||||
|
mesecons =
|
||||||
|
{
|
||||||
|
conductor =
|
||||||
|
{
|
||||||
|
rules = mesecon.rules.default,
|
||||||
|
state = mesecon.state.on,
|
||||||
|
offstate = "lwcomponents:solid_conductor_off",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groups = {
|
||||||
|
dig_immediate = 2,
|
||||||
|
ud_param2_colorable = 1,
|
||||||
|
not_in_creative_inventory = 1
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unifieddyes.register_color_craft ({
|
||||||
|
output = "lwcomponents:solid_conductor_off 3",
|
||||||
|
palette = "extended",
|
||||||
|
type = "shapeless",
|
||||||
|
neutral_node = "lwcomponents:solid_conductor_off",
|
||||||
|
recipe = {
|
||||||
|
"NEUTRAL_NODE",
|
||||||
|
"NEUTRAL_NODE",
|
||||||
|
"NEUTRAL_NODE",
|
||||||
|
"MAIN_DYE"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mesecon.register_node (":lwcomponents:solid_horizontal_conductor",
|
||||||
|
{
|
||||||
|
description = S("Solid Color Horizontal Conductor"),
|
||||||
|
tiles = { "lwsolid_conductor.png" },
|
||||||
|
is_ground_content = false,
|
||||||
|
sounds = ( default and default.node_sound_wood_defaults() ),
|
||||||
|
paramtype2 = "color",
|
||||||
|
palette = "unifieddyes_palette_extended.png",
|
||||||
|
on_rotate = false,
|
||||||
|
drop = "lwcomponents:solid_horizontal_conductor_off",
|
||||||
|
digiline = { wire = { rules = mesecon.rules.flat } },
|
||||||
|
on_construct = unifieddyes.on_construct,
|
||||||
|
on_dig = unifieddyes.on_dig,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tiles = { "lwsolid_conductor.png" },
|
||||||
|
mesecons =
|
||||||
|
{
|
||||||
|
conductor =
|
||||||
|
{
|
||||||
|
rules = mesecon.rules.flat,
|
||||||
|
state = mesecon.state.off,
|
||||||
|
onstate = "lwcomponents:solid_horizontal_conductor_on",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groups = {
|
||||||
|
dig_immediate = 2,
|
||||||
|
ud_param2_colorable = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tiles = { "lwsolid_conductor.png" },
|
||||||
|
mesecons =
|
||||||
|
{
|
||||||
|
conductor =
|
||||||
|
{
|
||||||
|
rules = mesecon.rules.flat,
|
||||||
|
state = mesecon.state.on,
|
||||||
|
offstate = "lwcomponents:solid_horizontal_conductor_off",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groups = {
|
||||||
|
dig_immediate = 2,
|
||||||
|
ud_param2_colorable = 1,
|
||||||
|
not_in_creative_inventory = 1
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unifieddyes.register_color_craft ({
|
||||||
|
output = "lwcomponents:solid_horizontal_conductor_off 3",
|
||||||
|
palette = "extended",
|
||||||
|
type = "shapeless",
|
||||||
|
neutral_node = "lwcomponents:solid_horizontal_conductor_off",
|
||||||
|
recipe = {
|
||||||
|
"NEUTRAL_NODE",
|
||||||
|
"NEUTRAL_NODE",
|
||||||
|
"NEUTRAL_NODE",
|
||||||
|
"MAIN_DYE"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end -- utils.unifieddyes_supported and utils.mesecon_supported and utils.digilines_supported then
|
131
utils.lua
Normal file
131
utils.lua
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
local utils, mod_storage = ...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if minetest.get_translator and minetest.get_translator ("lwcomponents") then
|
||||||
|
utils.S = minetest.get_translator ("lwcomponents")
|
||||||
|
elseif minetest.global_exists ("intllib") then
|
||||||
|
if intllib.make_gettext_pair then
|
||||||
|
utils.S = intllib.make_gettext_pair ()
|
||||||
|
else
|
||||||
|
utils.S = intllib.Getter ()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
utils.S = function (s) return s end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- check for mesecon
|
||||||
|
if minetest.global_exists ("mesecon") then
|
||||||
|
utils.mesecon_supported = true
|
||||||
|
utils.mesecon_state_on = mesecon.state.on
|
||||||
|
utils.mesecon_state_off = mesecon.state.off
|
||||||
|
utils.mesecon_receptor_on = mesecon.receptor_on
|
||||||
|
utils.mesecon_receptor_off = mesecon.receptor_off
|
||||||
|
utils.mesecon_default_rules = mesecon.rules.default
|
||||||
|
utils.mesecon_flat_rules = mesecon.rules.flat
|
||||||
|
|
||||||
|
else
|
||||||
|
utils.mesecon_supported = false
|
||||||
|
utils.mesecon_state_on = "on"
|
||||||
|
utils.mesecon_state_off = "off"
|
||||||
|
utils.mesecon_default_rules = { }
|
||||||
|
utils.mesecon_flat_rules = { }
|
||||||
|
|
||||||
|
-- dummies
|
||||||
|
utils.mesecon_receptor_on = function (pos, rules)
|
||||||
|
end
|
||||||
|
|
||||||
|
utils.mesecon_receptor_off = function (pos, rules)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- check for digilines
|
||||||
|
if minetest.global_exists ("digilines") then
|
||||||
|
utils.digilines_supported = true
|
||||||
|
utils.digilines_receptor_send = digilines.receptor_send
|
||||||
|
else
|
||||||
|
utils.digilines_supported = false
|
||||||
|
|
||||||
|
-- dummy
|
||||||
|
utils.digilines_receptor_send = function (pos, rules, channel, msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- check for lwdrops
|
||||||
|
if minetest.global_exists ("lwdrops") then
|
||||||
|
utils.lwdrops_supported = true
|
||||||
|
utils.on_destroy = lwdrops.on_destroy
|
||||||
|
utils.item_pickup = lwdrops.item_pickup
|
||||||
|
utils.item_drop = lwdrops.item_drop
|
||||||
|
else
|
||||||
|
utils.lwdrops_supported = false
|
||||||
|
|
||||||
|
-- dummy
|
||||||
|
utils.on_destroy = function (itemstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
utils.item_pickup = function (entity, cleanup)
|
||||||
|
local stack = nil
|
||||||
|
|
||||||
|
if entity and entity.name and entity.name == "__builtin:item" and
|
||||||
|
entity.itemstring and entity.itemstring ~= "" then
|
||||||
|
|
||||||
|
stack = ItemStack (entity.itemstring)
|
||||||
|
|
||||||
|
if cleanup ~= false then
|
||||||
|
entity.itemstring = ""
|
||||||
|
entity.object:remove ()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return stack
|
||||||
|
end
|
||||||
|
|
||||||
|
utils.item_drop = function (itemstack, dropper, pos)
|
||||||
|
return minetest.item_drop (itemstack, dropper, pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- check for unifieddyes
|
||||||
|
if minetest.global_exists ("unifieddyes") then
|
||||||
|
utils.unifieddyes_supported = true
|
||||||
|
else
|
||||||
|
utils.unifieddyes_supported = false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function utils.can_interact_with_node (pos, player)
|
||||||
|
if not player or not player:is_player () then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if minetest.check_player_privs (player, "protection_bypass") then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta (pos)
|
||||||
|
if meta then
|
||||||
|
local owner = meta:get_string ("owner")
|
||||||
|
local name = player:get_player_name ()
|
||||||
|
|
||||||
|
if not owner or owner == "" or owner == name then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
Reference in New Issue
Block a user