diff --git a/FS25_ADSmartPickup/adFlowWagons.lua b/FS25_ADSmartPickup/adFlowWagons.lua index 33b0e18..11de8a5 100644 --- a/FS25_ADSmartPickup/adFlowWagons.lua +++ b/FS25_ADSmartPickup/adFlowWagons.lua @@ -32,6 +32,23 @@ function ADFlowWagons.startAction(s) return "fetch" end +-- Ingen husket vogn: gæt ud fra parkeringsnavnet — en ledig vogn hvis parkering indeholder flowets navn, helst med +-- traktorens nummer til sidst ("Cow Food 3" -> "P Cow Food vogn 3"). candidates = {{id, parkName}}, taken = {[id]=true} +function ADFlowWagons.guessWagon(runName, tractorNumber, candidates, taken) + local wanted = tostring(runName or ""):lower() + if wanted == "" then return nil end + local matching = {} + for _, candidate in ipairs(candidates or {}) do + local park = tostring(candidate.parkName or ""):lower() + if not (taken or {})[candidate.id] and park:find(wanted, 1, true) ~= nil then table.insert(matching, candidate) end + end + table.sort(matching, function(a, b) return tostring(a.parkName) < tostring(b.parkName) end) + for _, candidate in ipairs(matching) do + if tractorNumber ~= nil and tostring(candidate.parkName):match("%s(%d+)$") == tostring(tractorNumber) then return candidate.id end + end + return matching[1] ~= nil and matching[1].id or nil +end + function ADFlowWagons.ownerOf(runs, wagonId) for _, run in ipairs(runs or {}) do for _, id in pairs(run.wagons or {}) do @@ -124,6 +141,37 @@ function ADFlowWagons.isHeldWagon(wagonId) return ADFlowWagons.isHeld(runs(), wagonId) end +-- Frakoblede vogne med parkering, som intet kørende flow holder, og som flowet ikke allerede har givet en traktor. +local function guessFor(adEnv, run, vehicle, tractorId) + local taken = {} + for _, id in pairs(run.wagons or {}) do taken[id] = true end + local candidates = {} + local farmId = g_currentMission:getFarmId() + for _, any in pairs(g_currentMission.vehicleSystem.vehicles) do + local index = any.advd ~= nil and any.advd.parkDestination or nil + local attached = any.getAttacherVehicle ~= nil and any:getAttacherVehicle() ~= nil + if any.spec_motorized == nil and any.spec_attachable ~= nil and not attached and type(index) == "number" and index >= 1 + and any.getOwnerFarmId ~= nil and any:getOwnerFarmId() == farmId then + local id = ADRunsController.getVehicleId(any) + local park = adEnv.ADGraphManager:getMapMarkerById(index) + if id ~= nil and park ~= nil and not ADFlowWagons.isHeld(runs(), id) then + table.insert(candidates, {id = id, parkName = park.name}) + end + end + end + local number = nil + for index, id in ipairs(run.vehicleIds or {}) do + if id == tractorId then number = index end + end + local label = tostring(ADRuns.vehicleLabel(vehicle)) + number = tonumber(label:match("%s(%d+)$")) or number + local wagonId = ADFlowWagons.guessWagon(run.name, number, candidates, taken) + if wagonId ~= nil then + Logging.info(ADFlowWagons.LOG_PREFIX .. "flow '%s': '%s' får vognen ved parkeringen der matcher flowets navn", tostring(run.name), label) + end + return wagonId +end + -- Lånt ud af puljen: markarbejde, marksilo-lån, på hjemtur eller Courseplay kører den. function ADFlowWagons.isPoolBusy(vehicle, tractorId) return (ADFieldJobs ~= nil and ADFieldJobs.state.assignments[tractorId] ~= nil) @@ -137,6 +185,10 @@ function ADFlowWagons.beforeStart(adEnv, run, vehicle) local tractorId = ADRunsController.getVehicleId(vehicle) if fetching[vehicle] ~= nil then return true, {vehicle = vehicle, ok = true, reason = "fetchingWagon"} end local wagonId = (run.wagons or {})[tractorId] + if wagonId == nil and #ADHitch.rearImplementsOf(vehicle) == 0 then + wagonId = guessFor(adEnv, run, vehicle, tractorId) + if wagonId ~= nil then run.wagons = ADFlowWagons.remember(run.wagons, tractorId, wagonId) end + end local wagon = wagonId ~= nil and findAnyVehicle(wagonId) or nil local connectId = wagon ~= nil and connectOf(adEnv, wagon) or nil local action = ADFlowWagons.startAction({ diff --git a/FS25_ADSmartPickup/adRunsController.lua b/FS25_ADSmartPickup/adRunsController.lua index 76247f4..581a325 100644 --- a/FS25_ADSmartPickup/adRunsController.lua +++ b/FS25_ADSmartPickup/adRunsController.lua @@ -1146,7 +1146,7 @@ function ADRunsController.queueStartAll(adEnv) if vehicle ~= nil then local validation = ADRunsController.validateVehicle(adEnv, run, vehicle) -- solo-traktor med husket vogn: henter den ved start (valideringen ser den uden vogn) - if validation.ok or (ADFlowWagons ~= nil and ADFlowWagons.hasWagonFor(run, vehicleId)) then + if validation.ok or (ADFlowWagons ~= nil and (validation.reason == "noTrailer" or ADFlowWagons.hasWagonFor(run, vehicleId))) then table.insert(queue, {runId = run.id, vehicleId = vehicleId}) else table.insert(summary.skipped, {vehicle = vehicle, ok = false, reason = validation.reason, missingBuilding = validation.missingBuilding}) diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index babc9da..4ec19c0 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.51.2.0 + 1.51.3.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adFlowWagons.lua b/tests/test_adFlowWagons.lua index 5ad6900..6b5abed 100644 --- a/tests/test_adFlowWagons.lua +++ b/tests/test_adFlowWagons.lua @@ -57,5 +57,14 @@ check("R4 holdt hvis ET kørende flow har vognen", W.isHeld(runs2, "w1"), true) local seen = {a = true, c = true} check("R+ bygning aldrig set i sessionen tæller ikke som væk", #W.missingBuildings({targetBuildingIds = {"b"}}, {a = true}, seen), 0) check("R+ bygning set og nu væk", W.missingBuildings({targetBuildingIds = {"c"}}, {a = true}, seen)[1], "c") +-- gæt flowets vogn ud fra parkeringsnavnet (ingen husket vogn: vognene var sat på plads før v1.51) +local cands = {{id = "v1", parkName = "P Cow Food vogn 1"}, {id = "v3", parkName = "P Cow Food vogn 3"}, + {id = "g1", parkName = "P Goat Food vogn 1"}, {id = "v2", parkName = "P Cow Food vogn 2"}} +check("gæt: samme nummer", W.guessWagon("Cow Food", 3, cands, {}), "v3") +check("gæt: nummer optaget -> anden med flowets navn", W.guessWagon("Cow Food", 3, cands, {v3 = true}), "v1") +check("gæt: andet flow", W.guessWagon("Goat Food", 2, cands, {}), "g1") +check("gæt: intet passer", W.guessWagon("Pig Food", 1, cands, {}), nil) +check("gæt: store/små bogstaver", W.guessWagon("cow food", 2, cands, {}), "v2") +check("gæt: 'Cow Food 1' matcher ikke 'Cow Food 10'", W.guessWagon("Cow Food", 1, {{id = "x", parkName = "P Cow Food vogn 10"}, {id = "y", parkName = "P Cow Food vogn 1"}}, {}), "y") print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)