Skip to content

Commit

Permalink
Improved tank modularity
Browse files Browse the repository at this point in the history
Should have replaced pretty much all the hardcoded stuff (and fixed the stuff that was just breaking)
  • Loading branch information
thecraftianman committed Oct 19, 2023
1 parent 5235a25 commit 76b5064
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 106 deletions.
32 changes: 26 additions & 6 deletions lua/acf/entities/fuel_tanks/box.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,38 @@ local FuelTanks = ACF.Classes.FuelTanks

FuelTanks.Register("FTS_B", {
Name = "Fuel Box",
Description = "Scalable fuel tank; required for engines to work."
Description = "Scalable fuel box; required for engines to work.",
IsScalable = true,
Model = "models/fueltank/fueltank_4x4x4.mdl",
Shape = "Box",
NameType = "Tank",
IsExplosive = true,
Unlinkable = false,
Preview = {
FOV = 120,
},
CalcVolume = function(Size, Wall)
local InteriorVolume = (Size.x - Wall) * (Size.y - Wall) * (Size.z - Wall) -- Math degree

local Area = (2 * Size.x * Size.y) + (2 * Size.y * Size.z) + (2 * Size.x * Size.z)
local Volume = InteriorVolume - (Area * Wall)

return Volume, Area
end,
CalcOverlaySize = function(Entity)
local X, Y, Z = Entity:GetSize():Unpack()
X = math.Round(X, 2)
Y = math.Round(Y, 2)
Z = math.Round(Z, 2)

return "Size: " .. X .. "x" .. Y .. "x" .. Z .. "\n\n"
end
})

do
FuelTanks.RegisterItem("Box", "FTS_B", {
Name = "Fuel Box",
Description = "", -- Blank to allow for dynamic descriptions better
Model = "models/fueltank/fueltank_4x4x4.mdl",
Shape = "Box",
Preview = {
FOV = 120,
},
})
end

Expand Down
35 changes: 29 additions & 6 deletions lua/acf/entities/fuel_tanks/drum.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,41 @@ local FuelTanks = ACF.Classes.FuelTanks

FuelTanks.Register("FTS_D", {
Name = "Fuel Drum",
Description = "Scalable fuel drum; required for engines to work."
Description = "Scalable fuel drum; required for engines to work.",
IsScalable = true,
Model = "models/props_c17/oildrum001_explosive.mdl",
Shape = "Drum",
NameType = "Drum",
IsExplosive = true,
Unlinkable = false,
Preview = {
FOV = 120,
},
CalcVolume = function(Size, Wall)
local Radius = Size.x / 2
local InteriorVolume = math.pi * ((Radius - Wall) ^ 2) * (Size.z - Wall)

local Area = 2 * math.pi * Radius * (Radius + Size.z)
local Volume = InteriorVolume - (Area * Wall)

return Volume, Area
end,
CalcOverlaySize = function(Entity)
local D, _, H = Entity:GetSize():Unpack()
D = math.Round(D, 2)
H = math.Round(H, 2)

return "Diameter: " .. D .. "\nHeight: " .. H .. "\n\n"
end,
VerifyData = function(Data, _) -- Diameter needs to be made equal for the X and Y dimensions
Data.Size.y = Data.Size.x
end
})

do
FuelTanks.RegisterItem("Drum", "FTS_D", {
Name = "Fuel Drum",
Description = "Tends to explode when shot.",
Model = "models/props_c17/oildrum001_explosive.mdl",
Shape = "Drum",
Preview = {
FOV = 120,
},
})
end

Expand Down
15 changes: 11 additions & 4 deletions lua/acf/entities/fuel_types/electric.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@ local ACF = ACF
local FuelTypes = ACF.Classes.FuelTypes

