LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

PlaceablePlacement

Description
Specialization for placeables
Functions

getHasOverlap

Description
Definition
getHasOverlap()
Code
328function PlaceablePlacement:getHasOverlap(x, y, z, rotY, checkFunc)
329 local spec = self.spec_placement
330
331 local callbackTarget = {hasOverlap = false}
332 callbackTarget.overlapCallback = function(target, hitObjectId, hitX, hitY, hitZ, distance)
333 if checkFunc ~= nil then
334 if checkFunc(hitObjectId) then
335 callbackTarget.hasOverlap = true
336 callbackTarget.node = hitObjectId
337 return false
338 end
339 else
340 if hitObjectId ~= g_currentMission.terrainRootNode then
341 callbackTarget.hasOverlap = true
342 callbackTarget.node = hitObjectId
343 return false
344 end
345 end
346
347 return true
348 end
349
350 for _, area in ipairs(spec.testAreas) do
351 local size = area.size
352 local center = area.center
353
354 local dirX, dirZ = MathUtil.getDirectionFromYRotation(rotY)
355 local normX, _, normZ = MathUtil.crossProduct(0, 1, 0, dirX, 0, dirZ)
356
357 local posX = x + dirX * center.z + normX * center.x
358 local posY = y + center.y
359 local posZ = z + dirZ * center.z + normZ * center.x
360
361 local sizeXHalf, sizeZHalf = size.x*0.5, size.z*0.5
362 local frontLeftX, frontLeftZ = posX + dirX*sizeZHalf - normX*sizeXHalf, posZ + dirZ*sizeZHalf - normZ*sizeXHalf
363 local frontRightX, frontRightZ = posX + dirX*sizeZHalf + normX*sizeXHalf, posZ + dirZ*sizeZHalf + normZ*sizeXHalf
364 local backLeftX, backLeftZ = posX - dirX*sizeZHalf - normX*sizeXHalf, posZ - dirZ*sizeZHalf - normZ*sizeXHalf
365 local backRightX, backRightZ = posX - dirX*sizeZHalf + normX*sizeXHalf, posZ - dirZ*sizeZHalf + normZ*sizeXHalf
366
367 local frontLeftY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, frontLeftX, 0, frontLeftZ)
368 local frontRightY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, frontRightX, 0, frontRightZ)
369 local backLeftY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, backLeftX, 0, backLeftZ)
370 local backRightY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, backRightX, 0, backRightZ)
371 local centerY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, posX, 0, posZ)
372
373 local terrainBasedCenterY = math.min(frontLeftY, frontRightY, backLeftY, backRightY, centerY) + size.y*0.5 - 0.5 -- we want to check 0.5m below terrain
374 posY = math.max(terrainBasedCenterY, posY)
375
376 overlapBox(posX, posY, posZ, 0, rotY + area.rotYOffset, 0, size.x*0.5, size.y*0.5, size.z*0.5, "overlapCallback", callbackTarget, nil, true, true, true, false)
377
378 --#debug DebugUtil.drawDebugGizmoAtWorldPos(frontLeftX, frontLeftY, frontLeftZ, dirX*5, 0, dirZ*5, 0, 1, 0, "frontLeft", false, {1, 1, 1, 1})
379 --#debug DebugUtil.drawDebugGizmoAtWorldPos(frontRightX, frontRightY, frontRightZ, dirX, 0, dirZ, 0, 1, 0, "frontLeft", false, {1, 1, 1, 1})
380 --#debug DebugUtil.drawDebugGizmoAtWorldPos(backLeftX, backLeftY, backLeftZ, dirX, 0, dirZ, 0, 1, 0, "frontLeft", false, {1, 1, 1, 1})
381 --#debug DebugUtil.drawDebugGizmoAtWorldPos(backRightX, backRightY, backRightZ, dirX, 0, dirZ, 0, 1, 0, "frontLeft", false, {1, 1, 1, 1})
382 --#debug DebugUtil.drawOverlapBox(posX, posY, posZ, 0, rotY + area.rotYOffset, 0, size.x*0.5, size.y*0.5, size.z*0.5, 1, 0, 0)
383
384 --#debug if area.debugTestBox then
385 --#debug area.debugTestBox:createWithStartEnd(area.startNode, area.endNode)
386 --#debug g_debugManager:addFrameElement(area.debugTestBox)
387 --#debug area.debugStartNode:createWithNode(area.startNode, getName(area.startNode), false, nil)
388 --#debug g_debugManager:addFrameElement(area.debugStartNode)
389 --#debug area.debugEndNode:createWithNode(area.endNode, getName(area.endNode), false, nil)
390 --#debug g_debugManager:addFrameElement(area.debugEndNode)
391 --#debug end
392
393 if callbackTarget.hasOverlap then
394 return true, callbackTarget.node
395 end
396
397 local startX,startZ, widthX,widthZ, heightX,heightZ = self:getTestParallelogramAtWorldPosition(area, x, z, rotY)
398
399 --#debug area.debugArea:createWithStartEnd(area.startNode, area.endNode)
400 --#debug g_debugManager:addFrameElement(area.debugArea)
401
402 local density = DensityMapHeightUtil.getValueAtArea(startX, startZ, widthX, widthZ, heightX, heightZ, true)
403 if density > 0 then
404 return true, nil
405 end
406 end
407
408 return false, nil
409end

