LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

WoodCrusher

Description
Specialization for wood crusher allowing to cut and convert tree trunks into wood chips
Functions

crushSplitShape

Description
Crush split shape
Definition
crushSplitShape(integer shape)
Arguments
integershapeid of shape
Code
628function WoodCrusher.crushSplitShape(self, woodCrusher, shape)
629 local splitType = g_splitTypeManager:getSplitTypeByIndex(getSplitType(shape))
630 if splitType ~= nil and splitType.woodChipsPerLiter > 0 then
631 local volume = getVolume(shape)
632 delete(shape)
633 woodCrusher.crushingTime = 1000
634 self:onCrushedSplitShape(splitType, volume)
635 end
636end

deleteWoodCrusher

Description
Delete wood crusher
Definition
deleteWoodCrusher()
Code
428function WoodCrusher.deleteWoodCrusher(self, woodCrusher)
429 if woodCrusher.moveTriggers ~= nil then
430 for _,node in pairs(woodCrusher.moveTriggers) do
431 removeTrigger(node)
432 end
433 end
434
435 if woodCrusher.downForceTriggers ~= nil then
436 for trigger, _ in pairs(woodCrusher.downForceTriggers) do
437 removeTrigger(trigger)
438 end
439 end
440
441 g_effectManager:deleteEffects(woodCrusher.crushEffects)
442 g_soundManager:deleteSamples(woodCrusher.samples)
443 g_animationManager:deleteAnimations(woodCrusher.animationNodes)
444end

getCanBeTurnedOn

Description
Returns if user is allowed to turn on the vehicle
Definition
getCanBeTurnedOn()
Return Values
booleanallowallow turn on
Code
236function WoodCrusher:getCanBeTurnedOn(superFunc)
237 local spec = self.spec_woodCrusher
238 if spec.turnOnAutomatically then
239 return false
240 end
241
242 return superFunc(self)
243end

getDirtMultiplier

Description
Returns current dirt multiplier
Definition
getDirtMultiplier()
Return Values
floatdirtMultipliercurrent dirt multiplier
Code
248function WoodCrusher:getDirtMultiplier(superFunc)
249 local multiplier = superFunc(self)
250
251 local spec = self.spec_woodCrusher
252 if spec.crushingTime > 0 then
253 multiplier = multiplier + self:getWorkDirtMultiplier()
254 end
255
256 return multiplier
257end

getWearMultiplier

Description
Returns current wear multiplier
Definition
getWearMultiplier()
Return Values
floatdirtMultipliercurrent wear multiplier
Code
262function WoodCrusher:getWearMultiplier(superFunc)
263 local multiplier = superFunc(self)
264
265 local spec = self.spec_woodCrusher
266 if spec.crushingTime > 0 then
267 multiplier = multiplier + self:getWorkWearMultiplier()
268 end
269
270 return multiplier
271end

initSpecialization

Description
Definition
initSpecialization()
Code
25function WoodCrusher.initSpecialization()
26 local schema = Vehicle.xmlSchema
27 schema:setXMLSpecializationType("WoodCrusher")
28
29 WoodCrusher.registerWoodCrusherXMLPaths(schema, "vehicle.woodCrusher")
30
31 schema:register(XMLValueType.BOOL, "vehicle.woodCrusher#moveColDisableCollisionPairs", "Activate collision between move collisions and components", true)
32 schema:register(XMLValueType.INT, "vehicle.woodCrusher#fillUnitIndex", "Fill unit index", 1)
33
34 schema:setXMLSpecializationType()
35end

loadWoodCrusher

