From b6c729ac59bf8b37a7142bc38988cd6642efda77 Mon Sep 17 00:00:00 2001 From: masterdraco Date: Wed, 23 Sep 2026 15:30:51 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20paller=20=E2=80=94=20'fuldt=20l=C3=A6s'?= =?UTF-8?q?=20for=20autoload-bil=20=3D=20mindst=204=20paller=20klar=20(ved?= =?UTF-8?q?=20spawner=20eller=20i=20objektlager)=20(v1.12.14.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adOutbound.lua | 2 +- FS25_ADSmartPickup/adOutboundPlanner.lua | 18 ++++++++++++++---- FS25_ADSmartPickup/adSources.lua | 18 ++++++++++++------ FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adOutbound.lua | 3 ++- tests/test_adOutboundPlanner.lua | 14 ++++++++++++++ tests/test_adSources.lua | 2 ++ 7 files changed, 46 insertions(+), 13 deletions(-) diff --git a/FS25_ADSmartPickup/adOutbound.lua b/FS25_ADSmartPickup/adOutbound.lua index eeed294..849fadc 100644 --- a/FS25_ADSmartPickup/adOutbound.lua +++ b/FS25_ADSmartPickup/adOutbound.lua @@ -220,7 +220,7 @@ function ADOutbound.buildPlanInput(adEnv, run, vehicle) byName[item.name] = product table.insert(products, product) end - table.insert(product.sources, {wayPointId = source.wayPointId, available = available, level = item.level, capacity = item.capacity}) + table.insert(product.sources, {wayPointId = source.wayPointId, available = available, level = item.level, capacity = item.capacity, palletCount = usePallets and (item.palletCount or 0) or 0}) end end end diff --git a/FS25_ADSmartPickup/adOutboundPlanner.lua b/FS25_ADSmartPickup/adOutboundPlanner.lua index ca9f252..0d525f6 100644 --- a/FS25_ADSmartPickup/adOutboundPlanner.lua +++ b/FS25_ADSmartPickup/adOutboundPlanner.lua @@ -20,6 +20,8 @@ ADOutboundPlanner = {} ADOutboundPlanner.MIN_AVAILABLE_LITERS = 1 -- Opsamlingsrunde (bulk): næste kilde besøges kun hvis mindst så stor en andel af vognen er fri. ADOutboundPlanner.ROUND_MIN_FREE_FRACTION = 0.1 +-- Paller: en autoload-bil opgiver ingen liter-kapacitet, så "fuldt læs" = mindst så mange paller klar. +ADOutboundPlanner.PALLET_FULL_LOAD_COUNT = 4 local function wantsSell(policy) return policy == "sell" or policy == "sellElseStore" @@ -31,25 +33,33 @@ end -- Samlet tilgængeligt over kilderne og den højeste fyldningsgrad (%) blandt dem. local function sumSources(product) - local total, percent = 0, 0 + local total, percent, pallets = 0, 0, 0 for _, source in ipairs(product.sources or {}) do total = total + (source.available or 0) + pallets = pallets + (source.palletCount or 0) if source.capacity ~= nil and source.capacity > 0 then percent = math.max(percent, 100 * (source.level or 0) / source.capacity) end end - return total, percent + return total, percent, pallets end function ADOutboundPlanner.evaluate(product, input) - local available, storagePercent = sumSources(product) + local available, storagePercent, palletCount = sumSources(product) local percent = product.quote ~= nil and product.quote.percent or nil local reserve = math.max(0, product.reserve or 0) + local fullLoad + if input.capacity ~= nil and input.capacity > 0 then + fullLoad = available >= input.capacity + else + fullLoad = product.isPallet == true and palletCount >= ADOutboundPlanner.PALLET_FULL_LOAD_COUNT + end return { available = available, reserve = reserve, sellable = math.max(0, available - reserve), - fullLoad = input.capacity ~= nil and input.capacity > 0 and available >= input.capacity, + palletCount = palletCount, + fullLoad = fullLoad, storagePercent = storagePercent, storageHigh = storagePercent >= (input.storeAbovePercent or 80), percent = percent, diff --git a/FS25_ADSmartPickup/adSources.lua b/FS25_ADSmartPickup/adSources.lua index be111ff..dfd77f0 100644 --- a/FS25_ADSmartPickup/adSources.lua +++ b/FS25_ADSmartPickup/adSources.lua @@ -174,7 +174,7 @@ local function getPalletsNearSpawner(placeable, fillType, farmId) return 0 end local vehicles = g_currentMission ~= nil and g_currentMission.vehicleSystem ~= nil and g_currentMission.vehicleSystem.vehicles or {} - local total = 0 + local total, count = 0, 0 local radius2 = ADSources.PALLET_RADIUS * ADSources.PALLET_RADIUS for _, vehicle in pairs(vehicles) do if isPalletVehicle(vehicle) and (vehicle.getOwnerFarmId == nil or vehicle:getOwnerFarmId() == farmId) then @@ -182,10 +182,11 @@ local function getPalletsNearSpawner(placeable, fillType, farmId) local x, z = getNodePosition(vehicle.rootNode) if palletFillType == fillType and x ~= nil and distance2(sx, sz, x, z) <= radius2 then total = total + level + count = count + 1 end end end - return total + return total, count end -- canPallet: varen er en palletype (kan stå på paller); palletLiters: liter på paller ved @@ -193,7 +194,7 @@ end local function newProduct(fillType, available, level, capacity, isPallet) local name = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType) local title = g_fillTypeManager ~= nil and g_fillTypeManager.getFillTypeTitleByIndex ~= nil and g_fillTypeManager:getFillTypeTitleByIndex(fillType) or nil - return {fillType = fillType, name = name, title = title or name, available = available, level = level, capacity = capacity, isPallet = isPallet, canPallet = isPallet or ADSources.isPalletFillType(fillType), palletLiters = 0} + return {fillType = fillType, name = name, title = title or name, available = available, level = level, capacity = capacity, isPallet = isPallet, canPallet = isPallet or ADSources.isPalletFillType(fillType), palletLiters = 0, palletCount = 0} end local function getFactoryProducts(source, farmId) @@ -208,10 +209,13 @@ local function getFactoryProducts(source, farmId) local level = storage ~= nil and storage.getFillLevel ~= nil and (storage:getFillLevel(fillType) or 0) or 0 local capacity = storage ~= nil and storage.getCapacity ~= nil and (storage:getCapacity(fillType) or 0) or 0 local isPallet = ADSources.isPalletAt(source, fillType) - local palletLiters = ADSources.isPalletFillType(fillType) and getPalletsNearSpawner(source.placeable, fillType, farmId) or 0 + local palletLiters, palletCount = 0, 0 + if ADSources.isPalletFillType(fillType) then + palletLiters, palletCount = getPalletsNearSpawner(source.placeable, fillType, farmId) + end local available = level + (isPallet and palletLiters or 0) local product = newProduct(fillType, available, level, capacity, isPallet) - product.palletLiters = palletLiters + product.palletLiters, product.palletCount = palletLiters, palletCount table.insert(products, product) end end @@ -258,7 +262,9 @@ local function getObjectStorageProducts(source) local fillType, perObject = getObjectInfoContent(objectInfo) local count = objectInfo.numObjects or 0 if fillType ~= nil and count > 0 then - table.insert(products, newProduct(fillType, count * perObject, spec.numStoredObjects or count, spec.capacity or 0, true)) + local product = newProduct(fillType, count * perObject, spec.numStoredObjects or count, spec.capacity or 0, true) + product.palletCount = count + table.insert(products, product) end end return products diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index 77b8854..c3d1996 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.12.13.0 + 1.12.14.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adOutbound.lua b/tests/test_adOutbound.lua index cfb4863..f086e98 100644 --- a/tests/test_adOutbound.lua +++ b/tests/test_adOutbound.lua @@ -419,11 +419,12 @@ check("O18 reserve spørges ikke for lager-politik", demandCalls[#demandCalls] ~ local v19 = newVehicle("Dragon", 0, 0, 6000, true) v19.carriable = {} runs[v19] = outboundRun(19, {1}, {{fillType = "SUGAR", policy = "sell"}}) -products[1] = {{fillType = SUGAR, name = "SUGAR", available = 150000, level = 150000, capacity = 180000, isPallet = false, canPallet = true, palletLiters = 3000}} +products[1] = {{fillType = SUGAR, name = "SUGAR", available = 150000, level = 150000, capacity = 180000, isPallet = false, canPallet = true, palletLiters = 3000, palletCount = 3}} quotes["selling station"][SUGAR].percent = 92 local input19 = ADOutbound.buildPlanInput(adEnv, runs[v19], v19) check("O19 varen tages som paller", input19.products[1] ~= nil and input19.products[1].isPallet, true) check("O19 mængde = paller ved spawner", input19.products[1].sources[1].available, 3000) +check("O19 palle-antal følger med", input19.products[1].sources[1].palletCount, 3) local v19b = newVehicle("Tipvogn", 0, 0, 20000) runs[v19b] = outboundRun(20, {1}, {{fillType = "SUGAR", policy = "sell"}}) local input19b = ADOutbound.buildPlanInput(adEnv, runs[v19b], v19b) diff --git a/tests/test_adOutboundPlanner.lua b/tests/test_adOutboundPlanner.lua index df0f45b..71eee2f 100644 --- a/tests/test_adOutboundPlanner.lua +++ b/tests/test_adOutboundPlanner.lua @@ -130,5 +130,19 @@ check("P13 lager rører ikke reserven", P.plan(input({storeReserve})).kind, "sto local e13 = P.evaluate(withReserve, input({}, {capacity = 20000})) check("P13 evaluate sellable", e13.sellable, 268000) +-- P14 (paller): kapacitet ukendt for en autoload-bil -> "fuldt læs" = mindst PALLET_FULL_LOAD_COUNT paller klar +local function palletInput(products) + local inp = input(products, {hasAutoload = true}) + inp.capacity = nil + return inp +end +local palletProduct = product("STRAW_BASKET", BASKET, "store", {{wayPointId = 5, available = 3000, level = 1600, capacity = 8000, palletCount = 3}}, nil, storeSilo, true) +check("P14 3 paller: ikke fuldt læs", P.plan(palletInput({palletProduct})), nil) +palletProduct.sources[1].palletCount = 4 +check("P14 4 paller: lager-tur", P.plan(palletInput({palletProduct})).kind, "store") +local twoSources = product("STRAW_BASKET", BASKET, "store", {{wayPointId = 5, available = 2000, level = 1600, capacity = 8000, palletCount = 2}, {wayPointId = 3, available = 2000, level = 2, capacity = 4000, palletCount = 2}}, nil, storeSilo, true) +check("P14 paller summeres over kilder", P.plan(palletInput({twoSources})).kind, "store") +check("P14 evaluate palletCount", P.evaluate(twoSources, palletInput({})).palletCount, 4) + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1) diff --git a/tests/test_adSources.lua b/tests/test_adSources.lua index 7411378..18a5c4d 100644 --- a/tests/test_adSources.lua +++ b/tests/test_adSources.lua @@ -157,6 +157,8 @@ addPallet(BASKET, 1000, 160, 100) -- 50 m væk: tæller ikke addPallet(BASKET, 1000, 112, 102, 2) -- anden farm: tæller ikke local products4 = ADSources.getProducts(adEnv, source1, 1) check("S4 paller ved spawner", products4[2].available, 2000) +check("S4 antal paller ved spawner", products4[2].palletCount, 2) +check("S3 antal paller i objektlager", products3[1].palletCount, 8) check("S4 bulk uændret", products4[1].available, 150000) addPallet(SUGAR, 2000, 111, 101) local products4b = ADSources.getProducts(adEnv, source1, 1)