LUADOC - Farming Simulator 19

AIVehicleUtil

Description
Util class for various ai vehicle functions
Functions

driveInDirection

Description
Drive in given direction
Definition
driveInDirection(table self, float dt, float steeringAngleLimit, float acceleration, float slowAcceleration, float slowAngleLimit, boolean allowedToDrive, boolean moveForwards, float lx, float lz, float maxSpeed, float slowDownFactor)
Arguments
tableselfobject of vehicle
floatdttime since last call in ms
floatsteeringAngleLimitlimit for steering angle
floataccelerationacceleration
floatslowAccelerationslow acceleration
floatslowAngleLimitlimit of slow angle
booleanallowedToDriveallow to drive
booleanmoveForwardsmove forwards
floatlxx direction
floatlzz direction
floatmaxSpeedmax speed
floatslowDownFactorslow down factor
Code
110function AIVehicleUtil.driveInDirection(self, dt, steeringAngleLimit, acceleration, slowAcceleration, slowAngleLimit, allowedToDrive, moveForwards, lx, lz, maxSpeed, slowDownFactor)
111
112 local angle = 0
113 if lx ~= nil and lz ~= nil then
114 local dot = lz
115 angle = math.deg(math.acos(dot))
116 if angle < 0 then
117 angle = angle+180
118 end
119
120 local turnLeft = lx > 0.00001
121 if not moveForwards then
122 turnLeft = not turnLeft
123 end
124
125 local targetRotTime
126 if turnLeft then
127 --rotate to the left
128 targetRotTime = self.maxRotTime*math.min(angle/steeringAngleLimit, 1)
129 else
130 --rotate to the right
131 targetRotTime = self.minRotTime*math.min(angle/steeringAngleLimit, 1)
132 end
133
134 if targetRotTime > self.rotatedTime then
135 self.rotatedTime = math.min(self.rotatedTime + dt*self:getAISteeringSpeed(), targetRotTime)
136 else
137 self.rotatedTime = math.max(self.rotatedTime - dt*self:getAISteeringSpeed(), targetRotTime)
138 end
139 end
140
141
142 if self.firstTimeRun then
143 local acc = acceleration
144 if maxSpeed ~= nil and maxSpeed ~= 0 then
145 if math.abs(angle) >= slowAngleLimit then
146 maxSpeed = maxSpeed * slowDownFactor
147 end
148 self.motor:setSpeedLimit(maxSpeed)
149
150 if self.cruiseControl.state ~= Drivable.CRUISECONTROL_STATE_ACTIVE then
151 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_ACTIVE)
152 end
153 else
154 if math.abs(angle) >= slowAngleLimit then
155 acc = slowAcceleration
156 end
157 end
158 if not allowedToDrive then
159 acc = 0
160 end
161 if not moveForwards then
162 acc = -acc
163 end
164 WheelsUtil.updateWheelsPhysics(self, dt, self.lastSpeedReal*self.movingDirection, acc, not allowedToDrive, true)
165 end
166end

driveToPoint

