LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

Attachable

Description
Specialization for vehicles that may be attached to another vehicle
Functions

attachableAddToolCameras

Description
Add tool cameras to root attacher vehicle
Definition
attachableAddToolCameras()
Code
834function Attachable:attachableAddToolCameras()
835 local spec = self.spec_attachable
836
837 if #spec.toolCameras > 0 then
838 local rootAttacherVehicle = self:getRootVehicle()
839 if rootAttacherVehicle ~= nil then
840 if rootAttacherVehicle.addToolCameras ~= nil then
841 rootAttacherVehicle:addToolCameras(spec.toolCameras)
842 end
843 end
844 end
845end

attachableRemoveToolCameras

Description
Remove tool cameras from root attacher vehicle
Definition
attachableRemoveToolCameras()
Code
849function Attachable:attachableRemoveToolCameras()
850 local spec = self.spec_attachable
851
852 if #spec.toolCameras > 0 then
853 local rootAttacherVehicle = self:getRootVehicle()
854 if rootAttacherVehicle ~= nil then
855 if rootAttacherVehicle.removeToolCameras ~= nil then
856 rootAttacherVehicle:removeToolCameras(spec.toolCameras)
857 end
858 end
859 end
860end

getActiveFarm

Description
Definition
getActiveFarm()
Code
1215function Attachable:getActiveFarm(superFunc)
1216 local spec = self.spec_attachable
1217
1218 -- Some vehicles can both be attached and entered. Entering takes precedence.
1219 if self.spec_enterable ~= nil and self.spec_enterable.controllerFarmId ~= 0 then
1220 return superFunc(self)
1221 end
1222
1223 if spec.attacherVehicle ~= nil then
1224 return spec.attacherVehicle:getActiveFarm()
1225 else
1226 return superFunc(self)
1227 end
1228end

getActiveInputAttacherJoint

Description
Definition
getActiveInputAttacherJoint()
Code
689function Attachable:getActiveInputAttacherJoint()
690 return self.spec_attachable.attacherJoint
691end

getActiveInputAttacherJointDescIndex

Description
Definition
getActiveInputAttacherJointDescIndex()
Code
683function Attachable:getActiveInputAttacherJointDescIndex()
684 return self.spec_attachable.inputAttacherJointDescIndex
685end

getAllowsLowering

Description
Returns true if tool can be lowered
Definition
getAllowsLowering()
Return Values
booleandetachAlloweddetach is allowed
stringwarning[optional] warning text to display
Code
697function Attachable:getAllowsLowering()
698 local inputAttacherJoint = self:getActiveInputAttacherJoint()
699 if inputAttacherJoint ~= nil then
700 if not inputAttacherJoint.allowsLowering then
701 return false, nil
702 end
703 end
704
705 return true, nil
706end

getAttachbleAirConsumerUsage

Description
Returns air consumer usage
Definition
getAttachbleAirConsumerUsage()
Return Values
floatusageusage
Code
760function Attachable:getAttachbleAirConsumerUsage()
761 return self.spec_attachable.airConsumerUsage
762end

getAttacherVehicle

Description
Definition
getAttacherVehicle()
Code
652function Attachable:getAttacherVehicle()
653 return self.spec_attachable.attacherVehicle
654end

getBrakeForce

Description
Definition
getBrakeForce()
Code
1137function Attachable:getBrakeForce(superFunc)
1138 local brakeForce = superFunc(self)
1139 return math.max(brakeForce, self.spec_attachable.brakeForce)
1140end

getCanAIImplementContinueWork

Description
Returns true if vehicle is ready for ai work
Definition
getCanAIImplementContinueWork()
Return Values
booleanisReadyis ready for ai work
Code
1194function Attachable:getCanAIImplementContinueWork(superFunc)
1195 local spec = self.spec_attachable
1196
1197 local isReady = true
1198 if spec.lowerAnimation ~= nil then
1199 local time = self:getAnimationTime(spec.lowerAnimation)
1200 isReady = time == 1 or time == 0
1201 end
1202
1203 local jointDesc = spec.attacherVehicle:getAttacherJointDescFromObject(self)
1204 if jointDesc.allowsLowering and self:getAINeedsLowering() then
1205 if jointDesc.moveDown then
1206 isReady = (jointDesc.moveAlpha == jointDesc.lowerAlpha or jointDesc.moveAlpha == jointDesc.upperAlpha) and isReady
1207 end
1208 end
1209
1210 return isReady
1211end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
1232function Attachable:getCanBeSelected(superFunc)
1233 return true
1234end

getCanToggleTurnedOn

Description
Definition
getCanToggleTurnedOn()
Code
1164function Attachable:getCanToggleTurnedOn(superFunc)
1165 local attacherVehicle = self:getAttacherVehicle()
1166 if attacherVehicle ~= nil then
1167 local jointDesc = attacherVehicle:getAttacherJointDescFromObject(self)
1168 if jointDesc ~= nil then
1169 if not jointDesc.canTurnOnImplement then
1170 return false
1171 end
1172 end
1173 end
1174
1175 return superFunc(self)
1176end

getDeactivateOnLeave

Description
Definition
getDeactivateOnLeave()
Code
1180function Attachable:getDeactivateOnLeave(superFunc)
1181 local attacherVehicle = self:getAttacherVehicle()
1182 if attacherVehicle ~= nil then
1183 if not attacherVehicle:getDeactivateOnLeave() then
1184 return false
1185 end
1186 end
1187
1188 return superFunc(self)
1189end

getInputAttacherJointByJointDescIndex

Description
Definition
getInputAttacherJointByJointDescIndex()
Code
646function Attachable:getInputAttacherJointByJointDescIndex(index)
647 return self.spec_attachable.inputAttacherJoints[index]
648end

getInputAttacherJoints

Description
Definition
getInputAttacherJoints()
Code
658function Attachable:getInputAttacherJoints()
659 return self.spec_attachable.inputAttacherJoints
660end

getIsActive

Description
Definition
getIsActive()
Code
1109function Attachable:getIsActive(superFunc)
1110 if superFunc(self) then
1111 return true
1112 end
1113 local spec = self.spec_attachable
1114 if spec.attacherVehicle ~= nil then
1115 return spec.attacherVehicle:getIsActive()
1116 end
1117 return false
1118end

getIsAttachedTo

Description
Definition
getIsAttachedTo()
Code
664function Attachable:getIsAttachedTo(vehicle)
665 if vehicle == self then
666 return true
667 end
668
669 local spec = self.spec_attachable
670 if spec.attacherVehicle ~= nil then
671 if spec.attacherVehicle == vehicle then
672 return true
673 end
674 if spec.attacherVehicle.getIsAttachedTo ~= nil then
675 return spec.attacherVehicle:getIsAttachedTo(vehicle)
676 end
677 end
678 return false
679end

getIsFoldAllowed

Description
Definition
getIsFoldAllowed()
Code
1144function Attachable:getIsFoldAllowed(superFunc, direction, onAiTurnOn)
1145 local spec = self.spec_attachable
1146
1147 if not spec.allowFoldingWhileAttached then
1148 if self:getAttacherVehicle() ~= nil then
1149 return false
1150 end
1151 end
1152
1153 if not spec.allowFoldingWhileLowered then
1154 if self:getIsLowered() then
1155 return false
1156 end
1157 end
1158
1159 return superFunc(self)
1160end

getIsImplementChainLowered

