LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

PowerTakeOffs

Description
Specialization for vehicles with power takeoffs (PTOs), both output (e.g. tractor) and input (e.g. tool) ones
Functions

attachPowerTakeOff

Description
Definition
attachPowerTakeOff()
Code
483function PowerTakeOffs:attachPowerTakeOff(attachableObject, inputJointDescIndex, jointDescIndex)
484 local spec = self.spec_powerTakeOffs
485 local outputs = self:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex)
486
487 for _, output in ipairs(outputs) do
488 if attachableObject.getInputPowerTakeOffsByJointDescIndexAndName ~= nil then
489 local inputs = attachableObject:getInputPowerTakeOffsByJointDescIndexAndName(inputJointDescIndex, output.ptoName)
490 for _, input in ipairs(inputs) do
491 output.connectedInput = input
492 output.connectedVehicle = attachableObject
493 input.connectedVehicle = self
494 input.connectedOutput = output
495
496 table.insert(spec.delayedPowerTakeOffsMountings, {jointDescIndex=jointDescIndex, input=input, output=output})
497 end
498 end
499 end
500
501 return true
502end

attachTypedPowerTakeOff

Description
Definition
attachTypedPowerTakeOff()
Code
787function PowerTakeOffs:attachTypedPowerTakeOff(powerTakeOff, output)
788 if self:validatePowerTakeOffAttachment(powerTakeOff, output) then
789 link(output.outputNode, powerTakeOff.linkNode)
790 link(powerTakeOff.inputNode, powerTakeOff.startNode)
791
792 setTranslation(powerTakeOff.linkNode, 0, 0, powerTakeOff.zOffset)
793 setTranslation(powerTakeOff.startNode, 0, 0, -powerTakeOff.zOffset)
794
795 self:updatePowerTakeOff(powerTakeOff, 0)
796 self:updatePowerTakeOffLength(powerTakeOff)
797 end
798end

detachPowerTakeOff

Description
Definition
detachPowerTakeOff()
Code
506function PowerTakeOffs:detachPowerTakeOff(detachingVehicle, implement)
507 local spec = self.spec_powerTakeOffs
508 -- clear delayed mountings
509 spec.delayedPowerTakeOffsMountings = {}
510
511 local outputs = detachingVehicle:getOutputPowerTakeOffsByJointDescIndex(implement.jointDescIndex)
512
513 for _, output in ipairs(outputs) do
514 if output.connectedInput ~= nil then
515 local input = output.connectedInput
516
517 if input.detachFunc ~= nil then
518 input.detachFunc(self, input, output)
519 end
520
521 input.connectedVehicle = nil
522 input.connectedOutput = nil
523 output.connectedVehicle = nil
524 output.connectedInput = nil
525
526 ObjectChangeUtil.setObjectChanges(input.objectChanges, false)
527 ObjectChangeUtil.setObjectChanges(output.objectChanges, false)
528 end
529 end
530
531 return true
532end

detachTypedPowerTakeOff

Description
Definition
detachTypedPowerTakeOff()
Code
802function PowerTakeOffs:detachTypedPowerTakeOff(powerTakeOff, output)
803 self:parkPowerTakeOff(powerTakeOff)
804end

getInputPowerTakeOffs

Description
Definition
getInputPowerTakeOffs()
Code
471function PowerTakeOffs:getInputPowerTakeOffs()
472 return self.spec_powerTakeOffs.inputPowerTakeOffs
473end

getInputPowerTakeOffsByJointDescIndexAndName

Description
Definition
getInputPowerTakeOffsByJointDescIndexAndName()
Code
441function PowerTakeOffs:getInputPowerTakeOffsByJointDescIndexAndName(jointDescIndex, ptoName)
442 local retInputs = {}
443
444 local spec = self.spec_powerTakeOffs
445 for _, input in pairs(spec.inputPowerTakeOffs) do
446 if input.inputAttacherJointIndices[jointDescIndex] ~= nil then
447 if input.ptoName == ptoName then
448 table.insert(retInputs, input)
449 end
450 end
451 end
452
453 if table.getn(retInputs) == 0 then
454 for _, output in pairs(spec.outputPowerTakeOffs) do
455 if output.skipToInputAttacherIndex == jointDescIndex then
456 for index, _ in pairs(output.attacherJointIndices) do
457 local implement = self:getImplementFromAttacherJointIndex(index)
458 if implement ~= nil then
459 retInputs = implement.object:getInputPowerTakeOffsByJointDescIndexAndName(implement.inputJointDescIndex, ptoName)
460 end
461 end
462 end
463 end
464 end
465
466 return retInputs
467end

getIsPowerTakeOffActive

Description
Definition
getIsPowerTakeOffActive()
Code
477function PowerTakeOffs:getIsPowerTakeOffActive()
478 return false
479end

getOutputPowerTakeOffs

Description
Definition
getOutputPowerTakeOffs()
Code
435function PowerTakeOffs:getOutputPowerTakeOffs()
436 return self.spec_powerTakeOffs.outputPowerTakeOffs
437end

getOutputPowerTakeOffsByJointDescIndex

