Some of these are copies from the respective origins from mtg, to make sure we have headers everywhere listing the proper code. I've relicensed spectator_mode from WT*PL to LGPL-2.1. No other licenses were changed.
137 lines
3.5 KiB
Lua
137 lines
3.5 KiB
Lua
|
|
--[[
|
|
|
|
spectator mode - originally by kilbith.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public License
|
|
as published by the Free Software Foundation; either version 2.1
|
|
of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
MA 02111-1307 USA
|
|
|
|
]]--
|
|
|
|
local original_pos = {}
|
|
|
|
local watching = {}
|
|
|
|
minetest.register_privilege("watch", "Player can watch other players")
|
|
|
|
local function toggle_hud_flags(player, bool)
|
|
local flags = player:hud_get_flags()
|
|
local new_hud_flags = {}
|
|
|
|
for flag in pairs(flags) do
|
|
new_hud_flags[flag] = bool
|
|
end
|
|
|
|
player:hud_set_flags(new_hud_flags)
|
|
end
|
|
|
|
local function unwatching(name)
|
|
local watcher = minetest.get_player_by_name(name)
|
|
local privs = minetest.get_player_privs(name)
|
|
|
|
if watcher and watching[name] then
|
|
watcher:set_detach()
|
|
watching[name] = nil
|
|
watcher:set_eye_offset(vector.new(), vector.new())
|
|
watcher:set_nametag_attributes({color = {a = 255, r = 255, g = 255, b = 255}})
|
|
|
|
toggle_hud_flags(watcher, true)
|
|
|
|
watcher:set_properties({
|
|
visual_size = {x = 1, y = 1},
|
|
makes_footstep_sound = true,
|
|
collisionbox = {-0.3, -1, -0.3, 0.3, 1, 0.3}
|
|
})
|
|
|
|
if not privs.interact and privs.watch == true then
|
|
privs.interact = true
|
|
minetest.set_player_privs(name, privs)
|
|
end
|
|
|
|
local pos = original_pos[watcher]
|
|
if pos then
|
|
-- setpos seems to be very unreliable
|
|
-- this workaround helps though
|
|
minetest.after(0.1, function()
|
|
watcher:setpos(pos)
|
|
end)
|
|
original_pos[watcher] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_chatcommand("watch", {
|
|
params = "<to_name>",
|
|
description = "watch a given player",
|
|
privs = {watch = true},
|
|
func = function(name, param)
|
|
local watcher = minetest.get_player_by_name(name)
|
|
local target = minetest.get_player_by_name(param)
|
|
local privs = minetest.get_player_privs(name)
|
|
|
|
if target and watcher ~= target then
|
|
if watching[name] then
|
|
unwatching(param)
|
|
else
|
|
original_pos[watcher] = watcher:getpos()
|
|
end
|
|
|
|
watching[name] = target
|
|
watcher:set_attach(target, "", vector.new(0, -5, -20), vector.new())
|
|
watcher:set_eye_offset(vector.new(0, -5, -20), vector.new())
|
|
watcher:set_nametag_attributes({color = {a = 0}})
|
|
|
|
toggle_hud_flags(watcher, true)
|
|
|
|
watcher:set_properties({
|
|
visual_size = {x = 0, y = 0},
|
|
makes_footstep_sound = false,
|
|
collisionbox = {0}
|
|
})
|
|
|
|
privs.interact = nil
|
|
minetest.set_player_privs(name, privs)
|
|
|
|
return true, "Watching '" .. param .. "' at "..
|
|
minetest.pos_to_string(vector.round(target:getpos()))
|
|
end
|
|
|
|
return false, "Invalid parameter ('" .. param .. "')."
|
|
end
|
|
})
|
|
|
|
minetest.register_chatcommand("unwatch", {
|
|
description = "unwatch a player",
|
|
privs = {watch=true},
|
|
func = function(name, param)
|
|
unwatching(name)
|
|
end
|
|
})
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
local name = player:get_player_name()
|
|
|
|
-- if watched target disconnects, stop spectator mode for the watcher
|
|
for k, v in pairs(watching) do
|
|
if name == v then
|
|
unwatching(k)
|
|
end
|
|
end
|
|
|
|
if watching[name] then
|
|
unwatching(name)
|
|
end
|
|
end)
|