-
-
Notifications
You must be signed in to change notification settings - Fork 69
Expand file tree
/
Copy pathCpAITaskFieldWork.lua
More file actions
161 lines (148 loc) · 6.7 KB
/
CpAITaskFieldWork.lua
File metadata and controls
161 lines (148 loc) · 6.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
---@class CpAITaskFieldWork : CpAITask
CpAITaskFieldWork = CpObject(CpAITask)
function CpAITaskFieldWork:reset()
self.startPosition = nil
self.waitingForRefillingActive = false
CpAITask.reset(self)
end
function CpAITaskFieldWork:setStartPosition(startPosition)
self.startPosition = startPosition
end
function CpAITaskFieldWork:setWaitingForRefillingActive()
local cpSpec = self.vehicle.spec_cpAIFieldWorker
if not self.waitingForRefillingActive and cpSpec.driveStrategy then
self.waitingForRefillingActive = true
cpSpec.driveStrategy:raiseControllerEvent(
AIDriveStrategyCourse.onStartRefillingEvent)
end
end
function CpAITaskFieldWork:update(dt)
-- Hack to reevaluate the refill condition for the new setting state after it changed.
local settingWasChanged = false
if self.lastSettingValues then
if self.lastSettingValues.optionalFertilizer ~= self.vehicle:getCpSettings().sowingMachineFertilizerEnabled:getValue() then
settingWasChanged = true
end
if self.lastSettingValues.optionalSowing ~= self.vehicle:getCpSettings().optionalSowingMachineEnabled:getValue() then
settingWasChanged = true
end
end
if self.waitingForRefillingActive then
self.vehicle:cpHold(1500, true)
local cpSpec = self.vehicle.spec_cpAIFieldWorker
self.vehicle:setCpInfoTextActive(InfoTextManager.NEEDS_FILLING)
local readyToContinue, fillLevelHasChanged = true, false
cpSpec.driveStrategy:raiseControllerEventWithLambda(
AIDriveStrategyCourse.onUpdateRefillingEvent,
function(timerHasFinished, hasChanged)
readyToContinue = readyToContinue and timerHasFinished
fillLevelHasChanged = fillLevelHasChanged or hasChanged
end)
if readyToContinue and fillLevelHasChanged or settingWasChanged then
cpSpec.driveStrategy:raiseControllerEvent(
AIDriveStrategyCourse.onStopRefillingEvent)
self.waitingForRefillingActive = false
self.vehicle:resetCpActiveInfoText(InfoTextManager.NEEDS_FILLING)
end
end
self.lastSettingValues = {
optionalFertilizer = self.vehicle:getCpSettings().sowingMachineFertilizerEnabled:getValue(),
optionalSowing = self.vehicle:getCpSettings().optionalSowingMachineEnabled:getValue()
}
end
--- This function can be used to trace the triggering of AI events. The timing of these is critical for multiplayer
--- to work properly, these traces help to determine if this timing is correct. Bad timing will result in implements
--- not lowering or not turning on in multiplayer, while there are no symptoms in single player.
---
--- The game engine needs a separate phase for preparing to make sure that the
--- * onAIFieldWorkerStart,
--- * onAIFieldWorkerPrepareForWork,
--- * onAIImplementStartLine
--- events are generated one by one, one in each update loop so that at the end of the loop,
--- AIFieldWorker:updateAIFieldWorker() triggers a onAIFieldWorkerActive event.
---
function CpAITaskFieldWork:turnOnAIEventTrace()
self.vehicle.raiseAIEvent = function(vehicle, event1, event2, ...)
if vehicle.cpLastRaiseAIEvent ~= event1 and vehicle.cpLastRaiseAIEvent2 ~= event2 then
CpUtil.infoVehicle(vehicle, "raiseAIEvent %s %s", event1, event2)
end
vehicle.cpLastRaiseAIEvent1 = event1
vehicle.cpLastRaiseAIEvent2 = event2
AIVehicle.raiseAIEvent(vehicle, event1, event2, ...)
end
if self.vehicle.actionController ~= nil then
self.vehicle.actionController.onAIEvent = function(actionController, sourceVehicle, eventName)
if eventName ~= 'onAIFieldWorkerActive' and eventName ~= 'onAIImplementActive' then
CpUtil.infoVehicle(self.vehicle, " onAIEvent %s, source %s", eventName, CpUtil.getName(sourceVehicle))
end
VehicleActionController.onAIEvent(actionController, sourceVehicle, eventName)
end
end
end
--- Makes sure the cp fieldworker gets started.
function CpAITaskFieldWork:start()
self:debug("Field work task started.")
local spec = self.vehicle.spec_aiFieldWorker
spec.isActive = true
if self.isServer then
self.vehicle:updateAIFieldWorkerImplementData()
self.vehicle:raiseAIEvent("onAIFieldWorkerStart", "onAIImplementStart")
if self.vehicle:getAINeedsTrafficCollisionBox() and (AIFieldWorker.TRAFFIC_COLLISION ~= nil and
(AIFieldWorker.TRAFFIC_COLLISION ~= 0 and spec.aiTrafficCollision == nil)) then
spec.aiTrafficCollision = clone(AIFieldWorker.TRAFFIC_COLLISION, true, false, true)
end
local cpSpec = self.vehicle.spec_cpAIFieldWorker
--- Remembers the last lane offset setting value that was used.
cpSpec.cpJobStartAtLastWp:getCpJobParameters().laneOffset:setValue(self.job:getCpJobParameters().laneOffset:getValue())
if spec.driveStrategies ~= nil then
-- This deletion code could be removed, but just to be sure we let it stay here for now.
for i = #spec.driveStrategies, 1, -1 do
spec.driveStrategies[i]:delete()
table.remove(spec.driveStrategies, i)
end
spec.driveStrategies = {}
end
local cpDriveStrategy
if self.startPosition and g_vineScanner:hasVineNodesCloseBy(self.startPosition.x, self.startPosition.z) then
--- Checks if there are any vine nodes close to the starting point.
self:debug('Found a vine course, install CP vine fieldwork drive strategy for it')
cpDriveStrategy = AIDriveStrategyVineFieldWorkCourse(self, self.job)
elseif AIUtil.hasChildVehicleWithSpecialization(self.vehicle, Plow) then
self:debug('Found a plow, install CP plow drive strategy for it')
cpDriveStrategy = AIDriveStrategyPlowCourse(self, self.job)
else
local combine = AIUtil.getImplementOrVehicleWithSpecialization(self.vehicle, Combine)
local pipe = combine and SpecializationUtil.hasSpecialization(Pipe, combine.specializations)
if combine and pipe then
-- Default harvesters with a pipe.
self:debug('Found a combine with pipe, install CP combine drive strategy for it')
cpDriveStrategy = AIDriveStrategyCombineCourse(self, self.job)
cpSpec.combineDriveStrategy = cpDriveStrategy
end
if not cpDriveStrategy then
self:debug('Installing default CP fieldwork drive strategy')
cpDriveStrategy = AIDriveStrategyFieldWorkCourse(self, self.job)
end
end
cpDriveStrategy:setAIVehicle(self.vehicle, self.job:getCpJobParameters())
cpSpec.driveStrategy = cpDriveStrategy
--- Only the last driving strategy can stop the helper, while it is running.
table.insert(spec.driveStrategies, cpDriveStrategy)
else
self.vehicle:raiseAIEvent("onAIFieldWorkerStart", "onAIImplementStart")
end
CpAITask.start(self)
end
function CpAITaskFieldWork:stop(wasJobStopped)
if self.waitingForRefillingActive then
local cpSpec = self.vehicle.spec_cpAIFieldWorker
cpSpec.driveStrategy:raiseControllerEvent(
AIDriveStrategyCourse.onStopRefillingEvent)
end
if self.isServer then
self:debug("Field work task stopped.")
self.vehicle:stopFieldWorker()
self.vehicle:cpBrakeToStop()
end
CpAITask.stop(self, wasJobStopped)
end