Description
Definition
getOutputPowerTakeOffsByJointDescIndex()
Code
407function PowerTakeOffs:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex)
408 local retOutputs = {}
409
410 local spec = self.spec_powerTakeOffs
411 for _, output in pairs(spec.outputPowerTakeOffs) do
412 if output.attacherJointIndices[jointDescIndex] ~= nil then
413 table.insert(retOutputs, output)
414 end
415 end
416
417 if table.getn(retOutputs) > 0 then
418 for _, output in ipairs(retOutputs) do
419 if output.skipToInputAttacherIndex ~= nil then
420 local secondAttacherVehicle = self:getAttacherVehicle()
421 if secondAttacherVehicle ~= nil then
422 local ownImplement = secondAttacherVehicle:getImplementByObject(self)
423 retOutputs = secondAttacherVehicle:getOutputPowerTakeOffsByJointDescIndex(ownImplement.jointDescIndex)
424 break
425 end
426 end
427 end
428 end
429
430 return retOutputs
431end

initSpecialization

Description
Definition
initSpecialization()
Code
77function PowerTakeOffs.initSpecialization()
78 g_configurationManager:addConfigurationType("powerTakeOff", g_i18n:getText("configuration_powerTakeOff"), "powerTakeOffs", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
79end

loadBasicPowerTakeOff

Description
Definition
loadBasicPowerTakeOff()
Code
755function PowerTakeOffs:loadBasicPowerTakeOff(powerTakeOff, xmlFile, rootNode)
756 powerTakeOff.startNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.startNode#node"))
757 powerTakeOff.linkNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.linkNode#node"))
758
759 powerTakeOff.attachFunc = PowerTakeOffs.attachTypedPowerTakeOff
760 powerTakeOff.detachFunc = PowerTakeOffs.detachTypedPowerTakeOff
761end

loadDoubleJointPowerTakeOff

Description
Definition
loadDoubleJointPowerTakeOff()
Code
693function PowerTakeOffs:loadDoubleJointPowerTakeOff(powerTakeOff, xmlFile, rootNode)
694 powerTakeOff.startJoint1 = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.startJoint1#node"))
695 powerTakeOff.startJoint2 = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.startJoint2#node"))
696
697 powerTakeOff.scalePart = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.scalePart#node"))
698 powerTakeOff.scalePartRef = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.scalePart#referenceNode"))
699 local _, _, dis = localToLocal(powerTakeOff.scalePartRef, powerTakeOff.scalePart, 0, 0, 0)
700 powerTakeOff.scalePartBaseDistance = dis
701
702 powerTakeOff.translationPart = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.translationPart#node"))
703 powerTakeOff.translationPartRef = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.translationPart#referenceNode"))
704 powerTakeOff.translationPartLength = getXMLFloat(xmlFile, "powerTakeOff.translationPart#length") or 0.4
705
706 powerTakeOff.decal = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.translationPart.decal#node"))
707 powerTakeOff.decalSize = getXMLFloat(xmlFile, "powerTakeOff.translationPart.decal#size") or 0.1
708 powerTakeOff.decalOffset = getXMLFloat(xmlFile, "powerTakeOff.translationPart.decal#offset") or 0.05
709 powerTakeOff.decalMinOffset = getXMLFloat(xmlFile, "powerTakeOff.translationPart.decal#minOffset") or 0.01
710
711 powerTakeOff.endJoint1 = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.endJoint1#node"))
712 powerTakeOff.endJoint1Ref = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.endJoint1#referenceNode"))
713
714 powerTakeOff.endJoint2 = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.endJoint2#node"))
715 powerTakeOff.linkNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.linkNode#node"))
716
717 local _, _, betweenLength = localToLocal(powerTakeOff.translationPart, powerTakeOff.translationPartRef, 0, 0, 0)
718 local _, _, ptoLength = localToLocal(powerTakeOff.startNode, powerTakeOff.linkNode, 0, 0, 0)
719 powerTakeOff.betweenLength = math.abs(betweenLength)
720 powerTakeOff.connectorLength = math.abs(ptoLength) - math.abs(betweenLength)
721
722 setTranslation(powerTakeOff.linkNode, 0, 0, 0)
723 setRotation(powerTakeOff.linkNode, 0, 0, 0)
724
725 powerTakeOff.updateFunc = PowerTakeOffs.updateDoubleJointPowerTakeOff
726 powerTakeOff.updateDistanceFunc = PowerTakeOffs.updateDistanceOfTypedPowerTakeOff
727 powerTakeOff.attachFunc = PowerTakeOffs.attachTypedPowerTakeOff
728 powerTakeOff.detachFunc = PowerTakeOffs.detachTypedPowerTakeOff
729end

loadExtraDependentParts

Description
Definition
loadExtraDependentParts()
Code
832function PowerTakeOffs:loadExtraDependentParts(superFunc, xmlFile, baseName, entry)
833 if not superFunc(self, xmlFile, baseName, entry) then
834 return false
835 end
836
837 local indices = StringUtil.getVectorNFromString(getXMLString(xmlFile, baseName.. ".powerTakeOffs#indices"))
838 if indices ~= nil then
839 entry.powerTakeOffs = {}
840
841 for i=1, table.getn(indices) do
842 table.insert(entry.powerTakeOffs, indices[i])
843 end
844 end
845
846 local localIndices = StringUtil.getVectorNFromString(getXMLString(xmlFile, baseName.. ".powerTakeOffs#localIndices"))
847 if localIndices ~= nil then
848 entry.localPowerTakeOffs = {}
849
850 for i=1, table.getn(localIndices) do
851 table.insert(entry.localPowerTakeOffs, localIndices[i])
852 end
853 end
854
855 return true
856end

loadInputPowerTakeOff

Description
Definition
loadInputPowerTakeOff()
Code
278function PowerTakeOffs:loadInputPowerTakeOff(xmlFile, baseName, entry)
279 local inputNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseName.."#inputNode"), self.i3dMappings)
280 if inputNode == nil then
281 g_logManager:xmlWarning(self.configFileName, "Pto input needs to have a valid 'inputNode' in '%s'", baseName)
282 return false
283 end
284
285 local inputAttacherJointIndices = {}
286 local inputAttacherJointIndicesStr = getXMLString(xmlFile, baseName .. "#inputAttacherJointIndices")
287
288 if inputAttacherJointIndicesStr == nil then
289 g_logManager:xmlWarning(self.configFileName, "Pto output needs to have valid 'inputAttacherJointIndices' in '%s'", baseName)
290 return false
291 else
292 local indices = {StringUtil.getVectorFromString(inputAttacherJointIndicesStr)}
293 for _, index in ipairs(indices) do
294 if self:getInputAttacherJointByJointDescIndex(index) == nil then
295 g_logManager:xmlWarning(self.configFileName, "The given inputAttacherJointIndex '%d' for '%s' can't be resolved into a valid inputAttacherJoint", index, baseName)
296 return false
297 else
298 inputAttacherJointIndices[index] = true
299 end
300 end
301 end
302
303 entry.inputNode = inputNode
304 entry.detachNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseName.."#detachNode"), self.i3dMappings)
305 entry.inputAttacherJointIndices = inputAttacherJointIndices
306
307 entry.aboveAttacher = Utils.getNoNil(getXMLBool(xmlFile, baseName.."#aboveAttacher"), true)
308
309 entry.color = ConfigurationUtil.getColorFromString(getXMLString(xmlFile, baseName .. "#color"))
310
311 local filename = Utils.getNoNil(getXMLString(xmlFile, baseName.. "#filename"), "$data/shared/assets/powerTakeOffs/walterscheidW.xml")
312 if filename ~= nil then
313 self:loadPowerTakeOffFromConfigFile(entry, filename)
314
315 if self.addAllSubWashableNodes ~= nil and entry.startNode ~= nil then
316 self:addAllSubWashableNodes(entry.startNode)
317 end
318 end
319
320 entry.ptoName = getXMLString(self.xmlFile, baseName .. "#ptoName") or "DEFAULT_PTO"
321
322 entry.objectChanges = {}
323 ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, baseName, entry.objectChanges, self.components, self)
324 ObjectChangeUtil.setObjectChanges(entry.objectChanges, false)
325
326 return true
327end