getHasOverlapWithPlaces

Description
Definition
getHasOverlapWithPlaces()
Code
413function PlaceablePlacement:getHasOverlapWithPlaces(places, x, y, z, rotY)
414 local spec = self.spec_placement
415 for _, area in ipairs(spec.testAreas) do
416 local x1, z1, x2, z2, x3, z3, x4, z4 = self:getTestParallelogramAtWorldPosition(area, x, z, rotY)
417
418 if PlacementUtil.isInsidePlacementPlaces(places, x1, y, z1) then
419 return true
420 end
421 if PlacementUtil.isInsidePlacementPlaces(places, x2, y, z2) then
422 return true
423 end
424 if PlacementUtil.isInsidePlacementPlaces(places, x3, y, z3) then
425 return true
426 end
427 if PlacementUtil.isInsidePlacementPlaces(places, x4, y, z4) then
428 return true
429 end
430 end
431
432 return false
433end

getHasOverlapWithZones

Description
Definition
getHasOverlapWithZones()
Code
437function PlaceablePlacement:getHasOverlapWithZones(zones, x, y, z, rotY)
438 local spec = self.spec_placement
439
440 for _, area in ipairs(spec.testAreas) do
441 local x1, z1, x2, z2, x3, z3, x4, z4 = self:getTestParallelogramAtWorldPosition(area, x, z, rotY)
442
443 --#debug DebugUtil.drawDebugGizmoAtWorldPos(x1, y, z1, 0, 0, 1, 0, 1, 0, "P1", true)
444 --#debug DebugUtil.drawDebugGizmoAtWorldPos(x2, y, z2, 0, 0, 1, 0, 1, 0, "P2", true)
445 --#debug DebugUtil.drawDebugGizmoAtWorldPos(x3, y, z3, 0, 0, 1, 0, 1, 0, "P3", true)
446 --#debug DebugUtil.drawDebugGizmoAtWorldPos(x4, y, z4, 0, 0, 1, 0, 1, 0, "P4", true)
447
448 if PlacementUtil.isInsideRestrictedZone(zones, x1, y, z1, false) then
449 return true
450 end
451 if PlacementUtil.isInsideRestrictedZone(zones, x2, y, z2, false) then
452 return true
453 end
454 if PlacementUtil.isInsideRestrictedZone(zones, x3, y, z3, false) then
455 return true
456 end
457 if PlacementUtil.isInsideRestrictedZone(zones, x4, y, z4, false) then
458 return true
459 end
460
461 end
462
463 return false
464end

