LUADOC - Farming Simulator 19

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

getIsAccessibleAtWorldPosition

Description
Definition
getIsAccessibleAtWorldPosition()
Code
106function WorkArea:getIsAccessibleAtWorldPosition(farmId, x, z, workAreaType)
107 -- Disallow mission vehicles outside mission fields
108 if self.propertyState == Vehicle.PROPERTY_STATE_MISSION then
109 return g_missionManager:getIsMissionWorkAllowed(farmId, x, z, workAreaType)
110 end
111
112 local farmlandId = g_farmlandManager:getFarmlandIdAtWorldPosition(x, z)
113 if farmlandId == nil then -- no valid farmland, or not buyable
114 return false
115 end
116
117 local landOwner = g_farmlandManager:getFarmlandOwner(farmlandId)
118 local accessible = (landOwner ~= 0 and g_currentMission.accessHandler:canFarmAccessOtherId(farmId, landOwner))
119 or g_missionManager:getIsMissionWorkAllowed(farmId, x, z, workAreaType)
120
121 return accessible, landOwner
122end

getIsFarmlandNotOwnedWarningShown

Description
Definition
getIsFarmlandNotOwnedWarningShown()
Code
458function WorkArea:getIsFarmlandNotOwnedWarningShown()
459 return self.spec_workArea.showFarmlandNotOwnedWarning
460end

getIsSpeedRotatingPartActive

Description
Returns true if speed rotating part is active
Definition
getIsSpeedRotatingPartActive(table speedRotatingPart)
Arguments
tablespeedRotatingPartspeedRotatingPart
Return Values
booleanisActivespeed rotating part is active
Code
482function WorkArea:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
483 if speedRotatingPart.workAreaIndex ~= nil then
484 local spec = self.spec_workArea
485 local workArea = spec.workAreas[speedRotatingPart.workAreaIndex]
486 if workArea == nil then
487 speedRotatingPart.workAreaIndex = nil
488 g_logManager:xmlWarning(self.configFileName, "Invalid workAreaIndex '%s'. Indexing starts with 1!", tostring(speedRotatingPart.workAreaIndex))
489 return true
490 end
491
492 if not self:getIsWorkAreaProcessing(spec.workAreas[speedRotatingPart.workAreaIndex]) then
493 return false
494 end
495 end
496
497 return superFunc(self, speedRotatingPart)
498end

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
443function WorkArea:getIsTypedWorkAreaActive(areaType)
444 local isActive = false
445 local typedWorkAreas = self:getTypedWorkAreas(areaType)
446 for _, workArea in pairs(typedWorkAreas) do
447 if self:getIsWorkAreaActive(workArea) then
448 isActive = true
449 break
450 end
451 end
452
453 return isActive, typedWorkAreas
454end

getIsWorkAreaActive

Description
Returns true if work area is active
Definition
getIsWorkAreaActive(table workArea)
Arguments
tableworkAreaworkArea
Return Values
booleanisActivework area is active
Code
363function WorkArea:getIsWorkAreaActive(workArea)
364
365 local isActive = true
366 if workArea.requiresGroundContact == true and workArea.groundReferenceNode ~= nil then
367 isActive = self:getIsGroundReferenceNodeActive(workArea.groundReferenceNode)
368 end
369
370 if isActive and workArea.disableBackwards then
371 isActive = isActive and self.movingDirection > 0
372 end
373
374 return isActive
375end

getIsWorkAreaProcessing

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

getLastTouchedFarmlandFarmId

