LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

TensionBelts

Description
Class for vehicle which can dynamically mount objects (e.g. bales and pallets)
Functions

actionEventToggleTensionBelts

Description
Definition
actionEventToggleTensionBelts()
Code
1178function TensionBelts.actionEventToggleTensionBelts(self, actionName, inputValue, callbackState, isAnalog)
1179 local spec = self.spec_tensionBelts
1180
1181 local newState = not spec.areBeltsFasten
1182 for _, belt in pairs(spec.sortedBelts) do
1183 self:setTensionBeltsActive(newState, belt.id, false)
1184 end
1185 spec.checkBoxes = {}
1186end

consoleCommandToggleTensionBeltDebugRendering

Description
Definition
consoleCommandToggleTensionBeltDebugRendering()
Code
1190function TensionBelts.consoleCommandToggleTensionBeltDebugRendering(unusedSelf)
1191 TensionBelts.debugRendering = not TensionBelts.debugRendering
1192 return "TensionBeltsDebugRendering = "..tostring(TensionBelts.debugRendering)
1193end

createTensionBelt

Description
Create tension belt
Definition
createTensionBelt(table belt, boolean isDummy, table object)
Arguments
tablebeltbelt to use
booleanisDummycreate dummy belt
tableobjectobjects to fasten
Code
735function TensionBelts:createTensionBelt(belt, isDummy, objects)
736 local spec = self.spec_tensionBelts
737
738 local tensionBelt = TensionBeltGeometryConstructor:new()
739
740 local beltData = spec.beltData
741
742 tensionBelt:setWidth(spec.width)
743 tensionBelt:setMaxEdgeLength(spec.maxEdgeLength)
744 if isDummy then
745 tensionBelt:setMaterial(beltData.dummyMaterial.materialId)
746 tensionBelt:setUVscale(beltData.dummyMaterial.uvScale)
747 else
748 tensionBelt:setMaterial(beltData.material.materialId)
749 tensionBelt:setUVscale(beltData.material.uvScale)
750 end
751
752 if spec.ratchetPosition ~= nil and beltData.ratchet ~= nil then
753 tensionBelt:addAttachment(0, spec.ratchetPosition, beltData.ratchet.sizeRatio*spec.width)
754 end
755
756 if spec.useHooks and beltData.hook ~= nil then
757 tensionBelt:addAttachment(0, 0, beltData.hook.sizeRatio*spec.width)
758 tensionBelt:addAttachment(1, 0, beltData.hook.sizeRatio*spec.width)
759 end
760
761 tensionBelt:setFixedPoints(belt.startNode, belt.endNode)
762 tensionBelt:setGeometryBias(spec.geometryBias)
763 tensionBelt:setLinkNode(spec.linkNode)
764
765 for _, pointNode in pairs(belt.intersectionNodes) do
766 local x,y,z = getWorldTranslation(pointNode)
767 local dirX, dirY, dirZ = localDirectionToWorld(pointNode, 1, 0, 0)
768 tensionBelt:addIntersectionPoint(x,y,z, dirX, dirY, dirZ)
769 end
770
771 for _, object in pairs(objects) do
772 for _, node in pairs(object.visuals) do
773 if getSplitType(node) ~= 0 then
774 -- Allow a larger range of uvs for trees
775 tensionBelt:addShape(node, -100, 100, -100, 100)
776 else
777 tensionBelt:addShape(node, 0, 1, 0, 1)
778 end
779 end
780 end
781
782 local beltShape, _, beltLength = tensionBelt:finalize()
783 if beltShape ~= 0 then
784 if isDummy then
785 belt.dummy = beltShape
786 else
787 local currentIndex = 0
788 if spec.ratchetPosition ~= nil and beltData.ratchet ~= nil then
789 if getNumOfChildren(beltShape) > currentIndex then
790 local scale = spec.width
791 local ratched = clone(beltData.ratchet.node, false, false, false)
792 link(getChildAt(beltShape, 0), ratched)
793 setScale(ratched, scale, scale, scale)
794 currentIndex = currentIndex + 1
795 end
796 end
797 if spec.useHooks then
798 if beltData.hook ~= nil and getNumOfChildren(beltShape) > currentIndex+1 then
799 local scale = spec.width
800 local hookStart = clone(beltData.hook.node, false, false, false)
801 link(getChildAt(beltShape, currentIndex), hookStart)
802 setScale(hookStart, scale, scale, scale)
803
804 local hookEnd = clone(beltData.hook.node, false, false, false)
805 link(getChildAt(beltShape, currentIndex+1), hookEnd)
806 setRotation(hookEnd, 0, math.pi, 0)
807 setTranslation(hookEnd, 0, 0, beltData.hook.sizeRatio*spec.width)
808 setScale(hookEnd, scale, scale, scale)
809 currentIndex = currentIndex + 2
810
811 setShaderParameter(beltShape, "beltClipOffsets", 0, beltData.hook.sizeRatio*spec.width, beltLength-beltData.hook.sizeRatio*spec.width, beltLength, false)
812 end
813 end
814
815 belt.mesh = beltShape
816 spec.belts[beltShape] = beltShape
817 if belt.dummy ~= nil then
818 delete(belt.dummy)
819 belt.dummy = nil
820 end
821 end
822
823 return beltShape
824 end
825
826 return nil
827end

freeTensionBeltObject