Description
Returns true if vehicle itself is lowered and all parent vehicles are lowered until the first vehicle is not attachable (e.g. all implements until a tractor is in the chain)
Definition
getIsImplementChainLowered(boolean defaultIsLowered)
Arguments
booleandefaultIsLowereddefault value if lowering is not allowed
Return Values
booleanisLoweredimplement chain is lowered
Code
731function Attachable:getIsImplementChainLowered(defaultIsLowered)
732 if not self:getIsLowered(defaultIsLowered) then
733 return false
734 end
735
736 local attacherVehicle = self:getAttacherVehicle()
737 if attacherVehicle ~= nil then
738 if attacherVehicle.getAllowsLowering ~= nil then
739 if attacherVehicle:getAllowsLowering() then
740 if not attacherVehicle:getIsImplementChainLowered(defaultIsLowered) then
741 return false
742 end
743 end
744 end
745 end
746
747 return true
748end

getIsInputAttacherActive

Description
Returns true if input attacher is active and can be used to attach
Definition
getIsInputAttacherActive(table inputAttacherJoint)
Arguments
tableinputAttacherJointinput attacher joint
Return Values
booleanisActiveinput attacher is active
Code
792function Attachable:getIsInputAttacherActive(inputAttacherJoint)
793 return true
794end

getIsInUse

Description
Definition
getIsInUse()
Code
1278function Attachable:getIsInUse(superFunc, connection)
1279 local spec = self.spec_attachable
1280 local attacherVehicle = self:getAttacherVehicle()
1281 if attacherVehicle ~= nil then
1282 return attacherVehicle:getIsInUse(connection)
1283 end
1284
1285 return superFunc(self, connection)
1286end

getIsInWorkPosition

Description
Returns true if it is in work position
Definition
getIsInWorkPosition()
Return Values
booleaninWorkPositionis in work position
Code
753function Attachable:getIsInWorkPosition()
754 return true
755end

getIsLowered

Description
Definition
getIsLowered()
Code
1238function Attachable:getIsLowered(superFunc, defaultIsLowered)
1239 local attacherVehicle = self:getAttacherVehicle()
1240 if attacherVehicle ~= nil then
1241 local jointDesc = attacherVehicle:getAttacherJointDescFromObject(self)
1242 if jointDesc.allowsLowering or jointDesc.isDefaultLowered then
1243 return jointDesc.moveDown
1244 else
1245 return defaultIsLowered
1246 end
1247 end
1248
1249 return superFunc(self, defaultIsLowered)
1250end

getIsOperating

Description
Returns if vehicle is operating
Definition
getIsOperating()
Return Values
booleanisOperatingis operating
Code
1123function Attachable:getIsOperating(superFunc)
1124 local spec = self.spec_attachable
1125
1126 local isOperating = superFunc(self)
1127
1128 if not isOperating and spec.attacherVehicle ~= nil then
1129 isOperating = spec.attacherVehicle:getIsOperating()
1130 end
1131
1132 return isOperating
1133end

getIsSteeringAxleAllowed

Description
Returns if steering axle is allowed to adjust
Definition
getIsSteeringAxleAllowed()
Code
828function Attachable:getIsSteeringAxleAllowed()
829 return true
830end

getIsSupportAnimationAllowed

Description
Returns if support animation is allowed to play
Definition
getIsSupportAnimationAllowed()
Code
723function Attachable:getIsSupportAnimationAllowed(supportAnimation)
724 return self.playAnimation ~= nil
725end

getLoweringActionEventState

Description
Definition
getLoweringActionEventState()
Code
1049function Attachable:getLoweringActionEventState()
1050 local showLower = false
1051
1052 local attacherVehicle = self:getAttacherVehicle()
1053 if attacherVehicle ~= nil then
1054 local jointDesc = attacherVehicle:getAttacherJointDescFromObject(self)
1055 local inputJointDesc = self:getActiveInputAttacherJoint()
1056 showLower = jointDesc.allowsLowering and inputJointDesc.allowsLowering
1057 end
1058
1059 local text
1060 if self:getIsLowered() then
1061 text = string.format(g_i18n:getText("action_liftOBJECT"), self.typeDesc)
1062 else
1063 text = string.format(g_i18n:getText("action_lowerOBJECT"), self.typeDesc)
1064 end
1065
1066 return showLower, text
1067end

getOwner

Description
Definition
getOwner()
Code
1266function Attachable:getOwner(superFunc)
1267 local spec = self.spec_attachable
1268
1269 if spec.attacherVehicle ~= nil then
1270 return spec.attacherVehicle:getOwner()
1271 end
1272
1273 return superFunc(self)
1274end

getRootVehicle

Description
Definition
getRootVehicle()
Code
1098function Attachable:getRootVehicle(superFunc)
1099 local spec = self.spec_attachable
1100 if spec.attacherVehicle ~= nil then
1101 return spec.attacherVehicle:getRootVehicle()
1102 end
1103
1104 return superFunc(self)
1105end

getSteeringAxleBaseVehicle

Description
Returns vehicle used to calculate steering axle
Definition
getSteeringAxleBaseVehicle()
Code
798function Attachable:getSteeringAxleBaseVehicle()
799 local spec = self.spec_attachable
800
801 if spec.steeringAxleUseSuperAttachable then
802 if spec.attacherVehicle ~= nil then
803 if spec.attacherVehicle.getAttacherVehicle ~= nil then
804 return spec.attacherVehicle:getAttacherVehicle()
805 end
806 end
807 end
808
809 return spec.attacherVehicle
810end

initSpecialization

