LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

SowingMachine

Description
Specialization for sowing machines provoding seed selection functionality
Functions

actionEventToggleSeedType

Description
Definition
actionEventToggleSeedType()
Code
819function SowingMachine.actionEventToggleSeedType(self, actionName, inputValue, callbackState, isAnalog)
820 if self:getIsSeedChangeAllowed() then
821 local spec = self.spec_sowingMachine
822 local seed = spec.currentSeed + 1
823 if seed > table.getn(spec.seeds) then
824 seed = 1
825 end
826 self:setSeedIndex(seed)
827 end
828end

addFillUnitFillLevel

Description
Definition
addFillUnitFillLevel()
Code
459function SowingMachine:addFillUnitFillLevel(superFunc, farmId, fillUnitIndex, fillLevelDelta, fillType, toolType, fillInfo)
460 local spec = self.spec_sowingMachine
461
462 if fillUnitIndex == spec.fillUnitIndex then
463 -- force material of fillVolume to be seeds, if fillType is accepted
464 if self:getFillUnitSupportsFillType(fillUnitIndex, fillType) then
465 fillType = FillType.SEEDS
466 self:setFillUnitForcedMaterialFillType(fillUnitIndex, fillType)
467 end
468
469 -- switch from seeds to 'fill type', if possible
470 local fruitType = spec.seeds[spec.currentSeed]
471 if fruitType ~= nil then
472 local seedsFillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(fruitType)
473 if seedsFillType ~= nil then
474 if self:getFillUnitSupportsFillType(fillUnitIndex, seedsFillType) then
475 self:setFillUnitForcedMaterialFillType(fillUnitIndex, seedsFillType)
476 end
477 end
478 end
479 end
480
481 return superFunc(self, farmId, fillUnitIndex, fillLevelDelta, fillType, toolType, fillInfo)
482end

doCheckSpeedLimit

Description
Definition
doCheckSpeedLimit()
Code
486function SowingMachine:doCheckSpeedLimit(superFunc)
487 local spec = self.spec_sowingMachine
488 return superFunc(self) or (self:getIsImplementChainLowered() and (not spec.needsActivation or self:getIsTurnedOn()))
489end

getAllowFillFromAir

Description
Definition
getAllowFillFromAir()
Code
436function SowingMachine:getAllowFillFromAir(superFunc)
437 local spec = self.spec_sowingMachine
438 if self:getIsTurnedOn() and not spec.allowFillFromAirWhileTurnedOn then
439 return false
440 end
441 return superFunc(self)
442end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
532function SowingMachine:getCanBeSelected(superFunc)
533 return true
534end

getCanToggleTurnedOn

Description
Definition
getCanToggleTurnedOn()
Code
425function SowingMachine:getCanToggleTurnedOn(superFunc)
426 local spec = self.spec_sowingMachine
427 if not spec.needsActivation then
428 return false
429 end
430
431 return superFunc(self)
432end

getDefaultSpeedLimit

Description
Definition
getDefaultSpeedLimit()
Code
813function SowingMachine.getDefaultSpeedLimit()
814 return 15
815end

getDirectionSnapAngle

Description
Definition
getDirectionSnapAngle()
Code
446function SowingMachine:getDirectionSnapAngle(superFunc)
447 local spec = self.spec_sowingMachine
448 local seedsFruitType = spec.seeds[spec.currentSeed]
449 local desc = g_fruitTypeManager:getFruitTypeByIndex(seedsFruitType)
450 local snapAngle = 0
451 if desc ~= nil then
452 snapAngle = desc.directionSnapAngle
453 end
454 return math.max(snapAngle, superFunc(self))
455end

getDirtMultiplier

Description
Definition
getDirtMultiplier()
Code
493function SowingMachine:getDirtMultiplier(superFunc)
494 local spec = self.spec_sowingMachine
495 local multiplier = superFunc(self)
496
497 if self.movingDirection > 0 and spec.isWorking and (not spec.needsActivation or self:getIsTurnedOn()) then
498 multiplier = multiplier + self:getWorkDirtMultiplier() * self:getLastSpeed() / self.speedLimit
499 end
500
501 return multiplier
502end

getDrawFirstFillText

Description
Definition
getDrawFirstFillText()
Code
391function SowingMachine:getDrawFirstFillText(superFunc)
392 local spec = self.spec_sowingMachine
393 if self.isClient then
394 if self:getIsActiveForInput() and self:getIsSelected() then
395 if self:getFillUnitFillLevel(spec.fillUnitIndex) <= 0 and self:getFillUnitCapacity(spec.fillUnitIndex) ~= 0 then
396 return true
397 end
398 end
399 end
400
401 return superFunc(self)
402end

getFillUnitAllowsFillType

