LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

WorkArea

Description
Specialization for work areas providing wrapper environment to allow vehicles to interact with the foliage/terrainDetail
Functions

checkMovingPartDirtyUpdateNode

Description
Definition
checkMovingPartDirtyUpdateNode()
Code
647function WorkArea:checkMovingPartDirtyUpdateNode(superFunc, node, movingPart)
648 superFunc(self, node, movingPart)
649
650 local spec = self.spec_workArea
651 for i=1, #spec.workAreas do
652 local workArea = spec.workAreas[i]
653 if node == workArea.start or node == workArea.width or node == workArea.height then
654 Logging.xmlError(self.xmlFile, "Found work area node '%s' in active dirty moving part '%s' with limited update distance. Remove limit or adjust hierarchy for correct function. (maxUpdateDistance='-')", getName(node), getName(movingPart.node))
655 end
656 end
657end

getIsAccessibleAtWorldPosition

Description
Definition
getIsAccessibleAtWorldPosition(boolean accessible, int landowner, boolean isBuyable)
Arguments
booleanaccessibletrue if farmland is accessible for current farmid
intlandownerfarmid of current landowner
booleanisBuyabletrue if farmland is buyable
Code
164function WorkArea:getIsAccessibleAtWorldPosition(farmId, x, z, workAreaType)
165 -- Disallow mission vehicles outside mission fields
166 if self.propertyState == Vehicle.PROPERTY_STATE_MISSION then
167 return g_missionManager:getIsMissionWorkAllowed(farmId, x, z, workAreaType), farmId, true
168 end
169
170 local farmlandId = g_farmlandManager:getFarmlandIdAtWorldPosition(x, z)
171 if farmlandId == nil then -- no valid farmland, or not buyable
172 return false, nil, false
173 end
174
175 if farmlandId == FarmlandManager.NOT_BUYABLE_FARM_ID then
176 return false, FarmlandManager.NO_OWNER_FARM_ID, false
177 end
178
179 local landOwner = g_farmlandManager:getFarmlandOwner(farmlandId)
180 local accessible = (landOwner ~= 0 and g_currentMission.accessHandler:canFarmAccessOtherId(farmId, landOwner))
181 or g_missionManager:getIsMissionWorkAllowed(farmId, x, z, workAreaType)
182
183 return accessible, landOwner, true
184end

getIsFarmlandNotOwnedWarningShown

Description
Definition
getIsFarmlandNotOwnedWarningShown()
Code
603function WorkArea:getIsFarmlandNotOwnedWarningShown()
604 return self.spec_workArea.showFarmlandNotOwnedWarning
605end

getIsSpeedRotatingPartActive

Description
Returns true if speed rotating part is active
Definition
getIsSpeedRotatingPartActive(table speedRotatingPart)
Arguments
tablespeedRotatingPartspeedRotatingPart
Return Values
booleanisActivespeed rotating part is active
Code
627function WorkArea:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
628 if speedRotatingPart.workAreaIndex ~= nil then
629 local spec = self.spec_workArea
630 local workArea = spec.workAreas[speedRotatingPart.workAreaIndex]
631 if workArea == nil then
632 speedRotatingPart.workAreaIndex = nil
633 Logging.xmlWarning(self.xmlFile, "Invalid workAreaIndex '%s'. Indexing starts with 1!", tostring(speedRotatingPart.workAreaIndex))
634 return true
635 end
636
637 if not self:getIsWorkAreaProcessing(spec.workAreas[speedRotatingPart.workAreaIndex]) then
638 return false
639 end
640 end
641
642 return superFunc(self, speedRotatingPart)
643end

getIsTypedWorkAreaActive