Description
Definition
freeTensionBeltObject()
Code
529function TensionBelts:freeTensionBeltObject(objectId, objectsToJointTable, isDynamic)
530 if entityExists(objectId) then
531 local jointData = objectsToJointTable[objectId]
532 if isDynamic then
533 if jointData ~= nil then
534 removeJoint(jointData.jointIndex)
535 delete(jointData.jointTransform)
536 end
537
538 -- reset collision
539 for obj, _ in pairs(objectsToJointTable) do
540 if obj ~= objectId then
541 setPairCollision(objectId, obj, true)
542 end
543 end
544 else
545 local parentNode
546 if jointData ~= nil then
547 parentNode = jointData.parent
548 end
549 if parentNode ~= nil and not entityExists(parentNode) then
550 -- For some reason the original parent node was deleted. Delete the attached node too
551 delete(objectId)
552 else
553 if parentNode == nil then
554 parentNode = getRootNode()
555 end
556 local x,y,z = getWorldTranslation(objectId)
557 local a,b,c = getWorldRotation(objectId)
558 link(parentNode, objectId)
559 setWorldTranslation(objectId, x, y, z)
560 setWorldRotation(objectId, a, b, c)
561 setRigidBodyType(objectId, "Dynamic")
562 end
563 end
564 end
565
566 -- remove objectId from object list
567 objectsToJointTable[objectId] = nil
568end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
1085function TensionBelts:getCanBeSelected(superFunc)
1086 return true
1087end

getIsDynamicallyMountedNode

Description
Definition
getIsDynamicallyMountedNode()
Code
1058function TensionBelts:getIsDynamicallyMountedNode(node)
1059 local spec = self.spec_tensionBelts
1060
1061 if spec.objectsToJoint ~= nil then
1062 for object,_ in pairs(spec.objectsToJoint) do
1063 if object == node then
1064 return true
1065 end
1066 end
1067 end
1068
1069 return false
1070end

getIsPlayerInTensionBeltsRange

Description
Returns if player is in tension belt range
Definition
getIsPlayerInTensionBeltsRange()
Return Values
booleaninRangeplayer is in range
tablebeltnearest belt
Code
1017function TensionBelts:getIsPlayerInTensionBeltsRange()
1018
1019 if g_currentMission.player == nil then
1020 return false, nil
1021 end
1022
1023 if not g_currentMission.accessHandler:canPlayerAccess(self) then
1024 return false, nil
1025 end
1026
1027 local spec = self.spec_tensionBelts
1028
1029 local px, py, pz = getWorldTranslation(g_currentMission.player.rootNode)
1030 local vx, vy, vz = localToWorld(spec.interactionBaseNode, spec.interactionBasePointX, 0, spec.interactionBasePointZ)
1031 local currentBelt = nil
1032 local distance = math.huge
1033
1034 if MathUtil.vector3Length(px-vx, py-vy, pz-vz) < spec.totalInteractionRadius then
1035 if spec.tensionBelts ~= nil then
1036 for _, belt in pairs(spec.singleBelts) do
1037 local sx, sy, sz = getWorldTranslation(belt.startNode)
1038 local ex, ey, ez = getWorldTranslation(belt.endNode)
1039 local sDistance = MathUtil.vector3Length(px-sx, py-sy, pz-sz)
1040 local eDistance = MathUtil.vector3Length(px-ex, py-ey, pz-ez)
1041 if (sDistance < distance and sDistance < spec.interactionRadius) or (eDistance < distance and eDistance < spec.interactionRadius) then
1042 currentBelt = belt
1043 distance = math.min(sDistance, eDistance)
1044 end
1045 end
1046 end
1047
1048 if distance < spec.interactionRadius then
1049 return true, currentBelt
1050 end
1051 end
1052
1053 return false, nil
1054end

getIsReadyForAutomatedTrainTravel

Description
Definition
getIsReadyForAutomatedTrainTravel()
Code
1074function TensionBelts:getIsReadyForAutomatedTrainTravel(superFunc)
1075 local spec = self.spec_tensionBelts
1076 if spec.hasTensionBelts and spec.numObjectsIntensionBeltRange > 0 then
1077 return false
1078 end
1079
1080 return superFunc(self)
1081end

getObjectsToUnmount

Description
Returns objects to unmount if given belt will be removed
Definition
getObjectsToUnmount(table belt)
Arguments
tablebeltbelt to check
Return Values
tableobjectIdsToUnmounttable with object ids to unmount
integernumObjectsnumber of objects to unmount
Code
952function TensionBelts:getObjectsToUnmount(belt)
953 local spec = self.spec_tensionBelts
954
955 local objectIdsToUnmount = {}
956 local numObjects = 0
957 -- copy mounted objects table
958 for objectId, _ in pairs(spec.objectsToJoint) do
959 objectIdsToUnmount[objectId] = objectId
960 numObjects = numObjects + 1
961 end
962
963 -- remove objects mounted by other active belts
964 for _, otherBelt in pairs(spec.singleBelts) do
965 if otherBelt.mesh ~= nil and otherBelt ~= belt then
966 local objectToMount,_ = self:getObjectToMount(otherBelt)
967 for _, object in pairs(objectToMount) do
968 -- remove objects mounted by other belts
969 if objectIdsToUnmount[object.physics] ~= nil then
970 objectIdsToUnmount[object.physics] = nil
971 numObjects = numObjects - 1
972 end
973 end
974 end
975 end
976
977 return objectIdsToUnmount, numObjects
978end

getObjectToMount

