Sprache Deutsch Language English

Script Dokumentation LS 2015 - Trailer (Patch 1.3)

Script Dokumentation Übersicht

scripts/vehicles/specializations/Trailer.lua

Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1--
2-- Trailer
3-- This is the specialization for trailers
4-- Note: tipState is not perfectly synced. It is only as accurate as the animation, which is only triggered by start and end events
5-- lastFillDelta is only valid on the server
6--
7-- @author Stefan Geiger
8-- @date 30/11/08
9--
10-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
11
12source("dataS/scripts/vehicles/specializations/TrailerToggleTipEvent.lua");
13source("dataS/scripts/vehicles/specializations/TrailerTipAreaEvent.lua");
14
15Trailer = {};
16
17Trailer.TIPSTATE_CLOSED = 0;
18Trailer.TIPSTATE_OPENING = 1;
19Trailer.TIPSTATE_OPEN = 2;
20Trailer.TIPSTATE_CLOSING = 3;
21
22function Trailer.prerequisitesPresent(specializations)
23 return SpecializationUtil.hasSpecialization(Fillable, specializations);
24end;
25
26function Trailer:load(xmlFile)
27
28 self.toggleTipState = Trailer.toggleTipState;
29 self.onStartTip = SpecializationUtil.callSpecializationsFunction("onStartTip");
30 self.onEndTip = SpecializationUtil.callSpecializationsFunction("onEndTip");
31 self.enableTipAnimation = SpecializationUtil.callSpecializationsFunction("enableTipAnimation");
32 self.disableCurrentTipAnimation = SpecializationUtil.callSpecializationsFunction("disableCurrentTipAnimation");
33 self.setCurrentTipAnimationTime = SpecializationUtil.callSpecializationsFunction("setCurrentTipAnimationTime");
34 self.getCurrentTipAnimationTime = Trailer.getCurrentTipAnimationTime;
35 self.getCurrentTipAnimationDuration = Trailer.getCurrentTipAnimationDuration;
36 self.setFillLevel = Utils.prependedFunction(self.setFillLevel, Trailer.setFillLevel);
37 self.getCurrentFruitType = Trailer.getCurrentFruitType;
38 self.updateTipping = Trailer.updateTipping;
39 self.getCanTipToGround = Trailer.getCanTipToGround;
40 self.getCanTip = Trailer.getCanTip;
41 self.getIsToggleCoverAllowed = Utils.overwrittenFunction(self.getIsToggleCoverAllowed, Trailer.getIsToggleCoverAllowed);
42 self.getTipScrollerSpeed = Trailer.getTipScrollerSpeed;
43 self.getEndTipIfEmpty = Trailer.getEndTipIfEmpty;
44
45 self.tipText = Utils.getXMLI18NValue(xmlFile, "vehicle", getXMLString, "tipText", g_i18n:getText("Dump"), self.customEnvironment, false);
46
47 self.lastFillDelta = 0;
48
49 self.tipAnimations = {};
50 local i = 0;
51 while true do
52 local key = string.format("vehicle.tipAnimations.tipAnimation(%d)", i);
53 if not hasXMLProperty(xmlFile, key) then
54 break;
55 end
56
57 local tipAnimation = {};
58 tipAnimation.dischargeEndTime = getXMLFloat(xmlFile, key.."#dischargeEndTime");
59 if tipAnimation.dischargeEndTime ~= nil then
60 tipAnimation.dischargeEndTime = tipAnimation.dischargeEndTime * 1000;
61 end
62 tipAnimation.dischargeStartTime = Utils.getNoNil(getXMLFloat(xmlFile, key.."#dischargeStartTime"), 0)*1000;
63 local animationName = getXMLString(xmlFile, key.."#animationName");
64
65 tipAnimation.animationOpenSpeedScale = getXMLFloat(xmlFile, key.."#openSpeedScale");
66 tipAnimation.animationCloseSpeedScale = getXMLFloat(xmlFile, key.."#closeSpeedScale");
67
68 local speedScale = Utils.getNoNil(getXMLFloat(xmlFile, key.."#speedScale"), 1);
69 if tipAnimation.animationOpenSpeedScale == nil then
70 tipAnimation.animationOpenSpeedScale = speedScale;
71 end
72 if tipAnimation.animationCloseSpeedScale == nil then
73 tipAnimation.animationCloseSpeedScale = -speedScale;
74 end
75
76 if animationName ~= nil then
77 if self.playAnimation ~= nil and self.getAnimationDuration ~= nil then
78 tipAnimation.animationName = animationName;
79 tipAnimation.animationDuration = self:getAnimationDuration(animationName);
80 else
81 print("Error: tip animation "..i.." has animation name, but misses specialization AnimatedVehicle in "..self.configFileName);
82 end
83 else
84 local animationRootNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#rootNode"));
85 if animationRootNode ~= nil then
86 local animationCharSet = getAnimCharacterSet(animationRootNode);
87 if animationCharSet ~= nil then
88 local clip = getAnimClipIndex(animationCharSet, getXMLString(xmlFile, key.."#clip"));
89 assignAnimTrackClip(animationCharSet, 0, clip);
90 setAnimTrackLoopState(animationCharSet, 0, false);
91
92 tipAnimation.animationCharSet = animationCharSet;
93 tipAnimation.animationDuration = getAnimClipDuration(animationCharSet, clip);
94 end
95 end
96 end
97 if tipAnimation.dischargeEndTime == nil and tipAnimation.animationDuration ~= nil then
98 tipAnimation.dischargeEndTime = tipAnimation.animationDuration*2.0;
99 end
100 if tipAnimation.dischargeEndTime ~= nil then
101 if self.isClient then
102 tipAnimation.dischargeParticleSystems = {};
103 local i = 0;
104 while true do
105 local keyPS = string.format(key..".dischargeParticleSystems.dischargeParticleSystem(%d)", i);
106 local t = getXMLString(xmlFile, keyPS .. "#type");
107 if t == nil then
108 break;
109 end;
110 local fillType = Fillable.fillTypeNameToInt[t];
111 if fillType ~= nil then
112 local currentPS = Utils.getNoNil(tipAnimation.dischargeParticleSystems[fillType], {});
113 local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, keyPS, self.components, false, nil, self.baseDirectory);
114 tipAnimation.dischargeParticleSystems[fillType] = currentPS;
115 end;
116 i = i + 1;
117 end;
118
119 local fillTypes = getXMLString(xmlFile, key..".tipEffect#fillTypes");
120 if fillTypes ~= nil then
121 for _, typeStr in pairs(Utils.splitString(" ", fillTypes)) do
122 if Fillable.fillTypeNameToInt[typeStr] ~= nil then
123 if tipAnimation.tipEffectFillTypes == nil then
124 tipAnimation.tipEffectFillTypes = {};
125 end;
126 tipAnimation.tipEffectFillTypes[Fillable.fillTypeNameToInt[typeStr]] = true;
127 end;
128 end;
129 end;
130
131 tipAnimation.tipEffect = EffectManager:loadEffect(xmlFile, key..".tipEffect", self.components, self);
132 end
133
134 tipAnimation.doorAnimationName = getXMLString(xmlFile, key.."#doorAnimationName");
135 tipAnimation.doorAnimationSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, key.."#doorAnimationSpeedScale"), 1.0);
136 tipAnimation.doorAnimationOpenSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, key.."#doorAnimationOpenSpeedScale"), speedScale);
137 tipAnimation.doorAnimationCloseSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, key.."#doorAnimationCloseSpeedScale"), -speedScale);
138
139 tipAnimation.fillVolumeDischargeInfo = {};
140 tipAnimation.fillVolumeDischargeInfo.node = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(xmlFile, key..".fillVolumeDischargeInfo#index"), "0>"));
141 tipAnimation.fillVolumeDischargeInfo.width = Utils.getNoNil(getXMLFloat(xmlFile, key..".fillVolumeDischargeInfo#width"), 1.0);
142 tipAnimation.fillVolumeDischargeInfo.length = Utils.getNoNil(getXMLFloat(xmlFile, key..".fillVolumeDischargeInfo#length"), 1.0);
143
144 tipAnimation.fillVolumeDischargeInfo.alsoUseLoadInfoForDischarge = Utils.getNoNil(getXMLBool(xmlFile, key..".fillVolumeDischargeInfo#alsoUseLoadInfoForDischarge"), false);
145 tipAnimation.fillVolumeDischargeInfo.loadInfoSizeScale = Utils.getVectorNFromString( Utils.getNoNil(getXMLString(xmlFile, key..".fillVolumeDischargeInfo#loadInfoSizeScale"), "1 1"), 2 );
146 tipAnimation.fillVolumeDischargeInfo.loadInfoFillFactor = Utils.getNoNil(getXMLFloat(xmlFile, key..".fillVolumeDischargeInfo#loadInfoFillFactor"), 0.6);
147
148 tipAnimation.fillVolumeHeightIndex = getXMLInt(xmlFile, key..".fillVolumeHeight#index");
149
150 table.insert(self.tipAnimations, tipAnimation);
151 else
152 print("Error: invalid tip animation "..i.." in "..self.configFileName);
153 end
154 i = i + 1;
155 end
156
157 -- Fallback for old tipAnimation and tipDischargeEndTime
158 if table.getn(self.tipAnimations) == 0 then
159 local tipAnimation = {};
160 tipAnimation.dischargeEndTime = getXMLFloat(xmlFile, "vehicle.tipDischargeEndTime#value");
161 tipAnimation.dischargeStartTime = 0;
162
163 local animationRootNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tipAnimation#rootNode"));
164 if animationRootNode ~= nil then
165 local animationCharSet = getAnimCharacterSet(animationRootNode);
166 if animationCharSet ~= 0 then
167
168 local clip = getAnimClipIndex(animationCharSet, getXMLString(xmlFile, "vehicle.tipAnimation#clip"));
169 assignAnimTrackClip(animationCharSet, 0, clip);
170 setAnimTrackLoopState(animationCharSet, 0, false);
171
172 tipAnimation.animationOpenSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.tipAnimation#speedScale"), 1);
173 tipAnimation.animationCloseSpeedScale = -tipAnimation.animationOpenSpeedScale;
174 tipAnimation.animationCharSet = animationCharSet;
175 tipAnimation.animationDuration = getAnimClipDuration(animationCharSet, clip);
176 if tipAnimation.dischargeEndTime == nil then
177 tipAnimation.dischargeEndTime = tipAnimation.animationDuration*2.0;
178 end
179 end
180 end
181
182 if tipAnimation.dischargeEndTime ~= nil then
183 if self.isClient then
184 tipAnimation.dischargeParticleSystems = {};
185 local i = 0;
186 while true do
187 local keyPS = string.format("vehicle.dischargeParticleSystems.dischargeParticleSystem(%d)", i);
188 local t = getXMLString(xmlFile, keyPS .. "#type");
189 if t == nil then
190 break;
191 end;
192 local fillType = Fillable.fillTypeNameToInt[t];
193 if fillType ~= nil then
194 local currentPS = Utils.getNoNil(tipAnimation.dischargeParticleSystems[fillType], {});
195 local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, keyPS, self.components, false, nil, self.baseDirectory);
196 tipAnimation.dischargeParticleSystems[fillType] = currentPS;
197 end;
198 i = i + 1;
199 end;
200 end
201
202 table.insert(self.tipAnimations, tipAnimation);
203 end
204 end
205 self.tipState = Trailer.TIPSTATE_CLOSED;
206
207 self.fillLevelToTippedFillLevel = 1;
208
209 self.tipReferencePoints = {};
210 local i = 0;
211 while true do
212 local key = string.format("vehicle.tipReferencePoints.tipReferencePoint(%d)", i);
213 if not hasXMLProperty(xmlFile, key) then
214 break;
215 end
216
217 node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
218 if node ~= nil then
219 local width = Utils.getNoNil(getXMLFloat(xmlFile, key.."#width"), 0);
220 table.insert(self.tipReferencePoints, {node=node, width=width});
221 end
222 i = i + 1;
223 end
224
225 if hasXMLProperty(xmlFile, "vehicle.tipReferencePoint") then
226 print("Warning: vehicle.tipReferencePoint is not supported anymore. Use vehicle.tipReferencePoints.tipReferencePoint instead");
227 end;
228
229 if self.isClient then
230 if hasXMLProperty(xmlFile, "vehicle.hydraulicSound#file") then
231 print("Warning: vehicle.hydraulicSound is not supported anymore. Use vehicle.cylinderedHydraulicSound instead");
232 end
233
234 self.sampleFillSound = Utils.loadSample(xmlFile, {}, "vehicle.fillSound", nil, self.baseDirectory);
235
236 self.tipRotationNodes = Utils.loadRotationNodes(xmlFile, {}, "vehicle.tipRotationNodes.tipRotationNode", "trailer", self.components);
237 self.tipScrollers = Utils.loadScrollers(self.components, xmlFile, "vehicle.tipScrollerNodes.tipScrollerNode", {}, false);
238 end;
239
240 local start = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.groundDropArea#startIndex"));
241 local width = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.groundDropArea#widthIndex"));
242 local height = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.groundDropArea#heightIndex"));
243 if start ~= nil and width ~= nil and height ~= nil then
244 local area = {};
245 area.start = start;
246 area.width = width;
247 area.height = height;
248 self.groundDropArea = area;
249 end;
250
251 self.groundAmountAccumulation = 0;
252
253 self.isSelectable = true;
254
255 self.allowTipDischarge = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.allowTipDischarge#value"), true);
256end;
257
258function Trailer:delete()
259 if self.isClient then
260 for _, tipAnimation in pairs(self.tipAnimations) do
261 for _, particleSystem in pairs(tipAnimation.dischargeParticleSystems) do
262 Utils.deleteParticleSystem(particleSystem);
263 end
264 if tipAnimation.tipEffect ~= nil then
265 EffectManager:deleteEffect(tipAnimation.tipEffect);
266 end;
267 end
268 Utils.deleteSample(self.sampleFillSound);
269 end
270end;
271
272function Trailer:mouseEvent(posX, posY, isDown, isUp, button)
273end;
274
275function Trailer:keyEvent(unicode, sym, modifier, isDown)
276end;
277
278function Trailer:readStream(streamId, connection)
279 if connection:getIsServer() then
280 local tipState = streamReadUIntN(streamId, 2);
281 if tipState ~= Trailer.TIPSTATE_CLOSED then
282 local tipReferencePointIndex = streamReadUIntN(streamId, 4);
283 local animTime = streamReadFloat32(streamId);
284
285 if self.currentTipReferencePointIndex ~= nil and self.currentTipReferencePointIndex ~= tipReferencePointIndex then
286 self:disableCurrentTipAnimation(0);
287 end
288
289 if tipState == Trailer.TIPSTATE_CLOSING then
290 self.currentTipReferencePointIndex = tipReferencePointIndex;
291 self:onEndTip(true);
292 else
293 self:onStartTip(nil, tipReferencePointIndex, true);
294 end;
295 self:setCurrentTipAnimationTime(animTime);
296 else
297 self:disableCurrentTipAnimation(0);
298 end;
299 self.tipState = tipState;
300 end;
301end;
302
303function Trailer:writeStream(streamId, connection)
304 if not connection:getIsServer() then
305 assert(self.tipState >= 0 and self.tipState <= 3);
306 streamWriteUIntN(streamId, self.tipState, 2);
307 if self.tipState ~= Trailer.TIPSTATE_CLOSED then
308 local animTime = self:getCurrentTipAnimationTime();
309 streamWriteFloat32(streamId, animTime);
310
311 local tipReferencePointIndex = Utils.getNoNil(self.currentTipReferencePointIndex, 1);
312 assert(tipReferencePointIndex <= 15);
313 streamWriteUIntN(streamId, tipReferencePointIndex, 4);
314 end;
315 end;
316end;
317
318--[[function Trailer:readUpdateStream(streamId, timestamp, connection)
319end;
320
321function Trailer:writeUpdateStream(streamId, connection, dirtyMask)
322end;]]
323
324function Trailer:update(dt)
325 if self:getIsActiveForInput() then
326 if self ~= g_currentMission.trailerInTipRange and self:getCanTipToGround() then
327 if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
328 self:toggleTipState(nil, 1, true);
329 end;
330 end;
331 end;
332
333 if self.isClient then
334 local tipScrollersSpeed = self:getTipScrollerSpeed()
335 Utils.updateScrollers(self.tipScrollers, dt*tipScrollersSpeed, tipScrollersSpeed > 0 );
336 Utils.updateRotationNodes(self, self.tipRotationNodes, dt, self:getIsActive() and self.tipState ~= Trailer.TIPSTATE_CLOSED );
337
338 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
339 for i,fillVolume in pairs(self.fillVolumes) do
340 if fillVolume.scrollSpeedDischarge[1] ~= 0 or fillVolume.scrollSpeedDischarge[2] ~= 0 or fillVolume.scrollSpeedDischarge[3] ~= 0 then
341 fillVolume.uvPosition[1] = fillVolume.uvPosition[1] + fillVolume.scrollSpeedDischarge[1]*dt;
342 fillVolume.uvPosition[2] = fillVolume.uvPosition[2] + fillVolume.scrollSpeedDischarge[2]*dt;
343 fillVolume.uvPosition[3] = fillVolume.uvPosition[3] + fillVolume.scrollSpeedDischarge[3]*dt;
344 setShaderParameter(fillVolume.volume, "uvOffset", fillVolume.uvPosition[1], fillVolume.uvPosition[2], fillVolume.uvPosition[3], 0, false);
345 end;
346 end;
347 end;
348 end;
349end;
350
351function Trailer:updateTick(dt)
352
353 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
354
355 if self.isServer then
356 self:updateTipping(dt);
357 end;
358
359 if self.fillLevel <= 0 and self:getEndTipIfEmpty() then
360 self:onEndTip(true);
361 end;
362
363 if self.tipState == Trailer.TIPSTATE_OPENING then
364 if self:getCurrentTipAnimationTime() >= self:getCurrentTipAnimationDuration() then
365 self.tipState = Trailer.TIPSTATE_OPEN;
366 end;
367 end;
368
369 if self.isClient then
370 -- check if we still are in opening/open state. Maybe we ended tipping before.
371 if (self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN) and self.fillLevel > 0 then
372 if self:getIsActiveForSound() then
373 Utils.playSample(self.sampleFillSound, 0, 0, nil);
374 end;
375 else
376 Utils.stopSample(self.sampleFillSound);
377 end;
378
379 if self.currentTipReferencePointIndex ~= nil then
380 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
381 local tipAnimation = self.tipAnimations[self.currentTipReferencePointIndex];
382 if tipAnimation ~= nil and tipAnimation.fillVolumeHeightIndex ~= nil then
383 if self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex] ~= nil then
384 self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex].volumeHeightIsDirty = true;
385 end;
386 end;
387 end;
388 end;
389
390 end;
391
392 elseif self.tipState == Trailer.TIPSTATE_CLOSING then
393 if self:getCurrentTipAnimationTime() <= 0.0 then
394 self:disableCurrentTipAnimation();
395 self.tipState = Trailer.TIPSTATE_CLOSED;
396 end;
397 end;
398
399 if self.isClient then
400 if self.currentTipReferencePointIndex ~= nil then
401 local tipAnimation = self.tipAnimations[self.currentTipReferencePointIndex];
402 if tipAnimation ~= nil then
403 if (self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN) and self.fillLevel > 0 and self:getCurrentTipAnimationTime() >= tipAnimation.dischargeStartTime then
404 Utils.setEmittingState(tipAnimation.dischargeParticleSystems[self.currentFillType], true);
405 if tipAnimation.tipEffect ~= nil and self.currentTipEffect == nil then
406 if tipAnimation.tipEffectFillTypes == nil or tipAnimation.tipEffectFillTypes[self.currentFillType] ~= nil then
407 self.currentTipEffect = tipAnimation.tipEffect;
408 self.currentTipEffect:setFillType(self.currentFillType);
409 EffectManager:startEffect(self.currentTipEffect);
410 end;
411 end;
412 else
413 Utils.setEmittingState(tipAnimation.dischargeParticleSystems[self.currentFillType], false);
414 end;
415 end
416 end
417
418 if self.currentTipEffect ~= nil then
419 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
420 if self.currentTipReferencePointIndex ~= nil then
421 local tipAnimation = self.tipAnimations[self.currentTipReferencePointIndex];
422 if tipAnimation ~= nil then
423 if self.fillLevel > 0 then
424 if tipAnimation.dischargeEndTime > tipAnimation.dischargeStartTime then
425 local m = self:getCapacity()/((tipAnimation.dischargeEndTime-tipAnimation.dischargeStartTime)/tipAnimation.animationOpenSpeedScale);
426 if self.fillLevel <= m * self.currentTipEffect.planeFadeTime then
427 EffectManager:stopEffect(self.currentTipEffect);
428 self.currentTipEffect = nil;
429 end;
430 end;
431 end;
432 end;
433 end;
434 end;
435 end;
436 end;
437end;
438
439function Trailer:updateTipping(dt)
440 if not self.isServer then
441 return;
442 end;
443 if self:getCanTip() then
444 local fillType = self.currentFillType;
445
446 local fillDelta = -self.fillLevel;
447 if self.currentTipReferencePointIndex ~= nil then
448 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
449 if animation ~= nil and animation.dischargeEndTime > animation.dischargeStartTime then
450 if self:getCurrentTipAnimationTime() >= animation.dischargeStartTime then
451 local m = self:getCapacity()/((animation.dischargeEndTime-animation.dischargeStartTime)/animation.animationOpenSpeedScale);
452 fillDelta = -m * dt;
453 else
454 fillDelta = 0;
455 end
456 end
457 end
458
459 if fillDelta < 0 then
460 local curFill = self.fillLevel;
461
462 if self.tipAnimations[self.currentTipReferencePointIndex].fillVolumeDischargeInfo ~= nil then
463 local info = self.tipAnimations[self.currentTipReferencePointIndex].fillVolumeDischargeInfo;
464 local x,y,z = getWorldTranslation(info.node);
465 local d1x,d1y,d1z = localDirectionToWorld(info.node, info.width,0,0); -- ToDo: estimate length of vector by ?delta filllevel?!
466 local d2x,d2y,d2z = localDirectionToWorld(info.node, 0,0,info.length);
467 local fillSourceStruct = {x=x,y=y,z=z, d1x=d1x,d1y=d1y,d1z=d1z, d2x=d2x,d2y=d2y,d2z=d2z};
468
469 if fillDelta < 0 then
470 if info.alsoUseLoadInfoForDischarge and self.fillVolumeLoadInfo ~= nil then
471 local fillDeltaLoadInfo = fillDelta*info.loadInfoFillFactor;
472 fillDelta = fillDelta - fillDeltaLoadInfo;
473 local x,y,z = getWorldTranslation(self.fillVolumeLoadInfo.node);
474 local d1x,d1y,d1z = localDirectionToWorld(self.fillVolumeLoadInfo.node, self.fillVolumeLoadInfo.width*info.loadInfoSizeScale[1],0,0);
475 local d2x,d2y,d2z = localDirectionToWorld(self.fillVolumeLoadInfo.node, 0,0,self.fillVolumeLoadInfo.length*info.loadInfoSizeScale[2]);
476 local fss2 = {x=x,y=y,z=z, d1x=d1x,d1y=d1y,d1z=d1z, d2x=d2x,d2y=d2y,d2z=d2z};
477 self:setFillLevel(self.fillLevel + fillDeltaLoadInfo, fillType, false, fss2);
478 end;
479 end;
480
481 self:setFillLevel(self.fillLevel + fillDelta, fillType, false, fillSourceStruct);
482 else
483 local fillSourceStruct = {x=0,y=0,z=0, d1x=0,d1y=0,d1z=0, d2x=0,d2y=0,d2z=0};
484 self:setFillLevel(self.fillLevel + fillDelta, fillType, false, fillSourceStruct);
485 end;
486
487 --
488 local fillDelta = self.fillLevel - curFill;
489 self.lastFillDelta = fillDelta;
490
491 if self.currentTipTrigger ~= nil then
492 if self.currentTipTrigger.updateTrailerTipping ~= nil then
493 self.currentTipTrigger:updateTrailerTipping(self, fillDelta*self.fillLevelToTippedFillLevel, fillType);
494 end
495 elseif self:getCanTipToGround() then
496 if fillDelta < 0 then
497 local x, _,z = getWorldTranslation(self.groundDropArea.start);
498 local x1,_,z1 = getWorldTranslation(self.groundDropArea.width);
499 local x2,_,z2 = getWorldTranslation(self.groundDropArea.height);
500
501 local area = {x,z,x1,z1,x2,z2, -fillDelta*self.fillLevelToTippedFillLevel};
502 local area, bitType, valueAccumulation = TrailerTipAreaEvent.runLocally(area, fillType, self.groundAmountAccumulation)
503 if area ~= nil then
504 g_server:broadcastEvent(TrailerTipAreaEvent:new(area, bitType, fillType));
505 end;
506 if valueAccumulation ~= nil then
507 self.groundAmountAccumulation = valueAccumulation;
508 end;
509 end;
510 end;
511 end
512
513 else
514 self:onEndTip();
515 end;
516end;
517
518function Trailer:draw()
519 if self.isClient then
520 if self:getIsActiveForInput(true) then
521 if self ~= g_currentMission.trailerInTipRange and self:getCanTipToGround() then
522 g_currentMission:addHelpButtonText(g_i18n:getText("Dump"), InputBinding.IMPLEMENT_EXTRA);
523 end;
524 end
525 end;
526end;
527
528function Trailer:toggleTipState(tipTrigger, tipReferencePointIndex, tipManually)
529
530 if self.tipState == Trailer.TIPSTATE_CLOSED or self.tipState == Trailer.TIPSTATE_CLOSING then
531 self:onStartTip(tipTrigger, tipReferencePointIndex, false, tipManually);
532 else
533 self:onEndTip();
534 end;
535end;
536
537
538-- TODO FS17: correct order of parameters
539function Trailer:onStartTip(tipTrigger, tipReferencePointIndex, noEventSend, tipManually)
540 -- we can not start tipping while we are tipping with another animation
541 if self.isServer then
542 if self.currentTipReferencePointIndex ~= nil and self.currentTipReferencePointIndex ~= tipReferencePointIndex then
543 return;
544 end
545 end
546
547 if noEventSend == nil or noEventSend == false then
548 if g_server ~= nil then
549 g_server:broadcastEvent(TrailerToggleTipEvent:new(self, true, tipTrigger, tipReferencePointIndex, tipManually), nil, nil, self);
550 else
551 g_client:getServerConnection():sendEvent(TrailerToggleTipEvent:new(self, true, tipTrigger, tipReferencePointIndex, tipManually));
552 end;
553 end;
554
555 if self.isServer then
556 self.currentTipTrigger = tipTrigger;
557 self.groundAmountAccumulation = 0;
558 end
559 self:enableTipAnimation(tipReferencePointIndex, 1);
560 self.currentTipReferencePointIndex = tipReferencePointIndex;
561 self.tipState = Trailer.TIPSTATE_OPENING;
562
563 if self.setCoverState ~= nil then
564 self:setCoverState(true, true);
565 end;
566
567 local tipAnimation = self.tipAnimations[tipReferencePointIndex];
568 if tipAnimation ~= nil then
569 if tipAnimation.fillVolumeHeightIndex ~= nil then
570 if self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex] ~= nil then
571 self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex].volumeHeightIsDirty = true;
572 end;
573 end;
574 end;
575end;
576
577function Trailer:onEndTip(noEventSend)
578 if noEventSend == nil or noEventSend == false then
579 if g_server ~= nil then
580 g_server:broadcastEvent(TrailerToggleTipEvent:new(self, false), nil, nil, self);
581 else
582 g_client:getServerConnection():sendEvent(TrailerToggleTipEvent:new(self, false));
583 end;
584 end;
585 if self.currentTipReferencePointIndex ~= nil then
586 self:enableTipAnimation(self.currentTipReferencePointIndex, -1);
587 end
588
589 if self.isServer then
590 self.currentTipTrigger = nil;
591 end
592
593 if self.isClient then
594 Utils.stopSample(self.sampleFillSound);
595 end;
596
597 self.tipState = Trailer.TIPSTATE_CLOSING;
598end;
599
600function Trailer:getCurrentFruitType()
601 local fruitType = FruitUtil.fillTypeToFruitType[self.currentFillType];
602 if fruitType == nil then
603 fruitType = FruitUtil.FRUITTYPE_UNKNOWN;
604 end;
605 return fruitType;
606end;
607
608function Trailer:setFillLevel(fillLevel, fillType, force, fillSourceStruct)
609
610 if self.isClient then
611 -- disable particle system if we switch the type or if the trailer is empty
612 if (self.currentFillType ~= fillType or fillLevel <= 0) and self.currentTipReferencePointIndex ~= nil then
613 local tipAnimation = self.tipAnimations[self.currentTipReferencePointIndex];
614 if tipAnimation ~= nil then
615 Utils.setEmittingState(tipAnimation.dischargeParticleSystems[self.currentFillType], false);
616 end
617 end
618 end
619end;
620
621function Trailer:onAttach(attacherVehicle)
622end;
623
624function Trailer:onDeactivateSounds()
625 if self.isClient then
626 Utils.stopSample(self.sampleFillSound, true);
627 end;
628end;
629
630function Trailer:getCanTip()
631 if self.currentFillType ~= Fillable.FILLTYPE_UNKNOWN then
632 if self.currentTipTrigger ~= nil then
633 return g_currentMission:getIsTrailerInTipRange(self, self.currentTipTrigger, self.currentTipReferencePointIndex);
634 else
635 return self:getCanTipToGround();
636 end
637 end
638 return false;
639end
640
641function Trailer:getCanTipToGround()
642 return g_currentMission.groundValueIds[self.currentFillType] ~= nil and self.groundDropArea ~= nil;
643end;
644
645function Trailer:getEndTipIfEmpty()
646 return true;
647end;
648
649function Trailer:enableTipAnimation(tipReferencePointIndex, direction, animTime)
650 if self.currentTipReferencePointIndex ~= tipReferencePointIndex then
651 self:disableCurrentTipAnimation(0);
652 end
653
654 self.currentTipReferencePointIndex = tipReferencePointIndex;
655
656 local animation = self.tipAnimations[tipReferencePointIndex];
657
658 if animation ~= nil then
659 local speedScale = animation.animationOpenSpeedScale;
660 if direction < 0 then
661 speedScale = animation.animationCloseSpeedScale;
662 end
663 if animation.animationName ~= nil then
664 self:playAnimation(animation.animationName, speedScale, self:getAnimationTime(animation.animationName), true);
665 if animTime ~= nil then
666 self:setRealAnimationTime(animation.animationName, animTime);
667 end
668 elseif animation.animationCharSet ~= nil then
669 enableAnimTrack(animation.animationCharSet, 0);
670 setAnimTrackSpeedScale(animation.animationCharSet, 0, speedScale);
671 if animTime ~= nil then
672 setAnimTrackTime(animation.animationCharSet, 0, animTime);
673 else
674 if direction > 0 then
675 if getAnimTrackTime(animation.animationCharSet, 0) < 0 then
676 setAnimTrackTime(animation.animationCharSet, 0, 0);
677 end;
678 else
679 if getAnimTrackTime(animation.animationCharSet, 0) > animation.animationDuration then
680 setAnimTrackTime(animation.animationCharSet, 0, animation.animationDuration);
681 end;
682 end
683 end
684 end
685
686 if animation.doorAnimationName ~= nil then
687 local speedScale = animation.doorAnimationOpenSpeedScale;
688 if direction < 0 then
689 speedScale = animation.doorAnimationCloseSpeedScale;
690 end;
691 self:playAnimation(animation.doorAnimationName, speedScale, self:getAnimationTime(animation.doorAnimationName), true);
692 end;
693
694 if direction <= 0 then
695 if self.currentTipEffect ~= nil then
696 EffectManager:stopEffect(self.currentTipEffect);
697 self.currentTipEffect = nil;
698 end;
699 end;
700 end
701end
702
703function Trailer:disableCurrentTipAnimation(animTime)
704 if self.currentTipReferencePointIndex ~= nil then
705 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
706 if animation ~= nil then
707 Utils.setEmittingState(animation.dischargeParticleSystems[self.currentFillType], false);
708
709 if animation.animationName ~= nil then
710 if animTime ~= nil then
711 self:setRealAnimationTime(animation.animationName, math.min(animTime, animation.animationDuration));
712 end
713 self:stopAnimation(animation.animationName, true);
714 elseif animation.animationCharSet ~= nil then
715 if animTime ~= nil then
716 enableAnimTrack(animation.animationCharSet, 0);
717 setAnimTrackTime(animation.animationCharSet, 0, animTime, true);
718 end
719 disableAnimTrack(animation.animationCharSet, 0);
720 end
721 end
722 self.currentTipReferencePointIndex = nil;
723 end
724end
725
726function Trailer:setCurrentTipAnimationTime(animTime)
727 if self.currentTipReferencePointIndex ~= nil then
728 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
729 if animation ~= nil then
730 if animation.animationName ~= nil then
731 self:setRealAnimationTime(animation.animationName, math.min(animTime, animation.animationDuration));
732 elseif animation.animationCharSet ~= nil then
733 setAnimTrackTime(animation.animationCharSet, 0, animTime);
734 end
735 end
736 end
737end
738
739function Trailer:getCurrentTipAnimationTime()
740 if self.currentTipReferencePointIndex ~= nil then
741 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
742 if animation ~= nil then
743 if animation.animationName ~= nil then
744 return self:getRealAnimationTime(animation.animationName);
745 elseif animation.animationCharSet ~= nil then
746 return getAnimTrackTime(animation.animationCharSet, 0);
747 end
748 end
749 end
750 return 0;
751end
752
753function Trailer:getCurrentTipAnimationDuration()
754 if self.currentTipReferencePointIndex ~= nil then
755 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
756 if animation ~= nil then
757 return animation.animationDuration;
758 end
759 end
760 return 0;
761end
762
763function Trailer:getIsToggleCoverAllowed(superFunc, isCoverOpen)
764 if not isCoverOpen and self.tipState ~= Trailer.TIPSTATE_CLOSED then
765 return false;
766 end;
767
768 if superFunc ~= nil then
769 return superFunc(self, isCoverOpen);
770 end;
771
772 return true;
773end
774
775function Trailer:getTipScrollerSpeed()
776 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
777 return 1.0;
778 else
779 return 0;
780 end;
781end;
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
Script Dokumentation Übersicht