Description
Definition
getLastTouchedFarmlandFarmId()
Code
126function WorkArea:getLastTouchedFarmlandFarmId()
127 local spec = self.spec_workArea
128
129 if spec.lastAccessedFarmlandOwner ~= 0 then
130 return spec.lastAccessedFarmlandOwner
131 end
132
133 return 0
134end

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
399function WorkArea:getTypedNetworkAreas(areaType, needsFieldProperty)
400 local workAreasSend = {}
401 local area = 0
402 local typedWorkAreas = self:getTypedWorkAreas(areaType)
403 local showFarmlandNotOwnedWarning = false
404
405 for _, workArea in pairs(typedWorkAreas) do
406 if self:getIsWorkAreaActive(workArea) then
407 local x,_,z = getWorldTranslation(workArea.start)
408
409 local isAccessible = not needsFieldProperty
410 if needsFieldProperty then
411 local farmId = g_currentMission:getFarmId()
412 isAccessible = g_currentMission.accessHandler:canFarmAccessLand(farmId, x, z) or g_missionManager:getIsMissionWorkAllowed(farmId, x, z, areaType)
413 end
414
415 if isAccessible then
416 local x1,_,z1 = getWorldTranslation(workArea.width)
417 local x2,_,z2 = getWorldTranslation(workArea.height)
418 area = area + math.abs((z1-z)*(x2-x) - (x1-x)*(z2-z))
419 table.insert(workAreasSend, {x,z,x1,z1,x2,z2})
420 else
421 showFarmlandNotOwnedWarning = true
422 end
423 end
424 end
425
426 return workAreasSend, showFarmlandNotOwnedWarning, area
427end

getTypedWorkAreas

Description
Returns areas by type
Definition
getTypedWorkAreas(integer areaType)
Arguments
integerareaTypearea type
Return Values
tableworkAreaswork areas
Code
433function WorkArea:getTypedWorkAreas(areaType)
434 local spec = self.spec_workArea
435 return Utils.getNoNil(spec.workAreaByType[areaType], {})
436end

getWorkAreaByIndex

Description
Definition
getWorkAreaByIndex()
Code
354function WorkArea:getWorkAreaByIndex(workAreaIndex)
355 local spec = self.spec_workArea
356 return spec.workAreas[workAreaIndex]
357end

initSpecialization