Description
Returns objects in belt range
Definition
getObjectToMount(table belt)
Arguments
tablebeltbelt to check
Return Values
tableobjectsInTensionBeltRangeobject in belt range
integernumObjectsIntensionBeltRangenumber of objects in belt range
Code
850function TensionBelts:getObjectToMount(belt)
851 local spec = self.spec_tensionBelts
852
853 local markerStart = spec.startNode
854 local markerEnd = spec.endNode
855 local offsetLeft = nil
856 local offsetRight = nil
857 local offset = nil
858 local height = nil
859 if belt ~= nil then
860 markerStart = belt.startNode
861 markerEnd = belt.endNode
862
863 offsetLeft = belt.offsetLeft
864 offsetRight = belt.offsetRight
865 offset = belt.offset
866 height = belt.height
867 if offsetLeft == nil then
868 if spec.sortedBelts[belt.id-1] ~= nil and spec.sortedBelts[belt.id-1].mesh ~= nil then
869 local x,_,_ = localToLocal(markerStart, spec.sortedBelts[belt.id-1].startNode, 0, 0, 0)
870 offsetLeft = math.abs(x)
871 end
872 end
873 if offsetRight == nil then
874 if spec.sortedBelts[belt.id+1] ~= nil and spec.sortedBelts[belt.id+1].mesh ~= nil then
875 local x,_,_ = localToLocal(markerStart, spec.sortedBelts[belt.id+1].startNode, 0, 0, 0)
876 offsetRight = math.abs(x)
877 end
878 end
879
880 end
881
882 if offsetLeft == nil then
883 offsetLeft = spec.defaultOffsetSide
884 end
885 if offsetRight == nil then
886 offsetRight = spec.defaultOffsetSide
887 end
888 if offset == nil then
889 offset = spec.defaultOffset
890 end
891 if height == nil then
892 height = spec.defaultHeight
893 end
894
895 local sizeX = (offsetLeft+offsetRight) * 0.5
896 local sizeY = height * 0.5
897 local _, _, width = localToLocal(markerEnd, markerStart, 0, 0, 0)
898 local sizeZ = width*0.5 - 2*offset
899
900 local centerX = (offsetLeft-offsetRight)*0.5
901 local centerY = height*0.5
902 local centerZ = width*0.5
903 local x,y,z = localToWorld(markerStart, centerX, centerY, centerZ)
904
905 if TensionBelts.debugRendering then
906 local box = {}
907 box.points = {}
908 local colorR = math.random(0, 1)
909 local colorG = math.random(0, 1)
910 local colorB = math.random(0, 1)
911 box.color = {colorR,colorG,colorB}
912
913 local blx, bly, blz = localToWorld(markerStart, centerX-sizeX, centerY-sizeY, centerZ-sizeZ)
914 local brx, bry, brz = localToWorld(markerStart, centerX+sizeX, centerY-sizeY, centerZ-sizeZ)
915 local flx, fly, flz = localToWorld(markerStart, centerX-sizeX, centerY-sizeY, centerZ+sizeZ)
916 local frx, fry, frz = localToWorld(markerStart, centerX+sizeX, centerY-sizeY, centerZ+sizeZ)
917
918 local tblx, tbly, tblz = localToWorld(markerStart, centerX-sizeX, centerY+sizeY, centerZ-sizeZ)
919 local tbrx, tbry, tbrz = localToWorld(markerStart, centerX+sizeX, centerY+sizeY, centerZ-sizeZ)
920 local tflx, tfly, tflz = localToWorld(markerStart, centerX-sizeX, centerY+sizeY, centerZ+sizeZ)
921 local tfrx, tfry, tfrz = localToWorld(markerStart, centerX+sizeX, centerY+sizeY, centerZ+sizeZ)
922
923 table.insert(box.points, { blx, bly, blz } ) -- lower: lb
924 table.insert(box.points, { brx, bry, brz } ) -- rb
925 table.insert(box.points, { frx, fry, frz } ) -- rf
926 table.insert(box.points, { flx, fly, flz } ) -- lf
927
928 table.insert(box.points, { tblx, tbly, tblz } ) -- upper: lb
929 table.insert(box.points, { tbrx, tbry, tbrz } ) -- rb
930 table.insert(box.points, { tfrx, tfry, tfrz } ) -- rf
931 table.insert(box.points, { tflx, tfly, tflz } ) -- lf
932 table.insert(box.points, { x, y, z } ) -- center
933
934 spec.checkBoxes[markerStart] = box
935 end
936
937 local rx,ry,rz = getWorldRotation(markerStart)
938 spec.objectsInTensionBeltRange = {}
939 spec.numObjectsIntensionBeltRange = 0
940
941 -- collision mask : all bits except bit 13, 23, 30
942 overlapBox(x, y, z, rx, ry, rz, sizeX, sizeY, sizeZ, "objectOverlapCallback", self, 3212828671, true, false, true)
943
944 return spec.objectsInTensionBeltRange, spec.numObjectsIntensionBeltRange
945end

initSpecialization

