Initial commit
This commit is contained in:
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user