Don't Store object into another table. Continue with all players instead of returning after first hit.
101 lines
3.0 KiB
Lua
101 lines
3.0 KiB
Lua
local NAME = minetest.get_current_modname()
|
|
|
|
-- TODO Outsource to sparktech library
|
|
function table.shallow_copy(tab)
|
|
local new = {}
|
|
for k,v in pairs(tab) do
|
|
new[k] = v
|
|
end
|
|
return new
|
|
end
|
|
|
|
sparktech.tool_focus = {}
|
|
|
|
function set_view(playername, object)
|
|
local player = minetest.get_player_by_name(playername)
|
|
local player_eyes = player:getpos()
|
|
player_eyes.y = player_eyes.y + 1
|
|
local offset = player:get_eye_offset()
|
|
player_eyes.x = player_eyes.x + offset.x
|
|
player_eyes.y = player_eyes.y + offset.y
|
|
player_eyes.z = player_eyes.z + offset.z
|
|
|
|
minetest.debug(dump2(object))
|
|
if object.type == "node" then
|
|
local vecnode = vector.normalize(vector.direction(player_eyes, object.under))
|
|
minetest.debug(dump2(vecnode))
|
|
-- Create vectors "lying" on the xz or yz plane
|
|
local yz_vec = table.shallow_copy(vecnode)
|
|
yz_vec.x = 0
|
|
local xz_vec = table.shallow_copy(vecnode)
|
|
yz_vec.y = 0
|
|
|
|
-- Calculate angle between the vector projected onto a plane and the target vector
|
|
local yaw = math.acos(math.abs(yz_vec.y * vecnode.y + yz_vec.z * vecnode.z) / (vector.length(yz_vec) * vector.length(vecnode)))
|
|
if vecnode.x > 0 then
|
|
-- The angle needs to be applied clockwise
|
|
yaw = -yaw
|
|
end
|
|
if vecnode.z < 0 then
|
|
-- The projection is PI rotated, so correct by starting with a PI rotation
|
|
yaw = math.pi - yaw
|
|
end
|
|
local pitch = math.acos(math.abs(xz_vec.x * vecnode.x + xz_vec.z * vecnode.z) / (vector.length(xz_vec) * vector.length(vecnode)))
|
|
if vecnode.y > 0 then
|
|
pitch = -pitch
|
|
end
|
|
--[[ Do proper rotation of vector and then set the view
|
|
reference is for both cases the z axis (e.g the planes (1 0 1) and (0 1 1)
|
|
]]--
|
|
minetest.debug("\n" .. dump2(player:get_look_dir()) .. "\nori: " .. player:get_look_horizontal() .. " " .. player:get_look_vertical() .. "\nnew: " .. yaw .. " " .. pitch)
|
|
player:set_look_horizontal(yaw)
|
|
player:set_look_vertical(pitch)
|
|
minetest.debug("\n" .. dump2(player:get_look_dir()))
|
|
else
|
|
-- either player or object now
|
|
-- return for object, for a player we can do stuff
|
|
return
|
|
end
|
|
end
|
|
|
|
function on_use(one, player, pointedobject)
|
|
if pointedobject == nil or player == nil then return end
|
|
local pname = player:get_player_name()
|
|
if sparktech.tool_focus[pname] ~= nil then
|
|
sparktech.tool_focus[pname] = nil
|
|
else
|
|
sparktech.tool_focus[pname] = pointedobject
|
|
end
|
|
set_view(pname, pointedobject)
|
|
end
|
|
|
|
minetest.register_tool(NAME .. ":focus", {
|
|
description = "focus",
|
|
inventory_image = "debug.png",
|
|
stack_max = 1,
|
|
range = 20,
|
|
on_use = on_use
|
|
})
|
|
|
|
local last = 0
|
|
minetest.register_globalstep(function(dtime)
|
|
-- last = dtime + last
|
|
-- if last < 0.15 then
|
|
-- return
|
|
-- end
|
|
last = 0
|
|
for k, i in pairs(sparktech.tool_focus) do
|
|
local player = minetest.get_player_by_name(k)
|
|
if player == nil then
|
|
sparktech.tool_focus[k] = nil
|
|
return
|
|
end
|
|
set_view(k,i)
|
|
end
|
|
end)
|
|
|
|
--[[
|
|
function to get item id
|
|
for k, v in pairs(core.luaentities) do if v == self then my_found_entity_id = k; break end
|
|
]]--
|