2021-11-13 00:09:13 +03:00

91 lines
2.6 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.masterThrottle = 0
self.limiterDuration = config.LimiterDuration
self.torqueMap = config.TorqueMap or {}
self._fwInertia = self.flywheelMass * self.flywheelRadius ^ 2 / 2
self._limiterTime = 0
self.clutch = clutch
clutch:linkEngine(self)
end
function Engine:getInputs()
return {
Throttle = 'number'
}
end
function Engine:getOutputs()
return {
Engine_RPM = 'number',
Engine_Torque = 'number',
Engine_MasterThrottle = 'number'
}
end
function Engine:updateOutputs()
wire.ports.Engine_RPM = self.rpm
wire.ports.Engine_Torque = self.torque
wire.ports.Engine_MasterThrottle = self.masterThrottle
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
self.masterThrottle = math.clamp(additionalEnergySupply + throttle, 0, 1)
local realInitialTorque = maxInitialTorque * self.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