Script v1.4.4.0
Engine v7.0.0.2
- General
- Entity
- Node
- Scenegraph
- Lighting
- Camera
- Shape
- Particle System
- Physics
- Spline
- Animation
- Overlays
- Sound
- Input
- XML
- Network
- Callbacks
- Text Rendering
- Terrain Detail
- Tire Track
- Editor
- Rendering
- String
- Math
- I3D
- Fillplanes
Foundation Reference
Attachable
DescriptionThis is the specialization for all vehicles that may be attachedFunctions
- prerequisitesPresent
- preLoad
- load
- postLoad
- loadInputAttacherJoint
- loadInputPowerTakeoff
- preDelete
- delete
- readStream
- writeStream
- getSaveAttributesAndNodes
- update
- onPreAttach
- onAttached
- onAttach
- onDetach
- onDetached
- onDeactivate
- onSelect
- onDeselect
- onBrake
- onReleaseBrake
- onSetLowered
- onLowerAll
- getIsInWorkPosition
- isDetachAllowed
- getIsInputAttacherActive
- getSteeringAxleBaseVehicle
- getIsPowerTakeoffActive
- attachableAddToolCameras
- attachableRemoveToolCameras
- onAiRaise
- onAiLower
- getIsAIReadyForWork
- getIsOperating
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
17 | function Attachable.prerequisitesPresent(specializations) |
18 | return SpecializationUtil.hasSpecialization(Lights, specializations); |
19 | end |
preLoad
DescriptionCalled before loadingDefinition
preLoad(table savegame)Arguments
table | savegame | savegame |
24 | function Attachable:preLoad(savegame) |
25 | self.isDetachAllowed = Utils.overwrittenFunction(self.isDetachAllowed, Attachable.isDetachAllowed); |
26 | self.getIsInWorkPosition = Utils.overwrittenFunction(self.getIsInWorkPosition, Attachable.getIsInWorkPosition); |
27 | self.loadInputAttacherJoint = Utils.overwrittenFunction(self.loadInputAttacherJoint, Attachable.loadInputAttacherJoint); |
28 | self.getIsPowerTakeoffActive = Utils.overwrittenFunction(self.getIsPowerTakeoffActive, Attachable.getIsPowerTakeoffActive); |
29 | self.getIsInputAttacherActive = Utils.overwrittenFunction(self.getIsInputAttacherActive, Attachable.getIsInputAttacherActive); |
30 | self.getSteeringAxleBaseVehicle = Utils.overwrittenFunction(self.getSteeringAxleBaseVehicle, Attachable.getSteeringAxleBaseVehicle); |
31 | self.loadInputPowerTakeoff = Utils.overwrittenFunction(self.loadInputPowerTakeoff, Attachable.loadInputPowerTakeoff); |
32 | self.getIsOperating = Utils.overwrittenFunction(self.getIsOperating, Attachable.getIsOperating); |
33 | self.onAttach = SpecializationUtil.callSpecializationsFunction("onAttach"); |
34 | self.onAttached = SpecializationUtil.callSpecializationsFunction("onAttached"); |
35 | self.onPreAttach = SpecializationUtil.callSpecializationsFunction("onPreAttach"); |
36 | self.onDetach = SpecializationUtil.callSpecializationsFunction("onDetach"); |
37 | self.onDetached = SpecializationUtil.callSpecializationsFunction("onDetached"); |
38 | self.onSelect = SpecializationUtil.callSpecializationsFunction("onSelect"); |
39 | self.onDeselect = SpecializationUtil.callSpecializationsFunction("onDeselect"); |
40 | self.onBrake = SpecializationUtil.callSpecializationsFunction("onBrake"); |
41 | self.onReleaseBrake = SpecializationUtil.callSpecializationsFunction("onReleaseBrake"); |
42 | self.onSetLowered = SpecializationUtil.callSpecializationsFunction("onSetLowered"); |
43 | self.onLowerAll = SpecializationUtil.callSpecializationsFunction("onLowerAll"); |
44 | self.attachableAddToolCameras = SpecializationUtil.callSpecializationsFunction("attachableAddToolCameras"); |
45 | self.attachableRemoveToolCameras = SpecializationUtil.callSpecializationsFunction("attachableRemoveToolCameras"); |
46 | end |
load
DescriptionCalled on loadingDefinition
load(table savegame)Arguments
table | savegame | savegame |
51 | function Attachable:load(savegame) |
52 | |
53 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.powerTakeoffInput", "vehicle.inputAttacherJoints.inputAttacherJoint#ptoInputNode") |
54 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attacherJoint", "vehicle.inputAttacherJoints.inputAttacherJoint") |
55 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.needsLowering", "vehicle.inputAttacherJoints.inputAttacherJoint#needsLowering") |
56 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.allowsLowering", "vehicle.inputAttacherJoints.inputAttacherJoint#allowsLowering") |
57 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.isDefaultLowered", "vehicle.inputAttacherJoints.inputAttacherJoint#isDefaultLowered") |
58 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.forceSelectionOnAttach#value", "vehicle.inputAttacherJoints.inputAttacherJoint#forceSelectionOnAttach") |
59 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.topReferenceNode#index", "vehicle.attacherJoint#topReferenceNode") |
60 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.attachRootNode#index", "vehicle.attacherJoint#rootNode") |
61 | |
62 | self.attacherJoint = nil; |
63 | |
64 | self.inputAttacherJoints = {}; |
65 | local i = 0; |
66 | while true do |
67 | local key = string.format("vehicle.inputAttacherJoints.inputAttacherJoint(%d)", i); |
68 | if not hasXMLProperty(self.xmlFile, key) then |
69 | break; |
70 | end |
71 | |
72 | local inputAttacherJoint = {}; |
73 | if self:loadInputAttacherJoint(self.xmlFile, key, inputAttacherJoint, i) then |
74 | table.insert(self.inputAttacherJoints, inputAttacherJoint); |
75 | end |
76 | |
77 | i = i + 1; |
78 | end |
79 | |
80 | if self.configurations["inputAttacherJoint"] ~= nil then |
81 | local attacherConfigs = string.format("vehicle.inputAttacherJointConfigurations.inputAttacherJointConfiguration(%d)", self.configurations["inputAttacherJoint"]-1); |
82 | local i=0; |
83 | while true do |
84 | local baseName = string.format(attacherConfigs..".inputAttacherJoint(%d)", i); |
85 | if not hasXMLProperty(self.xmlFile, baseName) then |
86 | break; |
87 | end |
88 | local inputAttacherJoint = {}; |
89 | if self:loadInputAttacherJoint(self.xmlFile, baseName, inputAttacherJoint, i) then |
90 | table.insert(self.inputAttacherJoints, inputAttacherJoint); |
91 | end |
92 | i = i + 1; |
93 | end |
94 | ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.inputAttacherJointConfigurations.inputAttacherJointConfiguration", self.configurations["inputAttacherJoint"], self.components, self); |
95 | end |
96 | |
97 | self.brakeForce = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.brakeForce"), 0)*10; |
98 | self.brakePedal = 0.0; |
99 | self.updateWheels = true; |
100 | self.updateSteeringAxleAngle = true; |
101 | |
102 | self.isSelected = false; |
103 | self.attachTime = 0; |
104 | |
105 | self.steeringAxleAngleScaleStart = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.steeringAxleAngleScale#startSpeed"), 10); |
106 | self.steeringAxleAngleScaleEnd = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.steeringAxleAngleScale#endSpeed"), 30); |
107 | self.steeringAxleUpdateBackwards = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.steeringAxleAngleScale#backwards"), false); |
108 | self.steeringAxleAngleSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.steeringAxleAngleScale#speed"), 0.001); |
109 | self.steeringAxleUseSuperAttachable = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.steeringAxleAngleScale#useSuperAttachable"), false); |
110 | |
111 | self.supportAnimation = getXMLString(self.xmlFile, "vehicle.support#animationName"); |
112 | self.lowerAnimation = getXMLString(self.xmlFile, "vehicle.lowerAnimation#name"); |
113 | self.lowerAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.lowerAnimation#speed"), 1); |
114 | self.lowerAnimationDirectionOnDetach = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.lowerAnimation#directionOnDetach"), 0); |
115 | |
116 | local defaultNeedsLowering = false; |
117 | for _, joint in pairs(self.inputAttacherJoints) do |
118 | if joint.needsLowering then |
119 | defaultNeedsLowering = true; |
120 | break; |
121 | end |
122 | end |
123 | self.aiNeedsLowering = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.ai.needsLowering#value"), defaultNeedsLowering); |
124 | self.aiLowerIfAnyIsLowerd = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.ai.needsLowering#lowerIfAnyIsLowerd"), false); |
125 | self.aiForceTurnNoBackward = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.ai.forceTurnNoBackward#value"), false); |
126 | |
127 | self.aiToolReverserDirectionNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.ai.toolReverserDirectionNode#index")); |
128 | self.aiSkipWorkAreaLengthOnTurn = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.ai.skipWorkAreaLengthOnTurn#value"), false); |
129 | |
130 | self.aiTurningRadiusLimitation = {}; |
131 | self.aiTurningRadiusLimitation.rotationJoint = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.ai.turningRadiusLimitation#rotationJointNode")); |
132 | if self.aiTurningRadiusLimitation.rotationJoint == nil then |
133 | self.aiTurningRadiusLimitation.rotationJoint = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.ai.turningRadiusLimiation#rotationJointNode")); |
134 | end |
135 | if self.aiTurningRadiusLimitation.rotationJoint ~= nil then |
136 | self.aiTurningRadiusLimitation.wheelIndices = { Utils.getVectorFromString(getXMLString(self.xmlFile, "vehicle.ai.turningRadiusLimitation#wheelIndices")) }; |
137 | if #self.aiTurningRadiusLimitation.wheelIndices == 0 then |
138 | self.aiTurningRadiusLimitation.wheelIndices = { Utils.getVectorFromString(getXMLString(self.xmlFile, "vehicle.ai.turningRadiusLimiation#wheelIndices")) }; |
139 | end |
140 | end |
141 | self.aiTurningRadiusLimitation.radius = getXMLFloat(self.xmlFile, "vehicle.ai.turningRadiusLimitation#radius"); |
142 | if self.aiTurningRadiusLimitation.radius == nil then |
143 | self.aiTurningRadiusLimitation.radius = getXMLFloat(self.xmlFile, "vehicle.ai.turningRadiusLimiation#radius"); |
144 | end |
145 | |
146 | if table.getn(self.inputAttacherJoints) > 0 then |
147 | -- all attachables are selectable, since they need to be detached |
148 | self.isSelectable = true |
149 | end |
150 | |
151 | self.numToolCameras = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.toolCameras#count"), 0); |
152 | self.toolCameras = {}; |
153 | for i=1, self.numToolCameras do |
154 | local cameraKey = string.format("vehicle.toolCameras.toolCamera%d", i); |
155 | local camera = VehicleCamera:new(self); |
156 | if camera:loadFromXML(self.xmlFile, cameraKey) then |
157 | table.insert(self.toolCameras, camera); |
158 | end |
159 | end |
160 | |
161 | self.isHardAttached = false |
162 | end |
postLoad
DescriptionCalled after loadingDefinition
postLoad(table savegame)Arguments
table | savegame | savegame |
167 | function Attachable:postLoad(savegame) |
168 | if self.supportAnimation ~= nil and self.playAnimation ~= nil then |
169 | self:playAnimation(self.supportAnimation, 1, nil, true); |
170 | end |
171 | |
172 | if savegame ~= nil and not savegame.resetVehicles then |
173 | if self.lowerAnimation ~= nil and self.playAnimation ~= nil then |
174 | local lowerAnimTime = getXMLFloat(savegame.xmlFile, savegame.key.."#lowerAnimTime"); |
175 | if lowerAnimTime ~= nil then |
176 | local speed = 1; |
177 | if lowerAnimTime < 0.5 then |
178 | speed = -1; |
179 | end |
180 | self:playAnimation(self.lowerAnimation, speed, nil, true); |
181 | self:setAnimationTime(self.lowerAnimation, lowerAnimTime); |
182 | |
183 | if self.updateCylinderedInitial ~= nil then |
184 | self:updateCylinderedInitial(false); |
185 | end |
186 | end |
187 | end |
188 | end |
189 | |
190 | for _, inputAttacherJoint in pairs(self.inputAttacherJoints) do |
191 | if inputAttacherJoint.steeringBarLeftNode ~= nil then |
192 | if self.nodesToMovingParts ~= nil and self.nodesToMovingParts[inputAttacherJoint.steeringBarLeftNode] ~= nil then |
193 | inputAttacherJoint.steeringBarLeftMovingPart = self.nodesToMovingParts[inputAttacherJoint.steeringBarLeftNode] |
194 | inputAttacherJoint.steeringBarLeftMovingPart.referencePointBackup = inputAttacherJoint.steeringBarLeftMovingPart.referencePoint |
195 | else |
196 | inputAttacherJoint.steeringBarLeftNode = nil |
197 | end |
198 | end |
199 | if inputAttacherJoint.steeringBarRightNode ~= nil then |
200 | if self.nodesToMovingParts ~= nil and self.nodesToMovingParts[inputAttacherJoint.steeringBarRightNode] ~= nil then |
201 | inputAttacherJoint.steeringBarRightMovingPart = self.nodesToMovingParts[inputAttacherJoint.steeringBarRightNode] |
202 | inputAttacherJoint.steeringBarRightMovingPart.referencePointBackup = inputAttacherJoint.steeringBarRightMovingPart.referencePoint |
203 | else |
204 | inputAttacherJoint.steeringBarRightNode = nil |
205 | end |
206 | end |
207 | end |
208 | |
209 | self:onBrake(1, true); |
210 | end |
loadInputAttacherJoint
DescriptionCalled on loadingDefinition
loadInputAttacherJoint(table savegame)Arguments
table | savegame | savegame |
215 | function Attachable:loadInputAttacherJoint(superFunc, xmlFile, key, inputAttacherJoint, index) |
216 | if superFunc ~= nil then |
217 | if not superFunc(self, xmlFile, key, inputAttacherJoint, index) then |
218 | return false; |
219 | end |
220 | end |
221 | |
222 | local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#index")); |
223 | if node ~= nil then |
224 | inputAttacherJoint.node = node; |
225 | |
226 | local jointTypeStr = getXMLString(xmlFile, key .. "#jointType") |
227 | local jointType; |
228 | if jointTypeStr ~= nil then |
229 | jointType = AttacherJoints.jointTypeNameToInt[jointTypeStr]; |
230 | if jointType == nil then |
231 | print("Warning: invalid jointType " .. jointTypeStr .. " for inputAttacherJoint "..(index+1).." in "..self.configFileName.."!"); |
232 | end |
233 | else |
234 | print("Warning: missing jointType for inputAttacherJoint "..(index+1).."!"); |
235 | end |
236 | if jointType == nil then |
237 | local needsTrailerJoint = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsTrailerJoint"), false); |
238 | local needsLowTrailerJoint = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsLowJoint"), false); |
239 | if needsTrailerJoint then |
240 | if needsLowTrailerJoint then |
241 | jointType = AttacherJoints.JOINTTYPE_TRAILERLOW; |
242 | else |
243 | jointType = AttacherJoints.JOINTTYPE_TRAILER; |
244 | end |
245 | else |
246 | jointType = AttacherJoints.JOINTTYPE_IMPLEMENT; |
247 | end |
248 | end |
249 | inputAttacherJoint.jointType = jointType; |
250 | |
251 | inputAttacherJoint.jointOrigTrans = { getTranslation(inputAttacherJoint.node) }; |
252 | inputAttacherJoint.topReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#topReferenceNode")); |
253 | inputAttacherJoint.rootNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#rootNode")), self.components[1].node); |
254 | inputAttacherJoint.rootNodeBackup = inputAttacherJoint.rootNode |
255 | inputAttacherJoint.fixedRotation = Utils.getNoNil(getXMLBool(xmlFile, key .. "#fixedRotation"), false); |
256 | inputAttacherJoint.hardAttach = Utils.getNoNil(getXMLBool(xmlFile, key .. "#hardAttach"), false); |
257 | if inputAttacherJoint.hardAttach and #self.components > 1 then |
258 | print("Warning: hardAttach only available for single component vehicles in " .. self.configFileName.."!") |
259 | inputAttacherJoint.hardAttach = false |
260 | end |
261 | inputAttacherJoint.visualNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#indexVisual")); |
262 | if inputAttacherJoint.hardAttach and inputAttacherJoint.visualNode ~= nil then |
263 | inputAttacherJoint.visualNodeData = { |
264 | parent = getParent(inputAttacherJoint.visualNode), |
265 | translation = { getTranslation(inputAttacherJoint.visualNode) }, |
266 | rotation = { getRotation(inputAttacherJoint.visualNode) }, |
267 | index = getChildIndex(inputAttacherJoint.visualNode) |
268 | } |
269 | end |
270 | |
271 | |
272 | if jointType == AttacherJoints.JOINTTYPE_IMPLEMENT or jointType == AttacherJoints.JOINTTYPE_CUTTER then |
273 | if getXMLFloat(xmlFile, key .. "#lowerDistanceToGround") == nil then |
274 | print("Warning: Missing 'lowerDistanceToGround' for inputAttacherJoint "..(index+1).." in "..self.configFileName.."!"); |
275 | end |
276 | if getXMLFloat(xmlFile, key .. "#upperDistanceToGround") == nil then |
277 | print("Warning: Missing 'upperDistanceToGround' for inputAttacherJoint "..(index+1).." in "..self.configFileName.."!"); |
278 | end |
279 | end |
280 | inputAttacherJoint.lowerDistanceToGround = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#lowerDistanceToGround"), 0.7); |
281 | inputAttacherJoint.upperDistanceToGround = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#upperDistanceToGround"), 1.0); |
282 | inputAttacherJoint.lowerRotationOffset = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key .. "#lowerRotationOffset"), 0)); |
283 | |
284 | |
285 | local defaultUpperRotationOffset = 8 |
286 | if jointType == AttacherJoints.JOINTTYPE_WHEELLOADER or jointType == AttacherJoints.JOINTTYPE_TELEHANDLER or jointType == AttacherJoints.JOINTTYPE_FRONTLOADER then |
287 | defaultUpperRotationOffset = 0 |
288 | end |
289 | |
290 | inputAttacherJoint.upperRotationOffset = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key .. "#upperRotationOffset"), defaultUpperRotationOffset)); |
291 | |
292 | inputAttacherJoint.allowsJointRotLimitMovement = Utils.getNoNil(getXMLBool(xmlFile, key .. "#allowsJointRotLimitMovement"), true); |
293 | inputAttacherJoint.allowsJointTransLimitMovement = Utils.getNoNil(getXMLBool(xmlFile, key .. "#allowsJointTransLimitMovement"), true); |
294 | |
295 | inputAttacherJoint.needsToolbar = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsToolbar"), false); |
296 | if inputAttacherJoint.needsToolbar and jointType ~= AttacherJoints.JOINTTYPE_IMPLEMENT then |
297 | print("Warning: 'needsToolbar' requires jointType 'implement' for inputAttacherJoint "..(index+1).." in "..self.configFileName.."!"); |
298 | inputAttacherJoint.needsToolbar = false |
299 | end |
300 | |
301 | inputAttacherJoint.steeringBarLeftNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#steeringBarLeftNode")); |
302 | inputAttacherJoint.steeringBarRightNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#steeringBarRightNode")); |
303 | |
304 | --load joint limit scales |
305 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key .. "#upperRotLimitScale")); |
306 | inputAttacherJoint.upperRotLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }; |
307 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key .. "#lowerRotLimitScale")); |
308 | if jointType == AttacherJoints.JOINTTYPE_IMPLEMENT then |
309 | inputAttacherJoint.lowerRotLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 1) }; |
310 | else |
311 | inputAttacherJoint.lowerRotLimitScale = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }; |
312 | end |
313 | |
314 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key .. "#upperTransLimitScale")); |
315 | inputAttacherJoint.upperTransLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }; |
316 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key .. "#lowerTransLimitScale")); |
317 | inputAttacherJoint.lowerTransLimitScale = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 1), Utils.getNoNil(z, 0) }; |
318 | |
319 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitSpring")); |
320 | inputAttacherJoint.rotLimitSpring = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }; |
321 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitDamping")); |
322 | inputAttacherJoint.rotLimitDamping = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }; |
323 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitForceLimit")); |
324 | inputAttacherJoint.rotLimitForceLimit = { Utils.getNoNil(x, -1), Utils.getNoNil(y, -1), Utils.getNoNil(z, -1) }; |
325 | |
326 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#transLimitSpring")); |
327 | inputAttacherJoint.transLimitSpring = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }; |
328 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#transLimitDamping")); |
329 | inputAttacherJoint.transLimitDamping = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }; |
330 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#transLimitForceLimit")); |
331 | inputAttacherJoint.transLimitForceLimit = { Utils.getNoNil(x, -1), Utils.getNoNil(y, -1), Utils.getNoNil(z, -1) }; |
332 | |
333 | inputAttacherJoint.attacherHeight = getXMLFloat(xmlFile, key .. "#attacherHeight"); |
334 | if inputAttacherJoint.attacherHeight == nil then |
335 | if jointType == AttacherJoints.JOINTTYPE_TRAILER then |
336 | inputAttacherJoint.attacherHeight = 0.9; |
337 | elseif jointType == AttacherJoints.JOINTTYPE_TRAILERLOW then |
338 | inputAttacherJoint.attacherHeight = 0.55; |
339 | end |
340 | end |
341 | |
342 | local defaultNeedsLowering = true; |
343 | local defaultAllowsLowering = false; |
344 | if inputAttacherJoint.jointType == AttacherJoints.JOINTTYPE_TRAILER or inputAttacherJoint.jointType == AttacherJoints.JOINTTYPE_TRAILERLOW then |
345 | defaultNeedsLowering = false; |
346 | end |
347 | if inputAttacherJoint.jointType ~= AttacherJoints.JOINTTYPE_TRAILER and inputAttacherJoint.jointType ~= AttacherJoints.JOINTTYPE_TRAILERLOW then |
348 | defaultAllowsLowering = true; |
349 | end |
350 | inputAttacherJoint.needsLowering = Utils.getNoNil(getXMLBool(xmlFile, key.. "#needsLowering"), defaultNeedsLowering); |
351 | inputAttacherJoint.allowsLowering = Utils.getNoNil(getXMLBool(xmlFile, key.. "#allowsLowering"), defaultAllowsLowering); |
352 | inputAttacherJoint.isDefaultLowered = Utils.getNoNil(getXMLBool(xmlFile, key.. "#isDefaultLowered"), false); |
353 | inputAttacherJoint.useFoldingLoweredState = Utils.getNoNil(getXMLBool(xmlFile, key.. "#useFoldingLoweredState"), false); |
354 | inputAttacherJoint.forceSelection = Utils.getNoNil(getXMLBool(self.xmlFile, key.."#forceSelectionOnAttach"), true); |
355 | |
356 | inputAttacherJoint.dependentAttacherJoints = {} |
357 | local k = 0 |
358 | while true do |
359 | local dependentKey = string.format(key .. ".dependentAttacherJoint(%d)", k) |
360 | if not hasXMLProperty(xmlFile, dependentKey) then |
361 | break |
362 | end |
363 | local attacherJointIndex = getXMLInt(xmlFile, dependentKey.."#attacherJointIndex") |
364 | if attacherJointIndex ~= nil then |
365 | table.insert(inputAttacherJoint.dependentAttacherJoints, attacherJointIndex) |
366 | end |
367 | k = k + 1 |
368 | end |
369 | |
370 | -- reset values if hardAttach is active |
371 | if inputAttacherJoint.hardAttach then |
372 | inputAttacherJoint.needsLowering = false |
373 | inputAttacherJoint.allowsLowering = false |
374 | inputAttacherJoint.isDefaultLowered = false |
375 | inputAttacherJoint.upperRotationOffset = 0 |
376 | end |
377 | |
378 | inputAttacherJoint.changeObjects = {}; |
379 | ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, key, inputAttacherJoint.changeObjects, self.components, self); |
380 | |
381 | self:loadInputPowerTakeoff(xmlFile, key, inputAttacherJoint, "pto"); |
382 | self:loadInputPowerTakeoff(xmlFile, key, inputAttacherJoint, "pto2"); |
383 | |
384 | return true; |
385 | end |
386 | |
387 | return false; |
388 | end |
loadInputPowerTakeoff
DescriptionCalled on loadingDefinition
loadInputPowerTakeoff(table savegame)Arguments
table | savegame | savegame |
393 | function Attachable:loadInputPowerTakeoff(superFunc, xmlFile, baseName, entry, name) |
394 | if superFunc ~= nil then |
395 | superFunc(self, xmlFile, baseName, entry, name) |
396 | end |
397 | |
398 | if name == "pto" then |
399 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseName.."#indexPTO", baseName.."#ptoInputNode") |
400 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseName.."#rotSpeedPTO", baseName.."#ptoRotSpeed") |
401 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseName.."#aboveAttacherPTO", baseName.."#ptoAboveAttacher") |
402 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseName.."#sizePTO", baseName.."#ptoSize") |
403 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseName.."#overrideFilenamePTO", baseName.."#ptoOverrideFilename") |
404 | end |
405 | |
406 | local xmlKey = baseName .. "#"..name |
407 | local ptoInputNode = Utils.indexToObject(self.components, getXMLString(xmlFile, xmlKey.."InputNode")); |
408 | if ptoInputNode ~= nil then |
409 | if entry[name.."Input"] == nil then |
410 | entry[name.."Input"] = {} |
411 | end |
412 | |
413 | entry[name.."Input"].node = ptoInputNode |
414 | entry[name.."Input"].aboveAttacher = Utils.getNoNil(getXMLBool(xmlFile, xmlKey.."AboveAttacher"), true) |
415 | entry[name.."Input"].size = Utils.getNoNil(getXMLFloat(xmlFile, xmlKey.."Size"), 0.09) |
416 | |
417 | local rotSpeed = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, xmlKey.."RotSpeed"), 0)*0.001); |
418 | if math.abs(rotSpeed) < 0.00001 then |
419 | rotSpeed = 0; |
420 | end |
421 | entry[name.."Input"].rotSpeed = rotSpeed |
422 | |
423 | local filename = getXMLString(xmlFile, xmlKey .. "OverrideFilename"); |
424 | if filename ~= nil then |
425 | local i3dNode = Utils.loadSharedI3DFile(filename, self.baseDirectory, false, false, false); |
426 | if i3dNode ~= 0 then |
427 | local rootNode = getChildAt(i3dNode, 0); |
428 | unlink(rootNode); |
429 | delete(i3dNode); |
430 | setTranslation(rootNode, 0,0,0); |
431 | local dirAndScaleNode = getChildAt(rootNode, 0); |
432 | local attachNode = getChildAt(dirAndScaleNode, 0); |
433 | local attachRefNode = getChildAt(attachNode, 0); |
434 | |
435 | local _,_,baseDistance = getTranslation(attachNode); |
436 | unlink(attachNode); |
437 | local ax, ay, az = getTranslation(attachRefNode); |
438 | setTranslation(attachNode, -ax, -ay, -az); |
439 | |
440 | entry[name.."Input"].rootNode = rootNode; |
441 | entry[name.."Input"].dirAndScaleNode = dirAndScaleNode; |
442 | entry[name.."Input"].attachNode = attachNode; |
443 | entry[name.."Input"].baseDistance = baseDistance; |
444 | |
445 | end |
446 | end |
447 | end |
448 | end |
preDelete
DescriptionCalled on before deletingDefinition
preDelete()Code
452 | function Attachable:preDelete() |
453 | if self.attacherVehicle ~= nil then |
454 | self.attacherVehicle:detachImplementByObject(self, true); |
455 | end |
456 | end |
delete
DescriptionCalled on deletingDefinition
delete()Code
460 | function Attachable:delete() |
461 | if self.ptoInput ~= nil and self.ptoInput.rootNode ~= nil then |
462 | delete(self.ptoInput.rootNode); |
463 | delete(self.ptoInput.attachNode); |
464 | end |
465 | if self.pto2Input ~= nil and self.pto2Input.rootNode ~= nil then |
466 | delete(self.pto2Input.rootNode); |
467 | delete(self.pto2Input.attachNode); |
468 | end |
469 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
475 | function Attachable:readStream(streamId, connection) |
476 | if streamReadBool(streamId) then |
477 | local object = readNetworkNodeObject(streamId); |
478 | local inputJointDescIndex = streamReadInt8(streamId); |
479 | local jointDescIndex = streamReadInt8(streamId); |
480 | local moveDown = streamReadBool(streamId); |
481 | local implementIndex = streamReadInt8(streamId); |
482 | if object ~= nil then |
483 | object:attachImplement(self, inputJointDescIndex, jointDescIndex, true, implementIndex); |
484 | object:setJointMoveDown(jointDescIndex, moveDown, true); |
485 | end |
486 | end |
487 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
493 | function Attachable:writeStream(streamId, connection) |
494 | streamWriteBool(streamId, self.attacherVehicle ~= nil); |
495 | if self.attacherVehicle ~= nil then |
496 | local implementIndex = self.attacherVehicle:getImplementIndexByObject(self); |
497 | local implement = self.attacherVehicle.attachedImplements[implementIndex]; |
498 | local inputJointDescIndex = self.inputAttacherJointDescIndex; |
499 | local jointDescIndex = implement.jointDescIndex; |
500 | local jointDesc = self.attacherVehicle.attacherJoints[jointDescIndex]; |
501 | local moveDown = jointDesc.moveDown; |
502 | writeNetworkNodeObject(streamId, self.attacherVehicle); |
503 | streamWriteInt8(streamId, inputJointDescIndex); |
504 | streamWriteInt8(streamId, jointDescIndex); |
505 | streamWriteBool(streamId, moveDown); |
506 | streamWriteInt8(streamId, implementIndex); |
507 | end |
508 | end |
getSaveAttributesAndNodes
DescriptionReturns attributes and nodes to saveDefinition
getSaveAttributesAndNodes(table nodeIdent)Arguments
table | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
515 | function Attachable:getSaveAttributesAndNodes(nodeIdent) |
516 | local attributes = ''; |
517 | if self.lowerAnimation ~= nil and self.playAnimation ~= nil then |
518 | local lowerAnimTime = self:getAnimationTime(self.lowerAnimation); |
519 | attributes = attributes..' lowerAnimTime="'..lowerAnimTime..'"'; |
520 | end |
521 | local nodes = ""; |
522 | return attributes, nodes; |
523 | end |
update
DescriptionCalled on updateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
534 | function Attachable:update(dt) |
535 | if self:getIsActive() then |
536 | if self.updateSteeringAxleAngle then |
537 | local baseVehicle = self:getSteeringAxleBaseVehicle() |
538 | if baseVehicle ~= nil and (self.movingDirection >= 0 or self.steeringAxleUpdateBackwards) then |
539 | local yRot = Utils.getYRotationBetweenNodes(self.steeringAxleNode, baseVehicle.steeringAxleNode); |
540 | if math.abs(yRot) > 1.57 then |
541 | if yRot > 0 then |
542 | yRot = yRot - 3.14; |
543 | else |
544 | yRot = yRot + 3.14; |
545 | end; |
546 | end; |
547 | |
548 | local startSpeed = self.steeringAxleAngleScaleStart; |
549 | local endSpeed = self.steeringAxleAngleScaleEnd; |
550 | local scale = Utils.clamp(1 + (self:getLastSpeed()-startSpeed) * 1.0/(startSpeed-endSpeed), 0, 1); |
551 | self.steeringAxleTargetAngle = yRot*scale; |
552 | elseif self:getLastSpeed() > 0.2 then |
553 | self.steeringAxleTargetAngle = 0; |
554 | end |
555 | |
556 | local dir = Utils.sign(self.steeringAxleTargetAngle-self.steeringAxleAngle); |
557 | if dir == 1 then |
558 | self.steeringAxleAngle = math.min(self.steeringAxleAngle + dir*dt*self.steeringAxleAngleSpeed, self.steeringAxleTargetAngle); |
559 | else |
560 | self.steeringAxleAngle = math.max(self.steeringAxleAngle + dir*dt*self.steeringAxleAngleSpeed, self.steeringAxleTargetAngle); |
561 | end |
562 | end |
563 | |
564 | if self.firstTimeRun and self.updateWheels and self.isServer and self.isAddedToPhysics then |
565 | local brakeForce = self.brakeForce*self.brakePedal; |
566 | for _,wheel in pairs(self.wheels) do |
567 | setWheelShapeProps(wheel.node, wheel.wheelShape, 0, brakeForce*wheel.brakeFactor, wheel.steeringAngle, wheel.rotationDamping); |
568 | end |
569 | end |
570 | end |
571 | end |
onPreAttach
DescriptionCalled before vehicle gets attachedDefinition
onPreAttach(table attacherVehicle, integer inputAttacherJointDescIndex)Arguments
table | attacherVehicle | attacher vehicle |
integer | inputAttacherJointDescIndex | index of input attacher joint |
580 | function Attachable:onPreAttach(attacherVehicle, inputAttacherJointDescIndex) |
581 | self.ptoInput = self.inputAttacherJoints[inputAttacherJointDescIndex].ptoInput; |
582 | self.pto2Input = self.inputAttacherJoints[inputAttacherJointDescIndex].pto2Input; |
583 | self.attacherJoint = self.inputAttacherJoints[inputAttacherJointDescIndex]; |
584 | self.inputAttacherJointDescIndex = inputAttacherJointDescIndex; |
585 | end |
onAttached
DescriptionCalled after vehicle was attachedDefinition
onAttached(table attacherVehicle, table implement)Arguments
table | attacherVehicle | attacher vehicle |
table | implement | implement to attach |
591 | function Attachable:onAttached(attacherVehicle, implement) |
592 | local jointDesc = attacherVehicle.attacherJoints[implement.jointDescIndex]; |
593 | |
594 | if jointDesc.steeringBarLeftNode ~= nil and self.attacherJoint.steeringBarLeftMovingPart ~= nil then |
595 | for _,movingPart in pairs(self.movingParts) do |
596 | if movingPart.referencePoint == self.attacherJoint.steeringBarLeftMovingPart.referencePoint and movingPart ~= self.attacherJoint.steeringBarLeftMovingPart then |
597 | movingPart.referencePoint = jointDesc.steeringBarLeftNode; |
598 | end |
599 | end |
600 | self.attacherJoint.steeringBarLeftMovingPart.referencePoint = jointDesc.steeringBarLeftNode |
601 | end |
602 | if jointDesc.steeringBarRightNode ~= nil and self.attacherJoint.steeringBarRightMovingPart ~= nil then |
603 | for _,movingPart in pairs(self.movingParts) do |
604 | if movingPart.referencePoint == self.attacherJoint.steeringBarRightMovingPart.referencePoint and movingPart ~= self.attacherJoint.steeringBarRightMovingPart then |
605 | movingPart.referencePoint = jointDesc.steeringBarRightNode; |
606 | end |
607 | end |
608 | self.attacherJoint.steeringBarRightMovingPart.referencePoint = jointDesc.steeringBarRightNode |
609 | end |
610 | end |
onAttach
DescriptionCalled if vehicle gets attachedDefinition
onAttach(table attacherVehicle, integer jointDescIndex)Arguments
table | attacherVehicle | attacher vehicle |
integer | jointDescIndex | index of attacher joint it gets attached to |
616 | function Attachable:onAttach(attacherVehicle, jointDescIndex) |
617 | self.attacherVehicle = attacherVehicle; |
618 | self:setLightsTypesMask(attacherVehicle.lightsTypesMask, true, true); |
619 | self:setBeaconLightsVisibility(attacherVehicle.beaconLightsActive, true, true); |
620 | self:setTurnLightState(attacherVehicle.turnLightState, true, true); |
621 | |
622 | self.attachTime = g_currentMission.time; |
623 | |
624 | self:onReleaseBrake(); |
625 | |
626 | if self.supportAnimation ~= nil and self.playAnimation ~= nil then |
627 | self:playAnimation(self.supportAnimation, -1, nil, true); |
628 | end |
629 | |
630 | self:attachableAddToolCameras(); |
631 | |
632 | local rootAttacherVehicle = self:getRootAttacherVehicle(); |
633 | if rootAttacherVehicle ~= nil and rootAttacherVehicle.aiToolsDirtyFlag ~= nil then |
634 | rootAttacherVehicle.aiToolsDirtyFlag = true; |
635 | end |
636 | |
637 | ObjectChangeUtil.setObjectChanges(self.attacherJoint.changeObjects, true, self, self.setMovingToolDirty); |
638 | end |
onDetach
DescriptionCalled if vehicle gets detachedDefinition
onDetach(table attacherVehicle, integer jointDescIndex)Arguments
table | attacherVehicle | attacher vehicle |
integer | jointDescIndex | index of attacher joint it was attached to |
644 | function Attachable:onDetach(attacherVehicle, jointDescIndex) |
645 | self:onDeactivate(); |
646 | |
647 | ObjectChangeUtil.setObjectChanges(self.attacherJoint.changeObjects, false, self, self.setMovingToolDirty); |
648 | |
649 | |
650 | if self.supportAnimation ~= nil and self.playAnimation ~= nil then |
651 | self:playAnimation(self.supportAnimation, 1, nil, true); |
652 | end |
653 | |
654 | if self.lowerAnimation ~= nil and self.lowerAnimationDirectionOnDetach ~= 0 then |
655 | self:playAnimation(self.lowerAnimation, self.lowerAnimationDirectionOnDetach, nil, true); |
656 | end |
657 | |
658 | self:attachableRemoveToolCameras(); |
659 | |
660 | self.attacherVehicle = nil; |
661 | end |
onDetached
DescriptionCalled after vehicle was detachedDefinition
onDetached(table attacherVehicle, integer jointDescIndex)Arguments
table | attacherVehicle | attacher vehicle |
integer | jointDescIndex | index of attacher joint it was attached to |
667 | function Attachable:onDetached(attacherVehicle, jointDescIndex) |
668 | self.attacherJoint = nil; |
669 | self.attacherJointIndex = nil; |
670 | end |
onDeactivate
DescriptionCalled on deactivateDefinition
onDeactivate()Code
674 | function Attachable:onDeactivate() |
675 | self:onBrake(1, true); |
676 | end |
onSelect
DescriptionCalled on selectDefinition
onSelect()Code
680 | function Attachable:onSelect() |
681 | self.isSelected = true; |
682 | end |
onDeselect
DescriptionCalled on deselectDefinition
onDeselect()Code
686 | function Attachable:onDeselect() |
687 | self.isSelected = false; |
688 | end |
onBrake
DescriptionBreak the vehicleDefinition
onBrake(float brakePedal, boolean forced)Arguments
float | brakePedal | force of brake |
boolean | forced | force action |
694 | function Attachable:onBrake(brakePedal, forced) |
695 | -- do not brake for the first 2 seconds after attaching, to allow balancing of the difference between the attacher joints |
696 | if self.attachTime+2000 < g_currentMission.time or forced then |
697 | self.brakePedal = brakePedal; |
698 | if self.isServer and self.isAddedToPhysics then |
699 | for _,wheel in pairs(self.wheels) do |
700 | setWheelShapeProps(wheel.node, wheel.wheelShape, 0, self.brakeForce*brakePedal*wheel.brakeFactor, wheel.steeringAngle, wheel.rotationDamping); |
701 | end |
702 | end |
703 | for _,implement in pairs(self.attachedImplements) do |
704 | if implement.object ~= nil then |
705 | implement.object:onBrake(brakePedal, forced); |
706 | end |
707 | end |
708 | end |
709 | end |
onReleaseBrake
DescriptionRelease the brakeDefinition
onReleaseBrake()Code
713 | function Attachable:onReleaseBrake() |
714 | self.brakePedal = 0; |
715 | if self.isServer and self.isAddedToPhysics then |
716 | for _,wheel in pairs(self.wheels) do |
717 | setWheelShapeProps(wheel.node, wheel.wheelShape, 0, 0, wheel.steeringAngle, wheel.rotationDamping); |
718 | end |
719 | end |
720 | for _,implement in pairs(self.attachedImplements) do |
721 | if implement.object ~= nil then |
722 | implement.object:onReleaseBrake(); |
723 | end |
724 | end |
725 | end |
onSetLowered
DescriptionSet attachables lowering stateDefinition
onSetLowered(boolean lowered)Arguments
boolean | lowered | attachable is lowered |
730 | function Attachable:onSetLowered(lowered) |
731 | if self.lowerAnimation ~= nil and self.playAnimation ~= nil then |
732 | if lowered then |
733 | self:playAnimation(self.lowerAnimation, self.lowerAnimationSpeed, nil, true); |
734 | else |
735 | self:playAnimation(self.lowerAnimation, -self.lowerAnimationSpeed, nil, true); |
736 | end |
737 | end |
738 | |
739 | if self.attacherJoint ~= nil then |
740 | for _, dependentAttacherJointIndex in pairs(self.attacherJoint.dependentAttacherJoints) do |
741 | if self.attacherJoints[dependentAttacherJointIndex] ~= nil then |
742 | self:setJointMoveDown(dependentAttacherJointIndex, lowered, true); |
743 | end |
744 | end |
745 | end |
746 | end |
onLowerAll
DescriptionLower allDefinition
onLowerAll(boolean doLowering, integer jointDescIndex)Arguments
boolean | doLowering | do lowering |
integer | jointDescIndex | index of joint desc |
752 | function Attachable:onLowerAll(doLowering, jointDescIndex) |
753 | self.attacherVehicle:setJointMoveDown(jointDescIndex, doLowering, true); |
754 | end |
getIsInWorkPosition
DescriptionReturns true if it is in work positionDefinition
getIsInWorkPosition()Return Values
boolean | inWorkPosition | is in work position |
759 | function Attachable:getIsInWorkPosition(superFunc) |
760 | if superFunc ~= nil then |
761 | if not superFunc(self) then |
762 | return false; |
763 | end |
764 | end |
765 | |
766 | return true; |
767 | end |
isDetachAllowed
DescriptionReturns true if detach is allowedDefinition
isDetachAllowed()Return Values
boolean | detachAllowed | detach is allowed |
772 | function Attachable:isDetachAllowed(superFunc) |
773 | if superFunc ~= nil then |
774 | if not superFunc(self) then |
775 | return false; |
776 | end |
777 | end |
778 | |
779 | return Utils.getNoNil(self.allowsDetaching, true) |
780 | end |
getIsInputAttacherActive
DescriptionReturns true if input attacher is active and can be used to attachDefinition
getIsInputAttacherActive(table inputAttacherJoint)Arguments
table | inputAttacherJoint | input attacher joint |
boolean | isActive | input attacher is active |
786 | function Attachable:getIsInputAttacherActive(superFunc, inputAttacherJoint) |
787 | if superFunc ~= nil then |
788 | if not superFunc(self, inputAttacherJoint) then |
789 | return false; |
790 | end |
791 | end |
792 | |
793 | return true; |
794 | end |
getSteeringAxleBaseVehicle
DescriptionReturns vehicle used to calculate steering axleDefinition
getSteeringAxleBaseVehicle()Return Values
table | vehicle | vehicle |
799 | function Attachable:getSteeringAxleBaseVehicle(superFunc) |
800 | if self.steeringAxleUseSuperAttachable then |
801 | if self.attacherVehicle ~= nil then |
802 | return self.attacherVehicle.attacherVehicle; |
803 | end; |
804 | end |
805 | |
806 | return self.attacherVehicle; |
807 | end |
getIsPowerTakeoffActive
DescriptionReturns true if pto is activeDefinition
getIsPowerTakeoffActive()Return Values
boolean | isActive | pto is active |
812 | function Attachable:getIsPowerTakeoffActive(superFunc) |
813 | if superFunc ~= nil then |
814 | if not superFunc(self) then |
815 | return false; |
816 | end |
817 | end |
818 | |
819 | if self:getIsTurnedOn() then |
820 | return true; |
821 | end |
822 | |
823 | return false; |
824 | end |
attachableAddToolCameras
DescriptionAdd tool cameras to root attacher vehicleDefinition
attachableAddToolCameras()Code
828 | function Attachable:attachableAddToolCameras() |
829 | for _,implement in pairs(self.attachedImplements) do |
830 | if implement.object ~= nil then |
831 | implement.object:attachableAddToolCameras(); |
832 | end |
833 | end |
834 | local rootAttacherVehicle = self:getRootAttacherVehicle(); |
835 | if self.numToolCameras > 0 and rootAttacherVehicle.addToolCameras ~= nil then |
836 | rootAttacherVehicle:addToolCameras(self.toolCameras); |
837 | end |
838 | end |
attachableRemoveToolCameras
DescriptionRemove tool cameras from root attacher vehicleDefinition
attachableRemoveToolCameras()Code
842 | function Attachable:attachableRemoveToolCameras() |
843 | for _,implement in pairs(self.attachedImplements) do |
844 | if implement.object ~= nil then |
845 | implement.object:attachableRemoveToolCameras(); |
846 | end |
847 | end |
848 | local rootAttacherVehicle = self:getRootAttacherVehicle(); |
849 | if self.numToolCameras > 0 and rootAttacherVehicle.removeToolCameras ~= nil then |
850 | rootAttacherVehicle:removeToolCameras(self.toolCameras); |
851 | end |
852 | end |
onAiRaise
DescriptionCalled on ai raiseDefinition
onAiRaise()Code
856 | function Attachable:onAiRaise() |
857 | local implement = self.attacherVehicle:getImplementByObject(self); |
858 | local jointDesc = self.attacherVehicle.attacherJoints[implement.jointDescIndex]; |
859 | if jointDesc.allowsLowering then |
860 | if self.aiNeedsLowering then |
861 | self.attacherVehicle:setJointMoveDown(implement.jointDescIndex, false, false); |
862 | end |
863 | end |
864 | end |
onAiLower
DescriptionCalled on ai lowerDefinition
onAiLower()Code
868 | function Attachable:onAiLower() |
869 | local implement = self.attacherVehicle:getImplementByObject(self); |
870 | local jointDesc = self.attacherVehicle.attacherJoints[implement.jointDescIndex]; |
871 | if jointDesc.allowsLowering then |
872 | if self.aiNeedsLowering then |
873 | self.attacherVehicle:setJointMoveDown(implement.jointDescIndex, true, false); |
874 | end |
875 | end |
876 | end |
getIsAIReadyForWork
DescriptionReturns true if vehicle is ready for ai workDefinition
getIsAIReadyForWork()Return Values
boolean | isReady | is ready for ai work |
881 | function Attachable:getIsAIReadyForWork() |
882 | local isReady = true; |
883 | if self.lowerAnimation ~= nil then |
884 | local t = self:getAnimationTime(self.lowerAnimation); |
885 | if self.lowerAnimationSpeed > 0 then |
886 | isReady = t == 1; |
887 | else |
888 | isReady = t == 0; |
889 | end |
890 | if not isReady then |
891 | if not self:getIsAnimationPlaying(self.lowerAnimation) then |
892 | self:playAnimation(self.lowerAnimation, self.lowerAnimationSpeed, self:getAnimationTime(self.lowerAnimation), false); |
893 | end |
894 | end |
895 | end |
896 | |
897 | local implement = self.attacherVehicle:getImplementByObject(self); |
898 | local jointDesc = self.attacherVehicle.attacherJoints[implement.jointDescIndex]; |
899 | if jointDesc.allowsLowering and self.aiNeedsLowering then |
900 | if jointDesc.moveDown then |
901 | return jointDesc.moveAlpha == jointDesc.lowerAlpha and isReady; |
902 | else |
903 | self.attacherVehicle:setJointMoveDown(implement.jointDescIndex, true, false); |
904 | return false; |
905 | end |
906 | else |
907 | return isReady; |
908 | end |
909 | end |
getIsOperating
DescriptionReturns if vehicle is operatingDefinition
getIsOperating()Return Values
boolean | isOperating | is operating |
914 | function Attachable:getIsOperating(superFunc) |
915 | local isOperating = false |
916 | if superFunc ~= nil then |
917 | isOperating = superFunc(self) |
918 | end |
919 | |
920 | if not isOperating and self.attacherVehicle ~= nil then |
921 | isOperating = self.attacherVehicle:getIsOperating() |
922 | end |
923 | |
924 | return isOperating |
925 | end |