FuelTypes.Register("Electric", {
Name = "Lit-Ion Battery",
Density = 3.89,
ConsumptionText = function(PeakkW, _, Efficiency)
Name = "Lit-Ion Battery",
Density = 3.89,
ConsumptionText = function(PeakkW, _, Efficiency)
local Text = "Peak Energy Consumption :\n%s kW - %s MJ/min"
local Rate = ACF.FuelRate * PeakkW / Efficiency

return Text:format(math.Round(Rate, 2), math.Round(Rate * 0.06, 2))
end,
FuelTankText = function(Capacity, Mass)
FuelTankText = function(Capacity, Mass)
local Text = "Tank Armor : %s mm\nCharge : %s kW per hour - %s MJ\nMass : %s"
local kWh = math.Round(Capacity * ACF.LiIonED, 2)
local MJ = math.Round(Capacity * ACF.LiIonED * 3.6, 2)

return Text:format(ACF.FuelArmor, kWh, MJ, ACF.GetProperMass(Mass))
end,
FuelTankOverlayText = function(Fuel)
local Text = "Charge Level: %s kWh / %s MJ"
local KiloWatt = math.Round(Fuel, 2)
local Joules = math.Round(Fuel * 3.6, 2)

return Text:format(KiloWatt, Joules)
end
})
34 changes: 14 additions & 20 deletions lua/acf/menu/items_cl/engines.lua
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,15 @@ local function CreateMenu(Menu)
local ClassData = FuelClass.Selected
local ClassDesc = ClassData.Description

self.Description = (ClassDesc and (ClassDesc .. "\n\n") or "") .. Data.Description
self.Description = (ClassDesc and (ClassDesc .. "\n\n") or "")
if Data.Description then
self.Description = self.Description .. Data.Description
end

ACF.SetClientData("FuelTank", Data.ID)

FuelPreview:UpdateModel(Data.Model)
FuelPreview:UpdateSettings(Data.Preview)
FuelPreview:UpdateModel(ClassData.Model or Data.Model)
FuelPreview:UpdateSettings(ClassData.Preview or Data.Preview)

FuelType:UpdateFuelText()
end
Expand All @@ -278,29 +281,20 @@ local function CreateMenu(Menu)
local FuelDescText = ""

local Wall = ACF.FuelArmor * ACF.MmToInch -- Wall thickness in inches
local Shape = FuelTank.Shape
local ClassData = FuelClass.Selected
local Volume, Area

if Shape == "Box" then
local InteriorVolume = (TankSize.x - Wall) * (TankSize.y - Wall) * (TankSize.z - Wall) -- Math degree
Area = (2 * TankSize.x * TankSize.y) + (2 * TankSize.y * TankSize.z) + (2 * TankSize.x * TankSize.z)

Volume = InteriorVolume - (Area * Wall)

-- Preserving flavor text from older fuel tank sizes
FuelDescText = FuelDescSentences[math.random(33)]
elseif Shape == "Drum" then
local Radius = TankSize.x / 2
local InteriorVolume = math.pi * ((Radius - Wall) ^ 2) * (TankSize.z - Wall)
Area = 2 * math.pi * Radius * (Radius + TankSize.z)

Volume = InteriorVolume - (Area * Wall)

FuelDescText = ""
if ClassData.CalcVolume then
Volume, Area = ClassData.CalcVolume(TankSize, Wall)
else
Area = FuelTank.SurfaceArea
Volume = FuelTank.Volume - (FuelTank.SurfaceArea * Wall) -- Total volume of tank (cu in), reduced by wall thickness
end

if ClassData.ID == "FTS_B" then
-- Preserving flavor text from older fuel tank sizes
FuelDescText = FuelDescSentences[math.random(33)]
else
FuelDescText = ""
end

Expand Down
103 changes: 33 additions & 70 deletions lua/entities/acf_fueltank/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ do -- Spawn and Update functions
if Class.IsScalable then
local FuelTank = FuelTanks.GetItem(Class.ID, Data.FuelTank)

