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

Scalable gearboxes rework #443

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
22 changes: 20 additions & 2 deletions lua/acf/core/classes/grouped.lua
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ function Classes.AddGroupedFunctions(Namespace, Entries)
--- @param GroupID string # The ID of the group the group item belongs to
--- @param ID string # The ID of the group item to make an alias of
--- @param Alias string # The alias to apply to the given group item
function Namespace.AddItemAlias(GroupID, ID, Alias)
--- @param Overrides? table # An optional table of overrides to alter the behavior of the alias
function Namespace.AddItemAlias(GroupID, ID, Alias, Overrides)
local Group = isstring(GroupID) and Entries[GroupID]

if not Group then return end
Expand All @@ -170,7 +171,24 @@ function Classes.AddGroupedFunctions(Namespace, Entries)

local Lookup = Group.Lookup

Lookup[Alias] = Lookup[ID]
-- NOTE: This is commented out to prevent cyclic references with the regular duplicator
-- Try to add this back in if it seems to be useful for something
-- Lookup[Alias] = Lookup[ID]

if istable(Overrides) then
-- Make a shallow copy of the table, then apply overrides
Lookup[Alias] = {}

for Key, Value in pairs(Lookup[ID]) do
Lookup[Alias][Key] = Value
end

for Key, Value in pairs(Overrides) do
Lookup[Alias][Key] = Value
end
else
Lookup[Alias] = Lookup[ID]
end
end

--- Checks whether an ID is an alias of a group item
Expand Down
35 changes: 22 additions & 13 deletions lua/acf/core/globals.lua
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,26 @@ do -- ACF global vars
ACF.GunInaccuracyBias = 2 -- Higher numbers make shots more likely to be inaccurate. Choose between 0.5 to 4. Default is 2 (unbiased).

-- Fuel
ACF.RequireFuel = true -- Whether or not fuel usage should be required for engines
ACF.FuelRate = 15 -- Multiplier for fuel usage, 1.0 is approx real world
ACF.FuelFactor = 1 -- Multiplier for ACF.FuelRate
ACF.FuelMinSize = 6 -- Defines the shortest possible length of fuel tanks for all their axises, in gmu
ACF.FuelMaxSize = 96 -- Defines the highest possible length of fuel tanks for all their axises, in gmu
ACF.FuelArmor = 1 -- How many millimeters of armor fuel tanks have
ACF.FuelRefillColor = Color(76, 201, 250, 10) -- The color to use for the fuel refill effect
ACF.TankVolumeMul = 1 -- Multiplier for fuel tank capacity, 1.0 is approx real world
ACF.LiIonED = 0.458 -- li-ion energy density: kw hours / liter
ACF.RefillDistance = 300 -- Distance in which ammo crate starts refilling.
ACF.RefillSpeed = 700 -- (ACF.RefillSpeed / RoundMass) / Distance
ACF.RefuelSpeed = 20 -- Liters per second * ACF.FuelRate
ACF.RequireFuel = true -- Whether or not fuel usage should be required for engines
ACF.FuelRate = 15 -- Multiplier for fuel usage, 1.0 is approx real world
ACF.FuelFactor = 1 -- Multiplier for ACF.FuelRate
ACF.FuelMinSize = 6 -- Defines the shortest possible length of fuel tanks for all their axises, in gmu
ACF.FuelMaxSize = 96 -- Defines the highest possible length of fuel tanks for all their axises, in gmu
ACF.FuelArmor = 1 -- How many millimeters of armor fuel tanks have
ACF.FuelRefillColor = Color(76, 201, 250, 10) -- The color to use for the fuel refill effect
ACF.TankVolumeMul = 1 -- Multiplier for fuel tank capacity, 1.0 is approx real world
ACF.LiIonED = 0.458 -- li-ion energy density: kw hours / liter
ACF.RefillDistance = 300 -- Distance in which ammo crate starts refilling.
ACF.RefillSpeed = 700 -- (ACF.RefillSpeed / RoundMass) / Distance
ACF.RefuelSpeed = 20 -- Liters per second * ACF.FuelRate