Description
Definition
getFillUnitAllowsFillType()
Code
406function SowingMachine:getFillUnitAllowsFillType(superFunc, fillUnitIndex, fillType)
407 if superFunc(self, fillUnitIndex, fillType) then
408 return true
409 end
410
411 local spec = self.spec_fillUnit
412 if spec.fillUnits[fillUnitIndex] ~= nil then
413 if self:getFillUnitSupportsFillType(fillUnitIndex, fillType) then
414 if fillType == FillType.SEEDS or spec.fillUnits[fillUnitIndex].fillType == FillType.SEEDS then
415 return true
416 end
417 end
418 end
419
420 return false
421end

getIsSeedChangeAllowed

Description
Definition
getIsSeedChangeAllowed()
Code
294function SowingMachine:getIsSeedChangeAllowed()
295 return self.spec_sowingMachine.allowsSeedChanging
296end

getSpecValueSeedFillTypes

Description
Definition
getSpecValueSeedFillTypes()
Code
841function SowingMachine.getSpecValueSeedFillTypes(storeItem, realItem)
842 local fruitTypes = nil
843
844 if storeItem.specs.seedFillTypes ~= nil then
845 local fruits = storeItem.specs.seedFillTypes
846 if fruits.categories ~= nil and fruits.names == nil then
847 fruitTypes = g_fruitTypeManager:getFillTypesByFruitTypeCategoryName(fruits.categories, nil)
848 elseif fruits.categories == nil and fruits.names ~= nil then
849 fruitTypes = g_fruitTypeManager:getFillTypesByFruitTypeNames(fruits.names, nil)
850 end
851 if fruitTypes ~= nil then
852 return fruitTypes
853 end
854 end
855
856 return nil
857end

getUseSowingMachineAIRquirements

Description
Definition
getUseSowingMachineAIRquirements()
Code
370function SowingMachine:getUseSowingMachineAIRquirements()
371 return self:getAIRequiresTurnOn() or self:getIsTurnedOn()
372end

getWearMultiplier

Description
Returns current wear multiplier
Definition
getWearMultiplier()
Return Values
floatdirtMultipliercurrent wear multiplier
Code
507function SowingMachine:getWearMultiplier(superFunc)
508 local spec = self.spec_sowingMachine
509 local multiplier = superFunc(self)
510
511 if self.movingDirection > 0 and spec.isWorking and (not spec.needsActivation or self:getIsTurnedOn()) then
512 multiplier = multiplier + self:getWorkWearMultiplier() * self:getLastSpeed() / self.speedLimit
513 end
514
515 return multiplier
516end

initSpecialization

Description
Definition
initSpecialization()
Code
19function SowingMachine.initSpecialization()
20 g_workAreaTypeManager:addWorkAreaType("sowingMachine", true)
21
22 g_storeManager:addSpecType("seedFillTypes", "shopListAttributeIconSeeds", SowingMachine.loadSpecValueSeedFillTypes, SowingMachine.getSpecValueSeedFillTypes)
23end

loadSpecValueSeedFillTypes

Description
Definition
loadSpecValueSeedFillTypes()
Code
832function SowingMachine.loadSpecValueSeedFillTypes(xmlFile, customEnvironment)
833 local categories = Utils.getNoNil(getXMLString(xmlFile, "vehicle.storeData.specs.seedFruitTypeCategories"), getXMLString(xmlFile, "vehicle.sowingMachine.seedFruitTypeCategories"))
834 local names = Utils.getNoNil(getXMLString(xmlFile, "vehicle.storeData.specs.seedFruitTypes"), getXMLString(xmlFile, "vehicle.sowingMachine.seedFruitTypes"))
835
836 return {categories=categories, names=names}
837end

loadWorkAreaFromXML

Description
Definition
loadWorkAreaFromXML()
Code
520function SowingMachine:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
521 local retValue = superFunc(self, workArea, xmlFile, key)
522
523 if workArea.type == WorkAreaType.DEFAULT then
524 workArea.type = WorkAreaType.SOWINGMACHINE
525 end
526
527 return retValue
528end

onChangedFillType

Description
Definition
onChangedFillType()
Code
744function SowingMachine:onChangedFillType(fillUnitIndex, fillTypeIndex, oldFillTypeIndex)
745 local spec = self.spec_sowingMachine
746 if fillUnitIndex == spec.fillUnitIndex then
747 g_animationManager:setFillType(spec.animationNodes, fillTypeIndex)
748 end
749end

onDeactivate

Description
Definition
onDeactivate()
Code
717function SowingMachine:onDeactivate()
718 local spec = self.spec_sowingMachine
719 if self.isClient then
720 g_soundManager:stopSamples(spec.samples)
721 spec.isWorkSamplePlaying = false
722 end
723end

onDelete

