dobrograd-13-06-2022/garrysmod/gamemodes/darkrp/gamemode/modules/fspectate/sv_init.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

121 lines
3.5 KiB
Lua

util.AddNetworkString("FSpectate")
local function findPlayer(info)
if not info or info == "" then return nil end
local pls = player.GetAll()
for k = 1, #pls do
local v = pls[k]
if tonumber(info) == v:UserID() then
return v
end
if info == v:SteamID() then
return v
end
if string.find(string.lower(v:Name()), string.lower(tostring(info)), 1, true) ~= nil then
return v
end
end
return nil
end
local function Spectate(ply, cmd, args)
CAMI.PlayerHasAccess(ply, "FSpectate", function(b, _)
if not b then ply:ChatPrint("No Access!") return end
local target = findPlayer(args[1])
if target == ply then ply:ChatPrint("Invalid target!") return end
ply.FSpectatingEnt = target
ply.FSpectating = true
hook.Run('fspectate.start', ply, target)
ply:ExitVehicle()
net.Start("FSpectate")
net.WriteBool(target == nil)
if IsValid(ply.FSpectatingEnt) then
net.WriteEntity(ply.FSpectatingEnt)
end
net.Send(ply)
local targetText = IsValid(target) and (target:Nick() .. " (" .. target:SteamID() .. ")") or ""
ply:ChatPrint("You are now spectating " .. targetText)
end)
end
concommand.Add("FSpectate", Spectate)
local function TPToPos(ply, cmd, args)
CAMI.PlayerHasAccess(ply, "FSpectateTeleport", function(b, _)
if not b then ply:ChatPrint("No Access!") return end
local x, y, z = string.match(args[1] or "", "([-0-9\\.]+),%s?([-0-9\\.]+),%s?([-0-9\\.]+)")
local vx, vy, vz = string.match(args[2] or "", "([-0-9\\.]+),%s?([-0-9\\.]+),%s?([-0-9\\.]+)")
local pos = Vector(tonumber(x), tonumber(y), tonumber(z))
local vel = Vector(tonumber(vx or 0), tonumber(vy or 0), tonumber(vz or 0))
if not args[1] or not x or not y or not z then return end
ply:SetPos(pos)
if vx and vy and vz then ply:SetVelocity(vel) end
end)
end
concommand.Add("FTPToPos", TPToPos)
local function SpectateVisibility(ply, viewEnt)
if not ply.FSpectating then return end
if IsValid(ply.FSpectatingEnt) then
AddOriginToPVS(ply.FSpectatingEnt:GetShootPos())
end
if ply.FSpectatePos then
AddOriginToPVS(ply.FSpectatePos)
end
end
hook.Add("SetupPlayerVisibility", "FSpectate", SpectateVisibility)
local function setSpectatePos(ply, cmd, args)
CAMI.PlayerHasAccess(ply, "FSpectate", function(b, _)
if not b then ply:ChatPrint("No Access!") return end
if not ply.FSpectating or not args[3] then return end
local x, y, z = tonumber(args[1] or 0), tonumber(args[2] or 0), tonumber(args[3] or 0)
ply.FSpectatePos = Vector(x, y, z)
end)
end
concommand.Add("_FSpectatePosUpdate", setSpectatePos)
local function endSpectate(ply, cmd, args)
ply.FSpectatingEnt = nil
ply.FSpectating = nil
ply.FSpectatePos = nil
hook.Run('fspectate.end', ply)
end
concommand.Add("FSpectate_StopSpectating", endSpectate)
local function playerVoice(listener, talker)
if not IsValid(listener.FSpectatingEnt) then return end
-- You can hear someone if your spectate target can hear them
local canHear, surround = GAMEMODE:PlayerCanHearPlayersVoice(listener.FSpectatingEnt, talker)
local canHearLocal = GAMEMODE:PlayerCanHearPlayersVoice(listener, talker)
-- you can always hear the person you're spectating
return canHear or canHearLocal or listener.FSpectatingEnt == talker, surround
end
hook.Add("PlayerCanHearPlayersVoice", "FSpectate", playerVoice)
-- ULX' !spectate command conflicts with mine
-- The concommand "ulx spectate" should still work.
local function fixULXIncompat()
if ULib then
ULib.removeSayCommand("!spectate")
end
end
hook.Add("InitPostEntity", "FSpectate", fixULXIncompat)