-- Kør: luajit tests/test_adRunsController.lua (fra repo-roden) -- Controlleren oversætter et run til AutoDrive-tilstand pr. traktor. Mock'er AD + de -- få ADSmartPickup-opslag den bruger. local STRAW, TMR, WATER, MILK = 31, 116, 8, 30 local FILL_TYPE_NAMES = {[STRAW] = "STRAW", [TMR] = "FORAGE", [WATER] = "WATER", [MILK] = "MILK"} local FILL_TYPE_INDEX = {} for index, name in pairs(FILL_TYPE_NAMES) do FILL_TYPE_INDEX[name] = index end g_fillTypeManager = { getFillTypeNameByIndex = function(_, index) return FILL_TYPE_NAMES[index] end, getFillTypeIndexByName = function(_, name) return FILL_TYPE_INDEX[name] end, getFillTypes = function() return { {index = STRAW, name = "STRAW", title = "Halm"}, {index = TMR, name = "FORAGE", title = "TMR"}, {index = WATER, name = "WATER", title = "Vand"}, {index = MILK, name = "MILK", title = "Mælk"}, } end, } local logLines = {} Logging = { info = function(fmt, ...) table.insert(logLines, string.format(fmt, ...)) end, warning = function(fmt, ...) table.insert(logLines, "WARN " .. string.format(fmt, ...)) end, } Utils = {prependedFunction = function(original, extra) return function(...) extra(...); return original(...) end end} ItemSystem = {save = function() end} g_currentMission = {getFarmId = function() return 1 end, missionInfo = {}} -- ---- AutoDrive-mock ---- local RT_NONE, RT_ONLYPICKUP = 1, 2 local MODE_PICKUPANDDELIVER = 2 local vehicles, markers, wayPoints = {}, {}, {} FS25_AutoDrive = { AutoDrive = { RT_NONE = RT_NONE, RT_ONLYPICKUP = RT_ONLYPICKUP, MODE_PICKUPANDDELIVER = MODE_PICKUPANDDELIVER, settings = { useFolders = {values = {false, true}, current = 1, isVehicleSpecific = false}, rotateTargets = {values = {1, 2, 3, 4}, current = 1, isVehicleSpecific = true}, }, getAllVehicles = function() return vehicles end, getAllUnits = function(vehicle) return vehicle.trailers end, getAllFillLevels = function(trailers) return trailers.level or 0, trailers.capacity or 0, false, 0 end, getSupportedFillTypesOfAllUnitsAlphabetically = function(vehicle) return vehicle.carriable or {} end, }, ADGraphManager = { getMapMarkers = function() return markers end, getMapMarkerByWayPointId = function(_, id) for _, m in ipairs(markers) do if m.id == id then return m end end end, getWayPointById = function(_, id) return wayPoints[id] end, getDistanceFromNetwork = function(_, vehicle) return vehicle.networkDistance or 0 end, }, } local function addMarker(id, name, group, x, z) wayPoints[id] = {x = x, z = z, incoming = {}} table.insert(markers, {id = id, markerIndex = #markers + 1, name = name, group = group}) end -- ADSmartPickup-opslag: hvilke waypoints har hvilken slags station, og hvad målet tager local unloadAt, loadAt = {}, {} ADSmartPickup = { getFarmId = function(vehicle) return vehicle.farmId end, getUnloadStationAtWayPointId = function(_, id) return unloadAt[id] end, getLoadStationAtWayPointId = function(_, id) return loadAt[id] end, getStationLevelAndCapacity = function(station, fillType) if station.accepts[fillType] == nil then return nil end 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} local function makeVehicle(uniqueId, name, carriable, capacity, x, z) local stateModule = {selectedFillTypes = {}, fillType = 0, active = false, loopCounter = 5, loopsDone = 3, dirtyCount = 0} stateModule.setMode = function(self, mode) self.mode = mode end stateModule.setFirstMarkerByWayPointId = function(self, id) self.firstMarkerId = id end stateModule.setSecondMarkerByWayPointId = function(self, id) self.secondMarkerId = id end stateModule.setFillType = function(self, fillType) self.fillType = fillType end stateModule.raiseDirtyFlag = function(self) self.dirtyCount = self.dirtyCount + 1 end stateModule.setLoopsDone = function(self, n) self.loopsDone = n end stateModule.isActive = function(self) return self.active end -- Bruges af C13: getTargetFillTypes skal følge AD's LIVE mål (mock'er AD's eget getSecondMarker). stateModule.getSecondMarker = function(self) return self.secondMarkerId ~= nil and {id = self.secondMarkerId} or nil end local vehicle = { uniqueId = uniqueId, farmId = 1, rootNode = uniqueId, carriable = carriable, trailers = {level = 0, capacity = capacity}, getName = function() return name end, getOwnerFarmId = function() return 1 end, startAutoDrive = function(self) self.ad.stateModule.active = true; self.started = (self.started or 0) + 1 end, getClosestWayPoint = function() return nil, 0 end, stopAutoDrive = function(self) self.ad.stateModule.active = false; self.stopped = (self.stopped or 0) + 1 end, ad = {stateModule = stateModule, settings = {rotateTargets = {values = {1, 2, 3, 4}, current = 1, new = 1, isVehicleSpecific = true}}}, } nodePositions = nodePositions or {} nodePositions[uniqueId] = {x = x or 0, z = z or 0} table.insert(vehicles, vehicle) return vehicle end function getWorldTranslation(node) local p = nodePositions[node]; return p.x, 0, p.z end dofile("FS25_ADSmartPickup/adRuns.lua") dofile("FS25_ADSmartPickup/adRunsStorage.lua") dofile("FS25_ADSmartPickup/adRunsController.lua") local adEnv = FS25_AutoDrive local failures = 0 local function check(name, actual, expected) if actual == expected then print("OK " .. name) else failures = failures + 1 print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual))) end end local function buildWorld() vehicles, markers, wayPoints, unloadAt, loadAt, logLines = {}, {}, {}, {}, {}, {} ADRunsController.store = ADRuns.newStore() addMarker(94, "Cow 1 Food", "Cow Food", 5000, 0); unloadAt[94] = {accepts = {[STRAW] = 300000, [TMR] = 300000, [WATER] = 50000}} addMarker(44, "10 Silo Storage", "Siloer", 0, 0); loadAt[44] = {} addMarker(75, "TMR Load", "Fabrication", 900, 0); loadAt[75] = {} addMarker(100, "Cow Wait", "Cow Wait", 5100, 0) addMarker(101, "Cow Wait", "Cow Wait", 5200, 0) addMarker(200, "F91 Wait", "F91", 8000, 0) addMarker(300, "Pig Wait", "Pig Wait", 9000, 0) end -- C1: køretøjs-id og farmens AD-køretøjer buildWorld() local fastracA = makeVehicle("vehicleA", "Fastrac A", {STRAW, TMR}, 1000000, 100, 0) local fastracB = makeVehicle("vehicleB", "Fastrac B", {STRAW}, 700000, 4000, 0) local noAd = {uniqueId = "vehicleC", getOwnerFarmId = function() return 1 end} table.insert(vehicles, noAd) local otherFarm = makeVehicle("vehicleD", "Nabo", {STRAW}, 1000, 0, 0); otherFarm.getOwnerFarmId = function() return 2 end check("C1 uniqueId", ADRunsController.getVehicleId(fastracA), "vehicleA") check("C1 fallback savegame-id", ADRunsController.getVehicleId({currentSavegameId = 7}), "7") check("C1 intet id -> nil", ADRunsController.getVehicleId({}), nil) check("C1 farmens AD-køretøjer", #ADRunsController.getFarmVehicles(adEnv), 2) check("C1 opslag på id", ADRunsController.findVehicleById(adEnv, "vehicleB"), fastracB) check("C1 ukendt id -> nil", ADRunsController.findVehicleById(adEnv, "nope"), nil) -- C2: opret run, tildel; opslag run for køretøj; flyt mellem runs local cow = ADRunsController.createRun("Cow Feed") check("C2 run oprettet", ADRuns.getRun(ADRunsController.store, cow.id).name, "Cow Feed") check("C2 ingen tidligere", ADRunsController.assignVehicle(cow.id, fastracA), nil) check("C2 run for køretøj", ADRunsController.getRunForVehicle(fastracA).id, cow.id) check("C2 ikke tildelt -> nil", ADRunsController.getRunForVehicle(fastracB), nil) local pig = ADRunsController.createRun("Pig Feed") check("C2 flyttet fra Cow", ADRunsController.assignVehicle(pig.id, fastracA), cow.id) check("C2 nu i Pig", ADRunsController.getRunForVehicle(fastracA).id, pig.id) ADRunsController.unassignVehicle(fastracA) check("C2 fjernet", ADRunsController.getRunForVehicle(fastracA), nil) ADRunsController.deleteRun(pig.id) check("C2 slettet", ADRuns.getRun(ADRunsController.store, pig.id), nil) -- C3: Auto-vareliste = vognens varer ∩ målets varer; manual = navne -> indeks (ukendte droppes) ADRunsController.updateRun(cow.id, {targetWayPointId = 94}) local cowRun = ADRuns.getRun(ADRunsController.store, cow.id) check("C3 auto: halm+TMR (vand kan vognen ikke bære)", table.concat(ADRunsController.getRunIngredients(adEnv, cowRun, fastracA), ","), STRAW .. "," .. TMR) check("C3 auto: kun halm for halm-vogn", table.concat(ADRunsController.getRunIngredients(adEnv, cowRun, fastracB), ","), tostring(STRAW)) ADRunsController.updateRun(cow.id, {ingredientMode = "manual", ingredients = {"FORAGE", "UNKNOWN_THING"}}) cowRun = ADRuns.getRun(ADRunsController.store, cow.id) check("C3 manual: FORAGE -> indeks, ukendt droppes", table.concat(ADRunsController.getRunIngredients(adEnv, cowRun, fastracA), ","), tostring(TMR)) ADRunsController.updateRun(cow.id, {ingredientMode = "auto"}) local noTarget = ADRunsController.createRun("Uden mål") check("C3 uden mål -> tom liste", #ADRunsController.getRunIngredients(adEnv, ADRuns.getRun(ADRunsController.store, noTarget.id), fastracA), 0) -- C4: validering cowRun = ADRuns.getRun(ADRunsController.store, cow.id) check("C4 ok", ADRunsController.validateVehicle(adEnv, cowRun, fastracA).ok, true) check("C4 kapacitet", ADRunsController.validateVehicle(adEnv, cowRun, fastracA).capacity, 1000000) local noTrailer = makeVehicle("vehicleE", "Uden vogn", {}, 0) check("C4 ingen vogn", ADRunsController.validateVehicle(adEnv, cowRun, noTrailer).reason, "noTrailer") local milkTruck = makeVehicle("vehicleF", "Mælkebil", {MILK}, 20000) check("C4 kan ikke bære", ADRunsController.validateVehicle(adEnv, cowRun, milkTruck).reason, "cannotCarry") fastracB.networkDistance = 31 check("C4 for langt fra vejnettet", ADRunsController.validateVehicle(adEnv, cowRun, fastracB).reason, "farFromNetwork") fastracB.networkDistance = 0 check("C4 intet mål", ADRunsController.validateVehicle(adEnv, ADRuns.getRun(ADRunsController.store, noTarget.id), fastracA).reason, "noTarget") ADRunsController.updateRun(noTarget.id, {targetWayPointId = 4242}) check("C4 mål-markør findes ikke", ADRunsController.validateVehicle(adEnv, ADRuns.getRun(ADRunsController.store, noTarget.id), fastracA).reason, "noTarget") -- C5: Start skriver AD-tilstand og starter; ✖-traktorer springes over ADRunsController.updateRun(cow.id, {loops = 4, waitPoolGroup = "Cow Wait"}) ADRunsController.assignVehicle(cow.id, fastracA) ADRunsController.assignVehicle(cow.id, noTrailer) local results = ADRunsController.startRun(adEnv, cow.id) check("C5 to resultater", #results, 2) check("C5 A startet", fastracA.started, 1) check("C5 A ok", results[1].ok, true) check("C5 uden vogn sprunget over", noTrailer.started, nil) check("C5 uden vogn grund", results[2].reason, "noTrailer") local state = fastracA.ad.stateModule check("C5 mode P&D", state.mode, MODE_PICKUPANDDELIVER) check("C5 mål = run'ets mål", state.secondMarkerId, 94) check("C5 start-pickup = nærmeste læssestation", state.firstMarkerId, 44) check("C5 varer = auto-listen", table.concat(state.selectedFillTypes, ","), STRAW .. "," .. TMR) check("C5 fillType = første", state.fillType, STRAW) check("C5 loops", state.loopCounter, 4) check("C5 loopsDone nulstillet", state.loopsDone, 0) check("C5 rotateTargets = kun pålæsning (current)", fastracA.ad.settings.rotateTargets.current, 2) check("C5 rotateTargets = kun pålæsning (new)", fastracA.ad.settings.rotateTargets.new, 2) check("C5 useFolders globalt til", adEnv.AutoDrive.settings.useFolders.current, 2) check("C5 dirty flag", state.dirtyCount > 0, true) check("C5 status", ADRunsController.getRunStatus(adEnv, ADRuns.getRun(ADRunsController.store, cow.id)).running, 1) check("C5 total", ADRunsController.getRunStatus(adEnv, ADRuns.getRun(ADRunsController.store, cow.id)).total, 2) check("C5 ukendt run -> tom", #ADRunsController.startRun(adEnv, 999), 0) -- C6: Stop check("C6 stoppede", ADRunsController.stopRun(adEnv, cow.id), 1) check("C6 A stoppet", fastracA.stopped, 1) check("C6 status 0", ADRunsController.getRunStatus(adEnv, ADRuns.getRun(ADRunsController.store, cow.id)).running, 0) check("C6 medlemskab bevaret", ADRunsController.getRunForVehicle(fastracA).id, cow.id) -- C7: Start på traktor der allerede kører -> ikke startet igen, men tilstand skrives fastracA.ad.stateModule.active = true ADRunsController.startRun(adEnv, cow.id) check("C7 ikke dobbelt-startet", fastracA.started, 1) -- C8: mål-markører (kun stalde og fabrikker — siloer tager alt og er ikke mål; stalde først, -- så fabrikker, så navn) og Wait-puljer til dropdowns unloadAt[94].owningPlaceable = {getHusbandryFillLevel = function() return 0 end} addMarker(96, "8 Silo Storage", "Siloer", 100, 0); unloadAt[96] = {accepts = {[STRAW] = 1}, owningPlaceable = {spec_silo = {}}} addMarker(97, "TMR Unload", "Fabrication", 900, 0); unloadAt[97] = {accepts = {[STRAW] = 1}, owningPlaceable = {spec_productionPoint = {}}} addMarker(98, "Bull Food", "Cow Food", 5100, 0); unloadAt[98] = {accepts = {[STRAW] = 1}, owningPlaceable = {getHusbandryFillLevel = function() return 0 end}} local targets = ADRunsController.getTargetMarkers(adEnv, 1) check("C8 kun stalde og fabrikker (ikke siloen)", #targets, 3) check("C8 stalde først, alfabetisk", targets[1].name .. "," .. targets[2].name, "Bull Food,Cow 1 Food") check("C8 fabrik sidst", targets[3].name, "TMR Unload") local pools = ADRunsController.getWaitPools(adEnv) check("C8 to puljer (F91 er ikke en Wait-mappe)", #pools, 2) check("C8 sorteret", pools[1].group, "Cow Wait") check("C8 antal", pools[1].count, 2) -- C9: gem/indlæs; ukendte køretøjs-id'er logges ved indlæsning men beholdes i run'et local savedRecords ADRunsStorage.save = function(store) savedRecords = ADRuns.toRecords(store); return true end ADRunsStorage.load = function() return ADRuns.fromRecords(savedRecords) end ADRunsController.assignVehicle(cow.id, {uniqueId = "vehicleGONE", ad = {}, getOwnerFarmId = function() return 1 end, getName = function() return "Væk" end}) check("C9 gemt", ADRunsController.save(), true) ADRunsController.store = ADRuns.newStore() ADRunsController.load(adEnv) check("C9 indlæst", ADRuns.getRun(ADRunsController.store, cow.id).name, "Cow Feed") check("C9 ukendt køretøj logget", logLines[#logLines]:find("vehicleGONE", 1, true) ~= nil, true) check("C9 run beholder kendte", ADRunsController.getRunForVehicle(fastracA).id, cow.id) local hooked = false ItemSystem.save = function() hooked = true end ADRunsController.installSaveHook() ItemSystem.save() check("C9 save-hook kaldes før ItemSystem.save", hooked, true) -- C11: vogn uden egen ad.settings-tabel (ingen rotateTargets pr. køretøj) -> den -- køretøjs-specifikke indstilling skrives IKKE til den globale settings-tabel adEnv.AutoDrive.settings.rotateTargets.current = 1 adEnv.AutoDrive.settings.useFolders.current = 1 local settingsRun = ADRunsController.createRun("Settings Test") ADRunsController.updateRun(settingsRun.id, {targetWayPointId = 94, loops = 1}) local noSettings = makeVehicle("vehicleH", "Uden AD-settings", {STRAW}, 500000, 200, 0) noSettings.ad.settings = {} ADRunsController.assignVehicle(settingsRun.id, noSettings) ADRunsController.startRun(adEnv, settingsRun.id) check("C11 global rotateTargets urørt", adEnv.AutoDrive.settings.rotateTargets.current, 1) check("C11 useFolders global stadig skrevet", adEnv.AutoDrive.settings.useFolders.current, 2) check("C11 køretøjet startet", noSettings.started, 1) -- C12: startAutoDrive() kaster for én traktor -> pcall'et applyAndStart fanger fejlen, -- resultatet markeres ok=false/reason="error", og de ØVRIGE traktorer i run'et startes stadig -- (fejlen må ikke undslippe startRun-loopet). buildWorld() local brokenRun = ADRunsController.createRun("Broken Start") ADRunsController.updateRun(brokenRun.id, {targetWayPointId = 94, loops = 2}) local broken = makeVehicle("vehicleBroken", "Fejl-traktor", {STRAW, TMR}, 500000, 100, 0) broken.startAutoDrive = function() error("boom") end local normal = makeVehicle("vehicleNormal", "Normal-traktor", {STRAW, TMR}, 500000, 200, 0) ADRunsController.assignVehicle(brokenRun.id, broken) ADRunsController.assignVehicle(brokenRun.id, normal) local c12Results = ADRunsController.startRun(adEnv, brokenRun.id) check("C12 to resultater", #c12Results, 2) check("C12 fejl-traktor ok=false", c12Results[1].ok, false) check("C12 fejl-traktor reason=error", c12Results[1].reason, "error") check("C12 fejl-traktor ikke startet", broken.started, nil) check("C12 normal-traktor ok=true", c12Results[2].ok, true) check("C12 normal-traktor startet", normal.started, 1) -- C13: Auto-listen følger traktorens LIVE AD-mål (stateModule:getSecondMarker()) mens den kører, -- IKKE run'ets gemte targetWayPointId — ellers afviger listen fra det choosePickup/findSupplyPickup -- faktisk bruger, hvis brugeren redigerer run'ets Mål mens traktoren kører. addMarker(95, "Alt Cow Food", "Cow Food", 5300, 0) unloadAt[95] = {accepts = {[STRAW] = 1000}} local liveRun = ADRunsController.createRun("Live Target") ADRunsController.updateRun(liveRun.id, {targetWayPointId = 94}) local liveRunData = ADRuns.getRun(ADRunsController.store, liveRun.id) local liveVehicle = makeVehicle("vehicleLive", "Live-traktor", {STRAW, TMR}, 500000, 300, 0) check("C13 inaktiv: auto-liste fra run'ets mål (94)", table.concat(ADRunsController.getRunIngredients(adEnv, liveRunData, liveVehicle), ","), STRAW .. "," .. TMR) liveVehicle.ad.stateModule.active = true liveVehicle.ad.stateModule.secondMarkerId = 95 check("C13 aktiv: auto-liste fra AD's live mål (95)", table.concat(ADRunsController.getRunIngredients(adEnv, liveRunData, liveVehicle), ","), tostring(STRAW)) liveVehicle.ad.stateModule.active = false liveVehicle.ad.stateModule.secondMarkerId = nil -- C10: målets accepterede varer (til afkrydsning i GUI'et) + køretøjs-label buildWorld() local labelA = makeVehicle("vehicleA", "Fastrac A", {STRAW, TMR}, 1000000) local labelB = makeVehicle("vehicleB", "Fastrac B", {STRAW}, 700000) local accRun = ADRunsController.createRun("Cow Feed") check("C10 uden mål -> tom", #ADRunsController.getTargetAcceptedFillTypes(adEnv, ADRuns.getRun(ADRunsController.store, accRun.id)), 0) ADRunsController.updateRun(accRun.id, {targetWayPointId = 94}) local accepted = ADRunsController.getTargetAcceptedFillTypes(adEnv, ADRuns.getRun(ADRunsController.store, accRun.id)) check("C10 tre varer (halm, TMR, vand)", #accepted, 3) check("C10 sorteret på titel", accepted[1].title .. "," .. accepted[2].title .. "," .. accepted[3].title, "Halm,TMR,Vand") check("C10 navn med", accepted[1].name, "STRAW") check("C10 label", ADRunsController.getVehicleLabel(adEnv, labelB), "Fastrac B (#2)") -- C14: Start går gennem AD's mode:start(USER_PLAYER) (som HUD'en), ikke kun startAutoDrive buildWorld() local modeVehicle = makeVehicle("vehicleM", "Mode-traktor", {STRAW, TMR}, 1000000, 100, 0) local modeStarts = {} modeVehicle.ad.stateModule.getCurrentMode = function() return {start = function(_, user) table.insert(modeStarts, user); modeVehicle:startAutoDrive() end} end modeVehicle.ad.stateModule.setActualFarmId = function(self, farmId) self.actualFarmId = farmId end adEnv.AutoDrive.USER_PLAYER = 1 local modeRun = ADRunsController.createRun("Mode") ADRunsController.updateRun(modeRun.id, {targetWayPointId = 94}) ADRunsController.assignVehicle(modeRun.id, modeVehicle) ADRunsController.startRun(adEnv, modeRun.id) check("C14 mode:start kaldt med USER_PLAYER", modeStarts[1], 1) check("C14 traktor aktiv", modeVehicle.started, 1) check("C14 farm-id sat", modeVehicle.ad.stateModule.actualFarmId, 1) check("C14 loopsDone nulstillet", modeVehicle.ad.stateModule.loopsDone, 0) -- C15: aktivitet til overblikket — stoppet / venter / med læs / tom på vej efter vare ADUnloadWait = {getWaitFor = function(v) return v.waitInfo end, getRestLoad = function(_, v) return v.loadType, v.loadLiters or 0 end} ADSmartPickup.getActivePickup = function(v) return v.pickupInfo end buildWorld() local actVehicle = makeVehicle("vehicleAct", "Akt", {STRAW, TMR}, 1000000, 100, 0) check("C15 stoppet", ADRunsController.getVehicleActivity(adEnv, actVehicle).kind, "stopped") actVehicle.ad.stateModule.active = true actVehicle.ad.stateModule.secondMarkerId = 94 actVehicle.loadType, actVehicle.loadLiters = STRAW, 8000 local loaded = ADRunsController.getVehicleActivity(adEnv, actVehicle) check("C15 med læs", loaded.kind .. "/" .. loaded.fillType .. "/" .. loaded.liters, "loaded/" .. STRAW .. "/8000") actVehicle.loadLiters = 0 actVehicle.pickupInfo = {markerName = "Silo 3", fillType = TMR} local empty = ADRunsController.getVehicleActivity(adEnv, actVehicle) check("C15 tom på vej efter TMR", empty.kind .. "/" .. tostring(empty.place) .. "/" .. tostring(empty.fillType), "empty/Silo 3/" .. TMR) 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)