feat: flere mål pr. run (afkrydsning; den stald der mangler mest får turen, AD's mål skiftes ved turstart) + under-faner Overblik/Runs (v1.11.0.0)

This commit is contained in:
2026-09-23 01:56:47 +02:00
parent 69a98984bb
commit bcd7de8344
12 changed files with 376 additions and 113 deletions
+19
View File
@@ -107,6 +107,25 @@ check("R7 i records", r7rec[1].returnBelow, 25)
check("R7 tilbage fra records", ADRuns.fromRecords(r7rec).runs[1].returnBelowPercent, 25)
check("R7 manglende i gammel fil -> 50", ADRuns.fromRecords({{id = 1, name = "Gammel"}}).runs[1].returnBelowPercent, 50)
-- R8: flere mål pr. run — liste + første som "primært" mål (bagudkompatibelt); toggle; records
local r8, r8run = ADRuns.createRun(ADRuns.newStore(), "Kvæg")
check("R8 ingen mål", #r8run.targetWayPointIds, 0)
r8 = ADRuns.updateRun(r8, r8run.id, {targetWayPointIds = {94, 99}})
check("R8 to mål", table.concat(ADRuns.getRun(r8, r8run.id).targetWayPointIds, ","), "94,99")
check("R8 primært mål = første", ADRuns.getRun(r8, r8run.id).targetWayPointId, 94)
r8 = ADRuns.toggleTarget(r8, r8run.id, 94)
check("R8 toggle fjerner", table.concat(ADRuns.getRun(r8, r8run.id).targetWayPointIds, ","), "99")
check("R8 primært følger med", ADRuns.getRun(r8, r8run.id).targetWayPointId, 99)
r8 = ADRuns.toggleTarget(r8, r8run.id, 120)
check("R8 toggle tilføjer", table.concat(ADRuns.getRun(r8, r8run.id).targetWayPointIds, ","), "99,120")
check("R8 gammel enkelt-sætning = liste med ét", table.concat(ADRuns.getRun(ADRuns.updateRun(r8, r8run.id, {targetWayPointId = 7}), r8run.id).targetWayPointIds, ","), "7")
check("R8 false rydder listen", #ADRuns.getRun(ADRuns.updateRun(r8, r8run.id, {targetWayPointId = false}), r8run.id).targetWayPointIds, 0)
local r8rec = ADRuns.toRecords(r8)
check("R8 records: targets-streng", r8rec[1].targets, "99 120")
check("R8 records: target = første (gammelt felt)", r8rec[1].target, 99)
check("R8 tilbage fra records", table.concat(ADRuns.fromRecords(r8rec).runs[1].targetWayPointIds, ","), "99,120")
check("R8 gammel fil med kun target", table.concat(ADRuns.fromRecords({{id = 1, name = "Gl", target = 55}}).runs[1].targetWayPointIds, ","), "55")
-- ==== XML-laget mod en flad XMLFile-mock (nøgle -> værdi) ====
dofile("FS25_ADSmartPickup/adRunsStorage.lua")
+31 -1
View File
@@ -64,7 +64,20 @@ ADSmartPickup = {
getLoadStationAtWayPointId = function(_, id) return loadAt[id] end,
getStationLevelAndCapacity = function(station, fillType)
if station.accepts[fillType] == nil then return nil end
return 0, station.accepts[fillType]
return (station.levels or {})[fillType] or 0, station.accepts[fillType]
end,
-- forenklet rangering: mest fri plads (relativt) først; fulde sidst
getTargetNeedsRanked = function(station, fillTypes)
local ranked = {}
for _, fillType in ipairs(fillTypes) do
local capacity = station.accepts[fillType]
if capacity ~= nil then
local level = (station.levels or {})[fillType] or 0
table.insert(ranked, {fillType = fillType, level = level, capacity = capacity, freeSpace = capacity - level, score = (capacity - level) / capacity})
end
end
table.sort(ranked, function(a, b) return a.score > b.score end)
return ranked
end,
}
ADSupplyPlanner = {isWaitMarker = function(marker) return string.find(string.lower(marker.group or ""), "%f[%a]wait%f[%A]") ~= nil end}
@@ -345,5 +358,22 @@ actVehicle.waitInfo = {markerName = "Cow Wait", fillType = STRAW, rest = 5000}
check("C15 venter", ADRunsController.getVehicleActivity(adEnv, actVehicle).kind, "waiting")
ADUnloadWait = nil
-- C16: flere mål pr. run — Auto-varer = union; chooseTarget = den stald der mangler mest; validering
buildWorld()
addMarker(99, "Cow 2 Food", "Cow Food", 5200, 0); unloadAt[99] = {accepts = {[STRAW] = 300000, [TMR] = 300000}, levels = {[STRAW] = 0, [TMR] = 0}}
unloadAt[94].levels = {[STRAW] = 250000, [TMR] = 250000, [WATER] = 50000}
local multiVehicle = makeVehicle("vehicleMulti", "Multi", {STRAW, TMR, WATER}, 1000000, 100, 0)
local multi = ADRunsController.createRun("Kvæg")
ADRunsController.updateRun(multi.id, {targetWayPointIds = {94, 99}})
local multiRun = ADRuns.getRun(ADRunsController.store, multi.id)
check("C16 auto-varer = union (vand kun i stald 1)", table.concat(ADRunsController.getRunIngredients(adEnv, multiRun, multiVehicle), ","), WATER .. "," .. STRAW .. "," .. TMR)
check("C16 accepterede varer = union", #ADRunsController.getTargetAcceptedFillTypes(adEnv, multiRun), 3)
check("C16 vælger stald 2 (tom)", ADRunsController.chooseTarget(adEnv, multiRun, multiVehicle), 99)
unloadAt[99].levels = {[STRAW] = 290000, [TMR] = 290000}
check("C16 vælger stald 1 når stald 2 er fuld", ADRunsController.chooseTarget(adEnv, multiRun, multiVehicle), 94)
check("C16 validering ok med flere mål", ADRunsController.validateVehicle(adEnv, multiRun, multiVehicle).ok, true)
ADRunsController.updateRun(multi.id, {targetWayPointIds = {4242}})
check("C16 kun ukendte mål -> noTarget", ADRunsController.validateVehicle(adEnv, ADRuns.getRun(ADRunsController.store, multi.id), multiVehicle).reason, "noTarget")
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)
+26
View File
@@ -119,6 +119,7 @@ FS25_AutoDrive = {
end,
getWayPointById = function(_, id) return wayPoints[id] end,
getMapMarkers = function() return markers end,
getMapMarkerByWayPointId = function(_, id) for _, m in ipairs(markers) do if m.id == id then return m end end end,
-- ruter: alt nåeligt medmindre testen sætter unreachable[id] (til eller fra)
unreachable = {},
getPathTo = function(self, vehicle, id) if self.unreachable[id] then return {} end; return {{id = id}} end,
@@ -897,6 +898,31 @@ UnloadTask.update(tt, 16)
check("I5 hjem når målet er under 20 %", tt.destinationID, 30)
ADRunsController.store = ADRuns.newStore()
-- I6: run med to stalde — ved turstart vælges den stald der mangler mest, AD's mål skiftes, og
-- varen hentes efter DEN stalds behov
buildCowWorld()
addMarker(31, "Cow 2 Food", "Cow Food", 6000, 0)
local cow2Levels = {[STRAW] = 95000, [TMR] = 95000}
table.insert(unloadStations, makeUnloadStation(131, 6000, 10, cow2Levels, {[STRAW] = 100000, [TMR] = 100000}, {name = "kostald 2"}))
cowLevels[STRAW], cowLevels[TMR] = 90000, 20000 -- stald 1: TMR mangler
local i6 = makeSupplyDriver(markerByIndex(21), markerByIndex(31), {TMR, STRAW}) -- AD peger på stald 2 (fuld)
i6.uniqueId = "vehicleI6"; i6.carriable = {TMR, STRAW}; i6.trailers = {level = 0, capacity = 8000}
i6.ad.stateModule.setSecondMarkerByWayPointId = function(self, id) self.secondMarkerId = id end
i6.ad.stateModule.getSecondMarker = function(self) return markerByIndex(self.secondMarkerId or 31) end
testVehicles = {i6}
ADRunsController.store = ADRuns.newStore()
local twoBarns = ADRunsController.createRun("Kvæg")
ADRunsController.updateRun(twoBarns.id, {targetWayPointIds = {30, 31}})
ADRunsController.assignVehicle(twoBarns.id, i6)
check("I6 henter TMR til stald 1", manager:getNextPickup(i6, false), 20)
check("I6 AD's mål skiftet til stald 1", i6.ad.stateModule.secondMarkerId, 30)
check("I6 skiftet logges", countLogsSince(1, "kører til Cow 1 Food") >= 1, true)
cowLevels[STRAW], cowLevels[TMR] = 99000, 99000
cow2Levels[STRAW] = 10000 -- nu mangler stald 2 halm
check("I6 næste tur: halm til stald 2", manager:getNextPickup(i6, false), 21)
check("I6 mål skiftet til stald 2", i6.ad.stateModule.secondMarkerId, 31)
ADRunsController.store = ADRuns.newStore()
-- ==== E: eksponerede opslag (bruges af runs-controller og læs-bytte) ====
local eDriver = buildCowWorld()
check("E1 aflæsningsstation ved waypoint", ADSmartPickup.getUnloadStationAtWayPointId(FS25_AutoDrive, 30, 1), unloadStations[1])