local hud = {} -- playername -> id missions.register_step({ type = "waypoint", name = "Waypoint", create = function() return {pos=nil, name="", radius=3, visible=1, description=""} end, get_status = function(ctx) return ctx.step.data.description end, validate = function(ctx) local stepdata = ctx.step.data if stepdata.pos == nil then return { success=false, failed=true, msg="No position defined" } else return {success=true} end 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 stack:get_name() == "missions:wand_position" then return true end return false end, edit_formspec = function(ctx) local stepdata = ctx.step.data local pos = ctx.pos local name = "" if stepdata.pos then local distance = vector.distance(pos, stepdata.pos) name = name .. "Position(" .. stepdata.pos.x .. "/" .. stepdata.pos.y .. "/" .. stepdata.pos.z ..") " .. "Distance: " .. math.floor(distance) .. " m" end if stepdata.name then name = name .. " with name '" .. stepdata.name .. "'" end local visibleText if stepdata.visible == 1 then visibleText = "Waypoint: Visible" else visibleText = "Waypoint: Hidden" end local formspec = "size[8,10;]" .. "label[0,0;Walk to (Step #" .. ctx.stepnumber .. ")]" .. "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main;0,1;1,1;0]" .. "label[0,2;" .. name .. "]" .. "field[0.2,3;8,1;description;Description;" .. stepdata.description .. "]" .. "field[0.2,4;4,1;radius;Radius;" .. stepdata.radius .. "]" .. "button[4,5;4,1;togglevisible;" .. visibleText .. "]" .. "list[current_player;main;0,6;8,4;]listring[]" .. "button[0,5;4,1;save;Save]" return formspec; end, update = function(ctx) local fields = ctx.fields local inv = ctx.inv local stepdata = ctx.step.data if fields.radius then local radius = tonumber(fields.radius) if radius and radius > 0 then stepdata.radius = radius end end if fields.togglevisible then if stepdata.visible == 1 then stepdata.visible = 0 else stepdata.visible = 1 end ctx.show_editor() end if fields.description then stepdata.description = fields.description end if fields.save then local stack = inv:get_stack("main", 1) if not stack:is_empty() then local meta = stack:get_meta() local pos = minetest.string_to_pos(meta:get_string("pos")) local name = meta:get_string("name") stepdata.pos = pos stepdata.name = name end ctx.show_mission() end end, on_step_enter = function(ctx) local player = ctx.player local stepdata = ctx.step.data if stepdata.visible == 1 then hud[player:get_player_name()] = player:hud_add({ hud_elem_type = "waypoint", name = "Mission-waypoint: " .. stepdata.name, text = "m", number = 0xFF0000, world_pos = stepdata.pos }) end end, on_step_interval = function(ctx) local player = ctx.player local stepdata = ctx.step.data local pos = player:get_pos() local distance = vector.distance(pos, stepdata.pos) if distance < stepdata.radius then ctx.on_success() end end, on_step_exit = function(ctx) local player = ctx.player local idx = hud[player:get_player_name()] if idx then player:hud_remove(idx) hud[player:get_player_name()] = nil end end })