LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

PlaceableLeveling

Description
Specialization for placeables
Functions

addDeformationArea

Description
Add a leveling area of a placeable to a terrain deformation object.
Definition
addDeformationArea(terrainDeform TerrainDeformation, area Table, terrainBrushId Terrain)
Arguments
terrainDeformTerrainDeformationinstance
areaTablewhich holds area nodes, {start=origin node, width=first side area delimiter node, height=second side area delimiter node}
terrainBrushIdTerrainbrush ID, currently this is a map layer index (zero-based)
Code
250function PlaceableLeveling:addDeformationArea(deformationObject, area, terrainBrushId, writeBlockedAreaMap)
251 local worldStartX, worldStartY, worldStartZ = getWorldTranslation(area.start)
252 local worldSide1X, worldSide1Y, worldSide1Z = getWorldTranslation(area.width)
253 local worldSide2X, worldSide2Y, worldSide2Z = getWorldTranslation(area.height)
254
255 local side1X, side1Y, side1Z = worldSide1X - worldStartX, worldSide1Y - worldStartY, worldSide1Z - worldStartZ
256 local side2X, side2Y, side2Z = worldSide2X - worldStartX, worldSide2Y - worldStartY, worldSide2Z - worldStartZ
257
258 deformationObject:addArea(
259 worldStartX, worldStartY, worldStartZ,
260 side1X, side1Y, side1Z,
261 side2X, side2Y, side2Z,
262 terrainBrushId,
263 writeBlockedAreaMap
264 )
265end

applyDeformation

Description
Definition
applyDeformation()
Code
275function PlaceableLeveling:applyDeformation(isPreview, callback)
276 local deformationObjects = self:getDeformationObjects(g_currentMission.terrainRootNode)
277
278 if #deformationObjects == 0 then
279 callback(TerrainDeformation.STATE_SUCCESS, 0, nil)
280 return
281 end
282
283 local recursiveCallback = {}
284 recursiveCallback.index = 1
285 recursiveCallback.volume = 0
286 recursiveCallback.deformationObjects = deformationObjects
287 recursiveCallback.finishCallback = callback
288 recursiveCallback.callback = function(target, errorCode, displacedVolume, blockedObjectName)
289 if errorCode ~= TerrainDeformation.STATE_SUCCESS then
290 -- Finished: delete all objects
291 local objects = {}
292 for _, object in ipairs(target.deformationObjects) do
293 table.insert(objects, object)
294 end
295
296 -- do the delete in the next frame
297 g_asyncTaskManager:addTask(function()
298 for _, object in ipairs(objects) do
299 object:delete()
300 end
301 end)
302
303 target.finishCallback(errorCode, target.volume, blockedObjectName)
304 return
305 end
306
307 target.volume = target.volume + displacedVolume
308 target.index = target.index + 1
309
310 local nextDeformationObject = target.deformationObjects[target.index]
311 if nextDeformationObject ~= nil then
312 g_terrainDeformationQueue:queueJob(nextDeformationObject, isPreview, "callback", target)
313 else
314 -- Finished: delete all objects
315 local objects = {}
316 for _, object in ipairs(target.deformationObjects) do
317 table.insert(objects, object)
318 end
319
320 -- do the delete in the next frame
321 g_asyncTaskManager:addTask(function()
322 for _, object in ipairs(objects) do
323 object:delete()
324 end
325 end)
326
327 target.finishCallback(TerrainDeformation.STATE_SUCCESS, target.volume, nil)
328 end
329 end
330
331 g_terrainDeformationQueue:queueJob(deformationObjects[1], isPreview, "callback", recursiveCallback)
332end

getDeformationObjects

Description
Create a TerrainDeformation object for leveling the ground beneath this placeable and any ramps.
Definition
getDeformationObjects(int terrainRootNode, bool forBlockingOnly, bool isBlocking)
Arguments
intterrainRootNodeMap terrain root node ID
boolforBlockingOnlyCreate the object only to write into the blocking map
boolisBlockingIf forBlockingOnly is true, this also tells the method if we intend to block areas (true) or unblock them (false)
Code
190function PlaceableLeveling:getDeformationObjects(terrainRootNode, forBlockingOnly, isBlocking)
191 local spec = self.spec_leveling
192 local deformationObjects = {}
193
194 if not forBlockingOnly then
195 isBlocking = false
196 end
197
198 if terrainRootNode ~= nil and terrainRootNode ~= 0 then
199 if #spec.levelAreas > 0 then
200 local deformationObject = TerrainDeformation.new(terrainRootNode)
201
202 if g_densityMapHeightManager.placementCollisionMap ~= nil then
203 deformationObject:setBlockedAreaMap(g_densityMapHeightManager.placementCollisionMap, 0)
204 end
205
206 for _, levelArea in pairs(spec.levelAreas) do
207 local layer = -1
208 if levelArea.groundType ~= nil then
209 layer = g_groundTypeManager:getTerrainLayerByType(levelArea.groundType)
210 end
211 self:addDeformationArea(deformationObject, levelArea, layer, true)
212 end
213
214 if spec.smoothingGroundType ~= nil then
215 deformationObject:setOutsideAreaBrush(g_groundTypeManager:getTerrainLayerByType(spec.smoothingGroundType))
216 end
217
218 deformationObject:setOutsideAreaConstraints(spec.maxSmoothDistance, spec.maxSlope, spec.maxEdgeAngle)
219
220 deformationObject:setBlockedAreaMaxDisplacement(0.1)
221 deformationObject:setDynamicObjectCollisionMask(CollisionMask.LEVELING)
222 deformationObject:setDynamicObjectMaxDisplacement(0.3)
223 table.insert(deformationObjects, deformationObject)
224 end
225 end
226
227 if not forBlockingOnly then
228 if #spec.paintAreas > 0 then
229 local paintingObject = TerrainDeformation.new(terrainRootNode)
230 for _, paintArea in pairs(spec.paintAreas) do
231 local layer = -1
232 if paintArea.groundType ~= nil then
233 layer = g_groundTypeManager:getTerrainLayerByType(paintArea.groundType)
234 end
235 self:addDeformationArea(paintingObject, paintArea, layer, true)
236 end
237 paintingObject:enablePaintingMode()
238 table.insert(deformationObjects, paintingObject)
239 end
240 end
241
242 return deformationObjects
243end

