2021-11-11 22:16:33 +05:00

74 lines
2.2 KiB
Plaintext

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