Description
Definition
onDelete()
Code
186function SowingMachine:onDelete()
187 local spec = self.spec_sowingMachine
188 if self.isClient then
189 for _,sample in pairs(spec.samples) do
190 g_soundManager:deleteSample(sample)
191 end
192 g_effectManager:deleteEffects(spec.effects)
193 g_animationManager:deleteAnimations(spec.animationNodes)
194 end
195end

onDraw

Description
Definition
onDraw()
Code
253function SowingMachine:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
254 local spec = self.spec_sowingMachine
255
256 if self.isClient then
257 if spec.showFruitCanNotBePlantedWarning then
258 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_theSelectedFruitTypeIsNotAvailableOnThisMap"))
259 elseif spec.showWrongFruitForMissionWarning then
260 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_theSelectedFruitTypeIsWrongForTheMission"))
261 end
262 end
263end

onEndWorkAreaProcessing

Description
Definition
onEndWorkAreaProcessing()
Code
663function SowingMachine:onEndWorkAreaProcessing(dt, hasProcessed)
664 local spec = self.spec_sowingMachine
665 if self.isServer then
666 local stats = g_farmManager:getFarmById(self:getLastTouchedFarmlandFarmId()).stats
667
668 if spec.workAreaParameters.lastChangedArea > 0 then
669 local fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(spec.workAreaParameters.seedsFruitType)
670 local lastHa = MathUtil.areaToHa(spec.workAreaParameters.lastChangedArea, g_currentMission:getFruitPixelsToSqm())
671 local usage = fruitDesc.seedUsagePerSqm * lastHa * 10000
672 local ha = MathUtil.areaToHa(spec.workAreaParameters.lastStatsArea, g_currentMission:getFruitPixelsToSqm()) -- 4096px are mapped to 2048m
673
674 local damage = self:getVehicleDamage()
675 if damage > 0 then
676 usage = usage * (1 + damage * SowingMachine.DAMAGED_USAGE_INCREASE)
677 end
678
679 stats:updateStats("seedUsage", usage)
680 stats:updateStats("sownHectares", ha)
681 stats:updateStats("workedHectares", ha)
682
683 if not self:getIsAIActive() or not g_currentMission.missionInfo.helperBuySeeds then
684 local vehicle = spec.workAreaParameters.seedsVehicle
685 local fillUnitIndex = spec.workAreaParameters.seedsVehicleFillUnitIndex
686 local fillType = vehicle:getFillUnitFillType(fillUnitIndex)
687 local unloadInfo = nil
688 vehicle:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, -usage, fillType, ToolType.UNDEFINED, unloadInfo)
689 else
690 local price = usage * g_currentMission.economyManager:getCostPerLiter(FillType.SEEDS, false) * 1.5 -- increase price if AI is active to reward the player's manual work
691 stats:updateStats("expenses", price)
692 g_currentMission:addMoney(-price, self:getOwnerFarmId(), MoneyType.PURCHASE_SEEDS)
693 end
694 end
695
696 stats:updateStats("sownTime", dt/(1000*60))
697 stats:updateStats("workedTime", dt/(1000*60))
698 end
699
700 if self.isClient then
701 if spec.isWorking then
702 if not spec.isWorkSamplePlaying then
703 g_soundManager:playSample(spec.samples.work)
704 spec.isWorkSamplePlaying = true
705 end
706 else
707 if spec.isWorkSamplePlaying then
708 g_soundManager:stopSample(spec.samples.work)
709 spec.isWorkSamplePlaying = false
710 end
711 end
712 end
713end

onLoad