getRequiresLeveling

Description
Definition
getRequiresLeveling()
Code
269function PlaceableLeveling:getRequiresLeveling()
270 return self.spec_leveling.requiresLeveling
271end

loadLevelArea

Description
Definition
loadLevelArea()
Code
129function PlaceableLeveling:loadLevelArea(xmlFile, key, area)
130 local start = xmlFile:getValue(key .. "#startNode", nil, self.components, self.i3dMappings)
131 if start == nil then
132 Logging.xmlWarning(xmlFile, "Leveling area start node not defined for '%s'", key)
133 return false
134 end
135
136 local width = xmlFile:getValue(key .. "#widthNode", nil, self.components, self.i3dMappings)
137 if width == nil then
138 Logging.xmlWarning(xmlFile, "Leveling area width node not defined for '%s'", key)
139 return false
140 end
141
142 local height = xmlFile:getValue(key .. "#heightNode", nil, self.components, self.i3dMappings)
143 if height == nil then
144 Logging.xmlWarning(xmlFile, "Leveling area height node not defined for '%s'", key)
145 return false
146 end
147
148 area.start = start
149 area.width = width
150 area.height = height
151 area.groundType = xmlFile:getValue(key .. "#groundType")
152
153 return true
154end

loadPaintArea

Description
Definition
loadPaintArea()
Code
158function PlaceableLeveling:loadPaintArea(xmlFile, key, area)
159 local start = xmlFile:getValue(key .. "#startNode", nil, self.components, self.i3dMappings)
160 if start == nil then
161 Logging.xmlWarning(xmlFile, "Paint area start node not defined for '%s'", key)
162 return false
163 end
164
165 local width = xmlFile:getValue(key .. "#widthNode", nil, self.components, self.i3dMappings)
166 if width == nil then
167 Logging.xmlWarning(xmlFile, "Paint area width node not defined for '%s'", key)
168 return false
169 end
170
171 local height = xmlFile:getValue(key .. "#heightNode", nil, self.components, self.i3dMappings)
172 if height == nil then
173 Logging.xmlWarning(xmlFile, "Paint area height node not defined for '%s'", key)
174 return false
175 end
176
177 area.start = start
178 area.width = width
179 area.height = height
180 area.groundType = xmlFile:getValue(key .. "#groundType")
181
182 return true
183end

onDelete

Description
Definition
onDelete()
Code
102function PlaceableLeveling:onDelete()
103 local spec = self.spec_leveling
104 if spec.writtenBlockedAreas then
105 -- unblock areas in the blocked area map
106 local deformationObjects = self:getDeformationObjects(g_currentMission.terrainRootNode, true, false)
107 for _, deformationObject in ipairs(deformationObjects) do
108 deformationObject:unblockAreas()
109 deformationObject:delete()
110 end
111 end
112end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
64function PlaceableLeveling:onLoad(savegame)
65 local spec = self.spec_leveling
66 local xmlFile = self.xmlFile
67
68 spec.writtenBlockedAreas = false
69
70 -- load leveling properties
71 spec.requiresLeveling = xmlFile:getValue("placeable.leveling#requireLeveling", false)
72 spec.maxSmoothDistance = xmlFile:getValue("placeable.leveling#maxSmoothDistance", 3)
73 spec.maxSlope = xmlFile:getValue("placeable.leveling#maxSlope", 45)
74 spec.maxEdgeAngle = xmlFile:getValue("placeable.leveling#maxEdgeAngle", 45)
75 spec.smoothingGroundType = xmlFile:getValue("placeable.leveling#smoothingGroundType")
76
77 if not self.xmlFile:hasProperty("placeable.leveling") then
78 Logging.xmlWarning(self.xmlFile, "Missing leveling areas")
79 end
80
81 spec.levelAreas = {}
82 xmlFile:iterate("placeable.leveling.levelAreas.levelArea", function(_, key)
83 local levelArea = {}
84 if self:loadLevelArea(xmlFile, key, levelArea) then
85 table.insert(spec.levelAreas, levelArea)
86 end
87 end)
88
89 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.leveling.rampAreas.rampArea", "placeable.leveling.levelAreas.levelArea") -- FS19 to FS22
90
91 spec.paintAreas = {}
92 xmlFile:iterate("placeable.leveling.paintAreas.paintArea", function(_, key)
93 local paintArea = {}
94 if self:loadPaintArea(xmlFile, key, paintArea) then
95 table.insert(spec.paintAreas, paintArea)
96 end
97 end)
98end