Description
Definition
initSpecialization()
Code
67function TensionBelts.initSpecialization()
68 g_configurationManager:addConfigurationType("tensionBelts", g_i18n:getText("configuration_tensionBelts"), "tensionBelts", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
69end

lockTensionBeltObject

Description
Definition
lockTensionBeltObject()
Code
572function TensionBelts:lockTensionBeltObject(objectId, objectsToJointTable, isDynamic, jointNode, object)
573
574 if objectsToJointTable[objectId] == nil then
575 if isDynamic then
576 local constr = JointConstructor:new()
577 constr:setActors(jointNode, objectId)
578
579 -- create joint at center of mass to avoid jittering (e.g. tree trunks pivots are not at center of mass position)
580 -- create a transformGroup at the joint position to move the joint afterwards based on this transformGroup
581 local jointTransform = createTransformGroup("tensionBeltJoint")
582 link(self.spec_tensionBelts.linkNode, jointTransform)
583 local x,y,z = localToWorld(objectId, getCenterOfMass(objectId))
584 setWorldTranslation(jointTransform, x,y,z)
585 local rx,ry,rz = getWorldRotation(objectId)
586 setWorldRotation(jointTransform, rx,ry,rz)
587
588 constr:setJointTransforms(jointTransform, jointTransform)
589
590 constr:setRotationLimit(0, 0, 0)
591 constr:setRotationLimit(1, 0, 0)
592 constr:setRotationLimit(2, 0, 0)
593 local springForce = 7500
594 local springDamping = 1500
595 constr:setRotationLimitSpring(springForce, springDamping, springForce, springDamping, springForce, springDamping)
596 constr:setTranslationLimitSpring(springForce, springDamping, springForce, springDamping, springForce, springDamping)
597 local jointIndex = constr:finalize()
598
599 objectsToJointTable[objectId] = {jointIndex=jointIndex, jointTransform=jointTransform}
600
601 -- just testing, if enabled collisions have any benefit
602 --for obj, _ in pairs(objectsToJointTable) do
603 -- if obj ~= objectId then
604 -- setPairCollision(obj, objectId, false)
605 -- end
606 --end
607 else
608 local parentNode = getParent(objectId)
609 local x,y,z = localToLocal(objectId, jointNode, 0, 0, 0)
610 local a,b,c = localRotationToLocal(objectId, jointNode, 0, 0, 0)
611 setRigidBodyType(objectId, "Kinematic")
612 link(jointNode, objectId)
613 setTranslation(objectId, x, y, z)
614 setRotation(objectId, a, b, c)
615 objectsToJointTable[objectId] = {parent=parentNode}
616
617 if object ~= nil then
618 if object.components ~= nil then
619 for _, component in ipairs(object.components) do
620 if component.node == objectId then
621 component.isKinematic = true
622 component.isDynamic = false
623 end
624 end
625 end
626 end
627 end
628 end
629end

objectOverlapCallback

Description
Overlap callback
Definition
objectOverlapCallback(integer transformId)
Arguments
integertransformIdid of found transform
Code
983function TensionBelts:objectOverlapCallback(transformId)
984 if transformId ~= 0 and getHasClassId(transformId, ClassIds.SHAPE) then
985 local spec = self.spec_tensionBelts
986
987 local object = g_currentMission:getNodeObject(transformId)
988 if object ~= nil then
989 if object.getSupportsTensionBelts ~= nil and object:getSupportsTensionBelts() then
990 if object.getMeshNodes ~= nil and object.dynamicMountObject == nil then
991 local nodeId = object:getTensionBeltNodeId()
992 if spec.objectsInTensionBeltRange[nodeId] == nil then
993 local nodes = object:getMeshNodes()
994 if nodes ~= nil then
995 spec.objectsInTensionBeltRange[nodeId] = {physics=nodeId, visuals=nodes, object=object}
996 spec.numObjectsIntensionBeltRange = spec.numObjectsIntensionBeltRange + 1
997 end
998 end
999 end
1000 end
1001 elseif getSplitType(transformId) ~= 0 then
1002 local rigidBodyType = getRigidBodyType(transformId)
1003 if (rigidBodyType == "Dynamic" or rigidBodyType == "Kinematic") and spec.objectsInTensionBeltRange[transformId] == nil then
1004 spec.objectsInTensionBeltRange[transformId] = {physics=transformId, visuals={transformId}}
1005 spec.numObjectsIntensionBeltRange = spec.numObjectsIntensionBeltRange + 1
1006 end
1007 end
1008 end
1009
1010 return true
1011end

onDelete

Description
Called on deleting
Definition
onDelete()
Code
277function TensionBelts:onDelete()
278 local spec = self.spec_tensionBelts
279
280 spec.isPlayerInRange = false
281 g_currentMission:removeActivatableObject(spec.activatable)
282 self:setTensionBeltsActive(false, nil, true)
283
284 if spec.activationTrigger ~= nil then
285 removeTrigger(spec.activationTrigger)
286 spec.activationTrigger = nil
287 end
288end

onDraw

Description
Called on draw
Definition
onDraw(boolean isActiveForInput, boolean isSelected)
Arguments
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
489function TensionBelts:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
490 local spec = self.spec_tensionBelts
491
492 if not spec.hasTensionBelts then
493 return
494 end
495
496 if isActiveForInputIgnoreSelection and isSelected then
497 if spec.areBeltsFasten then
498 g_currentMission:addHelpButtonText(g_i18n:getText("action_unfastenTensionBelts"), InputBinding.TOGGLE_TENSION_BELTS, nil, GS_PRIO_NORMAL)
499 else
500 g_currentMission:addHelpButtonText(g_i18n:getText("action_fastenTensionBelts"), InputBinding.TOGGLE_TENSION_BELTS, nil, GS_PRIO_NORMAL)
501 end
502 end
503
504-- for _, d in pairs(spec.objectsToJoint) do
505-- local node = d.jointTransform
506-- DebugUtil.drawDebugNode(node, getName(node))
507-- end
508end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
74function TensionBelts:onLoad(savegame)
75 local spec = self.spec_tensionBelts
76
77 local tensionBeltConfigurationId = Utils.getNoNil(self.configurations["tensionBelts"], 1)
78 local configKey = string.format("vehicle.tensionBelts.tensionBeltsConfigurations.tensionBeltsConfiguration(%d).tensionBelts", tensionBeltConfigurationId -1)
79 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.tensionBelts.tensionBeltsConfigurations.tensionBeltsConfiguration", tensionBeltConfigurationId , self.components, self)
80
81
82 spec.hasTensionBelts = true
83 if not hasXMLProperty(self.xmlFile, configKey) then
84 spec.hasTensionBelts = false
85 return
86 end
87
88 spec.belts = {}
89 spec.activatable = TensionBeltsActivatable:new(self)
90
91 spec.totalInteractionRadius = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#totalInteractionRadius"), 6)
92 spec.interactionRadius = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#interactionRadius"), 1)
93 spec.interactionBaseNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, configKey.."#interactionBasenode"), self.i3dMappings), self.rootNode)
94 spec.activationTrigger = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, configKey.."#activationTrigger"), self.i3dMappings)
95 if spec.activationTrigger ~= nil then
96 addTrigger(spec.activationTrigger, "tensionBeltActivationTriggerCallback", self)
97 end
98
99 spec.isPlayerInTrigger = false
100 spec.checkSizeOffsets = {0*0.5, 5*0.5, 3*0.5}
101 spec.numObjectsIntensionBeltRange = 0
102
103 local tensionBeltType = Utils.getNoNil(getXMLString(self.xmlFile, configKey.."#tensionBeltType"), "basic")
104 local beltData = g_tensionBeltManager:getBeltData(tensionBeltType)
105
106 if beltData ~= nil then
107 spec.tensionBelts = {}
108 spec.singleBelts = {}
109 spec.sortedBelts = {}
110 spec.width = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#width"), 0.15)
111 spec.ratchetPosition = getXMLFloat(self.xmlFile, configKey.."#ratchetPosition")
112 spec.useHooks = Utils.getNoNil(getXMLBool(self.xmlFile, configKey.."#useHooks"), true)
113 spec.maxEdgeLength = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#maxEdgeLength"), 0.1)
114 spec.geometryBias = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#geometryBias"), 0.01)
115 spec.defaultOffsetSide = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#defaultOffsetSide"), 0.1)
116 spec.defaultOffset = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#defaultOffset"), 0)
117 spec.defaultHeight = Utils.getNoNil(getXMLFloat(self.xmlFile, configKey.."#defaultHeight"), 5)
118 spec.beltData = beltData
119 spec.linkNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, configKey.."#linkNode"), self.i3dMappings)
120 spec.rootNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, configKey.."#rootNode"), self.i3dMappings), self.components[1].node)
121 spec.jointNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, configKey.."#jointNode"), self.i3dMappings), spec.rootNode)
122 spec.checkTimerDuration = 500
123 spec.checkTimer = spec.checkTimerDuration
124
125 if getRigidBodyType(spec.jointNode) ~= "Dynamic" and getRigidBodyType(spec.jointNode) ~= "Kinematic" then
126 print("Error: Given jointNode '"..getName(spec.jointNode).."' has invalid rigidBodyType. Have to be 'Dynamic' or 'Kinematic'! Using '"..getName(self.components[1].node).."' instead!")
127 spec.jointNode = self.components[1].node
128 end
129
130 local rigidBodyType = getRigidBodyType(spec.jointNode)
131 spec.isDynamic = rigidBodyType == "Dynamic"
132
133 local x,y,z = localToLocal(spec.linkNode, spec.jointNode, 0,0,0)
134 local rx,ry,rz = localRotationToLocal(spec.linkNode, spec.jointNode, 0,0,0)
135 spec.linkNodePosition = {x, y, z}
136 spec.linkNodeRotation = {rx, ry, rz}
137
138 local i = 0
139 while true do
140 local key = string.format(configKey..".tensionBelt(%d)", i)
141 if not hasXMLProperty(self.xmlFile, key) then
142 break
143 end
144
145 if #spec.sortedBelts == 2^TensionBelts.NUM_SEND_BITS then
146 print("Warning: Max number of tension belts is ".. 2^TensionBelts.NUM_SEND_BITS.."!")
147 break
148 end
149
150 local startNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key.."#startNode"), self.i3dMappings)
151 local endNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key.."#endNode"), self.i3dMappings)
152 if startNode ~= nil and endNode ~= nil then
153 local x,y,_ = localToLocal(endNode, startNode, 0, 0, 0)
154
155 if math.abs(x) < 0.0001 and math.abs(y) < 0.0001 then
156 if spec.linkNode == nil then
157 spec.linkNode = getParent(startNode)
158 end
159 if spec.startNode == nil then
160 spec.startNode = startNode
161 end
162 spec.endNode = endNode
163
164 local offsetLeft = getXMLFloat(self.xmlFile, key.."#offsetLeft")
165 local offsetRight = getXMLFloat(self.xmlFile, key.."#offsetRight")
166 local offset = getXMLFloat(self.xmlFile, key.."#offset")
167 local height = getXMLFloat(self.xmlFile, key.."#height")
168
169 local intersectionNodes = {}
170 local j = 0
171 while true do
172 local intersectionKey = string.format(key..".intersectionNode(%d)", j)
173 if not hasXMLProperty(self.xmlFile, intersectionKey) then
174 break
175 end
176 local node = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, intersectionKey.."#node"), self.i3dMappings)
177 if node ~= nil then
178 table.insert(intersectionNodes, node)
179 end
180 j = j + 1
181 end
182
183 local belt = {id=i+1, startNode=startNode, endNode=endNode, offsetLeft=offsetLeft, offsetRight=offsetRight, offset=offset, height=height, mesh=nil, intersectionNodes=intersectionNodes, dummy=nil, objectsToMount=nil}
184 spec.singleBelts[belt] = belt
185 table.insert(spec.sortedBelts, belt)
186 else
187 print("Warning: x and y position of endNode need to be 0 for tension belt '"..key.."' in '"..self.configFileName.."'!")
188 end
189 end
190
191 i = i + 1
192 end
193
194 local minX, minZ = math.huge, math.huge
195 local maxX, maxZ = -math.huge, -math.huge
196 for _, belt in pairs(spec.singleBelts) do
197 local sx,_,sz = localToLocal(belt.startNode, spec.interactionBaseNode, 0, 0, 0)
198 local ex,_,ez = localToLocal(belt.endNode, spec.interactionBaseNode, 0, 0, 0)
199 minX = math.min(minX, sx, ex)
200 minZ = math.min(minZ, sz, ez)
201 maxX = math.max(maxX, sx, ex)
202 maxZ = math.max(maxZ, sz, ez)
203 end
204
205 spec.interactionBasePointX = (maxX + minX) / 2
206 spec.interactionBasePointZ = (maxZ + minZ) / 2
207
208 for _, belt in pairs(spec.singleBelts) do
209 local sx,_,sz = localToLocal(belt.startNode, spec.interactionBaseNode, 0, 0, 0)
210 local sl = MathUtil.vector2Length(spec.interactionBasePointX-sx, spec.interactionBasePointZ-sz)+1
211 local el = MathUtil.vector2Length(spec.interactionBasePointX-sx, spec.interactionBasePointZ-sz)+1
212 spec.totalInteractionRadius = math.max(spec.totalInteractionRadius, sl, el)
213 end
214
215 spec.hasTensionBelts = #spec.sortedBelts > 0
216 else
217 print("Warning: No belt data found for tension belts in '"..self.configFileName.."'!")
218 end
219
220 spec.checkBoxes = {}
221 spec.objectsToJoint = {}
222 spec.isPlayerInRange = false
223 spec.currentBelt = nil
224 spec.areBeltsFasten = false
225end

