LUADOC - Farming Simulator 17

Printable Version

Combine

Description
Class for all combines
Functions

initSpecialization

Description
Called on specialization initializing
Definition
initSpecialization()
Code
17function Combine.initSpecialization()
18 WorkArea.registerAreaType("combine");
19end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
25function Combine.prerequisitesPresent(specializations)
26 return (SpecializationUtil.hasSpecialization(Drivable, specializations) or SpecializationUtil.hasSpecialization(Attachable, specializations)) and
27 SpecializationUtil.hasSpecialization(WorkArea, specializations) and
28 SpecializationUtil.hasSpecialization(Overloading, specializations) and
29 SpecializationUtil.hasSpecialization(Pipe, specializations) and
30 SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations);
31end

preLoad

Description
Called before loading
Definition
preLoad(table savegame)
Arguments
tablesavegamesavegame
Code
36function Combine:preLoad(savegame)
37 self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Combine.loadWorkAreaFromXML);
38end

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
43function Combine:load(savegame)
44 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.strawParticleSystems#toggleTime", "vehicle.combine#toggleTime")
45 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.chopperParticleSystems#toggleTime", "vehicle.combine#toggleTime")
46 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.chopperParticleSystems", "vehicle.combine.chopperParticleSystems")
47 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.strawParticleSystems", "vehicle.combine.strawParticleSystems")
48 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.allowThreshingDuringRain", "vehicle.combine#allowThreshingDuringRain")
49 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.chopperSwitch#available", "vehicle.combine.chopperSwitch#available")
50 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.combineThreshingFillParticleSystem", "vehicle.combine.threshingFillParticleSystem")
51 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.combineThreshingScrollers.combineThreshingScroller", "vehicle.combine.threshingScrollers.threshingScroller")
52 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.combineThreshingFillScrollers.combineThreshingFillScroller", "vehicle.combine.threshingFillScrollers.threshingFillScroller")
53 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.combineThreshingFillParticleSystems", "vehicle.combine.threshingFillParticleSystems")
54 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.chopperEffect", "vehicle.combine.chopperEffect")
55 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.strawEffect", "vehicle.combine.strawEffect")
56 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fillEffect", "vehicle.combine.fillEffect")
57 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.threshingStartAnimation", "vehicle.combine.threshingStartAnimation")
58 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.threshingFold", "vehicle.combine.threshingFold")
59
60
61 self.getIsCutterFruitTypeAllowed = Combine.getIsCutterFruitTypeAllowed;
62 self.setWorkedHectars = Combine.setWorkedHectars;
63 self.getIsThreshingAllowed = Combine.getIsThreshingAllowed;
64 self.setIsStrawEnabled = Combine.setIsStrawEnabled;
65 self.getNeedsCutterFolding = Combine.getNeedsCutterFolding;
66 self.processCombineAreas = Combine.processCombineAreas;
67 self.getIsFoldAllowed = Utils.overwrittenFunction(self.getIsFoldAllowed, Combine.getIsFoldAllowed);
68 self.getTurnedOnNotAllowedWarning = Utils.overwrittenFunction(self.getTurnedOnNotAllowedWarning, Combine.getTurnedOnNotAllowedWarning);
69 self.applyInitialAnimation = Utils.overwrittenFunction(self.applyInitialAnimation, Combine.applyInitialAnimation);
70 self.getFillLevelInformation = Utils.overwrittenFunction(self.getFillLevelInformation, Combine.getFillLevelInformation);
71 self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, Combine.getIsTurnedOnAllowed);
72 self.addCutterArea = Utils.overwrittenFunction(self.addCutterArea, Combine.addCutterArea);
73
74 self.startThreshing = SpecializationUtil.callSpecializationsFunction("startThreshing");
75 self.stopThreshing = SpecializationUtil.callSpecializationsFunction("stopThreshing");
76 self.setCombineIsFilling = SpecializationUtil.callSpecializationsFunction("setCombineIsFilling");
77 self.setChopperPSEnabled = SpecializationUtil.callSpecializationsFunction("setChopperPSEnabled");
78 self.setStrawPSEnabled = SpecializationUtil.callSpecializationsFunction("setStrawPSEnabled");
79
80 if self.isClient then
81 self.combineTurnedOnRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "combine", self.components);
82
83 self.sampleThreshingStart = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.threshingStartSound", nil, self.baseDirectory);
84 self.sampleThreshing = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.threshingSound", nil, self.baseDirectory, self.components[1].node);
85 self.sampleThreshingStop = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.threshingStopSound", nil, self.baseDirectory);
86 if self.sampleThreshing ~= nil and self.sampleThreshing.sample ~= nil then
87 self.sampleThreshing.cuttingPitchOffset = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.threshingSound#cuttingPitchOffset"), self.sampleThreshing.pitchOffset);
88 self.sampleThreshing.lastCuttingPitchTime = 0;
89 self.sampleThreshing.currentPitchOffset = self.sampleThreshing.pitchOffset;
90 end
91
92 local loadParticleSystem = function(targetTable, name, defaultTableName)
93 local i = 0;
94 while true do
95 local key = string.format("vehicle.combine."..name.."s."..name.."(%d)", i);
96 local t = getXMLString(self.xmlFile, key .. "#type");
97 if t == nil then
98 break;
99 end
100 local desc = FruitUtil.fruitTypes[t];
101 if desc ~= nil then
102 local fillType = FruitUtil.fruitTypeToFillType[desc.index]
103 if fillType == nil then
104 print("Error: (Combine) Could not resolve '"..tostring(t).."' into valid fill type!");
105 else
106 if targetTable[fillType] == nil then
107 targetTable[fillType] = {}
108 end
109 local currentPS = {}
110 ParticleUtil.loadParticleSystem(self.xmlFile, currentPS, key, self.components, false, nil, self.baseDirectory);
111 table.insert(targetTable[fillType], currentPS)
112 if defaultTableName ~= nil and self[defaultTableName] == nil then
113 self[defaultTableName] = currentPS;
114 end
115 end
116 end
117 i = i + 1;
118 end
119
120 local i = 0
121 while true do
122 local key = string.format("vehicle.combine."..name.."s.emitterShape(%d)", i);
123 if not hasXMLProperty(self.xmlFile, key) then
124 break
125 end
126
127 local emitterShape = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node"));
128 local particleType = getXMLString(self.xmlFile, key.."#particleType")
129 if emitterShape ~= nil then
130 for index, _ in pairs(self.fillUnits) do
131 for fillType, _ in pairs(self:getUnitFillTypes(index)) do
132 local particleSystem = MaterialUtil.getParticleSystem(fillType, particleType)
133 if particleSystem ~= nil then
134 if targetTable[fillType] == nil then
135 targetTable[fillType] = {}
136 end
137 local ps = ParticleUtil.copyParticleSystem(self.xmlFile, key, particleSystem, emitterShape)
138 table.insert(targetTable[fillType], ps)
139 if defaultTableName ~= nil and self[defaultTableName] == nil then
140 self[defaultTableName] = ps;
141 end
142 end
143 end
144 end
145 end
146 i = i + 1
147 end
148 end
149
150 self.chopperParticleSystems = {}
151 loadParticleSystem(self.chopperParticleSystems, "chopperParticleSystem", "defaultChopperParticleSystem")
152
153 self.strawParticleSystems = {}
154 loadParticleSystem(self.strawParticleSystems, "strawParticleSystem", "defaultStrawParticleSystem")
155
156 self.combineThreshingFillParticleSystems = {}
157 loadParticleSystem(self.combineThreshingFillParticleSystems, "threshingFillParticleSystem", nil)
158
159
160 self.chopperEffects = EffectManager:loadEffect(self.xmlFile, "vehicle.combine.chopperEffect", self.components, self);
161 self.strawEffects = EffectManager:loadEffect(self.xmlFile, "vehicle.combine.strawEffect", self.components, self);
162 self.fillEffects = EffectManager:loadEffect(self.xmlFile, "vehicle.combine.fillEffect", self.components, self);
163
164 self.combineThreshingScrollers = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.combine.threshingScrollers.threshingScroller", {}, false);
165 self.combineThreshingFillScrollers = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.combine.threshingFillScrollers.threshingFillScroller", {}, true);
166
167 self.combineRotationNodes = {};
168 local i=0;
169 while true do
170 local key = string.format("vehicle.combine.rotationNodes.rotationNode(%d)", i);
171 if not hasXMLProperty(self.xmlFile, key) then
172 break;
173 end
174 local node = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key .. "#index"));
175 if node ~= nil then
176 local entry = {};
177 entry.node = node;
178 entry.rotAxis = getXMLInt(self.xmlFile, key .. "#rotAxis");
179 entry.rotSpeed = Utils.getRadiansFromString(getXMLString(self.xmlFile, key .. "#rotSpeed"), 2);
180 entry.rotSpeed[1], entry.rotSpeed[2] = entry.rotSpeed[1]/1000, entry.rotSpeed[2]/1000;
181 entry.curSpeed = 0;
182 entry.fillLevelPercentageToChangeSpeed = getXMLFloat(self.xmlFile, key .. "#fillLevelPercentageToChangeSpeed");
183 entry.rotAcceleration = math.rad( (getXMLFloat(self.xmlFile, key .. "#rotAcceleration")) ) / (1000*1000);
184 table.insert(self.combineRotationNodes, entry);
185 end
186 i=i+1;
187 end
188 end
189
190 self.combineFillToggleTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.combine.threshingFillParticleSystem#toggleTime"), Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.combine.threshingFillScrollers#toggleTime"), 2500));
191 self.combineFillEnableTime = nil;
192 self.combineFillDisableTime = nil;
193
194 -- straw buffer
195 self.strawToggleTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.combine#toggleTime"), 2500);
196 self.strawBufferDuration = 200
197 local bufferItems = math.ceil(self.strawToggleTime / self.strawBufferDuration)
198 if bufferItems > 20 then
199 bufferItems = 20
200 self.strawBufferDuration = self.strawToggleTime / 20
201 end
202 self.strawBufferFillIndex = 1
203 self.strawBufferDropIndex = self.strawBufferFillIndex + 1
204 bufferItems = bufferItems + 1 -- add 1 extra buffers
205 self.strawBufferFillIndexTimer = self.strawBufferDuration
206 self.strawBufferCheckTimer = self.strawBufferDuration*bufferItems
207 self.strawBufferDropValue = 0
208 self.strawToDrop = 0;
209 self.strawBuffer = {}
210 -- initialize buffer
211 for i=1, bufferItems do
212 table.insert(self.strawBuffer, 0)
213 end
214
215 self.chopperSwitchAvailable = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.combine.chopperSwitch#available"), false);
216 if self.chopperSwitchAvailable then
217 self.toggleChopperAnimName = Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.combine.chopperSwitch#animName"), "toggleChopper");
218 self.toggleChopperWarningTime = 0;
219 self:setIsStrawEnabled(true, true, true);
220 end
221
222 self.threshingStartAnimation = getXMLString(self.xmlFile, "vehicle.combine.threshingStartAnimation#name");
223 self.threshingStartAnimationSpeedScale = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.combine.threshingStartAnimation#speedScale"), 1);
224 self.threshingStartAnimationInitialIsStarted = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.combine.threshingStartAnimation#initialIsStarted"), false);
225
226 self.foldMinFillLevel = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.combine.threshingFold#foldMinFillLevel"), 0);
227 self.foldMaxFillLevel = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.combine.threshingFold#foldMaxFillLevel"), 0);
228 self.allowFoldWhileThreshing = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.combine.threshingFold#allowFoldWhileThreshing"), false);
229
230 self.allowThreshingDuringRain = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.combine#allowThreshingDuringRain"), false);
231 self.allowsThreshing = true;
232 self.combineIsFilling = false;
233 self.strawPSenabled = false;
234 self.chopperPSenabled = false;
235 self.threshingScale = 1;
236 self.isStrawEnabled = true;
237 self.lastLostFillLevel = 0;
238 self.attachedCutters = {};
239 self.numAttachedCutters = 0;
240 self.updateShaderParticleTime = 0;
241 self.lastArea = 0;
242 self.lastAreaZeroTime = 0;
243 self.lastAreaNonZeroTime = -1000000;
244 self.lastCuttersArea = 0;
245 self.lastCuttersAreaTime = -10000;
246 self.lastInputFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
247 self.lastValidInputFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
248 self.lastCuttersFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
249 self.lastCuttersInputFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
250 self.lastWorkedHectars = 0;
251 self.workedHectars = 0;
252 self.workedHectarsHud = VehicleHudUtils.loadHud(self, self.xmlFile, "workedHectars");
253 self.combine = {};
254 --self.combine.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.combine#fillUnitIndex"), 1);
255 --self.combine.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.combine#unloadInfoIndex"), 1);
256 --self.combine.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.combine#loadInfoIndex"), 1);
257 self.combine.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.combine#dischargeInfoIndex"), 1);
258
259 self.remainingWindrowToDrop = 0;
260
261 self.combineDirtyFlag = self:getNextDirtyFlag();
262end