-- Gearboxes
ACF.GearEfficiency = 0.99 -- The percentage of RPM efficiency kept when increasing the gear count
ACF.GearboxMassScale = 2 -- The exponent to determine the gearbox's mass in proportion to its scale
ACF.GearboxTorqueScale = 3 -- The exponent to determine the gearbox's torque in proportion to its scale
ACF.TorqueMult = 2 -- The arbitrary multiplier for the final amount of torque; TODO: we should probably implement this in a better way
ACF.MinGearRatio = -10 -- The minimum value that a gear's ratio can be set to
ACF.MaxGearRatio = 10 -- The maximum value that a gear's ratio can be set to
end

do -- ACF Convars & Particles
Expand Down Expand Up @@ -170,7 +178,8 @@ if SERVER then
elseif CLIENT then
CreateClientConVar("acf_show_entity_info", 1, true, false, "Defines under what conditions the info bubble on ACF entities will be shown. 0 = Never, 1 = When not seated, 2 = Always", 0, 2)
CreateClientConVar("acf_cl_particlemul", 1, true, true, "Multiplier for the density of ACF effects.", 0.1, 1)
CreateClientConVar("acf_mobilityropelinks", 1, true, true)
CreateClientConVar("acf_mobilityropelinks", 0, true, true, "Toggles the visibility of the links connecting mobility components.")
CreateClientConVar("acf_advancedmobilityropelinks", 0, true, true, "Uses generated models to represent mobility links.")
CreateClientConVar("acf_maxroundsdisplay", 16, true, false, "Maximum rounds to display before using bulk display (0 to only display bulk)", 0, 5000)
CreateClientConVar("acf_drawboxes", 1, true, false, "Whether or not to draw hitboxes on ACF entities", 0, 1)
CreateClientConVar("acf_legalhints", 1, true, true, "If enabled, ACF will throw a warning hint whenever an entity gets disabled.", 0, 1)
Expand Down
90 changes: 28 additions & 62 deletions lua/acf/core/utilities/util_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ do -- Panel helpers
local Count = 0

for _, Value in pairs(List) do
if Value.SuppressLoad then continue end

Count = Count + 1

Choices[Count] = Value
Expand Down Expand Up @@ -85,39 +87,27 @@ do -- Default gearbox menus
local Values = {}

do -- Manual Gearbox Menu
function ACF.ManualGearboxMenu(Class, Data, Menu, Base)
local Text = "Mass : %s\nTorque Rating : %s n/m - %s fl-lb\n"
local Mass = ACF.GetProperMass(Data.Mass)
local Gears = Class.Gears
local Torque = math.floor(Data.MaxTorque * 0.73)

Base:AddLabel(Text:format(Mass, Data.MaxTorque, Torque))

if Data.DualClutch then
Base:AddLabel("The dual clutch allows you to apply power and brake each side independently.")
end

-----------------------------------

function ACF.ManualGearboxMenu(Class, _, Menu, _)
local Gears = Class.CanSetGears and ACF.GetClientNumber("GearAmount", 3) or Class.Gears.Max
local GearBase = Menu:AddCollapsible("Gear Settings")

Values[Class.ID] = Values[Class.ID] or {}

local ValuesData = Values[Class.ID]

for I = 1, Gears.Max do
for I = 1, Gears do
local Variable = "Gear" .. I
local Default = ValuesData[Variable]

if not Default then
Default = math.Clamp(I * 0.1, -1, 1)
Default = math.Clamp(I * 0.1, ACF.MinGearRatio, ACF.MaxGearRatio)

ValuesData[Variable] = Default
end

ACF.SetClientData(Variable, Default)

