60 | function AIDriveStrategy:getDistanceToEndOfField(dt, vX,vY,vZ) |
61 | |
62 | if self.lastHasNoField then |
63 | local dist = MathUtil.vector3Length(self.lastValidGroundPosX - vX, self.lastValidGroundPosY - vY, self.lastValidGroundPosZ - vZ) |
64 | return self.distanceToEnd - dist, false, true |
65 | end |
66 | if self.fieldEndGabDetected then |
67 | return 0, false, true |
68 | end |
69 | local distanceToTurn = self.lookAheadDistanceField |
70 | local attachedAIImplements = self.vehicle:getAttachedAIImplements() |
71 | |
72 | local hasField = false |
73 | local ownedField = true |
74 | |
75 | -- implement list must be sorted in decreasing order by distance to vehicle (front to back) |
76 | local lookAheadDist |
77 | |
78 | for i=1, table.getn(attachedAIImplements) do |
79 | local implement = attachedAIImplements[i] |
80 | local leftMarker, rightMarker, backMarker = implement.object:getAIMarkers() |
81 | |
82 | if i == 1 then |
83 | lookAheadDist = self.lookAheadDistanceField |
84 | else |
85 | local implementPre = attachedAIImplements[i-1] |
86 | |
87 | local leftMarker2, _, backMarker2 = implementPre.object:getAIMarkers() |
88 | |
89 | local _,_,zDiffArea = localToLocal(leftMarker2, backMarker2, 0,0,0) |
90 | local _,_,zDiff = localToLocal(leftMarker2, leftMarker, 0,0,0) |
91 | |
92 | lookAheadDist = math.max(0, zDiff - zDiffArea - implement.object:getAILookAheadSize()) |
93 | |
94 | -- tools behind the first tool should test at the same 'z value' if they are the same type |
95 | -- e.g. two cutters in comparison to fruit preparer and harvester |
96 | if self.turnData ~= nil and self.turnData.allImplementsOfSameType == true then |
97 | lookAheadDist = lookAheadDist + self.lookAheadDistanceField + zDiffArea + implement.object:getAILookAheadSize() |
98 | end |
99 | end |
100 | |
101 | local _, _, markerZOffset = 0, 0, 0 |
102 | local size = implement.object:getAILookAheadSize() |
103 | |
104 | if implement.object:getAIHasNoFullCoverageArea() then |
105 | _, _, markerZOffset = localToLocal(backMarker, leftMarker, 0,0,0) |
106 | lookAheadDist = 0 |
107 | size = size + math.abs(markerZOffset) |
108 | end |
109 | |
110 | local lX0, _, lZ0 = localToWorld(leftMarker, 0, 0, markerZOffset) |
111 | local rX0, _, rZ0 = localToWorld(rightMarker, 0, 0, markerZOffset) |
112 | |
113 | local lX = lX0 + self.vehicle.aiDriveDirection[1] * lookAheadDist |
114 | local lZ = lZ0 + self.vehicle.aiDriveDirection[2] * lookAheadDist |
115 | local rX = rX0 + self.vehicle.aiDriveDirection[1] * lookAheadDist |
116 | local rZ = rZ0 + self.vehicle.aiDriveDirection[2] * lookAheadDist |
117 | |
118 | local hX = lX + self.vehicle.aiDriveDirection[1] * size |
119 | local hZ = lZ + self.vehicle.aiDriveDirection[2] * size |
120 | |
121 | local area, areaTotal = AIVehicleUtil.getAIAreaOfVehicle(implement.object, lX,lZ, rX,rZ, hX,hZ, false) |
122 | if VehicleDebug.state == VehicleDebug.DEBUG_AI then |
123 | self.vehicle:addAIDebugText(string.format("tool %d: area=%.1f areaTotal=%.1f", i, area, areaTotal)) |
124 | |
125 | local lY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, lX,0,lZ)+2 |
126 | local rY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, rX,0,rZ)+2 |
127 | local hY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, hX,0,hZ)+2 |
128 | |
129 | self.vehicle:addAIDebugLine({lX,lY,lZ}, {rX,rY,rZ}, {0,1,0}) |
130 | self.vehicle:addAIDebugLine({lX,lY,lZ}, {hX,hY,hZ}, {0,1,0}) |
131 | end |
132 | |
133 | -- We're good if any tool is above a field owned by the player and has valid ground |
134 | if area > 0 then |
135 | local farmId = self.vehicle.spec_aiVehicle.startedFarmId |
136 | |
137 | if g_farmlandManager:getIsOwnedByFarmAtWorldPosition(farmId, (rX + hX)*0.5, (rZ + hZ)*0.5) |
138 | or g_missionManager:getIsMissionWorkAllowed(farmId, (rX + hX)*0.5, (rZ + hZ)*0.5, nil) then |
139 | hasField = true |
140 | break |
141 | else |
142 | ownedField = false |
143 | end |
144 | end |
145 | end |
146 | |
147 | self.lastHasNoField = not hasField |
148 | if hasField then |
149 | local distance = self.vehicle.lastMovedDistance |
150 | local dirX, dirY, dirZ = localDirectionToWorld(self.vehicle:getAIVehicleDirectionNode(), 0,0,distance + 0.75) |
151 | |
152 | self.lastValidGroundPosX = vX + dirX |
153 | self.lastValidGroundPosY = vY + dirY |
154 | self.lastValidGroundPosZ = vZ + dirZ |
155 | else |
156 | self.distanceToEnd = lookAheadDist |
157 | local dist = MathUtil.vector3Length(self.lastValidGroundPosX - vX, self.lastValidGroundPosY - vY, self.lastValidGroundPosZ - vZ) |
158 | distanceToTurn = self.distanceToEnd - dist |
159 | end |
160 | |
161 | return distanceToTurn, hasField, ownedField |
162 | end |