2023-05-22 22:35:45 +03:00

137 lines
4.0 KiB
Plaintext

--@include ./powertrain_component.txt
--@include ../wheel/wheel.txt
--@include /koptilnya/libs/constants.txt
--@include /koptilnya/libs/entity.txt
local PowertrainComponent = require('./powertrain_component.txt')
local CustomWheel = require('../wheel/wheel.txt')
require('/koptilnya/libs/constants.txt')
require('/koptilnya/libs/entity.txt')
local Wheel = class('Wheel', PowertrainComponent)
function Wheel:initialize(vehicle, name, config)
PowertrainComponent.initialize(self, vehicle, name, config)
self.steerLock = config.SteerLock or 0
self.brakePower = config.BrakePower or 0
self.handbrakePower = config.HandbrakePower or 0
self.rotationAxle = config.RotationAxle or Angle(0, 0, 1)
self.wireInputs = {
[self.name] = 'entity'
}
self.wireOutputs = {
[string.format('%s_RPM', self.name)] = 'number',
[string.format('%s_Mz', self.name)] = 'number',
[string.format('%s_Fz', self.name)] = 'number',
}
self.rot = 0
self.offset = config.Offset or 0
self.entity = config.Entity or NULL_ENTITY
self.holo = self:createHolo(self.entity)
self.customWheel = CustomWheel:new(config.CustomWheel)
hook.add('input', 'vehicle_wheel_update' .. self.name, function(name, value)
if name == self.name then
self.entity = value
self.customWheel:setEntity(value)
if isValid(self.holo) then
self.holo:remove()
end
self.holo = self:createHolo(self.entity)
if not config.Radius then
self.customWheel.radius = self:getEntityRadius()
end
end
end)
local right = self.entity:getRight()
local offsetRight = self.entity:getRight():rotateAroundAxis(self.entity:getUp(), self.offset)
self.dir = right:dot(offsetRight)
end
function Wheel:getEntityRadius()
if not isValid(self.entity) then
return 0
end
return self.entity:getModelRadius() * UNITS_TO_METERS
end
function Wheel:createHolo(entity)
if not isValid(entity) then
return NULL_ENTITY
end
local holo = holograms.create(
entity:getPos(),
entity:getAngles() + Angle(0, self.offset, 0),
self.CONFIG.Model or ''
)
holo:setParent(entity)
entity:setColor(Color(0,0,0,0))
return holo
end
function Wheel:updateWireOutputs()
wire.ports[string.format('%s_RPM', self.name)] = self.customWheel:getRPM()
wire.ports[string.format('%s_Mz', self.name)] = self.customWheel.mz
wire.ports[string.format('%s_Fz', self.name)] = self.customWheel.load
end
function Wheel:queryInertia()
return self.customWheel.inertia
end
function Wheel:queryAngularVelocity()
return self.angularVelocity
end
function Wheel:forwardStep(torque, inertia)
if not isValid(self.customWheel) then
return 0
end
self.customWheel.steerAngle = self.vehicle.steer * self.steerLock
--self.customWheel.inertia = inertia
--self.customWheel:setInertia(inertia)
self.customWheel.motorTorque = torque
self.customWheel.brakeTorque = math.max(self.brakePower * self.vehicle.brake, self.handbrakePower * self.vehicle.handbrake)
self.customWheel:update()
self.angularVelocity = self.customWheel.angularVelocity
if self.customWheel.hasHit and isValid(self.vehicle.basePhysObject) then
local surfaceForceVector = self.customWheel.right * self.customWheel.sideFriction.force + self.customWheel.forward * self.customWheel.forwardFriction.force
self.vehicle.basePhysObject:applyForceOffset(surfaceForceVector, self.entity:getPos() - Vector(0, 0, self.customWheel.radius))
end
if isValid(self.holo) then
self.rot = self.rot + math.deg(self.angularVelocity) * TICK_INTERVAL * self.dir
local steerAngle = self.entity:localToWorldAngles(Angle(0, self.offset - self.customWheel.steerAngle, 0) + self.rotationAxle * self.rot)
local angle = steerAngle
self.holo:setAngles(angle)
end
return self.customWheel.counterTorque
end
return Wheel