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
|
||||
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
|
||||
-- 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.
|
||||
@@ -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
|
||||
-- i spillerens eget CP-job 45 s efter indlæsning)
|
||||
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 slice = ADFieldJobs.tickCount % ADFieldJobs.PASSIVE_SLICES
|
||||
local stepped = 0
|
||||
|
||||
@@ -811,6 +811,15 @@ local function followWorking(adEnv, field, assignment)
|
||||
end
|
||||
if ADCpBridge.isWorking(vehicle) or isAdActive(vehicle) then
|
||||
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
|
||||
end
|
||||
assignment.idleSince = assignment.idleSince or now()
|
||||
@@ -827,6 +836,42 @@ local function followWorking(adEnv, field, assignment)
|
||||
finishAssignment(adEnv, assignment)
|
||||
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)
|
||||
local vehicle = assignment.vehicle
|
||||
-- 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"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.36.7.0</version>
|
||||
<version>1.37.0.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</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 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"))
|
||||
os.exit(failures == 0 and 0 or 1)
|
||||
|
||||
Reference in New Issue
Block a user