local Control = GearBase:AddSlider("Gear " .. I, -1, 1, 2)
local Control = GearBase:AddSlider("Gear " .. I, ACF.MinGearRatio, ACF.MaxGearRatio, 2)
Control:SetClientData(Variable, "OnValueChanged")
Control:DefineSetter(function(Panel, _, _, Value)
Value = math.Round(Value, 2)
Expand All @@ -136,7 +126,7 @@ do -- Default gearbox menus

ACF.SetClientData("FinalDrive", ValuesData.FinalDrive)

local FinalDrive = GearBase:AddSlider("Final Drive", -1, 1, 2)
local FinalDrive = GearBase:AddSlider("Final Drive", ACF.MinGearRatio, ACF.MaxGearRatio, 2)
FinalDrive:SetClientData("FinalDrive", "OnValueChanged")
FinalDrive:DefineSetter(function(Panel, _, _, Value)
Value = math.Round(Value, 2)
Expand All @@ -155,10 +145,10 @@ do -- Default gearbox menus
{
Name = "Gear 2",
Variable = "Gear2",
Min = -1,
Max = 1,
Min = ACF.MinGearRatio,
Max = ACF.MaxGearRatio,
Decimals = 2,
Default = -0.1,
Default = -1,
},
{
Name = "Min Target RPM",
Expand All @@ -179,33 +169,21 @@ do -- Default gearbox menus
{
Name = "Final Drive",
Variable = "FinalDrive",
Min = -1,
Max = 1,
Min = ACF.MinGearRatio,
Max = ACF.MaxGearRatio,
Decimals = 2,
Default = 1,
},
}

function ACF.CVTGearboxMenu(Class, Data, Menu, Base)
local Text = "Mass : %s\nTorque Rating : %s n/m - %s fl-lb\n"
local Mass = ACF.GetProperMass(Data.Mass)
local Torque = math.floor(Data.MaxTorque * 0.73)

Base:AddLabel(Text:format(Mass, Data.MaxTorque, Torque))

if Data.DualClutch then
Base:AddLabel("The dual clutch allows you to apply power and brake each side independently.")
end

-----------------------------------

function ACF.CVTGearboxMenu(Class, _, Menu, _)
local GearBase = Menu:AddCollapsible("Gear Settings")

Values[Class.ID] = Values[Class.ID] or {}

local ValuesData = Values[Class.ID]

ACF.SetClientData("Gear1", 0.01)
ACF.SetClientData("Gear1", 1)

for _, GearData in ipairs(CVTData) do
local Variable = GearData.Variable
Expand Down Expand Up @@ -240,16 +218,16 @@ do -- Default gearbox menus
{
Name = "Reverse Gear",
Variable = "Reverse",
Min = -1,
Max = 1,
Min = ACF.MinGearRatio,
Max = ACF.MaxGearRatio,
Decimals = 2,
Default = -0.1,
Default = -1,
},
{
Name = "Final Drive",
Variable = "FinalDrive",
Min = -1,
Max = 1,
Min = ACF.MinGearRatio,
Max = ACF.MaxGearRatio,
Decimals = 2,
Default = 1,
},
Expand All @@ -268,7 +246,7 @@ do -- Default gearbox menus
{
Name = "Total Ratio",
Variable = "TotalRatio",
Tooltip = "Total ratio is the ratio of all gearboxes (exluding this one) multiplied together.\nFor example, if you use engine to automatic to diffs to wheels, your total ratio would be (diff gear ratio * diff final ratio).",
Tooltip = "Total ratio is the ratio of all gearboxes (excluding this one) multiplied together.\nFor example, if you use engine to automatic to diffs to wheels, your total ratio would be (diff gear ratio * diff final ratio).",
Min = 0,
Max = 1,
Decimals = 2,
Expand All @@ -285,20 +263,8 @@ do -- Default gearbox menus
},
}

function ACF.AutomaticGearboxMenu(Class, Data, Menu, Base)
local Text = "Mass : %s\nTorque Rating : %s n/m - %s fl-lb\n"
local Mass = ACF.GetProperMass(Data.Mass)
local Gears = Class.Gears
local Torque = math.floor(Data.MaxTorque * 0.73)

Base:AddLabel(Text:format(Mass, Data.MaxTorque, Torque))

if Data.DualClutch then
Base:AddLabel("The dual clutch allows you to apply power and brake each side independently.")
end

-----------------------------------

function ACF.AutomaticGearboxMenu(Class, _, Menu, _)
local Gears = Class.CanSetGears and ACF.GetClientNumber("GearAmount", 3) or Class.Gears.Max
local GearBase = Menu:AddCollapsible("Gear Settings")

Values[Class.ID] = Values[Class.ID] or {}
Expand All @@ -319,7 +285,7 @@ do -- Default gearbox menus

local Delta = UnitMult / Mult

for I = 1, Gears.Max do
for I = 1, Gears do
local Var = "Shift" .. I
local Old = ACF.GetClientNumber(Var)

Expand All @@ -331,19 +297,19 @@ do -- Default gearbox menus
UnitMult = Mult
end

for I = 1, Gears.Max do
for I = 1, Gears do
local GearVar = "Gear" .. I
local DefGear = ValuesData[GearVar]

if not DefGear then
DefGear = math.Clamp(I * 0.1, -1, 1)
DefGear = math.Clamp(I * 0.1, ACF.MinGearRatio, ACF.MaxGearRatio)

ValuesData[GearVar] = DefGear
end

ACF.SetClientData(GearVar, DefGear)

local Gear = GearBase:AddSlider("Gear " .. I, -1, 1, 2)
local Gear = GearBase:AddSlider("Gear " .. I, ACF.MinGearRatio, ACF.MaxGearRatio, 2)
Gear:SetClientData(GearVar, "OnValueChanged")
Gear:DefineSetter(function(Panel, _, _, Value)
Value = math.Round(Value, 2)
Expand Down Expand Up @@ -450,7 +416,7 @@ do -- Default gearbox menus
local WheelDiameter = ValuesData.WheelDiameter
local Multiplier = math.pi * UpshiftRPM * TotalRatio * FinalDrive * WheelDiameter / (60 * UnitMult)

for I = 1, Gears.Max do
for I = 1, Gears do
local Gear = ValuesData["Gear" .. I]

ACF.SetClientData("Shift" .. I, Gear * Multiplier)
Expand Down
24 changes: 24 additions & 0 deletions lua/acf/core/utilities/util_sh.lua
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,30 @@ do -- Mobility functions
Class.RPM.PeakMin = math.Round(PowerbandMinRPM, -1)
Class.RPM.PeakMax = math.Round(PowerbandMaxRPM, -1)
end

--- Processes the stats of a gearbox into formatted mass and torque formats.
--- @param BaseMass number The mass value as a number to be formatted into a string
--- @param Scale number The scale value of the gearbox
--- @param MaxTorque number The maximum torque value of the gearbox
--- @param GearCount number The number of gears present in the gearbox
--- @return string # The mass of the gearbox formatted cleanly with units
--- @return number # The torque value of the gearbox in fl-lb
--- @return number # The torque rating of the gearbox in N/m
function ACF.GetGearboxStats(BaseMass, Scale, MaxTorque, GearCount)
local Mass = ACF.GetProperMass(BaseMass * (Scale ^ ACF.GearboxMassScale))

-- Torque calculations
local Torque, TorqueRating = 0, 0

if MaxTorque and GearCount then
local TorqueLoss = MaxTorque * (ACF.GearEfficiency ^ GearCount)
local ScalingCurve = Scale ^ ACF.GearboxTorqueScale
TorqueRating = math.floor((TorqueLoss * ScalingCurve) / 10) * 10
Torque = math.Round(TorqueRating * 0.73)
end

return Mass, Torque, TorqueRating
end
end

do -- Unit conversion
Expand Down
Loading
Loading