feat(markarbejde): faste maskiner pr. mark (bruges kun dér; marken venter på sin egen); fix: AD-påfyldning får varen sat (kom tom tilbage); AD der stopper undervejs startes igen 2x, ellers hjem til parkering (v1.30.0.0)

This commit is contained in:
2026-09-26 18:09:12 +02:00
parent 9ef1eb6655
commit 4c60fd555f
10 changed files with 129 additions and 6 deletions
+37
View File
@@ -78,6 +78,43 @@ end
-- Nærmeste brugbare sæt. Grund når intet passer: noRig (ingen med flueben og rollen), cannotDo (ingen kan -- Nærmeste brugbare sæt. Grund når intet passer: noRig (ingen med flueben og rollen), cannotDo (ingen kan
-- tage opgaven, fx afgrøden), allBusy, tooWide/tooNarrow (bredden, med tal fra den første). -- tage opgaven, fx afgrøden), allBusy, tooWide/tooNarrow (bredden, med tal fra den første).
-- accept (valgfri): candidate -> bool, fx "høsteren kan tage hvede". -- accept (valgfri): candidate -> bool, fx "høsteren kan tage hvede".
-- Faste maskiner: rigIdsByField = {[fieldId] = {id, ...}}. En maskine der er fast på en ANDEN mark må
-- ikke bruges her. Har marken selv faste maskiner med rollen, bruges kun de (marken venter på sin egen);
-- ellers de frie. (in-game 26/9: sprøjten "til F22" blev sendt til F109.)
function ADFieldFleet.filterDedicated(candidates, fieldId, role, rigIdsByField)
local ownerOf, own = {}, {}
for otherId, ids in pairs(rigIdsByField or {}) do
for _, id in ipairs(ids or {}) do
ownerOf[id] = otherId
if otherId == fieldId then own[id] = true end
end
end
local ownWithRole = {}
for _, candidate in ipairs(candidates or {}) do
local hasRole = candidate.role == role or (candidate.roles ~= nil and candidate.roles[role])
if own[candidate.id] and hasRole then table.insert(ownWithRole, candidate) end
end
if #ownWithRole > 0 then return ownWithRole end
local free = {}
for _, candidate in ipairs(candidates or {}) do
if ownerOf[candidate.id] == nil then table.insert(free, candidate) end
end
return free
end
-- Gør en maskine fast på én mark (fjernes fra andre marker). Returnerer ny tabel {[fieldId] = ids}.
function ADFieldFleet.dedicate(rigIdsByField, fieldId, vehicleId, isOn)
local result = {}
for otherId, ids in pairs(rigIdsByField or {}) do
local copy = {}
for _, id in ipairs(ids or {}) do if id ~= vehicleId then table.insert(copy, id) end end
result[otherId] = copy
end
result[fieldId] = result[fieldId] or {}
if isOn then table.insert(result[fieldId], vehicleId) end
return result
end
function ADFieldFleet.pick(candidates, role, x, z, requiredWidth, accept) function ADFieldFleet.pick(candidates, role, x, z, requiredWidth, accept)
local usable, reason, args = sortCandidates(candidates, role, x, z, requiredWidth, accept) local usable, reason, args = sortCandidates(candidates, role, x, z, requiredWidth, accept)
if usable[1] ~= nil then return usable[1].candidate end if usable[1] ~= nil then return usable[1].candidate end
+4
View File
@@ -61,6 +61,8 @@ local function copyPlan(plan)
for key, value in pairs(DEFAULT_PLAN) do copy[key] = value end for key, value in pairs(DEFAULT_PLAN) do copy[key] = value end
for key, value in pairs(plan or {}) do copy[key] = value end for key, value in pairs(plan or {}) do copy[key] = value end
copy.storeBuildingIds = copyList(plan ~= nil and plan.storeBuildingIds or nil) copy.storeBuildingIds = copyList(plan ~= nil and plan.storeBuildingIds or nil)
-- faste maskiner (køretøjs-id'er) til marken; en fast maskine bruges kun her
copy.rigIds = copyList(plan ~= nil and plan.rigIds or nil)
return copy return copy
end end
@@ -448,6 +450,7 @@ function ADFieldModel.toRecord(field)
return { return {
id = field.id, stage = field.stage, mode = plan.mode, product = plan.product, id = field.id, stage = field.stage, mode = plan.mode, product = plan.product,
rake = flag(plan.rake), store = table.concat(plan.storeBuildingIds, " "), rake = flag(plan.rake), store = table.concat(plan.storeBuildingIds, " "),
dedicated = table.concat(plan.rigIds or {}, " "),
rigs = plan.rigs, unloaders = plan.unloaders, mulch = flag(plan.mulch), lime = flag(plan.lime), rigs = plan.rigs, unloaders = plan.unloaders, mulch = flag(plan.mulch), lime = flag(plan.lime),
soil = plan.soil, sow = flag(plan.sow), sowFruit = plan.sowFruit or "", roll = flag(plan.roll), soil = plan.soil, sow = flag(plan.sow), sowFruit = plan.sowFruit or "", roll = flag(plan.roll),
fertilize = flag(plan.fertilize), weed = flag(plan.weed), fertilize = flag(plan.fertilize), weed = flag(plan.weed),
@@ -479,6 +482,7 @@ function ADFieldModel.fromRecord(record)
plan.product = PRODUCTS[record.product] and record.product or "auto" plan.product = PRODUCTS[record.product] and record.product or "auto"
plan.rake = readFlag(record.rake, false) plan.rake = readFlag(record.rake, false)
for id in string.gmatch(record.store or "", "%S+") do table.insert(plan.storeBuildingIds, id) end for id in string.gmatch(record.store or "", "%S+") do table.insert(plan.storeBuildingIds, id) end
for id in string.gmatch(record.dedicated or "", "%S+") do table.insert(plan.rigIds, id) end
plan.rigs = clamp(record.rigs or 1, 1, ADFieldModel.MAX_RIGS) plan.rigs = clamp(record.rigs or 1, 1, ADFieldModel.MAX_RIGS)
plan.unloaders = clamp(record.unloaders or 1, 1, ADFieldModel.MAX_UNLOADERS) plan.unloaders = clamp(record.unloaders or 1, 1, ADFieldModel.MAX_UNLOADERS)
plan.mulch = readFlag(record.mulch, false) plan.mulch = readFlag(record.mulch, false)
+1
View File
@@ -13,6 +13,7 @@ ADFieldStorage.FIELD_TYPES = {
sowFruit = "String", roll = "Int", fertilize = "Int", weed = "Int", sowFruit = "String", roll = "Int", fertilize = "Int", weed = "Int",
kind = "String", lastFruit = "String", care = "String", targetFruit = "String", prepAfterMow = "Int", straw = "String", kind = "String", lastFruit = "String", care = "String", targetFruit = "String", prepAfterMow = "Int", straw = "String",
mowWidth = "Float", mowVehicle = "String", rakeVehicle = "String", harvestVehicle = "String", windrowOffset = "String", mowWidth = "Float", mowVehicle = "String", rakeVehicle = "String", harvestVehicle = "String", windrowOffset = "String",
dedicated = "String",
} }
function ADFieldStorage.getPath() function ADFieldStorage.getPath()
+27 -3
View File
@@ -15,6 +15,8 @@ ADFieldWork.PLAYER_DRIVING_KMH = 3
ADFieldWork.WINDROW_MEASURE_MS = 10000 ADFieldWork.WINDROW_MEASURE_MS = 10000
-- mangler der sæt, prøves igen efter så lang tid (ikke hvert sekund over hele flåden) -- mangler der sæt, prøves igen efter så lang tid (ikke hvert sekund over hele flåden)
ADFieldWork.NO_RIG_RETRY_MS = 30000 ADFieldWork.NO_RIG_RETRY_MS = 30000
-- AutoDrive der stopper før markøren startes igen så mange gange, før turen opgives
ADFieldWork.DRIVE_RETRIES = 2
ADFieldWork.REFILL_ROLES = {seeder = true, fertilizer = true, limer = true, weeder = true} ADFieldWork.REFILL_ROLES = {seeder = true, fertilizer = true, limer = true, weeder = true}
local function log(...) ADFieldJobs.log(...) end local function log(...) ADFieldJobs.log(...) end
@@ -57,12 +59,18 @@ local function helperCp(adEnv)
return adEnv.ADStateModule ~= nil and adEnv.ADStateModule.HELPER_CP or 1 return adEnv.ADStateModule ~= nil and adEnv.ADStateModule.HELPER_CP or 1
end end
local function startAd(adEnv, vehicle, mode, firstId, secondId) -- fillType (valgfri, LOAD): varen AutoDrive skal læsse — uden den kører AD til påfyldningen og hjem tom
-- (in-game 26/9: sprøjten kom tom tilbage fra Buying Station Multifruit)
local function startAd(adEnv, vehicle, mode, firstId, secondId, fillType)
local module = stateModule(vehicle) local module = stateModule(vehicle)
stopAd(vehicle) stopAd(vehicle)
module:setMode(mode) module:setMode(mode)
module:setFirstMarkerByWayPointId(firstId) module:setFirstMarkerByWayPointId(firstId)
if secondId ~= nil then module:setSecondMarkerByWayPointId(secondId) end if secondId ~= nil then module:setSecondMarkerByWayPointId(secondId) end
if fillType ~= nil then
module:setFillType(fillType)
module.selectedFillTypes = {fillType}
end
module:setStartHelper(false) module:setStartHelper(false)
if module.setActualFarmId ~= nil then module:setActualFarmId(vehicle:getOwnerFarmId()) end if module.setActualFarmId ~= nil then module:setActualFarmId(vehicle:getOwnerFarmId()) end
module:raiseDirtyFlag() module:raiseDirtyFlag()
@@ -316,7 +324,10 @@ function ADFieldWork.dispatch(adEnv, field, info, decision)
note(field.id, {retryAt = now() + ADFieldModel.RETRY_MS, reason = reason}) note(field.id, {retryAt = now() + ADFieldModel.RETRY_MS, reason = reason})
return return
end end
local candidates = ADFieldWork.getRigs(adEnv) -- faste maskiner: andre markers faste bruges ikke; har marken selv faste med rollen, kun dem
local rigIdsByField = {}
for fieldId, other in pairs(ADFieldJobs.state.fields) do rigIdsByField[fieldId] = other.plan ~= nil and other.plan.rigIds or nil end
local candidates = ADFieldFleet.filterDedicated(ADFieldWork.getRigs(adEnv), field.id, role, rigIdsByField)
local required = ADFieldModel.requiredWidth(field, role) local required = ADFieldModel.requiredWidth(field, role)
local accept = acceptFor(field, info, role) local accept = acceptFor(field, info, role)
local rigs, why, args local rigs, why, args
@@ -349,12 +360,14 @@ function ADFieldWork.dispatch(adEnv, field, info, decision)
ADFieldJobs.state.assignments[rig.id] = assignment ADFieldJobs.state.assignments[rig.id] = assignment
if refill ~= nil and refill.empty then if refill ~= nil and refill.empty then
-- AutoDrive LOAD: påfyldningen (2. markør), fyld op, videre til F-markøren (1.) — så Courseplay -- AutoDrive LOAD: påfyldningen (2. markør), fyld op, videre til F-markøren (1.) — så Courseplay
startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_LOAD, info.markerId, refill.refillId) startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_LOAD, info.markerId, refill.refillId, refill.fillType)
assignment.drive = {mode = adEnv.AutoDrive.MODE_LOAD, first = info.markerId, second = refill.refillId, fillType = refill.fillType}
local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(refill.refillId) local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(refill.refillId)
log(field.id, "%s '%s' er tom — fyldes med %s ved %s og kører så til %s", role, rig.label, fillTypeName(refill.fillType), log(field.id, "%s '%s' er tom — fyldes med %s ved %s og kører så til %s", role, rig.label, fillTypeName(refill.fillType),
tostring(marker ~= nil and marker.name or refill.refillId), tostring(info.markerName)) tostring(marker ~= nil and marker.name or refill.refillId), tostring(info.markerName))
else else
startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_DRIVETO, info.markerId, nil) startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_DRIVETO, info.markerId, nil)
assignment.drive = {mode = adEnv.AutoDrive.MODE_DRIVETO, first = info.markerId}
log(field.id, "%s '%s' sendt til %s (%.1f m%s)", role, rig.label, tostring(info.markerName), rig.width or 0, log(field.id, "%s '%s' sendt til %s (%.1f m%s)", role, rig.label, tostring(info.markerName), rig.width or 0,
assignment.lane ~= nil and string.format(", bane %d", assignment.lane) or "") assignment.lane ~= nil and string.format(", bane %d", assignment.lane) or "")
end end
@@ -751,9 +764,20 @@ function ADFieldWork.follow(adEnv, assignment)
local distance = wayPoint ~= nil and math.sqrt((wayPoint.x - x) ^ 2 + (wayPoint.z - z) ^ 2) or math.huge local distance = wayPoint ~= nil and math.sqrt((wayPoint.x - x) ^ 2 + (wayPoint.z - z) ^ 2) or math.huge
if distance <= ADFieldWork.ARRIVE_DISTANCE then if distance <= ADFieldWork.ARRIVE_DISTANCE then
beginWork(adEnv, field, info, assignment) beginWork(adEnv, field, info, assignment)
elseif assignment.drive ~= nil and (assignment.driveRetries or 0) < ADFieldWork.DRIVE_RETRIES then
-- AutoDrive stoppede undervejs (spilleren byggede, trafik, ...): kør videre i stedet for at opgive
assignment.driveRetries = (assignment.driveRetries or 0) + 1
assignment.since = now()
local d = assignment.drive
startAd(adEnv, vehicle, d.mode, d.first, d.second, d.fillType)
log(assignment.fieldId, "'%s' stoppede %.0f m fra %s — AutoDrive startes igen (%d/%d)", ADRuns.vehicleLabel(vehicle), distance,
tostring(info ~= nil and info.markerName or "?"), assignment.driveRetries, ADFieldWork.DRIVE_RETRIES)
else else
ADFieldWork.release(assignment) ADFieldWork.release(assignment)
fail(assignment.fieldId, string.format("%s nåede ikke %s (%.0f m væk)", ADRuns.vehicleLabel(vehicle), tostring(info ~= nil and info.markerName or "?"), distance)) fail(assignment.fieldId, string.format("%s nåede ikke %s (%.0f m væk)", ADRuns.vehicleLabel(vehicle), tostring(info ~= nil and info.markerName or "?"), distance))
-- ikke efterladt midt på vejen/ved en mark: hjem til parkeringen
local park = parkMarkerId(adEnv, vehicle)
if park ~= nil then startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DRIVETO, park, nil) end
end end
end end
elseif assignment.phase == "waitingCourse" then elseif assignment.phase == "waitingCourse" then
+36 -1
View File
@@ -9,7 +9,7 @@ SmartPickupFrame.FIELD_ROW_KINDS = {
fieldProduct = true, fieldMode = true, fieldRake = true, fieldStore = true, fleetVehicle = true, fieldProduct = true, fieldMode = true, fieldRake = true, fieldStore = true, fleetVehicle = true,
fieldRigs = true, fieldUnloaders = true, fieldMulch = true, fieldLime = true, fieldSoil = true, fieldRigs = true, fieldUnloaders = true, fieldMulch = true, fieldLime = true, fieldSoil = true,
fieldSow = true, fieldSowFruit = true, fieldRoll = true, fieldFertilize = true, fieldWeed = true, fieldSow = true, fieldSowFruit = true, fieldRoll = true, fieldFertilize = true, fieldWeed = true,
fieldTarget = true, fleetMode = true, fieldStraw = true, fieldTarget = true, fleetMode = true, fieldStraw = true, fieldRig = true,
} }
SmartPickupFrame.ROLE_KEYS = { SmartPickupFrame.ROLE_KEYS = {
mower = "spu_field_role_mower", tedder = "spu_field_role_tedder", rake = "spu_field_role_rake", mower = "spu_field_role_mower", tedder = "spu_field_role_tedder", rake = "spu_field_role_rake",
@@ -277,6 +277,7 @@ function SmartPickupFrame:fillFieldStoreRows(adEnv, info, field)
fillType = info.harvestFillType fillType = info.harvestFillType
end end
if fillType == nil then return end if fillType == nil then return end
self:fillDedicatedRows(adEnv, field)
self:addTextRow(i18n:getText("spu_field_section_store")) self:addTextRow(i18n:getText("spu_field_section_store"))
local chosen = {} local chosen = {}
for _, id in ipairs(field.plan.storeBuildingIds) do chosen[id] = true end for _, id in ipairs(field.plan.storeBuildingIds) do chosen[id] = true end
@@ -358,6 +359,31 @@ function SmartPickupFrame:rigDetails(rig)
return #parts > 0 and (" — " .. table.concat(parts, " — ")) or "" return #parts > 0 and (" — " .. table.concat(parts, " — ")) or ""
end end
-- Faste maskiner til den valgte mark: en fast maskine bruges kun her, og marken venter på sin egen hellere
-- end at låne en anden med samme opgave. Maskiner der er faste på en anden mark er markeret.
function SmartPickupFrame:fillDedicatedRows(adEnv, field)
local i18n = self.i18n
self:addTextRow(i18n:getText("spu_field_section_dedicated"))
local owner = {}
for fieldId, other in pairs(ADFieldJobs.state.fields) do
for _, id in ipairs(other.plan ~= nil and other.plan.rigIds or {}) do owner[id] = fieldId end
end
local rigs = ADFieldJobs.getRigs(adEnv)
table.sort(rigs, function(a, b)
local ma, mb = owner[a.id] == field.id, owner[b.id] == field.id
if ma ~= mb then return ma end
if a.role ~= b.role then return a.role < b.role end
return ADFlowView.naturalLess(a.label, b.label)
end)
for _, rig in ipairs(rigs) do
local row = self:addRow(self.vehiclePrefab, {kind = "fieldRig", vehicleId = rig.id})
local elsewhere = owner[rig.id] ~= nil and owner[rig.id] ~= field.id
and (" — " .. string.format(i18n:getText("spu_field_dedicatedElsewhere"), tostring(owner[rig.id]))) or ""
row:getDescendantByName("title"):setText(string.format(" %s — %s%s", tostring(rig.label), self:roleText(rig.role), elsewhere))
row:getDescendantByName("option"):setState(owner[rig.id] == field.id and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false)
end
end
function SmartPickupFrame:fillFleetRows(adEnv) function SmartPickupFrame:fillFleetRows(adEnv)
local i18n = self.i18n local i18n = self.i18n
self:addTextRow(i18n:getText("spu_field_section_fleet")) self:addTextRow(i18n:getText("spu_field_section_fleet"))
@@ -424,6 +450,15 @@ function SmartPickupFrame:onClickFieldRow(state, data)
ADFieldJobs.setPlan(id, {mode = isOn and "auto" or "manual"}) ADFieldJobs.setPlan(id, {mode = isOn and "auto" or "manual"})
elseif SmartPickupFrame.PLAN_TOGGLES[data.kind] ~= nil then elseif SmartPickupFrame.PLAN_TOGGLES[data.kind] ~= nil then
ADFieldJobs.setPlan(id, {[SmartPickupFrame.PLAN_TOGGLES[data.kind]] = isOn}) ADFieldJobs.setPlan(id, {[SmartPickupFrame.PLAN_TOGGLES[data.kind]] = isOn})
elseif data.kind == "fieldRig" then
-- fast på denne mark (og fjernes fra en anden mark)
local byField = {}
for fieldId, other in pairs(ADFieldJobs.state.fields) do byField[fieldId] = other.plan ~= nil and other.plan.rigIds or {} end
local updated = ADFieldFleet.dedicate(byField, id, data.vehicleId, isOn)
for fieldId, ids in pairs(updated) do
local before = table.concat(byField[fieldId] or {}, " ")
if before ~= table.concat(ids, " ") then ADFieldJobs.setPlan(fieldId, {rigIds = ids}) end
end
elseif data.kind == "fieldStore" then elseif data.kind == "fieldStore" then
local ids = {} local ids = {}
for _, buildingId in ipairs(ADFieldJobs.getField(id).plan.storeBuildingIds) do for _, buildingId in ipairs(ADFieldJobs.getField(id).plan.storeBuildingIds) do
+2
View File
@@ -80,6 +80,8 @@
<text name="spu_field_marker" text=" Markør %s, %.0f m fra marken"/> <text name="spu_field_marker" text=" Markør %s, %.0f m fra marken"/>
<text name="spu_field_mowWidth" text=" Slået med %.1f m — opsamling skal være mindst lige så bred"/> <text name="spu_field_mowWidth" text=" Slået med %.1f m — opsamling skal være mindst lige så bred"/>
<text name="spu_field_section_store" text="— Tving lager (ellers nærmeste silo med plads) —"/> <text name="spu_field_section_store" text="— Tving lager (ellers nærmeste silo med plads) —"/>
<text name="spu_field_section_dedicated" text="— Faste maskiner til denne mark (bruges kun her; ingen valgt = de frie) —"/>
<text name="spu_field_dedicatedElsewhere" text="fast på F%s"/>
<text name="spu_field_fieldSilo" text="marksilo"/> <text name="spu_field_fieldSilo" text="marksilo"/>
<text name="spu_field_storeHidden" text="+ %d siloer længere væk vises ikke"/> <text name="spu_field_storeHidden" text="+ %d siloer længere væk vises ikke"/>
<text name="spu_field_noStore" text="ingen silo tager markens vare"/> <text name="spu_field_noStore" text="ingen silo tager markens vare"/>
+2
View File
@@ -80,6 +80,8 @@
<text name="spu_field_marker" text=" Marker %s, %.0f m from the field"/> <text name="spu_field_marker" text=" Marker %s, %.0f m from the field"/>
<text name="spu_field_mowWidth" text=" Mowed at %.1f m — collecting must be at least as wide"/> <text name="spu_field_mowWidth" text=" Mowed at %.1f m — collecting must be at least as wide"/>
<text name="spu_field_section_store" text="— Force storage (else nearest silo with room) —"/> <text name="spu_field_section_store" text="— Force storage (else nearest silo with room) —"/>
<text name="spu_field_section_dedicated" text="— Dedicated machines for this field (used only here; none = the free ones) —"/>
<text name="spu_field_dedicatedElsewhere" text="dedicated to F%s"/>
<text name="spu_field_fieldSilo" text="field silo"/> <text name="spu_field_fieldSilo" text="field silo"/>
<text name="spu_field_storeHidden" text="+ %d silos further away not shown"/> <text name="spu_field_storeHidden" text="+ %d silos further away not shown"/>
<text name="spu_field_noStore" text="no silo takes this field's goods"/> <text name="spu_field_noStore" text="no silo takes this field's goods"/>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107"> <modDesc descVersion="107">
<author>masterdraco</author> <author>masterdraco</author>
<version>1.29.6.0</version> <version>1.30.0.0</version>
<title> <title>
<en>AD Smart Pickup</en> <en>AD Smart Pickup</en>
</title> </title>
+17
View File
@@ -105,5 +105,22 @@ check("FLS gødskning: tom før nærmere med kalk på", F.pick(spreaders, "ferti
check("FLS kun kalk-sprederen: bruges (tømmes)", F.pick({spreaders[1]}, "fertilizer", 0, 0).id, "kalk") check("FLS kun kalk-sprederen: bruges (tømmes)", F.pick({spreaders[1]}, "fertilizer", 0, 0).id, "kalk")
check("FLS kalkning: den med kalk på foretrækkes", F.pick(spreaders, "limer", 0, 0).id, "kalk") check("FLS kalkning: den med kalk på foretrækkes", F.pick(spreaders, "limer", 0, 0).id, "kalk")
-- FLD: faste maskiner pr. mark
local sprayA = {id = "sprøjte", role = "fertilizer"}
local sprayB = {id = "spreder", role = "fertilizer"}
local harve = {id = "harve", role = "cultivator"}
local all = {sprayA, sprayB, harve}
local byField = {[22] = {"sprøjte"}}
local function ids(list) local out = {} for _, c in ipairs(list) do table.insert(out, c.id) end return table.concat(out, ",") end
check("FLD F22 gødskning: kun sin faste", ids(F.filterDedicated(all, 22, "fertilizer", byField)), "sprøjte")
check("FLD F109 gødskning: ikke F22's", ids(F.filterDedicated(all, 109, "fertilizer", byField)), "spreder,harve")
check("FLD F22 kultivering: ingen fast med rollen -> frie", ids(F.filterDedicated(all, 22, "cultivator", byField)), "spreder,harve")
check("FLD uden faste = alle", ids(F.filterDedicated(all, 5, "fertilizer", {})), "sprøjte,spreder,harve")
local moved = F.dedicate(byField, 109, "sprøjte", true)
check("FLD flyt: væk fra F22", #moved[22], 0)
check("FLD flyt: fast på F109", moved[109][1], "sprøjte")
check("FLD original urørt", byField[22][1], "sprøjte")
check("FLD fjern", #F.dedicate(moved, 109, "sprøjte", false)[109], 0)
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1) os.exit(failures == 0 and 0 or 1)
+2 -1
View File
@@ -90,7 +90,7 @@ check("M7 wantsRig klar = nil", M.wantsRig(ready, 0, 0), nil)
-- M8: gem/indlæs bevarer trin, plan og slåbredde -- M8: gem/indlæs bevarer trin, plan og slåbredde
local saved = M.advance(M.start(M.onReadiness(M.newField(109), 1))); saved.mowWidth = 40.8; saved.mowVehicleId = "vehicleBigM" local saved = M.advance(M.start(M.onReadiness(M.newField(109), 1))); saved.mowWidth = 40.8; saved.mowVehicleId = "vehicleBigM"
saved.plan = {mode = "auto", product = "hay", rake = true, storeBuildingIds = {"b12", "b7"}} saved.plan = {mode = "auto", product = "hay", rake = true, storeBuildingIds = {"b12", "b7"}, rigIds = {"v1", "v2"}}
local back = M.fromRecord(M.toRecord(saved)) local back = M.fromRecord(M.toRecord(saved))
check("M8 id", back.id, 109) check("M8 id", back.id, 109)
check("M8 stage", back.stage, saved.stage) check("M8 stage", back.stage, saved.stage)
@@ -98,6 +98,7 @@ check("M8 mode", back.plan.mode, "auto")
check("M8 product", back.plan.product, "hay") check("M8 product", back.plan.product, "hay")
check("M8 rake", back.plan.rake, true) check("M8 rake", back.plan.rake, true)
check("M8 lager", table.concat(back.plan.storeBuildingIds, " "), "b12 b7") check("M8 lager", table.concat(back.plan.storeBuildingIds, " "), "b12 b7")
check("M8 faste maskiner", table.concat(back.plan.rigIds, " "), "v1 v2")
check("M8 slåbredde", back.mowWidth, 40.8) check("M8 slåbredde", back.mowWidth, 40.8)
check("M8 slåmaskine", back.mowVehicleId, "vehicleBigM") check("M8 slåmaskine", back.mowVehicleId, "vehicleBigM")
check("M8 ingen slåmaskine", M.fromRecord({id = 4, stage = "idle"}).mowVehicleId, nil) check("M8 ingen slåmaskine", M.fromRecord({id = 4, stage = "idle"}).mowVehicleId, nil)