LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

Baler

Description
Class for all Balers
Functions

initSpecialization

Description
Called on specialization initializing
Definition
initSpecialization()
Code
25function Baler.initSpecialization()
26 WorkArea.registerAreaType("baler")
27end

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
33function Baler.prerequisitesPresent(specializations)
34 return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) and SpecializationUtil.hasSpecialization(Pickup, specializations)
35end

preLoad

Description
Called before loading
Definition
preLoad(table savegame)
Arguments
tablesavegamesavegame
Code
40function Baler:preLoad(savegame)
41 self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Baler.loadWorkAreaFromXML)
42 self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, Baler.loadSpeedRotatingPartFromXML)
43end

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
48function Baler:load(savegame)
49
50 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fillScale#value", "vehicle.baler#fillScale")
51 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleAnimation", "vehicle.baler.baleAnimation")
52 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleAnimation", "vehicle.baler.baleAnimation")
53 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.balerUVScrollParts.balerUVScrollPart", "vehicle.baler.uvScrollParts.uvScrollPart")
54 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.knotingAnimation", "vehicle.baler.knotingAnimation")
55 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.balingAnimation", "vehicle.baler.balingAnimation")
56 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleUnloading#allowed", "vehicle.baler.baleUnloading#allowed")
57 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleUnloading#time", "vehicle.baler.baleUnloading#time")
58 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleUnloading#foldThreshold", "vehicle.baler.baleUnloading#foldThreshold")
59
60 self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Baler.doCheckSpeedLimit)
61 self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, Baler.getIsSpeedRotatingPartActive)
62 self.allowPickingUp = Utils.overwrittenFunction(self.allowPickingUp, Baler.allowPickingUp)
63 self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, Baler.getIsTurnedOnAllowed)
64 self.getIsFoldAllowed = Utils.overwrittenFunction(self.getIsFoldAllowed, Baler.getIsFoldAllowed)
65 self.setUnitFillLevel = Utils.appendedFunction(self.setUnitFillLevel, Baler.setUnitFillLevel)
66 self.isUnloadingAllowed = Baler.isUnloadingAllowed
67 self.getTimeFromLevel = Baler.getTimeFromLevel
68 self.moveBales = SpecializationUtil.callSpecializationsFunction("moveBales")
69 self.moveBale = SpecializationUtil.callSpecializationsFunction("moveBale")
70 self.allowFillType = Baler.allowFillType
71 self.setIsUnloadingBale = Baler.setIsUnloadingBale
72 self.dropBale = Baler.dropBale
73 self.createBale = Baler.createBale
74 self.setBaleTime = Baler.setBaleTime
75 self.processBalerAreas = Baler.processBalerAreas
76
77 self.baler = {}
78 self.baler.fillScale = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.fillScale#value"), 1)
79 self.baler.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#fillUnitIndex"), 1)
80 self.baler.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#unloadInfoIndex"), 1)
81 self.baler.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#loadInfoIndex"), 1)
82 self.baler.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.baler#dischargeInfoIndex"), 1)
83
84 local firstBaleMarker = getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#firstBaleMarker")
85 if firstBaleMarker ~= nil then
86 local baleAnimCurve = AnimCurve:new(linearInterpolatorN)
87 local keyI = 0
88 while true do
89 local key = string.format("vehicle.baler.baleAnimation.key(%d)", keyI)
90 local t = getXMLFloat(self.xmlFile, key.."#time")
91 local x,y,z = Utils.getVectorFromString(getXMLString(self.xmlFile, key.."#pos"))
92 if x == nil or y == nil or z == nil then
93 break
94 end
95 local rx, ry, rz = Utils.getVectorFromString(getXMLString(self.xmlFile, key.."#rot"))
96 rx = math.rad(Utils.getNoNil(rx, 0))
97 ry = math.rad(Utils.getNoNil(ry, 0))
98 rz = math.rad(Utils.getNoNil(rz, 0))
99 baleAnimCurve:addKeyframe({ v={x, y, z, rx, ry, rz}, time = t})
100 keyI = keyI +1
101 end
102 if keyI > 0 then
103 self.baler.baleAnimCurve = baleAnimCurve
104 self.baler.firstBaleMarker = firstBaleMarker
105 end
106 end
107 self.baler.baleAnimRoot, self.baler.baleAnimRootComponent = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#node"))
108 if self.baler.baleAnimRoot == nil then
109 self.baler.baleAnimRoot = self.components[1].node
110 self.baler.baleAnimRootComponent = self.components[1].node
111 end
112 -- there is no standard bale animation, load the unload animation (for round baler)
113 if self.baler.firstBaleMarker == nil then
114 local unloadAnimationName = getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationName")
115 local closeAnimationName = getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#closeAnimationName")
116 local unloadAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#unloadAnimationSpeed"), 1)
117 local closeAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#closeAnimationSpeed"), 1)
118 if unloadAnimationName ~= nil and closeAnimationName ~= nil then
119 if self.playAnimation ~= nil and self.animations ~= nil then
120 if self.animations[unloadAnimationName] ~= nil and self.animations[closeAnimationName] ~= nil then
121 --print("has unload animation")
122 self.baler.baleUnloadAnimationName = unloadAnimationName
123 self.baler.baleUnloadAnimationSpeed = unloadAnimationSpeed
124
125 self.baler.baleCloseAnimationName = closeAnimationName
126 self.baler.baleCloseAnimationSpeed = closeAnimationSpeed
127
128 self.baler.baleDropAnimTime = getXMLFloat(self.xmlFile, "vehicle.baler.baleAnimation#baleDropAnimTime")
129 if self.baler.baleDropAnimTime == nil then
130 self.baler.baleDropAnimTime = self:getAnimationDuration(self.baler.baleUnloadAnimationName)
131 else
132 self.baler.baleDropAnimTime = self.baler.baleDropAnimTime * 1000
133 end
134 else
135 print("Error: Failed to find unload animations '"..unloadAnimationName.."' and '"..closeAnimationName.."' in '"..self.configFileName.."'.")
136 end
137 else
138 print("Error: There is an unload animation in '"..self.configFileName.."' but it is not a AnimatedVehicle. Change to a vehicle type which has the AnimatedVehicle specialization.")
139 end
140 end
141 end
142
143 self.baler.baleTypes = {}
144 local i = 0
145 while true do
146 local key = string.format("vehicle.baler.baleTypes.baleType(%d)", i)
147 if not hasXMLProperty(self.xmlFile, key) then
148 break
149 end
150 local isRoundBale = Utils.getNoNil(getXMLBool(self.xmlFile, key.."#isRoundBale"), false)
151 local width = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#width"), 1.2), 2)
152 local height = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#height"), 0.9), 2)
153 local length = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#length"), 2.4), 2)
154 local diameter = Utils.round(Utils.getNoNil(getXMLFloat(self.xmlFile, key.."#diameter"), 1.8), 2)
155 table.insert(self.baler.baleTypes, {isRoundBale=isRoundBale, width=width, height=height, length=length, diameter=diameter})
156 i = i + 1
157 end
158 self.baler.currentBaleTypeId = 1
159
160 if table.getn(self.baler.baleTypes) == 0 then
161 self.baler.baleTypes = nil
162 end
163
164 if self.isClient then
165 self.baler.sampleBaler = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerSound", nil, self.baseDirectory)
166 self.baler.sampleBalerAlarm = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerAlarm", nil, self.baseDirectory)
167 self.baler.sampleBalerEject = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerBaleEject", nil, self.baseDirectory)
168 self.baler.sampleBalerDoor = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerDoor", nil, self.baseDirectory)
169 self.baler.sampleBalerKnotCleaning = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.baler.balerKnotCleaning", nil, self.baseDirectory)
170 self.baler.knotCleaningTime = 10000
171
172 self.baler.uvScrollParts = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.baler.uvScrollParts.uvScrollPart", {}, false)
173 self.baler.turnedOnRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "baler", self.components)
174
175 self.baler.fillEffects = EffectManager:loadEffect(self.xmlFile, "vehicle.baler.fillEffect", self.components, self)
176
177 self.baler.knotingAnimation = getXMLString(self.xmlFile, "vehicle.baler.knotingAnimation#name")
178 self.baler.knotingAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.knotingAnimation#speed"), 1)
179 end
180
181 self.baler.balingAnimationName = Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.baler.balingAnimation#name"), "")
182 if self.playAnimation == nil or self.getIsAnimationPlaying == nil then
183 self.baler.balingAnimationName = ""
184 end
185
186 self.baler.lastAreaBiggerZero = false
187 self.baler.lastAreaBiggerZeroSent = false
188 self.baler.lastAreaBiggerZeroTime = 0
189
190 self.baler.unloadingState = Baler.UNLOADING_CLOSED
191 self.baler.pickupFillTypes = {}
192
193 self.baler.bales = {}
194 self.baler.hasBaler = true
195
196 self.baler.dummyBale = {}
197 self.baler.dummyBale.scaleNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#scaleNode"))
198 self.baler.dummyBale.baleNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.baler.baleAnimation#baleNode"))
199 self.baler.dummyBale.currentBaleFillType = FillUtil.FILLTYPE_UNKNOWN
200 self.baler.dummyBale.currentBale = nil
201
202 self.baler.allowsBaleUnloading = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.baler.baleUnloading#allowed"), false)
203 self.baler.baleUnloadingTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleUnloading#time"), 4) * 1000
204 self.baler.baleFoldThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.baler.baleUnloading#foldThreshold"), 0.25) * self:getCapacity()
205
206 self.baler.isBaleUnloading = false
207 self.baler.isSpeedLimitActive = false
208
209 self.baler.dirtyFlag = self:getNextDirtyFlag()
210end

