LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

Trailer

Description
This is the specialization for trailers
Functions

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
27function Trailer.prerequisitesPresent(specializations)
28 return SpecializationUtil.hasSpecialization(Fillable, specializations);
29end

preLoad

Description
Called before loading
Definition
preLoad(table savegame)
Arguments
tablesavegamesavegame
Code
34function Trailer:preLoad(savegame)
35 self.togglePreferedTipReferencePointIndex = Trailer.togglePreferedTipReferencePointIndex;
36 self.toggleTipState = Trailer.toggleTipState;
37 self.onStartTip = SpecializationUtil.callSpecializationsFunction("onStartTip");
38 self.onEndTip = SpecializationUtil.callSpecializationsFunction("onEndTip");
39 self.enableTipAnimation = SpecializationUtil.callSpecializationsFunction("enableTipAnimation");
40 self.disableCurrentTipAnimation = SpecializationUtil.callSpecializationsFunction("disableCurrentTipAnimation");
41 self.setCurrentTipAnimationTime = SpecializationUtil.callSpecializationsFunction("setCurrentTipAnimationTime");
42 self.getCurrentTipAnimationTime = Trailer.getCurrentTipAnimationTime;
43 self.getCurrentTipAnimationDuration = Trailer.getCurrentTipAnimationDuration;
44 self.setFillLevel = Utils.prependedFunction(self.setFillLevel, Trailer.setFillLevel);
45 self.getCurrentFruitType = Trailer.getCurrentFruitType;
46 self.updateTipping = Trailer.updateTipping;
47 self.getCanTipToGround = Trailer.getCanTipToGround;
48 self.getCanTip = Trailer.getCanTip;
49 self.getIsToggleCoverAllowed = Utils.overwrittenFunction(self.getIsToggleCoverAllowed, Trailer.getIsToggleCoverAllowed);
50 self.getTipScrollerSpeed = Trailer.getTipScrollerSpeed;
51 self.getEndTipIfEmpty = Trailer.getEndTipIfEmpty;
52 self.isDetachAllowed = Utils.overwrittenFunction(self.isDetachAllowed, Trailer.isDetachAllowed);
53end

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
58function Trailer:load(savegame)
59 self.getAllowFillFromAir = Utils.overwrittenFunction(self.getAllowFillFromAir, Trailer.getAllowFillFromAir);
60 self.getDischargeInfos = Utils.overwrittenFunction(self.getDischargeInfos, Trailer.getDischargeInfos);
61 self.tipText = Utils.getXMLI18NValue(self.xmlFile, "vehicle", getXMLString, "tipText", g_i18n:getText("action_tip"), self.customEnvironment, true);
62
63 --self.lastFillDelta = 0;
64
65 self.tipAnimations = {};
66 local i = 0;
67 while true do
68 local key = string.format("vehicle.tipAnimations.tipAnimation(%d)", i);
69 if not hasXMLProperty(self.xmlFile, key) then
70 break;
71 end
72
73 local tipAnimation = {};
74
75 tipAnimation.name = getXMLString(self.xmlFile, key.."#name");
76 if tipAnimation.name ~= nil then
77 local i18n = g_i18n;
78 if self.customEnvironment ~= nil then
79 i18n = _G[self.customEnvironment].g_i18n;
80 end
81
82 tipAnimation.name = i18n:getText(tipAnimation.name);
83 else
84 tipAnimation.name = i + 1;
85 end
86
87 tipAnimation.dischargeEndTime = getXMLFloat(self.xmlFile, key.."#dischargeEndTime");
88 if tipAnimation.dischargeEndTime ~= nil then
89 tipAnimation.dischargeEndTime = tipAnimation.dischargeEndTime * 1000;
90 end
91 tipAnimation.dischargeStartTime = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#dischargeStartTime"), 0)*1000;
92 local animationName = getXMLString(self.xmlFile, key.."#animationName");
93
94 tipAnimation.animationOpenSpeedScale = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#openSpeedScale"), 1);
95 tipAnimation.animationCloseSpeedScale = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#closeSpeedScale"), -1);
96
97 tipAnimation.unloadingSpeedScale = getXMLFloat(self.xmlFile, key.."#speedScale");
98
99 if tipAnimation.unloadingSpeedScale == nil then
100 tipAnimation.unloadingSpeedScale = tipAnimation.animationOpenSpeedScale;
101 end;
102
103 if animationName ~= nil then
104 if self.playAnimation ~= nil and self.getAnimationDuration ~= nil then
105 tipAnimation.animationName = animationName;
106 tipAnimation.animationDuration = self:getAnimationDuration(animationName);
107 else
108 print("Error: tip animation "..i.." has animation name, but misses specialization AnimatedVehicle in "..self.configFileName);
109 end
110 else
111 local animationRootNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key.."#rootNode"));
112 if animationRootNode ~= nil then
113 local animationCharSet = getAnimCharacterSet(animationRootNode);
114 if animationCharSet ~= nil then
115 local clip = getAnimClipIndex(animationCharSet, getXMLString(self.xmlFile, key.."#clip"));
116 assignAnimTrackClip(animationCharSet, 0, clip);
117 setAnimTrackLoopState(animationCharSet, 0, false);
118
119 tipAnimation.animationCharSet = animationCharSet;
120 tipAnimation.animationDuration = getAnimClipDuration(animationCharSet, clip);
121 end
122 end
123 end
124 if tipAnimation.dischargeEndTime == nil and tipAnimation.animationDuration ~= nil then
125 tipAnimation.dischargeEndTime = tipAnimation.animationDuration*2.0;
126 end
127 if tipAnimation.dischargeEndTime ~= nil then
128 if self.isClient then
129 tipAnimation.emitterShape = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key..".emitterShape#node"));
130 tipAnimation.emitCountScale = Utils.getNoNil(getXMLFloat(self.xmlFile, key..".emitterShape#emitCountScale"), 1);
131 tipAnimation.isAdditionalEffect = Utils.getNoNil(getXMLBool(self.xmlFile, key..".emitterShape#isAdditionalEffect"), false);
132 tipAnimation.particleType = getXMLString(self.xmlFile, key..".emitterShape#particleType")
133 tipAnimation.tipEffect = EffectManager:loadEffect(self.xmlFile, key..".tipEffect", self.components, self);
134 end
135
136 tipAnimation.doorAnimationName = getXMLString(self.xmlFile, key.."#doorAnimationName");
137 tipAnimation.doorAnimationSpeedScale = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#doorAnimationSpeedScale"), 1.0);
138 tipAnimation.doorAnimationOpenSpeedScale = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#doorAnimationOpenSpeedScale"), 1);
139 tipAnimation.doorAnimationCloseSpeedScale = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#doorAnimationCloseSpeedScale"), -1);
140
141 tipAnimation.fillVolumeUnloadInfoIndex = getXMLInt(self.xmlFile, key..".fillVolume.unloadInfo#index");
142 tipAnimation.fillVolumeDischargeInfoIndex = getXMLInt(self.xmlFile, key..".fillVolume.dischargeInfo#index");
143 tipAnimation.fillVolumeHeightIndex = getXMLInt(self.xmlFile, key..".fillVolume.height#index");
144
145 table.insert(self.tipAnimations, tipAnimation);
146 else
147 print("Error: invalid tip animation "..i.." in "..self.configFileName);
148 end
149
150 i = i + 1;
151 end
152
153 if self.isClient then
154 self.referenceParticleSystems = {};
155 for _, tipAnimation in pairs(self.tipAnimations) do
156 local fillUnitIndex = 1
157 if tipAnimation.fillVolumeHeightIndex ~= nil then
158 local volumeId = self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex].fillVolumeIndex;
159 fillUnitIndex = self.fillVolumes[volumeId].fillUnitIndex;
160 end
161 if self.fillUnits[fillUnitIndex] ~= nil then
162 for fillType, _ in pairs(self:getUnitFillTypes(fillUnitIndex)) do
163 if self.referenceParticleSystems[fillType] == nil then
164 local particleSystem = MaterialUtil.getParticleSystem(fillType, Utils.getNoNil(tipAnimation.particleType, "unloading"))
165 if particleSystem ~= nil then
166 local psClone = clone( particleSystem.shape, true, false, true );
167 local currentPS = {};
168 ParticleUtil.loadParticleSystemFromNode(psClone, currentPS, false, true, particleSystem.forceFullLifespan);
169 self.referenceParticleSystems[fillType] = currentPS;
170 end
171 end
172 end
173 end
174 end
175 end
176
177 self.tipState = Trailer.TIPSTATE_CLOSED;
178
179 self.fillLevelToTippedFillLevel = 1;
180
181 self.tipReferencePoints = {};
182 local i = 0;
183 while true do
184 local key = string.format("vehicle.tipReferencePoints.tipReferencePoint(%d)", i);
185 if not hasXMLProperty(self.xmlFile, key) then
186 break;
187 end
188
189 local node = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key.."#index"));
190 if node ~= nil then
191 local width = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#width"), 0);
192 local maxZOffset = Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#maxZOffset"), 2);
193 table.insert(self.tipReferencePoints, {node=node, width=width, zOffset=0, maxZOffset=maxZOffset});
194 end
195 i = i + 1;
196 end
197 if self.tipReferencePoints ~= nil then
198 self.numTipReferencePoints = table.getn(self.tipReferencePoints);
199 else
200 self.numTipReferencePoints = 0;
201 end
202 self.preferedTipReferencePointIndex = 1
203
204 if hasXMLProperty(self.xmlFile, "vehicle.tipReferencePoint") then
205 print("Warning: vehicle.tipReferencePoint is not supported anymore. Use vehicle.tipReferencePoints.tipReferencePoint instead");
206 end
207 if self.isClient then
208 if hasXMLProperty(self.xmlFile, "vehicle.hydraulicSound#file") then
209 print("Warning: vehicle.hydraulicSound is not supported anymore. Use vehicle.cylinderedHydraulicSound instead");
210 end
211
212 self.sampleFillSound = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.fillSound", nil, self.baseDirectory);
213
214 self.tipRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.tipRotationNodes.tipRotationNode", "trailer", self.components);
215 self.tipScrollers = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.tipScrollerNodes.tipScrollerNode", {}, false);
216 end
217
218 local start = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.groundDropArea#startIndex"));
219 local width = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.groundDropArea#widthIndex"));
220 local height = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.groundDropArea#heightIndex"));
221 if start ~= nil and width ~= nil and height ~= nil then
222 local area = {};
223 area.start = start;
224 area.width = width;
225 area.height = height;
226 self.groundDropArea = area;
227 end
228
229 self.remainingFillDelta = 0;
230
231 self.isSelectable = true;
232
233 self.couldNotDropTimer = 0;
234 self.couldNotDropTimerThreshold = 1000;
235
236 self.allowTipDischarge = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.allowTipDischarge#value"), true);
237
238 self.trailer = {};
239 self.trailer.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.trailer#fillUnitIndex"), 1);
240 self.trailer.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.trailer#unloadInfoIndex"), 1);
241 self.trailer.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.trailer#loadInfoIndex"), 1);
242 self.trailer.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.trailer#dischargeInfoIndex"), 1);
243 self.trailer.stopTipToGroundIfEmpty = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.trailer#stopTipToGroundIfEmpty"), false);
244
245 if savegame ~= nil then
246 self.preferedTipReferencePointIndex = Utils.getNoNil(getXMLFloat(savegame.xmlFile, savegame.key .. "#preferedTipReferencePointIndex"), self.preferedTipReferencePointIndex);
247 end
248end