Description
Returns if at least one area from type is active
Definition
getIsTypedWorkAreaActive(integer areaType)
Arguments
integerareaTypearea type
Return Values
booleanisActiveisActive
tabletypedWorkAreasareas from given type
Code
588function WorkArea:getIsTypedWorkAreaActive(areaType)
589 local isActive = false
590 local typedWorkAreas = self:getTypedWorkAreas(areaType)
591 for _, workArea in pairs(typedWorkAreas) do
592 if self:getIsWorkAreaActive(workArea) then
593 isActive = true
594 break
595 end
596 end
597
598 return isActive, typedWorkAreas
599end

getIsWorkAreaActive

Description
Returns true if work area is active
Definition
getIsWorkAreaActive(table workArea)
Arguments
tableworkAreaworkArea
Return Values
booleanisActivework area is active
Code
479function WorkArea:getIsWorkAreaActive(workArea)
480 if workArea.requiresGroundContact == true and workArea.groundReferenceNode ~= nil then
481 if not self:getIsGroundReferenceNodeActive(workArea.groundReferenceNode) then
482 return false
483 end
484 end
485
486 if workArea.disableBackwards then
487 if self.movingDirection <= 0 then
488 return false
489 end
490 end
491
492 if workArea.onlyActiveWhenLowered then
493 if self.getIsLowered ~= nil then
494 if not self:getIsLowered(false) then
495 return false
496 end
497 end
498 end
499
500 return true
501end

getIsWorkAreaProcessing

Description
Returns true if work area is processing
Definition
getIsWorkAreaProcessing(table workArea)
Arguments
tableworkAreaworkArea
Code
528function WorkArea:getIsWorkAreaProcessing(workArea)
529 return workArea.lastProcessingTime + 200 >= g_currentMission.time
530end

getLastActiveMissionWork

Description
Definition
getLastActiveMissionWork()
Code
207function WorkArea:getLastActiveMissionWork()
208 return self.spec_workArea.lastActiveMissionWork
209end

getLastTouchedFarmlandFarmId

Description
Definition
getLastTouchedFarmlandFarmId()
Code
195function WorkArea:getLastTouchedFarmlandFarmId()
196 local spec = self.spec_workArea
197
198 if spec.lastAccessedFarmlandOwner ~= 0 then
199 return spec.lastAccessedFarmlandOwner
200 end
201
202 return 0
203end

getTypedNetworkAreas

Description
Returns positions of active work areas by type
Definition
getTypedNetworkAreas(integer areaType, boolean needsFieldProperty)
Arguments
integerareaTypearea type
booleanneedsFieldPropertyneeds field property
Return Values
tableworkAreasSendwork areas send
booleanshowFarmlandNotOwnedWarningshow field not owned warning
floatareasize of areas
Code
539function WorkArea:getTypedNetworkAreas(areaType, needsFieldProperty)
540 local workAreasSend = {}
541 local area = 0
542 local typedWorkAreas = self:getTypedWorkAreas(areaType)
543 local showFarmlandNotOwnedWarning = false
544
545 for _, workArea in pairs(typedWorkAreas) do
546 if self:getIsWorkAreaActive(workArea) then
547 local x,_,z = getWorldTranslation(workArea.start)
548
549 local isAccessible = not needsFieldProperty
550 if needsFieldProperty then
551 local farmId = g_currentMission:getFarmId()
552 isAccessible = g_currentMission.accessHandler:canFarmAccessLand(farmId, x, z) or g_missionManager:getIsMissionWorkAllowed(farmId, x, z, areaType)
553 end
554
555 if isAccessible then
556 local x1,_,z1 = getWorldTranslation(workArea.width)
557 local x2,_,z2 = getWorldTranslation(workArea.height)
558 area = area + math.abs((z1-z)*(x2-x) - (x1-x)*(z2-z))
559 table.insert(workAreasSend, {x,z,x1,z1,x2,z2})
560 else
561 showFarmlandNotOwnedWarning = true
562 end
563 end
564 end
565
566 return workAreasSend, showFarmlandNotOwnedWarning, area
567end

getTypedWorkAreas