loadLocalPowerTakeOff

Description
Definition
loadLocalPowerTakeOff()
Code
331function PowerTakeOffs:loadLocalPowerTakeOff(xmlFile, baseName, entry)
332 entry.inputNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseName.."#startNode"), self.i3dMappings)
333 if entry.inputNode == nil then
334 g_logManager:xmlWarning(self.configFileName, "Missing startNode for local power take off '%s'", baseName)
335 return false
336 end
337
338 entry.endNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseName.."#endNode"), self.i3dMappings)
339 if entry.endNode == nil then
340 g_logManager:xmlWarning(self.configFileName, "Missing endNode for local power take off '%s'", baseName)
341 return false
342 end
343
344 entry.color = ConfigurationUtil.getColorFromString(getXMLString(xmlFile, baseName .. "#color"))
345
346 local filename = Utils.getNoNil(getXMLString(xmlFile, baseName.. "#filename"), "$data/shared/assets/powerTakeOffs/walterscheidW.xml")
347 if filename ~= nil then
348 self:loadPowerTakeOffFromConfigFile(entry, filename)
349
350 if self.addAllSubWashableNodes ~= nil and entry.startNode ~= nil then
351 self:addAllSubWashableNodes(entry.startNode)
352 end
353 end
354
355 return true
356end

loadOutputPowerTakeOff

Description
Definition
loadOutputPowerTakeOff()
Code
233function PowerTakeOffs:loadOutputPowerTakeOff(xmlFile, baseName, entry)
234 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, baseName .. "#linkNode", baseName .."#outputNode") -- FS19 to FS19
235 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, baseName .. "#filename", "pto file is now defined in the pto input node") -- FS19 to FS19
236
237 entry.skipToInputAttacherIndex = getXMLInt(xmlFile, baseName.. "#skipToInputAttacherIndex")
238
239 local outputNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseName.. "#outputNode"), self.i3dMappings)
240 if outputNode == nil and entry.skipToInputAttacherIndex == nil then
241 g_logManager:xmlWarning(self.configFileName, "Pto output needs to have either a valid 'outputNode' or a 'skipToInputAttacherIndex' in '%s'", baseName)
242 return false
243 end
244
245 local attacherJointIndices = {}
246 local attacherJointIndicesStr = getXMLString(xmlFile, baseName .. "#attacherJointIndices")
247
248 if attacherJointIndicesStr == nil then
249 g_logManager:xmlWarning(self.configFileName, "Pto output needs to have valid 'attacherJointIndices' in '%s'", baseName)
250 return false
251 else
252 local indices = {StringUtil.getVectorFromString(attacherJointIndicesStr)}
253 for _, index in ipairs(indices) do
254 if self:getAttacherJointByJointDescIndex(index) == nil then
255 g_logManager:xmlWarning(self.configFileName, "The given attacherJointIndex '%d' for '%s' can't be resolved into a valid attacherJoint", index, baseName)
256 return false
257 else
258 attacherJointIndices[index] = true
259 end
260 end
261 end
262
263 entry.outputNode = outputNode
264 entry.attacherJointIndices = attacherJointIndices
265 entry.connectedInput = nil
266
267 entry.ptoName = getXMLString(self.xmlFile, baseName .. "#ptoName") or "DEFAULT_PTO"
268
269 entry.objectChanges = {}
270 ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, baseName, entry.objectChanges, self.components, self)
271 ObjectChangeUtil.setObjectChanges(entry.objectChanges, false)
272
273 return true
274end

