119 lines
3.2 KiB
Plaintext
119 lines
3.2 KiB
Plaintext
-- @include ./math.txt
|
|
require("./math.txt")
|
|
|
|
Engine = class("Engine")
|
|
|
|
function Engine:initialize()
|
|
self.config = {}
|
|
|
|
if SERVER then
|
|
self.active = true
|
|
|
|
self.desiredRPM = 0
|
|
self.RPM = 0
|
|
|
|
self.throttle = 0
|
|
|
|
self.flywheelInertiaMoment = 0
|
|
self.volume = 0
|
|
self.peakTq = 0
|
|
self.torque = 0
|
|
self.power = 0
|
|
|
|
self.gearboxRPM = 0
|
|
|
|
self.torqueTable = {}
|
|
end
|
|
end
|
|
|
|
if SERVER then
|
|
|
|
function Engine:setThrottle(throttle)
|
|
self.throttle = throttle
|
|
end
|
|
|
|
function Engine:update()
|
|
-- check if config table is not empty
|
|
if next(self.config) ~= nil then
|
|
local activeCoeff = self.active and 1 or 0
|
|
|
|
self.desiredRPM = self.throttle * self.config.maxRPM + self.config.idleRPM
|
|
|
|
local masterThrottle = activeCoeff * self.RPM > self.config.maxRPM and 0 or 1
|
|
|
|
self.RPM = math.lerp(1 / (self.flywheelInertiaMoment * 100), self.RPM, self.desiredRPM * masterThrottle)
|
|
|
|
self:calculateTorque()
|
|
end
|
|
|
|
end
|
|
|
|
function Engine:updateStats()
|
|
local bore = self.config.bore
|
|
local stroke = self.config.stroke
|
|
local flywheelMass = self.config.flywheelMass
|
|
local cylinders = self.config.cylinders
|
|
local BMEP = self.config.BMEP
|
|
|
|
self.flywheelInertiaMoment = (stroke / 1000) * flywheelMass
|
|
|
|
self.volume = math.floor((bore / 2) ^ 2 * stroke * cylinders * math.pi / 1000)
|
|
|
|
self.peakTq = (stroke / bore) * self.volume * BMEP / 100
|
|
|
|
self.torqueTable = {}
|
|
|
|
for i = 1, #self.config.curve do
|
|
table.insert(self.torqueTable, self:getTorqueValue(i / #self.config.curve))
|
|
end
|
|
|
|
print("Peak Torque: " .. math.ceil(self.peakTq) .. "nm")
|
|
end
|
|
|
|
function Engine:calculateTorque()
|
|
local RPMfrac = math.min(1, self.RPM / self.config.maxRPM)
|
|
local tableCount = table.count(self.torqueTable)
|
|
|
|
local lerpTo = math.ceil(RPMfrac * tableCount)
|
|
local lerpFrom = math.floor(RPMfrac * tableCount)
|
|
|
|
local lerpToVal = self.torqueTable[lerpTo] or 0
|
|
local lerpFromVal = self.torqueTable[lerpFrom] or 0
|
|
|
|
local frac = (RPMfrac * tableCount) % 1
|
|
local minActiveThrottle = self.config.idleRPM / self.config.maxRPM
|
|
|
|
local value = math.lerp(frac, lerpFromVal, lerpToVal) * self.peakTq
|
|
|
|
local overdrive = math.clamp(1 - self.gearboxRPM / self.desiredRPM, -1, 0)
|
|
|
|
local idleRPM = self.config.idleRPM
|
|
local maxRPM = self.config.maxRPM
|
|
local brakeTorqueCoeff = self.config.brakeTorqueCoeff
|
|
|
|
local RPMLimiter = math.clamp(1 - self.throttle * (self.gearboxRPM / self.desiredRPM), self.throttle, 1)
|
|
local netTq = value * math.max(self.throttle, idleRPM / maxRPM) * RPMLimiter
|
|
|
|
self.torque = netTq
|
|
end
|
|
|
|
function Engine:getTorqueValue(num)
|
|
local torque = 0
|
|
|
|
for key, segment in pairs(self.config.curve) do
|
|
torque = torque + segment * polinom(key, table.count(self.config.curve), num)
|
|
end
|
|
|
|
return torque
|
|
end
|
|
|
|
end
|
|
|
|
function Engine:setConfig(config)
|
|
self.config = config
|
|
|
|
if SERVER then
|
|
self:updateStats()
|
|
end
|
|
end
|