Description
Drive vehicle to given point
Definition
driveToPoint(table self, float dt, float acceleration, boolean allowedToDrive, boolean moveForwards, float tX, float tY, float maxSpeed, boolean doNotSteer)
Arguments
tableselfobject of vehicle to move
floatdttime since last call in ms
floataccelerationacceleration
booleanallowedToDriveallowed to drive
booleanmoveForwardsmove forwards
floattXlocal space x position
floattYlocal space y position
floatmaxSpeedspeed limit
booleandoNotSteerdo not steer
Code
27function AIVehicleUtil.driveToPoint(self, dt, acceleration, allowedToDrive, moveForwards, tX, tZ, maxSpeed, doNotSteer)
28
29 if self.firstTimeRun then
30
31 if allowedToDrive then
32
33 local tX_2 = tX * 0.5
34 local tZ_2 = tZ * 0.5
35
36 local d1X, d1Z = tZ_2, -tX_2
37 if tX > 0 then
38 d1X, d1Z = -tZ_2, tX_2
39 end
40
41 local hit,_,f2 = MathUtil.getLineLineIntersection2D(tX_2,tZ_2, d1X,d1Z, 0,0, tX, 0)
42
43 if doNotSteer == nil or not doNotSteer then
44 local rotTime = 0
45 if hit and math.abs(f2) < 100000 then
46 local radius = tX * f2
47 rotTime = self.wheelSteeringDuration * ( math.atan(1/radius) / math.atan(1/self.maxTurningRadius) )
48 end
49
50 local targetRotTime
51 if rotTime >= 0 then
52 targetRotTime = math.min(rotTime, self.maxRotTime)
53 else
54 targetRotTime = math.max(rotTime, self.minRotTime)
55 end
56
57 if targetRotTime > self.rotatedTime then
58 self.rotatedTime = math.min(self.rotatedTime + dt*self:getAISteeringSpeed(), targetRotTime)
59 else
60 self.rotatedTime = math.max(self.rotatedTime - dt*self:getAISteeringSpeed(), targetRotTime)
61 end
62
63 -- adjust maxSpeed
64 local steerDiff = targetRotTime - self.rotatedTime
65 local fac = math.abs(steerDiff) / math.max(self.maxRotTime, -self.minRotTime)
66 local speedReduction = 1.0 - math.pow(fac, 0.25)
67
68 -- if the speed is decreased to less than 1.5km/h we do not accelrate anymore
69 if maxSpeed * speedReduction < 1.5 then
70 acceleration = 0
71 speedReduction = 1.5 / maxSpeed
72 end
73
74 maxSpeed = maxSpeed * speedReduction
75 end
76 end
77
78 self:getMotor():setSpeedLimit(math.min(maxSpeed, self:getCruiseControlSpeed()))
79 if self:getCruiseControlState() ~= Drivable.CRUISECONTROL_STATE_ACTIVE then
80 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_ACTIVE)
81 end
82
83 if not allowedToDrive then
84 acceleration = 0
85 end
86 if not moveForwards then
87 acceleration = -acceleration
88 end
89
90 WheelsUtil.updateWheelsPhysics(self, dt, self.lastSpeedReal*self.movingDirection, acceleration, not allowedToDrive, true)
91
92 end
93
94end

getAIAreaOfVehicle

Description
Returns amount of fruit to work for ai vehicle is in given area
Definition
getAIAreaOfVehicle(table vehicle, float startWorldX, float startWorldZ, float widthWorldX, float widthWorldZ, float heightWorldX, float heightWorldZ)
Arguments
tablevehiclevehicle
floatstartWorldXstart world x
floatstartWorldZstart world z
floatwidthWorldXwidth world x
floatwidthWorldZwidth world z
floatheightWorldXheight world x
floatheightWorldZheight world z
Return Values
floatareaarea found
floattotalAreatotal area checked
Code
599function AIVehicleUtil.getAIAreaOfVehicle(vehicle, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ)
600 local useDensityHeightMap, useWindrowFruitType = vehicle:getAIFruitExtraRequirements()
601
602 if not useDensityHeightMap then
603 local query = vehicle:getFieldCropsQuery()
604 return AIVehicleUtil.getAIFruitArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, query)
605 else
606 local fruitRequirements = vehicle:getAIFruitRequirements()
607 return AIVehicleUtil.getAIDensityHeightArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, fruitRequirements, useWindrowFruitType)
608 end
609end

getAIDensityHeightArea