getIsAreaOwned

Description
Definition
getIsAreaOwned()
Code
303function PlaceablePlacement:getIsAreaOwned(farmId)
304 local spec = self.spec_placement
305 local halfX = spec.testSizeX * 0.5
306 local halfZ = spec.testSizeZ * 0.5
307 local offsetX = spec.testSizeOffsetX
308 local offsetZ = spec.testSizeOffsetZ
309
310 local x1, _, z1 = localToWorld(self.rootNode, -halfX + offsetX, 0, -halfZ + offsetZ)
311 local x2, _, z2 = localToWorld(self.rootNode, halfX + offsetX, 0, -halfZ + offsetZ)
312 local x3, _, z3 = localToWorld(self.rootNode, -halfX + offsetX, 0, halfZ + offsetZ)
313 local x4, _, z4 = localToWorld(self.rootNode, halfX + offsetX, 0, halfZ + offsetZ)
314
315 return g_farmlandManager:getIsOwnedByFarmAtWorldPosition(farmId, x1, z1) and
316 g_farmlandManager:getIsOwnedByFarmAtWorldPosition(farmId, x2, z2) and
317 g_farmlandManager:getIsOwnedByFarmAtWorldPosition(farmId, x3, z3) and
318 g_farmlandManager:getIsOwnedByFarmAtWorldPosition(farmId, x4, z4)
319end

getPlacementPosition

Description
Definition
getPlacementPosition()
Code
243function PlaceablePlacement:getPlacementPosition(x, y, z)
244 local spec = self.spec_placement
245 local snapSize = spec.positionSnapSize
246 if snapSize ~= 0 then
247 snapSize = 1 / snapSize
248
249 x = math.floor(x * snapSize) / snapSize + spec.positionSnapOffset
250 z = math.floor(z * snapSize) / snapSize + spec.positionSnapOffset
251 end
252
253 return x, y, z
254end

getPlacementRotation

Description
Definition
getPlacementRotation()
Code
231function PlaceablePlacement:getPlacementRotation(x, y, z)
232 local spec = self.spec_placement
233 if spec.rotationSnapAngle ~= 0 then
234 local degAngle = MathUtil.snapValue(math.deg(y), math.deg(spec.rotationSnapAngle))
235 y = math.rad(degAngle)
236 end
237
238 return x, y, z
239end

getPositionSnapOffset

Description
Definition
getPositionSnapOffset()
Code
264function PlaceablePlacement:getPositionSnapOffset()
265 return self.spec_placement.positionSnapOffset
266end

getPositionSnapSize

Description
Definition
getPositionSnapSize()
Code
258function PlaceablePlacement:getPositionSnapSize()
259 return self.spec_placement.positionSnapSize
260end

getRotationSnapAngle

Description
Definition
getRotationSnapAngle()
Code
270function PlaceablePlacement:getRotationSnapAngle()
271 return self.spec_placement.rotationSnapAngle
272end

getTestParallelogramAtWorldPosition

Description
Definition
getTestParallelogramAtWorldPosition()
Code
468function PlaceablePlacement:getTestParallelogramAtWorldPosition(testArea, x, z, rotY)
469 local dirX, dirZ = MathUtil.getDirectionFromYRotation(rotY)
470 local normX, _, normZ = MathUtil.crossProduct(0, 1, 0, dirX, 0, dirZ)
471
472 local centerXOffset = testArea.center.x
473 local centerZOffset = testArea.center.z
474 local centerX = x + dirX * centerZOffset + normX * centerXOffset
475 local centerZ = z + dirZ * centerZOffset + normZ * centerXOffset
476
477 dirX, dirZ = MathUtil.getDirectionFromYRotation(rotY + testArea.rotYOffset)
478 normX, _, normZ = MathUtil.crossProduct(0, 1, 0, dirX, 0, dirZ)
479
480 local startOffsetX = testArea.size.x * 0.5
481 local startOffsetZ = testArea.size.z * 0.5
482 local startX = centerX - dirX * startOffsetZ - normX * startOffsetX
483 local startZ = centerZ - dirZ * startOffsetZ - normZ * startOffsetX
484
485 local widthOffset = testArea.size.x
486 local widthX = startX + normX * widthOffset
487 local widthZ = startZ + normZ * widthOffset
488
489 local heightOffset = testArea.size.z
490 local heightX = startX + dirX * heightOffset
491 local heightZ = startZ + dirZ * heightOffset
492
493 local heightX2 = widthX + dirX * heightOffset
494 local heightZ2 = widthZ + dirZ * heightOffset
495
496 return startX, startZ, widthX, widthZ, heightX, heightZ, heightX2, heightZ2
497end