postLoad

Description
Called after loading
Definition
postLoad(table savegame)
Arguments
tablesavegamesavegame
Code
215function Baler:postLoad(savegame)
216
217 for fillType, enabled in pairs(self:getUnitFillTypes(self.baler.fillUnitIndex)) do
218 if enabled and fillType ~= FillUtil.FILLTYPE_UNKNOWN then
219 if FruitUtil.fillTypeIsWindrow[fillType] then
220 table.insert(self.baler.pickupFillTypes, fillType)
221 end
222 end
223 end
224
225 if self.isClient then
226 self.baler.fillParticleSystems = {}
227 self.baler.currentFillParticleSystem = nil
228 local i = 0
229 while true do
230 local key = string.format("vehicle.baler.fillParticleSystems.emitterShape(%d)", i)
231 if not hasXMLProperty(self.xmlFile, key) then
232 break
233 end
234
235 local emitterShape = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node"))
236 local particleType = getXMLString(self.xmlFile, key.."#particleType")
237 if emitterShape ~= nil then
238 for _, fillType in pairs(self.baler.pickupFillTypes) do
239 local particleSystem = MaterialUtil.getParticleSystem(fillType, particleType)
240 if particleSystem ~= nil then
241 if self.baler.fillParticleSystems[fillType] == nil then
242 self.baler.fillParticleSystems[fillType] = {}
243 end
244 table.insert(self.baler.fillParticleSystems[fillType], ParticleUtil.copyParticleSystem(self.xmlFile, key, particleSystem, emitterShape))
245 end
246 end
247 end
248 i = i + 1
249 end
250 end
251
252 if savegame ~= nil and not savegame.resetVehicles then
253 local numBales = getXMLInt(savegame.xmlFile, savegame.key.."#numBales")
254 if numBales ~= nil then
255 self.baler.balesToLoad = {}
256 for i=1, numBales do
257 local baleKey = savegame.key..string.format(".bale(%d)", i-1)
258 local bale = {}
259 local fillTypeStr = getXMLString(savegame.xmlFile, baleKey.."#fillType")
260 local fillType = FillUtil.fillTypeNameToInt[fillTypeStr]
261 bale.fillType = fillType
262 bale.fillLevel = getXMLFloat(savegame.xmlFile, baleKey.."#fillLevel")
263 bale.baleTime = getXMLFloat(savegame.xmlFile, baleKey.."#baleTime")
264 table.insert(self.baler.balesToLoad, bale)
265 end
266 end
267 end
268
269 if self.baler.firstBaleMarker == nil then
270 if self:getUnitFillLevel(self.baler.fillUnitIndex) >= self:getUnitCapacity(self.baler.fillUnitIndex) then
271 self.baler.baleToCreate = true;
272 end;
273 end;
274end

