From 9348443f619665e5732e67a4d6cf8109cfefd539 Mon Sep 17 00:00:00 2001 From: masterdraco Date: Sun, 27 Sep 2026 15:18:50 +0200 Subject: [PATCH] =?UTF-8?q?fix(navne):=20navnefilen=20skrives=20i=20spille?= =?UTF-8?q?ts=20gem-hook=20=E2=80=94=20FS25=20genskriver=20savegame-mappen?= =?UTF-8?q?=20og=20slettede=20ADSmartPickup=5Fnames.xml;=20startk=C3=B8=20?= =?UTF-8?q?(=C3=A9n=20traktor=20ad=20gangen)=20forberedt=20(v1.41.1.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adRunsController.lua | 107 ++++++++++++++++++------ FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adRunsController.lua | 27 ++++++ 3 files changed, 111 insertions(+), 25 deletions(-) diff --git a/FS25_ADSmartPickup/adRunsController.lua b/FS25_ADSmartPickup/adRunsController.lua index b1ad08a..bdb0c50 100644 --- a/FS25_ADSmartPickup/adRunsController.lua +++ b/FS25_ADSmartPickup/adRunsController.lua @@ -1072,6 +1072,29 @@ end -- Pr. tildelt traktor: validér, skriv AD-tilstand, start. Afviste traktorer springes over -- og logges med årsag (samme nøgle som fanen viser). +-- Start én traktor i et run: valider, anvend run'et og start AutoDrive. Returnerer resultat-posten. +function ADRunsController.startVehicle(adEnv, run, vehicle) + local validation = ADRunsController.validateVehicle(adEnv, run, vehicle) + local result = {vehicle = vehicle, ok = validation.ok, reason = validation.reason, missingBuilding = validation.missingBuilding} + if not validation.ok then + Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' sprunget over (%s)", tostring(run.name), tostring(ADRuns.vehicleLabel(vehicle)), tostring(validation.reason)) + return result + end + local ingredients = ADRunsController.getRunIngredients(adEnv, run, vehicle) + local ok, err = pcall(applyAndStart, adEnv, run, vehicle, ingredients) + if ok then + ADRunsController.runningRuns[run.id] = true + local second = vehicle.ad.stateModule.getSecondMarker ~= nil and vehicle.ad.stateModule:getSecondMarker() or nil + local target = run.kind == "outbound" and ("kilde " .. tostring(run.sourceWayPointIds[1])) + or ("markør " .. tostring(second ~= nil and second.id or run.targetWayPointId)) + Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' startet mod %s", tostring(run.name), tostring(ADRuns.vehicleLabel(vehicle)), target) + else + result.ok, result.reason = false, "error" + Logging.warning(ADRunsController.LOG_PREFIX .. "run '%s': kunne ikke starte '%s': %s", tostring(run.name), tostring(ADRuns.vehicleLabel(vehicle)), tostring(err)) + end + return result +end + function ADRunsController.startRun(adEnv, runId) local run = ADRuns.getRun(ADRunsController.store, runId) local results = {} @@ -1079,38 +1102,71 @@ function ADRunsController.startRun(adEnv, runId) return results end local vehiclesById = getFarmVehiclesById(adEnv) - local started = 0 for _, vehicleId in ipairs(run.vehicleIds) do local vehicle = vehiclesById[vehicleId] if vehicle ~= nil then - local validation = ADRunsController.validateVehicle(adEnv, run, vehicle) - local result = {vehicle = vehicle, ok = validation.ok, reason = validation.reason, missingBuilding = validation.missingBuilding} - if not validation.ok then - Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' sprunget over (%s)", tostring(run.name), tostring(ADRuns.vehicleLabel(vehicle)), tostring(validation.reason)) - end - if validation.ok then - local ingredients = ADRunsController.getRunIngredients(adEnv, run, vehicle) - local ok, err = pcall(applyAndStart, adEnv, run, vehicle, ingredients) - if ok then - started = started + 1 - local second = vehicle.ad.stateModule.getSecondMarker ~= nil and vehicle.ad.stateModule:getSecondMarker() or nil - local target = run.kind == "outbound" and ("kilde " .. tostring(run.sourceWayPointIds[1])) - or ("markør " .. tostring(second ~= nil and second.id or run.targetWayPointId)) - Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' startet mod %s", tostring(run.name), tostring(ADRuns.vehicleLabel(vehicle)), target) - else - result.ok, result.reason = false, "error" - Logging.warning(ADRunsController.LOG_PREFIX .. "run '%s': kunne ikke starte '%s': %s", tostring(run.name), tostring(ADRuns.vehicleLabel(vehicle)), tostring(err)) - end - end - table.insert(results, result) + table.insert(results, ADRunsController.startVehicle(adEnv, run, vehicle)) end end - if started > 0 then - ADRunsController.runningRuns[runId] = true - end return results end +-- ---- Start alle i kø ---- +-- Én traktor ad gangen med STAGGER_MS mellemrum: ellers kører de sammen fra parkeringspladsen (in-game 27/9). +ADRunsController.STAGGER_MS = 10000 +ADRunsController.startQueue = {} +local staggerTimerMs = 0 + +function ADRunsController.clearStartQueue() + ADRunsController.startQueue = {} +end + +-- Lægger alle traktorer i flows der ikke kører i kø; ugyldige (fx uden vogn) springes over med det samme. +-- Returnerer {queued, alreadyRunning, skipped = {resultater}}. +function ADRunsController.queueStartAll(adEnv) + local summary = {queued = 0, alreadyRunning = 0, skipped = {}} + local vehiclesById = getFarmVehiclesById(adEnv) + local queue = {} + for _, run in ipairs(ADRunsController.store.runs) do + if #run.vehicleIds > 0 then + if ADRunsController.getRunStatus(adEnv, run).isRunning then + summary.alreadyRunning = summary.alreadyRunning + 1 + else + for _, vehicleId in ipairs(run.vehicleIds) do + local vehicle = vehiclesById[vehicleId] + if vehicle ~= nil then + local validation = ADRunsController.validateVehicle(adEnv, run, vehicle) + if validation.ok then + table.insert(queue, {runId = run.id, vehicleId = vehicleId}) + else + table.insert(summary.skipped, {vehicle = vehicle, ok = false, reason = validation.reason, missingBuilding = validation.missingBuilding}) + end + end + end + end + end + end + ADRunsController.startQueue = queue + ADRunsController.startQueueTotal = #queue + staggerTimerMs = ADRunsController.STAGGER_MS -- første startes ved næste tick + summary.queued = #queue + return summary +end + +-- Starter næste traktor i køen, når der er gået STAGGER_MS siden forrige. +function ADRunsController.processStartQueue(adEnv, dt) + if #ADRunsController.startQueue == 0 then return end + staggerTimerMs = staggerTimerMs + (dt or 0) + if staggerTimerMs < ADRunsController.STAGGER_MS then return end + staggerTimerMs = 0 + local item = table.remove(ADRunsController.startQueue, 1) + local run = ADRuns.getRun(ADRunsController.store, item.runId) + local vehicle = run ~= nil and getFarmVehiclesById(adEnv)[item.vehicleId] or nil + if run ~= nil and vehicle ~= nil and not isVehicleActive(vehicle) then + ADRunsController.startVehicle(adEnv, run, vehicle) + end +end + -- En kørende traktor der fjernes fra sit run (eller hvis run slettes) kører run'ets job — -- den stoppes, så den ikke fortsætter uden run. Returnerer true hvis den blev stoppet. function ADRunsController.stopIfRunning(vehicle, reason) @@ -1327,6 +1383,9 @@ function ADRunsController.save() pcall(ADFieldJobs.save) end if ADFieldSilos ~= nil then pcall(ADFieldSilos.save) end + -- navnefilen skal skrives under spillets gem: FS25 genskriver savegame-mappen, og filer ingen skriver + -- under gemningen forsvinder (in-game 27/9: ADSmartPickup_names.xml blev slettet ved første gem) + if ADNames ~= nil and ADNames.byId ~= nil then pcall(ADNames.save) end return saved end diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index 10b470c..bad3104 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.41.0.0 + 1.41.1.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adRunsController.lua b/tests/test_adRunsController.lua index e91ea62..4040129 100644 --- a/tests/test_adRunsController.lua +++ b/tests/test_adRunsController.lua @@ -836,5 +836,32 @@ do check("SA isRunning ryddet", ADRunsController.getRunStatus(adEnv, ADRuns.getRun(ADRunsController.store, runA.id)).isRunning, false) end + +-- C20: Start alle i kø — én traktor ad gangen med STAGGER_MS mellemrum (in-game 27/9: ellers kører de +-- sammen på parkeringspladsen); pause ophæves +do + buildWorld() + local q1 = makeVehicle("vehicleQ1", "Q1", {STRAW, TMR}, 1000000, 100, 0) + local q2 = makeVehicle("vehicleQ2", "Q2", {STRAW, TMR}, 1000000, 110, 0) + local q3 = makeVehicle("vehicleQ3", "Q3", {}, 0, 120, 0) -- ingen vogn -> springes over, ikke i kø + local qrun = ADRunsController.createRun("Kø") + ADRunsController.updateRun(qrun.id, {targetWayPointIds = {94}}) + ADRunsController.assignVehicle(qrun.id, q1) + ADRunsController.assignVehicle(qrun.id, q2) + ADRunsController.assignVehicle(qrun.id, q3) + local summary = ADRunsController.queueStartAll(adEnv) + check("C20 to i kø", summary.queued, 2) + check("C20 en sprunget over", #summary.skipped, 1) + check("C20 intet startet før første tick", (q1.started or 0) + (q2.started or 0), 0) + ADRunsController.processStartQueue(adEnv, 0) + check("C20 første startes straks", (q1.started or 0) + (q2.started or 0), 1) + ADRunsController.processStartQueue(adEnv, ADRunsController.STAGGER_MS - 1) + check("C20 næste venter mellemrummet", (q1.started or 0) + (q2.started or 0), 1) + ADRunsController.processStartQueue(adEnv, 1) + check("C20 næste efter mellemrummet", (q1.started or 0) + (q2.started or 0), 2) + check("C20 kø tom", #ADRunsController.startQueue, 0) + check("C20 run markeret kørende", ADRunsController.runningRuns[qrun.id], true) +end + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)