Description
Definition
onLoad()
Code
84function SowingMachine:onLoad(savegame)
85 local spec = self.spec_sowingMachine
86
87 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.sowingMachine.animationNodes.animationNode", "sowingMachine") --FS17 to FS19
88 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnScrollers", "vehicle.sowingMachine.scrollerNodes.scrollerNode") --FS17 to FS19
89 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.useDirectPlanting", "vehicle.sowingMachine.useDirectPlanting#value") --FS17 to FS19
90 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.needsActivation#value", "vehicle.sowingMachine.needsActivation#value") --FS17 to FS19
91 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.sowingEffects", "vehicle.sowingMachine.effects") --FS17 to FS19
92 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.sowingEffectsWithFixedFillType", "vehicle.sowingMachine.fixedEffects") --FS17 to FS19
93 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.sowingMachine#supportsAiWithoutSowingMachine", "vehicle.turnOnVehicle.aiRequiresTurnOn") --FS17 to FS19
94
95 spec.allowFillFromAirWhileTurnedOn = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine.allowFillFromAirWhileTurnedOn#value"), true)
96 spec.directionNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.sowingMachine.directionNode#index"), self.i3dMappings), self.components[1].node)
97 spec.useDirectPlanting = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine.useDirectPlanting#value"), false)
98 spec.isWorking = false
99 spec.isProcessing = false
100
101 spec.seeds = {}
102 local fruitTypes = {}
103 local fruitTypeCategories = getXMLString(self.xmlFile, "vehicle.sowingMachine.seedFruitTypeCategories")
104 local fruitTypeNames = getXMLString(self.xmlFile, "vehicle.sowingMachine.seedFruitTypes")
105 if fruitTypeCategories ~= nil and fruitTypeNames == nil then
106 fruitTypes = g_fruitTypeManager:getFruitTypesByCategoryNames(fruitTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fruitTypeCategory '%s'.")
107 elseif fruitTypeCategories == nil and fruitTypeNames ~= nil then
108 fruitTypes = g_fruitTypeManager:getFruitTypesByNames(fruitTypeNames, "Warning: '"..self.configFileName.. "' has invalid fruitType '%s'.")
109 else
110 print("Warning: '"..self.configFileName.. "' a sowingMachine needs either the 'seedFruitTypeCategories' or 'seedFruitTypes' element.")
111 end
112
113 if fruitTypes ~= nil then
114 for _,fruitType in pairs(fruitTypes) do
115 table.insert(spec.seeds, fruitType)
116 end
117 end
118
119 spec.needsActivation = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine.needsActivation#value"), false)
120
121 if self.isClient then
122 spec.isWorkSamplePlaying = false
123 spec.samples = {}
124 spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.sowingMachine.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self)
125 spec.samples.airBlower = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.sowingMachine.sounds", "airBlower", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self)
126
127 spec.sampleFillEnabled = false
128 spec.sampleFillStopTime = -1
129 spec.lastFillLevel = -1
130
131 spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.sowingMachine.animationNodes", self.components, self, self.i3dMappings)
132 g_animationManager:setFillType(spec.animationNodes, FillType.UNKNOWN)
133
134 local changeSeedInputButtonStr = getXMLString(self.xmlFile, "vehicle.sowingMachine.changeSeedInputButton")
135 if changeSeedInputButtonStr ~= nil then
136 spec.changeSeedInputButton = InputAction[changeSeedInputButtonStr]
137 end
138 spec.changeSeedInputButton = Utils.getNoNil(spec.changeSeedInputButton, InputAction.IMPLEMENT_EXTRA3)
139 end
140
141 spec.currentSeed = 1
142 spec.allowsSeedChanging = true
143 spec.showFruitCanNotBePlantedWarning = false
144 spec.showWrongFruitForMissionWarning = false
145
146 spec.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#fillUnitIndex"), 1)
147 spec.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#unloadInfoIndex"), 1)
148 spec.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#loadInfoIndex"), 1)
149
150 spec.fillTypeSources = {}
151
152 if self.isClient then
153 spec.effects = g_effectManager:loadEffect(self.xmlFile, "vehicle.sowingMachine.effects", self.components, self, self.i3dMappings)
154 end
155
156 spec.workAreaParameters = {}
157 spec.workAreaParameters.seedsFruitType = nil
158 spec.workAreaParameters.angle = 0
159 spec.workAreaParameters.lastChangedArea = 0
160 spec.workAreaParameters.lastStatsArea = 0
161 spec.workAreaParameters.lastArea = 0
162
163
164 self:setSeedIndex(1, true)
165
166 if savegame ~= nil then
167 local selectedSeedFruitType = getXMLString(savegame.xmlFile, savegame.key..".sowingMachine#selectedSeedFruitType")
168 if selectedSeedFruitType ~= nil then
169 local fruitTypeDesc = g_fruitTypeManager:getFruitTypeByName(selectedSeedFruitType)
170 if fruitTypeDesc ~= nil then
171 self:setSeedFruitType(fruitTypeDesc.index, true)
172 end
173 end
174 end
175end

onPostLoad

Description
Definition
onPostLoad()
Code
179function SowingMachine:onPostLoad(savegame)
180 -- Update the ai parameters after all specs have been loaded to make sure we always have the same setup in case a spec changes these during loading (otherwise it might be changed when seed selection is changed)
181 SowingMachine.updateAiParameters(self)
182end

onReadStream

Description
Definition
onReadStream()
Code
212function SowingMachine:onReadStream(streamId, connection)
213 local seedIndex = streamReadUInt8(streamId)
214 self:setSeedIndex(seedIndex, true)
215end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
538function SowingMachine:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
539 if self.isClient then
540 local spec = self.spec_sowingMachine
541 self:clearActionEventsTable(spec.actionEvents)
542
543 if isActiveForInputIgnoreSelection and table.getn(spec.seeds) > 1 then
544 local _, actionEventId = self:addActionEvent(spec.actionEvents, spec.changeSeedInputButton, self, SowingMachine.actionEventToggleSeedType, false, true, false, true, nil)
545 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH)
546
547 SowingMachine.updateChooseSeedActionEvent(self)
548 end
549 end
550end

onStartWorkAreaProcessing

