From 781c81752c9eaa0860ca09519b8d3cba19b85566 Mon Sep 17 00:00:00 2001 From: masterdraco Date: Tue, 29 Sep 2026 19:11:17 +0200 Subject: [PATCH] =?UTF-8?q?fix(flows):=20t=C3=B8mning=20bruger=20aldrig=20?= =?UTF-8?q?marksiloer;=20kan=20en=20silo=20ikke=20tage=20imod,=20pr=C3=B8v?= =?UTF-8?q?es=20den=20n=C3=A6ste=20(op=20til=203)=20f=C3=B8r=20parkering?= =?UTF-8?q?=20med=20last=20(v1.60.6.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adFieldSilos.lua | 11 +++++++++++ FS25_ADSmartPickup/adFlowWagons.lua | 17 ++++++++++++++--- FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adFlowWagons.lua | 3 ++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/FS25_ADSmartPickup/adFieldSilos.lua b/FS25_ADSmartPickup/adFieldSilos.lua index 5da5457..3c2a7f4 100644 --- a/FS25_ADSmartPickup/adFieldSilos.lua +++ b/FS25_ADSmartPickup/adFieldSilos.lua @@ -229,6 +229,17 @@ function ADFieldSilos.collectBuildings(adEnv) return silos, stores, byId end +-- Marksiloernes placeables som sæt (til at udelukke dem som tømmested — de er til markens høst). +function ADFieldSilos.fieldSiloPlaceableSet(adEnv) + local set = {} + local silos, _, byId = ADFieldSilos.collectBuildings(adEnv) + for _, silo in ipairs(silos or {}) do + local building = byId[silo.id] + if building ~= nil and building.placeable ~= nil then set[building.placeable] = true end + end + return set +end + local function trailerInfo(adEnv, vehicle) local capacity, carries, cargo = 0, {}, nil for _, unit in ipairs(adEnv.AutoDrive.getAllDischargeableUnits(vehicle) or {}) do diff --git a/FS25_ADSmartPickup/adFlowWagons.lua b/FS25_ADSmartPickup/adFlowWagons.lua index 41683f2..feb078d 100644 --- a/FS25_ADSmartPickup/adFlowWagons.lua +++ b/FS25_ADSmartPickup/adFlowWagons.lua @@ -132,6 +132,7 @@ ADFlowWagons.EMPTY_MIN_LITERS = 100 ADFlowWagons.EMPTY_TIMEOUT_MS = 600000 ADFlowWagons.EMPTY_STALL_MS = 45000 -- ved målet uden at læsset falder så længe = målet er fuldt ADFlowWagons.EMPTY_NEAR_M = 40 -- m fra aflæsningsmarkøren tæller som "ved målet" +ADFlowWagons.MAX_DUMP_ATTEMPTS = 3 -- siloer der prøves før vognen parkeres med last -- s = {nearTarget, sinceChangeMs} function ADFlowWagons.isStalled(s) @@ -145,7 +146,11 @@ function ADFlowWagons.emptyStep(stage, s) return s.hasTarget and "target" or "dump" end if (s.elapsedMs or 0) >= ADFlowWagons.EMPTY_TIMEOUT_MS then return "giveUp" end - if s.stalled and cargo >= ADFlowWagons.EMPTY_MIN_LITERS then return stage == "target" and "dump" or "giveUp" end + if s.stalled and cargo >= ADFlowWagons.EMPTY_MIN_LITERS then + if stage == "target" then return "dump" end + -- silo der ikke kunne tage imod: prøv den næste (op til MAX_DUMP_ATTEMPTS) + return (s.dumpAttempts or 0) < ADFlowWagons.MAX_DUMP_ATTEMPTS and "dump" or "giveUp" + end if s.adActive then return "wait" end if cargo < ADFlowWagons.EMPTY_MIN_LITERS then return "home" end if stage == "target" then return "dump" end @@ -404,7 +409,11 @@ local function startDump(adEnv, vehicle, state) local isReachable = function(markerId) return ADUnloadWait == nil or ADUnloadWait.hasRouteTo == nil or ADUnloadWait.hasRouteTo(adEnv, vehicle, markerId) end - local ok, marker, why = pcall(ADLoadSwap.findDumpMarker, adEnv, vehicle, fillType, cargo, nil, isReachable, nil, nil, true) + -- marksiloer er ikke tømmesteder (de er til markens høst); siloer der allerede fejlede springes over + local okSet, fieldSilos = pcall(function() return ADFieldSilos ~= nil and ADFieldSilos.fieldSiloPlaceableSet(adEnv) or nil end) + state.triedMarkers = state.triedMarkers or {} + local ok, marker, why = pcall(ADLoadSwap.findDumpMarker, adEnv, vehicle, fillType, cargo, nil, isReachable, + okSet and fieldSilos or nil, state.triedMarkers, true) if not ok or marker == nil then Logging.warning(ADFlowWagons.LOG_PREFIX .. "'%s' har stadig %d l %s — intet sted at aflæsse (%s); parkeres med last", tostring(ADRuns.vehicleLabel(vehicle)), math.floor(cargo), fillName(fillType), tostring(ok and why or marker)) @@ -413,6 +422,8 @@ local function startDump(adEnv, vehicle, state) end state.stage, state.since = "dump", nowMs state.markerId, state.markerName, state.lastCargo = marker.id, marker.name, nil + state.dumpAttempts = (state.dumpAttempts or 0) + 1 + state.triedMarkers[marker.id] = true ADFieldWork.startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DELIVERTO, marker.id, nil, fillType) Logging.info(ADFlowWagons.LOG_PREFIX .. "'%s' aflæsser resten (%d l %s) ved %s før parkering", tostring(ADRuns.vehicleLabel(vehicle)), math.floor(cargo), fillName(fillType), tostring(marker.name)) @@ -551,7 +562,7 @@ local function tickEmptying(adEnv) else local stalled = stalledAt(adEnv, vehicle, state, cargo) local action = ADFlowWagons.emptyStep(state.stage, {cargo = cargo, adActive = module ~= nil and module:isActive(), - elapsedMs = nowMs - state.since, stalled = stalled}) + elapsedMs = nowMs - state.since, stalled = stalled, dumpAttempts = state.dumpAttempts}) if stalled and action ~= "wait" then Logging.info(ADFlowWagons.LOG_PREFIX .. "'%s' kan ikke aflæsse ved %s (fuldt?) — videre", tostring(ADRuns.vehicleLabel(vehicle)), tostring(state.markerName)) diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index e216ffa..8cc414b 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.60.5.0 + 1.60.6.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adFlowWagons.lua b/tests/test_adFlowWagons.lua index fb80e3e..843e548 100644 --- a/tests/test_adFlowWagons.lua +++ b/tests/test_adFlowWagons.lua @@ -100,7 +100,8 @@ check("vent-årsag: vogn på en anden", W.waitReason({wagonAttached = true}), "w check("vent-årsag: vogn reserveret", W.waitReason({wagonBusy = true}), "wagonReserved") -- tømning går i stå ved et fuldt mål (in-game 29/9: fåre-/BGA-vogne stod 10 min ved fuldt mål efter Stop alt) check("tøm: står ved fuldt mål -> silo", W.emptyStep("target", {cargo = 5000, adActive = true, stalled = true}), "dump") -check("tøm: står ved silo uden at tømme -> giv op", W.emptyStep("dump", {cargo = 5000, adActive = true, stalled = true}), "giveUp") +check("tøm: står ved silo uden at tømme -> næste silo", W.emptyStep("dump", {cargo = 5000, adActive = true, stalled = true, dumpAttempts = 1}), "dump") +check("tøm: 3 siloer prøvet -> giv op", W.emptyStep("dump", {cargo = 5000, adActive = true, stalled = true, dumpAttempts = W.MAX_DUMP_ATTEMPTS}), "giveUp") check("tøm: kører mod målet (ikke i stå) -> vent", W.emptyStep("target", {cargo = 5000, adActive = true, stalled = false}), "wait") check("i stå: tæt på, uændret længe", W.isStalled({nearTarget = true, sinceChangeMs = W.EMPTY_STALL_MS}), true) check("i stå: tæt på, lige ankommet", W.isStalled({nearTarget = true, sinceChangeMs = 5000}), false)