feat: spuSellBlock slår salgssteder fra/til pr. savegame
This commit is contained in:
@@ -8,6 +8,7 @@ står i [docs/BRUGERMANUAL.md](docs/BRUGERMANUAL.md) (dansk) og [docs/USER_MANUA
|
||||
|
||||
## 1.62 — Kæder slås selv til
|
||||
|
||||
- **1.62.7** Nyt: konsolkommandoen `spuSellBlock` slår salgssteder fra og til (pr. savegame). Et salgssted, der er slået fra, bruges hverken til udkørsel eller i priserne. Til stationer, hvor aflæsningen går i stå, fx "Market Price Liquid Fill Station".
|
||||
- **1.62.6** Pålæsningsdiagnosen logger kun, når en trigger med varen er inden for 20 m (køretøjer der holder ved Wait-punkter eller marker gav falske meldinger).
|
||||
- Manualerne understreger nu, at parkering og hentning af redskaber kun virker ved at bakke: ruten til `P <navn>` og `Connect P <navn>` skal slutte som en bakrute.
|
||||
- **1.62.5** Diagnose: står AutoDrive 30 s ved et LOAD-mål uden at fylde, skriver loggen én linje med markør, vare og for hver vogn den nærmeste AD-læssetrigger (afstand, har varen, står vognen i triggerens boks). Ingen indgreb.
|
||||
|
||||
@@ -1478,6 +1478,7 @@ function ADRunsController.save()
|
||||
if ADFieldSilos ~= nil then pcall(ADFieldSilos.save) end
|
||||
-- kædens tilstand (tændte mellemled, pausede kæder, afviste forslag) — samme gem-regel som navnefilen
|
||||
if ADChain ~= nil and ADChain.save ~= nil then pcall(ADChain.save) end
|
||||
if ADSellBlock ~= nil and ADSellBlock.save ~= nil then pcall(ADSellBlock.save) end
|
||||
-- navnefilen skal skrives under spillets gem: FS25 genskriver savegame-mappen, og filer ingen skriver
|
||||
-- under gemningen forsvinder (in-game 27/9: ADSmartPickup_names.xml blev slettet ved første gem)
|
||||
if ADNames ~= nil and ADNames.byId ~= nil then pcall(ADNames.save) end
|
||||
@@ -1498,6 +1499,7 @@ function ADRunsController.load(adEnv)
|
||||
pcall(ADRunsController.migrateBuildings, adEnv)
|
||||
if ADFieldSilos ~= nil then pcall(ADFieldSilos.load) end
|
||||
if ADChain ~= nil and ADChain.load ~= nil then pcall(ADChain.load) end
|
||||
if ADSellBlock ~= nil and ADSellBlock.load ~= nil then pcall(ADSellBlock.load) end
|
||||
if ADCpResume ~= nil then pcall(ADCpResume.load) end
|
||||
local vehiclesById = getFarmVehiclesById(adEnv)
|
||||
for _, run in ipairs(store.runs) do
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
-- AD Sell Block
|
||||
-- Salgssteder spilleren har slået fra (in-game 30/9: "Market Price Liquid Fill Station" fra FarmFillStations gik i stå
|
||||
-- ved aflæsning af gylle). Konsol: spuSellBlock viser salgsstederne; spuSellBlock <del af navn> slår dem fra/til.
|
||||
-- Udkørsel (ADSources.findSellMarkers) og priser (ADSources.getMarketQuote) springer udelukkede over. Gemmes pr.
|
||||
-- savegame i ADSmartPickup_sellblock.xml (skrives fra ADRunsController.save, som de andre filer).
|
||||
|
||||
ADSellBlock = {}
|
||||
ADSellBlock.FILE_NAME = "ADSmartPickup_sellblock.xml"
|
||||
ADSellBlock.ROOT = "sellBlock"
|
||||
ADSellBlock.blocked = {} -- {[stationId] = visningsnavn}
|
||||
|
||||
-- ---- ren logik ----
|
||||
|
||||
-- stations = {{id, names = {...}}}, query = del af et navn (små/store bogstaver ligegyldige) -> matchende stationer
|
||||
function ADSellBlock.match(stations, query)
|
||||
local wanted = string.lower(tostring(query or ""))
|
||||
local hits = {}
|
||||
if wanted == "" then return hits end
|
||||
for _, station in ipairs(stations or {}) do
|
||||
for _, name in ipairs(station.names or {}) do
|
||||
if string.find(string.lower(tostring(name)), wanted, 1, true) ~= nil then
|
||||
table.insert(hits, station)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return hits
|
||||
end
|
||||
|
||||
-- Ny tabel: hver station skiftes (fra -> til, til -> fra). Første navn huskes til visning.
|
||||
function ADSellBlock.toggle(blocked, stations)
|
||||
local result = {}
|
||||
for id, name in pairs(blocked or {}) do result[id] = name end
|
||||
for _, station in ipairs(stations or {}) do
|
||||
if result[station.id] ~= nil then
|
||||
result[station.id] = nil
|
||||
else
|
||||
result[station.id] = tostring((station.names or {})[1] or station.id)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- ---- spil ----
|
||||
|
||||
local function stationId(station)
|
||||
local placeable = station ~= nil and station.owningPlaceable or nil
|
||||
if placeable ~= nil and placeable.uniqueId ~= nil then return tostring(placeable.uniqueId) end
|
||||
return nil
|
||||
end
|
||||
|
||||
function ADSellBlock.isBlocked(station)
|
||||
local id = stationId(station)
|
||||
return id ~= nil and ADSellBlock.blocked[id] ~= nil
|
||||
end
|
||||
|
||||
local function stationNames(station)
|
||||
local names = {}
|
||||
local placeable = station.owningPlaceable
|
||||
if placeable ~= nil and placeable.getName ~= nil then
|
||||
local ok, name = pcall(placeable.getName, placeable)
|
||||
if ok and name ~= nil then table.insert(names, name) end
|
||||
end
|
||||
if station.getName ~= nil then
|
||||
local ok, name = pcall(station.getName, station)
|
||||
if ok and name ~= nil then table.insert(names, name) end
|
||||
end
|
||||
return names
|
||||
end
|
||||
|
||||
-- Alle salgssteder med AD-markør -> {{id, names}} (markørens navn først: det spilleren ser i AutoDrive).
|
||||
local function sellStations(adEnv)
|
||||
local list, byId = {}, {}
|
||||
local farmId = g_currentMission:getFarmId()
|
||||
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
|
||||
local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId)
|
||||
local id = station ~= nil and ADPrices.isSellingStation(station) and stationId(station) or nil
|
||||
if id ~= nil then
|
||||
if byId[id] == nil then
|
||||
byId[id] = {id = id, names = {}}
|
||||
table.insert(list, byId[id])
|
||||
for _, name in ipairs(stationNames(station)) do table.insert(byId[id].names, name) end
|
||||
end
|
||||
table.insert(byId[id].names, 1, marker.name)
|
||||
end
|
||||
end
|
||||
table.sort(list, function(a, b) return tostring(a.names[1]) < tostring(b.names[1]) end)
|
||||
return list
|
||||
end
|
||||
|
||||
function ADSellBlock:consoleSellBlock(...)
|
||||
local query = table.concat({...}, " ")
|
||||
local adEnv = FS25_AutoDrive
|
||||
if adEnv == nil or adEnv.ADGraphManager == nil then return "AutoDrive ikke fundet" end
|
||||
local stations = sellStations(adEnv)
|
||||
if query == "" then
|
||||
local lines = {"Salgssteder (spuSellBlock <del af navn> slår fra/til):"}
|
||||
for _, station in ipairs(stations) do
|
||||
table.insert(lines, string.format(" %s %s", ADSellBlock.blocked[station.id] ~= nil and "[FRA]" or "[til]", table.concat(station.names, " / ")))
|
||||
end
|
||||
return table.concat(lines, "\n")
|
||||
end
|
||||
local hits = ADSellBlock.match(stations, query)
|
||||
if #hits == 0 then return string.format("Intet salgssted matcher '%s' (spuSellBlock uden navn viser listen)", query) end
|
||||
ADSellBlock.blocked = ADSellBlock.toggle(ADSellBlock.blocked, hits)
|
||||
local lines = {}
|
||||
for _, station in ipairs(hits) do
|
||||
local text = string.format("%s: %s", station.names[1], ADSellBlock.blocked[station.id] ~= nil and "slået FRA som salgssted" or "bruges igen")
|
||||
table.insert(lines, text)
|
||||
Logging.info("ADSmartPickup: salgssted " .. text)
|
||||
end
|
||||
if ADRunsController ~= nil and ADRunsController.save ~= nil then pcall(ADRunsController.save) end
|
||||
return table.concat(lines, "\n")
|
||||
end
|
||||
|
||||
local function getPath()
|
||||
local path = ADRunsStorage ~= nil and ADRunsStorage.getPath() or nil
|
||||
if path == nil then return nil end
|
||||
return (path:gsub(ADRunsStorage.FILE_NAME .. "$", ADSellBlock.FILE_NAME))
|
||||
end
|
||||
|
||||
function ADSellBlock.save()
|
||||
local path = getPath()
|
||||
if path == nil then return false end
|
||||
local xmlFile = XMLFile.create("ADSmartPickupSellBlock", path, ADSellBlock.ROOT)
|
||||
if xmlFile == nil then return false end
|
||||
local index = 0
|
||||
for id, name in pairs(ADSellBlock.blocked) do
|
||||
local key = string.format("%s.station(%d)", ADSellBlock.ROOT, index)
|
||||
xmlFile:setString(key .. "#id", id)
|
||||
xmlFile:setString(key .. "#name", name)
|
||||
index = index + 1
|
||||
end
|
||||
xmlFile:save()
|
||||
xmlFile:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
function ADSellBlock.load()
|
||||
ADSellBlock.blocked = {}
|
||||
local path = getPath()
|
||||
if path == nil or not fileExists(path) then return end
|
||||
local xmlFile = XMLFile.load("ADSmartPickupSellBlock", path)
|
||||
if xmlFile == nil then return end
|
||||
xmlFile:iterate(ADSellBlock.ROOT .. ".station", function(_, key)
|
||||
local id = xmlFile:getString(key .. "#id")
|
||||
if id ~= nil then ADSellBlock.blocked[id] = xmlFile:getString(key .. "#name") or id end
|
||||
end)
|
||||
xmlFile:delete()
|
||||
end
|
||||
|
||||
if addConsoleCommand ~= nil then
|
||||
addConsoleCommand("spuSellBlock", "Salgssteder: uden navn = liste; spuSellBlock <del af navn> slår fra/til", "consoleSellBlock", ADSellBlock)
|
||||
end
|
||||
@@ -644,7 +644,12 @@ function ADSources.describeAccepted(station)
|
||||
return table.concat(names, ", ")
|
||||
end
|
||||
|
||||
-- Markører hvis aflæsningsstation er et rigtigt salgssted: { {marker, station} }.
|
||||
-- Salgssted spilleren har slået fra (spuSellBlock, ADSellBlock).
|
||||
function ADSources.isSellBlocked(station)
|
||||
return ADSellBlock ~= nil and ADSellBlock.isBlocked ~= nil and ADSellBlock.isBlocked(station) == true
|
||||
end
|
||||
|
||||
-- Markører hvis aflæsningsstation er et rigtigt salgssted (og ikke slået fra): { {marker, station} }.
|
||||
function ADSources.getSellMarkers(adEnv, farmId)
|
||||
return cacheGet("sellMarkers", tostring(farmId), 10000, function() return ADSources.findSellMarkers(adEnv, farmId) end)
|
||||
end
|
||||
@@ -653,7 +658,7 @@ function ADSources.findSellMarkers(adEnv, farmId)
|
||||
local result = {}
|
||||
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
|
||||
local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId)
|
||||
if station ~= nil and ADPrices.isSellingStation(station) then
|
||||
if station ~= nil and ADPrices.isSellingStation(station) and not ADSources.isSellBlocked(station) then
|
||||
table.insert(result, {marker = marker, station = station})
|
||||
end
|
||||
end
|
||||
@@ -1002,7 +1007,7 @@ function ADSources.getMarketQuote(fillType)
|
||||
local storage = g_currentMission ~= nil and g_currentMission.storageSystem or nil
|
||||
local best = nil
|
||||
for _, station in pairs(storage ~= nil and storage:getUnloadingStations() or {}) do
|
||||
if ADPrices.isSellingStation(station) and ADSources.stationAccepts(station, fillType) then
|
||||
if ADPrices.isSellingStation(station) and not ADSources.isSellBlocked(station) and ADSources.stationAccepts(station, fillType) then
|
||||
local quote = ADPrices.getQuote(station, fillType)
|
||||
if quote ~= nil and (best == nil or quote.price > best.price) then
|
||||
best = {price = quote.price, top = quote.top}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.62.6.0</version>
|
||||
<version>1.62.7.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
@@ -33,6 +33,7 @@
|
||||
<sourceFile filename="adOutbound.lua"/>
|
||||
<sourceFile filename="adTipSide.lua"/>
|
||||
<sourceFile filename="adLoadDiag.lua"/>
|
||||
<sourceFile filename="adSellBlock.lua"/>
|
||||
<sourceFile filename="adUnloadWait.lua"/>
|
||||
<sourceFile filename="adFieldModel.lua"/>
|
||||
<sourceFile filename="adFieldFleet.lua"/>
|
||||
|
||||
@@ -1206,6 +1206,7 @@ FS25 kan ikke selv omdøbe bygninger, så moden har sine egne navne. De gemmes i
|
||||
| `spuNameFleet` | Giver alle traktorer og lastbiler uden for flows butiksnavnet (*Fendt 942 1*, *Fendt 942 2* …) og omdøber deres egen parkering til `P <navn>`, hvis ingen anden deler den. Overskriver egne navne på de køretøjer. Gem spillet bagefter. Pas på: en eksisterende `Connect <gammelt navn>`-markør passer ikke længere |
|
||||
| `spuConnect` | Kobler det nærmeste redskab (inden for ca. 3 m) på den maskine, du sidder i |
|
||||
| `spuDetach` | Kobler redskaberne bag den maskine, du sidder i, af |
|
||||
| `spuSellBlock [del af navn]` | Uden navn: viser alle salgssteder, og hvilke der er slået fra. Med navn: slår de salgssteder fra/til, hvis navn indeholder teksten (fx `spuSellBlock market price`). Et salgssted, der er slået fra, bruges hverken til udkørsel eller i priserne. Gemmes pr. savegame. Til salgssteder, hvor aflæsningen går i stå |
|
||||
| `spuTrip A > B > C` | Kører en tur over flere markører: Connect-markører kobler på, Afkobl eller redskabets egen parkering kobler af, og ved andre markører holdes der 10 sekunder. Mest til test |
|
||||
|
||||
---
|
||||
|
||||
@@ -1244,6 +1244,7 @@ Open the game's console to use them:
|
||||
| `spuNameFleet` | Gives all tractors and trucks outside flows their shop name (*Fendt 942 1*, *Fendt 942 2* …) and renames their own parking spot to `P <name>` if nobody else shares it. Overwrites custom names on those vehicles. Save the game afterwards. Note: an existing `Connect <old name>` marker no longer matches |
|
||||
| `spuConnect` | Hitches the nearest implement (within about 3 m) to the machine you are sitting in |
|
||||
| `spuDetach` | Detaches the implements behind the machine you are sitting in |
|
||||
| `spuSellBlock [part of name]` | Without a name: lists all selling points and which ones are switched off. With a name: switches off/on the selling points whose name contains the text (e.g. `spuSellBlock market price`). A switched-off selling point is used neither for outbound trips nor in prices. Saved per savegame. For selling points where unloading keeps stalling |
|
||||
| `spuTrip A > B > C` | Drives a trip over several markers: Connect markers hitch, Afkobl or the implement's own parking detach, and at other markers it stops for 10 seconds. Mostly for testing |
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user