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:
@@ -267,6 +267,24 @@ function ADFieldSilos.collectVehicles(adEnv)
|
|||||||
byId[rig.id] = rig.vehicle
|
byId[rig.id] = rig.vehicle
|
||||||
end
|
end
|
||||||
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)
|
local ok, needs = pcall(ADFieldSilos.harvestNeeds, adEnv, rigs)
|
||||||
if ok and #needs > 0 then
|
if ok and #needs > 0 then
|
||||||
local before = #vehicles
|
local before = #vehicles
|
||||||
@@ -277,7 +295,7 @@ function ADFieldSilos.collectVehicles(adEnv)
|
|||||||
end
|
end
|
||||||
why.eligible = #vehicles
|
why.eligible = #vehicles
|
||||||
ADFieldSilos.lastVehicleReasons = why
|
ADFieldSilos.lastVehicleReasons = why
|
||||||
return vehicles, byId
|
return vehicles, byId, poolById
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Høsten først: pr. høster der arbejder (CP kører) holdes dens planlagte antal tømmevogne tilbage, minus dem
|
-- 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))
|
tostring(store ~= nil and store.name or order.storeId))
|
||||||
end
|
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 function release(adEnv, vehicle, reason)
|
||||||
local loan = loans[vehicle]
|
local loan = loans[vehicle]
|
||||||
loans[vehicle] = nil
|
loans[vehicle] = nil
|
||||||
@@ -361,6 +406,14 @@ local function release(adEnv, vehicle, reason)
|
|||||||
pcall(vehicle.stopAutoDrive, vehicle)
|
pcall(vehicle.stopAutoDrive, vehicle)
|
||||||
end
|
end
|
||||||
Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s' frigivet (%s)", tostring(ADRuns.vehicleLabel(vehicle)), tostring(reason))
|
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
|
end
|
||||||
|
|
||||||
function ADFieldSilos.stopAll(adEnv)
|
function ADFieldSilos.stopAll(adEnv)
|
||||||
@@ -378,6 +431,8 @@ local function checkLoans(adEnv)
|
|||||||
else
|
else
|
||||||
local ok, err = pcall(function()
|
local ok, err = pcall(function()
|
||||||
local loan = loans[vehicle]
|
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 stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
|
||||||
local fill = fillLevel(adEnv, vehicle)
|
local fill = fillLevel(adEnv, vehicle)
|
||||||
local vehicleState = {
|
local vehicleState = {
|
||||||
@@ -429,7 +484,7 @@ end
|
|||||||
function ADFieldSilos.planNow(adEnv)
|
function ADFieldSilos.planNow(adEnv)
|
||||||
local cfg = ADFieldSilos.config
|
local cfg = ADFieldSilos.config
|
||||||
local silos, stores, byId = ADFieldSilos.collectBuildings(adEnv)
|
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
|
local feedReserve, farmStock = nil, nil
|
||||||
if cfg.toProduction then
|
if cfg.toProduction then
|
||||||
local ok, reserve, stock = pcall(ADFieldSilos.collectFeed, stores, byId, farmId(), cfg.reserveDays)
|
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
|
if vehicle ~= nil and not hasRoutes(adEnv, vehicle, order) then
|
||||||
vehicle = nil
|
vehicle = nil
|
||||||
end
|
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)
|
local ok, err = pcall(dispatchOne, adEnv, order, vehicle, silosById, storesById)
|
||||||
if not ok then
|
if not ok then
|
||||||
loans[vehicle] = nil
|
loans[vehicle] = nil
|
||||||
|
|||||||
@@ -153,6 +153,25 @@ function ADPool.pairFor(role, fieldX, fieldZ, implements, tractors, blocked, acc
|
|||||||
return nil, "tooWeak", {weakest ~= nil and weakest.neededHp or 0, weakest ~= nil and weakest.name or "?"}
|
return nil, "tooWeak", {weakest ~= nil and weakest.neededHp or 0, weakest ~= nil and weakest.name or "?"}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Alle frie puljeredskaber med rollen, hver parret med den nærmeste endnu ubrugte traktor med nok hk
|
||||||
|
-- (marksilo-flowet planlægger over mange vogne på én gang).
|
||||||
|
function ADPool.pairAll(role, implements, tractors, blocked)
|
||||||
|
blocked = blocked or {}
|
||||||
|
local used, result = {}, {}
|
||||||
|
for _, implement in ipairs(implements or {}) do
|
||||||
|
if hasRole(implement, role) and not blocked[implement.id] then
|
||||||
|
local tractor = nearest(tractors or {}, implement.x, implement.z, function(t)
|
||||||
|
return not used[t.id] and not blocked[t.id] and not t.offNetwork and ADPool.powerOk(t.hp, implement.neededHp)
|
||||||
|
end)
|
||||||
|
if tractor ~= nil then
|
||||||
|
used[tractor.id] = true
|
||||||
|
table.insert(result, {implement = implement, tractor = tractor})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
-- Ventende marker prøver igen på fælles taktslag (ikke hver sin 30 s fra eget forsøg): så udløber de i samme
|
-- Ventende marker prøver igen på fælles taktslag (ikke hver sin 30 s fra eget forsøg): så udløber de i samme
|
||||||
-- tick, og køens rækkefølge (længst ventende først) afgør hvem der får den næste ledige traktor.
|
-- tick, og køens rækkefølge (længst ventende først) afgør hvem der får den næste ledige traktor.
|
||||||
function ADPool.alignedRetry(nowMs, periodMs)
|
function ADPool.alignedRetry(nowMs, periodMs)
|
||||||
|
|||||||
@@ -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.49.0.0</version>
|
<version>1.50.0.0</version>
|
||||||
<title>
|
<title>
|
||||||
<en>AD Smart Pickup</en>
|
<en>AD Smart Pickup</en>
|
||||||
</title>
|
</title>
|
||||||
|
|||||||
@@ -141,5 +141,13 @@ check("bære: vare understøttet", P.canCarry({carries = {[3] = true}}, 3), true
|
|||||||
check("bære: vare ikke understøttet", P.canCarry({carries = {[3] = true}}, 7), false)
|
check("bære: vare ikke understøttet", P.canCarry({carries = {[3] = true}}, 7), false)
|
||||||
check("bære: ingen vare krævet", P.canCarry({carries = {}}, nil), true)
|
check("bære: ingen vare krævet", P.canCarry({carries = {}}, nil), true)
|
||||||
check("bære: ukendt last", P.canCarry({}, 3), false)
|
check("bære: ukendt last", P.canCarry({}, 3), false)
|
||||||
|
-- etape 3: alle puljevogne parret med hver sin nærmeste traktor (en traktor bruges kun én gang)
|
||||||
|
local wagons = {{id = "v1", role = "unloader", x = 0, z = 0}, {id = "v2", role = "unloader", x = 100, z = 0},
|
||||||
|
{id = "v3", role = "unloader", x = 200, z = 0}, {id = "plovX", role = "plow", x = 0, z = 0}}
|
||||||
|
local pairs3 = P.pairAll("unloader", wagons, {{id = "tA", x = 10, z = 0}, {id = "tB", x = 90, z = 0}}, {v2 = true})
|
||||||
|
check("par-alle: antal (v2 reserveret, 2 traktorer)", #pairs3, 2)
|
||||||
|
check("par-alle: v1 -> tA", pairs3[1].implement.id .. ">" .. pairs3[1].tractor.id, "v1>tA")
|
||||||
|
check("par-alle: v3 -> tB (tA er brugt)", pairs3[2].implement.id .. ">" .. pairs3[2].tractor.id, "v3>tB")
|
||||||
|
check("par-alle: ingen traktorer", #P.pairAll("unloader", wagons, {}, {}), 0)
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user