Description
Returns amount of density height to work is in given area
Definition
getAIDensityHeightArea(float startWorldX, float startWorldZ, float widthWorldX, float widthWorldZ, float heightWorldX, float heightWorldZ, table fruitRequirements, boolean useWindrowed)
Arguments
floatstartWorldXstart world x
floatstartWorldZstart world z
floatwidthWorldXwidth world x
floatwidthWorldZwidth world z
floatheightWorldXheight world x
floatheightWorldZheight world z
tablefruitRequirementstable with all required fruit types
booleanuseWindroweduse windrow
Return Values
floatareaarea found
floattotalAreatotal area checked
Code
639function AIVehicleUtil.getAIDensityHeightArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, fruitRequirements, useWindrowed)
640 -- first check if we are on a field
641
642 local data = g_currentMission.densityMapModifiers.getAIDensityHeightArea
643 local modifier = data.modifier
644 local filter = data.filter
645
646 modifier:setParallelogramWorldCoords(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, "ppp")
647 filter:setValueCompareParams("greater", 0)
648
649 local _, detailArea, _ = modifier:executeGet(filter)
650 if detailArea == 0 then
651 return 0, 0
652 end
653
654 local retArea, retTotalArea = 0, 0
655 for _, fruitRequirement in pairs(fruitRequirements) do
656 if fruitRequirement.fruitType ~= FruitType.UNKNOWN then
657 local fillType
658 if useWindrowed then
659 fillType = g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(fruitRequirement.fruitType)
660 else
661 fillType = g_fruitTypeManager:getFruitTypeIndexByFillTypeIndex(fruitRequirement.fruitType)
662 end
663 local _, area, totalArea = DensityMapHeightUtil.getFillLevelAtArea(fillType, startWorldX,startWorldZ, widthWorldX,widthWorldZ, heightWorldX,heightWorldZ)
664 retArea, retTotalArea = retArea+area, totalArea
665 end
666 end
667
668 return retArea, retTotalArea
669end

getAIFruitArea

Description
Returns amount of fruit to work is in given area
Definition
getAIFruitArea(float startWorldX, float startWorldZ, float widthWorldX, float widthWorldZ, float heightWorldX, float heightWorldZ, table query)
Arguments
floatstartWorldXstart world x
floatstartWorldZstart world z
floatwidthWorldXwidth world x
floatwidthWorldZwidth world z
floatheightWorldXheight world x
floatheightWorldZheight world z
tablequeryfield crops query of vehicle
Return Values
floatareaarea found
floattotalAreatotal area checked
Code
622function AIVehicleUtil.getAIFruitArea(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, query)
623 local x,z, widthX,widthZ, heightX,heightZ = MathUtil.getXZWidthAndHeight(startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ)
624 return query:getParallelogram(x,z, widthX,widthZ, heightX,heightZ, false)
625end

getAIToolReverserDirectionNode

Description
Returns reverser direction node of attached ai tool
Definition
getAIToolReverserDirectionNode(table vehicle)
Arguments
tablevehiclevehicle to check
Return Values
integeraiToolReverserDirectionNodereverser direction node of ai tool
Code
302function AIVehicleUtil.getAIToolReverserDirectionNode(vehicle)
303 for _, implement in pairs(vehicle:getAttachedImplements()) do
304 if implement.object ~= nil then
305 local reverserNode = implement.object:getAIToolReverserDirectionNode()
306
307 local attachedReverserNode = AIVehicleUtil.getAIToolReverserDirectionNode(implement.object)
308 reverserNode = reverserNode or attachedReverserNode
309
310 if reverserNode ~= nil then
311 return reverserNode
312 end
313 end
314 end
315end

getAreaDimensions

