Initial commit

This commit is contained in:
Haodong Mo 2020-06-25 12:24:08 +10:00
commit 724dde6df3
249 changed files with 12642 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

View 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

View 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

View 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)

View 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)

View 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
View 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,
-- } )

View 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

View 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)

View 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)

View 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
*/

View 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)

View 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
View 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)

View 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

View 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 )

View 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

View 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/"

View 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

View 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)

View 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.")

View 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" )

View 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)

View 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)

View File

@ -0,0 +1 @@
ArcCW.PhysBullets = {}

View 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

View 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)

View 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

View 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

View 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

View 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

View 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
View 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

View 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"

View 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"

View 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"

View 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"

View 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"

View 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"

View 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"

View 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"

View 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"

View 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

View 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

View 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"

View 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"

View 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

View 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"

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -0,0 +1,8 @@
UnLitGeneric
{
"$basetexture" "arccw\laser"
"$additive" "1"
"$translucent" "1"
"$vertexcolor" "1"
"$vertexalpha" "1"
}

BIN
materials/arccw/laser.vtf Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
"UnlitGeneric"
{
"$basetexture" "effects/fas_debris"
"$vertexcolor" 1
"$vertexalpha" 1
"$translucent" 1
}

Binary file not shown.

View File

@ -0,0 +1,9 @@
"UnlitGeneric"
{
"$basetexture" "effects/fas_debris_add_b"
"$vertexcolor" 1
"$vertexalpha" 1
"$translucent" 1
"$additive" 1
"$overbrightfactor" 5
}

Binary file not shown.

View 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
}

Binary file not shown.

View 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
}

View 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
}

Binary file not shown.

View 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
}

View 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
}

Binary file not shown.

View File

@ -0,0 +1,7 @@
"UnlitGeneric"
{
"$basetexture" "effects/fas_flamering"
"$additive" "1"
"$vertexcolor" 1
"$vertexalpha" "1"
}

Binary file not shown.

View File

@ -0,0 +1,7 @@
"UnlitGeneric"
{
"$basetexture" "effects/fas_glow_debris"
"$additive" "1"
"$vertexcolor" 1
"$vertexalpha" "1"
}

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More