Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Cutter |
3 | -- This is the specialization for cutters |
4 | -- It reacts both to steerable and attachable events |
5 | -- |
6 | -- @author Stefan Geiger |
7 | -- @date 04/12/08 |
8 | -- |
9 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
10 | |
11 | Cutter = {}; |
12 | source("dataS/scripts/vehicles/specializations/CutterAreaEvent.lua"); |
13 | source("dataS/scripts/vehicles/specializations/ForageWagonAreaEvent.lua"); |
14 | |
15 | function Cutter.initSpecialization() |
16 | WorkArea.registerAreaType("cutter"); |
17 | end; |
18 | |
19 | function Cutter.prerequisitesPresent(specializations) |
20 | return SpecializationUtil.hasSpecialization(WorkArea, specializations); |
21 | end; |
22 | |
23 | function Cutter:preLoad(xmlFile) |
24 | self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, Cutter.loadSpeedRotatingPartFromXML); |
25 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Cutter.loadWorkAreaFromXML); |
26 | self.loadTestAreaFromXML = Cutter.loadTestAreaFromXML; |
27 | self.getIsTestAreaActive = Cutter.getIsTestAreaActive; |
28 | end |
29 | |
30 | function Cutter:load(xmlFile) |
31 | |
32 | self.onStartReel = SpecializationUtil.callSpecializationsFunction("onStartReel"); |
33 | self.onStopReel = SpecializationUtil.callSpecializationsFunction("onStopReel"); |
34 | --self.setFruitType = SpecializationUtil.callSpecializationsFunction("setFruitType"); |
35 | self.getCombine = Cutter.getCombine; |
36 | self.applyInitialAnimation = Utils.overwrittenFunction(self.applyInitialAnimation, Cutter.applyInitialAnimation); |
37 | self.getDirectionSnapAngle = Utils.overwrittenFunction(self.getDirectionSnapAngle, Cutter.getDirectionSnapAngle); |
38 | self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, Cutter.getIsSpeedRotatingPartActive); |
39 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Cutter.doCheckSpeedLimit); |
40 | |
41 | if self.isClient then |
42 | self.cutterTurnedOnRotationNodes = Utils.loadRotationNodes(xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "cutter", self.components); |
43 | self.cutterTurnedOnScrollers = Utils.loadScrollers(self.components, xmlFile, "vehicle.cutterTurnedOnScrollers.cutterTurnedOnScroller", {}, false); |
44 | |
45 | if hasXMLProperty(xmlFile, "vehicle.reel#index") then |
46 | print("Warning: vehicle.reel is no longer used, use vehicle.turnedOnRotationNodes.turnedOnRotationNode (type: cutter)\n"); |
47 | end; |
48 | |
49 | if hasXMLProperty(xmlFile, "vehicle.cutterThreshingUVScrollParts") then |
50 | print("Warning: vehicle.cutterThreshingUVScrollParts is no longer used, use vehicle.cutterTurnedOnScrollers.cutterTurnedOnScroller \n"); |
51 | end; |
52 | |
53 | if hasXMLProperty(xmlFile, "vehicle.rolls") then |
54 | print("Warning: vehicle.rolls is no longer used, use vehicle.turnedOnRotationNodes.turnedOnRotationNode (type: cutter)\n"); |
55 | end; |
56 | |
57 | if hasXMLProperty(xmlFile, "vehicle.cutterSpeedRotatingParts") then |
58 | print("Warning: vehicle.cutterSpeedRotatingParts is no longer used, use vehicle.speedRotatingParts.speedRotatingPart\n"); |
59 | end; |
60 | |
61 | self.spikesCount = getXMLInt(xmlFile, "vehicle.reelspikes#count"); |
62 | local indexSpikesStr = getXMLString(xmlFile, "vehicle.reelspikes#index"); |
63 | self.spikesRootNode = Utils.indexToObject(self.components, indexSpikesStr); |
64 | |
65 | self.spikeAnimNodes = {}; |
66 | local i = 0; |
67 | while true do |
68 | local key = string.format("vehicle.reelspikes.spike(%d)", i); |
69 | if not hasXMLProperty(xmlFile, key) then |
70 | break; |
71 | end; |
72 | |
73 | local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#node")); |
74 | local animCurve = AnimCurve:new(linearInterpolator1); |
75 | local keyI = 0; |
76 | while true do |
77 | local animKey = key .. string.format(".key(%d)", keyI); |
78 | if not hasXMLProperty(xmlFile, animKey) then |
79 | break; |
80 | end; |
81 | local keyTime = getXMLFloat(xmlFile, animKey.."#time"); |
82 | local xRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, animKey.."#rotX"), 0)); |
83 | |
84 | animCurve:addKeyframe({v=xRot, time=keyTime}); |
85 | keyI = keyI +1; |
86 | end; |
87 | table.insert(self.spikeAnimNodes, {node=node, animCurve = animCurve}); |
88 | i = i + 1; |
89 | end; |
90 | |
91 | if table.getn(self.spikeAnimNodes) == 0 then |
92 | self.spikeAnimNodes = nil; |
93 | end; |
94 | |
95 | local turnedOnRotNodeRef = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.reelspikes#turnedOnRotNodeRef"), 1); |
96 | if self.cutterTurnedOnRotationNodes.nodes[turnedOnRotNodeRef] == nil and (self.spikesRootNode ~= nil or self.spikeAnimNodes ~= nil) then |
97 | print("Warning: No 'turnedOnRotNodeRef' defined for reelspikes in '"..self.configFileName.."'"); |
98 | self.spikesRootNode = nil; |
99 | self.spikeAnimNodes = nil; |
100 | else |
101 | self.spikesRef = self.cutterTurnedOnRotationNodes.nodes[turnedOnRotNodeRef]; |
102 | end; |
103 | |
104 | self.fruitExtraObjects = {}; |
105 | local i = 0; |
106 | while true do |
107 | local key = string.format("vehicle.fruitExtraObjects.fruitExtraObject(%d)", i); |
108 | local t = getXMLString(xmlFile, key.."#fruitType"); |
109 | local index = getXMLString(xmlFile, key.."#index"); |
110 | local anim = getXMLString(xmlFile, key.."#anim"); |
111 | if t==nil or (index==nil and anim==nil) then |
112 | break; |
113 | end; |
114 | |
115 | local node = Utils.indexToObject(self.components, index); |
116 | if node ~= nil then |
117 | setVisibility(node, false); |
118 | end; |
119 | self.fruitExtraObjects[t] = {node=node, anim=anim}; |
120 | i = i +1; |
121 | end; |
122 | |
123 | self.cutterStartAnimation = getXMLString(xmlFile, "vehicle.cutterStartAnimation#name"); |
124 | self.cutterStartAnimationSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cutterStartAnimation#speedScale"), 1); |
125 | self.cutterStartAnimationInitialIsStarted = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.cutterStartAnimation#initialIsStarted"), false); |
126 | |
127 | self.threshingParticleSystems = {}; |
128 | local psName = "vehicle.threshingParticleSystem"; |
129 | Utils.loadParticleSystem(xmlFile, self.threshingParticleSystems, psName, self.components, false, nil, self.baseDirectory) |
130 | end; |
131 | |
132 | self.cutterTestAreas = {}; |
133 | local i = 0; |
134 | while true do |
135 | local key = string.format("vehicle.cutterTestAreas.cutterTestArea(%d)", i); |
136 | if not hasXMLProperty(xmlFile, key) then |
137 | break; |
138 | end; |
139 | local testArea = {}; |
140 | if self:loadTestAreaFromXML(testArea, xmlFile, key) then |
141 | table.insert(self.cutterTestAreas, testArea); |
142 | end; |
143 | i = i + 1; |
144 | end; |
145 | self.cutterEffectBaseNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.cutterEffects#baseNode")), self.rootNode); |
146 | self.cutterEffects = {}; |
147 | self.currentCutterEffect = nil; |
148 | self.defaultCutterEffect = nil; |
149 | local i = 0; |
150 | while true do |
151 | local key = string.format("vehicle.cutterEffects.cutterEffect(%d)", i); |
152 | if not hasXMLProperty(xmlFile, key) then |
153 | break; |
154 | end; |
155 | local t = getXMLString(xmlFile, key.."#fruitType"); |
156 | local desc = FruitUtil.fruitTypes[t]; |
157 | if desc == nil then |
158 | print("Invalid fruittype '"..tostring(t).."' in '"..self.configFileName.."'"); |
159 | break; |
160 | end; |
161 | local effect = EffectManager:loadEffect(xmlFile, key, self.components, self); |
162 | self.cutterEffects[desc.index] = {effect=effect, baseNode=effect.node}; |
163 | if self.defaultCutterEffect == nil then |
164 | self.defaultCutterEffect = self.cutterEffects[desc.index]; |
165 | end; |
166 | i = i +1; |
167 | end; |
168 | |
169 | self.cutterAllowCuttingWhileRaised = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.cutterAllowCuttingWhileRaised"), false); |
170 | self.preferedCombineSize = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.preferedCombineSize"), 1); |
171 | |
172 | self.fruitTypes = {}; |
173 | local fruitTypes = getXMLString(xmlFile, "vehicle.fruitTypes#fruitTypes"); |
174 | if fruitTypes ~= nil then |
175 | local types = Utils.splitString(" ", fruitTypes); |
176 | for k,v in pairs(types) do |
177 | local desc = FruitUtil.fruitTypes[v]; |
178 | if desc ~= nil then |
179 | self.fruitTypes[desc.index] = true; |
180 | end; |
181 | end; |
182 | end; |
183 | |
184 | self.fruitTypesUseWindrowed = getXMLBool(xmlFile, "vehicle.fruitTypes#useWindrowed"); |
185 | self.windrowFillTypes = {}; |
186 | if self.fruitTypesUseWindrowed then |
187 | for fruitType, state in pairs(self.fruitTypes) do |
188 | local windrowFillType = FruitUtil.fruitTypeToWindrowFillType[fruitType]; |
189 | self.windrowFillTypes[windrowFillType] = true; |
190 | end; |
191 | end; |
192 | |
193 | self.convertedFruits = {}; |
194 | local i = 0; |
195 | while true do |
196 | local key = string.format("vehicle.convertedFruits.convertedFruit(%d)", i); |
197 | if not hasXMLProperty(xmlFile, key) then |
198 | break; |
199 | end; |
200 | local inputType = getXMLString(xmlFile, key .. "#input"); |
201 | local outputType = getXMLString(xmlFile, key .. "#output"); |
202 | |
203 | if inputType ~= nil and outputType ~= nil then |
204 | local inputDesc = FruitUtil.fruitTypes[inputType]; |
205 | local outputDesc = FruitUtil.fruitTypes[outputType]; |
206 | if inputDesc ~= nil and outputDesc ~= nil then |
207 | self.convertedFruits[inputDesc.index] = outputDesc.index; |
208 | end; |
209 | end; |
210 | |
211 | i = i + 1; |
212 | end; |
213 | |
214 | self.cutterMovingDirection = Utils.sign(Utils.getNoNil(getXMLInt(xmlFile, "vehicle.cutterMovingDirection"), -1)); |
215 | self.currentInputFruitType = FruitUtil.FRUITTYPE_UNKNOWN; |
216 | self.reelStarted = false; |
217 | self.isCutterSpeedLimitActive = false; |
218 | |
219 | self.forceLowSpeed = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.cutterSpeedLimit#forceLow"), false); |
220 | |
221 | self.lastCutterArea = 0; |
222 | self.lastCutterAreaBiggerZero = self.lastCutterArea > 0; |
223 | self.cutterGroundFlag = self:getNextDirtyFlag(); |
224 | end; |
225 | |
226 | function Cutter:applyInitialAnimation(superFunc) |
227 | if self.cutterStartAnimation ~= nil and self.playAnimation ~= nil and self.cutterStartAnimationInitialIsStarted then |
228 | self:playAnimation(self.cutterStartAnimation, -self.cutterStartAnimationSpeedScale, nil, true); |
229 | AnimatedVehicle.updateAnimations(self, 99999999); |
230 | end |
231 | if superFunc ~= nil then |
232 | superFunc(self); |
233 | end |
234 | end |
235 | |
236 | function Cutter:delete() |
237 | if self.isClient then |
238 | Utils.deleteParticleSystem(self.threshingParticleSystems); |
239 | end; |
240 | for _, effectAttribute in pairs(self.cutterEffects) do |
241 | EffectManager:deleteEffect(effectAttribute.effect); |
242 | end; |
243 | end; |
244 | |
245 | function Cutter:readStream(streamId, timestamp, connection) |
246 | self.lastCutterAreaBiggerZero = streamReadBool(streamId); |
247 | local reelStarted = streamReadBool(streamId); |
248 | if reelStarted then |
249 | self:onStartReel(); |
250 | end; |
251 | end; |
252 | |
253 | function Cutter:writeStream(streamId, connection, dirtyMask) |
254 | streamWriteBool(streamId, self.lastCutterAreaBiggerZero); |
255 | streamWriteBool(streamId, self.reelStarted); |
256 | end; |
257 | |
258 | function Cutter:readUpdateStream(streamId, timestamp, connection) |
259 | if connection:getIsServer() then |
260 | self.lastCutterAreaBiggerZero = streamReadBool(streamId); |
261 | end; |
262 | end; |
263 | |
264 | function Cutter:writeUpdateStream(streamId, connection, dirtyMask) |
265 | if not connection:getIsServer() then |
266 | streamWriteBool(streamId, self.lastCutterAreaBiggerZero); |
267 | end; |
268 | end; |
269 | |
270 | function Cutter:mouseEvent(posX, posY, isDown, isUp, button) |
271 | end; |
272 | |
273 | function Cutter:keyEvent(unicode, sym, modifier, isDown) |
274 | end; |
275 | |
276 | function Cutter:update(dt) |
277 | end; |
278 | |
279 | function Cutter:updateTick(dt) |
280 | self.isCutterSpeedLimitActive = false; |
281 | if self.isServer then |
282 | self.lastCutterArea = 0; |
283 | self.lastCutterAreaBiggerZero = false; |
284 | end; |
285 | |
286 | if self.reelStarted and self.movingDirection == self.cutterMovingDirection and (self.cutterAllowCuttingWhileRaised or self:isLowered(true)) then |
287 | local minEffectValue = math.huge; |
288 | local maxEffectValue = -math.huge; |
289 | if self:getLastSpeed() > 0.5 and self.currentInputFruitType ~= nil then |
290 | for k, testArea in pairs(self.cutterTestAreas) do |
291 | if self:getIsTestAreaActive(testArea) then |
292 | local x,y,z = getWorldTranslation(testArea.start); |
293 | local x1,y1,z1 = getWorldTranslation(testArea.width); |
294 | local x2,_,z2 = getWorldTranslation(testArea.height); |
295 | local fruitValue = Utils.getFruitArea(self.currentInputFruitType, x, z, x1, z1, x2, z2); |
296 | if fruitValue > 0 then |
297 | local lx1,_,_ = worldToLocal(self.cutterEffectBaseNode, x,y,z); |
298 | local lx2,_,_ = worldToLocal(self.cutterEffectBaseNode, x1,y1,z1); |
299 | minEffectValue = math.min(minEffectValue, lx1, lx2); |
300 | maxEffectValue = math.max(maxEffectValue, lx1, lx2); |
301 | end; |
302 | end; |
303 | end; |
304 | end; |
305 | if self.currentInputFruitType ~= nil then |
306 | local effectElement = Utils.getNoNil(self.cutterEffects[self.currentInputFruitType], self.defaultCutterEffect); |
307 | if effectElement ~= nil then |
308 | if self.currentCutterEffect ~= effectElement.effect then |
309 | EffectManager:resetEffect(self.currentCutterEffect); |
310 | end; |
311 | |
312 | self.currentCutterEffect = effectElement.effect; |
313 | local reset = false; |
314 | if minEffectValue == math.huge and maxEffectValue == -math.huge then |
315 | minEffectValue = 0; |
316 | maxEffectValue = 0; |
317 | reset = true; |
318 | end; |
319 | if self.cutterMovingDirection > 0 then |
320 | minEffectValue = minEffectValue * -1; |
321 | maxEffectValue = maxEffectValue * -1; |
322 | if maxEffectValue < minEffectValue then |
323 | local t = minEffectValue; |
324 | minEffectValue = maxEffectValue; |
325 | maxEffectValue = t; |
326 | end; |
327 | end; |
328 | self.currentCutterEffect:setMinMax(minEffectValue, maxEffectValue, reset); |
329 | end; |
330 | end; |
331 | |
332 | self.isCutterSpeedLimitActive = true; |
333 | |
334 | local oldInputFruitType = self.currentInputFruitType; |
335 | if self.isServer then |
336 | local combine = self:getCombine(); |
337 | if combine ~= nil and combine:getIsThreshingAllowed(false) and combine.allowsThreshing then |
338 | local workAreasSend, _, _ = self:getTypedNetworkAreas(WorkArea.AREATYPE_CUTTER, false); |
339 | |
340 | if (table.getn(workAreasSend) > 0) then |
341 | for fruitType,_ in pairs(self.fruitTypes) do |
342 | local fruitTypeWindrow; |
343 | local outputFruitType = fruitType; |
344 | if self.convertedFruits[fruitType] ~= nil then |
345 | outputFruitType = self.convertedFruits[fruitType]; |
346 | end; |
347 | if combine:getIsCutterFruitTypeAllowed(outputFruitType) then |
348 | local lastCutterArea = 0; |
349 | local lastRealArea = 0; |
350 | if self.fruitTypesUseWindrowed then |
351 | local totalArea, usedFruitType = ForageWagonAreaEvent.runLocally(workAreasSend, self.windrowFillTypes, false, fruitType); |
352 | lastCutterArea = totalArea; |
353 | lastRealArea = totalArea; |
354 | fruitTypeWindrow = usedFruitType; |
355 | else |
356 | local cutterArea, realArea = CutterAreaEvent.runLocally(workAreasSend, fruitType); |
357 | lastCutterArea = cutterArea; |
358 | lastRealArea = realArea; |
359 | end; |
360 | |
361 | |
362 | if lastCutterArea > 0 then |
363 | |
364 | self.lastCutterArea = lastCutterArea; |
365 | self.lastCutterAreaBiggerZero = (self.lastCutterArea > 0); |
366 | |
367 | combine:addCutterArea(self, lastCutterArea, lastRealArea, fruitType, outputFruitType); |
368 | |
369 | if self.fruitTypesUseWindrowed then |
370 | g_server:broadcastEvent(ForageWagonAreaEvent:new(workAreasSend, fruitTypeWindrow)); |
371 | self.currentInputFruitType = fruitTypeWindrow; |
372 | else |
373 | g_server:broadcastEvent(CutterAreaEvent:new(workAreasSend, fruitType)); |
374 | self.currentInputFruitType = fruitType; |
375 | end; |
376 | |
377 | if self.lastCutterAreaBiggerZero ~= self.lastCutterAreaBiggerZeroSent then |
378 | self:raiseDirtyFlags(self.cutterGroundFlag); |
379 | self.lastCutterAreaBiggerZeroSent = self.lastCutterAreaBiggerZero; |
380 | end; |
381 | |
382 | local ha = Utils.areaToHa(lastRealArea, g_currentMission:getFruitPixelsToSqm()); -- 4096px are mapped to 2048m |
383 | g_currentMission.missionStats:updateStats("hectaresThreshed", ha); |
384 | |
385 | -- Stop the loop over all fruit types |
386 | break; |
387 | end |
388 | end |
389 | end |
390 | end |
391 | end |
392 | else |
393 | local combine = self:getCombine(); |
394 | if combine ~= nil and combine.lastValidInputFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then |
395 | self.currentInputFruitType = combine.lastValidInputFruitType; |
396 | end |
397 | end |
398 | if self.currentInputFruitType ~= oldInputFruitType and self.isClient then |
399 | Cutter.updateExtraObjects(self); |
400 | end |
401 | else |
402 | if self.currentCutterEffect ~= nil then |
403 | self.currentCutterEffect:setMinMax(0, 0, true); |
404 | end; |
405 | end |
406 | |
407 | if self.isClient then |
408 | Utils.setEmittingState(self.threshingParticleSystems, (self.reelStarted and self.lastCutterAreaBiggerZero)); |
409 | Utils.updateRotationNodes(self, self.cutterTurnedOnRotationNodes, dt, self:getIsActive() and self.reelStarted); |
410 | Utils.updateScrollers(self.cutterTurnedOnScrollers, dt, self:getIsActive() and self.reelStarted); |
411 | |
412 | if self.cutterTurnedOnRotationNodes.isRunning then |
413 | if self.spikesRootNode ~= nil then |
414 | --correct spikes, so that they always look down |
415 | local atx, aty, atz = getRotation(self.spikesRef.node); |
416 | for i=1, self.spikesCount do |
417 | local spike = getChildAt(self.spikesRootNode, i-1); |
418 | setRotation(spike, -atx, aty, atz); |
419 | end; |
420 | end; |
421 | |
422 | if self.spikeAnimNodes ~= nil then |
423 | local x,y,z = getRotation(self.spikesRef.node); |
424 | local ref = x; |
425 | if self.spikesRef.rotAxis == 2 then |
426 | ref = y; |
427 | elseif self.spikesRef.rotAxis == 3 then |
428 | ref = z; |
429 | end; |
430 | local t = (ref % (2*math.pi)) / (2*math.pi); |
431 | for k, spike in pairs(self.spikeAnimNodes) do |
432 | local rotX = spike.animCurve:get(t); |
433 | setRotation(spike.node, rotX, 0, 0); |
434 | end; |
435 | end; |
436 | end; |
437 | end; |
438 | end |
439 | |
440 | function Cutter:draw() |
441 | end; |
442 | |
443 | function Cutter:onDeactivate() |
444 | self:onStopReel(); |
445 | if self.isClient then |
446 | Utils.setEmittingState(self.threshingParticleSystems, false); |
447 | end; |
448 | end; |
449 | |
450 | function Cutter:onStartReel() |
451 | if not self.reelStarted then |
452 | self.reelStarted = true; |
453 | |
454 | if self.isClient then |
455 | if self.cutterStartAnimation ~= nil and self.playAnimation ~= nil then |
456 | self:playAnimation(self.cutterStartAnimation, self.cutterStartAnimationSpeedScale, nil, true); |
457 | end |
458 | end; |
459 | end; |
460 | end; |
461 | |
462 | function Cutter:onStopReel() |
463 | if self.reelStarted then |
464 | self.reelStarted = false; |
465 | if self.isClient then |
466 | Utils.setEmittingState(self.threshingParticleSystems, false); |
467 | |
468 | if self.cutterStartAnimation ~= nil and self.playAnimation ~= nil then |
469 | self:playAnimation(self.cutterStartAnimation, -self.cutterStartAnimationSpeedScale, nil, true); |
470 | end |
471 | end; |
472 | if self.currentCutterEffect ~= nil then |
473 | EffectManager:resetEffect(self.currentCutterEffect); |
474 | end; |
475 | end; |
476 | end; |
477 | |
478 | function Cutter:getDirectionSnapAngle(superFunc) |
479 | local snapAngle = 0; |
480 | for fruitType,_ in pairs(self.fruitTypes) do |
481 | local desc = FruitUtil.fruitIndexToDesc[fruitType]; |
482 | if desc ~= nil then |
483 | snapAngle = math.max(snapAngle, desc.directionSnapAngle); |
484 | end |
485 | end |
486 | return math.max(snapAngle, superFunc(self)); |
487 | end |
488 | |
489 | function Cutter:getCombine() |
490 | if self.getIsThreshingAllowed ~= nil and self.getIsCutterFruitTypeAllowed ~= nil and self.fillLevel ~= nil then |
491 | return self; |
492 | else |
493 | local c = self.attacherVehicle; |
494 | if c ~= nil and c.getIsThreshingAllowed ~= nil and c.getIsCutterFruitTypeAllowed ~= nil and c.fillLevel ~= nil then |
495 | return c; |
496 | end |
497 | end; |
498 | return nil; |
499 | end |
500 | |
501 | function Cutter:doCheckSpeedLimit(superFunc) |
502 | local parent = true; |
503 | if superFunc ~= nil then |
504 | parent = superFunc(self); |
505 | end |
506 | |
507 | return parent and self.isCutterSpeedLimitActive; |
508 | end; |
509 | |
510 | function Cutter:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key) |
511 | if superFunc ~= nil then |
512 | if not superFunc(self, speedRotatingPart, xmlFile, key) then |
513 | return false; |
514 | end |
515 | end |
516 | |
517 | speedRotatingPart.rotateIfTurnedOn = Utils.getNoNil(getXMLBool(xmlFile, key .. "#rotateIfTurnedOn"), false); |
518 | |
519 | return true; |
520 | end |
521 | |
522 | function Cutter:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart) |
523 | if (not self.cutterAllowCuttingWhileRaised and not self:isLowered(true)) or (speedRotatingPart.rotateIfTurnedOn and not self.reelStarted) then |
524 | return false; |
525 | end; |
526 | |
527 | if superFunc ~= nil then |
528 | return superFunc(self, speedRotatingPart); |
529 | end |
530 | return true; |
531 | end; |
532 | |
533 | function Cutter:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
534 | local retValue = true; |
535 | if superFunc ~= nil then |
536 | retValue = superFunc(self, workArea, xmlFile, key) |
537 | end |
538 | |
539 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
540 | workArea.type = WorkArea.AREATYPE_CUTTER; |
541 | end; |
542 | |
543 | return retValue; |
544 | end; |
545 | |
546 | function Cutter.getUseLowSpeedLimit(self) |
547 | local combineSize = self.combineSize; |
548 | if combineSize == nil then |
549 | if self.attacherVehicle ~= nil then |
550 | combineSize = self.attacherVehicle.combineSize; |
551 | end |
552 | end |
553 | |
554 | if self.forceLowSpeed or (combineSize ~= nil and self.preferedCombineSize > combineSize) then |
555 | return true; |
556 | end |
557 | return false; |
558 | end; |
559 | |
560 | function Cutter.updateExtraObjects(self) |
561 | if self.currentExtraObject ~= nil then |
562 | if self.currentExtraObject.node ~= nil then |
563 | setVisibility(self.currentExtraObject.node, false); |
564 | end; |
565 | if self.currentExtraObject.anim ~= nil and self.playAnimation ~= nil then |
566 | self:playAnimation(self.currentExtraObject.anim, -1, self:getAnimationTime(self.currentExtraObject.anim), true); |
567 | end |
568 | self.currentExtraObject = nil; |
569 | end; |
570 | if self.currentInputFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then |
571 | local name = FruitUtil.fruitIndexToDesc[self.currentInputFruitType].name; |
572 | local extraObject = self.fruitExtraObjects[name]; |
573 | if extraObject ~= nil then |
574 | if extraObject.node ~= nil then |
575 | setVisibility(extraObject.node, true); |
576 | end; |
577 | if extraObject.anim ~= nil and self.playAnimation ~= nil then |
578 | self:playAnimation(extraObject.anim, 1, self:getAnimationTime(extraObject.anim), true); |
579 | end |
580 | self.currentExtraObject = extraObject; |
581 | end; |
582 | end; |
583 | end; |
584 | |
585 | function Cutter:loadTestAreaFromXML(testArea, xmlFile, key) |
586 | local start = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#startIndex")); |
587 | local width = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#widthIndex")); |
588 | local height = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#heightIndex")); |
589 | |
590 | if start ~= nil and width ~= nil and height ~= nil then |
591 | testArea.start = start; |
592 | testArea.width = width; |
593 | testArea.height = height; |
594 | return true; |
595 | end; |
596 | return false; |
597 | end; |
598 | |
599 | function Cutter:getIsTestAreaActive(area) |
600 | return true; |
601 | end; |
602 | |
603 | function Cutter.getDefaultSpeedLimit() |
604 | return 10; |
605 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de