delete

Description
Called on deleting
Definition
delete()
Code
278function Baler:delete()
279 for k, _ in pairs(self.baler.bales) do
280 self:dropBale(k)
281 end
282
283 if self.baler.dummyBale.currentBale ~= nil then
284 delete(self.baler.dummyBale.currentBale)
285 self.baler.dummyBale.currentBale = nil
286 end
287
288 if self.isClient then
289 SoundUtil.deleteSample(self.baler.sampleBaler)
290 SoundUtil.deleteSample(self.baler.sampleBalerAlarm)
291 SoundUtil.deleteSample(self.baler.sampleBalerDoor)
292 SoundUtil.deleteSample(self.baler.sampleBalerEject)
293 SoundUtil.deleteSample(self.baler.sampleBalerKnotCleaning)
294
295 for _,v in pairs(self.baler.fillParticleSystems) do
296 ParticleUtil.deleteParticleSystems(v)
297 end
298
299 EffectManager:deleteEffects(self.baler.fillEffects);
300 end
301end

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
307function Baler:readStream(streamId, connection)
308 if self.baler.baleUnloadAnimationName ~= nil then
309 local state = streamReadUIntN(streamId, 7)
310 local animTime = streamReadFloat32(streamId)
311 if state == Baler.UNLOADING_CLOSED or state == Baler.UNLOADING_CLOSING then
312 self:setIsUnloadingBale(false, true)
313 self:setRealAnimationTime(self.baler.baleCloseAnimationName, animTime)
314 elseif state == Baler.UNLOADING_OPEN or state == Baler.UNLOADING_OPENING then
315 self:setIsUnloadingBale(true, true)
316 self:setRealAnimationTime(self.baler.baleUnloadAnimationName, animTime)
317 end
318 end
319
320 local numBales = streamReadUInt8(streamId)
321 for i=1, numBales do
322 local fillType = streamReadInt8(streamId)
323 local fillLevel = streamReadFloat32(streamId)
324 self:createBale(fillType, fillLevel)
325 if self.baler.baleAnimCurve ~= nil then
326 local baleTime = streamReadFloat32(streamId)
327 self:setBaleTime(i, baleTime)
328 end
329 end
330
331 self.baler.lastAreaBiggerZero = streamReadBool(streamId)
332end

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
338function Baler:writeStream(streamId, connection)
339
340 if self.baler.baleUnloadAnimationName ~= nil then
341 streamWriteUIntN(streamId, self.baler.unloadingState, 7)
342 local animTime = 0
343 if self.baler.unloadingState == Baler.UNLOADING_CLOSED or self.baler.unloadingState == Baler.UNLOADING_CLOSING then
344 animTime = self:getRealAnimationTime(self.baler.baleCloseAnimationName)
345 elseif self.baler.unloadingState == Baler.UNLOADING_OPEN or self.baler.unloadingState == Baler.UNLOADING_OPENING then
346 animTime = self:getRealAnimationTime(self.baler.baleUnloadAnimationName)
347 end
348 streamWriteFloat32(streamId, animTime)
349 end
350
351 streamWriteUInt8(streamId, table.getn(self.baler.bales))
352 for i=1, table.getn(self.baler.bales) do
353 local bale = self.baler.bales[i]
354 streamWriteInt8(streamId, bale.fillType)
355 streamWriteFloat32(streamId, bale.fillLevel)
356 if self.baler.baleAnimCurve ~= nil then
357 streamWriteFloat32(streamId, bale.time)
358 end
359 end
360
361 streamWriteBool(streamId, self.baler.lastAreaBiggerZero)
362end

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
369function Baler:readUpdateStream(streamId, timestamp, connection)
370 if connection:getIsServer() then
371 self.baler.lastAreaBiggerZero = streamReadBool(streamId)
372 end
373end

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
380function Baler:writeUpdateStream(streamId, connection, dirtyMask)
381 if not connection:getIsServer() then
382 streamWriteBool(streamId, self.baler.lastAreaBiggerZero)
383 end
384end

getSaveAttributesAndNodes

Description
Returns attributes and nodes to save
Definition
getSaveAttributesAndNodes(table nodeIdent)
Arguments
tablenodeIdentnode ident
Return Values
stringattributesattributes
stringnodesnodes
Code
391function Baler:getSaveAttributesAndNodes(nodeIdent)
392 if self.baler.firstBaleMarker ~= nil then
393 local attributes = 'numBales="'..table.getn(self.baler.bales)..'"'
394 local nodes = ""
395 local baleNum = 0
396
397 for i=1, table.getn(self.baler.bales) do
398 local bale = self.baler.bales[i]
399 local fillTypeStr = "unknown"
400 if bale.fillType ~= FillUtil.FILLTYPE_UNKNOWN then
401 fillTypeStr = FillUtil.fillTypeIntToName[bale.fillType]
402 end
403
404 if baleNum>0 then
405 nodes = nodes.."\n"
406 end
407 nodes = nodes..nodeIdent..'<bale fillType="'..fillTypeStr..'" fillLevel="'..bale.fillLevel..'"'
408 if self.baler.baleAnimCurve ~= nil then
409 nodes = nodes..' baleTime="'..bale.time..'"'
410 end
411 nodes = nodes..' />'
412 baleNum = baleNum+1
413 end
414 return attributes,nodes
415 end;
416
417 return "","";
418end

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
429function Baler:update(dt)
430
431 if self.firstTimeRun and self.baler.balesToLoad ~= nil then
432 if table.getn(self.baler.balesToLoad) > 0 then
433 local v = self.baler.balesToLoad[1];
434
435 if v.targetBaleTime == nil then
436 self:createBale(v.fillType, v.fillLevel)
437 self:setBaleTime(table.getn(self.baler.bales), 0, true);
438 v.targetBaleTime = v.baleTime;
439 v.baleTime = 0;
440 else
441 v.baleTime = math.min(v.baleTime + dt / 1000, v.targetBaleTime);
442 self:setBaleTime(table.getn(self.baler.bales), v.baleTime, true);
443
444 if v.baleTime == v.targetBaleTime then
445
446 local index = table.getn(self.baler.balesToLoad);
447 if index == 1 then
448 self.baler.balesToLoad = nil;
449 else
450 table.remove(self.baler.balesToLoad, 1);
451 end;
452 end;
453 end;
454 end;
455 end
456
457 if self.firstTimeRun and self.baler.baleToCreate ~= nil then
458 self:createBale(self:getUnitFillType(self.baler.fillUnitIndex), self:getUnitCapacity(self.baler.fillUnitIndex))
459 g_server:broadcastEvent(BalerCreateBaleEvent:new(self, self:getUnitFillType(self.baler.fillUnitIndex), 0), nil, nil, self)
460
461 self.baler.baleToCreate = nil;
462 end;
463
464 if self:getIsActiveForInput() then
465 if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then
466 if self:isUnloadingAllowed() then
467 if self.baler.baleUnloadAnimationName ~= nil or self.baler.allowsBaleUnloading then
468 if self.baler.unloadingState == Baler.UNLOADING_CLOSED then
469 if table.getn(self.baler.bales) > 0 then
470 self:setIsUnloadingBale(true)
471 end
472 elseif self.baler.unloadingState == Baler.UNLOADING_OPEN then
473 if self.baler.baleUnloadAnimationName ~= nil then
474 self:setIsUnloadingBale(false)
475 end
476 end
477 end
478 end
479 end
480 end
481
482 if self.isClient then
483 Utils.updateRotationNodes(self, self.baler.turnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn() )
484 Utils.updateScrollers(self.baler.uvScrollParts, dt, self:getIsActive() and self:getIsTurnedOn())
485 end
486end

