fix: stå og læs ved den valgte silo — AutoDrive kørte tom videre (v1.2.0.0)
Med rotateTargets + mapper afslutter AutoDrives LoadAtDestinationTask pålæsningen i det øjeblik markøren nås; traktoren kørte derfor lige igennem silo-markøren og tom til aflæsning. Når moden har valgt siloen, ses rotationen som slået fra for netop det køretøj under opgavens update, så AutoDrive står og læsser. Grebet slippes når kilden er tom eller AD stopper. Desuden: samme valg logges kun én gang, og loggen viser eget/nabo-lager.
This commit is contained in:
@@ -24,6 +24,10 @@ local isHooked = false
|
||||
-- køretøj -> {ingredients, narrowedTo}. AutoDrive roterer selv vare ved triggeren
|
||||
-- når flere er valgt, så valget indsnævres til én pr. tur; listen huskes her.
|
||||
local supplyState = setmetatable({}, {__mode = "k"})
|
||||
-- køretøj -> {station, fillTypes}: siloen moden sendte køretøjet til på denne tur.
|
||||
local activePickups = setmetatable({}, {__mode = "k"})
|
||||
-- køretøj -> senest loggede valg (AutoDrive spørger flere gange pr. start).
|
||||
local lastLogged = setmetatable({}, {__mode = "k"})
|
||||
|
||||
-- Cross-mod adgang: FS25-mods er sandboxede; AutoDrives globals ligger
|
||||
-- i den globale tabel FS25_AutoDrive (zip-navnet).
|
||||
@@ -155,7 +159,7 @@ local function findLeastFilled(markerStations, fillTypes, farmId)
|
||||
for _, entry in ipairs(markerStations) do
|
||||
local level, isOwn = getStationFillLevel(entry.station, fillTypes, farmId)
|
||||
if level >= ADSmartPickup.MIN_USEFUL_LITERS and level < best[isOwn].level then
|
||||
best[isOwn] = {level = level, marker = entry.marker}
|
||||
best[isOwn] = {level = level, marker = entry.marker, station = entry.station, isOwn = isOwn}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -168,6 +172,9 @@ local function findLeastFilled(markerStations, fillTypes, farmId)
|
||||
markerName = choice.marker.name,
|
||||
group = choice.marker.group,
|
||||
level = choice.level,
|
||||
station = choice.station,
|
||||
isOwn = choice.isOwn,
|
||||
fillTypes = fillTypes,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -243,6 +250,9 @@ function ADSmartPickup.findSupplyPickup(adEnv, driver, ingredients)
|
||||
markerName = choice.markerName,
|
||||
group = choice.group,
|
||||
level = choice.level,
|
||||
station = choice.station,
|
||||
isOwn = choice.isOwn,
|
||||
fillTypes = choice.fillTypes,
|
||||
fillType = need.fillType,
|
||||
need = need,
|
||||
}
|
||||
@@ -277,11 +287,63 @@ function ADSmartPickup.choosePickup(adEnv, driver)
|
||||
end
|
||||
|
||||
local function describeChoice(choice)
|
||||
local source = choice.isOwn and "eget lager" or "nabo-lager"
|
||||
if choice.fillType == nil then
|
||||
return string.format("%.0f l", choice.level)
|
||||
return string.format("%.0f l, %s", choice.level, source)
|
||||
end
|
||||
local fillTypeName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(choice.fillType) or tostring(choice.fillType)
|
||||
return string.format("%s: kilde %.0f l, målet har %.0f/%.0f l", tostring(fillTypeName), choice.level, choice.need.level, choice.need.capacity)
|
||||
return string.format("%s: kilde %.0f l, %s, målet har %.0f/%.0f l", tostring(fillTypeName), choice.level, source, choice.need.level, choice.need.capacity)
|
||||
end
|
||||
|
||||
local function logChoiceOnce(driver, choice)
|
||||
local message = string.format("'%s' -> %s (%s)", tostring(driver:getName()), tostring(choice.markerName), describeChoice(choice))
|
||||
if lastLogged[driver] ~= message then
|
||||
lastLogged[driver] = message
|
||||
Logging.info(ADSmartPickup.LOG_PREFIX .. "%s", message)
|
||||
end
|
||||
end
|
||||
|
||||
-- Sendte moden køretøjet til en silo der stadig har varen? Så skal AutoDrive
|
||||
-- stå og læsse dér; løber kilden tør, slippes grebet og turen fortsætter.
|
||||
function ADSmartPickup.shouldWaitForLoading(vehicle)
|
||||
local pickup = activePickups[vehicle]
|
||||
if pickup == nil then
|
||||
return false
|
||||
end
|
||||
local level = getStationFillLevel(pickup.station, pickup.fillTypes, getFarmId(vehicle))
|
||||
return level >= ADSmartPickup.MIN_USEFUL_LITERS
|
||||
end
|
||||
|
||||
-- Med "Rotér mål" + mapper afslutter AutoDrive pålæsningen i det øjeblik markøren
|
||||
-- nås (LoadAtDestinationTask: rotation = "prøv næste silo", aldrig vente). Moden
|
||||
-- har valgt en silo der HAR varen, så under opgavens update ser AutoDrive
|
||||
-- rotationen som slået fra for netop det køretøj -> den står og læsser som normalt.
|
||||
local function installLoadWaitHook(adEnv)
|
||||
local task, autoDrive = adEnv.LoadAtDestinationTask, adEnv.AutoDrive
|
||||
if task == nil or task.update == nil or autoDrive == nil or autoDrive.getSetting == nil then
|
||||
Logging.warning(ADSmartPickup.LOG_PREFIX .. "kunne ikke koble på pålæsningsopgaven; traktoren venter ikke ved siloen")
|
||||
return
|
||||
end
|
||||
|
||||
local originalGetSetting, originalUpdate = autoDrive.getSetting, task.update
|
||||
local waitingVehicle = nil
|
||||
|
||||
autoDrive.getSetting = function(settingName, vehicle)
|
||||
if waitingVehicle ~= nil and vehicle == waitingVehicle and settingName == "rotateTargets" then
|
||||
return autoDrive.RT_NONE
|
||||
end
|
||||
return originalGetSetting(settingName, vehicle)
|
||||
end
|
||||
|
||||
task.update = function(self, dt)
|
||||
local ok, shouldWait = pcall(ADSmartPickup.shouldWaitForLoading, self.vehicle)
|
||||
waitingVehicle = ok and shouldWait and self.vehicle or nil
|
||||
local updateOk, err = pcall(originalUpdate, self, dt)
|
||||
waitingVehicle = nil
|
||||
if not updateOk then
|
||||
error(err, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function installHook(adEnv)
|
||||
@@ -292,27 +354,39 @@ local function installHook(adEnv)
|
||||
local ok, choice = pcall(ADSmartPickup.choosePickup, adEnv, driver)
|
||||
if not ok then
|
||||
Logging.warning(ADSmartPickup.LOG_PREFIX .. "fejl i silo-opslag, bruger AutoDrives rotation: %s", tostring(choice))
|
||||
activePickups[driver] = nil
|
||||
return originalGetNextPickup(self, driver, forcedSkip)
|
||||
end
|
||||
if choice == nil then
|
||||
activePickups[driver] = nil
|
||||
return originalGetNextPickup(self, driver, forcedSkip)
|
||||
end
|
||||
activePickups[driver] = {station = choice.station, fillTypes = choice.fillTypes}
|
||||
|
||||
-- hold AutoDrives egen rotations-tilstand konsistent med vores valg
|
||||
self.pickups[choice.group] = self.pickups[choice.group] or {}
|
||||
self.pickups[choice.group].lastTarget = choice.markerIndex
|
||||
self.pickups[choice.group].lastVehicle = driver
|
||||
|
||||
Logging.info(ADSmartPickup.LOG_PREFIX .. "'%s' -> %s (%s)", tostring(driver:getName()), tostring(choice.markerName), describeChoice(choice))
|
||||
logChoiceOnce(driver, choice)
|
||||
return choice.markerIndex
|
||||
end
|
||||
|
||||
installLoadWaitHook(adEnv)
|
||||
|
||||
Logging.info(ADSmartPickup.LOG_PREFIX .. "aktiv (mindst fyldte silo med varen; flere valgte varer = behovsstyret forsyning)")
|
||||
end
|
||||
|
||||
-- Når AutoDrive stopper, får køretøjet hele ingredienslisten tilbage i varevalget
|
||||
-- (AutoDrive gemmer valget i savegame, så listen overlever også en genindlæsning).
|
||||
local function restoreStoppedVehicles()
|
||||
-- en standset traktor må ikke tage "stå og læs"-grebet med over i næste opgave
|
||||
for vehicle in pairs(activePickups) do
|
||||
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
|
||||
if stateModule == nil or stateModule.isActive == nil or not stateModule:isActive() then
|
||||
activePickups[vehicle] = nil
|
||||
end
|
||||
end
|
||||
for vehicle, state in pairs(supplyState) do
|
||||
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
|
||||
if stateModule == nil or not stateModule:isActive() then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.1.0.0</version>
|
||||
<version>1.2.0.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
|
||||
Reference in New Issue
Block a user