loadPowerTakeOffFromConfigFile

Description
Definition
loadPowerTakeOffFromConfigFile()
Code
584function PowerTakeOffs:loadPowerTakeOffFromConfigFile(powerTakeOff, xmlFilename)
585 xmlFilename = Utils.getFilename(xmlFilename, self.baseDirectory)
586 local xmlFile = loadXMLFile("TempConfig", xmlFilename)
587 if xmlFile ~= nil then
588 local filename = getXMLString(xmlFile, "powerTakeOff#filename")
589 if filename ~= nil then
590 powerTakeOff.filename = filename
591 local i3dNode = g_i3DManager:loadSharedI3DFile(filename, self.baseDirectory, false, false, false)
592 if i3dNode ~= 0 then
593 powerTakeOff.startNode = I3DUtil.indexToObject(i3dNode, getXMLString(xmlFile, "powerTakeOff.startNode#node"))
594 powerTakeOff.size = Utils.getNoNil(getXMLFloat(xmlFile, "powerTakeOff#size"), 0.19)
595 powerTakeOff.minLength = Utils.getNoNil(getXMLFloat(xmlFile, "powerTakeOff#minLength"), 0.6)
596 powerTakeOff.maxAngle = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, "powerTakeOff#maxAngle"), 45))
597 powerTakeOff.zOffset = getXMLFloat(xmlFile, "powerTakeOff#zOffset") or 0
598
599 powerTakeOff.animationNodes = g_animationManager:loadAnimations(xmlFile, "powerTakeOff.animationNodes", i3dNode, self)
600
601 if getXMLBool(xmlFile, "powerTakeOff#isSingleJoint") then
602 self:loadSingleJointPowerTakeOff(powerTakeOff, xmlFile, i3dNode)
603 elseif getXMLBool(xmlFile, "powerTakeOff#isDoubleJoint") then
604 self:loadDoubleJointPowerTakeOff(powerTakeOff, xmlFile, i3dNode)
605 else
606 self:loadBasicPowerTakeOff(powerTakeOff, xmlFile, i3dNode)
607 end
608
609 if powerTakeOff.color ~= nil and #powerTakeOff.color >= 3 then
610 local colorShaderParameter = getXMLString(xmlFile, "powerTakeOff#colorShaderParameter")
611 if colorShaderParameter ~= nil then
612 local nodes = {}
613 I3DUtil.getNodesByShaderParam(powerTakeOff.startNode, colorShaderParameter, nodes)
614 for _, node in pairs(nodes) do
615 local _, _, _, mat = getShaderParameter(node, colorShaderParameter)
616 setShaderParameter(node, colorShaderParameter, powerTakeOff.color[1], powerTakeOff.color[2], powerTakeOff.color[3], mat, false)
617 end
618 end
619 end
620
621 link(powerTakeOff.inputNode, powerTakeOff.startNode)
622 delete(i3dNode)
623 else
624 g_logManager:xmlWarning(self.configFileName, "Failed to find powerTakeOff in i3d file '%s'", filename, xmlFilename)
625 return false
626 end
627 else
628 g_logManager:xmlWarning(self.configFileName, "Failed to open powerTakeOff i3d file '%s' in '%s'", filename, xmlFilename)
629 return false
630 end
631
632 delete(xmlFile)
633 return true
634 end
635
636 g_logManager:xmlWarning(self.configFileName, "Failed to open powerTakeOff config file '%s'", xmlFilename)
637 return false
638end

loadSingleJointPowerTakeOff

Description
Definition
loadSingleJointPowerTakeOff()
Code
642function PowerTakeOffs:loadSingleJointPowerTakeOff(powerTakeOff, xmlFile, rootNode)
643 powerTakeOff.startJoint = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.startJoint#node"))
644
645 powerTakeOff.scalePart = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.scalePart#node"))
646 powerTakeOff.scalePartRef = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.scalePart#referenceNode"))
647 local _, _, dis = localToLocal(powerTakeOff.scalePartRef, powerTakeOff.scalePart, 0, 0, 0)
648 powerTakeOff.scalePartBaseDistance = dis
649
650 powerTakeOff.translationPart = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.translationPart#node"))
651 powerTakeOff.translationPartRef = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.translationPart#referenceNode"))
652 powerTakeOff.translationPartLength = getXMLFloat(xmlFile, "powerTakeOff.translationPart#length") or 0.4
653
654 powerTakeOff.decal = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.translationPart.decal#node"))
655 powerTakeOff.decalSize = getXMLFloat(xmlFile, "powerTakeOff.translationPart.decal#size") or 0.1
656 powerTakeOff.decalOffset = getXMLFloat(xmlFile, "powerTakeOff.translationPart.decal#offset") or 0.05
657 powerTakeOff.decalMinOffset = getXMLFloat(xmlFile, "powerTakeOff.translationPart.decal#minOffset") or 0.01
658
659 powerTakeOff.endJoint = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.endJoint#node"))
660 powerTakeOff.linkNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "powerTakeOff.linkNode#node"))
661
662 local _, _, betweenLength = localToLocal(powerTakeOff.translationPart, powerTakeOff.translationPartRef, 0, 0, 0)
663 local _, _, ptoLength = localToLocal(powerTakeOff.startNode, powerTakeOff.linkNode, 0, 0, 0)
664 powerTakeOff.betweenLength = math.abs(betweenLength)
665 powerTakeOff.connectorLength = math.abs(ptoLength) - math.abs(betweenLength)
666
667 setTranslation(powerTakeOff.linkNode, 0, 0, 0)
668 setRotation(powerTakeOff.linkNode, 0, 0, 0)
669
670 powerTakeOff.updateFunc = PowerTakeOffs.updateSingleJointPowerTakeOff
671 powerTakeOff.updateDistanceFunc = PowerTakeOffs.updateDistanceOfTypedPowerTakeOff
672 powerTakeOff.attachFunc = PowerTakeOffs.attachTypedPowerTakeOff
673 powerTakeOff.detachFunc = PowerTakeOffs.detachTypedPowerTakeOff
674end

