diff --git a/mods/dctest/init.lua b/mods/dctest/init.lua index b68d550..c3dbabd 100644 --- a/mods/dctest/init.lua +++ b/mods/dctest/init.lua @@ -5,6 +5,7 @@ -- purpose: define nodes that spawn specific mobs if there are not too many around yet -- from https://forum.minetest.net/viewtopic.php?p=57231#p57231 + function mob_breeder(pos, mob_name) local objects = minetest.get_objects_inside_radius(pos, 8) -- radius local mob_count = 0 @@ -33,7 +34,10 @@ minetest.register_abm({ nodenames = {"dctest:mob_breeder"}, interval = 1.0, chance = 10, - action = function(pos) + action = function(pos, node, active_object_count, active_object_count_wider) + if active_object_count_wider > 30 then -- no more than 30 chickens + return + end local pos_under = {x=pos.x,y=pos.y-1,z=pos.z} local under = minetest.get_node(pos_under) if under.name == "default:furnace_active" then diff --git a/mods/mobs/bee.lua b/mods/mobs/bee.lua index 54a2ceb..cd84676 100644 --- a/mods/mobs/bee.lua +++ b/mods/mobs/bee.lua @@ -114,7 +114,7 @@ minetest.register_abm({ interval = 20, chance = 5, action = function(pos, node, active_object_count, active_object_count_wider) - if active_object_count_wider > 50 then -- no more than 50 bees + if active_object_count_wider > 30 then -- no more than 30 bees return end local objs = minetest.env:get_objects_inside_radius(pos,8) diff --git a/mods/mymod/mover.lua b/mods/mymod/mover.lua index 3f195f1..3b06fdb 100644 --- a/mods/mymod/mover.lua +++ b/mods/mymod/mover.lua @@ -19,43 +19,51 @@ minetest.register_node("mymod:mover", { meta:set_int("x1",0);meta:set_int("y1",-1);meta:set_int("z1",0); 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 form = - "size[3,3]" .. -- width, height - "field[0,0.5;1,1;x1;x1;0] field[1,0.5;1,1;y1;y1;-1] field[2,0.5;1,1;z1;z1;0]".. - "field[0,1.5;1,1;x2;x2;0] field[1,1.5;1,1;y2;y2;1] field[2,1.5;1,1;z2;z2;0]".. - "button[0,2.;1,1;OK;OK]" - meta:set_string("formspec", form) - end, - - - on_receive_fields = function(pos, formname, fields, sender) - local name = sender:get_player_name(); if name==nil then return end - local meta = minetest.get_meta(pos) - if name ~= meta:get_string("owner") 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; - x1=tonumber(fields.x1);y1=tonumber(fields.y1);z1=tonumber(fields.z1) - x2=tonumber(fields.x2);y2=tonumber(fields.y2);z2=tonumber(fields.z2); - if math.abs(x1)>5 or math.abs(y1)>5 or math.abs(z1)>5 or math.abs(x2)>5 or math.abs(y2)>5 or math.abs(z2)>5 then - minetest.chat_send_player(name,"all coordinates must be between -5 and 5"); 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_string("infotext", "Mover block. Set up with source coords ".. x1 ..","..y1..","..z1.. " and target coord ".. x2 ..","..y2..",".. z2 .. ". Put chest with coal next to it and start with mese signal."); - end end, + -- on_receive_fields = function(pos, formname, fields, sender) + -- local name = sender:get_player_name(); if name==nil then return end + -- local meta = minetest.get_meta(pos) + -- if name ~= meta:get_string("owner") 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; + -- 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 math.abs(x1)>5 or math.abs(y1)>5 or math.abs(z1)>5 or math.abs(x2)>5 or math.abs(y2)>5 or math.abs(z2)>5 then + -- minetest.chat_send_player(name,"all coordinates must be between -5 and 5"); 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_string("infotext", "Mover block. Set up with source coords ".. x1 ..","..y1..","..z1.. " and target coord ".. x2 ..","..y2..",".. z2 .. ". Put chest with coal next to it and start with mese signal."); + -- end + -- end, + mesecons = {effector = { action_on = function (pos, node) local meta = minetest.get_meta(pos); local fuel = meta:get_float("fuel"); if fuel < 0 then return end -- deactivated - if fuel==0 then -- needs fuel to operate - --minetest.chat_send_all(" no fuel ") - local fpos = minetest.find_node_near(pos, 1, {"default:chest"}) -- furnace position + if fuel==0 then -- needs fuel to operate, find nearby open chest with fuel within radius 1 + local r = 1; + local pos1 = {x=meta:get_int("x1")+pos.x,y=meta:get_int("y1")+pos.y,z=meta:get_int("z1")+pos.z}; + local pos2 = {x=meta:get_int("x2")+pos.x,y=meta:get_int("y2")+pos.y,z=meta:get_int("z2")+pos.z}; + 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") + 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 with fuel found local cmeta = minetest.get_meta(fpos); local inv = cmeta:get_inventory(); @@ -84,37 +92,93 @@ minetest.register_node("mymod:mover", { return end local node1 = minetest.get_node(pos1); + local source_chest; if string.find(node1.name,"default:chest") then source_chest=true end if node1.name == "air" then return end -- nothing to move + local prefer = meta:get_string("prefer") + 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({name=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 local node2 = minetest.get_node(pos2); - local meta1 = minetest.get_meta(pos1);local table1=meta1:to_table(); -- copy meta - --minetest.chat_send_all(" moving ") meta:set_float("fuel", fuel - 1); meta:set_string("infotext", "Mover block. Fuel "..fuel-1); -- if target chest put in chest + local target_chest = false if node2.name == "default:chest" or node2.name == "default:chest_locked" then + target_chest = true local cmeta = minetest.get_meta(pos2); local inv = cmeta:get_inventory(); local stack = ItemStack({name=node1.name}) if inv:room_for_item("main", stack) then - minetest.set_node(pos1, {name = "air"}); inv:add_item("main", stack); - else return end - return + end + + if not target_chest then + minetest.set_node(pos2, {name = node1.name}); + end + if not source_chest then + minetest.set_node(pos1, {name = "air"}); end - - - minetest.set_node(pos2, {name = node1.name}); - minetest.set_node(pos1, {name = "air"}); - local meta2 = minetest.get_meta(pos2);meta2:from_table(table1); end } }, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + local meta = minetest.get_meta(pos); + local x1,y1,z1,x2,y2,z2,prefer; + 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"); + prefer = meta:get_string("prefer"); + local form = + "size[3,3]" .. -- width, height + "field[0,0.5;1,1;x1;x1;"..x1.."] field[1,0.5;1,1;y1;y1;"..y1.."] field[2,0.5;1,1;z1;z1;"..z1.."]".. + "field[0,1.5;1,1;x2;x2;"..x2.."] field[1,1.5;1,1;y2;y2;"..y2.."] field[2,1.5;1,1;z2;z2;"..z2.."]".. + "button[0,2.;1,1;OK;OK] field[1.5,2.5;2,1;prefer;prefered block;"..prefer.."]" + --meta:set_string("formspec", form) + minetest.show_formspec(player:get_player_name(), "mymod:mover_"..minetest.pos_to_string(pos), form) + end }) +minetest.register_on_player_receive_fields(function(player,formname,fields) + + local fname = "mymod: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) + if name ~= meta:get_string("owner") 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; + 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 math.abs(x1)>5 or math.abs(y1)>5 or math.abs(z1)>5 or math.abs(x2)>5 or math.abs(y2)>5 or math.abs(z2)>5 then + minetest.chat_send_player(name,"all coordinates must be between -5 and 5"); 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_string("prefer",fields.prefer or ""); + meta:set_string("infotext", "Mover block. Set up with source coords ".. x1 ..","..y1..","..z1.. " and target coord ".. x2 ..","..y2..",".. z2 .. ". Put chest with coal next to it and start with mese signal."); + end + end +end) + minetest.register_craft({ output = "mymod:mover", recipe = {