postLoad

Description
Called after loading
Definition
postLoad(table savegame)
Arguments
tablesavegamesavegame
Code
267function Combine:postLoad(savegame)
268 if self.onStartReel ~= nil and self.onStopReel ~= nil then
269 self.attachedCutters[self] = {};
270 self.numAttachedCutters = self.numAttachedCutters+1;
271 end
272
273 if savegame ~= nil then
274 if self.chopperSwitchAvailable then
275 local isStrawEnabled = Utils.getNoNil(getXMLBool(savegame.xmlFile, savegame.key .. "#isStrawEnabled"), self.isStrawEnabled);
276 self:setIsStrawEnabled(isStrawEnabled, true, true);
277 end
278 self:setWorkedHectars(Utils.getNoNil(getXMLFloat(savegame.xmlFile, savegame.key .. "#workedHectars"), self.workedHectars));
279
280 if savegame.resetVehicles and self.foldAnimTime ~= nil then --and (self.fillLevel > self.foldMaxFillLevel or self.fillLevel < self.foldMinFillLevel) then
281 local animTime = getXMLFloat(savegame.xmlFile, savegame.key.."#foldAnimTime");
282 if animTime ~= nil then
283 Foldable.setAnimTime(self, animTime, false)
284 end
285 end
286 end
287end

