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 | |
3 | SiloTrigger = {}; |
4 | |
5 | local SiloTrigger_mt = Class(SiloTrigger, Object); |
6 | |
7 | InitStaticObjectClass(SiloTrigger, "SiloTrigger", ObjectIds.OBJECT_SILO_TRIGGER); |
8 | |
9 | function SiloTrigger:onCreate(id) |
10 | local trigger = SiloTrigger:new(g_server ~= nil, g_client ~= nil); |
11 | local index = g_currentMission:addOnCreateLoadedObject(trigger); |
12 | trigger:load(id); |
13 | trigger:register(true); |
14 | --[[if g_client ~= nil then |
15 | -- request server id from server |
16 | g_client:getServerConnection():sendEvent(OnCreateLoadedObjectEvent:new(index)); |
17 | end;]] |
18 | end; |
19 | |
20 | function SiloTrigger:new(isServer, isClient) |
21 | local self = Object:new(isServer, isClient, SiloTrigger_mt); |
22 | self.rootNode = 0; |
23 | |
24 | self.siloTriggerDirtyFlag = self:getNextDirtyFlag(); |
25 | return self; |
26 | end; |
27 | |
28 | |
29 | function SiloTrigger:load(id) |
30 | |
31 | self.rootNode = id; |
32 | if self.isServer then |
33 | self.triggerIds = {}; |
34 | |
35 | local triggerRoot = Utils.indexToObject(id, getUserAttribute(id, "triggerIndex")); |
36 | if triggerRoot == nil then |
37 | triggerRoot = id; |
38 | end |
39 | |
40 | table.insert(self.triggerIds, triggerRoot); |
41 | addTrigger(triggerRoot, "triggerCallback", self); |
42 | for i=1, 3 do |
43 | local child = getChildAt(triggerRoot, i-1); |
44 | table.insert(self.triggerIds, child); |
45 | addTrigger(child, "triggerCallback", self); |
46 | end; |
47 | end; |
48 | |
49 | self.fillVolumeDischargeInfo = {}; |
50 | self.fillVolumeDischargeInfo.name = "fillVolumeDischargeInfo"; |
51 | self.fillVolumeDischargeInfo.node = Utils.indexToObject(id, getUserAttribute(id, "fillVolumeDischargeNode")); |
52 | self.fillVolumeDischargeInfo.width = Utils.getNoNil( getUserAttribute(id, "fillVolumeDischargeNodeWidth"), 0.5 ); |
53 | self.fillVolumeDischargeInfo.length = Utils.getNoNil( getUserAttribute(id, "fillVolumeDischargeNodeLength"), 0.5 ); |
54 | |
55 | self.fillType = Fillable.FILLTYPE_UNKNOWN; |
56 | local fruitType = getUserAttribute(id, "fruitType"); |
57 | if fruitType ~= nil then |
58 | local desc = FruitUtil.fruitTypes[fruitType]; |
59 | if desc ~= nil then |
60 | self.fillType = FruitUtil.fruitTypeToFillType[desc.index]; |
61 | end; |
62 | elseif Utils.getNoNil(getUserAttribute(id, "fillTypeWheat"), false) then |
63 | self.fillType = Fillable.FILLTYPE_WHEAT; |
64 | elseif Utils.getNoNil(getUserAttribute(id, "fillTypeGrass"), false) then |
65 | self.fillType = Fillable.FILLTYPE_GRASS; |
66 | end; |
67 | |
68 | self.isEnabled = true; |
69 | |
70 | self.fill = 0; |
71 | self.siloTrailer = nil; |
72 | self.fillDone = false; |
73 | |
74 | self.isFilling = false; |
75 | |
76 | self.fillLitersPerSecond = Utils.getNoNil(tonumber(getUserAttribute(id, "fillLitersPerSecond")), 1500); |
77 | |
78 | if self.isClient then |
79 | local dropParticleSystem = Utils.indexToObject(id, getUserAttribute(id, "dropParticleSystemIndex")); |
80 | if dropParticleSystem ~= nil then |
81 | self.dropParticleSystems = {}; |
82 | Utils.loadParticleSystemFromNode(dropParticleSystem, self.dropParticleSystems, false, true); |
83 | end |
84 | local lyingParticleSystem = Utils.indexToObject(id, getUserAttribute(id, "lyingParticleSystemIndex")); |
85 | if lyingParticleSystem ~= nil then |
86 | self.lyingParticleSystems = {}; |
87 | Utils.loadParticleSystemFromNode(lyingParticleSystem, self.lyingParticleSystems, true, true); |
88 | |
89 | for _, ps in ipairs(self.lyingParticleSystems) do |
90 | local lifespan = getParticleSystemLifespan(ps.geometry); |
91 | addParticleSystemSimulationTime(ps.geometry, lifespan); |
92 | end |
93 | |
94 | Utils.setParticleSystemTimeScale(self.lyingParticleSystems, 0); |
95 | end |
96 | |
97 | if self.dropParticleSystems == nil then |
98 | local particleSystem = Utils.getNoNil(getUserAttribute(id, "particleSystem"), "wheatParticleSystemLong"); |
99 | |
100 | local x,y,z = getTranslation(id); |
101 | |
102 | local particlePositionStr = getUserAttribute(id, "particlePosition"); |
103 | if particlePositionStr ~= nil then |
104 | local psx,psy,psz = Utils.getVectorFromString(particlePositionStr); |
105 | if psx ~= nil and psy ~= nil and psz ~= nil then |
106 | x = x + psx; |
107 | y = y + psy; |
108 | z = z + psz; |
109 | end; |
110 | end; |
111 | |
112 | local psData = {}; |
113 | psData.psFile = getUserAttribute(id, "particleSystemFilename"); |
114 | if psData.psFile == nil then |
115 | local particleSystem = Utils.getNoNil(getUserAttribute(id, "particleSystem"), "wheatParticleSystemLong"); |
116 | psData.psFile = "$data/vehicles/particleSystems/" .. particleSystem .. ".i3d"; |
117 | end |
118 | psData.posX, psData.posY, psData.posZ = x,y,z; |
119 | psData.forceNoWorldSpace = true; |
120 | |
121 | self.dropParticleSystems = {}; |
122 | Utils.loadParticleSystemFromData(psData, self.dropParticleSystems, nil, false, nil, g_currentMission.baseDirectory, getParent(id)); |
123 | end |
124 | |
125 | local fillSoundFilename = getUserAttribute(id, "fillSoundFilename"); |
126 | if fillSoundFilename == nil then |
127 | fillSoundFilename = "$data/maps/sounds/siloFillSound.wav"; |
128 | end |
129 | if fillSoundFilename ~= "" and fillSoundFilename ~= "none" then |
130 | fillSoundFilename = Utils.getFilename(fillSoundFilename, g_currentMission.baseDirectory); |
131 | self.siloFillSound = createAudioSource("siloFillSound", fillSoundFilename, 30, 10, 1, 0); |
132 | link(id, self.siloFillSound); |
133 | setVisibility(self.siloFillSound, false); |
134 | end |
135 | |
136 | |
137 | self.scroller = Utils.indexToObject(id, getUserAttribute(id, "scrollerIndex")); |
138 | if self.scroller ~= nil then |
139 | self.scrollerShaderParameterName = Utils.getNoNil(getUserAttribute(self.scroller, "shaderParameterName"), "uvScrollSpeed"); |
140 | local scrollerScrollSpeed = getUserAttribute(self.scroller, "scrollSpeed"); |
141 | if scrollerScrollSpeed ~= nil then |
142 | self.scrollerSpeedX, self.scrollerSpeedY = Utils.getVectorFromString(scrollerScrollSpeed); |
143 | end |
144 | if self.scrollerSpeedX == nil then |
145 | self.scrollerSpeedX = 0; |
146 | end |
147 | if self.scrollerSpeedY == nil then |
148 | self.scrollerSpeedY = -0.75; |
149 | end |
150 | setShaderParameter(self.scroller, self.scrollerShaderParameterName, 0, 0, 0, 0, false); |
151 | end |
152 | end; |
153 | end; |
154 | |
155 | function SiloTrigger:delete() |
156 | |
157 | if self.isClient then |
158 | if self.siloFillSound ~= nil then |
159 | delete(self.siloFillSound); |
160 | end |
161 | |
162 | Utils.deleteParticleSystem(self.dropParticleSystems); |
163 | Utils.deleteParticleSystem(self.lyingParticleSystems); |
164 | end |
165 | |
166 | if self.isServer then |
167 | for i=1, table.getn(self.triggerIds) do |
168 | removeTrigger(self.triggerIds[i]); |
169 | end |
170 | end |
171 | |
172 | delete(self.rootNode); |
173 | SiloTrigger:superClass().delete(self); |
174 | end; |
175 | |
176 | function SiloTrigger:readStream(streamId, connection) |
177 | SiloTrigger:superClass().readStream(self, streamId); |
178 | if connection:getIsServer() then |
179 | local isFilling = streamReadBool(streamId); |
180 | if isFilling then |
181 | self:startFill(); |
182 | else |
183 | self:stopFill(); |
184 | end; |
185 | end; |
186 | end; |
187 | |
188 | function SiloTrigger:writeStream(streamId, connection) |
189 | SiloTrigger:superClass().writeStream(self, streamId); |
190 | if not connection:getIsServer() then |
191 | streamWriteBool(streamId, self.isFilling); |
192 | end; |
193 | end; |
194 | |
195 | function SiloTrigger:readUpdateStream(streamId, timestamp, connection) |
196 | SiloTrigger:superClass().readUpdateStream(self, streamId, timestamp, connection); |
197 | if connection:getIsServer() then |
198 | local isFilling = streamReadBool(streamId); |
199 | if isFilling then |
200 | self:startFill(); |
201 | else |
202 | self:stopFill(); |
203 | end; |
204 | end; |
205 | end; |
206 | |
207 | function SiloTrigger:writeUpdateStream(streamId, connection, dirtyMask) |
208 | SiloTrigger:superClass().writeUpdateStream(self, streamId, connection, dirtyMask); |
209 | if not connection:getIsServer() then |
210 | -- note: do not test for the dirty flags, since we only send 1 bit |
211 | streamWriteBool(streamId, self.isFilling); |
212 | end; |
213 | end; |
214 | |
215 | function SiloTrigger:update(dt) |
216 | |
217 | if self.isServer then |
218 | local trailer = self.siloTrailer; |
219 | if self.fill >= 4 and trailer ~= nil and not self.fillDone then |
220 | trailer:resetFillLevelIfNeeded(self.fillType); |
221 | local fillLevel = trailer:getFillLevel(self.fillType); |
222 | local siloAmount = g_currentMission:getSiloAmount(self.fillType); |
223 | if siloAmount > 0 and trailer:allowFillType(self.fillType, false) then |
224 | local deltaFillLevel = math.min(self.fillLitersPerSecond*0.001*dt, siloAmount); |
225 | local x,y,z = getWorldTranslation(self.fillVolumeDischargeInfo.node); |
226 | local d1x,d1y,d1z = localDirectionToWorld(self.fillVolumeDischargeInfo.node, self.fillVolumeDischargeInfo.width,0,0); |
227 | local d2x,d2y,d2z = localDirectionToWorld(self.fillVolumeDischargeInfo.node, 0,0,self.fillVolumeDischargeInfo.length); |
228 | local fillSourceStruct = {x=x,y=y,z=z, d1x=d1x,d1y=d1y,d1z=d1z, d2x=d2x,d2y=d2y,d2z=d2z}; |
229 | trailer:setFillLevel(fillLevel+deltaFillLevel, self.fillType, false, fillSourceStruct); |
230 | local newFillLevel = trailer:getFillLevel(self.fillType); |
231 | |
232 | if fillLevel ~= newFillLevel then |
233 | g_currentMission:setSiloAmount(self.fillType, math.max(siloAmount-(newFillLevel-fillLevel), 0)); |
234 | self:startFill(); |
235 | else |
236 | self.fillDone = true; -- trailer is full |
237 | self:stopFill(); |
238 | end; |
239 | |
240 | else |
241 | self.fillDone = true; -- silo is empty or trailer does not support fill type |
242 | self:stopFill(); |
243 | end; |
244 | end; |
245 | end; |
246 | |
247 | end; |
248 | |
249 | function SiloTrigger:stopFill() |
250 | --print("stopFill"); |
251 | if self.isFilling then |
252 | self.isFilling = false; |
253 | if self.isServer then |
254 | self:raiseDirtyFlags(self.siloTriggerDirtyFlag); |
255 | end; |
256 | if self.isClient then |
257 | if self.siloFillSoundEnabled then |
258 | setVisibility(self.siloFillSound, false); |
259 | self.siloFillSoundEnabled = false; |
260 | end; |
261 | Utils.setEmittingState(self.dropParticleSystems, false); |
262 | Utils.setParticleSystemTimeScale(self.lyingParticleSystems, 0); |
263 | if self.scroller ~= nil then |
264 | setShaderParameter(self.scroller, self.scrollerShaderParameterName, 0, 0, 0, 0, false); |
265 | end |
266 | end; |
267 | end; |
268 | end; |
269 | |
270 | function SiloTrigger:startFill() |
271 | --print("startFill"); |
272 | if not self.isFilling then |
273 | self.isFilling = true; |
274 | if self.isServer then |
275 | self:raiseDirtyFlags(self.siloTriggerDirtyFlag); |
276 | end; |
277 | if self.isClient then |
278 | if not self.siloFillSoundEnabled and self.siloFillSound ~= nil then |
279 | setVisibility(self.siloFillSound, true); |
280 | self.siloFillSoundEnabled = true; |
281 | end; |
282 | Utils.setEmittingState(self.dropParticleSystems, true); |
283 | Utils.setParticleSystemTimeScale(self.lyingParticleSystems, 1.0); |
284 | |
285 | if self.scroller ~= nil then |
286 | setShaderParameter(self.scroller, self.scrollerShaderParameterName, self.scrollerSpeedX, self.scrollerSpeedY, 0, 0, false); |
287 | end |
288 | end; |
289 | end; |
290 | end; |
291 | |
292 | function SiloTrigger:triggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId) |
293 | |
294 | assert(self.isServer); |
295 | if self.isEnabled then |
296 | local trailer = g_currentMission.objectToTrailer[otherShapeId]; |
297 | if trailer ~= nil and trailer:allowFillType(self.fillType, false) and trailer.getAllowFillFromAir ~= nil and trailer:getAllowFillFromAir() then |
298 | if onEnter then |
299 | self.fill = self.fill+1; |
300 | self.siloTrailer = trailer; |
301 | self.fillDone = false; |
302 | elseif onLeave then |
303 | self.fill = math.max(self.fill-1, 0); |
304 | self.siloTrailer = nil; |
305 | self.fillDone = false; |
306 | self:stopFill(); |
307 | end; |
308 | end; |
309 | end; |
310 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de