mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
409 lines
13 KiB
Lua
409 lines
13 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
local ang0 = Angle(0, 0, 0)
|
|
local dev_alwaysready = ArcCW.ConVars["dev_alwaysready"]
|
|
|
|
function SWEP:Deploy()
|
|
if !IsValid(self:GetOwner()) or self:GetOwner():IsNPC() then
|
|
return
|
|
end
|
|
|
|
if self.UnReady then
|
|
local sp = game.SinglePlayer()
|
|
|
|
if sp then
|
|
if SERVER then
|
|
self:CallOnClient("LoadPreset", "autosave")
|
|
else
|
|
self:LoadPreset("autosave")
|
|
end
|
|
else
|
|
if SERVER then
|
|
-- the server... can't get the client's attachments in time.
|
|
-- can make it so client has to do a thing and tell the server it's ready,
|
|
-- and that's probably what i'll do later.
|
|
else
|
|
self:LoadPreset("autosave")
|
|
end
|
|
end
|
|
end
|
|
|
|
self:InitTimers()
|
|
|
|
self:SetShouldHoldType()
|
|
|
|
self:SetReloading(false)
|
|
self:SetPriorityAnim(false)
|
|
self:SetInUBGL(false)
|
|
self:SetMagUpCount(0)
|
|
self:SetMagUpIn(0)
|
|
self:SetShotgunReloading(0)
|
|
self:SetHolster_Time(0)
|
|
self:SetHolster_Entity(NULL)
|
|
|
|
self:SetFreeAimAngle(ang0)
|
|
self:SetLastAimAngle(ang0)
|
|
|
|
self.LHIKAnimation = nil
|
|
self.CrosshairDelta = 0
|
|
|
|
self:SetBurstCount(0)
|
|
|
|
self:WepSwitchCleanup()
|
|
if game.SinglePlayer() then self:CallOnClient("WepSwitchCleanup") end
|
|
|
|
if !self:GetOwner():InVehicle() then -- Don't play anim if in vehicle. This can be caused by HL2 level changes
|
|
local prd = false
|
|
|
|
local r_anim = self:SelectAnimation("ready")
|
|
local d_anim = self:SelectAnimation("draw")
|
|
|
|
if (CLIENT and !game.SinglePlayer() and LocalPlayer():IsListenServerHost()) then
|
|
self.ReadySoundTableHack = true
|
|
end
|
|
|
|
if self.Animations[r_anim] and ( dev_alwaysready:GetBool() or self.UnReady ) then
|
|
self:PlayAnimation(r_anim, 1, true, 0, false)
|
|
prd = self.Animations[r_anim].ProcDraw
|
|
|
|
self:SetPriorityAnim(CurTime() + self:GetAnimKeyTime(r_anim, true))
|
|
|
|
if CLIENT then
|
|
self:SetTimer(self:GetAnimKeyTime(r_anim, true), function() self.UnReady = false end, "UnReady")
|
|
end
|
|
elseif self.Animations[d_anim] then
|
|
self:PlayAnimation(d_anim, self:GetBuff_Mult("Mult_DrawTime"), true, 0, false)
|
|
prd = self.Animations[d_anim].ProcDraw
|
|
|
|
self:SetPriorityAnim(CurTime() + self:GetAnimKeyTime(d_anim, true) * self:GetBuff_Mult("Mult_DrawTime"))
|
|
end
|
|
|
|
if prd or (!self.Animations[r_anim] and !self.Animations[d_anim]) then
|
|
self:ProceduralDraw()
|
|
end
|
|
end
|
|
|
|
self:SetState(ArcCW.STATE_DISABLE)
|
|
|
|
if (SERVER or game.SinglePlayer()) and self.UnReady then
|
|
if SERVER then
|
|
self:InitialDefaultClip()
|
|
end
|
|
self.UnReady = false
|
|
end
|
|
|
|
if self:GetBuff_Override("Override_AutoReload", self.AutoReload) then
|
|
self:RestoreAmmo()
|
|
end
|
|
|
|
timer.Simple(0, function()
|
|
if IsValid(self) then self:SetupModel(false) end
|
|
end)
|
|
|
|
if SERVER then
|
|
self:SetupShields()
|
|
-- Networking the weapon at this time is too early - entity is not yet valid on client
|
|
-- Also not a good idea because networking many weapons will cause mass lag (e.g. TTT round setup)
|
|
-- Instead, make client send a request when it is valid there
|
|
--self:NetworkWeapon()
|
|
self:GetOwner():SetSaveValue("m_flNextAttack", 0) -- the magic fix-it-all solution for custom deploy problems including sounds
|
|
elseif CLIENT and !self.CertainAboutAtts and !self.AttReqSent and IsValid(self:GetOwner()) then
|
|
-- If client is aware of this weapon and it's not on the ground, ask for attachment info
|
|
-- If it is not on a player, delay networking until it is rendered (in cl_viewmodel)
|
|
-- print(self, "network weapon from sh_deploy")
|
|
self.AttReqSent = true
|
|
net.Start("arccw_rqwpnnet")
|
|
net.WriteEntity(self)
|
|
net.SendToServer()
|
|
end
|
|
|
|
-- self:RefreshBGs()
|
|
|
|
self:GetBuff_Hook("Hook_OnDeploy")
|
|
|
|
return true
|
|
end
|
|
|
|
function SWEP:ResetCheckpoints()
|
|
self.CheckpointAnimation = nil
|
|
|
|
if game.SinglePlayer() and SERVER then
|
|
net.Start("arccw_sp_checkpoints")
|
|
net.Broadcast()
|
|
end
|
|
end
|
|
|
|
function SWEP:InitialDefaultClip()
|
|
if !self.Primary.Ammo then return end
|
|
if engine.ActiveGamemode() == "darkrp" then return end -- DarkRP is god's second biggest mistake after gmod
|
|
|
|
if self:GetOwner() and self:GetOwner():IsPlayer() then
|
|
if self:HasBottomlessClip() then
|
|
self:SetClip1(0)
|
|
end
|
|
if self.ForceDefaultAmmo then
|
|
self:GetOwner():GiveAmmo(self.ForceDefaultAmmo, self.Primary.Ammo)
|
|
elseif engine.ActiveGamemode() != "terrortown" then
|
|
self:GetOwner():GiveAmmo(self:GetCapacity() * ArcCW.ConVars["mult_defaultammo"]:GetInt(), self.Primary.Ammo)
|
|
end
|
|
end
|
|
end
|
|
|
|
function SWEP:Initialize()
|
|
if SERVER and game.SinglePlayer() and IsValid(self:GetOwner()) and self:GetOwner():IsPlayer() then
|
|
self:CallOnClient("Initialize")
|
|
end
|
|
|
|
if CLIENT then
|
|
local class = self:GetClass()
|
|
|
|
if self.KillIconAlias then
|
|
killicon.AddAlias(class, self.KillIconAlias)
|
|
class = self.KillIconAlias
|
|
end
|
|
|
|
local path = "arccw/weaponicons/" .. class
|
|
local mat = Material(path)
|
|
|
|
if !mat:IsError() then
|
|
|
|
local tex = mat:GetTexture("$basetexture")
|
|
if tex then
|
|
local texpath = tex:GetName()
|
|
killicon.Add(class, texpath, Color(255, 255, 255))
|
|
self.WepSelectIcon = surface.GetTextureID(texpath)
|
|
|
|
if self.ShootEntity then
|
|
killicon.Add(self.ShootEntity, texpath, Color(255, 255, 255))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Check for incompatibile addons once
|
|
if LocalPlayer().ArcCW_IncompatibilityCheck != true and game.SinglePlayer() then
|
|
LocalPlayer().ArcCW_IncompatibilityCheck = true
|
|
|
|
local incompatList = {}
|
|
local addons = engine.GetAddons()
|
|
for _, addon in pairs(addons) do
|
|
if ArcCW.IncompatibleAddons[tostring(addon.wsid)] and addon.mounted then
|
|
incompatList[tostring(addon.wsid)] = addon
|
|
end
|
|
end
|
|
|
|
local predrawvmhooks = hook.GetTable().PreDrawViewModel
|
|
if predrawvmhooks and (predrawvmhooks.DisplayDistancePlaneLS or predrawvmhooks.DisplayDistancePlane) then -- vtools lua breaks arccw with stupid return in vm hook, ya dont need it if you going to play with guns
|
|
hook.Remove("PreDrawViewModel", "DisplayDistancePlane")
|
|
hook.Remove("PreDrawViewModel", "DisplayDistancePlaneLS")
|
|
incompatList["DisplayDistancePlane"] = {
|
|
title = "Light Sprayer / Scenic Dispenser tool",
|
|
wsid = "DisplayDistancePlane",
|
|
nourl = true,
|
|
}
|
|
end
|
|
local shouldDo = true
|
|
-- If never show again is on, verify we have no new addons
|
|
if file.Exists("arccw_incompatible.txt", "DATA") then
|
|
shouldDo = false
|
|
local oldTbl = util.JSONToTable(file.Read("arccw_incompatible.txt"))
|
|
for id, addon in pairs(incompatList) do
|
|
if !oldTbl[id] then shouldDo = true break end
|
|
end
|
|
if shouldDo then file.Delete("arccw_incompatible.txt") end
|
|
end
|
|
if shouldDo and !table.IsEmpty(incompatList) then
|
|
ArcCW.MakeIncompatibleWindow(incompatList)
|
|
elseif !table.IsEmpty(incompatList) then
|
|
print("ArcCW ignored " .. table.Count(incompatList) .. " incompatible addons. If things break, it's your fault.")
|
|
end
|
|
end
|
|
end
|
|
|
|
if ArcCW.ConVars["equipmentsingleton"]:GetBool() and self.Throwing then
|
|
self.Singleton = true
|
|
self.Primary.ClipSize = -1
|
|
self.Primary.Ammo = ""
|
|
end
|
|
|
|
self:SetState(0)
|
|
self:SetClip2(0)
|
|
self:SetLastLoad(self:Clip1())
|
|
|
|
self.Attachments["BaseClass"] = nil
|
|
|
|
if !self:GetOwner():IsNPC() then
|
|
self:SetHoldType(self.HoldtypeActive)
|
|
end
|
|
|
|
local og = weapons.Get(self:GetClass())
|
|
|
|
self.RegularClipSize = og.Primary.ClipSize
|
|
|
|
self.OldPrintName = self.PrintName
|
|
|
|
self:InitTimers()
|
|
|
|
if engine.ActiveGamemode() == "terrortown" then
|
|
self:TTT_Init()
|
|
end
|
|
|
|
hook.Run("ArcCW_WeaponInit", self)
|
|
|
|
if (!IsValid(self:GetOwner()) or self:GetOwner():IsNPC()) and self:IsValid() and self.NPC_Initialize then
|
|
self:NPC_Initialize()
|
|
else
|
|
self:AdjustAtts()
|
|
self:RefreshBGs()
|
|
end
|
|
end
|
|
|
|
function SWEP:Holster(wep)
|
|
if !IsFirstTimePredicted() then return end
|
|
if self:GetOwner():IsNPC() then return end
|
|
|
|
if CLIENT and self:GetOwner() == LocalPlayer() and ArcCW.InvHUD then ArcCW.InvHUD:Remove() end
|
|
|
|
if self:GetBurstCount() > 0 and self:Clip1() > self:GetBuff("AmmoPerShot") then return false end
|
|
|
|
if CLIENT and LocalPlayer() != self:GetOwner() then
|
|
return
|
|
end
|
|
|
|
if self:GetGrenadePrimed() then
|
|
self:GrenadeDrop(true)
|
|
end
|
|
|
|
self:WepSwitchCleanup()
|
|
if game.SinglePlayer() then self:CallOnClient("WepSwitchCleanup") end
|
|
|
|
if wep == self then self:Deploy() return false end
|
|
if self:GetHolster_Time() > CurTime() then return false end
|
|
|
|
self.UnReady = false
|
|
|
|
-- Props deploy to NULL, finish holster on NULL too
|
|
if (self:GetHolster_Time() != 0 and self:GetHolster_Time() <= CurTime()) or !IsValid(wep) then
|
|
self:SetHolster_Time(0)
|
|
self:SetHolster_Entity(NULL)
|
|
self:FinishHolster()
|
|
self:GetBuff_Hook("Hook_OnHolsterEnd")
|
|
return true
|
|
else
|
|
self:SetHolster_Entity(wep)
|
|
|
|
if self:GetGrenadePrimed() then
|
|
self:Throw()
|
|
end
|
|
|
|
self.Sighted = false
|
|
self.Sprinted = false
|
|
self:SetShotgunReloading(0)
|
|
self:SetMagUpCount(0)
|
|
self:SetMagUpIn(0)
|
|
|
|
local time = 0.25
|
|
local anim = self:SelectAnimation("holster")
|
|
if anim then
|
|
local prd = self.Animations[anim].ProcHolster
|
|
time = self:GetAnimKeyTime(anim)
|
|
if prd then
|
|
self:ProceduralHolster()
|
|
time = 0.25
|
|
end
|
|
self:PlayAnimation(anim, self:GetBuff_Mult("Mult_DrawTime"), true, nil, nil, nil, true)
|
|
self:SetHolster_Time(CurTime() + time * self:GetBuff_Mult("Mult_DrawTime"))
|
|
else
|
|
self:ProceduralHolster()
|
|
self:SetHolster_Time(CurTime() + time * self:GetBuff_Mult("Mult_DrawTime"))
|
|
end
|
|
self:SetPriorityAnim(CurTime() + time * self:GetBuff_Mult("Mult_DrawTime"))
|
|
self:SetWeaponOpDelay(CurTime() + time * self:GetBuff_Mult("Mult_DrawTime"))
|
|
|
|
self:GetBuff_Hook("Hook_OnHolster")
|
|
end
|
|
end
|
|
|
|
function SWEP:FinishHolster()
|
|
self:KillTimers()
|
|
|
|
if CLIENT then
|
|
self:KillFlashlights()
|
|
else
|
|
if self:GetBuff_Override("UBGL_UnloadOnDequip") then
|
|
local clip = self:Clip2()
|
|
|
|
local ammo = self:GetBuff_Override("UBGL_Ammo") or "smg1_grenade"
|
|
|
|
if IsValid(self:GetOwner()) then
|
|
self:GetOwner():GiveAmmo(clip, ammo, true)
|
|
end
|
|
|
|
self:SetClip2(0)
|
|
end
|
|
|
|
self:KillShields()
|
|
|
|
local vm = self:GetOwner():GetViewModel()
|
|
if IsValid(vm) then
|
|
for i = 0, vm:GetNumBodyGroups() do
|
|
vm:SetBodygroup(i, 0)
|
|
end
|
|
vm:SetSkin(0)
|
|
vm:SetPlaybackRate(1)
|
|
end
|
|
|
|
if self.Disposable and self:Clip1() == 0 and self:Ammo1() == 0 then
|
|
self:GetOwner():StripWeapon(self:GetClass())
|
|
end
|
|
end
|
|
end
|
|
|
|
-- doesn't work if they dont call in prediction blah blah
|
|
|
|
function SWEP:ProceduralDraw()
|
|
if SERVER and self:GetOwner():IsValid() then
|
|
self:CallOnClient("ProceduralDraw")
|
|
end
|
|
|
|
self.InProcDraw = true
|
|
self.ProcDrawTime = CurTime()
|
|
end
|
|
|
|
function SWEP:ProceduralHolster()
|
|
if SERVER and self:GetOwner():IsValid() then
|
|
self:CallOnClient("ProceduralHolster")
|
|
end
|
|
|
|
self.InProcHolster = true
|
|
self.ProcHolsterTime = CurTime()
|
|
end
|
|
|
|
function SWEP:WepSwitchCleanup()
|
|
-- table.Empty(self.EventTable)
|
|
self.InProcDraw = false
|
|
self.InProcHolster = false
|
|
end
|
|
|
|
function SWEP:ProceduralBash()
|
|
if game.SinglePlayer() and self:GetOwner():IsValid() then
|
|
self:CallOnClient("ProceduralBash")
|
|
end
|
|
|
|
local mult = self:GetBuff_Mult("Mult_MeleeTime")
|
|
local mt = self.MeleeTime * mult
|
|
|
|
self.InProcBash = true
|
|
self.ProcBashTime = CurTime()
|
|
self:SetTimer(mt, function()
|
|
self.InProcBash = false
|
|
end)
|
|
end
|