LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

DynamicMountAttacher

Description
Specialization for automatically attaching objects to vehicles (e.g. cutters to cutter trailers, bales to baleforks, ...)
Functions

addDynamicMountedObject

Description
Definition
addDynamicMountedObject()
Code
386function DynamicMountAttacher:addDynamicMountedObject(object)
387 local spec = self.spec_dynamicMountAttacher
388
389 if spec.dynamicMountedObjects[object] == nil then
390 spec.dynamicMountedObjects[object] = object
391
392 local lockedToPosition = false
393 if object.getMountableLockPositions ~= nil then
394 local lockPositions = object:getMountableLockPositions()
395 for i=1, #lockPositions do
396 local position = lockPositions[i]
397 if string.endsWith(self.configFileName, position.xmlFilename) then
398 local jointNode = I3DUtil.indexToObject(self.components, position.jointNode, self.i3dMappings)
399 if jointNode ~= nil then
400 local x, y, z = localToWorld(jointNode, position.transOffset[1], position.transOffset[2], position.transOffset[3])
401 local rx, ry, rz = localRotationToWorld(jointNode, position.rotOffset[1], position.rotOffset[2], position.rotOffset[3])
402 self:lockDynamicMountedObject(object, x, y, z, rx, ry, rz)
403
404 lockedToPosition = true
405 break
406 end
407 end
408 end
409 end
410
411 if not lockedToPosition then
412 for i=1, #spec.lockPositions do
413 local position = spec.lockPositions[i]
414 if string.endsWith(object.configFileName, position.xmlFilename) then
415 local x, y, z = getWorldTranslation(position.jointNode)
416 local rx, ry, rz = getWorldRotation(position.jointNode)
417 self:lockDynamicMountedObject(object, x, y, z, rx, ry, rz)
418
419 ObjectChangeUtil.setObjectChanges(position.objectChanges, true, self, self.setMovingToolDirty)
420
421 break
422 end
423 end
424 end
425
426 for _, info in pairs(spec.dynamicMountCollisionMasks) do
427 setCollisionMask(info.node, info.mountedCollisionMask)
428 end
429
430 if spec.transferMass then
431 if object.setReducedComponentMass ~= nil then
432 object:setReducedComponentMass(true)
433 self:setMassDirty()
434 end
435 end
436
437 self:setDynamicMountAnimationState(true)
438
439 self:raiseDirtyFlags(spec.dynamicMountedObjectsDirtyFlag)
440 end
441end

addNodeObjectMapping

Description
Definition
addNodeObjectMapping()
Code
703function DynamicMountAttacher:addNodeObjectMapping(superFunc, list)
704 superFunc(self, list)
705
706 local spec = self.spec_dynamicMountAttacher
707 if spec.dynamicMountAttacherTrigger ~= nil and spec.dynamicMountAttacherTrigger.triggerNode ~= nil then
708 list[spec.dynamicMountAttacherTrigger.triggerNode] = self
709 end
710end

dynamicMountTriggerCallback

Description
Definition
dynamicMountTriggerCallback()
Code
530function DynamicMountAttacher:dynamicMountTriggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId)
531 local spec = self.spec_dynamicMountAttacher
532
533 if getRigidBodyType(otherActorId) == RigidBodyType.DYNAMIC
534 and not getHasTrigger(otherActorId) then
535 if onEnter then
536 local object = g_currentMission:getNodeObject(otherActorId)
537 if object == nil then
538 object = g_currentMission.nodeToObject[otherActorId]
539 end
540 if object == self.rootVehicle or (self.spec_attachable ~= nil and self.spec_attachable.attacherVehicle == object) then
541 object = nil
542 end
543 if object ~= nil and object ~= self then
544 -- is a mountable object (e.g. bales)
545 local isObject = object.getSupportsMountDynamic ~= nil and object:getSupportsMountDynamic() and object.lastMoveTime ~= nil
546
547 -- is a mountable vehicle (e.g. pallets)
548 local isVehicle = object.getSupportsTensionBelts ~= nil and object:getSupportsTensionBelts() and object.lastMoveTime ~= nil
549
550 if isObject or isVehicle then
551 spec.pendingDynamicMountObjects[object] = Utils.getNoNil(spec.pendingDynamicMountObjects[object], 0) + 1
552
553 if spec.pendingDynamicMountObjects[object] == 1 then
554 self:raiseDirtyFlags(spec.dynamicMountedObjectsDirtyFlag)
555 end
556 end
557 end
558 elseif onLeave then
559 local object = g_currentMission:getNodeObject(otherActorId)
560 if object == nil then
561 object = g_currentMission.nodeToObject[otherActorId]
562 end
563 if object ~= nil then
564 if spec.pendingDynamicMountObjects[object] ~= nil then
565 local count = spec.pendingDynamicMountObjects[object]-1
566 if count == 0 then
567 spec.pendingDynamicMountObjects[object] = nil
568
569 if spec.dynamicMountedObjects[object] ~= nil then
570 self:removeDynamicMountedObject(object, false)
571 object:unmountDynamic()
572
573 if object.additionalDynamicMountJointNode ~= nil then
574 delete(object.additionalDynamicMountJointNode)
575 object.additionalDynamicMountJointNode = nil
576 end
577 end
578
579 self:raiseDirtyFlags(spec.dynamicMountedObjectsDirtyFlag)
580 else
581 spec.pendingDynamicMountObjects[object] = count
582 end
583 end
584 end
585 end
586 end
587end