Description
Definition
initSpecialization()
Code
106function Attachable.initSpecialization()
107 g_configurationManager:addConfigurationType("inputAttacherJoint", g_i18n:getText("configuration_inputAttacherJoint"), "attachable", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
108end

isDetachAllowed

Description
Returns true if detach is allowed
Definition
isDetachAllowed()
Return Values
booleandetachAlloweddetach is allowed
stringwarning[optional] warning text to display
Code
768function Attachable:isDetachAllowed()
769 local spec = self.spec_attachable
770 if spec.attacherJoint ~= nil then
771 if spec.attacherJoint.allowsDetaching == false then
772 return false, nil, false
773 end
774 end
775
776 -- block detach while the attaching is still in progress
777 local attacherVehicle = self:getAttacherVehicle()
778 if attacherVehicle ~= nil then
779 local implement = attacherVehicle:getImplementByObject(self)
780 if implement ~= nil and implement.attachingIsInProgress then
781 return false
782 end
783 end
784
785 return true, nil
786end

loadInputAttacherJoint

Description
Called on loading
Definition
loadInputAttacherJoint(table savegame)
Arguments
tablesavegamesavegame
Code
435function Attachable:loadInputAttacherJoint(xmlFile, key, inputAttacherJoint, index)
436 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. "#index", key .. "#node") -- FS17 to FS19
437 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. "#indexVisual", key .. "#nodeVisual") -- FS17 to FS19
438 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. "#ptoInputNode", "vehicle.powerTakeOffs.input") -- FS17 to FS19
439 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. "#lowerDistanceToGround", key..".distanceToGround#lower") -- FS17 to FS19
440 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. "#upperDistanceToGround", key..".distanceToGround#upper") -- FS17 to FS19
441
442 local node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#node"), self.i3dMappings)
443 if node ~= nil then
444 inputAttacherJoint.node = node
445 inputAttacherJoint.heightNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. ".heightNode#node"), self.i3dMappings)
446 if inputAttacherJoint.heightNode ~= nil then
447 inputAttacherJoint.heightNodeOffset = {localToLocal(inputAttacherJoint.heightNode, node, 0, 0, 0)}
448 end
449
450 local jointTypeStr = getXMLString(xmlFile, key .. "#jointType")
451 local jointType
452 if jointTypeStr ~= nil then
453 jointType = AttacherJoints.jointTypeNameToInt[jointTypeStr]
454 if jointType == nil then
455 g_logManager:xmlWarning(self.configFileName, "Invalid jointType '%s' for inputAttacherJoint '%s'!", tostring(jointTypeStr), key)
456 end
457 else
458 g_logManager:xmlWarning(self.configFileName, "Missing jointType for inputAttacherJoint '%s'!", key)
459 end
460 if jointType == nil then
461 local needsTrailerJoint = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsTrailerJoint"), false)
462 local needsLowTrailerJoint = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsLowJoint"), false)
463 if needsTrailerJoint then
464 if needsLowTrailerJoint then
465 jointType = AttacherJoints.JOINTTYPE_TRAILERLOW
466 else
467 jointType = AttacherJoints.JOINTTYPE_TRAILER
468 end
469 else
470 jointType = AttacherJoints.JOINTTYPE_IMPLEMENT
471 end
472 end
473 inputAttacherJoint.jointType = jointType
474
475 inputAttacherJoint.jointOrigTrans = { getTranslation(inputAttacherJoint.node) }
476 inputAttacherJoint.topReferenceNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#topReferenceNode"), self.i3dMappings)
477 inputAttacherJoint.rootNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#rootNode"), self.i3dMappings), self.components[1].node)
478 inputAttacherJoint.rootNodeBackup = inputAttacherJoint.rootNode
479 inputAttacherJoint.allowsDetaching = Utils.getNoNil(getXMLBool(xmlFile, key .. "#allowsDetaching"), true)
480 inputAttacherJoint.fixedRotation = Utils.getNoNil(getXMLBool(xmlFile, key .. "#fixedRotation"), false)
481 inputAttacherJoint.hardAttach = Utils.getNoNil(getXMLBool(xmlFile, key .. "#hardAttach"), false)
482 if inputAttacherJoint.hardAttach and #self.components > 1 then
483 g_logManager:xmlWarning(self.configFileName, "hardAttach only available for single component vehicles! InputAttacherJoint '%s'!", key)
484 inputAttacherJoint.hardAttach = false
485 end
486 inputAttacherJoint.visualNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#nodeVisual"), self.i3dMappings)
487 if inputAttacherJoint.hardAttach and inputAttacherJoint.visualNode ~= nil then
488 inputAttacherJoint.visualNodeData = {
489 parent = getParent(inputAttacherJoint.visualNode),
490 translation = { getTranslation(inputAttacherJoint.visualNode) },
491 rotation = { getRotation(inputAttacherJoint.visualNode) },
492 index = getChildIndex(inputAttacherJoint.visualNode)
493 }
494 end
495
496
497 if jointType == AttacherJoints.JOINTTYPE_IMPLEMENT or jointType == AttacherJoints.JOINTTYPE_CUTTER then
498 if getXMLFloat(xmlFile, key .. ".distanceToGround#lower") == nil then
499 g_logManager:xmlWarning(self.configFileName, "Missing '.distanceToGround#lower' for inputAttacherJoint '%s'!", key)
500 end
501 if getXMLFloat(xmlFile, key .. ".distanceToGround#upper") == nil then
502 g_logManager:xmlWarning(self.configFileName, "Missing '.distanceToGround#upper' for inputAttacherJoint '%s'!", key)
503 end
504 end
505 inputAttacherJoint.lowerDistanceToGround = Utils.getNoNil(getXMLFloat(xmlFile, key .. ".distanceToGround#lower"), 0.7)
506 inputAttacherJoint.upperDistanceToGround = Utils.getNoNil(getXMLFloat(xmlFile, key .. ".distanceToGround#upper"), 1.0)
507 if inputAttacherJoint.lowerDistanceToGround > inputAttacherJoint.upperDistanceToGround then
508 g_logManager:xmlWarning(self.configFileName, "distanceToGround#lower may not be larger than distanceToGround#upper for inputAttacherJoint '%s'. Switching values!", key)
509 local copy = inputAttacherJoint.lowerDistanceToGround
510 inputAttacherJoint.lowerDistanceToGround = inputAttacherJoint.upperDistanceToGround
511 inputAttacherJoint.upperDistanceToGround = copy
512 end
513
514 inputAttacherJoint.lowerRotationOffset = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key .. "#lowerRotationOffset"), 0))
515
516
517 local defaultUpperRotationOffset = 8
518 if jointType == AttacherJoints.JOINTTYPE_CUTTER
519 or jointType == AttacherJoints.JOINTTYPE_WHEELLOADER
520 or jointType == AttacherJoints.JOINTTYPE_TELEHANDLER
521 or jointType == AttacherJoints.JOINTTYPE_FRONTLOADER
522 or jointType == AttacherJoints.JOINTTYPE_LOADERFORK then
523 defaultUpperRotationOffset = 0
524 end
525
526 inputAttacherJoint.upperRotationOffset = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key .. "#upperRotationOffset"), defaultUpperRotationOffset))
527
528 inputAttacherJoint.allowsJointRotLimitMovement = Utils.getNoNil(getXMLBool(xmlFile, key .. "#allowsJointRotLimitMovement"), true)
529 inputAttacherJoint.allowsJointTransLimitMovement = Utils.getNoNil(getXMLBool(xmlFile, key .. "#allowsJointTransLimitMovement"), true)
530
531 inputAttacherJoint.needsToolbar = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsToolbar"), false)
532 if inputAttacherJoint.needsToolbar and jointType ~= AttacherJoints.JOINTTYPE_IMPLEMENT then
533 g_logManager:xmlWarning(self.configFileName, "'needsToolbar' requires jointType 'implement' for inputAttacherJoint '%s'!", key)
534 inputAttacherJoint.needsToolbar = false
535 end
536
537 inputAttacherJoint.steeringBarLeftNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#steeringBarLeftNode"), self.i3dMappings)
538 inputAttacherJoint.steeringBarRightNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#steeringBarRightNode"), self.i3dMappings)
539
540 --load joint limit scales
541 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key .. "#upperRotLimitScale"))
542 inputAttacherJoint.upperRotLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }
543 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key .. "#lowerRotLimitScale"))
544 if jointType == AttacherJoints.JOINTTYPE_IMPLEMENT then
545 inputAttacherJoint.lowerRotLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 1) }
546 else
547 inputAttacherJoint.lowerRotLimitScale = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }
548 end
549
550 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key .. "#upperTransLimitScale"))
551 inputAttacherJoint.upperTransLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }
552 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key .. "#lowerTransLimitScale"))
553 inputAttacherJoint.lowerTransLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 1), Utils.getNoNil(z, 0) }
554
555 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitSpring"))
556 inputAttacherJoint.rotLimitSpring = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }
557 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitDamping"))
558 inputAttacherJoint.rotLimitDamping = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }
559 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitForceLimit"))
560 inputAttacherJoint.rotLimitForceLimit = { Utils.getNoNil(x, -1), Utils.getNoNil(y, -1), Utils.getNoNil(z, -1) }
561
562 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key.."#transLimitSpring"))
563 inputAttacherJoint.transLimitSpring = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }
564 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key.."#transLimitDamping"))
565 inputAttacherJoint.transLimitDamping = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }
566 local x, y, z = StringUtil.getVectorFromString(getXMLString(xmlFile, key.."#transLimitForceLimit"))
567 inputAttacherJoint.transLimitForceLimit = { Utils.getNoNil(x, -1), Utils.getNoNil(y, -1), Utils.getNoNil(z, -1) }
568
569 inputAttacherJoint.attacherHeight = getXMLFloat(xmlFile, key .. "#attacherHeight")
570 if inputAttacherJoint.attacherHeight == nil then
571 if jointType == AttacherJoints.JOINTTYPE_TRAILER then
572 inputAttacherJoint.attacherHeight = 0.9
573 elseif jointType == AttacherJoints.JOINTTYPE_TRAILERLOW then
574 inputAttacherJoint.attacherHeight = 0.55
575 end
576 end
577
578 local defaultNeedsLowering = true
579 local defaultAllowsLowering = false
580 if inputAttacherJoint.jointType == AttacherJoints.JOINTTYPE_TRAILER or inputAttacherJoint.jointType == AttacherJoints.JOINTTYPE_TRAILERLOW then
581 defaultNeedsLowering = false
582 end
583 if inputAttacherJoint.jointType ~= AttacherJoints.JOINTTYPE_TRAILER and inputAttacherJoint.jointType ~= AttacherJoints.JOINTTYPE_TRAILERLOW then
584 defaultAllowsLowering = true
585 end
586 inputAttacherJoint.needsLowering = Utils.getNoNil(getXMLBool(xmlFile, key.. "#needsLowering"), defaultNeedsLowering)
587 inputAttacherJoint.allowsLowering = Utils.getNoNil(getXMLBool(xmlFile, key.. "#allowsLowering"), defaultAllowsLowering)
588 inputAttacherJoint.isDefaultLowered = Utils.getNoNil(getXMLBool(xmlFile, key.. "#isDefaultLowered"), false)
589 inputAttacherJoint.useFoldingLoweredState = Utils.getNoNil(getXMLBool(xmlFile, key.. "#useFoldingLoweredState"), false)
590 inputAttacherJoint.forceSelection = Utils.getNoNil(getXMLBool(self.xmlFile, key.."#forceSelectionOnAttach"), true)
591 inputAttacherJoint.forceAllowDetachWhileLifted = Utils.getNoNil(getXMLBool(self.xmlFile, key.."#forceAllowDetachWhileLifted"), false)
592
593 inputAttacherJoint.dependentAttacherJoints = {}
594 local k = 0
595 while true do
596 local dependentKey = string.format(key .. ".dependentAttacherJoint(%d)", k)
597 if not hasXMLProperty(xmlFile, dependentKey) then
598 break
599 end
600 local attacherJointIndex = getXMLInt(xmlFile, dependentKey.."#attacherJointIndex")
601 if attacherJointIndex ~= nil then
602 table.insert(inputAttacherJoint.dependentAttacherJoints, attacherJointIndex)
603 end
604 k = k + 1
605 end
606
607 -- reset values if hardAttach is active
608 if inputAttacherJoint.hardAttach then
609 inputAttacherJoint.needsLowering = false
610 inputAttacherJoint.allowsLowering = false
611 inputAttacherJoint.isDefaultLowered = false
612 inputAttacherJoint.upperRotationOffset = 0
613 end
614
615 inputAttacherJoint.changeObjects = {}
616 ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, key, inputAttacherJoint.changeObjects, self.components, self)
617
618 inputAttacherJoint.additionalObjects = {}
619 local i = 0
620 while true do
621 local baseKey = string.format("%s.additionalObjects.additionalObject(%d)", key, i)
622 if not hasXMLProperty(xmlFile, baseKey) then
623 break
624 end
625
626 local entry = {}
627 entry.node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, baseKey .. "#node"), self.i3dMappings)
628 entry.attacherVehiclePath = getXMLString(xmlFile, baseKey.."#attacherVehiclePath")
629
630 if entry.node ~= nil and entry.attacherVehiclePath ~= nil then
631 entry.attacherVehiclePath = NetworkUtil.convertToNetworkFilename(entry.attacherVehiclePath)
632 table.insert(inputAttacherJoint.additionalObjects, entry)
633 end
634
635 i = i + 1
636 end
637
638 return true
639 end
640
641 return false
642end

