feat(gui): guiden "Opsæt flow" — Flows-fanen får tavle + resumé (klik = ret ét trin, Navn = omdøb) og trin-for-trin-guide på samme ramme som markguiden; Nyt flow oprettes først ved Gem (v1.32.0.0)
This commit is contained in:
@@ -0,0 +1,447 @@
|
||||
-- AD Flow Guide
|
||||
-- "Opsæt flow": flowguidens trin oven på ADGuide (ren Lua, ingen spil-API) — samme trin-skærm og knapper
|
||||
-- som markguiden. Kladden er en kopi af flowets felter, så intet ændres før [Gem]/[Start flow]. Det
|
||||
-- spil-afhængige kommer i `context` (GUI'et henter det ud fra kladden, se previewRun):
|
||||
-- {buildings = {{id, name, label, hasMarker, text}} -- kandidater til Fra (udkørsel) / Til (forsyning)
|
||||
-- fillTypes = {{name, title}} -- varer målet tager (forsyning, Vælg selv)
|
||||
-- products = {{name, title}} -- varer kilderne har (udkørsel)
|
||||
-- storeBuildings = {{id, name, text}} -- lagre der kan tage flowets lagervarer
|
||||
-- waitPools = {{group, count}}
|
||||
-- vehicles = {{id, label, text, otherRunId, otherRunName, blocked}}} -- label = kort navn (resumé)
|
||||
-- Gem: ADRunsController.createRun/updateRun + assignVehicle/unassignVehicle (GUI'et).
|
||||
|
||||
ADFlowGuide = {}
|
||||
|
||||
ADFlowGuide.ORDER = {"name", "direction", "buildings", "goods", "store", "rules", "wait", "tractors", "summary"}
|
||||
ADFlowGuide.POLICIES = {"off", "store", "sell", "sellElseStore"}
|
||||
ADFlowGuide.MAX_NAMED_TRACTORS = 3
|
||||
ADFlowGuide.MAX_NAMED_GOODS = 3
|
||||
|
||||
local function L(key, args) return {key = key, args = args} end
|
||||
local function T(text) return {text = text} end
|
||||
|
||||
local function isOut(guide) return guide.draft.kind == "outbound" end
|
||||
|
||||
local function hasStorePolicy(draft)
|
||||
for _, product in ipairs(draft.products or {}) do
|
||||
if product.policy == "store" or product.policy == "sellElseStore" then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local VISIBLE = {
|
||||
name = function(guide) return guide.draft.isNew == true end,
|
||||
store = function(guide) return isOut(guide) and hasStorePolicy(guide.draft) end,
|
||||
}
|
||||
|
||||
function ADFlowGuide.isVisible(step, guide)
|
||||
local rule = VISIBLE[step]
|
||||
if rule ~= nil then return rule(guide) == true end
|
||||
for _, id in ipairs(ADFlowGuide.ORDER) do
|
||||
if id == step then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
ADFlowGuide.DEF = {order = ADFlowGuide.ORDER, isVisible = ADFlowGuide.isVisible}
|
||||
|
||||
-- Overskrift pr. trin; "Fra"/"Til" følger retningen.
|
||||
function ADFlowGuide.stepKey(step, guide)
|
||||
if step == "buildings" then
|
||||
return (guide ~= nil and isOut(guide)) and "spu_guide_flow_step_from" or "spu_guide_flow_step_to"
|
||||
end
|
||||
return "spu_guide_flow_step_" .. tostring(step)
|
||||
end
|
||||
|
||||
local KIND_HINTS = {buildings = true, goods = true, rules = true}
|
||||
function ADFlowGuide.hintKey(step, guide)
|
||||
if KIND_HINTS[step] then
|
||||
return "spu_guide_flow_hint_" .. step .. ((guide ~= nil and isOut(guide)) and "_out" or "_in")
|
||||
end
|
||||
return "spu_guide_flow_hint_" .. tostring(step)
|
||||
end
|
||||
|
||||
-- ---- kladde ----
|
||||
|
||||
local RUN_FIELDS = {
|
||||
"id", "name", "kind", "sourceBuildingIds", "targetBuildingIds", "storeBuildingIds", "products",
|
||||
"ingredientMode", "ingredients", "sellAtPercent", "storeAbovePercent", "collectRound", "loops",
|
||||
"returnBelowPercent", "waitPoolGroup", "vehicleIds",
|
||||
}
|
||||
|
||||
local function draftFrom(run, isNew)
|
||||
local draft = {}
|
||||
for _, key in ipairs(RUN_FIELDS) do draft[key] = ADGuide.deepCopy(run[key]) end
|
||||
for _, key in ipairs({"sourceBuildingIds", "targetBuildingIds", "storeBuildingIds", "products", "ingredients", "vehicleIds"}) do
|
||||
draft[key] = draft[key] or {}
|
||||
end
|
||||
draft.kind = draft.kind == "outbound" and "outbound" or "supply"
|
||||
draft.ingredientMode = draft.ingredientMode == "manual" and "manual" or "auto"
|
||||
draft.sellAtPercent = draft.sellAtPercent or ADRuns.DEFAULT_SELL_AT_PERCENT
|
||||
draft.storeAbovePercent = draft.storeAbovePercent or ADRuns.DEFAULT_STORE_ABOVE_PERCENT
|
||||
draft.returnBelowPercent = draft.returnBelowPercent or ADRuns.DEFAULT_RETURN_BELOW_PERCENT
|
||||
draft.loops = draft.loops or 0
|
||||
draft.waitPoolGroup = draft.waitPoolGroup or ""
|
||||
draft.collectRound = draft.collectRound == true
|
||||
draft.isNew = isNew == true
|
||||
draft.showAllBuildings = false
|
||||
draft.storeAuto = #draft.storeBuildingIds == 0
|
||||
return draft
|
||||
end
|
||||
|
||||
function ADFlowGuide.open(run, context, options)
|
||||
return ADGuide.new(ADFlowGuide.DEF, draftFrom(run, false), context, options)
|
||||
end
|
||||
|
||||
-- Nyt flow: intet oprettes før [Gem]; kladden har standardværdierne fra ADRuns.createRun.
|
||||
function ADFlowGuide.openNew(name, context)
|
||||
local _, run = ADRuns.createRun(ADRuns.newStore(), name, "supply")
|
||||
local draft = draftFrom(run, true)
|
||||
draft.id = nil
|
||||
return ADGuide.new(ADFlowGuide.DEF, draft, context)
|
||||
end
|
||||
|
||||
-- Run-formet tabel til controllerens opslag (varer, vogne) før noget er gemt: markører fra de valgte
|
||||
-- bygninger. markerIds(buildingId, role) -> {wayPointId, ...}.
|
||||
function ADFlowGuide.previewRun(draft, markerIds)
|
||||
local run = ADGuide.deepCopy(draft)
|
||||
local function resolve(ids, role)
|
||||
local result, seen = {}, {}
|
||||
for _, buildingId in ipairs(ids or {}) do
|
||||
for _, wayPointId in ipairs(markerIds(buildingId, role) or {}) do
|
||||
if not seen[wayPointId] then
|
||||
seen[wayPointId] = true
|
||||
table.insert(result, wayPointId)
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
run.sourceWayPointIds = resolve(draft.sourceBuildingIds, "load")
|
||||
run.targetWayPointIds = resolve(draft.targetBuildingIds, "unload")
|
||||
run.targetWayPointId = run.targetWayPointIds[1]
|
||||
return run
|
||||
end
|
||||
|
||||
-- ---- valg ----
|
||||
|
||||
local SET_VALUES = {
|
||||
kind = true, ingredientMode = true, sellAtPercent = true, storeAbovePercent = true, loops = true,
|
||||
returnBelowPercent = true, waitPoolGroup = true,
|
||||
}
|
||||
local BOOL_VALUES = {showAllBuildings = true, storeAuto = true, collectRound = true}
|
||||
local LIST_VALUES = {ingredients = true, storeBuildingIds = true, vehicleIds = true}
|
||||
|
||||
local function setPolicy(products, name, policy)
|
||||
local result = {}
|
||||
for _, product in ipairs(products or {}) do
|
||||
if product.fillType ~= name then table.insert(result, {fillType = product.fillType, policy = product.policy}) end
|
||||
end
|
||||
if policy ~= "off" then table.insert(result, {fillType = name, policy = policy}) end
|
||||
return result
|
||||
end
|
||||
|
||||
function ADFlowGuide.choose(guide, id, value)
|
||||
local draft = ADGuide.deepCopy(guide.draft)
|
||||
if SET_VALUES[id] then
|
||||
draft[id] = value
|
||||
elseif BOOL_VALUES[id] then
|
||||
draft[id] = value == true
|
||||
elseif LIST_VALUES[id] then
|
||||
draft[id] = ADGuide.toggleItem(draft[id], value.item, value.on)
|
||||
elseif id == "buildings" then
|
||||
local key = draft.kind == "outbound" and "sourceBuildingIds" or "targetBuildingIds"
|
||||
draft[key] = ADGuide.toggleItem(draft[key], value.item, value.on)
|
||||
elseif id == "policy" then
|
||||
draft.products = setPolicy(draft.products, value.item, value.value)
|
||||
elseif id == "name" then
|
||||
if type(value) ~= "string" or not value:match("%S") then return guide end
|
||||
draft.name = value
|
||||
else
|
||||
return guide
|
||||
end
|
||||
return ADGuide.withDraft(guide, draft)
|
||||
end
|
||||
|
||||
-- ---- rækker ----
|
||||
|
||||
local function choice(id, title, options, value, item)
|
||||
return {type = "choice", id = id, title = title, options = options, value = value, item = item}
|
||||
end
|
||||
|
||||
local function toggle(id, title, value)
|
||||
return {type = "toggle", id = id, title = title, off = L("ui_no"), on = L("ui_yes"), value = value == true}
|
||||
end
|
||||
|
||||
local function check(id, item, text, value)
|
||||
return {type = "check", id = id, item = item, title = T(text), value = value == true}
|
||||
end
|
||||
|
||||
local function text(key, args) return {type = "text", label = L(key, args)} end
|
||||
|
||||
local function percentOptions(from, to, step)
|
||||
local options = {}
|
||||
for percent = from, to, step do table.insert(options, {label = T(string.format("%d %%", percent)), value = percent}) end
|
||||
return options
|
||||
end
|
||||
|
||||
local function chosenSet(list)
|
||||
local set = {}
|
||||
for _, value in ipairs(list or {}) do set[value] = true end
|
||||
return set
|
||||
end
|
||||
|
||||
local function buildingIds(draft)
|
||||
return draft.kind == "outbound" and draft.sourceBuildingIds or draft.targetBuildingIds
|
||||
end
|
||||
|
||||
local function rowsName(guide)
|
||||
return {
|
||||
{type = "text", label = T(guide.draft.name or "")},
|
||||
{type = "link", id = "rename", value = true, label = L("spu_guide_flow_rename")},
|
||||
}
|
||||
end
|
||||
|
||||
local function rowsDirection(guide)
|
||||
return {choice("kind", L("spu_direction"), {
|
||||
{label = L("spu_direction_in"), value = "supply"}, {label = L("spu_direction_out"), value = "outbound"}}, guide.draft.kind)}
|
||||
end
|
||||
|
||||
-- Bygninger i fast rækkefølge (navn, markør); uden markør kun med "Vis alle" (eller når valgt).
|
||||
local function rowsBuildings(guide)
|
||||
local draft, rows = guide.draft, {}
|
||||
local chosen = chosenSet(buildingIds(draft))
|
||||
local candidates = guide.context.buildings or {}
|
||||
local shown = ADFlowView.buildingRows(candidates, chosen, draft.showAllBuildings)
|
||||
local hidden = ADFlowView.hiddenCount(candidates, shown)
|
||||
if hidden > 0 or draft.showAllBuildings then
|
||||
table.insert(rows, toggle("showAllBuildings", L("spu_showAllBuildings", {hidden}), draft.showAllBuildings))
|
||||
end
|
||||
for _, building in ipairs(shown) do
|
||||
table.insert(rows, check("buildings", building.id, building.text or building.name, chosen[building.id]))
|
||||
end
|
||||
if #shown == 0 then table.insert(rows, text("spu_noBuildings")) end
|
||||
return rows
|
||||
end
|
||||
|
||||
local function rowsGoods(guide)
|
||||
local draft, context, rows = guide.draft, guide.context, {}
|
||||
if isOut(guide) then
|
||||
local products = context.products or {}
|
||||
if #products == 0 then return {text("spu_guide_flow_noProducts")} end
|
||||
local options = {}
|
||||
for _, policy in ipairs(ADFlowGuide.POLICIES) do table.insert(options, {label = L("spu_policy_" .. policy), value = policy}) end
|
||||
for _, product in ipairs(products) do
|
||||
table.insert(rows, choice("policy", T(product.text or product.title), options, ADRuns.getProductPolicy(draft, product.name), product.name))
|
||||
end
|
||||
return rows
|
||||
end
|
||||
table.insert(rows, choice("ingredientMode", L("spu_guide_flow_goods"), {
|
||||
{label = L("spu_guide_flow_goodsAutoChoice"), value = "auto"}, {label = L("spu_guide_manual"), value = "manual"}}, draft.ingredientMode))
|
||||
if draft.ingredientMode ~= "manual" then
|
||||
table.insert(rows, text("spu_guide_flow_goodsAutoText"))
|
||||
return rows
|
||||
end
|
||||
local chosen = chosenSet(draft.ingredients)
|
||||
for _, fillType in ipairs(context.fillTypes or {}) do
|
||||
table.insert(rows, check("ingredients", fillType.name, " " .. tostring(fillType.title), chosen[fillType.name]))
|
||||
end
|
||||
if #(context.fillTypes or {}) == 0 then table.insert(rows, text("spu_guide_flow_noGoodsTo")) end
|
||||
return rows
|
||||
end
|
||||
|
||||
local function rowsStore(guide)
|
||||
local draft, rows = guide.draft, {}
|
||||
table.insert(rows, choice("storeAuto", L("spu_guide_store"), {
|
||||
{label = L("spu_guide_flow_storeAutoChoice"), value = true}, {label = L("spu_guide_manual"), value = false}}, draft.storeAuto))
|
||||
if draft.storeAuto then
|
||||
table.insert(rows, text("spu_guide_flow_storeAutoText"))
|
||||
return rows
|
||||
end
|
||||
local chosen = chosenSet(draft.storeBuildingIds)
|
||||
for _, building in ipairs(guide.context.storeBuildings or {}) do
|
||||
table.insert(rows, check("storeBuildingIds", building.id, building.text, chosen[building.id]))
|
||||
end
|
||||
if #(guide.context.storeBuildings or {}) == 0 then table.insert(rows, text("spu_noBuildings")) end
|
||||
return rows
|
||||
end
|
||||
|
||||
local function rowsRules(guide)
|
||||
local draft = guide.draft
|
||||
if isOut(guide) then
|
||||
return {
|
||||
choice("sellAtPercent", L("spu_sellAt"), percentOptions(ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT, 5), draft.sellAtPercent),
|
||||
choice("storeAbovePercent", L("spu_storeAbove"), percentOptions(ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT, 5), draft.storeAbovePercent),
|
||||
toggle("collectRound", L("spu_collectRound"), draft.collectRound),
|
||||
}
|
||||
end
|
||||
local loops = {{label = L("spu_loops_infinite"), value = 0}}
|
||||
for count = 1, ADRuns.MAX_LOOPS do table.insert(loops, {label = T(tostring(count)), value = count}) end
|
||||
return {
|
||||
choice("loops", L("spu_loops"), loops, draft.loops),
|
||||
choice("returnBelowPercent", L("spu_returnBelow"), percentOptions(ADRuns.MIN_RETURN_BELOW_PERCENT, ADRuns.MAX_RETURN_BELOW_PERCENT, 10), draft.returnBelowPercent),
|
||||
}
|
||||
end
|
||||
|
||||
local function rowsWait(guide)
|
||||
local options = {{label = L("spu_waitPool_all"), value = ""}}
|
||||
for _, pool in ipairs(guide.context.waitPools or {}) do
|
||||
table.insert(options, {label = T(string.format("%s (%d)", tostring(pool.group), pool.count or 0)), value = pool.group})
|
||||
end
|
||||
return {choice("waitPoolGroup", L("spu_waitPool"), options, guide.draft.waitPoolGroup or "")}
|
||||
end
|
||||
|
||||
-- Traktorer: flowets egne først, så de ledige. Traktorer i andre flows og blokerede (vognen passer ikke)
|
||||
-- skjules med en linje hver.
|
||||
local function rowsTractors(guide)
|
||||
local draft, rows = guide.draft, {}
|
||||
local inRun = chosenSet(draft.vehicleIds)
|
||||
local entries = {}
|
||||
local other, blocked = 0, 0
|
||||
for _, vehicle in ipairs(guide.context.vehicles or {}) do
|
||||
local state = "free"
|
||||
if inRun[vehicle.id] then
|
||||
state = "in"
|
||||
elseif vehicle.otherRunId ~= nil and vehicle.otherRunId ~= draft.id then
|
||||
state = "other"
|
||||
other = other + 1
|
||||
elseif vehicle.blocked then
|
||||
state = "blocked"
|
||||
blocked = blocked + 1
|
||||
end
|
||||
table.insert(entries, {id = vehicle.id, label = tostring(vehicle.text), state = state})
|
||||
end
|
||||
for _, entry in ipairs(ADFlowView.vehicleRows(entries, false)) do
|
||||
table.insert(rows, check("vehicleIds", entry.id, entry.label, entry.state == "in"))
|
||||
end
|
||||
if #rows == 0 then table.insert(rows, text("spu_guide_flow_noTractors")) end
|
||||
if other > 0 then table.insert(rows, text("spu_guide_flow_otherFlows", {other})) end
|
||||
if blocked > 0 then table.insert(rows, text("spu_guide_flow_blocked", {blocked})) end
|
||||
return rows
|
||||
end
|
||||
|
||||
local function rowsSummary(guide)
|
||||
local rows = {}
|
||||
for _, line in ipairs(ADFlowGuide.summary(guide)) do
|
||||
table.insert(rows, {type = "link", id = "jump", value = line.step, line = line})
|
||||
end
|
||||
return rows
|
||||
end
|
||||
|
||||
local ROWS = {
|
||||
name = rowsName, direction = rowsDirection, buildings = rowsBuildings, goods = rowsGoods, store = rowsStore,
|
||||
rules = rowsRules, wait = rowsWait, tractors = rowsTractors, summary = rowsSummary,
|
||||
}
|
||||
|
||||
function ADFlowGuide.rows(guide)
|
||||
local builder = ROWS[guide.step]
|
||||
return builder ~= nil and builder(guide) or {}
|
||||
end
|
||||
|
||||
-- ---- resumé ----
|
||||
|
||||
-- Korte navne til resuméet (field, ellers navn, ellers rækkens tekst).
|
||||
local function namesFor(ids, entries, field)
|
||||
local byId = {}
|
||||
for _, entry in ipairs(entries or {}) do byId[entry.id or entry.name] = entry[field] or entry.name or entry.text end
|
||||
local names = {}
|
||||
for _, id in ipairs(ids or {}) do table.insert(names, tostring(byId[id] or id)) end
|
||||
return names
|
||||
end
|
||||
|
||||
local SUMMARY = {
|
||||
name = function(guide) return {T(guide.draft.name or "")} end,
|
||||
direction = function(guide) return {L(isOut(guide) and "spu_direction_out" or "spu_direction_in")} end,
|
||||
buildings = function(guide)
|
||||
local names = namesFor(buildingIds(guide.draft), guide.context.buildings, "name")
|
||||
if #names == 0 then return {L("spu_guide_flow_none")} end
|
||||
return {T(ADFlowView.joinCounted(names, " + ", ""))}
|
||||
end,
|
||||
goods = function(guide)
|
||||
local draft = guide.draft
|
||||
if isOut(guide) then
|
||||
local parts = {}
|
||||
local titles = {}
|
||||
for _, product in ipairs(guide.context.products or {}) do titles[product.name] = product.title end
|
||||
for _, product in ipairs(draft.products or {}) do
|
||||
table.insert(parts, {key = "spu_policy_" .. product.policy, prefix = tostring(titles[product.fillType] or product.fillType) .. ": "})
|
||||
end
|
||||
if #parts == 0 then return {L("spu_guide_flow_none")} end
|
||||
return parts
|
||||
end
|
||||
if draft.ingredientMode ~= "manual" then return {L("spu_guide_flow_goodsAuto")} end
|
||||
if #draft.ingredients == 0 then return {L("spu_guide_flow_none")} end
|
||||
if #draft.ingredients > ADFlowGuide.MAX_NAMED_GOODS then return {L("spu_guide_flow_sumGoods", {#draft.ingredients})} end
|
||||
local byName = {}
|
||||
for _, fillType in ipairs(guide.context.fillTypes or {}) do byName[fillType.name] = fillType.title end
|
||||
local names = {}
|
||||
for _, name in ipairs(draft.ingredients) do table.insert(names, tostring(byName[name] or name)) end
|
||||
return {T(table.concat(names, " + "))}
|
||||
end,
|
||||
store = function(guide)
|
||||
local draft = guide.draft
|
||||
if draft.storeAuto or #draft.storeBuildingIds == 0 then return {L("spu_guide_sum_auto")} end
|
||||
if #draft.storeBuildingIds > 2 then return {L("spu_guide_sum_stores", {#draft.storeBuildingIds})} end
|
||||
return {T(table.concat(namesFor(draft.storeBuildingIds, guide.context.storeBuildings, "name"), " + "))}
|
||||
end,
|
||||
rules = function(guide)
|
||||
local draft = guide.draft
|
||||
if isOut(guide) then
|
||||
local parts = {L("spu_guide_flow_sumSellAt", {draft.sellAtPercent}), L("spu_guide_flow_sumStoreAbove", {draft.storeAbovePercent})}
|
||||
if draft.collectRound then table.insert(parts, L("spu_guide_flow_sumRound")) end
|
||||
return parts
|
||||
end
|
||||
local loops = (draft.loops or 0) > 0 and L("spu_guide_flow_sumLoops", {draft.loops}) or L("spu_guide_flow_sumLoopsInf")
|
||||
return {loops, L("spu_guide_flow_sumReturn", {draft.returnBelowPercent})}
|
||||
end,
|
||||
wait = function(guide)
|
||||
local group = guide.draft.waitPoolGroup or ""
|
||||
return {group == "" and L("spu_waitPool_all") or T(group)}
|
||||
end,
|
||||
tractors = function(guide)
|
||||
local ids = guide.draft.vehicleIds
|
||||
if #ids == 0 then return {L("spu_guide_flow_sumNoTractors")} end
|
||||
if #ids > ADFlowGuide.MAX_NAMED_TRACTORS then return {L("spu_guide_flow_sumTractors", {#ids})} end
|
||||
return {T(table.concat(namesFor(ids, guide.context.vehicles, "label"), ", "))}
|
||||
end,
|
||||
}
|
||||
|
||||
-- Resumé-linjer {step, title, parts}: Navn (altid) + de synlige trin.
|
||||
function ADFlowGuide.summary(guide)
|
||||
local lines = {}
|
||||
for _, step in ipairs(ADFlowGuide.ORDER) do
|
||||
local build = SUMMARY[step]
|
||||
if build ~= nil and (step == "name" or ADFlowGuide.isVisible(step, guide)) then
|
||||
table.insert(lines, {step = step, title = L(ADFlowGuide.stepKey(step, guide)), parts = build(guide)})
|
||||
end
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
-- ---- gem ----
|
||||
|
||||
function ADFlowGuide.result(guide)
|
||||
local draft = guide.draft
|
||||
local storeIds = ADGuide.deepCopy(draft.storeBuildingIds)
|
||||
if ADFlowGuide.isVisible("store", guide) and draft.storeAuto then storeIds = {} end
|
||||
local changes = {
|
||||
kind = draft.kind, sourceBuildingIds = ADGuide.deepCopy(draft.sourceBuildingIds),
|
||||
targetBuildingIds = ADGuide.deepCopy(draft.targetBuildingIds), storeBuildingIds = storeIds,
|
||||
products = ADGuide.deepCopy(draft.products), ingredientMode = draft.ingredientMode,
|
||||
ingredients = ADGuide.deepCopy(draft.ingredients), sellAtPercent = draft.sellAtPercent,
|
||||
storeAbovePercent = draft.storeAbovePercent, collectRound = draft.collectRound, loops = draft.loops,
|
||||
returnBelowPercent = draft.returnBelowPercent, waitPoolGroup = draft.waitPoolGroup or "",
|
||||
}
|
||||
if draft.name ~= nil and draft.name:match("%S") then changes.name = draft.name end
|
||||
return {isNew = draft.isNew == true, runId = draft.id, name = draft.name, kind = draft.kind, changes = changes,
|
||||
vehicleIds = ADGuide.deepCopy(draft.vehicleIds)}
|
||||
end
|
||||
|
||||
-- Traktorer der skal tildeles/fjernes efter gem.
|
||||
function ADFlowGuide.vehicleChanges(oldIds, newIds)
|
||||
local old, new = chosenSet(oldIds), chosenSet(newIds)
|
||||
local added, removed = {}, {}
|
||||
for _, id in ipairs(newIds or {}) do if not old[id] then table.insert(added, id) end end
|
||||
for _, id in ipairs(oldIds or {}) do if not new[id] then table.insert(removed, id) end end
|
||||
return added, removed
|
||||
end
|
||||
Reference in New Issue
Block a user