loadTestArea

Description
Definition
loadTestArea()
Code
176function PlaceablePlacement:loadTestArea(xmlFile, key, area)
177 local startNode = xmlFile:getValue(key .. "#startNode", nil, self.components, self.i3dMappings)
178 local endNode = xmlFile:getValue(key .. "#endNode", nil, self.components, self.i3dMappings)
179
180 if startNode == nil then
181 Logging.xmlWarning(xmlFile, "Missing test area start node for '%s'", key)
182 return false
183 end
184
185 if endNode == nil then
186 Logging.xmlWarning(xmlFile, "Missing test area end node for '%s'", key)
187 return false
188 end
189
190 if getParent(endNode) ~= startNode then
191 Logging.xmlWarning(xmlFile, "Test area end node is not a direct child of startNode for '%s'", key)
192 return false
193 end
194
195 area.startNode = startNode
196 area.endNode = endNode
197
198 local ySafetyOffset = 0.05 -- shift all test areas down by 5cm to avoid stacking of placables with testArea start at y=0
199 local offsetX, offsetY, offsetZ = localToLocal(endNode, startNode, 0, -ySafetyOffset, 0)
200 local centerX, centerY, centerZ = localToLocal(startNode, self.rootNode, offsetX*0.5, offsetY*0.5, offsetZ*0.5)
201 local sizeX, sizeY, sizeZ = math.abs(offsetX), math.abs(offsetY+ySafetyOffset), math.abs(offsetZ)
202
203 if offsetY < 0.01 then
204 Logging.xmlDevWarning(xmlFile, "TestArea '%s 'has no height (endNode has same y as startNode)", key)
205 end
206
207 area.size = {}
208 area.size.x = math.abs(sizeX)
209 area.size.y = math.abs(sizeY)
210 area.size.z = math.abs(sizeZ)
211
212 area.center = {}
213 area.center.x = centerX
214 area.center.y = centerY
215 area.center.z = centerZ
216
217 local dirX, _, dirZ = localDirectionToLocal(startNode, self.rootNode, 0, 0, 1)
218 local rotY = MathUtil.getYRotationFromDirection(dirX, dirZ)
219 area.rotYOffset = rotY
220
221 area.debugTestBox = DebugCube.new()
222 area.debugStartNode = DebugGizmo.new()
223 area.debugEndNode = DebugGizmo.new()
224 area.debugArea = Debug2DArea.new(true, false, {1, 0, 0, 0.3})
225
226 return true
227end

onDelete

