-- @include ../libs/constants.txt require('../libs/constants.txt') Engine = class('Engine') function Engine:initialize(options) options = options or {} self.idleRPM = options.IdleRPM or 800 self.maxRPM = options.MaxRPM or 8000 self.flywheelMass = options.FlywheelMass or 4 self.flywheelRadius = options.FlywheelRadius or 0.3 self.startFriction = options.StartFriction or -30 self.frictionCoeff = options.FrictionCoeff or 0.02 self.limiterDuration = options.LimiterDuration or 0.05 self.torqueMap = options.TorqueMap or {} self.throttle = 0 self.torque = 0 self.rpmFrac = 0 self.rpm = self.idleRPM self.friction = 0 self._fwInertia = self.flywheelMass * self.flywheelRadius ^ 2 / 2 self._limiterTime = 0 self._clutch = nil end function Engine:setThrottle(throttle) self.throttle = throttle end function Engine:linkClutch(clutch) self._clutch = clutch clutch:linkEngine(self) end function Engine:update() self.rpmFrac = math.clamp((self.rpm - self.idleRPM) / (self.maxRPM - self.idleRPM), 0, 1) self.friction = self.startFriction - self.rpm * self.frictionCoeff local tqIdx = math.clamp(math.floor(self.rpmFrac * #self.torqueMap), 1, #self.torqueMap) local maxInitialTorque = self.torqueMap[tqIdx] - self.friction local idleFadeStart = math.clamp(math.remap(self.rpm, self.idleRPM - 300, self.idleRPM, 1, 0), 0, 1) local idleFadeEnd = math.clamp(math.remap(self.rpm, self.idleRPM, self.idleRPM + 600, 1, 0), 0, 1) local additionalEnergySupply = idleFadeEnd * (-self.friction / maxInitialTorque) + idleFadeStart if self.rpm > self.maxRPM then self.throttle = 0 self._limiterTime = timer.systime() else self.throttle = timer.systime() >= self._limiterTime + self.limiterDuration and self.throttle or 0 end local masterThrottle = math.clamp(additionalEnergySupply + self.throttle, 0, 1) local realInitialTorque = maxInitialTorque * masterThrottle local loadTorque = self._clutch and self._clutch.torque or 0 self.torque = realInitialTorque + self.friction self.rpm = self.rpm + (self.torque - loadTorque) / self._fwInertia * RAD_TO_RPM * TICK_INTERVAL self.rpm = math.max(self.rpm, 0) end