Description
Definition
getAreaDimensions()
Code
553function AIVehicleUtil.getAreaDimensions(directionX, directionZ, leftNode, rightNode, xOffset, zOffset, areaSize, invertXOffset)
554 local xOffsetLeft, xOffsetRight = xOffset, xOffset
555 if invertXOffset == nil or invertXOffset then
556 xOffsetLeft = -xOffsetLeft
557 end
558 local lX, _, lZ = localToWorld(leftNode, xOffsetLeft, 0, zOffset)
559 local rX, _, rZ = localToWorld(rightNode, xOffsetRight, 0, zOffset)
560
561 local sX = lX - (0.5 * directionX)
562 local sZ = lZ - (0.5 * directionZ)
563 local wX = rX - (0.5 * directionX)
564 local wZ = rZ - (0.5 * directionZ)
565 local hX = lX + (areaSize * directionX)
566 local hZ = lZ + (areaSize * directionZ)
567
568 return sX, sZ, wX, wZ, hX, hZ
569end

getAttachedImplementsAllowTurnBackward

Description
Returns if trailer or trailer low is attached
Definition
getAttachedImplementsAllowTurnBackward(table vehicle)
Arguments
tablevehiclevehicle to check
Return Values
booleanisAttachedis attached
Code
214function AIVehicleUtil.getAttachedImplementsAllowTurnBackward(vehicle)
215 if vehicle.getAIAllowTurnBackward ~= nil then
216 if not vehicle:getAIAllowTurnBackward() then
217 return false
218 end
219 end
220
221 if vehicle.getAttachedImplements ~= nil then
222 for _, implement in pairs(vehicle:getAttachedImplements()) do
223 local object = implement.object
224 if object ~= nil then
225 if object.getAIAllowTurnBackward ~= nil then
226 if not object:getAIAllowTurnBackward() then
227 return false
228 end
229 end
230
231 if not AIVehicleUtil.getAttachedImplementsAllowTurnBackward(object) then
232 return false
233 end
234 end
235 end
236 end
237
238 return true
239end

getAttachedImplementsBlockTurnBackward

Description
Returns if one of the attached implements blocks reverse driving
Definition
getAttachedImplementsBlockTurnBackward(table vehicle)
Arguments
tablevehiclevehicle to check
Return Values
booleandoesBlockimplement does block
Code
245function AIVehicleUtil.getAttachedImplementsBlockTurnBackward(vehicle)
246 if vehicle.getAIBlockTurnBackward ~= nil then
247 if vehicle:getAIBlockTurnBackward() then
248 return true
249 end
250 end
251
252 if vehicle.getAttachedImplements ~= nil then
253 for _, implement in pairs(vehicle:getAttachedImplements()) do
254 local object = implement.object
255 if object ~= nil then
256 if object.getAIBlockTurnBackward ~= nil then
257 if object:getAIBlockTurnBackward() then
258 return true
259 end
260 end
261
262 if AIVehicleUtil.getAttachedImplementsBlockTurnBackward(object) then
263 return true
264 end
265 end
266 end
267 end
268
269 return false
270end

getAttachedImplementsMaxTurnRadius

Description
Definition
getAttachedImplementsMaxTurnRadius()
Code
274function AIVehicleUtil.getAttachedImplementsMaxTurnRadius(vehicle)
275 local maxRadius = -1
276 if vehicle.getAttachedImplements ~= nil then
277 for _, implement in pairs(vehicle:getAttachedImplements()) do
278 local object = implement.object
279 if object ~= nil then
280 if object.getAITurnRadiusLimitation ~= nil then
281 local radius = object:getAITurnRadiusLimitation()
282 if radius ~= nil and radius > maxRadius then
283 maxRadius = radius
284 end
285 end
286
287 local radius = AIVehicleUtil.getAttachedImplementsMaxTurnRadius(object)
288 if radius > maxRadius then
289 maxRadius = radius
290 end
291 end
292 end
293 end
294
295 return maxRadius
296end

getAverageDriveDirection