updateTick

Description
Called on update tick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
491function Baler:updateTick(dt)
492 self.baler.isSpeedLimitActive = false
493
494 if self.isServer then
495 self.baler.lastAreaBiggerZero = false
496 end
497
498 if self:getIsActive() then
499 if self:getIsTurnedOn() then
500 if self:allowPickingUp() then
501 if g_currentMission:getCanAddLimitedObject(FSBaseMission.LIMITED_OBJECT_TYPE_BALE) then
502 self.baler.isSpeedLimitActive = true
503 if self.isServer then
504 local workAreas, _, _ = self:getTypedNetworkAreas(WorkArea.AREATYPE_BALER, false)
505 local totalLiters = 0
506 local usedFillType = FillUtil.FILLTYPE_UNKNOWN
507 if table.getn(workAreas) > 0 then
508 totalLiters, usedFillType = self:processBalerAreas(workAreas, self.baler.pickupFillTypes)
509 end
510
511 if totalLiters > 0 then
512 self.baler.lastAreaBiggerZero = true
513 if self.baler.lastAreaBiggerZero ~= self.baler.lastAreaBiggerZeroSent then
514 self:raiseDirtyFlags(self.baler.dirtyFlag)
515 self.baler.lastAreaBiggerZeroSent = self.baler.lastAreaBiggerZero
516 end
517
518 local deltaLevel = totalLiters * self.baler.fillScale
519
520 if self.baler.baleUnloadAnimationName == nil then
521 -- move all bales
522 local deltaTime = self:getTimeFromLevel(deltaLevel)
523 self:moveBales(deltaTime)
524 end
525
526 local oldFillLevel = self:getUnitFillLevel(self.baler.fillUnitIndex)
527 self:setUnitFillLevel(self.baler.fillUnitIndex, oldFillLevel+deltaLevel, usedFillType, true)
528 if self:getUnitFillLevel(self.baler.fillUnitIndex) >= self:getUnitCapacity(self.baler.fillUnitIndex) then
529 if self.baler.baleTypes ~= nil then
530 -- create bale
531 if self.baler.baleAnimCurve ~= nil then
532 local restDeltaFillLevel = deltaLevel - (self:getUnitFillLevel(self.baler.fillUnitIndex)-oldFillLevel)
533 self:setUnitFillLevel(self.baler.fillUnitIndex, restDeltaFillLevel, usedFillType, true)
534
535 self:createBale(usedFillType, self:getUnitCapacity(self.baler.fillUnitIndex))
536
537 local numBales = table.getn(self.baler.bales)
538 local bale = self.baler.bales[numBales]
539
540 self:moveBale(numBales, self:getTimeFromLevel(restDeltaFillLevel), true)
541 -- note: self.baler.bales[numBales] can not be accessed anymore since the bale might be dropped already
542 g_server:broadcastEvent(BalerCreateBaleEvent:new(self, usedFillType, bale.time), nil, nil, self)
543 elseif self.baler.baleUnloadAnimationName ~= nil then
544 self:createBale(usedFillType, self:getUnitCapacity(self.baler.fillUnitIndex))
545 g_server:broadcastEvent(BalerCreateBaleEvent:new(self, usedFillType, 0), nil, nil, self)
546 end
547 end
548 end
549 end
550 end
551 else
552 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_tooManyBales"), 500)
553 end
554 end
555
556
557 if self.baler.lastAreaBiggerZero and self.fillUnits[self.baler.fillUnitIndex].lastValidFillType ~= FillUtil.FILLTYPE_UNKNOWN then
558 self.baler.lastAreaBiggerZeroTime = 500
559 else
560 if self.baler.lastAreaBiggerZeroTime > 0 then
561 self.baler.lastAreaBiggerZeroTime = self.baler.lastAreaBiggerZeroTime - dt
562 end
563 end
564
565 if self.isClient then
566 if self.baler.fillEffects ~= nil then
567 if self.baler.lastAreaBiggerZeroTime > 0 then
568 EffectManager:setFillType(self.baler.fillEffects, self.fillUnits[self.baler.fillUnitIndex].lastValidFillType)
569 EffectManager:startEffects(self.baler.fillEffects)
570 else
571 EffectManager:stopEffects(self.baler.fillEffects)
572 end
573 end
574
575 local currentFillParticleSystem = self.baler.fillParticleSystems[self.fillUnits[self.baler.fillUnitIndex].lastValidFillType]
576 if currentFillParticleSystem ~= self.baler.currentFillParticleSystem then
577 if self.baler.currentFillParticleSystem ~= nil then
578 for _, ps in pairs(self.baler.currentFillParticleSystem) do
579 ParticleUtil.setEmittingState(ps, false)
580 end
581 self.baler.currentFillParticleSystem = nil
582 end
583 self.baler.currentFillParticleSystem = currentFillParticleSystem
584 end
585
586 if self.baler.currentFillParticleSystem ~= nil then
587 for _, ps in pairs(self.baler.currentFillParticleSystem) do
588 ParticleUtil.setEmittingState(ps, self.baler.lastAreaBiggerZeroTime > 0)
589 end
590 end
591
592 if self:getIsActiveForSound() then
593 if self.baler.knotCleaningTime <= g_currentMission.time then
594 SoundUtil.playSample(self.baler.sampleBalerKnotCleaning, 1, 0, nil)
595 self.baler.knotCleaningTime = g_currentMission.time + 120000
596 end
597 SoundUtil.playSample(self.baler.sampleBaler, 0, 0, nil)
598 end
599 end
600 else
601 if self.baler.isBaleUnloading and self.isServer then
602 local deltaTime = dt / self.baler.baleUnloadingTime
603 self:moveBales(deltaTime)
604 end
605 end
606
607 if self.isClient then
608 if not self:getIsTurnedOn() then
609 SoundUtil.stopSample(self.baler.sampleBalerKnotCleaning)
610 SoundUtil.stopSample(self.baler.sampleBaler)
611 end
612
613 if self:getIsTurnedOn() and self:getUnitFillLevel(self.baler.fillUnitIndex) > (self:getUnitCapacity(self.baler.fillUnitIndex) * 0.68) and self:getUnitFillLevel(self.baler.fillUnitIndex) < self:getUnitCapacity(self.baler.fillUnitIndex) then
614 -- start alarm sound
615 if self:getIsActiveForSound() then
616 SoundUtil.playSample(self.baler.sampleBalerAlarm, 0, 0, nil)
617 end
618 else
619 SoundUtil.stopSample(self.baler.sampleBalerAlarm)
620 end
621
622 --delete dummy bale on client after physical bale is displayed
623 if self.baler.unloadingState == Baler.UNLOADING_OPEN then
624 if getNumOfChildren(self.baler.baleAnimRoot) > 0 then
625 delete(getChildAt(self.baler.baleAnimRoot, 0));
626 end;
627 end;
628 end;
629
630 if self.baler.unloadingState == Baler.UNLOADING_OPENING then
631 local isPlaying = self:getIsAnimationPlaying(self.baler.baleUnloadAnimationName)
632 local animTime = self:getRealAnimationTime(self.baler.baleUnloadAnimationName)
633 if not isPlaying or animTime >= self.baler.baleDropAnimTime then
634 if table.getn(self.baler.bales) > 0 then
635 self:dropBale(1)
636 if self.isServer then
637 self:setUnitFillLevel(self.baler.fillUnitIndex, 0, self:getUnitFillType(self.baler.fillUnitIndex), true)
638 end
639 end
640 if not isPlaying then
641 self.baler.unloadingState = Baler.UNLOADING_OPEN
642
643 if self.isClient then
644 SoundUtil.stopSample(self.baler.sampleBalerEject)
645 SoundUtil.stopSample(self.baler.sampleBalerDoor)
646 end
647 end
648 end
649 elseif self.baler.unloadingState == Baler.UNLOADING_CLOSING then
650 if not self:getIsAnimationPlaying(self.baler.baleCloseAnimationName) then
651 self.baler.unloadingState = Baler.UNLOADING_CLOSED
652 if self.isClient then
653 SoundUtil.stopSample(self.baler.sampleBalerDoor)
654 end
655 end
656 end
657 end
658end

