ctf_marker = {} -- Locally cache list of team members when adding -- marker, because the members in the team needn't -- be the same within an extended duration of time local teams = {} local visibility_time = 30 -- Convenience function that returns passed -- string enclosed by color escape codes local function msg(str) if not str then return end return minetest.colorize("#ABCDEF", str) end -- Remove waypoint element for valid players in team tname function ctf_marker.remove_marker(tname) if not teams[tname] then return end for name, hud in pairs(teams[tname].players) do local player = minetest.get_player_by_name(name) if player then player:hud_remove(hud) end end teams[tname] = nil end -- Add waypoint element to all players in the same team as name function ctf_marker.add_marker(name, tname, pos, str) local player = minetest.get_player_by_name(name) if not player then return end local team = ctf.team(tname) teams[tname] = { players = {}, time = 0 } for pname, _ in pairs(team.players) do local tplayer = minetest.get_player_by_name(pname) if tplayer then teams[tname].players[pname] = tplayer:hud_add({ hud_elem_type = "waypoint", name = str, number = tonumber(ctf.flag_colors[team.data.color]), world_pos = pos }) end minetest.log("action", name .. " placed a marker at " .. minetest.pos_to_string(pos) .. ": '" .. str .. "'") minetest.chat_send_player(pname, msg("* " .. name .. " placed a marker!")) end end minetest.register_globalstep(function(dtime) for tname, team in pairs(teams) do -- Increment time of team marker local time = team.time + dtime teams[tname].time = time -- If time > visibility_time, destroy team marker if time >= visibility_time then ctf_marker.remove_marker(tname) end end end) minetest.register_chatcommand("m", { param = "[Optional description]", description = "Allows players to share the location of where " .. "they're looking at with their team-mates.", privs = { interact = true }, func = function(name, param) local player = minetest.get_player_by_name(name) if not player then return end -- Calculate marker pos local dir = player:get_look_dir() local p1 = vector.add(player:get_pos(), { x = 0, y = player:get_properties().eye_height, z = 0 }) p1 = vector.add(p1, dir) local p2 = vector.add(p1, vector.multiply(dir, 500)) local pointed = minetest.raycast(p1, p2, true, true):next() if not pointed then minetest.chat_send_player(name, msg("Pointed thing out of range!")) return end local tname = ctf.player(name).team -- Handle waypoint string local str = (param and param:trim() ~= "") and param or name .. "'s marker" if pointed.type == "object" then local concat local obj = pointed.ref local entity = obj:get_luaentity() -- If object is a player, append player name to display text -- Else if obj is item entity, append item description and count to str. if obj:is_player() then concat = obj:get_player_name() elseif entity then if entity.name == "__builtin:item" then local stack = ItemStack(entity.itemstring) local itemdef = minetest.registered_items[stack:get_name()] -- Fallback to itemstring if description doesn't exist concat = itemdef.description or entity.itemstring concat = concat .. " " .. stack:get_count() else -- Pointed thing is a trivial entity, abort minetest.chat_send_player(name, msg("Invalid marker position. Please try again.")) return end end str = concat and str .. " <" .. concat .. ">" end str = "[" .. str .. "]" -- Remove existing marker if it exists ctf_marker.remove_marker(tname) ctf_marker.add_marker(name, tname, minetest.get_pointed_thing_position(pointed), str) end })