onPostLoad

Description
Called after loading
Definition
onPostLoad(table savegame)
Arguments
tablesavegamesavegame
Code
230function TensionBelts:onPostLoad(savegame)
231 if savegame ~= nil then
232 local spec = self.spec_tensionBelts
233
234 spec.beltsToLoad = {}
235 local i = 0
236 while true do
237 local key = string.format("%s.tensionBelts.belt(%d)", savegame.key, i)
238 if not hasXMLProperty(savegame.xmlFile, key) then
239 break
240 end
241 if getXMLBool(savegame.xmlFile, key.."#isActive") then
242 table.insert(spec.beltsToLoad, i+1)
243 end
244 i = i + 1
245 end
246 end
247end

onPreDelete

Description
Definition
onPreDelete()
Code
264function TensionBelts:onPreDelete()
265 if self.spec_tensionBelts.sortedBelts ~= nil then
266 for _, belt in pairs(self.spec_tensionBelts.sortedBelts) do
267 local objects, _ = self:getObjectToMount(belt)
268 for id, _ in pairs(objects) do
269 I3DUtil.wakeUpObject(id)
270 end
271 end
272 end
273end

onReadStream

Description
Called on client side on join
Definition
onReadStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
294function TensionBelts:onReadStream(streamId, connection)
295 local spec = self.spec_tensionBelts
296
297 if not spec.hasTensionBelts then
298 return
299 end
300 if spec.tensionBelts ~= nil then
301 spec.beltsToLoad = {}
302 for k, _ in ipairs(spec.sortedBelts) do
303 local beltActive = streamReadBool(streamId)
304 if beltActive then
305 table.insert(spec.beltsToLoad, k)
306 end
307 end
308 end
309end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
1091function TensionBelts:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
1092 local spec = self.spec_tensionBelts
1093 if self.isClient and spec.hasTensionBelts then
1094 self:clearActionEventsTable(spec.actionEvents)
1095
1096 if isActiveForInputIgnoreSelection then
1097 local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_TENSION_BELTS, self, TensionBelts.actionEventToggleTensionBelts, false, true, false, true, nil)
1098 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
1099 end
1100 end
1101end

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
333function TensionBelts:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
334 local spec = self.spec_tensionBelts
335
336 if not spec.hasTensionBelts then
337 return
338 end
339
340 if spec.beltsToLoad ~= nil then
341 for _, k in pairs(spec.beltsToLoad) do
342 local noEventSend = false
343 if not self.isServer then
344 -- do not resend event to server after sync. Only send event after loading to make sure client have visible tension belts
345 noEventSend = true
346 end
347 self:setTensionBeltsActive(true, spec.sortedBelts[k].id, noEventSend)
348 end
349 spec.beltsToLoad = nil
350 end
351
352 if self.isServer and spec.isDynamic then
353 local x,y,z = localToLocal(spec.linkNode, spec.jointNode, 0,0,0)
354 local rx,ry,rz = localRotationToLocal(spec.linkNode, spec.jointNode, 0,0,0)
355
356 local isDirty = false
357 if math.abs(x - spec.linkNodePosition[1]) > 0.001 or math.abs(y - spec.linkNodePosition[2]) > 0.001 or math.abs(z - spec.linkNodePosition[3]) > 0.001 or
358 math.abs(rx - spec.linkNodeRotation[1]) > 0.001 or math.abs(ry - spec.linkNodeRotation[2]) > 0.001 or math.abs(rz - spec.linkNodeRotation[3]) > 0.001 then
359 isDirty = true
360 end
361 if isDirty then
362 spec.linkNodePosition[1], spec.linkNodePosition[2], spec.linkNodePosition[3] = x, y, z
363 spec.linkNodeRotation[1], spec.linkNodeRotation[2], spec.linkNodeRotation[3] = rx, ry, rz
364 for _, joint in pairs(spec.objectsToJoint) do
365 setJointFrame(joint.jointIndex, 0, joint.jointTransform)
366 end
367 end
368 end
369
370 if TensionBelts.debugRendering then
371 for belt,_ in pairs(spec.belts) do
372 DebugUtil.drawDebugNode(belt)
373 for i=0, getNumOfChildren(belt)-1 do
374 DebugUtil.drawDebugNode(getChildAt(belt, i))
375 end
376 end
377
378 if spec.checkBoxes ~= nil then
379 for _, box in pairs(spec.checkBoxes) do
380 local p = box.points
381 local c = box.color
382
383 -- bottom
384 drawDebugLine(p[1][1],p[1][2],p[1][3], c[1],c[2],c[3], p[2][1],p[2][2],p[2][3], c[1],c[2],c[3])
385 drawDebugLine(p[2][1],p[2][2],p[2][3], c[1],c[2],c[3], p[3][1],p[3][2],p[3][3], c[1],c[2],c[3])
386 drawDebugLine(p[3][1],p[3][2],p[3][3], c[1],c[2],c[3], p[4][1],p[4][2],p[4][3], c[1],c[2],c[3])
387 drawDebugLine(p[4][1],p[4][2],p[4][3], c[1],c[2],c[3], p[1][1],p[1][2],p[1][3], c[1],c[2],c[3])
388 -- top
389 drawDebugLine(p[5][1],p[5][2],p[5][3], c[1],c[2],c[3], p[6][1],p[6][2],p[6][3], c[1],c[2],c[3])
390 drawDebugLine(p[6][1],p[6][2],p[6][3], c[1],c[2],c[3], p[7][1],p[7][2],p[7][3], c[1],c[2],c[3])
391 drawDebugLine(p[7][1],p[7][2],p[7][3], c[1],c[2],c[3], p[8][1],p[8][2],p[8][3], c[1],c[2],c[3])
392 drawDebugLine(p[8][1],p[8][2],p[8][3], c[1],c[2],c[3], p[5][1],p[5][2],p[5][3], c[1],c[2],c[3])
393 -- left
394 drawDebugLine(p[1][1],p[1][2],p[1][3], c[1],c[2],c[3], p[5][1],p[5][2],p[5][3], c[1],c[2],c[3])
395 drawDebugLine(p[4][1],p[4][2],p[4][3], c[1],c[2],c[3], p[8][1],p[8][2],p[8][3], c[1],c[2],c[3])
396 -- right
397 drawDebugLine(p[2][1],p[2][2],p[2][3], c[1],c[2],c[3], p[6][1],p[6][2],p[6][3], c[1],c[2],c[3])
398 drawDebugLine(p[3][1],p[3][2],p[3][3], c[1],c[2],c[3], p[7][1],p[7][2],p[7][3], c[1],c[2],c[3])
399 drawDebugPoint(p[9][1], p[9][2], p[9][3], 1, 1, 1, 1)
400 end
401 end
402
403 local a,b,c = localToWorld(spec.interactionBaseNode, spec.interactionBasePointX, 0, spec.interactionBasePointZ)
404 drawDebugPoint(a,b,c, 0,0,1, 1,1,1,1)
405
406 for i=0, 360-10, 10 do
407 local x,y,z = localToWorld(spec.interactionBaseNode, spec.interactionBasePointX+math.cos(math.rad(i))*spec.totalInteractionRadius,0, spec.interactionBasePointZ+math.sin(math.rad(i))*spec.totalInteractionRadius)
408 drawDebugPoint(x, y, z, 1,1,1,1)
409 for _, belt in pairs(spec.singleBelts) do
410 local x,y,z = localToWorld(belt.startNode, math.cos(math.rad(i))*spec.interactionRadius, 0, math.sin(math.rad(i))*spec.interactionRadius)
411 drawDebugPoint(x, y, z, 0,1,0,1)
412 local x,y,z = localToWorld(belt.endNode, math.cos(math.rad(i))*spec.interactionRadius, 0, math.sin(math.rad(i))*spec.interactionRadius)
413 drawDebugPoint(x, y, z, 1,0,0,1)
414 end
415 end
416 end
417
418 if spec.isPlayerInTrigger or spec.isPlayerInRange then
419 self:raiseActive()
420 end
421
422 -- create tension belt preview and control activation
423 local currentBelt = nil
424 local wasInRange = spec.isPlayerInRange
425 spec.isPlayerInRange, currentBelt = self:getIsPlayerInTensionBeltsRange()
426 if spec.isPlayerInRange then
427 if currentBelt ~= spec.currentBelt then
428 if spec.currentBelt ~= nil and spec.currentBelt.dummy ~= nil then
429 delete(spec.currentBelt.dummy)
430 spec.currentBelt.dummy = nil
431 end
432 spec.currentBelt = currentBelt
433
434 if spec.currentBelt ~= nil and spec.currentBelt.mesh == nil then
435 local objects, _ = self:getObjectToMount(spec.currentBelt)
436 self:createTensionBelt(spec.currentBelt, true, objects)
437 end
438 end
439 g_currentMission:addActivatableObject(spec.activatable)
440 else
441 if wasInRange then
442 g_currentMission:removeActivatableObject(spec.activatable)
443 if spec.currentBelt ~= nil and spec.currentBelt.dummy ~= nil then
444 delete(spec.currentBelt.dummy)
445 spec.currentBelt.dummy = nil
446 spec.currentBelt = nil
447 end
448 end
449 end
450end

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
457function TensionBelts:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
458 local spec = self.spec_tensionBelts
459
460 if not spec.hasTensionBelts then
461 return
462 end
463
464 if self.isServer and spec.tensionBelts ~= nil then
465 spec.checkTimer = spec.checkTimer - dt
466 if spec.checkTimer < 0 then
467 -- check if entities have been deleted
468 local needUpdate = false
469 for phyiscObject, _ in pairs(spec.objectsToJoint) do
470 if not entityExists(phyiscObject) then
471 spec.objectsToJoint[phyiscObject] = nil
472 needUpdate = true
473 break
474 end
475 end
476 if needUpdate then
477 self:refreshTensionBelts()
478 end
479
480 spec.checkTimer = spec.checkTimerDuration
481 end
482 end
483end

