b33f7682b4
Moddets markopgaver starter CP med eget job; HUD'en kunne stå på bunkersilo, og HUD-starten efter indlæsning gav 'CP: No silo found' (v1.60.13.0).
129 lines
5.1 KiB
Lua
129 lines
5.1 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()
|
|
Logging.info(ADCpResume.LOG_PREFIX .. "gemt: %d maskine(r) kører Courseplay", #ids)
|
|
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
|