feat(pulje): etape 3 — marksilo-flowet låner også ledig solo-traktor + puljevogn: henter vognen, kører Hent og aflever, sætter vognen af og kører hjem; høstreserven tæller puljevogne (v1.50.0.0)

This commit is contained in:
2026-09-28 18:56:06 +02:00
parent 473f6110bf
commit 6f46bb543a
4 changed files with 93 additions and 4 deletions
+65 -3
View File
@@ -267,6 +267,24 @@ function ADFieldSilos.collectVehicles(adEnv)
byId[rig.id] = rig.vehicle
end
end
-- puljevogne: en ledig solo-traktor henter vognen først (maskinpulje etape 3)
local poolById = {}
if ADPool ~= nil then
local okPool, implements, tractors = pcall(ADPool.collect, adEnv, function(v)
return ADFieldWork.isBusyVehicle(v, ADRunsController.getVehicleId(v))
end)
if okPool then
for _, pair in ipairs(ADPool.pairAll("unloader", implements, tractors, ADPool.blocked(ADFieldJobs.now or 0))) do
local entryId = "pool:" .. tostring(pair.implement.id)
table.insert(vehicles, {id = entryId, x = pair.implement.x, z = pair.implement.z,
capacity = pair.implement.capacity or 0, carries = pair.implement.carries or {}})
byId[entryId] = pair.tractor.vehicle
poolById[entryId] = pair
end
else
Logging.warning(ADFieldSilos.LOG_PREFIX .. "maskinpuljen kunne ikke læses: %s", tostring(implements))
end
end
local ok, needs = pcall(ADFieldSilos.harvestNeeds, adEnv, rigs)
if ok and #needs > 0 then
local before = #vehicles
@@ -277,7 +295,7 @@ function ADFieldSilos.collectVehicles(adEnv)
end
why.eligible = #vehicles
ADFieldSilos.lastVehicleReasons = why
return vehicles, byId
return vehicles, byId, poolById
end
-- Høsten først: pr. høster der arbejder (CP kører) holdes dens planlagte antal tømmevogne tilbage, minus dem
@@ -346,6 +364,33 @@ local function dispatchOne(adEnv, order, vehicle, silosById, storesById)
tostring(store ~= nil and store.name or order.storeId))
end
-- Puljevogn: traktoren henter vognen ved "Connect X" og kører derefter turen som en almindelig tømmevogn.
local function dispatchPool(adEnv, order, pair, silosById, storesById)
local tractor = pair.tractor.vehicle
local silo = silosById[order.siloId]
local owner = {siloId = order.siloId, storeId = order.storeId, siloName = silo ~= nil and silo.name or order.siloId,
fillType = order.fillType, liters = order.liters, startedMs = nowMs, lastProgressMs = nowMs, lastFill = 0, fetching = true}
loans[tractor] = owner
ADPool.reserve(owner, {pair.implement.id, pair.tractor.id})
ADHitch.fetch(adEnv, tractor, pair.implement.connectId, function(_, ok, detail)
ADPool.release(owner)
if loans[tractor] ~= owner then return end -- lånet blev afbrudt imens (Stop alt / flow slået fra)
if not ok then
loans[tractor] = nil
local blamed = ADPool.failureBlames(detail) == "tractor" and pair.tractor.id or pair.implement.id
ADPool.quarantine(blamed, ADFieldJobs.now or 0)
Logging.warning(ADFieldSilos.LOG_PREFIX .. "'%s' kunne ikke hente puljevognen '%s' (%s) — prøver en anden om lidt",
tostring(ADRuns.vehicleLabel(tractor)), tostring(pair.implement.name), tostring(detail))
local park = ADFieldWork.parkMarkerId(adEnv, tractor)
if park ~= nil then ADFieldWork.startAd(adEnv, tractor, adEnv.AutoDrive.MODE_DRIVETO, park, nil) end
return
end
dispatchOne(adEnv, order, tractor, silosById, storesById)
end)
Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s' henter puljevognen '%s' til %d l %s i %s", tostring(ADRuns.vehicleLabel(tractor)),
tostring(pair.implement.name), math.floor(order.liters), fillTypeName(order.fillType), tostring(silo ~= nil and silo.name or order.siloId))
end
local function release(adEnv, vehicle, reason)
local loan = loans[vehicle]
loans[vehicle] = nil
@@ -361,6 +406,14 @@ local function release(adEnv, vehicle, reason)
pcall(vehicle.stopAutoDrive, vehicle)
end
Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s' frigivet (%s)", tostring(ADRuns.vehicleLabel(vehicle)), tostring(reason))
-- puljevogn bag traktoren: sæt den af på sin plads og kør hjem (ikke når spilleren har overtaget)
if reason ~= "player" and ADHitch ~= nil then
local okHome, pooled = pcall(ADHitch.returnHome, adEnv, vehicle)
if not (okHome and pooled) and loan.fetching then
local park = ADFieldWork.parkMarkerId(adEnv, vehicle)
if park ~= nil then ADFieldWork.startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DRIVETO, park, nil) end
end
end
end
function ADFieldSilos.stopAll(adEnv)
@@ -378,6 +431,8 @@ local function checkLoans(adEnv)
else
local ok, err = pcall(function()
local loan = loans[vehicle]
-- henter puljevognen: AD holder stille under koblingen — ikke "færdig"
if loan.fetching then return end
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
local fill = fillLevel(adEnv, vehicle)
local vehicleState = {
@@ -429,7 +484,7 @@ end
function ADFieldSilos.planNow(adEnv)
local cfg = ADFieldSilos.config
local silos, stores, byId = ADFieldSilos.collectBuildings(adEnv)
local vehicles, vehiclesById = ADFieldSilos.collectVehicles(adEnv)
local vehicles, vehiclesById, poolById = ADFieldSilos.collectVehicles(adEnv)
local feedReserve, farmStock = nil, nil
if cfg.toProduction then
local ok, reserve, stock = pcall(ADFieldSilos.collectFeed, stores, byId, farmId(), cfg.reserveDays)
@@ -451,7 +506,14 @@ function ADFieldSilos.planNow(adEnv)
if vehicle ~= nil and not hasRoutes(adEnv, vehicle, order) then
vehicle = nil
end
if vehicle ~= nil then
local pair = poolById ~= nil and poolById[order.vehicleId] or nil
if vehicle ~= nil and pair ~= nil then
local ok, err = pcall(dispatchPool, adEnv, order, pair, silosById, storesById)
if not ok then
loans[vehicle] = nil
Logging.warning(ADFieldSilos.LOG_PREFIX .. "kunne ikke sende '%s' efter puljevogn: %s", tostring(ADRuns.vehicleLabel(vehicle)), tostring(err))
end
elseif vehicle ~= nil then
local ok, err = pcall(dispatchOne, adEnv, order, vehicle, silosById, storesById)
if not ok then
loans[vehicle] = nil