fix(bygninger): pallespawnere viger for aflæsningen når begge vil have samme markør og aflæsningen står tættere — fårestaldens foderindkast fik 'Sheep Milk' som mål; gælder alle bygningstyper, rigtige læssetriggere beholder forrang (v1.36.5.0)

This commit is contained in:
2026-09-27 13:31:22 +02:00
parent 4ae268376d
commit a626fcdd95
3 changed files with 63 additions and 4 deletions
+48 -3
View File
@@ -119,7 +119,10 @@ local function collectNodes(placeable, loadStations, unloadStations)
for _, place in ipairs(spawner.spawnPlaces or {}) do for _, place in ipairs(spawner.spawnPlaces or {}) do
if place.startNode ~= nil then table.insert(nodes, place.startNode) end if place.startNode ~= nil then table.insert(nodes, place.startNode) end
end end
if #nodes > 0 then table.insert(loadGroups, nodes) end if #nodes > 0 then
nodes.isSpawner = true
table.insert(loadGroups, nodes)
end
end end
-- stald uden aflæsningsnoder i stationen (hønsehus: kun foder-triggeren) -> søg i staldens foderdata -- stald uden aflæsningsnoder i stationen (hønsehus: kun foder-triggeren) -> søg i staldens foderdata
if #unloadNodes == 0 and placeable.getHusbandryFillLevel ~= nil then if #unloadNodes == 0 and placeable.getHusbandryFillLevel ~= nil then
@@ -140,7 +143,10 @@ local function collectNodes(placeable, loadStations, unloadStations)
for _, place in ipairs(palletSpawner.spawnPlaces or {}) do for _, place in ipairs(palletSpawner.spawnPlaces or {}) do
if place.startNode ~= nil then table.insert(nodes, place.startNode) end if place.startNode ~= nil then table.insert(nodes, place.startNode) end
end end
if #nodes > 0 then table.insert(loadGroups, nodes) end if #nodes > 0 then
nodes.isSpawner = true
table.insert(loadGroups, nodes)
end
end end
end end
if placeable.spec_objectStorage ~= nil and placeable.rootNode ~= nil then if placeable.spec_objectStorage ~= nil and placeable.rootNode ~= nil then
@@ -219,6 +225,44 @@ end
-- Aflæsningsmarkør: nærmeste ikke-Wait-markør ≤ MAX_MARKER_DISTANCE til aflæsningsnoderne — men ikke -- Aflæsningsmarkør: nærmeste ikke-Wait-markør ≤ MAX_MARKER_DISTANCE til aflæsningsnoderne — men ikke
-- bygningens egne LÆSSEmarkører, når der findes en anden (Sugarbeet Crusher: pickup står tættere på -- bygningens egne LÆSSEmarkører, når der findes en anden (Sugarbeet Crusher: pickup står tættere på
-- aflæsningstriggeren end drop). Kun én fælles markør (AIO Load / Unload) bruges til begge. -- aflæsningstriggeren end drop). Kun én fælles markør (AIO Load / Unload) bruges til begge.
-- Alle ikke-Wait-markører ≤ MAX_MARKER_DISTANCE til nodes, nærmeste først: {{id, name, distance}}.
local function markerCandidates(adEnv, nodes)
local positions, found = {}, {}
for _, node in ipairs(nodes) do
local x, z = getNodePosition(node)
if x ~= nil then table.insert(positions, {x = x, z = z}) end
end
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
local wayPoint = not ADSupplyPlanner.isWaitMarker(marker) and adEnv.ADGraphManager:getWayPointById(marker.id) or nil
if wayPoint ~= nil then
local nearest = nil
for _, position in ipairs(positions) do
local distance = math.sqrt((wayPoint.x - position.x) ^ 2 + (wayPoint.z - position.z) ^ 2)
if nearest == nil or distance < nearest then nearest = distance end
end
if nearest ~= nil and nearest < ADBuildings.MAX_MARKER_DISTANCE then
table.insert(found, {id = marker.id, name = tostring(marker.name), distance = nearest})
end
end
end
table.sort(found, function(a, b) return a.distance < b.distance end)
return found
end
-- Læssemarkør for én læssegruppe. En pallespawner (upræcist startpunkt) viger for aflæsningen, når begge vil
-- have samme markør og aflæsningen står tættere — så tager den sin næstnærmeste. Rigtige læssetriggere beholder
-- markøren (Sugarbeet Crusher: pickup står tættere på aflæsningstriggeren end drop). Gælder alle bygningstyper.
-- (in-game 27/9 fårestald: spawner 9 m fra "Sheep Food", foderindkast 5 m -> Goat Food fik "Sheep Milk")
function ADBuildings.pickLoadMarker(candidates, unloadBest, yieldsToUnload)
for _, candidate in ipairs(candidates or {}) do
local isUnloads = yieldsToUnload and unloadBest ~= nil and candidate.id == unloadBest.id and unloadBest.distance < candidate.distance
if not isUnloads then
return {id = candidate.id, name = candidate.name, distance = math.floor(candidate.distance + 0.5)}
end
end
return nil
end
-- Diagnose (én gang pr. stald pr. session): hvilke markører ligger nærmest læsse- og aflæsningspunkterne. -- Diagnose (én gang pr. stald pr. session): hvilke markører ligger nærmest læsse- og aflæsningspunkterne.
-- (in-game 27/9: Goat Food fik "Sheep Milk"-markørerne som mål og Goat Milk Pickup "Sheep Food" som kilde) -- (in-game 27/9: Goat Food fik "Sheep Milk"-markørerne som mål og Goat Milk Pickup "Sheep Food" som kilde)
local diagnosed = {} local diagnosed = {}
@@ -371,8 +415,9 @@ local function build(adEnv, farmId)
local marker = siloLoadMarker(adEnv, farmId, placeable, loadStations) local marker = siloLoadMarker(adEnv, farmId, placeable, loadStations)
if marker ~= nil then table.insert(loadMarkers, marker) end if marker ~= nil then table.insert(loadMarkers, marker) end
else else
local unloadBest = markerCandidates(adEnv, unloadNodes)[1]
for _, nodes in ipairs(loadGroups) do for _, nodes in ipairs(loadGroups) do
local marker = nearestMarker(adEnv, nodes) local marker = ADBuildings.pickLoadMarker(markerCandidates(adEnv, nodes), unloadBest, nodes.isSpawner == true)
if marker ~= nil and not seen[marker.id] then if marker ~= nil and not seen[marker.id] then
seen[marker.id] = true seen[marker.id] = true
table.insert(loadMarkers, marker) table.insert(loadMarkers, marker)
+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.36.4.0</version> <version>1.36.5.0</version>
<title> <title>
<en>AD Smart Pickup</en> <en>AD Smart Pickup</en>
</title> </title>
+14
View File
@@ -234,5 +234,19 @@ do
check("B-SHED aflæsning = nærmeste (Unload)", byShed.shedX.unloadMarker and byShed.shedX.unloadMarker.id, 71) check("B-SHED aflæsning = nærmeste (Unload)", byShed.shedX.unloadMarker and byShed.shedX.unloadMarker.id, 71)
end end
-- pickLoadMarker: en pallespawner viger for aflæsningen, når begge vil have samme markør og aflæsningen står
-- tættere (in-game 27/9 fårestald: spawner 9 m fra "Sheep Food", foderindkast 5 m -> Goat Food fik "Sheep Milk")
do
local food, milk = {id = 1, name = "Sheep Food 1", distance = 9}, {id = 2, name = "Sheep Milk 1", distance = 13}
local unloadBest = {id = 1, name = "Sheep Food 1", distance = 5}
check("PL spawner viger for tættere aflæsning", ADBuildings.pickLoadMarker({food, milk}, unloadBest, true).name, "Sheep Milk 1")
check("PL rigtig læssetrigger beholder markøren (Sugarbeet Crusher)", ADBuildings.pickLoadMarker({food, milk}, unloadBest, false).name, "Sheep Food 1")
check("PL spawner tættest selv -> beholder", ADBuildings.pickLoadMarker({food, milk}, {id = 1, name = "Sheep Food 1", distance = 12}, true).name, "Sheep Food 1")
check("PL ingen konflikt", ADBuildings.pickLoadMarker({milk}, unloadBest, true).name, "Sheep Milk 1")
check("PL eneste kandidat er aflæsningens -> ingen læssemarkør", ADBuildings.pickLoadMarker({food}, unloadBest, true), nil)
check("PL ingen kandidater", ADBuildings.pickLoadMarker({}, unloadBest, true), nil)
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)