Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Attachable |
3 | -- This is the specialization for all vehicles that may be attached |
4 | -- |
5 | -- @author Stefan Geiger |
6 | -- @date 22/05/14 |
7 | -- |
8 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
9 | |
10 | Attachable = {}; |
11 | |
12 | function Attachable.prerequisitesPresent(specializations) |
13 | return true; |
14 | end; |
15 | |
16 | function Attachable:preLoad(xmlFile) |
17 | self.getIsPowerTakeoffActive = Attachable.getIsPowerTakeoffActive; |
18 | self.isDetachAllowed = Attachable.isDetachAllowed; |
19 | self.getIsInputAttacherActive = Attachable.getIsInputAttacherActive; |
20 | self.loadInputAttacherJoint = Attachable.loadInputAttacherJoint; |
21 | self.getIsInWorkPosition = Attachable.getIsInWorkPosition; |
22 | end; |
23 | |
24 | function Attachable:load(xmlFile) |
25 | |
26 | self.onAttach = SpecializationUtil.callSpecializationsFunction("onAttach"); |
27 | self.onAttached = SpecializationUtil.callSpecializationsFunction("onAttached"); |
28 | self.onPreAttach = SpecializationUtil.callSpecializationsFunction("onPreAttach"); |
29 | self.onDetach = SpecializationUtil.callSpecializationsFunction("onDetach"); |
30 | self.onDetached = SpecializationUtil.callSpecializationsFunction("onDetached"); |
31 | self.onSelect = SpecializationUtil.callSpecializationsFunction("onSelect"); |
32 | self.onDeselect = SpecializationUtil.callSpecializationsFunction("onDeselect"); |
33 | self.onBrake = SpecializationUtil.callSpecializationsFunction("onBrake"); |
34 | self.onReleaseBrake = SpecializationUtil.callSpecializationsFunction("onReleaseBrake"); |
35 | self.onSetLowered = SpecializationUtil.callSpecializationsFunction("onSetLowered"); |
36 | self.aiTurnOn = SpecializationUtil.callSpecializationsFunction("aiTurnOn"); |
37 | self.aiTurnOff = SpecializationUtil.callSpecializationsFunction("aiTurnOff"); |
38 | self.aiLower = SpecializationUtil.callSpecializationsFunction("aiLower"); |
39 | self.aiRaise = SpecializationUtil.callSpecializationsFunction("aiRaise"); |
40 | self.aiRotateLeft = SpecializationUtil.callSpecializationsFunction("aiRotateLeft"); |
41 | self.aiRotateRight = SpecializationUtil.callSpecializationsFunction("aiRotateRight"); |
42 | self.updatePowerTakeoff = SpecializationUtil.callSpecializationsFunction("updatePowerTakeoff"); |
43 | self.onLowerAll = SpecializationUtil.callSpecializationsFunction("onLowerAll"); |
44 | self.attachableAddToolCameras = SpecializationUtil.callSpecializationsFunction("attachableAddToolCameras"); |
45 | self.attachableRemoveToolCameras = SpecializationUtil.callSpecializationsFunction("attachableRemoveToolCameras"); |
46 | |
47 | Attachable.loadPTOInput(self, xmlFile, "vehicle.powerTakeoffInput", self, ""); |
48 | |
49 | self.attacherJoint = nil; |
50 | self.inputAttacherJoints = {}; |
51 | local i = 0; |
52 | while true do |
53 | local key = string.format("vehicle.inputAttacherJoints.inputAttacherJoint(%d)", i); |
54 | if not hasXMLProperty(xmlFile, key) then |
55 | break; |
56 | end |
57 | |
58 | local inputAttacherJoint = {}; |
59 | if self:loadInputAttacherJoint(xmlFile, key, inputAttacherJoint) then |
60 | table.insert(self.inputAttacherJoints, inputAttacherJoint); |
61 | end; |
62 | |
63 | i = i + 1; |
64 | end; |
65 | |
66 | -- backward compatibility |
67 | local inputAttacherJoint = {}; |
68 | if self:loadInputAttacherJoint(xmlFile, "vehicle.attacherJoint", inputAttacherJoint) then |
69 | table.insert(self.inputAttacherJoints, inputAttacherJoint); |
70 | end; |
71 | |
72 | if hasXMLProperty(xmlFile, "vehicle.topReferenceNode#index") then |
73 | print("Warning: vehicle.topReferenceNode is ignored, update to vehicle.attacherJoint#topReferenceNode"); |
74 | end; |
75 | |
76 | if hasXMLProperty(xmlFile, "vehicle.attachRootNode#index") then |
77 | print("Warning: vehicle.attachRootNode is ignored, update to vehicle.attacherJoint#rootNode"); |
78 | end; |
79 | |
80 | self.brakeForce = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.brakeForce"), 0)*10; |
81 | |
82 | self.brakePedal = 0.0; |
83 | self.updateWheels = true; |
84 | self.updateSteeringAxleAngle = true; |
85 | |
86 | self.isSelected = false; |
87 | self.attachTime = 0; |
88 | |
89 | self.steeringAxleAngleScaleStart = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.steeringAxleAngleScale#startSpeed"), 10); |
90 | self.steeringAxleAngleScaleEnd = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.steeringAxleAngleScale#endSpeed"), 30); |
91 | self.steeringAxleUpdateBackwards = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.steeringAxleAngleScale#backwards"), false); |
92 | self.steeringAxleAngleSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.steeringAxleAngleScale#speed"), 0.001); |
93 | |
94 | self.supportAnimation = getXMLString(xmlFile, "vehicle.support#animationName"); |
95 | self.lowerAnimation = getXMLString(xmlFile, "vehicle.lowerAnimation#name"); |
96 | self.lowerAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.lowerAnimation#speed"), 1); |
97 | |
98 | self.aiLeftMarker = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aiLeftMarker#index")); |
99 | self.aiRightMarker = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aiRightMarker#index")); |
100 | self.aiBackMarker = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aiBackMarker#index")); |
101 | self.aiTrafficCollisionTrigger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aiTrafficCollisionTrigger#index")); |
102 | |
103 | local defaultNeedsLowering = false; |
104 | for _, joint in pairs(self.inputAttacherJoints) do |
105 | if joint.needsLowering then |
106 | defaultNeedsLowering = true; |
107 | break; |
108 | end |
109 | end |
110 | self.aiNeedsLowering = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.aiNeedsLowering#value"), defaultNeedsLowering); |
111 | self.aiForceTurnNoBackward = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.aiForceTurnNoBackward#value"), false); |
112 | |
113 | self.aiTerrainDetailChannel1 = -1; |
114 | self.aiTerrainDetailChannel2 = -1; |
115 | self.aiTerrainDetailChannel3 = -1; |
116 | self.aiTerrainDetailChannel4 = -1; |
117 | |
118 | self.aiTerrainDetailProhibitedMask = 0; |
119 | self.aiRequiredFruitType = FruitUtil.FRUITTYPE_UNKNOWN; |
120 | self.aiRequiredMinGrowthState = 0; |
121 | self.aiRequiredMaxGrowthState = 0; |
122 | self.aiProhibitedFruitType = FruitUtil.FRUITTYPE_UNKNOWN; |
123 | self.aiProhibitedMinGrowthState = 0; |
124 | self.aiProhibitedMaxGrowthState = 0; |
125 | |
126 | self.deactivateOnDetach = true; |
127 | |
128 | if table.getn(self.inputAttacherJoints) > 0 then |
129 | -- all attachables are selectable, since they need to be detached |
130 | self.isSelectable = true; |
131 | self.forceSelection = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.forceSelectionOnAttach#value"), true); |
132 | end; |
133 | |
134 | self.numToolCameras = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.toolCameras#count"), 0); |
135 | self.toolCameras = {}; |
136 | for i=1, self.numToolCameras do |
137 | local cameraKey = string.format("vehicle.toolCameras.toolCamera%d", i); |
138 | local camera = VehicleCamera:new(self); |
139 | if camera:loadFromXML(xmlFile, cameraKey) then |
140 | table.insert(self.toolCameras, camera); |
141 | end; |
142 | end; |
143 | end; |
144 | |
145 | function Attachable:loadInputAttacherJoint(xmlFile, key, inputAttacherJoint) |
146 | local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#index")); |
147 | if node ~= nil then |
148 | inputAttacherJoint.node = node; |
149 | inputAttacherJoint.jointOrigTrans = { getTranslation(inputAttacherJoint.node) }; |
150 | inputAttacherJoint.topReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#topReferenceNode")); |
151 | inputAttacherJoint.rootNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#rootNode")), self.components[1].node); |
152 | inputAttacherJoint.fixedRotation = Utils.getNoNil(getXMLBool(xmlFile, key .. "#fixedRotation"), false); |
153 | inputAttacherJoint.lowerDistanceToGround = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#lowerDistanceToGround"), 0.7); |
154 | inputAttacherJoint.upperDistanceToGround = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#upperDistanceToGround"), 1.0); |
155 | inputAttacherJoint.lowerRotationOffset = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key .. "#lowerRotationOffset"), 0)); |
156 | inputAttacherJoint.upperRotationOffset = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key .. "#upperRotationOffset"), 8)); |
157 | |
158 | inputAttacherJoint.allowsJointRotLimitMovement = Utils.getNoNil(getXMLBool(xmlFile, key .. "#allowsJointRotLimitMovement"), true); |
159 | inputAttacherJoint.allowsJointTransLimitMovement = Utils.getNoNil(getXMLBool(xmlFile, key .. "#allowsJointTransLimitMovement"), true); |
160 | |
161 | --load joint limit scales |
162 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key .. "#rotLimitScale")); |
163 | inputAttacherJoint.rotLimitScale = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }; |
164 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key .. "#transLimitScale")); |
165 | inputAttacherJoint.transLimitScale = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }; |
166 | |
167 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitSpring")); |
168 | local rotLimitSpring = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }; |
169 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rotLimitDamping")); |
170 | local rotLimitDamping = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }; |
171 | inputAttacherJoint.rotLimitSpring = rotLimitSpring; |
172 | inputAttacherJoint.rotLimitDamping = rotLimitDamping; |
173 | |
174 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#transLimitSpring")); |
175 | local transLimitSpring = { Utils.getNoNil(x, 0), Utils.getNoNil(y, 0), Utils.getNoNil(z, 0) }; |
176 | local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#transLimitDamping")); |
177 | local transLimitDamping = { Utils.getNoNil(x, 1), Utils.getNoNil(y, 1), Utils.getNoNil(z, 1) }; |
178 | inputAttacherJoint.transLimitSpring = transLimitSpring; |
179 | inputAttacherJoint.transLimitDamping = transLimitDamping; |
180 | |
181 | local jointTypeStr = getXMLString(xmlFile, key .. "#jointType") |
182 | local jointType; |
183 | if jointTypeStr ~= nil then |
184 | jointType = Vehicle.jointTypeNameToInt[jointTypeStr]; |
185 | if jointType == nil then |
186 | print("Warning: invalid jointType " .. jointTypeStr); |
187 | end; |
188 | else |
189 | print("Warning: missing jointType"); |
190 | end; |
191 | if jointType == nil then |
192 | local needsTrailerJoint = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsTrailerJoint"), false); |
193 | local needsLowTrailerJoint = Utils.getNoNil(getXMLBool(xmlFile, key .. "#needsLowJoint"), false); |
194 | if needsTrailerJoint then |
195 | if needsLowTrailerJoint then |
196 | jointType = Vehicle.JOINTTYPE_TRAILERLOW; |
197 | else |
198 | jointType = Vehicle.JOINTTYPE_TRAILER; |
199 | end; |
200 | else |
201 | jointType = Vehicle.JOINTTYPE_IMPLEMENT; |
202 | end; |
203 | end; |
204 | inputAttacherJoint.jointType = jointType; |
205 | |
206 | inputAttacherJoint.attacherHeight = getXMLFloat(xmlFile, key .. "#attacherHeight"); |
207 | if inputAttacherJoint.attacherHeight == nil then |
208 | if jointType == Vehicle.JOINTTYPE_TRAILER then |
209 | inputAttacherJoint.attacherHeight = 0.9; |
210 | elseif jointType == Vehicle.JOINTTYPE_TRAILERLOW then |
211 | inputAttacherJoint.attacherHeight = 0.55; |
212 | end; |
213 | end; |
214 | |
215 | local defaultNeedsLowering = true; |
216 | local defaultAllowsLowering = false; |
217 | if inputAttacherJoint.jointType == Vehicle.JOINTTYPE_TRAILER or inputAttacherJoint.jointType == Vehicle.JOINTTYPE_TRAILERLOW then |
218 | defaultNeedsLowering = false; |
219 | end; |
220 | if inputAttacherJoint.jointType ~= Vehicle.JOINTTYPE_TRAILER and inputAttacherJoint.jointType ~= Vehicle.JOINTTYPE_TRAILERLOW then |
221 | defaultAllowsLowering = true; |
222 | end; |
223 | inputAttacherJoint.needsLowering = Utils.getNoNil(getXMLBool(xmlFile, key.. "#needsLowering"), Utils.getNoNil(getXMLBool(xmlFile, "vehicle.needsLowering#value"), defaultNeedsLowering)); |
224 | inputAttacherJoint.allowsLowering = Utils.getNoNil(getXMLBool(xmlFile, key.. "#allowsLowering"), Utils.getNoNil(getXMLBool(xmlFile, "vehicle.allowsLowering#value"), defaultAllowsLowering)); |
225 | inputAttacherJoint.isDefaultLowered = Utils.getNoNil(getXMLBool(xmlFile, key.. "#isDefaultLowered"), Utils.getNoNil(getXMLBool(xmlFile, "vehicle.isDefaultLowered#value"), false)); |
226 | |
227 | Attachable.loadPTOInput(self, xmlFile, key, inputAttacherJoint, "PTO"); |
228 | if inputAttacherJoint.ptoInput == nil then |
229 | inputAttacherJoint.ptoInput = self.ptoInput; |
230 | end; |
231 | |
232 | return true; |
233 | end; |
234 | |
235 | return false; |
236 | end; |
237 | |
238 | function Attachable:loadPTOInput(xmlFile, basename, inputAttacher, attrPostFix) |
239 | local attrPostFix = Utils.getNoNil(attrPostFix, ""); |
240 | local ptoInputNode = Utils.indexToObject(self.components, getXMLString(xmlFile, basename .. "#index"..attrPostFix)); |
241 | if ptoInputNode ~= nil then |
242 | local rotSpeed = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, basename .. "#rotSpeed"..attrPostFix), 0)*0.001); |
243 | if math.abs(rotSpeed) < 0.00001 then |
244 | rotSpeed = 0; |
245 | end |
246 | |
247 | inputAttacher.ptoInput = {node = ptoInputNode, rotSpeed=rotSpeed}; |
248 | |
249 | local filename = getXMLString(xmlFile, basename .. "#overrideFilename"..attrPostFix); |
250 | if filename ~= nil then |
251 | local i3dNode = Utils.loadSharedI3DFile(filename, self.baseDirectory, false, false, false); |
252 | if i3dNode ~= 0 then |
253 | local rootNode = getChildAt(i3dNode, 0); |
254 | unlink(rootNode); |
255 | delete(i3dNode); |
256 | setTranslation(rootNode, 0,0,0); |
257 | local dirAndScaleNode = getChildAt(rootNode, 0); |
258 | local attachNode = getChildAt(dirAndScaleNode, 0); |
259 | local attachRefNode = getChildAt(attachNode, 0); |
260 | |
261 | local _,_,baseDistance = getTranslation(attachNode); |
262 | unlink(attachNode); |
263 | local ax, ay, az = getTranslation(attachRefNode); |
264 | setTranslation(attachNode, -ax, -ay, -az); |
265 | |
266 | inputAttacher.ptoInput.rootNode = rootNode; |
267 | inputAttacher.ptoInput.dirAndScaleNode = dirAndScaleNode; |
268 | inputAttacher.ptoInput.attachNode = attachNode; |
269 | inputAttacher.ptoInput.baseDistance = baseDistance; |
270 | end |
271 | end |
272 | end |
273 | end; |
274 | |
275 | function Attachable:preDelete() |
276 | if self.attacherVehicle ~= nil then |
277 | self.attacherVehicle:detachImplementByObject(self, true); |
278 | end; |
279 | end; |
280 | |
281 | function Attachable:delete() |
282 | if self.ptoInput ~= nil and self.ptoInput.rootNode ~= nil then |
283 | delete(self.ptoInput.rootNode); |
284 | delete(self.ptoInput.attachNode); |
285 | end |
286 | end; |
287 | |
288 | function Attachable:readStream(streamId, connection) |
289 | if streamReadBool(streamId) then |
290 | local attacherId = streamReadInt32(streamId); |
291 | local inputJointDescIndex = streamReadInt8(streamId); |
292 | local jointDescIndex = streamReadInt8(streamId); |
293 | local moveDown = streamReadBool(streamId); |
294 | local implementIndex = streamReadInt8(streamId); |
295 | local object = networkGetObject(attacherId) |
296 | if object ~= nil then |
297 | object:attachImplement(self, inputJointDescIndex, jointDescIndex, true, implementIndex); |
298 | object:setJointMoveDown(jointDescIndex, moveDown, true); |
299 | end; |
300 | end; |
301 | end; |
302 | |
303 | function Attachable:writeStream(streamId, connection) |
304 | streamWriteBool(streamId, self.attacherVehicle ~= nil); |
305 | if self.attacherVehicle ~= nil then |
306 | local implementIndex = self.attacherVehicle:getImplementIndexByObject(self); |
307 | local implement = self.attacherVehicle.attachedImplements[implementIndex]; |
308 | local inputJointDescIndex = self.inputAttacherJointDescIndex; |
309 | local jointDescIndex = implement.jointDescIndex; |
310 | local jointDesc = self.attacherVehicle.attacherJoints[jointDescIndex]; |
311 | local moveDown = jointDesc.moveDown; |
312 | streamWriteInt32(streamId, networkGetObjectId(self.attacherVehicle)); |
313 | streamWriteInt8(streamId, inputJointDescIndex); |
314 | streamWriteInt8(streamId, jointDescIndex); |
315 | streamWriteBool(streamId, moveDown); |
316 | streamWriteInt8(streamId, implementIndex); |
317 | end; |
318 | end; |
319 | |
320 | |
321 | function Attachable:loadFromAttributesAndNodes(xmlFile, key, resetVehicles) |
322 | if not resetVehicles then |
323 | if self.lowerAnimation ~= nil and self.playAnimation ~= nil then |
324 | local lowerAnimTime = getXMLFloat(xmlFile, key.."#lowerAnimTime"); |
325 | if lowerAnimTime ~= nil then |
326 | local speed = 1; |
327 | if lowerAnimTime < 0.5 then |
328 | speed = -1; |
329 | end |
330 | self:playAnimation(self.lowerAnimation, speed, nil, true); |
331 | self:setAnimationTime(self.lowerAnimation, lowerAnimTime); |
332 | |
333 | if self.updateCylinderedInitial ~= nil then |
334 | self:updateCylinderedInitial(false); |
335 | end |
336 | end |
337 | end |
338 | end |
339 | |
340 | return BaseMission.VEHICLE_LOAD_OK; |
341 | end; |
342 | |
343 | function Attachable:getSaveAttributesAndNodes(nodeIdent) |
344 | local attributes = ''; |
345 | if self.lowerAnimation ~= nil and self.playAnimation ~= nil then |
346 | local lowerAnimTime = self:getAnimationTime(self.lowerAnimation); |
347 | attributes = attributes..' lowerAnimTime="'..lowerAnimTime..'"'; |
348 | end |
349 | local nodes = ""; |
350 | return attributes, nodes; |
351 | end; |
352 | |
353 | |
354 | function Attachable:mouseEvent(posX, posY, isDown, isUp, button) |
355 | end; |
356 | |
357 | function Attachable:keyEvent(unicode, sym, modifier, isDown) |
358 | end; |
359 | |
360 | function Attachable:update(dt) |
361 | if self:getIsActive() then |
362 | if self.updateSteeringAxleAngle then |
363 | if self.attacherVehicle ~= nil and (self.movingDirection >= 0 or self.steeringAxleUpdateBackwards) then |
364 | local yRot = Utils.getYRotationBetweenNodes(self.steeringAxleNode, self.attacherVehicle.steeringAxleNode); |
365 | local startSpeed = self.steeringAxleAngleScaleStart; |
366 | local endSpeed = self.steeringAxleAngleScaleEnd; |
367 | local scale = Utils.clamp(1 + (self:getLastSpeed()-startSpeed) * 1.0/(startSpeed-endSpeed), 0, 1); |
368 | self.steeringAxleTargetAngle = yRot*scale; |
369 | else |
370 | self.steeringAxleTargetAngle = 0; |
371 | end; |
372 | |
373 | local dir = Utils.sign(self.steeringAxleTargetAngle-self.steeringAxleAngle); |
374 | if dir == 1 then |
375 | self.steeringAxleAngle = math.min(self.steeringAxleAngle + dir*dt*self.steeringAxleAngleSpeed, self.steeringAxleTargetAngle); |
376 | else |
377 | self.steeringAxleAngle = math.max(self.steeringAxleAngle + dir*dt*self.steeringAxleAngleSpeed, self.steeringAxleTargetAngle); |
378 | end; |
379 | end; |
380 | |
381 | if self.firstTimeRun and self.updateWheels and self.isServer then |
382 | local brakeForce = self.brakeForce*self.brakePedal; |
383 | for _,wheel in pairs(self.wheels) do |
384 | setWheelShapeProps(wheel.node, wheel.wheelShape, 0, brakeForce, wheel.steeringAngle); |
385 | end; |
386 | end; |
387 | end; |
388 | end; |
389 | |
390 | function Attachable:draw() |
391 | end; |
392 | |
393 | function Attachable:onPreAttach(attacherVehicle, inputAttacherJointDescIndex) |
394 | self.ptoInput = self.inputAttacherJoints[inputAttacherJointDescIndex].ptoInput; |
395 | self.attacherJoint = self.inputAttacherJoints[inputAttacherJointDescIndex]; |
396 | self.inputAttacherJointDescIndex = inputAttacherJointDescIndex; |
397 | end; |
398 | |
399 | function Attachable:onAttach(attacherVehicle, jointDescIndex) |
400 | self.attacherVehicle = attacherVehicle; |
401 | self:setLightsTypesMask(attacherVehicle.lightsTypesMask, true); |
402 | self:setBeaconLightsVisibility(attacherVehicle.beaconLightsActive, true); |
403 | self:setTurnSignalState(attacherVehicle.turnSignalState, true); |
404 | |
405 | self.attachTime = g_currentMission.time; |
406 | |
407 | self:onReleaseBrake(); |
408 | |
409 | if self.supportAnimation ~= nil and self.playAnimation ~= nil then |
410 | self:playAnimation(self.supportAnimation, -1, nil, true); |
411 | end; |
412 | |
413 | self:attachableAddToolCameras(); |
414 | end; |
415 | |
416 | function Attachable:onDetach(attacherVehicle, jointDescIndex) |
417 | if self.deactivateOnDetach then |
418 | self:onDeactivate(); |
419 | else |
420 | self:onDeactivateSounds(); |
421 | self:onDeactivateLights(); |
422 | end; |
423 | |
424 | if self.supportAnimation ~= nil and self.playAnimation ~= nil then |
425 | self:playAnimation(self.supportAnimation, 1, nil, true); |
426 | end; |
427 | |
428 | self:attachableRemoveToolCameras(); |
429 | |
430 | self.attacherVehicle = nil; |
431 | end; |
432 | |
433 | function Attachable:onDetached(attacherVehicle, jointDescIndex) |
434 | self.attacherJoint = nil; |
435 | self.attacherJointIndex = nil; |
436 | end; |
437 | |
438 | function Attachable:onDeactivate() |
439 | self:onBrake(1, true); |
440 | self.steeringAxleAngle = 0; |
441 | end; |
442 | |
443 | function Attachable:onSelect() |
444 | self.isSelected = true; |
445 | end; |
446 | |
447 | function Attachable:onDeselect() |
448 | self.isSelected = false; |
449 | end; |
450 | |
451 | function Attachable:onBrake(brakePedal, forced) |
452 | -- do not brake for the first 2 seconds after attaching, to allow balancing of the difference between the attacher joints |
453 | if self.attachTime+2000 < g_currentMission.time or forced then |
454 | self.brakePedal = brakePedal; |
455 | if self.isServer then |
456 | for _,wheel in pairs(self.wheels) do |
457 | setWheelShapeProps(wheel.node, wheel.wheelShape, 0, self.brakeForce*brakePedal, wheel.steeringAngle); |
458 | end; |
459 | end; |
460 | for _,implement in pairs(self.attachedImplements) do |
461 | if implement.object ~= nil then |
462 | implement.object:onBrake(brakePedal, forced); |
463 | end |
464 | end; |
465 | end; |
466 | end; |
467 | |
468 | function Attachable:onReleaseBrake() |
469 | self.brakePedal = 0; |
470 | if self.isServer then |
471 | for _,wheel in pairs(self.wheels) do |
472 | setWheelShapeProps(wheel.node, wheel.wheelShape, 0, 0, wheel.steeringAngle); |
473 | end; |
474 | end; |
475 | for _,implement in pairs(self.attachedImplements) do |
476 | if implement.object ~= nil then |
477 | implement.object:onReleaseBrake(); |
478 | end |
479 | end; |
480 | end; |
481 | |
482 | function Attachable:onSetLowered(lowered) |
483 | if self.lowerAnimation ~= nil and self.playAnimation ~= nil then |
484 | if lowered then |
485 | self:playAnimation(self.lowerAnimation, self.lowerAnimationSpeed, nil, true); |
486 | else |
487 | self:playAnimation(self.lowerAnimation, -self.lowerAnimationSpeed, nil, true); |
488 | end; |
489 | end; |
490 | end; |
491 | |
492 | function Attachable:getIsInWorkPosition() |
493 | return true; |
494 | end; |
495 | |
496 | function Attachable:isDetachAllowed() |
497 | return Utils.getNoNil(self.allowsDetaching, true) |
498 | end; |
499 | |
500 | function Attachable:onLowerAll(doLowering, jointDescIndex) |
501 | self.attacherVehicle:setJointMoveDown(jointDescIndex, doLowering, true); |
502 | end; |
503 | |
504 | function Attachable:getIsInputAttacherActive(inputAttacherJoint) |
505 | return true; |
506 | end; |
507 | |
508 | function Attachable:getIsPowerTakeoffActive() |
509 | if self.isTurnedOn then |
510 | return true; |
511 | end |
512 | |
513 | return false; |
514 | end; |
515 | |
516 | function Attachable:attachableAddToolCameras() |
517 | for _,implement in pairs(self.attachedImplements) do |
518 | if implement.object ~= nil then |
519 | implement.object:attachableAddToolCameras(); |
520 | end |
521 | end |
522 | local rootAttacherVehicle = self:getRootAttacherVehicle(); |
523 | if self.numToolCameras > 0 and rootAttacherVehicle.addToolCameras ~= nil then |
524 | rootAttacherVehicle:addToolCameras(self.toolCameras); |
525 | end; |
526 | end; |
527 | |
528 | function Attachable:attachableRemoveToolCameras() |
529 | for _,implement in pairs(self.attachedImplements) do |
530 | if implement.object ~= nil then |
531 | implement.object:attachableRemoveToolCameras(); |
532 | end |
533 | end |
534 | local rootAttacherVehicle = self:getRootAttacherVehicle(); |
535 | if self.numToolCameras > 0 and rootAttacherVehicle.removeToolCameras ~= nil then |
536 | rootAttacherVehicle:removeToolCameras(self.toolCameras); |
537 | end; |
538 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de