Description
Load wood crusher from xml file
Definition
loadWoodCrusher(table woodCrusher, integer xmlFile, integer rootNode, table i3dMappings)
Arguments
tablewoodCrushertarget wood crusher table
integerxmlFileid of xml object
integerrootNodeid of root node or list of components
tablei3dMappingsi3d mappings
Code
294function WoodCrusher.loadWoodCrusher(self, woodCrusher, xmlFile, rootNode, i3dMappings)
295 woodCrusher.vehicle = self
296
297 woodCrusher.woodCrusherSplitShapeCallback = WoodCrusher.woodCrusherSplitShapeCallback
298 woodCrusher.woodCrusherMoveTriggerCallback = WoodCrusher.woodCrusherMoveTriggerCallback
299 woodCrusher.woodCrusherDownForceTriggerCallback = WoodCrusher.woodCrusherDownForceTriggerCallback
300
301 local xmlRoot = xmlFile:getRootName()
302 local baseKey = xmlRoot .. ".woodCrusher"
303
304 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".woodCrusher.moveTrigger(0)#index", xmlRoot .. ".woodCrusher.moveTriggers.trigger#node") --FS17 to FS19
305 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".woodCrusher.moveCollision(0)#index", xmlRoot .. ".woodCrusher.moveCollisions.collision#node") --FS17 to FS19
306 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".woodCrusher.emitterShape(0)", xmlRoot .. ".woodCrusher.crushEffects with effectClass 'ParticleEffect'") --FS17 to FS19
307 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".woodCrusherStartSound", xmlRoot .. ".woodCrusher.sounds.start") --FS17 to FS19
308 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".woodCrusherIdleSound", xmlRoot .. ".woodCrusher.sounds.idle") --FS17 to FS19
309 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".woodCrusherWorkSound", xmlRoot .. ".woodCrusher.sounds.work") --FS17 to FS19
310 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".woodCrusherStopSound", xmlRoot .. ".woodCrusher.sounds.stop") --FS17 to FS19
311 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".turnedOnRotationNodes.turnedOnRotationNode#type", xmlRoot .. ".woodCrusher.animationNodes.animationNode", "woodCrusher") --FS17 to FS19
312 XMLUtil.checkDeprecatedXMLElements(xmlFile, xmlRoot .. ".turnedOnScrollers.turnedOnScroller", xmlRoot .. ".woodCrusher.animationNodes.animationNode") --FS17 to FS19
313
314 XMLUtil.checkDeprecatedXMLElements(xmlFile, baseKey .. "#downForceNode", baseKey .. ".downForceNodes.downForceNode#node") --FS19 to FS22
315 XMLUtil.checkDeprecatedXMLElements(xmlFile, baseKey .. "#downForce", baseKey .. ".downForceNodes.downForceNode#force") --FS19 to FS22
316 XMLUtil.checkDeprecatedXMLElements(xmlFile, baseKey .. "#downForceSizeY", baseKey .. ".downForceNodes.downForceNode#sizeY") --FS19 to FS22
317 XMLUtil.checkDeprecatedXMLElements(xmlFile, baseKey .. "#downForceSizeZ", baseKey .. ".downForceNodes.downForceNode#sizeZ") --FS19 to FS22
318
319 woodCrusher.cutNode = xmlFile:getValue(baseKey .. "#cutNode", nil, rootNode, i3dMappings)
320 woodCrusher.mainDrumRefNode = xmlFile:getValue(baseKey .. "#mainDrumRefNode", nil, rootNode, i3dMappings)
321 woodCrusher.mainDrumRefNodeMaxY = xmlFile:getValue(baseKey .. "#mainDrumRefNodeMaxY", math.huge)
322
323 if woodCrusher.mainDrumRefNode ~= nil then
324 local mainDrumRefNodeParent = createTransformGroup("mainDrumRefNodeParent")
325 link(getParent(woodCrusher.mainDrumRefNode), mainDrumRefNodeParent, getChildIndex(woodCrusher.mainDrumRefNode))
326 setTranslation(mainDrumRefNodeParent, getTranslation(woodCrusher.mainDrumRefNode))
327 setRotation(mainDrumRefNodeParent, getRotation(woodCrusher.mainDrumRefNode))
328 link(mainDrumRefNodeParent, woodCrusher.mainDrumRefNode)
329 setTranslation(woodCrusher.mainDrumRefNode, 0, 0, 0)
330 setRotation(woodCrusher.mainDrumRefNode, 0, 0, 0)
331 end
332
333 woodCrusher.moveTriggers = {}
334 local i = 0
335 while true do
336 local key = string.format("%s.moveTriggers.trigger(%d)", baseKey, i)
337 if not xmlFile:hasProperty(key) then
338 break
339 end
340
341 local node = xmlFile:getValue(key .. "#node", nil, rootNode, i3dMappings)
342 if node ~= nil then
343 if not CollisionFlag.getHasFlagSet(node, CollisionFlag.TREE) then
344 Logging.xmlWarning(self.xmlFile, "Missing collision mask bit '%d'. Please add this bit to move trigger node '%s' in '%s'", CollisionFlag.getBit(CollisionFlag.TREE), getName(node), key)
345 break
346 end
347 table.insert(woodCrusher.moveTriggers, node)
348 end
349 i = i + 1
350 end
351
352 woodCrusher.moveColNodes = {}
353 i = 0
354 while true do
355 local key = string.format("%s.moveCollisions.collision(%d)", baseKey, i)
356 if not xmlFile:hasProperty(key) then
357 break
358 end
359
360 local moveColNode = {}
361 moveColNode.node = xmlFile:getValue(key .. "#node", nil, rootNode, i3dMappings)
362 if moveColNode.node ~= nil then
363 moveColNode.transX, moveColNode.transY, moveColNode.transZ = getTranslation(moveColNode.node)
364 table.insert(woodCrusher.moveColNodes, moveColNode)
365 end
366 i = i + 1
367 end
368
369 woodCrusher.moveVelocityZ = xmlFile:getValue(baseKey.."#moveVelocityZ", 0.8) -- m/s
370 woodCrusher.moveMaxForce = xmlFile:getValue(baseKey.."#moveMaxForce", 7) -- input is kN
371 woodCrusher.shapeSizeDetectionNode = xmlFile:getValue(baseKey.."#shapeSizeDetectionNode", nil, rootNode, i3dMappings)
372 woodCrusher.cutSizeY = xmlFile:getValue(baseKey.."#cutSizeY", 1)
373 woodCrusher.cutSizeZ = xmlFile:getValue(baseKey.."#cutSizeZ", 1)
374
375 woodCrusher.downForceNodes = {}
376 woodCrusher.downForceTriggers = {}
377 xmlFile:iterate(baseKey .. ".downForceNodes.downForceNode", function(_, key)
378 local downForceNode = {}
379 downForceNode.node = xmlFile:getValue(key .. "#node", nil, rootNode, i3dMappings)
380 if downForceNode.node ~= nil then
381 downForceNode.force = xmlFile:getValue(key.."#force", 2)
382 downForceNode.trigger = xmlFile:getValue(key .. "#trigger", nil, rootNode, i3dMappings)
383
384 downForceNode.sizeY = xmlFile:getValue(key.."#sizeY", woodCrusher.cutSizeY)
385 downForceNode.sizeZ = xmlFile:getValue(key.."#sizeZ", woodCrusher.cutSizeZ)
386
387 downForceNode.woodCrusher = woodCrusher
388 downForceNode.triggerNodes = {}
389
390 if downForceNode.trigger ~= nil and woodCrusher.downForceTriggers[downForceNode.trigger] == nil then
391 if self.isServer then
392 woodCrusher.downForceTriggers[downForceNode.trigger] = true
393 addTrigger(downForceNode.trigger, "woodCrusherDownForceTriggerCallback", woodCrusher)
394 end
395 end
396
397 table.insert(woodCrusher.downForceNodes, downForceNode)
398 end
399 end)
400
401 woodCrusher.moveTriggerNodes = {}
402 if self.isServer and woodCrusher.moveTriggers ~= nil then
403 for _,node in pairs(woodCrusher.moveTriggers) do
404 addTrigger(node, "woodCrusherMoveTriggerCallback", woodCrusher)
405 end
406 end
407
408 woodCrusher.crushNodes = {}
409 woodCrusher.crushingTime = 0
410 woodCrusher.turnOnAutomatically = xmlFile:getValue(baseKey .. "#automaticallyTurnOn", false)
411
412 if self.isClient then
413 woodCrusher.crushEffects = g_effectManager:loadEffect(xmlFile, baseKey..".crushEffects", rootNode, self, i3dMappings)
414
415 woodCrusher.animationNodes = g_animationManager:loadAnimations(xmlFile, baseKey..".animationNodes", rootNode, self, i3dMappings)
416
417 woodCrusher.isWorkSamplePlaying = false
418 woodCrusher.samples = {}
419 woodCrusher.samples.start = g_soundManager:loadSampleFromXML(xmlFile, baseKey..".sounds", "start", self.baseDirectory, rootNode, 1, AudioGroup.VEHICLE, i3dMappings, self)
420 woodCrusher.samples.stop = g_soundManager:loadSampleFromXML(xmlFile, baseKey..".sounds", "stop", self.baseDirectory, rootNode, 1, AudioGroup.VEHICLE, i3dMappings, self)
421 woodCrusher.samples.work = g_soundManager:loadSampleFromXML(xmlFile, baseKey..".sounds", "work", self.baseDirectory, rootNode, 0, AudioGroup.VEHICLE, i3dMappings, self)
422 woodCrusher.samples.idle = g_soundManager:loadSampleFromXML(xmlFile, baseKey..".sounds", "idle", self.baseDirectory, rootNode, 0, AudioGroup.VEHICLE, i3dMappings, self)
423 end
424end

