diff --git a/FS25_ADSmartPickup/adRunsController.lua b/FS25_ADSmartPickup/adRunsController.lua index f2a2aed..2b3c491 100644 --- a/FS25_ADSmartPickup/adRunsController.lua +++ b/FS25_ADSmartPickup/adRunsController.lua @@ -309,6 +309,36 @@ function ADRunsController.validateVehicle(adEnv, run, vehicle) return result end +-- Vognens last som INGEN af run'ets mål tager -> {marker, fillType, liters} for en silo der gør +-- (plads >= resten, vejnet til siloen og fra siloen til målet); nil når lasten passer eller +-- ingen silo findes (så kører AD som normalt og Wait-logikken tager over). +function ADRunsController.findWrongCargoDump(adEnv, run, vehicle, targetId) + if ADUnloadWait == nil or ADUnloadWait.getRestLoad == nil or ADLoadSwap == nil or ADLoadSwap.findDumpMarker == nil then + return nil + end + local fillType, liters = ADUnloadWait.getRestLoad(adEnv, vehicle) + if fillType == nil or liters < 100 then + return nil + end + local farmId = ADSmartPickup.getFarmId(vehicle) + for _, entry in ipairs(getTargetStations(adEnv, run, farmId)) do + if ADSmartPickup.getStationLevelAndCapacity(entry.station, fillType, farmId) ~= nil then + return nil + end + end + local isReachable = function(markerId) + return ADUnloadWait.hasRouteBothWays == nil or ADUnloadWait.hasRouteBothWays(adEnv, vehicle, markerId, targetId) + end + local marker = ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, liters, targetId, isReachable) + local fillTypeName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType) + if marker == nil then + Logging.warning(ADRunsController.LOG_PREFIX .. "run '%s': '%s' har %.0f l %s på vognen, som målet ikke tager, og ingen silo med plads/vejnet tager den — AutoDrive starter som normalt", tostring(run.name), tostring(vehicle:getName()), liters, tostring(fillTypeName)) + return nil + end + Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' læsser først %.0f l %s af i %s (markør %s) — målet tager ikke varen", tostring(run.name), tostring(vehicle:getName()), liters, tostring(fillTypeName), tostring(marker.name), tostring(marker.markerIndex or marker.id)) + return {marker = marker, fillType = fillType, liters = liters} +end + -- ---- Start / Stop ---- -- AD gemmer indstillinger som INDEKS i values; useFolders er global, rotateTargets pr. køretøj. @@ -360,7 +390,11 @@ local function applyRunToVehicle(adEnv, run, vehicle, ingredients) local stateModule = vehicle.ad.stateModule local farmId = ADSmartPickup.getFarmId(vehicle) stateModule:setMode(adEnv.AutoDrive.MODE_PICKUPANDDELIVER) - stateModule:setSecondMarkerByWayPointId(ADRunsController.chooseTarget(adEnv, run, vehicle) or run.targetWayPointId) + -- Forkert last på vognen (fx halm fra et tidligere run, mål = sukkerfabrik): første stop + -- bliver en silo der tager varen; næste tur sætter choosePickup målet tilbage til run'ets. + local targetId = ADRunsController.chooseTarget(adEnv, run, vehicle) or run.targetWayPointId + local dump = ADRunsController.findWrongCargoDump(adEnv, run, vehicle, targetId) + stateModule:setSecondMarkerByWayPointId(dump ~= nil and dump.marker.id or targetId) local loadMarker = findNearestLoadMarker(adEnv, vehicle, farmId) if loadMarker ~= nil then stateModule:setFirstMarkerByWayPointId(loadMarker.id) diff --git a/FS25_ADSmartPickup/adSmartPickup.lua b/FS25_ADSmartPickup/adSmartPickup.lua index 802b3b1..74d31db 100644 --- a/FS25_ADSmartPickup/adSmartPickup.lua +++ b/FS25_ADSmartPickup/adSmartPickup.lua @@ -611,11 +611,12 @@ function ADSmartPickup.getIngredientsFor(adEnv, driver) return ADSupplyPlanner.resolveIngredients(supplyState[driver], driver.ad.stateModule:getSelectedFillTypes()) end --- Run med flere mål: ved turens start sættes AD's aflæsningsmål til den stald der mangler --- mest. AD læser først målet når vognen er læsset, så skiftet her gælder for hele turen. +-- Ved turens start sættes AD's aflæsningsmål til run'ets mål — ved flere mål den stald der +-- mangler mest; ved ét mål gendannes det (fx efter at forkert last er læsset af i en silo). +-- AD læser først målet når vognen er læsset, så skiftet her gælder for hele turen. local function chooseRunTarget(adEnv, driver) local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle(driver) or nil - if run == nil or ADRunsController.chooseTarget == nil or #ADRunsController.getRunTargets(run) < 2 then + if run == nil or ADRunsController.chooseTarget == nil or #ADRunsController.getRunTargets(run) < 1 then return end local stateModule = driver.ad.stateModule @@ -626,7 +627,8 @@ local function chooseRunTarget(adEnv, driver) end stateModule:setSecondMarkerByWayPointId(targetId) local marker = adEnv.ADGraphManager.getMapMarkerByWayPointId ~= nil and adEnv.ADGraphManager:getMapMarkerByWayPointId(targetId) or nil - Logging.info(ADSmartPickup.LOG_PREFIX .. "'%s' kører til %s (mangler mest af run'ets mål)", tostring(driver:getName()), marker ~= nil and tostring(marker.name) or tostring(targetId)) + local why = #ADRunsController.getRunTargets(run) > 1 and "mangler mest af run'ets mål" or "run'ets mål" + Logging.info(ADSmartPickup.LOG_PREFIX .. "'%s' kører til %s (%s)", tostring(driver:getName()), marker ~= nil and tostring(marker.name) or tostring(targetId), why) end -- Samlet valg: behovsstyret med ingrediensliste, ellers mappe-logik. nil = AutoDrives original. diff --git a/FS25_ADSmartPickup/adUnloadWait.lua b/FS25_ADSmartPickup/adUnloadWait.lua index 1cace98..545b1c4 100644 --- a/FS25_ADSmartPickup/adUnloadWait.lua +++ b/FS25_ADSmartPickup/adUnloadWait.lua @@ -208,6 +208,10 @@ 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.getRestLoad(adEnv, vehicle) return getRestLoad(adEnv, vehicle) end diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index e803d87..0eba7f3 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.11.5.0 + 1.11.6.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adRunsController.lua b/tests/test_adRunsController.lua index b42414b..845a83c 100644 --- a/tests/test_adRunsController.lua +++ b/tests/test_adRunsController.lua @@ -391,5 +391,26 @@ ADRunsController.deleteRun(stopRun.id, adEnv) check("C17 run slettet -> stoppet", runVehicle.stopped, 2) check("C17 stop logget", logLines[#logLines]:find("stoppet", 1, true) ~= nil, true) +-- C18: forkert last ved Start (halm på vognen, run mod sukkerfabrik) -> første stop = silo der tager halm +ADUnloadWait = {getRestLoad = function(_, v) return v.loadType, v.loadLiters or 0 end, getWaitFor = function() return nil end, + hasRouteBothWays = function() return true end} +ADLoadSwap = {findDumpMarker = function(_, v, fillType, rest, homeId, isReachable) return {id = 44, name = "10 Silo Storage", markerIndex = 2} end} +buildWorld() +addMarker(77, "sugar offload", "Fabrication", 950, 0); unloadAt[77] = {accepts = {[TMR] = 360000}} -- "fabrik" der ikke tager halm (TMR står for roer her) +local sugarVehicle = makeVehicle("vehicleSugar", "Roe-traktor", {STRAW, TMR}, 20000, 100, 0) +sugarVehicle.loadType, sugarVehicle.loadLiters = STRAW, 8000 +local sugar = ADRunsController.createRun("Sugar") +ADRunsController.updateRun(sugar.id, {targetWayPointId = 77}) +ADRunsController.assignVehicle(sugar.id, sugarVehicle) +ADRunsController.startRun(adEnv, sugar.id) +check("C18 første stop = siloen (aflæs forkert last)", sugarVehicle.ad.stateModule.secondMarkerId, 44) +check("C18 logget", logLines[#logLines]:find("læsser", 1, true) ~= nil or logLines[#logLines - 1]:find("læsser", 1, true) ~= nil, true) +-- rigtig last (TMR=roer) -> direkte til fabrikken +sugarVehicle.loadType = TMR +sugarVehicle.ad.stateModule.active = false +ADRunsController.startRun(adEnv, sugar.id) +check("C18 rigtig last -> målet", sugarVehicle.ad.stateModule.secondMarkerId, 77) +ADUnloadWait = nil; ADLoadSwap = nil + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)