loadSteeringAxleFromXML

Description
Definition
loadSteeringAxleFromXML()
Code
814function Attachable:loadSteeringAxleFromXML(spec, xmlFile, key)
815 spec.steeringAxleAngleScaleStart = Utils.getNoNil(getXMLFloat(xmlFile, key.."#startSpeed"), 10)
816 spec.steeringAxleAngleScaleEnd = Utils.getNoNil(getXMLFloat(xmlFile, key.."#endSpeed"), 30)
817 spec.steeringAxleUpdateBackwards = Utils.getNoNil(getXMLBool(xmlFile, key.."#backwards"), false)
818 spec.steeringAxleAngleSpeed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#speed"), 0.001)
819 spec.steeringAxleUseSuperAttachable = Utils.getNoNil(getXMLFloat(xmlFile, key.."#useSuperAttachable"), false)
820 spec.steeringAxleTargetNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#targetNode"), self.i3dMappings)
821 spec.steeringAxleAngleMinRot = Utils.getNoNilRad(getXMLFloat(xmlFile, key.."#minRot"), 0)
822 spec.steeringAxleAngleMaxRot = Utils.getNoNilRad(getXMLFloat(xmlFile, key.."#maxRot"), 0)
823 spec.steeringAxleDirection = Utils.getNoNil(getXMLFloat(xmlFile, key.."#direction"), 1)
824end

loadSupportAnimationFromXML

Description
Loads support animation from xml
Definition
loadSupportAnimationFromXML(table supportAnimation, int xmlFile, string key)
Arguments
tablesupportAnimationsupportAnimation
intxmlFilexmlFile id
stringkeykey to load from
Code
713function Attachable:loadSupportAnimationFromXML(supportAnimation, xmlFile, key)
714 supportAnimation.animationName = getXMLString(xmlFile, key.."#animationName")
715 supportAnimation.delayedOnLoad = Utils.getNoNil(getXMLBool(xmlFile, key.."#delayedOnLoad"), false) -- defines if the animation is played onPostLoad or onLoadFinished -> usefull if the animation collides e.g. with the folding animation
716 supportAnimation.delayedOnAttach = Utils.getNoNil(getXMLBool(xmlFile, key.."#delayedOnAttach"), true) -- defines if the animation is played before or after the attaching process
717
718 return supportAnimation.animationName ~= nil
719end

mountDynamic

Description
Definition
mountDynamic()
Code
1254function Attachable:mountDynamic(superFunc, object, objectActorId, jointNode, mountType, forceAcceleration)
1255 local spec = self.spec_attachable
1256
1257 if spec.attacherVehicle ~= nil then
1258 return false
1259 end
1260
1261 return superFunc(self, object, objectActorId, jointNode, mountType, forceAcceleration)
1262end

onAIImplementEndLine

Description
Definition
onAIImplementEndLine()
Code
1315function Attachable:onAIImplementEndLine()
1316 local spec = self.spec_attachable
1317
1318 local jointDesc = spec.attacherVehicle:getAttacherJointDescFromObject(self)
1319 if jointDesc.allowsLowering then
1320 if self:getAINeedsLowering() then
1321 if self:getIsLowered(true) then
1322 local jointDescIndex = spec.attacherVehicle:getAttacherJointIndexFromObject(self)
1323 spec.attacherVehicle:setJointMoveDown(jointDescIndex, false, false)
1324 end
1325 end
1326 end
1327end

onAIImplementStartLine

Description
Definition
onAIImplementStartLine()
Code
1299function Attachable:onAIImplementStartLine()
1300 local spec = self.spec_attachable
1301
1302 local jointDesc = spec.attacherVehicle:getAttacherJointDescFromObject(self)
1303 if jointDesc.allowsLowering then
1304 if self:getAINeedsLowering() then
1305 if not self:getIsLowered(false) then
1306 local jointDescIndex = spec.attacherVehicle:getAttacherJointIndexFromObject(self)
1307 spec.attacherVehicle:setJointMoveDown(jointDescIndex, true, false)
1308 end
1309 end
1310 end
1311end

onDeactivate