onCrushedSplitShape

Description
Called on crush split shape
Definition
onCrushedSplitShape(table splitType, float volume)
Arguments
tablesplitTypesplit type
floatvolumevolume
Code
277function WoodCrusher:onCrushedSplitShape(splitType, volume)
278 local spec = self.spec_woodCrusher
279
280 local damage = self:getVehicleDamage()
281 if damage > 0 then
282 volume = volume * (1 - damage * WoodCrusher.DAMAGED_YIELD_DECREASE)
283 end
284
285 self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, volume * 1000 * splitType.woodChipsPerLiter, FillType.WOODCHIPS, ToolType.UNDEFINED)
286end

onDelete

Description
Called on deleting
Definition
onDelete()
Code
119function WoodCrusher:onDelete()
120 WoodCrusher.deleteWoodCrusher(self, self.spec_woodCrusher)
121end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
100function WoodCrusher:onLoad(savegame)
101 local spec = self.spec_woodCrusher
102
103 WoodCrusher.loadWoodCrusher(self, spec, self.xmlFile, self.components, self.i3dMappings)
104
105 local moveColDisableCollisionPairs = self.xmlFile:getValue("vehicle.woodCrusher#moveColDisableCollisionPairs", true)
106 if moveColDisableCollisionPairs then
107 for _, component in pairs(self.components) do
108 for _, node in pairs(spec.moveColNodes) do
109 setPairCollision(component.node, node, false)
110 end
111 end
112 end
113
114 spec.fillUnitIndex = self.xmlFile:getValue("vehicle.woodCrusher#fillUnitIndex", 1)
115end