Description
Definition
onStartWorkAreaProcessing()
Code
596function SowingMachine:onStartWorkAreaProcessing(dt)
597 local spec = self.spec_sowingMachine
598
599 spec.isWorking = false
600 spec.isProcessing = false
601
602 local seedsFruitType = spec.seeds[spec.currentSeed]
603
604 local dx,_,dz = localDirectionToWorld(spec.directionNode, 0, 0, 1)
605 local angleRad = MathUtil.getYRotationFromDirection(dx, dz)
606 local desc = g_fruitTypeManager:getFruitTypeByIndex(seedsFruitType)
607 if desc ~= nil and desc.directionSnapAngle ~= 0 then
608 angleRad = math.floor(angleRad / desc.directionSnapAngle + 0.5) * desc.directionSnapAngle
609 end
610 local angle = FSDensityMapUtil.convertToDensityMapAngle(angleRad, g_currentMission.terrainDetailAngleMaxValue)
611
612 local seedsVehicle, seedsVehicleFillUnitIndex
613 if self:getFillUnitFillLevel(spec.fillUnitIndex) > 0 then
614 seedsVehicle = self
615 seedsVehicleFillUnitIndex = spec.fillUnitIndex
616 else
617 if spec.fillTypeSources[FillType.SEEDS] ~= nil then
618 for _, src in ipairs(spec.fillTypeSources[FillType.SEEDS]) do
619 local vehicle = src.vehicle
620 if vehicle:getFillUnitFillLevel(src.fillUnitIndex) > 0 and vehicle:getFillUnitFillType(src.fillUnitIndex) == FillType.SEEDS then
621 seedsVehicle = vehicle
622 seedsVehicleFillUnitIndex = src.fillUnitIndex
623 break
624 end
625 end
626 end
627 end
628
629 if seedsVehicle ~= nil and seedsVehicle ~= self then
630 local fillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(seedsFruitType)
631 seedsVehicle:setFillUnitFillTypeToDisplay(seedsVehicleFillUnitIndex, fillType)
632 end
633
634 -- check if selected fruit is available in current map
635 local canFruitBePlanted = false
636 if g_currentMission.fruits ~= nil then
637 if g_currentMission.fruits[seedsFruitType] ~= nil then
638 if g_currentMission.fruits[seedsFruitType].id ~= nil and g_currentMission.fruits[seedsFruitType].id ~= 0 then
639 canFruitBePlanted = true
640 end
641 end
642 end
643
644 if spec.showWrongFruitForMissionWarning then
645 spec.showWrongFruitForMissionWarning = false
646 end
647
648 spec.showFruitCanNotBePlantedWarning = not canFruitBePlanted
649
650 spec.workAreaParameters.isActive = not spec.needsActivation or self:getIsTurnedOn()
651 spec.workAreaParameters.canFruitBePlanted = canFruitBePlanted
652 spec.workAreaParameters.seedsFruitType = seedsFruitType
653 spec.workAreaParameters.angle = angle
654 spec.workAreaParameters.seedsVehicle = seedsVehicle
655 spec.workAreaParameters.seedsVehicleFillUnitIndex = seedsVehicleFillUnitIndex
656 spec.workAreaParameters.lastTotalArea = 0
657 spec.workAreaParameters.lastChangedArea = 0
658 spec.workAreaParameters.lastStatsArea = 0
659end

onStateChange

Description
Definition
onStateChange()
Code
727function SowingMachine:onStateChange(state, data)
728 if state == Vehicle.STATE_CHANGE_ATTACH or state == Vehicle.STATE_CHANGE_DETACH or Vehicle.STATE_CHANGE_FILLTYPE_CHANGE then
729 local spec = self.spec_sowingMachine
730 spec.fillTypeSources = {}
731 if FillType.SEEDS ~= nil then
732 spec.fillTypeSources[FillType.SEEDS] = {}
733 local root = self:getRootVehicle()
734 FillUnit.addFillTypeSources(spec.fillTypeSources, root, self, {FillType.SEEDS})
735
736 local fillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(spec.seeds[spec.currentSeed])
737 self:setFillTypeSourceDisplayFillType(fillType)
738 end
739 end
740end

onTurnedOff

Description
Definition
onTurnedOff()
Code
584function SowingMachine:onTurnedOff()
585 if self.isClient then
586 local spec = self.spec_sowingMachine
587 g_soundManager:stopSample(spec.samples.airBlower)
588 g_animationManager:stopAnimations(spec.animationNodes)
589 end
590
591 SowingMachine.updateAiParameters(self)
592end

onTurnedOn

Description
Definition
onTurnedOn()
Code
572function SowingMachine:onTurnedOn()
573 if self.isClient then
574 local spec = self.spec_sowingMachine
575 g_soundManager:playSample(spec.samples.airBlower)
576 g_animationManager:startAnimations(spec.animationNodes)
577 end
578
579 SowingMachine.updateAiParameters(self)
580end

