feat(markarbejde): manuel transport af brede høstere — flueben pr. høster i markflåden; moden beder spilleren køre den til marken og montere skærebordet (dialog + påmindelse hvert 5. min), overtager når den står på marken med passende skærebord og spilleren er steget ud (eller ved Start nu), tømmevogne først når høsten kører, ingen AD-parkering bagefter (v1.38.0.0)
This commit is contained in:
@@ -138,6 +138,8 @@ function ADFieldWork.getRigs(adEnv)
|
||||
busy = state.assignments[id] ~= nil or isAdActive(vehicle) or ADCpBridge.isWorking(vehicle)
|
||||
or (ADFieldSilos ~= nil and ADFieldSilos.isLoaned(vehicle)),
|
||||
controlled = isControlledByPlayer(vehicle),
|
||||
-- manuel transport: spilleren kører den til marken (for bred til vejene med skærebord)
|
||||
manual = (state.manual or {})[id] == true,
|
||||
width = ADCpBridge.getWorkWidth(vehicle), x = x, z = z,
|
||||
-- tom spreder kan flere ting (gødning og kalk): alle dens roller
|
||||
roles = specs.sprayRoles, filledRole = specs.filledRole, dumpable = specs.dumpable,
|
||||
@@ -300,7 +302,7 @@ end
|
||||
local function acceptFor(field, info, role)
|
||||
if role == "harvester" then
|
||||
local fruit = info.fruitIndex
|
||||
return function(candidate) return fruit ~= nil and candidate.fruits ~= nil and candidate.fruits[fruit] == true end
|
||||
return function(candidate) return ADManualTransport.acceptsHarvester(candidate, fruit) end
|
||||
elseif role == "seeder" then
|
||||
local fruitIndex = ADFieldWork.sowFruitIndex(field)
|
||||
return function(candidate) return candidate.hasSeeds and fruitIndex ~= nil and candidate.seedFruits[fruitIndex] == true end
|
||||
@@ -351,6 +353,19 @@ local function refillPlan(adEnv, fieldId, vehicle, role, x, z)
|
||||
return {fillType = fillType, empty = empty, refillId = refillId}
|
||||
end
|
||||
|
||||
-- Manuel transport: bed spilleren køre høsteren til marken (dialog første gang, ellers besked i hjørnet).
|
||||
local function askPlayer(field, info, assignment, withDialog)
|
||||
local text = string.format("F%s skal høstes: kør '%s' til %s, montér skærebordet og stig ud — så overtager Smart Pickup",
|
||||
tostring(field.id), ADRuns.vehicleLabel(assignment.vehicle), tostring(info.markerName or ("F" .. tostring(field.id))))
|
||||
assignment.remindedAt = now()
|
||||
log(field.id, "venter på spilleren: %s", text)
|
||||
if withDialog and InfoDialog ~= nil and InfoDialog.show ~= nil then
|
||||
pcall(InfoDialog.show, "Smart Pickup: " .. text)
|
||||
else
|
||||
ADFieldJobs.notify(text, true)
|
||||
end
|
||||
end
|
||||
|
||||
function ADFieldWork.dispatch(adEnv, field, info, decision)
|
||||
local role = decision.role
|
||||
local ok, reason = preflight(field, role)
|
||||
@@ -409,26 +424,34 @@ function ADFieldWork.dispatch(adEnv, field, info, decision)
|
||||
groupSize = decision.helper and 1 or count, lane = count > 1 and lanes[index] or nil, leader = index == 1,
|
||||
fillType = decision.helper and info.harvestFillType or nil,
|
||||
}
|
||||
local refill = refillPlan(adEnv, field.id, rig.vehicle, role, info.x, info.z)
|
||||
if refill ~= nil and refill.empty and refill.refillId == nil then
|
||||
-- tom og intet sted at fylde op: ud på marken ville den bare køre kurset uden at sprede
|
||||
fail(field.id, string.format("'%s' er tom for %s og der er ingen påfyldning med AutoDrive-markør — fyld den op", rig.label, fillTypeName(refill.fillType)))
|
||||
return
|
||||
end
|
||||
assignment.startX, assignment.startZ = rig.x, rig.z
|
||||
ADFieldJobs.state.assignments[rig.id] = assignment
|
||||
if refill ~= nil and refill.empty then
|
||||
-- AutoDrive LOAD: påfyldningen (2. markør), fyld op, videre til F-markøren (1.) — så Courseplay
|
||||
startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_LOAD, info.markerId, refill.refillId, refill.fillType)
|
||||
assignment.drive = {mode = adEnv.AutoDrive.MODE_LOAD, first = info.markerId, second = refill.refillId, fillType = refill.fillType}
|
||||
local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(refill.refillId)
|
||||
log(field.id, "%s '%s' er tom — fyldes med %s ved %s og kører så til %s", role, rig.label, fillTypeName(refill.fillType),
|
||||
tostring(marker ~= nil and marker.name or refill.refillId), tostring(info.markerName))
|
||||
if role == "harvester" and rig.manual and not assignment.helper then
|
||||
-- for bred til vejene: spilleren kører den selv til marken og monterer skærebordet
|
||||
assignment.phase, assignment.manual = "awaitingPlayer", true
|
||||
assignment.startX, assignment.startZ = rig.x, rig.z
|
||||
ADFieldJobs.state.assignments[rig.id] = assignment
|
||||
askPlayer(field, info, assignment, true)
|
||||
else
|
||||
startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_DRIVETO, info.markerId, nil)
|
||||
assignment.drive = {mode = adEnv.AutoDrive.MODE_DRIVETO, first = info.markerId}
|
||||
log(field.id, "%s '%s' sendt til %s (%.1f m%s)", role, rig.label, tostring(info.markerName), rig.width or 0,
|
||||
assignment.lane ~= nil and string.format(", bane %d", assignment.lane) or "")
|
||||
local refill = refillPlan(adEnv, field.id, rig.vehicle, role, info.x, info.z)
|
||||
if refill ~= nil and refill.empty and refill.refillId == nil then
|
||||
-- tom og intet sted at fylde op: ud på marken ville den bare køre kurset uden at sprede
|
||||
fail(field.id, string.format("'%s' er tom for %s og der er ingen påfyldning med AutoDrive-markør — fyld den op", rig.label, fillTypeName(refill.fillType)))
|
||||
return
|
||||
end
|
||||
assignment.startX, assignment.startZ = rig.x, rig.z
|
||||
ADFieldJobs.state.assignments[rig.id] = assignment
|
||||
if refill ~= nil and refill.empty then
|
||||
-- AutoDrive LOAD: påfyldningen (2. markør), fyld op, videre til F-markøren (1.) — så Courseplay
|
||||
startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_LOAD, info.markerId, refill.refillId, refill.fillType)
|
||||
assignment.drive = {mode = adEnv.AutoDrive.MODE_LOAD, first = info.markerId, second = refill.refillId, fillType = refill.fillType}
|
||||
local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(refill.refillId)
|
||||
log(field.id, "%s '%s' er tom — fyldes med %s ved %s og kører så til %s", role, rig.label, fillTypeName(refill.fillType),
|
||||
tostring(marker ~= nil and marker.name or refill.refillId), tostring(info.markerName))
|
||||
else
|
||||
startAd(adEnv, rig.vehicle, adEnv.AutoDrive.MODE_DRIVETO, info.markerId, nil)
|
||||
assignment.drive = {mode = adEnv.AutoDrive.MODE_DRIVETO, first = info.markerId}
|
||||
log(field.id, "%s '%s' sendt til %s (%.1f m%s)", role, rig.label, tostring(info.markerName), rig.width or 0,
|
||||
assignment.lane ~= nil and string.format(", bane %d", assignment.lane) or "")
|
||||
end
|
||||
end
|
||||
end
|
||||
note(field.id, {reason = false})
|
||||
@@ -790,14 +813,53 @@ local function finishAssignment(adEnv, assignment)
|
||||
end
|
||||
log(assignment.fieldId, "%s '%s' færdig", assignment.role, ADRuns.vehicleLabel(vehicle))
|
||||
-- læssevogn/påfyldte sæt parkeres af AutoDrive selv (onCpFinished med parkering sat)
|
||||
local park = not assignment.adHandlesEnd and parkMarkerId(adEnv, vehicle) or nil
|
||||
-- manuel transport: ALDRIG ud på vejen med AutoDrive (skærebordet sidder på) — spilleren henter den
|
||||
local park = not assignment.adHandlesEnd and not assignment.manual and parkMarkerId(adEnv, vehicle) or nil
|
||||
if park ~= nil then startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DRIVETO, park, nil) end
|
||||
if assignment.manual then
|
||||
ADFieldJobs.notify(string.format("F%s høstet — afmontér skærebordet og kør '%s' hjem", tostring(assignment.fieldId), ADRuns.vehicleLabel(vehicle)), true)
|
||||
end
|
||||
restoreToolOffset(assignment)
|
||||
assignment.phase = "finished"
|
||||
table.insert(ADFieldJobs.finished, assignment)
|
||||
ADFieldJobs.state.assignments[assignment.vehicleId] = nil
|
||||
end
|
||||
|
||||
local MANUAL_REASON_TEXT = {
|
||||
notThere = "kør den til marken",
|
||||
noHeader = "montér skærebordet",
|
||||
wrongHeader = "skærebordet kan ikke høste afgrøden — montér det rigtige",
|
||||
playerInside = "stig ud, så overtager Smart Pickup",
|
||||
}
|
||||
|
||||
-- Manuel transport: overtag når høsteren står på marken med passende skærebord og spilleren er steget ud
|
||||
-- (eller når spilleren trykker "Start nu"); påmind hvert 5. minut indtil da.
|
||||
local function followManual(adEnv, field, info, assignment)
|
||||
if field == nil or info == nil then return ADFieldWork.release(assignment) end
|
||||
local vehicle = assignment.vehicle
|
||||
local x, z = vehiclePosition(vehicle)
|
||||
local atField = #(info.verts or {}) >= 3 and ADFieldJobs.insidePolygon(x, z, info.verts)
|
||||
if not atField and info.markerId ~= nil then
|
||||
local wayPoint = adEnv.ADGraphManager:getWayPointById(info.markerId)
|
||||
atField = wayPoint ~= nil and math.sqrt((wayPoint.x - x) ^ 2 + (wayPoint.z - z) ^ 2) <= ADFieldWork.ARRIVE_DISTANCE
|
||||
end
|
||||
local forced = ADFieldJobs.takeoverRequested[field.id] == true
|
||||
ADFieldJobs.takeoverRequested[field.id] = nil
|
||||
local ok, why = ADManualTransport.readiness({atField = atField, fruits = ADCpBridge.getHarvestFruits(vehicle) or {},
|
||||
fruit = info.fruitIndex, controlled = isControlledByPlayer(vehicle), forced = forced})
|
||||
if ok then
|
||||
log(field.id, "overtager '%s'%s", ADRuns.vehicleLabel(vehicle), forced and " (Start nu)" or "")
|
||||
return beginWork(adEnv, field, info, assignment)
|
||||
end
|
||||
local reason = MANUAL_REASON_TEXT[why] or tostring(why)
|
||||
note(field.id, {reason = {text = string.format("venter på dig: '%s' — %s", ADRuns.vehicleLabel(vehicle), reason)}})
|
||||
if forced then
|
||||
ADFieldJobs.notify(string.format("F%s: kan ikke starte '%s' endnu — %s", tostring(field.id), ADRuns.vehicleLabel(vehicle), reason), true)
|
||||
elseif ADManualTransport.shouldRemind(assignment.remindedAt, now()) then
|
||||
askPlayer(field, info, assignment, false)
|
||||
end
|
||||
end
|
||||
|
||||
local function followWorking(adEnv, field, assignment)
|
||||
local vehicle = assignment.vehicle
|
||||
if assignment.role == "rake" and field.windrowOffset == nil and now() - assignment.since >= ADFieldWork.WINDROW_MEASURE_MS
|
||||
@@ -859,7 +921,7 @@ function ADFieldWork.resumeAfterLoad(adEnv)
|
||||
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}
|
||||
groupSize = 1, leader = true, resumed = true, manual = rig.manual == true}
|
||||
-- lager til læssevognens rest, som ved en normal start
|
||||
local assignment = ADFieldJobs.state.assignments[rig.id]
|
||||
local field, info = ADFieldJobs.getField(fieldId), ADFields.getInfo(fieldId)
|
||||
@@ -886,7 +948,7 @@ function ADFieldWork.follow(adEnv, assignment)
|
||||
-- førersædet og kigge må ikke slippe det (in-game 25/9).
|
||||
local steeredByAi = ADCpBridge.isWorking(vehicle) or isAdActive(vehicle) or assignment.phase == "starting"
|
||||
local speed = vehicle.getLastSpeed ~= nil and vehicle:getLastSpeed() or 0
|
||||
if isControlledByPlayer(vehicle) and not steeredByAi and speed > ADFieldWork.PLAYER_DRIVING_KMH then
|
||||
if assignment.phase ~= "awaitingPlayer" and isControlledByPlayer(vehicle) and not steeredByAi and speed > ADFieldWork.PLAYER_DRIVING_KMH then
|
||||
log(assignment.fieldId, "'%s' frigivet — spilleren kører det", ADRuns.vehicleLabel(vehicle))
|
||||
return ADFieldWork.release(assignment)
|
||||
end
|
||||
@@ -935,6 +997,8 @@ function ADFieldWork.follow(adEnv, assignment)
|
||||
end
|
||||
elseif assignment.phase == "working" then
|
||||
followWorking(adEnv, field, assignment)
|
||||
elseif assignment.phase == "awaitingPlayer" then
|
||||
followManual(adEnv, field, info, assignment)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user