Initial commit
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
include("shared.lua")
|
||||
|
||||
ENT.DrawPos = Vector(1, -111, 58)
|
||||
|
||||
ENT.Width = 558
|
||||
ENT.Height = 290
|
||||
|
||||
ENT.HeaderMargin = 10
|
||||
ENT.BodyMargin = 10
|
||||
|
||||
ENT.HeaderFont = "Trebuchet48"
|
||||
ENT.BodyFont = "DermaLarge"
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
local DrawPos = self:LocalToWorld(self.DrawPos)
|
||||
|
||||
local DrawAngles = self:GetAngles()
|
||||
DrawAngles:RotateAroundAxis(self:GetAngles():Forward(), 90)
|
||||
DrawAngles:RotateAroundAxis(self:GetAngles():Up(), 90)
|
||||
|
||||
local backgroundColor = self:GetBackgroundColor() * 255
|
||||
local barColor = self:GetBarColor() * 255
|
||||
local topText = DarkRP.textWrap(self:GetTopText(), self.HeaderFont, self.Width - self.BodyMargin * 2)
|
||||
|
||||
local bottomText = string.gsub(string.gsub(self:GetBottomText() or "", "//", "\n"), "\\n", "\n")
|
||||
bottomText = DarkRP.textWrap(string.Replace(bottomText, "\\n", "\n"), self.BodyFont, self.Width - self.BodyMargin * 2)
|
||||
|
||||
if not self.HeaderFontHeight then self.HeaderFontHeight = draw.GetFontHeight(self.HeaderFont) end
|
||||
|
||||
local barHeight = 1
|
||||
for _ in string.gmatch(topText, "\n") do barHeight = barHeight + 1 end
|
||||
barHeight = self.HeaderMargin * 2 + barHeight * self.HeaderFontHeight
|
||||
|
||||
local centerX = self.Width / 2
|
||||
|
||||
render.EnableClipping(true)
|
||||
local normal = self:GetUp()
|
||||
render.PushCustomClipPlane(normal, normal:Dot(DrawPos - normal * self.Height * 0.4))
|
||||
|
||||
cam.Start3D2D(DrawPos, DrawAngles, 0.4)
|
||||
|
||||
surface.SetDrawColor(backgroundColor.x, backgroundColor.y, backgroundColor.z, 255)
|
||||
surface.DrawRect(0, 0, self.Width, self.Height)
|
||||
|
||||
draw.RoundedBox(0, 0, 0, self.Width, barHeight, Color(barColor.x, barColor.y, barColor.z))
|
||||
|
||||
draw.DrawText(topText, self.HeaderFont, centerX, self.HeaderMargin, color_white, TEXT_ALIGN_CENTER)
|
||||
draw.DrawText(bottomText, self.BodyFont, centerX, barHeight + self.BodyMargin, color_white, TEXT_ALIGN_CENTER)
|
||||
|
||||
cam.End3D2D()
|
||||
|
||||
render.PopCustomClipPlane()
|
||||
render.EnableClipping(false)
|
||||
end
|
||||
|
||||
language.Add("Cleaned_advert_billboards", "Cleaned up Advert Billboards")
|
||||
language.Add("Cleanup_advert_billboards", "Advert Billboards")
|
||||
language.Add("Undone_advert_billboard", "Undone Advert Billboard")
|
||||
100
gamemodes/darkrp/entities/entities/darkrp_billboard/init.lua
Normal file
100
gamemodes/darkrp/entities/entities/darkrp_billboard/init.lua
Normal file
@@ -0,0 +1,100 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel(self.Model or "models/props/cs_assault/billboard.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_WORLD)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SetDefaults(txt)
|
||||
txt = string.gsub(string.gsub(txt or "", "//", "\n"), "\\n", "\n")
|
||||
local split = string.Split(txt, "\n") or {}
|
||||
local hasTitle = #split > 1
|
||||
if not hasTitle then split = string.Split(txt, " ") end
|
||||
|
||||
self:SetTopText(split[1] or "Placeholder")
|
||||
self:SetBottomText(table.concat(split, hasTitle and "\n" or " ", 2))
|
||||
|
||||
self:SetBarColor(Vector(1, 0.5, 0))
|
||||
end
|
||||
|
||||
local function canEditVariable(self, ent, ply, key, val, editor)
|
||||
if self ~= ent then return end
|
||||
return self:CPPICanPhysgun(ply)
|
||||
end
|
||||
|
||||
local function placeBillboard(ply, args)
|
||||
local canEdit, message = hook.Call("canAdvert", nil, ply, args)
|
||||
|
||||
if canEdit == false then
|
||||
DarkRP.notify(ply, 1, 4, message or DarkRP.getPhrase("unable", GAMEMODE.Config.chatCommandPrefix .. "advert", ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
ply.DarkRP_advertboards = ply.DarkRP_advertboards or 0
|
||||
|
||||
if ply.DarkRP_advertboards >= GAMEMODE.Config.maxadvertbillboards then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("limit", GAMEMODE.Config.chatCommandPrefix .. "advert"))
|
||||
return ""
|
||||
end
|
||||
|
||||
local trace = {}
|
||||
trace.start = ply:EyePos()
|
||||
trace.endpos = trace.start + ply:GetAimVector() * 85
|
||||
trace.filter = ply
|
||||
|
||||
local tr = util.TraceLine(trace)
|
||||
|
||||
local ent = ents.Create("darkrp_billboard")
|
||||
ent:SetPos(tr.HitPos + Vector(0, 0, (ply:GetPos().z - tr.HitPos.z) + 69))
|
||||
|
||||
local ang = ply:GetAngles()
|
||||
ang:RotateAroundAxis(ang:Up(), 180)
|
||||
ent:SetAngles(ang)
|
||||
|
||||
ent:CPPISetOwner(ply)
|
||||
ent.SID = ply.SID
|
||||
|
||||
ent:SetDefaults(args)
|
||||
hook.Add("CanEditVariable", ent, canEditVariable)
|
||||
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
if IsValid(ent) then
|
||||
ply.DarkRP_advertboards = ply.DarkRP_advertboards + 1
|
||||
end
|
||||
|
||||
ply:DeleteOnRemove(ent)
|
||||
|
||||
undo.Create("advert_billboard")
|
||||
undo.SetPlayer(ply)
|
||||
undo.AddEntity(ent)
|
||||
undo.Finish()
|
||||
|
||||
ply:AddCleanup("advert_billboards", ent)
|
||||
|
||||
hook.Call("playerAdverted", nil, ply, args, ent)
|
||||
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("advert", placeBillboard)
|
||||
|
||||
function ENT:OnRemove()
|
||||
local ply = Player(self.SID)
|
||||
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
ply.DarkRP_advertboards = (ply.DarkRP_advertboards or 1) - 1
|
||||
end
|
||||
113
gamemodes/darkrp/entities/entities/darkrp_billboard/shared.lua
Normal file
113
gamemodes/darkrp/entities/entities/darkrp_billboard/shared.lua
Normal file
@@ -0,0 +1,113 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "DarkRP billboard"
|
||||
ENT.Instructions = "Shows advertisements."
|
||||
ENT.Author = "FPtje"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.Editable = true
|
||||
ENT.IsDarkRPBillboard = true
|
||||
|
||||
cleanup.Register("advert_billboards")
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("String", 0, "TopText", {
|
||||
KeyName = "toptext",
|
||||
Edit = {
|
||||
type = "Generic",
|
||||
title = "Top text",
|
||||
category = "Text",
|
||||
order = 0
|
||||
}
|
||||
})
|
||||
|
||||
self:NetworkVar("String", 1, "BottomText", {
|
||||
KeyName = "bottomtext",
|
||||
Edit = {
|
||||
type = "Generic",
|
||||
title = "Bottom text",
|
||||
category = "Text",
|
||||
order = 1
|
||||
}
|
||||
})
|
||||
|
||||
self:NetworkVar("Vector", 0, "BackgroundColor", {
|
||||
KeyName = "backgroundcolor",
|
||||
Edit = {
|
||||
type = "VectorColor",
|
||||
title = "Background color",
|
||||
category = "Color",
|
||||
order = 0
|
||||
}
|
||||
})
|
||||
|
||||
self:NetworkVar("Vector", 1, "BarColor", {
|
||||
KeyName = "barcolor",
|
||||
Edit = {
|
||||
type = "VectorColor",
|
||||
title = "Top bar color",
|
||||
category = "Color",
|
||||
order = 1
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "advert",
|
||||
description = "Create a billboard holding an advertisement.",
|
||||
delay = 1.5
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canAdvert",
|
||||
description = "Whether someone can place an advertisement billboard.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player trying to advertise.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "arguments",
|
||||
description = "The advertisement itself.",
|
||||
type = "table"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "canAdvert",
|
||||
description = "A yes or no as to whether the player can place the billboard.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "message",
|
||||
description = "The message that is shown when they can't place the billboard.",
|
||||
type = "string"
|
||||
}
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerAdverted",
|
||||
description = "Called when a player placed an advertisement billboard.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "arguments",
|
||||
description = "The advertisement itself.",
|
||||
type = "string"
|
||||
},
|
||||
{
|
||||
name = "entity",
|
||||
description = "The placed advertisement billboard.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {},
|
||||
realm = "Server"
|
||||
}
|
||||
31
gamemodes/darkrp/entities/entities/darkrp_cheque/cl_init.lua
Normal file
31
gamemodes/darkrp/entities/entities/darkrp_cheque/cl_init.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
include("shared.lua")
|
||||
|
||||
ENT.TextColors = {
|
||||
OtherToSelf = Color(0, 255, 0, 255),
|
||||
SelfToSelf = Color(255, 255, 0, 255),
|
||||
SelfToOther = Color(0, 0, 255, 255),
|
||||
OtherToOther = Color(255, 0, 0, 255)
|
||||
}
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
local owner = self:Getowning_ent()
|
||||
local recipient = self:Getrecipient()
|
||||
local ownerplayer = owner:IsPlayer()
|
||||
local recipientplayer = recipient:IsPlayer()
|
||||
local localplayer = LocalPlayer()
|
||||
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
local Up = Ang:Up()
|
||||
Up:Mul(0.9)
|
||||
Pos:Add(Up)
|
||||
|
||||
surface.SetFont("ChatFont")
|
||||
local text = DarkRP.getPhrase("cheque_pay", recipientplayer and recipient:Nick() or DarkRP.getPhrase("unknown")) .. "\n" .. DarkRP.formatMoney(self:Getamount()) .. "\n" .. DarkRP.getPhrase("signed", ownerplayer and owner:Nick() or DarkRP.getPhrase("unknown"))
|
||||
|
||||
cam.Start3D2D(Pos, Ang, 0.1)
|
||||
draw.DrawNonParsedText(text, "ChatFont", surface.GetTextSize(text) * -0.5, -25, localplayer:IsValid() and (ownerplayer and localplayer == owner and (recipientplayer and localplayer == recipient and self.TextColors.SelfToSelf or self.TextColors.SelfToOther) or recipientplayer and localplayer == recipient and self.TextColors.OtherToSelf) or self.TextColors.OtherToOther, 0)
|
||||
cam.End3D2D()
|
||||
end
|
||||
147
gamemodes/darkrp/entities/entities/darkrp_cheque/init.lua
Normal file
147
gamemodes/darkrp/entities/entities/darkrp_cheque/init.lua
Normal file
@@ -0,0 +1,147 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_lab/clipboard.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
|
||||
self.nodupe = true
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
hook.Add("PlayerDisconnected", self, self.onPlayerDisconnected)
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
local owner = self:Getowning_ent()
|
||||
local recipient = self:Getrecipient()
|
||||
local amount = self:Getamount() or 0
|
||||
|
||||
if (IsValid(activator) and IsValid(recipient)) and activator == recipient then
|
||||
owner = (IsValid(owner) and owner:Nick()) or DarkRP.getPhrase("disconnected_player")
|
||||
DarkRP.notify(activator, 0, 4, DarkRP.getPhrase("found_cheque", DarkRP.formatMoney(amount), "", owner))
|
||||
activator:addMoney(amount)
|
||||
hook.Call("playerPickedUpCheque", nil, activator, recipient, amount or 0, true, self)
|
||||
self:Remove()
|
||||
elseif (IsValid(owner) and IsValid(recipient)) and owner ~= activator then
|
||||
DarkRP.notify(activator, 0, 4, DarkRP.getPhrase("cheque_details", recipient:Nick()))
|
||||
hook.Call("playerPickedUpCheque", nil, activator, recipient, amount or 0, false, self)
|
||||
elseif IsValid(owner) and owner == activator then
|
||||
DarkRP.notify(activator, 0, 4, DarkRP.getPhrase("cheque_torn"))
|
||||
owner:addMoney(self:Getamount()) -- return the money on the cheque to the owner.
|
||||
hook.Call("playerToreUpCheque", nil, activator, recipient, amount, self)
|
||||
self:Remove()
|
||||
elseif not IsValid(recipient) then self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:StartTouch(ent)
|
||||
-- the .USED var is also used in other mods for the same purpose
|
||||
if ent:GetClass() ~= "darkrp_cheque" or self.USED or ent.USED or self.hasMerged or ent.hasMerged then return end
|
||||
if ent:Getowning_ent() ~= self:Getowning_ent() then return end
|
||||
if ent:Getrecipient() ~= self:Getrecipient() then return end
|
||||
|
||||
-- Both hasMerged and USED are used by third party mods. Keep both in.
|
||||
ent.USED = true
|
||||
ent.hasMerged = true
|
||||
|
||||
ent:Remove()
|
||||
self:Setamount(self:Getamount() + ent:Getamount())
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
local typ = dmg:GetDamageType()
|
||||
if bit.band(typ, bit.bor(DMG_FALL, DMG_VEHICLE, DMG_DROWN, DMG_RADIATION, DMG_PHYSGUN)) > 0 then return end
|
||||
|
||||
self.USED = true
|
||||
self.hasMerged = true
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:onPlayerDisconnected(ply)
|
||||
if self:Getowning_ent() == ply or self:Getrecipient() == ply then
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerPickedUpCheque",
|
||||
description = "Called when a player picks up a cheque.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who attempted to pick up the cheque.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who the cheque was written to.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "amount",
|
||||
description = "The amount of money the cheque has.",
|
||||
type = "number"
|
||||
},
|
||||
{
|
||||
name = "success",
|
||||
description = "Whether the player was allowed to cash the cheque.",
|
||||
type = "bool"
|
||||
},
|
||||
{
|
||||
name = "entity",
|
||||
description = "The entity of the cheque.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerToreUpCheque",
|
||||
description = "Called when a player tears up a cheque.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who tore up the cheque.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who the cheque was written to.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "amount",
|
||||
description = "The amount of money the cheque has.",
|
||||
type = "number"
|
||||
},
|
||||
{
|
||||
name = "entity",
|
||||
description = "The entity of the cheque.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
12
gamemodes/darkrp/entities/entities/darkrp_cheque/shared.lua
Normal file
12
gamemodes/darkrp/entities/entities/darkrp_cheque/shared.lua
Normal file
@@ -0,0 +1,12 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Cheque"
|
||||
ENT.Author = "Eusion"
|
||||
ENT.Spawnable = false
|
||||
ENT.IsDarkRPCheque = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Entity", 0, "owning_ent")
|
||||
self:NetworkVar("Entity", 1, "recipient")
|
||||
self:NetworkVar("Int", 0, "amount")
|
||||
end
|
||||
72
gamemodes/darkrp/entities/entities/darkrp_laws/cl_init.lua
Normal file
72
gamemodes/darkrp/entities/entities/darkrp_laws/cl_init.lua
Normal file
@@ -0,0 +1,72 @@
|
||||
include("shared.lua")
|
||||
|
||||
local Laws = {}
|
||||
|
||||
ENT.DrawPos = Vector(1, -111, 58)
|
||||
|
||||
local color_navy_200 = Color(0, 0, 70, 200)
|
||||
local color_red = Color(255, 0, 0, 255)
|
||||
local color_white = color_white
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
local DrawPos = self:LocalToWorld(self.DrawPos)
|
||||
|
||||
local DrawAngles = self:GetAngles()
|
||||
DrawAngles:RotateAroundAxis(self:GetAngles():Forward(), 90)
|
||||
DrawAngles:RotateAroundAxis(self:GetAngles():Up(), 90)
|
||||
|
||||
cam.Start3D2D(DrawPos, DrawAngles, 0.4)
|
||||
|
||||
surface.SetDrawColor(0, 0, 0, 255)
|
||||
surface.DrawRect(0, 0, 558, 290)
|
||||
|
||||
draw.RoundedBox(4, 0, 0, 558, 30, color_navy_200)
|
||||
|
||||
draw.DrawNonParsedSimpleText(DarkRP.getPhrase("laws_of_the_land"), "Roboto20", 279, 5, color_red, TEXT_ALIGN_CENTER)
|
||||
|
||||
local lastHeight = 0
|
||||
for k, v in ipairs(Laws) do
|
||||
draw.DrawNonParsedText(string.format("%u. %s", k, v), "Roboto20", 5, 35 + lastHeight, color_white)
|
||||
lastHeight = lastHeight + (fn.ReverseArgs(string.gsub(v, "\n", "")) + 1) * 21
|
||||
end
|
||||
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
local function addLaw(inLaw)
|
||||
local law = DarkRP.textWrap(inLaw, "Roboto20", 522)
|
||||
|
||||
local lawNumber = table.insert(Laws, law)
|
||||
hook.Run("addLaw", lawNumber, inLaw)
|
||||
end
|
||||
|
||||
local function umAddLaw(um)
|
||||
local law = um:ReadString()
|
||||
timer.Simple(0, fn.Curry(addLaw, 2)(law))
|
||||
end
|
||||
usermessage.Hook("DRP_AddLaw", umAddLaw)
|
||||
|
||||
local function umRemoveLaw(um)
|
||||
local i = um:ReadShort()
|
||||
|
||||
local removed = table.remove(Laws, i)
|
||||
hook.Run("removeLaw", i, removed)
|
||||
end
|
||||
usermessage.Hook("DRP_RemoveLaw", umRemoveLaw)
|
||||
|
||||
local function umResetLaws(um)
|
||||
Laws = {}
|
||||
fn.Foldl(function(val,v) addLaw(v) end, nil, GAMEMODE.Config.DefaultLaws)
|
||||
hook.Run("resetLaws")
|
||||
end
|
||||
usermessage.Hook("DRP_ResetLaws", umResetLaws)
|
||||
|
||||
function DarkRP.getLaws()
|
||||
return Laws
|
||||
end
|
||||
|
||||
timer.Simple(0, function()
|
||||
fn.Foldl(function(val,v) addLaw(v) end, nil, GAMEMODE.Config.DefaultLaws)
|
||||
end)
|
||||
193
gamemodes/darkrp/entities/entities/darkrp_laws/init.lua
Normal file
193
gamemodes/darkrp/entities/entities/darkrp_laws/init.lua
Normal file
@@ -0,0 +1,193 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
local Laws = {}
|
||||
local FixedLaws = {}
|
||||
|
||||
timer.Simple(0, function()
|
||||
Laws = table.Copy(GAMEMODE.Config.DefaultLaws)
|
||||
FixedLaws = table.Copy(Laws)
|
||||
end)
|
||||
|
||||
local hookCanEditLaws = {canEditLaws = function(_, ply, action, args)
|
||||
if IsValid(ply) and (not RPExtraTeams[ply:Team()] or not RPExtraTeams[ply:Team()].mayor) then
|
||||
return false, DarkRP.getPhrase("incorrect_job", GAMEMODE.Config.chatCommandPrefix .. action)
|
||||
end
|
||||
return true
|
||||
end}
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props/cs_assault/Billboard.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
end
|
||||
|
||||
local function addLaw(ply, args)
|
||||
local canEdit, message = hook.Call("canEditLaws", hookCanEditLaws, ply, "addLaw", args)
|
||||
|
||||
if not canEdit then
|
||||
DarkRP.notify(ply, 1, 4, message ~= nil and message or DarkRP.getPhrase("unable", GAMEMODE.Config.chatCommandPrefix .. "addLaw", ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
if not args or args == "" then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
if string.len(args) < 3 then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("law_too_short"))
|
||||
return ""
|
||||
end
|
||||
|
||||
if #Laws >= 12 then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("laws_full"))
|
||||
return ""
|
||||
end
|
||||
|
||||
local num = table.insert(Laws, args)
|
||||
|
||||
umsg.Start("DRP_AddLaw")
|
||||
umsg.String(args)
|
||||
umsg.End()
|
||||
|
||||
hook.Run("addLaw", num, args, ply)
|
||||
|
||||
DarkRP.notify(ply, 0, 2, DarkRP.getPhrase("law_added"))
|
||||
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("addLaw", addLaw)
|
||||
|
||||
local function removeLaw(ply, args)
|
||||
local canEdit, message = hook.Call("canEditLaws", hookCanEditLaws, ply, "removeLaw", args)
|
||||
|
||||
if not canEdit then
|
||||
DarkRP.notify(ply, 1, 4, message ~= nil and message or DarkRP.getPhrase("unable", GAMEMODE.Config.chatCommandPrefix .. "removeLaw", ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
local i = DarkRP.toInt(args)
|
||||
|
||||
if not i or not Laws[i] then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
if FixedLaws[i] then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("default_law_change_denied"))
|
||||
return ""
|
||||
end
|
||||
|
||||
local law = Laws[i]
|
||||
|
||||
table.remove(Laws, i)
|
||||
|
||||
umsg.Start("DRP_RemoveLaw")
|
||||
umsg.Short(i)
|
||||
umsg.End()
|
||||
|
||||
hook.Run("removeLaw", i, law, ply)
|
||||
|
||||
DarkRP.notify(ply, 0, 2, DarkRP.getPhrase("law_removed"))
|
||||
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("removeLaw", removeLaw)
|
||||
|
||||
function DarkRP.resetLaws()
|
||||
Laws = table.Copy(FixedLaws)
|
||||
|
||||
umsg.Start("DRP_ResetLaws")
|
||||
umsg.End()
|
||||
end
|
||||
|
||||
local function resetLaws(ply, args)
|
||||
local canEdit, message = hook.Call("canEditLaws", hookCanEditLaws, ply, "resetLaws", args)
|
||||
|
||||
if not canEdit then
|
||||
DarkRP.notify(ply, 1, 4, message ~= nil and message or DarkRP.getPhrase("unable", GAMEMODE.Config.chatCommandPrefix .. "resetLaws", ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
hook.Run("resetLaws", ply)
|
||||
|
||||
DarkRP.resetLaws()
|
||||
|
||||
DarkRP.notify(ply, 0, 2, DarkRP.getPhrase("law_reset"))
|
||||
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("resetLaws", resetLaws)
|
||||
|
||||
local numlaws = 0
|
||||
local function placeLaws(ply, args)
|
||||
local canEdit, message = hook.Call("canEditLaws", hookCanEditLaws, ply, "placeLaws", args)
|
||||
|
||||
if not canEdit then
|
||||
DarkRP.notify(ply, 1, 4, message ~= nil and message or DarkRP.getPhrase("unable", GAMEMODE.Config.chatCommandPrefix .. "placeLaws", ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
if numlaws >= GAMEMODE.Config.maxlawboards then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("limit", GAMEMODE.Config.chatCommandPrefix .. "placeLaws"))
|
||||
return ""
|
||||
end
|
||||
|
||||
local trace = {}
|
||||
trace.start = ply:EyePos()
|
||||
trace.endpos = trace.start + ply:GetAimVector() * 85
|
||||
trace.filter = ply
|
||||
|
||||
local tr = util.TraceLine(trace)
|
||||
|
||||
local ent = ents.Create("darkrp_laws")
|
||||
ent:SetPos(tr.HitPos + Vector(0, 0, 100))
|
||||
|
||||
local ang = ply:GetAngles()
|
||||
ang:RotateAroundAxis(ang:Up(), 180)
|
||||
ent:SetAngles(ang)
|
||||
|
||||
ent:CPPISetOwner(ply)
|
||||
ent.SID = ply.SID
|
||||
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
if IsValid(ent) then
|
||||
numlaws = numlaws + 1
|
||||
end
|
||||
|
||||
ply.lawboards = ply.lawboards or {}
|
||||
table.insert(ply.lawboards, ent)
|
||||
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("placeLaws", placeLaws)
|
||||
|
||||
function ENT:OnRemove()
|
||||
numlaws = numlaws - 1
|
||||
end
|
||||
|
||||
hook.Add("PlayerInitialSpawn", "SendLaws", function(ply)
|
||||
for i, law in ipairs(Laws) do
|
||||
if FixedLaws[i] then continue end
|
||||
|
||||
umsg.Start("DRP_AddLaw", ply)
|
||||
umsg.String(law)
|
||||
umsg.End()
|
||||
end
|
||||
end)
|
||||
|
||||
function DarkRP.getLaws()
|
||||
return Laws
|
||||
end
|
||||
161
gamemodes/darkrp/entities/entities/darkrp_laws/shared.lua
Normal file
161
gamemodes/darkrp/entities/entities/darkrp_laws/shared.lua
Normal file
@@ -0,0 +1,161 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "DarkRP Laws"
|
||||
ENT.Instructions = "Use /addlaws to add a custom law, /removelaw <num> to remove a law."
|
||||
ENT.Author = "Drakehawke"
|
||||
|
||||
ENT.Spawnable = false
|
||||
|
||||
local plyMeta = FindMetaTable("Player")
|
||||
DarkRP.declareChatCommand{
|
||||
command = "addlaw",
|
||||
description = "Add a law to the laws board.",
|
||||
delay = 1.5,
|
||||
condition = plyMeta.isMayor
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "removelaw",
|
||||
description = "Remove a law from the laws board.",
|
||||
delay = 1.5,
|
||||
condition = plyMeta.isMayor
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "placelaws",
|
||||
description = "Place a laws board.",
|
||||
delay = 1.5
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "resetlaws",
|
||||
description = "Reset all laws.",
|
||||
delay = 1.5
|
||||
}
|
||||
|
||||
DarkRP.getLaws = DarkRP.stub{
|
||||
name = "getLaws",
|
||||
description = "Get the table of all current laws.",
|
||||
parameters = {
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "laws",
|
||||
description = "A table of all current laws.",
|
||||
type = "table"
|
||||
}
|
||||
},
|
||||
metatable = DarkRP,
|
||||
realm = "Shared"
|
||||
}
|
||||
|
||||
DarkRP.resetLaws = DarkRP.stub{
|
||||
name = "resetLaws",
|
||||
description = "Reset to default laws.",
|
||||
parameters = {
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
metatable = DarkRP,
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "addLaw",
|
||||
description = "Called when a law is added.",
|
||||
parameters = {
|
||||
{
|
||||
name = "index",
|
||||
description = "Index of the law",
|
||||
type = "number"
|
||||
},
|
||||
{
|
||||
name = "law",
|
||||
description = "Law string",
|
||||
type = "string"
|
||||
},
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who added the law",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Shared"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "removeLaw",
|
||||
description = "Called when a law is removed.",
|
||||
parameters = {
|
||||
{
|
||||
name = "index",
|
||||
description = "Index of law",
|
||||
type = "number"
|
||||
},
|
||||
{
|
||||
name = "law",
|
||||
description = "Law string",
|
||||
type = "string"
|
||||
},
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who removed the law",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Shared"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "resetLaws",
|
||||
description = "Called when laws are reset.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player resetting the laws.",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Shared"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canEditLaws",
|
||||
description = "Whether someone can edit laws.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player trying to edit laws.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "action",
|
||||
description = "How the player is trying to edit laws.",
|
||||
type = "string"
|
||||
},
|
||||
{
|
||||
name = "arguments",
|
||||
description = "Arguments related to editing laws.",
|
||||
type = "table"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "canEdit",
|
||||
description = "A yes or no as to whether the player can edit the law.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "message",
|
||||
description = "The message that is shown when they can't edit the law.",
|
||||
type = "string"
|
||||
}
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
137
gamemodes/darkrp/entities/entities/darkrp_tip_jar/cl_init.lua
Normal file
137
gamemodes/darkrp/entities/entities/darkrp_tip_jar/cl_init.lua
Normal file
@@ -0,0 +1,137 @@
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:initVars()
|
||||
self:initVarsClient()
|
||||
end
|
||||
|
||||
function ENT:initVarsClient()
|
||||
self.colorBackground = Color(140, 0, 0, 100)
|
||||
self.colorText = color_white
|
||||
self.donateAnimColor = Color(20, 100, 20)
|
||||
|
||||
self.rotationSpeed = 130
|
||||
self.rotationOffset = 0
|
||||
self:InitCsModel()
|
||||
|
||||
self.firstDonateAnimation = nil
|
||||
self.lastDonateAnimation = nil
|
||||
self.donateAnimSpeed = 0.3
|
||||
end
|
||||
|
||||
function ENT:InitCsModel()
|
||||
self.csModel = ClientsideModel(self.model)
|
||||
self.csModel:SetPos(self:GetPos())
|
||||
self.csModel:SetParent(self)
|
||||
self.csModel:SetModelScale(1.5, 0)
|
||||
self.csModel:SetNoDraw(true)
|
||||
self:CallOnRemove("csModel", fp{SafeRemoveEntity, self.csModel})
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
local sysTime = SysTime()
|
||||
local eyepos = EyePos()
|
||||
local planeNormal = Ang:Up()
|
||||
|
||||
local rotAng = Angle(Ang)
|
||||
self.rotationOffset = sysTime % 360 * self.rotationSpeed
|
||||
rotAng:RotateAroundAxis(planeNormal, self.rotationOffset)
|
||||
|
||||
-- Something about cs models getting removed on their own...
|
||||
if not IsValid(self.csModel) then
|
||||
self:InitCsModel()
|
||||
end
|
||||
self.csModel:SetPos(Pos)
|
||||
self.csModel:SetAngles(rotAng)
|
||||
if not self:IsDormant() then
|
||||
self.csModel:DrawModel()
|
||||
end
|
||||
|
||||
|
||||
local owner = self:Getowning_ent()
|
||||
owner = (IsValid(owner) and owner:Nick()) or DarkRP.getPhrase("unknown")
|
||||
local title = DarkRP.getPhrase("tip_jar")
|
||||
|
||||
surface.SetFont("HUDNumber5")
|
||||
local titleTextWidth, titleTextHeight = surface.GetTextSize(title)
|
||||
local ownerTextWidth = surface.GetTextSize(owner)
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Forward(), 90)
|
||||
|
||||
-- The text can be considered to be "standing" on a plane with normal =
|
||||
-- Ang:Up(). The vector towards the player's EyePos is projected onto that
|
||||
-- plane, normalised and rotated to have the text face the user.
|
||||
local relativeEye = eyepos - Pos
|
||||
local relativeEyeOnPlane = relativeEye - planeNormal * relativeEye:Dot(planeNormal)
|
||||
local textAng = relativeEyeOnPlane:AngleEx(planeNormal)
|
||||
|
||||
textAng:RotateAroundAxis(textAng:Up(), 90)
|
||||
textAng:RotateAroundAxis(textAng:Forward(), 90)
|
||||
|
||||
|
||||
cam.Start3D2D(Pos - Ang:Right() * 11.5 , textAng, 0.2)
|
||||
draw.WordBox(2, -titleTextWidth * 0.5, -72 , title, "HUDNumber5", self.colorBackground, self.colorText)
|
||||
draw.WordBox(2, -ownerTextWidth * 0.5, -72 + titleTextHeight + 4, owner, "HUDNumber5", self.colorBackground, self.colorText)
|
||||
|
||||
self:DrawAnims(sysTime)
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
function ENT:DrawAnims(sysTime)
|
||||
local anim = self.firstDonateAnimation
|
||||
|
||||
while anim do
|
||||
if anim.progress > 1 then
|
||||
anim = anim.nextDonateAnimation
|
||||
self.firstDonateAnimation = anim
|
||||
|
||||
continue
|
||||
end
|
||||
|
||||
draw.SimpleText(
|
||||
anim.amount,
|
||||
"DarkRP_tipjar",
|
||||
-anim.textWidth / 2,
|
||||
-100 - anim.progress * 200,
|
||||
ColorAlpha(self.donateAnimColor, Lerp(anim.progress, 1024, 0)),
|
||||
0
|
||||
)
|
||||
|
||||
anim.progress = (sysTime - anim.start) * self.donateAnimSpeed
|
||||
|
||||
anim = anim.nextDonateAnimation
|
||||
end
|
||||
|
||||
if not self.firstDonateAnimation then
|
||||
self.lastDonateAnimation = nil
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Donated(ply, amount)
|
||||
local txtAmount = DarkRP.formatMoney(amount)
|
||||
|
||||
surface.SetFont("DarkRP_tipjar")
|
||||
|
||||
local anim = {
|
||||
amount = txtAmount,
|
||||
start = SysTime(),
|
||||
textWidth = surface.GetTextSize(txtAmount),
|
||||
progress = 0,
|
||||
nextDonateAnimation = nil,
|
||||
}
|
||||
|
||||
if self.lastDonateAnimation then
|
||||
self.lastDonateAnimation.nextDonateAnimation = anim
|
||||
else
|
||||
self.firstDonateAnimation = anim
|
||||
end
|
||||
|
||||
self.lastDonateAnimation = anim
|
||||
|
||||
self:AddDonation(ply:Nick(), amount)
|
||||
end
|
||||
|
||||
-- Disable halos
|
||||
function ENT:Think() end
|
||||
46
gamemodes/darkrp/entities/entities/darkrp_tip_jar/init.lua
Normal file
46
gamemodes/darkrp/entities/entities/darkrp_tip_jar/init.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:initVars()
|
||||
|
||||
self:SetModel(self.model)
|
||||
|
||||
self:SetModelScale(1.5, 0)
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
self:Activate()
|
||||
|
||||
self.nodupe = true
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
self.damage = (self.damage or 100) - dmg:GetDamage()
|
||||
if self.damage <= 0 then
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
net.Start("DarkRP_TipJarUI")
|
||||
net.WriteEntity(self)
|
||||
net.Send(activator)
|
||||
end
|
||||
80
gamemodes/darkrp/entities/entities/darkrp_tip_jar/shared.lua
Normal file
80
gamemodes/darkrp/entities/entities/darkrp_tip_jar/shared.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Tip Jar"
|
||||
ENT.Author = "FPtje"
|
||||
ENT.Spawnable = false
|
||||
ENT.IsTipjar = true
|
||||
|
||||
function ENT:initVars()
|
||||
self.model = "models/props_lab/jar01a.mdl"
|
||||
self.damage = 100
|
||||
self.callOnRemoveId = "tipjar_activedonation_" .. self:EntIndex() .. "_"
|
||||
|
||||
self.activeDonations = {}
|
||||
self.madeDonations = {}
|
||||
|
||||
self.PlayerUse = true
|
||||
end
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Entity", 0, "owning_ent")
|
||||
end
|
||||
|
||||
function ENT:UpdateActiveDonation(ply, amount)
|
||||
local old = self.activeDonations[ply]
|
||||
self.activeDonations[ply] = amount
|
||||
|
||||
self:PruneActiveDonations()
|
||||
|
||||
ply:CallOnRemove(self.callOnRemoveId .. ply:UserID(), function()
|
||||
if not IsValid(self) then return end
|
||||
|
||||
self:ExitActiveDonation(ply)
|
||||
end)
|
||||
|
||||
hook.Call("tipjarUpdateActiveDonation", DarkRP.hooks, self, ply, amount, old)
|
||||
end
|
||||
|
||||
function ENT:ExitActiveDonation(ply)
|
||||
local old = self.activeDonations[ply]
|
||||
|
||||
self.activeDonations[ply] = nil
|
||||
|
||||
self:PruneActiveDonations()
|
||||
hook.Call("tipjarExitActiveDonation", DarkRP.hooks, self, ply, old)
|
||||
|
||||
self:RemoveCallOnRemove(self.callOnRemoveId .. ply:UserID())
|
||||
end
|
||||
|
||||
function ENT:ClearActiveDonations()
|
||||
table.Empty(self.activeDonations)
|
||||
hook.Call("tipjarClearActiveDonation", DarkRP.hooks, self)
|
||||
end
|
||||
|
||||
function ENT:PruneActiveDonations()
|
||||
for ply, _ in pairs(self.activeDonations) do
|
||||
if not IsValid(ply) then self.activeDonations[ply] = nil end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:AddDonation(name, amount)
|
||||
local lastDonation = self.madeDonations[#self.madeDonations]
|
||||
|
||||
if lastDonation and lastDonation.name == name then
|
||||
lastDonation.amount = lastDonation.amount + amount
|
||||
else
|
||||
table.insert(self.madeDonations, {
|
||||
name = name,
|
||||
amount = amount,
|
||||
})
|
||||
end
|
||||
|
||||
-- Enforce maximum of 100 donations
|
||||
while #self.madeDonations > 100 do
|
||||
table.remove(self.madeDonations, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:ClearDonations()
|
||||
table.Empty(self.madeDonations)
|
||||
end
|
||||
53
gamemodes/darkrp/entities/entities/drug/cl_init.lua
Normal file
53
gamemodes/darkrp/entities/entities/drug/cl_init.lua
Normal file
@@ -0,0 +1,53 @@
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
local color_red = Color(140, 0, 0, 100)
|
||||
local color_white = color_white
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
|
||||
local owner = self:Getowning_ent()
|
||||
owner = (IsValid(owner) and owner:Nick()) or DarkRP.getPhrase("unknown")
|
||||
|
||||
surface.SetFont("HUDNumber5")
|
||||
local text = DarkRP.getPhrase("drugs")
|
||||
local text2 = DarkRP.getPhrase("priceTag", DarkRP.formatMoney(self:Getprice()), "")
|
||||
local TextWidth = surface.GetTextSize(text)
|
||||
local TextWidth2 = surface.GetTextSize(text2)
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Forward(), 90)
|
||||
local TextAng = Ang
|
||||
|
||||
TextAng:RotateAroundAxis(TextAng:Right(), CurTime() * -180)
|
||||
|
||||
cam.Start3D2D(Pos + Ang:Right() * -15, TextAng, 0.1)
|
||||
draw.WordBox(2, -TextWidth * 0.5 + 5, -30, text, "HUDNumber5", color_red, color_white)
|
||||
draw.WordBox(2, -TextWidth2 * 0.5 + 5, 18, text2, "HUDNumber5", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
local function drugEffects(um)
|
||||
local toggle = um:ReadBool()
|
||||
|
||||
LocalPlayer().isDrugged = toggle
|
||||
|
||||
if toggle then
|
||||
hook.Add("RenderScreenspaceEffects", "drugged", function()
|
||||
DrawSharpen(-1, 2)
|
||||
DrawMaterialOverlay("models/props_lab/Tank_Glass001", 0)
|
||||
DrawMotionBlur(0.13, 1, 0.00)
|
||||
end)
|
||||
else
|
||||
hook.Remove("RenderScreenspaceEffects", "drugged")
|
||||
end
|
||||
end
|
||||
usermessage.Hook("DrugEffects", drugEffects)
|
||||
105
gamemodes/darkrp/entities/entities/drug/init.lua
Normal file
105
gamemodes/darkrp/entities/entities/drug/init.lua
Normal file
@@ -0,0 +1,105 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
local function UnDrugPlayer(ply)
|
||||
if not IsValid(ply) then return end
|
||||
ply.isDrugged = false
|
||||
local IDSteam = ply:SteamID64()
|
||||
|
||||
timer.Remove(IDSteam .. "DruggedHealth")
|
||||
|
||||
SendUserMessage("DrugEffects", ply, false)
|
||||
end
|
||||
|
||||
hook.Add("PlayerDeath", "UndrugPlayers", function(ply) if ply.isDrugged then UnDrugPlayer(ply) end end)
|
||||
|
||||
local function DrugPlayer(ply)
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
SendUserMessage("DrugEffects", ply, true)
|
||||
|
||||
ply.isDrugged = true
|
||||
|
||||
local IDSteam = ply:SteamID64()
|
||||
|
||||
if not timer.Exists(IDSteam .. "DruggedHealth") then
|
||||
ply:SetHealth(ply:Health() + 100)
|
||||
|
||||
timer.Create(IDSteam .. "DruggedHealth", 60 / (100 + 5), 100 + 5, function()
|
||||
if not IsValid(ply) then return end
|
||||
ply:SetHealth(ply:Health() - 1)
|
||||
|
||||
if ply:Health() <= 0 then
|
||||
ply:Kill()
|
||||
end
|
||||
|
||||
if timer.RepsLeft(IDSteam .. "DruggedHealth") == 0 then
|
||||
UnDrugPlayer(ply)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_lab/jar01a.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
self.CanUse = true
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
self.damage = 10
|
||||
self:Setprice(self:Getprice() or 100)
|
||||
self.SeizeReward = GAMEMODE.Config.pricemin or 35
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
self.damage = self.damage - dmg:GetDamage()
|
||||
|
||||
if self.damage <= 0 then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin(self:GetPos())
|
||||
effectdata:SetMagnitude(2)
|
||||
effectdata:SetScale(2)
|
||||
effectdata:SetRadius(3)
|
||||
util.Effect("Sparks", effectdata)
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
if not self.CanUse then return end
|
||||
local Owner = self:Getowning_ent()
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
if activator ~= Owner then
|
||||
if not activator:canAfford(self:Getprice()) then return end
|
||||
DarkRP.payPlayer(activator, Owner, self:Getprice())
|
||||
DarkRP.notify(activator, 0, 4, DarkRP.getPhrase("you_bought", DarkRP.getPhrase("drugs"), DarkRP.formatMoney(self:Getprice()), ""))
|
||||
DarkRP.notify(Owner, 0, 4, DarkRP.getPhrase("you_received_x", DarkRP.formatMoney(self:Getprice()), DarkRP.getPhrase("drugs")))
|
||||
end
|
||||
DrugPlayer(caller)
|
||||
self.CanUse = false
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
local ply = self:Getowning_ent()
|
||||
if not IsValid(ply) then return end
|
||||
ply.maxDrugs = ply.maxDrugs - 1
|
||||
end
|
||||
23
gamemodes/darkrp/entities/entities/drug/shared.lua
Normal file
23
gamemodes/darkrp/entities/entities/drug/shared.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Drugs"
|
||||
ENT.Author = "Rickster"
|
||||
ENT.Spawnable = false
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Int", 0, "price")
|
||||
self:NetworkVar("Entity", 1, "owning_ent")
|
||||
end
|
||||
|
||||
hook.Add("Move", "DruggedPlayer", function(ply, mv)
|
||||
if not ply.isDrugged then return end
|
||||
|
||||
mv:SetMaxSpeed(mv:GetMaxSpeed() * 2)
|
||||
mv:SetMaxClientSpeed(mv:GetMaxClientSpeed() * 2)
|
||||
|
||||
if ply:IsOnGround() and mv:KeyPressed(IN_JUMP) then
|
||||
local vec = mv:GetVelocity()
|
||||
vec.z = 100 -- Adds on to the jump power
|
||||
mv:SetVelocity(vec)
|
||||
end
|
||||
end)
|
||||
40
gamemodes/darkrp/entities/entities/drug_lab/init.lua
Normal file
40
gamemodes/darkrp/entities/entities/drug_lab/init.lua
Normal file
@@ -0,0 +1,40 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
DEFINE_BASECLASS("lab_base")
|
||||
|
||||
ENT.SeizeReward = 350
|
||||
ENT.SpawnOffset = Vector(0, 0, 35)
|
||||
|
||||
function ENT:Initialize()
|
||||
BaseClass.Initialize(self)
|
||||
self.SID = self:Getowning_ent().SID
|
||||
end
|
||||
|
||||
function ENT:SalePrice(activator)
|
||||
return math.random(math.Round(self:Getprice() / 8), math.Round(self:Getprice() / 4))
|
||||
end
|
||||
|
||||
function ENT:canUse(activator)
|
||||
if activator.maxDrugs and activator.maxDrugs >= GAMEMODE.Config.maxdrugs then
|
||||
DarkRP.notify(activator, 1, 3, DarkRP.getPhrase("limit", self.itemPhrase))
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:createItem(activator)
|
||||
local drugPos = self:GetPos() + self.SpawnOffset
|
||||
local drug = ents.Create("drug")
|
||||
drug:SetPos(drugPos)
|
||||
drug:Setowning_ent(activator)
|
||||
drug.SID = activator.SID
|
||||
drug.nodupe = true
|
||||
drug:Setprice(self:Getprice() or self.initialPrice)
|
||||
drug:Spawn()
|
||||
if not activator.maxDrugs then
|
||||
activator.maxDrugs = 0
|
||||
end
|
||||
activator.maxDrugs = activator.maxDrugs + 1
|
||||
end
|
||||
11
gamemodes/darkrp/entities/entities/drug_lab/shared.lua
Normal file
11
gamemodes/darkrp/entities/entities/drug_lab/shared.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
ENT.Base = "lab_base"
|
||||
ENT.PrintName = "Drug Lab"
|
||||
|
||||
function ENT:initVars()
|
||||
self.model = "models/props_lab/crematorcase.mdl"
|
||||
self.initialPrice = GAMEMODE.Config.druglabdrugcost
|
||||
self.labPhrase = DarkRP.getPhrase("drug_lab")
|
||||
self.itemPhrase = DarkRP.getPhrase("drugs")
|
||||
self.noIncome = true
|
||||
self.camMul = -39
|
||||
end
|
||||
52
gamemodes/darkrp/entities/entities/fadmin_jail/init.lua
Normal file
52
gamemodes/darkrp/entities/entities/fadmin_jail/init.lua
Normal file
@@ -0,0 +1,52 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
|
||||
self.SolidPos = self:GetPos()
|
||||
self.SolidAng = self:GetAngles()
|
||||
end
|
||||
|
||||
function ENT:SetCanRemove(bool)
|
||||
self.CanRemove = bool
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if FAdmin.shuttingDown or self.CanRemove or not IsValid(self.target) then return end
|
||||
|
||||
local Replace = ents.Create("fadmin_jail")
|
||||
if (not Replace:IsValid()) then return end
|
||||
|
||||
Replace:SetPos(self.SolidPos)
|
||||
Replace:SetAngles(self.SolidAng)
|
||||
Replace:SetModel(self:GetModel())
|
||||
Replace:Spawn()
|
||||
Replace:Activate()
|
||||
|
||||
Replace.target = self.target
|
||||
Replace.targetPos = self.targetPos
|
||||
|
||||
self.target.FAdminJailProps = self.target.FAdminJailProps or {}
|
||||
self.target.FAdminJailProps[self] = nil
|
||||
self.target.FAdminJailProps[Replace] = true
|
||||
|
||||
if self.targetPos then self.target:SetPos(self.targetPos) end -- Back in jail you! :V
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if not IsValid(self.target) then
|
||||
self:SetCanRemove(true)
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
end
|
||||
13
gamemodes/darkrp/entities/entities/fadmin_jail/shared.lua
Normal file
13
gamemodes/darkrp/entities/entities/fadmin_jail/shared.lua
Normal file
@@ -0,0 +1,13 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "fadmin_jail"
|
||||
ENT.Author = "FPtje"
|
||||
ENT.Spawnable = false
|
||||
|
||||
function ENT:CanTool()
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:PhysgunPickup(ply)
|
||||
return false
|
||||
end
|
||||
182
gamemodes/darkrp/entities/entities/fadmin_motd/cl_init.lua
Normal file
182
gamemodes/darkrp/entities/entities/fadmin_motd/cl_init.lua
Normal file
@@ -0,0 +1,182 @@
|
||||
include("shared.lua")
|
||||
local defaultHTML
|
||||
|
||||
-- I love the garry's mod wiki!
|
||||
-- Credits to whoever made this function!
|
||||
local function WorldToScreen(vWorldPos, vPos, vScale, aRot)
|
||||
vWorldPos = vWorldPos - vPos
|
||||
vWorldPos:Rotate(Angle(0, -aRot.y, 0))
|
||||
vWorldPos:Rotate(Angle(-aRot.p, 0, 0))
|
||||
vWorldPos:Rotate(Angle(0, 0, -aRot.r))
|
||||
|
||||
return vWorldPos.x / vScale, (-vWorldPos.y) / vScale
|
||||
end
|
||||
|
||||
function ENT:LoadPage()
|
||||
local Page = self.MOTDPage:GetString()
|
||||
if string.lower(Page) == "data/fadmin/motd.txt" or string.lower(Page) == "default" then
|
||||
self.HTML:SetHTML(defaultHTML)
|
||||
elseif string.lower(string.sub(Page, -4)) == ".txt" and string.lower(string.sub(Page, 1, 5)) == "data/" then -- If it's a text file somewhere in data...
|
||||
Page = string.sub(Page, 6)
|
||||
self.HTML:SetHTML(file.Read(Page, "DATA") or "")
|
||||
else
|
||||
self.HTML:OpenURL(Page)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self.MOTDPage = GetConVar("_FAdmin_MOTDPage")
|
||||
self.Disabled = true
|
||||
self.LastDrawn = CurTime()
|
||||
self.HTML = self.HTMLControl or vgui.Create("HTML")
|
||||
self.HTML:SetPaintedManually(false)
|
||||
self.HTML:SetPos(-512, -256)
|
||||
self.HTMLWidth = 1448
|
||||
self.HTMLHeight = 724
|
||||
self.HTML:SetSize(self.HTMLWidth, self.HTMLHeight)
|
||||
self:LoadPage()
|
||||
|
||||
self.HTML:SetVisible(false)
|
||||
self.HTML:SetKeyboardInputEnabled(false)
|
||||
timer.Simple(0, function() -- Fix areas of the FAdmin scoreboard coming unclickable
|
||||
self.HTML:SetPaintedManually(true)
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if not self.HTML or self.Disabled or self.HTMLCloseButton then
|
||||
self.HTMLMat = nil
|
||||
else
|
||||
self.HTML:UpdateHTMLTexture()
|
||||
self.HTMLMat = self.HTML:GetHTMLMaterial()
|
||||
end
|
||||
self:NextThink(CurTime() + 0.1)
|
||||
end
|
||||
|
||||
local gripTexture = surface.GetTextureID("sprites/grip")
|
||||
local ArrowTexture = surface.GetTextureID("gui/arrow")
|
||||
local color_white = color_white
|
||||
local color_darkgrey = Color(100, 100, 100, 255)
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
local pos = self:GetPos()
|
||||
local ply = LocalPlayer()
|
||||
if pos:DistToSqr(ply:GetShootPos()) > 90000 then return end
|
||||
|
||||
if CurTime() - self.LastDrawn > 0.5 then
|
||||
self.Disabled = true --Disable it again when you stop looking at it
|
||||
end
|
||||
|
||||
self.LastDrawn = CurTime()
|
||||
local IsAdmin = ply:IsAdmin()
|
||||
local HasPhysgun = ply:GetActiveWeapon():IsValid() and ply:GetActiveWeapon():GetClass() == "weapon_physgun"
|
||||
local isUsing = (HasPhysgun and ply:KeyDown(IN_ATTACK)) or ply:KeyDown(IN_USE)
|
||||
|
||||
surface.SetFont("Roboto20")
|
||||
local TextPosX = surface.GetTextSize("Physgun/use the button to see the MOTD!") * (-0.5)
|
||||
|
||||
local ang = self:GetAngles()
|
||||
ang:RotateAroundAxis(ang:Right(), -90)
|
||||
ang:RotateAroundAxis(ang:Up(), 90)
|
||||
|
||||
local posX, posY = WorldToScreen(ply:GetEyeTrace().HitPos, self:GetPos() + ang:Up() * 3, 0.25, ang)
|
||||
render.SuppressEngineLighting(true)
|
||||
cam.Start3D2D(self:GetPos() + ang:Up() * 3, ang, 0.25)
|
||||
|
||||
if self.Disabled then
|
||||
surface.SetDrawColor(0, 0, 0, 255)
|
||||
surface.DrawRect(-512, 256, 1024, -512)
|
||||
surface.SetTextColor(255, 255, 255, 255)
|
||||
surface.SetTextPos(TextPosX, 0)
|
||||
surface.DrawNonParsedText("Physgun/use the button to see the MOTD!")
|
||||
|
||||
draw.WordBox(4, -16, 24, "Click!", "default", color_darkgrey, color_white)
|
||||
|
||||
surface.SetDrawColor(255, 255, 255, 255)
|
||||
if IsAdmin and HasPhysgun then
|
||||
surface.SetTexture(gripTexture)
|
||||
surface.DrawTexturedRect(-10, 240, 16, 16)
|
||||
end
|
||||
if isUsing then
|
||||
|
||||
posX, posY = math.Clamp(posX, -506, 506), math.Clamp(posY, -250, 250)
|
||||
surface.SetTexture(ArrowTexture)
|
||||
surface.DrawTexturedRectRotated(posX + 5, posY + 5, 16, 16, 45)
|
||||
|
||||
-- Clicking button
|
||||
if posX > -16 and posX < 16 and posY > 24 and posY < 48 then
|
||||
self:LoadPage()
|
||||
self.Disabled = false
|
||||
self.CanClickAgain = CurTime() + 1
|
||||
end
|
||||
end
|
||||
elseif not self.HTMLMat then
|
||||
self.HTML:SetVisible(true)
|
||||
self.HTML:SetKeyboardInputEnabled(true)
|
||||
self.HTML:SetPaintedManually(false)
|
||||
self.HTML:UpdateHTMLTexture()
|
||||
|
||||
timer.Simple(0, function() -- Fix HTML material
|
||||
self.HTML:SetPaintedManually(true)
|
||||
self.HTML:SetVisible(false)
|
||||
self.HTML:SetKeyboardInputEnabled(false)
|
||||
end)
|
||||
|
||||
else
|
||||
surface.SetMaterial(self.HTMLMat)
|
||||
surface.SetDrawColor(255, 255, 255, 255)
|
||||
surface.DrawTexturedRect(-512, -256, self.HTMLWidth, self.HTMLHeight)
|
||||
end
|
||||
|
||||
cam.End3D2D()
|
||||
render.SuppressEngineLighting(false)
|
||||
if self.HTMLCloseButton then return end
|
||||
|
||||
--Drawing the actual HTML panel:
|
||||
|
||||
if isUsing and posX > -500 and posX < 500 and posY < 250 and posY > -250 and
|
||||
not self.Disabled and self.HTML and self.HTML:IsValid() and self.CanClickAgain and CurTime() > self.CanClickAgain then
|
||||
self.CanClickAgain = CurTime() + 1
|
||||
self.HTML:SetPaintedManually(false)
|
||||
self.HTML:SetPos(0, 100)
|
||||
self.HTML:SetSize(ScrW(), ScrH() - 100)
|
||||
gui.EnableScreenClicker(true)
|
||||
-- gui.SetMousePos(posX/1024*ScrW(), posY/512*(ScrH() - 100) + 100)
|
||||
self.HTMLCloseButton = self.HTMLCloseButton or vgui.Create("DButton")
|
||||
self.HTMLCloseButton:SetPos(ScrW() - 100, 0)
|
||||
self.HTMLCloseButton:SetSize(100, 100)
|
||||
self.HTMLCloseButton:SetText("X")
|
||||
self.HTMLCloseButton:SetVisible(true)
|
||||
self.HTML:SetVisible(true)
|
||||
self.HTML:RequestFocus()
|
||||
self.HTML:SetKeyboardInputEnabled(true)
|
||||
self.HTML:MakePopup()
|
||||
|
||||
function self.HTMLCloseButton.DoClick() -- Revert to drawing on the prop
|
||||
self.HTML:SetPos(-512, -256)
|
||||
self.HTML:SetSize(self.HTMLWidth, self.HTMLHeight)
|
||||
self.HTML:SetPaintedManually(true)
|
||||
self.HTML:SetKeyboardInputEnabled(false)
|
||||
self.HTML:SetVisible(false)
|
||||
gui.EnableScreenClicker(false)
|
||||
self.HTMLCloseButton:Remove()
|
||||
self.HTMLCloseButton = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defaultHTML = [[
|
||||
<html>
|
||||
<title>MOTD!</title>
|
||||
<body bgcolor="888888">
|
||||
<center><h1>Example MOTD/Instructions on how to set a proper MOTD</h1></center>
|
||||
<h2>Of course you have to be superadmin or owner.</h2>
|
||||
<ol>
|
||||
<li>Copy the website URL to the clipboard<br></li>
|
||||
<li>Enter the command: FAdmin MOTDPage "your website here"<br><br></li>
|
||||
<i>Example:</i><br>
|
||||
FAdmin MOTDPage "www.facepunch.com"
|
||||
</body>
|
||||
</html>]]
|
||||
54
gamemodes/darkrp/entities/entities/fadmin_motd/init.lua
Normal file
54
gamemodes/darkrp/entities/entities/fadmin_motd/init.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_wasteland/interior_fence002d.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
|
||||
self.SolidPos = self:GetPos()
|
||||
self.SolidAng = self:GetAngles()
|
||||
self:SetMaterial("models/props_lab/warp_sheet")
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if not self.CanRemove and IsValid(self.target) then
|
||||
local Replace = ents.Create("fadmin_motd")
|
||||
|
||||
Replace:SetPos(self.SolidPos)
|
||||
Replace:SetAngles(self.SolidAng)
|
||||
Replace:Spawn()
|
||||
Replace:SetModel(self:GetModel())
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnPhysgunFreeze(Weapon, PhysObj, ent, ply)
|
||||
FAdmin.MOTD.SaveMOTD(ent, ply)
|
||||
end
|
||||
|
||||
function ENT:SpawnFunction(ply, tr)
|
||||
if not tr.Hit then return end
|
||||
for _, v in ipairs(ents.FindByClass("fadmin_motd")) do
|
||||
v.CanRemove = true
|
||||
v:Remove() --There can only be one motd per level
|
||||
end
|
||||
|
||||
local SpawnPos = tr.HitPos + tr.HitNormal * 16 + Vector(0,0,50)
|
||||
|
||||
local ent = ents.Create("fadmin_motd")
|
||||
ent:SetPos(SpawnPos)
|
||||
local Ang = ply:EyeAngles()
|
||||
ent:SetAngles(Angle(0, Ang.y-180, Ang.r))
|
||||
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
end
|
||||
21
gamemodes/darkrp/entities/entities/fadmin_motd/shared.lua
Normal file
21
gamemodes/darkrp/entities/entities/fadmin_motd/shared.lua
Normal file
@@ -0,0 +1,21 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "fadmin MOTD"
|
||||
ENT.Information = "Place this MOTD somewhere, freeze it and it will be saved automatically"
|
||||
ENT.Author = "FPtje"
|
||||
ENT.Spawnable = false
|
||||
|
||||
function ENT:CanTool(ply, trace, tool)
|
||||
if ply:IsAdmin() and tool == "remover" then
|
||||
self.CanRemove = true
|
||||
if SERVER then FAdmin.MOTD.RemoveMOTD(self, ply) end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local PickupPos = Vector(1.8079, -0.6743, -62.3193)
|
||||
function ENT:PhysgunPickup(ply)
|
||||
if ply:IsAdmin() and PickupPos:DistToSqr(self:WorldToLocal(ply:GetEyeTrace().HitPos)) < 49 then return true end
|
||||
return false
|
||||
end
|
||||
54
gamemodes/darkrp/entities/entities/food/init.lua
Normal file
54
gamemodes/darkrp/entities/entities/food/init.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_junk/garbage_takeoutcarton001a.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
self.damage = 10
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
self.damage = self.damage - dmg:GetDamage()
|
||||
|
||||
if (self.damage <= 0) then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin(self:GetPos())
|
||||
effectdata:SetMagnitude(2)
|
||||
effectdata:SetScale(2)
|
||||
effectdata:SetRadius(3)
|
||||
util.Effect("Sparks", effectdata)
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
caller:setSelfDarkRPVar("Energy", 100)
|
||||
umsg.Start("AteFoodIcon", caller)
|
||||
umsg.End()
|
||||
|
||||
self:Remove()
|
||||
activator:EmitSound(self.EatSound, 100, 100)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
local ply = self:Getowning_ent()
|
||||
ply.maxFoods = ply.maxFoods and ply.maxFoods - 1 or 0
|
||||
end
|
||||
10
gamemodes/darkrp/entities/entities/food/shared.lua
Normal file
10
gamemodes/darkrp/entities/entities/food/shared.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Food"
|
||||
ENT.Author = "Pcwizdan"
|
||||
ENT.Spawnable = false
|
||||
ENT.EatSound = "vo/sandwicheat09.mp3" -- Requires Team Fortress 2
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Entity", 1, "owning_ent")
|
||||
end
|
||||
17
gamemodes/darkrp/entities/entities/gunlab/init.lua
Normal file
17
gamemodes/darkrp/entities/entities/gunlab/init.lua
Normal file
@@ -0,0 +1,17 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
ENT.SpawnOffset = Vector(0, 0, 27)
|
||||
|
||||
function ENT:createItem()
|
||||
local gun = ents.Create("spawned_weapon")
|
||||
|
||||
local wep = weapons.Get(GAMEMODE.Config.gunlabweapon)
|
||||
gun:SetModel(wep and wep.WorldModel or "models/weapons/w_pist_p228.mdl")
|
||||
gun:SetWeaponClass(GAMEMODE.Config.gunlabweapon)
|
||||
local gunPos = self:GetPos() + self.SpawnOffset
|
||||
gun:SetPos(gunPos)
|
||||
gun.nodupe = true
|
||||
gun:Spawn()
|
||||
end
|
||||
9
gamemodes/darkrp/entities/entities/gunlab/shared.lua
Normal file
9
gamemodes/darkrp/entities/entities/gunlab/shared.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
ENT.Base = "lab_base"
|
||||
ENT.PrintName = "Gun Lab"
|
||||
|
||||
function ENT:initVars()
|
||||
self.model = "models/props_c17/TrapPropeller_Engine.mdl"
|
||||
self.initialPrice = GAMEMODE.Config.gunlabguncost
|
||||
self.labPhrase = DarkRP.getPhrase("gun_lab")
|
||||
self.itemPhrase = DarkRP.getPhrase("gun")
|
||||
end
|
||||
34
gamemodes/darkrp/entities/entities/lab_base/cl_init.lua
Normal file
34
gamemodes/darkrp/entities/entities/lab_base/cl_init.lua
Normal file
@@ -0,0 +1,34 @@
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:initVars()
|
||||
end
|
||||
|
||||
local color_red = Color(140, 0, 0, 100)
|
||||
local color_white = color_white
|
||||
|
||||
function ENT:DrawTranslucent()
|
||||
self:DrawModel()
|
||||
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
|
||||
local owner = self:Getowning_ent()
|
||||
owner = (IsValid(owner) and owner:Nick()) or DarkRP.getPhrase("unknown")
|
||||
|
||||
surface.SetFont("HUDNumber5")
|
||||
local text = self.labPhrase
|
||||
local text2 = DarkRP.getPhrase("priceTag", DarkRP.formatMoney(self:Getprice()), "")
|
||||
local TextWidth = surface.GetTextSize(text)
|
||||
local TextWidth2 = surface.GetTextSize(text2)
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Forward(), 90)
|
||||
local TextAng = Ang
|
||||
|
||||
TextAng:RotateAroundAxis(TextAng:Right(), CurTime() * -180)
|
||||
|
||||
cam.Start3D2D(Pos + Ang:Right() * self.camMul, TextAng, 0.2)
|
||||
draw.WordBox(2, -TextWidth * 0.5 + 5, -30, text, "HUDNumber5", color_red, color_white)
|
||||
draw.WordBox(2, -TextWidth2 * 0.5 + 5, 18, text2, "HUDNumber5", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
end
|
||||
149
gamemodes/darkrp/entities/entities/lab_base/init.lua
Normal file
149
gamemodes/darkrp/entities/entities/lab_base/init.lua
Normal file
@@ -0,0 +1,149 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:initVars()
|
||||
|
||||
self:SetModel(self.model)
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
self.sparking = false
|
||||
self.damage = 100
|
||||
self:Setprice(math.Clamp(self.initialPrice, (GAMEMODE.Config.pricemin ~= 0 and GAMEMODE.Config.pricemin) or self.initialPrice, (GAMEMODE.Config.pricecap ~= 0 and GAMEMODE.Config.pricecap) or self.initialPrice))
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
self.damage = self.damage - dmg:GetDamage()
|
||||
if self.damage <= 0 and not self.Destructed then
|
||||
self.Destructed = true
|
||||
self:Destruct()
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Destruct()
|
||||
local vPoint = self:GetPos()
|
||||
|
||||
util.BlastDamage(self, self, vPoint, self.blastRadius, self.blastDamage)
|
||||
util.ScreenShake(vPoint, 512, 255, 1.5, 200)
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetStart(vPoint)
|
||||
effectdata:SetOrigin(vPoint)
|
||||
effectdata:SetScale(1)
|
||||
util.Effect(self:WaterLevel() > 1 and "WaterSurfaceExplosion" or "Explosion", effectdata)
|
||||
util.Decal("Scorch", vPoint, vPoint - Vector(0, 0, 25), self)
|
||||
end
|
||||
|
||||
function ENT:SalePrice(activator)
|
||||
local owner = self:Getowning_ent()
|
||||
|
||||
if activator == owner then
|
||||
if self.allowed and istable(self.allowed) and table.HasValue(self.allowed, activator:Team()) then
|
||||
return math.ceil(self:Getprice() * 0.8)
|
||||
else
|
||||
return math.ceil(self:Getprice() * 0.9)
|
||||
end
|
||||
else
|
||||
return self:Getprice()
|
||||
end
|
||||
end
|
||||
|
||||
ENT.Once = false
|
||||
function ENT:Use(activator, caller)
|
||||
-- The lab cannot be used by non-players (e.g. wire user)
|
||||
-- The player must be known for the lab to work.
|
||||
if not activator:IsPlayer() then return end
|
||||
|
||||
if self.Once then return end
|
||||
|
||||
local owner = self:Getowning_ent()
|
||||
|
||||
if not IsValid(owner) then
|
||||
DarkRP.notify(activator, 1, 3, DarkRP.getPhrase("disabled", self.labPhrase, DarkRP.getPhrase("disconnected_player")))
|
||||
return
|
||||
end
|
||||
|
||||
local cost = self:SalePrice(activator)
|
||||
|
||||
if not activator:canAfford(cost) then
|
||||
DarkRP.notify(activator, 1, 3, DarkRP.getPhrase("cant_afford", self.itemPhrase))
|
||||
return
|
||||
end
|
||||
|
||||
local diff = cost - self:SalePrice(owner)
|
||||
if not self.noIncome and diff < 0 and not owner:canAfford(math.abs(diff)) then
|
||||
DarkRP.notify(activator, 1, 3, DarkRP.getPhrase("owner_poor", self.labPhrase))
|
||||
return
|
||||
end
|
||||
|
||||
if not self:canUse(activator) then return end
|
||||
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
self.Once = true
|
||||
self.sparking = true
|
||||
|
||||
activator:addMoney(-cost)
|
||||
DarkRP.notify(activator, 0, 3, DarkRP.getPhrase("you_bought", self.itemPhrase, DarkRP.formatMoney(cost)))
|
||||
|
||||
if activator ~= owner and not self.noIncome then
|
||||
if diff == 0 then
|
||||
DarkRP.notify(owner, 0, 3, DarkRP.getPhrase("you_received_x", DarkRP.formatMoney(0) .. " " .. DarkRP.getPhrase("profit"), self.itemPhrase))
|
||||
else
|
||||
owner:addMoney(diff)
|
||||
local word = DarkRP.getPhrase("profit")
|
||||
if diff < 0 then word = DarkRP.getPhrase("loss") end
|
||||
DarkRP.notify(owner, 0, 3, DarkRP.getPhrase("you_received_x", DarkRP.formatMoney(math.abs(diff)) .. " " .. word, self.itemPhrase))
|
||||
end
|
||||
end
|
||||
|
||||
timer.Create(self:EntIndex() .. self.itemPhrase, 1, 1, function()
|
||||
if not IsValid(self) then return end
|
||||
if IsValid(activator) then
|
||||
self:createItem(activator)
|
||||
end
|
||||
self.Once = false
|
||||
self.sparking = false
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:canUse(owner, activator)
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:createItem(activator)
|
||||
-- Implement this function
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self.sparking then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin(self:GetPos())
|
||||
effectdata:SetMagnitude(1)
|
||||
effectdata:SetScale(1)
|
||||
effectdata:SetRadius(2)
|
||||
util.Effect("Sparks", effectdata)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
timer.Remove(self:EntIndex() .. self.itemPhrase)
|
||||
end
|
||||
27
gamemodes/darkrp/entities/entities/lab_base/shared.lua
Normal file
27
gamemodes/darkrp/entities/entities/lab_base/shared.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Lab"
|
||||
ENT.Author = "DarkRP Developers"
|
||||
ENT.Spawnable = false
|
||||
ENT.CanSetPrice = true
|
||||
|
||||
-- These are variables that should be set in entities that base from this
|
||||
ENT.model = ""
|
||||
ENT.initialPrice = 0
|
||||
ENT.labPhrase = ""
|
||||
ENT.itemPhrase = ""
|
||||
ENT.noIncome = false
|
||||
ENT.camMul = -30
|
||||
ENT.blastRadius = 200
|
||||
ENT.blastDamage = 200
|
||||
|
||||
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||
|
||||
function ENT:initVars()
|
||||
-- Implement this to set the above variables
|
||||
end
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Int", 0, "price")
|
||||
self:NetworkVar("Entity", 1, "owning_ent")
|
||||
end
|
||||
76
gamemodes/darkrp/entities/entities/letter/cl_init.lua
Normal file
76
gamemodes/darkrp/entities/entities/letter/cl_init.lua
Normal file
@@ -0,0 +1,76 @@
|
||||
include("shared.lua")
|
||||
|
||||
local frame
|
||||
local SignButton
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
end
|
||||
|
||||
local function KillLetter(msg)
|
||||
hook.Remove("HUDPaint", "ShowLetter")
|
||||
frame:Remove()
|
||||
end
|
||||
usermessage.Hook("KillLetter", KillLetter)
|
||||
|
||||
local function ShowLetter(msg)
|
||||
if frame then
|
||||
frame:Remove()
|
||||
end
|
||||
|
||||
local LetterMsg = ""
|
||||
local Letter = msg:ReadEntity()
|
||||
local LetterType = msg:ReadShort()
|
||||
local LetterPos = msg:ReadVector()
|
||||
local sectionCount = msg:ReadShort()
|
||||
local LetterY = ScrH() / 2 - 300
|
||||
local LetterAlpha = 255
|
||||
|
||||
Letter:CallOnRemove("Kill letter HUD on remove", KillLetter)
|
||||
|
||||
for k = 1, sectionCount, 1 do
|
||||
LetterMsg = LetterMsg .. msg:ReadString()
|
||||
end
|
||||
|
||||
frame = vgui.Create("DFrame")
|
||||
frame:SetTitle("")
|
||||
frame:ShowCloseButton(false)
|
||||
|
||||
SignButton = vgui.Create("DButton", frame)
|
||||
SignButton:SetText(DarkRP.getPhrase("sign_this_letter"))
|
||||
frame:SetPos(ScrW() - 256, ScrH() - 256)
|
||||
SignButton:SetSize(256, 256)
|
||||
frame:SetSize(256, 256)
|
||||
SignButton:SetSkin(GAMEMODE.Config.DarkRPSkin)
|
||||
frame:SizeToContents()
|
||||
frame:MakePopup()
|
||||
frame:SetKeyboardInputEnabled(false)
|
||||
|
||||
function SignButton:DoClick()
|
||||
RunConsoleCommand("_DarkRP_SignLetter", Letter:EntIndex())
|
||||
SignButton:SetDisabled(true)
|
||||
end
|
||||
SignButton:SetDisabled(IsValid(Letter:Getsigned()))
|
||||
|
||||
hook.Add("HUDPaint", "ShowLetter", function()
|
||||
if not Letter.dt then KillLetter() return end
|
||||
if LetterAlpha < 255 then
|
||||
LetterAlpha = math.Clamp(LetterAlpha + 400 * FrameTime(), 0, 255)
|
||||
end
|
||||
|
||||
local font = (LetterType == 1 and "AckBarWriting") or "Default"
|
||||
|
||||
draw.RoundedBox(2, ScrW() * .2, LetterY, ScrW() * .8 - (ScrW() * .2), ScrH(), Color(255, 255, 255, math.Clamp(LetterAlpha, 0, 200)))
|
||||
draw.DrawNonParsedText(LetterMsg .. "\n\n\n" .. DarkRP.getPhrase("signed", IsValid(Letter:Getsigned()) and Letter:Getsigned():Nick() or DarkRP.getPhrase("no_one")), font, ScrW() * .25 + 20, LetterY + 80, Color(0, 0, 0, LetterAlpha), 0)
|
||||
|
||||
if LocalPlayer():GetPos():DistToSqr(LetterPos) > 10000 then
|
||||
LetterY = Lerp(0.1, LetterY, ScrH())
|
||||
LetterAlpha = Lerp(0.1, LetterAlpha, 0)
|
||||
if frame and frame.Close then frame:Close() end
|
||||
if math.Round(LetterAlpha) <= 10 then
|
||||
KillLetter()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
usermessage.Hook("ShowLetter", ShowLetter)
|
||||
94
gamemodes/darkrp/entities/entities/letter/commands.lua
Normal file
94
gamemodes/darkrp/entities/entities/letter/commands.lua
Normal file
@@ -0,0 +1,94 @@
|
||||
local function MakeLetter(ply, args, type)
|
||||
if not GAMEMODE.Config.letters then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("disabled", "/write / /type", ""))
|
||||
return ""
|
||||
end
|
||||
|
||||
if ply.maxletters and ply.maxletters >= GAMEMODE.Config.maxletters then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("limit", "letter"))
|
||||
return ""
|
||||
end
|
||||
|
||||
if CurTime() - ply:GetTable().LastLetterMade < 3 then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("have_to_wait", math.ceil(3 - (CurTime() - ply:GetTable().LastLetterMade)), "/write / /type"))
|
||||
return ""
|
||||
end
|
||||
|
||||
ply:GetTable().LastLetterMade = CurTime()
|
||||
|
||||
-- Instruct the player's letter window to open
|
||||
|
||||
local ftext = string.gsub(args, "//", "\n")
|
||||
ftext = string.gsub(ftext, "\\n", "\n") .. "\n\n" .. DarkRP.getPhrase("signed_yours") .. "\n" .. ply:Nick()
|
||||
local length = string.len(ftext)
|
||||
|
||||
local numParts = math.floor(length / 39) + 1
|
||||
|
||||
local trace = {}
|
||||
trace.start = ply:EyePos()
|
||||
trace.endpos = trace.start + ply:GetAimVector() * 85
|
||||
trace.filter = ply
|
||||
|
||||
local tr = util.TraceLine(trace)
|
||||
|
||||
local letter = ents.Create("letter")
|
||||
letter:SetModel("models/props_c17/paper01.mdl")
|
||||
letter:SetPos(tr.HitPos)
|
||||
letter:Setowning_ent(ply)
|
||||
letter.nodupe = true
|
||||
letter:Spawn()
|
||||
|
||||
letter:GetTable().Letter = true
|
||||
letter.type = type
|
||||
letter.numPts = numParts
|
||||
|
||||
DarkRP.placeEntity(letter, tr, ply)
|
||||
|
||||
local startpos = 1
|
||||
local endpos = 39
|
||||
letter.Parts = {}
|
||||
|
||||
for k = 1, numParts, 1 do
|
||||
table.insert(letter.Parts, string.sub(ftext, startpos, endpos))
|
||||
startpos = startpos + 39
|
||||
endpos = endpos + 39
|
||||
end
|
||||
|
||||
letter.SID = ply.SID
|
||||
|
||||
DarkRP.printMessageAll(2, DarkRP.getPhrase("created_x", ply:Nick(), "mail"))
|
||||
if not ply.maxletters then
|
||||
ply.maxletters = 0
|
||||
end
|
||||
ply.maxletters = ply.maxletters + 1
|
||||
timer.Simple(600, function() if IsValid(letter) then letter:Remove() end end)
|
||||
end
|
||||
|
||||
local function WriteLetter(ply, args)
|
||||
if args == "" then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
||||
return ""
|
||||
end
|
||||
MakeLetter(ply, args, 1)
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("write", WriteLetter)
|
||||
|
||||
local function TypeLetter(ply, args)
|
||||
if args == "" then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
||||
return ""
|
||||
end
|
||||
MakeLetter(ply, args, 2)
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("type", TypeLetter)
|
||||
|
||||
local function RemoveLetters(ply)
|
||||
for k, v in ipairs(ents.FindByClass("letter")) do
|
||||
if v.SID == ply.SID then v:Remove() end
|
||||
end
|
||||
DarkRP.notify(ply, 4, 4, DarkRP.getPhrase("cleaned_up", "mails"))
|
||||
return ""
|
||||
end
|
||||
DarkRP.defineChatCommand("removeletters", RemoveLetters)
|
||||
98
gamemodes/darkrp/entities/entities/letter/init.lua
Normal file
98
gamemodes/darkrp/entities/entities/letter/init.lua
Normal file
@@ -0,0 +1,98 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
include("commands.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_c17/paper01.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
|
||||
self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE_DEBRIS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
hook.Add("PlayerDisconnected", self, self.onPlayerDisconnected)
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
local typ = dmg:GetDamageType()
|
||||
if bit.band(typ, bit.bor(DMG_FALL, DMG_VEHICLE, DMG_DROWN, DMG_RADIATION, DMG_PHYSGUN)) > 0 then return end
|
||||
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
local ply = self:Getowning_ent()
|
||||
if not IsValid(ply) then return end
|
||||
if not ply.maxletters then
|
||||
ply.maxletters = 0
|
||||
end
|
||||
ply.maxletters = ply.maxletters - 1
|
||||
end
|
||||
|
||||
function ENT:Use(ply)
|
||||
if not ply:KeyDown(IN_ATTACK) then
|
||||
umsg.Start("ShowLetter", ply)
|
||||
umsg.Entity(self)
|
||||
umsg.Short(self.type)
|
||||
umsg.Vector(self:GetPos())
|
||||
local numParts = self.numPts
|
||||
umsg.Short(numParts)
|
||||
for _, b in ipairs(self.Parts) do umsg.String(b) end
|
||||
umsg.End()
|
||||
else
|
||||
umsg.Start("KillLetter", ply)
|
||||
umsg.End()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SignLetter(ply)
|
||||
self:Setsigned(ply)
|
||||
end
|
||||
|
||||
function ENT:onPlayerDisconnected(ply)
|
||||
if self:Getowning_ent() == ply then
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
concommand.Add("_DarkRP_SignLetter", function(ply, cmd, args)
|
||||
if not args[1] or ply:EntIndex() == 0 then return end
|
||||
local letter = ents.GetByIndex(tonumber(args[1]))
|
||||
if not IsValid(letter) or letter:GetClass() ~= "letter" then return end
|
||||
letter:SignLetter(ply)
|
||||
end)
|
||||
|
||||
local function removeLetters(ply, args)
|
||||
local target = DarkRP.findPlayer(args)
|
||||
|
||||
if target then
|
||||
for _, v in ipairs(ents.FindByClass("letter")) do
|
||||
if v.SID == target.SID then v:Remove() end
|
||||
end
|
||||
else
|
||||
-- Remove ALL letters
|
||||
for _, v in ipairs(ents.FindByClass("letter")) do
|
||||
v:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
if ply:EntIndex() == 0 then
|
||||
DarkRP.log("Console force-removed all letters", Color(30, 30, 30))
|
||||
else
|
||||
DarkRP.log(ply:Nick() .. " (" .. ply:SteamID() .. ") force-removed all letters", Color(30, 30, 30))
|
||||
end
|
||||
|
||||
DarkRP.notify(ply, 0, 4, "All letters removed")
|
||||
end
|
||||
DarkRP.definePrivilegedChatCommand("removeletters", "DarkRP_AdminCommands", removeLetters)
|
||||
28
gamemodes/darkrp/entities/entities/letter/shared.lua
Normal file
28
gamemodes/darkrp/entities/entities/letter/shared.lua
Normal file
@@ -0,0 +1,28 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "letter"
|
||||
ENT.Author = "Pcwizdan"
|
||||
ENT.Spawnable = false
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Entity",1,"owning_ent")
|
||||
self:NetworkVar("Entity",2,"signed")
|
||||
end
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "write",
|
||||
description = "Write a letter.",
|
||||
delay = 5
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "type",
|
||||
description = "Type a letter.",
|
||||
delay = 5
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "removeletters",
|
||||
description = "Remove all of your letters.",
|
||||
delay = 5
|
||||
}
|
||||
36
gamemodes/darkrp/entities/entities/meteor/cl_init.lua
Normal file
36
gamemodes/darkrp/entities/entities/meteor/cl_init.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
language.Add("meteor", "meteor")
|
||||
|
||||
function ENT:Initialize()
|
||||
local mx, mn = self:GetRenderBounds()
|
||||
self:SetRenderBounds(mn + Vector(0,0,128), mx, 0)
|
||||
self.emitter = ParticleEmitter(LocalPlayer():GetShootPos())
|
||||
end
|
||||
|
||||
local color_grey = Color(200, 200, 210)
|
||||
|
||||
function ENT:Think()
|
||||
local vOffset = self:LocalToWorld(VectorRand(-3, 3)) + VectorRand(-3, 3)
|
||||
local vNormal = (vOffset - self:GetPos()):GetNormalized()
|
||||
|
||||
if not self.emitter then return end
|
||||
|
||||
local particle = self.emitter:Add(Model("particles/smokey"), vOffset)
|
||||
particle:SetVelocity(vNormal * math.Rand(10, 30))
|
||||
particle:SetDieTime(2.0)
|
||||
particle:SetStartAlpha(math.Rand(50, 150))
|
||||
particle:SetStartSize(math.Rand(8, 16))
|
||||
particle:SetEndSize(math.Rand(32, 64))
|
||||
particle:SetRoll(math.Rand(-0.2, 0.2))
|
||||
particle:SetColor(color_grey)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if IsValid(self.emitter) then
|
||||
self.emitter:Finish()
|
||||
end
|
||||
end
|
||||
69
gamemodes/darkrp/entities/entities/meteor/init.lua
Normal file
69
gamemodes/darkrp/entities/entities/meteor/init.lua
Normal file
@@ -0,0 +1,69 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_junk/Rock001a.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:Ignite(20, 0)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
phys:EnableMotion(true)
|
||||
phys:SetMass(1000)
|
||||
phys:EnableGravity(false)
|
||||
end
|
||||
|
||||
function ENT:SetMeteorTarget(ent)
|
||||
local foundSky = util.IsInWorld(ent:GetPos())
|
||||
local zPos = ent:GetPos().z
|
||||
|
||||
for a = 1, 30, 1 do
|
||||
zPos = zPos + 100
|
||||
foundSky = util.IsInWorld(Vector(ent:GetPos().x ,ent:GetPos().y ,zPos))
|
||||
if (foundSky == false) then
|
||||
zPos = zPos - 120
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self:SetPos(Vector(ent:GetPos().x + math.random(-4000,4000),ent:GetPos().y + math.random(-4000,4000), zPos))
|
||||
local speed = 100000000
|
||||
local VNormal = (Vector(ent:GetPos().x + math.random(-500,500),ent:GetPos().y + math.random(-500,500),ent:GetPos().z) - self:GetPos()):GetNormal()
|
||||
self:GetPhysicsObject():ApplyForceCenter(VNormal * speed)
|
||||
end
|
||||
|
||||
function ENT:Destruct(notexplode)
|
||||
if not notexplode then
|
||||
util.BlastDamage(self, self, self:GetPos(), 200, 60)
|
||||
end
|
||||
|
||||
self:Extinguish()
|
||||
local vPoint = self:GetPos()
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetStart(vPoint)
|
||||
effectdata:SetOrigin(vPoint)
|
||||
effectdata:SetScale(1)
|
||||
util.Effect("Explosion", effectdata)
|
||||
-- You get warnings about changing collision rule when removing immediately
|
||||
-- https://github.com/FPtje/DarkRP/issues/2832
|
||||
timer.Simple(0, fp{SafeRemoveEntity, self})
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
if (dmg:GetDamage() > 5) then
|
||||
self:Destruct(true)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:PhysicsCollide(data, physobj)
|
||||
if data.HitEntity:GetClass() == "func_breakable_surf" then self:Remove() return end
|
||||
self:Destruct()
|
||||
end
|
||||
6
gamemodes/darkrp/entities/entities/meteor/shared.lua
Normal file
6
gamemodes/darkrp/entities/entities/meteor/shared.lua
Normal file
@@ -0,0 +1,6 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Meteor"
|
||||
ENT.Author = "Rickster"
|
||||
ENT.Contact = "Rickyman35@hotmail.com"
|
||||
ENT.Spawnable = false
|
||||
26
gamemodes/darkrp/entities/entities/microwave/init.lua
Normal file
26
gamemodes/darkrp/entities/entities/microwave/init.lua
Normal file
@@ -0,0 +1,26 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
ENT.SpawnOffset = Vector(0, 0, 23)
|
||||
|
||||
function ENT:canUse(activator)
|
||||
if activator.maxFoods and activator.maxFoods >= GAMEMODE.Config.maxfoods then
|
||||
DarkRP.notify(activator, 1, 3, DarkRP.getPhrase("limit", self.itemPhrase))
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:createItem(activator)
|
||||
local foodPos = self:GetPos() + self.SpawnOffset
|
||||
local food = ents.Create("food")
|
||||
food:SetPos(foodPos)
|
||||
food:Setowning_ent(activator)
|
||||
food.nodupe = true
|
||||
food:Spawn()
|
||||
if not activator.maxFoods then
|
||||
activator.maxFoods = 0
|
||||
end
|
||||
activator.maxFoods = activator.maxFoods + 1
|
||||
end
|
||||
9
gamemodes/darkrp/entities/entities/microwave/shared.lua
Normal file
9
gamemodes/darkrp/entities/entities/microwave/shared.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
ENT.Base = "lab_base"
|
||||
ENT.PrintName = "Microwave"
|
||||
|
||||
function ENT:initVars()
|
||||
self.model = "models/props/cs_office/microwave.mdl"
|
||||
self.initialPrice = GAMEMODE.Config.microwavefoodcost
|
||||
self.labPhrase = DarkRP.getPhrase("microwave")
|
||||
self.itemPhrase = DarkRP.getPhrase("food")
|
||||
end
|
||||
41
gamemodes/darkrp/entities/entities/money_printer/cl_init.lua
Normal file
41
gamemodes/darkrp/entities/entities/money_printer/cl_init.lua
Normal file
@@ -0,0 +1,41 @@
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:initVars()
|
||||
if not self.DisplayName or self.DisplayName == "" then
|
||||
self.DisplayName = DarkRP.getPhrase("money_printer")
|
||||
end
|
||||
end
|
||||
|
||||
local camStart3D2D = cam.Start3D2D
|
||||
local camEnd3D2D = cam.End3D2D
|
||||
local drawWordBox = draw.WordBox
|
||||
local IsValid = IsValid
|
||||
|
||||
local color_red = Color(140,0,0,100)
|
||||
local color_white = color_white
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
|
||||
local owner = self:Getowning_ent()
|
||||
owner = (IsValid(owner) and owner:Nick()) or DarkRP.getPhrase("unknown")
|
||||
|
||||
surface.SetFont("HUDNumber5")
|
||||
local text = self.DisplayName
|
||||
local TextWidth = surface.GetTextSize(text)
|
||||
local TextWidth2 = surface.GetTextSize(owner)
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Up(), 90)
|
||||
|
||||
camStart3D2D(Pos + Ang:Up() * 11.5, Ang, 0.11)
|
||||
drawWordBox(2, -TextWidth * 0.5, -30, text, "HUDNumber5", color_red, color_white)
|
||||
drawWordBox(2, -TextWidth2 * 0.5, 18, owner, "HUDNumber5", color_red, color_white)
|
||||
camEnd3D2D()
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
144
gamemodes/darkrp/entities/entities/money_printer/init.lua
Normal file
144
gamemodes/darkrp/entities/entities/money_printer/init.lua
Normal file
@@ -0,0 +1,144 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.SpawnOffset = Vector(15, 0, 15)
|
||||
|
||||
local function PrintMore(ent)
|
||||
if not IsValid(ent) then return end
|
||||
|
||||
ent.sparking = true
|
||||
timer.Simple(3, function()
|
||||
if not IsValid(ent) then return end
|
||||
ent:CreateMoneybag()
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:StartSound()
|
||||
self.sound = CreateSound(self, Sound("ambient/levels/labs/equipment_printer_loop1.wav"))
|
||||
self.sound:SetSoundLevel(52)
|
||||
self.sound:PlayEx(1, 100)
|
||||
end
|
||||
|
||||
function ENT:PostInit()
|
||||
--Dumb things what you want to run on printer spawn
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self:initVars()
|
||||
self:SetModel(self.model)
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
timer.Simple(math.random(self.MinTimer, self.MaxTimer), function() PrintMore(self) end)
|
||||
self:StartSound()
|
||||
self:PostInit()
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
if self.burningup then return end
|
||||
|
||||
self.damage = (self.damage or 100) - dmg:GetDamage()
|
||||
if self.damage <= 0 then
|
||||
local rnd = math.random(1, 10)
|
||||
if rnd < 3 then
|
||||
self:BurstIntoFlames()
|
||||
else
|
||||
self:Destruct()
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Destruct()
|
||||
local vPoint = self:GetPos()
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetStart(vPoint)
|
||||
effectdata:SetOrigin(vPoint)
|
||||
effectdata:SetScale(1)
|
||||
util.Effect("Explosion", effectdata)
|
||||
if IsValid(self:Getowning_ent()) then DarkRP.notify(self:Getowning_ent(), 1, 4, DarkRP.getPhrase("money_printer_exploded")) end
|
||||
end
|
||||
|
||||
function ENT:BurstIntoFlames()
|
||||
if hook.Run("moneyPrinterCatchFire", self) == true then return end
|
||||
|
||||
if IsValid(self:Getowning_ent()) then DarkRP.notify(self:Getowning_ent(), 0, 4, DarkRP.getPhrase("money_printer_overheating")) end
|
||||
self.burningup = true
|
||||
local burntime = math.random(8, 18)
|
||||
self:Ignite(burntime, 0)
|
||||
timer.Simple(burntime, function() self:Fireball() end)
|
||||
end
|
||||
|
||||
function ENT:Fireball()
|
||||
if not self:IsOnFire() then self.burningup = false return end
|
||||
local dist = math.random(20, 280) -- Explosion radius
|
||||
self:Destruct()
|
||||
for k, v in ipairs(ents.FindInSphere(self:GetPos(), dist)) do
|
||||
if not v:IsPlayer() and not v:IsWeapon() and v:GetClass() ~= "predicted_viewmodel" and not v.IsMoneyPrinter then
|
||||
v:Ignite(math.random(5, 22), 0)
|
||||
elseif v:IsPlayer() then
|
||||
local distance = v:GetPos():Distance(self:GetPos())
|
||||
v:TakeDamage(distance / dist * 100, self, self)
|
||||
end
|
||||
end
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:CreateMoneybag()
|
||||
if self:IsOnFire() then return end
|
||||
|
||||
local amount = self.MoneyCount or (GAMEMODE.Config.mprintamount ~= 0 and GAMEMODE.Config.mprintamount or 250)
|
||||
local prevent, hookAmount = hook.Run("moneyPrinterPrintMoney", self, amount)
|
||||
if prevent == true then return end
|
||||
|
||||
local MoneyPos = self:GetPos() + self.SpawnOffset
|
||||
amount = hookAmount or amount
|
||||
|
||||
if self.OverheatChance and self.OverheatChance > 0 then
|
||||
local overheatchance
|
||||
if self.OverheatChance <= 3 then
|
||||
overheatchance = 22
|
||||
else
|
||||
overheatchance = self.OverheatChance or 22
|
||||
end
|
||||
if math.random(1, overheatchance) == 3 then self:BurstIntoFlames() end
|
||||
end
|
||||
|
||||
local moneybag = DarkRP.createMoneyBag(MoneyPos, amount)
|
||||
hook.Run("moneyPrinterPrinted", self, moneybag)
|
||||
self.sparking = false
|
||||
timer.Simple(math.random(self.MinTimer, self.MaxTimer), function() PrintMore(self) end)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self:WaterLevel() > 0 then
|
||||
self:Destruct()
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
self:StartSound()
|
||||
if not self.sparking then return end
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin(self:GetPos())
|
||||
effectdata:SetMagnitude(1)
|
||||
effectdata:SetScale(1)
|
||||
effectdata:SetRadius(2)
|
||||
util.Effect("Sparks", effectdata)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if self.sound then
|
||||
self.sound:Stop()
|
||||
end
|
||||
end
|
||||
94
gamemodes/darkrp/entities/entities/money_printer/shared.lua
Normal file
94
gamemodes/darkrp/entities/entities/money_printer/shared.lua
Normal file
@@ -0,0 +1,94 @@
|
||||
--Static Vars
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Money Printer"
|
||||
ENT.Author = "DarkRP Developers"
|
||||
ENT.Spawnable = false
|
||||
ENT.sparking = false
|
||||
ENT.IsMoneyPrinter = true
|
||||
|
||||
function ENT:initVars()
|
||||
self.MoneyCount = GAMEMODE.Config.mprintamount
|
||||
self.OverheatChance = GAMEMODE.Config.printeroverheatchance
|
||||
self.model = "models/props_c17/consolebox01a.mdl"
|
||||
self.damage = 100
|
||||
self.DisplayName = "Money Printer"
|
||||
self.MinTimer = 100
|
||||
self.MaxTimer = 350
|
||||
self.SeizeReward = GAMEMODE.Config.printerreward
|
||||
end
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Int", 0, "price")
|
||||
self:NetworkVar("Entity", 0, "owning_ent")
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "moneyPrinterCatchFire",
|
||||
description = "Called when a money printer is about to catch fire.",
|
||||
parameters = {
|
||||
{
|
||||
name = "moneyprinter",
|
||||
description = "The money printer that is about to catch fire",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "prevent",
|
||||
description = "Set to true to prevent the money printer from catching fire",
|
||||
type = "boolean"
|
||||
}
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "moneyPrinterPrintMoney",
|
||||
description = "Called when a money printer is about to print money.",
|
||||
parameters = {
|
||||
{
|
||||
name = "moneyprinter",
|
||||
description = "The money printer that is about to print money",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "amount",
|
||||
description = "The amount to be printed",
|
||||
type = "number"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "prevent",
|
||||
description = "Set to true to prevent the money printer from printing the money.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "amount",
|
||||
description = "Optionally override the amount of money that will be printed.",
|
||||
type = "number"
|
||||
}
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "moneyPrinterPrinted",
|
||||
description = "Called after a money printer is has printed money.",
|
||||
parameters = {
|
||||
{
|
||||
name = "moneyprinter",
|
||||
description = "The money printer",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "moneybag",
|
||||
description = "The moneybag produced by the printer.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
74
gamemodes/darkrp/entities/entities/spawned_ammo/init.lua
Normal file
74
gamemodes/darkrp/entities/entities/spawned_ammo/init.lua
Normal file
@@ -0,0 +1,74 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
local phys = self:GetPhysicsObject()
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
hook.Call("playerPickedUpAmmo", nil, activator, self.amountGiven, self.ammoType, self)
|
||||
|
||||
activator:GiveAmmo(self.amountGiven, self.ammoType)
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
end
|
||||
|
||||
function ENT:StartTouch(ent)
|
||||
-- the .USED var is also used in other mods for the same purpose
|
||||
if ent.IsSpawnedAmmo ~= true or
|
||||
self.ammoType ~= ent.ammoType or
|
||||
self.hasMerged or ent.hasMerged then return end
|
||||
|
||||
ent.hasMerged = true
|
||||
ent.USED = true
|
||||
|
||||
local selfAmount, entAmount = self.amountGiven, ent.amountGiven
|
||||
local totalAmount = selfAmount + entAmount
|
||||
self.amountGiven = totalAmount
|
||||
|
||||
ent:Remove()
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerPickedUpAmmo",
|
||||
description = "When a player picks up ammo.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player who picked up ammo.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "amount",
|
||||
description = "Ammo amount.",
|
||||
type = "number"
|
||||
},
|
||||
{
|
||||
name = "type",
|
||||
description = "Ammo type.",
|
||||
type = "number"
|
||||
},
|
||||
{
|
||||
name = "spawnedAmmo",
|
||||
description = "Entity of spawned ammo.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Spawned Ammo"
|
||||
ENT.Author = "FPtje"
|
||||
ENT.Spawnable = false
|
||||
ENT.IsSpawnedAmmo = true
|
||||
68
gamemodes/darkrp/entities/entities/spawned_food/init.lua
Normal file
68
gamemodes/darkrp/entities/entities/spawned_food/init.lua
Normal file
@@ -0,0 +1,68 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
local override = self.foodItem.onEaten and self.foodItem.onEaten(self, activator, self.foodItem)
|
||||
|
||||
if override then
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
|
||||
hook.Call("playerAteFood", nil, activator, self.foodItem, self)
|
||||
|
||||
activator:setSelfDarkRPVar("Energy", math.Clamp((activator:getDarkRPVar("Energy") or 100) + (self.FoodEnergy or 1), 0, 100))
|
||||
umsg.Start("AteFoodIcon", activator)
|
||||
umsg.End()
|
||||
|
||||
self:Remove()
|
||||
activator:EmitSound(self.EatSound, 100, 100)
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerAteFood",
|
||||
description = "When a player eats food.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player who ate food.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "food",
|
||||
description = "Food table.",
|
||||
type = "table"
|
||||
},
|
||||
{
|
||||
name = "spawnedfood",
|
||||
description = "Entity of spawned food.",
|
||||
type = "Entity"
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
}
|
||||
11
gamemodes/darkrp/entities/entities/spawned_food/shared.lua
Normal file
11
gamemodes/darkrp/entities/entities/spawned_food/shared.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Spawned Food"
|
||||
ENT.Author = "Rickster"
|
||||
ENT.Spawnable = false
|
||||
ENT.IsSpawnedFood = true
|
||||
ENT.EatSound = "vo/sandwicheat09.mp3" -- Requires Team Fortress 2
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Entity", 1, "owning_ent")
|
||||
end
|
||||
32
gamemodes/darkrp/entities/entities/spawned_money/cl_init.lua
Normal file
32
gamemodes/darkrp/entities/entities/spawned_money/cl_init.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
include("shared.lua")
|
||||
|
||||
local color_red = Color(140, 0, 0, 100)
|
||||
local color_white = color_white
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
|
||||
-- Do not draw labels when a different model is used.
|
||||
-- If you want a different model with labels, make your own money entity and use GM.Config.MoneyClass.
|
||||
if self:GetModel() ~= "models/props/cs_assault/money.mdl" then return end
|
||||
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
|
||||
surface.SetFont("ChatFont")
|
||||
local text = DarkRP.formatMoney(self:Getamount())
|
||||
local TextWidth = surface.GetTextSize(text)
|
||||
|
||||
cam.Start3D2D(Pos + Ang:Up() * 0.82, Ang, 0.1)
|
||||
draw.WordBox(2, -TextWidth * 0.5, -10, text, "ChatFont", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Right(), 180)
|
||||
|
||||
cam.Start3D2D(Pos, Ang, 0.1)
|
||||
draw.WordBox(2, -TextWidth * 0.5, -10, text, "ChatFont", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
126
gamemodes/darkrp/entities/entities/spawned_money/init.lua
Normal file
126
gamemodes/darkrp/entities/entities/spawned_money/init.lua
Normal file
@@ -0,0 +1,126 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel(GAMEMODE.Config.moneyModel or "models/props/cs_assault/money.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_WEAPON)
|
||||
|
||||
self.nodupe = true
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
if self.USED or self.hasMerged then return end
|
||||
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
self.USED = true
|
||||
local amount = self:Getamount()
|
||||
|
||||
hook.Call("playerPickedUpMoney", nil, activator, amount or 0, self)
|
||||
|
||||
activator:addMoney(amount or 0)
|
||||
DarkRP.notify(activator, 0, 4, DarkRP.getPhrase("found_money", DarkRP.formatMoney(self:Getamount())))
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
|
||||
local typ = dmg:GetDamageType()
|
||||
if bit.band(typ, bit.bor(DMG_FALL, DMG_VEHICLE, DMG_DROWN, DMG_RADIATION, DMG_PHYSGUN)) > 0 then return end
|
||||
|
||||
self.USED = true
|
||||
self.hasMerged = true
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:StartTouch(ent)
|
||||
-- the .USED var is also used in other mods for the same purpose
|
||||
if ent:GetClass() ~= "spawned_money" or self.USED or ent.USED or self.hasMerged or ent.hasMerged then return end
|
||||
|
||||
-- Both hasMerged and USED are used by third party mods. Keep both in.
|
||||
ent.USED = true
|
||||
ent.hasMerged = true
|
||||
|
||||
ent:Remove()
|
||||
self:Setamount(self:Getamount() + ent:Getamount())
|
||||
if GAMEMODE.Config.moneyRemoveTime and GAMEMODE.Config.moneyRemoveTime ~= 0 then
|
||||
timer.Adjust("RemoveEnt" .. self:EntIndex(), GAMEMODE.Config.moneyRemoveTime, 1, fn.Partial(SafeRemoveEntity, self))
|
||||
end
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerPickedUpMoney",
|
||||
description = "Called when a player picked up money.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who picked up the money.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "amount",
|
||||
description = "The amount of money picked up.",
|
||||
type = "number"
|
||||
},
|
||||
{
|
||||
name = "entity",
|
||||
description = "The entity of the money picked up itself.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canDarkRPUse",
|
||||
description = "When a player uses an entity.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player who tries to use the entity.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "entity",
|
||||
description = "The actual entity the player attempts to use.",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "caller",
|
||||
description = "The entity that directly triggered the input.",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "canUse",
|
||||
description = "Whether the entity should be used or not.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "reason",
|
||||
description = "Why the entity cannot be used.",
|
||||
optional = true,
|
||||
type = "string"
|
||||
},
|
||||
},
|
||||
}
|
||||
10
gamemodes/darkrp/entities/entities/spawned_money/shared.lua
Normal file
10
gamemodes/darkrp/entities/entities/spawned_money/shared.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Spawned Money"
|
||||
ENT.Author = "FPtje"
|
||||
ENT.Spawnable = false
|
||||
ENT.IsSpawnedMoney = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Int",0,"amount")
|
||||
end
|
||||
161
gamemodes/darkrp/entities/entities/spawned_shipment/cl_init.lua
Normal file
161
gamemodes/darkrp/entities/entities/spawned_shipment/cl_init.lua
Normal file
@@ -0,0 +1,161 @@
|
||||
include("shared.lua")
|
||||
|
||||
local matBallGlow = Material("models/props_combine/tpballglow")
|
||||
function ENT:Draw()
|
||||
self.height = self.height or 0
|
||||
self.colr = self.colr or 1
|
||||
self.colg = self.colg or 0
|
||||
self.StartTime = self.StartTime or CurTime()
|
||||
|
||||
if GAMEMODE.Config.shipmentspawntime > 0 and self.height < self:OBBMaxs().z then
|
||||
self:drawSpawning()
|
||||
else
|
||||
self:DrawModel()
|
||||
end
|
||||
|
||||
self:drawFloatingGun()
|
||||
self:drawInfo()
|
||||
end
|
||||
|
||||
net.Receive("DarkRP_shipmentSpawn", function()
|
||||
local ent = net.ReadEntity()
|
||||
if not IsValid(ent) or not ent.IsSpawnedShipment then return end
|
||||
|
||||
ent.height = 0
|
||||
ent.StartTime = CurTime()
|
||||
end)
|
||||
|
||||
function ENT:drawSpawning()
|
||||
render.MaterialOverride(matBallGlow)
|
||||
|
||||
render.SetColorModulation(self.colr, self.colg, 0)
|
||||
|
||||
self:DrawModel()
|
||||
|
||||
render.MaterialOverride()
|
||||
self.colr = 1 - ((CurTime() - self.StartTime) / GAMEMODE.Config.shipmentspawntime)
|
||||
self.colg = (CurTime() - self.StartTime) / GAMEMODE.Config.shipmentspawntime
|
||||
|
||||
render.SetColorModulation(1, 1, 1)
|
||||
|
||||
render.MaterialOverride()
|
||||
|
||||
local normal = - self:GetAngles():Up()
|
||||
local pos = self:LocalToWorld(Vector(0, 0, self:OBBMins().z + self.height))
|
||||
local distance = normal:Dot(pos)
|
||||
self.height = self:OBBMaxs().z * ((CurTime() - self.StartTime) / GAMEMODE.Config.shipmentspawntime)
|
||||
render.EnableClipping(true)
|
||||
render.PushCustomClipPlane(normal, distance)
|
||||
|
||||
self:DrawModel()
|
||||
|
||||
render.PopCustomClipPlane()
|
||||
end
|
||||
|
||||
function ENT:drawFloatingGun()
|
||||
local contents = CustomShipments[self:Getcontents() or ""]
|
||||
if not contents or not IsValid(self:GetgunModel()) then return end
|
||||
self:GetgunModel():SetNoDraw(true)
|
||||
|
||||
local pos = self:GetPos()
|
||||
local ang = self:GetAngles()
|
||||
|
||||
-- Position the gun
|
||||
local gunPos = self:GetAngles():Up() * 40 + ang:Up() * (math.sin(CurTime() * 3) * 8)
|
||||
self:GetgunModel():SetPos(pos + gunPos)
|
||||
|
||||
|
||||
-- Make it dance
|
||||
ang:RotateAroundAxis(ang:Up(), (CurTime() * 180) % 360)
|
||||
self:GetgunModel():SetAngles(ang)
|
||||
|
||||
-- Draw the model
|
||||
if self:Getgunspawn() < CurTime() - 2 then
|
||||
self:GetgunModel():DrawModel()
|
||||
return
|
||||
elseif self:Getgunspawn() < CurTime() then -- Not when a gun just spawned
|
||||
return
|
||||
end
|
||||
|
||||
-- Draw the spawning effect
|
||||
local delta = self:Getgunspawn() - CurTime()
|
||||
local min, max = self:GetgunModel():OBBMins(), self:GetgunModel():OBBMaxs()
|
||||
min, max = self:GetgunModel():LocalToWorld(min), self:GetgunModel():LocalToWorld(max)
|
||||
|
||||
-- Draw the ghosted weapon
|
||||
render.MaterialOverride(matBallGlow)
|
||||
render.SetColorModulation(1 - delta, delta, 0) -- From red to green
|
||||
self:GetgunModel():DrawModel()
|
||||
render.MaterialOverride()
|
||||
render.SetColorModulation(1, 1, 1)
|
||||
|
||||
-- Draw the cut-off weapon
|
||||
render.EnableClipping(true)
|
||||
-- The clipping plane only draws objects that face the plane
|
||||
local normal = -self:GetgunModel():GetAngles():Forward()
|
||||
local cutPosition = LerpVector(delta, max, min) -- Where it cuts
|
||||
local cutDistance = normal:Dot(cutPosition) -- Project the vector onto the normal to get the shortest distance between the plane and origin
|
||||
|
||||
-- Activate the plane
|
||||
render.PushCustomClipPlane(normal, cutDistance);
|
||||
-- Draw the partial model
|
||||
self:GetgunModel():DrawModel()
|
||||
-- Remove the plane
|
||||
render.PopCustomClipPlane()
|
||||
|
||||
render.EnableClipping(false)
|
||||
end
|
||||
|
||||
local color_red = Color(140, 0, 0, 100)
|
||||
local color_white = color_white
|
||||
|
||||
function ENT:drawInfo()
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
|
||||
local content = self:Getcontents() or ""
|
||||
local contents = CustomShipments[content]
|
||||
if not contents then return end
|
||||
contents = contents.name
|
||||
|
||||
surface.SetFont("HUDNumber5")
|
||||
local text = DarkRP.getPhrase("contents")
|
||||
local TextWidth = surface.GetTextSize(text)
|
||||
local TextWidth2 = surface.GetTextSize(contents)
|
||||
|
||||
cam.Start3D2D(Pos + Ang:Up() * 25, Ang, 0.2)
|
||||
draw.WordBox(2, -TextWidth * 0.5 + 5, -30, text, "HUDNumber5", color_red, color_white)
|
||||
draw.WordBox(2, -TextWidth2 * 0.5 + 5, 18, contents, "HUDNumber5", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Forward(), 90)
|
||||
|
||||
text = DarkRP.getPhrase("amount")
|
||||
TextWidth = surface.GetTextSize(text)
|
||||
TextWidth2 = surface.GetTextSize(self:Getcount())
|
||||
|
||||
cam.Start3D2D(Pos + Ang:Up() * 17, Ang, 0.14)
|
||||
draw.WordBox(2, -TextWidth * 0.5 + 5, -150, text, "HUDNumber5", color_red, color_white)
|
||||
draw.WordBox(2, -TextWidth2 * 0.5 + 0, -102, self:Getcount(), "HUDNumber5", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Create a shipment from a spawned_weapon
|
||||
---------------------------------------------------------------------------]]
|
||||
properties.Add("splitShipment",
|
||||
{
|
||||
MenuLabel = DarkRP.getPhrase("splitshipment"),
|
||||
Order = 2004,
|
||||
MenuIcon = "icon16/arrow_divide.png",
|
||||
|
||||
Filter = function(self, ent, ply)
|
||||
if not IsValid(ent) then return false end
|
||||
return ent.IsSpawnedShipment
|
||||
end,
|
||||
|
||||
Action = function(self, ent)
|
||||
if not IsValid(ent) then return end
|
||||
RunConsoleCommand("darkrp", "splitshipment", ent:EntIndex())
|
||||
end
|
||||
})
|
||||
103
gamemodes/darkrp/entities/entities/spawned_shipment/commands.lua
Normal file
103
gamemodes/darkrp/entities/entities/spawned_shipment/commands.lua
Normal file
@@ -0,0 +1,103 @@
|
||||
--[[---------------------------------------------------------------------------
|
||||
Create a shipment from a spawned_weapon
|
||||
---------------------------------------------------------------------------]]
|
||||
local function createShipment(ply, args)
|
||||
local id = tonumber(args) or -1
|
||||
local ent = Entity(id)
|
||||
|
||||
ent = IsValid(ent) and ent or ply:GetEyeTrace().Entity
|
||||
|
||||
if not IsValid(ent) or not ent.IsSpawnedWeapon or ent.PlayerUse == false then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
||||
return
|
||||
end
|
||||
|
||||
local pos = ent:GetPos()
|
||||
|
||||
if pos:DistToSqr(ply:GetShootPos()) > 16900 or not pos:isInSight({ent, ply} , ply) then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("distance_too_big"))
|
||||
return
|
||||
end
|
||||
|
||||
ent.PlayerUse = false
|
||||
|
||||
local shipID
|
||||
for k, v in pairs(CustomShipments) do
|
||||
if v.entity == ent:GetWeaponClass() then
|
||||
shipID = k
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not shipID or ent.USED then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("unable", "/makeshipment", ""))
|
||||
return
|
||||
end
|
||||
|
||||
local crate = ents.Create(CustomShipments[shipID].shipmentClass or "spawned_shipment")
|
||||
crate.SID = ply.SID
|
||||
crate:SetPos(ent:GetPos())
|
||||
crate.nodupe = true
|
||||
crate:SetContents(shipID, ent:Getamount())
|
||||
crate:Spawn()
|
||||
crate:SetPlayer(ply)
|
||||
crate.clip1 = ent.clip1
|
||||
crate.clip2 = ent.clip2
|
||||
crate.ammoadd = ent.ammoadd or 0
|
||||
|
||||
SafeRemoveEntity(ent)
|
||||
|
||||
local phys = crate:GetPhysicsObject()
|
||||
phys:Wake()
|
||||
end
|
||||
DarkRP.defineChatCommand("makeshipment", createShipment, 0.3)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Split a shipment in two
|
||||
---------------------------------------------------------------------------]]
|
||||
local function splitShipment(ply, args)
|
||||
local id = tonumber(args) or -1
|
||||
local ent = Entity(id)
|
||||
|
||||
ent = IsValid(ent) and ent or ply:GetEyeTrace().Entity
|
||||
|
||||
if not IsValid(ent) or not ent.IsSpawnedShipment then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("invalid_x", DarkRP.getPhrase("arguments"), ""))
|
||||
return
|
||||
end
|
||||
|
||||
if ent:Getcount() < 2 or ent.locked or ent.USED then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("shipment_cannot_split"))
|
||||
return
|
||||
end
|
||||
|
||||
local pos = ent:GetPos()
|
||||
|
||||
if pos:DistToSqr(ply:GetShootPos()) > 16900 or not pos:isInSight({ent, ply} , ply) then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("distance_too_big"))
|
||||
return
|
||||
end
|
||||
|
||||
local count = math.floor(ent:Getcount() / 2)
|
||||
ent:Setcount(ent:Getcount() - count)
|
||||
|
||||
ent:StartSpawning()
|
||||
|
||||
local crate = ents.Create("spawned_shipment")
|
||||
crate.locked = true
|
||||
crate.SID = ply.SID
|
||||
crate:SetPos(ent:GetPos())
|
||||
crate.nodupe = true
|
||||
crate:SetContents(ent:Getcontents(), count)
|
||||
crate:SetPlayer(ply)
|
||||
|
||||
crate.clip1 = ent.clip1
|
||||
crate.clip2 = ent.clip2
|
||||
crate.ammoadd = ent.ammoadd
|
||||
|
||||
crate:Spawn()
|
||||
|
||||
local phys = crate:GetPhysicsObject()
|
||||
phys:Wake()
|
||||
end
|
||||
DarkRP.defineChatCommand("splitshipment", splitShipment, 0.3)
|
||||
257
gamemodes/darkrp/entities/entities/spawned_shipment/init.lua
Normal file
257
gamemodes/darkrp/entities/entities/spawned_shipment/init.lua
Normal file
@@ -0,0 +1,257 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
include("commands.lua")
|
||||
|
||||
util.AddNetworkString("DarkRP_shipmentSpawn")
|
||||
|
||||
function ENT:Initialize()
|
||||
local contents = CustomShipments[self:Getcontents() or ""]
|
||||
|
||||
self.Destructed = false
|
||||
self:SetModel(contents and contents.shipmodel or "models/Items/item_item_crate.mdl")
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
self:StartSpawning()
|
||||
self.damage = 100
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
-- Create a serverside gun model
|
||||
-- it's required serverside to be able to get OBB information clientside
|
||||
self:SetgunModel(IsValid(self:GetgunModel()) and self:GetgunModel() or ents.Create("prop_physics"))
|
||||
self:GetgunModel():SetModel(contents.model)
|
||||
self:GetgunModel():SetPos(self:GetPos())
|
||||
self:GetgunModel():Spawn()
|
||||
self:GetgunModel():Activate()
|
||||
self:GetgunModel():SetSolid(SOLID_NONE)
|
||||
self:GetgunModel():SetParent(self)
|
||||
|
||||
phys = self:GetgunModel():GetPhysicsObject()
|
||||
|
||||
if phys:IsValid() then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
|
||||
-- The following code should not be reached
|
||||
if self:Getcount() < 1 then
|
||||
self.PlayerUse = false
|
||||
SafeRemoveEntity(self)
|
||||
if not contents then
|
||||
DarkRP.error("Shipment created with zero or fewer elements.", 2)
|
||||
else
|
||||
DarkRP.error(string.format("Some smartass thought they were clever by setting the 'amount' of shipment '%s' to 0.\nWhat the fuck do you expect the use of an empty shipment to be?", contents.name), 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:StartSpawning()
|
||||
self.locked = true
|
||||
timer.Simple(0, function()
|
||||
net.Start("DarkRP_shipmentSpawn")
|
||||
net.WriteEntity(self)
|
||||
net.Broadcast()
|
||||
end)
|
||||
|
||||
timer.Simple(0, function() self.locked = true end) -- when spawning through pocket it might be unlocked
|
||||
timer.Simple(GAMEMODE.Config.shipmentspawntime, function() if IsValid(self) then self.locked = false end end)
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
if not self.locked then
|
||||
self.damage = self.damage - dmg:GetDamage()
|
||||
if self.damage <= 0 then
|
||||
self:Destruct()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SetContents(s, c)
|
||||
self:Setcontents(s)
|
||||
self:Setcount(c)
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
if self.IsPocketed then return end
|
||||
if isfunction(self.PlayerUse) then
|
||||
local val = self:PlayerUse(activator, caller)
|
||||
if val ~= nil then return val end
|
||||
elseif self.PlayerUse ~= nil then
|
||||
return self.PlayerUse
|
||||
end
|
||||
|
||||
if self.locked or self.USED then return end
|
||||
|
||||
local canUse, reason = hook.Call("canDarkRPUse", nil, activator, self, caller)
|
||||
if canUse == false then
|
||||
if reason then DarkRP.notify(activator, 1, 4, reason) end
|
||||
return
|
||||
end
|
||||
|
||||
hook.Call("playerOpenedShipment", nil, activator, self)
|
||||
|
||||
self.locked = true -- One activation per second
|
||||
self.USED = true
|
||||
self.sparking = true
|
||||
self:Setgunspawn(CurTime() + 1)
|
||||
timer.Create(self:EntIndex() .. "crate", 1, 1, function()
|
||||
if not IsValid(self) then return end
|
||||
self.SpawnItem(self)
|
||||
end)
|
||||
end
|
||||
|
||||
local function calculateAmmo(class, shipment)
|
||||
local clip1, ammoadd = shipment.clip1, shipment.ammoadd
|
||||
|
||||
local defaultClip, clipSize = 0, 0
|
||||
local wep_tbl = weapons.Get(class)
|
||||
if wep_tbl and istable(wep_tbl.Primary) then
|
||||
defaultClip = wep_tbl.Primary.DefaultClip or -1
|
||||
clipSize = wep_tbl.Primary.ClipSize or -1
|
||||
end
|
||||
ammoadd = ammoadd or defaultClip
|
||||
|
||||
if not clip1 then
|
||||
clip1 = clipSize
|
||||
end
|
||||
return ammoadd, clip1
|
||||
end
|
||||
|
||||
function ENT:SpawnItem()
|
||||
timer.Remove(self:EntIndex() .. "crate")
|
||||
self.sparking = false
|
||||
local count = self:Getcount()
|
||||
if count <= 1 then self:Remove() end
|
||||
local contents = self:Getcontents()
|
||||
|
||||
if CustomShipments[contents] and CustomShipments[contents].spawn then self.USED = false return CustomShipments[contents].spawn(self, CustomShipments[contents]) end
|
||||
|
||||
local weapon = ents.Create("spawned_weapon")
|
||||
|
||||
local weaponAng = self:GetAngles()
|
||||
local weaponPos = self:GetAngles():Up() * 40 + weaponAng:Up() * (math.sin(CurTime() * 3) * 8)
|
||||
weaponAng:RotateAroundAxis(weaponAng:Up(), (CurTime() * 180) % 360)
|
||||
|
||||
if not CustomShipments[contents] then
|
||||
weapon:Remove()
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
|
||||
local class = CustomShipments[contents].entity
|
||||
local model = CustomShipments[contents].model
|
||||
|
||||
weapon:SetWeaponClass(class)
|
||||
weapon:SetModel(model)
|
||||
|
||||
weapon.ammoadd, weapon.clip1 = calculateAmmo(class, self)
|
||||
weapon.clip2 = self.clip2
|
||||
weapon:SetPos(self:GetPos() + weaponPos)
|
||||
weapon:SetAngles(weaponAng)
|
||||
weapon.nodupe = true
|
||||
weapon:Spawn()
|
||||
count = count - 1
|
||||
self:Setcount(count)
|
||||
self.locked = false
|
||||
self.USED = nil
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self.sparking then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin(self:GetPos())
|
||||
effectdata:SetMagnitude(1)
|
||||
effectdata:SetScale(1)
|
||||
effectdata:SetRadius(2)
|
||||
util.Effect("Sparks", effectdata)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Destruct()
|
||||
if self.Destructed then return end
|
||||
self.Destructed = true
|
||||
local vPoint = self:GetPos()
|
||||
local contents = self:Getcontents()
|
||||
local count = self:Getcount()
|
||||
local class = nil
|
||||
local model = nil
|
||||
|
||||
if CustomShipments[contents] then
|
||||
class = CustomShipments[contents].entity
|
||||
model = CustomShipments[contents].model
|
||||
else
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
|
||||
local weapon = ents.Create("spawned_weapon")
|
||||
weapon:SetModel(model)
|
||||
weapon:SetWeaponClass(class)
|
||||
weapon:SetPos(Vector(vPoint.x, vPoint.y, vPoint.z + 5))
|
||||
weapon.ammoadd, weapon.clip1 = calculateAmmo(class, self)
|
||||
weapon.clip2 = self.clip2
|
||||
weapon.nodupe = true
|
||||
weapon:Spawn()
|
||||
weapon:Setamount(count)
|
||||
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:StartTouch(ent)
|
||||
-- the .USED var is also used in other mods for the same purpose
|
||||
if not ent.IsSpawnedShipment or
|
||||
self:Getcontents() ~= ent:Getcontents() or
|
||||
self.locked or ent.locked or
|
||||
self.USED or ent.USED or
|
||||
self.hasMerged or ent.hasMerged then return end
|
||||
|
||||
-- Both hasMerged and USED are used by third party mods. Keep both in.
|
||||
ent.hasMerged = true
|
||||
ent.USED = true
|
||||
|
||||
local selfCount, entCount = self:Getcount(), ent:Getcount()
|
||||
local count = selfCount + entCount
|
||||
self:Setcount(count)
|
||||
|
||||
-- Merge ammo information (avoid ammo exploits)
|
||||
if self.clip1 or ent.clip1 then -- If neither have a clip, use default clip, otherwise merge the two
|
||||
self.clip1 = math.floor(((ent.clip1 or 0) * entCount + (self.clip1 or 0) * selfCount) / count)
|
||||
end
|
||||
|
||||
if self.clip2 or ent.clip2 then
|
||||
self.clip2 = math.floor(((ent.clip2 or 0) * entCount + (self.clip2 or 0) * selfCount) / count)
|
||||
end
|
||||
|
||||
if self.ammoadd or ent.ammoadd then
|
||||
self.ammoadd = math.floor(((ent.ammoadd or 0) * entCount + (self.ammoadd or 0) * selfCount) / count)
|
||||
end
|
||||
|
||||
ent:Remove()
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerOpenedShipment",
|
||||
description = "When a player opens a shipment.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who opens a shipment.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "entity",
|
||||
description = "Entity of spawned shipment.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Shipment"
|
||||
ENT.Author = "philxyz"
|
||||
ENT.Spawnable = false
|
||||
ENT.IsSpawnedShipment = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Int",0,"contents")
|
||||
self:NetworkVar("Int",1,"count")
|
||||
self:NetworkVar("Float", 0, "gunspawn")
|
||||
self:NetworkVar("Entity", 0, "owning_ent")
|
||||
self:NetworkVar("Entity", 1, "gunModel")
|
||||
end
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "splitshipment",
|
||||
description = "Split the shipment you're looking at.",
|
||||
delay = 1.5
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "makeshipment",
|
||||
description = "Create a shipment from a dropped weapon.",
|
||||
delay = 1.5
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
include("shared.lua")
|
||||
|
||||
local color_red = Color(140, 0, 0, 100)
|
||||
local color_white = color_white
|
||||
|
||||
function ENT:Draw()
|
||||
local ret = hook.Call("onDrawSpawnedWeapon", nil, self)
|
||||
if ret ~= nil then return end
|
||||
self:DrawModel()
|
||||
|
||||
local amount = self:Getamount()
|
||||
if amount == 1 then return end
|
||||
|
||||
local Pos = self:GetPos()
|
||||
local Ang = self:GetAngles()
|
||||
local text = DarkRP.getPhrase("amount") .. amount
|
||||
|
||||
surface.SetFont("HUDNumber5")
|
||||
local TextWidth = surface.GetTextSize(text)
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Forward(), 90)
|
||||
|
||||
cam.Start3D2D(Pos + Ang:Up(), Ang, 0.11)
|
||||
draw.WordBox(2, 0, -40, text, "HUDNumber5", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
|
||||
Ang:RotateAroundAxis(Ang:Right(), 180)
|
||||
|
||||
cam.Start3D2D(Pos + Ang:Up() * 3, Ang, 0.11)
|
||||
draw.WordBox(2, -TextWidth, -40, text, "HUDNumber5", color_red, color_white)
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Create a shipment from a spawned_weapon
|
||||
---------------------------------------------------------------------------]]
|
||||
properties.Add("createShipment",
|
||||
{
|
||||
MenuLabel = DarkRP.getPhrase("createshipment"),
|
||||
Order = 2003,
|
||||
MenuIcon = "icon16/add.png",
|
||||
|
||||
Filter = function(self, ent, ply)
|
||||
if not IsValid(ent) then return false end
|
||||
return ent.IsSpawnedWeapon
|
||||
end,
|
||||
|
||||
Action = function(self, ent)
|
||||
if not IsValid(ent) then return end
|
||||
RunConsoleCommand("darkrp", "makeshipment", ent:EntIndex())
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Interface
|
||||
---------------------------------------------------------------------------]]
|
||||
DarkRP.hookStub{
|
||||
name = "onDrawSpawnedWeapon",
|
||||
description = "Draw spawned weapons.",
|
||||
realm = "Client",
|
||||
parameters = {
|
||||
{
|
||||
name = "weapon",
|
||||
description = "The weapon to perform drawing operations on.",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "value",
|
||||
description = "Return a value to completely override drawing",
|
||||
type = "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
163
gamemodes/darkrp/entities/entities/spawned_weapon/init.lua
Normal file
163
gamemodes/darkrp/entities/entities/spawned_weapon/init.lua
Normal file
@@ -0,0 +1,163 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
DarkRP.ValidatedPhysicsInit(self, SOLID_VPHYSICS,
|
||||
string.format("The issue lies with weapon \"%s\"", self:GetWeaponClass() or "unknown"))
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
local phys = self:GetPhysicsObject()
|
||||
phys:Wake()
|
||||
|
||||
if self:Getamount() == 0 then
|
||||
self:Setamount(1)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:DecreaseAmount()
|
||||
local amount = self:Getamount() - 1
|
||||
self:Setamount(amount)
|
||||
|
||||
if amount <= 0 then
|
||||
self:Remove()
|
||||
self.PlayerUse = false
|
||||
self.Removed = true -- because it is not removed immediately
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmg)
|
||||
self:TakePhysicsDamage(dmg)
|
||||
end
|
||||
|
||||
function ENT:Use(activator, caller)
|
||||
if isfunction(self.PlayerUse) then
|
||||
local val = self:PlayerUse(activator, caller)
|
||||
if val ~= nil then return val end
|
||||
elseif self.PlayerUse ~= nil then
|
||||
return self.PlayerUse
|
||||
end
|
||||
|
||||
local class = self:GetWeaponClass()
|
||||
local weapon = ents.Create(class)
|
||||
|
||||
if not weapon:IsWeapon() then
|
||||
weapon:SetPos(self:GetPos())
|
||||
weapon:SetAngles(self:GetAngles())
|
||||
weapon:Spawn()
|
||||
weapon:Activate()
|
||||
self:DecreaseAmount()
|
||||
return
|
||||
end
|
||||
|
||||
local CanPickup = hook.Call("PlayerCanPickupWeapon", GAMEMODE, activator, weapon)
|
||||
local ShouldntContinue = hook.Call("PlayerPickupDarkRPWeapon", nil, activator, self, weapon)
|
||||
if not CanPickup or ShouldntContinue then
|
||||
weapon:Remove()
|
||||
return
|
||||
end
|
||||
|
||||
weapon:Remove()
|
||||
|
||||
weapon = activator:Give(class, true)
|
||||
|
||||
-- The player already had the weapon when the result of :Give() is not a
|
||||
-- valid weapon
|
||||
local activatorHadWeapon = not weapon:IsValid()
|
||||
weapon = activatorHadWeapon and activator:GetWeapon(class) or weapon
|
||||
|
||||
hook.Call("playerPickedUpWeapon", nil, activator, self, weapon)
|
||||
|
||||
self:GivePlayerAmmo(activator, weapon, activatorHadWeapon)
|
||||
|
||||
self:DecreaseAmount()
|
||||
end
|
||||
|
||||
function ENT:GivePlayerAmmo(ply, weapon, playerHadWeapon)
|
||||
local primaryAmmoType = weapon:GetPrimaryAmmoType()
|
||||
local secondaryAmmoType = weapon:GetSecondaryAmmoType()
|
||||
local clip1, clip2 = self.clip1, self.clip2
|
||||
|
||||
if playerHadWeapon then
|
||||
if clip2 and clip2 > 0 and weapon:Clip2() ~= -1 then
|
||||
weapon:SetClip2(weapon:Clip2() + clip2)
|
||||
clip2 = 0
|
||||
end
|
||||
else
|
||||
if clip1 and clip1 ~= -1 and weapon:Clip1() ~= -1 then
|
||||
weapon:SetClip1(clip1)
|
||||
clip1 = 0
|
||||
end
|
||||
if clip2 and clip2 ~= -1 and weapon:Clip2() ~= -1 then
|
||||
weapon:SetClip2(self.clip2)
|
||||
clip2 = 0
|
||||
end
|
||||
end
|
||||
|
||||
if primaryAmmoType > 0 then
|
||||
local primAmmo = ply:GetAmmoCount(primaryAmmoType)
|
||||
primAmmo = primAmmo + (self.ammoadd or 0) + (clip1 or 0) -- Gets rid of any ammo given during weapon pickup
|
||||
ply:SetAmmo(primAmmo, primaryAmmoType)
|
||||
end
|
||||
|
||||
if secondaryAmmoType > 0 then
|
||||
local secAmmo = ply:GetAmmoCount(secondaryAmmoType) + (clip2 or 0)
|
||||
ply:SetAmmo(secAmmo, secondaryAmmoType)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:StartTouch(ent)
|
||||
-- the .USED var is also used in other mods for the same purpose
|
||||
if ent.IsSpawnedWeapon ~= true or
|
||||
self:GetWeaponClass() ~= ent:GetWeaponClass() or
|
||||
self.hasMerged or ent.hasMerged then return end
|
||||
|
||||
ent.hasMerged = true
|
||||
ent.USED = true
|
||||
|
||||
local selfAmount, entAmount = self:Getamount(), ent:Getamount()
|
||||
local totalAmount = selfAmount + entAmount
|
||||
self.ammoadd, ent.ammoadd = self.ammoadd or 0, ent.ammoadd or 0
|
||||
|
||||
-- ammoAdd will be the floored average of both weapons' ammoadd
|
||||
-- Some ammo might get lost there.
|
||||
self.ammoadd = math.floor((self.ammoadd * selfAmount + ent.ammoadd * entAmount) / totalAmount)
|
||||
|
||||
-- If neither have a clip, use default clip, otherwise merge the two
|
||||
if self.clip1 or ent.clip1 then
|
||||
self.clip1 = math.floor(((self.clip1 or 0) * selfAmount + (ent.clip1 or 0) * entAmount) / totalAmount)
|
||||
end
|
||||
|
||||
if self.clip2 or ent.clip2 then
|
||||
self.clip2 = math.floor(((self.clip2 or 0) * selfAmount + (ent.clip2 or 0) * entAmount) / totalAmount)
|
||||
end
|
||||
|
||||
self:Setamount(totalAmount)
|
||||
ent:Remove()
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerPickedUpWeapon",
|
||||
description = "When a player picks up a weapon.",
|
||||
parameters = {
|
||||
{
|
||||
name = "player",
|
||||
description = "The player who picks up the weapon.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "entity",
|
||||
description = "Entity of spawned weapon.",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "weapon",
|
||||
description = "The weapon entity that the player is holding after picking up the weapon.",
|
||||
type = "Weapon"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
}
|
||||
11
gamemodes/darkrp/entities/entities/spawned_weapon/shared.lua
Normal file
11
gamemodes/darkrp/entities/entities/spawned_weapon/shared.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.PrintName = "Spawned Weapon"
|
||||
ENT.Author = "Rickster"
|
||||
ENT.Spawnable = false
|
||||
ENT.IsSpawnedWeapon = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Int", 0, "amount")
|
||||
self:NetworkVar("String", 0, "WeaponClass")
|
||||
end
|
||||
139
gamemodes/darkrp/entities/weapons/arrest_stick/shared.lua
Normal file
139
gamemodes/darkrp/entities/weapons/arrest_stick/shared.lua
Normal file
@@ -0,0 +1,139 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 3
|
||||
end
|
||||
|
||||
DEFINE_BASECLASS("stick_base")
|
||||
|
||||
SWEP.Instructions = "Left click to arrest\nRight click to switch batons"
|
||||
SWEP.IsDarkRPArrestStick = true
|
||||
|
||||
SWEP.PrintName = "Arrest Baton"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
|
||||
SWEP.StickColor = Color(255, 0, 0)
|
||||
|
||||
SWEP.Switched = true
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canArrest",
|
||||
description = "Whether someone can arrest another player.",
|
||||
parameters = {
|
||||
{
|
||||
name = "arrester",
|
||||
description = "The player trying to arrest someone.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "arrestee",
|
||||
description = "The player being arrested.",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "canArrest",
|
||||
description = "A yes or no as to whether the arrester can arrest the arestee.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "message",
|
||||
description = "The message that is shown when they can't arrest the player.",
|
||||
type = "string"
|
||||
}
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "setArrestStickTime",
|
||||
description = "Sets arrest time for an arrest made via the arrest stick",
|
||||
parameters = {
|
||||
{
|
||||
name = "arrest_stick",
|
||||
description = "The arrest strick weapon with which the arrestee was arrested.",
|
||||
type = "Weapon"
|
||||
},
|
||||
{
|
||||
name = "arrester",
|
||||
description = "The player trying to arrest someone.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "arrestee",
|
||||
description = "The player being arrested.",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "time",
|
||||
description = "The time to arrest the player.",
|
||||
type = "integer"
|
||||
}
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
function SWEP:Deploy()
|
||||
self.Switched = true
|
||||
return BaseClass.Deploy(self)
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
BaseClass.PrimaryAttack(self)
|
||||
|
||||
if CLIENT then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
Owner:LagCompensation(true)
|
||||
local trace = util.QuickTrace(Owner:EyePos(), Owner:GetAimVector() * 90, {Owner})
|
||||
Owner:LagCompensation(false)
|
||||
|
||||
local ent = trace.Entity
|
||||
if IsValid(ent) and ent.onArrestStickUsed then
|
||||
ent:onArrestStickUsed(Owner)
|
||||
return
|
||||
end
|
||||
|
||||
ent = Owner:getEyeSightHitEntity(nil, nil, function(p) return p ~= Owner and p:IsPlayer() and p:Alive() and p:IsSolid() end)
|
||||
|
||||
local stickRange = self.stickRange * self.stickRange
|
||||
if not IsValid(ent) or (Owner:EyePos():DistToSqr(ent:GetPos()) > stickRange) or not ent:IsPlayer() then
|
||||
return
|
||||
end
|
||||
|
||||
local canArrest, message = hook.Call("canArrest", DarkRP.hooks, Owner, ent)
|
||||
if not canArrest then
|
||||
if message then DarkRP.notify(Owner, 1, 5, message) end
|
||||
return
|
||||
end
|
||||
|
||||
local time = hook.Call("setArrestStickTime", DarkRP.hooks, self, Owner, ent)
|
||||
ent:arrest(time, Owner)
|
||||
DarkRP.notify(ent, 0, 20, DarkRP.getPhrase("youre_arrested_by", Owner:Nick()))
|
||||
|
||||
if Owner.SteamName then
|
||||
DarkRP.log(Owner:Nick() .. " (" .. Owner:SteamID() .. ") arrested " .. ent:Nick(), Color(0, 255, 255))
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:startDarkRPCommand(usrcmd)
|
||||
local Owner = self:GetOwner()
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
if game.SinglePlayer() and CLIENT then return end
|
||||
if usrcmd:KeyDown(IN_ATTACK2) then
|
||||
if not self.Switched and Owner:HasWeapon("unarrest_stick") then
|
||||
usrcmd:SelectWeapon(Owner:GetWeapon("unarrest_stick"))
|
||||
end
|
||||
else
|
||||
self.Switched = false
|
||||
end
|
||||
end
|
||||
319
gamemodes/darkrp/entities/weapons/door_ram/shared.lua
Normal file
319
gamemodes/darkrp/entities/weapons/door_ram/shared.lua
Normal file
@@ -0,0 +1,319 @@
|
||||
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
|
||||
DEFINE_BASECLASS("weapon_cs_base2")
|
||||
|
||||
SWEP.PrintName = "Battering Ram"
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Instructions = "Left click to break open doors/unfreeze props or get people out of their vehicles\nRight click to raise"
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.IsDarkRPDoorRam = true
|
||||
|
||||
SWEP.IconLetter = ""
|
||||
|
||||
SWEP.ViewModelFOV = 62
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.ViewModel = Model("models/weapons/c_rpg.mdl")
|
||||
SWEP.WorldModel = Model("models/weapons/w_rocket_launcher.mdl")
|
||||
SWEP.AnimPrefix = "rpg"
|
||||
|
||||
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 = 0 -- Default number of bullets in a clip
|
||||
SWEP.Secondary.Automatic = false -- Automatic/Semi Auto
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:Initialize()
|
||||
Desc: Called when the weapon is first loaded
|
||||
---------------------------------------------------------]]
|
||||
function SWEP:Initialize()
|
||||
if CLIENT then self.LastIron = CurTime() end
|
||||
self:SetHoldType("normal")
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
self:SetIronsights(false)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check whether an object of this player can be rammed
|
||||
local function canRam(ply)
|
||||
return IsValid(ply) and (ply.warranted == true or ply:isWanted() or ply:isArrested())
|
||||
end
|
||||
|
||||
-- Ram action when ramming a door
|
||||
local function ramDoor(ply, trace, ent)
|
||||
if ply:EyePos():DistToSqr(trace.HitPos) > 2025 or (not GAMEMODE.Config.canforcedooropen and ent:getKeysNonOwnable()) then return false end
|
||||
|
||||
local allowed = false
|
||||
|
||||
-- if we need a warrant to get in
|
||||
if GAMEMODE.Config.doorwarrants and ent:isKeysOwned() and not ent:isKeysOwnedBy(ply) then
|
||||
-- if anyone who owns this door has a warrant for their arrest
|
||||
-- allow the police to smash the door in
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if ent:isKeysOwnedBy(v) and canRam(v) then
|
||||
allowed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
-- door warrants not needed, allow warrantless entry
|
||||
allowed = true
|
||||
end
|
||||
|
||||
-- Be able to open the door if any member of the door group is warranted
|
||||
local keysDoorGroup = ent:getKeysDoorGroup()
|
||||
if GAMEMODE.Config.doorwarrants and keysDoorGroup then
|
||||
local teamDoors = RPExtraTeamDoors[keysDoorGroup]
|
||||
if teamDoors then
|
||||
allowed = false
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if table.HasValue(teamDoors, v:Team()) and canRam(v) then
|
||||
allowed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if CLIENT then return allowed end
|
||||
|
||||
-- Do we have a warrant for this player?
|
||||
if not allowed then
|
||||
DarkRP.notify(ply, 1, 5, DarkRP.getPhrase("warrant_required"))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
ent:keysUnLock()
|
||||
ent:Fire("open", "", .6)
|
||||
ent:Fire("setanimation", "open", .6)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Ram action when ramming a vehicle
|
||||
local function ramVehicle(ply, trace, ent)
|
||||
if ply:EyePos():DistToSqr(trace.HitPos) > 10000 then return false end
|
||||
|
||||
if CLIENT then return false end -- Ideally this would return true after ent:GetDriver() check
|
||||
|
||||
local driver = ent:GetDriver()
|
||||
if not IsValid(driver) or not driver.ExitVehicle then return false end
|
||||
|
||||
driver:ExitVehicle()
|
||||
ent:keysLock()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Ram action when ramming a fading door
|
||||
local function ramFadingDoor(ply, trace, ent)
|
||||
if ply:EyePos():DistToSqr(trace.HitPos) > 10000 then return false end
|
||||
|
||||
local Owner = ent:CPPIGetOwner()
|
||||
|
||||
if CLIENT then return canRam(Owner) end
|
||||
|
||||
if not canRam(Owner) then
|
||||
DarkRP.notify(ply, 1, 5, DarkRP.getPhrase("warrant_required"))
|
||||
return false
|
||||
end
|
||||
|
||||
if not ent.fadeActive then
|
||||
ent:fadeActivate()
|
||||
timer.Simple(5, function() if IsValid(ent) and ent.fadeActive then ent:fadeDeactivate() end end)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Ram action when ramming a frozen prop
|
||||
local function ramProp(ply, trace, ent)
|
||||
if ply:EyePos():DistToSqr(trace.HitPos) > 10000 then return false end
|
||||
if ent:GetClass() ~= "prop_physics" then return false end
|
||||
|
||||
local Owner = ent:CPPIGetOwner()
|
||||
|
||||
if CLIENT then return canRam(Owner) end
|
||||
|
||||
if not canRam(Owner) then
|
||||
DarkRP.notify(ply, 1, 5, DarkRP.getPhrase(GAMEMODE.Config.copscanunweld and "warrant_required_unweld" or "warrant_required_unfreeze"))
|
||||
return false
|
||||
end
|
||||
|
||||
if GAMEMODE.Config.copscanunweld then
|
||||
constraint.RemoveConstraints(ent, "Weld")
|
||||
end
|
||||
|
||||
if GAMEMODE.Config.copscanunfreeze then
|
||||
ent:GetPhysicsObject():EnableMotion(true)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Decides the behaviour of the ram function for the given entity
|
||||
local function getRamFunction(ply, trace)
|
||||
local ent = trace.Entity
|
||||
|
||||
if not IsValid(ent) then return fp{fn.Id, false} end
|
||||
|
||||
local override = hook.Call("canDoorRam", nil, ply, trace, ent)
|
||||
|
||||
return
|
||||
override ~= nil and fp{fn.Id, override} or
|
||||
ent:isDoor() and fp{ramDoor, ply, trace, ent} or
|
||||
ent:IsVehicle() and fp{ramVehicle, ply, trace, ent} or
|
||||
ent.fadeActivate and fp{ramFadingDoor, ply, trace, ent} or
|
||||
ent:GetPhysicsObject():IsValid() and not ent:GetPhysicsObject():IsMoveable()
|
||||
and fp{ramProp, ply, trace, ent} or
|
||||
fp{fn.Id, false} -- no ramming was performed
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:PrimaryAttack()
|
||||
Desc: +attack1 has been pressed
|
||||
---------------------------------------------------------]]
|
||||
function SWEP:PrimaryAttack()
|
||||
if not self:GetIronsights() then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
self:SetNextPrimaryFire(CurTime() + 0.1)
|
||||
|
||||
Owner:LagCompensation(true)
|
||||
local trace = Owner:GetEyeTrace()
|
||||
Owner:LagCompensation(false)
|
||||
|
||||
local hasRammed = getRamFunction(Owner, trace)()
|
||||
|
||||
if SERVER then
|
||||
hook.Call("onDoorRamUsed", GAMEMODE, hasRammed, Owner, trace)
|
||||
end
|
||||
|
||||
if not hasRammed then return end
|
||||
|
||||
self:SetNextPrimaryFire(CurTime() + 2.5)
|
||||
|
||||
self:SetTotalUsedMagCount(self:GetTotalUsedMagCount() + 1)
|
||||
|
||||
Owner:SetAnimation(PLAYER_ATTACK1)
|
||||
Owner:EmitSound(self.Sound)
|
||||
Owner:ViewPunch(Angle(-10, math.Round(util.SharedRandom("DarkRP_DoorRam" .. self:EntIndex() .. "_" .. self:GetTotalUsedMagCount(), -5, 5)), 0))
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
if CLIENT then self.LastIron = CurTime() end
|
||||
self:SetNextSecondaryFire(CurTime() + 0.30)
|
||||
self:SetIronsights(not self:GetIronsights())
|
||||
if self:GetIronsights() then
|
||||
self:SetHoldType("rpg")
|
||||
else
|
||||
self:SetHoldType("normal")
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:GetViewModelPosition(pos, ang)
|
||||
local Mul = 1
|
||||
|
||||
if self.LastIron > CurTime() - 0.25 then
|
||||
Mul = math.Clamp((CurTime() - self.LastIron) / 0.25, 0, 1)
|
||||
end
|
||||
|
||||
if self:GetIronsights() then
|
||||
Mul = 1-Mul
|
||||
end
|
||||
|
||||
ang:RotateAroundAxis(ang:Right(), - 15 * Mul)
|
||||
return pos,ang
|
||||
end
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canDoorRam",
|
||||
description = "Called when a player attempts to ram something. Use this to override ram behaviour or to disallow ramming.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player using the door ram.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "trace",
|
||||
description = "The trace containing information about the hit position and ram entity.",
|
||||
type = "table"
|
||||
},
|
||||
{
|
||||
name = "ent",
|
||||
description = "Short for the entity that is about to be hit by the door ram.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "override",
|
||||
description = "Return true to override behaviour, false to disallow ramming and nil (or no value) to defer the decision.",
|
||||
type = "boolean"
|
||||
}
|
||||
},
|
||||
realm = "Shared"
|
||||
}
|
||||
|
||||
if SERVER then
|
||||
DarkRP.hookStub{
|
||||
name = "onDoorRamUsed",
|
||||
description = "Called when the door ram has been used.",
|
||||
parameters = {
|
||||
{
|
||||
name = "success",
|
||||
description = "Whether the door ram has been successful in ramming.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player that used the door ram.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "trace",
|
||||
description = "The trace containing information about the hit position and ram entity.",
|
||||
type = "table"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
hook.Add("SetupMove", "DarkRP_DoorRamJump", function(ply, mv)
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if not wep:IsValid() or wep:GetClass() ~= "door_ram" or not wep.GetIronsights or not wep:GetIronsights() then return end
|
||||
|
||||
mv:SetButtons(bit.band(mv:GetButtons(), bit.bnot(IN_JUMP)))
|
||||
end)
|
||||
@@ -0,0 +1,54 @@
|
||||
TOOL.Category = "Falco Prop Protection"
|
||||
TOOL.Name = "Share props"
|
||||
TOOL.Command = nil
|
||||
TOOL.ConfigName = ""
|
||||
|
||||
function TOOL:RightClick(trace)
|
||||
local ent = trace.Entity
|
||||
if not IsValid(ent) or CLIENT then return true end
|
||||
|
||||
ent.SharePhysgun1 = nil
|
||||
ent.ShareGravgun1 = nil
|
||||
ent.SharePlayerUse1 = nil
|
||||
ent.ShareEntityDamage1 = nil
|
||||
ent.ShareToolgun1 = nil
|
||||
|
||||
ent.AllowedPlayers = nil
|
||||
return true
|
||||
end
|
||||
|
||||
function TOOL:LeftClick(trace)
|
||||
local ent = trace.Entity
|
||||
if not IsValid(ent) or CLIENT then return true end
|
||||
|
||||
local ply = self:GetOwner()
|
||||
|
||||
local Physgun = ent.SharePhysgun1 or false
|
||||
local GravGun = ent.ShareGravgun1 or false
|
||||
local PlayerUse = ent.SharePlayerUse1 or false
|
||||
local Damage = ent.ShareEntityDamage1 or false
|
||||
local Toolgun = ent.ShareToolgun1 or false
|
||||
|
||||
-- This big usermessage will be too big if you select 63 players, since that will not happen I can't be arsed to solve it
|
||||
umsg.Start("FPP_ShareSettings", ply)
|
||||
umsg.Entity(ent)
|
||||
umsg.Bool(Physgun)
|
||||
umsg.Bool(GravGun)
|
||||
umsg.Bool(PlayerUse)
|
||||
umsg.Bool(Damage)
|
||||
umsg.Bool(Toolgun)
|
||||
if ent.AllowedPlayers then
|
||||
umsg.Long(#ent.AllowedPlayers)
|
||||
for k,v in pairs(ent.AllowedPlayers) do
|
||||
umsg.Entity(v)
|
||||
end
|
||||
end
|
||||
umsg.End()
|
||||
return true
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
language.Add("Tool.shareprops.name", "Share tool")
|
||||
language.Add("Tool.shareprops.desc", "Change sharing settings per prop")
|
||||
language.Add("Tool.shareprops.0", "Left click: shares a prop. Right click unshares a prop")
|
||||
end
|
||||
210
gamemodes/darkrp/entities/weapons/keys/cl_menu.lua
Normal file
210
gamemodes/darkrp/entities/weapons/keys/cl_menu.lua
Normal file
@@ -0,0 +1,210 @@
|
||||
local function AddButtonToFrame(Frame)
|
||||
Frame:SetTall(Frame:GetTall() + 110)
|
||||
|
||||
local button = vgui.Create("DButton", Frame)
|
||||
button:SetPos(10, Frame:GetTall() - 110)
|
||||
button:SetSize(180, 100)
|
||||
|
||||
Frame.buttonCount = (Frame.buttonCount or 0) + 1
|
||||
Frame.lastButton = button
|
||||
return button
|
||||
end
|
||||
|
||||
DarkRP.stub{
|
||||
name = "openKeysMenu",
|
||||
description = "Open the keys/F2 menu.",
|
||||
parameters = {},
|
||||
realm = "Client",
|
||||
returns = {},
|
||||
metatable = DarkRP
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "onKeysMenuOpened",
|
||||
description = "Called when the keys menu is opened.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ent",
|
||||
description = "The door entity.",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "Frame",
|
||||
description = "The keys menu frame.",
|
||||
type = "Panel"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
realm = "Client"
|
||||
}
|
||||
|
||||
local KeyFrameVisible = false
|
||||
|
||||
local function openMenu(setDoorOwnerAccess, doorSettingsAccess)
|
||||
if KeyFrameVisible then return end
|
||||
local trace = LocalPlayer():GetEyeTrace()
|
||||
local ent = trace.Entity
|
||||
-- Don't open the menu if the entity is not ownable, the entity is too far away or the door settings are not loaded yet
|
||||
if not IsValid(ent) or not ent:isKeysOwnable() or trace.HitPos:DistToSqr(LocalPlayer():EyePos()) > 40000 then return end
|
||||
|
||||
KeyFrameVisible = true
|
||||
local Frame = vgui.Create("DFrame")
|
||||
Frame:SetSize(200, 30) -- Base size
|
||||
Frame.btnMaxim:SetVisible(false)
|
||||
Frame.btnMinim:SetVisible(false)
|
||||
Frame:SetVisible(true)
|
||||
Frame:MakePopup()
|
||||
Frame:ParentToHUD()
|
||||
|
||||
function Frame:Think()
|
||||
local tr = LocalPlayer():GetEyeTrace()
|
||||
local LAEnt = tr.Entity
|
||||
if not IsValid(LAEnt) or not LAEnt:isKeysOwnable() or tr.HitPos:DistToSqr(LocalPlayer():EyePos()) > 40000 then
|
||||
self:Close()
|
||||
end
|
||||
if not self.Dragging then return end
|
||||
local x = gui.MouseX() - self.Dragging[1]
|
||||
local y = gui.MouseY() - self.Dragging[2]
|
||||
x = math.Clamp(x, 0, ScrW() - self:GetWide())
|
||||
y = math.Clamp(y, 0, ScrH() - self:GetTall())
|
||||
self:SetPos(x, y)
|
||||
end
|
||||
|
||||
local entType = DarkRP.getPhrase(ent:IsVehicle() and "vehicle" or "door")
|
||||
Frame:SetTitle(DarkRP.getPhrase("x_options", entType:gsub("^%a", string.upper)))
|
||||
|
||||
function Frame:Close()
|
||||
KeyFrameVisible = false
|
||||
self:SetVisible(false)
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
-- All the buttons
|
||||
|
||||
if ent:isKeysOwnedBy(LocalPlayer()) then
|
||||
local Owndoor = AddButtonToFrame(Frame)
|
||||
Owndoor:SetText(DarkRP.getPhrase("sell_x", entType))
|
||||
Owndoor.DoClick = function() RunConsoleCommand("darkrp", "toggleown") Frame:Close() end
|
||||
|
||||
local AddOwner = AddButtonToFrame(Frame)
|
||||
AddOwner:SetText(DarkRP.getPhrase("add_owner"))
|
||||
AddOwner.DoClick = function()
|
||||
local menu = DermaMenu()
|
||||
menu.found = false
|
||||
for _, v in ipairs(DarkRP.nickSortedPlayers()) do
|
||||
if not ent:isKeysOwnedBy(v) and not ent:isKeysAllowedToOwn(v) then
|
||||
local steamID = v:SteamID()
|
||||
menu.found = true
|
||||
menu:AddOption(v:Nick(), function() RunConsoleCommand("darkrp", "ao", steamID) end)
|
||||
end
|
||||
end
|
||||
if not menu.found then
|
||||
menu:AddOption(DarkRP.getPhrase("noone_available"), function() end)
|
||||
end
|
||||
menu:Open()
|
||||
end
|
||||
|
||||
local RemoveOwner = AddButtonToFrame(Frame)
|
||||
RemoveOwner:SetText(DarkRP.getPhrase("remove_owner"))
|
||||
RemoveOwner.DoClick = function()
|
||||
local menu = DermaMenu()
|
||||
for _, v in ipairs(DarkRP.nickSortedPlayers()) do
|
||||
if (ent:isKeysOwnedBy(v) and not ent:isMasterOwner(v)) or ent:isKeysAllowedToOwn(v) then
|
||||
local steamID = v:SteamID()
|
||||
menu.found = true
|
||||
menu:AddOption(v:Nick(), function() RunConsoleCommand("darkrp", "ro", steamID) end)
|
||||
end
|
||||
end
|
||||
if not menu.found then
|
||||
menu:AddOption(DarkRP.getPhrase("noone_available"), function() end)
|
||||
end
|
||||
menu:Open()
|
||||
end
|
||||
if not ent:isMasterOwner(LocalPlayer()) then
|
||||
RemoveOwner:SetDisabled(true)
|
||||
end
|
||||
end
|
||||
|
||||
if doorSettingsAccess then
|
||||
local DisableOwnage = AddButtonToFrame(Frame)
|
||||
DisableOwnage:SetText(DarkRP.getPhrase(ent:getKeysNonOwnable() and "allow_ownership" or "disallow_ownership"))
|
||||
DisableOwnage.DoClick = function() Frame:Close() RunConsoleCommand("darkrp", "toggleownable") end
|
||||
end
|
||||
|
||||
if doorSettingsAccess and (ent:isKeysOwned() or ent:getKeysNonOwnable() or ent:getKeysDoorGroup() or hasTeams) or ent:isKeysOwnedBy(LocalPlayer()) then
|
||||
local DoorTitle = AddButtonToFrame(Frame)
|
||||
DoorTitle:SetText(DarkRP.getPhrase("set_x_title", entType))
|
||||
DoorTitle.DoClick = function()
|
||||
Derma_StringRequest(DarkRP.getPhrase("set_x_title", entType), DarkRP.getPhrase("set_x_title_long", entType), "", function(text)
|
||||
RunConsoleCommand("darkrp", "title", text)
|
||||
if IsValid(Frame) then
|
||||
Frame:Close()
|
||||
end
|
||||
end,
|
||||
function() end, DarkRP.getPhrase("ok"), DarkRP.getPhrase("cancel"))
|
||||
end
|
||||
end
|
||||
|
||||
if not ent:isKeysOwned() and not ent:getKeysNonOwnable() and not ent:getKeysDoorGroup() and not ent:getKeysDoorTeams() or not ent:isKeysOwnedBy(LocalPlayer()) and ent:isKeysAllowedToOwn(LocalPlayer()) then
|
||||
local Owndoor = AddButtonToFrame(Frame)
|
||||
Owndoor:SetText(DarkRP.getPhrase("buy_x", entType))
|
||||
Owndoor.DoClick = function() RunConsoleCommand("darkrp", "toggleown") Frame:Close() end
|
||||
end
|
||||
|
||||
if doorSettingsAccess then
|
||||
local EditDoorGroups = AddButtonToFrame(Frame)
|
||||
EditDoorGroups:SetText(DarkRP.getPhrase("edit_door_group"))
|
||||
EditDoorGroups.DoClick = function()
|
||||
local menu = DermaMenu()
|
||||
local groups = menu:AddSubMenu(DarkRP.getPhrase("door_groups"))
|
||||
local teams = menu:AddSubMenu(DarkRP.getPhrase("jobs"))
|
||||
local add = teams:AddSubMenu(DarkRP.getPhrase("add"))
|
||||
local remove = teams:AddSubMenu(DarkRP.getPhrase("remove"))
|
||||
|
||||
menu:AddOption(DarkRP.getPhrase("none"), function()
|
||||
RunConsoleCommand("darkrp", "togglegroupownable")
|
||||
if IsValid(Frame) then Frame:Close() end
|
||||
end)
|
||||
|
||||
for k in pairs(RPExtraTeamDoors) do
|
||||
groups:AddOption(k, function()
|
||||
RunConsoleCommand("darkrp", "togglegroupownable", k)
|
||||
if IsValid(Frame) then Frame:Close() end
|
||||
end)
|
||||
end
|
||||
|
||||
local doorTeams = ent:getKeysDoorTeams()
|
||||
for k, v in pairs(RPExtraTeams) do
|
||||
local which = (not doorTeams or not doorTeams[k]) and add or remove
|
||||
which:AddOption(v.name, function()
|
||||
RunConsoleCommand("darkrp", "toggleteamownable", k)
|
||||
if IsValid(Frame) then Frame:Close() end
|
||||
end)
|
||||
end
|
||||
|
||||
menu:Open()
|
||||
end
|
||||
end
|
||||
|
||||
if Frame.buttonCount == 1 then
|
||||
Frame.lastButton:DoClick()
|
||||
elseif Frame.buttonCount == 0 or not Frame.buttonCount then
|
||||
Frame:Close()
|
||||
KeyFrameVisible = true
|
||||
timer.Simple(0.3, function() KeyFrameVisible = false end)
|
||||
end
|
||||
|
||||
|
||||
hook.Call("onKeysMenuOpened", nil, ent, Frame)
|
||||
|
||||
Frame:Center()
|
||||
Frame:SetSkin(GAMEMODE.Config.DarkRPSkin)
|
||||
end
|
||||
|
||||
function DarkRP.openKeysMenu(um)
|
||||
CAMI.PlayerHasAccess(LocalPlayer(), "DarkRP_SetDoorOwner", function(setDoorOwnerAccess)
|
||||
CAMI.PlayerHasAccess(LocalPlayer(), "DarkRP_ChangeDoorSettings", fp{openMenu, setDoorOwnerAccess})
|
||||
end)
|
||||
end
|
||||
usermessage.Hook("KeysMenu", DarkRP.openKeysMenu)
|
||||
163
gamemodes/darkrp/entities/weapons/keys/shared.lua
Normal file
163
gamemodes/darkrp/entities/weapons/keys/shared.lua
Normal file
@@ -0,0 +1,163 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile("cl_menu.lua")
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 1
|
||||
SWEP.DrawAmmo = false
|
||||
SWEP.DrawCrosshair = false
|
||||
|
||||
include("cl_menu.lua")
|
||||
end
|
||||
|
||||
SWEP.PrintName = "Keys"
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Instructions = "Left click to lock\nRight click to unlock\nReload for door settings or animation menu"
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.IsDarkRPKeys = true
|
||||
|
||||
SWEP.WorldModel = ""
|
||||
|
||||
SWEP.ViewModelFOV = 62
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.AnimPrefix = "rpg"
|
||||
|
||||
SWEP.UseHands = true
|
||||
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
SWEP.Sound = "doors/door_latch3.wav"
|
||||
|
||||
SWEP.Primary.Delay = 0.3
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = 0
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = ""
|
||||
|
||||
SWEP.Secondary.Delay = 0.3
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = 0
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType("normal")
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
if CLIENT or not IsValid(self:GetOwner()) then return true end
|
||||
self:GetOwner():DrawWorldModel(false)
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:PreDrawViewModel()
|
||||
return true
|
||||
end
|
||||
|
||||
local function lookingAtLockable(ply, ent, hitpos)
|
||||
local eyepos = ply:EyePos()
|
||||
return IsValid(ent)
|
||||
and ent:isKeysOwnable()
|
||||
and (
|
||||
ent:isDoor() and eyepos:DistToSqr(hitpos) < 2000
|
||||
or
|
||||
ent:IsVehicle() and eyepos:DistToSqr(hitpos) < 4000
|
||||
)
|
||||
end
|
||||
|
||||
local function lockUnlockAnimation(ply, snd)
|
||||
ply:EmitSound("npc/metropolice/gear" .. math.random(1, 6) .. ".wav")
|
||||
timer.Simple(0.9, function() if IsValid(ply) then ply:EmitSound(snd) end end)
|
||||
|
||||
umsg.Start("anim_keys")
|
||||
umsg.Entity(ply)
|
||||
umsg.String("usekeys")
|
||||
umsg.End()
|
||||
|
||||
ply:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_GMOD_GESTURE_ITEM_PLACE, true)
|
||||
end
|
||||
|
||||
local function doKnock(ply, sound)
|
||||
ply:EmitSound(sound, 100, math.random(90, 110))
|
||||
|
||||
umsg.Start("anim_keys")
|
||||
umsg.Entity(ply)
|
||||
umsg.String("knocking")
|
||||
umsg.End()
|
||||
|
||||
ply:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_HL2MP_GESTURE_RANGE_ATTACK_FIST, true)
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local trace = Owner:GetEyeTrace()
|
||||
|
||||
local ent = trace.Entity
|
||||
|
||||
if not lookingAtLockable(Owner, ent, trace.HitPos) then return end
|
||||
|
||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
||||
|
||||
if CLIENT then return end
|
||||
|
||||
if Owner:canKeysLock(ent) then
|
||||
ent:keysLock() -- Lock the door immediately so it won't annoy people
|
||||
lockUnlockAnimation(Owner, self.Sound)
|
||||
elseif ent:IsVehicle() then
|
||||
DarkRP.notify(Owner, 1, 3, DarkRP.getPhrase("do_not_own_ent"))
|
||||
else
|
||||
doKnock(Owner, "physics/wood/wood_crate_impact_hard2.wav")
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local trace = Owner:GetEyeTrace()
|
||||
|
||||
local ent = trace.Entity
|
||||
|
||||
if not lookingAtLockable(Owner, ent, trace.HitPos) then return end
|
||||
|
||||
self:SetNextSecondaryFire(CurTime() + self.Secondary.Delay)
|
||||
|
||||
if CLIENT then return end
|
||||
|
||||
if Owner:canKeysUnlock(ent) then
|
||||
ent:keysUnLock() -- Unlock the door immediately so it won't annoy people
|
||||
lockUnlockAnimation(Owner, self.Sound)
|
||||
elseif ent:IsVehicle() then
|
||||
DarkRP.notify(Owner, 1, 3, DarkRP.getPhrase("do_not_own_ent"))
|
||||
else
|
||||
doKnock(Owner, "physics/wood/wood_crate_impact_hard3.wav")
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
local trace = self:GetOwner():GetEyeTrace()
|
||||
|
||||
local ent = trace.Entity
|
||||
|
||||
if not IsValid(ent) or ((not ent:isDoor() and not ent:IsVehicle()) or self:GetOwner():EyePos():DistToSqr(trace.HitPos) > 40000) then
|
||||
if CLIENT and not DarkRP.disabledDefaults["modules"]["animations"] then RunConsoleCommand("_DarkRP_AnimationMenu") end
|
||||
return
|
||||
end
|
||||
if SERVER then
|
||||
umsg.Start("KeysMenu", self:GetOwner())
|
||||
umsg.End()
|
||||
end
|
||||
end
|
||||
309
gamemodes/darkrp/entities/weapons/lockpick/shared.lua
Normal file
309
gamemodes/darkrp/entities/weapons/lockpick/shared.lua
Normal file
@@ -0,0 +1,309 @@
|
||||
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"
|
||||
}
|
||||
17
gamemodes/darkrp/entities/weapons/ls_sniper/cl_init.lua
Normal file
17
gamemodes/darkrp/entities/weapons/ls_sniper/cl_init.lua
Normal file
@@ -0,0 +1,17 @@
|
||||
include("shared.lua")
|
||||
local deltas = {-44, -34, -24, -14, 44, 34, 24, 14}
|
||||
function SWEP:DrawHUD()
|
||||
if self:GetScopeLevel() < 2 then return end
|
||||
|
||||
--Width hairs
|
||||
draw.RoundedBox(1, ScrW() / 2 - 54, ScrH() / 2, 50, 1, color_black)
|
||||
draw.RoundedBox(1, ScrW() / 2 + 4, ScrH() / 2, 50, 1, color_black)
|
||||
|
||||
draw.RoundedBox(1, ScrW() / 2, ScrH() / 2 - 54, 1, 50, color_black)
|
||||
draw.RoundedBox(1, ScrW() / 2, ScrH() / 2 + 4, 1, 50, color_black)
|
||||
|
||||
for _, v in ipairs(deltas) do
|
||||
draw.RoundedBox(1, ScrW() / 2 + v, ScrH() / 2 - 5, 1, 11, color_black)
|
||||
draw.RoundedBox(1, ScrW() / 2 - 5, ScrH() / 2 + v, 11, 1, color_black)
|
||||
end
|
||||
end
|
||||
84
gamemodes/darkrp/entities/weapons/ls_sniper/shared.lua
Normal file
84
gamemodes/darkrp/entities/weapons/ls_sniper/shared.lua
Normal file
@@ -0,0 +1,84 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.IconLetter = "n"
|
||||
|
||||
killicon.AddFont("ls_sniper", "CSKillIcons", SWEP.IconLetter, Color(200, 200, 200, 255))
|
||||
end
|
||||
|
||||
DEFINE_BASECLASS("weapon_cs_base2")
|
||||
|
||||
SWEP.PrintName = "Silenced Sniper"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_snip_g3sg1.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_snip_g3sg1.mdl"
|
||||
|
||||
SWEP.Weight = 3
|
||||
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.LoweredHoldType = "passive"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_M4A1.Silenced")
|
||||
SWEP.Primary.Damage = 100
|
||||
SWEP.Primary.Recoil = 0.03
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.0001 - .05
|
||||
SWEP.Primary.ClipSize = 25
|
||||
SWEP.Primary.Delay = 0.7
|
||||
SWEP.Primary.DefaultClip = 75
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "smg1"
|
||||
SWEP.IronSightsPos = Vector(0, 0, 0) -- this is just to make it disappear so it doesn't show up whilst scoped
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
BaseClass.SetupDataTables(self)
|
||||
-- Int 0 = BurstBulletNum
|
||||
-- Int 1 = TotalUsedMagCount
|
||||
self:NetworkVar("Int", 2, "ScopeLevel")
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
self:GetOwner():SetFOV(0, 0)
|
||||
|
||||
self:SetScopeLevel(0)
|
||||
|
||||
return BaseClass.Deploy(self)
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
self:GetOwner():SetFOV(0, 0)
|
||||
|
||||
self:SetScopeLevel(0)
|
||||
|
||||
return BaseClass.Holster(self)
|
||||
end
|
||||
|
||||
local zoomFOV = {0, 0, 25, 5}
|
||||
function SWEP:SecondaryAttack()
|
||||
if not self.IronSightsPos then return end
|
||||
|
||||
self:SetNextSecondaryFire(CurTime() + 0.1)
|
||||
|
||||
self:SetScopeLevel((self:GetScopeLevel() + 1) % 4)
|
||||
self:SetIronsights(self:GetScopeLevel() > 0)
|
||||
|
||||
self:GetOwner():SetFOV(zoomFOV[self:GetScopeLevel() + 1], 0)
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
self:GetOwner():SetFOV(0, 0)
|
||||
|
||||
self:SetScopeLevel(0)
|
||||
|
||||
return BaseClass.Reload(self)
|
||||
end
|
||||
81
gamemodes/darkrp/entities/weapons/med_kit/shared.lua
Normal file
81
gamemodes/darkrp/entities/weapons/med_kit/shared.lua
Normal file
@@ -0,0 +1,81 @@
|
||||
if SERVER then
|
||||
AddCSLuaFile("shared.lua")
|
||||
end
|
||||
|
||||
SWEP.PrintName = "Medic Kit"
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 4
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.Description = "Heals the wounded."
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.Instructions = "Left click to heal someone\nRight click to heal yourself"
|
||||
SWEP.IsDarkRPMedKit = true
|
||||
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/c_medkit.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_medkit.mdl"
|
||||
SWEP.UseHands = true
|
||||
|
||||
SWEP.Primary.Recoil = 0
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = 1
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Delay = 0.1
|
||||
SWEP.Primary.Ammo = "none"
|
||||
|
||||
SWEP.Secondary.Recoil = 0
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = 1
|
||||
SWEP.Secondary.Automatic = true
|
||||
SWEP.Secondary.Delay = 0.3
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local found
|
||||
local lastDot = -1 -- the opposite of what you're looking at
|
||||
Owner:LagCompensation(true)
|
||||
local aimVec = Owner:GetAimVector()
|
||||
local shootPos = Owner:GetShootPos()
|
||||
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
local maxhealth = v:GetMaxHealth() or 100
|
||||
local targetShootPos = v:GetShootPos()
|
||||
if v == Owner or targetShootPos:DistToSqr(shootPos) > 7225 or v:Health() >= maxhealth or not v:Alive() then continue end
|
||||
|
||||
local direction = targetShootPos - shootPos
|
||||
direction:Normalize()
|
||||
local dot = direction:Dot(aimVec)
|
||||
|
||||
-- Looking more in the direction of this player
|
||||
if dot > lastDot then
|
||||
lastDot = dot
|
||||
found = v
|
||||
end
|
||||
end
|
||||
Owner:LagCompensation(false)
|
||||
|
||||
if found then
|
||||
found:SetHealth(found:Health() + 1)
|
||||
self:EmitSound("hl1/fvox/boop.wav", 150, math.max(found:Health() / found:GetMaxHealth() * 100, 25), 1, CHAN_AUTO)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
self:SetNextSecondaryFire(CurTime() + self.Secondary.Delay)
|
||||
local ply = self:GetOwner()
|
||||
local maxhealth = ply:GetMaxHealth() or 100
|
||||
if ply:Health() < maxhealth then
|
||||
ply:SetHealth(ply:Health() + 1)
|
||||
self:EmitSound("hl1/fvox/boop.wav", 150, math.max(ply:Health() / ply:GetMaxHealth() * 100, 25), 1, CHAN_AUTO)
|
||||
end
|
||||
end
|
||||
128
gamemodes/darkrp/entities/weapons/pocket/cl_menu.lua
Normal file
128
gamemodes/darkrp/entities/weapons/pocket/cl_menu.lua
Normal file
@@ -0,0 +1,128 @@
|
||||
local meta = FindMetaTable("Player")
|
||||
local pocket = {}
|
||||
local frame
|
||||
local reload
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Stubs
|
||||
---------------------------------------------------------------------------]]
|
||||
DarkRP.stub{
|
||||
name = "openPocketMenu",
|
||||
description = "Open the DarkRP pocket menu.",
|
||||
realm = "Client",
|
||||
parameters = {
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
metatable = DarkRP
|
||||
}
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Interface functions
|
||||
---------------------------------------------------------------------------]]
|
||||
function meta:getPocketItems()
|
||||
if self ~= LocalPlayer() then return nil end
|
||||
|
||||
return pocket
|
||||
end
|
||||
|
||||
function DarkRP.openPocketMenu()
|
||||
if IsValid(frame) and frame:IsVisible() then return end
|
||||
local wep = LocalPlayer():GetActiveWeapon()
|
||||
if not wep:IsValid() or wep:GetClass() ~= "pocket" then return end
|
||||
|
||||
if not pocket then
|
||||
pocket = {}
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if table.IsEmpty(pocket) then return end
|
||||
frame = vgui.Create("DFrame")
|
||||
|
||||
local count = GAMEMODE.Config.pocketitems or GM.Config.pocketitems
|
||||
frame:SetSize(345, 32 + 64 * math.ceil(count / 5) + 3 * math.ceil(count / 5))
|
||||
frame:SetTitle(DarkRP.getPhrase("drop_item"))
|
||||
frame.btnMaxim:SetVisible(false)
|
||||
frame.btnMinim:SetVisible(false)
|
||||
frame:SetDraggable(false)
|
||||
frame:MakePopup()
|
||||
frame:Center()
|
||||
|
||||
local Scroll = vgui.Create("DScrollPanel", frame)
|
||||
Scroll:Dock(FILL)
|
||||
|
||||
local sbar = Scroll:GetVBar()
|
||||
sbar:SetWide(3)
|
||||
frame.List = vgui.Create("DIconLayout", Scroll)
|
||||
frame.List:Dock(FILL)
|
||||
frame.List:SetSpaceY(3)
|
||||
frame.List:SetSpaceX(3)
|
||||
reload()
|
||||
frame:SetSkin(GAMEMODE.Config.DarkRPSkin)
|
||||
end
|
||||
net.Receive("DarkRP_PocketMenu", DarkRP.openPocketMenu)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
UI
|
||||
---------------------------------------------------------------------------]]
|
||||
function reload()
|
||||
if not IsValid(frame) or not frame:IsVisible() then return end
|
||||
if not pocket or next(pocket) == nil then frame:Close() return end
|
||||
|
||||
local itemCount = table.Count(pocket)
|
||||
|
||||
frame.List:Clear()
|
||||
local items = {}
|
||||
|
||||
for k, v in pairs(pocket) do
|
||||
local ListItem = frame.List:Add("DPanel")
|
||||
ListItem:SetSize(64, 64)
|
||||
|
||||
local icon = vgui.Create("SpawnIcon", ListItem)
|
||||
icon:SetModel(v.model)
|
||||
icon:SetSize(64, 64)
|
||||
icon:SetTooltip()
|
||||
icon.DoClick = function(self)
|
||||
icon:SetTooltip()
|
||||
|
||||
net.Start("DarkRP_spawnPocket")
|
||||
net.WriteFloat(k)
|
||||
net.SendToServer()
|
||||
pocket[k] = nil
|
||||
|
||||
itemCount = itemCount - 1
|
||||
|
||||
if itemCount == 0 then
|
||||
frame:Close()
|
||||
return
|
||||
end
|
||||
|
||||
fn.Map(self.Remove, items)
|
||||
items = {}
|
||||
|
||||
local wep = LocalPlayer():GetActiveWeapon()
|
||||
|
||||
wep:SetHoldType("pistol")
|
||||
timer.Simple(0.2, function()
|
||||
if wep:IsValid() then
|
||||
wep:SetHoldType("normal")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
table.insert(items, icon)
|
||||
end
|
||||
if itemCount < GAMEMODE.Config.pocketitems then
|
||||
for _ = 1, GAMEMODE.Config.pocketitems - itemCount do
|
||||
local ListItem = frame.List:Add("DPanel")
|
||||
ListItem:SetSize(64, 64)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function retrievePocket()
|
||||
pocket = net.ReadTable()
|
||||
reload()
|
||||
end
|
||||
net.Receive("DarkRP_Pocket", retrievePocket)
|
||||
146
gamemodes/darkrp/entities/weapons/pocket/shared.lua
Normal file
146
gamemodes/darkrp/entities/weapons/pocket/shared.lua
Normal file
@@ -0,0 +1,146 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile("cl_menu.lua")
|
||||
include("sv_init.lua")
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
include("cl_menu.lua")
|
||||
end
|
||||
|
||||
SWEP.PrintName = "Pocket"
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 1
|
||||
SWEP.DrawAmmo = false
|
||||
SWEP.DrawCrosshair = true
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Instructions = "Left click to pick up\nRight click to drop\nReload to open the menu"
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.IsDarkRPPocket = true
|
||||
|
||||
SWEP.IconLetter = ""
|
||||
|
||||
SWEP.ViewModelFOV = 62
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.AnimPrefix = "rpg"
|
||||
SWEP.WorldModel = ""
|
||||
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = 0
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = ""
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = 0
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType("normal")
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:DrawWorldModel() end
|
||||
|
||||
function SWEP:PreDrawViewModel(vm)
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
if not SERVER then return true end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
Owner:DrawViewModel(true)
|
||||
Owner:DrawWorldModel(true)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
self:SetNextPrimaryFire(CurTime() + 0.2)
|
||||
|
||||
if not SERVER then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local ent = Owner:GetEyeTrace().Entity
|
||||
local canPickup, message = hook.Call("canPocket", GAMEMODE, Owner, ent)
|
||||
|
||||
if not canPickup then
|
||||
if message then DarkRP.notify(Owner, 1, 4, message) end
|
||||
return
|
||||
end
|
||||
|
||||
Owner:addPocketItem(ent)
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
if not SERVER then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local maxK = 0
|
||||
|
||||
for k in pairs(Owner:getPocketItems()) do
|
||||
if k < maxK then continue end
|
||||
maxK = k
|
||||
end
|
||||
|
||||
if maxK == 0 then
|
||||
DarkRP.notify(Owner, 1, 4, DarkRP.getPhrase("pocket_no_items"))
|
||||
return
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
local canPickup, message = hook.Call("canDropPocketItem", nil, Owner, maxK, Owner.darkRPPocket[maxK])
|
||||
if canPickup == false then
|
||||
if message then DarkRP.notify(Owner, 1, 4, message) end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Owner:dropPocketItem(maxK)
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
if CLIENT then
|
||||
DarkRP.openPocketMenu()
|
||||
end
|
||||
|
||||
if SERVER and game.SinglePlayer() then
|
||||
net.Start("DarkRP_PocketMenu")
|
||||
net.Send(self:GetOwner())
|
||||
end
|
||||
end
|
||||
|
||||
local meta = FindMetaTable("Player")
|
||||
DarkRP.stub{
|
||||
name = "getPocketItems",
|
||||
description = "Get a player's pocket items.",
|
||||
parameters = {
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "items",
|
||||
description = "A table containing crucial information about the items in the pocket.",
|
||||
type = "table"
|
||||
}
|
||||
},
|
||||
metatable = meta,
|
||||
realm = "Shared"
|
||||
}
|
||||
375
gamemodes/darkrp/entities/weapons/pocket/sv_init.lua
Normal file
375
gamemodes/darkrp/entities/weapons/pocket/sv_init.lua
Normal file
@@ -0,0 +1,375 @@
|
||||
local meta = FindMetaTable("Player")
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Stubs
|
||||
---------------------------------------------------------------------------]]
|
||||
DarkRP.stub{
|
||||
name = "dropPocketItem",
|
||||
description = "Make the player drop an item from the pocket.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ent",
|
||||
description = "The entity to drop.",
|
||||
type = "Entity",
|
||||
optional = false
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
metatable = meta
|
||||
}
|
||||
|
||||
DarkRP.stub{
|
||||
name = "addPocketItem",
|
||||
description = "Add an item to the pocket of the player.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ent",
|
||||
description = "The entity to add.",
|
||||
type = "Entity",
|
||||
optional = false
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
metatable = meta
|
||||
}
|
||||
|
||||
DarkRP.stub{
|
||||
name = "removePocketItem",
|
||||
description = "Remove an item from the pocket of the player.",
|
||||
parameters = {
|
||||
{
|
||||
name = "item",
|
||||
description = "The index of the entity to remove from pocket.",
|
||||
type = "number",
|
||||
optional = false
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
metatable = meta
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canPocket",
|
||||
description = "Whether a player can pocket a certain item.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "item",
|
||||
description = "The item to be pocketed.",
|
||||
type = "Entity"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "answer",
|
||||
description = "Whether the entity can be pocketed.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "message",
|
||||
description = "The message to send to the player when the answer is false.",
|
||||
type = "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "onPocketItemAdded",
|
||||
description = "Called when an entity is added to the pocket.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The pocket holder.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "ent",
|
||||
description = "The entity.",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "serialized",
|
||||
description = "The serialized version of the pocketed entity.",
|
||||
type = "table"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
}
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canDropPocketItem",
|
||||
description = "Whether someone is allowed to drop something from their pocket.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The pocket holder.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "item",
|
||||
description = "The pocket item's index in the pocket.",
|
||||
type = "table"
|
||||
},
|
||||
{
|
||||
name = "serialized",
|
||||
description = "The pocket item.",
|
||||
type = "table"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "answer",
|
||||
description = "Whether the item can be dropped.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "message",
|
||||
description = "The message to send to the player when the answer is false.",
|
||||
type = "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "onPocketItemRemoved",
|
||||
description = "Called when an item is removed from the pocket.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The pocket holder.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "item",
|
||||
description = "The index of the pocket item.",
|
||||
type = "number"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
}
|
||||
}
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Functions
|
||||
---------------------------------------------------------------------------]]
|
||||
-- workaround: GetNetworkVars doesn't give entities because the /duplicator/ doesn't want to save entities
|
||||
local function getDTVars(ent)
|
||||
if not ent.GetNetworkVars then return nil end
|
||||
local name, value = debug.getupvalue(ent.GetNetworkVars, 1)
|
||||
if name ~= "datatable" then
|
||||
ErrorNoHalt("Warning: Datatable cannot be stored properly in pocket. Tell a developer!")
|
||||
end
|
||||
|
||||
local res = {}
|
||||
|
||||
for k,v in pairs(value) do
|
||||
res[k] = v.GetFunc(ent, v.index)
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
local function serialize(ent)
|
||||
local serialized = duplicator.CopyEntTable(ent)
|
||||
serialized.DT = getDTVars(ent)
|
||||
|
||||
-- this function is also called in duplicator.CopyEntTable, but some
|
||||
-- entities change the DT vars of a copied entity (e.g. Lexic's moneypot)
|
||||
-- That is undone with the getDTVars function call.
|
||||
-- Re-call OnEntityCopyTableFinish assuming its implementation is pure.
|
||||
if ent.OnEntityCopyTableFinish then
|
||||
ent:OnEntityCopyTableFinish(serialized)
|
||||
end
|
||||
|
||||
return serialized
|
||||
end
|
||||
|
||||
local function deserialize(ply, item)
|
||||
local ent = ents.Create(item.Class)
|
||||
duplicator.DoGeneric(ent, item)
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
duplicator.DoGenericPhysics(ent, ply, item)
|
||||
table.Merge(ent:GetTable(), item)
|
||||
|
||||
if ent:IsWeapon() and ent.Weapon ~= nil and not ent.Weapon:IsValid() then ent.Weapon = ent end
|
||||
if ent.Entity ~= nil and not ent.Entity:IsValid() then ent.Entity = ent end
|
||||
|
||||
local trace = {}
|
||||
trace.start = ply:EyePos()
|
||||
trace.endpos = trace.start + ply:GetAimVector() * 85
|
||||
trace.filter = ply
|
||||
|
||||
local tr = util.TraceLine(trace)
|
||||
|
||||
ent:SetPos(tr.HitPos)
|
||||
|
||||
DarkRP.placeEntity(ent, tr, ply)
|
||||
|
||||
local phys = ent:GetPhysicsObject()
|
||||
timer.Simple(0, function() if phys:IsValid() then phys:Wake() end end)
|
||||
|
||||
if ent.OnDuplicated then
|
||||
ent:OnDuplicated(item)
|
||||
end
|
||||
|
||||
if ent.PostEntityPaste then
|
||||
ent:PostEntityPaste(ply, ent, {ent})
|
||||
end
|
||||
|
||||
return ent
|
||||
end
|
||||
|
||||
local function dropAllPocketItems(ply)
|
||||
for k in pairs(ply.darkRPPocket or {}) do
|
||||
ply:dropPocketItem(k)
|
||||
end
|
||||
end
|
||||
|
||||
util.AddNetworkString("DarkRP_Pocket")
|
||||
local function sendPocketItems(ply)
|
||||
net.Start("DarkRP_Pocket")
|
||||
net.WriteTable(ply:getPocketItems())
|
||||
net.Send(ply)
|
||||
end
|
||||
|
||||
util.AddNetworkString("DarkRP_PocketMenu")
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Interface functions
|
||||
---------------------------------------------------------------------------]]
|
||||
function meta:addPocketItem(ent)
|
||||
if not IsValid(ent) then DarkRP.error("Entity not valid", 2) end
|
||||
if ent.USED then return end
|
||||
|
||||
-- This item cannot be used until it has been removed
|
||||
ent.USED = true
|
||||
|
||||
local serialized = serialize(ent)
|
||||
|
||||
hook.Call("onPocketItemAdded", nil, self, ent, serialized)
|
||||
|
||||
ent.IsPocketing = true
|
||||
ent:Remove()
|
||||
|
||||
self.darkRPPocket = self.darkRPPocket or {}
|
||||
|
||||
local id = table.insert(self.darkRPPocket, serialized)
|
||||
sendPocketItems(self)
|
||||
return id
|
||||
end
|
||||
|
||||
function meta:removePocketItem(item)
|
||||
if not self.darkRPPocket or not self.darkRPPocket[item] then DarkRP.error("Player does not contain " .. item .. " in their pocket.", 2) end
|
||||
|
||||
hook.Call("onPocketItemRemoved", nil, self, item)
|
||||
|
||||
self.darkRPPocket[item] = nil
|
||||
sendPocketItems(self)
|
||||
end
|
||||
|
||||
function meta:dropPocketItem(item)
|
||||
if not self.darkRPPocket or not self.darkRPPocket[item] then DarkRP.error("Player does not contain " .. item .. " in their pocket.", 2) end
|
||||
|
||||
local id = self.darkRPPocket[item]
|
||||
local ent = deserialize(self, id)
|
||||
|
||||
-- reset USED status
|
||||
ent.USED = nil
|
||||
|
||||
hook.Call("onPocketItemDropped", nil, self, ent, item, id)
|
||||
|
||||
self:removePocketItem(item)
|
||||
|
||||
return ent
|
||||
end
|
||||
|
||||
-- serverside implementation
|
||||
function meta:getPocketItems()
|
||||
self.darkRPPocket = self.darkRPPocket or {}
|
||||
|
||||
local res = {}
|
||||
for k, v in pairs(self.darkRPPocket) do
|
||||
res[k] = {
|
||||
model = v.Model,
|
||||
class = v.Class
|
||||
}
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Commands
|
||||
---------------------------------------------------------------------------]]
|
||||
util.AddNetworkString("DarkRP_spawnPocket")
|
||||
net.Receive("DarkRP_spawnPocket", function(len, ply)
|
||||
local item = net.ReadFloat()
|
||||
if not ply.darkRPPocket or not ply.darkRPPocket[item] then return end
|
||||
local canPickup, message = hook.Call("canDropPocketItem", nil, ply, item, ply.darkRPPocket[item])
|
||||
if canPickup == false then
|
||||
if message then DarkRP.notify(ply, 1, 4, message) end
|
||||
sendPocketItems(ply)
|
||||
return
|
||||
end
|
||||
ply:dropPocketItem(item)
|
||||
end)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Hooks
|
||||
---------------------------------------------------------------------------]]
|
||||
function GAMEMODE:canPocket(ply, item)
|
||||
if not IsValid(item) then return false end
|
||||
local class = item:GetClass()
|
||||
|
||||
if item.Removed then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
if not item:CPPICanPickup(ply) then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
if item.jailWall then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
if GAMEMODE.Config.PocketBlacklist[class] then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
if string.find(class, "func_") then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
if item:IsRagdoll() then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
if item:IsNPC() then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
if not duplicator.IsAllowed(class) then return false, DarkRP.getPhrase("cannot_pocket_x") end
|
||||
-- Entities being held by the gravgun have different properties than
|
||||
-- entities not being held. One such property is mass, which is set to 1.
|
||||
-- The simple solution is to disallow pocketing entities that are being
|
||||
-- held.
|
||||
if item.DarkRPBeingGravGunHeldBy ~= nil then return false, DarkRP.getPhrase("cannot_pocket_gravgunned") end
|
||||
|
||||
local trace = ply:GetEyeTrace()
|
||||
if ply:EyePos():DistToSqr(trace.HitPos) > 22500 then return false end
|
||||
|
||||
local ent = trace.Entity
|
||||
local phys = ent:GetPhysicsObject()
|
||||
if not phys:IsValid() then return false end
|
||||
|
||||
local mass = ent.RPOriginalMass and ent.RPOriginalMass or phys:GetMass()
|
||||
if mass > 100 then return false, DarkRP.getPhrase("object_too_heavy") end
|
||||
|
||||
local job = ply:Team()
|
||||
local max = RPExtraTeams[job].maxpocket or GAMEMODE.Config.pocketitems
|
||||
if table.Count(ply.darkRPPocket or {}) >= max then return false, DarkRP.getPhrase("pocket_full") end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Drop pocket items on death
|
||||
hook.Add("PlayerDeath", "DropPocketItems", function(ply)
|
||||
if not GAMEMODE.Config.droppocketdeath or not ply.darkRPPocket then return end
|
||||
dropAllPocketItems(ply)
|
||||
end)
|
||||
|
||||
hook.Add("playerArrested", "DropPocketItems", function(ply)
|
||||
if not GAMEMODE.Config.droppocketarrest then return end
|
||||
dropAllPocketItems(ply)
|
||||
end)
|
||||
169
gamemodes/darkrp/entities/weapons/stick_base/shared.lua
Normal file
169
gamemodes/darkrp/entities/weapons/stick_base/shared.lua
Normal file
@@ -0,0 +1,169 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.DrawAmmo = false
|
||||
SWEP.DrawCrosshair = false
|
||||
end
|
||||
|
||||
DEFINE_BASECLASS("weapon_cs_base2")
|
||||
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.IconLetter = ""
|
||||
|
||||
SWEP.ViewModelFOV = 62
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.AnimPrefix = "stunstick"
|
||||
|
||||
SWEP.UseHands = false
|
||||
|
||||
SWEP.AdminOnly = true
|
||||
|
||||
SWEP.StickColor = color_white
|
||||
|
||||
SWEP.ViewModel = Model("models/weapons/v_stunbaton.mdl")
|
||||
SWEP.WorldModel = Model("models/weapons/w_stunbaton.mdl")
|
||||
|
||||
SWEP.Sound = Sound("weapons/stunstick/stunstick_swing1.wav")
|
||||
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = 0
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = ""
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = 0
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
BaseClass.SetupDataTables(self)
|
||||
-- Bool 0 = IronsightsPredicted
|
||||
-- Bool 1 = Reloading
|
||||
self:NetworkVar("Bool", 2, "SeqIdling")
|
||||
-- Float 0 = IronsightsTime
|
||||
-- Float 1 = LastPrimaryAttack
|
||||
-- Float 2 = ReloadEndTime
|
||||
-- Float 3 = BurstTime
|
||||
self:NetworkVar("Float", 4, "SeqIdleTime")
|
||||
self:NetworkVar("Float", 5, "HoldTypeChangeTime")
|
||||
end
|
||||
|
||||
local stunstickMaterials
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType("normal")
|
||||
|
||||
self.stickRange = 90
|
||||
|
||||
if SERVER then return end
|
||||
|
||||
stunstickMaterials = stunstickMaterials or {}
|
||||
|
||||
local materialName = "darkrp/" .. self:GetClass()
|
||||
if stunstickMaterials[materialName] then return end
|
||||
|
||||
CreateMaterial(materialName, "VertexLitGeneric", {
|
||||
["$basetexture"] = "models/debug/debugwhite",
|
||||
["$surfaceprop"] = "metal",
|
||||
["$envmap"] = "env_cubemap",
|
||||
["$envmaptint"] = "[ .5 .5 .5 ]",
|
||||
["$selfillum"] = 0,
|
||||
["$model"] = 1
|
||||
}):SetVector("$color2", self.StickColor:ToVector())
|
||||
|
||||
stunstickMaterials[materialName] = true
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
BaseClass.Deploy(self)
|
||||
if SERVER then
|
||||
self:SetMaterial("!darkrp/" .. self:GetClass())
|
||||
end
|
||||
|
||||
local vm = self:GetOwner():GetViewModel()
|
||||
if not IsValid(vm) then return true end
|
||||
|
||||
vm:SendViewModelMatchingSequence(vm:LookupSequence("idle01"))
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:PreDrawViewModel(vm)
|
||||
for i = 9, 15 do
|
||||
vm:SetSubMaterial(i, "!darkrp/" .. self:GetClass())
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:ViewModelDrawn(vm)
|
||||
if not IsValid(vm) then return end
|
||||
vm:SetSubMaterial() -- clear sub-materials
|
||||
end
|
||||
|
||||
function SWEP:ResetStick()
|
||||
if not IsValid(self:GetOwner()) then return end
|
||||
if SERVER then
|
||||
self:SetMaterial() -- clear material
|
||||
end
|
||||
self:SetSeqIdling(false)
|
||||
self:SetSeqIdleTime(0)
|
||||
self:SetHoldTypeChangeTime(0)
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
BaseClass.Holster(self)
|
||||
self:ResetStick()
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Think()
|
||||
if self:GetSeqIdling() then
|
||||
self:SetSeqIdling(false)
|
||||
|
||||
if not IsValid(self:GetOwner()) then return end
|
||||
self:GetOwner():SetAnimation(PLAYER_ATTACK1)
|
||||
self:EmitSound(self.Sound)
|
||||
|
||||
local vm = self:GetOwner():GetViewModel()
|
||||
if not IsValid(vm) then return end
|
||||
vm:SendViewModelMatchingSequence(vm:LookupSequence("attackch"))
|
||||
vm:SetPlaybackRate(1 + 1 / 3)
|
||||
local duration = vm:SequenceDuration() / vm:GetPlaybackRate()
|
||||
local time = CurTime() + duration
|
||||
self:SetSeqIdleTime(time)
|
||||
self:SetNextPrimaryFire(time)
|
||||
end
|
||||
if self:GetSeqIdleTime() ~= 0 and CurTime() >= self:GetSeqIdleTime() then
|
||||
self:SetSeqIdleTime(0)
|
||||
|
||||
if not IsValid(self:GetOwner()) then return end
|
||||
local vm = self:GetOwner():GetViewModel()
|
||||
if not IsValid(vm) then return end
|
||||
vm:SendViewModelMatchingSequence(vm:LookupSequence("idle01"))
|
||||
end
|
||||
if self:GetHoldTypeChangeTime() ~= 0 and CurTime() >= self:GetHoldTypeChangeTime() then
|
||||
self:SetHoldTypeChangeTime(0)
|
||||
self:SetHoldType("normal")
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
self:SetHoldType("melee")
|
||||
self:SetHoldTypeChangeTime(CurTime() + 0.3)
|
||||
|
||||
self:SetNextPrimaryFire(CurTime() + 0.51) -- Actual delay is set later.
|
||||
|
||||
local vm = self:GetOwner():GetViewModel()
|
||||
if IsValid(vm) then
|
||||
vm:SendViewModelMatchingSequence(vm:LookupSequence("idle01"))
|
||||
self:SetSeqIdling(true)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
-- Do nothing
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
-- Do nothing
|
||||
end
|
||||
196
gamemodes/darkrp/entities/weapons/stunstick/shared.lua
Normal file
196
gamemodes/darkrp/entities/weapons/stunstick/shared.lua
Normal file
@@ -0,0 +1,196 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 5
|
||||
SWEP.RenderGroup = RENDERGROUP_BOTH
|
||||
|
||||
killicon.AddAlias("stunstick", "weapon_stunstick")
|
||||
|
||||
CreateMaterial("darkrp/stunstick_beam", "UnlitGeneric", {
|
||||
["$basetexture"] = "sprites/lgtning",
|
||||
["$additive"] = 1
|
||||
})
|
||||
end
|
||||
|
||||
DEFINE_BASECLASS("stick_base")
|
||||
|
||||
SWEP.Instructions = "Left click to discipline\nRight click to kill\nHold reload to threaten"
|
||||
SWEP.IsDarkRPStunstick = true
|
||||
|
||||
SWEP.PrintName = "Stun Stick"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
|
||||
SWEP.StickColor = Color(0, 0, 255)
|
||||
|
||||
function SWEP:Initialize()
|
||||
BaseClass.Initialize(self)
|
||||
|
||||
self.Hit = {
|
||||
Sound("weapons/stunstick/stunstick_impact1.wav"),
|
||||
Sound("weapons/stunstick/stunstick_impact2.wav")
|
||||
}
|
||||
|
||||
self.FleshHit = {
|
||||
Sound("weapons/stunstick/stunstick_fleshhit1.wav"),
|
||||
Sound("weapons/stunstick/stunstick_fleshhit2.wav")
|
||||
}
|
||||
end
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
BaseClass.SetupDataTables(self)
|
||||
-- Float 0 = IronsightsTime
|
||||
-- Float 1 = LastPrimaryAttack
|
||||
-- Float 2 = ReloadEndTime
|
||||
-- Float 3 = BurstTime
|
||||
-- Float 4 = SeqIdleTime
|
||||
-- Float 5 = HoldTypeChangeTime
|
||||
self:NetworkVar("Float", 6, "LastReload")
|
||||
end
|
||||
|
||||
function SWEP:Think()
|
||||
BaseClass.Think(self)
|
||||
if self.WaitingForAttackEffect and self:GetSeqIdleTime() ~= 0 and CurTime() >= self:GetSeqIdleTime() - 0.35 then
|
||||
self.WaitingForAttackEffect = false
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
local effectData = EffectData()
|
||||
effectData:SetOrigin(Owner:GetShootPos() + (Owner:EyeAngles():Forward() * 45))
|
||||
effectData:SetNormal(Owner:EyeAngles():Forward())
|
||||
util.Effect("StunstickImpact", effectData)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:DoFlash(ply)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
|
||||
ply:ScreenFade(SCREENFADE.IN, color_white, 1.2, 0)
|
||||
end
|
||||
|
||||
local stunstickMaterial = Material("effects/stunstick")
|
||||
local stunstickBeam = Material("!darkrp/stunstick_beam")
|
||||
local colorSprite = Color(180, 180, 180)
|
||||
function SWEP:PostDrawViewModel(vm)
|
||||
if self:GetSeqIdleTime() ~= 0 or self:GetLastReload() >= CurTime() - 0.1 then
|
||||
local attachment = vm:GetAttachment(1)
|
||||
local pos = attachment.Pos
|
||||
cam.Start3D(EyePos(), EyeAngles())
|
||||
render.SetMaterial(stunstickMaterial)
|
||||
render.DrawSprite(pos, 12, 12, colorSprite)
|
||||
for i = 1, 3 do
|
||||
local randVec = VectorRand() * 3
|
||||
local offset = (attachment.Ang:Forward() * randVec.x) + (attachment.Ang:Right() * randVec.y) + (attachment.Ang:Up() * randVec.z)
|
||||
render.SetMaterial(stunstickBeam)
|
||||
render.DrawBeam(pos, pos + offset, 3.25 - i, 1, 1.25, colorSprite)
|
||||
pos = pos + offset
|
||||
end
|
||||
cam.End3D()
|
||||
end
|
||||
end
|
||||
|
||||
local light_glow02_add = Material("sprites/light_glow02_add")
|
||||
function SWEP:DrawWorldModelTranslucent()
|
||||
if CurTime() <= self:GetLastReload() + 0.1 then
|
||||
local bone = self:GetOwner():LookupBone("ValveBiped.Bip01_R_Hand")
|
||||
if not bone then self:DrawModel() return end
|
||||
local bonePos, boneAng = self:GetOwner():GetBonePosition(bone)
|
||||
if bonePos then
|
||||
local pos = bonePos + (boneAng:Up() * -16) + (boneAng:Right() * 3) + (boneAng:Forward() * 6.5)
|
||||
render.SetMaterial(light_glow02_add)
|
||||
render.DrawSprite(pos, 32, 32, color_white)
|
||||
end
|
||||
end
|
||||
self:DrawModel()
|
||||
end
|
||||
|
||||
local entMeta = FindMetaTable("Entity")
|
||||
function SWEP:DoAttack(dmg)
|
||||
if CLIENT then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
Owner:LagCompensation(true)
|
||||
local trace = util.QuickTrace(Owner:EyePos(), Owner:GetAimVector() * 90, {Owner})
|
||||
Owner:LagCompensation(false)
|
||||
|
||||
local ent = trace.Entity
|
||||
if IsValid(ent) and ent.onStunStickUsed then
|
||||
ent:onStunStickUsed(Owner)
|
||||
return
|
||||
elseif IsValid(ent) and ent:GetClass() == "func_breakable_surf" then
|
||||
ent:Fire("Shatter")
|
||||
Owner:EmitSound(self.Hit[math.random(#self.Hit)])
|
||||
return
|
||||
end
|
||||
|
||||
self.WaitingForAttackEffect = true
|
||||
|
||||
ent = Owner:getEyeSightHitEntity(
|
||||
self.stickRange,
|
||||
15,
|
||||
fn.FAnd{
|
||||
fp{fn.Neq, Owner},
|
||||
fc{IsValid, entMeta.GetPhysicsObject},
|
||||
entMeta.IsSolid
|
||||
}
|
||||
)
|
||||
|
||||
if not IsValid(ent) then return end
|
||||
if ent:IsPlayer() and not ent:Alive() then return end
|
||||
|
||||
if not ent:isDoor() then
|
||||
ent:SetVelocity((ent:GetPos() - Owner:GetPos()) * 7)
|
||||
end
|
||||
|
||||
if dmg > 0 then
|
||||
ent:TakeDamage(dmg, Owner, self)
|
||||
end
|
||||
|
||||
if ent:IsPlayer() or ent:IsNPC() or ent:IsVehicle() then
|
||||
self:DoFlash(ent)
|
||||
Owner:EmitSound(self.FleshHit[math.random(#self.FleshHit)])
|
||||
else
|
||||
Owner:EmitSound(self.Hit[math.random(#self.Hit)])
|
||||
if FPP and FPP.plyCanTouchEnt(Owner, ent, "EntityDamage") then
|
||||
if ent.SeizeReward and not ent.beenSeized and not ent.burningup and Owner:isCP() and ent.Getowning_ent and Owner ~= ent:Getowning_ent() then
|
||||
local amount = isfunction(ent.SeizeReward) and ent:SeizeReward(Owner, dmg) or ent.SeizeReward
|
||||
|
||||
Owner:addMoney(amount)
|
||||
DarkRP.notify(Owner, 1, 4, DarkRP.getPhrase("you_received_x", DarkRP.formatMoney(amount), DarkRP.getPhrase("bonus_destroying_entity")))
|
||||
ent.beenSeized = true
|
||||
end
|
||||
local health = math.max(ent:Health(), ent:GetMaxHealth())
|
||||
health = health == 0 and 1000 or health
|
||||
|
||||
local dmgToTake = GAMEMODE.Config.stunstickdamage <= 1 and GAMEMODE.Config.stunstickdamage * health or GAMEMODE.Config.stunstickdamage
|
||||
-- Ceil because health is an integer value
|
||||
dmgToTake = math.max(0, math.ceil(dmgToTake - dmg))
|
||||
ent:TakeDamage(dmgToTake, Owner, self) -- for illegal entities
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
BaseClass.PrimaryAttack(self)
|
||||
self:SetNextSecondaryFire(self:GetNextPrimaryFire())
|
||||
self:DoAttack(0)
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
BaseClass.PrimaryAttack(self)
|
||||
self:SetNextSecondaryFire(self:GetNextPrimaryFire())
|
||||
self:DoAttack(10)
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
self:SetHoldType("melee")
|
||||
self:SetHoldTypeChangeTime(CurTime() + 0.1)
|
||||
|
||||
if self:GetLastReload() + 0.1 > CurTime() then self:SetLastReload(CurTime()) return end
|
||||
self:SetLastReload(CurTime())
|
||||
self:EmitSound("weapons/stunstick/spark" .. math.random(1, 3) .. ".wav")
|
||||
end
|
||||
107
gamemodes/darkrp/entities/weapons/unarrest_stick/shared.lua
Normal file
107
gamemodes/darkrp/entities/weapons/unarrest_stick/shared.lua
Normal file
@@ -0,0 +1,107 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 3
|
||||
end
|
||||
|
||||
DEFINE_BASECLASS("stick_base")
|
||||
|
||||
SWEP.Instructions = "Left click to unarrest\nRight click to switch batons"
|
||||
SWEP.IsDarkRPUnarrestStick = true
|
||||
|
||||
SWEP.PrintName = "Unarrest Baton"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
|
||||
SWEP.StickColor = Color(0, 255, 0)
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "canUnarrest",
|
||||
description = "Whether someone can unarrest another player.",
|
||||
parameters = {
|
||||
{
|
||||
name = "unarrester",
|
||||
description = "The player trying to unarrest someone.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "unarrestee",
|
||||
description = "The player being unarrested.",
|
||||
type = "Player"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "canUnarrest",
|
||||
description = "A yes or no as to whether the player can unarrest the other player.",
|
||||
type = "boolean"
|
||||
},
|
||||
{
|
||||
name = "message",
|
||||
description = "The message that is shown when they can't unarrest the player.",
|
||||
type = "string"
|
||||
}
|
||||
},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
-- Default for canUnarrest hook
|
||||
local hookCanUnarrest = {canUnarrest = fp{fn.Id, true}}
|
||||
|
||||
function SWEP:Deploy()
|
||||
self.Switched = true
|
||||
return BaseClass.Deploy(self)
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
BaseClass.PrimaryAttack(self)
|
||||
|
||||
if CLIENT then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
Owner:LagCompensation(true)
|
||||
local trace = util.QuickTrace(Owner:EyePos(), Owner:GetAimVector() * 90, {Owner})
|
||||
Owner:LagCompensation(false)
|
||||
|
||||
local ent = trace.Entity
|
||||
if IsValid(ent) and ent.onUnArrestStickUsed then
|
||||
ent:onUnArrestStickUsed(Owner)
|
||||
return
|
||||
end
|
||||
|
||||
ent = Owner:getEyeSightHitEntity(nil, nil, function(p) return p ~= Owner and p:IsPlayer() and p:Alive() and p:IsSolid() end)
|
||||
if not ent then return end
|
||||
|
||||
local stickRange = self.stickRange * self.stickRange
|
||||
if not IsValid(ent) or not ent:IsPlayer() or (Owner:EyePos():DistToSqr(ent:GetPos()) > stickRange) or not ent:getDarkRPVar("Arrested") then
|
||||
return
|
||||
end
|
||||
|
||||
local canUnarrest, message = hook.Call("canUnarrest", hookCanUnarrest, Owner, ent)
|
||||
if not canUnarrest then
|
||||
if message then DarkRP.notify(Owner, 1, 5, message) end
|
||||
return
|
||||
end
|
||||
|
||||
ent:unArrest(Owner)
|
||||
DarkRP.notify(ent, 0, 4, DarkRP.getPhrase("youre_unarrested_by", Owner:Nick()))
|
||||
|
||||
if Owner.SteamName then
|
||||
DarkRP.log(Owner:Nick() .. " (" .. Owner:SteamID() .. ") unarrested " .. ent:Nick(), Color(0, 255, 255))
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:startDarkRPCommand(usrcmd)
|
||||
if game.SinglePlayer() and CLIENT then return end
|
||||
if usrcmd:KeyDown(IN_ATTACK2) then
|
||||
if not self.Switched and self:GetOwner():HasWeapon("arrest_stick") then
|
||||
usrcmd:SelectWeapon(self:GetOwner():GetWeapon("arrest_stick"))
|
||||
end
|
||||
else
|
||||
self.Switched = false
|
||||
end
|
||||
end
|
||||
49
gamemodes/darkrp/entities/weapons/weapon_ak472/shared.lua
Normal file
49
gamemodes/darkrp/entities/weapons/weapon_ak472/shared.lua
Normal file
@@ -0,0 +1,49 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 3
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.IconLetter = "b"
|
||||
|
||||
killicon.AddFont("weapon_ak472", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "AK47"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.UseHands = true
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_rif_ak47.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_rif_ak47.mdl"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.LoweredHoldType = "passive"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_AK47.Single")
|
||||
SWEP.Primary.Recoil = 1.5
|
||||
SWEP.Primary.Damage = 40
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.002
|
||||
SWEP.Primary.ClipSize = 30
|
||||
SWEP.Primary.Delay = 0.08
|
||||
SWEP.Primary.DefaultClip = 30
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Ammo = "smg1"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.IronSightsPos = Vector(-6.6, -15, 2.6)
|
||||
SWEP.IronSightsAng = Vector(2.6, 0.02, 0)
|
||||
|
||||
SWEP.MultiMode = true
|
||||
@@ -0,0 +1,19 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "drop",
|
||||
description = "Drop the weapon you're holding.",
|
||||
delay = 1.5
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "dropweapon",
|
||||
description = "Drop the weapon you're holding.",
|
||||
delay = 1.5
|
||||
}
|
||||
|
||||
DarkRP.declareChatCommand{
|
||||
command = "weapondrop",
|
||||
description = "Drop the weapon you're holding.",
|
||||
delay = 1.5
|
||||
}
|
||||
516
gamemodes/darkrp/entities/weapons/weapon_cs_base2/shared.lua
Normal file
516
gamemodes/darkrp/entities/weapons/weapon_cs_base2/shared.lua
Normal file
@@ -0,0 +1,516 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if SERVER then
|
||||
include("sv_commands.lua")
|
||||
include("sh_commands.lua")
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
SWEP.DrawAmmo = true
|
||||
SWEP.DrawCrosshair = false
|
||||
SWEP.ViewModelFOV = 82
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.CSMuzzleFlashes = true
|
||||
|
||||
-- This is the font that's used to draw the death icons
|
||||
surface.CreateFont("CSKillIcons", {
|
||||
size = ScreenScale(30),
|
||||
weight = 500,
|
||||
antialias = true,
|
||||
shadow = true,
|
||||
font = "csd"
|
||||
})
|
||||
surface.CreateFont("CSSelectIcons", {
|
||||
size = ScreenScale(60),
|
||||
weight = 500,
|
||||
antialias = true,
|
||||
shadow = true,
|
||||
font = "csd"
|
||||
})
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_base"
|
||||
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.Instructions = ""
|
||||
|
||||
SWEP.Spawnable = false
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.UseHands = true
|
||||
|
||||
SWEP.HoldType = "normal"
|
||||
SWEP.LoweredHoldType = "normal"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_AK47.Single")
|
||||
SWEP.Primary.Recoil = 1.5
|
||||
SWEP.Primary.Damage = 40
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.02
|
||||
SWEP.Primary.Delay = 0.15
|
||||
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "none"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.MultiMode = false
|
||||
|
||||
SWEP.DarkRPBased = true
|
||||
|
||||
function SWEP:SetIronsights(b)
|
||||
if (b ~= self:GetIronsights()) then
|
||||
self:SetIronsightsPredicted(b)
|
||||
self:SetIronsightsTime(CurTime())
|
||||
if GAMEMODE.Config.ironshoot then
|
||||
self:SetHoldType(b and self.HoldType or self.LoweredHoldType)
|
||||
end
|
||||
if CLIENT then
|
||||
self:CalcViewModel()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:GetIronsights()
|
||||
return self:GetIronsightsPredicted()
|
||||
end
|
||||
|
||||
--- Dummy functions that will be replaced when SetupDataTables runs. These are
|
||||
--- here for when that does not happen (due to e.g. stacking base classes)
|
||||
function SWEP:GetIronsightsTime() return -1 end
|
||||
function SWEP:SetIronsightsTime() end
|
||||
function SWEP:GetIronsightsPredicted() return false end
|
||||
function SWEP:SetIronsightsPredicted() end
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
self:NetworkVar("Bool", 0, "IronsightsPredicted")
|
||||
self:NetworkVar("Float", 0, "IronsightsTime")
|
||||
self:NetworkVar("Bool", 1, "Reloading")
|
||||
self:NetworkVar("Float", 1, "LastPrimaryAttack")
|
||||
self:NetworkVar("Float", 2, "ReloadEndTime")
|
||||
self:NetworkVar("Float", 3, "BurstTime")
|
||||
self:NetworkVar("Int", 0, "BurstBulletNum")
|
||||
self:NetworkVar("Int", 1, "TotalUsedMagCount")
|
||||
self:NetworkVar("String", 0, "FireMode")
|
||||
self:NetworkVar("Entity", 0, "LastOwner")
|
||||
end
|
||||
|
||||
function SWEP:Initialize()
|
||||
if CLIENT and IsValid(self:GetOwner()) then
|
||||
local vm = self:GetOwner():GetViewModel()
|
||||
self:ResetDarkRPBones(vm)
|
||||
end
|
||||
|
||||
self:SetHoldType(GAMEMODE.Config.ironshoot and self.LoweredHoldType or self.HoldType)
|
||||
if SERVER then
|
||||
self:SetNPCMinBurst(30)
|
||||
self:SetNPCMaxBurst(30)
|
||||
self:SetNPCFireRate(0.01)
|
||||
end
|
||||
|
||||
self:SetFireMode(self.Primary.Automatic and "auto" or "semi")
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
self:SetHoldType(GAMEMODE.Config.ironshoot and self.LoweredHoldType or self.HoldType)
|
||||
self:SetIronsights(false)
|
||||
self:SetReloading(false)
|
||||
self:SetReloadEndTime(0)
|
||||
self:SetBurstTime(0)
|
||||
self:SetBurstBulletNum(0)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
self:SetIronsights(false)
|
||||
self:SetReloading(false)
|
||||
self:SetReloadEndTime(0)
|
||||
self:SetBurstTime(0)
|
||||
self:SetBurstBulletNum(0)
|
||||
|
||||
if CLIENT then self.hasShot = false end
|
||||
|
||||
if not IsValid(self:GetOwner()) then return true end
|
||||
if CLIENT then
|
||||
local vm = self:GetOwner():GetViewModel()
|
||||
self:ResetDarkRPBones(vm)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:OnRemove()
|
||||
if CLIENT and IsValid(self:GetOwner()) then
|
||||
local vm = self:GetOwner():GetViewModel()
|
||||
self:ResetDarkRPBones(vm)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:OwnerChanged()
|
||||
if IsValid(self:GetOwner()) then self:SetLastOwner(self:GetOwner()) end
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
self.Primary.Automatic = self:GetFireMode() == "auto"
|
||||
|
||||
if self:GetBurstBulletNum() > 0 and CurTime() < self:GetBurstTime() then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
if self.MultiMode and Owner:KeyDown(IN_USE) then
|
||||
if self:GetFireMode() == "semi" then
|
||||
self:SetFireMode("burst")
|
||||
self.Primary.Automatic = false
|
||||
Owner:PrintMessage(HUD_PRINTCENTER, DarkRP.getPhrase("switched_burst"))
|
||||
elseif self:GetFireMode() == "burst" then
|
||||
self:SetFireMode("auto")
|
||||
self.Primary.Automatic = true
|
||||
Owner:PrintMessage(HUD_PRINTCENTER, DarkRP.getPhrase("switched_fully_auto"))
|
||||
elseif self:GetFireMode() == "auto" then
|
||||
self:SetFireMode("semi")
|
||||
self.Primary.Automatic = false
|
||||
Owner:PrintMessage(HUD_PRINTCENTER, DarkRP.getPhrase("switched_semi_auto"))
|
||||
end
|
||||
self:SetNextPrimaryFire(CurTime() + 0.5)
|
||||
self:SetNextSecondaryFire(CurTime() + 0.5)
|
||||
return
|
||||
end
|
||||
|
||||
if self:GetFireMode() ~= "burst" then
|
||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
||||
end
|
||||
|
||||
self:SetNextSecondaryFire(CurTime() + self.Primary.Delay)
|
||||
|
||||
if self:Clip1() <= 0 then
|
||||
self:EmitSound("weapons/clipempty_rifle.wav")
|
||||
self:SetNextPrimaryFire(CurTime() + 2)
|
||||
return
|
||||
end
|
||||
|
||||
if not self:CanPrimaryAttack() then self:SetIronsights(false) return end
|
||||
if not self:GetIronsights() and GAMEMODE.Config.ironshoot then return end
|
||||
-- Play shoot sound
|
||||
self:EmitSound(self.Primary.Sound)
|
||||
|
||||
-- Shoot the bullet
|
||||
self:CSShootBullet(self.Primary.Damage, self.Primary.Recoil + 3, self.Primary.NumShots, self.Primary.Cone + .05)
|
||||
|
||||
if self:GetFireMode() == "burst" then
|
||||
self:SetBurstBulletNum(self:GetBurstBulletNum() + 1)
|
||||
if self:GetBurstBulletNum() == 3 then
|
||||
self:SetBurstTime(0)
|
||||
self:SetBurstBulletNum(0)
|
||||
else
|
||||
self:SetBurstTime(CurTime() + 0.1)
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove 1 bullet from our clip
|
||||
self:TakePrimaryAmmo(1)
|
||||
|
||||
self:SetLastPrimaryAttack(CurTime())
|
||||
|
||||
if Owner:IsNPC() then return end
|
||||
|
||||
-- Punch the player's view
|
||||
Owner:ViewPunch(Angle(util.SharedRandom("DarkRP_CSBase" .. self:EntIndex() .. "Mag" .. self:GetTotalUsedMagCount() .. "p" .. self:Clip1(), -1.2, -1.1) * self.Primary.Recoil, util.SharedRandom("DarkRP_CSBase" .. self:EntIndex() .. "Mag" .. self:GetTotalUsedMagCount() .. "y" .. self:Clip1(), -1.1, 1.1) * self.Primary.Recoil, 0))
|
||||
end
|
||||
|
||||
function SWEP:CSShootBullet(dmg, recoil, numbul, cone)
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
numbul = numbul or 1
|
||||
cone = cone or 0.01
|
||||
|
||||
local bullet = {}
|
||||
bullet.Num = numbul or 1
|
||||
bullet.Src = Owner:GetShootPos() -- Source
|
||||
bullet.Dir = (Owner:GetAimVector():Angle() + Owner:GetViewPunchAngles()):Forward() -- Dir of bullet
|
||||
bullet.Spread = Vector(cone, cone, 0) -- Aim Cone
|
||||
bullet.Tracer = 4 -- Show a tracer on every x bullets
|
||||
bullet.Force = 5 -- Amount of force to give to phys objects
|
||||
bullet.Damage = dmg
|
||||
|
||||
Owner:FireBullets(bullet)
|
||||
self:SendWeaponAnim(ACT_VM_PRIMARYATTACK) -- View model animation
|
||||
Owner:MuzzleFlash() -- Crappy muzzle light
|
||||
Owner:SetAnimation(PLAYER_ATTACK1) -- 3rd Person Animation
|
||||
|
||||
if Owner:IsNPC() then return end
|
||||
|
||||
-- Part of workaround, different viewmodel position if shots have been fired
|
||||
if CLIENT then self.hasShot = true end
|
||||
end
|
||||
|
||||
local host_timescale = GetConVar("host_timescale")
|
||||
local IRONSIGHT_TIME = 0.25
|
||||
function SWEP:GetViewModelPosition(pos, ang)
|
||||
if (not self.IronSightsPos) then return pos, ang end
|
||||
|
||||
pos = pos + ang:Forward() * -5
|
||||
|
||||
if (self.bIron == nil) then return pos, ang end
|
||||
|
||||
local bIron = self.bIron
|
||||
local time = self.fCurrentTime + (SysTime() - self.fCurrentSysTime) * game.GetTimeScale() * host_timescale:GetFloat()
|
||||
|
||||
if bIron then
|
||||
self.SwayScale = 0.3
|
||||
self.BobScale = 0.1
|
||||
else
|
||||
self.SwayScale = 1.0
|
||||
self.BobScale = 1.0
|
||||
end
|
||||
|
||||
if GAMEMODE.Config.ironshoot then
|
||||
ang:RotateAroundAxis(ang:Right(), -15)
|
||||
end
|
||||
|
||||
local fIronTime = self.fIronTime
|
||||
if (not bIron) and fIronTime < time - IRONSIGHT_TIME then
|
||||
return pos, ang
|
||||
end
|
||||
|
||||
local mul = 1.0
|
||||
|
||||
if fIronTime > time - IRONSIGHT_TIME then
|
||||
mul = math.Clamp((time - fIronTime) / IRONSIGHT_TIME, 0, 1)
|
||||
|
||||
if not bIron then mul = 1 - mul end
|
||||
end
|
||||
|
||||
local offset = self.IronSightsPos
|
||||
|
||||
if self.IronSightsAng then
|
||||
ang = ang * 1
|
||||
ang:RotateAroundAxis(ang:Right(), self.IronSightsAng.x * mul)
|
||||
ang:RotateAroundAxis(ang:Up(), self.IronSightsAng.y * mul)
|
||||
ang:RotateAroundAxis(ang:Forward(), self.IronSightsAng.z * mul)
|
||||
end
|
||||
|
||||
if GAMEMODE.Config.ironshoot then
|
||||
ang:RotateAroundAxis(ang:Right(), mul * 15)
|
||||
else
|
||||
ang:RotateAroundAxis(ang:Right(), mul)
|
||||
end
|
||||
|
||||
pos = pos + offset.x * ang:Right() * mul
|
||||
pos = pos + offset.y * ang:Forward() * mul
|
||||
pos = pos + offset.z * ang:Up() * mul
|
||||
|
||||
if not self.hasShot then
|
||||
if self.IronSightsAngAfterShootingAdjustment then
|
||||
ang:RotateAroundAxis(ang:Right(), self.IronSightsAngAfterShootingAdjustment.x * mul)
|
||||
ang:RotateAroundAxis(ang:Up(), self.IronSightsAngAfterShootingAdjustment.y * mul)
|
||||
ang:RotateAroundAxis(ang:Forward(), self.IronSightsAngAfterShootingAdjustment.z * mul)
|
||||
end
|
||||
|
||||
if self.IronSightsPosAfterShootingAdjustment then
|
||||
offset = self.IronSightsPosAfterShootingAdjustment
|
||||
local right = ang:Right()
|
||||
local up = ang:Up()
|
||||
local forward = ang:Forward()
|
||||
|
||||
pos = pos + offset.x * right * mul
|
||||
pos = pos + offset.y * forward * mul
|
||||
pos = pos + offset.z * up * mul
|
||||
end
|
||||
end
|
||||
|
||||
return pos, ang
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
if not self.IronSightsPos then return end
|
||||
|
||||
if self:GetReloading() then return end
|
||||
|
||||
self:SetIronsights(not self:GetIronsights())
|
||||
|
||||
self:SetNextSecondaryFire(CurTime() + 0.3)
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Reload does nothing
|
||||
---------------------------------------------------------]]
|
||||
function SWEP:Reload()
|
||||
if not self:DefaultReload(ACT_VM_RELOAD) then return end
|
||||
self:SetReloading(true)
|
||||
self:SetIronsights(false)
|
||||
self:SetBurstTime(0)
|
||||
self:SetBurstBulletNum(0)
|
||||
self:GetOwner():SetAnimation(PLAYER_RELOAD)
|
||||
self:SetReloadEndTime(CurTime() + 2)
|
||||
self:SetTotalUsedMagCount(self:GetTotalUsedMagCount() + 1)
|
||||
end
|
||||
|
||||
function SWEP:OnRestore()
|
||||
self:SetNextSecondaryFire(0)
|
||||
self:SetIronsights(false)
|
||||
end
|
||||
|
||||
function SWEP:Equip(NewOwner)
|
||||
if self.PrimaryClipLeft and self.SecondaryClipLeft and self.PrimaryAmmoLeft and self.SecondaryAmmoLeft then
|
||||
NewOwner:SetAmmo(self.PrimaryAmmoLeft, self:GetPrimaryAmmoType())
|
||||
NewOwner:SetAmmo(self.SecondaryAmmoLeft, self:GetSecondaryAmmoType())
|
||||
|
||||
self:SetClip1(self.PrimaryClipLeft)
|
||||
self:SetClip2(self.SecondaryClipLeft)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:OnDrop()
|
||||
self.PrimaryClipLeft = self:Clip1()
|
||||
self.SecondaryClipLeft = self:Clip2()
|
||||
|
||||
if not IsValid(self:GetLastOwner()) then return end
|
||||
self.PrimaryAmmoLeft = self:GetLastOwner():GetAmmoCount(self:GetPrimaryAmmoType())
|
||||
self.SecondaryAmmoLeft = self:GetLastOwner():GetAmmoCount(self:GetSecondaryAmmoType())
|
||||
self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE_DEBRIS)
|
||||
end
|
||||
|
||||
function SWEP:CalcViewModel()
|
||||
if (not CLIENT) or (not IsFirstTimePredicted()) then return end
|
||||
self.bIron = self:GetIronsights()
|
||||
self.fIronTime = self:GetIronsightsTime()
|
||||
self.fCurrentTime = CurTime()
|
||||
self.fCurrentSysTime = SysTime()
|
||||
end
|
||||
|
||||
-- Note that if you override Think in your SWEP, you should call
|
||||
-- BaseClass.Think(self) so as not to break ironsights
|
||||
function SWEP:Think()
|
||||
self:CalcViewModel()
|
||||
if self.Primary.ClipSize ~= -1 and not self:GetReloading() and not self:GetIronsights() and self:GetLastPrimaryAttack() + 1 < CurTime() and self:GetHoldType() == self.HoldType and GAMEMODE.Config.ironshoot then
|
||||
self:SetHoldType(self.LoweredHoldType)
|
||||
end
|
||||
if self:GetReloadEndTime() ~= 0 and CurTime() >= self:GetReloadEndTime() then
|
||||
self:SetReloadEndTime(0)
|
||||
self:SetReloading(false)
|
||||
if GAMEMODE.Config.ironshoot then
|
||||
self:SetHoldType(self.LoweredHoldType)
|
||||
end
|
||||
if CLIENT then self.hasShot = false end
|
||||
end
|
||||
if self:GetBurstTime() ~= 0 and CurTime() >= self:GetBurstTime() then
|
||||
self:PrimaryAttack()
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:DrawWeaponSelection(x, y, wide, tall, alpha)
|
||||
if self.IconLetter and string.find(self.IconLetter, "^[0-9a-wA-Z]$") then
|
||||
draw.DrawNonParsedSimpleText(self.IconLetter, "CSSelectIcons", x + wide / 2, y + tall * 0.2, Color(255, 210, 0, 255), TEXT_ALIGN_CENTER)
|
||||
|
||||
-- try to fool them into thinking they're playing a Tony Hawks game
|
||||
draw.DrawNonParsedSimpleText(self.IconLetter, "CSSelectIcons", x + wide / 2 + math.Rand(-4, 4), y + tall * 0.2 + math.Rand(-14, 14), Color(255, 210, 0, math.Rand(10, 120)), TEXT_ALIGN_CENTER)
|
||||
draw.DrawNonParsedSimpleText(self.IconLetter, "CSSelectIcons", x + wide / 2 + math.Rand(-4, 4), y + tall * 0.2 + math.Rand(-9, 9), Color(255, 210, 0, math.Rand(10, 120)), TEXT_ALIGN_CENTER)
|
||||
else
|
||||
-- Set us up the texture
|
||||
surface.SetDrawColor(255, 255, 255, alpha)
|
||||
surface.SetTexture(self.WepSelectIcon)
|
||||
|
||||
-- Lets get a sin wave to make it bounce
|
||||
local fsin = 0
|
||||
|
||||
if self.BounceWeaponIcon then
|
||||
fsin = math.sin(CurTime() * 10) * 5
|
||||
end
|
||||
|
||||
-- Borders
|
||||
y = y + 10
|
||||
x = x + 10
|
||||
wide = wide - 20
|
||||
|
||||
-- Draw that motherfucker
|
||||
surface.DrawTexturedRect(x + fsin, y - fsin, wide - fsin * 2, (wide / 2) + fsin)
|
||||
|
||||
-- Draw weapon info box
|
||||
self:PrintWeaponInfo(x + wide + 20, y + tall * 0.95, alpha)
|
||||
end
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
function SWEP:ViewModelDrawn(vm)
|
||||
if self.DarkRPViewModelBoneManipulations and not self:GetReloading() then
|
||||
self:UpdateDarkRPBones(vm, self.DarkRPViewModelBoneManipulations)
|
||||
else
|
||||
self:ResetDarkRPBones(vm)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:UpdateDarkRPBones(vm, manipulations)
|
||||
if not IsValid(vm) or not vm:GetBoneCount() then return end
|
||||
|
||||
-- Fill in missing bone names. Things fuck up when we workaround the scale bug and bones are missing.
|
||||
local bones = {}
|
||||
for i = 0, vm:GetBoneCount() - 1 do
|
||||
local bonename = vm:GetBoneName(i)
|
||||
if manipulations[bonename] then
|
||||
bones[bonename] = manipulations[bonename]
|
||||
else
|
||||
bones[bonename] = {
|
||||
scale = Vector(1,1,1),
|
||||
pos = Vector(0,0,0),
|
||||
angle = Angle(0,0,0)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(bones) do
|
||||
local bone = vm:LookupBone(k)
|
||||
if not bone then continue end
|
||||
|
||||
-- Bone scaling seems to be buggy. Workaround.
|
||||
local scale = Vector(v.scale.x, v.scale.y, v.scale.z)
|
||||
local ms = Vector(1,1,1)
|
||||
local cur = vm:GetBoneParent(bone)
|
||||
while cur >= 0 do
|
||||
local pscale = bones[vm:GetBoneName(cur)].scale
|
||||
ms = ms * pscale
|
||||
cur = vm:GetBoneParent(cur)
|
||||
end
|
||||
scale = scale * ms
|
||||
|
||||
if vm:GetManipulateBoneScale(bone) ~= scale then
|
||||
vm:ManipulateBoneScale(bone, scale)
|
||||
end
|
||||
if vm:GetManipulateBonePosition(bone) ~= v.pos then
|
||||
vm:ManipulateBonePosition(bone, v.pos)
|
||||
end
|
||||
if vm:GetManipulateBoneAngles(bone) ~= v.angle then
|
||||
vm:ManipulateBoneAngles(bone, v.angle)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:ResetDarkRPBones(vm)
|
||||
if not IsValid(vm) or not vm:GetBoneCount() then return end
|
||||
for i = 0, vm:GetBoneCount() - 1 do
|
||||
vm:ManipulateBoneScale(i, Vector(1, 1, 1))
|
||||
vm:ManipulateBoneAngles(i, Angle(0, 0, 0))
|
||||
vm:ManipulateBonePosition(i, Vector(0, 0, 0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("SetupMove", "DarkRP_WeaponSpeed", function(ply, mv)
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if not wep:IsValid() or not wep.DarkRPBased or not wep.GetIronsights or not wep:GetIronsights() then return end
|
||||
|
||||
mv:SetMaxClientSpeed(mv:GetMaxClientSpeed() / 3)
|
||||
end)
|
||||
@@ -0,0 +1,158 @@
|
||||
local meta = FindMetaTable("Player")
|
||||
function meta:dropDRPWeapon(weapon)
|
||||
if not weapon:IsValid() or weapon:GetOwner() ~= self or weapon.IsBeingDarkRPDropped then return end
|
||||
|
||||
if GAMEMODE.Config.restrictdrop then
|
||||
local found = false
|
||||
for k,v in pairs(CustomShipments) do
|
||||
if v.entity == weapon:GetClass() then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then return end
|
||||
end
|
||||
|
||||
-- Mark the weapon as being dropped. This, along with the check above will
|
||||
-- prevent the same weapon from being dropped twice.
|
||||
weapon.IsBeingDarkRPDropped = true
|
||||
|
||||
local primAmmo = self:GetAmmoCount(weapon:GetPrimaryAmmoType())
|
||||
self:DropWeapon(weapon) -- Drop it so the model isn't the viewmodel
|
||||
weapon:SetOwner(self)
|
||||
|
||||
local ent = ents.Create("spawned_weapon")
|
||||
|
||||
local model = (weapon:GetModel() == "models/weapons/v_physcannon.mdl" and "models/weapons/w_physics.mdl") or weapon:GetModel()
|
||||
model = util.IsValidModel(model) and model or "models/weapons/w_rif_ak47.mdl"
|
||||
|
||||
ent:SetModel(model)
|
||||
ent:SetSkin(weapon:GetSkin() or 0)
|
||||
ent:SetWeaponClass(weapon:GetClass())
|
||||
ent.nodupe = true
|
||||
ent.clip1 = weapon:Clip1()
|
||||
ent.clip2 = weapon:Clip2()
|
||||
ent.ammoadd = primAmmo
|
||||
|
||||
self:RemoveAmmo(primAmmo, weapon:GetPrimaryAmmoType())
|
||||
self:RemoveAmmo(self:GetAmmoCount(weapon:GetSecondaryAmmoType()), weapon:GetSecondaryAmmoType())
|
||||
|
||||
local trace = {}
|
||||
trace.start = self:GetShootPos()
|
||||
trace.endpos = trace.start + self:GetAimVector() * 50
|
||||
trace.filter = {self, weapon, ent}
|
||||
|
||||
local tr = util.TraceLine(trace)
|
||||
|
||||
ent:SetPos(tr.HitPos)
|
||||
ent:Spawn()
|
||||
|
||||
DarkRP.placeEntity(ent, tr, self)
|
||||
|
||||
hook.Call("onDarkRPWeaponDropped", nil, self, ent, weapon)
|
||||
|
||||
weapon:Remove()
|
||||
end
|
||||
|
||||
local function DropWeapon(ply)
|
||||
local curTime = CurTime()
|
||||
if (ply.DelayDropWeapon or 0) >= curTime then return "" end --Fix Dupe Weapon
|
||||
|
||||
local ent = ply:GetActiveWeapon()
|
||||
if not ent:IsValid() or ent:GetModel() == "" then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("cannot_drop_weapon"))
|
||||
return ""
|
||||
end
|
||||
|
||||
local canDrop = hook.Call("canDropWeapon", GAMEMODE, ply, ent)
|
||||
if not canDrop then
|
||||
DarkRP.notify(ply, 1, 4, DarkRP.getPhrase("cannot_drop_weapon"))
|
||||
return ""
|
||||
end
|
||||
|
||||
ply:DoAnimationEvent(ACT_GMOD_GESTURE_ITEM_DROP)
|
||||
|
||||
ply.DelayDropWeapon = curTime + 1.1
|
||||
|
||||
timer.Simple(1, function()
|
||||
if IsValid(ply) and IsValid(ent) and ply:Alive() and ent:GetModel() ~= "" and not IsValid(ply:GetObserverTarget()) then
|
||||
ply:dropDRPWeapon(ent)
|
||||
end
|
||||
end)
|
||||
return ""
|
||||
end
|
||||
|
||||
DarkRP.defineChatCommand("drop", DropWeapon)
|
||||
DarkRP.defineChatCommand("dropweapon", DropWeapon)
|
||||
DarkRP.defineChatCommand("weapondrop", DropWeapon)
|
||||
|
||||
DarkRP.stub{
|
||||
name = "dropDRPWeapon",
|
||||
description = "Drop the weapon with animations.",
|
||||
parameters = {
|
||||
{
|
||||
name = "weapon",
|
||||
description = "The weapon to drop",
|
||||
type = "Entity",
|
||||
optional = false
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
},
|
||||
metatable = meta
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "onDarkRPWeaponDropped",
|
||||
description = "When a player drops a weapon. Use this hook (in combination with PlayerPickupDarkRPWeapon) to store extra information about a weapon. This hook cannot prevent weapon dropping. If you want to prevent weapon dropping, use canDropWeapon instead.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player who dropped the weapon.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "spawned_weapon",
|
||||
description = "The spawned_weapon created from the weapon that is dropped.",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "original_weapon",
|
||||
description = "The original weapon from which the spawned_weapon is made.",
|
||||
type = "Weapon"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "PlayerPickupDarkRPWeapon",
|
||||
description = "When a player picks up a spawned_weapon.",
|
||||
parameters = {
|
||||
{
|
||||
name = "ply",
|
||||
description = "The player who dropped the weapon.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "spawned_weapon",
|
||||
description = "The spawned_weapon created from the weapon that is dropped.",
|
||||
type = "Entity"
|
||||
},
|
||||
{
|
||||
name = "real_weapon",
|
||||
description = "The actual weapon that will be used by the player.",
|
||||
type = "Weapon"
|
||||
}
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "ShouldntContinue",
|
||||
description = "Whether weapon should be picked up or not.",
|
||||
type = "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
46
gamemodes/darkrp/entities/weapons/weapon_deagle2/shared.lua
Normal file
46
gamemodes/darkrp/entities/weapons/weapon_deagle2/shared.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 1
|
||||
SWEP.IconLetter = "f"
|
||||
|
||||
killicon.AddFont("weapon_deagle2", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "Deagle"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_pist_deagle.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_pist_deagle.mdl"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.HoldType = "pistol"
|
||||
SWEP.LoweredHoldType = "normal"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_Deagle.Single")
|
||||
SWEP.Primary.Recoil = 5.1
|
||||
SWEP.Primary.Damage = 25
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.01
|
||||
SWEP.Primary.ClipSize = 7
|
||||
SWEP.Primary.Delay = 0.3
|
||||
SWEP.Primary.DefaultClip = 7
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "pistol"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.IronSightsPos = Vector(-6.35, -7.5, 2.02)
|
||||
SWEP.IronSightsAng = Vector(0.51, 0, 0)
|
||||
@@ -0,0 +1,45 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 1
|
||||
SWEP.IconLetter = "u"
|
||||
|
||||
killicon.AddFont("weapon_fiveseven2", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "FiveSeven"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_pist_fiveseven.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_pist_fiveseven.mdl"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
SWEP.HoldType = "pistol"
|
||||
SWEP.LoweredHoldType = "normal"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_FiveSeven.Single")
|
||||
SWEP.Primary.Recoil = .5
|
||||
SWEP.Primary.Damage = 10
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.03
|
||||
SWEP.Primary.ClipSize = 21
|
||||
SWEP.Primary.Delay = 0.05
|
||||
SWEP.Primary.DefaultClip = 21
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "pistol"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.IronSightsPos = Vector(-5.92, -6.2, 3)
|
||||
SWEP.IronSightsAng = Vector(-0.5, 0.07, 0)
|
||||
48
gamemodes/darkrp/entities/weapons/weapon_glock2/shared.lua
Normal file
48
gamemodes/darkrp/entities/weapons/weapon_glock2/shared.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Instructions = "Shoot with it"
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.IconLetter = "c"
|
||||
|
||||
killicon.AddFont("weapon_glock2", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "Glock"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_pist_glock18.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_pist_glock18.mdl"
|
||||
SWEP.HoldType = "pistol"
|
||||
SWEP.LoweredHoldType = "normal"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_Glock.Single")
|
||||
SWEP.Primary.Recoil = 2
|
||||
SWEP.Primary.Unrecoil = 6
|
||||
SWEP.Primary.Damage = 10
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.05
|
||||
SWEP.Primary.ClipSize = 20
|
||||
SWEP.Primary.Delay = 0.06
|
||||
SWEP.Primary.DefaultClip = 20
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "pistol"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
--Start of Firemode configuration
|
||||
SWEP.IronSightsPos = Vector(-5.77, -6.6, 2.7)
|
||||
SWEP.IronSightsAng = Vector(0.9, 0, 0)
|
||||
@@ -0,0 +1,59 @@
|
||||
include("shared.lua")
|
||||
|
||||
local DrawData = {}
|
||||
local KeypadCheckerHalos
|
||||
|
||||
net.Receive("DarkRP_keypadData", function(len)
|
||||
DrawData = net.ReadTable()
|
||||
hook.Add("PreDrawHalos", "KeypadCheckerHalos", KeypadCheckerHalos)
|
||||
end)
|
||||
|
||||
local lineMat = Material("cable/chain")
|
||||
local textCol = Color(0, 0, 0, 120)
|
||||
local haloCol = Color(0, 255, 0, 255)
|
||||
|
||||
function SWEP:DrawHUD()
|
||||
local screenCenter = ScrH() / 2
|
||||
draw.WordBox(2, 10, screenCenter, DarkRP.getPhrase("keypad_checker_shoot_keypad"), "UiBold", textCol, color_white)
|
||||
draw.WordBox(2, 10, screenCenter + 20, DarkRP.getPhrase("keypad_checker_shoot_entity"), "UiBold", textCol, color_white)
|
||||
draw.WordBox(2, 10, screenCenter + 40, DarkRP.getPhrase("keypad_checker_click_to_clear"), "UiBold", textCol, color_white)
|
||||
|
||||
local eyePos = EyePos()
|
||||
local eyeAngles = EyeAngles()
|
||||
|
||||
local entMessages = {}
|
||||
for k,v in ipairs(DrawData or {}) do
|
||||
if not IsValid(v.ent) or not IsValid(v.original) then continue end
|
||||
entMessages[v.ent] = (entMessages[v.ent] or 0) + 1
|
||||
local obbCenter = v.ent:OBBCenter()
|
||||
local pos = v.ent:LocalToWorld(obbCenter):ToScreen()
|
||||
|
||||
local name = v.name and ": " .. v.name:gsub("onDown", DarkRP.getPhrase("keypad_on")):gsub("onUp", DarkRP.getPhrase("keypad_off")) or ""
|
||||
|
||||
draw.WordBox(2, pos.x, pos.y + entMessages[v.ent] * 16, (v.delay and v.delay .. " " .. DarkRP.getPhrase("seconds") .. " " or "") .. v.type .. name, "UiBold", textCol, color_white)
|
||||
|
||||
cam.Start3D(eyePos, eyeAngles)
|
||||
render.SetMaterial(lineMat)
|
||||
render.DrawBeam(v.original:GetPos(), v.ent:GetPos(), 2, 0.01, 20, haloCol)
|
||||
cam.End3D()
|
||||
end
|
||||
end
|
||||
|
||||
KeypadCheckerHalos = function()
|
||||
local drawEnts = {}
|
||||
local i = 1
|
||||
for k,v in ipairs(DrawData) do
|
||||
if not IsValid(v.ent) then continue end
|
||||
|
||||
drawEnts[i] = v.ent
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if table.IsEmpty(drawEnts) then return end
|
||||
halo.Add(drawEnts, haloCol, 5, 5, 5, nil, true)
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
DrawData = {}
|
||||
hook.Remove("PreDrawHalos", "KeypadCheckerHalos")
|
||||
end
|
||||
@@ -0,0 +1,187 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
|
||||
util.AddNetworkString("DarkRP_keypadData")
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_base"
|
||||
|
||||
SWEP.PrintName = "Admin Keypad Checker"
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Instructions = "Left click on a keypad or fading door to check it\nRight click to clear"
|
||||
SWEP.Slot = 5
|
||||
SWEP.SlotPos = 1
|
||||
SWEP.DrawAmmo = false
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.Primary.ClipSize = 0
|
||||
SWEP.Primary.Ammo = ""
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
|
||||
SWEP.HoldType = "normal"
|
||||
SWEP.ViewModel = Model("models/weapons/c_pistol.mdl")
|
||||
SWEP.WorldModel = "models/weapons/w_toolgun.mdl"
|
||||
SWEP.IconLetter = ""
|
||||
|
||||
SWEP.ViewModel = "models/weapons/c_pistol.mdl"
|
||||
SWEP.UseHands = true
|
||||
|
||||
local table_insert = table.insert
|
||||
local tonumber = tonumber
|
||||
|
||||
--[[
|
||||
Gets which entities are controlled by which keyboard keys
|
||||
]]
|
||||
local function getTargets(keypad, keyPass, keyDenied, delayPass, delayDenied)
|
||||
local targets = {}
|
||||
local Owner = keypad:CPPIGetOwner()
|
||||
|
||||
for _, v in ipairs(numpad.OnDownItems or {}) do
|
||||
if v.key == keyPass and v.ply == Owner then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_entering_right_pass"), name = v.name, ent = v.ent, original = keypad})
|
||||
end
|
||||
if v.key == keyDenied and v.ply == Owner then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_entering_wrong_pass"), name = v.name, ent = v.ent, original = keypad})
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(numpad.OnUpItems or {}) do
|
||||
if v.key == keyPass and v.ply == Owner then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_after_right_pass"), name = v.name, delay = math.Round(delayPass, 2), ent = v.ent, original = keypad})
|
||||
end
|
||||
if v.key == keyDenied and v.ply == Owner then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_after_wrong_pass"), name = v.name, delay = math.Round(delayDenied, 2), ent = v.ent, original = keypad})
|
||||
end
|
||||
end
|
||||
|
||||
return targets
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Get the entities that are affected by the keypad
|
||||
---------------------------------------------------------------------------]]
|
||||
local function get_sent_keypad_Info(keypad)
|
||||
local keyPass = keypad:GetNWInt("keypad_keygroup1")
|
||||
local keyDenied = keypad:GetNWInt("keypad_keygroup2")
|
||||
local delayPass = keypad:GetNWInt("keypad_length1")
|
||||
local delayDenied = keypad:GetNWInt("keypad_length2")
|
||||
|
||||
return getTargets(keypad, keyPass, keyDenied, delayPass, delayDenied)
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Overload for a different keypad addon
|
||||
---------------------------------------------------------------------------]]
|
||||
local function get_keypad_Info(keypad)
|
||||
local keyPass = tonumber(keypad.KeypadData.KeyGranted) or 0
|
||||
local keyDenied = tonumber(keypad.KeypadData.KeyDenied) or 0
|
||||
local delayPass = tonumber(keypad.KeypadData.LengthGranted) or 0
|
||||
local delayDenied = tonumber(keypad.KeypadData.LengthDenied) or 0
|
||||
|
||||
return getTargets(keypad, keyPass, keyDenied, delayPass, delayDenied)
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Get the keypads that trigger this entity
|
||||
---------------------------------------------------------------------------]]
|
||||
local function getEntityKeypad(ent)
|
||||
local targets = {}
|
||||
local doorKeys = {} -- The numpad keys that activate this entity
|
||||
local entOwner = ent:CPPIGetOwner()
|
||||
|
||||
for _, v in ipairs(numpad.OnDownItems or {}) do
|
||||
if v.ent == ent then
|
||||
table_insert(doorKeys, v.key)
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(numpad.OnUpItems or {}) do
|
||||
if v.ent == ent then
|
||||
table_insert(doorKeys, v.key)
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(ents.FindByClass("sent_keypad")) do
|
||||
local vOwner = v:CPPIGetOwner()
|
||||
|
||||
if vOwner == entOwner and table.HasValue(doorKeys, v:GetNWInt("keypad_keygroup1")) then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_right_pass_entered"), ent = v, original = ent})
|
||||
end
|
||||
if vOwner == entOwner and table.HasValue(doorKeys, v:GetNWInt("keypad_keygroup2")) then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_wrong_pass_entered"), ent = v, original = ent})
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(ents.FindByClass("keypad")) do
|
||||
local vOwner = v:CPPIGetOwner()
|
||||
|
||||
if vOwner == entOwner and table.HasValue(doorKeys, tonumber(v.KeypadData.KeyGranted) or 0) then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_right_pass_entered"), ent = v, original = ent})
|
||||
end
|
||||
if vOwner == entOwner and table.HasValue(doorKeys, tonumber(v.KeypadData.KeyDenied) or 0) then
|
||||
table_insert(targets, {type = DarkRP.getPhrase("keypad_checker_wrong_pass_entered"), ent = v, original = ent})
|
||||
end
|
||||
end
|
||||
|
||||
return targets
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Send the info to the client
|
||||
---------------------------------------------------------------------------]]
|
||||
function SWEP:PrimaryAttack()
|
||||
self:SetNextPrimaryFire(CurTime() + 0.3)
|
||||
if not SERVER then return end
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
local trace = Owner:GetEyeTrace()
|
||||
if not IsValid(trace.Entity) then return end
|
||||
local ent, class = trace.Entity, string.lower(trace.Entity:GetClass() or "")
|
||||
local data
|
||||
|
||||
if class == "sent_keypad" then
|
||||
data = get_sent_keypad_Info(ent)
|
||||
DarkRP.notify(Owner, 1, 4, DarkRP.getPhrase("keypad_checker_controls_x_entities", #data / 2))
|
||||
elseif class == "keypad" then
|
||||
data = get_keypad_Info(ent)
|
||||
DarkRP.notify(Owner, 1, 4, DarkRP.getPhrase("keypad_checker_controls_x_entities", #data / 2))
|
||||
else
|
||||
data = getEntityKeypad(ent)
|
||||
DarkRP.notify(Owner, 1, 4, DarkRP.getPhrase("keypad_checker_controlled_by_x_keypads", #data))
|
||||
end
|
||||
|
||||
net.Start("DarkRP_keypadData")
|
||||
net.WriteTable(data)
|
||||
net.Send(Owner)
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
end
|
||||
|
||||
if not SERVER then return end
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Registering numpad data
|
||||
---------------------------------------------------------------------------]]
|
||||
local oldNumpadUp = numpad.OnUp
|
||||
local oldNumpadDown = numpad.OnDown
|
||||
|
||||
function numpad.OnUp(ply, key, name, ent, ...)
|
||||
numpad.OnUpItems = numpad.OnUpItems or {}
|
||||
table_insert(numpad.OnUpItems, {ply = ply, key = key, name = name, ent = ent, arg = {...}})
|
||||
|
||||
return oldNumpadUp(ply, key, name, ent, ...)
|
||||
end
|
||||
|
||||
function numpad.OnDown(ply, key, name, ent, ...)
|
||||
numpad.OnDownItems = numpad.OnDownItems or {}
|
||||
table_insert(numpad.OnDownItems, {ply = ply, key = key, name = name, ent = ent, arg = {...}})
|
||||
|
||||
return oldNumpadDown(ply, key, name, ent, ...)
|
||||
end
|
||||
131
gamemodes/darkrp/entities/weapons/weapon_m42/shared.lua
Normal file
131
gamemodes/darkrp/entities/weapons/weapon_m42/shared.lua
Normal file
@@ -0,0 +1,131 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.Instructions = "Hold use and left-click to change firemodes."
|
||||
SWEP.Slot = 2
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.IconLetter = "w"
|
||||
|
||||
killicon.AddFont("weapon_m42", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "M4"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_rif_m4a1.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_rif_m4a1.mdl"
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.LoweredHoldType = "passive"
|
||||
SWEP.DarkRPViewModelBoneManipulations = {
|
||||
["ValveBiped.Bip01_Spine4"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(2, 0, 0),
|
||||
angle = Angle(0, 0, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Hand"] = {
|
||||
scale = Vector(0.7, 0.7, 0.5),
|
||||
pos = Vector(-0.6, -0.6, 0),
|
||||
angle = Angle(17, -21, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger0"] = {
|
||||
scale = Vector(1, 1, 1.5),
|
||||
pos = Vector(0, 0, 0),
|
||||
angle = Angle(0, -2, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger1"] = {
|
||||
scale = Vector(1, 1, 1.5),
|
||||
pos = Vector(-0.3, -0.8, 0),
|
||||
angle = Angle(0, -10, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger11"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(0, 0, 0),
|
||||
angle = Angle(0, -15, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger12"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(0, 0, 0),
|
||||
angle = Angle(0, -14, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger2"] = {
|
||||
scale = Vector(1, 1, 1.5),
|
||||
pos = Vector(-0.6, -1, -0),
|
||||
angle = Angle(0, 7, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger21"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(0, 0, 0),
|
||||
angle = Angle(0, -15, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger22"] = {
|
||||
scale = Vector(0.8, 0.8, 1),
|
||||
pos = Vector(0, -0.3, 0),
|
||||
angle = Angle(0, -36, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger3"] = {
|
||||
scale = Vector(1, 1, 1.5),
|
||||
pos = Vector(-0.36, -1.2, -0.2),
|
||||
angle = Angle(-6, -2, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger31"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(0, -0.1, 0),
|
||||
angle = Angle(0, -4, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger32"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(0, -0.2, 0),
|
||||
angle = Angle(0, -12, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger4"] = {
|
||||
scale = Vector(1, 1, 1.5),
|
||||
pos = Vector(-0.3, -1.2, 0.3),
|
||||
angle = Angle(12, -6.2, -4)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger41"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(0, 0, 0),
|
||||
angle = Angle(0, 38, 0)
|
||||
},
|
||||
["ValveBiped.Bip01_L_Finger42"] = {
|
||||
scale = Vector(1, 1, 1),
|
||||
pos = Vector(0, 0, 0),
|
||||
angle = Angle(0, 30, 0)
|
||||
}
|
||||
}
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_M4A1.Single")
|
||||
SWEP.Primary.Recoil = 1.25
|
||||
SWEP.Primary.Unrecoil = 8
|
||||
SWEP.Primary.Damage = 15
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.03
|
||||
SWEP.Primary.ClipSize = 30
|
||||
SWEP.Primary.Delay = 0.07
|
||||
SWEP.Primary.DefaultClip = 30
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Ammo = "smg1"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
-- Start of Firemode configuration
|
||||
SWEP.IronSightsPos = Vector(-8.09, -4.5, 0.56)
|
||||
SWEP.IronSightsAng = Vector(2.75, -3.97, -3.8)
|
||||
SWEP.IronSightsPosAfterShootingAdjustment = Vector(0.5, 0, 0)
|
||||
SWEP.IronSightsAngAfterShootingAdjustment = Vector(0, 1.65, 0)
|
||||
|
||||
SWEP.MultiMode = true
|
||||
46
gamemodes/darkrp/entities/weapons/weapon_mac102/shared.lua
Normal file
46
gamemodes/darkrp/entities/weapons/weapon_mac102/shared.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 2
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.IconLetter = "l"
|
||||
|
||||
killicon.AddFont("weapon_mac102", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "Mac10"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_smg_mac10.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_smg_mac10.mdl"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.HoldType = "pistol"
|
||||
SWEP.LoweredHoldType = "normal"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_mac10.Single")
|
||||
SWEP.Primary.Recoil = .8
|
||||
SWEP.Primary.Damage = 30
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.02
|
||||
SWEP.Primary.ClipSize = 25
|
||||
SWEP.Primary.Delay = 0.09
|
||||
SWEP.Primary.DefaultClip = 25
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Ammo = "smg1"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.IronSightsPos = Vector(-9.08, -8, 2.6)
|
||||
SWEP.IronSightsAng = Vector(1.8, -7.06, -6.1)
|
||||
46
gamemodes/darkrp/entities/weapons/weapon_mp52/shared.lua
Normal file
46
gamemodes/darkrp/entities/weapons/weapon_mp52/shared.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 2
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.IconLetter = "x"
|
||||
|
||||
killicon.AddFont("weapon_mp52", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "MP5"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_smg_mp5.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_smg_mp5.mdl"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.HoldType = "smg"
|
||||
SWEP.LoweredHoldType = "passive"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_MP5Navy.Single")
|
||||
SWEP.Primary.Recoil = 0.5
|
||||
SWEP.Primary.Damage = 15
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.005
|
||||
SWEP.Primary.ClipSize = 32
|
||||
SWEP.Primary.Delay = 0.08
|
||||
SWEP.Primary.DefaultClip = 32
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Ammo = "smg1"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.IronSightsPos = Vector(-5.3, -7, 2.1)
|
||||
SWEP.IronSightsAng = Vector(0.9, 0.1, 0)
|
||||
46
gamemodes/darkrp/entities/weapons/weapon_p2282/shared.lua
Normal file
46
gamemodes/darkrp/entities/weapons/weapon_p2282/shared.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 1
|
||||
SWEP.IconLetter = "y"
|
||||
|
||||
killicon.AddFont("weapon_p2282", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_cs_base2"
|
||||
|
||||
SWEP.PrintName = "P228"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.HoldType = "pistol"
|
||||
SWEP.LoweredHoldType = "normal"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_pist_p228.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_pist_p228.mdl"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_p228.Single")
|
||||
SWEP.Primary.Recoil = 0.8
|
||||
SWEP.Primary.Damage = 10
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.04
|
||||
SWEP.Primary.ClipSize = 12
|
||||
SWEP.Primary.Delay = 0.1
|
||||
SWEP.Primary.DefaultClip = 12
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "pistol"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.IronSightsPos = Vector(-5.985, -6.7, 2.87)
|
||||
SWEP.IronSightsAng = Vector(-0.3, -0.03, 0)
|
||||
136
gamemodes/darkrp/entities/weapons/weapon_pumpshotgun2/shared.lua
Normal file
136
gamemodes/darkrp/entities/weapons/weapon_pumpshotgun2/shared.lua
Normal file
@@ -0,0 +1,136 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Slot = 2
|
||||
SWEP.SlotPos = 0
|
||||
SWEP.IconLetter = "k"
|
||||
|
||||
killicon.AddFont("weapon_pumpshotgun2", "CSKillIcons", SWEP.IconLetter, Color(255, 80, 0, 255))
|
||||
end
|
||||
|
||||
DEFINE_BASECLASS("weapon_cs_base2")
|
||||
|
||||
SWEP.PrintName = "Pump Shotgun"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = false
|
||||
SWEP.Category = "DarkRP (Weapon)"
|
||||
|
||||
SWEP.ViewModel = "models/weapons/cstrike/c_shot_m3super90.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_shot_m3super90.mdl"
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.HoldType = "shotgun"
|
||||
SWEP.LoweredHoldType = "normal"
|
||||
|
||||
SWEP.Primary.Sound = Sound("Weapon_M3.Single")
|
||||
SWEP.Primary.Recoil = 1.5
|
||||
SWEP.Primary.Damage = 20
|
||||
SWEP.Primary.NumShots = 8
|
||||
SWEP.Primary.Cone = 0.08
|
||||
SWEP.Primary.ClipSize = 8
|
||||
SWEP.Primary.Delay = 0.95
|
||||
SWEP.Primary.DefaultClip = 8
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "buckshot"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.IronSightsPos = Vector(-7.64, -8, 3.56)
|
||||
SWEP.IronSightsAng = Vector(-0.1, 0.02, 0)
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
BaseClass.SetupDataTables(self)
|
||||
-- Float 0 = IronsightsTime
|
||||
-- Float 1 = LastPrimaryAttack
|
||||
-- Float 2 = ReloadEndTime
|
||||
-- Float 3 = BurstTime
|
||||
self:NetworkVar("Float", 4, "QueuedAttackTime")
|
||||
-- Bool 0 = IronsightsPredicted
|
||||
-- Bool 1 = Reloading
|
||||
self:NetworkVar("Bool", 2, "AttackQueued")
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
self:SetAttackQueued(false)
|
||||
|
||||
return BaseClass.Deploy(self)
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
self:SetAttackQueued(false)
|
||||
|
||||
return BaseClass.Holster(self)
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
if self:GetAttackQueued() then return end
|
||||
|
||||
if self:GetReloading() then
|
||||
self:SetAttackQueued(true) -- this way it doesn't interupt the reload animation
|
||||
return
|
||||
end
|
||||
|
||||
BaseClass.PrimaryAttack(self)
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
-- Already reloading
|
||||
if self:GetReloading() then return end
|
||||
|
||||
-- Start reloading if we can
|
||||
if self:Clip1() < self.Primary.ClipSize and self:GetOwner():GetAmmoCount(self.Primary.Ammo) > 0 then
|
||||
self:SetReloading(true)
|
||||
self:SetReloadEndTime(CurTime() + 0.3)
|
||||
self:SendWeaponAnim(ACT_VM_RELOAD)
|
||||
self:SetIronsights(false)
|
||||
self:SetHoldType(self.HoldType)
|
||||
self:GetOwner():SetAnimation(PLAYER_RELOAD)
|
||||
self:SetHoldType("normal")
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Think()
|
||||
self:CalcViewModel()
|
||||
if self:GetReloadEndTime() ~= 0 and CurTime() >= self:GetReloadEndTime() then
|
||||
-- Finished reload -
|
||||
if self:Clip1() >= self.Primary.ClipSize or self:GetOwner():GetAmmoCount(self.Primary.Ammo) <= 0 then
|
||||
self:SetReloading(false)
|
||||
self:SetReloadEndTime(0)
|
||||
self:SetAttackQueued(false)
|
||||
return
|
||||
end
|
||||
|
||||
if self:GetAttackQueued() then
|
||||
self:SendWeaponAnim(ACT_SHOTGUN_RELOAD_FINISH)
|
||||
self:SetReloading(false)
|
||||
self:SetReloadEndTime(0)
|
||||
self:SetAttackQueued(false)
|
||||
self:SetQueuedAttackTime(CurTime() + 0.8)
|
||||
return
|
||||
end
|
||||
|
||||
-- Next cycle
|
||||
self:SetReloadEndTime(CurTime() + 0.3)
|
||||
self:SendWeaponAnim(ACT_VM_RELOAD)
|
||||
|
||||
-- Add ammo
|
||||
self:GetOwner():RemoveAmmo(1, self.Primary.Ammo, false)
|
||||
self:SetClip1(self:Clip1() + 1)
|
||||
|
||||
-- Finish filling, final pump
|
||||
if self:Clip1() >= self.Primary.ClipSize or self:GetOwner():GetAmmoCount(self.Primary.Ammo) <= 0 then
|
||||
self:SendWeaponAnim(ACT_SHOTGUN_RELOAD_FINISH)
|
||||
end
|
||||
end
|
||||
if self:GetQueuedAttackTime() ~= 0 and CurTime() >= self:GetQueuedAttackTime() then
|
||||
self:SetQueuedAttackTime(0)
|
||||
self:PrimaryAttack()
|
||||
end
|
||||
end
|
||||
409
gamemodes/darkrp/entities/weapons/weaponchecker/shared.lua
Normal file
409
gamemodes/darkrp/entities/weapons/weaponchecker/shared.lua
Normal file
@@ -0,0 +1,409 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1
|
||||
SWEP.SlotPos = 9
|
||||
SWEP.DrawAmmo = false
|
||||
SWEP.DrawCrosshair = false
|
||||
end
|
||||
|
||||
SWEP.Author = "DarkRP Developers"
|
||||
SWEP.Instructions = "Left click to weapon check\nRight click to confiscate weapons\nReload to give back the weapons"
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.IsDarkRPWeaponChecker = true
|
||||
|
||||
SWEP.ViewModelFOV = 62
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.AnimPrefix = "rpg"
|
||||
|
||||
SWEP.PrintName = "Weapon Checker"
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = true
|
||||
SWEP.Category = "DarkRP (Utility)"
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = 0
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = ""
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = 0
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
SWEP.MinCheckTime = 5
|
||||
SWEP.MaxCheckTime = 10
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerWeaponsChecked",
|
||||
description = "Called when a player with a weapon checker has checked another player's weapons. Note: Only called when the player looks at the weapons without confiscating. Please see playerWeaponsConfiscated for when weapons are actually confiscated.",
|
||||
parameters = {
|
||||
{
|
||||
name = "checker",
|
||||
description = "The player holding the weapon checker.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "target",
|
||||
description = "The player whose weapons have been checked.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "weapons",
|
||||
description = "The weapons that have been checked.",
|
||||
type = "table"
|
||||
},
|
||||
},
|
||||
returns = {},
|
||||
realm = "Shared"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerWeaponsReturned",
|
||||
description = "Called when a player with a weapon checker has returned another player's weapons.",
|
||||
parameters = {
|
||||
{
|
||||
name = "checker",
|
||||
description = "The player holding the weapon checker.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "target",
|
||||
description = "The player whose weapons have been returned.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "weapons",
|
||||
description = "The weapons that have been returned.",
|
||||
type = "table"
|
||||
},
|
||||
},
|
||||
returns = {},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
DarkRP.hookStub{
|
||||
name = "playerWeaponsConfiscated",
|
||||
description = "Called when a player with a weapon checker has confiscated another player's weapons.",
|
||||
parameters = {
|
||||
{
|
||||
name = "checker",
|
||||
description = "The player holding the weapon checker.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "target",
|
||||
description = "The player whose weapons have been confiscated.",
|
||||
type = "Player"
|
||||
},
|
||||
{
|
||||
name = "weapons",
|
||||
description = "The weapons that have been confiscated.",
|
||||
type = "table"
|
||||
},
|
||||
},
|
||||
returns = {},
|
||||
realm = "Server"
|
||||
}
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
self:NetworkVar("Bool", 0, "IsWeaponChecking")
|
||||
self:NetworkVar("Float", 0, "StartCheckTime")
|
||||
self:NetworkVar("Float", 1, "EndCheckTime")
|
||||
self:NetworkVar("Float", 2, "NextSoundTime")
|
||||
self:NetworkVar("Int", 0, "TotalWeaponChecks")
|
||||
end
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType("normal")
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:DrawWorldModel()
|
||||
end
|
||||
|
||||
function SWEP:PreDrawViewModel(vm)
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:GetStrippableWeapons(ent, callback)
|
||||
CAMI.PlayerHasAccess(ent, "DarkRP_GetAdminWeapons", function(access)
|
||||
for _, v in ipairs(ent:GetWeapons()) do
|
||||
local class = v:GetClass()
|
||||
|
||||
if GAMEMODE.Config.weaponCheckerHideDefault and (table.HasValue(GAMEMODE.Config.DefaultWeapons, class) or
|
||||
access and table.HasValue(GAMEMODE.Config.AdminWeapons, class) or
|
||||
ent:getJobTable() and ent:getJobTable().weapons and table.HasValue(ent:getJobTable().weapons, class)) then
|
||||
continue
|
||||
end
|
||||
|
||||
if (GAMEMODE.Config.weaponCheckerHideNoLicense and GAMEMODE.NoLicense[class]) or GAMEMODE.Config.noStripWeapons[class] then continue end
|
||||
|
||||
callback(v)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
if self:GetIsWeaponChecking() then return end
|
||||
self:SetNextPrimaryFire(CurTime() + 0.3)
|
||||
|
||||
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 not ent:IsPlayer() or ent:GetPos():DistToSqr(Owner:GetPos()) > 10000 then
|
||||
return
|
||||
end
|
||||
|
||||
self:EmitSound("npc/combine_soldier/gear5.wav", 50, 100)
|
||||
self:SetNextSoundTime(CurTime() + 0.3)
|
||||
|
||||
if not IsFirstTimePredicted() then return end
|
||||
|
||||
local weps = {}
|
||||
self:GetStrippableWeapons(ent, function(wep)
|
||||
table.insert(weps, wep)
|
||||
end)
|
||||
|
||||
hook.Call("playerWeaponsChecked", nil, Owner, ent, weps)
|
||||
|
||||
if not CLIENT then return end
|
||||
|
||||
self:PrintWeapons(ent, DarkRP.getPhrase("persons_weapons", ent:Nick()))
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
if self:GetIsWeaponChecking() then return end
|
||||
self:SetNextSecondaryFire(CurTime() + 0.3)
|
||||
|
||||
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 not ent:IsPlayer() or ent:GetPos():DistToSqr(Owner:GetPos()) > 10000 then
|
||||
return
|
||||
end
|
||||
|
||||
self:SetIsWeaponChecking(true)
|
||||
self:SetStartCheckTime(CurTime())
|
||||
self:SetEndCheckTime(CurTime() + util.SharedRandom("DarkRP_WeaponChecker" .. self:EntIndex() .. "_" .. self:GetTotalWeaponChecks(), self.MinCheckTime, self.MaxCheckTime))
|
||||
self:SetTotalWeaponChecks(self:GetTotalWeaponChecks() + 1)
|
||||
|
||||
self:SetNextSoundTime(CurTime() + 0.5)
|
||||
|
||||
if CLIENT then
|
||||
self.Dots = ""
|
||||
self.NextDotsTime = CurTime() + 0.5
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
if CLIENT or CurTime() < (self.NextReloadTime or 0) then return end
|
||||
self.NextReloadTime = CurTime() + 1
|
||||
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local trace = Owner:GetEyeTrace()
|
||||
|
||||
local ent = trace.Entity
|
||||
if not IsValid(ent) or not ent:IsPlayer() or ent:GetPos():DistToSqr(Owner:GetPos()) > 10000 then
|
||||
return
|
||||
end
|
||||
|
||||
if not ent.ConfiscatedWeapons then
|
||||
DarkRP.notify(Owner, 1, 4, DarkRP.getPhrase("no_weapons_confiscated", ent:Nick()))
|
||||
return
|
||||
else
|
||||
ent:RemoveAllAmmo()
|
||||
for _, v in pairs(ent.ConfiscatedWeapons) do
|
||||
local wep = ent:Give(v.class, true)
|
||||
|
||||
-- :Give returns NULL when the player already has the weapon
|
||||
wep = IsValid(wep) and wep or ent:GetWeapon(v.class)
|
||||
if not IsValid(wep) then continue end
|
||||
|
||||
ent:GiveAmmo(v.primaryAmmoCount, v.primaryAmmoType, true)
|
||||
ent:GiveAmmo(v.secondaryAmmoCount, v.secondaryAmmoType, true)
|
||||
|
||||
wep:SetClip1(v.clip1)
|
||||
wep:SetClip2(v.clip2)
|
||||
|
||||
end
|
||||
DarkRP.notify(Owner, 2, 4, DarkRP.getPhrase("returned_persons_weapons", ent:Nick()))
|
||||
|
||||
hook.Call("playerWeaponsReturned", nil, Owner, ent, ent.ConfiscatedWeapons)
|
||||
ent.ConfiscatedWeapons = nil
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
self:SetIsWeaponChecking(false)
|
||||
self:SetNextSoundTime(0)
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Succeed()
|
||||
if not IsValid(self:GetOwner()) then return end
|
||||
self:SetIsWeaponChecking(false)
|
||||
|
||||
local trace = self:GetOwner():GetEyeTrace()
|
||||
local ent = trace.Entity
|
||||
if not IsValid(ent) or not ent:IsPlayer() then return end
|
||||
|
||||
if CLIENT then
|
||||
if not IsFirstTimePredicted() then return end
|
||||
self:PrintWeapons(ent, DarkRP.getPhrase("confiscated_these_weapons"))
|
||||
return
|
||||
end
|
||||
|
||||
local stripped = {}
|
||||
|
||||
self:GetStrippableWeapons(ent, function(wep)
|
||||
local class = wep:GetClass()
|
||||
ent:StripWeapon(class)
|
||||
stripped[class] = {
|
||||
class = class,
|
||||
primaryAmmoCount = ent:GetAmmoCount(wep:GetPrimaryAmmoType()),
|
||||
primaryAmmoType = wep:GetPrimaryAmmoType(),
|
||||
secondaryAmmoCount = ent:GetAmmoCount(wep:GetSecondaryAmmoType()),
|
||||
secondaryAmmoType = wep:GetSecondaryAmmoType(),
|
||||
clip1 = wep:Clip1(),
|
||||
clip2 = wep:Clip2()
|
||||
}
|
||||
end)
|
||||
|
||||
if not ent.ConfiscatedWeapons then
|
||||
if next(stripped) ~= nil then ent.ConfiscatedWeapons = stripped end
|
||||
else
|
||||
-- Merge stripped weapons into confiscated weapons
|
||||
for k,v in pairs(stripped) do
|
||||
if ent.ConfiscatedWeapons[k] then continue end
|
||||
|
||||
ent.ConfiscatedWeapons[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
hook.Call("playerWeaponsConfiscated", nil, self:GetOwner(), ent, ent.ConfiscatedWeapons)
|
||||
|
||||
if next(stripped) ~= nil then
|
||||
self:EmitSound("npc/combine_soldier/gear5.wav", 50, 100)
|
||||
self:SetNextSoundTime(CurTime() + 0.3)
|
||||
else
|
||||
self:EmitSound("ambient/energy/zap1.wav", 50, 100)
|
||||
self:SetNextSoundTime(0)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:PrintWeapons(ent, weaponsFoundPhrase)
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
local result = {}
|
||||
local weps = {}
|
||||
self:GetStrippableWeapons(ent, function(wep)
|
||||
table.insert(weps, wep)
|
||||
end)
|
||||
|
||||
for _, wep in ipairs(weps) do
|
||||
table.insert(result, wep:GetPrintName() and language.GetPhrase(wep:GetPrintName()) or wep:GetClass())
|
||||
end
|
||||
|
||||
result = table.concat(result, ", ")
|
||||
|
||||
if result == "" then
|
||||
Owner:ChatPrint(DarkRP.getPhrase("no_illegal_weapons", ent:Nick()))
|
||||
return
|
||||
end
|
||||
|
||||
Owner:ChatPrint(weaponsFoundPhrase)
|
||||
if string.len(result) >= 126 then
|
||||
local amount = math.ceil(string.len(result) / 126)
|
||||
for i = 1, amount, 1 do
|
||||
Owner:ChatPrint(string.sub(result, (i-1) * 126, i * 126 - 1))
|
||||
end
|
||||
else
|
||||
Owner:ChatPrint(result)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Fail()
|
||||
self:SetIsWeaponChecking(false)
|
||||
self:SetHoldType("normal")
|
||||
self:SetNextSoundTime(0)
|
||||
end
|
||||
|
||||
function SWEP:Think()
|
||||
local Owner = self:GetOwner()
|
||||
|
||||
if not IsValid(Owner) then return end
|
||||
|
||||
if self:GetIsWeaponChecking() and self:GetEndCheckTime() ~= 0 then
|
||||
Owner:LagCompensation(true)
|
||||
local trace = Owner:GetEyeTrace()
|
||||
Owner:LagCompensation(false)
|
||||
if not IsValid(trace.Entity) or trace.HitPos:DistToSqr(Owner:GetShootPos()) > 10000 or not trace.Entity:IsPlayer() then
|
||||
self:Fail()
|
||||
end
|
||||
if self:GetEndCheckTime() <= CurTime() then
|
||||
self:Succeed()
|
||||
end
|
||||
end
|
||||
if self:GetNextSoundTime() ~= 0 and CurTime() >= self:GetNextSoundTime() then
|
||||
if self:GetIsWeaponChecking() then
|
||||
self:SetNextSoundTime(CurTime() + 0.5)
|
||||
self:EmitSound("npc/combine_soldier/gear5.wav", 100, 100)
|
||||
else
|
||||
self:SetNextSoundTime(0)
|
||||
self:EmitSound("npc/combine_soldier/gear5.wav", 50, 100)
|
||||
end
|
||||
end
|
||||
if CLIENT and self.NextDotsTime and CurTime() >= self.NextDotsTime then
|
||||
self.NextDotsTime = CurTime() + 0.5
|
||||
self.Dots = self.Dots or ""
|
||||
local len = string.len(self.Dots)
|
||||
local dots = {
|
||||
[0] = ".",
|
||||
[1] = "..",
|
||||
[2] = "...",
|
||||
[3] = ""
|
||||
}
|
||||
self.Dots = dots[len]
|
||||
end
|
||||
end
|
||||
|
||||
local colorBackground = Color(10, 10, 10, 120)
|
||||
|
||||
function SWEP:DrawHUD()
|
||||
if self:GetIsWeaponChecking() and self:GetEndCheckTime() ~= 0 then
|
||||
self.Dots = self.Dots or ""
|
||||
local w = ScrW()
|
||||
local h = ScrH()
|
||||
local x, y, width, height = w / 2 - w / 10, h / 2, w / 5, h / 15
|
||||
local time = self:GetEndCheckTime() - self:GetStartCheckTime()
|
||||
local curtime = CurTime() - self:GetStartCheckTime()
|
||||
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(8, x, y, width, height, colorBackground)
|
||||
draw.RoundedBox(cornerRadius, x + 8, y + 8, BarWidth, height - 16, Color(0, 0 + (status * 255), 255 - (status * 255), 255))
|
||||
draw.DrawNonParsedSimpleText(DarkRP.getPhrase("checking_weapons") .. self.Dots, "Trebuchet24", w / 2, y + height / 2, color_white, 1, 1)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user