Description
Called on specialization initializing
Definition
initSpecialization()
Code
15function WorkArea.initSpecialization()
16 g_workAreaTypeManager:addWorkAreaType("default", false)
17 g_workAreaTypeManager:addWorkAreaType("auxiliary", false)
18end

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
468function WorkArea:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
469 if not superFunc(self, speedRotatingPart, xmlFile, key) then
470 return false
471 end
472
473 speedRotatingPart.workAreaIndex = getXMLInt(xmlFile, key.."#workAreaIndex")
474
475 return true
476end

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
267function WorkArea:loadWorkAreaFromXML(workArea, xmlFile, key)
268 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. ".area#startIndex", key .. ".area#startNode") --FS17 to FS19
269 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. ".area#widthIndex", key .. ".area#widthNode") --FS17 to FS19
270 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. ".area#heightIndex", key .. ".area#heightNode") --FS17 to FS19
271
272 local start = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".area#startNode"), self.i3dMappings)
273 local width = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".area#widthNode"), self.i3dMappings)
274 local height = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".area#heightNode"), self.i3dMappings)
275
276 if start ~= nil and width ~= nil and height ~= nil then
277 local areaTypeStr = getXMLString(xmlFile, key .."#type")
278 workArea.type = g_workAreaTypeManager:getWorkAreaTypeIndexByName(areaTypeStr) or WorkAreaType.DEFAULT
279
280 if workArea.type == nil then
281 g_logManager:xmlWarning(self.configFileName, "Invalid workArea type '%s' for workArea '%s'!", areaTypeStr, key)
282 return false
283 end
284
285 workArea.isSynchronized = Utils.getNoNil(getXMLBool(xmlFile, key.."#isSynchronized"), true)
286 workArea.requiresGroundContact = Utils.getNoNil(getXMLBool(xmlFile, key .. "#requiresGroundContact"), true)
287
288 if workArea.type ~= WorkAreaType.AUXILIARY then
289
290 if workArea.requiresGroundContact then
291 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. "#refNodeIndex", key .. ".groundReferenceNode#index") --FS17 to FS19
292 local groundReferenceNodeIndex = getXMLInt(xmlFile, key ..".groundReferenceNode#index")
293 if groundReferenceNodeIndex == nil then
294 g_logManager:xmlWarning(self.configFileName, "Missing groundReference 'groundReferenceNode#index' for workArea '%s'. Add requiresGroundContact=\"false\" if groundContact is not required!", key)
295 return false
296 end
297 local groundReferenceNode = self:getGroundReferenceNodeFromIndex(groundReferenceNodeIndex)
298 if groundReferenceNode ~= nil then
299 workArea.groundReferenceNode = groundReferenceNode
300 else
301 g_logManager:xmlWarning(self.configFileName, "Invalid groundReferenceNode-index for workArea '%s'!", key)
302 return false
303 end
304 end
305
306 workArea.disableBackwards = Utils.getNoNil(getXMLBool(xmlFile, key .. "#disableBackwards"), true)
307
308 workArea.functionName = getXMLString(xmlFile, key .. "#functionName")
309 if workArea.functionName == nil then
310 g_logManager:xmlWarning(self.configFileName, "Missing 'functionName' for workArea '%s'!", key)
311 return false
312 else
313 if self[workArea.functionName] == nil then
314 g_logManager:xmlWarning(self.configFileName, "Given functionName '%s' not defined. Please add missing function or specialization!", tostring(workArea.functionName))
315 return false
316 end
317 workArea.processingFunction = self[workArea.functionName]
318 end
319
320 workArea.preprocessFunctionName = getXMLString(xmlFile, key .. "#preprocessFunctionName")
321 if workArea.preprocessFunctionName ~= nil then
322 if self[workArea.preprocessFunctionName] == nil then
323 g_logManager:xmlWarning(self.configFileName, "Given preprocessFunctionName '%s' not defined. Please add missing function or specialization!", tostring(workArea.preprocessFunctionName))
324 return false
325 end
326 workArea.preprocessingFunction = self[workArea.preprocessFunctionName]
327 end
328
329 workArea.postprocessFunctionName = getXMLString(xmlFile, key .. "#postprocessFunctionName")
330 if workArea.postprocessFunctionName ~= nil then
331 if self[workArea.postprocessFunctionName] == nil then
332 g_logManager:xmlWarning(self.configFileName, "Given postprocessFunctionName '%s' not defined. Please add missing function or specialization!", tostring(workArea.postprocessFunctionName))
333 return false
334 end
335 workArea.postprocessingFunction = self[workArea.postprocessFunctionName]
336 end
337
338 workArea.requiresOwnedFarmland = Utils.getNoNil(getXMLBool(xmlFile, key .. "#requiresOwnedFarmland"), true)
339 end
340
341 workArea.lastProcessingTime = 0
342 workArea.start = start
343 workArea.width = width
344 workArea.height = height
345
346 return true
347 end
348
349 return false
350end

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
246function WorkArea:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
247 local spec = self.spec_workArea
248 if spec.showFarmlandNotOwnedWarning then
249 -- If this vehicle is a mission vehicle, the land-not-owned warning only shows when not working the mission field
250 -- that could be because the land is unowned by the player but not for, or the vehicle is being used on owned land,
251 -- which is not allowed to prevent cheating with free vehicles. Therefor, if this is a mission vehicle, we
252 -- show a different warning
253 if self.propertyState == Vehicle.PROPERTY_STATE_MISSION then
254 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_cantUseMissionVehiclesOnOtherLand"))
255 else
256 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_youDontHaveAccessToThisLand"))
257 end
258 end
259end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
67function WorkArea:onLoad(savegame)
68 local spec = self.spec_workArea
69
70 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.workAreas.workArea(0)#startIndex", "vehicle.workAreas.workArea(0).area#startIndex") --FS17 to FS19
71 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.workAreas.workArea(0)#widthIndex", "vehicle.workAreas.workArea(0).area#widthIndex") --FS17 to FS19
72 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.workAreas.workArea(0)#heightIndex", "vehicle.workAreas.workArea(0).area#heightIndex") --FS17 to FS19
73 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.workAreas.workArea(0)#foldMinLimit", "vehicle.workAreas.workArea(0).folding#minLimit") --FS17 to FS19
74 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.workAreas.workArea(0)#foldMaxLimit", "vehicle.workAreas.workArea(0).folding#maxLimit") --FS17 to FS19
75 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.workAreas.workArea(0)#refNodeIndex", "vehicle.workAreas.workArea(0).groundReferenceNode#index") --FS17 to FS19
76
77 spec.workAreas = {}
78 local i = 0
79 while true do
80 local key = string.format("vehicle.workAreas.workArea(%d)", i)
81 if not hasXMLProperty(self.xmlFile, key) then
82 break
83 end
84 local workArea = {}
85 if self:loadWorkAreaFromXML(workArea, self.xmlFile, key) then
86 table.insert(spec.workAreas, workArea)
87 workArea.index = #spec.workAreas
88 end
89 i = i + 1
90 end
91
92 spec.workAreaByType = {}
93 for _, area in pairs(spec.workAreas) do
94 if spec.workAreaByType[area.type] == nil then
95 spec.workAreaByType[area.type] = {}
96 end
97 table.insert(spec.workAreaByType[area.type], area)
98 end
99
100 spec.lastAccessedFarmlandOwner = 0
101 spec.showFarmlandNotOwnedWarning = false
102end

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
141function WorkArea:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
142 local spec = self.spec_workArea
143 SpecializationUtil.raiseEvent(self, "onStartWorkAreaProcessing", dt, spec.workAreas)
144
145 spec.showFarmlandNotOwnedWarning = false
146 -- do not reset last accessed farmland owner
147 -- spec.lastAccessedFarmlandOwner = 0
148 local hasProcessed = false
149
150 local isOwned = false
151 local allowWarning = false
152 for _,workArea in ipairs(spec.workAreas) do
153 if workArea.type ~= WorkAreaType.AUXILIARY then
154 workArea.lastWorkedHectares = 0
155
156 local isAreaActive = self:getIsWorkAreaActive(workArea)
157 if isAreaActive and workArea.requiresOwnedFarmland then
158 local farmId = self:getActiveFarm()
159 if farmId == nil then -- Shop
160 farmId = AccessHandler.EVERYONE
161 end
162
163 local xs,_,zs = getWorldTranslation(workArea.start)
164 local isAccessible, farmlandOwner = self:getIsAccessibleAtWorldPosition(farmId, xs, zs, workArea.type)
165 if isAccessible then
166 if farmlandOwner ~= nil then
167 spec.lastAccessedFarmlandOwner = farmlandOwner
168 end
169 isOwned = true
170 else
171 local xw,_,zw = getWorldTranslation(workArea.width)
172 if self:getIsAccessibleAtWorldPosition(farmId, xw, zw, workArea.type) then
173 isOwned = true
174 else
175 local xh,_,zh = getWorldTranslation(workArea.height)
176 if self:getIsAccessibleAtWorldPosition(farmId, xh, zh, workArea.type) then
177 isOwned = true
178 else
179 local x = xw + (xh - xs)
180 local z = zw + (zh - zs)
181 if self:getIsAccessibleAtWorldPosition(farmId, x, z, workArea.type) then
182 isOwned = true
183 end
184 end
185 end
186 end
187
188 if not isOwned then
189 isAreaActive = false
190 end
191
192 allowWarning = true
193 end
194
195 if isAreaActive then
196 if workArea.preprocessingFunction ~= nil then
197 workArea.preprocessingFunction(self, workArea, dt)
198 end
199
200 if workArea.processingFunction ~= nil then
201 local realArea, _ = workArea.processingFunction(self, workArea, dt)
202
203 workArea.lastWorkedHectares = MathUtil.areaToHa(realArea, g_currentMission:getFruitPixelsToSqm()) -- 4096px are mapped to 2048m
204
205 if workArea.lastWorkedHectares > 0 then
206 self:setWorkAreaProcessingTime(workArea, g_currentMission.time)
207 end
208
209 -- Adding an area of interest for the wildlife spawners / keep (xw,zw) and (xh,zh)
210 if g_wildlifeSpawnerManager ~= nil and realArea > 0 then
211 local workAreaType = g_workAreaTypeManager:getWorkAreaTypeByIndex(workArea.type)
212 if workAreaType.attractWildlife then
213 local xw,_,zw = getWorldTranslation(workArea.width)
214 local xh,_,zh = getWorldTranslation(workArea.height)
215
216 local radius = 3.0
217 local posX = 0.5 * xw + 0.5 * xh
218 local posZ = 0.5 * zw + 0.5 * zh
219 local lifeTime = 0
220 g_wildlifeSpawnerManager:addAreaOfInterest(lifeTime, posX, posZ, radius)
221 end
222 end
223 end
224
225 if workArea.postprocessingFunction ~= nil then
226 workArea.postprocessingFunction(self, workArea, dt)
227 end
228
229 hasProcessed = true
230 end
231 end
232 end
233
234 -- display warning if none of the work areas got valid owned ground
235 if allowWarning and not isOwned then
236 spec.showFarmlandNotOwnedWarning = true
237 end
238
239 SpecializationUtil.raiseEvent(self, "onEndWorkAreaProcessing", dt, hasProcessed)
240end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
22function WorkArea.prerequisitesPresent(specializations)
23 return SpecializationUtil.hasSpecialization(GroundReference, specializations)
24end

