337 | function DynamicMountAttacher:dynamicMountTriggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId) |
338 | local spec = self.spec_dynamicMountAttacher |
339 | |
340 | if onEnter then |
341 | local object = g_currentMission:getNodeObject(otherActorId) |
342 | if object == nil then |
343 | object = g_currentMission.nodeToObject[otherActorId] |
344 | end |
345 | if object == self:getRootVehicle() or (self.spec_attachable ~= nil and self.spec_attachable.attacherVehicle == object) then |
346 | object = nil |
347 | end |
348 | if object ~= nil and object ~= self then |
349 | -- is a mountable object (e.g. bales) |
350 | local isObject = object.getSupportsMountDynamic ~= nil and object:getSupportsMountDynamic() and object.lastMoveTime ~= nil |
351 | |
352 | -- is a mountable vehicle (e.g. pallets) |
353 | local isVehicle = object.getSupportsTensionBelts ~= nil and object:getSupportsTensionBelts() and object.lastMoveTime ~= nil |
354 | |
355 | if isObject or isVehicle then |
356 | local canBeMounted = true |
357 | -- check if otherActor is a trigger and if trigger mounting is allowed |
358 | if object.spec_dynamicMountAttacher ~= nil then |
359 | local dynMountAttacher = object.spec_dynamicMountAttacher |
360 | if dynMountAttacher.dynamicMountAttacherTrigger ~= nil then |
361 | if dynMountAttacher.dynamicMountAttacherTrigger.triggerNode == otherActorId and not spec.isTriggerMountingAllowed then |
362 | canBeMounted = false |
363 | end |
364 | end |
365 | end |
366 | |
367 | if canBeMounted then |
368 | spec.pendingDynamicMountObjects[object] = Utils.getNoNil(spec.pendingDynamicMountObjects[object], 0) + 1 |
369 | end |
370 | end |
371 | end |
372 | elseif onLeave then |
373 | local object = g_currentMission:getNodeObject(otherActorId) |
374 | if object == nil then |
375 | object = g_currentMission.nodeToObject[otherActorId] |
376 | end |
377 | if object ~= nil then |
378 | if spec.pendingDynamicMountObjects[object] ~= nil then |
379 | local count = spec.pendingDynamicMountObjects[object]-1 |
380 | if count == 0 then |
381 | spec.pendingDynamicMountObjects[object] = nil |
382 | |
383 | if spec.dynamicMountedObjects[object] ~= nil then |
384 | self:removeDynamicMountedObject(object, false) |
385 | object:unmountDynamic() |
386 | end |
387 | else |
388 | spec.pendingDynamicMountObjects[object] = count |
389 | end |
390 | end |
391 | end |
392 | end |
393 | end |
423 | function DynamicMountAttacher:getFillLevelInformation(superFunc, fillLevelInformations) |
424 | superFunc(self, fillLevelInformations) |
425 | |
426 | if self:getAllowDynamicMountFillLevelInfo() then |
427 | local spec = self.spec_dynamicMountAttacher |
428 | for object,_ in pairs(spec.dynamicMountedObjects) do |
429 | if object.getFillLevelInformation ~= nil then |
430 | object:getFillLevelInformation(fillLevelInformations) |
431 | else |
432 | if object.getFillLevel ~= nil and object.getFillType ~= nil then |
433 | local added = false |
434 | for _,fillLevelInformation in pairs(fillLevelInformations) do |
435 | if fillLevelInformation.fillType == object:getFillType() then |
436 | fillLevelInformation.fillLevel = fillLevelInformation.fillLevel + object:getFillLevel() |
437 | if object.getCapacity ~= nil then |
438 | fillLevelInformation.capacity = fillLevelInformation.capacity + object:getCapacity() |
439 | else |
440 | fillLevelInformation.capacity = fillLevelInformation.capacity + object:getFillLevel() -- bale |
441 | end |
442 | added = true |
443 | break |
444 | end |
445 | end |
446 | if not added then |
447 | if object.getCapacity ~= nil then |
448 | table.insert(fillLevelInformations, {fillType=object:getFillType(), fillLevel=object:getFillLevel(), capacity=object:getCapacity()}) |
449 | else |
450 | table.insert(fillLevelInformations, {fillType=object:getFillType(), fillLevel=object:getFillLevel(), capacity=object:getFillLevel()}) |
451 | end |
452 | end |
453 | end |
454 | end |
455 | end |
456 | end |
457 | end |
55 | function DynamicMountAttacher:onLoad(savegame) |
56 | local spec = self.spec_dynamicMountAttacher |
57 | |
58 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.dynamicMountAttacher#index", "vehicle.dynamicMountAttacher#node") --FS17 to FS19 |
59 | |
60 | -- Allow mountable object to attach them selfs to us |
61 | spec.dynamicMountAttacherNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.dynamicMountAttacher#node"), self.i3dMappings) |
62 | spec.dynamicMountAttacherForceLimitScale = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.dynamicMountAttacher#forceLimitScale"), 1) |
63 | spec.dynamicMountAttacherTimeToMount = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.dynamicMountAttacher#timeToMount"), 1000) |
64 | spec.numObjectBits = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.dynamicMountAttacher#numObjectBits"), 5) |
65 | |
66 | local grabKey = "vehicle.dynamicMountAttacher.grab" |
67 | if hasXMLProperty(self.xmlFile, grabKey) then |
68 | spec.dynamicMountAttacherGrab = {} |
69 | self:loadDynamicMountGrabFromXML(self.xmlFile, grabKey, spec.dynamicMountAttacherGrab) |
70 | end |
71 | |
72 | if self.isServer then |
73 | spec.dynamicMountCollisionMasks = {} |
74 | local i=0 |
75 | while true do |
76 | local key = string.format("vehicle.dynamicMountAttacher.mountCollisionMask(%d)", i) |
77 | if not hasXMLProperty(self.xmlFile, key) then |
78 | break |
79 | end |
80 | |
81 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#index", key.."#node") --FS17 to FS19 |
82 | |
83 | local node = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node"), self.i3dMappings) |
84 | local mask = getXMLInt(self.xmlFile, key.."#collisionMask") |
85 | if node ~= nil and mask ~= nil then |
86 | table.insert(spec.dynamicMountCollisionMasks, {node=node, mountedCollisionMask=mask, unmountedCollisionMask=getCollisionMask(node)}) |
87 | end |
88 | i=i+1 |
89 | end |
90 | |
91 | local attacherTriggerTriggerNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.dynamicMountAttacher#triggerNode"), self.i3dMappings) |
92 | local attacherTriggerRootNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.dynamicMountAttacher#rootNode"), self.i3dMappings) |
93 | local attacherTriggerJointNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.dynamicMountAttacher#jointNode"), self.i3dMappings) |
94 | if attacherTriggerTriggerNode ~= nil and attacherTriggerRootNode ~= nil and attacherTriggerJointNode ~= nil then |
95 | local forceAcceleration = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.dynamicMountAttacher#forceAcceleration"), 30) |
96 | addTrigger(attacherTriggerTriggerNode, "dynamicMountTriggerCallback", self) |
97 | local mountTypeString = Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.dynamicMountAttacher#mountType"), "TYPE_AUTO_ATTACH_XZ") |
98 | local mountType = Utils.getNoNil(DynamicMountUtil[mountTypeString], DynamicMountUtil.TYPE_AUTO_ATTACH_XZ) |
99 | spec.dynamicMountAttacherTrigger = {triggerNode=attacherTriggerTriggerNode, rootNode=attacherTriggerRootNode, jointNode=attacherTriggerJointNode, forceAcceleration=forceAcceleration, mountType = mountType, mountTypeClosed=mountTypeClosed, currentMountType=mountType} |
100 | end |
101 | spec.pendingDynamicMountObjects = {} |
102 | end |
103 | |
104 | spec.isTriggerMountingAllowed = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.dynamicMountAttacher#isTriggerMountingAllowed"), true) |
105 | spec.animationName = getXMLString(self.xmlFile, "vehicle.dynamicMountAttacher.animation#name") |
106 | spec.animationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.dynamicMountAttacher.animation#speed"), 1) |
107 | if spec.animationName ~= nil then |
108 | self:playAnimation(spec.animationName, spec.animationSpeed, self:getAnimationTime(spec.animationName), true) |
109 | end |
110 | |
111 | spec.dynamicMountedObjects = {} |
112 | spec.dynamicMountedObjectsDirtyFlag = self:getNextDirtyFlag() |
113 | end |
180 | function DynamicMountAttacher:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
181 | if self.isServer then |
182 | local spec = self.spec_dynamicMountAttacher |
183 | |
184 | if self:getAllowDynamicMountObjects() then |
185 | if self.lastMoveTime + spec.dynamicMountAttacherTimeToMount < g_currentMission.time then |
186 | for object,_ in pairs(spec.pendingDynamicMountObjects) do |
187 | if spec.dynamicMountedObjects[object] == nil then |
188 | if object.lastMoveTime + spec.dynamicMountAttacherTimeToMount < g_currentMission.time then |
189 | local doAttach = false |
190 | if object.components ~= nil then |
191 | if object.getCanByMounted ~= nil then |
192 | doAttach = object:getCanByMounted() |
193 | elseif entityExists(object.components[1].node) then |
194 | doAttach = true |
195 | end |
196 | end |
197 | if object.nodeId ~= nil then |
198 | if object.getCanByMounted ~= nil then |
199 | doAttach = object:getCanByMounted() |
200 | elseif entityExists(object.nodeId) then |
201 | doAttach = true |
202 | end |
203 | end |
204 | if doAttach then |
205 | local trigger = spec.dynamicMountAttacherTrigger |
206 | local couldMount = object:mountDynamic(self, trigger.rootNode, trigger.jointNode, trigger.mountType, trigger.forceAcceleration) |
207 | |
208 | if couldMount then |
209 | self:addDynamicMountedObject(object) |
210 | end |
211 | else |
212 | spec.pendingDynamicMountObjects[object] = nil |
213 | end |
214 | end |
215 | end |
216 | end |
217 | end |
218 | else |
219 | for object,_ in pairs(spec.dynamicMountedObjects) do |
220 | self:removeDynamicMountedObject(object, false) |
221 | object:unmountDynamic() |
222 | end |
223 | end |
224 | |
225 | if spec.dynamicMountAttacherGrab ~= nil then |
226 | for object,_ in pairs(spec.dynamicMountedObjects) do |
227 | local usedMountType = spec.dynamicMountAttacherGrab.closedMountType |
228 | |
229 | if self:getIsDynamicMountGrabOpened(spec.dynamicMountAttacherGrab) then |
230 | usedMountType = spec.dynamicMountAttacherGrab.openMountType |
231 | end |
232 | |
233 | if spec.dynamicMountAttacherGrab.currentMountType ~= usedMountType then |
234 | spec.dynamicMountAttacherGrab.currentMountType = usedMountType |
235 | |
236 | local x, y, z = getWorldTranslation(spec.dynamicMountAttacherNode) |
237 | setJointPosition(object.dynamicMountJointIndex, 1, x,y,z) |
238 | if usedMountType == DynamicMountUtil.TYPE_FORK then |
239 | |
240 | setJointRotationLimit(object.dynamicMountJointIndex, 0, true, 0, 0) |
241 | setJointRotationLimit(object.dynamicMountJointIndex, 1, true, 0, 0) |
242 | setJointRotationLimit(object.dynamicMountJointIndex, 2, true, 0, 0) |
243 | |
244 | if object.dynamicMountSingleAxisFreeX then |
245 | setJointTranslationLimit(object.dynamicMountJointIndex, 0, false, 0, 0) |
246 | else |
247 | setJointTranslationLimit(object.dynamicMountJointIndex, 0, true, -0.01, 0.01) |
248 | end |
249 | if object.dynamicMountSingleAxisFreeY then |
250 | setJointTranslationLimit(object.dynamicMountJointIndex, 1, false, 0, 0) |
251 | else |
252 | setJointTranslationLimit(object.dynamicMountJointIndex, 1, true, -0.01, 0.01) |
253 | end |
254 | setJointTranslationLimit(object.dynamicMountJointIndex, 2, false, 0, 0) |
255 | else |
256 | setJointRotationLimit(object.dynamicMountJointIndex, 0, true, 0, 0) |
257 | setJointRotationLimit(object.dynamicMountJointIndex, 1, true, 0, 0) |
258 | setJointRotationLimit(object.dynamicMountJointIndex, 2, true, 0, 0) |
259 | |
260 | if usedMountType == DynamicMountUtil.TYPE_AUTO_ATTACH_XYZ or usedMountType == DynamicMountUtil.TYPE_FIX_ATTACH then |
261 | setJointTranslationLimit(object.dynamicMountJointIndex, 0, true, -0.01, 0.01) |
262 | setJointTranslationLimit(object.dynamicMountJointIndex, 1, true, -0.01, 0.01) |
263 | setJointTranslationLimit(object.dynamicMountJointIndex, 2, true, -0.01, 0.01) |
264 | elseif usedMountType == DynamicMountUtil.TYPE_AUTO_ATTACH_XZ then |
265 | setJointTranslationLimit(object.dynamicMountJointIndex, 0, true, -0.01, 0.01) |
266 | setJointTranslationLimit(object.dynamicMountJointIndex, 1, false, 0, 0) |
267 | setJointTranslationLimit(object.dynamicMountJointIndex, 2, true, -0.01, 0.01) |
268 | elseif usedMountType == DynamicMountUtil.TYPE_AUTO_ATTACH_Y then |
269 | setJointTranslationLimit(object.dynamicMountJointIndex, 0, false, 0, 0) |
270 | setJointTranslationLimit(object.dynamicMountJointIndex, 1, true, -0.01, 0.01) |
271 | setJointTranslationLimit(object.dynamicMountJointIndex, 2, false, 0, 0) |
272 | end |
273 | end |
274 | end |
275 | end |
276 | end |
277 | end |
278 | end |
521 | function DynamicMountAttacher:updateDebugValues(values) |
522 | local spec = self.spec_dynamicMountAttacher |
523 | |
524 | local timeToMount = self.lastMoveTime + spec.dynamicMountAttacherTimeToMount - g_currentMission.time |
525 | table.insert(values, {name="timeToMount:", value=string.format("%d", timeToMount)}) |
526 | |
527 | for object, _ in pairs(spec.pendingDynamicMountObjects) do |
528 | table.insert(values, {name="pendingDynamicMountObject:", value=string.format("%s timeToMount: %d", object.configFileName or object, math.max(object.lastMoveTime + spec.dynamicMountAttacherTimeToMount - g_currentMission.time, 0))}) |
529 | end |
530 | |
531 | for object, _ in pairs(spec.dynamicMountedObjects) do |
532 | table.insert(values, {name="dynamicMountedObjects:", value=string.format("%s", object.configFileName or object)}) |
533 | end |
534 | |
535 | table.insert(values, {name="allowMountObjects:", value=string.format("%s", self:getAllowDynamicMountObjects())}) |
536 | |
537 | if spec.dynamicMountAttacherGrab ~= nil then |
538 | table.insert(values, {name="grabOpened:", value=string.format("%s", self:getIsDynamicMountGrabOpened(spec.dynamicMountAttacherGrab))}) |
539 | end |
540 | end |