LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

SowingMachine

Description
Class for all sowing machines
Functions

initSpecialization

Description
Called on specialization initializing
Definition
initSpecialization()
Code
19function SowingMachine.initSpecialization()
20 WorkArea.registerAreaType("sowingMachine")
21end

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
27function SowingMachine.prerequisitesPresent(specializations)
28 return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) and SpecializationUtil.hasSpecialization(FillVolume, specializations)
29end

preLoad

Description
Called before loading
Definition
preLoad(table savegame)
Arguments
tablesavegamesavegame
Code
34function SowingMachine:preLoad(savegame)
35 self.supportsFillTriggers = true
36 self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, SowingMachine.loadWorkAreaFromXML)
37 self.getDrawFirstFillText = Utils.overwrittenFunction(self.getDrawFirstFillText, SowingMachine.getDrawFirstFillText)
38end

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
43function SowingMachine:load(savegame)
44
45 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnOnAnimation#name", "vehicle.turnOnVehicle.turnedAnimation#name")
46 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnOnAnimation#speed", "vehicle.turnOnVehicle.turnedAnimation#turnOnSpeedScale")
47 Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.drum#index", "vehicle.speedRotatingParts.speedRotatingPart")
48
49
50 self.setSeedFruitType = SpecializationUtil.callSpecializationsFunction("setSeedFruitType")
51 self.setSeedIndex = SpecializationUtil.callSpecializationsFunction("setSeedIndex")
52 self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, SowingMachine.getIsTurnedOnAllowed)
53 self.getAllowFillFromAir = Utils.overwrittenFunction(self.getAllowFillFromAir, SowingMachine.getAllowFillFromAir)
54 self.getDirectionSnapAngle = Utils.overwrittenFunction(self.getDirectionSnapAngle, SowingMachine.getDirectionSnapAngle)
55 self.resetUnitFillLevelIfNeeded = Utils.overwrittenFunction(self.resetUnitFillLevelIfNeeded, SowingMachine.resetUnitFillLevelIfNeeded)
56 self.resetFillLevelIfNeeded = Utils.overwrittenFunction(self.resetFillLevelIfNeeded, SowingMachine.resetFillLevelIfNeeded)
57 self.allowFillType = Utils.overwrittenFunction(self.allowFillType, SowingMachine.allowFillType)
58 self.allowUnitFillType = Utils.overwrittenFunction(self.allowUnitFillType, SowingMachine.allowUnitFillType)
59 self.setUnitFillLevel = Utils.overwrittenFunction(self.setUnitFillLevel, SowingMachine.setUnitFillLevel)
60 self.getDirtMultiplier = Utils.overwrittenFunction(self.getDirtMultiplier, SowingMachine.getDirtMultiplier)
61 self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, SowingMachine.doCheckSpeedLimit)
62 self.getFillLevelInformation = Utils.overwrittenFunction(self.getFillLevelInformation, SowingMachine.getFillLevelInformation)
63 self.processSowingMachineAreas = SowingMachine.processSowingMachineAreas
64 self.getIsSeedChangeAllowed = SowingMachine.getIsSeedChangeAllowed
65
66 self.isSeedTank = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine#isTank"), false);
67 self.requiresTank = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine#requiresTank"), false);
68
69 if next(self.groundReferenceNodes) == nil and not self.isSeedTank then
70 print("Warning: No ground reference nodes in "..self.configFileName)
71 end
72
73 self.allowFillFromAirWhileTurnedOn = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.allowFillFromAirWhileTurnedOn#value"), true)
74 self.sowingDirectionNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.sowingDirectionNode#index")), self.components[1].node)
75 self.useDirectPlanting = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.useDirectPlanting"), false)
76 self.sowingMachineHasGroundContact = false
77
78 self.seeds = {}
79 local fruitTypes = {}
80 local fruitTypeCategories = getXMLString(self.xmlFile, "vehicle.seedFruitTypeCategories")
81 local fruitTypeNames = getXMLString(self.xmlFile, "vehicle.seedFruitTypes")
82 if fruitTypeCategories ~= nil and fruitTypeNames == nil then
83 fruitTypes = FruitUtil.getFruitTypeByCategoryName(fruitTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fruitTypeCategory '%s'.")
84 elseif fruitTypeCategories == nil and fruitTypeNames ~= nil then
85 fruitTypes = FruitUtil.getFruitTypesByNames(fruitTypeNames, "Warning: '"..self.configFileName.. "' has invalid fruitType '%s'.")
86 else
87 print("Warning: '"..self.configFileName.. "' a sowingMachine needs either the 'seedFruitTypeCategories' or 'seedFruitTypes' element.")
88 end
89
90 if fruitTypes ~= nil then
91 for _,fruitType in pairs(fruitTypes) do
92 table.insert(self.seeds, fruitType)
93 end
94 end
95
96 self.needsActivation = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.needsActivation#value"), false)
97
98 if self.isClient then
99 self.sampleSowing = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.sowingSound", nil, self.baseDirectory)
100 self.sampleAirBlower = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.airBlowerSound", nil, self.baseDirectory)
101
102 if self.sampleFill == nil then
103 local linkNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.fillSound#linkNode"), "0>"))
104 self.sampleFill = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.fillSound", nil, self.baseDirectory, linkNode)
105 end
106 self.sampleFillEnabled = false
107 self.sampleFillStopTime = -1
108 self.lastFillLevel = -1
109
110 self.sowingMachineTurnedOnRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "sowingMachine", self.components)
111 self.turnedOnScrollers = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.turnedOnScrollers.turnedOnScroller", {}, false)
112
113 local changeSeedInputButtonStr = getXMLString(self.xmlFile, "vehicle.changeSeedInputButton")
114 if changeSeedInputButtonStr ~= nil then
115 self.changeSeedInputButton = InputBinding[changeSeedInputButtonStr]
116 end
117 self.changeSeedInputButton = Utils.getNoNil(self.changeSeedInputButton, InputBinding.IMPLEMENT_EXTRA3)
118 end
119
120 self.lastSowingArea = 0
121 self.currentSeed = 1
122 self.allowsSeedChanging = not self.isSeedTank;
123 self.showFieldNotOwnedWarning = false
124
125 self.isSowingSpeedLimitActive = false
126
127 self.sowingMachine = {}
128 self.sowingMachine.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#fillUnitIndex"), 1)
129 self.sowingMachine.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#unloadInfoIndex"), 1)
130 self.sowingMachine.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#loadInfoIndex"), 1)
131 self.sowingMachine.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#dischargeInfoIndex"), 1)
132
133 if self.fillUnits ~= nil and self.fillUnits[self.sowingMachine.fillUnitIndex] ~= nil then
134 self.fillUnits[self.sowingMachine.fillUnitIndex].forcedFillPlaneType = self.seeds[self.currentSeed]
135 end
136
137 if self.fillUnits[self.sowingMachine.fillUnitIndex] ~= nil then
138 self.fillUnits[self.sowingMachine.fillUnitIndex].fillTypes[FillUtil.FILLTYPE_SEEDS] = true
139 end
140
141 self.sowingMachine.supportsAiWithoutSowingMachine = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine#supportsAiWithoutSowingMachine"), false);
142 self.sowingMachine.ignoreSowingMachineAiRequirements = false; -- This is set to true in case the ai should not use the sowing machine
143
144 self.sowingMachineGroundContactFlag = self:getNextDirtyFlag()
145
146 if savegame ~= nil then
147 local selectedSeedFruitType = getXMLString(savegame.xmlFile, savegame.key.."#selectedSeedFruitType")
148 if selectedSeedFruitType ~= nil then
149 local fruitTypeDesc = FruitUtil.fruitTypes[selectedSeedFruitType]
150 if fruitTypeDesc ~= nil then
151 self:setSeedFruitType(fruitTypeDesc.index, true)
152 end
153 end
154 else
155 self:setSeedIndex(1, true)
156 end
157end

