Script v1.4.4.0
Engine v7.0.0.2
- General
- Entity
- Node
- Scenegraph
- Lighting
- Camera
- Shape
- Particle System
- Physics
- Spline
- Animation
- Overlays
- Sound
- Input
- XML
- Network
- Callbacks
- Text Rendering
- Terrain Detail
- Tire Track
- Editor
- Rendering
- String
- Math
- I3D
- Fillplanes
Foundation Reference
Combine
DescriptionClass for all combinesFunctions
- initSpecialization
- prerequisitesPresent
- preLoad
- load
- postLoad
- applyInitialAnimation
- delete
- readStream
- writeStream
- readUpdateStream
- writeUpdateStream
- getSaveAttributesAndNodes
- update
- updateTick
- draw
- onDeactivate
- onDeactivateSounds
- onAttachImplement
- onDetachImplement
- startThreshing
- stopThreshing
- setWorkedHectars
- getNeedsCutterFolding
- getIsTurnedOnAllowed
- onTurnedOn
- onTurnedOff
- setUnitLastValidFillType
- setCombineIsFilling
- setChopperPSEnabled
- setStrawPSEnabled
- getIsCutterFruitTypeAllowed
- addCutterArea
- getIsThreshingAllowed
- getIsFoldAllowed
- getTurnedOnNotAllowedWarning
- setIsStrawEnabled
- loadWorkAreaFromXML
- getFillLevelInformation
initSpecialization
DescriptionCalled on specialization initializingDefinition
initSpecialization()Code
17 | function Combine.initSpecialization() |
18 | WorkArea.registerAreaType("combine"); |
19 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
25 | function 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); |
31 | end |
preLoad
DescriptionCalled before loadingDefinition
preLoad(table savegame)Arguments
table | savegame | savegame |
36 | function Combine:preLoad(savegame) |
37 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Combine.loadWorkAreaFromXML); |
38 | end |
load
DescriptionCalled on loadingDefinition
load(table savegame)Arguments
table | savegame | savegame |
43 | function 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(); |
262 | end |
postLoad
DescriptionCalled after loadingDefinition
postLoad(table savegame)Arguments
table | savegame | savegame |
267 | function 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 |
287 | end |
applyInitialAnimation
DescriptionCalled at the end of loading to apply an initial animation stateDefinition
applyInitialAnimation()Code
291 | function 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 |
299 | end |
delete
DescriptionCalled on deletingDefinition
delete()Code
303 | function 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 |
322 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
328 | function 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); |
343 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
349 | function 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); |
356 | end |
readUpdateStream
DescriptionCalled on on updateDefinition
readUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
363 | function 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 |
390 | end |
writeUpdateStream
DescriptionCalled on on updateDefinition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
397 | function 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 |
406 | end |
getSaveAttributesAndNodes
DescriptionReturns attributes and nodes to saveDefinition
getSaveAttributesAndNodes(table nodeIdent)Arguments
table | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
413 | function 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; |
420 | end |
update
DescriptionCalled on updateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
431 | function 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 |
562 | end |
updateTick
DescriptionCalled on update tickDefinition
updateTick(float dt)Arguments
float | dt | time since last call in ms |
567 | function 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 |
700 | end |
draw
DescriptionCalled on drawDefinition
draw()Code
704 | function 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 |
752 | end |
onDeactivate
DescriptionCalled on deactivateDefinition
onDeactivate()Code
756 | function 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; |
763 | end |
onDeactivateSounds
DescriptionCalled on deactivating soundsDefinition
onDeactivateSounds()Code
767 | function Combine:onDeactivateSounds() |
768 | if self.isClient then |
769 | SoundUtil.stopSample(self.sampleThreshing, true); |
770 | SoundUtil.stopSample(self.sampleThreshingStart, true); |
771 | end |
772 | end |
onAttachImplement
DescriptionCalled on attaching a implementDefinition
onAttachImplement(table implement)Arguments
table | implement | implement to attach |
777 | function 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 |
783 | end |
onDetachImplement
DescriptionCalled on detaching a implementDefinition
onDetachImplement(integer implementIndex)Arguments
integer | implementIndex | index of implement to detach |
788 | function 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 |
799 | end |
startThreshing
DescriptionStart threshingDefinition
startThreshing()Code
803 | function 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 |
822 | end |
stopThreshing
DescriptionStop threshingDefinition
stopThreshing()Code
826 | function 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 |
848 | end |
setWorkedHectars
DescriptionSet worked hectars value and updated hudDefinition
setWorkedHectars(float hectars)Arguments
float | hectars | new hectars value |
853 | function 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 |
859 | end |
getNeedsCutterFolding
DescriptionChecks if cutter needs folding and is unfoldedDefinition
getNeedsCutterFolding()Return Values
string | unfoldWarning | unfold warning if cutter needs unfold, nil if not |
864 | function 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; |
875 | end |
getIsTurnedOnAllowed
DescriptionReturns if turn on is allowedDefinition
getIsTurnedOnAllowed(boolean isTurnedOn)Arguments
boolean | isTurnedOn | is turned on |
boolean | allow | allow turn on |
881 | function 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; |
899 | end |
onTurnedOn
DescriptionCalled on turn onDefinition
onTurnedOn(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
904 | function Combine:onTurnedOn(noEventSend) |
905 | self:startThreshing(); |
906 | end |
onTurnedOff
DescriptionCalled on turn offDefinition
onTurnedOff(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
911 | function Combine:onTurnedOff(noEventSend) |
912 | self:stopThreshing(); |
913 | end |
setUnitLastValidFillType
DescriptionSet unit last valid fill typeDefinition
setUnitLastValidFillType(integer fillUnitIndex, integer lastValidFillType, boolean hasChanged)Arguments
integer | fillUnitIndex | index of fill unit |
integer | lastValidFillType | index new last valid fill type |
boolean | hasChanged | fill type has changed |
920 | function 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 |
935 | end |
setCombineIsFilling
DescriptionSet combine is fillingDefinition
setCombineIsFilling(boolean combineIsFilling, boolean fruitTypeChanged, boolean isSynchronized)Arguments
boolean | combineIsFilling | combine is filling |
boolean | fruitTypeChanged | fruit type has changed |
boolean | isSynchronized | filling is synchronized |
942 | function 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 |
973 | end |
setChopperPSEnabled
DescriptionSet chopper PS enabledDefinition
setChopperPSEnabled(boolean chopperPSenabled, boolean fruitTypeChanged, boolean isSynchronized)Arguments
boolean | chopperPSenabled | set enabled |
boolean | fruitTypeChanged | fruit type has changed |
boolean | isSynchronized | filling is synchronized |
980 | function 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 |
1014 | end |
setStrawPSEnabled
DescriptionSet straw PS enabledDefinition
setStrawPSEnabled(boolean strawPSenabled, boolean fruitTypeChanged, boolean isSynchronized)Arguments
boolean | strawPSenabled | set enabled |
boolean | fruitTypeChanged | fruit type has changed |
boolean | isSynchronized | filling is synchronized |
1021 | function 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 |
1058 | end |
getIsCutterFruitTypeAllowed
DescriptionReturns if cutter allows fruit typeDefinition
getIsCutterFruitTypeAllowed(integer fruitType)Arguments
integer | fruitType | fruit type |
boolean | allows | cutter allows fillType |
1064 | function Combine:getIsCutterFruitTypeAllowed(fruitType) |
1065 | return self:allowFillType(FruitUtil.fruitTypeToFillType[fruitType], false); |
1066 | end |
addCutterArea
DescriptionAdd harvested fill level and straw to combineDefinition
addCutterArea(table cutter, float area, float realArea, integer inputFruitType, integer outputFillType)Arguments
table | cutter | cutter |
float | area | area value |
float | realArea | real area value |
integer | inputFruitType | input fruit type |
integer | outputFillType | output fill type |
1075 | function 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 |
1123 | end |
getIsThreshingAllowed
DescriptionReturns if threshing is allowedDefinition
getIsThreshingAllowed(boolean earlyWarning)Arguments
boolean | earlyWarning | early warning |
boolean | allows | allows threshing |
1129 | function 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; |
1143 | end |
getIsFoldAllowed
DescriptionReturns if fold is allowedDefinition
getIsFoldAllowed()Return Values
boolean | allowsFold | allows folding |
1148 | function 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; |
1161 | end |
getTurnedOnNotAllowedWarning
DescriptionReturns turn on not allowed warning textDefinition
getTurnedOnNotAllowedWarning()Return Values
string | warningText | turn on not allowed warning text |
1166 | function 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; |
1180 | end |
setIsStrawEnabled
DescriptionSet is straw enabledDefinition
setIsStrawEnabled(boolean isStrawEnabled, boolean noEventSend, boolean force)Arguments
boolean | isStrawEnabled | new state |
boolean | noEventSend | no event send |
boolean | force | force action |
1187 | function 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 |
1200 | end |
loadWorkAreaFromXML
DescriptionLoads work areas from xmlDefinition
loadWorkAreaFromXML(table workArea, integer xmlFile, string key)Arguments
table | workArea | workArea |
integer | xmlFile | id of xml object |
string | key | key |
boolean | success | success |
1208 | function 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; |
1219 | end |
getFillLevelInformation
DescriptionAdded fill level information to display it on the hudDefinition
getFillLevelInformation(table fillLevelInformations)Arguments
table | fillLevelInformations | table to add the informations |
1224 | function 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 |
1260 | end |