if FuelTank then
if FuelTank and FuelTank.Size then
Data.FuelTank = Class.ID
Data.Size = Vector(FuelTank.Size)
elseif not isvector(Data.Size) then
Expand Down Expand Up @@ -109,10 +109,13 @@ do -- Spawn and Update functions
local Percentage = Entity.Capacity and Entity.Fuel / Entity.Capacity or 1

Entity.ACF = Entity.ACF or {}
Entity.ACF.Model = FuelTank.Model -- Must be set before changing model
Entity.ACF.Model = Class.Model or FuelTank and FuelTank.Model -- Must be set before changing model
Entity.ClassData = Class

if FuelTank.Shape ~= "Box" and FuelTank.Shape ~= "Drum" then
Entity:SetModel(FuelTank.Model)
if Class.IsScalable then
Entity:SetSize(Data.Size)
else
Entity:SetModel(Entity.ACF.Model)
Entity:PhysicsInit(SOLID_VPHYSICS, true)
Entity:SetMoveType(MOVETYPE_VPHYSICS)
end
Expand All @@ -122,48 +125,29 @@ do -- Spawn and Update functions
Entity[V] = Data[V]
end

local Size = Data.Size
local Volume, Area, NameType
local Volume, Area
local Wall = ACF.FuelArmor * ACF.MmToInch -- Wall thickness in inches

if FuelTank.Shape == "Box" then
local InteriorVolume = (Size.x - Wall) * (Size.y - Wall) * (Size.z - Wall) -- Math degree
Area = (2 * Size.x * Size.y) + (2 * Size.y * Size.z) + (2 * Size.x * Size.z)

Volume = InteriorVolume - (Area * Wall)

NameType = " Tank"

Entity:SetSize(Data.Size)
elseif FuelTank.Shape == "Drum" then
local Radius = Size.x / 2
local InteriorVolume = math.pi * ((Radius - Wall) ^ 2) * (Size.z - Wall)
Area = 2 * math.pi * Radius * (Radius + Size.z)

Volume = InteriorVolume - (Area * Wall)

NameType = " Drum"

Entity:SetSize(Data.Size)
else
if Class.CalcVolume then
Volume, Area = Class.CalcVolume(Data.Size, Wall)
else -- Default to finding surface area/volume based off physics object instead
local PhysObj = Entity:GetPhysicsObject()
Area = PhysObj:GetSurfaceArea()

Area = PhysObj:GetSurfaceArea()
Volume = PhysObj:GetVolume() - (Area * Wall) -- Total volume of tank (cu in), reduced by wall thickness

NameType = " " .. FuelTank.Name
end

local NameType = " " .. (Class.NameType or FuelTank.Name)

Entity.Name = Entity.FuelType .. NameType
Entity.ShortName = Entity.FuelType
Entity.EntType = Class.Name
Entity.ClassData = Class
Entity.FuelDensity = FuelType.Density
Entity.Capacity = Volume * ACF.gCmToKgIn * ACF.TankVolumeMul -- Internal volume available for fuel in liters
Entity.EmptyMass = (Area * Wall) * 16.387 * 0.0079 -- Total wall volume * cu in to cc * density of steel (kg/cc)
Entity.IsExplosive = FuelTank.IsExplosive
Entity.NoLinks = FuelTank.Unlinkable
Entity.Shape = FuelTank.Shape
Entity.IsExplosive = FuelTank and FuelTank.IsExplosive or Class.IsExplosive
Entity.NoLinks = FuelTank and FuelTank.Unlinkable or Class.Unlinkable
Entity.Shape = FuelTank and FuelTank.Shape or Class.Shape

WireIO.SetupInputs(Entity, Inputs, Data, Class, FuelTank, FuelType)
WireIO.SetupOutputs(Entity, Outputs, Data, Class, FuelTank, FuelType)
Expand Down Expand Up @@ -203,7 +187,7 @@ do -- Spawn and Update functions
local FuelTank = FuelTanks.GetItem(Class.ID, Data.FuelTank)
local FuelType = FuelTypes.Get(Data.FuelType)
local Limit = Class.LimitConVar.Name
local Model = FuelTank.Model
local Model = Class.Model or FuelTank and FuelTank.Model