Description
Returns areas by type
Definition
getTypedWorkAreas(integer areaType)
Arguments
integerareaTypearea type
Return Values
tableworkAreaswork areas
Code
573function WorkArea:getTypedWorkAreas(areaType)
574 local spec = self.spec_workArea
575 local workAreas = spec.workAreaByType[areaType]
576 if workAreas == nil then
577 workAreas = {}
578 end
579
580 return workAreas
581end

getWorkAreaByIndex

Description
Definition
getWorkAreaByIndex()
Code
470function WorkArea:getWorkAreaByIndex(workAreaIndex)
471 local spec = self.spec_workArea
472 return spec.workAreas[workAreaIndex]
473end

getWorkAreaWidth

Description
Returns last calculated work area width
Definition
getWorkAreaWidth(integer workAreaIndex)
Arguments
integerworkAreaIndexindex of work area
Code
520function WorkArea:getWorkAreaWidth(workAreaIndex)
521 local spec = self.spec_workArea
522 return spec.workAreas[workAreaIndex].workWidth
523end

initSpecialization

Description
Called on specialization initializing
Definition
initSpecialization()
Code
18function WorkArea.initSpecialization()
19 g_workAreaTypeManager:addWorkAreaType("default", false)
20 g_workAreaTypeManager:addWorkAreaType("auxiliary", false)
21
22 g_configurationManager:addConfigurationType("workArea", g_i18n:getText("configuration_workArea"), "workAreas", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
23
24 local schema = Vehicle.xmlSchema
25 schema:setXMLSpecializationType("WorkArea")
26
27 WorkArea.registerWorkAreaXMLPaths(schema, WorkArea.WORK_AREA_XML_KEY)
28 WorkArea.registerWorkAreaXMLPaths(schema, WorkArea.WORK_AREA_XML_CONFIG_KEY)
29
30 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.workAreas.workAreaConfigurations.workAreaConfiguration(?)")
31
32 schema:register(XMLValueType.INT, SpeedRotatingParts.SPEED_ROTATING_PART_XML_KEY .. "#workAreaIndex", "Work area index")
33
34 schema:setXMLSpecializationType()
35end

loadSpeedRotatingPartFromXML

Description
Loads speed rotating parts from xml
Definition
loadSpeedRotatingPartFromXML(table speedRotatingPart, integer xmlFile, string key)
Arguments
tablespeedRotatingPartspeedRotatingPart
integerxmlFileid of xml object
stringkeykey
Return Values
booleansuccesssuccess
Code
613function WorkArea:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
614 if not superFunc(self, speedRotatingPart, xmlFile, key) then
615 return false
616 end
617
618 speedRotatingPart.workAreaIndex = xmlFile:getValue(key.."#workAreaIndex")
619
620 return true
621end

loadWorkAreaFromXML

Description
Loads work areas from xml
Definition
loadWorkAreaFromXML(table workArea, integer xmlFile, string key)
Arguments
tableworkAreaworkArea
integerxmlFileid of xml object
stringkeykey
Return Values
booleansuccesssuccess
Code
363function WorkArea:loadWorkAreaFromXML(workArea, xmlFile, key)
364 XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. ".area#startIndex", key .. ".area#startNode") --FS17 to FS19
365 XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. ".area#widthIndex", key .. ".area#widthNode") --FS17 to FS19
366 XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. ".area#heightIndex", key .. ".area#heightNode") --FS17 to FS19
367
368 local start = xmlFile:getValue(key .. ".area#startNode", workArea.start, self.components, self.i3dMappings)
369 local width = xmlFile:getValue(key .. ".area#widthNode", workArea.width, self.components, self.i3dMappings)
370 local height = xmlFile:getValue(key .. ".area#heightNode", workArea.height, self.components, self.i3dMappings)
371
372 if start ~= nil and width ~= nil and height ~= nil then
373 if calcDistanceFrom(start, width) < 0.001 then
374 Logging.xmlError(xmlFile, "'start' and 'width' have the same position for '%s'!", key)
375 return false
376 end
377 if calcDistanceFrom(width, height) < 0.001 then
378 Logging.xmlError(xmlFile, "'width' and 'height' have the same position for '%s'!", key)
379 return false
380 end
381
382 local areaTypeStr = xmlFile:getValue(key .."#type")
383 workArea.type = g_workAreaTypeManager:getWorkAreaTypeIndexByName(areaTypeStr) or WorkAreaType.DEFAULT
384
385 if workArea.type == nil then
386 Logging.xmlWarning(xmlFile, "Invalid workArea type '%s' for workArea '%s'!", areaTypeStr, key)
387 return false
388 end
389
390 workArea.requiresGroundContact = xmlFile:getValue(key .. "#requiresGroundContact", true)
391
392 if workArea.type ~= WorkAreaType.AUXILIARY then
393
394 if workArea.requiresGroundContact then
395 XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. "#refNodeIndex", key .. ".groundReferenceNode#index") --FS17 to FS19
396 local groundReferenceNodeIndex = xmlFile:getValue(key ..".groundReferenceNode#index")
397 if groundReferenceNodeIndex == nil then
398 Logging.xmlWarning(xmlFile, "Missing groundReference 'groundReferenceNode#index' for workArea '%s'. Add requiresGroundContact=\"false\" if groundContact is not required!", key)
399 return false
400 end
401 local groundReferenceNode = self:getGroundReferenceNodeFromIndex(groundReferenceNodeIndex)
402 if groundReferenceNode ~= nil then
403 workArea.groundReferenceNode = groundReferenceNode
404 else
405 Logging.xmlWarning(xmlFile, "Invalid groundReferenceNode-index for workArea '%s'!", key)
406 return false
407 end
408 end
409
410 workArea.disableBackwards = xmlFile:getValue(key .. "#disableBackwards", true)
411 workArea.onlyActiveWhenLowered = xmlFile:getValue(key .. ".onlyActiveWhenLowered#value", false)
412
413 workArea.functionName = xmlFile:getValue(key .. "#functionName")
414 if workArea.functionName == nil then
415 Logging.xmlWarning(xmlFile, "Missing 'functionName' for workArea '%s'!", key)
416 return false
417 else
418 if self[workArea.functionName] == nil then
419 Logging.xmlWarning(xmlFile, "Given functionName '%s' not defined. Please add missing function or specialization!", tostring(workArea.functionName))
420 return false
421 end
422 workArea.processingFunction = self[workArea.functionName]
423 end
424
425 if g_isDevelopmentVersion then
426 if not SpecializationUtil.hasSpecialization(Cutter, self.specializations)
427 and not SpecializationUtil.hasSpecialization(Pickup, self.specializations)
428 and not SpecializationUtil.hasSpecialization(Drivable, self.specializations)
429 and xmlFile:getString(key .. ".onlyActiveWhenLowered#value") == nil then
430 Logging.xmlDevWarning(xmlFile, "Work area has no 'onlyActiveWhenLowered' attribute set! '%s'", key)
431 end
432 end
433
434 workArea.preprocessFunctionName = xmlFile:getValue(key .. "#preprocessFunctionName")
435 if workArea.preprocessFunctionName ~= nil then
436 if self[workArea.preprocessFunctionName] == nil then
437 Logging.xmlWarning(xmlFile, "Given preprocessFunctionName '%s' not defined. Please add missing function or specialization!", tostring(workArea.preprocessFunctionName))
438 return false
439 end
440 workArea.preprocessingFunction = self[workArea.preprocessFunctionName]
441 end
442
443 workArea.postprocessFunctionName = xmlFile:getValue(key .. "#postprocessFunctionName")
444 if workArea.postprocessFunctionName ~= nil then
445 if self[workArea.postprocessFunctionName] == nil then
446 Logging.xmlWarning(xmlFile, "Given postprocessFunctionName '%s' not defined. Please add missing function or specialization!", tostring(workArea.postprocessFunctionName))
447 return false
448 end
449 workArea.postprocessingFunction = self[workArea.postprocessFunctionName]
450 end
451
452 workArea.requiresOwnedFarmland = xmlFile:getValue(key .. "#requiresOwnedFarmland", true)
453 end
454
455 workArea.lastProcessingTime = 0
456 workArea.start = start
457 workArea.width = width
458 workArea.height = height
459
460 workArea.workWidth = -1
461
462 return true
463 end
464
465 return false
466end

