mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
415
lua/weapons/arccw_base/sv_npc.lua
Normal file
415
lua/weapons/arccw_base/sv_npc.lua
Normal file
@@ -0,0 +1,415 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
-- NPC integration
|
||||
|
||||
function SWEP:NPC_Initialize()
|
||||
if CLIENT then return end
|
||||
|
||||
if !IsValid(self:GetOwner()) then return end
|
||||
if !self:GetOwner():IsNPC() then return end
|
||||
|
||||
self:NPC_SetupAttachments()
|
||||
|
||||
self:SetHoldType(self.HoldtypeNPC or self:GetBuff_Override("Override_HoldtypeActive") or self.HoldtypeActive)
|
||||
|
||||
self:SetNextPrimaryFire(CurTime())
|
||||
|
||||
self:SetClip1(self:GetCapacity() or self.Primary.ClipSize)
|
||||
|
||||
-- print(self:Clip1())
|
||||
|
||||
local range = self:GetBuff("Range") / ArcCW.HUToM
|
||||
|
||||
if self:GetBuff("DamageMin") >= self:GetBuff("Damage") or (self:GetBuff_Override("Override_ManualAction") or self.ManualAction) and self:GetBuff("Num") == 1 then
|
||||
range = math.max(range, 10000) * 2
|
||||
end
|
||||
|
||||
range = math.Clamp(range, 2048, 36000)
|
||||
|
||||
self:GetOwner():Input("SetMaxLookDistance", nil, nil, range)
|
||||
|
||||
self:SetNextPrimaryFire(CurTime())
|
||||
self:SetNextSecondaryFire(CurTime() + 30)
|
||||
self:GetOwner():NextThink(CurTime())
|
||||
end
|
||||
|
||||
function SWEP:AssignRandomAttToSlot(slot)
|
||||
if slot.DoNotRandomize then return end
|
||||
if slot.Installed then return end
|
||||
|
||||
local att = ArcCW:RollRandomAttachment(true, self, slot)
|
||||
if !att then return end
|
||||
slot.Installed = att
|
||||
|
||||
local atttbl = ArcCW.AttachmentTable[slot.Installed]
|
||||
|
||||
--if !ArcCW:SlotAcceptsAtt(slot.Slot, self, slot.Installed) then return end
|
||||
--if !self:CheckFlags(atttbl.ExcludeFlags, atttbl.RequireFlags) then return end
|
||||
|
||||
if atttbl.MountPositionOverride then
|
||||
slot.SlidePos = atttbl.MountPositionOverride
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:NPC_SetupAttachments()
|
||||
if self:GetOwner():IsNPC() and !ArcCW.ConVars["npc_atts"]:GetBool() then return end
|
||||
|
||||
local pick = self:GetPickX()
|
||||
|
||||
local chance = 25 * ArcCW.ConVars["mult_attchance"]:GetFloat()
|
||||
local chancestep = 0
|
||||
|
||||
if pick > 0 then
|
||||
chancestep = chance / pick
|
||||
--chance = chancestep
|
||||
else
|
||||
pick = 1000
|
||||
end
|
||||
|
||||
local n = 0
|
||||
|
||||
for i, slot in pairs(self.Attachments) do
|
||||
if n > pick then continue end
|
||||
if !self:CheckFlags(slot.ExcludeFlags, slot.RequireFlags) then continue end
|
||||
if math.Rand(0, 100) > (chance * (slot.RandomChance or 1)) then continue end
|
||||
|
||||
if slot.Hidden then continue end
|
||||
|
||||
local s = i
|
||||
|
||||
if slot.MergeSlots then
|
||||
local ss = {i}
|
||||
table.Add(ss, slot.MergeSlots)
|
||||
|
||||
s = table.Random(ss) or i
|
||||
end
|
||||
if !self.Attachments[s] then s = i end
|
||||
|
||||
chance = chance - chancestep
|
||||
|
||||
self:AssignRandomAttToSlot(self.Attachments[s])
|
||||
|
||||
n = n + 1
|
||||
end
|
||||
|
||||
self.ActiveElementCache = nil -- Reset cache so we have the proper attachments to check with
|
||||
for i, slot in pairs(self.Attachments) do
|
||||
if !slot.Installed then continue end
|
||||
local atttbl = ArcCW.AttachmentTable[slot.Installed]
|
||||
if !ArcCW:SlotAcceptsAtt(slot.Slot, self, slot.Installed) then slot.Installed = nil continue end
|
||||
if !self:CheckFlags(slot.ExcludeFlags, slot.RequireFlags) then slot.Installed = nil continue end
|
||||
if !self:CheckFlags(atttbl.ExcludeFlags, atttbl.RequireFlags) then slot.Installed = nil continue end
|
||||
end
|
||||
|
||||
if self:GetBuff_Override("UBGL") and self:GetBuff_Override("UBGL_Capacity") then
|
||||
self:SetClip2(self:GetBuff_Override("UBGL_Capacity"))
|
||||
end
|
||||
|
||||
self:AdjustAtts()
|
||||
self:RefreshBGs()
|
||||
|
||||
if self:GetOwner():IsNPC() then
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:NetworkWeapon()
|
||||
end)
|
||||
else
|
||||
self:NetworkWeapon()
|
||||
self:SetupModel(false)
|
||||
self:SetupModel(true)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:NPC_Shoot()
|
||||
-- if self:GetNextPrimaryFire() > CurTime() then return end
|
||||
|
||||
if !IsValid(self:GetOwner()) then return end
|
||||
if self:Clip1() <= 0 then self:GetOwner():SetSchedule(SCHED_HIDE_AND_RELOAD) return end
|
||||
|
||||
if self:GetOwner().ArcCW_Smoked then return end
|
||||
|
||||
|
||||
self.Primary.Automatic = true
|
||||
|
||||
|
||||
local delay = self:GetFiringDelay()
|
||||
|
||||
if (self:GetBuff_Override("Override_ManualAction") or self.ManualAction) then
|
||||
delay = self:GetAnimKeyTime("cycle", true) * self:GetBuff("CycleTime")
|
||||
end
|
||||
|
||||
local num = self:GetBuff("Num")
|
||||
|
||||
if num > 0 then
|
||||
local spread = ArcCW.MOAToAcc * self:GetBuff("AccuracyMOA")
|
||||
|
||||
local btabl = {
|
||||
Attacker = self:GetOwner(),
|
||||
Damage = 0,
|
||||
Force = 1,
|
||||
Distance = 33000,
|
||||
Num = num,
|
||||
Tracer = self.TracerNum,
|
||||
AmmoType = self.Primary.Ammo,
|
||||
Dir = self:GetOwner():GetAimVector(),
|
||||
Src = self:GetShootSrc(),
|
||||
Spread = Vector(spread, spread, spread),
|
||||
Callback = function(att, tr, dmg)
|
||||
ArcCW:BulletCallback(att, tr, dmg, self)
|
||||
end,
|
||||
--[[]
|
||||
Callback = function(att, tr, dmg)
|
||||
local dist = (tr.HitPos - tr.StartPos):Length() * ArcCW.HUToM
|
||||
|
||||
local pen = self:GetBuff("Penetration")
|
||||
|
||||
-- local frags = math.random(1, self.Frangibility)
|
||||
|
||||
-- for i = 1, frags do
|
||||
-- self:DoPenetration(tr, (self.Penetration / frags) - 0.5, tr.Entity)
|
||||
-- end
|
||||
|
||||
if self.DamageMin > self.Damage then
|
||||
dist = -dist + self.Range + self.Range
|
||||
end
|
||||
|
||||
local m = 1 * self:GetBuff_Mult("Mult_DamageNPC")
|
||||
|
||||
local ret = self:GetBuff_Hook("Hook_BulletHit", {
|
||||
range = dist,
|
||||
damage = self:GetDamage(dist, true) * m,
|
||||
dmgtype = self:GetBuff_Override("Override_DamageType") or self.DamageType,
|
||||
penleft = pen,
|
||||
att = att,
|
||||
tr = tr,
|
||||
dmg = dmg
|
||||
})
|
||||
|
||||
if !ret then return end
|
||||
|
||||
dmg:SetDamageType(ret.dmgtype)
|
||||
dmg:SetDamage(ret.damage)
|
||||
|
||||
if dmg:IsDamageType(DMG_BURN) and hit.range <= self.Range then
|
||||
dmg:SetDamageType(dmg:GetDamageType() - DMG_BURN)
|
||||
|
||||
local fx = EffectData()
|
||||
fx:SetOrigin(tr.HitPos)
|
||||
util.Effect("arccw_incendiaryround", fx)
|
||||
|
||||
util.Decal("FadingScorch", tr.StartPos, tr.HitPos - (tr.HitNormal * 16), self:GetOwner())
|
||||
|
||||
tr.Entity:Ignite(1, 32)
|
||||
end
|
||||
end
|
||||
]]
|
||||
}
|
||||
|
||||
local sp = self:GetBuff_Override("Override_ShotgunSpreadPattern") or self.ShotgunSpreadPattern
|
||||
local spo = self:GetBuff_Override("Override_ShotgunSpreadPatternOverrun") or self.ShotgunSpreadPatternOverrun
|
||||
local se = self:GetBuff_Override("Override_ShootEntity") or self.ShootEntity
|
||||
|
||||
if sp or spo then
|
||||
btabl = self:GetBuff_Hook("Hook_FireBullets", btabl)
|
||||
|
||||
if !btabl then return end
|
||||
if btabl.Num == 0 then return end
|
||||
|
||||
for n = 1, btabl.Num do
|
||||
btabl.Num = 1
|
||||
local ang = self:GetOwner():GetAimVector():Angle() + self:GetShotgunSpreadOffset(n)
|
||||
|
||||
btabl.Dir = ang:Forward()
|
||||
|
||||
self:DoPrimaryFire(false, btabl)
|
||||
end
|
||||
elseif se then
|
||||
self:FireRocket(se, self:GetBuff("MuzzleVelocity"))
|
||||
else
|
||||
self:GetBuff_Hook("Hook_FireBullets", btabl)
|
||||
|
||||
for n = 1, btabl.Num do
|
||||
btabl.Num = 1
|
||||
|
||||
local dispers = self:GetBuff_Override("Override_ShotgunSpreadDispersion", self.ShotgunSpreadDispersion)
|
||||
local offset = self:GetShotgunSpreadOffset(n)
|
||||
local calcoff = dispers and (offset * self:GetDispersion() * ArcCW.MOAToAcc / 10) or offset
|
||||
|
||||
local ang = self:GetOwner():GetAimVector():Angle()
|
||||
-- ang:RotateAroundAxis(ang:Right(), -1 * calcoff.p)
|
||||
-- ang:RotateAroundAxis(ang:Up(), calcoff.y)
|
||||
-- ang:RotateAroundAxis(ang:Forward(), calcoff.r)
|
||||
|
||||
btabl.Dir = ang:Forward()
|
||||
|
||||
self:DoPrimaryFire(false, btabl)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:DoEffects()
|
||||
|
||||
if !self.RevolverReload then
|
||||
self:DoShellEject()
|
||||
end
|
||||
|
||||
--[[]
|
||||
local ss = self.ShootSound
|
||||
|
||||
if self:GetBuff_Override("Silencer") then
|
||||
ss = self.ShootSoundSilenced
|
||||
end
|
||||
|
||||
ss = self:GetBuff_Hook("Hook_GetShootSound", ss)
|
||||
|
||||
local dss = self.DistantShootSound
|
||||
|
||||
if self:GetBuff_Override("Silencer") then
|
||||
dss = nil
|
||||
end
|
||||
|
||||
dss = self:GetBuff_Hook("Hook_GetDistantShootSound", dss)
|
||||
|
||||
local svol = self:GetBuff("ShootVol")
|
||||
local spitch = self.ShootPitch * math.Rand(0.95, 1.05) * self:GetBuff_Mult("Mult_ShootPitch")
|
||||
|
||||
svol = svol * 0.75
|
||||
|
||||
svol = math.Clamp(svol, 51, 149)
|
||||
spitch = math.Clamp(spitch, 51, 149)
|
||||
|
||||
if dss then
|
||||
-- sound.Play(self.DistantShootSound, self:GetPos(), 149, self.ShootPitch * math.Rand(0.95, 1.05), 1)
|
||||
self:MyEmitSound(dss, 130, spitch, 0.5, CHAN_BODY)
|
||||
end
|
||||
|
||||
if ss then
|
||||
self:MyEmitSound(ss, svol, spitch, 1, CHAN_WEAPON)
|
||||
end
|
||||
]]
|
||||
|
||||
self:DoShootSound()
|
||||
|
||||
self:SetClip1(self:Clip1() - 1)
|
||||
|
||||
self:SetNextPrimaryFire(CurTime() + delay)
|
||||
if delay < 0.1 then
|
||||
self:GetOwner():NextThink(CurTime() + delay)
|
||||
end
|
||||
|
||||
if self:GetBuff_Override("UBGL_NPCFire") and self:GetNextSecondaryFire() < CurTime() then
|
||||
if math.random(0, 100) < (self:GetOwner():GetCurrentWeaponProficiency() + 1) then
|
||||
self:SetNextSecondaryFire(CurTime() + math.random(3, 5))
|
||||
else
|
||||
local func = self:GetBuff_Override("UBGL_NPCFire")
|
||||
if func then
|
||||
func(self)
|
||||
end
|
||||
if self:Clip2() == 0 then
|
||||
self:SetClip2(self.Secondary.ClipSize)
|
||||
self:SetNextSecondaryFire(CurTime() + math.random(300, 600) / (self:GetOwner():GetCurrentWeaponProficiency() + 1))
|
||||
else
|
||||
self:SetNextSecondaryFire(CurTime() + 1 / ((self:GetBuff_Override("UBGL_RPM") or 300) / 60))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:GetNPCBulletSpread(prof)
|
||||
local mode = self:GetCurrentFiremode()
|
||||
mode = mode.Mode
|
||||
|
||||
if mode < 0 then
|
||||
return 15 / (prof + 1)
|
||||
elseif mode == 1 then
|
||||
if math.Rand(0, 100) < (prof + 5) * 5 then
|
||||
return 5 / (prof + 1)
|
||||
else
|
||||
return 30 / (prof + 1)
|
||||
end
|
||||
elseif mode > 1 then
|
||||
if math.Rand(0, 100) < (prof + 5) * 2 then
|
||||
return 15 / (prof + 1)
|
||||
else
|
||||
return (20 + self:GetBuff("Recoil") * 10) / (prof + 1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return 15
|
||||
end
|
||||
|
||||
function SWEP:GetNPCBurstSettings()
|
||||
local mode = self:GetCurrentFiremode()
|
||||
mode = mode.Mode
|
||||
|
||||
local delay = self:GetFiringDelay()
|
||||
|
||||
if !mode then return 1, 1, delay end
|
||||
|
||||
if self.ManualAction or self:GetBuff_Override("Override_ManualAction") then
|
||||
return 1, 1, self:GetAnimKeyTime("cycle") * self:GetBuff("CycleTime")
|
||||
end
|
||||
|
||||
if mode < 0 then
|
||||
return -mode, -mode, delay
|
||||
elseif mode == 0 then
|
||||
return 0, 0, delay
|
||||
elseif mode == 1 then
|
||||
local c = self:GetCapacity()
|
||||
return math.ceil(c * 0.075), math.floor(c * math.Rand(0.15, 0.3)), delay + math.Rand(0.2, 0.4)
|
||||
elseif mode >= 2 then
|
||||
if self:GetCurrentFiremode().RunawayBurst then
|
||||
return self:Clip1(), self:Clip1(), delay
|
||||
else
|
||||
return 2, math.floor(2.5 / delay), delay
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:GetNPCRestTimes()
|
||||
local mode = self:GetCurrentFiremode()
|
||||
mode = mode.Mode
|
||||
local postburst = self:GetCurrentFiremode().PostBurstDelay or 0
|
||||
local m = self:GetBuff("Recoil")
|
||||
local rs = self:GetBuff("RecoilSide")
|
||||
|
||||
if !mode then return 0.3, 0.6 end
|
||||
|
||||
local o = m * 0.3 + rs * 0.15
|
||||
if self.ManualAction or self:GetBuff_Override("Override_ManualAction") then
|
||||
local cycle = self:GetAnimKeyTime("cycle") * self:GetBuff("CycleTime")
|
||||
return cycle + 0.1 * o, cycle + 0.2 * o
|
||||
elseif mode < 0 then
|
||||
o = o * 0.5 + postburst * self:GetBuff("PostBurstDelay")
|
||||
end
|
||||
|
||||
return 0.4 * o, 0.6 * o
|
||||
end
|
||||
|
||||
function SWEP:CanBePickedUpByNPCs()
|
||||
return !self.NotForNPCs
|
||||
end
|
||||
|
||||
function SWEP:OnDrop()
|
||||
self.Primary.DefaultClip = 0
|
||||
|
||||
if self.Singleton or self.Primary.ClipSize == -1 then
|
||||
self.Primary.DefaultClip = 1
|
||||
end
|
||||
|
||||
self.UnReady = false
|
||||
-- if engine.ActiveGamemode() == "terrortown" then
|
||||
-- self.UnReady = true
|
||||
-- else
|
||||
-- self.UnReady = false
|
||||
-- end
|
||||
end
|
||||
Reference in New Issue
Block a user