delete

Description
Called on deleting
Definition
delete()
Code
166function SowingMachine:delete()
167 if self.isClient then
168 SoundUtil.deleteSample(self.sampleSowing)
169 SoundUtil.deleteSample(self.sampleAirBlower)
170 SoundUtil.deleteSample(self.sampleFill)
171 end
172end

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
178function SowingMachine:readStream(streamId, connection)
179 local seedIndex = streamReadUInt8(streamId)
180 self:setSeedIndex(seedIndex, true)
181end

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
187function SowingMachine:writeStream(streamId, connection)
188 streamWriteUInt8(streamId, self.currentSeed)
189end

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
197function SowingMachine:readUpdateStream(streamId, timestamp, connection)
198 if connection:getIsServer() then
199 self.sowingMachineHasGroundContact = streamReadBool(streamId)
200 self.showFieldNotOwnedWarning = streamReadBool(streamId)
201 end
202end

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
209function SowingMachine:writeUpdateStream(streamId, connection, dirtyMask)
210 if not connection:getIsServer() then
211 streamWriteBool(streamId, self.sowingMachineHasGroundContact)
212 streamWriteBool(streamId, self.showFieldNotOwnedWarning)
213 end
214end

getSaveAttributesAndNodes

Description
Returns attributes and nodes to save
Definition
getSaveAttributesAndNodes(table nodeIdent)
Arguments
tablenodeIdentnode ident
Return Values
stringattributesattributes
stringnodesnodes
Code
221function SowingMachine:getSaveAttributesAndNodes(nodeIdent)
222 local selectedSeedFruitTypeName = "unknown"
223 local selectedSeedFruitType = self.seeds[self.currentSeed]
224 if selectedSeedFruitType ~= nil and selectedSeedFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
225 selectedSeedFruitTypeName = FruitUtil.fruitIndexToDesc[selectedSeedFruitType].name
226 end
227 local attributes = 'selectedSeedFruitType="'..selectedSeedFruitTypeName..'"'
228 return attributes, nil
229end

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
240function SowingMachine:update(dt)
241
242 if self:getIsActive() then
243 if self:getIsActiveForInput() then
244 if InputBinding.hasEvent(self.changeSeedInputButton) then
245
246 if self:getIsSeedChangeAllowed() then
247 local seed = self.currentSeed + 1
248 if seed > table.getn(self.seeds) then
249 seed = 1
250 end
251 self:setSeedIndex(seed)
252 end
253 end
254 end
255 end
256 if self.isClient then
257 Utils.updateRotationNodes(self, self.sowingMachineTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn())
258 Utils.updateScrollers(self.turnedOnScrollers, dt, self:getIsActive() and self:getIsTurnedOn())
259 end
260end

