diff --git a/FS25_ADSmartPickup/adLoadSwap.lua b/FS25_ADSmartPickup/adLoadSwap.lua index f545ada..19411a4 100644 --- a/FS25_ADSmartPickup/adLoadSwap.lua +++ b/FS25_ADSmartPickup/adLoadSwap.lua @@ -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 diff --git a/FS25_ADSmartPickup/adOutbound.lua b/FS25_ADSmartPickup/adOutbound.lua index fbcb043..cdb88df 100644 --- a/FS25_ADSmartPickup/adOutbound.lua +++ b/FS25_ADSmartPickup/adOutbound.lua @@ -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 diff --git a/FS25_ADSmartPickup/adOutboundPlanner.lua b/FS25_ADSmartPickup/adOutboundPlanner.lua index 8998af7..d2a71f0 100644 --- a/FS25_ADSmartPickup/adOutboundPlanner.lua +++ b/FS25_ADSmartPickup/adOutboundPlanner.lua @@ -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 diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index 40977f7..edeeb2e 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.17.5.0 + 1.17.6.0 <en>AD Smart Pickup</en> diff --git a/docs/BRUGERMANUAL.md b/docs/BRUGERMANUAL.md index 7f4befb..0a93d56 100644 --- a/docs/BRUGERMANUAL.md +++ b/docs/BRUGERMANUAL.md @@ -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 | diff --git a/docs/USER_MANUAL.md b/docs/USER_MANUAL.md index 412376b..ae20f6f 100644 --- a/docs/USER_MANUAL.md +++ b/docs/USER_MANUAL.md @@ -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 | diff --git a/tests/test_adLoadSwap.lua b/tests/test_adLoadSwap.lua index 30833a6..23420d9 100644 --- a/tests/test_adLoadSwap.lua +++ b/tests/test_adLoadSwap.lua @@ -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) diff --git a/tests/test_adOutboundPlanner.lua b/tests/test_adOutboundPlanner.lua index 2eefc8d..8e93c2b 100644 --- a/tests/test_adOutboundPlanner.lua +++ b/tests/test_adOutboundPlanner.lua @@ -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}))