draw

Description
Called on draw
Definition
draw()
Code
662function Baler:draw()
663 if self.isClient then
664 if self:getIsActiveForInput(true) then
665 if self:isUnloadingAllowed() then
666 if self.baler.baleUnloadAnimationName ~= nil or self.baler.allowsBaleUnloading then
667 if self.baler.unloadingState == Baler.UNLOADING_CLOSED then
668 if table.getn(self.baler.bales) > 0 then
669 g_currentMission:addHelpButtonText(g_i18n:getText("action_unloadBaler"), InputBinding.IMPLEMENT_EXTRA3, nil, GS_PRIO_HIGH)
670 end
671 elseif self.baler.unloadingState == Baler.UNLOADING_OPEN then
672 if self.baler.baleUnloadAnimationName ~= nil then
673 g_currentMission:addHelpButtonText(g_i18n:getText("action_closeBack"), InputBinding.IMPLEMENT_EXTRA3, nil, GS_PRIO_HIGH)
674 end
675 end
676 end
677 end
678 end
679 end
680end

getIsFoldAllowed

Description
Returns if fold is allowed
Definition
getIsFoldAllowed(boolean onAiTurnOn)
Arguments
booleanonAiTurnOncalled on ai turn on
Return Values
booleanallowsFoldallows folding
Code
686function Baler:getIsFoldAllowed(superFunc, onAiTurnOn)
687 if (table.getn(self.baler.bales) > 0 and self:getUnitFillLevel(self.baler.fillUnitIndex) > self.baler.baleFoldThreshold) or table.getn(self.baler.bales) > 1 or self:getIsTurnedOn() then
688 return false
689 end
690
691 if superFunc ~= nil then
692 return superFunc(self, onAiTurnOn)
693 end
694
695 return true
696end

onDeactivate

Description
Called on deactivate
Definition
onDeactivate()
Code
700function Baler:onDeactivate()
701 if self.baler.balingAnimationName ~= "" then
702 self:stopAnimation(self.baler.balingAnimationName, true)
703 end
704 if self.isClient then
705 if self.baler.fillEffects ~= nil then
706 EffectManager:stopEffects(self.baler.fillEffects)
707 end
708 if self.baler.currentFillParticleSystem ~= nil then
709 for _, ps in pairs(self.baler.currentFillParticleSystem) do
710 ParticleUtil.setEmittingState(ps, false)
711 end
712 end
713 end
714end

onDeactivateSounds

Description
Called on deactivating sounds
Definition
onDeactivateSounds()
Code
718function Baler:onDeactivateSounds()
719 if self.isClient then
720 SoundUtil.stopSample(self.baler.sampleBaler, true)
721 SoundUtil.stopSample(self.baler.sampleBalerAlarm, true)
722 SoundUtil.stopSample(self.baler.sampleBalerDoor, true)
723 SoundUtil.stopSample(self.baler.sampleBalerEject, true)
724 SoundUtil.stopSample(self.baler.sampleBalerKnotCleaning, true)
725 end
726end