applyInitialAnimation

Description
Called at the end of loading to apply an initial animation state
Definition
applyInitialAnimation()
Code
291function Combine:applyInitialAnimation(superFunc)
292 if self.threshingStartAnimation ~= nil and self.playAnimation ~= nil and self.threshingStartAnimationInitialIsStarted then
293 self:playAnimation(self.threshingStartAnimation, -self.threshingStartAnimationSpeedScale, nil, true);
294 AnimatedVehicle.updateAnimations(self, 99999999);
295 end
296 if superFunc ~= nil then
297 superFunc(self);
298 end
299end

delete

Description
Called on deleting
Definition
delete()
Code
303function Combine:delete()
304 if self.isClient then
305 EffectManager:deleteEffects(self.fillEffects);
306 EffectManager:deleteEffects(self.strawEffects);
307 EffectManager:deleteEffects(self.chopperEffects);
308
309 for _,v in pairs(self.chopperParticleSystems) do
310 ParticleUtil.deleteParticleSystems(v)
311 end
312 for _,v in pairs(self.strawParticleSystems) do
313 ParticleUtil.deleteParticleSystems(v)
314 end
315 for _,v in pairs(self.combineThreshingFillParticleSystems) do
316 ParticleUtil.deleteParticleSystems(v)
317 end
318 SoundUtil.deleteSample(self.sampleThreshingStart);
319 SoundUtil.deleteSample(self.sampleThreshingStop);
320 SoundUtil.deleteSample(self.sampleThreshing);
321 end
322end

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
328function Combine:readStream(streamId, connection)
329 self.lastValidInputFruitType = streamReadUIntN(streamId, FruitUtil.sendNumBits);
330 local combineIsFilling = streamReadBool(streamId);
331 local chopperPSenabled = streamReadBool(streamId);
332 local strawPSenabled = streamReadBool(streamId);
333
334 self:setCombineIsFilling(combineIsFilling, false, true);
335 self:setChopperPSEnabled(chopperPSenabled, false, true);
336 self:setStrawPSEnabled(strawPSenabled, false, true);
337
338 local isStrawEnabled = streamReadBool(streamId);
339 self:setIsStrawEnabled(isStrawEnabled, true);
340
341 local workedHectars = streamReadFloat32(streamId);
342 self:setWorkedHectars(workedHectars);
343end

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
349function Combine:writeStream(streamId, connection)
350 streamWriteUIntN(streamId, self.lastValidInputFruitType, FruitUtil.sendNumBits);
351 streamWriteBool(streamId, self.combineIsFilling);
352 streamWriteBool(streamId, self.chopperPSenabled);
353 streamWriteBool(streamId, self.strawPSenabled);
354 streamWriteBool(streamId, self.isStrawEnabled);
355 streamWriteFloat32(streamId, self.workedHectars);
356end

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
363function Combine:readUpdateStream(streamId, timestamp, connection)
364 if connection:getIsServer() then
365 if streamReadBool(streamId) then
366 self.lastValidInputFruitType = streamReadUIntN(streamId, FruitUtil.sendNumBits);
367
368 if not self.chopperSwitchAvailable then
369 if self:getUnitLastValidFillType(self.overloading.fillUnitIndex) ~= FillUtil.FILLTYPE_UNKNOWN then
370 local fruitType = FruitUtil.fillTypeToFruitType[self:getUnitLastValidFillType(self.overloading.fillUnitIndex)];
371 local fruitDesc = FruitUtil.fruitIndexToDesc[fruitType];
372 if fruitDesc ~= nil then
373 self.isStrawEnabled = not fruitDesc.hasWindrow;
374 else
375 self.isStrawEnabled = false;
376 end
377 else
378 self.isStrawEnabled = false;
379 end
380 end
381
382 local combineIsFilling = streamReadBool(streamId);
383 local chopperPSenabled = streamReadBool(streamId);
384 local strawPSenabled = streamReadBool(streamId);
385 self:setCombineIsFilling(combineIsFilling, false, true);
386 self:setChopperPSEnabled(chopperPSenabled, false, true);
387 self:setStrawPSEnabled(strawPSenabled, false, true);
388 end
389 end
390end

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
397function Combine:writeUpdateStream(streamId, connection, dirtyMask)
398 if not connection:getIsServer() then
399 if streamWriteBool(streamId, bitAND(dirtyMask, self.combineDirtyFlag) ~= 0) then
400 streamWriteUIntN(streamId, self.lastValidInputFruitType, FruitUtil.sendNumBits);
401 streamWriteBool(streamId, self.combineIsFilling);
402 streamWriteBool(streamId, self.chopperPSenabled);
403 streamWriteBool(streamId, self.strawPSenabled);
404 end
405 end
406end

getSaveAttributesAndNodes

