LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

WorkParticles

Description
Specialization for adding various particles to vehicles while working
Functions

getDoGroundManipulation

Description
Definition
getDoGroundManipulation()
Code
298function WorkParticles:getDoGroundManipulation()
299 return true
300end

getFillTypeFromWorkAreaIndex

Description
Definition
getFillTypeFromWorkAreaIndex()
Code
554function WorkParticles:getFillTypeFromWorkAreaIndex(workAreaIndex)
555 local fillType = FillType.UNKNOWN
556 local workArea = self:getWorkAreaByIndex(workAreaIndex)
557 if workArea ~= nil then
558 if workArea.fillType ~= nil then
559 fillType = workArea.fillType
560 elseif workArea.fruitType ~= nil then
561 fillType = g_fruitTypeManager:getFruitTypeIndexByFillTypeIndex(workArea.fruitType)
562 end
563 end
564 return fillType
565end

groundParticleI3DLoaded

Description
Definition
groundParticleI3DLoaded()
Code
443function WorkParticles:groundParticleI3DLoaded(i3dNode, failedReason, args)
444 local xmlFile = args.xmlFile
445 local key = args.key
446 local particle = args.particle
447 local filename = args.filename
448
449 local j = 0
450 while true do
451 local nodeBaseName = string.format(key .. ".node(%d)", j)
452 if not xmlFile:hasProperty(nodeBaseName) then
453 break
454 end
455
456 local mapping = {}
457 if self:loadGroundParticleMapping(xmlFile, nodeBaseName, mapping, j, i3dNode) then
458 table.insert(particle.mappings, mapping)
459 end
460 j = j + 1
461 end
462
463 if i3dNode ~= 0 then
464 -- link after loading to make sure all indices are correct
465 for _, mapping in ipairs(particle.mappings) do
466 link(mapping.node, mapping.particleNode)
467 ParticleUtil.loadParticleSystemFromNode(mapping.particleNode, mapping.particleSystem, false, true)
468 end
469
470 particle.filename = filename
471 delete(i3dNode)
472 end
473end

initSpecialization

Description
Called on specialization initializing
Definition
initSpecialization()
Code
23function WorkParticles.initSpecialization()
24 local schema = Vehicle.xmlSchema
25 schema:setXMLSpecializationType("WorkParticles")
26
27 schema:register(XMLValueType.STRING, "vehicle.workParticles.particleAnimation(?)#file", "External effect i3d file")
28 schema:register(XMLValueType.FLOAT, "vehicle.workParticles.particleAnimation(?)#speedThreshold", "Speed threshold", 0)
29 WorkParticles.registerGroundAnimationMappingXMLPaths(schema, "vehicle.workParticles.particleAnimation(?).node(?)")
30
31 schema:register(XMLValueType.STRING, "vehicle.workParticles.particle(?)#file", "External effect i3d file")
32 WorkParticles.registerGroundParticleMappingXMLPaths(schema, "vehicle.workParticles.particle(?).node(?)")
33
34 EffectManager.registerEffectXMLPaths(schema, "vehicle.workParticles.effect(?)")
35 schema:register(XMLValueType.FLOAT, "vehicle.workParticles.effect(?)#speedThreshold", "Speed threshold", 0.5)
36 schema:register(XMLValueType.INT, "vehicle.workParticles.effect(?)#activeDirection", "Active Direction (effect will be turned off wen in opposite direction)", 1)
37 schema:register(XMLValueType.INT, "vehicle.workParticles.effect(?)#workAreaIndex", "Work area index")
38 schema:register(XMLValueType.INT, "vehicle.workParticles.effect(?)#groundReferenceNodeIndex", "Index of ground reference node")
39 schema:register(XMLValueType.BOOL, "vehicle.workParticles.effect(?)#needsSetIsTurnedOn", "Needs set is turned on", false)
40
41 schema:register(XMLValueType.NODE_INDEX, GroundReference.GROUND_REFERENCE_XML_KEY .. "#depthNode", "Depth node")
42
43 schema:setXMLSpecializationType()
44end

loadGroundAnimationMapping