onReadUpdateStream

Description
Called on on update
Definition
onReadUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
128function WoodCrusher:onReadUpdateStream(streamId, timestamp, connection)
129 if connection:getIsServer() then
130 local spec = self.spec_woodCrusher
131 if streamReadBool(streamId) then
132 spec.crushingTime = 1000
133 else
134 spec.crushingTime = 0
135 end
136 end
137end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
229function WoodCrusher:onTurnedOff()
230 WoodCrusher.turnOffWoodCrusher(self, self.spec_woodCrusher)
231end

onTurnedOn

Description
Called on turn on
Definition
onTurnedOn(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
222function WoodCrusher:onTurnedOn()
223 WoodCrusher.turnOnWoodCrusher(self, self.spec_woodCrusher)
224end

onUpdate

Description
Called on update
Definition
onUpdate(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
156function WoodCrusher:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
157 WoodCrusher.updateWoodCrusher(self, self.spec_woodCrusher, dt, self:getIsTurnedOn())
158end

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
165function WoodCrusher:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
166 WoodCrusher.updateTickWoodCrusher(self, self.spec_woodCrusher, dt, self:getIsTurnedOn())
167
168 local spec = self.spec_woodCrusher
169 -- turn on/off automatically if tree node is in trigger
170 if self.isServer then
171 if g_currentMission.missionInfo.automaticMotorStartEnabled then
172 if spec.turnOnAutomatically and self.setIsTurnedOn ~= nil then
173 if next(spec.moveTriggerNodes) ~= nil then
174 if self.getIsMotorStarted ~= nil then
175 if not self:getIsMotorStarted() then
176 self:startMotor()
177 end
178 else
179 if self.attacherVehicle ~= nil then
180 if self.attacherVehicle.getIsMotorStarted ~= nil then
181 if not self.attacherVehicle:getIsMotorStarted() then
182 self.attacherVehicle:startMotor()
183 end
184 end
185 end
186 end
187
188 if not self.isControlled and not self:getIsTurnedOn() and self:getCanBeTurnedOn() then
189 self:setIsTurnedOn(true)
190 end
191 spec.turnOffTimer = 3000
192 else
193 if self:getIsTurnedOn() then
194 if spec.turnOffTimer == nil then
195 spec.turnOffTimer = 3000
196 end
197 spec.turnOffTimer = spec.turnOffTimer - dt
198
199 if spec.turnOffTimer < 0 then
200 local rootAttacherVehicle = self:getRootVehicle()
201
202 if not rootAttacherVehicle.isControlled then
203 if self.getIsMotorStarted ~= nil then
204 if self:getIsMotorStarted() then
205 self:stopMotor()
206 end
207 end
208
209 self:setIsTurnedOn(false)
210 end
211 end
212 end
213 end
214 end
215 end
216 end
217end

onWriteUpdateStream

Description
Called on on update
Definition
onWriteUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
144function WoodCrusher:onWriteUpdateStream(streamId, connection, dirtyMask)
145 if not connection:getIsServer() then
146 local spec = self.spec_woodCrusher
147 streamWriteBool(streamId, spec.crushingTime > 0)
148 end
149end

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
19function WoodCrusher.prerequisitesPresent(specializations)
20 return SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) and SpecializationUtil.hasSpecialization(FillUnit, specializations)
21end

registerEventListeners

Description
Definition
registerEventListeners()
Code
86function WoodCrusher.registerEventListeners(vehicleType)
87 SpecializationUtil.registerEventListener(vehicleType, "onLoad", WoodCrusher)
88 SpecializationUtil.registerEventListener(vehicleType, "onDelete", WoodCrusher)
89 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", WoodCrusher)
90 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", WoodCrusher)
91 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", WoodCrusher)
92 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", WoodCrusher)
93 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", WoodCrusher)
94 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", WoodCrusher)
95end

registerFunctions

Description
Definition
registerFunctions()
Code
72function WoodCrusher.registerFunctions(vehicleType)
73 SpecializationUtil.registerFunction(vehicleType, "onCrushedSplitShape", WoodCrusher.onCrushedSplitShape)
74end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
78function WoodCrusher.registerOverwrittenFunctions(vehicleType)
79 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", WoodCrusher.getDirtMultiplier)
80 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", WoodCrusher.getWearMultiplier)
81 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", WoodCrusher.getCanBeTurnedOn)
82end

registerWoodCrusherXMLPaths

Description
Definition
registerWoodCrusherXMLPaths()
Code
39function WoodCrusher.registerWoodCrusherXMLPaths(schema, key)
40 schema:register(XMLValueType.NODE_INDEX, key .. "#cutNode", "Cut node")
41 schema:register(XMLValueType.NODE_INDEX, key .. "#mainDrumRefNode", "Main drum reference node")
42 schema:register(XMLValueType.FLOAT, key .. "#mainDrumRefNodeMaxY", "Max tree size the main drum can handle")
43
44 schema:register(XMLValueType.NODE_INDEX, key .. ".moveTriggers.trigger(?)#node", "Move trigger")
45 schema:register(XMLValueType.NODE_INDEX, key .. ".moveCollisions.collision(?)#node", "Move collision")
46
47 schema:register(XMLValueType.FLOAT, key .. "#moveVelocityZ", "Move velocity Z (m/s)", 0.8)
48 schema:register(XMLValueType.FLOAT, key .. "#moveMaxForce", "Move max. force (kN)", 7)
49 schema:register(XMLValueType.NODE_INDEX, key .. "#shapeSizeDetectionNode", "At this node the tree shape size will be detected to set the #mainDrumRefNode")
50 schema:register(XMLValueType.FLOAT, key .. "#cutSizeY", "Cut size Y", 1)
51 schema:register(XMLValueType.FLOAT, key .. "#cutSizeZ", "Cut size Z", 1)
52
53 schema:register(XMLValueType.NODE_INDEX, key .. ".downForceNodes.downForceNode(?)#node", "Down force node")
54 schema:register(XMLValueType.NODE_INDEX, key .. ".downForceNodes.downForceNode(?)#trigger", "Additional trigger (If defined the tree needs to be present in the mover trigger and inside this trigger)")
55 schema:register(XMLValueType.FLOAT, key .. ".downForceNodes.downForceNode(?)#force", "Down force (kN)", 2)
56 schema:register(XMLValueType.FLOAT, key .. ".downForceNodes.downForceNode(?)#sizeY", "Size Y in which the down force node detects trees", "Cut size Y")
57 schema:register(XMLValueType.FLOAT, key .. ".downForceNodes.downForceNode(?)#sizeZ", "Size Z in which the down force node detects trees", "Cut size Z")
58
59 schema:register(XMLValueType.BOOL, key .. "#automaticallyTurnOn", "Automatically turned on", false)
60
61 EffectManager.registerEffectXMLPaths(schema, key .. ".crushEffects")
62 AnimationManager.registerAnimationNodesXMLPaths(schema, key .. ".animationNodes")
63
64 SoundManager.registerSampleXMLPaths(schema, key .. ".sounds", "start")
65 SoundManager.registerSampleXMLPaths(schema, key .. ".sounds", "stop")
66 SoundManager.registerSampleXMLPaths(schema, key .. ".sounds", "work")
67 SoundManager.registerSampleXMLPaths(schema, key .. ".sounds", "idle")
68end

turnOffWoodCrusher

Description
Turn off wood crusher
Definition
turnOffWoodCrusher()
Code
600function WoodCrusher.turnOffWoodCrusher(self, woodCrusher)
601 if self.isServer then
602 for node in pairs(woodCrusher.crushNodes) do
603 WoodCrusher.crushSplitShape(self, woodCrusher, node)
604 woodCrusher.crushNodes[node] = nil
605 end
606 if woodCrusher.moveColNodes ~= nil then
607 for _, moveColNode in pairs(woodCrusher.moveColNodes) do
608 setFrictionVelocity(moveColNode.node, 0.0)
609 end
610 end
611 end
612
613 if self.isClient then
614 g_effectManager:stopEffects(woodCrusher.crushEffects)
615 g_soundManager:stopSamples(woodCrusher.samples)
616 g_soundManager:playSample(woodCrusher.samples.stop)
617 woodCrusher.isWorkSamplePlaying = false
618
619 if self.isClient then
620 g_animationManager:stopAnimations(woodCrusher.animationNodes)
621 end
622 end
623end

turnOnWoodCrusher

Description
Turn on wood crusher
Definition
turnOnWoodCrusher()
Code
579function WoodCrusher.turnOnWoodCrusher(self, woodCrusher)
580 if self.isServer and woodCrusher.moveColNodes ~= nil then
581 for _, moveColNode in pairs(woodCrusher.moveColNodes) do
582 setFrictionVelocity(moveColNode.node, woodCrusher.moveVelocityZ)
583 end
584 end
585
586 if self.isClient then
587 g_soundManager:stopSamples(woodCrusher.samples)
588 woodCrusher.isWorkSamplePlaying = false
589 g_soundManager:playSample(woodCrusher.samples.start)
590 g_soundManager:playSample(woodCrusher.samples.idle, 0, woodCrusher.samples.start)
591
592 if self.isClient then
593 g_animationManager:startAnimations(woodCrusher.animationNodes)
594 end
595 end
596end

updateTickWoodCrusher

Description
Update tick wood crusher
Definition
updateTickWoodCrusher(float dt)
Arguments
floatdttime since last call in ms
Code
516function WoodCrusher.updateTickWoodCrusher(self, woodCrusher, dt, isTurnedOn)
517 if isTurnedOn then
518 if self.isServer then
519 if woodCrusher.cutNode ~= nil and next(woodCrusher.moveTriggerNodes) ~= nil then
520 local x,y,z = getWorldTranslation(woodCrusher.cutNode)
521 local nx,ny,nz = localDirectionToWorld(woodCrusher.cutNode, 1,0,0)
522 local yx,yy,yz = localDirectionToWorld(woodCrusher.cutNode, 0,1,0)
523 for id in pairs(woodCrusher.moveTriggerNodes) do
524 local lenBelow, lenAbove = getSplitShapePlaneExtents(id, x,y,z, nx,ny,nz)
525 if lenAbove ~= nil and lenBelow ~= nil then
526 if lenBelow <= 0.4 then
527 woodCrusher.moveTriggerNodes[id] = nil
528 WoodCrusher.crushSplitShape(self, woodCrusher, id)
529 elseif lenAbove >= 0.2 then
530 self.shapeBeingCut = id
531 local minY = splitShape(id, x,y,z, nx,ny,nz, yx,yy,yz, woodCrusher.cutSizeY, woodCrusher.cutSizeZ, "woodCrusherSplitShapeCallback", woodCrusher)
532 g_treePlantManager:removingSplitShape(id)
533 if minY ~= nil then
534 woodCrusher.moveTriggerNodes[id] = nil
535 end
536 end
537 end
538 end
539 end
540
541 if self.isServer and woodCrusher.moveColNodes ~= nil then
542 for _, moveColNode in pairs(woodCrusher.moveColNodes) do
543 setTranslation(moveColNode.node, moveColNode.transX, moveColNode.transY + math.random() * 0.005, moveColNode.transZ)
544 end
545 end
546 end
547 end
548
549 if woodCrusher.crushingTime > 0 then
550 woodCrusher.crushingTime = math.max(woodCrusher.crushingTime - dt, 0)
551 end
552
553 local isCrushing = woodCrusher.crushingTime > 0
554
555 if self.isClient then
556 if isCrushing then
557 g_effectManager:setFillType(woodCrusher.crushEffects, FillType.WOODCHIPS)
558 g_effectManager:startEffects(woodCrusher.crushEffects)
559 else
560 g_effectManager:stopEffects(woodCrusher.crushEffects)
561 end
562
563 if isTurnedOn and isCrushing then
564 if not woodCrusher.isWorkSamplePlaying then
565 g_soundManager:playSample(woodCrusher.samples.work)
566 woodCrusher.isWorkSamplePlaying = true
567 end
568 else
569 if woodCrusher.isWorkSamplePlaying then
570 g_soundManager:stopSample(woodCrusher.samples.work)
571 woodCrusher.isWorkSamplePlaying = false
572 end
573 end
574 end
575end

updateWoodCrusher

Description
Update wood crusher
Definition
updateWoodCrusher(float dt)
Arguments
floatdttime since last call in ms
Code
449function WoodCrusher.updateWoodCrusher(self, woodCrusher, dt, isTurnedOn)
450 if isTurnedOn then
451 if self.isServer then
452 for node in pairs(woodCrusher.crushNodes) do
453 WoodCrusher.crushSplitShape(self, woodCrusher, node)
454 woodCrusher.crushNodes[node] = nil
455 woodCrusher.moveTriggerNodes[node] = nil
456 end
457
458 local maxTreeSizeY = 0
459 for id in pairs(woodCrusher.moveTriggerNodes) do
460 if not entityExists(id) then
461 woodCrusher.moveTriggerNodes[id] = nil
462 else
463 for i=1, #woodCrusher.downForceNodes do
464 local downForceNode = woodCrusher.downForceNodes[i]
465 if downForceNode.triggerNodes[id] ~= nil or downForceNode.trigger == nil then
466 local x, y, z = getWorldTranslation(downForceNode.node)
467 local nx, ny, nz = localDirectionToWorld(downForceNode.node, 1,0,0)
468 local yx, yy, yz = localDirectionToWorld(downForceNode.node, 0,1,0)
469
470 local minY,maxY, minZ,maxZ = testSplitShape(id, x,y,z, nx,ny,nz, yx,yy,yz, downForceNode.sizeY, downForceNode.sizeZ)
471 if minY ~= nil then
472 local cx,cy,cz = localToWorld(downForceNode.node, 0, (minY+maxY)*0.5, (minZ+maxZ)*0.5)
473 local downX,downY,downZ = localDirectionToWorld(downForceNode.node, 0, -downForceNode.force, 0)
474 addForce(id, downX, downY, downZ, cx,cy,cz, false)
475 --#debug drawDebugLine(cx, cy, cz, 1, 0, 0, cx+downX, cy+downY, cz+downZ, 0, 1, 0, true)
476 end
477 end
478 end
479
480 if woodCrusher.shapeSizeDetectionNode ~= nil then
481 local x, y, z = getWorldTranslation(woodCrusher.shapeSizeDetectionNode)
482 local nx, ny, nz = localDirectionToWorld(woodCrusher.shapeSizeDetectionNode, 1,0,0)
483 local yx, yy, yz = localDirectionToWorld(woodCrusher.shapeSizeDetectionNode, 0,1,0)
484
485 local minY, maxY, _, _ = testSplitShape(id, x, y, z, nx, ny, nz, yx, yy, yz, woodCrusher.cutSizeY, woodCrusher.cutSizeZ)
486 if minY ~= nil then
487 if woodCrusher.mainDrumRefNode ~= nil then
488 maxTreeSizeY = math.max(maxTreeSizeY, maxY)
489 end
490 end
491 end
492 end
493 end
494 if woodCrusher.mainDrumRefNode ~= nil then
495 local x, y, z = getTranslation(woodCrusher.mainDrumRefNode)
496 local ty = math.min(maxTreeSizeY, woodCrusher.mainDrumRefNodeMaxY)
497 if ty > y then
498 y = math.min(y + 0.0003*dt, ty)
499 else
500 y = math.max(y - 0.0003*dt, ty)
501 end
502
503 setTranslation(woodCrusher.mainDrumRefNode, x, y, z)
504 end
505
506 if next(woodCrusher.moveTriggerNodes) ~= nil or woodCrusher.crushingTime > 0 then
507 self:raiseActive()
508 end
509 end
510 end
511end

woodCrusherDownForceTriggerCallback

Description
Trigger callback
Definition
woodCrusherDownForceTriggerCallback(integer triggerId, integer otherActorId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)
Arguments
integertriggerIdid of trigger
integerotherActorIdid of other actor
booleanonEnteron enter
booleanonLeaveon leave
booleanonStayon stay
integerotherShapeIdid of other shape
Code
693function WoodCrusher.woodCrusherDownForceTriggerCallback(self, triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId)
694 local vehicle = g_currentMission.nodeToObject[otherActorId]
695 if vehicle == nil and getRigidBodyType(otherActorId) == RigidBodyType.DYNAMIC then
696 local splitType = g_splitTypeManager:getSplitTypeByIndex(getSplitType(otherActorId))
697 if splitType ~= nil and splitType.woodChipsPerLiter > 0 then
698 for i=1, #self.downForceNodes do
699 local downForceNode = self.downForceNodes[i]
700 if downForceNode.trigger == triggerId then
701 if onEnter then
702 downForceNode.triggerNodes[otherActorId] = Utils.getNoNil(downForceNode.triggerNodes[otherActorId], 0) + 1
703 self.vehicle:raiseActive()
704 elseif onLeave then
705 local c = downForceNode.triggerNodes[otherActorId]
706 if c ~= nil then
707 c = c-1
708 if c == 0 then
709 downForceNode.triggerNodes[otherActorId] = nil
710 else
711 downForceNode.triggerNodes[otherActorId] = c
712 end
713 end
714 end
715 end
716 end
717 end
718 end
719end

woodCrusherMoveTriggerCallback

Description
Trigger callback
Definition
woodCrusherMoveTriggerCallback(integer triggerId, integer otherActorId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)
Arguments
integertriggerIdid of trigger
integerotherActorIdid of other actor
booleanonEnteron enter
booleanonLeaveon leave
booleanonStayon stay
integerotherShapeIdid of other shape
Code
662function WoodCrusher.woodCrusherMoveTriggerCallback(self, triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId)
663 local vehicle = g_currentMission.nodeToObject[otherActorId]
664 if vehicle == nil and getRigidBodyType(otherActorId) == RigidBodyType.DYNAMIC then
665 local splitType = g_splitTypeManager:getSplitTypeByIndex(getSplitType(otherActorId))
666 if splitType ~= nil and splitType.woodChipsPerLiter > 0 then
667 if onEnter then
668 self.moveTriggerNodes[otherActorId] = Utils.getNoNil(self.moveTriggerNodes[otherActorId],0)+1
669 self.vehicle:raiseActive()
670 elseif onLeave then
671 local c = self.moveTriggerNodes[otherActorId]
672 if c ~= nil then
673 c = c-1
674 if c == 0 then
675 self.moveTriggerNodes[otherActorId] = nil
676 else
677 self.moveTriggerNodes[otherActorId] = c
678 end
679 end
680 end
681 end
682 end
683end

woodCrusherSplitShapeCallback

Description
Split shape callback
Definition
woodCrusherSplitShapeCallback(integer shape, boolean isBelow, boolean isAbove, float minY, float maxY, float minZ, float maxZ)
Arguments
integershapeshape
booleanisBelowis below
booleanisAboveis above
floatminYmin y split position
floatmaxYmax y split position
floatminZmin z split position
floatmaxZmax z split position
Code
647function WoodCrusher.woodCrusherSplitShapeCallback(self, shape, isBelow, isAbove, minY, maxY, minZ, maxZ)
648 if not isBelow then
649 self.crushNodes[shape] = shape
650 g_treePlantManager:addingSplitShape(shape, self.shapeBeingCut)
651 end
652end