add pointing to objects and nodes

This commit is contained in:
whosit 2024-12-08 19:18:49 +03:00
parent 87bd7a098c
commit de63351c41
2 changed files with 105 additions and 4 deletions

View File

@ -1,4 +1,7 @@
local MODNAME = core.get_current_modname()
local MODPATH = core.get_modpath(MODNAME)
local util = dofile(MODPATH .. DIR_DELIM .. "util.lua")
local api = {}
_G[MODNAME] = api
@ -8,21 +11,41 @@ api.e = {}
local function create_shared_environment(player_name)
local me = core.get_player_by_name(player_name)
local magic_keys = {
me = function()
return core.get_player_by_name(player_name)
end,
my_pos = function()
local pos = here
local me = core.get_player_by_name(player_name)
local pos = vector.zero() -- FIXME use last command position
if me:is_player() then
pos = me:get_pos()
end
return pos
end,
this_obj = function()
point = function()
local me = core.get_player_by_name(player_name)
local pointed_thing = util.raycast_crosshair(me, 200, true, false)
if pointed_thing then
return pointed_thing.intersection_point
end
return me:get_pos()
end,
this_node = function()
this_obj = function()
local me = core.get_player_by_name(player_name)
local pointed_thing = util.raycast_crosshair_to_object(me, 200)
if pointed_thing then
return pointed_thing.ref
end
return nil
end,
this_node_pos = function()
local me = core.get_player_by_name(player_name)
local pointed_thing = util.raycast_crosshair(me, 200, false, false)
if pointed_thing then
return pointed_thing.under
end
return vector.round(me:get_pos())
end,
}

78
util.lua Normal file
View File

@ -0,0 +1,78 @@
-- get actual eye_pos of the player (including eye_offset)
local function player_get_eye_pos(player)
local p_pos = player:get_pos()
local p_eye_height = player:get_properties().eye_height
p_pos.y = p_pos.y + p_eye_height
local p_eye_pos = p_pos
local p_eye_offset = vector.multiply(player:get_eye_offset(), 0.1)
local yaw = player:get_look_horizontal()
p_eye_pos = vector.add(p_eye_pos, vector.rotate_around_axis(p_eye_offset, {x=0,y=1,z=0}, yaw))
return p_eye_pos
end
-- return first thing player is pointing at
local function raycast_crosshair(player, range, point_to_objects, point_to_liquids)
local p_eye_pos = player_get_eye_pos(player)
local to = vector.add(p_eye_pos, vector.multiply(player:get_look_dir(), range))
local ray = core.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
-- exclude the player themselves from the raycast
pointed_thing = ray:next()
else
return pointed_thing
end
end
-- FIXME return "nothing" pointed thing?
return nil
end
-- return first object
local function raycast_crosshair_to_object(player, range)
local p_eye_pos = player_get_eye_pos(player)
local to = vector.add(p_eye_pos, vector.multiply(player:get_look_dir(), range))
local ray = core.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" then
if pointed_thing.ref ~= player then
return pointed_thing
end
end
pointed_thing = ray:next()
end
-- FIXME return "nothing" pointed thing?
return nil
end
-- get position and thing that player is pointing at or nil
local function get_pointed_position(player, range, point_to_objects, point_to_liquids)
local pointed_thing = raycast_crosshair(player, range, point_to_objects, point_to_liquids)
local pointed_pos = nil
if pointed_thing then
if pointed_thing.type == "node" then
-- middle between "above" and "under"
pointed_pos = vector.multiply(vector.add(pointed_thing.above, pointed_thing.under), 0.5)
elseif pointed_thing.type == "object" then
-- TODO point at the middle of collision box? (or not, ground may be better)
pointed_pos = pointed_thing.ref:get_pos()
end
end
return pointed_pos, pointed_thing
end
local util = {
player_get_eye_pos = player_get_eye_pos,
raycast_crosshair = raycast_crosshair,
raycast_crosshair_to_object = raycast_crosshair_to_object,
get_pointed_position = get_pointed_position,
}
return util