fix(marksilo): høsten først — tømmevogne holdes tilbage til høstere der kører (planlagt antal minus udsendte); fabrik kun med plads til hele læsset (v1.45.1.0)

This commit is contained in:
2026-09-28 00:51:15 +02:00
parent 28d2f2c086
commit 5a715bc3e9
7 changed files with 94 additions and 2 deletions
+24
View File
@@ -39,6 +39,9 @@ local function chooseStore(stores, silo, fillType, liters, minLiters, reserved,
if mostFree == nil or free > mostFree then most, mostFree = store, free end
end
end
-- fabrikker kun med plads til hele læsset: en fabrik tager kun det den forbruger, så en vogn med resten
-- holder ved den i timevis (in-game 28/9: 252.000 l kartofler ved en fuld snackfabrik)
if production then return best end
return best or most
end
@@ -69,6 +72,27 @@ local function pickStore(input, farmIncoming, task, liters, minLiters, reserved)
or chooseStore(input.stores, task.silo, fillType, liters, minLiters, reserved, not wantProduction)
end
-- Høsten først: for hvert behov {fillType, count} (høstere i arbejde, der mangler tømmevogne) holdes så mange
-- vogne der kan bære afgrøden tilbage; resten må marksilo-flowet låne. Ny liste; input muteres ikke.
function ADFieldSiloPlanner.withoutHarvestReserve(vehicles, needs)
local held = {}
for _, need in ipairs(needs or {}) do
local left = need.count or 0
for _, vehicle in ipairs(vehicles or {}) do
if left <= 0 then break end
if not held[vehicle.id] and canCarry(vehicle, need.fillType) then
held[vehicle.id] = true
left = left - 1
end
end
end
local free = {}
for _, vehicle in ipairs(vehicles or {}) do
if not held[vehicle.id] then table.insert(free, vehicle) end
end
return free
end
function ADFieldSiloPlanner.plan(input)
local minLiters = input.minLiters or 10000
local storesById = {}
+45 -1
View File
@@ -251,7 +251,8 @@ function ADFieldSilos.collectVehicles(adEnv)
local vehicles, byId = {}, {}
-- hvorfor tømmevogne ikke kan lånes (til fanens statuslinje)
local why = {notEnabled = 0, busy = 0, controlled = 0, noPark = 0}
for _, rig in ipairs(ADFieldWork.getRigs(adEnv)) do
local rigs = ADFieldWork.getRigs(adEnv)
for _, rig in ipairs(rigs) do
-- uden AD-parkeringspunkt bliver vognen holdende på lagerets markør og spærrer for de næste
local canPark = ADFieldWork.parkMarkerId == nil or ADFieldWork.parkMarkerId(adEnv, rig.vehicle) ~= nil
if rig.role == "unloader" then
@@ -266,11 +267,54 @@ function ADFieldSilos.collectVehicles(adEnv)
byId[rig.id] = rig.vehicle
end
end
local ok, needs = pcall(ADFieldSilos.harvestNeeds, adEnv, rigs)
if ok and #needs > 0 then
local before = #vehicles
vehicles = ADFieldSiloPlanner.withoutHarvestReserve(vehicles, needs)
why.harvest = before - #vehicles
elseif not ok then
Logging.warning(ADFieldSilos.LOG_PREFIX .. "høstreserve kunne ikke beregnes: %s", tostring(needs))
end
why.eligible = #vehicles
ADFieldSilos.lastVehicleReasons = why
return vehicles, byId
end
-- Høsten først: pr. høster der arbejder (CP kører) holdes dens planlagte antal tømmevogne tilbage, minus dem
-- markarbejdet allerede har sendt til marken. (in-game 28/9: marksilo-flowet havde lånt begge kartoffelvogne,
-- og ingen kom til roeoptagerne.)
function ADFieldSilos.harvestNeeds(adEnv, rigs)
local assignments = ADFieldJobs ~= nil and ADFieldJobs.state ~= nil and ADFieldJobs.state.assignments or {}
local sent = {}
for _, assignment in pairs(assignments) do
if assignment.role == "unloader" and assignment.fieldId ~= nil then sent[assignment.fieldId] = (sent[assignment.fieldId] or 0) + 1 end
end
local needs = {}
for _, rig in ipairs(rigs) do
if rig.role == "harvester" and ADCpBridge.isWorking(rig.vehicle) then
local assignment = assignments[rig.id]
local fieldId = assignment ~= nil and assignment.fieldId or nil
local field = fieldId ~= nil and ADFieldJobs.getField(fieldId) or nil
local info = fieldId ~= nil and ADFields.getInfo(fieldId) or nil
local count = field ~= nil and ADFieldModel.maxHelpers("harvesting", field.plan) or 1
count = count - (fieldId ~= nil and (sent[fieldId] or 0) or 0)
local fillTypes = {}
if info ~= nil and info.harvestFillType ~= nil then
fillTypes[info.harvestFillType] = true
else
for fruitIndex in pairs(rig.fruits or {}) do
local fruit = g_fruitTypeManager ~= nil and g_fruitTypeManager:getFruitTypeByIndex(fruitIndex) or nil
if fruit ~= nil and fruit.fillType ~= nil then fillTypes[fruit.fillType.index] = true end
end
end
for fillType in pairs(fillTypes) do
if count > 0 then table.insert(needs, {fillType = fillType, count = count}) end
end
end
end
return needs
end
-- ---- lån ----
local function fillTypeName(fillType)
@@ -61,6 +61,10 @@ function SmartPickupFrame:fillFieldSiloRows(adEnv)
self:addTextRow(string.format(i18n:getText("spu_fs_noVehicle"), why.noPark, why.busy, why.controlled, why.notEnabled))
end
if why ~= nil and (why.harvest or 0) > 0 then
self:addTextRow(string.format(i18n:getText("spu_fs_harvestHeld"), why.harvest))
end
self:addTextRow(i18n:getText("spu_fs_silosTitle"))
if plan == nil or #plan.status == 0 then
self:addTextRow(" " .. i18n:getText("spu_fs_nothing"))
+1
View File
@@ -501,5 +501,6 @@
<text name="spu_fs_reserveDays" text="Foderreserve: staldenes forbrug i"/>
<text name="spu_fs_days" text="%d døgn"/>
<text name="spu_fs_toFactory" text="→ fabrik"/>
<text name="spu_fs_harvestHeld" text="%d tømmevogn(e) holdes tilbage til høstere der arbejder"/>
</texts>
</l10n>
+1
View File
@@ -501,5 +501,6 @@
<text name="spu_fs_reserveDays" text="Feed reserve: barn consumption for"/>
<text name="spu_fs_days" text="%d days"/>
<text name="spu_fs_toFactory" text="→ factory"/>
<text name="spu_fs_harvestHeld" text="%d unloading trailer(s) held back for working harvesters"/>
</texts>
</l10n>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107">
<author>masterdraco</author>
<version>1.45.0.0</version>
<version>1.45.1.0</version>
<title>
<en>AD Smart Pickup</en>
</title>