feat(markarbejde): efter genindlæsning genstartes CP-maskiner der var midt i et job fra sidste waypoint (CP's eget fortsæt-job; HUD'ens startpunkt urørt) og meldes ind på marken igen, hvis trinnet passer til rollen (v1.37.0.0)
This commit is contained in:
@@ -44,6 +44,28 @@ local function cropGone(stage, info)
|
|||||||
return (info.readyRatio or 0) < ADFieldModel.CUT_RATIO
|
return (info.readyRatio or 0) < ADFieldModel.CUT_RATIO
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Ligger (x, z) inden for omridset? (lige-ulige-reglen; kanten tæller som inde)
|
||||||
|
local function insidePolygon(x, z, verts)
|
||||||
|
local inside, j = false, #verts
|
||||||
|
for i = 1, #verts do
|
||||||
|
local a, b = verts[i], verts[j]
|
||||||
|
if (a.z > z) ~= (b.z > z) and x <= (b.x - a.x) * (z - a.z) / (b.z - a.z) + a.x then inside = not inside end
|
||||||
|
j = i
|
||||||
|
end
|
||||||
|
return inside
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Efter genindlæsning: marken en CP-maskine står på, hvis markens aktuelle trin er maskinens rolle (ellers nil).
|
||||||
|
-- fields = {{id, stage, verts = {{x, z}}}}
|
||||||
|
function ADFieldJobs.resumeField(x, z, role, fields)
|
||||||
|
for _, field in ipairs(fields or {}) do
|
||||||
|
if #(field.verts or {}) >= 3 and ADFieldModel.roleFor(field.stage) == role and insidePolygon(x, z, field.verts) then
|
||||||
|
return field.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Beslutning for én mark. assignments = sæt på marken ({phase, stage, helper}); kun sæt på det aktuelle
|
-- Beslutning for én mark. assignments = sæt på marken ({phase, stage, helper}); kun sæt på det aktuelle
|
||||||
-- trin tæller (en aflæsningsvogn på vej hjem fra høsten forstyrrer ikke kultiveringen).
|
-- trin tæller (en aflæsningsvogn på vej hjem fra høsten forstyrrer ikke kultiveringen).
|
||||||
-- env = {raining = bool}: vejrfølsomme trin (høst/slå/vend/riv/hø) sendes ikke ud i regn.
|
-- env = {raining = bool}: vejrfølsomme trin (høst/slå/vend/riv/hø) sendes ikke ud i regn.
|
||||||
@@ -340,6 +362,12 @@ function ADFieldJobs.tick(adEnv, dt)
|
|||||||
-- lidt efter start, og indtil da ligner de maskiner ledige (in-game 26/9: kultivatoren blev taget midt
|
-- lidt efter start, og indtil da ligner de maskiner ledige (in-game 26/9: kultivatoren blev taget midt
|
||||||
-- i spillerens eget CP-job 45 s efter indlæsning)
|
-- i spillerens eget CP-job 45 s efter indlæsning)
|
||||||
if ADFieldJobs.now < ADFieldJobs.STARTUP_GRACE_MS then return end
|
if ADFieldJobs.now < ADFieldJobs.STARTUP_GRACE_MS then return end
|
||||||
|
if not ADFieldJobs.resumedAfterLoad then
|
||||||
|
-- én gang, før noget nyt sendes ud: CP-maskiner der var midt i et job, fortsætter (og tæller som aktive)
|
||||||
|
ADFieldJobs.resumedAfterLoad = true
|
||||||
|
local okResume, errResume = pcall(ADFieldWork.resumeAfterLoad, adEnv)
|
||||||
|
if not okResume then Logging.warning(ADFieldJobs.LOG_PREFIX .. "genstart efter indlæsning fejlede: %s", tostring(errResume)) end
|
||||||
|
end
|
||||||
local env = ADFieldJobs.environment()
|
local env = ADFieldJobs.environment()
|
||||||
local slice = ADFieldJobs.tickCount % ADFieldJobs.PASSIVE_SLICES
|
local slice = ADFieldJobs.tickCount % ADFieldJobs.PASSIVE_SLICES
|
||||||
local stepped = 0
|
local stepped = 0
|
||||||
|
|||||||
@@ -811,6 +811,15 @@ local function followWorking(adEnv, field, assignment)
|
|||||||
end
|
end
|
||||||
if ADCpBridge.isWorking(vehicle) or isAdActive(vehicle) then
|
if ADCpBridge.isWorking(vehicle) or isAdActive(vehicle) then
|
||||||
assignment.idleSince = nil
|
assignment.idleSince = nil
|
||||||
|
assignment.seenWorking = true
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- genoptaget efter indlæsning: CP starter asynkront — vent til den kører, før "står stille" betyder færdig
|
||||||
|
if assignment.resumed and not assignment.seenWorking then
|
||||||
|
if now() - assignment.since > ADFieldWork.START_TIMEOUT_MS then
|
||||||
|
ADFieldWork.release(assignment)
|
||||||
|
fail(assignment.fieldId, string.format("'%s': Courseplay fortsatte ikke efter genindlæsning", ADRuns.vehicleLabel(vehicle)))
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
assignment.idleSince = assignment.idleSince or now()
|
assignment.idleSince = assignment.idleSince or now()
|
||||||
@@ -827,6 +836,42 @@ local function followWorking(adEnv, field, assignment)
|
|||||||
finishAssignment(adEnv, assignment)
|
finishAssignment(adEnv, assignment)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Efter genindlæsning: spillet stopper alle arbejdere ved gem, og Courseplay genstarter dem ikke (in-game 27/9).
|
||||||
|
-- En maskine med CP-kursus og et husket waypoint (CP nulstiller det når kurset er kørt færdigt) var midt i et job:
|
||||||
|
-- start den fra sidste waypoint med CP's eget "fortsæt"-job (HUD'ens eget startpunkt røres ikke). Står den på en
|
||||||
|
-- mark hvis aktuelle trin er maskinens rolle, meldes den ind på marken igen, så den følges og trinnet afsluttes.
|
||||||
|
function ADFieldWork.resumeAfterLoad(adEnv)
|
||||||
|
local fields, stageById = {}, {}
|
||||||
|
for _, info in ipairs(ADFields.list()) do
|
||||||
|
local field = ADFieldJobs.getField(info.id)
|
||||||
|
if field ~= nil and ADFieldModel.isWorking(field) then
|
||||||
|
table.insert(fields, {id = info.id, stage = field.stage, verts = info.verts})
|
||||||
|
stageById[info.id] = field.stage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, rig in ipairs(ADFieldWork.getRigs(adEnv)) do
|
||||||
|
local vehicle = rig.vehicle
|
||||||
|
local wasWorking = vehicle.startCpAtLastWp ~= nil and vehicle.hasCpCourse ~= nil and vehicle:hasCpCourse()
|
||||||
|
and vehicle.getCpLastRememberedWaypointIx ~= nil and vehicle:getCpLastRememberedWaypointIx() ~= nil
|
||||||
|
if wasWorking and not rig.busy and not rig.controlled then
|
||||||
|
local ok, started = pcall(vehicle.startCpAtLastWp, vehicle)
|
||||||
|
if not ok then
|
||||||
|
Logging.warning(ADFieldJobs.LOG_PREFIX .. "'%s' kunne ikke genstartes: %s", tostring(rig.label), tostring(started))
|
||||||
|
elseif started then
|
||||||
|
local fieldId = ADFieldJobs.resumeField(rig.x, rig.z, rig.role, fields)
|
||||||
|
if fieldId ~= nil then
|
||||||
|
ADFieldJobs.state.assignments[rig.id] = {vehicleId = rig.id, vehicle = vehicle, fieldId = fieldId, role = rig.role,
|
||||||
|
stage = stageById[fieldId], helper = false, phase = "working", since = now(), width = rig.width,
|
||||||
|
groupSize = 1, leader = true, resumed = true}
|
||||||
|
log(fieldId, "'%s' fortsætter efter genindlæsning (Courseplay fra sidste waypoint)", tostring(rig.label))
|
||||||
|
else
|
||||||
|
Logging.info(ADFieldJobs.LOG_PREFIX .. "'%s' genstartet fra sidste waypoint efter genindlæsning", tostring(rig.label))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function ADFieldWork.follow(adEnv, assignment)
|
function ADFieldWork.follow(adEnv, assignment)
|
||||||
local vehicle = assignment.vehicle
|
local vehicle = assignment.vehicle
|
||||||
-- Kun når spilleren selv KØRER (bevæger sig uden Courseplay/AutoDrive) slippes sættet — at sidde i
|
-- Kun når spilleren selv KØRER (bevæger sig uden Courseplay/AutoDrive) slippes sættet — at sidde i
|
||||||
|
|||||||
@@ -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.36.7.0</version>
|
<version>1.37.0.0</version>
|
||||||
<title>
|
<title>
|
||||||
<en>AD Smart Pickup</en>
|
<en>AD Smart Pickup</en>
|
||||||
</title>
|
</title>
|
||||||
|
|||||||
@@ -111,5 +111,22 @@ check("J14 uhøstet -> spol tilbage", J.decide(cultivatingField, {id = 16, marke
|
|||||||
check("J14 høstrest 30 % -> kultiver", J.decide(cultivatingField, {id = 16, markerId = 9, kind = "harvest", phase = "ready", readyRatio = 0.3}, {}, 0).action ~= "rewind", true)
|
check("J14 høstrest 30 % -> kultiver", J.decide(cultivatingField, {id = 16, markerId = 9, kind = "harvest", phase = "ready", readyRatio = 0.3}, {}, 0).action ~= "rewind", true)
|
||||||
check("J14 stub -> kultiver", J.decide(cultivatingField, {id = 16, markerId = 9, kind = "bare", phase = "cut", readyRatio = 0}, {}, 0).action ~= "rewind", true)
|
check("J14 stub -> kultiver", J.decide(cultivatingField, {id = 16, markerId = 9, kind = "bare", phase = "cut", readyRatio = 0}, {}, 0).action ~= "rewind", true)
|
||||||
|
|
||||||
|
|
||||||
|
-- resumeField: efter genindlæsning stopper spillet alle arbejdere; en CP-maskine der står PÅ en mark hvis
|
||||||
|
-- aktuelle trin passer til maskinens rolle, meldes ind på den mark igen (in-game 27/9)
|
||||||
|
do
|
||||||
|
local square = {{x = 0, z = 0}, {x = 100, z = 0}, {x = 100, z = 100}, {x = 0, z = 100}}
|
||||||
|
local fields = {
|
||||||
|
{id = 90, stage = "collecting", verts = square},
|
||||||
|
{id = 111, stage = "harvesting", verts = {{x = 200, z = 0}, {x = 300, z = 0}, {x = 300, z = 100}, {x = 200, z = 100}}},
|
||||||
|
}
|
||||||
|
check("RF høster på F111", ADFieldJobs.resumeField(250, 50, "harvester", fields), 111)
|
||||||
|
check("RF læssevogn på F90", ADFieldJobs.resumeField(50, 50, "collector", fields), 90)
|
||||||
|
check("RF forkert rolle til trinnet -> nil", ADFieldJobs.resumeField(250, 50, "collector", fields), nil)
|
||||||
|
check("RF uden for alle marker -> nil", ADFieldJobs.resumeField(150, 50, "harvester", fields), nil)
|
||||||
|
check("RF mark uden omrids -> nil", ADFieldJobs.resumeField(50, 50, "collector", {{id = 1, stage = "collecting", verts = {}}}), nil)
|
||||||
|
check("RF på kanten tæller som indenfor", ADFieldJobs.resumeField(0.5, 50, "collector", fields), 90)
|
||||||
|
end
|
||||||
|
|
||||||
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