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 ----
|
-- ---- 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)
|
function ADRunsController.getTargetMarkers(adEnv, farmId)
|
||||||
local result = {}
|
local entries = {}
|
||||||
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
|
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
|
||||||
if ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId) ~= nil then
|
local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId)
|
||||||
table.insert(result, marker)
|
local kind = station ~= nil and getTargetKind(station) or nil
|
||||||
|
if kind ~= nil then
|
||||||
|
table.insert(entries, {marker = marker, kind = kind})
|
||||||
end
|
end
|
||||||
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
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -368,13 +368,68 @@ local function getHusbandry(station)
|
|||||||
return nil
|
return nil
|
||||||
end
|
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)
|
local function isFillTypeAccepted(station, husbandry, fillType)
|
||||||
if husbandry ~= nil and husbandry.getHusbandryIsFillTypeSupported ~= nil then
|
if husbandry ~= nil then
|
||||||
return husbandry:getHusbandryIsFillTypeSupported(fillType)
|
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
|
end
|
||||||
return station.getIsFillTypeSupported == nil or station:getIsFillTypeSupported(fillType)
|
return station.getIsFillTypeSupported == nil or station:getIsFillTypeSupported(fillType)
|
||||||
end
|
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.
|
-- Niveau + kapacitet for én vare i aflæsningsmålet; nil hvis målet ikke tager varen.
|
||||||
function ADSmartPickup.getStationLevelAndCapacity(station, fillType, farmId)
|
function ADSmartPickup.getStationLevelAndCapacity(station, fillType, farmId)
|
||||||
local husbandry = getHusbandry(station)
|
local husbandry = getHusbandry(station)
|
||||||
@@ -382,6 +437,10 @@ function ADSmartPickup.getStationLevelAndCapacity(station, fillType, farmId)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
if husbandry ~= nil then
|
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
|
local level = husbandry:getHusbandryFillLevel(fillType) or 0
|
||||||
return level, husbandry:getHusbandryCapacity(fillType) or level
|
return level, husbandry:getHusbandryCapacity(fillType) or level
|
||||||
end
|
end
|
||||||
@@ -676,48 +735,31 @@ local function restoreStoppedVehicles()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Indsætter fanen i ESC-menuen foran Statistik/Priser (mønster fra FS25_FarmOperationsDashboard).
|
-- Tilføjer fanen SIDST i ESC-menuen (mønster fra FS25_FarmManager/Courseplay). Siden skal
|
||||||
local function insertInGameMenuPage(frame, pageName, iconFile, iconUVs, position, predicate)
|
-- 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
|
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
|
return false
|
||||||
end
|
end
|
||||||
local insertAt = position
|
local position = #inGameMenu.pageFrames + 1
|
||||||
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
|
|
||||||
if inGameMenu.controlIDs ~= nil then
|
if inGameMenu.controlIDs ~= nil then
|
||||||
inGameMenu.controlIDs[pageName] = nil
|
inGameMenu.controlIDs[pageName] = nil
|
||||||
end
|
end
|
||||||
|
if inGameMenu.exposeControlsAsFields ~= nil then
|
||||||
|
inGameMenu:exposeControlsAsFields({pageName})
|
||||||
|
end
|
||||||
inGameMenu[pageName] = frame
|
inGameMenu[pageName] = frame
|
||||||
inGameMenu.pagingElement:addElement(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:updateAbsolutePosition()
|
||||||
inGameMenu.pagingElement:updatePageMapping()
|
inGameMenu.pagingElement:updatePageMapping()
|
||||||
inGameMenu:registerPage(frame, position, predicate)
|
inGameMenu:registerPage(frame, position, predicate)
|
||||||
inGameMenu:addPageTab(frame, iconFile, iconUVs)
|
inGameMenu:addPageTab(frame, iconFile, iconUVs)
|
||||||
|
if frame.updateAbsolutePosition ~= nil then
|
||||||
|
frame:updateAbsolutePosition()
|
||||||
|
end
|
||||||
inGameMenu:rebuildTabList()
|
inGameMenu:rebuildTabList()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -733,7 +775,7 @@ local function loadGui()
|
|||||||
-- icon.dds er 512×512. Uden referencestørrelsen normaliserer getUVs mod 1024×1024,
|
-- icon.dds er 512×512. Uden referencestørrelsen normaliserer getUVs mod 1024×1024,
|
||||||
-- og fanen ville kun vise ikonets øverste venstre fjerdedel.
|
-- og fanen ville kun vise ikonets øverste venstre fjerdedel.
|
||||||
local iconUVs = GuiUtils.getUVs({0, 0, 512, 512}, {512, 512})
|
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")
|
Logging.warning(ADSmartPickup.LOG_PREFIX .. "kunne ikke indsætte fanen i ESC-menuen")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -340,7 +340,9 @@ function SmartPickupFrame:fillPoolRows(adEnv)
|
|||||||
local occupied = {}
|
local occupied = {}
|
||||||
for _, claim in ipairs(ADUnloadWait.getClaims()) do
|
for _, claim in ipairs(ADUnloadWait.getClaims()) do
|
||||||
occupied[claim.marker.group] = occupied[claim.marker.group] or {}
|
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
|
end
|
||||||
for _, pool in ipairs(ADRunsController.getWaitPools(adEnv)) do
|
for _, pool in ipairs(ADRunsController.getWaitPools(adEnv)) do
|
||||||
local names = occupied[pool.group] or {}
|
local names = occupied[pool.group] or {}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
<modDesc descVersion="107">
|
<modDesc descVersion="107">
|
||||||
<author>masterdraco</author>
|
<author>masterdraco</author>
|
||||||
<version>1.9.1.0</version>
|
<version>1.9.2.0</version>
|
||||||
<title>
|
<title>
|
||||||
<en>AD Smart Pickup</en>
|
<en>AD Smart Pickup</en>
|
||||||
</title>
|
</title>
|
||||||
|
|||||||
@@ -215,10 +215,16 @@ fastracA.ad.stateModule.active = true
|
|||||||
ADRunsController.startRun(adEnv, cow.id)
|
ADRunsController.startRun(adEnv, cow.id)
|
||||||
check("C7 ikke dobbelt-startet", fastracA.started, 1)
|
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)
|
local targets = ADRunsController.getTargetMarkers(adEnv, 1)
|
||||||
check("C8 kun markører med aflæsningsstation", #targets, 1)
|
check("C8 kun stalde og fabrikker (ikke siloen)", #targets, 3)
|
||||||
check("C8 navn", targets[1].name, "Cow 1 Food")
|
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)
|
local pools = ADRunsController.getWaitPools(adEnv)
|
||||||
check("C8 to puljer (F91 er ikke en Wait-mappe)", #pools, 2)
|
check("C8 to puljer (F91 er ikke en Wait-mappe)", #pools, 2)
|
||||||
check("C8 sorteret", pools[1].group, "Cow Wait")
|
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 niveau i målet", eLevel, 40000)
|
||||||
check("E3 kapacitet i målet", eCapacity, 100000)
|
check("E3 kapacitet i målet", eCapacity, 100000)
|
||||||
check("E3 vare målet ikke tager -> nil", ADSmartPickup.getStationLevelAndCapacity(unloadStations[1], MILK, 1), nil)
|
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)
|
check("E3 farmId", ADSmartPickup.getFarmId(eDriver), 1)
|
||||||
|
|
||||||
-- L6: samme valg logges kun én gang
|
-- L6: samme valg logges kun én gang
|
||||||
|
|||||||
Reference in New Issue
Block a user