Description
Returns attributes and nodes to save
Definition
getSaveAttributesAndNodes(table nodeIdent)
Arguments
tablenodeIdentnode ident
Return Values
stringattributesattributes
stringnodesnodes
Code
413function Combine:getSaveAttributesAndNodes(nodeIdent)
414 local attributes = "";
415 if self.chopperSwitchAvailable then
416 attributes = 'isStrawEnabled="' .. tostring(self.isStrawEnabled) ..'" workedHectars="' .. tostring(self.workedHectars) ..'"';
417 end
418
419 return attributes, nil;
420end

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
431function Combine:update(dt)
432
433 if self:getIsActive() then
434 if self.isClient then
435 if self:getIsTurnedOn() then
436 if self:getIsActiveForSound() then
437 if not SoundUtil.isSamplePlaying(self.sampleThreshingStart, 1.8*dt) then
438 SoundUtil.playSample(self.sampleThreshing, 0, 0, nil);
439 end
440 SoundUtil.stop3DSample(self.sampleThreshing);
441 else
442 SoundUtil.play3DSample(self.sampleThreshing);
443 end
444
445 if self.sampleThreshing ~= nil and self.sampleThreshing.sample ~= nil and self.sampleThreshing.cuttingPitchOffset ~= nil then
446
447 for object,_ in pairs(self.attachedCutters) do
448 if object.lastCutterAreaBiggerZero == true then
449 self.sampleThreshing.lastCuttingPitchTime = g_currentMission.time;
450 break;
451 end
452 end
453
454 local pitchOffset = self.sampleThreshing.pitchOffset;
455
456 if (self.sampleThreshing.lastCuttingPitchTime + 500) > g_currentMission.time then
457 pitchOffset = self.sampleThreshing.cuttingPitchOffset;
458 end
459
460 local pitchDiff = math.abs(self.sampleThreshing.pitchOffset - self.sampleThreshing.cuttingPitchOffset);
461
462 if pitchOffset > self.sampleThreshing.currentPitchOffset then
463 self.sampleThreshing.currentPitchOffset = math.min(pitchOffset, self.sampleThreshing.currentPitchOffset + (0.00066 * dt * pitchDiff));
464 elseif pitchOffset < self.sampleThreshing.currentPitchOffset then
465 self.sampleThreshing.currentPitchOffset = math.max(pitchOffset, self.sampleThreshing.currentPitchOffset - (0.00066 * dt * pitchDiff));
466 end
467
468 SoundUtil.setSamplePitch(self.sampleThreshing, self.sampleThreshing.currentPitchOffset);
469 end
470 end
471
472
473 if self.chopperSwitchAvailable then
474 local fruitType = FruitUtil.fillTypeToFruitType[self:getUnitFillType(self.overloading.fillUnitIndex)]
475
476 if self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() then
477 if InputBinding.hasEvent(InputBinding.TOGGLE_CHOPPER) then
478 if fruitType ~= nil and fruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
479 local fruitDesc = FruitUtil.fruitIndexToDesc[fruitType];
480 if fruitDesc.hasWindrow then
481 self:setIsStrawEnabled(not self.isStrawEnabled);
482 else
483 self.toggleChopperWarningTime = g_currentMission.time + 2000;
484 end
485 else
486 self:setIsStrawEnabled(not self.isStrawEnabled);
487 end
488 end
489 end
490
491 -- check for changes while threshing, e.g. activated straw swath and then start threshing rape (has no windrow)
492 if self.isStrawEnabled and fruitType ~= nil and fruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
493 local fruitDesc = FruitUtil.fruitIndexToDesc[fruitType];
494 if not fruitDesc.hasWindrow then
495 self:setIsStrawEnabled(false);
496 end
497 end
498 end
499 end
500
501 if self.isServer then
502 if self:getUnitFillLevel(self.overloading.fillUnitIndex) >= self:getUnitCapacity(self.overloading.fillUnitIndex) and self:getUnitCapacity(self.overloading.fillUnitIndex) > 0 then
503 self:setIsTurnedOn(false);
504 end
505 end
506 end
507
508 if self.isClient then
509 Utils.updateRotationNodes(self, self.combineTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn());
510 Utils.updateScrollers(self.combineThreshingScrollers, dt, self:getIsActive() and self:getIsTurnedOn());
511
512 if self.combineThreshingFillScrollers ~= nil then
513 if self:getIsTurnedOn() and self.combineIsFilling then
514 Utils.updateScrollers(self.combineThreshingFillScrollers, dt, true, true, self:getUnitLastValidFillType(self.overloading.fillUnitIndex));
515 else
516 if self.combineThreshingFillScrollers.isRunning then
517 Utils.updateScrollers(self.combineThreshingFillScrollers, dt, false, true, self:getUnitLastValidFillType(self.overloading.fillUnitIndex));
518 else
519 Utils.updateScrollers(self.combineThreshingFillScrollers, dt, false, false, self:getUnitLastValidFillType(self.overloading.fillUnitIndex));
520 end
521 end
522 end;
523
524 if self.lastCombineThreshingFillScrollers ~= nil then
525 Utils.updateScrollers(self.lastCombineThreshingFillScrollers, dt, false, false);
526 self.lastCombineThreshingFillScrollers = nil;
527 end
528
529 if self.combineRotationNodes ~= nil then
530 local fillLevelPercentage = self:getUnitFillLevel(self.overloading.fillUnitIndex) / self:getUnitCapacity(self.overloading.fillUnitIndex);
531 local doRotate = self:getIsTurnedOn();
532 for _,node in pairs(self.combineRotationNodes) do
533 local targetSpeed = 0;
534 if doRotate then
535 targetSpeed = node.rotSpeed[1];
536 if fillLevelPercentage > node.fillLevelPercentageToChangeSpeed then
537 targetSpeed = node.rotSpeed[2];
538 end
539 end
540
541 if node.curSpeed < targetSpeed then
542 node.curSpeed = math.min(targetSpeed, node.curSpeed + (dt*node.rotAcceleration));
543 elseif node.curSpeed > targetSpeed then
544 node.curSpeed = math.max(targetSpeed, node.curSpeed - (dt*node.rotAcceleration));
545 end
546
547 local rot = node.curSpeed * dt;
548 if math.abs(rot) > 0 then
549 if node.rotAxis == 2 then
550 rotate(node.node, 0, rot, 0);
551 elseif node.rotAxis == 1 then
552 rotate(node.node, rot, 0, 0);
553 else
554 rotate(node.node, 0, 0, rot);
555 end
556
557 end
558
559 end
560 end
561 end
562end

updateTick