onWriteStream

Description
Called on server side on join
Definition
onWriteStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
315function TensionBelts:onWriteStream(streamId, connection)
316 local spec = self.spec_tensionBelts
317
318 if not spec.hasTensionBelts then
319 return
320 end
321 if spec.tensionBelts ~= nil then
322 for _, belt in ipairs(spec.sortedBelts) do
323 streamWriteBool(streamId, belt.mesh ~= nil)
324 end
325 end
326end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
21function TensionBelts.prerequisitesPresent(specializations)
22 return true
23end

refreshTensionBelts

Description
Definition
refreshTensionBelts()
Code
512function TensionBelts:refreshTensionBelts()
513 if self.isServer then
514 if g_server ~= nil then
515 g_server:broadcastEvent(TensionBeltsRefreshEvent:new(self), nil, nil, self)
516 end
517 end
518 for _, belt in pairs(self.spec_tensionBelts.sortedBelts) do
519 if belt.mesh ~= nil then
520 self:removeTensionBelt(belt)
521 local objects, _ = self:getObjectToMount(belt)
522 self:createTensionBelt(belt, false, objects)
523 end
524 end
525end

registerEventListeners

Description
Definition
registerEventListeners()
Code
52function TensionBelts.registerEventListeners(vehicleType)
53 SpecializationUtil.registerEventListener(vehicleType, "onLoad", TensionBelts)
54 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", TensionBelts)
55 SpecializationUtil.registerEventListener(vehicleType, "onDelete", TensionBelts)
56 SpecializationUtil.registerEventListener(vehicleType, "onPreDelete", TensionBelts)
57 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", TensionBelts)
58 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", TensionBelts)
59 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", TensionBelts)
60 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", TensionBelts)
61 SpecializationUtil.registerEventListener(vehicleType, "onDraw", TensionBelts)
62 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", TensionBelts)
63end