onDelete

Description
Definition
onDelete()
Code
167function PowerTakeOffs:onDelete()
168 local spec = self.spec_powerTakeOffs
169 for _,output in pairs(spec.outputPowerTakeOffs) do
170 if output.rootNode ~= nil then
171 delete(output.rootNode)
172 delete(output.attachNode)
173 end
174 end
175 for _,input in pairs(spec.inputPowerTakeOffs) do
176 if input.rootNode ~= nil then
177 delete(input.rootNode)
178 delete(input.attachNode)
179 end
180 g_animationManager:deleteAnimations(input.animationNodes)
181 end
182 for _,localPto in pairs(spec.localPowerTakeOffs) do
183 g_animationManager:deleteAnimations(localPto.animationNodes)
184 end
185end

onLoad

Description
Definition
onLoad()
Code
83function PowerTakeOffs:onLoad(savegame)
84 local spec = self.spec_powerTakeOffs
85 spec.outputPowerTakeOffs = {}
86 spec.inputPowerTakeOffs = {}
87 spec.localPowerTakeOffs = {}
88
89 spec.delayedPowerTakeOffsMountings = {}
90end

onLoadFinished

Description
Definition
onLoadFinished()
Code
157function PowerTakeOffs:onLoadFinished(savegame)
158 local spec = self.spec_powerTakeOffs
159
160 for _, powerTakeOff in ipairs(spec.localPowerTakeOffs) do
161 self:placeLocalPowerTakeOff(powerTakeOff)
162 end
163end

onPostAttachImplement

Description
Definition
onPostAttachImplement()
Code
556function PowerTakeOffs:onPostAttachImplement(attachableObject, inputJointDescIndex, jointDescIndex)
557 local spec = self.spec_powerTakeOffs
558 for i=#spec.delayedPowerTakeOffsMountings, 1, -1 do
559 local delayedMounting = spec.delayedPowerTakeOffsMountings[i]
560 if delayedMounting.jointDescIndex == jointDescIndex then
561 local input = delayedMounting.input
562 local output = delayedMounting.output
563
564 if input.attachFunc ~= nil then
565 input.attachFunc(self, input, output)
566 end
567
568 ObjectChangeUtil.setObjectChanges(input.objectChanges, true)
569 ObjectChangeUtil.setObjectChanges(output.objectChanges, true)
570
571 table.remove(spec.delayedPowerTakeOffsMountings, i)
572 end
573 end
574end

onPostLoad

Description
Definition
onPostLoad()
Code
94function PowerTakeOffs:onPostLoad(savegame)
95 local spec = self.spec_powerTakeOffs
96
97 local ptoConfigurationId = Utils.getNoNil(self.configurations["powerTakeOff"], 1)
98 local configKey = string.format("vehicle.powerTakeOffs.powerTakeOffConfigurations.powerTakeOffConfiguration(%d)", ptoConfigurationId -1)
99 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.powerTakeOffs.powerTakeOffConfigurations.powerTakeOffConfiguration", ptoConfigurationId , self.components, self)
100
101 -- fallback key
102 if not hasXMLProperty(self.xmlFile, configKey) then
103 configKey = "vehicle.powerTakeOffs"
104 end
105
106 if SpecializationUtil.hasSpecialization(AttacherJoints, self.specializations) then
107 local i = 0
108 while true do
109 local baseName = string.format("%s.output(%d)", configKey, i)
110 if not hasXMLProperty(self.xmlFile, baseName) then
111 break
112 end
113
114 local entry = {}
115 if self:loadOutputPowerTakeOff(self.xmlFile, baseName, entry) then
116 table.insert(spec.outputPowerTakeOffs, entry)
117 end
118 i = i + 1
119 end
120 end
121
122 if SpecializationUtil.hasSpecialization(Attachable, self.specializations) then
123 local i = 0
124 while true do
125 local baseName = string.format("%s.input(%d)", configKey, i)
126 if not hasXMLProperty(self.xmlFile, baseName) then
127 break
128 end
129
130 local entry = {}
131 if self:loadInputPowerTakeOff(self.xmlFile, baseName, entry) then
132 table.insert(spec.inputPowerTakeOffs, entry)
133
134 self:parkPowerTakeOff(entry)
135 end
136 i = i + 1
137 end
138 end
139
140 local i = 0
141 while true do
142 local baseName = string.format("%s.local(%d)", configKey, i)
143 if not hasXMLProperty(self.xmlFile, baseName) then
144 break
145 end
146
147 local entry = {}
148 if self:loadLocalPowerTakeOff(self.xmlFile, baseName, entry) then
149 table.insert(spec.localPowerTakeOffs, entry)
150 end
151 i = i + 1
152 end
153end

