-- -- Map handling -- nav.map_radius = 256 nav.waypoints = {} local open_formspecs = {} -- Timer local timer_interval = 0.1 local timer = 10 function nav.add_waypoint(pos, name, label, isinfo, type) nav.waypoints[name] = { pos = pos, label = label, isinfo = isinfo or false, type = type } end function nav.remove_waypoint(name) nav.waypoints[name] = nil end function nav.relocate_waypoint(name, pos) nav.waypoints[name].pos = pos end function nav.get_waypoints_in_square(pos, radius) local wpts = {} for name, data in pairs(nav.waypoints) do local wp = data.pos if wp.x > pos.x-radius and wp.x < pos.x+radius and wp.z > pos.z-radius and wp.z < pos.z+radius then table.insert(wpts, name) end end return wpts end local function get_formspec_waypoint(x, y, name, label, isinfo) local img = "nav_waypoint.png" if isinfo then img = "nav_info.png" end local form = "" form = form .. "image_button[" .. (x-0.72) .. "," .. (y-0.53) .. ";0.5,0.5;" .. img .. ";" .. name .. ";;false;false;" .. img .. "]" form = form .. "tooltip[" .. name .. ";" .. minetest.formspec_escape(label) .. "]" return form end function nav.show_map(player) if player == nil then return end local name = player:get_player_name() if not open_formspecs[name] then return end local pos = player:getpos() local form = default.ui.get_page("default:default") form = form .. "field[-1,-1;0,0;nav_map_tracker;;]" form = form .. "label[0.25,0.25;" .. minetest.formspec_escape(name) .. " (x: " .. math.floor(pos.x+0.5) .. ", y: " .. math.floor(pos.y) .. ", z: " .. math.floor(pos.z+0.5) .. ")]" form = form .. "image[0.5,3;6,6;nav_background.png]" local wpts = nav.get_waypoints_in_square(pos, nav.map_radius) for _, wptname in pairs(wpts) do local wpt = nav.waypoints[wptname] form = form .. get_formspec_waypoint( 3.5+(((wpt.pos.x-pos.x)/nav.map_radius)*3), 6+(((pos.z-wpt.pos.z)/nav.map_radius)*3), wptname, wpt.label, wpt.isinfo) end form = form .. "image[5.5,3;1,1;nav_map_compass.png]" form = form .. "label[6.25,6.6;" .. nav.map_radius .. "m]" form = form .. "image[5.5,5.5;3,3;" .. minetest.formspec_escape("nav_legend.png^[transformFX") .. "]" minetest.show_formspec(name, "nav:map", form) end -- Formspec interaction local function on_player_recieve_fields(player, form_name, fields) if form_name == "nav:map" then if fields.quit or fields.nav_map_tracker then open_formspecs[player:get_player_name()] = false end end end if minetest.setting_get_pos("static_spawnpoint") and (not minetest.is_singleplayer()) then minetest.after( 1.0, function() nav.add_waypoint(minetest.setting_get_pos("static_spawnpoint"), "spawn", "Spawn", true, "spawn") end) end -- Joining player local function on_joinplayer(player) local name = player:get_player_name() minetest.after( 1.0, function() nav.add_waypoint( player:getpos(), "player_" .. name, name, true, "player" ) end) end -- Disconnecting player local function on_leaveplayer(player) local name = player:get_player_name() nav.remove_waypoint("player_" .. name) end -- Global update function local function on_globalstep(dtime) timer = timer + dtime if timer < timer_interval then return end timer = 0 local players = {} for _, player in pairs(minetest.get_connected_players()) do if player ~= nil then local name = player:get_player_name() players[name] = player nav.show_map(player) end end for wptname, wpt in pairs(nav.waypoints) do if wpt.type == "player" then if players[wpt.label] ~= nil and minetest.get_player_by_name(wpt.label) ~= nil then nav.relocate_waypoint(wptname, players[wpt.label]:getpos()) end end end end minetest.register_on_joinplayer(on_joinplayer) minetest.register_on_leaveplayer(on_leaveplayer) minetest.register_on_player_receive_fields(on_player_recieve_fields) minetest.register_globalstep(on_globalstep) -- Items minetest.register_craftitem( "nav:map", { description = "Map", inventory_image = "nav_inventory.png", wield_image = "nav_inventory.png", stack_max = 1, on_use = function(itemstack, player, pointed_thing) open_formspecs[player:get_player_name()] = true nav.show_map(player) end, }) -- Crafting crafting.register_craft( { output = "nav:map", items = { "default:stick 6", "default:paper 3", } }) -- Achievements achievements.register_achievement( "navigator", { title = "Navigator", description = "Craft a map", times = 1, craftitem = "nav:map", }) default.log("map", "loaded")