Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Windrower |
3 | -- Class for all windrowers |
4 | -- Note: the animation is not perfectly synchronized, thus do not attach any gameplay relevant stuff to the animation |
5 | -- |
6 | -- @author Stefan Geiger |
7 | -- @date 11/05/08 |
8 | -- |
9 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
10 | |
11 | source("dataS/scripts/vehicles/specializations/SetTurnedOnEvent.lua"); |
12 | source("dataS/scripts/vehicles/specializations/WindrowAreaEvent.lua"); |
13 | |
14 | Windrower = {}; |
15 | |
16 | function Windrower.initSpecialization() |
17 | WorkArea.registerAreaType("windrower"); |
18 | WorkArea.registerAreaType("windrowerDrop"); |
19 | end; |
20 | |
21 | function Windrower.prerequisitesPresent(specializations) |
22 | return SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations); |
23 | end; |
24 | |
25 | function Windrower:preLoad(xmlFile) |
26 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Windrower.loadWorkAreaFromXML); |
27 | end |
28 | |
29 | function Windrower:load(xmlFile) |
30 | |
31 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Windrower.doCheckSpeedLimit); |
32 | |
33 | self.animation = {}; |
34 | self.animation.animCharSet = 0; |
35 | self.animationEnabled = false; |
36 | |
37 | self.animation.alpha = 0; |
38 | self.animation.fadeTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.animation#fadeTime"), 0)*1000; |
39 | local rootNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.animation#rootNode")); |
40 | |
41 | if rootNode ~= nil then |
42 | self.animation.animCharSet = getAnimCharacterSet(rootNode); |
43 | if self.animation.animCharSet ~= 0 then |
44 | self.animation.clip = getAnimClipIndex(self.animation.animCharSet, getXMLString(xmlFile, "vehicle.animation#animationClip")); |
45 | if self.animation.clip >= 0 then |
46 | assignAnimTrackClip(self.animation.animCharSet, 0, self.animation.clip); |
47 | self.animation.speedScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.animation#speedScale"), 1); |
48 | setAnimTrackSpeedScale(self.animation.animCharSet, self.animation.clip, self.animation.speedScale); |
49 | setAnimTrackLoopState(self.animation.animCharSet, 0, true); |
50 | setAnimTrackTime(self.animation.animCharSet, 0, 0); |
51 | end; |
52 | else |
53 | print("Warning: No windrower animation set to node ("..getXMLString(xmlFile, "vehicle.animation#rootNode")..")!"); |
54 | end; |
55 | end; |
56 | |
57 | local numWindrowerDropAreas = table.getn(self:getTypedWorkAreas(WorkArea.AREATYPE_WINDROWERDROP)); |
58 | if numWindrowerDropAreas == 0 then |
59 | print("Warning: No drop areas specified in '"..self.configFileName.."'"); |
60 | else |
61 | if numWindrowerDropAreas ~= 1 and numWindrowerDropAreas ~= table.getn(self:getTypedWorkAreas(WorkArea.AREATYPE_WINDROWER)) then |
62 | print("Warning: Number of cutting areas and drop areas should be equal in '"..self.configFileName.."'"); |
63 | end; |
64 | end; |
65 | |
66 | self.windrowerParticleSystems = {}; |
67 | local i=0; |
68 | while true do |
69 | local keyPS = string.format("vehicle.windrowerParticleSystems.windrowerParticleSystem(%d)", i); |
70 | local t = getXMLString(xmlFile, keyPS .. "#type"); |
71 | if t == nil then |
72 | break; |
73 | end; |
74 | local fillType = Fillable.fillTypeNameToInt[t]; |
75 | local fruitType = FruitUtil.fillTypeToFruitType[fillType]; |
76 | if fruitType ~= nil then |
77 | local particleSystem = {}; |
78 | particleSystem.ps = {}; |
79 | |
80 | local particleNode = Utils.loadParticleSystem(xmlFile, particleSystem.ps, keyPS, self.components, false, nil, self.baseDirectory); |
81 | |
82 | particleSystem.disableTime = 0; |
83 | particleSystem.isEnabled = false; |
84 | |
85 | particleSystem.fruitType = fruitType; |
86 | particleSystem.workAreaIndex = Utils.getNoNil(getXMLInt(xmlFile, keyPS.."#workAreaIndex"),0)+1; |
87 | |
88 | table.insert(self.windrowerParticleSystems, particleSystem); |
89 | end |
90 | i=i+1; |
91 | end; |
92 | |
93 | self.accumulatedFruitType = FruitUtil.FRUITTYPE_UNKNOWN; |
94 | |
95 | if self.isClient then |
96 | self.sampleWindrower = Utils.loadSample(xmlFile, {}, "vehicle.windrowerSound", nil, self.baseDirectory); |
97 | end; |
98 | |
99 | self.doTurnOn = false; |
100 | self.isWindrowerSpeedLimitActive = false; |
101 | |
102 | self.windrowerGroundFlag = self:getNextDirtyFlag(); |
103 | end; |
104 | |
105 | function Windrower:delete() |
106 | if self.isClient then |
107 | Utils.deleteSample(self.sampleWindrower); |
108 | end; |
109 | for _,v in pairs(self.windrowerParticleSystems) do |
110 | Utils.deleteParticleSystem(v.ps); |
111 | end; |
112 | end; |
113 | |
114 | function Windrower:mouseEvent(posX, posY, isDown, isUp, button) |
115 | end; |
116 | |
117 | function Windrower:keyEvent(unicode, sym, modifier, isDown) |
118 | end; |
119 | |
120 | function Windrower:readStream(streamId, connection) |
121 | for k,v in ipairs(self.windrowerParticleSystems) do |
122 | local enabled = streamReadBool(streamId); |
123 | Utils.setEmittingState(v.ps, enabled); |
124 | end; |
125 | end; |
126 | |
127 | function Windrower:writeStream(streamId, connection) |
128 | for k,v in ipairs(self.windrowerParticleSystems) do |
129 | streamWriteBool(streamId, v.isEnabled); |
130 | end; |
131 | end; |
132 | |
133 | function Windrower:readUpdateStream(streamId, timestamp, connection) |
134 | if connection:getIsServer() then |
135 | local hasUpdate = streamReadBool(streamId); |
136 | if hasUpdate then |
137 | for k,v in ipairs(self.windrowerParticleSystems) do |
138 | local enabled = streamReadBool(streamId); |
139 | Utils.setEmittingState(v.ps, enabled); |
140 | end; |
141 | end; |
142 | end; |
143 | end; |
144 | |
145 | function Windrower:writeUpdateStream(streamId, connection, dirtyMask) |
146 | if not connection:getIsServer() then |
147 | if bitAND(dirtyMask, self.windrowerGroundFlag) ~= 0 then |
148 | streamWriteBool(streamId, true); |
149 | for k,v in ipairs(self.windrowerParticleSystems) do |
150 | streamWriteBool(streamId, v.isEnabled); |
151 | end; |
152 | else |
153 | streamWriteBool(streamId, false); |
154 | end; |
155 | end; |
156 | end; |
157 | |
158 | function Windrower:update(dt) |
159 | end; |
160 | |
161 | function Windrower:updateTick(dt) |
162 | self.isWindrowerSpeedLimitActive = false; |
163 | if self:getIsActive() then |
164 | if self:getIsTurnedOn() then |
165 | local hasGroundContact, typedWorkAreas = self:getIsTypedWorkAreaActive(WorkArea.AREATYPE_WINDROWER); |
166 | self.hasGroundContact = hasGroundContact; |
167 | |
168 | if hasGroundContact then |
169 | self.isWindrowerSpeedLimitActive = true; |
170 | if self.isServer then |
171 | |
172 | local workAreasSend = {}; |
173 | local typedWorkAreasDrop = self:getTypedWorkAreas(WorkArea.AREATYPE_WINDROWERDROP); |
174 | for k, workArea in pairs(typedWorkAreas) do |
175 | if self:getIsWorkAreaActive(workArea) then |
176 | local x,y,z = getWorldTranslation(workArea.start); |
177 | local x1,y1,z1 = getWorldTranslation(workArea.width); |
178 | local x2,y2,z2 = getWorldTranslation(workArea.height); |
179 | |
180 | local dropArea = typedWorkAreasDrop[workArea.dropAreaIndex]; |
181 | local dx,dy,dz = getWorldTranslation(dropArea.start); |
182 | local dx1,dy1,dz1 = getWorldTranslation(dropArea.width); |
183 | local dx2,dy2,dz2 = getWorldTranslation(dropArea.height); |
184 | |
185 | table.insert(workAreasSend, {x,z, x1,z1, x2,z2, dx,dz, dx1,dz1, dx2,dz2, 0, k}); |
186 | end; |
187 | end; |
188 | |
189 | if table.getn(typedWorkAreas) > 0 then |
190 | local workAreasRet, fruitType, bitType = WindrowAreaEvent.runLocally(workAreasSend, self.accumulatedWorkAreaValues, self.accumulatedFruitType); |
191 | |
192 | if table.getn(workAreasRet) > 0 then |
193 | self.accumulatedFruitType = fruitType; |
194 | g_server:broadcastEvent(WindrowAreaEvent:new(workAreasRet, fruitType, bitType)); |
195 | |
196 | if self:getLastSpeed(true) > 0.5 then |
197 | for i=1, table.getn(workAreasRet) do |
198 | if workAreasRet[i][13] > 0 then |
199 | local workArea = typedWorkAreas[workAreasRet[i][14]]; |
200 | for _,v in pairs(self.windrowerParticleSystems) do |
201 | if v.ps ~= nil and v.workAreaIndex == workAreasRet[i][14] and v.fruitType == self.accumulatedFruitType then |
202 | v.disableTime = g_currentMission.time + 300; |
203 | if not v.isEnabled then |
204 | v.isEnabled = true; |
205 | self:raiseDirtyFlags(self.windrowerGroundFlag); |
206 | if self.isClient then |
207 | Utils.setEmittingState(v.ps, true); |
208 | end; |
209 | end; |
210 | end; |
211 | end; |
212 | end; |
213 | end; |
214 | end; |
215 | |
216 | end; |
217 | end; |
218 | end; |
219 | end; |
220 | if self.isClient and self:getIsActiveForSound() then |
221 | Utils.playSample(self.sampleWindrower, 0, 0, nil); |
222 | end; |
223 | |
224 | if self.isServer then |
225 | for k,v in pairs(self.windrowerParticleSystems) do |
226 | if g_currentMission.time > v.disableTime then |
227 | if v.isEnabled then |
228 | v.isEnabled = false; |
229 | self:raiseDirtyFlags(self.windrowerGroundFlag); |
230 | if self.isClient then |
231 | Utils.setEmittingState(v.ps, false); |
232 | end; |
233 | end; |
234 | end; |
235 | end; |
236 | end; |
237 | |
238 | end; |
239 | |
240 | end; |
241 | |
242 | if self:getIsTurnedOn() or self.animation.alpha ~= 0 then |
243 | self.animation.alpha = Utils.getMovedLimitedValue(self.animation.alpha, 1, 0, self.animation.fadeTime, dt, not self.doTurnOn); |
244 | |
245 | if self.animation.alpha == 0 then |
246 | if self.animationEnabled and self.animation.animCharSet ~= 0 then |
247 | disableAnimTrack(self.animation.animCharSet, 0); |
248 | self.animationEnabled = false; |
249 | end; |
250 | end; |
251 | |
252 | if self.animationEnabled and self.animation.animCharSet ~= 0 then |
253 | setAnimTrackSpeedScale(self.animation.animCharSet, self.animation.clip, self.animation.speedScale*self.animation.alpha); |
254 | end; |
255 | end; |
256 | end; |
257 | |
258 | function Windrower:draw() |
259 | end; |
260 | |
261 | function Windrower:onDeactivate() |
262 | self.doTurnOn = false; |
263 | end; |
264 | |
265 | function Windrower:onDeactivateSounds() |
266 | if self.isClient then |
267 | Utils.stopSample(self.sampleWindrower, true); |
268 | end; |
269 | end; |
270 | |
271 | function Windrower:onTurnedOn(noEventSend) |
272 | self.doTurnOn = true; |
273 | if not self.animationEnabled and self.animation.animCharSet ~= 0 then |
274 | enableAnimTrack(self.animation.animCharSet, 0); |
275 | self.animationEnabled = true; |
276 | end; |
277 | end; |
278 | |
279 | function Windrower:onTurnedOff(noEventSend) |
280 | self.doTurnOn = false; |
281 | |
282 | if self.accumulatedWorkAreaValues ~= nil then |
283 | for k,_ in pairs(self.accumulatedWorkAreaValues) do |
284 | self.accumulatedWorkAreaValues[k] = 0; |
285 | end |
286 | end; |
287 | |
288 | if self.isClient then |
289 | for k,v in pairs(self.windrowerParticleSystems) do |
290 | v.isEnabled = false; |
291 | Utils.setEmittingState(v.ps, false); |
292 | end; |
293 | end; |
294 | |
295 | Windrower.onDeactivateSounds(self) |
296 | end; |
297 | |
298 | function Windrower:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
299 | local retValue = true; |
300 | if superFunc ~= nil then |
301 | retValue = superFunc(self, workArea, xmlFile, key) |
302 | end |
303 | |
304 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
305 | workArea.type = WorkArea.AREATYPE_WINDROWER; |
306 | end; |
307 | |
308 | if workArea.type == WorkArea.AREATYPE_WINDROWER then |
309 | workArea.windrowerParticleSystemIndex = getXMLInt(xmlFile, key .. "#particleSystemIndex"); |
310 | workArea.dropAreaIndex = Utils.getNoNil(getXMLInt(xmlFile, key .. "#dropAreaIndex"), 0) + 1; |
311 | |
312 | if self.accumulatedWorkAreaValues == nil then |
313 | self.accumulatedWorkAreaValues = {}; |
314 | end; |
315 | self.accumulatedWorkAreaValues[table.getn(self.accumulatedWorkAreaValues)+1] = 0; |
316 | end; |
317 | |
318 | return retValue; |
319 | end; |
320 | |
321 | function Windrower:doCheckSpeedLimit(superFunc) |
322 | local parent = true; |
323 | if superFunc ~= nil then |
324 | parent = superFunc(self); |
325 | end |
326 | |
327 | return parent and self.isWindrowerSpeedLimitActive; |
328 | end; |
329 | |
330 | function Windrower.getDefaultSpeedLimit() |
331 | return 15; |
332 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de