Script v1_7_1_0
- AI
- Animals
- Collections
- Contracts
- Debug
- Economy
- Elements
- EnvironmentalScore
- Errors
- Events
- GUI
- Handtools
- Hud
- I3d
- Input
- Jobs
- Maps
- Materials
- Misc
- Objects
- Parameters
- Placeables
- Placement
- Player
- Shop
- Sounds
- Specialization
- Specializations
- AIConveyorBelt
- AIDrivable
- AIFieldWorker
- AIImplement
- AIJobVehicle
- AIVehicle
- AIVehicleObstacle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- AutoLoader
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BigBag
- BunkerSiloCompacter
- BunkerSiloInteractor
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- CropSensor
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- ExtendedAIVehicle
- ExtendedCombine
- ExtendedMotorized
- ExtendedMower
- ExtendedSowingMachine
- ExtendedSprayer
- ExtendedWearable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- HeadlandAnimation
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- InlineWrapper
- JigglingParts
- Leveler
- LicensePlates
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- ManureSensor
- MixerWagon
- Motorized
- Mountable
- Mower
- Mulcher
- MultipleItemPurchase
- Pallet
- Pickup
- Pipe
- PlaceableAI
- PlaceableAnimatedObjects
- PlaceableBeehive
- PlaceableBeehivePalletSpa...
- PlaceableBunkerSilo
- PlaceableBuyingStation
- PlaceableCartridgePlayer
- PlaceableChargingStation
- PlaceableClearAreas
- PlaceableColorable
- PlaceableDeletedNodes
- PlaceableDoghouse
- PlaceableDynamicallyLoade...
- PlaceableFarmhouse
- PlaceableFence
- PlaceableFoliageAreas
- PlaceableGreenhouse
- PlaceableHighPressureWash...
- PlaceableHotspots
- PlaceableHusbandry
- PlaceableHusbandryAnimals
- PlaceableHusbandryFeeding...
- PlaceableHusbandryFence
- PlaceableHusbandryFood
- PlaceableHusbandryLiquidM...
- PlaceableHusbandryMilk
- PlaceableHusbandryPallets
- PlaceableHusbandryStraw
- PlaceableHusbandryWater
- PlaceableIncomePerHour
- PlaceableIndoorAreas
- PlaceableInfoTrigger
- PlaceableLeveling
- PlaceableLights
- PlaceableManureHeap
- PlaceablePlacement
- PlaceableProductionPoint
- PlaceableSellingStation
- PlaceableSilo
- PlaceableSiloExtension
- PlaceableSolarPanels
- PlaceableTipOcclusionArea...
- PlaceableTrainSystem
- PlaceableTriggerMarkers
- PlaceableVine
- PlaceableWardrobe
- PlaceableWeatherStation
- PlaceableWeighingStation
- PlaceableWindTurbine
- PlaceableWorkshop
- Plow
- PlowPacker
- PowerConsumer
- PowerTakeOffs
- PrecisionFarmingStatistic
- PushHandTool
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- RTKStation
- SaltSpreader
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SoilSampler
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StonePicker
- StrawBlower
- StumpCutter
- SupportVehicle
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TestAreas
- TipOccluder
- Trailer
- TreePlanter
- TreeSaplingPallet
- TreeSaw
- TurnOnVehicle
- VariableWorkWidth
- VehicleSettings
- VineCutter
- VineDetector
- VinePrepruner
- Washable
- WaterTrailer
- Wearable
- Weeder
- WeedSpotSpray
- Wheels
- WindBending
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- StateMachine
- Statistics
- Tasks
- Triggers
- Utils
- Vehicles
Engine v1_7_1_0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- general
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- NoteNode
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- VoiceChat
- XML
Foundation Reference
SowingMachine
DescriptionSpecialization for sowing machines provoding seed selection functionalityFunctions
- actionEventToggleSeedType
- actionEventToggleSeedTypeBack
- addFillUnitFillLevel
- changeSeedIndex
- doCheckSpeedLimit
- getAllowFillFromAir
- getAreControlledActionsAllowed
- getCanAIImplementContinueWork
- getCanBeSelected
- getCanPlantOutsideSeason
- getCanToggleTurnedOn
- getCurrentSeedTypeIcon
- getDefaultSpeedLimit
- getDirectionSnapAngle
- getDirtMultiplier
- getDrawFirstFillText
- getFillUnitAllowsFillType
- getIsSeedChangeAllowed
- getSowingMachineFillUnitIndex
- getSpecValueSeedFillTypes
- getUseSowingMachineAIRequirements
- getWearMultiplier
- initSpecialization
- loadSpecValueSeedFillTypes
- loadWorkAreaFromXML
- onChangedFillType
- onDeactivate
- onDelete
- onEndWorkAreaProcessing
- onLoad
- onPostLoad
- onReadStream
- onRegisterActionEvents
- onStartWorkAreaProcessing
- onStateChange
- onTurnedOff
- onTurnedOn
- onUpdate
- onUpdateTick
- onWriteStream
- prerequisitesPresent
- processSowingMachineArea
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- saveToXMLFile
- setFillTypeSourceDisplayFillType
- setSeedFruitType
- setSeedIndex
- updateAiParameters
- updateChooseSeedActionEvent
- updateMissionSowingWarning
actionEventToggleSeedType
DescriptionDefinitionactionEventToggleSeedType()Code
1008 | function SowingMachine.actionEventToggleSeedType(self, actionName, inputValue, callbackState, isAnalog) |
1009 | if self:getIsSeedChangeAllowed() then |
1010 | self:changeSeedIndex(1) |
1011 | end |
1012 | end |
actionEventToggleSeedTypeBack
DescriptionDefinitionactionEventToggleSeedTypeBack()Code
1016 | function SowingMachine.actionEventToggleSeedTypeBack(self, actionName, inputValue, callbackState, isAnalog) |
1017 | if self:getIsSeedChangeAllowed() then |
1018 | self:changeSeedIndex(-1) |
1019 | end |
1020 | end |
addFillUnitFillLevel
DescriptionDefinitionaddFillUnitFillLevel()Code
600 | function SowingMachine:addFillUnitFillLevel(superFunc, farmId, fillUnitIndex, fillLevelDelta, fillType, toolType, fillInfo) |
601 | local spec = self.spec_sowingMachine |
602 | |
603 | if fillUnitIndex == spec.fillUnitIndex then |
604 | -- force material of fillVolume to be seeds, if fillType is accepted |
605 | if self:getFillUnitSupportsFillType(fillUnitIndex, fillType) then |
606 | fillType = FillType.SEEDS |
607 | self:setFillUnitForcedMaterialFillType(fillUnitIndex, fillType) |
608 | end |
609 | |
610 | -- switch from seeds to 'fill type', if possible |
611 | local fruitType = spec.seeds[spec.currentSeed] |
612 | if fruitType ~= nil then |
613 | local seedsFillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(fruitType) |
614 | if seedsFillType ~= nil then |
615 | if self:getFillUnitSupportsFillType(fillUnitIndex, seedsFillType) then |
616 | self:setFillUnitForcedMaterialFillType(fillUnitIndex, seedsFillType) |
617 | end |
618 | end |
619 | end |
620 | end |
621 | |
622 | return superFunc(self, farmId, fillUnitIndex, fillLevelDelta, fillType, toolType, fillInfo) |
623 | end |
changeSeedIndex
DescriptionDefinitionchangeSeedIndex()Code
346 | function SowingMachine:changeSeedIndex(increment) |
347 | local spec = self.spec_sowingMachine |
348 | local seed = spec.currentSeed + increment |
349 | if seed > #spec.seeds then |
350 | seed = 1 |
351 | elseif seed < 1 then |
352 | seed = #spec.seeds |
353 | end |
354 | |
355 | self:setSeedIndex(seed) |
356 | end |
doCheckSpeedLimit
DescriptionDefinitiondoCheckSpeedLimit()Code
627 | function SowingMachine:doCheckSpeedLimit(superFunc) |
628 | local spec = self.spec_sowingMachine |
629 | return superFunc(self) or (self:getIsImplementChainLowered() and (not spec.needsActivation or self:getIsTurnedOn())) |
630 | end |
getAllowFillFromAir
DescriptionDefinitiongetAllowFillFromAir()Code
577 | function SowingMachine:getAllowFillFromAir(superFunc) |
578 | local spec = self.spec_sowingMachine |
579 | if self:getIsTurnedOn() and not spec.allowFillFromAirWhileTurnedOn then |
580 | return false |
581 | end |
582 | return superFunc(self) |
583 | end |
getAreControlledActionsAllowed
DescriptionReturns if controlled actions are allowedDefinition
getAreControlledActionsAllowed()Return Values
boolean | allow | allow controlled actions |
string | warning | not allowed warning |
527 | function SowingMachine:getAreControlledActionsAllowed(superFunc) |
528 | local spec = self.spec_sowingMachine |
529 | |
530 | if spec.requiresFilling then |
531 | if self:getFillUnitFillLevel(spec.fillUnitIndex) <= 0 and self:getFillUnitCapacity(spec.fillUnitIndex) ~= 0 then |
532 | return false, g_i18n:getText("info_firstFillTheTool") |
533 | end |
534 | end |
535 | |
536 | return superFunc(self) |
537 | end |
getCanAIImplementContinueWork
DescriptionDefinitiongetCanAIImplementContinueWork()Code
684 | function SowingMachine:getCanAIImplementContinueWork(superFunc) |
685 | local canContinue, stopAI, stopReason = superFunc(self) |
686 | if not canContinue then |
687 | return false, stopAI, stopReason |
688 | end |
689 | |
690 | if not self:getCanPlantOutsideSeason() then |
691 | local spec = self.spec_sowingMachine |
692 | if not g_currentMission.growthSystem:canFruitBePlanted(spec.workAreaParameters.seedsFruitType) then |
693 | return false, true, AIMessageErrorWrongSeason.new() |
694 | end |
695 | end |
696 | |
697 | return canContinue, stopAI, stopReason |
698 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
678 | function SowingMachine:getCanBeSelected(superFunc) |
679 | return true |
680 | end |
getCanPlantOutsideSeason
DescriptionDefinitiongetCanPlantOutsideSeason()Code
571 | function SowingMachine:getCanPlantOutsideSeason() |
572 | return false |
573 | end |
getCanToggleTurnedOn
DescriptionDefinitiongetCanToggleTurnedOn()Code
560 | function SowingMachine:getCanToggleTurnedOn(superFunc) |
561 | local spec = self.spec_sowingMachine |
562 | if not spec.needsActivation then |
563 | return false |
564 | end |
565 | |
566 | return superFunc(self) |
567 | end |
getCurrentSeedTypeIcon
DescriptionDefinitiongetCurrentSeedTypeIcon()Code
384 | function SowingMachine:getCurrentSeedTypeIcon() |
385 | local spec = self.spec_sowingMachine |
386 | local fillType = g_fruitTypeManager:getFillTypeByFruitTypeIndex(spec.seeds[spec.currentSeed]) |
387 | if fillType ~= nil then |
388 | return fillType.hudOverlayFilename |
389 | end |
390 | |
391 | return nil |
392 | end |
getDefaultSpeedLimit
DescriptionDefinitiongetDefaultSpeedLimit()Code
1002 | function SowingMachine.getDefaultSpeedLimit() |
1003 | return 15 |
1004 | end |
getDirectionSnapAngle
DescriptionDefinitiongetDirectionSnapAngle()Code
587 | function SowingMachine:getDirectionSnapAngle(superFunc) |
588 | local spec = self.spec_sowingMachine |
589 | local seedsFruitType = spec.seeds[spec.currentSeed] |
590 | local desc = g_fruitTypeManager:getFruitTypeByIndex(seedsFruitType) |
591 | local snapAngle = 0 |
592 | if desc ~= nil then |
593 | snapAngle = desc.directionSnapAngle |
594 | end |
595 | return math.max(snapAngle, superFunc(self)) |
596 | end |
getDirtMultiplier
DescriptionDefinitiongetDirtMultiplier()Code
634 | function SowingMachine:getDirtMultiplier(superFunc) |
635 | local spec = self.spec_sowingMachine |
636 | local multiplier = superFunc(self) |
637 | |
638 | if self.movingDirection > 0 and spec.isWorking and (not spec.needsActivation or self:getIsTurnedOn()) then |
639 | multiplier = multiplier + self:getWorkDirtMultiplier() * self:getLastSpeed() / self.speedLimit |
640 | end |
641 | |
642 | return multiplier |
643 | end |
getDrawFirstFillText
DescriptionDefinitiongetDrawFirstFillText()Code
509 | function SowingMachine:getDrawFirstFillText(superFunc) |
510 | local spec = self.spec_sowingMachine |
511 | if self.isClient then |
512 | if self:getIsActiveForInput() and self:getIsSelected() then |
513 | if self:getFillUnitFillLevel(spec.fillUnitIndex) <= 0 and self:getFillUnitCapacity(spec.fillUnitIndex) ~= 0 then |
514 | return true |
515 | end |
516 | end |
517 | end |
518 | |
519 | return superFunc(self) |
520 | end |
getFillUnitAllowsFillType
DescriptionDefinitiongetFillUnitAllowsFillType()Code
541 | function SowingMachine:getFillUnitAllowsFillType(superFunc, fillUnitIndex, fillType) |
542 | if superFunc(self, fillUnitIndex, fillType) then |
543 | return true |
544 | end |
545 | |
546 | local spec = self.spec_fillUnit |
547 | if spec.fillUnits[fillUnitIndex] ~= nil then |
548 | if self:getFillUnitSupportsFillType(fillUnitIndex, fillType) then |
549 | if fillType == FillType.SEEDS or spec.fillUnits[fillUnitIndex].fillType == FillType.SEEDS then |
550 | return true |
551 | end |
552 | end |
553 | end |
554 | |
555 | return false |
556 | end |
getIsSeedChangeAllowed
DescriptionDefinitiongetIsSeedChangeAllowed()Code
372 | function SowingMachine:getIsSeedChangeAllowed() |
373 | return self.spec_sowingMachine.allowsSeedChanging |
374 | end |
getSowingMachineFillUnitIndex
DescriptionDefinitiongetSowingMachineFillUnitIndex()Code
378 | function SowingMachine:getSowingMachineFillUnitIndex() |
379 | return self.spec_sowingMachine.fillUnitIndex |
380 | end |
getSpecValueSeedFillTypes
DescriptionDefinitiongetSpecValueSeedFillTypes()Code
1033 | function SowingMachine.getSpecValueSeedFillTypes(storeItem, realItem) |
1034 | local fruitTypes = nil |
1035 | |
1036 | if storeItem.specs.seedFillTypes ~= nil then |
1037 | local fruits = storeItem.specs.seedFillTypes |
1038 | if fruits.categories ~= nil and fruits.names == nil then |
1039 | fruitTypes = g_fruitTypeManager:getFillTypesByFruitTypeCategoryName(fruits.categories, nil) |
1040 | elseif fruits.categories == nil and fruits.names ~= nil then |
1041 | fruitTypes = g_fruitTypeManager:getFillTypesByFruitTypeNames(fruits.names, nil) |
1042 | end |
1043 | if fruitTypes ~= nil then |
1044 | return fruitTypes |
1045 | end |
1046 | end |
1047 | |
1048 | return nil |
1049 | end |
getUseSowingMachineAIRequirements
DescriptionDefinitiongetUseSowingMachineAIRequirements()Code
472 | function SowingMachine:getUseSowingMachineAIRequirements() |
473 | return self:getAIRequiresTurnOn() or self:getIsTurnedOn() |
474 | end |
getWearMultiplier
DescriptionReturns current wear multiplierDefinition
getWearMultiplier()Return Values
float | dirtMultiplier | current wear multiplier |
648 | function SowingMachine:getWearMultiplier(superFunc) |
649 | local spec = self.spec_sowingMachine |
650 | local multiplier = superFunc(self) |
651 | |
652 | if self.movingDirection > 0 and spec.isWorking and (not spec.needsActivation or self:getIsTurnedOn()) then |
653 | local stoneMultiplier = 1 |
654 | if spec.stoneLastState ~= 0 and spec.stoneWearMultiplierData ~= nil then |
655 | stoneMultiplier = spec.stoneWearMultiplierData[spec.stoneLastState] or 1 |
656 | end |
657 | |
658 | multiplier = multiplier + self:getWorkWearMultiplier() * self:getLastSpeed() / self.speedLimit * stoneMultiplier |
659 | end |
660 | |
661 | return multiplier |
662 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
35 | function SowingMachine.initSpecialization() |
36 | g_workAreaTypeManager:addWorkAreaType("sowingMachine", true) |
37 | |
38 | g_storeManager:addSpecType("seedFillTypes", "shopListAttributeIconSeeds", SowingMachine.loadSpecValueSeedFillTypes, SowingMachine.getSpecValueSeedFillTypes, "vehicle") |
39 | |
40 | local schema = Vehicle.xmlSchema |
41 | schema:setXMLSpecializationType("SowingMachine") |
42 | |
43 | schema:register(XMLValueType.BOOL, "vehicle.sowingMachine.allowFillFromAirWhileTurnedOn#value", "Allow fill from air while turned on") |
44 | schema:register(XMLValueType.NODE_INDEX, "vehicle.sowingMachine.directionNode#node", "Direction node") |
45 | schema:register(XMLValueType.BOOL, "vehicle.sowingMachine.useDirectPlanting#value", "Use direct planting", false) |
46 | schema:register(XMLValueType.STRING, "vehicle.sowingMachine.seedFruitTypeCategories", "Seed fruit type categories") |
47 | schema:register(XMLValueType.STRING, "vehicle.sowingMachine.seedFruitTypes", "Seed fruit types") |
48 | schema:register(XMLValueType.BOOL, "vehicle.sowingMachine.needsActivation#value", "Needs activation", false) |
49 | schema:register(XMLValueType.BOOL, "vehicle.sowingMachine.requiresFilling#value", "Requires filling", true) |
50 | schema:register(XMLValueType.STRING, "vehicle.sowingMachine.fieldGroundType#value", "Defines the field ground type", "SOWN") |
51 | |
52 | SoundManager.registerSampleXMLPaths(schema, "vehicle.sowingMachine.sounds", "work") |
53 | SoundManager.registerSampleXMLPaths(schema, "vehicle.sowingMachine.sounds", "airBlower") |
54 | |
55 | AnimationManager.registerAnimationNodesXMLPaths(schema, "vehicle.sowingMachine.animationNodes") |
56 | |
57 | schema:register(XMLValueType.STRING, "vehicle.sowingMachine.changeSeedInputButton", "Input action name", "IMPLEMENT_EXTRA3") |
58 | schema:register(XMLValueType.INT, "vehicle.sowingMachine#fillUnitIndex", "Fill unit index", 1) |
59 | schema:register(XMLValueType.INT, "vehicle.sowingMachine#unloadInfoIndex", "Unload info index", 1) |
60 | |
61 | EffectManager.registerEffectXMLPaths(schema, "vehicle.sowingMachine.effects") |
62 | |
63 | schema:register(XMLValueType.STRING, "vehicle.storeData.specs.seedFruitTypeCategories", "Seed fruit type categories") |
64 | schema:register(XMLValueType.STRING, "vehicle.storeData.specs.seedFruitTypes", "Seed fruit types") |
65 | |
66 | schema:setXMLSpecializationType() |
67 | |
68 | local schemaSavegame = Vehicle.xmlSchemaSavegame |
69 | schemaSavegame:register(XMLValueType.STRING, "vehicles.vehicle(?).sowingMachine#selectedSeedFruitType", "Selected fruit type name") |
70 | end |
loadSpecValueSeedFillTypes
DescriptionDefinitionloadSpecValueSeedFillTypes()Code
1024 | function SowingMachine.loadSpecValueSeedFillTypes(xmlFile, customEnvironment, baseDir) |
1025 | local categories = Utils.getNoNil(xmlFile:getValue("vehicle.storeData.specs.seedFruitTypeCategories"), xmlFile:getValue("vehicle.sowingMachine.seedFruitTypeCategories")) |
1026 | local names = Utils.getNoNil(xmlFile:getValue("vehicle.storeData.specs.seedFruitTypes"), xmlFile:getValue("vehicle.sowingMachine.seedFruitTypes")) |
1027 | |
1028 | return {categories=categories, names=names} |
1029 | end |
loadWorkAreaFromXML
DescriptionDefinitionloadWorkAreaFromXML()Code
666 | function SowingMachine:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
667 | local retValue = superFunc(self, workArea, xmlFile, key) |
668 | |
669 | if workArea.type == WorkAreaType.DEFAULT then |
670 | workArea.type = WorkAreaType.SOWINGMACHINE |
671 | end |
672 | |
673 | return retValue |
674 | end |
onChangedFillType
DescriptionDefinitiononChangedFillType()Code
925 | function SowingMachine:onChangedFillType(fillUnitIndex, fillTypeIndex, oldFillTypeIndex) |
926 | local spec = self.spec_sowingMachine |
927 | if fillUnitIndex == spec.fillUnitIndex then |
928 | g_animationManager:setFillType(spec.animationNodes, fillTypeIndex) |
929 | end |
930 | end |
onDeactivate
DescriptionDefinitiononDeactivate()Code
898 | function SowingMachine:onDeactivate() |
899 | local spec = self.spec_sowingMachine |
900 | if self.isClient then |
901 | g_soundManager:stopSamples(spec.samples) |
902 | spec.isWorkSamplePlaying = false |
903 | end |
904 | end |
onDelete
DescriptionDefinitiononDelete()Code
260 | function SowingMachine:onDelete() |
261 | local spec = self.spec_sowingMachine |
262 | g_soundManager:deleteSamples(spec.samples) |
263 | g_effectManager:deleteEffects(spec.effects) |
264 | g_animationManager:deleteAnimations(spec.animationNodes) |
265 | end |
onEndWorkAreaProcessing
DescriptionDefinitiononEndWorkAreaProcessing()Code
837 | function SowingMachine:onEndWorkAreaProcessing(dt, hasProcessed) |
838 | local spec = self.spec_sowingMachine |
839 | if self.isServer then |
840 | local stats = g_farmManager:getFarmById(self:getLastTouchedFarmlandFarmId()).stats |
841 | |
842 | if spec.workAreaParameters.lastChangedArea > 0 then |
843 | local fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(spec.workAreaParameters.seedsFruitType) |
844 | local lastHa = MathUtil.areaToHa(spec.workAreaParameters.lastChangedArea, g_currentMission:getFruitPixelsToSqm()) |
845 | local usage = fruitDesc.seedUsagePerSqm * lastHa * 10000 |
846 | local ha = MathUtil.areaToHa(spec.workAreaParameters.lastStatsArea, g_currentMission:getFruitPixelsToSqm()) -- 4096px are mapped to 2048m |
847 | |
848 | local damage = self:getVehicleDamage() |
849 | if damage > 0 then |
850 | usage = usage * (1 + damage * SowingMachine.DAMAGED_USAGE_INCREASE) |
851 | end |
852 | |
853 | stats:updateStats("seedUsage", usage) |
854 | stats:updateStats("sownHectares", ha) |
855 | self:updateLastWorkedArea(spec.workAreaParameters.lastStatsArea) |
856 | |
857 | if not self:getIsAIActive() or not g_currentMission.missionInfo.helperBuySeeds then |
858 | local vehicle = spec.workAreaParameters.seedsVehicle |
859 | local fillUnitIndex = spec.workAreaParameters.seedsVehicleFillUnitIndex |
860 | local unloadInfoIndex = spec.workAreaParameters.seedsVehicleUnloadInfoIndex |
861 | local fillType = vehicle:getFillUnitFillType(fillUnitIndex) |
862 | local unloadInfo |
863 | if vehicle.getFillVolumeUnloadInfo ~= nil then |
864 | unloadInfo = vehicle:getFillVolumeUnloadInfo(unloadInfoIndex) |
865 | end |
866 | vehicle:addFillUnitFillLevel(self:getOwnerFarmId(), fillUnitIndex, -usage, fillType, ToolType.UNDEFINED, unloadInfo) |
867 | else |
868 | 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 |
869 | stats:updateStats("expenses", price) |
870 | g_currentMission:addMoney(-price, self:getOwnerFarmId(), MoneyType.PURCHASE_SEEDS) |
871 | end |
872 | end |
873 | |
874 | self:updateLastWorkedArea(0) -- mark as working |
875 | |
876 | if spec.isWorking then |
877 | stats:updateStats("sownTime", dt/(1000*60)) |
878 | end |
879 | end |
880 | |
881 | if self.isClient then |
882 | if spec.isWorking then |
883 | if not spec.isWorkSamplePlaying then |
884 | g_soundManager:playSample(spec.samples.work) |
885 | spec.isWorkSamplePlaying = true |
886 | end |
887 | else |
888 | if spec.isWorkSamplePlaying then |
889 | g_soundManager:stopSample(spec.samples.work) |
890 | spec.isWorkSamplePlaying = false |
891 | end |
892 | end |
893 | end |
894 | end |
onLoad
DescriptionDefinitiononLoad()Code
136 | function SowingMachine:onLoad(savegame) |
137 | local spec = self.spec_sowingMachine |
138 | |
139 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.sowingMachine.animationNodes.animationNode", "sowingMachine") --FS17 to FS19 |
140 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.turnedOnScrollers", "vehicle.sowingMachine.scrollerNodes.scrollerNode") --FS17 to FS19 |
141 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.useDirectPlanting", "vehicle.sowingMachine.useDirectPlanting#value") --FS17 to FS19 |
142 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.needsActivation#value", "vehicle.sowingMachine.needsActivation#value") --FS17 to FS19 |
143 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.sowingEffects", "vehicle.sowingMachine.effects") --FS17 to FS19 |
144 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.sowingEffectsWithFixedFillType", "vehicle.sowingMachine.fixedEffects") --FS17 to FS19 |
145 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.sowingMachine#supportsAiWithoutSowingMachine", "vehicle.turnOnVehicle.aiRequiresTurnOn") --FS17 to FS19 |
146 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.sowingMachine.directionNode#index", "vehicle.sowingMachine.directionNode#node") --FS19 to FS21 |
147 | |
148 | spec.allowFillFromAirWhileTurnedOn = self.xmlFile:getValue("vehicle.sowingMachine.allowFillFromAirWhileTurnedOn#value", true) |
149 | spec.directionNode = self.xmlFile:getValue("vehicle.sowingMachine.directionNode#node", self.components[1].node, self.components, self.i3dMappings) |
150 | spec.useDirectPlanting = self.xmlFile:getValue("vehicle.sowingMachine.useDirectPlanting#value", false) |
151 | spec.isWorking = false |
152 | spec.isProcessing = false |
153 | |
154 | spec.stoneLastState = 0 |
155 | spec.stoneWearMultiplierData = g_currentMission.stoneSystem:getWearMultiplierByType("SOWINGMACHINE") |
156 | |
157 | spec.seeds = {} |
158 | local fruitTypes = {} |
159 | local fruitTypeCategories = self.xmlFile:getValue("vehicle.sowingMachine.seedFruitTypeCategories") |
160 | local fruitTypeNames = self.xmlFile:getValue("vehicle.sowingMachine.seedFruitTypes") |
161 | if fruitTypeCategories ~= nil and fruitTypeNames == nil then |
162 | fruitTypes = g_fruitTypeManager:getFruitTypesByCategoryNames(fruitTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fruitTypeCategory '%s'.") |
163 | elseif fruitTypeCategories == nil and fruitTypeNames ~= nil then |
164 | fruitTypes = g_fruitTypeManager:getFruitTypesByNames(fruitTypeNames, "Warning: '"..self.configFileName.. "' has invalid fruitType '%s'.") |
165 | else |
166 | print("Warning: '"..self.configFileName.. "' a sowingMachine needs either the 'seedFruitTypeCategories' or 'seedFruitTypes' element.") |
167 | end |
168 | |
169 | if fruitTypes ~= nil then |
170 | for _,fruitType in pairs(fruitTypes) do |
171 | table.insert(spec.seeds, fruitType) |
172 | end |
173 | end |
174 | |
175 | spec.needsActivation = self.xmlFile:getValue("vehicle.sowingMachine.needsActivation#value", false) |
176 | spec.requiresFilling = self.xmlFile:getValue("vehicle.sowingMachine.requiresFilling#value", true) |
177 | |
178 | spec.fieldGroundType = g_currentMission.fieldGroundSystem:getFieldGroundValueByName(self.xmlFile:getValue("vehicle.sowingMachine.fieldGroundType#value", "SOWN")) |
179 | |
180 | if self.isClient then |
181 | spec.isWorkSamplePlaying = false |
182 | spec.samples = {} |
183 | spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.sowingMachine.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
184 | spec.samples.airBlower = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.sowingMachine.sounds", "airBlower", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
185 | |
186 | spec.sampleFillEnabled = false |
187 | spec.sampleFillStopTime = -1 |
188 | spec.lastFillLevel = -1 |
189 | |
190 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.sowingMachine.animationNodes", self.components, self, self.i3dMappings) |
191 | g_animationManager:setFillType(spec.animationNodes, FillType.UNKNOWN) |
192 | |
193 | local changeSeedInputButtonStr = self.xmlFile:getValue("vehicle.sowingMachine.changeSeedInputButton") |
194 | if changeSeedInputButtonStr ~= nil then |
195 | spec.changeSeedInputButton = InputAction[changeSeedInputButtonStr] |
196 | end |
197 | spec.changeSeedInputButton = Utils.getNoNil(spec.changeSeedInputButton, InputAction.TOGGLE_SEEDS) |
198 | end |
199 | |
200 | spec.currentSeed = 1 |
201 | spec.allowsSeedChanging = true |
202 | spec.showFruitCanNotBePlantedWarning = false |
203 | spec.showWrongFruitForMissionWarning = false |
204 | |
205 | spec.warnings = {} |
206 | spec.warnings.fruitCanNotBePlanted = g_i18n:getText("warning_theSelectedFruitTypeIsNotAvailableOnThisMap") |
207 | spec.warnings.wrongFruitForMission = g_i18n:getText("warning_theSelectedFruitTypeIsWrongForTheMission") |
208 | spec.warnings.wrongPlantingTime = g_i18n:getText("warning_theSelectedFruitTypeCantBePlantedInThisPeriod") |
209 | |
210 | spec.fillUnitIndex = self.xmlFile:getValue("vehicle.sowingMachine#fillUnitIndex", 1) |
211 | spec.unloadInfoIndex = self.xmlFile:getValue("vehicle.sowingMachine#unloadInfoIndex", 1) |
212 | |
213 | if self:getFillUnitByIndex(spec.fillUnitIndex) == nil then |
214 | Logging.xmlError(self.xmlFile, "FillUnit '%d' not defined!", spec.fillUnitIndex) |
215 | self:setLoadingState(VehicleLoadingUtil.VEHICLE_LOAD_ERROR) |
216 | return |
217 | end |
218 | |
219 | spec.fillTypeSources = {} |
220 | |
221 | if self.isClient then |
222 | spec.effects = g_effectManager:loadEffect(self.xmlFile, "vehicle.sowingMachine.effects", self.components, self, self.i3dMappings) |
223 | end |
224 | |
225 | spec.workAreaParameters = {} |
226 | spec.workAreaParameters.seedsFruitType = nil |
227 | spec.workAreaParameters.angle = 0 |
228 | spec.workAreaParameters.lastChangedArea = 0 |
229 | spec.workAreaParameters.lastStatsArea = 0 |
230 | spec.workAreaParameters.lastArea = 0 |
231 | |
232 | |
233 | self:setSeedIndex(1, true) |
234 | |
235 | if savegame ~= nil then |
236 | local selectedSeedFruitType = savegame.xmlFile:getValue(savegame.key..".sowingMachine#selectedSeedFruitType") |
237 | if selectedSeedFruitType ~= nil then |
238 | local fruitTypeDesc = g_fruitTypeManager:getFruitTypeByName(selectedSeedFruitType) |
239 | if fruitTypeDesc ~= nil then |
240 | self:setSeedFruitType(fruitTypeDesc.index, true) |
241 | end |
242 | end |
243 | end |
244 | |
245 | if not self.isClient then |
246 | SpecializationUtil.removeEventListener(self, "onUpdate", SowingMachine) |
247 | SpecializationUtil.removeEventListener(self, "onUpdateTick", SowingMachine) |
248 | end |
249 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
253 | function SowingMachine:onPostLoad(savegame) |
254 | -- 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) |
255 | SowingMachine.updateAiParameters(self) |
256 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
282 | function SowingMachine:onReadStream(streamId, connection) |
283 | local seedIndex = streamReadUInt8(streamId) |
284 | self:setSeedIndex(seedIndex, true) |
285 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
702 | function SowingMachine:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
703 | if self.isClient then |
704 | local spec = self.spec_sowingMachine |
705 | self:clearActionEventsTable(spec.actionEvents) |
706 | |
707 | if isActiveForInputIgnoreSelection and table.getn(spec.seeds) > 1 then |
708 | local _, actionEventId = self:addActionEvent(spec.actionEvents, spec.changeSeedInputButton, self, SowingMachine.actionEventToggleSeedType, false, true, false, true, nil) |
709 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH) |
710 | |
711 | SowingMachine.updateChooseSeedActionEvent(self) |
712 | |
713 | _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.TOGGLE_SEEDS_BACK, self, SowingMachine.actionEventToggleSeedTypeBack, false, true, false, true, nil) |
714 | g_inputBinding:setActionEventTextVisibility(actionEventId, false) |
715 | end |
716 | end |
717 | end |
onStartWorkAreaProcessing
DescriptionDefinitiononStartWorkAreaProcessing()Code
763 | function SowingMachine:onStartWorkAreaProcessing(dt) |
764 | local spec = self.spec_sowingMachine |
765 | |
766 | spec.isWorking = false |
767 | spec.isProcessing = false |
768 | |
769 | local seedsFruitType = spec.seeds[spec.currentSeed] |
770 | |
771 | local dx,_,dz = localDirectionToWorld(spec.directionNode, 0, 0, 1) |
772 | local angleRad = MathUtil.getYRotationFromDirection(dx, dz) |
773 | local desc = g_fruitTypeManager:getFruitTypeByIndex(seedsFruitType) |
774 | if desc ~= nil and desc.directionSnapAngle ~= 0 then |
775 | angleRad = math.floor(angleRad / desc.directionSnapAngle + 0.5) * desc.directionSnapAngle |
776 | end |
777 | local angle = FSDensityMapUtil.convertToDensityMapAngle(angleRad, g_currentMission.fieldGroundSystem:getGroundAngleMaxValue()) |
778 | |
779 | local seedsVehicle, seedsVehicleFillUnitIndex, seedsVehicleUnloadInfoIndex |
780 | if self:getFillUnitFillLevel(spec.fillUnitIndex) > 0 then |
781 | seedsVehicle = self |
782 | seedsVehicleFillUnitIndex = spec.fillUnitIndex |
783 | seedsVehicleUnloadInfoIndex = spec.unloadInfoIndex |
784 | else |
785 | if spec.fillTypeSources[FillType.SEEDS] ~= nil then |
786 | for _, src in ipairs(spec.fillTypeSources[FillType.SEEDS]) do |
787 | local vehicle = src.vehicle |
788 | if vehicle:getFillUnitFillLevel(src.fillUnitIndex) > 0 and vehicle:getFillUnitFillType(src.fillUnitIndex) == FillType.SEEDS then |
789 | seedsVehicle = vehicle |
790 | seedsVehicleFillUnitIndex = src.fillUnitIndex |
791 | break |
792 | end |
793 | end |
794 | end |
795 | end |
796 | |
797 | if seedsVehicle ~= nil and seedsVehicle ~= self then |
798 | local fillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(seedsFruitType) |
799 | seedsVehicle:setFillUnitFillTypeToDisplay(seedsVehicleFillUnitIndex, fillType) |
800 | end |
801 | |
802 | local isTurnedOn = self:getIsTurnedOn() |
803 | |
804 | -- check if selected fruit is available in current map |
805 | local canFruitBePlanted = false |
806 | if desc.terrainDataPlaneId ~= nil then |
807 | canFruitBePlanted = true |
808 | end |
809 | |
810 | if spec.showWrongFruitForMissionWarning then |
811 | spec.showWrongFruitForMissionWarning = false |
812 | end |
813 | |
814 | local isPlantingSeason = true |
815 | if not self:getCanPlantOutsideSeason() then |
816 | isPlantingSeason = g_currentMission.growthSystem:canFruitBePlanted(seedsFruitType) |
817 | end |
818 | |
819 | spec.showFruitCanNotBePlantedWarning = not canFruitBePlanted |
820 | spec.showWrongPlantingTimeWarning = not isPlantingSeason and (isTurnedOn or (not spec.needsActivation and self:getIsLowered())) |
821 | |
822 | spec.workAreaParameters.isActive = not spec.needsActivation or isTurnedOn |
823 | spec.workAreaParameters.canFruitBePlanted = canFruitBePlanted and isPlantingSeason |
824 | spec.workAreaParameters.seedsFruitType = seedsFruitType |
825 | spec.workAreaParameters.fieldGroundType = spec.fieldGroundType |
826 | spec.workAreaParameters.angle = angle |
827 | spec.workAreaParameters.seedsVehicle = seedsVehicle |
828 | spec.workAreaParameters.seedsVehicleFillUnitIndex = seedsVehicleFillUnitIndex |
829 | spec.workAreaParameters.seedsVehicleUnloadInfoIndex = seedsVehicleUnloadInfoIndex |
830 | spec.workAreaParameters.lastTotalArea = 0 |
831 | spec.workAreaParameters.lastChangedArea = 0 |
832 | spec.workAreaParameters.lastStatsArea = 0 |
833 | end |
onStateChange
DescriptionDefinitiononStateChange()Code
908 | function SowingMachine:onStateChange(state, data) |
909 | if state == Vehicle.STATE_CHANGE_ATTACH or state == Vehicle.STATE_CHANGE_DETACH or Vehicle.STATE_CHANGE_FILLTYPE_CHANGE then |
910 | local spec = self.spec_sowingMachine |
911 | spec.fillTypeSources = {} |
912 | if FillType.SEEDS ~= nil then |
913 | spec.fillTypeSources[FillType.SEEDS] = {} |
914 | local root = self.rootVehicle |
915 | FillUnit.addFillTypeSources(spec.fillTypeSources, root, self, {FillType.SEEDS}) |
916 | |
917 | local fillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(spec.seeds[spec.currentSeed]) |
918 | self:setFillTypeSourceDisplayFillType(fillType) |
919 | end |
920 | end |
921 | end |
onTurnedOff
DescriptionDefinitiononTurnedOff()Code
751 | function SowingMachine:onTurnedOff() |
752 | if self.isClient then |
753 | local spec = self.spec_sowingMachine |
754 | g_soundManager:stopSample(spec.samples.airBlower) |
755 | g_animationManager:stopAnimations(spec.animationNodes) |
756 | end |
757 | |
758 | SowingMachine.updateAiParameters(self) |
759 | end |
onTurnedOn
DescriptionDefinitiononTurnedOn()Code
739 | function SowingMachine:onTurnedOn() |
740 | if self.isClient then |
741 | local spec = self.spec_sowingMachine |
742 | g_soundManager:playSample(spec.samples.airBlower) |
743 | g_animationManager:startAnimations(spec.animationNodes) |
744 | end |
745 | |
746 | SowingMachine.updateAiParameters(self) |
747 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
296 | function SowingMachine:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
297 | local spec = self.spec_sowingMachine |
298 | if spec.isProcessing then |
299 | local fillType = self:getFillUnitForcedMaterialFillType(spec.fillUnitIndex) |
300 | if fillType ~= nil then |
301 | g_effectManager:setFillType(spec.effects, fillType) |
302 | g_effectManager:startEffects(spec.effects) |
303 | end |
304 | else |
305 | g_effectManager:stopEffects(spec.effects) |
306 | end |
307 | end |
onUpdateTick
DescriptionDefinitiononUpdateTick()Code
311 | function SowingMachine:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
312 | local spec = self.spec_sowingMachine |
313 | local actionEvent = spec.actionEvents[spec.changeSeedInputButton] |
314 | if actionEvent ~= nil then |
315 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, self:getIsSeedChangeAllowed()) |
316 | end |
317 | |
318 | if self.isActiveForInputIgnoreSelectionIgnoreAI then |
319 | if spec.showFruitCanNotBePlantedWarning then |
320 | g_currentMission:showBlinkingWarning(spec.warnings.fruitCanNotBePlanted) |
321 | elseif spec.showWrongFruitForMissionWarning then |
322 | g_currentMission:showBlinkingWarning(spec.warnings.wrongFruitForMission) |
323 | elseif spec.showWrongPlantingTimeWarning then |
324 | g_currentMission:showBlinkingWarning(string.format(spec.warnings.wrongPlantingTime, g_i18n:formatPeriod())) |
325 | end |
326 | end |
327 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
289 | function SowingMachine:onWriteStream(streamId, connection) |
290 | local spec = self.spec_sowingMachine |
291 | streamWriteUInt8(streamId, spec.currentSeed) |
292 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
74 | function SowingMachine.prerequisitesPresent(specializations) |
75 | return SpecializationUtil.hasSpecialization(FillUnit, specializations) and |
76 | SpecializationUtil.hasSpecialization(WorkArea, specializations) and |
77 | SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) |
78 | end |
processSowingMachineArea
DescriptionDefinitionprocessSowingMachineArea()Code
396 | function SowingMachine:processSowingMachineArea(workArea, dt) |
397 | local spec = self.spec_sowingMachine |
398 | local changedArea, totalArea = 0, 0 |
399 | spec.isWorking = self:getLastSpeed() > 0.5 |
400 | |
401 | if not spec.workAreaParameters.isActive then |
402 | return changedArea, totalArea |
403 | end |
404 | |
405 | if not self:getIsAIActive() or not g_currentMission.missionInfo.helperBuySeeds then |
406 | if spec.workAreaParameters.seedsVehicle == nil then |
407 | if self:getIsAIActive() then |
408 | local rootVehicle = self.rootVehicle |
409 | rootVehicle:stopCurrentAIJob(AIMessageErrorOutOfFill.new()) |
410 | end |
411 | |
412 | return changedArea, totalArea |
413 | end |
414 | end |
415 | |
416 | if not spec.workAreaParameters.canFruitBePlanted then |
417 | return changedArea, totalArea |
418 | end |
419 | |
420 | local sx,_,sz = getWorldTranslation(workArea.start) |
421 | local wx,_,wz = getWorldTranslation(workArea.width) |
422 | local hx,_,hz = getWorldTranslation(workArea.height) |
423 | |
424 | spec.isProcessing = spec.isWorking |
425 | |
426 | if not spec.useDirectPlanting then |
427 | local area, _ = FSDensityMapUtil.updateSowingArea(spec.workAreaParameters.seedsFruitType, sx,sz, wx,wz, hx,hz, spec.workAreaParameters.fieldGroundType, spec.workAreaParameters.angle, nil) |
428 | changedArea = changedArea + area |
429 | else |
430 | local area, _ = FSDensityMapUtil.updateDirectSowingArea(spec.workAreaParameters.seedsFruitType, sx,sz, wx,wz, hx,hz, spec.workAreaParameters.fieldGroundType, spec.workAreaParameters.angle, nil) |
431 | changedArea = changedArea + area |
432 | end |
433 | |
434 | if spec.isWorking then |
435 | spec.stoneLastState = FSDensityMapUtil.getStoneArea(sx, sz, wx, wz, hx, hz) |
436 | else |
437 | spec.stoneLastState = 0 |
438 | end |
439 | |
440 | spec.workAreaParameters.lastChangedArea = spec.workAreaParameters.lastChangedArea + changedArea |
441 | spec.workAreaParameters.lastStatsArea = spec.workAreaParameters.lastStatsArea + changedArea |
442 | spec.workAreaParameters.lastTotalArea = spec.workAreaParameters.lastTotalArea + totalArea |
443 | |
444 | -- remove tireTracks |
445 | FSDensityMapUtil.eraseTireTrack(sx,sz, wx,wz, hx,hz) |
446 | |
447 | self:updateMissionSowingWarning(sx, sz) |
448 | |
449 | return changedArea, totalArea |
450 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
116 | function SowingMachine.registerEventListeners(vehicleType) |
117 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", SowingMachine) |
118 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", SowingMachine) |
119 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", SowingMachine) |
120 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", SowingMachine) |
121 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", SowingMachine) |
122 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", SowingMachine) |
123 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", SowingMachine) |
124 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", SowingMachine) |
125 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", SowingMachine) |
126 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", SowingMachine) |
127 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", SowingMachine) |
128 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", SowingMachine) |
129 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", SowingMachine) |
130 | SpecializationUtil.registerEventListener(vehicleType, "onStateChange", SowingMachine) |
131 | SpecializationUtil.registerEventListener(vehicleType, "onChangedFillType", SowingMachine) |
132 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
82 | function SowingMachine.registerFunctions(vehicleType) |
83 | SpecializationUtil.registerFunction(vehicleType, "setSeedFruitType", SowingMachine.setSeedFruitType) |
84 | SpecializationUtil.registerFunction(vehicleType, "setSeedIndex", SowingMachine.setSeedIndex) |
85 | SpecializationUtil.registerFunction(vehicleType, "changeSeedIndex", SowingMachine.changeSeedIndex) |
86 | SpecializationUtil.registerFunction(vehicleType, "getIsSeedChangeAllowed", SowingMachine.getIsSeedChangeAllowed) |
87 | SpecializationUtil.registerFunction(vehicleType, "getSowingMachineFillUnitIndex", SowingMachine.getSowingMachineFillUnitIndex) |
88 | SpecializationUtil.registerFunction(vehicleType, "getCurrentSeedTypeIcon", SowingMachine.getCurrentSeedTypeIcon) |
89 | SpecializationUtil.registerFunction(vehicleType, "processSowingMachineArea", SowingMachine.processSowingMachineArea) |
90 | SpecializationUtil.registerFunction(vehicleType, "getUseSowingMachineAIRequirements", SowingMachine.getUseSowingMachineAIRequirements) |
91 | SpecializationUtil.registerFunction(vehicleType, "setFillTypeSourceDisplayFillType", SowingMachine.setFillTypeSourceDisplayFillType) |
92 | SpecializationUtil.registerFunction(vehicleType, "updateMissionSowingWarning", SowingMachine.updateMissionSowingWarning) |
93 | SpecializationUtil.registerFunction(vehicleType, "getCanPlantOutsideSeason", SowingMachine.getCanPlantOutsideSeason) |
94 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
98 | function SowingMachine.registerOverwrittenFunctions(vehicleType) |
99 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDrawFirstFillText", SowingMachine.getDrawFirstFillText) |
100 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAreControlledActionsAllowed", SowingMachine.getAreControlledActionsAllowed) |
101 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillUnitAllowsFillType", SowingMachine.getFillUnitAllowsFillType) |
102 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanToggleTurnedOn", SowingMachine.getCanToggleTurnedOn) |
103 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowFillFromAir", SowingMachine.getAllowFillFromAir) |
104 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirectionSnapAngle", SowingMachine.getDirectionSnapAngle) |
105 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "addFillUnitFillLevel", SowingMachine.addFillUnitFillLevel) |
106 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", SowingMachine.doCheckSpeedLimit) |
107 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", SowingMachine.getDirtMultiplier) |
108 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", SowingMachine.getWearMultiplier) |
109 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", SowingMachine.loadWorkAreaFromXML) |
110 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", SowingMachine.getCanBeSelected) |
111 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanAIImplementContinueWork", SowingMachine.getCanAIImplementContinueWork) |
112 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
269 | function SowingMachine:saveToXMLFile(xmlFile, key, usedModNames) |
270 | local spec = self.spec_sowingMachine |
271 | local selectedSeedFruitTypeName = "unknown" |
272 | local selectedSeedFruitType = spec.seeds[spec.currentSeed] |
273 | if selectedSeedFruitType ~= nil and selectedSeedFruitType ~= FruitType.UNKNOWN then |
274 | local fruitType = g_fruitTypeManager:getFruitTypeByIndex(selectedSeedFruitType) |
275 | selectedSeedFruitTypeName = fruitType.name |
276 | end |
277 | xmlFile:setValue(key.."#selectedSeedFruitType", selectedSeedFruitTypeName) |
278 | end |
setFillTypeSourceDisplayFillType
DescriptionDefinitionsetFillTypeSourceDisplayFillType()Code
478 | function SowingMachine:setFillTypeSourceDisplayFillType(fillType) |
479 | local spec = self.spec_sowingMachine |
480 | if spec.fillTypeSources[FillType.SEEDS] ~= nil then |
481 | for _, src in ipairs(spec.fillTypeSources[FillType.SEEDS]) do |
482 | local vehicle = src.vehicle |
483 | local fillLevel = vehicle:getFillUnitFillLevel(src.fillUnitIndex) |
484 | if fillLevel > 0 and vehicle:getFillUnitFillType(src.fillUnitIndex) == FillType.SEEDS then |
485 | vehicle:setFillUnitFillTypeToDisplay(src.fillUnitIndex, fillType) |
486 | break |
487 | elseif fillLevel == 0 then |
488 | -- when fill unit allowes only one fill type this icon is displayed permanently |
489 | -- so we overwrite this one as well |
490 | local fillTypes = vehicle:getFillUnitSupportedFillTypes(src.fillUnitIndex) |
491 | local numFillTypes = 0 |
492 | for fillTypeIndex, state in pairs(fillTypes) do |
493 | if state then |
494 | numFillTypes = numFillTypes + 1 |
495 | end |
496 | end |
497 | |
498 | if numFillTypes == 1 and fillTypes[FillType.SEEDS] == true then |
499 | vehicle:setFillUnitFillTypeToDisplay(src.fillUnitIndex, fillType) |
500 | break |
501 | end |
502 | end |
503 | end |
504 | end |
505 | end |
setSeedFruitType
DescriptionDefinitionsetSeedFruitType()Code
360 | function SowingMachine:setSeedFruitType(fruitType, noEventSend) |
361 | local spec = self.spec_sowingMachine |
362 | for i,v in ipairs(spec.seeds) do |
363 | if v == fruitType then |
364 | self:setSeedIndex(i, noEventSend) |
365 | break |
366 | end |
367 | end |
368 | end |
setSeedIndex
DescriptionDefinitionsetSeedIndex()Code
331 | function SowingMachine:setSeedIndex(seedIndex, noEventSend) |
332 | local spec = self.spec_sowingMachine |
333 | SetSeedIndexEvent.sendEvent(self, seedIndex, noEventSend) |
334 | spec.currentSeed = math.min(math.max(seedIndex, 1), table.getn(spec.seeds)) |
335 | |
336 | local fillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(spec.seeds[spec.currentSeed]) |
337 | self:setFillUnitFillTypeToDisplay(spec.fillUnitIndex, fillType, true) |
338 | self:setFillTypeSourceDisplayFillType(fillType) |
339 | |
340 | SowingMachine.updateAiParameters(self) |
341 | SowingMachine.updateChooseSeedActionEvent(self) |
342 | end |
updateAiParameters
DescriptionDefinitionupdateAiParameters()Code
934 | function SowingMachine.updateAiParameters(self) |
935 | local spec = self.spec_sowingMachine |
936 | |
937 | if self.addAITerrainDetailRequiredRange ~= nil then |
938 | self:clearAITerrainDetailRequiredRange() |
939 | self:clearAITerrainDetailProhibitedRange() |
940 | self:clearAIFruitProhibitions() |
941 | |
942 | -- if a cultivator is attached we estimate that it will cultivate infront of our sowing machine and we use also fieldGroundType, potatoHillValue and grass as requirements |
943 | local isCultivatorAttached = false |
944 | local isWeederAttached = false |
945 | local isRollerAttached = false |
946 | local vehicles = self.rootVehicle:getChildVehicles() |
947 | for i=1, #vehicles do |
948 | if SpecializationUtil.hasSpecialization(Cultivator, vehicles[i].specializations) then |
949 | isCultivatorAttached = true |
950 | vehicles[i]:updateCultivatorAIRequirements() |
951 | vehicles[i]:updateCultivatorEnabledState() |
952 | end |
953 | if SpecializationUtil.hasSpecialization(Weeder, vehicles[i].specializations) then |
954 | isWeederAttached = true |
955 | vehicles[i]:updateWeederAIRequirements() |
956 | end |
957 | if SpecializationUtil.hasSpecialization(Roller, vehicles[i].specializations) then |
958 | isRollerAttached = true |
959 | vehicles[i]:updateRollerAIRequirements() |
960 | end |
961 | end |
962 | |
963 | if isCultivatorAttached then |
964 | -- if sowing machine ai requirements are not used it's fully handled by cultivator spec |
965 | -- use direct seeding requirements since we can cultivate as well |
966 | if self:getUseSowingMachineAIRequirements() then |
967 | self:addAIGroundTypeRequirements(SowingMachine.AI_REQUIRED_GROUND_TYPES) |
968 | self:addAIGroundTypeRequirements(SowingMachine.AI_OUTPUT_GROUND_TYPES) |
969 | end |
970 | elseif isWeederAttached then |
971 | -- only if the weeder is turned on we use to sowingMachine requirements to sow the area |
972 | if self:getUseSowingMachineAIRequirements() then |
973 | self:clearAITerrainDetailRequiredRange() |
974 | self:addAIGroundTypeRequirements(SowingMachine.AI_REQUIRED_GROUND_TYPES) |
975 | end |
976 | elseif isRollerAttached then |
977 | -- only if the roller is turned on we use to sowingMachine requirements to sow the area |
978 | if self:getUseSowingMachineAIRequirements() then |
979 | self:clearAITerrainDetailRequiredRange() |
980 | self:addAIGroundTypeRequirements(SowingMachine.AI_REQUIRED_GROUND_TYPES) |
981 | end |
982 | else |
983 | self:addAIGroundTypeRequirements(SowingMachine.AI_REQUIRED_GROUND_TYPES) |
984 | |
985 | if spec.useDirectPlanting then |
986 | self:addAIGroundTypeRequirements(SowingMachine.AI_OUTPUT_GROUND_TYPES) |
987 | end |
988 | end |
989 | |
990 | if self:getUseSowingMachineAIRequirements() then |
991 | local fruitTypeIndex = spec.seeds[spec.currentSeed] |
992 | local fruitTypeDesc = g_fruitTypeManager:getFruitTypeByIndex(fruitTypeIndex) |
993 | if fruitTypeDesc ~= nil then |
994 | self:setAIFruitProhibitions(fruitTypeIndex, 0, fruitTypeDesc.maxHarvestingGrowthState) |
995 | end |
996 | end |
997 | end |
998 | end |
updateChooseSeedActionEvent
DescriptionDefinitionupdateChooseSeedActionEvent()Code
721 | function SowingMachine.updateChooseSeedActionEvent(self) |
722 | local spec = self.spec_sowingMachine |
723 | local actionEvent = spec.actionEvents[spec.changeSeedInputButton] |
724 | if actionEvent ~= nil then |
725 | local additionalText = "" |
726 | local fillType = g_fillTypeManager:getFillTypeByIndex(g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(spec.seeds[spec.currentSeed])) |
727 | if fillType ~= nil then |
728 | if fillType ~= FillType.UNKNOWN then |
729 | additionalText = string.format(" (%s)", fillType.title) |
730 | end |
731 | end |
732 | |
733 | g_inputBinding:setActionEventText(actionEvent.actionEventId, string.format("%s%s", g_i18n:getText("action_chooseSeed"), additionalText)) |
734 | end |
735 | end |
updateMissionSowingWarning
DescriptionDefinitionupdateMissionSowingWarning()Code
454 | function SowingMachine:updateMissionSowingWarning(x, z) |
455 | local spec = self.spec_sowingMachine |
456 | |
457 | spec.showWrongFruitForMissionWarning = false |
458 | |
459 | -- Unowned field. This function executes and thus it is allowed which means it is a mission field |
460 | if self:getLastTouchedFarmlandFarmId() == 0 then |
461 | local mission = g_missionManager:getMissionAtWorldPosition(x, z) |
462 | if mission ~= nil and mission.type.name == "sow" then |
463 | if mission.fruitType ~= spec.workAreaParameters.seedsFruitType then |
464 | spec.showWrongFruitForMissionWarning = true |
465 | end |
466 | end |
467 | end |
468 | end |