delete

Description
Called on deleting
Definition
delete()
Code
252function Trailer:delete()
253 if self.isClient then
254 ParticleUtil.deleteParticleSystems(self.referenceParticleSystems)
255 for _, tipAnimation in pairs(self.tipAnimations) do
256 if tipAnimation.tipEffect ~= nil then
257 EffectManager:deleteEffects(tipAnimation.tipEffect);
258 end
259 end
260 SoundUtil.deleteSample(self.sampleFillSound);
261 end
262end

getSaveAttributesAndNodes

Description
Returns attributes and nodes to save
Definition
getSaveAttributesAndNodes(table nodeIdent)
Arguments
tablenodeIdentnode ident
Return Values
stringattributesattributes
stringnodesnodes
Code
275function Trailer:getSaveAttributesAndNodes(nodeIdent)
276 local attributes = "";
277 attributes = ' preferedTipReferencePointIndex="' .. tostring(self.preferedTipReferencePointIndex)..'"';
278 return attributes, nil;
279end

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
285function Trailer:readStream(streamId, connection)
286 if connection:getIsServer() then
287 local tipState = streamReadUIntN(streamId, 2);
288 if tipState ~= Trailer.TIPSTATE_CLOSED then
289 local tipReferencePointIndex = streamReadUIntN(streamId, 4);
290 local animTime = streamReadFloat32(streamId);
291
292 if self.currentTipReferencePointIndex ~= nil and self.currentTipReferencePointIndex ~= tipReferencePointIndex then
293 self:disableCurrentTipAnimation(0);
294 end
295
296 if tipState == Trailer.TIPSTATE_CLOSING then
297 self.currentTipReferencePointIndex = tipReferencePointIndex;
298 self:onEndTip(true);
299 else
300 self:onStartTip(nil, tipReferencePointIndex, true);
301 end
302 self:setCurrentTipAnimationTime(animTime);
303 else
304 self:disableCurrentTipAnimation(0);
305 end
306 self.tipState = tipState;
307 end
308end

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
314function Trailer:writeStream(streamId, connection)
315 if not connection:getIsServer() then
316 assert(self.tipState >= 0 and self.tipState <= 3);
317 streamWriteUIntN(streamId, self.tipState, 2);
318 if self.tipState ~= Trailer.TIPSTATE_CLOSED then
319 local animTime = self:getCurrentTipAnimationTime();
320 streamWriteFloat32(streamId, animTime);
321
322 local tipReferencePointIndex = Utils.getNoNil(self.currentTipReferencePointIndex, 1);
323 assert(tipReferencePointIndex <= 15);
324 streamWriteUIntN(streamId, tipReferencePointIndex, 4);
325 end
326 end
327end

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
332function Trailer:update(dt)
333 if self:getIsActiveForInput() and self.allowTipDischarge then
334 if InputBinding.hasEvent(InputBinding.TOGGLE_TIPSTATE_GROUND) then
335 if self.numTipReferencePoints > 0 then
336 if self ~= g_currentMission.trailerInTipRange and self:getCanTipToGround() then
337 self:toggleTipState(nil, self.preferedTipReferencePointIndex); --, true);
338 end
339 end
340 end
341 if InputBinding.hasEvent(InputBinding.TOGGLE_TIPSIDE) then
342 if self.numTipReferencePoints > 1 then
343 if self.tipState == Trailer.TIPSTATE_CLOSED then
344 local index = self.preferedTipReferencePointIndex + 1;
345 if index > table.getn(self.tipReferencePoints) then
346 index = 1;
347 end
348 self:togglePreferedTipReferencePointIndex(index);
349 end
350 end
351 end
352 end
353
354 if self.isClient then
355 local tipScrollersSpeed = self:getTipScrollerSpeed()
356 Utils.updateScrollers(self.tipScrollers, dt*tipScrollersSpeed, tipScrollersSpeed > 0 );
357 Utils.updateRotationNodes(self, self.tipRotationNodes, dt, self:getIsActive() and self.tipState ~= Trailer.TIPSTATE_CLOSED );
358
359 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
360 if self.tipAnimations[self.currentTipReferencePointIndex] ~= nil and self.tipAnimations[self.currentTipReferencePointIndex].fillVolumeHeightIndex then
361 local volumeHeight = self.fillVolumeHeights[self.tipAnimations[self.currentTipReferencePointIndex].fillVolumeHeightIndex];
362 if volumeHeight ~= nil then
363 local fillVolume = self.fillVolumes[volumeHeight.fillVolumeIndex];
364 if fillVolume ~= nil then
365 if fillVolume.scrollSpeedDischarge[1] ~= 0 or fillVolume.scrollSpeedDischarge[2] ~= 0 or fillVolume.scrollSpeedDischarge[3] ~= 0 then
366 fillVolume.uvPosition[1] = fillVolume.uvPosition[1] + fillVolume.scrollSpeedDischarge[1]*dt;
367 fillVolume.uvPosition[2] = fillVolume.uvPosition[2] + fillVolume.scrollSpeedDischarge[2]*dt;
368 fillVolume.uvPosition[3] = fillVolume.uvPosition[3] + fillVolume.scrollSpeedDischarge[3]*dt;
369 setShaderParameter(fillVolume.volume, "uvOffset", fillVolume.uvPosition[1], fillVolume.uvPosition[2], fillVolume.uvPosition[3], 0, false);
370 end
371 end
372 end
373 end
374 end
375 end
376end

