feat(marksilo): 'Kør overskud til produktion' — foder først: staldenes forbrug × valgt antal døgn bliver på gården, overskud køres til gårdens fabrikker (v1.44.0.0)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
-- AD Field Silo Planner
|
||||
-- Ren planlægning for marksilo-flowet: hvilke (silo, vare) skal hjem, hvor mange lånte vogne sendes, og til
|
||||
-- hvilket gårdlager. Ingen spil-kald; input muteres ikke.
|
||||
-- hvilket gårdlager eller (med "kør til produktion") hvilken fabrik. Ingen spil-kald; input muteres ikke.
|
||||
|
||||
ADFieldSiloPlanner = {}
|
||||
|
||||
@@ -24,12 +24,16 @@ local function anyStoreTakes(stores, fillType, minLiters, reserved)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Nærmeste lager med plads til hele turen; ellers det med mest plads (over tærsklen).
|
||||
local function chooseStore(stores, silo, fillType, liters, minLiters, reserved)
|
||||
local function isProduction(store)
|
||||
return store ~= nil and store.kind == "production"
|
||||
end
|
||||
|
||||
-- Nærmeste lager af den ønskede slags (fabrik/gård) med plads til hele turen; ellers det med mest plads.
|
||||
local function chooseStore(stores, silo, fillType, liters, minLiters, reserved, production)
|
||||
local best, bestD, most, mostFree = nil, nil, nil, nil
|
||||
for _, store in ipairs(stores or {}) do
|
||||
local free = freeIn(store, fillType, reserved)
|
||||
if store.markerId ~= nil and free >= minLiters then
|
||||
if store.markerId ~= nil and free >= minLiters and isProduction(store) == production then
|
||||
local d = dist2(store, silo)
|
||||
if free >= liters and (bestD == nil or d < bestD) then best, bestD = store, d end
|
||||
if mostFree == nil or free > mostFree then most, mostFree = store, free end
|
||||
@@ -55,19 +59,34 @@ local function nearestVehicle(vehicles, used, silo, fillType)
|
||||
return best
|
||||
end
|
||||
|
||||
-- Foder først: mangler gården stadig foderreserve for varen (reserve − beholdning − læs på vej hjem), køres til
|
||||
-- gårdlager; ellers til fabrik. Findes kun den ene slags, bruges den.
|
||||
local function pickStore(input, farmIncoming, task, liters, minLiters, reserved)
|
||||
local fillType = task.fillType
|
||||
local short = ((input.feedReserve or {})[fillType] or 0) - ((input.farmStock or {})[fillType] or 0) - (farmIncoming[fillType] or 0)
|
||||
local wantProduction = short <= 0
|
||||
return chooseStore(input.stores, task.silo, fillType, liters, minLiters, reserved, wantProduction)
|
||||
or chooseStore(input.stores, task.silo, fillType, liters, minLiters, reserved, not wantProduction)
|
||||
end
|
||||
|
||||
function ADFieldSiloPlanner.plan(input)
|
||||
local minLiters = input.minLiters or 10000
|
||||
local reserved, onWay = {}, {}
|
||||
local storesById = {}
|
||||
for _, store in ipairs(input.stores or {}) do storesById[store.id] = store end
|
||||
local reserved, onWay, farmIncoming = {}, {}, {}
|
||||
for _, loan in ipairs(input.loans or {}) do
|
||||
local k = key(loan.siloId, loan.fillType)
|
||||
onWay[k] = (onWay[k] or 0) + (loan.liters or 0)
|
||||
if loan.storeId ~= nil and not isProduction(storesById[loan.storeId]) then
|
||||
farmIncoming[loan.fillType] = (farmIncoming[loan.fillType] or 0) + (loan.liters or 0)
|
||||
end
|
||||
-- læs på vej til et lager optager pladsen, til de er aflæsset (også i senere runder)
|
||||
if loan.storeId ~= nil then
|
||||
local reserveKey = loan.storeId .. ":" .. tostring(loan.fillType)
|
||||
reserved[reserveKey] = (reserved[reserveKey] or 0) + (loan.liters or 0)
|
||||
end
|
||||
end
|
||||
local status, tasks = {}, {}
|
||||
local status, tasks, statusByKey = {}, {}, {}
|
||||
for _, silo in ipairs(input.silos or {}) do
|
||||
for fillType, liters in pairs(silo.stock or {}) do
|
||||
if (liters or 0) >= minLiters then
|
||||
@@ -85,6 +104,7 @@ function ADFieldSiloPlanner.plan(input)
|
||||
if rest >= minLiters then table.insert(tasks, {silo = silo, fillType = fillType, rest = rest}) end
|
||||
end
|
||||
table.insert(status, entry)
|
||||
statusByKey[k] = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -104,8 +124,13 @@ function ADFieldSiloPlanner.plan(input)
|
||||
local vehicle = nearestVehicle(input.vehicles, used, task.silo, task.fillType)
|
||||
if vehicle == nil then break end
|
||||
local liters = math.min(vehicle.capacity, task.rest)
|
||||
local store = chooseStore(input.stores, task.silo, task.fillType, liters, minLiters, reserved)
|
||||
local store = pickStore(input, farmIncoming, task, liters, minLiters, reserved)
|
||||
if store == nil then break end
|
||||
if isProduction(store) then
|
||||
statusByKey[key(task.silo.id, task.fillType)].toProduction = true
|
||||
else
|
||||
farmIncoming[task.fillType] = (farmIncoming[task.fillType] or 0) + liters
|
||||
end
|
||||
used[vehicle.id] = true
|
||||
local reserveKey = store.id .. ":" .. tostring(task.fillType)
|
||||
reserved[reserveKey] = (reserved[reserveKey] or 0) + liters
|
||||
|
||||
Reference in New Issue
Block a user