169 lines
7.0 KiB
Lua
169 lines
7.0 KiB
Lua
-- AD Names
|
|
-- Egne bygningsnavne (FS25 kan ikke omdøbe bygninger): ADSmartPickup_names.xml i savegame-mappen,
|
|
-- <ADSmartPickupNames><building id="placeable…" name="Gårdsilo 10"/></ADSmartPickupNames>.
|
|
-- Moden tilføjer kun navne (nye bygninger / Omdøb-knappen) og ændrer aldrig et eksisterende navn af sig selv.
|
|
|
|
ADNames = {}
|
|
ADNames.FILE_NAME = "ADSmartPickup_names.xml"
|
|
ADNames.ROOT = "ADSmartPickupNames"
|
|
ADNames.byId = nil
|
|
|
|
-- records = {{id, name}} -> {[id] = name}; tomme/ugyldige springes over
|
|
function ADNames.fromRecords(records)
|
|
local byId = {}
|
|
for _, record in ipairs(records or {}) do
|
|
local id, name = record.id, record.name
|
|
if type(id) == "string" and id ~= "" and type(name) == "string" and name:match("%S") then byId[id] = name end
|
|
end
|
|
return 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 .. "$", ADNames.FILE_NAME))
|
|
end
|
|
|
|
function ADNames.load()
|
|
ADNames.byId = {}
|
|
local path = getPath()
|
|
if path == nil or not fileExists(path) then return end
|
|
local xmlFile = XMLFile.load("ADSmartPickupNames", path)
|
|
if xmlFile == nil then return end
|
|
local records = {}
|
|
xmlFile:iterate(ADNames.ROOT .. ".building", function(_, key)
|
|
table.insert(records, {id = xmlFile:getString(key .. "#id"), name = xmlFile:getString(key .. "#name")})
|
|
end)
|
|
xmlFile:delete()
|
|
ADNames.byId = ADNames.fromRecords(records)
|
|
local count = 0
|
|
for _ in pairs(ADNames.byId) do count = count + 1 end
|
|
Logging.info("ADSmartPickup: %d egne bygningsnavne indlæst", count)
|
|
end
|
|
|
|
-- Eget navn for bygningen (placeable), ellers nil.
|
|
function ADNames.forPlaceable(placeable)
|
|
if placeable == nil or placeable.uniqueId == nil then return nil end
|
|
if ADNames.byId == nil then pcall(ADNames.load) end
|
|
return (ADNames.byId or {})[tostring(placeable.uniqueId)]
|
|
end
|
|
|
|
function ADNames.save()
|
|
local path = getPath()
|
|
if path == nil then return false end
|
|
local xmlFile = XMLFile.create("ADSmartPickupNames", path, ADNames.ROOT)
|
|
if xmlFile == nil then return false end
|
|
local ids = {}
|
|
for id in pairs(ADNames.byId or {}) do table.insert(ids, id) end
|
|
table.sort(ids)
|
|
for index, id in ipairs(ids) do
|
|
local key = string.format("%s.building(%d)", ADNames.ROOT, index - 1)
|
|
xmlFile:setString(key .. "#id", id)
|
|
xmlFile:setString(key .. "#name", ADNames.byId[id])
|
|
end
|
|
xmlFile:save()
|
|
xmlFile:delete()
|
|
return true
|
|
end
|
|
|
|
-- Omdøb (knappen i bygningsfanerne): gemmes straks; tomt navn = tilbage til butiksnavnet.
|
|
function ADNames.set(id, name)
|
|
if ADNames.byId == nil then pcall(ADNames.load) end
|
|
local trimmed = type(name) == "string" and name:match("^%s*(.-)%s*$") or ""
|
|
ADNames.byId[id] = trimmed ~= "" and trimmed or nil
|
|
pcall(ADNames.save)
|
|
Logging.info("ADSmartPickup: bygning %s omdøbt til '%s'", tostring(id), trimmed)
|
|
if ADBuildings ~= nil and ADBuildings.invalidate ~= nil then ADBuildings.invalidate() end
|
|
end
|
|
|
|
local function position(placeable)
|
|
local node = placeable ~= nil and placeable.rootNode or nil
|
|
if node == nil then return nil end
|
|
local x, _, z = getWorldTranslation(node)
|
|
return x, z
|
|
end
|
|
|
|
local function animalTypeName(placeable)
|
|
local ok, name = pcall(function()
|
|
local index = placeable:getAnimalTypeIndex()
|
|
local animalType = g_currentMission.animalSystem:getTypeByIndex(index)
|
|
return animalType ~= nil and animalType.name or nil
|
|
end)
|
|
return ok and name or nil
|
|
end
|
|
|
|
local function rawName(placeable)
|
|
local ok, name = pcall(placeable.getName, placeable)
|
|
return ok and name ~= nil and tostring(name) or nil
|
|
end
|
|
|
|
-- Mark-markører ("F118") fra AutoDrive: {{name, x, z}}
|
|
local function fieldMarkers(adEnv)
|
|
local result = {}
|
|
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
|
|
if tostring(marker.name):match("^F%d+$") then
|
|
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
|
|
if wayPoint ~= nil then table.insert(result, {name = marker.name, x = wayPoint.x, z = wayPoint.z}) end
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
-- Nye bygninger (uden navn) får et navn efter ADNaming; kaldes når bygningslisten bygges. Retter navnene i
|
|
-- listen med det samme og gemmer filen, hvis der kom nye.
|
|
function ADNames.autoName(adEnv, buildings)
|
|
if ADNames.byId == nil then pcall(ADNames.load) end
|
|
local existing = ADNames.byId or {}
|
|
local missing = false
|
|
for _, building in ipairs(buildings) do if existing[building.id] == nil and building.kind ~= "sell" then missing = true break end end
|
|
if not missing then return end
|
|
-- gårdens klynge: valgte gårdlagre i marksilo-flowet + siloer der allerede hedder "Gårdsilo …", og naboer ≤ 60 m
|
|
local silos, farm, queue = {}, {}, {}
|
|
for _, building in ipairs(buildings) do
|
|
if building.kind == "silo" then
|
|
local x, z = position(building.placeable)
|
|
if x ~= nil then
|
|
local silo = {id = building.id, x = x, z = z}
|
|
table.insert(silos, silo)
|
|
local isStore = ADFieldSilos ~= nil and ADFieldSiloConfig ~= nil and ADFieldSiloConfig.hasStore(ADFieldSilos.config, building.id)
|
|
if isStore or tostring(existing[building.id] or ""):match("^Gårdsilo") then farm[building.id] = true; table.insert(queue, silo) end
|
|
end
|
|
end
|
|
end
|
|
while #queue > 0 do
|
|
local current = table.remove(queue)
|
|
for _, silo in ipairs(silos) do
|
|
if not farm[silo.id] and (silo.x - current.x) ^ 2 + (silo.z - current.z) ^ 2 <= 3600 then farm[silo.id] = true; table.insert(queue, silo) end
|
|
end
|
|
end
|
|
local fields = fieldMarkers(adEnv)
|
|
local inputs = {}
|
|
for _, building in ipairs(buildings) do
|
|
if existing[building.id] == nil then
|
|
local x, z = position(building.placeable)
|
|
local nearest = nil
|
|
if x ~= nil and building.kind == "silo" then
|
|
for _, field in ipairs(fields) do
|
|
local distance = math.sqrt((field.x - x) ^ 2 + (field.z - z) ^ 2)
|
|
if nearest == nil or distance < nearest.distance then nearest = {name = field.name, distance = distance} end
|
|
end
|
|
end
|
|
table.insert(inputs, {id = building.id, kind = building.kind, animal = building.kind == "husbandry" and animalTypeName(building.placeable) or nil,
|
|
storeName = rawName(building.placeable), inFarmCluster = farm[building.id] == true, nearestField = nearest})
|
|
end
|
|
end
|
|
local added = ADNaming.assign(inputs, existing)
|
|
local count = 0
|
|
for id, name in pairs(added) do
|
|
existing[id] = name
|
|
count = count + 1
|
|
Logging.info("ADSmartPickup: ny bygning navngivet '%s' (%s)", name, id)
|
|
end
|
|
if count == 0 then return end
|
|
ADNames.byId = existing
|
|
for _, building in ipairs(buildings) do
|
|
if added[building.id] ~= nil then building.name = added[building.id] end
|
|
end
|
|
pcall(ADNames.save)
|
|
end
|