feat(lager): lagerture kan aflæsse i gårdens egne fabrikker der bruger varen som input (gylle -> biogasanlæg) (v1.17.6.0)

This commit is contained in:
2026-09-24 04:41:51 +02:00
parent 73e886ee26
commit b603bd7765
8 changed files with 57 additions and 13 deletions
+30 -3
View File
@@ -42,6 +42,33 @@ local function isSilo(station, homeStation)
and placeable.spec_productionPoint == nil and (homeStation == nil or placeable ~= homeStation.owningPlaceable)
end
local function usesAsInput(placeable, fillType)
local productionPoint = placeable.spec_productionPoint ~= nil and placeable.spec_productionPoint.productionPoint or nil
for _, production in ipairs(productionPoint ~= nil and productionPoint.productions or {}) do
for _, input in ipairs(production.inputs or {}) do
if input.type == fillType then return true end
end
end
return false
end
-- Lagermål: rene siloer; med allowFactories også gårdens EGNE fabrikker der bruger varen som input
-- (fx et biogasanlæg med gyllesilo). Stalde, fremmede anlæg og hjemmet (målet selv) aldrig.
function ADLoadSwap.isStoreTarget(station, fillType, homeStation, allowFactories)
if isSilo(station, homeStation) then
return true
end
local placeable = station.owningPlaceable
if not allowFactories or placeable == nil or placeable.spec_productionPoint == nil or placeable.getHusbandryFillLevel ~= nil then
return false
end
if homeStation ~= nil and placeable == homeStation.owningPlaceable then
return false
end
local owned = ADPrices ~= nil and ADPrices.isOwnedByPlayer ~= nil and ADPrices.isOwnedByPlayer(placeable)
return owned and usesAsInput(placeable, fillType)
end
local function acceptsRest(station, fillType, rest, farmId)
if station.getIsFillTypeSupported ~= nil and not station:getIsFillTypeSupported(fillType) then
return false
@@ -70,7 +97,7 @@ function ADLoadSwap.rankDumpCandidates(candidates, avoidMarkers)
return ranked
end
function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointId, isReachable, excludedPlaceables, avoidMarkers)
function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointId, isReachable, excludedPlaceables, avoidMarkers, allowFactories)
if vehicle.rootNode == nil then
return nil, "køretøjet har ingen position"
end
@@ -82,7 +109,7 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId)
local isExcluded = excludedPlaceables ~= nil and excludedPlaceables[station ~= nil and station.owningPlaceable or false] == true
if station ~= nil and isSilo(station, homeStation) and not isExcluded then
if station ~= nil and ADLoadSwap.isStoreTarget(station, fillType, homeStation, allowFactories) and not isExcluded then
silos = silos + 1
if acceptsRest(station, fillType, rest, farmId) then
withSpace = withSpace + 1
@@ -105,7 +132,7 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI
end
end
if silos == 0 then
return nil, "ingen silo med aflæsningsmarkør fundet (siloen skal have en AD-markør ved aflæsningstriggeren)"
return nil, allowFactories and "ingen silo eller egen fabrik der bruger varen, med aflæsningsmarkør (sæt en AD-markør ved aflæsningstriggeren)" or "ingen silo med aflæsningsmarkør fundet (siloen skal have en AD-markør ved aflæsningstriggeren)"
elseif withSpace == 0 then
return nil, string.format("%d silo(er) fundet, men ingen tager varen med plads til %.0f l", silos, rest)
end
+3 -3
View File
@@ -201,7 +201,7 @@ local function findStoreMarker(adEnv, vehicle, product, capacity, sources, liter
end
local liters = math.max(1, math.min(available, capacity or available))
local avoid = ADRunsController ~= nil and ADRunsController.getPickupMarkers ~= nil and ADRunsController.getPickupMarkers() or nil
local marker = ADLoadSwap.findDumpMarker(adEnv, vehicle, product.fillType, liters, nil, isReachable, ADSources.getSourcePlaceables(sources), avoid)
local marker = ADLoadSwap.findDumpMarker(adEnv, vehicle, product.fillType, liters, nil, isReachable, ADSources.getSourcePlaceables(sources), avoid, true)
if marker == nil then
return nil
end
@@ -479,8 +479,8 @@ function ADOutbound.choosePickup(adEnv, vehicle)
local runStatus = getStatus(run)
runStatus.reasons = reasons
for _, reason in ipairs(reasons) do
if string.find(reason, ": ingen silo med plads", 1, true) then
warnOnce(adEnv, vehicle, "store:" .. reason, string.format("'%s' finder ingen silo med plads (%s)", tostring(ADRuns.vehicleLabel(vehicle)), reason))
if string.find(reason, ": intet lager med plads", 1, true) then
warnOnce(adEnv, vehicle, "store:" .. reason, string.format("'%s' finder intet lager med plads (%s)", tostring(ADRuns.vehicleLabel(vehicle)), reason))
end
end
if trip == nil then
+1 -1
View File
@@ -99,7 +99,7 @@ local function reasonFor(product, e, input)
return product.name .. ": intet nåeligt salgssted"
end
if wantsStore(product.policy) and product.store == nil and (e.fullLoad or e.storageHigh) and not e.priceOk then
return product.name .. ": ingen silo med plads"
return product.name .. ": intet lager med plads (silo eller egen fabrik der bruger varen)"
end
local parts = {}
if wantsSell(product.policy) and e.percent ~= nil then
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107">
<author>masterdraco</author>
<version>1.17.5.0</version>
<version>1.17.6.0</version>
<title>
<en>AD Smart Pickup</en>
</title>
+2 -2
View File
@@ -1,6 +1,6 @@
# AD Smart Pickup — brugermanual
Version 1.17.5 · Farming Simulator 25 · tillæg til AutoDrive
Version 1.17.6 · Farming Simulator 25 · tillæg til AutoDrive
*English version: [USER_MANUAL.md](USER_MANUAL.md)*
@@ -282,7 +282,7 @@ Hver vare, kilderne har, står med sin mængde og nuværende pris. Vælg en poli
| Politik | Betydning |
|---|---|
| **Fra** | Varen røres ikke |
| **Lager** | Køres til en silo eller et palleskur, når der er et fuldt læs, eller kilden er ved at være fuld |
| **Lager** | Køres til en silo, et palleskur eller en af gårdens egne fabrikker, der bruger varen, fx gylle til et biogasanlæg. Det sker, når der er et fuldt læs, eller kilden er ved at være fuld |
| **Salg** | Sælges, når prisen er tæt nok på årets top |
| **Salg, ellers lager** | Sælges ved god pris. Ellers køres den til lager, når kilden er ved at være fuld |
+2 -2
View File
@@ -1,6 +1,6 @@
# AD Smart Pickup — user manual
Version 1.17.5 · Farming Simulator 25 · add-on for AutoDrive
Version 1.17.6 · Farming Simulator 25 · add-on for AutoDrive
*Dansk version: [BRUGERMANUAL.md](BRUGERMANUAL.md)*
@@ -286,7 +286,7 @@ Every good in the sources is listed with its amount and current price. Pick a po
| Policy | Meaning |
|---|---|
| **Off** | The good is left alone |
| **Store** | Taken to a silo or pallet shed when there is a full load, or the source is nearly full |
| **Store** | Taken to a silo, a pallet shed or one of the farm's own factories that uses the good, such as slurry for a biogas plant. This happens when there is a full load, or the source is nearly full |
| **Sell** | Sold when the price is close enough to the yearly top |
| **Sell, else store** | Sold at a good price. Otherwise taken to storage when the source is nearly full |
+17
View File
@@ -1,6 +1,7 @@
-- Kør: luajit tests/test_adLoadSwap.lua (fra repo-roden)
-- Ren rangering af aflæsnings-siloer (lagermål for udkørsel og læs-bytte).
dofile("FS25_ADSmartPickup/adPrices.lua")
dofile("FS25_ADSmartPickup/adLoadSwap.lua")
local L = ADLoadSwap
@@ -27,5 +28,21 @@ check("LS1 afhentning sidst (stadig mulig)", ranked[3].marker.id, 1)
local plain = L.rankDumpCandidates(candidates, nil)
check("LS1 uden undgå-liste: har varen + nærmest", plain[1].marker.id, 1)
-- LS2: lagermål — rene siloer altid; egne fabrikker der bruger varen som input kun når tilladt (udkørsel)
local SLURRY, MILK = 20, 21
g_currentMission = {getFarmId = function() return 1 end}
local biogas = {spec_productionPoint = {productionPoint = {productions = {{inputs = {{type = SLURRY, amount = 1}}}}}}, getOwnerFarmId = function() return 1 end}
local foreignBiogas = {spec_productionPoint = {productionPoint = {productions = {{inputs = {{type = SLURRY, amount = 1}}}}}}, getOwnerFarmId = function() return 0 end}
local silo = {spec_silo = {}}
local barn = {spec_silo = {}, getHusbandryFillLevel = function() return 0 end}
check("LS2 silo", L.isStoreTarget({owningPlaceable = silo}, SLURRY, nil, false), true)
check("LS2 stald aldrig", L.isStoreTarget({owningPlaceable = barn}, SLURRY, nil, true), false)
check("LS2 biogas kun når fabrikker tilladt", L.isStoreTarget({owningPlaceable = biogas}, SLURRY, nil, false), false)
check("LS2 biogas tager gylle", L.isStoreTarget({owningPlaceable = biogas}, SLURRY, nil, true), true)
check("LS2 biogas tager ikke mælk", L.isStoreTarget({owningPlaceable = biogas}, MILK, nil, true), false)
check("LS2 fremmed anlæg aldrig", L.isStoreTarget({owningPlaceable = foreignBiogas}, SLURRY, nil, true), false)
check("LS2 hjemmet selv aldrig", L.isStoreTarget({owningPlaceable = biogas}, SLURRY, {owningPlaceable = biogas}, true), false)
g_currentMission = nil
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)
+1 -1
View File
@@ -69,7 +69,7 @@ check("P6 begrundelse", reasons6[1], "SUGAR: intet nåeligt salgssted")
-- P7: ingen silo med plads ved lagerbehov
local trip7, reasons7 = P.plan(input({product("FORAGE", FORAGE, "store", {{wayPointId = 2, available = 3000000, level = 3000000, capacity = 3500000}}, nil, nil)}))
check("P7 ingen tur", trip7, nil)
check("P7 begrundelse", reasons7[1], "FORAGE: ingen silo med plads")
check("P7 begrundelse", reasons7[1], "FORAGE: intet lager med plads (silo eller egen fabrik der bruger varen)")
-- P8: runde, bulk: samme vare fra flere kilder, mest først
local trip8 = P.plan(input({product("SUGAR", SUGAR, "sell", {{wayPointId = 1, available = 3000, level = 3000, capacity = 180000}, {wayPointId = 3, available = 9000, level = 9000, capacity = 180000}}, quoteS, nil)}, {collectRound = true, capacity = 10000}))