updateTick

Description
Called on update tick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
381function Trailer:updateTick(dt)
382
383 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
384 if self.isServer then
385 self:updateTipping(dt);
386 end
387
388 if ((self ~= g_currentMission.trailerInTipRange and self:getIsActiveForSound()) or self:getUnitFillLevel(self.trailer.fillUnitIndex) <= 0) and self:getEndTipIfEmpty() then
389 self:onEndTip();
390 end
391
392 if self.tipState == Trailer.TIPSTATE_OPENING then
393 if self:getCurrentTipAnimationTime() >= self:getCurrentTipAnimationDuration() then
394 self.tipState = Trailer.TIPSTATE_OPEN;
395 end
396 end
397
398 if self.isClient then
399 -- check if we still are in opening/open state. Maybe we ended tipping before.
400 if (self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN) and self:getUnitFillLevel(self.trailer.fillUnitIndex) > 0 then
401 if self:getIsActiveForSound() then
402 SoundUtil.playSample(self.sampleFillSound, 0, 0, nil);
403 end
404 else
405 SoundUtil.stopSample(self.sampleFillSound);
406 end
407
408 if self.currentTipReferencePointIndex ~= nil then
409 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
410 local tipAnimation = self.tipAnimations[self.currentTipReferencePointIndex];
411 if tipAnimation ~= nil and tipAnimation.fillVolumeHeightIndex ~= nil then
412 if self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex] ~= nil then
413 self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex].volumeHeightIsDirty = true;
414 end
415 end
416 end
417 end
418
419 end
420
421 elseif self.tipState == Trailer.TIPSTATE_CLOSING then
422 if self:getCurrentTipAnimationTime() <= 0.0 then
423 self:disableCurrentTipAnimation();
424 self.tipState = Trailer.TIPSTATE_CLOSED;
425 end
426 end
427
428 if self.isClient then
429 if self.currentTipReferencePointIndex ~= nil then
430 local tipAnimation = self.tipAnimations[self.currentTipReferencePointIndex];
431 if tipAnimation ~= nil then
432 if (self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN) and self:getUnitFillLevel(self.trailer.fillUnitIndex) > 0 and self:getCurrentTipAnimationTime() >= tipAnimation.dischargeStartTime then
433
434 -- try to find a normal PS for the current fill type first
435 local currentFillType = self:getUnitFillType(self.trailer.fillUnitIndex);
436 local loadEffect = true
437 if tipAnimation.emitterShape ~= nil and self.referenceParticleSystems[currentFillType] ~= nil then
438 if not tipAnimation.isAdditionalEffect then
439 loadEffect = false
440 end
441
442 if self.currentDischargeParticleSystem == nil then
443 ParticleUtil.setEmitterShape(self.referenceParticleSystems[currentFillType], tipAnimation.emitterShape);
444 self.currentDischargeParticleSystem = self.referenceParticleSystems[currentFillType];
445 local scale = (self.currentDischargeParticleSystem.emitterShapeSize/self.currentDischargeParticleSystem.defaultEmitterShapeSize)*tipAnimation.emitCountScale
446 ParticleUtil.initEmitterScale(self.currentDischargeParticleSystem, scale)
447 end
448 ParticleUtil.setEmittingState(self.currentDischargeParticleSystem, true);
449
450 if tipAnimation.fillVolumeHeightIndex ~= nil then
451 local currentScale = 1
452 if self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex] ~= nil and self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex].currentMinHeight ~= nil then
453 currentScale = self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex].currentMinHeight;
454 end
455 ParticleUtil.setEmitCountScale(self.currentDischargeParticleSystem, currentScale);
456 end
457 end
458
459 if loadEffect and tipAnimation.tipEffect ~= nil then
460 self.currentTipEffects = tipAnimation.tipEffect;
461 EffectManager:setFillType(self.currentTipEffects, currentFillType)
462 EffectManager:startEffects(self.currentTipEffects);
463 end
464 else
465 if self.currentDischargeParticleSystem ~= nil then
466 ParticleUtil.setEmittingState(self.currentDischargeParticleSystem, false);
467 self.currentDischargeParticleSystem = nil;
468 end
469 end
470 end
471 end
472
473 if self.currentTipEffects ~= nil and self.currentTipEffects[1] ~= nil then
474 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
475 if self.currentTipReferencePointIndex ~= nil then
476 local tipAnimation = self.tipAnimations[self.currentTipReferencePointIndex];
477 if tipAnimation ~= nil then
478 if self:getUnitFillLevel(self.trailer.fillUnitIndex) > 0 then
479 if tipAnimation.dischargeEndTime > tipAnimation.dischargeStartTime then
480 local m = self:getCapacity()/((tipAnimation.dischargeEndTime-tipAnimation.dischargeStartTime)/tipAnimation.unloadingSpeedScale);
481 if self:getUnitFillLevel(self.trailer.fillUnitIndex) <= m * self.currentTipEffects[1].planeFadeTime then
482 EffectManager:stopEffects(self.currentTipEffects);
483 self.currentTipEffects = nil;
484 end
485 end
486 end
487 end
488 end
489 end
490 end
491 end
492end

