Skip to content

Commit e7f36c1

Browse files
authored
Merge pull request #1100 from Courseplay/mp-trace
Implement start/lowering fix for multiplayer
2 parents a57effb + 458d912 commit e7f36c1

2 files changed

Lines changed: 45 additions & 11 deletions

File tree

scripts/ai/strategies/AIDriveStrategyFieldWorkCourse.lua

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ AIDriveStrategyFieldWorkCourse = CpObject(AIDriveStrategyCourse)
2424

2525
AIDriveStrategyFieldWorkCourse.myStates = {
2626
WORKING = {},
27+
PREPARING = {},
2728
WAITING_FOR_LOWER = {},
2829
WAITING_FOR_LOWER_DELAYED = {},
2930
WAITING_FOR_STOP = {},
@@ -89,19 +90,11 @@ function AIDriveStrategyFieldWorkCourse:start(course, startIx, jobParameters)
8990
self:debug('Close enough to start waypoint %d, no alignment course needed', startIx)
9091
self:startCourse(course, startIx)
9192
self.state = self.states.INITIAL
92-
self:prepareForFieldWork()
9393
end
9494
--- Store a reference to the original generated course
9595
self.originalGeneratedFieldWorkCourse = self.vehicle:getFieldWorkCourse()
9696
end
9797

98-
--- If the strategy needs a field polygon to work, it won't transition out of the INITIAL state
99-
--- until the field detection, an asynchronous process that may have started only when the job was started, is finished.
100-
---@return boolean true if the strategy needs the field polygon to work
101-
function AIDriveStrategyFieldWorkCourse:needsFieldPolygon()
102-
return false
103-
end
104-
10598
--- Make sure all implements are in the working state
10699
function AIDriveStrategyFieldWorkCourse:prepareForFieldWork()
107100
self.vehicle:raiseAIEvent('onAIFieldWorkerPrepareForWork', 'onAIImplementPrepareForWork')
@@ -164,6 +157,17 @@ function AIDriveStrategyFieldWorkCourse:getDriveData(dt, vX, vY, vZ)
164157
end
165158
----------------------------------------------------------------
166159
if self.state == self.states.INITIAL then
160+
-- We need a separate phase for preparing to make sure that the
161+
-- * onAIFieldWorkerStart,
162+
-- * onAIFieldWorkerPrepareForWork,
163+
-- * onAIImplementStartLine
164+
-- events are generated one by one, one in each update loop so that at the end of the loop,
165+
-- AIFieldWorker:updateAIFieldWorker() triggers a onAIFieldWorkerActive event.
166+
-- This makes sure that all implements are lowered and started correctly in multiplayer as well.
167+
self:setMaxSpeed(0)
168+
self:prepareForFieldWork()
169+
self.state = self.states.PREPARING
170+
elseif self.state == self.states.PREPARING then
167171
self:setMaxSpeed(0)
168172
self:startWaitingForLower()
169173
self:lowerImplements()
@@ -328,7 +332,7 @@ function AIDriveStrategyFieldWorkCourse:onWaypointChange(ix, course)
328332
self:calculateTightTurnOffset()
329333
if not self.state ~= self.states.TURNING
330334
and self.course:isTurnStartAtIx(ix) then
331-
if self.state == self.states.INITIAL then
335+
if self.state == self.states.INITIAL or self.state == self.states.PREPARING then
332336
self:debug('Waypoint change (%d) to turn start right after starting work, lowering implements.', ix)
333337
self:startWaitingForLower()
334338
self:lowerImplements()
@@ -483,8 +487,8 @@ function AIDriveStrategyFieldWorkCourse:startAlignmentTurn(fieldWorkCourse, star
483487
alignmentCourse = self:createAlignmentCourse(fieldWorkCourse, startIx)
484488
end
485489
self.ppc:setShortLookaheadDistance()
486-
self:prepareForFieldWork()
487490
if alignmentCourse then
491+
self:prepareForFieldWork()
488492
local fm, bm = self:getFrontAndBackMarkers()
489493
self.turnContext = RowStartOrFinishContext(self.vehicle, fieldWorkCourse, startIx, startIx, self.turnNodes,
490494
self:getWorkWidth(), fm, bm, self:getTurnEndSideOffset(false), self:getTurnEndForwardOffset())
@@ -495,7 +499,6 @@ function AIDriveStrategyFieldWorkCourse:startAlignmentTurn(fieldWorkCourse, star
495499
self:debug('Could not create alignment course to first up/down row waypoint, continue without it')
496500
self:startCourse(fieldWorkCourse, startIx)
497501
self.state = self.states.INITIAL
498-
self:prepareForFieldWork()
499502
end
500503
end
501504

scripts/ai/tasks/CpAITaskFieldWork.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,37 @@ function CpAITaskFieldWork:update(dt)
5959

6060
end
6161

62+
--- This function can be used to trace the triggering of AI events. The timing of these is critical for multiplayer
63+
--- to work properly, these traces help to determine if this timing is correct. Bad timing will result in implements
64+
--- not lowering or not turning on in multiplayer, while there are no symptoms in single player.
65+
---
66+
--- The game engine needs a separate phase for preparing to make sure that the
67+
--- * onAIFieldWorkerStart,
68+
--- * onAIFieldWorkerPrepareForWork,
69+
--- * onAIImplementStartLine
70+
--- events are generated one by one, one in each update loop so that at the end of the loop,
71+
--- AIFieldWorker:updateAIFieldWorker() triggers a onAIFieldWorkerActive event.
72+
---
73+
function CpAITaskFieldWork:turnOnAIEventTrace()
74+
self.vehicle.raiseAIEvent = function(vehicle, event1, event2, ...)
75+
if vehicle.cpLastRaiseAIEvent ~= event1 and vehicle.cpLastRaiseAIEvent2 ~= event2 then
76+
CpUtil.infoVehicle(vehicle, "raiseAIEvent %s %s", event1, event2)
77+
end
78+
vehicle.cpLastRaiseAIEvent1 = event1
79+
vehicle.cpLastRaiseAIEvent2 = event2
80+
AIVehicle.raiseAIEvent(vehicle, event1, event2, ...)
81+
end
82+
83+
if self.vehicle.actionController ~= nil then
84+
self.vehicle.actionController.onAIEvent = function(actionController, sourceVehicle, eventName)
85+
if eventName ~= 'onAIFieldWorkerActive' and eventName ~= 'onAIImplementActive' then
86+
CpUtil.infoVehicle(self.vehicle, " onAIEvent %s, source %s", eventName, CpUtil.getName(sourceVehicle))
87+
end
88+
VehicleActionController.onAIEvent(actionController, sourceVehicle, eventName)
89+
end
90+
end
91+
end
92+
6293
--- Makes sure the cp fieldworker gets started.
6394
function CpAITaskFieldWork:start()
6495
self:debug("Field work task started.")

0 commit comments

Comments
 (0)