fix(stald): foder-trigger søges i spec_husbandryFood (feedingTrough findes ikke i FS25) når stationen er uden noder — hønsehus; diagnose-log af feltnavne (v1.19.4.0)

This commit is contained in:
2026-09-24 19:47:54 +02:00
parent b86f420a41
commit ff71fb4f43
8 changed files with 78 additions and 19 deletions
+25 -5
View File
@@ -72,6 +72,22 @@ local function getKind(placeable)
return nil return nil
end end
local logHusbandryFoodOnce
ADBuildings.findTriggerNodes = function(root, maxDepth) return ADSupplyPlanner.findTriggerNodes(root, maxDepth) end
-- Diagnose én gang pr. stald: hvilke felter foderdataene har, når ingen trigger-node blev fundet.
local loggedFood = setmetatable({}, {__mode = "k"})
logHusbandryFoodOnce = function(placeable)
if loggedFood[placeable] then return end
loggedFood[placeable] = true
local keys = {}
for key, value in pairs(placeable.spec_husbandryFood or {}) do table.insert(keys, tostring(key) .. ":" .. type(value)) end
table.sort(keys)
if Logging ~= nil and Logging.info ~= nil then
Logging.info(ADBuildings.LOG_PREFIX .. "stald '%s' har ingen aflæsnings-trigger; spec_husbandryFood-felter: %s", getName(placeable, "?"), table.concat(keys, ", "))
end
end
-- Trigger-noder pr. bygning: læsse (loadTriggers.triggerNode, pallespawner, objektlager) og -- Trigger-noder pr. bygning: læsse (loadTriggers.triggerNode, pallespawner, objektlager) og
-- aflæsning (unloadTriggers exactFillRootNode/triggerNode/aiNode). -- aflæsning (unloadTriggers exactFillRootNode/triggerNode/aiNode).
-- loadGroups: én gruppe noder pr. læssepunkt (mælketank, gyllebeholder ...), så hvert punkt får sin -- loadGroups: én gruppe noder pr. læssepunkt (mælketank, gyllebeholder ...), så hvert punkt får sin
@@ -104,11 +120,15 @@ local function collectNodes(placeable, loadStations, unloadStations)
end end
if #nodes > 0 then table.insert(loadGroups, nodes) end if #nodes > 0 then table.insert(loadGroups, nodes) end
end end
-- staldens foderkrybbe (hønsehus: kun krybben, ingen trigger i aflæsningsstationen) -- stald uden aflæsningsnoder i stationen (hønsehus: kun foder-triggeren) -> søg i staldens foderdata
local food = placeable.spec_husbandryFood if #unloadNodes == 0 and placeable.getHusbandryFillLevel ~= nil then
local trough = food ~= nil and food.feedingTrough or nil for _, node in ipairs(ADSupplyPlanner.findTriggerNodes(placeable.spec_husbandryFood)) do
local troughNode = trough ~= nil and (trough.exactFillRootNode or trough.triggerNode) or nil table.insert(unloadNodes, node)
if troughNode ~= nil then table.insert(unloadNodes, troughNode) end end
if #unloadNodes == 0 then
logHusbandryFoodOnce(placeable)
end
end
-- stald med egne pallespawnere (hønsehus: æg, fårestald: uld) — én læssegruppe pr. spawner -- stald med egne pallespawnere (hønsehus: æg, fårestald: uld) — én læssegruppe pr. spawner
local husbandryPallets = placeable.spec_husbandryPallets local husbandryPallets = placeable.spec_husbandryPallets
local seenSpawners = {} local seenSpawners = {}
+12 -9
View File
@@ -167,9 +167,10 @@ local function getLoadStationAtMarker(adEnv, wayPoint, farmId)
return getClosestStation(adEnv, g_currentMission.storageSystem:getLoadingStations(), "loadTriggers", LOAD_TRIGGER_NODE_FIELDS, wayPoint, farmId) return getClosestStation(adEnv, g_currentMission.storageSystem:getLoadingStations(), "loadTriggers", LOAD_TRIGGER_NODE_FIELDS, wayPoint, farmId)
end end
-- Staldes foderkrybbe (spec_husbandryFood.feedingTrough, samme tippe-trigger som AutoDrive bruger) står -- En stalds foder-trigger står ikke altid i aflæsningsstationens unloadTriggers (hønsehuset har kun
-- ikke altid i aflæsningsstationens unloadTriggers — hønsehuset har KUN krybben. Opslaget får derfor en -- foder-triggeren under spec_husbandryFood; feltstien varierer). Står stationen uden trigger-noder, søges
-- proxy pr. krybbe der peger på staldens station (eller en minimal station). Caches i UNLOAD_CACHE_MS. -- foderdataene, og opslaget får en proxy med de fundne noder, der peger på staldens station (eller en
-- minimal station). Caches i UNLOAD_CACHE_MS.
ADSmartPickup.UNLOAD_CACHE_MS = 1000 ADSmartPickup.UNLOAD_CACHE_MS = 1000
local unloadCache = {list = nil, time = -math.huge} local unloadCache = {list = nil, time = -math.huge}
@@ -191,16 +192,18 @@ local function getUnloadCandidates()
end end
local placeables = g_currentMission.placeableSystem ~= nil and g_currentMission.placeableSystem.placeables or {} local placeables = g_currentMission.placeableSystem ~= nil and g_currentMission.placeableSystem.placeables or {}
for _, placeable in pairs(placeables) do for _, placeable in pairs(placeables) do
local food = placeable.spec_husbandryFood local ownStation = byPlaceable[placeable]
local trough = food ~= nil and food.feedingTrough or nil local ownHasNodes = ownStation ~= nil and ownStation.unloadTriggers ~= nil and #ADSupplyPlanner.findTriggerNodes(ownStation.unloadTriggers, 1) > 0
local node = trough ~= nil and (trough.exactFillRootNode or trough.triggerNode) or nil local foodNodes = (placeable.getHusbandryFillLevel ~= nil and not ownHasNodes) and ADSupplyPlanner.findTriggerNodes(placeable.spec_husbandryFood) or {}
if node ~= nil then if #foodNodes > 0 then
local station = byPlaceable[placeable] or { local triggers = {}
for _, foodNode in ipairs(foodNodes) do table.insert(triggers, {exactFillRootNode = foodNode}) end
local station = ownStation or {
owningPlaceable = placeable, owningPlaceable = placeable,
-- spillets adgangstjek kalder getOwnerFarmId på stationen -- spillets adgangstjek kalder getOwnerFarmId på stationen
getOwnerFarmId = function() return placeable.getOwnerFarmId ~= nil and placeable:getOwnerFarmId() or placeable.ownerFarmId end, getOwnerFarmId = function() return placeable.getOwnerFarmId ~= nil and placeable:getOwnerFarmId() or placeable.ownerFarmId end,
} }
table.insert(list, setmetatable({unloadTriggers = {{exactFillRootNode = node}}}, {__index = station})) table.insert(list, setmetatable({unloadTriggers = triggers}, {__index = station}))
end end
end end
unloadCache.list, unloadCache.time = list, now or -math.huge unloadCache.list, unloadCache.time = list, now or -math.huge
+27
View File
@@ -296,3 +296,30 @@ function ADSupplyPlanner.resolveIngredients(state, selected)
end end
return nil return nil
end end
-- Trigger-noder (exactFillRootNode/triggerNode) i indlejrede tabeller, fx en stalds foderdata hvor feltstien
-- varierer mellem FS-versioner og mods (hønsehuset har kun foder-triggeren, ikke i aflæsningsstationen).
-- Højst maxDepth niveauer (standard 3); løkker og placeable-referencer følges ikke.
local SKIP_KEYS = {owningPlaceable = true, placeable = true, owner = true, parent = true, vehicle = true, target = true, mission = true}
function ADSupplyPlanner.findTriggerNodes(root, maxDepth)
local nodes, seen = {}, {}
local function visit(value, depth)
if type(value) ~= "table" or seen[value] or depth > (maxDepth or 3) then
return
end
seen[value] = true
for _, field in ipairs({"exactFillRootNode", "triggerNode"}) do
local node = rawget(value, field)
if node ~= nil and type(node) ~= "boolean" then table.insert(nodes, node) end
end
for key, child in pairs(value) do
if type(child) == "table" and not SKIP_KEYS[key] then
visit(child, depth + 1)
end
end
end
visit(root, 0)
return nodes
end
+1 -1
View File
@@ -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.19.3.0</version> <version>1.19.4.0</version>
<title> <title>
<en>AD Smart Pickup</en> <en>AD Smart Pickup</en>
</title> </title>
+1 -1
View File
@@ -1,6 +1,6 @@
# AD Smart Pickup — brugermanual # AD Smart Pickup — brugermanual
Version 1.19.3 · Farming Simulator 25 · tillæg til AutoDrive Version 1.19.4 · Farming Simulator 25 · tillæg til AutoDrive
*English version: [USER_MANUAL.md](USER_MANUAL.md)* *English version: [USER_MANUAL.md](USER_MANUAL.md)*
+1 -1
View File
@@ -1,6 +1,6 @@
# AD Smart Pickup — user manual # AD Smart Pickup — user manual
Version 1.19.3 · Farming Simulator 25 · add-on for AutoDrive Version 1.19.4 · Farming Simulator 25 · add-on for AutoDrive
*Dansk version: [BRUGERMANUAL.md](BRUGERMANUAL.md)* *Dansk version: [BRUGERMANUAL.md](BRUGERMANUAL.md)*
+10 -1
View File
@@ -189,7 +189,7 @@ end
-- B-COOP: hønsehus — foder aflæsses i den ene ende, æg-paller spawnes i den anden (ingen læssestation) -- B-COOP: hønsehus — foder aflæsses i den ene ende, æg-paller spawnes i den anden (ingen læssestation)
do do
local coop = placeable("coop1", "Chicken Coop", 10000, 0, {getHusbandryFillLevel = function() return 0 end, local coop = placeable("coop1", "Chicken Coop", 10000, 0, {getHusbandryFillLevel = function() return 0 end,
spec_husbandryFood = {feedingTrough = {exactFillRootNode = {x = 9970, z = 0}}}, spec_husbandryFood = {triggers = {{someTrigger = {exactFillRootNode = {x = 9970, z = 0}}}}}, -- ukendt feltsti: søges
spec_husbandryPallets = {fillTypeIndexToPalletSpawner = {[99] = {spawnPlaces = {{startNode = {x = 10030, z = 0}}}}}}}) spec_husbandryPallets = {fillTypeIndexToPalletSpawner = {[99] = {spawnPlaces = {{startNode = {x = 10030, z = 0}}}}}}})
table.insert(unloadStations, {owningPlaceable = coop, unloadTriggers = {}}) -- som chickenBarnBig: tom station table.insert(unloadStations, {owningPlaceable = coop, unloadTriggers = {}}) -- som chickenBarnBig: tom station
addMarker(61, "Chicken Food", "Chicken", 9965, 0) addMarker(61, "Chicken Food", "Chicken", 9965, 0)
@@ -214,5 +214,14 @@ do
g_fillTypeManager = fmBefore g_fillTypeManager = fmBefore
end end
-- B-SCAN: søgning efter trigger-noder i indlejrede tabeller (dybde ≤ 3, ingen løkker)
do
local loop = {}
loop.self = loop
local nodes = ADBuildings.findTriggerNodes({a = {b = {exactFillRootNode = "n1"}}, c = {triggerNode = "n2"}, d = loop, e = {f = {g = {h = {exactFillRootNode = "for-dybt"}}}}})
table.sort(nodes)
check("B-SCAN finder n1 og n2, ikke for dybt", table.concat(nodes, ","), "n1,n2")
end
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1) os.exit(failures == 0 and 0 or 1)
+1 -1
View File
@@ -1263,7 +1263,7 @@ ADOutbound = nil
-- unloadTriggers; stationsopslaget ved markøren skal alligevel finde hønsehuset -- unloadTriggers; stationsopslaget ved markøren skal alligevel finde hønsehuset
do do
local coop = {getHusbandryFillLevel = function() return 0 end, getName = function() return "Chicken Coop" end, local coop = {getHusbandryFillLevel = function() return 0 end, getName = function() return "Chicken Coop" end,
spec_husbandryFood = {feedingTrough = {exactFillRootNode = 9901}}} spec_husbandryFood = {unloadTrigger = {exactFillRootNode = 9901}}}
nodePositions[9901] = {x = 20000, z = 3} nodePositions[9901] = {x = 20000, z = 3}
local coopStation = {owningPlaceable = coop, unloadTriggers = {}} local coopStation = {owningPlaceable = coop, unloadTriggers = {}}
table.insert(unloadStations, coopStation) table.insert(unloadStations, coopStation)