Sprache Deutsch Language English

Script Dokumentation LS 2015 - MultiSiloTrigger (Patch 1.3)

Script Dokumentation Übersicht

scripts/triggers/MultiSiloTrigger.lua

Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
2
3MultiSiloTrigger = {};
4
5source("dataS/scripts/triggers/MultiSiloTriggerSetIsFillingEvent.lua");
6
7local MultiSiloTrigger_mt = Class(MultiSiloTrigger, Object);
8
9InitStaticObjectClass(MultiSiloTrigger, "MultiSiloTrigger", ObjectIds.OBJECT_MULTI_SILO_TRIGGER);
10
11function MultiSiloTrigger:onCreate(id)
12 local trigger = MultiSiloTrigger:new(g_server ~= nil, g_client ~= nil);
13 local index = g_currentMission:addOnCreateLoadedObject(trigger);
14 trigger:load(id);
15 trigger:register(true);
16end;
17
18function MultiSiloTrigger:new(isServer, isClient)
19 local self = Object:new(isServer, isClient, MultiSiloTrigger_mt);
20 self.rootNode = 0;
21 self.multiSiloTriggerDirtyFlag = self:getNextDirtyFlag();
22 return self;
23end;
24
25
26function MultiSiloTrigger:load(id)
27 self.rootNode = id;
28 if self.isServer then
29 self.triggerIds = {};
30
31 local triggerRoot = Utils.indexToObject(id, getUserAttribute(id, "triggerIndex"));
32 if triggerRoot == nil then
33 triggerRoot = id;
34 end
35
36 table.insert(self.triggerIds, triggerRoot);
37 addTrigger(triggerRoot, "triggerCallback", self);
38 for i=1, 3 do
39 local child = getChildAt(triggerRoot, i-1);
40 table.insert(self.triggerIds, child);
41 addTrigger(child, "triggerCallback", self);
42 end;
43 end;
44
45 self.fillVolumeDischargeInfo = {};
46 self.fillVolumeDischargeInfo.name = "fillVolumeDischargeInfo";
47 self.fillVolumeDischargeInfo.node = Utils.indexToObject(id, getUserAttribute(id, "fillVolumeDischargeNode"));
48 self.fillVolumeDischargeInfo.width = Utils.getNoNil( getUserAttribute(id, "fillVolumeDischargeNodeWidth"), 0.5 );
49 self.fillVolumeDischargeInfo.length = Utils.getNoNil( getUserAttribute(id, "fillVolumeDischargeNodeLength"), 0.5 );
50
51 self.fillTypes = {};
52 self.selectedFillType = nil;
53 local fillTypesStr = getUserAttribute(id, "fillTypes");
54 if fillTypesStr ~= nil then
55 local fillTypes = Utils.splitString(" ", fillTypesStr);
56 for k,v in pairs(fillTypes) do
57 local fillType = Fillable.fillTypeNameToInt[v];
58 if fillType ~= nil then
59 if self.selectedFillType == nil then
60 self.selectedFillType = fillType;
61 end;
62 self.fillTypes[fillType] = fillType;
63 end;
64 end;
65 end;
66
67 if self.isClient then
68 local dropParticleSystem = Utils.indexToObject(id, getUserAttribute(id, "dropParticleSystemIndex"));
69 if dropParticleSystem ~= nil then
70 self.dropParticleSystems = {};
71 Utils.loadParticleSystemFromNode(dropParticleSystem, self.dropParticleSystems, false, true);
72 end
73 local lyingParticleSystem = Utils.indexToObject(id, getUserAttribute(id, "lyingParticleSystemIndex"));
74 if lyingParticleSystem ~= nil then
75 self.lyingParticleSystems = {};
76 Utils.loadParticleSystemFromNode(lyingParticleSystem, self.lyingParticleSystems, true, true);
77
78 for _, ps in ipairs(self.lyingParticleSystems) do
79 local lifespan = getParticleSystemLifespan(ps.geometry);
80 addParticleSystemSimulationTime(ps.geometry, lifespan);
81 end
82
83 Utils.setParticleSystemTimeScale(self.lyingParticleSystems, 0);
84 end
85
86 if self.dropParticleSystems == nil then
87 self.dropEffect = EffectManager:loadFromNode(id, self);
88
89 if self.dropEffect == nil then
90 local particleSystem = Utils.getNoNil(getUserAttribute(id, "particleSystem"), "unloadingSiloParticles");
91
92 local x,y,z = getTranslation(id);
93
94 local particlePositionStr = getUserAttribute(id, "particlePosition");
95 if particlePositionStr ~= nil then
96 local psx,psy,psz = Utils.getVectorFromString(particlePositionStr);
97 if psx ~= nil and psy ~= nil and psz ~= nil then
98 x = x + psx;
99 y = y + psy;
100 z = z + psz;
101 end;
102 end;
103
104 local psData = {};
105 psData.psFile = getUserAttribute(id, "particleSystemFilename");
106 if psData.psFile == nil then
107 local particleSystem = Utils.getNoNil(getUserAttribute(id, "particleSystem"), "unloadingSiloParticles");
108 psData.psFile = "$data/vehicles/particleAnimation/shared/" .. particleSystem .. ".i3d";
109 end
110 psData.posX, psData.posY, psData.posZ = x,y,z;
111 psData.forceNoWorldSpace = true;
112
113 self.dropParticleSystems = {};
114 Utils.loadParticleSystemFromData(psData, self.dropParticleSystems, nil, false, nil, g_currentMission.baseDirectory, getParent(id));
115 end;
116 end
117
118 local fillSoundFilename = getUserAttribute(id, "fillSoundFilename");
119 if fillSoundFilename == nil then
120 fillSoundFilename = "$data/maps/sounds/siloFillSound.wav";
121 end
122 if fillSoundFilename ~= "" and fillSoundFilename ~= "none" then
123 fillSoundFilename = Utils.getFilename(fillSoundFilename, g_currentMission.baseDirectory);
124 self.siloFillSound = createAudioSource("siloFillSound", fillSoundFilename, 30, 10, 1, 0);
125 link(id, self.siloFillSound);
126 setVisibility(self.siloFillSound, false);
127 end
128
129
130 self.scroller = Utils.indexToObject(id, getUserAttribute(id, "scrollerIndex"));
131 if self.scroller ~= nil then
132 self.scrollerShaderParameterName = Utils.getNoNil(getUserAttribute(self.scroller, "shaderParameterName"), "uvScrollSpeed");
133 local scrollerScrollSpeed = getUserAttribute(self.scroller, "scrollSpeed");
134 if scrollerScrollSpeed ~= nil then
135 self.scrollerSpeedX, self.scrollerSpeedY = Utils.getVectorFromString(scrollerScrollSpeed);
136 end
137 if self.scrollerSpeedX == nil then
138 self.scrollerSpeedX = 0;
139 end
140 if self.scrollerSpeedY == nil then
141 self.scrollerSpeedY = -0.75;
142 end
143 setShaderParameter(self.scroller, self.scrollerShaderParameterName, 0, 0, 0, 0, false);
144 end
145 end;
146
147 self.fillLitersPerSecond = Utils.getNoNil(tonumber(getUserAttribute(id, "fillLitersPerSecond")), 1500);
148
149 self.stationName = g_i18n:getText(Utils.getNoNil(getUserAttribute(id, "stationName"), "StationFarmSilo"));
150 self.isEnabled = true;
151 self.fill = 0;
152 self.siloTrailer = nil;
153 self.siloTrailerSend = nil;
154 self.isFilling = false;
155
156 self.startFillText = g_i18n:getText("siloStartFilling");
157 self.stopFillText = g_i18n:getText("siloStopFilling");
158
159 self.activateText = self.startFillText;
160 self.objectActivated = false;
161end;
162
163function MultiSiloTrigger:delete()
164
165 if self.isClient then
166 if self.siloFillSound ~= nil then
167 delete(self.siloFillSound);
168 end
169 EffectManager:deleteEffect(self.dropEffect);
170 Utils.deleteParticleSystem(self.dropParticleSystems);
171 Utils.deleteParticleSystem(self.lyingParticleSystems);
172 end
173
174 if self.isServer then
175 for i=1, table.getn(self.triggerIds) do
176 removeTrigger(self.triggerIds[i]);
177 end
178 end
179
180 delete(self.rootNode);
181 MultiSiloTrigger:superClass().delete(self);
182end;
183
184function MultiSiloTrigger:readStream(streamId, connection)
185 MultiSiloTrigger:superClass().readStream(self, streamId);
186 if connection:getIsServer() then
187 local isFilling = streamReadBool(streamId);
188 if isFilling then
189 local fillType = streamReadUIntN(streamId, Fillable.sendNumBits);
190 self:setIsFilling(true, fillType, true);
191 else
192 self:setIsFilling(false, Fillable.FILLTYPE_UNKNOWN, true);
193 end;
194 local siloTrailer = streamReadInt32(streamId);
195 if siloTrailer ~= 0 then
196 self.siloTrailer = networkGetObject(siloTrailer);
197 else
198 self.siloTrailer = nil;
199 end;
200 end;
201end;
202
203function MultiSiloTrigger:writeStream(streamId, connection)
204 MultiSiloTrigger:superClass().writeStream(self, streamId);
205 if not connection:getIsServer() then
206 streamWriteBool(streamId, self.isFilling);
207 if self.isFilling then
208 streamWriteUIntN(streamId, self.selectedFillType, Fillable.sendNumBits);
209 end;
210 if self.siloTrailerSend ~= nil then
211 streamWriteInt32(streamId, networkGetObjectId(self.object));
212 else
213 streamWriteInt32(streamId, 0);
214 end;
215 end;
216end;
217
218function MultiSiloTrigger:readUpdateStream(streamId, timestamp, connection)
219 MultiSiloTrigger:superClass().readUpdateStream(self, streamId, timestamp, connection);
220 if connection:getIsServer() then
221 if streamReadBool(streamId) then
222 local siloTrailer = streamReadInt32(streamId);
223 if siloTrailer ~= 0 then
224 self.siloTrailer = networkGetObject(siloTrailer);
225 g_currentMission:addActivatableObject(self);
226 else
227 self.siloTrailer = nil;
228 g_currentMission:removeActivatableObject(self);
229 end;
230 end;
231 end;
232end;
233
234function MultiSiloTrigger:writeUpdateStream(streamId, connection, dirtyMask)
235 MultiSiloTrigger:superClass().writeUpdateStream(self, streamId, connection, dirtyMask);
236 if not connection:getIsServer() then
237 if streamWriteBool(streamId, bitAND(dirtyMask, self.multiSiloTriggerDirtyFlag) ~= 0) then
238 if self.siloTrailerSend ~= nil then
239 streamWriteInt32(streamId, networkGetObjectId(self.siloTrailerSend));
240 else
241 streamWriteInt32(streamId, 0);
242 end;
243 end;
244 end;
245end;
246
247function MultiSiloTrigger:update(dt)
248
249 if self.isServer then
250 local trailer = self.siloTrailer;
251 if self.fill >= 4 and trailer ~= nil then
252 if self.isFilling then
253 trailer:resetFillLevelIfNeeded(self.selectedFillType);
254 local fillLevel = trailer:getFillLevel(self.selectedFillType);
255 local siloAmount = g_currentMission:getSiloAmount(self.selectedFillType);
256 if siloAmount > 0 and trailer:allowFillType(self.selectedFillType, false) then
257 local deltaFillLevel = math.min(self.fillLitersPerSecond*0.001*dt, siloAmount);
258 local x,y,z = getWorldTranslation(self.fillVolumeDischargeInfo.node);
259 local d1x,d1y,d1z = localDirectionToWorld(self.fillVolumeDischargeInfo.node, self.fillVolumeDischargeInfo.width,0,0);
260 local d2x,d2y,d2z = localDirectionToWorld(self.fillVolumeDischargeInfo.node, 0,0,self.fillVolumeDischargeInfo.length);
261 local fillSourceStruct = {x=x,y=y,z=z, d1x=d1x,d1y=d1y,d1z=d1z, d2x=d2x,d2y=d2y,d2z=d2z};
262 trailer:setFillLevel(fillLevel+deltaFillLevel, self.selectedFillType, false, fillSourceStruct);
263 local newFillLevel = trailer:getFillLevel(self.selectedFillType);
264
265 if fillLevel ~= newFillLevel then
266 g_currentMission:setSiloAmount(self.selectedFillType, math.max(siloAmount-(newFillLevel-fillLevel), 0));
267 else
268 self:setIsFilling(false, Fillable.FILLTYPE_UNKNOWN);
269 end;
270 else
271 self:setIsFilling(false, Fillable.FILLTYPE_UNKNOWN);
272 end;
273 end;
274 elseif self.isFilling then
275 self:setIsFilling(false, Fillable.FILLTYPE_UNKNOWN);
276 end;
277
278 if self.siloTrailerSend ~= self.siloTrailer then
279 self.siloTrailerSend = self.siloTrailer;
280 self:raiseDirtyFlags(self.multiSiloTriggerDirtyFlag);
281 end;
282
283 end;
284end;
285
286function MultiSiloTrigger:getIsActivatable()
287 if not self.isEnabled then
288 return false;
289 end;
290 if self.isFilling then
291 if self.siloTrailer:getRootAttacherVehicle() == g_currentMission.controlledVehicle then
292 return true;
293 end;
294 else
295 if self.siloTrailer ~= nil then
296 local trailer = self.siloTrailer;
297 if trailer:getRootAttacherVehicle() ~= g_currentMission.controlledVehicle then
298 return false;
299 end;
300 if trailer.fillLevel == 0 then
301 return true;
302 elseif trailer.fillLevel > 0 and self.fillTypes[trailer.currentFillType] ~= nil and trailer.fillLevel < trailer:getCapacity() and g_currentMission:getSiloAmount(trailer.currentFillType) > 0 then
303 return true;
304 end;
305 end;
306 end;
307
308 return false;
309end;
310
311function MultiSiloTrigger:drawActivate()
312 return;
313end;
314
315function MultiSiloTrigger:onActivateObject()
316 if not self.isFilling then
317 if self.siloTrailer ~= nil and self.siloTrailer.fillLevel > 0 then
318 self:setIsFilling(true, self.siloTrailer.currentFillType);
319 else
320 g_multiSiloDialog:setFillTypes(self.fillTypes);
321 g_multiSiloDialog:setTitle(self.stationName);
322 g_multiSiloDialog:setSelectionCallback(self.onFillTypeSelection, self);
323 self.multiSiloDialog = g_gui:showGui("MultiSiloDialog");
324 end;
325 else
326 self:setIsFilling(false, Fillable.FILLTYPE_UNKNOWN);
327 end;
328 g_currentMission:addActivatableObject(self);
329end;
330
331function MultiSiloTrigger:onFillTypeSelection(fillType)
332 if fillType ~= nil then
333 if self.siloTrailer ~= nil then
334 if self:getIsValidTrailer(self.siloTrailer) then
335 self:setIsFilling(true, fillType);
336 end;
337 end;
338 end;
339end;
340
341function MultiSiloTrigger:setIsFilling(isFilling, fillType, noEventSend)
342 MultiSiloTriggerSetIsFillingEvent.sendEvent(self, isFilling, fillType, noEventSend);
343 if isFilling then
344 self:startFill(fillType);
345 else
346 self:stopFill();
347 end;
348end;
349
350function MultiSiloTrigger:stopFill()
351 if self.isFilling then
352 self.isFilling = false;
353 self.activateText = self.startFillText;
354 if self.isClient then
355 if self.siloFillSoundEnabled then
356 setVisibility(self.siloFillSound, false);
357 self.siloFillSoundEnabled = false;
358 end;
359 Utils.setEmittingState(self.dropParticleSystems, false);
360 Utils.setParticleSystemTimeScale(self.lyingParticleSystems, 0);
361 EffectManager:stopEffect(self.dropEffect);
362 if self.scroller ~= nil then
363 setShaderParameter(self.scroller, self.scrollerShaderParameterName, 0, 0, 0, 0, false);
364 end
365 end;
366 end;
367end;
368
369function MultiSiloTrigger:startFill(fillType)
370 if not self.isFilling then
371 self.activateText = self.stopFillText;
372 self.isFilling = true;
373 self.selectedFillType = fillType;
374 if self.isClient then
375 if not self.siloFillSoundEnabled and self.siloFillSound ~= nil then
376 setVisibility(self.siloFillSound, true);
377 self.siloFillSoundEnabled = true;
378 end;
379 Utils.setEmittingState(self.dropParticleSystems, true);
380 Utils.setParticleSystemTimeScale(self.lyingParticleSystems, 1.0);
381 if self.dropEffect ~= nil then
382 self.dropEffect:setFillType(self.selectedFillType);
383 EffectManager:startEffect(self.dropEffect);
384 end;
385
386 if self.scroller ~= nil then
387 setShaderParameter(self.scroller, self.scrollerShaderParameterName, self.scrollerSpeedX, self.scrollerSpeedY, 0, 0, false);
388 end
389 end;
390 end;
391end;
392
393function MultiSiloTrigger:getIsValidTrailer(trailer)
394 for _, fillType in pairs(self.fillTypes) do
395 if trailer:allowFillType(fillType, false) then
396 return true;
397 end;
398 end;
399
400 return false;
401end;
402
403function MultiSiloTrigger:triggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId)
404 assert(self.isServer);
405 if self.isEnabled then
406 local trailer = g_currentMission.objectToTrailer[otherShapeId];
407 if trailer ~= nil then
408 if onEnter then
409 if self:getIsValidTrailer(trailer) and trailer.getAllowFillFromAir ~= nil and trailer:getAllowFillFromAir() then
410 self.fill = self.fill+1;
411 self.siloTrailer = trailer;
412 if self.fill >= 4 then
413 g_currentMission:addActivatableObject(self);
414 end;
415 end;
416 elseif onLeave then
417 self.fill = math.max(self.fill-1, 0);
418 self.siloTrailer = nil;
419 --self:stopFill();
420 self:setIsFilling(false, Fillable.FILLTYPE_UNKNOWN);
421 g_currentMission:removeActivatableObject(self);
422 end;
423 end;
424 end;
425end;
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