Skip to content

Commit

Permalink
Add Effects.CreateEffect
Browse files Browse the repository at this point in the history
For the moment, this only serves as a wrapper for util.Effect, but it should be possible to expand upon this in the future for more advanced effects. Also includes the hook ACF_PreCreateEffect in order to allow for effect overrides as requested in #321
  • Loading branch information
thecraftianman committed Aug 29, 2024
1 parent 977a944 commit 28916bc
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 157 deletions.
32 changes: 12 additions & 20 deletions lua/acf/ballistics/ballistics_sv.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local ACF = ACF
local Ballistics = ACF.Ballistics
local Damage = ACF.Damage
local Clock = ACF.Utilities.Clock
local Effects = ACF.Utilities.Effects
local Debug = ACF.Debug

Ballistics.Bullets = Ballistics.Bullets or {}
Expand All @@ -23,26 +24,17 @@ local HookRun = hook.Run
function Ballistics.BulletClient(Bullet, Type, Hit, HitPos)
if Bullet.NoEffect then return end -- No clientside effect will be created for this bullet

local Effect = EffectData()
Effect:SetDamageType(Bullet.Index)
Effect:SetStart(Bullet.Flight * 0.1)
Effect:SetAttachment(Bullet.Hide and 0 or 1)

if Type == "Update" then
if Hit > 0 then
Effect:SetOrigin(HitPos)
else
Effect:SetOrigin(Bullet.Pos)
end

Effect:SetScale(Hit)
else
Effect:SetOrigin(Bullet.Pos)
Effect:SetEntIndex(Bullet.Crate)
Effect:SetScale(0)
end

util.Effect("ACF_Bullet_Effect", Effect, true, true)
local IsUpdate = Type == "Update"
local EffectTable = {
DamageType = Bullet.Index,
Start = Bullet.Flight * 0.1,
Attachment = Bullet.Hide and 0 or 1,
Origin = (IsUpdate and Hit > 0) and HitPos or Bullet.Pos,
Scale = IsUpdate and Hit or 0,
EntIndex = not IsUpdate and Bullet.Crate or nil,
}

Effects.CreateEffect("ACF_Bullet_Effect", EffectTable, true, true)
end

function Ballistics.RemoveBullet(Bullet)
Expand Down
7 changes: 4 additions & 3 deletions lua/acf/core/utilities/effects/effects_cl.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
local ACF = ACF
local Refills = {}

ACF.Utilities.Effects.Refills = Refills
local Effects = ACF.Utilities.Effects

do -- Resupply effect (applies to ammo and fuel)
local render = render
local Distance = ACF.RefillDistance

local Refills = {}
Effects.Refills = Refills

local function DrawSpheres(bDrawingDepth, _, isDraw3DSkybox)
if bDrawingDepth or isDraw3DSkybox then return end
render.SetColorMaterial()
Expand Down
29 changes: 29 additions & 0 deletions lua/acf/core/utilities/effects/effects_sh.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
local ACF = ACF
local Effects = ACF.Utilities.Effects

do
--- Creates effects based on util.Effect with ACF-specific functionality.
--- @param EffectName string The name of the effect to create
--- @param EffectTable table The table containing all of the parameters for the effect (case-sensitive)
--- @param AllowOverride? boolean Whether Lua-defined effects should override engine-defined effects
--- @param Filter? any Can be either a boolean to ignore the prediction filter or a CRecipientFilter
function Effects.CreateEffect(EffectName, EffectTable, AllowOverride, Filter)
if not EffectName or not EffectTable then return end

local Effect = EffectData()

local NewName, NewTable = hook.Run("ACF_PreCreateEffect", EffectName, EffectTable)
EffectName = NewName or EffectName
EffectTable = NewTable or EffectTable

-- Set values for all possible valid CEffectData attributes present in EffectTable
for Name, Value in pairs(EffectTable) do
local EffectFunc = Effect["Set" .. Name]
if not EffectFunc then continue end

