fix(marksilo): fuld fabrik — lånt vogn med last der holder ved et lager uden plads i 60 s, kører resten til et andet lager (gårdsilo) (v1.50.5.0)

This commit is contained in:
2026-09-28 20:06:03 +02:00
parent e778ab44b4
commit 1759d62600
4 changed files with 70 additions and 21 deletions
+15 -2
View File
@@ -54,9 +54,22 @@ function ADFieldSiloPlanner.restDue(s)
and (s.cargo or 0) >= ADFieldSiloPlanner.REST_MIN_LITERS and (s.siloStock or 0) < ADFieldSiloPlanner.REST_MIN_LITERS and (s.cargo or 0) >= ADFieldSiloPlanner.REST_MIN_LITERS and (s.siloStock or 0) < ADFieldSiloPlanner.REST_MIN_LITERS
end end
-- Fuld fabrik/lager: vognen med last har holdt ved sit lager i STORE_FULL_MS, og lageret har ikke plads.
-- s = {atStore, stillMs, cargo, storeFree}
ADFieldSiloPlanner.STORE_FULL_MS = 60000
function ADFieldSiloPlanner.storeFullDue(s)
return s.atStore == true and (s.stillMs or 0) >= ADFieldSiloPlanner.STORE_FULL_MS
and (s.cargo or 0) >= ADFieldSiloPlanner.REST_MIN_LITERS and (s.storeFree or 0) < ADFieldSiloPlanner.REST_MIN_LITERS
end
-- Lager til en rest: fabrik kun med plads til hele resten, ellers gårdlager (nærmeste med plads, ellers mest plads). -- Lager til en rest: fabrik kun med plads til hele resten, ellers gårdlager (nærmeste med plads, ellers mest plads).
function ADFieldSiloPlanner.restStore(stores, silo, fillType, liters) -- excludeId: lageret vognen holder fast ved (fuldt).
return chooseStore(stores, silo, fillType, liters, 1, {}, true) or chooseStore(stores, silo, fillType, liters, 1, {}, false) function ADFieldSiloPlanner.restStore(stores, silo, fillType, liters, excludeId)
local candidates = {}
for _, store in ipairs(stores or {}) do
if store.id ~= excludeId then table.insert(candidates, store) end
end
return chooseStore(candidates, silo, fillType, liters, 1, {}, true) or chooseStore(candidates, silo, fillType, liters, 1, {}, false)
end end
local function canCarry(vehicle, fillType) local function canCarry(vehicle, fillType)
+43 -18
View File
@@ -455,7 +455,12 @@ function ADFieldSilos.adoptOrphans(adEnv, silos)
local silo = first ~= nil and byMarker[first.id] or nil local silo = first ~= nil and byMarker[first.id] or nil
if silo ~= nil then if silo ~= nil then
local fillType = module.getFillType ~= nil and module:getFillType() or nil local fillType = module.getFillType ~= nil and module:getFillType() or nil
loans[vehicle] = {siloId = silo.id, siloName = silo.name, fillType = fillType, liters = 0, startedMs = nowMs, local second = module.getSecondMarker ~= nil and module:getSecondMarker() or nil
local storeId = nil
for _, store in ipairs(ADFieldSilos.lastStores or {}) do
if second ~= nil and store.markerId == second.id then storeId = store.id end
end
loans[vehicle] = {siloId = silo.id, storeId = storeId, siloName = silo.name, fillType = fillType, liters = 0, startedMs = nowMs,
lastProgressMs = nowMs, lastFill = fillLevel(adEnv, vehicle), hasProgressed = true, adopted = true} lastProgressMs = nowMs, lastFill = fillLevel(adEnv, vehicle), hasProgressed = true, adopted = true}
Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s' overtaget igen (AutoDrive kører fra %s efter genindlæsning)", Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s' overtaget igen (AutoDrive kører fra %s efter genindlæsning)",
tostring(ADRuns.vehicleLabel(vehicle)), tostring(silo.name)) tostring(ADRuns.vehicleLabel(vehicle)), tostring(silo.name))
@@ -467,22 +472,41 @@ end
-- Tom silo-vagt: en lånt vogn med last, der står stille ved en tom marksilo, kører resten videre — til en fabrik -- Tom silo-vagt: en lånt vogn med last, der står stille ved en tom marksilo, kører resten videre — til en fabrik
-- med plads til hele resten, ellers til et gårdlager (AutoDrive venter ellers til vognen er fuld). -- med plads til hele resten, ellers til et gårdlager (AutoDrive venter ellers til vognen er fuld).
local warnedNoRestStore = {} local warnedNoRestStore = {}
local function checkRest(adEnv, vehicle, loan, moving, fill) local function isNear(adEnv, vehicle, markerId)
if loan.delivering or loan.fetching then return end local wayPoint = markerId ~= nil and adEnv.ADGraphManager:getWayPointById(markerId) or nil
local silo = nil if wayPoint == nil or vehicle.rootNode == nil then return false end
for _, candidate in ipairs(ADFieldSilos.lastSilos or {}) do
if candidate.id == loan.siloId then silo = candidate end
end
local wayPoint = silo ~= nil and silo.markerId ~= nil and adEnv.ADGraphManager:getWayPointById(silo.markerId) or nil
if wayPoint == nil or vehicle.rootNode == nil then return end
local x, _, z = getWorldTranslation(vehicle.rootNode) local x, _, z = getWorldTranslation(vehicle.rootNode)
local atSilo = (x - wayPoint.x) ^ 2 + (z - wayPoint.z) ^ 2 <= ADFieldSilos.REST_SILO_DISTANCE ^ 2 return (x - wayPoint.x) ^ 2 + (z - wayPoint.z) ^ 2 <= ADFieldSilos.REST_SILO_DISTANCE ^ 2
if moving or not atSilo then loan.stillSince = nil return end end
local function findById(list, id)
for _, item in ipairs(list or {}) do
if item.id == id then return item end
end
return nil
end
local function checkRest(adEnv, vehicle, loan, moving, fill)
if loan.fetching then return end
local silo = findById(ADFieldSilos.lastSilos, loan.siloId)
if silo == nil then return end
if moving then loan.stillSince = nil return end
loan.stillSince = loan.stillSince or nowMs loan.stillSince = loan.stillSince or nowMs
local state = {atSilo = atSilo, stillMs = nowMs - loan.stillSince, local stillMs = nowMs - loan.stillSince
siloStock = (silo.stock or {})[loan.fillType] or 0, cargo = fill} local fullStore = nil
if not ADFieldSiloPlanner.restDue(state) then return end if not loan.delivering and isNear(adEnv, vehicle, silo.markerId) then
local store = ADFieldSiloPlanner.restStore(ADFieldSilos.lastStores, silo, loan.fillType, fill) -- tom marksilo med last på
local state = {atSilo = true, stillMs = stillMs, siloStock = (silo.stock or {})[loan.fillType] or 0, cargo = fill}
if not ADFieldSiloPlanner.restDue(state) then return end
else
-- fuldt lager (fabrik der kun tager sit forbrug) med last på
local current = findById(ADFieldSilos.lastStores, loan.storeId)
if current == nil or not isNear(adEnv, vehicle, current.markerId) then return end
local state = {atStore = true, stillMs = stillMs, cargo = fill, storeFree = (current.free or {})[loan.fillType] or 0}
if not ADFieldSiloPlanner.storeFullDue(state) then return end
fullStore = current
end
local store = ADFieldSiloPlanner.restStore(ADFieldSilos.lastStores, silo, loan.fillType, fill, fullStore ~= nil and fullStore.id or nil)
if store == nil then if store == nil then
if not warnedNoRestStore[vehicle] then if not warnedNoRestStore[vehicle] then
warnedNoRestStore[vehicle] = true warnedNoRestStore[vehicle] = true
@@ -492,13 +516,14 @@ local function checkRest(adEnv, vehicle, loan, moving, fill)
return return
end end
warnedNoRestStore[vehicle] = nil warnedNoRestStore[vehicle] = nil
loan.delivering = true loan.delivering, loan.storeId, loan.stillSince = true, store.id, nil
loan.startedMs, loan.hasProgressed = nowMs, true loan.startedMs, loan.hasProgressed = nowMs, true
local isPool = ADHitch ~= nil and #ADHitch.poolParkIds(adEnv, vehicle) > 0 local isPool = ADHitch ~= nil and #ADHitch.poolParkIds(adEnv, vehicle) > 0
if not isPool then ADFieldWork.enableParkAtJobFinished(vehicle) end if not isPool then ADFieldWork.enableParkAtJobFinished(vehicle) end
ADFieldWork.startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DELIVERTO, store.markerId, nil, loan.fillType) ADFieldWork.startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DELIVERTO, store.markerId, nil, loan.fillType)
Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s': %s er tom — kører resten (%d l %s) til %s", Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s': %s — kører resten (%d l %s) til %s",
tostring(ADRuns.vehicleLabel(vehicle)), tostring(silo.name), math.floor(fill), fillTypeName(loan.fillType), tostring(store.name)) tostring(ADRuns.vehicleLabel(vehicle)), fullStore ~= nil and (tostring(fullStore.name) .. " er fuld") or (tostring(silo.name) .. " er tom"),
math.floor(fill), fillTypeName(loan.fillType), tostring(store.name))
end end
local function checkLoans(adEnv) local function checkLoans(adEnv)
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107"> <modDesc descVersion="107">
<author>masterdraco</author> <author>masterdraco</author>
<version>1.50.4.0</version> <version>1.50.5.0</version>
<title> <title>
<en>AD Smart Pickup</en> <en>AD Smart Pickup</en>
</title> </title>
+11
View File
@@ -144,5 +144,16 @@ local restStores = {
check("RS6 fabrik uden plads til hele resten -> gårdsilo", P.restStore(restStores, {x = 0, z = 0}, 10, 12000).id, "gaard") check("RS6 fabrik uden plads til hele resten -> gårdsilo", P.restStore(restStores, {x = 0, z = 0}, 10, 12000).id, "gaard")
check("RS7 fabrik med plads -> fabrik", P.restStore(restStores, {x = 0, z = 0}, 10, 4000).id, "fab") check("RS7 fabrik med plads -> fabrik", P.restStore(restStores, {x = 0, z = 0}, 10, 4000).id, "fab")
check("RS8 intet tager varen", P.restStore(restStores, {x = 0, z = 0}, 99, 4000), nil) check("RS8 intet tager varen", P.restStore(restStores, {x = 0, z = 0}, 99, 4000), nil)
-- Fuld fabrik: lånt vogn med last holder ved et lager uden plads -> resten til et andet lager (gård)
check("SF1 fuld fabrik -> videre", P.storeFullDue({atStore = true, stillMs = 70000, cargo = 12000, storeFree = 0}), true)
check("SF2 fabrikken tager stadig imod -> vent", P.storeFullDue({atStore = true, stillMs = 70000, cargo = 12000, storeFree = 8000}), false)
check("SF3 lige ankommet -> vent", P.storeFullDue({atStore = true, stillMs = 20000, cargo = 12000, storeFree = 0}), false)
check("SF4 ikke ved lageret -> nej", P.storeFullDue({atStore = false, stillMs = 70000, cargo = 12000, storeFree = 0}), false)
local fullStores = {
{id = "fab", kind = "production", markerId = 1, x = 10, z = 0, free = {[10] = 0}},
{id = "gaard", kind = "silo", markerId = 2, x = 500, z = 0, free = {[10] = 900000}},
}
check("SF5 andet lager end det fulde", P.restStore(fullStores, {x = 0, z = 0}, 10, 12000, "fab").id, "gaard")
check("SF6 kun det fulde tager varen -> intet", P.restStore({fullStores[1]}, {x = 0, z = 0}, 10, 12000, "fab"), nil)
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1) os.exit(failures == 0 and 0 or 1)