registerEventListeners

Description
Definition
registerEventListeners()
Code
58function WorkArea.registerEventListeners(vehicleType)
59 SpecializationUtil.registerEventListener(vehicleType, "onLoad", WorkArea)
60 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", WorkArea)
61 SpecializationUtil.registerEventListener(vehicleType, "onDraw", WorkArea)
62end

registerEvents

Description
Definition
registerEvents()
Code
28function WorkArea.registerEvents(vehicleType)
29 SpecializationUtil.registerEvent(vehicleType, "onStartWorkAreaProcessing")
30 SpecializationUtil.registerEvent(vehicleType, "onEndWorkAreaProcessing")
31end

registerFunctions

Description
Definition
registerFunctions()
Code
35function WorkArea.registerFunctions(vehicleType)
36 SpecializationUtil.registerFunction(vehicleType, "loadWorkAreaFromXML", WorkArea.loadWorkAreaFromXML)
37 SpecializationUtil.registerFunction(vehicleType, "getWorkAreaByIndex", WorkArea.getWorkAreaByIndex)
38 SpecializationUtil.registerFunction(vehicleType, "getIsWorkAreaActive", WorkArea.getIsWorkAreaActive)
39 SpecializationUtil.registerFunction(vehicleType, "setWorkAreaProcessingTime", WorkArea.setWorkAreaProcessingTime)
40 SpecializationUtil.registerFunction(vehicleType, "getIsWorkAreaProcessing", WorkArea.getIsWorkAreaProcessing)
41 SpecializationUtil.registerFunction(vehicleType, "getTypedNetworkAreas", WorkArea.getTypedNetworkAreas)
42 SpecializationUtil.registerFunction(vehicleType, "getTypedWorkAreas", WorkArea.getTypedWorkAreas)
43 SpecializationUtil.registerFunction(vehicleType, "getIsTypedWorkAreaActive", WorkArea.getIsTypedWorkAreaActive)
44 SpecializationUtil.registerFunction(vehicleType, "getIsFarmlandNotOwnedWarningShown", WorkArea.getIsFarmlandNotOwnedWarningShown)
45 SpecializationUtil.registerFunction(vehicleType, "getLastTouchedFarmlandFarmId", WorkArea.getLastTouchedFarmlandFarmId)
46 SpecializationUtil.registerFunction(vehicleType, "getIsAccessibleAtWorldPosition", WorkArea.getIsAccessibleAtWorldPosition)
47end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
51function WorkArea.registerOverwrittenFunctions(vehicleType)
52 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSpeedRotatingPartFromXML", WorkArea.loadSpeedRotatingPartFromXML)
53 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSpeedRotatingPartActive", WorkArea.getIsSpeedRotatingPartActive)
54end

setWorkAreaProcessingTime

Description
Sets work area processing time
Definition
setWorkAreaProcessingTime(table workArea, float time)
Arguments
tableworkAreaworkArea
floattimetime
Code
381function WorkArea:setWorkAreaProcessingTime(workArea, time)
382 workArea.lastProcessingTime = time
383end