Description
Called on deactivate
Definition
onDeactivate()
Code
1071function Attachable:onDeactivate()
1072 if self.brake ~= nil then
1073 local spec = self.spec_attachable
1074 self:brake(spec.brakeForce, true)
1075 end
1076end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
113function Attachable:onLoad(savegame)
114 local spec = self.spec_attachable
115
116 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attacherJoint", "vehicle.inputAttacherJoints.inputAttacherJoint") -- FS15 to FS17
117 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.needsLowering", "vehicle.inputAttacherJoints.inputAttacherJoint#needsLowering") -- FS15 to FS17
118 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.allowsLowering", "vehicle.inputAttacherJoints.inputAttacherJoint#allowsLowering") -- FS15 to FS17
119 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.isDefaultLowered", "vehicle.inputAttacherJoints.inputAttacherJoint#isDefaultLowered") -- FS15 to FS17
120 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.forceSelectionOnAttach#value", "vehicle.inputAttacherJoints.inputAttacherJoint#forceSelectionOnAttach") -- FS15 to FS17
121 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.topReferenceNode#index", "vehicle.attacherJoint#topReferenceNode") -- FS15 to FS17
122 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attachRootNode#index", "vehicle.attacherJoint#rootNode") -- FS15 to FS17
123
124 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.inputAttacherJoints", "vehicle.attachable.inputAttacherJoints") -- FS17 to FS19
125 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.inputAttacherJointConfigurations", "vehicle.attachable.inputAttacherJointConfigurations") -- FS17 to FS19
126 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.brakeForce", "vehicle.attachable.brakeForce") -- FS17 to FS19
127 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.steeringAxleAngleScale", "vehicle.attachable.steeringAxleAngleScale") -- FS17 to FS19
128 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.support", "vehicle.attachable.support") -- FS17 to FS19
129 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.lowerAnimation", "vehicle.attachable.lowerAnimation") -- FS17 to FS19
130 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.toolCameras", "vehicle.attachable.toolCameras") -- FS17 to FS19
131 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attachable.toolCameras#count", "vehicle.attachable.toolCameras") -- FS17 to FS19
132 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attachable.toolCameras.toolCamera1", "vehicle.attachable.toolCamera") -- FS17 to FS19
133 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attachable.toolCameras.toolCamera2", "vehicle.attachable.toolCamera") -- FS17 to FS19
134 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attachable.toolCameras.toolCamera3", "vehicle.attachable.toolCamera") -- FS17 to FS19
135
136 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.foldable.foldingParts#onlyFoldOnDetach", "vehicle.attachable#allowFoldingWhileAttached") -- FS17 to FS19
137 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.maximalAirConsumptionPerFullStop", "vehicle.attachable.airConsumer#usage (is now in usage per second at full brake power)") --FS17 to FS19
138
139 spec.attacherJoint = nil
140
141 spec.inputAttacherJoints = {}
142 local i = 0
143 while true do
144 local key = string.format("vehicle.attachable.inputAttacherJoints.inputAttacherJoint(%d)", i)
145 if not hasXMLProperty(self.xmlFile, key) then
146 break
147 end
148
149 local inputAttacherJoint = {}
150 if self:loadInputAttacherJoint(self.xmlFile, key, inputAttacherJoint, i) then
151 table.insert(spec.inputAttacherJoints, inputAttacherJoint)
152 end
153
154 i = i + 1
155 end
156
157 if self.configurations["inputAttacherJoint"] ~= nil then
158 local attacherConfigs = string.format("vehicle.attachable.inputAttacherJointConfigurations.inputAttacherJointConfiguration(%d)", self.configurations["inputAttacherJoint"]-1)
159 local i=0
160 while true do
161 local baseName = string.format(attacherConfigs..".inputAttacherJoint(%d)", i)
162 if not hasXMLProperty(self.xmlFile, baseName) then
163 break
164 end
165 local inputAttacherJoint = {}
166 if self:loadInputAttacherJoint(self.xmlFile, baseName, inputAttacherJoint, i) then
167 table.insert(spec.inputAttacherJoints, inputAttacherJoint)
168 end
169 i = i + 1
170 end
171 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.attachable.inputAttacherJointConfigurations.inputAttacherJointConfiguration", self.configurations["inputAttacherJoint"], self.components, self)
172 end
173
174 spec.brakeForce = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.attachable.brakeForce"), 0)*10
175 spec.airConsumerUsage = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.attachable.airConsumer#usage"), 0)
176
177 spec.allowFoldingWhileAttached = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.attachable#allowFoldingWhileAttached"), true)
178 spec.allowFoldingWhileLowered = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.attachable#allowFoldingWhileLowered"), true)
179
180 spec.updateWheels = true
181 spec.updateSteeringAxleAngle = true
182
183 spec.isSelected = false
184 spec.attachTime = 0
185
186 spec.steeringAxleAngle = 0
187 spec.steeringAxleTargetAngle = 0
188
189 self:loadSteeringAxleFromXML(spec, self.xmlFile, "vehicle.attachable.steeringAxleAngleScale")
190
191 spec.supportAnimations = {}
192 i = 0
193 while true do
194 local baseKey = string.format("vehicle.attachable.support(%d)", i)
195 if not hasXMLProperty(self.xmlFile, baseKey) then
196 break
197 end
198
199 local entry = {}
200 if self:loadSupportAnimationFromXML(entry, self.xmlFile, baseKey) then
201 table.insert(spec.supportAnimations, entry)
202 end
203
204 i = i + 1
205 end
206
207 spec.lowerAnimation = getXMLString(self.xmlFile, "vehicle.attachable.lowerAnimation#name")
208 spec.lowerAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.attachable.lowerAnimation#speed"), 1)
209 spec.lowerAnimationDirectionOnDetach = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.attachable.lowerAnimation#directionOnDetach"), 0)
210 spec.lowerAnimationDefaultLowered = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.attachable.lowerAnimation#defaultLowered"), false)
211
212 spec.toolCameras = {}
213 i = 0
214 while true do
215 local cameraKey = string.format("vehicle.attachable.toolCameras.toolCamera(%d)", i)
216 if not hasXMLProperty(self.xmlFile, cameraKey) then
217 break
218 end
219
220 local camera = VehicleCamera:new(self)
221 if camera:loadFromXML(self.xmlFile, cameraKey) then
222 table.insert(spec.toolCameras, camera)
223 end
224
225 i = i + 1
226 end
227
228 spec.isHardAttached = false
229end

onLoadFinished

Description
Called on load finished
Definition
onLoadFinished(table savegame)
Arguments
tablesavegamesavegame
Code
306function Attachable:onLoadFinished(savegame)
307 local spec = self.spec_attachable
308
309 for _, supportAnimation in ipairs(spec.supportAnimations) do
310 if supportAnimation.delayedOnLoad then
311 if self:getIsSupportAnimationAllowed(supportAnimation) then
312 self:playAnimation(supportAnimation.animationName, 1, nil, true)
313 AnimatedVehicle.updateAnimationByName(self, supportAnimation.animationName, 9999999)
314 end
315 end
316 end
317end

onPostLoad