Description
Definition
onDelete()
Code
163function PlaceablePlacement:onDelete()
164 if self.isClient then
165 local spec = self.spec_placement
166 if spec.samples ~= nil then
167 g_soundManager:deleteSample(spec.samples.place)
168 g_soundManager:deleteSample(spec.samples.placeLayered)
169 g_soundManager:deleteSample(spec.samples.destroy)
170 end
171 end
172end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
76function PlaceablePlacement:onLoad(savegame)
77 local spec = self.spec_placement
78 local xmlFile = self.xmlFile
79
80 spec.testAreas = {}
81 xmlFile:iterate("placeable.placement.testAreas.testArea", function(_, key)
82 local testArea = {}
83 if self:loadTestArea(xmlFile, key, testArea) then
84 table.insert(spec.testAreas, testArea)
85 end
86 end)
87
88 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#sizeX") -- FS19 to FS22
89 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#sizeZ") -- FS19 to FS22
90 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#sizeOffsetX") -- FS19 to FS22
91 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#sizeOffsetZ") -- FS19 to FS22
92 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#testSizeX", "placeable.placement.testAreas.testArea") -- FS19 to FS22
93 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#testSizeZ", "placeable.placement.testAreas.testArea") -- FS19 to FS22
94 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#testSizeOffsetX", "placeable.placement.testAreas.testArea") -- FS19 to FS22
95 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "placeable.placement#testSizeOffsetZ", "placeable.placement.testAreas.testArea") -- FS19 to FS22
96
97 -- fallback to legacy xmls
98 -- TODO: remove
99 local testSizeX = xmlFile:getFloat("placeable.placement#testSizeX")
100 local testSizeZ = xmlFile:getFloat("placeable.placement#testSizeZ")
101 if testSizeX ~= nil and testSizeZ ~= nil then
102 local testSizeOffsetX = xmlFile:getFloat("placeable.placement#testSizeOffsetX", 0)
103 local testSizeOffsetZ = xmlFile:getFloat("placeable.placement#testSizeOffsetZ", 0)
104
105 local startNode = createTransformGroup("legacyTestAreaStartNode")
106 local endNode = createTransformGroup("legacyTestAreaEndNode")
107 link(self.rootNode, startNode)
108 link(startNode, endNode)
109
110 setTranslation(startNode, -testSizeX * 0.5 + testSizeOffsetX, 0, -testSizeZ * 0.5 + testSizeOffsetZ)
111 setTranslation(endNode, testSizeX, 2, testSizeZ)
112
113 local testArea = {}
114 testArea.startNode = startNode
115 testArea.endNode = endNode
116
117 testArea.size = {}
118 testArea.size.x = math.abs(testSizeX)
119 testArea.size.y = 2
120 testArea.size.z = math.abs(testSizeZ)
121
122 testArea.center = {}
123 testArea.center.x = testSizeOffsetX
124 testArea.center.y = testArea.size.y * 0.5
125 testArea.center.z = testSizeOffsetZ
126
127 testArea.debugTestBox = DebugCube.new()
128 testArea.debugStartNode = DebugGizmo.new()
129 testArea.debugEndNode = DebugGizmo.new()
130 testArea.debugArea = Debug2DArea.new(true, false, {1, 0, 0, 0.3})
131
132 testArea.rotYOffset = 0
133 table.insert(spec.testAreas, testArea)
134 end
135
136 spec.useRandomYRotation = xmlFile:getValue("placeable.placement#useRandomYRotation", spec.useRandomYRotation)
137 spec.useManualYRotation = xmlFile:getValue("placeable.placement#useManualYRotation", spec.useManualYRotation)
138 spec.positionSnapSize = math.abs(xmlFile:getValue("placeable.placement#placementPositionSnapSize", 0.0))
139 spec.positionSnapOffset = math.abs(xmlFile:getValue("placeable.placement#placementPositionSnapOffset", 0.0))
140 spec.rotationSnapAngle = math.abs(xmlFile:getValue("placeable.placement#placementRotationSnapAngle", 0.0))
141
142 spec.alignToWorldY = xmlFile:getValue("placeable.placement#alignToWorldY", true)
143 if not spec.alignToWorldY then
144 spec.pos1Node = xmlFile:getValue("placeable.placement#pos1Node", nil, self.components, self.i3dMappings)
145 spec.pos2Node = xmlFile:getValue("placeable.placement#pos2Node", nil, self.components, self.i3dMappings)
146 spec.pos3Node = xmlFile:getValue("placeable.placement#pos3Node", nil, self.components, self.i3dMappings)
147 if spec.pos1Node == nil or spec.pos2Node == nil or spec.pos3Node == nil then
148 spec.alignToWorldY = true
149 Logging.xmlWarning(xmlFile, "pos1Node, pos2Node and pos3Node has to be set when alignToWorldY is false!")
150 end
151 end
152
153 if self.isClient then
154 spec.samples = {}
155 spec.samples.place = g_soundManager:loadSample2DFromXML(xmlFile.handle, "placeable.placement.sounds", "place", self.baseDirectory, 1, AudioGroup.GUI)
156 spec.samples.placeLayered = g_soundManager:loadSample2DFromXML(xmlFile.handle, "placeable.placement.sounds", "placeLayered", self.baseDirectory, 1, AudioGroup.GUI)
157 spec.samples.destroy = g_soundManager:loadSample2DFromXML(xmlFile.handle, "placeable.placement.sounds", "destroy", self.baseDirectory, 1, AudioGroup.GUI)
158 end
159end

