-- @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