forked from HaodongMo/ArcCW
Initial commit
This commit is contained in:
commit
724dde6df3
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
128
lua/arccw/client/cl_autostats.lua
Normal file
128
lua/arccw/client/cl_autostats.lua
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
-- ["buff"] = {"desc", bool ismult, bool lowerbetter}
|
||||||
|
ArcCW.AutoStats = {
|
||||||
|
["Mult_BipodRecoil"] = {"Recoil in bipod", true, true},
|
||||||
|
["Mult_BipodDispersion"] = {"Dispersion in bipod", true, true},
|
||||||
|
["Mult_Damage"] = {"Close range damage", true, false},
|
||||||
|
["Mult_DamageMin"] = {"Long range damage", true, false},
|
||||||
|
["Mult_Range"] = {"Range", true, false},
|
||||||
|
["Mult_Penetration"] = {"Penetration", true, false},
|
||||||
|
["Mult_MuzzleVelocity"] = {"Muzzle velocity", true, false},
|
||||||
|
["Mult_MeleeTime"] = {"Melee attack time", true, true},
|
||||||
|
["Mult_MeleeDamage"] = {"Melee damage", true, false},
|
||||||
|
["Add_MeleeRange"] = {"Melee range", false, false},
|
||||||
|
["Mult_Recoil"] = {"Recoil", true, true},
|
||||||
|
["Mult_RecoilSide"] = {"Horizontal recoil", true, true},
|
||||||
|
["Mult_RPM"] = {"Fire rate", true, false},
|
||||||
|
["Mult_AccuracyMOA"] = {"Imprecision", true, true},
|
||||||
|
["Mult_HipDispersion"] = {"Hip fire spread", true, true},
|
||||||
|
["Mult_SightsDispersion"] = {"Sighted spread", true, true},
|
||||||
|
["Mult_MoveDispersion"] = {"Moving spread", true, true},
|
||||||
|
["Mult_ShootVol"] = {"Weapon volume", true, true},
|
||||||
|
["Mult_SpeedMult"] = {"Movement speed", true, false},
|
||||||
|
["Mult_MoveSpeed"] = {"Movement speed", true, false},
|
||||||
|
["Mult_SightedSpeedMult"] = {"Sighted strafe speed", true, false},
|
||||||
|
["Mult_SightedMoveSpeed"] = {"Sighted strafe speed", true, false},
|
||||||
|
["Mult_ReloadTime"] = {"Reload time", true, true},
|
||||||
|
["Mult_DrawTime"] = {"Draw time", true, true},
|
||||||
|
["Mult_SightTime"] = {"Sight time", true, true},
|
||||||
|
["Mult_CycleTime"] = {"Cycle time", true, true}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function getsimpleamt(stat)
|
||||||
|
if stat > 1 then
|
||||||
|
if stat >= 2 then
|
||||||
|
return "++++ "
|
||||||
|
elseif stat >= 1.5 then
|
||||||
|
return "+++ "
|
||||||
|
elseif stat >= 1.25 then
|
||||||
|
return "++ "
|
||||||
|
else
|
||||||
|
return "+ "
|
||||||
|
end
|
||||||
|
elseif stat < 1 then
|
||||||
|
if stat <= 0.25 then
|
||||||
|
return "---- "
|
||||||
|
elseif stat <= 0.5 then
|
||||||
|
return "--- "
|
||||||
|
elseif stat <= 0.25 then
|
||||||
|
return "-- "
|
||||||
|
else
|
||||||
|
return "- "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW:GetProsCons(att)
|
||||||
|
local pros = {}
|
||||||
|
local cons = {}
|
||||||
|
|
||||||
|
table.Add(pros, att.Desc_Pros or {})
|
||||||
|
table.Add(cons, att.Desc_Cons or {})
|
||||||
|
|
||||||
|
if !att.AutoStats then
|
||||||
|
return pros, cons
|
||||||
|
end
|
||||||
|
|
||||||
|
local simple = GetConVar("arccw_attinv_simpleproscons"):GetBool()
|
||||||
|
|
||||||
|
for i, k in pairs(att) do
|
||||||
|
if ArcCW.AutoStats[i] then
|
||||||
|
local stat = ArcCW.AutoStats[i]
|
||||||
|
local txt = ""
|
||||||
|
|
||||||
|
if stat[2] then
|
||||||
|
-- mult
|
||||||
|
if k > 1 then
|
||||||
|
if simple then
|
||||||
|
txt = getsimpleamt(k) .. stat[1]
|
||||||
|
else
|
||||||
|
txt = "+" .. tostring((k - 1) * 100) .. "% " .. stat[1]
|
||||||
|
end
|
||||||
|
if stat[3] then
|
||||||
|
table.insert(cons, txt)
|
||||||
|
else
|
||||||
|
table.insert(pros, txt)
|
||||||
|
end
|
||||||
|
elseif k < 1 then
|
||||||
|
if simple then
|
||||||
|
txt = getsimpleamt(k) .. stat[1]
|
||||||
|
else
|
||||||
|
txt = "-" .. tostring((1 - k) * 100) .. "% " .. stat[1]
|
||||||
|
end
|
||||||
|
if stat[3] then
|
||||||
|
table.insert(pros, txt)
|
||||||
|
else
|
||||||
|
table.insert(cons, txt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- add
|
||||||
|
if k > 0 then
|
||||||
|
if simple then
|
||||||
|
txt = "+ " .. stat[1]
|
||||||
|
else
|
||||||
|
txt = "+" .. tostring(k) .. " " .. stat[1]
|
||||||
|
end
|
||||||
|
if stat[3] then
|
||||||
|
table.insert(cons, txt)
|
||||||
|
else
|
||||||
|
table.insert(pros, txt)
|
||||||
|
end
|
||||||
|
elseif k < 0 then
|
||||||
|
if simple then
|
||||||
|
txt = "+ " .. stat[1]
|
||||||
|
else
|
||||||
|
txt = "-" .. tostring(-k) .. " " .. stat[1]
|
||||||
|
end
|
||||||
|
if stat[3] then
|
||||||
|
table.insert(pros, txt)
|
||||||
|
else
|
||||||
|
table.insert(cons, txt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return pros, cons
|
||||||
|
end
|
142
lua/arccw/client/cl_binds.lua
Normal file
142
lua/arccw/client/cl_binds.lua
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
ArcCW.KEY_FIREMODE = "+zoom"
|
||||||
|
ArcCW.KEY_FIREMODE_ALT = "arccw_firemode"
|
||||||
|
ArcCW.KEY_ZOOMIN = "invnext"
|
||||||
|
ArcCW.KEY_ZOOMIN_ALT = "arccw_zoom_in"
|
||||||
|
ArcCW.KEY_ZOOMOUT = "invprev"
|
||||||
|
ArcCW.KEY_ZOOMOUT_ALT = "arccw_zoom_out"
|
||||||
|
ArcCW.KEY_TOGGLEINV = "+menu_context"
|
||||||
|
ArcCW.KEY_TOGGLEINV_ALT = "arccw_toggle_inv"
|
||||||
|
ArcCW.KEY_SWITCHSCOPE = "+use"
|
||||||
|
ArcCW.KEY_SWITCHSCOPE_ALT = "arccw_switch_scope"
|
||||||
|
ArcCW.KEY_TOGGLEUBGL_ALT = "arccw_toggle_ubgl"
|
||||||
|
|
||||||
|
local lastpressZ = 0
|
||||||
|
local lastpressE = 0
|
||||||
|
|
||||||
|
function ArcCW:GetBind(bind)
|
||||||
|
if ArcCW[bind] then return ArcCW[bind] end
|
||||||
|
|
||||||
|
return input.LookupBinding(bind)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ArcCW_PlayerBindPress(ply, bind, pressed)
|
||||||
|
if !pressed then return end
|
||||||
|
if !ply:IsValid() then return end
|
||||||
|
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
local block = false
|
||||||
|
|
||||||
|
if bind == ArcCW.KEY_FIREMODE then
|
||||||
|
if wpn:GetBuff_Override("UBGL") then
|
||||||
|
if lastpressZ >= CurTime() - 0.25 then
|
||||||
|
if wpn:GetNWBool("ubgl") then
|
||||||
|
net.Start("arccw_ubgl")
|
||||||
|
net.WriteBool(false)
|
||||||
|
net.SendToServer()
|
||||||
|
|
||||||
|
wpn:DeselectUBGL()
|
||||||
|
else
|
||||||
|
net.Start("arccw_ubgl")
|
||||||
|
net.WriteBool(true)
|
||||||
|
net.SendToServer()
|
||||||
|
|
||||||
|
wpn:SelectUBGL()
|
||||||
|
end
|
||||||
|
lastpressZ = 0
|
||||||
|
|
||||||
|
timer.Remove("ArcCW_doubletapZ")
|
||||||
|
else
|
||||||
|
lastpressZ = CurTime()
|
||||||
|
timer.Create("ArcCW_doubletapZ", 0.25, 1, function()
|
||||||
|
if !IsValid(ply) then return end
|
||||||
|
if !IsValid(wpn) then return end
|
||||||
|
if ply:GetActiveWeapon() != wpn then return end
|
||||||
|
if wpn:GetNWBool("ubgl") then return end
|
||||||
|
|
||||||
|
net.Start("arccw_firemode")
|
||||||
|
net.SendToServer()
|
||||||
|
|
||||||
|
wpn:ChangeFiremode()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
net.Start("arccw_firemode")
|
||||||
|
net.SendToServer()
|
||||||
|
|
||||||
|
wpn:ChangeFiremode()
|
||||||
|
end
|
||||||
|
|
||||||
|
block = true
|
||||||
|
elseif bind == ArcCW.KEY_TOGGLEINV then
|
||||||
|
local p = wpn:GetState() != ArcCW.STATE_CUSTOMIZE
|
||||||
|
wpn:ToggleCustomizeHUD(p)
|
||||||
|
|
||||||
|
net.Start("arccw_togglecustomize")
|
||||||
|
net.WriteBool(p)
|
||||||
|
net.SendToServer()
|
||||||
|
|
||||||
|
block = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if wpn:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
if bind == ArcCW.KEY_ZOOMIN then
|
||||||
|
wpn:Scroll(1)
|
||||||
|
block = true
|
||||||
|
elseif bind == ArcCW.KEY_ZOOMOUT then
|
||||||
|
wpn:Scroll(-1)
|
||||||
|
block = true
|
||||||
|
elseif bind == ArcCW.KEY_SWITCHSCOPE then
|
||||||
|
if lastpressE >= CurTime() - 0.25 then
|
||||||
|
wpn:SwitchActiveSights()
|
||||||
|
lastpressE = 0
|
||||||
|
else
|
||||||
|
lastpressE = CurTime()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if block then return true end
|
||||||
|
end
|
||||||
|
|
||||||
|
hook.Add("PlayerBindPress", "ArcCW_PlayerBindPress", ArcCW_PlayerBindPress)
|
||||||
|
|
||||||
|
-- ArcCW.CaptureKeys = {
|
||||||
|
-- KEY_G
|
||||||
|
-- }
|
||||||
|
-- ArcCW.LastInputs = {}
|
||||||
|
-- ArcCW.Inputs = {}
|
||||||
|
|
||||||
|
-- local function ArcCW_CustomInputs()
|
||||||
|
-- local inputs = {}
|
||||||
|
|
||||||
|
-- for _, i in pairs(ArcCW.CaptureKeys) do
|
||||||
|
-- -- local conv = GetConVar(i)
|
||||||
|
|
||||||
|
-- -- if !conv then continue end
|
||||||
|
-- -- if !IsValid(conv) then continue end
|
||||||
|
|
||||||
|
-- local kc = i
|
||||||
|
|
||||||
|
-- inputs[kc] = input.IsKeyDown(kc)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- ArcCW.LastInputs = ArcCW.Inputs
|
||||||
|
-- ArcCW.Inputs = inputs
|
||||||
|
|
||||||
|
-- if ArcCW:KeyPressed(KEY_G) then
|
||||||
|
-- ArcCW:QuickNade("frag")
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- hook.Add("Think", "ArcCW_CustomInputs", ArcCW_CustomInputs)
|
||||||
|
|
||||||
|
-- function ArcCW:KeyPressed(key)
|
||||||
|
-- if !ArcCW.LastInputs[key] and ArcCW.Inputs[key] then
|
||||||
|
-- return true
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- return false
|
||||||
|
-- end
|
37
lua/arccw/client/cl_convars.lua
Normal file
37
lua/arccw/client/cl_convars.lua
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
-- CreateClientConVar("arccw_quicknade", KEY_G)
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_crosshair", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_attinv_simpleproscons", "0")
|
||||||
|
CreateClientConVar("arccw_attinv_onlyinspect", "0")
|
||||||
|
CreateClientConVar("arccw_attinv_hideunowned", "0")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_cheapscopes", "1")
|
||||||
|
CreateClientConVar("arccw_cheapscopesautoconfig", "0")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_shake", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_muzzleeffects", "1")
|
||||||
|
CreateClientConVar("arccw_shelleffects", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_att_showothers", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_2d3d", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_hud_3dfun", "0")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_scope_r", "255")
|
||||||
|
CreateClientConVar("arccw_scope_g", "0")
|
||||||
|
CreateClientConVar("arccw_scope_b", "0")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_blur", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_glare", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_autosave", "1")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_vm_right", "0")
|
||||||
|
CreateClientConVar("arccw_vm_up", "0")
|
||||||
|
CreateClientConVar("arccw_vm_forward", "0")
|
||||||
|
|
||||||
|
CreateClientConVar("arccw_toggleads", "0", true, true)
|
60
lua/arccw/client/cl_garbage.lua
Normal file
60
lua/arccw/client/cl_garbage.lua
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
ArcCW.CSModels = {
|
||||||
|
-- [entid] = {
|
||||||
|
-- Weapon = NULL,
|
||||||
|
-- WModels = {},
|
||||||
|
-- VModels = {}
|
||||||
|
-- }
|
||||||
|
}
|
||||||
|
ArcCW.CSModelPile = {}
|
||||||
|
-- {
|
||||||
|
-- {Model = NULL, Weapon = NULL}
|
||||||
|
--}
|
||||||
|
|
||||||
|
ArcCW.ReferenceModel = NULL
|
||||||
|
|
||||||
|
local function ArcCW_CollectGarbage()
|
||||||
|
local removed = 0
|
||||||
|
local removedents = {}
|
||||||
|
|
||||||
|
for i, k in pairs(ArcCW.CSModels) do
|
||||||
|
if !IsValid(k.Weapon) then
|
||||||
|
removed = removed + 1
|
||||||
|
table.insert(removedents, i)
|
||||||
|
|
||||||
|
if k.WModels then
|
||||||
|
for _, m in pairs(k.WModels) do
|
||||||
|
SafeRemoveEntity(m.Model)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if k.VModels then
|
||||||
|
for _, m in pairs(k.VModels) do
|
||||||
|
SafeRemoveEntity(m.Model)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, i in pairs(removedents) do
|
||||||
|
ArcCW.CSModels[i] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local newpile = {}
|
||||||
|
|
||||||
|
for i, k in pairs(ArcCW.CSModelPile) do
|
||||||
|
if !IsValid(k.Weapon) then
|
||||||
|
SafeRemoveEntity(k.Model)
|
||||||
|
removed = removed + 1
|
||||||
|
else
|
||||||
|
table.insert(newpile, k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.CSModelPile = newpile
|
||||||
|
|
||||||
|
if GetConVar("developer"):GetBool() and removed > 0 then
|
||||||
|
print("Removed " .. tostring(removed) .. " CSModels")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
timer.Create("ArcCW CSModel Garbage Collector", 5, 0, ArcCW_CollectGarbage)
|
54
lua/arccw/client/cl_glint.lua
Normal file
54
lua/arccw/client/cl_glint.lua
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
local glintmat = Material("effects/blueflare1")
|
||||||
|
|
||||||
|
hook.Add("PostDrawEffects", "ArcCW_ScopeGlint", function()
|
||||||
|
local e = player.GetAll()
|
||||||
|
|
||||||
|
cam.Start3D()
|
||||||
|
|
||||||
|
for _, ply in pairs(e) do
|
||||||
|
if !IsValid(ply) then continue end
|
||||||
|
if !ply:ShouldDrawLocalPlayer() then continue end
|
||||||
|
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
if !IsValid(wpn) then continue end
|
||||||
|
|
||||||
|
if !wpn.ArcCW then continue end
|
||||||
|
|
||||||
|
if !wpn:GetBuff_Override("ScopeGlint") then continue end
|
||||||
|
|
||||||
|
local v1 = (ply:EyePos() - EyePos()):GetNormalized()
|
||||||
|
local v2 = -ply:EyeAngles():Forward()
|
||||||
|
|
||||||
|
local d = v1:Dot(v2)
|
||||||
|
|
||||||
|
d = (d * d * 1.75) - 0.75
|
||||||
|
|
||||||
|
if d < 0 then continue end
|
||||||
|
|
||||||
|
local pos = ply:EyePos() + (ply:EyeAngles():Forward() * 16) + (ply:EyeAngles():Right() * 8)
|
||||||
|
|
||||||
|
local _, scope_i = wpn:GetBuff_Override("ScopeGlint")
|
||||||
|
|
||||||
|
if scope_i then
|
||||||
|
local wme = (wpn.Attachments[scope_i].WElement or {}).Model
|
||||||
|
|
||||||
|
if wme then
|
||||||
|
local att = wme:LookupAttachment("holosight")
|
||||||
|
|
||||||
|
if !att then
|
||||||
|
att = wme:LookupAttachment("scope")
|
||||||
|
end
|
||||||
|
|
||||||
|
if att then
|
||||||
|
pos = wme:GetAttachment(att).Pos
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
render.SetMaterial(glintmat)
|
||||||
|
render.DrawSprite(pos, 64 * d, 64 * d, Color(255, 255, 255))
|
||||||
|
end
|
||||||
|
|
||||||
|
cam.End3D()
|
||||||
|
end)
|
156
lua/arccw/client/cl_hud.lua
Normal file
156
lua/arccw/client/cl_hud.lua
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
local hide = {
|
||||||
|
["CHudHealth"] = true,
|
||||||
|
["CHudBattery"] = true,
|
||||||
|
["CHudAmmo"] = true,
|
||||||
|
["CHudSecondaryAmmo"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.HUDElementConVars = {
|
||||||
|
["CHudHealth"] = CreateClientConVar("arccw_hud_showhealth", "1"),
|
||||||
|
["CHudBattery"] = GetConVar("arccw_hud_showhealth"),
|
||||||
|
["CHudAmmo"] = CreateClientConVar("arccw_hud_showammo", "1"),
|
||||||
|
["CHudSecondaryAmmo"] = GetConVar("arccw_hud_showammo"),
|
||||||
|
}
|
||||||
|
|
||||||
|
hook.Add("HUDShouldDraw", "ArcCW_HideHUD", function(name)
|
||||||
|
if !hide[name] then return end
|
||||||
|
if !LocalPlayer():IsValid() then return end
|
||||||
|
if !LocalPlayer():GetActiveWeapon().ArcCW then return end
|
||||||
|
if ArcCW.PollingDefaultHUDElements then return end
|
||||||
|
if ArcCW.HUDElementConVars[name] and ArcCW.HUDElementConVars[name]:GetBool() == false then return end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end)
|
||||||
|
|
||||||
|
ArcCW.PollingDefaultHUDElements = false
|
||||||
|
|
||||||
|
function ArcCW:ShouldDrawHUDElement(ele)
|
||||||
|
if !GetConVar("cl_drawhud"):GetBool() then return false end
|
||||||
|
|
||||||
|
if ArcCW.HUDElementConVars[ele] and !ArcCW.HUDElementConVars[ele]:GetBool() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.PollingDefaultHUDElements = true
|
||||||
|
|
||||||
|
if hook.Call("HUDShouldDraw", nil, ele) == false then
|
||||||
|
ArcCW.PollingDefaultHUDElements = false
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.PollingDefaultHUDElements = false
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local font = "Bahnschrift"
|
||||||
|
|
||||||
|
local sizes_to_make = {
|
||||||
|
6,
|
||||||
|
8,
|
||||||
|
12,
|
||||||
|
16,
|
||||||
|
20,
|
||||||
|
24,
|
||||||
|
26
|
||||||
|
}
|
||||||
|
|
||||||
|
local unscaled_sizes_to_make = {
|
||||||
|
32,
|
||||||
|
24
|
||||||
|
}
|
||||||
|
|
||||||
|
local function generatefonts()
|
||||||
|
|
||||||
|
for _, i in pairs(sizes_to_make) do
|
||||||
|
|
||||||
|
surface.CreateFont( "ArcCW_" .. tostring(i), {
|
||||||
|
font = font,
|
||||||
|
size = ScreenScale(i),
|
||||||
|
weight = 0,
|
||||||
|
antialias = true,
|
||||||
|
} )
|
||||||
|
|
||||||
|
surface.CreateFont( "ArcCW_" .. tostring(i) .. "_Glow", {
|
||||||
|
font = font,
|
||||||
|
size = ScreenScale(i),
|
||||||
|
weight = 0,
|
||||||
|
antialias = true,
|
||||||
|
blursize = 8,
|
||||||
|
} )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, i in pairs(unscaled_sizes_to_make) do
|
||||||
|
|
||||||
|
surface.CreateFont( "ArcCW_" .. tostring(i) .. "_Unscaled", {
|
||||||
|
font = font,
|
||||||
|
size = i,
|
||||||
|
weight = 0,
|
||||||
|
antialias = true,
|
||||||
|
} )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
generatefonts()
|
||||||
|
|
||||||
|
language.Add("SniperPenetratedRound_ammo", "Sniper Ammo")
|
||||||
|
|
||||||
|
local lastScrH = ScrH()
|
||||||
|
local lastScrW = ScrW()
|
||||||
|
|
||||||
|
hook.Add("HUDPaint", "ArcCW_FontRegen", function()
|
||||||
|
if (lastScrH != ScrH()) or (lastScrW != ScrW()) then
|
||||||
|
generatefonts()
|
||||||
|
end
|
||||||
|
|
||||||
|
lastScrH = ScrH()
|
||||||
|
lastScrW = ScrW()
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- surface.CreateFont( "ArcCW_12", {
|
||||||
|
-- font = font,
|
||||||
|
-- size = ScreenScale(12),
|
||||||
|
-- weight = 0,
|
||||||
|
-- antialias = true,
|
||||||
|
-- } )
|
||||||
|
|
||||||
|
-- surface.CreateFont( "ArcCW_12_Glow", {
|
||||||
|
-- font = font,
|
||||||
|
-- size = ScreenScale(12),
|
||||||
|
-- weight = 0,
|
||||||
|
-- antialias = true,
|
||||||
|
-- blursize = 8,
|
||||||
|
-- } )
|
||||||
|
|
||||||
|
-- surface.CreateFont( "ArcCW_16", {
|
||||||
|
-- font = font,
|
||||||
|
-- size = ScreenScale(16),
|
||||||
|
-- weight = 0,
|
||||||
|
-- antialias = true,
|
||||||
|
-- } )
|
||||||
|
|
||||||
|
-- surface.CreateFont( "ArcCW_16_Glow", {
|
||||||
|
-- font = font,
|
||||||
|
-- size = ScreenScale(16),
|
||||||
|
-- weight = 0,
|
||||||
|
-- antialias = true,
|
||||||
|
-- blursize = 8,
|
||||||
|
-- } )
|
||||||
|
|
||||||
|
-- surface.CreateFont( "ArcCW_26", {
|
||||||
|
-- font = font,
|
||||||
|
-- size = ScreenScale(26),
|
||||||
|
-- weight = 0,
|
||||||
|
-- antialias = true,
|
||||||
|
-- } )
|
||||||
|
|
||||||
|
-- surface.CreateFont( "ArcCW_26_Glow", {
|
||||||
|
-- font = font,
|
||||||
|
-- size = ScreenScale(26),
|
||||||
|
-- weight = 0,
|
||||||
|
-- antialias = true,
|
||||||
|
-- blursize = 8,
|
||||||
|
-- } )
|
105
lua/arccw/client/cl_menus.lua
Normal file
105
lua/arccw/client/cl_menus.lua
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
hook.Add( "PopulateToolMenu", "ArcCW_Options", function()
|
||||||
|
spawnmenu.AddToolMenuOption( "Options", "ArcCW", "ArcCW_Options_HUD", "HUD", "", "", ArcCW_Options_HUD)
|
||||||
|
spawnmenu.AddToolMenuOption( "Options", "ArcCW", "ArcCW_Options_Client", "Client", "", "", ArcCW_Options_Client)
|
||||||
|
spawnmenu.AddToolMenuOption( "Options", "ArcCW", "ArcCW_Options_Server", "Server", "", "", ArcCW_Options_Server)
|
||||||
|
spawnmenu.AddToolMenuOption( "Options", "ArcCW", "ArcCW_Options_Mults", "Multipliers", "", "", ArcCW_Options_Mults)
|
||||||
|
spawnmenu.AddToolMenuOption( "Options", "ArcCW", "ArcCW_Options_NPC", "NPCs", "", "", ArcCW_Options_NPC)
|
||||||
|
spawnmenu.AddToolMenuOption( "Options", "ArcCW", "ArcCW_Options_Atts", "Attachments", "", "", ArcCW_Options_Atts)
|
||||||
|
spawnmenu.AddToolMenuOption( "Options", "ArcCW", "ArcCW_Options_Ammo", "Ammo", "", "", ArcCW_Options_Ammo)
|
||||||
|
end )
|
||||||
|
|
||||||
|
function ArcCW_Options_Ammo( CPanel )
|
||||||
|
CPanel:AddControl("Header", {Description = "These options require admin privileges to change."})
|
||||||
|
CPanel:AddControl("Header", {Description = ""})
|
||||||
|
CPanel:AddControl("Header", {Description = "-1 = don't explode, 0 = simple explosion, 1 = fragmentation, 2 = full"})
|
||||||
|
CPanel:AddControl("Slider", {Label = "Detonation Mode", Command = "arccw_ammo_detonationmode", Min = -1, Max = 2, Type = "int" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Auto Pickup", Command = "arccw_ammo_autopickup" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Large Pickup Trigger", Command = "arccw_ammo_largetrigger" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Rare Skin Chance", Command = "arccw_ammo_rareskin", Min = 0, Max = 1, Type = "float" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Chain Detonation", Command = "arccw_ammo_chaindet" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Ammo Health (-1 for indestructible)", Command = "arccw_mult_ammohealth", Min = -1, Max = 10, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Ammo Amount", Command = "arccw_mult_ammoamount", Min = 0.1, Max = 10, Type = "float" })
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW_Options_HUD( CPanel )
|
||||||
|
CPanel:AddControl("Header", {Description = "All options in this menu can be customized by players, and do not need admin privileges."})
|
||||||
|
CPanel:AddControl("Header", {Description = ""})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "3D Alt HUD", Command = "arccw_hud_3dfun" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Show Crosshair", Command = "arccw_crosshair" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Show Health", Command = "arccw_hud_showhealth" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Show Ammo", Command = "arccw_hud_showammo" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Hide Unowned Attachments", Command = "arccw_attinv_hideunowned" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Hide Customization UI", Command = "arccw_attinv_onlyinspect" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Simple Pros And Cons", Command = "arccw_attinv_simpleproscons" })
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW_Options_Client( CPanel )
|
||||||
|
CPanel:AddControl("Header", {Description = "All options in this menu can be customized by players, and do not need admin privileges."})
|
||||||
|
CPanel:AddControl("Header", {Description = ""})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Toggle Aim", Command = "arccw_toggleads" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Weapon Autosave", Command = "arccw_autosave" })
|
||||||
|
CPanel:AddControl("Header", {Description = "Attempt to re-equip the last equipped set of attachments."})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Cheap Scopes", Command = "arccw_cheapscopes" })
|
||||||
|
CPanel:AddControl("Header", {Description = "A cheaper PIP scope implementation that is very low quality but saves a significant amount of performance. Can be a little glitchy."})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Scope Glare", Command = "arccw_glare" })
|
||||||
|
CPanel:AddControl("Header", {Description = "Glare visible on your scope lens when aiming."})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Customization Blur", Command = "arccw_blur" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Screen Shake", Command = "arccw_shake" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Floating Help Text", Command = "arccw_2d3d" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Muzzle Effects (Others Only)", Command = "arccw_muzzleeffects" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Case Effects (Others Only)", Command = "arccw_shelleffects" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Show World Attachments (Others Only)", Command = "arccw_att_showothers" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Viewmodel Right", Command = "arccw_vm_right", Min = -5, Max = 5, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Viewmodel Forward", Command = "arccw_vm_forward", Min = -5, Max = 5, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Viewmodel Up", Command = "arccw_vm_up", Min = -5, Max = 5, Type = "float" })
|
||||||
|
CPanel:AddControl("Header", {Description = " Warning! Viewmodel offset settings may cause clipping or other undesired effects!"})
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW_Options_Mults( CPanel )
|
||||||
|
CPanel:AddControl("Header", {Description = "These options require admin privileges to change."})
|
||||||
|
CPanel:AddControl("Header", {Description = ""})
|
||||||
|
CPanel:AddControl("Slider", {Label = "Damage", Command = "arccw_mult_damage", Min = 0, Max = 20, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "NPC Damage", Command = "arccw_mult_npcdamage", Min = 0, Max = 20, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Range", Command = "arccw_mult_range", Min = 0.01, Max = 20, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Recoil", Command = "arccw_mult_recoil", Min = 0, Max = 100, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Penetration", Command = "arccw_mult_penetration", Min = 0, Max = 25, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Hip Dispersion", Command = "arccw_mult_hipfire", Min = 0, Max = 100, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Move Dispersion", Command = "arccw_mult_movedisp", Min = 0, Max = 100, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Reload Time", Command = "arccw_mult_reloadtime", Min = 0.01, Max = 10, Type = "float" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "ADS Time", Command = "arccw_mult_sighttime", Min = 0.1, Max = 10, Type = "float" })
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW_Options_NPC( CPanel )
|
||||||
|
CPanel:AddControl("Header", {Description = "These options require admin privileges to change."})
|
||||||
|
CPanel:AddControl("Header", {Description = ""})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Replace NPC Weapons", Command = "arccw_npc_replace" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "NPC Attachments", Command = "arccw_npc_atts" })
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW_Options_Atts( CPanel )
|
||||||
|
CPanel:AddControl("Header", {Description = "These options require admin privileges to change."})
|
||||||
|
CPanel:AddControl("Header", {Description = ""})
|
||||||
|
CPanel:AddControl("Header", {Description = "ArcCW supports attachment inventory style behaviour (Like ACT3) as well as attachment locking style behaviour (Like CW2.0) as well as giving everyone all attachments for free (Like TFA Base)."})
|
||||||
|
CPanel:AddControl("Header", {Description = "Leave all options off for ACT3 style attachment inventory behaviour."})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Free Attachments", Command = "arccw_attinv_free" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Attachment Locking", Command = "arccw_attinv_lockmode" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Lose Attachments on Death", Command = "arccw_attinv_loseondie" })
|
||||||
|
CPanel:AddControl("Header", {Description = "Pick X behaviour allows you to set a limit on attachments that can be placed on any weapon. 0 = unlimited."})
|
||||||
|
CPanel:AddControl("Slider", {Label = "Pick X", Command = "arccw_atts_pickx", Min = 0, Max = 25, Type = "int" })
|
||||||
|
CPanel:AddControl("color", {Label = "Sight Color",
|
||||||
|
Red = "arccw_scope_r",
|
||||||
|
Green = "arccw_scope_g",
|
||||||
|
Blue = "arccw_scope_b",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW_Options_Server( CPanel )
|
||||||
|
CPanel:AddControl("Header", {Description = "These options require admin privileges to change."})
|
||||||
|
CPanel:AddControl("Header", {Description = ""})
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Enable Penetration", Command = "arccw_enable_penetration" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Enable Customization", Command = "arccw_enable_customization" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "True Names (Requires Restart)", Command = "arccw_truenames" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Equipment Self-Destruct Time", Command = "arccw_equipmenttime", Min = 15, Max = 3600, Type = "int" })
|
||||||
|
CPanel:AddControl("Checkbox", {Label = "Enable Year Limit", Command = "arccw_limityear_enable" })
|
||||||
|
CPanel:AddControl("Slider", {Label = "Year Limit", Command = "arccw_limityear", Min = 1800, Max = 2100, Type = "int" })
|
||||||
|
end
|
32
lua/arccw/client/cl_npc.lua
Normal file
32
lua/arccw/client/cl_npc.lua
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
hook.Add("PopulateMenuBar", "ArcCW_NPCWeaponMenu", function ( menubar )
|
||||||
|
local m = menubar:AddOrGetMenu("ArcCW Weapons")
|
||||||
|
local weaponlist = weapons.GetList()
|
||||||
|
|
||||||
|
m:AddCVar("None", "gmod_npcweapon", "none")
|
||||||
|
m:AddSpacer()
|
||||||
|
|
||||||
|
local cats = {}
|
||||||
|
|
||||||
|
table.SortByMember( weaponlist, "PrintName", true )
|
||||||
|
|
||||||
|
for i, k in pairs(weaponlist) do
|
||||||
|
if weapons.IsBasedOn(k.ClassName, "arccw_base") and !k.PrimaryBash and k.Spawnable and !k.NotForNPCs then
|
||||||
|
local cat = k.Category or "Other"
|
||||||
|
if !cats[cat] then
|
||||||
|
cats[cat] = m:AddSubMenu(cat)
|
||||||
|
end
|
||||||
|
|
||||||
|
cats[cat]:SetDeleteSelf(false)
|
||||||
|
|
||||||
|
cats[cat]:AddCVar(k.PrintName, "gmod_npcweapon", k.ClassName)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_npcgiverequest", function(len, ply)
|
||||||
|
local class = GetConVar("gmod_npcweapon"):GetString()
|
||||||
|
|
||||||
|
net.Start("arccw_npcgivereturn")
|
||||||
|
net.WriteString(class)
|
||||||
|
net.SendToServer()
|
||||||
|
end)
|
53
lua/arccw/client/cl_singleplayer.lua
Normal file
53
lua/arccw/client/cl_singleplayer.lua
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
net.Receive("arccw_sp_anim", function(len, ply)
|
||||||
|
local key = net.ReadString()
|
||||||
|
local mult = net.ReadFloat()
|
||||||
|
local sf = net.ReadFloat()
|
||||||
|
|
||||||
|
local wpn = LocalPlayer():GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
wpn:PlayAnimation(key, mult, false, sf)
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_sp_lhikanim", function(len, ply)
|
||||||
|
local key = net.ReadString()
|
||||||
|
local time = net.ReadFloat()
|
||||||
|
|
||||||
|
local wpn = LocalPlayer():GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
wpn:DoLHIKAnimation(key, time)
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_sp_health", function(len, ply)
|
||||||
|
local ent = net.ReadEntity()
|
||||||
|
|
||||||
|
if !IsValid(ent) then return end
|
||||||
|
|
||||||
|
ent:SetHealth(0)
|
||||||
|
ent.ArcCWCLHealth = 0
|
||||||
|
end)
|
||||||
|
|
||||||
|
concommand.Add("arccw_listvmanims", function()
|
||||||
|
local wpn = LocalPlayer():GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn then return end
|
||||||
|
|
||||||
|
local vm = LocalPlayer():GetViewModel()
|
||||||
|
|
||||||
|
if !vm then return end
|
||||||
|
|
||||||
|
PrintTable(vm:GetSequenceList())
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_sp_loadautosave", function(len, ply)
|
||||||
|
local wpn = LocalPlayer():GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn then return end
|
||||||
|
if !IsValid(wpn) then return end
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
wpn:LoadPreset()
|
||||||
|
end)
|
78
lua/arccw/documentation/content.lua
Normal file
78
lua/arccw/documentation/content.lua
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
People Other Than Arctic:
|
||||||
|
Fleshy Mammal
|
||||||
|
TankNut
|
||||||
|
Fesiug
|
||||||
|
Code_GS
|
||||||
|
Zeaga
|
||||||
|
Rubat
|
||||||
|
TheOnly8Z
|
||||||
|
Dynamic
|
||||||
|
|
||||||
|
Audio - CS:GO
|
||||||
|
Models - CS:S
|
||||||
|
Editing Program - Blender
|
||||||
|
General Model Decompiler/Compiler/Extractor - Crowbar
|
||||||
|
Texture Editor - Paint.NET w/ VTF plugin
|
||||||
|
|
||||||
|
Double Barrel - 586 Studios
|
||||||
|
https://gamebanana.com/skins/72959
|
||||||
|
|
||||||
|
Barrett M82 - ???
|
||||||
|
https://gamebanana.com/skins/72430
|
||||||
|
|
||||||
|
"Docter Sight" - tenoyl/Street-you
|
||||||
|
https://gamebanana.com/models/4337
|
||||||
|
|
||||||
|
Pistol Foregrip from M93 - Destiny
|
||||||
|
https://gamebanana.com/skins/112837
|
||||||
|
|
||||||
|
Compact laser for pistols - Krycek
|
||||||
|
https://gamebanana.com/models/3743
|
||||||
|
|
||||||
|
EOTech sight - TheLama/flamshmizer
|
||||||
|
https://gamebanana.com/models/2957
|
||||||
|
|
||||||
|
Micro T-1 sight - kouoaeha
|
||||||
|
https://gamebanana.com/models/3241
|
||||||
|
|
||||||
|
Trijicon reflex sight - dav0r
|
||||||
|
https://gamebanana.com/models/21
|
||||||
|
|
||||||
|
Kobra sight - TheLama
|
||||||
|
https://gamebanana.com/skins/111299
|
||||||
|
|
||||||
|
AFG - MirzaMiftahulFadilla h
|
||||||
|
https://gamebanana.com/models/download/3382
|
||||||
|
|
||||||
|
PVS-4 - Rectus
|
||||||
|
https://gamebanana.com/models/download/3749
|
||||||
|
|
||||||
|
MRS - Outlaws
|
||||||
|
https://gamebanana.com/skins/162976
|
||||||
|
|
||||||
|
AK Mount Redux - Pete3D, Steelbeast
|
||||||
|
https://gamebanana.com/models/797
|
||||||
|
|
||||||
|
Mk. 3 - mantuna
|
||||||
|
https://gamebanana.com/skins/143829
|
||||||
|
|
||||||
|
Raging Bull - Millennia
|
||||||
|
http://gamebanana.com/css/skins/16585
|
||||||
|
|
||||||
|
M60 - Twinke Masta
|
||||||
|
http://gamebanana.com/css/skins/16849
|
||||||
|
|
||||||
|
M14 - General Tso
|
||||||
|
https://gamebanana.com/skins/110796
|
||||||
|
|
||||||
|
OKP-7 - StreetYou
|
||||||
|
https://gamebanana.com/models/4134
|
||||||
|
|
||||||
|
Delta - eNse7en
|
||||||
|
https://gamebanana.com/models/4075
|
||||||
|
|
||||||
|
Green Laser - TenoYL
|
||||||
|
https://gamebanana.com/models/2833
|
||||||
|
*/
|
11
lua/arccw/server/sv_defaultclip.lua
Normal file
11
lua/arccw/server/sv_defaultclip.lua
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
hook.Add( "OnEntityCreated", "ArcCW_DefaultClip", function(ent)
|
||||||
|
if !ent.ArcCW then return end
|
||||||
|
|
||||||
|
if ent.Primary.DefaultClip <= 0 then return end
|
||||||
|
|
||||||
|
ent.Primary.DefaultClip = ent.Primary.ClipSize * 3
|
||||||
|
|
||||||
|
if ent.Primary.ClipSize >= 100 then
|
||||||
|
ent.Primary.DefaultClip = ent.Primary.ClipSize * 2
|
||||||
|
end
|
||||||
|
end)
|
22
lua/arccw/server/sv_net.lua
Normal file
22
lua/arccw/server/sv_net.lua
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
if game.SinglePlayer() then
|
||||||
|
|
||||||
|
util.AddNetworkString("arccw_sp_lhikanim")
|
||||||
|
util.AddNetworkString("arccw_sp_anim")
|
||||||
|
util.AddNetworkString("arccw_sp_health")
|
||||||
|
util.AddNetworkString("arccw_sp_loadautosave")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
util.AddNetworkString("arccw_sendattinv")
|
||||||
|
util.AddNetworkString("arccw_slidepos")
|
||||||
|
util.AddNetworkString("arccw_colorindex")
|
||||||
|
util.AddNetworkString("arccw_asktoattach")
|
||||||
|
util.AddNetworkString("arccw_asktodetach")
|
||||||
|
util.AddNetworkString("arccw_networkatts")
|
||||||
|
util.AddNetworkString("arccw_firemode")
|
||||||
|
util.AddNetworkString("arccw_quicknade")
|
||||||
|
util.AddNetworkString("arccw_togglecustomize")
|
||||||
|
util.AddNetworkString("arccw_ubgl")
|
||||||
|
util.AddNetworkString("arccw_npcgiverequest")
|
||||||
|
util.AddNetworkString("arccw_npcgivereturn")
|
||||||
|
util.AddNetworkString("arccw_rqwpnnet")
|
150
lua/arccw/server/sv_npc.lua
Normal file
150
lua/arccw/server/sv_npc.lua
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
hook.Add("PlayerSpawnedNPC", "ArcCW_PlayerSpawnedNPC", function( ply, ent )
|
||||||
|
net.Start("arccw_npcgiverequest")
|
||||||
|
net.Send(ply)
|
||||||
|
|
||||||
|
ply.ArcCW_LastSpawnedNPC = ent
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_npcgivereturn", function(len, ply)
|
||||||
|
local class = net.ReadString()
|
||||||
|
local ent = ply.ArcCW_LastSpawnedNPC
|
||||||
|
|
||||||
|
if !ent then return end
|
||||||
|
if !IsValid(ent) then return end
|
||||||
|
if !ent:IsNPC() then return end
|
||||||
|
if !class then return end
|
||||||
|
|
||||||
|
local wpn = weapons.Get(class)
|
||||||
|
|
||||||
|
local cap = ent:CapabilitiesGet()
|
||||||
|
|
||||||
|
if bit.band(cap, CAP_USE_WEAPONS) != CAP_USE_WEAPONS then return end
|
||||||
|
|
||||||
|
if weapons.IsBasedOn(class, "arccw_base") and wpn.Spawnable and !wpn.NotForNPCs and (!wpn.AdminOnly or ply:IsAdmin()) then
|
||||||
|
ent:Give(class)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
function ArcCW:GetRandomWeapon(wpn)
|
||||||
|
local tbl = {}
|
||||||
|
local wgt = 0
|
||||||
|
|
||||||
|
for i, k in pairs(weapons.GetList()) do
|
||||||
|
if !weapons.IsBasedOn(k.ClassName, "arccw_base") then continue end
|
||||||
|
if k.PrimaryBash then continue end
|
||||||
|
if !k.Spawnable then continue end
|
||||||
|
if k.NotForNPCs then continue end
|
||||||
|
|
||||||
|
if GetConVar("arccw_limityear_enable"):GetBool() then
|
||||||
|
local year = GetConVar("arccw_limityear"):GetInt()
|
||||||
|
|
||||||
|
if k.Trivia_Year and isnumber(k.Trivia_Year) then
|
||||||
|
if k.Trivia_Year > year then continue end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if k.NPCWeaponType then
|
||||||
|
if isstring(k.NPCWeaponType) then
|
||||||
|
if k.NPCWeaponType != wpn then continue end
|
||||||
|
elseif istable(k.NPCWeaponType) then
|
||||||
|
if !table.HasValue(k.NPCWeaponType, wpn) then continue end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local og = weapons.Get(wpn)
|
||||||
|
|
||||||
|
if og and og.ArcCW then continue end
|
||||||
|
end
|
||||||
|
|
||||||
|
wgt = wgt + (k.NPCWeight or 100)
|
||||||
|
|
||||||
|
table.insert(tbl, {k.ClassName, wgt})
|
||||||
|
end
|
||||||
|
|
||||||
|
local r = math.random(0, wgt)
|
||||||
|
|
||||||
|
for _, i in pairs(tbl) do
|
||||||
|
if i[2] >= r then
|
||||||
|
return i[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
hook.Add( "OnEntityCreated", "ArcCW_NPCWeaponReplacement", function(ent)
|
||||||
|
if CLIENT then return end
|
||||||
|
if !GetConVar("arccw_npc_replace"):GetBool() then return end
|
||||||
|
timer.Simple(0, function()
|
||||||
|
if !ent:IsValid() then return end
|
||||||
|
if !ent:IsNPC() then return end
|
||||||
|
local cap = ent:CapabilitiesGet()
|
||||||
|
|
||||||
|
if bit.band(cap, CAP_USE_WEAPONS) != CAP_USE_WEAPONS then return end
|
||||||
|
|
||||||
|
local class
|
||||||
|
|
||||||
|
if IsValid(ent:GetActiveWeapon()) then
|
||||||
|
class = ent:GetActiveWeapon():GetClass()
|
||||||
|
end
|
||||||
|
|
||||||
|
if !class then return end
|
||||||
|
|
||||||
|
local wpn = ArcCW:GetRandomWeapon(class)
|
||||||
|
|
||||||
|
if wpn then
|
||||||
|
ent:Give(wpn)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
timer.Simple(0, function()
|
||||||
|
if !ent:IsValid() then return end
|
||||||
|
if !ent:IsWeapon() then return end
|
||||||
|
if ent:GetOwner() then return end
|
||||||
|
|
||||||
|
local class = ent:GetClass()
|
||||||
|
|
||||||
|
local wpn = ArcCW:GetRandomWeapon(class)
|
||||||
|
|
||||||
|
if wpn then
|
||||||
|
local wpnent = ents.Create(wpn)
|
||||||
|
wpnent:SetPos(ent:GetPos())
|
||||||
|
wpnent:SetAngles(ent:GetAngles())
|
||||||
|
|
||||||
|
wpnent:NPC_Initialize()
|
||||||
|
|
||||||
|
wpnent:Spawn()
|
||||||
|
|
||||||
|
timer.Simple(0, function()
|
||||||
|
if !ent:IsValid() then return end
|
||||||
|
wpnent:OnDrop(true)
|
||||||
|
ent:Remove()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
hook.Add("PlayerCanPickupWeapon", "ArcCW_PlayerCanPickupWeapon", function(ply, wep)
|
||||||
|
if !wep.ArcCW then return end
|
||||||
|
if !ply:HasWeapon(wep:GetClass()) then return end
|
||||||
|
|
||||||
|
for _, i in pairs(wep.Attachments) do
|
||||||
|
if i.Installed then
|
||||||
|
ArcCW:PlayerGiveAtt(ply, i.Installed)
|
||||||
|
end
|
||||||
|
|
||||||
|
i.Installed = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW:PlayerSendAttInv(ply)
|
||||||
|
wep:NetworkWeapon()
|
||||||
|
end)
|
||||||
|
|
||||||
|
hook.Add("onDarkRPWeaponDropped", "ArcCW_DarkRP", function(ply, spawned_weapon, wep)
|
||||||
|
if wep.ArcCW and wep.Attachments then
|
||||||
|
for i, k in pairs(wep.Attachments) do
|
||||||
|
if k.Installed then
|
||||||
|
ArcCW:PlayerGiveAtt(ply, k.Installed, 1)
|
||||||
|
-- Has to be sent to client or desync will happen
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW:PlayerSendAttInv(ply)
|
||||||
|
end
|
||||||
|
end)
|
14
lua/arccw/server/sv_singleplayer.lua
Normal file
14
lua/arccw/server/sv_singleplayer.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
if game.SinglePlayer() then
|
||||||
|
|
||||||
|
hook.Add("EntityTakeDamage", "ArcCW_ETD", function(npc, dmg)
|
||||||
|
timer.Simple(0, function()
|
||||||
|
if !IsValid(npc) then return end
|
||||||
|
if npc:Health() <= 0 then
|
||||||
|
net.Start("arccw_sp_health")
|
||||||
|
net.WriteEntity(npc)
|
||||||
|
net.Broadcast()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
end
|
14
lua/arccw/server/sv_year.lua
Normal file
14
lua/arccw/server/sv_year.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
hook.Add( "PlayerGiveSWEP", "ArcCW_YearLimiter", function( ply, class, swep )
|
||||||
|
local wep = weapons.Get(class)
|
||||||
|
if !wep then return end
|
||||||
|
if !wep.ArcCW then return end
|
||||||
|
|
||||||
|
if !GetConVar("arccw_limityear_enable"):GetBool() then return end
|
||||||
|
|
||||||
|
local year = GetConVar("arccw_limityear"):GetInt()
|
||||||
|
|
||||||
|
if !wep.Trivia_Year then return end
|
||||||
|
if !isnumber(wep.Trivia_Year) then return end
|
||||||
|
|
||||||
|
if wep.Trivia_Year > year then return false end
|
||||||
|
end )
|
297
lua/arccw/shared/attachments/default.lua
Normal file
297
lua/arccw/shared/attachments/default.lua
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
att.PrintName = ""
|
||||||
|
att.Icon = nil
|
||||||
|
att.Description = ""
|
||||||
|
att.Desc_Pros = {}
|
||||||
|
att.Desc_Cons = {}
|
||||||
|
att.Slot = ""
|
||||||
|
att.TargetSpecificWeapon = "" -- ALWAYS make this attachment available on a specific weapon
|
||||||
|
att.TargetSpecificSlot = 0 -- on this specific slot
|
||||||
|
|
||||||
|
att.SortOrder = 0
|
||||||
|
|
||||||
|
att.Spawnable = false -- generate entity
|
||||||
|
att.AdminOnly = false -- see above
|
||||||
|
att.Ignore = true
|
||||||
|
att.InvAtt = nil -- use this other attachment in inventory
|
||||||
|
att.Free = false -- attachment is always available, and does not need to be picked up or unlocked
|
||||||
|
att.Hidden = false
|
||||||
|
|
||||||
|
att.AddPrefix = ""
|
||||||
|
att.AddSuffix = ""
|
||||||
|
|
||||||
|
att.GivesFlags = {}
|
||||||
|
att.RequireFlags = {}
|
||||||
|
att.ExcludeFlags = {}
|
||||||
|
|
||||||
|
att.Model = ""
|
||||||
|
att.HideModel = false
|
||||||
|
att.ModelBodygroups = ""
|
||||||
|
att.ModelSkin = 0
|
||||||
|
att.ModelScale = 1
|
||||||
|
att.ModelOffset = Vector(0, 0, 0)
|
||||||
|
att.ModelIsShield = false
|
||||||
|
|
||||||
|
att.Breakable = false
|
||||||
|
att.Health = 0 -- for shields
|
||||||
|
att.ShieldCorrectAng = Angle(0, 0, 0)
|
||||||
|
att.ShieldCorrectPos = Vector(0, 0, 0)
|
||||||
|
|
||||||
|
-- amount of damage done to this attachment
|
||||||
|
-- attachments which are even a bit damaged are not returned
|
||||||
|
att.DamageOnShoot = 0
|
||||||
|
att.DamageOnReload = 0
|
||||||
|
att.DamagePerSecond = 0
|
||||||
|
|
||||||
|
-- {slot = int, oldhp = float, dmg = float}
|
||||||
|
att.Hook_AttTakeDamage = function(wep, data) end
|
||||||
|
|
||||||
|
-- {slot = int, dmg = float}
|
||||||
|
att.Hook_AttDestroyed = function(wep, data) end
|
||||||
|
|
||||||
|
att.VMColor = Color(255, 255, 255)
|
||||||
|
att.WMColor = Color(255, 255, 255)
|
||||||
|
att.VMMaterial = ""
|
||||||
|
att.WMMaterial = ""
|
||||||
|
|
||||||
|
att.DroppedModel = nil
|
||||||
|
att.LHIKHide = false -- use this to just hide the left hand
|
||||||
|
att.LHIK = false -- use this model for left hand IK
|
||||||
|
att.LHIK_Animation = false
|
||||||
|
|
||||||
|
att.ActivateElements = {}
|
||||||
|
|
||||||
|
att.MountPositionOverride = nil -- set between 0 to 1 to always mount in a certain position
|
||||||
|
|
||||||
|
att.AdditionalSights = {
|
||||||
|
{
|
||||||
|
Pos = Vector(0, 0, 0), -- relative to where att.Model is placed
|
||||||
|
Ang = Angle(0, 0, 0),
|
||||||
|
ScrollFunc = ArcCW.SCROLL_ZOOM,
|
||||||
|
ZoomLevels = 6,
|
||||||
|
ZoomSound = "weapons/arccw/fiveseven/fiveseven_slideback.wav",
|
||||||
|
NVScope = nil, -- enables night vision effects for scope
|
||||||
|
NVScopeColor = Color(0, 255, 100),
|
||||||
|
NVFullColor = false, -- night vision scope is true full color
|
||||||
|
Thermal = true,
|
||||||
|
ThermalScopeColor = Color(255, 255, 255),
|
||||||
|
ThermalHighlightColor = Color(255, 255, 255),
|
||||||
|
ThermalScopeSimple = false,
|
||||||
|
ThermalNoCC = false,
|
||||||
|
ThermalBHOT = false, -- invert bright/dark
|
||||||
|
IgnoreExtra = false -- ignore gun-determined extra sight distance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
att.UBGL = false -- is underbarrel grenade launcher
|
||||||
|
|
||||||
|
att.UBGL_Automatic = false
|
||||||
|
att.UBGL_ClipSize = 1
|
||||||
|
att.UBGL_Ammo = "smg1_grenade"
|
||||||
|
att.UBGL_RPM = 300
|
||||||
|
|
||||||
|
-- wep: weapon
|
||||||
|
-- ubgl: UBGL attachment slot.
|
||||||
|
att.UBGL_Fire = function(wep, ubgl) end
|
||||||
|
att.UBGL_Reload = function(wep, ubgl) end
|
||||||
|
|
||||||
|
att.Silencer = false
|
||||||
|
|
||||||
|
att.Bipod = false
|
||||||
|
att.Mult_BipodRecoil = 0.25
|
||||||
|
att.Mult_BipodDispersion = 0.1
|
||||||
|
|
||||||
|
att.MagExtender = false
|
||||||
|
att.MagReducer = false
|
||||||
|
att.OverrideClipSize = nil
|
||||||
|
att.Add_ClipSize = 0
|
||||||
|
|
||||||
|
att.Laser = false
|
||||||
|
att.LaserStrength = 1
|
||||||
|
att.LaserBone = "laser"
|
||||||
|
|
||||||
|
att.Holosight = false
|
||||||
|
att.HolosightReticle = nil
|
||||||
|
att.HolosightFlare = nil
|
||||||
|
att.HolosightSize = nil
|
||||||
|
att.HolosightBone = "holosight"
|
||||||
|
att.HolosightPiece = nil -- the lens of the holo sight, if applicable
|
||||||
|
att.HolosightMagnification = 1 -- magnify the lens by this much
|
||||||
|
att.HolosightBlackbox = false
|
||||||
|
att.HolosightNoHSP = false -- for this holosight ignore HSP
|
||||||
|
att.HolosightConstDist = nil -- constant holosight distance, mainly for scopes with range finder
|
||||||
|
|
||||||
|
att.Colorable = false -- automatically use the player's color option
|
||||||
|
att.HolosightColor = Color(255, 255, 255)
|
||||||
|
|
||||||
|
att.Override_Firemodes = {}
|
||||||
|
|
||||||
|
-- all hooks will work when applied to the SWEP table as well
|
||||||
|
-- e.g. SWEP.Hook_FireBullets
|
||||||
|
|
||||||
|
-- use A_Hook_[Add_Whatever] to hook into additive hooks.
|
||||||
|
-- {buff = string buff, add = num add}
|
||||||
|
-- return table
|
||||||
|
|
||||||
|
-- use O_Hook_[Override_Whatever] to hook into override hooks.
|
||||||
|
-- {buff = string buff, current = any override, winningslot = int slot}
|
||||||
|
|
||||||
|
-- use M_Hook_[Mult_Whatever] to hook into multiply hooks.
|
||||||
|
-- {buff = string buff, mult = num mult}
|
||||||
|
|
||||||
|
-- all hooks, mults, and adds will work on fire modes
|
||||||
|
|
||||||
|
-- done before playing an effect
|
||||||
|
-- return false to prevent playing
|
||||||
|
-- fx: {fx = EffectData()}
|
||||||
|
att.Hook_PreDoEffects = function(wep, fx) end
|
||||||
|
|
||||||
|
-- return true = compatible
|
||||||
|
-- return false = incompatible
|
||||||
|
-- data = {slot = string or table, att = string}
|
||||||
|
att.Hook_Compatible = function(wep, data) end
|
||||||
|
|
||||||
|
-- hook that lets you change the values of the bullet before it's fired.
|
||||||
|
att.Hook_FireBullets = function(wep, bullettable) end
|
||||||
|
|
||||||
|
-- called after all other primary attack functions. Do stuff here.
|
||||||
|
att.Hook_PostFireBullets = function(wep) end
|
||||||
|
|
||||||
|
-- return true to prevent fire
|
||||||
|
att.Hook_ShouldNotFire = function(wep) end
|
||||||
|
|
||||||
|
-- return anything to select this reload animation. Bear in mind that not all guns have the same animations, so check first.
|
||||||
|
att.Hook_SelectReloadAnimation = function(wep, curanim) end
|
||||||
|
|
||||||
|
-- return anything to multiply reload time by that much
|
||||||
|
att.Hook_MultReload = function(wep, mult) end
|
||||||
|
|
||||||
|
-- data has entries:
|
||||||
|
-- number count, how much ammo to add with this insert
|
||||||
|
-- string anim, which animation to play
|
||||||
|
-- bool empty, whether we are reloading from empty
|
||||||
|
att.Hook_SelectInsertAnimation = function(wep, data) end
|
||||||
|
|
||||||
|
-- return to override fire animation
|
||||||
|
att.Hook_SelectFireAnimation = function(wep, curanim) end
|
||||||
|
|
||||||
|
-- return string to change played anim
|
||||||
|
-- string anim, animation we are attempting to play
|
||||||
|
-- return false to block animation
|
||||||
|
-- return nil to do nothing
|
||||||
|
att.Hook_TranslateAnimation = function(wep, anim) end
|
||||||
|
|
||||||
|
att.Hook_LHIK_TranslateAnimation = function(wep, anim) end
|
||||||
|
|
||||||
|
-- att.Hook_TranslateAnimation = function(wep, anim)
|
||||||
|
-- if anim == "reload" then
|
||||||
|
-- return "reload_soh"
|
||||||
|
-- elseif anim == "reload_empty" then
|
||||||
|
-- return "reload_empty_soh"
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- data has entries:
|
||||||
|
-- number range, the distance the bullet had to travel
|
||||||
|
-- number damage, the calculated damage the bullet will do
|
||||||
|
-- number penleft, the amount of penetration the bullet still possesses
|
||||||
|
-- enum dmgtype, the DMG_ enum of the damagetype
|
||||||
|
-- table tr, the trace result
|
||||||
|
-- entity att, the attacker (?)
|
||||||
|
-- DamageInfo dmg, the damage info
|
||||||
|
|
||||||
|
-- changes to dmg may be overwritten later, so set damage and dmgtype instead
|
||||||
|
att.Hook_BulletHit = function(wep, data) end
|
||||||
|
|
||||||
|
-- return to set mag capacity
|
||||||
|
att.Hook_GetCapacity = function(wep, cap) end
|
||||||
|
|
||||||
|
-- return false to suppress shoot sound
|
||||||
|
-- string sound = default sound
|
||||||
|
att.Hook_GetShootSound = function(wep, sound) end
|
||||||
|
att.Hook_GetDistantShootSound = function(wep, sound) end
|
||||||
|
|
||||||
|
-- allows you to modify the weapon's rate of fire
|
||||||
|
att.Hook_ModifyRPM = function(wep, delay) end
|
||||||
|
|
||||||
|
-- run in Think()
|
||||||
|
att.Hook_Think = function(wep) end
|
||||||
|
|
||||||
|
-- thinking hook for att
|
||||||
|
att.DrawFunc = function(wep, element, wm) end
|
||||||
|
|
||||||
|
att.Mult_Damage = 1
|
||||||
|
att.Mult_DamageMin = 1
|
||||||
|
att.Mult_DamageNPC = 1 -- damage WHEN USED BY NPCS not when used against them
|
||||||
|
att.Mult_Range = 1
|
||||||
|
att.Mult_Penetration = 1
|
||||||
|
att.Override_DamageType = nil
|
||||||
|
att.Override_ShootEntity = nil
|
||||||
|
att.Mult_MuzzleVelocity = 1
|
||||||
|
|
||||||
|
att.Override_ShotgunSpreadPattern = {}
|
||||||
|
att.Override_ShotgunSpreadPatternOverrun = {}
|
||||||
|
|
||||||
|
att.Mult_MeleeTime = 1
|
||||||
|
att.Mult_MeleeDamage = 1
|
||||||
|
att.Add_MeleeRange = 0
|
||||||
|
att.Mult_MeleeAttackTime = 1
|
||||||
|
|
||||||
|
att.Override_Tracer = nil -- tracer effect name
|
||||||
|
att.Override_TracerNum = nil
|
||||||
|
-- att.Override_TracerCol = nil
|
||||||
|
-- att.Mult_TracerWidth = 1
|
||||||
|
|
||||||
|
att.Override_ShotgunReload = nil
|
||||||
|
att.Override_HybridReload = nil
|
||||||
|
|
||||||
|
att.Override_ManualAction = nil
|
||||||
|
|
||||||
|
att.Override_CanFireUnderwater = nil
|
||||||
|
|
||||||
|
att.Override_ChamberSize = nil
|
||||||
|
|
||||||
|
att.Mult_Recoil = 1
|
||||||
|
att.Mult_RecoilSide = 1
|
||||||
|
att.Mult_VisualRecoilMult = 1
|
||||||
|
|
||||||
|
att.Override_ShootWhileSprint = nil
|
||||||
|
|
||||||
|
att.Mult_RPM = 1
|
||||||
|
|
||||||
|
att.Override_Num = nil
|
||||||
|
|
||||||
|
att.Mult_AccuracyMOA = 1
|
||||||
|
att.Mult_HipDispersion = 1
|
||||||
|
att.Mult_SightsDispersion = 1
|
||||||
|
|
||||||
|
att.Mult_ShootVol = 1
|
||||||
|
att.Mult_ShootPitch = 1
|
||||||
|
|
||||||
|
att.Override_MuzzleEffect = nil
|
||||||
|
|
||||||
|
att.Override_ShellMaterial = nil
|
||||||
|
|
||||||
|
att.Override_MuzzleEffectAttachment = nil
|
||||||
|
att.Override_CaseEffectAttachment = nil
|
||||||
|
|
||||||
|
att.Mult_SpeedMult = 1
|
||||||
|
att.Mult_SightedSpeedMult = 1
|
||||||
|
|
||||||
|
att.Override_HoldtypeHolstered = nil
|
||||||
|
att.Override_HoldtypeActive = nil
|
||||||
|
att.Override_HoldtypeSights = nil
|
||||||
|
|
||||||
|
att.Override_AnimShoot = nil
|
||||||
|
|
||||||
|
att.Override_HolsterPos = nil
|
||||||
|
att.Override_HolsterAng = nil
|
||||||
|
|
||||||
|
att.Add_BarrelLength = 0
|
||||||
|
|
||||||
|
att.Override_BarrelOffsetSighted = nil
|
||||||
|
att.Override_BarrelOffsetHip = nil
|
||||||
|
|
||||||
|
att.Mult_ReloadTime = 1
|
||||||
|
att.Mult_DrawTime = 1
|
||||||
|
att.Mult_SightTime = 1
|
||||||
|
att.Mult_CycleTime = 1
|
107
lua/arccw/shared/sh_acwcommon.lua
Normal file
107
lua/arccw/shared/sh_acwcommon.lua
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
ArcCW.HUToM = 1 / 12 * 0.3048
|
||||||
|
ArcCW.MOAToAcc = 10 / 180 / 60
|
||||||
|
|
||||||
|
ArcCW.EnableCustomization = true
|
||||||
|
|
||||||
|
ArcCW.STATE_IDLE = 0
|
||||||
|
ArcCW.STATE_SIGHTS = 1
|
||||||
|
ArcCW.STATE_SPRINT = 2
|
||||||
|
ArcCW.STATE_DISABLE = 3
|
||||||
|
ArcCW.STATE_CUSTOMIZE = 4
|
||||||
|
ArcCW.STATE_BIPOD = 5
|
||||||
|
|
||||||
|
ArcCW.SCROLL_NONE = 0
|
||||||
|
ArcCW.SCROLL_ZOOM = 1
|
||||||
|
|
||||||
|
ArcCW.ShellSoundsTable = {
|
||||||
|
"player/pl_shell1.wav",
|
||||||
|
"player/pl_shell2.wav",
|
||||||
|
"player/pl_shell3.wav"
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.ShotgunShellSoundsTable = {
|
||||||
|
"weapons/fx/tink/shotgun_shell1.wav",
|
||||||
|
"weapons/fx/tink/shotgun_shell2.wav",
|
||||||
|
"weapons/fx/tink/shotgun_shell3.wav"
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.ReloadTimeTable = {
|
||||||
|
[ACT_HL2MP_GESTURE_RELOAD_AR2] = 2,
|
||||||
|
[ACT_HL2MP_GESTURE_RELOAD_SMG1] = 2,
|
||||||
|
[ACT_HL2MP_GESTURE_RELOAD_PISTOL] = 1.5,
|
||||||
|
[ACT_HL2MP_GESTURE_RELOAD_REVOLVER] = 2.5,
|
||||||
|
[ACT_HL2MP_GESTURE_RELOAD_SHOTGUN] = 2.5,
|
||||||
|
[ACT_HL2MP_GESTURE_RELOAD_DUEL] = 3.25,
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.ReplaceWeapons = {
|
||||||
|
["weapon_pistol"] = true,
|
||||||
|
["weapon_smg1"] = true,
|
||||||
|
["weapon_ar2"] = true,
|
||||||
|
["weapon_shotgun"] = true,
|
||||||
|
["weapon_357"] = true,
|
||||||
|
["weapon_alyxgun"] = true,
|
||||||
|
["weapon_crossbow"] = true,
|
||||||
|
["weapon_rpg"] = true,
|
||||||
|
["weapon_annabelle"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.PenTable = {
|
||||||
|
[MAT_ANTLION] = 1,
|
||||||
|
[MAT_BLOODYFLESH] = 1,
|
||||||
|
[MAT_CONCRETE] = 1,
|
||||||
|
[MAT_DIRT] = 0.75,
|
||||||
|
[MAT_EGGSHELL] = 1,
|
||||||
|
[MAT_FLESH] = 0.25,
|
||||||
|
[MAT_GRATE] = 1,
|
||||||
|
[MAT_ALIENFLESH] = 0.25,
|
||||||
|
[MAT_CLIP] = 1000,
|
||||||
|
[MAT_SNOW] = 0.75,
|
||||||
|
[MAT_PLASTIC] = 2,
|
||||||
|
[MAT_METAL] = 5,
|
||||||
|
[MAT_SAND] = 1,
|
||||||
|
[MAT_FOLIAGE] = 0.5,
|
||||||
|
[MAT_COMPUTER] = 0.75,
|
||||||
|
[MAT_SLOSH] = 1,
|
||||||
|
[MAT_TILE] = 1,
|
||||||
|
[MAT_GRASS] = 1,
|
||||||
|
[MAT_VENT] = 1,
|
||||||
|
[MAT_WOOD] = 0.75,
|
||||||
|
[MAT_DEFAULT] = 1,
|
||||||
|
[MAT_GLASS] = 0.2,
|
||||||
|
[MAT_WARPSHIELD] = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.Colors = {
|
||||||
|
POS = Color(25, 225, 25),
|
||||||
|
MINIPOS = Color(75, 225, 75),
|
||||||
|
NEU = Color(225, 225, 225),
|
||||||
|
MININEG = Color(225, 75, 75),
|
||||||
|
NEG = Color(225, 25, 25),
|
||||||
|
COSM = Color(100, 100, 225)
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.LHIKBones = {
|
||||||
|
"ValveBiped.Bip01_L_UpperArm",
|
||||||
|
"ValveBiped.Bip01_L_Forearm",
|
||||||
|
"ValveBiped.Bip01_L_Hand",
|
||||||
|
"ValveBiped.Bip01_L_Finger4",
|
||||||
|
"ValveBiped.Bip01_L_Finger41",
|
||||||
|
"ValveBiped.Bip01_L_Finger42",
|
||||||
|
"ValveBiped.Bip01_L_Finger3",
|
||||||
|
"ValveBiped.Bip01_L_Finger31",
|
||||||
|
"ValveBiped.Bip01_L_Finger32",
|
||||||
|
"ValveBiped.Bip01_L_Finger2",
|
||||||
|
"ValveBiped.Bip01_L_Finger21",
|
||||||
|
"ValveBiped.Bip01_L_Finger22",
|
||||||
|
"ValveBiped.Bip01_L_Finger1",
|
||||||
|
"ValveBiped.Bip01_L_Finger11",
|
||||||
|
"ValveBiped.Bip01_L_Finger12",
|
||||||
|
"ValveBiped.Bip01_L_Finger0",
|
||||||
|
"ValveBiped.Bip01_L_Finger01",
|
||||||
|
"ValveBiped.Bip01_L_Finger02",
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcCW.NoDraw = true
|
||||||
|
|
||||||
|
ArcCW.PresetPath = "arccw_presets/"
|
282
lua/arccw/shared/sh_attachments.lua
Normal file
282
lua/arccw/shared/sh_attachments.lua
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
function ArcCW:GetAttsForSlot(slot, wep)
|
||||||
|
local ret = {}
|
||||||
|
|
||||||
|
for id, _ in pairs(ArcCW.AttachmentTable) do
|
||||||
|
|
||||||
|
if !ArcCW:SlotAcceptsAtt(slot, wep, id) then continue end
|
||||||
|
|
||||||
|
table.insert(ret, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW:SlotAcceptsAtt(slot, wep, att)
|
||||||
|
local slots = {}
|
||||||
|
|
||||||
|
if isstring(slot) then
|
||||||
|
slots[slot] = true
|
||||||
|
elseif istable(slot) then
|
||||||
|
for _, i in pairs(slot) do
|
||||||
|
slots[i] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[att]
|
||||||
|
|
||||||
|
if atttbl.Hidden then return false end
|
||||||
|
|
||||||
|
if atttbl.NotForNPC and wep.Owner:IsNPC() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if wep.RejectAttachments and wep.RejectAttachments[att] then return false end
|
||||||
|
|
||||||
|
if wep and atttbl.Hook_Compatible then
|
||||||
|
local compat = atttbl.Hook_Compatible(wep, {slot = slot, att = att})
|
||||||
|
if compat == true then
|
||||||
|
return true
|
||||||
|
elseif compat == false then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isstring(atttbl.Slot) then
|
||||||
|
if !slots[atttbl.Slot] then return false end
|
||||||
|
elseif istable(atttbl.Slot) then
|
||||||
|
local yeah = false
|
||||||
|
|
||||||
|
for _, i in pairs(atttbl.Slot) do
|
||||||
|
if slots[i] then
|
||||||
|
yeah = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !yeah then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW:PlayerGetAtts(ply, att)
|
||||||
|
if GetConVar("arccw_attinv_free"):GetBool() then return 999 end
|
||||||
|
|
||||||
|
if att == "" then return 999 end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[att]
|
||||||
|
|
||||||
|
if atttbl.Free then return 999 end
|
||||||
|
|
||||||
|
if !IsValid(ply) then return 0 end
|
||||||
|
|
||||||
|
if !ply:IsAdmin() then
|
||||||
|
if atttbl.AdminOnly then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if atttbl.InvAtt then att = atttbl.InvAtt end
|
||||||
|
|
||||||
|
if !ply.ArcCW_AttInv then return 0 end
|
||||||
|
|
||||||
|
if !ply.ArcCW_AttInv[att] then return 0 end
|
||||||
|
|
||||||
|
return ply.ArcCW_AttInv[att]
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW:PlayerGiveAtt(ply, att, amt)
|
||||||
|
amt = amt or 1
|
||||||
|
|
||||||
|
if !IsValid(ply) then return end
|
||||||
|
|
||||||
|
if !ply.ArcCW_AttInv then
|
||||||
|
ply.ArcCW_AttInv = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[att]
|
||||||
|
|
||||||
|
if atttbl.InvAtt then att = atttbl.InvAtt end
|
||||||
|
|
||||||
|
if GetConVar("arccw_attinv_lockmode"):GetBool() then
|
||||||
|
if ply.ArcCW_AttInv[att] == 1 then return end
|
||||||
|
ply.ArcCW_AttInv[att] = 1
|
||||||
|
else
|
||||||
|
ply.ArcCW_AttInv[att] = (ply.ArcCW_AttInv[att] or 0) + amt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW:PlayerTakeAtt(ply, att, amt)
|
||||||
|
amt = amt or 1
|
||||||
|
|
||||||
|
if GetConVar("arccw_attinv_lockmode"):GetBool() then return end
|
||||||
|
|
||||||
|
if !IsValid(ply) then return end
|
||||||
|
|
||||||
|
if !ply.ArcCW_AttInv then
|
||||||
|
ply.ArcCW_AttInv = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[att]
|
||||||
|
|
||||||
|
if atttbl.InvAtt then att = atttbl.InvAtt end
|
||||||
|
|
||||||
|
ply.ArcCW_AttInv[att] = ply.ArcCW_AttInv[att] or 0
|
||||||
|
|
||||||
|
if ply.ArcCW_AttInv[att] <= 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
ply.ArcCW_AttInv[att] = (ply.ArcCW_AttInv[att] or 0) - amt
|
||||||
|
|
||||||
|
if ply.ArcCW_AttInv[att] < 0 then
|
||||||
|
ply.ArcCW_AttInv[att] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
|
||||||
|
local function postsetup(wpn)
|
||||||
|
if wpn.SetupModel then
|
||||||
|
wpn:SetupModel(true)
|
||||||
|
if wpn:GetOwner() == LocalPlayer() then
|
||||||
|
wpn:SetupModel(false)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
timer.Simple(0.1, function()
|
||||||
|
postsetup(wpn)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
net.Receive("arccw_networkatts", function(len, ply)
|
||||||
|
local wpn = net.ReadEntity()
|
||||||
|
|
||||||
|
if !IsValid(wpn) then return end
|
||||||
|
|
||||||
|
local attnum = net.ReadUInt(8)
|
||||||
|
|
||||||
|
wpn.Attachments = wpn.Attachments or {}
|
||||||
|
|
||||||
|
for i = 1, attnum do
|
||||||
|
local attid = net.ReadUInt(ArcCW.GetBitNecessity())
|
||||||
|
|
||||||
|
wpn.Attachments[i] = wpn.Attachments[i] or {}
|
||||||
|
|
||||||
|
if attid == 0 then
|
||||||
|
wpn.Attachments[i].Installed = false
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
local att = ArcCW.AttachmentIDTable[attid]
|
||||||
|
|
||||||
|
wpn.Attachments[i].Installed = att
|
||||||
|
|
||||||
|
if wpn.Attachments[i].SlideAmount then
|
||||||
|
wpn.Attachments[i].SlidePos = net.ReadFloat()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wpn.CertainAboutAtts = true
|
||||||
|
|
||||||
|
postsetup(wpn)
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_sendattinv", function(len, ply)
|
||||||
|
LocalPlayer().ArcCW_AttInv = {}
|
||||||
|
|
||||||
|
local count = net.ReadUInt(32)
|
||||||
|
|
||||||
|
for i = 1, count do
|
||||||
|
local attid = net.ReadUInt(ArcCW.GetBitNecessity())
|
||||||
|
local acount = net.ReadUInt(32)
|
||||||
|
|
||||||
|
local att = ArcCW.AttachmentIDTable[attid]
|
||||||
|
|
||||||
|
LocalPlayer().ArcCW_AttInv[att] = acount
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
elseif SERVER then
|
||||||
|
|
||||||
|
hook.Add("PlayerSpawn", "ArcCW_SpawnAttInv", function(ply, trans)
|
||||||
|
if trans then return end
|
||||||
|
|
||||||
|
if GetConVar("arccw_attinv_loseondie"):GetBool() then
|
||||||
|
ply.ArcCW_AttInv = {}
|
||||||
|
|
||||||
|
ArcCW:PlayerSendAttInv(ply)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_rqwpnnet", function(len, ply)
|
||||||
|
local wpn = net.ReadEntity()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
wpn:NetworkWeapon(ply)
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_slidepos", function(len, ply)
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
local slot = net.ReadUInt(8)
|
||||||
|
local pos = net.ReadFloat()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
if !wpn.Attachments[slot] then return end
|
||||||
|
|
||||||
|
wpn.Attachments[slot].SlidePos = pos
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_asktoattach", function(len, ply)
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
local slot = net.ReadUInt(8)
|
||||||
|
local attid = net.ReadUInt(24)
|
||||||
|
|
||||||
|
local att = ArcCW.AttachmentIDTable[attid]
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
if !wpn.Attachments[slot] then return end
|
||||||
|
if !att then return end
|
||||||
|
|
||||||
|
wpn:Attach(slot, att)
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_asktodetach", function(len, ply)
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
local slot = net.ReadUInt(8)
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
if !wpn.Attachments[slot] then return end
|
||||||
|
|
||||||
|
wpn:Detach(slot)
|
||||||
|
end)
|
||||||
|
|
||||||
|
function ArcCW:PlayerSendAttInv(ply)
|
||||||
|
if GetConVar("arccw_attinv_free"):GetBool() then return end
|
||||||
|
|
||||||
|
if !IsValid(ply) then return end
|
||||||
|
|
||||||
|
if !ply.ArcCW_AttInv then return end
|
||||||
|
|
||||||
|
net.Start("arccw_sendattinv")
|
||||||
|
|
||||||
|
net.WriteUInt(table.Count(ply.ArcCW_AttInv), 32)
|
||||||
|
|
||||||
|
for att, count in pairs(ply.ArcCW_AttInv) do
|
||||||
|
local atttbl = ArcCW.AttachmentTable[att]
|
||||||
|
local attid = atttbl.ID
|
||||||
|
net.WriteUInt(attid, ArcCW.GetBitNecessity())
|
||||||
|
net.WriteUInt(count, 32)
|
||||||
|
end
|
||||||
|
|
||||||
|
net.Send(ply)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
29
lua/arccw/shared/sh_controls.lua
Normal file
29
lua/arccw/shared/sh_controls.lua
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
net.Receive("arccw_firemode", function(len, ply)
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
wpn:ChangeFiremode()
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_ubgl", function(len, ply)
|
||||||
|
local on = net.ReadBool()
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
if on then
|
||||||
|
wpn:SelectUBGL()
|
||||||
|
else
|
||||||
|
wpn:DeselectUBGL()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("arccw_togglecustomize", function(len, ply)
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
local onoff = net.ReadBool()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
wpn:ToggleCustomizeHUD(onoff)
|
||||||
|
end)
|
42
lua/arccw/shared/sh_convars.lua
Normal file
42
lua/arccw/shared/sh_convars.lua
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
CreateConVar("arccw_enable_penetration", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "")
|
||||||
|
CreateConVar("arccw_enable_customization", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "")
|
||||||
|
|
||||||
|
CreateConVar("arccw_attinv_lockmode", 0, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Once owned, players can use attachments as much as they like.")
|
||||||
|
CreateConVar("arccw_attinv_free", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "All attachments can always be used.")
|
||||||
|
CreateConVar("arccw_attinv_loseondie", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "All attachments reset on death.")
|
||||||
|
|
||||||
|
CreateConVar("arccw_atts_pickx", 0, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Limit weapons to this many maximum attachments. 0 = disable system.", 0)
|
||||||
|
|
||||||
|
CreateConVar("arccw_npc_replace", 0, FCVAR_ARCHIVE, "Replace NPC weapons with ArcCW weapons.")
|
||||||
|
CreateConVar("arccw_npc_atts", 1, FCVAR_ARCHIVE, "Randomly give NPC weapons attachments.")
|
||||||
|
|
||||||
|
CreateConVar("arccw_truenames", 0, FCVAR_ARCHIVE, "Use true names instead of fake names, where applicable. Requires restart.")
|
||||||
|
|
||||||
|
CreateConVar("arccw_equipmenttime", 180, FCVAR_ARCHIVE, "How long equipment such as Claymores will remain on the map before self-destructing.")
|
||||||
|
|
||||||
|
CreateConVar("arccw_mult_damage", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for damage done by all ArcCW weapons.")
|
||||||
|
CreateConVar("arccw_mult_npcdamage", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for damage done by all ArcCW weapons used by NPCs.")
|
||||||
|
CreateConVar("arccw_mult_hipfire", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for hip fire spread for ArcCW.")
|
||||||
|
CreateConVar("arccw_mult_reloadtime", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for how long ArcCW weapons take to reload.", 0.01)
|
||||||
|
CreateConVar("arccw_mult_sighttime", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for how long ArcCW weapons take to enter sights.", 0.1)
|
||||||
|
CreateConVar("arccw_mult_range", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for range of all ArcCW weapons.")
|
||||||
|
CreateConVar("arccw_mult_recoil", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for recoil of all ArcCW weapons.")
|
||||||
|
CreateConVar("arccw_mult_movedisp", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for moving inaccuracy of ArcCW weapons.")
|
||||||
|
CreateConVar("arccw_mult_penetration", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for ArcCW penetration amount.")
|
||||||
|
|
||||||
|
CreateConVar("arccw_reloadonrefresh", 1, FCVAR_ARCHIVE, "Whether to reload ArcCW attachments on admin clean up.")
|
||||||
|
|
||||||
|
CreateConVar("arccw_override_crosshair_off", 0, FCVAR_ARCHIVE + FCVAR_REPLICATED, "")
|
||||||
|
|
||||||
|
CreateConVar("arccw_ammo_detonationmode", 2, FCVAR_ARCHIVE + FCVAR_REPLICATED, "The type of ammo detonation to use. -1 = don't explode, 0 = simple explosion, 1 = fragmentation, 2 = full", -1, 2)
|
||||||
|
CreateConVar("arccw_ammo_autopickup", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Whether to pick up ammo when walking over in addition to pressing Use.", 0, 1)
|
||||||
|
CreateConVar("arccw_ammo_largetrigger", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Whether to use larger trigger boxes for ammo, similar to HL2. Only useful when autopickup is true.", 0, 1)
|
||||||
|
CreateConVar("arccw_ammo_rareskin", 0.08, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Chance for a rare skin to appear. Only specific models have these.", 0, 1)
|
||||||
|
CreateConVar("arccw_ammo_chaindet", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Whether to allow ammoboxes to detonate each other. If disabled, they will still be destroyed but not explode.", 0, 1)
|
||||||
|
|
||||||
|
|
||||||
|
CreateConVar("arccw_mult_ammohealth", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for how much health ammo boxes have. Set to -1 for indestructible boxes.", -1)
|
||||||
|
CreateConVar("arccw_mult_ammoamount", 1, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Multiplier for how much ammo are in ammo boxes.", 0)
|
||||||
|
|
||||||
|
CreateConVar("arccw_limityear_enable", 0, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Limit the maximum year for weapons.")
|
||||||
|
CreateConVar("arccw_limityear", 0, FCVAR_ARCHIVE + FCVAR_REPLICATED, "Limit the maximum year for weapons.")
|
20
lua/arccw/shared/sh_effects.lua
Normal file
20
lua/arccw/shared/sh_effects.lua
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
game.AddParticles( "particles/muzzleflashes_test.pcf" )
|
||||||
|
game.AddParticles( "particles/muzzleflashes_test_b.pcf" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_smg" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_shotgun" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_slug" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_pistol" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_pistol_deagle" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_suppressed" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_mp5" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_MINIMI" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_m79" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_m14" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_ak74" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_m82" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_m3" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_1" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_3" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_4" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_5" )
|
||||||
|
PrecacheParticleSystem( "muzzleflash_6" )
|
96
lua/arccw/shared/sh_loadatts.lua
Normal file
96
lua/arccw/shared/sh_loadatts.lua
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
ArcCW = ArcCW or {}
|
||||||
|
ArcCW.AttachmentTable = {}
|
||||||
|
ArcCW.AttachmentIDTable = {}
|
||||||
|
ArcCW.AttachmentSlotTable = {}
|
||||||
|
ArcCW.NumAttachments = 1
|
||||||
|
|
||||||
|
ArcCW.GenerateAttEntities = true
|
||||||
|
|
||||||
|
shortname = ""
|
||||||
|
|
||||||
|
function ArcCW.LoadAttachmentType(att)
|
||||||
|
if !att.Ignore then
|
||||||
|
ArcCW.AttachmentTable[shortname] = att
|
||||||
|
ArcCW.AttachmentIDTable[ArcCW.NumAttachments] = shortname
|
||||||
|
|
||||||
|
att.ShortName = shortname
|
||||||
|
|
||||||
|
if !ArcCW.AttachmentSlotTable[att.Slot] then
|
||||||
|
ArcCW.AttachmentSlotTable[att.Slot] = {}
|
||||||
|
end
|
||||||
|
table.insert(ArcCW.AttachmentSlotTable[att.Slot], ArcCW.NumAttachments)
|
||||||
|
|
||||||
|
att.ID = ArcCW.NumAttachments
|
||||||
|
|
||||||
|
if ArcCW.GenerateAttEntities then
|
||||||
|
if !att.DoNotRegister and !att.InvAtt and !att.Free and !att.Ignore then
|
||||||
|
local attent = {}
|
||||||
|
attent.Base = "arccw_att_base"
|
||||||
|
attent.Icon = att.Icon
|
||||||
|
attent.PrintName = att.PrintName or shortname
|
||||||
|
attent.Spawnable = att.Spawnable or true
|
||||||
|
attent.AdminOnly = att.AdminOnly or false
|
||||||
|
attent.Category = "ArcCW - Attachments"
|
||||||
|
attent.Model = att.DroppedModel or att.Model or "models/Items/BoxSRounds.mdl"
|
||||||
|
attent.GiveAttachments = {
|
||||||
|
[att.ShortName] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, k in pairs(att) do
|
||||||
|
attent[i] = k
|
||||||
|
end
|
||||||
|
|
||||||
|
scripted_ents.Register( attent, "acwatt_" .. shortname )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.NumAttachments = ArcCW.NumAttachments + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ArcCW_LoadAtts()
|
||||||
|
ArcCW.AttachmentTable = {}
|
||||||
|
ArcCW.AttachmentIDTable = {}
|
||||||
|
ArcCW.AttachmentSlotTable = {}
|
||||||
|
ArcCW.NumAttachments = 1
|
||||||
|
|
||||||
|
for k, v in pairs(file.Find("arccw/shared/attachments/*", "LUA")) do
|
||||||
|
att = {}
|
||||||
|
shortname = string.sub(v, 1, -5)
|
||||||
|
|
||||||
|
include("arccw/shared/attachments/" .. v)
|
||||||
|
AddCSLuaFile("arccw/shared/attachments/" .. v)
|
||||||
|
|
||||||
|
ArcCW.LoadAttachmentType(att)
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Loaded " .. tostring(ArcCW.NumAttachments) .. " ArcCW attachments.")
|
||||||
|
end
|
||||||
|
|
||||||
|
function ArcCW.GetBitNecessity()
|
||||||
|
local bits = 1
|
||||||
|
|
||||||
|
bits = math.ceil(math.sqrt(ArcCW.NumAttachments))
|
||||||
|
|
||||||
|
return bits
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW_LoadAtts()
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
spawnmenu.AddCreationTab( "#spawnmenu.category.entities", function()
|
||||||
|
|
||||||
|
local ctrl = vgui.Create( "SpawnmenuContentPanel" )
|
||||||
|
ctrl:EnableSearch( "entities", "PopulateEntities" )
|
||||||
|
ctrl:CallPopulateHook( "PopulateEntities" )
|
||||||
|
|
||||||
|
return ctrl
|
||||||
|
|
||||||
|
end, "icon16/bricks.png", 20 )
|
||||||
|
end
|
||||||
|
|
||||||
|
hook.Add("PostCleanupMap", "ArcCW_ReloadAttsDebug", function()
|
||||||
|
if !GetConVar("arccw_reloadonrefresh"):GetBool() then return end
|
||||||
|
|
||||||
|
ArcCW_LoadAtts()
|
||||||
|
end)
|
26
lua/arccw/shared/sh_move.lua
Normal file
26
lua/arccw/shared/sh_move.lua
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
function ArcCW.Move(ply, mv, cmd)
|
||||||
|
local wpn = ply:GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
local s = 1
|
||||||
|
|
||||||
|
-- look, basically I made a bit of an oopsy and uh this is the best way to fix that
|
||||||
|
s = s * math.Clamp(wpn.SpeedMult * wpn:GetBuff_Mult("Mult_SpeedMult") * wpn:GetBuff_Mult("Mult_MoveSpeed"), 0, 1)
|
||||||
|
|
||||||
|
local basespd = (Vector(cmd:GetForwardMove(), cmd:GetUpMove(), cmd:GetSideMove())):Length()
|
||||||
|
basespd = math.min(basespd, mv:GetMaxClientSpeed())
|
||||||
|
|
||||||
|
if wpn:GetState() == ArcCW.STATE_SIGHTS or
|
||||||
|
wpn:GetState() == ArcCW.STATE_CUSTOMIZE then
|
||||||
|
basespd = math.min(basespd, ply:GetWalkSpeed())
|
||||||
|
s = s * math.Clamp(wpn.SightedSpeedMult * wpn:GetBuff_Mult("Mult_SightedSpeedMult") * wpn:GetBuff_Mult("Mult_SightedMoveSpeed"), 0, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
mv:SetMaxSpeed(basespd * s)
|
||||||
|
mv:SetMaxClientSpeed(basespd * s)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
hook.Add("SetupMove", "ArcCW_SetupMove", ArcCW.Move)
|
1
lua/arccw/shared/sh_physbullet2.lua
Normal file
1
lua/arccw/shared/sh_physbullet2.lua
Normal file
@ -0,0 +1 @@
|
|||||||
|
ArcCW.PhysBullets = {}
|
19
lua/arccw/shared/sh_quicknade.lua
Normal file
19
lua/arccw/shared/sh_quicknade.lua
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
-- ArcCW.QuickNadeTable = {
|
||||||
|
-- ["frag"] = {
|
||||||
|
-- ShortName = "FRAG",
|
||||||
|
-- ThrowEntity = "arccw_proj_frag",
|
||||||
|
-- ViewModel = "models/weapons/cstrike/c_eq_fraggrenade.mdl"
|
||||||
|
-- }
|
||||||
|
-- }
|
||||||
|
|
||||||
|
-- if CLIENT then
|
||||||
|
|
||||||
|
-- function ArcCW:QuickNade(index)
|
||||||
|
-- if !ArcCW.QuickNadeTable[index] then return end
|
||||||
|
|
||||||
|
-- local wpn = LocalPlayer():GetActiveWeapon()
|
||||||
|
|
||||||
|
-- if !wpn.ArcCW then return end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- end
|
11
lua/arccw/shared/sh_truenames.lua
Normal file
11
lua/arccw/shared/sh_truenames.lua
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
hook.Add("CreateTeams", "ArcCW_TrueNames", function()
|
||||||
|
if !GetConVar("arccw_truenames"):GetBool() then return end
|
||||||
|
|
||||||
|
for _, i in pairs(weapons.GetList()) do
|
||||||
|
local wpn = weapons.GetStored(i.ClassName)
|
||||||
|
|
||||||
|
if wpn.TrueName then
|
||||||
|
wpn.PrintName = wpn.TrueName
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
46
lua/autorun/arccw_autorun.lua
Normal file
46
lua/autorun/arccw_autorun.lua
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
-- the main object
|
||||||
|
ArcCW = {}
|
||||||
|
|
||||||
|
ArcCWInstalled = true
|
||||||
|
|
||||||
|
ArcCW.GenerateAttEntities = true
|
||||||
|
|
||||||
|
for _, v in pairs(file.Find("arccw/shared/*", "LUA")) do
|
||||||
|
include("arccw/shared/" .. v)
|
||||||
|
AddCSLuaFile("arccw/shared/" .. v)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, v in pairs(file.Find("arccw/client/*", "LUA")) do
|
||||||
|
AddCSLuaFile("arccw/client/" .. v)
|
||||||
|
if CLIENT then
|
||||||
|
include("arccw/client/" .. v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER or game.SinglePlayer() then
|
||||||
|
for _, v in pairs(file.Find("arccw/server/*", "LUA")) do
|
||||||
|
include("arccw/server/" .. v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if you want to override arccw functions, put your override files in the arccw/mods directory so it will be guaranteed to override the base
|
||||||
|
|
||||||
|
for _, v in pairs(file.Find("arccw/mods/shared/*", "LUA")) do
|
||||||
|
include("arccw/mods/shared/" .. v)
|
||||||
|
AddCSLuaFile("arccw/mods/shared/" .. v)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, v in pairs(file.Find("arccw/mods/client/*", "LUA")) do
|
||||||
|
AddCSLuaFile("arccw/mods/client/" .. v)
|
||||||
|
if CLIENT then
|
||||||
|
include("arccw/mods/client/" .. v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER or game.SinglePlayer() then
|
||||||
|
for _, v in pairs(file.Find("arccw/mods/server/*", "LUA")) do
|
||||||
|
include("arccw/mods/server/" .. v)
|
||||||
|
end
|
||||||
|
end
|
77
lua/effects/arccw_flashexplosion.lua
Normal file
77
lua/effects/arccw_flashexplosion.lua
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
local images_smoke = {"particle/smokesprites_0001", "particle/smokesprites_0002", "particle/smokesprites_0003", "particle/smokesprites_0004", "particle/smokesprites_0005", "particle/smokesprites_0006", "particle/smokesprites_0007", "particle/smokesprites_0008", "particle/smokesprites_0009", "particle/smokesprites_0010", "particle/smokesprites_0011", "particle/smokesprites_0012", "particle/smokesprites_0013", "particle/smokesprites_0014", "particle/smokesprites_0015", "particle/smokesprites_0016"}
|
||||||
|
|
||||||
|
local function TableRandomChoice(tbl)
|
||||||
|
return tbl[math.random(#tbl)]
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Init(data)
|
||||||
|
self.Origin = data:GetOrigin()
|
||||||
|
|
||||||
|
util.Decal("FadingScorch", self.Origin, self.Origin - Vector(0, 0, 16))
|
||||||
|
|
||||||
|
local emitter = ParticleEmitter( self.Origin + Vector( 0, 0, 16 ) )
|
||||||
|
|
||||||
|
for i = 0,5 do
|
||||||
|
local particle = emitter:Add( TableRandomChoice(images_smoke) , self.Origin )
|
||||||
|
local scol = math.Rand( 200, 225 )
|
||||||
|
|
||||||
|
particle:SetVelocity( 250 * VectorRand() )
|
||||||
|
particle:SetDieTime( math.Rand(1.5, 5) )
|
||||||
|
particle:SetStartAlpha( 255 )
|
||||||
|
particle:SetEndAlpha( 0 )
|
||||||
|
particle:SetStartSize( math.Rand(100,200) )
|
||||||
|
particle:SetEndSize( math.Rand(300,400) )
|
||||||
|
particle:SetRoll( math.Rand(0,360) )
|
||||||
|
particle:SetRollDelta( math.Rand(-1,1) )
|
||||||
|
particle:SetColor( scol,scol,scol )
|
||||||
|
particle:SetAirResistance( 100 )
|
||||||
|
particle:SetGravity( Vector( math.Rand(-30,30) ,math.Rand(-30,30),math.Rand(10,40)) )
|
||||||
|
particle:SetLighting( true )
|
||||||
|
particle:SetCollide( true )
|
||||||
|
particle:SetBounce( 0.5 )
|
||||||
|
end
|
||||||
|
|
||||||
|
local particle = emitter:Add( "sprites/heatwave", self.Origin )
|
||||||
|
particle:SetAirResistance( 0 )
|
||||||
|
particle:SetDieTime( 1.5 )
|
||||||
|
particle:SetStartAlpha( 255 )
|
||||||
|
particle:SetEndAlpha( 255 )
|
||||||
|
particle:SetStartSize( 250 )
|
||||||
|
particle:SetEndSize( 0 )
|
||||||
|
particle:SetRoll( math.Rand(180,480) )
|
||||||
|
particle:SetRollDelta( math.Rand(-5,5) )
|
||||||
|
particle:SetColor( 255, 255, 255 )
|
||||||
|
|
||||||
|
local fire = emitter:Add( "particle/fire", self.Origin )
|
||||||
|
fire:SetAirResistance( 0 )
|
||||||
|
fire:SetDieTime( 0.1 )
|
||||||
|
fire:SetStartAlpha( 255 )
|
||||||
|
fire:SetEndAlpha( 0 )
|
||||||
|
fire:SetEndSize( 0 )
|
||||||
|
fire:SetStartSize( 800 )
|
||||||
|
fire:SetRoll( math.Rand(180,480) )
|
||||||
|
fire:SetRollDelta( math.Rand(-1,1) )
|
||||||
|
fire:SetColor( 255, 255, 255 )
|
||||||
|
|
||||||
|
local light = DynamicLight(self:EntIndex())
|
||||||
|
if (light) then
|
||||||
|
light.Pos = self.Origin
|
||||||
|
light.r = 255
|
||||||
|
light.g = 255
|
||||||
|
light.b = 255
|
||||||
|
light.Brightness = 9
|
||||||
|
light.Decay = 2500
|
||||||
|
light.Size = 512
|
||||||
|
light.DieTime = CurTime() + 0.1
|
||||||
|
end
|
||||||
|
|
||||||
|
emitter:Finish()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Think()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Render()
|
||||||
|
end
|
79
lua/effects/arccw_incendiaryround.lua
Normal file
79
lua/effects/arccw_incendiaryround.lua
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
local images_muzzle = {"effects/muzzleflash1", "effects/muzzleflash2", "effects/muzzleflash3", "effects/muzzleflash4"}
|
||||||
|
local images_smoke = {"particle/smokesprites_0001", "particle/smokesprites_0002", "particle/smokesprites_0003", "particle/smokesprites_0004", "particle/smokesprites_0005", "particle/smokesprites_0006", "particle/smokesprites_0007", "particle/smokesprites_0008", "particle/smokesprites_0009", "particle/smokesprites_0010", "particle/smokesprites_0011", "particle/smokesprites_0012", "particle/smokesprites_0013", "particle/smokesprites_0014", "particle/smokesprites_0015", "particle/smokesprites_0016"}
|
||||||
|
|
||||||
|
local function TableRandomChoice(tbl)
|
||||||
|
return tbl[math.random(#tbl)]
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Init(data)
|
||||||
|
self.Origin = data:GetOrigin()
|
||||||
|
|
||||||
|
local emitter = ParticleEmitter( self.Origin + Vector( 0, 0, 16 ) )
|
||||||
|
|
||||||
|
for i = 0,3 do
|
||||||
|
local particle = emitter:Add( TableRandomChoice(images_smoke) , self.Origin )
|
||||||
|
local scol = math.Rand( 200, 225 )
|
||||||
|
|
||||||
|
particle:SetVelocity( 50 * VectorRand() )
|
||||||
|
particle:SetDieTime( math.Rand(0.2, 0.5) )
|
||||||
|
particle:SetStartAlpha( 255 )
|
||||||
|
particle:SetEndAlpha( 0 )
|
||||||
|
particle:SetStartSize( math.Rand(20,30) )
|
||||||
|
particle:SetEndSize( math.Rand(50,75) )
|
||||||
|
particle:SetRoll( math.Rand(0,360) )
|
||||||
|
particle:SetRollDelta( math.Rand(-1,1) )
|
||||||
|
particle:SetColor( scol,scol,scol )
|
||||||
|
particle:SetAirResistance( 100 )
|
||||||
|
particle:SetGravity( Vector( math.Rand(-30,30) ,math.Rand(-30,30),math.Rand(10,40)) )
|
||||||
|
particle:SetLighting( true )
|
||||||
|
particle:SetCollide( true )
|
||||||
|
particle:SetBounce( 0.5 )
|
||||||
|
end
|
||||||
|
|
||||||
|
local particle = emitter:Add( "sprites/heatwave", self.Origin )
|
||||||
|
particle:SetAirResistance( 0 )
|
||||||
|
particle:SetDieTime( 0.5 )
|
||||||
|
particle:SetStartAlpha( 255 )
|
||||||
|
particle:SetEndAlpha( 255 )
|
||||||
|
particle:SetStartSize( 100 )
|
||||||
|
particle:SetEndSize( 0 )
|
||||||
|
particle:SetRoll( math.Rand(180,480) )
|
||||||
|
particle:SetRollDelta( math.Rand(-5,5) )
|
||||||
|
particle:SetColor( 255, 255, 255 )
|
||||||
|
|
||||||
|
for i = 0, 2 do
|
||||||
|
local fire = emitter:Add( TableRandomChoice(images_muzzle), self.Origin )
|
||||||
|
fire:SetVelocity(VectorRand() * 100)
|
||||||
|
fire:SetAirResistance( 0 )
|
||||||
|
fire:SetDieTime( 0.25 )
|
||||||
|
fire:SetStartAlpha( 255 )
|
||||||
|
fire:SetEndAlpha( 0 )
|
||||||
|
fire:SetEndSize( 0 )
|
||||||
|
fire:SetStartSize( 50 )
|
||||||
|
fire:SetRoll( math.Rand(180,480) )
|
||||||
|
fire:SetRollDelta( math.Rand(-1,1) )
|
||||||
|
fire:SetColor( 255, 255, 255 )
|
||||||
|
end
|
||||||
|
|
||||||
|
local light = DynamicLight(self:EntIndex())
|
||||||
|
if (light) then
|
||||||
|
light.Pos = self.Origin
|
||||||
|
light.r = 255
|
||||||
|
light.g = 206
|
||||||
|
light.b = 122
|
||||||
|
light.Brightness = 5
|
||||||
|
light.Decay = 2500
|
||||||
|
light.Size = 256
|
||||||
|
light.DieTime = CurTime() + 0.1
|
||||||
|
end
|
||||||
|
|
||||||
|
emitter:Finish()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Think()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Render()
|
||||||
|
end
|
57
lua/effects/arccw_muzzleeffect.lua
Normal file
57
lua/effects/arccw_muzzleeffect.lua
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
function EFFECT:Init(data)
|
||||||
|
local pos = data:GetOrigin()
|
||||||
|
local wpn = data:GetEntity()
|
||||||
|
|
||||||
|
if !IsValid(wpn) then return end
|
||||||
|
|
||||||
|
local muzzle = wpn:GetBuff_Override("Override_MuzzleEffect") or wpn.MuzzleEffect
|
||||||
|
|
||||||
|
if wpn:GetNWBool("ubgl", false) then
|
||||||
|
muzzle = wpn:GetBuff_Override("UBGL_MuzzleEffect") or muzzle
|
||||||
|
end
|
||||||
|
|
||||||
|
local att = data:GetAttachment() or 1
|
||||||
|
|
||||||
|
if !muzzle then return end
|
||||||
|
|
||||||
|
local wm = false
|
||||||
|
|
||||||
|
if (LocalPlayer():ShouldDrawLocalPlayer() or wpn.Owner != LocalPlayer()) and !wpn.AlwaysWM then
|
||||||
|
wm = true
|
||||||
|
att = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if wpn.Owner != LocalPlayer() then
|
||||||
|
if !GetConVar("arccw_muzzleeffects"):GetBool() then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mdl = wpn:GetMuzzleDevice(wm)
|
||||||
|
|
||||||
|
ParticleEffectAttach(muzzle, PATTACH_POINT_FOLLOW, mdl, att)
|
||||||
|
|
||||||
|
pos = (mdl:GetAttachment(att) or {}).Pos
|
||||||
|
|
||||||
|
if !pos then return end
|
||||||
|
|
||||||
|
if !wpn:GetBuff_Override("Silencer") then
|
||||||
|
local light = DynamicLight(self:EntIndex())
|
||||||
|
if (light) then
|
||||||
|
light.Pos = pos
|
||||||
|
light.r = 244
|
||||||
|
light.g = 209
|
||||||
|
light.b = 66
|
||||||
|
light.Brightness = 2
|
||||||
|
light.Decay = 2500
|
||||||
|
light.Size = 256
|
||||||
|
light.DieTime = CurTime() + 0.1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Think()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Render()
|
||||||
|
return false
|
||||||
|
end
|
141
lua/effects/arccw_shelleffect.lua
Normal file
141
lua/effects/arccw_shelleffect.lua
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
|
||||||
|
EFFECT.Sounds = {}
|
||||||
|
EFFECT.Pitch = 90
|
||||||
|
EFFECT.Scale = 1.5
|
||||||
|
EFFECT.PhysScale = 1
|
||||||
|
EFFECT.Model = "models/shells/shell_57.mdl"
|
||||||
|
EFFECT.Material = nil
|
||||||
|
EFFECT.JustOnce = true
|
||||||
|
EFFECT.AlreadyPlayedSound = false
|
||||||
|
EFFECT.ShellTime = 1
|
||||||
|
|
||||||
|
EFFECT.SpawnTime = 0
|
||||||
|
|
||||||
|
function EFFECT:Init(data)
|
||||||
|
|
||||||
|
local att = data:GetAttachment()
|
||||||
|
local ent = data:GetEntity()
|
||||||
|
local mag = data:GetMagnitude()
|
||||||
|
|
||||||
|
local mdl = LocalPlayer():GetViewModel()
|
||||||
|
|
||||||
|
if LocalPlayer():ShouldDrawLocalPlayer() then
|
||||||
|
mdl = ent
|
||||||
|
end
|
||||||
|
|
||||||
|
if !IsValid(ent) then return end
|
||||||
|
|
||||||
|
if ent.Owner != LocalPlayer() then
|
||||||
|
mdl = ent
|
||||||
|
end
|
||||||
|
|
||||||
|
if ent.Owner != LocalPlayer() then
|
||||||
|
if !GetConVar("arccw_shelleffects"):GetBool() then self:Remove() return end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !mdl or !IsValid(mdl) then return end
|
||||||
|
|
||||||
|
if !mdl:GetAttachment(att) then return end
|
||||||
|
|
||||||
|
local origin, ang = mdl:GetAttachment(att).Pos, mdl:GetAttachment(att).Ang
|
||||||
|
|
||||||
|
ang:RotateAroundAxis(ang:Right(), -90 + ent.ShellRotate)
|
||||||
|
|
||||||
|
ang:RotateAroundAxis(ang:Right(), (ent.ShellRotateAngle or Angle(0, 0, 0))[1])
|
||||||
|
ang:RotateAroundAxis(ang:Up(), (ent.ShellRotateAngle or Angle(0, 0, 0))[2])
|
||||||
|
ang:RotateAroundAxis(ang:Forward(), (ent.ShellRotateAngle or Angle(0, 0, 0))[3])
|
||||||
|
|
||||||
|
local dir = ang:Up()
|
||||||
|
|
||||||
|
if ent then
|
||||||
|
self.Model = ent.ShellModel
|
||||||
|
self.Material = ent.ShellMaterial
|
||||||
|
self.Scale = ent.ShellScale or 1
|
||||||
|
self.PhysScale = ent.ShellPhysScale or 1
|
||||||
|
self.Pitch = ent.ShellPitch or 100
|
||||||
|
self.Sounds = ent.ShellSounds
|
||||||
|
self.ShellTime = ent.ShellTime
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetPos(origin)
|
||||||
|
self:SetModel(self.Model)
|
||||||
|
self:SetModelScale(self.Scale)
|
||||||
|
self:DrawShadow(true)
|
||||||
|
self:SetAngles(ang)
|
||||||
|
|
||||||
|
if self.Material then
|
||||||
|
self:SetMaterial(self.Material)
|
||||||
|
end
|
||||||
|
|
||||||
|
local pb_vert = 2 * self.Scale * self.PhysScale
|
||||||
|
local pb_hor = 0.5 * self.Scale * self.PhysScale
|
||||||
|
|
||||||
|
self:PhysicsInitBox(Vector(-pb_vert,-pb_hor,-pb_hor), Vector(pb_vert,pb_hor,pb_hor))
|
||||||
|
|
||||||
|
self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE_DEBRIS)
|
||||||
|
|
||||||
|
local phys = self:GetPhysicsObject()
|
||||||
|
|
||||||
|
local plyvel = Vector(0, 0, 0)
|
||||||
|
|
||||||
|
if IsValid(ent.Owner) then
|
||||||
|
plyvel = ent.Owner:GetAbsVelocity()
|
||||||
|
end
|
||||||
|
|
||||||
|
phys:Wake()
|
||||||
|
phys:SetDamping(0, 0)
|
||||||
|
phys:SetMass(1)
|
||||||
|
phys:SetMaterial("gmod_silent")
|
||||||
|
|
||||||
|
phys:SetVelocity((dir * mag * math.Rand(1, 2)) + plyvel)
|
||||||
|
phys:AddAngleVelocity(VectorRand() * 400)
|
||||||
|
|
||||||
|
self.HitPitch = self.Pitch + math.Rand(-5,5)
|
||||||
|
|
||||||
|
local emitter = ParticleEmitter(origin)
|
||||||
|
|
||||||
|
for i = 1, 3 do
|
||||||
|
local particle = emitter:Add("particles/smokey", origin + (dir * 2))
|
||||||
|
|
||||||
|
if (particle) then
|
||||||
|
particle:SetVelocity(VectorRand() * 10 + (dir * i * math.Rand(48, 64)) + plyvel)
|
||||||
|
particle:SetLifeTime(0)
|
||||||
|
particle:SetDieTime(math.Rand(0.05, 0.15))
|
||||||
|
particle:SetStartAlpha(math.Rand(40, 60))
|
||||||
|
particle:SetEndAlpha(0)
|
||||||
|
particle:SetStartSize(0)
|
||||||
|
particle:SetEndSize(math.Rand(18, 24))
|
||||||
|
particle:SetRoll(math.rad(math.Rand(0, 360)))
|
||||||
|
particle:SetRollDelta(math.Rand(-1, 1))
|
||||||
|
particle:SetLighting(true)
|
||||||
|
particle:SetAirResistance(96)
|
||||||
|
particle:SetGravity(Vector(-7, 3, 20))
|
||||||
|
particle:SetColor(150, 150, 150)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.SpawnTime = CurTime()
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:PhysicsCollide()
|
||||||
|
if self.AlreadyPlayedSound and self.JustOnce then return end
|
||||||
|
|
||||||
|
sound.Play(self.Sounds[math.random(#self.Sounds)], self:GetPos(), 65, self.HitPitch, 1)
|
||||||
|
|
||||||
|
self.AlreadyPlayedSound = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Think()
|
||||||
|
if (self.SpawnTime + self.ShellTime) <= CurTime() then
|
||||||
|
self:SetRenderFX( kRenderFxFadeFast )
|
||||||
|
if (self.SpawnTime + self.ShellTime + 1) <= CurTime() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function EFFECT:Render()
|
||||||
|
if !IsValid(self) then return end
|
||||||
|
self:DrawModel()
|
||||||
|
end
|
235
lua/entities/arccw_ammo.lua
Normal file
235
lua/entities/arccw_ammo.lua
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Type = "anim"
|
||||||
|
ENT.Base = "base_gmodentity"
|
||||||
|
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||||
|
|
||||||
|
ENT.PrintName = "Base Ammo"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
ENT.ArcCW_Ammo = true
|
||||||
|
|
||||||
|
ENT.Spawnable = false
|
||||||
|
ENT.Model = "models/items/sniper_round_box.mdl"
|
||||||
|
ENT.MaxHealth = 40
|
||||||
|
ENT.Scale = 1
|
||||||
|
|
||||||
|
ENT.AmmoType = "SniperPenetratedRound"
|
||||||
|
ENT.AmmoCount = 5
|
||||||
|
ENT.DetonationDamage = 10 -- Per-round damage
|
||||||
|
ENT.DetonationRadius = 256
|
||||||
|
ENT.DetonationSound = "weapons/arccw/glock18/glock18-1.wav" -- string or table
|
||||||
|
|
||||||
|
ENT.ShellModel = "models/shells/shell_9mm.mdl"
|
||||||
|
ENT.ShellScale = 1.5
|
||||||
|
|
||||||
|
ENT.ResistanceMult = {
|
||||||
|
[DMG_BURN] = 5,
|
||||||
|
[DMG_BLAST] = 2,
|
||||||
|
[DMG_BULLET] = 0.5,
|
||||||
|
[DMG_BUCKSHOT] = 0.5,
|
||||||
|
[DMG_CLUB] = 0.25,
|
||||||
|
[DMG_SLASH] = 0.25,
|
||||||
|
[DMG_CRUSH] = 0.25,
|
||||||
|
}
|
||||||
|
|
||||||
|
function ENT:Initialize()
|
||||||
|
self:SetModel(self.Model)
|
||||||
|
self:SetHealth(math.max(math.ceil(self.MaxHealth * GetConVar("arccw_mult_ammohealth"):GetFloat()), 1))
|
||||||
|
self.AmmoCount = self.AmmoCount * GetConVar("arccw_mult_ammoamount"):GetFloat()
|
||||||
|
self.MaxAmmoCount = self.AmmoCount
|
||||||
|
|
||||||
|
if self.Scale ~= 1 then
|
||||||
|
self:SetModelScale(self.Scale)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:SkinCount() > 1 and math.random() <= GetConVar("arccw_ammo_rareskin"):GetFloat() then
|
||||||
|
self:SetSkin(math.random(1, self:SkinCount() - 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
|
||||||
|
self:PhysicsInit(SOLID_VPHYSICS)
|
||||||
|
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||||
|
self:SetSolid(SOLID_VPHYSICS)
|
||||||
|
self:SetCollisionGroup(COLLISION_GROUP_WEAPON)
|
||||||
|
self:SetUseType(SIMPLE_USE)
|
||||||
|
self:PhysWake()
|
||||||
|
|
||||||
|
self:SetTrigger(true) -- Enables Touch() to be called even when not colliding
|
||||||
|
if GetConVar("arccw_ammo_largetrigger"):GetBool() then
|
||||||
|
self:UseTriggerBounds(true, 24)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:ApplyAmmo(ply)
|
||||||
|
if self.USED then return end
|
||||||
|
self.USED = true -- Prevent multiple uses
|
||||||
|
ply:GiveAmmo(self.AmmoCount, self.AmmoType)
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:DetonateRound()
|
||||||
|
local count = math.Clamp(math.random(1, self.MaxAmmoCount / 5), 1, self.AmmoCount)
|
||||||
|
-- Default function
|
||||||
|
self:FireBullets({
|
||||||
|
Attacker = self.Burner,
|
||||||
|
Damage = self.DetonationDamage,
|
||||||
|
Force = self.DetonationDamage / 5,
|
||||||
|
Num = count,
|
||||||
|
AmmoType = self.AmmoType,
|
||||||
|
Src = self:WorldSpaceCenter(),
|
||||||
|
Dir = self:GetUp(),
|
||||||
|
Spread = Vector(3, 3, 0),
|
||||||
|
IgnoreEntity = self
|
||||||
|
})
|
||||||
|
self.AmmoCount = self.AmmoCount - count
|
||||||
|
|
||||||
|
self:GetPhysicsObject():AddVelocity(VectorRand() * math.random(30, 50) * self:GetPhysicsObject():GetMass())
|
||||||
|
self:GetPhysicsObject():AddAngleVelocity(VectorRand() * math.random(60, 300))
|
||||||
|
|
||||||
|
if self.DetonationSound then
|
||||||
|
self:EmitSound(istable(self.DetonationSound) and table.Random(self.DetonationSound) or self.DetonationSound)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Detonate(wet, attacker)
|
||||||
|
if wet then
|
||||||
|
self:FireBullets({
|
||||||
|
Attacker = attacker,
|
||||||
|
Damage = self.DetonationDamage,
|
||||||
|
Force = self.DetonationDamage / 5,
|
||||||
|
Num = math.max(self.AmmoCount, 50),
|
||||||
|
AmmoType = self.AmmoType,
|
||||||
|
Src = self:WorldSpaceCenter(),
|
||||||
|
Dir = self:GetUp(),
|
||||||
|
Spread = Vector(3, 3, 0),
|
||||||
|
IgnoreEntity = self
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local e = EffectData()
|
||||||
|
e:SetOrigin(self:GetPos())
|
||||||
|
util.Effect("Explosion", e)
|
||||||
|
|
||||||
|
util.BlastDamage(self, attacker, self:GetPos(), self.DetonationRadius, self.DetonationDamage * (wet and 0.5 or 1))
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
|
||||||
|
function ENT:Use(ply)
|
||||||
|
if !ply:IsPlayer() then return end
|
||||||
|
self:ApplyAmmo(ply)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ENT:Touch(ply)
|
||||||
|
if !ply:IsPlayer() or !GetConVar("arccw_ammo_autopickup"):GetBool() then return end
|
||||||
|
self:ApplyAmmo(ply)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Burn(attacker)
|
||||||
|
self.Burning = true
|
||||||
|
self.Burner = attacker
|
||||||
|
self:Ignite(30)
|
||||||
|
self:SetHealth(-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:OnTakeDamage(dmginfo)
|
||||||
|
|
||||||
|
if self:Health() <= 0 or self.USED then return end
|
||||||
|
|
||||||
|
self:TakePhysicsDamage(dmginfo)
|
||||||
|
self:SetHealth(self:Health() - dmginfo:GetDamage())
|
||||||
|
|
||||||
|
if self:Health() <= 0 then
|
||||||
|
|
||||||
|
self.USED = true
|
||||||
|
|
||||||
|
local cvar = GetConVar("arccw_ammo_detonationmode"):GetInt()
|
||||||
|
|
||||||
|
if cvar == -1 or (!GetConVar("arccw_ammo_chaindet"):GetBool() and dmginfo:GetInflictor().ArcCW_Ammo) then
|
||||||
|
-- Go quietly
|
||||||
|
local e = EffectData()
|
||||||
|
e:SetOrigin(self:GetPos())
|
||||||
|
e:SetMagnitude(8)
|
||||||
|
e:SetScale(2)
|
||||||
|
util.Effect("Sparks", e)
|
||||||
|
self:EmitSound("physics/cardboard/cardboard_box_break2.wav", 80, 120)
|
||||||
|
self:Remove()
|
||||||
|
elseif cvar == 2 and (math.random() <= 0.25 or dmginfo:IsDamageType(DMG_BURN)) then
|
||||||
|
-- Fancy ammobox burning
|
||||||
|
self:Burn(dmginfo:GetAttacker())
|
||||||
|
else
|
||||||
|
-- Plain old explosion
|
||||||
|
self:Detonate(cvar >= 1, dmginfo:GetAttacker())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Think()
|
||||||
|
if self.Burning then
|
||||||
|
|
||||||
|
if self.AmmoCount <= 0 then
|
||||||
|
self:Detonate(false, IsValid(self.Burner) and self.Burner or self)
|
||||||
|
else
|
||||||
|
self:DetonateRound()
|
||||||
|
end
|
||||||
|
|
||||||
|
self:NextThink(CurTime() + math.random() * 0.3 + 0.2)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Do it during the hook so that hit damage numbers show up properly (yes, I am _that_ pedantic)
|
||||||
|
hook.Add("EntityTakeDamage", "ArcCW_Ammo", function(ent, dmginfo)
|
||||||
|
if ent.ArcCW_Ammo then
|
||||||
|
if GetConVar("arccw_mult_ammohealth"):GetFloat() < 0 then
|
||||||
|
dmginfo:ScaleDamage(0)
|
||||||
|
elseif ent.ResistanceMult then
|
||||||
|
-- Only apply one multiplier, and prioritize larger ones
|
||||||
|
for k, v in SortedPairsByValue(ent.ResistanceMult, true) do if dmginfo:IsDamageType(k) then dmginfo:ScaleDamage(v) break end end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
elseif CLIENT then
|
||||||
|
|
||||||
|
function ENT:Draw()
|
||||||
|
self:DrawModel()
|
||||||
|
|
||||||
|
if !GetConVar("arccw_2d3d"):GetBool() then return end
|
||||||
|
|
||||||
|
if (EyePos() - self:GetPos()):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, (self:OBBMaxs().z - self:OBBMins().z) * 0.5 + 8) , ang, 0.1)
|
||||||
|
surface.SetFont("ArcCW_32_Unscaled")
|
||||||
|
|
||||||
|
local w = surface.GetTextSize(self.PrintName)
|
||||||
|
|
||||||
|
surface.SetTextPos(-w / 2, 0)
|
||||||
|
surface.SetTextColor(255, 255, 255, 255)
|
||||||
|
surface.DrawText(self.PrintName)
|
||||||
|
|
||||||
|
if self.AmmoCount > 1 then
|
||||||
|
w = surface.GetTextSize("×" .. self.AmmoCount)
|
||||||
|
surface.SetTextPos(-w / 2, 25)
|
||||||
|
surface.DrawText("×" .. self.AmmoCount)
|
||||||
|
end
|
||||||
|
|
||||||
|
--surface.SetDrawColor(255, 255, 255)
|
||||||
|
--surface.SetMaterial(self.Icon or defaulticon)
|
||||||
|
--local iw = 64
|
||||||
|
--surface.DrawTexturedRect(-iw / 2, -iw - 8, iw, iw)
|
||||||
|
cam.End3D2D()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
17
lua/entities/arccw_ammo_357.lua
Normal file
17
lua/entities/arccw_ammo_357.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||||
|
|
||||||
|
ENT.PrintName = "Magnum Ammo"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/magnum_ammo.mdl"
|
||||||
|
|
||||||
|
ENT.AmmoType = "357"
|
||||||
|
ENT.AmmoCount = 12
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 50
|
||||||
|
ENT.DetonationRadius = 128
|
||||||
|
ENT.DetonationSound = "weapons/arccw/deagle/deagle-1.wav"
|
18
lua/entities/arccw_ammo_357_large.lua
Normal file
18
lua/entities/arccw_ammo_357_large.lua
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||||
|
|
||||||
|
ENT.PrintName = "Magnum Ammo (Large)"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/magnum_ammo.mdl"
|
||||||
|
|
||||||
|
ENT.AmmoType = "357"
|
||||||
|
ENT.AmmoCount = 60
|
||||||
|
ENT.Scale = 1.5
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 50
|
||||||
|
ENT.DetonationRadius = 128
|
||||||
|
ENT.DetonationSound = "weapons/arccw/deagle/deagle-1.wav"
|
17
lua/entities/arccw_ammo_ar2.lua
Normal file
17
lua/entities/arccw_ammo_ar2.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||||
|
|
||||||
|
ENT.PrintName = "Rifle Ammo"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/rifle_ammo.mdl"
|
||||||
|
|
||||||
|
ENT.AmmoType = "ar2"
|
||||||
|
ENT.AmmoCount = 30
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 50
|
||||||
|
ENT.DetonationRadius = 256
|
||||||
|
ENT.DetonationSound = "weapons/arccw/ak47/ak47-1.wav"
|
18
lua/entities/arccw_ammo_ar2_large.lua
Normal file
18
lua/entities/arccw_ammo_ar2_large.lua
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||||
|
|
||||||
|
ENT.PrintName = "Rifle Ammo (Large)"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/rifle_ammo.mdl"
|
||||||
|
ENT.Scale = 1.5
|
||||||
|
|
||||||
|
ENT.AmmoType = "ar2"
|
||||||
|
ENT.AmmoCount = 150
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 50
|
||||||
|
ENT.DetonationRadius = 256
|
||||||
|
ENT.DetonationSound = "weapons/arccw/ak47/ak47-1.wav"
|
16
lua/entities/arccw_ammo_buckshot.lua
Normal file
16
lua/entities/arccw_ammo_buckshot.lua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Shotgun Ammo"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/shotgun_ammo.mdl"
|
||||||
|
|
||||||
|
ENT.AmmoType = "buckshot"
|
||||||
|
ENT.AmmoCount = 20
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 80
|
||||||
|
ENT.DetonationRadius = 128
|
||||||
|
ENT.DetonationSound = "weapons/shotgun/shotgun_fire6.wav"
|
17
lua/entities/arccw_ammo_buckshot_large.lua
Normal file
17
lua/entities/arccw_ammo_buckshot_large.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Shotgun Ammo (Large)"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/shotgun_ammo.mdl"
|
||||||
|
ENT.Scale = 1.5
|
||||||
|
|
||||||
|
ENT.AmmoType = "buckshot"
|
||||||
|
ENT.AmmoCount = 100
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 80
|
||||||
|
ENT.DetonationRadius = 128
|
||||||
|
ENT.DetonationSound = "weapons/shotgun/shotgun_fire6.wav"
|
16
lua/entities/arccw_ammo_pistol.lua
Normal file
16
lua/entities/arccw_ammo_pistol.lua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Pistol Ammo"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/pistol_ammo.mdl"
|
||||||
|
|
||||||
|
ENT.AmmoType = "pistol"
|
||||||
|
ENT.AmmoCount = 40
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 10
|
||||||
|
ENT.DetonationRadius = 256
|
||||||
|
ENT.DetonationSound = "weapons/arccw/glock18/glock18-1.wav"
|
17
lua/entities/arccw_ammo_pistol_large.lua
Normal file
17
lua/entities/arccw_ammo_pistol_large.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Pistol Ammo (Large)"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/pistol_ammo.mdl"
|
||||||
|
ENT.Scale = 1.5
|
||||||
|
|
||||||
|
ENT.AmmoType = "pistol"
|
||||||
|
ENT.AmmoCount = 200
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 10
|
||||||
|
ENT.DetonationRadius = 256
|
||||||
|
ENT.DetonationSound = "weapons/arccw/glock18/glock18-1.wav"
|
16
lua/entities/arccw_ammo_smg1.lua
Normal file
16
lua/entities/arccw_ammo_smg1.lua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Carbine Ammo"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/smg_ammo.mdl"
|
||||||
|
|
||||||
|
ENT.AmmoType = "smg1"
|
||||||
|
ENT.AmmoCount = 60
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 30
|
||||||
|
ENT.DetonationRadius = 256
|
||||||
|
ENT.DetonationSound = "weapons/arccw/galilar/galil-1.wav"
|
39
lua/entities/arccw_ammo_smg1_grenade.lua
Normal file
39
lua/entities/arccw_ammo_smg1_grenade.lua
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Rifle Grenade"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/Items/AR2_Grenade.mdl"
|
||||||
|
ENT.Health = 15
|
||||||
|
|
||||||
|
ENT.AmmoType = "smg1_grenade"
|
||||||
|
ENT.AmmoCount = 1
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 50 -- Per-round damage
|
||||||
|
ENT.DetonationRadius = 300
|
||||||
|
|
||||||
|
function ENT:DetonateRound(attacker)
|
||||||
|
local nade = ents.Create("arccw_gl_ammodet")
|
||||||
|
nade:SetPos(self:GetPos())
|
||||||
|
nade:SetAngles(self:GetAngles() + AngleRand(-10, 10))
|
||||||
|
nade:Spawn()
|
||||||
|
nade:GetPhysicsObject():AddVelocity(self:GetVelocity() + self:GetForward() * math.random(500, 2000))
|
||||||
|
nade:SetOwner(attacker or self.Burner)
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Detonate(wet, attacker)
|
||||||
|
if wet then
|
||||||
|
self:DetonateRound(attacker)
|
||||||
|
else
|
||||||
|
local e = EffectData()
|
||||||
|
e:SetOrigin(self:GetPos())
|
||||||
|
util.Effect("Explosion", e)
|
||||||
|
|
||||||
|
util.BlastDamage(self, attacker, self:GetPos(), self.DetonationRadius, self.DetonationDamage)
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
end
|
48
lua/entities/arccw_ammo_smg1_grenade_large.lua
Normal file
48
lua/entities/arccw_ammo_smg1_grenade_large.lua
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Rifle Grenade Box"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/riflegrenade_ammo.mdl"
|
||||||
|
ENT.Health = 70
|
||||||
|
|
||||||
|
ENT.AmmoType = "smg1_grenade"
|
||||||
|
ENT.AmmoCount = 5
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 100 -- Per-round damage
|
||||||
|
ENT.DetonationRadius = 300
|
||||||
|
|
||||||
|
function ENT:DetonateRound(attacker)
|
||||||
|
local nade = ents.Create("arccw_gl_ammodet")
|
||||||
|
nade:SetPos(self:GetPos())
|
||||||
|
local v = self:GetUp():Angle() + AngleRand(-60, 60)
|
||||||
|
nade:SetAngles(v)
|
||||||
|
nade:Spawn()
|
||||||
|
nade:GetPhysicsObject():AddVelocity(self:GetVelocity() + self:GetForward() * math.random(2000, 3000))
|
||||||
|
nade:SetOwner(attacker or self.Burner)
|
||||||
|
|
||||||
|
self.AmmoCount = self.AmmoCount - 1
|
||||||
|
|
||||||
|
self:GetPhysicsObject():AddVelocity(VectorRand() * math.random(5, 10) * self:GetPhysicsObject():GetMass())
|
||||||
|
self:GetPhysicsObject():AddAngleVelocity(VectorRand() * math.random(60, 300))
|
||||||
|
|
||||||
|
self:EmitSound("weapons/ar2/ar2_altfire.wav", 80, 150)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Detonate(wet, attacker)
|
||||||
|
if wet then
|
||||||
|
for i = 1, math.random(1, 3) do
|
||||||
|
self:DetonateRound(attacker)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local e = EffectData()
|
||||||
|
e:SetOrigin(self:GetPos())
|
||||||
|
util.Effect("Explosion", e)
|
||||||
|
|
||||||
|
util.BlastDamage(self, attacker, self:GetPos(), self.DetonationRadius, self.DetonationDamage * (wet and 1 or 2))
|
||||||
|
self:Remove()
|
||||||
|
end
|
17
lua/entities/arccw_ammo_smg1_large.lua
Normal file
17
lua/entities/arccw_ammo_smg1_large.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Carbine Ammo (Large)"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/smg_ammo.mdl"
|
||||||
|
ENT.Scale = 1.5
|
||||||
|
|
||||||
|
ENT.AmmoType = "smg1"
|
||||||
|
ENT.AmmoCount = 300
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 30
|
||||||
|
ENT.DetonationRadius = 256
|
||||||
|
ENT.DetonationSound = "weapons/arccw/galilar/galil-1.wav"
|
17
lua/entities/arccw_ammo_sniper.lua
Normal file
17
lua/entities/arccw_ammo_sniper.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Sniper Ammo"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/sniper_ammo.mdl"
|
||||||
|
|
||||||
|
ENT.AmmoType = "SniperPenetratedRound"
|
||||||
|
ENT.AmmoCount = 10
|
||||||
|
ENT.MaxHealth = 20
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 80
|
||||||
|
ENT.DetonationRadius = 128
|
||||||
|
ENT.DetonationSound = "weapons/arccw/ssg08/ssg08-1.wav"
|
31
lua/entities/arccw_ammo_sniper/shared.lua
Normal file
31
lua/entities/arccw_ammo_sniper/shared.lua
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Type = "anim"
|
||||||
|
ENT.Base = "base_gmodentity"
|
||||||
|
|
||||||
|
ENT.PrintName = "Sniper Ammo"
|
||||||
|
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
|
||||||
|
ENT.Model = "models/items/sniper_round_box.mdl"
|
||||||
|
|
||||||
|
function ENT:Initialize()
|
||||||
|
self:SetModel(self.Model)
|
||||||
|
self:UseTriggerBounds(true, 24)
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:PhysicsInit(SOLID_VPHYSICS)
|
||||||
|
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||||
|
self:SetSolid(SOLID_VPHYSICS)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Touch(ply)
|
||||||
|
if !ply:IsPlayer() then return end
|
||||||
|
|
||||||
|
ply:GiveAmmo(5, "SniperPenetratedRound")
|
||||||
|
|
||||||
|
self:Remove()
|
||||||
|
end
|
18
lua/entities/arccw_ammo_sniper_large.lua
Normal file
18
lua/entities/arccw_ammo_sniper_large.lua
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_ammo"
|
||||||
|
|
||||||
|
ENT.PrintName = "Sniper Ammo (Large)"
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
ENT.Model = "models/items/arccw/sniper_ammo.mdl"
|
||||||
|
ENT.Scale = 1.5
|
||||||
|
|
||||||
|
ENT.AmmoType = "SniperPenetratedRound"
|
||||||
|
ENT.AmmoCount = 50
|
||||||
|
ENT.MaxHealth = 20
|
||||||
|
|
||||||
|
ENT.DetonationDamage = 80
|
||||||
|
ENT.DetonationRadius = 128
|
||||||
|
ENT.DetonationSound = "weapons/arccw/ssg08/ssg08-1.wav"
|
31
lua/entities/arccw_ammo_sniper_large/shared.lua
Normal file
31
lua/entities/arccw_ammo_sniper_large/shared.lua
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Type = "anim"
|
||||||
|
ENT.Base = "base_gmodentity"
|
||||||
|
|
||||||
|
ENT.PrintName = "Sniper Ammo (Large)"
|
||||||
|
|
||||||
|
ENT.Category = "ArcCW - Ammo"
|
||||||
|
|
||||||
|
ENT.Spawnable = true
|
||||||
|
|
||||||
|
ENT.Model = "models/items/sniper_round_box.mdl"
|
||||||
|
|
||||||
|
function ENT:Initialize()
|
||||||
|
self:SetModel(self.Model)
|
||||||
|
self:UseTriggerBounds(true, 24)
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:PhysicsInit(SOLID_VPHYSICS)
|
||||||
|
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||||
|
self:SetSolid(SOLID_VPHYSICS)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Touch(ply)
|
||||||
|
if !ply:IsPlayer() then return end
|
||||||
|
|
||||||
|
ply:GiveAmmo(20, "SniperPenetratedRound")
|
||||||
|
|
||||||
|
self:Remove()
|
||||||
|
end
|
114
lua/entities/arccw_att_base/shared.lua
Normal file
114
lua/entities/arccw_att_base/shared.lua
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
ENT.Type = "anim"
|
||||||
|
ENT.Base = "base_entity"
|
||||||
|
ENT.PrintName = "Base Dropped Attachment"
|
||||||
|
ENT.Author = ""
|
||||||
|
ENT.Information = ""
|
||||||
|
|
||||||
|
ENT.Spawnable = false
|
||||||
|
|
||||||
|
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||||
|
|
||||||
|
ENT.Category = "ArcCW - Attachments"
|
||||||
|
|
||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.GiveAttachments = {} -- table of all the attachments to give, and in what quantity. {{["id"] = int quantity}}
|
||||||
|
|
||||||
|
ENT.SoundImpact = "weapon.ImpactSoft"
|
||||||
|
ENT.Model = ""
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
|
||||||
|
function ENT:Initialize()
|
||||||
|
if !self.Model then
|
||||||
|
self:Remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetModel(self.Model)
|
||||||
|
self:PhysicsInit(SOLID_VPHYSICS)
|
||||||
|
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||||
|
self:SetSolid(SOLID_VPHYSICS)
|
||||||
|
self:SetCollisionGroup(COLLISION_GROUP_WEAPON)
|
||||||
|
self:SetTrigger( true )
|
||||||
|
self:SetPos(self:GetPos() + Vector(0, 0, 4))
|
||||||
|
local phys = self:GetPhysicsObject()
|
||||||
|
if phys:IsValid() then
|
||||||
|
phys:Wake()
|
||||||
|
phys:SetBuoyancyRatio(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:PhysicsCollide(colData, collider)
|
||||||
|
if colData.DeltaTime < 0.25 then return end
|
||||||
|
|
||||||
|
self:EmitSound(self.SoundImpact)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Use(activator, caller)
|
||||||
|
if !caller:IsPlayer() then return end
|
||||||
|
|
||||||
|
if GetConVar("arccw_attinv_free"):GetBool() then return end
|
||||||
|
|
||||||
|
local take = false
|
||||||
|
|
||||||
|
for i, k in pairs(self.GiveAttachments) do
|
||||||
|
if i == "BaseClass" then continue end
|
||||||
|
|
||||||
|
if GetConVar("arccw_attinv_lockmode"):GetBool() then
|
||||||
|
if ArcCW:PlayerGetAtts(caller, i) > 0 then
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW:PlayerGiveAtt(caller, i, k)
|
||||||
|
|
||||||
|
take = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if take then
|
||||||
|
ArcCW:PlayerSendAttInv(caller)
|
||||||
|
|
||||||
|
self:EmitSound("weapons/arccw/useatt.wav")
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local defaulticon = Material("hud/atts/default.png")
|
||||||
|
|
||||||
|
function ENT:DrawTranslucent()
|
||||||
|
|
||||||
|
self:Draw()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Draw()
|
||||||
|
self:DrawModel()
|
||||||
|
|
||||||
|
if !GetConVar("arccw_2d3d"):GetBool() then return end
|
||||||
|
|
||||||
|
if (EyePos() - self:GetPos()):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:GetPos() + Vector(0, 0, 16), ang, 0.1)
|
||||||
|
surface.SetFont("ArcCW_32_Unscaled")
|
||||||
|
|
||||||
|
local w = surface.GetTextSize(self.PrintName)
|
||||||
|
|
||||||
|
surface.SetTextPos(-w / 2, 0)
|
||||||
|
surface.SetTextColor(255, 255, 255, 255)
|
||||||
|
surface.DrawText(self.PrintName)
|
||||||
|
|
||||||
|
surface.SetDrawColor(255, 255, 255)
|
||||||
|
surface.SetMaterial(self.Icon or defaulticon)
|
||||||
|
local iw = 64
|
||||||
|
surface.DrawTexturedRect(-iw / 2, -iw - 8, iw, iw)
|
||||||
|
cam.End3D2D()
|
||||||
|
end
|
||||||
|
end
|
71
lua/entities/arccw_gl_ammodet.lua
Normal file
71
lua/entities/arccw_gl_ammodet.lua
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Base = "arccw_gl_he"
|
||||||
|
ENT.Model = "models/items/ar2_grenade.mdl"
|
||||||
|
ENT.Spawnable = false
|
||||||
|
ENT.Ticks = 0
|
||||||
|
|
||||||
|
function ENT:Detonate()
|
||||||
|
if !self:IsValid() then return end
|
||||||
|
local effectdata = EffectData()
|
||||||
|
effectdata:SetOrigin( self:GetPos() )
|
||||||
|
|
||||||
|
if self:WaterLevel() >= 1 then
|
||||||
|
util.Effect( "WaterSurfaceExplosion", effectdata )
|
||||||
|
self:EmitSound("weapons/underwater_explode3.wav", 125, 100, 1, CHAN_AUTO)
|
||||||
|
else
|
||||||
|
util.Effect( "Explosion", effectdata)
|
||||||
|
self:EmitSound("phx/kaboom.wav", 125, 100, 1, CHAN_AUTO)
|
||||||
|
end
|
||||||
|
|
||||||
|
local attacker = self
|
||||||
|
|
||||||
|
if self:GetOwner():IsValid() then
|
||||||
|
attacker = self:GetOwner()
|
||||||
|
end
|
||||||
|
|
||||||
|
util.BlastDamage(self, attacker, self:GetPos(), 300, 50)
|
||||||
|
|
||||||
|
self:FireBullets({
|
||||||
|
Attacker = attacker,
|
||||||
|
Damage = 0,
|
||||||
|
Tracer = 0,
|
||||||
|
Distance = 20000,
|
||||||
|
Dir = self:GetVelocity(),
|
||||||
|
Src = self:GetPos(),
|
||||||
|
Callback = function(att, tr, dmg)
|
||||||
|
util.Decal("Scorch", tr.StartPos, tr.HitPos - (tr.HitNormal * 16), self)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
function ENT:Think()
|
||||||
|
if self.Ticks % 2 == 0 then
|
||||||
|
local emitter = ParticleEmitter(self:GetPos())
|
||||||
|
|
||||||
|
if !self:IsValid() or self:WaterLevel() > 2 then return end
|
||||||
|
if !IsValid(emitter) then return end
|
||||||
|
|
||||||
|
local smoke = emitter:Add("particle/particle_smokegrenade", self:GetPos())
|
||||||
|
smoke:SetVelocity( VectorRand() * 25 )
|
||||||
|
smoke:SetGravity( Vector(math.Rand(-5, 5), math.Rand(-5, 5), math.Rand(-20, -25)) )
|
||||||
|
smoke:SetDieTime( math.Rand(1.5, 2.0) )
|
||||||
|
smoke:SetStartAlpha( 255 )
|
||||||
|
smoke:SetEndAlpha( 0 )
|
||||||
|
smoke:SetStartSize( 0 )
|
||||||
|
smoke:SetEndSize( 100 )
|
||||||
|
smoke:SetRoll( math.Rand(-180, 180) )
|
||||||
|
smoke:SetRollDelta( math.Rand(-0.2,0.2) )
|
||||||
|
smoke:SetColor( 20, 20, 20 )
|
||||||
|
smoke:SetAirResistance( 5 )
|
||||||
|
smoke:SetPos( self:GetPos() )
|
||||||
|
smoke:SetLighting( false )
|
||||||
|
emitter:Finish()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Ticks = self.Ticks + 1
|
||||||
|
end
|
||||||
|
end
|
116
lua/entities/arccw_smoke/shared.lua
Normal file
116
lua/entities/arccw_smoke/shared.lua
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
ENT.Type = "anim"
|
||||||
|
ENT.Base = "base_entity"
|
||||||
|
ENT.PrintName = "Smoke Cloud"
|
||||||
|
ENT.Author = ""
|
||||||
|
ENT.Information = ""
|
||||||
|
ENT.Spawnable = false
|
||||||
|
ENT.AdminSpawnable = false
|
||||||
|
|
||||||
|
local smokeimages = {"particle/smokesprites_0001", "particle/smokesprites_0002", "particle/smokesprites_0003", "particle/smokesprites_0004", "particle/smokesprites_0005", "particle/smokesprites_0006", "particle/smokesprites_0007", "particle/smokesprites_0008", "particle/smokesprites_0009", "particle/smokesprites_0010", "particle/smokesprites_0011", "particle/smokesprites_0012", "particle/smokesprites_0013", "particle/smokesprites_0014", "particle/smokesprites_0015", "particle/smokesprites_0016"}
|
||||||
|
|
||||||
|
local function GetSmokeImage()
|
||||||
|
return smokeimages[math.random(#smokeimages)]
|
||||||
|
end
|
||||||
|
|
||||||
|
ENT.Particles = nil
|
||||||
|
ENT.SmokeRadius = 256
|
||||||
|
ENT.SmokeColor = Color(150, 150, 150)
|
||||||
|
ENT.BillowTime = 1
|
||||||
|
ENT.Life = 15
|
||||||
|
|
||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
function ENT:Initialize()
|
||||||
|
if SERVER then
|
||||||
|
self:SetModel( "models/weapons/w_eq_smokegrenade_thrown.mdl" )
|
||||||
|
self:SetMoveType( MOVETYPE_NONE )
|
||||||
|
self:SetSolid( SOLID_NONE )
|
||||||
|
self:DrawShadow( false )
|
||||||
|
else
|
||||||
|
local emitter = ParticleEmitter(self:GetPos())
|
||||||
|
|
||||||
|
self.Particles = {}
|
||||||
|
|
||||||
|
local amt = 20
|
||||||
|
|
||||||
|
for i = 1, amt do
|
||||||
|
local smoke = emitter:Add(GetSmokeImage(), self:GetPos())
|
||||||
|
smoke:SetVelocity( VectorRand() * 8 + (Angle(0, i * (360 / amt), 0):Forward() * 400) )
|
||||||
|
smoke:SetDieTime( self.BillowTime )
|
||||||
|
smoke:SetStartAlpha( 0 )
|
||||||
|
smoke:SetEndAlpha( 255 )
|
||||||
|
smoke:SetStartSize( 0 )
|
||||||
|
smoke:SetEndSize( self.SmokeRadius )
|
||||||
|
smoke:SetRoll( math.Rand(-180, 180) )
|
||||||
|
smoke:SetRollDelta( math.Rand(-0.2,0.2) )
|
||||||
|
smoke:SetColor( self.SmokeColor.r, self.SmokeColor.g, self.SmokeColor.b )
|
||||||
|
smoke:SetAirResistance( 75 )
|
||||||
|
smoke:SetPos( self:GetPos() )
|
||||||
|
smoke:SetCollide( true )
|
||||||
|
smoke:SetBounce( 0.2 )
|
||||||
|
smoke:SetLighting( false )
|
||||||
|
smoke:SetNextThink( CurTime() + FrameTime() )
|
||||||
|
smoke:SetThinkFunction( function(pa)
|
||||||
|
if !pa then return end
|
||||||
|
|
||||||
|
local d = pa:GetLifeTime() / pa:GetDieTime()
|
||||||
|
|
||||||
|
local prog = (-d ^ 2) + (2 * d)
|
||||||
|
|
||||||
|
pa:SetEndSize( self.SmokeRadius * prog )
|
||||||
|
pa:SetStartSize( self.SmokeRadius * prog )
|
||||||
|
pa:SetNextThink( CurTime() + FrameTime() )
|
||||||
|
end )
|
||||||
|
|
||||||
|
table.insert(self.Particles, smoke)
|
||||||
|
end
|
||||||
|
|
||||||
|
emitter:Finish()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.bt = CurTime() + self.BillowTime
|
||||||
|
self.billowed = false
|
||||||
|
self.dt = CurTime() + self.Life + self.BillowTime
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Think()
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
local targets = ents.FindInSphere(self:GetPos(), 256)
|
||||||
|
for _, k in pairs(targets) do
|
||||||
|
if k:IsNPC() then
|
||||||
|
k:SetNPCState(NPC_STATE_PRONE)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.bt < CurTime() and !self.billowed then
|
||||||
|
self.billowed = true
|
||||||
|
if CLIENT then
|
||||||
|
for i, k in pairs(self.Particles or {}) do
|
||||||
|
if !k then continue end
|
||||||
|
k:SetThinkFunction(nil)
|
||||||
|
k:SetLifeTime(0)
|
||||||
|
k:SetDieTime(self.Life)
|
||||||
|
k:SetStartAlpha(255)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.dt < CurTime() then
|
||||||
|
if CLIENT then
|
||||||
|
for i, k in pairs(self.Particles or {}) do
|
||||||
|
if !k then continue end
|
||||||
|
k:SetLifeTime(0)
|
||||||
|
k:SetDieTime(math.Rand(2.5, 5))
|
||||||
|
k:SetEndAlpha(0)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
SafeRemoveEntity(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Draw()
|
||||||
|
return false
|
||||||
|
end
|
84
lua/weapons/arccw_base/cl_blur.lua
Normal file
84
lua/weapons/arccw_base/cl_blur.lua
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
local dofmat = Material("pp/dof")
|
||||||
|
|
||||||
|
function SWEP:BlurWeapon()
|
||||||
|
if !GetConVar("arccw_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 !GetConVar("arccw_blur"):GetBool() 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.SetStencilReferenceValue(0)
|
||||||
|
|
||||||
|
render.SetBlend(0)
|
||||||
|
|
||||||
|
render.SetStencilPassOperation(STENCIL_REPLACE)
|
||||||
|
render.SetStencilCompareFunction(STENCIL_EQUAL)
|
||||||
|
|
||||||
|
-- render.SetColorMaterial()
|
||||||
|
|
||||||
|
dofmat:SetFloat("bluramount", 0.1)
|
||||||
|
|
||||||
|
render.SetMaterial(dofmat)
|
||||||
|
render.DrawScreenQuad()
|
||||||
|
|
||||||
|
render.SetStencilEnable( false )
|
||||||
|
end
|
137
lua/weapons/arccw_base/cl_crosshair.lua
Normal file
137
lua/weapons/arccw_base/cl_crosshair.lua
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
local delta = 0
|
||||||
|
local size = 0
|
||||||
|
local cw = nil
|
||||||
|
|
||||||
|
function SWEP:ShouldDrawCrosshair()
|
||||||
|
if !GetConVar("arccw_override_crosshair_off") then return false end
|
||||||
|
if !GetConVar("arccw_crosshair"):GetBool() then return false end
|
||||||
|
if self:GetNWBool("reloading") then return false end
|
||||||
|
local asight = self:GetActiveSights()
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS and !asight.CrosshairInSights then return false end
|
||||||
|
if self:GetState() == ArcCW.STATE_SPRINT and !(self:GetBuff_Override("Override_ShootWhileSprint") or self.ShootWhileSprint) then return false end
|
||||||
|
if self:GetCurrentFiremode().Mode == 0 then return false end
|
||||||
|
if self:GetBuff_Hook("Hook_ShouldNotFire") then return false end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DoDrawCrosshair(x, y)
|
||||||
|
local pos = EyePos()
|
||||||
|
local ang = EyeAngles() - LocalPlayer():GetViewPunchAngles()
|
||||||
|
local dot = true
|
||||||
|
local prong_top = true
|
||||||
|
local prong_left = true
|
||||||
|
local prong_right = true
|
||||||
|
local prong_down = true
|
||||||
|
|
||||||
|
local gap = ScreenScale(24) * math.Clamp(self:GetDispersion() / 1000, 0.1, 100)
|
||||||
|
|
||||||
|
gap = gap + ScreenScale(8) * math.Clamp(self.RecoilAmount, 0, 1)
|
||||||
|
|
||||||
|
local prong = ScreenScale(4)
|
||||||
|
|
||||||
|
cw = cw or self
|
||||||
|
|
||||||
|
cam.Start3D()
|
||||||
|
local sp = (pos + (ang:Forward() * 3200)):ToScreen()
|
||||||
|
cam.End3D()
|
||||||
|
|
||||||
|
x, y = sp.x, sp.y
|
||||||
|
|
||||||
|
local st = self:GetSightTime() / 4
|
||||||
|
|
||||||
|
if self:ShouldDrawCrosshair() then
|
||||||
|
delta = math.Approach(delta, 1, RealFrameTime() * 1 / st)
|
||||||
|
else
|
||||||
|
delta = math.Approach(delta, 0, RealFrameTime() * 1 / st)
|
||||||
|
end
|
||||||
|
|
||||||
|
local p_w = ScreenScale(1)
|
||||||
|
local p_w2 = p_w + 2
|
||||||
|
|
||||||
|
if self:GetBuff_Override("Override_ShootEntity") or self.ShootEntity then
|
||||||
|
gap = gap * 1.5
|
||||||
|
prong = ScreenScale(1)
|
||||||
|
p_w = ScreenScale(1)
|
||||||
|
p_w2 = p_w + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.PrimaryBash then
|
||||||
|
dot = false
|
||||||
|
gap = gap * 2
|
||||||
|
prong = ScreenScale(1)
|
||||||
|
p_w = ScreenScale(1)
|
||||||
|
p_w2 = p_w + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
if dot then
|
||||||
|
|
||||||
|
surface.SetDrawColor(0, 0, 0, 150 * delta)
|
||||||
|
surface.DrawRect(x - p_w2 / 2, y - p_w2 / 2, p_w2, p_w2)
|
||||||
|
|
||||||
|
surface.SetDrawColor(255, 255, 255, 255 * delta)
|
||||||
|
surface.DrawRect(x - p_w / 2, y - p_w / 2, p_w, p_w)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local num = (self:GetBuff_Override("Override_Num") or self.Num) + self:GetBuff_Add("Add_Num")
|
||||||
|
|
||||||
|
size = math.Approach(size, gap, RealFrameTime() * 32 * gap)
|
||||||
|
|
||||||
|
if cw != self then
|
||||||
|
delta = 0
|
||||||
|
size = gap
|
||||||
|
end
|
||||||
|
|
||||||
|
cw = self
|
||||||
|
|
||||||
|
gap = size
|
||||||
|
|
||||||
|
if num > 1 then
|
||||||
|
dot = false
|
||||||
|
gap = gap * 2.5
|
||||||
|
prong = ScreenScale(1)
|
||||||
|
p_w = ScreenScale(10)
|
||||||
|
p_w2 = p_w + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
local prong2 = prong + 2
|
||||||
|
|
||||||
|
surface.SetDrawColor(0, 0, 0, 150 * delta)
|
||||||
|
|
||||||
|
if prong_left then
|
||||||
|
surface.DrawRect(x - gap - prong2 + 1, y - p_w2 / 2, prong2, p_w2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if prong_right then
|
||||||
|
surface.DrawRect(x + gap - 1, y - p_w2 / 2, prong2, p_w2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if prong_top then
|
||||||
|
surface.DrawRect(x - p_w2 / 2, y - gap - prong2 + 1, p_w2, prong2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if prong_down then
|
||||||
|
surface.DrawRect(x - p_w2 / 2, y + gap - 1, p_w2, prong2)
|
||||||
|
end
|
||||||
|
|
||||||
|
surface.SetDrawColor(255, 255, 255, 255 * delta)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
651
lua/weapons/arccw_base/cl_holosight.lua
Normal file
651
lua/weapons/arccw_base/cl_holosight.lua
Normal file
@ -0,0 +1,651 @@
|
|||||||
|
function SWEP:DoHolosight()
|
||||||
|
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
|
||||||
|
|
||||||
|
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 shadow = Material("hud/scopes/shadow.png")
|
||||||
|
|
||||||
|
-- local thermal = Material("models/debug/debugwhite")
|
||||||
|
local colormod = Material("pp/colour")
|
||||||
|
-- local warp = Material("models/props_c17/fisheyelens2")
|
||||||
|
local coldtime = 30
|
||||||
|
|
||||||
|
-- shamelessly robbed from Jackarunda
|
||||||
|
local function IsWHOT(ent)
|
||||||
|
if !ent:IsValid() then return false end
|
||||||
|
if (ent:IsWorld()) then return false end
|
||||||
|
if (ent.Health and (ent:Health() <= 0)) then return false end
|
||||||
|
if ((ent:IsPlayer()) or (ent:IsOnFire())) then return true end
|
||||||
|
if ent:IsNextBot() then return true end
|
||||||
|
if (ent:IsNPC()) then
|
||||||
|
if ent.ArcCWCLHealth and ent.ArcCWCLHealth <= 0 then return false end
|
||||||
|
if (ent.Health and (ent:Health() > 0)) then return true end
|
||||||
|
elseif (ent:IsRagdoll()) then
|
||||||
|
local Time = CurTime()
|
||||||
|
if !ent.ArcCW_ColdTime then ent.ArcCW_ColdTime = Time + coldtime end
|
||||||
|
return ent.ArcCW_ColdTime > Time
|
||||||
|
elseif (ent:IsVehicle()) then
|
||||||
|
return ent:GetVelocity():Length() >= 100
|
||||||
|
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 Color(255, 255, 255)
|
||||||
|
local tvsc = asight.ThermalHighlightColor or Color(255, 255, 255)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
local Br = 0.9
|
||||||
|
if v.ArcCW_ColdTime then
|
||||||
|
Br = (0.75 * v.ArcCW_ColdTime - CurTime()) / coldtime
|
||||||
|
end
|
||||||
|
|
||||||
|
if v:IsVehicle() then
|
||||||
|
Br = math.Clamp(v:GetVelocity():Length() / 400, 0, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Br > 0 then
|
||||||
|
|
||||||
|
if !asight.ThermalScopeSimple then
|
||||||
|
render.SetBlend(0.5)
|
||||||
|
render.SuppressEngineLighting(true)
|
||||||
|
|
||||||
|
Br = Br * 250
|
||||||
|
|
||||||
|
-- render.MaterialOverride(thermal)
|
||||||
|
|
||||||
|
render.SetColorModulation(Br, Br, Br)
|
||||||
|
end
|
||||||
|
|
||||||
|
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(tvsc)
|
||||||
|
surface.DrawRect(0, 0, ScrW(), ScrH())
|
||||||
|
end
|
||||||
|
|
||||||
|
if !asight.ThermalNoCC 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
|
||||||
|
})
|
||||||
|
|
||||||
|
DrawColorModify({
|
||||||
|
["$pp_colour_addr"] = tvsc.r - 255,
|
||||||
|
["$pp_colour_addg"] = tvsc.g - 255,
|
||||||
|
["$pp_colour_addb"] = tvsc.b - 255,
|
||||||
|
["$pp_colour_brightness"] = 0,
|
||||||
|
["$pp_colour_contrast"] = 1,
|
||||||
|
["$pp_colour_colour"] = 0,
|
||||||
|
["$pp_colour_mulr"] = 0,
|
||||||
|
["$pp_colour_mulg"] = 0,
|
||||||
|
["$pp_colour_mulb"] = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
render.SetStencilCompareFunction(STENCIL_NOTEQUAL)
|
||||||
|
|
||||||
|
DrawColorModify({
|
||||||
|
["$pp_colour_addr"] = 0,
|
||||||
|
["$pp_colour_addg"] = 0,
|
||||||
|
["$pp_colour_addb"] = 0,
|
||||||
|
["$pp_colour_brightness"] = 0.1,
|
||||||
|
["$pp_colour_contrast"] = 0.5,
|
||||||
|
["$pp_colour_colour"] = 0,
|
||||||
|
["$pp_colour_mulr"] = 0,
|
||||||
|
["$pp_colour_mulg"] = 0,
|
||||||
|
["$pp_colour_mulb"] = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
DrawColorModify({
|
||||||
|
["$pp_colour_addr"] = nvsc.r - 255,
|
||||||
|
["$pp_colour_addg"] = nvsc.g - 255,
|
||||||
|
["$pp_colour_addb"] = nvsc.b - 255,
|
||||||
|
["$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
|
||||||
|
|
||||||
|
render.SetScissorRect( sx, sy, sx + sw, sy + sh, false )
|
||||||
|
|
||||||
|
render.SetStencilEnable(false)
|
||||||
|
|
||||||
|
colormod:SetTexture("$fbtexture", render.GetScreenEffectTexture())
|
||||||
|
|
||||||
|
cam.End3D()
|
||||||
|
|
||||||
|
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 Color(0, 255, 0)
|
||||||
|
|
||||||
|
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"] = -0.05,
|
||||||
|
["$pp_colour_contrast"] = 4,
|
||||||
|
["$pp_colour_colour"] = 1,
|
||||||
|
["$pp_colour_mulr"] = 0,
|
||||||
|
["$pp_colour_mulg"] = 0,
|
||||||
|
["$pp_colour_mulb"] = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
render.PopRenderTarget()
|
||||||
|
|
||||||
|
colormod:SetTexture("$fbtexture", orig)
|
||||||
|
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()
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
local rt = {
|
||||||
|
w = rtsize,
|
||||||
|
h = rtsize,
|
||||||
|
angles = LocalPlayer():EyeAngles() + (self:GetOwner():GetViewPunchAngles() * 0.5),
|
||||||
|
origin = LocalPlayer():EyePos(),
|
||||||
|
drawviewmodel = false,
|
||||||
|
fov = self:GetOwner():GetFOV() / mag / 1.2,
|
||||||
|
}
|
||||||
|
|
||||||
|
rtsize = ScrH()
|
||||||
|
|
||||||
|
if ScrH() > ScrW() then rtsize = ScrW() end
|
||||||
|
|
||||||
|
rtmat = GetRenderTarget("arccw_rtmat", rtsize, rtsize, false)
|
||||||
|
|
||||||
|
render.PushRenderTarget(rtmat, 0, 0, rtsize, rtsize)
|
||||||
|
|
||||||
|
render.ClearRenderTarget(rt, Color(0, 0, 0))
|
||||||
|
|
||||||
|
if self:GetSightDelta() < 1 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
|
||||||
|
|
||||||
|
render.PopRenderTarget()
|
||||||
|
|
||||||
|
cam.End3D()
|
||||||
|
|
||||||
|
if asight.Thermal then
|
||||||
|
self:FormThermalImaging(rtmat)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
hook.Add("RenderScene", "ArcCW", function()
|
||||||
|
if GetConVar("arccw_cheapscopes"):GetBool() then return end
|
||||||
|
|
||||||
|
local wpn = LocalPlayer():GetActiveWeapon()
|
||||||
|
|
||||||
|
if !wpn.ArcCW then return end
|
||||||
|
|
||||||
|
wpn:FormRTScope()
|
||||||
|
end)
|
||||||
|
|
||||||
|
local black = Material("hud/black.png")
|
||||||
|
local defaultdot = Material("hud/scopes/dot.png")
|
||||||
|
|
||||||
|
function SWEP:DrawHolosight(hs, hsm, hsp)
|
||||||
|
-- holosight structure
|
||||||
|
-- holosight model
|
||||||
|
|
||||||
|
local asight = self:GetActiveSights()
|
||||||
|
local delta = self:GetSightDelta()
|
||||||
|
|
||||||
|
if asight.HolosightData then
|
||||||
|
hs = asight.HolosightData
|
||||||
|
end
|
||||||
|
|
||||||
|
if delta == 1 then return end
|
||||||
|
|
||||||
|
if !hs then return end
|
||||||
|
|
||||||
|
local hsc = Color(255, 255, 255)
|
||||||
|
|
||||||
|
if hs.Colorable then
|
||||||
|
hsc.r = GetConVar("arccw_scope_r"):GetInt()
|
||||||
|
hsc.g = GetConVar("arccw_scope_g"):GetInt()
|
||||||
|
hsc.b = GetConVar("arccw_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 size = hs.HolosightSize or 1
|
||||||
|
|
||||||
|
local hsmag = asight.ScopeMagnification or 1
|
||||||
|
|
||||||
|
-- if asight.NightVision then
|
||||||
|
|
||||||
|
if hsmag and hsmag > 1 and delta < 1 and asight.NVScope then
|
||||||
|
local screen = rtmat
|
||||||
|
|
||||||
|
if GetConVar("arccw_cheapscopes"):GetBool() then
|
||||||
|
screen = rtmat_cheap
|
||||||
|
end
|
||||||
|
self:FormNightVision(screen)
|
||||||
|
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(55)
|
||||||
|
|
||||||
|
ArcCW.Overdraw = true
|
||||||
|
|
||||||
|
render.OverrideDepthEnable( true, true )
|
||||||
|
|
||||||
|
if !hsm then
|
||||||
|
hsp:DrawModel()
|
||||||
|
else
|
||||||
|
|
||||||
|
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(55)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
ang = ang + (self:GetOwner():GetViewPunchAngles() * 0.25)
|
||||||
|
|
||||||
|
local dir = ang:Up()
|
||||||
|
|
||||||
|
local pdiff = (pos - EyePos()):Length()
|
||||||
|
|
||||||
|
pos = LerpVector(delta, EyePos(), pos)
|
||||||
|
|
||||||
|
local eyeangs = self:GetOwner():EyeAngles() - (self:GetOwner():GetViewPunchAngles() * 0.25)
|
||||||
|
|
||||||
|
-- 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 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 GetConVar("arccw_cheapscopes"):GetBool() then
|
||||||
|
|
||||||
|
screen = rtmat_cheap
|
||||||
|
|
||||||
|
local ssmag = hsmag
|
||||||
|
|
||||||
|
local sw = ScrW() * ssmag
|
||||||
|
local sh = ScrH() * ssmag
|
||||||
|
|
||||||
|
-- local sx = -(sw - ScrW()) / 2
|
||||||
|
-- local sy = -(sh - ScrH()) / 2
|
||||||
|
|
||||||
|
local cpos = self.Owner:EyePos() + ((EyeAngles() + (self:GetOwner():GetViewPunchAngles() * 0.5)):Forward() * 2048)
|
||||||
|
|
||||||
|
local ts = cpos:ToScreen()
|
||||||
|
|
||||||
|
local sx = ts.x - (sw / 2)
|
||||||
|
local sy = ts.y - (sh / 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
|
||||||
|
local sy = (ScrH() - sh) / 2
|
||||||
|
|
||||||
|
render.SetMaterial(black)
|
||||||
|
render.DrawScreenQuad()
|
||||||
|
|
||||||
|
render.DrawTextureToScreenRect(screen, sx, sy, sw, sh)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- warp:SetFloat("$refractamount", -0.015)
|
||||||
|
-- render.UpdateRefractTexture()
|
||||||
|
-- render.SetMaterial(warp)
|
||||||
|
-- render.DrawScreenQuad()
|
||||||
|
|
||||||
|
-- render.SetScissorRect( sx2, sy2, sx2 + sw2, sy2 + sh2, false )
|
||||||
|
end
|
||||||
|
|
||||||
|
cam.Start3D()
|
||||||
|
|
||||||
|
-- render.SetColorMaterialIgnoreZ()
|
||||||
|
-- render.DrawScreenQuad()
|
||||||
|
|
||||||
|
-- render.DrawQuad( corner1, corner2, corner3, corner4, hsc or hs.HolosightColor )
|
||||||
|
cam.IgnoreZ( true )
|
||||||
|
|
||||||
|
if hs.HolosightBlackbox then
|
||||||
|
render.SetStencilPassOperation(STENCIL_ZERO)
|
||||||
|
render.SetStencilCompareFunction(STENCIL_EQUAL)
|
||||||
|
|
||||||
|
render.SetStencilReferenceValue(55)
|
||||||
|
|
||||||
|
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)
|
||||||
|
render.DrawSprite(pos, size * 0.5 * hsx, size * 0.5 * hsy, Color(255, 255, 255))
|
||||||
|
end
|
||||||
|
|
||||||
|
render.SetStencilPassOperation(STENCIL_REPLACE)
|
||||||
|
render.SetStencilCompareFunction(STENCIL_EQUAL)
|
||||||
|
|
||||||
|
render.SetMaterial(black)
|
||||||
|
render.DrawScreenQuad()
|
||||||
|
else
|
||||||
|
render.SetStencilReferenceValue(55)
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
render.SetStencilEnable( false )
|
||||||
|
|
||||||
|
cam.IgnoreZ( false )
|
||||||
|
|
||||||
|
cam.End3D()
|
||||||
|
|
||||||
|
if hsp then
|
||||||
|
|
||||||
|
cam.IgnoreZ(true)
|
||||||
|
|
||||||
|
if GetConVar("arccw_glare"):GetBool() then
|
||||||
|
render.SetBlend(delta + 0.1)
|
||||||
|
else
|
||||||
|
render.SetBlend(delta)
|
||||||
|
end
|
||||||
|
hsp:DrawModel()
|
||||||
|
render.SetBlend(1)
|
||||||
|
|
||||||
|
cam.IgnoreZ( false )
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
400
lua/weapons/arccw_base/cl_hud.lua
Normal file
400
lua/weapons/arccw_base/cl_hud.lua
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
local function MyDrawText(tbl)
|
||||||
|
local x = tbl.x
|
||||||
|
local y = tbl.y
|
||||||
|
surface.SetFont(tbl.font)
|
||||||
|
|
||||||
|
if tbl.alpha then
|
||||||
|
tbl.col.a = tbl.alpha
|
||||||
|
end
|
||||||
|
|
||||||
|
if tbl.align or tbl.yalign then
|
||||||
|
local w, h = surface.GetTextSize(tbl.text)
|
||||||
|
if tbl.align == 1 then
|
||||||
|
x = x - w
|
||||||
|
elseif tbl.align == 2 then
|
||||||
|
x = x - (w / 2)
|
||||||
|
end
|
||||||
|
if tbl.yalign == 1 then
|
||||||
|
y = y - h
|
||||||
|
elseif tbl.yalign == 2 then
|
||||||
|
y = y - h / 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if tbl.shadow then
|
||||||
|
surface.SetTextColor(Color(0, 0, 0, tbl.alpha or 255))
|
||||||
|
surface.SetTextPos(x, y)
|
||||||
|
surface.SetFont(tbl.font .. "_Glow")
|
||||||
|
surface.DrawText(tbl.text)
|
||||||
|
end
|
||||||
|
|
||||||
|
surface.SetTextColor(tbl.col)
|
||||||
|
surface.SetTextPos(x, y)
|
||||||
|
surface.SetFont(tbl.font)
|
||||||
|
surface.DrawText(tbl.text)
|
||||||
|
end
|
||||||
|
|
||||||
|
local vhp = 0
|
||||||
|
local varmor = 0
|
||||||
|
local vclip = 0
|
||||||
|
local vreserve = 0
|
||||||
|
local lastwpn = ""
|
||||||
|
local lastinfo = {ammo = 0, clip = 0, firemode = "", plus = 0}
|
||||||
|
local lastinfotime = 0
|
||||||
|
|
||||||
|
function SWEP:DrawHUD()
|
||||||
|
-- info panel
|
||||||
|
|
||||||
|
local col1 = Color(0, 0, 0, 100)
|
||||||
|
local col2 = Color(255, 255, 255, 255)
|
||||||
|
local col3 = Color(255, 0, 0, 255)
|
||||||
|
|
||||||
|
local airgap = ScreenScale(8)
|
||||||
|
|
||||||
|
local apan_bg = {
|
||||||
|
w = ScreenScale(128),
|
||||||
|
h = ScreenScale(48),
|
||||||
|
}
|
||||||
|
|
||||||
|
local bargap = ScreenScale(2)
|
||||||
|
|
||||||
|
if self:CanBipod() then
|
||||||
|
local txt = "[" .. string.upper(ArcCW:GetBind("+use")) .. "]"
|
||||||
|
|
||||||
|
if self:InBipod() then
|
||||||
|
txt = txt .. " Retract Bipod"
|
||||||
|
else
|
||||||
|
txt = txt .. " Deploy Bipod"
|
||||||
|
end
|
||||||
|
|
||||||
|
local bip = {
|
||||||
|
shadow = true,
|
||||||
|
x = ScrW() / 2,
|
||||||
|
y = (ScrH() / 2) + ScreenScale(36),
|
||||||
|
font = "ArcCW_12",
|
||||||
|
text = txt,
|
||||||
|
col = col2,
|
||||||
|
align = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
MyDrawText(bip)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ArcCW:ShouldDrawHUDElement("CHudAmmo") then
|
||||||
|
|
||||||
|
local curTime = CurTime()
|
||||||
|
local ammo = math.Round(vreserve)
|
||||||
|
local clip = math.Round(vclip)
|
||||||
|
local plus = 0
|
||||||
|
local mode = self:GetFiremodeName()
|
||||||
|
|
||||||
|
if clip > self:GetCapacity() then
|
||||||
|
plus = clip - self:GetCapacity()
|
||||||
|
clip = clip - plus
|
||||||
|
end
|
||||||
|
|
||||||
|
local muzz = self:GetBuff_Override("Override_MuzzleEffectAttachment") or self.MuzzleEffectAttachment or 1
|
||||||
|
|
||||||
|
local suckitYurie = GetConVar("arccw_hud_3dfun"):GetBool()
|
||||||
|
|
||||||
|
local vm = self.Owner:GetViewModel()
|
||||||
|
|
||||||
|
local angpos
|
||||||
|
|
||||||
|
if vm and vm:IsValid() then
|
||||||
|
angpos = vm:GetAttachment(muzz)
|
||||||
|
end
|
||||||
|
|
||||||
|
if suckitYurie and muzz and angpos then
|
||||||
|
|
||||||
|
local visible = (lastinfotime + 4 > curTime or lastinfotime - 0.5 > curTime)
|
||||||
|
|
||||||
|
-- Detect changes to stuff drawn in HUD
|
||||||
|
local curInfo = {ammo = ammo, clip = clip, plus = plus, firemode = mode}
|
||||||
|
for i, v in pairs(curInfo) do
|
||||||
|
if v != lastinfo[i] then
|
||||||
|
lastinfotime = visible and (curTime - 0.5) or curTime
|
||||||
|
lastinfo = curInfo
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: There's an issue where this won't ping the HUD when switching in from non-ArcCW weapons
|
||||||
|
if LocalPlayer():KeyDown(IN_RELOAD) or lastwpn != self then lastinfotime = visible and (curTime - 0.5) or curTime end
|
||||||
|
|
||||||
|
local alpha
|
||||||
|
if lastinfotime + 3 < curTime then
|
||||||
|
alpha = 255 - (curTime - lastinfotime - 3) * 255
|
||||||
|
elseif lastinfotime + 0.5 > curTime then
|
||||||
|
alpha = 255 - (lastinfotime + 0.5 - curTime) * 255
|
||||||
|
else
|
||||||
|
alpha = 255
|
||||||
|
end
|
||||||
|
|
||||||
|
if alpha > 0 then
|
||||||
|
|
||||||
|
cam.Start3D()
|
||||||
|
local toscreen = angpos.Pos:ToScreen()
|
||||||
|
cam.End3D()
|
||||||
|
|
||||||
|
apan_bg.x = toscreen.x - apan_bg.w - ScreenScale(8)
|
||||||
|
apan_bg.y = toscreen.y - apan_bg.h * 0.5
|
||||||
|
|
||||||
|
if self.PrimaryBash or self:Clip1() == -1 or self:GetCapacity() == 0 or self.Primary.ClipSize == -1 then
|
||||||
|
clip = "-"
|
||||||
|
end
|
||||||
|
|
||||||
|
local wammo = {
|
||||||
|
x = apan_bg.x + apan_bg.w - airgap,
|
||||||
|
y = apan_bg.y,
|
||||||
|
text = tostring(clip),
|
||||||
|
font = "ArcCW_26",
|
||||||
|
col = col2,
|
||||||
|
align = 1,
|
||||||
|
shadow = true,
|
||||||
|
alpha = alpha,
|
||||||
|
}
|
||||||
|
|
||||||
|
wammo.col = col2
|
||||||
|
|
||||||
|
if self:Clip1() == 0 then
|
||||||
|
wammo.col = col3
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetNWBool("ubgl") then
|
||||||
|
wammo.col = col2
|
||||||
|
wammo.text = self:Clip2()
|
||||||
|
end
|
||||||
|
|
||||||
|
MyDrawText(wammo)
|
||||||
|
wammo.w, wammo.h = surface.GetTextSize(wammo.text)
|
||||||
|
|
||||||
|
if plus > 0 and !self:GetNWBool("ubgl") then
|
||||||
|
local wplus = {
|
||||||
|
x = wammo.x,
|
||||||
|
y = wammo.y,
|
||||||
|
text = "+" .. tostring(plus),
|
||||||
|
font = "ArcCW_16",
|
||||||
|
col = col2,
|
||||||
|
shadow = true,
|
||||||
|
alpha = alpha,
|
||||||
|
}
|
||||||
|
|
||||||
|
MyDrawText(wplus)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local wreserve = {
|
||||||
|
x = wammo.x - wammo.w - ScreenScale(4),
|
||||||
|
y = apan_bg.y + ScreenScale(26 - 12),
|
||||||
|
text = tostring(ammo) .. " /",
|
||||||
|
font = "ArcCW_12",
|
||||||
|
col = col2,
|
||||||
|
align = 1,
|
||||||
|
yalign = 2,
|
||||||
|
shadow = true,
|
||||||
|
alpha = alpha,
|
||||||
|
}
|
||||||
|
|
||||||
|
if self:GetNWBool("ubgl") then
|
||||||
|
local ubglammo = self:GetBuff_Override("UBGL_Ammo")
|
||||||
|
|
||||||
|
if ubglammo then
|
||||||
|
wreserve.text = tostring(self:GetOwner():GetAmmoCount(ubglammo)) .. " /"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.PrimaryBash then
|
||||||
|
wreserve.text = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
MyDrawText(wreserve)
|
||||||
|
wreserve.w, wreserve.h = surface.GetTextSize(wreserve.text)
|
||||||
|
|
||||||
|
local wmode = {
|
||||||
|
x = apan_bg.x + apan_bg.w - airgap,
|
||||||
|
y = wammo.y + wammo.h,
|
||||||
|
font = "ArcCW_12",
|
||||||
|
text = mode,
|
||||||
|
col = col2,
|
||||||
|
align = 1,
|
||||||
|
shadow = true,
|
||||||
|
alpha = alpha,
|
||||||
|
}
|
||||||
|
MyDrawText(wmode)
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
|
apan_bg.x = ScrW() - apan_bg.w - airgap
|
||||||
|
apan_bg.y = ScrH() - apan_bg.h - airgap
|
||||||
|
|
||||||
|
surface.SetDrawColor(col1)
|
||||||
|
surface.DrawRect(apan_bg.x, apan_bg.y, apan_bg.w, apan_bg.h)
|
||||||
|
|
||||||
|
local bar = {
|
||||||
|
w = (apan_bg.w - (6 * bargap)) / 5,
|
||||||
|
h = ScreenScale(3),
|
||||||
|
x = apan_bg.x + bargap,
|
||||||
|
y = apan_bg.y + ScreenScale(14)
|
||||||
|
}
|
||||||
|
|
||||||
|
local bars = self:GetFiremodeBars()
|
||||||
|
|
||||||
|
for i = 1, 5 do
|
||||||
|
local c = bars[i]
|
||||||
|
|
||||||
|
surface.SetDrawColor(col2)
|
||||||
|
|
||||||
|
if c == "-" then
|
||||||
|
surface.DrawRect(bar.x, bar.y, bar.w, bar.h)
|
||||||
|
else
|
||||||
|
surface.DrawOutlinedRect(bar.x, bar.y, bar.w, bar.h)
|
||||||
|
end
|
||||||
|
|
||||||
|
bar.x = bar.x + bar.w + bargap
|
||||||
|
end
|
||||||
|
|
||||||
|
local wname = {
|
||||||
|
x = apan_bg.x + ScreenScale(4),
|
||||||
|
y = apan_bg.y,
|
||||||
|
font = "ArcCW_12",
|
||||||
|
text = self.PrintName,
|
||||||
|
col = col2
|
||||||
|
}
|
||||||
|
|
||||||
|
MyDrawText(wname)
|
||||||
|
|
||||||
|
local wmode = {
|
||||||
|
x = apan_bg.x + apan_bg.w - ScreenScale(4) - surface.GetTextSize(mode),
|
||||||
|
y = apan_bg.y,
|
||||||
|
font = "ArcCW_12",
|
||||||
|
text = mode,
|
||||||
|
col = col2
|
||||||
|
}
|
||||||
|
|
||||||
|
MyDrawText(wmode)
|
||||||
|
|
||||||
|
if self.PrimaryBash or self:Clip1() == -1 or self:GetCapacity() == 0 or self.Primary.ClipSize == -1 then
|
||||||
|
clip = "-"
|
||||||
|
end
|
||||||
|
|
||||||
|
local wammo = {
|
||||||
|
x = apan_bg.x + airgap,
|
||||||
|
y = bar.y + ScreenScale(4),
|
||||||
|
text = tostring(clip),
|
||||||
|
font = "ArcCW_26",
|
||||||
|
col = col2
|
||||||
|
}
|
||||||
|
|
||||||
|
wammo.col = col2
|
||||||
|
|
||||||
|
if self:Clip1() == 0 then
|
||||||
|
wammo.col = col3
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetNWBool("ubgl") then
|
||||||
|
wammo.col = col2
|
||||||
|
wammo.text = self:Clip2()
|
||||||
|
end
|
||||||
|
|
||||||
|
MyDrawText(wammo)
|
||||||
|
|
||||||
|
local wreserve = {
|
||||||
|
x = apan_bg.x + ScreenScale(64) - airgap,
|
||||||
|
y = bar.y + ScreenScale(4),
|
||||||
|
text = "/ " .. tostring(ammo),
|
||||||
|
font = "ArcCW_26",
|
||||||
|
col = col2,
|
||||||
|
}
|
||||||
|
|
||||||
|
if self:GetNWBool("ubgl") then
|
||||||
|
local ubglammo = self:GetBuff_Override("UBGL_Ammo")
|
||||||
|
|
||||||
|
if ubglammo then
|
||||||
|
wreserve.text = "/ " .. tostring(self:GetOwner():GetAmmoCount(ubglammo))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.PrimaryBash then
|
||||||
|
wreserve.text = "/ -"
|
||||||
|
end
|
||||||
|
|
||||||
|
MyDrawText(wreserve)
|
||||||
|
|
||||||
|
wammo.w = surface.GetTextSize(tostring(clip))
|
||||||
|
|
||||||
|
if plus > 0 and !self:GetNWBool("ubgl") then
|
||||||
|
local wplus = {
|
||||||
|
x = wammo.x + bargap + wammo.w,
|
||||||
|
y = wammo.y,
|
||||||
|
text = "+" .. tostring(plus),
|
||||||
|
font = "ArcCW_16",
|
||||||
|
col = col2
|
||||||
|
}
|
||||||
|
|
||||||
|
MyDrawText(wplus)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- health + armor
|
||||||
|
|
||||||
|
if ArcCW:ShouldDrawHUDElement("CHudHealth") then
|
||||||
|
|
||||||
|
local colhp = col2
|
||||||
|
|
||||||
|
if LocalPlayer():Health() <= 30 then
|
||||||
|
colhp = col3
|
||||||
|
end
|
||||||
|
|
||||||
|
local whp = {
|
||||||
|
x = airgap,
|
||||||
|
y = ScrH() - ScreenScale(26) - ScreenScale(16) - airgap,
|
||||||
|
font = "ArcCW_26",
|
||||||
|
text = "HP: " .. tostring(math.Round(vhp)),
|
||||||
|
col = colhp,
|
||||||
|
shadow = true
|
||||||
|
}
|
||||||
|
|
||||||
|
MyDrawText(whp)
|
||||||
|
|
||||||
|
if LocalPlayer():Armor() > 0 then
|
||||||
|
local war = {
|
||||||
|
x = airgap,
|
||||||
|
y = ScrH() - ScreenScale(16) - airgap,
|
||||||
|
font = "ArcCW_16",
|
||||||
|
text = "ARMOR: " .. tostring(math.Round(varmor)),
|
||||||
|
col = col2,
|
||||||
|
shadow = true
|
||||||
|
}
|
||||||
|
|
||||||
|
MyDrawText(war)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
vhp = math.Approach(vhp, self:GetOwner():Health(), RealFrameTime() * 100)
|
||||||
|
varmor = math.Approach(varmor, self:GetOwner():Armor(), RealFrameTime() * 100)
|
||||||
|
|
||||||
|
local clipdiff = math.abs(vclip - self:Clip1())
|
||||||
|
local reservediff = math.abs(vreserve - self:Ammo1())
|
||||||
|
|
||||||
|
if clipdiff == 1 then
|
||||||
|
vclip = self:Clip1()
|
||||||
|
end
|
||||||
|
|
||||||
|
vclip = math.Approach(vclip, self:Clip1(), RealFrameTime() * 30 * clipdiff)
|
||||||
|
vreserve = math.Approach(vreserve, self:Ammo1(), RealFrameTime() * 30 * reservediff)
|
||||||
|
|
||||||
|
if lastwpn != self then
|
||||||
|
vclip = self:Clip1()
|
||||||
|
vreserve = self:Ammo1()
|
||||||
|
vhp = self:GetOwner():Health()
|
||||||
|
varmor = self:GetOwner():Armor()
|
||||||
|
end
|
||||||
|
|
||||||
|
lastwpn = self
|
||||||
|
end
|
159
lua/weapons/arccw_base/cl_laser.lua
Normal file
159
lua/weapons/arccw_base/cl_laser.lua
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
function SWEP:DoLaser(wm)
|
||||||
|
wm = wm or false
|
||||||
|
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if atttbl.Laser then
|
||||||
|
if wm then
|
||||||
|
if !k.WElement then continue end
|
||||||
|
cam.Start3D()
|
||||||
|
self:DrawLaser(atttbl, k.WElement.Model, atttbl.ColorOptionsTable[k.ColorOptionIndex or 1], true)
|
||||||
|
cam.End3D()
|
||||||
|
else
|
||||||
|
if !k.VElement then continue end
|
||||||
|
self:DrawLaser(atttbl, k.VElement.Model, atttbl.ColorOptionsTable[k.ColorOptionIndex or 1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- hook.Add("PostDrawEffects", "ArcCW_ScopeLaser", function()
|
||||||
|
-- -- if !ArcCW.LaserBehavior then return end
|
||||||
|
|
||||||
|
-- -- local wep = LocalPlayer():GetActiveWeapon()
|
||||||
|
|
||||||
|
-- -- if !wep.ArcCW then return end
|
||||||
|
|
||||||
|
-- -- wep:DoLaser(false)
|
||||||
|
-- end)
|
||||||
|
|
||||||
|
local lasermat = Material("arccw/laser")
|
||||||
|
local laserflare = Material("effects/whiteflare")
|
||||||
|
|
||||||
|
local delta = 1
|
||||||
|
|
||||||
|
function SWEP:DrawLaser(ls, lsm, lsc, wm)
|
||||||
|
if !self:GetOwner() then return end
|
||||||
|
if !IsValid(self:GetOwner()) then return end
|
||||||
|
|
||||||
|
if !lsm then return end
|
||||||
|
if !IsValid(lsm) then return end
|
||||||
|
|
||||||
|
local attid = lsm:LookupAttachment(ls.LaserBone or "laser")
|
||||||
|
|
||||||
|
if attid == 0 then
|
||||||
|
attid = lsm:LookupAttachment("muzzle")
|
||||||
|
end
|
||||||
|
|
||||||
|
if attid == 0 then return end
|
||||||
|
|
||||||
|
local ret = lsm:GetAttachment(attid)
|
||||||
|
local pos = ret.Pos
|
||||||
|
local ang = ret.Ang
|
||||||
|
|
||||||
|
local dir = -ang:Right()
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
if self:GetOwner():IsNPC() then
|
||||||
|
dir = -ang:Right()
|
||||||
|
else
|
||||||
|
dir = self:GetOwner():EyeAngles():Forward()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ang:RotateAroundAxis(ang:Up(), 90)
|
||||||
|
|
||||||
|
dir = ang:Forward()
|
||||||
|
|
||||||
|
local eang = self:GetOwner():EyeAngles() + (self:GetOwner():GetViewPunchAngles() * 0.5)
|
||||||
|
|
||||||
|
if self:GetCurrentFiremode().Mode != 0 and !self:GetNWBool("reloading", 0) then
|
||||||
|
delta = math.Approach(delta, self:GetSightDelta(), RealFrameTime() * 1 / 0.15)
|
||||||
|
else
|
||||||
|
delta = math.Approach(delta, 1, RealFrameTime() * 1 / 0.15)
|
||||||
|
end
|
||||||
|
|
||||||
|
dir = Lerp(delta, eang:Forward(), dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
local dir2 = dir
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
dir2 = -ang:Right()
|
||||||
|
end
|
||||||
|
|
||||||
|
local tpos = pos
|
||||||
|
|
||||||
|
-- if !wm then
|
||||||
|
-- tpos = EyePos()
|
||||||
|
-- end
|
||||||
|
|
||||||
|
if ArcCW.LaserBehavior and !wm then
|
||||||
|
ang = EyeAngles() - (self:GetOwner():GetViewPunchAngles() * 0.5)
|
||||||
|
|
||||||
|
if GetConVar("arccw_cheapscopes"):GetBool() then
|
||||||
|
ang = EyeAngles() - (self:GetOwner():GetViewPunchAngles())
|
||||||
|
end
|
||||||
|
|
||||||
|
tpos = EyePos() - Vector(0, 0, 1)
|
||||||
|
pos = tpos
|
||||||
|
dir = ang:Forward()
|
||||||
|
dir2 = dir
|
||||||
|
end
|
||||||
|
|
||||||
|
local di = 128
|
||||||
|
|
||||||
|
local tr = util.TraceLine({
|
||||||
|
start = tpos,
|
||||||
|
endpos = tpos + (dir * 40000),
|
||||||
|
filter = self:GetOwner()
|
||||||
|
})
|
||||||
|
|
||||||
|
local btr = util.TraceLine({
|
||||||
|
start = tpos,
|
||||||
|
endpos = tpos + (dir2 * di),
|
||||||
|
filter = self:GetOwner()
|
||||||
|
})
|
||||||
|
|
||||||
|
local hit = tr.HitPos
|
||||||
|
local didhit = tr.Hit
|
||||||
|
local m = ls.LaserStrength or 1
|
||||||
|
local col = lsc
|
||||||
|
|
||||||
|
if tr.StartSolid then
|
||||||
|
hit = tr.StartPos
|
||||||
|
end
|
||||||
|
|
||||||
|
hit = hit - (EyeAngles():Forward() * 1.5)
|
||||||
|
|
||||||
|
-- local hte = (hit - EyePos()):Length()
|
||||||
|
-- local htl = (pos - EyePos()):Length()
|
||||||
|
|
||||||
|
if tr.StartSolid then return end
|
||||||
|
|
||||||
|
local width = math.Rand(0.05, 0.1) * m
|
||||||
|
|
||||||
|
if !ArcCW.LaserBehavior or wm then
|
||||||
|
render.SetMaterial(lasermat)
|
||||||
|
render.DrawBeam(pos, btr.HitPos, width, 1, 0, col)
|
||||||
|
else
|
||||||
|
cam.IgnoreZ(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
if didhit then
|
||||||
|
local sd = (tr.HitPos - EyePos()):Length()
|
||||||
|
local mult = math.log10(sd) * m
|
||||||
|
|
||||||
|
render.SetMaterial(laserflare)
|
||||||
|
local r1 = math.Rand(4, 6) * mult
|
||||||
|
local r2 = math.Rand(4, 6) * mult
|
||||||
|
|
||||||
|
render.DrawSprite(hit, r1, r2, col)
|
||||||
|
render.DrawSprite(hit, r1 * 0.25, r2 * 0.25, Color(255, 255, 255))
|
||||||
|
end
|
||||||
|
|
||||||
|
if ArcCW.LaserBehavior and !wm then
|
||||||
|
cam.IgnoreZ(false)
|
||||||
|
end
|
||||||
|
end
|
243
lua/weapons/arccw_base/cl_lhik.lua
Normal file
243
lua/weapons/arccw_base/cl_lhik.lua
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
function SWEP:DoLHIKAnimation(key, time)
|
||||||
|
local lhik_model
|
||||||
|
|
||||||
|
local tranim = self:GetBuff_Hook("Hook_LHIK_TranslateAnimation", key)
|
||||||
|
|
||||||
|
key = tranim or key
|
||||||
|
|
||||||
|
for _, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
if !k.VElement then continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if atttbl.LHIK then
|
||||||
|
lhik_model = k.VElement.Model
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !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 !time then time = lhik_model:SequenceDuration(seq) end
|
||||||
|
|
||||||
|
self.LHIKAnimation = seq
|
||||||
|
self.LHIKAnimationStart = CurTime()
|
||||||
|
self.LHIKAnimationTime = time
|
||||||
|
|
||||||
|
self.LHIKAnimation_IsIdle = false
|
||||||
|
|
||||||
|
-- lhik_model:SetCycle(0)
|
||||||
|
-- lhik_model:SetPlaybackRate(dur / time)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
SWEP.LHIKDelta = {}
|
||||||
|
SWEP.LHIKDeltaAng = {}
|
||||||
|
SWEP.ViewModel_Hit = Vector(0, 0, 0)
|
||||||
|
|
||||||
|
function SWEP:GetLHIKAnim()
|
||||||
|
local cyc = (CurTime() - 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()
|
||||||
|
local justhide = false
|
||||||
|
local lhik_model = nil
|
||||||
|
local delta = 1
|
||||||
|
|
||||||
|
local vm = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
|
||||||
|
for _, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if atttbl.LHIKHide then
|
||||||
|
justhide = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if !k.VElement then continue end
|
||||||
|
|
||||||
|
if atttbl.LHIK then
|
||||||
|
lhik_model = k.VElement.Model
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.LHIKTimeline then
|
||||||
|
local tl = self.LHIKTimeline
|
||||||
|
|
||||||
|
if tl[4] <= CurTime() then
|
||||||
|
-- it's over
|
||||||
|
delta = 1
|
||||||
|
elseif tl[3] <= CurTime() then
|
||||||
|
-- transition back to 1
|
||||||
|
delta = (CurTime() - 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 > 0 then
|
||||||
|
lhik_model:SetSequence(seq)
|
||||||
|
lhik_model:SetCycle(delta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif tl[2] <= CurTime() then
|
||||||
|
-- hold 0
|
||||||
|
delta = 0
|
||||||
|
elseif tl[1] <= CurTime() then
|
||||||
|
-- transition to 0
|
||||||
|
delta = (CurTime() - 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
|
||||||
|
end
|
||||||
|
|
||||||
|
if justhide then
|
||||||
|
for _, bone in pairs(ArcCW.LHIKBones) do
|
||||||
|
local vmbone = vm:LookupBone(bone)
|
||||||
|
|
||||||
|
local vmtransform = vm:GetBoneMatrix(vmbone)
|
||||||
|
|
||||||
|
if !vmtransform then return 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() * 64)))
|
||||||
|
newtransform:SetAngles(vm_ang)
|
||||||
|
|
||||||
|
vm:SetBoneMatrix(vmbone, newtransform)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !lhik_model or !IsValid(lhik_model) then return end
|
||||||
|
if justhide then return end
|
||||||
|
|
||||||
|
lhik_model:SetupBones()
|
||||||
|
|
||||||
|
local cyc = (CurTime() - self.LHIKAnimationStart) / self.LHIKAnimationTime
|
||||||
|
|
||||||
|
if self.LHIKAnimation and cyc < 1 then
|
||||||
|
lhik_model:SetSequence(self.LHIKAnimation)
|
||||||
|
lhik_model:SetCycle(cyc)
|
||||||
|
else
|
||||||
|
local key = "idle"
|
||||||
|
|
||||||
|
local tranim = self:GetBuff_Hook("Hook_LHIK_TranslateAnimation", key)
|
||||||
|
|
||||||
|
key = tranim or key
|
||||||
|
|
||||||
|
self:DoLHIKAnimation(key, 1)
|
||||||
|
|
||||||
|
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.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)
|
||||||
|
|
||||||
|
vm:SetBoneMatrix(vmbone, newtransform)
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
|
||||||
|
new[1] = cf_deltapos[2]
|
||||||
|
new[2] = cf_deltapos[1]
|
||||||
|
new[3] = cf_deltapos[3]
|
||||||
|
|
||||||
|
self.ViewModel_Hit = LerpVector(0.25, self.ViewModel_Hit, new / cf)
|
||||||
|
end
|
||||||
|
end
|
292
lua/weapons/arccw_base/cl_presets.lua
Normal file
292
lua/weapons/arccw_base/cl_presets.lua
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
-- atts are comma separated
|
||||||
|
-- optic_mrs,,,perk_quickdraw,ammo_match
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
return files
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:LoadPreset(filename)
|
||||||
|
filename = filename or "autosave"
|
||||||
|
if !GetConVar("arccw_autosave"):GetBool() then
|
||||||
|
if filename == "autosave" then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
if filename != "autosave" then
|
||||||
|
surface.PlaySound("weapons/arccw/install.wav")
|
||||||
|
end
|
||||||
|
|
||||||
|
filename = ArcCW.PresetPath .. self:GetPresetBase() .. "/" .. filename .. ".txt"
|
||||||
|
|
||||||
|
if !file.Exists(filename, "DATA") then return end
|
||||||
|
|
||||||
|
local f = file.Open(filename, "r", "DATA")
|
||||||
|
|
||||||
|
if !f then return end
|
||||||
|
|
||||||
|
for i = 1, table.Count(self.Attachments) do
|
||||||
|
local att = f:ReadLine()
|
||||||
|
|
||||||
|
if !att then continue end
|
||||||
|
|
||||||
|
att = string.Trim(att, "\n")
|
||||||
|
|
||||||
|
if !att then continue end
|
||||||
|
|
||||||
|
if !self.Attachments[i] then continue end
|
||||||
|
if att == self.Attachments[i].Installed then continue end
|
||||||
|
|
||||||
|
self:Detach(i, true)
|
||||||
|
|
||||||
|
if !ArcCW.AttachmentTable[att] then continue end
|
||||||
|
|
||||||
|
self:Attach(i, att, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
f:Close()
|
||||||
|
|
||||||
|
self:SavePreset()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SavePreset(filename)
|
||||||
|
filename = filename or "autosave"
|
||||||
|
|
||||||
|
local str = ""
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if k.Installed then
|
||||||
|
str = str .. k.Installed .. "\n"
|
||||||
|
else
|
||||||
|
str = str .. "\n"
|
||||||
|
end
|
||||||
|
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(ScreenScale(256), ScreenScale(26))
|
||||||
|
text:Center()
|
||||||
|
text:RequestFocus()
|
||||||
|
text:SetFont("ArcCW_24")
|
||||||
|
text:SetText("")
|
||||||
|
|
||||||
|
local accept = vgui.Create("DButton", bg)
|
||||||
|
accept:SetSize((ScreenScale(256) - ScreenScale(2)) / 2, ScreenScale(14))
|
||||||
|
accept:SetText("")
|
||||||
|
accept:SetPos((ScrW() - ScreenScale(256)) / 2, ((ScrH() - ScreenScale(14)) / 2) + ScreenScale(26) + ScreenScale(2))
|
||||||
|
|
||||||
|
accept.OnMousePressed = function(spaa, kc)
|
||||||
|
local txt = text:GetText()
|
||||||
|
txt = string.sub(txt, 0, 36)
|
||||||
|
self:SavePreset(txt)
|
||||||
|
bg:Close()
|
||||||
|
bg:Remove()
|
||||||
|
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(ScreenScale(2), ScreenScale(1))
|
||||||
|
surface.SetFont("ArcCW_12")
|
||||||
|
surface.DrawText(txt)
|
||||||
|
end
|
||||||
|
|
||||||
|
local cancel = vgui.Create("DButton", bg)
|
||||||
|
cancel:SetSize((ScreenScale(256) - ScreenScale(2)) / 2, ScreenScale(14))
|
||||||
|
cancel:SetText("")
|
||||||
|
cancel:SetPos(((ScrW() - ScreenScale(256)) / 2) + ScreenScale(128 + 1), ((ScrH() - ScreenScale(14)) / 2) + ScreenScale(26) + ScreenScale(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(ScreenScale(2), ScreenScale(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(ScreenScale(128), ScreenScale(14))
|
||||||
|
cancel:SetText("")
|
||||||
|
cancel:SetPos((ScrW() - ScreenScale(128)) / 2, ScrH() - ScreenScale(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(ScreenScale(2), ScreenScale(1))
|
||||||
|
surface.SetFont("ArcCW_12")
|
||||||
|
surface.DrawText(txt)
|
||||||
|
end
|
||||||
|
|
||||||
|
local presetsmenu = vgui.Create("DScrollPanel", bg)
|
||||||
|
presetsmenu:SetText("")
|
||||||
|
presetsmenu:SetSize(ScreenScale(256), ScrH() - ScreenScale(64))
|
||||||
|
presetsmenu:SetPos((ScrW() - ScreenScale(256)) / 2, ScreenScale(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 k == "autosave.txt" then continue end
|
||||||
|
local preset = vgui.Create("DButton", presetsmenu)
|
||||||
|
preset:SetSize(ScreenScale(254), ScreenScale(14))
|
||||||
|
preset:SetText("")
|
||||||
|
preset:Dock(TOP)
|
||||||
|
preset:DockMargin( 0, 0, 0, ScreenScale(2) )
|
||||||
|
|
||||||
|
preset.PresetName = string.sub(k, 1, -5)
|
||||||
|
|
||||||
|
preset.OnMousePressed = function(spaa, kc)
|
||||||
|
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(ScreenScale(2), ScreenScale(1))
|
||||||
|
surface.SetFont("ArcCW_12")
|
||||||
|
surface.DrawText(string.upper(spaa.PresetName))
|
||||||
|
end
|
||||||
|
c = c + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if c == 0 then
|
||||||
|
local label = vgui.Create("DLabel", presetsmenu)
|
||||||
|
label:SetSize(ScreenScale(254), ScreenScale(14))
|
||||||
|
label:SetText("")
|
||||||
|
label:Dock(TOP)
|
||||||
|
label:DockMargin( 0, 0, 0, ScreenScale(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(ScreenScale(2), ScreenScale(1))
|
||||||
|
surface.SetFont("ArcCW_12")
|
||||||
|
surface.DrawText(txt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ClosePresetMenu()
|
||||||
|
end
|
65
lua/weapons/arccw_base/cl_scope.lua
Normal file
65
lua/weapons/arccw_base/cl_scope.lua
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
function SWEP:AdjustMouseSensitivity()
|
||||||
|
if self:GetState() != ArcCW.STATE_SIGHTS then return end
|
||||||
|
|
||||||
|
local irons = self:GetActiveSights()
|
||||||
|
|
||||||
|
return 1 / (irons.Magnification + (irons.ScopeMagnification or 0))
|
||||||
|
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:EmitSound(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:EmitSound(irons.ZoomSound or "", 75, 100, 1, CHAN_ITEM)
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:CalcView(ply, pos, ang, fov)
|
||||||
|
if !GetConVar("arccw_shake"):GetBool() then return end
|
||||||
|
|
||||||
|
return pos, ang + (AngleRand() * self.RecoilAmount * 0.008), fov
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ShouldGlint()
|
||||||
|
return self:GetBuff_Override("ScopeGlint") and self:GetNWBool("state") == ArcCW.STATE_SIGHTS
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DoScopeGlint()
|
||||||
|
end
|
424
lua/weapons/arccw_base/cl_viewmodel.lua
Normal file
424
lua/weapons/arccw_base/cl_viewmodel.lua
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
SWEP.ActualVMData = false
|
||||||
|
|
||||||
|
local function ApproachVector(vec1, vec2, d)
|
||||||
|
local vec3 = Vector()
|
||||||
|
vec3[1] = math.Approach(vec1[1], vec2[1], d)
|
||||||
|
vec3[2] = math.Approach(vec1[2], vec2[2], d)
|
||||||
|
vec3[3] = math.Approach(vec1[3], vec2[3], d)
|
||||||
|
|
||||||
|
return vec3
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ApproachAngleA(vec1, vec2, d)
|
||||||
|
local vec3 = Angle()
|
||||||
|
vec3[1] = math.ApproachAngle(vec1[1], vec2[1], d)
|
||||||
|
vec3[2] = math.ApproachAngle(vec1[2], vec2[2], d)
|
||||||
|
vec3[3] = math.ApproachAngle(vec1[3], vec2[3], d)
|
||||||
|
|
||||||
|
return vec3
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetViewModelPosition(pos, ang)
|
||||||
|
local oldpos = Vector()
|
||||||
|
local oldang = Angle()
|
||||||
|
|
||||||
|
local ft = RealFrameTime()
|
||||||
|
|
||||||
|
local asight = self:GetActiveSights()
|
||||||
|
|
||||||
|
oldpos:Set(pos)
|
||||||
|
oldang:Set(ang)
|
||||||
|
|
||||||
|
ang = ang - (self:GetOwner():GetViewPunchAngles() * 0.5)
|
||||||
|
|
||||||
|
actual = self.ActualVMData or {pos = Vector(0, 0, 0), ang = Angle(0, 0, 0), down = 1, sway = 1, bob = 1}
|
||||||
|
|
||||||
|
local target = {
|
||||||
|
pos = self:GetBuff_Override("Override_ActivePos") or self.ActivePos,
|
||||||
|
ang = self:GetBuff_Override("Override_ActiveAng") or self.ActiveAng,
|
||||||
|
down = 1,
|
||||||
|
sway = 2,
|
||||||
|
bob = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
local vm_right = GetConVar("arccw_vm_right"):GetFloat()
|
||||||
|
local vm_up = GetConVar("arccw_vm_up"):GetFloat()
|
||||||
|
local vm_forward = GetConVar("arccw_vm_forward"):GetFloat()
|
||||||
|
|
||||||
|
target.pos = target.pos + Vector(vm_right, vm_forward, vm_up)
|
||||||
|
|
||||||
|
local state = self:GetState()
|
||||||
|
|
||||||
|
if self:GetOwner():Crouching() then
|
||||||
|
target.down = 0
|
||||||
|
if self.CrouchPos then
|
||||||
|
target.pos = self.CrouchPos
|
||||||
|
target.ang = self.CrouchAng
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:InBipod() then
|
||||||
|
target.pos = target.pos + ((self.BipodAngle - self:GetOwner():EyeAngles()):Right() * -4)
|
||||||
|
target.sway = 0.2
|
||||||
|
end
|
||||||
|
|
||||||
|
local sighted = self.Sighted or state == ArcCW.STATE_SIGHTS
|
||||||
|
if game.SinglePlayer() then
|
||||||
|
sighted = state == ArcCW.STATE_SIGHTS
|
||||||
|
end
|
||||||
|
|
||||||
|
local sprinted = self.Sprinted or state == ArcCW.STATE_SPRINT
|
||||||
|
if game.SinglePlayer() then
|
||||||
|
sprinted = state == ArcCW.STATE_SPRINT
|
||||||
|
end
|
||||||
|
|
||||||
|
if state == ArcCW.STATE_CUSTOMIZE then
|
||||||
|
target = {
|
||||||
|
pos = Vector(),
|
||||||
|
ang = Angle(),
|
||||||
|
down = 1,
|
||||||
|
sway = 3,
|
||||||
|
bob = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
local mx, my = input.GetCursorPos()
|
||||||
|
|
||||||
|
mx = 2 * mx / ScrW()
|
||||||
|
my = 2 * my / ScrH()
|
||||||
|
|
||||||
|
target.pos:Set(self.CustomizePos)
|
||||||
|
target.ang:Set(self.CustomizeAng)
|
||||||
|
|
||||||
|
target.pos = target.pos + Vector(mx, 0, my)
|
||||||
|
target.ang = target.ang + Angle(0, my * 2, mx * 2)
|
||||||
|
|
||||||
|
if self.InAttMenu then
|
||||||
|
target.ang = target.ang + Angle(0, -5, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif (sprinted or (self:GetCurrentFiremode().Mode == 0 and !sighted)) and !(self:GetBuff_Override("Override_ShootWhileSprint") or self.ShootWhileSprint) then
|
||||||
|
target = {
|
||||||
|
pos = self.HolsterPos,
|
||||||
|
ang = Angle(),
|
||||||
|
down = 1,
|
||||||
|
sway = 4,
|
||||||
|
bob = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
target.ang:Set(self.HolsterAng)
|
||||||
|
|
||||||
|
if ang.p < -15 then
|
||||||
|
target.ang.p = target.ang.p + ang.p + 15
|
||||||
|
end
|
||||||
|
|
||||||
|
target.ang.p = math.Clamp(target.ang.p, -80, 80)
|
||||||
|
elseif sighted then
|
||||||
|
local irons = self:GetActiveSights()
|
||||||
|
|
||||||
|
target = {
|
||||||
|
pos = irons.Pos,
|
||||||
|
ang = irons.Ang,
|
||||||
|
evpos = irons.EVPos or Vector(0, 0, 0),
|
||||||
|
evang = irons.EVAng or Angle(0, 0, 0),
|
||||||
|
down = 0,
|
||||||
|
sway = 0.1,
|
||||||
|
bob = 0.1,
|
||||||
|
}
|
||||||
|
|
||||||
|
local sr = self:GetBuff_Override("Override_AddSightRoll")
|
||||||
|
|
||||||
|
if sr then
|
||||||
|
target.ang = Angle()
|
||||||
|
|
||||||
|
target.ang:Set(irons.Ang)
|
||||||
|
target.ang.r = sr
|
||||||
|
end
|
||||||
|
|
||||||
|
-- local anchor = irons.AnchorBone
|
||||||
|
|
||||||
|
-- if anchor then
|
||||||
|
-- local vm = self:GetOwner():GetViewModel()
|
||||||
|
-- local bone = vm:LookupBone(anchor)
|
||||||
|
-- local bpos, bang = vm:GetBonePosition(bone)
|
||||||
|
|
||||||
|
-- print(bpos)
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
|
||||||
|
local deg = self:BarrelHitWall()
|
||||||
|
|
||||||
|
if deg > 0 then
|
||||||
|
target = {
|
||||||
|
pos = LerpVector(deg, target.pos, self.HolsterPos),
|
||||||
|
ang = LerpAngle(deg, target.ang, self.HolsterAng),
|
||||||
|
down = 2,
|
||||||
|
sway = 2,
|
||||||
|
bob = 2,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
if isangle(target.ang) then
|
||||||
|
target.ang = Angle(target.ang)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.InProcDraw then
|
||||||
|
self.InProcHolster = false
|
||||||
|
local delta = math.Clamp((CurTime() - self.ProcDrawTime) / (0.25 * self:GetBuff_Mult("Mult_HolsterTime")), 0, 1)
|
||||||
|
target = {
|
||||||
|
pos = LerpVector(delta, Vector(0, -30, -30), target.pos),
|
||||||
|
ang = LerpAngle(delta, Angle(40, 30, 0), target.ang),
|
||||||
|
down = target.down,
|
||||||
|
sway = target.sway,
|
||||||
|
bob = target.bob,
|
||||||
|
}
|
||||||
|
|
||||||
|
if delta == 1 then
|
||||||
|
self.InProcDraw = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.InProcHolster then
|
||||||
|
self.InProcDraw = false
|
||||||
|
local delta = 1 - math.Clamp((CurTime() - self.ProcHolsterTime) / 0.25, 0, 1)
|
||||||
|
target = {
|
||||||
|
pos = LerpVector(delta, Vector(0, -30, -30), target.pos),
|
||||||
|
ang = LerpAngle(delta, Angle(40, 30, 0), target.ang),
|
||||||
|
down = target.down,
|
||||||
|
sway = target.sway,
|
||||||
|
bob = target.bob,
|
||||||
|
}
|
||||||
|
|
||||||
|
if delta == 0 then
|
||||||
|
self.InProcHolster = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.InProcBash then
|
||||||
|
self.InProcDraw = false
|
||||||
|
|
||||||
|
local mult = self:GetBuff_Mult("Mult_MeleeTime")
|
||||||
|
local mt = self.MeleeTime * mult
|
||||||
|
|
||||||
|
local delta = 1 - math.Clamp((CurTime() - self.ProcBashTime) / mt, 0, 1)
|
||||||
|
|
||||||
|
local bp = self.BashPos
|
||||||
|
local ba = self.BashAng
|
||||||
|
|
||||||
|
if delta > 0.3 then
|
||||||
|
bp = self.BashPreparePos
|
||||||
|
ba = self.BashPrepareAng
|
||||||
|
delta = (delta - 0.5) * 2
|
||||||
|
else
|
||||||
|
delta = delta * 2
|
||||||
|
end
|
||||||
|
|
||||||
|
target = {
|
||||||
|
pos = LerpVector(delta, bp, target.pos),
|
||||||
|
ang = LerpAngle(delta, ba, target.ang),
|
||||||
|
down = target.down,
|
||||||
|
sway = target.sway,
|
||||||
|
bob = target.bob,
|
||||||
|
speed = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
if delta == 0 then
|
||||||
|
self.InProcBash = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.ViewModel_Hit then
|
||||||
|
local nap = Vector()
|
||||||
|
|
||||||
|
nap[1] = self.ViewModel_Hit[1]
|
||||||
|
nap[2] = self.ViewModel_Hit[2]
|
||||||
|
nap[3] = self.ViewModel_Hit[3]
|
||||||
|
|
||||||
|
nap[1] = math.Clamp(nap[1], -1, 1)
|
||||||
|
nap[2] = math.Clamp(nap[2], -1, 1)
|
||||||
|
nap[3] = math.Clamp(nap[3], -1, 1)
|
||||||
|
|
||||||
|
target.pos = target.pos + nap
|
||||||
|
|
||||||
|
if !self.ViewModel_Hit:IsZero() then
|
||||||
|
local naa = Angle()
|
||||||
|
|
||||||
|
naa[1] = self.ViewModel_Hit[1]
|
||||||
|
naa[2] = self.ViewModel_Hit[2]
|
||||||
|
naa[3] = self.ViewModel_Hit[3]
|
||||||
|
|
||||||
|
naa[1] = math.Clamp(naa[1], -1, 1)
|
||||||
|
naa[2] = math.Clamp(naa[2], -1, 1)
|
||||||
|
naa[3] = math.Clamp(naa[3], -1, 1)
|
||||||
|
|
||||||
|
target.ang = target.ang + (naa * 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
local nvmh = Vector(0, 0, 0)
|
||||||
|
|
||||||
|
local spd = self.ViewModel_Hit:Length()
|
||||||
|
|
||||||
|
nvmh[1] = math.Approach(self.ViewModel_Hit[1], 0, ft * 5 * spd)
|
||||||
|
nvmh[2] = math.Approach(self.ViewModel_Hit[2], 0, ft * 5 * spd)
|
||||||
|
nvmh[3] = math.Approach(self.ViewModel_Hit[3], 0, ft * 5 * spd)
|
||||||
|
|
||||||
|
self.ViewModel_Hit = nvmh
|
||||||
|
|
||||||
|
-- local nvma = Angle(0, 0, 0)
|
||||||
|
|
||||||
|
-- local spd2 = 360
|
||||||
|
|
||||||
|
-- nvma[1] = math.ApproachAngle(self.ViewModel_HitAng[1], 0, ft * 5 * spd2)
|
||||||
|
-- nvma[2] = math.ApproachAngle(self.ViewModel_HitAng[2], 0, ft * 5 * spd2)
|
||||||
|
-- nvma[3] = math.ApproachAngle(self.ViewModel_HitAng[3], 0, ft * 5 * spd2)
|
||||||
|
|
||||||
|
-- self.ViewModel_HitAng = nvma
|
||||||
|
end
|
||||||
|
|
||||||
|
target.pos = target.pos + (VectorRand() * self.RecoilAmount * 0.2)
|
||||||
|
|
||||||
|
local speed = target.speed or 3
|
||||||
|
|
||||||
|
speed = 1 / self:GetSightTime() * speed * ft
|
||||||
|
|
||||||
|
actual.pos = LerpVector(speed, actual.pos, target.pos)
|
||||||
|
actual.ang = LerpAngle(speed, actual.ang, target.ang)
|
||||||
|
actual.down = Lerp(speed, actual.down, target.down)
|
||||||
|
actual.sway = Lerp(speed, actual.sway, target.sway)
|
||||||
|
actual.bob = Lerp(speed, actual.bob, target.bob)
|
||||||
|
actual.evpos = Lerp(speed, actual.evpos or Vector(0, 0, 0), target.evpos or Vector(0, 0, 0))
|
||||||
|
actual.evang = Lerp(speed, actual.evang or Angle(0, 0, 0), target.evang or Angle(0, 0, 0))
|
||||||
|
|
||||||
|
actual.pos = ApproachVector(actual.pos, target.pos, speed * 0.1)
|
||||||
|
actual.ang = ApproachAngleA(actual.ang, target.ang, speed * 0.1)
|
||||||
|
actual.down = math.Approach(actual.down, target.down, speed * 0.1)
|
||||||
|
|
||||||
|
self.SwayScale = actual.sway
|
||||||
|
self.BobScale = actual.bob
|
||||||
|
|
||||||
|
pos = pos + self.RecoilPunchBack * -oldang:Forward()
|
||||||
|
pos = pos + self.RecoilPunchSide * oldang:Right()
|
||||||
|
pos = pos + self.RecoilPunchUp * -oldang:Up()
|
||||||
|
|
||||||
|
ang:RotateAroundAxis( oldang:Right(), actual.ang.x )
|
||||||
|
ang:RotateAroundAxis( oldang:Up(), actual.ang.y )
|
||||||
|
ang:RotateAroundAxis( oldang:Forward(), actual.ang.z )
|
||||||
|
|
||||||
|
ang:RotateAroundAxis( oldang:Right(), actual.evang.x )
|
||||||
|
ang:RotateAroundAxis( oldang:Up(), actual.evang.y )
|
||||||
|
ang:RotateAroundAxis( oldang:Forward(), actual.evang.z )
|
||||||
|
|
||||||
|
pos = pos + (oldang:Right() * actual.evpos.x)
|
||||||
|
pos = pos + (oldang:Forward() * actual.evpos.y)
|
||||||
|
pos = pos + (oldang:Up() * actual.evpos.z)
|
||||||
|
|
||||||
|
pos = pos + actual.pos.x * ang:Right()
|
||||||
|
pos = pos + actual.pos.y * ang:Forward()
|
||||||
|
pos = pos + actual.pos.z * ang:Up()
|
||||||
|
|
||||||
|
pos = pos - Vector(0, 0, actual.down)
|
||||||
|
|
||||||
|
if asight and asight.Holosight then
|
||||||
|
ang = ang - (self:GetOwner():GetViewPunchAngles() * 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.ActualVMData = actual
|
||||||
|
|
||||||
|
return pos, ang
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ShouldCheapWorldModel()
|
||||||
|
return !GetConVar("arccw_att_showothers"):GetBool()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DrawWorldModel()
|
||||||
|
if !IsValid(self:GetOwner()) and GetConVar("arccw_2d3d"):GetBool() then
|
||||||
|
if (EyePos() - self:GetPos()):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:GetPos() + Vector(0, 0, 16), ang, 0.1)
|
||||||
|
surface.SetFont("ArcCW_32_Unscaled")
|
||||||
|
|
||||||
|
local w = surface.GetTextSize(self.PrintName)
|
||||||
|
|
||||||
|
surface.SetTextPos(-w / 2, 0)
|
||||||
|
surface.SetTextColor(255, 255, 255, 255)
|
||||||
|
surface.DrawText(self.PrintName)
|
||||||
|
|
||||||
|
surface.SetFont("ArcCW_24_Unscaled")
|
||||||
|
|
||||||
|
local t = tostring(self:CountAttachments()) .. " Attachments"
|
||||||
|
|
||||||
|
w = surface.GetTextSize(t)
|
||||||
|
|
||||||
|
surface.SetTextPos(-w / 2, 32)
|
||||||
|
surface.SetTextColor(255, 255, 255, 255)
|
||||||
|
surface.DrawText(t)
|
||||||
|
cam.End3D2D()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ShouldCheapWorldModel() then
|
||||||
|
self:DrawModel()
|
||||||
|
else
|
||||||
|
self:DrawCustomModel(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:DoLaser(true)
|
||||||
|
|
||||||
|
if self:ShouldGlint() then
|
||||||
|
self:DoScopeGlint()
|
||||||
|
end
|
||||||
|
|
||||||
|
if !self.CertainAboutAtts then
|
||||||
|
net.Start("arccw_rqwpnnet")
|
||||||
|
net.WriteEntity(self)
|
||||||
|
net.SendToServer()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:PreDrawViewModel(vm)
|
||||||
|
if !vm then return end
|
||||||
|
|
||||||
|
if GetConVar("arccw_cheapscopesautoconfig"):GetBool() then
|
||||||
|
-- auto configure what the best option is likely to be
|
||||||
|
-- if you can't get more than 45fps you probably want cheap scopes
|
||||||
|
|
||||||
|
local fps = 1 / RealFrameTime()
|
||||||
|
|
||||||
|
if fps >= 45 then
|
||||||
|
GetConVar("arccw_cheapscopes"):SetBool(false)
|
||||||
|
else
|
||||||
|
GetConVar("arccw_cheapscopes"):SetBool(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
GetConVar("arccw_cheapscopesautoconfig"):SetBool(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
local asight = self:GetActiveSights()
|
||||||
|
|
||||||
|
if GetConVar("arccw_cheapscopes"):GetBool() and self:GetSightDelta() < 1 and asight.MagnifiedOptic then
|
||||||
|
self:FormCheapScope()
|
||||||
|
end
|
||||||
|
|
||||||
|
self:DrawCustomModel(false)
|
||||||
|
|
||||||
|
self:DoLHIK()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:PostDrawViewModel()
|
||||||
|
|
||||||
|
if ArcCW.Overdraw then
|
||||||
|
ArcCW.Overdraw = false
|
||||||
|
else
|
||||||
|
self:DoLaser()
|
||||||
|
self:DoHolosight()
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_CUSTOMIZE then
|
||||||
|
self:BlurNotWeapon()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
273
lua/weapons/arccw_base/sh_anim.lua
Normal file
273
lua/weapons/arccw_base/sh_anim.lua
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
if SERVER then
|
||||||
|
|
||||||
|
function SWEP:DoLHIKAnimation(key, time)
|
||||||
|
if game.SinglePlayer() then
|
||||||
|
net.Start("arccw_sp_lhikanim")
|
||||||
|
net.WriteString(key)
|
||||||
|
net.WriteFloat(time)
|
||||||
|
net.Send(self:GetOwner())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:PlayAnimation(key, mult, pred, startfrom, tt, skipholster)
|
||||||
|
mult = mult or 1
|
||||||
|
pred = pred or false
|
||||||
|
startfrom = startfrom or 0
|
||||||
|
tt = tt or false
|
||||||
|
skipholster = skipholster or false
|
||||||
|
|
||||||
|
if !self.Animations[key] then return end
|
||||||
|
|
||||||
|
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
|
||||||
|
-- print(key)
|
||||||
|
|
||||||
|
local anim = self.Animations[key]
|
||||||
|
|
||||||
|
local tranim = self:GetBuff_Hook("Hook_TranslateAnimation", key)
|
||||||
|
|
||||||
|
if tranim == false then return end
|
||||||
|
|
||||||
|
if self.Animations[tranim] then
|
||||||
|
anim = self.Animations[tranim]
|
||||||
|
end
|
||||||
|
|
||||||
|
if anim.Mult then
|
||||||
|
mult = mult * anim.Mult
|
||||||
|
end
|
||||||
|
|
||||||
|
if game.SinglePlayer() and SERVER and pred then
|
||||||
|
net.Start("arccw_sp_anim")
|
||||||
|
net.WriteString(key)
|
||||||
|
net.WriteFloat(mult)
|
||||||
|
net.WriteFloat(startfrom)
|
||||||
|
net.Send(self:GetOwner())
|
||||||
|
end
|
||||||
|
|
||||||
|
if anim.ProcHolster and !skipholster then
|
||||||
|
self:ProceduralHolster()
|
||||||
|
self:SetTimer(0.25, function()
|
||||||
|
self:PlayAnimation(anim, mult, true, startfrom, tt, true)
|
||||||
|
end)
|
||||||
|
if tt then
|
||||||
|
self:SetNextPrimaryFire(CurTime() + 0.25)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if anim.ViewPunchTable 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) then
|
||||||
|
if st < 0 then continue end
|
||||||
|
if self:GetOwner():IsPlayer() then
|
||||||
|
self:SetTimer(st, function() if !game.SinglePlayer() and !IsFirstTimePredicted() then return end self:GetOwner():ViewPunch(v.p or Vector(0, 0, 0)) end, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isnumber(anim.ShellEjectAt) then
|
||||||
|
self:SetTimer(anim.ShellEjectAt, function()
|
||||||
|
self:DoShellEject()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local vm = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
if !vm then return end
|
||||||
|
if !IsValid(vm) then return end
|
||||||
|
|
||||||
|
self:KillTimer("idlereset")
|
||||||
|
|
||||||
|
self:GetAnimTime(key)
|
||||||
|
|
||||||
|
local ttime = (anim.Time * mult) - startfrom
|
||||||
|
|
||||||
|
if startfrom > anim.Time then return end
|
||||||
|
|
||||||
|
if tt then
|
||||||
|
self:SetNextPrimaryFire(CurTime() + ttime)
|
||||||
|
end
|
||||||
|
|
||||||
|
if anim.LHIK then
|
||||||
|
self.LHIKTimeline = {
|
||||||
|
CurTime() - startfrom,
|
||||||
|
CurTime() - startfrom + (anim.LHIKIn or 0.1) * mult,
|
||||||
|
CurTime() - startfrom + ttime - (anim.LHIKOut or 0.1) * mult,
|
||||||
|
CurTime() - startfrom + ttime
|
||||||
|
}
|
||||||
|
|
||||||
|
if !anim.LHIKIn or anim.LHIKIn == 0 then
|
||||||
|
self.LHIKTimeline[1] = 0
|
||||||
|
self.LHIKTimeline[2] = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if !anim.LHIKOut or anim.LHIKOut == 0 then
|
||||||
|
self.LHIKTimeline[3] = math.huge
|
||||||
|
self.LHIKTimeline[4] = math.huge
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if anim.LastClip1OutTime then
|
||||||
|
self.LastClipOutTime = CurTime() + ((anim.LastClip1OutTime * mult) - startfrom)
|
||||||
|
end
|
||||||
|
|
||||||
|
local seq = anim.Source
|
||||||
|
|
||||||
|
if anim.RareSource and math.random(1, 100) <= 1 then
|
||||||
|
seq = anim.RareSource
|
||||||
|
end
|
||||||
|
|
||||||
|
if istable(seq) then
|
||||||
|
seq["BaseClass"] = nil
|
||||||
|
|
||||||
|
seq = table.Random(seq)
|
||||||
|
end
|
||||||
|
|
||||||
|
if isstring(seq) then
|
||||||
|
seq = vm:LookupSequence(seq)
|
||||||
|
end
|
||||||
|
|
||||||
|
vm:SendViewModelMatchingSequence(seq)
|
||||||
|
|
||||||
|
local framestorealtime = 1
|
||||||
|
|
||||||
|
if anim.FrameRate then
|
||||||
|
framestorealtime = 1 / anim.FrameRate
|
||||||
|
end
|
||||||
|
|
||||||
|
local dur = vm:SequenceDuration()
|
||||||
|
|
||||||
|
vm:SetPlaybackRate(dur / (ttime + startfrom))
|
||||||
|
|
||||||
|
if anim.Checkpoints then
|
||||||
|
self.CheckpointAnimation = key
|
||||||
|
self.CheckpointTime = startfrom
|
||||||
|
|
||||||
|
for i, k in pairs(anim.Checkpoints) do
|
||||||
|
if !k then continue end
|
||||||
|
if istable(k) then continue end
|
||||||
|
local realtime = k * framestorealtime
|
||||||
|
|
||||||
|
if realtime > startfrom then
|
||||||
|
self:SetTimer((realtime * mult) - startfrom, function()
|
||||||
|
self.CheckpointAnimation = key
|
||||||
|
self.CheckpointTime = realtime
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
if startfrom >= 0 then
|
||||||
|
vm:SetAnimTime(CurTime() - startfrom)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if anim.TPAnim then
|
||||||
|
if anim.TPAnimStartTime then
|
||||||
|
local aseq = self:GetOwner():SelectWeightedSequence(anim.TPAnim)
|
||||||
|
if aseq then
|
||||||
|
self:GetOwner():AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, aseq, anim.TPAnimStartTime, true )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:GetOwner():DoAnimationEvent(anim.TPAnim)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:PlaySoundTable(anim.SoundTable or {}, 1 / mult, startfrom)
|
||||||
|
|
||||||
|
self:SetTimer(ttime, function()
|
||||||
|
self:NextAnimation()
|
||||||
|
|
||||||
|
if anim.Checkpoints then
|
||||||
|
self.CheckpointAnimation = nil
|
||||||
|
self.CheckpointTime = 0
|
||||||
|
end
|
||||||
|
end, key)
|
||||||
|
if key != "idle" then
|
||||||
|
self:SetTimer(ttime, function()
|
||||||
|
if self:GetState() == ArcCW.STATE_SPRINT and self.Animations.idle_sprint then
|
||||||
|
if self:Clip1() == 0 and self.Animations.idle_sprint_empty then
|
||||||
|
self:PlayAnimation("idle_sprint_empty", 1, pred)
|
||||||
|
else
|
||||||
|
self:PlayAnimation("idle_sprint", 1, pred)
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:InBipod() and self.Animations.idle_bipod then
|
||||||
|
if self:Clip1() == 0 and self.Animations.idle_bipod_empty then
|
||||||
|
self:PlayAnimation("idle_bipod_empty", 1, pred)
|
||||||
|
else
|
||||||
|
self:PlayAnimation("idle_bipod", 1, pred)
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS and self.Animations.idle_sights then
|
||||||
|
if self:Clip1() == 0 and self.Animations.idle_sights_empty then
|
||||||
|
self:PlayAnimation("idle_sights_empty", 1, pred)
|
||||||
|
else
|
||||||
|
self:PlayAnimation("idle_sights", 1, pred)
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:Clip1() == 0 and self.Animations.idle_empty then
|
||||||
|
self:PlayAnimation("idle_empty", 1, pred)
|
||||||
|
else
|
||||||
|
self:PlayAnimation("idle", 1, pred)
|
||||||
|
end
|
||||||
|
end, "idlereset")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetAnimTime(key)
|
||||||
|
local anim = self.Animations[key]
|
||||||
|
|
||||||
|
if !anim then return end
|
||||||
|
|
||||||
|
if !anim.Time then
|
||||||
|
local tseq = anim.Source
|
||||||
|
|
||||||
|
if istable(tseq) then
|
||||||
|
tseq["BaseClass"] = nil -- god I hate Lua inheritance
|
||||||
|
tseq = tseq[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
tseq = vm:LookupSequence(tseq)
|
||||||
|
|
||||||
|
anim.Time = vm:SequenceDuration(tseq) or 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return anim.Time
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:QueueAnimation(key, mult, pred, sf)
|
||||||
|
pred = pred or false
|
||||||
|
sf = sf or false
|
||||||
|
table.insert(self.AnimQueue, {k = key, m = mult, p = pred, sf = sf})
|
||||||
|
|
||||||
|
if table.Count(self.AnimQueue) == 0 then
|
||||||
|
self:NextAnimation()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:NextAnimation()
|
||||||
|
if table.Count(self.AnimQueue) == 0 then return end
|
||||||
|
|
||||||
|
local anim = table.remove(self.AnimQueue, 1)
|
||||||
|
|
||||||
|
self:PlayAnimation(anim.k, anim.m, anim.p, 0, anim.sf)
|
||||||
|
end
|
840
lua/weapons/arccw_base/sh_attach.lua
Normal file
840
lua/weapons/arccw_base/sh_attach.lua
Normal file
@ -0,0 +1,840 @@
|
|||||||
|
ArcCW.ConVar_BuffMults = {
|
||||||
|
["Mult_Damage"] = "arccw_mult_damage",
|
||||||
|
["Mult_DamageMin"] = "arccw_mult_damage",
|
||||||
|
["Mult_DamageNPC"] = "arccw_mult_npcdamage",
|
||||||
|
["Mult_HipDispersion"] = "arccw_mult_hipfire",
|
||||||
|
["Mult_ReloadTime"] = "arccw_mult_reloadtime",
|
||||||
|
["Mult_SightTime"] = "arccw_mult_sighttime",
|
||||||
|
["Mult_Range"] = "arccw_mult_range",
|
||||||
|
["Mult_Recoil"] = "arccw_mult_recoil",
|
||||||
|
["Mult_MoveDispersion"] = "arccw_mult_movedisp",
|
||||||
|
["Mult_Penetration"] = "arccw_mult_penetration"
|
||||||
|
}
|
||||||
|
|
||||||
|
function SWEP:GetBuff_Hook(buff, data)
|
||||||
|
-- call through hook function, args = data. return nil to do nothing. return false to prevent thing from happening.
|
||||||
|
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if !atttbl then continue end
|
||||||
|
|
||||||
|
if isfunction(atttbl[buff]) then
|
||||||
|
local ret = atttbl[buff](self, data)
|
||||||
|
|
||||||
|
if ret == nil then continue end
|
||||||
|
|
||||||
|
if ret == false then return end
|
||||||
|
|
||||||
|
data = ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local cfm = self:GetCurrentFiremode()
|
||||||
|
|
||||||
|
if cfm and isfunction(cfm[buff]) then
|
||||||
|
local ret = cfm[buff](self, data)
|
||||||
|
|
||||||
|
if ret != nil then
|
||||||
|
|
||||||
|
if ret == false then return end
|
||||||
|
|
||||||
|
data = ret
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, e in pairs(self:GetActiveElements()) do
|
||||||
|
local ele = self.AttachmentElements[e]
|
||||||
|
|
||||||
|
if ele then
|
||||||
|
if ele[buff] then
|
||||||
|
local ret = ele[buff](self, data)
|
||||||
|
|
||||||
|
if ret != nil then
|
||||||
|
|
||||||
|
if ret == false then return end
|
||||||
|
|
||||||
|
data = ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isfunction(self:GetTable()[buff]) then
|
||||||
|
local ret = self:GetTable()[buff](self, data)
|
||||||
|
|
||||||
|
if ret != nil then
|
||||||
|
|
||||||
|
if ret == false then return end
|
||||||
|
|
||||||
|
data = ret
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
hook.Call(buff, ArcCW, self, data)
|
||||||
|
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetBuff_Override(buff)
|
||||||
|
local level = 0
|
||||||
|
local current = nil
|
||||||
|
local winningslot = nil
|
||||||
|
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if !atttbl then continue end
|
||||||
|
|
||||||
|
if atttbl[buff] != nil then
|
||||||
|
if level == 0 or (atttbl[buff .. "_Priority"] and atttbl[buff .. "_Priority"] > level) then
|
||||||
|
current = atttbl[buff]
|
||||||
|
level = atttbl[buff .. "_Priority"] or 1
|
||||||
|
winningslot = i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !ArcCW.BuffStack then
|
||||||
|
|
||||||
|
ArcCW.BuffStack = true
|
||||||
|
|
||||||
|
local cfm = self:GetCurrentFiremode()
|
||||||
|
|
||||||
|
if cfm and cfm[buff] != nil then
|
||||||
|
if level == 0 or (cfm[buff .. "_Priority"] and cfm[buff .. "_Priority"] > level) then
|
||||||
|
current = cfm[buff]
|
||||||
|
level = cfm[buff .. "_Priority"] or 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.BuffStack = false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, e in pairs(self:GetActiveElements()) do
|
||||||
|
local ele = self.AttachmentElements[e]
|
||||||
|
|
||||||
|
if ele then
|
||||||
|
if ele[buff] != nil then
|
||||||
|
if level == 0 or (ele[buff .. "_Priority"] and ele[buff .. "_Priority"] > level) then
|
||||||
|
current = ele[buff]
|
||||||
|
level = ele[buff .. "_Priority"] or 1
|
||||||
|
winningslot = i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetTable()[buff] != nil then
|
||||||
|
if level == 0 or (self:GetTable()[buff .. "_Priority"] and self:GetTable()[buff .. "_Priority"] > level) then
|
||||||
|
current = self:GetTable()[buff]
|
||||||
|
level = self:GetTable()[buff .. "_Priority"] or 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
buff = buff,
|
||||||
|
current = current,
|
||||||
|
winningslot = winningslot
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ArcCW.BuffStack then
|
||||||
|
|
||||||
|
ArcCW.BuffStack = true
|
||||||
|
|
||||||
|
current = (self:GetBuff_Hook("O_Hook_" .. buff, data) or {}).current or current
|
||||||
|
|
||||||
|
ArcCW.BuffStack = false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return current, winningslot
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetBuff_Mult(buff)
|
||||||
|
local mult = 1
|
||||||
|
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if atttbl[buff] then
|
||||||
|
mult = mult * atttbl[buff]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local cfm = self:GetCurrentFiremode()
|
||||||
|
|
||||||
|
if cfm and cfm[buff] then
|
||||||
|
mult = mult * cfm[buff]
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetTable()[buff] then
|
||||||
|
mult = mult * self:GetTable()[buff]
|
||||||
|
end
|
||||||
|
|
||||||
|
if ArcCW.ConVar_BuffMults[buff] then
|
||||||
|
mult = mult * GetConVar(ArcCW.ConVar_BuffMults[buff]):GetFloat()
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, e in pairs(self:GetActiveElements()) do
|
||||||
|
local ele = self.AttachmentElements[e]
|
||||||
|
|
||||||
|
if ele then
|
||||||
|
if ele[buff] then
|
||||||
|
mult = mult * ele[buff]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
buff = buff,
|
||||||
|
mult = mult
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ArcCW.BuffStack then
|
||||||
|
|
||||||
|
ArcCW.BuffStack = true
|
||||||
|
|
||||||
|
mult = (self:GetBuff_Hook("M_Hook_" .. buff, data) or {}).mult or mult
|
||||||
|
|
||||||
|
ArcCW.BuffStack = false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return mult
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetBuff_Add(buff)
|
||||||
|
local add = 0
|
||||||
|
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if atttbl[buff] then
|
||||||
|
add = add + atttbl[buff]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local cfm = self:GetCurrentFiremode()
|
||||||
|
|
||||||
|
if cfm and cfm[buff] then
|
||||||
|
add = add + cfm[buff]
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, e in pairs(self:GetActiveElements()) do
|
||||||
|
local ele = self.AttachmentElements[e]
|
||||||
|
|
||||||
|
if ele then
|
||||||
|
if ele[buff] then
|
||||||
|
add = add + ele[buff]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
buff = buff,
|
||||||
|
add = add
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ArcCW.BuffStack then
|
||||||
|
|
||||||
|
ArcCW.BuffStack = true
|
||||||
|
|
||||||
|
add = (self:GetBuff_Hook("A_Hook_" .. buff, data) or {}).add or add
|
||||||
|
|
||||||
|
ArcCW.BuffStack = false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return add
|
||||||
|
end
|
||||||
|
|
||||||
|
SWEP.ActiveElementCache = nil
|
||||||
|
|
||||||
|
function SWEP:GetActiveElements(recache)
|
||||||
|
if self.ActiveElementCache and !recache then return self.ActiveElementCache end
|
||||||
|
|
||||||
|
local eles = {}
|
||||||
|
|
||||||
|
for _, i in pairs(self.Attachments) do
|
||||||
|
if !i.Installed then continue end
|
||||||
|
|
||||||
|
if i.InstalledEles then
|
||||||
|
table.Add(eles, i.InstalledEles)
|
||||||
|
end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[i.Installed]
|
||||||
|
|
||||||
|
if atttbl.ActivateElements then
|
||||||
|
table.Add(eles, atttbl.ActivateElements)
|
||||||
|
end
|
||||||
|
|
||||||
|
local slots = atttbl.Slot
|
||||||
|
|
||||||
|
if isstring(slots) then
|
||||||
|
slots = {slots}
|
||||||
|
end
|
||||||
|
|
||||||
|
table.Add(eles, slots or {})
|
||||||
|
|
||||||
|
table.insert(eles, i.Installed)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.Add(eles, self.DefaultElements)
|
||||||
|
|
||||||
|
local eles2 = {}
|
||||||
|
|
||||||
|
ArcCW.Overflow = true
|
||||||
|
|
||||||
|
for f, i in pairs(eles) do
|
||||||
|
local e = self.AttachmentElements[i]
|
||||||
|
|
||||||
|
if !e then continue end
|
||||||
|
|
||||||
|
if !self:CheckFlags(e.ExcludeFlags, e.RequireFlags) then continue end
|
||||||
|
|
||||||
|
local a = false
|
||||||
|
local c = 0
|
||||||
|
|
||||||
|
for g = f, table.Count(eles) do
|
||||||
|
if eles[g] == i then c = c + 1 end
|
||||||
|
|
||||||
|
if c > 1 then a = true break end
|
||||||
|
end
|
||||||
|
|
||||||
|
if a then continue end
|
||||||
|
|
||||||
|
table.insert(eles2, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.Overflow = false
|
||||||
|
|
||||||
|
self.ActiveElementCache = eles2
|
||||||
|
|
||||||
|
return eles2
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetMuzzleDevice(wm)
|
||||||
|
local model = self.WM
|
||||||
|
local muzz = self
|
||||||
|
|
||||||
|
if !wm then
|
||||||
|
model = self.VM
|
||||||
|
muzz = self:GetOwner():GetViewModel()
|
||||||
|
end
|
||||||
|
|
||||||
|
if model then
|
||||||
|
for _, ele in pairs(model) do
|
||||||
|
if ele.IsMuzzleDevice then
|
||||||
|
muzz = ele.Model or muzz
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetNWBool("ubgl") then
|
||||||
|
local _, slot = self:GetBuff_Override("UBGL")
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
muzz = (self.Attachments[slot].WMuzzleDeviceElement or {}).Model or muzz
|
||||||
|
else
|
||||||
|
muzz = (self.Attachments[slot].VMuzzleDeviceElement or {}).Model or muzz
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return muzz
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:CheckFlags(reject, need)
|
||||||
|
local flags = self:GetWeaponFlags()
|
||||||
|
|
||||||
|
reject = reject or {}
|
||||||
|
need = need or {}
|
||||||
|
|
||||||
|
for _, i in pairs(reject) do
|
||||||
|
if table.HasValue(flags, i) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, i in pairs(need) do
|
||||||
|
if !table.HasValue(flags, i) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetWeaponFlags()
|
||||||
|
local flags = {}
|
||||||
|
|
||||||
|
for _, i in pairs(self.Attachments) do
|
||||||
|
if !i.Installed then continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[i.Installed]
|
||||||
|
|
||||||
|
if atttbl.GivesFlags then
|
||||||
|
table.Add(flags, atttbl.GivesFlags)
|
||||||
|
end
|
||||||
|
|
||||||
|
if i.GivesFlags then
|
||||||
|
table.Add(flags, i.GivesFlags)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.Add(flags, i.Installed)
|
||||||
|
end
|
||||||
|
|
||||||
|
return flags
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:PlayerOwnsAtt(att)
|
||||||
|
local qty = ArcCW:PlayerGetAtts(self:GetOwner(), att)
|
||||||
|
|
||||||
|
return qty > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:NetworkWeapon(sendto)
|
||||||
|
net.Start("arccw_networkatts")
|
||||||
|
net.WriteEntity(self) -- self entity
|
||||||
|
|
||||||
|
net.WriteUInt(table.Count(self.Attachments), 8)
|
||||||
|
|
||||||
|
for _, i in pairs(self.Attachments) do
|
||||||
|
if !i.Installed then net.WriteUInt(0, ArcCW.GetBitNecessity()) continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[i.Installed]
|
||||||
|
local id = atttbl.ID
|
||||||
|
|
||||||
|
net.WriteUInt(id, ArcCW.GetBitNecessity())
|
||||||
|
|
||||||
|
if i.SlideAmount then
|
||||||
|
net.WriteFloat(i.SlidePos or 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if atttbl.ColorOptionsTable then
|
||||||
|
-- net.WriteUInt(i.ColorOptionIndex or 1, 8) -- look if you want more than 256 fucking color options you're insane and stupid and just don't ok
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
|
||||||
|
if sendto then
|
||||||
|
net.Send(sendto)
|
||||||
|
else
|
||||||
|
net.Broadcast()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SendDetail_ColorIndex(slot)
|
||||||
|
net.Start("arccw_colorindex")
|
||||||
|
net.WriteUInt(slot, 8)
|
||||||
|
net.WriteUInt(self.Attachments[slot].ColorOptionIndex)
|
||||||
|
net.SendToServer()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SendDetail_SlidePos(slot)
|
||||||
|
if !self.Attachments then return end
|
||||||
|
if !self.Attachments[slot].SlidePos then return end
|
||||||
|
|
||||||
|
net.Start("arccw_slidepos")
|
||||||
|
net.WriteUInt(slot, 8)
|
||||||
|
net.WriteFloat(self.Attachments[slot].SlidePos or 0.5)
|
||||||
|
net.SendToServer()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SendAllDetails()
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
self:SendDetail_SlidePos(i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:CountAttachments()
|
||||||
|
local total = 0
|
||||||
|
|
||||||
|
for _, i in pairs(self.Attachments) do
|
||||||
|
if i.Installed and !i.FreeSlot then
|
||||||
|
total = total + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return total
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:RefreshBGs()
|
||||||
|
local vm
|
||||||
|
|
||||||
|
local vmm = self:GetBuff_Override("Override_VMMaterial") or ""
|
||||||
|
local wmm = self:GetBuff_Override("Override_WMMaterial") or ""
|
||||||
|
|
||||||
|
local vmc = self:GetBuff_Override("Override_VMColor") or Color(255, 255, 255)
|
||||||
|
local wmc = self:GetBuff_Override("Override_WMColor") or Color(255, 255, 255)
|
||||||
|
|
||||||
|
local vms = self:GetBuff_Override("Override_VMSkin") or self.DefaultSkin
|
||||||
|
local wms = self:GetBuff_Override("Override_WMSkin") or self.DefaultWMSkin
|
||||||
|
|
||||||
|
if self:GetOwner():IsPlayer() then
|
||||||
|
vm = self:GetOwner():GetViewModel()
|
||||||
|
end
|
||||||
|
|
||||||
|
if vm and vm:IsValid() then
|
||||||
|
vm:SetBodyGroups(self.DefaultBodygroups)
|
||||||
|
vm:SetMaterial(vmm)
|
||||||
|
vm:SetColor(vmc)
|
||||||
|
vm:SetSkin(vms)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetMaterial(wmm)
|
||||||
|
self:SetColor(wmc)
|
||||||
|
self:SetSkin(wms)
|
||||||
|
|
||||||
|
if self.WMModel and self.WMModel:IsValid() then
|
||||||
|
self.WMModel:SetMaterial(wmm)
|
||||||
|
self.WMModel:SetColor(wmc)
|
||||||
|
self.WMModel:SetSkin(wms)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, e in pairs(self:GetActiveElements()) do
|
||||||
|
local ele = self.AttachmentElements[e]
|
||||||
|
|
||||||
|
if !ele then continue end
|
||||||
|
|
||||||
|
if ele.VMSkin and vm and IsValid(vm) then
|
||||||
|
vm:SetSkin(ele.VMSkin)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.WMModel and self.WMModel:IsValid() and ele.WMSkin then
|
||||||
|
self.WMModel:SetSkin(ele.WMSkin)
|
||||||
|
self:SetSkin(ele.WMSkin)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ele.VMColor and vm and IsValid(vm) then
|
||||||
|
vm:SetColor(ele.VMColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.WMModel and self.WMModel:IsValid() and ele.WMColor then
|
||||||
|
self.WMModel:SetColor(ele.WMColor)
|
||||||
|
self:SetColor(ele.WMColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ele.VMMaterial and vm and IsValid(vm) then
|
||||||
|
vm:SetMaterial(ele.VMMaterial)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.WMModel and self.WMModel:IsValid() and ele.WMMaterial then
|
||||||
|
self.WMModel:SetMaterial(ele.WMMaterial)
|
||||||
|
self:SetMaterial(ele.WMMaterial)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ele.VMBodygroups then
|
||||||
|
for _, i in pairs(ele.VMBodygroups) do
|
||||||
|
if !i.ind or !i.bg then continue end
|
||||||
|
|
||||||
|
if vm and IsValid(vm) and vm:GetBodygroup(i.ind) != i.bg then
|
||||||
|
vm:SetBodygroup(i.ind, i.bg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ele.WMBodygroups then
|
||||||
|
for _, i in pairs(ele.WMBodygroups) do
|
||||||
|
if !i.ind or !i.bg then continue end
|
||||||
|
|
||||||
|
if self.WMModel and IsValid(self.WMModel) and self.WMModel:GetBodygroup(i.ind) != i.bg then
|
||||||
|
self.WMModel:SetBodygroup(i.ind, i.bg)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetBodygroup(i.ind) != i.bg then
|
||||||
|
self:SetBodygroup(i.ind, i.bg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ele.VMBoneMods then
|
||||||
|
for bone, i in pairs(ele.VMBoneMods) do
|
||||||
|
local boneind = vm:LookupBone(bone)
|
||||||
|
|
||||||
|
if !boneind then continue end
|
||||||
|
|
||||||
|
vm:ManipulateBonePosition(boneind, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ele.WMBoneMods then
|
||||||
|
for bone, i in pairs(ele.WMBoneMods) do
|
||||||
|
if !(self.WMModel and self.WMModel:IsValid()) then break end
|
||||||
|
local boneind = self:LookupBone(bone)
|
||||||
|
|
||||||
|
if !boneind then continue end
|
||||||
|
|
||||||
|
self:ManipulateBonePosition(boneind, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:SetupShields()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:Attach(slot, attname, silent)
|
||||||
|
silent = silent or false
|
||||||
|
local attslot = self.Attachments[slot]
|
||||||
|
if !attslot then return end
|
||||||
|
if attslot.Installed == attname then return end
|
||||||
|
|
||||||
|
if !ArcCW.EnableCustomization or !GetConVar("arccw_enable_customization"):GetBool() then
|
||||||
|
if CLIENT and !silent then
|
||||||
|
surface.PlaySound("items/medshotno1.wav")
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local pick = GetConVar("arccw_atts_pickx"):GetInt()
|
||||||
|
|
||||||
|
if pick > 0 then
|
||||||
|
if self:CountAttachments() >= pick and !attslot.FreeSlot then
|
||||||
|
if CLIENT and !silent then
|
||||||
|
surface.PlaySound("items/medshotno1.wav")
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !self:CheckFlags(attslot.ExcludeFlags, attslot.RequireFlags) then return end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[attname]
|
||||||
|
|
||||||
|
if !ArcCW:SlotAcceptsAtt(attslot.Slot, self, attname) then return end
|
||||||
|
if !self:CheckFlags(atttbl.ExcludeFlags, atttbl.RequireFlags) then return end
|
||||||
|
if !self:PlayerOwnsAtt(attname) then return end
|
||||||
|
|
||||||
|
if attslot.SlideAmount then
|
||||||
|
attslot.SlidePos = 0.5
|
||||||
|
end
|
||||||
|
|
||||||
|
if atttbl.MountPositionOverride then
|
||||||
|
attslot.SlidePos = atttbl.MountPositionOverride
|
||||||
|
end
|
||||||
|
|
||||||
|
if atttbl.AdditionalSights then
|
||||||
|
self.SightMagnifications = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
-- we are asking to attach something
|
||||||
|
|
||||||
|
self:SendAllDetails()
|
||||||
|
|
||||||
|
net.Start("arccw_asktoattach")
|
||||||
|
net.WriteUInt(slot, 8)
|
||||||
|
net.WriteUInt(atttbl.ID, 24)
|
||||||
|
net.SendToServer()
|
||||||
|
|
||||||
|
if !silent then
|
||||||
|
surface.PlaySound("weapons/arccw/install.wav")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:DetachAllMergeSlots(slot)
|
||||||
|
end
|
||||||
|
|
||||||
|
attslot.Installed = attname
|
||||||
|
|
||||||
|
if atttbl.Breakable then
|
||||||
|
attslot.HP = self:GetAttachmentMaxHP(slot)
|
||||||
|
end
|
||||||
|
|
||||||
|
if atttbl.ColorOptionsTable then
|
||||||
|
attslot.ColorOptionIndex = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW:PlayerTakeAtt(self:GetOwner(), attname)
|
||||||
|
|
||||||
|
local fmt = self:GetBuff_Override("Override_Firemodes") or self.Firemodes
|
||||||
|
local fmi = self:GetNWInt("firemode", 1)
|
||||||
|
|
||||||
|
if fmi > table.Count(fmt) then
|
||||||
|
self:SetNWInt("firemode", 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.UnReady = false
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:NetworkWeapon()
|
||||||
|
self:SetupModel(false)
|
||||||
|
self:SetupModel(true)
|
||||||
|
ArcCW:PlayerSendAttInv(self:GetOwner())
|
||||||
|
else
|
||||||
|
self:SetupActiveSights()
|
||||||
|
|
||||||
|
self.LHIKAnimation = 0
|
||||||
|
self.LHIKAnimationStart = 0
|
||||||
|
self.LHIKAnimationTime = 0
|
||||||
|
|
||||||
|
self.LHIKDelta = {}
|
||||||
|
self.LHIKDeltaAng = {}
|
||||||
|
|
||||||
|
self.ViewModel_Hit = Vector(0, 0, 0)
|
||||||
|
|
||||||
|
if !silent then
|
||||||
|
self:SavePreset("autosave")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:AdjustAtts()
|
||||||
|
|
||||||
|
for s, i in pairs(self.Attachments) do
|
||||||
|
if !self:CheckFlags(i.ExcludeFlags, i.RequireFlags) then
|
||||||
|
self:Detach(s, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:RefreshBGs()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DetachAllMergeSlots(slot, silent)
|
||||||
|
local slots = {slot}
|
||||||
|
|
||||||
|
table.Add(slots, self.Attachments[slot].MergeSlots or {})
|
||||||
|
|
||||||
|
for _, i in pairs(slots) do
|
||||||
|
self:Detach(i, silent)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:Detach(slot, silent)
|
||||||
|
if !slot then return end
|
||||||
|
if !self.Attachments[slot] then return end
|
||||||
|
|
||||||
|
if !ArcCW.EnableCustomization or !GetConVar("arccw_enable_customization"):GetBool() then
|
||||||
|
if CLIENT then
|
||||||
|
surface.PlaySound("items/medshotno1.wav")
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if !self.Attachments[slot].Installed then return end
|
||||||
|
|
||||||
|
local previnstall = self.Attachments[slot].Installed
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[previnstall]
|
||||||
|
|
||||||
|
if atttbl.UBGL then
|
||||||
|
local clip = self:Clip2()
|
||||||
|
|
||||||
|
local ammo = atttbl.UBGL_Ammo or "smg1_grenade"
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:GetOwner():GiveAmmo(clip, ammo, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetClip2(0)
|
||||||
|
|
||||||
|
self:DeselectUBGL()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Attachments[slot].Installed = nil
|
||||||
|
|
||||||
|
if self:GetAttachmentHP(slot) >= self:GetAttachmentMaxHP(slot) then
|
||||||
|
ArcCW:PlayerGiveAtt(self:GetOwner(), previnstall)
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
self:SendAllDetails()
|
||||||
|
|
||||||
|
-- we are asking to detach something
|
||||||
|
net.Start("arccw_asktodetach")
|
||||||
|
net.WriteUInt(slot, 8)
|
||||||
|
net.SendToServer()
|
||||||
|
|
||||||
|
if !silent then
|
||||||
|
surface.PlaySound("weapons/arccw/uninstall.wav")
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetupActiveSights()
|
||||||
|
|
||||||
|
self.LHIKAnimation = 0
|
||||||
|
self.LHIKAnimationStart = 0
|
||||||
|
self.LHIKAnimationTime = 0
|
||||||
|
|
||||||
|
if !silent then
|
||||||
|
self:SavePreset("autosave")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:NetworkWeapon()
|
||||||
|
self:SetupModel(false)
|
||||||
|
self:SetupModel(true)
|
||||||
|
ArcCW:PlayerSendAttInv(self:GetOwner())
|
||||||
|
end
|
||||||
|
|
||||||
|
self:RefreshBGs()
|
||||||
|
|
||||||
|
self:AdjustAtts()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:AdjustAtts()
|
||||||
|
if SERVER then
|
||||||
|
local cs = self:GetBuff_Override("Override_ChamberSize") or self.ChamberSize
|
||||||
|
|
||||||
|
if self:Clip1() > self:GetCapacity() + cs then
|
||||||
|
local diff = self:Clip1() - (self:GetCapacity() + cs)
|
||||||
|
self:GetOwner():GiveAmmo(diff, self.Primary.Ammo, true)
|
||||||
|
self:SetClip1(self:GetCapacity() + cs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetBuff_Override("UBGL_Capacity") then
|
||||||
|
self.Secondary.ClipSize = self:GetBuff_Override("UBGL_Capacity")
|
||||||
|
else
|
||||||
|
self.Secondary.ClipSize = -1
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetBuff_Override("UBGL_Ammo") then
|
||||||
|
self.Secondary.Ammo = self:GetBuff_Override("UBGL_Ammo")
|
||||||
|
else
|
||||||
|
self.Secondary.Ammo = "none"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetAttachmentMaxHP(slot)
|
||||||
|
if !self.Attachments[slot] then return 100 end
|
||||||
|
if !self.Attachments[slot].Installed then return 100 end
|
||||||
|
local maxhp = 100
|
||||||
|
local atttbl = ArcCW.AttachmentTable[self.Attachments[slot].Installed]
|
||||||
|
|
||||||
|
if atttbl.Health then
|
||||||
|
maxhp = atttbl.Health
|
||||||
|
end
|
||||||
|
|
||||||
|
return maxhp
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetAttachmentHP(slot)
|
||||||
|
if !self.Attachments[slot] then return 100 end
|
||||||
|
if !self.Attachments[slot].Installed then return 100 end
|
||||||
|
|
||||||
|
if self.Attachments[slot].HP then return self.Attachments[slot].HP end
|
||||||
|
|
||||||
|
self.Attachments[slot].HP = self:GetAttachmentMaxHP(slot)
|
||||||
|
|
||||||
|
return self.Attachments[slot].HP
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DamageAttachment(slot, dmg)
|
||||||
|
if !self.Attachments[slot] then return end
|
||||||
|
if !self.Attachments[slot].Installed then return end
|
||||||
|
|
||||||
|
self.Attachments[slot].HP = self:GetAttachmentHP(slot) - dmg
|
||||||
|
|
||||||
|
if self:GetAttachmentHP(slot) <= 0 then
|
||||||
|
self:Detach(slot, true)
|
||||||
|
end
|
||||||
|
end
|
155
lua/weapons/arccw_base/sh_bash.lua
Normal file
155
lua/weapons/arccw_base/sh_bash.lua
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
function SWEP:Bash(melee2)
|
||||||
|
melee2 = melee2 or false
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS then return end
|
||||||
|
if self:GetNextPrimaryFire() > CurTime() then return end
|
||||||
|
|
||||||
|
self.Primary.Automatic = true
|
||||||
|
|
||||||
|
local mult = self:GetBuff_Mult("Mult_MeleeTime")
|
||||||
|
local mt = self.MeleeTime * mult
|
||||||
|
|
||||||
|
if melee2 then
|
||||||
|
mt = self.Melee2Time * mult
|
||||||
|
end
|
||||||
|
|
||||||
|
if melee2 then
|
||||||
|
if self.Animations.bash2_empty and self:Clip1() == 0 then
|
||||||
|
self:PlayAnimation("bash2_empty", mult, true, 0, true)
|
||||||
|
else
|
||||||
|
self:PlayAnimation("bash2", mult, true, 0, true)
|
||||||
|
end
|
||||||
|
elseif self.Animations.bash then
|
||||||
|
if self.Animations.bash_empty and self:Clip1() == 0 then
|
||||||
|
self:PlayAnimation("bash_empty", mult, true, 0, true)
|
||||||
|
else
|
||||||
|
self:PlayAnimation("bash", mult, true, 0, true)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:ProceduralBash()
|
||||||
|
|
||||||
|
self:EmitSound(self.MeleeSwingSound, 75, 100, 1, CHAN_USER_BASE + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:GetOwner():ViewPunch(-self.BashPrepareAng * 0.05)
|
||||||
|
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_MELEE)
|
||||||
|
else
|
||||||
|
self:GetOwner():DoAnimationEvent(self.Melee2Gesture or ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE2)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if self.HoldtypeActive == "pistol" or self.HoldtypeActive == "revolver" then
|
||||||
|
self:GetOwner():DoAnimationEvent(self.MeleeGesture or ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE)
|
||||||
|
else
|
||||||
|
self:GetOwner():DoAnimationEvent(self.MeleeGesture or ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mat = self.MeleeAttackTime
|
||||||
|
|
||||||
|
if melee2 then
|
||||||
|
mat = self.Melee2AttackTime
|
||||||
|
end
|
||||||
|
|
||||||
|
mat = mat * self:GetBuff_Mult("Mult_MeleeAttackTime")
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
self:GetOwner():ViewPunch(-self.BashAng * 0.05)
|
||||||
|
|
||||||
|
self:MeleeAttack(melee2)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:MeleeAttack(melee2)
|
||||||
|
local reach = 32 + self:GetBuff_Add("Add_MeleeRange") + self.MeleeRange
|
||||||
|
local dmg = self:GetBuff_Override("Override_MeleeDamage") or self.MeleeDamage or 20
|
||||||
|
|
||||||
|
if melee2 then
|
||||||
|
reach = 32 + self:GetBuff_Add("Add_MeleeRange") + self.Melee2Range
|
||||||
|
dmg = self:GetBuff_Override("Override_MeleeDamage") or self.Melee2Damage or 20
|
||||||
|
end
|
||||||
|
|
||||||
|
dmg = dmg * self:GetBuff_Mult("Mult_MeleeDamage")
|
||||||
|
|
||||||
|
self:GetOwner():LagCompensation(true)
|
||||||
|
|
||||||
|
local tr = util.TraceLine({
|
||||||
|
start = self:GetOwner():GetShootPos(),
|
||||||
|
endpos = self:GetOwner():GetShootPos() + self:GetOwner():GetAimVector() * reach,
|
||||||
|
filter = self:GetOwner(),
|
||||||
|
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 = self:GetOwner(),
|
||||||
|
mins = Vector(-16, -16, -8),
|
||||||
|
maxs = Vector(16, 16, 8),
|
||||||
|
mask = MASK_SHOT_HULL
|
||||||
|
})
|
||||||
|
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:IsPlayer() then
|
||||||
|
self:EmitSound(self.MeleeHitNPCSound, 75, 100, 1, CHAN_USER_BASE + 2)
|
||||||
|
else
|
||||||
|
self:EmitSound(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:EmitSound(self.MeleeMissSound or "weapons/iceaxe/iceaxe_swing1.wav", 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.MeleeDamageType or DMG_CLUB)
|
||||||
|
|
||||||
|
dmginfo:SetDamageForce(self:GetOwner():GetRight() * -4912 + self:GetOwner():GetForward() * 9989)
|
||||||
|
|
||||||
|
SuppressHostEvents(NULL)
|
||||||
|
tr.Entity:TakeDamageInfo(dmginfo)
|
||||||
|
SuppressHostEvents(self:GetOwner())
|
||||||
|
|
||||||
|
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
|
114
lua/weapons/arccw_base/sh_bipod.lua
Normal file
114
lua/weapons/arccw_base/sh_bipod.lua
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
function SWEP:InBipod()
|
||||||
|
local bip = self:GetNWBool("bipod", false)
|
||||||
|
|
||||||
|
if !self:CanBipod() then
|
||||||
|
self:ExitBipod()
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.BipodPos != self:GetOwner():EyePos() then
|
||||||
|
self:ExitBipod()
|
||||||
|
end
|
||||||
|
|
||||||
|
return bip
|
||||||
|
end
|
||||||
|
|
||||||
|
SWEP.BipodAngle = Angle(0, 0, 0)
|
||||||
|
SWEP.CachedCanBipod = true
|
||||||
|
SWEP.CachedCanBipodTime = 0
|
||||||
|
|
||||||
|
function SWEP:CanBipod()
|
||||||
|
if !(self:GetBuff_Override("Bipod") or self.Bipod_Integral) then return false end
|
||||||
|
|
||||||
|
if self.CachedCanBipodTime >= CurTime() then return self.CachedCanBipod end
|
||||||
|
|
||||||
|
local maxs = Vector(2, 2, 2)
|
||||||
|
local mins = Vector(-2, -2, -2)
|
||||||
|
|
||||||
|
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 = 2.5
|
||||||
|
end
|
||||||
|
|
||||||
|
local tr = util.TraceLine({
|
||||||
|
start = pos,
|
||||||
|
endpos = pos + (angle:Forward() * 48 * rangemult),
|
||||||
|
filter = self:GetOwner(),
|
||||||
|
mask = MASK_SOLID
|
||||||
|
})
|
||||||
|
|
||||||
|
if tr.Hit then -- check for stuff in front of us
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
maxs = Vector(8, 8, 0)
|
||||||
|
mins = Vector(-8, -8, -16)
|
||||||
|
|
||||||
|
angle.p = angle.p + 15
|
||||||
|
|
||||||
|
tr = util.TraceHull({
|
||||||
|
start = pos,
|
||||||
|
endpos = pos + (angle:Forward() * 24 * rangemult),
|
||||||
|
filter = self:GetOwner(),
|
||||||
|
maxs = maxs,
|
||||||
|
mins = mins,
|
||||||
|
mask = MASK_SOLID
|
||||||
|
})
|
||||||
|
|
||||||
|
self.CachedCanBipodTime = CurTime()
|
||||||
|
|
||||||
|
if tr.Hit then
|
||||||
|
self.CachedCanBipod = true
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
self.CachedCanBipod = false
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:EnterBipod()
|
||||||
|
if self:GetNWBool("bipod", false) then return end
|
||||||
|
if !self:CanBipod() then return end
|
||||||
|
if CurTime() < self:GetNextSecondaryFire() then return end
|
||||||
|
|
||||||
|
if self.Bipod_Integral then
|
||||||
|
if self.Animations.enter_bipod then
|
||||||
|
self:PlayAnimation("enter_bipod")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:EmitSound(self.EnterBipodSound)
|
||||||
|
self:DoLHIKAnimation("enter", 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.BipodPos = self:GetOwner():EyePos()
|
||||||
|
self.BipodAngle = self:GetOwner():EyeAngles()
|
||||||
|
|
||||||
|
self:SetNextSecondaryFire(CurTime() + 0.075)
|
||||||
|
|
||||||
|
self:SetNWBool("bipod", true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ExitBipod()
|
||||||
|
if !self:GetNWBool("bipod", false) then return end
|
||||||
|
if CurTime() < self:GetNextSecondaryFire() then return end
|
||||||
|
|
||||||
|
if self.Bipod_Integral then
|
||||||
|
if self.Animations.exit_bipod then
|
||||||
|
self:PlayAnimation("exit_bipod")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:EmitSound(self.ExitBipodSound)
|
||||||
|
self:DoLHIKAnimation("exit", 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetNextSecondaryFire(CurTime() + 0.075)
|
||||||
|
|
||||||
|
self:SetNWBool("bipod", false)
|
||||||
|
end
|
1199
lua/weapons/arccw_base/sh_customize.lua
Normal file
1199
lua/weapons/arccw_base/sh_customize.lua
Normal file
File diff suppressed because it is too large
Load Diff
256
lua/weapons/arccw_base/sh_deploy.lua
Normal file
256
lua/weapons/arccw_base/sh_deploy.lua
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
function SWEP:Deploy()
|
||||||
|
if !IsValid(self:GetOwner()) or self:GetOwner():IsNPC() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self:InitTimers()
|
||||||
|
|
||||||
|
self.FullyHolstered = false
|
||||||
|
|
||||||
|
self:SetShouldHoldType()
|
||||||
|
|
||||||
|
self:SetNWBool("reloading", false)
|
||||||
|
self:SetNWBool("incustomize", false)
|
||||||
|
self:SetState(0)
|
||||||
|
self:SetNWBool("ubgl", false)
|
||||||
|
|
||||||
|
self.LHIKAnimation = nil
|
||||||
|
|
||||||
|
self.BurstCount = 0
|
||||||
|
|
||||||
|
if self.CheckpointAnimation then
|
||||||
|
self:PlayAnimation(self.CheckpointAnimation, self:GetBuff_Mult("Mult_ReloadTime"), true, self.CheckpointTime, true)
|
||||||
|
self:ProceduralDraw()
|
||||||
|
self:SetNWBool("reloading", true)
|
||||||
|
|
||||||
|
self:SetTimer((self:GetAnimTime(self.CheckpointAnimation) * self:GetBuff_Mult("Mult_ReloadTime")) - self.CheckpointTime,
|
||||||
|
function()
|
||||||
|
self:SetNWBool("reloading", false)
|
||||||
|
self.CheckpointAnimation = nil
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
local prd = false
|
||||||
|
|
||||||
|
if self.Animations.ready and self.UnReady then
|
||||||
|
self:PlayAnimation("ready", 1, true, 0, true)
|
||||||
|
self.UnReady = false
|
||||||
|
|
||||||
|
self:SetNWBool("reloading", true)
|
||||||
|
|
||||||
|
self:SetTimer(self:GetAnimTime("ready"),
|
||||||
|
function()
|
||||||
|
self:SetNWBool("reloading", false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
prd = self.Animations.ready.ProcDraw
|
||||||
|
|
||||||
|
self:SetNWBool("reloading", true)
|
||||||
|
else
|
||||||
|
if self.Animations.draw_empty and self:Clip1() == 0 then
|
||||||
|
self:PlayAnimation("draw_empty", self:GetBuff_Mult("Mult_DrawTime"), true, 0, true)
|
||||||
|
|
||||||
|
self:SetNWBool("reloading", true)
|
||||||
|
|
||||||
|
self:SetTimer(self:GetAnimTime("draw_empty") * self:GetBuff_Mult("Mult_DrawTime"),
|
||||||
|
function()
|
||||||
|
self:SetNWBool("reloading", false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
prd = self.Animations.draw_empty.ProcDraw
|
||||||
|
else
|
||||||
|
self:PlayAnimation("draw", self:GetBuff_Mult("Mult_DrawTime"), true, 0, true)
|
||||||
|
|
||||||
|
self:SetNWBool("reloading", true)
|
||||||
|
|
||||||
|
self:SetTimer(self:GetAnimTime("draw") * self:GetBuff_Mult("Mult_DrawTime"),
|
||||||
|
function()
|
||||||
|
self:SetNWBool("reloading", false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
prd = self.Animations.draw.ProcDraw
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if prd then
|
||||||
|
self:ProceduralDraw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.LHIKAnimation = nil
|
||||||
|
|
||||||
|
self:SetupModel(false)
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:SetupShields()
|
||||||
|
self:NetworkWeapon()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:Initialize()
|
||||||
|
if (!IsValid(self:GetOwner()) or self:GetOwner():IsNPC()) and self:IsValid() and self.NPC_Initialize and SERVER then
|
||||||
|
self:NPC_Initialize()
|
||||||
|
end
|
||||||
|
|
||||||
|
if game.SinglePlayer() and self:GetOwner():IsValid() and SERVER 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")
|
||||||
|
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
|
||||||
|
|
||||||
|
self:SetState(0)
|
||||||
|
self:SetClip2(0)
|
||||||
|
|
||||||
|
self.Attachments["BaseClass"] = nil
|
||||||
|
|
||||||
|
self.Primary.DefaultClip = self.Primary.ClipSize * 3
|
||||||
|
|
||||||
|
if self.Primary.ClipSize >= 100 then
|
||||||
|
self.Primary.DefaultClip = self.Primary.ClipSize * 2
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetHoldType(self.HoldtypeActive)
|
||||||
|
|
||||||
|
local og = weapons.Get(self:GetClass())
|
||||||
|
|
||||||
|
self.RegularClipSize = og.Primary.ClipSize
|
||||||
|
|
||||||
|
self.OldPrintName = self.PrintName
|
||||||
|
|
||||||
|
self:InitTimers()
|
||||||
|
end
|
||||||
|
|
||||||
|
SWEP.FullyHolstered = false
|
||||||
|
SWEP.HolsterSwitchTo = nil
|
||||||
|
|
||||||
|
function SWEP:Holster(wep)
|
||||||
|
if self:GetOwner():IsNPC() then return end
|
||||||
|
if self.BurstCount > 0 and self:Clip1() > 0 then return false end
|
||||||
|
|
||||||
|
-- if game.SinglePlayer() and self:GetOwner():IsValid() and SERVER then
|
||||||
|
-- self:CallOnClient("Holster")
|
||||||
|
-- end
|
||||||
|
|
||||||
|
if self:GetNWBool("grenadeprimed") then
|
||||||
|
self:Throw()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Sighted = false
|
||||||
|
self.Sprinted = false
|
||||||
|
|
||||||
|
self.HolsterSwitchTo = wep
|
||||||
|
|
||||||
|
local time = 0.25
|
||||||
|
if self.Animations.holster then
|
||||||
|
self:PlayAnimation("holster", self:GetBuff_Mult("Mult_HolsterTime"))
|
||||||
|
time = self.Animations.holster.Time
|
||||||
|
else
|
||||||
|
if CLIENT then
|
||||||
|
self:ProceduralHolster()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
time = time * self:GetBuff_Mult("Mult_HolsterTime")
|
||||||
|
|
||||||
|
-- if !self.FullyHolstered then
|
||||||
|
-- self:SetTimer(time, function()
|
||||||
|
self.ReqEnd = true
|
||||||
|
self:KillTimers()
|
||||||
|
|
||||||
|
-- self.FullyHolstered = true
|
||||||
|
|
||||||
|
-- self:Holster(self.HolsterSwitchTo)
|
||||||
|
|
||||||
|
-- if CLIENT then
|
||||||
|
-- input.SelectWeapon(self.HolsterSwitchTo)
|
||||||
|
-- else
|
||||||
|
if SERVER then
|
||||||
|
if self:GetBuff_Override("UBGL_UnloadOnDequip") then
|
||||||
|
local clip = self:Clip2()
|
||||||
|
|
||||||
|
local ammo = self:GetBuff_Override("UBGL_Ammo") or "smg1_grenade"
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:GetOwner():GiveAmmo(clip, ammo, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetClip2(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:KillShields()
|
||||||
|
|
||||||
|
-- self:GetOwner():SelectWeapon(self.HolsterSwitchTo:GetClass())
|
||||||
|
|
||||||
|
local vm = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
for i = 0, vm:GetNumBodyGroups() do
|
||||||
|
vm:SetBodygroup(i, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
vm:SetSkin(0)
|
||||||
|
end
|
||||||
|
-- end
|
||||||
|
-- end)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
-- return self.FullyHolstered
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ProceduralDraw()
|
||||||
|
if game.SinglePlayer() and self:GetOwner():IsValid() then
|
||||||
|
self:CallOnClient("ProceduralDraw")
|
||||||
|
end
|
||||||
|
|
||||||
|
self.InProcDraw = true
|
||||||
|
self.ProcDrawTime = CurTime()
|
||||||
|
self:SetTimer(0.25, function()
|
||||||
|
self.InProcDraw = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ProceduralHolster()
|
||||||
|
self.InProcHolster = true
|
||||||
|
self.ProcHolsterTime = CurTime()
|
||||||
|
self:SetTimer(0.25 * self:GetBuff_Mult("Mult_HolsterTime"), function()
|
||||||
|
self.InProcHolster = false
|
||||||
|
end)
|
||||||
|
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
|
97
lua/weapons/arccw_base/sh_firemodes.lua
Normal file
97
lua/weapons/arccw_base/sh_firemodes.lua
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
function SWEP:ChangeFiremode(pred)
|
||||||
|
pred = pred or true
|
||||||
|
local fmt = self:GetBuff_Override("Override_Firemodes") or self.Firemodes
|
||||||
|
|
||||||
|
fmt["BaseClass"] = nil
|
||||||
|
|
||||||
|
if table.Count(fmt) == 1 then return end
|
||||||
|
|
||||||
|
local fmi = self:GetNWInt("firemode", 1)
|
||||||
|
local lastfmi = fmi
|
||||||
|
|
||||||
|
fmi = fmi + 1
|
||||||
|
|
||||||
|
if fmi > table.Count(fmt) then
|
||||||
|
fmi = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if !fmt[fmi] then fmi = 1 end
|
||||||
|
|
||||||
|
self:SetNWInt("firemode", fmi)
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
if pred then
|
||||||
|
SuppressHostEvents(self:GetOwner())
|
||||||
|
end
|
||||||
|
self:EmitSound(self.FiremodeSound, 75, 100, 1, CHAN_ITEM + 2)
|
||||||
|
if pred then
|
||||||
|
SuppressHostEvents(NULL)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:EmitSound(self.FiremodeSound, 75, 100, 1, CHAN_ITEM + 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local a = tostring(lastfmi) .. "_to_" .. tostring(fmi)
|
||||||
|
|
||||||
|
self:SetShouldHoldType()
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
if !ArcCW:ShouldDrawHUDElement("CHudAmmo") then
|
||||||
|
self:GetOwner():ChatPrint(self:GetFiremodeName() .. "|" .. self:GetFiremodeBars())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Animations[a] then
|
||||||
|
self:PlayAnimation(a)
|
||||||
|
elseif self.Animations.changefiremode then
|
||||||
|
self:PlayAnimation("changefiremode")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetCurrentFiremode()
|
||||||
|
local fmt = self:GetBuff_Override("Override_Firemodes") or self.Firemodes
|
||||||
|
|
||||||
|
if self:GetNWInt("firemode", 1) > table.Count(fmt) then
|
||||||
|
self:SetNWInt("firemode", 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
return fmt[self:GetNWInt("firemode", 1)]
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetFiremodeName()
|
||||||
|
if self:GetNWBool("ubgl", false) then
|
||||||
|
return self:GetBuff_Override("UBGL_PrintName") or "UBGL"
|
||||||
|
end
|
||||||
|
|
||||||
|
local fm = self:GetCurrentFiremode()
|
||||||
|
|
||||||
|
if fm.PrintName then return fm.PrintName end
|
||||||
|
|
||||||
|
local mode = fm.Mode
|
||||||
|
|
||||||
|
if mode == 0 then return "SAFE" end
|
||||||
|
if mode == 1 then return "SEMI" end
|
||||||
|
if mode >= 2 then return "AUTO" end
|
||||||
|
if mode < 0 then return tostring(-mode) .. "BST" end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetFiremodeBars()
|
||||||
|
if self:GetNWBool("ubgl", false) 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
|
688
lua/weapons/arccw_base/sh_firing.lua
Normal file
688
lua/weapons/arccw_base/sh_firing.lua
Normal file
@ -0,0 +1,688 @@
|
|||||||
|
function SWEP:PrimaryAttack()
|
||||||
|
if self:GetOwner():IsNPC() then
|
||||||
|
self:NPC_Shoot()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetNextPrimaryFire() >= CurTime() then return end
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_CUSTOMIZE then return end
|
||||||
|
|
||||||
|
if self:GetState() != ArcCW.STATE_SIGHTS and self:GetOwner():KeyDown(IN_USE) or self.PrimaryBash then
|
||||||
|
self:Bash()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Throwing then
|
||||||
|
self:PreThrow()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:BarrelHitWall() > 0 then return end
|
||||||
|
if self:GetState() == ArcCW.STATE_SPRINT and !(self:GetBuff_Override("Override_ShootWhileSprint") or self.ShootWhileSprint) then return end
|
||||||
|
|
||||||
|
if self:GetNWBool("ubgl") then
|
||||||
|
self:ShootUBGL()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:Clip1() <= 0 then self.BurstCount = 0 self:DryFire() return end
|
||||||
|
if self:GetNWBool("cycle", false) then return end
|
||||||
|
if self.BurstCount >= self:GetBurstLength() then return end
|
||||||
|
if self:GetCurrentFiremode().Mode == 0 then
|
||||||
|
self:ChangeFiremode(false)
|
||||||
|
self.Primary.Automatic = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetBuff_Hook("Hook_ShouldNotFire") then return end
|
||||||
|
|
||||||
|
math.randomseed(self:GetOwner():GetCurrentCommand():CommandNumber() + (self:EntIndex() % 30241))
|
||||||
|
|
||||||
|
self.Primary.Automatic = self:ShouldBeAutomatic()
|
||||||
|
|
||||||
|
local ss = self.ShootSound
|
||||||
|
|
||||||
|
if self:GetBuff_Override("Silencer") then
|
||||||
|
ss = self.ShootSoundSilenced
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.BurstCount == 0 and self.FirstShootSound then
|
||||||
|
ss = self.FirstShootSound
|
||||||
|
|
||||||
|
if self:GetBuff_Override("Silencer") then
|
||||||
|
if self.FirstShootSoundSilenced then
|
||||||
|
ss = self.FirstShootSoundSilenced
|
||||||
|
else
|
||||||
|
ss = self.ShootSoundSilenced
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:Clip1() == 1 and self.LastShootSound then
|
||||||
|
ss = self.LastShootSound
|
||||||
|
|
||||||
|
if self:GetBuff_Override("Silencer") then
|
||||||
|
if self.LastShootSoundSilenced then
|
||||||
|
ss = self.LastShootSoundSilenced
|
||||||
|
else
|
||||||
|
ss = self.ShootSoundSilenced
|
||||||
|
end
|
||||||
|
end
|
||||||
|
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 dir = self:GetOwner():EyeAngles()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
local spread = ArcCW.MOAToAcc * self.AccuracyMOA * self:GetBuff_Mult("Mult_AccuracyMOA")
|
||||||
|
|
||||||
|
dir = dir + (AngleRand() * self:GetDispersion() / 360 / 60)
|
||||||
|
|
||||||
|
local delay = (self.Delay * (1 / self:GetBuff_Mult("Mult_RPM")))
|
||||||
|
|
||||||
|
delay = self:GetBuff_Hook("Hook_ModifyRPM", delay) or delay
|
||||||
|
|
||||||
|
self:SetNextPrimaryFire(CurTime() + delay)
|
||||||
|
|
||||||
|
-- if IsFirstTimePredicted() then
|
||||||
|
|
||||||
|
local num = self:GetBuff_Override("Override_Num")
|
||||||
|
|
||||||
|
if !num then
|
||||||
|
num = self.Num
|
||||||
|
end
|
||||||
|
|
||||||
|
num = num + self:GetBuff_Add("Add_Num")
|
||||||
|
|
||||||
|
local btabl = {
|
||||||
|
Attacker = self:GetOwner(),
|
||||||
|
Damage = 0,
|
||||||
|
Force = 5 / num,
|
||||||
|
Distance = 33000,
|
||||||
|
Num = num,
|
||||||
|
Tracer = self:GetBuff_Override("Override_TracerNum") or self.TracerNum,
|
||||||
|
TracerName = self:GetBuff_Override("Override_Tracer") or self.Tracer,
|
||||||
|
AmmoType = self.Primary.Ammo,
|
||||||
|
Dir = dir:Forward(),
|
||||||
|
Src = src,
|
||||||
|
Spread = Vector(spread, spread, spread),
|
||||||
|
Callback = function(att, tr, dmg)
|
||||||
|
local dist = (tr.HitPos - src):Length() * ArcCW.HUToM
|
||||||
|
|
||||||
|
local pen = self.Penetration * self:GetBuff_Mult("Mult_Penetration")
|
||||||
|
|
||||||
|
-- local frags = math.random(1, self.Frangibility)
|
||||||
|
|
||||||
|
-- for i = 1, frags do
|
||||||
|
-- self:DoPenetration(tr, (self.Penetration / frags) - 0.5, tr.Entity)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
local ret = self:GetBuff_Hook("Hook_BulletHit", {
|
||||||
|
range = dist,
|
||||||
|
damage = self:GetDamage(dist),
|
||||||
|
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:GetDamageType() == DMG_BURN and ret.range <= self.Range then
|
||||||
|
if num == 1 then
|
||||||
|
dmg:SetDamageType(DMG_BULLET)
|
||||||
|
else
|
||||||
|
dmg:SetDamageType(DMG_BUCKSHOT)
|
||||||
|
end
|
||||||
|
local fx = EffectData()
|
||||||
|
fx:SetOrigin(tr.HitPos)
|
||||||
|
util.Effect("arccw_incendiaryround", fx)
|
||||||
|
|
||||||
|
util.Decal("FadingScorch", tr.StartPos, tr.HitPos - (tr.HitNormal * 16), self:GetOwner())
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
if vFireInstalled then
|
||||||
|
CreateVFire(tr.Entity, tr.HitPos, tr.HitNormal, ret.damage * 0.02)
|
||||||
|
else
|
||||||
|
tr.Entity:Ignite(1, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:DoPenetration(tr, ret.penleft)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
local se = self:GetBuff_Override("Override_ShootEntity") or self.ShootEntity
|
||||||
|
|
||||||
|
local sp = self:GetBuff_Override("Override_ShotgunSpreadPattern") or self.ShotgunSpreadPattern
|
||||||
|
local spo = self:GetBuff_Override("Override_ShotgunSpreadPatternOverrun") or self.ShotgunSpreadPatternOverrun
|
||||||
|
|
||||||
|
if sp or spo then
|
||||||
|
btabl = self:GetBuff_Hook("Hook_FireBullets", btabl)
|
||||||
|
|
||||||
|
if !btabl then return end
|
||||||
|
-- if btabl.Num == 0 then return end
|
||||||
|
|
||||||
|
local spd = AngleRand() * self:GetDispersion() / 360 / 60
|
||||||
|
|
||||||
|
if btabl.Num > 0 then
|
||||||
|
for n = 1, btabl.Num do
|
||||||
|
btabl.Num = 1
|
||||||
|
local ang
|
||||||
|
if self:GetBuff_Hook("Override_ShotgunSpreadDispersion") or self.ShotgunSpreadDispersion then
|
||||||
|
ang = self:GetOwner():EyeAngles() + (self:GetShotgunSpreadOffset(n) * self:GetDispersion() / 60)
|
||||||
|
else
|
||||||
|
ang = self:GetOwner():EyeAngles() + self:GetShotgunSpreadOffset(n) + spd
|
||||||
|
end
|
||||||
|
|
||||||
|
ang = ang + AngleRand() * spread / 10
|
||||||
|
|
||||||
|
btabl.Dir = ang:Forward()
|
||||||
|
|
||||||
|
self:GetOwner():LagCompensation(true)
|
||||||
|
|
||||||
|
self:GetOwner():FireBullets(btabl)
|
||||||
|
|
||||||
|
self:GetOwner():LagCompensation(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif se then
|
||||||
|
if num > 1 then
|
||||||
|
local spd = AngleRand() * self:GetDispersion() / 360 / 60
|
||||||
|
|
||||||
|
for n = 1, btabl.Num do
|
||||||
|
btabl.Num = 1
|
||||||
|
local ang
|
||||||
|
if self:GetBuff_Hook("Override_ShotgunSpreadDispersion") or self.ShotgunSpreadDispersion then
|
||||||
|
ang = self:GetOwner():EyeAngles() + (self:GetShotgunSpreadOffset(n) * self:GetDispersion() / 360 / 60)
|
||||||
|
else
|
||||||
|
ang = self:GetOwner():EyeAngles() + self:GetShotgunSpreadOffset(n) + spd
|
||||||
|
end
|
||||||
|
|
||||||
|
ang = ang + AngleRand() * spread / 10
|
||||||
|
|
||||||
|
self:FireRocket(se, self.MuzzleVelocity * ArcCW.HUToM * self:GetBuff_Mult("Mult_MuzzleVelocity"), ang)
|
||||||
|
end
|
||||||
|
elseif num > 0 then
|
||||||
|
self:FireRocket(se, self.MuzzleVelocity * ArcCW.HUToM * self:GetBuff_Mult("Mult_MuzzleVelocity"))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
btabl = self:GetBuff_Hook("Hook_FireBullets", btabl)
|
||||||
|
|
||||||
|
if !btabl then return end
|
||||||
|
if btabl.Num > 0 then
|
||||||
|
|
||||||
|
self:GetOwner():LagCompensation(true)
|
||||||
|
|
||||||
|
self:GetOwner():FireBullets(btabl)
|
||||||
|
|
||||||
|
self:GetOwner():LagCompensation(false)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:DoRecoil()
|
||||||
|
|
||||||
|
self:GetOwner():DoAnimationEvent(self:GetBuff_Override("Override_AnimShoot") or self.AnimShoot)
|
||||||
|
|
||||||
|
local svol = self.ShootVol * self:GetBuff_Mult("Mult_ShootVol")
|
||||||
|
local spitch = self.ShootPitch * math.Rand(0.95, 1.05) * self:GetBuff_Mult("Mult_ShootPitch")
|
||||||
|
|
||||||
|
svol = math.Clamp(svol, 51, 149)
|
||||||
|
spitch = math.Clamp(spitch, 51, 149)
|
||||||
|
|
||||||
|
if SERVER and !game.SinglePlayer() then
|
||||||
|
SuppressHostEvents(self:GetOwner())
|
||||||
|
end
|
||||||
|
|
||||||
|
self:DoEffects()
|
||||||
|
|
||||||
|
if dss then
|
||||||
|
-- sound.Play(self.DistantShootSound, self:GetPos(), 149, self.ShootPitch * math.Rand(0.95, 1.05), 1)
|
||||||
|
self:EmitSound(dss, 149, spitch, 0.5, CHAN_WEAPON + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ss then
|
||||||
|
self:EmitSound(ss, svol, spitch, 1, CzfHAN_WEAPON)
|
||||||
|
end
|
||||||
|
|
||||||
|
if IsFirstTimePredicted() then
|
||||||
|
self.BurstCount = self.BurstCount + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
self:TakePrimaryAmmo(1)
|
||||||
|
|
||||||
|
local ret = "fire"
|
||||||
|
|
||||||
|
if self:Clip1() == 0 and self.Animations.fire_iron_empty and self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
ret = "fire_iron_empty"
|
||||||
|
elseif self:Clip1() == 0 and self.Animations.fire_empty and self:GetState() != ArcCW.STATE_SIGHTS then
|
||||||
|
ret = "fire_empty"
|
||||||
|
else
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS and self.Animations.fire_iron then
|
||||||
|
ret = "fire_iron"
|
||||||
|
else
|
||||||
|
ret = "fire"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.ProceduralIronFire and self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
ret = nil
|
||||||
|
elseif self.ProceduralRegularFire and self:GetState() != ArcCW.STATE_SIGHTS then
|
||||||
|
ret = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
ret = ret or self:GetBuff_Hook("Hook_SelectFireAnimation", ret)
|
||||||
|
|
||||||
|
if ret then
|
||||||
|
self:PlayAnimation(ret, 1, true, 0, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.ManualAction or self:GetBuff_Override("Override_ManualAction") then
|
||||||
|
if !(self.NoLastCycle and self:Clip1() == 0) then
|
||||||
|
self:SetNWBool("cycle", true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetCurrentFiremode().Mode < 0 and self.BurstCount == -self:GetCurrentFiremode().Mode then
|
||||||
|
local postburst = self:GetCurrentFiremode().PostBurstDelay or 0
|
||||||
|
|
||||||
|
self:SetNextPrimaryFire(CurTime() + postburst)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:GetBuff_Hook("Hook_PostFireBullets")
|
||||||
|
|
||||||
|
if SERVER and !game.SinglePlayer() then
|
||||||
|
SuppressHostEvents(nil)
|
||||||
|
end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
math.randomseed(CurTime() + (self:EntIndex() % 31259))
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DoPenetration(tr, penleft)
|
||||||
|
if CLIENT then return end
|
||||||
|
if penleft <= 0 then return end
|
||||||
|
|
||||||
|
if tr.HitSky then return end
|
||||||
|
|
||||||
|
local penmult = ArcCW.PenTable[tr.MatType] or 1
|
||||||
|
local pentracelen = 2
|
||||||
|
|
||||||
|
local curr_ent = tr.Entity
|
||||||
|
|
||||||
|
if !tr.HitWorld then
|
||||||
|
penmult = penmult * 1.5
|
||||||
|
end
|
||||||
|
|
||||||
|
if tr.Entity.mmRHAe then
|
||||||
|
penmult = tr.Entity.mmRHAe
|
||||||
|
end
|
||||||
|
|
||||||
|
penmult = penmult * math.random(0.9, 1.1) * math.random(0.9, 1.1)
|
||||||
|
|
||||||
|
local dir = (tr.HitPos - tr.StartPos):GetNormalized()
|
||||||
|
local endpos = tr.HitPos
|
||||||
|
|
||||||
|
local ptr = util.TraceLine({
|
||||||
|
start = endpos,
|
||||||
|
endpos = endpos + (dir * pentracelen),
|
||||||
|
mask = MASK_SHOT
|
||||||
|
})
|
||||||
|
|
||||||
|
while penleft > 0 and (!ptr.StartSolid or ptr.AllSolid) and ptr.Fraction < 1 and ptr.Entity == curr_ent do
|
||||||
|
penleft = penleft - (pentracelen * penmult)
|
||||||
|
|
||||||
|
ptr = util.TraceLine({
|
||||||
|
start = endpos,
|
||||||
|
endpos = endpos + (dir * pentracelen),
|
||||||
|
mask = MASK_SHOT
|
||||||
|
})
|
||||||
|
|
||||||
|
if ptr.Entity != curr_ent then
|
||||||
|
curr_ent = ptr.Entity
|
||||||
|
|
||||||
|
local dist = (ptr.HitPos - tr.StartPos):Length() * ArcCW.HUToM
|
||||||
|
local pdelta = penleft / (self.Penetration * self:GetBuff_Mult("Mult_Penetration"))
|
||||||
|
|
||||||
|
local dmg = DamageInfo()
|
||||||
|
|
||||||
|
dmg:SetDamageType(self:GetBuff_Override("Override_DamageType") or self.DamageType)
|
||||||
|
dmg:SetDamage(self:GetDamage(dist) * pdelta)
|
||||||
|
dmg:SetDamagePosition(ptr.HitPos)
|
||||||
|
|
||||||
|
if IsValid(ptr.Entity) then
|
||||||
|
ptr.Entity:TakeDamageInfo(dmg)
|
||||||
|
end
|
||||||
|
|
||||||
|
penmult = ArcCW.PenTable[ptr.MatType] or 1
|
||||||
|
|
||||||
|
if !ptr.HitWorld then
|
||||||
|
penmult = penmult * 1.5
|
||||||
|
end
|
||||||
|
|
||||||
|
if ptr.Entity.mmRHAe then
|
||||||
|
penmult = ptr.Entity.mmRHAe
|
||||||
|
end
|
||||||
|
|
||||||
|
penmult = penmult * math.random(0.9, 1.1) * math.random(0.9, 1.1)
|
||||||
|
|
||||||
|
debugoverlay.Line(endpos, endpos + (dir * pentracelen), 10, Color(0, 0, 255), true)
|
||||||
|
end
|
||||||
|
|
||||||
|
if GetConVar("developer"):GetBool() then
|
||||||
|
local pdeltap = penleft / self.Penetration
|
||||||
|
|
||||||
|
local c = Lerp(pdeltap, 0, 255)
|
||||||
|
|
||||||
|
debugoverlay.Line(endpos, endpos + (dir * pentracelen), 10, Color(255,c, c), true)
|
||||||
|
end
|
||||||
|
|
||||||
|
endpos = endpos + (dir * pentracelen)
|
||||||
|
|
||||||
|
dir = dir + (VectorRand() * 0.025 * penmult)
|
||||||
|
end
|
||||||
|
|
||||||
|
if penleft > 0 then
|
||||||
|
-- print("bullet penetrated with " .. penleft .. "mm pen left")
|
||||||
|
--print(vel)
|
||||||
|
if (dir:Length() == 0) then return end
|
||||||
|
|
||||||
|
local pdelta = penleft / (self.Penetration * self:GetBuff_Mult("Mult_Penetration"))
|
||||||
|
|
||||||
|
self:GetOwner():FireBullets( {
|
||||||
|
Attacker = self:GetOwner(),
|
||||||
|
Damage = self.Damage * pdelta,
|
||||||
|
Force = 0,
|
||||||
|
Distance = 33000,
|
||||||
|
Num = 1,
|
||||||
|
Tracer = 0,
|
||||||
|
AmmoType = self.Primary.Ammo,
|
||||||
|
Dir = dir,
|
||||||
|
Src = endpos,
|
||||||
|
Spread = Vector(spread, spread, spread),
|
||||||
|
Callback = function(att, btr, dmg)
|
||||||
|
local dist = (btr.HitPos - endpos):Length() * ArcCW.HUToM
|
||||||
|
|
||||||
|
dmg:SetDamageType(self:GetBuff_Override("Override_DamageType") or self.DamageType)
|
||||||
|
dmg:SetDamage(self:GetDamage(dist) * pdelta)
|
||||||
|
|
||||||
|
self:DoPenetration(btr, penleft)
|
||||||
|
end
|
||||||
|
} )
|
||||||
|
|
||||||
|
self:GetOwner():FireBullets({
|
||||||
|
Damage = 0,
|
||||||
|
Src = endpos,
|
||||||
|
Dir = -dir,
|
||||||
|
Distance = 8,
|
||||||
|
Tracer = 0,
|
||||||
|
Force = 0
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
-- debugoverlay.Line(endpos, endpos + (dir * 3), 10, Color(0, 255, 0), true)
|
||||||
|
--else
|
||||||
|
--print("bullet stopped")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetShootSrc()
|
||||||
|
if self:GetOwner():IsNPC() then return self:GetOwner():GetShootPos() end
|
||||||
|
|
||||||
|
local dir = self:GetOwner():EyeAngles()
|
||||||
|
local offset = self:GetBuff_Override("Override_BarrelOffsetHip") or self.BarrelOffsetHip
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
offset = self:GetBuff_Override("Override_BarrelOffsetSighted") or self.BarrelOffsetSighted
|
||||||
|
end
|
||||||
|
|
||||||
|
local src = self:GetOwner():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(n)
|
||||||
|
local sp = self:GetBuff_Override("Override_ShotgunSpreadPattern") or self.ShotgunSpreadPattern or {}
|
||||||
|
local spo = self:GetBuff_Override("Override_ShotgunSpreadPatternOverrun") or self.ShotgunSpreadPatternOverrun or {Angle(0, 0, 0)}
|
||||||
|
|
||||||
|
sp["BaseClass"] = nil
|
||||||
|
spo["BaseClass"] = nil
|
||||||
|
|
||||||
|
if n > #sp then
|
||||||
|
if spo then
|
||||||
|
n = n - #sp
|
||||||
|
n = math.fmod(n, #spo) + 1
|
||||||
|
return spo[n]
|
||||||
|
else
|
||||||
|
n = math.fmod(n, #sp) + 1
|
||||||
|
return sp[n]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return sp[n]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetDispersion()
|
||||||
|
local delta = self:GetSightDelta()
|
||||||
|
|
||||||
|
local hip = delta * self:GetBuff_Mult("Mult_HipDispersion") * self.HipDispersion
|
||||||
|
|
||||||
|
if self:InBipod() then
|
||||||
|
hip = hip * (self:GetBuff_Mult("Mult_BipodDispersion") or 0.1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
hip = self.SightsDispersion * self:GetBuff_Mult("Mult_SightsDispersion")
|
||||||
|
end
|
||||||
|
|
||||||
|
local spd = self:GetOwner():GetAbsVelocity():Length()
|
||||||
|
|
||||||
|
spd = spd / self:GetOwner():GetWalkSpeed()
|
||||||
|
|
||||||
|
spd = math.Clamp(spd, 0, 2)
|
||||||
|
|
||||||
|
hip = hip + (spd * self.MoveDispersion * self:GetBuff_Mult("Mult_MoveDispersion"))
|
||||||
|
|
||||||
|
return hip
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DoShellEject()
|
||||||
|
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
|
||||||
|
if !IsValid(self:GetOwner()) then return end
|
||||||
|
|
||||||
|
local vm = self
|
||||||
|
|
||||||
|
if !self:GetOwner():IsNPC() then
|
||||||
|
self:GetOwner():GetViewModel()
|
||||||
|
end
|
||||||
|
|
||||||
|
local posang = vm:GetAttachment(self.CaseEffectAttachment)
|
||||||
|
|
||||||
|
if !posang then return end
|
||||||
|
|
||||||
|
local pos = posang.Pos
|
||||||
|
local ang = posang.Ang
|
||||||
|
|
||||||
|
local fx = EffectData()
|
||||||
|
fx:SetOrigin(pos)
|
||||||
|
fx:SetAngles(ang)
|
||||||
|
fx:SetAttachment(self:GetBuff_Override("Override_CaseEffectAttachment") or self.CaseEffectAttachment or 2)
|
||||||
|
fx:SetScale(1)
|
||||||
|
fx:SetEntity(self)
|
||||||
|
fx:SetNormal(ang:Forward())
|
||||||
|
fx:SetMagnitude(100)
|
||||||
|
|
||||||
|
util.Effect("arccw_shelleffect", fx)
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DoEffects()
|
||||||
|
if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
|
||||||
|
local fx = EffectData()
|
||||||
|
fx:SetScale(1)
|
||||||
|
fx:SetAttachment(self:GetBuff_Override("Override_MuzzleEffectAttachment") or self.MuzzleEffectAttachment or 1)
|
||||||
|
fx:SetEntity(self)
|
||||||
|
|
||||||
|
if self:GetBuff_Hook("Hook_PreDoEffects", {fx = fx}) == false then return end
|
||||||
|
|
||||||
|
util.Effect("arccw_muzzleeffect", fx)
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DryFire()
|
||||||
|
if self.Animations.fire_dry then
|
||||||
|
self:PlayAnimation("fire_dry", 1, true, 0, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Primary.Automatic = false
|
||||||
|
|
||||||
|
self:EmitSound("weapons/arccw/dryfire.wav", 75, 100, 1, CHAN_ITEM)
|
||||||
|
self:SetNextPrimaryFire(CurTime() + 0.25)
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DoRecoil()
|
||||||
|
if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
if game.SinglePlayer() and self:GetOwner():IsValid() and SERVER then
|
||||||
|
self:CallOnClient("DoRecoil")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if !game.SinglePlayer() and SERVER then return end
|
||||||
|
|
||||||
|
local r = math.Rand(-1, 1)
|
||||||
|
local ru = math.Rand(0.75, 1.25)
|
||||||
|
|
||||||
|
local m = 1 * self:GetBuff_Mult("Mult_Recoil")
|
||||||
|
local rs = 1 * self:GetBuff_Mult("Mult_RecoilSide")
|
||||||
|
local vsm = 1 * self:GetBuff_Mult("Mult_VisualRecoilMult")
|
||||||
|
|
||||||
|
if self:InBipod() then
|
||||||
|
m = m * (self:GetBuff_Mult("Mult_BipodRecoil") or 0.25)
|
||||||
|
rs = rs * (self:GetBuff_Mult("Mult_BipodRecoil") or 0.25)
|
||||||
|
end
|
||||||
|
|
||||||
|
local vpa = Angle(0, 0, 0)
|
||||||
|
|
||||||
|
vpa = vpa + ((self:GetBuff_Override("Override_RecoilDirection") or self.RecoilDirection) * self.Recoil * m * vsm)
|
||||||
|
|
||||||
|
vpa = vpa + ((self:GetBuff_Override("Override_RecoilDirectionSide") or self.RecoilDirectionSide) * r * self.RecoilSide * m * vsm)
|
||||||
|
|
||||||
|
vpa = vpa * (self.RecoilPunch or 1) * self:GetBuff_Mult("Mult_RecoilPunch")
|
||||||
|
|
||||||
|
self:GetOwner():ViewPunch(vpa)
|
||||||
|
-- self:SetNWFloat("recoil", self.Recoil * m)
|
||||||
|
-- self:SetNWFloat("recoilside", r * self.RecoilSide * m)
|
||||||
|
|
||||||
|
local ang = self:GetOwner():GetViewPunchAngles()
|
||||||
|
|
||||||
|
ang[1] = math.Clamp(ang[1], -180, 180)
|
||||||
|
ang[2] = math.Clamp(ang[2], -180, 180)
|
||||||
|
ang[3] = math.Clamp(ang[3], -180, 180)
|
||||||
|
|
||||||
|
self:GetOwner():SetViewPunchAngles(ang)
|
||||||
|
|
||||||
|
if CLIENT or game.SinglePlayer() then
|
||||||
|
vsm = vsm * self.VisualRecoilMult
|
||||||
|
|
||||||
|
self.RecoilAmount = self.RecoilAmount + (self.Recoil * m)
|
||||||
|
self.RecoilAmountSide = self.RecoilAmountSide + (r * self.RecoilSide * m * rs)
|
||||||
|
|
||||||
|
self.RecoilPunchBack = self.Recoil * 2.5 * m
|
||||||
|
|
||||||
|
if self.MaxRecoilBlowback > 0 then
|
||||||
|
self.RecoilPunchBack = math.Clamp(self.RecoilPunchBack, 0, self.MaxRecoilBlowback)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.RecoilPunchSide = r * self.RecoilSide * m * 0.1 * vsm
|
||||||
|
self.RecoilPunchUp = math.Clamp(ru * self.Recoil * m * 0.6 * vsm * self.RecoilRise, 0, 0.5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetBurstLength()
|
||||||
|
local bl = self:GetCurrentFiremode().Mode
|
||||||
|
|
||||||
|
if !self:GetCurrentFiremode().Mode then
|
||||||
|
return self.BurstCount + 10
|
||||||
|
end
|
||||||
|
|
||||||
|
local hsb = self:GetBuff_Hook("Hook_GetBurstLength", bl)
|
||||||
|
|
||||||
|
if bl >= 2 then return self.BurstCount + 10 end
|
||||||
|
|
||||||
|
if hsb != bl then return hsb end
|
||||||
|
|
||||||
|
if bl < 0 then return -bl end
|
||||||
|
|
||||||
|
return self.BurstCount + 10
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ShouldBeAutomatic()
|
||||||
|
if self:GetCurrentFiremode().Mode == 1 then return false end
|
||||||
|
|
||||||
|
if self:GetCurrentFiremode().RunawayBurst then return true end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:FireAnimationEvent( pos, ang, event, options )
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetDamage(range)
|
||||||
|
local num = (self:GetBuff_Override("Override_Num") or self.Num) + self:GetBuff_Add("Add_Num")
|
||||||
|
local dmult = 1
|
||||||
|
|
||||||
|
if num then
|
||||||
|
dmult = self.Num / dmult
|
||||||
|
end
|
||||||
|
|
||||||
|
local dmgmax = self.Damage * self:GetBuff_Mult("Mult_Damage") * dmult
|
||||||
|
local dmgmin = self.DamageMin * self:GetBuff_Mult("Mult_DamageMin") * dmult
|
||||||
|
|
||||||
|
local delta = 1
|
||||||
|
|
||||||
|
if dmgmax < dmgmin then
|
||||||
|
delta = range / (self.Range / self:GetBuff_Mult("Mult_Range"))
|
||||||
|
else
|
||||||
|
delta = range / (self.Range * self:GetBuff_Mult("Mult_Range"))
|
||||||
|
end
|
||||||
|
|
||||||
|
delta = math.Clamp(delta, 0, 1)
|
||||||
|
|
||||||
|
local amt = Lerp(delta, dmgmax, dmgmin)
|
||||||
|
|
||||||
|
return amt
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SecondaryAttack()
|
||||||
|
if self.Melee2 then
|
||||||
|
self:Bash(true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
65
lua/weapons/arccw_base/sh_grenade.lua
Normal file
65
lua/weapons/arccw_base/sh_grenade.lua
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
SWEP.GrenadePrimeTime = 0
|
||||||
|
|
||||||
|
function SWEP:PreThrow()
|
||||||
|
if self:Clip1() == 0 then
|
||||||
|
if self:Ammo1() == 0 then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
self:SetClip1(1)
|
||||||
|
self:GetOwner():SetAmmo(self:Ammo1() - 1, self.Primary.Ammo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self:GetNWBool("grenadeprimed") then return end
|
||||||
|
|
||||||
|
self:PlayAnimation("pre_throw", 1, false, 0, true)
|
||||||
|
|
||||||
|
self:SetNextPrimaryFire(CurTime() + self.PullPinTime)
|
||||||
|
|
||||||
|
self:SetNWBool("grenadeprimed", true)
|
||||||
|
|
||||||
|
self.GrenadePrimeTime = CurTime()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:Throw()
|
||||||
|
if self:GetNextPrimaryFire() > CurTime() then return end
|
||||||
|
|
||||||
|
self:SetNWBool("grenadeprimed", false)
|
||||||
|
|
||||||
|
self:PlayAnimation("throw", 1, false, 0, true)
|
||||||
|
|
||||||
|
local heldtime = (CurTime() - self.GrenadePrimeTime)
|
||||||
|
|
||||||
|
local windup = heldtime / 0.5
|
||||||
|
|
||||||
|
windup = math.Clamp(windup, 0, 1)
|
||||||
|
|
||||||
|
local force = Lerp(windup, self.MuzzleVelocity * 0.25, self.MuzzleVelocity)
|
||||||
|
|
||||||
|
self:SetTimer(0.25, function()
|
||||||
|
local rocket = self:FireRocket(self.ShootEntity, force)
|
||||||
|
|
||||||
|
if !rocket then return end
|
||||||
|
|
||||||
|
if self.FuseTime then
|
||||||
|
rocket.FuseTime = self.FuseTime - heldtime
|
||||||
|
end
|
||||||
|
|
||||||
|
local phys = rocket:GetPhysicsObject()
|
||||||
|
|
||||||
|
phys:AddAngleVelocity( Vector(0, 750, 0) )
|
||||||
|
|
||||||
|
self:TakePrimaryAmmo(1)
|
||||||
|
|
||||||
|
if self:Clip1() == 0 and self:Ammo1() >= 1 then
|
||||||
|
self:SetClip1(1)
|
||||||
|
self:GetOwner():SetAmmo(self:Ammo1() - 1, self.Primary.Ammo)
|
||||||
|
else
|
||||||
|
self:GetOwner():StripWeapon(self:GetClass())
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
self:SetTimer(self:GetAnimTime("throw"), function()
|
||||||
|
self:PlayAnimation("draw")
|
||||||
|
end)
|
||||||
|
|
||||||
|
self:SetNextPrimaryFire(CurTime() + 1)
|
||||||
|
end
|
703
lua/weapons/arccw_base/sh_model.lua
Normal file
703
lua/weapons/arccw_base/sh_model.lua
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
function SWEP:KillModels()
|
||||||
|
self:KillModel(self.WM)
|
||||||
|
self.WM = nil
|
||||||
|
self:KillModel(self.VM)
|
||||||
|
self.VM = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:AddElement(elementname, wm)
|
||||||
|
local e = self.AttachmentElements[elementname]
|
||||||
|
|
||||||
|
if !e then return end
|
||||||
|
if !wm and self:GetOwner():IsNPC() then return end
|
||||||
|
|
||||||
|
if !self:CheckFlags(e.ExcludeFlags, e.RequireFlags) then return end
|
||||||
|
|
||||||
|
if GetConVar("arccw_truenames"):GetBool() and e.TrueNameChange then
|
||||||
|
self.PrintName = e.TrueNameChange
|
||||||
|
end
|
||||||
|
|
||||||
|
if !GetConVar("arccw_truenames"):GetBool() and e.NameChange then
|
||||||
|
self.PrintName = e.NameChange
|
||||||
|
end
|
||||||
|
|
||||||
|
if e.AddPrefix then
|
||||||
|
self.PrintName = e.AddPrefix .. self.PrintName
|
||||||
|
end
|
||||||
|
|
||||||
|
if e.AddSuffix then
|
||||||
|
self.PrintName = self.PrintName .. e.AddSuffix
|
||||||
|
end
|
||||||
|
|
||||||
|
local og_weapon = weapons.GetStored(self:GetClass())
|
||||||
|
|
||||||
|
local og_vm = og_weapon.ViewModel
|
||||||
|
local og_wm = og_weapon.WorldModel
|
||||||
|
|
||||||
|
self.ViewModel = og_vm
|
||||||
|
self.WorldModel = og_wm
|
||||||
|
|
||||||
|
local parent = self
|
||||||
|
local elements = self.WM
|
||||||
|
|
||||||
|
if !wm then
|
||||||
|
parent = self:GetOwner():GetViewModel()
|
||||||
|
elements = self.VM
|
||||||
|
end
|
||||||
|
|
||||||
|
local eles = e.VMElements
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
eles = e.WMElements
|
||||||
|
|
||||||
|
self.WorldModel = e.WMOverride or self.WorldModel
|
||||||
|
self:SetSkin(e.WMSkin or self.DefaultWMSkin)
|
||||||
|
else
|
||||||
|
self.ViewModel = e.VMOverride or self.ViewModel
|
||||||
|
self:GetOwner():GetViewModel():SetSkin(e.VMSkin or self.DefaultSkin)
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER then return end
|
||||||
|
|
||||||
|
for _, i in pairs(eles or {}) do
|
||||||
|
local model = ClientsideModel(i.Model)
|
||||||
|
|
||||||
|
if !model then continue end
|
||||||
|
|
||||||
|
if i.BoneMerge then
|
||||||
|
model:SetParent(parent)
|
||||||
|
model:AddEffects(EF_BONEMERGE)
|
||||||
|
else
|
||||||
|
model:SetParent(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
local element = {}
|
||||||
|
|
||||||
|
local scale = Matrix()
|
||||||
|
scale:Scale(i.Scale or Vector(1, 1, 1))
|
||||||
|
|
||||||
|
model:SetNoDraw(ArcCW.NoDraw)
|
||||||
|
model:DrawShadow(true)
|
||||||
|
model:SetPredictable(false)
|
||||||
|
model.Weapon = self
|
||||||
|
model:SetSkin(i.ModelSkin or 0)
|
||||||
|
model:SetBodyGroups(i.ModelBodygroups or "")
|
||||||
|
model:EnableMatrix("RenderMultiply", scale)
|
||||||
|
model:SetupBones()
|
||||||
|
element.Model = model
|
||||||
|
element.RenderFunc = i.RenderFunc
|
||||||
|
element.WM = wm or false
|
||||||
|
element.Bone = i.Bone
|
||||||
|
element.NoDraw = i.NoDraw or false
|
||||||
|
element.BoneMerge = i.BoneMerge or false
|
||||||
|
element.Bodygroups = i.ModelBodygroups
|
||||||
|
element.DrawFunc = i.DrawFunc
|
||||||
|
element.OffsetAng = Angle()
|
||||||
|
element.OffsetAng:Set(i.Offset.ang or Angle(0, 0, 0))
|
||||||
|
element.OffsetPos = Vector()
|
||||||
|
element.OffsetPos:Set(i.Offset.pos or Vector(), 0, 0)
|
||||||
|
element.IsMuzzleDevice = i.IsMuzzleDevice
|
||||||
|
|
||||||
|
table.insert(elements, element)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SetupModel(wm)
|
||||||
|
local elements = {}
|
||||||
|
|
||||||
|
if !wm and !self:GetOwner():IsPlayer() then return end
|
||||||
|
|
||||||
|
local og = weapons.Get(self:GetClass())
|
||||||
|
|
||||||
|
self.PrintName = self.OldPrintName or og.PrintName
|
||||||
|
|
||||||
|
self:GetActiveElements(true)
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
self:KillModel(self.WM)
|
||||||
|
self.WM = elements
|
||||||
|
|
||||||
|
if !GetConVar("arccw_att_showothers"):GetBool() then
|
||||||
|
if LocalPlayer() != self:GetOwner() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:KillModel(self.VM)
|
||||||
|
self.VM = elements
|
||||||
|
|
||||||
|
if !IsValid(self:GetOwner()) or self:GetOwner():IsNPC() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if !IsValid(self:GetOwner():GetViewModel()) then
|
||||||
|
self:SetTimer(0.5, function()
|
||||||
|
self:SetupModel(wm)
|
||||||
|
end)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self:GetOwner():GetViewModel():SetupBones()
|
||||||
|
end
|
||||||
|
|
||||||
|
render.OverrideDepthEnable( true, true )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if wm and CLIENT then
|
||||||
|
local model = ClientsideModel(self.WorldModel)
|
||||||
|
|
||||||
|
if !model then return end
|
||||||
|
if !IsValid(model) then return end
|
||||||
|
|
||||||
|
model:SetNoDraw(ArcCW.NoDraw)
|
||||||
|
model:DrawShadow(true)
|
||||||
|
model:SetPredictable(false)
|
||||||
|
model:SetParent(self:GetOwner() or self)
|
||||||
|
model:AddEffects(EF_BONEMERGE)
|
||||||
|
model.Weapon = self
|
||||||
|
model:SetSkin(self.DefaultWMSkin or 0)
|
||||||
|
model:SetBodyGroups(self.DefaultWMBodygroups or "")
|
||||||
|
model:SetupBones()
|
||||||
|
local element = {}
|
||||||
|
element.Model = model
|
||||||
|
element.WM = true
|
||||||
|
element.OffsetAng = Angle(0, 0, 0)
|
||||||
|
element.IsBaseWM = true
|
||||||
|
element.BoneMerge = true
|
||||||
|
|
||||||
|
self.WMModel = model
|
||||||
|
|
||||||
|
table.insert(elements, element)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, k in pairs(self.DefaultElements) do
|
||||||
|
self:AddElement(k, wm)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
|
||||||
|
if k.InstalledEles then
|
||||||
|
for _, ele in pairs(k.InstalledEles or {}) do
|
||||||
|
self:AddElement(ele, wm)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
for _, ele in pairs(atttbl.ActivateElements or {}) do
|
||||||
|
self:AddElement(ele, wm)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.AttachmentElements[k.Installed] then
|
||||||
|
self:AddElement(k.Installed, wm)
|
||||||
|
end
|
||||||
|
|
||||||
|
local slots = atttbl.Slot
|
||||||
|
|
||||||
|
if isstring(slots) then
|
||||||
|
slots = {slots}
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, ele in pairs(slots) do
|
||||||
|
self:AddElement(ele, wm)
|
||||||
|
end
|
||||||
|
|
||||||
|
if atttbl.AddPrefix then
|
||||||
|
self.PrintName = atttbl.AddPrefix .. self.PrintName
|
||||||
|
end
|
||||||
|
|
||||||
|
if atttbl.AddSuffix then
|
||||||
|
self.PrintName = self.PrintName .. atttbl.AddSuffix
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER then continue end
|
||||||
|
|
||||||
|
if wm and k.NoWM then continue end
|
||||||
|
if !wm and k.NoVM then continue end
|
||||||
|
|
||||||
|
if !atttbl.Model then continue end
|
||||||
|
if atttbl.HideModel then continue end
|
||||||
|
|
||||||
|
if !k.Offset and !atttbl.BoneMerge then continue end
|
||||||
|
|
||||||
|
local model = ClientsideModel(atttbl.Model)
|
||||||
|
|
||||||
|
if !model then continue end
|
||||||
|
|
||||||
|
if atttbl.BoneMerge then
|
||||||
|
local parent = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
parent = self:GetOwner()
|
||||||
|
end
|
||||||
|
|
||||||
|
model:SetParent(parent)
|
||||||
|
model:AddEffects(EF_BONEMERGE)
|
||||||
|
else
|
||||||
|
model:SetParent(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
local repbone = nil
|
||||||
|
local repang = nil
|
||||||
|
|
||||||
|
for _, e in pairs(self:GetActiveElements()) do
|
||||||
|
local ele = self.AttachmentElements[e]
|
||||||
|
|
||||||
|
if !ele then continue end
|
||||||
|
|
||||||
|
if ((ele.AttPosMods or {})[i] or {}).bone then
|
||||||
|
repbone = ele.AttPosMods.bone
|
||||||
|
end
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
if ((ele.AttPosMods or {})[i] or {}).wmang then
|
||||||
|
repang = ele.AttPosMods.wmang
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ((ele.AttPosMods or {})[i] or {}).vmang then
|
||||||
|
repang = ele.AttPosMods.vmang
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local element = {}
|
||||||
|
|
||||||
|
local scale = Matrix()
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
scale:Scale((k.WMScale or Vector(1, 1, 1)) * (atttbl.ModelScale or 1))
|
||||||
|
else
|
||||||
|
scale:Scale((k.VMScale or Vector(1, 1, 1)) * (atttbl.ModelScale or 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
model:SetNoDraw(ArcCW.NoDraw)
|
||||||
|
model:DrawShadow(true)
|
||||||
|
model:SetPredictable(false)
|
||||||
|
model.Weapon = self
|
||||||
|
model:SetSkin(atttbl.ModelSkin or 0)
|
||||||
|
model:SetBodyGroups(atttbl.ModelBodygroups or "")
|
||||||
|
model:SetupBones()
|
||||||
|
model:EnableMatrix("RenderMultiply", scale)
|
||||||
|
element.Model = model
|
||||||
|
element.RenderFunc = atttbl.RenderFunc
|
||||||
|
element.WM = wm or false
|
||||||
|
element.Bone = repbone or k.Bone
|
||||||
|
element.NoDraw = atttbl.NoDraw or false
|
||||||
|
element.BoneMerge = k.BoneMerge or false
|
||||||
|
element.Bodygroups = atttbl.ModelBodygroups
|
||||||
|
element.DrawFunc = atttbl.DrawFunc
|
||||||
|
element.Slot = i
|
||||||
|
element.ModelOffset = atttbl.ModelOffset or Vector(0, 0, 0)
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
element.OffsetAng = Angle()
|
||||||
|
element.OffsetAng:Set(repang or k.Offset.wang or Angle(0, 0, 0))
|
||||||
|
element.OffsetAng = element.OffsetAng + (atttbl.OffsetAng or Angle(0, 0, 0))
|
||||||
|
k.WElement = element
|
||||||
|
else
|
||||||
|
element.OffsetAng = Angle()
|
||||||
|
element.OffsetAng:Set(repang or k.Offset.vang or Angle(0, 0, 0))
|
||||||
|
element.OffsetAng = element.OffsetAng + (atttbl.OffsetAng or Angle(0, 0, 0))
|
||||||
|
k.VMOffsetAng = element.OffsetAng
|
||||||
|
k.VElement = element
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(elements, element)
|
||||||
|
|
||||||
|
if atttbl.IsMuzzleDevice or atttbl.UBGL then
|
||||||
|
local hspmodel = ClientsideModel(atttbl.Model)
|
||||||
|
|
||||||
|
if k.BoneMerge then
|
||||||
|
local parent = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
parent = self:GetOwner()
|
||||||
|
end
|
||||||
|
|
||||||
|
hspmodel:SetParent(parent)
|
||||||
|
hspmodel:AddEffects(EF_BONEMERGE)
|
||||||
|
else
|
||||||
|
hspmodel:SetParent(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
local hspelement = {}
|
||||||
|
hspmodel:SetNoDraw(true)
|
||||||
|
hspmodel:DrawShadow(true)
|
||||||
|
hspmodel:SetPredictable(false)
|
||||||
|
hspmodel.Weapon = self
|
||||||
|
|
||||||
|
hspelement.Model = hspmodel
|
||||||
|
hspmodel:EnableMatrix("RenderMultiply", scale)
|
||||||
|
|
||||||
|
hspelement.WM = wm or false
|
||||||
|
hspelement.Bone = repbone or k.Bone
|
||||||
|
hspelement.NoDraw = true
|
||||||
|
hspelement.BoneMerge = k.BoneMerge or false
|
||||||
|
hspelement.Slot = i
|
||||||
|
|
||||||
|
hspelement.OffsetAng = element.OffsetAng
|
||||||
|
|
||||||
|
if atttbl.IsMuzzleDevice then
|
||||||
|
hspelement.IsMuzzleDevice = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
k.WMuzzleDeviceElement = hspelement
|
||||||
|
else
|
||||||
|
k.VMuzzleDeviceElement = hspelement
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(elements, hspelement)
|
||||||
|
else
|
||||||
|
k.VMuzzleDeviceElement = nil
|
||||||
|
k.WMuzzleDeviceElement = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if atttbl.HolosightPiece then
|
||||||
|
local hspmodel = ClientsideModel(atttbl.HolosightPiece)
|
||||||
|
|
||||||
|
if k.BoneMerge then
|
||||||
|
local parent = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
parent = self:GetOwner()
|
||||||
|
end
|
||||||
|
|
||||||
|
hspmodel:SetParent(parent)
|
||||||
|
hspmodel:AddEffects(EF_BONEMERGE)
|
||||||
|
else
|
||||||
|
hspmodel:SetParent(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
local hspelement = {}
|
||||||
|
hspmodel:SetNoDraw(true)
|
||||||
|
hspmodel:DrawShadow(true)
|
||||||
|
hspmodel:SetPredictable(false)
|
||||||
|
hspmodel:EnableMatrix("RenderMultiply", scale)
|
||||||
|
hspmodel.Weapon = self
|
||||||
|
|
||||||
|
hspelement.Model = hspmodel
|
||||||
|
|
||||||
|
hspelement.WM = wm or false
|
||||||
|
hspelement.Bone = repbone or k.Bone
|
||||||
|
hspelement.NoDraw = atttbl.NoDraw or false
|
||||||
|
hspelement.BoneMerge = k.BoneMerge or false
|
||||||
|
hspelement.Slot = i
|
||||||
|
|
||||||
|
hspelement.OffsetAng = element.OffsetAng
|
||||||
|
|
||||||
|
if !wm then
|
||||||
|
k.HSPElement = hspelement
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(elements, hspelement)
|
||||||
|
else
|
||||||
|
k.HSPElement = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
|
||||||
|
if !wm and self.HolosightPiece then
|
||||||
|
local hspmodel = ClientsideModel(self.HolosightPiece)
|
||||||
|
|
||||||
|
hspmodel:SetParent(parent)
|
||||||
|
hspmodel:AddEffects(EF_BONEMERGE)
|
||||||
|
|
||||||
|
local hspelement = {}
|
||||||
|
hspmodel:SetNoDraw(true)
|
||||||
|
hspmodel:DrawShadow(true)
|
||||||
|
hspmodel:SetPredictable(false)
|
||||||
|
hspmodel.Weapon = self
|
||||||
|
|
||||||
|
hspelement.Model = hspmodel
|
||||||
|
|
||||||
|
hspelement.WM = wm or false
|
||||||
|
hspelement.BoneMerge = true
|
||||||
|
hspelement.NoDraw = false
|
||||||
|
|
||||||
|
if !wm then
|
||||||
|
self.HSPElement = hspelement
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(elements, hspelement)
|
||||||
|
end
|
||||||
|
|
||||||
|
local eid = self:EntIndex()
|
||||||
|
|
||||||
|
for i, k in pairs(elements) do
|
||||||
|
local piletab = {
|
||||||
|
Model = k.Model,
|
||||||
|
Weapon = self
|
||||||
|
}
|
||||||
|
|
||||||
|
table.insert(ArcCW.CSModelPile, piletab)
|
||||||
|
end
|
||||||
|
|
||||||
|
if !ArcCW.CSModels[eid] then
|
||||||
|
ArcCW.CSModels[eid] = {
|
||||||
|
Weapon = self
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
self.WM = elements
|
||||||
|
self:KillModel(ArcCW.CSModels[eid].WModels)
|
||||||
|
ArcCW.CSModels[eid].WModels = elements
|
||||||
|
else
|
||||||
|
self.VM = elements
|
||||||
|
self:KillModel(ArcCW.CSModels[eid].VModels)
|
||||||
|
ArcCW.CSModels[eid].VModels = elements
|
||||||
|
end
|
||||||
|
|
||||||
|
render.OverrideDepthEnable( false, true )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetupActiveSights()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:KillModel(models)
|
||||||
|
if !models then return end
|
||||||
|
if table.Count(models) == 0 then return end
|
||||||
|
|
||||||
|
for _, i in pairs(models) do
|
||||||
|
if !isentity(i.Model) then continue end
|
||||||
|
SafeRemoveEntity(i.Model)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DrawCustomModel(wm)
|
||||||
|
local models = self.VM
|
||||||
|
local vm
|
||||||
|
local selfmode = false
|
||||||
|
|
||||||
|
-- self:KillModel(self.VM)
|
||||||
|
-- self:KillModel(self.WM)
|
||||||
|
-- self.VM = nil
|
||||||
|
-- self.WM = nil
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
if !self.WM then
|
||||||
|
self:SetupModel(wm)
|
||||||
|
end
|
||||||
|
|
||||||
|
models = self.WM
|
||||||
|
|
||||||
|
vm = self:GetOwner()
|
||||||
|
|
||||||
|
if !IsValid(self:GetOwner()) then
|
||||||
|
vm = self
|
||||||
|
selfmode = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if !self.VM then
|
||||||
|
self:SetupModel(wm)
|
||||||
|
end
|
||||||
|
|
||||||
|
vm = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
models = self.VM
|
||||||
|
|
||||||
|
if self.HSPElement then
|
||||||
|
self.HSPElement.Model:DrawModel()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, k in pairs(models) do
|
||||||
|
if !IsValid(k.Model) then
|
||||||
|
self:SetupModel(wm)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- local asight = self:GetActiveSights()
|
||||||
|
|
||||||
|
-- if asight then
|
||||||
|
-- local activeslot = asight.Slot
|
||||||
|
-- if k.Slot == activeslot and ArcCW.Overdraw then
|
||||||
|
-- continue
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
if k.IsBaseWM then
|
||||||
|
if self:GetOwner():IsValid() then
|
||||||
|
k.Model:SetParent(self:GetOwner())
|
||||||
|
else
|
||||||
|
k.Model:SetParent(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if k.BoneMerge and !k.NoDraw then
|
||||||
|
k.Model:DrawModel()
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
local bonename = k.Bone
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
bonename = k.WMBone or "ValveBiped.Bip01_R_Hand"
|
||||||
|
end
|
||||||
|
|
||||||
|
if !bonename then continue end
|
||||||
|
|
||||||
|
local bpos, bang
|
||||||
|
|
||||||
|
local boneindex = vm:LookupBone(bonename)
|
||||||
|
|
||||||
|
if selfmode then
|
||||||
|
boneindex = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if !boneindex then continue end
|
||||||
|
|
||||||
|
bpos, bang = vm:GetBonePosition(boneindex)
|
||||||
|
|
||||||
|
if bpos == vm:GetPos() then
|
||||||
|
bpos = vm:GetBoneMatrix(boneindex):GetTranslation()
|
||||||
|
end
|
||||||
|
|
||||||
|
local offset = k.OffsetPos
|
||||||
|
|
||||||
|
if k.Slot then
|
||||||
|
|
||||||
|
local attslot = self.Attachments[k.Slot]
|
||||||
|
|
||||||
|
local delta = attslot.SlidePos or 0.5
|
||||||
|
|
||||||
|
local vmelemod = nil
|
||||||
|
local wmelemod = 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 {})[k.Slot] or {}).vpos then
|
||||||
|
vmelemod = ele.AttPosMods[k.Slot].vpos
|
||||||
|
end
|
||||||
|
|
||||||
|
if ((ele.AttPosMods or {})[k.Slot] or {}).wpos then
|
||||||
|
wmelemod = ele.AttPosMods[k.Slot].wpos
|
||||||
|
end
|
||||||
|
|
||||||
|
if ((ele.AttPosMods or {})[k.Slot] or {}).slide then
|
||||||
|
slidemod = ele.AttPosMods[k.Slot].slide
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if wm then
|
||||||
|
offset = wmelemod or (attslot.Offset or {}).wpos or Vector(0, 0, 0)
|
||||||
|
|
||||||
|
if attslot.SlideAmount then
|
||||||
|
offset = LerpVector(delta, (slidemod or attslot.SlideAmount).wmin or Vector(0, 0, 0), (slidemod or attslot.SlideAmount).wmax or Vector(0, 0, 0))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
offset = vmelemod or (attslot.Offset or {}).vpos or Vector(0, 0, 0)
|
||||||
|
|
||||||
|
if attslot.SlideAmount then
|
||||||
|
offset = LerpVector(delta, (slidemod or attslot.SlideAmount).vmin or Vector(0, 0, 0), (slidemod or attslot.SlideAmount).vmax or Vector(0, 0, 0))
|
||||||
|
end
|
||||||
|
|
||||||
|
attslot.VMOffsetPos = offset
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos = offset or Vector(0, 0, 0)
|
||||||
|
local ang = k.OffsetAng or Angle(0, 0, 0)
|
||||||
|
|
||||||
|
local moffset = (k.ModelOffset or Vector(0, 0, 0))
|
||||||
|
|
||||||
|
apos = bpos + bang:Forward() * pos.x
|
||||||
|
apos = apos + bang:Right() * pos.y
|
||||||
|
apos = apos + bang:Up() * pos.z
|
||||||
|
|
||||||
|
local aang = Angle()
|
||||||
|
aang:Set(bang)
|
||||||
|
|
||||||
|
aang:RotateAroundAxis(aang:Right(), ang.p)
|
||||||
|
aang:RotateAroundAxis(aang:Up(), ang.y)
|
||||||
|
aang:RotateAroundAxis(aang:Forward(), ang.r)
|
||||||
|
|
||||||
|
apos = apos + aang:Forward() * moffset.x
|
||||||
|
apos = apos + aang:Right() * moffset.y
|
||||||
|
apos = apos + aang:Up() * moffset.z
|
||||||
|
|
||||||
|
k.Model:SetPos(apos)
|
||||||
|
k.Model:SetAngles(aang)
|
||||||
|
k.Model:SetRenderOrigin(apos)
|
||||||
|
k.Model:SetRenderAngles(apos)
|
||||||
|
|
||||||
|
if k.Bodygroups then
|
||||||
|
k.Model:SetBodyGroups(k.Bodygroups)
|
||||||
|
end
|
||||||
|
|
||||||
|
if k.DrawFunc then
|
||||||
|
k.DrawFunc(self, k, wm)
|
||||||
|
end
|
||||||
|
|
||||||
|
if !k.NoDraw then
|
||||||
|
k.Model:DrawModel()
|
||||||
|
end
|
||||||
|
|
||||||
|
if activeslot then
|
||||||
|
if i != activeslot and ArcCW.Overdraw then
|
||||||
|
k.Model:SetBodygroup(1, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:RefreshBGs()
|
||||||
|
end
|
||||||
|
|
||||||
|
SWEP.ReferencePosCache = {}
|
||||||
|
|
||||||
|
function SWEP:GetFromReference(boneid)
|
||||||
|
if !boneid then boneid = 1 end
|
||||||
|
if self.ReferencePosCache[boneid] then
|
||||||
|
return self.ReferencePosCache[boneid].Pos, self.ReferencePosCache[boneid].Ang
|
||||||
|
end
|
||||||
|
|
||||||
|
SafeRemoveEntity(ArcCW.ReferenceModel)
|
||||||
|
|
||||||
|
if !self.ViewModel then
|
||||||
|
-- uh oh panic
|
||||||
|
local og = weapons.Get(self:GetClass())
|
||||||
|
self.ViewModel = og.ViewModel
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.ReferenceModel = ClientsideModel(self.ViewModel)
|
||||||
|
|
||||||
|
local pos = self:GetOwner():EyePos()
|
||||||
|
local ang = self:GetOwner():EyeAngles()
|
||||||
|
|
||||||
|
ArcCW.ReferenceModel:SetPos(pos)
|
||||||
|
ArcCW.ReferenceModel:SetAngles(ang)
|
||||||
|
ArcCW.ReferenceModel:SetNoDraw(true)
|
||||||
|
ArcCW.ReferenceModel:SetupBones()
|
||||||
|
|
||||||
|
local id = ArcCW.ReferenceModel:LookupSequence("idle")
|
||||||
|
|
||||||
|
ArcCW.ReferenceModel:SetSequence(id)
|
||||||
|
ArcCW.ReferenceModel:SetCycle(0)
|
||||||
|
|
||||||
|
-- local transform = ArcCW.ReferenceModel:GetBoneMatrix(boneid)
|
||||||
|
|
||||||
|
-- local bpos, bang = transform:GetTranslation(), transform:GetAngles()
|
||||||
|
|
||||||
|
local bpos, bang = ArcCW.ReferenceModel:GetBonePosition(boneid)
|
||||||
|
|
||||||
|
-- SafeRemoveEntity(ArcCW.ReferenceModel)
|
||||||
|
|
||||||
|
bpos, bang = WorldToLocal(pos, ang, bpos, bang)
|
||||||
|
|
||||||
|
self.ReferencePosCache[boneid] = {Pos = bpos, Ang = bang}
|
||||||
|
|
||||||
|
return bpos, bang
|
||||||
|
end
|
247
lua/weapons/arccw_base/sh_reload.lua
Normal file
247
lua/weapons/arccw_base/sh_reload.lua
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
function SWEP:Reload()
|
||||||
|
if self:GetOwner():IsNPC() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetNextPrimaryFire() >= CurTime() then return end
|
||||||
|
if self:GetNextSecondaryFire() > CurTime() then return end
|
||||||
|
|
||||||
|
if self.Throwing then return end
|
||||||
|
if self.PrimaryBash then return end
|
||||||
|
|
||||||
|
if self:GetNWBool("ubgl") then
|
||||||
|
self:ReloadUBGL()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:Ammo1() <= 0 then return end
|
||||||
|
|
||||||
|
self.LastClip1 = self:Clip1()
|
||||||
|
|
||||||
|
local reserve = self:Ammo1()
|
||||||
|
|
||||||
|
reserve = reserve + self:Clip1()
|
||||||
|
|
||||||
|
local clip = self:GetCapacity()
|
||||||
|
|
||||||
|
local chamber = math.Clamp(self:Clip1(), 0, self:GetBuff_Override("Override_ChamberSize") or self.ChamberSize)
|
||||||
|
|
||||||
|
local load = math.Clamp(clip + chamber, 0, reserve)
|
||||||
|
|
||||||
|
if load <= self:Clip1() then return end
|
||||||
|
|
||||||
|
if !self.ReloadInSights then
|
||||||
|
self:ExitSights()
|
||||||
|
self.Sighted = false
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetNWBool("reloading", true)
|
||||||
|
self:SetNWBool("reqend", false)
|
||||||
|
self.BurstCount = 0
|
||||||
|
|
||||||
|
local shouldshotgunreload = self.ShotgunReload
|
||||||
|
|
||||||
|
if self:GetBuff_Override("Override_ShotgunReload") then
|
||||||
|
shouldshotgunreload = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetBuff_Override("Override_ShotgunReload") == false then
|
||||||
|
shouldshotgunreload = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.HybridReload or self:GetBuff_Override("Override_HybridReload") then
|
||||||
|
if self:Clip1() == 0 then
|
||||||
|
shouldshotgunreload = false
|
||||||
|
else
|
||||||
|
shouldshotgunreload = true
|
||||||
|
end
|
||||||
|
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:GetNWBool("cycle", false)
|
||||||
|
|
||||||
|
if self.Animations.sgreload_start_empty and empty then
|
||||||
|
anim = "sgreload_start_empty"
|
||||||
|
empty = false
|
||||||
|
|
||||||
|
insertcount = (self.Animations.sgreload_start_empty or {}).RestoreAmmo or 1
|
||||||
|
end
|
||||||
|
|
||||||
|
anim = self:GetBuff_Hook("Hook_SelectReloadAnimation", anim) or anim
|
||||||
|
|
||||||
|
self:GetOwner():SetAmmo(self:Ammo1() - insertcount, self.Primary.Ammo)
|
||||||
|
self:SetClip1(self:Clip1() + insertcount)
|
||||||
|
|
||||||
|
self:PlayAnimation(anim, mult, true, 0, true)
|
||||||
|
|
||||||
|
self:SetTimer(self:GetAnimTime(anim) * mult,
|
||||||
|
function()
|
||||||
|
self:ReloadInsert(empty)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
local anim = self:SelectReloadAnimation()
|
||||||
|
|
||||||
|
if self:Clip1() == 0 then
|
||||||
|
self:SetNWBool("cycle", false)
|
||||||
|
end
|
||||||
|
|
||||||
|
if !self.Animations[anim] then print("Invalid animation \"" .. anim .. "\"") return end
|
||||||
|
|
||||||
|
self:PlayAnimation(anim, mult, true, 0, true)
|
||||||
|
self:SetTimer(self:GetAnimTime(anim) * mult,
|
||||||
|
function()
|
||||||
|
self:SetNWBool("reloading", false)
|
||||||
|
end)
|
||||||
|
self.CheckpointAnimation = anim
|
||||||
|
self.CheckpointTime = 0
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
self:GetOwner():GiveAmmo(self:Clip1(), self.Primary.Ammo, true)
|
||||||
|
self:SetClip1(0)
|
||||||
|
self:TakePrimaryAmmo(load)
|
||||||
|
self:SetClip1(load)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.RevolverReload then
|
||||||
|
self.LastClip1 = load
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Primary.Automatic = false
|
||||||
|
end
|
||||||
|
|
||||||
|
local lastframeclip1 = 0
|
||||||
|
|
||||||
|
SWEP.LastClipOutTime = 0
|
||||||
|
|
||||||
|
function SWEP:GetVisualBullets()
|
||||||
|
if self.LastClipOutTime > CurTime() then
|
||||||
|
return self.LastClip1_B or self:Clip1()
|
||||||
|
else
|
||||||
|
self.LastClip1_B = self:Clip1()
|
||||||
|
|
||||||
|
return self:Clip1()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetVisualClip()
|
||||||
|
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
|
||||||
|
|
||||||
|
return self:Clip1()
|
||||||
|
end
|
||||||
|
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 !empty then
|
||||||
|
total = total + (self:GetBuff_Override("Override_ChamberSize") or self.ChamberSize)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetNWBool("reloading", true)
|
||||||
|
|
||||||
|
local mult = self:GetBuff_Mult("Mult_ReloadTime")
|
||||||
|
|
||||||
|
if self:Clip1() >= total or self:Ammo1() == 0 or self:GetNWBool("reqend", false) then
|
||||||
|
local ret = "sgreload_finish"
|
||||||
|
|
||||||
|
if empty then
|
||||||
|
ret = "sgreload_finish_empty"
|
||||||
|
if self:GetNWBool("cycle") then
|
||||||
|
self:SetNWBool("cycle", false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ret = self:GetBuff_Hook("Hook_SelectReloadAnimation", ret) or ret
|
||||||
|
|
||||||
|
self:PlayAnimation(ret, mult, true, 0, true)
|
||||||
|
self:SetTimer(self:GetAnimTime(ret) * mult,
|
||||||
|
function()
|
||||||
|
self:SetNWBool("reloading", false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
self:SetNWBool("reqend", false)
|
||||||
|
else
|
||||||
|
local insertcount = 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
|
||||||
|
|
||||||
|
self:GetOwner():SetAmmo(self:Ammo1() - insertcount, self.Primary.Ammo)
|
||||||
|
self:SetClip1(self:Clip1() + insertcount)
|
||||||
|
|
||||||
|
self:PlayAnimation(insertanim, mult, true, 0, true)
|
||||||
|
self:SetTimer(self:GetAnimTime(insertanim) * mult,
|
||||||
|
function()
|
||||||
|
self:ReloadInsert(empty)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetCapacity()
|
||||||
|
local clip = self.RegularClipSize or self.Primary.ClipSize
|
||||||
|
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_Override("Override_ClipSize") or clip
|
||||||
|
|
||||||
|
clip = clip + self:GetBuff_Add("Add_ClipSize")
|
||||||
|
|
||||||
|
local ret = self:GetBuff_Hook("Hook_GetCapacity", clip)
|
||||||
|
|
||||||
|
clip = ret or clip
|
||||||
|
|
||||||
|
clip = math.Clamp(clip, 0, math.huge)
|
||||||
|
|
||||||
|
self.Primary.ClipSize = clip
|
||||||
|
|
||||||
|
return clip
|
||||||
|
end
|
30
lua/weapons/arccw_base/sh_rocket.lua
Normal file
30
lua/weapons/arccw_base/sh_rocket.lua
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function SWEP:FireRocket(ent, vel, ang)
|
||||||
|
if CLIENT then return end
|
||||||
|
|
||||||
|
local rocket = ents.Create(ent)
|
||||||
|
|
||||||
|
ang = ang or self:GetOwner():EyeAngles()
|
||||||
|
|
||||||
|
local src = self:GetShootSrc()
|
||||||
|
|
||||||
|
if !rocket:IsValid() then print("!!! INVALID ROUND " .. ent) return end
|
||||||
|
|
||||||
|
rocket:SetAngles(ang)
|
||||||
|
rocket:SetPos(src)
|
||||||
|
rocket:Spawn()
|
||||||
|
rocket:Activate()
|
||||||
|
constraint.NoCollide(self:GetOwner(), rocket, 0, 0)
|
||||||
|
rocket:GetPhysicsObject():SetVelocity(self:GetOwner():GetAbsVelocity())
|
||||||
|
rocket:GetPhysicsObject():SetVelocityInstantaneous(ang:Forward() * vel)
|
||||||
|
rocket:SetCollisionGroup(COLLISION_GROUP_PROJECTILE)
|
||||||
|
|
||||||
|
rocket.Owner = self:GetOwner()
|
||||||
|
|
||||||
|
if rocket.ArcCW_Killable == nil then
|
||||||
|
rocket.ArcCW_Killable = true
|
||||||
|
end
|
||||||
|
|
||||||
|
rocket.ArcCWProjectile = true
|
||||||
|
|
||||||
|
return rocket
|
||||||
|
end
|
424
lua/weapons/arccw_base/sh_sights.lua
Normal file
424
lua/weapons/arccw_base/sh_sights.lua
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
SWEP.Sighted = false
|
||||||
|
SWEP.Sprinted = false
|
||||||
|
|
||||||
|
function SWEP:GetSightTime()
|
||||||
|
return self.SightTime * self:GetBuff_Mult("Mult_SightTime")
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:EnterSprint()
|
||||||
|
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
self:SetState(ArcCW.STATE_SPRINT)
|
||||||
|
self.Sighted = false
|
||||||
|
self.Sprinted = true
|
||||||
|
|
||||||
|
-- self.SwayScale = 1
|
||||||
|
-- self.BobScale = 5
|
||||||
|
|
||||||
|
self:SetShouldHoldType()
|
||||||
|
|
||||||
|
local s = self:GetBuff_Override("Override_ShootWhileSprint") or self.ShootWhileSprint
|
||||||
|
|
||||||
|
if !s and self:GetNextPrimaryFire() <= (CurTime() + self:GetSightTime()) then
|
||||||
|
self:SetNextPrimaryFire(CurTime() + self:GetSightTime())
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Animations.enter_sprint then
|
||||||
|
self:PlayAnimation("enter_sprint", self:GetSightTime())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ExitSprint()
|
||||||
|
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
self:SetState(ArcCW.STATE_IDLE)
|
||||||
|
self.Sighted = false
|
||||||
|
self.Sprinted = false
|
||||||
|
|
||||||
|
-- self.SwayScale = 1
|
||||||
|
-- self.BobScale = 1.5
|
||||||
|
|
||||||
|
self:SetShouldHoldType()
|
||||||
|
|
||||||
|
local s = self:GetBuff_Override("Override_ShootWhileSprint") or self.ShootWhileSprint
|
||||||
|
|
||||||
|
if !s and self:GetNextPrimaryFire() <= (CurTime() + self:GetSightTime()) then
|
||||||
|
self:SetNextPrimaryFire(CurTime() + self:GetSightTime())
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetOwner():KeyDown(IN_ATTACK2) then
|
||||||
|
self:EnterSights()
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Animations.exit_sprint then
|
||||||
|
self:PlayAnimation("exit_sprint", self:GetSightTime())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SWEP.LastEnterSightTime = 0
|
||||||
|
SWEP.LastExitSightTime = 0
|
||||||
|
|
||||||
|
function SWEP:EnterSights()
|
||||||
|
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
local asight = self:GetActiveSights()
|
||||||
|
if !asight then return end
|
||||||
|
if self:GetState() != ArcCW.STATE_IDLE then return end
|
||||||
|
if !self.ReloadInSights and self:GetNWBool("reloading", false) then return end
|
||||||
|
|
||||||
|
self:SetupActiveSights()
|
||||||
|
|
||||||
|
self:SetState(ArcCW.STATE_SIGHTS)
|
||||||
|
self.Sighted = true
|
||||||
|
self.Sprinted = false
|
||||||
|
|
||||||
|
self:SetShouldHoldType()
|
||||||
|
|
||||||
|
-- self.SwayScale = 0.1
|
||||||
|
-- self.BobScale = 0.1
|
||||||
|
|
||||||
|
if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
|
||||||
|
self:EmitSound(asight.SwitchToSound or "weapons/arccw/movement1.wav", 75, math.Rand(95, 105), 0.5, CHAN_VOICE2)
|
||||||
|
|
||||||
|
self.LastEnterSightTime = CurTime()
|
||||||
|
|
||||||
|
if self.Animations.enter_sight then
|
||||||
|
self:PlayAnimation("enter_sight", self:GetSightTime())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ExitSights()
|
||||||
|
-- if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
local asight = self:GetActiveSights()
|
||||||
|
if self:GetState() != ArcCW.STATE_SIGHTS then return end
|
||||||
|
|
||||||
|
self:SetState(ArcCW.STATE_IDLE)
|
||||||
|
self.Sighted = false
|
||||||
|
self.Sprinted = false
|
||||||
|
|
||||||
|
-- self.SwayScale = 1
|
||||||
|
-- self.BobScale = 1.5
|
||||||
|
|
||||||
|
self:SetShouldHoldType()
|
||||||
|
|
||||||
|
if self:InSprint() then
|
||||||
|
self:EnterSprint()
|
||||||
|
end
|
||||||
|
|
||||||
|
if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
|
||||||
|
self:EmitSound(asight.SwitchFromSound or "weapons/arccw/movement1.wav", 75, math.Rand(80, 90), 0.5, CHAN_VOICE2)
|
||||||
|
|
||||||
|
self.LastExitSightTime = CurTime()
|
||||||
|
|
||||||
|
if self.Animations.exit_sight then
|
||||||
|
self:PlayAnimation("exit_sight", self:GetSightTime())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetSightDelta()
|
||||||
|
local lst = self.LastExitSightTime
|
||||||
|
local minus = 0
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
lst = self.LastEnterSightTime
|
||||||
|
minus = 1
|
||||||
|
|
||||||
|
if CurTime() - lst >= self:GetSightTime() then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if CurTime() - lst >= self:GetSightTime() then
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local delta = minus - math.Clamp((CurTime() - lst) / self:GetSightTime(), 0, 1)
|
||||||
|
|
||||||
|
delta = math.abs(delta)
|
||||||
|
|
||||||
|
return delta
|
||||||
|
end
|
||||||
|
|
||||||
|
SWEP.SightTable = {}
|
||||||
|
SWEP.SightMagnifications = {}
|
||||||
|
|
||||||
|
function SWEP:SetupActiveSights()
|
||||||
|
if !self.IronSightStruct then return 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
|
||||||
|
|
||||||
|
for i, k in pairs(self.Attachments) do
|
||||||
|
if !k.Installed then continue end
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
||||||
|
|
||||||
|
if !atttbl.AdditionalSights then continue end
|
||||||
|
|
||||||
|
if !k.KeepBaseIrons then kbi = false end
|
||||||
|
|
||||||
|
for _, s in pairs(atttbl.AdditionalSights) 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
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
offset = vmelemod or attslot.Offset.vpos
|
||||||
|
|
||||||
|
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 !s.IgnoreExtra 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
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(sighttable, stab)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if kbi then
|
||||||
|
table.insert(sighttable, table.Copy(self:GetBuff_Override("Override_IronSightStruct") or self.IronSightStruct))
|
||||||
|
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
|
||||||
|
|
||||||
|
if self:GetNextPrimaryFire() <= (CurTime() + self:GetSightTime()) then
|
||||||
|
self:SetNextPrimaryFire(CurTime() + self:GetSightTime())
|
||||||
|
end
|
||||||
|
|
||||||
|
local asight = self:GetActiveSights()
|
||||||
|
|
||||||
|
if asight.SwitchToSound then
|
||||||
|
self:EmitSound(asight.SwitchToSound, 75, math.Rand(95, 105), 0.5, CHAN_VOICE2)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.LastEnterSightTime = CurTime()
|
||||||
|
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
|
||||||
|
|
||||||
|
function SWEP:TranslateFOV(fov)
|
||||||
|
local irons = self:GetActiveSights()
|
||||||
|
if !irons then return end
|
||||||
|
if !irons.Magnification then return fov end
|
||||||
|
if irons.Magnification == 1 then return fov end
|
||||||
|
|
||||||
|
self.ApproachFOV = self.ApproachFOV or fov
|
||||||
|
self.CurrentFOV = self.CurrentFOV or fov
|
||||||
|
|
||||||
|
if self:GetState() != ArcCW.STATE_SIGHTS then
|
||||||
|
self.ApproachFOV = fov
|
||||||
|
else
|
||||||
|
self.ApproachFOV = fov / irons.Magnification
|
||||||
|
end
|
||||||
|
|
||||||
|
self.CurrentFOV = math.Approach(self.CurrentFOV, self.ApproachFOV, FrameTime() * (self.CurrentFOV - self.ApproachFOV))
|
||||||
|
return self.CurrentFOV
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SetShouldHoldType()
|
||||||
|
if self:GetCurrentFiremode().Mode == 0 then
|
||||||
|
self:SetHoldType(self.HoldtypeHolstered)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
self:SetHoldType(self:GetBuff_Override("Override_HoldtypeSights") or self.HoldtypeSights)
|
||||||
|
elseif self:GetState() == ArcCW.STATE_SPRINT then
|
||||||
|
self:SetHoldType(self:GetBuff_Override("Override_HoldtypeHolstered") or self.HoldtypeHolstered)
|
||||||
|
elseif self:GetState() == ArcCW.STATE_CUSTOMIZE then
|
||||||
|
self:SetHoldType(self:GetBuff_Override("Override_HoldtypeCustomize") or self.HoldtypeCustomize)
|
||||||
|
elseif self:GetCurrentFiremode().Mode == 0 then
|
||||||
|
self:SetHoldType(self:GetBuff_Override("Override_HoldtypeHolstered") or self.HoldtypeHolstered)
|
||||||
|
else
|
||||||
|
self:SetHoldType(self:GetBuff_Override("Override_HoldtypeActive") or self.HoldtypeActive)
|
||||||
|
end
|
||||||
|
end
|
243
lua/weapons/arccw_base/sh_think.lua
Normal file
243
lua/weapons/arccw_base/sh_think.lua
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
if CLIENT then
|
||||||
|
|
||||||
|
ArcCW.LastWeapon = nil
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:Think()
|
||||||
|
if !IsValid(self:GetOwner()) or self:GetOwner():IsNPC() then return end
|
||||||
|
|
||||||
|
local vm = self:GetOwner():GetViewModel()
|
||||||
|
|
||||||
|
if self:GetOwner():KeyPressed(IN_ATTACK) then
|
||||||
|
self:SetNWBool("reqend", true)
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
if ArcCW.LastWeapon != self then
|
||||||
|
self:LoadPreset("autosave")
|
||||||
|
end
|
||||||
|
|
||||||
|
ArcCW.LastWeapon = self
|
||||||
|
end
|
||||||
|
|
||||||
|
self:InBipod()
|
||||||
|
|
||||||
|
if (self:GetCurrentFiremode().Mode == 2 or !self:GetOwner():KeyDown(IN_ATTACK)) and self:GetNWBool("cycle", false) and !self:GetNWBool("reloading", false) then
|
||||||
|
local anim = "cycle"
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS and self.Animations.cycle_iron then
|
||||||
|
anim = "cycle_iron"
|
||||||
|
end
|
||||||
|
anim = self:GetBuff_Hook("Hook_SelectCycleAnimation", anim) or anim
|
||||||
|
local mult = self:GetBuff_Mult("Mult_CycleTime")
|
||||||
|
self:PlayAnimation(anim, mult, true, 0, true)
|
||||||
|
self:SetNWBool("cycle", false)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetNWBool("grenadeprimed") and !self:GetOwner():KeyDown(IN_ATTACK) then
|
||||||
|
self:Throw()
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetNWBool("grenadeprimed") and self.GrenadePrimeTime > 0 then
|
||||||
|
local heldtime = (CurTime() - self.GrenadePrimeTime)
|
||||||
|
|
||||||
|
if self.FuseTime and (heldtime >= self.FuseTime) then
|
||||||
|
self:Throw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetOwner():KeyPressed(IN_USE) then
|
||||||
|
if self:InBipod() then
|
||||||
|
self:ExitBipod()
|
||||||
|
else
|
||||||
|
self:EnterBipod()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetCurrentFiremode().RunawayBurst and self:Clip1() > 0 then
|
||||||
|
if self.BurstCount > 0 then
|
||||||
|
self:PrimaryAttack()
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.BurstCount == self:GetBurstLength() then
|
||||||
|
self.Primary.Automatic = false
|
||||||
|
self.BurstCount = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetOwner():KeyReleased(IN_ATTACK) then
|
||||||
|
if !self:GetCurrentFiremode().RunawayBurst then
|
||||||
|
self.BurstCount = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:GetCurrentFiremode().Mode < 0 and !self:GetCurrentFiremode().RunawayBurst then
|
||||||
|
local postburst = self:GetCurrentFiremode().PostBurstDelay or 0
|
||||||
|
|
||||||
|
if (CurTime() + postburst) > self:GetNextPrimaryFire() then
|
||||||
|
self:SetNextPrimaryFire(CurTime() + postburst)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if self:GetOwner():GetInfoNum("arccw_toggleads", 0) == 0 then
|
||||||
|
if self:GetOwner():KeyDown(IN_ATTACK2) and self:GetState() != ArcCW.STATE_SIGHTS then
|
||||||
|
self:EnterSights()
|
||||||
|
elseif !self:GetOwner():KeyDown(IN_ATTACK2) and self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
self:ExitSights()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if self:GetOwner():KeyPressed(IN_ATTACK2) then
|
||||||
|
if self:GetState() != ArcCW.STATE_SIGHTS then
|
||||||
|
self:EnterSights()
|
||||||
|
else
|
||||||
|
self:ExitSights()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (CLIENT or game.SinglePlayer()) and (IsFirstTimePredicted() or game.SinglePlayer()) then
|
||||||
|
local ft = FrameTime()
|
||||||
|
-- if CLIENT then
|
||||||
|
-- ft = RealFrameTime()
|
||||||
|
-- end
|
||||||
|
|
||||||
|
local newang = self:GetOwner():EyeAngles()
|
||||||
|
local r = self.RecoilAmount -- self:GetNWFloat("recoil", 0)
|
||||||
|
local rs = self.RecoilAmountSide -- self:GetNWFloat("recoilside", 0)
|
||||||
|
|
||||||
|
local ra = Angle(0, 0, 0)
|
||||||
|
|
||||||
|
ra = ra + ((self:GetBuff_Override("Override_RecoilDirection") or self.RecoilDirection) * self.RecoilAmount * 0.5)
|
||||||
|
ra = ra + ((self:GetBuff_Override("Override_RecoilDirectionSide") or self.RecoilDirectionSide) * self.RecoilAmountSide * 0.5)
|
||||||
|
|
||||||
|
newang = newang - ra
|
||||||
|
|
||||||
|
self.RecoilAmount = r - (ft * r * 20)
|
||||||
|
self.RecoilAmountSide = rs - (ft * rs * 20)
|
||||||
|
|
||||||
|
self.RecoilAmount = math.Approach(self.RecoilAmount, 0, ft * 0.1)
|
||||||
|
self.RecoilAmountSide = math.Approach(self.RecoilAmountSide, 0, ft * 0.1)
|
||||||
|
|
||||||
|
-- self:SetNWFloat("recoil", r - (FrameTime() * r * 50))
|
||||||
|
-- self:SetNWFloat("recoilside", rs - (FrameTime() * rs * 50))
|
||||||
|
|
||||||
|
self:GetOwner():SetEyeAngles(newang)
|
||||||
|
|
||||||
|
for i = 1, vm:GetBoneCount() do
|
||||||
|
vm:ManipulateBoneScale(i, Vector(1, 1, 1) )
|
||||||
|
end
|
||||||
|
|
||||||
|
local rpb = self.RecoilPunchBack
|
||||||
|
local rps = self.RecoilPunchSide
|
||||||
|
local rpu = self.RecoilPunchUp
|
||||||
|
|
||||||
|
if rpb != 0 then
|
||||||
|
self.RecoilPunchBack = math.Approach(rpb, 0, ft * rpb * 2.5)
|
||||||
|
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
|
||||||
|
|
||||||
|
local vec1 = Vector(1, 1, 1)
|
||||||
|
local vec0 = vec1 * 0
|
||||||
|
|
||||||
|
for i, k in pairs(self.CaseBones or {}) do
|
||||||
|
if !isnumber(i) then continue end
|
||||||
|
local bone = vm:LookupBone(k)
|
||||||
|
|
||||||
|
if !bone then continue end
|
||||||
|
|
||||||
|
vm:ManipulateBoneScale(bone, vec0)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, k in pairs(self.BulletBones or {}) do
|
||||||
|
if !isnumber(i) then continue end
|
||||||
|
local bone = vm:LookupBone(k)
|
||||||
|
|
||||||
|
if !bone then continue end
|
||||||
|
|
||||||
|
vm:ManipulateBoneScale(bone, vec0)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, k in pairs(self.CaseBones or {}) do
|
||||||
|
if !isnumber(i) then continue end
|
||||||
|
local bone = vm:LookupBone(k)
|
||||||
|
|
||||||
|
if !bone then continue end
|
||||||
|
|
||||||
|
if self:GetVisualClip() >= i then
|
||||||
|
vm:ManipulateBoneScale(bone, vec1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, k in pairs(self.BulletBones or {}) do
|
||||||
|
if !isnumber(i) then continue end
|
||||||
|
local bone = vm:LookupBone(k)
|
||||||
|
|
||||||
|
if !bone then continue end
|
||||||
|
|
||||||
|
if self:GetVisualBullets() >= i then
|
||||||
|
vm:ManipulateBoneScale(bone, vec1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
if self.Throwing then
|
||||||
|
if self:Clip1() == 0 then
|
||||||
|
if self:Ammo1() > 0 then
|
||||||
|
self:SetClip1(1)
|
||||||
|
self:GetOwner():SetAmmo(self:Ammo1() - 1, self.Primary.Ammo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- self:RefreshBGs()
|
||||||
|
|
||||||
|
self:GetBuff_Override("Hook_Think")
|
||||||
|
|
||||||
|
if SERVER or !game.SinglePlayer() then
|
||||||
|
self:ProcessTimers()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:InSprint()
|
||||||
|
local sm = self.SpeedMult * self:GetBuff_Mult("Mult_SpeedMult") * self:GetBuff_Mult("Mult_MoveSpeed")
|
||||||
|
|
||||||
|
sm = math.Clamp(sm, 0, 1)
|
||||||
|
|
||||||
|
local sprintspeed = self:GetOwner():GetRunSpeed() * sm
|
||||||
|
local walkspeed = self:GetOwner():GetWalkSpeed() * sm
|
||||||
|
|
||||||
|
local curspeed = self:GetOwner():GetVelocity():Length()
|
||||||
|
|
||||||
|
if !self:GetOwner():KeyDown(IN_SPEED) then return false end
|
||||||
|
if curspeed < Lerp(0.5, walkspeed, sprintspeed) then return false end
|
||||||
|
if !self:GetOwner():OnGround() then return false end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
97
lua/weapons/arccw_base/sh_timers.lua
Normal file
97
lua/weapons/arccw_base/sh_timers.lua
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
function SWEP:InitTimers()
|
||||||
|
self.ActiveTimers = {} -- {{time, callback}}
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SetTimer(time, callback, id)
|
||||||
|
-- if !IsFirstTimePredicted() then return end
|
||||||
|
-- if time < 0 then return end
|
||||||
|
id = id or ""
|
||||||
|
table.insert(self.ActiveTimers, {time + CurTime(), id, callback})
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:TimerExists(id)
|
||||||
|
for k, 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 k, v in pairs(self.ActiveTimers) do
|
||||||
|
if v[2] != id then
|
||||||
|
table.insert(keeptimers, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.ActiveTimers = keeptimers
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:KillTimers()
|
||||||
|
self.ActiveTimers = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ProcessTimers()
|
||||||
|
local ct = CurTime()
|
||||||
|
|
||||||
|
if !self.ActiveTimers then
|
||||||
|
self:InitTimers()
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, v in pairs(self.ActiveTimers) do
|
||||||
|
if v[1] <= ct then
|
||||||
|
v[3]()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local keeptimers = {}
|
||||||
|
|
||||||
|
for k, v in pairs(self.ActiveTimers) do
|
||||||
|
if v[1] > ct then
|
||||||
|
table.insert(keeptimers, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.ActiveTimers = keeptimers
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:PlaySoundTable(soundtable, mult, startfrom)
|
||||||
|
if CLIENT and game.SinglePlayer() then return end
|
||||||
|
mult = mult or 1
|
||||||
|
mult = 1 / mult
|
||||||
|
startfrom = startfrom or 0
|
||||||
|
for k, v in pairs(soundtable) do
|
||||||
|
|
||||||
|
if !v.t then continue end
|
||||||
|
|
||||||
|
local pitch = 100
|
||||||
|
local vol = 75
|
||||||
|
|
||||||
|
if v.p then
|
||||||
|
pitch = v.p
|
||||||
|
end
|
||||||
|
|
||||||
|
if v.v then
|
||||||
|
vol = v.v
|
||||||
|
end
|
||||||
|
|
||||||
|
local st = (v.t * mult) - startfrom
|
||||||
|
|
||||||
|
if isnumber(v.t) then
|
||||||
|
if st < 0 then continue end
|
||||||
|
if self:GetOwner():IsNPC() then
|
||||||
|
timer.Simple(st, function()
|
||||||
|
if !IsValid(self) then return end
|
||||||
|
if !IsValid(self:GetOwner()) then return end
|
||||||
|
self:EmitSound(v.s, vol, pitch, 1, CHAN_AUTO)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
self:SetTimer(st, function() self:EmitSound(v.s, vol, pitch, 1, v.c or CHAN_AUTO) end, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
116
lua/weapons/arccw_base/sh_ubgl.lua
Normal file
116
lua/weapons/arccw_base/sh_ubgl.lua
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
|
||||||
|
function SWEP:SelectUBGL()
|
||||||
|
self:SetNWBool("ubgl", true)
|
||||||
|
self:EmitSound(self.SelectUBGLSound)
|
||||||
|
self:SetNWInt("firemode", 1)
|
||||||
|
|
||||||
|
if CLIENT 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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:DeselectUBGL()
|
||||||
|
self:SetNWBool("ubgl", false)
|
||||||
|
self:EmitSound(self.ExitUBGLSound)
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
if !ArcCW:ShouldDrawHUDElement("CHudAmmo") then
|
||||||
|
self:GetOwner():ChatPrint("Deselected " .. self:GetBuff_Override("UBGL_PrintName") or "UBGL")
|
||||||
|
end
|
||||||
|
if !self:GetLHIKAnim() then
|
||||||
|
self:DoLHIKAnimation("exit")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:RecoilUBGL()
|
||||||
|
if !game.SinglePlayer() and !IsFirstTimePredicted() then return end
|
||||||
|
if game.SinglePlayer() and self:GetOwner():IsValid() and SERVER then
|
||||||
|
self:CallOnClient("RecoilUBGL")
|
||||||
|
end
|
||||||
|
|
||||||
|
local amt = self:GetBuff_Override("UBGL_Recoil")
|
||||||
|
|
||||||
|
local r = math.Rand(-1, 1)
|
||||||
|
local ru = math.Rand(0.75, 1.25)
|
||||||
|
|
||||||
|
local m = 1 * amt
|
||||||
|
local rs = 1 * amt * 0.1
|
||||||
|
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 * amt * m * vsm)
|
||||||
|
|
||||||
|
self:GetOwner():ViewPunch(vpa)
|
||||||
|
-- self:SetNWFloat("recoil", self.Recoil * m)
|
||||||
|
-- self:SetNWFloat("recoilside", r * self.RecoilSide * m)
|
||||||
|
|
||||||
|
local ang = self:GetOwner():GetViewPunchAngles()
|
||||||
|
|
||||||
|
ang[1] = math.Clamp(ang[1], -180, 180)
|
||||||
|
ang[2] = math.Clamp(ang[2], -180, 180)
|
||||||
|
ang[3] = math.Clamp(ang[3], -180, 180)
|
||||||
|
|
||||||
|
self:GetOwner():SetViewPunchAngles(ang)
|
||||||
|
|
||||||
|
if CLIENT or game.SinglePlayer() then
|
||||||
|
|
||||||
|
self.RecoilAmount = self.RecoilAmount + (amt * m)
|
||||||
|
self.RecoilAmountSide = self.RecoilAmountSide + (r * amt * m * rs)
|
||||||
|
|
||||||
|
self.RecoilPunchBack = amt * 1 * m
|
||||||
|
|
||||||
|
if self.MaxRecoilBlowback > 0 then
|
||||||
|
self.RecoilPunchBack = math.Clamp(self.RecoilPunchBack, 0, self.MaxRecoilBlowback)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.RecoilPunchSide = rs * rs * m * 0.1 * vsm
|
||||||
|
self.RecoilPunchUp = ru * amt * m * 0.3 * vsm
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:ShootUBGL()
|
||||||
|
if self:GetNextSecondaryFire() > CurTime() then return 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.Primary.Automatic = false
|
||||||
|
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
|
542
lua/weapons/arccw_base/shared.lua
Normal file
542
lua/weapons/arccw_base/shared.lua
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
SWEP.Spawnable = false -- this obviously has to be set to true
|
||||||
|
SWEP.Category = "ArcCW - Firearms" -- edit this if you like
|
||||||
|
SWEP.AdminOnly = false
|
||||||
|
|
||||||
|
SWEP.PrintName = "MP-K1"
|
||||||
|
SWEP.Trivia_Class = nil -- "Submachine Gun"
|
||||||
|
SWEP.Trivia_Desc = nil -- "Ubiquitous 9mm SMG. Created as a response to the need for a faster-firing and more reliable submachine gun than existing options at the time."
|
||||||
|
SWEP.Trivia_Manufacturer = nil -- "Auschen Waffenfabrik"
|
||||||
|
SWEP.Trivia_Calibre = nil -- "9x21mm Jager"
|
||||||
|
SWEP.Trivia_Mechanism = nil -- "Roller-Delayed Blowback"
|
||||||
|
SWEP.Trivia_Country = nil -- "Austria"
|
||||||
|
SWEP.Trivia_Year = nil -- 1968
|
||||||
|
|
||||||
|
SWEP.UseHands = true
|
||||||
|
|
||||||
|
SWEP.ViewModel = "" -- I mean, you probably have to edit these too
|
||||||
|
SWEP.WorldModel = ""
|
||||||
|
|
||||||
|
SWEP.PresetBase = nil -- make this weapon share presets with this one.
|
||||||
|
|
||||||
|
SWEP.KillIconAlias = nil -- set to other weapon class to share select and kill icons
|
||||||
|
|
||||||
|
SWEP.DefaultBodygroups = "00000000"
|
||||||
|
SWEP.DefaultWMBodygroups = "00000000"
|
||||||
|
SWEP.DefaultSkin = 0
|
||||||
|
SWEP.DefaultWMSkin = 0
|
||||||
|
|
||||||
|
SWEP.Damage = 26
|
||||||
|
SWEP.DamageMin = 10 -- damage done at maximum range
|
||||||
|
SWEP.Range = 200 -- in METRES
|
||||||
|
SWEP.Penetration = 4
|
||||||
|
SWEP.DamageType = DMG_BULLET
|
||||||
|
SWEP.ShootEntity = nil -- entity to fire, if any
|
||||||
|
SWEP.MuzzleVelocity = 400 -- projectile or phys bullet muzzle velocity
|
||||||
|
-- IN M/S
|
||||||
|
|
||||||
|
SWEP.TracerNum = 1 -- tracer every X
|
||||||
|
SWEP.Tracer = nil -- override tracer effect
|
||||||
|
SWEP.TracerCol = Color(255, 255, 255)
|
||||||
|
|
||||||
|
SWEP.ChamberSize = 1 -- how many rounds can be chambered.
|
||||||
|
SWEP.Primary.ClipSize = 25 -- DefaultClip is automatically set.
|
||||||
|
SWEP.ExtendedClipSize = 50
|
||||||
|
SWEP.ReducedClipSize = 10
|
||||||
|
|
||||||
|
SWEP.ShotgunReload = false -- reloads like shotgun instead of magazines
|
||||||
|
SWEP.HybridReload = false -- reload normally when empty, reload like shotgun when part full
|
||||||
|
|
||||||
|
SWEP.ManualAction = false -- pump/bolt action
|
||||||
|
SWEP.NoLastCycle = false -- do not cycle on last shot
|
||||||
|
|
||||||
|
SWEP.RevolverReload = false -- cases all eject on reload
|
||||||
|
|
||||||
|
SWEP.ReloadInSights = false
|
||||||
|
|
||||||
|
SWEP.CanFireUnderwater = false
|
||||||
|
|
||||||
|
SWEP.Recoil = 2
|
||||||
|
SWEP.RecoilSide = 1
|
||||||
|
SWEP.RecoilRise = 1
|
||||||
|
SWEP.MaxRecoilBlowback = -1
|
||||||
|
SWEP.VisualRecoilMult = 1.25
|
||||||
|
SWEP.RecoilPunch = 1.5
|
||||||
|
|
||||||
|
SWEP.ShotgunSpreadDispersion = false -- dispersion will cause pattern to increase instead of shifting
|
||||||
|
SWEP.ShotgunSpreadPattern = nil
|
||||||
|
SWEP.ShotgunSpreadPatternOverrun = nil
|
||||||
|
-- {Angle(1, 1, 0), Angle(1, 0, 0) ..}
|
||||||
|
-- list of how far each pellet should veer
|
||||||
|
-- if only one pellet then it'll use the first index
|
||||||
|
-- if two then the first two
|
||||||
|
-- in case of overrun pellets will start looping, preferably with the second one, so use that for the loopables
|
||||||
|
-- precision will still be applied
|
||||||
|
|
||||||
|
SWEP.RecoilDirection = Angle(1, 0, 0)
|
||||||
|
SWEP.RecoilDirectionSide = Angle(0, 1, 0)
|
||||||
|
|
||||||
|
SWEP.Delay = 60 / 750 -- 60 / RPM.
|
||||||
|
SWEP.Num = 1 -- number of shots per trigger pull.
|
||||||
|
SWEP.Firemode = 1 -- 0: safe, 1: semi, 2: auto, negative: burst
|
||||||
|
SWEP.RunawayBurst = false
|
||||||
|
SWEP.Firemodes = {
|
||||||
|
-- {
|
||||||
|
-- Mode = 1,
|
||||||
|
-- CustomBars = "----_", -- custom bar setup
|
||||||
|
-- PrintName = "PUMP",
|
||||||
|
-- RunAwayBurst = false,
|
||||||
|
-- PostBurstDelay = 0,
|
||||||
|
-- }
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.NotForNPCS = false
|
||||||
|
SWEP.NPCWeaponType = nil -- string or table, the NPC weapons for this gun to replace
|
||||||
|
-- if nil, this will be based on holdtype
|
||||||
|
SWEP.NPCWeight = 100 -- relative likeliness for an NPC to have this weapon
|
||||||
|
|
||||||
|
SWEP.AccuracyMOA = 15 -- accuracy in Minutes of Angle. There are 60 MOA in a degree.
|
||||||
|
SWEP.HipDispersion = 500 -- inaccuracy added by hip firing.
|
||||||
|
SWEP.MoveDispersion = 150 -- inaccuracy added by moving. Applies in sights as well! Walking speed is considered as "maximum".
|
||||||
|
SWEP.SightsDispersion = 0 -- dispersion that remains even in sights
|
||||||
|
|
||||||
|
SWEP.ShootWhileSprint = false
|
||||||
|
|
||||||
|
SWEP.Primary.Ammo = "pistol" -- what ammo type the gun uses
|
||||||
|
SWEP.MagID = "mpk1" -- the magazine pool this gun draws from
|
||||||
|
|
||||||
|
SWEP.ShootVol = 125 -- volume of shoot sound
|
||||||
|
SWEP.ShootPitch = 100 -- pitch of shoot sound
|
||||||
|
|
||||||
|
SWEP.FirstShootSound = nil
|
||||||
|
SWEP.ShootSound = ""
|
||||||
|
SWEP.FirstShootSoundSilenced = nil
|
||||||
|
SWEP.DistantShootSound = nil
|
||||||
|
SWEP.ShootSoundSilenced = "weapons/arccw/m4a1/m4a1-1.wav"
|
||||||
|
SWEP.FiremodeSound = "weapons/arccw/firemode.wav"
|
||||||
|
SWEP.MeleeSwingSound = "weapons/arccw/m249/m249_draw.wav"
|
||||||
|
SWEP.MeleeHitSound = "weapons/arccw/knife/knife_hitwall1.wav"
|
||||||
|
SWEP.MeleeHitNPCSound = "physics/body/body_medium_break2.wav"
|
||||||
|
SWEP.EnterBipodSound = "weapons/arccw/m249/m249_coverdown.wav"
|
||||||
|
SWEP.ExitBipodSound = "weapons/arccw/m249/m249_coverup.wav"
|
||||||
|
SWEP.SelectUBGLSound = "weapons/arccw/ubgl_select.wav"
|
||||||
|
SWEP.ExitUBGLSound = "weapons/arccw/ubgl_exit.wav"
|
||||||
|
|
||||||
|
SWEP.MuzzleEffect = "arccw_muzzleeffect"
|
||||||
|
|
||||||
|
SWEP.ShellModel = "models/shells/shell_556.mdl"
|
||||||
|
SWEP.ShellMaterial = nil
|
||||||
|
SWEP.ShellScale = 1
|
||||||
|
SWEP.ShellPhysScale = 1
|
||||||
|
SWEP.ShellPitch = 100
|
||||||
|
SWEP.ShellSounds = ArcCW.ShellSoundsTable
|
||||||
|
SWEP.ShellRotate = 0
|
||||||
|
SWEP.ShellTime = 1 -- add shell life time
|
||||||
|
|
||||||
|
SWEP.MuzzleEffectAttachment = 1 -- which attachment to put the muzzle on
|
||||||
|
SWEP.CaseEffectAttachment = 2 -- which attachment to put the case effect on
|
||||||
|
|
||||||
|
SWEP.SpeedMult = 0.9
|
||||||
|
SWEP.SightedSpeedMult = 0.75
|
||||||
|
|
||||||
|
SWEP.BulletBones = { -- the bone that represents bullets in gun/mag
|
||||||
|
-- [0] = "bulletchamber",
|
||||||
|
-- [1] = "bullet1"
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.CaseBones = {}
|
||||||
|
|
||||||
|
SWEP.KeepBaseIrons = false -- do not override iron sights when scope installed
|
||||||
|
|
||||||
|
SWEP.IronSightStruct = {
|
||||||
|
Pos = Vector(-8.728, -13.702, 4.014),
|
||||||
|
Ang = Angle(-1.397, -0.341, -2.602),
|
||||||
|
Magnification = 1,
|
||||||
|
BlackBox = false,
|
||||||
|
ScopeTexture = nil,
|
||||||
|
ScopeFOV = nil, -- FOV of the scope texture
|
||||||
|
SwitchToSound = "", -- sound that plays when switching to this sight
|
||||||
|
SwitchFromSound = "",
|
||||||
|
ScrollFunc = ArcCW.SCROLL_NONE,
|
||||||
|
CrosshairInSights = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.ProceduralRegularFire = false
|
||||||
|
SWEP.ProceduralIronFire = false
|
||||||
|
SWEP.SightTime = 0.33
|
||||||
|
|
||||||
|
SWEP.HoldtypeHolstered = "passive"
|
||||||
|
SWEP.HoldtypeActive = "shotgun"
|
||||||
|
SWEP.HoldtypeSights = "smg"
|
||||||
|
SWEP.HoldtypeCustomize = "slam"
|
||||||
|
SWEP.HoldtypeNPC = nil
|
||||||
|
|
||||||
|
SWEP.AnimShoot = ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2
|
||||||
|
|
||||||
|
SWEP.CanBash = true
|
||||||
|
SWEP.PrimaryBash = false -- primary attack triggers melee attack
|
||||||
|
|
||||||
|
SWEP.MeleeDamage = 25
|
||||||
|
SWEP.MeleeRange = 16
|
||||||
|
SWEP.MeleeDamageType = DMG_CLUB
|
||||||
|
SWEP.MeleeTime = 0.5
|
||||||
|
SWEP.MeleeGesture = nil
|
||||||
|
SWEP.MeleeAttackTime = 0.2
|
||||||
|
|
||||||
|
SWEP.Melee2 = false
|
||||||
|
SWEP.Melee2Damage = 25
|
||||||
|
SWEP.Melee2Range = 16
|
||||||
|
SWEP.Melee2Time = 0.5
|
||||||
|
SWEP.Melee2Gesture = nil
|
||||||
|
SWEP.Melee2AttackTime = 0.2
|
||||||
|
|
||||||
|
SWEP.BashPreparePos = Vector(2.187, -4.117, -7.14)
|
||||||
|
SWEP.BashPrepareAng = Angle(32.182, -3.652, -19.039)
|
||||||
|
|
||||||
|
SWEP.BashPos = Vector(8.876, 0, 0)
|
||||||
|
SWEP.BashAng = Angle(-16.524, 70, -11.046)
|
||||||
|
|
||||||
|
SWEP.ActivePos = Vector(0, 0, 0)
|
||||||
|
SWEP.ActiveAng = Angle(0, 0, 0)
|
||||||
|
|
||||||
|
SWEP.CrouchPos = nil
|
||||||
|
SWEP.CrouchAng = nil
|
||||||
|
|
||||||
|
SWEP.HolsterPos = Vector(0.532, -6, 0)
|
||||||
|
SWEP.HolsterAng = Angle(-4.633, 36.881, 0)
|
||||||
|
|
||||||
|
SWEP.BarrelOffsetSighted = Vector(0, 0, 0)
|
||||||
|
SWEP.BarrelOffsetHip = Vector(3, 0, -3)
|
||||||
|
|
||||||
|
SWEP.CustomizePos = Vector(9.824, 0, -4.897)
|
||||||
|
SWEP.CustomizeAng = Angle(12.149, 30.547, 0)
|
||||||
|
|
||||||
|
SWEP.BarrelLength = 24
|
||||||
|
|
||||||
|
SWEP.Bipod_Integral = false
|
||||||
|
|
||||||
|
SWEP.SightPlusOffset = nil
|
||||||
|
|
||||||
|
SWEP.DefaultElements = {} -- {"ele1", "ele2"}
|
||||||
|
|
||||||
|
SWEP.AttachmentElements = {
|
||||||
|
-- ["name"] = {
|
||||||
|
-- RequireFlags = {}, -- same as attachments
|
||||||
|
-- ExcludeFlags = {},
|
||||||
|
-- NamePriority = 0, -- higher = more likely to be chosen
|
||||||
|
-- NameChange = "",
|
||||||
|
-- TrueNameChange = "",
|
||||||
|
-- AddPrefix = "",
|
||||||
|
-- AddSuffix = "",
|
||||||
|
-- VMColor = Color(),
|
||||||
|
-- VMMaterial = "",
|
||||||
|
-- VMBodygroups = {{ind = 1, bg = 1}},
|
||||||
|
-- VMElements = {
|
||||||
|
-- {
|
||||||
|
-- Model = "",
|
||||||
|
-- Bone = "",
|
||||||
|
-- Offset = {
|
||||||
|
-- pos = Vector(),
|
||||||
|
-- ang = Angle(),
|
||||||
|
-- },
|
||||||
|
-- ModelSkin = 0,
|
||||||
|
-- ModelBodygroups = "",
|
||||||
|
-- Scale = Vector(1, 1, 1),
|
||||||
|
-- IsMuzzleDevice = false -- this element is a muzzle device, and the muzzle flash should come from here.
|
||||||
|
-- }
|
||||||
|
-- },
|
||||||
|
-- VMOverride = "", -- change the view model to something else. Please make sure it's compatible with the last one.
|
||||||
|
-- VMBoneMods = {
|
||||||
|
-- ["bone"] = Vector(0, 0, 0)
|
||||||
|
-- },
|
||||||
|
-- WMColor = Color(),
|
||||||
|
-- WMMaterial = "",
|
||||||
|
-- WMBodygroups = {},
|
||||||
|
-- WMElements = {
|
||||||
|
-- {
|
||||||
|
-- Model = "",
|
||||||
|
-- Offset = {
|
||||||
|
-- pos = Vector(),
|
||||||
|
-- ang = Angle(),
|
||||||
|
-- },
|
||||||
|
-- IsMuzzleDevice = false -- this element is a muzzle device, and the muzzle flash should come from here.
|
||||||
|
-- }
|
||||||
|
-- },
|
||||||
|
-- WMOverride = "", -- change the world model to something else. Please make sure it's compatible with the last one.
|
||||||
|
-- WMBoneMods = {
|
||||||
|
-- ["bone"] = Vector(0, 0, 0)
|
||||||
|
-- },
|
||||||
|
-- AttPosMods = {
|
||||||
|
-- [1] = {
|
||||||
|
-- bone = "", -- optional
|
||||||
|
-- vpos = Vector(0, 0, 0),
|
||||||
|
-- vang = Angle(0, 0, 0),
|
||||||
|
-- wpos = Vector(0, 0, 0),
|
||||||
|
-- wang = Angle(0, 0, 0),
|
||||||
|
-- slide = { -- only if base att has slideable
|
||||||
|
-- vmin = Vector(0, 0, 0),
|
||||||
|
-- vmax = Vector(0, 0, 0),
|
||||||
|
-- wmin = Vector(0, 0, 0),
|
||||||
|
-- wmax = Vector(0, 0, 0)
|
||||||
|
-- }
|
||||||
|
-- }
|
||||||
|
-- }
|
||||||
|
-- }
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.RejectAttachments = {
|
||||||
|
-- ["optic_docter"] = true -- stop this attachment from being usable on this gun
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.AttachmentOverrides = {
|
||||||
|
-- ["optic_docter"] = {} -- allows you to overwrite atttbl values
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.Attachments = {}
|
||||||
|
-- [1] = {
|
||||||
|
-- PrintName = "Optic", -- print name
|
||||||
|
-- DefaultAttName = "Iron Sights", -- used to display the "no attachment" text
|
||||||
|
-- Slot = "pic_sight", -- what kind of attachments can fit here
|
||||||
|
-- MergeSlots = {}, -- these other slots will be merged into this one.
|
||||||
|
-- Bone = "sight", -- relevant bone any attachments will be mostly referring to
|
||||||
|
-- KeepBaseIrons = false,
|
||||||
|
-- ExtraSightDist = 0,
|
||||||
|
-- Offset = {
|
||||||
|
-- vpos = Vector(0, 0, 0), -- offset that the attachment will be relative to the bone
|
||||||
|
-- vang = Angle(0, 0, 0),
|
||||||
|
-- wpos = Vector(0, 0, 0), -- same, for the worldmodels
|
||||||
|
-- wang = Angle(0, 0, 0)
|
||||||
|
-- },
|
||||||
|
-- RejectAttachments = {}, -- specific blacklist of attachments this slot cannot accept. Needs to be like {"optic_mrs" = true}
|
||||||
|
-- VScale = Vector(1, 1, 1),
|
||||||
|
-- WScale = Vector(1, 1, 1),
|
||||||
|
-- LHIKOutTime = 0.5, -- how much time we should blend out any left hand IK for
|
||||||
|
-- LHIKInTime = 0.5, -- ditto
|
||||||
|
-- SlideAmount = { -- how far this attachment can slide in both directions.
|
||||||
|
-- -- overrides Offset.
|
||||||
|
-- vmin = Vector(0, 0, 0),
|
||||||
|
-- vmax = Vector(0, 0, 0),
|
||||||
|
-- wmin = Vector(0, 0, 0),
|
||||||
|
-- wmax = Vector(0, 0, 0),
|
||||||
|
-- },
|
||||||
|
-- CorrectiveAng = Vector(1, 1, 1), -- okay, I know I said sights were pain-free.
|
||||||
|
-- CorrectivePos = Vector(0, 0, 0), -- that won't always be the case. Use these to fix it. Issues mainly crop up in case of sights parented to bones that are not a root bone.
|
||||||
|
-- InstalledEles = {"toprail"}, -- activate these AttachmentElements if something is installed
|
||||||
|
-- Hidden = false, -- attachment cannot be seen in customize menu
|
||||||
|
-- Integral = false, -- attachment is assumed never to change
|
||||||
|
-- RandomChance = 1, -- multiplies chance this slot will get a random attachment
|
||||||
|
-- DoNotRandomize = false,
|
||||||
|
-- NoWM = false, -- do not make this show up on worldmodel
|
||||||
|
-- NoVM = false, -- what do *you* think this one does?
|
||||||
|
-- FreeSlot = false, -- slot does not count towards attachment capacity
|
||||||
|
-- -- ABOUT THE FLAG SYSTEM:
|
||||||
|
-- -- Attachments and slots can give flags
|
||||||
|
-- -- All attachments automatically give themselves as a flag, e.g. "optic_mrs"
|
||||||
|
-- -- If requirements are not satisfied, the slot or attachment will not be attachable
|
||||||
|
-- ExcludeFlags = {}, -- if the weapon has this flag, hide this slot
|
||||||
|
-- RequireFlags = {}, -- if the weapon does NOT have all these flags, hide this slot
|
||||||
|
-- GivesFlags = {} -- give these slots if something is installed here
|
||||||
|
-- }
|
||||||
|
|
||||||
|
-- ready: deploy first time
|
||||||
|
-- draw
|
||||||
|
-- holster
|
||||||
|
-- reload
|
||||||
|
-- fire
|
||||||
|
-- fire_empty
|
||||||
|
-- cycle (for bolt actions)
|
||||||
|
-- bash
|
||||||
|
-- enter_bipod
|
||||||
|
-- exit_bipod
|
||||||
|
-- enter_sight
|
||||||
|
-- exit_sight
|
||||||
|
-- a_to_b: switch from firemode a to firemode b. e.g.: 1_to_2
|
||||||
|
-- idle
|
||||||
|
-- idle_sights
|
||||||
|
-- idle_sprint
|
||||||
|
-- idle_bipod
|
||||||
|
-- enter_inspect
|
||||||
|
-- idle_inspect
|
||||||
|
-- exit_inspect
|
||||||
|
-- append _empty for empty variation
|
||||||
|
-- use SWEP.Hook_TranslateAnimation, same as in attachment, to do even more behaviours
|
||||||
|
|
||||||
|
SWEP.Animations = {
|
||||||
|
-- ["idle"] = {
|
||||||
|
-- Source = "idle",
|
||||||
|
-- Time = 10
|
||||||
|
-- },
|
||||||
|
-- ["draw"] = {
|
||||||
|
-- RestoreAmmo = 1, -- only used by shotgun reload
|
||||||
|
-- Source = "deploy",
|
||||||
|
-- RareSource = "", -- 1/100 chance of playing this animation instead
|
||||||
|
-- Time = 0.5,
|
||||||
|
-- TPAnim = ACT_HL2MP_GESTURE_RELOAD_AR2, -- third person animation to play when this animation is played
|
||||||
|
-- TPAnimStartTime = 0, -- when to start it from
|
||||||
|
-- Checkpoints = {}, -- time checkpoints. If weapon is unequipped, the animation will continue to play from these checkpoints when reequipped.
|
||||||
|
-- ShellEjectAt = 0, -- animation includes a shell eject at these times
|
||||||
|
-- LHIKIn = 0.25, -- left hand inverse kinematics. In/Out controls how long it takes to switch to regular animation.
|
||||||
|
-- LHIKOut = 0.25, -- (not actually inverse kinematics)
|
||||||
|
-- LHIK = true, -- basically disable foregrips on this anim
|
||||||
|
-- SoundTable = {
|
||||||
|
-- {
|
||||||
|
-- s = "", -- sound; can be string or table
|
||||||
|
-- p = 100, -- pitch
|
||||||
|
-- v = 75, -- volume
|
||||||
|
-- t = 1, -- time at which to play relative to Animations.Time
|
||||||
|
-- c = CHAN_ITEM -- channel to play the sound
|
||||||
|
-- }
|
||||||
|
-- },
|
||||||
|
-- ViewPunchTable = {
|
||||||
|
-- {
|
||||||
|
-- p = Vector(0, 0, 0),
|
||||||
|
-- t = 1
|
||||||
|
-- }
|
||||||
|
-- },
|
||||||
|
-- ProcDraw = false, -- for draw/deploy animations, always procedurally draw in addition to playing animation
|
||||||
|
-- ProcHolster = false -- procedural holster weapon, THEN play animation
|
||||||
|
-- LastClip1OutTime = 0 -- when should the belt visually replenish on a belt fed
|
||||||
|
-- }
|
||||||
|
}
|
||||||
|
|
||||||
|
-- don't change any of this stuff
|
||||||
|
|
||||||
|
SWEP.Primary.Automatic = true
|
||||||
|
SWEP.Primary.DefaultClip = 1
|
||||||
|
SWEP.Secondary.ClipSize = -1
|
||||||
|
SWEP.Secondary.DefaultClip = -1
|
||||||
|
SWEP.Secondary.Automatic = false
|
||||||
|
SWEP.Secondary.Ammo = "none"
|
||||||
|
SWEP.DrawCrosshair = true
|
||||||
|
|
||||||
|
SWEP.ArcCW = true
|
||||||
|
SWEP.BurstCount = 0
|
||||||
|
SWEP.AnimQueue = {}
|
||||||
|
SWEP.FiremodeIndex = 1
|
||||||
|
SWEP.UnReady = true
|
||||||
|
|
||||||
|
SWEP.ProneMod_DisableTransitions = true
|
||||||
|
|
||||||
|
SWEP.DrawWeaponInfoBox = false
|
||||||
|
SWEP.BounceWeaponIcon = false
|
||||||
|
|
||||||
|
if CLIENT or game.SinglePlayer() then
|
||||||
|
|
||||||
|
SWEP.RecoilAmount = 0
|
||||||
|
SWEP.RecoilAmountSide = 0
|
||||||
|
SWEP.RecoilPunchBack = 0
|
||||||
|
SWEP.RecoilPunchUp = 0
|
||||||
|
SWEP.RecoilPunchSide = 0
|
||||||
|
SWEP.HammerDown = false
|
||||||
|
|
||||||
|
SWEP.LHIKTimeline = nil
|
||||||
|
-- {number starttime, number intime, number outtime, number finishouttime}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if SERVER then
|
||||||
|
|
||||||
|
include("sv_npc.lua")
|
||||||
|
include("sv_shield.lua")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
include("sh_model.lua")
|
||||||
|
include("sh_timers.lua")
|
||||||
|
include("sh_think.lua")
|
||||||
|
include("sh_deploy.lua")
|
||||||
|
include("sh_anim.lua")
|
||||||
|
include("sh_firing.lua")
|
||||||
|
include("sh_reload.lua")
|
||||||
|
include("sh_attach.lua")
|
||||||
|
include("sh_sights.lua")
|
||||||
|
include("sh_firemodes.lua")
|
||||||
|
include("sh_customize.lua")
|
||||||
|
include("sh_ubgl.lua")
|
||||||
|
include("sh_rocket.lua")
|
||||||
|
include("sh_bash.lua")
|
||||||
|
include("sh_bipod.lua")
|
||||||
|
include("sh_grenade.lua")
|
||||||
|
AddCSLuaFile("sh_model.lua")
|
||||||
|
AddCSLuaFile("sh_timers.lua")
|
||||||
|
AddCSLuaFile("sh_think.lua")
|
||||||
|
AddCSLuaFile("sh_deploy.lua")
|
||||||
|
AddCSLuaFile("sh_anim.lua")
|
||||||
|
AddCSLuaFile("sh_firing.lua")
|
||||||
|
AddCSLuaFile("sh_reload.lua")
|
||||||
|
AddCSLuaFile("sh_attach.lua")
|
||||||
|
AddCSLuaFile("sh_sights.lua")
|
||||||
|
AddCSLuaFile("sh_firemodes.lua")
|
||||||
|
AddCSLuaFile("sh_customize.lua")
|
||||||
|
AddCSLuaFile("sh_ubgl.lua")
|
||||||
|
AddCSLuaFile("sh_rocket.lua")
|
||||||
|
AddCSLuaFile("sh_bash.lua")
|
||||||
|
AddCSLuaFile("sh_bipod.lua")
|
||||||
|
AddCSLuaFile("sh_grenade.lua")
|
||||||
|
|
||||||
|
AddCSLuaFile("cl_viewmodel.lua")
|
||||||
|
AddCSLuaFile("cl_scope.lua")
|
||||||
|
AddCSLuaFile("cl_crosshair.lua")
|
||||||
|
AddCSLuaFile("cl_hud.lua")
|
||||||
|
AddCSLuaFile("cl_holosight.lua")
|
||||||
|
AddCSLuaFile("cl_lhik.lua")
|
||||||
|
AddCSLuaFile("cl_laser.lua")
|
||||||
|
AddCSLuaFile("cl_blur.lua")
|
||||||
|
AddCSLuaFile("cl_presets.lua")
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
include("cl_viewmodel.lua")
|
||||||
|
include("cl_scope.lua")
|
||||||
|
include("cl_crosshair.lua")
|
||||||
|
include("cl_hud.lua")
|
||||||
|
include("cl_holosight.lua")
|
||||||
|
include("cl_lhik.lua")
|
||||||
|
include("cl_laser.lua")
|
||||||
|
include("cl_blur.lua")
|
||||||
|
include("cl_presets.lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:SetupDataTables()
|
||||||
|
self:NetworkVar("Int", 0, "State")
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:IsProne()
|
||||||
|
if PRONE_INPRONE then
|
||||||
|
return self:GetOwner():IsProne()
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:BarrelHitWall()
|
||||||
|
local offset = self.BarrelOffsetHip
|
||||||
|
|
||||||
|
if self:GetState() == ArcCW.STATE_SIGHTS then
|
||||||
|
offset = self.BarrelOffsetSighted
|
||||||
|
end
|
||||||
|
|
||||||
|
local dir = self:GetOwner():EyeAngles()
|
||||||
|
local src = self:GetOwner():EyePos()
|
||||||
|
|
||||||
|
src = src + dir:Right() * offset[1]
|
||||||
|
src = src + dir:Forward() * offset[2]
|
||||||
|
src = src + dir:Up() * offset[3]
|
||||||
|
|
||||||
|
local mask = MASK_SOLID
|
||||||
|
|
||||||
|
local tr = util.TraceLine({
|
||||||
|
start = src,
|
||||||
|
endpos = src + (dir:Forward() * (self.BarrelLength + self:GetBuff_Add("Add_BarrelLength"))),
|
||||||
|
filter = {self:GetOwner()},
|
||||||
|
mask = mask
|
||||||
|
})
|
||||||
|
|
||||||
|
if tr.Hit then
|
||||||
|
local l = (tr.HitPos - src):Length()
|
||||||
|
l = l
|
||||||
|
return 1 - math.Clamp(l / (self.BarrelLength + self:GetBuff_Add("Add_BarrelLength")), 0, 1)
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
306
lua/weapons/arccw_base/sv_npc.lua
Normal file
306
lua/weapons/arccw_base/sv_npc.lua
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
-- 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)
|
||||||
|
|
||||||
|
local range = self.Range
|
||||||
|
|
||||||
|
range = range / ArcCW.HUToM
|
||||||
|
|
||||||
|
range = range * 2
|
||||||
|
|
||||||
|
if self.DamageMin > self.Damage then
|
||||||
|
range = 15000
|
||||||
|
end
|
||||||
|
|
||||||
|
range = math.Clamp(range, 2048, 36000)
|
||||||
|
|
||||||
|
self:GetOwner():Input("SetMaxLookDistance", nil, nil, range)
|
||||||
|
|
||||||
|
self:SetNextPrimaryFire(CurTime())
|
||||||
|
self:GetOwner():NextThink(CurTime())
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:NPC_SetupAttachments()
|
||||||
|
if !GetConVar("arccw_npc_atts"):GetBool() then return end
|
||||||
|
|
||||||
|
local pick = GetConVar("arccw_atts_pickx"):GetInt()
|
||||||
|
|
||||||
|
local chance = 25
|
||||||
|
|
||||||
|
local chancestep = 0
|
||||||
|
|
||||||
|
if pick > 0 then
|
||||||
|
|
||||||
|
chancestep = chance / pick
|
||||||
|
chance = chancestep
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
pick = 1000
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local n = 0
|
||||||
|
|
||||||
|
for _, 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.DoNotRandomize then continue end
|
||||||
|
|
||||||
|
if slot.Installed then continue end
|
||||||
|
|
||||||
|
local atts = ArcCW:GetAttsForSlot(slot.Slot, self)
|
||||||
|
|
||||||
|
if #atts <= 0 then continue end
|
||||||
|
|
||||||
|
chance = chance + chancestep
|
||||||
|
|
||||||
|
slot.Installed = table.Random(atts)
|
||||||
|
|
||||||
|
local atttbl = ArcCW.AttachmentTable[slot.Installed]
|
||||||
|
|
||||||
|
if atttbl.MountPositionOverride then
|
||||||
|
slot.SlidePos = atttbl.MountPositionOverride
|
||||||
|
end
|
||||||
|
|
||||||
|
n = n + 1
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
self.Primary.Automatic = self:ShouldBeAutomatic()
|
||||||
|
|
||||||
|
|
||||||
|
local delay = (self.Delay * (1 / self:GetBuff_Mult("Mult_RPM")))
|
||||||
|
|
||||||
|
delay = self:GetBuff_Hook("Hook_ModifyRPM", delay) or delay
|
||||||
|
|
||||||
|
local num = self:GetBuff_Override("Override_Num")
|
||||||
|
|
||||||
|
if !num then
|
||||||
|
num = self.Num
|
||||||
|
end
|
||||||
|
|
||||||
|
num = num + self:GetBuff_Add("Add_Num")
|
||||||
|
|
||||||
|
local spread = ArcCW.MOAToAcc * self.AccuracyMOA * self:GetBuff_Mult("Mult_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)
|
||||||
|
local dist = (tr.HitPos - tr.StartPos):Length() * ArcCW.HUToM
|
||||||
|
|
||||||
|
local pen = self.Penetration * self:GetBuff_Mult("Mult_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) * 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:GetDamageType() == DMG_BURN and ret.range <= self.Range then
|
||||||
|
if num == 1 then
|
||||||
|
dmg:SetDamageType(DMG_BULLET)
|
||||||
|
else
|
||||||
|
dmg:SetDamageType(DMG_BUCKSHOT)
|
||||||
|
end
|
||||||
|
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
|
||||||
|
|
||||||
|
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:GetOwner():FireBullets(btabl)
|
||||||
|
end
|
||||||
|
elseif se then
|
||||||
|
self:FireRocket(se, self.MuzzleVelocity * ArcCW.HUToM * self:GetBuff_Mult("Mult_MuzzleVelocity"))
|
||||||
|
else
|
||||||
|
self:GetBuff_Hook("Hook_FireBullets", btabl)
|
||||||
|
self:FireBullets(btabl)
|
||||||
|
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.ShootVol * self:GetBuff_Mult("Mult_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:EmitSound(dss, 130, spitch, 0.5, CHAN_BODY)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ss then
|
||||||
|
self:EmitSound(ss, svol, spitch, 1, CHAN_WEAPON)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetClip1(self:Clip1() - 1)
|
||||||
|
|
||||||
|
self:SetNextPrimaryFire(CurTime() + delay)
|
||||||
|
if delay < 0.1 then
|
||||||
|
self:GetOwner():NextThink(CurTime() + delay)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetNPCBulletSpread(prof)
|
||||||
|
local mode = self:GetCurrentFiremode()
|
||||||
|
mode = mode.Mode
|
||||||
|
|
||||||
|
if mode < 0 then
|
||||||
|
return 15
|
||||||
|
elseif mode == 0 then
|
||||||
|
return 20
|
||||||
|
elseif mode == 1 then
|
||||||
|
if math.Rand(0, 100) < 25 then
|
||||||
|
return 5
|
||||||
|
else
|
||||||
|
return 50
|
||||||
|
end
|
||||||
|
elseif mode >= 2 then
|
||||||
|
return 20
|
||||||
|
end
|
||||||
|
|
||||||
|
return 15
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:GetNPCBurstSettings()
|
||||||
|
local mode = self:GetCurrentFiremode()
|
||||||
|
mode = mode.Mode
|
||||||
|
|
||||||
|
local delay = (self.Delay * (1 / self:GetBuff_Mult("Mult_RPM")))
|
||||||
|
|
||||||
|
delay = self:GetBuff_Hook("Hook_ModifyRPM", delay) or delay
|
||||||
|
|
||||||
|
self:SetNextPrimaryFire(CurTime() + delay)
|
||||||
|
|
||||||
|
if !mode then return 1, 1, delay end
|
||||||
|
|
||||||
|
if self.ManualAction or self:GetBuff_Override("Override_ManualAction") then
|
||||||
|
return 0, 1, delay + self:GetAnimTime("cycle")
|
||||||
|
end
|
||||||
|
|
||||||
|
if mode < 0 then
|
||||||
|
return -mode, -mode, delay
|
||||||
|
elseif mode == 0 then
|
||||||
|
return 0, 0, delay
|
||||||
|
elseif mode == 1 then
|
||||||
|
return 0, 1, delay + math.Rand(0.3, 0.6)
|
||||||
|
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 postburst = self:GetCurrentFiremode().PostBurstDelay or 0
|
||||||
|
local m = 1 * self:GetBuff_Mult("Mult_Recoil")
|
||||||
|
local rs = 1 * self:GetBuff_Mult("Mult_RecoilSide")
|
||||||
|
|
||||||
|
local o = 1
|
||||||
|
|
||||||
|
o = o + (m * rs * 0.5)
|
||||||
|
o = o + postburst
|
||||||
|
|
||||||
|
return 0.2 * o, 0.6 * o
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:CanBePickedUpByNPCs()
|
||||||
|
return !self.NotForNPCs
|
||||||
|
end
|
78
lua/weapons/arccw_base/sv_shield.lua
Normal file
78
lua/weapons/arccw_base/sv_shield.lua
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
SWEP.Shields = {}
|
||||||
|
|
||||||
|
function SWEP:SetupShields()
|
||||||
|
self:KillShields()
|
||||||
|
|
||||||
|
bonename = "ValveBiped.Bip01_R_Hand"
|
||||||
|
|
||||||
|
local boneindex = self:GetOwner():LookupBone(bonename)
|
||||||
|
|
||||||
|
if !boneindex then return end
|
||||||
|
|
||||||
|
local bpos, bang = self:GetOwner():GetBonePosition(boneindex)
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
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:SetModel( atttbl.Model )
|
||||||
|
shield:FollowBone( self:GetOwner(), self:GetOwner():LookupBone("ValveBiped.Bip01_R_Hand") )
|
||||||
|
shield:SetPos( apos )
|
||||||
|
shield:SetAngles( self.Owner:GetAngles() + ang + (atttbl.ShieldCorrectAng or Angle(0, 0, 0)) )
|
||||||
|
shield:SetCollisionGroup( COLLISION_GROUP_WORLD )
|
||||||
|
shield:SetColor( Color(0, 0, 0, 0) )
|
||||||
|
table.insert(self.Shields, shield)
|
||||||
|
shield:Spawn()
|
||||||
|
shield:Activate()
|
||||||
|
|
||||||
|
local phys = shield:GetPhysicsObject()
|
||||||
|
|
||||||
|
phys:SetMass(1000)
|
||||||
|
|
||||||
|
shield:SetRenderMode(RENDERMODE_NONE)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SWEP:KillShields()
|
||||||
|
for i, k in pairs(self.Shields) do
|
||||||
|
SafeRemoveEntity(k)
|
||||||
|
end
|
||||||
|
end
|
62
lua/weapons/arccw_base_melee/shared.lua
Normal file
62
lua/weapons/arccw_base_melee/shared.lua
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
SWEP.Base = "arccw_base"
|
||||||
|
|
||||||
|
SWEP.MeleeDamage = 25
|
||||||
|
SWEP.MeleeRange = 16
|
||||||
|
SWEP.MeleeDamageType = DMG_CLUB
|
||||||
|
SWEP.MeleeTime = 0.5
|
||||||
|
SWEP.MeleeGesture = nil
|
||||||
|
SWEP.MeleeAttackTime = 0.2
|
||||||
|
|
||||||
|
SWEP.Melee2 = false
|
||||||
|
SWEP.Melee2Damage = 25
|
||||||
|
SWEP.Melee2Range = 16
|
||||||
|
SWEP.Melee2Time = 0.5
|
||||||
|
SWEP.Melee2Gesture = nil
|
||||||
|
SWEP.Melee2AttackTime = 0.2
|
||||||
|
|
||||||
|
SWEP.NotForNPCs = true
|
||||||
|
|
||||||
|
SWEP.Firemodes = {
|
||||||
|
{
|
||||||
|
Mode = 1,
|
||||||
|
PrintName = "MELEE"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.HoldtypeHolstered = "normal"
|
||||||
|
SWEP.HoldtypeActive = "melee"
|
||||||
|
|
||||||
|
SWEP.Primary.ClipSize = -1
|
||||||
|
|
||||||
|
SWEP.Animations = {
|
||||||
|
-- ["draw"] = {
|
||||||
|
-- Source = "draw",
|
||||||
|
-- Time = 0.5,
|
||||||
|
-- },
|
||||||
|
-- ["ready"] = {
|
||||||
|
-- Source = "draw",
|
||||||
|
-- Time = 0.5,
|
||||||
|
-- },
|
||||||
|
-- ["bash"] = {
|
||||||
|
-- Source = {"stab", "midslash1", "midslash2", "stab_miss"},
|
||||||
|
-- Time = 0.5,
|
||||||
|
-- },
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.IronSightStruct = false
|
||||||
|
|
||||||
|
SWEP.BashPreparePos = Vector(0, 0, 0)
|
||||||
|
SWEP.BashPrepareAng = Angle(0, 0, 0)
|
||||||
|
|
||||||
|
SWEP.BashPos = Vector(0, 0, 0)
|
||||||
|
SWEP.BashAng = Angle(0, 0, 0)
|
||||||
|
|
||||||
|
SWEP.HolsterPos = Vector(0, -1, 0)
|
||||||
|
SWEP.HolsterAng = Angle(-10, 0, 0)
|
||||||
|
|
||||||
|
SWEP.ShootWhileSprint = true
|
||||||
|
|
||||||
|
SWEP.SpeedMult = 1
|
||||||
|
|
||||||
|
SWEP.Secondary.Automatic = true
|
||||||
|
|
65
lua/weapons/arccw_base_nade/shared.lua
Normal file
65
lua/weapons/arccw_base_nade/shared.lua
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
SWEP.Base = "arccw_base"
|
||||||
|
|
||||||
|
SWEP.Throwing = true
|
||||||
|
|
||||||
|
SWEP.NotForNPCs = true
|
||||||
|
|
||||||
|
SWEP.Firemodes = {
|
||||||
|
{
|
||||||
|
Mode = 1,
|
||||||
|
PrintName = "NADE"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.PullPinTime = 0.25
|
||||||
|
SWEP.FuseTime = 3.5
|
||||||
|
|
||||||
|
SWEP.HoldtypeHolstered = "normal"
|
||||||
|
SWEP.HoldtypeActive = "grenade"
|
||||||
|
|
||||||
|
SWEP.Primary.ClipSize = 1
|
||||||
|
SWEP.Primary.Ammo = "grenade"
|
||||||
|
|
||||||
|
SWEP.Animations = {
|
||||||
|
-- ["draw"] = {
|
||||||
|
-- Source = "draw",
|
||||||
|
-- Time = 0.5,
|
||||||
|
-- },
|
||||||
|
-- ["ready"] = {
|
||||||
|
-- Source = "draw",
|
||||||
|
-- Time = 0.5,
|
||||||
|
-- },
|
||||||
|
-- ["pre_throw"] = {
|
||||||
|
-- Source = "pullpin",
|
||||||
|
-- Time = 0.5,
|
||||||
|
-- },
|
||||||
|
-- ["throw"] = {
|
||||||
|
-- Source = "throw",
|
||||||
|
-- Time = 0.5
|
||||||
|
-- }
|
||||||
|
}
|
||||||
|
|
||||||
|
SWEP.BashPreparePos = Vector(2.187, -7.117, -1)
|
||||||
|
SWEP.BashPrepareAng = Angle(5, -3.652, -19.039)
|
||||||
|
|
||||||
|
SWEP.BashPos = Vector(8.876, 0, 0)
|
||||||
|
SWEP.BashAng = Angle(-16.524, 70, -11.046)
|
||||||
|
|
||||||
|
SWEP.HolsterPos = Vector(0.532, -1, 0)
|
||||||
|
SWEP.HolsterAng = Angle(-10, 0, 0)
|
||||||
|
|
||||||
|
SWEP.IronSightStruct = false
|
||||||
|
|
||||||
|
SWEP.MeleeSwingSound = "weapons/arccw/m249/m249_draw.wav"
|
||||||
|
SWEP.MeleeHitSound = "weapons/arccw/knife/knife_hitwall1.wav"
|
||||||
|
SWEP.MeleeHitNPCSound = "physics/body/body_medium_break2.wav"
|
||||||
|
|
||||||
|
SWEP.ShootWhileSprint = true
|
||||||
|
|
||||||
|
SWEP.SpeedMult = 1
|
||||||
|
|
||||||
|
SWEP.Secondary.Automatic = true
|
||||||
|
|
||||||
|
function SWEP:SecondaryAttack()
|
||||||
|
self:PrimaryAttack()
|
||||||
|
end
|
8
materials/arccw/laser.vmt
Normal file
8
materials/arccw/laser.vmt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
UnLitGeneric
|
||||||
|
{
|
||||||
|
"$basetexture" "arccw\laser"
|
||||||
|
"$additive" "1"
|
||||||
|
"$translucent" "1"
|
||||||
|
"$vertexcolor" "1"
|
||||||
|
"$vertexalpha" "1"
|
||||||
|
}
|
BIN
materials/arccw/laser.vtf
Normal file
BIN
materials/arccw/laser.vtf
Normal file
Binary file not shown.
7
materials/effects/fas_debris.vmt
Normal file
7
materials/effects/fas_debris.vmt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
"UnlitGeneric"
|
||||||
|
{
|
||||||
|
"$basetexture" "effects/fas_debris"
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" 1
|
||||||
|
"$translucent" 1
|
||||||
|
}
|
BIN
materials/effects/fas_debris.vtf
Normal file
BIN
materials/effects/fas_debris.vtf
Normal file
Binary file not shown.
9
materials/effects/fas_debris_add_b.vmt
Normal file
9
materials/effects/fas_debris_add_b.vmt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
"UnlitGeneric"
|
||||||
|
{
|
||||||
|
"$basetexture" "effects/fas_debris_add_b"
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" 1
|
||||||
|
"$translucent" 1
|
||||||
|
"$additive" 1
|
||||||
|
"$overbrightfactor" 5
|
||||||
|
}
|
BIN
materials/effects/fas_debris_add_b.vtf
Normal file
BIN
materials/effects/fas_debris_add_b.vtf
Normal file
Binary file not shown.
12
materials/effects/fas_dust_a.vmt
Normal file
12
materials/effects/fas_dust_a.vmt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"SpriteCard"
|
||||||
|
{
|
||||||
|
$basetexture "effects/fas_dust_a"
|
||||||
|
$SEQUENCE_BLEND_MODE 1 //2
|
||||||
|
$MAXLUMFRAMEBLEND1 0
|
||||||
|
$MAXLUMFRAMEBLEND2 1
|
||||||
|
$depthblend 1
|
||||||
|
$STARTFADESIZE .45
|
||||||
|
$ENDFADESIZE .575
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" 1
|
||||||
|
}
|
BIN
materials/effects/fas_dust_a.vtf
Normal file
BIN
materials/effects/fas_dust_a.vtf
Normal file
Binary file not shown.
14
materials/effects/fas_dust_a_near.vmt
Normal file
14
materials/effects/fas_dust_a_near.vmt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"SpriteCard"
|
||||||
|
{
|
||||||
|
$basetexture "effects/fas_dust_a"
|
||||||
|
$SEQUENCE_BLEND_MODE 1 //2
|
||||||
|
$MAXLUMFRAMEBLEND1 0
|
||||||
|
$MAXLUMFRAMEBLEND2 1
|
||||||
|
$depthblend 1
|
||||||
|
$STARTFADESIZE 3
|
||||||
|
$ENDFADESIZE 4.5
|
||||||
|
$MAXDISTANCE 800
|
||||||
|
$FARFADEINTERVAL 100
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" 1
|
||||||
|
}
|
12
materials/effects/fas_dust_b.vmt
Normal file
12
materials/effects/fas_dust_b.vmt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"SpriteCard"
|
||||||
|
{
|
||||||
|
$basetexture "effects/fas_dust_b"
|
||||||
|
$SEQUENCE_BLEND_MODE 1 //2
|
||||||
|
$MAXLUMFRAMEBLEND1 0
|
||||||
|
$MAXLUMFRAMEBLEND2 1
|
||||||
|
$depthblend 1
|
||||||
|
$STARTFADESIZE .45
|
||||||
|
$ENDFADESIZE .575
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" 1
|
||||||
|
}
|
BIN
materials/effects/fas_dust_b.vtf
Normal file
BIN
materials/effects/fas_dust_b.vtf
Normal file
Binary file not shown.
14
materials/effects/fas_dust_b_near.vmt
Normal file
14
materials/effects/fas_dust_b_near.vmt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"SpriteCard"
|
||||||
|
{
|
||||||
|
$basetexture "effects/fas_dust_b"
|
||||||
|
$SEQUENCE_BLEND_MODE 1 //2
|
||||||
|
$MAXLUMFRAMEBLEND1 0
|
||||||
|
$MAXLUMFRAMEBLEND2 1
|
||||||
|
$depthblend 1
|
||||||
|
$STARTFADESIZE .45
|
||||||
|
$ENDFADESIZE .575
|
||||||
|
$MAXDISTANCE 800
|
||||||
|
$FARFADEINTERVAL 100
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" 1
|
||||||
|
}
|
12
materials/effects/fas_dust_thick.vmt
Normal file
12
materials/effects/fas_dust_thick.vmt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"SpriteCard"
|
||||||
|
{
|
||||||
|
$basetexture "effects/fas_dust_thick"
|
||||||
|
$SEQUENCE_BLEND_MODE 1 //2
|
||||||
|
$MAXLUMFRAMEBLEND1 0
|
||||||
|
$MAXLUMFRAMEBLEND2 1
|
||||||
|
$depthblend 1
|
||||||
|
$STARTFADESIZE 3
|
||||||
|
$ENDFADESIZE 4.5
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" 1
|
||||||
|
}
|
BIN
materials/effects/fas_dust_thick.vtf
Normal file
BIN
materials/effects/fas_dust_thick.vtf
Normal file
Binary file not shown.
7
materials/effects/fas_flamering.vmt
Normal file
7
materials/effects/fas_flamering.vmt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
"UnlitGeneric"
|
||||||
|
{
|
||||||
|
"$basetexture" "effects/fas_flamering"
|
||||||
|
"$additive" "1"
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" "1"
|
||||||
|
}
|
BIN
materials/effects/fas_flamering.vtf
Normal file
BIN
materials/effects/fas_flamering.vtf
Normal file
Binary file not shown.
7
materials/effects/fas_glow_debris.vmt
Normal file
7
materials/effects/fas_glow_debris.vmt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
"UnlitGeneric"
|
||||||
|
{
|
||||||
|
"$basetexture" "effects/fas_glow_debris"
|
||||||
|
"$additive" "1"
|
||||||
|
"$vertexcolor" 1
|
||||||
|
"$vertexalpha" "1"
|
||||||
|
}
|
BIN
materials/effects/fas_glow_debris.vtf
Normal file
BIN
materials/effects/fas_glow_debris.vtf
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user