updateTick

Description
Called on update tick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
265function SowingMachine:updateTick(dt)
266 self.isSowingSpeedLimitActive = false
267 if self:getIsActive() then
268
269 self.lastSowingArea = 0
270 local showFieldNotOwnedWarning = false
271 if self.isServer then
272 local hasGroundContact = self:getIsTypedWorkAreaActive(WorkArea.AREATYPE_SOWINGMACHINE)
273
274 if self.sowingMachineHasGroundContact ~= hasGroundContact then
275 self:raiseDirtyFlags(self.sowingMachineGroundContactFlag)
276
277 self.sowingMachineHasGroundContact = hasGroundContact
278 end
279 end
280 local hasGroundContact = self.sowingMachineHasGroundContact
281
282 local doGroundManipulation = (self.movingDirection > 0 and hasGroundContact and (not self.needsActivation or self:getIsTurnedOn())) and (not self.sowingMachine.ignoreSowingMachineAiRequirements);
283
284 if doGroundManipulation then
285 local workAreas, showWarning, _ = self:getTypedNetworkAreas(WorkArea.AREATYPE_SOWINGMACHINE, true)
286
287 self.isSowingSpeedLimitActive = true
288 if self.isServer then
289
290 local hasSeeds = false
291 local seedVehicle = self
292 local seedTank = nil;
293
294 if self:getUnitFillLevel(self.sowingMachine.fillUnitIndex) > 0 then
295 hasSeeds = true
296 else
297 -- try to find another attached sowingMachine
298 seedTank = SowingMachine.findAttachedSeedTank(self:getRootAttacherVehicle(), FillUtil.FILLTYPE_SEEDS, self.needsTankActivation)
299 if seedTank ~= nil then
300 if seedTank:getFillLevel(FillUtil.FILLTYPE_SEEDS) > 0 then
301 hasSeeds = true
302 seedVehicle = seedTank
303 end
304 end
305 end
306
307 if self.requiresTank and seedTank == nil then
308 hasSeeds = false;
309 end;
310
311 if not hasSeeds and (self:getIsHired() and g_currentMission.missionInfo.helperBuySeeds) then
312 hasSeeds = true
313 end
314
315 if hasSeeds then
316 showFieldNotOwnedWarning = showWarning
317
318 if (table.getn(workAreas) > 0) then
319 local seedsFruitType = self.seeds[self.currentSeed]
320 local dx,_,dz = localDirectionToWorld(self.sowingDirectionNode, 0, 0, 1)
321
322 local angleRad = Utils.getYRotationFromDirection(dx, dz)
323 local desc = FruitUtil.fruitIndexToDesc[seedsFruitType]
324 if desc ~= nil and desc.directionSnapAngle ~= 0 then
325 angleRad = math.floor(angleRad / desc.directionSnapAngle + 0.5) * desc.directionSnapAngle
326 end
327
328 local angle = Utils.convertToDensityMapAngle(angleRad, g_currentMission.terrainDetailAngleMaxValue)
329
330 local area, detailArea = self:processSowingMachineAreas(workAreas, seedsFruitType, angle, self.useDirectPlanting)
331 if area > 0 or detailArea > 0 then
332 if area > 0 then
333 local fruitDesc = FruitUtil.fruitIndexToDesc[seedsFruitType]
334 self.lastSowingArea = Utils.areaToHa(area, g_currentMission:getFruitPixelsToSqm())
335 local usage = fruitDesc.seedUsagePerSqm * self.lastSowingArea * 10000
336
337 g_currentMission.missionStats:updateStats("seedUsage", usage)
338 g_currentMission.missionStats:updateStats("sownHectares", self.lastSowingArea)
339 g_currentMission.missionStats:updateStats("workedHectares", self.lastSowingArea)
340
341 if not self:getIsHired() or not g_currentMission.missionInfo.helperBuySeeds then
342 local oldFillLevel = seedVehicle:getFillLevel(FillUtil.FILLTYPE_SEEDS)
343 local fillInfos = seedVehicle.fillVolumeUnloadInfos[seedVehicle.sowingMachine.unloadInfoIndex]
344 seedVehicle:setFillLevel(oldFillLevel - usage, FillUtil.FILLTYPE_SEEDS, fillInfos)
345 else
346 local price = usage * g_currentMission.economyManager:getCostPerLiter(FillUtil.FILLTYPE_SEEDS) * 1.5 -- increase price if AI is active to reward the player's manual work
347 g_currentMission.missionStats:updateStats("expenses", price)
348 g_currentMission:addSharedMoney(-price, "purchaseSeeds")
349 end
350 end
351 end
352 end
353 else
354 if self:getIsHired() then
355 local rootVehicle = self:getRootAttacherVehicle()
356 rootVehicle:stopAIVehicle(AIVehicle.STOP_REASON_OUT_OF_FILL)
357 end
358 end
359 end
360
361 -- remove tireTracks
362 for _, workArea in pairs(workAreas) do
363 Utils.eraseTireTrack(workArea[1], workArea[2], workArea[3], workArea[4], workArea[5], workArea[6])
364 end
365
366 g_currentMission.missionStats:updateStats("sownTime", dt/(1000*60))
367 g_currentMission.missionStats:updateStats("workedTime", dt/(1000*60))
368 end
369
370 if self.isClient then
371 if doGroundManipulation and self:getLastSpeed() > 3 then
372 if self:getIsActiveForSound() then
373 SoundUtil.playSample(self.sampleSowing, 0, 0, nil)
374 end
375 else
376 SoundUtil.stopSample(self.sampleSowing)
377 end
378
379 if self:getIsTurnedOn() and self:getIsActiveForSound() then
380 SoundUtil.playSample(self.sampleAirBlower, 0, 0, nil)
381 end
382 end
383
384 if self.isServer then
385 if showFieldNotOwnedWarning ~= self.showFieldNotOwnedWarning then
386 self.showFieldNotOwnedWarning = showFieldNotOwnedWarning
387 self:raiseDirtyFlags(self.sowingMachineGroundContactFlag)
388 end
389 end
390 end
391
392 if self.isClient then
393 if self.isFilling then
394 if self:getIsActiveForSound(true) then
395 SoundUtil.playSample(self.sampleFill, 0, 0, nil)
396 SoundUtil.stop3DSample(self.sampleFill)
397 else
398 SoundUtil.stopSample(self.sampleFill)
399 SoundUtil.play3DSample(self.sampleFill)
400 end
401 else
402 SoundUtil.stopSample(self.sampleFill)
403 SoundUtil.stop3DSample(self.sampleFill)
404 end
405 end
406end