onDraw

Description
Called on draw
Definition
onDraw(boolean isActiveForInput, boolean isSelected)
Arguments
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
342function WorkArea:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
343 local spec = self.spec_workArea
344 if spec.showFarmlandNotOwnedWarning then
345 -- If this vehicle is a mission vehicle, the land-not-owned warning only shows when not working the mission field
346 -- that could be because the land is unowned by the player but not for, or the vehicle is being used on owned land,
347 -- which is not allowed to prevent cheating with free vehicles. Therefor, if this is a mission vehicle, we
348 -- show a different warning
349 if self.propertyState == Vehicle.PROPERTY_STATE_MISSION then
350 g_currentMission:showBlinkingWarning(spec.warningCantUseMissionVehiclesOnOtherLand)
351 else
352 g_currentMission:showBlinkingWarning(spec.warningYouDontHaveAccessToThisLand)
353 end
354 end
355end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
107function WorkArea:onLoad(savegame)
108 local spec = self.spec_workArea
109
110 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.workAreas.workArea(0)#startIndex", "vehicle.workAreas.workArea(0).area#startIndex") --FS17 to FS19
111 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.workAreas.workArea(0)#widthIndex", "vehicle.workAreas.workArea(0).area#widthIndex") --FS17 to FS19
112 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.workAreas.workArea(0)#heightIndex", "vehicle.workAreas.workArea(0).area#heightIndex") --FS17 to FS19
113 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.workAreas.workArea(0)#foldMinLimit", "vehicle.workAreas.workArea(0).folding#minLimit") --FS17 to FS19
114 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.workAreas.workArea(0)#foldMaxLimit", "vehicle.workAreas.workArea(0).folding#maxLimit") --FS17 to FS19
115 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.workAreas.workArea(0)#refNodeIndex", "vehicle.workAreas.workArea(0).groundReferenceNode#index") --FS17 to FS19
116
117 local configurationId = Utils.getNoNil(self.configurations["workArea"], 1)
118 local configKey = string.format("vehicle.workAreas.workAreaConfigurations.workAreaConfiguration(%d)", configurationId - 1)
119 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.workAreas.workAreaConfigurations.workAreaConfiguration", configurationId , self.components, self)
120
121 if not self.xmlFile:hasProperty(configKey) then
122 configKey = "vehicle.workAreas"
123 end
124
125 spec.workAreas = {}
126 local i = 0
127 while true do
128 local key = string.format("%s.workArea(%d)", configKey, i)
129 if not self.xmlFile:hasProperty(key) then
130 break
131 end
132 local workArea = {}
133 if self:loadWorkAreaFromXML(workArea, self.xmlFile, key) then
134 table.insert(spec.workAreas, workArea)
135 workArea.index = #spec.workAreas
136
137 self:updateWorkAreaWidth(workArea.index)
138 end
139
140 i = i + 1
141 end
142
143 spec.workAreaByType = {}
144 for _, area in pairs(spec.workAreas) do
145 if spec.workAreaByType[area.type] == nil then
146 spec.workAreaByType[area.type] = {}
147 end
148 table.insert(spec.workAreaByType[area.type], area)
149 end
150
151 spec.lastAccessedFarmlandOwner = 0
152 spec.lastActiveMissionWork = false
153 spec.lastWorkedArea = -1
154 spec.showFarmlandNotOwnedWarning = false
155 spec.warningCantUseMissionVehiclesOnOtherLand = g_i18n:getText("warning_cantUseMissionVehiclesOnOtherLand")
156 spec.warningYouDontHaveAccessToThisLand = g_i18n:getText("warning_youDontHaveAccessToThisLand")
157end

