42.20 and Towtrucks
This commit is contained in:
+110
-9
@@ -29,14 +29,23 @@ Assert-True (Test-Path -LiteralPath $releaseRoot) "Missing 42.20 release folder.
|
||||
|
||||
$releaseInfo = Get-Content -LiteralPath (Join-Path $releaseRoot "mod.info")
|
||||
$rootInfo = Get-Content -LiteralPath (Join-Path $repositoryRoot "mod.info")
|
||||
Assert-True ($releaseInfo -contains "id=hrsys_towbars") "42.20 must use the stable mod id."
|
||||
Assert-True ($releaseInfo -contains "id=hrsys_towbars_testing") "42.20 must retain the current testing mod id."
|
||||
Assert-True ($releaseInfo -contains "versionMin=42.20.0") "42.20 must require Build 42.20."
|
||||
Assert-True ($releaseInfo -contains "modversion=1.0.5") "42.20 must declare mod version 1.0.5."
|
||||
Assert-True ($rootInfo -contains "modversion=1.0.5") "Root and release mod versions must match."
|
||||
Assert-True ($releaseInfo -contains "modversion=1.0.12") "42.20 must declare mod version 1.0.12."
|
||||
Assert-True ($rootInfo -contains "modversion=1.0.12") "Root and release mod versions must match."
|
||||
|
||||
$baselineFiles = Get-RelativeFileNames $baselineRoot
|
||||
$releaseFiles = Get-RelativeFileNames $releaseRoot
|
||||
Assert-True (-not (Compare-Object $baselineFiles $releaseFiles)) "42.20 file layout must match the latest baseline."
|
||||
$allowedAdditions = @(
|
||||
"media/lua/client/TowBar/WreckerSyncClient.lua",
|
||||
"media/lua/client/TowBar/WreckerTimedAction.lua",
|
||||
"media/lua/client/TowBar/WreckerUI.lua",
|
||||
"media/lua/server/WreckerCommands.lua",
|
||||
"media/lua/shared/TowBar/Persistence.lua",
|
||||
"media/lua/shared/TowBar/WreckerUtils.lua"
|
||||
)
|
||||
$expectedReleaseFiles = @($baselineFiles) + $allowedAdditions | Sort-Object
|
||||
Assert-True (-not (Compare-Object $expectedReleaseFiles $releaseFiles)) "42.20 file layout must match baseline plus declared wrecker compatibility files."
|
||||
|
||||
foreach ($jsonFile in Get-ChildItem -LiteralPath $releaseRoot -Recurse -Filter "*.json") {
|
||||
try {
|
||||
@@ -52,18 +61,42 @@ $btTowPath = Join-Path $releaseRoot "media/lua/server/BTTow.lua"
|
||||
$clientSyncPath = Join-Path $releaseRoot "media/lua/client/TowBar/TowSyncClient.lua"
|
||||
$hookingPath = Join-Path $releaseRoot "media/lua/client/TowBar/TowingHooking.lua"
|
||||
$towbarTemplatePath = Join-Path $releaseRoot "media/scripts/vehicles/template_towbar.txt"
|
||||
$itemNamePath = Join-Path $releaseRoot "media/lua/shared/Translate/EN/ItemName.json"
|
||||
$persistencePath = Join-Path $releaseRoot "media/lua/shared/TowBar/Persistence.lua"
|
||||
$legacyItemNamePath = Join-Path $repositoryRoot "common/media/lua/shared/Translate/EN/ItemName_EN.txt"
|
||||
$serverCommands = Get-Content -LiteralPath $serverCommandsPath -Raw
|
||||
$btTow = Get-Content -LiteralPath $btTowPath -Raw
|
||||
$clientSync = Get-Content -LiteralPath $clientSyncPath -Raw
|
||||
$hooking = Get-Content -LiteralPath $hookingPath -Raw
|
||||
$towbarTemplate = Get-Content -LiteralPath $towbarTemplatePath -Raw
|
||||
$itemNames = Get-Content -LiteralPath $itemNamePath -Raw | ConvertFrom-Json
|
||||
$persistence = Get-Content -LiteralPath $persistencePath -Raw
|
||||
$legacyItemNames = Get-Content -LiteralPath $legacyItemNamePath -Raw
|
||||
|
||||
$towbarVisualScale = 2.5
|
||||
$towbarBaseScriptScale = 0.01
|
||||
$towbarScaledScriptScale = $towbarBaseScriptScale * $towbarVisualScale
|
||||
$towbarMeasuredLengthAtBaseScale = 0.9714089036
|
||||
$towbarScaledHalfLength = ($towbarMeasuredLengthAtBaseScale * $towbarVisualScale) / 2
|
||||
|
||||
Assert-True ($towbarTemplate -match ('(?s)model towbarModel\s*\{{.*?scale = {0},' -f [regex]::Escape($towbarScaledScriptScale.ToString('0.000', [Globalization.CultureInfo]::InvariantCulture)))) "The normal towbar visual must render at 2.5x its measured 0.01 script scale."
|
||||
Assert-True ($hooking -match 'local TowbarVisualScale = 2\.5') "Client placement must declare the 2.5x visual scale."
|
||||
Assert-True ($btTow -match 'local TowbarVisualScale = 2\.5') "Part initialization must declare the 2.5x visual scale."
|
||||
Assert-True ($hooking -match '(?s)local TowbarScaledModelLength = TowbarModelLength \* TowbarVisualScale.*?local TowbarModelHalfLength = TowbarScaledModelLength / 2') "Client placement must compensate offsets using the scaled mesh length."
|
||||
Assert-True ($btTow -match '(?s)local TowbarScaledModelLength = TowbarModelLength \* TowbarVisualScale.*?local TowbarModelHalfLength = TowbarScaledModelLength / 2') "Part initialization must compensate offsets using the scaled mesh length."
|
||||
Assert-True ([Math]::Abs((0.9714089036 / 2) - ($towbarScaledHalfLength / $towbarVisualScale)) -lt 0.000000001) "Scaling and offset compensation must retain the original mesh-relative half-length contact point."
|
||||
|
||||
$towBarDisplayName = $itemNames.PSObject.Properties["TowBar.TowBar"]
|
||||
Assert-True ($null -ne $towBarDisplayName -and $towBarDisplayName.Value -ceq "Tow Bar") "B42.20 must display TowBar.TowBar as Tow Bar."
|
||||
Assert-True ($null -eq $itemNames.PSObject.Properties["ItemName_TowBar.TowBar"]) "B42 JSON must not use the legacy ItemName_ prefix."
|
||||
Assert-True ($legacyItemNames -match 'ItemName_TowBar\.TowBar\s*=\s*"Tow Bar"') "Legacy translations must retain their prefixed item-name key."
|
||||
|
||||
Assert-True ($serverCommands -match 'detachTrailerSpontaneous') "Server must handle Build 42.20 spontaneous towing detach."
|
||||
Assert-True ($serverCommands -match 'towBarTowedVehicleId') "Server must persist the expected towbar pair."
|
||||
Assert-True ($serverCommands -match '(?s)local function markExpectedTowBarPair.*?towingModData\["towBarTowingVehicleId"\] = nil.*?towedModData\["towBarTowedVehicleId"\] = nil') "Pair marking must clear stale opposite-role IDs."
|
||||
Assert-True ($serverCommands -match '(?s)local function clearExpectedTowBarPair.*?towingModData\["towBarTowedVehicleId"\] = nil.*?towingModData\["towBarTowingVehicleId"\] = nil.*?towedModData\["towBarTowedVehicleId"\] = nil.*?towedModData\["towBarTowingVehicleId"\] = nil') "Pair cleanup must clear both role IDs from both vehicles."
|
||||
Assert-True ($serverCommands -match 'local function isExpectedTowBarPair') "Server must validate reciprocal expected towbar IDs."
|
||||
Assert-True ($serverCommands -match '(?s)isExpectedTowBarPair.*?towBarTowedVehicleId.*?vehicleB:getId\(\).*?towBarTowingVehicleId.*?vehicleA:getId\(\)') "Expected towbar pair validation must be reciprocal."
|
||||
Assert-True ($serverCommands -match '(?s)isExpectedTowBarPair.*?matchesSavedVehicle\(.*?towBarTowedVehicleId.*?towBarTowedVehicleSqlId.*?vehicleB.*?matchesSavedVehicle\(.*?towBarTowingVehicleId.*?towBarTowingVehicleSqlId.*?vehicleA') "Expected towbar pair validation must use reciprocal stable vehicle identities."
|
||||
Assert-True ($serverCommands -match 'local function isLegacyTowBarPair') "Server must isolate legacy pair recovery from stale modern pair IDs."
|
||||
Assert-True ($serverCommands -match '(?s)isLegacyTowBarPair.*?hasTowBarState\(vehicleA\) and hasTowBarState\(vehicleB\).*?towed.*?== true.*?towingModData\["towBarTowedVehicleId"\].*?== nil.*?towingModData\["towBarTowingVehicleId"\].*?== nil.*?towedModData\["towBarTowedVehicleId"\].*?== nil.*?towedModData\["towBarTowingVehicleId"\].*?== nil') "Legacy recovery must require both role markers and no modern pair IDs on either vehicle."
|
||||
Assert-True ($serverCommands -match '(?s)local function resolveExpectedTowBarPair.*?towingVehicle and towedVehicle.*?isExpectedTowBarPair\(towingVehicle, towedVehicle\)') "Current-link spontaneous resolution must still require reciprocal towbar identity."
|
||||
@@ -83,13 +116,30 @@ Assert-True ($serverCommands -match 'if item\.reservedTowBar then') "Failed mult
|
||||
Assert-True ($serverCommands -match 'Constraint creation may complete on a later server tick') "Multiplayer attach must preserve delayed constraint confirmation."
|
||||
Assert-True ($serverCommands -match 'local function finalizeBrokenTowBarPair') "Broken towbar cleanup must use one idempotent finalizer."
|
||||
Assert-True ($serverCommands -match 'local function reconcileBrokenTowBarPairsServer') "Server and single-player must audit confirmed towbar constraints for silent breaks."
|
||||
Assert-True ($serverCommands -match '(?s)local function reconcileBrokenTowBarPairsServer.*?towBarTowedVehicleId.*?getVehicleById.*?isExpectedTowBarPair.*?isLinked.*?markTowBarPairConfirmed.*?isTowBarPairConfirmed.*?finalizeBrokenTowBarPair') "The physical-link audit must confirm reciprocal pairs and finalize a missing constraint."
|
||||
Assert-True ($serverCommands -match '(?s)local function reconcileBrokenTowBarPairsServer.*?Persistence\.advanceRecoveryState.*?RestoreRetryMs, SustainedBreakMs.*?action == "break".*?finalizeBrokenTowBarPair.*?action == "restore".*?restorePersistedTowBarPair') "The physical-link audit must use the shared bounded recovery state machine."
|
||||
Assert-True ($persistence -match '(?s)function Persistence\.advanceRecoveryState.*?state\.unlinkedSince = state\.unlinkedSince or now.*?now - state\.unlinkedSince >= breakMs.*?return state, "break"' -and $persistence -match '(?s)if not state\.pendingUntil or now >= state\.pendingUntil then.*?state\.pendingUntil = now \+ retryMs.*?return state, "restore"') "Persistent-pair recovery must debounce restores and require a sustained break before cleanup."
|
||||
Assert-True ($serverCommands -match '(?s)local function restorePersistedTowBarPair.*?towBarExpectedAttachment.*?addPointConstraint.*?broadcastAttach') "A saved towbar pair must rebuild its physical constraint without consuming another item."
|
||||
Assert-True ($persistence -match '(?s)if not state\.pendingUntil or now >= state\.pendingUntil then.*?return state, "restore"') "An unconfirmed saved pair must schedule a bounded restoration attempt."
|
||||
Assert-True ($clientSync -match 'TowBarMod\.Sync\.applyAttachSync = applyAttachSync') "Single-player must expose the existing attach synchronizer for saved-pair recovery."
|
||||
Assert-True ($clientSync -match '(?s)local key = tostring\(vehicleA:getId\(\)\).*?if TowBarMod\.Sync\.appliedPairs\[key\] and not isLinked\(vehicleA, vehicleB\) then.*?TowBarMod\.Sync\.appliedPairs\[key\] = nil.*?if not TowBarMod\.Sync\.appliedPairs\[key\] then.*?breakTowBarPair\(vehicleA, vehicleB\).*?setVehicleScriptWithTowBarHidden\(vehicleB, "notTowingA_Trailer"\).*?addPointConstraint\(nil, vehicleB, attachmentA, attachmentB, true\)') "Every fresh or recovered towbar pair must replace the native rope with one local rigid constraint."
|
||||
Assert-True ($clientSync -notmatch '(?s)if linked then\s*--.*?appliedPairs\[key\] = true') "A newly observed native tow link must not be accepted as rigid without rebuilding it."
|
||||
Assert-True ($clientSync -match '(?s)local function clearAppliedPairForVehicle.*?TowBarMod\.Sync\.appliedPairs\[key\] = nil.*?Events\.OnSpawnVehicleEnd\.Add\(clearAppliedPairForVehicle\)') "Vehicle streaming must invalidate cached rigid towbar constraints."
|
||||
Assert-True ($serverCommands -match '(?s)local function broadcastAttach.*?if isServer\(\).*?sendServerCommand.*?elseif not isClient\(\).*?TowBarMod\.Sync\.applyAttachSync') "Saved towbar recovery must synchronize both dedicated-server and single-player sessions."
|
||||
Assert-True ($serverCommands -match 'towBarTowedVehicleSqlId' -and $serverCommands -match 'towBarTowingVehicleSqlId' -and $serverCommands -match 'getSqlId') "Towbar persistence must use stable save IDs in addition to live network IDs."
|
||||
Assert-True ($serverCommands -match 'Persistence\.savePair\("towbar"' -and $serverCommands -match 'Persistence\.forEachPair\("towbar"') "Towbar persistence must use the server-owned saved-pair registry."
|
||||
Assert-True ($hooking -match '(?s)local function recoverTowBarVehicleAfterLoad.*?authoritative audit will.*?reconnect') "Client load recovery must defer missing constraints to the authoritative saved-pair audit."
|
||||
$loadRecoveryStart = $hooking.IndexOf('local function recoverTowBarVehicleAfterLoad')
|
||||
$loadRecoveryEnd = $hooking.IndexOf('function TowBarMod.Hook.setVehiclePostAttach', $loadRecoveryStart)
|
||||
if ($loadRecoveryStart -ge 0 -and $loadRecoveryEnd -gt $loadRecoveryStart) {
|
||||
$loadRecovery = $hooking.Substring($loadRecoveryStart, $loadRecoveryEnd - $loadRecoveryStart)
|
||||
Assert-True ($loadRecovery -notmatch 'detachTowBar|attachTowBar|reattachTowBarPairAfterCleanDetach') "Loading a saved towbar pair must not refund or consume the item."
|
||||
}
|
||||
Assert-True ($serverCommands -match '(?s)local function processPendingSync.*?reconcileBrokenTowBarPairsServer\(\)') "The physical-link audit must run from the server/SP tick handler."
|
||||
Assert-True ($serverCommands -match '(?s)local function finalizeBrokenTowBarPair.*?dropTowBarOnGround.*?cancelPendingAttach.*?breakTowBarConstraint.*?clearExpectedTowBarPair.*?broadcastSpontaneousDetach') "Broken-pair finalization must drop, disconnect, clear state, and synchronize cleanup."
|
||||
Assert-True ($serverCommands -match '(?s)local function finalizeBrokenTowBarPair.*?if isServer\(\) then.*?elseif not isClient\(\).*?TowBarMod\.Hook\.cleanupDetachedTowBar') "Single-player breaks must directly restore the vehicle without relying on a server command."
|
||||
Assert-True ($clientSync -match 'spontaneousDetachSync') "Client sync must receive spontaneous towbar cleanup."
|
||||
Assert-True ($clientSync -match 'local function hasConflictingTowLink') "Client detach sync must detect links to unrelated vehicles."
|
||||
Assert-True ($clientSync -match 'local function breakTowBarPair') "Client detach sync must break only the requested pair."
|
||||
Assert-True ($clientSync -match 'local breakTowBarPair' -and $clientSync -match 'breakTowBarPair = function') "Client detach sync must break only the requested pair."
|
||||
Assert-True ($clientSync -notmatch 'local function safeBreak') "Client detach sync must not use an unrestricted per-vehicle constraint break."
|
||||
Assert-True ($clientSync -match '(?s)local function applyDetachSync.*?hasConflictingTowLink\(vehicleA, vehicleB\).*?return.*?breakTowBarPair\(vehicleA, vehicleB\).*?cleanupDetachedTowBar') "Client detach sync must reject conflicting links before cleanup."
|
||||
Assert-True ($hooking -match 'function TowBarMod\.Hook\.cleanupDetachedTowBar') "Client must expose idempotent towbar cleanup."
|
||||
@@ -97,13 +147,63 @@ Assert-True ($hooking -match '(?s)if modData\.towBarOriginalParkingBrakeOn ~= ni
|
||||
Assert-True ($hooking -notmatch 'tryVehicleCall\(vehicle, "setBrake"') "Free-rolling state must not change an unrestorable brake control."
|
||||
Assert-True ($hooking -notmatch 'tryVehicleCall\(vehicle, "setBraking"') "Free-rolling state must not change an unrestorable braking control."
|
||||
|
||||
Assert-True ($hooking -match '(?s)local function getTowbarModelSlot\(script\).*?if not isVanillaScale\(script\) then.*?return 0\s+end') "KI5 client rendering must select towbar slot 0."
|
||||
Assert-True ($btTow -match '(?s)local function getTowbarModelSlot\(script\).*?if not isVanillaScale\(script\) then.*?return 0\s+end') "KI5 part initialization must select towbar slot 0."
|
||||
Assert-True ($hooking -match 'local TowbarFirstZ = 1\.0') "Client hitbox placement must use the first model's Z position."
|
||||
Assert-True ($hooking -match 'local TowbarSlotStep = 0\.1') "Client hitbox placement must use the model bank's Z spacing."
|
||||
Assert-True ($hooking -match 'local TowbarVisualScale = 2\.5') "Client placement must account for the enlarged visual."
|
||||
Assert-True ($hooking -match 'local TowbarScaledModelLength = TowbarModelLength \* TowbarVisualScale') "Client placement must derive the enlarged mesh length."
|
||||
Assert-True ($hooking -match 'local TowbarModelHalfLength = TowbarScaledModelLength / 2') "Client placement must offset the mesh center by half its enlarged length."
|
||||
Assert-True ($btTow -match 'local TowbarVisualScale = 2\.5') "Part initialization must account for the enlarged visual."
|
||||
Assert-True ($btTow -match 'local TowbarScaledModelLength = TowbarModelLength \* TowbarVisualScale') "Part initialization must derive the enlarged mesh length."
|
||||
Assert-True ($btTow -match 'local TowbarModelHalfLength = TowbarScaledModelLength / 2') "Part initialization must offset the mesh center by half its enlarged length."
|
||||
Assert-True ($hooking -match '(?s)local function getTowbarFrontEdgeZ\(script\).*?getPhysicsChassisShape\(\).*?getCenterOfMassOffset\(\).*?centerZ.*?shapeZ / 2') "Client visual position must derive from the hitbox front edge."
|
||||
Assert-True ($btTow -match '(?s)local function getTowbarFrontEdgeZ\(script\).*?getPhysicsChassisShape\(\).*?getCenterOfMassOffset\(\).*?centerZ.*?shapeZ / 2') "Part initialization must derive visual position from the hitbox front edge."
|
||||
Assert-True ($hooking -match '(?s)local centerOk, center = pcall.*?if not centerOk or not center then return nil end.*?if not zOk or type\(centerZ\) ~= "number" then return nil end') "Client must not show a dynamically placed towbar when center-of-mass geometry is invalid."
|
||||
Assert-True ($btTow -match '(?s)local centerOk, center = pcall.*?if not centerOk or not center then return nil end.*?if not zOk or type\(centerZ\) ~= "number" then return nil end') "Part initialization must not show a towbar when center-of-mass geometry is invalid."
|
||||
Assert-True ($hooking -match '(?s)local function getTowbarModelSlot\(script\).*?local frontEdgeZ = getTowbarFrontEdgeZ\(script\).*?local modelCenterZ = frontEdgeZ \+ TowbarModelHalfLength.*?math\.floor\(\(\(modelCenterZ - TowbarFirstZ\) / TowbarSlotStep\) \+ 0\.5\).*?math\.max\(0, math\.min\(TowbarMaxIndex, index\)\)') "Client must place the towbar's inner end at the hitbox edge."
|
||||
Assert-True ($btTow -match '(?s)local function getTowbarModelSlot\(script\).*?local frontEdgeZ = getTowbarFrontEdgeZ\(script\).*?local modelCenterZ = frontEdgeZ \+ TowbarModelHalfLength.*?math\.floor\(\(\(modelCenterZ - TowbarFirstZ\) / TowbarSlotStep\) \+ 0\.5\).*?math\.max\(0, math\.min\(TowbarMaxIndex, index\)\)') "Part initialization must place the towbar's inner end at the hitbox edge."
|
||||
Assert-True ($hooking -notmatch 'isVanillaScale|modelScale') "Dynamic hitbox placement must not apply a second model-scale correction."
|
||||
Assert-True ($btTow -notmatch 'isVanillaScale|modelScale') "Part initialization must not apply a second model-scale correction."
|
||||
Assert-True ($hooking -match '(?s)local function setTowBarModelVisible.*?local part = normalPart.*?part:setModelVisible\("towbar" \.\. index, true\)') "Automatic rendering must use the normal towbar part."
|
||||
Assert-True ($btTow -match '(?s)function BTtow\.Init\.towbar.*?local shouldShowOnThisPart = part:getId\(\) == "towbar"') "Automatic part initialization must only show the normal towbar part."
|
||||
Assert-True ($hooking -notmatch 'local part = isVanilla and normalPart or largePart') "KI5 automatic rendering must not select the large towbar part."
|
||||
$normalTowbarPart = $towbarTemplate.Substring($towbarTemplate.IndexOf('part towbar'), $towbarTemplate.IndexOf('part towbarLarge') - $towbarTemplate.IndexOf('part towbar'))
|
||||
Assert-True ($towbarTemplate -match '(?s)model towbarModel\s*\{.*?scale = 0\.025,') "The rendered towbar mesh must be exactly 2.5 times its original 0.01 scale."
|
||||
Assert-True ($normalTowbarPart -match '(?s)model towbar0\s*\{\s*file = towbarModel,\s*offset = 0 -0\.3 1\.0,') "Normal towbar0 must retain the radial-menu Z=1.0 geometry."
|
||||
$normalTowbarModels = [regex]::Matches($normalTowbarPart, '(?s)model towbar(\d+)\s*\{\s*file = towbarModel,\s*offset = ([\d.-]+) ([\d.-]+) ([\d.-]+),')
|
||||
Assert-True ($normalTowbarModels.Count -eq 24) "Normal towbar part must provide all 24 dynamic Z slots."
|
||||
for ($slot = 0; $slot -lt $normalTowbarModels.Count; $slot++) {
|
||||
$match = $normalTowbarModels[$slot]
|
||||
Assert-True ([int]$match.Groups[1].Value -eq $slot) "Normal towbar slots must be sequential."
|
||||
Assert-True ([double]$match.Groups[2].Value -eq 0) "Dynamic placement must not alter lateral X."
|
||||
Assert-True ([double]$match.Groups[3].Value -eq -0.3) "Dynamic placement must not alter vertical Y."
|
||||
$expectedZ = 1.0 + ($slot * 0.1)
|
||||
Assert-True ([Math]::Abs(([double]$match.Groups[4].Value) - $expectedZ) -lt 0.000001) "Towbar slot $slot must map to Z=$expectedZ."
|
||||
}
|
||||
|
||||
function Get-ExpectedTowbarSlot {
|
||||
param([double]$ShapeZ, [double]$CenterZ)
|
||||
$towbarModelHalfLength = (0.9714089036 * 2.5) / 2
|
||||
$targetCenterZ = $CenterZ + $ShapeZ / 2 + $towbarModelHalfLength
|
||||
$raw = [Math]::Floor((($targetCenterZ - 1.0) / 0.1) + 0.5)
|
||||
return [Math]::Max(0, [Math]::Min(23, [int]$raw))
|
||||
}
|
||||
|
||||
$geometryCases = @(
|
||||
@{ Name = "B42 Ranger"; ShapeZ = 2.6044; CenterZ = 0.0; Slot = 15 },
|
||||
@{ Name = "KI5 Corolla"; ShapeZ = 4.3111; CenterZ = -0.0444; Slot = 23 },
|
||||
@{ Name = "KI5 Range"; ShapeZ = 4.4444; CenterZ = -0.2556; Slot = 22 },
|
||||
@{ Name = "short vehicle"; ShapeZ = 1.2; CenterZ = 0.0; Slot = 8 },
|
||||
@{ Name = "long clamp"; ShapeZ = 7.2; CenterZ = 0.0; Slot = 23 }
|
||||
)
|
||||
foreach ($case in $geometryCases) {
|
||||
Assert-True ((Get-ExpectedTowbarSlot $case.ShapeZ $case.CenterZ) -eq $case.Slot) "$($case.Name) hitbox must map to towbar slot $($case.Slot)."
|
||||
$frontEdgeZ = $case.CenterZ + ($case.ShapeZ / 2)
|
||||
$chosenCenterZ = 1.0 + ($case.Slot * 0.1)
|
||||
$chosenInnerEndZ = $chosenCenterZ - $towbarScaledHalfLength
|
||||
if ($case.Slot -gt 0 -and $case.Slot -lt 23) {
|
||||
Assert-True ([Math]::Abs($chosenInnerEndZ - $frontEdgeZ) -le 0.0500001) "$($case.Name) enlarged visual must retain contact with the hitbox edge within half a model slot."
|
||||
}
|
||||
}
|
||||
Assert-True ($hooking -match 'function TowBarMod\.Hook\.setVehicleScriptWithTowBarHidden') "Vehicle script swaps must use the anti-flicker helper."
|
||||
Assert-True ($hooking -match '(?s)setVehicleScriptWithTowBarHidden.*?setTowBarModelVisible\(vehicle, false\).*?towBarModelSwapInProgress.*?vehicle:setScriptName\(scriptName\).*?setTowBarModelVisible\(vehicle, false\)') "The anti-flicker helper must hide towbar models for the full script swap."
|
||||
Assert-True ($btTow -match '(?s)function BTtow\.Init\.towbar.*?setModelVisible\("towbar" \.\. j, false\).*?towBarModelSwapInProgress.*?return') "Part initialization must not show a towbar during a script swap."
|
||||
@@ -130,6 +230,7 @@ if ($cleanupStart -ge 0 -and $cleanupEnd -gt $cleanupStart) {
|
||||
$cleanupBranch = $hooking.Substring($cleanupStart, $cleanupEnd - $cleanupStart)
|
||||
Assert-True ($cleanupBranch -match 'updateAttachmentsOnDefaultValues') "Break cleanup must restore attachment offsets."
|
||||
Assert-True ($cleanupBranch -match 'setVehicleScriptWithTowBarHidden.*?towBarOriginalScriptName') "Break cleanup must restore the original vehicle script."
|
||||
Assert-True ($cleanupBranch -match '(?s)setVehicleScriptWithTowBarHidden.*?towBarOriginalScriptName.*?updateAttachmentsOnDefaultValues') "Break cleanup must restore the real vehicle script before restoring its attachment offsets."
|
||||
Assert-True ($cleanupBranch -match 'restoreFreeRollingTowState') "Break cleanup must restore mass, brakes, and parking-brake state."
|
||||
Assert-True ($cleanupBranch -match 'setTowBarModelVisible\(towedVehicle, false\)') "Break cleanup must hide the towbar model."
|
||||
Assert-True ($cleanupBranch -match '(?s)towingModData\["towBarTowedVehicleId"\] = nil.*?towingModData\["towBarTowingVehicleId"\] = nil.*?towedModData\["towBarTowedVehicleId"\] = nil.*?towedModData\["towBarTowingVehicleId"\] = nil') "Client cleanup must remove stale IDs for either tow role."
|
||||
|
||||
Reference in New Issue
Block a user