Description
Called after loading
Definition
onPostLoad(table savegame)
Arguments
tablesavegamesavegame
Code
234function Attachable:onPostLoad(savegame)
235 local spec = self.spec_attachable
236
237 for _, supportAnimation in ipairs(spec.supportAnimations) do
238 if not supportAnimation.delayedOnLoad then
239 if self:getIsSupportAnimationAllowed(supportAnimation) then
240 self:playAnimation(supportAnimation.animationName, 1, nil, true)
241 AnimatedVehicle.updateAnimationByName(self, supportAnimation.animationName, 9999999)
242 end
243 end
244 end
245
246 if savegame ~= nil and not savegame.resetVehicles then
247 if spec.lowerAnimation ~= nil and self.playAnimation ~= nil then
248 local lowerAnimTime = getXMLFloat(savegame.xmlFile, savegame.key..".attachable#lowerAnimTime")
249 if lowerAnimTime ~= nil then
250 local speed = 1
251 if lowerAnimTime < 0.5 then
252 speed = -1
253 end
254 self:playAnimation(spec.lowerAnimation, speed, nil, true)
255 self:setAnimationTime(spec.lowerAnimation, lowerAnimTime)
256 AnimatedVehicle.updateAnimationByName(self, spec.lowerAnimation, 9999999)
257
258 if self.updateCylinderedInitial ~= nil then
259 self:updateCylinderedInitial(false)
260 end
261 end
262 end
263 else
264 if spec.lowerAnimationDefaultLowered then
265 self:playAnimation(spec.lowerAnimation, 1, nil, true)
266 AnimatedVehicle.updateAnimationByName(self, spec.lowerAnimation, 9999999)
267 end
268 end
269
270 for _, inputAttacherJoint in pairs(spec.inputAttacherJoints) do
271 if self.getMovingPartByNode ~= nil then
272 if inputAttacherJoint.steeringBarLeftNode ~= nil then
273 local movingPart = self:getMovingPartByNode(inputAttacherJoint.steeringBarLeftNode)
274 if movingPart ~= nil then
275 inputAttacherJoint.steeringBarLeftMovingPart = movingPart
276 else
277 inputAttacherJoint.steeringBarLeftNode = nil
278 end
279 end
280 if inputAttacherJoint.steeringBarRightNode ~= nil then
281 local movingPart = self:getMovingPartByNode(inputAttacherJoint.steeringBarRightNode)
282 if movingPart ~= nil then
283 inputAttacherJoint.steeringBarRightMovingPart = movingPart
284 else
285 inputAttacherJoint.steeringBarRightNode = nil
286 end
287 end
288 else
289 inputAttacherJoint.steeringBarLeftNode = nil
290 inputAttacherJoint.steeringBarRightNode = nil
291 end
292 end
293
294 if self.brake ~= nil then
295 self:brake(spec.brakeForce, true)
296 end
297
298 if #spec.inputAttacherJoints > 0 then
299 g_currentMission:addAttachableVehicle(self)
300 end
301end

onPreDelete

Description
Called on before deleting
Definition
onPreDelete()
Code
321function Attachable:onPreDelete()
322 local spec = self.spec_attachable
323
324 if spec.attacherVehicle ~= nil then
325 spec.attacherVehicle:detachImplementByObject(self, true)
326 end
327
328 g_currentMission:removeAttachableVehicle(self)
329end

onReadStream

Description
Called on client side on join
Definition
onReadStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
345function Attachable:onReadStream(streamId, connection)
346 if streamReadBool(streamId) then
347 local object = NetworkUtil.readNodeObject(streamId)
348 local inputJointDescIndex = streamReadInt8(streamId)
349 local jointDescIndex = streamReadInt8(streamId)
350 local moveDown = streamReadBool(streamId)
351 local implementIndex = streamReadInt8(streamId)
352 if object ~= nil then
353 object:attachImplement(self, inputJointDescIndex, jointDescIndex, true, implementIndex)
354 object:setJointMoveDown(jointDescIndex, moveDown, true)
355 end
356 end
357end

onSelect

Description
Definition
onSelect()
Code
1080function Attachable:onSelect(subSelectionIndex)
1081 local attacherVehicle = self:getAttacherVehicle()
1082 if attacherVehicle ~= nil then
1083 attacherVehicle:setSelectedImplementByObject(self)
1084 end
1085end

onStateChange

Description
Definition
onStateChange()
Code
1331function Attachable:onStateChange(state, data)
1332 if self.getAILowerIfAnyIsLowered ~= nil then
1333 if self:getAILowerIfAnyIsLowered() then
1334 if state == Vehicle.STATE_CHANGE_AI_START_LINE then
1335 Attachable.onAIImplementStartLine(self)
1336 elseif state == Vehicle.STATE_CHANGE_AI_END_LINE then
1337 Attachable.onAIImplementEndLine(self)
1338 end
1339 end
1340 end
1341end

onUnselect

Description
Definition
onUnselect()
Code
1089function Attachable:onUnselect()
1090 local attacherVehicle = self:getAttacherVehicle()
1091 if attacherVehicle ~= nil then
1092 attacherVehicle:setSelectedImplementByObject(nil)
1093 end
1094end

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
388function Attachable:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
389 local spec = self.spec_attachable
390
391 if spec.updateSteeringAxleAngle then
392 if self:getLastSpeed() > 0.1 then
393 local baseVehicle = self:getSteeringAxleBaseVehicle()
394 if baseVehicle ~= nil and (self.movingDirection >= 0 or spec.steeringAxleUpdateBackwards) then
395 local yRot = Utils.getYRotationBetweenNodes(self.steeringAxleNode, baseVehicle.steeringAxleNode)
396 if math.abs(yRot) > 1.57 then
397 if yRot > 0 then
398 yRot = yRot - 3.14
399 else
400 yRot = yRot + 3.14
401 end
402 end
403
404 local startSpeed = spec.steeringAxleAngleScaleStart
405 local endSpeed = spec.steeringAxleAngleScaleEnd
406 local scale = MathUtil.clamp(1 + (self:getLastSpeed()-startSpeed) * 1.0/(startSpeed-endSpeed), 0, 1)
407 spec.steeringAxleTargetAngle = yRot*scale
408 elseif self:getLastSpeed() > 0.2 then
409 spec.steeringAxleTargetAngle = 0
410 end
411
412 if not self:getIsSteeringAxleAllowed() then
413 spec.steeringAxleTargetAngle = 0
414 end
415
416 local dir = MathUtil.sign(spec.steeringAxleTargetAngle - spec.steeringAxleAngle)
417 if dir == 1 then
418 spec.steeringAxleAngle = math.min(spec.steeringAxleAngle + dir*dt*spec.steeringAxleAngleSpeed, spec.steeringAxleTargetAngle)
419 else
420 spec.steeringAxleAngle = math.max(spec.steeringAxleAngle + dir*dt*spec.steeringAxleAngleSpeed, spec.steeringAxleTargetAngle)
421 end
422
423 if spec.steeringAxleTargetNode ~= nil then
424 local angle = MathUtil.clamp(spec.steeringAxleAngle, spec.steeringAxleAngleMinRot, spec.steeringAxleAngleMaxRot)
425 setRotation(spec.steeringAxleTargetNode, 0, angle * spec.steeringAxleDirection, 0)
426 self:setMovingToolDirty(spec.steeringAxleTargetNode)
427 end
428 end
429 end
430end

onWriteStream

Description
Called on server side on join
Definition
onWriteStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
363function Attachable:onWriteStream(streamId, connection)
364 local spec = self.spec_attachable
365
366 streamWriteBool(streamId, spec.attacherVehicle ~= nil)
367 if spec.attacherVehicle ~= nil then
368 local attacherJointVehicleSpec = spec.attacherVehicle.spec_attacherJoints
369 local implementIndex = spec.attacherVehicle:getImplementIndexByObject(self)
370 local implement = attacherJointVehicleSpec.attachedImplements[implementIndex]
371 local inputJointDescIndex = spec.inputAttacherJointDescIndex
372 local jointDescIndex = implement.jointDescIndex
373 local jointDesc = attacherJointVehicleSpec.attacherJoints[jointDescIndex]
374 local moveDown = jointDesc.moveDown
375 NetworkUtil.writeNodeObject(streamId, spec.attacherVehicle)
376 streamWriteInt8(streamId, inputJointDescIndex)
377 streamWriteInt8(streamId, jointDescIndex)
378 streamWriteBool(streamId, moveDown)
379 streamWriteInt8(streamId, implementIndex)
380 end
381end

postAttach