EffectFunc(Effect, Value)
end

util.Effect(EffectName, Effect, AllowOverride, Filter)
end
end
11 changes: 7 additions & 4 deletions lua/acf/damage/damage_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ do
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")
Expand Down Expand Up @@ -252,10 +253,12 @@ do -- Debris Effects ------------------------
end
end

local Effect = EffectData()
Effect:SetOrigin(Data.Position) -- TODO: Change this to the hit vector, but we need to redefine HitVec as HitNorm
Effect:SetScale(20)
util.Effect("cball_explode", Effect)
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")
Expand Down
21 changes: 11 additions & 10 deletions lua/acf/damage/explosion_sh.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
local math = math
local util = util
local ACF = ACF
local Damage = ACF.Damage
local Down = Vector(0, 0, -1)
local math = math
local ACF = ACF
local Damage = ACF.Damage
local Effects = ACF.Utilities.Effects
local Down = Vector(0, 0, -1)

--- Returns the blast radius based on a given amount of filler mass
-- Note: Scaling law found on the net, based on 1PSI overpressure from 1 kg of TNT at 15m
Expand All @@ -21,10 +21,11 @@ end
function Damage.explosionEffect(Position, Direction, Filler)
local Radius = math.max(1, Damage.getBlastRadius(Filler))

local Effect = EffectData()
Effect:SetOrigin(Position)
Effect:SetNormal(Direction or Down)
Effect:SetScale(Radius)
local EffectTable = {
Origin = Position,
Normal = Direction or Down,
Scale = Radius,
}

util.Effect("ACF_Explosion", Effect)
Effects.CreateEffect("ACF_Explosion", EffectTable)
end
55 changes: 30 additions & 25 deletions lua/acf/entities/ammo_types/ap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ if SERVER then
Ballistics.RemoveBullet(Bullet)
end
else
local Effects = ACF.Utilities.Effects

ACF.RegisterAmmoDecal("AP", "damage/ap_pen", "damage/ap_rico")

local DecalIndex = ACF.GetAmmoDecalIndex
Expand Down Expand Up @@ -201,37 +203,40 @@ else
end

function Ammo:ImpactEffect(_, Bullet)
local Effect = EffectData()
Effect:SetOrigin(Bullet.SimPos)
Effect:SetNormal(Bullet.SimFlight:GetNormalized())
Effect:SetRadius(Bullet.Caliber)
Effect:SetDamageType(DecalIndex(Bullet.AmmoType))

util.Effect("ACF_Impact", Effect)
local EffectTable = {
Origin = Bullet.SimPos,
Normal = Bullet.SimFlight:GetNormalized(),
Radius = Bullet.Caliber,
DamageType = DecalIndex(Bullet.AmmoType),
}

Effects.CreateEffect("ACF_Impact", EffectTable)
end

function Ammo:PenetrationEffect(_, Bullet)
local Effect = EffectData()
Effect:SetOrigin(Bullet.SimPos)
Effect:SetNormal(Bullet.SimFlight:GetNormalized())
Effect:SetScale(Bullet.SimFlight:Length())
Effect:SetMagnitude(Bullet.RoundMass)
Effect:SetRadius(Bullet.Caliber)
Effect:SetDamageType(DecalIndex(Bullet.AmmoType))

util.Effect("ACF_Penetration", Effect)
local EffectTable = {
Origin = Bullet.SimPos,
Normal = Bullet.SimFlight:GetNormalized(),
Scale = Bullet.SimFlight:Length(),
Magnitude = Bullet.RoundMass,
Radius = Bullet.Caliber,
DamageType = DecalIndex(Bullet.AmmoType),
}

Effects.CreateEffect("ACF_Penetration", EffectTable)
end