forceDynamicMountPendingObjects

Description
Definition
forceDynamicMountPendingObjects()
Code
629function DynamicMountAttacher:forceDynamicMountPendingObjects(onlyBales)
630 if self:getAllowDynamicMountObjects() then
631 local spec = self.spec_dynamicMountAttacher
632 for object,_ in pairs(spec.pendingDynamicMountObjects) do
633 if spec.dynamicMountedObjects[object] == nil then
634 if not onlyBales or object:isa(Bale) then
635 local trigger = spec.dynamicMountAttacherTrigger
636 local couldMount = object:mountDynamic(self, trigger.rootNode, trigger.jointNode, trigger.mountType, trigger.forceAcceleration)
637 if couldMount then
638 self:addDynamicMountedObject(object)
639 end
640 end
641 end
642 end
643 end
644end

forceUnmountDynamicMountedObjects

Description
Definition
forceUnmountDynamicMountedObjects()
Code
648function DynamicMountAttacher:forceUnmountDynamicMountedObjects()
649 local spec = self.spec_dynamicMountAttacher
650 for object, _ in pairs(spec.dynamicMountedObjects) do
651 self:removeDynamicMountedObject(object, false)
652 object:unmountDynamic()
653
654 if object.additionalDynamicMountJointNode ~= nil then
655 delete(object.additionalDynamicMountJointNode)
656 object.additionalDynamicMountJointNode = nil
657 end
658 end
659end

getAdditionalComponentMass

Description
Definition
getAdditionalComponentMass()
Code
776function DynamicMountAttacher:getAdditionalComponentMass(superFunc, component)
777 local additionalMass = superFunc(self, component)
778 local spec = self.spec_dynamicMountAttacher
779
780 if spec.transferMass then
781 if spec.dynamicMountAttacherTrigger.component == component.node then
782 for object, _ in pairs(spec.dynamicMountedObjects) do
783 if object.getAllowComponentMassReduction ~= nil and object:getAllowComponentMassReduction() then
784 additionalMass = additionalMass + (object:getDefaultMass() - 0.1)
785 end
786 end
787 end
788 end
789
790 return additionalMass
791end

getAllowDynamicMountFillLevelInfo

Description
Definition
getAllowDynamicMountFillLevelInfo()
Code
591function DynamicMountAttacher:getAllowDynamicMountFillLevelInfo()
592 return true
593end

getAllowDynamicMountObjects

Description
Definition
getAllowDynamicMountObjects()
Code
524function DynamicMountAttacher:getAllowDynamicMountObjects()
525 return true
526end

getDynamicMountAttacherSettingsByNode

Description
Definition
getDynamicMountAttacherSettingsByNode()
Code
663function DynamicMountAttacher:getDynamicMountAttacherSettingsByNode(node)
664 local spec = self.spec_dynamicMountAttacher
665 for i=1, #spec.dynamicMountCollisionMasks do
666 local mountCollision = spec.dynamicMountCollisionMasks[i]
667 if mountCollision.triggerNode == node then
668 return mountCollision.mountType, mountCollision.forceLimitScale
669 end
670 end
671
672 return DynamicMountUtil.TYPE_FORK, 1
673end

getDynamicMountTimeToMount

Description
Definition
getDynamicMountTimeToMount()
Code
617function DynamicMountAttacher:getDynamicMountTimeToMount()
618 return self.spec_dynamicMountAttacher.dynamicMountAttacherTimeToMount
619end

getFillLevelInformation

Description
Definition
getFillLevelInformation()
Code
677function DynamicMountAttacher:getFillLevelInformation(superFunc, display)
678 superFunc(self, display)
679
680 if self:getAllowDynamicMountFillLevelInfo() then
681 local spec = self.spec_dynamicMountAttacher
682 for object,_ in pairs(spec.dynamicMountedObjects) do
683 if object.getFillLevelInformation ~= nil then
684 object:getFillLevelInformation(display)
685 else
686 if object.getFillLevel ~= nil and object.getFillType ~= nil then
687 local fillType = object:getFillType()
688 local fillLevel = object:getFillLevel()
689 local capacity = fillLevel
690 if object.getCapacity ~= nil then
691 capacity = object:getCapacity()
692 end
693
694 display:addFillLevel(fillType, fillLevel, capacity)
695 end
696 end
697 end
698 end
699end

getHasDynamicMountedObjects

Description
Definition
getHasDynamicMountedObjects()
Code
623function DynamicMountAttacher:getHasDynamicMountedObjects()
624 return next(self.spec_dynamicMountAttacher.dynamicMountedObjects) ~= nil
625end

getIsAttachedTo

