357 lines
9.3 KiB
Lua
357 lines
9.3 KiB
Lua
SWEP.Weight = 5
|
|
SWEP.DrawAmmo = true
|
|
SWEP.DrawCrosshair = false
|
|
SWEP.CSMuzzleFlashes = true
|
|
|
|
SWEP.Base = 'weapon_base'
|
|
SWEP.IsQWB = true
|
|
|
|
SWEP.Author = 'qurs'
|
|
SWEP.Contact = ''
|
|
SWEP.Purpose = ''
|
|
SWEP.Instructions = ''
|
|
|
|
SWEP.ViewModel = 'models/weapons/v_knife_t.mdl'
|
|
SWEP.DefaultScopeMat = Material('materials/qwb/scope/awp.png')
|
|
|
|
SWEP.Category = 'qurs\' weapons base'
|
|
|
|
SWEP.Spawnable = false
|
|
SWEP.UseHands = true
|
|
|
|
SWEP.Secondary.ClipSize = -1
|
|
SWEP.Secondary.DefaultClip = 0
|
|
SWEP.Secondary.Automatic = false
|
|
SWEP.Secondary.Ammo = 'none'
|
|
|
|
SWEP.ShellType = '9mm'
|
|
|
|
SWEP.SafetyStanceSound = Sound('weapons/smg1/switch_single.wav')
|
|
|
|
local angle_zero = Angle()
|
|
|
|
local passiveHoldTypes = {
|
|
revolver = 'normal',
|
|
ar2 = 'passive',
|
|
smg = 'passive',
|
|
}
|
|
|
|
-- Thanks to octothorp team for this solution, which calculates the shot position
|
|
local defaultBulletPosAng = {
|
|
default = { Vector(7.7, 0.4, 3.95), Angle(-3, 5.5, 0) },
|
|
|
|
revolver = { Vector(7.7, 0.4, 3.95), Angle(-3, 5.5, 0) },
|
|
ar2 = { Vector(20, -0.8, 11.2), Angle(-9.5, 0, 0) },
|
|
smg = { Vector(14, -0.8, 6.8), Angle(-9.5, 0, 0) },
|
|
}
|
|
|
|
function SWEP:CalculatePassiveHoldType()
|
|
return passiveHoldTypes[self.HoldType] or 'normal'
|
|
end
|
|
|
|
function SWEP:SafetyStanceChanged(_, old, new)
|
|
self:GetOwner():EmitSound(self.SafetyStanceSound)
|
|
|
|
if new == true then
|
|
self:SetHoldType(self.PassiveHoldType or self:CalculatePassiveHoldType())
|
|
else
|
|
self:SetHoldType(self.HoldType)
|
|
end
|
|
end
|
|
|
|
function SWEP:SetupDataTables()
|
|
self:NetworkVar('Bool', 0, 'SafetyStance')
|
|
|
|
self:NetworkVar('Vector', 0, 'LocalMuzzlePos')
|
|
self:NetworkVar('Angle', 0, 'LocalMuzzleAng')
|
|
|
|
if SERVER then
|
|
self:NetworkVarNotify('SafetyStance', self.SafetyStanceChanged)
|
|
end
|
|
end
|
|
|
|
function SWEP:Initialize()
|
|
self:SetHoldType(self.HoldType)
|
|
|
|
local lpos, lang = unpack( defaultBulletPosAng[ self:GetHoldType() ] or defaultBulletPosAng.default )
|
|
|
|
self._sourceLocalMuzzlePos = self.ShootPos or lpos
|
|
self._sourceLocalMuzzleAng = self.ShootAng or lang
|
|
|
|
if CLIENT then return end
|
|
|
|
self:SetLocalMuzzlePos(self._sourceLocalMuzzlePos)
|
|
self:SetLocalMuzzleAng(self._sourceLocalMuzzleAng)
|
|
end
|
|
|
|
function SWEP:Deploy()
|
|
return true
|
|
end
|
|
|
|
function SWEP:Holster()
|
|
if SERVER then
|
|
self.Ironsighted = false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function SWEP:OnRemove()
|
|
self:Holster()
|
|
end
|
|
|
|
function SWEP:Reload()
|
|
if not IsFirstTimePredicted() then return end
|
|
|
|
local owner = self:GetOwner()
|
|
if not IsValid(owner) then return end
|
|
|
|
if owner:KeyDown(IN_USE) then return end
|
|
if qwb.isPlayerRunning(owner) then return end
|
|
|
|
if not self:DefaultReload(ACT_VM_RELOAD) then return end
|
|
owner:SetAnimation(PLAYER_RELOAD)
|
|
|
|
if SERVER then
|
|
self.Ironsighted = false
|
|
|
|
net.Start('qwb.setIronsight')
|
|
net.WriteBool(self.Ironsighted)
|
|
net.Send(owner)
|
|
end
|
|
|
|
self:SetNextPrimaryFire(CurTime() + 2)
|
|
end
|
|
|
|
function SWEP:GetMuzzlePos()
|
|
local owner = self:GetOwner()
|
|
if not IsValid(owner) then return end
|
|
|
|
local att = owner:GetAttachment( owner:LookupAttachment('anim_attachment_rh') )
|
|
if not att then return end
|
|
|
|
local lpos, lang = self:GetLocalMuzzlePos(), self:GetLocalMuzzleAng()
|
|
local pos, ang = LocalToWorld(lpos, lang, att.Pos, att.Ang)
|
|
|
|
return pos, ang
|
|
end
|
|
|
|
function SWEP:GetBoneAng()
|
|
local ang = self:GetLocalMuzzleAng()
|
|
local sourceAng = self._sourceLocalMuzzleAng
|
|
local pitch = ang.p - sourceAng.p
|
|
|
|
return Angle(-pitch, 0, 0)
|
|
end
|
|
|
|
function SWEP:GetBulletSourcePos()
|
|
return self:GetMuzzlePos()
|
|
end
|
|
|
|
function SWEP:ShootBullet( src, dir, num_bullets, aimcone, tracer )
|
|
local bullet = {}
|
|
bullet.Num = num_bullets
|
|
bullet.Src = src
|
|
bullet.Dir = dir
|
|
bullet.Spread = Vector( aimcone, aimcone, 0 )
|
|
bullet.Tracer = tracer or 5
|
|
bullet.Force = 1
|
|
bullet.Damage = self.Primary.Damage
|
|
bullet.AmmoType = self.Primary.Ammo
|
|
bullet.TracerName = self.TracerName
|
|
|
|
self:GetOwner():FireBullets( bullet )
|
|
self:TakePrimaryAmmo(1)
|
|
|
|
self:ShootEffects()
|
|
end
|
|
|
|
function SWEP:MuzzleFlashCustom()
|
|
if SERVER then
|
|
net.Start('qwb.muzzleFlashLight')
|
|
net.WriteEntity(self)
|
|
net.SendPVS(self:GetBulletSourcePos())
|
|
|
|
return
|
|
end
|
|
|
|
local effectData = EffectData()
|
|
effectData:SetEntity(self)
|
|
effectData:SetFlags(1)
|
|
|
|
util.Effect('MuzzleFlash', effectData)
|
|
end
|
|
|
|
function SWEP:ShellEffect()
|
|
if SERVER then return end
|
|
if self.NoShell then return end
|
|
|
|
local shellType = self.ShellType
|
|
|
|
local effectData = EffectData()
|
|
|
|
local pos = self:GetPos()
|
|
if self.ShellOffset then
|
|
local att = self:GetAttachment( self:LookupAttachment('muzzle') )
|
|
if att then
|
|
pos = LocalToWorld(self.ShellOffset, angle_zero, att.Pos, att.Ang)
|
|
end
|
|
end
|
|
|
|
effectData:SetOrigin(pos)
|
|
effectData:SetFlags(self.ShellVelocity or 75)
|
|
|
|
util.Effect('EjectBrass_' .. shellType, effectData)
|
|
end
|
|
|
|
function SWEP:ShootEffects()
|
|
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
|
|
self:MuzzleFlashCustom()
|
|
self:ShellEffect()
|
|
|
|
self:EmitSound( self.Primary.Sound )
|
|
|
|
self.RecoilAnimBack = nil
|
|
self.RecoilAnim = true
|
|
end
|
|
|
|
function SWEP:PrimaryAttack()
|
|
if not self:CanPrimaryAttack() then return end
|
|
if not IsValid(self) or not IsValid(self:GetOwner()) then return end
|
|
local owner = self:GetOwner()
|
|
|
|
local pos, ang = self:GetBulletSourcePos()
|
|
if not pos or not ang then return end
|
|
|
|
local forward = ang:Forward()
|
|
|
|
owner:LagCompensation(true)
|
|
self:ShootBullet(pos, forward, self.Primary.NumShots or 1, 0, 1) -- pre-last self.Primary.Spread or 0.01
|
|
owner:LagCompensation(false)
|
|
|
|
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
|
|
|
if SERVER then self:CreateShootRage() end
|
|
|
|
-- if not self.IronSighted and self.HipFireRecoil then
|
|
-- local pitch = math.random() >= 0.5 and -self.HipFireRecoil or self.HipFireRecoil
|
|
-- local yaw = math.random() >= 0.5 and -self.HipFireRecoil or self.HipFireRecoil
|
|
-- local roll = math.random() >= 0.5 and -self.HipFireRecoil or self.HipFireRecoil
|
|
|
|
-- owner:SetViewPunchAngles(Angle(pitch, yaw, roll))
|
|
-- end
|
|
|
|
if self.PostPrimaryAttack then self:PostPrimaryAttack() end
|
|
end
|
|
|
|
function SWEP:CanPrimaryAttack()
|
|
if self:GetSafetyStance() then return end
|
|
|
|
local owner = self:GetOwner()
|
|
if not IsValid(owner) then return end
|
|
|
|
if qwb.isPlayerRunning(owner) then return end
|
|
|
|
if self:Clip1() <= 0 then
|
|
self:EmitSound('weapons/clipempty_rifle.wav')
|
|
self:SetNextPrimaryFire(CurTime() + 0.7)
|
|
|
|
return false
|
|
end
|
|
|
|
if owner:WaterLevel() > 2 then return false end
|
|
|
|
return true
|
|
end
|
|
|
|
function SWEP:Think()
|
|
local owner = self:GetOwner()
|
|
if not IsValid(self:GetOwner()) then return end
|
|
|
|
if owner:KeyDown(IN_USE) and owner:KeyDown(IN_RELOAD) and (not self.SafetyStanceCD or CurTime() >= self.SafetyStanceCD) then
|
|
self.SafetyStanceCD = CurTime() + 0.4
|
|
self:SetSafetyStance( not self:GetSafetyStance() )
|
|
end
|
|
|
|
local passiveHoldType = self.PassiveHoldType or self:CalculatePassiveHoldType()
|
|
if qwb.isPlayerRunning(owner) and self:GetHoldType() ~= passiveHoldType then
|
|
self:SetHoldType(passiveHoldType)
|
|
|
|
if self.Ironsighted then self.Ironsighted = false end
|
|
elseif not qwb.isPlayerRunning(owner) and not self:GetSafetyStance() and self:GetHoldType() == passiveHoldType then
|
|
self:SetHoldType(self.HoldType)
|
|
end
|
|
|
|
if not self.ShootRageDelta then self.ShootRageDelta = 0 end
|
|
|
|
if self.ShootRage and self.ShootRage > 0 then
|
|
self.ShootRageDelta = self.ShootRageDelta + 0.2
|
|
|
|
self.ShootRage = self.ShootRage - 0.05
|
|
if self.ShootRage < 0 then self.ShootRage = 0 end
|
|
else
|
|
self.ShootRageDelta = 0
|
|
end
|
|
|
|
if self.RecoilAnim then
|
|
local bone = owner:LookupBone('ValveBiped.Bip01_R_Hand')
|
|
local bone2 = owner:LookupBone('ValveBiped.Bip01_R_UpperArm')
|
|
local needle = Angle(self.Recoil / 50 * 90, 0, 0)
|
|
local needle2 = Angle(0, (self.ShootRage or 0) * math.sin(self.ShootRageDelta or 0), 0)
|
|
|
|
owner:ManipulateBoneAngles( bone, LerpAngle(0.8, owner:GetManipulateBoneAngles(bone), needle), true )
|
|
owner:ManipulateBoneAngles( bone2, LerpAngle(0.45, owner:GetManipulateBoneAngles(bone2), needle2), true )
|
|
|
|
local ang = owner:GetManipulateBoneAngles(bone)
|
|
if math.abs(ang[1] - needle[1]) <= 0.1 then
|
|
self.RecoilAnim = nil
|
|
self.RecoilAnimBack = true
|
|
end
|
|
elseif self.RecoilAnimBack then
|
|
local bone = owner:LookupBone('ValveBiped.Bip01_R_Hand')
|
|
local bone2 = owner:LookupBone('ValveBiped.Bip01_R_UpperArm')
|
|
local needle = Angle(0, 0, 0)
|
|
local needle2 = Angle(0, (self.ShootRage or 0) * math.sin(self.ShootRageDelta or 0), 0)
|
|
|
|
owner:ManipulateBoneAngles( bone, LerpAngle(0.1, owner:GetManipulateBoneAngles(bone), needle), true )
|
|
owner:ManipulateBoneAngles( bone2, LerpAngle(0.1, owner:GetManipulateBoneAngles(bone2), needle2), true )
|
|
|
|
local ang = owner:GetManipulateBoneAngles(bone)
|
|
if math.abs(ang[1] - needle[1]) <= 0.1 then
|
|
self.RecoilAnimBack = nil
|
|
end
|
|
end
|
|
|
|
-- if CLIENT then
|
|
-- local bone = owner:LookupBone('ValveBiped.Bip01_R_Hand')
|
|
-- local ang = self:GetBoneAng()
|
|
-- owner:ManipulateBoneAngles(bone, ang)
|
|
-- end
|
|
|
|
-- if CLIENT then return end
|
|
|
|
-- if owner.RecoilAnim then
|
|
-- local curAng = self:GetLocalMuzzleAng()
|
|
-- local sourceAng = self._sourceLocalMuzzleAng
|
|
|
|
-- local needle = Angle(sourceAng[1] - (self.Recoil / 50 * 90), curAng[2], curAng[3])
|
|
|
|
-- self:SetLocalMuzzleAng( LerpAngle(0.8, self:GetLocalMuzzleAng(), needle) )
|
|
|
|
-- local ang = self:GetLocalMuzzleAng()
|
|
-- if math.abs(ang[1] - needle[1]) <= 0.1 then
|
|
-- owner.RecoilAnim = nil
|
|
-- owner.RecoilAnimBack = true
|
|
-- end
|
|
-- elseif owner.RecoilAnimBack then
|
|
-- local needle = self._sourceLocalMuzzleAng
|
|
|
|
-- self:SetLocalMuzzleAng( LerpAngle(0.025, self:GetLocalMuzzleAng(), needle) )
|
|
|
|
-- local ang = self:GetLocalMuzzleAng()
|
|
-- if math.abs(ang[1] - needle[1]) <= 0.1 then
|
|
-- owner.RecoilAnimBack = nil
|
|
-- end
|
|
-- end
|
|
end
|