onPreFinalizePlacement

Description
Definition
onPreFinalizePlacement()
Code
116function PlaceableLeveling:onPreFinalizePlacement()
117 local spec = self.spec_leveling
118 -- block areas in the blocked area map to prevent placeable overlaps
119 local deformationObjects = self:getDeformationObjects(g_currentMission.terrainRootNode, true, false)
120 for _, deformationObject in ipairs(deformationObjects) do
121 deformationObject:blockAreas()
122 deformationObject:delete()
123 end
124 spec.writtenBlockedAreas = true
125end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
18function PlaceableLeveling.prerequisitesPresent(specializations)
19 return true
20end

registerEventListeners

Description
Definition
registerEventListeners()
Code
35function PlaceableLeveling.registerEventListeners(placeableType)
36 SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceableLeveling)
37 SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceableLeveling)
38 SpecializationUtil.registerEventListener(placeableType, "onPreFinalizePlacement", PlaceableLeveling)
39end

registerFunctions

Description
Definition
registerFunctions()
Code
24function PlaceableLeveling.registerFunctions(placeableType)
25 SpecializationUtil.registerFunction(placeableType, "loadLevelArea", PlaceableLeveling.loadLevelArea)
26 SpecializationUtil.registerFunction(placeableType, "loadPaintArea", PlaceableLeveling.loadPaintArea)
27 SpecializationUtil.registerFunction(placeableType, "addDeformationArea", PlaceableLeveling.addDeformationArea)
28 SpecializationUtil.registerFunction(placeableType, "applyDeformation", PlaceableLeveling.applyDeformation)
29 SpecializationUtil.registerFunction(placeableType, "getDeformationObjects", PlaceableLeveling.getDeformationObjects)
30 SpecializationUtil.registerFunction(placeableType, "getRequiresLeveling", PlaceableLeveling.getRequiresLeveling)
31end

registerXMLPaths

Description
Definition
registerXMLPaths()
Code
43function PlaceableLeveling.registerXMLPaths(schema, basePath)
44 schema:setXMLSpecializationType("Leveling")
45 schema:register(XMLValueType.BOOL, basePath .. ".leveling#requireLeveling", "If true, the ground around the placeable is leveled and all other leveling properties are used", false)
46 schema:register(XMLValueType.FLOAT, basePath .. ".leveling#maxSmoothDistance", "Radius around leveling areas where terrain will be smoothed towards the placeable", 3)
47 schema:register(XMLValueType.ANGLE, basePath .. ".leveling#maxSlope", "Maximum slope of terrain created by outside smoothing expressed as an angle in degrees", 45)
48 schema:register(XMLValueType.ANGLE, basePath .. ".leveling#maxEdgeAngle", "Maximum angle between polygons in smoothed areas expressed as an angle in degrees", 45)
49 schema:register(XMLValueType.STRING, basePath .. ".leveling#smoothingGroundType", "Ground type used to paint the smoothed ground from leveling areas up to the radius of 'maxSmoothDistance' (one of the ground types defined in groundTypes.xml)")
50 schema:register(XMLValueType.NODE_INDEX, basePath .. ".leveling.levelAreas.levelArea(?)#startNode", "Start node")
51 schema:register(XMLValueType.NODE_INDEX, basePath .. ".leveling.levelAreas.levelArea(?)#widthNode", "Width node")
52 schema:register(XMLValueType.NODE_INDEX, basePath .. ".leveling.levelAreas.levelArea(?)#heightNode", "Height node")
53 schema:register(XMLValueType.STRING, basePath .. ".leveling.levelAreas.levelArea(?)#groundType", "Ground type name (one of the ground types defined in groundTypes.xml)")
54 schema:register(XMLValueType.NODE_INDEX, basePath .. ".leveling.paintAreas.paintArea(?)#startNode", "Start node")
55 schema:register(XMLValueType.NODE_INDEX, basePath .. ".leveling.paintAreas.paintArea(?)#widthNode", "Width node")
56 schema:register(XMLValueType.NODE_INDEX, basePath .. ".leveling.paintAreas.paintArea(?)#heightNode", "Height node")
57 schema:register(XMLValueType.STRING, basePath .. ".leveling.paintAreas.paintArea(?)#groundType", "Ground type name (one of the ground types defined in groundTypes.xml)")
58 schema:setXMLSpecializationType()
59end