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