Description
Definition
loadGroundAnimationMapping()
Code
353function WorkParticles:loadGroundAnimationMapping(xmlFile, key, mapping, index)
354 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key.."#index", key.."#node") --FS17 to FS19
355 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key.."#animMeshIndex", key.."#animMeshNode") --FS17 to FS19
356
357 local node = xmlFile:getValue(key.."#node", nil, self.components, self.i3dMappings)
358 if node == nil then
359 Logging.xmlWarning(self.xmlFile, "Invalid node '%s' for '%s'", getXMLString(xmlFile.handle, key.."#node"), key)
360 return false
361 end
362
363 local groundRefIndex = xmlFile:getValue(key .. "#refNodeIndex")
364 if groundRefIndex == nil or self:getGroundReferenceNodeFromIndex(groundRefIndex) == nil then
365 Logging.xmlWarning(self.xmlFile, "Invalid refNodeIndex '%s' for '%s'", xmlFile:getValue(key.."#refNodeIndex"), key)
366 return false
367 end
368
369 local animNode
370 local animMeshNode = xmlFile:getValue(key.."#animMeshNode")
371 if animMeshNode ~= nil then
372 animNode = I3DUtil.indexToObject(node, animMeshNode, self.i3dMappings)
373 if animNode == nil then
374 Logging.xmlWarning(self.xmlFile, "Invalid animMesh node '%s' '%s'", xmlFile:getValue(key.."#animMeshNode"), key)
375 return false
376 end
377 else
378 local materialType = xmlFile:getValue(key.."#materialType")
379 local materialId = xmlFile:getValue(key.."#materialId", 1)
380 if materialType == nil then
381 Logging.xmlWarning(self.xmlFile, "Missing materialType in '%s'", key)
382 return false
383 end
384
385 animNode = node
386
387 local material = g_materialManager:getBaseMaterialByName(materialType)
388 if material ~= nil then
389 setMaterial(node, material, 0)
390 else
391 Logging.xmlWarning(self.xmlFile, "Invalid materialType '%s' or materialId '%s' in '%s'", materialType, materialId, key)
392 end
393
394 setVisibility(animNode, false)
395 end
396
397 mapping.node = node
398 mapping.animNode = animNode
399 mapping.groundRefNode = self:getGroundReferenceNodeFromIndex(groundRefIndex)
400 mapping.lastDepth = 0
401 mapping.speed = 0
402 mapping.maxWorkDepth = xmlFile:getValue(key.."#maxDepth", -0.1)
403
404 return true
405end

loadGroundAnimations

Description
Definition
loadGroundAnimations()
Code
304function WorkParticles:loadGroundAnimations(xmlFile, key, animation, index)
305 animation.speedThreshold = xmlFile:getValue(key .. "#speedThreshold", 0)
306
307 animation.mappings = {}
308 local j = 0
309 while true do
310 local nodeBaseName = string.format(key .. ".node(%d)", j)
311 if not self.xmlFile:hasProperty(nodeBaseName) then
312 break
313 end
314
315 local mapping = {}
316 if self:loadGroundAnimationMapping(xmlFile, nodeBaseName, mapping, j) then
317 table.insert(animation.mappings, mapping)
318 end
319 j = j + 1
320 end
321
322 local filenameStr = self.xmlFile:getValue(key .. "#file")
323 if filenameStr ~= nil then
324 filenameStr = Utils.getFilename(filenameStr, self.baseDirectory)
325 local arguments = {
326 filename = filenameStr,
327 animation = animation
328 }
329 animation.sharedLoadRequestId = self:loadSubSharedI3DFile(filenameStr, false, false, self.onGroundAnimationI3DLoaded, self, arguments)
330 end
331
332 return true
333end

loadGroundEffects

Description
Definition
loadGroundEffects()
Code
541function WorkParticles:loadGroundEffects(xmlFile, key, effect, index)
542 effect.speedThreshold = xmlFile:getValue(key .. "#speedThreshold", 0.5)
543 effect.activeDirection = xmlFile:getValue(key .. "#activeDirection", 1)
544 effect.workAreaIndex = xmlFile:getValue(key .. "#workAreaIndex")
545 effect.groundReferenceNodeIndex = xmlFile:getValue(key .. "#groundReferenceNodeIndex")
546 effect.needsSetIsTurnedOn = xmlFile:getValue(key .. "#needsSetIsTurnedOn", false)
547 effect.effect = g_effectManager:loadEffect(xmlFile, key, self.components, self, self.i3dMappings)
548
549 return true
550end

loadGroundParticleMapping