draw

Description
Called on draw
Definition
draw()
Code
410function SowingMachine:draw()
411
412 if self.isClient then
413 if self:getIsActiveForInput(true) then
414 if self:getIsSeedChangeAllowed() and table.getn(self.seeds) > 1 then
415 g_currentMission:addHelpButtonText(g_i18n:getText("action_chooseSeed"), self.changeSeedInputButton, nil, GS_PRIO_HIGH)
416 end
417 end
418
419 --g_currentMission:setFruitOverlayFruitType(self.seeds[self.currentSeed])
420
421 if self.showFieldNotOwnedWarning then
422 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_youDontOwnThisField"))
423 end
424 end
425end

getDrawFirstFillText

Description
Returns if 'first fill tool' text should be drawed
Definition
getDrawFirstFillText()
Return Values
booleandrawdraw text
Code
430function SowingMachine:getDrawFirstFillText(superFunc)
431 if self.isClient then
432 if self:getIsActiveForInput(true) then
433 if self:getUnitFillLevel(self.sowingMachine.fillUnitIndex) <= 0 and self:getUnitCapacity(self.sowingMachine.fillUnitIndex) ~= 0 then
434 return true
435 end
436 end
437 end
438 if superFunc ~= nil then
439 return superFunc(self)
440 end
441
442 return false
443end