updateTipping

Description
Update tipping
Definition
updateTipping(float dt)
Arguments
floatdttime since last call in ms
Code
497function Trailer:updateTipping(dt)
498
499 if not self.isServer then
500 return;
501 end
502 if self:getCanTip() then
503 local currentFillType = self:getUnitFillType(self.trailer.fillUnitIndex);
504
505 local fillDelta = self:getUnitFillLevel(self.trailer.fillUnitIndex);
506
507 if fillDelta == 0 and self.trailer.stopTipToGroundIfEmpty then
508 self:onEndTip();
509 return;
510 end
511
512 if self.currentTipReferencePointIndex ~= nil then
513 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
514 if animation ~= nil and animation.dischargeEndTime > animation.dischargeStartTime then
515 if self:getCurrentTipAnimationTime() >= animation.dischargeStartTime then
516 local m = self:getCapacity()/((animation.dischargeEndTime-animation.dischargeStartTime)/animation.unloadingSpeedScale);
517 fillDelta = math.min(fillDelta, m * dt);
518 else
519 fillDelta = 0;
520 end
521 end
522 end
523 if self:getUnitFillLevel(self.trailer.fillUnitIndex) < 0.01 and self.tipState == Trailer.TIPSTATE_OPEN then
524 if self:getEndTipIfEmpty() then
525 self:onEndTip();
526 end
527 end
528
529 fillDelta = fillDelta + self.remainingFillDelta;
530 local dropped = 0;
531 local remaining = 0;
532
533 if fillDelta > 0.01 then
534 local curFill = self:getUnitFillLevel(self.trailer.fillUnitIndex);
535 local infos = self.fillVolumeUnloadInfos[self.tipAnimations[self.currentTipReferencePointIndex].fillVolumeUnloadInfoIndex];
536 local tipRefPoint = self.tipReferencePoints[self.currentTipReferencePointIndex]
537
538 if self.currentTipTrigger ~= nil then
539 if self.currentTipTrigger.addFillLevelFromTool ~= nil then
540 dropped = self.currentTipTrigger:addFillLevelFromTool(self, fillDelta*self.fillLevelToTippedFillLevel, currentFillType) / self.fillLevelToTippedFillLevel;
541 if dropped == 0 and self.currentTipTrigger ~= nil then
542 local text = self.currentTipTrigger:getNotAllowedText(self, TipTrigger.TOOL_TYPE_TRAILER);
543 if text ~= nil and text ~= "" then
544 self.tipErrorMessageTime = 3000;
545 self.tipErrorMessage = text;
546 end
547 self:onEndTip();
548 end
549 end
550 else
551 local sx,sy,sz = localToWorld(tipRefPoint.node, math.max(0.3, 0.5*tipRefPoint.width), 0, tipRefPoint.zOffset);
552 local ex,ey,ez = localToWorld(tipRefPoint.node, -math.max(0.3, 0.5*tipRefPoint.width), 0, tipRefPoint.zOffset);
553
554 local tipOcclusionAreas = {};
555 for _,area in pairs(self.tipOcclusionAreas) do
556 table.insert(tipOcclusionAreas, area);
557 end
558
559 local droppedToLine, lineOffset = TipUtil.tipToGroundAroundLine(self, fillDelta, currentFillType, sx,sy,sz, ex,ey,ez, 0, nil, self.trailerLineOffset, false, tipOcclusionAreas, true);
560 self.trailerLineOffset = lineOffset;
561 dropped = droppedToLine;
562 remaining = fillDelta - droppedToLine;
563 end
564
565 self.remainingFillDelta = math.min(remaining, 2*TipUtil.getMinValidLiterValue(currentFillType));
566 if self.remainingFillDelta > TipUtil.getMinValidLiterValue(currentFillType) then
567 tipRefPoint.zOffset = math.min(2.0, tipRefPoint.zOffset + 0.1);
568 end
569
570 if dropped < 0.01 then
571 self.couldNotDropTimer = self.couldNotDropTimer + dt;
572 if self.couldNotDropTimer > self.couldNotDropTimerThreshold then
573 if curFill < TipUtil.getMinValidLiterValue(currentFillType) then
574 self:setUnitFillLevel(self.trailer.fillUnitIndex, 0, FillUtil.FILLTYPE_UNKNOWN, true);
575 else
576 self:onEndTip();
577 end
578 end
579 else
580 self:setUnitFillLevel(self.trailer.fillUnitIndex, curFill - dropped, currentFillType, false, infos);
581 self.couldNotDropTimer = 0;
582 end
583
584 end
585 else
586 self:onEndTip();
587 end
588end

