feat: spuNameFleet giver traktorer uden for flows butiksnavne (+ parkering 'P <navn>'); stoppede flows' traktorer der holder med vogn efter indlæsning sætter den på plads (v1.51.1.0)

This commit is contained in:
2026-09-28 23:20:10 +02:00
parent b0d22236b0
commit d2ac2fb36d
4 changed files with 137 additions and 1 deletions
+78
View File
@@ -0,0 +1,78 @@
-- AD Fleet Names
-- Konsol "spuNameFleet": traktorer/lastbiler uden for flows får spillets butiksnavn (nummereret når der er flere
-- af samme model), og deres egen AD-parkering hedder "P <navn>". Flow-traktorer beholder flowets navn (mod'en
-- sætter det selv); selvkørende maskiner (mejetærsker, roeoptager …) beholder deres navn.
ADFleetNames = {}
ADFleetNames.LOG_PREFIX = "ADSmartPickup: navne: "
-- ---- ren logik ----
-- vehicles = {{id, model, name, inRun, selfPropelled}} -> {{id, name, parkName, rename}}
function ADFleetNames.plan(vehicles)
local byModel = {}
for _, vehicle in ipairs(vehicles or {}) do
if not vehicle.inRun and not vehicle.selfPropelled then
byModel[vehicle.model] = byModel[vehicle.model] or {}
table.insert(byModel[vehicle.model], vehicle)
end
end
local newNames = {}
for model, list in pairs(byModel) do
table.sort(list, function(a, b) return tostring(a.id) < tostring(b.id) end)
for index, vehicle in ipairs(list) do
newNames[vehicle.id] = #list > 1 and string.format("%s %d", model, index) or model
end
end
local result = {}
for _, vehicle in ipairs(vehicles or {}) do
local name = newNames[vehicle.id] or vehicle.name or vehicle.model
table.insert(result, {id = vehicle.id, name = name, parkName = "P " .. name, rename = newNames[vehicle.id] ~= nil and name ~= vehicle.name})
end
return result
end
-- ---- spil ----
function ADFleetNames.apply(adEnv)
local vehicles, byId = {}, {}
for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do
local id = ADRunsController.getVehicleId(vehicle)
if id ~= nil and vehicle.getName ~= nil then
table.insert(vehicles, {id = id, model = tostring(vehicle:getName()), name = ADRuns.vehicleLabel(vehicle),
inRun = ADRunsController.getRunForVehicle(vehicle) ~= nil,
selfPropelled = not ADPool.canPull(ADPool.ownRole(vehicle))})
byId[id] = vehicle
end
end
local renamed, parks = 0, 0
for _, entry in ipairs(ADFleetNames.plan(vehicles)) do
local vehicle = byId[entry.id]
local module = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
if entry.rename and module ~= nil and module.setName ~= nil then
module:setName(entry.name)
if module.raiseDirtyFlag ~= nil then module:raiseDirtyFlag() end
renamed = renamed + 1
end
local index = vehicle.advd ~= nil and vehicle.advd.parkDestination or nil
local marker = type(index) == "number" and index >= 1 and adEnv.ADGraphManager:getMapMarkerById(index) or nil
if marker ~= nil and marker.name ~= entry.parkName then
adEnv.ADGraphManager:renameMapMarker(entry.parkName, index)
parks = parks + 1
end
end
Logging.info(ADFleetNames.LOG_PREFIX .. "%d maskiner omdøbt, %d parkeringer omdøbt", renamed, parks)
return renamed, parks
end
function ADFleetNames:consoleNameFleet()
local adEnv = ADFieldSilos ~= nil and ADFieldSilos.adEnv or nil
if adEnv == nil then return "spuNameFleet: AutoDrive er ikke klar endnu" end
local ok, renamed, parks = pcall(ADFleetNames.apply, adEnv)
if not ok then return "spuNameFleet: fejl: " .. tostring(renamed) end
return string.format("spuNameFleet: %d maskiner og %d parkeringer omdøbt — gem spillet", renamed, parks)
end
if addConsoleCommand ~= nil then
addConsoleCommand("spuNameFleet", "Giver traktorer uden for flows butiksnavne og deres parkeringer 'P <navn>'", "consoleNameFleet", ADFleetNames)
end
+30
View File
@@ -222,8 +222,38 @@ local function checkBuildings(adEnv)
end
end
-- Én gang efter indlæsning: et stoppet flows traktor der holder stille med sin vogn (gemt midt i hjemturen — AD
-- kørte den færdig, men afkoblingen er glemt) køres hjem. Ikke løbende: spilleren kan selv have koblet på.
ADFlowWagons.AFTER_LOAD_MS = 120000
local sinceLoad, cleanedUp = 0, false
local function cleanupAfterLoad(adEnv)
for _, run in ipairs(runs()) do
if run.stopped then
for _, vehicleId in ipairs(run.vehicleIds or {}) do
local vehicle = ADRunsController.findVehicleById(adEnv, vehicleId)
local module = vehicle ~= nil and vehicle.ad ~= nil and vehicle.ad.stateModule or nil
local controlled = vehicle ~= nil and vehicle.getIsControlled ~= nil and vehicle:getIsControlled()
if module ~= nil and not module:isActive() and not controlled and #ADHitch.poolParkIds(adEnv, vehicle) > 0 then
Logging.info(ADFlowWagons.LOG_PREFIX .. "flow '%s' er stoppet: '%s' sætter sin vogn på plads", tostring(run.name),
tostring(ADRuns.vehicleLabel(vehicle)))
pcall(ADHitch.returnHome, adEnv, vehicle)
end
end
end
end
end
function ADFlowWagons.tick(adEnv, dt)
if adEnv == nil or ADRunsController.store == nil then return end
if not cleanedUp then
sinceLoad = sinceLoad + dt
if sinceLoad >= ADFlowWagons.AFTER_LOAD_MS then
cleanedUp = true
local ok, err = pcall(cleanupAfterLoad, adEnv)
if not ok then Logging.warning(ADFlowWagons.LOG_PREFIX .. "oprydning efter indlæsning: %s", tostring(err)) end
end
end
rememberTimer = rememberTimer + dt
buildingTimer = buildingTimer + dt
if rememberTimer >= ADFlowWagons.REMEMBER_MS then
+2 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107">
<author>masterdraco</author>
<version>1.51.0.0</version>
<version>1.51.1.0</version>
<title>
<en>AD Smart Pickup</en>
</title>
@@ -49,6 +49,7 @@
<sourceFile filename="adHitch.lua"/>
<sourceFile filename="adPool.lua"/>
<sourceFile filename="adFlowWagons.lua"/>
<sourceFile filename="adFleetNames.lua"/>
<sourceFile filename="adFieldJobs.lua"/>
<sourceFile filename="adMonthView.lua"/>
<sourceFile filename="adProfiler.lua"/>
+27
View File
@@ -0,0 +1,27 @@
-- Kør: luajit tests/test_adFleetNames.lua (fra repo-roden)
dofile("FS25_ADSmartPickup/adFleetNames.lua")
local N = ADFleetNames
local failures = 0
local function check(name, actual, expected)
if actual == expected then print("OK " .. name) else
failures = failures + 1
print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual)))
end
end
local plan = N.plan({
{id = "b", model = "Puma 260 CVX"}, {id = "a", model = "Puma 260 CVX"}, {id = "c", model = "Fastrac 4220"},
{id = "d", model = "Cow Food", inRun = true, name = "Cow Food 1"}, {id = "e", model = "CR11", selfPropelled = true, name = "Mejetærsker"},
})
local byId = {}
for _, entry in ipairs(plan) do byId[entry.id] = entry end
check("navne: samme model nummereres (efter id)", byId.a.name, "Puma 260 CVX 1")
check("navne: anden af samme model", byId.b.name, "Puma 260 CVX 2")
check("navne: enlig model uden nummer", byId.c.name, "Fastrac 4220")
check("navne: flow-traktor beholder navn", byId.d.name, "Cow Food 1")
check("navne: selvkørende beholder navn", byId.e.name, "Mejetærsker")
check("parkering: P + navn", byId.a.parkName, "P Puma 260 CVX 1")
check("parkering: flow-traktor", byId.d.parkName, "P Cow Food 1")
check("omdøb: kun hvis ændret", byId.d.rename, false)
check("omdøb: ny navn", byId.a.rename, true)
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)