Description
Definition
getIsAttachedTo()
Code
752function DynamicMountAttacher:getIsAttachedTo(superFunc, vehicle)
753 if superFunc(self, vehicle) then
754 return true
755 end
756
757 local spec = self.spec_dynamicMountAttacher
758
759 for object, _ in pairs(spec.dynamicMountedObjects) do
760 if object == vehicle then
761 return true
762 end
763 end
764
765 for object, _ in pairs(spec.pendingDynamicMountObjects) do
766 if object == vehicle then
767 return true
768 end
769 end
770
771 return false
772end

getIsDynamicMountGrabOpened

Description
Definition
getIsDynamicMountGrabOpened()
Code
611function DynamicMountAttacher:getIsDynamicMountGrabOpened(grab)
612 return true
613end

initSpecialization

Description
Definition
initSpecialization()
Code
23function DynamicMountAttacher.initSpecialization()
24 local schema = Vehicle.xmlSchema
25 schema:setXMLSpecializationType("DynamicMountAttacher")
26
27 schema:register(XMLValueType.NODE_INDEX, "vehicle.dynamicMountAttacher#node", "Attacher node")
28 schema:register(XMLValueType.FLOAT, "vehicle.dynamicMountAttacher#forceLimitScale", "Force limit", 1)
29 schema:register(XMLValueType.FLOAT, "vehicle.dynamicMountAttacher#timeToMount", "No movement time until mounting", 1000)
30 schema:register(XMLValueType.INT, "vehicle.dynamicMountAttacher#numObjectBits", "Number of object bits to sync", 5)
31
32 schema:register(XMLValueType.STRING, "vehicle.dynamicMountAttacher.grab#openMountType", "Open mount type", "TYPE_FORK")
33 schema:register(XMLValueType.STRING, "vehicle.dynamicMountAttacher.grab#closedMountType", "Closed mount type", "TYPE_AUTO_ATTACH_XYZ")
34
35 schema:register(XMLValueType.NODE_INDEX, "vehicle.dynamicMountAttacher.mountCollisionMask(?)#node", "Collision node")
36 schema:register(XMLValueType.NODE_INDEX, "vehicle.dynamicMountAttacher.mountCollisionMask(?)#triggerNode", "Trigger node")
37 schema:register(XMLValueType.STRING, "vehicle.dynamicMountAttacher.mountCollisionMask(?)#mountType", "Mount type name", "FORK")
38 schema:register(XMLValueType.FLOAT, "vehicle.dynamicMountAttacher.mountCollisionMask(?)#forceLimitScale", "Force limit", 1)
39 schema:register(XMLValueType.INT, "vehicle.dynamicMountAttacher.mountCollisionMask(?)#collisionMask", "Collision mask while object mounted")
40
41 schema:register(XMLValueType.NODE_INDEX, "vehicle.dynamicMountAttacher#triggerNode", "Trigger node")
42 schema:register(XMLValueType.NODE_INDEX, "vehicle.dynamicMountAttacher#rootNode", "Root node")
43 schema:register(XMLValueType.NODE_INDEX, "vehicle.dynamicMountAttacher#jointNode", "Joint node")
44 schema:register(XMLValueType.FLOAT, "vehicle.dynamicMountAttacher#forceAcceleration", "Force acceleration", 30)
45 schema:register(XMLValueType.STRING, "vehicle.dynamicMountAttacher#mountType", "Mount type", "TYPE_AUTO_ATTACH_XZ")
46
47 schema:register(XMLValueType.BOOL, "vehicle.dynamicMountAttacher#transferMass", "If this is set to 'true' the mass of the object to mount is tranfered to our own component. This improves phyiscs stability", false)
48
49 schema:register(XMLValueType.STRING, "vehicle.dynamicMountAttacher.lockPosition(?)#xmlFilename", "XML filename of vehicle to lock (needs to match only the end of the filename)")
50 schema:register(XMLValueType.NODE_INDEX, "vehicle.dynamicMountAttacher.lockPosition(?)#jointNode", "Joint node (Representens the position of the other vehicles root node)")
51
52 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.dynamicMountAttacher.lockPosition(?)")
53
54 schema:register(XMLValueType.STRING, "vehicle.dynamicMountAttacher.animation#name", "Animation name")
55 schema:register(XMLValueType.FLOAT, "vehicle.dynamicMountAttacher.animation#speed", "Animation speed", 1)
56
57 schema:register(XMLValueType.BOOL, Cylindered.MOVING_TOOL_XML_KEY .. ".dynamicMountAttacher#value", "Update dynamic mount attacher joints")
58 schema:register(XMLValueType.BOOL, Cylindered.MOVING_PART_XML_KEY .. ".dynamicMountAttacher#value", "Update dynamic mount attacher joints")
59
60 schema:setXMLSpecializationType()
61end

loadDynamicMountGrabFromXML

Description
Definition
loadDynamicMountGrabFromXML()
Code
597function DynamicMountAttacher:loadDynamicMountGrabFromXML(xmlFile, key, entry)
598 local openMountType = self.xmlFile:getValue(key.."#openMountType")
599 entry.openMountType = Utils.getNoNil(DynamicMountUtil[openMountType], DynamicMountUtil.TYPE_FORK)
600
601 local closedMountType = self.xmlFile:getValue(key.."#closedMountType")
602 entry.closedMountType = Utils.getNoNil(DynamicMountUtil[closedMountType], DynamicMountUtil.TYPE_AUTO_ATTACH_XYZ)
603
604 entry.currentMountType = entry.openMountType
605
606 return true
607end

