local HUD_POSITION = {x = missions.hud.posx, y = missions.hud.posy } local HUD_ALIGNMENT = {x = 1, y = 0} local stacks = {} -- playername -> stack_str local hud = {} -- playername -> {} missions.register_step({ type = "buildspecific", name = "Place specific nodes", create = function() return {stack="default:stone 99"} end, allow_inv_stack_put = function(listname, index, stack) -- allow position wand on pos 1 of main inv if listname == "main" and index == 1 and minetest.registered_nodes[stack:get_name()] then -- stack is a node return true end return false end, get_status = function(ctx) local player = ctx.player local name = player:get_player_name() local stack = ItemStack(stacks[name] or "") local hud_data = hud[name]; player:hud_change(hud_data.counter, "text", stack:get_count() .. "x") return "Place " .. stack:get_count() .. " " .. stack:get_name() end, edit_formspec = function(ctx) local stepdata = ctx.step.data local pos = ctx.pos local stack = ItemStack(stepdata.stack) ctx.inv:set_stack("main", 1, stack) local formspec = "size[8,8;]" .. "label[0,0;Place specific nodes]" .. "label[0,1;Node:]" .. "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main;3,1;1,1;0]" .. "list[current_player;main;0,2.5;8,4;]listring[]" .. "button[0,7;8,1;save;Save]" return formspec; end, update = function(ctx) local fields = ctx.fields local inv = ctx.inv local stepdata = ctx.step.data if fields.save then local stack = inv:get_stack("main", 1) if not stack:is_empty() then stepdata.stack = stack:to_string() end ctx.show_mission() end end, on_step_enter = function(ctx) local player = ctx.player local stepdata = ctx.step.data local stack = ItemStack(stepdata.stack) local name = player:get_player_name() stacks[name] = stack:to_string() local hud_data = {} hud[player:get_player_name()] = hud_data; hud_data.counter = player:hud_add({ hud_elem_type = "text", position = HUD_POSITION, offset = {x = 0, y = 140}, text = "", alignment = HUD_ALIGNMENT, scale = {x = 100, y = 100}, number = 0x00FF00 }) hud_data.image = player:hud_add({ hud_elem_type = "image", position = HUD_POSITION, offset = {x = 32, y = 140}, text = missions.get_image(stack:get_name()), alignment = HUD_ALIGNMENT, scale = {x = 1, y = 1}, }) end, on_step_interval = function(ctx) local player = ctx.player local name = player:get_player_name() local stack = ItemStack(stacks[name] or "") if stack:get_count() == 0 then ctx.on_success() end end, on_step_exit = function(ctx) local player = ctx.player local name = player:get_player_name() local hud_data = hud[name] if hud_data and hud_data.image then player:hud_remove(hud_data.image) end if hud_data and hud_data.counter then player:hud_remove(hud_data.counter) end hud[name] = nil stacks[name] = nil end }) minetest.register_on_placenode(function(pos, newnode, player, oldnode, itemstack) if player ~= nil and player:is_player() then local name = player:get_player_name() local stack = ItemStack(stacks[name] or "") if newnode.name == stack:get_name() then -- node name matches stack:take_item(1) end stacks[name] = stack:to_string() end end) minetest.register_on_dignode(function(pos, oldnode, digger) if digger ~= nil and digger:is_player() then local name = digger:get_player_name() if not stacks[name] then return end local stack = ItemStack(stacks[name]) if oldnode.name == stack:get_name() then -- node name matches stack:set_count(stack:get_count() + 1) end stacks[name] = stack:to_string() end end)