From 473f6110bf5770d483ea1f24beefc1fa2bba841a Mon Sep 17 00:00:00 2001 From: masterdraco Date: Mon, 28 Sep 2026 18:54:44 +0200 Subject: [PATCH] =?UTF-8?q?feat(pulje):=20etape=202=20=E2=80=94=20t=C3=B8m?= =?UTF-8?q?mevogne=20ved=20h=C3=B8st=20fra=20puljen:=20ledig=20traktor=20h?= =?UTF-8?q?enter=20en=20puljevogn=20der=20kan=20b=C3=A6re=20afgr=C3=B8den,?= =?UTF-8?q?=20f=C3=B8lger=20h=C3=B8steren=20til=20h=C3=B8sten=20er=20f?= =?UTF-8?q?=C3=A6rdig,=20s=C3=A6tter=20vognen=20af=20og=20k=C3=B8rer=20hje?= =?UTF-8?q?m=20(v1.49.0.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adFieldWork.lua | 11 ++++++++--- FS25_ADSmartPickup/adPool.lua | 25 ++++++++++++++++++++++--- FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adPool.lua | 7 ++++++- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/FS25_ADSmartPickup/adFieldWork.lua b/FS25_ADSmartPickup/adFieldWork.lua index b77c789..1a934f2 100644 --- a/FS25_ADSmartPickup/adFieldWork.lua +++ b/FS25_ADSmartPickup/adFieldWork.lua @@ -391,7 +391,7 @@ end -- Puljekombination: nærmeste puljeredskab til marken + nærmeste ledige traktor med nok hk. Traktoren kører til -- "Connect X", kobler på og fortsætter så som en almindelig udsendelse (fase fetching -> driving). -function ADFieldWork.dispatchPool(adEnv, field, info, role, roleAccept) +function ADFieldWork.dispatchPool(adEnv, field, info, role, roleAccept, decision) local implements, tractors = ADPool.collect(adEnv, function(vehicle) return isBusyVehicle(vehicle, ADRunsController.getVehicleId(vehicle)) end) @@ -404,6 +404,8 @@ function ADFieldWork.dispatchPool(adEnv, field, info, role, roleAccept) end if role == "weeder" then candidate.mechanical = ADCpBridge.isMechanicalWeeder(implement.vehicle) end if roleAccept ~= nil and not roleAccept(candidate) then return false end + -- tømmevogn: skal kunne bære høstens vare + if role == "unloader" and not ADPool.canCarry(implement, info.harvestFillType) then return false end local required = ADFieldModel.requiredWidth(field, role) return (implement.width or 0) <= 0 or ADFieldModel.checkWidth(role, implement.width, required) end @@ -412,7 +414,8 @@ function ADFieldWork.dispatchPool(adEnv, field, info, role, roleAccept) local tractor, implement = pair.tractor, pair.implement local assignment = { vehicleId = tractor.id, vehicle = tractor.vehicle, fieldId = field.id, role = role, stage = field.stage, - helper = false, phase = "fetching", since = now(), width = implement.width, groupSize = 1, leader = true, + helper = decision ~= nil and decision.helper == true, phase = "fetching", since = now(), width = implement.width, + groupSize = 1, leader = true, fillType = decision ~= nil and decision.helper and info.harvestFillType or nil, startX = tractor.x, startZ = tractor.z, pool = {implementId = implement.id, implementName = implement.name, connectId = implement.connectId}, hitch = {done = false}, @@ -444,6 +447,8 @@ function ADFieldWork.dispatch(adEnv, field, info, decision) local offNetwork = {} local accept = function(candidate) if roleAccept ~= nil and not roleAccept(candidate) then return false end + -- tømmevogn: skal kunne bære høstens vare + if role == "unloader" and not ADPool.canCarry(implement, info.harvestFillType) then return false end -- manuel transport: spilleren kører den — afstand til AutoDrive-vejnettet er ligegyldig if role == "harvester" and candidate.manual then return true end local d = candidate.x ~= nil and ADFieldWork.distanceToNetwork(adEnv, candidate.x, candidate.z) or nil @@ -471,7 +476,7 @@ function ADFieldWork.dispatch(adEnv, field, info, decision) end if ADPool ~= nil and ADPool.mayUsePool(decision, hasOwnForRole) and (why == "noRig" or why == "allBusy" or why == "cannotDo") then - local pooled, poolWhy, poolArgs = ADFieldWork.dispatchPool(adEnv, field, info, role, roleAccept) + local pooled, poolWhy, poolArgs = ADFieldWork.dispatchPool(adEnv, field, info, role, roleAccept, decision) if pooled then return end if poolWhy == "tooWeak" then note(field.id, {reason = {text = string.format("ingen ledig traktor med ≥%.0f hk til '%s'", diff --git a/FS25_ADSmartPickup/adPool.lua b/FS25_ADSmartPickup/adPool.lua index b470348..1499c18 100644 --- a/FS25_ADSmartPickup/adPool.lua +++ b/FS25_ADSmartPickup/adPool.lua @@ -90,9 +90,16 @@ function ADPool.nextDrive(refill) return "empty" end --- Puljen bruges kun til hovedopgaver med ét sæt, og ikke når marken har egne faste maskiner til rollen. +-- Puljen bruges til opgaver med ét sæt (også tømmevogne ved høst), ikke når marken har egne faste maskiner +-- til rollen. function ADPool.mayUsePool(decision, hasOwnForRole) - return not decision.helper and (decision.count or 1) == 1 and not hasOwnForRole + return (decision.count or 1) == 1 and not hasOwnForRole +end + +-- Kan puljevognen bære varen? (implement.carries = {[fillType] = true}; nil vare = intet krav) +function ADPool.canCarry(implement, fillType) + if fillType == nil then return true end + return implement.carries ~= nil and implement.carries[fillType] == true end -- Status til flådefanen. s = {parkName, hasConnect, attachedTo, quarantineMin, reserved} -> nøgle, argument @@ -261,6 +268,17 @@ local function tractorHpOf(vehicle) return item ~= nil and item.specs ~= nil and ADPool.numberOf(item.specs.power) or nil end +-- Varer og samlet kapacitet i redskabets fyldenheder (tømmevogne). +function ADPool.cargoOf(vehicle) + local carries, capacity = {}, 0 + local units = vehicle.spec_fillUnit ~= nil and vehicle.spec_fillUnit.fillUnits or {} + for index in ipairs(units) do + capacity = capacity + (vehicle:getFillUnitCapacity(index) or 0) + for fillType in pairs(vehicle:getFillUnitSupportedFillTypes(index) or {}) do carries[fillType] = true end + end + return carries, capacity +end + local function isAttached(vehicle) return vehicle.getAttacherVehicle ~= nil and vehicle:getAttacherVehicle() ~= nil end @@ -290,7 +308,8 @@ function ADPool.collect(adEnv, isBusy) local role = specs ~= nil and ADPool.roleOf(specs) or nil if role ~= nil then local x, z = positionOf(vehicle) - table.insert(implements, { + local carries, capacity = ADPool.cargoOf(vehicle) + table.insert(implements, {carries = carries, capacity = capacity, id = ADRunsController.getVehicleId(vehicle), vehicle = vehicle, name = ADRuns.vehicleLabel(vehicle), role = role, roles = specs.sprayRoles or ADFieldFleet.rolesFor(role), x = x, z = z, width = ADCpBridge.getWorkWidth(vehicle), neededHp = neededHpOf(vehicle), connectId = connect.id, parkId = park.id, diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index 23c4890..f53761c 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.48.4.0 + 1.49.0.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adPool.lua b/tests/test_adPool.lua index 08276d8..e37b1c1 100644 --- a/tests/test_adPool.lua +++ b/tests/test_adPool.lua @@ -99,7 +99,7 @@ check("I3: tom med påfyldning", P.nextDrive({empty = true, refillId = 7}), "loa check("I3: tom uden påfyldning", P.nextDrive({empty = true}), "empty") -- I4: puljen kun til hovedopgaver med ét sæt, og ikke når marken har egne faste maskiner til rollen check("I4: almindelig", P.mayUsePool({count = 1}, false), true) -check("I4: tømmevogn", P.mayUsePool({count = 1, helper = true}, false), false) +check("etape 2: tømmevogn må bruge puljen", P.mayUsePool({count = 1, helper = true}, false), true) check("I4: multi-tool", P.mayUsePool({count = 2}, false), false) check("I4: marken har faste", P.mayUsePool({count = 1}, true), false) -- status til flådefanen @@ -136,5 +136,10 @@ check("M3: på grænsen -> næste", P.alignedRetry(60000, 30000), 90000) check("M3: to marker samme takt", P.alignedRetry(62000, 30000) == P.alignedRetry(89000, 30000), true) -- M4: for svag nævner redskabets navn check("M4: navn i args", weakArgs[2], "Plov nær") +-- etape 2: puljevogn skal kunne bære høstens vare +check("bære: vare understøttet", P.canCarry({carries = {[3] = true}}, 3), true) +check("bære: vare ikke understøttet", P.canCarry({carries = {[3] = true}}, 7), false) +check("bære: ingen vare krævet", P.canCarry({carries = {}}, nil), true) +check("bære: ukendt last", P.canCarry({}, 3), false) print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)