loadExtraDependentParts

Description
Definition
loadExtraDependentParts()
Code
725function DynamicMountAttacher:loadExtraDependentParts(superFunc, xmlFile, baseName, entry)
726 if not superFunc(self, xmlFile, baseName, entry) then
727 return false
728 end
729
730 entry.updateDynamicMountAttacher = xmlFile:getValue(baseName.. ".dynamicMountAttacher#value")
731
732 return true
733end

lockDynamicMountedObject

Description
Definition
lockDynamicMountedObject()
Code
365function DynamicMountAttacher:lockDynamicMountedObject(object, x, y, z, rx, ry, rz)
366 local spec = self.spec_dynamicMountAttacher
367
368 DynamicMountUtil.unmountDynamic(object, false)
369
370 object:removeFromPhysics()
371 spec.pendingDynamicMountObjects[object] = nil -- will be readded on addToPhysics
372
373 object:setWorldPosition(x, y, z, rx, ry, rz, 1, true)
374 object:addToPhysics()
375
376 local trigger = spec.dynamicMountAttacherTrigger
377
378 local couldMount = object:mountDynamic(self, trigger.rootNode, trigger.jointNode, trigger.mountType, trigger.forceAcceleration)
379 if not couldMount then
380 self:removeDynamicMountedObject(object, false)
381 end
382end

onDelete

Description
Definition
onDelete()
Code
203function DynamicMountAttacher:onDelete()
204 local spec = self.spec_dynamicMountAttacher
205
206 if self.isServer and spec.dynamicMountedObjects ~= nil then
207 for object,_ in pairs(spec.dynamicMountedObjects) do
208 object:unmountDynamic()
209 end
210 end
211 if spec.dynamicMountAttacherTrigger ~= nil then
212 removeTrigger(spec.dynamicMountAttacherTrigger.triggerNode)
213 end
214end

onLoad

