fix: læs lager direkte fra produktionspunktet når targetStorages mangler (v1.1.0.0)

Genskabt efter disk-crash 2026-09-21: det oprindelige commit (d38366e) gik tabt
som tomt objekt; indholdet er gendannet fra arbejdskopien. README udvidet med
behovsstyret forsyning, test S10 dækker produktionspunkt-lageret.
This commit is contained in:
2026-09-21 15:18:02 +02:00
parent fb87dc4d37
commit 95615253b0
4 changed files with 59 additions and 8 deletions
+15 -1
View File
@@ -186,13 +186,27 @@ function ADSmartPickup.findLeastFilledPickup(adEnv, driver)
return findLeastFilled(collectMarkerStations(adEnv, groupMarkers, farmId, nil), fillTypes, farmId) return findLeastFilled(collectMarkerStations(adEnv, groupMarkers, farmId, nil), fillTypes, farmId)
end end
-- Lagrene bag aflæsningsstationen; produktionspunkter uden targetStorages læses direkte.
local function getTargetStorages(station)
if station.targetStorages ~= nil and next(station.targetStorages) ~= nil then
return station.targetStorages
end
local placeable = station.owningPlaceable
local productionPoint = placeable ~= nil and placeable.spec_productionPoint ~= nil and placeable.spec_productionPoint.productionPoint or nil
if productionPoint ~= nil and productionPoint.storage ~= nil then
return {productionPoint.storage}
end
return {}
end
-- Niveau + kapacitet pr. ingrediens i aflæsningsmålets lager. -- Niveau + kapacitet pr. ingrediens i aflæsningsmålets lager.
local function getTargetNeeds(station, ingredients, farmId) local function getTargetNeeds(station, ingredients, farmId)
local needs = {} local needs = {}
local storages = getTargetStorages(station)
for _, fillType in ipairs(ingredients) do for _, fillType in ipairs(ingredients) do
if station.getIsFillTypeSupported == nil or station:getIsFillTypeSupported(fillType) then if station.getIsFillTypeSupported == nil or station:getIsFillTypeSupported(fillType) then
local level, freeSpace = 0, 0 local level, freeSpace = 0, 0
for _, storage in pairs(station.targetStorages or {}) do for _, storage in pairs(storages) do
level = level + (storage:getFillLevel(fillType) or 0) level = level + (storage:getFillLevel(fillType) or 0)
freeSpace = freeSpace + (storage:getFreeCapacity(fillType) or 0) freeSpace = freeSpace + (storage:getFreeCapacity(fillType) or 0)
end end
+3 -2
View File
@@ -1,16 +1,17 @@
<?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.0.0.0</version> <version>1.1.0.0</version>
<title> <title>
<en>AD Smart Pickup</en> <en>AD Smart Pickup</en>
</title> </title>
<description> <description>
<en><![CDATA[AutoDrive-tillæg: når pålæsningsmål roteres i en mappe, køres der direkte til den silo i mappen, der har den valgte vare (mindst fyldte først), i stedet for at prøve markørerne én efter én. Kræver FS25_AutoDrive med "Brug mapper" + "Rotér mål: pålæsning".]]></en> <en><![CDATA[AutoDrive-tillæg: når pålæsningsmål roteres i en mappe, køres der direkte til den silo i mappen, der har den valgte vare (mindst fyldte først), i stedet for at prøve markørerne én efter én. Vælges FLERE varer i AutoDrive, ses de som ingredienser til aflæsningsmålet (fx en TMR-blander): én traktor henter pr. tur den vare målet mangler mest, fra en silo hvor som helst på kortet. Kræver FS25_AutoDrive med "Brug mapper" + "Rotér mål: pålæsning".]]></en>
</description> </description>
<iconFilename>icon.dds</iconFilename> <iconFilename>icon.dds</iconFilename>
<multiplayer supported="true"/> <multiplayer supported="true"/>
<extraSourceFiles> <extraSourceFiles>
<sourceFile filename="adSupplyPlanner.lua"/>
<sourceFile filename="adSmartPickup.lua"/> <sourceFile filename="adSmartPickup.lua"/>
</extraSourceFiles> </extraSourceFiles>
</modDesc> </modDesc>
+32 -5
View File
@@ -1,12 +1,39 @@
# FS25_ADSmartPickup # FS25_ADSmartPickup
AutoDrive-tillæg til Farming Simulator 25: når pålæsningsmål roteres i en AD-mappe, køres der AutoDrive-tillæg til Farming Simulator 25 med to funktioner oven på Pickup&Deliver:
direkte til den silo i mappen, der har den valgte vare — **mindst fyldte først** — i stedet for
at prøve markørerne én efter én. ## 1. Vare-bevidst mappe-rotation (én vare valgt)
Når pålæsningsmål roteres i en AD-mappe, køres der direkte til den silo i mappen, der har den
valgte vare — **mindst fyldte først** — i stedet for at prøve markørerne én efter én.
## 2. Behovsstyret forsyning (flere varer valgt)
Én traktor holder alle input i en produktion fyldt — fx hø, græs, ensilage og sukkerroer til en
TMR-blander — i stedet for én traktor pr. vare.
1. Aflæsningsmål = produktionens markør.
2. Multi-vælg ingredienserne i AutoDrives vare-dropdown.
3. Start Pickup&Deliver. Loop-tælleren virker som normalt (N læs → parkér, 0 = uendeligt).
Pr. tur læses målets lager; den ingrediens der mangler mest (relativt til kapacitet) hentes fra en
silo **hvor som helst på kortet** (eget lager før nabo-lån, mindst fyldte først). Ingredienser uden
plads i målet (< 1000 l fri) eller uden kilde springes over. Mens AD kører viser HUD'en kun turens
vare (AutoDrive ville ellers selv rotere vare ved triggeren); når AD stopper, gendannes hele listen.
Slå fra ved at vælge en anden enkelt vare.
"Mest brug for" defineres i `ADSupplyPlanner.scoreNeed` (`adSupplyPlanner.lua`).
## Fælles
- Wrapper `ADMultipleTargetsManager.getNextPickup` (via den globale `FS25_AutoDrive`-tabel); rører ikke AutoDrive-zip'en. - Wrapper `ADMultipleTargetsManager.getNextPickup` (via den globale `FS25_AutoDrive`-tabel); rører ikke AutoDrive-zip'en.
- Siloens eget lager rangeres før nabo-lån (udvidelses-siloer deler lager inden for `storageRadius`). - Siloens eget lager rangeres før nabo-lån (udvidelses-siloer deler lager inden for `storageRadius`).
- Finder den ingen silo med varen, eller fejler et spil-API, bruges AutoDrives originale rotation. - Intet fund, intet behov eller fejl i et spil-API → AutoDrives originale rotation. Valg logges som `ADSmartPickup:` i log.txt.
- Kræver i AutoDrive: "Brug mapper" + "Rotér mål: pålæsning" på køretøjet. - Kræver i AutoDrive: "Brug mapper" + "Rotér mål: pålæsning" på køretøjet.
Test: `luajit tests/test_adSmartPickup.lua` · Byg: zip indholdet af `FS25_ADSmartPickup/` til `FS25_ADSmartPickup.zip`. Begrænsninger: AD læsser fuld vogn — er der mindre plads i målet end ét læs, venter traktoren ved
aflæsning. Målet skal være en placeable med aflæsningstrigger (ikke en blandevogn).
Test: `luajit tests/test_adSupplyPlanner.lua && luajit tests/test_adSmartPickup.lua`
Byg: `cd FS25_ADSmartPickup && zip -qr ../FS25_ADSmartPickup.zip .`
Design/plan: `docs/superpowers/`
+9
View File
@@ -254,5 +254,14 @@ feeder = makeSupplyDriver(markerByIndex(1), markerByIndex(10), {HAY, GRASS})
check("S9 fejl giver fallback", manager:getNextPickup(feeder, false), "ORIGINAL") check("S9 fejl giver fallback", manager:getNextPickup(feeder, false), "ORIGINAL")
check("S9 fejl logges som advarsel", logLines[#logLines]:sub(1, 4), "WARN") check("S9 fejl logges som advarsel", logLines[#logLines]:sub(1, 4), "WARN")
-- S10: stationen eksponerer ikke targetStorages -> lageret læses fra produktionspunktet
buildFeedWorld()
local bareStation = unloadStations[1]
local productionStorage = next(bareStation.targetStorages)
bareStation.targetStorages = nil
bareStation.owningPlaceable = {spec_productionPoint = {productionPoint = {storage = productionStorage}}}
feeder = makeSupplyDriver(markerByIndex(1), markerByIndex(10), {HAY, GRASS, SILAGE})
check("S10 lager læses fra produktionspunktet", manager:getNextPickup(feeder, false), 3)
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)