onUpdateTick

Description
Called on update tick
Definition
onUpdateTick(float dt, boolean isActiveForInput, boolean isSelected)
Arguments
floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
216function WorkArea:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
217 local spec = self.spec_workArea
218 SpecializationUtil.raiseEvent(self, "onStartWorkAreaProcessing", dt, spec.workAreas)
219
220 spec.showFarmlandNotOwnedWarning = false
221 -- do not reset last accessed farmland owner
222 -- spec.lastAccessedFarmlandOwner = 0
223 local hasProcessed = false
224
225 local farmId = self:getActiveFarm()
226 if farmId == nil then -- Shop
227 farmId = AccessHandler.EVERYONE
228 end
229
230 local isOwned = false
231 local isBuyable = false
232 local allowWarning = false
233 for i=1, #spec.workAreas do
234 local workArea = spec.workAreas[i]
235 if workArea.type ~= WorkAreaType.AUXILIARY then
236 workArea.lastWorkedHectares = 0
237
238 local isAreaActive = self:getIsWorkAreaActive(workArea)
239 if isAreaActive and workArea.requiresOwnedFarmland then
240 local xs,_,zs = getWorldTranslation(workArea.start)
241 local isAccessible, farmlandOwner, buyable = self:getIsAccessibleAtWorldPosition(farmId, xs, zs, workArea.type)
242 isBuyable = isBuyable or buyable
243 if isAccessible then
244 if farmlandOwner ~= nil then
245 spec.lastAccessedFarmlandOwner = farmlandOwner
246 spec.lastActiveMissionWork = g_missionManager:getIsMissionWorkAllowed(farmId, xs, zs, workArea.type)
247 end
248 isOwned = true
249 else
250 local xw,_,zw = getWorldTranslation(workArea.width)
251 isAccessible, _, buyable = self:getIsAccessibleAtWorldPosition(farmId, xw, zw, workArea.type)
252 isBuyable = isBuyable or buyable
253 if isAccessible then
254 isOwned = true
255 else
256 local xh,_,zh = getWorldTranslation(workArea.height)
257 isAccessible, _, buyable = self:getIsAccessibleAtWorldPosition(farmId, xh, zh, workArea.type)
258 isBuyable = isBuyable or buyable
259 if isAccessible then
260 isOwned = true
261 else
262 local x = xw + (xh - xs)
263 local z = zw + (zh - zs)
264 isAccessible, _, buyable = self:getIsAccessibleAtWorldPosition(farmId, x, z, workArea.type)
265 isBuyable = isBuyable or buyable
266 if isAccessible then
267 isOwned = true
268 end
269 end
270 end
271 end
272
273 if not isOwned then
274 isAreaActive = false
275 end
276
277 allowWarning = isBuyable
278 end
279
280 if isAreaActive then
281 if workArea.preprocessingFunction ~= nil then
282 workArea.preprocessingFunction(self, workArea, dt)
283 end
284
285 if workArea.processingFunction ~= nil then
286 local realArea, _ = workArea.processingFunction(self, workArea, dt)
287
288 if realArea > 0 then
289 workArea.lastWorkedHectares = MathUtil.areaToHa(realArea, g_currentMission:getFruitPixelsToSqm()) -- 4096px are mapped to 2048m
290
291 workArea.lastProcessingTime = g_currentMission.time
292
293 -- Adding an area of interest for the wildlife spawners / keep (xw,zw) and (xh,zh)
294 if g_currentMission.wildlifeSpawner ~= nil then
295 local workAreaType = g_workAreaTypeManager:getWorkAreaTypeByIndex(workArea.type)
296 if workAreaType.attractWildlife then
297 local xw,_,zw = getWorldTranslation(workArea.width)
298 local xh,_,zh = getWorldTranslation(workArea.height)
299
300 local radius = 3.0
301 local posX = 0.5 * xw + 0.5 * xh
302 local posZ = 0.5 * zw + 0.5 * zh
303 local lifeTime = 0
304 g_currentMission.wildlifeSpawner:addAreaOfInterest(lifeTime, posX, posZ, radius)
305 end
306 end
307 else
308 workArea.lastWorkedHectares = 0
309 end
310 end
311
312 if workArea.postprocessingFunction ~= nil then
313 workArea.postprocessingFunction(self, workArea, dt)
314 end
315
316 hasProcessed = true
317 end
318 end
319 end
320
321 -- display warning if none of the work areas got valid owned ground
322 if allowWarning and not isOwned then
323 spec.showFarmlandNotOwnedWarning = true
324 end
325
326 SpecializationUtil.raiseEvent(self, "onEndWorkAreaProcessing", dt, hasProcessed)
327
328 if spec.lastWorkedArea >= 0 then
329 local stats = g_currentMission:farmStats(self:getLastTouchedFarmlandFarmId())
330 local ha = MathUtil.areaToHa(spec.lastWorkedArea, g_currentMission:getFruitPixelsToSqm()) -- 4096px are mapped to 2048m
331 stats:updateStats("workedHectares", ha)
332 stats:updateStats("workedTime", dt/(1000*60))
333
334 spec.lastWorkedArea = -1
335 end
336end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
58function WorkArea.prerequisitesPresent(specializations)
59 return SpecializationUtil.hasSpecialization(GroundReference, specializations)
60end

