feat: Wait-punkter for rest-læs + læs der passer foretrækkes (v1.7.0.0)
Rest-læs ved fuldt mål: AutoDrive ventede ved aflæsningspunktet 'til tømt' og spærrede køen. Nu omdirigeres den aktuelle UnloadAtDestinationTask (destinationID + drivePathModule:setPathTo) til nærmeste ledige markør med 'Wait' i navnet / mappen Wait (fælles pulje, reservationer pr. køretøj); tilbage når målet har plads til hele resten. Ventende ser rotateTargets=RT_NONE så 'rotér aflæsning' ikke kører videre fra Wait-punktet. Ingen ledige punkter = som i dag + én advarsel. Rangering: varer hvor et fuldt læs (AutoDrive.getAllFillLevels-kapacitet) passer i målet går forud; passer intet, mest trængende. Nyt modul adUnloadWait.lua; ADSmartPickup.getTargetFreeCapacity delt hjælper.
This commit is contained in:
@@ -114,9 +114,46 @@ function ADSupplyPlanner.scoreNeed(level, capacity, freeSpace, minutesToEmpty)
|
||||
return freeSpace / capacity
|
||||
end
|
||||
|
||||
-- nil når læs-størrelsen er ukendt, ellers om et fuldt læs kan komme af i målet.
|
||||
function ADSupplyPlanner.fullLoadFits(freeSpace, loadCapacity)
|
||||
if loadCapacity == nil or loadCapacity <= 0 then
|
||||
return nil
|
||||
end
|
||||
return freeSpace >= loadCapacity
|
||||
end
|
||||
|
||||
-- Wait-punkter: markører med ordet "Wait" i navnet (uanset store/små) eller i mappen "Wait".
|
||||
-- Her venter en traktor med rest-læs, til der igen er plads i målet.
|
||||
function ADSupplyPlanner.isWaitMarker(marker)
|
||||
if marker.group == "Wait" then
|
||||
return true
|
||||
end
|
||||
local name = string.lower(tostring(marker.name or ""))
|
||||
return string.find(name, "%f[%a]wait%f[%A]") ~= nil
|
||||
end
|
||||
|
||||
-- candidates: {{marker, x, z}}; claims: {[marker.id] = køretøj}. Nærmeste punkt der er
|
||||
-- ledigt eller allerede reserveret af dette køretøj. nil hvis alle er optaget.
|
||||
function ADSupplyPlanner.pickNearestFreeWaitPoint(candidates, claims, x, z, vehicle)
|
||||
local best, bestDistance = nil, nil
|
||||
for _, candidate in ipairs(candidates) do
|
||||
local owner = claims[candidate.marker.id]
|
||||
if owner == nil or owner == vehicle then
|
||||
local dx, dz = candidate.x - x, candidate.z - z
|
||||
local distance = dx * dx + dz * dz
|
||||
if bestDistance == nil or distance < bestDistance then
|
||||
best, bestDistance = candidate, distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return best
|
||||
end
|
||||
|
||||
-- needs: {{fillType, level, capacity[, litersPerMinute]}, ...}. Returnerer NY liste,
|
||||
-- mest trængende først; ingredienser uden plads i målet er sorteret fra.
|
||||
function ADSupplyPlanner.rankNeeds(needs)
|
||||
-- loadCapacity (valgfri): vognens kapacitet — varer hvor et FULDT læs kan komme af
|
||||
-- går forud (så vognen ikke ender med rest-læs); passer intet, gælder ren trang.
|
||||
function ADSupplyPlanner.rankNeeds(needs, loadCapacity)
|
||||
local ranked = {}
|
||||
for _, need in ipairs(needs) do
|
||||
local freeSpace = need.capacity - need.level
|
||||
@@ -129,11 +166,15 @@ function ADSupplyPlanner.rankNeeds(needs)
|
||||
freeSpace = freeSpace,
|
||||
litersPerMinute = need.litersPerMinute,
|
||||
minutesToEmpty = minutesToEmpty,
|
||||
fits = ADSupplyPlanner.fullLoadFits(freeSpace, loadCapacity),
|
||||
score = ADSupplyPlanner.scoreNeed(need.level, need.capacity, freeSpace, minutesToEmpty),
|
||||
})
|
||||
end
|
||||
end
|
||||
table.sort(ranked, function(a, b)
|
||||
if a.fits ~= b.fits then
|
||||
return a.fits == true
|
||||
end
|
||||
if a.score ~= b.score then
|
||||
return a.score > b.score
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user