draw

Description
Called on draw
Definition
draw()
Code
592function Trailer:draw()
593 if self.isClient then
594 if self:getIsActiveForInput(true) then
595 if self.numTipReferencePoints > 0 then
596 -- shown by drivable.lua
597 --if self == g_currentMission.trailerInTipRange then
598 -- g_currentMission:addHelpButtonText(g_i18n:getText("action_tip"), InputBinding.TOGGLE_TIPSTATE, nil, GS_PRIO_NORMAL);
599 --end
600 if self ~= g_currentMission.trailerInTipRange then
601 if self:getCanTipToGround() and (self.tipState == Trailer.TIPSTATE_CLOSED or self.tipState == Trailer.TIPSTATE_CLOSING) then
602 g_currentMission:addHelpButtonText(g_i18n:getText("action_startTipToGround"), InputBinding.TOGGLE_TIPSTATE_GROUND, nil, GS_PRIO_NORMAL);
603 elseif self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
604 g_currentMission:addHelpButtonText(g_i18n:getText("action_stopTipToGround"), InputBinding.TOGGLE_TIPSTATE_GROUND, nil, GS_PRIO_NORMAL);
605 end
606 end
607 if self.numTipReferencePoints > 1 then
608 if self.tipState == Trailer.TIPSTATE_CLOSED then
609 local animation = self.tipAnimations[self.preferedTipReferencePointIndex]
610 g_currentMission:addHelpButtonText(string.format(g_i18n:getText("action_toggleTipSide"), animation.name), InputBinding.TOGGLE_TIPSIDE, nil, GS_PRIO_NORMAL);
611 end
612 end
613 end
614 end
615 end
616end

