42.19 Support

This commit is contained in:
2026-06-01 19:51:40 -04:00
parent 8c0afd857b
commit 40f0296080
3 changed files with 186 additions and 33 deletions
+107 -21
View File
@@ -1,11 +1,88 @@
if not TowBarMod then TowBarMod = {} end
if not TowBarMod.Hook then TowBarMod.Hook = {} end
local TowBarTowMass = 200
local DefaultTowBarTowMass = 200
local AutoReattachCooldownHours = 1 / 7200 -- 0.5 seconds
TowBarMod.Hook.lastAutoReattachAtByVehicle = TowBarMod.Hook.lastAutoReattachAtByVehicle or {}
local AutoReattachPlayerCooldownHours = 1 / 14400 -- 0.25 seconds
TowBarMod.Hook.lastAutoReattachAtByPlayer = TowBarMod.Hook.lastAutoReattachAtByPlayer or {}
local FreeRollTickInterval = 15
local freeRollTickCounter = 0
local function tryVehicleCall(vehicle, methodName, arg)
if not vehicle or not methodName then return false, nil end
local method = vehicle[methodName]
if method == nil then return false, nil end
return pcall(function()
if arg ~= nil then
return method(vehicle, arg)
end
return method(vehicle)
end)
end
local function storeOriginalVehicleCall(vehicle, modData, key, getterName)
if not vehicle or not modData or modData[key] ~= nil then return end
local ok, value = tryVehicleCall(vehicle, getterName)
if ok and value ~= nil then
modData[key] = value
end
end
local function applyFreeRollingTowState(vehicle)
if not vehicle then return end
local modData = vehicle:getModData()
if not modData then return end
if modData.towBarOriginalMass == nil then
modData.towBarOriginalMass = vehicle:getMass()
end
if modData.towBarOriginalBrakingForce == nil then
modData.towBarOriginalBrakingForce = vehicle:getBrakingForce()
end
storeOriginalVehicleCall(vehicle, modData, "towBarOriginalParkingBrakeOn", "isParkingBrakeOn")
storeOriginalVehicleCall(vehicle, modData, "towBarOriginalParkingBrake", "isParkingBrake")
storeOriginalVehicleCall(vehicle, modData, "towBarOriginalHandbrake", "isHandbrake")
local configuredTowMass = TowBarMod.Config and tonumber(TowBarMod.Config.towedVehicleRollingMass)
vehicle:setMass(configuredTowMass or DefaultTowBarTowMass)
vehicle:setBrakingForce(0)
tryVehicleCall(vehicle, "setParkingBrakeOn", false)
tryVehicleCall(vehicle, "setParkingBrake", false)
tryVehicleCall(vehicle, "setHandbrake", false)
tryVehicleCall(vehicle, "setBrake", false)
tryVehicleCall(vehicle, "setBraking", false)
vehicle:constraintChanged()
vehicle:updateTotalMass()
end
local function restoreFreeRollingTowState(vehicle, modData)
if not vehicle or not modData then return end
if modData.towBarOriginalMass ~= nil then
vehicle:setMass(modData.towBarOriginalMass)
end
if modData.towBarOriginalBrakingForce ~= nil then
vehicle:setBrakingForce(modData.towBarOriginalBrakingForce)
end
if modData.towBarOriginalParkingBrakeOn ~= nil then
tryVehicleCall(vehicle, "setParkingBrakeOn", modData.towBarOriginalParkingBrakeOn)
end
if modData.towBarOriginalParkingBrake ~= nil then
tryVehicleCall(vehicle, "setParkingBrake", modData.towBarOriginalParkingBrake)
end
if modData.towBarOriginalHandbrake ~= nil then
tryVehicleCall(vehicle, "setHandbrake", modData.towBarOriginalHandbrake)
end
vehicle:constraintChanged()
vehicle:updateTotalMass()
end
local function isTowBarTowPair(towingVehicle, towedVehicle)
if not towingVehicle or not towedVehicle then return false end
@@ -269,12 +346,7 @@ local function reattachTowBarPair(playerObj, towingVehicle, towedVehicle, requir
TowBarMod.Utils.updateAttachmentsForRigidTow(towingVehicle, towedVehicle, attachmentA, attachmentB)
towedModData.towBarOriginalScriptName = towedModData.towBarOriginalScriptName or towedVehicle:getScriptName()
if towedModData.towBarOriginalMass == nil then
towedModData.towBarOriginalMass = towedVehicle:getMass()
end
if towedModData.towBarOriginalBrakingForce == nil then
towedModData.towBarOriginalBrakingForce = towedVehicle:getBrakingForce()
end
applyFreeRollingTowState(towedVehicle)
towingModData["isTowingByTowBar"] = true
towedModData["isTowingByTowBar"] = true
@@ -376,10 +448,7 @@ function TowBarMod.Hook.setVehiclePostAttach(playerObj, towedVehicle, retriesLef
end
end
towedVehicle:setMass(TowBarTowMass)
towedVehicle:setBrakingForce(0)
towedVehicle:constraintChanged()
towedVehicle:updateTotalMass()
applyFreeRollingTowState(towedVehicle)
-- Re-show the towbar model after the script name has been restored.
-- setScriptName() resets model visibility, so we must set it again here.
@@ -402,8 +471,7 @@ function TowBarMod.Hook.performAttachTowBar(playerObj, towingVehicle, towedVehic
local towedModData = towedVehicle:getModData()
towedModData.towBarOriginalScriptName = towedVehicle:getScriptName()
towedModData.towBarOriginalMass = towedVehicle:getMass()
towedModData.towBarOriginalBrakingForce = towedVehicle:getBrakingForce()
applyFreeRollingTowState(towedVehicle)
towingModData["isTowingByTowBar"] = true
towedModData["isTowingByTowBar"] = true
@@ -438,14 +506,7 @@ function TowBarMod.Hook.performDetachTowBar(playerObj, towingVehicle, towedVehic
if towedModData.towBarOriginalScriptName then
towedVehicle:setScriptName(towedModData.towBarOriginalScriptName)
end
if towedModData.towBarOriginalMass ~= nil then
towedVehicle:setMass(towedModData.towBarOriginalMass)
end
if towedModData.towBarOriginalBrakingForce ~= nil then
towedVehicle:setBrakingForce(towedModData.towBarOriginalBrakingForce)
end
towedVehicle:constraintChanged()
towedVehicle:updateTotalMass()
restoreFreeRollingTowState(towedVehicle, towedModData)
sendClientCommand(playerObj, "towbar", "giveTowBar", { equipPrimary = true })
@@ -456,6 +517,9 @@ function TowBarMod.Hook.performDetachTowBar(playerObj, towingVehicle, towedVehic
towedModData.towBarOriginalScriptName = nil
towedModData.towBarOriginalMass = nil
towedModData.towBarOriginalBrakingForce = nil
towedModData.towBarOriginalParkingBrakeOn = nil
towedModData.towBarOriginalParkingBrake = nil
towedModData.towBarOriginalHandbrake = nil
towingVehicle:transmitModData()
towedVehicle:transmitModData()
@@ -526,6 +590,27 @@ local function forEachCollectionItem(collection, callback)
end
end
local function keepTowBarVehiclesFreeRolling()
freeRollTickCounter = freeRollTickCounter + 1
if freeRollTickCounter < FreeRollTickInterval then
return
end
freeRollTickCounter = 0
local cell = getCell()
if not cell then return end
local vehicles = cell:getVehicles()
if not vehicles then return end
forEachCollectionItem(vehicles, function(vehicle)
local modData = vehicle and vehicle:getModData() or nil
if isActiveTowBarTowedVehicle(vehicle, modData) then
applyFreeRollingTowState(vehicle)
end
end)
end
function TowBarMod.Hook.OnEnterVehicle(character)
tryAutoReattachFromCharacter(character)
end
@@ -716,3 +801,4 @@ if Events.OnGameStart then
end
Events.OnEnterVehicle.Add(TowBarMod.Hook.OnEnterVehicle)
Events.OnSwitchVehicleSeat.Add(TowBarMod.Hook.OnSwitchVehicleSeat)
Events.OnTick.Add(keepTowBarVehiclesFreeRolling)