Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cheaper gibs/debris when FPS is low. #453

Merged
merged 4 commits into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lua/acf/core/globals.lua
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ elseif CLIENT then
CreateClientConVar("acf_legalhints", 1, true, true, "If enabled, ACF will throw a warning hint whenever an entity gets disabled.", 0, 1)
CreateClientConVar("acf_legalshame", 0, true, true, "If enabled, you will get a message in console from the server if someone else has an ACF entity get disabled, but only when the server has that logging enabled.", 0, 1)
CreateClientConVar("acf_debris", 1, true, false, "Toggles ACF Debris.", 0, 1)
CreateClientConVar("acf_debris_autolod", 1, true, false, "Automatically disables some effects on debris if FPS is low.", 0, 1)
CreateClientConVar("acf_debris_collision", 0, true, false, "Toggles debris collisions with other entities.", 0, 1)
CreateClientConVar("acf_debris_gibmultiplier", 1, true, false, "The amount of gibs spawned when created by ACF debris.", 0, 1)
CreateClientConVar("acf_debris_giblifetime", 60, true, false, "Defines lifetime in seconds of each debris gib.", 1, 300)
Expand Down
96 changes: 80 additions & 16 deletions lua/acf/damage/debris_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@ local ACF = ACF

local Effects = ACF.Utilities.Effects
local AllowDebris = GetConVar("acf_debris")
local AutoLod = GetConVar("acf_debris_autolod")
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 math = math

local AutoLod_TerribleFps = 15
local AutoLod_ReallyBadFps = 25
local AutoLod_LowFps = 35
local AutoLod_OkayFps = 40
local AutoLod_GoodFps = 45

local function Particle(Entity, Effect)
return CreateParticleSystem(Entity, Effect, PATTACH_ABSORIGIN_FOLLOW)
end
Expand Down Expand Up @@ -56,33 +65,61 @@ local function Ignite(Entity, Lifetime, IsGib)
end
end

local function CreateDebris(Model, Position, Angles, Material, Color, Normal, Power, ShouldIgnite)
local function CreateDebris(Model, Position, Angles, Material, Color, Normal, Power, ShouldIgnite, AutoLOD)
-- TODO: This fixes a crashing bug, but the underlying issue that Model can sometimes be blank ("") isn't fixed yet
if not util.IsValidModel(Model) then return end

local Lifetime = DebrisLife:GetFloat() * math.Rand(0.5, 1)
local CollideAll = CollideAll:GetBool()
local DoParticles = true
local AllowIgnite = ShouldIgnite
local AllowSmoke = true

if AutoLOD then
local FPS = 1 / RealFrameTime()
if FPS < AutoLod_ReallyBadFps then
if FPS < math.random(0, AutoLod_TerribleFps) then return end -- their game is basically crashing, dont add to the problem
DoParticles = false
CollideAll = false
Lifetime = Lifetime * math.Rand(0.01, 0.1)
elseif FPS < AutoLod_LowFps then
AllowIgnite = AllowIgnite and math.random(0, 100) < 15
AllowSmoke = math.random(0, 100) < 25
CollideAll = false
Lifetime = Lifetime * math.Rand(0.1, 0.25)
elseif FPS < AutoLod_OkayFps then
AllowIgnite = AllowIgnite and math.random(0, 100) < 25
AllowSmoke = math.random(0, 100) < 50
CollideAll = CollideAll and math.random(0, 100) < 50
Lifetime = Lifetime * math.Rand(0.25, 0.5)
elseif FPS <= AutoLod_GoodFps then
Lifetime = Lifetime * 0.5
end
end

local Debris = ents.CreateClientProp(Model)

if not IsValid(Debris) then return end

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

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

if not CollideAll:GetBool() then
if CollideAll then
marchc1 marked this conversation as resolved.
Show resolved Hide resolved
Debris:SetCollisionGroup(COLLISION_GROUP_WORLD)
end

Debris:Spawn()

Debris.EmberParticle = Particle(Debris, "embers_medium_01")
if DoParticles then
Debris.EmberParticle = Particle(Debris, "embers_medium_01")

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

