310 lines
9.2 KiB
Lua
310 lines
9.2 KiB
Lua
AddCSLuaFile()
|
|
|
|
if CLIENT then
|
|
SWEP.Slot = 5
|
|
SWEP.SlotPos = 1
|
|
SWEP.DrawAmmo = false
|
|
SWEP.DrawCrosshair = false
|
|
end
|
|
|
|
-- Variables that are used on both client and server
|
|
|
|
SWEP.PrintName = "Lock Pick"
|
|
SWEP.Author = "DarkRP Developers"
|
|
SWEP.Instructions = "Left or right click to pick a lock"
|
|
SWEP.Contact = ""
|
|
SWEP.Purpose = ""
|
|
SWEP.IsDarkRPLockpick = true
|
|
|
|
SWEP.ViewModelFOV = 62
|
|
SWEP.ViewModelFlip = false
|
|
SWEP.ViewModel = Model("models/weapons/c_crowbar.mdl")
|
|
SWEP.WorldModel = Model("models/weapons/w_crowbar.mdl")
|
|
|
|
SWEP.UseHands = true
|
|
|
|
SWEP.Spawnable = true
|
|
SWEP.AdminOnly = true
|
|
SWEP.Category = "DarkRP (Utility)"
|
|
|
|
SWEP.Sound = Sound("physics/wood/wood_box_impact_hard3.wav")
|
|
|
|
SWEP.Primary.ClipSize = -1 -- Size of a clip
|
|
SWEP.Primary.DefaultClip = 0 -- Default number of bullets in a clip
|
|
SWEP.Primary.Automatic = false -- Automatic/Semi Auto
|
|
SWEP.Primary.Ammo = ""
|
|
|
|
SWEP.Secondary.ClipSize = -1 -- Size of a clip
|
|
SWEP.Secondary.DefaultClip = -1 -- Default number of bullets in a clip
|
|
SWEP.Secondary.Automatic = false -- Automatic/Semi Auto
|
|
SWEP.Secondary.Ammo = ""
|
|
|
|
function SWEP:SetupDataTables()
|
|
self:NetworkVar("Bool", 0, "IsLockpicking")
|
|
self:NetworkVar("Float", 0, "LockpickStartTime")
|
|
self:NetworkVar("Float", 1, "LockpickEndTime")
|
|
self:NetworkVar("Float", 2, "NextSoundTime")
|
|
self:NetworkVar("Int", 0, "TotalLockpicks")
|
|
self:NetworkVar("Entity", 0, "LockpickEnt")
|
|
end
|
|
|
|
function SWEP:Initialize()
|
|
self:SetHoldType("normal")
|
|
end
|
|
|
|
function SWEP:PrimaryAttack()
|
|
self:SetNextPrimaryFire(CurTime() + 0.5)
|
|
if self:GetIsLockpicking() then return end
|
|
|
|
local Owner = self:GetOwner()
|
|
|
|
if not IsValid(Owner) then return end
|
|
|
|
Owner:LagCompensation(true)
|
|
local trace = Owner:GetEyeTrace()
|
|
Owner:LagCompensation(false)
|
|
local ent = trace.Entity
|
|
|
|
if not IsValid(ent) or ent.DarkRPCanLockpick == false then return end
|
|
local canLockpick = hook.Call("canLockpick", nil, Owner, ent, trace)
|
|
|
|
if canLockpick == false then return end
|
|
if canLockpick ~= true and (
|
|
trace.HitPos:DistToSqr(Owner:GetShootPos()) > 10000 or
|
|
(not GAMEMODE.Config.canforcedooropen and ent:getKeysNonOwnable()) or
|
|
(not ent:isDoor() and not ent:IsVehicle() and not string.find(string.lower(ent:GetClass()), "vehicle") and (not GAMEMODE.Config.lockpickfading or not ent.isFadingDoor))
|
|
) then
|
|
return
|
|
end
|
|
|
|
self:SetHoldType("pistol")
|
|
|
|
self:SetIsLockpicking(true)
|
|
self:SetLockpickEnt(ent)
|
|
self:SetLockpickStartTime(CurTime())
|
|
local endDelta = hook.Call("lockpickTime", nil, Owner, ent) or util.SharedRandom("DarkRP_Lockpick" .. self:EntIndex() .. "_" .. self:GetTotalLockpicks(), 10, 30)
|
|
self:SetLockpickEndTime(CurTime() + endDelta)
|
|
self:SetTotalLockpicks(self:GetTotalLockpicks() + 1)
|
|
|
|
|
|
if IsFirstTimePredicted() then
|
|
hook.Call("lockpickStarted", nil, Owner, ent, trace)
|
|
end
|
|
|
|
if CLIENT then
|
|
self.Dots = ""
|
|
self.NextDotsTime = SysTime() + 0.5
|
|
return
|
|
end
|
|
|
|
local onFail = function(ply) if ply == Owner then hook.Call("onLockpickCompleted", nil, ply, false, ent) end end
|
|
|
|
-- Lockpick fails when dying or disconnecting
|
|
hook.Add("PlayerDeath", self, fc{onFail, fn.Flip(fn.Const)})
|
|
hook.Add("PlayerDisconnected", self, fc{onFail, fn.Flip(fn.Const)})
|
|
-- Remove hooks when finished
|
|
hook.Add("onLockpickCompleted", self, fc{fp{hook.Remove, "PlayerDisconnected", self}, fp{hook.Remove, "PlayerDeath", self}})
|
|
end
|
|
|
|
function SWEP:Holster()
|
|
if self:GetIsLockpicking() and self:GetLockpickEndTime() ~= 0 then
|
|
self:Fail()
|
|
end
|
|
return true
|
|
end
|
|
|
|
function SWEP:Succeed()
|
|
self:SetHoldType("normal")
|
|
|
|
local ent = self:GetLockpickEnt()
|
|
self:SetIsLockpicking(false)
|
|
self:SetLockpickEnt(nil)
|
|
|
|
if not IsValid(ent) then return end
|
|
|
|
local override = hook.Call("onLockpickCompleted", nil, self:GetOwner(), true, ent)
|
|
|
|
if override then return end
|
|
|
|
if ent.isFadingDoor and ent.fadeActivate and not ent.fadeActive then
|
|
ent:fadeActivate()
|
|
if IsFirstTimePredicted() then timer.Simple(5, function() if IsValid(ent) and ent.fadeActive then ent:fadeDeactivate() end end) end
|
|
elseif ent.Fire then
|
|
ent:keysUnLock()
|
|
ent:Fire("open", "", .6)
|
|
ent:Fire("setanimation", "open", .6)
|
|
end
|
|
end
|
|
|
|
function SWEP:Fail()
|
|
self:SetIsLockpicking(false)
|
|
self:SetHoldType("normal")
|
|
|
|
hook.Call("onLockpickCompleted", nil, self:GetOwner(), false, self:GetLockpickEnt())
|
|
self:SetLockpickEnt(nil)
|
|
end
|
|
|
|
local colorBackground = Color(10, 10, 10, 120)
|
|
local dots = {
|
|
[0] = ".",
|
|
[1] = "..",
|
|
[2] = "...",
|
|
[3] = ""
|
|
}
|
|
function SWEP:Think()
|
|
if not self:GetIsLockpicking() or self:GetLockpickEndTime() == 0 then return end
|
|
|
|
if CurTime() >= self:GetNextSoundTime() then
|
|
self:SetNextSoundTime(CurTime() + 1)
|
|
local snd = {1,3,4}
|
|
self:EmitSound("weapons/357/357_reload" .. tostring(snd[math.Round(util.SharedRandom("DarkRP_LockpickSnd" .. CurTime(), 1, #snd))]) .. ".wav", 50, 100)
|
|
end
|
|
if CLIENT and (not self.NextDotsTime or SysTime() >= self.NextDotsTime) then
|
|
self.NextDotsTime = SysTime() + 0.5
|
|
self.Dots = self.Dots or ""
|
|
local len = string.len(self.Dots)
|
|
|
|
self.Dots = dots[len]
|
|
end
|
|
|
|
local trace = self:GetOwner():GetEyeTrace()
|
|
if not IsValid(trace.Entity) or trace.Entity ~= self:GetLockpickEnt() or trace.HitPos:DistToSqr(self:GetOwner():GetShootPos()) > 10000 then
|
|
self:Fail()
|
|
elseif self:GetLockpickEndTime() <= CurTime() then
|
|
self:Succeed()
|
|
end
|
|
end
|
|
|
|
function SWEP:DrawHUD()
|
|
if not self:GetIsLockpicking() or self:GetLockpickEndTime() == 0 then return end
|
|
|
|
self.Dots = self.Dots or ""
|
|
local w = ScrW()
|
|
local h = ScrH()
|
|
local x, y, width, height = w / 2 - w / 10, h / 2 - 60, w / 5, h / 15
|
|
draw.RoundedBox(8, x, y, width, height, colorBackground)
|
|
|
|
local time = self:GetLockpickEndTime() - self:GetLockpickStartTime()
|
|
local curtime = CurTime() - self:GetLockpickStartTime()
|
|
local status = math.Clamp(curtime / time, 0, 1)
|
|
local BarWidth = status * (width - 16)
|
|
local cornerRadius = math.Min(8, BarWidth / 3 * 2 - BarWidth / 3 * 2 % 2)
|
|
draw.RoundedBox(cornerRadius, x + 8, y + 8, BarWidth, height - 16, Color(255 - (status * 255), 0 + (status * 255), 0, 255))
|
|
|
|
draw.DrawNonParsedSimpleText(DarkRP.getPhrase("picking_lock") .. self.Dots, "Trebuchet24", w / 2, y + height / 2, color_white, 1, 1)
|
|
end
|
|
|
|
function SWEP:SecondaryAttack()
|
|
self:PrimaryAttack()
|
|
end
|
|
|
|
|
|
DarkRP.hookStub{
|
|
name = "canLockpick",
|
|
description = "Whether an entity can be lockpicked.",
|
|
parameters = {
|
|
{
|
|
name = "ply",
|
|
description = "The player attempting to lockpick an entity.",
|
|
type = "Player"
|
|
},
|
|
{
|
|
name = "ent",
|
|
description = "The entity being lockpicked.",
|
|
type = "Entity"
|
|
},
|
|
{
|
|
name = "trace",
|
|
description = "The trace result.",
|
|
type = "table"
|
|
}
|
|
},
|
|
returns = {
|
|
{
|
|
name = "allowed",
|
|
description = "Whether the entity can be lockpicked",
|
|
type = "boolean"
|
|
}
|
|
},
|
|
realm = "Shared"
|
|
}
|
|
|
|
DarkRP.hookStub{
|
|
name = "lockpickStarted",
|
|
description = "Called when a player is about to pick a lock.",
|
|
parameters = {
|
|
{
|
|
name = "ply",
|
|
description = "The player that is about to pick a lock.",
|
|
type = "Player"
|
|
},
|
|
{
|
|
name = "ent",
|
|
description = "The entity being lockpicked.",
|
|
type = "Entity"
|
|
},
|
|
{
|
|
name = "trace",
|
|
description = "The trace result.",
|
|
type = "table"
|
|
}
|
|
},
|
|
returns = {},
|
|
realm = "Shared"
|
|
}
|
|
|
|
DarkRP.hookStub{
|
|
name = "onLockpickCompleted",
|
|
description = "Result of a player attempting to lockpick an entity.",
|
|
parameters = {
|
|
{
|
|
name = "ply",
|
|
description = "The player attempting to lockpick the entity.",
|
|
type = "Player"
|
|
},
|
|
{
|
|
name = "success",
|
|
description = "Whether the player succeeded in lockpicking the entity.",
|
|
type = "boolean"
|
|
},
|
|
{
|
|
name = "ent",
|
|
description = "The entity that was lockpicked.",
|
|
type = "Entity"
|
|
},
|
|
},
|
|
returns = {
|
|
{
|
|
name = "override",
|
|
description = "Return true to override default behaviour, which is opening the (fading) door.",
|
|
type = "boolean"
|
|
}
|
|
},
|
|
realm = "Shared"
|
|
}
|
|
|
|
DarkRP.hookStub{
|
|
name = "lockpickTime",
|
|
description = "The length of time, in seconds, it takes to lockpick an entity.",
|
|
parameters = {
|
|
{
|
|
name = "ply",
|
|
description = "The player attempting to lockpick an entity.",
|
|
type = "Player"
|
|
},
|
|
{
|
|
name = "ent",
|
|
description = "The entity being lockpicked.",
|
|
type = "Entity"
|
|
},
|
|
},
|
|
returns = {
|
|
{
|
|
name = "time",
|
|
description = "Seconds in which it takes a player to lockpick an entity",
|
|
type = "number"
|
|
}
|
|
},
|
|
realm = "Shared"
|
|
}
|