283 | function Mountable:getRootVehicle(superFunc) |
284 | local spec = self.spec_mountable |
285 | |
286 | local rootAttacherVehicle = superFunc(self) |
287 | if rootAttacherVehicle == nil or rootAttacherVehicle == self then |
288 | if spec.dynamicMountObject ~= nil and spec.dynamicMountObject.getRootVehicle ~= nil then |
289 | rootAttacherVehicle = spec.dynamicMountObject:getRootVehicle() |
290 | end |
291 | end |
292 | if rootAttacherVehicle == nil then |
293 | rootAttacherVehicle = self |
294 | end |
295 | return rootAttacherVehicle |
296 | end |
154 | function Mountable:mount(object, node, x,y,z, rx,ry,rz) |
155 | local spec = self.spec_mountable |
156 | |
157 | -- set isDelete = true to remove Mountable from pendingDynamicMountObjects (no delete leave callback) |
158 | self:unmountDynamic(true) |
159 | |
160 | if spec.mountObject == nil then |
161 | removeFromPhysics(self.rootNode) |
162 | end |
163 | link(node, self.rootNode) |
164 | |
165 | local wx,wy,wz = localToWorld(node, x,y,z) |
166 | local wqx,wqy,wqz,wqw = mathEulerToQuaternion( localRotationToWorld(node, rx,ry,rz) ) |
167 | self:setWorldPositionQuaternion(wx,wy,wz, wqx,wqy,wqz,wqw, 1, true) |
168 | |
169 | spec.mountObject = object |
170 | end |
112 | function Mountable:mountableTriggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId) |
113 | local spec = self.spec_mountable |
114 | |
115 | if onEnter then |
116 | if spec.mountObject == nil then |
117 | local vehicle = g_currentMission.nodeToObject[otherActorId] |
118 | |
119 | if vehicle ~= nil and vehicle.spec_dynamicMountAttacher ~= nil then |
120 | local dynamicMountAttacher = vehicle.spec_dynamicMountAttacher |
121 | |
122 | if dynamicMountAttacher ~= nil and dynamicMountAttacher.dynamicMountAttacherNode ~= nil then |
123 | if spec.dynamicMountObjectActorId == nil then |
124 | self:mountDynamic(vehicle, otherActorId, dynamicMountAttacher.dynamicMountAttacherNode, DynamicMountUtil.TYPE_FORK, spec.dynamicMountTriggerForceAcceleration*dynamicMountAttacher.dynamicMountAttacherForceLimitScale) |
125 | spec.dynamicMountObjectTriggerCount = 1 |
126 | elseif otherActorId ~= spec.dynamicMountObjectActorId and spec.dynamicMountObjectTriggerCount == nil then |
127 | -- we are already attached to another actor, but not from our mount trigger (e.g. a bale trailer) |
128 | self:unmountDynamic() |
129 | self:mountDynamic(vehicle, otherActorId, dynamicMountAttacher.dynamicMountAttacherNode, DynamicMountUtil.TYPE_FORK, spec.dynamicMountTriggerForceAcceleration*dynamicMountAttacher.dynamicMountAttacherForceLimitScale) |
130 | spec.dynamicMountObjectTriggerCount = 1 |
131 | elseif otherActorId == spec.dynamicMountObjectActorId then |
132 | if spec.dynamicMountObjectTriggerCount ~= nil then |
133 | spec.dynamicMountObjectTriggerCount = spec.dynamicMountObjectTriggerCount + 1 |
134 | end |
135 | end |
136 | end |
137 | |
138 | end |
139 | |
140 | end |
141 | elseif onLeave then |
142 | if otherActorId == spec.dynamicMountObjectActorId and spec.dynamicMountObjectTriggerCount ~= nil then |
143 | spec.dynamicMountObjectTriggerCount = spec.dynamicMountObjectTriggerCount-1 |
144 | if spec.dynamicMountObjectTriggerCount == 0 then |
145 | self:unmountDynamic() |
146 | spec.dynamicMountObjectTriggerCount = nil |
147 | end |
148 | end |
149 | end |
150 | end |
193 | function Mountable:mountDynamic(object, objectActorId, jointNode, mountType, forceAcceleration) |
194 | local spec = self.spec_mountable |
195 | |
196 | if not self:getSupportsMountDynamic() or spec.mountObject ~= nil then |
197 | return false |
198 | end |
199 | |
200 | -- do not allow to mount myself to an object that has the same root vehicle as an object that i got already mounted |
201 | local dynamicMountSpec = self.spec_dynamicMountAttacher |
202 | if dynamicMountSpec ~= nil then |
203 | for _, mountedObject in pairs(dynamicMountSpec.dynamicMountedObjects) do |
204 | if mountedObject:getRootVehicle() == object:getRootVehicle() then |
205 | return false |
206 | end |
207 | end |
208 | end |
209 | |
210 | local rootVehicle = self:getRootVehicle() |
211 | local vehicleList = {} |
212 | rootVehicle:addToTotalVehicleList(vehicleList) |
213 | for _, vehicle in pairs(vehicleList) do |
214 | local mountableSpec = vehicle.spec_mountable |
215 | if mountableSpec ~= nil then |
216 | if mountableSpec.mountObject == object or vehicle.dynamicMountObject == object then |
217 | return false |
218 | end |
219 | end |
220 | |
221 | local dynamicMountAttacherSpec = vehicle.spec_dynamicMountAttacher |
222 | if dynamicMountAttacherSpec ~= nil then |
223 | for mountedObject, _ in pairs(dynamicMountAttacherSpec.dynamicMountedObjects) do |
224 | if mountedObject == object then |
225 | return false |
226 | end |
227 | end |
228 | end |
229 | end |
230 | |
231 | return DynamicMountUtil.mountDynamic(self, self.rootNode, object, objectActorId, jointNode, mountType, forceAcceleration*spec.dynamicMountForceLimitScale) |
232 | end |
76 | function Mountable:onDelete() |
77 | local spec = self.spec_mountable |
78 | |
79 | if spec.dynamicMountJointIndex ~= nil then |
80 | removeJointBreakReport(spec.dynamicMountJointIndex) |
81 | removeJoint(spec.dynamicMountJointIndex) |
82 | end |
83 | if spec.dynamicMountObject ~= nil then |
84 | spec.dynamicMountObject:removeDynamicMountedObject(self, true) |
85 | end |
86 | if spec.dynamicMountTriggerId ~= nil then |
87 | removeTrigger(spec.dynamicMountTriggerId) |
88 | end |
89 | end |
52 | function Mountable:onLoad(savegame) |
53 | local spec = self.spec_mountable |
54 | |
55 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.dynamicMount#triggerIndex", "vehicle.dynamicMount#triggerNode") --FS17 to FS19 |
56 | |
57 | spec.dynamicMountJointIndex = nil |
58 | spec.dynamicMountObject = nil |
59 | spec.dynamicMountObjectActorId = nil |
60 | spec.dynamicMountForceLimitScale = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.dynamicMount#forceLimitScale"), 1) |
61 | spec.mountObject = nil |
62 | |
63 | if self.isServer then |
64 | spec.dynamicMountTriggerId = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.dynamicMount#triggerNode"), self.i3dMappings) |
65 | if spec.dynamicMountTriggerId ~= nil then |
66 | addTrigger(spec.dynamicMountTriggerId, "mountableTriggerCallback", self) |
67 | end |
68 | spec.dynamicMountTriggerForceAcceleration = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.dynamicMount#triggerForceAcceleration"), 4) |
69 | spec.dynamicMountSingleAxisFreeY = getXMLBool(self.xmlFile, "vehicle.dynamicMount#singleAxisFreeY") |
70 | spec.dynamicMountSingleAxisFreeX = getXMLBool(self.xmlFile, "vehicle.dynamicMount#singleAxisFreeX") |
71 | end |
72 | end |
21 | function Mountable.registerFunctions(vehicleType) |
22 | SpecializationUtil.registerFunction(vehicleType, "getSupportsMountDynamic", Mountable.getSupportsMountDynamic) |
23 | SpecializationUtil.registerFunction(vehicleType, "onDynamicMountJointBreak", Mountable.onDynamicMountJointBreak) |
24 | SpecializationUtil.registerFunction(vehicleType, "mountableTriggerCallback", Mountable.mountableTriggerCallback) |
25 | SpecializationUtil.registerFunction(vehicleType, "mount", Mountable.mount) |
26 | SpecializationUtil.registerFunction(vehicleType, "unmount", Mountable.unmount) |
27 | SpecializationUtil.registerFunction(vehicleType, "mountDynamic", Mountable.mountDynamic) |
28 | SpecializationUtil.registerFunction(vehicleType, "unmountDynamic", Mountable.unmountDynamic) |
29 | SpecializationUtil.registerFunction(vehicleType, "getMountObject", Mountable.getMountObject) |
30 | SpecializationUtil.registerFunction(vehicleType, "getDynamicMountObject", Mountable.getDynamicMountObject) |
31 | end |
174 | function Mountable:unmount() |
175 | local spec = self.spec_mountable |
176 | |
177 | if spec.mountObject ~= nil then |
178 | spec.mountObject = nil |
179 | local x,y,z = getWorldTranslation(self.rootNode) |
180 | local qx,qy,qz,qw = getWorldQuaternion(self.rootNode) |
181 | |
182 | link(getRootNode(), self.rootNode) |
183 | self:setWorldPositionQuaternion(x,y,z, qx,qy,qz,qw, 1, true) |
184 | |
185 | addToPhysics(self.rootNode) |
186 | return true |
187 | end |
188 | return false |
189 | end |