90 | function AIDriveStrategyCombine:getDriveData(dt, vX,vY,vZ) |
91 | local isTurning = self.vehicle:getRootVehicle():getAIIsTurning() |
92 | |
93 | local allowedToDrive = true |
94 | local waitForStraw = false |
95 | local maxSpeed = math.huge |
96 | |
97 | for _, combine in pairs(self.combines) do |
98 | if not combine:getIsThreshingAllowed() then |
99 | self.vehicle:stopAIVehicle(AIVehicle.STOP_REASON_REGULAR) |
100 | self:debugPrint("Stopping AIVehicle - combine not allowed to thresh") |
101 | |
102 | return nil, nil, nil, nil, nil |
103 | end |
104 | |
105 | if combine.spec_pipe ~= nil then |
106 | local fillLevel = 0 |
107 | local capacity = 0 |
108 | |
109 | local trailerInTrigger = false |
110 | local invalidTrailerInTrigger = false |
111 | local dischargeNode = combine:getCurrentDischargeNode() |
112 | if dischargeNode ~= nil then |
113 | fillLevel = combine:getFillUnitFillLevel(dischargeNode.fillUnitIndex) |
114 | capacity = combine:getFillUnitCapacity(dischargeNode.fillUnitIndex) |
115 | end |
116 | |
117 | local trailer = NetworkUtil.getObject(combine.spec_pipe.nearestObjectInTriggers.objectId) |
118 | local trailerFillUnitIndex = combine.spec_pipe.nearestObjectInTriggers.fillUnitIndex |
119 | if trailer ~= nil then |
120 | trailerInTrigger = true |
121 | end |
122 | |
123 | if combine.spec_pipe.nearestObjectInTriggerIgnoreFillLevel then |
124 | invalidTrailerInTrigger = true |
125 | end |
126 | |
127 | local currentPipeTargetState = combine.spec_pipe.targetState |
128 | |
129 | if capacity == math.huge then |
130 | -- forage harvesters |
131 | if currentPipeTargetState ~= 2 then |
132 | combine:setPipeState(2) |
133 | end |
134 | |
135 | if not isTurning then |
136 | local targetObject, _ = combine:getDischargeTargetObject(dischargeNode) |
137 | allowedToDrive = trailerInTrigger and targetObject ~= nil |
138 | |
139 | if VehicleDebug.state == VehicleDebug.DEBUG_AI then |
140 | if not trailerInTrigger then |
141 | self.vehicle:addAIDebugText("COMBINE -> Waiting for trailer enter the trigger") |
142 | elseif trailerInTrigger and targetObject == nil then |
143 | self.vehicle:addAIDebugText("COMBINE -> Waiting for pipe hitting the trailer") |
144 | end |
145 | end |
146 | end |
147 | else |
148 | -- combine harvesters |
149 | local pipeState = currentPipeTargetState |
150 | |
151 | if fillLevel > (0.8*capacity) then |
152 | if not self.beaconLightsActive then |
153 | self.vehicle:setAIMapHotspotBlinking(true) |
154 | self.vehicle:setBeaconLightsVisibility(true) |
155 | self.beaconLightsActive = true |
156 | end |
157 | |
158 | if not self.notificationGrainTankWarningShown then |
159 | g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_CRITICAL, string.format(g_i18n:getText("ingameNotification_aiVehicleReasonGrainTankIsNearlyFull"), self.vehicle:getCurrentHelper().name) ) |
160 | self.notificationGrainTankWarningShown = true |
161 | end |
162 | else |
163 | if self.beaconLightsActive then |
164 | self.vehicle:setAIMapHotspotBlinking(false) |
165 | self.vehicle:setBeaconLightsVisibility(false) |
166 | self.beaconLightsActive = false |
167 | end |
168 | |
169 | self.notificationGrainTankWarningShown = false |
170 | end |
171 | |
172 | if fillLevel == capacity then |
173 | pipeState = 2 |
174 | self.wasCompletelyFull = true |
175 | if self.notificationFullGrainTankShown ~= true then |
176 | g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_CRITICAL, string.format(g_i18n:getText(AIVehicle.REASON_TEXT_MAPPING[AIVehicle.STOP_REASON_GRAINTANK_IS_FULL]), self.vehicle:getCurrentHelper().name) ) |
177 | self.notificationFullGrainTankShown = true |
178 | end |
179 | else |
180 | self.notificationFullGrainTankShown = false |
181 | end |
182 | |
183 | if trailerInTrigger then |
184 | pipeState = 2 |
185 | end |
186 | |
187 | if not trailerInTrigger then |
188 | if fillLevel < capacity * 0.8 then |
189 | self.wasCompletelyFull = false |
190 | |
191 | if not combine:getIsTurnedOn() and combine:getCanBeTurnedOn() then |
192 | combine:setIsTurnedOn(true) |
193 | end |
194 | end |
195 | end |
196 | |
197 | if (not trailerInTrigger and not invalidTrailerInTrigger) and fillLevel < capacity then |
198 | pipeState = 1 |
199 | end |
200 | |
201 | if fillLevel < 0.1 then |
202 | if not combine.spec_pipe.aiFoldedPipeUsesTrailerSpace then |
203 | if not trailerInTrigger and not invalidTrailerInTrigger then |
204 | pipeState = 1 |
205 | end |
206 | |
207 | if not combine:getIsTurnedOn() and combine:getCanBeTurnedOn() then |
208 | combine:setIsTurnedOn(true) |
209 | end |
210 | end |
211 | |
212 | self.wasCompletelyFull = false |
213 | end |
214 | |
215 | if currentPipeTargetState ~= pipeState then |
216 | combine:setPipeState(pipeState) |
217 | end |
218 | |
219 | allowedToDrive = fillLevel < capacity |
220 | |
221 | if pipeState == 2 and self.wasCompletelyFull then |
222 | allowedToDrive = false |
223 | if VehicleDebug.state == VehicleDebug.DEBUG_AI then |
224 | self.vehicle:addAIDebugText("COMBINE -> Waiting for trailer to unload") |
225 | end |
226 | end |
227 | |
228 | if isTurning and trailerInTrigger then |
229 | if combine:getCanDischargeToObject(dischargeNode) then |
230 | allowedToDrive = fillLevel == 0 |
231 | |
232 | if VehicleDebug.state == VehicleDebug.DEBUG_AI then |
233 | if not allowedToDrive then |
234 | self.vehicle:addAIDebugText("COMBINE -> Unload to trailer on headland") |
235 | end |
236 | end |
237 | end |
238 | end |
239 | |
240 | local freeFillLevel = capacity - fillLevel |
241 | if freeFillLevel < self.slowDownFillLevel then |
242 | -- we want to drive at least 2 km/h to avoid combine stops too early |
243 | maxSpeed = 2 + (freeFillLevel / self.slowDownFillLevel) * self.slowDownStartSpeed |
244 | |
245 | if VehicleDebug.state == VehicleDebug.DEBUG_AI then |
246 | self.vehicle:addAIDebugText(string.format("COMBINE -> Slow down because nearly full: %.2f", maxSpeed)) |
247 | end |
248 | end |
249 | end |
250 | |
251 | if not trailerInTrigger then |
252 | if combine.spec_combine.isSwathActive then |
253 | if combine.spec_combine.strawPSenabled then |
254 | waitForStraw = true |
255 | end |
256 | end |
257 | end |
258 | end |
259 | end |
260 | |
261 | if isTurning and waitForStraw then |
262 | if VehicleDebug.state == VehicleDebug.DEBUG_AI then |
263 | self.vehicle:addAIDebugText("COMBINE -> Waiting for straw to drop") |
264 | end |
265 | |
266 | local h = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, self.vehicle.aiDriveTarget[1],0,self.vehicle.aiDriveTarget[2]) |
267 | local x,_,z = worldToLocal(self.vehicle:getAIVehicleDirectionNode(), self.vehicle.aiDriveTarget[1],h,self.vehicle.aiDriveTarget[2]) |
268 | local dist = MathUtil.vector2Length(vX-x, vZ-z) |
269 | return x, z, false, 10, dist |
270 | else |
271 | if not allowedToDrive then |
272 | return 0, 1, true, 0, math.huge |
273 | else |
274 | return nil, nil, nil, maxSpeed, nil |
275 | end |
276 | end |
277 | end |