feat: paller — 'fuldt læs' for autoload-bil = mindst 4 paller klar (ved spawner eller i objektlager) (v1.12.14.0)
This commit is contained in:
@@ -220,7 +220,7 @@ function ADOutbound.buildPlanInput(adEnv, run, vehicle)
|
|||||||
byName[item.name] = product
|
byName[item.name] = product
|
||||||
table.insert(products, product)
|
table.insert(products, product)
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ ADOutboundPlanner = {}
|
|||||||
ADOutboundPlanner.MIN_AVAILABLE_LITERS = 1
|
ADOutboundPlanner.MIN_AVAILABLE_LITERS = 1
|
||||||
-- Opsamlingsrunde (bulk): næste kilde besøges kun hvis mindst så stor en andel af vognen er fri.
|
-- 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
|
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)
|
local function wantsSell(policy)
|
||||||
return policy == "sell" or policy == "sellElseStore"
|
return policy == "sell" or policy == "sellElseStore"
|
||||||
@@ -31,25 +33,33 @@ end
|
|||||||
|
|
||||||
-- Samlet tilgængeligt over kilderne og den højeste fyldningsgrad (%) blandt dem.
|
-- Samlet tilgængeligt over kilderne og den højeste fyldningsgrad (%) blandt dem.
|
||||||
local function sumSources(product)
|
local function sumSources(product)
|
||||||
local total, percent = 0, 0
|
local total, percent, pallets = 0, 0, 0
|
||||||
for _, source in ipairs(product.sources or {}) do
|
for _, source in ipairs(product.sources or {}) do
|
||||||
total = total + (source.available or 0)
|
total = total + (source.available or 0)
|
||||||
|
pallets = pallets + (source.palletCount or 0)
|
||||||
if source.capacity ~= nil and source.capacity > 0 then
|
if source.capacity ~= nil and source.capacity > 0 then
|
||||||
percent = math.max(percent, 100 * (source.level or 0) / source.capacity)
|
percent = math.max(percent, 100 * (source.level or 0) / source.capacity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return total, percent
|
return total, percent, pallets
|
||||||
end
|
end
|
||||||
|
|
||||||
function ADOutboundPlanner.evaluate(product, input)
|
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 percent = product.quote ~= nil and product.quote.percent or nil
|
||||||
local reserve = math.max(0, product.reserve or 0)
|
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 {
|
return {
|
||||||
available = available,
|
available = available,
|
||||||
reserve = reserve,
|
reserve = reserve,
|
||||||
sellable = math.max(0, available - 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,
|
storagePercent = storagePercent,
|
||||||
storageHigh = storagePercent >= (input.storeAbovePercent or 80),
|
storageHigh = storagePercent >= (input.storeAbovePercent or 80),
|
||||||
percent = percent,
|
percent = percent,
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ local function getPalletsNearSpawner(placeable, fillType, farmId)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
local vehicles = g_currentMission ~= nil and g_currentMission.vehicleSystem ~= nil and g_currentMission.vehicleSystem.vehicles or {}
|
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
|
local radius2 = ADSources.PALLET_RADIUS * ADSources.PALLET_RADIUS
|
||||||
for _, vehicle in pairs(vehicles) do
|
for _, vehicle in pairs(vehicles) do
|
||||||
if isPalletVehicle(vehicle) and (vehicle.getOwnerFarmId == nil or vehicle:getOwnerFarmId() == farmId) then
|
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)
|
local x, z = getNodePosition(vehicle.rootNode)
|
||||||
if palletFillType == fillType and x ~= nil and distance2(sx, sz, x, z) <= radius2 then
|
if palletFillType == fillType and x ~= nil and distance2(sx, sz, x, z) <= radius2 then
|
||||||
total = total + level
|
total = total + level
|
||||||
|
count = count + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return total
|
return total, count
|
||||||
end
|
end
|
||||||
|
|
||||||
-- canPallet: varen er en palletype (kan stå på paller); palletLiters: liter på paller ved
|
-- 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 function newProduct(fillType, available, level, capacity, isPallet)
|
||||||
local name = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
|
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
|
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
|
end
|
||||||
|
|
||||||
local function getFactoryProducts(source, farmId)
|
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 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 capacity = storage ~= nil and storage.getCapacity ~= nil and (storage:getCapacity(fillType) or 0) or 0
|
||||||
local isPallet = ADSources.isPalletAt(source, fillType)
|
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 available = level + (isPallet and palletLiters or 0)
|
||||||
local product = newProduct(fillType, available, level, capacity, isPallet)
|
local product = newProduct(fillType, available, level, capacity, isPallet)
|
||||||
product.palletLiters = palletLiters
|
product.palletLiters, product.palletCount = palletLiters, palletCount
|
||||||
table.insert(products, product)
|
table.insert(products, product)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -258,7 +262,9 @@ local function getObjectStorageProducts(source)
|
|||||||
local fillType, perObject = getObjectInfoContent(objectInfo)
|
local fillType, perObject = getObjectInfoContent(objectInfo)
|
||||||
local count = objectInfo.numObjects or 0
|
local count = objectInfo.numObjects or 0
|
||||||
if fillType ~= nil and count > 0 then
|
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
|
||||||
end
|
end
|
||||||
return products
|
return products
|
||||||
|
|||||||
@@ -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.12.13.0</version>
|
<version>1.12.14.0</version>
|
||||||
<title>
|
<title>
|
||||||
<en>AD Smart Pickup</en>
|
<en>AD Smart Pickup</en>
|
||||||
</title>
|
</title>
|
||||||
|
|||||||
@@ -419,11 +419,12 @@ check("O18 reserve spørges ikke for lager-politik", demandCalls[#demandCalls] ~
|
|||||||
local v19 = newVehicle("Dragon", 0, 0, 6000, true)
|
local v19 = newVehicle("Dragon", 0, 0, 6000, true)
|
||||||
v19.carriable = {}
|
v19.carriable = {}
|
||||||
runs[v19] = outboundRun(19, {1}, {{fillType = "SUGAR", policy = "sell"}})
|
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
|
quotes["selling station"][SUGAR].percent = 92
|
||||||
local input19 = ADOutbound.buildPlanInput(adEnv, runs[v19], v19)
|
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 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 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)
|
local v19b = newVehicle("Tipvogn", 0, 0, 20000)
|
||||||
runs[v19b] = outboundRun(20, {1}, {{fillType = "SUGAR", policy = "sell"}})
|
runs[v19b] = outboundRun(20, {1}, {{fillType = "SUGAR", policy = "sell"}})
|
||||||
local input19b = ADOutbound.buildPlanInput(adEnv, runs[v19b], v19b)
|
local input19b = ADOutbound.buildPlanInput(adEnv, runs[v19b], v19b)
|
||||||
|
|||||||
@@ -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}))
|
local e13 = P.evaluate(withReserve, input({}, {capacity = 20000}))
|
||||||
check("P13 evaluate sellable", e13.sellable, 268000)
|
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"))
|
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)
|
||||||
|
|||||||
@@ -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
|
addPallet(BASKET, 1000, 112, 102, 2) -- anden farm: tæller ikke
|
||||||
local products4 = ADSources.getProducts(adEnv, source1, 1)
|
local products4 = ADSources.getProducts(adEnv, source1, 1)
|
||||||
check("S4 paller ved spawner", products4[2].available, 2000)
|
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)
|
check("S4 bulk uændret", products4[1].available, 150000)
|
||||||
addPallet(SUGAR, 2000, 111, 101)
|
addPallet(SUGAR, 2000, 111, 101)
|
||||||
local products4b = ADSources.getProducts(adEnv, source1, 1)
|
local products4b = ADSources.getProducts(adEnv, source1, 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user