Description
Definition
loadGroundParticleMapping()
Code
477function WorkParticles:loadGroundParticleMapping(xmlFile, key, mapping, index, i3dNode)
478 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key.."#index", key.."#node") --FS17 to FS19
479 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key.."#particleIndex", key.."#particleNode") --FS17 to FS19
480
481 mapping.particleSystem = {}
482
483 local node = xmlFile:getValue(key.."#node", nil, self.components, self.i3dMappings)
484 if node == nil then
485 Logging.xmlWarning(self.xmlFile, "Invalid node '%s' for '%s'", xmlFile:getValue(key.."#node"), key)
486 return false
487 end
488
489 local groundRefIndex = xmlFile:getValue(key .. "#refNodeIndex")
490 if groundRefIndex == nil or self:getGroundReferenceNodeFromIndex(groundRefIndex) == nil then
491 Logging.xmlWarning(self.xmlFile, "Invalid refNodeIndex '%s' for '%s'", xmlFile:getValue(key.."#refNodeIndex"), key)
492 return false
493 end
494
495 local particleNode
496 local particleNodeIndex = xmlFile:getValue(key.."#particleNode")
497 if particleNodeIndex ~= nil then
498 particleNode = I3DUtil.indexToObject(i3dNode, particleNodeIndex, self.i3dMappings)
499 if particleNode == nil then
500 Logging.xmlWarning(self.xmlFile, "Invalid particle node '%s' '%s'", xmlFile:getValue(key.."#particleNode"), key)
501 return false
502 end
503 else
504 particleNode = node
505
506 local particleType = xmlFile:getValue(key.."#particleType")
507 if particleType == nil then
508 Logging.xmlWarning(self.xmlFile, "Missing particleType in '%s'", key)
509 return false
510 end
511
512 local fillTypeStr = xmlFile:getValue(key.."#fillType")
513 local fillType = Utils.getNoNil(g_fillTypeManager:getFillTypeIndexByName(fillTypeStr), FillType.UNKNOWN)
514
515 local particleSystem = g_particleSystemManager:getParticleSystem(particleType)
516 if particleSystem ~= nil then
517 if fillType ~= FillType.UNKNOWN then
518 local material = g_materialManager:getParticleMaterial(fillType, particleType, 1)
519 if material ~= nil then
520 ParticleUtil.setMaterial(particleSystem, material)
521 end
522 end
523
524 mapping.particleSystem = ParticleUtil.copyParticleSystem(xmlFile, key, particleSystem, node)
525 else
526 return false
527 end
528 end
529
530 mapping.node = node
531 mapping.particleNode = particleNode
532 mapping.groundRefNode = self:getGroundReferenceNodeFromIndex(groundRefIndex)
533 mapping.speedThreshold = xmlFile:getValue(key.."#speedThreshold", 0.5)
534 mapping.movingDirection = xmlFile:getValue(key.."#movingDirection")
535
536 return true
537end

loadGroundParticles

Description
Definition
loadGroundParticles()
Code
409function WorkParticles:loadGroundParticles(xmlFile, key, particle, index)
410 particle.mappings = {}
411
412 local filename = xmlFile:getValue(key .. "#file")
413 if filename ~= nil then
414 filename = Utils.getFilename(filename, self.baseDirectory)
415 local arguments = {
416 xmlFile = xmlFile,
417 key = key,
418 particle = particle,
419 filename = filename
420 }
421 particle.sharedLoadRequestId = g_i3DManager:loadSharedI3DFileAsync(filename, false, false, self.groundParticleI3DLoaded, self, arguments)
422 else
423 local j = 0
424 while true do
425 local nodeBaseName = string.format(key .. ".node(%d)", j)
426 if not xmlFile:hasProperty(nodeBaseName) then
427 break
428 end
429
430 local mapping = {}
431 if self:loadGroundParticleMapping(xmlFile, nodeBaseName, mapping, j) then
432 table.insert(particle.mappings, mapping)
433 end
434 j = j + 1
435 end
436 end
437
438 return true
439end

loadGroundReferenceNode

Description
Definition
loadGroundReferenceNode()
Code
569function WorkParticles:loadGroundReferenceNode(superFunc, xmlFile, key, groundReferenceNode)
570 local returnValue = superFunc(self, xmlFile, key, groundReferenceNode)
571
572 if returnValue then
573 groundReferenceNode.depthNode = xmlFile:getValue(key .. "#depthNode", nil, self.components, self.i3dMappings)
574 groundReferenceNode.movedDistance = 0
575 groundReferenceNode.depth = 0
576 groundReferenceNode.movingDirection = 0
577 end
578
579 return returnValue
580end

onDeactivate

