mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
223 lines
7.4 KiB
Lua
223 lines
7.4 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
if CLIENT then return end
|
|
|
|
ArcCW.RandomWeaponCache = {}
|
|
|
|
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)
|
|
|
|
if wpn and wpn.AdminOnly and !ply:IsPlayer() then return end
|
|
if !ArcCW:WithinYearLimit(wpn) then
|
|
return
|
|
end
|
|
|
|
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 = ArcCW.RandomWeaponCache[wpn] and ArcCW.RandomWeaponCache[wpn][2]
|
|
local wgt = ArcCW.RandomWeaponCache[wpn] and ArcCW.RandomWeaponCache[wpn][1] or 0
|
|
|
|
if !tbl then
|
|
tbl = {}
|
|
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 !nades and k.NotForNPCs then continue end -- what does nades do???
|
|
if k.AutoSpawnable == false then continue end
|
|
|
|
if !ArcCW:WithinYearLimit(k) then
|
|
continue
|
|
end
|
|
|
|
local weight = k.NPCWeight or 0
|
|
if engine.ActiveGamemode() == "terrortown" and k.TTTWeight then
|
|
weight = k.TTTWeight
|
|
end
|
|
|
|
if wpn and engine.ActiveGamemode() == "terrortown" and k.TTTWeaponType then -- TTT weapon type(s) take priority over NPC weapon types
|
|
if isstring(k.TTTWeaponType) then
|
|
if k.TTTWeaponType != wpn then continue end
|
|
elseif istable(k.TTTWeaponType) then
|
|
if !table.HasValue(k.TTTWeaponType, wpn) then continue end
|
|
end
|
|
elseif wpn and k.NPCWeaponType then
|
|
local class = wpn
|
|
if engine.ActiveGamemode() == "terrortown" and ArcCW.TTTReplaceTable[wpn] then
|
|
class = ArcCW.TTTReplaceTable[wpn]
|
|
end
|
|
if isstring(k.NPCWeaponType) then
|
|
if k.NPCWeaponType != class then continue end
|
|
elseif istable(k.NPCWeaponType) then
|
|
if !table.HasValue(k.NPCWeaponType, class) then continue end
|
|
end
|
|
else
|
|
local og = weapons.Get(wpn)
|
|
|
|
if og and og.ArcCW then continue end
|
|
weight = 0 -- Don't spawn if there is none of either
|
|
end
|
|
|
|
if weight > 0 then
|
|
-- Don't insert 0 weight, otherwise they still spawn
|
|
wgt = wgt + weight
|
|
table.insert(tbl, {k.ClassName, wgt})
|
|
end
|
|
end
|
|
|
|
ArcCW.RandomWeaponCache[wpn] = {wgt, tbl}
|
|
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 ent:IsNPC() and ArcCW.ConVars["npc_replace"]:GetBool() then
|
|
timer.Simple(0, function()
|
|
if !ent:IsValid() 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
|
|
|
|
wpn = ArcCW:GetRandomWeapon(class)
|
|
|
|
if wpn then
|
|
ent:Give(wpn)
|
|
end
|
|
end)
|
|
elseif ent:IsWeapon() and ((engine.ActiveGamemode() == "terrortown" and ArcCW.ConVars["ttt_replace"]:GetBool()) or (engine.ActiveGamemode() != "terrortown" and ArcCW.ConVars["npc_replace"]:GetBool())) then
|
|
timer.Simple(0, function()
|
|
if !ent:IsValid() then return end
|
|
if IsValid(ent:GetOwner()) then return end
|
|
if ent.ArcCW 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
|
|
end)
|
|
|
|
-- This hook steals attachments from dropped weapons when a player walks over.
|
|
-- Disabled cause this is called CONSTANTLY when player is over a weapon, causing massive network lag.
|
|
-- Also it's just weird and hard to understand.
|
|
-- hook.Add("PlayerCanPickupWeapon", "ArcCW_PlayerCanPickupWeapon", function(ply, wep)
|
|
-- if !wep.ArcCW then return end
|
|
-- if !ply:HasWeapon(wep:GetClass()) then return end
|
|
|
|
-- if wep.Singleton then return false end
|
|
|
|
-- if !ArcCW.EnableCustomization or ArcCW.ConVars["enable_customization"]:GetInt() < 0 or ArcCW.ConVars["attinv_free"]:GetBool() 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)
|
|
end
|
|
end
|
|
-- Has to be sent to client or desync will happen
|
|
ArcCW:PlayerSendAttInv(ply)
|
|
end
|
|
end)
|
|
|
|
hook.Add("PlayerGiveSWEP", "ArcCW_SpawnRandomAttachments", function(ply, class, tbl)
|
|
if weapons.IsBasedOn(class, "arccw_base") and ArcCW.ConVars["atts_spawnrand"]:GetBool() then
|
|
-- We can't get the weapon entity here - it's spawned after the hook call.
|
|
-- Mark the player to disable autosave tempoarily if we're spawning random attachments.
|
|
ply.ArcCW_Sandbox_RandomAtts = true
|
|
timer.Simple(0.0001, function()
|
|
local wpn = ply:GetWeapon(class)
|
|
if IsValid(ply) and IsValid(wpn) then
|
|
wpn:NPC_SetupAttachments()
|
|
|
|
if ply.ArcCW_Sandbox_FirstSpawn then
|
|
wpn:RestoreAmmo()
|
|
ply.ArcCW_Sandbox_FirstSpawn = nil
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
end)
|
|
|
|
hook.Add("PlayerSpawnedSWEP", "ArcCW_SpawnRandomAttachments", function(ply, wep)
|
|
if wep.ArcCW and ArcCW.ConVars["atts_spawnrand"]:GetBool() then
|
|
wep:NPC_SetupAttachments()
|
|
end
|
|
end) |