Description
Called on update tick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
567function Combine:updateTick(dt)
568 if self.isServer then
569 self.lastArea = self.lastCuttersArea;
570 self.lastAreaZeroTime = self.lastAreaZeroTime + dt;
571 if self.lastArea > 0 then
572 self.lastAreaZeroTime = 0;
573 self.lastAreaNonZeroTime = g_currentMission.time;
574 end
575 self.lastInputFruitType = self.lastCuttersInputFruitType;
576 self.lastCuttersArea = 0;
577 self.lastCuttersInputFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
578 self.lastCuttersFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
579
580 if self.lastInputFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
581 self.lastValidInputFruitType = self.lastInputFruitType;
582 end
583
584 if self:getIsActive() then
585 self.strawBufferCheckTimer = (#self.strawBuffer+2)*self.strawBufferDuration
586
587 if self.lastAreaZeroTime > 500 then
588 if self.combineFillDisableTime == nil then
589 self.combineFillDisableTime = g_currentMission.time + self.combineFillToggleTime;
590 end
591 end
592 if self.combineFillEnableTime ~= nil and self.combineFillEnableTime <= g_currentMission.time then
593 self:setCombineIsFilling(true, false, false);
594 self.combineFillEnableTime = nil;
595 end
596 if self.combineFillDisableTime ~= nil and self.combineFillDisableTime <= g_currentMission.time then
597 self:setCombineIsFilling(false, false, false);
598 self.combineFillDisableTime = nil;
599 end
600
601 if self:getIsTurnedOn() then
602 g_currentMission.missionStats:updateStats("threshedTime", dt/(1000*60));
603 g_currentMission.missionStats:updateStats("workedTime", dt/(1000*60));
604 end
605 else
606 if self.strawBufferCheckTimer >= 0 then
607 self.strawBufferCheckTimer = self.strawBufferCheckTimer - dt
608 end
609 end
610
611 if self.strawBufferCheckTimer >= 0 then
612 self.strawBufferFillIndexTimer = self.strawBufferFillIndexTimer - dt
613 if self.strawBufferFillIndexTimer < 0 then
614 self.strawBufferFillIndex = self.strawBufferFillIndex + 1
615 if self.strawBufferFillIndex > #self.strawBuffer then
616 self.strawBufferFillIndex = 1
617 end
618 self.strawBufferFillIndexTimer = self.strawBufferDuration
619
620
621 self.strawBufferDropIndex = self.strawBufferDropIndex + 1
622 if self.strawBufferDropIndex > #self.strawBuffer then
623 self.strawBufferDropIndex = 1
624 end
625 self.strawBufferDropValue = self.strawBuffer[self.strawBufferDropIndex]
626 end
627
628 local isStrawEffectEnabled = false
629 local isChopperEffectEnabled = false
630
631 if self:getUnitLastValidFillType(self.overloading.fillUnitIndex) ~= FillUtil.FILLTYPE_UNKNOWN then
632 local litersPerFrame = math.min(self.strawBufferDropValue * (dt/self.strawBufferDuration), self.strawBuffer[self.strawBufferDropIndex])
633
634 if self.isStrawEnabled then
635 local literToDrop = litersPerFrame + self.strawToDrop
636 local fruitDesc = FruitUtil.fruitIndexToDesc[FruitUtil.fillTypeToFruitType[self:getUnitLastValidFillType(self.overloading.fillUnitIndex)]];
637 if fruitDesc ~= nil and fruitDesc.windrowLiterPerSqm ~= nil then
638 local windrowFillType = FruitUtil.fruitTypeToWindrowFillType[fruitDesc.index];
639
640 if literToDrop > 0 and windrowFillType ~= nil then
641 isStrawEffectEnabled = litersPerFrame > 0
642 local typedWorkAreas = self:getTypedWorkAreas(WorkArea.AREATYPE_COMBINE);
643 local value = literToDrop/table.getn(typedWorkAreas);
644
645 for _, workArea in pairs(typedWorkAreas) do
646 local sx,sy,sz = getWorldTranslation(workArea.start);
647 local ex,ey,ez = getWorldTranslation(workArea.width);
648 local dropped, lineOffset = TipUtil.tipToGroundAroundLine(self, value, windrowFillType, sx,sy,sz, ex,ey,ez, 0, nil, self.combineLineOffset, false, nil, false);
649 self.combineLineOffset = lineOffset;
650 self.strawToDrop = value-dropped
651 end
652 end
653 end
654 else
655 isChopperEffectEnabled = litersPerFrame > 0
656 end
657
658 -- remove straw from buffer if chopper is active to allow instant switch to straw
659 self.strawBuffer[self.strawBufferDropIndex] = self.strawBuffer[self.strawBufferDropIndex] - litersPerFrame
660 end
661
662 local currentDropIndex = self.strawBufferDropIndex
663 for i=1, 2 do
664 currentDropIndex = currentDropIndex + 1
665 if currentDropIndex > #self.strawBuffer then
666 currentDropIndex = 1
667 end
668 if self.strawBuffer[currentDropIndex] > 0 then
669 if self.chopperPSenabled and not self.isStrawEnabled and not isChopperEffectEnabled then
670 isChopperEffectEnabled = true
671 end
672 if self.strawPSenabled and self.isStrawEnabled and not isStrawEffectEnabled then
673 isStrawEffectEnabled = true
674 end
675 end
676 end
677
678 self:setChopperPSEnabled(isChopperEffectEnabled, false, false);
679 self:setStrawPSEnabled(isStrawEffectEnabled, false, false);
680 end
681
682 if self:getUnitCapacity(self.overloading.fillUnitIndex) <= 0 then
683 local fillLevel = self:getUnitFillLevel(self.overloading.fillUnitIndex);
684 self.lastLostFillLevel = fillLevel;
685 if fillLevel > 0 then
686 self:setUnitFillLevel(self.overloading.fillUnitIndex, 0, self:getUnitFillType(self.overloading.fillUnitIndex), false);
687 end
688 end
689
690 if self.combineIsFilling ~= self.sentCombineIsFilling or
691 self.chopperPSenabled ~= self.sentChopperPSenabled or
692 self.strawPSenabled ~= self.sentStrawPSenabled
693 then
694 self:raiseDirtyFlags(self.combineDirtyFlag);
695 self.sentCombineIsFilling = self.combineIsFilling;
696 self.sentChopperPSenabled = self.chopperPSenabled;
697 self.sentStrawPSenabled = self.strawPSenabled;
698 end
699 end
700end

draw

Description
Called on draw
Definition
draw()
Code
704function Combine:draw()
705 if self.isClient then
706 local percent = 0;
707 if self:getUnitCapacity(self.overloading.fillUnitIndex) > 0 then
708 local fillLevel = math.max(self:getUnitFillLevel(self.overloading.fillUnitIndex), self.lastLostFillLevel);
709 local capacity = self:getUnitCapacity(self.overloading.fillUnitIndex);
710 percent = fillLevel/capacity*100;
711 if self.pipeCurrentState ~= nil and self.pipeCurrentState == 2 and fillLevel > 0 and not self.overloading.didOverload and not self.dischargeToGround then
712 g_currentMission:addExtraPrintText(g_i18n:getText("info_movePipeOverTrailer"));
713 elseif fillLevel == capacity then
714 g_currentMission:addExtraPrintText(g_i18n:getText("info_emptyTankToContinueThreshing"));
715 end
716 end
717
718 if self:getIsTurnedOn() and not self:getIsThreshingAllowed(false) then
719 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_doNotThreshDuringRainOrHail"), 2000);
720 end
721
722 if self.chopperSwitchAvailable then
723 if self:getIsActiveForInput() then
724 local fruitType = FruitUtil.fillTypeToFruitType[self:getUnitFillType(self.overloading.fillUnitIndex)]
725 local fruitDesc = FruitUtil.fruitIndexToDesc[fruitType];
726 if fruitType == nil or fruitDesc.hasWindrow then
727 if self.isStrawEnabled then
728 g_currentMission:addHelpButtonText(g_i18n:getText("action_disableStrawSwath"), InputBinding.TOGGLE_CHOPPER, nil, GS_PRIO_NORMAL);
729 else
730 g_currentMission:addHelpButtonText(g_i18n:getText("action_enableStrawSwath"), InputBinding.TOGGLE_CHOPPER, nil, GS_PRIO_NORMAL);
731 end
732 end
733 end
734
735 if self.toggleChopperWarningTime > g_currentMission.time then
736 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_couldNotToggleChopper"), 2000);
737 end
738 end
739
740 -- renderText(0.5, 0.9, 0.015, "StrawToDrop: " .. self.strawToDrop)
741 -- for k, buffer in pairs(self.strawBuffer) do
742 -- local text = "Buffer "..k..": " .. buffer
743 -- if self.strawBufferDropIndex == k then
744 -- text = text .. " <-- drop"
745 -- end
746 -- if self.strawBufferFillIndex == k then
747 -- text = text .. " <-- fill"
748 -- end
749 -- renderText(0.5, 0.9-k*0.015, 0.015, text)
750 -- end
751 end
752end

onDeactivate

Description
Called on deactivate
Definition
onDeactivate()
Code
756function Combine:onDeactivate()
757 self:setChopperPSEnabled(false, false, true);
758 self:setStrawPSEnabled(false, false, true);
759 self:setCombineIsFilling(false, false, true);
760
761 self.combineFillEnableTime = nil;
762 self.combineFillDisableTime = nil;
763end

onDeactivateSounds

Description
Called on deactivating sounds
Definition
onDeactivateSounds()
Code
767function Combine:onDeactivateSounds()
768 if self.isClient then
769 SoundUtil.stopSample(self.sampleThreshing, true);
770 SoundUtil.stopSample(self.sampleThreshingStart, true);
771 end
772end

onAttachImplement

Description
Called on attaching a implement
Definition
onAttachImplement(table implement)
Arguments
tableimplementimplement to attach
Code
777function Combine:onAttachImplement(implement)
778 local object = implement.object;
779 if object.attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTER or object.attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTERHARVESTER then
780 self.attachedCutters[object] = implement;
781 self.numAttachedCutters = self.numAttachedCutters+1;
782 end
783end

onDetachImplement

Description
Called on detaching a implement
Definition
onDetachImplement(integer implementIndex)
Arguments
integerimplementIndexindex of implement to detach
Code
788function Combine:onDetachImplement(implementIndex)
789 local object = self.attachedImplements[implementIndex].object;
790 if object ~= nil then
791 if object.attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTER or object.attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTERHARVESTER then
792 self.numAttachedCutters = self.numAttachedCutters-1;
793 if self.numAttachedCutters == 0 then
794 self:setIsTurnedOn(false, true);
795 end
796 self.attachedCutters[object] = nil;
797 end
798 end
799end

startThreshing

Description
Start threshing
Definition
startThreshing()
Code
803function Combine:startThreshing()
804 if self.numAttachedCutters > 0 then
805 for cutter,implement in pairs(self.attachedCutters) do
806 if cutter ~= self then
807 self:setJointMoveDown(implement.jointDescIndex, true, true);
808 end
809 cutter:onStartReel();
810 end
811 if self.threshingStartAnimation ~= nil and self.playAnimation ~= nil then
812 self:playAnimation(self.threshingStartAnimation, self.threshingStartAnimationSpeedScale, self:getAnimationTime(self.threshingStartAnimation), true);
813 end
814
815 if self.isClient then
816 SoundUtil.stopSample(self.sampleThreshingStop, true);
817 if self:getIsActiveForSound() then
818 SoundUtil.playSample(self.sampleThreshingStart, 1, 0, nil);
819 end
820 end
821 end
822end

stopThreshing

Description
Stop threshing
Definition
stopThreshing()
Code
826function Combine:stopThreshing()
827 if self.isClient then
828 SoundUtil.stopSample(self.sampleThreshing, true);
829 SoundUtil.stopSample(self.sampleThreshingStart, true);
830 SoundUtil.stop3DSample(self.sampleThreshing);
831
832 if self:getIsActiveForSound() then
833 SoundUtil.playSample(self.sampleThreshingStop, 1, 0, nil);
834 end
835 end
836
837 self:setCombineIsFilling(false, false, true);
838
839 for cutter,implement in pairs(self.attachedCutters) do
840 if cutter ~= self then
841 self:setJointMoveDown(implement.jointDescIndex, false, true);
842 end
843 cutter:onStopReel();
844 end
845 if self.threshingStartAnimation ~= nil and self.playAnimation ~= nil then
846 self:playAnimation(self.threshingStartAnimation, -self.threshingStartAnimationSpeedScale, self:getAnimationTime(self.threshingStartAnimation), true);
847 end
848end

setWorkedHectars

Description
Set worked hectars value and updated hud
Definition
setWorkedHectars(float hectars)
Arguments
floathectarsnew hectars value
Code
853function Combine:setWorkedHectars(hectars)
854 self.workedHectars = hectars;
855 if self.workedHectarsHud ~= nil and math.abs(self.lastWorkedHectars-self.workedHectars) > 0.1 then
856 VehicleHudUtils.setHudValue(self, self.workedHectarsHud, self.workedHectars, 9999);
857 self.lastWorkedHectars = self.workedHectars;
858 end
859end

getNeedsCutterFolding

Description
Checks if cutter needs folding and is unfolded
Definition
getNeedsCutterFolding()
Return Values
stringunfoldWarningunfold warning if cutter needs unfold, nil if not
Code
864function Combine:getNeedsCutterFolding()
865 if self.attachedCutters[self] == nil then
866 for cutter, _ in pairs(self.attachedCutters) do
867 if cutter.getIsTurnedOnAllowed ~= nil and not cutter:getIsTurnedOnAllowed(true) then
868 if (cutter.foldAnimTime > cutter.turnOnFoldMaxLimit or cutter.foldAnimTime < cutter.turnOnFoldMinLimit) then
869 return cutter.unfoldWarning;
870 end
871 end
872 end
873 end
874 return nil;
875end

getIsTurnedOnAllowed

Description
Returns if turn on is allowed
Definition
getIsTurnedOnAllowed(boolean isTurnedOn)
Arguments
booleanisTurnedOnis turned on
Return Values
booleanallowallow turn on
Code
881function Combine:getIsTurnedOnAllowed(superFunc, isTurnedOn)
882 if self.numAttachedCutters <= 0 then
883 return false;
884 else
885 if self.attachedCutters[self] == nil then
886 for cutter, _ in pairs(self.attachedCutters) do
887 if cutter.getIsTurnedOnAllowed ~= nil and not cutter:getIsTurnedOnAllowed(isTurnedOn) then
888 return false;
889 end
890 end
891 end
892 end
893
894 if superFunc ~= nil then
895 return superFunc(self, isTurnedOn);
896 end
897
898 return true;
899end

onTurnedOn

Description
Called on turn on
Definition
onTurnedOn(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
904function Combine:onTurnedOn(noEventSend)
905 self:startThreshing();
906end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
911function Combine:onTurnedOff(noEventSend)
912 self:stopThreshing();
913end

setUnitLastValidFillType

Description
Set unit last valid fill type
Definition
setUnitLastValidFillType(integer fillUnitIndex, integer lastValidFillType, boolean hasChanged)
Arguments
integerfillUnitIndexindex of fill unit
integerlastValidFillTypeindex new last valid fill type
booleanhasChangedfill type has changed
Code
920function Combine:setUnitLastValidFillType(fillUnitIndex, lastValidFillType, hasChanged)
921 if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then
922 return;
923 end
924 if fillUnitIndex == self.overloading.fillUnitIndex then
925 if self.chopperPSenabled then
926 self:setChopperPSEnabled(true, hasChanged, true);
927 end
928 if self.strawPSenabled then
929 self:setStrawPSEnabled(true, hasChanged, true);
930 end
931 if self.combineIsFilling then
932 self:setCombineIsFilling(true, hasChanged, true);
933 end
934 end
935end

setCombineIsFilling

Description
Set combine is filling
Definition
setCombineIsFilling(boolean combineIsFilling, boolean fruitTypeChanged, boolean isSynchronized)
Arguments
booleancombineIsFillingcombine is filling
booleanfruitTypeChangedfruit type has changed
booleanisSynchronizedfilling is synchronized
Code
942function Combine:setCombineIsFilling(combineIsFilling, fruitTypeChanged, isSynchronized)
943 if self.combineIsFilling ~= combineIsFilling or fruitTypeChanged then
944 self.combineIsFilling = combineIsFilling;
945 if self.isServer and isSynchronized then
946 self.sentCombineIsFilling = combineIsFilling;
947 end
948
949 if self.currentCombineThreshingFillParticleSystems ~= nil then
950 for _, ps in pairs(self.currentCombineThreshingFillParticleSystems) do
951 ParticleUtil.setEmittingState(ps, false);
952 end
953 self.currentCombineThreshingFillParticleSystems = nil;
954 end
955
956 if self.fillEffects ~= nil and (not combineIsFilling or fruitTypeChanged) then
957 EffectManager:stopEffects(self.fillEffects)
958 end
959
960 if combineIsFilling then
961 self.currentCombineThreshingFillParticleSystems = self.combineThreshingFillParticleSystems[self:getUnitLastValidFillType(self.overloading.fillUnitIndex)];
962 if self.currentCombineThreshingFillParticleSystems ~= nil then
963 for _, ps in pairs(self.currentCombineThreshingFillParticleSystems) do
964 ParticleUtil.setEmittingState(ps, true);
965 end
966 end
967 if self.fillEffects ~= nil then
968 EffectManager:setFillType(self.fillEffects, self:getUnitLastValidFillType(self.overloading.fillUnitIndex));
969 EffectManager:startEffects(self.fillEffects)
970 end
971 end
972 end
973end

setChopperPSEnabled

Description
Set chopper PS enabled
Definition
setChopperPSEnabled(boolean chopperPSenabled, boolean fruitTypeChanged, boolean isSynchronized)
Arguments
booleanchopperPSenabledset enabled
booleanfruitTypeChangedfruit type has changed
booleanisSynchronizedfilling is synchronized
Code
980function Combine:setChopperPSEnabled(chopperPSenabled, fruitTypeChanged, isSynchronized)
981 if self.chopperPSenabled ~= chopperPSenabled or fruitTypeChanged then
982 if self.currentChopperParticleSystems ~= nil then
983 for _, ps in pairs(self.currentChopperParticleSystems) do
984 ParticleUtil.setEmittingState(ps, false);
985 end
986 self.currentChopperParticleSystems = nil;
987 end
988
989 if self.chopperEffects ~= nil and (not chopperPSenabled or fruitTypeChanged) then
990 EffectManager:stopEffects(self.chopperEffects)
991 end
992
993 self.chopperPSenabled = chopperPSenabled;
994 if self.isServer and isSynchronized then
995 self.sentChopperPSenabled = chopperPSenabled;
996 end
997 if chopperPSenabled and self.isClient then
998 self.currentChopperParticleSystems = self.chopperParticleSystems[self:getUnitLastValidFillType(self.overloading.fillUnitIndex)];
999 if self.currentChopperParticleSystems == nil then
1000 self.currentChopperParticleSystems = self.defaultChopperParticleSystem;
1001 end
1002 if self.currentChopperParticleSystems ~= nil then
1003 for _, ps in pairs(self.currentChopperParticleSystems) do
1004 ParticleUtil.setEmittingState(ps, true);
1005 end
1006 end
1007
1008 if self.chopperEffects ~= nil then
1009 EffectManager:setFillType(self.chopperEffects, self:getUnitLastValidFillType(self.overloading.fillUnitIndex))
1010 EffectManager:startEffects(self.chopperEffects)
1011 end
1012 end
1013 end
1014end

setStrawPSEnabled

Description
Set straw PS enabled
Definition
setStrawPSEnabled(boolean strawPSenabled, boolean fruitTypeChanged, boolean isSynchronized)
Arguments
booleanstrawPSenabledset enabled
booleanfruitTypeChangedfruit type has changed
booleanisSynchronizedfilling is synchronized
Code
1021function Combine:setStrawPSEnabled(strawPSenabled, fruitTypeChanged, isSynchronized)
1022 if self.strawPSenabled ~= strawPSenabled or fruitTypeChanged then
1023 if self.currentStrawParticleSystems ~= nil then
1024 for _, ps in pairs(self.currentStrawParticleSystems) do
1025 ParticleUtil.setEmittingState(ps, false);
1026 end
1027 self.currentStrawParticleSystems = nil;
1028 end
1029
1030 if self.strawEffects ~= nil and (not strawPSenabled or fruitTypeChanged) then
1031 EffectManager:stopEffects(self.strawEffects)
1032 end
1033
1034 self.strawPSenabled = strawPSenabled;
1035 if self.isServer and isSynchronized then
1036 self.sentStrawPSenabled = strawPSenabled;
1037 end
1038 if not strawPSenabled then
1039 self.strawToDrop = 0
1040 end
1041 if strawPSenabled and self.isClient then
1042 self.currentStrawParticleSystems = self.strawParticleSystems[self:getUnitLastValidFillType(self.overloading.fillUnitIndex)];
1043 if self.currentStrawParticleSystems == nil then
1044 self.currentStrawParticleSystems = self.defaultStrawParticleSystem;
1045 end
1046 if self.currentStrawParticleSystems ~= nil then
1047 for _, ps in pairs(self.currentStrawParticleSystems) do
1048 ParticleUtil.setEmittingState(ps, true);
1049 end
1050 end
1051
1052 if self.strawEffects ~= nil then
1053 EffectManager:setFillType(self.strawEffects, self:getUnitLastValidFillType(self.overloading.fillUnitIndex))
1054 EffectManager:startEffects(self.strawEffects);
1055 end
1056 end
1057 end
1058end

getIsCutterFruitTypeAllowed

Description
Returns if cutter allows fruit type
Definition
getIsCutterFruitTypeAllowed(integer fruitType)
Arguments
integerfruitTypefruit type
Return Values
booleanallowscutter allows fillType
Code
1064function Combine:getIsCutterFruitTypeAllowed(fruitType)
1065 return self:allowFillType(FruitUtil.fruitTypeToFillType[fruitType], false);
1066end

addCutterArea

Description
Add harvested fill level and straw to combine
Definition
addCutterArea(table cutter, float area, float realArea, integer inputFruitType, integer outputFillType)
Arguments
tablecuttercutter
floatareaarea value
floatrealAreareal area value
integerinputFruitTypeinput fruit type
integeroutputFillTypeoutput fill type
Code
1075function Combine:addCutterArea(superFunc, cutter, area, realArea, inputFruitType, outputFillType)
1076 if superFunc ~= nil then
1077 if not superFunc(self, cutter, area, realArea, inputFruitType, outputFillType) then
1078 return false
1079 end
1080 end
1081
1082 if area > 0 and (self.lastCuttersFruitType == FruitUtil.FRUITTYPE_UNKNOWN or self.lastCuttersArea == 0 or self.lastCuttersOutputFillType == outputFillType) then
1083 self.lastCuttersArea = self.lastCuttersArea + area;
1084 self.lastCuttersOutputFillType = outputFillType;
1085 self.lastCuttersInputFruitType = inputFruitType;
1086 self.lastCuttersAreaTime = g_currentMission.time;
1087
1088 if not self.chopperSwitchAvailable then
1089 local fruitDesc = FruitUtil.fruitIndexToDesc[inputFruitType];
1090 self.isStrawEnabled = not fruitDesc.hasWindrow;
1091 end
1092
1093 local litersPerSqm = 60
1094 local fruitDesc = FruitUtil.fruitIndexToDesc[inputFruitType];
1095 if fruitDesc.windrowLiterPerSqm ~= nil then
1096 litersPerSqm = fruitDesc.windrowLiterPerSqm
1097 end
1098
1099 self.strawBuffer[self.strawBufferFillIndex] = self.strawBuffer[self.strawBufferFillIndex] + (realArea * g_currentMission:getFruitPixelsToSqm() * litersPerSqm)
1100
1101 if self.combineFillEnableTime == nil then
1102 self.combineFillEnableTime = g_currentMission.time + self.combineFillToggleTime;
1103 end
1104 self.combineFillDisableTime = nil;
1105
1106 -- 8000/1200 = 6.66 liter/meter
1107 -- 8000/1200 / 6 = 1.111 liter/m^2
1108 -- 8000/1200 / 6 / 2^2 = 0.277777 liter / density pixel (density is 4096^2, on a area of 2048m^2
1109 local pixelToSqm = g_currentMission:getFruitPixelsToSqm(); -- 4096px are mapped to 2048m
1110 local literPerSqm = 1;
1111 if (inputFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN) then
1112 literPerSqm = FruitUtil.fruitIndexToDesc[inputFruitType].literPerSqm;
1113 end
1114 local sqm = area*pixelToSqm;
1115 local deltaFillLevel = sqm*literPerSqm*self.threshingScale;
1116 local newFillLevel = self:getUnitFillLevel(self.overloading.fillUnitIndex) + deltaFillLevel;
1117 local fillType = outputFillType;
1118
1119 self:setWorkedHectars(self.workedHectars + Utils.areaToHa(realArea, g_currentMission:getFruitPixelsToSqm()));
1120
1121 self:setUnitFillLevel(self.overloading.fillUnitIndex, newFillLevel, fillType, false, self.fillVolumeLoadInfos[self.overloading.loadInfoIndex]);
1122 end
1123end

getIsThreshingAllowed

Description
Returns if threshing is allowed
Definition
getIsThreshingAllowed(boolean earlyWarning)
Arguments
booleanearlyWarningearly warning
Return Values
booleanallowsallows threshing
Code
1129function Combine:getIsThreshingAllowed(earlyWarning)
1130 if self.allowThreshingDuringRain then
1131 return true;
1132 end
1133 if earlyWarning ~= nil and earlyWarning == true then
1134 if g_currentMission.environment.lastRainScale <= 0.02 and g_currentMission.environment.timeSinceLastRain > 20 then
1135 return true;
1136 end
1137 else
1138 if g_currentMission.environment.lastRainScale <= 0.1 and g_currentMission.environment.timeSinceLastRain > 20 then
1139 return true;
1140 end
1141 end
1142 return false;
1143end

getIsFoldAllowed

Description
Returns if fold is allowed
Definition
getIsFoldAllowed()
Return Values
booleanallowsFoldallows folding
Code
1148function Combine:getIsFoldAllowed(superFunc)
1149 if (not self.allowFoldWhileThreshing and self:getIsTurnedOn()) then
1150 return false;
1151 end
1152 local fillLevel = self:getUnitFillLevel(self.overloading.fillUnitIndex);
1153 if self.foldAnimTime ~= nil and (fillLevel > self.foldMaxFillLevel or fillLevel < self.foldMinFillLevel) then
1154 return false;
1155 end
1156
1157 if superFunc ~= nil then
1158 return superFunc(self);
1159 end
1160 return true;
1161end

getTurnedOnNotAllowedWarning

Description
Returns turn on not allowed warning text
Definition
getTurnedOnNotAllowedWarning()
Return Values
stringwarningTextturn on not allowed warning text
Code
1166function Combine:getTurnedOnNotAllowedWarning(superFunc)
1167 if self.isSelectable == nil or self:getIsActiveForInput(true) then
1168 if not self:getIsTurnedOnAllowed(true) then
1169 local warning = self:getNeedsCutterFolding();
1170 if warning ~= nil then
1171 return warning;
1172 end
1173 end
1174 end
1175
1176 if superFunc ~= nil then
1177 return superFunc(self);
1178 end
1179 return nil;
1180end

setIsStrawEnabled

Description
Set is straw enabled
Definition
setIsStrawEnabled(boolean isStrawEnabled, boolean noEventSend, boolean force)
Arguments
booleanisStrawEnablednew state
booleannoEventSendno event send
booleanforceforce action
Code
1187function Combine:setIsStrawEnabled(isStrawEnabled, noEventSend, force)
1188 if isStrawEnabled ~= self.isStrawEnabled or force then
1189 CombineStrawEnableEvent.sendEvent(self, isStrawEnabled, noEventSend);
1190 self.isStrawEnabled = isStrawEnabled;
1191
1192 if self.playAnimation ~= nil and self.toggleChopperAnimName ~= nil then
1193 local dir = 1;
1194 if isStrawEnabled then
1195 dir = -1;
1196 end
1197 self:playAnimation(self.toggleChopperAnimName, dir, self:getAnimationTime(self.toggleChopperAnimName), true);
1198 end
1199 end
1200end

loadWorkAreaFromXML

Description
Loads work areas from xml
Definition
loadWorkAreaFromXML(table workArea, integer xmlFile, string key)
Arguments
tableworkAreaworkArea
integerxmlFileid of xml object
stringkeykey
Return Values
booleansuccesssuccess
Code
1208function Combine:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
1209 local retValue = true;
1210 if superFunc ~= nil then
1211 retValue = superFunc(self, workArea, xmlFile, key)
1212 end
1213
1214 if workArea.type == WorkArea.AREATYPE_DEFAULT then
1215 workArea.type = WorkArea.AREATYPE_COMBINE;
1216 end
1217
1218 return retValue;
1219end

getFillLevelInformation

Description
Added fill level information to display it on the hud
Definition
getFillLevelInformation(table fillLevelInformations)
Arguments
tablefillLevelInformationstable to add the informations
Code
1224function Combine:getFillLevelInformation(superFunc, fillLevelInformations)
1225
1226 if self.fillUnits ~= nil then
1227 for i,fillUnit in pairs(self.fillUnits) do
1228 if fillUnit.capacity > 0 and fillUnit.showOnHud then
1229 local added = false;
1230 local fillType = fillUnit.currentFillType;
1231 local fillLevel = fillUnit.fillLevel;
1232 local capacity = fillUnit.capacity;
1233
1234 if i == self.overloading.fillUnitIndex and self:getUnitCapacity(self.overloading.fillUnitIndex) <= 0 then
1235 fillType = self:getUnitLastValidFillType(self.overloading.fillUnitIndex);
1236 fillLevel = self.lastLostFillLevel;
1237 end
1238
1239 for _,fillLevelInformation in pairs(fillLevelInformations) do
1240 if fillLevelInformation.fillType == fillType then
1241 fillLevelInformation.fillLevel = fillLevelInformation.fillLevel + fillLevel;
1242 fillLevelInformation.capacity = fillLevelInformation.capacity + capacity;
1243 added = true;
1244 break;
1245 end
1246 end
1247
1248 if not added then
1249 table.insert(fillLevelInformations, {fillType=fillType, fillLevel=fillLevel, capacity=capacity});
1250 end
1251 end;
1252 end
1253 end
1254
1255 for _, implement in pairs(self.attachedImplements) do
1256 if implement.object ~= nil then
1257 implement.object:getFillLevelInformation(fillLevelInformations);
1258 end
1259 end
1260end