onAttach

Description
Called if vehicle gets attached
Definition
onAttach(table attacherVehicle)
Arguments
tableattacherVehicleattacher vehicle
Code
448function SowingMachine:onAttach(attacherVehicle)
449 SowingMachine.onActivate(self)
450end

onEnter

Description
Called on enter vehicle
Definition
onEnter(boolean isControlling)
Arguments
booleanisControllingis player controlling the vehicle
Code
455function SowingMachine:onEnter(isControlling)
456 if isControlling then
457 SowingMachine.onActivate(self)
458 end
459end

onDeactivate

Description
Called on deactivate
Definition
onDeactivate()
Code
466function SowingMachine:onDeactivate()
467 self.showFieldNotOwnedWarning = false
468end

getIsTurnedOnAllowed

Description
Returns if turn on is allowed
Definition
getIsTurnedOnAllowed(boolean isTurnedOn)
Arguments
booleanisTurnedOnis turned on
Return Values
booleanallowallow turn on
Code
474function SowingMachine:getIsTurnedOnAllowed(superFunc, isTurnedOn)
475 if not self.needsActivation then
476 return false
477 end
478
479 if isTurnedOn and self:getUnitFillLevel(self.sowingMachine.fillUnitIndex) <= 0 then
480 if self:getUnitCapacity(self.sowingMachine.fillUnitIndex) > 0 and not self:getIsHired() then
481 local seedTank = SowingMachine.findAttachedSeedTank(self:getRootAttacherVehicle(), FillUtil.FILLTYPE_SEEDS, self.needsTankActivation)
482 if seedTank ~= nil then
483 if seedTank:getFillLevel(FillUtil.FILLTYPE_SEEDS) <= 0 then
484 seedTank = nil;
485 end;
486 end;
487
488 if seedTank == nil then
489 return false
490 end;
491 end
492 end
493
494 if superFunc ~= nil then
495 return superFunc(self, isTurnedOn)
496 end
497
498 return true
499end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
504function SowingMachine:onTurnedOff(noEventSend)
505 if self.isClient then
506 SoundUtil.stopSample(self.sampleAirBlower)
507 end
508end

onDeactivateSounds

Description
Called on deactivating sounds
Definition
onDeactivateSounds()
Code
512function SowingMachine:onDeactivateSounds()
513 if self.isClient then
514 SoundUtil.stopSample(self.sampleSowing, true)
515 SoundUtil.stopSample(self.sampleAirBlower, true)
516 end
517end

setSeedIndex

Description
Change selected seed
Definition
setSeedIndex(integer seedIndex, boolean noEventSend)
Arguments
integerseedIndexnew seed index
booleannoEventSendno event send
Code
523function SowingMachine:setSeedIndex(seedIndex, noEventSend)
524 SowingMachineSetSeedIndex.sendEvent(self, seedIndex, noEventSend)
525 self.currentSeed = math.min(math.max(seedIndex, 1), table.getn(self.seeds))
526 SowingMachine.updateAiParameters(self)
527end

setSeedFruitType

Description
Set selected seed by fruit type index
Definition
setSeedFruitType(integer fruitType, boolean noEventSend)
Arguments
integerfruitTypeindex of fruit type
booleannoEventSendno event send
Code
584function SowingMachine:setSeedFruitType(fruitType, noEventSend)
585 for i,v in ipairs(self.seeds) do
586 if v == fruitType then
587 self:setSeedIndex(i, noEventSend)
588 break
589 end
590 end
591end

onAiTurnOn

Description
Called on ai turn on
Definition
onAiTurnOn()
Code
595function SowingMachine:onAiTurnOn()
596 if self.sowingMachine.supportsAiWithoutSowingMachine then
597 if SpecializationUtil.hasSpecialization(Cultivator, self.specializations) or
598 SpecializationUtil.hasSpecialization(Weeder, self.specializations)
599 then
600 -- Don't use the sowing machine, when turning on the helper while the sowing machine is not turned on
601 self.sowingMachine.ignoreSowingMachineAiRequirements = self.sowingMachine.ignoreSowingMachineAiRequirements or not self:getIsTurnedOn();
602 SowingMachine.updateAiParameters(self);
603 end
604 end
605 self:setIsTurnedOn(true, true)
606end

onAiTurnOff

Description
Called on ai turn off
Definition
onAiTurnOff()
Code
610function SowingMachine:onAiTurnOff()
611 self:setIsTurnedOn(false, true)
612 if self.sowingMachine.supportsAiWithoutSowingMachine then
613 self.sowingMachine.ignoreSowingMachineAiRequirements = false;
614 SowingMachine.updateAiParameters(self);
615 end
616end