Description
Returns average drive direction between 2 given vectors
Definition
getAverageDriveDirection(integer refNode, float x, float y, float z, float x2, float y2, float z2)
Arguments
integerrefNodeid of ref node
floatxworld x 1
floatyworld y 1
floatzworld z 1
floatx2world x 2
floaty2world y 2
floatz2world z 2
Return Values
floatlxaverage x direction
floatlzaverage z direction
Code
199function AIVehicleUtil.getAverageDriveDirection(refNode, x, y, z, x2, y2, z2)
200 local lx, _, lz = worldToLocal(refNode, (x+x2)*0.5, (y+y2)*0.5, (z+z2)*0.5)
201
202 local length = MathUtil.vector2Length(lx, lz)
203 if length > 0.00001 then
204 lx = lx/length
205 lz = lz/length
206 end
207 return lx, lz, length
208end

getDriveDirection

Description
Returns drive direction
Definition
getDriveDirection(integer refNode, float x, float y, float z)
Arguments
integerrefNodeid of ref node
floatxworld x
floatyworld y
floatzworld z
Return Values
floatlxx direction
floatlzz direction
Code
176function AIVehicleUtil.getDriveDirection(refNode, x, y, z)
177 local lx, _, lz = worldToLocal(refNode, x, y, z)
178
179 local length = MathUtil.vector2Length(lx, lz)
180 if length > 0.00001 then
181 length = 1/length
182 lx = lx*length
183 lz = lz*length
184 end
185 return lx, lz
186end

getIsAreaOwned

Description
Definition
getIsAreaOwned()
Code
573function AIVehicleUtil.getIsAreaOwned(vehicle, sX, sZ, wX, wZ, hX, hZ)
574 local farmId = vehicle.spec_aiVehicle.startedFarmId
575 local centerX, centerZ = (sX + wX)*0.5, (sZ + wZ)*0.5
576 if g_farmlandManager:getIsOwnedByFarmAtWorldPosition(farmId, centerX, centerZ) then
577 return true
578 end
579
580 if g_missionManager:getIsMissionWorkAllowed(farmId, centerX, centerZ, nil) then
581 return true
582 end
583
584 return false
585end

getMaxToolRadius

Description
Returns max tool turn radius
Definition
getMaxToolRadius(table implement)
Arguments
tableimplementimplement to check
Return Values
floatmaxTurnRadiusmax turn radius
Code
321function AIVehicleUtil.getMaxToolRadius(implement)
322 local radius = 0
323
324 local _, rotationNode, wheels = implement.object:getAITurnRadiusLimitation()
325
326 -- collect the max manual defined turn radius of all vehicles, not only valid ai implements
327 local rootVehicle = implement.object:getRootVehicle()
328 local retRadius = AIVehicleUtil.getAttachedImplementsMaxTurnRadius(rootVehicle)
329
330 if retRadius ~= -1 then
331 radius = retRadius
332 end
333
334 if rotationNode then
335 local activeInputAttacherJoint = implement.object:getActiveInputAttacherJoint()
336 local refNode = rotationNode
337
338 -- If the refNode is any attacher joint, we always use the currently used attacher joint
339 for _, inputAttacherJoint in pairs(implement.object:getInputAttacherJoints()) do
340 if refNode == inputAttacherJoint.node then
341 refNode = activeInputAttacherJoint.node
342 break
343 end
344 end
345
346 local rx,_,rz = localToLocal(refNode, implement.object.components[1].node, 0,0,0)
347
348 for _, wheel in pairs(wheels) do
349 local nx,_,nz = localToLocal(wheel.repr, implement.object.components[1].node, 0,0,0)
350
351 local x,z = nx-rx, nz-rz
352 local cx,cz = 0,0
353
354 -- get max rotation
355 local rotMax
356 if refNode == activeInputAttacherJoint.node then
357 local attacherVehicle = implement.object:getAttacherVehicle()
358 local jointDesc = attacherVehicle:getAttacherJointDescFromObject(implement.object)
359 rotMax = math.max(jointDesc.upperRotLimit[2], jointDesc.lowerRotLimit[2]) * activeInputAttacherJoint.lowerRotLimitScale[2]
360 else
361 for _,compJoint in pairs(implement.object.componentJoints) do
362 if refNode == compJoint.jointNode then
363 rotMax = compJoint.rotLimit[2]
364 break
365 end
366 end
367 end
368
369 -- calc turning radius
370 local x1 = x*math.cos(rotMax) - z*math.sin(rotMax)
371 local z1 = x*math.sin(rotMax) + z*math.cos(rotMax)
372
373 local dx = -z1
374 local dz = x1
375 if wheel.steeringAxleScale ~= 0 and wheel.steeringAxleRotMax ~= 0 then
376 local tmpx, tmpz = dx, dz
377 dx = tmpx*math.cos(wheel.steeringAxleRotMax) - tmpz*math.sin(wheel.steeringAxleRotMax)
378 dz = tmpx*math.sin(wheel.steeringAxleRotMax) + tmpz*math.cos(wheel.steeringAxleRotMax)
379 end
380
381 local hit,f1,_ = MathUtil.getLineLineIntersection2D(cx,cz, 1,0, x1,z1, dx,dz)
382 if hit then
383 radius = math.max(radius, math.abs(f1))
384 end
385 end
386 end
387
388 return radius
389end