setUnitFillLevel

Description
Set unit fill level
Definition
setUnitFillLevel(integer fillUnitIndex, float fillLevel, integer fillType, boolean force, table fillInfo)
Arguments
integerfillUnitIndexindex of fill unit
floatfillLevelnew fill level
integerfillTypefill type
booleanforceforce action
tablefillInfofill info for fill volume
Code
735function Baler:setUnitFillLevel(fillUnitIndex, fillLevel, fillType, force, fillInfo)
736 if fillUnitIndex == self.baler.fillUnitIndex then
737 if self.baler.dummyBale.baleNode ~= nil and fillLevel > 0 and fillLevel < self:getUnitCapacity(fillUnitIndex) and (self.baler.dummyBale.currentBale == nil or self.baler.dummyBale.currentBaleFillType ~= fillType) then
738 if self.baler.dummyBale.currentBale ~= nil then
739 delete(self.baler.dummyBale.currentBale)
740 self.baler.dummyBale.currentBale = nil
741 end
742 local t = self.baler.baleTypes[self.baler.currentBaleTypeId]
743
744 local baleType = BaleUtil.getBale(fillType, t.width, t.height, t.length, t.diameter, t.isRoundBale)
745
746 local baleRoot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory, false, false)
747 local baleId = getChildAt(baleRoot, 0)
748 setRigidBodyType(baleId, "NoRigidBody")
749 link(self.baler.dummyBale.baleNode, baleId)
750 delete(baleRoot)
751 self.baler.dummyBale.currentBale = baleId
752 self.baler.dummyBale.currentBaleFillType = fillType
753 end
754
755 if self.baler.dummyBale.currentBale ~= nil then
756 local percent = fillLevel / self:getUnitCapacity(fillUnitIndex)
757 local y = 1
758 if getUserAttribute(self.baler.dummyBale.currentBale, "isRoundbale") then
759 y = percent
760 end
761 setScale(self.baler.dummyBale.scaleNode, 1, y, percent)
762 end
763 end
764end

onTurnedOn

Description
Called on turn on
Definition
onTurnedOn(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
769function Baler:onTurnedOn(noEventSend)
770 if self.setFoldState ~= nil then
771 self:setFoldState(-1)
772 end
773 if self.baler.balingAnimationName ~= "" then
774 self:playAnimation(self.baler.balingAnimationName, 1, self:getAnimationTime(self.baler.balingAnimationName), true)
775 end
776end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
781function Baler:onTurnedOff(noEventSend)
782 if self.baler.balingAnimationName ~= "" then
783 self:stopAnimation(self.baler.balingAnimationName, true)
784 end
785 if self.isClient then
786 if self.baler.fillEffects ~= nil then
787 EffectManager:stopEffects(self.baler.fillEffects)
788 end
789 if self.baler.currentFillParticleSystem ~= nil then
790 for _, ps in pairs(self.baler.currentFillParticleSystem) do
791 ParticleUtil.setEmittingState(ps, false)
792 end
793 end
794 end
795end

doCheckSpeedLimit

Description
Returns if speed limit should be checked
Definition
doCheckSpeedLimit()
Return Values
booleancheckSpeedlimitcheck speed limit
Code
800function Baler:doCheckSpeedLimit(superFunc)
801 local parent = false
802 if superFunc ~= nil then
803 parent = superFunc(self)
804 end
805
806 return parent or self.baler.isSpeedLimitActive
807end

isUnloadingAllowed

Description
Returns if unloading is allowed
Definition
isUnloadingAllowed()
Return Values
booleanisAllowedunloading is allowed
Code
812function Baler:isUnloadingAllowed()
813 if self.hasBaleWrapper == nil or not self.hasBaleWrapper then
814 return not self.baler.allowsBaleUnloading or (self.baler.allowsBaleUnloading and not self:getIsTurnedOn() and not self.baler.isBaleUnloading)
815 end
816
817 return self:allowsGrabbingBale()
818end

setIsUnloadingBale

Description
Set bale unloading
Definition
setIsUnloadingBale(boolean isUnloadingBale, boolean noEventSend)
Arguments
booleanisUnloadingBaleis unloading bale
booleannoEventSendno event send
Code
824function Baler:setIsUnloadingBale(isUnloadingBale, noEventSend)
825 if self.baler.baleUnloadAnimationName ~= nil then
826 if isUnloadingBale then
827 if self.baler.unloadingState ~= Baler.UNLOADING_OPENING then
828 BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend)
829 self.baler.unloadingState = Baler.UNLOADING_OPENING
830 if self.isClient and self:getIsActiveForSound() then
831 SoundUtil.playSample(self.baler.sampleBalerEject, 1, 0, nil)
832 SoundUtil.playSample(self.baler.sampleBalerDoor, 1, 0, nil)
833 end
834 self:playAnimation(self.baler.baleUnloadAnimationName, self.baler.baleUnloadAnimationSpeed, nil, true)
835 end
836 else
837 if self.baler.unloadingState ~= Baler.UNLOADING_CLOSING then
838 BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend)
839 self.baler.unloadingState = Baler.UNLOADING_CLOSING
840 if self.isClient and self:getIsActiveForSound() then
841 SoundUtil.playSample(self.baler.sampleBalerDoor, 1, 0, nil)
842 end
843 self:playAnimation(self.baler.baleCloseAnimationName, self.baler.baleCloseAnimationSpeed, nil, true)
844 end
845 end
846 elseif self.baler.allowsBaleUnloading then
847 if isUnloadingBale then
848 BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend)
849 self.baler.isBaleUnloading = true
850 end
851 end
852end

getTimeFromLevel

Description
Returns time on animation depending on fill level
Definition
getTimeFromLevel(float level)
Arguments
floatlevelcurrent bale fill level
Code
858function Baler:getTimeFromLevel(level)
859 -- level = capacity -> time = firstBaleMarker
860 -- level = 0 -> time = 0
861 if self.baler.firstBaleMarker ~= nil then
862 return level / self:getCapacity() * self.baler.firstBaleMarker
863 end
864 return 0
865end

moveBales

