74 lines
2.2 KiB
Plaintext
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
|