Description
Definition
onDeactivate()
Code
608function WorkParticles:onDeactivate()
609 local spec = self.spec_workParticles
610
611 for _,ps in pairs(spec.particles) do
612 for _, mapping in ipairs(ps.mappings) do
613 ParticleUtil.setEmittingState(mapping.particleSystem, false)
614 end
615 end
616 for _, animation in ipairs(spec.particleAnimations) do
617 for _, mapping in ipairs(animation.mappings) do
618 setVisibility(mapping.animNode, false)
619 end
620 end
621end

onDelete

Description
Definition
onDelete()
Code
172function WorkParticles:onDelete()
173 local spec = self.spec_workParticles
174
175 if spec.particleAnimations ~= nil then
176 for _, animation in ipairs(spec.particleAnimations) do
177 if animation.sharedLoadRequestId ~= nil then
178 g_i3DManager:releaseSharedI3DFile(animation.sharedLoadRequestId)
179 animation.sharedLoadRequestId = nil
180 end
181 end
182 end
183
184 if spec.particles ~= nil then
185 for _, ps in pairs(spec.particles) do
186 for _, mapping in ipairs(ps.mappings) do
187 ParticleUtil.deleteParticleSystem(mapping.particleSystem)
188 end
189
190 if ps.sharedLoadRequestId ~= nil then
191 g_i3DManager:releaseSharedI3DFile(ps.sharedLoadRequestId)
192 ps.sharedLoadRequestId = nil
193 end
194 end
195 end
196
197 if spec.effects ~= nil then
198 for _, effect in pairs(spec.effects) do
199 g_effectManager:deleteEffects(effect.effect)
200 end
201 end
202end

onGroundAnimationI3DLoaded

Description
Definition
onGroundAnimationI3DLoaded()
Code
337function WorkParticles:onGroundAnimationI3DLoaded(i3dNode, args)
338 if i3dNode ~= 0 then
339 local animation = args.animation
340 -- link after loading to make sure all indices are correct
341 for _, mapping in ipairs(animation.mappings) do
342 link(mapping.node, mapping.animNode)
343 setVisibility(mapping.animNode, false)
344 end
345
346 animation.filename = args.filename
347 delete(i3dNode)
348 end
349end

onLoad

Description
Definition
onLoad()
Code
107function WorkParticles:onLoad(savegame)
108 local spec = self.spec_workParticles
109
110 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.groundParticleAnimations.groundParticleAnimation", "vehicle.workParticles.particleAnimation") --FS17 to FS19
111 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.groundParticleAnimations.groundParticle", "vehicle.workParticles.particle") --FS17 to FS19
112
113 if self.isClient then
114 spec.particleAnimations = {}
115 local i = 0
116 while true do
117 local key = string.format("vehicle.workParticles.particleAnimation(%d)", i)
118 if not self.xmlFile:hasProperty(key) then
119 break
120 end
121
122 local animation = {}
123 if self:loadGroundAnimations(self.xmlFile, key, animation, i) then
124 table.insert(spec.particleAnimations, animation)
125 end
126
127 i = i + 1
128 end
129
130 spec.particles = {}
131 i = 0
132 while true do
133 local key = string.format("vehicle.workParticles.particle(%d)", i)
134 if not self.xmlFile:hasProperty(key) then
135 break
136 end
137
138 local particle = {}
139 if self:loadGroundParticles(self.xmlFile, key, particle, i) then
140 table.insert(spec.particles, particle)
141 end
142
143 i = i + 1
144 end
145
146 spec.effects = {}
147 i = 0
148 while true do
149 local key = string.format("vehicle.workParticles.effect(%d)", i)
150 if not self.xmlFile:hasProperty(key) then
151 break
152 end
153
154 local effect = {}
155 if self:loadGroundEffects(self.xmlFile, key, effect, i) then
156 table.insert(spec.effects, effect)
157 end
158
159 i = i + 1
160 end
161 end
162
163 if not self.isClient then
164 SpecializationUtil.removeEventListener(self, "onDelete", WorkParticles)
165 SpecializationUtil.removeEventListener(self, "onUpdateTick", WorkParticles)
166 SpecializationUtil.removeEventListener(self, "onDeactivate", WorkParticles)
167 end
168end

onUpdateTick

