259 | function Sprayer:getExternalFill(fillType, dt) |
260 | local found = false |
261 | local isUnknownFillType = fillType == FillType.UNKNOWN |
262 | local allowLiquidManure = self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.LIQUIDMANURE) |
263 | local allowDigestate = self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.DIGESTATE) |
264 | local allowManure = self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.MANURE) |
265 | local allowLiquidFertilizer = self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.LIQUIDFERTILIZER) |
266 | local allowFertilizer = self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.FERTILIZER) |
267 | local allowsLiquidManureDigistate = allowLiquidManure or allowDigestate |
268 | local usage = 0 |
269 | |
270 | local farmId = self:getActiveFarm() |
271 | local stats = g_currentMission:farmStats(self:getLastTouchedFarmlandFarmId()) |
272 | |
273 | if fillType == FillType.LIQUIDMANURE or fillType == FillType.DIGESTATE or (isUnknownFillType and allowsLiquidManureDigistate) then |
274 | if g_currentMission.missionInfo.helperSlurrySource == 2 then -- buy manure |
275 | found = true |
276 | if g_currentMission.economyManager:getCostPerLiter(FillType.LIQUIDMANURE, false) then |
277 | fillType = FillType.LIQUIDMANURE |
278 | else |
279 | fillType = FillType.DIGESTATE |
280 | end |
281 | |
282 | usage = self:getSprayerUsage(fillType, dt) |
283 | if self.isServer then |
284 | local price = usage * g_currentMission.economyManager:getCostPerLiter(fillType, false) * 1.5 -- increase price if AI is active to reward the player's manual work |
285 | stats:updateStats("expenses", price) |
286 | g_currentMission:addMoney(-price, farmId, MoneyType.PURCHASE_FERTILIZER) |
287 | end |
288 | elseif g_currentMission.missionInfo.helperSlurrySource > 2 then |
289 | local info = g_currentMission.liquidManureTriggers[g_currentMission.missionInfo.helperSlurrySource-2] |
290 | if info ~= nil then -- Can be nil if pen was removed |
291 | local fillLevel = info.silo:getFillLevel(FillType.LIQUIDMANURE) |
292 | if fillLevel > 0 then |
293 | found = true |
294 | usage = self:getSprayerUsage(FillType.LIQUIDMANURE, dt) |
295 | if self.isServer then |
296 | info.silo:setFillLevel(FillType.LIQUIDMANURE, fillLevel-usage) |
297 | end |
298 | end |
299 | end |
300 | end -- |
301 | elseif fillType == FillType.MANURE or (fillType == FillType.UNKNOWN and allowManure) then |
302 | if fillType == FillType.UNKNOWN and allowManure then |
303 | fillType = FillType.MANURE |
304 | end |
305 | |
306 | if g_currentMission.missionInfo.helperManureSource == 2 then -- buy manure |
307 | found = true |
308 | fillType = FillType.MANURE |
309 | |
310 | usage = self:getSprayerUsage(fillType, dt) |
311 | if self.isServer then |
312 | local price = usage * g_currentMission.economyManager:getCostPerLiter(fillType, false) * 1.5 -- increase price if AI is active to reward the player's manual work |
313 | stats:updateStats("expenses", price) |
314 | g_currentMission:addMoney(-price, farmId, MoneyType.PURCHASE_FERTILIZER) |
315 | end |
316 | elseif g_currentMission.missionInfo.helperManureSource > 2 then |
317 | local info = g_currentMission.manureHeaps[g_currentMission.missionInfo.helperManureSource-2] |
318 | if info ~= nil then -- Can be nil if pen was removed |
319 | usage = self:getSprayerUsage(FillType.MANURE, dt) |
320 | if self.isServer then |
321 | if info.manureHeap:removeManure(usage) > 0 then |
322 | found = true |
323 | fillType = FillType.MANURE |
324 | end |
325 | end |
326 | end |
327 | end -- |
328 | elseif fillType == FillType.FERTILIZER or |
329 | fillType == FillType.LIQUIDFERTILIZER or |
330 | fillType == FillType.HERBICIDE or |
331 | fillType == FillType.LIME or |
332 | (fillType == FillType.UNKNOWN and (allowLiquidFertilizer or allowFertilizer)) then |
333 | if g_currentMission.missionInfo.helperBuyFertilizer then |
334 | found = true |
335 | if fillType == FillType.UNKNOWN then |
336 | if self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.LIQUIDFERTILIZER) then |
337 | fillType = FillType.LIQUIDFERTILIZER |
338 | else |
339 | fillType = FillType.FERTILIZER |
340 | end |
341 | end |
342 | |
343 | usage = self:getSprayerUsage(fillType, dt) |
344 | if self.isServer then |
345 | local price = usage * g_currentMission.economyManager:getCostPerLiter(fillType, false) * 1.5 -- increase price if AI is active to reward the player's manual work |
346 | stats:updateStats("expenses", price) |
347 | g_currentMission:addMoney(-price, farmId, MoneyType.PURCHASE_FERTILIZER) |
348 | end |
349 | end |
350 | end |
351 | |
352 | if found then |
353 | return fillType, usage |
354 | end |
355 | |
356 | return FillType.UNKNOWN, 0 |
357 | end |
447 | function Sprayer:loadSprayTypeFromXML(xmlFile, key, sprayType) |
448 | sprayType.fillUnitIndex = Utils.getNoNil(getXMLInt(xmlFile, key.. "#fillUnitIndex"), 1) |
449 | sprayType.unloadInfoIndex = Utils.getNoNil(getXMLInt(xmlFile, key.. "#unloadInfoIndex"), 1) |
450 | sprayType.fillVolumeIndex = getXMLInt(xmlFile, key.. "#fillVolumeIndex") |
451 | |
452 | sprayType.samples = {} |
453 | sprayType.samples.work = g_soundManager:loadSampleFromXML(xmlFile, key.. ".sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
454 | |
455 | sprayType.effects = g_effectManager:loadEffect(xmlFile, key.. ".effects", self.components, self, self.i3dMappings) |
456 | |
457 | sprayType.animationNodes = g_animationManager:loadAnimations(xmlFile, key.. ".animationNodes", self.components, self, self.i3dMappings) |
458 | |
459 | sprayType.turnedAnimation = getXMLString(self.xmlFile, key .. ".turnedAnimation#name") or "" |
460 | |
461 | sprayType.ai = {} |
462 | sprayType.ai.leftMarker = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key .. ".ai.areaMarkers#leftNode"), self.i3dMappings) |
463 | sprayType.ai.rightMarker = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key .. ".ai.areaMarkers#rightNode"), self.i3dMappings) |
464 | sprayType.ai.backMarker = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key .. ".ai.areaMarkers#backNode"), self.i3dMappings) |
465 | |
466 | sprayType.ai.sizeLeftMarker = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key .. ".ai.sizeMarkers#leftNode"), self.i3dMappings) |
467 | sprayType.ai.sizeRightMarker = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key .. ".ai.sizeMarkers#rightNode"), self.i3dMappings) |
468 | sprayType.ai.sizeBackMarker = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key .. ".ai.sizeMarkers#backNode"), self.i3dMappings) |
469 | |
470 | sprayType.ai.collisionTrigger = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key .. ".ai.collisionTrigger#node"), self.i3dMappings) |
471 | if sprayType.ai.collisionTrigger ~= nil then |
472 | local rigidBodyType = getRigidBodyType(sprayType.ai.collisionTrigger) |
473 | if rigidBodyType ~= "Kinematic" then |
474 | g_logManager:xmlWarning(self.configFileName, "'aiCollisionTrigger' is not a kinematic body type") |
475 | end |
476 | end |
477 | |
478 | local fillTypesStr = getXMLString(xmlFile, key.. "#fillTypes") |
479 | if fillTypesStr ~= nil then |
480 | sprayType.fillTypes = StringUtil.splitString(" ", fillTypesStr) |
481 | end |
482 | |
483 | sprayType.objectChanges = {} |
484 | ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, key, sprayType.objectChanges, self.components, self) |
485 | ObjectChangeUtil.setObjectChanges(sprayType.objectChanges, false) |
486 | |
487 | sprayType.usageScale = {} |
488 | sprayType.usageScale.workingWidth = Utils.getNoNil(getXMLFloat(self.xmlFile, key..".usageScales#workingWidth"), 12) |
489 | |
490 | return true |
491 | end |
879 | function Sprayer:onEndWorkAreaProcessing(dt, hasProcessed) |
880 | local spec = self.spec_sprayer |
881 | |
882 | if self.isServer then |
883 | if spec.workAreaParameters.isActive then |
884 | local sprayVehicle = spec.workAreaParameters.sprayVehicle |
885 | local usage = spec.workAreaParameters.usage |
886 | |
887 | if sprayVehicle ~= nil then |
888 | local sprayVehicleFillUnitIndex = spec.workAreaParameters.sprayVehicleFillUnitIndex |
889 | local sprayFillType = spec.workAreaParameters.sprayFillType |
890 | |
891 | local unloadInfoIndex = spec.unloadInfoIndex |
892 | local sprayType = self:getActiveSprayType() |
893 | if sprayType ~= nil then |
894 | unloadInfoIndex = sprayType.unloadInfoIndex |
895 | end |
896 | |
897 | local unloadInfo = self:getFillVolumeUnloadInfo(unloadInfoIndex) |
898 | sprayVehicle:addFillUnitFillLevel(self:getOwnerFarmId(), sprayVehicleFillUnitIndex, -usage, sprayFillType, ToolType.UNDEFINED, unloadInfo) |
899 | end |
900 | |
901 | local ha = MathUtil.areaToHa(spec.workAreaParameters.lastStatsArea, g_currentMission:getFruitPixelsToSqm()) |
902 | local stats = g_currentMission:farmStats(self:getLastTouchedFarmlandFarmId()) |
903 | stats:updateStats("workedHectares", ha) |
904 | stats:updateStats("fertilizedHectares", ha) |
905 | stats:updateStats("fertilizedTime", dt/(1000*60)) |
906 | stats:updateStats("sprayUsage", usage) |
907 | end |
908 | end |
909 | end |
86 | function Sprayer:onLoad(savegame) |
87 | local spec = self.spec_sprayer |
88 | |
89 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.sprayParticles.emitterShape", "vehicle.sprayer.effects.effectNode#effectClass='ParticleEffect'") --FS17 to FS19 |
90 | |
91 | spec.allowsSpraying = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sprayer#allowsSpraying"), true) |
92 | spec.needsTankActivation = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sprayer#needsTankActivation"), false) |
93 | spec.activateTankOnLowering = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sprayer#activateTankOnLowering"), false) |
94 | spec.activateOnLowering = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sprayer#activateOnLowering"), false) |
95 | |
96 | spec.usageScale = {} |
97 | spec.usageScale.default = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.sprayer.usageScales#scale"), 1) |
98 | spec.usageScale.workingWidth = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.sprayer.usageScales#workingWidth"), 12) |
99 | spec.usageScale.fillTypeScales = {} |
100 | local i=0 |
101 | while true do |
102 | local key = string.format("vehicle.sprayer.usageScales.sprayUsageScale(%d)", i) |
103 | if not hasXMLProperty(self.xmlFile, key) then |
104 | break |
105 | end |
106 | local fillTypeStr = getXMLString(self.xmlFile, key.. "#fillType") |
107 | local scale = getXMLFloat(self.xmlFile, key.. "#scale") |
108 | if fillTypeStr ~= nil and scale ~= nil then |
109 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeStr) |
110 | if fillTypeIndex ~= nil then |
111 | spec.usageScale.fillTypeScales[fillTypeIndex] = scale |
112 | else |
113 | print("Warning: Invalid spray usage scale fill type '"..fillTypeStr.."' in '" .. self.configFileName.. "'") |
114 | end |
115 | end |
116 | i = i+1 |
117 | end |
118 | |
119 | spec.sprayTypes = {} |
120 | i = 0 |
121 | while true do |
122 | local key = string.format("vehicle.sprayer.sprayTypes.sprayType(%d)", i) |
123 | if not hasXMLProperty(self.xmlFile, key) then |
124 | break |
125 | end |
126 | |
127 | local sprayType = {} |
128 | if self:loadSprayTypeFromXML(self.xmlFile, key, sprayType) then |
129 | table.insert(spec.sprayTypes, sprayType) |
130 | sprayType.index = #spec.sprayTypes |
131 | end |
132 | |
133 | i = i + 1 |
134 | end |
135 | |
136 | spec.lastActiveSprayType = nil |
137 | |
138 | if self.isClient then |
139 | spec.effects = g_effectManager:loadEffect(self.xmlFile, "vehicle.sprayer.effects", self.components, self, self.i3dMappings) |
140 | |
141 | spec.animationName = Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.sprayer.animation#name"), "") |
142 | |
143 | spec.samples = {} |
144 | spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.sprayer.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
145 | |
146 | spec.sampleFillEnabled = false |
147 | spec.sampleFillStopTime = -1 |
148 | spec.lastFillLevel = -1 |
149 | |
150 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.sprayer.animationNodes", self.components, self, self.i3dMappings) |
151 | end |
152 | |
153 | if self.sowingMachineGroundContactFlag == nil and self.cultivatorGroundContactFlag == nil then |
154 | if self.addAITerrainDetailRequiredRange ~= nil then |
155 | self:addAITerrainDetailRequiredRange(g_currentMission.plowValue, g_currentMission.plowValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
156 | self:addAITerrainDetailRequiredRange(g_currentMission.cultivatorValue, g_currentMission.cultivatorValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
157 | self:addAITerrainDetailRequiredRange(g_currentMission.sowingValue, g_currentMission.sowingValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
158 | self:addAITerrainDetailRequiredRange(g_currentMission.sowingWidthValue, g_currentMission.sowingWidthValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
159 | self:addAITerrainDetailRequiredRange(g_currentMission.grassValue, g_currentMission.grassValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels) |
160 | end |
161 | |
162 | --if self.addAITerrainDetailProhibitedRange ~= nil then |
163 | -- self:addAITerrainDetailProhibitedRange(1, 2, g_currentMission.sprayFirstChannel, g_currentMission.sprayNumChannels) |
164 | -- self:addAITerrainDetailProhibitedRange(g_currentMission.sprayLevelMaxValue, g_currentMission.sprayLevelMaxValue, g_currentMission.sprayLevelFirstChannel, g_currentMission.sprayLevelNumChannels) |
165 | --end |
166 | end |
167 | |
168 | spec.supportedSprayTypes = {} |
169 | |
170 | spec.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sprayer#fillUnitIndex"), 1) |
171 | spec.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sprayer#unloadInfoIndex"), 1) |
172 | spec.fillVolumeIndex = getXMLInt(self.xmlFile, "vehicle.sprayer#fillVolumeIndex") |
173 | spec.dischargeUVScrollSpeed = { StringUtil.getVectorFromString(Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.sprayer#fillVolumeDischargeScrollSpeed"), "0 0 0")) } |
174 | |
175 | spec.needsToBeFilledToTurnOn = true |
176 | spec.useSpeedLimit = true |
177 | spec.isWorking = false |
178 | |
179 | spec.workAreaParameters = {} |
180 | spec.workAreaParameters.sprayVehicle = nil |
181 | spec.workAreaParameters.sprayVehicleFillUnitIndex = nil |
182 | spec.workAreaParameters.lastChangedArea = 0 |
183 | spec.workAreaParameters.lastTotalArea = 0 |
184 | end |
794 | function Sprayer:onStartWorkAreaProcessing(dt) |
795 | local spec = self.spec_sprayer |
796 | |
797 | local sprayVehicle = nil |
798 | local sprayVehicleFillUnitIndex = nil |
799 | local fillType = self:getFillUnitFillType(self:getSprayerFillUnitIndex()) |
800 | local usage = self:getSprayerUsage(fillType, dt) |
801 | local sprayFillLevel = self:getFillUnitFillLevel(self:getSprayerFillUnitIndex()) |
802 | |
803 | if sprayFillLevel > 0 then |
804 | sprayVehicle = self |
805 | sprayVehicleFillUnitIndex = self:getSprayerFillUnitIndex() |
806 | else |
807 | for _, supportedSprayType in ipairs(spec.supportedSprayTypes) do |
808 | for _, src in ipairs(spec.fillTypeSources[supportedSprayType]) do |
809 | local vehicle = src.vehicle |
810 | if vehicle:getIsFillUnitActive(src.fillUnitIndex) then |
811 | local vehicleFillType = vehicle:getFillUnitFillType(src.fillUnitIndex) |
812 | local vehicleFillLevel = vehicle:getFillUnitFillLevel(src.fillUnitIndex) |
813 | if vehicleFillLevel > 0 and vehicleFillType == supportedSprayType then |
814 | sprayVehicle = vehicle |
815 | sprayVehicleFillUnitIndex = src.fillUnitIndex |
816 | fillType = sprayVehicle:getFillUnitFillType(sprayVehicleFillUnitIndex) |
817 | usage = self:getSprayerUsage(fillType, dt) |
818 | sprayFillLevel = vehicleFillLevel |
819 | break |
820 | end |
821 | else |
822 | -- if the ai is active we try to activate the source to activate the fill unit |
823 | if self:getIsAIActive() then |
824 | if vehicle.setIsTurnedOn ~= nil then |
825 | if not vehicle:getIsTurnedOn() then |
826 | vehicle:setIsTurnedOn(true) |
827 | end |
828 | end |
829 | end |
830 | end |
831 | end |
832 | end |
833 | end |
834 | |
835 | if self:getIsAIActive() then |
836 | local isSlurryTanker = self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.LIQUIDMANURE) or self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.DIGESTATE) |
837 | local isManureSpreader = self:getFillUnitAllowsFillType(self:getSprayerFillUnitIndex(), FillType.MANURE) |
838 | local isFertilizerSprayer = not isSlurryTanker and not isManureSpreader |
839 | |
840 | local isBuying = (isSlurryTanker and g_currentMission.missionInfo.helperSlurrySource > 1) |
841 | or (isManureSpreader and g_currentMission.missionInfo.helperManureSource > 1) |
842 | or (isFertilizerSprayer and g_currentMission.missionInfo.helperBuyFertilizer) |
843 | |
844 | if isBuying then |
845 | -- only consume while ai is on field, not while turning, so we check for the tools turned on state |
846 | if self:getIsTurnedOn() then |
847 | fillType, usage = self:getExternalFill(fillType, dt) |
848 | sprayFillLevel = usage |
849 | |
850 | -- do not consume the fill unit fill level if we buy fertilizer |
851 | sprayVehicle = nil |
852 | sprayVehicleFillUnitIndex = nil |
853 | end |
854 | end |
855 | end |
856 | |
857 | if self.isServer then |
858 | if fillType ~= FillType.UNKNOWN and fillType ~= spec.workAreaParameters.sprayFillType then |
859 | self:setSprayerAITerrainDetailProhibitedRange(fillType) |
860 | end |
861 | end |
862 | |
863 | spec.workAreaParameters.sprayType = g_sprayTypeManager:getSprayTypeIndexByFillTypeIndex(fillType) |
864 | spec.workAreaParameters.sprayFillType = fillType |
865 | spec.workAreaParameters.sprayFillLevel = sprayFillLevel |
866 | spec.workAreaParameters.usage = usage |
867 | spec.workAreaParameters.sprayVehicle = sprayVehicle |
868 | spec.workAreaParameters.sprayVehicleFillUnitIndex = sprayVehicleFillUnitIndex |
869 | spec.workAreaParameters.lastChangedArea = 0 |
870 | spec.workAreaParameters.lastTotalArea = 0 |
871 | spec.workAreaParameters.lastStatsArea = 0 |
872 | spec.workAreaParameters.isActive = false |
873 | |
874 | spec.isWorking = false |
875 | end |
720 | function Sprayer:onTurnedOn() |
721 | local spec = self.spec_sprayer |
722 | if self.isClient then |
723 | local sprayType = self:getActiveSprayType() |
724 | |
725 | if self:getAreEffectsVisible() then |
726 | local fillType = self:getFillUnitLastValidFillType(self:getSprayerFillUnitIndex()) |
727 | if fillType == FillType.UNKNOWN then |
728 | fillType = self:getFillUnitFirstSupportedFillType(self:getSprayerFillUnitIndex()) |
729 | end |
730 | |
731 | g_effectManager:setFillType(spec.effects, fillType) |
732 | g_effectManager:startEffects(spec.effects) |
733 | |
734 | if sprayType ~= nil then |
735 | g_effectManager:setFillType(sprayType.effects, fillType) |
736 | g_effectManager:startEffects(sprayType.effects) |
737 | |
738 | g_animationManager:startAnimations(sprayType.animationNodes) |
739 | end |
740 | |
741 | g_animationManager:startAnimations(spec.animationNodes) |
742 | end |
743 | |
744 | if spec.animationName ~= "" and self.playAnimation ~= nil then |
745 | self:playAnimation(spec.animationName, 1, self:getAnimationTime(spec.animationName), true) |
746 | end |
747 | |
748 | g_soundManager:playSample(spec.samples.work) |
749 | |
750 | if sprayType ~= nil then |
751 | g_soundManager:playSample(sprayType.samples.work) |
752 | |
753 | self:playAnimation(sprayType.turnedAnimation, 1, self:getAnimationTime(sprayType.turnedAnimation), true) |
754 | end |
755 | end |
756 | end |
223 | function Sprayer:processSprayerArea(workArea, dt) |
224 | local spec = self.spec_sprayer |
225 | |
226 | if self:getIsAIActive() and self.isServer then |
227 | if spec.workAreaParameters.sprayFillType == nil or spec.workAreaParameters.sprayFillType == FillType.UNKNOWN then |
228 | local rootVehicle = self:getRootVehicle() |
229 | rootVehicle:stopAIVehicle(AIVehicle.STOP_REASON_OUT_OF_FILL) |
230 | |
231 | return 0, 0 |
232 | end |
233 | end |
234 | |
235 | if spec.workAreaParameters.sprayFillLevel <= 0 then |
236 | return 0, 0 |
237 | end |
238 | |
239 | local sx,_,sz = getWorldTranslation(workArea.start) |
240 | local wx,_,wz = getWorldTranslation(workArea.width) |
241 | local hx,_,hz = getWorldTranslation(workArea.height) |
242 | |
243 | local changedArea, totalArea = FSDensityMapUtil.updateSprayArea(sx,sz, wx,wz, hx,hz, spec.workAreaParameters.sprayType) |
244 | |
245 | spec.workAreaParameters.isActive = true |
246 | spec.workAreaParameters.lastChangedArea = spec.workAreaParameters.lastChangedArea + changedArea |
247 | spec.workAreaParameters.lastStatsArea = spec.workAreaParameters.lastStatsArea + changedArea |
248 | spec.workAreaParameters.lastTotalArea = spec.workAreaParameters.lastTotalArea + totalArea |
249 | |
250 | if self:getLastSpeed() > 1 then |
251 | spec.isWorking = true |
252 | end |
253 | |
254 | return changedArea, totalArea |
255 | end |
68 | function Sprayer.registerEventListeners(vehicleType) |
69 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Sprayer) |
70 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Sprayer) |
71 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Sprayer) |
72 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", Sprayer) |
73 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", Sprayer) |
74 | SpecializationUtil.registerEventListener(vehicleType, "onPreDetach", Sprayer) |
75 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Sprayer) |
76 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Sprayer) |
77 | SpecializationUtil.registerEventListener(vehicleType, "onStateChange", Sprayer) |
78 | SpecializationUtil.registerEventListener(vehicleType, "onSetLowered", Sprayer) |
79 | SpecializationUtil.registerEventListener(vehicleType, "onFillUnitFillLevelChanged", Sprayer) |
80 | SpecializationUtil.registerEventListener(vehicleType, "onSprayTypeChange", Sprayer) |
81 | SpecializationUtil.registerEventListener(vehicleType, "onAIImplementEnd", Sprayer) |
82 | end |
50 | function Sprayer.registerOverwrittenFunctions(vehicleType) |
51 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAIMarkers", Sprayer.getAIMarkers) |
52 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAISizeMarkers", Sprayer.getAISizeMarkers) |
53 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAIImplementCollisionTriggers", Sprayer.getAIImplementCollisionTriggers) |
54 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDrawFirstFillText", Sprayer.getDrawFirstFillText) |
55 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanToggleTurnedOn", Sprayer.getCanToggleTurnedOn) |
56 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", Sprayer.getCanBeTurnedOn) |
57 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", Sprayer.loadWorkAreaFromXML) |
58 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", Sprayer.getIsWorkAreaActive) |
59 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Sprayer.doCheckSpeedLimit) |
60 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillVolumeUVScrollSpeed", Sprayer.getFillVolumeUVScrollSpeed) |
61 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAIRequiresTurnOffOnHeadland", Sprayer.getAIRequiresTurnOffOnHeadland) |
62 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", Sprayer.getDirtMultiplier) |
63 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", Sprayer.getWearMultiplier) |
64 | end |
399 | function Sprayer:setSprayerAITerrainDetailProhibitedRange(fillType) |
400 | if self:getUseSprayerAIRequirements() then |
401 | if self.addAITerrainDetailProhibitedRange ~= nil then |
402 | self:clearAITerrainDetailProhibitedRange() |
403 | self:clearAIFruitRequirements() |
404 | self:clearAIFruitProhibitions() |
405 | |
406 | local sprayTypeDesc = g_sprayTypeManager:getSprayTypeByFillTypeIndex(fillType) |
407 | if sprayTypeDesc ~= nil then |
408 | if sprayTypeDesc.isHerbicide then |
409 | local fruitType = g_fruitTypeManager:getFruitTypeByName("weed") |
410 | if fruitType ~= nil then |
411 | self:setAIFruitRequirements(fruitType.index, 1, 2) |
412 | end |
413 | else |
414 | self:addAITerrainDetailProhibitedRange(sprayTypeDesc.groundType, sprayTypeDesc.groundType, g_currentMission.sprayFirstChannel, g_currentMission.sprayNumChannels) |
415 | self:addAITerrainDetailProhibitedRange(g_currentMission.sprayLevelMaxValue, g_currentMission.sprayLevelMaxValue, g_currentMission.sprayLevelFirstChannel, g_currentMission.sprayLevelNumChannels) |
416 | end |
417 | |
418 | -- block ai from working on fully growth fields |
419 | if sprayTypeDesc.isHerbicide or sprayTypeDesc.isFertilizer then |
420 | for index, entry in pairs(g_currentMission.fruits) do |
421 | local fruitType = g_fruitTypeManager:getFruitTypeByIndex(index) |
422 | if fruitType.name:lower() ~= "grass" then |
423 | if fruitType.minHarvestingGrowthState ~= nil and fruitType.maxHarvestingGrowthState ~= nil and fruitType.weed == nil then |
424 | self:addAIFruitProhibitions(fruitType.index, fruitType.minHarvestingGrowthState, fruitType.maxHarvestingGrowthState) |
425 | end |
426 | end |
427 | end |
428 | end |
429 | end |
430 | end |
431 | end |
432 | end |