Description
Definition
onLoad()
Code
109function DynamicMountAttacher:onLoad(savegame)
110 local spec = self.spec_dynamicMountAttacher
111
112 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.dynamicMountAttacher#index", "vehicle.dynamicMountAttacher#node") --FS17 to FS19
113
114 -- Allow mountable object to attach them selfs to us
115 spec.dynamicMountAttacherNode = self.xmlFile:getValue("vehicle.dynamicMountAttacher#node", nil, self.components, self.i3dMappings)
116 spec.dynamicMountAttacherForceLimitScale = self.xmlFile:getValue("vehicle.dynamicMountAttacher#forceLimitScale", 1)
117 spec.dynamicMountAttacherTimeToMount = self.xmlFile:getValue("vehicle.dynamicMountAttacher#timeToMount", 1000)
118 spec.numObjectBits = self.xmlFile:getValue("vehicle.dynamicMountAttacher#numObjectBits", 5)
119 spec.maxNumObjectsToSend = 2 ^ spec.numObjectBits - 1
120
121 local grabKey = "vehicle.dynamicMountAttacher.grab"
122 if self.xmlFile:hasProperty(grabKey) then
123 spec.dynamicMountAttacherGrab = {}
124 self:loadDynamicMountGrabFromXML(self.xmlFile, grabKey, spec.dynamicMountAttacherGrab)
125 end
126
127 spec.pendingDynamicMountObjects = {}
128 spec.dynamicMountCollisionMasks = {}
129 spec.lockPositions = {}
130
131 if self.isServer then
132 self.xmlFile:iterate("vehicle.dynamicMountAttacher.mountCollisionMask", function(index, key)
133 local mountCollision = {}
134 mountCollision.node = self.xmlFile:getValue(key.."#node", nil, self.components, self.i3dMappings)
135 mountCollision.triggerNode = self.xmlFile:getValue(key.."#triggerNode", nil, self.components, self.i3dMappings)
136 mountCollision.mountedCollisionMask = self.xmlFile:getValue(key.."#collisionMask")
137 if mountCollision.node ~= nil and mountCollision.mountedCollisionMask ~= nil then
138 local mountTypeStr = self.xmlFile:getValue(key.."#mountType", "FORK")
139 mountCollision.mountType = DynamicMountUtil["TYPE_" .. mountTypeStr] or DynamicMountUtil.TYPE_FORK
140 mountCollision.forceLimitScale = self.xmlFile:getValue(key .. "#forceLimitScale", spec.dynamicMountAttacherForceLimitScale)
141
142 mountCollision.unmountedCollisionMask = getCollisionMask(mountCollision.node)
143
144 table.insert(spec.dynamicMountCollisionMasks, mountCollision)
145 else
146 Logging.xmlWarning(self.xmlFile, "Missing node or collisionMask in '%s'", key)
147 end
148 end)
149
150 local dynamicMountTrigger = {}
151 dynamicMountTrigger.triggerNode = self.xmlFile:getValue("vehicle.dynamicMountAttacher#triggerNode", nil, self.components, self.i3dMappings)
152 dynamicMountTrigger.rootNode = self.xmlFile:getValue("vehicle.dynamicMountAttacher#rootNode", nil, self.components, self.i3dMappings)
153 dynamicMountTrigger.jointNode = self.xmlFile:getValue("vehicle.dynamicMountAttacher#jointNode", nil, self.components, self.i3dMappings)
154 if dynamicMountTrigger.triggerNode ~= nil and dynamicMountTrigger.rootNode ~= nil and dynamicMountTrigger.jointNode ~= nil then
155 local collisionMask = getCollisionMask(dynamicMountTrigger.triggerNode)
156 if collisionMask == CollisionMask.TRIGGER_DYNAMIC_MOUNT then
157 addTrigger(dynamicMountTrigger.triggerNode, "dynamicMountTriggerCallback", self)
158
159 dynamicMountTrigger.forceAcceleration = self.xmlFile:getValue("vehicle.dynamicMountAttacher#forceAcceleration", 30)
160 local mountTypeString = self.xmlFile:getValue("vehicle.dynamicMountAttacher#mountType", "TYPE_AUTO_ATTACH_XZ")
161 dynamicMountTrigger.mountType = Utils.getNoNil(DynamicMountUtil[mountTypeString], DynamicMountUtil.TYPE_AUTO_ATTACH_XZ)
162 dynamicMountTrigger.currentMountType = dynamicMountTrigger.mountType
163 dynamicMountTrigger.component = self:getParentComponent(dynamicMountTrigger.triggerNode)
164
165 spec.dynamicMountAttacherTrigger = dynamicMountTrigger
166 else
167 Logging.xmlWarning(self.xmlFile, "Dynamic Mount trigger has invalid collision mask (should be %d)!", CollisionMask.TRIGGER_DYNAMIC_MOUNT)
168 end
169 end
170
171 spec.transferMass = self.xmlFile:getValue("vehicle.dynamicMountAttacher#transferMass", false)
172
173 self.xmlFile:iterate("vehicle.dynamicMountAttacher.lockPosition", function(index, key)
174 local entry = {}
175
176 entry.xmlFilename = self.xmlFile:getValue(key .. "#xmlFilename")
177 entry.jointNode = self.xmlFile:getValue(key .. "#jointNode", nil, self.components, self.i3dMappings)
178 if entry.xmlFilename ~= nil and entry.jointNode ~= nil then
179 entry.xmlFilename = entry.xmlFilename:gsub("$data", "data")
180
181 entry.objectChanges = {}
182 ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, key, entry.objectChanges, self.components, self)
183
184 table.insert(spec.lockPositions, entry)
185 else
186 Logging.xmlWarning(self.xmlFile, "Invalid lock position '%s'. Missing xmlFilename or jointNode!", key)
187 end
188 end)
189 end
190
191 spec.animationName = self.xmlFile:getValue("vehicle.dynamicMountAttacher.animation#name")
192 spec.animationSpeed = self.xmlFile:getValue("vehicle.dynamicMountAttacher.animation#speed", 1)
193 if spec.animationName ~= nil then
194 self:playAnimation(spec.animationName, spec.animationSpeed, self:getAnimationTime(spec.animationName), true)
195 end
196
197 spec.dynamicMountedObjects = {}
198 spec.dynamicMountedObjectsDirtyFlag = self:getNextDirtyFlag()
199end

onPreAttachImplement

Description
Definition
onPreAttachImplement()
Code
795function DynamicMountAttacher:onPreAttachImplement(object, inputJointDescIndex, jointDescIndex)
796 local objSpec = object.spec_dynamicMountAttacher
797 if objSpec ~= nil and self.isServer then
798 objSpec.pendingDynamicMountObjects[self] = nil
799 if objSpec.dynamicMountedObjects[self] ~= nil then
800 object:removeDynamicMountedObject(self, false)
801 self:unmountDynamic()
802
803 if object.additionalDynamicMountJointNode ~= nil then
804 delete(object.additionalDynamicMountJointNode)
805 object.additionalDynamicMountJointNode = nil
806 end
807 end
808 end
809end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
218function DynamicMountAttacher:onReadUpdateStream(streamId, timestamp, connection)
219 if connection:getIsServer() then
220 local spec = self.spec_dynamicMountAttacher
221
222 if streamReadBool(streamId) then
223 local sum = self:readDynamicMountObjectsFromStream(streamId, spec.dynamicMountedObjects)
224 self:setDynamicMountAnimationState(sum > 0)
225
226 self:readDynamicMountObjectsFromStream(streamId, spec.pendingDynamicMountObjects)
227 end
228 end
229end

onUpdateTick

