Skip to content

Commit

Permalink
Added improved projectile effect, implemented new tracer
Browse files Browse the repository at this point in the history
- Added ACF_Projectile effect, with the idea of making all the logic from the former ACF_Bullet_Effect more straight forward.
- Implemented the new tracer model with the new projectile effect, scaling and bloom simulating are not there yet.
  • Loading branch information
TwistedTail committed May 8, 2024
1 parent acd9cad commit 84ce777
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 33 deletions.
16 changes: 8 additions & 8 deletions lua/acf/ballistics/ballistics_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ local Yellow = Color(255, 255, 0)
ACF.BulletEffect = ACF.BulletEffect or {}

local function BulletFlight(Bullet, DeltaTime)
local Drag = Bullet.SimFlight:GetNormalized() * (Bullet.DragCoef * Bullet.SimFlight:LengthSqr()) / ACF.DragDiv
local Drag = Bullet.Flight:GetNormalized() * (Bullet.DragCoef * Bullet.Flight:LengthSqr()) / ACF.DragDiv
local Correction = 0.5 * (Bullet.Accel - Drag) * DeltaTime -- Double integrates constant acceleration for better positional accuracy

Bullet.SimPosLast = Bullet.SimPos
Bullet.SimPos = Bullet.SimPos + ACF.Scale * DeltaTime * (Bullet.SimFlight + Correction) -- Calculates the next shell position
Bullet.SimFlight = Bullet.SimFlight + (Bullet.Accel - Drag) * DeltaTime -- Calculates the next shell vector
Bullet.LastPos = Bullet.Pos
Bullet.Pos = Bullet.Pos + ACF.Scale * DeltaTime * (Bullet.Flight + Correction) -- Calculates the next shell position
Bullet.Flight = Bullet.Flight + (Bullet.Accel - Drag) * DeltaTime -- Calculates the next shell vector

if IsValid(Bullet.Effect) then
Bullet.Effect:ApplyMovement(Bullet)
end
--if IsValid(Bullet.Effect) then
--Bullet.Effect:ApplyMovement(Bullet)
--end

debugoverlay.Line(Bullet.SimPosLast, Bullet.SimPos, 15, Yellow)
debugoverlay.Line(Bullet.LastPos, Bullet.Pos, 15, Yellow)
end

