feat(oversigt): Start/Stop alle flows + klik på flow hopper til redigering; palleskure viser paller af pladser (v1.20.0.0)
- ADRunsController.startAllRuns/stopAllRuns/hasActiveRuns (kørende flows røres ikke ved Start alle) - Oversigt: knapsæt Start alle / Stop alle / Nyt run, samlet status, klikbare rækker (hop via update) - Palleskur-statistik: kapacitet = (egne + ledige pladser) x indhold; 24/4000 paller 1 % i stedet for 600 % - Manualer da/en opdateret
This commit is contained in:
@@ -1120,6 +1120,46 @@ function ADRunsController.getRunStatus(adEnv, run)
|
||||
return {running = running, total = #run.vehicleIds, isRunning = isRunning}
|
||||
end
|
||||
|
||||
-- Start alle (Oversigt): flows der allerede kører røres ikke, så et halvt kørende gårdbillede kan
|
||||
-- "fyldes op" uden at traktorer midt i en tur afbrydes. Flows uden traktorer springes over.
|
||||
function ADRunsController.startAllRuns(adEnv)
|
||||
local summary = {runsStarted = 0, alreadyRunning = 0, vehiclesStarted = 0, results = {}}
|
||||
for _, run in ipairs(ADRunsController.store.runs) do
|
||||
if #run.vehicleIds > 0 then
|
||||
if ADRunsController.getRunStatus(adEnv, run).isRunning then
|
||||
summary.alreadyRunning = summary.alreadyRunning + 1
|
||||
else
|
||||
local startedHere = 0
|
||||
for _, result in ipairs(ADRunsController.startRun(adEnv, run.id)) do
|
||||
table.insert(summary.results, result)
|
||||
if result.ok then startedHere = startedHere + 1 end
|
||||
end
|
||||
summary.vehiclesStarted = summary.vehiclesStarted + startedHere
|
||||
if startedHere > 0 then summary.runsStarted = summary.runsStarted + 1 end
|
||||
end
|
||||
end
|
||||
end
|
||||
return summary
|
||||
end
|
||||
|
||||
-- Stop alle: stopper alle aktive traktorer i alle flows (også dem der er startet manuelt i AD).
|
||||
function ADRunsController.stopAllRuns(adEnv)
|
||||
local stopped = 0
|
||||
for _, run in ipairs(ADRunsController.store.runs) do
|
||||
stopped = stopped + ADRunsController.stopRun(adEnv, run.id)
|
||||
end
|
||||
return stopped
|
||||
end
|
||||
|
||||
function ADRunsController.hasActiveRuns(adEnv)
|
||||
for _, run in ipairs(ADRunsController.store.runs) do
|
||||
if ADRunsController.getRunStatus(adEnv, run).running > 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- ---- overblik ----
|
||||
|
||||
-- Hvad laver traktoren lige nu? {kind = "stopped"|"waiting"|"loaded"|"empty", fillType, liters, place}
|
||||
|
||||
@@ -894,6 +894,7 @@ local function addEntry(entries, fillType, level, capacity, extra)
|
||||
local entry = newProduct(fillType, level, level, capacity, false)
|
||||
entry.isOutput = extra ~= nil and extra.isOutput or false
|
||||
entry.count = extra ~= nil and extra.count or nil
|
||||
entry.slots = extra ~= nil and extra.slots or nil
|
||||
table.insert(entries, entry)
|
||||
end
|
||||
|
||||
@@ -936,7 +937,10 @@ local function objectStorageEntries(placeable)
|
||||
local fillType, perObject = getObjectInfoContent(objectInfo)
|
||||
local count = objectInfo.numObjects or 0
|
||||
if fillType ~= nil and count > 0 then
|
||||
addEntry(entries, fillType, count * perObject, spec.capacity or 0, {count = count})
|
||||
-- spec.capacity er PLADSER (delt mellem alle varer); i liter: (egne + ledige) paller x indhold
|
||||
local free = ADSources.objectStorageFreeSlots(placeable)
|
||||
local slots = free ~= math.huge and count + free or nil -- skur uden grænse: ingen procent
|
||||
addEntry(entries, fillType, count * perObject, slots ~= nil and slots * perObject or 0, {count = count, slots = slots})
|
||||
end
|
||||
end
|
||||
return entries
|
||||
|
||||
@@ -11,11 +11,18 @@ function ADStorageStats.itemStats(item, farmTotal, rate, quote)
|
||||
local capacity = item.capacity or 0
|
||||
local consumption = rate ~= nil and rate.consumption or 0
|
||||
local production = rate ~= nil and rate.production or 0
|
||||
-- palleskure: fyldning i paller af pladser (kapaciteten er et antal pladser, ikke liter)
|
||||
local percent = capacity > 0 and math.floor(100 * level / capacity + 0.5) or nil
|
||||
if item.count ~= nil and (item.slots or 0) > 0 then
|
||||
percent = math.floor(100 * item.count / item.slots + 0.5)
|
||||
end
|
||||
return {
|
||||
fillType = item.fillType,
|
||||
level = level,
|
||||
capacity = capacity,
|
||||
percent = capacity > 0 and math.floor(100 * level / capacity + 0.5) or nil,
|
||||
count = item.count,
|
||||
slots = item.slots,
|
||||
percent = percent,
|
||||
valueNow = quote ~= nil and quote.price ~= nil and math.floor(level * quote.price + 0.5) or nil,
|
||||
valueTop = quote ~= nil and quote.top ~= nil and math.floor(level * quote.top + 0.5) or nil,
|
||||
farmTotal = farmTotal or level,
|
||||
|
||||
@@ -64,15 +64,45 @@ function SmartPickupFrame:flowCells(adEnv, run)
|
||||
return {name, products, from, to, string.format("%d/%d", row.running, row.total), status}
|
||||
end
|
||||
|
||||
-- Fanen Oversigt: alle flows som tabel, grupperet Ind/Ud efter navn.
|
||||
-- Hele rækken klikbar med musen (Bitmap-rækker har ingen onClick). Klikket gemmes kun som
|
||||
-- pendingJumpRunId; hoppet sker i update(), fordi genopbygningen sletter netop denne række.
|
||||
local MOUSE_LEFT = Input ~= nil and Input.MOUSE_BUTTON_LEFT or 1
|
||||
|
||||
local function isInside(element, posX, posY)
|
||||
local position, size = element.absPosition, element.absSize
|
||||
if position == nil or size == nil then return false end
|
||||
return posX >= position[1] and posX <= position[1] + size[1] and posY >= position[2] and posY <= position[2] + size[2]
|
||||
end
|
||||
|
||||
function SmartPickupFrame:makeRowClickable(row, runId)
|
||||
local frame = self
|
||||
local baseMouseEvent = row.mouseEvent
|
||||
row.mouseEvent = function(element, posX, posY, isDown, isUp, button, eventUsed)
|
||||
local used = baseMouseEvent(element, posX, posY, isDown, isUp, button, eventUsed)
|
||||
-- også inden for listens synlige udsnit: rækker scrollet ud af syne må ikke fange klik
|
||||
if not used and not eventUsed and isUp and button == MOUSE_LEFT and (element.getIsVisible == nil or element:getIsVisible())
|
||||
and isInside(element, posX, posY) and isInside(frame.boxLayout, posX, posY) then
|
||||
frame.pendingJumpRunId = runId
|
||||
return true
|
||||
end
|
||||
return used
|
||||
end
|
||||
end
|
||||
|
||||
-- Fanen Oversigt: alle flows som tabel, grupperet Ind/Ud efter navn. Klik på et flow = redigér det.
|
||||
function SmartPickupFrame:fillOverviewRows(adEnv)
|
||||
self.overviewRows = {}
|
||||
local i18n = self.i18n
|
||||
self:addTextRow(i18n:getText("spu_overview_hint"))
|
||||
self:addCellRow(self.flowPrefab, {i18n:getText("spu_col_flow"), i18n:getText("spu_col_goods"), i18n:getText("spu_col_from"), i18n:getText("spu_col_to"), i18n:getText("spu_col_tractors"), i18n:getText("spu_col_status")})
|
||||
for _, group in ipairs(ADFlowView.boardGroups(ADRunsController.store.runs)) do
|
||||
self:addTextRow(i18n:getText(group.kind == "outbound" and "spu_board_outbound" or "spu_board_supply"))
|
||||
for _, run in ipairs(group.runs) do
|
||||
table.insert(self.overviewRows, {runId = run.id, cells = self:addCellRow(self.flowPrefab, self:flowCells(adEnv, run))})
|
||||
local cells = self:addCellRow(self.flowPrefab, self:flowCells(adEnv, run))
|
||||
if cells[1] ~= nil and cells[1].parent ~= nil then
|
||||
self:makeRowClickable(cells[1].parent, run.id)
|
||||
end
|
||||
table.insert(self.overviewRows, {runId = run.id, cells = cells})
|
||||
end
|
||||
end
|
||||
if #ADRunsController.store.runs == 0 then
|
||||
|
||||
@@ -8,6 +8,7 @@ SmartPickupFrame._mt = Class(SmartPickupFrame, TabbedMenuFrameElement)
|
||||
|
||||
SmartPickupFrame.REFRESH_INTERVAL_MS = 1000
|
||||
SmartPickupFrame.STATUS_OVERRIDE_TICKS = 6
|
||||
SmartPickupFrame.MAX_STATUS_REASONS = 3
|
||||
SmartPickupFrame.LOG_PREFIX = "ADSmartPickup: "
|
||||
SmartPickupFrame.STATE_OFF, SmartPickupFrame.STATE_ON = 1, 2
|
||||
SmartPickupFrame.TAB_OVERVIEW, SmartPickupFrame.TAB_FLOWS = 1, 2
|
||||
@@ -45,8 +46,13 @@ function SmartPickupFrame.new(i18n, getAdEnv)
|
||||
self.newButtonInfo = {inputAction = InputAction.MENU_EXTRA_1, text = i18n:getText("spu_button_new"), callback = function() self:onClickNew() end}
|
||||
self.renameButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_button_rename"), callback = function() self:onClickRename() end}
|
||||
self.deleteButtonInfo = {inputAction = InputAction.MENU_CANCEL, text = i18n:getText("spu_button_delete"), callback = function() self:onClickDelete() end}
|
||||
-- Oversigt: Start/Stop alle i stedet for knapperne der virker på ét valgt flow.
|
||||
self.startAllButtonInfo = {inputAction = InputAction.MENU_ACTIVATE, text = i18n:getText("spu_button_startAll"), callback = function() self:onClickStartAll() end}
|
||||
self.stopAllButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_button_stopAll"), callback = function() self:onClickStopAll() end}
|
||||
self.flowButtons = {self.backButtonInfo, self.startButtonInfo, self.newButtonInfo, self.renameButtonInfo, self.deleteButtonInfo}
|
||||
self.overviewButtons = {self.backButtonInfo, self.startAllButtonInfo, self.stopAllButtonInfo, self.newButtonInfo}
|
||||
-- Egen reference til listen: fallback'en i refreshButtons skal kunne sende den igen.
|
||||
self.menuButtonInfo = {self.backButtonInfo, self.startButtonInfo, self.newButtonInfo, self.renameButtonInfo, self.deleteButtonInfo}
|
||||
self.menuButtonInfo = self.overviewButtons
|
||||
self:setMenuButtonInfo(self.menuButtonInfo)
|
||||
return self
|
||||
end
|
||||
@@ -195,7 +201,11 @@ end
|
||||
-- dets egen klik-håndtering, hopper værdien frem og tilbage og fokus ryger.
|
||||
function SmartPickupFrame:update(dt)
|
||||
SmartPickupFrame:superClass().update(self, dt)
|
||||
if self.pendingRebuild then
|
||||
if self.pendingJumpRunId ~= nil then
|
||||
local runId = self.pendingJumpRunId
|
||||
self.pendingJumpRunId = nil
|
||||
self:safe(function(frame) frame:openFlow(runId) end)
|
||||
elseif self.pendingRebuild then
|
||||
self.pendingRebuild = false
|
||||
self:safe(self.rebuild)
|
||||
end
|
||||
@@ -632,6 +642,11 @@ end
|
||||
-- setMenuButtonInfoDirty findes i FS22/25's TabbedMenuFrameElement; mangler den,
|
||||
-- sendes listen igen. Kaldes hvert sekund, så den må aldrig kaste.
|
||||
function SmartPickupFrame:refreshButtons()
|
||||
local wanted = self.currentTab == SmartPickupFrame.TAB_OVERVIEW and self.overviewButtons or self.flowButtons
|
||||
if self.menuButtonInfo ~= wanted then
|
||||
self.menuButtonInfo = wanted
|
||||
self:setMenuButtonInfo(wanted)
|
||||
end
|
||||
if self.setMenuButtonInfoDirty ~= nil then
|
||||
self:setMenuButtonInfoDirty()
|
||||
else
|
||||
@@ -647,12 +662,22 @@ function SmartPickupFrame:refreshLive()
|
||||
self:setStatusText(self.i18n:getText("spu_status_noAd"))
|
||||
return
|
||||
end
|
||||
if self.currentTab == SmartPickupFrame.TAB_OVERVIEW then
|
||||
local isOverview = self.currentTab == SmartPickupFrame.TAB_OVERVIEW
|
||||
if isOverview then
|
||||
self:refreshOverview(adEnv)
|
||||
end
|
||||
self:refreshStorageRows(adEnv)
|
||||
local isRunning = false
|
||||
if run ~= nil then
|
||||
if isOverview then
|
||||
local running, total, activeRuns = 0, 0, 0
|
||||
for _, anyRun in ipairs(ADRunsController.store.runs) do
|
||||
local status = ADRunsController.getRunStatus(adEnv, anyRun)
|
||||
running, total = running + status.running, total + status.total
|
||||
if status.running > 0 then activeRuns = activeRuns + 1 end
|
||||
end
|
||||
self:setStatusText(self.statusOverride or string.format(self.i18n:getText("spu_status_overview"), running, total, activeRuns, #ADRunsController.store.runs))
|
||||
self.stopAllButtonInfo.disabled = running == 0
|
||||
elseif run ~= nil then
|
||||
self:syncOptionsFromModel(adEnv, run)
|
||||
if run.kind == "outbound" then
|
||||
self:refreshOutboundRows(adEnv, run)
|
||||
@@ -766,30 +791,80 @@ function SmartPickupFrame:onClickStartStop()
|
||||
ADRunsController.stopRun(adEnv, run.id)
|
||||
frame.statusOverride = nil
|
||||
else
|
||||
local started, skipped, reasons = 0, 0, {}
|
||||
for _, result in ipairs(ADRunsController.startRun(adEnv, run.id)) do
|
||||
if result.ok then
|
||||
started = started + 1
|
||||
else
|
||||
skipped = skipped + 1
|
||||
local reasonText = frame.i18n:getText("spu_reason_" .. tostring(result.reason))
|
||||
if result.reason == "noMarker" and result.missingBuilding ~= nil then
|
||||
reasonText = string.format(reasonText, tostring(result.missingBuilding))
|
||||
end
|
||||
table.insert(reasons, string.format("%s: %s", tostring(ADRuns.vehicleLabel(result.vehicle)), reasonText))
|
||||
end
|
||||
end
|
||||
frame.statusOverride = string.format(frame.i18n:getText("spu_status_started"), started, skipped)
|
||||
if #reasons > 0 then
|
||||
frame.statusOverride = frame.statusOverride .. " — " .. table.concat(reasons, "; ")
|
||||
end
|
||||
frame.statusOverrideTicks = SmartPickupFrame.STATUS_OVERRIDE_TICKS
|
||||
local started, skipped, reasons = frame:summarizeStartResults(ADRunsController.startRun(adEnv, run.id))
|
||||
frame:showOverride(string.format(frame.i18n:getText("spu_status_started"), started, skipped), reasons)
|
||||
end
|
||||
ADRunsController.save()
|
||||
frame:requestRebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
-- Start-resultater -> antal startet/sprunget over + "Traktor: grund"-liste til statuslinjen.
|
||||
function SmartPickupFrame:summarizeStartResults(results)
|
||||
local started, skipped, reasons = 0, 0, {}
|
||||
for _, result in ipairs(results) do
|
||||
if result.ok then
|
||||
started = started + 1
|
||||
else
|
||||
skipped = skipped + 1
|
||||
local reasonText = self.i18n:getText("spu_reason_" .. tostring(result.reason))
|
||||
if result.reason == "noMarker" and result.missingBuilding ~= nil then
|
||||
reasonText = string.format(reasonText, tostring(result.missingBuilding))
|
||||
end
|
||||
table.insert(reasons, string.format("%s: %s", tostring(ADRuns.vehicleLabel(result.vehicle)), reasonText))
|
||||
end
|
||||
end
|
||||
return started, skipped, reasons
|
||||
end
|
||||
|
||||
function SmartPickupFrame:showOverride(text, reasons)
|
||||
if reasons ~= nil and #reasons > 0 then
|
||||
-- én statuslinje: højst MAX_STATUS_REASONS grunde, resten står i log.txt
|
||||
local shown = {}
|
||||
for index = 1, math.min(#reasons, SmartPickupFrame.MAX_STATUS_REASONS) do shown[index] = reasons[index] end
|
||||
text = text .. " — " .. table.concat(shown, "; ")
|
||||
if #reasons > #shown then text = text .. string.format(" (+%d)", #reasons - #shown) end
|
||||
end
|
||||
self.statusOverride = text
|
||||
self.statusOverrideTicks = SmartPickupFrame.STATUS_OVERRIDE_TICKS
|
||||
self:setStatusText(text)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickStartAll()
|
||||
self:safe(function(frame)
|
||||
local adEnv = frame.getAdEnv()
|
||||
if adEnv == nil then return end
|
||||
local summary = ADRunsController.startAllRuns(adEnv)
|
||||
local _, skipped, reasons = frame:summarizeStartResults(summary.results)
|
||||
Logging.info(SmartPickupFrame.LOG_PREFIX .. "Start alle: %d flows startet (%d traktorer), %d kørte allerede, %d sprunget over",
|
||||
summary.runsStarted, summary.vehiclesStarted, summary.alreadyRunning, skipped)
|
||||
frame:showOverride(string.format(frame.i18n:getText("spu_status_startedAll"), summary.runsStarted, summary.vehiclesStarted, summary.alreadyRunning, skipped), reasons)
|
||||
ADRunsController.save()
|
||||
frame:requestRebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickStopAll()
|
||||
self:safe(function(frame)
|
||||
local adEnv = frame.getAdEnv()
|
||||
if adEnv == nil then return end
|
||||
local stopped = ADRunsController.stopAllRuns(adEnv)
|
||||
Logging.info(SmartPickupFrame.LOG_PREFIX .. "Stop alle: %d traktorer stoppet", stopped)
|
||||
frame:showOverride(string.format(frame.i18n:getText("spu_status_stoppedAll"), stopped))
|
||||
ADRunsController.save()
|
||||
frame:requestRebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
-- Klik på en række i Oversigt: vælg flowet og hop til fanen Flows (kaldes fra update, aldrig inde i
|
||||
-- rækkens eget mouseEvent — rækken slettes af genopbygningen).
|
||||
function SmartPickupFrame:openFlow(runId)
|
||||
if ADRuns.getRun(ADRunsController.store, runId) == nil then return end
|
||||
self.selectedRunId = runId
|
||||
self.statusOverride = nil
|
||||
self:switchTab(SmartPickupFrame.TAB_FLOWS)
|
||||
end
|
||||
|
||||
-- Nyt run: navnet vælges FØR run'et oprettes (annulleres dialogen, oprettes intet).
|
||||
-- Forslaget tæller efter antal runs, ikke efter løbenummeret, så "Run 2" kan genbruges.
|
||||
function SmartPickupFrame:onClickNew()
|
||||
|
||||
@@ -93,6 +93,9 @@ function SmartPickupFrame:statCells(stat)
|
||||
local i18n = self.i18n
|
||||
local fc = SmartPickupFrame.formatCompact
|
||||
local here = string.format("%s/%s", fc(stat.level), fc(stat.capacity))
|
||||
if stat.count ~= nil and stat.slots ~= nil then
|
||||
here = string.format(i18n:getText("spu_stat_pallets"), stat.count, stat.slots)
|
||||
end
|
||||
if stat.percent ~= nil then here = here .. string.format(" %d %%", stat.percent) end
|
||||
local now, top = i18n:getText("spu_stat_noSell"), ""
|
||||
if stat.valueNow ~= nil then
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
<text name="spu_reason_noTarget" text="intet mål"/>
|
||||
<text name="spu_reason_error" text="fejl ved start (se log)"/>
|
||||
<text name="spu_movedFrom" text="flyttet fra '%s'"/>
|
||||
<text name="spu_button_startAll" text="Start alle flows"/>
|
||||
<text name="spu_button_stopAll" text="Stop alle flows"/>
|
||||
<text name="spu_status_overview" text="Kører: %d af %d traktorer · %d af %d flows aktive"/>
|
||||
<text name="spu_status_startedAll" text="Startet %d flows (%d traktorer), %d kørte allerede, %d sprunget over"/>
|
||||
<text name="spu_status_stoppedAll" text="Stoppet %d traktorer"/>
|
||||
<text name="spu_overview_hint" text="Klik på et flow for at redigere det"/>
|
||||
<text name="spu_button_start" text="Start run"/>
|
||||
<text name="spu_button_stop" text="Stop run"/>
|
||||
<text name="spu_button_new" text="Nyt run"/>
|
||||
@@ -63,6 +69,7 @@
|
||||
<text name="spu_tab_outbound" text="Udkørsel"/>
|
||||
<text name="spu_tab_storage" text="Lagre"/>
|
||||
<text name="spu_section_storage" text="— Gårdens beholdning (* = fabrikkens output) —"/>
|
||||
<text name="spu_stat_pallets" text="%d/%d paller"/>
|
||||
<text name="spu_storage_pallets" text="%d paller"/>
|
||||
<text name="spu_storage_empty" text="Ingen bygninger med indhold"/>
|
||||
<text name="spu_source_kind_husbandry" text="stald"/>
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
<text name="spu_reason_noTarget" text="no target"/>
|
||||
<text name="spu_reason_error" text="start failed (see log)"/>
|
||||
<text name="spu_movedFrom" text="moved from '%s'"/>
|
||||
<text name="spu_button_startAll" text="Start all flows"/>
|
||||
<text name="spu_button_stopAll" text="Stop all flows"/>
|
||||
<text name="spu_status_overview" text="Running: %d of %d tractors · %d of %d flows active"/>
|
||||
<text name="spu_status_startedAll" text="Started %d flows (%d tractors), %d already running, %d skipped"/>
|
||||
<text name="spu_status_stoppedAll" text="Stopped %d tractors"/>
|
||||
<text name="spu_overview_hint" text="Click a flow to edit it"/>
|
||||
<text name="spu_button_start" text="Start run"/>
|
||||
<text name="spu_button_stop" text="Stop run"/>
|
||||
<text name="spu_button_new" text="New run"/>
|
||||
@@ -63,6 +69,7 @@
|
||||
<text name="spu_tab_outbound" text="Outbound"/>
|
||||
<text name="spu_tab_storage" text="Storage"/>
|
||||
<text name="spu_section_storage" text="— Farm inventory (* = production output) —"/>
|
||||
<text name="spu_stat_pallets" text="%d/%d pallets"/>
|
||||
<text name="spu_storage_pallets" text="%d pallets"/>
|
||||
<text name="spu_storage_empty" text="No buildings with contents"/>
|
||||
<text name="spu_source_kind_husbandry" text="barn"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.19.10.0</version>
|
||||
<version>1.20.0.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
|
||||
+16
-2
@@ -1,6 +1,6 @@
|
||||
# AD Smart Pickup — brugermanual
|
||||
|
||||
Version 1.19.10 · Farming Simulator 25 · tillæg til AutoDrive
|
||||
Version 1.20.0 · Farming Simulator 25 · tillæg til AutoDrive
|
||||
|
||||
*English version: [USER_MANUAL.md](USER_MANUAL.md)*
|
||||
|
||||
@@ -137,6 +137,9 @@ Fanen **Overblik** viser alle flows som en tabel med kolonnerne **Flow**, **Vare
|
||||
**Kører** og **Status**. Det valgte flow er markeret med `>`. Kører viser traktorer i gang ud af flowets
|
||||
traktorer. Status viser en advarsel, grunden til at traktorerne holder, eller flowets regel.
|
||||
|
||||
**Klik på et flow** i tabellen for at hoppe direkte til fanen **Flows** med det flow valgt. Statuslinjen
|
||||
nederst viser, hvor mange traktorer og flows der kører i alt.
|
||||
|
||||
Tidligere stod tavlen som én lang linje pr. flow:
|
||||
|
||||
```
|
||||
@@ -161,6 +164,17 @@ samme rækkefølge.
|
||||
| **Slet run** | Sletter flowet og stopper dets kørende traktorer. Kan ikke fortrydes |
|
||||
| **Start run / Stop run** | Starter eller stopper alle traktorer i flowet |
|
||||
|
||||
På fanen **Overblik** er knapperne i stedet:
|
||||
|
||||
| Knap | Funktion |
|
||||
|---|---|
|
||||
| **Start alle flows** | Starter alle flows med traktorer. Flows, der allerede kører, røres ikke, så ingen tur afbrydes |
|
||||
| **Stop alle flows** | Stopper alle aktive traktorer i alle flows |
|
||||
| **Nyt run** | Opretter et nyt flow og hopper til fanen **Flows** |
|
||||
|
||||
Statuslinjen viser bagefter, hvor mange flows og traktorer der blev startet, og op til tre grunde til
|
||||
traktorer, der blev sprunget over. Alle grunde står i `log.txt`.
|
||||
|
||||
Vælg flow i feltet **Run** øverst. Under tavlen står detaljerne for det valgte flow.
|
||||
|
||||
### Retning
|
||||
@@ -478,7 +492,7 @@ kolonneoverskrifter øverst:
|
||||
|
||||
| Kolonne | Betydning |
|
||||
|---|---|
|
||||
| **I bygningen** | Mængde og kapacitet i den valgte bygning samt fyldningsgrad |
|
||||
| **I bygningen** | Mængde og kapacitet i den valgte bygning samt fyldningsgrad. Palleskure viser paller af ledige pladser, fx `24/4000 paller 1 %` |
|
||||
| **Værdi nu** | Værdien ved den bedste pris lige nu, blandt alle salgssteder på kortet |
|
||||
| **Ved toppris** | Værdien, hvis du sælger ved årets højeste pris |
|
||||
| **Gården** | Gårdens samlede beholdning af varen i alle bygninger, også dem på de andre faner |
|
||||
|
||||
+16
-2
@@ -1,6 +1,6 @@
|
||||
# AD Smart Pickup — user manual
|
||||
|
||||
Version 1.19.10 · Farming Simulator 25 · add-on for AutoDrive
|
||||
Version 1.20.0 · Farming Simulator 25 · add-on for AutoDrive
|
||||
|
||||
*Dansk version: [BRUGERMANUAL.md](BRUGERMANUAL.md)*
|
||||
|
||||
@@ -139,6 +139,9 @@ The **Overview** tab shows all flows as a table with the columns **Flow**, **Goo
|
||||
**Running** and **Status**. The selected flow is marked with `>`. Running shows tractors at work out of
|
||||
the flow's tractors. Status shows a warning, the reason tractors are waiting, or the flow's rule.
|
||||
|
||||
**Click a flow** in the table to jump straight to the **Flows** tab with that flow selected. The status
|
||||
line at the bottom shows how many tractors and flows are running in total.
|
||||
|
||||
Earlier the board was one long line per flow:
|
||||
|
||||
```
|
||||
@@ -163,6 +166,17 @@ the same order.
|
||||
| **Delete run** | Deletes the flow and stops its running tractors. Cannot be undone |
|
||||
| **Start run / Stop run** | Starts or stops all tractors in the flow |
|
||||
|
||||
On the **Overview** tab the buttons are instead:
|
||||
|
||||
| Button | What it does |
|
||||
|---|---|
|
||||
| **Start all flows** | Starts every flow that has tractors. Flows already running are left alone, so no trip is interrupted |
|
||||
| **Stop all flows** | Stops all active tractors in all flows |
|
||||
| **New run** | Creates a new flow and jumps to the **Flows** tab |
|
||||
|
||||
Afterwards the status line shows how many flows and tractors were started, plus up to three reasons for
|
||||
tractors that were skipped. All reasons are in `log.txt`.
|
||||
|
||||
Pick a flow in the **Run** field at the top. The details of the selected flow are shown below the board.
|
||||
|
||||
### Direction
|
||||
@@ -484,7 +498,7 @@ one row per good:
|
||||
|
||||
| Column | Meaning |
|
||||
|---|---|
|
||||
| **In building** | Amount and capacity in the selected building, plus fill level |
|
||||
| **In building** | Amount and capacity in the selected building, plus fill level. Pallet sheds show pallets out of free slots, such as `24/4000 pallets 1 %` |
|
||||
| **Value now** | The value at the best price right now, across all selling points on the map |
|
||||
| **At top price** | The value if you sell at the year's highest price |
|
||||
| **Farm** | The farm's total amount of the good across all buildings, including those on the other tabs |
|
||||
|
||||
@@ -770,5 +770,35 @@ do
|
||||
check("PM forsyning tæller ikke", pickups[9999], nil)
|
||||
end
|
||||
|
||||
-- SA: Start/Stop alle flows — kørende flows røres ikke ved Start alle; Stop alle stopper alt aktivt
|
||||
do
|
||||
buildWorld()
|
||||
local idle = makeVehicle("vehicleAllA", "Alle A", {STRAW, TMR}, 1000000, 100, 0)
|
||||
local busy = makeVehicle("vehicleAllB", "Alle B", {STRAW, TMR}, 1000000, 100, 0)
|
||||
local runA = ADRunsController.createRun("Alle-A")
|
||||
ADRunsController.updateRun(runA.id, {targetWayPointId = 94})
|
||||
ADRunsController.assignVehicle(runA.id, idle)
|
||||
local runB = ADRunsController.createRun("Alle-B")
|
||||
ADRunsController.updateRun(runB.id, {targetWayPointId = 94})
|
||||
ADRunsController.assignVehicle(runB.id, busy)
|
||||
ADRunsController.createRun("Alle-tom") -- ingen traktorer: tæller ikke med
|
||||
ADRunsController.startRun(adEnv, runB.id)
|
||||
local busyStarts = busy.started
|
||||
local summary = ADRunsController.startAllRuns(adEnv)
|
||||
check("SA idle startet", idle.started, 1)
|
||||
check("SA kørende flow ikke genstartet", busy.started, busyStarts)
|
||||
check("SA mindst ét flow startet", summary.runsStarted >= 1, true)
|
||||
check("SA kørende flow talt", summary.alreadyRunning >= 1, true)
|
||||
check("SA traktorer startet tæller idle", summary.vehiclesStarted >= 1, true)
|
||||
check("SA resultater med", type(summary.results), "table")
|
||||
check("SA noget aktivt", ADRunsController.hasActiveRuns(adEnv), true)
|
||||
local stopped = ADRunsController.stopAllRuns(adEnv)
|
||||
check("SA stop alle stopper begge", stopped >= 2, true)
|
||||
check("SA idle stoppet", idle.ad.stateModule.active, false)
|
||||
check("SA busy stoppet", busy.ad.stateModule.active, false)
|
||||
check("SA intet aktivt bagefter", ADRunsController.hasActiveRuns(adEnv), false)
|
||||
check("SA isRunning ryddet", ADRunsController.getRunStatus(adEnv, ADRuns.getRun(ADRunsController.store, runA.id)).isRunning, false)
|
||||
end
|
||||
|
||||
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||
os.exit(failures == 0 and 0 or 1)
|
||||
|
||||
@@ -323,6 +323,9 @@ check("S12 TMR-fabrik roer er input", beetEntry.isOutput, false)
|
||||
check("S12 outputs først", byName["TMR-fabrik"].entries[1].isOutput, true)
|
||||
check("S12 silo", byName["Farma"].entries[1].fillType, FORAGE)
|
||||
check("S12 objektlager kurve som antal", byName["Objektlager"].entries[1].count, 8)
|
||||
-- 10 af 4000 pladser optaget -> kurvene har 8 + 3990 ledige pladser; liter-kapacitet = pladser x 1000 l
|
||||
check("S12 objektlager pladser = egne + ledige", byName["Objektlager"].entries[1].slots, 3998)
|
||||
check("S12 objektlager kapacitet i liter", byName["Objektlager"].entries[1].capacity, 3998000)
|
||||
check("S12 stald halm", byName["Kostald"].entries[1].level, 2000)
|
||||
check("S12 stald kapacitet = niveau + fri", byName["Kostald"].entries[1].capacity, 21375)
|
||||
check("S12 tomt skur udeladt", byName["Fuldt skur"], nil)
|
||||
|
||||
@@ -70,5 +70,11 @@ check("ST9 stiger-flag", rising.rising, true)
|
||||
check("ST1 falder -> ikke stiger", st.rising, false)
|
||||
check("ST2 intet forbrug -> ikke stiger", st2.rising, false)
|
||||
|
||||
-- ST3: palleskur — procent af PLADSER (24 paller af 4000), ikke liter mod pladsantal (600 %)
|
||||
local egg = S.itemStats({fillType = 8, level = 24000, capacity = 4000000, count = 24, slots = 4000}, 24000, nil, nil)
|
||||
check("ST3 paller med", egg.count, 24)
|
||||
check("ST3 pladser med", egg.slots, 4000)
|
||||
check("ST3 procent af pladser", egg.percent, 1)
|
||||
|
||||
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||
os.exit(failures == 0 and 0 or 1)
|
||||
|
||||
Reference in New Issue
Block a user