Description
Definition
onUpdateTick()
Code
207function WorkParticles:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
208 local spec = self.spec_workParticles
209 local isOnField = self:getIsOnField()
210
211 for _, animation in ipairs(spec.particleAnimations) do
212 for _, mapping in ipairs(animation.mappings) do
213 local refNode = mapping.groundRefNode
214 if refNode ~= nil and refNode.depthNode ~= nil then
215 local depth = MathUtil.clamp(refNode.depth / mapping.maxWorkDepth, 0, 1)
216 if not isOnField then
217 depth = 0
218 end
219
220 depth = MathUtil.clamp(math.min(depth, mapping.lastDepth + refNode.movingDirection * (refNode.movedDistance/0.5)), 0 ,1)
221 mapping.lastDepth = depth
222 mapping.speed = mapping.speed - (refNode.movedDistance * refNode.movingDirection)
223 setVisibility(mapping.animNode, depth > 0)
224 setShaderParameter(mapping.animNode, "VertxoffsetVertexdeformMotionUVscale", -6, depth, mapping.speed, 1.5, false)
225 end
226 end
227 end
228
229 local lastSpeed = self:getLastSpeed(true)
230 local enabled = self:getDoGroundManipulation() and isOnField
231
232 for _,ps in pairs(spec.particles) do
233 for _, mapping in ipairs(ps.mappings) do
234 local nodeEnabled = enabled
235 if nodeEnabled then
236 nodeEnabled = mapping.groundRefNode.isActive and lastSpeed > mapping.speedThreshold
237 end
238 if mapping.movingDirection ~= nil then
239 nodeEnabled = nodeEnabled and mapping.movingDirection == self.movingDirection
240 end
241 ParticleUtil.setEmittingState(mapping.particleSystem, nodeEnabled)
242 end
243 end
244
245 for _,effect in pairs(spec.effects) do
246 local state = enabled and lastSpeed > effect.speedThreshold
247
248 if effect.needsSetIsTurnedOn then
249 if self.getIsTurnedOn ~= nil then
250 local turnedOn = self:getIsTurnedOn()
251 if self.getAttacherVehicle ~= nil then
252 local attacherVehicle = self:getAttacherVehicle()
253 if attacherVehicle ~= nil then
254 if attacherVehicle.getIsTurnedOn ~= nil then
255 turnedOn = turnedOn or attacherVehicle:getIsTurnedOn()
256 end
257 end
258 end
259
260 state = state and turnedOn
261 end
262 end
263
264 local workArea = self:getWorkAreaByIndex(effect.workAreaIndex)
265 if workArea ~= nil then
266 if workArea.requiresGroundContact then
267 state = state and workArea.groundReferenceNode ~= nil and workArea.groundReferenceNode.isActive
268 end
269 end
270
271 if effect.groundReferenceNodeIndex ~= nil and effect.groundReferenceNode == nil then
272 effect.groundReferenceNode = self:getGroundReferenceNodeFromIndex(effect.groundReferenceNodeIndex)
273 if effect.groundReferenceNode == nil then
274 Logging.warning("Unknown ground reference node '%s' for WorkParticle effect!", effect.groundReferenceNodeIndex)
275 effect.groundReferenceNodeIndex = nil
276 end
277 end
278
279 if effect.groundReferenceNode ~= nil then
280 state = state and effect.groundReferenceNode.isActive
281 end
282
283 -- ignore direction 0
284 state = state and (self.movingDirection ~= -effect.activeDirection or self:getLastSpeed() < 0.5)
285
286 if state then
287 local fillType = self:getFillTypeFromWorkAreaIndex(effect.workAreaIndex)
288 g_effectManager:setFillType(effect.effect, fillType)
289 g_effectManager:startEffects(effect.effect)
290 else
291 g_effectManager:stopEffects(effect.effect)
292 end
293 end
294end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
17function WorkParticles.prerequisitesPresent(specializations)
18 return true
19end

registerEventListeners

Description
Definition
registerEventListeners()
Code
98function WorkParticles.registerEventListeners(vehicleType)
99 SpecializationUtil.registerEventListener(vehicleType, "onLoad", WorkParticles)
100 SpecializationUtil.registerEventListener(vehicleType, "onDelete", WorkParticles)
101 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", WorkParticles)
102 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", WorkParticles)
103end

registerFunctions