registerEventListeners

Description
Definition
registerEventListeners()
Code
98function WorkArea.registerEventListeners(vehicleType)
99 SpecializationUtil.registerEventListener(vehicleType, "onLoad", WorkArea)
100 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", WorkArea)
101 SpecializationUtil.registerEventListener(vehicleType, "onDraw", WorkArea)
102end

registerEvents

Description
Definition
registerEvents()
Code
64function WorkArea.registerEvents(vehicleType)
65 SpecializationUtil.registerEvent(vehicleType, "onStartWorkAreaProcessing")
66 SpecializationUtil.registerEvent(vehicleType, "onEndWorkAreaProcessing")
67end

registerFunctions

Description
Definition
registerFunctions()
Code
71function WorkArea.registerFunctions(vehicleType)
72 SpecializationUtil.registerFunction(vehicleType, "loadWorkAreaFromXML", WorkArea.loadWorkAreaFromXML)
73 SpecializationUtil.registerFunction(vehicleType, "getWorkAreaByIndex", WorkArea.getWorkAreaByIndex)
74 SpecializationUtil.registerFunction(vehicleType, "getIsWorkAreaActive", WorkArea.getIsWorkAreaActive)
75 SpecializationUtil.registerFunction(vehicleType, "updateWorkAreaWidth", WorkArea.updateWorkAreaWidth)
76 SpecializationUtil.registerFunction(vehicleType, "getWorkAreaWidth", WorkArea.getWorkAreaWidth)
77 SpecializationUtil.registerFunction(vehicleType, "getIsWorkAreaProcessing", WorkArea.getIsWorkAreaProcessing)
78 SpecializationUtil.registerFunction(vehicleType, "getTypedNetworkAreas", WorkArea.getTypedNetworkAreas)
79 SpecializationUtil.registerFunction(vehicleType, "getTypedWorkAreas", WorkArea.getTypedWorkAreas)
80 SpecializationUtil.registerFunction(vehicleType, "getIsTypedWorkAreaActive", WorkArea.getIsTypedWorkAreaActive)
81 SpecializationUtil.registerFunction(vehicleType, "getIsFarmlandNotOwnedWarningShown", WorkArea.getIsFarmlandNotOwnedWarningShown)
82 SpecializationUtil.registerFunction(vehicleType, "getLastTouchedFarmlandFarmId", WorkArea.getLastTouchedFarmlandFarmId)
83 SpecializationUtil.registerFunction(vehicleType, "getLastActiveMissionWork", WorkArea.getLastActiveMissionWork)
84 SpecializationUtil.registerFunction(vehicleType, "getIsAccessibleAtWorldPosition", WorkArea.getIsAccessibleAtWorldPosition)
85 SpecializationUtil.registerFunction(vehicleType, "updateLastWorkedArea", WorkArea.updateLastWorkedArea)
86end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
90function WorkArea.registerOverwrittenFunctions(vehicleType)
91 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSpeedRotatingPartFromXML", WorkArea.loadSpeedRotatingPartFromXML)
92 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSpeedRotatingPartActive", WorkArea.getIsSpeedRotatingPartActive)
93 SpecializationUtil.registerOverwrittenFunction(vehicleType, "checkMovingPartDirtyUpdateNode", WorkArea.checkMovingPartDirtyUpdateNode)
94end

