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:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
@@ -215,10 +215,16 @@ fastracA.ad.stateModule.active = true
|
||||
ADRunsController.startRun(adEnv, cow.id)
|
||||
check("C7 ikke dobbelt-startet", fastracA.started, 1)
|
||||
|
||||
-- C8: mål-markører og Wait-puljer til dropdowns
|
||||
-- C8: mål-markører (kun stalde og fabrikker — siloer tager alt og er ikke mål; stalde først,
|
||||
-- så fabrikker, så navn) og Wait-puljer til dropdowns
|
||||
unloadAt[94].owningPlaceable = {getHusbandryFillLevel = function() return 0 end}
|
||||
addMarker(96, "8 Silo Storage", "Siloer", 100, 0); unloadAt[96] = {accepts = {[STRAW] = 1}, owningPlaceable = {spec_silo = {}}}
|
||||
addMarker(97, "TMR Unload", "Fabrication", 900, 0); unloadAt[97] = {accepts = {[STRAW] = 1}, owningPlaceable = {spec_productionPoint = {}}}
|
||||
addMarker(98, "Bull Food", "Cow Food", 5100, 0); unloadAt[98] = {accepts = {[STRAW] = 1}, owningPlaceable = {getHusbandryFillLevel = function() return 0 end}}
|
||||
local targets = ADRunsController.getTargetMarkers(adEnv, 1)
|
||||
check("C8 kun markører med aflæsningsstation", #targets, 1)
|
||||
check("C8 navn", targets[1].name, "Cow 1 Food")
|
||||
check("C8 kun stalde og fabrikker (ikke siloen)", #targets, 3)
|
||||
check("C8 stalde først, alfabetisk", targets[1].name .. "," .. targets[2].name, "Bull Food,Cow 1 Food")
|
||||
check("C8 fabrik sidst", targets[3].name, "TMR Unload")
|
||||
local pools = ADRunsController.getWaitPools(adEnv)
|
||||
check("C8 to puljer (F91 er ikke en Wait-mappe)", #pools, 2)
|
||||
check("C8 sorteret", pools[1].group, "Cow Wait")
|
||||
|
||||
@@ -840,6 +840,37 @@ local eLevel, eCapacity = ADSmartPickup.getStationLevelAndCapacity(unloadStation
|
||||
check("E3 niveau i målet", eLevel, 40000)
|
||||
check("E3 kapacitet i målet", eCapacity, 100000)
|
||||
check("E3 vare målet ikke tager -> nil", ADSmartPickup.getStationLevelAndCapacity(unloadStations[1], MILK, 1), nil)
|
||||
|
||||
-- E4: FS25-stald med foder-spec: foder læses fra spec_husbandryFood (fælles kapacitet),
|
||||
-- fodertyper fra animalFoodSystem, halm fra spec_husbandryStraw; outputs (mælk) tages ikke
|
||||
buildCowWorld()
|
||||
local foodLevels = {[TMR] = 10000, [HAY] = 5000}
|
||||
local fs25Barn = {
|
||||
getName = function() return "FS25-kostald" end,
|
||||
spec_husbandryFood = {fillLevels = foodLevels, capacity = 100000, animalTypeIndex = 7},
|
||||
spec_husbandryStraw = {fillLevel = 20000, capacity = 300000},
|
||||
-- staldens egen "understøtter" siger også ja til mælk (output) — må ikke blive et mål
|
||||
getHusbandryIsFillTypeSupported = function(_, fillType) return fillType == MILK or fillType == STRAW or fillType == TMR end,
|
||||
getHusbandryFillLevel = function(_, fillType) if fillType == STRAW then return 20000 end return 0 end,
|
||||
getHusbandryCapacity = function(_, fillType) if fillType == STRAW then return 300000 end return 0 end,
|
||||
}
|
||||
g_currentMission.animalFoodSystem = {
|
||||
getAnimalFood = function(_, animalTypeIndex) if animalTypeIndex == 7 then return {groups = {{fillTypes = {TMR}}, {fillTypes = {HAY, GRASS}}}} end end,
|
||||
getMixturesByAnimalTypeIndex = function() return {} end,
|
||||
}
|
||||
unloadStations[1].targetStorages = nil
|
||||
unloadStations[1].owningPlaceable = fs25Barn
|
||||
local tmrLevel, tmrCapacity = ADSmartPickup.getStationLevelAndCapacity(unloadStations[1], TMR, 1)
|
||||
check("E4 TMR-niveau fra foder-spec", tmrLevel, 10000)
|
||||
check("E4 TMR-kapacitet = eget + fælles fri plads", tmrCapacity, 10000 + (100000 - 15000))
|
||||
local grassLevel, grassCapacity = ADSmartPickup.getStationLevelAndCapacity(unloadStations[1], GRASS, 1)
|
||||
check("E4 græs (fodergruppe uden lager) niveau 0", grassLevel, 0)
|
||||
check("E4 græs kapacitet = fælles fri plads", grassCapacity, 85000)
|
||||
local strawLevel, strawCapacity = ADSmartPickup.getStationLevelAndCapacity(unloadStations[1], STRAW, 1)
|
||||
check("E4 halm via husbandry-opslag", strawLevel .. "/" .. strawCapacity, "20000/300000")
|
||||
check("E4 mælk (output) er ikke et mål", ADSmartPickup.getStationLevelAndCapacity(unloadStations[1], MILK, 1), nil)
|
||||
check("E4 sukkerroer (ikke foder) er ikke et mål", ADSmartPickup.getStationLevelAndCapacity(unloadStations[1], SUGARBEET, 1), nil)
|
||||
g_currentMission.animalFoodSystem = nil
|
||||
check("E3 farmId", ADSmartPickup.getFarmId(eDriver), 1)
|
||||
|
||||
-- L6: samme valg logges kun én gang
|
||||
|
||||
Reference in New Issue
Block a user