feat(marker): markflåde — rolle fra redskab, valg af nærmeste ledige sæt m. bredde-regler
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
-- AD Field Fleet
|
||||
-- Markflåden som ren logik: hvilken rolle et sæt har ud fra redskabernes specs, og hvilket ledigt sæt
|
||||
-- der sendes til en mark. Kun sæt med flueben bruges; et sæt spilleren sidder i, røres aldrig.
|
||||
|
||||
ADFieldFleet = {}
|
||||
|
||||
-- Rækkefølge = prioritet når et køretøj har flere (læssevogn med egen pickup m.m.)
|
||||
ADFieldFleet.ROLE_SPECS = {
|
||||
{role = "collector", spec = "spec_forageWagon"},
|
||||
{role = "rake", spec = "spec_windrower"},
|
||||
{role = "tedder", spec = "spec_tedder"},
|
||||
{role = "mower", spec = "spec_mower"},
|
||||
}
|
||||
|
||||
function ADFieldFleet.roleFromSpecs(specs)
|
||||
for _, entry in ipairs(ADFieldFleet.ROLE_SPECS) do
|
||||
if specs[entry.spec] then return entry.role end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Nærmeste brugbare sæt til rollen. Grund når intet passer: noRig (ingen med flueben og rollen),
|
||||
-- allBusy (alle optaget/i brug af spilleren), tooWide/tooNarrow (bredden, med tal fra den første).
|
||||
function ADFieldFleet.pick(candidates, role, x, z, mowWidth)
|
||||
local best, bestDistance = nil, math.huge
|
||||
local sawRole, widthReason, widthArgs = false, nil, nil
|
||||
for _, candidate in ipairs(candidates) do
|
||||
if candidate.role == role and candidate.enabled then
|
||||
sawRole = true
|
||||
if not candidate.busy and not candidate.controlled then
|
||||
local ok, reason, args = ADFieldModel.checkWidth(role, candidate.width or 0, mowWidth)
|
||||
if ok then
|
||||
local dx, dz = candidate.x - x, candidate.z - z
|
||||
local distance = dx * dx + dz * dz
|
||||
if distance < bestDistance then best, bestDistance = candidate, distance end
|
||||
elseif widthReason == nil then
|
||||
widthReason, widthArgs = reason, args
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if best ~= nil then return best end
|
||||
if not sawRole then return nil, "noRig" end
|
||||
if widthReason ~= nil then return nil, widthReason, widthArgs end
|
||||
return nil, "allBusy"
|
||||
end
|
||||
|
||||
function ADFieldFleet.toggle(enabledIds, id)
|
||||
local copy = {}
|
||||
for key, value in pairs(enabledIds or {}) do copy[key] = value end
|
||||
copy[id] = (not copy[id]) or nil
|
||||
return copy
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
-- Kør: luajit tests/test_adFieldFleet.lua (fra repo-roden)
|
||||
dofile("FS25_ADSmartPickup/adFieldModel.lua")
|
||||
dofile("FS25_ADSmartPickup/adFieldFleet.lua")
|
||||
local F = ADFieldFleet
|
||||
local failures = 0
|
||||
local function check(name, actual, expected)
|
||||
if actual == expected then print("OK " .. name) else
|
||||
failures = failures + 1
|
||||
print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual)))
|
||||
end
|
||||
end
|
||||
|
||||
-- FL1: rolle ud fra redskabets spec (læssevogn vinder over andet på samme køretøj)
|
||||
check("FL1 slåmaskine", F.roleFromSpecs({spec_mower = true}), "mower")
|
||||
check("FL1 vender", F.roleFromSpecs({spec_tedder = true}), "tedder")
|
||||
check("FL1 river", F.roleFromSpecs({spec_windrower = true}), "rake")
|
||||
check("FL1 læssevogn", F.roleFromSpecs({spec_forageWagon = true, spec_mower = true}), "collector")
|
||||
check("FL1 intet", F.roleFromSpecs({spec_plow = true}), nil)
|
||||
|
||||
local function rig(id, role, x, extra)
|
||||
local r = {id = id, role = role, enabled = true, busy = false, controlled = false, width = 40.8, x = x, z = 0, label = id}
|
||||
for k, v in pairs(extra or {}) do r[k] = v end
|
||||
return r
|
||||
end
|
||||
|
||||
-- FL2: nærmeste ledige med flueben og rigtig rolle
|
||||
local picked = F.pick({rig("far", "mower", 500), rig("near", "mower", 50), rig("wagon", "collector", 10)}, "mower", 0, 0, nil)
|
||||
check("FL2 nærmeste slåmaskine", picked.id, "near")
|
||||
|
||||
-- FL3: uden flueben / optaget / spiller i sædet springes over
|
||||
local _, why = F.pick({rig("a", "mower", 1, {enabled = false})}, "mower", 0, 0)
|
||||
check("FL3 intet med flueben", why, "noRig")
|
||||
local _, whyBusy = F.pick({rig("a", "mower", 1, {busy = true}), rig("b", "mower", 2, {controlled = true})}, "mower", 0, 0)
|
||||
check("FL3 alle optaget", whyBusy, "allBusy")
|
||||
check("FL3 ingen med rollen", select(2, F.pick({rig("a", "tedder", 1)}, "mower", 0, 0)), "noRig")
|
||||
|
||||
-- FL4: læssevogn smallere end slåbredden springes over, bredere vælges
|
||||
local wide = F.pick({rig("smal", "collector", 1, {width = 20}), rig("bred", "collector", 900, {width = 40.8})}, "collector", 0, 0, 40.8)
|
||||
check("FL4 bred valgt selv om længere væk", wide.id, "bred")
|
||||
-- FL5: kun for smalle -> grund tooNarrow med tal
|
||||
local none, whyNarrow, args = F.pick({rig("smal", "collector", 1, {width = 20})}, "collector", 0, 0, 40.8)
|
||||
check("FL5 ingen", none, nil); check("FL5 grund", whyNarrow, "tooNarrow"); check("FL5 bredde", args[1], 20)
|
||||
-- FL6: over 50 m -> tooWide
|
||||
check("FL6 for bred", select(2, F.pick({rig("x", "mower", 1, {width = 60})}, "mower", 0, 0)), "tooWide")
|
||||
|
||||
-- FL7: toggle giver ny tabel
|
||||
local enabled = {a = true}
|
||||
local toggled = F.toggle(enabled, "b")
|
||||
check("FL7 b til", toggled.b, true); check("FL7 original urørt", enabled.b, nil)
|
||||
check("FL7 a fra", F.toggle(toggled, "a").a, nil)
|
||||
|
||||
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