Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Sprayer |
3 | -- Class for all sprayers |
4 | -- |
5 | -- @author Stefan Geiger |
6 | -- @date 24/02/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/SprayerAreaEvent.lua"); |
12 | Sprayer = {}; |
13 | |
14 | |
15 | Sprayer.SPRAYTYPE_UNKNOWN = 0; |
16 | Sprayer.NUM_SPRAYTYPES = 0; |
17 | |
18 | Sprayer.sprayTypes = {}; |
19 | Sprayer.sprayTypeIndexToDesc = {}; |
20 | |
21 | Sprayer.sprayTypeToFillType = {}; |
22 | Sprayer.fillTypeToSprayType = {}; |
23 | |
24 | function Sprayer.registerSprayType(name, nameI18N, pricePerLiter, litersPerSqmPerSecond, partOfEconomy, hudOverlayFilename, hudOverlayFilenameSmall, massPerLiter) |
25 | local key = "SPRAYTYPE_"..string.upper(name); |
26 | if Sprayer[key] == nil then |
27 | Sprayer.NUM_SPRAYTYPES = Sprayer.NUM_SPRAYTYPES+1; |
28 | Sprayer[key] = Sprayer.NUM_SPRAYTYPES; |
29 | |
30 | local desc = {name = name, index = Sprayer.NUM_SPRAYTYPES}; |
31 | desc.litersPerSqmPerSecond = litersPerSqmPerSecond; |
32 | desc.massPerLiter = Utils.getNoNil(massPerLiter, 0.0001); |
33 | |
34 | |
35 | Sprayer.sprayTypes[name] = desc; |
36 | Sprayer.sprayTypeIndexToDesc[Sprayer.NUM_SPRAYTYPES] = desc; |
37 | |
38 | local fillType = Fillable.registerFillType(name, nameI18N, pricePerLiter, partOfEconomy, hudOverlayFilename, hudOverlayFilenameSmall, desc.massPerLiter) |
39 | Sprayer.sprayTypeToFillType[Sprayer.NUM_SPRAYTYPES] = fillType; |
40 | Sprayer.fillTypeToSprayType[fillType] = Sprayer.NUM_SPRAYTYPES; |
41 | end |
42 | end |
43 | |
44 | function Sprayer.initSpecialization() |
45 | WorkArea.registerAreaType("sprayer"); |
46 | end |
47 | |
48 | function Sprayer.prerequisitesPresent(specializations) |
49 | return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations); |
50 | end |
51 | |
52 | function Sprayer:preLoad(xmlFile) |
53 | self.supportsFillTriggers = true; |
54 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Sprayer.loadWorkAreaFromXML); |
55 | self.getIsReadyToSpray = Sprayer.getIsReadyToSpray; |
56 | self.getAreEffectsVisible = Sprayer.getAreEffectsVisible; |
57 | self.getLitersPerSecond = Sprayer.getLitersPerSecond; |
58 | end |
59 | |
60 | function Sprayer:load(xmlFile) |
61 | |
62 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Sprayer.doCheckSpeedLimit); |
63 | self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, Sprayer.getIsTurnedOnAllowed); |
64 | self.setJointMoveDown = Utils.appendedFunction(self.setJointMoveDown, Sprayer.setJointMoveDown); |
65 | |
66 | self.isSprayerTank = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.sprayer#isTank"), false); |
67 | self.allowsSpraying = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.sprayer#allowsSpraying"), true); |
68 | self.needsTankActivation = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.sprayer#needsTankActivation"), false); |
69 | self.activateTankOnLowering = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.sprayer#activateTankOnLowering"), false); |
70 | |
71 | self.sprayLitersPerSecond = {}; |
72 | local i=0; |
73 | while true do |
74 | local key = string.format("vehicle.sprayUsages.sprayUsage(%d)", i); |
75 | if not hasXMLProperty(xmlFile, key) then |
76 | break; |
77 | end |
78 | local fillType = getXMLString(xmlFile, key.. "#fillType"); |
79 | local litersPerSecond = getXMLFloat(xmlFile, key.. "#litersPerSecond"); |
80 | if fillType ~= nil and litersPerSecond ~= nil then |
81 | local fillTypeInt = Fillable.fillTypeNameToInt[fillType]; |
82 | if fillTypeInt ~= nil then |
83 | self.sprayLitersPerSecond[fillTypeInt] = litersPerSecond; |
84 | if self.defaultSprayLitersPerSecond == nil then |
85 | self.defaultSprayLitersPerSecond = litersPerSecond; |
86 | end |
87 | else |
88 | print("Warning: Invalid spray usage fill type '"..fillType.."' in '" .. self.configFileName.. "'"); |
89 | end |
90 | end |
91 | i = i+1; |
92 | end |
93 | if self.defaultSprayLitersPerSecond == nil then |
94 | if self.allowsSpraying then |
95 | print("Warning: No spray usage specified for '" .. self.configFileName.. "'. This sprayer will not use any spray."); |
96 | end |
97 | self.defaultSprayLitersPerSecond = 0; |
98 | end |
99 | |
100 | self.lastSprayValveUpdateFoldTime = nil; |
101 | self.sprayValves = {}; |
102 | self.sprayParticleSystems = {}; |
103 | self.sprayerEffects = {}; |
104 | |
105 | if self.isClient then |
106 | local psFile = getXMLString(xmlFile, "vehicle.sprayParticleSystem#file"); |
107 | if psFile ~= nil then |
108 | local i=0; |
109 | while true do |
110 | local baseName = string.format("vehicle.sprayValves.sprayValve(%d)", i); |
111 | local node = getXMLString(xmlFile, baseName.. "#index"); |
112 | if node == nil then |
113 | break; |
114 | end |
115 | node = Utils.indexToObject(self.components, node); |
116 | if node ~= nil then |
117 | local sprayValve = {}; |
118 | sprayValve.particleSystems = {}; |
119 | Utils.loadParticleSystem(xmlFile, sprayValve.particleSystems, "vehicle.sprayParticleSystem", node, false, nil, self.baseDirectory); |
120 | |
121 | sprayValve.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName.."#foldMinLimit"), 0); |
122 | sprayValve.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName.."#foldMaxLimit"), 1); |
123 | |
124 | table.insert(self.sprayValves, sprayValve); |
125 | end |
126 | i = i+1; |
127 | end |
128 | end |
129 | |
130 | local i=0; |
131 | while true do |
132 | local keyPS = string.format("vehicle.sprayParticleSystems.sprayParticleSystem(%d)", i); |
133 | local t = getXMLString(xmlFile, keyPS .. "#type"); |
134 | if t == nil then |
135 | break; |
136 | end |
137 | local fillType = Fillable.fillTypeNameToInt[t]; |
138 | if fillType ~= nil then |
139 | local currentPS = {}; |
140 | local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, keyPS, self.components, false, nil, self.baseDirectory); |
141 | self.sprayParticleSystems[fillType] = currentPS; |
142 | self.sprayParticleSystems[fillType].foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, keyPS.."#foldMinLimit"), 0); |
143 | self.sprayParticleSystems[fillType].foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, keyPS.."#foldMaxLimit"), 1); |
144 | end |
145 | i=i+1; |
146 | end |
147 | |
148 | local i = 0; |
149 | while true do |
150 | local key = string.format("vehicle.sprayerEffects.sprayerEffect(%d)", i); |
151 | if not hasXMLProperty(xmlFile, key) then |
152 | break; |
153 | end |
154 | local effect = EffectManager:loadEffect(xmlFile, key, self.components, self); |
155 | if effect ~= nil then |
156 | effect.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#foldMinLimit"), 0); |
157 | effect.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#foldMaxLimit"), 1); |
158 | table.insert(self.sprayerEffects, effect); |
159 | end |
160 | i = i + 1; |
161 | end |
162 | |
163 | self.sprayingAnimationName = Utils.getNoNil(getXMLString(xmlFile, "vehicle.sprayingAnimation#name"), ""); |
164 | |
165 | self.sampleSprayer = Utils.loadSample(xmlFile, {}, "vehicle.spraySound", nil, self.baseDirectory); |
166 | |
167 | local linkNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(xmlFile, "vehicle.fillSound#linkNode"), "0>")); |
168 | self.sampleFill = Utils.loadSample(xmlFile, {}, "vehicle.fillSound", nil, self.baseDirectory, linkNode); |
169 | self.sampleFillEnabled = false; |
170 | self.sampleFillStopTime = -1; |
171 | self.lastFillLevel = -1; |
172 | end |
173 | |
174 | self.sprayerTurnedOnRotationNodes = Utils.loadRotationNodes(xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "sprayer", self.components); |
175 | |
176 | self.showFieldNotOwnedWarning = false; |
177 | |
178 | self.isSprayerSpeedLimitActive = false; |
179 | |
180 | self.aiTerrainDetailChannel1 = g_currentMission.ploughChannel; |
181 | self.aiTerrainDetailChannel2 = g_currentMission.cultivatorChannel; |
182 | self.aiTerrainDetailChannel3 = g_currentMission.sowingChannel; |
183 | self.aiTerrainDetailChannel4 = g_currentMission.sowingWidthChannel; |
184 | |
185 | self.aiTerrainDetailProhibitedMask = 2^g_currentMission.sprayChannel; |
186 | |
187 | self.sprayerDirtyFlag = self:getNextDirtyFlag(); |
188 | end |
189 | |
190 | function Sprayer:delete() |
191 | for _, effect in pairs(self.sprayerEffects) do |
192 | EffectManager:deleteEffect(effect); |
193 | end |
194 | |
195 | for _, particleSystem in pairs(self.sprayParticleSystems) do |
196 | Utils.deleteParticleSystem(particleSystem); |
197 | end |
198 | |
199 | for k,sprayValve in pairs(self.sprayValves) do |
200 | Utils.deleteParticleSystem(sprayValve.particleSystems); |
201 | end |
202 | |
203 | if self.isClient then |
204 | Utils.deleteSample(self.sampleSprayer); |
205 | Utils.deleteSample(self.sampleFill); |
206 | end |
207 | end |
208 | |
209 | function Sprayer:readStream(streamId, connection) |
210 | end |
211 | |
212 | function Sprayer:writeStream(streamId, connection) |
213 | end |
214 | |
215 | function Sprayer:readUpdateStream(streamId, timestamp, connection) |
216 | if connection:getIsServer() then |
217 | self.showFieldNotOwnedWarning = streamReadBool(streamId); |
218 | end |
219 | end |
220 | |
221 | function Sprayer:writeUpdateStream(streamId, connection, dirtyMask) |
222 | if not connection:getIsServer() then |
223 | streamWriteBool(streamId, self.showFieldNotOwnedWarning); |
224 | end |
225 | end |
226 | |
227 | function Sprayer:mouseEvent(posX, posY, isDown, isUp, button) |
228 | end |
229 | |
230 | function Sprayer:keyEvent(unicode, sym, modifier, isDown) |
231 | end |
232 | |
233 | function Sprayer:update(dt) |
234 | if self.isClient then |
235 | Utils.updateRotationNodes(self, self.sprayerTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn()); |
236 | end |
237 | end |
238 | |
239 | function Sprayer:updateTick(dt) |
240 | self.isSprayerSpeedLimitActive = false; |
241 | if self:getIsActive() then |
242 | local showFieldNotOwnedWarning = false; |
243 | if self.turnOnDueToLoweredImplement ~= nil then |
244 | if self:getIsTurnedOn() == false then |
245 | self:setIsTurnedOn(true); |
246 | end |
247 | end |
248 | if self:getIsTurnedOn() then |
249 | if not self:getIsTurnedOnAllowed(true) then |
250 | self:setIsTurnedOn(false); |
251 | end |
252 | end |
253 | if self:getIsTurnedOn() and self.allowsSpraying then |
254 | self.isSprayerSpeedLimitActive = true; |
255 | local readyToSpray = self:getIsReadyToSpray(); |
256 | local fillType = self.currentFillType; |
257 | if fillType == Fillable.FILLTYPE_UNKNOWN then |
258 | fillType = self:getFirstEnabledFillType(); |
259 | end |
260 | |
261 | if self.isClient then |
262 | -- update valve particle systems |
263 | local foldAnimTime; |
264 | if self.doorAnimation ~= nil and self.doorAnimation.name ~= nil then |
265 | foldAnimTime = self:getAnimationTime(self.doorAnimation.name); |
266 | end |
267 | if (foldAnimTime ~= nil and foldAnimTime ~= self.lastSprayValveUpdateFoldTime) or self.lastTurnedOn == false then |
268 | |
269 | self.lastSprayValveUpdateFoldTime = foldAnimTime; |
270 | self.lastTurnedOn = true; |
271 | |
272 | if self:getAreEffectsVisible() then |
273 | if foldAnimTime ~= nil then |
274 | for _,sprayValve in pairs(self.sprayValves) do |
275 | readyToSpray = readyToSpray and (foldAnimTime > sprayValve.foldMinLimit); |
276 | Utils.setEmittingState(sprayValve.particleSystems, foldAnimTime <= sprayValve.foldMaxLimit and foldAnimTime >= sprayValve.foldMinLimit); |
277 | end |
278 | |
279 | if self.sprayParticleSystems[fillType] ~= nil then |
280 | local ps = self.sprayParticleSystems[fillType]; |
281 | readyToSpray = readyToSpray and (foldAnimTime > ps.foldMinLimit); |
282 | if foldAnimTime <= ps.foldMaxLimit and foldAnimTime >= ps.foldMinLimit then |
283 | Utils.setEmittingState(ps, true); |
284 | else |
285 | Utils.setEmittingState(ps, false); |
286 | end |
287 | end |
288 | |
289 | for _, effect in pairs(self.sprayerEffects) do |
290 | readyToSpray = readyToSpray and (foldAnimTime > effect.foldMinLimit); |
291 | if foldAnimTime <= effect.foldMaxLimit and foldAnimTime >= effect.foldMinLimit then |
292 | effect:setFillType(fillType); |
293 | EffectManager:startEffect(effect); |
294 | else |
295 | EffectManager:stopEffect(effect); |
296 | end |
297 | end |
298 | else |
299 | for _,sprayValve in pairs(self.sprayValves) do |
300 | Utils.setEmittingState(sprayValve.particleSystems, true); |
301 | end |
302 | if self.sprayParticleSystems[fillType] ~= nil then |
303 | Utils.setEmittingState(self.sprayParticleSystems[fillType], true); |
304 | end |
305 | for _, effect in pairs(self.sprayerEffects) do |
306 | effect:setFillType(fillType); |
307 | EffectManager:startEffect(effect); |
308 | end |
309 | end |
310 | end |
311 | end |
312 | end |
313 | |
314 | self.lastSprayingArea = 0; |
315 | |
316 | if self.isServer and readyToSpray then |
317 | local litersPerSecond = self:getLitersPerSecond(fillType); |
318 | local usage = litersPerSecond * dt*0.001; |
319 | g_currentMission.missionStats:updateStats("sprayUsage", usage); |
320 | |
321 | local hasSpray = false; |
322 | |
323 | --[[ |
324 | if self:getCapacity() == 0 or self:getIsHired() then |
325 | hasSpray = true; |
326 | local fillTypeDesc = Fillable.fillTypeIndexToDesc[fillType]; |
327 | if fillTypeDesc ~= nil then |
328 | local delta = usage*fillTypeDesc.pricePerLiter; |
329 | g_currentMission.missionStats:updateStats("expenses", delta); |
330 | g_currentMission:addSharedMoney(-delta, "other"); |
331 | end |
332 | else |
333 | ]]-- |
334 | if self.fillLevel > 0 then |
335 | hasSpray = true; |
336 | |
337 | local info = self.fillVolumeDischargeInfo; |
338 | |
339 | if usage > 0 then |
340 | if info.alsoUseLoadInfoForDischarge and self.fillVolumeLoadInfo ~= nil then |
341 | local fillDeltaLoadInfo = usage*info.loadInfoFillFactor; |
342 | usage = usage - fillDeltaLoadInfo; |
343 | local x,y,z = getWorldTranslation(self.fillVolumeLoadInfo.node); |
344 | local d1x,d1y,d1z = localDirectionToWorld(self.fillVolumeLoadInfo.node, self.fillVolumeLoadInfo.width*info.loadInfoSizeScale[1],0,0); |
345 | local d2x,d2y,d2z = localDirectionToWorld(self.fillVolumeLoadInfo.node, 0,0,self.fillVolumeLoadInfo.length*info.loadInfoSizeScale[2]); |
346 | local fss = {x=x,y=y,z=z, d1x=d1x,d1y=d1y,d1z=d1z, d2x=d2x,d2y=d2y,d2z=d2z}; |
347 | self:setFillLevel(self.fillLevel - fillDeltaLoadInfo, fillType, false, fss); |
348 | end |
349 | end |
350 | |
351 | local x,y,z = getWorldTranslation(info.node); |
352 | local d1x,d1y,d1z = localDirectionToWorld(info.node, info.width,0,0); |
353 | local d2x,d2y,d2z = localDirectionToWorld(info.node, 0,0,info.length); |
354 | local fillSourceStruct = {x=x,y=y,z=z, d1x=d1x,d1y=d1y,d1z=d1z, d2x=d2x,d2y=d2y,d2z=d2z}; |
355 | |
356 | self:setFillLevel(self.fillLevel - usage, fillType, false, fillSourceStruct); |
357 | else |
358 | -- try to find another attached sprayer |
359 | local sprayerTank = Sprayer.findAttachedSprayerTank(self:getRootAttacherVehicle(), fillType, self.needsTankActivation); |
360 | if sprayerTank ~= nil then |
361 | hasSpray = sprayerTank:getFillLevel(fillType) > 0; |
362 | |
363 | if hasSpray then |
364 | local x,y,z = getWorldTranslation(sprayerTank.fillVolumeDischargeInfo.node); |
365 | local d1x,d1y,d1z = localDirectionToWorld(sprayerTank.fillVolumeDischargeInfo.node, sprayerTank.fillVolumeDischargeInfo.width,0,0); |
366 | local d2x,d2y,d2z = localDirectionToWorld(sprayerTank.fillVolumeDischargeInfo.node, 0,0,sprayerTank.fillVolumeDischargeInfo.length); |
367 | local fillSourceStruct = {x=x,y=y,z=z, d1x=d1x,d1y=d1y,d1z=d1z, d2x=d2x,d2y=d2y,d2z=d2z}; |
368 | |
369 | sprayerTank:setFillLevel(sprayerTank:getFillLevel(fillType) - usage, fillType, false, fillSourceStruct); |
370 | end |
371 | end |
372 | end |
373 | |
374 | if not hasSpray and (self:getCapacity() == 0 or self:getIsHired()) then |
375 | hasSpray = true; |
376 | local fillTypeDesc = Fillable.fillTypeIndexToDesc[fillType]; |
377 | if fillTypeDesc ~= nil then |
378 | local delta = usage*fillTypeDesc.pricePerLiter*1.5; -- increase price if AI is active to reward the player's manual work |
379 | g_currentMission.missionStats:updateStats("expenses", delta); |
380 | g_currentMission:addSharedMoney(-delta, "other"); |
381 | end |
382 | end |
383 | |
384 | if hasSpray then |
385 | local workAreasSend, showWarning, area = self:getTypedNetworkAreas(WorkArea.AREATYPE_SPRAYER, true); |
386 | showFieldNotOwnedWarning = showWarning; |
387 | self.lastSprayingArea = area; |
388 | |
389 | if (table.getn(workAreasSend) > 0) then |
390 | SprayerAreaEvent.runLocally(workAreasSend); |
391 | g_server:broadcastEvent(SprayerAreaEvent:new(workAreasSend)); |
392 | end |
393 | end |
394 | end |
395 | |
396 | if self.isClient and self:getIsActiveForSound() then |
397 | Utils.playSample(self.sampleSprayer, 0, 0, nil); |
398 | end |
399 | else |
400 | if self.isClient then |
401 | for _,sprayValve in pairs(self.sprayValves) do |
402 | Utils.setEmittingState(sprayValve.particleSystems, false); |
403 | end |
404 | for _, particleSystem in pairs(self.sprayParticleSystems) do |
405 | Utils.setEmittingState(particleSystem, false); |
406 | end |
407 | for _, effect in pairs(self.sprayerEffects) do |
408 | EffectManager:stopEffect(effect); |
409 | end |
410 | end |
411 | end |
412 | self.lastTurnedOn = self:getIsTurnedOn(); |
413 | |
414 | if self.isServer then |
415 | if showFieldNotOwnedWarning ~= self.showFieldNotOwnedWarning then |
416 | self.showFieldNotOwnedWarning = showFieldNotOwnedWarning; |
417 | self:raiseDirtyFlags(self.sprayerDirtyFlag); |
418 | end |
419 | end |
420 | end |
421 | |
422 | if self.isClient then |
423 | if self.lastFillLevel ~= self.fillLevel and self.fillLevel > 0 then |
424 | if self.lastFillLevel < self.fillLevel and self.lastFillLevel ~= -1 then |
425 | self.sampleFillStopTime = g_currentMission.time + 150; |
426 | end |
427 | self.lastFillLevel = self.fillLevel; |
428 | end |
429 | |
430 | if self.sampleFillStopTime > g_currentMission.time then |
431 | if self:getIsActiveForSound(true) then |
432 | Utils.playSample(self.sampleFill, 0, 0, nil); |
433 | Utils.stop3DSample(self.sampleFill); |
434 | else |
435 | Utils.stopSample(self.sampleFill); |
436 | Utils.play3DSample(self.sampleFill); |
437 | end |
438 | else |
439 | Utils.stopSample(self.sampleFill); |
440 | Utils.stop3DSample(self.sampleFill); |
441 | end |
442 | end |
443 | end |
444 | |
445 | function Sprayer:draw() |
446 | |
447 | if self.isClient then |
448 | if self:getIsActiveForInput(true) and not self.isAlwaysTurnedOn then |
449 | if not self:getIsTurnedOnAllowed(true) and self.fillLevel <= 0 and self:getCapacity() > 0 then |
450 | g_currentMission:addExtraPrintText(g_i18n:getText("FirstFillTheTool")); |
451 | end |
452 | end |
453 | |
454 | if self.showFieldNotOwnedWarning then |
455 | g_currentMission:showBlinkingWarning(g_i18n:getText("You_dont_own_this_field")); |
456 | end |
457 | end |
458 | end |
459 | |
460 | function Sprayer:onDetach(attacherVehicle, jointDescIndex) |
461 | if attacherVehicle.setIsTurnedOn ~= nil and attacherVehicle:getIsTurnedOn() then |
462 | attacherVehicle:setIsTurnedOn(false); |
463 | end |
464 | end |
465 | |
466 | function Sprayer:onDeactivate() |
467 | self.showFieldNotOwnedWarning = false; |
468 | end |
469 | |
470 | function Sprayer:onDeactivateSounds() |
471 | if self.isClient then |
472 | Utils.stopSample(self.sampleSprayer, true); |
473 | end |
474 | end |
475 | |
476 | function Sprayer:setJointMoveDown(jointDescIndex, moveDown, noEventSend) |
477 | if self.isSprayerTank then |
478 | |
479 | local jointDesc = self.attacherJoints[jointDescIndex] |
480 | jointDesc.moveDown = moveDown; |
481 | |
482 | local implementIndex = self:getImplementIndexByJointDescIndex(jointDescIndex); |
483 | if implementIndex ~= nil then |
484 | local implement = self.attachedImplements[implementIndex]; |
485 | if implement.object ~= nil then |
486 | if implement.object.activateTankOnLowering then |
487 | |
488 | if moveDown then |
489 | if self:getFillLevel(self.currentFillType) > 0 then |
490 | self.turnOnDueToLoweredImplement = implement; |
491 | end |
492 | else |
493 | self:setIsTurnedOn(false); |
494 | self.turnOnDueToLoweredImplement = nil; |
495 | end |
496 | |
497 | end |
498 | end |
499 | end |
500 | end |
501 | end |
502 | |
503 | function Sprayer:getIsTurnedOnAllowed(superFunc, isTurnedOn) |
504 | if not self.allowsSpraying then |
505 | return false; |
506 | end |
507 | |
508 | if isTurnedOn and self.fillLevel <= 0 then |
509 | |
510 | -- try to find tank |
511 | local fillType = self.currentFillType; |
512 | if fillType == Fillable.FILLTYPE_UNKNOWN then |
513 | fillType = self:getFirstEnabledFillType(); |
514 | end |
515 | local sprayerTank = Sprayer.findAttachedSprayerTank(self:getRootAttacherVehicle(), fillType, self.needsTankActivation); |
516 | |
517 | if self:getCapacity() > 0 and not self:getIsHired() and sprayerTank == nil then |
518 | return false; |
519 | end |
520 | |
521 | end |
522 | |
523 | if superFunc ~= nil then |
524 | return superFunc(self, isTurnedOn); |
525 | end |
526 | |
527 | return true; |
528 | end |
529 | |
530 | function Sprayer:onTurnedOn(noEventSend) |
531 | if self.isClient then |
532 | if self.foldAnimTime == nil then |
533 | -- If the sprayer is foldable, the spray valves are only turned on within the update loop |
534 | for _,sprayValve in pairs(self.sprayValves) do |
535 | Utils.setEmittingState(sprayValve.particleSystems, true); |
536 | end |
537 | for _, particleSystem in pairs(self.sprayParticleSystems) do |
538 | Utils.setEmittingState(particleSystem, false); |
539 | end |
540 | for _, effect in pairs(self.sprayerEffects) do |
541 | EffectManager:startEffect(effect); |
542 | end |
543 | end |
544 | if self.sprayingAnimationName ~= "" and self.playAnimation ~= nil then |
545 | self:playAnimation(self.sprayingAnimationName, 1, self:getAnimationTime(self.sprayingAnimationName), true); |
546 | end |
547 | end |
548 | end |
549 | |
550 | function Sprayer:onTurnedOff(noEventSend) |
551 | if self.isClient then |
552 | for _,sprayValve in pairs(self.sprayValves) do |
553 | Utils.setEmittingState(sprayValve.particleSystems, false); |
554 | end |
555 | for _, particleSystem in pairs(self.sprayParticleSystems) do |
556 | Utils.setEmittingState(particleSystem, false); |
557 | end |
558 | for _, effect in pairs(self.sprayerEffects) do |
559 | EffectManager:stopEffect(effect); |
560 | end |
561 | Utils.stopSample(self.sampleSprayer); |
562 | |
563 | if self.sprayingAnimationName ~= "" and self.stopAnimation ~= nil then |
564 | self:stopAnimation(self.sprayingAnimationName, true); |
565 | end |
566 | end |
567 | end |
568 | |
569 | function Sprayer:aiTurnOn() |
570 | if self.setIsTurnedOn ~= nil then |
571 | self:setIsTurnedOn(true, true); |
572 | end |
573 | end |
574 | |
575 | function Sprayer:aiTurnOff() |
576 | if self.setIsTurnedOn ~= nil then |
577 | self:setIsTurnedOn(false, true); |
578 | end |
579 | end |
580 | |
581 | function Sprayer:aiLower() |
582 | if self.setIsTurnedOn ~= nil then |
583 | self:setIsTurnedOn(true, true); |
584 | end |
585 | end |
586 | |
587 | function Sprayer:aiRaise() |
588 | if self.setIsTurnedOn ~= nil then |
589 | self:setIsTurnedOn(false, true); |
590 | end |
591 | end |
592 | |
593 | |
594 | function Sprayer.findAttachedSprayerTank(currentVehicle, fillType, needsTankActivation) |
595 | if currentVehicle.isSprayerTank and currentVehicle.getFillLevel ~= nil and currentVehicle.setFillLevel ~= nil and currentVehicle:getFillLevel(fillType) > 0 and (not needsTankActivation or (currentVehicle.getIsTurnedOn ~= nil and currentVehicle:getIsTurnedOn())) then |
596 | return currentVehicle; |
597 | end |
598 | for _,implement in pairs(currentVehicle.attachedImplements) do |
599 | if implement.object ~= nil then |
600 | local ret = Sprayer.findAttachedSprayerTank(implement.object, fillType, needsTankActivation); |
601 | if ret ~= nil then |
602 | return ret; |
603 | end |
604 | end |
605 | end |
606 | return nil; |
607 | end |
608 | |
609 | function Sprayer:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
610 | local retValue = true; |
611 | if superFunc ~= nil then |
612 | retValue = superFunc(self, workArea, xmlFile, key) |
613 | end |
614 | |
615 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
616 | workArea.type = WorkArea.AREATYPE_SPRAYER; |
617 | end |
618 | |
619 | return retValue; |
620 | end |
621 | |
622 | function Sprayer:getIsReadyToSpray() |
623 | return true; |
624 | end |
625 | |
626 | function Sprayer:getAreEffectsVisible() |
627 | return true; |
628 | end |
629 | |
630 | function Sprayer:getLitersPerSecond(fillType) |
631 | local litersPerSecond = self.sprayLitersPerSecond[fillType]; |
632 | if litersPerSecond == nil then |
633 | litersPerSecond = self.defaultSprayLitersPerSecond; |
634 | end |
635 | |
636 | return litersPerSecond; |
637 | end |
638 | |
639 | function Sprayer:doCheckSpeedLimit(superFunc) |
640 | local parent = true; |
641 | if superFunc ~= nil then |
642 | parent = superFunc(self); |
643 | end |
644 | |
645 | return parent and self.isSprayerSpeedLimitActive; |
646 | end |
647 | |
648 | function Sprayer.getDefaultSpeedLimit() |
649 | return 15; |
650 | end
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de