onAiLower

Description
Called on ai lower
Definition
onAiLower()
Code
620function SowingMachine:onAiLower()
621 self:setIsTurnedOn(true, true)
622end

onAiRaise

Description
Called on ai raise
Definition
onAiRaise()
Code
626function SowingMachine:onAiRaise()
627end

findAttachedSeedTank

Description
Searches for attached tanks
Definition
findAttachedSeedTank(table currentVehicle, integer fillType, boolean needsActivation)
Arguments
tablecurrentVehiclecurrent vehicle to check
integerfillTypefill type
booleanneedsActivationtank has to be turned on
Return Values
tableattachedSeedTankattached seed tank
Code
635function SowingMachine.findAttachedSeedTank(currentVehicle, fillType, needsTankActivation, ignoreFillLevel)
636 if currentVehicle.isSeedTank and currentVehicle.getFillLevel ~= nil and currentVehicle.setFillLevel ~= nil and (currentVehicle:getFillLevel(fillType) > 0 or ignoreFillLevel) and (not needsTankActivation or (currentVehicle.getIsTurnedOn ~= nil and currentVehicle:getIsTurnedOn())) then
637 return currentVehicle
638 end
639 for _,implement in pairs(currentVehicle.attachedImplements) do
640 if implement.object ~= nil then
641 local ret = SowingMachine.findAttachedSeedTank(implement.object, fillType, needsTankActivation, ignoreFillLevel)
642 if ret ~= nil then
643 return ret
644 end
645 end
646 end
647 return nil
648end

getAllowFillFromAir

Description
Returns if fill from air is allowed
Definition
getAllowFillFromAir()
Return Values
booleanisAllowedfill from air is allowed
Code
653function SowingMachine:getAllowFillFromAir(superFunc)
654 if self:getIsTurnedOn() and not self.allowFillFromAirWhileTurnedOn then
655 return false
656 end
657 return superFunc(self)
658end

getDirectionSnapAngle

Description
Returns direction snap angle
Definition
getDirectionSnapAngle()
Return Values
floatdirectionSnapAngledirection snap angle
Code
663function SowingMachine:getDirectionSnapAngle(superFunc)
664 local seedsFruitType = self.seeds[self.currentSeed]
665 local desc = FruitUtil.fruitIndexToDesc[seedsFruitType]
666 local snapAngle = 0
667 if desc ~= nil then
668 snapAngle = desc.directionSnapAngle
669 end
670 return math.max(snapAngle, superFunc(self))
671end

resetFillLevelIfNeeded

Description
Resets fill level if given fillType is different than the current fill type
Definition
resetFillLevelIfNeeded(integer fillType)
Arguments
integerfillTypefill type
Return Values
booleansuccessreturns false if reset failed
Code
677function SowingMachine:resetFillLevelIfNeeded(superFunc, fillType)
678 return false;
679end

resetUnitFillLevelIfNeeded

Description
Resets fill level of fill unit if given fillType is different than the current fill type
Definition
resetUnitFillLevelIfNeeded(integer fillUnitIndex, integer fillType)
Arguments
integerfillUnitIndexindex of fill unit
integerfillTypefill type
Return Values
booleansuccessreturns false if reset failed
Code
686function SowingMachine:resetUnitFillLevelIfNeeded(superFunc, fillUnitIndex, fillType)
687 return false;
688end

allowFillType

Description
Returns if fill type is allowed
Definition
allowFillType(integer fillType, boolean allowEmptying)
Arguments
integerfillTypefill type
booleanallowEmptyingallow emptying
Return Values
booleanallowallow fill type
Code
695function SowingMachine:allowFillType(superFunc, fillType, allowEmptying)
696 if fillType == FillUtil.FILLTYPE_UNKNOWN then
697 return true;
698 end
699 for i,fillUnit in pairs(self.fillUnits) do
700 if fillUnit.fillTypes[fillType] then
701 return true;
702 end
703 end
704 return false;
705end

allowUnitFillType

