464 lines
15 KiB
Lua
464 lines
15 KiB
Lua
local plyMeta = FindMetaTable("Player")
|
|
local finishWarrantRequest
|
|
local arrestedPlayers = {}
|
|
|
|
--[[---------------------------------------------------------------------------
|
|
Interface functions
|
|
---------------------------------------------------------------------------]]
|
|
function plyMeta:warrant(warranter, reason)
|
|
if self.warranted then return end
|
|
local suppressMsg = hook.Call("playerWarranted", GAMEMODE, self, warranter, reason)
|
|
|
|
self.warranted = true
|
|
timer.Simple(GAMEMODE.Config.searchtime, function()
|
|
if not IsValid(self) then return end
|
|
self:unWarrant(warranter)
|
|
end)
|
|
|
|
if suppressMsg then return end
|
|
|
|
local warranterNick = IsValid(warranter) and warranter:Nick() or DarkRP.getPhrase("disconnected_player")
|
|
local centerMessage = DarkRP.getPhrase("warrant_approved", self:Nick(), reason, warranterNick)
|
|
local printMessage = DarkRP.getPhrase("warrant_ordered", warranterNick, self:Nick(), reason)
|
|
|
|
for _, b in ipairs(player.GetAll()) do
|
|
b:PrintMessage(HUD_PRINTCENTER, centerMessage)
|
|
b:PrintMessage(HUD_PRINTCONSOLE, printMessage)
|
|
end
|
|
|
|
DarkRP.notify(warranter, 0, 4, DarkRP.getPhrase("warrant_approved2"))
|
|
end
|
|
|
|
function plyMeta:unWarrant(unwarranter)
|
|
if not self.warranted then return end
|
|
|
|
local suppressMsg = hook.Call("playerUnWarranted", GAMEMODE, self, unwarranter)
|
|
|
|
self.warranted = false
|
|
|
|
if suppressMsg then return end
|
|
|
|
DarkRP.notify(unwarranter, 2, 4, DarkRP.getPhrase("warrant_expired", self:Nick()))
|
|
end
|
|
|
|
function plyMeta:requestWarrant(suspect, actor, reason)
|
|
local question = DarkRP.getPhrase("warrant_request", actor:Nick(), suspect:Nick(), reason)
|
|
DarkRP.createQuestion(question, suspect:EntIndex() .. "warrant", self, 40, finishWarrantRequest, actor, suspect, reason)
|
|
end
|
|
|
|
function plyMeta:wanted(actor, reason, time)
|
|
local suppressMsg = hook.Call("playerWanted", DarkRP.hooks, self, actor, reason)
|
|
|
|
self:setDarkRPVar("wanted", true)
|
|
self:setDarkRPVar("wantedReason", reason)
|
|
|
|
if time and time > 0 or GAMEMODE.Config.wantedtime > 0 then
|
|
timer.Create(self:SteamID64() .. " wantedtimer", time or GAMEMODE.Config.wantedtime, 1, function()
|
|
if not IsValid(self) then return end
|
|
self:unWanted()
|
|
end)
|
|
end
|
|
|
|
if suppressMsg then return end
|
|
|
|
local actorNick = IsValid(actor) and actor:Nick() or DarkRP.getPhrase("disconnected_player")
|
|
local centerMessage = DarkRP.getPhrase("wanted_by_police", self:Nick(), reason, actorNick)
|
|
local printMessage = DarkRP.getPhrase("wanted_by_police_print", actorNick, self:Nick(), reason)
|
|
|
|
for _, ply in ipairs(player.GetAll()) do
|
|
ply:PrintMessage(HUD_PRINTCENTER, centerMessage)
|
|
ply:PrintMessage(HUD_PRINTCONSOLE, printMessage)
|
|
end
|
|
|
|
DarkRP.log(string.Replace(printMessage, "\n", " "), Color(0, 150, 255))
|
|
end
|
|
|
|
function plyMeta:unWanted(actor)
|
|
local suppressMsg = hook.Call("playerUnWanted", GAMEMODE, self, actor)
|
|
self:setDarkRPVar("wanted", nil)
|
|
self:setDarkRPVar("wantedReason", nil)
|
|
|
|
timer.Remove(self:SteamID64() .. " wantedtimer")
|
|
|
|
if suppressMsg then return end
|
|
|
|
local expiredMessage = IsValid(actor) and DarkRP.getPhrase("wanted_revoked", self:Nick(), actor:Nick() or "") or
|
|
DarkRP.getPhrase("wanted_expired", self:Nick())
|
|
|
|
DarkRP.log(string.Replace(expiredMessage, "\n", " "), Color(0, 150, 255))
|
|
|
|
for _, ply in ipairs(player.GetAll()) do
|
|
ply:PrintMessage(HUD_PRINTCENTER, expiredMessage)
|
|
ply:PrintMessage(HUD_PRINTCONSOLE, expiredMessage)
|
|
end
|
|
end
|
|
|
|
function plyMeta:arrest(time, arrester)
|
|
time = time or GAMEMODE.Config.jailtimer or 120
|
|
|
|
hook.Call("playerArrested", DarkRP.hooks, self, time, arrester)
|
|
if self:InVehicle() then self:ExitVehicle() end
|
|
self:setDarkRPVar("Arrested", true)
|
|
arrestedPlayers[self:SteamID()] = true
|
|
|
|
-- Always get sent to jail when Arrest() is called, even when already under arrest
|
|
if GAMEMODE.Config.teletojail and DarkRP.jailPosCount() ~= 0 then
|
|
self:Spawn()
|
|
end
|
|
end
|
|
|
|
function plyMeta:unArrest(unarrester, teleportOverride)
|
|
if not self:isArrested() then return end
|
|
|
|
self:setDarkRPVar("Arrested", nil)
|
|
arrestedPlayers[self:SteamID()] = nil
|
|
hook.Call("playerUnArrested", DarkRP.hooks, self, unarrester, teleportOverride)
|
|
end
|
|
|
|
function DarkRP.iterateArrestedPlayers()
|
|
local index = nil
|
|
local function iterator()
|
|
local found_player = nil
|
|
index = next(arrestedPlayers, index)
|
|
|
|
if index == nil then return end
|
|
|
|
found_player = player.GetBySteamID(index)
|
|
-- player.GetBySteamID returns false when the player is not in the
|
|
-- server. In that case, skip the player.
|
|
if not found_player then return iterator() end
|
|
|
|
return found_player
|
|
end
|
|
return iterator
|
|
end
|
|
|
|
function DarkRP.arrestedPlayers()
|
|
local result = {}
|
|
for ply in DarkRP.iterateArrestedPlayers() do
|
|
table.insert(result, ply)
|
|
end
|
|
|
|
return result
|
|
end
|
|
|
|
|
|
function DarkRP.arrestedPlayerCount()
|
|
local count = 0
|
|
|
|
for _ in DarkRP.iterateArrestedPlayers() do count = count + 1 end
|
|
|
|
return count
|
|
end
|
|
|
|
--[[---------------------------------------------------------------------------
|
|
Chat commands
|
|
---------------------------------------------------------------------------]]
|
|
local function CombineRequest(ply, args)
|
|
if args == "" then
|
|
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
|
return ""
|
|
end
|
|
|
|
local DoSay = function(text)
|
|
if text == "" then
|
|
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
|
return
|
|
end
|
|
|
|
local col = team.GetColor(ply:Team())
|
|
local col2 = Color(255, 0, 0, 255)
|
|
local phrase = DarkRP.getPhrase("request")
|
|
local name = ply:Nick()
|
|
for _, v in ipairs(player.GetAll()) do
|
|
if v:isCP() or v == ply then
|
|
DarkRP.talkToPerson(v, col, phrase .. " " .. name, col2, text, ply)
|
|
end
|
|
end
|
|
end
|
|
return args, DoSay
|
|
end
|
|
for _, cmd in ipairs{"cr", "911", "999", "112", "000"} do
|
|
DarkRP.defineChatCommand(cmd, CombineRequest, 1.5)
|
|
end
|
|
|
|
local function warrantCommand(ply, args)
|
|
local target = DarkRP.findPlayer(args[1])
|
|
local reason = table.concat(args, " ", 2)
|
|
|
|
local canRequest, message = hook.Call("canRequestWarrant", DarkRP.hooks, target, ply, reason)
|
|
if not canRequest then
|
|
if message then DarkRP.notify(ply, 1, 4, message) end
|
|
return ""
|
|
end
|
|
|
|
local Team = ply:Team()
|
|
if not RPExtraTeams[Team] or not RPExtraTeams[Team].mayor then -- No need to search through all the teams if the player is a mayor
|
|
local mayors = {}
|
|
|
|
for k, v in pairs(RPExtraTeams) do
|
|
if v.mayor then
|
|
table.Add(mayors, team.GetPlayers(k))
|
|
end
|
|
end
|
|
|
|
if not table.IsEmpty(mayors) then -- Request a warrant if there's a mayor
|
|
local mayor = table.Random(mayors)
|
|
mayor:requestWarrant(target, ply, reason)
|
|
DarkRP.notify(ply, 0, 4, DarkRP.getPhrase("warrant_request2", mayor:Nick()))
|
|
return ""
|
|
end
|
|
end
|
|
|
|
target:warrant(ply, reason)
|
|
|
|
return ""
|
|
end
|
|
DarkRP.defineChatCommand("warrant", warrantCommand)
|
|
|
|
local function unwarrantCommand(ply, args)
|
|
local target = DarkRP.findPlayer(args[1])
|
|
local reason = table.concat(args, " ", 2)
|
|
|
|
local canRemove, message = hook.Call("canRemoveWarrant", DarkRP.hooks, target, ply, reason)
|
|
if not canRemove then
|
|
if message then DarkRP.notify(ply, 1, 4, message) end
|
|
return ""
|
|
end
|
|
|
|
target:unWarrant(ply, reason)
|
|
|
|
return ""
|
|
end
|
|
DarkRP.defineChatCommand("unwarrant", unwarrantCommand)
|
|
|
|
local function wantedCommand(ply, args)
|
|
local target = DarkRP.findPlayer(args[1])
|
|
local reason = table.concat(args, " ", 2)
|
|
|
|
local canWanted, message = hook.Call("canWanted", DarkRP.hooks, target, ply, reason)
|
|
if not canWanted then
|
|
if message then DarkRP.notify(ply, 1, 4, message) end
|
|
return ""
|
|
end
|
|
|
|
target:wanted(ply, reason)
|
|
|
|
return ""
|
|
end
|
|
DarkRP.defineChatCommand("wanted", wantedCommand)
|
|
|
|
local function unwantedCommand(ply, args)
|
|
local target = DarkRP.findPlayer(args)
|
|
|
|
local canUnwant, message = hook.Call("canUnwant", DarkRP.hooks, target, ply)
|
|
if not canUnwant then
|
|
if message then DarkRP.notify(ply, 1, 4, message) end
|
|
return ""
|
|
end
|
|
|
|
target:unWanted(ply)
|
|
|
|
return ""
|
|
end
|
|
DarkRP.defineChatCommand("unwanted", unwantedCommand)
|
|
|
|
--[[---------------------------------------------------------------------------
|
|
Admin commands
|
|
---------------------------------------------------------------------------]]
|
|
local function ccArrest(ply, args)
|
|
if DarkRP.jailPosCount() == 0 then
|
|
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("no_jail_pos"))
|
|
return
|
|
end
|
|
|
|
local targets = DarkRP.findPlayers(args[1])
|
|
|
|
if not targets then
|
|
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("could_not_find", args[1]))
|
|
return
|
|
end
|
|
|
|
for _, target in ipairs(targets) do
|
|
local length = tonumber(args[2])
|
|
if length then
|
|
target:arrest(length, ply)
|
|
else
|
|
target:arrest(nil, ply)
|
|
end
|
|
|
|
if ply:EntIndex() == 0 then
|
|
DarkRP.log("Console force-arrested " .. target:SteamName(), Color(0, 255, 255))
|
|
else
|
|
DarkRP.log(ply:Nick() .. " (" .. ply:SteamID() .. ") force-arrested " .. target:SteamName(), Color(0, 255, 255))
|
|
end
|
|
end
|
|
end
|
|
DarkRP.definePrivilegedChatCommand("arrest", "DarkRP_AdminCommands", ccArrest)
|
|
|
|
local function ccUnarrest(ply, args)
|
|
local targets = DarkRP.findPlayers(args[1])
|
|
|
|
if not targets then
|
|
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("could_not_find", args[1]))
|
|
return
|
|
end
|
|
|
|
for _, target in ipairs(targets) do
|
|
target:unArrest(ply)
|
|
if not target:Alive() then target:Spawn() end
|
|
|
|
if ply:EntIndex() == 0 then
|
|
DarkRP.log("Console force-unarrested " .. target:SteamName(), Color(0, 255, 255))
|
|
else
|
|
DarkRP.log(ply:Nick() .. " (" .. ply:SteamID() .. ") force-unarrested " .. target:SteamName(), Color(0, 255, 255))
|
|
end
|
|
end
|
|
end
|
|
DarkRP.definePrivilegedChatCommand("unarrest", "DarkRP_AdminCommands", ccUnarrest)
|
|
|
|
--[[---------------------------------------------------------------------------
|
|
Callback functions
|
|
---------------------------------------------------------------------------]]
|
|
function finishWarrantRequest(choice, mayor, initiator, suspect, reason)
|
|
if not tobool(choice) then
|
|
DarkRP.notify(initiator, 1, 4, DarkRP.getPhrase("warrant_denied", mayor:Nick()))
|
|
return
|
|
end
|
|
if IsValid(suspect) then
|
|
suspect:warrant(initiator, reason)
|
|
end
|
|
end
|
|
|
|
--[[---------------------------------------------------------------------------
|
|
Hooks
|
|
---------------------------------------------------------------------------]]
|
|
|
|
function DarkRP.hooks:canArrest(arrester, arrestee)
|
|
if IsValid(arrestee) and arrestee:IsPlayer() and arrestee:isCP() and not GAMEMODE.Config.cpcanarrestcp then
|
|
return false, DarkRP.getPhrase("cant_arrest_other_cp")
|
|
end
|
|
|
|
if not GAMEMODE.Config.npcarrest and arrestee:IsNPC() then
|
|
return false, DarkRP.getPhrase("unable", "arrest", "NPC")
|
|
end
|
|
|
|
if GAMEMODE.Config.needwantedforarrest and not arrestee:IsNPC() and not arrestee:getDarkRPVar("wanted") then
|
|
return false, DarkRP.getPhrase("must_be_wanted_for_arrest")
|
|
end
|
|
|
|
if arrestee:IsPlayer() and arrestee.FAdmin_GetGlobal and arrestee:FAdmin_GetGlobal("fadmin_jailed") then
|
|
return false, DarkRP.getPhrase("cant_arrest_fadmin_jailed")
|
|
end
|
|
|
|
local jpc = DarkRP.jailPosCount()
|
|
|
|
if not jpc or jpc == 0 then
|
|
return false, DarkRP.getPhrase("cant_arrest_no_jail_pos")
|
|
end
|
|
|
|
if arrestee.Babygod then
|
|
return false, DarkRP.getPhrase("cant_arrest_spawning_players")
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function DarkRP.hooks:playerArrested(ply, time, arrester)
|
|
if ply:isWanted() then ply:unWanted(arrester) end
|
|
local job = RPExtraTeams[ply:Team()]
|
|
if not job or not job.hasLicense then
|
|
ply:setDarkRPVar("HasGunlicense", nil)
|
|
end
|
|
|
|
ply:StripWeapons()
|
|
ply:StripAmmo()
|
|
|
|
if ply:isArrested() then return end -- hasn't been arrested before
|
|
|
|
ply:PrintMessage(HUD_PRINTCENTER, DarkRP.getPhrase("youre_arrested", time))
|
|
|
|
local phrase = DarkRP.getPhrase("hes_arrested", ply:Nick(), time)
|
|
for _, v in ipairs(player.GetAll()) do
|
|
if v == ply then continue end
|
|
v:PrintMessage(HUD_PRINTCENTER, phrase)
|
|
end
|
|
|
|
local steamID = ply:SteamID()
|
|
timer.Create(ply:SteamID64() .. "jailtimer", time, 1, function()
|
|
if IsValid(ply) then ply:unArrest() end
|
|
arrestedPlayers[steamID] = nil
|
|
end)
|
|
umsg.Start("GotArrested", ply)
|
|
umsg.Float(time)
|
|
umsg.End()
|
|
end
|
|
|
|
function DarkRP.hooks:playerUnArrested(ply, actor, teleportOverride)
|
|
if ply:InVehicle() then ply:ExitVehicle() end
|
|
|
|
if ply.Sleeping then
|
|
DarkRP.toggleSleep(ply, "force")
|
|
end
|
|
|
|
if not ply:Alive() and not GAMEMODE.Config.respawninjail then
|
|
ply.NextSpawnTime = CurTime()
|
|
end
|
|
|
|
gamemode.Call("PlayerLoadout", ply)
|
|
-- teleportOverride can either be nil, false, or a vector. Nil means "do not
|
|
-- modify behavior", false means "do not teleport", and a vector means
|
|
-- "teleport to this place instead"
|
|
if (GAMEMODE.Config.telefromjail or teleportOverride ~= nil) and teleportOverride ~= false then
|
|
local pos
|
|
if isvector(teleportOverride) then
|
|
pos = teleportOverride
|
|
else
|
|
local ent
|
|
ent, pos = hook.Call("PlayerSelectSpawn", GAMEMODE, ply)
|
|
pos = pos or ent:GetPos()
|
|
end
|
|
-- workaround for SetPos in weapon event bug
|
|
timer.Simple(0, function() if IsValid(ply) then ply:SetPos(pos) end end)
|
|
end
|
|
|
|
timer.Remove(ply:SteamID64() .. "jailtimer")
|
|
DarkRP.notifyAll(0, 4, DarkRP.getPhrase("hes_unarrested", ply:Nick()))
|
|
end
|
|
|
|
hook.Add("PlayerInitialSpawn", "Arrested", function(ply)
|
|
if not arrestedPlayers[ply:SteamID()] then return end
|
|
local time = GAMEMODE.Config.jailtimer
|
|
-- Delay the actual arrest by a single frame to allow
|
|
-- the player to initialise
|
|
timer.Simple(0, function()
|
|
-- In case the timer ended right this tick
|
|
if not IsValid(ply) or not arrestedPlayers[ply:SteamID()] then return end
|
|
|
|
ply:arrest(time)
|
|
end)
|
|
DarkRP.notify(ply, 0, 5, DarkRP.getPhrase("jail_punishment", time))
|
|
end)
|
|
|
|
function DarkRP.hooks:canGiveLicense(ply, target)
|
|
-- Mayors can hand out licenses
|
|
if ply:isMayor() then return true end
|
|
|
|
local reason = DarkRP.getPhrase("incorrect_job", "/givelicense")
|
|
|
|
local players = player.GetAll()
|
|
-- Chiefs can if there is no mayor
|
|
local mayorExists = #fn.Filter(plyMeta.isMayor, players) > 0
|
|
if mayorExists then return false, reason end
|
|
|
|
if ply:isChief() then return true end
|
|
|
|
-- CPs can if there are no chiefs nor mayors
|
|
local chiefExists = #fn.Filter(plyMeta.isChief, players) > 0
|
|
if chiefExists then return false, reason end
|
|
|
|
if ply:isCP() then return true end
|
|
|
|
return false, reason
|
|
end
|