87 lines
2.4 KiB
Plaintext
87 lines
2.4 KiB
Plaintext
-- @include ./wire_component.txt
|
|
-- @include /koptilnya/libs/constants.txt
|
|
require('./wire_component.txt')
|
|
require('/koptilnya/libs/constants.txt')
|
|
|
|
Engine = class('Engine', WireComponent)
|
|
|
|
function Engine:initialize(config, clutch)
|
|
self.idleRPM = config.IdleRPM
|
|
self.maxRPM = config.MaxRPM
|
|
|
|
self.flywheelMass = config.FlywheelMass
|
|
self.flywheelRadius = config.FlywheelRadius
|
|
|
|
self.startFriction = config.StartFriction
|
|
self.frictionCoeff = config.FrictionCoeff
|
|
|
|
self.torque = 0
|
|
self.rpmFrac = 0
|
|
self.rpm = self.idleRPM
|
|
self.friction = 0
|
|
|
|
self.limiterDuration = config.LimiterDuration
|
|
|
|
self.torqueMap = config.TorqueMap or {}
|
|
|
|
self._fwInertia = self.flywheelMass * self.flywheelRadius ^ 2 / 2
|
|
self._limiterTime = 0
|
|
|
|
self._clutch = clutch
|
|
end
|
|
|
|
function Engine:getInputs()
|
|
return {
|
|
Throttle = 'number'
|
|
}
|
|
end
|
|
|
|
function Engine:getOutputs()
|
|
return {
|
|
RPM = 'number',
|
|
Torque = 'number'
|
|
}
|
|
end
|
|
|
|
function Engine:updateOutputs()
|
|
wire.ports.RPM = self.rpm
|
|
wire.ports.Torque = self.torque
|
|
end
|
|
|
|
function Engine:getThrottle()
|
|
return wire.ports.Throttle
|
|
end
|
|
|
|
function Engine:update()
|
|
local throttle = self:getThrottle()
|
|
|
|
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
|
|
throttle = 0
|
|
self._limiterTime = timer.systime()
|
|
else
|
|
throttle = timer.systime() >= self._limiterTime + self.limiterDuration and throttle or 0
|
|
end
|
|
|
|
local masterThrottle = math.clamp(additionalEnergySupply + 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
|