Description
Move bales
Definition
moveBales(float dt)
Arguments
floatdttime since last call in ms
Code
870function Baler:moveBales(dt)
871 for i=table.getn(self.baler.bales), 1, -1 do
872 self:moveBale(i, dt)
873 end
874end

moveBale

Description
Move bale
Definition
moveBale(integer i, float dt, boolean noEventSend)
Arguments
integeriindex of bale to move
floatdttime since last call in ms
booleannoEventSendno event send
Code
881function Baler:moveBale(i, dt, noEventSend)
882 local bale = self.baler.bales[i]
883 self:setBaleTime(i, bale.time + dt, noEventSend)
884end

setBaleTime

Description
Set bale animation time
Definition
setBaleTime(integer i, float baleTime, boolean noEventSend)
Arguments
integeriindex of bale to move
floatbaleTimenew bale time
booleannoEventSendno event send
Code
891function Baler:setBaleTime(i, baleTime, noEventSend)
892 if self.baler.baleAnimCurve ~= nil then
893 local bale = self.baler.bales[i]
894 bale.time = baleTime
895 if self.isServer then
896 local v = self.baler.baleAnimCurve:get(bale.time)
897 --setTranslation(bale.id, v[1], v[2], v[3])
898 --setRotation(bale.id, v[4], v[5], v[6])
899 setTranslation(bale.baleJointNode, v[1], v[2], v[3])
900 setRotation(bale.baleJointNode, v[4], v[5], v[6])
901 if bale.baleJointIndex ~= 0 then
902 setJointFrame(bale.baleJointIndex, 0, bale.baleJointNode)
903 end
904 end
905 if bale.time >= 1 then
906 self:dropBale(i)
907 end
908 if table.getn(self.baler.bales) == 0 then
909 self.baler.isBaleUnloading = false
910 end
911 if self.isServer then
912 if noEventSend == nil or not noEventSend then
913 g_server:broadcastEvent(BalerSetBaleTimeEvent:new(self, i, bale.time), nil, nil, self)
914 end
915 end
916 end
917end

allowFillType

Description
Returns if fill type is allowed
Definition
allowFillType(integer fillType)
Arguments
integerfillTypefill type
Return Values
booleanisAllowedfill type is allowed
Code
923function Baler:allowFillType(fillType)
924 return self.baler.pickupFillTypes[fillType] ~= nil
925end

allowPickingUp

Description
Returns if picking up is allowed
Definition
allowPickingUp()
Return Values
booleanisAllowedpicking up is allowed
Code
930function Baler:allowPickingUp(superFunc)
931 if self.baler.baleUnloadAnimationName ~= nil then
932 if table.getn(self.baler.bales) > 0 or self.baler.unloadingState ~= Baler.UNLOADING_CLOSED then
933 return false
934 end
935 end
936
937 if superFunc ~= nil then
938 return superFunc(self)
939 end
940 return true
941end

createBale

Description
Create new bale in baler
Definition
createBale(integer baleFillType, float fillLevel)
Arguments
integerbaleFillTypefill type of bale to create
floatfillLevelfill level of bale
Code
947function Baler:createBale(baleFillType, fillLevel)
948
949 if self.baler.knotingAnimation ~= nil then
950 self:playAnimation(self.baler.knotingAnimation, self.baler.knotingAnimationSpeed, nil, true)
951 end
952
953 if self.baler.dummyBale.currentBale ~= nil then
954 delete(self.baler.dummyBale.currentBale)
955 self.baler.dummyBale.currentBale = nil
956 end
957
958 local t = self.baler.baleTypes[self.baler.currentBaleTypeId]
959 local baleType = BaleUtil.getBale(baleFillType, t.width, t.height, t.length, t.diameter, t.isRoundBale)
960
961 local bale = {}
962 bale.filename = Utils.getFilename(baleType.filename, self.baseDirectory)
963 bale.time = 0
964 bale.fillType = baleFillType
965 bale.fillLevel = fillLevel
966
967 if self.baler.baleUnloadAnimationName ~= nil then
968 local baleRoot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory, false, false)
969 local baleId = getChildAt(baleRoot, 0)
970 link(self.baler.baleAnimRoot, baleId)
971 delete(baleRoot)
972 bale.id = baleId
973 end
974
975 if self.isServer and self.baler.baleUnloadAnimationName == nil then
976 local x,y,z = getWorldTranslation(self.baler.baleAnimRoot)
977 local rx,ry,rz = getWorldRotation(self.baler.baleAnimRoot)
978
979 local baleObject = Bale:new(self.isServer, self.isClient)
980 baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel)
981 baleObject:register()
982 baleObject:setCanBeSold(false)
983
984 local baleJointNode = createTransformGroup("BaleJointTG")
985 link(self.baler.baleAnimRoot, baleJointNode)
986 setTranslation(baleJointNode, 0,0,0)
987 setRotation(baleJointNode, 0,0,0)
988
989 local constr = JointConstructor:new()
990 constr:setActors(self.baler.baleAnimRootComponent, baleObject.nodeId)
991 constr:setJointTransforms(baleJointNode, baleObject.nodeId)
992 for i=1, 3 do
993 constr:setRotationLimit(i-1, 0, 0)
994 constr:setTranslationLimit(i-1, true, 0, 0)
995 end
996 constr:setEnableCollision(false)
997 local baleJointIndex = constr:finalize()
998
999 g_currentMission:removeItemToSave(baleObject)
1000
1001 bale.baleJointNode = baleJointNode
1002 bale.baleJointIndex = baleJointIndex
1003 bale.baleObject = baleObject
1004 end
1005
1006 table.insert(self.baler.bales, bale)
1007end

dropBale

