feat: run-model v2 — retning, kilder, varepolitik, tærskler, runde (XML v2 + v1-migration)
This commit is contained in:
@@ -9,8 +9,14 @@ ADRuns.MAX_LOOPS = 99
|
||||
-- "Kør hjem fra Wait når målet er under X %": 10..90, standard 50 (= den gamle 50 %-regel).
|
||||
ADRuns.DEFAULT_RETURN_BELOW_PERCENT = 50
|
||||
ADRuns.MIN_RETURN_BELOW_PERCENT, ADRuns.MAX_RETURN_BELOW_PERCENT = 10, 90
|
||||
ADRuns.XML_VERSION = 1
|
||||
ADRuns.XML_VERSION = 2
|
||||
ADRuns.INGREDIENT_MODES = {auto = true, manual = true}
|
||||
-- Retning: Forsyning (ind til stald/fabrik) eller Udkørsel (fabrik/lager -> silo/salg).
|
||||
ADRuns.KINDS = {supply = true, outbound = true}
|
||||
-- Politik pr. vare i et udkørsels-run; "off" = varen er ikke med (fjernes fra listen).
|
||||
ADRuns.POLICIES = {store = true, sell = true, sellElseStore = true}
|
||||
ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT = 90, 50, 100
|
||||
ADRuns.DEFAULT_STORE_ABOVE_PERCENT, ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT = 80, 50, 95
|
||||
|
||||
local function copyList(list)
|
||||
local copy = {}
|
||||
@@ -20,10 +26,29 @@ local function copyList(list)
|
||||
return copy
|
||||
end
|
||||
|
||||
local function copyProducts(products)
|
||||
local copy = {}
|
||||
for index, product in ipairs(products or {}) do
|
||||
copy[index] = {fillType = product.fillType, policy = product.policy}
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
local function clampRange(value, default, min, max)
|
||||
local number = tonumber(value) or default
|
||||
return math.max(min, math.min(max, math.floor(number)))
|
||||
end
|
||||
|
||||
local function copyRun(run)
|
||||
return {
|
||||
id = run.id,
|
||||
name = run.name,
|
||||
kind = run.kind,
|
||||
sourceWayPointIds = copyList(run.sourceWayPointIds),
|
||||
products = copyProducts(run.products),
|
||||
sellAtPercent = run.sellAtPercent,
|
||||
storeAbovePercent = run.storeAbovePercent,
|
||||
collectRound = run.collectRound,
|
||||
targetWayPointId = run.targetWayPointId,
|
||||
targetWayPointIds = copyList(run.targetWayPointIds),
|
||||
ingredientMode = run.ingredientMode,
|
||||
@@ -57,11 +82,17 @@ function ADRuns.newStore()
|
||||
return {nextId = 1, runs = {}}
|
||||
end
|
||||
|
||||
function ADRuns.createRun(store, name)
|
||||
function ADRuns.createRun(store, name, kind)
|
||||
local new = copyStore(store)
|
||||
local run = {
|
||||
id = new.nextId,
|
||||
name = name,
|
||||
kind = ADRuns.KINDS[kind] and kind or "supply",
|
||||
sourceWayPointIds = {},
|
||||
products = {},
|
||||
sellAtPercent = ADRuns.DEFAULT_SELL_AT_PERCENT,
|
||||
storeAbovePercent = ADRuns.DEFAULT_STORE_ABOVE_PERCENT,
|
||||
collectRound = false,
|
||||
targetWayPointId = nil,
|
||||
targetWayPointIds = {},
|
||||
ingredientMode = "auto",
|
||||
@@ -119,9 +150,84 @@ function ADRuns.updateRun(store, runId, changes)
|
||||
if changes.waitPoolGroup ~= nil then run.waitPoolGroup = changes.waitPoolGroup end
|
||||
if changes.loops ~= nil then run.loops = clampLoops(changes.loops) end
|
||||
if changes.returnBelowPercent ~= nil then run.returnBelowPercent = clampPercent(changes.returnBelowPercent) end
|
||||
if ADRuns.KINDS[changes.kind] then run.kind = changes.kind end
|
||||
if changes.sourceWayPointIds ~= nil then run.sourceWayPointIds = copyList(changes.sourceWayPointIds) end
|
||||
if changes.products ~= nil then run.products = copyProducts(changes.products) end
|
||||
if changes.sellAtPercent ~= nil then run.sellAtPercent = clampRange(changes.sellAtPercent, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT) end
|
||||
if changes.storeAbovePercent ~= nil then run.storeAbovePercent = clampRange(changes.storeAbovePercent, ADRuns.DEFAULT_STORE_ABOVE_PERCENT, ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT) end
|
||||
if changes.collectRound ~= nil then run.collectRound = changes.collectRound == true end
|
||||
return new
|
||||
end
|
||||
|
||||
-- ---- udkørsel: kilder og varer ----
|
||||
|
||||
-- Tilføj/fjern en kilde-markør (afkrydsning i fanen Udkørsel).
|
||||
function ADRuns.toggleSource(store, runId, wayPointId)
|
||||
local run = ADRuns.getRun(store, runId)
|
||||
if run == nil then
|
||||
return copyStore(store)
|
||||
end
|
||||
local sources, found = {}, false
|
||||
for _, id in ipairs(run.sourceWayPointIds) do
|
||||
if id == wayPointId then
|
||||
found = true
|
||||
else
|
||||
table.insert(sources, id)
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
table.insert(sources, wayPointId)
|
||||
end
|
||||
return ADRuns.updateRun(store, runId, {sourceWayPointIds = sources})
|
||||
end
|
||||
|
||||
function ADRuns.getProductPolicy(run, fillTypeName)
|
||||
for _, product in ipairs(run.products or {}) do
|
||||
if product.fillType == fillTypeName then
|
||||
return product.policy
|
||||
end
|
||||
end
|
||||
return "off"
|
||||
end
|
||||
|
||||
-- policy "off" fjerner varen; ukendt politik ignoreres (store uændret).
|
||||
function ADRuns.setProductPolicy(store, runId, fillTypeName, policy)
|
||||
local run = ADRuns.getRun(store, runId)
|
||||
if run == nil or (policy ~= "off" and not ADRuns.POLICIES[policy]) then
|
||||
return copyStore(store)
|
||||
end
|
||||
local products = {}
|
||||
for _, product in ipairs(run.products) do
|
||||
if product.fillType ~= fillTypeName then
|
||||
table.insert(products, product)
|
||||
end
|
||||
end
|
||||
if policy ~= "off" then
|
||||
table.insert(products, {fillType = fillTypeName, policy = policy})
|
||||
end
|
||||
return ADRuns.updateRun(store, runId, {products = products})
|
||||
end
|
||||
|
||||
-- "SUGAR:sell FORAGE:store" — navne er stabile på tværs af mods, fillType-indeks er det ikke.
|
||||
function ADRuns.serializeProducts(products)
|
||||
local parts = {}
|
||||
for _, product in ipairs(products or {}) do
|
||||
table.insert(parts, product.fillType .. ":" .. product.policy)
|
||||
end
|
||||
return table.concat(parts, " ")
|
||||
end
|
||||
|
||||
function ADRuns.parseProducts(text)
|
||||
local products = {}
|
||||
for token in string.gmatch(tostring(text or ""), "%S+") do
|
||||
local name, policy = string.match(token, "^([^:]+):(%a+)$")
|
||||
if name ~= nil and ADRuns.POLICIES[policy] then
|
||||
table.insert(products, {fillType = name, policy = policy})
|
||||
end
|
||||
end
|
||||
return products
|
||||
end
|
||||
|
||||
-- Tilføj/fjern et mål (afkrydsning i fanen).
|
||||
function ADRuns.toggleTarget(store, runId, wayPointId)
|
||||
local run = ADRuns.getRun(store, runId)
|
||||
@@ -211,6 +317,12 @@ function ADRuns.toRecords(store)
|
||||
loops = run.loops,
|
||||
returnBelow = run.returnBelowPercent,
|
||||
vehicleIds = copyList(run.vehicleIds),
|
||||
kind = run.kind,
|
||||
sources = table.concat(run.sourceWayPointIds or {}, " "),
|
||||
products = ADRuns.serializeProducts(run.products),
|
||||
sellAt = run.sellAtPercent,
|
||||
storeAbove = run.storeAbovePercent,
|
||||
collectRound = run.collectRound and 1 or 0,
|
||||
}
|
||||
end
|
||||
return records
|
||||
@@ -232,9 +344,20 @@ function ADRuns.fromRecords(records)
|
||||
if #targets == 0 and target ~= nil and target > 0 then
|
||||
targets = {target}
|
||||
end
|
||||
local sources = {}
|
||||
for token in string.gmatch(tostring(record.sources or ""), "%S+") do
|
||||
local wayPointId = tonumber(token)
|
||||
if wayPointId ~= nil and wayPointId > 0 then table.insert(sources, wayPointId) end
|
||||
end
|
||||
table.insert(store.runs, {
|
||||
id = id,
|
||||
name = record.name,
|
||||
kind = ADRuns.KINDS[record.kind] and record.kind or "supply",
|
||||
sourceWayPointIds = sources,
|
||||
products = ADRuns.parseProducts(record.products),
|
||||
sellAtPercent = clampRange(record.sellAt, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT),
|
||||
storeAbovePercent = clampRange(record.storeAbove, ADRuns.DEFAULT_STORE_ABOVE_PERCENT, ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT),
|
||||
collectRound = tonumber(record.collectRound) == 1,
|
||||
targetWayPointId = targets[1],
|
||||
targetWayPointIds = targets,
|
||||
ingredientMode = ADRuns.INGREDIENT_MODES[record.ingredientMode] and record.ingredientMode or "auto",
|
||||
|
||||
Reference in New Issue
Block a user