Description
Definition
registerFunctions()
Code
77function WorkParticles.registerFunctions(vehicleType)
78 SpecializationUtil.registerFunction(vehicleType, "getDoGroundManipulation", WorkParticles.getDoGroundManipulation)
79 SpecializationUtil.registerFunction(vehicleType, "loadGroundAnimations", WorkParticles.loadGroundAnimations)
80 SpecializationUtil.registerFunction(vehicleType, "onGroundAnimationI3DLoaded", WorkParticles.onGroundAnimationI3DLoaded)
81 SpecializationUtil.registerFunction(vehicleType, "loadGroundAnimationMapping", WorkParticles.loadGroundAnimationMapping)
82 SpecializationUtil.registerFunction(vehicleType, "loadGroundParticles", WorkParticles.loadGroundParticles)
83 SpecializationUtil.registerFunction(vehicleType, "groundParticleI3DLoaded", WorkParticles.groundParticleI3DLoaded)
84 SpecializationUtil.registerFunction(vehicleType, "loadGroundParticleMapping", WorkParticles.loadGroundParticleMapping)
85 SpecializationUtil.registerFunction(vehicleType, "loadGroundEffects", WorkParticles.loadGroundEffects)
86 SpecializationUtil.registerFunction(vehicleType, "getFillTypeFromWorkAreaIndex", WorkParticles.getFillTypeFromWorkAreaIndex)
87end

registerGroundAnimationMappingXMLPaths

Description
Definition
registerGroundAnimationMappingXMLPaths()
Code
48function WorkParticles.registerGroundAnimationMappingXMLPaths(schema, key)
49 schema:register(XMLValueType.NODE_INDEX, key .. "#node", "Link node in vehicle")
50 schema:register(XMLValueType.INT, key .. "#refNodeIndex", "Ground reference node index")
51 schema:register(XMLValueType.STRING, key .. "#animMeshNode", "Animation mesh node in external file")
52
53 schema:register(XMLValueType.STRING, key .. "#materialType", "Material type name (If external file is not given)")
54 schema:register(XMLValueType.INT, key .. "#materialId", "Material index (If external file is not given)", 1)
55
56 schema:register(XMLValueType.FLOAT, key .. "#maxDepth", "Max. depth", -0.1)
57end

registerGroundParticleMappingXMLPaths

Description
Definition
registerGroundParticleMappingXMLPaths()
Code
61function WorkParticles.registerGroundParticleMappingXMLPaths(schema, key)
62 schema:register(XMLValueType.NODE_INDEX, key .. "#node", "Link node in vehicle")
63 schema:register(XMLValueType.INT, key .. "#refNodeIndex", "Ground reference node index")
64 schema:register(XMLValueType.STRING, key .. "#particleNode", "Particle node in external file")
65
66 schema:register(XMLValueType.STRING, key .. "#particleType", "Particle type name (If external file is not given)")
67 schema:register(XMLValueType.STRING, key .. "#fillType", "Fill type for particles (If external file is not given)", "UNKNOWN")
68
69 schema:register(XMLValueType.FLOAT, key .. "#speedThreshold", "Speed threshold", 0.5)
70 schema:register(XMLValueType.INT, key .. "#movingDirection", "Moving direction")
71
72 ParticleUtil.registerParticleCopyXMLPaths(schema, key)
73end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
91function WorkParticles.registerOverwrittenFunctions(vehicleType)
92 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadGroundReferenceNode", WorkParticles.loadGroundReferenceNode)
93 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateGroundReferenceNode", WorkParticles.updateGroundReferenceNode)
94end

updateGroundReferenceNode

Description
Definition
updateGroundReferenceNode()
Code
584function WorkParticles:updateGroundReferenceNode(superFunc, groundReferenceNode, x, y, z, terrainHeight, densityHeight)
585
586 superFunc(self, groundReferenceNode, x, y, z, terrainHeight, densityHeight)
587 if self.isClient and groundReferenceNode.depthNode ~= nil then
588 local newX, newY, newZ = getWorldTranslation(groundReferenceNode.depthNode)
589 if groundReferenceNode.lastPosition == nil then
590 groundReferenceNode.lastPosition = {newX, newY, newZ}
591 end
592 local dx, dy, dz = worldDirectionToLocal(groundReferenceNode.depthNode, newX-groundReferenceNode.lastPosition[1], newY-groundReferenceNode.lastPosition[2], newZ-groundReferenceNode.lastPosition[3])
593 groundReferenceNode.movingDirection = 0
594 if dz > 0.0001 then
595 groundReferenceNode.movingDirection = 1
596 elseif dz < -0.0001 then
597 groundReferenceNode.movingDirection = -1
598 end
599 groundReferenceNode.movedDistance = MathUtil.vector3Length(dx, dy, dz)
600 groundReferenceNode.lastPosition[1], groundReferenceNode.lastPosition[2], groundReferenceNode.lastPosition[3] = newX, newY, newZ
601 local terrainHeightDepthNode = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, newX, newY, newZ)
602 groundReferenceNode.depth = newY - terrainHeightDepthNode
603 end
604end