Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Mower |
3 | -- Class for all mowers |
4 | -- |
5 | -- @author Stefan Geiger |
6 | -- @date 11/05/08 |
7 | -- |
8 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
9 | |
10 | source("dataS/scripts/vehicles/specializations/SetTurnedOnEvent.lua"); |
11 | source("dataS/scripts/vehicles/specializations/MowerAreaEvent.lua"); |
12 | source("dataS/scripts/vehicles/specializations/MowerToggleWindrowDropEvent.lua"); |
13 | |
14 | Mower = {}; |
15 | |
16 | function Mower.initSpecialization() |
17 | WorkArea.registerAreaType("mower"); |
18 | WorkArea.registerAreaType("mowerDrop"); |
19 | end; |
20 | |
21 | function Mower.prerequisitesPresent(specializations) |
22 | return SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations); |
23 | end; |
24 | |
25 | function Mower:preLoad(xmlFile) |
26 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Mower.loadWorkAreaFromXML); |
27 | end |
28 | |
29 | function Mower:load(xmlFile) |
30 | |
31 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Mower.doCheckSpeedLimit); |
32 | self.setUseMowerWindrowDropAreas = Mower.setUseMowerWindrowDropAreas; |
33 | self.setEffectEnabled = Mower.setEffectEnabled; |
34 | |
35 | if self.isClient then |
36 | self.sampleMowerStart = Utils.loadSample(xmlFile, {}, "vehicle.mowerStartSound", nil, self.baseDirectory); |
37 | self.sampleMowerStop = Utils.loadSample(xmlFile, {}, "vehicle.mowerStopSound", nil, self.baseDirectory); |
38 | self.sampleMower = Utils.loadSample(xmlFile, {}, "vehicle.mowerSound", nil, self.baseDirectory, self.components[1].node); |
39 | |
40 | self.mowerEffects = {}; |
41 | local i = 0; |
42 | while true do |
43 | local key = string.format("vehicle.mowerEffects.mowerEffect(%d)", i); |
44 | if not hasXMLProperty(xmlFile, key) then |
45 | break; |
46 | end; |
47 | local effect = EffectManager:loadEffect(xmlFile, key, self.components, self); |
48 | if effect ~= nil then |
49 | effect.mowerCutArea = Utils.getNoNil(getXMLInt(xmlFile, key .. "#mowerCutArea"), 0) + 1; |
50 | effect.activeTime = -1; |
51 | effect.isActive = false; |
52 | effect.isActiveSent = false; |
53 | table.insert(self.mowerEffects, effect); |
54 | end; |
55 | i = i + 1; |
56 | end; |
57 | end; |
58 | |
59 | self.mowerTurnedOnRotationNodes = Utils.loadRotationNodes(xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "mower", self.components); |
60 | |
61 | self.mowerTurnOnAnimation = getXMLString(xmlFile, "vehicle.mowerTurnOnAnimation#name"); |
62 | self.mowerTurnOnAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.mowerTurnOnAnimation#turnOnSpeed"), 1); |
63 | self.mowerTurnOffAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.mowerTurnOnAnimation#turnOffSpeed"), -self.mowerTurnOnAnimationSpeed); |
64 | |
65 | self.useMowerWindrowDropAreas = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.mowerToggleWindrowDrop#startEnabled"), table.getn(self:getTypedWorkAreas(WorkArea.AREATYPE_MOWERDROP)) > 0); |
66 | |
67 | local i18n = g_i18n; |
68 | if self.customEnvironment ~= nil then |
69 | i18n = _G[self.customEnvironment].g_i18n; |
70 | end |
71 | |
72 | self.mowerToggleWindrowDropEnableText = getXMLString(xmlFile, "vehicle.mowerToggleWindrowDrop#enableText"); |
73 | self.mowerToggleWindrowDropDisableText = getXMLString(xmlFile, "vehicle.mowerToggleWindrowDrop#disableText"); |
74 | if self.mowerToggleWindrowDropEnableText ~= nil then |
75 | self.mowerToggleWindrowDropEnableText = i18n:getText(self.mowerToggleWindrowDropEnableText); |
76 | end |
77 | if self.mowerToggleWindrowDropDisableText ~= nil then |
78 | self.mowerToggleWindrowDropDisableText = i18n:getText(self.mowerToggleWindrowDropDisableText); |
79 | end |
80 | |
81 | self.mowerToggleWindrowDropAnimation = getXMLString(xmlFile, "vehicle.mowerToggleWindrowDrop#animationName"); |
82 | self.mowerEnableWindrowDropAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.mowerToggleWindrowDrop#animationEnableSpeed"), 1); |
83 | self.mowerDisableWindrowDropAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.mowerToggleWindrowDrop#animationDisableSpeed"), -self.mowerEnableWindrowDropAnimationSpeed); |
84 | |
85 | self.mowerPickupFillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.mowerCutAreas#pickupFillScale"), 1); |
86 | |
87 | local cutAreas = self:getTypedWorkAreas(WorkArea.AREATYPE_MOWER); |
88 | local dropAreas = self:getTypedWorkAreas(WorkArea.AREATYPE_MOWERDROP); |
89 | for _, workArea in pairs(cutAreas) do |
90 | if workArea.dropAreaIndex ~= nil and dropAreas[workArea.dropAreaIndex] == nil then |
91 | workArea.dropAreaIndex = nil; |
92 | else |
93 | dropAreas[workArea.dropAreaIndex].cutArea = workArea; |
94 | end; |
95 | end; |
96 | |
97 | self.isMowerSpeedLimitActive = false; |
98 | |
99 | self.mowerDirtyFlag = self:getNextDirtyFlag(); |
100 | end; |
101 | |
102 | function Mower:delete() |
103 | if self.isClient then |
104 | for _, effect in pairs(self.mowerEffects) do |
105 | EffectManager:deleteEffect(effect); |
106 | end; |
107 | Utils.deleteSample(self.sampleMowerStart); |
108 | Utils.deleteSample(self.sampleMowerStop); |
109 | Utils.deleteSample(self.sampleMower); |
110 | end; |
111 | end; |
112 | |
113 | function Mower:readStream(streamId, connection) |
114 | if self.mowerToggleWindrowDropEnableText ~= nil and self.mowerToggleWindrowDropDisableText ~= nil then |
115 | local useMowerWindrowDropAreas = streamReadBool(streamId); |
116 | self:setUseMowerWindrowDropAreas(useMowerWindrowDropAreas, true); |
117 | end |
118 | end; |
119 | |
120 | function Mower:writeStream(streamId, connection) |
121 | if self.mowerToggleWindrowDropEnableText ~= nil and self.mowerToggleWindrowDropDisableText ~= nil then |
122 | streamWriteBool(streamId, self.useMowerWindrowDropAreas); |
123 | end |
124 | end; |
125 | |
126 | function Mower:readUpdateStream(streamId, timestamp, connection) |
127 | if connection:getIsServer() then |
128 | if table.getn(self.mowerEffects) > 0 then |
129 | if streamReadBool(streamId) then |
130 | for _, effect in pairs(self.mowerEffects) do |
131 | self:setEffectEnabled(effect, streamReadBool(streamId)); |
132 | end; |
133 | end; |
134 | end; |
135 | end; |
136 | end; |
137 | |
138 | function Mower:writeUpdateStream(streamId, connection, dirtyMask) |
139 | if not connection:getIsServer() then |
140 | if table.getn(self.mowerEffects) > 0 then |
141 | if streamWriteBool(streamId, bitAND(dirtyMask, self.mowerDirtyFlag) ~= 0) then |
142 | for _, effect in pairs(self.mowerEffects) do |
143 | streamWriteBool(streamId, effect.isActiveSent); |
144 | end; |
145 | end; |
146 | end; |
147 | end; |
148 | end; |
149 | |
150 | function Mower:mouseEvent(posX, posY, isDown, isUp, button) |
151 | end; |
152 | |
153 | function Mower:keyEvent(unicode, sym, modifier, isDown) |
154 | end; |
155 | |
156 | function Mower:update(dt) |
157 | if self:getIsActive() then |
158 | if self:getIsActiveForInput() then |
159 | if self.mowerToggleWindrowDropEnableText ~= nil and self.mowerToggleWindrowDropDisableText ~= nil then |
160 | if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then |
161 | self:setUseMowerWindrowDropAreas(not self.useMowerWindrowDropAreas); |
162 | end; |
163 | end |
164 | end; |
165 | end |
166 | if self.isClient then |
167 | Utils.updateRotationNodes(self, self.mowerTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn()); |
168 | end; |
169 | end; |
170 | |
171 | function Mower:updateTick(dt) |
172 | self.isMowerSpeedLimitActive = false; |
173 | if self:getIsActive() then |
174 | if self:getIsTurnedOn() then |
175 | local hasGroundContact, typedWorkAreas = self:getIsTypedWorkAreaActive(WorkArea.AREATYPE_MOWER); |
176 | if hasGroundContact then |
177 | self.isMowerSpeedLimitActive = true; |
178 | if self.isServer then |
179 | local numAreasSend = 0; |
180 | local numDropAreas = 0; |
181 | local areasSend = self.mowerCutAreasSend; |
182 | local dropAreas = self:getTypedWorkAreas(WorkArea.AREATYPE_MOWERDROP); |
183 | for _,workArea in pairs(typedWorkAreas) do |
184 | if self:getIsWorkAreaActive(workArea) then |
185 | numAreasSend = numAreasSend + 1; |
186 | areasSend[numAreasSend].x,_,areasSend[numAreasSend].z = getWorldTranslation(workArea.start); |
187 | areasSend[numAreasSend].x1,_,areasSend[numAreasSend].z1 = getWorldTranslation(workArea.width); |
188 | areasSend[numAreasSend].x2,_,areasSend[numAreasSend].z2 = getWorldTranslation(workArea.height); |
189 | areasSend[numAreasSend].dropWindrow = workArea.dropWindrow; |
190 | areasSend[numAreasSend].dropArea = workArea.dropAreaIndex; |
191 | if self.useMowerWindrowDropAreas then |
192 | areasSend[numAreasSend].dropWindrow = true; |
193 | else |
194 | areasSend[numAreasSend].dropArea = nil; |
195 | end |
196 | end |
197 | end |
198 | |
199 | for k, dropArea in pairs(dropAreas) do |
200 | numDropAreas = numDropAreas + 1; |
201 | dropArea.x, _,dropArea.z = getWorldTranslation(dropArea.start); |
202 | dropArea.x1,_,dropArea.z1 = getWorldTranslation(dropArea.width); |
203 | dropArea.x2,_,dropArea.z2 = getWorldTranslation(dropArea.height); |
204 | dropArea.dropAreaId = k; |
205 | end |
206 | |
207 | if numAreasSend > 0 then |
208 | local numAreasUsed, numDropAreasUsed, pickedUpWindrow = MowerAreaEvent.runLocally(areasSend, numAreasSend, dropAreas, numDropAreas); |
209 | for _, effect in pairs(self.mowerEffects) do |
210 | local hasContact = false; |
211 | if dropAreas[effect.mowerCutArea] ~= nil and dropAreas[effect.mowerCutArea].cutArea ~= nil then |
212 | local dropArea = dropAreas[effect.mowerCutArea]; |
213 | hasContact = self:getIsWorkAreaActive(dropArea.cutArea); |
214 | --local active = dropArea.valueAccum > 0 and hasContact and self:getLastSpeed() > 1 and numDropAreasUsed > 0; |
215 | local active = dropArea.value > 0 and hasContact and self:getLastSpeed() > 1 and numDropAreasUsed > 0; |
216 | if active then |
217 | effect.activeTime = 250; |
218 | else |
219 | effect.activeTime = effect.activeTime - dt; |
220 | if effect.activeTime > 0 then |
221 | active = true; |
222 | end; |
223 | end; |
224 | if active then |
225 | self:setEffectEnabled(effect, true); |
226 | else |
227 | self:setEffectEnabled(effect, false); |
228 | end; |
229 | end; |
230 | end; |
231 | |
232 | if numAreasUsed > 0 or numDropAreasUsed > 0 then |
233 | g_server:broadcastEvent(MowerAreaEvent:new(areasSend, numAreasUsed, dropAreas, numDropAreas, numDropAreasUsed)); |
234 | end |
235 | if pickedUpWindrow > 0 and self.allowFillType ~= nil and self:allowFillType(Fillable.FILLTYPE_GRASS_WINDROW) then |
236 | local fillDelta = pickedUpWindrow * FruitUtil.getFillTypeLiterPerSqm(Fillable.FILLTYPE_GRASS_WINDROW, 1) * self.mowerPickupFillScale; |
237 | self:setFillLevel(self:getFillLevel(Fillable.FILLTYPE_GRASS_WINDROW)+fillDelta, Fillable.FILLTYPE_GRASS_WINDROW); |
238 | end |
239 | end; |
240 | |
241 | local isDirty = false; |
242 | for _, effect in pairs(self.mowerEffects) do |
243 | if effect.isActive ~= effect.isActiveSent then |
244 | isDirty = true; |
245 | end; |
246 | effect.isActiveSent = effect.isActive; |
247 | end; |
248 | if isDirty then |
249 | self:raiseDirtyFlags(self.mowerDirtyFlag); |
250 | end; |
251 | end; |
252 | else |
253 | for _, effect in pairs(self.mowerEffects) do |
254 | self:setEffectEnabled(effect, false); |
255 | end; |
256 | end; |
257 | |
258 | if self.isClient then |
259 | if self:getIsActiveForSound() then |
260 | if not Utils.isSamplePlaying(self.sampleMowerStart, 1.8*dt) then |
261 | Utils.playSample(self.sampleMower, 0, 0, nil); |
262 | end |
263 | Utils.stop3DSample(self.sampleMower); |
264 | else |
265 | Utils.play3DSample(self.sampleMower); |
266 | end |
267 | end; |
268 | end; |
269 | end; |
270 | end; |
271 | |
272 | function Mower:setEffectEnabled(effect, isActive) |
273 | effect.isActive = isActive; |
274 | if isActive then |
275 | EffectManager:startEffect(effect); |
276 | else |
277 | EffectManager:stopEffect(effect); |
278 | end; |
279 | end; |
280 | |
281 | function Mower:draw() |
282 | if self.isClient then |
283 | if self:getIsActiveForInput(true) then |
284 | if self.mowerToggleWindrowDropEnableText ~= nil and self.mowerToggleWindrowDropDisableText ~= nil then |
285 | if self.useMowerWindrowDropAreas then |
286 | g_currentMission:addHelpButtonText(string.format(self.mowerToggleWindrowDropDisableText, self.typeDesc), InputBinding.IMPLEMENT_EXTRA3); |
287 | else |
288 | g_currentMission:addHelpButtonText(string.format(self.mowerToggleWindrowDropEnableText, self.typeDesc), InputBinding.IMPLEMENT_EXTRA3); |
289 | end; |
290 | end |
291 | end |
292 | end; |
293 | end; |
294 | |
295 | function Mower:onDeactivateSounds() |
296 | if self.isClient then |
297 | for _, effect in pairs(self.mowerEffects) do |
298 | self:setEffectEnabled(effect, false); |
299 | end; |
300 | Utils.stopSample(self.sampleMower, true); |
301 | Utils.stopSample(self.sampleMowerStart, true); |
302 | Utils.stop3DSample(self.sampleMower); |
303 | end; |
304 | end; |
305 | |
306 | function Mower:onTurnedOn(noEventSend) |
307 | if self.isClient then |
308 | Mower.onDeactivateSounds(self); |
309 | Utils.stopSample(self.sampleMowerStop, true); |
310 | if self:getIsActiveForSound() then |
311 | Utils.playSample(self.sampleMowerStart, 1, 0, nil); |
312 | end; |
313 | if self.mowerTurnOnAnimation ~= nil and self.playAnimation ~= nil then |
314 | self:playAnimation(self.mowerTurnOnAnimation, self.mowerTurnOnAnimationSpeed, nil, true); |
315 | end; |
316 | end; |
317 | end; |
318 | |
319 | function Mower:onTurnedOff(noEventSend) |
320 | if self.isClient then |
321 | Mower.onDeactivateSounds(self); |
322 | Utils.stopSample(self.sampleMowerStart, true); |
323 | if self:getIsActiveForSound() then |
324 | Utils.playSample(self.sampleMowerStop, 1, 0, nil); |
325 | end; |
326 | if self.mowerTurnOnAnimation ~= nil and self.playAnimation ~= nil then |
327 | self:playAnimation(self.mowerTurnOnAnimation, self.mowerTurnOffAnimationSpeed, nil, true); |
328 | end; |
329 | for _, effect in pairs(self.mowerEffects) do |
330 | self:setEffectEnabled(effect, false); |
331 | end; |
332 | end; |
333 | end; |
334 | |
335 | function Mower:doCheckSpeedLimit(superFunc) |
336 | local parent = true; |
337 | if superFunc ~= nil then |
338 | parent = superFunc(self); |
339 | end |
340 | |
341 | return parent and self.isMowerSpeedLimitActive; |
342 | end; |
343 | |
344 | function Mower:setUseMowerWindrowDropAreas(useMowerWindrowDropAreas, noEventSend) |
345 | if useMowerWindrowDropAreas ~= self.useMowerWindrowDropAreas then |
346 | MowerToggleWindrowDropEvent.sendEvent(self, useMowerWindrowDropAreas, noEventSend) |
347 | self.useMowerWindrowDropAreas = useMowerWindrowDropAreas; |
348 | |
349 | if self.mowerToggleWindrowDropAnimation ~= nil and self.playAnimation ~= nil then |
350 | local speed = self.mowerEnableWindrowDropAnimationSpeed; |
351 | if not useMowerWindrowDropAreas then |
352 | speed = self.mowerDisableWindrowDropAnimationSpeed; |
353 | end |
354 | self:playAnimation(self.mowerToggleWindrowDropAnimation, speed, nil, true); |
355 | end; |
356 | end |
357 | end; |
358 | |
359 | function Mower:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
360 | local retValue = true; |
361 | if superFunc ~= nil then |
362 | retValue = superFunc(self, workArea, xmlFile, key) |
363 | end |
364 | |
365 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
366 | workArea.type = WorkArea.AREATYPE_MOWER; |
367 | end; |
368 | |
369 | if workArea.type == WorkArea.AREATYPE_MOWER then |
370 | workArea.dropWindrow = Utils.getNoNil(getXMLBool(xmlFile, key .. "#dropWindrow"), true); |
371 | workArea.dropAreaIndex = Utils.getNoNil(getXMLInt(xmlFile, key .. "#dropArea"), 0) + 1; |
372 | |
373 | if self.mowerCutAreasSend == nil then |
374 | self.mowerCutAreasSend = {}; |
375 | end; |
376 | table.insert(self.mowerCutAreasSend, {}); |
377 | end; |
378 | |
379 | if workArea.type == WorkArea.AREATYPE_MOWERDROP then |
380 | workArea.value = 0; |
381 | workArea.valueAccum = 0; |
382 | end; |
383 | |
384 | return retValue; |
385 | end; |
386 | |
387 | function Mower.getDefaultSpeedLimit() |
388 | return 20; |
389 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de