diff --git a/koptilnya/suspension/main.txt b/koptilnya/suspension/main.txt new file mode 100644 index 0000000..e113dd3 --- /dev/null +++ b/koptilnya/suspension/main.txt @@ -0,0 +1,99 @@ +--@name apply force suspension +--@author Koptilnya1337 +--@shared + + local _restLength = 26.0 + local _springTravel = 20.0 + local _springStiffness = 35000 + local _compressionDamper = 140000 -- 45000 + local _reboundDamper = 35000 -- 196000 + local _maxForce = 500000 + + local _minLength = 0 + local _maxLength = 0 + local _lastLength = 0 + local _springLength = 0 + local _springVelocity = 0 + local _springForce = 0 + local _damperForce = 0 + +if SERVER then + wire.adjustInputs( + { + 'Wheel1', + 'Wheel2', + 'Wheel3', + 'Wheel4', + 'Strut1', + 'Strut2', + 'Strut3', + 'Strut4', + 'Base' + }, + { + 'entity', + 'entity', + 'entity', + 'entity', + 'entity', + 'entity', + 'entity', + 'entity', + 'entity' + } + ) + + local wheel1 = wire.ports.Wheel1 + local wheel2 = wire.ports.Wheel2 + local wheel3 = wire.ports.Wheel3 + local wheel4 = wire.ports.Wheel4 + + local strut1 = wire.ports.Strut1 + local strut2 = wire.ports.Strut2 + local strut3 = wire.ports.Strut3 + local strut4 = wire.ports.Strut4 + + local wheels = { wheel1, wheel2, wheel3, wheel4 } + local struts = { strut1, strut2, strut3, strut4 } + + local base = wire.ports.Base + + function handleWheel(base, wheel, strut) + local lastLength = 0 + + return function () + if not base:isValid() then return end + if not wheel:isValid() then return end + if not strut:isValid() then return end + + local distance = strut:getPos():getDistance(wheel:getPos()) - _restLength + local strutToWheelDirection = (strut:getPos() - wheel:getPos()):setX(0):setY(0):getNormalized() + local springVelocity = (distance - lastLength) + + local usedDamper = springVelocity > 0 and _compressionDamper or _reboundDamper + local spring = distance * _springStiffness + local dampener = springVelocity * usedDamper + + local force = math.clamp((spring + dampener) * game.getTickInterval(), -_maxForce, _maxForce) + local direction = (strut:getPos() - wheel:getPos()):getNormalized() --base:getUp() + + lastLength = distance + + base:applyForceOffset(-force * direction, wheel:getPos()) + wheel:applyForceCenter(force * direction * strutToWheelDirection) + end + end + + local wheelHandlers = {} + + for idx, wheel in ipairs(wheels) do + table.insert(wheelHandlers, handleWheel(base, wheel, struts[idx])) + end + + hook.add('tick', 'runtime', function() + for _, handler in ipairs(wheelHandlers) do + handler() + end + end) + +end \ No newline at end of file