hook.Add("ACF_OnClock", "ACF_ManageBulletEffects", function(_, DeltaTime)
Expand Down
2 changes: 1 addition & 1 deletion lua/acf/ballistics/ballistics_sv.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function Ballistics.BulletClient(Bullet, Type, Hit, HitPos)
Effect:SetScale(0)
end

util.Effect("ACF_Bullet_Effect", Effect, true, true)
util.Effect("ACF_Projectile", Effect, true, true)
end

function Ballistics.RemoveBullet(Bullet)
Expand Down
5 changes: 5 additions & 0 deletions lua/acf/core/networking/networking_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ net.Receive("ACF_Networking", function(Bits)
local Handler = Receiver[Name]

if Handler then
if Name == "ACF_Projectile" then
print("Received bytes", Bits * 0.125)
print("Received bullets", table.Count(Data))
end

Handler(Data)
end
end
Expand Down
20 changes: 10 additions & 10 deletions lua/acf/entities/ammo_types/ap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ else

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

Expand All @@ -212,10 +212,10 @@ else

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:SetOrigin(Bullet.Pos)
Effect:SetNormal(Bullet.Flight:GetNormalized())
Effect:SetScale(Bullet.Flight:Length())
Effect:SetMagnitude(Bullet.ProjMass)
Effect:SetRadius(Bullet.Caliber)
Effect:SetDamageType(DecalIndex(Bullet.AmmoType))

Expand All @@ -224,10 +224,10 @@ else

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:SetOrigin(Bullet.Pos)
Effect:SetNormal(Bullet.Flight:GetNormalized())
Effect:SetScale(Bullet.Flight:Length())
Effect:SetMagnitude(Bullet.ProjMass)
Effect:SetRadius(Bullet.Caliber)
Effect:SetDamageType(DecalIndex(Bullet.AmmoType))

Expand Down
4 changes: 2 additions & 2 deletions lua/acf/entities/ammo_types/aphe.lua
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ else
ACF.RegisterAmmoDecal("APHE", "damage/ap_pen", "damage/ap_rico")

function Ammo:ImpactEffect(_, Bullet)
local Position = Bullet.SimPos
local Direction = Bullet.SimFlight
local Position = Bullet.Pos
local Direction = Bullet.Flight
local Filler = Bullet.FillerMass

Damage.explosionEffect(Position, Direction, Filler)
Expand Down
20 changes: 10 additions & 10 deletions lua/acf/entities/ammo_types/heat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -452,18 +452,18 @@ else
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:SetOrigin(Bullet.Pos)
Data:SetNormal(Bullet.Flight:GetNormalized())
Data:SetScale(Bullet.Flight:Length())
Data:SetMagnitude(Bullet.ProjMass)
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:SetOrigin(Bullet.Pos)
Data:SetNormal(Bullet.Flight:GetNormalized())
Data:SetRadius(math.max(Bullet.FillerMass ^ 0.33 * 8 * 39.37, 1))

util.Effect("ACF_HEAT_Explosion", Data)
Expand All @@ -477,10 +477,10 @@ else

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:SetOrigin(Bullet.Pos)
Effect:SetNormal(Bullet.Flight:GetNormalized())
Effect:SetScale(Bullet.Flight:Length())
Effect:SetMagnitude(Bullet.ProjMass)
Effect:SetRadius(Bullet.Caliber)
Effect:SetDamageType(DecalIndex(Bullet.AmmoType))
util.Effect("ACF_Ricochet", Effect)
Expand Down
4 changes: 2 additions & 2 deletions lua/acf/entities/ammo_types/smoke.lua
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ else
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:SetOrigin(Bullet.Pos)
Effect:SetNormal(Bullet.Flight: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))
Expand Down
172 changes: 172 additions & 0 deletions lua/effects/acf_projectile.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
local ACF = ACF
local Bullets = ACF.BulletEffect
local AmmoTypes = ACF.Classes.AmmoTypes
local Clock = ACF.Utilities.Clock

local Actions = {
[0] = "Create",
[1] = "Impact",
[2] = "Penetrate",
[3] = "Ricochet"
}

function EFFECT:Init(Data)
local Index = Data:GetDamageType()
local Action = Actions[Data:GetScale()]

if Action then
local Function = self[Action]
local Remove = Function(self, Index, Data)

if Remove then self:Remove() end
else
print("Invalid action for bullet #" .. Index .. ", removing.")

self:Remove()
end
end

function EFFECT:Create(Index, Data)
local Crate = Data:GetEntity()

--TODO: Check if it is actually a crate
if not IsValid(Crate) then return true end

local Flight = Data:GetStart() * 10
local Pos = Data:GetOrigin()
local Caliber = Crate:GetNW2Float("Caliber", 10)
local Tracer = Crate:GetNW2Float("Tracer") > 0
local Color = Tracer and Crate:GetColor() or nil
local Bullet = {
Index = Index,
Crate = Crate,
Pos = Pos,
LastPos = Pos,
Flight = Flight,
Caliber = Caliber,
ProjMass = Crate:GetNW2Float("ProjMass", 10),
FillerMass = Crate:GetNW2Float("FillerMass"),
WPMass = Crate:GetNW2Float("WPMass"),
DragCoef = Crate:GetNW2Float("DragCoef", 1),
AmmoType = Crate:GetNW2String("AmmoType", "AP"),
Accel = Crate:GetNW2Vector("Accel", ACF.Gravity),
Color = Color,
LastThink = Clock.CurTime,
Effect = self,
}

if Color then
self:ManipulateBoneScale(0, Vector(Caliber * 4, Caliber * 2, Caliber * 2))
self:SetModel("models/acf/core/tracer.mdl")
self:SetColor(Color)

self.IsTracer = true
else
self:SetModel("models/munitions/round_100mm_shot.mdl")
self:SetModelScale(Caliber * 0.1, 0)
end

self:SetNoDraw(Data:GetAttachment() == 0)
self:SetAngles(Bullet.Flight:Angle())
self:SetPos(Bullet.Pos)

self.Bullet = Bullet

--TODO: Add an index delay on the serverside to prevent this, how long though.
if Bullets[Index] then
Bullets[Index].Removed = true
print("WARNING: #" .. Index .. " ALREADY EXISTS.")
end

Bullets[Index] = Bullet
end

function EFFECT:Impact(Index, Data)
local Bullet = Bullets[Index]

if not Bullet or Bullet.Removed then return true end

local Effect = Bullet.Effect

if not IsValid(Effect) then return true end

local AmmoType = AmmoTypes.Get(Bullet.AmmoType)

Effect:SetNoDraw(Data:GetAttachment() == 0)

Bullet.Flight = Data:GetStart() * 10
Bullet.Pos = Data:GetOrigin()
Bullet.Removed = true

AmmoType:ImpactEffect(Effect, Bullet)

Bullets[Index] = nil

return true
end

function EFFECT:Penetrate(Index, Data)
local Bullet = Bullets[Index]

if not Bullet or Bullet.Removed then return true end

local Effect = Bullet.Effect

if not IsValid(Effect) then return true end

local AmmoType = AmmoTypes.Get(Bullet.AmmoType)

Effect:SetNoDraw(Data:GetAttachment() == 0)

Bullet.Flight = Data:GetStart() * 10
Bullet.Pos = Data:GetOrigin()

AmmoType:PenetrationEffect(Effect, Bullet)

return true
end

function EFFECT:Ricochet(Index, Data)
local Bullet = Bullets[Index]

if not Bullet or Bullet.Removed then return true end

local Effect = Bullet.Effect

if not IsValid(Effect) then return true end

local AmmoType = AmmoTypes.Get(Bullet.AmmoType)

Effect:SetNoDraw(Data:GetAttachment() == 0)

Bullet.Flight = Data:GetStart() * 10
Bullet.Pos = Data:GetOrigin()

AmmoType:RicochetEffect(Effect, Bullet)

return true
end

function EFFECT:Think()
local Bullet = self.Bullet

if not Bullet or Bullet.Removed then return false end

return self:ApplyMovement(Bullet)
end

function EFFECT:ApplyMovement(Bullet)
local Position = Bullet.Pos

--TODO: Replace this logic, map bounds might not be compliant with this in all cases
if math.abs(Position.x) > 16380 or math.abs(Position.y) > 16380 or Position.z < -16380 then
return false
end

if Position.z < 16380 then
self:SetAngles(Bullet.Flight:Angle())
self:SetPos(Position)
end

return true
end

0 comments on commit 84ce777

Please sign in to comment.