function Ammo:RicochetEffect(_, Bullet)
local Effect = EffectData()
Effect:SetOrigin(Bullet.SimPos)
Effect:SetNormal(Bullet.SimFlight:GetNormalized())
Effect:SetScale(Bullet.SimFlight:Length())
Effect:SetMagnitude(Bullet.RoundMass)
Effect:SetRadius(Bullet.Caliber)
Effect:SetDamageType(DecalIndex(Bullet.AmmoType))

util.Effect("ACF_Ricochet", Effect)
local EffectTable = {
Origin = Bullet.SimPos,
Normal = Bullet.SimFlight:GetNormalized(),
Scale = Bullet.SimFlight:Length(),
Magnitude = Bullet.RoundMass,
Radius = Bullet.Caliber,
DamageType = DecalIndex(Bullet.AmmoType),
}

Effects.CreateEffect("ACF_Ricochet", EffectTable)
end

function Ammo:AddCrateDataTrackers(Trackers)
Expand Down
52 changes: 26 additions & 26 deletions lua/acf/entities/ammo_types/heat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ if SERVER then
else
ACF.RegisterAmmoDecal("HEAT", "damage/heat_pen", "damage/heat_rico", function(Caliber) return Caliber * 0.1667 end)
local DecalIndex = ACF.GetAmmoDecalIndex
local Effects = ACF.Utilities.Effects

function Ammo:ImpactEffect(Effect, Bullet)
if not Bullet.Detonated then
Expand All @@ -456,24 +457,21 @@ else
end

function Ammo:PenetrationEffect(Effect, Bullet)
if Bullet.Detonated then
local Data = EffectData()
Data:SetOrigin(Bullet.SimPos)
Data:SetNormal(Bullet.SimFlight:GetNormalized())
Data:SetScale(Bullet.SimFlight:Length())
Data:SetMagnitude(Bullet.RoundMass)
Data:SetRadius(Bullet.Caliber)
Data:SetDamageType(DecalIndex(Bullet.AmmoType))

util.Effect("ACF_Penetration", Data)
else
local Data = EffectData()
Data:SetOrigin(Bullet.SimPos)
Data:SetNormal(Bullet.SimFlight:GetNormalized())
Data:SetRadius(math.max(Bullet.FillerMass ^ 0.33 * 8 * 39.37, 1))

util.Effect("ACF_HEAT_Explosion", Data)

local Detonated = Bullet.Detonated
local EffectName = Detonated and "ACF_Penetration" or "ACF_HEAT_Explosion"
local Radius = Detonated and Bullet.Caliber or math.max(Bullet.FillerMass ^ 0.33 * 8 * 39.37, 1)
local EffectTable = {
Origin = Bullet.SimPos,
Normal = Bullet.SimFlight:GetNormalized(),
Radius = Radius,
Magnitude = Detonated and Bullet.RoundMass or nil,
Scale = Detonated and Bullet.SimFlight:Length() or nil,
DamageType = Detonated and DecalIndex(Bullet.AmmoType) or nil,
}

Effects.CreateEffect(EffectName, EffectTable)

if not Detonated then
Bullet.Detonated = true
Bullet.LimitVel = 999999

Expand All @@ -482,14 +480,16 @@ else
end

function Ammo:RicochetEffect(_, Bullet)
local Effect = EffectData()
Effect:SetOrigin(Bullet.SimPos)
Effect:SetNormal(Bullet.SimFlight:GetNormalized())
Effect:SetScale(Bullet.SimFlight:Length())
Effect:SetMagnitude(Bullet.RoundMass)
Effect:SetRadius(Bullet.Caliber)
Effect:SetDamageType(DecalIndex(Bullet.AmmoType))
util.Effect("ACF_Ricochet", Effect)
local EffectTable = {
Origin = Bullet.SimPos,
Normal = Bullet.SimFlight:GetNormalized(),
Scale = Bullet.SimFlight:Length(),
Magnitude = Bullet.RoundMass,
Radius = Bullet.Caliber,
DamageType = DecalIndex(Bullet.AmmoType),
}