Description
Definition
onUpdateTick()
Code
246function DynamicMountAttacher:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
247 if self.isServer then
248 local spec = self.spec_dynamicMountAttacher
249 if self:getAllowDynamicMountObjects() then
250 for object,_ in pairs(spec.pendingDynamicMountObjects) do
251 -- raise active as long as we got pending objects to give the objects a chance to be mounted if they are not moving
252 self:raiseActive()
253
254 if spec.dynamicMountedObjects[object] == nil then
255 if object.lastMoveTime + self:getDynamicMountTimeToMount() < g_currentMission.time then
256 local doAttach = false
257 local objectRoot
258 if object.components ~= nil then
259 if object.getCanByMounted ~= nil then
260 doAttach = object:getCanByMounted()
261 elseif entityExists(object.components[1].node) then
262 doAttach = true
263 end
264
265 objectRoot = object.components[1].node
266 end
267 if object.nodeId ~= nil then
268 if object.getCanByMounted ~= nil then
269 doAttach = object:getCanByMounted()
270 elseif entityExists(object.nodeId) then
271 doAttach = true
272 end
273 objectRoot = object.nodeId
274 end
275 if doAttach then
276 local trigger = spec.dynamicMountAttacherTrigger
277 local objectJoint = createTransformGroup("dynamicMountObjectJoint")
278 link(trigger.jointNode, objectJoint)
279 setWorldTranslation(objectJoint, getWorldTranslation(objectRoot))
280
281 local couldMount = object:mountDynamic(self, trigger.rootNode, objectJoint, trigger.mountType, trigger.forceAcceleration)
282 if couldMount then
283 object.additionalDynamicMountJointNode = objectJoint
284 self:addDynamicMountedObject(object)
285 else
286 delete(objectJoint)
287 end
288 else
289 spec.pendingDynamicMountObjects[object] = nil
290
291 self:raiseDirtyFlags(spec.dynamicMountedObjectsDirtyFlag)
292 end
293 end
294 end
295 end
296 else
297 for object,_ in pairs(spec.dynamicMountedObjects) do
298 self:removeDynamicMountedObject(object, false)
299 object:unmountDynamic()
300
301 if object.additionalDynamicMountJointNode ~= nil then
302 delete(object.additionalDynamicMountJointNode)
303 object.additionalDynamicMountJointNode = nil
304 end
305 end
306 end
307
308 if spec.dynamicMountAttacherGrab ~= nil then
309 for object,_ in pairs(spec.dynamicMountedObjects) do
310 local usedMountType = spec.dynamicMountAttacherGrab.closedMountType
311
312 if self:getIsDynamicMountGrabOpened(spec.dynamicMountAttacherGrab) then
313 usedMountType = spec.dynamicMountAttacherGrab.openMountType
314 end
315
316 if spec.dynamicMountAttacherGrab.currentMountType ~= usedMountType then
317 spec.dynamicMountAttacherGrab.currentMountType = usedMountType
318
319 local x, y, z = getWorldTranslation(spec.dynamicMountAttacherNode)
320 setJointPosition(object.dynamicMountJointIndex, 1, x,y,z)
321 if usedMountType == DynamicMountUtil.TYPE_FORK then
322
323 setJointRotationLimit(object.dynamicMountJointIndex, 0, true, 0, 0)
324 setJointRotationLimit(object.dynamicMountJointIndex, 1, true, 0, 0)
325 setJointRotationLimit(object.dynamicMountJointIndex, 2, true, 0, 0)
326
327 if object.dynamicMountSingleAxisFreeX then
328 setJointTranslationLimit(object.dynamicMountJointIndex, 0, false, 0, 0)
329 else
330 setJointTranslationLimit(object.dynamicMountJointIndex, 0, true, -0.01, 0.01)
331 end
332 if object.dynamicMountSingleAxisFreeY then
333 setJointTranslationLimit(object.dynamicMountJointIndex, 1, false, 0, 0)
334 else
335 setJointTranslationLimit(object.dynamicMountJointIndex, 1, true, -0.01, 0.01)
336 end
337 setJointTranslationLimit(object.dynamicMountJointIndex, 2, false, 0, 0)
338 else
339 setJointRotationLimit(object.dynamicMountJointIndex, 0, true, 0, 0)
340 setJointRotationLimit(object.dynamicMountJointIndex, 1, true, 0, 0)
341 setJointRotationLimit(object.dynamicMountJointIndex, 2, true, 0, 0)
342
343 if usedMountType == DynamicMountUtil.TYPE_AUTO_ATTACH_XYZ or usedMountType == DynamicMountUtil.TYPE_FIX_ATTACH then
344 setJointTranslationLimit(object.dynamicMountJointIndex, 0, true, -0.01, 0.01)
345 setJointTranslationLimit(object.dynamicMountJointIndex, 1, true, -0.01, 0.01)
346 setJointTranslationLimit(object.dynamicMountJointIndex, 2, true, -0.01, 0.01)
347 elseif usedMountType == DynamicMountUtil.TYPE_AUTO_ATTACH_XZ then
348 setJointTranslationLimit(object.dynamicMountJointIndex, 0, true, -0.01, 0.01)
349 setJointTranslationLimit(object.dynamicMountJointIndex, 1, false, 0, 0)
350 setJointTranslationLimit(object.dynamicMountJointIndex, 2, true, -0.01, 0.01)
351 elseif usedMountType == DynamicMountUtil.TYPE_AUTO_ATTACH_Y then
352 setJointTranslationLimit(object.dynamicMountJointIndex, 0, false, 0, 0)
353 setJointTranslationLimit(object.dynamicMountJointIndex, 1, true, -0.01, 0.01)
354 setJointTranslationLimit(object.dynamicMountJointIndex, 2, false, 0, 0)
355 end
356 end
357 end
358 end
359 end
360 end
361end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
233function DynamicMountAttacher:onWriteUpdateStream(streamId, connection, dirtyMask)
234 if not connection:getIsServer() then
235 local spec = self.spec_dynamicMountAttacher
236
237 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dynamicMountedObjectsDirtyFlag) ~= 0) then
238 self:writeDynamicMountObjectsToStream(streamId, spec.dynamicMountedObjects)
239 self:writeDynamicMountObjectsToStream(streamId, spec.pendingDynamicMountObjects)
240 end
241 end
242end