onUpdate

Description
Definition
onUpdate()
Code
226function SowingMachine:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
227 local spec = self.spec_sowingMachine
228 if self.isClient then
229 if spec.isProcessing then
230 local fillType = self:getFillUnitForcedMaterialFillType(spec.fillUnitIndex)
231 if fillType ~= nil then
232 g_effectManager:setFillType(spec.effects, fillType)
233 g_effectManager:startEffects(spec.effects)
234 end
235 else
236 g_effectManager:stopEffects(spec.effects)
237 end
238 end
239end

onUpdateTick

Description
Definition
onUpdateTick()
Code
243function SowingMachine:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
244 local spec = self.spec_sowingMachine
245 local actionEvent = spec.actionEvents[spec.changeSeedInputButton]
246 if actionEvent ~= nil then
247 g_inputBinding:setActionEventActive(actionEvent.actionEventId, self:getIsSeedChangeAllowed())
248 end
249end

onWriteStream

Description
Definition
onWriteStream()
Code
219function SowingMachine:onWriteStream(streamId, connection)
220 local spec = self.spec_sowingMachine
221 streamWriteUInt8(streamId, spec.currentSeed)
222end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
27function SowingMachine.prerequisitesPresent(specializations)
28 return SpecializationUtil.hasSpecialization(FillUnit, specializations) and
29 SpecializationUtil.hasSpecialization(WorkArea, specializations) and
30 SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations)
31end

processSowingMachineArea

Description
Definition
processSowingMachineArea()
Code
300function SowingMachine:processSowingMachineArea(workArea, dt)
301 local spec = self.spec_sowingMachine
302 local changedArea, totalArea = 0, 0
303 spec.isWorking = self:getLastSpeed() > 0.5
304
305 if not spec.workAreaParameters.isActive then
306 return changedArea, totalArea
307 end
308
309 if not self:getIsAIActive() or not g_currentMission.missionInfo.helperBuySeeds then
310 if spec.workAreaParameters.seedsVehicle == nil then
311 if self:getIsAIActive() then
312 local rootVehicle = self:getRootVehicle()
313 rootVehicle:stopAIVehicle(AIVehicle.STOP_REASON_OUT_OF_FILL)
314 end
315
316 return changedArea, totalArea
317 end
318 end
319
320 if not spec.workAreaParameters.canFruitBePlanted then
321 return changedArea, totalArea
322 end
323
324 local sx,_,sz = getWorldTranslation(workArea.start)
325 local wx,_,wz = getWorldTranslation(workArea.width)
326 local hx,_,hz = getWorldTranslation(workArea.height)
327
328 spec.isProcessing = spec.isWorking
329
330 if not spec.useDirectPlanting then
331 local area, _ = FSDensityMapUtil.updateSowingArea(spec.workAreaParameters.seedsFruitType, sx,sz, wx,wz, hx,hz, spec.workAreaParameters.angle, nil)
332 changedArea = changedArea + area
333 else
334 local area, _ = FSDensityMapUtil.updateDirectSowingArea(spec.workAreaParameters.seedsFruitType, sx,sz, wx,wz, hx,hz, spec.workAreaParameters.angle, nil)
335 changedArea = changedArea + area
336 end
337
338 spec.workAreaParameters.lastChangedArea = spec.workAreaParameters.lastChangedArea + changedArea
339 spec.workAreaParameters.lastStatsArea = spec.workAreaParameters.lastStatsArea + changedArea
340 spec.workAreaParameters.lastTotalArea = spec.workAreaParameters.lastTotalArea + totalArea
341
342 -- remove tireTracks
343 FSDensityMapUtil.eraseTireTrack(sx,sz, wx,wz, hx,hz)
344
345 self:updateMissionSowingWarning(sx, sz)
346
347 return changedArea, totalArea
348end

registerEventListeners

Description
Definition
registerEventListeners()
Code
63function SowingMachine.registerEventListeners(vehicleType)
64 SpecializationUtil.registerEventListener(vehicleType, "onLoad", SowingMachine)
65 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", SowingMachine)
66 SpecializationUtil.registerEventListener(vehicleType, "onDelete", SowingMachine)
67 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", SowingMachine)
68 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", SowingMachine)
69 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", SowingMachine)
70 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", SowingMachine)
71 SpecializationUtil.registerEventListener(vehicleType, "onDraw", SowingMachine)
72 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", SowingMachine)
73 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", SowingMachine)
74 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", SowingMachine)
75 SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", SowingMachine)
76 SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", SowingMachine)
77 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", SowingMachine)
78 SpecializationUtil.registerEventListener(vehicleType, "onStateChange", SowingMachine)
79 SpecializationUtil.registerEventListener(vehicleType, "onChangedFillType", SowingMachine)
80end

registerFunctions

