Skip to content

Commit

Permalink
Merge pull request #427 from marchc1/debris-optimization
Browse files Browse the repository at this point in the history
Optimize debris networking
  • Loading branch information
thecraftianman authored Sep 4, 2024
2 parents 88660cd + 39a4b9d commit 7cfe88f
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 185 deletions.
176 changes: 1 addition & 175 deletions lua/acf/damage/damage_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -95,178 +95,4 @@ do
end
end
end)
end

do -- Debris Effects ------------------------
local Effects = ACF.Utilities.Effects
local AllowDebris = GetConVar("acf_debris")
local CollideAll = GetConVar("acf_debris_collision")
local DebrisLife = GetConVar("acf_debris_lifetime")
local GibMult = GetConVar("acf_debris_gibmultiplier")
local GibLife = GetConVar("acf_debris_giblifetime")
local GibModel = "models/gibs/metal_gib%s.mdl"

local function Particle(Entity, Effect)
return CreateParticleSystem(Entity, Effect, PATTACH_ABSORIGIN_FOLLOW)
end

local function FadeAway(Entity)
if not IsValid(Entity) then return end

local Smoke = Entity.SmokeParticle
local Ember = Entity.EmberParticle

Entity:SetRenderMode(RENDERMODE_TRANSCOLOR)
Entity:SetRenderFX(kRenderFxFadeSlow) -- NOTE: Not synced to CurTime()
Entity:CallOnRemove("ACF_Debris_Fade", function()
Entity:StopAndDestroyParticles()
end)

if IsValid(Smoke) then Smoke:StopEmission() end
if IsValid(Ember) then Ember:StopEmission() end

timer.Simple(5, function()
if not IsValid(Entity) then return end

Entity:Remove()
end)
end

local function Ignite(Entity, Lifetime, IsGib)
if IsGib then
Particle(Entity, "burning_gib_01")

timer.Simple(Lifetime * 0.2, function()
if not IsValid(Entity) then return end

Entity:StopParticlesNamed("burning_gib_01")
end)
else
Entity.SmokeParticle = Particle(Entity, "smoke_small_01b")

Particle(Entity, "env_fire_small_smoke")

timer.Simple(Lifetime * 0.4, function()
if not IsValid(Entity) then return end

Entity:StopParticlesNamed("env_fire_small_smoke")
end)
end
end

local function CreateDebris(Data)
local Debris = ents.CreateClientProp(Data.Model)

if not IsValid(Debris) then return end

local Lifetime = DebrisLife:GetFloat() * math.Rand(0.5, 1)

Debris:SetPos(Data.Position)
Debris:SetAngles(Data.Angles)
Debris:SetColor(Data.Color)
Debris:SetMaterial(Data.Material)

if not CollideAll:GetBool() then
Debris:SetCollisionGroup(COLLISION_GROUP_WORLD)
end

Debris:Spawn()

Debris.EmberParticle = Particle(Debris, "embers_medium_01")

if Data.Ignite and math.Rand(0, 0.5) < ACF.DebrisIgniteChance then
Ignite(Debris, Lifetime)
else
Debris.SmokeParticle = Particle(Debris, "smoke_exhaust_01a")
end

local PhysObj = Debris:GetPhysicsObject()

if IsValid(PhysObj) then
PhysObj:ApplyForceOffset(Data.Normal * Data.Power, Data.Position + VectorRand() * 20)
end

timer.Simple(Lifetime, function()
FadeAway(Debris)
end)

return Debris
end

local function CreateGib(Data, Min, Max)
local Gib = ents.CreateClientProp(GibModel:format(math.random(1, 5)))

if not IsValid(Gib) then return end

local Lifetime = GibLife:GetFloat() * math.Rand(0.5, 1)
local Offset = ACF.RandomVector(Min, Max)

Offset:Rotate(Data.Angles)

Gib:SetPos(Data.Position + Offset)
Gib:SetAngles(AngleRand(-180, 180))
Gib:SetModelScale(math.Rand(0.5, 2))
Gib:SetMaterial(Data.Material)
Gib:SetColor(Data.Color)
Gib:Spawn()

Gib.SmokeParticle = Particle(Gib, "smoke_gib_01")

if math.random() < ACF.DebrisIgniteChance then
Ignite(Gib, Lifetime, true)
end

local PhysObj = Gib:GetPhysicsObject()

if IsValid(PhysObj) then
PhysObj:ApplyForceOffset(Data.Normal * Data.Power, Gib:GetPos() + VectorRand() * 20)
end

timer.Simple(Lifetime, function()
FadeAway(Gib)
end)

return true
end

net.Receive("ACF_Debris", function()
local Data = util.JSONToTable(net.ReadString())

if not AllowDebris:GetBool() then return end

local Debris = CreateDebris(Data)

if IsValid(Debris) then
local Multiplier = GibMult:GetFloat()
local Radius = Debris:BoundingRadius()
local Min = Debris:OBBMins()
local Max = Debris:OBBMaxs()

if Data.CanGib and Multiplier > 0 then
local GibCount = math.Clamp(Radius * 0.1, 1, math.max(10 * Multiplier, 1))

for _ = 1, GibCount do
if not CreateGib(Data, Min, Max) then
break
end
end
end
end

local EffectTable = {
Origin = Data.Position, -- TODO: Change this to the hit vector, but we need to redefine HitVec as HitNorm
Scale = 20,
}

Effects.CreateEffect("cball_explode", EffectTable)
end)

game.AddParticles("particles/fire_01.pcf")

PrecacheParticleSystem("burning_gib_01")
PrecacheParticleSystem("env_fire_small_smoke")
PrecacheParticleSystem("smoke_gib_01")
PrecacheParticleSystem("smoke_exhaust_01a")
PrecacheParticleSystem("smoke_small_01b")
PrecacheParticleSystem("embers_medium_01")
end -----------------------------------------
end
Loading

0 comments on commit 7cfe88f

Please sign in to comment.