Description
Returns if fill type is allowed by fill unit
Definition
allowUnitFillType(integer fillUnitIndex, integer fillType, boolean allowEmptying)
Arguments
integerfillUnitIndexindex of fill unit
integerfillTypefill type
booleanallowEmptyingallow emptying
Return Values
booleanallowallow fill type
Code
713function SowingMachine:allowUnitFillType(superFunc, fillUnitIndex, fillType, allowEmptying)
714 if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then
715 return false;
716 end
717 local fillUnit = self.fillUnits[fillUnitIndex];
718 if fillUnit.fillTypes[fillType] then
719 return true;
720 end
721 return false;
722end

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
731function SowingMachine:setUnitFillLevel(superFunc, fillUnitIndex, fillLevel, fillType, force, fillInfo)
732 if fillUnitIndex == self.sowingMachine.fillUnitIndex then
733 -- convert everything to seeds if it is accepted
734 if self:allowUnitFillType(fillUnitIndex, fillType, false) then
735 fillType = FillUtil.FILLTYPE_SEEDS
736 self.fillUnits[fillUnitIndex].forcedFillPlaneType = FillUtil.FILLTYPE_SEEDS
737 end
738
739 -- switch from seeds to 'fill type', if possible
740 local fruitType = self.seeds[self.currentSeed]
741 if fruitType ~= nil then
742 local seedsFillType = FruitUtil.fruitTypeToFillType[fruitType]
743 if seedsFillType ~= nil then
744 if self:allowUnitFillType(fillUnitIndex, seedsFillType, false) then
745 self.fillUnits[fillUnitIndex].forcedFillPlaneType = seedsFillType
746 end
747 end
748 end
749
750 end
751
752 superFunc(self, fillUnitIndex, fillLevel, fillType, force, fillInfo)
753end

doCheckSpeedLimit

Description
Returns if speed limit should be checked
Definition
doCheckSpeedLimit()
Return Values
booleancheckSpeedlimitcheck speed limit
Code
758function SowingMachine:doCheckSpeedLimit(superFunc)
759 local parent = false
760 if superFunc ~= nil then
761 parent = superFunc(self)
762 end
763
764 return parent or self.isSowingSpeedLimitActive
765end

getDirtMultiplier

Description
Returns current dirt multiplier
Definition
getDirtMultiplier()
Return Values
floatdirtMultipliercurrent dirt multiplier
Code
770function SowingMachine:getDirtMultiplier(superFunc)
771 local multiplier = 0
772 if superFunc ~= nil then
773 multiplier = multiplier + superFunc(self)
774 end
775
776 if self.movingDirection > 0 and self.sowingMachineHasGroundContact and (not self.needsActivation or self:getIsTurnedOn()) then
777 multiplier = multiplier + self.workMultiplier * self:getLastSpeed() / self.speedLimit
778 end
779
780 return multiplier
781end

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
789function SowingMachine:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
790 local retValue = true
791 if superFunc ~= nil then
792 retValue = superFunc(self, workArea, xmlFile, key)
793 end
794
795 if workArea.type == WorkArea.AREATYPE_DEFAULT then
796 workArea.type = WorkArea.AREATYPE_SOWINGMACHINE
797 end
798
799 return retValue
800end

getDefaultSpeedLimit

Description
Returns default speed limit
Definition
getDefaultSpeedLimit()
Return Values
floatspeedLimitspeed limit
Code
805function SowingMachine.getDefaultSpeedLimit()
806 return 15
807end

processSowingMachineAreas

Description
Process sowing machine areas
Definition
processSowingMachineAreas(table workAreas, integer seed, float angle, boolean useDirectPlanting)
Arguments
tableworkAreaswork areas
integerseedseed type
floatanglecurrent angle
booleanuseDirectPlantinguse direction planting
Return Values
floatareaarea changed
floatdensityAreadensity area changed
Code
817function SowingMachine:processSowingMachineAreas(workAreas, seed, angle, useDirectPlanting)
818 local area = 0
819 local densityArea = 0
820 local numAreas = table.getn(workAreas)
821 for i=1, numAreas do
822 local x = workAreas[i][1]
823 local z = workAreas[i][2]
824 local x1 = workAreas[i][3]
825 local z1 = workAreas[i][4]
826 local x2 = workAreas[i][5]
827 local z2 = workAreas[i][6]
828
829 local areaI, densityAreaI
830
831 if not useDirectPlanting then
832 areaI, densityAreaI = Utils.updateSowingArea(seed, x, z, x1, z1, x2, z2, angle, useDirectPlanting)
833 else
834 areaI, densityAreaI = Utils.updateDirectSowingArea(seed, x, z, x1, z1, x2, z2, angle, 1);
835 end
836 area = area + areaI
837 densityArea = densityArea + densityAreaI
838 end
839 return area, densityArea
840end

getFillLevelInformation

