Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Foldable |
3 | -- Class for vehicles which have folding parts |
4 | -- |
5 | -- @author Stefan Geiger |
6 | -- @date 12/01/09 |
7 | -- |
8 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
9 | |
10 | source("dataS/scripts/vehicles/specializations/FoldableSetFoldDirectionEvent.lua"); |
11 | Foldable = {}; |
12 | |
13 | function Foldable.prerequisitesPresent(specializations) |
14 | return true; |
15 | end |
16 | |
17 | function Foldable:preLoad(xmlFile) |
18 | self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, Foldable.loadSpeedRotatingPartFromXML); |
19 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Foldable.loadWorkAreaFromXML); |
20 | end |
21 | |
22 | function Foldable:load(xmlFile) |
23 | |
24 | self.setFoldDirection = SpecializationUtil.callSpecializationsFunction("setFoldDirection"); |
25 | self.setFoldState = SpecializationUtil.callSpecializationsFunction("setFoldState"); |
26 | self.getToggledFoldDirection = Foldable.getToggledFoldDirection; |
27 | self.getToggledFoldMiddleDirection = Foldable.getToggledFoldMiddleDirection; |
28 | |
29 | self.getIsFoldAllowed = Utils.overwrittenFunction(self.getIsFoldAllowed, Foldable.getIsFoldAllowed); |
30 | self.getIsFoldMiddleAllowed = Utils.overwrittenFunction(self.getIsFoldMiddleAllowed, Foldable.getIsFoldMiddleAllowed); |
31 | self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, Foldable.getIsSpeedRotatingPartActive); |
32 | self.getIsWorkAreaActive = Utils.overwrittenFunction(self.getIsWorkAreaActive, Foldable.getIsWorkAreaActive); |
33 | self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, Foldable.getIsTurnedOnAllowed); |
34 | self.getIsInWorkPosition = Utils.overwrittenFunction(self.getIsInWorkPosition, Foldable.getIsInWorkPosition); |
35 | self.isLowered = Utils.overwrittenFunction(self.isLowered, Foldable.isLowered); |
36 | self.getTurnedOnNotAllowedWarning = Utils.overwrittenFunction(self.getTurnedOnNotAllowedWarning, Foldable.getTurnedOnNotAllowedWarning); |
37 | self.isDetachAllowed = Utils.overwrittenFunction(self.isDetachAllowed, Foldable.isDetachAllowed); |
38 | |
39 | self.applyInitialAnimation = Utils.overwrittenFunction(self.applyInitialAnimation, Foldable.applyInitialAnimation); |
40 | |
41 | self.posDirectionText = Utils.getNoNil(getXMLString(xmlFile, "vehicle.foldingParts#posDirectionText"), "fold_OBJECT"); |
42 | self.negDirectionText = Utils.getNoNil(getXMLString(xmlFile, "vehicle.foldingParts#negDirectionText"), "unfold_OBJECT"); |
43 | self.middlePosDirectionText = Utils.getNoNil(getXMLString(xmlFile, "vehicle.foldingParts#middlePosDirectionText"), "lift_OBJECT"); |
44 | self.middleNegDirectionText = Utils.getNoNil(getXMLString(xmlFile, "vehicle.foldingParts#middleNegDirectionText"), "lower_OBJECT"); |
45 | self.startAnimTime = getXMLFloat(xmlFile, "vehicle.foldingParts#startAnimTime"); |
46 | self.foldMoveDirection = 0; |
47 | self.moveToMiddle = false; |
48 | if self.startAnimTime == nil then |
49 | self.startAnimTime = 0; |
50 | local startMoveDirection = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.foldingParts#startMoveDirection"), 0); |
51 | if startMoveDirection > 0.1 then |
52 | self.startAnimTime = 1; |
53 | end |
54 | end |
55 | self.turnOnFoldDirection = 1; |
56 | if self.startAnimTime > 0.5 then |
57 | self.turnOnFoldDirection = -1; |
58 | end |
59 | |
60 | self.turnOnFoldDirection = Utils.sign(Utils.getNoNil(getXMLInt(xmlFile, "vehicle.foldingParts#turnOnFoldDirection"), self.turnOnFoldDirection)); |
61 | |
62 | local foldInputButtonStr = getXMLString(xmlFile, "vehicle.foldingParts#foldInputButton"); |
63 | if foldInputButtonStr ~= nil then |
64 | self.foldInputButton = InputBinding[foldInputButtonStr]; |
65 | end |
66 | self.foldInputButton = Utils.getNoNil(self.foldInputButton, InputBinding.IMPLEMENT_EXTRA2); |
67 | |
68 | local foldMiddleInputButtonStr = getXMLString(xmlFile, "vehicle.foldingParts#foldMiddleInputButton"); |
69 | if foldMiddleInputButtonStr ~= nil then |
70 | self.foldMiddleInputButton = InputBinding[foldMiddleInputButtonStr]; |
71 | end |
72 | self.foldMiddleInputButton = Utils.getNoNil(self.foldMiddleInputButton, InputBinding.LOWER_IMPLEMENT); |
73 | |
74 | self.foldMiddleAnimTime = getXMLFloat(xmlFile, "vehicle.foldingParts#foldMiddleAnimTime"); |
75 | self.foldMiddleDirection = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.foldingParts#foldMiddleDirection"), 1); |
76 | self.foldMiddleAIRaiseDirection = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.foldingParts#foldMiddleAIRaiseDirection"), self.foldMiddleDirection); |
77 | |
78 | self.turnOnFoldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.foldingParts#turnOnFoldMaxLimit"), 1); |
79 | self.turnOnFoldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.foldingParts#turnOnFoldMinLimit"), 0); |
80 | self.detachingMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.foldingParts#detachingMaxLimit"), 1); |
81 | self.detachingMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.foldingParts#detachingMinLimit"), 0); |
82 | self.turnOffOnFold = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.foldingParts#turnOffOnFold"), false); |
83 | self.unfoldWarning = string.format(g_i18n:getText(Utils.getNoNil(getXMLString(xmlFile, "vehicle.foldingParts#unfoldWarning"), "FirstUnfoldTheTool")), self.typeDesc); |
84 | |
85 | self.foldAnimTime = 0; |
86 | self.maxFoldAnimDuration = 0.0001; |
87 | |
88 | self.foldingParts = {}; |
89 | local i=0; |
90 | while true do |
91 | local baseName = string.format("vehicle.foldingParts.foldingPart(%d)", i); |
92 | if not hasXMLProperty(xmlFile, baseName) then |
93 | break; |
94 | end |
95 | |
96 | local isValid = false; |
97 | local entry = {}; |
98 | entry.speedScale = Utils.getNoNil(getXMLFloat(xmlFile, baseName.."#speedScale"), 1); |
99 | local componentJointIndex = getXMLInt(xmlFile, baseName.. "#componentJointIndex"); |
100 | local componentJoint = nil; |
101 | if componentJointIndex ~= nil then |
102 | componentJoint = self.componentJoints[componentJointIndex+1]; |
103 | entry.componentJoint = componentJoint; |
104 | end |
105 | entry.anchorActor = Utils.getNoNil(getXMLInt(xmlFile, baseName.."#anchorActor"), 0); |
106 | |
107 | entry.animCharSet = 0; |
108 | |
109 | local rootNode = Utils.indexToObject(self.components, getXMLString(xmlFile, baseName.."#rootNode")); |
110 | if rootNode ~= nil then |
111 | local animCharSet = getAnimCharacterSet(rootNode); |
112 | if animCharSet ~= 0 then |
113 | local clip = getAnimClipIndex(animCharSet, getXMLString(xmlFile, baseName.."#animationClip")); |
114 | if clip >= 0 then |
115 | isValid = true; |
116 | |
117 | entry.animCharSet = animCharSet; |
118 | assignAnimTrackClip(entry.animCharSet, 0, clip); |
119 | setAnimTrackLoopState(entry.animCharSet, 0, false); |
120 | entry.animDuration = getAnimClipDuration(entry.animCharSet, clip); |
121 | |
122 | end |
123 | end |
124 | end |
125 | -- try AnimatedVehicle specialization support |
126 | if not isValid and self.playAnimation ~= nil and self.animations ~= nil then |
127 | local animationName = getXMLString(xmlFile, baseName.."#animationName"); |
128 | if animationName ~= nil then |
129 | if self.animations[animationName] ~= nil then |
130 | isValid = true; |
131 | entry.animDuration = self:getAnimationDuration(animationName); |
132 | entry.animationName = animationName; |
133 | end |
134 | end |
135 | end |
136 | |
137 | if isValid then |
138 | self.maxFoldAnimDuration = math.max(self.maxFoldAnimDuration, entry.animDuration); |
139 | if componentJoint ~= nil then |
140 | local node = self.components[componentJoint.componentIndices[((entry.anchorActor+1)%2)+1] ].node; |
141 | entry.x,entry.y,entry.z = worldToLocal(componentJoint.jointNode, getWorldTranslation(node)); |
142 | entry.upX,entry.upY,entry.upZ = worldDirectionToLocal(componentJoint.jointNode, localDirectionToWorld(node, 0, 1, 0)); |
143 | entry.dirX,entry.dirY,entry.dirZ = worldDirectionToLocal(componentJoint.jointNode, localDirectionToWorld(node, 0, 0, 1)); |
144 | end |
145 | |
146 | table.insert(self.foldingParts, entry); |
147 | end |
148 | i = i+1; |
149 | end |
150 | |
151 | if table.getn(self.foldingParts) > 0 then |
152 | self.isSelectable = true; |
153 | end |
154 | end |
155 | |
156 | function Foldable:applyInitialAnimation(superFunc) |
157 | self.foldAnimTime = 1-self.startAnimTime; -- make sure that foldAnimTime ~= startAnimTime |
158 | Foldable.setAnimTime(self, self.startAnimTime) |
159 | if superFunc ~= nil then |
160 | superFunc(self); |
161 | end |
162 | end |
163 | |
164 | function Foldable:delete() |
165 | end |
166 | |
167 | function Foldable:readStream(streamId, connection) |
168 | local direction = streamReadUIntN(streamId, 2)-1; |
169 | local moveToMiddle = streamReadBool(streamId); |
170 | local animTime = streamReadFloat32(streamId); |
171 | Foldable.setAnimTime(self, animTime, false); |
172 | self:setFoldState(direction, moveToMiddle, true); |
173 | end |
174 | |
175 | function Foldable:writeStream(streamId, connection) |
176 | local direction = Utils.sign(self.foldMoveDirection)+1; |
177 | streamWriteUIntN(streamId, direction, 2); |
178 | streamWriteBool(streamId, self.moveToMiddle); |
179 | streamWriteFloat32(streamId, self.foldAnimTime); |
180 | end |
181 | |
182 | function Foldable:readUpdateStream(streamId, timestamp, connection) |
183 | end |
184 | |
185 | function Foldable:writeUpdateStream(streamId, connection, dirtyMask) |
186 | end |
187 | |
188 | function Foldable:loadFromAttributesAndNodes(xmlFile, key, resetVehicles) |
189 | if not resetVehicles then |
190 | local animTime = getXMLFloat(xmlFile, key.."#foldAnimTime"); |
191 | if animTime == nil then |
192 | animTime = self.startAnimTime; |
193 | end |
194 | |
195 | Foldable.setAnimTime(self, animTime, false) |
196 | end |
197 | return BaseMission.VEHICLE_LOAD_OK; |
198 | end |
199 | |
200 | function Foldable:getSaveAttributesAndNodes(nodeIdent) |
201 | local attributes = 'foldAnimTime="'..self.foldAnimTime..'"'; |
202 | return attributes, nil; |
203 | end |
204 | |
205 | function Foldable:setRelativePosition(positionX, offsetY, positionZ, yRot) |
206 | self.foldAnimTime = 1-self.startAnimTime; -- make sure that foldAnimTime ~= startAnimTime |
207 | Foldable.setAnimTime(self, self.startAnimTime); |
208 | end |
209 | |
210 | function Foldable:mouseEvent(posX, posY, isDown, isUp, button) |
211 | end |
212 | |
213 | function Foldable:keyEvent(unicode, sym, modifier, isDown) |
214 | end |
215 | |
216 | function Foldable:update(dt) |
217 | |
218 | if self:getIsActive() then |
219 | |
220 | if math.abs(self.foldMoveDirection) > 0.1 then |
221 | local isInvalid = false; |
222 | local foldAnimTime = 0; |
223 | if self.foldMoveDirection < -0.1 then |
224 | foldAnimTime = 1; |
225 | end |
226 | for _,foldingPart in pairs(self.foldingParts) do |
227 | local charSet = foldingPart.animCharSet; |
228 | if self.foldMoveDirection > 0 then |
229 | local animTime = 0; |
230 | if charSet ~= 0 then |
231 | animTime = getAnimTrackTime(charSet, 0); |
232 | else |
233 | animTime = self:getRealAnimationTime(foldingPart.animationName); |
234 | end |
235 | if animTime < foldingPart.animDuration then |
236 | isInvalid = true; |
237 | end |
238 | foldAnimTime = math.max(foldAnimTime, animTime / self.maxFoldAnimDuration); |
239 | elseif self.foldMoveDirection < 0 then |
240 | local animTime = 0; |
241 | if charSet ~= 0 then |
242 | animTime = getAnimTrackTime(charSet, 0); |
243 | else |
244 | animTime = self:getRealAnimationTime(foldingPart.animationName); |
245 | end |
246 | if animTime > 0 then |
247 | isInvalid = true; |
248 | end |
249 | foldAnimTime = math.min(foldAnimTime, animTime / self.maxFoldAnimDuration); |
250 | end |
251 | end |
252 | self.foldAnimTime = Utils.clamp(foldAnimTime, 0, 1); |
253 | |
254 | if isInvalid and self.isServer then |
255 | for _,foldingPart in pairs(self.foldingParts) do |
256 | if foldingPart.componentJoint ~= nil then |
257 | setJointFrame(foldingPart.componentJoint.jointIndex, foldingPart.anchorActor, foldingPart.componentJoint.jointNode); |
258 | end |
259 | end |
260 | end |
261 | end |
262 | end |
263 | |
264 | if self.isClient and table.getn(self.foldingParts) > 0 and self:getIsActiveForInput(true) then |
265 | if InputBinding.hasEvent(self.foldInputButton) then |
266 | if self:getIsFoldAllowed() then |
267 | if self:getToggledFoldDirection() == self.turnOnFoldDirection then |
268 | self:setFoldState(self:getToggledFoldDirection(), true); |
269 | else |
270 | self:setFoldState(self:getToggledFoldDirection(), false); |
271 | end; |
272 | end |
273 | end |
274 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleInputButton ~= nil then |
275 | if InputBinding.hasEvent(self.foldMiddleInputButton) then |
276 | if self:getIsFoldMiddleAllowed() then |
277 | local direction = self:getToggledFoldMiddleDirection(); |
278 | if direction ~= 0 then |
279 | if direction == self.turnOnFoldDirection then |
280 | self:setFoldState(direction, false) |
281 | else |
282 | self:setFoldState(direction, true) |
283 | end; |
284 | end |
285 | end |
286 | end |
287 | end |
288 | end |
289 | end |
290 | |
291 | function Foldable:updateTick(dt) |
292 | if self:getIsActive() then |
293 | if self.turnOffOnFold then |
294 | if not self:getIsTurnedOnAllowed(true) then |
295 | if self.setIsTurnedOn ~= nil and self:getIsTurnedOn() then |
296 | self:setIsTurnedOn(false, true); |
297 | elseif self.attacherVehicle ~= nil and self.attacherVehicle.setIsTurnedOn ~= nil and self.attacherVehicle:getIsTurnedOn() then |
298 | self.attacherVehicle:setIsTurnedOn(false, true); |
299 | end; |
300 | end; |
301 | end; |
302 | end; |
303 | end |
304 | |
305 | function Foldable:draw() |
306 | if self.isClient then |
307 | if table.getn(self.foldingParts) > 0 and self:getIsActiveForInput(true) then |
308 | local i18n = g_i18n; |
309 | if self.customEnvironment ~= nil then |
310 | i18n = _G[self.customEnvironment].g_i18n; |
311 | end |
312 | if self:getIsFoldAllowed() then |
313 | if self.foldMiddleAnimTime == nil or self.foldMiddleAnimTime ~= 1 then |
314 | if self:getToggledFoldDirection() > 0 then |
315 | g_currentMission:addHelpButtonText(string.format(i18n:getText(self.posDirectionText), self.typeDesc), self.foldInputButton); |
316 | else |
317 | g_currentMission:addHelpButtonText(string.format(i18n:getText(self.negDirectionText), self.typeDesc), self.foldInputButton); |
318 | end |
319 | end; |
320 | end |
321 | if self:getIsFoldMiddleAllowed() then |
322 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleInputButton ~= nil then |
323 | local direction = self:getToggledFoldMiddleDirection(); |
324 | if direction > 0 then |
325 | g_currentMission:addHelpButtonText(string.format(i18n:getText(self.middlePosDirectionText), self.typeDesc), self.foldMiddleInputButton); |
326 | elseif direction < 0 then |
327 | g_currentMission:addHelpButtonText(string.format(i18n:getText(self.middleNegDirectionText), self.typeDesc), self.foldMiddleInputButton); |
328 | end |
329 | end |
330 | end |
331 | end |
332 | end; |
333 | end |
334 | |
335 | function Foldable:onDeactivate() |
336 | self:setFoldDirection(0, true); |
337 | end |
338 | |
339 | function Foldable:aiTurnOn() |
340 | if self:getIsFoldAllowed() then |
341 | if self.turnOnFoldDirection ~= 0 then |
342 | self:setFoldDirection(self.turnOnFoldDirection, true); |
343 | end |
344 | end |
345 | end |
346 | |
347 | function Foldable:aiTurnOff() |
348 | --[[ |
349 | if self:getIsFoldAllowed() then |
350 | if self.turnOnFoldDirection ~= 0 then |
351 | self:setFoldDirection(-self.turnOnFoldDirection, true); |
352 | end |
353 | end |
354 | ]]-- |
355 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleAIRaiseDirection ~= 0 then |
356 | if self.foldMiddleAIRaiseDirection > 0 then |
357 | if self.foldAnimTime > self.foldMiddleAnimTime then |
358 | self:setFoldState(self.foldMiddleAIRaiseDirection, false, true); |
359 | else |
360 | self:setFoldState(self.foldMiddleAIRaiseDirection, true, true); |
361 | end; |
362 | else |
363 | if self.foldAnimTime < self.foldMiddleAnimTime then |
364 | self:setFoldState(self.foldMiddleAIRaiseDirection, false, true); |
365 | else |
366 | self:setFoldState(self.foldMiddleAIRaiseDirection, true, true); |
367 | end; |
368 | end; |
369 | end |
370 | end |
371 | |
372 | function Foldable:aiLower() |
373 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleAIRaiseDirection ~= 0 then |
374 | self:setFoldState(-self.foldMiddleAIRaiseDirection, false, true); |
375 | end |
376 | end; |
377 | |
378 | function Foldable:aiRaise() |
379 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleAIRaiseDirection ~= 0 then |
380 | if self.foldMiddleAIRaiseDirection > 0 then |
381 | if self.foldAnimTime > self.foldMiddleAnimTime then |
382 | self:setFoldState(self.foldMiddleAIRaiseDirection, false, true); |
383 | else |
384 | self:setFoldState(self.foldMiddleAIRaiseDirection, true, true); |
385 | end; |
386 | else |
387 | if self.foldAnimTime < self.foldMiddleAnimTime then |
388 | self:setFoldState(self.foldMiddleAIRaiseDirection, false, true); |
389 | else |
390 | self:setFoldState(self.foldMiddleAIRaiseDirection, true, true); |
391 | end; |
392 | end; |
393 | end |
394 | end; |
395 | |
396 | function Foldable:startThreshing() |
397 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleAIRaiseDirection ~= 0 then |
398 | self:setFoldState(-self.foldMiddleAIRaiseDirection, false, true); |
399 | end; |
400 | end |
401 | |
402 | function Foldable:stopThreshing() |
403 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleAIRaiseDirection ~= 0 then |
404 | self:setFoldState(self.foldMiddleAIRaiseDirection, true, true); |
405 | end; |
406 | end |
407 | |
408 | function Foldable:setFoldDirection(direction, noEventSend) |
409 | self:setFoldState(direction, false, noEventSend); |
410 | end |
411 | |
412 | function Foldable:setFoldState(direction, moveToMiddle, noEventSend) |
413 | if self.foldMiddleAnimTime == nil then |
414 | moveToMiddle = false; |
415 | end |
416 | if self.foldMoveDirection ~= direction or self.moveToMiddle ~= moveToMiddle then |
417 | if noEventSend == nil or noEventSend == false then |
418 | if g_server ~= nil then |
419 | g_server:broadcastEvent(FoldableSetFoldDirectionEvent:new(self, direction, moveToMiddle), nil, nil, self); |
420 | else |
421 | g_client:getServerConnection():sendEvent(FoldableSetFoldDirectionEvent:new(self, direction, moveToMiddle)); |
422 | end |
423 | end |
424 | self.foldMoveDirection = direction; |
425 | self.moveToMiddle = moveToMiddle; |
426 | |
427 | for _,foldingPart in pairs(self.foldingParts) do |
428 | local speedScale = nil; |
429 | if self.foldMoveDirection > 0.1 then |
430 | speedScale = foldingPart.speedScale; |
431 | elseif self.foldMoveDirection < -0.1 then |
432 | speedScale = -foldingPart.speedScale; |
433 | end |
434 | |
435 | local charSet = foldingPart.animCharSet; |
436 | if charSet ~= 0 then |
437 | if speedScale ~= nil then |
438 | if speedScale > 0 then |
439 | if getAnimTrackTime(charSet, 0) < 0.0 then |
440 | setAnimTrackTime(charSet, 0, 0.0); |
441 | end |
442 | else |
443 | if getAnimTrackTime(charSet, 0) > foldingPart.animDuration then |
444 | setAnimTrackTime(charSet, 0, foldingPart.animDuration); |
445 | end |
446 | end |
447 | setAnimTrackSpeedScale(charSet, 0, speedScale); |
448 | enableAnimTrack(charSet, 0); |
449 | else |
450 | disableAnimTrack(charSet, 0); |
451 | end |
452 | else |
453 | -- always stop to make sure the animation state is reset |
454 | self:stopAnimation(foldingPart.animationName, true); |
455 | if speedScale ~= nil then |
456 | local animTime = (self.foldAnimTime*self.maxFoldAnimDuration)/self:getAnimationDuration(foldingPart.animationName); |
457 | self:playAnimation(foldingPart.animationName, speedScale, animTime, true); |
458 | |
459 | if moveToMiddle then |
460 | local stopAnimTime = (self.foldMiddleAnimTime*self.maxFoldAnimDuration)/self:getAnimationDuration(foldingPart.animationName); |
461 | self:setAnimationStopTime(foldingPart.animationName, stopAnimTime); |
462 | end |
463 | end |
464 | end |
465 | end |
466 | -- slightly move fold anim time, so that fold limits can trigger for different actions |
467 | if self.foldMoveDirection > 0.1 then |
468 | self.foldAnimTime = math.min(self.foldAnimTime + 0.0001, math.max(self.foldAnimTime, 1)); |
469 | elseif self.foldMoveDirection < -0.1 then |
470 | self.foldAnimTime = math.max(self.foldAnimTime - 0.0001, math.min(self.foldAnimTime, 0)); |
471 | end |
472 | end |
473 | end |
474 | |
475 | function Foldable:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key) |
476 | if superFunc ~= nil then |
477 | if not superFunc(self, speedRotatingPart, xmlFile, key) then |
478 | return false; |
479 | end |
480 | end |
481 | speedRotatingPart.foldLimitedOuterRange = Utils.getNoNil(getXMLBool(xmlFile, key.."#foldLimitedOuterRange"), false); |
482 | local minFoldLimit = 0; |
483 | local maxFoldLimit = 1; |
484 | if speedRotatingPart.foldLimitedOuterRange then |
485 | minFoldLimit = 0.5; |
486 | maxFoldLimit = 0.5; |
487 | end; |
488 | speedRotatingPart.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#foldMinLimit"), minFoldLimit); |
489 | speedRotatingPart.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#foldMaxLimit"), maxFoldLimit); |
490 | |
491 | return true; |
492 | end |
493 | |
494 | function Foldable:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart) |
495 | if not speedRotatingPart.foldLimitedOuterRange then |
496 | if self.foldAnimTime > speedRotatingPart.foldMaxLimit or self.foldAnimTime < speedRotatingPart.foldMinLimit then |
497 | return false; |
498 | end |
499 | else |
500 | if self.foldAnimTime <= speedRotatingPart.foldMaxLimit and self.foldAnimTime > speedRotatingPart.foldMinLimit then |
501 | return false; |
502 | end |
503 | end; |
504 | |
505 | if superFunc ~= nil then |
506 | return superFunc(self, speedRotatingPart); |
507 | end |
508 | return true; |
509 | end; |
510 | |
511 | function Foldable:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
512 | workArea.foldLimitedOuterRange = Utils.getNoNil(getXMLBool(xmlFile, key.."#foldLimitedOuterRange"), false); |
513 | local minFoldLimit = 0; |
514 | local maxFoldLimit = 1; |
515 | if workArea.foldLimitedOuterRange then |
516 | minFoldLimit = 0.5; |
517 | maxFoldLimit = 0.5; |
518 | end; |
519 | workArea.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#foldMinLimit"), minFoldLimit); |
520 | workArea.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#foldMaxLimit"), maxFoldLimit); |
521 | |
522 | |
523 | if superFunc ~= nil then |
524 | return superFunc(self, workArea, xmlFile, key); |
525 | end; |
526 | return true; |
527 | end; |
528 | |
529 | function Foldable:getIsWorkAreaActive(superFunc, workArea) |
530 | if not workArea.foldLimitedOuterRange then |
531 | if self.foldAnimTime > workArea.foldMaxLimit or self.foldAnimTime < workArea.foldMinLimit then |
532 | return false; |
533 | end |
534 | else |
535 | if self.foldAnimTime <= workArea.foldMaxLimit and self.foldAnimTime > workArea.foldMinLimit then |
536 | return false; |
537 | end |
538 | end; |
539 | if superFunc ~= nil then |
540 | return superFunc(self, workArea); |
541 | end |
542 | return true; |
543 | end; |
544 | |
545 | function Foldable:getIsTurnedOnAllowed(superFunc, isTurnOn) |
546 | if isTurnOn then |
547 | if self.foldAnimTime > self.turnOnFoldMaxLimit or self.foldAnimTime < self.turnOnFoldMinLimit then |
548 | return false; |
549 | end |
550 | end; |
551 | |
552 | if superFunc ~= nil then |
553 | return superFunc(self, isTurnOn); |
554 | end |
555 | return true; |
556 | end; |
557 | |
558 | function Foldable:getIsInWorkPosition(superFunc) |
559 | if self.turnOnFoldDirection ~= 0 and not (table.getn(self.foldingParts) == 0 or (self.turnOnFoldDirection == -1 and self.foldAnimTime == 0) or (self.turnOnFoldDirection == 1 and self.foldAnimTime == 1)) then |
560 | return false; |
561 | end; |
562 | |
563 | if superFunc ~= nil then |
564 | return superFunc(self); |
565 | end |
566 | return true; |
567 | end; |
568 | |
569 | function Foldable:getTurnedOnNotAllowedWarning(superFunc) |
570 | if self.foldAnimTime > self.turnOnFoldMaxLimit or self.foldAnimTime < self.turnOnFoldMinLimit then |
571 | return self.unfoldWarning; |
572 | end; |
573 | |
574 | if superFunc ~= nil then |
575 | return superFunc(self); |
576 | end |
577 | return nil; |
578 | end; |
579 | |
580 | function Foldable:isDetachAllowed(superFunc) |
581 | if self.foldAnimTime > self.detachingMaxLimit or self.foldAnimTime < self.detachingMinLimit then |
582 | return false; |
583 | end; |
584 | |
585 | |
586 | if superFunc ~= nil then |
587 | return superFunc(self); |
588 | end |
589 | return true; |
590 | end; |
591 | |
592 | function Foldable:isLowered(superFunc, default) |
593 | |
594 | if self:getIsFoldMiddleAllowed() then |
595 | if self.foldMiddleAnimTime ~= nil and self.foldMiddleInputButton ~= nil then |
596 | |
597 | if self.foldMoveDirection ~= 0 then |
598 | if self.foldMiddleDirection > 0 then |
599 | if self.foldAnimTime < self.foldMiddleAnimTime + 0.01 then |
600 | return self.foldMoveDirection < 0 and self.moveToMiddle ~= true; |
601 | end; |
602 | else |
603 | if self.foldAnimTime > self.foldMiddleAnimTime - 0.01 then |
604 | return self.foldMoveDirection > 0 and self.moveToMiddle ~= true; |
605 | end; |
606 | end; |
607 | else |
608 | if self.foldMiddleDirection > 0 and self.foldAnimTime < 0.01 then |
609 | return true; |
610 | elseif self.foldMiddleDirection < 0 and math.abs(1.0 - self.foldAnimTime) < 0.01 then |
611 | return true; |
612 | end; |
613 | end; |
614 | |
615 | return false; |
616 | |
617 | end |
618 | end |
619 | |
620 | if superFunc ~= nil then |
621 | return superFunc(self, default); |
622 | end |
623 | return default; |
624 | end; |
625 | |
626 | function Foldable:getIsFoldAllowed(superFunc) |
627 | if superFunc ~= nil then |
628 | return superFunc(self); |
629 | end |
630 | return true; |
631 | end |
632 | |
633 | function Foldable:getIsFoldMiddleAllowed(superFunc) |
634 | if superFunc ~= nil then |
635 | return superFunc(self); |
636 | end |
637 | return true; |
638 | end |
639 | |
640 | function Foldable:getToggledFoldDirection() |
641 | local foldMidTime = 0.5; |
642 | if self.foldMiddleAnimTime ~= nil then |
643 | if self.foldMiddleDirection > 0 then |
644 | foldMidTime = (1+self.foldMiddleAnimTime) * 0.5; |
645 | else |
646 | foldMidTime = self.foldMiddleAnimTime * 0.5; |
647 | end |
648 | end |
649 | if self.moveToMiddle then |
650 | return self.foldMiddleDirection; |
651 | elseif self.foldMoveDirection > 0.1 or (self.foldMoveDirection == 0 and self.foldAnimTime > foldMidTime) then |
652 | return -1; |
653 | else |
654 | return 1; |
655 | end |
656 | end |
657 | |
658 | function Foldable:getToggledFoldMiddleDirection() |
659 | local ret = 0; |
660 | if self.foldMiddleAnimTime ~= nil then |
661 | if self.foldMoveDirection > 0.1 then |
662 | ret = -1; |
663 | else |
664 | ret = 1; |
665 | end |
666 | if self.foldMiddleDirection > 0 then |
667 | if self.foldAnimTime >= self.foldMiddleAnimTime - 0.01 then |
668 | ret = -1; |
669 | end; |
670 | else |
671 | if self.foldAnimTime <= self.foldMiddleAnimTime + 0.01 then |
672 | ret = 1; |
673 | end; |
674 | end; |
675 | end |
676 | return ret; |
677 | end |
678 | |
679 | function Foldable:onLowerAll(doLowering, jointIndex) |
680 | if self.foldMiddleAnimTime ~= nil then |
681 | if self:getIsFoldMiddleAllowed() then |
682 | if doLowering then |
683 | self:setFoldState(-self.foldMiddleAIRaiseDirection, false, true); |
684 | else |
685 | self:setFoldState(self.foldMiddleAIRaiseDirection, true, true); |
686 | end; |
687 | end |
688 | end; |
689 | end; |
690 | |
691 | function Foldable.setAnimTime(self, animTime, placeComponents) |
692 | local currentTime = self.foldAnimTime; |
693 | self.foldAnimTime = animTime; |
694 | for _,foldingPart in pairs(self.foldingParts) do |
695 | if foldingPart.animCharSet ~= 0 then |
696 | enableAnimTrack(foldingPart.animCharSet, 0); |
697 | setAnimTrackTime(foldingPart.animCharSet, 0, self.foldAnimTime*foldingPart.animDuration, true); |
698 | disableAnimTrack(foldingPart.animCharSet, 0); |
699 | else |
700 | local speed = 1; |
701 | if self.foldAnimTime < currentTime then |
702 | speed = -1; |
703 | end |
704 | local stopAnimTime = (self.foldAnimTime*self.maxFoldAnimDuration)/self:getAnimationDuration(foldingPart.animationName); |
705 | self:playAnimation(foldingPart.animationName, speed, nil, true); |
706 | self:setAnimationStopTime(foldingPart.animationName, stopAnimTime); |
707 | AnimatedVehicle.updateAnimationByName(self, foldingPart.animationName, 99999999); |
708 | end |
709 | end |
710 | |
711 | if placeComponents == nil then |
712 | placeComponents = true; |
713 | end |
714 | |
715 | if self.updateCylinderedInitial ~= nil then |
716 | self:updateCylinderedInitial(placeComponents); |
717 | end |
718 | |
719 | if placeComponents then |
720 | if self.isServer then |
721 | for _,foldingPart in pairs(self.foldingParts) do |
722 | if foldingPart.componentJoint ~= nil then |
723 | local componentJoint = foldingPart.componentJoint; |
724 | |
725 | local jointNode = componentJoint.jointNode; |
726 | if foldingPart.anchorActor == 1 then |
727 | jointNode = componentJoint.jointNodeActor1; |
728 | end |
729 | |
730 | local node = self.components[componentJoint.componentIndices[((foldingPart.anchorActor+1)%2)+1] ].node; |
731 | local x,y,z = localToWorld(jointNode, foldingPart.x, foldingPart.y, foldingPart.z); |
732 | local upX,upY,upZ = localDirectionToWorld(jointNode, foldingPart.upX,foldingPart.upY,foldingPart.upZ); |
733 | local dirX,dirY,dirZ = localDirectionToWorld(jointNode, foldingPart.dirX,foldingPart.dirY,foldingPart.dirZ); |
734 | Utils.setWorldTranslation(node, x,y,z); |
735 | Utils.setWorldDirection(node, dirX,dirY,dirZ, upX,upY,upZ); |
736 | |
737 | setJointFrame(componentJoint.jointIndex, foldingPart.anchorActor, jointNode); |
738 | end |
739 | end |
740 | end |
741 | end |
742 | end
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de