onPreFinalizePlacement

Description
Definition
onPreFinalizePlacement()
Code
276function PlaceablePlacement:onPreFinalizePlacement()
277 local spec = self.spec_placement
278 -- only (re-)align if the property is set and we're on the server, clients will get the correct transform in sync.
279 -- This also avoids wrong positioning of placeables on modified terrain.
280 if not spec.alignToWorldY and self.isServer then
281 local x1,y1,z1 = getWorldTranslation(self.rootNode)
282 y1 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x1,y1,z1)
283 setTranslation(self.rootNode, x1,y1,z1)
284 local x2,y2,z2 = getWorldTranslation(spec.pos1Node)
285 y2 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x2,y2,z2)
286 local x3,y3,z3 = getWorldTranslation(spec.pos2Node)
287 y3 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x3,y3,z3)
288 local x4,y4,z4 = getWorldTranslation(spec.pos3Node)
289 y4 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x4,y4,z4)
290 local dirX = x2 - x1
291 local dirY = y2 - y1
292 local dirZ = z2 - z1
293 local dir2X = x3 - x4
294 local dir2Y = y3 - y4
295 local dir2Z = z3 - z4
296 local upX,upY,upZ = MathUtil.crossProduct(dir2X, dir2Y, dir2Z, dirX, dirY, dirZ)
297 setDirection(self.rootNode, dirX, dirY, dirZ, upX,upY,upZ)
298 end
299end

playDestroySound

Description
Definition
playDestroySound()
Code
511function PlaceablePlacement:playDestroySound(onlyIfNotPlaying)
512 if self.isClient then
513 local spec = self.spec_placement
514
515 if not onlyIfNotPlaying or not g_soundManager:getIsSamplePlaying(spec.samples.destroy) then
516 g_soundManager:playSample(spec.samples.destroy)
517 end
518 end
519end

playPlaceSound

Description
Definition
playPlaceSound()
Code
501function PlaceablePlacement:playPlaceSound()
502 if self.isClient then
503 local spec = self.spec_placement
504 g_soundManager:playSample(spec.samples.place)
505 g_soundManager:playSample(spec.samples.placeLayered)
506 end
507end

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 PlaceablePlacement.prerequisitesPresent(specializations)
19 return true
20end

registerEventListeners

Description
Definition
registerEventListeners()
Code
42function PlaceablePlacement.registerEventListeners(placeableType)
43 SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceablePlacement)
44 SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceablePlacement)
45 SpecializationUtil.registerEventListener(placeableType, "onPreFinalizePlacement", PlaceablePlacement)
46end

registerFunctions