Description
Added fill level information to display it on the hud
Definition
getFillLevelInformation(table fillLevelInformations)
Arguments
tablefillLevelInformationstable to add the informations
Code
845function SowingMachine:getFillLevelInformation(superFunc, fillLevelInformations)
846 if self.fillUnits ~= nil then
847 for fillUnitIndex,fillUnit in pairs(self.fillUnits) do
848 if fillUnit.showOnHud then
849 -- info for seed type
850 local fillType = fillUnit.currentFillType
851 local fillLevel = fillUnit.fillLevel;
852 local capacity = fillUnit.capacity;
853
854 if fillUnitIndex == self.sowingMachine.fillUnitIndex then
855 local fruitType = self.seeds[self.currentSeed]
856 fillType = FruitUtil.fruitTypeToFillType[fruitType]
857
858 -- add fill level from attached seed tank
859 if not self.isSeedTank then
860 local seedTank = SowingMachine.findAttachedSeedTank(self:getRootAttacherVehicle(), FillUtil.FILLTYPE_SEEDS, self.needsTankActivation, true)
861 if seedTank ~= nil then
862 fillLevel = fillLevel + seedTank:getUnitFillLevel(seedTank.sowingMachine.fillUnitIndex);
863 capacity = capacity + seedTank:getUnitCapacity(seedTank.sowingMachine.fillUnitIndex);
864 end;
865 end;
866 end
867
868 -- default info for sprayer, if empty
869 if fillUnit.fillLevel == 0 and self.sprayer ~= nil and fillUnitIndex == self.sprayer.fillUnitIndex and self.sprayer.fillUnitIndex ~= self.sowingMachine.fillUnitIndex then
870 for fType,state in pairs(fillUnit.fillTypes) do
871 if state then
872 fillType = fType
873 break
874 end
875 end
876 end
877
878 local added = false
879 for _,fillLevelInformation in pairs(fillLevelInformations) do
880 if fillLevelInformation.fillType == fillType then
881 fillLevelInformation.fillLevel = fillLevelInformation.fillLevel + fillLevel
882 fillLevelInformation.capacity = fillLevelInformation.capacity + capacity
883 added = true
884 break
885 end
886 end
887 if not added then
888 table.insert(fillLevelInformations, {fillType=fillType, fillLevel=fillLevel, capacity=capacity})
889 end
890 end;
891 end
892 end
893
894 for _, implement in pairs(self.attachedImplements) do
895 if implement.object ~= nil then
896 implement.object:getFillLevelInformation(fillLevelInformations)
897 end
898 end
899end

getIsSeedChangeAllowed

Description
Returns if seed change is allowed
Definition
getIsSeedChangeAllowed()
Return Values
booleanisAllowedseed change is allowed
Code
904function SowingMachine:getIsSeedChangeAllowed()
905 if self.getCanBeTurnedOn ~= nil and self:getCanBeTurnedOn() then
906 return (not self:getIsTurnedOn()) and self.allowsSeedChanging
907 end
908 return self.allowsSeedChanging
909end

loadSpecValueSeedFillTypes

Description
Loads seed fruit type categories and seed fruit types spec value
Definition
loadSpecValueSeedFillTypes(integer xmlFile, string customEnvironment)
Arguments
integerxmlFileid of xml object
stringcustomEnvironmentcustom environment
Return Values
tablespecValue[categories, names]
Code
916function SowingMachine.loadSpecValueSeedFillTypes(xmlFile, customEnvironment)
917 local categories = Utils.getNoNil(getXMLString(xmlFile, "vehicle.storeData.specs.seedFruitTypeCategories"), getXMLString(xmlFile, "vehicle.seedFruitTypeCategories"))
918 local names = Utils.getNoNil(getXMLString(xmlFile, "vehicle.storeData.specs.seedFruitTypes"), getXMLString(xmlFile, "vehicle.seedFruitTypes"))
919
920 return {categories=categories, names=names}
921end

getSpecValueSeedFillTypes

Description
Returns seed fill types spec value
Definition
getSpecValueSeedFillTypes(table storeItem, table realItem)
Arguments
tablestoreItemstore item
tablerealItemreal item
Return Values
tablefruitTypesfruit types
Code
928function SowingMachine.getSpecValueSeedFillTypes(storeItem, realItem)
929 local fruitTypes = nil
930
931 if storeItem.specs.seedFillTypes ~= nil then
932 local fruits = storeItem.specs.seedFillTypes
933 if fruits.categories ~= nil and fruits.names == nil then
934 fruitTypes = FillUtil.getFillTypesByFruitTypeCategoryName(fruits.categories, nil)
935 elseif fruits.categories == nil and fruits.names ~= nil then
936 fruitTypes = FillUtil.getFillTypesByFruitTypeNames(fruits.names, nil)
937 end
938 if fruitTypes ~= nil then
939 return fruitTypes
940 end
941 end
942
943 return nil
944end