basic announcement with a waypoint
This commit is contained in:
commit
dcfd8dfd33
100
init.lua
Normal file
100
init.lua
Normal file
@ -0,0 +1,100 @@
|
||||
-- TODO show some text on screen for a short while?
|
||||
-- TODO "admin" command version with configurable pos, radius and timeout
|
||||
|
||||
local announce_command_name = "look!"
|
||||
local announce_radius = 256
|
||||
local announce_timeout = 20
|
||||
local waypoint_precision = 1 -- set to 1 to show whole number or 10 for 1 decimal
|
||||
local waypoint_color = 0xFFFFFF
|
||||
local point_range = 180
|
||||
local point_to_objects = true
|
||||
local point_to_liquids = true
|
||||
|
||||
-- return first thing player is pointing at
|
||||
local function raycast_crosshair(player, range)
|
||||
local p_pos = player:get_pos()
|
||||
local p_eye_height = player:get_properties().eye_height
|
||||
local p_eye_pos = { x = p_pos.x, y = p_pos.y + p_eye_height, z = p_pos.z }
|
||||
local to = vector.add(p_eye_pos, vector.multiply(player:get_look_dir(), range))
|
||||
local ray = minetest.raycast(p_eye_pos, to, point_to_objects, point_to_liquids)
|
||||
local pointed_thing = ray:next()
|
||||
while pointed_thing do
|
||||
if pointed_thing.type == "object" and pointed_thing.ref == player then
|
||||
pointed_thing = ray:next()
|
||||
else
|
||||
print("pointed_thing.type", pointed_thing.type)
|
||||
return pointed_thing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function get_pointed_position(player, range)
|
||||
local pointed_thing = raycast_crosshair(player, range)
|
||||
local pointed_pos = nil
|
||||
if pointed_thing then
|
||||
if pointed_thing.type == "node" then
|
||||
pointed_pos = vector.multiply(vector.add(pointed_thing.above, pointed_thing.under), 0.5)
|
||||
elseif pointed_thing.type == "object" then
|
||||
pointed_pos = pointed_thing.ref:get_pos()
|
||||
end
|
||||
end
|
||||
return pointed_pos, pointed_thing
|
||||
end
|
||||
|
||||
|
||||
local function show_hud_waypoint(player, point_pos, name)
|
||||
local hud_id = player:hud_add({
|
||||
hud_elem_type = "waypoint",
|
||||
name = name,
|
||||
text = "m", -- distance suffix
|
||||
precision = waypoint_precision,
|
||||
number = waypoint_color,
|
||||
world_pos = point_pos,
|
||||
})
|
||||
return hud_id
|
||||
end
|
||||
|
||||
|
||||
local function hide_hud_waypoint(player_name, hud_id)
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
if player then
|
||||
player:hud_remove(hud_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function add_announcement(announcer, pos, radius, point_pos, name, timeout)
|
||||
for i, object in pairs(minetest.get_objects_inside_radius(pos, radius)) do
|
||||
if object:is_player() then
|
||||
local player = object
|
||||
local player_name = player:get_player_name()
|
||||
local hud_id = show_hud_waypoint(player, point_pos, name)
|
||||
minetest.after(announce_timeout, hide_hud_waypoint, player_name, hud_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_chatcommand(announce_command_name, {
|
||||
privs = {
|
||||
shout = true,
|
||||
},
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then -- player is online
|
||||
local player_pos = player:get_pos()
|
||||
-- TODO use pointed thing to provide some description?
|
||||
local pointed_pos, pointed_thing = get_pointed_position(player, point_range)
|
||||
if not pointed_pos then
|
||||
-- player is pointing into the void, use him as target
|
||||
pointed_pos = player_pos
|
||||
end
|
||||
-- TODO limit message length?
|
||||
add_announcement(player, player_pos, announce_radius, pointed_pos, param, announce_timeout)
|
||||
return true, "Look at " .. minetest.pos_to_string(pointed_pos)
|
||||
else
|
||||
return false
|
||||
end
|
||||
end,
|
||||
})
|
Loading…
Reference in New Issue
Block a user