This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 0e770b2b49
commit 94063e4369
7342 changed files with 1718932 additions and 14 deletions

View File

@@ -0,0 +1,52 @@
--[[
| 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 dofmat = Material("pp/dof")
function SWEP:BlurWeapon()
if !ArcCW.ConVars["blur"]:GetBool() then return end
local delta = self:GetSightDelta()
if delta >= 1 then return end
local vm = self:GetOwner():GetViewModel()
render.UpdateScreenEffectTexture()
render.ClearStencil()
render.SetStencilEnable(true)
render.SetStencilCompareFunction(STENCIL_ALWAYS)
render.SetStencilPassOperation(STENCIL_REPLACE)
render.SetStencilFailOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_REPLACE)
render.SetStencilWriteMask(0xFF)
render.SetStencilTestMask(0xFF)
render.SetBlend(1)
render.SetStencilReferenceValue(55)
ArcCW.Overdraw = true
vm:DrawModel()
ArcCW.Overdraw = false
render.SetBlend(0)
render.SetStencilPassOperation(STENCIL_REPLACE)
render.SetStencilCompareFunction(STENCIL_EQUAL)
-- render.SetColorMaterial()
dofmat:SetFloat("bluramount", 0.1 * (1 - delta))
render.SetMaterial(dofmat)
render.DrawScreenQuad()
render.SetStencilEnable(false)
end
function SWEP:BlurNotWeapon()
if !ArcCW.ConVars["blur"]:GetBool() then return end
render.UpdateRefractTexture()
DrawToyTown(3, ScrH())
end
function SWEP:DoToyTown()
if !ArcCW.ConVars["blur_toytown"]:GetBool() then return end
render.UpdateRefractTexture()
DrawToyTown(3, ScrH() * 0.4 * (1 - self:GetSightDelta()))
end

View File

@@ -0,0 +1,303 @@
--[[
| 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 size = 0
local clump_inner = Material("arccw/hud/clump_inner.png", "mips smooth")
local clump_outer = Material("arccw/hud/clump_outer.png", "mips smooth")
local aimtr_result = {}
local aimtr = {}
local square_mat = Material("color")
function SWEP:ShouldDrawCrosshair()
if ArcCW.ConVars["override_crosshair_off"]:GetBool() then return false end
if !ArcCW.ConVars["crosshair"]:GetBool() then return false end
if self:GetReloading() then return false end
if self:BarrelHitWall() > 0 then return false end
local asight = self:GetActiveSights()
if !self:GetOwner():ShouldDrawLocalPlayer()
and self:GetState() == ArcCW.STATE_SIGHTS and !asight.CrosshairInSights then
return false
end
if self:GetNWState() == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() then return false end
if self:GetCurrentFiremode().Mode == 0 then return false end
if self:GetBuff_Hook("Hook_ShouldNotFire") then return false end
if self:GetNWState() == ArcCW.STATE_CUSTOMIZE then return false end
if self:GetNWState() == ArcCW.STATE_DISABLE then return false end
return true
end
local cr_main = Color( 0, 255, 0 )
local cr_shad = Color( 0, 0, 0, 127 )
local gaA = 0
local gaD = 0
function SWEP:GetFOVAcc( acc, disp )
cam.Start3D()
local lool = ( EyePos() + ( EyeAngles():Forward() ) + ( ( ArcCW.MOAToAcc * (acc or self:GetBuff("AccuracyMOA")) ) * EyeAngles():Up() ) ):ToScreen()
local lool2 = ( EyePos() + ( EyeAngles():Forward() ) + ( ( (disp or self:GetDispersion()) * ArcCW.MOAToAcc / 10 ) * EyeAngles():Up() ) ):ToScreen()
cam.End3D()
local gau = 0
gau = ( (ScrH() / 2) - lool.y )
gaA = math.Approach(gaA, gau, (ScrH() / 2) * FrameTime())
gau = 0
gau = ( (ScrH() / 2) - lool2.y )
gaD = math.Approach(gaD, gau, (ScrH() / 2) * FrameTime())
return gaA, gaD
end
function SWEP:DrawDevCrosshair(x, y)
surface.SetDrawColor(255, 50, 50, 255)
surface.DrawLine(x, y - 256, x, y + 256)
surface.DrawLine(x - 256, y, x + 256, y)
local gA, gD = self:GetFOVAcc( self:GetBuff("AccuracyMOA"), self:GetDispersion() )
surface.DrawCircle(x, y, gA + gD, 255, 255, 255, 155)
surface.DrawCircle(x, y, gA, 255, 255, 0, 55)
draw.SimpleTextOutlined(math.Round(self:GetDispersion(), 1) .. " MOA", "ArcCW_24_Unscaled", x - gA - gD - 16, y, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_BOTTOM, 1, Color(0, 0, 0))
draw.SimpleTextOutlined(math.Round(self:GetBuff("AccuracyMOA"), 1) .. " MOA", "ArcCW_24_Unscaled", x - gA - gD - 16, y, Color(255, 255, 0), TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP, 1, Color(0, 0, 0))
local dist = self:GetOwner():GetEyeTrace().HitPos:Distance(self:GetOwner():GetShootPos()) * ArcCW.HUToM
local rf = self:GetRangeFraction(dist)
local dmg = math.floor(self:GetDamage(dist))
draw.SimpleTextOutlined(dmg .. " damage", "ArcCW_24_Unscaled", x + 256, y, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_BOTTOM, 1, Color(0, 0, 0))
draw.SimpleTextOutlined(math.Round(dist, 1) .. "m", "ArcCW_24_Unscaled", x + 256 - 64, y, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP, 1, Color(0, 0, 0))
draw.SimpleTextOutlined(math.Round(rf * 100) .. "%", "ArcCW_24_Unscaled", x + 256, y, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP, 1, Color(0, 0, 0))
end
function SWEP:DoDrawCrosshair(x, y)
local ply = LocalPlayer()
local pos = ply:EyePos()
local ang = ply:EyeAngles() - self:GetOurViewPunchAngles() + self:GetFreeAimOffset()
if self:GetBuff_Hook("Hook_PreDrawCrosshair") then return end
local static = ArcCW.ConVars["crosshair_static"]:GetBool()
local prong_dot = ArcCW.ConVars["crosshair_dot"]:GetBool()
local prong_top = ArcCW.ConVars["crosshair_prong_top"]:GetBool()
local prong_left = ArcCW.ConVars["crosshair_prong_left"]:GetBool()
local prong_right = ArcCW.ConVars["crosshair_prong_right"]:GetBool()
local prong_down = ArcCW.ConVars["crosshair_prong_bottom"]:GetBool()
local prong_len = ArcCW.ConVars["crosshair_length"]:GetFloat()
local prong_wid = ArcCW.ConVars["crosshair_thickness"]:GetFloat()
local prong_out = ArcCW.ConVars["crosshair_outline"]:GetInt()
local prong_tilt = ArcCW.ConVars["crosshair_tilt"]:GetBool()
local clr = Color(ArcCW.ConVars["crosshair_clr_r"]:GetInt(),
ArcCW.ConVars["crosshair_clr_g"]:GetInt(),
ArcCW.ConVars["crosshair_clr_b"]:GetInt())
if ArcCW.ConVars["ttt_rolecrosshair"] and ArcCW.ConVars["ttt_rolecrosshair"]:GetBool() then
if GetRoundState() == ROUND_PREP or GetRoundState() == ROUND_POST then
clr = Color(255, 255, 255)
elseif ply.GetRoleColor and ply:GetRoleColor() then
clr = ply:GetRoleColor() -- TTT2 feature
elseif ply:IsActiveTraitor() then
clr = Color(255, 50, 50)
elseif ply:IsActiveDetective() then
clr = Color(50, 50, 255)
else
clr = Color(50, 255, 50)
end
end
if ArcCW.ConVars["crosshair_aa"]:GetBool() and ply.ArcCW_AATarget != nil and ArcCW.ConVars["aimassist"]:GetBool() and ArcCW.ConVars["aimassist_cl"]:GetBool() then
-- whooie
clr = Color(255, 0, 0)
end
clr.a = ArcCW.ConVars["crosshair_clr_a"]:GetInt()
local outlineClr = Color(ArcCW.ConVars["crosshair_outline_r"]:GetInt(),
ArcCW.ConVars["crosshair_outline_g"]:GetInt(),
ArcCW.ConVars["crosshair_outline_b"]:GetInt(),
ArcCW.ConVars["crosshair_outline_a"]:GetInt())
local gA, gD = self:GetFOVAcc( self:GetBuff("AccuracyMOA"), self:GetDispersion() )
local gap = (static and 8 or gA + gD) * ArcCW.ConVars["crosshair_gap"]:GetFloat()
gap = gap + ( ScreenScale(8) * math.Clamp(self.RecoilAmount, 0, 1) )
local prong = ScreenScale(prong_len)
local p_w = ScreenScale(prong_wid)
local p_w2 = p_w + prong_out
local sp
if self:GetOwner():ShouldDrawLocalPlayer() then
local tr = util.GetPlayerTrace(self:GetOwner())
local trace = util.TraceLine( tr )
cam.Start3D()
local coords = trace.HitPos:ToScreen()
coords.x = math.Round(coords.x)
coords.y = math.Round(coords.y)
cam.End3D()
sp = { visible = true, x = coords.x, y = coords.y }
end
cam.Start3D()
sp = (pos + (ang:Forward() * 3200)):ToScreen()
cam.End3D()
if ArcCW.ConVars["crosshair_trueaim"]:GetBool() then
aimtr.start = self:GetShootSrc()
else
aimtr.start = pos
end
aimtr.endpos = aimtr.start + ((ply:EyeAngles() + self:GetFreeAimOffset()):Forward() * 100000)
aimtr.filter = {ply}
aimtr.output = aimtr_result
table.Add(aimtr.filter, ArcCW:GetVehicleFilter(ply) or {})
util.TraceLine(aimtr)
cam.Start3D()
local w2s = aimtr_result.HitPos:ToScreen()
w2s.x = math.Round(w2s.x)
w2s.y = math.Round(w2s.y)
cam.End3D()
sp.x = w2s.x sp.y = w2s.y
x, y = sp.x, sp.y
if ArcCW.ConVars["dev_crosshair"]:GetBool() and LocalPlayer():IsAdmin() then
self:DrawDevCrosshair(x, y)
end
local st = self:GetSightTime() / 2
if self:ShouldDrawCrosshair() then
self.CrosshairDelta = math.Approach(self.CrosshairDelta or 0, 1, FrameTime() * 1 / st)
else
self.CrosshairDelta = math.Approach(self.CrosshairDelta or 0, 0, FrameTime() * 1 / st)
end
if ArcCW.ConVars["crosshair_equip"]:GetBool() and (self:GetBuff("ShootEntity", true) or self.PrimaryBash) then
prong = ScreenScale(prong_wid)
p_w = ScreenScale(prong_wid)
p_w2 = p_w + prong_out
end
if prong_dot then
surface.SetDrawColor(outlineClr.r, outlineClr.g, outlineClr.b, outlineClr.a * self.CrosshairDelta)
surface.DrawRect(x - p_w2 / 2, y - p_w2 / 2, p_w2, p_w2)
surface.SetDrawColor(clr.r, clr.g, clr.b, clr.a * self.CrosshairDelta)
surface.DrawRect(x - p_w / 2, y - p_w / 2, p_w, p_w)
end
size = math.Approach(size, gap, FrameTime() * 32 * gap)
gap = size
if !static then gap = gap * self.CrosshairDelta end
gap = math.max(4, gap)
local num = self:GetBuff("Num")
if ArcCW.ConVars["crosshair_shotgun"]:GetBool() and num > 1 then
prong = ScreenScale(prong_wid)
p_w = ScreenScale(prong_len)
p_w2 = p_w + prong_out
end
local prong2 = prong + prong_out
if prong_tilt then
local angle = (prong_left and prong_top and prong_right and prong_down) and 45 or 30
local rad = math.rad(angle)
local dx = gap * math.cos(rad) + prong * math.cos(rad) / 2
local dy = gap * math.sin(rad) + prong * math.sin(rad) / 2
surface.SetMaterial(square_mat)
-- Shade
surface.SetDrawColor(outlineClr.r, outlineClr.g, outlineClr.b, outlineClr.a * self.CrosshairDelta)
if prong_left and prong_top then
surface.DrawTexturedRectRotated(x - dx, y - dy, prong2, p_w2, -angle)
surface.DrawTexturedRectRotated(x + dx, y - dy, prong2, p_w2, angle)
elseif prong_left or prong_top then
surface.DrawRect(x - p_w2 / 2, y - gap - prong2 + prong_out / 2, p_w2, prong2)
end
if prong_right and prong_down then
surface.DrawTexturedRectRotated(x + dx, y + dy, prong2, p_w2, -angle)
surface.DrawTexturedRectRotated(x - dx, y + dy, prong2, p_w2, angle)
elseif prong_right or prong_down then
surface.DrawRect(x - p_w2 / 2, y + gap - prong_out / 2, p_w2, prong2)
end
-- Fill
surface.SetDrawColor(clr.r, clr.g, clr.b, clr.a * self.CrosshairDelta)
if prong_left and prong_top then
surface.DrawTexturedRectRotated(x - dx, y - dy, prong, p_w, -angle)
surface.DrawTexturedRectRotated(x + dx, y - dy, prong, p_w, angle)
elseif prong_left or prong_top then
surface.DrawRect(x - p_w / 2, y - gap - prong, p_w, prong)
end
if prong_right and prong_down then
surface.DrawTexturedRectRotated(x + dx, y + dy, prong, p_w, -angle)
surface.DrawTexturedRectRotated(x - dx, y + dy, prong, p_w, angle)
elseif prong_right or prong_down then
surface.DrawRect(x - p_w / 2, y + gap, p_w, prong)
end
else
-- Shade
surface.SetDrawColor(outlineClr.r, outlineClr.g, outlineClr.b, outlineClr.a * self.CrosshairDelta)
if prong_left then
surface.DrawRect(x - gap - prong2 + prong_out / 2, y - p_w2 / 2, prong2, p_w2)
end
if prong_right then
surface.DrawRect(x + gap - prong_out / 2, y - p_w2 / 2, prong2, p_w2)
end
if prong_top then
surface.DrawRect(x - p_w2 / 2, y - gap - prong2 + prong_out / 2, p_w2, prong2)
end
if prong_down then
surface.DrawRect(x - p_w2 / 2, y + gap - prong_out / 2, p_w2, prong2)
end
-- Fill
surface.SetDrawColor(clr.r, clr.g, clr.b, clr.a * self.CrosshairDelta)
if prong_left then
surface.DrawRect(x - gap - prong, y - p_w / 2, prong, p_w)
end
if prong_right then
surface.DrawRect(x + gap, y - p_w / 2, prong, p_w)
end
if prong_top then
surface.DrawRect(x - p_w / 2, y - gap - prong, p_w, prong)
end
if prong_down then
surface.DrawRect(x - p_w / 2, y + gap, p_w, prong)
end
end
if ArcCW.ConVars["crosshair_clump"]:GetBool() and (ArcCW.ConVars["crosshair_clump_always"]:GetBool() or num > 1) then
local acc = math.max(1, gA)
if ArcCW.ConVars["crosshair_clump_outline"]:GetBool() then
surface.SetMaterial(clump_outer)
for i=1, prong_out do
surface.DrawCircle(x-1, y-0, acc + math.ceil(i*0.5) * (i % 2 == 1 and 1 or -1), outlineClr.r, outlineClr.g, outlineClr.b, outlineClr.a * self.CrosshairDelta)
end
surface.DrawCircle(x-1, y-0, acc, outlineClr.r, outlineClr.g, outlineClr.b, outlineClr.a * self.CrosshairDelta)
end
surface.DrawCircle(x-1, y-0, acc, clr.r, clr.g, clr.b, clr.a * self.CrosshairDelta)
end
self:GetBuff_Hook("Hook_PostDrawCrosshair", w2s)
return true
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,968 @@
--[[
| 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/
--]]
function SWEP:DoHolosight()
-- In VRMod, we draw all holosights all the time
if vrmod and vrmod.IsPlayerInVR(self:GetOwner()) then
for i, asight in pairs(self.SightTable) do
local aslot = self.Attachments[asight.Slot] or {}
local atttbl = asight.HolosightData
if !atttbl and aslot.Installed then
atttbl = ArcCW.AttachmentTable[aslot.Installed]
if !atttbl.Holosight then return end
end
if atttbl then
local hsp = asight.HolosightPiece or self.HSPElement
local hsm = asight.HolosightModel
if !hsp and !hsm then
self:SetupActiveSights()
return
end
self:DrawHolosight(atttbl, hsm, hsp, asight)
end
end
return
end
local asight = self:GetActiveSights()
if !asight then return end
local aslot = self.Attachments[asight.Slot] or {}
local atttbl = asight.HolosightData
if !atttbl and aslot.Installed then
atttbl = ArcCW.AttachmentTable[aslot.Installed]
if !atttbl.Holosight then return end
end
if atttbl then
local hsp = asight.HolosightPiece or self.HSPElement
local hsm = asight.HolosightModel
if !hsp and !hsm then
self:SetupActiveSights()
return
end
self:DrawHolosight(atttbl, hsm, hsp)
end
end
function SWEP:ShouldFlatScope()
return false -- this system was removed, but we need to keep this function
end
local rtsize = ScrH()
local rtmat = GetRenderTarget("arccw_rtmat", rtsize, rtsize, false)
local rtmat_cheap = GetRenderTarget("arccw_rtmat_cheap", ScrW(), ScrH(), false)
local rtmat_spare = GetRenderTarget("arccw_rtmat_spare", ScrW(), ScrH(), false)
local thermal = Material("models/debug/debugwhite")
local colormod = Material("pp/colour")
local coldtime = 30
local additionalFOVconvar = ArcCW.ConVars["vm_add_ads"]
local matRefract = Material("pp/arccw/refract_rt")
local matRefract_cheap = Material("pp/arccw/refract_cs") -- cheap scopes stretches square overlays so i need to make it 16x9
matRefract:SetTexture("$fbtexture", render.GetScreenEffectTexture())
matRefract_cheap:SetTexture("$fbtexture", render.GetScreenEffectTexture())
timer.Create("ihategmod", 5, 0, function() -- i really dont know what the fucking problem with cheap scopes they dont want to set texture as not cheap ones
matRefract_cheap:SetTexture("$fbtexture", render.GetScreenEffectTexture())
matRefract:SetTexture("$fbtexture", render.GetScreenEffectTexture()) -- not cheap scope here why not
end)
local pp_ca_base, pp_ca_r, pp_ca_g, pp_ca_b = Material("pp/arccw/ca_base"), Material("pp/arccw/ca_r"), Material("pp/arccw/ca_g"), Material("pp/arccw/ca_b")
local pp_ca_r_thermal, pp_ca_g_thermal, pp_ca_b_thermal = Material("pp/arccw/ca_r_thermal"), Material("pp/arccw/ca_g_thermal"), Material("pp/arccw/ca_b_thermal")
pp_ca_r:SetTexture("$basetexture", render.GetScreenEffectTexture())
pp_ca_g:SetTexture("$basetexture", render.GetScreenEffectTexture())
pp_ca_b:SetTexture("$basetexture", render.GetScreenEffectTexture())
pp_ca_r_thermal:SetTexture("$basetexture", render.GetScreenEffectTexture())
pp_ca_g_thermal:SetTexture("$basetexture", render.GetScreenEffectTexture())
pp_ca_b_thermal:SetTexture("$basetexture", render.GetScreenEffectTexture())
local greenColor = Color(0, 255, 0) -- optimized +10000fps
local whiteColor = Color(255, 255, 255)
local blackColor = Color(0, 0, 0)
local function DrawTexturedRectRotatedPoint( x, y, w, h, rot, x0, y0 ) -- stolen from gmod wiki
local c = math.cos( math.rad( rot ) )
local s = math.sin( math.rad( rot ) )
local newx = y0 * s - x0 * c
local newy = y0 * c + x0 * s
surface.DrawTexturedRectRotated( x + newx, y + newy, w, h, rot )
end
local function IsWHOT(ent)
if !ent:IsValid() or ent:IsWorld() then return false end
if ent:IsPlayer() then -- balling
if ent.ArcticMedShots_ActiveEffects and ent.ArcticMedShots_ActiveEffects["coldblooded"] or ent:Health() <= 0 then return false end -- arc stims
return true
end
if ent:IsNPC() or ent:IsNextBot() then -- npcs
if ent.ArcCWCLHealth and ent.ArcCWCLHealth <= 0 or ent:Health() <= 0 then return false end
return true
end
if ent:IsRagdoll() then -- ragdolling
if !ent.ArcCW_ColdTime then ent.ArcCW_ColdTime = CurTime() + coldtime end
return ent.ArcCW_ColdTime > CurTime()
end
if ent:IsVehicle() or ent:IsOnFire() or ent.ArcCW_Hot or ent:IsScripted() and !ent:GetOwner():IsValid() then -- vroom vroom + :fire: + ents but not guns (guns on ground will be fine)
return true
end
return false
end
function SWEP:FormThermalImaging(tex)
if !tex then
tex = render.GetRenderTarget()
end
render.PushRenderTarget(tex)
cam.Start3D()
if tex then
colormod:SetTexture("$fbtexture", tex)
else
colormod:SetTexture("$fbtexture", render.GetScreenEffectTexture())
end
local asight = self:GetActiveSights()
local nvsc = asight.ThermalScopeColor or whiteColor
local tvsc = asight.ThermalHighlightColor or whiteColor
local tab = ents.GetAll()
-- table.Add(tab, player.GetAll())
-- table.Add(tab, ents.FindByClass("npc_*"))
render.SetStencilEnable(true)
render.SetStencilWriteMask(255)
render.SetStencilTestMask(255)
render.ClearStencil()
local sw = ScrH()
local sh = sw
local sx = (ScrW() - sw) / 2
local sy = (ScrH() - sh) / 2
render.SetScissorRect( sx, sy, sx + sw, sy + sh, true )
render.SetStencilReferenceValue(64)
render.SetStencilPassOperation(STENCIL_REPLACE)
render.SetStencilFailOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_KEEP)
render.SetStencilCompareFunction(STENCIL_ALWAYS)
for _, v in pairs(tab) do
if !IsWHOT(v) then continue end
if !asight.ThermalScopeSimple then
render.SetBlend(0.5)
render.SuppressEngineLighting(true)
render.SetColorModulation(250, 250, 250)
v:DrawModel()
end
end
render.SetColorModulation(1, 1, 1)
render.SuppressEngineLighting(false)
render.MaterialOverride()
render.SetBlend(1)
render.SetStencilCompareFunction(STENCIL_EQUAL)
if asight.ThermalScopeSimple then
surface.SetDrawColor(255, 255, 255, 255)
surface.DrawRect(0, 0, ScrW(), ScrH())
end
DrawColorModify({
["$pp_colour_addr"] = 0,
["$pp_colour_addg"] = 0,
["$pp_colour_addb"] = 0,
["$pp_colour_brightness"] = 0,
["$pp_colour_contrast"] = 1,
["$pp_colour_colour"] = 0,
["$pp_colour_mulr"] = 0,
["$pp_colour_mulg"] = 0,
["$pp_colour_mulb"] = 0
})
DrawColorModify({
["$pp_colour_addr"] = tvsc.r - 255,
["$pp_colour_addg"] = tvsc.g - 255,
["$pp_colour_addb"] = tvsc.b - 255,
["$pp_colour_addr"] = 0,
["$pp_colour_addg"] = 0,
["$pp_colour_addb"] = 0,
["$pp_colour_brightness"] = 0,
["$pp_colour_contrast"] = 1,
["$pp_colour_colour"] = 1,
["$pp_colour_mulr"] = 0,
["$pp_colour_mulg"] = 0,
["$pp_colour_mulb"] = 0
})
if !asight.ThermalNoCC then
render.SetStencilCompareFunction(STENCIL_NOTEQUAL)
render.SetStencilPassOperation(STENCIL_KEEP)
if !asight.ThermalFullColor then
DrawColorModify({
["$pp_colour_addr"] = 0,
["$pp_colour_addg"] = 0,
["$pp_colour_addb"] = 0,
["$pp_colour_brightness"] = 0,
["$pp_colour_contrast"] = 1,
["$pp_colour_colour"] = 0,
["$pp_colour_mulr"] = 0,
["$pp_colour_mulg"] = 0,
["$pp_colour_mulb"] = 0
})
end
if ArcCW.ConVars["thermalpp"]:GetBool() and ArcCW.ConVars["scopepp"]:GetBool() then
-- chromatic abberation
render.CopyRenderTargetToTexture(render.GetScreenEffectTexture())
render.SetMaterial( pp_ca_base )
render.DrawScreenQuad()
render.SetMaterial( pp_ca_r_thermal )
render.DrawScreenQuad()
render.SetMaterial( pp_ca_g_thermal )
render.DrawScreenQuad()
render.SetMaterial( pp_ca_b_thermal )
render.DrawScreenQuad()
-- pasted here cause otherwise either target colors will get fucked either pp either motion blur
end
DrawColorModify({
["$pp_colour_addr"] = nvsc.r - 255,
["$pp_colour_addg"] = nvsc.g - 255,
["$pp_colour_addb"] = nvsc.b - 255,
-- ["$pp_colour_addr"] = 0,
-- ["$pp_colour_addg"] = 0,
-- ["$pp_colour_addb"] = 0,
["$pp_colour_brightness"] = asight.Brightness or 0.1,
["$pp_colour_contrast"] = asight.Contrast or 0.5,
["$pp_colour_colour"] = asight.Colormult or 1,
["$pp_colour_mulr"] = 0,
["$pp_colour_mulg"] = 0,
["$pp_colour_mulb"] = 0
})
end
render.SetScissorRect( sx, sy, sx + sw, sy + sh, false )
render.SetStencilEnable(false)
colormod:SetTexture("$fbtexture", render.GetScreenEffectTexture())
cam.End3D()
if ArcCW.ConVars["thermalpp"]:GetBool() then
if !render.SupportsPixelShaders_2_0() then return end
DrawSharpen(0.3,0.9)
DrawBloom(0,0.3,5,5,3,0.5,1,1,1)
-- DrawMotionBlur(0.7,1,1/(asight.FPSLock or 45)) -- upd i changed order and it fucking worked lmao //////i cant fucking understand why motionblur fucks render target
end
render.PopRenderTarget()
end
function SWEP:FormNightVision(tex)
local asight = self:GetActiveSights()
local orig = colormod:GetTexture("$fbtexture")
colormod:SetTexture("$fbtexture", tex)
render.PushRenderTarget(tex)
local nvsc = asight.NVScopeColor or greenColor
if !asight.NVFullColor then
DrawColorModify({
["$pp_colour_addr"] = 0,
["$pp_colour_addg"] = 0,
["$pp_colour_addb"] = 0,
["$pp_colour_brightness"] = 0,
["$pp_colour_contrast"] = 1,
["$pp_colour_colour"] = 0,
["$pp_colour_mulr"] = 0,
["$pp_colour_mulg"] = 0,
["$pp_colour_mulb"] = 0
})
end
DrawColorModify({
["$pp_colour_addr"] = nvsc.r - 255,
["$pp_colour_addg"] = nvsc.g - 255,
["$pp_colour_addb"] = nvsc.b - 255,
["$pp_colour_brightness"] = asight.Brightness or -0.05,
["$pp_colour_contrast"] = asight.Contrast or 4,
["$pp_colour_colour"] = 1,
["$pp_colour_mulr"] = 0,
["$pp_colour_mulg"] = 0,
["$pp_colour_mulb"] = 0
})
render.PopRenderTarget()
colormod:SetTexture("$fbtexture", orig)
end
local pp_cc_tab = {
["$pp_colour_addr"] = 0,
["$pp_colour_addg"] = 0,
["$pp_colour_addb"] = 0,
["$pp_colour_brightness"] = 0, -- why nothing works hh
["$pp_colour_contrast"] = 0.9, -- but same time chroma dont work without calling it
["$pp_colour_colour"] = 1,
["$pp_colour_mulr"] = 0,
["$pp_colour_mulg"] = 0,
["$pp_colour_mulb"] = 0
}
function SWEP:FormPP(tex)
if !render.SupportsPixelShaders_2_0() then return end
local asight = self:GetActiveSights()
if asight.Thermal then return end -- eyah
local cs = ArcCW.ConVars["cheapscopes"]:GetBool()
local refract = ArcCW.ConVars["scopepp_refract"]:GetBool()
local pp = ArcCW.ConVars["scopepp"]:GetBool()
if refract or pp then
if !cs then render.PushRenderTarget(tex) end
render.CopyRenderTargetToTexture(render.GetScreenEffectTexture())
if pp then
render.SetMaterial( pp_ca_base )
render.DrawScreenQuad()
render.SetMaterial( pp_ca_r )
render.DrawScreenQuad()
render.SetMaterial( pp_ca_g )
render.DrawScreenQuad()
render.SetMaterial( pp_ca_b )
render.DrawScreenQuad()
-- Color modify
DrawColorModify( pp_cc_tab )
-- Sharpen
DrawSharpen(-0.1, 5) -- dont work for some reason
end
if refract then
local addads = math.Clamp(additionalFOVconvar:GetFloat(), -2, 14)
local refractratio = ArcCW.ConVars["scopepp_refract_ratio"]:GetFloat() or 0
local refractamount = (-0.6 + addads / 30) * refractratio
local refractmat = cs and matRefract_cheap or matRefract
refractmat:SetFloat( "$refractamount", refractamount )
render.SetMaterial(refractmat)
render.DrawScreenQuad()
end
if !cs then render.PopRenderTarget() end
end
end
function SWEP:FormCheapScope()
local screen = render.GetRenderTarget()
render.CopyTexture( screen, rtmat_spare )
render.PushRenderTarget(screen)
cam.Start3D(EyePos(), EyeAngles(), nil, nil, nil, nil, nil, 0, nil)
ArcCW.LaserBehavior = true
self:DoLaser(false)
ArcCW.LaserBehavior = false
cam.End3D()
self:FormPP(screen)
render.PopRenderTarget()
-- so, in order to avoid the fact that copying RTs doesn't transfer depth buffer data, we just take the screen texture and...
-- redraw it to cover up the thermal scope stuff. Don't think too hard about this. You have plenty of VRAM.
local asight = self:GetActiveSights()
if asight.Thermal then
self:FormThermalImaging(screen)
end
if asight.SpecialScopeFunction then
asight.SpecialScopeFunction(screen)
end
-- integrated render delay for better optimization
if asight.FPSLock then
asight.fpsdelay = CurTime() + 1 / (asight.FPSLock or 45)
end
render.CopyTexture( screen, rtmat_cheap )
render.DrawTextureToScreen(rtmat_spare)
render.UpdateFullScreenDepthTexture()
end
function SWEP:FormRTScope()
local asight = self:GetActiveSights()
if !asight then return end
if !asight.MagnifiedOptic then return end
local mag = asight.ScopeMagnification
cam.Start3D()
ArcCW.Overdraw = true
ArcCW.LaserBehavior = true
ArcCW.VMInRT = true
local rtangles, rtpos, rtdrawvm
if self:GetState() == ArcCW.STATE_SIGHTS then
if ArcCW.ConVars["drawbarrel"]:GetBool() and ArcCW.ConVars["vm_coolsway"]:GetBool() and asight.Slot and asight.Slot == 1 then -- slot check to ignore integrated
rtangles = self.VMAng - self.VMAngOffset - (self:GetOurViewPunchAngles() * mag * 0.1)
rtangles.x = rtangles.x - self.VMPosOffset_Lerp.z * 10
rtangles.y = rtangles.y + self.VMPosOffset_Lerp.y * 10
rtpos = self.VMPos + self.VMAng:Forward() * (asight.EVPos.y + 7 + (asight.ScopeMagnificationMax and asight.ScopeMagnificationMax / 3 or asight.HolosightData.HolosightMagnification / 3)) -- eh
rtdrawvm = true
else
rtangles = EyeAngles()
rtpos = EyePos()
rtdrawvm = false
-- HACK HACK HACK HACK HACK
-- If we do not draw the viewmodel in RT scope, calling GetAttachment on the vm seems to break LHIK.
-- So... just draw it! The results gets drawn over again so it doesn't affect the outcome
render.RenderView({drawviewmodel = true}) -- ?????
end
end
local addads = math.Clamp(additionalFOVconvar:GetFloat(), -2, 14)
local rt = {
w = rtsize,
h = rtsize,
angles = rtangles,
origin = rtpos,
drawviewmodel = rtdrawvm,
fov = self:GetOwner():GetFOV() / mag / 1.2 - (addads or 0) / 4,
}
rtsize = ScrH()
if ScrH() > ScrW() then rtsize = ScrW() end
local rtres = asight.ForceLowRes and ScrH() * 0.6 or ScrH() -- we can emit low res lcd displays for scopes
rtmat = GetRenderTarget("arccw_rtmat" .. rtres, rtres, rtres, false)
render.PushRenderTarget(rtmat, 0, 0, rtsize, rtsize)
render.ClearRenderTarget(rt, blackColor)
if self:GetState() == ArcCW.STATE_SIGHTS then
render.RenderView(rt)
cam.Start3D(EyePos(), EyeAngles(), rt.fov, 0, 0, nil, nil, 0, nil)
self:DoLaser(false)
cam.End3D()
end
ArcCW.Overdraw = false
ArcCW.LaserBehavior = false
ArcCW.VMInRT = false
self:FormPP(rtmat)
render.PopRenderTarget()
cam.End3D()
if asight.Thermal then
self:FormThermalImaging(rtmat)
end
if asight.SpecialScopeFunction then
asight.SpecialScopeFunction(rtmat)
end
-- integrated render delay for better optimization
if asight.FPSLock then
asight.fpsdelay = CurTime() + 1 / (asight.FPSLock or 45)
end
end
-- local fpsdelay = CurTime()
hook.Add("RenderScene", "ArcCW", function()
if ArcCW.ConVars["cheapscopes"]:GetBool() then return end
local wpn = LocalPlayer():GetActiveWeapon()
if !wpn.ArcCW then return end
if wpn:GetActiveSights() and wpn:GetActiveSights().FPSLock
and (wpn:GetActiveSights().fpsdelay or 0) > CurTime() then
return
end
wpn:FormRTScope()
end)
local black = Material("arccw/hud/black.png")
local defaultdot = Material("arccw/hud/hit_dot.png")
function SWEP:DrawHolosight(hs, hsm, hsp, asight)
-- holosight structure
-- holosight model
local ref = 32
asight = asight or self:GetActiveSights()
local delta = self:GetSightDelta()
if asight.HolosightData then
hs = asight.HolosightData
end
if self:GetState() != ArcCW.STATE_SIGHTS and delta > 0.5 or self:GetBarrelNearWall() > 0 then return end
if !hs then return end
if delta != 0 and ArcCW.ConVars["scopepp"]:GetBool() then
pp_ca_r:SetVector("$color2", Vector(1-delta, 0, 0))
pp_ca_g:SetVector("$color2", Vector(0, 1-delta, 0))
pp_ca_b:SetVector("$color2", Vector(0, 0, 1-delta))
pp_ca_base:SetFloat("$alpha", 1-delta)
end
local hsc = Color(255, 255, 255) -- putting here global or white local SOMEHOW FUCKS IT EVEN GLOBAL BEING FUCKED WTF I HATE
if hs.Colorable then
hsc.r = ArcCW.ConVars["scope_r"]:GetInt()
hsc.g = ArcCW.ConVars["scope_g"]:GetInt()
hsc.b = ArcCW.ConVars["scope_b"]:GetInt()
else
hsc = hs.HolosightColor or hsc
end
local attid = 0
if hsm then
attid = hsm:LookupAttachment(asight.HolosightBone or hs.HolosightBone or "holosight")
if attid == 0 then
attid = hsm:LookupAttachment("holosight")
end
end
local ret, pos, ang
if attid != 0 then
ret = hsm:GetAttachment(attid)
pos = ret.Pos
ang = ret.Ang
else
pos = EyePos()
ang = EyeAngles()
end
local hsmag = asight.ScopeMagnification or 1
local size = hs.HolosightSize or 1
local addads = math.Clamp(additionalFOVconvar:GetFloat(), -2, 14)
local addconvar = asight.MagnifiedOptic and (addads or 0) or 0
size = size + addconvar + (addconvar > 5.5 and (addconvar-5.5) * 2 or 0)
-- if asight.NightVision then
if hsmag and hsmag > 1 and delta < 1 and asight.NVScope then
local screen = rtmat
if ArcCW.ConVars["cheapscopes"]:GetBool() then
screen = rtmat_cheap
end
if asight.NVScope then
self:FormNightVision(screen)
end
end
render.UpdateScreenEffectTexture()
render.ClearStencil()
render.SetStencilEnable(true)
render.SetStencilCompareFunction(STENCIL_ALWAYS)
render.SetStencilPassOperation(STENCIL_REPLACE)
render.SetStencilFailOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_REPLACE)
render.SetStencilWriteMask(255)
render.SetStencilTestMask(255)
render.SetBlend(0)
render.SetStencilReferenceValue(ref)
ArcCW.Overdraw = true
render.OverrideDepthEnable( true, true )
if !hsm then
hsp:DrawModel()
else
hsm:SetBodygroup(1, 0)
if !hsp or hs.HolosightNoHSP then
hsm:DrawModel()
end
-- render.MaterialOverride()
render.SetStencilReferenceValue(0)
hsm:SetBodygroup(1, 1)
-- hsm:SetSubMaterial(0, "dev/no_pixel_write")
hsm:DrawModel()
-- hsm:SetSubMaterial()
hsm:SetBodygroup(1, 0)
-- local vm = self:GetOwner():GetViewModel()
-- ArcCW.Overdraw = true
-- vm:DrawModel()
-- ArcCW.Overdraw = false
render.SetStencilReferenceValue(ref)
if hsp then
hsp:DrawModel()
end
end
-- render.MaterialOverride()
render.OverrideDepthEnable( false, true )
ArcCW.Overdraw = false
render.SetBlend(1)
render.SetStencilPassOperation(STENCIL_REPLACE)
render.SetStencilCompareFunction(STENCIL_EQUAL)
-- local pos = EyePos()
-- local ang = EyeAngles()
ang:RotateAroundAxis(ang:Forward(), -90)
local dir = ang:Up()
local pdiff = (pos - EyePos()):Length()
pos = LerpVector(delta, EyePos(), pos)
local eyeangs = self:GetOwner():EyeAngles() - self:GetOurViewPunchAngles() * hsmag * 0.1
-- local vm = hsm or hsp
-- eyeangs = eyeangs + (eyeangs - vm:GetAngles())
dir = LerpVector(delta, eyeangs:Forward(), dir:GetNormalized())
pdiff = Lerp(delta, pdiff, 0)
local d = (8 + pdiff)
d = hs.HolosightConstDist or d
local vmscale = (self.Attachments[asight.Slot] or {}).VMScale or Vector(1, 1, 1)
if hs.HolosightConstDist then
vmscale = Vector(1, 1, 1)
end
local hsx = vmscale[2] or 1
local hsy = vmscale[3] or 1
pos = pos + (dir * d)
local pos2 = pos + (dir * -8)
local a = self:GetOwner():InVehicle() and {x = ScrW() / 2, y = ScrH() / 2} or pos:ToScreen()
local x = a.x - (self.VMAngOffset.y - self.VMPosOffset_Lerp.y * 10) * (hsmag * 1.5) ^ 2
local y = a.y + (self.VMAngOffset.x * 5 + self.VMPosOffset_Lerp.z * 10) * (hsmag * 1.5) ^ 2
local a2 = self:GetOwner():InVehicle() and {x = ScrW() / 2, y = ScrH() / 2} or pos2:ToScreen()
local off_x = a2.x - (ScrW() / 2)
local off_y = a2.y - (ScrH() / 2)
--pos = pos + Vector(ArcCW.StrafeTilt(self), 0, 0)
-- local corner1, corner2, corner3, corner4
-- corner2 = pos + (ang:Right() * (-0.5 * size)) + (ang:Forward() * (0.5 * size))
-- corner1 = pos + (ang:Right() * (-0.5 * size)) + (ang:Forward() * (-0.5 * size))
-- corner4 = pos + (ang:Right() * (0.5 * size)) + (ang:Forward() * (-0.5 * size))
-- corner3 = pos + (ang:Right() * (0.5 * size)) + (ang:Forward() * (0.5 * size))
-- render.SetColorMaterialIgnoreZ()
-- render.DrawScreenQuad()
-- render.SetStencilEnable( false )
-- local fovmag = asight.Magnification or 1
if hsmag and hsmag > 1 and delta < 1 then
local screen = rtmat
-- local sw2 = ScrH()
-- local sh2 = sw2
-- local sx2 = (ScrW() - sw2) / 2
-- local sy2 = (ScrH() - sh2) / 2
-- render.SetScissorRect( sx2, sy2, sx2 + sw2, sy2 + sh2, true )
if render.GetHDREnabled() and delta < 0.07 then
render.SetToneMappingScaleLinear(Vector(1,1,1)) -- hdr fix
end
if ArcCW.ConVars["cheapscopes"]:GetBool() then
screen = rtmat_cheap
local addads = math.Clamp(additionalFOVconvar:GetFloat(), -2, 14)
local csratio = math.Clamp(GetConVar("arccw_cheapscopesv2_ratio"):GetFloat(), 0, 1)
local ssmag = 1 + csratio * hsmag + (addads or 0) / 20 -- idk why 20
local sw = ScrW() * ssmag
local sh = ScrH() * ssmag
-- local sx = -(sw - ScrW()) / 2
-- local sy = -(sh - ScrH()) / 2
local cpos = self:GetOwner():EyePos() + ((EyeAngles() + (self:GetOurViewPunchAngles() * 0.5)):Forward() * 2048)
--cpos:Rotate(Angle(0, -ArcCW.StrafeTilt(self), 0))
local ts = self:GetOwner():InVehicle() and {x = ScrW() / 2, y = ScrH() / 2} or cpos:ToScreen()
local sx = ts.x - (sw / 2) - off_x - (self.VMAngOffset.y - self.VMPosOffset_Lerp.y * 15) * (hsmag * 1) ^ 2
local sy = ts.y - (sh / 2) - off_y + (self.VMAngOffset.x * 5 + self.VMPosOffset_Lerp.z * 15) * (hsmag * 1) ^ 2
render.SetMaterial(black)
render.DrawScreenQuad()
render.DrawTextureToScreenRect(screen, sx, sy, sw, sh)
else
local sw = ScrH()
local sh = sw
local sx = ((ScrW() - sw) / 2) - off_x
local sy = ((ScrH() - sh) / 2) - off_x
render.SetMaterial(black)
render.DrawScreenQuad()
render.DrawTextureToScreenRect(screen, sx, sy, sw, sh)
end
end
-- cam.Start3D()
-- render.SetColorMaterialIgnoreZ()
-- render.DrawScreenQuad()
-- render.DrawQuad( corner1, corner2, corner3, corner4, hsc or hs.HolosightColor )
cam.IgnoreZ( true )
render.SetStencilReferenceValue(ref)
-- render.SetMaterial(hs.HolosightReticle or defaultdot)
-- render.DrawSprite( pos, size * hsx, size * hsy, hsc or Color(255, 255, 255) )
-- if !hs.HolosightNoFlare then
-- render.SetMaterial(hs.HolosightFlare or hs.HolosightReticle or defaultdot)
-- local hss = 0.75
-- if hs.HolosightFlare then
-- hss = 1
-- end
-- render.DrawSprite( pos, size * hss * hsx, size * hss * hsy, Color(255, 255, 255, 255) )
-- end
cam.Start2D()
if hs.HolosightBlackbox then
render.SetStencilPassOperation(STENCIL_KEEP)
surface.SetDrawColor(0, 0, 0, 255 * delta)
surface.DrawRect(0, 0, ScrW(), ScrH())
end
render.SetStencilPassOperation(STENCIL_DECR)
render.SetStencilCompareFunction(STENCIL_EQUAL)
local hss = size * 32 * math.min(ScrW(), ScrH()) / 800
--local thej = self.TheJ.anga + LocalPlayer():GetViewPunchAngles() + self:GetOurViewPunchAngles()
-- AYE, UR ACTIVE ANG BEIN TWISTED DUNT GIVE AUH SHET
surface.SetMaterial(hs.HolosightReticle or defaultdot)
surface.SetDrawColor(hsc or 255, 255, 255)
-- surface.DrawTexturedRect(x - (hss / 2), y - (hss / 2), hss, hss)
DrawTexturedRectRotatedPoint(x, y, hss, hss, -(self.VMAngOffset.r+self.VMAngOffset_Lerp.r+self:GetOurViewPunchAngles().r)*5 , 0, 0)
if !hs.HolosightNoFlare then
render.SetStencilPassOperation(STENCIL_KEEP)
render.SetStencilReferenceValue(ref - 1)
surface.SetMaterial(hs.HolosightFlare or hs.HolosightReticle or defaultdot)
surface.SetDrawColor(255, 255, 255, 150)
local hss2 = hss
if !hs.HolosightFlare then
hss2 = hss - 2
end
surface.DrawTexturedRect(x - (hss2 / 2), y - (hss2 / 2), hss2, hss2)
--surface.DrawTexturedRectRotated(x, y, hss2, hss2, -thej.r or 0)
render.SetStencilReferenceValue(ref)
end
if hs.HolosightBlackbox then
-- render.SetColorMaterialIgnoreZ()
-- render.DrawScreenQuad()
surface.SetDrawColor(0, 0, 0)
surface.DrawRect(0, 0, ScrW(), ScrH())
-- surface.DrawRect(0, (ScrH() - hss) / 2, ScrW(), (ScrH() - hss) / 2)
end
cam.End2D()
render.SetStencilEnable( false )
cam.IgnoreZ( false )
-- cam.End3D()
if hsp then
cam.IgnoreZ(true)
if ArcCW.ConVars["glare"]:GetBool() then
render.SetBlend(delta + 0.1)
else
render.SetBlend(delta)
end
hsp:DrawModel()
render.SetBlend(1)
cam.IgnoreZ( false )
end
end
-- I wanted to make here procedural normal map for refract using rt but steamsnooze
-- local TEX_SIZE = 512
-- local tex = GetRenderTarget( "ExampleRT", TEX_SIZE, TEX_SIZE )
-- local txBackground = surface.GetTextureID( "pp/arccw/lense_nrm2" )
-- local myMat = CreateMaterial( "ExampleRTMat3", "UnlitGeneric", {
-- ["$basetexture"] = tex:GetName() -- Make the material use our render target texture
-- } )
-- hook.Add( "HUDPaint", "DrawExampleMat", function()
-- render.PushRenderTarget( tex )
-- cam.Start2D()
-- surface.SetDrawColor( 128,128,255 )
-- surface.DrawRect(0,0,TEX_SIZE, TEX_SIZE)
-- surface.SetDrawColor( color_white )
-- surface.SetTexture( txBackground )
-- local joke = math.sin(CurTime()*5)/4
-- surface.DrawTexturedRect( TEX_SIZE/4-joke/2, TEX_SIZE/4-joke/2, TEX_SIZE/2+joke, TEX_SIZE/2+joke )
-- cam.End2D()
-- render.PopRenderTarget()
-- surface.SetDrawColor( color_white )
-- surface.SetMaterial( myMat )
-- surface.DrawTexturedRect( 25, 25, TEX_SIZE, TEX_SIZE )
-- print()
-- DrawTexturedRectRotatedPoint(250+250/2,250+250/2,250,250,(CurTime()%360)*50,0,0)
-- surface.DrawRect(250,250,250,250)
-- end )

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
--[[
| 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 mth = math
local m_log10 = mth.log10
local m_rand = mth.Rand
local rnd = render
local SetMat = rnd.SetMaterial
local DrawBeam = rnd.DrawBeam
local DrawSprite = rnd.DrawSprite
local cam = cam
local lasermat = Material("arccw/laser")
local flaremat = Material("effects/whiteflare")
local delta = 1
function SWEP:DoLaser(world, nocontext)
world = world or false
if !nocontext then
if world then
cam.Start3D()
else
cam.Start3D(EyePos(), EyeAngles(), self:QuickFOVix(self.CurrentViewModelFOV))
end
end
for slot, k in pairs(self.Attachments) do
if !k.Installed then continue end
local attach = ArcCW.AttachmentTable[k.Installed]
if self:GetBuff_Stat("Laser", slot) then
local color = self:GetBuff_Stat("LaserColor", slot) or attach.ColorOptionsTable[k.ColorOptionIndex or 1]
if world then
if !k.WElement then continue end
self:DrawLaser(attach, k.WElement.Model, color, true)
else
if !k.VElement then continue end
self:DrawLaser(attach, k.VElement.Model, color)
end
end
end
if self.Lasers then
if world then
for _, k in pairs(self.Lasers) do
self:DrawLaser(k, self.WMModel or self, k.LaserColor, true)
end
else
-- cam.Start3D(nil, nil, self.ViewmodelFOV)
for _, k in pairs(self.Lasers) do
self:DrawLaser(k, self:GetOwner():GetViewModel(), k.LaserColor)
end
-- cam.End3D()
end
end
if !nocontext then
cam.End3D()
end
end
function SWEP:DrawLaser(laser, model, color, world)
local owner = self:GetOwner()
local behav = ArcCW.LaserBehavior
if !owner then return end
if !IsValid(owner) then return end
if !model then return end
if !IsValid(model) then return end
local att = model:LookupAttachment(laser.LaserBone or "laser")
att = att == 0 and model:LookupAttachment("muzzle") or att
local pos, ang, dir
if att == 0 then
pos = model:GetPos()
ang = owner:EyeAngles() + self:GetFreeAimOffset()
dir = ang:Forward()
else
local attdata = model:GetAttachment(att)
pos, ang = attdata.Pos, attdata.Ang
dir = -ang:Right()
end
if world then
dir = owner:IsNPC() and (-ang:Right()) or dir
else
ang:RotateAroundAxis(ang:Up(), 90)
if self.LaserOffsetAngle then
ang:RotateAroundAxis(ang:Right(), self.LaserOffsetAngle[1])
ang:RotateAroundAxis(ang:Up(), self.LaserOffsetAngle[2])
ang:RotateAroundAxis(ang:Forward(), self.LaserOffsetAngle[3])
end
if self.LaserIronsAngle and self:GetActiveSights().IronSight then
local d = 1 - self:GetSightDelta()
ang:RotateAroundAxis(ang:Right(), d * self.LaserIronsAngle[1])
ang:RotateAroundAxis(ang:Up(), d * self.LaserIronsAngle[2])
ang:RotateAroundAxis(ang:Forward(), d * self.LaserIronsAngle[3])
end
dir = ang:Forward()
local eyeang = EyeAngles() - self:GetOurViewPunchAngles() + self:GetFreeAimOffset()
local canlaser = self:GetCurrentFiremode().Mode != 0 and !self:GetReloading() and self:BarrelHitWall() <= 0
delta = Lerp(0, delta, canlaser and self:GetSightDelta() or 1)
if self.GuaranteeLaser then
delta = 1
else
delta = self:GetSightDelta()
end
dir = Lerp(delta, eyeang:Forward(), dir)
end
local beamdir, tracepos = dir, pos
beamdir = world and (-ang:Right()) or beamdir
if behav and !world then
-- local cheap = ArcCW.ConVars["cheapscopes"]:GetBool()
local punch = self:GetOurViewPunchAngles()
ang = EyeAngles() - punch + self:GetFreeAimOffset()
tracepos = EyePos() - Vector(0, 0, 1)
pos, dir = tracepos, ang:Forward()
beamdir = dir
end
local dist = 128
local tl = {}
tl.start = tracepos
tl.endpos = tracepos + (dir * 33000)
tl.filter = owner
local tr = util.TraceLine(tl)
tl.endpos = tracepos + (beamdir * dist)
local btr = util.TraceLine(tl)
local hit = tr.Hit
local hitpos = tr.HitPos
local solid = tr.StartSolid
local strength = laser.LaserStrength or 1
local laserpos = solid and tr.StartPos or hitpos
laserpos = laserpos - ((EyeAngles() + self:GetFreeAimOffset()):Forward())
if solid then return end
local width = m_rand(0.05, 0.1) * strength * 1
if (!behav or world) and hit then
SetMat(lasermat)
local a = 200
DrawBeam(pos, btr.HitPos, width * 0.3, 1, 0, Color(a, a, a, a))
DrawBeam(pos, btr.HitPos, width, 1, 0, color)
end
if hit and !tr.HitSky then
local mul = 1 * strength
mul = m_log10((hitpos - EyePos()):Length()) * strength
local rad = m_rand(4, 6) * mul
local glr = rad * m_rand(0.2, 0.3)
SetMat(flaremat)
-- if !world then
-- cam.IgnoreZ(true)
-- end
DrawSprite(laserpos, rad, rad, color)
DrawSprite(laserpos, glr, glr, color_white)
-- if !world then
-- cam.IgnoreZ(false)
-- end
end
end

View File

@@ -0,0 +1,402 @@
--[[
| 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 function qerp(delta, a, b)
local qdelta = -(delta ^ 2) + (delta * 2)
qdelta = math.Clamp(qdelta, 0, 1)
return Lerp(qdelta, a, b)
end
SWEP.LHIKAnimation_IsIdle = false
SWEP.LHIKAnimation = nil
SWEP.LHIKAnimationStart = 0
SWEP.LHIKAnimationTime = 0
SWEP.LHIKCamAng = Angle(0, 0, 0)
SWEP.LHIKGunAng = Angle(0, 0, 0)
function SWEP:DoLHIKAnimation(key, time, spbitch)
if !IsValid(self:GetOwner()) then return end
if game.SinglePlayer() and !spbitch then
timer.Simple(0, function() if IsValid(self) then self:DoLHIKAnimation(key, time, true) end end)
return
end
local vm = self:GetOwner():GetViewModel()
if !IsValid(vm) then return end
local lhik_model
local lhik_anim_model
local LHIK_GunDriver
local LHIK_CamDriver
local offsetang
local tranim = self:GetBuff_Hook("Hook_LHIK_TranslateAnimation", key)
key = tranim or key
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
if !k.VElement then continue end
if self:GetBuff_Stat("LHIK", i) then
lhik_model = k.VElement.Model
lhik_anim_model = k.GodDriver and k.GodDriver.Model or false
offsetang = k.VElement.OffsetAng
if self:GetBuff_Stat("LHIK_GunDriver", i) then
LHIK_GunDriver = self:GetBuff_Stat("LHIK_GunDriver", i)
end
if self:GetBuff_Stat("LHIK_CamDriver", i) then
LHIK_CamDriver = self:GetBuff_Stat("LHIK_CamDriver", i)
end
end
end
if !IsValid(lhik_model) then return false end
local seq = lhik_model:LookupSequence(key)
if !seq then return false end
if seq == -1 then return false end
lhik_model:ResetSequence(seq)
if IsValid(lhik_anim_model) then
lhik_anim_model:ResetSequence(seq)
end
if !time or time < 0 then time = lhik_model:SequenceDuration(seq) end
self.LHIKAnimation = seq
self.LHIKAnimationStart = UnPredictedCurTime()
self.LHIKAnimationTime = time
self.LHIKAnimation_IsIdle = false
if IsValid(lhik_anim_model) and LHIK_GunDriver then
local att = lhik_anim_model:LookupAttachment(LHIK_GunDriver)
local ang = lhik_anim_model:GetAttachment(att).Ang
local pos = lhik_anim_model:GetAttachment(att).Pos
self.LHIKGunAng = lhik_anim_model:WorldToLocalAngles(ang) - Angle(0, 90, 90)
self.LHIKGunPos = lhik_anim_model:WorldToLocal(pos)
self.LHIKGunAngVM = vm:WorldToLocalAngles(ang) - Angle(0, 90, 90)
self.LHIKGunPosVM = vm:WorldToLocal(pos)
end
if IsValid(lhik_anim_model) and LHIK_CamDriver then
local att = lhik_anim_model:LookupAttachment(LHIK_CamDriver)
local ang = lhik_anim_model:GetAttachment(att).Ang
self.LHIKCamOffsetAng = offsetang
self.LHIKCamAng = lhik_anim_model:WorldToLocalAngles(ang)
end
-- lhik_model:SetCycle(0)
-- lhik_model:SetPlaybackRate(dur / time)
return true
end
SWEP.LHIKDelta = {}
SWEP.LHIKDeltaAng = {}
SWEP.ViewModel_Hit = Vector(0, 0, 0)
SWEP.Customize_Hide = 0
function SWEP:GetLHIKAnim()
local cyc = (UnPredictedCurTime() - self.LHIKAnimationStart) / self.LHIKAnimationTime
if cyc > 1 then return nil end
if self.LHIKAnimation_IsIdle then return nil end
return self.LHIKAnimation
end
function SWEP:DoLHIK()
if !IsValid(self:GetOwner()) then return end
local justhide = false
local lhik_model = nil
local lhik_anim_model = nil
local hide_component = false
local delta = 1
local vm = self:GetOwner():GetViewModel()
if !ArcCW.ConVars["reloadincust"]:GetBool() and !self.NoHideLeftHandInCustomization and !self:GetBuff_Override("Override_NoHideLeftHandInCustomization") then
if self:GetState() == ArcCW.STATE_CUSTOMIZE then
self.Customize_Hide = math.Approach(self.Customize_Hide, 1, FrameTime() / 0.25)
else
self.Customize_Hide = math.Approach(self.Customize_Hide, 0, FrameTime() / 0.25)
end
end
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
-- local atttbl = ArcCW.AttachmentTable[k.Installed]
-- if atttbl.LHIKHide then
if self:GetBuff_Stat("LHIKHide", i) then
justhide = true
end
if !k.VElement then continue end
-- if atttbl.LHIK then
if self:GetBuff_Stat("LHIK", i) then
lhik_model = k.VElement.Model
if k.GodDriver then
lhik_anim_model = k.GodDriver.Model
end
end
end
if self.LHIKTimeline then
local tl = self.LHIKTimeline
local stage, next_stage, next_stage_index
for i, k in pairs(tl) do
if !k or !k.t then continue end
if k.t + self.LHIKStartTime > UnPredictedCurTime() then
next_stage_index = i
break
end
end
if next_stage_index then
if next_stage_index == 1 then
-- we are on the first stage.
stage = {t = 0, lhik = 0}
next_stage = self.LHIKTimeline[next_stage_index]
else
stage = self.LHIKTimeline[next_stage_index - 1]
next_stage = self.LHIKTimeline[next_stage_index]
end
else
stage = self.LHIKTimeline[#self.LHIKTimeline]
next_stage = {t = self.LHIKEndTime, lhik = self.LHIKTimeline[#self.LHIKTimeline].lhik}
end
local local_time = UnPredictedCurTime() - self.LHIKStartTime
local delta_time = next_stage.t - stage.t
delta_time = (local_time - stage.t) / delta_time
delta = qerp(delta_time, stage.lhik, next_stage.lhik)
if lhik_model and IsValid(lhik_model) then
local key
if stage.lhik > next_stage.lhik then
key = "in"
elseif next_stage.lhik > stage.lhik then
key = "out"
end
if key then
local tranim = self:GetBuff_Hook("Hook_LHIK_TranslateAnimation", key)
key = tranim or key
local seq = lhik_model:LookupSequence(key)
if seq and seq > 0 then
lhik_model:SetSequence(seq)
lhik_model:SetCycle(delta)
if lhik_anim_model then
lhik_anim_model:SetSequence(seq)
lhik_anim_model:SetCycle(delta)
end
end
end
end
-- if tl[4] <= UnPredictedCurTime() then
-- -- it's over
-- delta = 1
-- elseif tl[3] <= UnPredictedCurTime() then
-- -- transition back to 1
-- delta = (UnPredictedCurTime() - tl[3]) / (tl[4] - tl[3])
-- delta = qerp(delta, 0, 1)
-- if lhik_model and IsValid(lhik_model) then
-- local key = "out"
-- local tranim = self:GetBuff_Hook("Hook_LHIK_TranslateAnimation", key)
-- key = tranim or key
-- local seq = lhik_model:LookupSequence(key)
-- if seq and seq > 0 then
-- lhik_model:SetSequence(seq)
-- lhik_model:SetCycle(delta)
-- end
-- end
-- elseif tl[2] <= UnPredictedCurTime() then
-- -- hold 0
-- delta = 0
-- elseif tl[1] <= UnPredictedCurTime() then
-- -- transition to 0
-- delta = (UnPredictedCurTime() - tl[1]) / (tl[2] - tl[1])
-- delta = qerp(delta, 1, 0)
-- if lhik_model and IsValid(lhik_model) then
-- local key = "in"
-- local tranim = self:GetBuff_Hook("Hook_LHIK_TranslateAnimation", key)
-- key = tranim or key
-- local seq = lhik_model:LookupSequence(key)
-- if seq and seq > 0 then
-- lhik_model:SetSequence(seq)
-- lhik_model:SetCycle(delta)
-- end
-- end
else
-- hasn't started yet
delta = 1
end
if delta == 1 and self.Customize_Hide > 0 then
if !lhik_model or !IsValid(lhik_model) then
justhide = true
delta = math.min(self.Customize_Hide, delta)
else
hide_component = true
end
end
if justhide then
for _, bone in pairs(ArcCW.LHIKBones) do
local vmbone = vm:LookupBone(bone)
if !vmbone then continue end -- Happens when spectating someone prolly
local vmtransform = vm:GetBoneMatrix(vmbone)
if !vmtransform then continue end -- something very bad has happened
local vm_pos = vmtransform:GetTranslation()
local vm_ang = vmtransform:GetAngles()
local newtransform = Matrix()
newtransform:SetTranslation(LerpVector(delta, vm_pos, vm_pos - (EyeAngles():Up() * 12) - (EyeAngles():Forward() * 12) - (EyeAngles():Right() * 4)))
newtransform:SetAngles(vm_ang)
vm:SetBoneMatrix(vmbone, newtransform)
end
end
if !lhik_model or !IsValid(lhik_model) then return end
lhik_model:SetupBones()
if justhide then return end
local cyc = (UnPredictedCurTime() - self.LHIKAnimationStart) / self.LHIKAnimationTime
if self.LHIKAnimation and cyc < 1 then
lhik_model:SetSequence(self.LHIKAnimation)
lhik_model:SetCycle(cyc)
if IsValid(lhik_anim_model) then
lhik_anim_model:SetSequence(self.LHIKAnimation)
lhik_anim_model:SetCycle(cyc)
end
else
local key = "idle"
local tranim = self:GetBuff_Hook("Hook_LHIK_TranslateAnimation", key)
key = tranim or key
if key and key != "DoNotPlayIdle" then
self:DoLHIKAnimation(key, -1)
end
self.LHIKAnimation_IsIdle = true
end
local cf_deltapos = Vector(0, 0, 0)
local cf = 0
for _, bone in pairs(ArcCW.LHIKBones) do
local vmbone = vm:LookupBone(bone)
local lhikbone = lhik_model:LookupBone(bone)
if !vmbone then continue end
if !lhikbone then continue end
local vmtransform = vm:GetBoneMatrix(vmbone)
local lhiktransform = lhik_model:GetBoneMatrix(lhikbone)
if !vmtransform then continue end
if !lhiktransform then continue end
local vm_pos = vmtransform:GetTranslation()
local vm_ang = vmtransform:GetAngles()
local lhik_pos = lhiktransform:GetTranslation()
local lhik_ang = lhiktransform:GetAngles()
local newtransform = Matrix()
newtransform:SetTranslation(LerpVector(delta, vm_pos, lhik_pos))
newtransform:SetAngles(LerpAngle(delta, vm_ang, lhik_ang))
if !self:GetBuff_Override("LHIK_GunDriver") and self.LHIKDelta[lhikbone] and self.LHIKAnimation and cyc < 1 then
local deltapos = lhik_model:WorldToLocal(lhik_pos) - self.LHIKDelta[lhikbone]
if !deltapos:IsZero() then
cf_deltapos = cf_deltapos + deltapos
cf = cf + 1
end
end
self.LHIKDelta[lhikbone] = lhik_model:WorldToLocal(lhik_pos)
if hide_component then
local new_pos = newtransform:GetTranslation()
newtransform:SetTranslation(LerpVector(self.Customize_Hide, new_pos, new_pos - (EyeAngles():Up() * 12) - (EyeAngles():Forward() * 12) - (EyeAngles():Right() * 4)))
end
local matrix = Matrix(newtransform)
vm:SetBoneMatrix(vmbone, matrix)
-- local vm_pos, vm_ang = vm:GetBonePosition(vmbone)
-- local lhik_pos, lhik_ang = lhik_model:GetBonePosition(lhikbone)
-- local pos = LerpVector(delta, vm_pos, lhik_pos)
-- local ang = LerpAngle(delta, vm_ang, lhik_ang)
-- vm:SetBonePosition(vmbone, pos, ang)
end
if !cf_deltapos:IsZero() and cf > 0 and self:GetBuff_Override("LHIK_Animation") then
local new = Vector(0, 0, 0)
local viewmult = self:GetBuff_Override("LHIK_MovementMult") or 1
new[1] = cf_deltapos[2] * viewmult
new[2] = cf_deltapos[1] * viewmult
new[3] = cf_deltapos[3] * viewmult
self.ViewModel_Hit = LerpVector(0.25, self.ViewModel_Hit, new / cf):GetNormalized()
end
end

View File

@@ -0,0 +1,373 @@
--[[
| 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/
--]]
SWEP.Flashlights = {} -- tracks projectedlights
-- {{att = int, light = ProjectedTexture}}
SWEP.CheapFlashlights = {} -- tracks cheap flashlight models + lights
-- {{att = int, dlight = DynamicLight, vlight = ClientsideModel}}
function SWEP:GetHasFlashlights()
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
if self:GetBuff_Stat("Flashlight", i) != nil then return true end
end
return false
end
function SWEP:CreateFlashlightsVM()
self:KillFlashlights()
self.Flashlights = {}
local total_lights = 0
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
if self:GetBuff_Stat("Flashlight", i) then
local newlight = {
att = i,
light = ProjectedTexture(),
bone = self:GetBuff_Stat("FlashlightBone", i) or "laser",
col = self:GetBuff_Stat("FlashlightColor", i) or Color(255, 255, 255),
br = self:GetBuff_Stat("FlashlightBrightness", i) or 2
}
total_lights = total_lights + 1
local l = newlight.light
if !IsValid(l) then continue end
table.insert(self.Flashlights, newlight)
l:SetFOV(self:GetBuff_Stat("FlashlightFOV", i) or 50)
if self:GetBuff_Stat("FlashlightHFOV", i) then
l:SetHorizontalFOV(self:GetBuff_Stat("FlashlightHFOV", i))
end
if self:GetBuff_Stat("FlashlightVFOV", i) then
l:SetVerticalFOV(self:GetBuff_Stat("FlashlightVFOV", i))
end
l:SetFarZ(self:GetBuff_Stat("FlashlightFarZ", i) or 512)
l:SetNearZ(self:GetBuff_Stat("FlashlightNearZ", i) or 4)
local atten = self:GetBuff_Stat("FlashlightAttenuationType", i) or ArcCW.FLASH_ATT_LINEAR
l:SetLinearAttenuation(0)
l:SetConstantAttenuation(0)
l:SetQuadraticAttenuation(0)
if atten == ArcCW.FLASH_ATT_CONSTANT then
l:SetConstantAttenuation(100)
elseif atten == ArcCW.FLASH_ATT_QUADRATIC then
l:SetQuadraticAttenuation(100)
else
l:SetLinearAttenuation(100)
end
l:SetColor(self:GetBuff_Stat("FlashlightColor", i) or Color(255, 255, 255))
l:SetTexture(self:GetBuff_Stat("FlashlightTexture", i))
l:SetBrightness(self:GetBuff_Stat("FlashlightBrightness", i))
l:SetEnableShadows(true)
l:Update()
local g_light = {
Weapon = self,
ProjectedTexture = l
}
table.insert(ArcCW.FlashlightPile, g_light)
end
end
if total_lights > 2 then -- you are a madman
for i, k in pairs(self.Flashlights) do
if k.light:IsValid() then k.light:SetEnableShadows(false) end
end
end
end
-- for world model flashlights we will use a cheap solution similar to what HL2 uses
-- throw up a volumetric light model
-- function SWEP:CreateFlashlightsWM()
-- self:KillFlashlights()
-- self.CheapFlashlights = {}
-- for i, k in pairs(self.Attachments) do
-- if !k.Installed then continue end
-- local atttbl = ArcCW.AttachmentTable[k.Installed]
-- if atttbl.Flashlight then
-- local newlight = {
-- att = i,
-- vlight = ClientsideModel(ArcCW.VolumetricLightModel),
-- scale_x = 1,
-- scale_y = 1,
-- maxz = atttbl.FlashlightFarZ or 512,
-- bone = atttbl.FlashlightBone or "laser",
-- col = Color(255, 255, 255)
-- }
-- local vl = newlight.vlight
-- if !IsValid(vl) then continue end
-- table.insert(self.CheapFlashlights, newlight)
-- local xfov = atttbl.FlashlightHFOV or atttbl.FlashlightFOV or 50
-- local yfov = atttbl.FlashlightVFOV or atttbl.FlashlightFOV or 50
-- local target_x = 128 * (xfov / 90)
-- local target_y = 128 * (yfov / 90)
-- local scale_x = target_x / ArcCW.VolumetricLightX
-- local scale_y = target_y / ArcCW.VolumetricLightY
-- newlight.scale_x = scale_x
-- newlight.scale_y = scale_y
-- vl:SetNoDraw(ArcCW.NoDraw)
-- vl:DrawShadow(false)
-- local col = atttbl.FlashlightColor or Color(255, 255, 255)
-- col = Color(255, 0, 0)
-- newlight.col = col
-- -- vl:SetColor(col)
-- local g_light = {
-- Model = vl,
-- Weapon = self
-- }
-- table.insert(ArcCW.CSModelPile, g_light)
-- end
-- end
-- end
function SWEP:KillFlashlights()
self:KillFlashlightsVM()
-- self:KillFlashlightsWM()
end
function SWEP:KillFlashlightsVM()
if !self.Flashlights then return end
for i, k in pairs(self.Flashlights) do
if k.light and k.light:IsValid() then
k.light:Remove()
end
end
self.Flashlights = nil
end
function SWEP:KillFlashlightsWM()
-- if !self.CheapFlashlights then return end
-- for i, k in pairs(self.CheapFlashlights) do
-- if k.vlight and k.vlight:IsValid() then
-- k.vlight:Remove()
-- end
-- end
-- self.CheapFlashlights = nil
end
-- given fov and distance solve apparent size
local function solvetriangle(angle, dist)
local a = angle / 2
local b = dist
return b * math.tan(a) * 2
end
local flashlight_mat = Material("models/effects/vol_light002")
-- local flashlight_mat = Material("effects/blueblacklargebeam")
function SWEP:DrawFlashlightsWM()
-- if !self.CheapFlashlights then
-- self:CreateFlashlightsWM()
-- end
local owner = self:GetOwner()
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
local atttbl = ArcCW.AttachmentTable[k.Installed]
if !atttbl or !self:GetBuff_Stat("Flashlight", i) then continue end
local maxz = atttbl.FlashlightFarZ or 512
local bone = atttbl.FlashlightBone or "laser"
local col = atttbl.FlashlightColor or Color(255, 255, 255)
if !k.WElement then continue end
local model = k.WElement.Model
if !IsValid(model) then return end
local pos, ang, dir
if !model then
pos = owner:EyePos()
ang = owner:EyeAngles()
dir = ang:Forward()
else
local att = model:LookupAttachment(bone or "laser")
att = att == 0 and model:LookupAttachment("muzzle") or att
if att == 0 then
pos = model:GetPos()
ang = IsValid(owner) and owner:EyeAngles() or model:GetAngles()
dir = ang:Forward()
dir_2 = ang:Up()
else
local attdata = model:GetAttachment(att)
pos, ang = attdata.Pos, attdata.Ang
dir = -ang:Right()
dir_2 = ang:Up()
end
end
local maxs = Vector(2, 2, 2)
local mins = -maxs
-- scale volumetric light
local tr = util.TraceHull({
start = pos,
endpos = pos + (dir * maxz),
mask = MASK_OPAQUE,
mins = mins,
maxs = maxs
})
local z = (tr.HitPos - tr.StartPos):Length()
-- local s_z = z / ArcCW.VolumetricLightZ
local xfov = atttbl.FlashlightHFOV or atttbl.FlashlightFOV or 50
local yfov = atttbl.FlashlightVFOV or atttbl.FlashlightFOV or 50
-- local target_x = 128 * (xfov / 90)
-- local target_y = 128 * (yfov / 90)
local target_x = solvetriangle(xfov, z)
local target_y = target_x
if xfov != yfov then
target_y = solvetriangle(yfov, z)
end
local vs = EyeAngles():Up()
local c1 = pos + vs
local c4 = pos - vs
local c2 = tr.HitPos + (vs * target_y * 0.75)
local c3 = tr.HitPos - (vs * target_y * 0.75)
render.SetMaterial(flashlight_mat)
render.DrawQuad(c1,c2,c3,c4, col)
-- local scale = Matrix()
-- scale:Scale(Vector(s_x, s_y, s_z))
-- k.vlight:SetPos(pos)
-- k.vlight:SetAngles(ang + Angle(0, 0, 90))
-- k.vlight:EnableMatrix("RenderMultiply", scale)
-- k.vlight:SetColor(Color(255, 0, 0, 255))
-- k.vlight:SetRenderMode(RENDERMODE_NORMAL)
-- k.vlight:SetKeyValue("RenderFX", kRenderFxNone)
-- k.vlight:DrawModel()
-- place dynamic light to make some light appear
local dl = DynamicLight(self:EntIndex())
local delta = (z / maxz)
delta = math.Clamp(delta, 0, 1)
if dl then
dl.pos = tr.HitPos
dl.r = col.r
dl.g = col.g
dl.b = col.b
dl.brightness = Lerp(delta, atttbl.FlashlightBrightness or 2, 0)
-- print(z / maxz)
dl.Decay = 1000 / 1
dl.dietime = CurTime() + 0.1
dl.size = xfov * 5
end
end
end
function SWEP:DrawFlashlightsVM()
if !self.Flashlights then
self:CreateFlashlightsVM()
end
local owner = self:GetOwner()
for i, k in pairs(self.Flashlights) do
local model = (self.Attachments[k.att].VElement or {}).Model
local pos, ang
if !model then
pos = owner:EyePos()
ang = owner:EyeAngles()
else
local att = model:LookupAttachment(k.bone or "laser")
att = att == 0 and model:LookupAttachment("muzzle") or att
if att == 0 then
pos = model:GetPos()
ang = owner:EyeAngles()
else
local attdata = model:GetAttachment(att)
pos, ang = attdata.Pos, attdata.Ang
end
end
local tr = util.TraceLine({
start = owner:EyePos(),
endpos = owner:EyePos() - ang:Right() * 128,
mask = MASK_OPAQUE,
filter = LocalPlayer(),
})
if tr.Fraction < 1 then -- We need to push the flashlight back
local tr2 = util.TraceLine({
start = owner:EyePos(),
endpos = owner:EyePos() + ang:Right() * 128,
mask = MASK_OPAQUE,
filter = LocalPlayer(),
})
-- push it as back as the area behind us allows
pos = pos + ang:Right() * 128 * math.min(1 - tr.Fraction, tr2.Fraction)
end
ang:RotateAroundAxis(ang:Up(), 90)
k.light:SetPos(pos)
k.light:SetAngles(ang)
k.light:Update()
-- local col = k.col
-- local dl = DynamicLight(self:EntIndex())
-- if dl then
-- dl.pos = pos
-- dl.r = col.r
-- dl.g = col.g
-- dl.b = col.b
-- dl.brightness = k.br or 2
-- -- print(z / maxz)
-- dl.Decay = 1000 / 0.1
-- dl.dietime = CurTime() + 0.1
-- dl.size = (k.br or 2) * 64
-- end
end
end

View File

@@ -0,0 +1,468 @@
--[[
| 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/
--]]
-- atts are comma separated
-- optic_mrs,,,perk_quickdraw,ammo_match
local function ScreenScaleMulti(input)
return ScreenScale(input) * ArcCW.ConVars["hud_size"]:GetFloat()
end
function SWEP:GetPresetBase()
return self.PresetBase or self:GetClass()
end
function SWEP:GetPresets()
local path = ArcCW.PresetPath .. self:GetPresetBase() .. "/*.txt"
local files = file.Find(path, "DATA")
files = table.Add(files, file.Find(ArcCW.PresetPath .. self:GetPresetBase() .. "/*.json", "DATA"))
return files
end
function SWEP:LoadPreset(presetname)
presetname = presetname or "autosave"
if presetname == "autosave" then
if self:GetNWBool("ArcCW_DisableAutosave", false) then return end
if !ArcCW.ConVars["autosave"]:GetBool() then return end
end
if presetname != "autosave" then
surface.PlaySound("weapons/arccw/install.wav")
end
-- ???
self.Attachments.BaseClass = nil
local presetTbl
-- New behavior
local filename = ArcCW.PresetPath .. self:GetPresetBase() .. "/" .. presetname .. ".json"
if file.Exists(filename, "DATA") then
presetTbl = util.JSONToTable(file.Read(filename))
if presetTbl and presetTbl != {} then
for i = 1, table.Count(self.Attachments) do
local ok = true
if !presetTbl[i] or !ArcCW.AttachmentTable[presetTbl[i].Installed or ""] then
ok = false
end
if !ok then
presetTbl[i] = nil
end
end
end
end
-- Legacy behavior
filename = ArcCW.PresetPath .. self:GetPresetBase() .. "/" .. presetname .. ".txt"
if presetTbl == nil and file.Exists(filename, "DATA") then
local f = file.Open(filename, "r", "DATA")
if !f then return end
presetTbl = {}
for i = 1, table.Count(self.Attachments) do
local line = f:ReadLine()
if !line then continue end
local split = string.Split(string.Trim(line, "\n"), ",")
if !ArcCW.AttachmentTable[split[1]] then continue end
presetTbl[i] = {
Installed = split[1],
SlidePos = split[2] and tonumber(split[2]),
SightMagnifications = split[3] and tonumber(split[3]),
ToggleNum = nil, -- not implemented in legacy preset
}
end
f:Close()
end
if !presetTbl then return end
net.Start("arccw_applypreset")
net.WriteEntity(self)
for k, v in pairs(self.Attachments) do
local att = (presetTbl[k] or {}).Installed
if !att or !ArcCW.AttachmentTable[att] then
net.WriteUInt(0, ArcCW.GetBitNecessity())
continue
end
net.WriteUInt(ArcCW.AttachmentTable[att].ID, ArcCW.GetBitNecessity())
net.WriteBool(presetTbl[k].SlidePos)
if presetTbl[k].SlidePos then
net.WriteFloat(presetTbl[k].SlidePos)
end
if ArcCW.AttachmentTable[att].ToggleStats != nil then
net.WriteUInt(presetTbl[k].ToggleNum or 1, 8)
end
v.ToggleNum = presetTbl[k].ToggleNum or 1
-- not networked
self.SightMagnifications[k] = presetTbl[k].SightMagnifications
end
net.SendToServer()
--[[]
for i = 1, table.Count(self.Attachments) do
local att = presetTbl[i]
if !att then continue end
if ArcCW:PlayerGetAtts(self:GetOwner(), att) == 0 then continue end
if !self.Attachments[i] then continue end
-- detect commas
-- no commas = do nothing
-- commas: If exactly two commas are detected
-- try to parse them as slidepos, magnification
local split = string.Split(att, ",")
local sc = table.Count(split)
local slidepos = 0.5
local mag = -1
if sc == 3 then
att = split[1]
slidepos = tonumber(split[2])
mag = tonumber(split[3])
end
if att == self.Attachments[i].Installed then continue end
self:Detach(i, true, true)
if !ArcCW.AttachmentTable[att] then continue end
self:Attach(i, att, true, true)
if slidepos != 0.5 then
self.Attachments[i].SlidePos = slidepos
end
if mag != -1 then
self.SightMagnifications[i] = mag
end
end
self:SendAllDetails()
self:SavePreset()
]]
end
function SWEP:SavePreset(presetname)
presetname = presetname or "autosave"
if presetname == "autosave" and !ArcCW.ConVars["attinv_free"]:GetBool() then return end
local presetTbl = {}
for i, k in pairs(self.Attachments) do
if k.Installed then
presetTbl[i] = {
Installed = k.Installed,
SlidePos = k.SlidePos,
SightMagnifications = self.SightMagnifications[i],
ToggleNum = k.ToggleNum
}
end
end
filename = ArcCW.PresetPath .. self:GetPresetBase() .. "/" .. presetname .. ".json"
file.CreateDir(ArcCW.PresetPath .. self:GetPresetBase())
file.Write(filename, util.TableToJSON(presetTbl))
local legacy_filename = ArcCW.PresetPath .. self:GetPresetBase() .. "/" .. presetname .. ".txt"
if file.Exists(legacy_filename, "DATA") then
file.Delete(legacy_filename)
end
-- Legacy presets
--[[]
local str = ""
for i, k in pairs(self.Attachments) do
if k.Installed then
str = str .. k.Installed
if k.SlidePos or self.SightMagnifications[i] then
str = str .. "," .. tostring(k.SlidePos or 0.5) .. "," .. tostring(self.SightMagnifications[i] or -1)
end
end
str = str .. "\n"
end
filename = ArcCW.PresetPath .. self:GetPresetBase() .. "/" .. filename .. ".txt"
file.CreateDir(ArcCW.PresetPath .. self:GetPresetBase())
file.Write(filename, str)
]]
end
function SWEP:CreatePresetSave()
if !IsValid(ArcCW.InvHUD) then return end
local bg = vgui.Create("DFrame", ArcCW.InvHUD)
bg:SetPos(0, 0)
bg:SetSize(ScrW(), ScrH())
bg:SetText("")
bg:SetTitle("")
bg:SetDraggable(false)
bg:ShowCloseButton(false)
bg.Paint = function(span)
surface.SetDrawColor(0, 0, 0, 200)
surface.DrawRect(0, 0, ScrW(), ScrH())
end
bg:MakePopup()
local text = vgui.Create("DTextEntry", bg)
text:SetSize(ScreenScaleMulti(256), ScreenScaleMulti(26))
text:Center()
text:RequestFocus()
text:SetFont("ArcCW_24")
text:SetText(self.LastPresetName or "")
local accept = vgui.Create("DButton", bg)
accept:SetSize((ScreenScaleMulti(256) - ScreenScaleMulti(2)) / 2, ScreenScaleMulti(14))
accept:SetText("")
accept:SetPos((ScrW() - ScreenScaleMulti(256)) / 2, ((ScrH() - ScreenScaleMulti(14)) / 2) + ScreenScaleMulti(26) + ScreenScaleMulti(2))
accept.OnMousePressed = function(spaa, kc)
local txt = text:GetText()
txt = string.sub(txt, 0, 36)
self.LastPresetName = txt
self:SavePreset(txt)
bg:Close()
bg:Remove()
ArcCW.InvHUD_FormPresets()
end
accept.Paint = function(spaa, w, h)
if !self:IsValid() then return end
local Bfg_col = Color(255, 255, 255, 255)
local Bbg_col = Color(0, 0, 0, 100)
if spaa:IsHovered() then
Bbg_col = Color(255, 255, 255, 100)
Bfg_col = Color(0, 0, 0, 255)
end
surface.SetDrawColor(Bbg_col)
surface.DrawRect(0, 0, w, h)
local txt = "Save"
surface.SetTextColor(Bfg_col)
surface.SetTextPos(ScreenScaleMulti(2), ScreenScaleMulti(1))
surface.SetFont("ArcCW_12")
surface.DrawText(txt)
end
local cancel = vgui.Create("DButton", bg)
cancel:SetSize((ScreenScaleMulti(256) - ScreenScaleMulti(2)) / 2, ScreenScaleMulti(14))
cancel:SetText("")
cancel:SetPos(((ScrW() - ScreenScaleMulti(256)) / 2) + ScreenScaleMulti(128 + 1), ((ScrH() - ScreenScaleMulti(14)) / 2) + ScreenScaleMulti(26) + ScreenScaleMulti(2))
cancel.OnMousePressed = function(spaa, kc)
bg:Close()
bg:Remove()
end
cancel.Paint = function(spaa, w, h)
if !self:IsValid() then return end
local Bfg_col = Color(255, 255, 255, 255)
local Bbg_col = Color(0, 0, 0, 100)
if spaa:IsHovered() then
Bbg_col = Color(255, 255, 255, 100)
Bfg_col = Color(0, 0, 0, 255)
end
surface.SetDrawColor(Bbg_col)
surface.DrawRect(0, 0, w, h)
local txt = "Cancel"
surface.SetTextColor(Bfg_col)
surface.SetTextPos(ScreenScaleMulti(2), ScreenScaleMulti(1))
surface.SetFont("ArcCW_12")
surface.DrawText(txt)
end
end
function SWEP:CreatePresetMenu()
if !IsValid(ArcCW.InvHUD) then return end
if !IsValid(ArcCW.InvHUD) then return end
local bg = vgui.Create("DFrame", ArcCW.InvHUD)
bg:SetPos(0, 0)
bg:SetSize(ScrW(), ScrH())
bg:SetText("")
bg:SetTitle("")
bg:SetDraggable(false)
bg:ShowCloseButton(false)
bg.Paint = function(span)
surface.SetDrawColor(0, 0, 0, 200)
surface.DrawRect(0, 0, ScrW(), ScrH())
end
local cancel = vgui.Create("DButton", bg)
cancel:SetSize(ScreenScaleMulti(128), ScreenScaleMulti(14))
cancel:SetText("")
cancel:SetPos((ScrW() - ScreenScaleMulti(128)) / 2, ScrH() - ScreenScaleMulti(32))
cancel.OnMousePressed = function(spaa, kc)
bg:Close()
bg:Remove()
end
cancel.Paint = function(spaa, w, h)
if !self:IsValid() then return end
local Bfg_col = Color(255, 255, 255, 255)
local Bbg_col = Color(0, 0, 0, 100)
if spaa:IsHovered() then
Bbg_col = Color(255, 255, 255, 100)
Bfg_col = Color(0, 0, 0, 255)
end
surface.SetDrawColor(Bbg_col)
surface.DrawRect(0, 0, w, h)
local txt = "Cancel"
surface.SetTextColor(Bfg_col)
surface.SetTextPos(ScreenScaleMulti(2), ScreenScaleMulti(1))
surface.SetFont("ArcCW_12")
surface.DrawText(txt)
end
local presetsmenu = vgui.Create("DScrollPanel", bg)
presetsmenu:SetText("")
presetsmenu:SetSize(ScreenScaleMulti(256), ScrH() - ScreenScaleMulti(64))
presetsmenu:SetPos((ScrW() - ScreenScaleMulti(256)) / 2, ScreenScaleMulti(8))
presetsmenu.Paint = function(span, w, h)
end
local sbar = presetsmenu:GetVBar()
sbar.Paint = function() end
sbar.btnUp.Paint = function(span, w, h)
end
sbar.btnDown.Paint = function(span, w, h)
end
sbar.btnGrip.Paint = function(span, w, h)
surface.SetDrawColor(255, 255, 255, 255)
surface.DrawRect(0, 0, w, h)
end
local c = 0
for i, k in pairs(self:GetPresets()) do
if string.StripExtension(k) == "autosave" then continue end
local preset = vgui.Create("DButton", presetsmenu)
preset:SetSize(ScreenScaleMulti(254), ScreenScaleMulti(14))
preset:SetText("")
preset:Dock(TOP)
preset:DockMargin( 0, 0, 0, ScreenScaleMulti(2) )
preset.PresetName = string.StripExtension(k) --string.sub(k, 1, -5)
preset.PresetFile = k
preset.OnMousePressed = function(spaa, kc)
self.LastPresetName = spaa.PresetName
self:LoadPreset(spaa.PresetName)
bg:Close()
bg:Remove()
end
preset.Paint = function(spaa, w, h)
if !self:IsValid() then return end
local Bfg_col = Color(255, 255, 255, 255)
local Bbg_col = Color(0, 0, 0, 100)
if spaa:IsHovered() then
Bbg_col = Color(255, 255, 255, 100)
Bfg_col = Color(0, 0, 0, 255)
end
surface.SetDrawColor(Bbg_col)
surface.DrawRect(0, 0, w, h)
surface.SetTextColor(Bfg_col)
surface.SetTextPos(ScreenScaleMulti(2), ScreenScaleMulti(1))
surface.SetFont("ArcCW_12")
surface.DrawText(string.upper(spaa.PresetName))
end
local close = vgui.Create("DButton", preset)
close:SetSize(ScreenScaleMulti(16), ScreenScaleMulti(16))
close:SetText("")
close:Dock(RIGHT)
close.OnMousePressed = function(spaa, kc)
local filename = spaa.PresetFile
file.Delete(filename)
preset:Remove()
end
close.Paint = function(spaa, w, h)
if !self:IsValid() or preset:IsHovered() then return end
local Bfg_col = Color(255, 255, 255, 255)
local Bbg_col = Color(0, 0, 0, 100)
if spaa:IsHovered() then
Bbg_col = Color(255, 255, 255, 100)
Bfg_col = Color(0, 0, 0, 255)
end
surface.SetDrawColor(Bbg_col)
surface.DrawRect(0, 0, w, h)
local w_x, h_x = surface.GetTextSize("×")
surface.SetTextColor(Bfg_col)
surface.SetTextPos((ScreenScaleMulti(16) - w_x) / 2, (ScreenScaleMulti(16) - h_x) / 2)
surface.SetFont("ArcCW_12")
surface.DrawText("×")
end
c = c + 1
end
if c == 0 then
local label = vgui.Create("DLabel", presetsmenu)
label:SetSize(ScreenScaleMulti(254), ScreenScaleMulti(14))
label:SetText("")
label:Dock(TOP)
label:DockMargin( 0, 0, 0, ScreenScaleMulti(2) )
label.Paint = function(spaa, w, h)
local Bfg_col = Color(255, 255, 255, 255)
local txt = "No presets found! Go make some!"
surface.SetTextColor(Bfg_col)
surface.SetTextPos(ScreenScaleMulti(2), ScreenScaleMulti(1))
surface.SetFont("ArcCW_12")
surface.DrawText(txt)
end
end
end
function SWEP:ClosePresetMenu()
end

View File

@@ -0,0 +1,266 @@
--[[
| 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/
--]]
function SWEP:AdjustMouseSensitivity()
if self:GetState() != ArcCW.STATE_SIGHTS then return end
local threshold = ArcCW.ConVars["adjustsensthreshold"]:GetFloat()
local irons = self:GetActiveSights() or {}
local tmag = ((irons.Magnification or 1) + (irons.ScopeMagnification or 0))
if tmag < threshold then return end
return 1 / tmag
end
function SWEP:Scroll(var)
local irons = self:GetActiveSights()
if irons.ScrollFunc == ArcCW.SCROLL_ZOOM then
if !irons.ScopeMagnificationMin then return end
if !irons.ScopeMagnificationMax then return end
local old = irons.ScopeMagnification
local minus = var < 0
var = math.abs(irons.ScopeMagnificationMax - irons.ScopeMagnificationMin)
var = var / (irons.ZoomLevels or 5)
if minus then
var = var * -1
end
irons.ScopeMagnification = irons.ScopeMagnification - var
irons.ScopeMagnification = math.Clamp(irons.ScopeMagnification, irons.ScopeMagnificationMin, irons.ScopeMagnificationMax)
self.SightMagnifications[irons.Slot or 0] = irons.ScopeMagnification
if old != irons.ScopeMagnification then
self:MyEmitSound(irons.ZoomSound or "", 75, math.Rand(95, 105), 1, CHAN_ITEM)
end
-- if !irons.MinZoom then return end
-- if !irons.MaxZoom then return end
-- local old = irons.Magnification
-- irons.Magnification = irons.Magnification - var
-- irons.Magnification = math.Clamp(irons.Magnification, irons.MinZoom, irons.MaxZoom)
-- if old != irons.Magnification then
-- self:MyEmitSound(irons.ZoomSound or "", 75, 100, 1, CHAN_ITEM)
-- end
end
end
local ang0 = Angle(0, 0, 0)
SWEP.ViewPunchAngle = Angle(ang0)
SWEP.ViewPunchVelocity = Angle(ang0)
function SWEP:OurViewPunch(angle)
self.ViewPunchVelocity:Add(angle)
for i = 1, 3 do self.ViewPunchVelocity[i] = math.Clamp(self.ViewPunchVelocity[i], -180, 180) end
end
function SWEP:GetOurViewPunchAngles()
local a = self:GetOwner():GetViewPunchAngles()
for i = 1, 3 do a[i] = a[i] + self.ViewPunchAngle[i] * 10 end
return a
end
local function lensqr(ang)
return (ang[1] ^ 2) + (ang[2] ^ 2) + (ang[3] ^ 2)
end
-- scraped from source SDK 2013, just like this viewpunch damping code
local PUNCH_DAMPING = 9
local PUNCH_SPRING_CONSTANT = 120
function SWEP:DoOurViewPunch()
-- if ( player->m_Local.m_vecPunchAngle->LengthSqr() > 0.001 || player->m_Local.m_vecPunchAngleVel->LengthSqr() > 0.001 )
local vpa = self.ViewPunchAngle
local vpv = self.ViewPunchVelocity
if lensqr(vpa) + lensqr(vpv) > 0.000001 then
-- {
-- player->m_Local.m_vecPunchAngle += player->m_Local.m_vecPunchAngleVel * gpGlobals->frametime;
-- float damping = 1 - (PUNCH_DAMPING * gpGlobals->frametime);
local ft = FrameTime()
vpa = vpa + (vpv * ft)
local damping = 1 - (PUNCH_DAMPING * ft)
-- if ( damping < 0 )
-- {
-- damping = 0;
-- }
if damping < 0 then damping = 0 end
-- player->m_Local.m_vecPunchAngleVel *= damping;
vpv = vpv * damping
-- // torsional spring
-- // UNDONE: Per-axis spring constant?
-- float springForceMagnitude = PUNCH_SPRING_CONSTANT * gpGlobals->frametime;
local springforcemagnitude = PUNCH_SPRING_CONSTANT * ft
-- springForceMagnitude = clamp(springForceMagnitude, 0.f, 2.f );
springforcemagnitude = math.Clamp(springforcemagnitude, 0, 2)
-- player->m_Local.m_vecPunchAngleVel -= player->m_Local.m_vecPunchAngle * springForceMagnitude;
vpv = vpv - (vpa * springforcemagnitude)
-- // don't wrap around
-- player->m_Local.m_vecPunchAngle.Init(
-- clamp(player->m_Local.m_vecPunchAngle->x, -89.f, 89.f ),
-- clamp(player->m_Local.m_vecPunchAngle->y, -179.f, 179.f ),
-- clamp(player->m_Local.m_vecPunchAngle->z, -89.f, 89.f ) );
-- }
vpa[1] = math.Clamp(vpa[1], -89.9, 89.9)
vpa[2] = math.Clamp(vpa[2], -179.9, 179.9)
vpa[3] = math.Clamp(vpa[3], -89.9, 89.9)
self.ViewPunchAngle = vpa
self.ViewPunchVelocity = vpv
else
self.ViewPunchAngle = Angle(ang0)
self.ViewPunchVelocity = Angle(ang0)
end
end
-- viewbob during reload and firing shake
SWEP.ProceduralViewOffset = Angle(ang0)
local procedural_spdlimit = 5
local oldangtmp
local mzang_fixed,mzang_fixed_last
local mzang_velocity = Angle(ang0)
local progress = 0
local targint,targbool
function SWEP:CoolView(ply, pos, ang, fov)
if !ang then return end
if ply != LocalPlayer() then return end
if ply:ShouldDrawLocalPlayer() then return end
local vm = ply:GetViewModel()
if !IsValid(vm) then return end
local ftv = FrameTime()
local gunbone, gbslot = self:GetBuff_Override("LHIK_CamDriver")
local lhik_anim_model = gbslot and self.Attachments[gbslot].GodDriver and self.Attachments[gbslot].GodDriver.Model
if IsValid(lhik_anim_model) and lhik_anim_model:GetAttachment(gunbone) then
local catang = lhik_anim_model:GetAttachment(gunbone).Ang
catang:Sub( Angle( 0, 90, 90 ) )
catang.y = -catang.y
local r = catang.r
catang.r = -catang.p
catang.p = -r
ang:RotateAroundAxis( ang:Right(), catang.x )
ang:RotateAroundAxis( ang:Up(), catang.y )
ang:RotateAroundAxis( ang:Forward(), catang.z )
end
-- Cam_Offset_Ang might not always be assigned properly. Try not to use it if it's nil, or it'll tilt the player's view.
local att = self:GetBuff_Override("Override_CamAttachment", self.CamAttachment) or -1
if vm:GetAttachment(att) and self.Cam_Offset_Ang then
local attang = vm:WorldToLocalAngles(vm:GetAttachment(att).Ang)
attang:Sub(self.Cam_Offset_Ang)
ang:Add(attang)
return
end
local viewbobintensity = self.ProceduralViewBobIntensity or 0.3
if viewbobintensity == 0 then return end
oldpostmp = pos * 1
oldangtmp = ang * 1
targbool = self:GetNextPrimaryFire() - .1 > CurTime()
targint = targbool and 1 or 0
targint = math.min(targint, 1-math.pow( vm:GetCycle(), 2 ) )
progress = Lerp(ftv * 15, progress, targint)
local angpos = vm:GetAttachment(self.ProceduralViewBobAttachment or self.MuzzleEffectAttachment or 1)
if angpos and self:GetReloading() then
mzang_fixed = vm:WorldToLocalAngles(angpos.Ang)
mzang_fixed:Normalize()
else return
end
self.ProceduralViewOffset:Normalize()
if mzang_fixed_last then
local delta = mzang_fixed - mzang_fixed_last
delta:Normalize()
mzang_velocity = mzang_velocity + delta * 2
mzang_velocity.p = math.Approach(mzang_velocity.p, -self.ProceduralViewOffset.p * 2, ftv * 20)
mzang_velocity.p = math.Clamp(mzang_velocity.p, -procedural_spdlimit, procedural_spdlimit)
self.ProceduralViewOffset.p = self.ProceduralViewOffset.p + mzang_velocity.p * ftv
self.ProceduralViewOffset.p = math.Clamp(self.ProceduralViewOffset.p, -90, 90)
mzang_velocity.y = math.Approach(mzang_velocity.y, -self.ProceduralViewOffset.y * 2, ftv * 20)
mzang_velocity.y = math.Clamp(mzang_velocity.y, -procedural_spdlimit, procedural_spdlimit)
self.ProceduralViewOffset.y = self.ProceduralViewOffset.y + mzang_velocity.y * ftv
self.ProceduralViewOffset.y = math.Clamp(self.ProceduralViewOffset.y, -90, 90)
mzang_velocity.r = math.Approach(mzang_velocity.r, -self.ProceduralViewOffset.r * 2, ftv * 20)
mzang_velocity.r = math.Clamp(mzang_velocity.r, -procedural_spdlimit, procedural_spdlimit)
self.ProceduralViewOffset.r = self.ProceduralViewOffset.r + mzang_velocity.r * ftv
self.ProceduralViewOffset.r = math.Clamp(self.ProceduralViewOffset.r, -90, 90)
end
self.ProceduralViewOffset.p = math.Approach(self.ProceduralViewOffset.p, 0, (1 - progress) * ftv * -self.ProceduralViewOffset.p)
self.ProceduralViewOffset.y = math.Approach(self.ProceduralViewOffset.y, 0, (1 - progress) * ftv * -self.ProceduralViewOffset.y)
self.ProceduralViewOffset.r = math.Approach(self.ProceduralViewOffset.r, 0, (1 - progress) * ftv * -self.ProceduralViewOffset.r)
mzang_fixed_last = mzang_fixed
local ints = 3 * ArcCW.ConVars["vm_coolview_mult"]:GetFloat() * -viewbobintensity
ang:RotateAroundAxis(ang:Right(), Lerp(progress, 0, -self.ProceduralViewOffset.p) * ints)
ang:RotateAroundAxis(ang:Up(), Lerp(progress, 0, self.ProceduralViewOffset.y / 2) * ints)
ang:RotateAroundAxis(ang:Forward(), Lerp(progress, 0, self.ProceduralViewOffset.r / 3) * ints)
ang = LerpAngle(0, ang, oldangtmp)
end
function SWEP:CalcView(ply, pos, ang, fov)
if !CLIENT then return end
if ArcCW.ConVars["vm_coolview"]:GetBool() then
self:CoolView(ply, pos, ang, fov)
end
if ArcCW.ConVars["shake"]:GetBool() and !engine.IsRecordingDemo() then
local de = (0.2 + (self:GetSightDelta()*0.8))
ang = ang + (AngleRand() * self.RecoilAmount * 0.006 * de)
end
ang = ang + (self.ViewPunchAngle * 10)
return pos, ang, fov
end
function SWEP:ShouldGlint()
return self:GetBuff_Override("ScopeGlint") and self:GetState() == ArcCW.STATE_SIGHTS
end
function SWEP:DoScopeGlint()
end

View File

@@ -0,0 +1,887 @@
--[[
| 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/
--]]
--[[
Please, for the love of god, don't create objects in functions that are called multiple times per frame.
The garbage collector will explode and so will players' comptuters.
That means minimize usage of things that generate new objects, including:
calls to Vector() or Angle(); use vector_origin and angle_zero if the value isn't modified
arithmetic using +, -, * and / on Vectors and Angles; modifying individual parameters is fine
functions like Angle:Right() and Vector:Angle(); however functions like Vector:Add() and Angle:Add() are fine
Cache them if you use them more than one time!
]]
local mth = math
local m_appor = mth.Approach
local m_clamp = mth.Clamp
local f_lerp = Lerp
local srf = surface
SWEP.ActualVMData = false
local swayxmult, swayymult, swayzmult, swayspeed = 1, 1, 1, 1
local lookxmult, lookymult = 1, 1
SWEP.VMPos = Vector()
SWEP.VMAng = Angle()
SWEP.VMPosOffset = Vector()
SWEP.VMAngOffset = Angle()
SWEP.VMPosOffset_Lerp = Vector()
SWEP.VMAngOffset_Lerp = Angle()
SWEP.VMLookLerp = Angle()
SWEP.StepBob = 0
SWEP.StepBobLerp = 0
SWEP.StepRandomX = 1
SWEP.StepRandomY = 1
SWEP.LastEyeAng = Angle()
SWEP.SmoothEyeAng = Angle()
SWEP.LastVelocity = Vector()
SWEP.Velocity_Lerp = Vector()
SWEP.VelocityLastDiff = 0
SWEP.Breath_Intensity = 1
SWEP.Breath_Rate = 1
-- magic variables
local sprint_vec1 = Vector(-2, 5, 2)
local sprint_vec2 = Vector(0, 7, 3)
local sprint_ang1 = Angle(-15, -15, 0)
local spring_ang2 = Angle(-15, 15, -22)
local sight_vec1 = Vector(0, 15, -4)
local sight_vec2 = Vector(1, 5, -1)
local sight_ang1 = Angle(0, 0, -45)
local sight_ang2 = Angle(-5, 0, -10)
local sextra_vec = Vector(0.0002, 0.001, 0.005)
local procdraw_vec = Vector(0, 0, -5)
local procdraw_ang = Angle(-70, 30, 0)
local prochol_ang = Angle(-70, 30, 10)
local lst = SysTime()
local function scrunkly()
local ret = (SysTime() - (lst or SysTime())) * GetConVar("host_timescale"):GetFloat()
return ret
end
local function LerpC(t, a, b, powa)
return a + (b - a) * math.pow(t, powa)
end
local function ApproachMod(usrobj, to, dlt)
usrobj[1] = m_appor(usrobj[1], to[1], dlt)
usrobj[2] = m_appor(usrobj[2], to[2], dlt)
usrobj[3] = m_appor(usrobj[3], to[3], dlt)
end
local function LerpMod(usrobj, to, dlt, clamp_ang)
usrobj[1] = f_lerp(dlt, usrobj[1], to[1])
usrobj[2] = f_lerp(dlt, usrobj[2], to[2])
usrobj[3] = f_lerp(dlt, usrobj[3], to[3])
if clamp_ang then
for i = 1, 3 do usrobj[i] = math.NormalizeAngle(usrobj[i]) end
end
end
local function LerpMod2(from, usrobj, dlt, clamp_ang)
usrobj[1] = f_lerp(dlt, from[1], usrobj[1])
usrobj[2] = f_lerp(dlt, from[2], usrobj[2])
usrobj[3] = f_lerp(dlt, from[3], usrobj[3])
if clamp_ang then
for i = 1, 3 do usrobj[i] = math.NormalizeAngle(usrobj[i]) end
end
end
-- debug for testing garbage count
-- TODO: comment this out or something before actually going into main branch
local sw = false
local tries = {}
local totaltries = 1000
local sw_start = 0
local sw_orig = 0
concommand.Add("arccw_dev_stopwatch", function() tries = {} sw = true end)
local function stopwatch(name)
if !sw then return end
if name == true then
local d = (collectgarbage("count") - sw_orig)
if #tries == 0 then print(" total garbage: " .. d) end
table.insert(tries, d)
if #tries == totaltries then
sw = false
local average = 0
for _, v in ipairs(tries) do average = average + v end
average = average / totaltries
print("----------------------------------")
print("average over " .. totaltries .. " tries: " .. average)
end
return
end
local gb = collectgarbage("count")
if name then
if #tries == 0 then print(name .. ": " .. (gb - sw_start)) end
else
if #tries == 0 then print("----------------------------------") end
sw_orig = gb
end
sw_start = gb
end
function SWEP:Move_Process(EyePos, EyeAng, velocity)
local VMPos, VMAng = self.VMPos, self.VMAng
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
local VMPosOffset_Lerp, VMAngOffset_Lerp = self.VMPosOffset_Lerp, self.VMAngOffset_Lerp
local FT = scrunkly()
local sightedmult = (self:GetState() == ArcCW.STATE_SIGHTS and 0.05) or 1
local sg = self:GetSightDelta()
VMPos:Set(EyePos)
VMAng:Set(EyeAng)
VMPosOffset.x = math.Clamp(velocity.z * 0.0025, -1, 1) * sightedmult
VMPosOffset.x = VMPosOffset.x + (velocity.x * 0.001 * sg)
VMPosOffset.y = math.Clamp(velocity.y * -0.002, -1, 1) * sightedmult
VMPosOffset.z = math.Clamp(VMPosOffset.x * -2, -4, 4)
VMPosOffset_Lerp.x = Lerp(8 * FT, VMPosOffset_Lerp.x, VMPosOffset.x)
VMPosOffset_Lerp.y = Lerp(8 * FT, VMPosOffset_Lerp.y, VMPosOffset.y)
VMPosOffset_Lerp.z = Lerp(8 * FT, VMPosOffset_Lerp.z, VMPosOffset.z)
--VMAngOffset.x = math.Clamp(VMPosOffset.x * 8, -4, 4)
VMAngOffset.y = VMPosOffset.y
VMAngOffset.z = VMPosOffset.y * 0.5 + (VMPosOffset.x * -5) + (velocity.x * -0.005 * sg)
VMAngOffset_Lerp.x = LerpC(10 * FT, VMAngOffset_Lerp.x, VMAngOffset.x, 0.75)
VMAngOffset_Lerp.y = LerpC(5 * FT, VMAngOffset_Lerp.y, VMAngOffset.y, 0.6)
VMAngOffset_Lerp.z = Lerp(25 * FT, VMAngOffset_Lerp.z, VMAngOffset.z)
VMPos:Add(VMAng:Up() * VMPosOffset_Lerp.x)
VMPos:Add(VMAng:Right() * VMPosOffset_Lerp.y)
VMPos:Add(VMAng:Forward() * VMPosOffset_Lerp.z)
VMAngOffset_Lerp:Normalize()
VMAng:Add(VMAngOffset_Lerp)
end
local stepend = math.pi * 4
function SWEP:Step_Process(EyePos, EyeAng, velocity)
local VMPos, VMAng = self.VMPos, self.VMAng
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
local VMPosOffset_Lerp = self.VMPosOffset_Lerp
local state = self:GetState()
local sprd = self:GetSprintDelta()
if state == ArcCW.STATE_SPRINT and self:SelectAnimation("idle_sprint") and !self:GetReloading() and !self:CanShootWhileSprint() then
velocity = 0
else
velocity = math.min(velocity:Length(), 400) * Lerp(sprd, 1, 1.25)
end
local delta = math.abs(self.StepBob * 2 / stepend - 1)
local FT = scrunkly() --FrameTime()
local sightedmult = (state == ArcCW.STATE_SIGHTS and 0.25) or 1
local sprintmult = (state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() and 2) or 1
local pronemult = (self:IsProne() and 10) or 1
local onground = self:GetOwner():OnGround()
self.StepBob = self.StepBob + (velocity * 0.00015 + (math.pow(delta, 0.01) * 0.03)) * swayspeed * FT * 300
if self.StepBob >= stepend then
self.StepBob = 0
self.StepRandomX = math.Rand(1, 1.5)
self.StepRandomY = math.Rand(1, 1.5)
end
if velocity == 0 then
self.StepBob = 0
end
if onground then
-- oh no it says sex tra
local sextra = vector_origin
if (state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() and !self:SelectAnimation("idle_sprint")) or true then
sextra = LerpVector(sprd, vector_origin, sextra_vec)
end
VMPosOffset.x = (math.sin(self.StepBob) * velocity * (0.000375 + sextra.x) * sightedmult * swayxmult) * self.StepRandomX
VMPosOffset.y = (math.sin(self.StepBob * 0.5) * velocity * (0.0005 + sextra.y) * sightedmult * sprintmult * pronemult * swayymult) * self.StepRandomY
VMPosOffset.z = math.sin(self.StepBob * 0.75) * velocity * (0.002 + sextra.z) * sightedmult * pronemult * swayzmult
end
VMPosOffset_Lerp.x = Lerp(32 * FT, VMPosOffset_Lerp.x, VMPosOffset.x)
VMPosOffset_Lerp.y = Lerp(4 * FT, VMPosOffset_Lerp.y, VMPosOffset.y)
VMPosOffset_Lerp.z = Lerp(2 * FT, VMPosOffset_Lerp.z, VMPosOffset.z)
VMAngOffset.x = VMPosOffset_Lerp.x * 2
VMAngOffset.y = VMPosOffset_Lerp.y * -7.5
VMAngOffset.z = VMPosOffset_Lerp.y * 10
VMPos:Add(VMAng:Up() * VMPosOffset_Lerp.x)
VMPos:Add(VMAng:Right() * VMPosOffset_Lerp.y)
VMPos:Add(VMAng:Forward() * VMPosOffset_Lerp.z)
VMAng:Add(VMAngOffset)
end
function SWEP:Breath_Health()
local owner = self:GetOwner()
if !IsValid(owner) then return end
local health = owner:Health()
local maxhealth = owner:GetMaxHealth()
self.Breath_Intensity = math.Clamp(maxhealth / health, 0, 2)
self.Breath_Rate = math.Clamp((maxhealth * 0.5) / health, 1, 1.5)
end
function SWEP:Breath_StateMult()
local owner = self:GetOwner()
if !IsValid(owner) then return end
local sightedmult = (self:GetState() == ArcCW.STATE_SIGHTS and 0.05) or 1
self.Breath_Intensity = self.Breath_Intensity * sightedmult
end
function SWEP:Breath_Process(EyePos, EyeAng)
local VMPos, VMAng = self.VMPos, self.VMAng
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
-- self:Breath_Health() Snaps around when regenerating
self:Breath_StateMult()
VMPosOffset.x = (math.sin(CurTime() * 2 * self.Breath_Rate) * 0.1) * self.Breath_Intensity
VMPosOffset.y = (math.sin(CurTime() * 2.5 * self.Breath_Rate) * 0.025) * self.Breath_Intensity
VMAngOffset.x = VMPosOffset.x * 1.5
VMAngOffset.y = VMPosOffset.y * 2
VMAngOffset.z = VMPosOffset.y * VMPosOffset.x * -40
VMPos:Add(VMAng:Up() * VMPosOffset.x)
VMPos:Add(VMAng:Right() * VMPosOffset.y)
VMAng:Add(VMAngOffset)
end
function SWEP:Look_Process(EyePos, EyeAng, velocity)
local VMPos, VMAng = self.VMPos, self.VMAng
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
local FT = scrunkly()
local sightedmult = (self:GetState() == ArcCW.STATE_SIGHTS and 0.25) or 1
self.SmoothEyeAng = LerpAngle(0.05, self.SmoothEyeAng, EyeAng - self.LastEyeAng)
-- local xd, yd = (velocity.z / 10), (velocity.y / 200)
VMPosOffset.x = -self.SmoothEyeAng.x * -0.5 * sightedmult * lookxmult
VMPosOffset.y = self.SmoothEyeAng.y * 0.5 * sightedmult * lookymult
VMAngOffset.x = VMPosOffset.x * 0.75
VMAngOffset.y = VMPosOffset.y * 2.5
VMAngOffset.z = VMPosOffset.x * 2 + VMPosOffset.y * -2
self.VMLookLerp.y = Lerp(FT * 10, self.VMLookLerp.y, VMAngOffset.y * -1.5 + self.SmoothEyeAng.y)
VMAng.y = VMAng.y - self.VMLookLerp.y
VMPos:Add(VMAng:Up() * VMPosOffset.x)
VMPos:Add(VMAng:Right() * VMPosOffset.y)
VMAng:Add(VMAngOffset)
end
function SWEP:GetVMPosition(EyePos, EyeAng)
local velocity = self:GetOwner():GetVelocity()
velocity = WorldToLocal(velocity, angle_zero, vector_origin, EyeAng)
self:Move_Process(EyePos, EyeAng, velocity)
stopwatch("Move_Process")
self:Step_Process(EyePos, EyeAng, velocity)
stopwatch("Step_Process")
self:Breath_Process(EyePos, EyeAng)
stopwatch("Breath_Process")
self:Look_Process(EyePos, EyeAng, velocity)
stopwatch("Look_Process")
self.LastEyeAng = EyeAng
self.LastEyePos = EyePos
self.LastVelocity = velocity
return self.VMPos, self.VMAng
end
SWEP.TheJ = {posa = Vector(), anga = Angle()}
local rap_pos = Vector()
local rap_ang = Angle()
local actual
local target = {pos = Vector(), ang = Angle()}
local GunDriverFix = Angle( 0, 90, 90 )
function SWEP:GetViewModelPosition(pos, ang)
if ArcCW.ConVars["dev_benchgun"]:GetBool() then
if ArcCW.ConVars["dev_benchgun_custom"]:GetString() then
local bgc = ArcCW.ConVars["dev_benchgun_custom"]:GetString()
if string.Left(bgc, 6) != "setpos" then return vector_origin, angle_zero end
bgc = string.TrimLeft(bgc, "setpos ")
bgc = string.Replace(bgc, ";setang", "")
bgc = string.Explode(" ", bgc)
return Vector(bgc[1], bgc[2], bgc[3]), Angle(bgc[4], bgc[5], bgc[6])
else
return vector_origin, angle_zero
end
end
stopwatch()
local owner = self:GetOwner()
if !IsValid(owner) or !owner:Alive() then return end
local FT = scrunkly()
local CT = CurTime()
local TargetTick = (1 / FT) / 66.66
local cdelta = math.Clamp(math.ease.InOutSine((owner:GetViewOffset().z - owner:GetCurrentViewOffset().z) / (owner:GetViewOffset().z - owner:GetViewOffsetDucked().z)),0,1)
if TargetTick < 1 then
FT = FT * TargetTick
end
local vm = LocalPlayer():GetViewModel()
local asight = self:GetActiveSights()
local state = self:GetState()
local sgtd = self:GetSightDelta()
local sprd = self:GetSprintDelta()
local sprinted = self.Sprinted or state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint()
local sighted = self.Sighted or state == ArcCW.STATE_SIGHTS
local holstered = self:GetCurrentFiremode().Mode == 0
if game.SinglePlayer() then
sprinted = state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint()
sighted = state == ArcCW.STATE_SIGHTS
end
local oldpos, oldang = Vector(), Angle()
oldpos:Set(pos)
oldang:Set(ang)
ang:Sub(self:GetOurViewPunchAngles())
actual = self.ActualVMData or {
pos = Vector(),
ang = Angle(),
down = 1,
sway = 1,
bob = 1,
evpos = Vector(),
evang = Angle(),
}
local apos, aang = self:GetBuff_Override("Override_ActivePos", self.ActivePos), self:GetBuff_Override("Override_ActiveAng", self.ActiveAng)
local cpos, cang = self:GetBuff("CrouchPos", true) or apos, self:GetBuff("CrouchAng", true) or aang
target.down = 1
target.sway = 2
target.bob = 2
stopwatch("set")
if self:InBipod() and self:GetBipodAngle() then
local bpos = self:GetBuff_Override("Override_InBipodPos", self.InBipodPos)
target.pos:Set(asight and asight.Pos or apos)
target.ang:Set(asight and asight.Ang or aang)
local BEA = (self.BipodStartAngle or self:GetBipodAngle()) - owner:EyeAngles()
target.pos:Add(BEA:Right() * bpos.x * self.InBipodMult.x)
target.pos:Add(BEA:Forward() * bpos.y * self.InBipodMult.y)
target.pos:Add(BEA:Up() * bpos.z * self.InBipodMult.z)
target.sway = 0.2
-- elseif (owner:Crouching() or owner:KeyDown(IN_DUCK)) and !self:GetReloading() then
-- target.pos:Set(self:GetBuff("CrouchPos", true) or apos)
-- target.ang:Set(self:GetBuff("CrouchAng", true) or aang)
elseif self:GetReloading() then
target.pos:Set(self:GetBuff("ReloadPos", true) or apos)
target.ang:Set(self:GetBuff("ReloadAng", true) or aang)
else
target.pos:Set(apos)
target.ang:Set(aang)
LerpMod(target.pos, cpos, cdelta)
LerpMod(target.ang, cang, cdelta, true)
end
if (owner:Crouching() or owner:KeyDown(IN_DUCK)) then target.down = 0 end
stopwatch("reload, crouch, bipod")
target.pos.x = target.pos.x + ArcCW.ConVars["vm_right"]:GetFloat()
target.pos.y = target.pos.y + ArcCW.ConVars["vm_forward"]:GetFloat()
target.pos.z = target.pos.z + ArcCW.ConVars["vm_up"]:GetFloat()
target.ang.p = target.ang.p + ArcCW.ConVars["vm_pitch"]:GetFloat()
target.ang.y = target.ang.y + ArcCW.ConVars["vm_yaw"]:GetFloat()
target.ang.r = target.ang.r + ArcCW.ConVars["vm_roll"]:GetFloat()
if state == ArcCW.STATE_CUSTOMIZE then
target.down = 1
target.sway = 3
target.bob = 1
local mx, my = input.GetCursorPos()
mx = 2 * mx / ScrW()
my = 2 * my / ScrH()
target.pos:Set(self:GetBuff_Override("Override_CustomizePos", self.CustomizePos))
target.ang:Set(self:GetBuff_Override("Override_CustomizeAng", self.CustomizeAng))
target.pos.x = target.pos.x + mx
target.pos.z = target.pos.z + my
target.ang.y = target.ang.y + my * 2
target.ang.r = target.ang.r + mx * 2
if self.InAttMenu then
target.ang.y = target.ang.y - 5
end
end
stopwatch("cust")
-- Sprinting
local hpos, spos = self:GetBuff("HolsterPos", true), self:GetBuff("SprintPos", true)
local hang, sang = self:GetBuff("HolsterAng", true), self:GetBuff("SprintAng", true)
do
local aaaapos = holstered and (hpos or spos) or (spos or hpos)
local aaaaang = holstered and (hang or sang) or (sang or hang)
local sd = (self:GetReloading() and 0) or (self:IsProne() and math.Clamp(owner:GetVelocity():Length() / prone.Config.MoveSpeed, 0, 1)) or (holstered and 1) or (!self:CanShootWhileSprint() and sprd) or 0
sd = math.pow(math.sin(sd * math.pi * 0.5), 2)
local d = math.pow(math.sin(sd * math.pi * 0.5), math.pi)
local coolilove = d * math.cos(d * math.pi * 0.5)
local joffset, jaffset
if !sprinted then
joffset = sprint_vec2
jaffset = spring_ang2
else
joffset = sprint_vec1
jaffset = sprint_ang1
end
LerpMod(target.pos, aaaapos, sd)
LerpMod(target.ang, aaaaang, sd, true)
for i = 1, 3 do
target.pos[i] = target.pos[i] + joffset[i] * coolilove
target.ang[i] = target.ang[i] + jaffset[i] * coolilove
end
local fu_sprint = (sprinted and self:SelectAnimation("idle_sprint"))
target.sway = target.sway * f_lerp(sd, 1, fu_sprint and 0 or 2)
target.bob = target.bob * f_lerp(sd, 1, fu_sprint and 0 or 2)
end
stopwatch("sprint")
-- Sighting
if asight then
local delta = sgtd
delta = math.pow(math.sin(delta * math.pi * 0.5), math.pi)
local im = asight.Midpoint
local coolilove = delta * math.cos(delta * math.pi * 0.5)
local joffset, jaffset
if !sighted then
joffset = sight_vec2
jaffset = sight_ang2
else
joffset = (im and im.Pos or sight_vec1)
jaffset = (im and im.Ang or sight_ang1)
end
target.pos.z = target.pos.z - 1
LerpMod2(asight.Pos, target.pos, delta)
LerpMod2(asight.Ang, target.ang, delta)
for i = 1, 3 do
target.pos[i] = target.pos[i] + joffset[i] * coolilove
target.ang[i] = target.ang[i] + jaffset[i] * coolilove
end
target.evpos = f_lerp(delta, asight.EVPos or vector_origin, vector_origin)
target.evang = f_lerp(delta, asight.EVAng or angle_zero, angle_zero)
target.down = 0
target.sway = target.sway * f_lerp(delta, 0.1, 1)
target.bob = target.bob * f_lerp(delta, 0.1, 1)
end
stopwatch("sight")
local deg = self:GetBarrelNearWall()
if deg > 0 and ArcCW.ConVars["vm_nearwall"]:GetBool() then
LerpMod(target.pos, hpos, deg)
LerpMod(target.ang, hang, deg)
target.down = 2 * math.max(sgtd, 0.5)
end
if !isangle(target.ang) then
target.ang = Angle(target.ang)
end
target.ang.y = target.ang.y + (self:GetFreeAimOffset().y * 0.5)
target.ang.p = target.ang.p - (self:GetFreeAimOffset().p * 0.5)
if self.InProcDraw then
self.InProcHolster = false
local delta = m_clamp((CT - self.ProcDrawTime) / (0.5 * self:GetBuff_Mult("Mult_DrawTime")), 0, 1)
target.pos = LerpVector(delta, procdraw_vec, target.pos)
target.ang = LerpAngle(delta, procdraw_ang, target.ang)
target.down = target.down
target.sway = target.sway
target.bob = target.bob
end
if self.InProcHolster then
self.InProcDraw = false
local delta = 1 - m_clamp((CT - self.ProcHolsterTime) / (0.25 * self:GetBuff_Mult("Mult_DrawTime")), 0, 1)
target.pos = LerpVector(delta, procdraw_vec, target.pos)
target.ang = LerpAngle(delta, prochol_ang, target.ang)
target.down = target.down
target.sway = target.sway
target.bob = target.bob
end
if self.InProcBash then
self.InProcDraw = false
local mult = self:GetBuff_Mult("Mult_MeleeTime")
local mtime = self.MeleeTime * mult
local delta = 1 - m_clamp((CT - self.ProcBashTime) / mtime, 0, 1)
local bp, ba
if delta > 0.3 then
bp = self:GetBuff_Override("Override_BashPreparePos", self.BashPreparePos)
ba = self:GetBuff_Override("Override_BashPrepareAng", self.BashPrepareAng)
delta = (delta - 0.5) * 2
else
bp = self:GetBuff_Override("Override_BashPos", self.BashPos)
ba = self:GetBuff_Override("Override_BashAng", self.BashAng)
delta = delta * 2
end
LerpMod2(bp, target.pos, delta)
LerpMod2(ba, target.ang, delta)
target.speed = 10
if delta == 0 then
self.InProcBash = false
end
end
stopwatch("proc")
-- local gunbone, gbslot = self:GetBuff_Override("LHIK_GunDriver")
-- if gunbone and IsValid(self.Attachments[gbslot].VElement.Model) and self.LHIKGunPos and self.LHIKGunAng then
-- local magnitude = 1 --Lerp(sgtd, 0.1, 1)
-- local lhik_model = self.Attachments[gbslot].VElement.Model
-- local att = lhik_model:GetAttachment(lhik_model:LookupAttachment(gunbone))
-- local attang = att.Ang
-- local attpos = att.Pos
-- attang = lhik_model:WorldToLocalAngles(attang)
-- attpos = lhik_model:WorldToLocal(attpos)
-- attang:Sub(self.LHIKGunAng)
-- attpos:Sub(self.LHIKGunPos)
-- attang:Mul(magnitude)
-- attpos:Mul(magnitude)
-- --target.ang:Add(attang)
-- --target.pos:Add(attpos)
-- --debugoverlay.Axis(lhik_model:GetPos() + attpos, att.Ang, 8, FrameTime() * 3, true)
-- debugoverlay.Axis(lhik_model:GetPos(), att.Ang, 8, FrameTime() * 3, true)
-- end
-- stopwatch("gunbone")
local vmhit = self.ViewModel_Hit
if vmhit then
if !vmhit:IsZero() then
target.pos.x = target.pos.x + m_clamp(vmhit.y, -1, 1) * 0.25
target.pos.y = target.pos.y + vmhit.y
target.pos.z = target.pos.z + m_clamp(vmhit.x, -1, 1) * 1
target.ang.x = target.ang.x + m_clamp(vmhit.x, -1, 1) * 5
target.ang.y = target.ang.y + m_clamp(vmhit.y, -1, 1) * -2
target.ang.z = target.ang.z + m_clamp(vmhit.z, -1, 1) * 12.5
end
local spd = vmhit:Length() * 5
vmhit.x = m_appor(vmhit.x, 0, FT * spd)
vmhit.y = m_appor(vmhit.y, 0, FT * spd)
vmhit.z = m_appor(vmhit.z, 0, FT * spd)
end
if ArcCW.ConVars["shakevm"]:GetBool() and !engine.IsRecordingDemo() then
target.pos:Add(VectorRand() * self.RecoilAmount * 0.2 * self.RecoilVMShake)
end
stopwatch("vmhit")
local speed = 15 * FT * (game.SinglePlayer() and 1 or 2)
LerpMod(actual.pos, target.pos, speed)
LerpMod(actual.ang, target.ang, speed, true)
LerpMod(actual.evpos, target.evpos or vector_origin, speed)
LerpMod(actual.evang, target.evang or angle_zero, speed, true)
actual.down = f_lerp(speed, actual.down, target.down)
actual.sway = f_lerp(speed, actual.sway, target.sway)
actual.bob = f_lerp(speed, actual.bob, target.bob)
ApproachMod(actual.pos, target.pos, speed * 0.1)
ApproachMod(actual.ang, target.ang, speed * 0.1)
actual.down = m_appor(actual.down, target.down, speed * 0.1)
stopwatch("actual -> target")
local coolsway = ArcCW.ConVars["vm_coolsway"]:GetBool()
self.SwayScale = (coolsway and 0) or actual.sway
self.BobScale = (coolsway and 0) or actual.bob
if coolsway then
swayxmult = ArcCW.ConVars["vm_sway_zmult"]:GetFloat() or 1
swayymult = ArcCW.ConVars["vm_sway_xmult"]:GetFloat() or 1
swayzmult = ArcCW.ConVars["vm_sway_ymult"]:GetFloat() or 1
swayspeed = ArcCW.ConVars["vm_sway_speedmult"]:GetFloat() or 1
lookxmult = ArcCW.ConVars["vm_look_xmult"]:GetFloat() or 1
lookymult = ArcCW.ConVars["vm_look_ymult"]:GetFloat() or 1
local sd = self:GetSightDelta()
lookxmult = Lerp(sd, 0, lookxmult)
lookymult = Lerp(sd, 0, lookymult)
swayxmult = Lerp(sd, 0, swayxmult)
swayymult = Lerp(sd, 0, swayymult)
swayzmult = Lerp(sd, 0, swayzmult)
swayspeed = Lerp(sd, 0, swayspeed)
stopwatch("before vmposition")
local npos, nang = self:GetVMPosition(oldpos, oldang)
pos:Set(npos)
ang:Set(nang)
end
local old_r, old_f, old_u = oldang:Right(), oldang:Forward(), oldang:Up()
pos:Add(math.min(self.RecoilPunchBack, Lerp(sgtd, self.RecoilPunchBackMaxSights or 1, self.RecoilPunchBackMax)) * -old_f)
ang:RotateAroundAxis(old_r, actual.ang.x)
ang:RotateAroundAxis(old_u, actual.ang.y)
ang:RotateAroundAxis(old_f, actual.ang.z)
ang:RotateAroundAxis(old_r, actual.evang.x)
ang:RotateAroundAxis(old_u, actual.evang.y)
ang:RotateAroundAxis(old_f, actual.evang.z)
local new_r, new_f, new_u = ang:Right(), ang:Forward(), ang:Up()
old_r:Mul(actual.evpos.x)
old_f:Mul(actual.evpos.y)
old_u:Mul(actual.evpos.z)
pos:Add(old_r)
pos:Add(old_f)
pos:Add(old_u)
new_r:Mul(actual.pos.x)
new_f:Mul(actual.pos.y)
new_u:Mul(actual.pos.z)
pos:Add(new_r)
pos:Add(new_f)
pos:Add(new_u)
pos.z = pos.z - actual.down
ang:Add(self:GetOurViewPunchAngles() * Lerp(sgtd, 1, -1))
local gunbone, gbslot = self:GetBuff_Override("LHIK_GunDriver")
local lhik_model = gbslot and self.Attachments[gbslot].VElement and self.Attachments[gbslot].VElement.Model -- Visual M203 attachment
local lhik_anim_model = gbslot and self.Attachments[gbslot].GodDriver and self.Attachments[gbslot].GodDriver.Model -- M203 anim and camera
local lhik_refl_model = gbslot and self.Attachments[gbslot].ReflectDriver and self.Attachments[gbslot].ReflectDriver.Model -- Rifle
if IsValid(lhik_model) and IsValid(lhik_anim_model) and IsValid(lhik_refl_model) and lhik_anim_model:GetAttachment(lhik_anim_model:LookupAttachment(gunbone)) then
local att = lhik_anim_model:LookupAttachment(gunbone)
local offset = lhik_anim_model:GetAttachment(att).Pos
local affset = lhik_anim_model:GetAttachment(att).Ang
affset:Sub( GunDriverFix )
local r = affset.r
affset.r = affset.p
affset.p = -r
affset.y = -affset.y
local anchor = self.Attachments[gbslot].VMOffsetPos
local looku = lhik_refl_model:LookupBone( self.Attachments[gbslot].Bone )
local bonp, bona = lhik_refl_model:GetBonePosition( looku )
if bonp == lhik_refl_model:GetPos() then
bonp = lhik_refl_model:GetBoneMatrix( looku ):GetTranslation()
bona = lhik_refl_model:GetBoneMatrix( looku ):GetAngles()
end
if anchor and bonp then -- Not ready / deploying
anchor = ( bonp + ( (bona:Forward()*anchor.x) + (bona:Right()*anchor.y) + (bona:Up()*anchor.z) ) )
debugoverlay.Axis(anchor, angle_zero, 4, FrameTime(), true)
rap_pos, rap_ang = ArcCW.RotateAroundPoint2(pos, ang, anchor, offset, affset)
rap_pos:Sub(pos)
rap_ang:Sub(ang)
pos:Add(rap_pos)
ang:Add(rap_ang)
end
end
self.ActualVMData = actual
stopwatch("apply actual")
stopwatch(true)
lst = SysTime()
return pos, ang
end
function SWEP:ShouldCheapWorldModel()
local lp = LocalPlayer()
if lp:GetObserverMode() == OBS_MODE_IN_EYE and lp:GetObserverTarget() == self:GetOwner() then return true end
if !IsValid(self:GetOwner()) and !ArcCW.ConVars["att_showground"]:GetBool() then return true end
return !ArcCW.ConVars["att_showothers"]:GetBool()
end
local bird = Material("arccw/hud/arccw_bird.png", "mips smooth")
local iw = 32
function SWEP:DrawWorldModel()
local cvar2d3d = ArcCW.ConVars["2d3d"]:GetInt()
if !IsValid(self:GetOwner()) and !TTT2
and (cvar2d3d == 2 or (cvar2d3d == 1 and LocalPlayer():GetEyeTrace().Entity == self))
and (EyePos() - self:WorldSpaceCenter()):LengthSqr() <= 262144 then -- 512^2
local ang = LocalPlayer():EyeAngles()
ang:RotateAroundAxis(ang:Forward(), 180)
ang:RotateAroundAxis(ang:Right(), 90)
ang:RotateAroundAxis(ang:Up(), 90)
cam.Start3D2D(self:WorldSpaceCenter() + Vector(0, 0, 16), ang, 0.1)
srf.SetFont("ArcCW_32_Unscaled")
local w = srf.GetTextSize(self.PrintName)
srf.SetTextPos(-w / 2 + 2, 2)
srf.SetTextColor(0, 0, 0, 150)
srf.DrawText(self.PrintName)
srf.SetTextPos(-w / 2, 0)
srf.SetTextColor(255, 255, 255, 255)
srf.DrawText(self.PrintName)
local icons = {}
for i, slot in pairs(self.Attachments or {}) do
if slot.Installed then
local atttbl = ArcCW.AttachmentTable[slot.Installed]
if !atttbl then continue end
local icon = atttbl.Icon
if !icon or icon:IsError() then icon = bird end
table.insert(icons, icon)
end
end
local ind = math.min(6, #icons)
surface.SetDrawColor(255, 255, 255)
for i = 1, ind do
if i == 6 and #icons > 6 then
local str = "+" .. (#icons - ind)
local strw = srf.GetTextSize(str)
srf.SetTextPos(-ind * iw / 2 + (i - 1) * iw + 2 + strw / 2, iw + 14)
srf.SetTextColor(0, 0, 0, 150)
srf.DrawText(str)
srf.SetTextPos(-ind * iw / 2 + (i - 1) * iw + strw / 2, iw + 12)
srf.SetTextColor(255, 255, 255, 255)
srf.DrawText(str)
else
local icon = icons[i]
surface.SetMaterial(icon)
surface.DrawTexturedRect(-ind * iw / 2 + (i - 1) * iw, iw + 12, iw, iw)
end
end
-- srf.SetFont("ArcCW_24_Unscaled")
-- local count = self:CountAttachments()
-- if count > 0 then
-- local t = tostring(count) .. " Attachments"
-- w = srf.GetTextSize(t)
-- srf.SetTextPos(-w / 2, 32)
-- srf.SetTextColor(255, 255, 255, 255)
-- srf.DrawText(t)
-- end
cam.End3D2D()
end
self:DrawCustomModel(true)
self:DoLaser(true)
if self:ShouldGlint() then
self:DoScopeGlint()
end
if !self.CertainAboutAtts and !self.AttReqSent and !IsValid(self:GetOwner()) then
self.AttReqSent = true
-- print(self, "network weapon from cl_viewmodel")
-- debugoverlay.Cross(self:GetPos(), 8, 10, color_white, true)
-- debugoverlay.EntityTextAtPosition(self:GetPos(), 1, tostring(self) .. " requesting networking data", 10, color_white)
net.Start("arccw_rqwpnnet")
net.WriteEntity(self)
net.SendToServer()
end
end
function SWEP:ShouldCheapScope()
if !ArcCW.ConVars["cheapscopes"]:GetBool() then return end
end
local POSTVMDONE = nil
local POSTVMDONE_TIME = 0
local lst2 = SysTime()
function SWEP:PreDrawViewModel(vm)
if ArcCW.VM_OverDraw then return end
if !vm then return end
if self:GetState() == ArcCW.STATE_CUSTOMIZE then
self:BlurNotWeapon()
end
if ArcCW.ConVars["cheapscopesautoconfig"]:GetBool() then
local fps = 1 / (SysTime() - lst2)
lst2 = SysTime()
local lowfps = fps <= 45
ArcCW.ConVars["cheapscopes"]:SetBool(lowfps)
ArcCW.ConVars["cheapscopesautoconfig"]:SetBool(false)
end
local asight = self:GetActiveSights()
if asight and ((ArcCW.ConVars["cheapscopes"]:GetBool() and self:GetSightDelta() < 1 and asight.MagnifiedOptic)
or (self:GetSightDelta() < 1 and asight.ScopeTexture)) then
-- Necessary to call here since physbullets are not drawn until PreDrawEffects; cheap scope implementation will not allow them to be visible
-- Introduces a bug when we try to call GetAttachment on the viewmodel in DrawPhysBullets here, so set a workaround variable to not call it
ArcCW:DrawPhysBullets(true)
self:FormCheapScope()
end
local coolFOV = self.CurrentViewModelFOV or self.ViewModelFOV
if ArcCW.VMInRT then
local mag = asight.ScopeMagnification
coolFOV = self.ViewModelFOV - mag * 4 - (ArcCW.ConVars["vm_add_ads"]:GetFloat() * 3 or 0)
ArcCW.VMInRT = false
end
cam.Start3D(EyePos(), EyeAngles(), self:QuickFOVix(coolFOV), nil, nil, nil, nil, 0.5, 1000)
cam.IgnoreZ(true)
self:DrawCustomModel(false)
self:DoLHIK()
if !ArcCW.Overdraw then
self:DoLaser(false, true)
end
-- patrol
if POSTVMDONE == false and POSTVMDONE_TIME <= CurTime() then
POSTVMDONE_TIME = CurTime() + 1
print( "[ArcCW] Warning: PostDrawViewModel failed response!! cam.End3D errors may be inbound!! You may have an addon conflict!!")
print( "[ArcCW] Follow the troubleshooting guide at https://github.com/HaodongMo/ArcCW/wiki/Help-&-Troubleshooting#camend3d-errors")
end
POSTVMDONE = false
end
function SWEP:PostDrawViewModel()
POSTVMDONE = true
if ArcCW.VM_OverDraw then return end
render.SetBlend(1)
cam.End3D()
cam.Start3D(EyePos(), EyeAngles(), self:QuickFOVix(self.CurrentViewModelFOV or self.ViewModelFOV), nil, nil, nil, nil, 0.5, 1000)
cam.IgnoreZ(true)
if ArcCW.Overdraw then
ArcCW.Overdraw = false
else
--self:DoLaser()
self:DoHolosight()
end
cam.End3D()
end

View File

@@ -0,0 +1,311 @@
--[[
| 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/
--]]
SWEP.Cam_Offset_Ang = nil --Angle(0, 0, 0)
function SWEP:SelectAnimation(anim)
if self:GetNWState() == ArcCW.STATE_SIGHTS and self.Animations[anim .. "_iron"] then
anim = anim .. "_iron"
end
if self:GetNWState() == ArcCW.STATE_SIGHTS and self.Animations[anim .. "_sights"] then
anim = anim .. "_sights"
end
if self:GetNWState() == ArcCW.STATE_SIGHTS and self.Animations[anim .. "_sight"] then
anim = anim .. "_sight"
end
if self:GetNWState() == ArcCW.STATE_SPRINT and self.Animations[anim .. "_sprint"] and !self:CanShootWhileSprint() then
anim = anim .. "_sprint"
end
if self:InBipod() and self.Animations[anim .. "_bipod"] then
anim = anim .. "_bipod"
end
if self:GetState() == ArcCW.STATE_CUSTOMIZE and self.Animations[anim .. "_inspect"] and ((CLIENT and !ArcCW.ConVars["noinspect"]:GetBool()) or (SERVER and self:GetOwner():GetInfoNum("arccw_noinspect", 0))) then
anim = anim .. "_inspect"
end
if (self:Clip1() == 0 or (self:HasBottomlessClip() and self:Ammo1() == 0)) and self.Animations[anim .. "_empty"] then
anim = anim .. "_empty"
end
if self:GetMalfunctionJam() and self.Animations[anim .. "_jammed"] then
anim = anim .. "_jammed"
end
if self:GetBuff_Override("Override_TriggerDelay", self.TriggerDelay) and self:IsTriggerHeld() and self.Animations[anim .. "_trigger"] then
anim = anim .. "_trigger"
end
if !self.Animations[anim] then return end
return anim
end
SWEP.LastAnimStartTime = 0
SWEP.LastAnimFinishTime = 0
function SWEP:PlayAnimationEZ(key, mult, priority)
return self:PlayAnimation(key, mult, true, 0, false, false, priority, false)
end
function SWEP:PlayAnimation(key, mult, pred, startfrom, tt, skipholster, priority, absolute)
mult = mult or 1
pred = pred or false
startfrom = startfrom or 0
tt = tt or false
--skipholster = skipholster or false Unused
priority = priority or false
absolute = absolute or false
if !key then return end
local ct = CurTime()
if self:GetPriorityAnim() and !priority then return end
if game.SinglePlayer() and SERVER and pred then
net.Start("arccw_sp_anim")
net.WriteString(key)
net.WriteFloat(mult)
net.WriteFloat(startfrom)
net.WriteBool(tt)
--net.WriteBool(skipholster) Unused
net.WriteBool(priority)
net.Send(self:GetOwner())
end
local anim = self.Animations[key]
if !anim then return end
local tranim = self:GetBuff_Hook("Hook_TranslateAnimation", key)
if self.Animations[tranim] then
key = tranim
anim = self.Animations[tranim]
--[[elseif self.Animations[key] then -- Can't do due to backwards compatibility... unless you have a better idea?
anim = self.Animations[key]
else
return]]
end
if anim.ViewPunchTable and CLIENT then
for k, v in pairs(anim.ViewPunchTable) do
if !v.t then continue end
local st = (v.t * mult) - startfrom
if isnumber(v.t) and st >= 0 and self:GetOwner():IsPlayer() and (game.SinglePlayer() or IsFirstTimePredicted()) then
self:SetTimer(st, function() self:OurViewPunch(v.p or Vector(0, 0, 0)) end, id)
end
end
end
if isnumber(anim.ShellEjectAt) then
self:SetTimer(anim.ShellEjectAt * mult, function()
local num = 1
if self.RevolverReload then
num = self.Primary.ClipSize - self:Clip1()
end
for i = 1,num do
self:DoShellEject()
end
end)
end
if !self:GetOwner() then return end
if !self:GetOwner().GetViewModel then return end
local vm = self:GetOwner():GetViewModel()
if !vm then return end
if !IsValid(vm) then return end
local seq = anim.Source
if anim.RareSource and util.SharedRandom("raresource", 0, 1, CurTime()) < (1 / (anim.RareSourceChance or 100)) then
seq = anim.RareSource
end
seq = self:GetBuff_Hook("Hook_TranslateSequence", seq)
if istable(seq) then
seq["BaseClass"] = nil
seq = seq[math.Round(util.SharedRandom("randomseq" .. CurTime(), 1, #seq))]
end
if isstring(seq) then
seq = vm:LookupSequence(seq)
end
local time = absolute and 1 or self:GetAnimKeyTime(key)
--if time == 0 then return end
local ttime = (time * mult) - startfrom
if startfrom > (time * mult) then return end
if tt then
self:SetNextPrimaryFire(ct + ((anim.MinProgress or time) * mult) - startfrom)
end
if anim.LHIK then
self.LHIKStartTime = ct
self.LHIKEndTime = ct + ttime
if anim.LHIKTimeline then
self.LHIKTimeline = {}
for i, k in pairs(anim.LHIKTimeline) do
table.Add(self.LHIKTimeline, {t = (k.t or 0) * mult, lhik = k.lhik or 1})
end
else
self.LHIKTimeline = {
{t = -math.huge, lhik = 1},
{t = ((anim.LHIKIn or 0.1) - (anim.LHIKEaseIn or anim.LHIKIn or 0.1)) * mult, lhik = 1},
{t = (anim.LHIKIn or 0.1) * mult, lhik = 0},
{t = ttime - ((anim.LHIKOut or 0.1) * mult), lhik = 0},
{t = ttime - (((anim.LHIKOut or 0.1) - (anim.LHIKEaseOut or anim.LHIKOut or 0.1)) * mult), lhik = 1},
{t = math.huge, lhik = 1}
}
if anim.LHIKIn == 0 then
self.LHIKTimeline[1].lhik = -math.huge
self.LHIKTimeline[2].lhik = -math.huge
end
if anim.LHIKOut == 0 then
self.LHIKTimeline[#self.LHIKTimeline - 1].lhik = math.huge
self.LHIKTimeline[#self.LHIKTimeline].lhik = math.huge
end
end
else
self.LHIKTimeline = nil
end
if anim.LastClip1OutTime then
self.LastClipOutTime = ct + ((anim.LastClip1OutTime * mult) - startfrom)
end
if anim.TPAnim then
local aseq = self:GetOwner():SelectWeightedSequence(anim.TPAnim)
if aseq then
self:GetOwner():AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, aseq, anim.TPAnimStartTime or 0, true )
if !game.SinglePlayer() and SERVER then
net.Start("arccw_networktpanim")
net.WriteEntity(self:GetOwner())
net.WriteUInt(aseq, 16)
net.WriteFloat(anim.TPAnimStartTime or 0)
net.SendPVS(self:GetOwner():GetPos())
end
end
end
if !(game.SinglePlayer() and CLIENT) and (game.SinglePlayer() or IsFirstTimePredicted() or self.ReadySoundTableHack) then
self:PlaySoundTable(anim.SoundTable or {}, 1 / mult, startfrom, key)
self.ReadySoundTableHack = nil
end
if seq then
vm:SendViewModelMatchingSequence(seq)
local dur = vm:SequenceDuration()
vm:SetPlaybackRate(math.Clamp(dur / (ttime + startfrom), -4, 12))
self.LastAnimStartTime = ct
self.LastAnimFinishTime = ct + dur
self.LastAnimKey = key
end
-- Grabs the current angle of the cam attachment bone and use it as the common offset for all cambone changes.
-- Problem: If this animation interrupted a previous animation with cambone movement,
-- it will start with an incorrect offset and snap at the end.
-- Therefore this now only ever sets it once.
local att = self:GetBuff_Override("Override_CamAttachment", self.CamAttachment)
if att and vm:GetAttachment(att) and (anim.ForceCamReset or self.Cam_Offset_Ang == nil) then
local ang = vm:GetAttachment(att).Ang
ang = vm:WorldToLocalAngles(ang)
self.Cam_Offset_Ang = Angle(ang)
end
self:SetNextIdle(CurTime() + ttime)
return true
end
function SWEP:PlayIdleAnimation(pred)
local ianim = self:SelectAnimation("idle")
if self:GetGrenadePrimed() then
ianim = self:GetGrenadeAlt() and self:SelectAnimation("pre_throw_hold_alt") or self:SelectAnimation("pre_throw_hold")
end
-- (key, mult, pred, startfrom, tt, skipholster, ignorereload)
if self:GetBuff_Override("UBGL_BaseAnims") and self:GetInUBGL()
and self.Animations.idle_ubgl_empty and self:Clip2() <= 0 then
ianim = "idle_ubgl_empty"
elseif self:GetBuff_Override("UBGL_BaseAnims") and self:GetInUBGL() and self.Animations.idle_ubgl then
ianim = "idle_ubgl"
end
if self.LastAnimKey ~= ianim then
ianim = self:GetBuff_Hook("Hook_IdleReset", ianim) or ianim
end
self:PlayAnimation(ianim, 1, pred, nil, nil, nil, true)
end
function SWEP:GetAnimKeyTime(key, min)
if !self:GetOwner() then return 1 end
local anim = self.Animations[key]
if !anim then return 1 end
if self:GetOwner():IsNPC() then return anim.Time or 1 end
local vm = self:GetOwner():GetViewModel()
if !vm or !IsValid(vm) then return 1 end
local t = anim.Time
if !t then
local tseq = anim.Source
if istable(tseq) then
tseq["BaseClass"] = nil -- god I hate Lua inheritance
tseq = tseq[1]
end
if !tseq then return 1 end
tseq = vm:LookupSequence(tseq)
-- to hell with it, just spits wrong on draw sometimes
t = vm:SequenceDuration(tseq) or 1
end
if min and anim.MinProgress then
t = anim.MinProgress
end
if anim.Mult then
t = t * anim.Mult
end
return t
end
if CLIENT then
net.Receive("arccw_networktpanim", function()
local ent = net.ReadEntity()
local aseq = net.ReadUInt(16)
local starttime = net.ReadFloat()
if IsValid(ent) and ent ~= LocalPlayer() and ent:IsPlayer() then
ent:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, aseq, starttime, true )
end
end)
end
function SWEP:QueueAnimation() end
function SWEP:NextAnimation() end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,271 @@
--[[
| 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/
--]]
function SWEP:CanBackstab(melee2, ent)
if !self:GetBuff_Override("Override_Backstab", self.Backstab) then return false end
local reach = 32 + self:GetBuff_Add("Add_MeleeRange") + (melee2 and self.Melee2Range or self.MeleeRange)
if (!IsValid(ent)) then
local tr = util.TraceLine({
start = self:GetOwner():GetShootPos(),
endpos = self:GetOwner():GetShootPos() + self:GetOwner():GetAimVector() * reach,
filter = {self:GetOwner()},
mask = MASK_SHOT_HULL
})
if tr.Entity:IsPlayer() or tr.Entity:IsNPC() or tr.Entity:IsNextBot() then
ent = tr.Entity
end
end
if (!IsValid(ent)) then
local tr = util.TraceHull({
start = self:GetOwner():GetShootPos(),
endpos = self:GetOwner():GetShootPos() + self:GetOwner():GetAimVector() * reach,
filter = {self:GetOwner()},
mins = Vector(-16, -16, -8),
maxs = Vector(16, 16, 8),
mask = MASK_SHOT_HULL
})
if tr.Entity:IsPlayer() or tr.Entity:IsNPC() or tr.Entity:IsNextBot() then
ent = tr.Entity
end
end
if IsValid(ent) then
local angle = math.NormalizeAngle(self:GetOwner():GetAngles().y - ent:GetAngles().y)
return angle <= 90 and angle >= -90
end
return false
end
function SWEP:DoLunge(melee2)
if ArcCW.ConVars["override_lunge_off"]:GetBool() then return end
local var = self:GetBuff_Override("Override_Lunge", self.Lunge)
if var == false or var == nil and self.PrimaryBash then return end
if !self:GetOwner():IsPlayer() or self:GetOwner():Crouching() then return end
local reach = 32 + self:GetBuff_Add("Add_MeleeRange") + (melee2 and self.Melee2Range or self.MeleeRange)
local tr = self:GetOwner():GetEyeTrace()
local tgt = tr.Entity
if IsValid(tgt) and (tgt:IsPlayer() or tgt:IsNPC() or tgt:IsNextBot()) then
local dist = (tr.HitPos - tr.StartPos):Length()
if dist > reach and dist < reach + self:GetBuff("LungeLength") then
local dir = tr.Normal
dir.z = math.min(dir.z, 0)
dir:Normalize()
self:GetOwner():SetVelocity(dir * (self:GetOwner():IsOnGround() and 5 or 2.5) * dist)
end
end
end
function SWEP:Bash(melee2)
melee2 = melee2 or false
if self:GetState() == ArcCW.STATE_SIGHTS
or (self:GetState() == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint())
or self:GetState() == ArcCW.STATE_CUSTOMIZE then
return
end
if self:GetNextPrimaryFire() > CurTime() or self:GetGrenadePrimed() or self:GetPriorityAnim() then return end
if !self.CanBash and !self:GetBuff_Override("Override_CanBash") then return end
self:GetBuff_Hook("Hook_PreBash")
self.Primary.Automatic = true
local mult = self:GetBuff_Mult("Mult_MeleeTime")
local mt = self.MeleeTime * mult
if melee2 then
mt = self.Melee2Time * mult
end
mt = mt * self:GetBuff_Mult("Mult_MeleeWaitTime")
local bashanim = "bash"
local canbackstab = self:CanBackstab(melee2)
if melee2 then
bashanim = canbackstab and self:SelectAnimation("bash2_backstab") or self:SelectAnimation("bash2") or bashanim
else
bashanim = canbackstab and self:SelectAnimation("bash_backstab") or self:SelectAnimation("bash") or bashanim
end
bashanim = self:GetBuff_Hook("Hook_SelectBashAnim", bashanim) or bashanim
if bashanim and self.Animations[bashanim] then
if SERVER then self:PlayAnimation(bashanim, mult, true, 0, true) end
else
self:ProceduralBash()
self:MyEmitSound(self.MeleeSwingSound, 75, 100, 1, CHAN_USER_BASE + 1)
end
if CLIENT then
self:OurViewPunch(-self.BashPrepareAng * 0.05)
end
self:SetNextPrimaryFire(CurTime() + mt )
if melee2 then
if self.HoldtypeActive == "pistol" or self.HoldtypeActive == "revolver" then
self:GetOwner():DoAnimationEvent(self.Melee2Gesture or ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE)
else
self:GetOwner():DoAnimationEvent(self.Melee2Gesture or ACT_GMOD_GESTURE_MELEE_SHOVE_2HAND)
end
else
if self.HoldtypeActive == "pistol" or self.HoldtypeActive == "revolver" then
self:GetOwner():DoAnimationEvent(self.MeleeGesture or ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE)
else
self:GetOwner():DoAnimationEvent(self.MeleeGesture or ACT_GMOD_GESTURE_MELEE_SHOVE_2HAND)
end
end
local mat = self.MeleeAttackTime
if melee2 then
mat = self.Melee2AttackTime
end
mat = mat * self:GetBuff_Mult("Mult_MeleeAttackTime") * math.pow(mult, 1.5)
self:SetTimer(mat or (0.125 * mt), function()
if !IsValid(self) then return end
if !IsValid(self:GetOwner()) then return end
if self:GetOwner():GetActiveWeapon() != self then return end
if CLIENT then
self:OurViewPunch(-self.BashAng * 0.05)
end
self:MeleeAttack(melee2)
end)
self:DoLunge()
end
function SWEP:MeleeAttack(melee2)
local reach = 32 + self:GetBuff_Add("Add_MeleeRange") + self.MeleeRange
local dmg = self:GetBuff_Override("Override_MeleeDamage", self.MeleeDamage) or 20
if melee2 then
reach = 32 + self:GetBuff_Add("Add_MeleeRange") + self.Melee2Range
dmg = self:GetBuff_Override("Override_MeleeDamage", self.Melee2Damage) or 20
end
dmg = dmg * self:GetBuff_Mult("Mult_MeleeDamage")
self:GetOwner():LagCompensation(true)
local filter = {self:GetOwner()}
table.Add(filter, self.Shields)
local tr = util.TraceLine({
start = self:GetOwner():GetShootPos(),
endpos = self:GetOwner():GetShootPos() + self:GetOwner():GetAimVector() * reach,
filter = filter,
mask = MASK_SHOT_HULL
})
if (!IsValid(tr.Entity)) then
tr = util.TraceHull({
start = self:GetOwner():GetShootPos(),
endpos = self:GetOwner():GetShootPos() + self:GetOwner():GetAimVector() * reach,
filter = filter,
mins = Vector(-16, -16, -8),
maxs = Vector(16, 16, 8),
mask = MASK_SHOT_HULL
})
end
-- Backstab damage if applicable
local backstab = tr.Hit and self:CanBackstab(melee2, tr.Entity)
if backstab then
if melee2 then
local bs_dmg = self:GetBuff_Override("Override_Melee2DamageBackstab", self.Melee2DamageBackstab)
if bs_dmg then
dmg = bs_dmg * self:GetBuff_Mult("Mult_MeleeDamage")
else
dmg = dmg * self:GetBuff("BackstabMultiplier") * self:GetBuff_Mult("Mult_MeleeDamage")
end
else
local bs_dmg = self:GetBuff_Override("Override_MeleeDamageBackstab", self.MeleeDamageBackstab)
if bs_dmg then
dmg = bs_dmg * self:GetBuff_Mult("Mult_MeleeDamage")
else
dmg = dmg * self:GetBuff("BackstabMultiplier") * self:GetBuff_Mult("Mult_MeleeDamage")
end
end
end
-- We need the second part for single player because SWEP:Think is ran shared in SP
if !(game.SinglePlayer() and CLIENT) then
if tr.Hit then
if tr.Entity:IsNPC() or tr.Entity:IsNextBot() or tr.Entity:IsPlayer() then
self:MyEmitSound(self.MeleeHitNPCSound, 75, 100, 1, CHAN_USER_BASE + 2)
else
self:MyEmitSound(self.MeleeHitSound, 75, 100, 1, CHAN_USER_BASE + 2)
end
if tr.MatType == MAT_FLESH or tr.MatType == MAT_ALIENFLESH or tr.MatType == MAT_ANTLION or tr.MatType == MAT_BLOODYFLESH then
local fx = EffectData()
fx:SetOrigin(tr.HitPos)
util.Effect("BloodImpact", fx)
end
else
self:MyEmitSound(self.MeleeMissSound, 75, 100, 1, CHAN_USER_BASE + 3)
end
end
if SERVER and IsValid(tr.Entity) and (tr.Entity:IsNPC() or tr.Entity:IsPlayer() or tr.Entity:Health() > 0) then
local dmginfo = DamageInfo()
local attacker = self:GetOwner()
if !IsValid(attacker) then attacker = self end
dmginfo:SetAttacker(attacker)
local relspeed = (tr.Entity:GetVelocity() - self:GetOwner():GetAbsVelocity()):Length()
relspeed = relspeed / 225
relspeed = math.Clamp(relspeed, 1, 1.5)
dmginfo:SetInflictor(self)
dmginfo:SetDamage(dmg * relspeed)
dmginfo:SetDamageType(self:GetBuff_Override("Override_MeleeDamageType") or self.MeleeDamageType or DMG_CLUB)
dmginfo:SetDamageForce(self:GetOwner():GetRight() * -4912 + self:GetOwner():GetForward() * 9989)
SuppressHostEvents(NULL)
tr.Entity:TakeDamageInfo(dmginfo)
SuppressHostEvents(self:GetOwner())
if tr.Entity:GetClass() == "func_breakable_surf" then
tr.Entity:Fire("Shatter", "0.5 0.5 256")
end
end
if SERVER and IsValid(tr.Entity) then
local phys = tr.Entity:GetPhysicsObject()
if IsValid(phys) then
phys:ApplyForceOffset(self:GetOwner():GetAimVector() * 80 * phys:GetMass(), tr.HitPos)
end
end
self:GetBuff_Hook("Hook_PostBash", {tr = tr, dmg = dmg})
self:GetOwner():LagCompensation(false)
end

View File

@@ -0,0 +1,147 @@
--[[
| 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/
--]]
function SWEP:InBipod()
local bip = self:GetInBipod()
-- if !self:CanBipod() then
-- self:ExitBipod()
-- end
if IsValid(self:GetOwner()) and self:GetBipodPos() != self:GetOwner():EyePos() then
self:ExitBipod()
end
return bip
end
SWEP.CachedCanBipod = true
SWEP.CachedCanBipodTime = 0
local dist = 24
function SWEP:CanBipod()
if !(self:GetBuff_Override("Bipod") or self.Bipod_Integral) then return false end
if self:GetOwner():InVehicle() then return false end
if self.CachedCanBipodTime >= CurTime() then return self.CachedCanBipod end
local pos = self:GetOwner():EyePos()
local angle = self:GetOwner():EyeAngles()
if self:GetOwner():GetVelocity():Length() > 0 then
return false
end
local rangemult = 2
if self:IsProne() then
rangemult = rangemult * 1.25
end
rangemult = rangemult * self:GetBuff_Mult("Mult_BipodRange")
local tr = util.TraceLine({
start = pos,
endpos = pos + (angle:Forward() * dist * rangemult),
filter = self:GetOwner(),
mask = MASK_PLAYERSOLID
})
if tr.Hit then -- check for stuff in front of us
return false
end
local maxs = Vector(8, 8, 16)
local mins = Vector(-8, -8, 0)
angle.p = angle.p + 45
tr = util.TraceHull({
start = pos,
endpos = pos + (angle:Forward() * dist * rangemult),
filter = self:GetOwner(),
maxs = maxs,
mins = mins,
mask = MASK_PLAYERSOLID
})
self.CachedCanBipodTime = CurTime()
if tr.Hit then
local tr2 = util.TraceHull({
start = tr.HitPos,
endpos = tr.HitPos + Vector(0, 0, -24),
filter = self:GetOwner(),
maxs = maxs,
mins = mins,
mask = MASK_PLAYERSOLID
})
if tr2.Hit then
self.CachedCanBipod = true
return true, tr2
end
end
self.CachedCanBipod = false
return false
end
function SWEP:EnterBipod(sp)
if !sp and self:GetInBipod() then return end
local can, tr = self:CanBipod()
if !sp and !can then return end
if SERVER and game.SinglePlayer() then self:CallOnClient("EnterBipod", "true") end
if self.Animations.enter_bipod then
self:PlayAnimation("enter_bipod", nil, nil, 0, true)
else
-- Block actions for a tiny bit even if there is no animation
self:SetNextPrimaryFire(CurTime() + 0.25)
end
if CLIENT and self:GetBuff_Override("LHIK") then
self:DoLHIKAnimation("enter")
end
local bipodang = tr.HitNormal:Cross(self:GetOwner():EyeAngles():Right()):Angle()
debugoverlay.Axis(tr.HitPos, tr.HitNormal:Angle(), 16, 5, true)
debugoverlay.Line(tr.HitPos, tr.HitPos + bipodang:Forward() * 32, 5, color_white, true)
debugoverlay.Line(tr.HitPos, tr.HitPos + self:GetOwner():EyeAngles():Forward() * 32, 5, Color(255, 255, 0), true)
self:SetBipodPos(self:GetOwner():EyePos())
self:SetBipodAngle(bipodang)
self.BipodStartAngle = self:GetOwner():EyeAngles()
if game.SinglePlayer() and CLIENT then return end
self:MyEmitSound(self.EnterBipodSound)
self:SetInBipod(true)
end
function SWEP:ExitBipod(sp)
if !sp and !self:GetInBipod() then return end
if SERVER and game.SinglePlayer() then self:CallOnClient("ExitBipod", "true") end
if self.Animations.exit_bipod then
self:PlayAnimation("exit_bipod", nil, nil, 0, true)
else
self:SetNextPrimaryFire(CurTime() + 0.25)
end
if CLIENT and self:GetBuff_Override("LHIK") then
self:DoLHIKAnimation("exit")
end
if game.SinglePlayer() and CLIENT then return end
self:MyEmitSound(self.ExitBipodSound)
self:SetInBipod(false)
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,408 @@
--[[
| 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

View File

@@ -0,0 +1,174 @@
--[[
| 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/
--]]
function SWEP:ChangeFiremode(pred)
pred = pred or true
local fmt = self:GetBuff_Override("Override_Firemodes", self.Firemodes)
fmt["BaseClass"] = nil
local check = self:GetBuff_Hook("Hook_ChangeFiremode")
if check then return end
local count = table.Count(fmt)
if count == 1 then return end
if self:GetNextPrimaryFire() > CurTime() then return end
if self:GetGrenadePrimed() then return end
local fmi = self:GetFireMode()
local lastfmi = fmi
fmi = fmi + 1
if fmi > count then
fmi = 1
end
local altsafety = SERVER and (self:GetOwner():GetInfo("arccw_altsafety") == "1") or CLIENT and (ArcCW.ConVars["altsafety"]:GetBool())
if altsafety and !self:GetOwner():KeyDown(IN_WALK) and fmt[fmi] and fmt[fmi].Mode == 0 then
-- Skip safety when walk key is not down
fmi = (fmi + 1 > count) and 1 or (fmi + 1)
elseif altsafety and self:GetOwner():KeyDown(IN_WALK) then
if fmt[lastfmi] and fmt[lastfmi].Mode == 0 then
-- Find the first non-safety firemode
local nonsafe_fmi = nil
for i, fm in pairs(fmt) do
if fm.Mode != 0 then nonsafe_fmi = i break end
end
fmi = nonsafe_fmi or fmi
else
-- Find the safety firemode
local safety_fmi = nil
for i, fm in pairs(fmt) do
if fm.Mode == 0 then safety_fmi = i break end
end
fmi = safety_fmi or fmi
end
end
if !fmt[fmi] then fmi = 1 end
local a = tostring(lastfmi) .. "_to_" .. tostring(fmi)
if !self.Animations[a] then a = "changefiremode" end
if self.Animations[a] then
self:PlayAnimationEZ(a, 1, true)
local t = CurTime() + self:GetAnimKeyTime(a, true)
self:SetPriorityAnim(t)
self:SetNextPrimaryFire(t)
end
local old_inf = self:HasInfiniteAmmo()
self:SetFireMode(fmi)
--timer.Simple(0, function() self:RecalcAllBuffs() end)
-- Absolutely, totally, completely ENSURE client has changed the value before attempting recalculation
-- Waiting one tick will not work on dedicated servers
local id = "ArcCW_RecalcWait_" .. self:EntIndex()
timer.Create(id, 0.01, 0, function()
if !IsValid(self) then timer.Remove(id) return end
if self:GetFireMode() == fmi then
self:RecalcAllBuffs()
self:GetActiveElements(true)
-- Timers solve everything!
timer.Simple(0.01, function()
if !IsValid(self) then return end
self:AdjustAmmo(old_inf)
if self:GetCurrentFiremode().RestoreAmmo then
-- No seriously, they really do
timer.Simple(0.01, function()
if !IsValid(self) then return end
self:RestoreAmmo()
end)
end
end)
timer.Remove(id)
end
end)
if lastfmi != fmi then
local snd = self:GetBuff_Override("Override_FiremodeSound", self.FiremodeSound)
if SERVER then
if pred then
SuppressHostEvents(self:GetOwner())
end
self:MyEmitSound(snd, 75, 100, 1, CHAN_ITEM + 2)
if pred then
SuppressHostEvents(NULL)
end
else
self:MyEmitSound(snd, 75, 100, 1, CHAN_ITEM + 2)
end
end
self:SetShouldHoldType()
if self:GetCurrentFiremode().Mode == 0 or self:GetBuff_Hook("Hook_ShouldNotSight") then
self:ExitSights()
end
end
function SWEP:GetCurrentFiremode()
local fmt = self:GetBuff_Override("Override_Firemodes", self.Firemodes)
fmt.BaseClass = nil
if self:GetFireMode() > table.Count(fmt) or self:GetFireMode() < 1 then
self:SetFireMode(1)
end
fmt[self:GetFireMode()].BaseClass = nil
return fmt[self:GetFireMode()]
end
function SWEP:GetFiremodeName()
if self:GetBuff_Hook("Hook_FiremodeName") then return self:GetBuff_Hook("Hook_FiremodeName") end
local abbrev = ArcCW.ConVars["hud_fcgabbrev"]:GetBool() and ".abbrev" or ""
if self:GetInUBGL() then
return self:GetBuff_Override("UBGL_PrintName") and self:GetBuff_Override("UBGL_PrintName") or ArcCW.GetTranslation("fcg.ubgl" .. abbrev)
end
local fm = self:GetCurrentFiremode()
if fm.PrintName then
local phrase = ArcCW.GetPhraseFromString(fm.PrintName)
return phrase and ArcCW.GetTranslation(phrase .. abbrev) or ArcCW.TryTranslation(fm.PrintName)
end
local mode = fm.Mode
if mode == 0 then return ArcCW.GetTranslation("fcg.safe" .. abbrev) end
if mode == 1 then return ArcCW.GetTranslation("fcg.semi" .. abbrev) end
if mode >= 2 then return ArcCW.GetTranslation("fcg.auto" .. abbrev) end
if mode < 0 then return string.format(ArcCW.GetTranslation("fcg.burst" .. abbrev), tostring(-mode)) end
end
function SWEP:GetFiremodeBars()
if self:GetBuff_Hook("Hook_FiremodeBars") then return self:GetBuff_Hook("Hook_FiremodeBars") end
if self:GetInUBGL() then
return "____-"
end
local fm = self:GetCurrentFiremode()
if fm.CustomBars then return fm.CustomBars end
local mode = fm.Mode
if mode == 0 then return "_____" end
if mode == 1 then return "-____" end
if mode >= 2 then return "-----" end
if mode == -2 then return "--___" end
if mode == -3 then return "---__" end
if mode == -4 then return "----_" end
return "-----"
end

View File

@@ -0,0 +1,923 @@
--[[
| 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/
--]]
function SWEP:CanPrimaryAttack()
local owner = self:GetOwner()
-- Should we not fire? But first.
if self:GetBuff_Hook("Hook_ShouldNotFireFirst") then return end
-- We're holstering
if IsValid(self:GetHolster_Entity()) then return end
if self:GetHolster_Time() > 0 then return end
-- Disabled (currently used only by deploy)
if self:GetState() == ArcCW.STATE_DISABLE then return end
-- Coostimzing
if self:GetState() == ArcCW.STATE_CUSTOMIZE then
if CLIENT and ArcCW.Inv_Hidden then
ArcCW.Inv_Hidden = false
gui.EnableScreenClicker(true)
elseif game.SinglePlayer() then
-- Kind of ugly hack: in SP this is only called serverside so we ask client to do the same check
self:CallOnClient("CanPrimaryAttack")
end
return
end
-- A priority animation is playing (reloading, cycling, firemode etc)
if self:GetPriorityAnim() then return end
-- Inoperable, but internally (burst resetting for example)
if self:GetWeaponOpDelay() > CurTime() then return end
-- Safety's on, dipshit
if self:GetCurrentFiremode().Mode == 0 then
self:ChangeFiremode(false)
self:SetNextPrimaryFire(CurTime())
self.Primary.Automatic = false
return
end
-- If we are an NPC, do our own little methods
if owner:IsNPC() then self:NPC_Shoot() return end
-- If we are in a UBGL, shoot the UBGL, not the gun
if self:GetInUBGL() then self:ShootUBGL() return end
-- Too early, come back later.
if self:GetNextPrimaryFire() >= CurTime() then return end
-- Gun is locked from heat.
if self:GetHeatLocked() then return end
-- Attempting a bash
if self:GetState() != ArcCW.STATE_SIGHTS and owner:KeyDown(IN_USE) or self.PrimaryBash then self:Bash() return end
-- Throwing weapon
if self.Throwing then self:PreThrow() return end
-- Too close to a wall
if self:BarrelHitWall() > 0 then return end
-- Can't shoot while sprinting
if self:GetNWState() == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() then return end
-- Maximum burst shots
if (self:GetBurstCount() or 0) >= self:GetBurstLength() then return end
-- We need to cycle
if self:GetNeedCycle() then return end
-- If we have a trigger delay, make sure its progress is done
if self:GetBuff_Override("Override_TriggerDelay", self.TriggerDelay) and ((!self:GetBuff_Override("Override_TriggerCharge", self.TriggerCharge) and self:GetTriggerDelta() < 1)
or (self:GetBuff_Override("Override_TriggerCharge", self.TriggerCharge) and self:IsTriggerHeld())) then
return
end
-- Should we not fire?
if self:GetBuff_Hook("Hook_ShouldNotFire") then return end
-- We made it
return true
end
function SWEP:TakePrimaryAmmo(num)
if self:HasBottomlessClip() or self:Clip1() <= 0 then
if self:Ammo1() <= 0 then return end
if self:HasInfiniteAmmo() then return end
self:GetOwner():RemoveAmmo(num, self:GetPrimaryAmmoType())
return end
self:SetClip1(self:Clip1() - num)
end
function SWEP:ApplyRandomSpread(dir, spread)
local radius = math.Rand(0, 1)
local theta = math.Rand(0, math.rad(360))
local bulletang = dir:Angle()
local forward, right, up = bulletang:Forward(), bulletang:Right(), bulletang:Up()
local x = radius * math.sin(theta)
local y = radius * math.cos(theta)
dir:Set(dir + right * spread * x + up * spread * y)
end
function SWEP:PrimaryAttack()
local owner = self:GetOwner()
self.Primary.Automatic = true
if !self:CanPrimaryAttack() then return end
local clip = self:Clip1()
local aps = self:GetBuff("AmmoPerShot")
if self:HasBottomlessClip() then
clip = self:Ammo1()
if self:HasInfiniteAmmo() then
clip = math.huge
end
end
if clip < aps then
self:SetBurstCount(0)
self:DryFire()
self.Primary.Automatic = false
return
end
local dir = (owner:EyeAngles() + self:GetFreeAimOffset()):Forward() --owner:GetAimVector()
local src = self:GetShootSrc()
if bit.band(util.PointContents(src), CONTENTS_WATER) == CONTENTS_WATER and !(self.CanFireUnderwater or self:GetBuff_Override("Override_CanFireUnderwater")) then
self:DryFire()
return
end
if self:GetMalfunctionJam() then
self:DryFire()
return
end
-- Try malfunctioning
local mal = self:DoMalfunction(false)
if mal == true then
local anim = "fire_jammed"
self:PlayAnimation(anim, 1, true, 0, true)
return
end
self:GetBuff_Hook("Hook_PreFireBullets")
local desync = ArcCW.ConVars["desync"]:GetBool()
local desyncnum = (desync and math.random()) or 0
math.randomseed(math.Round(util.SharedRandom(self:GetBurstCount(), -1337, 1337, !game.SinglePlayer() and self:GetOwner():GetCurrentCommand():CommandNumber() or CurTime()) * (self:EntIndex() % 30241)) + desyncnum)
self.Primary.Automatic = true
local spread = ArcCW.MOAToAcc * self:GetBuff("AccuracyMOA")
local disp = self:GetDispersion() * ArcCW.MOAToAcc / 10
--dir:Rotate(Angle(0, ArcCW.StrafeTilt(self), 0))
--dir = dir + VectorRand() * disp
self:ApplyRandomSpread(dir, disp)
if (CLIENT or game.SinglePlayer()) and ArcCW.ConVars["dev_shootinfo"]:GetInt() >= 3 and disp > 0 then
local dev_tr = util.TraceLine({
start = src,
endpos = src + owner:GetAimVector() * 33000,
mask = MASK_SHOT,
filter = {self, self:GetOwner()}
})
local dist = (dev_tr.HitPos - src):Length()
local r = dist / (1 / math.tan(disp)) -- had to google "trig cheat sheet to figure this one out"
local a = owner:GetAimVector():Angle()
local r_sqrt = r / math.sqrt(2)
debugoverlay.Line(dev_tr.HitPos - a:Up() * r, dev_tr.HitPos + a:Up() * r, 5, color_white, true)
debugoverlay.Line(dev_tr.HitPos - a:Right() * r, dev_tr.HitPos + a:Right() * r, 5, color_white, true)
debugoverlay.Line(dev_tr.HitPos - a:Right() * r_sqrt - a:Up() * r_sqrt, dev_tr.HitPos + a:Right() * r_sqrt + a:Up() * r_sqrt, 5, color_white, true)
debugoverlay.Line(dev_tr.HitPos - a:Right() * r_sqrt + a:Up() * r_sqrt, dev_tr.HitPos + a:Right() * r_sqrt - a:Up() * r_sqrt, 5, color_white, true)
debugoverlay.Text(dev_tr.HitPos, math.Round(self:GetDispersion(), 1) .. "MOA (" .. math.Round(disp, 3) .. "°)", 5)
end
local delay = self:GetFiringDelay()
local curtime = CurTime()
local curatt = self:GetNextPrimaryFire()
local diff = curtime - curatt
if diff > engine.TickInterval() or diff < 0 then
curatt = curtime
end
self:SetNextPrimaryFire(curatt + delay)
self:SetNextPrimaryFireSlowdown(curatt + delay) -- shadow for ONLY fire time
local num = self:GetBuff("Num")
num = num + self:GetBuff_Add("Add_Num")
local tracer = self:GetBuff_Override("Override_Tracer", self.Tracer)
local tracernum = self:GetBuff_Override("Override_TracerNum", self.TracerNum)
local lastout = self:GetBuff_Override("Override_TracerFinalMag", self.TracerFinalMag)
if lastout >= clip then
tracernum = 1
tracer = self:GetBuff_Override("Override_TracerFinal", self.TracerFinal) or self:GetBuff_Override("Override_Tracer", self.Tracer)
end
local dmgtable = self.BodyDamageMults
dmgtable = self:GetBuff_Override("Override_BodyDamageMults") or dmgtable
-- drive by is cool
src = ArcCW:GetVehicleFireTrace(self:GetOwner(), src, dir) or src
local bullet = {}
bullet.Attacker = owner
bullet.Dir = dir
bullet.Src = src
bullet.Spread = Vector(0, 0, 0) --Vector(spread, spread, spread)
bullet.Damage = 0
bullet.Num = num
local sglove = math.ceil(num / 3)
bullet.Force = self:GetBuff("Force", true) or math.Clamp( ( (50 / sglove) / ( (self:GetBuff("Damage") + self:GetBuff("DamageMin")) / (self:GetBuff("Num") * 2) ) ) * sglove, 1, 3 )
-- Overperforming weapons get the jerf, underperforming gets boost
bullet.Distance = self:GetBuff("Distance", true) or 33300
-- Setting AmmoType makes the engine look for the tracer effect on the ammo instead of TracerName!
--bullet.AmmoType = self.Primary.Ammo
bullet.HullSize = self:GetBuff("HullSize")
bullet.Tracer = tracernum or 0
bullet.TracerName = tracer
bullet.Weapon = self
bullet.Callback = function(att, tr, dmg)
ArcCW:BulletCallback(att, tr, dmg, self)
end
local shootent = self:GetBuff("ShootEntity", true) --self:GetBuff_Override("Override_ShootEntity", self.ShootEntity)
local shpatt = self:GetBuff_Override("Override_ShotgunSpreadPattern", self.ShotgunSpreadPattern)
local shpattov = self:GetBuff_Override("Override_ShotgunSpreadPatternOverrun", self.ShotgunSpreadPatternOverrun)
local extraspread = AngleRand() * self:GetDispersion() * ArcCW.MOAToAcc / 10
local projectiledata = {}
if shpatt or shpattov or shootent then
if shootent then
projectiledata.ent = shootent
projectiledata.vel = self:GetBuff("MuzzleVelocity")
end
bullet = self:GetBuff_Hook("Hook_FireBullets", bullet)
if !bullet then return end
local doent = shootent and num or bullet.Num
local minnum = shootent and 1 or 0
if doent > minnum then
for n = 1, bullet.Num do
bullet.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 = owner:EyeAngles() + self:GetFreeAimOffset()
local ang2 = Angle(ang)
ang2:RotateAroundAxis(ang:Right(), -1 * calcoff.p)
ang2:RotateAroundAxis(ang:Up(), calcoff.y)
ang2:RotateAroundAxis(ang:Forward(), calcoff.r)
if !self:GetBuff_Override("Override_NoRandSpread", self.NoRandSpread) then -- Needs testing
ang2 = ang2 + AngleRand() * spread / 5
end
if shootent then
projectiledata.ang = ang2
self:DoPrimaryFire(true, projectiledata)
else
bullet.Dir = ang2:Forward()
self:DoPrimaryFire(false, bullet)
end
end
elseif shootent then
local ang = owner:EyeAngles() + self:GetFreeAimOffset()
if !self:GetBuff_Override("Override_NoRandSpread", self.NoRandSpread) then
-- ang = (dir + VectorRand() * spread / 5):Angle()
local newdir = Vector(dir)
self:ApplyRandomSpread(newdir, spread / 5)
ang = newdir:Angle()
end
projectiledata.ang = ang
self:DoPrimaryFire(true, projectiledata)
end
else
if !bullet then return end
for n = 1, bullet.Num do
bullet.Num = 1
local dirry = Vector(dir.x, dir.y, dir.z)
math.randomseed(math.Round(util.SharedRandom(n, -1337, 1337, !game.SinglePlayer() and self:GetOwner():GetCurrentCommand():CommandNumber() or CurTime()) * (self:EntIndex() % 30241)) + desyncnum)
if !self:GetBuff_Override("Override_NoRandSpread", self.NoRandSpread) then
self:ApplyRandomSpread(dirry, spread)
bullet.Dir = dirry
end
bullet = self:GetBuff_Hook("Hook_FireBullets", bullet) or bullet
self:DoPrimaryFire(false, bullet)
end
end
self:DoRecoil()
self:SetNthShot(self:GetNthShot() + 1)
owner:DoAnimationEvent(self:GetBuff_Override("Override_AnimShoot") or self.AnimShoot)
local shouldsupp = SERVER and !game.SinglePlayer()
if shouldsupp then SuppressHostEvents(owner) end
self:DoEffects()
self:SetBurstCount(self:GetBurstCount() + 1)
self:TakePrimaryAmmo(aps)
self:DoShootSound()
self:DoPrimaryAnim()
if self:GetCurrentFiremode().Mode < 0 and self:GetBurstCount() == self:GetBurstLength() then
local postburst = (self:GetCurrentFiremode().PostBurstDelay or 0)
self:SetWeaponOpDelay(CurTime() + postburst * self:GetBuff_Mult("Mult_PostBurstDelay") + self:GetBuff_Add("Add_PostBurstDelay"))
end
if (self:GetIsManualAction()) and !(self.NoLastCycle and self:Clip1() == 0) then
local fireanim = self:GetBuff_Hook("Hook_SelectFireAnimation") or self:SelectAnimation("fire")
local firedelay = self.Animations[fireanim].MinProgress or 0
self:SetNeedCycle(true)
self:SetWeaponOpDelay(CurTime() + (firedelay * self:GetBuff_Mult("Mult_CycleTime")))
self:SetNextPrimaryFire(CurTime() + 0.1)
end
self:ApplyAttachmentShootDamage()
self:AddHeat(self:GetBuff("HeatGain"))
mal = self:DoMalfunction(true)
if mal == true then
local anim = "fire_jammed"
self:PlayAnimation(anim, 1, true, 0, true)
end
if self:GetCurrentFiremode().Mode == 1 then
self.LastTriggerTime = -1 -- Cannot fire again until trigger released
self.LastTriggerDuration = 0
end
self:GetBuff_Hook("Hook_PostFireBullets")
if shouldsupp then SuppressHostEvents(nil) end
end
function SWEP:TryBustDoor(ent, dmg)
ArcCW.TryBustDoor(ent, dmg)
end
function SWEP:DoShootSound(sndoverride, dsndoverride, voloverride, pitchoverride)
local fsound = self.ShootSound
local suppressed = self:GetBuff_Override("Silencer")
if suppressed then
fsound = self.ShootSoundSilenced
end
local firstsound = self.FirstShootSound
if self:GetBurstCount() == 1 and firstsound then
fsound = firstsound
local firstsil = self.FirstShootSoundSilenced
if suppressed then
fsound = firstsil and firstsil or self.ShootSoundSilenced
end
end
local lastsound = self.LastShootSound
local clip = self:Clip1()
if clip == 1 and lastsound then
fsound = lastsound
local lastsil = self.LastShootSoundSilenced
if suppressed then
fsound = lastsil and lastsil or self.ShootSoundSilenced
end
end
fsound = self:GetBuff_Hook("Hook_GetShootSound", fsound)
local distancesound = self.DistantShootSound
if suppressed then
distancesound = self.DistantShootSoundSilenced
end
distancesound = self:GetBuff_Hook("Hook_GetDistantShootSound", distancesound)
local spv = self.ShootPitchVariation
local volume = self.ShootVol
local pitch = self.ShootPitch * math.Rand(1 - spv, 1 + spv) * self:GetBuff_Mult("Mult_ShootPitch")
local v = ArcCW.ConVars["weakensounds"]:GetFloat()
volume = volume - v
volume = volume * self:GetBuff_Mult("Mult_ShootVol")
volume = math.Clamp(volume, 51, 149)
pitch = math.Clamp(pitch, 0, 255)
if sndoverride then fsound = sndoverride end
if dsndoverride then distancesound = dsndoverride end
if voloverride then volume = voloverride end
if pitchoverride then pitch = pitchoverride end
if distancesound then self:MyEmitSound(distancesound, 149, pitch, 0.5, CHAN_WEAPON + 1) end
if fsound then self:MyEmitSound(fsound, volume, pitch, 1, CHAN_WEAPON) end
local data = {
sound = fsound,
volume = volume,
pitch = pitch,
}
self:GetBuff_Hook("Hook_AddShootSound", data)
end
function SWEP:GetMuzzleVelocity()
local vel = self:GetBuff_Override("Override_PhysBulletMuzzleVelocity", self.PhysBulletMuzzleVelocity)
if !vel then
vel = self:GetBuff("Range") * 3.5
if self:GetBuff("DamageMin") > self:GetBuff("Damage") then
vel = vel * 2
end
vel = math.Clamp(vel, 200, 1000)
end
vel = vel / ArcCW.HUToM
vel = vel * self:GetBuff_Mult("Mult_PhysBulletMuzzleVelocity")
vel = vel * ArcCW.ConVars["bullet_velocity"]:GetFloat()
return vel
end
function SWEP:DoPrimaryFire(isent, data)
local clip = self:Clip1()
if self:HasBottomlessClip() then
if !self:GetOwner():IsPlayer() then
clip = math.huge
else
clip = self:Ammo1()
end
end
local owner = self:GetOwner()
local shouldphysical = ArcCW.ConVars["bullet_enable"]:GetBool()
if self.AlwaysPhysBullet or self:GetBuff_Override("Override_AlwaysPhysBullet") then
shouldphysical = true
end
if self.NeverPhysBullet or self:GetBuff_Override("Override_NeverPhysBullet") then
shouldphysical = false
end
if isent then
self:FireRocket(data.ent, data.vel, data.ang, self.PhysBulletDontInheritPlayerVelocity)
else
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
if !IsFirstTimePredicted() then return end
if shouldphysical then
local tracernum = data.Tracer or 1
local phystracer = self:GetBuff_Override("Override_PhysTracerProfile", self.PhysTracerProfile)
local lastout = self:GetBuff_Override("Override_TracerFinalMag", self.TracerFinalMag)
if lastout >= self:Clip1() then
phystracer = self:GetBuff_Override("Override_PhysTracerProfileFinal", self.PhysTracerProfileFinal) or phystracer
elseif tracernum == 0 or clip % tracernum != 0 then
phystracer = 7
end
local vel = self:GetMuzzleVelocity()
vel = vel * data.Dir:GetNormalized()
ArcCW:ShootPhysBullet(self, data.Src, vel, phystracer or 0)
else
owner:FireBullets(data, true)
end
end
end
function SWEP:DoPrimaryAnim()
local anim = "fire"
local inbipod = self:InBipod()
local iron = self:GetState() == ArcCW.STATE_SIGHTS
-- Needs testing
if inbipod then
anim = self:SelectAnimation("fire_bipod") or self:SelectAnimation("fire") or anim
else
anim = self:SelectAnimation("fire") or anim
end
if (self.ProceduralIronFire and iron) or (self.ProceduralRegularFire and !iron) then anim = nil end
anim = self:GetBuff_Hook("Hook_SelectFireAnimation", anim) or anim
local time = self:GetBuff_Mult("Mult_FireAnimTime", anim) or 1
if anim then self:PlayAnimation(anim, time, true, 0, false) end
end
function SWEP:DoPenetration(tr, penleft, alreadypenned)
local bullet = {
Damage = self:GetDamage((tr.HitPos - tr.StartPos):Length() * ArcCW.HUToM),
DamageType = self:GetBuff_Override("Override_DamageType") or self.DamageType,
Weapon = self,
Penetration = self:GetBuff("Penetration"),
Attacker = self:GetOwner(),
Travelled = (tr.HitPos - tr.StartPos):Length()
}
ArcCW:DoPenetration(tr, bullet.Damage, bullet, penleft, false, alreadypenned)
end
function SWEP:GetFiringDelay()
local delay = (self.Delay * (1 / self:GetBuff_Mult("Mult_RPM")))
delay = self:GetBuff_Hook("Hook_ModifyRPM", delay) or delay
return delay
end
function SWEP:GetShootSrc()
local owner = self:GetOwner()
if !IsValid(owner) then return self:GetPos() end
if owner:IsNPC() then return owner:GetShootPos() end
local dir = owner:EyeAngles()
local offset = Vector(0, 0, 0)
if self:GetOwner():Crouching() then
offset = self:GetBuff_Override("Override_BarrelOffsetCrouch") or self.BarrelOffsetCrouch or offset
end
if self:GetNWState() == ArcCW.STATE_SIGHTS then
offset = LerpVector(self:GetNWSightDelta(), offset, self:GetBuff_Override("Override_BarrelOffsetSighted", self.BarrelOffsetSighted) or offset)
else
offset = LerpVector(1 - self:GetNWSightDelta(), offset, self:GetBuff_Override("Override_BarrelOffsetHip", self.BarrelOffsetHip) or offset)
end
local src = owner:EyePos()
src = src + dir:Right() * offset[1]
src = src + dir:Forward() * offset[2]
src = src + dir:Up() * offset[3]
return src
end
function SWEP:GetShotgunSpreadOffset(num)
local rotate = Angle()
local spreadpt = self:GetBuff_Override("Override_ShotgunSpreadPattern") or self.ShotgunSpreadPattern or {}
local spreadov = self:GetBuff_Override("Override_ShotgunSpreadPatternOverrun") or self.ShotgunSpreadPatternOverrun or { Angle() }
if istable(spreadpt) and istable(spreadov) then
spreadpt["BaseClass"] = nil
spreadov["BaseClass"] = nil
if num > #spreadpt then
if spo then
num = num - #spreadpt
num = math.fmod(num, #spreadov) + 1
rotate = spreadov[num]
else
num = math.fmod(num, #spreadpt) + 1
rotate = spreadpt[num]
end
else
rotate = spreadpt[num]
end
end
local rottoang = {}
rottoang.num = num
rottoang.ang = rotate
rotate = self:GetBuff_Hook("Hook_ShotgunSpreadOffset", rottoang).ang
return rotate or Angle()
end
function SWEP:GetDispersion()
local owner = self:GetOwner()
if vrmod and vrmod.IsPlayerInVR(owner) then return 0 end
local hipdisp = self:GetBuff("HipDispersion")
local sights = self:GetState() == ArcCW.STATE_SIGHTS
local hip = hipdisp
local sightdisp = self:GetBuff("SightsDispersion")
if sights then hip = Lerp(self:GetNWSightDelta(), sightdisp, hipdisp) end
local speed = owner:GetAbsVelocity():Length()
local maxspeed = owner:GetWalkSpeed() * self:GetBuff("SpeedMult")
if sights then maxspeed = maxspeed * self:GetBuff("SightedSpeedMult") end
speed = math.Clamp(speed / maxspeed, 0, 2)
if owner:OnGround() or owner:WaterLevel() > 0 and owner:GetMoveType() != MOVETYPE_NOCLIP then
hip = hip + speed * self:GetBuff("MoveDispersion")
elseif owner:GetMoveType() != MOVETYPE_NOCLIP then
hip = hip + math.max(speed * self:GetBuff("MoveDispersion"), self:GetBuff("JumpDispersion"))
end
if self:InBipod() then hip = hip * (self.BipodDispersion * self:GetBuff_Mult("Mult_BipodDispersion")) end
if ArcCW.ConVars["mult_crouchdisp"]:GetFloat() != 1 and owner:OnGround() and owner:Crouching() then
hip = hip * ArcCW.ConVars["mult_crouchdisp"]:GetFloat()
end
if ArcCW.ConVars["freeaim"]:GetInt() == 1 and !sights then
hip = hip ^ 0.9
end
--local t = hook.Run("ArcCW_ModDispersion", self, {dispersion = hip})
--hip = t and t.dispersion or hip
hip = self:GetBuff_Hook("Hook_ModDispersion", hip) or hip
return hip
end
function SWEP:DoShellEject(atti)
local eff = self:GetBuff_Override("Override_ShellEffect") or self.ShellEffect or "arccw_shelleffect"
if eff == "NONE" then return end
local owner = self:GetOwner()
if !IsValid(owner) then return end
local vm = self
if !owner:IsNPC() then owner:GetViewModel() end
local att = vm:GetAttachment(atti or self:GetBuff_Override("Override_CaseEffectAttachment") or self.CaseEffectAttachment or 2)
if !att then return end
local pos, ang = att.Pos, att.Ang
if pos and ang and self.ShellEjectPosCorrection then
local up = ang:Up()
local right = ang:Right()
local forward = ang:Forward()
pos = pos + up * self.ShellEjectPosCorrection.z + right * self.ShellEjectPosCorrection.x + forward * self.ShellEjectPosCorrection.y
end
local ed = EffectData()
ed:SetOrigin(pos)
ed:SetAngles(ang)
ed:SetAttachment(atti or self:GetBuff_Override("Override_CaseEffectAttachment") or self.CaseEffectAttachment or 2)
ed:SetScale(1)
ed:SetEntity(self)
ed:SetNormal(ang:Forward())
ed:SetMagnitude(100)
local efov = {}
efov.eff = eff
efov.fx = ed
if self:GetBuff_Hook("Hook_PreDoEffects", efov) == true then return end
util.Effect(eff, ed)
end
function SWEP:DoEffects(att)
if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
local ed = EffectData()
ed:SetStart(self:GetShootSrc())
ed:SetOrigin(self:GetShootSrc())
ed:SetScale(1)
ed:SetEntity(self)
ed:SetAttachment(att or self:GetBuff_Override("Override_MuzzleEffectAttachment") or self.MuzzleEffectAttachment or 1)
local efov = {}
efov.eff = "arccw_muzzleeffect"
efov.fx = ed
if self:GetBuff_Hook("Hook_PreDoEffects", efov) == true then return end
util.Effect("arccw_muzzleeffect", ed)
end
function SWEP:DryFire()
if self.Animations.fire_dry then
return self:PlayAnimation("fire_dry", 1, true, 0, true)
end
self:MyEmitSound(self.ShootDrySound or "weapons/arccw/dryfire.wav", 75, 100, 1, CHAN_ITEM)
self:SetNextPrimaryFire(CurTime() + 0.25)
end
function SWEP:DoRecoil()
local single = game.SinglePlayer()
if !single and !IsFirstTimePredicted() then return end
if single and self:GetOwner():IsValid() and SERVER then self:CallOnClient("DoRecoil") end
-- math.randomseed(self:GetBurstLength() + (self.Recoil * 409) + (self.RecoilSide * 519))
local rec = {
Recoil = 1,
RecoilSide = 1,
VisualRecoilMul = 1
}
rec = self:GetBuff_Hook("Hook_ModifyRecoil", rec) or rec
local recoil = rec.Recoil
local side = rec.RecoilSide
local visual = rec.VisualRecoilMul
local rmul = (recoil or 1) * self:GetBuff_Mult("Mult_Recoil")
local recv = (visual or 1) * self:GetBuff_Mult("Mult_VisualRecoilMult")
local recs = (side or 1) * self:GetBuff_Mult("Mult_RecoilSide")
-- local rrange = math.Rand(-recs, recs) * self.RecoilSide
-- local irec = math.Rand(rrange - 1, rrange + 1)
-- local recu = math.Rand(0.5, 1)
local irec = math.Rand(-1, 1)
local recu = 1
if self:InBipod() then
local b = self.BipodRecoil * self:GetBuff_Mult("Mult_BipodRecoil")
rmul = rmul * b
recs = recs * b
recv = recv * b
end
local recoiltbl = self:GetBuff_Override("Override_ShotRecoilTable") or self.ShotRecoilTable
if recoiltbl and recoiltbl[self:GetBurstCount()] then rmul = rmul * recoiltbl[self:GetBurstCount()] end
if ArcCW.ConVars["mult_crouchrecoil"]:GetFloat() != 1 and self:GetOwner():OnGround() and self:GetOwner():Crouching() then
rmul = rmul * ArcCW.ConVars["mult_crouchrecoil"]:GetFloat()
end
local punch = Angle()
punch = punch + (self:GetBuff_Override("Override_RecoilDirection", self.RecoilDirection) * math.max(self.Recoil, 0.25) * recu * recv * rmul)
punch = punch + (self:GetBuff_Override("Override_RecoilDirectionSide", self.RecoilDirectionSide) * math.max(self.RecoilSide, 0.25) * irec * recv * rmul)
punch = punch + Angle(0, 0, 90) * math.Rand(-1, 1) * math.Clamp(self.Recoil, 0.25, 1) * recv * rmul * 0.01
punch = punch * (self.RecoilPunch or 1) * self:GetBuff_Mult("Mult_RecoilPunch")
self:SetFreeAimAngle(self:GetFreeAimAngle() - punch)
if CLIENT then self:OurViewPunch(punch) end
if CLIENT or single then
recv = recv * self.VisualRecoilMult
self.RecoilAmount = self.RecoilAmount + (self.Recoil * rmul * recu)
self.RecoilAmountSide = self.RecoilAmountSide + (self.RecoilSide * irec * recs * rmul)
self.RecoilPunchBack = math.Clamp(self.RecoilAmount * recv * 5, 1, 5)
if self.MaxRecoilBlowback > 0 then
self.RecoilPunchBack = math.Clamp(self.RecoilPunchBack, 0, self.MaxRecoilBlowback)
end
self.RecoilPunchSide = self.RecoilSide * 0.1 * irec * recv * rmul
self.RecoilPunchUp = self.RecoilRise * 0.1 * recu
end
-- math.randomseed(CurTime() + (self:EntIndex() * 3))
end
function SWEP:GetBurstLength()
local clip = self:Clip1()
if self:HasBottomlessClip() then
clip = self:Ammo1()
if self:HasInfiniteAmmo() then
clip = math.huge
end
end
--if clip == 0 then return 1 end
local len = self:GetCurrentFiremode().Mode
if !len then return self:GetBurstCount() + 10 end
local hookedlen = self:GetBuff_Hook("Hook_GetBurstLength", len)
if len == 1 then return 1 end
if len >= 2 then return self:GetBurstCount() + 10 end
if hookedlen != len then return hookedlen end
if len < 0 then return -len end
return self:GetBurstCount() + 10
end
function SWEP:FireAnimationEvent(pos, ang, event, options)
return true
end
function SWEP:IsRampupWeapon()
local ovr = self:GetBuff_Override("Override_IsRampupWeapon")
if ovr != nil then return ovr end
return self:GetBuff("Damage") < self:GetBuff("DamageMin")
end
function SWEP:GetMinMaxRange()
local decrease = !self:IsRampupWeapon()
local min = self:GetBuff_Override("Override_RangeMin", self.RangeMin or 0)
local max = self:GetBuff_Override("Override_Range", self.Range)
local min_add = self:GetBuff_Add("Add_RangeMin")
local max_add = self:GetBuff_Add("Add_Range")
local min_mult = self:GetBuff_Mult("Mult_RangeMin")
local max_mult = self:GetBuff_Mult("Mult_Range")
if decrease then
-- MinRange is also affected by Mult_Range, this is intentional
local total_min = math.max((min + min_add) * min_mult * max_mult, 0)
return total_min, math.max((max + max_add) * max_mult, total_min)
else
-- For "rampup weapons" (dmgmin > dmg), range buffs *decrease* range, as it ramps up damage quicker
-- After all, +Range is supposed to be a positive buff no matter the kind of gun
local total_min = math.max((min - min_add) / min_mult / max_mult, 0)
return total_min, math.max((max - max_add) / max_mult, total_min)
end
end
function SWEP:GetRangeFraction(range)
local min, max = self:GetMinMaxRange()
if range < min then
return 0
else
return math.Clamp((range - min) / (max - min), 0, 1)
end
end
function SWEP:GetDamage(range, pellet)
local ovr = self:GetBuff_Override("Override_Num")
local add = self:GetBuff_Add("Add_Num")
local mul = self:GetBuff_Mult("Mult_Num")
local num = self.Num
local nbr = (ovr or num) * mul + add
local factor = 1
-- Total damage should be unchanged regardless of whether the weapon originally fired 1 pellet or > 1
-- If pellet is set, we return per-pellet damage instead of total damage
if pellet and num == 1 then
factor = 1 / ((ovr or 1) * mul + add)
elseif num != nbr then
factor = num / nbr
end
--factor = ((pellet and num == 1) and (1 / ((ovr or 1) + add))) or ((num != nbr) and (num / nbr)) or 1
if !pellet then factor = factor * nbr end
local dmgmax = self:GetBuff("Damage") * factor
local dmgmin = self:GetBuff("DamageMin") * factor
local delta = self:GetRangeFraction(range)
local lerped = Lerp(delta, dmgmax, dmgmin)
return lerped
end
function SWEP:SecondaryAttack()
return self.Melee2 and self:Bash(true)
end
function SWEP:CanShootWhileSprint()
return ArcCW.ConVars["mult_shootwhilesprinting"]:GetBool() or self:GetBuff_Override("Override_ShootWhileSprint", self.ShootWhileSprint)
end

View File

@@ -0,0 +1,73 @@
--[[
| 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)
SWEP.ClientFreeAimAng = Angle(ang0)
function SWEP:ShouldFreeAim()
if self:GetOwner():IsNPC() then return false end
if (ArcCW.ConVars["freeaim"]:GetInt() == 0 or self:GetBuff_Override("NeverFreeAim", self.NeverFreeAim)) and !self:GetBuff_Override("AlwaysFreeAim", self.AlwaysFreeAim) then return false end
return true
end
function SWEP:FreeAimMaxAngle()
local ang = self.FreeAimAngle and self:GetBuff("FreeAimAngle") or math.Clamp(self:GetBuff("HipDispersion") / 80, 3, 10)
return ang
end
function SWEP:ThinkFreeAim()
if self:ShouldFreeAim() then
local diff = self:GetOwner():EyeAngles() - self:GetLastAimAngle()
--diff = diff * 2
local freeaimang = Angle(self:GetFreeAimAngle())
local max = self:FreeAimMaxAngle()
local delta = math.min(self:GetSightDelta(),
self:CanShootWhileSprint() and 1 or (1 - self:GetSprintDelta()),
self:GetState() == ArcCW.STATE_CUSTOMIZE and 0 or 1)
max = max * delta
diff.p = math.NormalizeAngle(diff.p)
diff.y = math.NormalizeAngle(diff.y)
diff = diff * Lerp(delta, 1, 0.25)
freeaimang.p = math.Clamp(math.NormalizeAngle(freeaimang.p) + math.NormalizeAngle(diff.p), -max, max)
freeaimang.y = math.Clamp(math.NormalizeAngle(freeaimang.y) + math.NormalizeAngle(diff.y), -max, max)
local ang2d = math.atan2(freeaimang.p, freeaimang.y)
local mag2d = math.sqrt(math.pow(freeaimang.p, 2) + math.pow(freeaimang.y, 2))
mag2d = math.min(mag2d, max)
freeaimang.p = mag2d * math.sin(ang2d)
freeaimang.y = mag2d * math.cos(ang2d)
self:SetFreeAimAngle(freeaimang)
if CLIENT then
self.ClientFreeAimAng = freeaimang
end
end
self:SetLastAimAngle(self:GetOwner():EyeAngles())
end
function SWEP:GetFreeAimOffset()
if !self:ShouldFreeAim() then return ang0 end
if CLIENT then
return self.ClientFreeAimAng
else
return self:GetFreeAimAngle()
end
end

View File

@@ -0,0 +1,200 @@
--[[
| 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/
--]]
SWEP.GrenadePrimeTime = 0
function SWEP:PreThrow()
if self:GetNWState() == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() then return end
local bot, inf = self:HasBottomlessClip(), self:HasInfiniteAmmo()
local aps = self:GetBuff("AmmoPerShot")
if !inf and (bot and self:Ammo1() or self:Clip1()) < aps then
if self:Ammo1() == 0 and self:Clip1() == 0 and !self:GetBuff_Override("Override_KeepIfEmpty", self.KeepIfEmpty) then
self:GetOwner():StripWeapon(self:GetClass())
end
return
end
if self:GetGrenadePrimed() then return end
if engine.ActiveGamemode() == "terrortown" and GetRoundState and GetRoundState() == ROUND_PREP and
((GetConVar("ttt_no_nade_throw_during_prep") and GetConVar("ttt_no_nade_throw_during_prep"):GetBool())
or (GetConVar("ttt_nade_throw_during_prep") and !GetConVar("ttt_nade_throw_during_prep"):GetBool())) then
return
end
self.GrenadePrimeTime = CurTime()
local alt = self:GetOwner():KeyDown(IN_ATTACK2)
self:SetGrenadeAlt(alt)
self:SetGrenadePrimed(true)
local pulltime = self:GetBuff("PullPinTime")
local anim = alt and self:SelectAnimation("pre_throw_alt") or self:SelectAnimation("pre_throw")
self:PlayAnimation(anim, self.PullPinTime / pulltime, true, 0, true, nil, true)
self.isCooked = (!alt and self:GetBuff("CookPrimFire", true)) or (alt and self:GetBuff("CookAltFire", true)) or nil
self:SetNextPrimaryFire(CurTime() + pulltime)
self:SetPriorityAnim(CurTime() + pulltime)
self:SetShouldHoldType()
self:GetBuff_Hook("Hook_PreThrow")
if pulltime == 0 then
self:Throw()
return
end
end
function SWEP:Throw()
if self:GetNextPrimaryFire() > CurTime() then return end
local isCooked = self.isCooked
self:SetGrenadePrimed(false)
self.isCooked = nil
local alt = self:GetGrenadeAlt()
local anim = alt and self:SelectAnimation("throw_alt") or self:SelectAnimation("throw")
self:PlayAnimation(anim, self:GetBuff_Mult("Mult_ThrowTime"), false, 0, true)
local animevent = alt and self:GetBuff_Override("Override_AnimShootAlt", self.AnimShootAlt) or self:GetBuff_Override("Override_AnimShoot", self.AnimShoot)
self:GetOwner():DoAnimationEvent(animevent)
local heldtime = CurTime() - self.GrenadePrimeTime
local mv = 0
if alt then
mv = self:GetBuff("MuzzleVelocityAlt", true) or self:GetBuff("MuzzleVelocity")
else
mv = self:GetBuff("MuzzleVelocity")
local chg = self:GetBuff("WindupTime")
if chg > 0 then
mv = Lerp(math.Clamp(heldtime / chg, 0, 1), mv * self:GetBuff("WindupMinimum"), mv)
end
end
local force = mv * ArcCW.HUToM
self:SetTimer(self:GetBuff("ShootEntityDelay"), function()
local ft = self:GetBuff("FuseTime", true)
local data = {
dodefault = true,
force = force,
shootentity = self:GetBuff_Override("Override_ShootEntity", self.ShootEntity),
fusetime = ft and (ft - (isCooked and heldtime or 0)),
}
local ovr = self:GetBuff_Hook("Hook_Throw", data)
if !ovr or ovr.dodefault then
local rocket = self:FireRocket(self:GetBuff_Override("Override_ShootEntity", self.ShootEntity), force / ArcCW.HUToM)
if !rocket then return end
if ft then
if isCooked then
rocket.FuseTime = ft - heldtime
else
rocket.FuseTime = ft
end
else
rocket.FuseTime = math.huge
end
local phys = rocket:GetPhysicsObject()
local inertia = self:GetBuff_Override("Override_ThrowInertia", self.ThrowInertia)
if inertia == nil then inertia = ArcCW.ConVars["throwinertia"]:GetBool() end
if inertia and mv > 100 then
phys:AddVelocity(self:GetOwner():GetVelocity())
end
phys:AddAngleVelocity( Vector(0, 750, 0) )
end
if !self:HasInfiniteAmmo() then
local aps = self:GetBuff("AmmoPerShot")
local a1 = self:Ammo1()
if self:HasBottomlessClip() or a1 >= aps then
self:TakePrimaryAmmo(aps)
elseif a1 < aps then
self:SetClip1(math.min(self:GetCapacity() + self:GetChamberSize(), self:Clip1() + a1))
self:TakePrimaryAmmo(a1)
end
if (self.Singleton or self:Ammo1() == 0) and !self:GetBuff_Override("Override_KeepIfEmpty", self.KeepIfEmpty) then
self:GetOwner():StripWeapon(self:GetClass())
return
end
end
end)
local t = self:GetAnimKeyTime(anim) * self:GetBuff_Mult("Mult_ThrowTime")
self:SetPriorityAnim(CurTime() + t)
self:SetTimer(t, function()
if !self:IsValid() then return end
local a = self:SelectAnimation("reload") or self:SelectAnimation("draw")
self:PlayAnimation(a, self:GetBuff_Mult("Mult_ReloadTime"), true, 0, nil, nil, true)
self:SetPriorityAnim(CurTime() + self:GetAnimKeyTime(a, true) * self:GetBuff_Mult("Mult_ReloadTime"))
end)
self:SetNextPrimaryFire(CurTime() + self:GetFiringDelay())
self:SetGrenadeAlt(false)
self:SetShouldHoldType()
self:GetBuff_Hook("Hook_PostThrow")
end
function SWEP:GrenadeDrop(doammo)
local rocket = self:FireRocket(self.ShootEntity, 0)
if IsValid(rocket) then
local phys = rocket:GetPhysicsObject()
if ArcCW.ConVars["throwinertia"]:GetBool() then
phys:AddVelocity(self:GetOwner():GetVelocity())
end
local ft = self:GetBuff_Override("Override_FuseTime") or self.FuseTime
if ft then
if self.isCooked then
rocket.FuseTime = ft - (CurTime() - self.GrenadePrimeTime)
else
rocket.FuseTime = ft
end
end
end
if doammo then
if !self:HasInfiniteAmmo() then
local aps = self:GetBuff("AmmoPerShot")
local a1 = self:Ammo1()
if self:HasBottomlessClip() or a1 >= aps then
self:TakePrimaryAmmo(aps)
elseif a1 < aps then
self:SetClip1(math.min(self:GetCapacity() + self:GetChamberSize(), self:Clip1() + a1))
self:TakePrimaryAmmo(a1)
end
if (self.Singleton or self:Ammo1() == 0) and !self:GetBuff_Override("Override_KeepIfEmpty", self.KeepIfEmpty) then
self:GetOwner():StripWeapon(self:GetClass())
return
end
end
self:SetNextPrimaryFire(CurTime() + 1)
self:SetGrenadePrimed(false)
end
end

View File

@@ -0,0 +1,222 @@
--[[
| 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/
--]]
SWEP.NextHeatDissipateTime = 0
SWEP.Heat = 0
function SWEP:GetMaxHeat()
return self:GetBuff("HeatCapacity")
end
function SWEP:AddHeat(a)
local single = game.SinglePlayer()
a = tonumber(a)
if !(self.Jamming or self:GetBuff_Override("Override_Jamming")) then return end
if single and self:GetOwner():IsValid() and SERVER then self:CallOnClient("AddHeat", a) end
-- if !single and !IsFirstTimePredicted() then return end
local max = self:GetBuff("HeatCapacity")
local mult = 1 * self:GetBuff_Mult("Mult_FixTime")
local heat = self:GetHeat()
local anim = self:SelectAnimation("fix")
anim = self:GetBuff_Hook("Hook_SelectFixAnim", anim) or anim
local amount = a or 1
local t = CurTime() + self:GetAnimKeyTime(anim) * mult
self.Heat = math.max(0, heat + amount * ArcCW.ConVars["mult_heat"]:GetFloat())
self.NextHeatDissipateTime = CurTime() + (self:GetBuff("HeatDelayTime"))
local overheat = self.Heat >= max
if overheat then
local h = self:GetBuff_Hook("Hook_Overheat", self.Heat)
if h == true then overheat = false end
end
if overheat then
self.Heat = math.min(self.Heat, max)
if self:GetBuff_Override("Override_HeatFix", self.HeatFix) then
self.NextHeatDissipateTime = t
elseif self:GetBuff_Override("Override_HeatLockout", self.HeatLockout) then
self.NextHeatDissipateTime = t
end
elseif !self:GetBuff_Override("Override_HeatOverflow", self.HeatOverflow) then
self.Heat = math.min(self.Heat, max)
end
if single and CLIENT then return end
self:SetHeat(self.Heat)
if overheat then
local ret = self:GetBuff_Hook("Hook_OnOverheat")
if ret then return end
if anim then
self:PlayAnimation(anim, mult, true, 0, true)
self:SetPriorityAnim(t)
self:SetNextPrimaryFire(t)
if self:GetBuff_Override("Override_HeatFix", self.HeatFix) then
self:SetTimer(t - CurTime(),
function()
self:SetHeat(0)
end)
end
end
if self.HeatLockout or self:GetBuff_Override("Override_HeatLockout") then
self:SetHeatLocked(true)
end
self:GetBuff_Hook("Hook_PostOverheat")
end
end
function SWEP:DoHeat()
if self.NextHeatDissipateTime > CurTime() then return end
--local diss = self.HeatDissipation or 2
--diss = diss * self:GetBuff_Mult("Mult_HeatDissipation")
local diss = self:GetBuff("HeatDissipation") or 2
local ft = FrameTime()
self.Heat = self:GetHeat() - (ft * diss)
self.Heat = math.max(self.Heat, 0)
self:SetHeat(self.Heat)
if self.Heat <= 0 and self:GetHeatLocked() then
self:SetHeatLocked(false)
end
end
function SWEP:HeatEnabled()
return self.Jamming or self:GetBuff_Override("Override_Jamming")
end
function SWEP:MalfunctionEnabled()
local cvar = ArcCW.ConVars["malfunction"]:GetInt()
return cvar == 2 or (cvar == 1 and self:GetBuff_Override("Override_Malfunction", self.Malfunction))
end
function SWEP:GetMalfunctionAnimation()
local anim = self:SelectAnimation("unjam")
if !self.Animations[anim] then
anim = self:SelectAnimation("fix")
anim = self:GetBuff_Hook("Hook_SelectFixAnim", anim) or anim
end
if !self.Animations[anim] then anim = self:SelectAnimation("cycle") end
if !self.Animations[anim] then anim = nil end
return anim
end
function SWEP:DoMalfunction(post)
if !IsFirstTimePredicted() then return end
if !self:MalfunctionEnabled() then return false end
local shouldpost = self:GetBuff_Override("Override_MalfunctionPostFire", self.MalfunctionPostFire)
if post != shouldpost then return false end
-- Auto calculated malfunction mean
if self.MalfunctionMean == nil then
local mm
if self.Jamming then mm = self.HeatCapacity * 4
else mm = self.Primary.ClipSize * 8 end
if self.ManualAction then
-- Manual guns are less likely to jam
mm = mm * 2
else
-- Burst and semi only guns are less likely to jam
local a, b = false, false
for k, v in pairs(self.Firemodes) do
if !v.Mode then continue end
if v.Mode == 2 then a = true
elseif v.Mode < 0 then b = true end
end
if !a and b then
mm = mm * 1.25
elseif !a and !b then
mm = mm * 1.5
end
end
self.MalfunctionMean = mm
end
local cvar = math.max(ArcCW.ConVars["mult_malfunction"]:GetFloat(), 0.00000001)
local mean = self:GetBuff("MalfunctionMean") / cvar
local var = mean * math.Clamp(self:GetBuff("MalfunctionVariance") * math.max(1, math.sqrt(cvar)), 0, 1)
local count = (self.ShotsSinceMalfunction or 0)
if !self.NextMalfunction then
math.randomseed(math.Round(util.SharedRandom(count, -1337, 1337, !game.SinglePlayer() and self:GetOwner():GetCurrentCommand():CommandNumber() or CurTime()) * (self:EntIndex() % 30241)))
self.NextMalfunction = math.ceil(math.sqrt(-2 * var * math.log(math.random())) * math.cos(2 * math.pi * math.random()))
end
local ret = self:GetBuff_Hook("Hook_Malfunction", count, true)
if ret != nil then return ret end
-- if self:Clip1() <= 1 then return false end -- Don't fucking
--print(mean, var, count, self.NextMalfunction)
if count >= self.NextMalfunction + mean then
local ret2 = self:GetBuff_Hook("Hook_OnMalfunction", count, true)
if ret2 then return false end
self:MyEmitSound(self:GetBuff_Override("Override_MalfunctionSound") or self.MalfunctionSound, 75, 100, 1, CHAN_ITEM)
local wait = self:GetBuff("MalfunctionWait")
self:SetNextPrimaryFire(CurTime() + wait)
local anim = self:GetMalfunctionAnimation()
if !anim or self:GetBuff_Override("Override_MalfunctionJam", self.MalfunctionJam) then
self:SetMalfunctionJam(true)
else
self:SetTimer(wait,
function()
self:MalfunctionClear()
end)
end
self:GetBuff_Hook("Hook_PostMalfunction")
self.ShotsSinceMalfunction = 0
self.NextMalfunction = nil
self:SetBurstCount(0)
return true
else
self.ShotsSinceMalfunction = (self.ShotsSinceMalfunction or 0) + 1
return false
end
end
function SWEP:MalfunctionClear()
if self:GetBuff_Override("Override_MalfunctionTakeRound", self.MalfunctionTakeRound) then
self:TakePrimaryAmmo(self:GetBuff("AmmoPerShot"))
end
local anim = self:GetMalfunctionAnimation()
if anim then
self:PlayAnimation(anim, self:GetBuff_Mult("Mult_MalfunctionFixTime"), true, 0, true)
local wait = self:GetAnimKeyTime(anim) - 0.01
self:SetTimer(wait,
function()
self:SetMalfunctionJam(false)
self:PlayIdleAnimation(true)
end)
return true
else
self:SetMalfunctionJam(false)
return false
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,476 @@
--[[
| 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/
--]]
function SWEP:GetReloadTime()
-- Only works with classic mag-fed weapons.
local mult = self:GetBuff_Mult("Mult_ReloadTime")
local anim = self:SelectReloadAnimation()
if !self.Animations[anim] then return false end
local full = self:GetAnimKeyTime(anim) * mult
local magin = self:GetAnimKeyTime(anim, true) * mult
return { full, magin }
end
function SWEP:SetClipInfo(load)
load = self:GetBuff_Hook("Hook_SetClipInfo", load) or load
self.LastLoadClip1 = load - self:Clip1()
self.LastClip1 = load
end
function SWEP:Reload()
if IsValid(self:GetHolster_Entity()) then return end
if self:GetHolster_Time() > 0 then return end
if self:GetOwner():IsNPC() then
return
end
if self:GetState() == ArcCW.STATE_CUSTOMIZE then
return
end
-- Switch to UBGL
if self:GetBuff_Override("UBGL") and self:GetOwner():KeyDown(IN_USE) then
if self:GetInUBGL() then
--net.Start("arccw_ubgl")
--net.WriteBool(false)
--net.SendToServer()
self:DeselectUBGL()
else
--net.Start("arccw_ubgl")
--net.WriteBool(true)
--net.SendToServer()
self:SelectUBGL()
end
return
end
if self:GetInUBGL() then
if self:GetNextSecondaryFire() > CurTime() then return end
self:ReloadUBGL()
return
end
if self:GetNextPrimaryFire() >= CurTime() then return end
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
if self.Throwing then return end
if self.PrimaryBash then return end
-- with the lite 3D HUD, you may want to check your ammo without reloading
local Lite3DHUD = self:GetOwner():GetInfo("arccw_hud_3dfun") == "1"
if self:GetOwner():KeyDown(IN_WALK) and Lite3DHUD then
return
end
if self:GetMalfunctionJam() then
local r = self:MalfunctionClear()
if r then return end
end
if !self:GetMalfunctionJam() and self:Ammo1() <= 0 and !self:HasInfiniteAmmo() then return end
if self:HasBottomlessClip() then return end
if self:GetBuff_Hook("Hook_PreReload") then return end
-- if we must dump our clip when reloading, our reserve ammo should be more than our clip
local dumpclip = self:GetBuff_Hook("Hook_ReloadDumpClip")
if dumpclip and !self:HasInfiniteAmmo() and self:Clip1() >= self:Ammo1() then
return
end
self.LastClip1 = self:Clip1()
local reserve = self:Ammo1()
reserve = reserve + self:Clip1()
if self:HasInfiniteAmmo() then reserve = self:GetCapacity() + self:Clip1() end
local clip = self:GetCapacity()
local chamber = math.Clamp(self:Clip1(), 0, self:GetChamberSize())
if self:GetNeedCycle() then chamber = 0 end
local load = math.Clamp(clip + chamber, 0, reserve)
if !self:GetMalfunctionJam() and load <= self:Clip1() then return end
self:SetBurstCount(0)
local shouldshotgunreload = self:GetBuff_Override("Override_ShotgunReload")
local shouldhybridreload = self:GetBuff_Override("Override_HybridReload")
if shouldshotgunreload == nil then shouldshotgunreload = self.ShotgunReload end
if shouldhybridreload == nil then shouldhybridreload = self.HybridReload end
if shouldhybridreload then
shouldshotgunreload = self:Clip1() != 0
end
if shouldshotgunreload and self:GetShotgunReloading() > 0 then return end
local mult = self:GetBuff_Mult("Mult_ReloadTime")
if shouldshotgunreload then
local anim = "sgreload_start"
local insertcount = 0
local empty = self:Clip1() == 0 --or self:GetNeedCycle()
if self.Animations.sgreload_start_empty and empty then
anim = "sgreload_start_empty"
empty = false
if (self.Animations.sgreload_start_empty or {}).ForceEmpty == true then
empty = true
end
insertcount = (self.Animations.sgreload_start_empty or {}).RestoreAmmo or 1
else
insertcount = (self.Animations.sgreload_start or {}).RestoreAmmo or 0
end
anim = self:GetBuff_Hook("Hook_SelectReloadAnimation", anim) or anim
local time = self:GetAnimKeyTime(anim)
local time2 = self:GetAnimKeyTime(anim, true)
if time2 >= time then
time2 = 0
end
if insertcount > 0 then
self:SetMagUpCount(insertcount)
self:SetMagUpIn(CurTime() + time2 * mult)
end
self:PlayAnimation(anim, mult, true, 0, true, nil, true)
self:SetReloading(CurTime() + time * mult)
self:SetShotgunReloading(empty and 4 or 2)
else
local anim = self:SelectReloadAnimation()
if !self.Animations[anim] then print("Invalid animation \"" .. anim .. "\"") return end
self:PlayAnimation(anim, mult, true, 0, false, nil, true)
local reloadtime = self:GetAnimKeyTime(anim, true) * mult
local reloadtime2 = self:GetAnimKeyTime(anim, false) * mult
self:SetNextPrimaryFire(CurTime() + reloadtime2)
self:SetReloading(CurTime() + reloadtime2)
self:SetMagUpCount(0)
self:SetMagUpIn(CurTime() + reloadtime)
end
self:SetClipInfo(load)
if game.SinglePlayer() then
self:CallOnClient("SetClipInfo", tostring(load))
end
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
local atttbl = ArcCW.AttachmentTable[k.Installed]
if atttbl.DamageOnReload then
self:DamageAttachment(i, atttbl.DamageOnReload)
end
end
if !self.ReloadInSights then
self:ExitSights()
self.Sighted = false
end
self:GetBuff_Hook("Hook_PostReload")
end
function SWEP:ReloadTimed()
-- yeah my function names are COOL and QUIRKY and you can't say a DAMN thing about it.
self:RestoreAmmo(self:GetMagUpCount() != 0 and self:GetMagUpCount())
self:SetMagUpCount(0)
self:SetLastLoad(self:Clip1())
self:SetNthReload(self:GetNthReload() + 1)
end
function SWEP:Unload()
if !self:GetOwner():IsPlayer() then return end
if SERVER and self:Clip1() != ArcCW.BottomlessMagicNumber then
self:GetOwner():GiveAmmo(self:Clip1(), self.Primary.Ammo or "", true)
end
self:SetClip1(0)
end
function SWEP:HasBottomlessClip()
if ArcCW.ConVars["mult_bottomlessclip"]:GetBool() then return true end
if self.BottomlessClip or self:GetBuff_Override("Override_BottomlessClip") then return true end
return false
end
function SWEP:HasInfiniteAmmo()
if ArcCW.ConVars["mult_infiniteammo"]:GetBool() then return true end
if self:GetBuff_Override("Override_InfiniteAmmo", self.InfiniteAmmo) then return true end
return false
end
function SWEP:RestoreAmmo(count)
if self:GetOwner():IsNPC() then return end
local chamber = math.Clamp(self:Clip1(), 0, self:GetChamberSize())
if self:GetNeedCycle() then chamber = 0 end
local clip = self:GetCapacity()
count = count or (clip + chamber)
local reserve = (self:HasInfiniteAmmo() and math.huge or self:Ammo1())
local dumpclip = self:GetBuff_Hook("Hook_ReloadDumpClip")
if !dumpclip then
reserve = reserve + self:Clip1()
end
local load = math.Clamp(self:Clip1() + count, 0, reserve)
load = math.Clamp(load, 0, clip + chamber)
reserve = reserve - load
if !self:HasInfiniteAmmo() then
self:GetOwner():SetAmmo(reserve, self.Primary.Ammo, true)
end
self:SetClip1(load)
end
-- local lastframeclip1 = 0
SWEP.LastClipOutTime = 0
function SWEP:GetVisualBullets()
local h = self:GetBuff_Hook("Hook_GetVisualBullets")
if h then return h end
local _clip = self:Clip1()
local _ammo = self:Ammo1()
if self:HasInfiniteAmmo() then
_ammo = math.huge
end
if self:HasBottomlessClip() then
_clip = _ammo
end
if self.LastClipOutTime > CurTime() then
return self.LastClip1_B or _clip
else
self.LastClip1_B = _clip
if self:GetReloading() and !(self.ShotgunReload or (self.HybridReload and _clip == 0)) then
return math.Clamp(_clip + _ammo, 0, self:GetCapacity() + self:GetChamberSize())
else
return _clip
end
end
end
function SWEP:GetVisualClip()
-- local reserve = self:Ammo1()
-- local chamber = math.Clamp(self:Clip1(), 0, self:GetChamberSize())
-- local abouttoload = math.Clamp(self:GetCapacity() + chamber, 0, reserve + self:Clip1())
-- local h = self:GetBuff_Hook("Hook_GetVisualClip")
-- if h then return h end
-- if self.LastClipOutTime > CurTime() then
-- return self.LastClip1 or self:Clip1()
-- else
-- if !self.RevolverReload then
-- self.LastClip1 = self:Clip1()
-- else
-- if self:Clip1() > lastframeclip1 then
-- self.LastClip1 = self:Clip1()
-- end
-- lastframeclip1 = self:Clip1()
-- end
-- if self:GetReloading() and !(self.ShotgunReload or (self.HybridReload and self:Clip1() == 0)) then
-- return abouttoload
-- else
-- return self.LastClip1 or self:Clip1()
-- end
-- end
local reserve = self:Ammo1()
if self:HasInfiniteAmmo() then
reserve = math.huge
end
local chamber = math.Clamp(self:Clip1(), 0, self:GetChamberSize())
local abouttoload = math.Clamp(self:GetCapacity() + chamber, 0, reserve + self:Clip1())
local h = self:GetBuff_Hook("Hook_GetVisualClip")
if h then return h end
if self.LastClipOutTime > CurTime() then
return self:GetLastLoad() or self:Clip1()
end
if self.RevolverReload then
if self:GetReloading() and !(self.ShotgunReload or (self.HybridReload and self:Clip1() == 0)) then
return abouttoload
else
return self:GetLastLoad() or self:Clip1()
end
else
return self:Clip1()
end
end
function SWEP:GetVisualLoadAmount()
return self.LastLoadClip1 or self:Clip1()
end
function SWEP:SelectReloadAnimation()
local ret
if self.Animations.reload_empty and self:Clip1() == 0 then
ret = "reload_empty"
else
ret = "reload"
end
ret = self:GetBuff_Hook("Hook_SelectReloadAnimation", ret) or ret
return ret
end
function SWEP:ReloadInsert(empty)
local total = self:GetCapacity()
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
if !empty and !self:GetNeedCycle() then
total = total + (self:GetBuff("ChamberLoadNonEmpty", true) or self:GetChamberSize())
else
total = total + (self:GetBuff("ChamberLoadEmpty", true) or 0)
end
local mult = self:GetBuff_Mult("Mult_ReloadTime")
if self:Clip1() >= total or (self:Ammo1() == 0 and !self:HasInfiniteAmmo()) or ((self:GetShotgunReloading() == 3 or self:GetShotgunReloading() == 5) and self:Clip1() > 0) then
local ret = "sgreload_finish"
if empty then
if self.Animations.sgreload_finish_empty then
ret = "sgreload_finish_empty"
end
if self:GetNeedCycle() then
self:SetNeedCycle(false)
end
end
ret = self:GetBuff_Hook("Hook_SelectReloadAnimation", ret) or ret
self:PlayAnimation(ret, mult, true, 0, true, nil, true)
self:SetReloading(CurTime() + (self:GetAnimKeyTime(ret, true) * mult))
self:SetTimer(self:GetAnimKeyTime(ret, true) * mult,
function()
self:SetNthReload(self:GetNthReload() + 1)
if self:GetOwner():KeyDown(IN_ATTACK2) then
self:EnterSights()
end
end)
self:SetShotgunReloading(0)
else
local insertcount = self:GetBuff_Override("Override_InsertAmount") or 1
local insertanim = "sgreload_insert"
local ret = self:GetBuff_Hook("Hook_SelectInsertAnimation", {count = insertcount, anim = insertanim, empty = empty})
if ret then
insertcount = ret.count
insertanim = ret.anim
end
local load = self:GetCapacity() + math.min(self:Clip1(), self:GetChamberSize())
if load - self:Clip1() > self:Ammo1() then load = self:Clip1() + self:Ammo1() end
self:SetClipInfo(load)
if game.SinglePlayer() then
self:CallOnClient("SetClipInfo", tostring(load))
end
local time = self:GetAnimKeyTime(insertanim, false)
local time2 = self:GetAnimKeyTime(insertanim, true)
if time2 >= time then
time2 = 0
end
self:SetMagUpCount(insertcount)
self:SetMagUpIn(CurTime() + time2 * mult)
self:SetReloading(CurTime() + time * mult)
self:PlayAnimation(insertanim, mult, true, 0, true, nil, true)
self:SetShotgunReloading(empty and 4 or 2)
end
end
function SWEP:GetCapacity()
local clip = self.RegularClipSize or self.Primary.ClipSize
if !self.RegularClipSize then
self.RegularClipSize = self.Primary.ClipSize
end
local level = 1
if self:GetBuff_Override("MagExtender") then
level = level + 1
end
if self:GetBuff_Override("MagReducer") then
level = level - 1
end
if level == 0 then
clip = self.ReducedClipSize
elseif level == 2 then
clip = self.ExtendedClipSize
end
clip = self:GetBuff("ClipSize", true, clip) or clip
local ret = self:GetBuff_Hook("Hook_GetCapacity", clip)
clip = ret or clip
clip = math.Clamp(math.Round(clip), 0, math.huge)
self.Primary.ClipSize = clip
return clip
end
function SWEP:GetChamberSize()
return self:GetBuff("ChamberSize") --(self:GetBuff_Override("Override_ChamberSize") or self.ChamberSize) + self:GetBuff_Add("Add_ChamberSize")
end

View File

@@ -0,0 +1,79 @@
--[[
| 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/
--]]
function SWEP:FireRocket(ent, vel, ang, dontinheritvel)
if CLIENT then return end
local rocket = ents.Create(ent)
ang = ang or (self:GetOwner():EyeAngles() + self:GetFreeAimOffset())
local src = self:GetShootSrc()
if !rocket:IsValid() then print("!!! INVALID ROUND " .. ent) return end
local rocketAng = Angle(ang.p, ang.y, ang.r)
if ang and self.ShootEntityAngleCorrection then
local up = ang:Up()
local right = ang:Right()
local forward = ang:Forward()
rocketAng:RotateAroundAxis(up, self.ShootEntityAngleCorrection.y)
rocketAng:RotateAroundAxis(right, self.ShootEntityAngleCorrection.p)
rocketAng:RotateAroundAxis(forward, self.ShootEntityAngleCorrection.r)
end
rocket:SetAngles(rocketAng)
rocket:SetPos(src)
rocket:SetOwner(self:GetOwner())
rocket.Inflictor = self
local randfactor = self:GetBuff("DamageRand")
local mul = 1
if randfactor > 0 then
mul = mul * math.Rand(1 - randfactor, 1 + randfactor)
end
rocket.Damage = self:GetBuff("Damage") * mul
if self.BlastRadius then
local r_randfactor = self:GetBuff("DamageRand")
local r_mul = 1
if r_randfactor > 0 then
r_mul = r_mul * math.Rand(1 - r_randfactor, 1 + r_randfactor)
end
rocket.BlastRadius = self:GetBuff("BlastRadius") * r_mul
end
local RealVelocity = (!dontinheritvel and self:GetOwner():GetAbsVelocity() or Vector(0, 0, 0)) + ang:Forward() * vel
rocket.CurVel = RealVelocity -- for non-physical projectiles that move themselves
rocket:Spawn()
rocket:Activate()
if !rocket.NoPhys and rocket:GetPhysicsObject():IsValid() then
rocket:SetCollisionGroup(rocket.CollisionGroup or COLLISION_GROUP_DEBRIS)
rocket:GetPhysicsObject():SetVelocityInstantaneous(RealVelocity)
end
if rocket.Launch and rocket.SetState then
rocket:SetState(1)
rocket:Launch()
end
if rocket.ArcCW_Killable == nil then
rocket.ArcCW_Killable = true
end
rocket.ArcCWProjectile = true
self:GetBuff_Hook("Hook_PostFireRocket", rocket)
return rocket
end

View File

@@ -0,0 +1,533 @@
--[[
| 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/
--]]
SWEP.Sighted = false
SWEP.Sprinted = false
local function linearlerp(a, b, c)
return b + (c - b) * a
end
function SWEP:GetSightTime()
return self:GetBuff("SightTime")
end
function SWEP:EnterSprint()
if engine.ActiveGamemode() == "terrortown" and !(TTT2 and self:GetOwner().isSprinting) then return end
if self:GetState() == ArcCW.STATE_SPRINT then return end
if self:GetState() == ArcCW.STATE_CUSTOMIZE then return end
if self:GetTriggerDelta() > 0 then return end
if self:GetGrenadePrimed() and !self:CanShootWhileSprint() then return end
self:SetState(ArcCW.STATE_SPRINT)
self.Sighted = false
self.Sprinted = true
local ct = CurTime()
-- self.SwayScale = 1
-- self.BobScale = 5
self:SetShouldHoldType()
local s = self:CanShootWhileSprint()
if !s and self:GetNextPrimaryFire() <= ct then
self:SetNextPrimaryFire(ct)
end
local anim = self:SelectAnimation("enter_sprint")
if anim and !s and self:GetNextSecondaryFire() <= ct then
self:PlayAnimation(anim, self:GetBuff("SightTime") / self:GetAnimKeyTime(anim, true), true, nil, false, nil, false, false)
end
end
function SWEP:ExitSprint()
if self:GetState() == ArcCW.STATE_IDLE then return end
local delta = self:GetNWSprintDelta()
local ct = CurTime()
self:SetState(ArcCW.STATE_IDLE)
self.Sighted = false
self.Sprinted = false
-- self.SwayScale = 1
-- self.BobScale = 1.5
self:SetShouldHoldType()
local s = self:CanShootWhileSprint()
if !s and self:GetNextPrimaryFire() <= ct then
self:SetNextPrimaryFire(ct + self:GetSprintTime() * delta)
end
if self:GetOwner():KeyDown(IN_ATTACK2) then
self:EnterSights()
end
local anim = self:SelectAnimation("exit_sprint")
if anim and !s then -- and self:GetNextSecondaryFire() <= ct
self:PlayAnimation(anim, self:GetBuff("SightTime") / self:GetAnimKeyTime(anim, true), true, nil, false, nil, false, false)
end
end
-- defined above already?
function SWEP:EnterSights()
local asight = self:GetActiveSights()
if !asight then return end
if self:GetState() != ArcCW.STATE_IDLE then return end
if self:GetCurrentFiremode().Mode == 0 then return end
if !self.ReloadInSights and (self:GetReloading() or self:GetOwner():KeyDown(IN_RELOAD)) then return end
if self.LockSightsInPriorityAnim and self:GetPriorityAnim() then return end
if self:GetBuff_Hook("Hook_ShouldNotSight") then return end
if (!game.SinglePlayer() and !IsFirstTimePredicted()) then return end
self:SetupActiveSights()
self:SetState(ArcCW.STATE_SIGHTS)
self.Sighted = true
self.Sprinted = false
self:SetShouldHoldType()
self:MyEmitSound(asight.SwitchToSound or "", 75, math.Rand(95, 105), 0.5, CHAN_AUTO)
local anim = self:SelectAnimation("enter_sight")
if anim then
self:PlayAnimation(anim, 1 * self:GetBuff_Mult("Mult_SightTime"), true)
end
self:GetBuff_Hook("Hook_SightToggle", true)
end
function SWEP:ExitSights()
local asight = self:GetActiveSights()
if self:GetState() != ArcCW.STATE_SIGHTS then return end
if self.LockSightsInReload and self:GetReloading() then return end
if self.LockSightsInPriorityAnim and self:GetPriorityAnim() then return end
if (!game.SinglePlayer() and !IsFirstTimePredicted()) then return end
self:SetState(ArcCW.STATE_IDLE)
self.Sighted = false
self.Sprinted = false
self:SetShouldHoldType()
self:MyEmitSound(asight.SwitchFromSound or "", 75, math.Rand(80, 90), 0.5, CHAN_AUTO)
if self:InSprint() then
self:EnterSprint()
end
self:MyEmitSound(asight.SwitchFromSound or "", 75, math.Rand(80, 90), 0.5, CHAN_AUTO)
local anim = self:SelectAnimation("exit_sight")
if anim then
self:PlayAnimation(anim, 1 * self:GetBuff_Mult("Mult_SightTime"), true)
end
self:GetBuff_Hook("Hook_SightToggle", false)
end
function SWEP:GetSprintTime()
return self:GetSightTime()
end
SWEP.SightTable = {}
SWEP.SightMagnifications = {}
function SWEP:SetupActiveSights()
if !self.IronSightStruct then return end
if self:GetBuff_Hook("Hook_ShouldNotSight") then return false end
if !self:GetOwner():IsPlayer() then return end
local sighttable = {}
local vm = self:GetOwner():GetViewModel()
if !vm or !vm:IsValid() then return end
local kbi = self.KeepBaseIrons or true
local bif = self.BaseIronsFirst or true
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
local atttbl = ArcCW.AttachmentTable[k.Installed]
local addsights = self:GetBuff_Stat("AdditionalSights", i)
if !addsights then continue end
if !k.KeepBaseIrons and !atttbl.KeepBaseIrons then kbi = false end
if !k.BaseIronsFirst and !atttbl.BaseIronsFirst then bif = false end
for _, s in pairs(addsights) do
local stab = table.Copy(s)
stab.Slot = i
if stab.HolosightData then atttbl = stab.HolosightData end
stab.HolosightData = atttbl
if atttbl.HolosightMagnification then
stab.MagnifiedOptic = true
stab.ScopeMagnification = atttbl.HolosightMagnification or 1
if atttbl.HolosightMagnificationMin then
stab.ScopeMagnificationMin = atttbl.HolosightMagnificationMin
stab.ScopeMagnificationMax = atttbl.HolosightMagnificationMax
stab.ScopeMagnification = math.max(stab.ScopeMagnificationMax, stab.ScopeMagnificationMin)
if !i and self.SightMagnifications[0] then
stab.ScopeMagnification = self.SightMagnifications[0]
elseif self.SightMagnifications[i] then
stab.ScopeMagnification = self.SightMagnifications[i]
end
else
stab.ScopeMagnification = atttbl.HolosightMagnification
end
end
if atttbl.Holosight then
stab.Holosight = true
end
if !k.Bone then return end
local boneid = vm:LookupBone(k.Bone)
if !boneid then return end
if CLIENT then
if atttbl.HolosightPiece then
stab.HolosightPiece = (k.HSPElement or {}).Model
end
if atttbl.Holosight then
stab.HolosightModel = (k.VElement or {}).Model
end
local bpos, bang = self:GetFromReference(boneid)
local offset
local offset_ang
local vmang = Angle()
offset = k.Offset.vpos or Vector(0, 0, 0)
local attslot = k
local delta = attslot.SlidePos or 0.5
local vmelemod = nil
local slidemod = nil
for _, e in pairs(self:GetActiveElements()) do
local ele = self.AttachmentElements[e]
if !ele then continue end
if ((ele.AttPosMods or {})[i] or {}).vpos then
vmelemod = ele.AttPosMods[i].vpos
end
if ((ele.AttPosMods or {})[i] or {}).slide then
slidemod = ele.AttPosMods[i].slide
end
-- Refer to sh_model Line 837
if ((ele.AttPosMods or {})[i] or {}).SlideAmount then
slidemod = ele.AttPosMods[i].SlideAmount
end
end
offset = vmelemod or attslot.Offset.vpos or Vector()
if slidemod or attslot.SlideAmount then
offset = LerpVector(delta, (slidemod or attslot.SlideAmount).vmin, (slidemod or attslot.SlideAmount).vmax)
end
offset_ang = k.Offset.vang or Angle(0, 0, 0)
offset_ang = offset_ang + (atttbl.OffsetAng or Angle(0, 0, 0))
offset_ang = k.VMOffsetAng or offset_ang
bpos, bang = WorldToLocal(Vector(0, 0, 0), Angle(0, 0, 0), bpos, bang)
bpos = bpos + bang:Forward() * offset.x
bpos = bpos + bang:Right() * offset.y
bpos = bpos + bang:Up() * offset.z
bang:RotateAroundAxis(bang:Right(), offset_ang.p)
bang:RotateAroundAxis(bang:Up(), -offset_ang.y)
bang:RotateAroundAxis(bang:Forward(), offset_ang.r)
local vpos = Vector()
vpos.y = -bpos.x
vpos.x = bpos.y
vpos.z = -bpos.z
local corpos = (k.CorrectivePos or Vector(0, 0, 0))
vpos = vpos + bang:Forward() * corpos.x
vpos = vpos + bang:Right() * corpos.y
vpos = vpos + bang:Up() * corpos.z
-- vpos = vpos + (bang:Forward() * s.Pos.x)
-- vpos = vpos - (bang:Right() * s.Pos.y)
-- vpos = vpos + (bang:Up() * s.Pos.z)
vmang:Set(-bang)
bang.r = -bang.r
bang.p = -bang.p
bang.y = -bang.y
corang = k.CorrectiveAng or Angle(0, 0, 0)
bang:RotateAroundAxis(bang:Right(), corang.p)
bang:RotateAroundAxis(bang:Up(), corang.y)
bang:RotateAroundAxis(bang:Forward(), corang.r)
-- vpos = LocalToWorld(s.Pos + Vector(0, self.ExtraSightDist or 0, 0), Angle(0, 0, 0), vpos, bang)
-- local vmf = (vmang):Forward():GetNormalized()
-- local vmr = (vmang):Right():GetNormalized()
-- local vmu = (vmang):Up():GetNormalized()
-- print(" ----- vmf, vmr, vmu")
-- print(vmf)
-- print(vmr)
-- print(vmu)
-- vmf = -vmf
-- vmf.x = -vmf.x
-- local r = vmf.y
-- vmf.y = vmf.z
-- vmf.z = r
-- vmr = -vmr
-- vmr.y = -vmr.y
-- -- local r = vmr.y
-- -- vmr.y = vmr.z
-- -- vmr.z = r
-- vmu = -vmu
-- vmu.z = vmu.z
-- local evpos = Vector(0, 0, 0)
-- evpos = evpos + (vmf * (s.Pos.x + k.CorrectivePos.x))
-- evpos = evpos - (vmr * (s.Pos.y + (self.ExtraSightDist or 0) + k.CorrectivePos.y))
-- evpos = evpos + (vmu * (s.Pos.z + k.CorrectivePos.z))
-- print(vmang:Forward())
local evpos = s.Pos
evpos = evpos * (k.VMScale or Vector(1, 1, 1))
if atttbl.Holosight and !atttbl.HolosightMagnification then
evpos = evpos + Vector(0, k.ExtraSightDist or self.ExtraSightDist or 0, 0)
end
evpos = evpos + (k.CorrectivePos or Vector(0, 0, 0))
stab.Pos, stab.Ang = vpos, bang
stab.EVPos = evpos
stab.EVAng = s.Ang
if s.GlobalPos then
stab.EVPos = Vector(0, 0, 0)
stab.Pos = s.Pos
end
if s.GlobalAng then
stab.Ang = Angle(0, 0, 0)
end
end
table.insert(sighttable, stab)
end
end
if kbi then
local extra = self.ExtraIrons
if extra then
for _, ot in pairs(extra) do
local t = table.Copy(ot)
t.IronSight = true
if bif then
table.insert(sighttable, 1, t)
else
table.insert(sighttable, t)
end
end
end
local t = table.Copy(self:GetBuff_Override("Override_IronSightStruct") or self.IronSightStruct)
t.IronSight = true
if bif then
table.insert(sighttable, 1, t)
else
table.insert(sighttable, t)
end
end
self.SightTable = sighttable
end
function SWEP:SwitchActiveSights()
if table.Count(self.SightTable) == 1 then return end
self.ActiveSight = (self.ActiveSight or 1) + 1
if self.ActiveSight > table.Count(self.SightTable) then
self.ActiveSight = 1
end
local asight = self:GetActiveSights()
local tbl = self:GetBuff_Hook("Hook_SwitchActiveSights", {active = self.ActiveSight, asight = asight})
self.ActiveSight = tbl.active or self.ActiveSight
if self.ActiveSight > table.Count(self.SightTable) then
self.ActiveSight = 1
end
local asight2 = self:GetActiveSights()
if asight2.SwitchToSound then
self:MyEmitSound(asight2.SwitchToSound, 75, math.Rand(95, 105), 0.5, CHAN_VOICE2)
end
end
function SWEP:GetActiveSights()
if (self.ActiveSight or 1) > table.Count(self.SightTable) then
self.ActiveSight = 1
end
if table.Count(self.SightTable) == 0 then
return self.IronSightStruct
else
return self.SightTable[self.ActiveSight or 1]
end
end
local function ScaleFOVByWidthRatio( fovDegrees, ratio )
local halfAngleRadians = fovDegrees * ( 0.5 * math.pi / 180 )
local t = math.tan( halfAngleRadians )
t = t * ratio
local retDegrees = ( 180 / math.pi ) * math.atan( t )
return retDegrees * 2
end
function SWEP:QuickFOVix( fov )
return ScaleFOVByWidthRatio( fov, (ScrW and ScrW() or 4)/(ScrH and ScrH() or 3)/(4/3) )
end
SWEP.LastTranslateFOV = 0
function SWEP:TranslateFOV(fov)
local irons = self:GetActiveSights()
if CLIENT and ArcCW.ConVars["dev_benchgun"]:GetBool() then self.CurrentFOV = fov self.CurrentViewModelFOV = fov return fov end
self.ApproachFOV = self.ApproachFOV or fov
self.CurrentFOV = self.CurrentFOV or fov
-- Only update every tick (this function is called multiple times per tick)
if self.LastTranslateFOV == UnPredictedCurTime() then return self.CurrentFOV end
local timed = UnPredictedCurTime() - self.LastTranslateFOV
self.LastTranslateFOV = UnPredictedCurTime()
local app_vm = self.ViewModelFOV + self:GetOwner():GetInfoNum("arccw_vm_fov", 0)
if CLIENT then
app_vm = app_vm * (LocalPlayer():GetFOV()/GetConVar("fov_desired"):GetInt())
end
if self:GetState() == ArcCW.STATE_SIGHTS then
local asight = self:GetActiveSights()
local mag = asight and asight.ScopeMagnification or 1
local delta = math.pow(self:GetSightDelta(), 2)
if CLIENT then
local addads = math.Clamp(ArcCW.ConVars["vm_add_ads"]:GetFloat() or 0, -2, 14)
local csratio = math.Clamp(GetConVar("arccw_cheapscopesv2_ratio"):GetFloat() or 0, 0, 1)
local pfov = GetConVar("fov_desired"):GetInt()
if ArcCW.ConVars["cheapscopes"]:GetBool() and mag > 1 then
fov = (pfov / (asight and asight.Magnification or 1)) / (mag / (1 + csratio * mag) + (addads or 0) / 3)
else
fov = ( (pfov / (asight and asight.Magnification or 1)) * (1 - delta)) + (GetConVar("fov_desired"):GetInt() * delta)
end
app_vm = irons.ViewModelFOV or 45
app_vm = app_vm - (asight.MagnifiedOptic and (addads or 0) * 3 or 0)
end
end
self.ApproachFOV = fov
-- magic number? multiplier of 10 seems similar to previous behavior
self.CurrentFOV = math.Approach(self.CurrentFOV, self.ApproachFOV, timed * 10 * (self.CurrentFOV - self.ApproachFOV))
self.CurrentViewModelFOV = self.CurrentViewModelFOV or self.ViewModelFOV
self.CurrentViewModelFOV = math.Approach(self.CurrentViewModelFOV, app_vm, timed * 10 * (self.CurrentViewModelFOV - app_vm))
return self.CurrentFOV
end
function SWEP:SetShouldHoldType()
if self:GetCurrentFiremode().Mode == 0 then
self:SetHoldType(self.HoldtypeHolstered)
return
end
if IsValid(self:GetOwner()) and self:GetOwner():IsNPC() and self.HoldtypeNPC then
self:SetHoldType(self.HoldtypeNPC)
return
end
local ht = "normal"
if self:GetState() == ArcCW.STATE_SIGHTS then
ht = self:GetBuff_Override("Override_HoldtypeSights", self.HoldtypeSights)
elseif self:GetState() == ArcCW.STATE_SPRINT then
if self:CanShootWhileSprint() then
ht = self:GetBuff_Override("Override_HoldtypeSprintShoot", self.HoldtypeSprintShoot) or self:GetBuff_Override("Override_HoldtypeActive", self.HoldtypeActive)
else
ht = self:GetBuff_Override("Override_HoldtypeHolstered", self.HoldtypeHolstered)
end
elseif self:GetState() == ArcCW.STATE_CUSTOMIZE then
ht = self:GetBuff_Override("Override_HoldtypeCustomize", self.HoldtypeCustomize)
elseif self:GetCurrentFiremode().Mode == 0 then
ht = self:GetBuff_Override("Override_HoldtypeHolstered", self.HoldtypeHolstered)
elseif self.Throwing and self:GetGrenadePrimed() then
ht = self:GetBuff_Override("Override_HoldtypeSights", self.HoldtypeSights)
else
ht = self:GetBuff_Override("Override_HoldtypeActive", self.HoldtypeActive)
end
self:SetHoldType(ht)
end

View File

@@ -0,0 +1,445 @@
--[[
| 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/
--]]
if CLIENT then
ArcCW.LastWeapon = nil
end
local vec1 = Vector(1, 1, 1)
local vec0 = vec1 * 0
local ang0 = Angle(0, 0, 0)
local lastUBGL = 0
function SWEP:Think()
if IsValid(self:GetOwner()) and self:GetClass() == "arccw_base" then
self:Remove()
return
end
local owner = self:GetOwner()
if !IsValid(owner) or owner:IsNPC() then return end
if self:GetState() == ArcCW.STATE_DISABLE and !self:GetPriorityAnim() then
self:SetState(ArcCW.STATE_IDLE)
if CLIENT and self.UnReady then
self.UnReady = false
end
end
for i, v in ipairs(self.EventTable) do
for ed, bz in pairs(v) do
if ed <= CurTime() then
if bz.AnimKey and (bz.AnimKey != self.LastAnimKey or bz.StartTime != self.LastAnimStartTime) then
continue
end
self:PlayEvent(bz)
self.EventTable[i][ed] = nil
--print(CurTime(), "Event completed at " .. i, ed)
if table.IsEmpty(v) and i != 1 then self.EventTable[i] = nil --[[print(CurTime(), "No more events at " .. i .. ", killing")]] end
end
end
end
if CLIENT and (!game.SinglePlayer() and IsFirstTimePredicted() or true)
and self:GetOwner() == LocalPlayer() and ArcCW.InvHUD
and !ArcCW.Inv_Hidden and ArcCW.Inv_Fade == 0 then
ArcCW.InvHUD:Remove()
ArcCW.Inv_Fade = 0.01
end
local vm = owner:GetViewModel()
self.BurstCount = self:GetBurstCount()
local sg = self:GetShotgunReloading()
if (sg == 2 or sg == 4) and owner:KeyPressed(IN_ATTACK) then
self:SetShotgunReloading(sg + 1)
elseif (sg >= 2) and self:GetReloadingREAL() <= CurTime() then
self:ReloadInsert((sg >= 4) and true or false)
end
self:InBipod()
if self:GetNeedCycle() and !self.Throwing and !self:GetReloading() and self:GetWeaponOpDelay() < CurTime() and self:GetNextPrimaryFire() < CurTime() and -- Adding this delays bolting if the RPM is too low, but removing it may reintroduce the double pump bug. Increasing the RPM allows you to shoot twice on many multiplayer servers. Sure would be convenient if everything just worked nicely
(!ArcCW.ConVars["clicktocycle"]:GetBool() and (self:GetCurrentFiremode().Mode == 2 or !owner:KeyDown(IN_ATTACK))
or ArcCW.ConVars["clicktocycle"]:GetBool() and (self:GetCurrentFiremode().Mode == 2 or owner:KeyPressed(IN_ATTACK))) then
local anim = self:SelectAnimation("cycle")
anim = self:GetBuff_Hook("Hook_SelectCycleAnimation", anim) or anim
local mult = self:GetBuff_Mult("Mult_CycleTime")
local p = self:PlayAnimation(anim, mult, true, 0, true)
if p then
self:SetNeedCycle(false)
self:SetPriorityAnim(CurTime() + self:GetAnimKeyTime(anim, true) * mult)
end
end
if self:GetGrenadePrimed() and !(owner:KeyDown(IN_ATTACK) or owner:KeyDown(IN_ATTACK2)) and (!game.SinglePlayer() or SERVER) then
self:Throw()
end
if self:GetGrenadePrimed() and self.GrenadePrimeTime > 0 and self.isCooked then
local heldtime = (CurTime() - self.GrenadePrimeTime)
local ft = self:GetBuff_Override("Override_FuseTime") or self.FuseTime
if ft and (heldtime >= ft) and (!game.SinglePlayer() or SERVER) then
self:Throw()
end
end
if IsFirstTimePredicted() and self:GetNextPrimaryFire() < CurTime() and owner:KeyReleased(IN_USE) then
if self:InBipod() then
self:ExitBipod()
else
self:EnterBipod()
end
end
if ((game.SinglePlayer() and SERVER) or (!game.SinglePlayer() and true)) and self:GetBuff_Override("Override_TriggerDelay", self.TriggerDelay) then
if owner:KeyReleased(IN_ATTACK) and self:GetBuff_Override("Override_TriggerCharge", self.TriggerCharge) and self:GetTriggerDelta(true) >= 1 then
self:PrimaryAttack()
else
self:DoTriggerDelay()
end
end
if self:GetCurrentFiremode().RunawayBurst then
if self:GetBurstCount() > 0 and ((game.SinglePlayer() and SERVER) or (!game.SinglePlayer() and true)) then
self:PrimaryAttack()
end
if self:Clip1() < self:GetBuff("AmmoPerShot") or self:GetBurstCount() == self:GetBurstLength() then
self:SetBurstCount(0)
if !self:GetCurrentFiremode().AutoBurst then
self.Primary.Automatic = false
end
end
end
if owner:KeyReleased(IN_ATTACK) then
if !self:GetCurrentFiremode().RunawayBurst then
self:SetBurstCount(0)
self.LastTriggerTime = -1 -- Cannot fire again until trigger released
self.LastTriggerDuration = 0
end
if self:GetCurrentFiremode().Mode < 0 and !self:GetCurrentFiremode().RunawayBurst then
local postburst = self:GetCurrentFiremode().PostBurstDelay or 0
if (CurTime() + postburst) > self:GetWeaponOpDelay() then
--self:SetNextPrimaryFire(CurTime() + postburst)
self:SetWeaponOpDelay(CurTime() + postburst * self:GetBuff_Mult("Mult_PostBurstDelay") + self:GetBuff_Add("Add_PostBurstDelay"))
end
end
end
if owner and owner:GetInfoNum("arccw_automaticreload", 0) == 1 and self:Clip1() == 0 and !self:GetReloading() and CurTime() > self:GetNextPrimaryFire() + 0.2 then
self:Reload()
end
if (!(self:GetBuff_Override("Override_ReloadInSights") or self.ReloadInSights) and (self:GetReloading() or owner:KeyDown(IN_RELOAD))) then
if !(self:GetBuff_Override("Override_ReloadInSights") or self.ReloadInSights) and self:GetReloading() then
self:ExitSights()
end
end
if self:GetBuff_Hook("Hook_ShouldNotSight") and (self.Sighted or self:GetState() == ArcCW.STATE_SIGHTS) then
self:ExitSights()
elseif self:GetHolster_Time() > 0 then
self:ExitSights()
else
-- no it really doesn't, past me
local sighted = self:GetState() == ArcCW.STATE_SIGHTS
local toggle = owner:GetInfoNum("arccw_toggleads", 0) >= 1
local suitzoom = owner:KeyDown(IN_ZOOM)
local sp_cl = game.SinglePlayer() and CLIENT
-- if in singleplayer, client realm should be completely ignored
if toggle and !sp_cl then
if owner:KeyPressed(IN_ATTACK2) then
if sighted then
self:ExitSights()
elseif !suitzoom then
self:EnterSights()
end
elseif suitzoom and sighted then
self:ExitSights()
end
elseif !toggle then
if (owner:KeyDown(IN_ATTACK2) and !suitzoom) and !sighted then
self:EnterSights()
elseif (!owner:KeyDown(IN_ATTACK2) or suitzoom) and sighted then
self:ExitSights()
end
end
end
if (!game.SinglePlayer() and IsFirstTimePredicted()) or (game.SinglePlayer() and true) then
if self:InSprint() and (self:GetState() != ArcCW.STATE_SPRINT) then
self:EnterSprint()
elseif !self:InSprint() and (self:GetState() == ArcCW.STATE_SPRINT) then
self:ExitSprint()
end
end
if game.SinglePlayer() or IsFirstTimePredicted() then
self:SetSightDelta(math.Approach(self:GetSightDelta(), self:GetState() == ArcCW.STATE_SIGHTS and 0 or 1, FrameTime() / self:GetSightTime()))
self:SetSprintDelta(math.Approach(self:GetSprintDelta(), self:GetState() == ArcCW.STATE_SPRINT and 1 or 0, FrameTime() / self:GetSprintTime()))
end
if CLIENT and (game.SinglePlayer() or IsFirstTimePredicted()) then
self:ProcessRecoil()
end
if CLIENT and IsValid(vm) then
for i = 1, vm:GetBoneCount() do
vm:ManipulateBoneScale(i, vec1)
end
for i, k in pairs(self:GetBuff_Override("Override_CaseBones", self.CaseBones) or {}) do
if !isnumber(i) then continue end
for _, b in pairs(istable(k) and k or {k}) do
local bone = vm:LookupBone(b)
if !bone then continue end
if self:GetVisualClip() >= i then
vm:ManipulateBoneScale(bone, vec1)
else
vm:ManipulateBoneScale(bone, vec0)
end
end
end
for i, k in pairs(self:GetBuff_Override("Override_BulletBones", self.BulletBones) or {}) do
if !isnumber(i) then continue end
for _, b in pairs(istable(k) and k or {k}) do
local bone = vm:LookupBone(b)
if !bone then continue end
if self:GetVisualBullets() >= i then
vm:ManipulateBoneScale(bone, vec1)
else
vm:ManipulateBoneScale(bone, vec0)
end
end
end
for i, k in pairs(self:GetBuff_Override("Override_StripperClipBones", self.StripperClipBones) or {}) do
if !isnumber(i) then continue end
for _, b in pairs(istable(k) and k or {k}) do
local bone = vm:LookupBone(b)
if !bone then continue end
if self:GetVisualLoadAmount() >= i then
vm:ManipulateBoneScale(bone, vec1)
else
vm:ManipulateBoneScale(bone, vec0)
end
end
end
end
self:DoHeat()
self:ThinkFreeAim()
-- if CLIENT then
-- if !IsValid(ArcCW.InvHUD) then
-- gui.EnableScreenClicker(false)
-- end
-- if self:GetState() != ArcCW.STATE_CUSTOMIZE then
-- self:CloseCustomizeHUD()
-- else
-- self:OpenCustomizeHUD()
-- end
-- end
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
local atttbl = ArcCW.AttachmentTable[k.Installed]
if atttbl.DamagePerSecond then
local dmg = atttbl.DamagePerSecond * FrameTime()
self:DamageAttachment(i, dmg)
end
end
if CLIENT then
self:DoOurViewPunch()
end
if self.Throwing and self:Clip1() == 0 and self:Ammo1() > 0 then
self:SetClip1(1)
owner:SetAmmo(self:Ammo1() - 1, self.Primary.Ammo)
end
-- self:RefreshBGs()
if self:GetMagUpIn() != 0 and CurTime() > self:GetMagUpIn() then
self:ReloadTimed()
self:SetMagUpIn( 0 )
end
if self:HasBottomlessClip() and self:Clip1() != ArcCW.BottomlessMagicNumber then
self:Unload()
self:SetClip1(ArcCW.BottomlessMagicNumber)
elseif !self:HasBottomlessClip() and self:Clip1() == ArcCW.BottomlessMagicNumber then
self:SetClip1(0)
end
-- Performing traces in rendering contexts seem to cause flickering with c_hands that have QC attachments(?)
-- Since we need to run the trace every tick anyways, do it here instead
if CLIENT then
self:BarrelHitWall()
end
self:GetBuff_Hook("Hook_Think")
-- Running this only serverside in SP breaks animation processing and causes CheckpointAnimation to !reset.
--if SERVER or !game.SinglePlayer() then
self:ProcessTimers()
--end
-- Only reset to idle if we don't need cycle. empty idle animation usually doesn't play nice
if self:GetNextIdle() != 0 and self:GetNextIdle() <= CurTime() and !self:GetNeedCycle()
and self:GetHolster_Time() == 0 and self:GetShotgunReloading() == 0 then
self:SetNextIdle(0)
self:PlayIdleAnimation(true)
end
if self:GetUBGLDebounce() and !self:GetOwner():KeyDown(IN_RELOAD) then
self:SetUBGLDebounce( false )
end
end
local lst = SysTime()
function SWEP:ProcessRecoil()
local owner = self:GetOwner()
local ft = (SysTime() - (lst or SysTime())) * GetConVar("host_timescale"):GetFloat()
local newang = owner:EyeAngles()
-- local r = self.RecoilAmount -- self:GetNWFloat("recoil", 0)
-- local rs = self.RecoilAmountSide -- self:GetNWFloat("recoilside", 0)
local ra = Angle(ang0)
ra = ra + (self:GetBuff_Override("Override_RecoilDirection", self.RecoilDirection) * self.RecoilAmount * 0.5)
ra = ra + (self:GetBuff_Override("Override_RecoilDirectionSide", self.RecoilDirectionSide) * self.RecoilAmountSide * 0.5)
newang = newang - ra
local rpb = self.RecoilPunchBack
local rps = self.RecoilPunchSide
local rpu = self.RecoilPunchUp
if rpb != 0 then
self.RecoilPunchBack = math.Approach(rpb, 0, ft * rpb * 10)
end
if rps != 0 then
self.RecoilPunchSide = math.Approach(rps, 0, ft * rps * 5)
end
if rpu != 0 then
self.RecoilPunchUp = math.Approach(rpu, 0, ft * rpu * 5)
end
lst = SysTime()
end
function SWEP:InSprint()
local owner = self:GetOwner()
local sm = self.SpeedMult * self:GetBuff_Mult("Mult_SpeedMult") * self:GetBuff_Mult("Mult_MoveSpeed")
sm = math.Clamp(sm, 0, 1)
local sprintspeed = owner:GetRunSpeed() * sm
local walkspeed = owner:GetWalkSpeed() * sm
local curspeed = owner:GetVelocity():Length()
if TTT2 and owner.isSprinting == true then
return (owner.sprintProgress or 0) > 0 and owner:KeyDown(IN_SPEED) and !owner:Crouching() and curspeed > walkspeed and owner:OnGround()
end
if !owner:KeyDown(IN_SPEED) or !owner:KeyDown(IN_FORWARD+IN_MOVELEFT+IN_MOVERIGHT+IN_BACK) then return false end
if !owner:OnGround() then return false end
if owner:Crouching() then return false end
if curspeed < Lerp(0.5, walkspeed, sprintspeed) then
-- provide some grace time so changing directions won't immediately exit sprint
self.LastExitSprintCheck = self.LastExitSprintCheck or CurTime()
if self.LastExitSprintCheck < CurTime() - 0.25 then
return false
end
else
self.LastExitSprintCheck = nil
end
return true
end
function SWEP:IsTriggerHeld()
return self:GetOwner():KeyDown(IN_ATTACK) and (self:CanShootWhileSprint() or (!self.Sprinted or self:GetState() != ArcCW.STATE_SPRINT)) and (self:GetHolster_Time() < CurTime()) and !self:GetPriorityAnim()
end
SWEP.LastTriggerTime = 0
SWEP.LastTriggerDuration = 0
function SWEP:GetTriggerDelta(noheldcheck)
if self.LastTriggerTime <= 0 or (!noheldcheck and !self:IsTriggerHeld()) then return 0 end
return math.Clamp((CurTime() - self.LastTriggerTime) / self.LastTriggerDuration, 0, 1)
end
function SWEP:DoTriggerDelay()
local shouldHold = self:IsTriggerHeld()
local reserve = self:HasBottomlessClip() and self:Ammo1() or self:Clip1()
if self.LastTriggerTime == -1 or (!self.TriggerPullWhenEmpty and (reserve < self:GetBuff("AmmoPerShot"))) and self:GetNextPrimaryFire() < CurTime() then
if !shouldHold then
self.LastTriggerTime = 0 -- Good to fire again
self.LastTriggerDuration = 0
end
return
end
if self:GetBurstCount() > 0 and self:GetCurrentFiremode().Mode == 1 then
self.LastTriggerTime = -1 -- Cannot fire again until trigger released
self.LastTriggerDuration = 0
elseif self:GetNextPrimaryFire() < CurTime() and self.LastTriggerTime > 0 and !shouldHold then
-- Attack key is released. Stop the animation and clear progress
local anim = self:SelectAnimation("untrigger")
if anim then
self:PlayAnimation(anim, self:GetBuff_Mult("Mult_TriggerDelayTime"), true, 0)
end
self.LastTriggerTime = 0
self.LastTriggerDuration = 0
self:GetBuff_Hook("Hook_OnTriggerRelease")
elseif self:GetNextPrimaryFire() < CurTime() and self.LastTriggerTime == 0 and shouldHold then
-- We haven't played the animation yet. Pull it!
local anim = self:SelectAnimation("trigger")
self:PlayAnimation(anim, self:GetBuff_Mult("Mult_TriggerDelayTime"), true, 0, nil, nil, true) -- need to overwrite sprint up
self.LastTriggerTime = CurTime()
self.LastTriggerDuration = self:GetAnimKeyTime(anim, true) * self:GetBuff_Mult("Mult_TriggerDelayTime")
self:GetBuff_Hook("Hook_OnTriggerHeld")
end
end

View File

@@ -0,0 +1,178 @@
--[[
| 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 tbl = table
local tbl_ins = tbl.insert
local tick = 0
function SWEP:InitTimers()
self.ActiveTimers = {} -- { { time, id, func } }
end
function SWEP:SetTimer(time, callback, id)
if !IsFirstTimePredicted() then return end
tbl_ins(self.ActiveTimers, { time + CurTime(), id or "", callback })
end
function SWEP:TimerExists(id)
for _, v in pairs(self.ActiveTimers) do
if v[2] == id then return true end
end
return false
end
function SWEP:KillTimer(id)
local keeptimers = {}
for _, v in pairs(self.ActiveTimers) do
if v[2] != id then tbl_ins(keeptimers, v) end
end
self.ActiveTimers = keeptimers
end
function SWEP:KillTimers()
self.ActiveTimers = {}
end
function SWEP:ProcessTimers()
local keeptimers, UCT = {}, CurTime()
if CLIENT and UCT == tick then return end
if !self.ActiveTimers then self:InitTimers() end
for _, v in pairs(self.ActiveTimers) do
if v[1] <= UCT then v[3]() end
end
for _, v in pairs(self.ActiveTimers) do
if v[1] > UCT then tbl_ins(keeptimers, v) end
end
self.ActiveTimers = keeptimers
end
local function DoShell(wep, data)
if !(IsValid(wep) and IsValid(wep:GetOwner())) then return end
local att = data.att or wep:GetBuff_Override("Override_CaseEffectAttachment") or wep.CaseEffectAttachment or 2
if !att then return end
local getatt = wep:GetAttachment(att)
if !getatt then return end
local pos, ang = getatt.Pos, getatt.Ang
local ed = EffectData()
ed:SetOrigin(pos)
ed:SetAngles(ang)
ed:SetAttachment(att)
ed:SetScale(1)
ed:SetEntity(wep)
ed:SetNormal(ang:Forward())
ed:SetMagnitude(data.mag or 100)
util.Effect(data.e, ed)
end
function SWEP:PlaySoundTable(soundtable, mult, start, key)
--if CLIENT and game.SinglePlayer() then return end
local owner = self:GetOwner()
start = start or 0
mult = 1 / (mult or 1)
for _, v in pairs(soundtable) do
if table.IsEmpty(v) then continue end
local ttime
if v.t then
ttime = (v.t * mult) - start
else
continue
end
if ttime < 0 then continue end
if !(IsValid(self) and IsValid(owner)) then continue end
local jhon = CurTime() + ttime
--[[if game.SinglePlayer() then
if SERVER then
net.Start("arccw_networksound")
v.ntttime = ttime
net.WriteTable(v)
net.WriteEntity(self)
net.Send(owner)
end
end]]
-- i may go fucking insane
if !self.EventTable[1] then self.EventTable[1] = {} end
for i, de in ipairs(self.EventTable) do
if de[jhon] then
if !self.EventTable[i + 1] then
--[[print(CurTime(), "Occupier at " .. i .. ", creating " .. i+1)]]
self.EventTable[i + 1] = {}
continue
end
else
self.EventTable[i][jhon] = table.Copy(v)
self.EventTable[i][jhon].StartTime = CurTime()
self.EventTable[i][jhon].AnimKey = key
-- print(CurTime(), "Clean at " .. i)
end
end
end
end
function SWEP:PlayEvent(v)
if !v or !istable(v) then error("no event to play") end
v = self:GetBuff_Hook("Hook_PrePlayEvent", v) or v
if v.e and IsFirstTimePredicted() then
DoShell(self, v)
end
if v.s then
if v.s_km then
self:StopSound(v.s)
end
self:MyEmitSound(v.s, v.l, v.p, v.v, v.c or CHAN_AUTO)
end
if v.bg then
self:SetBodygroupTr(v.ind or 0, v.bg)
end
if v.pp then
local vm = self:GetOwner():GetViewModel()
vm:SetPoseParameter(pp, ppv)
end
v = self:GetBuff_Hook("Hook_PostPlayEvent", v) or v
end
if CLIENT then
net.Receive("arccw_networksound", function(len)
local v = net.ReadTable()
local wep = net.ReadEntity()
wep.EventTable[CurTime() + v.ntttime] = v
end)
end

View File

@@ -0,0 +1,153 @@
--[[
| 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/
--]]
function SWEP:OnRestore()
end
function SWEP:GetHeadshotMultiplier(victim, dmginfo)
return 2.5 -- Hey hey hey, don't forget about me!!!
end
function SWEP:IsEquipment()
return WEPS.IsEquipment(self)
end
SWEP.IsSilent = false
-- The OnDrop() hook is useless for this as it happens AFTER the drop. OwnerChange
-- does not occur when a drop happens for some reason. Hence this thing.
function SWEP:PreDrop()
if self.Throwing then
if self:GetGrenadePrimed() then
self:Throw()
end
else
if SERVER and IsValid(self:GetOwner()) and self.Primary.Ammo != "none" then
local ammo = self:Ammo1()
-- Do not drop ammo if we have another gun that uses this type
for _, w in ipairs(self:GetOwner():GetWeapons()) do
if IsValid(w) and w != self and w:GetPrimaryAmmoType() == self:GetPrimaryAmmoType() then
ammo = 0
end
end
self.StoredAmmo = ammo
if ammo > 0 then
self:GetOwner():RemoveAmmo(ammo, self.Primary.Ammo)
end
end
end
net.Start("arccw_togglecustomize")
net.WriteBool(false)
net.Send(self:GetOwner())
self:ToggleCustomizeHUD(false)
end
function SWEP:DampenDrop()
-- For some reason gmod drops guns on death at a speed of 400 units, which
-- catapults them away from the body. Here we want people to actually be able
-- to find a given corpse's weapon, so we override the velocity here and call
-- this when dropping guns on death.
local phys = self:GetPhysicsObject()
if IsValid(phys) then
phys:SetVelocityInstantaneous(Vector(0,0,-75) + phys:GetVelocity() * 0.001)
phys:AddAngleVelocity(phys:GetAngleVelocity() * -0.99)
end
end
SWEP.StoredAmmo = 0
-- Picked up by player. Transfer of stored ammo and such.
function SWEP:Equip(newowner)
if SERVER then
if self:IsOnFire() then
self:Extinguish()
end
self.fingerprints = self.fingerprints or {}
if !table.HasValue(self.fingerprints, newowner) then
table.insert(self.fingerprints, newowner)
end
end
if SERVER and IsValid(newowner) and self.StoredAmmo > 0 and self.Primary.Ammo != "none" then
local ammo = newowner:GetAmmoCount(self.Primary.Ammo)
local given = math.min(self.StoredAmmo, self.Primary.ClipMax - ammo)
newowner:GiveAmmo( given, self.Primary.Ammo)
self.StoredAmmo = 0
end
end
function SWEP:WasBought(buyer)
if self.TTT_DoNotAttachOnBuy then return end
for i, k in pairs(self.Attachments) do
k.RandomChance = 100
end
-- if ArcCW.ConVars["ttt_atts"]:GetBool() then
-- self:NPC_SetupAttachments()
-- end
end
function SWEP:TTT_PostAttachments()
self.IsSilent = self:GetBuff_Override("Silencer")
if !self.IsSilent then
self.IsSilent = true
end
end
function SWEP:TTT_Init()
if engine.ActiveGamemode() != "terrortown" then return end
if SERVER then
self.fingerprints = {}
end
if self.Throwing then
self.Primary.ClipMax = 0
end
if ArcCW.ConVars["ttt_atts"]:GetBool() then
if SERVER then
self:NPC_SetupAttachments()
end
elseif !IsValid(self:GetOwner()) then
-- If attachments aren't randomized, client will not need to ask for att info.
self.CertainAboutAtts = true
end
if self.ForgetDefaultBehavior then return end
self.Primary.ClipMax = ArcCW.TTTAmmoToClipMax[self.Primary.Ammo] or self.RegularClipSize * 2 or self.Primary.ClipSize * 2
-- This will overwrite mag reducers, so give it a bit of time
timer.Simple(0.1, function()
if !IsValid(self) then return end
self:SetClip1(self:GetCapacity() or self.RegularClipSize or self.Primary.ClipSize)
self.Primary.DefaultClip = self.ForceDefaultAmmo or self.ForceDefaultClip or self:GetCapacity()
end)
if self.Throwing and self.Primary.Ammo and !self.ForceDefaultClip then
self.Primary.Ammo = "none"
self.Primary.DefaultClip = 0
self:SetClip1(-1)
self.Singleton = true
end
end
--- TTT2 uses this to populate custom convars in the equip menu
function SWEP:AddToSettingsMenu(parent)
end

View File

@@ -0,0 +1,173 @@
--[[
| 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/
--]]
function SWEP:SelectUBGL()
if !self:GetBuff_Override("UBGL") then return end
if self:GetReloading() then return end
if self:GetNextPrimaryFire() > CurTime() then return end
if self:GetNextSecondaryFire() > CurTime() then return end
if self:GetUBGLDebounce() then return end
self:SetUBGLDebounce( true )
self:SetInUBGL(true)
self:SetFireMode(1)
if CLIENT and (game.SinglePlayer() or (!game.SinglePlayer() and IsFirstTimePredicted())) then
-- if !ArcCW:ShouldDrawHUDElement("CHudAmmo") then
-- self:GetOwner():ChatPrint("Selected " .. self:GetBuff_Override("UBGL_PrintName") or "UBGL")
-- end
if !self:GetLHIKAnim() then
self:DoLHIKAnimation("enter")
end
self:MyEmitSound( self:GetBuff_Override("SelectUBGLSound") or self.SelectUBGLSound )
end
if self:GetBuff_Override("UBGL_BaseAnims") and self.Animations.enter_ubgl_empty and self:Clip2() == 0 then
self:PlayAnimation("enter_ubgl_empty", 1, true)
self:SetNextSecondaryFire(CurTime() + self:GetAnimKeyTime("enter_ubgl_empty"))
elseif self:GetBuff_Override("UBGL_BaseAnims") and self.Animations.enter_ubgl then
self:PlayAnimation("enter_ubgl", 1, true)
self:SetNextSecondaryFire(CurTime() + self:GetAnimKeyTime("enter_ubgl"))
else
self:PlayAnimationEZ("idle", 1, false)
self:SetNextSecondaryFire(CurTime() + 0.1)
end
self:GetBuff_Hook("Hook_OnSelectUBGL")
end
function SWEP:DeselectUBGL()
if !self:GetInUBGL() then return end
if self:GetReloading() then return end
if self:GetNextPrimaryFire() > CurTime() then return end
if self:GetNextSecondaryFire() > CurTime() then return end
if self:GetUBGLDebounce() then return end
self:SetUBGLDebounce( true )
self:SetInUBGL(false)
if CLIENT and (game.SinglePlayer() or (!game.SinglePlayer() and IsFirstTimePredicted())) then
-- if !ArcCW:ShouldDrawHUDElement("CHudAmmo") then
-- self:GetOwner():ChatPrint("Deselected " .. self:GetBuff_Override("UBGL_PrintName") or "UBGL")
-- end
if !self:GetLHIKAnim() and bong then
self:DoLHIKAnimation("exit")
end
self:MyEmitSound( self:GetBuff_Override("ExitUBGLSound") or self.ExitUBGLSound )
end
if self:GetBuff_Override("UBGL_BaseAnims") and self.Animations.exit_ubgl_empty and self:Clip2() == 0 then
self:PlayAnimation("exit_ubgl_empty", 1, true)
elseif self:GetBuff_Override("UBGL_BaseAnims") and self.Animations.exit_ubgl then
self:PlayAnimation("exit_ubgl", 1, true)
else
self:PlayAnimationEZ("idle", 1, false)
self:SetNextSecondaryFire(CurTime() + 0.1)
end
self:GetBuff_Hook("Hook_OnDeselectUBGL")
end
function SWEP:RecoilUBGL()
local single = game.SinglePlayer()
if !single and !IsFirstTimePredicted() then return end
if single and self:GetOwner():IsValid() and SERVER then self:CallOnClient("RecoilUBGL") end
local amt = self:GetBuff_Override("UBGL_Recoil")
local amtside = self:GetBuff_Override("UBGL_RecoilSide") or (self:GetBuff_Override("UBGL_Recoil") * 0.5)
local amtrise = self:GetBuff_Override("UBGL_RecoilRise") or 1
local r = math.Rand(-1, 1)
local ru = math.Rand(0.75, 1.25)
local m = 1 * amt
local rs = 1 * amtside
local vsm = 1
local vpa = Angle(0, 0, 0)
vpa = vpa + (Angle(1, 0, 0) * amt * m * vsm)
vpa = vpa + (Angle(0, 1, 0) * r * amtside * m * vsm)
if CLIENT then
self:OurViewPunch(vpa)
end
if CLIENT or game.SinglePlayer() then
self.RecoilAmount = self.RecoilAmount + (amt * m)
self.RecoilAmountSide = self.RecoilAmountSide + (r * amtside * m * rs)
self.RecoilPunchBack = amt * 2.5 * m
if self.MaxRecoilBlowback > 0 then
self.RecoilPunchBack = math.Clamp(self.RecoilPunchBack, 0, self.MaxRecoilBlowback)
end
self.RecoilPunchSide = r * rs * m * 0.1 * vsm
self.RecoilPunchUp = math.Clamp(ru * amt * m * 0.6 * vsm * amtrise, 0, 0.1)
end
end
function SWEP:ShootUBGL()
if self:GetNextSecondaryFire() > CurTime() then return end
if self:GetState() == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() then return false end
self.Primary.Automatic = self:GetBuff_Override("UBGL_Automatic")
local ubglammo = self:GetBuff_Override("UBGL_Ammo")
if self:Clip2() <= 0 and self:GetOwner():GetAmmoCount(ubglammo) <= 0 then
self:DeselectUBGL()
return
end
if self:Clip2() <= 0 then
return
end
self:RecoilUBGL()
local func, slot = self:GetBuff_Override("UBGL_Fire")
if func then
func(self, self.Attachments[slot].VElement)
end
self:SetNextSecondaryFire(CurTime() + (60 / self:GetBuff_Override("UBGL_RPM")))
end
function SWEP:ReloadUBGL()
if self:GetNextSecondaryFire() > CurTime() then return end
local reloadfunc, slot = self:GetBuff_Override("UBGL_Reload")
if reloadfunc then
reloadfunc(self, self.Attachments[slot].VElement)
end
end
if SERVER then
function SWEP:DoLHIKAnimation(key, time)
if game.SinglePlayer() then
net.Start("arccw_sp_lhikanim")
net.WriteString(key)
net.WriteFloat(time or -1)
net.Send(self:GetOwner())
end
end
end

View File

@@ -0,0 +1,29 @@
--[[
| 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/
--]]
function SWEP:TableRandom(table)
return table[math.random(#table)]
end
function SWEP:MyEmitSound(fsound, level, pitch, vol, chan, useWorld)
if !fsound then return end
fsound = self:GetBuff_Hook("Hook_TranslateSound", fsound) or fsound
if istable(fsound) then fsound = self:TableRandom(fsound) end
if fsound and fsound != "" then
if useWorld then
sound.Play(fsound, self:GetOwner():GetShootPos(), level, pitch, vol)
else
self:EmitSound(fsound, level, pitch, vol, chan or CHAN_AUTO)
end
end
end

File diff suppressed because it is too large Load Diff

View 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

View File

@@ -0,0 +1,145 @@
--[[
| 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/
--]]
SWEP.Shields = {}
function SWEP:SetupShields()
self:KillShields()
for i, k in pairs(self.Attachments) do
if !k then continue end
if !k.Installed then continue end
local atttbl = ArcCW.AttachmentTable[k.Installed]
if atttbl.ModelIsShield then
for _, e in pairs(self:GetActiveElements()) do
local ele = self.AttachmentElements[e]
if !ele then continue end
if ((ele.AttPosMods or {})[i] or {}).wpos then
wmelemod = ele.AttPosMods[i].wpos
end
if ((ele.AttPosMods or {})[i] or {}).slide then
slidemod = ele.AttPosMods[i].slide
end
-- Refer to sh_model Line 837
if ((ele.AttPosMods or {})[i] or {}).SlideAmount then
slidemod = ele.AttPosMods[i].SlideAmount
end
end
local bonename = atttbl.ShieldBone or "ValveBiped.Bip01_R_Hand"
local boneindex = self:GetOwner():LookupBone(bonename)
local bpos, bang = self:GetOwner():GetBonePosition(boneindex)
local delta = k.SlidePos or 0.5
local offset = wmelemod or k.Offset.wpos or Vector(0, 0, 0)
if k.SlideAmount then
offset = LerpVector(delta, (slidemod or k.SlideAmount).wmin, (slidemod or k.SlideAmount).wmax)
end
local pos = offset + (atttbl.ShieldCorrectPos or Vector(0, 0, 0))
local ang = k.Offset.wang or Angle(0, 0, 0)
local apos = LocalToWorld(pos, ang, bpos, bang)
local shield = ents.Create("physics_prop")
if !shield then
print("!!! Unable to spawn shield!")
continue
end
shield.mmRHAe = atttbl.ShieldResistance
shield:SetModel( atttbl.Model )
shield:FollowBone( self:GetOwner(), boneindex )
shield:SetPos( apos )
shield:SetAngles( self:GetOwner():GetAngles() + ang + (atttbl.ShieldCorrectAng or Angle(0, 0, 0)) )
shield:SetCollisionGroup( COLLISION_GROUP_WORLD )
shield.Weapon = self
if GetConVar("developer"):GetBool() then
shield:SetColor( Color(0, 0, 0, 255) )
else
shield:SetColor( Color(0, 0, 0, 0) )
shield:SetRenderMode(RENDERMODE_NONE)
end
table.insert(self.Shields, shield)
shield:Spawn()
shield:Activate()
table.insert(ArcCW.ShieldPropPile, {Weapon = self, Model = shield})
local phys = shield:GetPhysicsObject()
phys:SetMass(1000)
end
end
for i, k in pairs(self.ShieldProps or {}) do
if !k then continue end
if !k.Model then continue end
local bonename = k.Bone or "ValveBiped.Bip01_R_Hand"
local boneindex = self:GetOwner():LookupBone(bonename)
local bpos, bang = self:GetOwner():GetBonePosition(boneindex)
local pos = k.Pos or Vector(0, 0, 0)
local ang = k.Ang or Angle(0, 0, 0)
local apos = LocalToWorld(pos, ang, bpos, bang)
local shield = ents.Create("physics_prop")
if !shield then
print("!!! Unable to spawn shield!")
continue
end
shield.mmRHAe = k.Resistance
shield:SetModel( k.Model )
shield:FollowBone( self:GetOwner(), boneindex )
shield:SetPos( apos )
shield:SetAngles( self:GetOwner():GetAngles() + ang )
shield:SetCollisionGroup( COLLISION_GROUP_WORLD )
shield.Weapon = self
if GetConVar("developer"):GetBool() then
shield:SetColor( Color(0, 0, 0, 255) )
else
shield:SetColor( Color(0, 0, 0, 0) )
shield:SetRenderMode(RENDERMODE_NONE)
end
table.insert(self.Shields, shield)
shield:Spawn()
shield:Activate()
table.insert(ArcCW.ShieldPropPile, {Weapon = self, Model = shield})
local phys = shield:GetPhysicsObject()
phys:SetMass(1000)
end
end
function SWEP:KillShields()
for i, k in pairs(self.Shields) do
SafeRemoveEntity(k)
end
end