docs: design for runs-UI (ESC-fane, run = mål+varer+Wait-pulje+traktorer)
This commit is contained in:
@@ -0,0 +1,143 @@
|
|||||||
|
# Runs-UI ("Cow Feed") — design
|
||||||
|
|
||||||
|
Dato: 2026-09-22 · Status: godkendt af bruger (sektion 1–3) · Version: v1.8
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
Al opsætning sker i dag pr. traktor i AutoDrives HUD: mål, multi-valg af varer (tændknap for
|
||||||
|
behovsstyring), mapper + rotation, loop-tæller. Med fire ens "Fastrac 2135" til to stalde og flere
|
||||||
|
Wait-puljer på vej (Cow/Pig/Sheep Wait) mangler overblik og central kontrol: *hvad* kører *hvor*
|
||||||
|
med *hvilke varer*, og hvor venter de.
|
||||||
|
|
||||||
|
## Løsning
|
||||||
|
|
||||||
|
Et **run** er den centrale enhed: navn, aflæsningsmål, varer, Wait-pulje, tildelte traktorer,
|
||||||
|
loop-tæller. En ESC-menu-fane ("Smart Pickup") viser og redigerer runs og starter/stopper dem.
|
||||||
|
"Start" skriver run'et ind i hver traktors AutoDrive-tilstand og kalder AD's start — alt det
|
||||||
|
eksisterende (behovsstyring, fabriks-inputs, Wait-punkter) virker uændret ovenpå, fordi det
|
||||||
|
læser præcis den tilstand. Traktorer uden run kører som i dag.
|
||||||
|
|
||||||
|
Valgt tilgang: **run-lag oven på AutoDrives tilstand** (fravalgt: egen dispatcher der kalder AD's
|
||||||
|
lav-niveau-opgaver — genopfinder P&D og knækker ved AD-opdateringer; konfig-fil uden UI — ikke det
|
||||||
|
brugeren bad om).
|
||||||
|
|
||||||
|
## 1. Datamodel og lagring
|
||||||
|
|
||||||
|
```
|
||||||
|
Run
|
||||||
|
id løbenummer (stabilt, unikt i savegame)
|
||||||
|
name "Cow Feed"
|
||||||
|
targetWayPointId AD-waypoint-id for mål-markøren (stald/fabrik); vises som markørnavn
|
||||||
|
ingredientMode "auto" | "manual"
|
||||||
|
ingredients liste af fillType-NAVNE (kun ved manual), fx {"STRAW","FORAGE"}
|
||||||
|
waitPoolGroup AD-mappenavn (fx "Cow Wait"); tom streng = alle Wait-mapper, nærmeste ledige
|
||||||
|
loops 0 = uendeligt, N = antal ture (AD's loop-tæller)
|
||||||
|
vehicleIds liste af køretøjs-referencer (se nedenfor)
|
||||||
|
|
||||||
|
Runtime (ikke gemt):
|
||||||
|
isRunning afledt: mindst én tildelt traktor har AD aktiv og run-medlemskab
|
||||||
|
runMembership vehicle -> run.id (svagt nøglet tabel)
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Køretøjs-reference:** AD's `uniqueId` (streng) når den findes på køretøjet, ellers savegame-id
|
||||||
|
(`vehicle.currentSavegameId`). Navne bruges aldrig som nøgle (fire hedder "Fastrac 2135 4WS").
|
||||||
|
- **WaitPool** er afledt, ikke gemt: alle AD-mapper med ordet "Wait" i navnet (`ADSupplyPlanner.isWaitMarker`).
|
||||||
|
Omdøbning sker i AutoDrive; vi læser kun.
|
||||||
|
- **Fil:** `savegameN/ADSmartPickup_runs.xml`, samme mappe som `AutoDrive_config.xml`. Skrives i
|
||||||
|
spillets gem-hook (som AD), læses ved `loadMap`. Ukendte køretøjs-referencer droppes med loglinje;
|
||||||
|
run'et beholdes. Runs der kørte ved gem genstartes IKKE ved load (AD gendanner selv aktive køretøjer).
|
||||||
|
- **Regler:** en traktor kan kun være i ét run (tildeles den et andet, flyttes den — UI'et siger det).
|
||||||
|
Singleplayer først; multiplayer kræver events og er uden for scope.
|
||||||
|
|
||||||
|
XML-format:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<ADSmartPickupRuns version="1">
|
||||||
|
<run id="1" name="Cow Feed" target="11066" ingredientMode="manual" ingredients="STRAW FORAGE"
|
||||||
|
waitPool="Cow Wait" loops="0">
|
||||||
|
<vehicle id="..."/>
|
||||||
|
<vehicle id="..."/>
|
||||||
|
</run>
|
||||||
|
</ADSmartPickupRuns>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. UI — ESC-fane "Smart Pickup"
|
||||||
|
|
||||||
|
Forbillede: FarmOperationsDashboard (`TabbedMenuFrameElement`, XML-layout med `SmoothList`,
|
||||||
|
`MultiTextOption`, `Button`; registreret via `g_gui:loadGui` + indsættelse i `InGameMenu.pagingElement`).
|
||||||
|
|
||||||
|
```
|
||||||
|
┌ Smart Pickup ─────────────────────────────────────────────────────────────┐
|
||||||
|
│ [Runs] [Wait-puljer] (under-faner) │
|
||||||
|
├──────────────────┬────────────────────────────────────────────────────────┤
|
||||||
|
│ RUNS │ RUN: Cow Feed ● Kører (2/2) │
|
||||||
|
│ ▶ Cow Feed 2/2 │ Mål: [Cow 1 Food ▼] (AD-markør) │
|
||||||
|
│ Cow 2 Feed 1/2 │ Varer: (•) Auto: alt målet tager / fabrikken │
|
||||||
|
│ TMR Fabrik 1/1 │ ( ) Vælg: [x] Halm [x] TMR [ ] Vand │
|
||||||
|
│ │ Wait-pulje: [Cow Wait ▼] (6 punkter)│
|
||||||
|
│ [+ Nyt run] │ Ture (loop): [0 = uendeligt ◄►] │
|
||||||
|
│ [Slet run] │ Traktorer: │
|
||||||
|
│ │ Fastrac 2135 (#1) vogn: 1.000.000 l halm+TMR ✔ │
|
||||||
|
│ │ Fastrac 2135 (#2) vogn: — INGEN VOGN ✖ │
|
||||||
|
│ │ [+ Tilføj traktor ▼] [Fjern] │
|
||||||
|
│ │ [▶ Start run] [■ Stop run] Status: 1 advarsel │
|
||||||
|
└──────────────────┴────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Runs-liste (venstre):** alle runs med "kører X af Y". Valg → detaljer til højre. `+ Nyt run`
|
||||||
|
opretter "Run N" (navn redigeres via AD-lignende tekstdialog). `Slet run` spørger ja/nej.
|
||||||
|
- **Mål:** dropdown over AD-markører der ligger ved en aflæsningsstation (`getUnloadStationAtMarker`
|
||||||
|
≠ nil) — ikke alle markører.
|
||||||
|
- **Varer:** *Auto* = det eksisterende: fabrik → ønskede produktioners inputs (v1.6); stald → alle
|
||||||
|
varer stalden tager (`getHusbandryIsFillTypeSupported`); andet mål → stationens understøttede varer.
|
||||||
|
*Vælg* = afkrydsning blandt målets mulige varer.
|
||||||
|
- **Wait-pulje:** dropdown "Alle (nærmeste ledige)" + hver mappe med "Wait" i navnet (antal punkter).
|
||||||
|
- **Ture:** 0–99.
|
||||||
|
- **Traktorer:** dropdown over farmens køretøjer med `vehicle.ad` (navn + `#løbenummer`). Pr. række:
|
||||||
|
vogn-kapacitet (AD `getAllFillLevels`), hvilke af run'ets varer vognen kan bære, og ✔/✖ med tekst:
|
||||||
|
"ingen vogn", "kan ikke bære: TMR", "N m fra vejnettet", "i run X (flyttes)".
|
||||||
|
- **Start/Stop** gælder hele run'et; ✖-traktorer springes over med besked i rækken.
|
||||||
|
- **Wait-puljer-fanen:** liste over Wait-mapper: antal punkter, hvilke traktorer holder hvor lige nu
|
||||||
|
(fra `adUnloadWait`'s reservationer). Kun visning.
|
||||||
|
- Live-opdatering hvert sekund mens siden er åben. Dansk + engelsk l10n. Ingen nye tastaturgenveje.
|
||||||
|
|
||||||
|
## 3. Start/Stop, integration, fejl og test
|
||||||
|
|
||||||
|
**Start run** (pr. tildelt traktor):
|
||||||
|
1. Validér: vogn tilkoblet og kan bære ≥1 af run'ets varer (`AutoDrive.getSupportedFillTypesOfAllUnitsAlphabetically`);
|
||||||
|
≤ 30 m fra vejnettet (`ADGraphManager:getDistanceFromNetwork`); mål-markør findes. Fejl → ✖ på rækken,
|
||||||
|
traktoren springes over, run'et fortsætter med de andre.
|
||||||
|
2. Skriv AD-tilstand: `stateModule:setMode(AutoDrive.MODE_PICKUPANDDELIVER)`;
|
||||||
|
`setSecondMarkerByWayPointId(target)`; `setFirstMarkerByWayPointId(nærmeste markør med læssestation)`
|
||||||
|
(kun en gyldig start — moden vælger reel kilde pr. tur); `selectedFillTypes` = run'ets varer
|
||||||
|
(Auto: udledt liste) + `raiseDirtyFlag`; loop-tæller; per-køretøj `vehicle.ad.settings.useFolders`
|
||||||
|
= til og `rotateTargets` = kun pålæsning (`current` og `new`).
|
||||||
|
3. `vehicle:startAutoDrive()`.
|
||||||
|
4. `runMembership[vehicle] = run.id`.
|
||||||
|
|
||||||
|
**Stop run:** `vehicle:stopAutoDrive()` pr. tildelt traktor; medlemskab bevares (konfigureret, ikke kørende).
|
||||||
|
|
||||||
|
**Integration:** de eksisterende hooks læser AD-tilstanden uændret. Run'et læses to steder:
|
||||||
|
(a) `adUnloadWait`: Wait-kandidater begrænses til run'ets mappe, hvis sat; (b) `choosePickup`:
|
||||||
|
for run-traktorer tages ingredienslisten fra run'et (Auto/manual) i stedet for "≥2 valgt i dropdown",
|
||||||
|
så tændknappen ikke længere kræves. Traktorer uden run: præcis som i dag.
|
||||||
|
|
||||||
|
**Fejlhåndtering:** al UI-kode og Start/Stop i `pcall`; fejl vises i status-linjen og logges med
|
||||||
|
`ADSmartPickup:`-præfiks; aldrig crash. Manglende AD-API → fanen viser "AutoDrive-API ikke fundet",
|
||||||
|
resten af moden upåvirket.
|
||||||
|
|
||||||
|
**Test:** rene funktioner i luajit (run-model: opret/omdøb/tildel/flyt; validering; Auto-vareliste;
|
||||||
|
XML ↔ tabel; kandidat-filtrering pr. Wait-pulje). GUI og AD-skrivning verificeres in-game efter
|
||||||
|
tjekliste: opret run → tildel 2 traktorer (én uden vogn) → Start (én ✖) → Stop → gem/load → run bevaret.
|
||||||
|
|
||||||
|
**Afgrænsning (YAGNI):** singleplayer; ingen kilde-begrænsning pr. run; ingen omdøbning af
|
||||||
|
Wait-mapper; ingen auto-genstart ved load; ingen genvejstast-dialog.
|
||||||
|
|
||||||
|
## Filer (forventet)
|
||||||
|
|
||||||
|
- `FS25_ADSmartPickup/adRuns.lua` — run-model + XML (rene funktioner hvor muligt)
|
||||||
|
- `FS25_ADSmartPickup/adRunsController.lua` — Start/Stop, validering mod AD/spil-API, medlemskab
|
||||||
|
- `FS25_ADSmartPickup/gui/SmartPickupFrame.lua` + `gui/SmartPickupFrame.xml` + `gui/guiProfiles.xml`
|
||||||
|
- `FS25_ADSmartPickup/l10n/l10n_da.xml`, `l10n_en.xml`
|
||||||
|
- `tests/test_adRuns.lua`
|
||||||
|
- Tilpasninger i `adSmartPickup.lua` (ingredienser fra run) og `adUnloadWait.lua` (pulje-filter)
|
||||||
Reference in New Issue
Block a user