Description
Called if vehicle gets attached
Definition
postAttach(table attacherVehicle, integer inputJointDescIndex, integer jointDescIndex, boolean loadFromSavegame)
Arguments
tableattacherVehicleattacher vehicle
integerinputJointDescIndexindex of input attacher joint
integerjointDescIndexindex of attacher joint it gets attached to
booleanloadFromSavegameattachment is loaded from savegame
Code
898function Attachable:postAttach(attacherVehicle, inputJointDescIndex, jointDescIndex, loadFromSavegame)
899 local spec = self.spec_attachable
900
901 -- only activate tool if root vehicle is controlled (activated). We don't want to activate a tool that is attached during loading
902 local rootVehicle = self:getRootVehicle()
903 if rootVehicle ~= nil and rootVehicle.getIsControlled ~= nil and rootVehicle:getIsControlled() then
904 self:activate()
905 end
906
907 if self.setLightsTypesMask ~= nil then
908 local lightsSpecAttacherVehicle = attacherVehicle.spec_lights
909 if lightsSpecAttacherVehicle ~= nil then
910 self:setLightsTypesMask(lightsSpecAttacherVehicle.lightsTypesMask, true, true)
911 self:setBeaconLightsVisibility(lightsSpecAttacherVehicle.beaconLightsActive, true, true)
912 self:setTurnLightState(lightsSpecAttacherVehicle.turnLightState, true, true)
913 end
914 end
915
916 spec.attachTime = g_currentMission.time
917
918 for _, supportAnimation in ipairs(spec.supportAnimations) do
919 if self:getIsSupportAnimationAllowed(supportAnimation) then
920 if supportAnimation.delayedOnAttach then
921 self:playAnimation(supportAnimation.animationName, -1, nil, true)
922 if self.propertyState == Vehicle.PROPERTY_STATE_SHOP_CONFIG or loadFromSavegame then
923 AnimatedVehicle.updateAnimationByName(self, supportAnimation.animationName, 9999999)
924 end
925 end
926 end
927 end
928
929 self:attachableAddToolCameras()
930
931 ObjectChangeUtil.setObjectChanges(spec.attacherJoint.changeObjects, true, self, self.setMovingToolDirty)
932
933 local jointDesc = attacherVehicle:getAttacherJointByJointDescIndex(jointDescIndex)
934 if jointDesc.steeringBarLeftNode ~= nil and spec.attacherJoint.steeringBarLeftMovingPart ~= nil then
935 for _,movingPart in pairs(self.spec_cylindered.movingParts) do
936 if movingPart.referencePoint == spec.attacherJoint.steeringBarLeftMovingPart.referencePoint and movingPart ~= spec.attacherJoint.steeringBarLeftMovingPart then
937 movingPart.referencePoint = jointDesc.steeringBarLeftNode
938 end
939 end
940 spec.attacherJoint.steeringBarLeftMovingPart.referencePoint = jointDesc.steeringBarLeftNode
941 end
942 if jointDesc.steeringBarRightNode ~= nil and spec.attacherJoint.steeringBarRightMovingPart ~= nil then
943 for _,movingPart in pairs(self.spec_cylindered.movingParts) do
944 if movingPart.referencePoint == spec.attacherJoint.steeringBarRightMovingPart.referencePoint and movingPart ~= spec.attacherJoint.steeringBarRightMovingPart then
945 movingPart.referencePoint = jointDesc.steeringBarRightNode
946 end
947 end
948 spec.attacherJoint.steeringBarRightMovingPart.referencePoint = jointDesc.steeringBarRightNode
949 end
950
951 SpecializationUtil.raiseEvent(self, "onPostAttach", attacherVehicle, inputJointDescIndex, jointDescIndex)
952end

postDetach

Description
Definition
postDetach()
Code
962function Attachable:postDetach(implementIndex)
963 local spec = self.spec_attachable
964
965 self:deactivate()
966
967 ObjectChangeUtil.setObjectChanges(spec.attacherJoint.changeObjects, false, self, self.setMovingToolDirty)
968
969
970 if self.playAnimation ~= nil then
971 for _, supportAnimation in ipairs(spec.supportAnimations) do
972 if self:getIsSupportAnimationAllowed(supportAnimation) then
973 self:playAnimation(supportAnimation.animationName, 1, nil, true)
974 end
975 end
976
977 if spec.lowerAnimation ~= nil and spec.lowerAnimationDirectionOnDetach ~= 0 then
978 self:playAnimation(spec.lowerAnimation, spec.lowerAnimationDirectionOnDetach, nil, true)
979 end
980 end
981
982 self:attachableRemoveToolCameras()
983
984 for _, additionalObject in ipairs(spec.attacherJoint.additionalObjects) do
985 setVisibility(additionalObject.node, false)
986 end
987
988 spec.attacherVehicle = nil
989
990 spec.attacherJoint = nil
991 spec.attacherJointIndex = nil
992
993 spec.inputAttacherJointDescIndex = nil
994
995 SpecializationUtil.raiseEvent(self, "onPostDetach")
996end

preAttach

Description
Called before vehicle gets attached
Definition
preAttach(table attacherVehicle, integer inputAttacherJointDescIndex, boolean loadFromSavegame)
Arguments
tableattacherVehicleattacher vehicle
integerinputAttacherJointDescIndexindex of input attacher joint
booleanloadFromSavegameattachment is loaded from savegame
Code
867function Attachable:preAttach(attacherVehicle, inputJointDescIndex, jointDescIndex, loadFromSavegame)
868 local spec = self.spec_attachable
869
870 spec.attacherVehicle = attacherVehicle
871 spec.attacherJoint = spec.inputAttacherJoints[inputJointDescIndex]
872 spec.inputAttacherJointDescIndex = inputJointDescIndex
873
874 for _, additionalObject in ipairs(spec.attacherJoint.additionalObjects) do
875 setVisibility(additionalObject.node, additionalObject.attacherVehiclePath == NetworkUtil.convertToNetworkFilename(attacherVehicle.configFileName))
876 end
877
878 for _, supportAnimation in ipairs(spec.supportAnimations) do
879 if self:getIsSupportAnimationAllowed(supportAnimation) then
880 if not supportAnimation.delayedOnAttach then
881 self:playAnimation(supportAnimation.animationName, -1, nil, true)
882 if self.propertyState == Vehicle.PROPERTY_STATE_SHOP_CONFIG or loadFromSavegame then
883 AnimatedVehicle.updateAnimationByName(self, supportAnimation.animationName, 9999999)
884 end
885 end
886 end
887 end
888
889 SpecializationUtil.raiseEvent(self, "onPreAttach", attacherVehicle, inputJointDescIndex, jointDescIndex)
890end

preDetach

Description
Definition
preDetach()
Code
956function Attachable:preDetach(attacherVehicle, implement)
957 SpecializationUtil.raiseEvent(self, "onPreDetach", attacherVehicle, implement)
958end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
17function Attachable.prerequisitesPresent(specializations)
18 return true
19end

registerEventListeners

Description
Definition
registerEventListeners()
Code
88function Attachable.registerEventListeners(vehicleType)
89 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Attachable)
90 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Attachable)
91 SpecializationUtil.registerEventListener(vehicleType, "onLoadFinished", Attachable)
92 SpecializationUtil.registerEventListener(vehicleType, "onPreDelete", Attachable)
93 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Attachable)
94 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Attachable)
95 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Attachable)
96 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Attachable)
97 SpecializationUtil.registerEventListener(vehicleType, "onSelect", Attachable)
98 SpecializationUtil.registerEventListener(vehicleType, "onUnselect", Attachable)
99 SpecializationUtil.registerEventListener(vehicleType, "onAIImplementStartLine", Attachable)
100 SpecializationUtil.registerEventListener(vehicleType, "onAIImplementEndLine", Attachable)
101 SpecializationUtil.registerEventListener(vehicleType, "onStateChange", Attachable)
102end

registerEvents

Description
Definition
registerEvents()
Code
23function Attachable.registerEvents(vehicleType)
24 SpecializationUtil.registerEvent(vehicleType, "onPreAttach")
25 SpecializationUtil.registerEvent(vehicleType, "onPostAttach")
26 SpecializationUtil.registerEvent(vehicleType, "onPreDetach")
27 SpecializationUtil.registerEvent(vehicleType, "onPostDetach")
28 SpecializationUtil.registerEvent(vehicleType, "onSetLowered")
29 SpecializationUtil.registerEvent(vehicleType, "onSetLoweredAll")
30 SpecializationUtil.registerEvent(vehicleType, "onLeaveRootVehicle")
31end

