Files
fs25-adsmartpickup/FS25_ADSmartPickup/adUnloadWait.lua
T

460 lines
23 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- AD Unload Wait
-- Holder en traktor med rest-læs ved en fuld stald AutoDrive i dag stille ved
-- aflæsningspunktet "til den er tømt på en eller anden måde" — og spærrer for
-- de næste i køen. Her omdirigeres den i stedet til nærmeste ledige Wait-punkt
-- (markør i en mappe med ordet "Wait" i navnet, fx "Cow Wait"), og når målet igen
-- har plads til HELE resten, sendes den tilbage og læsser af.
--
-- Kun den aktuelle aflæsningsopgaves destination ændres; AutoDrives mål,
-- rotation og loop-tæller røres ikke.
ADUnloadWait = {}
-- Under dette regnes vognen som tom (AutoDrive selv bruger 0,1 l).
ADUnloadWait.MIN_REST_LITERS = 100
-- Kan målet tage mindre end dette, regnes det som fuldt (aflæsning starter ikke).
ADUnloadWait.MIN_FREE_TO_UNLOAD = 100
ADUnloadWait.LOG_PREFIX = "ADSmartPickup: "
-- køretøj -> {task, homeDestinationID, waitMarker, fillType, rest}
local waits = setmetatable({}, {__mode = "k"})
local warnedNoWaitPoint = setmetatable({}, {__mode = "k"})
local isInstalled = false
-- Den vare og mængde der er tilbage på vognen (største fyldte aflæsselige enhed).
local function getRestLoad(adEnv, vehicle)
local bestFillType, bestLevel = nil, 0
for _, unit in ipairs(adEnv.AutoDrive.getAllDischargeableUnits(vehicle) or {}) do
local object = unit.object
if object ~= nil and object.getFillUnitFillLevel ~= nil then
local level = object:getFillUnitFillLevel(unit.fillUnitIndex) or 0
if level > bestLevel then
bestLevel = level
bestFillType = object.getFillUnitFillType ~= nil and object:getFillUnitFillType(unit.fillUnitIndex) or nil
end
end
end
return bestFillType, bestLevel
end
local function getWaitPoolGroup(vehicle)
local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle(vehicle) or nil
return run ~= nil and run.waitPoolGroup or nil
end
-- Rutetjek, reservationer og omdirigering deles med udkørsels-modulet (adWaitPool).
-- Kun "til punktet" ved silo-aflæsning: næste tur er AD's egen rute fra siloen.
local function hasRouteTo(adEnv, vehicle, wayPointId)
return ADWaitPool.hasRouteTo(adEnv, vehicle, wayPointId)
end
local function hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
return ADWaitPool.hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
end
local function redirect(task, destinationID)
ADWaitPool.redirect(task, destinationID)
end
-- køretøj -> AD's oprindelige 2. markør (waypoint-id) mens der læsses af i en silo
local pendingTargetRestore = setmetatable({}, {__mode = "k"})
-- Aflæsning ved en ANDEN destination end AD's mål: AD tipper kun når vognen er tæt på
-- AD's egen 2. markør (getDistanceToUnloadPosition), så den skiftes midlertidigt til
-- siloen og gendannes når opgaven er færdig.
local function redirectForUnload(task, destinationID)
local vehicle = task.vehicle
local stateModule = vehicle.ad.stateModule
local current = stateModule.getSecondMarker ~= nil and stateModule:getSecondMarker() or nil
if current ~= nil and current.id ~= destinationID and stateModule.setSecondMarkerByWayPointId ~= nil then
pendingTargetRestore[vehicle] = pendingTargetRestore[vehicle] or current.id
stateModule:setSecondMarkerByWayPointId(destinationID)
end
redirect(task, destinationID)
end
local function restoreTarget(vehicle)
local homeId = pendingTargetRestore[vehicle]
if homeId == nil then
return
end
pendingTargetRestore[vehicle] = nil
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
if stateModule ~= nil and stateModule.setSecondMarkerByWayPointId ~= nil then
stateModule:setSecondMarkerByWayPointId(homeId)
end
end
local function release(vehicle)
if waits[vehicle] ~= nil then
ADWaitPool.releaseVehicle(vehicle)
end
waits[vehicle] = nil
if ADLoadSwap ~= nil then
ADLoadSwap.clearWarning(vehicle)
end
end
-- "Fremme ved målet": AD stopper vognen så snart den står i aflæsningstriggeren — ofte
-- 5–10 m FØR markøren, så isTargetReached() bliver aldrig sand (set ved sukkerfabrikken).
-- Derfor tæller også AD's eget mål for tipning (afstand til aflæsningsstedet inden for
-- AD's trigger-afstand) og at AD er i gang med at tippe.
local function isAtUnloadTarget(adEnv, vehicle)
if vehicle.ad.drivePathModule:isTargetReached() then
return true
end
local trailerModule = vehicle.ad.trailerModule
if trailerModule ~= nil and trailerModule.isUnloading then
return true
end
local autoDrive = adEnv.AutoDrive
if autoDrive.getDistanceToUnloadPosition ~= nil and autoDrive.getMaxTriggerDistance ~= nil then
local ok, distance = pcall(autoDrive.getDistanceToUnloadPosition, vehicle)
local okMax, maxDistance = pcall(autoDrive.getMaxTriggerDistance, vehicle)
if ok and okMax and type(distance) == "number" and type(maxDistance) == "number" then
return distance <= maxDistance
end
end
return false
end
-- Står køretøjet ved målet med rest-læs, som målet ikke kan tage? Så find et Wait-punkt.
ADUnloadWait.MIN_FREE_FOR_OTHER_TARGET = 1000
-- Det af run'ets ANDRE mål der tager varen og har mest fri plads (≥ MIN_FREE_FOR_OTHER_TARGET) og vej.
local function findOtherTargetForRest(adEnv, vehicle, fillType, currentId)
local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle ~= nil and ADRunsController.getRunForVehicle(vehicle) or nil
if run == nil or (run.kind or "supply") ~= "supply" or vehicle.ad.stateModule.setSecondMarkerByWayPointId == nil then
return nil
end
local best, bestFree = nil, ADUnloadWait.MIN_FREE_FOR_OTHER_TARGET - 1
for _, targetId in ipairs(ADRunsController.getRunTargets(run)) do
if targetId ~= currentId then
local free = ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType, false, targetId)
if free ~= nil and free > bestFree and hasRouteTo(adEnv, vehicle, targetId) then
local marker = adEnv.ADGraphManager.getMapMarkerByWayPointId ~= nil and adEnv.ADGraphManager:getMapMarkerByWayPointId(targetId) or nil
best, bestFree = {id = targetId, name = marker ~= nil and marker.name or tostring(targetId)}, free
end
end
end
return best, bestFree
end
local function startWaiting(adEnv, task)
local vehicle = task.vehicle
-- Kun "fremme ved målet". At AD stadig regner vognen som aflæssende (isActiveAtTrigger)
-- tæller IKKE med: ved et fuldt fodertrug bliver isUnloading stående for evigt, selv om
-- intet løber — og så blokerede traktoren stalden i stedet for at køre til Wait.
if not isAtUnloadTarget(adEnv, vehicle) then
return
end
-- Efter et bytte er opgavens mål en silo, ikke AD's rigtige aflæsningsmål (anden markør);
-- der skal AD bare læsse af som normalt, uden Wait-logik.
local target = vehicle.ad.stateModule.getSecondMarker ~= nil and vehicle.ad.stateModule:getSecondMarker() or nil
if target == nil or task.destinationID ~= target.id then
return
end
local fillType, rest = getRestLoad(adEnv, vehicle)
if fillType == nil then
return
end
if rest < ADUnloadWait.MIN_REST_LITERS then
-- En lille rest som målet ikke kan tage: AutoDrive venter ellers for evigt i triggeren
-- ("til den er tømt") og spærrer for de næste. Regn vognen som tom og kør videre.
local smallFree = ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType)
if rest > 0 and (smallFree == nil or smallFree < rest) and task.finished ~= nil then
Logging.info(ADUnloadWait.LOG_PREFIX .. "'%s': %.0f l %s rest kan ikke komme af — regnes som tom, kører videre", tostring(ADRuns.vehicleLabel(vehicle)), rest, g_fillTypeManager ~= nil and tostring(g_fillTypeManager:getFillTypeNameByIndex(fillType)) or tostring(fillType))
task:finished()
end
return
end
local free, capacity = ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType)
-- nil = målet tager slet ikke varen (forkert last fra et tidligere run): som "fuldt"
local isRejected = free == nil and ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType, true) == false
if isRejected then
free = 0
end
if free == nil or free >= ADUnloadWait.MIN_FREE_TO_UNLOAD then
return
end
-- Run med flere mål: resten køres til det af run'ets andre mål der har mest plads til varen,
-- før der ventes (en 2,4M l-vogn kan ellers aldrig komme af med resten ved én svinesti)
local other, otherFree = findOtherTargetForRest(adEnv, vehicle, fillType, target.id)
if other ~= nil then
vehicle.ad.stateModule:setSecondMarkerByWayPointId(other.id)
redirect(task, other.id)
Logging.info(ADUnloadWait.LOG_PREFIX .. "'%s': %s er fuld — resten (%.0f l %s) køres til %s (%.0f l fri)", tostring(ADRuns.vehicleLabel(vehicle)), tostring(target.name), rest,
g_fillTypeManager ~= nil and tostring(g_fillTypeManager:getFillTypeNameByIndex(fillType)) or tostring(fillType), tostring(other.name), otherFree)
return
end
local isReachable = function(candidate)
return hasRouteBothWays(adEnv, vehicle, candidate.marker.id, task.destinationID)
end
local pool = getWaitPoolGroup(vehicle)
local candidate = ADWaitPool.pickFree(adEnv, vehicle, pool, isReachable)
if candidate == nil then
if not warnedNoWaitPoint[vehicle] then
warnedNoWaitPoint[vehicle] = true
local poolText = pool ~= nil and pool ~= "" and (" i puljen '" .. pool .. "'") or ""
Logging.warning(ADUnloadWait.LOG_PREFIX .. "'%s' har %.0f l rest, og målet er fuldt — intet ledigt Wait-punkt%s med vejnet til OG fra målet (markør i en mappe med 'Wait' i navnet), så AutoDrive venter ved målet", tostring(ADRuns.vehicleLabel(vehicle)), rest, poolText)
end
return
end
warnedNoWaitPoint[vehicle] = nil
ADWaitPool.claim(candidate.marker.id, vehicle)
waits[vehicle] = {task = task, homeDestinationID = task.destinationID, waitMarker = candidate.marker, fillType = fillType, rest = rest}
-- AD tipper (og holder vognen stille) så længe den står nær sit EGET mål — også i små
-- portioner, når målet forbruger løbende. Derfor peger AD's mål på Wait-punktet imens.
redirectForUnload(task, candidate.marker.id)
local fillTypeName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
Logging.info(ADUnloadWait.LOG_PREFIX .. "'%s' venter ved %s (markør %s): %.0f l %s rest, målet har kun %.0f l fri", tostring(ADRuns.vehicleLabel(vehicle)), tostring(candidate.marker.name), tostring(candidate.marker.markerIndex or candidate.marker.id), rest, tostring(fillTypeName), free)
end
-- Ventende køretøj: er der nu plads til hele resten, køres tilbage til målet.
local function updateWaiting(adEnv, task, wait, dt)
local vehicle = task.vehicle
if wait.task ~= task then
release(vehicle)
return
end
local fillType, rest = getRestLoad(adEnv, vehicle)
if fillType == nil or rest < ADUnloadWait.MIN_REST_LITERS then
release(vehicle)
return
end
-- Friske tal til evt. bytte og til tilbage-loggen — ikke dem fra da ventningen startede.
wait.fillType, wait.rest = fillType, rest
local home = wait.homeDestinationID
local free, capacity = ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType, nil, home)
local isRejected = free == nil and ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType, true, home) == false
if isRejected then
free = 0
end
wait.isRejected = isRejected
-- run'ets "kør hjem under X %" (fri ≥ (100-X) % af kapaciteten), ellers standardreglen
local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle(vehicle) or nil
local freeFraction = run ~= nil and run.returnBelowPercent ~= nil and (1 - run.returnBelowPercent / 100) or nil
if free == nil or not ADSupplyPlanner.canUnloadRest(free, rest, capacity, freeFraction) then
if ADLoadSwap ~= nil then
local isReachable = function(markerId)
return hasRouteTo(adEnv, vehicle, markerId)
end
ADLoadSwap.tryFromWait(adEnv, task, wait, dt, redirectForUnload, release, isReachable)
end
return
end
release(vehicle)
restoreTarget(vehicle)
redirect(task, home)
Logging.info(ADUnloadWait.LOG_PREFIX .. "'%s' kører tilbage fra %s og læsser %.0f l af (målet har %.0f l fri)", tostring(ADRuns.vehicleLabel(vehicle)), tostring(wait.waitMarker.name), rest, free)
end
-- Diagnose (midlertidig): mens en traktor holder ved sit mål med last, logges hvert 15. s hvad
-- AD ser — vognens indhold, målets fri plads, AD's aflæsningstilstand og vognens dischargeState.
ADUnloadWait.DEBUG_INTERVAL_MS = 15000
local debugTimers = setmetatable({}, {__mode = "k"})
local function debugAtTarget(adEnv, task, dt)
local vehicle = task.vehicle
local targetReached = vehicle.ad.drivePathModule:isTargetReached()
debugTimers[vehicle] = (debugTimers[vehicle] or ADUnloadWait.DEBUG_INTERVAL_MS) + (dt or 0)
if debugTimers[vehicle] < ADUnloadWait.DEBUG_INTERVAL_MS then
return
end
debugTimers[vehicle] = 0
local fillType, rest = getRestLoad(adEnv, vehicle)
if fillType == nil or rest < ADUnloadWait.MIN_REST_LITERS then
return
end
local free, capacity = ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType)
-- kun den tilstand vi vil se: målet fuldt/afvist, og traktoren venter ikke ved et Wait-punkt
if waits[vehicle] ~= nil or (free ~= nil and free >= ADUnloadWait.MIN_FREE_TO_UNLOAD) then
return
end
local trailerModule = vehicle.ad.trailerModule
local states = {}
for _, unit in ipairs(adEnv.AutoDrive.getAllDischargeableUnits(vehicle) or {}) do
local object = unit.object
local state = object ~= nil and object.getDischargeState ~= nil and object:getDischargeState() or "?"
local canDischarge = "?"
if object ~= nil and object.getCanDischargeToObject ~= nil and object.getCurrentDischargeNode ~= nil then
local ok, value = pcall(function() return object:getCanDischargeToObject(object:getCurrentDischargeNode()) end)
canDischarge = ok and tostring(value) or "err"
end
table.insert(states, string.format("dischargeState=%s canDischargeToObject=%s", tostring(state), canDischarge))
end
local fillTypeName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
local distance = adEnv.AutoDrive.getDistanceToUnloadPosition ~= nil and adEnv.AutoDrive.getDistanceToUnloadPosition(vehicle) or -1
local secondMarker = vehicle.ad.stateModule.getSecondMarker ~= nil and vehicle.ad.stateModule:getSecondMarker() or nil
Logging.info(ADUnloadWait.LOG_PREFIX .. "DEBUG '%s': targetReached=%s taskDest=%s adMål=%s; %.0f l %s på vognen; målet fri=%s/kap=%s; AD isUnloading=%s isLoading=%s afstandTilAflæsning=%.1f; venter=%s; %s", tostring(ADRuns.vehicleLabel(vehicle)), tostring(targetReached), tostring(task.destinationID), tostring(secondMarker ~= nil and secondMarker.id or nil), rest, tostring(fillTypeName), tostring(free), tostring(capacity), tostring(trailerModule ~= nil and trailerModule.isUnloading), tostring(trailerModule ~= nil and trailerModule.isLoading), tonumber(distance) or -1, tostring(waits[vehicle] ~= nil), table.concat(states, " | "))
end
function ADUnloadWait.beforeUpdate(adEnv, task, dt)
-- Udkørsels-traktorer: plads i målet er tjekket før turen, og målet skiftes pr. tur — ingen Wait-logik.
if ADOutbound ~= nil and ADOutbound.isOutboundVehicle ~= nil and ADOutbound.isOutboundVehicle(task.vehicle) then
return
end
-- Tømning efter stop (ADFlowWagons): ingen Wait-pulje eller læs-bytte — den skal tømme og hjem
-- (in-game 29/9: Goat Food blev sendt til Cow Wait efter Stop alt)
if ADFlowWagons ~= nil and ADFlowWagons.isEmptying ~= nil and ADFlowWagons.isEmptying(task.vehicle) then
if waits[task.vehicle] ~= nil then release(task.vehicle) end
return
end
pcall(debugAtTarget, adEnv, task, dt)
local wait = waits[task.vehicle]
if wait ~= nil then
updateWaiting(adEnv, task, wait, dt)
else
startWaiting(adEnv, task)
end
end
-- Efter en genindlæsning er ventetilstanden (kun i hukommelsen) væk, men AutoDrives gemte mål
-- peger stadig på Wait-punktet, og traktoren står der med rest-læs — uden dette ville den blive
-- stående for evigt. Her genoptages ventningen for aktive traktorer i et forsynings-run hvis
-- aflæsningsopgave peger på en Wait-markør: hjem = run'ets mål, og reservationen sættes igen.
-- Kaldes fra ADSmartPickup:update (throttlet).
ADUnloadWait.ADOPT_INTERVAL_MS = 5300
local adoptTimerMs = ADUnloadWait.ADOPT_INTERVAL_MS
function ADUnloadWait.adoptOrphans(adEnv)
if ADRunsController == nil or ADRunsController.getFarmVehicles == nil then
return
end
for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
local isActive = stateModule ~= nil and stateModule.isActive ~= nil and stateModule:isActive()
local run = isActive and waits[vehicle] == nil and ADRunsController.getRunForVehicle(vehicle) or nil
if run ~= nil and (run.kind or "supply") == "supply" and stateModule.getSecondMarker ~= nil then
local marker = stateModule:getSecondMarker()
local task = vehicle.ad.taskModule ~= nil and vehicle.ad.taskModule.getActiveTask ~= nil and vehicle.ad.taskModule:getActiveTask() or nil
if marker ~= nil and marker.id ~= nil and ADSupplyPlanner.isWaitMarker(marker) and task ~= nil and task.destinationID == marker.id and task.trailers ~= nil then
local fillType, rest = getRestLoad(adEnv, vehicle)
local homeId = ADRunsController.chooseTarget ~= nil and ADRunsController.chooseTarget(adEnv, run, vehicle) or run.targetWayPointId
if fillType ~= nil and rest >= ADUnloadWait.MIN_REST_LITERS and homeId ~= nil then
ADWaitPool.claim(marker.id, vehicle)
pendingTargetRestore[vehicle] = homeId
waits[vehicle] = {task = task, homeDestinationID = homeId, waitMarker = marker, fillType = fillType, rest = rest}
local fillTypeName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
Logging.info(ADUnloadWait.LOG_PREFIX .. "'%s' genoptager ventning ved %s efter genindlæsning: %.0f l %s rest, hjem = markør %s", tostring(ADRuns.vehicleLabel(vehicle)), tostring(marker.name), rest, tostring(fillTypeName), tostring(homeId))
end
end
end
end
end
function ADUnloadWait.adoptOrphansThrottled(adEnv, dt)
adoptTimerMs = adoptTimerMs + (dt or 0)
if adoptTimerMs < ADUnloadWait.ADOPT_INTERVAL_MS then
return
end
adoptTimerMs = 0
local ok, err = pcall(ADUnloadWait.adoptOrphans, adEnv)
if not ok then
Logging.warning(ADUnloadWait.LOG_PREFIX .. "kunne ikke genoptage ventende traktorer: %s", tostring(err))
end
end
-- Kaldes fra ADSmartPickup:update — standsede køretøjer slipper deres Wait-punkt.
function ADUnloadWait.releaseInactive()
for vehicle in pairs(waits) do
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
if stateModule == nil or stateModule.isActive == nil or not stateModule:isActive() then
release(vehicle)
end
end
for vehicle in pairs(pendingTargetRestore) do
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
if stateModule == nil or stateModule.isActive == nil or not stateModule:isActive() then
restoreTarget(vehicle)
end
end
end
function ADUnloadWait.getPendingTargetRestore(vehicle)
return pendingTargetRestore[vehicle]
end
-- Ved Start med forkert last: AD's mål peger på siloen indtil aflæsningen er færdig;
-- det oprindelige mål gendannes af finished-hook'en.
function ADUnloadWait.setDumpTarget(vehicle, dumpWayPointId)
local stateModule = vehicle.ad.stateModule
local current = stateModule.getSecondMarker ~= nil and stateModule:getSecondMarker() or nil
if current ~= nil and current.id ~= dumpWayPointId then
pendingTargetRestore[vehicle] = pendingTargetRestore[vehicle] or current.id
end
if stateModule.setSecondMarkerByWayPointId ~= nil then
stateModule:setSecondMarkerByWayPointId(dumpWayPointId)
end
end
-- Hvem holder hvor (GUI'ets Wait-puljer-visning). Sorteret på mappe, dernæst markør-id.
-- Vognens indhold (største enhed) og evt. Wait-tilstand — til overblikket i fanen.
function ADUnloadWait.hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPointId)
return hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPointId)
end
function ADUnloadWait.hasRouteTo(adEnv, vehicle, wayPointId)
return hasRouteTo(adEnv, vehicle, wayPointId)
end
function ADUnloadWait.getRestLoad(adEnv, vehicle)
return getRestLoad(adEnv, vehicle)
end
function ADUnloadWait.getWaitFor(vehicle)
local wait = waits[vehicle]
if wait == nil then
return nil
end
return {markerName = wait.waitMarker ~= nil and wait.waitMarker.name or nil, fillType = wait.fillType, rest = wait.rest}
end
-- Alle reservationer i puljen (også udkørsels-traktorer der holder).
function ADUnloadWait.getClaims(adEnv)
return ADWaitPool.getClaims(adEnv)
end
function ADUnloadWait.install(adEnv)
local task, autoDrive = adEnv.UnloadAtDestinationTask, adEnv.AutoDrive
if isInstalled or task == nil or task.update == nil or autoDrive == nil or autoDrive.getSetting == nil then
return
end
isInstalled = true
ADUnloadWait.STATE_DRIVING = task.STATE_DRIVING or 2
ADWaitPool.STATE_DRIVING = ADUnloadWait.STATE_DRIVING
local originalUpdate, originalFinished, originalGetSetting = task.update, task.finished, autoDrive.getSetting
task.update = function(self, dt)
local ok, err = pcall(ADUnloadWait.beforeUpdate, adEnv, self, dt)
if not ok then
Logging.warning(ADUnloadWait.LOG_PREFIX .. "fejl i Wait-punkt-logik, AutoDrive fortsætter selv: %s", tostring(err))
release(self.vehicle)
end
return originalUpdate(self, dt)
end
if originalFinished ~= nil then
task.finished = function(self)
release(self.vehicle)
restoreTarget(self.vehicle)
-- læsset er afleveret: tæller ikke længere som "på vej" for de andre traktorer
if ADSmartPickup ~= nil and ADSmartPickup.clearEnRoute ~= nil then
ADSmartPickup.clearEnRoute(self.vehicle)
end
return originalFinished(self)
end
end
-- Ved "rotér aflæsning" kører AutoDrive straks videre fra et mål den ikke kan læsse
-- af ved — også fra Wait-punktet. Ventende køretøjer ser derfor rotationen som slået fra.
autoDrive.getSetting = function(settingName, vehicle)
if settingName == "rotateTargets" and vehicle ~= nil and waits[vehicle] ~= nil then
return autoDrive.RT_NONE
end
return originalGetSetting(settingName, vehicle)
end
end