getValidityOfTurnDirections

Description
Checks fruits on left and right side of vehicle to decide the turn direction
Definition
getValidityOfTurnDirections(table vehicle, float checkFrontDistance, table turnData)
Arguments
tablevehiclevehicle to check
floatcheckFrontDistancedistance to check in front of vehicle
tableturnDataproperties for turning
Return Values
floatleftAreaPercentageleft area percentage
floatrightAreaPercentageright area percentage
Code
416function AIVehicleUtil.getValidityOfTurnDirections(vehicle, turnData)
417 -- let's check the area at/around the marker which is farest behind of vehicle
418 local directionNode = vehicle:getAIVehicleDirectionNode()
419 local attachedAIImplements = vehicle:getAttachedAIImplements()
420 local checkFrontDistance = 5
421
422 local leftAreaPercentage = 0
423 local rightAreaPercentage = 0
424
425 local minZ = math.huge
426 local maxZ = -math.huge
427 for _,implement in pairs(attachedAIImplements) do
428 local leftMarker, rightMarker, backMarker = implement.object:getAIMarkers()
429
430 local _,_,zl = localToLocal(leftMarker, directionNode, 0,0,0)
431 local _,_,zr = localToLocal(rightMarker, directionNode, 0,0,0)
432 local _,_,zb = localToLocal(backMarker, directionNode, 0,0,0)
433
434 minZ = math.min(minZ, zl, zr, zb)
435 maxZ = math.max(maxZ, zl, zr, zb)
436 end
437
438 local sideDistance
439 if turnData == nil then
440 local minAreaWidth = math.huge
441 for _,implement in pairs(attachedAIImplements) do
442 local leftMarker, rightMarker, _ = implement.object:getAIMarkers()
443
444 local lx, _, _ = localToLocal(leftMarker, directionNode, 0,0,0)
445 local rx, _, _ = localToLocal(rightMarker, directionNode, 0,0,0)
446 minAreaWidth = math.min(minAreaWidth, math.abs(lx-rx))
447 end
448 sideDistance = minAreaWidth
449 else
450 sideDistance = math.abs(turnData.sideOffsetRight - turnData.sideOffsetLeft)
451 end
452
453 local dx, dz = vehicle.aiDriveDirection[1], vehicle.aiDriveDirection[2]
454 local sx, sz = -dz, dx
455
456 for _,implement in pairs(attachedAIImplements) do
457 local leftMarker, rightMarker, _ = implement.object:getAIMarkers()
458
459 local lx, ly, lz = localToLocal(leftMarker, directionNode, 0,0,0)
460 local rx, ry, rz = localToLocal(rightMarker, directionNode, 0,0,0)
461
462 local width = math.abs(lx-rx)
463 local length = checkFrontDistance + (maxZ - minZ) + math.max(sideDistance*1.3 + 2, checkFrontDistance) -- 1.3~tan(53) allows detecting back along a field side with angle 53 (and 2m extra compensates for some variances, or higher angles with small tools)
464
465 lx, _, lz = localToWorld(directionNode, lx,ly,maxZ + checkFrontDistance)
466 rx, _, rz = localToWorld(directionNode, rx,ry,maxZ + checkFrontDistance)
467
468 local lSX = lx
469 local lSZ = lz
470 local lWX = lSX - sx * width
471 local lWZ = lSZ - sz * width
472 local lHX = lSX - dx * length
473 local lHZ = lSZ - dz * length
474
475 local rSX = rx
476 local rSZ = rz
477 local rWX = rSX + sx * width
478 local rWZ = rSZ + sz * width
479 local rHX = rSX - dx * length
480 local rHZ = rSZ - dz * length
481
482 local lArea, lTotal = AIVehicleUtil.getAIAreaOfVehicle(implement.object, lSX,lSZ, lWX,lWZ, lHX,lHZ, false)
483 local rArea, rTotal = AIVehicleUtil.getAIAreaOfVehicle(implement.object, rSX,rSZ, rWX,rWZ, rHX,rHZ, false)
484
485 if lTotal > 0 then
486 leftAreaPercentage = leftAreaPercentage + (lArea / lTotal)
487 end
488 if rTotal > 0 then
489 rightAreaPercentage = rightAreaPercentage + (rArea / rTotal)
490 end
491
492 -- just visual debuging
493 if VehicleDebug.state == VehicleDebug.DEBUG_AI then
494 local lSY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, lSX,0,lSZ)+2
495 local lWY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, lWX,0,lWZ)+2
496 local lHY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, lHX,0,lHZ)+2
497 local rSY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, rSX,0,rSZ)+2
498 local rWY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, rWX,0,rWZ)+2
499 local rHY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, rHX,0,rHZ)+2
500
501 vehicle:addAIDebugLine({lSX,lSY,lSZ}, {lWX,lWY,lWZ}, {0.5, 0.5, 0.5})
502 vehicle:addAIDebugLine({lSX,lSY,lSZ}, {lHX,lHY,lHZ}, {0.5, 0.5, 0.5})
503 vehicle:addAIDebugLine({rSX,rSY,rSZ}, {rWX,rWY,rWZ}, {0.5, 0.5, 0.5})
504 vehicle:addAIDebugLine({rSX,rSY,rSZ}, {rHX,rHY,rHZ}, {0.5, 0.5, 0.5})
505 end
506 end
507
508 leftAreaPercentage = leftAreaPercentage / table.getn(attachedAIImplements)
509 rightAreaPercentage = rightAreaPercentage / table.getn(attachedAIImplements)
510
511 return leftAreaPercentage, rightAreaPercentage
512end

updateInvertLeftRightMarkers

Description
Update invertation of ai left and right markers on vehicle
Definition
updateInvertLeftRightMarkers(table rootAttacherVehicle, table vehicle)
Arguments
tablerootAttacherVehicleroot attacher vehicle
tablevehiclevehicle
Code
395function AIVehicleUtil.updateInvertLeftRightMarkers(rootAttacherVehicle, vehicle)
396 if vehicle.getAIMarkers ~= nil then
397 local leftMarker, rightMarker, _ = vehicle:getAIMarkers()
398 if leftMarker ~= nil and rightMarker ~= nil then
399 local lX, _, _ = localToLocal(leftMarker, rootAttacherVehicle:getAIVehicleDirectionNode(), 0,0,0)
400 local rX, _, _ = localToLocal(rightMarker, rootAttacherVehicle:getAIVehicleDirectionNode(), 0,0,0)
401
402 if rX > lX then
403 vehicle:setAIMarkersInverted()
404 end
405 end
406 end
407end