-- Kør: luajit tests/test_adWaitPool.lua (fra repo-roden) -- Wait-puljen: kandidater pr. mappe, reservationer, nærmeste ledige, rutetjek, redirect. dofile("FS25_ADSmartPickup/adSupplyPlanner.lua") dofile("FS25_ADSmartPickup/adWaitPool.lua") 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 markers, wayPoints = {}, {} local function addMarker(id, name, group, x, z) wayPoints[id] = {id = id, x = x, z = z, incoming = {}} local marker = {id = id, markerIndex = #markers + 1, name = name, group = group} table.insert(markers, marker) return marker end local unreachable = {} local adEnv = { 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, getPathTo = function(_, vehicle, id) if unreachable[id] then return {} end return {{id = id}} end, pathFromTo = function(_, from, to) if unreachable[to] then return {} end return {{id = to}} end, }, } getWorldTranslation = function(node) return node.x, 0, node.z end addMarker(10, "cow wait 1", "cow wait", 0, 0) addMarker(11, "cow wait 2", "cow wait", 50, 0) addMarker(20, "Wait 3", "General Wait", 10, 0) addMarker(30, "silo 1", "silo", 5, 0) -- W1: kandidater check("W1 kun mappen", #ADWaitPool.getCandidates(adEnv, "cow wait"), 2) check("W1 tom pulje = alle Wait-mapper", #ADWaitPool.getCandidates(adEnv, ""), 3) check("W1 nil = alle", #ADWaitPool.getCandidates(adEnv, nil), 3) -- W2: nærmeste ledige fra vognens position; reserverede springes over; egen reservation OK local v1, v2 = {name = "v1", rootNode = {x = 45, z = 0}}, {name = "v2", rootNode = {x = 45, z = 0}} check("W2 nærmeste", ADWaitPool.pickFree(adEnv, v1, "cow wait").marker.id, 11) ADWaitPool.claim(11, v1) check("W2 reserveret springes over", ADWaitPool.pickFree(adEnv, v2, "cow wait").marker.id, 10) check("W2 egen reservation genbruges", ADWaitPool.pickFree(adEnv, v1, "cow wait").marker.id, 11) -- W3: claim / owner / release check("W3 ejer", ADWaitPool.getOwner(11), v1) ADWaitPool.releaseVehicle(v1) check("W3 frigivet", ADWaitPool.getOwner(11), nil) check("W3 nu ledig for v2", ADWaitPool.pickFree(adEnv, v2, "cow wait").marker.id, 11) -- W4: nåelighed unreachable[11] = true check("W4 uopnåelig nærmeste -> næste", ADWaitPool.pickFree(adEnv, v2, "cow wait", function(c) return ADWaitPool.hasRouteTo(adEnv, v2, c.marker.id) end).marker.id, 10) check("W4 hasRouteTo false", ADWaitPool.hasRouteTo(adEnv, v2, 11), false) check("W4 hasRouteBothWays true", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 30), true) check("W4 hasRouteBothWays hjem uopnåelig", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 11), false) unreachable[11] = nil check("W4 intet punkt -> nil", ADWaitPool.pickFree(adEnv, v2, "cow wait", function() return false end), nil) -- W5: getClaims sorteret på mappe, dernæst id ADWaitPool.claim(20, v2) ADWaitPool.claim(10, v1) local claims = ADWaitPool.getClaims(adEnv) check("W5 to reservationer", #claims, 2) check("W5 første = General Wait", claims[1].marker.group, "General Wait") check("W5 anden = cow wait 1", claims[2].marker.id, 10) ADWaitPool.releaseVehicle(v1) ADWaitPool.releaseVehicle(v2) check("W5 alt frigivet", #ADWaitPool.getClaims(adEnv), 0) -- W6: redirect stopper trigger-aktivitet og sætter sti local stopped = {} local task = { destinationID = 99, state = 1, vehicle = {ad = { trailerModule = {isActiveAtTrigger = function() return true end, stopUnloading = function() stopped.unload = true end, stopLoading = function() stopped.load = true end}, drivePathModule = {setPathTo = function(_, id) stopped.pathTo = id end}, }}, } ADWaitPool.STATE_DRIVING = 2 ADWaitPool.redirect(task, 10) check("W6 destination", task.destinationID, 10) check("W6 state driving", task.state, 2) check("W6 setPathTo", stopped.pathTo, 10) check("W6 stopUnloading", stopped.unload, true) -- WR: AD's rutesøgning siger nej, men vejnettet har en vej fra traktorens nærmeste waypoint -> godtages -- (in-game 24/9: 'Æg storage' ved Chicken Wait 1, "ingen vej til 'Chicken Storage Unload'" trods vej) do wayPoints[901] = {id = 901, x = 0, z = 0, out = {902}} wayPoints[902] = {id = 902, x = 5, z = 0, out = {903}} wayPoints[903] = {id = 903, x = 10, z = 0, out = {}} wayPoints[904] = {id = 904, x = 20, z = 0, out = {}} -- ingen indgang unreachable[903], unreachable[904] = true, true local vehicle = {getClosestWayPoint = function() return 901, 1 end} check("WR AD nej, vejnettet ja -> nåelig", ADWaitPool.hasRouteTo(adEnv, vehicle, 903), true) check("WR hverken AD eller vejnet -> ikke nåelig", ADWaitPool.hasRouteTo(adEnv, vehicle, 904), false) check("WR uden nærmeste waypoint -> AD's svar", ADWaitPool.hasRouteTo(adEnv, {}, 903), false) unreachable[903], unreachable[904] = nil, nil end -- RC: rutesvar gemmes 30 s pr. mål og 10 m-område (holdende vogne spurgte hvert 5. s -> hak hvert 5. s) do local pathCalls = 0 local realGetPathTo = adEnv.ADGraphManager.getPathTo adEnv.ADGraphManager.getPathTo = function(self, vehicle, id) pathCalls = pathCalls + 1; return realGetPathTo(self, vehicle, id) end local clock = 0 netGetTime = function() return clock end local positions = {[500] = {100, 100}} getWorldTranslation = function(node) local p = positions[node]; return p[1], 0, p[2] end local parked = {rootNode = 500, getClosestWayPoint = function() return 901, 1 end} ADWaitPool.hasRouteTo(adEnv, parked, 10) ADWaitPool.hasRouteTo(adEnv, parked, 10) check("RC samme svar genbruges", pathCalls, 1) positions[500] = {104, 103} ADWaitPool.hasRouteTo(adEnv, parked, 10) check("RC samme 10 m-område genbruges", pathCalls, 1) positions[500] = {160, 100} ADWaitPool.hasRouteTo(adEnv, parked, 10) check("RC nyt sted -> nyt svar", pathCalls, 2) clock = 31000 ADWaitPool.hasRouteTo(adEnv, parked, 10) check("RC efter 30 s -> nyt svar", pathCalls, 3) local first = ADWaitPool.hasRouteTo(adEnv, parked, 11) check("RC andet mål -> nyt svar", pathCalls, 4) check("RC samme svar igen", ADWaitPool.hasRouteTo(adEnv, parked, 11), first) check("RC uden nyt kald", pathCalls, 4) adEnv.ADGraphManager.getPathTo = realGetPathTo netGetTime = nil end -- MR: rute markør->markør gemmes (uafhængig af hvor vognen er) — hak 26/9: 30-39 ms pr. rutetjek do local calls = 0 local realFromTo = adEnv.ADGraphManager.pathFromTo adEnv.ADGraphManager.pathFromTo = function(self, from, to) calls = calls + 1; return realFromTo(self, from, to) end local savedClock = netGetTime local t = 1000 netGetTime = function() return t end ADWaitPool.resetMarkerRoutes() local far = {name = "far", rootNode = {x = 5000, z = 5000}} check("MR første: rute", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 30), true) local afterFirst = calls t = t + 60000 check("MR anden fra en helt anden position: samme svar", ADWaitPool.hasRouteBothWays(adEnv, far, 10, 30), true) check("MR anden gang ingen ny ruteberegning", calls, afterFirst) adEnv.ADGraphManager.pathFromTo = realFromTo netGetTime = savedClock end -- ankerpunkt for "All": midt mellem flowets kilder (in-game 29/9: Milk Store ventede ved sukkerroeknuseren) local ax, az = ADWaitPool.anchorOf({{x = 0, z = 0}, {x = 100, z = 50}}) check("anker: midtpunkt x", ax, 50) check("anker: midtpunkt z", az, 25) check("anker: ingen punkter", ADWaitPool.anchorOf({}), nil) check("anker: nil", ADWaitPool.anchorOf(nil), nil) print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)