feat(pulje): bedste pasform — mindste traktor med hk nok vælges; afstand kun inden for ±15 %; over 2,5x redskabets behov kun som nødløsning (v1.56.0.0)
This commit is contained in:
@@ -70,7 +70,7 @@ end
|
|||||||
local function nearest(items, x, z, keep)
|
local function nearest(items, x, z, keep)
|
||||||
local best, bestDistance = nil, math.huge
|
local best, bestDistance = nil, math.huge
|
||||||
for _, item in ipairs(items) do
|
for _, item in ipairs(items) do
|
||||||
if keep(item) then
|
if keep == nil or keep(item) then
|
||||||
local distance = distanceSq(item.x, item.z, x, z)
|
local distance = distanceSq(item.x, item.z, x, z)
|
||||||
if distance < bestDistance then best, bestDistance = item, distance end
|
if distance < bestDistance then best, bestDistance = item, distance end
|
||||||
end
|
end
|
||||||
@@ -80,6 +80,38 @@ end
|
|||||||
|
|
||||||
-- Når opgaven slutter, sættes puljeredskabet af — også når AutoDrive ellers selv ville parkere (påfyldte
|
-- Når opgaven slutter, sættes puljeredskabet af — også når AutoDrive ellers selv ville parkere (påfyldte
|
||||||
-- sæt): AD parkerer ved redskabets plads med redskabet på. Aldrig ved manuel transport.
|
-- sæt): AD parkerer ved redskabets plads med redskabet på. Aldrig ved manuel transport.
|
||||||
|
-- Bedste pasform: den mindste traktor med hk nok; afstand afgør kun mellem traktorer inden for FIT_BAND af den
|
||||||
|
-- mindste. Over OVERSIZE_FACTOR x behovet kun når intet andet passer; ukendt traktor-hk efter de kendte.
|
||||||
|
-- Redskab uden hk-data: nærmeste (intet at matche på). tractors = allerede filtrerede kandidater.
|
||||||
|
ADPool.FIT_BAND = 1.15
|
||||||
|
ADPool.OVERSIZE_FACTOR = 2.5
|
||||||
|
|
||||||
|
function ADPool.bestFit(tractors, implement, role)
|
||||||
|
local fitting = {}
|
||||||
|
for _, tractor in ipairs(tractors or {}) do
|
||||||
|
if suits(tractor, implement, role) then table.insert(fitting, tractor) end
|
||||||
|
end
|
||||||
|
local needed = implement.neededHp
|
||||||
|
if needed == nil or needed <= 0 then return nearest(fitting, implement.x, implement.z) end
|
||||||
|
local sized, oversized, unknown = {}, {}, {}
|
||||||
|
for _, tractor in ipairs(fitting) do
|
||||||
|
if tractor.hp == nil or tractor.hp <= 0 then table.insert(unknown, tractor)
|
||||||
|
elseif tractor.hp > needed * ADPool.OVERSIZE_FACTOR then table.insert(oversized, tractor)
|
||||||
|
else table.insert(sized, tractor) end
|
||||||
|
end
|
||||||
|
local pool = #sized > 0 and sized or (#unknown > 0 and unknown or oversized)
|
||||||
|
if pool ~= unknown then
|
||||||
|
local smallest = math.huge
|
||||||
|
for _, tractor in ipairs(pool) do smallest = math.min(smallest, tractor.hp) end
|
||||||
|
local band = {}
|
||||||
|
for _, tractor in ipairs(pool) do
|
||||||
|
if tractor.hp <= smallest * ADPool.FIT_BAND then table.insert(band, tractor) end
|
||||||
|
end
|
||||||
|
pool = band
|
||||||
|
end
|
||||||
|
return nearest(pool, implement.x, implement.z)
|
||||||
|
end
|
||||||
|
|
||||||
function ADPool.shouldReturnHome(assignment)
|
function ADPool.shouldReturnHome(assignment)
|
||||||
return not assignment.manual
|
return not assignment.manual
|
||||||
end
|
end
|
||||||
@@ -160,7 +192,7 @@ function ADPool.pairFor(role, fieldX, fieldZ, implements, tractors, blocked, acc
|
|||||||
end)
|
end)
|
||||||
local weakest = nil
|
local weakest = nil
|
||||||
for _, implement in ipairs(candidates) do
|
for _, implement in ipairs(candidates) do
|
||||||
local tractor = nearest(free, implement.x, implement.z, function(t) return suits(t, implement, role) end)
|
local tractor = ADPool.bestFit(free, implement, role)
|
||||||
if tractor ~= nil then return {implement = implement, tractor = tractor} end
|
if tractor ~= nil then return {implement = implement, tractor = tractor} end
|
||||||
if weakest == nil or (implement.neededHp or 0) < (weakest.neededHp or 0) then weakest = implement end
|
if weakest == nil or (implement.neededHp or 0) < (weakest.neededHp or 0) then weakest = implement end
|
||||||
end
|
end
|
||||||
@@ -174,9 +206,11 @@ function ADPool.pairAll(role, implements, tractors, blocked)
|
|||||||
local used, result = {}, {}
|
local used, result = {}, {}
|
||||||
for _, implement in ipairs(implements or {}) do
|
for _, implement in ipairs(implements or {}) do
|
||||||
if hasRole(implement, role) and not blocked[implement.id] then
|
if hasRole(implement, role) and not blocked[implement.id] then
|
||||||
local tractor = nearest(tractors or {}, implement.x, implement.z, function(t)
|
local open = {}
|
||||||
return not used[t.id] and not blocked[t.id] and not t.offNetwork and suits(t, implement, role)
|
for _, t in ipairs(tractors or {}) do
|
||||||
end)
|
if not used[t.id] and not blocked[t.id] and not t.offNetwork then table.insert(open, t) end
|
||||||
|
end
|
||||||
|
local tractor = ADPool.bestFit(open, implement, role)
|
||||||
if tractor ~= nil then
|
if tractor ~= nil then
|
||||||
used[tractor.id] = true
|
used[tractor.id] = true
|
||||||
table.insert(result, {implement = implement, tractor = tractor})
|
table.insert(result, {implement = implement, tractor = tractor})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
<modDesc descVersion="107">
|
<modDesc descVersion="107">
|
||||||
<author>masterdraco</author>
|
<author>masterdraco</author>
|
||||||
<version>1.55.1.0</version>
|
<version>1.56.0.0</version>
|
||||||
<title>
|
<title>
|
||||||
<en>AD Smart Pickup</en>
|
<en>AD Smart Pickup</en>
|
||||||
</title>
|
</title>
|
||||||
|
|||||||
@@ -164,5 +164,19 @@ check("par-alle: ingen traktorer", #P.pairAll("unloader", wagons, {}, {}), 0)
|
|||||||
-- flow-vogne: vogn der hører til et kørende flow vises sådan (og er ikke i puljen)
|
-- flow-vogne: vogn der hører til et kørende flow vises sådan (og er ikke i puljen)
|
||||||
check("redskab: flowets vogn", ist({parkName = "P Cow Food vogn 1", hasConnect = true, flowName = "Cow Food"}), "flow|Cow Food")
|
check("redskab: flowets vogn", ist({parkName = "P Cow Food vogn 1", hasConnect = true, flowName = "Cow Food"}), "flow|Cow Food")
|
||||||
check("redskab: flowets vogn koblet på", ist({parkName = "P Cow Food vogn 1", hasConnect = true, flowName = "Cow Food", attachedTo = "Cow Food 1"}), "attached|Cow Food 1")
|
check("redskab: flowets vogn koblet på", ist({parkName = "P Cow Food vogn 1", hasConnect = true, flowName = "Cow Food", attachedTo = "Cow Food 1"}), "attached|Cow Food 1")
|
||||||
|
-- pasform: mindste traktor med hk nok; afstand kun inden for ±15 %; over 2,5x behovet kun som nødløsning
|
||||||
|
-- (in-game 29/9: en meget stor traktor blev sendt til et lille job og kunne ikke komme rundt)
|
||||||
|
local impl120 = {id = "k", x = 0, z = 0, neededHp = 120}
|
||||||
|
local t150 = {id = "t150", x = 900, z = 0, hp = 150}
|
||||||
|
local t170 = {id = "t170", x = 300, z = 0, hp = 180}
|
||||||
|
local t500 = {id = "t500", x = 50, z = 0, hp = 500}
|
||||||
|
check("pasform: mindste der passer vinder over nærmere", P.bestFit({t500, t170, t150}, impl120, "cultivator").id, "t150")
|
||||||
|
local t160 = {id = "t160", x = 100, z = 0, hp = 160}
|
||||||
|
check("pasform: inden for 15 % vinder den nærmeste", P.bestFit({t150, t160}, impl120, "cultivator").id, "t160")
|
||||||
|
check("pasform: kun for stor -> nødløsning", P.bestFit({t500}, impl120, "cultivator").id, "t500")
|
||||||
|
check("pasform: for svag -> ingen", P.bestFit({{id = "t90", x = 0, z = 0, hp = 90}}, impl120, "cultivator"), nil)
|
||||||
|
check("pasform: redskab uden hk-data -> nærmeste", P.bestFit({t150, t500}, {id = "x", x = 0, z = 0}, "cultivator").id, "t500")
|
||||||
|
check("pasform: ukendt traktor-hk efter kendte", P.bestFit({{id = "u", x = 0, z = 0}, t170}, impl120, "cultivator").id, "t170")
|
||||||
|
check("pasform: lastbil tæller ikke", P.bestFit({{id = "lb", x = 0, z = 0, hp = 150, category = "TRUCKS"}, t500}, impl120, "cultivator").id, "t500")
|
||||||
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||||
os.exit(failures == 0 and 0 or 1)
|
os.exit(failures == 0 and 0 or 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user