Description
Definition
registerFunctions()
Code
35function SowingMachine.registerFunctions(vehicleType)
36 SpecializationUtil.registerFunction(vehicleType, "setSeedFruitType", SowingMachine.setSeedFruitType)
37 SpecializationUtil.registerFunction(vehicleType, "setSeedIndex", SowingMachine.setSeedIndex)
38 SpecializationUtil.registerFunction(vehicleType, "getIsSeedChangeAllowed", SowingMachine.getIsSeedChangeAllowed)
39 SpecializationUtil.registerFunction(vehicleType, "processSowingMachineArea", SowingMachine.processSowingMachineArea)
40 SpecializationUtil.registerFunction(vehicleType, "getUseSowingMachineAIRquirements", SowingMachine.getUseSowingMachineAIRquirements)
41 SpecializationUtil.registerFunction(vehicleType, "setFillTypeSourceDisplayFillType", SowingMachine.setFillTypeSourceDisplayFillType)
42 SpecializationUtil.registerFunction(vehicleType, "updateMissionSowingWarning", SowingMachine.updateMissionSowingWarning)
43end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
47function SowingMachine.registerOverwrittenFunctions(vehicleType)
48 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDrawFirstFillText", SowingMachine.getDrawFirstFillText)
49 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillUnitAllowsFillType", SowingMachine.getFillUnitAllowsFillType)
50 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanToggleTurnedOn", SowingMachine.getCanToggleTurnedOn)
51 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowFillFromAir", SowingMachine.getAllowFillFromAir)
52 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirectionSnapAngle", SowingMachine.getDirectionSnapAngle)
53 SpecializationUtil.registerOverwrittenFunction(vehicleType, "addFillUnitFillLevel", SowingMachine.addFillUnitFillLevel)
54 SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", SowingMachine.doCheckSpeedLimit)
55 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", SowingMachine.getDirtMultiplier)
56 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", SowingMachine.getWearMultiplier)
57 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", SowingMachine.loadWorkAreaFromXML)
58 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", SowingMachine.getCanBeSelected)
59end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
199function SowingMachine:saveToXMLFile(xmlFile, key, usedModNames)
200 local spec = self.spec_sowingMachine
201 local selectedSeedFruitTypeName = "unknown"
202 local selectedSeedFruitType = spec.seeds[spec.currentSeed]
203 if selectedSeedFruitType ~= nil and selectedSeedFruitType ~= FruitType.UNKNOWN then
204 local fruitType = g_fruitTypeManager:getFruitTypeByIndex(selectedSeedFruitType)
205 selectedSeedFruitTypeName = fruitType.name
206 end
207 setXMLString(xmlFile, key.."#selectedSeedFruitType", selectedSeedFruitTypeName)
208end

setFillTypeSourceDisplayFillType

Description
Definition
setFillTypeSourceDisplayFillType()
Code
376function SowingMachine:setFillTypeSourceDisplayFillType(fillType)
377 local spec = self.spec_sowingMachine
378 if spec.fillTypeSources[FillType.SEEDS] ~= nil then
379 for _, src in ipairs(spec.fillTypeSources[FillType.SEEDS]) do
380 local vehicle = src.vehicle
381 if vehicle:getFillUnitFillLevel(src.fillUnitIndex) > 0 and vehicle:getFillUnitFillType(src.fillUnitIndex) == FillType.SEEDS then
382 vehicle:setFillUnitFillTypeToDisplay(src.fillUnitIndex, fillType)
383 break
384 end
385 end
386 end
387end

setSeedFruitType

Description
Definition
setSeedFruitType()
Code
282function SowingMachine:setSeedFruitType(fruitType, noEventSend)
283 local spec = self.spec_sowingMachine
284 for i,v in ipairs(spec.seeds) do
285 if v == fruitType then
286 self:setSeedIndex(i, noEventSend)
287 break
288 end
289 end
290end

setSeedIndex

Description
Definition
setSeedIndex()
Code
267function SowingMachine:setSeedIndex(seedIndex, noEventSend)
268 local spec = self.spec_sowingMachine
269 SetSeedIndexEvent.sendEvent(self, seedIndex, noEventSend)
270 spec.currentSeed = math.min(math.max(seedIndex, 1), table.getn(spec.seeds))
271
272 local fillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(spec.seeds[spec.currentSeed])
273 self:setFillUnitFillTypeToDisplay(spec.fillUnitIndex, fillType, true)
274 self:setFillTypeSourceDisplayFillType(fillType)
275
276 SowingMachine.updateAiParameters(self)
277 SowingMachine.updateChooseSeedActionEvent(self)
278end

updateAiParameters

