VoxeLibre/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua

405 lines
13 KiB
Lua

-- Function that get the input/output rules of the delayer
local delayer_get_output_rules = function(node)
local rules = {{x = -1, y = 0, z = 0, spread=true}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local delayer_get_input_rules = function(node)
local rules = {{x = 1, y = 0, z = 0}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
local delayer_get_all_rules = function(node)
local orules = delayer_get_output_rules(node)
local irules = delayer_get_input_rules(node)
return mesecon.mergetables(orules, irules)
end
-- Functions that are called after the delay time
local delayer_activate = function(pos, node)
local def = minetest.registered_nodes[node.name]
local time = def.delayer_time
minetest.swap_node(pos, {name=def.delayer_onstate, param2=node.param2})
mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil)
-- Lock repeater
local r = delayer_get_output_rules(node)[1]
local lpos = vector.add(pos, r)
local lnode = minetest.get_node(lpos)
local ldef = minetest.registered_nodes[lnode.name]
local g = minetest.get_item_group(lnode.name, "redstone_repeater")
if g >= 1 and g <= 4 then
local lrs = delayer_get_input_rules(lnode)
local fail = false
for _, lr in pairs(lrs) do
if lr.x == r.x or lr.z == r.z then
fail = true
break
end
end
if not fail then
minetest.swap_node(lpos, {name=ldef.delayer_lockstate, param2=lnode.param2})
end
end
end
local delayer_deactivate = function(pos, node)
local def = minetest.registered_nodes[node.name]
local time = def.delayer_time
minetest.swap_node(pos, {name=def.delayer_offstate, param2=node.param2})
mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil)
-- Unlock repeater
local r = delayer_get_output_rules(node)[1]
local lpos = vector.add(pos, r)
local lnode = minetest.get_node(lpos)
local ldef = minetest.registered_nodes[lnode.name]
local g = minetest.get_item_group(lnode.name, "redstone_repeater")
if g == 5 then
local lrs = delayer_get_input_rules(lnode)
local fail = false
for _, lr in pairs(lrs) do
if lr.x == r.x or lr.z == r.z then
fail = true
break
end
end
if not fail then
if mesecon.is_powered(lpos) then
minetest.swap_node(lpos, {name="mesecons_delayer:delayer_on_1", param2=lnode.param2})
mesecon.queue:add_action(lpos, "receptor_on", {delayer_get_output_rules(lnode)}, ldef.delayer_time, nil)
else
minetest.swap_node(lpos, {name="mesecons_delayer:delayer_off_1", param2=lnode.param2})
mesecon.queue:add_action(lpos, "receptor_off", {delayer_get_output_rules(lnode)}, ldef.delayer_time, nil)
end
end
end
end
-- Register the 2 (states) x 4 (delay times) delayers
for i = 1, 4 do
local groups = {}
if i == 1 then
groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i}
else
groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i,not_in_creative_inventory=1}
end
local delaytime
if i == 1 then delaytime = 0.1
elseif i == 2 then delaytime = 0.2
elseif i == 3 then delaytime = 0.3
elseif i == 4 then delaytime = 0.4
end
local boxes
if i == 1 then
boxes = {
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
{ -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
{ -1/16, -6/16, 0/16, 1/16, -1/16, 2/16}, -- moved torch
}
elseif i == 2 then
boxes = {
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
{ -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
{ -1/16, -6/16, -2/16, 1/16, -1/16, 0/16}, -- moved torch
}
elseif i == 3 then
boxes = {
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
{ -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
{ -1/16, -6/16, -4/16, 1/16, -1/16, -2/16}, -- moved torch
}
elseif i == 4 then
boxes = {
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
{ -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
{ -1/16, -6/16, -6/16, 1/16, -1/16, -4/16}, -- moved torch
}
end
local help, longdesc, usagehelp, icon
if i == 1 then
help = true
longdesc = "Redstone repeaters are versatile redstone components which delay redstone signals and only allow redstone signals to travel through one direction. The delay of the signal is indicated by the redstone torches and is between 0.1 and 0.4 seconds long."
usagehelp = "To power a redstone repeater, send a signal in “arrow” direction. To change the delay, rightclick the redstone repeater. The delay is changed in steps of 0.1 seconds."
icon = "mesecons_delayer_item.png"
else
help = false
end
local on_rotate
if minetest.get_modpath("screwdriver") then
on_rotate = screwdriver.disallow
end
minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
description = "Redstone Repeater",
inventory_image = icon,
wield_image = icon,
_doc_items_create_entry = help,
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = usagehelp,
drawtype = "nodebox",
tiles = {
"mesecons_delayer_off.png",
"mcl_stairs_stone_slab_top.png",
"mesecons_delayer_sides_off.png",
"mesecons_delayer_sides_off.png",
"mesecons_delayer_ends_off.png",
"mesecons_delayer_ends_off.png",
},
wield_image = "mesecons_delayer_off.png",
walkable = true,
selection_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
collision_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
node_box = {
type = "fixed",
fixed = boxes
},
groups = groups,
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = false,
is_ground_content = false,
drop = 'mesecons_delayer:delayer_off_1',
on_rightclick = function (pos, node)
if node.name=="mesecons_delayer:delayer_off_1" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_2", param2=node.param2})
elseif node.name=="mesecons_delayer:delayer_off_2" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_3", param2=node.param2})
elseif node.name=="mesecons_delayer:delayer_off_3" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_4", param2=node.param2})
elseif node.name=="mesecons_delayer:delayer_off_4" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_1", param2=node.param2})
end
end,
delayer_time = delaytime,
delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
delayer_lockstate = "mesecons_delayer:delayer_off_locked",
sounds = mcl_sounds.node_sound_stone_defaults(),
mesecons = {
receptor =
{
state = mesecon.state.off,
rules = delayer_get_output_rules
},
effector =
{
rules = delayer_get_input_rules,
action_on = delayer_activate
}
},
on_rotate = on_rotate,
})
minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
description = "Redstone Repeater (Powered)",
_doc_items_create_entry = false,
drawtype = "nodebox",
tiles = {
"mesecons_delayer_on.png",
"mcl_stairs_stone_slab_top.png",
"mesecons_delayer_sides_on.png",
"mesecons_delayer_sides_on.png",
"mesecons_delayer_ends_on.png",
"mesecons_delayer_ends_on.png",
},
walkable = true,
selection_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
collision_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
node_box = {
type = "fixed",
fixed = boxes
},
groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=i, not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = false,
is_ground_content = false,
drop = 'mesecons_delayer:delayer_off_1',
on_rightclick = function (pos, node)
if node.name=="mesecons_delayer:delayer_on_1" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_2",param2=node.param2})
elseif node.name=="mesecons_delayer:delayer_on_2" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_3",param2=node.param2})
elseif node.name=="mesecons_delayer:delayer_on_3" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_4",param2=node.param2})
elseif node.name=="mesecons_delayer:delayer_on_4" then
minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_1",param2=node.param2})
end
end,
delayer_time = delaytime,
delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
delayer_lockstate = "mesecons_delayer:delayer_on_locked",
sounds = mcl_sounds.node_sound_stone_defaults(),
mesecons = {
receptor =
{
state = mesecon.state.on,
rules = delayer_get_output_rules
},
effector =
{
rules = delayer_get_input_rules,
action_off = delayer_deactivate
}
},
on_rotate = on_rotate,
})
end
-- Locked repeater
minetest.register_node("mesecons_delayer:delayer_off_locked", {
description = "Redstone Repeater (Locked)",
inventory_image = icon,
wield_image = icon,
_doc_items_create_entry = false,
drawtype = "nodebox",
-- FIXME: Textures of torch and the lock bar overlap. Nodeboxes are (sadly) not suitable for this.
-- So this needs to be turned into a mesh.
tiles = {
"mesecons_delayer_locked_off.png",
"mcl_stairs_stone_slab_top.png",
"mesecons_delayer_sides_locked_off.png",
"mesecons_delayer_sides_locked_off.png",
"mesecons_delayer_front_locked_off.png",
"mesecons_delayer_end_locked_off.png",
},
wield_image = "mesecons_delayer_locked_off.png",
walkable = true,
selection_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
collision_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
node_box = {
type = "fixed",
fixed = {
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
{ -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
{ -6/16, -6/16, 0/16, 6/16, -4/16, 2/16}, -- lock
}
},
groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=5, not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = false,
is_ground_content = false,
drop = 'mesecons_delayer:delayer_off_1',
delayer_time = 0.1,
sounds = mcl_sounds.node_sound_stone_defaults(),
mesecons = {
receptor =
{
state = mesecon.state.off,
rules = delayer_get_output_rules
},
effector =
{
rules = delayer_get_input_rules,
}
},
on_rotate = on_rotate,
})
minetest.register_node("mesecons_delayer:delayer_on_locked", {
description = "Redstone Repeater (Locked, Powered)",
_doc_items_create_entry = false,
drawtype = "nodebox",
tiles = {
"mesecons_delayer_locked_on.png",
"mcl_stairs_stone_slab_top.png",
"mesecons_delayer_sides_locked_on.png",
"mesecons_delayer_sides_locked_on.png",
"mesecons_delayer_front_locked_on.png",
"mesecons_delayer_end_locked_on.png",
},
walkable = true,
selection_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
collision_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
},
node_box = {
type = "fixed",
fixed = {
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
{ -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
{ -6/16, -6/16, 0/16, 6/16, -4/16, 2/16}, -- lock
}
},
groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=5, not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = false,
is_ground_content = false,
drop = 'mesecons_delayer:delayer_off_1',
delayer_time = 0.1,
sounds = mcl_sounds.node_sound_stone_defaults(),
mesecons = {
receptor =
{
state = mesecon.state.on,
rules = delayer_get_output_rules
},
effector =
{
rules = delayer_get_input_rules,
}
},
on_rotate = on_rotate,
})
minetest.register_craft({
output = "mesecons_delayer:delayer_off_1",
recipe = {
{"mesecons_torch:mesecon_torch_on", "mesecons:redstone", "mesecons_torch:mesecon_torch_on"},
{"mcl_core:stone","mcl_core:stone", "mcl_core:stone"},
}
})
-- Add entry aliases for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_2")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_3")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_4")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_locked")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_1")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_2")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_3")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_4")
doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_locked")
end