fix: fane sidst i ESC-menuen (ingen omrokering), stald-foder via spec_husbandryFood/animalFoodSystem, mål = kun stalde+fabrikker, korte Wait-labels (v1.9.2.0)

This commit is contained in:
2026-09-23 00:13:58 +02:00
parent 90d86b22e9
commit 3c22eae0eb
6 changed files with 150 additions and 42 deletions
+31 -4
View File
@@ -371,14 +371,41 @@ end
-- ---- opslag til dropdowns ----
-- Mål er steder der SKAL holdes fyldt: stalde (1) og fabrikker (2). Siloer tager alt og
-- er kilder, ikke mål. Returnerer markører sorteret efter type, dernæst navn.
local function getTargetKind(station)
local placeable = station.owningPlaceable
if placeable == nil then
return nil
end
if placeable.getHusbandryFillLevel ~= nil then
return 1
end
if placeable.spec_productionPoint ~= nil then
return 2
end
return nil
end
function ADRunsController.getTargetMarkers(adEnv, farmId)
local result = {}
local entries = {}
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
if ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId) ~= nil then
table.insert(result, marker)
local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId)
local kind = station ~= nil and getTargetKind(station) or nil
if kind ~= nil then
table.insert(entries, {marker = marker, kind = kind})
end
end
table.sort(result, function(a, b) return tostring(a.name) < tostring(b.name) end)
table.sort(entries, function(a, b)
if a.kind ~= b.kind then
return a.kind < b.kind
end
return tostring(a.marker.name) < tostring(b.marker.name)
end)
local result = {}
for index, entry in ipairs(entries) do
result[index] = entry.marker
end
return result
end
+75 -33
View File
@@ -368,13 +368,68 @@ local function getHusbandry(station)
return nil
end
-- FS25-staldes foder ligger i spec_husbandryFood: ét fælles trug (capacity) med niveau pr.
-- vare (fillLevels). Hvilke varer der er foder, ved animalFoodSystem (grupper + blandinger).
-- Returnerer {[fillType] = true} eller nil når stalden ikke har foder-spec.
local function getHusbandryFoodFillTypes(husbandry)
local foodSpec = husbandry.spec_husbandryFood
local foodSystem = g_currentMission ~= nil and g_currentMission.animalFoodSystem or nil
if foodSpec == nil or foodSystem == nil or foodSpec.animalTypeIndex == nil then
return nil
end
local fillTypes = {}
local animalFood = foodSystem.getAnimalFood ~= nil and foodSystem:getAnimalFood(foodSpec.animalTypeIndex) or nil
for _, group in pairs(animalFood ~= nil and animalFood.groups or {}) do
for _, fillType in pairs(group.fillTypes or {}) do
fillTypes[fillType] = true
end
end
local mixtures = foodSystem.getMixturesByAnimalTypeIndex ~= nil and foodSystem:getMixturesByAnimalTypeIndex(foodSpec.animalTypeIndex) or nil
for _, mixture in pairs(mixtures or {}) do
local fillType = type(mixture) == "table" and (mixture.fillType or mixture.fillTypeIndex) or mixture
if type(fillType) == "number" then
fillTypes[fillType] = true
end
end
return fillTypes
end
-- En stald kan MODTAGE foder, halm og vand — ikke sine egne outputs (mælk, gødning, gylle),
-- selv om placeable'n "understøtter" dem som lager. Uden foder-spec (ældre/mod-stalde)
-- spørges staldens egen understøttelse.
local function isFillTypeAccepted(station, husbandry, fillType)
if husbandry ~= nil and husbandry.getHusbandryIsFillTypeSupported ~= nil then
return husbandry:getHusbandryIsFillTypeSupported(fillType)
if husbandry ~= nil then
local foodFillTypes = getHusbandryFoodFillTypes(husbandry)
if foodFillTypes ~= nil then
if foodFillTypes[fillType] then
return true
end
local strawSpec, waterSpec = husbandry.spec_husbandryStraw, husbandry.spec_husbandryWater
local isStraw = strawSpec ~= nil and (strawSpec.fillType == nil or strawSpec.fillType == fillType)
and g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) == "STRAW"
local isWater = waterSpec ~= nil and waterSpec.automaticWaterSupply ~= true
and (waterSpec.fillType == fillType or g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) == "WATER")
return isStraw or isWater
end
if husbandry.getHusbandryIsFillTypeSupported ~= nil then
return husbandry:getHusbandryIsFillTypeSupported(fillType)
end
end
return station.getIsFillTypeSupported == nil or station:getIsFillTypeSupported(fillType)
end
-- Foder deler ét trug: varens eget niveau + trugets fri plads = den kapacitet varen kan nå.
local function getHusbandryFoodLevelAndCapacity(husbandry, fillType)
local foodSpec = husbandry.spec_husbandryFood
local total = 0
for _, level in pairs(foodSpec.fillLevels or {}) do
total = total + (level or 0)
end
local level = (foodSpec.fillLevels or {})[fillType] or 0
local freeSpace = math.max(0, (foodSpec.capacity or 0) - total)
return level, level + freeSpace
end
-- Niveau + kapacitet for én vare i aflæsningsmålet; nil hvis målet ikke tager varen.
function ADSmartPickup.getStationLevelAndCapacity(station, fillType, farmId)
local husbandry = getHusbandry(station)
@@ -382,6 +437,10 @@ function ADSmartPickup.getStationLevelAndCapacity(station, fillType, farmId)
return nil
end
if husbandry ~= nil then
local foodFillTypes = getHusbandryFoodFillTypes(husbandry)
if foodFillTypes ~= nil and foodFillTypes[fillType] then
return getHusbandryFoodLevelAndCapacity(husbandry, fillType)
end
local level = husbandry:getHusbandryFillLevel(fillType) or 0
return level, husbandry:getHusbandryCapacity(fillType) or level
end
@@ -676,48 +735,31 @@ local function restoreStoppedVehicles()
end
end
-- Indsætter fanen i ESC-menuen foran Statistik/Priser (mønster fra FS25_FarmOperationsDashboard).
local function insertInGameMenuPage(frame, pageName, iconFile, iconUVs, position, predicate)
-- Tilføjer fanen SIDST i ESC-menuen (mønster fra FS25_FarmManager/Courseplay). Siden skal
-- først være barn af PagingElement, ellers mangler den i idPageHash og rebuildTabList
-- fejler. Omrokering af siderne forskyder fane↔side-koblingen (sidebjælkens markering
-- hoppede), så positionen er den samme overalt: efter de eksisterende sider.
local function insertInGameMenuPage(frame, pageName, iconFile, iconUVs, predicate)
local inGameMenu = g_gui ~= nil and g_gui.screenControllers ~= nil and g_gui.screenControllers[InGameMenu] or nil
if inGameMenu == nil or inGameMenu.pagingElement == nil then
if inGameMenu == nil or inGameMenu.pagingElement == nil or inGameMenu.pageFrames == nil then
return false
end
local insertAt = position
for i = 1, #inGameMenu.pagingElement.elements do
local child = inGameMenu.pagingElement.elements[i]
if child == inGameMenu.pageStatistics or child == inGameMenu.pagePrices then
insertAt = i
break
end
end
local position = #inGameMenu.pageFrames + 1
if inGameMenu.controlIDs ~= nil then
inGameMenu.controlIDs[pageName] = nil
end
if inGameMenu.exposeControlsAsFields ~= nil then
inGameMenu:exposeControlsAsFields({pageName})
end
inGameMenu[pageName] = frame
inGameMenu.pagingElement:addElement(frame)
if inGameMenu.exposeControlsAsFields ~= nil then
inGameMenu:exposeControlsAsFields(pageName)
end
for _, list in ipairs({inGameMenu.pagingElement.elements, inGameMenu.pageFrames}) do
for i = 1, #list do
if list[i] == frame then
table.remove(list, i)
table.insert(list, insertAt, frame)
break
end
end
end
for i = 1, #inGameMenu.pagingElement.pages do
if inGameMenu.pagingElement.pages[i].element == frame then
local page = table.remove(inGameMenu.pagingElement.pages, i)
table.insert(inGameMenu.pagingElement.pages, insertAt, page)
break
end
end
inGameMenu.pagingElement:updateAbsolutePosition()
inGameMenu.pagingElement:updatePageMapping()
inGameMenu:registerPage(frame, position, predicate)
inGameMenu:addPageTab(frame, iconFile, iconUVs)
if frame.updateAbsolutePosition ~= nil then
frame:updateAbsolutePosition()
end
inGameMenu:rebuildTabList()
return true
end
@@ -733,7 +775,7 @@ local function loadGui()
-- icon.dds er 512×512. Uden referencestørrelsen normaliserer getUVs mod 1024×1024,
-- og fanen ville kun vise ikonets øverste venstre fjerdedel.
local iconUVs = GuiUtils.getUVs({0, 0, 512, 512}, {512, 512})
if not insertInGameMenuPage(frame, "smartPickupFrame", iconFile, iconUVs, 2, function() return g_currentMission ~= nil end) then
if not insertInGameMenuPage(frame, "smartPickupFrame", iconFile, iconUVs, function() return g_currentMission ~= nil end) then
Logging.warning(ADSmartPickup.LOG_PREFIX .. "kunne ikke indsætte fanen i ESC-menuen")
return
end
+3 -1
View File
@@ -340,7 +340,9 @@ function SmartPickupFrame:fillPoolRows(adEnv)
local occupied = {}
for _, claim in ipairs(ADUnloadWait.getClaims()) do
occupied[claim.marker.group] = occupied[claim.marker.group] or {}
table.insert(occupied[claim.marker.group], ADRunsController.getVehicleLabel(adEnv, claim.vehicle))
-- kun løbenummeret ("#31") — fulde navne klippes af i rækken
local label = ADRunsController.getVehicleLabel(adEnv, claim.vehicle)
table.insert(occupied[claim.marker.group], string.match(label, "%(#(%d+)%)") and ("#" .. string.match(label, "%(#(%d+)%)")) or label)
end
for _, pool in ipairs(ADRunsController.getWaitPools(adEnv)) do
local names = occupied[pool.group] or {}
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107">
<author>masterdraco</author>
<version>1.9.1.0</version>
<version>1.9.2.0</version>
<title>
<en>AD Smart Pickup</en>
</title>