Effects.CreateEffect("ACF_Ricochet", EffectTable)
end

function Ammo:AddAmmoControls(Base, ToolData, BulletData)
Expand Down
19 changes: 11 additions & 8 deletions lua/acf/entities/ammo_types/smoke.lua
Original file line number Diff line number Diff line change
Expand Up @@ -168,21 +168,24 @@ if SERVER then
return false
end
else
local Effects = ACF.Utilities.Effects

ACF.RegisterAmmoDecal("SM", "damage/he_pen", "damage/he_rico")

function Ammo:ImpactEffect(_, Bullet)
local Crate = Bullet.Crate
local Color = IsValid(Crate) and Crate:GetColor() or Color(255, 255, 255)

local Effect = EffectData()
Effect:SetOrigin(Bullet.SimPos)
Effect:SetNormal(Bullet.SimFlight:GetNormalized())
Effect:SetScale(math.max(Bullet.FillerMass * 8 * 39.37, 0))
Effect:SetMagnitude(math.max(Bullet.WPMass * 8 * 39.37, 0))
Effect:SetStart(Vector(Color.r, Color.g, Color.b))
Effect:SetRadius(Bullet.Caliber)
local EffectTable = {
Origin = Bullet.SimPos,
Normal = Bullet.SimFlight:GetNormalized(),
Scale = math.max(Bullet.FillerMass * 8 * 39.37, 0),
Magnitude = math.max(Bullet.WPMass * 8 * 39.37, 0),
Start = Vector(Color.r, Color.g, Color.b),
Radius = Bullet.Caliber,
}

util.Effect("ACF_Smoke", Effect)
Effects.CreateEffect("ACF_Smoke", EffectTable)
end

function Ammo:AddAmmoControls(Base, ToolData, BulletData)
Expand Down
13 changes: 8 additions & 5 deletions lua/effects/acf_heat_explosion.lua
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
local Effects = ACF.Utilities.Effects

function EFFECT:Init(Data)
local Origin = Data:GetOrigin()
local Normal = Data:GetNormal()
local Radius = math.max(Data:GetRadius() * 0.02, 1)
local Emitter = ParticleEmitter(Origin)

local Effect = EffectData()
Effect:SetOrigin(Origin)
Effect:SetNormal(Normal)
Effect:SetScale(Radius * 50)
local EffectTable = {
Origin = Origin,
Normal = Normal,
Scale = Radius * 50,
}

util.Effect("ACF_Explosion", Effect)
Effects.CreateEffect("ACF_Explosion", EffectTable)

if not IsValid(Emitter) then return end

Expand Down
20 changes: 11 additions & 9 deletions lua/effects/acf_impact.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
local TraceData = { start = true, endpos = true }
local TraceLine = util.TraceLine
local TraceData = { start = true, endpos = true }
local TraceLine = util.TraceLine
local Effects = ACF.Utilities.Effects
local ValidDecal = ACF.IsValidAmmoDecal
local GetDecal = ACF.GetRicochetDecal
local GetScale = ACF.GetDecalScale
local GetDecal = ACF.GetRicochetDecal
local GetScale = ACF.GetDecalScale

function EFFECT:Init(Data)
local Caliber = Data:GetRadius() or 0
Expand All @@ -19,12 +20,13 @@ function EFFECT:Init(Data)
local Trace = TraceLine(TraceData)

-- Placeholder
local Effect = EffectData()
Effect:SetStart(Origin)
Effect:SetNormal(Trace.HitNormal)
Effect:SetMagnitude(0)
local EffectTable = {
Start = Origin,
Normal = Trace.HitNormal,
Magnitude = 0,
}

util.Effect("ElectricSpark", Effect)
Effects.CreateEffect("ElectricSpark", EffectTable)

if IsValid(Trace.Entity) or Trace.HitWorld then
local DecalType = ValidDecal(Type) and Type or 1
Expand Down
Loading

0 comments on commit 28916bc

Please sign in to comment.