Files
wnsrc/lua/sam/modules/teleport.lua

198 lines
4.6 KiB
Lua
Raw Normal View History

2024-08-04 22:55:00 +03:00
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
if SAM_LOADED then return end
local sam, command, language = sam, sam.command, sam.language
command.set_category("Teleport")
local find_empty_pos -- https://github.com/FPtje/DarkRP/blob/b147d6fa32799136665a9fd52d35c2fe87cf7f78/gamemode/modules/base/sv_util.lua#L149
do
local is_empty = function(vector, ignore)
local point = util.PointContents(vector)
local a = point ~= CONTENTS_SOLID
and point ~= CONTENTS_MOVEABLE
and point ~= CONTENTS_LADDER
and point ~= CONTENTS_PLAYERCLIP
and point ~= CONTENTS_MONSTERCLIP
if not a then return false end
local ents_found = ents.FindInSphere(vector, 35)
for i = 1, #ents_found do
local v = ents_found[i]
if (v:IsNPC() or v:IsPlayer() or v:GetClass() == "prop_physics" or v.NotEmptyPos) and v ~= ignore then
return false
end
end
return true
end
local distance, step, area = 600, 30, Vector(16, 16, 64)
local north_vec, east_vec, up_vec = Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)
find_empty_pos = function(pos, ignore)
if is_empty(pos, ignore) and is_empty(pos + area, ignore) then
return pos
end
for j = step, distance, step do
for i = -1, 1, 2 do
local k = j * i
-- North/South
north_vec.x = k
if is_empty(pos + north_vec, ignore) and is_empty(pos + north_vec + area, ignore) then
return pos + north_vec
end
-- East/West
east_vec.y = k
if is_empty(pos + east_vec, ignore) and is_empty(pos + east_vec + area, ignore) then
return pos + east_vec
end
-- Up/Down
up_vec.z = k
if is_empty(pos + up_vec, ignore) and is_empty(pos + up_vec + area, ignore) then
return pos + up_vec
end
end
end
return pos
end
end
command.new("bring")
:DisallowConsole()
:SetPermission("bring", "admin")
:AddArg("player", {cant_target_self = true})
:Help("bring_help")
:OnExecute(function(ply, targets)
if not ply:Alive() then
return ply:sam_send_message("dead")
end
if ply:InVehicle() then
return ply:sam_send_message("leave_car")
end
if ply:sam_get_exclusive(ply) then
return ply:sam_send_message(ply:sam_get_exclusive(ply))
end
local teleported = {admin = ply}
local all = targets.input == "*"
for i = 1, #targets do
local target = targets[i]
if target:sam_get_exclusive(ply) then
if not all then
ply:sam_send_message(target:sam_get_exclusive(ply))
end
continue
end
if not target:Alive() then
target:Spawn()
end
target.sam_tele_pos, target.sam_tele_ang = target:GetPos(), target:EyeAngles()
target:ExitVehicle()
target:SetVelocity(Vector(0, 0, 0))
target:SetPos(find_empty_pos(ply:GetPos(), target))
target:SetEyeAngles((ply:EyePos() - target:EyePos()):Angle())
table.insert(teleported, target)
end
if #teleported > 0 then
sam.player.send_message(nil, "bring", {
A = ply, T = teleported
})
end
end)
:End()
command.new("goto")
:DisallowConsole()
:SetPermission("goto", "admin")
:AddArg("player", {single_target = true, allow_higher_target = true, cant_target_self = true})
:Help("goto_help")
:OnExecute(function(ply, targets)
if ply:sam_get_exclusive(ply) then
return ply:sam_send_message(ply:sam_get_exclusive(ply))
end
if not ply:Alive() then
ply:Spawn()
end
local target = targets[1]
ply.sam_tele_pos, ply.sam_tele_ang = ply:GetPos(), ply:EyeAngles()
ply:ExitVehicle()
ply:SetVelocity(Vector(0, 0, 0))
ply:SetPos(find_empty_pos(target:GetPos(), ply))
ply:SetEyeAngles((target:EyePos() - ply:EyePos()):Angle())
sam.player.send_message(nil, "goto", {
A = ply, T = targets
})
end)
:End()
command.new("return")
:SetPermission("return", "admin")
:AddArg("player", {single_target = true, optional = true})
:Help("return_help")
:OnExecute(function(ply, targets)
local target = targets[1]
local last_pos, last_ang = target.sam_tele_pos, target.sam_tele_ang
if not last_pos then
return sam.player.send_message(ply, "no_location", {
T = targets
})
end
if target:sam_get_exclusive(ply) then
return ply:sam_send_message(target:sam_get_exclusive(ply))
end
if not target:Alive() then
return ply:sam_send_message(target:Name() .. " is dead!")
end
target:ExitVehicle()
target:SetVelocity(Vector(0, 0, 0))
target:SetPos(last_pos)
target:SetEyeAngles(last_ang)
target.sam_tele_pos, target.sam_tele_ang = nil, nil
sam.player.send_message(nil, "returned", {
A = ply, T = targets
})
end)
:End()