togglePreferedTipReferencePointIndex

Description
Toggle preferred tip reference point
Definition
togglePreferedTipReferencePointIndex(integer index, boolean noEventSend)
Arguments
integerindexindex of new preferred tip reference point
booleannoEventSendno event send
Code
622function Trailer:togglePreferedTipReferencePointIndex(index, noEventSend)
623 if self.preferedTipReferencePointIndex == index then
624 return;
625 end
626 self.preferedTipReferencePointIndex = index;
627end

toggleTipState

Description
Toggle tip state
Definition
toggleTipState(table tipTrigger, integer tipReferencePointIndex)
Arguments
tabletipTriggertip trigger
integertipReferencePointIndexindex of tip reference point
Code
633function Trailer:toggleTipState(tipTrigger, tipReferencePointIndex)
634 if self.tipState == Trailer.TIPSTATE_CLOSED or self.tipState == Trailer.TIPSTATE_CLOSING then
635 -- check if we can use prefered tip ref index for tipping at a trigger
636 if tipTrigger ~= nil and g_currentMission:getIsTrailerInTipRange(self, tipTrigger, self.preferedTipReferencePointIndex) then
637 self:onStartTip(tipTrigger, self.preferedTipReferencePointIndex, false);
638 else
639 self:onStartTip(tipTrigger, tipReferencePointIndex, false);
640 end
641 else
642 self:onEndTip();
643 end
644end

onStartTip

Description
Called on start tipping
Definition
onStartTip(table tipTrigger, integer tipReferencePointIndex, boolean noEventSend)
Arguments
tabletipTriggertip trigger
integertipReferencePointIndexindex of tip reference point
booleannoEventSendno event send
Code
651function Trailer:onStartTip(tipTrigger, tipReferencePointIndex, noEventSend)
652 -- we can not start tipping while we are tipping with another animation
653 if self.isServer then
654 if self.currentTipReferencePointIndex ~= nil and self.currentTipReferencePointIndex ~= tipReferencePointIndex then
655 return;
656 end
657 end
658
659 if noEventSend == nil or noEventSend == false then
660 if g_server ~= nil then
661 g_server:broadcastEvent(TrailerToggleTipEvent:new(self, true, tipTrigger, tipReferencePointIndex), nil, nil, self);
662 else
663 g_client:getServerConnection():sendEvent(TrailerToggleTipEvent:new(self, true, tipTrigger, tipReferencePointIndex));
664 end
665 end
666
667 self.currentTipTrigger = tipTrigger;
668 if self.isServer then
669 self.remainingFillDelta = 0;
670 self.tipReferencePoints[tipReferencePointIndex].zOffset = 0;
671 end
672 self:enableTipAnimation(tipReferencePointIndex, 1);
673 self.currentTipReferencePointIndex = tipReferencePointIndex;
674 self.tipState = Trailer.TIPSTATE_OPENING;
675
676 local tipAnimation = self.tipAnimations[tipReferencePointIndex];
677 if tipAnimation ~= nil then
678 if tipAnimation.fillVolumeHeightIndex ~= nil then
679 if self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex] ~= nil then
680 self.fillVolumeHeights[tipAnimation.fillVolumeHeightIndex].volumeHeightIsDirty = true;
681 end
682 end
683 end
684
685 self.couldNotDropTimer = 0;
686end

onEndTip

