mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
223
lua/arccw/server/sv_npc.lua
Normal file
223
lua/arccw/server/sv_npc.lua
Normal file
@@ -0,0 +1,223 @@
|
||||
--[[
|
||||
| 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)
|
||||
Reference in New Issue
Block a user