diff --git a/lua/acf/core/networking/networking_datatypes.lua b/lua/acf/core/networking/networking_datatypes.lua deleted file mode 100644 index 0825748d4..000000000 --- a/lua/acf/core/networking/networking_datatypes.lua +++ /dev/null @@ -1,66 +0,0 @@ -local Network = ACF.Networking - --- "Grainy" datatypes --- These are basically less-accurate vectors and angles for non-critical things like debris positions. - -local round = math.Round -local pow = math.pow -local maxSUEdge = pow(2, 14) - -local function UnitsToGrain(Value, Base, Grain) - Value = ((Value / Base) + 1) / 2 - Value = Value * (pow(2, Grain) - 1) - return round(Value) -end - -local function GrainToUnits(Value, Base, Grain) - Value = Value / (pow(2, Grain) - 1) - Value = (Value - 0.5) * Base * 2 - return round(Value) -end - -function Network.ReadGrainyVector(Grain, Base) - assert(isnumber(Grain), "expected vector in argument #1") - - local X = GrainToUnits(net.ReadUInt(Grain), Base or maxSUEdge, Grain) - local Y = GrainToUnits(net.ReadUInt(Grain), Base or maxSUEdge, Grain) - local Z = GrainToUnits(net.ReadUInt(Grain), Base or maxSUEdge, Grain) - - return Vector(X, Y, Z) -end - -function Network.ReadGrainyAngle(Grain, Base) - assert(isnumber(Grain), "expected number in argument #1") - - local X = GrainToUnits(net.ReadUInt(Grain), Base or maxSUEdge, Grain) - local Y = GrainToUnits(net.ReadUInt(Grain), Base or maxSUEdge, Grain) - local Z = GrainToUnits(net.ReadUInt(Grain), Base or maxSUEdge, Grain) - - return Angle(X, Y, Z) -end - -function Network.WriteGrainyVector(Vector, Grain, Base) - assert(isvector(Vector), "expected vector in argument #1") - assert(isnumber(Grain), "expected number in argument #2") - - local X = UnitsToGrain(Vector[1], Base or maxSUEdge, Grain) - local Y = UnitsToGrain(Vector[2], Base or maxSUEdge, Grain) - local Z = UnitsToGrain(Vector[3], Base or maxSUEdge, Grain) - - net.WriteUInt(X, Grain) - net.WriteUInt(Y, Grain) - net.WriteUInt(Z, Grain) -end - -function Network.WriteGrainyAngle(Angle, Grain, Base) - assert(isangle(Angle), "expected angle in argument #1") - assert(isnumber(Grain), "expected number in argument #2") - - local X = UnitsToGrain(Angle[1], Base or maxSUEdge, Grain) - local Y = UnitsToGrain(Angle[2], Base or maxSUEdge, Grain) - local Z = UnitsToGrain(Angle[3], Base or maxSUEdge, Grain) - - net.WriteUInt(X, Grain) - net.WriteUInt(Y, Grain) - net.WriteUInt(Z, Grain) -end \ No newline at end of file diff --git a/lua/acf/damage/debris_cl.lua b/lua/acf/damage/debris_cl.lua index fdb592577..62a2fb444 100644 --- a/lua/acf/damage/debris_cl.lua +++ b/lua/acf/damage/debris_cl.lua @@ -1,5 +1,4 @@ local ACF = ACF -local Network = ACF.Networking local Effects = ACF.Utilities.Effects local AllowDebris = GetConVar("acf_debris") @@ -57,7 +56,7 @@ local function Ignite(Entity, Lifetime, IsGib) end end -local function CreateDebris(Model, Position, Angles, Normal, Power, ShouldIgnite) +local function CreateDebris(Model, Position, Angles, Material, Color, Normal, Power, ShouldIgnite) local Debris = ents.CreateClientProp(Model) if not IsValid(Debris) then return end @@ -66,7 +65,8 @@ local function CreateDebris(Model, Position, Angles, Normal, Power, ShouldIgnite Debris:SetPos(Position) Debris:SetAngles(Angles) - Debris:SetMaterial("models/props_pipes/GutterMetal01a") + Debris:SetMaterial(Material) + Debris:SetColor(Color) if not CollideAll:GetBool() then Debris:SetCollisionGroup(COLLISION_GROUP_WORLD) @@ -95,7 +95,7 @@ local function CreateDebris(Model, Position, Angles, Normal, Power, ShouldIgnite return Debris end -local function CreateGib(Position, Angles, Normal, Power, Min, Max) +local function CreateGib(Position, Angles, Material, Color, Normal, Power, Min, Max) local Gib = ents.CreateClientProp(GibModel:format(math.random(1, 5))) if not IsValid(Gib) then return end @@ -108,7 +108,8 @@ local function CreateGib(Position, Angles, Normal, Power, Min, Max) Gib:SetPos(Position + Offset) Gib:SetAngles(AngleRand(-180, 180)) Gib:SetModelScale(math.Rand(0.5, 2)) - Gib:SetMaterial("models/props_pipes/GutterMetal01a") + Gib:SetMaterial(Material) + Gib:SetColor(Color) Gib:Spawn() Gib.SmokeParticle = Particle(Gib, "smoke_gib_01") @@ -130,11 +131,11 @@ local function CreateGib(Position, Angles, Normal, Power, Min, Max) return true end -function ACF.CreateDebris(Model, Position, Angles, Normal, Power, CanGib, Ignite) +function ACF.CreateDebris(Model, Position, Angles, Material, Color, Normal, Power, CanGib, Ignite) if not AllowDebris:GetBool() then return end if not Model then return end - local Debris = CreateDebris(Model, Position, Angles, Normal, Power, CanGib, Ignite) + local Debris = CreateDebris(Model, Position, Angles, Material, Color, Normal, Power, CanGib, Ignite) if IsValid(Debris) then local Multiplier = GibMult:GetFloat() @@ -146,7 +147,7 @@ function ACF.CreateDebris(Model, Position, Angles, Normal, Power, CanGib, Ignite local GibCount = math.Clamp(Radius * 0.1, 1, math.max(10 * Multiplier, 1)) for _ = 1, GibCount do - if not CreateGib(Position, Angles, Normal, Power, Min, Max) then + if not CreateGib(Position, Angles, Material, Color, Normal, Power, Min, Max) then break end end @@ -163,38 +164,50 @@ end local EntData = {} --- Models MIGHT change, but aren't likely to, especially in combat, so rather than running some intensive model checker on entities --- it would be better to just store it on creation. It's worth a model or two being wrong every now and then for reducing 40+ bytes --- into just two bytes when writing the model part of debris -hook.Add("OnEntityCreated", "ACF_Debris_TrackEnts", function(ent) - timer.Simple(0.001, function() - if IsValid(ent) then - local id = ent:EntIndex() - if id ~= -1 then - EntData[ent:EntIndex()] = ent:GetModel() - end - end +-- Store data of potentially ACF-killed entities for debris use, then remove from cache soon after +hook.Add("EntityRemoved", "ACF_Debris_TrackEnts", function(Ent) + local EntID = Ent:EntIndex() + if EntID == -1 then return end + + EntData[EntID] = { + Model = Ent:GetModel(), + Material = Ent:GetMaterial(), + Color = Ent:GetColor(), + Position = Ent:GetPos(), + Angles = Ent:GetAngles(), + } + + timer.Simple(2, function() + if not EntData[EntID] then return end + EntData[EntID] = nil end) end) net.Receive("ACF_Debris", function() - local EntID = net.ReadUInt(14) - local Position = Network.ReadGrainyVector(12) - local Angles = Network.ReadGrainyAngle(8) - local Normal = Network.ReadGrainyVector(8, 1) + local EntID = net.ReadUInt(13) + local Normal = Vector(net.ReadInt(8) / 100, net.ReadInt(8) / 100, net.ReadInt(8) / 100) local Power = net.ReadUInt(16) local CanGib = net.ReadBool() local Ignite = net.ReadBool() - ACF.CreateDebris( - EntData[EntID], - Position, - Angles, - Normal, - Power, - CanGib, - Ignite - ) + timer.Simple(0, function() + local EntInfo = EntData[EntID] + local NewColor = EntInfo.Color:ToVector() * math.Rand(0.3, 0.6) + + ACF.CreateDebris( + EntInfo.Model, + EntInfo.Position, + EntInfo.Angles, + EntInfo.Material, + NewColor:ToColor(), + Normal, + Power, + CanGib, + Ignite + ) + + EntData[EntID] = nil + end) end) game.AddParticles("particles/fire_01.pcf") diff --git a/lua/acf/damage/debris_sv.lua b/lua/acf/damage/debris_sv.lua index 440863ab2..a56c0394c 100644 --- a/lua/acf/damage/debris_sv.lua +++ b/lua/acf/damage/debris_sv.lua @@ -1,7 +1,6 @@ util.AddNetworkString("ACF_Debris") local Contraption = ACF.Contraption -local Network = ACF.Networking local ValidDebris = ACF.ValidDebris local ChildDebris = ACF.ChildDebris local Queue = {} @@ -10,10 +9,10 @@ local function SendQueue() for Entity, Data in pairs(Queue) do net.Start("ACF_Debris") - net.WriteUInt(Data.ID, 14) - Network.WriteGrainyVector(Data.Position, 12) - Network.WriteGrainyAngle(Data.Angles, 8) - Network.WriteGrainyVector(Data.Normal, 8, 1) + net.WriteUInt(Data.ID, 13) + net.WriteInt(Data.Normal.x * 100, 8) + net.WriteInt(Data.Normal.y * 100, 8) + net.WriteInt(Data.Normal.z * 100, 8) net.WriteUInt(Data.Power, 16) net.WriteBool(Data.CanGib) net.WriteBool(Data.Ignite) @@ -35,7 +34,6 @@ local function DebrisNetter(Entity, Normal, Power, CanGib, Ignite) Queue[Entity] = { ID = Entity:EntIndex(), Position = Entity:GetPos(), - Angles = Entity:GetAngles(), Normal = Normal, Power = Power, CanGib = CanGib or nil,