if not Player:CheckLimit(Limit) then return end

Expand All @@ -216,7 +200,7 @@ do -- Spawn and Update functions
if not IsValid(Tank) then return end

Tank:SetPlayer(Player)
if FuelTank.Shape == "Box" or FuelTank.Shape == "Drum" then
if Class.IsScalable then
Tank:SetScaledModel(Model)
end
Tank:SetAngles(Angle)
Expand Down Expand Up @@ -452,6 +436,9 @@ do -- Mass Update
end

do -- Overlay Update
local Classes = ACF.Classes
local FuelTypes = Classes.FuelTypes

local Text = "%s\n\n%sFuel Type: %s\n%s"

function ENT:UpdateOverlayText()
Expand All @@ -464,31 +451,19 @@ do -- Overlay Update
Status = self:CanConsume() and "Providing Fuel" or "Idle"
end

local Shape = self.Shape

if Shape == "Box" then
local X, Y, Z = self:GetSize():Unpack()
X = math.Round(X, 2)
Y = math.Round(Y, 2)
Z = math.Round(Z, 2)
local Class = self.ClassData

Size = "Size: " .. X .. "x" .. Y .. "x" .. Z .. "\n\n"
elseif Shape == "Drum" then
local D, _, H = self:GetSize():Unpack()
D = math.Round(D, 2)
H = math.Round(H, 2)

Size = "Diameter: " .. D .. "\nHeight: " .. H .. "\n\n"
if Class and Class.CalcOverlaySize then
Size = Class.CalcOverlaySize(self)
end

if self.FuelType == "Electric" then -- TODO: Replace hardcoded stuff
local KiloWatt = math.Round(self.Fuel, 1)
local Joules = math.Round(self.Fuel * 3.6, 1)
local FuelType = FuelTypes.Get(self.FuelType)

Content = "Charge Level: " .. KiloWatt .. " kWh / " .. Joules .. " MJ"
if FuelType and FuelType.FuelTankOverlayText then
Content = FuelType.FuelTankOverlayText(self.Fuel)
else
local Liters = math.Round(self.Fuel, 1)
local Gallons = math.Round(self.Fuel * 0.264172, 1)
local Liters = math.Round(self.Fuel, 2)
local Gallons = math.Round(self.Fuel * 0.264172, 2)

Content = "Fuel Remaining: " .. Liters .. " liters / " .. Gallons .. " gallons"
end
Expand Down Expand Up @@ -587,23 +562,11 @@ end

function ENT:OnResized(Size)
do -- Calculate new empty mass
local Volume
local Wall = ACF.FuelArmor * ACF.MmToInch -- Wall thickness in inches
local Class = self.ClassData
local _, Area = Class.CalcVolume(Size, Wall)

if self.FuelTank == "Drum" then
local Radius = Size.x / 2
local ExteriorVolume = math.pi * (Radius ^ 2) * Size.z
local InteriorVolume = math.pi * ((Radius - Wall) ^ 2) * (Size.z - Wall)

Volume = ExteriorVolume - InteriorVolume
else
local ExteriorVolume = Size.x * Size.y * Size.z
local InteriorVolume = (Size.x - Wall) * (Size.y - Wall) * (Size.z - Wall) -- Math degree

Volume = ExteriorVolume - InteriorVolume
end

local Mass = Volume * 16.387 * 0.0079 -- Total wall volume * cu in to cc * density of steel (kg/cc)
local Mass = (Area * Wall) * 16.387 * 0.0079 -- Total wall volume * cu in to cc * density of steel (kg/cc)

self.EmptyMass = Mass
end
Expand Down

0 comments on commit 76b5064

Please sign in to comment.