Description
Definition
updateAiParameters()
Code
753function SowingMachine.updateAiParameters(self)
754 local spec = self.spec_sowingMachine
755
756 if self.addAITerrainDetailRequiredRange ~= nil then
757 self:clearAITerrainDetailRequiredRange()
758 self:clearAITerrainDetailProhibitedRange()
759
760 -- if a cultivator is attached we estimate that it will cultivate infront of our sowing machine and we use also sowingValue, sowingWidthValue and grass as requirements
761 local isCultivatorAttached = false
762 local rootVehicle = self:getRootVehicle()
763 if rootVehicle.getAttachedAIImplements ~= nil then
764 for _, implement in ipairs(rootVehicle:getAttachedAIImplements()) do
765 if SpecializationUtil.hasSpecialization(Cultivator, implement.object.specializations) then
766 isCultivatorAttached = true
767 end
768 end
769 end
770
771 if SpecializationUtil.hasSpecialization(Cultivator, self.specializations) or isCultivatorAttached then
772 self:addAITerrainDetailRequiredRange(g_currentMission.plowValue, g_currentMission.plowValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
773 self:addAITerrainDetailRequiredRange(g_currentMission.sowingValue, g_currentMission.sowingValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
774 self:addAITerrainDetailRequiredRange(g_currentMission.sowingWidthValue, g_currentMission.sowingWidthValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
775 self:addAITerrainDetailRequiredRange(g_currentMission.grassValue, g_currentMission.grassValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
776
777 if self:getUseSowingMachineAIRquirements() then
778 self:addAITerrainDetailRequiredRange(g_currentMission.cultivatorValue, g_currentMission.cultivatorValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
779 end
780 elseif SpecializationUtil.hasSpecialization(Weeder, self.specializations) then
781 self:addAITerrainDetailRequiredRange(g_currentMission.sowingValue, g_currentMission.sowingValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
782 self:addAITerrainDetailRequiredRange(g_currentMission.sowingWidthValue, g_currentMission.sowingWidthValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
783
784 if self:getUseSowingMachineAIRquirements() then
785 self:addAITerrainDetailRequiredRange(g_currentMission.cultivatorValue, g_currentMission.cultivatorValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
786 self:addAITerrainDetailRequiredRange(g_currentMission.plowValue, g_currentMission.plowValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
787 end
788 else
789 self:addAITerrainDetailRequiredRange(g_currentMission.cultivatorValue, g_currentMission.cultivatorValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
790 self:addAITerrainDetailRequiredRange(g_currentMission.plowValue, g_currentMission.plowValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
791
792 if spec.useDirectPlanting then
793 self:addAITerrainDetailRequiredRange(g_currentMission.sowingValue, g_currentMission.sowingValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
794 self:addAITerrainDetailRequiredRange(g_currentMission.sowingWidthValue, g_currentMission.sowingWidthValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
795 self:addAITerrainDetailRequiredRange(g_currentMission.grassValue, g_currentMission.grassValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels)
796 end
797 end
798
799 if self:getUseSowingMachineAIRquirements() then
800 local fruitTypeIndex = spec.seeds[spec.currentSeed]
801 local fruitTypeDesc = g_fruitTypeManager:getFruitTypeByIndex(fruitTypeIndex)
802 if fruitTypeDesc ~= nil then
803 self:setAIFruitProhibitions(fruitTypeIndex, 0, fruitTypeDesc.maxHarvestingGrowthState)
804 end
805 else
806 self:clearAIFruitProhibitions()
807 end
808 end
809end

updateChooseSeedActionEvent

Description
Definition
updateChooseSeedActionEvent()
Code
554function SowingMachine.updateChooseSeedActionEvent(self)
555 local spec = self.spec_sowingMachine
556 local actionEvent = spec.actionEvents[spec.changeSeedInputButton]
557 if actionEvent ~= nil then
558 local additionalText = ""
559 local fillType = g_fillTypeManager:getFillTypeByIndex(g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(spec.seeds[spec.currentSeed]))
560 if fillType ~= nil then
561 if fillType ~= FillType.UNKNOWN then
562 additionalText = string.format(" (%s)", fillType.title)
563 end
564 end
565
566 g_inputBinding:setActionEventText(actionEvent.actionEventId, string.format("%s%s", g_i18n:getText("action_chooseSeed"), additionalText))
567 end
568end

updateMissionSowingWarning

Description
Definition
updateMissionSowingWarning()
Code
352function SowingMachine:updateMissionSowingWarning(x, z)
353 local spec = self.spec_sowingMachine
354
355 spec.showWrongFruitForMissionWarning = false
356
357 -- Unowned field. This function executes and thus it is allowed which means it is a mission field
358 if self:getLastTouchedFarmlandFarmId() == 0 then
359 local mission = g_missionManager:getMissionAtWorldPosition(x, z)
360 if mission ~= nil and mission.type.name == "sow" then
361 if mission.fruitType ~= spec.workAreaParameters.seedsFruitType then
362 spec.showWrongFruitForMissionWarning = true
363 end
364 end
365 end
366end