onPreAttachImplement

Description
Definition
onPreAttachImplement()
Code
550function PowerTakeOffs:onPreAttachImplement(attachableObject, inputJointDescIndex, jointDescIndex)
551 self:attachPowerTakeOff(attachableObject, inputJointDescIndex, jointDescIndex)
552end

onPreDetachImplement

Description
Definition
onPreDetachImplement()
Code
578function PowerTakeOffs:onPreDetachImplement(implement)
579 self:detachPowerTakeOff(self, implement)
580end

onUpdateInterpolation

Description
Definition
onUpdateInterpolation()
Code
189function PowerTakeOffs:onUpdateInterpolation(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
190 if self.isClient then
191 local spec = self.spec_powerTakeOffs
192 for _, input in pairs(spec.inputPowerTakeOffs) do
193 if input.connectedVehicle ~= nil then
194 if self.updateLoopIndex == input.connectedVehicle.updateLoopIndex then
195 self:updatePowerTakeOff(input, dt)
196 end
197 end
198 end
199
200 if self.getAttachedImplements ~= nil then
201 for _, implement in ipairs(self:getAttachedImplements()) do
202 if implement.object.updateAttachedPowerTakeOffs ~= nil then
203 implement.object:updateAttachedPowerTakeOffs(dt, self)
204 end
205 end
206 end
207
208 local isPowerTakeOffActive = self:getIsPowerTakeOffActive()
209 if spec.lastIsPowerTakeOffActive ~= isPowerTakeOffActive then
210 for _, input in pairs(spec.inputPowerTakeOffs) do
211 if isPowerTakeOffActive then
212 g_animationManager:startAnimations(input.animationNodes)
213 else
214 g_animationManager:stopAnimations(input.animationNodes)
215 end
216 end
217
218 for _, localPto in pairs(spec.localPowerTakeOffs) do
219 if isPowerTakeOffActive then
220 g_animationManager:startAnimations(localPto.animationNodes)
221 else
222 g_animationManager:stopAnimations(localPto.animationNodes)
223 end
224 end
225
226 spec.lastIsPowerTakeOffActive = isPowerTakeOffActive
227 end
228 end
229end

parkPowerTakeOff

Description
Definition
parkPowerTakeOff()
Code
536function PowerTakeOffs:parkPowerTakeOff(input)
537 if input.detachNode ~= nil then
538 link(input.detachNode, input.linkNode)
539 link(input.inputNode, input.startNode)
540 self:updatePowerTakeOff(input, 0)
541 self:updatePowerTakeOffLength(input)
542 else
543 unlink(input.linkNode)
544 unlink(input.startNode)
545 end
546end

placeLocalPowerTakeOff

Description
Definition
placeLocalPowerTakeOff()
Code
360function PowerTakeOffs:placeLocalPowerTakeOff(powerTakeOff)
361 if not powerTakeOff.isPlaced then
362 link(powerTakeOff.endNode, powerTakeOff.linkNode)
363
364 setTranslation(powerTakeOff.linkNode, 0, 0, powerTakeOff.zOffset)
365 setTranslation(powerTakeOff.startNode, 0, 0, -powerTakeOff.zOffset)
366
367 self:updatePowerTakeOffLength(powerTakeOff)
368 powerTakeOff.isPlaced = true
369 end
370
371 self:updatePowerTakeOff(powerTakeOff, 0)
372end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
15function PowerTakeOffs.prerequisitesPresent(specializations)
16 return SpecializationUtil.hasSpecialization(AttacherJoints, specializations)
17 or SpecializationUtil.hasSpecialization(Attachable, specializations)
18end

registerEventListeners

Description
Definition
registerEventListeners()
Code
64function PowerTakeOffs.registerEventListeners(vehicleType)
65 SpecializationUtil.registerEventListener(vehicleType, "onLoad", PowerTakeOffs)
66 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", PowerTakeOffs)
67 SpecializationUtil.registerEventListener(vehicleType, "onLoadFinished", PowerTakeOffs)
68 SpecializationUtil.registerEventListener(vehicleType, "onDelete", PowerTakeOffs)
69 SpecializationUtil.registerEventListener(vehicleType, "onUpdateInterpolation", PowerTakeOffs)
70 SpecializationUtil.registerEventListener(vehicleType, "onPreAttachImplement", PowerTakeOffs)
71 SpecializationUtil.registerEventListener(vehicleType, "onPostAttachImplement", PowerTakeOffs)
72 SpecializationUtil.registerEventListener(vehicleType, "onPreDetachImplement", PowerTakeOffs)
73end

registerFunctions

Description
Definition
registerFunctions()
Code
22function PowerTakeOffs.registerFunctions(vehicleType)
23 SpecializationUtil.registerFunction(vehicleType, "loadOutputPowerTakeOff", PowerTakeOffs.loadOutputPowerTakeOff)
24 SpecializationUtil.registerFunction(vehicleType, "loadInputPowerTakeOff", PowerTakeOffs.loadInputPowerTakeOff)
25 SpecializationUtil.registerFunction(vehicleType, "loadLocalPowerTakeOff", PowerTakeOffs.loadLocalPowerTakeOff)
26 SpecializationUtil.registerFunction(vehicleType, "placeLocalPowerTakeOff", PowerTakeOffs.placeLocalPowerTakeOff)
27 SpecializationUtil.registerFunction(vehicleType, "updatePowerTakeOff", PowerTakeOffs.updatePowerTakeOff)
28 SpecializationUtil.registerFunction(vehicleType, "updateAttachedPowerTakeOffs", PowerTakeOffs.updateAttachedPowerTakeOffs)
29 SpecializationUtil.registerFunction(vehicleType, "updatePowerTakeOffLength", PowerTakeOffs.updatePowerTakeOffLength)
30 SpecializationUtil.registerFunction(vehicleType, "getOutputPowerTakeOffsByJointDescIndex", PowerTakeOffs.getOutputPowerTakeOffsByJointDescIndex)
31 SpecializationUtil.registerFunction(vehicleType, "getOutputPowerTakeOffs", PowerTakeOffs.getOutputPowerTakeOffs)
32 SpecializationUtil.registerFunction(vehicleType, "getInputPowerTakeOffs", PowerTakeOffs.getInputPowerTakeOffs)
33 SpecializationUtil.registerFunction(vehicleType, "getInputPowerTakeOffsByJointDescIndexAndName", PowerTakeOffs.getInputPowerTakeOffsByJointDescIndexAndName)
34 SpecializationUtil.registerFunction(vehicleType, "getIsPowerTakeOffActive", PowerTakeOffs.getIsPowerTakeOffActive)
35 SpecializationUtil.registerFunction(vehicleType, "attachPowerTakeOff", PowerTakeOffs.attachPowerTakeOff)
36 SpecializationUtil.registerFunction(vehicleType, "detachPowerTakeOff", PowerTakeOffs.detachPowerTakeOff)
37 SpecializationUtil.registerFunction(vehicleType, "parkPowerTakeOff", PowerTakeOffs.parkPowerTakeOff)
38
39 SpecializationUtil.registerFunction(vehicleType, "loadPowerTakeOffFromConfigFile", PowerTakeOffs.loadPowerTakeOffFromConfigFile)
40
41 SpecializationUtil.registerFunction(vehicleType, "loadSingleJointPowerTakeOff", PowerTakeOffs.loadSingleJointPowerTakeOff)
42 SpecializationUtil.registerFunction(vehicleType, "updateSingleJointPowerTakeOff", PowerTakeOffs.updateSingleJointPowerTakeOff)
43
44 SpecializationUtil.registerFunction(vehicleType, "loadDoubleJointPowerTakeOff", PowerTakeOffs.loadDoubleJointPowerTakeOff)
45 SpecializationUtil.registerFunction(vehicleType, "updateDoubleJointPowerTakeOff", PowerTakeOffs.updateDoubleJointPowerTakeOff)
46
47 SpecializationUtil.registerFunction(vehicleType, "loadBasicPowerTakeOff", PowerTakeOffs.loadBasicPowerTakeOff)
48
49 SpecializationUtil.registerFunction(vehicleType, "attachTypedPowerTakeOff", PowerTakeOffs.attachTypedPowerTakeOff)
50 SpecializationUtil.registerFunction(vehicleType, "detachTypedPowerTakeOff", PowerTakeOffs.detachTypedPowerTakeOff)
51
52 SpecializationUtil.registerFunction(vehicleType, "validatePowerTakeOffAttachment", PowerTakeOffs.validatePowerTakeOffAttachment)
53end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
57function PowerTakeOffs.registerOverwrittenFunctions(vehicleType)
58 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadExtraDependentParts", PowerTakeOffs.loadExtraDependentParts)
59 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateExtraDependentParts", PowerTakeOffs.updateExtraDependentParts)
60end

updateAttachedPowerTakeOffs

Description
Definition
updateAttachedPowerTakeOffs()
Code
384function PowerTakeOffs:updateAttachedPowerTakeOffs(dt, attacherVehicle)
385 local spec = self.spec_powerTakeOffs
386 for _, input in pairs(spec.inputPowerTakeOffs) do
387 if input.connectedVehicle ~= nil then
388 if input.connectedVehicle == attacherVehicle then
389 if self.updateLoopIndex == input.connectedVehicle.updateLoopIndex then
390 self:updatePowerTakeOff(input, dt)
391 end
392 end
393 end
394 end
395end

updateDistanceOfTypedPowerTakeOff

Description
Definition
updateDistanceOfTypedPowerTakeOff()
Code
765function PowerTakeOffs:updateDistanceOfTypedPowerTakeOff(powerTakeOff)
766 local attachLength = calcDistanceFrom(powerTakeOff.linkNode, powerTakeOff.startNode)
767 local transPartScale = math.max(attachLength - powerTakeOff.connectorLength, 0) / powerTakeOff.betweenLength
768 setScale(powerTakeOff.translationPart, 1, 1, transPartScale)
769
770 if powerTakeOff.decal ~= nil then
771 local transPartLength = transPartScale * powerTakeOff.translationPartLength
772
773 if transPartLength > powerTakeOff.decalMinOffset * 2 + powerTakeOff.decalSize then
774 local offset = math.min((transPartLength - powerTakeOff.decalSize) / 2, powerTakeOff.decalOffset)
775 local decalTranslation = offset + powerTakeOff.decalSize * 0.5
776 local x, y, _ = getTranslation(powerTakeOff.decal)
777 setTranslation(powerTakeOff.decal, x, y, -decalTranslation/transPartScale)
778 setScale(powerTakeOff.decal, 1, 1, 1/transPartScale)
779 else
780 setVisibility(powerTakeOff.decal, false)
781 end
782 end
783end

updateDoubleJointPowerTakeOff

Description
Definition
updateDoubleJointPowerTakeOff()
Code
733function PowerTakeOffs:updateDoubleJointPowerTakeOff(powerTakeOff, dt)
734 local x, y, z = getWorldTranslation(powerTakeOff.startNode)
735 local dx, dy, dz = worldToLocal(getParent(powerTakeOff.endJoint2), x, y, z)
736 I3DUtil.setDirection(powerTakeOff.endJoint2, dx*0.5, dy*0.5, dz, 0, 1, 0)
737
738 x, y, z = getWorldTranslation(powerTakeOff.endJoint1Ref)
739 dx, dy, dz = worldToLocal(getParent(powerTakeOff.startJoint1), x, y, z)
740 I3DUtil.setDirection(powerTakeOff.startJoint1, dx*0.5, dy*0.5, dz, 0, 1, 0)
741
742 x, y, z = getWorldTranslation(powerTakeOff.endJoint1Ref)
743 dx, dy, dz = worldToLocal(getParent(powerTakeOff.startJoint2), x, y, z)
744 I3DUtil.setDirection(powerTakeOff.startJoint2, dx, dy, dz, 0, 1, 0)
745
746 dx, dy, dz = worldToLocal(getParent(powerTakeOff.endJoint1), x, y, z)
747 setTranslation(powerTakeOff.endJoint1, 0, 0, MathUtil.vector3Length(dx, dy, dz))
748
749 local dist = calcDistanceFrom(powerTakeOff.scalePart, powerTakeOff.scalePartRef)
750 setScale(powerTakeOff.scalePart, 1, 1, dist / powerTakeOff.scalePartBaseDistance)
751end

updateExtraDependentParts

Description
Definition
updateExtraDependentParts()
Code
860function PowerTakeOffs:updateExtraDependentParts(superFunc, part, dt)
861 superFunc(self, part, dt)
862
863 if part.powerTakeOffs ~= nil then
864 local spec = self.spec_powerTakeOffs
865 for i, index in ipairs(part.powerTakeOffs) do
866 if spec.inputPowerTakeOffs[index] == nil then
867 part.powerTakeOffs[i] = nil
868 g_logManager:xmlWarning(self.configFileName, "Unable to find powerTakeOff index '%d' for movingPart/movingTool '%s'", index, getName(part.node))
869 else
870 self:updatePowerTakeOff(spec.inputPowerTakeOffs[index], dt)
871 end
872 end
873 end
874
875 if part.localPowerTakeOffs ~= nil then
876 local spec = self.spec_powerTakeOffs
877 for i, index in ipairs(part.localPowerTakeOffs) do
878 if spec.localPowerTakeOffs[index] == nil then
879 part.localPowerTakeOffs[i] = nil
880 g_logManager:xmlWarning(self.configFileName, "Unable to find local powerTakeOff index '%d' for movingPart/movingTool '%s'", index, getName(part.node))
881 else
882 self:placeLocalPowerTakeOff(spec.localPowerTakeOffs[index], dt)
883 end
884 end
885 end
886end

updatePowerTakeOff

Description
Definition
updatePowerTakeOff()
Code
376function PowerTakeOffs:updatePowerTakeOff(input, dt)
377 if input.updateFunc ~= nil then
378 input.updateFunc(self, input, dt)
379 end
380end

updatePowerTakeOffLength

Description
Definition
updatePowerTakeOffLength()
Code
399function PowerTakeOffs:updatePowerTakeOffLength(input)
400 if input.updateDistanceFunc ~= nil then
401 input.updateDistanceFunc(self, input)
402 end
403end

updateSingleJointPowerTakeOff

Description
Definition
updateSingleJointPowerTakeOff()
Code
678function PowerTakeOffs:updateSingleJointPowerTakeOff(powerTakeOff, dt)
679 local x, y, z = getWorldTranslation(powerTakeOff.linkNode)
680
681 local dx, dy, dz = worldToLocal(powerTakeOff.startNode, x, y, z)
682 I3DUtil.setDirection(powerTakeOff.startJoint, dx, dy, dz, 0, 1, 0)
683
684 dx, dy, dz = worldToLocal(getParent(powerTakeOff.endJoint), x, y, z)
685 setTranslation(powerTakeOff.endJoint, 0, 0, MathUtil.vector3Length(dx, dy, dz))
686
687 local dist = calcDistanceFrom(powerTakeOff.scalePart, powerTakeOff.scalePartRef)
688 setScale(powerTakeOff.scalePart, 1, 1, dist / powerTakeOff.scalePartBaseDistance)
689end

validatePowerTakeOffAttachment

Description
Definition
validatePowerTakeOffAttachment()
Code
808function PowerTakeOffs:validatePowerTakeOffAttachment(powerTakeOff, output)
809 if output.outputNode == nil or powerTakeOff.inputNode == nil then
810 return false
811 end
812
813 local x1, y1, z1 = getWorldTranslation(output.outputNode)
814 local x2, y2, z2 = getWorldTranslation(powerTakeOff.inputNode)
815
816 local length = MathUtil.vector3Length(x1-x2, y1-y2, z1-z2)
817 if length < powerTakeOff.minLength then
818 return false
819 end
820
821 local length2D = MathUtil.vector2Length(x1-x2, z1-z2)
822 local angle = math.acos(length2D / length)
823 if angle > powerTakeOff.maxAngle then
824 return false
825 end
826
827 return true
828end