registerWorkAreaXMLPaths

Description
Definition
registerWorkAreaXMLPaths()
Code
39function WorkArea.registerWorkAreaXMLPaths(schema, basePath)
40 schema:register(XMLValueType.STRING, basePath .. "#type", "Work area type", "DEFAULT")
41 schema:register(XMLValueType.BOOL, basePath .. "#requiresGroundContact", "Requires ground contact to work", true)
42 schema:register(XMLValueType.BOOL, basePath .. "#disableBackwards", "Area is disabled while driving backwards", true)
43 schema:register(XMLValueType.BOOL, basePath .. "#requiresOwnedFarmland", "Requires owned farmland", true)
44 schema:register(XMLValueType.STRING, basePath .. "#functionName", "Work area script function")
45 schema:register(XMLValueType.STRING, basePath .. "#preprocessFunctionName", "Pre process work area script function")
46 schema:register(XMLValueType.STRING, basePath .. "#postprocessFunctionName", "Post process work area script function")
47
48 schema:register(XMLValueType.NODE_INDEX, basePath .. ".area#startNode", "Start node")
49 schema:register(XMLValueType.NODE_INDEX, basePath .. ".area#widthNode", "Width node")
50 schema:register(XMLValueType.NODE_INDEX, basePath .. ".area#heightNode", "Height node")
51
52 schema:register(XMLValueType.INT, basePath .. ".groundReferenceNode#index", "Ground reference node index")
53 schema:register(XMLValueType.BOOL, basePath .. ".onlyActiveWhenLowered#value", "Work area is only active when lowered", false)
54end

updateLastWorkedArea

Description
Definition
updateLastWorkedArea()
Code
188function WorkArea:updateLastWorkedArea(area)
189 local spec = self.spec_workArea
190 spec.lastWorkedArea = math.max(area, spec.lastWorkedArea)
191end

updateWorkAreaWidth

Description
Updates work area width based on position of area nodes
Definition
updateWorkAreaWidth(integer workAreaIndex)
Arguments
integerworkAreaIndexindex of work area
Code
506function WorkArea:updateWorkAreaWidth(workAreaIndex)
507 local spec = self.spec_workArea
508 local workArea = spec.workAreas[workAreaIndex]
509
510 local x1, _, _ = localToLocal(self.components[1].node, workArea.start, 0, 0, 0)
511 local x2, _, _ = localToLocal(self.components[1].node, workArea.width, 0, 0, 0)
512 local x3, _, _ = localToLocal(self.components[1].node, workArea.height, 0, 0, 0)
513
514 workArea.workWidth = math.max(x1, x2, x3) - math.min(x1, x2, x3)
515end