basic_machines/mover.lua
2015-05-18 17:46:26 +02:00

1144 lines
48 KiB
Lua

------------------------------------------------------------------------------------------------------------------------------------
-- BASIC MACHINES MOD by rnd
-- mod with basic simple automatization for minetest. No background processing, just one abm with 5s timer, no other lag causing background processing.
------------------------------------------------------------------------------------------------------------------------------------
-- MOVER: universal moving machine, requires coal in nearby chest to operate
-- can take item from chest and place it in chest or as a node outside at ranges -5,+5
-- it can be used for filtering by setting "filter". if set to "object" it will teleport all objects at start location.
-- if set to "drop" it will drop node at target location, if set to "dig" it will dig out nodes and return appropriate drops.
-- input is: where to take and where to put
-- to operate mese power is needed
-- KEYPAD: can serve as a button to activate machines ( partially mesecons compatible ). Can be password protected. Can serve as a
-- replacement for mesecons blinky plant, limited to max 100 operations.
-- As a simple example it can be used to open doors, which close automatically after 5 seconds.
local punchset = {};
local max_range = 10; -- machines range of operation
local machines_timer = 5 -- timestep
local machines_TTL = 4; -- time to live for signals
MOVER_FUEL_STORAGE_CAPACITY = 5; -- how many operations from one coal lump - base unit
minetest.register_node("basic_machines:mover", {
description = "Mover",
tiles = {"compass_top.png","default_furnace_top.png"},
groups = {oddly_breakable_by_hand=2,mesecon_effector_on = 1},
sounds = default.node_sound_wood_defaults(),
after_place_node = function(pos, placer)
local meta = minetest.env:get_meta(pos)
meta:set_string("infotext", "Mover block. Right click to set it up. Or set positions by punching it.")
meta:set_string("owner", placer:get_player_name()); meta:set_int("public",0);
meta:set_int("x0",0);meta:set_int("y0",-1);meta:set_int("z0",0); -- source1
meta:set_int("x1",0);meta:set_int("y1",-1);meta:set_int("z1",0); -- source2: defines cube
meta:set_int("pc",0); meta:set_int("dim",1);-- current cube position and dimensions
meta:set_int("x2",0);meta:set_int("y2",1);meta:set_int("z2",0);
meta:set_float("fuel",0)
meta:set_string("prefer", "");
local inv = meta:get_inventory();inv:set_size("mode", 5*1)
inv:set_stack("mode", 1, ItemStack("default:coal_lump"))
local name = placer:get_player_name(); punchset[name].state = 0
end,
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
local meta = minetest.get_meta(pos);
local privs = minetest.get_player_privs(player:get_player_name());
if meta:get_string("owner")~=player:get_player_name() and not privs.privs then return end -- only owner can set up mover
local x0,y0,z0,x1,y1,z1,x2,y2,z2,prefer,mode;
x0=meta:get_int("x0");y0=meta:get_int("y0");z0=meta:get_int("z0");
x1=meta:get_int("x1");y1=meta:get_int("y1");z1=meta:get_int("z1");
x2=meta:get_int("x2");y2=meta:get_int("y2");z2=meta:get_int("z2");
machines.pos1[player:get_player_name()] = {x=pos.x+x1,y=pos.y+y1,z=pos.z+z1};
machines.mark_pos1(player:get_player_name()) -- mark pos1
machines.pos2[player:get_player_name()] = {x=pos.x+x2,y=pos.y+y2,z=pos.z+z2};
machines.mark_pos2(player:get_player_name()) -- mark pos2
prefer = meta:get_string("prefer");mode = meta:get_string("mode");
local list_name = "nodemeta:"..pos.x..','..pos.y..','..pos.z
local form =
"size[5,5.5]" .. -- width, height
--"size[6,10]" .. -- width, height
"field[0.25,0.5;1,1;x0;source1;"..x0.."] field[1.25,0.5;1,1;y0;;"..y0.."] field[2.25,0.5;1,1;z0;;"..z0.."]"..
"field[0.25,1.5;1,1;x1;source2;"..x1.."] field[1.25,1.5;1,1;y1;;"..y1.."] field[2.25,1.5;1,1;z1;;"..z1.."]"..
"field[0.25,2.5;1,1;x2;Target;"..x2.."] field[1.25,2.5;1,1;y2;;"..y2.."] field[2.25,2.5;1,1;z2;;"..z2.."]"..
"button_exit[3,3.25;1,1;OK;OK] field[0.25,3.5;3,1;prefer;filter only block;"..prefer.."]"..
"button[3,2.25;1,1;help;help]"..
"label[0.,4.0;MODE: normal,dig,drop,reverse,object]"..
"list["..list_name..";mode;0.,4.5;6,1;]"--..
--"field[0.25,4.5;2,1;mode;mode;"..mode.."]";
minetest.show_formspec(player:get_player_name(), "basic_machines:mover_"..minetest.pos_to_string(pos), form)
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
return 0
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
return 0
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
--minetest.chat_send_all("mover inventory: moved from pos ".. from_index .. " to pos " .. to_index )
local meta = minetest.get_meta(pos);
local mode = "";
if to_index == 1 then
meta:set_string("mode","")
elseif to_index==2 then mode = "dig"
elseif to_index==3 then mode = "drop"
elseif to_index==4 then mode = "reverse"
elseif to_index==5 then mode = "object"
end
meta:set_string("mode",mode)
if mode == "" then mode = "normal" end; minetest.chat_send_player(player:get_player_name(), "MOVER: Mode of operation set to: "..mode)
return count
end,
mesecons = {effector = {
action_on = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
local meta = minetest.get_meta(pos);
local fuel = meta:get_float("fuel");
--minetest.chat_send_all("mover mesecons: runnning with pos " .. pos.x .. " " .. pos.y .. " " .. pos.z)
local x0,y0,z0,x1,y1,z1;
x0=meta:get_int("x0");y0=meta:get_int("y0");z0=meta:get_int("z0");
local pos1 = {x=x0+pos.x,y=y0+pos.y,z=z0+pos.z}; -- where to take from
local pos2 = {x=meta:get_int("x2")+pos.x,y=meta:get_int("y2")+pos.y,z=meta:get_int("z2")+pos.z}; -- where to put
local pc = meta:get_int("pc"); local dim = meta:get_int("dim"); pc = (pc+1) % dim;meta:set_int("pc",pc) -- cycle position
x1=meta:get_int("x1")-x0+1;y1=meta:get_int("y1")-y0+1;z1=meta:get_int("z1")-z0+1; -- get dimensions
--pc = z*a*b+x*b+y, from x,y,z to pc
-- set current input position
pos1.y = y0 + (pc % y1); pc = (pc - (pc % y1))/y1;
pos1.x = x0 + (pc % x1); pc = (pc - (pc % x1))/x1;
pos1.z = z0 + pc;
pos1.x = pos.x+pos1.x;pos1.y = pos.y+pos1.y;pos1.z = pos.z+pos1.z;
if fuel<=0 then -- needs fuel to operate, find nearby open chest with fuel within radius 1
local found_fuel = nil;
local r = 1;local positions = minetest.find_nodes_in_area( --find furnace with fuel
{x=pos.x-r, y=pos.y-r, z=pos.z-r},
{x=pos.x+r, y=pos.y+r, z=pos.z+r},
"default:chest_locked")
local fpos = nil;
for _, p in ipairs(positions) do
-- dont take coal from source or target location
if (p.x ~= pos1.x or p.y~=pos1.y or p.z ~= pos1.z) and (p.x ~= pos2.x or p.y~=pos2.y or p.z ~= pos2.z) then
fpos = p;
end
end
if not fpos then return end -- no chest found
local cmeta = minetest.get_meta(fpos);
local inv = cmeta:get_inventory();
--fuels and their caloric value: 1 = 5 uses
local fuels = {["default:coal_lump"]=1,["default:cactus"]=0.75,["default:coalblock"]=10,["default:lava_source"]=40};
local stack;
for i,v in pairs(fuels) do
stack = ItemStack({name=i})
if inv:contains_item("main", stack) then found_fuel = v break end
end
-- check for this fuel
if found_fuel~=nil then
--minetest.chat_send_all(" refueled ")
inv:remove_item("main", stack)
meta:set_float("fuel", fuel+MOVER_FUEL_STORAGE_CAPACITY*found_fuel);
fuel = fuel+MOVER_FUEL_STORAGE_CAPACITY*found_fuel;
meta:set_string("infotext", "Mover block refueled. Fuel "..MOVER_FUEL_STORAGE_CAPACITY);
else meta:set_string("infotext", "Mover block. Out of fuel. Put fuel chest so that it touches mover.");return
end
--check fuel
if fuel == 0 then return end
end
local owner = meta:get_string("owner");
-- check protections
if minetest.is_protected(pos1, owner) or minetest.is_protected(pos2, owner) then
meta:set_float("fuel", -1);
meta:set_string("infotext", "Mover block. Protection fail. Deactivated.")
return end
local prefer = meta:get_string("prefer"); local mode = meta:get_string("mode");
if mode == "reverse" then -- reverse pos1, pos2
local post = {x=pos1.x,y=pos1.y,z=pos1.z};
pos1 = {x=pos2.x,y=pos2.y,z=pos2.z};
pos2 = {x=post.x,y=post.y,z=post.z};
end
local node1 = minetest.get_node(pos1);local node2 = minetest.get_node(pos2);
if mode == "object" then -- teleport objects, for free
for _,obj in pairs(minetest.get_objects_inside_radius(pos1, 2)) do
obj:moveto(pos2, false)
end
minetest.sound_play("transporter", {pos=pos2,gain=1.0,max_hear_distance = 32,})
--meta:set_float("fuel", fuel - 1);
return
end
local dig=false; if mode == "dig" then dig = true; end -- digs at target location
local drop = false; if mode == "drop" then drop = true; end -- drops node instead of placing it
-- decide what to do if source or target are chests
local source_chest=false; if string.find(node1.name,"default:chest") then source_chest=true end
if node1.name == "air" then return end -- nothing to move
local target_chest = false
if node2.name == "default:chest" or node2.name == "default:chest_locked" then
target_chest = true
end
if not target_chest and minetest.get_node(pos2).name ~= "air" then return end -- do nothing if target nonempty and not chest
-- filtering
if prefer~="" then -- prefered node set
if prefer~=node1.name and not source_chest then return end -- only take prefered node or from chests
if source_chest then -- take stuff from chest
--minetest.chat_send_all(" source chest detected")
local cmeta = minetest.get_meta(pos1);
local inv = cmeta:get_inventory();
local stack = ItemStack(prefer)
if inv:contains_item("main", stack) then
inv:remove_item("main", stack);
else return
end
end
node1 = {}; node1.name = prefer;
end
if source_chest and prefer == "" then return end -- doesnt know what to take out of chest
--minetest.chat_send_all(" moving ")
-- if target chest put in chest
if target_chest then
local cmeta = minetest.get_meta(pos2);
local inv = cmeta:get_inventory();
-- dig tree or cactus
local count = 0;-- check for cactus or tree
local dig_up = false;
if dig then
-- define which nodes are dug up completely, like a tree
local dig_up_table = {["default:cactus"]=true,["default:tree"]=true,["default:jungletree"]=true,["default:papyrus"]=true};
if not source_chest and dig_up_table[node1.name] then dig_up = true end
if dig_up == true then -- dig up to height 10, break sooner if needed
for i=0,10 do
local pos3 = {x=pos1.x,y=pos1.y+i,z=pos1.z};
local dname= minetest.get_node(pos3).name;
if dname ~=node1.name then break end
minetest.set_node(pos3,{name="air"}); count = count+1;
end
end
-- read what to drop, if none just keep original node
local table = minetest.registered_items[node1.name];
if table~=nil then
if table.drop~= nil and table.drop~="" then
node1={}; node1.name = table.drop;
end
end
end
local stack = ItemStack(node1.name)
if dig_up then
stack = ItemStack(node1.name .. " " .. count) -- if tree or cactus was digged up
end
if inv:room_for_item("main", stack) then
inv:add_item("main", stack);
end
end
minetest.sound_play("transporter", {pos=pos2,gain=1.0,max_hear_distance = 32,})
if not(target_chest and source_chest) then -- chest to chest transport is free
fuel = fuel -1; meta:set_float("fuel", fuel); -- burn fuel
end
meta:set_string("infotext", "Mover block. Fuel "..fuel);
if not target_chest then
if not drop then minetest.set_node(pos2, {name = node1.name}); end
if drop then
local stack = ItemStack(node1.name);minetest.add_item(pos2,stack) -- drops it
end
end
if not source_chest then
if dig then nodeupdate(pos1) end
minetest.set_node(pos1, {name = "air"});
end
end
}
}
})
-- KEYPAD
local function use_keypad(pos,ttl) -- position, time to live ( how many times can signal travel before vanishing to prevent infinite recursion )
local meta = minetest.get_meta(pos);
local name = meta:get_string("owner");
if minetest.is_protected(pos,name) then meta:set_string("infotext", "Protection fail. reset."); meta:set_int("count",0) end
local count = meta:get_int("count") or 0;
if count<=0 and ttl<0 then return end;
count = count - 1; meta:set_int("count",count);
if count>=0 then
meta:set_string("infotext", "Keypad operation: ".. count .." cycles left")
else
meta:set_string("infotext", "Keypad operation: activation ".. -count)
end
if count>0 then -- only trigger repeat if count on
minetest.after(machines_timer, function() use_keypad(pos,machines_TTL) end ) -- repeat operation as many times as set with "iter"
end
local x0,y0,z0,mode;
x0=meta:get_int("x0");y0=meta:get_int("y0");z0=meta:get_int("z0");
x0=pos.x+x0;y0=pos.y+y0;z0=pos.z+z0;
mode = meta:get_int("mode");
--minetest.chat_send_all("KEYPAD USED. TARGET ".. x0 .. " " .. y0 .. " " .. z0);
-- pass the signal on to target, depending on mode
local tpos = {x=x0,y=y0,z=z0};
local node = minetest.get_node(tpos);if not node.name then return end -- error
local table = minetest.registered_nodes[node.name];
if not table then return end -- error
if not table.mesecons then return end -- error
if not table.mesecons.effector then return end -- error
local effector=table.mesecons.effector;
-- pass the signal on to target
if mode == 1 then
if not effector.action_on then return end
effector.action_on(tpos,node,ttl-1); -- run
else
if not effector.action_off then return end
effector.action_off(tpos,node,ttl-1); -- run
end
--minetest.chat_send_all("MESECONS RUN")
end
local function check_keypad(pos,name,ttl) -- called only when manually activated via punch
local meta = minetest.get_meta(pos);
local pass = meta:get_string("pass");
if pass == "" then
meta:set_int("count",meta:get_int("iter")); use_keypad(pos,machines_TTL) -- time to live is 3 when punched
return
end
if name == "" then return end
pass = ""
local form =
"size[3,1]" .. -- width, height
"button[0.,0.5;1,1;OK;OK] field[0.25,0.25;3,1;pass;Enter Password: ;".."".."]";
minetest.show_formspec(name, "basic_machines:check_keypad_"..minetest.pos_to_string(pos), form)
end
minetest.register_node("basic_machines:keypad", {
description = "Keypad",
tiles = {"keypad.png"},
groups = {oddly_breakable_by_hand=2},
sounds = default.node_sound_wood_defaults(),
after_place_node = function(pos, placer)
local meta = minetest.env:get_meta(pos)
meta:set_string("infotext", "Keypad. Right click to set it up or punch it.")
meta:set_string("owner", placer:get_player_name()); meta:set_int("public",1);
meta:set_int("x0",0);meta:set_int("y0",0);meta:set_int("z0",0); -- target
meta:set_string("pass", "");meta:set_int("mode",1); -- pasword, mode of operation
meta:set_int("iter",1);meta:set_int("count",0); -- max repeats, repeat count
local name = placer:get_player_name();punchset[name] = {};punchset[name].state = 0
end,
mesecons = {effector = {
action_on = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
if ttl<0 then return end -- machines_TTL prevents infinite recursion
use_keypad(pos,ttl-1);
end
}
},
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
local meta = minetest.get_meta(pos);
local privs = minetest.get_player_privs(player:get_player_name());
if meta:get_string("owner")~= player:get_player_name() and not privs.privs then return end -- only owner can setup keypad
local x0,y0,z0,x1,y1,z1,pass,iter,mode;
x0=meta:get_int("x0");y0=meta:get_int("y0");z0=meta:get_int("z0");iter=meta:get_int("iter") or 1;
mode = meta:get_int("mode") or 1;
machines.pos1[player:get_player_name()] = {x=pos.x+x0,y=pos.y+y0,z=pos.z+z0};machines.mark_pos1(player:get_player_name()) -- mark pos1
pass = meta:get_string("pass");
local form =
"size[3,2.75]" .. -- width, height
"field[0.25,0.5;1,1;x0;target;"..x0.."] field[1.25,0.5;1,1;y0;;"..y0.."] field[2.25,0.5;1,1;z0;;"..z0.."]"..
"button_exit[0.,2.25;1,1;OK;OK] field[0.25,1.5;2,1;pass;Password: ;"..pass.."]" .. "field[1.25,2.5;2,1;iter;Repeat;".. iter .."]"..
"field[2.25,1.5;1,1;mode;ON/OFF: ;"..mode.."]"
minetest.show_formspec(player:get_player_name(), "basic_machines:keypad_"..minetest.pos_to_string(pos), form)
end
})
-- DETECTOR
minetest.register_node("basic_machines:detector", {
description = "Detector",
tiles = {"detector.png"},
groups = {oddly_breakable_by_hand=2},
sounds = default.node_sound_wood_defaults(),
after_place_node = function(pos, placer)
local meta = minetest.env:get_meta(pos)
meta:set_string("infotext", "Detector. Right click/punch to set it up.")
meta:set_string("owner", placer:get_player_name()); meta:set_int("public",0);
meta:set_int("x1",0);meta:set_int("y1",0);meta:set_int("z0",0); -- source: read
meta:set_int("x2",0);meta:set_int("y2",0);meta:set_int("z2",0); -- target: activate
meta:set_int("r",0)
meta:set_string("node","");meta:set_int("NOT",0);meta:set_string("mode","node");
meta:set_int("public",0);
local inv = meta:get_inventory();inv:set_size("mode_select", 2*1)
inv:set_stack("mode_select", 1, ItemStack("default:coal_lump"))
local name = placer:get_player_name();punchset[name] = {}; punchset[name].node = ""; punchset[name].state = 0
end,
mesecons = {effector = {
action_on = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
if ttl<0 then return end -- prevent infinite recursion
local meta = minetest.get_meta(pos);
-- not yet defined ... ???
end
}
},
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
local meta = minetest.get_meta(pos);
local privs = minetest.get_player_privs(player:get_player_name());
if meta:get_string("owner")~= player:get_player_name() and not privs.privs then return end -- only owner can setup keypad
local x0,y0,z0,x1,y1,z1,r,node,NOT;
x0=meta:get_int("x0");y0=meta:get_int("y0");z0=meta:get_int("z0");
x1=meta:get_int("x1");y1=meta:get_int("y1");z1=meta:get_int("z1");r=meta:get_int("r");
machines.pos1[player:get_player_name()] = {x=pos.x+x0,y=pos.y+y0,z=pos.z+z0};machines.mark_pos1(player:get_player_name()) -- mark pos1
machines.pos2[player:get_player_name()] = {x=pos.x+x1,y=pos.y+y1,z=pos.z+z1};machines.mark_pos2(player:get_player_name()) -- mark pos2
node=meta:get_string("node") or "";
NOT=meta:get_int("NOT");
local list_name = "nodemeta:"..pos.x..','..pos.y..','..pos.z
local form =
"size[4,4.25]" .. -- width, height
"field[0.25,0.5;1,1;x0;source;"..x0.."] field[1.25,0.5;1,1;y0;;"..y0.."] field[2.25,0.5;1,1;z0;;"..z0.."]"..
"field[0.25,1.5;1,1;x1;target;"..x1.."] field[1.25,1.5;1,1;y1;;"..y1.."] field[2.25,1.5;1,1;z1;;"..z1.."]"..
"button[3.,3.25;1,1;OK;OK] field[0.25,2.5;2,1;node;Node/player: ;"..node.."]".."field[3.25,1.5;1,1;r;radius;"..r.."]"..
"button[3.,0.25;1,1;help;help]"..
"label[0.,3.0;MODE: node,player]".. "list["..list_name..";mode_select;0.,3.5;3,1;]"..
"field[3.25,2.5;1,1;NOT;NOT 0/1;"..NOT.."]"
minetest.show_formspec(player:get_player_name(), "basic_machines:detector_"..minetest.pos_to_string(pos), form)
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
return 0
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
return 0
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
--minetest.chat_send_all("mover inventory: moved from pos ".. from_index .. " to pos " .. to_index )
local meta = minetest.get_meta(pos);
local mode = "node";
if to_index == 2 then
mode = "player";
meta:set_int("r",math.max(meta:get_int("r"),1))
end
meta:set_string("mode",mode)
minetest.chat_send_player(player:get_player_name(), "DETECTOR: Mode of operation set to: "..mode)
return count
end,
})
minetest.register_abm({
nodenames = {"basic_machines:detector"},
neighbors = {""},
interval = machines_timer,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos);
local x0,y0,z0,x1,y1,z1,r,node,NOT,mode;
x0=meta:get_int("x0")+pos.x;y0=meta:get_int("y0")+pos.y;z0=meta:get_int("z0")+pos.z;
x1=meta:get_int("x1")+pos.x;y1=meta:get_int("y1")+pos.y;z1=meta:get_int("z1")+pos.z;
r = meta:get_int("r") or 0; NOT = meta:get_int("NOT")
node=meta:get_string("node") or ""; mode=meta:get_string("mode") or "";
local trigger = false
if mode == "node" then
local tnode = minetest.get_node({x=x0,y=y0,z=z0}).name; -- read node at source position
if node~="" and string.find(tnode,"default:chest") then -- it source is chest, look inside chest for items
local cmeta = minetest.get_meta({x=x0,y=y0,z=z0});
local inv = cmeta:get_inventory();
local stack = ItemStack(node)
if inv:contains_item("main", stack) then trigger = true end
else -- source not a chest
if (node=="" and tnode~="air") or node == tnode then trigger = true end
if r>0 and node~="" then
local found_node = minetest.find_node_near({x=x0, y=y0, z=z0}, r, {node})
if node ~= "" and found_node then trigger = true end
end
end
if NOT == 1 then trigger = not trigger end
else
local objects = minetest.get_objects_inside_radius({x=x0,y=y0,z=z0}, r)
for _,obj in pairs(objects) do
if obj:is_player() and (node=="" or obj:get_player_name()==node) then trigger = true break end
end
if NOT == 1 then trigger = not trigger end
end
local node = minetest.get_node({x=x1,y=y1,z=z1});if not node.name then return end -- error
local table = minetest.registered_nodes[node.name];
if not table then return end -- error
if not table.mesecons then return end -- error
if not table.mesecons.effector then return end -- error
local effector=table.mesecons.effector;
if trigger then -- activate target node if succesful
meta:set_string("infotext", "detector: on");
if not effector.action_on then return end
effector.action_on({x=x1,y=y1,z=z1},node,3); -- run
else
meta:set_string("infotext", "detector: idle");
if not effector.action_off then return end
effector.action_off({x=x1,y=y1,z=z1},node,3); -- run
end
end,
})
-- DISTRIBUTOR: spreads one signal to two outputs
minetest.register_node("basic_machines:distributor", {
description = "Distributor",
tiles = {"distributor.png"},
groups = {oddly_breakable_by_hand=2},
sounds = default.node_sound_wood_defaults(),
after_place_node = function(pos, placer)
local meta = minetest.env:get_meta(pos)
meta:set_string("infotext", "Distributor. Right click/punch to set it up.")
meta:set_string("owner", placer:get_player_name()); meta:set_int("public",0);
meta:set_int("x1",0);meta:set_int("y1",0);meta:set_int("z0",0);meta:set_int("active1",1) -- target1
meta:set_int("x2",0);meta:set_int("y2",0);meta:set_int("z2",0);meta:set_int("active2",0) -- target2
meta:set_int("public",0); -- can other ppl set it up?
local name = placer:get_player_name();punchset[name] = {}; punchset[name].node = ""; punchset[name].state = 0
end,
mesecons = {effector = {
action_on = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
if not(ttl>0) then return end
local meta = minetest.get_meta(pos);
local x1,y1,z1,x2,y2,z2,active1,active2
x1=meta:get_int("x1")+pos.x;y1=meta:get_int("y1")+pos.y;z1=meta:get_int("z1")+pos.z;active1=meta:get_int("active1");
x2=meta:get_int("x2")+pos.x;y2=meta:get_int("y2")+pos.y;z2=meta:get_int("z2")+pos.z;active2=meta:get_int("active2");
local node, table
if active1~=0 then
node = minetest.get_node({x=x1,y=y1,z=z1});if not node.name then return end -- error
table = minetest.registered_nodes[node.name];
if not table then return end -- error
if not table.mesecons then return end -- error
if not table.mesecons.effector then return end -- error
local effector=table.mesecons.effector;
if active1 == 1 and effector.action_on then effector.action_on({x=x1,y=y1,z=z1},node,ttl-1);
elseif active1 == -1 and effector.action_off then effector.action_off({x=x1,y=y1,z=z1},node,ttl-1);
end
end
if active2~=0 then
node = minetest.get_node({x=x2,y=y2,z=z2});if not node.name then return end -- error
table = minetest.registered_nodes[node.name];
if not table then return end -- error
if not table.mesecons then return end -- error
if not table.mesecons.effector then return end -- error
local effector=table.mesecons.effector;
if active2 == 1 and effector.action_on then effector.action_on({x=x2,y=y2,z=z2},node,ttl-1);
elseif active2 == -1 and effector.action_off then effector.action_off({x=x2,y=y2,z=z2},node,ttl-1);
end
end
end,
action_off = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
if ttl<0 then return end
local meta = minetest.get_meta(pos);
local x1,y1,z1,x2,y2,z2,active1,active2
x1=meta:get_int("x1")+pos.x;y1=meta:get_int("y1")+pos.y;z1=meta:get_int("z1")+pos.z;active1=meta:get_int("active1");
x2=meta:get_int("x2")+pos.x;y2=meta:get_int("y2")+pos.y;z2=meta:get_int("z2")+pos.z;active2=meta:get_int("active2");
local node, table
node = nil;
if active1~=0 then
node = minetest.get_node({x=x1,y=y1,z=z1});if not node.name then return end -- error
table = minetest.registered_nodes[node.name];
if not table then return end -- error
if not table.mesecons then return end -- error
if not table.mesecons.effector then return end -- error
local effector=table.mesecons.effector;
if active1 == 1 and effector.action_off then effector.action_off({x=x1,y=y1,z=z1},node,ttl-1);
elseif active1 == -1 and effector.action_on then effector.action_on({x=x1,y=y1,z=z1},node,ttl-1);
end
end
if active2~=0 then
node = minetest.get_node({x=x2,y=y2,z=z2});if not node.name then return end -- error
table = minetest.registered_nodes[node.name];
if not table then return end -- error
if not table.mesecons then return end -- error
if not table.mesecons.effector then return end -- error
local effector=table.mesecons.effector;
if active2 == 1 and effector.action_off then effector.action_off({x=x2,y=y2,z=z2},node,ttl-1);
elseif active2 == -1 and effector.action_on then effector.action_on({x=x2,y=y2,z=z2},node,ttl-1);
end
end
end
}
},
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
local meta = minetest.get_meta(pos);
local privs = minetest.get_player_privs(player:get_player_name());
if meta:get_string("owner")~= player:get_player_name() and not privs.privs then return end -- only owner can setup keypad
local x1,y1,z1,x2,y2,z2,active1,active2
x1=meta:get_int("x1");y1=meta:get_int("y1");z1=meta:get_int("z1");active1=meta:get_int("active1");
x2=meta:get_int("x2");y2=meta:get_int("y2");z2=meta:get_int("z2");active2=meta:get_int("active2");
machines.pos1[player:get_player_name()] = {x=pos.x+x1,y=pos.y+y1,z=pos.z+z1};machines.mark_pos1(player:get_player_name()) -- mark pos1
machines.pos2[player:get_player_name()] = {x=pos.x+x2,y=pos.y+y2,z=pos.z+z2};machines.mark_pos2(player:get_player_name()) -- mark pos2
local list_name = "nodemeta:"..pos.x..','..pos.y..','..pos.z
local form =
"size[4,2.5]" .. -- width, height
"label[0,-0.25;target1: x y z, Active -1/0/1]"..
"field[0.25,0.5;1,1;x1;;"..x1.."] field[1.25,0.5;1,1;y1;;"..y1.."] field[2.25,0.5;1,1;z1;;"..z1.."] field [ 3.25,0.5;1,1;active1;;" .. active1 .. "]"..
"field[0.25,1.5;1,1;x2;target2;"..x2.."] field[1.25,1.5;1,1;y2;;"..y2.."] field[2.25,1.5;1,1;z2;;"..z2.."] field [ 3.25,1.5;1,1;active2;;" .. active2 .. "]"..
"button[3.,2;1,1;OK;OK]";
minetest.show_formspec(player:get_player_name(), "basic_machines:distributor_"..minetest.pos_to_string(pos), form)
end,
}
)
-- LIGHT
minetest.register_node("basic_machines:light_off", {
description = "Light off",
tiles = {"light_off.png"},
groups = {oddly_breakable_by_hand=2},
mesecons = {effector = {
action_on = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
minetest.set_node(pos,{name = "basic_machines:light_on"});
end
}
},
})
minetest.register_node("basic_machines:light_on", {
description = "Light off",
tiles = {"light.png"},
groups = {oddly_breakable_by_hand=2},
light_source = LIGHT_MAX,
mesecons = {effector = {
action_off = function (pos, node,ttl)
minetest.set_node(pos,{name = "basic_machines:light_off"});
end
}
},
})
punchset.known_nodes = {["basic_machines:mover"]=true,["basic_machines:keypad"]=true,["basic_machines:detector"]=true,["basic_machines:distributor"]=true};
-- handles set up punches
minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
local name = puncher:get_player_name(); if name==nil then return end
if punchset[name]== nil then -- set up punchstate
punchset[name] = {}
punchset[name].node = ""
punchset[name].pos1 = {x=0,y=0,z=0};punchset[name].pos2 = {x=0,y=0,z=0};punchset[name].pos = {x=0,y=0,z=0};
punchset[name].state = 0; -- 0 ready for punch, 1 ready for start position, 2 ready for end position
return
end
--minetest.chat_send_all("debug: PUNCH, state: " .. punchset[name].state .. " set node " .. punchset[name].node)
-- check for known node names in case of first punch
if punchset[name].state == 0 and not punchset.known_nodes[node.name] then return end
-- from now on only punches with mover/keypad/... or setup punches
if punchset.known_nodes[node.name] then -- check if owner of machine is punching or if machine public
local meta = minetest.get_meta(pos);
if not (meta:get_int("public") == 1) then
if meta:get_string("owner")~= name then return end
end
end
if node.name == "basic_machines:mover" then -- mover init code
if punchset[name].state == 0 then
-- if not puncher:get_player_control().sneak then
-- return
-- end
minetest.chat_send_player(name, "MOVER: Now punch starting and end position to set up mover.")
punchset[name].node = node.name;punchset[name].pos = {x=pos.x,y=pos.y,z=pos.z};
punchset[name].state = 1
return
end
end
if punchset[name].node == "basic_machines:mover" then -- mover code
if punchset[name].state == 1 then
if math.abs(punchset[name].pos.x - pos.x)>max_range or math.abs(punchset[name].pos.y - pos.y)>max_range or math.abs(punchset[name].pos.z - pos.z)>max_range then
minetest.chat_send_player(name, "MOVER: Punch closer to mover. reseting.")
punchset[name].state = 0; return
end
if punchset[name].pos.x==pos.x and punchset[name].pos.y==pos.y and punchset[name].pos.z==pos.z then
minetest.chat_send_player(name, "MOVER: Punch something else. aborting.")
punchset[name].state = 0;
return
end
punchset[name].pos1 = {x=pos.x,y=pos.y,z=pos.z};punchset[name].state = 2;
machines.pos1[name] = punchset[name].pos1;machines.mark_pos1(name) -- mark position
minetest.chat_send_player(name, "MOVER: Start position for mover set. Punch again to set end position.")
return
end
if punchset[name].state == 2 then
if punchset[name].node~="basic_machines:mover" then punchset[name].state = 0 return end
if math.abs(punchset[name].pos.x - pos.x)>max_range or math.abs(punchset[name].pos.y - pos.y)>max_range or math.abs(punchset[name].pos.z - pos.z)>max_range then
minetest.chat_send_player(name, "MOVER: Punch closer to mover. aborting.")
punchset[name].state = 0; return
end
punchset[name].pos2 = {x=pos.x,y=pos.y,z=pos.z}; punchset[name].state = 0;
machines.pos2[name] = punchset[name].pos2;machines.mark_pos2(name) -- mark pos2
minetest.chat_send_player(name, "MOVER: End position for mover set.")
local x = punchset[name].pos1.x-punchset[name].pos.x;
local y = punchset[name].pos1.y-punchset[name].pos.y;
local z = punchset[name].pos1.z-punchset[name].pos.z;
local meta = minetest.get_meta(punchset[name].pos);
meta:set_int("x0",x);meta:set_int("y0",y);meta:set_int("z0",z);
meta:set_int("x1",x);meta:set_int("y1",y);meta:set_int("z1",z);
x = punchset[name].pos2.x-punchset[name].pos.x;
y = punchset[name].pos2.y-punchset[name].pos.y;
z = punchset[name].pos2.z-punchset[name].pos.z;
meta:set_int("x2",x);meta:set_int("y2",y);meta:set_int("z2",z);
meta:set_int("pc",0); meta:set_int("dim",1);
return
end
end
-- KEYPAD
if node.name == "basic_machines:keypad" then -- keypad init/usage code
local meta = minetest.get_meta(pos);
if not (meta:get_int("x0")==0 and meta:get_int("y0")==0 and meta:get_int("z0")==0) then -- already configured
check_keypad(pos,name)-- not setup, just standard operation
else
if meta:get_string("owner")~= name then minetest.chat_send_player(name, "KEYPAD: Only owner can set up keypad.") return end
if punchset[name].state == 0 then
minetest.chat_send_player(name, "KEYPAD: Now punch the target block.")
punchset[name].node = node.name;punchset[name].pos = {x=pos.x,y=pos.y,z=pos.z};
punchset[name].state = 1
return
end
end
end
if punchset[name].node=="basic_machines:keypad" then -- keypad setup code
if punchset[name].state == 1 then
local meta = minetest.get_meta(punchset[name].pos);
local x = pos.x-punchset[name].pos.x;
local y = pos.y-punchset[name].pos.y;
local z = pos.z-punchset[name].pos.z;
if math.abs(x)>max_range or math.abs(y)>max_range or math.abs(z)>max_range then
minetest.chat_send_player(name, "KEYPAD: Punch closer to keypad. reseting.")
punchset[name].state = 0; return
end
machines.pos1[name] = pos;
machines.mark_pos1(name) -- mark pos1
meta:set_int("x0",x);meta:set_int("y0",y);meta:set_int("z0",z);
punchset[name].state = 0
minetest.chat_send_player(name, "KEYPAD: Keypad target set with coordinates " .. x .. " " .. y .. " " .. z)
meta:set_string("infotext", "Punch keypad to use it.");
return
end
end
-- DETECTOR "basic_machines:detector"
if node.name == "basic_machines:detector" then -- detector init code
local meta = minetest.get_meta(pos);
if meta:get_string("owner")~= name then minetest.chat_send_player(name, "DETECTOR: Only owner can set up detector.") return end
if punchset[name].state == 0 then
minetest.chat_send_player(name, "DETECTOR: Now punch the source block.")
punchset[name].node = node.name;
punchset[name].pos = {x=pos.x,y=pos.y,z=pos.z};
punchset[name].state = 1
return
end
end
if punchset[name].node == "basic_machines:detector" then
if punchset[name].state == 1 then
if math.abs(punchset[name].pos.x - pos.x)>max_range or math.abs(punchset[name].pos.y - pos.y)>max_range or math.abs(punchset[name].pos.z - pos.z)>max_range then
minetest.chat_send_player(name, "DETECTOR: Punch closer to detector. aborting.")
punchset[name].state = 0; return
end
minetest.chat_send_player(name, "DETECTOR: Now punch the target machine.")
punchset[name].pos1 = {x=pos.x,y=pos.y,z=pos.z};
machines.pos1[name] = pos;machines.mark_pos1(name) -- mark pos1
punchset[name].state = 2
return
end
if minetest.is_protected(pos,name) then
minetest.chat_send_player(name, "DETECTOR: Target position is protected. aborting.")
punchset[name].state = 0; return
end
if punchset[name].state == 2 then
if math.abs(punchset[name].pos.x - pos.x)>max_range or math.abs(punchset[name].pos.y - pos.y)>max_range or math.abs(punchset[name].pos.z - pos.z)>max_range then
minetest.chat_send_player(name, "DETECTOR: Punch closer to detector. aborting.")
punchset[name].state = 0; return
end
minetest.chat_send_player(name, "DETECTOR: Setup complete.")
machines.pos2[name] = pos;machines.mark_pos2(name) -- mark pos2
local x = punchset[name].pos1.x-punchset[name].pos.x;
local y = punchset[name].pos1.y-punchset[name].pos.y;
local z = punchset[name].pos1.z-punchset[name].pos.z;
local meta = minetest.get_meta(punchset[name].pos);
meta:set_int("x0",x);meta:set_int("y0",y);meta:set_int("z0",z);
x=pos.x-punchset[name].pos.x;y=pos.y-punchset[name].pos.y;z=pos.z-punchset[name].pos.z;
meta:set_int("x1",x);meta:set_int("y1",y);meta:set_int("z1",z);
punchset[name].state = 0
return
end
end
-- Distributor "basic_machines:distributor"
if node.name == "basic_machines:distributor" then -- distributor init code
local meta = minetest.get_meta(pos);
if meta:get_string("owner")~= name then minetest.chat_send_player(name, "DISTRIBUTOR: Only owner can set up distributor.") return end
if punchset[name].state == 0 then
minetest.chat_send_player(name, "DISTRIBUTOR: Now punch target1 machine.")
punchset[name].node = node.name;
punchset[name].pos = {x=pos.x,y=pos.y,z=pos.z};
punchset[name].state = 1
return
end
end
if punchset[name].node == "basic_machines:distributor" then
if punchset[name].state == 1 then
if math.abs(punchset[name].pos.x - pos.x)>max_range or math.abs(punchset[name].pos.y - pos.y)>max_range or math.abs(punchset[name].pos.z - pos.z)>max_range then
minetest.chat_send_player(name, "DISTRIBUTOR: Punch closer to distributor. aborting.")
punchset[name].state = 0; return
end
minetest.chat_send_player(name, "DISTRIBUTOR: Now punch target2 machine.")
punchset[name].pos1 = {x=pos.x,y=pos.y,z=pos.z};
machines.pos1[name] = pos;machines.mark_pos1(name) -- mark pos1
punchset[name].state = 2
return
end
if minetest.is_protected(pos,name) then
minetest.chat_send_player(name, "DISTRIBUTOR: Target position is protected. aborting.")
punchset[name].state = 0; return
end
if punchset[name].state == 2 then
if math.abs(punchset[name].pos.x - pos.x)>max_range or math.abs(punchset[name].pos.y - pos.y)>max_range or math.abs(punchset[name].pos.z - pos.z)>max_range then
minetest.chat_send_player(name, "DISTRIBUTOR: Punch closer to distributor. aborting.")
punchset[name].state = 0; return
end
minetest.chat_send_player(name, "DISTRIBUTOR: Setup complete.")
machines.pos2[name] = pos;machines.mark_pos2(name) -- mark pos2
local x = punchset[name].pos1.x-punchset[name].pos.x;
local y = punchset[name].pos1.y-punchset[name].pos.y;
local z = punchset[name].pos1.z-punchset[name].pos.z;
local meta = minetest.get_meta(punchset[name].pos);
meta:set_int("x1",x);meta:set_int("y1",y);meta:set_int("z1",z);
x=pos.x-punchset[name].pos.x;y=pos.y-punchset[name].pos.y;z=pos.z-punchset[name].pos.z;
meta:set_int("x2",x);meta:set_int("y2",y);meta:set_int("z2",z);
punchset[name].state = 0
return
end
end
end)
-- handles forms processing for all machines
minetest.register_on_player_receive_fields(function(player,formname,fields)
-- MOVER
local fname = "basic_machines:mover_"
if string.sub(formname,0,string.len(fname)) == fname then
local pos_s = string.sub(formname,string.len(fname)+1); local pos = minetest.string_to_pos(pos_s)
local name = player:get_player_name(); if name==nil then return end
local meta = minetest.get_meta(pos)
local privs = minetest.get_player_privs(name);
if (name ~= meta:get_string("owner") and not privs.privs) or not fields then return end -- only owner can interact
--minetest.chat_send_all("formname " .. formname .. " fields " .. dump(fields))
if fields.help == "help" then
local text = "SETUP: right click and define box where to dig from and where to put. Positions are defined by x y z coordinates (see top of mover). Mover has coordinates 0 0 0. If you prefer interactive setup "..
"punch the mover and then punch source and target node. Put chest with fuel right next to it. "..
"\n\nMODES of operation: normal ( just teleport), dig ( digs and gives you resulted node), drop "..
"( drops node on ground), reverse(takes from target position, places on source positions - good for planting a farm), object (teleportation of player and objects). "..
"\n\nBy setting 'filter only block' only selected nodes are moved. Activate it by keypad signal or mese signal (if mesecons mod) .";
local form = "size [5,5] textarea[0,0;5.5,6.5;help;MOVER HELP;".. text.."]"
minetest.show_formspec(name, "basic_machines:help_mover", form)
end
if fields.OK == "OK" then
local x0,y0,z0,x1,y1,z1,x2,y2,z2;
x0=tonumber(fields.x0) or 0;y0=tonumber(fields.y0) or -1;z0=tonumber(fields.z0) or 0
x1=tonumber(fields.x1) or 0;y1=tonumber(fields.y1) or -1;z1=tonumber(fields.z1) or 0
x2=tonumber(fields.x2) or 0;y2=tonumber(fields.y2) or 1;z2=tonumber(fields.z2) or 0;
if not privs.privs and (math.abs(x1)>max_range or math.abs(y1)>max_range or math.abs(z1)>max_range or math.abs(x2)>max_range or math.abs(y2)>max_range or math.abs(z2)>max_range) then
minetest.chat_send_player(name,"all coordinates must be between ".. -max_range .. " and " .. max_range); return
end
local x = x0; x0 = math.min(x,x1); x1 = math.max(x,x1);
local y = y0; y0 = math.min(y,y1); y1 = math.max(y,y1);
local z = z0; z0 = math.min(z,z1); z1 = math.max(z,z1);
meta:set_int("x0",x0);meta:set_int("y0",y0);meta:set_int("z0",z0);
meta:set_int("x1",x1);meta:set_int("y1",y1);meta:set_int("z1",z1);
meta:set_int("pc",0); meta:set_int("dim",(x1-x0+1)*(y1-y0+1)*(z1-z0+1))
meta:set_int("x2",x2);meta:set_int("y2",y2);meta:set_int("z2",z2);
meta:set_string("prefer",fields.prefer or "");
meta:set_string("infotext", "Mover block. Set up with source coordinates ".. x0 ..","..y0..","..z0.. " -> ".. x1 ..","..y1..","..z1.. " and target coord ".. x2 ..","..y2..",".. z2 .. ". Put locked chest with fuel next to it and start it with keypad/mese signal.");
if meta:get_float("fuel")<0 then meta:set_float("fuel",0) end -- reset block
end
return
end
-- KEYPAD
fname = "basic_machines:keypad_"
if string.sub(formname,0,string.len(fname)) == fname then
local pos_s = string.sub(formname,string.len(fname)+1); local pos = minetest.string_to_pos(pos_s)
local name = player:get_player_name(); if name==nil then return end
local meta = minetest.get_meta(pos)
local privs = minetest.get_player_privs(player:get_player_name());
if (name ~= meta:get_string("owner") and not privs.privs) or not fields then return end -- only owner can interact
if fields.OK == "OK" then
local x0,y0,z0,pass,mode;
x0=tonumber(fields.x0) or 0;y0=tonumber(fields.y0) or 1;z0=tonumber(fields.z0) or 0
pass = fields.pass or ""; mode = fields.mode or 1;
if not privs.privs and (math.abs(x0)>max_range or math.abs(y0)>max_range or math.abs(z0)>max_range) then
minetest.chat_send_player(name,"all coordinates must be between ".. -max_range .. " and " .. max_range); return
end
meta:set_int("x0",x0);meta:set_int("y0",y0);meta:set_int("z0",z0);meta:set_string("pass",pass);
meta:set_int("iter",math.min(tonumber(fields.iter) or 1,100));meta:set_int("mode",mode);
meta:set_string("infotext", "Punch keypad to use it.");
if pass~="" then meta:set_string("infotext",meta:get_string("infotext").. ". Password protected."); end
end
return
end
fname = "basic_machines:check_keypad_"
if string.sub(formname,0,string.len(fname)) == fname then
local pos_s = string.sub(formname,string.len(fname)+1); local pos = minetest.string_to_pos(pos_s)
local name = player:get_player_name(); if name==nil then return end
local meta = minetest.get_meta(pos)
if fields.OK == "OK" then
local pass;
pass = fields.pass or "";
if pass~=meta:get_string("pass") then
minetest.chat_send_player(name,"ACCESS DENIED. WRONG PASSWORD.")
return
end
minetest.chat_send_player(name,"ACCESS GRANTED.")
if meta:get_int("count")<=0 then -- only accept new operation requests if idle
meta:set_int("count",meta:get_int("iter")); use_keypad(pos,machines_TTL)
else meta:set_int("count",0); meta:set_string("infotext","operation aborted by user. punch to activate.") -- reset
end
return
end
end
-- MOVER
local fname = "basic_machines:detector_"
if string.sub(formname,0,string.len(fname)) == fname then
local pos_s = string.sub(formname,string.len(fname)+1); local pos = minetest.string_to_pos(pos_s)
local name = player:get_player_name(); if name==nil then return end
local meta = minetest.get_meta(pos)
local privs = minetest.get_player_privs(player:get_player_name());
if (name ~= meta:get_string("owner") and not privs.privs) or not fields then return end -- only owner can interact
--minetest.chat_send_all("formname " .. formname .. " fields " .. dump(fields))
if fields.help == "help" then
local text = "SETUP: right click or punch and follow chat instructions. Detector checks area around source position inside specified radius."..
"If detector activates it will trigger machine at target position.\n\n There are 2 modes of operation - node or player detection. Inside node/player "..
"write node/player name. If you want detector to activate target precisely when its not triggered set NOT to 1\n\n"..
"For example, to detect empty space write air, to detect tree write default:tree, to detect ripe wheat write farming:wheat_8, for flowing water write default:water_flowing ... "..
"If source position is chest it will look into it and check if there are items inside. For example to check if there is at least 2 dirt write default:dirt 2"
local form = "size [5,5] textarea[0,0;5.5,6.5;help;DETECTOR HELP;".. text.."]"
minetest.show_formspec(name, "basic_machines:help_detector", form)
end
if fields.OK == "OK" then
local x0,y0,z0,x1,y1,z1,r,node,NOT;
x0=tonumber(fields.x0) or 0;y0=tonumber(fields.y0) or 0;z0=tonumber(fields.z0) or 0
x1=tonumber(fields.x1) or 0;y1=tonumber(fields.y1) or 0;z1=tonumber(fields.z1) or 0
r=tonumber(fields.r) or 1;
NOT = tonumber(fields.NOT)
if not privs.privs and(math.abs(x0)>max_range or math.abs(y0)>max_range or math.abs(z0)>max_range or math.abs(x1)>max_range or math.abs(y1)>max_range or math.abs(z1)>max_range) then
minetest.chat_send_player(name,"all coordinates must be between ".. -max_range .. " and " .. max_range); return
end
meta:set_int("x0",x0);meta:set_int("y0",y0);meta:set_int("z0",z0);
meta:set_int("x1",x1);meta:set_int("y1",y1);meta:set_int("z1",z1);meta:set_int("r",math.min(r,5));
meta:set_int("NOT",NOT);
meta:set_string("node",fields.node or "");
end
return
end
local fname = "basic_machines:distributor_"
if string.sub(formname,0,string.len(fname)) == fname then
local pos_s = string.sub(formname,string.len(fname)+1); local pos = minetest.string_to_pos(pos_s)
local name = player:get_player_name(); if name==nil then return end
local meta = minetest.get_meta(pos)
local privs = minetest.get_player_privs(player:get_player_name());
if (name ~= meta:get_string("owner") and not privs.privs) or not fields then return end -- only owner can interact
--minetest.chat_send_all("formname " .. formname .. " fields " .. dump(fields))
if fields.OK == "OK" then
local x1,y1,z1,x2,y2,z2,active1,active2
x1=tonumber(fields.x1) or 0;y1=tonumber(fields.y1) or 0;z1=tonumber(fields.z1) or 0
x2=tonumber(fields.x2) or 0;y2=tonumber(fields.y2) or 0; z2=tonumber(fields.z2) or 0
active1=tonumber(fields.active1) or 0;active2=tonumber(fields.active2) or 0
if not privs.privs and (math.abs(x1)>max_range or math.abs(y1)>max_range or math.abs(z1)>max_range or math.abs(x2)>max_range or math.abs(y2)>max_range or math.abs(z2)>max_range) then
minetest.chat_send_player(name,"all coordinates must be between ".. -max_range .. " and " .. max_range); return
end
meta:set_int("x1",x1);meta:set_int("y1",y1);meta:set_int("z1",z1);
meta:set_int("x2",x2);meta:set_int("y2",y2);meta:set_int("z2",z2);
meta:set_int("active1",active1);meta:set_int("active2",active2);
end
return
end
end)
-- CRAFTS
minetest.register_craft({
output = "basic_machines:mover",
recipe = {
{"default:mese_crystal", "default:mese_crystal","default:mese_crystal"},
{"default:mese_crystal", "default:mese_crystal","default:mese_crystal"},
{"default:stone", "default:wood", "default:stone"}
}
})
minetest.register_craft({
output = "basic_machines:detector",
recipe = {
{"default:mese_crystal", "default:mese_crystal"},
{"default:mese_crystal", "default:mese_crystal"}
}
})
minetest.register_craft({
output = "basic_machines:light_on",
recipe = {
{"default:torch", "default:torch"},
{"default:torch", "default:torch"}
}
})
minetest.register_craft({
output = "basic_machines:keypad",
recipe = {
{"default:stick"},
{"default:wood"},
}
})
minetest.register_craft({
output = "basic_machines:distributor",
recipe = {
{"default:steel_ingot"},
{"default:mese_crystal"},
}
})