registerFunctions

Description
Definition
registerFunctions()
Code
35function Attachable.registerFunctions(vehicleType)
36 SpecializationUtil.registerFunction(vehicleType, "loadInputAttacherJoint", Attachable.loadInputAttacherJoint)
37 SpecializationUtil.registerFunction(vehicleType, "getInputAttacherJointByJointDescIndex", Attachable.getInputAttacherJointByJointDescIndex)
38 SpecializationUtil.registerFunction(vehicleType, "getAttacherVehicle", Attachable.getAttacherVehicle)
39 SpecializationUtil.registerFunction(vehicleType, "getInputAttacherJoints", Attachable.getInputAttacherJoints)
40 SpecializationUtil.registerFunction(vehicleType, "getIsAttachedTo", Attachable.getIsAttachedTo)
41 SpecializationUtil.registerFunction(vehicleType, "getActiveInputAttacherJointDescIndex", Attachable.getActiveInputAttacherJointDescIndex)
42 SpecializationUtil.registerFunction(vehicleType, "getActiveInputAttacherJoint", Attachable.getActiveInputAttacherJoint)
43 SpecializationUtil.registerFunction(vehicleType, "getAllowsLowering", Attachable.getAllowsLowering)
44 SpecializationUtil.registerFunction(vehicleType, "loadSupportAnimationFromXML", Attachable.loadSupportAnimationFromXML)
45 SpecializationUtil.registerFunction(vehicleType, "getIsSupportAnimationAllowed", Attachable.getIsSupportAnimationAllowed)
46 SpecializationUtil.registerFunction(vehicleType, "getIsImplementChainLowered", Attachable.getIsImplementChainLowered)
47 SpecializationUtil.registerFunction(vehicleType, "getIsInWorkPosition", Attachable.getIsInWorkPosition)
48 SpecializationUtil.registerFunction(vehicleType, "getAttachbleAirConsumerUsage", Attachable.getAttachbleAirConsumerUsage)
49 SpecializationUtil.registerFunction(vehicleType, "isDetachAllowed", Attachable.isDetachAllowed)
50 SpecializationUtil.registerFunction(vehicleType, "getIsInputAttacherActive", Attachable.getIsInputAttacherActive)
51 SpecializationUtil.registerFunction(vehicleType, "getSteeringAxleBaseVehicle", Attachable.getSteeringAxleBaseVehicle)
52 SpecializationUtil.registerFunction(vehicleType, "loadSteeringAxleFromXML", Attachable.loadSteeringAxleFromXML)
53 SpecializationUtil.registerFunction(vehicleType, "getIsSteeringAxleAllowed", Attachable.getIsSteeringAxleAllowed)
54 SpecializationUtil.registerFunction(vehicleType, "attachableAddToolCameras", Attachable.attachableAddToolCameras)
55 SpecializationUtil.registerFunction(vehicleType, "attachableRemoveToolCameras", Attachable.attachableRemoveToolCameras)
56 SpecializationUtil.registerFunction(vehicleType, "preAttach", Attachable.preAttach)
57 SpecializationUtil.registerFunction(vehicleType, "postAttach", Attachable.postAttach)
58 SpecializationUtil.registerFunction(vehicleType, "preDetach", Attachable.preDetach)
59 SpecializationUtil.registerFunction(vehicleType, "postDetach", Attachable.postDetach)
60 SpecializationUtil.registerFunction(vehicleType, "setLowered", Attachable.setLowered)
61 SpecializationUtil.registerFunction(vehicleType, "setLoweredAll", Attachable.setLoweredAll)
62 SpecializationUtil.registerFunction(vehicleType, "registerLoweringActionEvent", Attachable.registerLoweringActionEvent)
63 SpecializationUtil.registerFunction(vehicleType, "getLoweringActionEventState", Attachable.getLoweringActionEventState)
64end

registerLoweringActionEvent

Description
Definition
registerLoweringActionEvent()
Code
1042function Attachable:registerLoweringActionEvent(actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName)
1043 self:addActionEvent(actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName)
1044end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
68function Attachable.registerOverwrittenFunctions(vehicleType)
69 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getRootVehicle", Attachable.getRootVehicle)
70 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsActive", Attachable.getIsActive)
71 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsOperating", Attachable.getIsOperating)
72 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getBrakeForce", Attachable.getBrakeForce)
73 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsFoldAllowed", Attachable.getIsFoldAllowed)
74 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanToggleTurnedOn", Attachable.getCanToggleTurnedOn)
75 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanAIImplementContinueWork", Attachable.getCanAIImplementContinueWork)
76 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDeactivateOnLeave", Attachable.getDeactivateOnLeave)
77 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getActiveFarm", Attachable.getActiveFarm)
78 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Attachable.getCanBeSelected)
79 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsLowered", Attachable.getIsLowered)
80 SpecializationUtil.registerOverwrittenFunction(vehicleType, "mountDynamic", Attachable.mountDynamic)
81 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getOwner", Attachable.getOwner)
82 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsInUse", Attachable.getIsInUse)
83 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getUpdatePriority", Attachable.getUpdatePriority)
84end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
333function Attachable:saveToXMLFile(xmlFile, key, usedModNames)
334 local spec = self.spec_attachable
335 if spec.lowerAnimation ~= nil and self.playAnimation ~= nil then
336 local lowerAnimTime = self:getAnimationTime(spec.lowerAnimation)
337 setXMLFloat(xmlFile, key.."#lowerAnimTime", lowerAnimTime)
338 end
339end

setLowered

Description
Set attachables lowering state
Definition
setLowered(boolean lowered)
Arguments
booleanloweredattachable is lowered
Code
1001function Attachable:setLowered(lowered)
1002 local spec = self.spec_attachable
1003
1004 if spec.lowerAnimation ~= nil and self.playAnimation ~= nil then
1005 if lowered then
1006 self:playAnimation(spec.lowerAnimation, spec.lowerAnimationSpeed, nil, true)
1007 else
1008 self:playAnimation(spec.lowerAnimation, -spec.lowerAnimationSpeed, nil, true)
1009 end
1010 end
1011
1012 if spec.attacherJoint ~= nil then
1013 for _, dependentAttacherJointIndex in pairs(spec.attacherJoint.dependentAttacherJoints) do
1014 if self.getAttacherJoints ~= nil then
1015 local attacherJoints = self:getAttacherJoints()
1016 if attacherJoints[dependentAttacherJointIndex] ~= nil then
1017 self:setJointMoveDown(dependentAttacherJointIndex, lowered, true)
1018 else
1019 g_logManager:xmlWarning(self.configFileName, "Failed to lower dependent attacher joint index '%d', No attacher joint defined!", dependentAttacherJointIndex)
1020 end
1021 else
1022 g_logManager:xmlWarning(self.configFileName, "Failed to lower dependent attacher joint index '%d', AttacherJoint specialization is missing!", dependentAttacherJointIndex)
1023 end
1024 end
1025 end
1026
1027 SpecializationUtil.raiseEvent(self, "onSetLowered", lowered)
1028end

setLoweredAll

Description
Set attachables lowering all state
Definition
setLoweredAll(boolean doLowering)
Arguments
booleandoLoweringdo lowering
Code
1034function Attachable:setLoweredAll(doLowering, jointDescIndex)
1035 self:getAttacherVehicle():handleLowerImplementByAttacherJointIndex(jointDescIndex, doLowering)
1036
1037 SpecializationUtil.raiseEvent(self, "onSetLoweredAll", doLowering, jointDescIndex)
1038end