Files
masterdraco 784144cd4e fix(aflæsning): tipvogn skiftes til en tip-side AD må aflæsse fra
EDK 650 Unrealistic har kun allowAIDischarge på bagudtip; på venstre/højre/
kornluge åbnede AD aflæsningen, men intet løb ud (Chicken Food 2 786.712 l
hvede ved Farma med plads; Disponibel Vogn 3 fuld af løg). CP-genstart logger
kun ved ændring (v1.60.16.0).
2026-09-29 23:23:20 +02:00

134 lines
5.4 KiB
Lua

-- AD CP Resume
-- Spillet stopper alle arbejdere ved gem, og Courseplay genstarter dem ikke (AutoDrive gør selv). Ved hvert gem
-- skrives de maskiner hvor CP kører (uden AD) til ADSmartPickup_cpresume.xml; efter indlæsning startes netop
-- dem igen fra nærmeste waypoint med CP's egen HUD-start (samme job som spilleren sidst valgte i HUD'en).
ADCpResume = {}
ADCpResume.FILE_NAME = "ADSmartPickup_cpresume.xml"
ADCpResume.ROOT = "ADSmartPickupCpResume"
ADCpResume.LOG_PREFIX = "ADSmartPickup: CP-genstart: "
ADCpResume.pending = nil -- {[vehicleId] = true} fra seneste gem; nil = ingen fil (gammel regel bruges)
-- ---- ren logik ----
-- vehicles = {{id, cpActive, adActive}} -> id'er der skal huskes
function ADCpResume.activeIds(vehicles)
local ids = {}
for _, vehicle in ipairs(vehicles or {}) do
if vehicle.cpActive and not vehicle.adActive then table.insert(ids, vehicle.id) end
end
return ids
end
function ADCpResume.fromRecords(ids)
local set = {}
for _, id in ipairs(ids or {}) do
if type(id) == "string" and id ~= "" then set[id] = true end
end
return set
end
-- vehicles = {{id, aiActive, controlled, fieldWork}} i fast rækkefølge -> id'er der skal startes (nil uden gemt liste).
-- fieldWork = false: CP's HUD-job er ikke markarbejde (fx bunkersilo) — HUD-start ville starte det forkerte job
-- (in-game 29/9: "CP: No silo found"); nil = ukendt (ældre CP) -> startes som før.
function ADCpResume.toStart(pending, vehicles)
if pending == nil then return nil end
local ids = {}
for _, vehicle in ipairs(vehicles or {}) do
if pending[vehicle.id] and not vehicle.aiActive and not vehicle.controlled and vehicle.fieldWork ~= false then
table.insert(ids, vehicle.id)
end
end
return ids
end
-- ---- spil ----
-- true/false fra CP's HUD; nil når CP-versionen ikke har funktionen
local function hudFieldWork(vehicle)
if vehicle.cpIsHudFieldWorkJobSelected == nil then return nil end
return vehicle:cpIsHudFieldWorkJobSelected() == true
end
local function vehicleState(adEnv, vehicle)
local ad = vehicle.ad
return {
id = ADRunsController.getVehicleId(vehicle),
cpActive = vehicle.getIsCpActive ~= nil and vehicle:getIsCpActive() == true,
adActive = ad ~= nil and ad.stateModule ~= nil and ad.stateModule:isActive(),
aiActive = vehicle.getIsAIActive ~= nil and vehicle:getIsAIActive() == true,
controlled = vehicle.getIsControlled ~= nil and vehicle:getIsControlled() == true,
fieldWork = hudFieldWork(vehicle),
}
end
local function farmVehicles(adEnv)
local list, byId = {}, {}
for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do
local ok, state = pcall(vehicleState, adEnv, vehicle)
if ok and state.id ~= nil then
table.insert(list, state)
byId[state.id] = vehicle
end
end
return list, byId
end
-- Starter CP fra nærmeste waypoint (HUD-startpunktet sættes som spillerens "start ved nærmeste"-tast).
function ADCpResume.startNearest(vehicle)
if vehicle.cpStartStopDriver == nil or (vehicle.getIsAIActive ~= nil and vehicle:getIsAIActive()) then return false end
if vehicle.getCpStartingPointSetting ~= nil and CpFieldWorkJobParameters ~= nil and vehicle.hasCpCourse ~= nil and vehicle:hasCpCourse() then
local setting = vehicle:getCpStartingPointSetting()
if setting ~= nil then setting:setValue(CpFieldWorkJobParameters.START_AT_NEAREST_POINT) end
end
vehicle:cpStartStopDriver(true)
return true
end
-- Id'er der skal startes nu (nil = ingen gemt liste). Listen bruges kun én gang.
function ADCpResume.takeToStart(adEnv)
local list, byId = farmVehicles(adEnv)
local ids = ADCpResume.toStart(ADCpResume.pending, list)
ADCpResume.pending = nil
return ids, byId
end
local function getPath()
local path = ADRunsStorage ~= nil and ADRunsStorage.getPath() or nil
if path == nil then return nil end
return (path:gsub(ADRunsStorage.FILE_NAME .. "$", ADCpResume.FILE_NAME))
end
function ADCpResume.save(adEnv)
local path = getPath()
if path == nil or adEnv == nil then return false end
local ids = ADCpResume.activeIds((farmVehicles(adEnv)))
local xmlFile = XMLFile.create("ADSmartPickupCpResume", path, ADCpResume.ROOT)
if xmlFile == nil then return false end
for index, id in ipairs(ids) do
xmlFile:setString(string.format("%s.vehicle(%d)#id", ADCpResume.ROOT, index - 1), id)
end
xmlFile:save()
xmlFile:delete()
-- gemmes ved hver runs-gem (flere gange i minuttet): log kun når listen ændrer sig
local signature = table.concat(ids, ",")
if signature ~= ADCpResume.lastLogged then
ADCpResume.lastLogged = signature
Logging.info(ADCpResume.LOG_PREFIX .. "gemt: %d maskine(r) kører Courseplay", #ids)
end
return true
end
function ADCpResume.load()
ADCpResume.pending = nil
local path = getPath()
if path == nil or not fileExists(path) then return end
local xmlFile = XMLFile.load("ADSmartPickupCpResume", path)
if xmlFile == nil then return end
local ids = {}
xmlFile:iterate(ADCpResume.ROOT .. ".vehicle", function(_, key) table.insert(ids, xmlFile:getString(key .. "#id")) end)
xmlFile:delete()
ADCpResume.pending = ADCpResume.fromRecords(ids)
Logging.info(ADCpResume.LOG_PREFIX .. "%d maskine(r) kørte Courseplay ved sidste gem", #ids)
end