local PhysObj = Debris:GetPhysicsObject()
Expand All @@ -98,12 +135,31 @@ local function CreateDebris(Model, Position, Angles, Material, Color, Normal, Po
return Debris
end

local function CreateGib(Position, Angles, Material, Color, Normal, Power, Min, Max)
local function CreateGib(Position, Angles, Material, Color, Normal, Power, Min, Max, AutoLOD)
local DoParticles = true
local AllowIgnite = true
local Lifetime = GibLife:GetFloat() * math.Rand(0.5, 1)
if AutoLOD then
local FPS = 1 / RealFrameTime()
if FPS < AutoLod_ReallyBadFps then
if FPS < math.random(0, AutoLod_ReallyBadFps) then return end
DoParticles = false
Lifetime = Lifetime * math.Rand(0.01, 0.1)
elseif FPS < AutoLod_LowFps then
DoParticles = math.random(0, 100) < 50
AllowIgnite = math.random(0, 100) < 15
Lifetime = Lifetime * math.Rand(0.1, 0.25)
elseif FPS < AutoLod_OkayFps then
AllowIgnite = math.random(0, 100) < 50
Lifetime = Lifetime * math.Rand(0.25, 0.5)
elseif FPS <= AutoLod_GoodFps then
Lifetime = Lifetime * 0.5
end
end
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(Angles)
Expand All @@ -115,10 +171,12 @@ local function CreateGib(Position, Angles, Material, Color, Normal, Power, Min,
Gib:SetColor(Color)
Gib:Spawn()

Gib.SmokeParticle = Particle(Gib, "smoke_gib_01")
if DoParticles then
Gib.SmokeParticle = Particle(Gib, "smoke_gib_01")

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

local PhysObj = Gib:GetPhysicsObject()
Expand All @@ -138,7 +196,9 @@ function ACF.CreateDebris(Model, Position, Angles, Material, Color, Normal, Powe
if not AllowDebris:GetBool() then return end
if not Model then return end

local Debris = CreateDebris(Model, Position, Angles, Material, Color, Normal, Power, CanGib, Ignite)
local AutoLOD = AutoLod:GetBool()

local Debris = CreateDebris(Model, Position, Angles, Material, Color, Normal, Power, CanGib, Ignite, AutoLOD)

if IsValid(Debris) then
local Multiplier = GibMult:GetFloat()
Expand All @@ -148,9 +208,13 @@ function ACF.CreateDebris(Model, Position, Angles, Material, Color, Normal, Powe

if CanGib and Multiplier > 0 then
local GibCount = math.Clamp(Radius * 0.1, 1, math.max(10 * Multiplier, 1))
if AutoLOD then
local FPS = 1 / RealFrameTime()
GibCount = math.Clamp(GibCount, 0, FPS * 0.5)
end

for _ = 1, GibCount do
if not CreateGib(Position, Angles, Material, Color, Normal, Power, Min, Max) then
if not CreateGib(Position, Angles, Material, Color, Normal, Power, Min, Max, AutoLOD) then
break
end
end
Expand Down
3 changes: 3 additions & 0 deletions lua/acf/menu/items_cl/settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ do -- Clientside settings
local Debris = Base:AddCheckBox("#acf.menu.settings.debris.clientside")
Debris:SetConVar("acf_debris")

local AutoLod = Base:AddCheckBox("#acf.menu.settings.debris.autolod")
AutoLod:SetConVar("acf_debris_autolod")

local Collisions = Base:AddCheckBox("#acf.menu.settings.debris.collision")
Collisions:SetConVar("acf_debris_collision")

Expand Down
2 changes: 2 additions & 0 deletions resource/localization/en/acf_menu_settings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ acf.menu.settings.debris=Debris

acf.menu.settings.debris.clientside=Allow creation of clientside debris.

acf.menu.settings.debris.autolod=Cheaper debris when FPS is low.

acf.menu.settings.debris.collision=Allow debris to collide with entities.
acf.menu.settings.debris.collision_desc=Disabling this can prevent certain types of spam-induced lag and crashes.

Expand Down
Loading