Description
Definition
registerFunctions()
Code
24function PlaceablePlacement.registerFunctions(placeableType)
25 SpecializationUtil.registerFunction(placeableType, "loadTestArea", PlaceablePlacement.loadTestArea)
26 SpecializationUtil.registerFunction(placeableType, "startPlacementCheck", PlaceablePlacement.startPlacementCheck)
27 SpecializationUtil.registerFunction(placeableType, "getPlacementRotation", PlaceablePlacement.getPlacementRotation)
28 SpecializationUtil.registerFunction(placeableType, "getPlacementPosition", PlaceablePlacement.getPlacementPosition)
29 SpecializationUtil.registerFunction(placeableType, "getPositionSnapSize", PlaceablePlacement.getPositionSnapSize)
30 SpecializationUtil.registerFunction(placeableType, "getPositionSnapOffset", PlaceablePlacement.getPositionSnapOffset)
31 SpecializationUtil.registerFunction(placeableType, "getRotationSnapAngle", PlaceablePlacement.getRotationSnapAngle)
32 SpecializationUtil.registerFunction(placeableType, "getHasOverlap", PlaceablePlacement.getHasOverlap)
33 SpecializationUtil.registerFunction(placeableType, "getHasOverlapWithPlaces", PlaceablePlacement.getHasOverlapWithPlaces)
34 SpecializationUtil.registerFunction(placeableType, "getHasOverlapWithZones", PlaceablePlacement.getHasOverlapWithZones)
35 SpecializationUtil.registerFunction(placeableType, "getTestParallelogramAtWorldPosition", PlaceablePlacement.getTestParallelogramAtWorldPosition)
36 SpecializationUtil.registerFunction(placeableType, "playPlaceSound", PlaceablePlacement.playPlaceSound)
37 SpecializationUtil.registerFunction(placeableType, "playDestroySound", PlaceablePlacement.playDestroySound)
38end

registerXMLPaths

Description
Definition
registerXMLPaths()
Code
50function PlaceablePlacement.registerXMLPaths(schema, basePath)
51 schema:setXMLSpecializationType("Placement")
52 schema:register(XMLValueType.NODE_INDEX, basePath .. ".placement#pos1Node", "Position node 1 (Required if alignToWorldY is false to calculate the terrain alignment)")
53 schema:register(XMLValueType.NODE_INDEX, basePath .. ".placement#pos2Node", "Position node 2 (Required if alignToWorldY is false to calculate the terrain alignment)")
54 schema:register(XMLValueType.NODE_INDEX, basePath .. ".placement#pos3Node", "Position node 3 (Required if alignToWorldY is false to calculate the terrain alignment)")
55
56 schema:register(XMLValueType.NODE_INDEX, basePath .. ".placement.testAreas.testArea(?)#startNode", "Start node of box for testing overlap")
57 schema:register(XMLValueType.NODE_INDEX, basePath .. ".placement.testAreas.testArea(?)#endNode", "End node of box for testing overlap")
58
59 schema:register(XMLValueType.BOOL, basePath .. ".placement#useRandomYRotation", "Use random Y rotation", false)
60 schema:register(XMLValueType.BOOL, basePath .. ".placement#useManualYRotation", "Use manual Y rotation", false)
61 schema:register(XMLValueType.BOOL, basePath .. ".placement#alignToWorldY", "Placeable is aligned to world Y instead of terrain", true)
62 schema:register(XMLValueType.FLOAT, basePath .. ".placement#placementPositionSnapSize", "Position snap size", 0)
63 schema:register(XMLValueType.FLOAT, basePath .. ".placement#placementPositionSnapOffset", "Position snap offset", 0)
64 schema:register(XMLValueType.ANGLE, basePath .. ".placement#placementRotationSnapAngle", "Rotation snap angle", 0)
65
66 SoundManager.registerSampleXMLPaths(schema, basePath .. ".placement.sounds", "place")
67 SoundManager.registerSampleXMLPaths(schema, basePath .. ".placement.sounds", "placeLayered")
68 SoundManager.registerSampleXMLPaths(schema, basePath .. ".placement.sounds", "destroy")
69
70 schema:setXMLSpecializationType()
71end

startPlacementCheck

Description
Definition
startPlacementCheck()
Code
323function PlaceablePlacement:startPlacementCheck(x, y, z, rotY)
324end