Description
Called at the end of tipping
Definition
onEndTip(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
691function Trailer:onEndTip(noEventSend)
692 if noEventSend == nil or noEventSend == false then
693 if g_server ~= nil then
694 g_server:broadcastEvent(TrailerToggleTipEvent:new(self, false), nil, nil, self);
695 else
696 g_client:getServerConnection():sendEvent(TrailerToggleTipEvent:new(self, false));
697 end
698 end
699 if self.currentTipReferencePointIndex ~= nil then
700 self:enableTipAnimation(self.currentTipReferencePointIndex, -1);
701 end
702
703 if self.isServer then
704 self.currentTipTrigger = nil;
705 end
706
707 if self.isClient then
708 SoundUtil.stopSample(self.sampleFillSound);
709 end
710
711 self.tipState = Trailer.TIPSTATE_CLOSING;
712end

setFillLevel

Description
Set fill level (filling all fill units that allow given fill type)
Definition
setFillLevel(float filllevel, integer fillType, boolean force, table fillInfo)
Arguments
floatfilllevelnew fill level
integerfillTypefill type
booleanforceforce action
tablefillInfofill info for fill volume
Code
720function Trailer:setFillLevel(fillLevel, fillType, force, fillInfos)
721
722 if self.isClient then
723 -- disable particle system if we switch the type or if the trailer is empty
724 local currentFillType = self:getUnitFillType(self.trailer.fillUnitIndex);
725 if (currentFillType ~= fillType or fillLevel <= 0) and self.currentTipReferencePointIndex ~= nil then
726 if self.currentDischargeParticleSystem ~= nil then
727 ParticleUtil.setEmittingState(self.currentDischargeParticleSystem, false);
728 self.currentDischargeParticleSystem = nil;
729 end
730 end
731 end
732end

onDeactivateSounds

Description
Called on deactivating sounds
Definition
onDeactivateSounds()
Code
739function Trailer:onDeactivateSounds()
740 if self.isClient then
741 SoundUtil.stopSample(self.sampleFillSound, true);
742 end
743end

getCanTipToGround

Description
Returns if can be tipped to ground
Definition
getCanTipToGround()
Return Values
booleancanTipToGroundcan tip to ground
Code
752function Trailer:getCanTipToGround()
753 if TipUtil.isValid() then
754 local currentFillType = self:getUnitFillType(self.trailer.fillUnitIndex);
755 if currentFillType == FillUtil.FILLTYPE_UNKNOWN then
756 return true;
757 end
758 return TipUtil.getCanTipToGround(currentFillType);
759 else
760 return false;
761 end
762end

getEndTipIfEmpty

Description
Returns if tipping should be ended on empty
Definition
getEndTipIfEmpty()
Return Values
booleanendTipend tip if empty
Code
767function Trailer:getEndTipIfEmpty()
768 return self.currentTipTrigger ~= nil;
769end

enableTipAnimation

Description
Enable tip animation
Definition
enableTipAnimation(integer tipReferencePointIndex, integer direction, float animTime)
Arguments
integertipReferencePointIndexindex of used tip reference point
integerdirectiondirection to use
floatanimTimenew animation time
Code
776function Trailer:enableTipAnimation(tipReferencePointIndex, direction, animTime)
777 if self.currentTipReferencePointIndex ~= tipReferencePointIndex then
778 self:disableCurrentTipAnimation(0);
779 end
780
781 self.currentTipReferencePointIndex = tipReferencePointIndex;
782
783 local animation = self.tipAnimations[tipReferencePointIndex];
784
785 if animation ~= nil then
786 local speedScale = animation.animationOpenSpeedScale;
787 if direction < 0 then
788 speedScale = animation.animationCloseSpeedScale;
789 end
790 if animation.animationName ~= nil then
791 self:playAnimation(animation.animationName, speedScale, self:getAnimationTime(animation.animationName), true);
792 if animTime ~= nil then
793 self:setRealAnimationTime(animation.animationName, animTime);
794 end
795 elseif animation.animationCharSet ~= nil then
796 enableAnimTrack(animation.animationCharSet, 0);
797 setAnimTrackSpeedScale(animation.animationCharSet, 0, speedScale);
798 if animTime ~= nil then
799 setAnimTrackTime(animation.animationCharSet, 0, animTime);
800 else
801 if direction > 0 then
802 if getAnimTrackTime(animation.animationCharSet, 0) < 0 then
803 setAnimTrackTime(animation.animationCharSet, 0, 0);
804 end
805 else
806 if getAnimTrackTime(animation.animationCharSet, 0) > animation.animationDuration then
807 setAnimTrackTime(animation.animationCharSet, 0, animation.animationDuration);
808 end
809 end
810 end
811 end
812
813 if animation.doorAnimationName ~= nil then
814 local speedScale = animation.doorAnimationOpenSpeedScale;
815 if direction < 0 then
816 speedScale = animation.doorAnimationCloseSpeedScale;
817 end
818 self:playAnimation(animation.doorAnimationName, speedScale, self:getAnimationTime(animation.doorAnimationName), true);
819 end
820
821 if direction <= 0 then
822 if self.currentTipEffects ~= nil then
823 EffectManager:stopEffects(self.currentTipEffects);
824 self.currentTipEffects = nil;
825 end
826 end
827 end
828end

disableCurrentTipAnimation

Description
Disable current tip animation
Definition
disableCurrentTipAnimation(float animTime)
Arguments
floatanimTimeanim time to set on animation
Code
833function Trailer:disableCurrentTipAnimation(animTime)
834 if self.currentTipReferencePointIndex ~= nil then
835 if self.currentDischargeParticleSystem ~= nil then
836 ParticleUtil.setEmittingState(self.currentDischargeParticleSystem, false);
837 self.currentDischargeParticleSystem = nil;
838 end
839 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
840 if animation ~= nil then
841 if animation.animationName ~= nil then
842 if animTime ~= nil then
843 self:setRealAnimationTime(animation.animationName, math.min(animTime, animation.animationDuration));
844 end
845 self:stopAnimation(animation.animationName, true);
846 elseif animation.animationCharSet ~= nil then
847 if animTime ~= nil then
848 enableAnimTrack(animation.animationCharSet, 0);
849 setAnimTrackTime(animation.animationCharSet, 0, animTime, true);
850 end
851 disableAnimTrack(animation.animationCharSet, 0);
852 end
853 end
854 self.currentTipReferencePointIndex = nil;
855 end
856end

setCurrentTipAnimationTime

Description
Set time of current tip animation
Definition
setCurrentTipAnimationTime(float animTime)
Arguments
floatanimTimenew animation time
Code
861function Trailer:setCurrentTipAnimationTime(animTime)
862 if self.currentTipReferencePointIndex ~= nil then
863 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
864 if animation ~= nil then
865 if animation.animationName ~= nil then
866 self:setRealAnimationTime(animation.animationName, math.min(animTime, animation.animationDuration));
867 elseif animation.animationCharSet ~= nil then
868 setAnimTrackTime(animation.animationCharSet, 0, animTime);
869 end
870 end
871 end
872end

getCurrentTipAnimationTime

Description
Returns current tip animation time
Definition
getCurrentTipAnimationTime()
Return Values
floatanimTimetime of current tip animation
Code
877function Trailer:getCurrentTipAnimationTime()
878 if self.currentTipReferencePointIndex ~= nil then
879 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
880 if animation ~= nil then
881 local maxTime = 0;
882 if animation.animationName ~= nil then
883 maxTime = math.max(maxTime, self:getRealAnimationTime(animation.animationName));
884 elseif animation.animationCharSet ~= nil then
885 maxTime = math.max(maxTime, getAnimTrackTime(animation.animationCharSet, 0));
886 end
887 if animation.doorAnimationName ~= nil then
888 maxTime = math.max(maxTime, self:getRealAnimationTime(animation.doorAnimationName));
889 end
890 return maxTime;
891 end
892 end
893 return 0;
894end

getCurrentTipAnimationDuration

Description
Returns duration of current tip animation
Definition
getCurrentTipAnimationDuration()
Return Values
floatdurationduration of current tip animation
Code
899function Trailer:getCurrentTipAnimationDuration()
900 if self.currentTipReferencePointIndex ~= nil then
901 local animation = self.tipAnimations[self.currentTipReferencePointIndex];
902 if animation ~= nil then
903 return animation.animationDuration;
904 end
905 end
906 return 0;
907end

getIsToggleCoverAllowed

Description
Returns if toggle cover is allowed
Definition
getIsToggleCoverAllowed(boolean isCoverOpen)
Arguments
booleanisCoverOpenis cover open
Return Values
booleanallowallows cover toggle
Code
913function Trailer:getIsToggleCoverAllowed(superFunc, isCoverOpen)
914 if not isCoverOpen and self.tipState ~= Trailer.TIPSTATE_CLOSED then
915 return false;
916 end
917
918 if superFunc ~= nil then
919 return superFunc(self, isCoverOpen);
920 end
921
922 return true;
923end

getTipScrollerSpeed

Description
Returns tip scroller speed
Definition
getTipScrollerSpeed()
Return Values
floattipScrollerSpeedtip scroller speed
Code
928function Trailer:getTipScrollerSpeed()
929 if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then
930 return 1.0;
931 else
932 return 0;
933 end
934end

isDetachAllowed

Description
Returns true if detach is allowed
Definition
isDetachAllowed()
Return Values
booleandetachAlloweddetach is allowed
Code
939function Trailer:isDetachAllowed(superFunc)
940 if self.tipState == Trailer.TIPSTATE_CLOSED then
941 return superFunc(self);
942 else
943 return false;
944 end
945end

getDischargeInfos

Description
Returns discharge infos by index
Definition
getDischargeInfos(integer index)
Arguments
integerindexindex
Return Values
tableinfosdischarge infos
Code
951function Trailer:getDischargeInfos(superFunc, index)
952 local infos;
953 if self.tipAnimations[index] ~= nil then
954 if self.tipAnimations[index].fillVolumeDischargeInfoIndex ~= nil then
955 if self.fillVolumeDischargeInfos[self.tipAnimations[index].fillVolumeDischargeInfoIndex] ~= nil then
956 infos = self.fillVolumeDischargeInfos[self.tipAnimations[index].fillVolumeDischargeInfoIndex];
957 end
958 end
959 if infos == nil then
960 if self.tipAnimations[index].fillVolumeUnloadInfoIndex ~= nil then
961 if self.fillVolumeUnloadInfos[self.tipAnimations[index].fillVolumeUnloadInfoIndex] ~= nil then
962 infos = self.fillVolumeUnloadInfos[self.tipAnimations[index].fillVolumeUnloadInfoIndex];
963 end
964 end
965 end
966 end
967 return infos;
968end

getAllowFillFromAir

Description
Returns if fill from air is allowed
Definition
getAllowFillFromAir()
Return Values
booleanisAllowedfill from air is allowed
Code
973function Trailer:getAllowFillFromAir(superFunc)
974 if self.tipState ~= Trailer.TIPSTATE_CLOSED then
975 return false;
976 end
977
978 if superFunc ~= nil then
979 return superFunc(self);
980 end
981
982 return true
983end