2021-03-28 18:30:08 +05:00

122 lines
3.4 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.max(minActiveThrottle, self.throttle) * 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 brakeTorque = -value * math.max(1 - self.throttle, idleRPM / maxRPM, -overdrive) *
(self.gearboxRPM / maxRPM) * 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 + brakeTorque
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