prerequisitesPresent

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

readDynamicMountObjectsFromStream

Description
Definition
readDynamicMountObjectsFromStream()
Code
504function DynamicMountAttacher:readDynamicMountObjectsFromStream(streamId, objects)
505 local spec = self.spec_dynamicMountAttacher
506 local sum = streamReadUIntN(streamId, spec.numObjectBits)
507
508 for k, _ in pairs(objects) do
509 objects[k] = nil
510 end
511
512 for _=1, sum do
513 local object = NetworkUtil.readNodeObject(streamId)
514 if object ~= nil then
515 objects[object] = object
516 end
517 end
518
519 return sum
520end

registerEventListeners

Description
Definition
registerEventListeners()
Code
98function DynamicMountAttacher.registerEventListeners(vehicleType)
99 SpecializationUtil.registerEventListener(vehicleType, "onLoad", DynamicMountAttacher)
100 SpecializationUtil.registerEventListener(vehicleType, "onDelete", DynamicMountAttacher)
101 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", DynamicMountAttacher)
102 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", DynamicMountAttacher)
103 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", DynamicMountAttacher)
104 SpecializationUtil.registerEventListener(vehicleType, "onPreAttachImplement", DynamicMountAttacher)
105end

registerFunctions

Description
Definition
registerFunctions()
Code
65function DynamicMountAttacher.registerFunctions(vehicleType)
66 SpecializationUtil.registerFunction(vehicleType, "writeDynamicMountObjectsToStream", DynamicMountAttacher.writeDynamicMountObjectsToStream)
67 SpecializationUtil.registerFunction(vehicleType, "readDynamicMountObjectsFromStream", DynamicMountAttacher.readDynamicMountObjectsFromStream)
68 SpecializationUtil.registerFunction(vehicleType, "getAllowDynamicMountObjects", DynamicMountAttacher.getAllowDynamicMountObjects)
69 SpecializationUtil.registerFunction(vehicleType, "dynamicMountTriggerCallback", DynamicMountAttacher.dynamicMountTriggerCallback)
70 SpecializationUtil.registerFunction(vehicleType, "lockDynamicMountedObject", DynamicMountAttacher.lockDynamicMountedObject)
71 SpecializationUtil.registerFunction(vehicleType, "addDynamicMountedObject", DynamicMountAttacher.addDynamicMountedObject)
72 SpecializationUtil.registerFunction(vehicleType, "removeDynamicMountedObject", DynamicMountAttacher.removeDynamicMountedObject)
73 SpecializationUtil.registerFunction(vehicleType, "setDynamicMountAnimationState", DynamicMountAttacher.setDynamicMountAnimationState)
74 SpecializationUtil.registerFunction(vehicleType, "getAllowDynamicMountFillLevelInfo", DynamicMountAttacher.getAllowDynamicMountFillLevelInfo)
75 SpecializationUtil.registerFunction(vehicleType, "loadDynamicMountGrabFromXML", DynamicMountAttacher.loadDynamicMountGrabFromXML)
76 SpecializationUtil.registerFunction(vehicleType, "getIsDynamicMountGrabOpened", DynamicMountAttacher.getIsDynamicMountGrabOpened)
77 SpecializationUtil.registerFunction(vehicleType, "getDynamicMountTimeToMount", DynamicMountAttacher.getDynamicMountTimeToMount)
78 SpecializationUtil.registerFunction(vehicleType, "getHasDynamicMountedObjects", DynamicMountAttacher.getHasDynamicMountedObjects)
79 SpecializationUtil.registerFunction(vehicleType, "forceDynamicMountPendingObjects", DynamicMountAttacher.forceDynamicMountPendingObjects)
80 SpecializationUtil.registerFunction(vehicleType, "forceUnmountDynamicMountedObjects", DynamicMountAttacher.forceUnmountDynamicMountedObjects)
81 SpecializationUtil.registerFunction(vehicleType, "getDynamicMountAttacherSettingsByNode", DynamicMountAttacher.getDynamicMountAttacherSettingsByNode)
82end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
86function DynamicMountAttacher.registerOverwrittenFunctions(vehicleType)
87 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillLevelInformation", DynamicMountAttacher.getFillLevelInformation)
88 SpecializationUtil.registerOverwrittenFunction(vehicleType, "addNodeObjectMapping", DynamicMountAttacher.addNodeObjectMapping)
89 SpecializationUtil.registerOverwrittenFunction(vehicleType, "removeNodeObjectMapping", DynamicMountAttacher.removeNodeObjectMapping)
90 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadExtraDependentParts", DynamicMountAttacher.loadExtraDependentParts)
91 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateExtraDependentParts", DynamicMountAttacher.updateExtraDependentParts)
92 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsAttachedTo", DynamicMountAttacher.getIsAttachedTo)
93 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAdditionalComponentMass", DynamicMountAttacher.getAdditionalComponentMass)
94end