registerFunctions

Description
Definition
registerFunctions()
Code
27function TensionBelts.registerFunctions(vehicleType)
28 SpecializationUtil.registerFunction(vehicleType, "createTensionBelt", TensionBelts.createTensionBelt)
29 SpecializationUtil.registerFunction(vehicleType, "removeTensionBelt", TensionBelts.removeTensionBelt)
30 SpecializationUtil.registerFunction(vehicleType, "setTensionBeltsActive", TensionBelts.setTensionBeltsActive)
31 SpecializationUtil.registerFunction(vehicleType, "objectOverlapCallback", TensionBelts.objectOverlapCallback)
32 SpecializationUtil.registerFunction(vehicleType, "getObjectToMount", TensionBelts.getObjectToMount)
33 SpecializationUtil.registerFunction(vehicleType, "getObjectsToUnmount", TensionBelts.getObjectsToUnmount)
34 SpecializationUtil.registerFunction(vehicleType, "updateFastenState", TensionBelts.updateFastenState)
35 SpecializationUtil.registerFunction(vehicleType, "refreshTensionBelts", TensionBelts.refreshTensionBelts)
36 SpecializationUtil.registerFunction(vehicleType, "freeTensionBeltObject", TensionBelts.freeTensionBeltObject)
37 SpecializationUtil.registerFunction(vehicleType, "lockTensionBeltObject", TensionBelts.lockTensionBeltObject)
38 SpecializationUtil.registerFunction(vehicleType, "getIsPlayerInTensionBeltsRange", TensionBelts.getIsPlayerInTensionBeltsRange)
39 SpecializationUtil.registerFunction(vehicleType, "getIsDynamicallyMountedNode", TensionBelts.getIsDynamicallyMountedNode)
40 SpecializationUtil.registerFunction(vehicleType, "tensionBeltActivationTriggerCallback", TensionBelts.tensionBeltActivationTriggerCallback)
41end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
45function TensionBelts.registerOverwrittenFunctions(vehicleType)
46 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsReadyForAutomatedTrainTravel", TensionBelts.getIsReadyForAutomatedTrainTravel)
47 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", TensionBelts.getCanBeSelected)
48end

