179 lines
5.3 KiB
Plaintext
179 lines
5.3 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)
|
|
|
|
local DEBUG = false
|
|
|
|
function Wheel:initialize(vehicle, name, config)
|
|
PowertrainComponent.initialize(self, vehicle, name, config)
|
|
|
|
if CLIENT and self.DEBUG then
|
|
local scale = 0.1
|
|
local font = render.createFont("Roboto", 256, 400, true)
|
|
local mat = render.createMaterial('models/debug/debugwhite')
|
|
|
|
|
|
hook.add("PostDrawTranslucentRenderables", "DEBUG_RENDER_" .. self.name, function()
|
|
if next(self.DEBUG_DATA) == nil then return end
|
|
if not isValid(self.DEBUG_DATA.entity) then return end
|
|
|
|
local pos = self.DEBUG_DATA.entity:getPos()
|
|
|
|
render.setMaterial(mat)
|
|
render.setColor(Color(255, 0, 0, 200))
|
|
render.draw3DBeam(pos, pos + (16 * self.DEBUG_DATA.forward), 1, 0, 0)
|
|
|
|
render.setColor(Color(0, 255, 0, 255))
|
|
render.draw3DBeam(pos, pos + (16 * self.DEBUG_DATA.right), 1, 0, 0)
|
|
|
|
render.setColor(Color(0, 0, 255, 200))
|
|
render.draw3DBeam(pos, pos + (16 * self.DEBUG_DATA.up), 1, 0, 0)
|
|
end)
|
|
|
|
if player() == owner() then
|
|
enableHud(nil, true)
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
self.steerLock = config.SteerLock or 0
|
|
self.brakePower = config.BrakePower or 0
|
|
self.handbrakePower = config.HandbrakePower or 0
|
|
|
|
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.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 self.DEBUG then
|
|
self.DEBUG_DATA.entity = self.entity
|
|
end
|
|
|
|
if not config.Radius then
|
|
self.customWheel.radius = self:getEntityRadius()
|
|
end
|
|
end
|
|
end)
|
|
|
|
self.steerVelocity = 0
|
|
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(),
|
|
self.CONFIG.Model or ''
|
|
)
|
|
|
|
holo:setParent(entity)
|
|
|
|
entity:setColor(Color(0,0,0,0))
|
|
|
|
return holo
|
|
end
|
|
|
|
function Wheel:updateWireOutputs()
|
|
PowertrainComponent.updateWireOutputs(self)
|
|
|
|
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
|
|
|
|
-- print(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:localToWorld(Vector(0, 0, -self.entity:getModelRadius())))
|
|
end
|
|
|
|
if isValid(self.holo) then
|
|
if self.DEBUG then
|
|
self.DEBUG_DATA.forward = self.customWheel.forward
|
|
self.DEBUG_DATA.right = self.customWheel.right
|
|
self.DEBUG_DATA.up = self.customWheel.up
|
|
end
|
|
|
|
local entityAngles = self.entity:getAngles()
|
|
|
|
self.rot = self.rot + self.angularVelocity * TICK_INTERVAL
|
|
|
|
local steerRotated = entityAngles:rotateAroundAxis(self.customWheel.up, nil, math.rad(-self.customWheel.steerAngle) + self.customWheel.toeAngle)
|
|
local camberRotated = steerRotated:rotateAroundAxis(self.customWheel.forward, nil, -self.customWheel.camberAngle)
|
|
local angularVelocityRotated = camberRotated:rotateAroundAxis(self.customWheel.right, nil, self.rot)
|
|
|
|
self.holo:setAngles(angularVelocityRotated)
|
|
end
|
|
|
|
return self.customWheel.counterTorque
|
|
end
|
|
|
|
return Wheel
|