removeDynamicMountedObject

Description
Definition
removeDynamicMountedObject()
Code
445function DynamicMountAttacher:removeDynamicMountedObject(object, isDeleting)
446 local spec = self.spec_dynamicMountAttacher
447
448 spec.dynamicMountedObjects[object] = nil
449 if isDeleting then
450 spec.pendingDynamicMountObjects[object] = nil
451 end
452
453 for i=1, #spec.lockPositions do
454 ObjectChangeUtil.setObjectChanges(spec.lockPositions[i].objectChanges, false, self, self.setMovingToolDirty)
455 end
456
457 if next(spec.dynamicMountedObjects) == nil and next(spec.pendingDynamicMountObjects) == nil then
458 for _, info in pairs(spec.dynamicMountCollisionMasks) do
459 setCollisionMask(info.node, info.unmountedCollisionMask)
460 end
461 end
462
463 if spec.transferMass then
464 self:setMassDirty()
465 end
466
467 self:setDynamicMountAnimationState(false)
468
469 self:raiseDirtyFlags(spec.dynamicMountedObjectsDirtyFlag)
470end

removeNodeObjectMapping

Description
Definition
removeNodeObjectMapping()
Code
714function DynamicMountAttacher:removeNodeObjectMapping(superFunc, list)
715 superFunc(self, list)
716
717 local spec = self.spec_dynamicMountAttacher
718 if spec.dynamicMountAttacherTrigger ~= nil and spec.dynamicMountAttacherTrigger.triggerNode ~= nil then
719 list[spec.dynamicMountAttacherTrigger.triggerNode] = nil
720 end
721end

setDynamicMountAnimationState

Description
Definition
setDynamicMountAnimationState()
Code
474function DynamicMountAttacher:setDynamicMountAnimationState(state)
475 local spec = self.spec_dynamicMountAttacher
476
477 if state then
478 self:playAnimation(spec.animationName, spec.animationSpeed, self:getAnimationTime(spec.animationName), true)
479 else
480 self:playAnimation(spec.animationName, -spec.animationSpeed, self:getAnimationTime(spec.animationName), true)
481 end
482end

updateDebugValues

Description
Definition
updateDebugValues()
Code
813function DynamicMountAttacher:updateDebugValues(values)
814 local spec = self.spec_dynamicMountAttacher
815
816 if self.isServer then
817 local timeToMount = self.lastMoveTime + spec.dynamicMountAttacherTimeToMount - g_currentMission.time
818 table.insert(values, {name="timeToMount:", value=string.format("%d", timeToMount)})
819
820 for object, _ in pairs(spec.pendingDynamicMountObjects) do
821 table.insert(values, {name="pendingDynamicMountObject:", value=string.format("%s timeToMount: %d", object.configFileName or object, math.max(object.lastMoveTime + spec.dynamicMountAttacherTimeToMount - g_currentMission.time, 0))})
822 end
823
824 for object, _ in pairs(spec.dynamicMountedObjects) do
825 table.insert(values, {name="dynamicMountedObjects:", value=string.format("%s", object.configFileName or object)})
826 end
827 end
828
829 table.insert(values, {name="allowMountObjects:", value=string.format("%s", self:getAllowDynamicMountObjects())})
830
831 if spec.dynamicMountAttacherGrab ~= nil then
832 table.insert(values, {name="grabOpened:", value=string.format("%s", self:getIsDynamicMountGrabOpened(spec.dynamicMountAttacherGrab))})
833 end
834end

updateExtraDependentParts

Description
Definition
updateExtraDependentParts()
Code
737function DynamicMountAttacher:updateExtraDependentParts(superFunc, part, dt)
738 superFunc(self, part, dt)
739
740 if self.isServer then
741 if part.updateDynamicMountAttacher ~= nil and part.updateDynamicMountAttacher then
742 local spec = self.spec_dynamicMountAttacher
743 for object,_ in pairs(spec.dynamicMountedObjects) do
744 setJointFrame(object.dynamicMountJointIndex, 0, object.dynamicMountJointNode)
745 end
746 end
747 end
748end

writeDynamicMountObjectsToStream

Description
Definition
writeDynamicMountObjectsToStream()
Code
486function DynamicMountAttacher:writeDynamicMountObjectsToStream(streamId, objects)
487 local spec = self.spec_dynamicMountAttacher
488 local num = math.min(table.size(objects), spec.maxNumObjectsToSend)
489 streamWriteUIntN(streamId, num, spec.numObjectBits)
490
491 local objectIndex = 0
492 for object,_ in pairs(objects) do
493 objectIndex = objectIndex + 1
494 if objectIndex <= num then
495 NetworkUtil.writeNodeObject(streamId, object)
496 else
497 Logging.xmlWarning(self.xmlFile, "Not enough bits to send all mounted objects. Please increase '%s'", "vehicle.dynamicMountAttacher#numObjectBits")
498 end
499 end
500end