removeTensionBelt

Description
Remove tension belt
Definition
removeTensionBelt(table belt)
Arguments
tablebeltbelt to remove
Code
832function TensionBelts:removeTensionBelt(belt)
833 if belt.mesh ~= nil then
834 local spec = self.spec_tensionBelts
835
836 spec.belts[belt.mesh] = nil
837 delete(belt.mesh)
838 belt.mesh = nil
839 if spec.currentBelt == belt then
840 spec.currentBelt = nil
841 end
842 end
843end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
251function TensionBelts:saveToXMLFile(xmlFile, key, usedModNames)
252 local spec = self.spec_tensionBelts
253
254 if spec.hasTensionBelts then
255 for i, belt in ipairs(spec.sortedBelts) do
256 local beltKey = string.format("%s.belt(%d)", key, i-1)
257 setXMLBool(xmlFile, beltKey.."#isActive", belt.mesh ~= nil)
258 end
259 end
260end

setTensionBeltsActive

Description
Set tensionbelts active state
Definition
setTensionBeltsActive(boolean isActive, integer beltId)
Arguments
booleanisActivenew active state
integerbeltIdid of belt to set state (if id is nil it uses every belt)
Code
635function TensionBelts:setTensionBeltsActive(isActive, beltId, noEventSend)
636 local spec = self.spec_tensionBelts
637
638 if spec.tensionBelts ~= nil then
639 TensionBeltsEvent.sendEvent(self, isActive, beltId, noEventSend)
640
641 local belt = nil
642 if beltId ~= nil then
643 belt = spec.sortedBelts[beltId]
644 end
645
646 if isActive then
647 local objects, _ = self:getObjectToMount(belt)
648 if belt == nil then
649 for _, belt in pairs(spec.singleBelts) do
650 if belt.mesh == nil then
651 self:createTensionBelt(belt, false, objects)
652 end
653 end
654 else
655 if belt.mesh == nil then
656 self:createTensionBelt(belt, false, objects)
657 end
658 end
659
660 if self.isServer then
661 for _, data in pairs(objects) do
662 self:lockTensionBeltObject(data.physics, spec.objectsToJoint, spec.isDynamic, spec.jointNode, data.object)
663 if data.object ~= nil then
664 data.object.tensionMountObject = self
665 end
666 end
667 else
668 for _, data in pairs(objects) do
669 if data.object ~= nil then
670 data.object.tensionMountObject = self
671 end
672 end
673 end
674 else
675 if belt == nil then
676 for _, belt in pairs(spec.singleBelts) do
677 self:removeTensionBelt(belt)
678 end
679 else
680 self:removeTensionBelt(belt)
681 end
682
683 if self.isServer then
684 -- remove joints
685 local objectIds, _ = self:getObjectsToUnmount(belt)
686 for _, objectId in pairs(objectIds) do
687 self:freeTensionBeltObject(objectId, spec.objectsToJoint, spec.isDynamic)
688 end
689 end
690
691 local objects, _ = self:getObjectToMount(belt)
692 for _, data in pairs(objects) do
693 if data.object ~= nil then
694 data.object.tensionMountObject = nil
695
696 if self.isServer then
697 if data.object.components ~= nil then
698 for _, component in ipairs(data.object.components) do
699 if component.node == data.physics then
700 component.isKinematic = false
701 component.isDynamic = true
702 end
703 end
704 end
705 end
706 end
707 end
708 end
709
710 self:updateFastenState()
711 end
712end

tensionBeltActivationTriggerCallback

Description
Definition
tensionBeltActivationTriggerCallback()
Code
1105function TensionBelts:tensionBeltActivationTriggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId)
1106 local spec = self.spec_tensionBelts
1107 if self.isClient and spec.hasTensionBelts then
1108 if onEnter or onLeave then
1109 if g_currentMission.player ~= nil and otherActorId == g_currentMission.player.rootNode then
1110 if onEnter then
1111 self:raiseActive()
1112 spec.isPlayerInTrigger = true
1113 else
1114 spec.isPlayerInTrigger = false
1115 end
1116 end
1117 end
1118 end
1119end

updateFastenState

Description
Update 'self.areBeltsFasten'
Definition
updateFastenState()
Code
716function TensionBelts:updateFastenState()
717 local spec = self.spec_tensionBelts
718
719 local unfastenBelts = false
720 for _, belt in pairs(spec.singleBelts) do
721 if belt.mesh == nil then
722 unfastenBelts = true
723 break
724 end
725 end
726
727 spec.areBeltsFasten = not unfastenBelts
728end