fix: markørens silo er den bag traktorens næse, ikke nærmeste trigger (v1.3.0.0)

I tætte silo-rækker står markøren ved NÆSTE silos rist (næsen stopper dér, vognen
holder et vogntog bagved). Nærmeste-trigger-koblingen ramte derfor nabosiloen og
forskød alle 40 markører én silo: roer i silo 2 blev til '1 Silo Storage'.
Koblingen bruger nu ankomstretningen fra forrige waypoint og vælger nærmeste
trigger bag næsen (højst 2 m foran); ellers nærmeste trigger som før.
Verificeret mod savegame: 40 markører -> 40 forskellige siloer, TMR Unload -> TMR.
This commit is contained in:
2026-09-21 16:00:53 +02:00
parent bcc245863e
commit e414c99b58
4 changed files with 76 additions and 21 deletions
+47 -18
View File
@@ -13,6 +13,9 @@ ADSmartPickup = {}
-- Markøren er dér hvor trækkerens næse stopper; læssetriggeren ligger et
-- vogntog bagved. Siloer tættere end dette regnes som "markørens silo".
ADSmartPickup.MAX_MARKER_TO_TRIGGER_DISTANCE = 40
-- I tætte silo-rækker ligger nabosiloens trigger FORAN næsen og er ofte nærmere
-- end markørens egen. Triggere mere end dette foran næsen hører til naboen.
ADSmartPickup.MAX_TRIGGER_AHEAD_OF_MARKER = 2
-- Under dette niveau regnes siloen som tom (undgår ture efter støv-rester).
ADSmartPickup.MIN_USEFUL_LITERS = 1
ADSmartPickup.LOG_PREFIX = "ADSmartPickup: "
@@ -68,41 +71,67 @@ local function getWantedFillTypes(driver)
return wanted
end
local function getDistanceToTriggers(triggers, nodeFields, x, z)
local closest = math.huge
-- Ankomstretning ved markøren (enhedsvektor) ud fra forrige waypoint, ellers nil.
local function getArrivalDirection(adEnv, wayPoint)
local previousId = wayPoint.incoming ~= nil and wayPoint.incoming[1] or nil
local previous = previousId ~= nil and adEnv.ADGraphManager:getWayPointById(previousId) or nil
if previous == nil then
return nil
end
local dx, dz = wayPoint.x - previous.x, wayPoint.z - previous.z
local length = math.sqrt(dx * dx + dz * dz)
if length < 0.01 then
return nil
end
return {x = dx / length, z = dz / length}
end
-- Nærmeste trigger-afstand for en station, samlet og blandt triggere BAG næsen.
local function getDistancesToTriggers(triggers, nodeFields, wayPoint, direction)
local closest, closestBehind = math.huge, math.huge
for _, trigger in pairs(triggers or {}) do
for _, field in ipairs(nodeFields) do
local node = trigger[field]
if node ~= nil and entityExists(node) then
local tx, _, tz = getWorldTranslation(node)
closest = math.min(closest, MathUtil.vector2Length(x - tx, z - tz))
local distance = MathUtil.vector2Length(wayPoint.x - tx, wayPoint.z - tz)
closest = math.min(closest, distance)
-- > 0: triggeren ligger bag næsen set i køreretningen
local behind = direction ~= nil and ((wayPoint.x - tx) * direction.x + (wayPoint.z - tz) * direction.z) or nil
if behind ~= nil and behind >= -ADSmartPickup.MAX_TRIGGER_AHEAD_OF_MARKER then
closestBehind = math.min(closestBehind, distance)
end
end
end
end
return closest
return closest, closestBehind
end
local function getClosestStation(candidateStations, triggersField, nodeFields, wayPoint, farmId)
local bestStation = nil
local bestDistance = ADSmartPickup.MAX_MARKER_TO_TRIGGER_DISTANCE
-- Markørens station: nærmeste trigger bag næsen; findes ingen (eller er
-- retningen ukendt), nærmeste trigger overhovedet.
local function getClosestStation(adEnv, candidateStations, triggersField, nodeFields, wayPoint, farmId)
local direction = getArrivalDirection(adEnv, wayPoint)
local best = {any = {distance = ADSmartPickup.MAX_MARKER_TO_TRIGGER_DISTANCE}, behind = {distance = ADSmartPickup.MAX_MARKER_TO_TRIGGER_DISTANCE}}
for _, station in pairs(candidateStations) do
if g_currentMission.accessHandler:canFarmAccess(farmId, station) then
local distance = getDistanceToTriggers(station[triggersField], nodeFields, wayPoint.x, wayPoint.z)
if distance < bestDistance then
bestDistance = distance
bestStation = station
local closest, closestBehind = getDistancesToTriggers(station[triggersField], nodeFields, wayPoint, direction)
if closest < best.any.distance then
best.any = {distance = closest, station = station}
end
if closestBehind < best.behind.distance then
best.behind = {distance = closestBehind, station = station}
end
end
end
return bestStation
return best.behind.station or best.any.station
end
local function getLoadStationAtMarker(wayPoint, farmId)
return getClosestStation(g_currentMission.storageSystem:getLoadingStations(), "loadTriggers", LOAD_TRIGGER_NODE_FIELDS, wayPoint, farmId)
local function getLoadStationAtMarker(adEnv, wayPoint, farmId)
return getClosestStation(adEnv, g_currentMission.storageSystem:getLoadingStations(), "loadTriggers", LOAD_TRIGGER_NODE_FIELDS, wayPoint, farmId)
end
local function getUnloadStationAtMarker(wayPoint, farmId)
return getClosestStation(g_currentMission.storageSystem:getUnloadingStations(), "unloadTriggers", UNLOAD_TRIGGER_NODE_FIELDS, wayPoint, farmId)
local function getUnloadStationAtMarker(adEnv, wayPoint, farmId)
return getClosestStation(adEnv, g_currentMission.storageSystem:getUnloadingStations(), "unloadTriggers", UNLOAD_TRIGGER_NODE_FIELDS, wayPoint, farmId)
end
-- Siloens EGET indhold. Udvidelses-siloer (isExtension) deler lager med naboer
@@ -143,7 +172,7 @@ local function collectMarkerStations(adEnv, candidateMarkers, farmId, excludedPl
local markerStations = {}
for _, marker in pairs(candidateMarkers) do
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
local station = wayPoint ~= nil and getLoadStationAtMarker(wayPoint, farmId) or nil
local station = wayPoint ~= nil and getLoadStationAtMarker(adEnv, wayPoint, farmId) or nil
local isExcluded = station ~= nil and excludedPlaceable ~= nil and station.owningPlaceable == excludedPlaceable
if station ~= nil and not isExcluded then
table.insert(markerStations, {marker = marker, station = station})
@@ -235,7 +264,7 @@ function ADSmartPickup.findSupplyPickup(adEnv, driver, ingredients)
return nil
end
local targetWayPoint = adEnv.ADGraphManager:getWayPointById(secondMarker.id)
local target = targetWayPoint ~= nil and getUnloadStationAtMarker(targetWayPoint, farmId) or nil
local target = targetWayPoint ~= nil and getUnloadStationAtMarker(adEnv, targetWayPoint, farmId) or nil
if target == nil then
return nil
end