Description
Drop bale
Definition
dropBale(integer baleIndex)
Arguments
integerbaleIndexindex of bale
Code
1012function Baler:dropBale(baleIndex)
1013 local bale = self.baler.bales[baleIndex]
1014
1015 if self.isServer then
1016 local baleObject
1017
1018 if bale.baleJointIndex ~= nil then
1019 baleObject = bale.baleObject
1020 removeJoint(bale.baleJointIndex)
1021 delete(bale.baleJointNode)
1022 g_currentMission:addItemToSave(bale.baleObject)
1023 else
1024 baleObject = Bale:new(self.isServer, self.isClient)
1025 local x,y,z = getWorldTranslation(bale.id)
1026 local rx,ry,rz = getWorldRotation(bale.id)
1027 baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel)
1028 baleObject:register()
1029 delete(bale.id)
1030 end
1031
1032 baleObject:setCanBeSold(true)
1033
1034 if (not self.hasBaleWrapper or self.moveBaleToWrapper == nil) and baleObject.nodeId ~= nil then
1035 -- release bale if there's no bale wrapper
1036 local x,y,z = getWorldTranslation(baleObject.nodeId)
1037 local vx,vy,vz = getVelocityAtWorldPos(self.baler.baleAnimRootComponent, x,y,z)
1038 setLinearVelocity(baleObject.nodeId, vx,vy,vz)
1039 elseif self.moveBaleToWrapper ~= nil then
1040 -- move bale to wrapper
1041 self:moveBaleToWrapper(baleObject)
1042 end
1043 end
1044
1045 Utils.releaseSharedI3DFile(bale.filename, nil, true)
1046 table.remove(self.baler.bales, baleIndex)
1047
1048 g_currentMission.missionStats:updateStats("baleCount", 1)
1049end

getIsTurnedOnAllowed

Description
Returns if turn on is allowed
Definition
getIsTurnedOnAllowed(boolean isTurnedOn)
Arguments
booleanisTurnedOnis turned on
Return Values
booleanallowallow turn on
Code
1055function Baler:getIsTurnedOnAllowed(superFunc, isTurnedOn)
1056 if isTurnedOn and self.baler.isBaleUnloading then
1057 return false
1058 end
1059
1060 if superFunc ~= nil then
1061 return superFunc(self, isTurnedOn)
1062 end
1063
1064 return true
1065end

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
1073function Baler:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
1074 local retValue = true
1075 if superFunc ~= nil then
1076 retValue = superFunc(self, workArea, xmlFile, key)
1077 end
1078
1079 if workArea.type == WorkArea.AREATYPE_DEFAULT then
1080 workArea.type = WorkArea.AREATYPE_BALER
1081 end
1082
1083 return retValue
1084end

loadSpeedRotatingPartFromXML

Description
Loads speed rotating parts from xml
Definition
loadSpeedRotatingPartFromXML(table speedRotatingPart, integer xmlFile, string key)
Arguments
tablespeedRotatingPartspeedRotatingPart
integerxmlFileid of xml object
stringkeykey
Return Values
booleansuccesssuccess
Code
1092function Baler:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
1093 if superFunc ~= nil then
1094 if not superFunc(self, speedRotatingPart, xmlFile, key) then
1095 return false
1096 end
1097 end
1098
1099 speedRotatingPart.rotateOnlyIfFillLevelIncreased = Utils.getNoNil(getXMLBool(xmlFile, key .. "#rotateOnlyIfFillLevelIncreased"), false)
1100
1101 return true
1102end

getIsSpeedRotatingPartActive

Description
Returns true if speed rotating part is active
Definition
getIsSpeedRotatingPartActive(table speedRotatingPart)
Arguments
tablespeedRotatingPartspeedRotatingPart
Return Values
booleanisActivespeed rotating part is active
Code
1108function Baler:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
1109 if speedRotatingPart.rotateOnlyIfFillLevelIncreased ~= nil then
1110 if speedRotatingPart.rotateOnlyIfFillLevelIncreased and not self.baler.lastAreaBiggerZero then
1111 return false
1112 end
1113 end
1114
1115 if superFunc ~= nil then
1116 return superFunc(self, speedRotatingPart)
1117 end
1118 return true
1119end

getDefaultSpeedLimit

Description
Returns default speed limit
Definition
getDefaultSpeedLimit()
Return Values
floatspeedLimitspeed limit
Code
1124function Baler.getDefaultSpeedLimit()
1125 return 25
1126end

processBalerAreas

Description
Process baler areas
Definition
processBalerAreas(table workAreas, table fillTypes)
Arguments
tableworkAreaswork areas to process
tablefillTypesfill types
Return Values
floattotalLiterstotal liters picked up
integerusedFillTypefill type picked up
Code
1134function Baler:processBalerAreas(workAreas, fillTypes)
1135
1136 local totalLiters = 0
1137 local usedFillType = FillUtil.FILLTYPE_UNKNOWN
1138
1139 local numAreas = table.getn(workAreas)
1140 for i=1, numAreas do
1141 local x0 = workAreas[i][1]
1142 local z0 = workAreas[i][2]
1143 local x1 = workAreas[i][3]
1144 local z1 = workAreas[i][4]
1145 local x2 = workAreas[i][5]
1146 local z2 = workAreas[i][6]
1147
1148 local hx = x2 - x0
1149 local hz = z2 - z0
1150 local hLength = Utils.vector2Length(hx, hz)
1151 local hLength_2 = 0.5 * hLength
1152
1153 local wx = x1 - x0
1154 local wz = z1 - z0
1155 local wLength = Utils.vector2Length(wx, wz)
1156
1157 local sx = x0 + (hx * 0.5) + ((wx/wLength)*hLength_2)
1158 local sz = z0 + (hz * 0.5) + ((wz/wLength)*hLength_2)
1159
1160 local ex = x1 + (hx * 0.5) - ((wx/wLength)*hLength_2)
1161 local ez = z1 + (hz * 0.5) - ((wz/wLength)*hLength_2)
1162
1163 local sy = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, sx,0,sz)
1164 local ey = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, ex,0,ez)
1165
1166
1167 if usedFillType == FillUtil.FILLTYPE_UNKNOWN then
1168 for _, fillType in pairs(fillTypes) do
1169 local liters = -TipUtil.tipToGroundAroundLine(self, -math.huge, fillType, sx,sy,sz, ex,ey,ez, hLength_2, nil, nil, false, nil)
1170 if liters > 0 then
1171 usedFillType = fillType
1172 totalLiters = totalLiters + liters
1173 break
1174 end
1175 end
1176 else
1177 totalLiters = totalLiters - TipUtil.tipToGroundAroundLine(self, -math.huge, usedFillType, sx,sy,sz, ex,ey,ez, hLength_2, nil, nil, false, nil)
1178 end
1179
1180 end
1181
1182 return totalLiters, usedFillType
1183end