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,5 +1,6 @@
|
||||
-- AD Field Silos
|
||||
-- Marksilo-flowet i spillet: samler marksiloer, gårdlagre og ledige vogne, lader ADFieldSiloPlanner vælge,
|
||||
-- med "kør til produktion" går overskud ud over gårdens foderreserve til gårdens fabrikker;
|
||||
-- låner vogne (AutoDrive "Hent og aflever", én tur, parkering bagefter) og frigiver dem igen.
|
||||
-- Lån ligger kun i hukommelsen; opsætningen gemmes i ADSmartPickup_fieldsilos.xml.
|
||||
|
||||
@@ -142,6 +143,53 @@ local function nearStore(stores, x, z)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Fabrikkens input-varer (dem aflæsningen tager imod) med fri plads i dens lager.
|
||||
local function factoryFree(placeable)
|
||||
local spec = placeable ~= nil and placeable.spec_productionPoint or nil
|
||||
local point = spec ~= nil and spec.productionPoint or nil
|
||||
local storage = point ~= nil and point.storage or nil
|
||||
if storage == nil or storage.getFreeCapacity == nil then return {} end
|
||||
local inputs = {}
|
||||
for fillType in pairs(point.inputFillTypeIds or {}) do inputs[fillType] = true end
|
||||
for _, production in ipairs(point.productions or {}) do
|
||||
for _, input in ipairs(production.inputs or {}) do inputs[input.type] = true end
|
||||
end
|
||||
local free = {}
|
||||
for fillType in pairs(inputs) do free[fillType] = storage:getFreeCapacity(fillType) or 0 end
|
||||
return free
|
||||
end
|
||||
|
||||
-- "Kør til produktion": gårdens fabrikker med aflæsningsmarkør bliver mål ved siden af gårdlagrene.
|
||||
local function addFactories(stores, buildings)
|
||||
for _, building in ipairs(buildings) do
|
||||
local markerId = building.kind == "factory" and firstMarker(building, "unload") or nil
|
||||
if markerId ~= nil then
|
||||
local x, z = position(building.placeable ~= nil and building.placeable.rootNode or nil)
|
||||
table.insert(stores, {id = building.id, name = building.name, kind = "production", markerId = markerId,
|
||||
x = x, z = z, free = factoryFree(building.placeable)})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Foderreserve (staldenes døgnforbrug × døgn) og gårdlagrenes beholdning pr. vare.
|
||||
function ADFieldSilos.collectFeed(stores, byId, fid, reserveDays)
|
||||
local reserve, stock = {}, {}
|
||||
local rates = ADSources ~= nil and ADSources.getFarmRates ~= nil and ADSources.getFarmRates(ADFieldSilos.adEnv, fid, true) or {}
|
||||
for fillType, rate in pairs(rates) do reserve[fillType] = (rate.consumption or 0) * reserveDays end
|
||||
local counted = {} -- Farma-siloer i samme klynge deler lager: tæl hvert lager én gang
|
||||
for _, store in ipairs(stores) do
|
||||
local building = byId[store.id]
|
||||
local spec = store.kind ~= "production" and building ~= nil and building.placeable ~= nil and building.placeable.spec_silo or nil
|
||||
for _, storage in pairs(spec ~= nil and spec.storages or {}) do
|
||||
if not counted[storage] then
|
||||
counted[storage] = true
|
||||
for fillType, level in pairs(storage.fillLevels or {}) do stock[fillType] = (stock[fillType] or 0) + (level or 0) end
|
||||
end
|
||||
end
|
||||
end
|
||||
return reserve, stock
|
||||
end
|
||||
|
||||
-- Gårdlagre fra opsætningen + marksiloer (alle markers marksiloer, uden dubletter og uden gårdlagre).
|
||||
function ADFieldSilos.collectBuildings(adEnv)
|
||||
local fid = farmId()
|
||||
@@ -159,6 +207,7 @@ function ADFieldSilos.collectBuildings(adEnv)
|
||||
x = x, z = z, free = siloFree(building.placeable)})
|
||||
end
|
||||
end
|
||||
if ADFieldSilos.config.toProduction then addFactories(stores, ADBuildings.list(adEnv, fid)) end
|
||||
local silos, seen = {}, runBuildingIds()
|
||||
for id in pairs(farmCluster(allSilos, storeIds)) do seen[id] = true end
|
||||
for _, info in ipairs(ADFields.list()) do
|
||||
@@ -175,7 +224,7 @@ function ADFieldSilos.collectBuildings(adEnv)
|
||||
end
|
||||
end
|
||||
end
|
||||
return silos, stores
|
||||
return silos, stores, byId
|
||||
end
|
||||
|
||||
local function trailerInfo(adEnv, vehicle)
|
||||
@@ -335,10 +384,18 @@ end
|
||||
|
||||
function ADFieldSilos.planNow(adEnv)
|
||||
local cfg = ADFieldSilos.config
|
||||
local silos, stores = ADFieldSilos.collectBuildings(adEnv)
|
||||
local silos, stores, byId = ADFieldSilos.collectBuildings(adEnv)
|
||||
local vehicles, vehiclesById = ADFieldSilos.collectVehicles(adEnv)
|
||||
local feedReserve, farmStock = nil, nil
|
||||
if cfg.toProduction then
|
||||
local ok, reserve, stock = pcall(ADFieldSilos.collectFeed, stores, byId, farmId(), cfg.reserveDays)
|
||||
if ok then feedReserve, farmStock = reserve, stock
|
||||
else Logging.warning(ADFieldSilos.LOG_PREFIX .. "foderreserve kunne ikke beregnes: %s", tostring(reserve)) end
|
||||
end
|
||||
local plan = ADFieldSiloPlanner.plan({silos = silos, stores = stores, loans = loanList(), vehicles = vehicles,
|
||||
paused = currentPaused(), maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters})
|
||||
paused = currentPaused(), maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters,
|
||||
feedReserve = feedReserve, farmStock = farmStock})
|
||||
ADFieldSilos.lastFeed = {reserve = feedReserve, stock = farmStock}
|
||||
ADFieldSilos.lastPlan = plan
|
||||
local paused = ADFieldJobs ~= nil and ADFieldJobs.state ~= nil and ADFieldJobs.state.paused
|
||||
if not cfg.enabled or paused then return plan end
|
||||
@@ -395,6 +452,8 @@ function ADFieldSilos.save()
|
||||
xmlFile:setString(ADFieldSilos.ROOT .. "#stores", record.stores)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#maxVehicles", record.maxVehicles)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#minLiters", record.minLiters)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#toProduction", record.toProduction)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#reserveDays", record.reserveDays)
|
||||
xmlFile:save()
|
||||
xmlFile:delete()
|
||||
return true
|
||||
@@ -416,6 +475,8 @@ function ADFieldSilos.load()
|
||||
stores = xmlFile:getString(ADFieldSilos.ROOT .. "#stores"),
|
||||
maxVehicles = xmlFile:getInt(ADFieldSilos.ROOT .. "#maxVehicles"),
|
||||
minLiters = xmlFile:getInt(ADFieldSilos.ROOT .. "#minLiters"),
|
||||
toProduction = xmlFile:getInt(ADFieldSilos.ROOT .. "#toProduction"),
|
||||
reserveDays = xmlFile:getInt(ADFieldSilos.ROOT .. "#reserveDays"),
|
||||
})
|
||||
xmlFile:delete()
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user