fix(forsyning): rest ved fuldt mål køres til run'ets andet mål med mest plads før Wait; staldes læssestationer er aldrig kilde for halm/foder (kun output) (v1.18.6.0)
This commit is contained in:
@@ -272,7 +272,27 @@ end
|
|||||||
-- En fabriks læssestation udleverer også dens INPUTS (fx halm i en TMR-fabrik).
|
-- En fabriks læssestation udleverer også dens INPUTS (fx halm i en TMR-fabrik).
|
||||||
-- Dem stjæler vi aldrig — fabrikken ville løbe tør for det, den skal bruge.
|
-- Dem stjæler vi aldrig — fabrikken ville løbe tør for det, den skal bruge.
|
||||||
-- Outputs (og varer der både er input og output i en kæde) må gerne hentes.
|
-- Outputs (og varer der både er input og output i en kæde) må gerne hentes.
|
||||||
|
-- En STALDS læssestation udleverer kun staldens produktion. Den kan dog "have" halm/foder/vand
|
||||||
|
-- (strøelse, trug, udvidelseslagre inden for storageRadius) — dem henter vi aldrig dér.
|
||||||
|
local HUSBANDRY_OUTPUTS = {MILK = true, GOATMILK = true, BUFFALOMILK = true, SHEEPMILK = true, LIQUIDMANURE = true, MANURE = true, DIGESTATE = true, EGG = true, WOOL = true}
|
||||||
|
|
||||||
|
local function isProtectedHusbandryInput(station, fillTypes)
|
||||||
|
local placeable = station.owningPlaceable
|
||||||
|
if placeable == nil or placeable.getHusbandryFillLevel == nil or g_fillTypeManager == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
for _, fillType in ipairs(fillTypes) do
|
||||||
|
if not HUSBANDRY_OUTPUTS[tostring(g_fillTypeManager:getFillTypeNameByIndex(fillType))] then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
local function isProtectedProductionInput(station, fillTypes)
|
local function isProtectedProductionInput(station, fillTypes)
|
||||||
|
if isProtectedHusbandryInput(station, fillTypes) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
local productionPoint = getProductionPoint(station)
|
local productionPoint = getProductionPoint(station)
|
||||||
if productionPoint == nil or productionPoint.productions == nil then
|
if productionPoint == nil or productionPoint.productions == nil then
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -119,6 +119,27 @@ local function isAtUnloadTarget(adEnv, vehicle)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Står køretøjet ved målet med rest-læs, som målet ikke kan tage? Så find et Wait-punkt.
|
-- Står køretøjet ved målet med rest-læs, som målet ikke kan tage? Så find et Wait-punkt.
|
||||||
|
ADUnloadWait.MIN_FREE_FOR_OTHER_TARGET = 1000
|
||||||
|
|
||||||
|
-- Det af run'ets ANDRE mål der tager varen og har mest fri plads (≥ MIN_FREE_FOR_OTHER_TARGET) og vej.
|
||||||
|
local function findOtherTargetForRest(adEnv, vehicle, fillType, currentId)
|
||||||
|
local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle ~= nil and ADRunsController.getRunForVehicle(vehicle) or nil
|
||||||
|
if run == nil or (run.kind or "supply") ~= "supply" or vehicle.ad.stateModule.setSecondMarkerByWayPointId == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local best, bestFree = nil, ADUnloadWait.MIN_FREE_FOR_OTHER_TARGET - 1
|
||||||
|
for _, targetId in ipairs(ADRunsController.getRunTargets(run)) do
|
||||||
|
if targetId ~= currentId then
|
||||||
|
local free = ADSmartPickup.getTargetFreeCapacity(adEnv, vehicle, fillType, false, targetId)
|
||||||
|
if free ~= nil and free > bestFree and hasRouteTo(adEnv, vehicle, targetId) then
|
||||||
|
local marker = adEnv.ADGraphManager.getMapMarkerByWayPointId ~= nil and adEnv.ADGraphManager:getMapMarkerByWayPointId(targetId) or nil
|
||||||
|
best, bestFree = {id = targetId, name = marker ~= nil and marker.name or tostring(targetId)}, free
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return best, bestFree
|
||||||
|
end
|
||||||
|
|
||||||
local function startWaiting(adEnv, task)
|
local function startWaiting(adEnv, task)
|
||||||
local vehicle = task.vehicle
|
local vehicle = task.vehicle
|
||||||
-- Kun "fremme ved målet". At AD stadig regner vognen som aflæssende (isActiveAtTrigger)
|
-- Kun "fremme ved målet". At AD stadig regner vognen som aflæssende (isActiveAtTrigger)
|
||||||
@@ -157,6 +178,17 @@ local function startWaiting(adEnv, task)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Run med flere mål: resten køres til det af run'ets andre mål der har mest plads til varen,
|
||||||
|
-- før der ventes (en 2,4M l-vogn kan ellers aldrig komme af med resten ved én svinesti)
|
||||||
|
local other, otherFree = findOtherTargetForRest(adEnv, vehicle, fillType, target.id)
|
||||||
|
if other ~= nil then
|
||||||
|
vehicle.ad.stateModule:setSecondMarkerByWayPointId(other.id)
|
||||||
|
redirect(task, other.id)
|
||||||
|
Logging.info(ADUnloadWait.LOG_PREFIX .. "'%s': %s er fuld — resten (%.0f l %s) køres til %s (%.0f l fri)", tostring(ADRuns.vehicleLabel(vehicle)), tostring(target.name), rest,
|
||||||
|
g_fillTypeManager ~= nil and tostring(g_fillTypeManager:getFillTypeNameByIndex(fillType)) or tostring(fillType), tostring(other.name), otherFree)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local isReachable = function(candidate)
|
local isReachable = function(candidate)
|
||||||
return hasRouteBothWays(adEnv, vehicle, candidate.marker.id, task.destinationID)
|
return hasRouteBothWays(adEnv, vehicle, candidate.marker.id, task.destinationID)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?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.18.5.0</version>
|
<version>1.18.6.0</version>
|
||||||
<title>
|
<title>
|
||||||
<en>AD Smart Pickup</en>
|
<en>AD Smart Pickup</en>
|
||||||
</title>
|
</title>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# AD Smart Pickup — brugermanual
|
# AD Smart Pickup — brugermanual
|
||||||
|
|
||||||
Version 1.18.5 · Farming Simulator 25 · tillæg til AutoDrive
|
Version 1.18.6 · Farming Simulator 25 · tillæg til AutoDrive
|
||||||
|
|
||||||
*English version: [USER_MANUAL.md](USER_MANUAL.md)*
|
*English version: [USER_MANUAL.md](USER_MANUAL.md)*
|
||||||
|
|
||||||
@@ -210,7 +210,8 @@ Før hver pålæsning ser moden på målene og vælger:
|
|||||||
ryddes. Mælk, gylle og digestat hentes fra den *fyldeste* kilde, så produktionen ikke stopper.
|
ryddes. Mælk, gylle og digestat hentes fra den *fyldeste* kilde, så produktionen ikke stopper.
|
||||||
|
|
||||||
En fabriks egne **inputs** hentes aldrig fra fabrikken selv. Halm i en TMR-fabrik bliver altså, hvor
|
En fabriks egne **inputs** hentes aldrig fra fabrikken selv. Halm i en TMR-fabrik bliver altså, hvor
|
||||||
den er.
|
den er. En stalds læssepunkter bruges kun til staldens produktion, altså mælk, gylle, gødning, æg og
|
||||||
|
uld. Halm og foder hentes aldrig ved en stald.
|
||||||
|
|
||||||
**Fabrikker følger produktionerne.** Tænder du TMR i en fabrik, begynder traktoren at hente
|
**Fabrikker følger produktionerne.** Tænder du TMR i en fabrik, begynder traktoren at hente
|
||||||
ensilage, hø, halm og mineralfoder af sig selv. Slukker du den, holder traktoren op. Produktioner,
|
ensilage, hø, halm og mineralfoder af sig selv. Slukker du den, holder traktoren op. Produktioner,
|
||||||
@@ -234,8 +235,10 @@ at alle henter det samme.
|
|||||||
Kan målet ikke tage hele læsset, sker følgende:
|
Kan målet ikke tage hele læsset, sker følgende:
|
||||||
|
|
||||||
1. Traktoren læsser af, hvad der er plads til.
|
1. Traktoren læsser af, hvad der er plads til.
|
||||||
2. Resten køres til det **nærmeste ledige Wait-punkt**, så triggeren ikke blokeres for de næste.
|
2. Har flowet flere mål, køres resten til det af de andre mål, der har mest plads til varen. Det
|
||||||
3. Den kører tilbage, når målet kan tage **hele resten**, eller er faldet under **Kør hjem fra Wait
|
kræver mindst 1.000 l fri plads. Store vogne fordeler sig altså på alle staldene.
|
||||||
|
3. Har ingen af målene plads, køres resten til det **nærmeste ledige Wait-punkt**, så triggeren ikke blokeres for de næste.
|
||||||
|
4. Den kører tilbage, når målet kan tage **hele resten**, eller er faldet under **Kør hjem fra Wait
|
||||||
under**.
|
under**.
|
||||||
|
|
||||||
En rest på under 100 l, som målet ikke kan tage, tæller som tom. Traktoren kører videre i stedet for
|
En rest på under 100 l, som målet ikke kan tage, tæller som tom. Traktoren kører videre i stedet for
|
||||||
|
|||||||
+7
-4
@@ -1,6 +1,6 @@
|
|||||||
# AD Smart Pickup — user manual
|
# AD Smart Pickup — user manual
|
||||||
|
|
||||||
Version 1.18.5 · Farming Simulator 25 · add-on for AutoDrive
|
Version 1.18.6 · Farming Simulator 25 · add-on for AutoDrive
|
||||||
|
|
||||||
*Dansk version: [BRUGERMANUAL.md](BRUGERMANUAL.md)*
|
*Dansk version: [BRUGERMANUAL.md](BRUGERMANUAL.md)*
|
||||||
|
|
||||||
@@ -212,7 +212,8 @@ Before each loading, the mod looks at the targets and picks:
|
|||||||
*fullest* source, so production never stops.
|
*fullest* source, so production never stops.
|
||||||
|
|
||||||
A factory's own **inputs** are never taken from the factory itself. Straw in a TMR factory stays
|
A factory's own **inputs** are never taken from the factory itself. Straw in a TMR factory stays
|
||||||
where it is.
|
where it is. A barn's loading points are only used for the barn's own products: milk, slurry,
|
||||||
|
manure, eggs and wool. Straw and feed are never collected at a barn.
|
||||||
|
|
||||||
**Factories follow their productions.** Switch TMR on in a factory, and the tractor starts fetching
|
**Factories follow their productions.** Switch TMR on in a factory, and the tractor starts fetching
|
||||||
silage, hay, straw and mineral feed by itself. Switch it off, and the tractor stops. Productions
|
silage, hay, straw and mineral feed by itself. Switch it off, and the tractor stops. Productions
|
||||||
@@ -236,9 +237,11 @@ of them fetching the same thing.
|
|||||||
When the target cannot take the whole load, this happens:
|
When the target cannot take the whole load, this happens:
|
||||||
|
|
||||||
1. The tractor unloads what fits.
|
1. The tractor unloads what fits.
|
||||||
2. The rest is taken to the **nearest free Wait point**, so the trigger is not blocked for the next
|
2. If the flow has several targets, the rest goes to the other target with the most room for the
|
||||||
|
good, at least 1,000 l free. Large trailers therefore spread over all the barns.
|
||||||
|
3. If none of the targets has room, the rest is taken to the **nearest free Wait point**, so the trigger is not blocked for the next
|
||||||
tractors.
|
tractors.
|
||||||
3. It drives back when the target can take **the whole rest**, or has dropped below **Return from
|
4. It drives back when the target can take **the whole rest**, or has dropped below **Return from
|
||||||
Wait below**.
|
Wait below**.
|
||||||
|
|
||||||
A rest of less than 100 l that the target cannot take counts as empty. The tractor drives on instead
|
A rest of less than 100 l that the target cannot take counts as empty. The tractor drives on instead
|
||||||
|
|||||||
@@ -409,6 +409,16 @@ local function buildCowWorld()
|
|||||||
return driver
|
return driver
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- P0: en STALDS læssestation (gylle/mælk) er aldrig kilde for halm/foder, selv om den "har" halm
|
||||||
|
-- (in-game 24/9: TMR- og Cow Food-traktorer skulle hente halm ved 'Pig Slurry 1')
|
||||||
|
do
|
||||||
|
local cowDriverP0 = buildCowWorld()
|
||||||
|
addMarker(22, "Pig Slurry 1", "Pig Slurry", 400, 0)
|
||||||
|
table.insert(stations, makeStation(122, 400, 15, {[STRAW] = 1000, [LIQUIDMANURE or 99] = 5000}))
|
||||||
|
stations[#stations].owningPlaceable = {getHusbandryFillLevel = function() return 0 end, getName = function() return "Svinesti" end}
|
||||||
|
check("P0 halm hentes ikke fra svinestiens gyllestation", manager:getNextPickup(cowDriverP0, false), 21)
|
||||||
|
end
|
||||||
|
|
||||||
-- P1: halm mangler mest -> hentes fra halmladen, IKKE fra fabrikken (selv om den er mindst fyldt)
|
-- P1: halm mangler mest -> hentes fra halmladen, IKKE fra fabrikken (selv om den er mindst fyldt)
|
||||||
local cowDriver = buildCowWorld()
|
local cowDriver = buildCowWorld()
|
||||||
check("P1 halm hentes fra siloen, ikke fabrikkens input", manager:getNextPickup(cowDriver, false), 21)
|
check("P1 halm hentes fra siloen, ikke fabrikkens input", manager:getNextPickup(cowDriver, false), 21)
|
||||||
@@ -863,6 +873,26 @@ UnloadTask.update(tp, 16)
|
|||||||
check("I4 kun run'ets pulje", tp.destinationID, 40)
|
check("I4 kun run'ets pulje", tp.destinationID, 40)
|
||||||
ADRunsController.store = ADRuns.newStore()
|
ADRunsController.store = ADRuns.newStore()
|
||||||
|
|
||||||
|
-- I8: målet er fuldt med rest på vognen, men run'et har FLERE mål -> resten køres til det mål med plads
|
||||||
|
-- (in-game 24/9: 'Pig Food' med 2,4M l halm holdt ved den første svinesti; de fire andre fik intet)
|
||||||
|
buildWaitWorld()
|
||||||
|
addMarker(31, "Cow 2 Food", "Cow Food", 6000, 0)
|
||||||
|
local pen2Levels = {[STRAW] = 10000}
|
||||||
|
table.insert(unloadStations, makeUnloadStation(131, 6000, 10, pen2Levels, {[STRAW] = 100000}, {name = "sti 2"}))
|
||||||
|
local v8, t8 = makeUnloadingVehicle("Pig Food", 531, 5000, 35000)
|
||||||
|
v8.uniqueId = "vehicleI8"
|
||||||
|
testVehicles = {v8}
|
||||||
|
ADRunsController.store = ADRuns.newStore()
|
||||||
|
local pens = ADRunsController.createRun("Pig Food")
|
||||||
|
ADRunsController.updateRun(pens.id, {targetWayPointIds = {30, 31}, waitPoolGroup = "Cow Wait"})
|
||||||
|
ADRunsController.assignVehicle(pens.id, v8)
|
||||||
|
UnloadTask.update(t8, 16)
|
||||||
|
check("I8 resten køres til det andet mål", t8.destinationID, 31)
|
||||||
|
check("I8 AD's aflæsningsmål skiftet", v8.ad.stateModule.secondMarkerId, 31)
|
||||||
|
check("I8 logget", countLogsSince(1, "resten") >= 1, true)
|
||||||
|
ADRunsController.store = ADRuns.newStore()
|
||||||
|
testVehicles = {}
|
||||||
|
|
||||||
-- ==== S: læs-bytte fra Wait — halm-rest ved Wait, målet mangler TMR -> aflæs halm i silo ====
|
-- ==== S: læs-bytte fra Wait — halm-rest ved Wait, målet mangler TMR -> aflæs halm i silo ====
|
||||||
local function buildSwapWorld()
|
local function buildSwapWorld()
|
||||||
buildWaitWorld() -- stald: halm FULD (50000/50000), TMR 10000/100000
|
buildWaitWorld() -- stald: halm FULD (50000/50000), TMR 10000/100000
|
||||||
|
|||||||
Reference in New Issue
Block a user