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:
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"/>
|
||||||
|
|||||||
@@ -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,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>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user