Finalized
This commit is contained in:
@@ -13,6 +13,7 @@ local LANDTRAIN_SAVED_POS_X_KEY = "landtrainSavedPosX"
|
|||||||
local LANDTRAIN_SAVED_POS_Y_KEY = "landtrainSavedPosY"
|
local LANDTRAIN_SAVED_POS_Y_KEY = "landtrainSavedPosY"
|
||||||
local LANDTRAIN_SAVED_POS_Z_KEY = "landtrainSavedPosZ"
|
local LANDTRAIN_SAVED_POS_Z_KEY = "landtrainSavedPosZ"
|
||||||
local LANDTRAIN_SAVED_DIR_KEY = "landtrainSavedDir"
|
local LANDTRAIN_SAVED_DIR_KEY = "landtrainSavedDir"
|
||||||
|
local LANDTRAIN_ATTACHMENT_BASE_OFFSETS = {}
|
||||||
|
|
||||||
local function emitLandtrainLog(line)
|
local function emitLandtrainLog(line)
|
||||||
print(line)
|
print(line)
|
||||||
@@ -48,6 +49,42 @@ local function hasAttachmentById(vehicle, attachmentId)
|
|||||||
return script:getAttachmentById(attachmentId) ~= nil
|
return script:getAttachmentById(attachmentId) ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function isUsableAttachmentPair(towingVehicle, towedVehicle, attachmentA, attachmentB)
|
||||||
|
if attachmentA == nil or attachmentB == nil or attachmentA == attachmentB then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return hasAttachmentById(towingVehicle, attachmentA) and hasAttachmentById(towedVehicle, attachmentB)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getAttachmentBaseOffsetKey(script, attachmentId)
|
||||||
|
if script == nil or attachmentId == nil then return nil end
|
||||||
|
local scriptName = script.getName and script:getName() or tostring(script)
|
||||||
|
return tostring(scriptName) .. "|" .. tostring(attachmentId)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function cacheAttachmentBaseOffset(script, attachmentId)
|
||||||
|
local key = getAttachmentBaseOffsetKey(script, attachmentId)
|
||||||
|
if key == nil or LANDTRAIN_ATTACHMENT_BASE_OFFSETS[key] ~= nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local attachment = script and script:getAttachmentById(attachmentId) or nil
|
||||||
|
if attachment == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local offset = attachment:getOffset()
|
||||||
|
LANDTRAIN_ATTACHMENT_BASE_OFFSETS[key] = {
|
||||||
|
x = offset:x(),
|
||||||
|
y = offset:y(),
|
||||||
|
z = offset:z()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getAttachmentBaseOffset(script, attachmentId)
|
||||||
|
local key = getAttachmentBaseOffsetKey(script, attachmentId)
|
||||||
|
if key == nil then return nil end
|
||||||
|
return LANDTRAIN_ATTACHMENT_BASE_OFFSETS[key]
|
||||||
|
end
|
||||||
|
|
||||||
local function getTowbarStyleAttachmentPair(towingVehicle, towedVehicle)
|
local function getTowbarStyleAttachmentPair(towingVehicle, towedVehicle)
|
||||||
local attachmentA = nil
|
local attachmentA = nil
|
||||||
local attachmentB = nil
|
local attachmentB = nil
|
||||||
@@ -133,20 +170,73 @@ local function chooseLandtrainAttachmentPair(towingVehicle, towedVehicle, prefer
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function chooseLandtrainTowbarPair(towingVehicle, towedVehicle, preferredA, preferredB)
|
local function chooseLandtrainTowbarPair(towingVehicle, towedVehicle, preferredA, preferredB)
|
||||||
local towbarA, towbarB = getTowbarStyleAttachmentPair(towingVehicle, towedVehicle)
|
if isUsableAttachmentPair(towingVehicle, towedVehicle, preferredA, preferredB) then
|
||||||
if towbarA ~= towbarB and hasAttachmentById(towingVehicle, towbarA) and hasAttachmentById(towedVehicle, towbarB) then
|
|
||||||
return towbarA, towbarB
|
|
||||||
end
|
|
||||||
|
|
||||||
if preferredA ~= nil and preferredB ~= nil and preferredA ~= preferredB
|
|
||||||
and hasAttachmentById(towingVehicle, preferredA)
|
|
||||||
and hasAttachmentById(towedVehicle, preferredB) then
|
|
||||||
return preferredA, preferredB
|
return preferredA, preferredB
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Match Towbar's load reapply pair selection before Landtrain-specific fallbacks.
|
||||||
|
local towbarA = (towingVehicle and towingVehicle:getTowAttachmentSelf()) or "trailer"
|
||||||
|
local towbarB = (towedVehicle and towedVehicle:getTowAttachmentSelf()) or "trailerfront"
|
||||||
|
if isUsableAttachmentPair(towingVehicle, towedVehicle, towbarA, towbarB) then
|
||||||
|
return towbarA, towbarB
|
||||||
|
end
|
||||||
|
|
||||||
|
local styleA, styleB = getTowbarStyleAttachmentPair(towingVehicle, towedVehicle)
|
||||||
|
if isUsableAttachmentPair(towingVehicle, towedVehicle, styleA, styleB) then
|
||||||
|
return styleA, styleB
|
||||||
|
end
|
||||||
|
|
||||||
return chooseLandtrainAttachmentPair(towingVehicle, towedVehicle, preferredA, preferredB)
|
return chooseLandtrainAttachmentPair(towingVehicle, towedVehicle, preferredA, preferredB)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function clearChangedTowedAttachmentOffset(vehicle)
|
||||||
|
if vehicle == nil then return end
|
||||||
|
local modData = vehicle:getModData()
|
||||||
|
if modData == nil or modData["isChangedTowedAttachment"] ~= true then return end
|
||||||
|
|
||||||
|
local script = vehicle:getScript()
|
||||||
|
local changedAttachmentId = modData["towBarChangedAttachmentId"]
|
||||||
|
if changedAttachmentId == nil and vehicle.getTowAttachmentSelf then
|
||||||
|
changedAttachmentId = vehicle:getTowAttachmentSelf()
|
||||||
|
end
|
||||||
|
|
||||||
|
if script ~= nil and changedAttachmentId ~= nil then
|
||||||
|
cacheAttachmentBaseOffset(script, changedAttachmentId)
|
||||||
|
local baseOffset = getAttachmentBaseOffset(script, changedAttachmentId)
|
||||||
|
local towedAttachment = script:getAttachmentById(changedAttachmentId)
|
||||||
|
if towedAttachment ~= nil then
|
||||||
|
if baseOffset ~= nil then
|
||||||
|
towedAttachment:getOffset():set(baseOffset.x, baseOffset.y, baseOffset.z)
|
||||||
|
else
|
||||||
|
local offset = towedAttachment:getOffset()
|
||||||
|
local storedShift = tonumber(modData["towBarChangedOffsetZShift"])
|
||||||
|
if storedShift ~= nil then
|
||||||
|
towedAttachment:getOffset():set(offset:x(), offset:y(), offset:z() - storedShift)
|
||||||
|
else
|
||||||
|
local zShift = offset:z() > 0 and -1 or 1
|
||||||
|
towedAttachment:getOffset():set(offset:x(), offset:y(), offset:z() + zShift)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
modData["isChangedTowedAttachment"] = false
|
||||||
|
modData["towBarChangedAttachmentId"] = nil
|
||||||
|
modData["towBarChangedOffsetZShift"] = nil
|
||||||
|
vehicle:transmitModData()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateAttachmentsForRigidTowNoStack(towingVehicle, towedVehicle, attachmentA, attachmentB)
|
||||||
|
if TowBarMod == nil or TowBarMod.Utils == nil or TowBarMod.Utils.updateAttachmentsForRigidTow == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local towedScript = towedVehicle and towedVehicle:getScript() or nil
|
||||||
|
cacheAttachmentBaseOffset(towedScript, attachmentB)
|
||||||
|
clearChangedTowedAttachmentOffset(towedVehicle)
|
||||||
|
TowBarMod.Utils.updateAttachmentsForRigidTow(towingVehicle, towedVehicle, attachmentA, attachmentB)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
local function dumpTowState(prefix, vehicle)
|
local function dumpTowState(prefix, vehicle)
|
||||||
if not LANDTRAIN_DEBUG then return end
|
if not LANDTRAIN_DEBUG then return end
|
||||||
if vehicle == nil then
|
if vehicle == nil then
|
||||||
@@ -287,7 +377,9 @@ local function storeLandtrainFrontLinkData(towingVehicle, towedVehicle, attachme
|
|||||||
towingModData[LANDTRAIN_REAR_SQL_ID_KEY] = nil
|
towingModData[LANDTRAIN_REAR_SQL_ID_KEY] = nil
|
||||||
end
|
end
|
||||||
towingVehicle:transmitModData()
|
towingVehicle:transmitModData()
|
||||||
local resolvedA, resolvedB = chooseLandtrainTowbarPair(towingVehicle, towedVehicle, attachmentA, attachmentB)
|
local preferredA = attachmentA or towedModData[LANDTRAIN_FRONT_ATTACHMENT_A_KEY]
|
||||||
|
local preferredB = attachmentB or towedModData[LANDTRAIN_FRONT_ATTACHMENT_B_KEY]
|
||||||
|
local resolvedA, resolvedB = chooseLandtrainTowbarPair(towingVehicle, towedVehicle, preferredA, preferredB)
|
||||||
towedModData[LANDTRAIN_FRONT_ATTACHMENT_A_KEY] = resolvedA
|
towedModData[LANDTRAIN_FRONT_ATTACHMENT_A_KEY] = resolvedA
|
||||||
towedModData[LANDTRAIN_FRONT_ATTACHMENT_B_KEY] = resolvedB
|
towedModData[LANDTRAIN_FRONT_ATTACHMENT_B_KEY] = resolvedB
|
||||||
towedVehicle:transmitModData()
|
towedVehicle:transmitModData()
|
||||||
@@ -737,7 +829,7 @@ local function attachSavedLandtrainLink(playerObj, link, delayTicks)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local originalScriptName = rearVehicle:getScriptName()
|
local originalScriptName = rearVehicle:getScriptName()
|
||||||
TowBarMod.Utils.updateAttachmentsForRigidTow(frontVehicle, rearVehicle, link.attachmentA, link.attachmentB)
|
updateAttachmentsForRigidTowNoStack(frontVehicle, rearVehicle, link.attachmentA, link.attachmentB)
|
||||||
rearVehicle:setScriptName("notTowingA_Trailer")
|
rearVehicle:setScriptName("notTowingA_Trailer")
|
||||||
local args = {
|
local args = {
|
||||||
vehicleA = frontVehicle:getId(),
|
vehicleA = frontVehicle:getId(),
|
||||||
@@ -971,7 +1063,10 @@ local function captureTowbarFrontLink(towingVehicle)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local attachmentA, attachmentB = chooseLandtrainTowbarPair(frontVehicle, towingVehicle, nil, nil)
|
local towingModData = towingVehicle:getModData()
|
||||||
|
local savedAttachmentA = towingModData and towingModData[LANDTRAIN_FRONT_ATTACHMENT_A_KEY] or nil
|
||||||
|
local savedAttachmentB = towingModData and towingModData[LANDTRAIN_FRONT_ATTACHMENT_B_KEY] or nil
|
||||||
|
local attachmentA, attachmentB = chooseLandtrainTowbarPair(frontVehicle, towingVehicle, savedAttachmentA, savedAttachmentB)
|
||||||
local link = {
|
local link = {
|
||||||
frontVehicle = frontVehicle,
|
frontVehicle = frontVehicle,
|
||||||
towingVehicle = towingVehicle,
|
towingVehicle = towingVehicle,
|
||||||
@@ -1005,7 +1100,7 @@ local function restoreTowbarFrontLink(playerObj, link)
|
|||||||
end
|
end
|
||||||
|
|
||||||
ltLog("restoreTowbarFrontLink restoring front=" .. vehLabel(frontVehicle) .. " middle=" .. vehLabel(towingVehicle))
|
ltLog("restoreTowbarFrontLink restoring front=" .. vehLabel(frontVehicle) .. " middle=" .. vehLabel(towingVehicle))
|
||||||
TowBarMod.Utils.updateAttachmentsForRigidTow(frontVehicle, towingVehicle, link.attachmentA, link.attachmentB)
|
updateAttachmentsForRigidTowNoStack(frontVehicle, towingVehicle, link.attachmentA, link.attachmentB)
|
||||||
towingVehicle:setScriptName("notTowingA_Trailer")
|
towingVehicle:setScriptName("notTowingA_Trailer")
|
||||||
|
|
||||||
local args = {
|
local args = {
|
||||||
@@ -1079,6 +1174,22 @@ local function ensureTowAttachmentsForTrailers()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function captureTowbarAttachmentDefaults()
|
||||||
|
local scriptManager = getScriptManager()
|
||||||
|
if scriptManager == nil then return end
|
||||||
|
|
||||||
|
local vehicleScripts = scriptManager:getAllVehicleScripts()
|
||||||
|
if vehicleScripts == nil then return end
|
||||||
|
|
||||||
|
for i = 0, vehicleScripts:size() - 1 do
|
||||||
|
local script = vehicleScripts:get(i)
|
||||||
|
if script ~= nil then
|
||||||
|
cacheAttachmentBaseOffset(script, "trailer")
|
||||||
|
cacheAttachmentBaseOffset(script, "trailerfront")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function menuHasTowbarAttachSlice(menu)
|
local function menuHasTowbarAttachSlice(menu)
|
||||||
if menu == nil or menu.slices == nil then return false end
|
if menu == nil or menu.slices == nil then return false end
|
||||||
local attachAction = TowBarMod and TowBarMod.Hook and TowBarMod.Hook.attachByTowBarAction or nil
|
local attachAction = TowBarMod and TowBarMod.Hook and TowBarMod.Hook.attachByTowBarAction or nil
|
||||||
@@ -1598,7 +1709,9 @@ local function startLandtrainInstallWatchdog()
|
|||||||
end
|
end
|
||||||
|
|
||||||
Events.OnGameBoot.Add(ensureTowAttachmentsForTrailers)
|
Events.OnGameBoot.Add(ensureTowAttachmentsForTrailers)
|
||||||
|
Events.OnGameBoot.Add(captureTowbarAttachmentDefaults)
|
||||||
Events.OnGameBoot.Add(startLandtrainInstallWatchdog)
|
Events.OnGameBoot.Add(startLandtrainInstallWatchdog)
|
||||||
|
Events.OnGameStart.Add(captureTowbarAttachmentDefaults)
|
||||||
Events.OnGameStart.Add(startLandtrainInstallWatchdog)
|
Events.OnGameStart.Add(startLandtrainInstallWatchdog)
|
||||||
Events.OnGameStart.Add(scheduleLandtrainSingleLoadRestore)
|
Events.OnGameStart.Add(scheduleLandtrainSingleLoadRestore)
|
||||||
Events.OnTick.Add(onLandtrainSaveSnapshotTick)
|
Events.OnTick.Add(onLandtrainSaveSnapshotTick)
|
||||||
|
|||||||
Reference in New Issue
Block a user