Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- AIConveyorBelt
- AIImplement
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BunkerSiloCompacter
- BunkerSiloInteractor
- BuyableBale
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- JigglingParts
- Leveler
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- MixerWagon
- Motorized
- Mountable
- Mower
- Pickup
- Pipe
- Plow
- PowerConsumer
- PowerTakeOffs
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StrawBlower
- StumpCutter
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TipOccluder
- Trailer
- TreePlanter
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Wearable
- Weeder
- Wheels
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
Combine
DescriptionSpecialization for combines providing threshing, effects, chopper and swath functionalityFunctions
- actionEventToggleChopper
- addCutterArea
- addCutterToCombine
- getCanBeSelected
- getCanBeTurnedOn
- getCombineLoadPercentage
- getFillLevelDependentSpeed
- getIsBufferCombine
- getIsFoldAllowed
- getIsThreshingAllowed
- getTurnedOnNotAllowedWarning
- initSpecialization
- loadCombineEffects
- loadCombineRotationNodes
- loadCombineSamples
- loadCombineSetup
- loadWorkAreaFromXML
- onChangedFillType
- onDeactivate
- onDelete
- onDraw
- onEndWorkAreaProcessing
- onEnterVehicle
- onFillUnitFillLevelChanged
- onFoldStateChanged
- onLeaveVehicle
- onLoad
- onPostAttachImplement
- onPostDetachImplement
- onPostLoad
- onReadStream
- onReadUpdateStream
- onRegisterActionEvents
- onStartWorkAreaProcessing
- onTurnedOff
- onTurnedOn
- onUpdate
- onUpdateTick
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- processCombineChopperArea
- processCombineSwathArea
- registerEventListeners
- registerEvents
- registerFunctions
- registerOverwrittenFunctions
- removeCutterFromCombine
- saveToXMLFile
- setChopperPSEnabled
- setCombineIsFilling
- setIsSwathActive
- setStrawPSEnabled
- setWorkedHectars
- startThreshing
- stopThreshing
- updateToggleStrawText
- verifyCombine
actionEventToggleChopper
DescriptionDefinitionactionEventToggleChopper()Code
1314 | function Combine.actionEventToggleChopper(self, actionName, inputValue, callbackState, isAnalog) |
1315 | local spec = self.spec_combine |
1316 | |
1317 | if spec.swath.isAvailable then |
1318 | local fruitType = g_fruitTypeManager:getFruitTypeIndexByFillTypeIndex(self:getFillUnitFillType(spec.fillUnitIndex)) |
1319 | if fruitType ~= nil and fruitType ~= FruitType.UNKNOWN then |
1320 | local fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(fruitType) |
1321 | if fruitDesc.hasWindrow then |
1322 | self:setIsSwathActive(not spec.isSwathActive) |
1323 | else |
1324 | g_currentMission:showBlinkingWarning(g_i18n:getText("warning_couldNotToggleChopper"), 2000) |
1325 | end |
1326 | else |
1327 | self:setIsSwathActive(not spec.isSwathActive) |
1328 | end |
1329 | end |
1330 | end |
addCutterArea
DescriptionDefinitionaddCutterArea()Code
865 | function Combine:addCutterArea(area, realArea, inputFruitType, outputFillType, strawRatio, farmId) |
866 | local spec = self.spec_combine |
867 | |
868 | if area > 0 and (spec.lastCuttersFruitType == FruitType.UNKNOWN or spec.lastCuttersArea == 0 or spec.lastCuttersOutputFillType == outputFillType) then |
869 | spec.lastCuttersArea = spec.lastCuttersArea + area |
870 | spec.lastCuttersOutputFillType = outputFillType |
871 | spec.lastCuttersInputFruitType = inputFruitType |
872 | spec.lastCuttersAreaTime = g_currentMission.time |
873 | |
874 | if not spec.swath.isAvailable then |
875 | local fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(inputFruitType) |
876 | spec.isSwathActive = not fruitDesc.hasWindrow |
877 | end |
878 | |
879 | local litersPerSqm = 60 |
880 | local fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(inputFruitType) |
881 | if fruitDesc.windrowLiterPerSqm ~= nil then |
882 | litersPerSqm = fruitDesc.windrowLiterPerSqm |
883 | end |
884 | |
885 | local liters = (realArea * g_currentMission:getFruitPixelsToSqm() * litersPerSqm) * strawRatio |
886 | local inputBuffer = spec.processing.inputBuffer |
887 | local slot = inputBuffer.buffer[inputBuffer.fillIndex] |
888 | slot.area = slot.area + area |
889 | slot.realArea = slot.realArea + realArea |
890 | slot.liters = slot.liters + liters |
891 | slot.inputLiters = slot.inputLiters + liters |
892 | slot.strawRatio = strawRatio |
893 | |
894 | if spec.fillEnableTime == nil then |
895 | spec.fillEnableTime = g_currentMission.time + spec.processing.toggleTime |
896 | end |
897 | |
898 | -- 8000/1200 = 6.66 liter/meter |
899 | -- 8000/1200 / 6 = 1.111 liter/m^2 |
900 | -- 8000/1200 / 6 / 2^2 = 0.277777 liter / density pixel (density is 4096^2, on a area of 2048m^2 |
901 | local pixelToSqm = g_currentMission:getFruitPixelsToSqm() -- 4096px are mapped to 2048m |
902 | local literPerSqm = 1 |
903 | if (inputFruitType ~= FruitType.UNKNOWN) then |
904 | fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(inputFruitType) |
905 | literPerSqm = fruitDesc.literPerSqm |
906 | end |
907 | local sqm = realArea*pixelToSqm |
908 | local deltaFillLevel = sqm*literPerSqm*spec.threshingScale |
909 | local fillType = outputFillType |
910 | |
911 | self:setWorkedHectars(spec.workedHectars + MathUtil.areaToHa(realArea, g_currentMission:getFruitPixelsToSqm())) |
912 | |
913 | if farmId ~= AccessHandler.EVERYONE then |
914 | local damage = self:getVehicleDamage() |
915 | if damage > 0 then |
916 | deltaFillLevel = deltaFillLevel * (1 - damage * Combine.DAMAGED_YIELD_REDUCTION) |
917 | end |
918 | end |
919 | |
920 | -- buffer only the set time in the xml, after that we do not add more to the fill unit |
921 | if self:getFillUnitCapacity(spec.fillUnitIndex) == math.huge and self:getFillUnitFillLevel(spec.fillUnitIndex) > 0.001 then |
922 | if spec.lastDischargeTime + spec.fillLevelBufferTime < g_time then |
923 | return deltaFillLevel |
924 | end |
925 | end |
926 | |
927 | local loadInfo = self:getFillVolumeLoadInfo(spec.loadInfoIndex) |
928 | return self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, deltaFillLevel, fillType, ToolType.UNDEFINED, loadInfo) |
929 | end |
930 | |
931 | return 0 |
932 | end |
addCutterToCombine
DescriptionDefinitionaddCutterToCombine()Code
831 | function Combine:addCutterToCombine(cutter) |
832 | local spec = self.spec_combine |
833 | |
834 | if spec.attachedCutters[cutter] == nil then |
835 | spec.attachedCutters[cutter] = cutter |
836 | spec.numAttachedCutters = spec.numAttachedCutters + 1 |
837 | end |
838 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
1101 | function Combine:getCanBeSelected(superFunc) |
1102 | return true |
1103 | end |
getCanBeTurnedOn
DescriptionReturns if turn on is allowedDefinition
getCanBeTurnedOn()Return Values
boolean | allow | allow turn on |
1036 | function Combine:getCanBeTurnedOn(superFunc) |
1037 | local spec = self.spec_combine |
1038 | |
1039 | if spec.numAttachedCutters <= 0 then |
1040 | return false |
1041 | end |
1042 | |
1043 | for cutter, _ in pairs(spec.attachedCutters) do |
1044 | if cutter ~= self then |
1045 | if cutter.getCanBeTurnedOn ~= nil and not cutter:getCanBeTurnedOn() then |
1046 | return false |
1047 | end |
1048 | end |
1049 | end |
1050 | |
1051 | return superFunc(self) |
1052 | end |
getCombineLoadPercentage
DescriptionDefinitiongetCombineLoadPercentage()Code
1013 | function Combine:getCombineLoadPercentage() |
1014 | local spec = self.spec_combine |
1015 | if spec ~= nil then |
1016 | if spec.numAttachedCutters > 0 then |
1017 | local loadSum = 0 |
1018 | for cutter, _ in pairs(spec.attachedCutters) do |
1019 | if cutter.getCutterLoad ~= nil then |
1020 | loadSum = loadSum + cutter:getCutterLoad() |
1021 | end |
1022 | end |
1023 | |
1024 | return loadSum / spec.numAttachedCutters |
1025 | end |
1026 | end |
1027 | |
1028 | return 0 |
1029 | end |
getFillLevelDependentSpeed
DescriptionDefinitiongetFillLevelDependentSpeed()Code
997 | function Combine:getFillLevelDependentSpeed() |
998 | local spec = self.spec_combine |
999 | if spec.rotationNodesSpeedReverseFillLevel ~= nil then |
1000 | local fillLevelPct = self:getFillUnitFillLevel(spec.fillUnitIndex) / self:getFillUnitCapacity(spec.fillUnitIndex) |
1001 | if fillLevelPct > spec.rotationNodesSpeedReverseFillLevel then |
1002 | return -1 |
1003 | else |
1004 | return 1 |
1005 | end |
1006 | else |
1007 | return 1 |
1008 | end |
1009 | end |
getIsBufferCombine
DescriptionDefinitiongetIsBufferCombine()Code
991 | function Combine:getIsBufferCombine() |
992 | return self:getFillUnitCapacity(self.spec_combine.fillUnitIndex) == math.huge |
993 | end |
getIsFoldAllowed
DescriptionReturns if fold is allowedDefinition
getIsFoldAllowed()Return Values
boolean | allowsFold | allows folding |
1084 | function Combine:getIsFoldAllowed(superFunc, direction, onAiTurnOn) |
1085 | local spec = self.spec_combine |
1086 | |
1087 | if not self.allowFoldWhileThreshing and self:getIsTurnedOn() then |
1088 | return false |
1089 | end |
1090 | |
1091 | local fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex) |
1092 | if direction == spec.foldDirection and (fillLevel > spec.foldFillLevelThreshold and self:getFillUnitCapacity(spec.fillUnitIndex) ~= math.huge) then |
1093 | return false |
1094 | end |
1095 | |
1096 | return superFunc(self, direction, onAiTurnOn) |
1097 | end |
getIsThreshingAllowed
DescriptionReturns if threshing is allowedDefinition
getIsThreshingAllowed(boolean earlyWarning)Arguments
boolean | earlyWarning | early warning |
boolean | allows | allows threshing |
938 | function Combine:getIsThreshingAllowed(earlyWarning) |
939 | local spec = self.spec_combine |
940 | |
941 | if spec.allowThreshingDuringRain then |
942 | return true |
943 | end |
944 | |
945 | local rainScale = g_currentMission.environment.weather:getRainFallScale() |
946 | local timeSinceLastRain = g_currentMission.environment.weather:getTimeSinceLastRain() |
947 | if earlyWarning ~= nil and earlyWarning == true then |
948 | if rainScale <= 0.02 and timeSinceLastRain > 20 then |
949 | return true |
950 | end |
951 | else |
952 | if rainScale <= 0.1 and timeSinceLastRain > 20 then |
953 | return true |
954 | end |
955 | end |
956 | |
957 | return false |
958 | end |
getTurnedOnNotAllowedWarning
DescriptionReturns turn on not allowed warning textDefinition
getTurnedOnNotAllowedWarning()Return Values
string | warningText | turn on not allowed warning text |
1057 | function Combine:getTurnedOnNotAllowedWarning(superFunc) |
1058 | if self:getIsActiveForInput(true) then |
1059 | local spec = self.spec_combine |
1060 | if not self:getCanBeTurnedOn() then |
1061 | if spec.numAttachedCutters == 0 then |
1062 | return spec.noCutterWarning |
1063 | else |
1064 | for cutter, _ in pairs(spec.attachedCutters) do |
1065 | if cutter ~= self then |
1066 | if cutter.getTurnedOnNotAllowedWarning ~= nil then |
1067 | local warning = cutter:getTurnedOnNotAllowedWarning() |
1068 | if warning ~= nil then |
1069 | return warning |
1070 | end |
1071 | end |
1072 | end |
1073 | end |
1074 | end |
1075 | end |
1076 | end |
1077 | |
1078 | return superFunc(self) |
1079 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
18 | function Combine.initSpecialization() |
19 | g_workAreaTypeManager:addWorkAreaType("combineChopper", false) |
20 | g_workAreaTypeManager:addWorkAreaType("combineSwath", false) |
21 | end |
loadCombineEffects
DescriptionDefinitionloadCombineEffects()Code
534 | function Combine:loadCombineEffects(xmlFile, baseKey, entry) |
535 | if self.isClient then |
536 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseKey .. ".chopperParticleSystems", baseKey..".chopperEffect") --FS17 to FS19 |
537 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseKey .. ".strawParticleSystems", baseKey..".strawEffect") --FS17 to FS19 |
538 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, baseKey .. ".threshingFillParticleSystems", baseKey..".fillEffect") --FS17 to FS19 |
539 | |
540 | entry.chopperEffects = g_effectManager:loadEffect(self.xmlFile, baseKey .. ".chopperEffect", self.components, self, self.i3dMappings) |
541 | entry.strawEffects = g_effectManager:loadEffect(self.xmlFile, baseKey .. ".strawEffect", self.components, self, self.i3dMappings) |
542 | entry.fillEffects = g_effectManager:loadEffect(self.xmlFile, baseKey .. ".fillEffect", self.components, self, self.i3dMappings) |
543 | |
544 | entry.strawPSenabled = false |
545 | entry.chopperPSenabled = false |
546 | entry.isFilling = false |
547 | |
548 | entry.fillEnableTime = nil |
549 | entry.fillDisableTime = nil |
550 | end |
551 | end |
loadCombineRotationNodes
DescriptionDefinitionloadCombineRotationNodes()Code
556 | function Combine:loadCombineRotationNodes(xmlFile, baseKey, entry) |
557 | if self.isClient then |
558 | entry.animationNodes = g_animationManager:loadAnimations(xmlFile, baseKey..".animationNodes", self.components, self, self.i3dMappings) |
559 | entry.fillingAnimationNodes = g_animationManager:loadAnimations(xmlFile, baseKey..".fillingAnimationNodes", self.components, self, self.i3dMappings) |
560 | entry.rotationNodesSpeedReverseFillLevel = getXMLFloat(xmlFile, baseKey .. ".animationNodes#speedReverseFillLevel") |
561 | end |
562 | end |
loadCombineSamples
DescriptionDefinitionloadCombineSamples()Code
567 | function Combine:loadCombineSamples(xmlFile, key, entry) |
568 | if self.isClient then |
569 | entry.samples = {} |
570 | entry.samples.start = g_soundManager:loadSampleFromXML(xmlFile, key .. ".sounds", "start", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
571 | entry.samples.stop = g_soundManager:loadSampleFromXML(xmlFile, key .. ".sounds", "stop", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
572 | entry.samples.work = g_soundManager:loadSampleFromXML(xmlFile, key .. ".sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
573 | end |
574 | end |
loadCombineSetup
DescriptionDefinitionloadCombineSetup()Code
451 | function Combine:loadCombineSetup(xmlFile, baseKey, entry) |
452 | entry.allowThreshingDuringRain = Utils.getNoNil(getXMLBool(xmlFile, baseKey .. "#allowThreshingDuringRain"), false) |
453 | |
454 | entry.fillUnitIndex = Utils.getNoNil(getXMLInt(xmlFile, baseKey .. "#fillUnitIndex"), 1) |
455 | entry.loadInfoIndex = Utils.getNoNil(getXMLInt(xmlFile, baseKey .. "#loadInfoIndex"), 1) |
456 | |
457 | -- swath |
458 | entry.swath = {} |
459 | entry.swath.isAvailable = Utils.getNoNil(getXMLBool(xmlFile, baseKey .. ".swath#available"), false) |
460 | local isDefaultActive = Utils.getNoNil(getXMLBool(xmlFile, baseKey .. ".swath#isDefaultActive"), entry.swath.isAvailable) |
461 | if entry.swath.isAvailable then |
462 | entry.swath.workAreaIndex = getXMLInt(xmlFile, baseKey .. ".swath#workAreaIndex") |
463 | if entry.swath.workAreaIndex == nil then |
464 | entry.swath.isAvailable = false |
465 | g_logManager:xmlWarning(self.configFileName, "Missing 'swath#workAreaIndex' for combine swath function!") |
466 | end |
467 | entry.warningTime = 0 |
468 | end |
469 | |
470 | -- chopper |
471 | entry.chopper = {} |
472 | entry.chopper.isAvailable = Utils.getNoNil(getXMLBool(xmlFile, baseKey .. ".chopper#available"), false) |
473 | if entry.chopper.isAvailable then |
474 | entry.chopper.workAreaIndex = getXMLInt(xmlFile, baseKey .. ".chopper#workAreaIndex") |
475 | if entry.chopper.workAreaIndex == nil then |
476 | entry.chopper.isAvailable = false |
477 | g_logManager:xmlWarning(self.configFileName, "Missing 'chopper#workAreaIndex' for combine chopper function!") |
478 | end |
479 | |
480 | entry.chopper.animName = getXMLString(xmlFile, baseKey .. ".chopper#animName") |
481 | entry.chopper.animSpeedScale = getXMLFloat(xmlFile, baseKey .. ".chopper#animSpeedScale") |
482 | end |
483 | |
484 | entry.isSwathActive = isDefaultActive |
485 | |
486 | --ladder |
487 | entry.ladder = {} |
488 | entry.ladder.animName = getXMLString(xmlFile, baseKey .. ".ladder#animName") |
489 | entry.ladder.animSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. ".ladder#animSpeedScale"), 1) |
490 | entry.ladder.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. ".ladder#foldMinLimit"), 0.99) |
491 | entry.ladder.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. ".ladder#foldMaxLimit"), 1) |
492 | entry.ladder.foldDirection = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. ".ladder#foldDirection"), MathUtil.sign(entry.ladder.animSpeedScale)) |
493 | |
494 | -- processing buffer |
495 | entry.processing = {} |
496 | local toggleTime = getXMLFloat(xmlFile, baseKey .. ".processing#toggleTime") |
497 | if toggleTime == nil and entry.chopper.animName ~= nil then |
498 | toggleTime = self:getAnimationDurection(entry.chopper.animName) |
499 | if toggleTime ~= nil then |
500 | toggleTime = toggleTime / 1000 |
501 | end |
502 | end |
503 | entry.processing.toggleTime = Utils.getNoNil(toggleTime, 0) * 1000 |
504 | |
505 | local inputBuffer = {} |
506 | local slotDuration = 300 |
507 | local slotCount = MathUtil.clamp(math.ceil(entry.processing.toggleTime / slotDuration), 2, 20) |
508 | inputBuffer.slotCount = slotCount |
509 | inputBuffer.slotDuration = math.ceil( entry.processing.toggleTime / inputBuffer.slotCount ) |
510 | inputBuffer.fillIndex = 1 |
511 | inputBuffer.dropIndex = inputBuffer.fillIndex + 1 |
512 | inputBuffer.slotTimer = inputBuffer.slotDuration |
513 | inputBuffer.activeTimeout = inputBuffer.slotDuration * (inputBuffer.slotCount + 2) |
514 | inputBuffer.activeTimer = inputBuffer.activeTimeout |
515 | inputBuffer.buffer = {} |
516 | for i=1, inputBuffer.slotCount do |
517 | table.insert(inputBuffer.buffer, {realArea = 0, area = 0, liters = 0, inputLiters = 0, strawRatio = 0} ) |
518 | end |
519 | entry.processing.inputBuffer = inputBuffer |
520 | |
521 | -- threhsing start animation |
522 | entry.threshingStartAnimation = getXMLString(xmlFile, baseKey .. ".threshingStartAnimation#name") |
523 | entry.threshingStartAnimationSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. ".threshingStartAnimation#speedScale"), 1) |
524 | entry.threshingStartAnimationInitialIsStarted = Utils.getNoNil(getXMLBool(xmlFile, baseKey .. ".threshingStartAnimation#initialIsStarted"), false) |
525 | |
526 | entry.foldFillLevelThreshold = Utils.getNoNil(getXMLFloat(xmlFile, baseKey .. ".folding#fillLevelThreshold"), (self:getFillUnitCapacity(entry.fillUnitIndex) or 0.04) * 0.15) |
527 | entry.foldDirection = Utils.getNoNil(getXMLInt(xmlFile, baseKey .. ".folding#direction"), 1) |
528 | entry.allowFoldWhileThreshing = Utils.getNoNil(getXMLBool(xmlFile, baseKey .. ".folding#allowWhileThreshing"), false) |
529 | end |
loadWorkAreaFromXML
DescriptionDefinitionloadWorkAreaFromXML()Code
1107 | function Combine:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
1108 | if not superFunc(self, workArea, xmlFile, key) then |
1109 | return false |
1110 | end |
1111 | |
1112 | if workArea.type == WorkAreaType.COMBINECHOPPER or workArea.type == WorkAreaType.COMBINESWATH then |
1113 | if getXMLBool(xmlFile, key .. "#requiresOwnedFarmland") == nil then |
1114 | workArea.requiresOwnedFarmland = false |
1115 | end |
1116 | if getXMLBool(xmlFile, key .. "#needsSetIsTurnedOn") == nil then |
1117 | workArea.needsSetIsTurnedOn = false |
1118 | end |
1119 | end |
1120 | |
1121 | return true |
1122 | end |
onChangedFillType
DescriptionDefinitiononChangedFillType()Code
1173 | function Combine:onChangedFillType(fillUnitIndex, fillTypeIndex) |
1174 | local spec = self.spec_combine |
1175 | if fillUnitIndex == spec.fillUnitIndex then |
1176 | if spec.chopperPSenabled then |
1177 | self:setChopperPSEnabled(true, true, true) |
1178 | end |
1179 | if spec.strawPSenabled then |
1180 | self:setStrawPSEnabled(true, true, true) |
1181 | end |
1182 | if spec.isFilling then |
1183 | self:setCombineIsFilling(true, true, true) |
1184 | end |
1185 | end |
1186 | end |
onDeactivate
DescriptionCalled on deactivateDefinition
onDeactivate()Code
1190 | function Combine:onDeactivate() |
1191 | local spec = self.spec_combine |
1192 | |
1193 | self:setChopperPSEnabled(false, false, true) |
1194 | self:setStrawPSEnabled(false, false, true) |
1195 | self:setCombineIsFilling(false, false, true) |
1196 | spec.fillEnableTime = nil |
1197 | spec.fillDisableTime = nil |
1198 | end |
onDelete
DescriptionCalled on deletingDefinition
onDelete()Code
200 | function Combine:onDelete() |
201 | if self.isClient then |
202 | local spec = self.spec_combine |
203 | |
204 | g_effectManager:deleteEffects(spec.fillEffects) |
205 | g_effectManager:deleteEffects(spec.strawEffects) |
206 | g_effectManager:deleteEffects(spec.chopperEffects) |
207 | |
208 | g_animationManager:deleteAnimations(spec.animationNodes) |
209 | |
210 | g_soundManager:deleteSamples(spec.samples) |
211 | end |
212 | end |
onDraw
DescriptionCalled on drawDefinition
onDraw(boolean isActiveForInput, boolean isSelected)Arguments
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
443 | function Combine:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
444 | if self:getIsTurnedOn() and not self:getIsThreshingAllowed(false) then |
445 | g_currentMission:showBlinkingWarning(g_i18n:getText("warning_doNotThreshDuringRainOrHail"), 2000) |
446 | end |
447 | end |
onEndWorkAreaProcessing
DescriptionDefinitiononEndWorkAreaProcessing()Code
1165 | function Combine:onEndWorkAreaProcessing(dt, hasProcessed) |
1166 | local spec = self.spec_combine |
1167 | local inputBuffer = spec.processing.inputBuffer |
1168 | inputBuffer.buffer[inputBuffer.dropIndex].liters = math.max(0, inputBuffer.buffer[inputBuffer.dropIndex].liters - spec.workAreaParameters.droppedLiters) |
1169 | end |
onEnterVehicle
DescriptionDefinitiononEnterVehicle()Code
1255 | function Combine:onEnterVehicle() |
1256 | local ladder = self.spec_combine.ladder |
1257 | if ladder.animName ~= nil then |
1258 | local fold = true |
1259 | if self.getFoldAnimTime ~= nil then |
1260 | local foldAnimTime = self:getFoldAnimTime() |
1261 | if foldAnimTime > ladder.foldMaxLimit or foldAnimTime < ladder.foldMinLimit then |
1262 | fold = false |
1263 | end |
1264 | end |
1265 | |
1266 | if fold then |
1267 | self:playAnimation(ladder.animName, -ladder.animSpeedScale, self:getAnimationTime(ladder.animName), true) |
1268 | end |
1269 | end |
1270 | end |
onFillUnitFillLevelChanged
DescriptionDefinitiononFillUnitFillLevelChanged()Code
1302 | function Combine:onFillUnitFillLevelChanged(fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData, appliedDelta) |
1303 | local spec = self.spec_combine |
1304 | |
1305 | if fillUnitIndex == spec.fillUnitIndex then |
1306 | if fillLevelDelta < 0 then |
1307 | spec.lastDischargeTime = g_time |
1308 | end |
1309 | end |
1310 | end |
onFoldStateChanged
DescriptionDefinitiononFoldStateChanged()Code
1293 | function Combine:onFoldStateChanged(direction, moveToMiddle) |
1294 | local ladder = self.spec_combine.ladder |
1295 | if ladder.animName ~= nil and direction ~= 0 and not moveToMiddle then |
1296 | self:playAnimation(ladder.animName, direction*ladder.animSpeedScale*ladder.foldDirection, self:getAnimationTime(ladder.animName), true) |
1297 | end |
1298 | end |
onLeaveVehicle
DescriptionDefinitiononLeaveVehicle()Code
1274 | function Combine:onLeaveVehicle() |
1275 | local ladder = self.spec_combine.ladder |
1276 | if ladder.animName ~= nil then |
1277 | local fold = true |
1278 | if self.getFoldAnimTime ~= nil then |
1279 | local foldAnimTime = self:getFoldAnimTime() |
1280 | if foldAnimTime > ladder.foldMaxLimit or foldAnimTime < ladder.foldMinLimit then |
1281 | fold = false |
1282 | end |
1283 | end |
1284 | |
1285 | if fold then |
1286 | self:playAnimation(ladder.animName, ladder.animSpeedScale, self:getAnimationTime(ladder.animName), true) |
1287 | end |
1288 | end |
1289 | end |
onLoad
DescriptionDefinitiononLoad()Code
106 | function Combine:onLoad(savegame) |
107 | local spec = self.spec_combine |
108 | |
109 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.combine.chopperSwitch", "vehicle.combine.swath and vehicle.combine.chopper") --FS17 to FS19 |
110 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.combine.rotationNodes.rotationNode", "combine") --FS17 to FS19 |
111 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.indoorHud.workedHectars", "vehicle.combine.dashboards.dashboard with valueType 'workedHectars'") --FS17 to FS19 |
112 | |
113 | self:loadCombineSetup(self.xmlFile, "vehicle.combine", spec) |
114 | self:loadCombineEffects(self.xmlFile, "vehicle.combine", spec) |
115 | self:loadCombineRotationNodes(self.xmlFile, "vehicle.combine", spec) |
116 | self:loadCombineSamples(self.xmlFile, "vehicle.combine", spec) |
117 | |
118 | spec.attachedCutters = {} |
119 | spec.numAttachedCutters = 0 |
120 | |
121 | spec.noCutterWarning = g_i18n:convertText(Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.combine.warning#noCutter"), "$l10n_warning_noCuttersAttached"), self.customEnvironment) |
122 | |
123 | spec.lastArea = 0 |
124 | spec.lastAreaZeroTime = 0 |
125 | spec.lastAreaNonZeroTime = -1000000 |
126 | spec.lastCuttersArea = 0 |
127 | spec.lastCuttersAreaTime = -10000 |
128 | spec.lastInputFruitType = FruitType.UNKNOWN |
129 | spec.lastValidInputFruitType = FruitType.UNKNOWN |
130 | spec.lastCuttersFruitType = FruitType.UNKNOWN |
131 | spec.lastCuttersInputFruitType = FruitType.UNKNOWN |
132 | spec.lastDischargeTime = 0 |
133 | spec.lastChargeTime = 0 |
134 | spec.fillLevelBufferTime = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.combine#fillLevelBufferTime"), 2000) -- time the fill level buffer is filled without unloading |
135 | |
136 | spec.workedHectars = 0 |
137 | spec.workedHectarsSent = 0 |
138 | if self.loadDashboardsFromXML ~= nil then |
139 | local dashboardData = {valueTypeToLoad = "workedHectars", |
140 | valueObject = spec, |
141 | valueFunc = "workedHectars"} |
142 | |
143 | self:loadDashboardsFromXML(self.xmlFile, "vehicle.combine.dashboards", dashboardData) |
144 | end |
145 | |
146 | spec.threshingScale = 1 |
147 | spec.lastLostFillLevel = 0 |
148 | |
149 | spec.workAreaParameters = {} |
150 | spec.workAreaParameters.lastRealArea = 0 |
151 | spec.workAreaParameters.lastArea = 0 |
152 | spec.workAreaParameters.litersToDrop = 0 |
153 | spec.workAreaParameters.droppedLiters = 0 |
154 | spec.workAreaParameters.isChopperEffectEnabled = 0 |
155 | spec.workAreaParameters.isStrawEffectEnabled = 0 |
156 | |
157 | spec.dirtyFlag = self:getNextDirtyFlag() |
158 | end |
onPostAttachImplement
DescriptionCalled on attaching a implementDefinition
onPostAttachImplement(table implement)Arguments
table | implement | implement to attach |
1203 | function Combine:onPostAttachImplement(attachable, inputJointDescIndex, jointDescIndex) |
1204 | local spec = self.spec_combine |
1205 | |
1206 | local attacherJoint = attachable:getActiveInputAttacherJoint() |
1207 | if attacherJoint ~= nil then |
1208 | if attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTER or attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTERHARVESTER then |
1209 | self:addCutterToCombine(attachable) |
1210 | end |
1211 | end |
1212 | end |
onPostDetachImplement
DescriptionCalled on detaching a implementDefinition
onPostDetachImplement(integer implementIndex)Arguments
integer | implementIndex | index of implement to detach |
1217 | function Combine:onPostDetachImplement(implementIndex) |
1218 | local spec = self.spec_combine |
1219 | |
1220 | local object = self:getObjectFromImplementIndex(implementIndex) |
1221 | if object ~= nil then |
1222 | local attacherJoint = object:getActiveInputAttacherJoint() |
1223 | if attacherJoint ~= nil then |
1224 | if attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTER or attacherJoint.jointType == AttacherJoints.JOINTTYPE_CUTTERHARVESTER then |
1225 | self:removeCutterFromCombine(object) |
1226 | end |
1227 | end |
1228 | end |
1229 | end |
onPostLoad
DescriptionCalled after loadingDefinition
onPostLoad(table savegame)Arguments
table | savegame | savegame |
163 | function Combine:onPostLoad(savegame) |
164 | local spec = self.spec_combine |
165 | |
166 | if savegame ~= nil then |
167 | if spec.swath.isAvailable then |
168 | local isSwathActive = Utils.getNoNil(getXMLBool(savegame.xmlFile, savegame.key .. ".combine#isSwathActive"), spec.isSwathActive) |
169 | self:setIsSwathActive(isSwathActive, true, true) |
170 | end |
171 | self:setWorkedHectars(Utils.getNoNil(getXMLFloat(savegame.xmlFile, savegame.key .. ".combine#workedHectars"), spec.workedHectars)) |
172 | else |
173 | self:setIsSwathActive(spec.isSwathActive, true, true) |
174 | end |
175 | |
176 | local ladder = spec.ladder |
177 | if ladder.animName ~= nil then |
178 | local time = 0 |
179 | if self.getFoldAnimTime ~= nil then |
180 | local foldAnimTime = self:getFoldAnimTime() |
181 | if foldAnimTime > ladder.foldMaxLimit or foldAnimTime < ladder.foldMinLimit then |
182 | time = 1 |
183 | end |
184 | end |
185 | |
186 | if ladder.foldDirection ~= 1 then |
187 | time = 1 - time |
188 | end |
189 | |
190 | self:setAnimationTime(ladder.animName, time, true) |
191 | end |
192 | |
193 | if self:getFillUnitCapacity(spec.fillUnitIndex) == 0 then |
194 | g_logManager:xmlWarning(self.configFileName, "Capacity of fill unit '%d' for combine needs to be set greater 0 or not defined! (not defined = infinity)", spec.fillUnitIndex) |
195 | end |
196 | end |
onReadStream
DescriptionCalled on client side on joinDefinition
onReadStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
229 | function Combine:onReadStream(streamId, connection) |
230 | local spec = self.spec_combine |
231 | |
232 | spec.lastValidInputFruitType = streamReadUIntN(streamId, FruitTypeManager.SEND_NUM_BITS) |
233 | local combineIsFilling = streamReadBool(streamId) |
234 | local chopperPSenabled = streamReadBool(streamId) |
235 | local strawPSenabled = streamReadBool(streamId) |
236 | |
237 | self:setCombineIsFilling(combineIsFilling, false, true) |
238 | self:setChopperPSEnabled(chopperPSenabled, false, true) |
239 | self:setStrawPSEnabled(strawPSenabled, false, true) |
240 | |
241 | local isSwathActive = streamReadBool(streamId) |
242 | self:setIsSwathActive(isSwathActive, true) |
243 | |
244 | local workedHectars = streamReadFloat32(streamId) |
245 | self:setWorkedHectars(workedHectars) |
246 | end |
onReadUpdateStream
DescriptionCalled on on updateDefinition
onReadUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
269 | function Combine:onReadUpdateStream(streamId, timestamp, connection) |
270 | if connection:getIsServer() then |
271 | if streamReadBool(streamId) then |
272 | local spec = self.spec_combine |
273 | spec.lastValidInputFruitType = streamReadUIntN(streamId, FruitTypeManager.SEND_NUM_BITS) |
274 | |
275 | local combineIsFilling = streamReadBool(streamId) |
276 | local chopperPSenabled = streamReadBool(streamId) |
277 | local strawPSenabled = streamReadBool(streamId) |
278 | self:setCombineIsFilling(combineIsFilling, false, true) |
279 | self:setChopperPSEnabled(chopperPSenabled, false, true) |
280 | self:setStrawPSEnabled(strawPSenabled, false, true) |
281 | |
282 | local workedHectars = streamReadFloat32(streamId) |
283 | self:setWorkedHectars(workedHectars) |
284 | end |
285 | end |
286 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
1126 | function Combine:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
1127 | if self.isClient then |
1128 | |
1129 | local spec = self.spec_combine |
1130 | self:clearActionEventsTable(spec.actionEvents) |
1131 | |
1132 | if isActiveForInputIgnoreSelection and spec.swath.isAvailable and spec.chopper.isAvailable then |
1133 | local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_CHOPPER, self, Combine.actionEventToggleChopper, false, true, false, true, nil) |
1134 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL) |
1135 | Combine.updateToggleStrawText(self) |
1136 | end |
1137 | end |
1138 | end |
onStartWorkAreaProcessing
DescriptionDefinitiononStartWorkAreaProcessing()Code
1142 | function Combine:onStartWorkAreaProcessing(dt) |
1143 | local spec = self.spec_combine |
1144 | |
1145 | spec.workAreaParameters.droppedLiters = 0 |
1146 | spec.workAreaParameters.litersToDrop = 0 |
1147 | spec.workAreaParameters.strawRatio = 0 |
1148 | spec.workAreaParameters.dropFillType = FillType.UNKNOWN |
1149 | |
1150 | local lastValidFillType = self:getFillUnitLastValidFillType(spec.fillUnitIndex) |
1151 | if lastValidFillType ~= FillType.UNKNOWN then |
1152 | local inputBuffer = spec.processing.inputBuffer |
1153 | local inputLiters = inputBuffer.buffer[inputBuffer.dropIndex].inputLiters |
1154 | spec.workAreaParameters.litersToDrop = math.min(inputBuffer.buffer[inputBuffer.dropIndex].liters, (dt / inputBuffer.slotDuration) * inputLiters) |
1155 | spec.workAreaParameters.strawRatio = inputBuffer.buffer[inputBuffer.dropIndex].strawRatio |
1156 | spec.workAreaParameters.dropFillType = lastValidFillType |
1157 | end |
1158 | |
1159 | spec.workAreaParameters.lastRealArea = 0 |
1160 | spec.workAreaParameters.lastArea = 0 |
1161 | end |
onTurnedOff
DescriptionCalled on turn offDefinition
onTurnedOff(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
1245 | function Combine:onTurnedOff() |
1246 | self:stopThreshing() |
1247 | if self.isClient then |
1248 | local spec = self.spec_combine |
1249 | g_animationManager:stopAnimations(spec.animationNodes) |
1250 | end |
1251 | end |
onTurnedOn
DescriptionCalled on turn onDefinition
onTurnedOn(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
1234 | function Combine:onTurnedOn() |
1235 | self:startThreshing() |
1236 | if self.isClient then |
1237 | local spec = self.spec_combine |
1238 | g_animationManager:startAnimations(spec.animationNodes) |
1239 | end |
1240 | end |
onUpdate
DescriptionCalled on updateDefinition
onUpdate(float dt, boolean isActiveForInput, boolean isSelected)Arguments
float | dt | time since last call in ms |
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
313 | function Combine:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
314 | local spec = self.spec_combine |
315 | |
316 | local isTurnedOn = self:getIsTurnedOn() |
317 | if isTurnedOn then |
318 | if self.isServer and spec.swath.isAvailable then |
319 | -- check for changes while threshing, e.g. activated straw swath and then start threshing canola (has no windrow) |
320 | local fruitType = g_fruitTypeManager:getFruitTypeIndexByFillTypeIndex(self:getFillUnitFillType(spec.fillUnitIndex)) |
321 | if spec.isSwathActive and fruitType ~= nil and fruitType ~= FruitType.UNKNOWN then |
322 | local fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(fruitType) |
323 | if not fruitDesc.hasWindrow then |
324 | self:setIsSwathActive(false) |
325 | end |
326 | else |
327 | -- if the combine does not support chopper but it was forced by the last fill type |
328 | -- if the new fill type supports swath again we change it back |
329 | if not spec.chopper.isAvailable then |
330 | if not spec.isSwathActive and fruitType ~= nil and fruitType ~= FruitType.UNKNOWN then |
331 | local fruitDesc = g_fruitTypeManager:getFruitTypeByIndex(fruitType) |
332 | if fruitDesc.hasWindrow then |
333 | self:setIsSwathActive(true) |
334 | end |
335 | end |
336 | end |
337 | end |
338 | end |
339 | end |
340 | |
341 | if self.isServer then |
342 | if self:getFillUnitFillLevel(spec.fillUnitIndex) < 0.0001 then |
343 | spec.lastDischargeTime = g_time |
344 | end |
345 | end |
346 | end |
onUpdateTick
DescriptionCalled on update tickDefinition
onUpdateTick(float dt, boolean isActiveForInput, boolean isSelected)Arguments
float | dt | time since last call in ms |
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
353 | function Combine:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
354 | local spec = self.spec_combine |
355 | |
356 | if self.isServer then |
357 | spec.lastArea = spec.lastCuttersArea |
358 | spec.lastAreaZeroTime = spec.lastAreaZeroTime + dt |
359 | if spec.lastArea > 0 then |
360 | spec.lastAreaZeroTime = 0 |
361 | spec.lastAreaNonZeroTime = g_currentMission.time |
362 | end |
363 | spec.lastInputFruitType = spec.lastCuttersInputFruitType |
364 | spec.lastCuttersArea = 0 |
365 | spec.lastCuttersInputFruitType = FruitType.UNKNOWN |
366 | spec.lastCuttersFruitType = FruitType.UNKNOWN |
367 | |
368 | if spec.lastInputFruitType ~= FruitType.UNKNOWN then |
369 | spec.lastValidInputFruitType = spec.lastInputFruitType |
370 | end |
371 | |
372 | local inputBuffer = spec.processing.inputBuffer |
373 | |
374 | if spec.lastAreaZeroTime > 500 then |
375 | if spec.fillDisableTime == nil then |
376 | spec.fillDisableTime = g_currentMission.time + spec.processing.toggleTime |
377 | end |
378 | end |
379 | if spec.fillEnableTime ~= nil and spec.fillEnableTime <= g_currentMission.time then |
380 | self:setCombineIsFilling(true, false, false) |
381 | spec.fillEnableTime = nil |
382 | end |
383 | if spec.fillDisableTime ~= nil and spec.fillDisableTime <= g_currentMission.time then |
384 | self:setCombineIsFilling(false, false, false) |
385 | spec.fillDisableTime = nil |
386 | end |
387 | |
388 | spec.workAreaParameters.isChopperEffectEnabled = math.max(spec.workAreaParameters.isChopperEffectEnabled - dt, 0) |
389 | spec.workAreaParameters.isStrawEffectEnabled = math.max(spec.workAreaParameters.isStrawEffectEnabled - dt, 0) |
390 | |
391 | local chopperPSActive = spec.workAreaParameters.isChopperEffectEnabled > 0 |
392 | local strawPSActive = spec.workAreaParameters.isStrawEffectEnabled > 0 |
393 | self:setChopperPSEnabled(chopperPSActive, false, false) |
394 | self:setStrawPSEnabled(strawPSActive, false, false) |
395 | |
396 | if chopperPSActive or strawPSActive then |
397 | self:raiseActive() |
398 | end |
399 | |
400 | if self:getIsTurnedOn() then |
401 | local stats = g_currentMission:farmStats(self:getOwnerFarmId()) |
402 | stats:updateStats("threshedTime", dt / (1000 * 60)) |
403 | stats:updateStats("workedTime", dt / (1000 * 60)) |
404 | end |
405 | |
406 | inputBuffer.slotTimer = inputBuffer.slotTimer - dt |
407 | if inputBuffer.slotTimer < 0 then |
408 | inputBuffer.slotTimer = inputBuffer.slotDuration |
409 | |
410 | inputBuffer.fillIndex = inputBuffer.fillIndex + 1 |
411 | if inputBuffer.fillIndex > inputBuffer.slotCount then |
412 | inputBuffer.fillIndex = 1 |
413 | end |
414 | |
415 | local lastDropIndex = inputBuffer.dropIndex |
416 | inputBuffer.dropIndex = inputBuffer.dropIndex + 1 |
417 | if inputBuffer.dropIndex > inputBuffer.slotCount then |
418 | inputBuffer.dropIndex = 1 |
419 | end |
420 | |
421 | inputBuffer.buffer[inputBuffer.dropIndex].liters = inputBuffer.buffer[inputBuffer.dropIndex].liters + inputBuffer.buffer[lastDropIndex].liters |
422 | inputBuffer.buffer[inputBuffer.dropIndex].inputLiters = inputBuffer.buffer[inputBuffer.dropIndex].inputLiters + inputBuffer.buffer[lastDropIndex].liters --inputLiters |
423 | |
424 | inputBuffer.buffer[lastDropIndex].area = 0 |
425 | inputBuffer.buffer[lastDropIndex].realArea = 0 |
426 | inputBuffer.buffer[lastDropIndex].liters = 0 |
427 | inputBuffer.buffer[lastDropIndex].inputLiters = 0 |
428 | end |
429 | |
430 | if spec.isFilling ~= spec.sentIsFilling or spec.chopperPSenabled ~= spec.sentChopperPSenabled or spec.strawPSenabled ~= spec.sentStrawPSenabled then |
431 | self:raiseDirtyFlags(spec.dirtyFlag) |
432 | spec.sentIsFilling = spec.isFilling |
433 | spec.sentChopperPSenabled = spec.chopperPSenabled |
434 | spec.sentStrawPSenabled = spec.strawPSenabled |
435 | end |
436 | end |
437 | end |
onWriteStream
DescriptionCalled on server side on joinDefinition
onWriteStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
252 | function Combine:onWriteStream(streamId, connection) |
253 | local spec = self.spec_combine |
254 | |
255 | streamWriteUIntN(streamId, spec.lastValidInputFruitType, FruitTypeManager.SEND_NUM_BITS) |
256 | streamWriteBool(streamId, spec.isFilling) |
257 | streamWriteBool(streamId, spec.chopperPSenabled) |
258 | streamWriteBool(streamId, spec.strawPSenabled) |
259 | streamWriteBool(streamId, spec.isSwathActive) |
260 | |
261 | streamWriteFloat32(streamId, spec.workedHectars) |
262 | end |
onWriteUpdateStream
DescriptionCalled on on updateDefinition
onWriteUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
293 | function Combine:onWriteUpdateStream(streamId, connection, dirtyMask) |
294 | if not connection:getIsServer() then |
295 | local spec = self.spec_combine |
296 | |
297 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
298 | streamWriteUIntN(streamId, spec.lastValidInputFruitType, FruitTypeManager.SEND_NUM_BITS) |
299 | streamWriteBool(streamId, spec.isFilling) |
300 | streamWriteBool(streamId, spec.chopperPSenabled) |
301 | streamWriteBool(streamId, spec.strawPSenabled) |
302 | |
303 | streamWriteFloat32(streamId, spec.workedHectars) |
304 | end |
305 | end |
306 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
25 | function Combine.prerequisitesPresent(specializations) |
26 | return SpecializationUtil.hasSpecialization(WorkArea, specializations) and |
27 | SpecializationUtil.hasSpecialization(FillUnit, specializations) and |
28 | (SpecializationUtil.hasSpecialization(Drivable, specializations) or SpecializationUtil.hasSpecialization(Attachable, specializations)) and |
29 | SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations) and |
30 | SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) |
31 | end |
processCombineChopperArea
DescriptionDefinitionprocessCombineChopperArea()Code
607 | function Combine:processCombineChopperArea(workArea) |
608 | local spec = self.spec_combine |
609 | |
610 | if not spec.isSwathActive then |
611 | local litersToDrop = spec.workAreaParameters.litersToDrop |
612 | local strawRatio = spec.workAreaParameters.strawRatio |
613 | spec.workAreaParameters.droppedLiters = litersToDrop |
614 | |
615 | if litersToDrop > 0 and strawRatio > 0 then |
616 | local xs,_,zs = getWorldTranslation(workArea.start) |
617 | local xw,_,zw = getWorldTranslation(workArea.width) |
618 | local xh,_,zh = getWorldTranslation(workArea.height) |
619 | |
620 | FSDensityMapUtil.setGroundTypeLayerArea(xs, zs, xw, zw, xh, zh, g_currentMission.chopperGroundLayerType) |
621 | |
622 | -- raise active until litersToDrop is 0 |
623 | self:raiseActive() |
624 | spec.workAreaParameters.isChopperEffectEnabled = 500 |
625 | end |
626 | end |
627 | |
628 | return spec.workAreaParameters.lastRealArea, spec.workAreaParameters.lastArea |
629 | end |
processCombineSwathArea
DescriptionDefinitionprocessCombineSwathArea()Code
633 | function Combine:processCombineSwathArea(workArea) |
634 | local spec = self.spec_combine |
635 | local litersToDrop = spec.workAreaParameters.litersToDrop |
636 | |
637 | if spec.isSwathActive then |
638 | if litersToDrop > 0 then |
639 | local droppedLiters = 0 |
640 | local fruitDesc = g_fruitTypeManager:getFruitTypeByFillTypeIndex(spec.workAreaParameters.dropFillType) |
641 | if fruitDesc ~= nil and fruitDesc.windrowLiterPerSqm ~= nil then |
642 | local windrowFillType = g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(fruitDesc.index) |
643 | if windrowFillType ~= nil then |
644 | local sx,sy,sz,ex,ey,ez = DensityMapHeightUtil.getLineByArea(workArea.start, workArea.width, workArea.height) |
645 | local dropped, lineOffset = DensityMapHeightUtil.tipToGroundAroundLine(self, litersToDrop, windrowFillType, sx, sy, sz, ex, ey, ez, 0, nil, workArea.lineOffset, false, nil, false) |
646 | droppedLiters = dropped |
647 | workArea.lineOffset = lineOffset |
648 | end |
649 | end |
650 | if droppedLiters > 0 then |
651 | spec.workAreaParameters.isStrawEffectEnabled = 500 |
652 | end |
653 | spec.workAreaParameters.droppedLiters = droppedLiters |
654 | end |
655 | end |
656 | |
657 | return spec.workAreaParameters.lastRealArea, spec.workAreaParameters.lastArea |
658 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
77 | function Combine.registerEventListeners(vehicleType) |
78 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Combine) |
79 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Combine) |
80 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Combine) |
81 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Combine) |
82 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Combine) |
83 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Combine) |
84 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Combine) |
85 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Combine) |
86 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Combine) |
87 | SpecializationUtil.registerEventListener(vehicleType, "onDraw", Combine) |
88 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Combine) |
89 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Combine) |
90 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Combine) |
91 | SpecializationUtil.registerEventListener(vehicleType, "onChangedFillType", Combine) |
92 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Combine) |
93 | SpecializationUtil.registerEventListener(vehicleType, "onPostAttachImplement", Combine) |
94 | SpecializationUtil.registerEventListener(vehicleType, "onPostDetachImplement", Combine) |
95 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", Combine) |
96 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", Combine) |
97 | SpecializationUtil.registerEventListener(vehicleType, "onEnterVehicle", Combine) |
98 | SpecializationUtil.registerEventListener(vehicleType, "onLeaveVehicle", Combine) |
99 | SpecializationUtil.registerEventListener(vehicleType, "onFoldStateChanged", Combine) |
100 | SpecializationUtil.registerEventListener(vehicleType, "onFillUnitFillLevelChanged", Combine) |
101 | end |
registerEvents
DescriptionDefinitionregisterEvents()Code
35 | function Combine.registerEvents(vehicleType) |
36 | SpecializationUtil.registerEvent(vehicleType, "onStartThreshing") |
37 | SpecializationUtil.registerEvent(vehicleType, "onStopThreshing") |
38 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
42 | function Combine.registerFunctions(vehicleType) |
43 | SpecializationUtil.registerFunction(vehicleType, "loadCombineSetup", Combine.loadCombineSetup) |
44 | SpecializationUtil.registerFunction(vehicleType, "loadCombineEffects", Combine.loadCombineEffects) |
45 | SpecializationUtil.registerFunction(vehicleType, "loadCombineRotationNodes", Combine.loadCombineRotationNodes) |
46 | SpecializationUtil.registerFunction(vehicleType, "loadCombineSamples", Combine.loadCombineSamples) |
47 | SpecializationUtil.registerFunction(vehicleType, "setIsSwathActive", Combine.setIsSwathActive) |
48 | SpecializationUtil.registerFunction(vehicleType, "processCombineChopperArea", Combine.processCombineChopperArea) |
49 | SpecializationUtil.registerFunction(vehicleType, "processCombineSwathArea", Combine.processCombineSwathArea) |
50 | SpecializationUtil.registerFunction(vehicleType, "setChopperPSEnabled", Combine.setChopperPSEnabled) |
51 | SpecializationUtil.registerFunction(vehicleType, "setStrawPSEnabled", Combine.setStrawPSEnabled) |
52 | SpecializationUtil.registerFunction(vehicleType, "setCombineIsFilling", Combine.setCombineIsFilling) |
53 | SpecializationUtil.registerFunction(vehicleType, "startThreshing", Combine.startThreshing) |
54 | SpecializationUtil.registerFunction(vehicleType, "stopThreshing", Combine.stopThreshing) |
55 | SpecializationUtil.registerFunction(vehicleType, "setWorkedHectars", Combine.setWorkedHectars) |
56 | SpecializationUtil.registerFunction(vehicleType, "addCutterToCombine", Combine.addCutterToCombine) |
57 | SpecializationUtil.registerFunction(vehicleType, "removeCutterFromCombine", Combine.removeCutterFromCombine) |
58 | SpecializationUtil.registerFunction(vehicleType, "addCutterArea", Combine.addCutterArea) |
59 | SpecializationUtil.registerFunction(vehicleType, "getIsThreshingAllowed", Combine.getIsThreshingAllowed) |
60 | SpecializationUtil.registerFunction(vehicleType, "verifyCombine", Combine.verifyCombine) |
61 | SpecializationUtil.registerFunction(vehicleType, "getIsBufferCombine", Combine.getIsBufferCombine) |
62 | SpecializationUtil.registerFunction(vehicleType, "getFillLevelDependentSpeed", Combine.getFillLevelDependentSpeed) |
63 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
67 | function Combine.registerOverwrittenFunctions(vehicleType) |
68 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", Combine.getCanBeTurnedOn) |
69 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getTurnedOnNotAllowedWarning", Combine.getTurnedOnNotAllowedWarning) |
70 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsFoldAllowed", Combine.getIsFoldAllowed) |
71 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Combine.getCanBeSelected) |
72 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", Combine.loadWorkAreaFromXML) |
73 | end |
removeCutterFromCombine
DescriptionDefinitionremoveCutterFromCombine()Code
842 | function Combine:removeCutterFromCombine(cutter) |
843 | local spec = self.spec_combine |
844 | |
845 | if spec.attachedCutters[cutter] ~= nil then |
846 | spec.numAttachedCutters = spec.numAttachedCutters - 1 |
847 | if spec.numAttachedCutters == 0 then |
848 | self:setIsTurnedOn(false, true) |
849 | -- if its a buffered combine -> clear the "invisible" tank on cutter detach |
850 | if self:getIsBufferCombine() then |
851 | local currentFillType = self:getFillUnitFillType(spec.fillUnitIndex) |
852 | if currentFillType ~= FillType.UNKNOWN then |
853 | if self:getIsBufferCombine() then |
854 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge, currentFillType, ToolType.UNDEFINED, nil) |
855 | end |
856 | end |
857 | end |
858 | end |
859 | spec.attachedCutters[cutter] = nil |
860 | end |
861 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
216 | function Combine:saveToXMLFile(xmlFile, key, usedModNames) |
217 | local spec = self.spec_combine |
218 | |
219 | if spec.swath.isAvailable then |
220 | setXMLBool(xmlFile, key.."#isSwathActive", spec.isSwathActive) |
221 | setXMLFloat(xmlFile, key.."#workedHectars", spec.workedHectars) |
222 | end |
223 | end |
setChopperPSEnabled
DescriptionSet chopper PS enabledDefinition
setChopperPSEnabled(boolean chopperPSenabled, boolean fruitTypeChanged, boolean isSynchronized)Arguments
boolean | chopperPSenabled | set enabled |
boolean | fruitTypeChanged | fruit type has changed |
boolean | isSynchronized | filling is synchronized |
665 | function Combine:setChopperPSEnabled(chopperPSenabled, fruitTypeChanged, isSynchronized) |
666 | local spec = self.spec_combine |
667 | |
668 | if spec.chopperPSenabled ~= chopperPSenabled or fruitTypeChanged then |
669 | if spec.chopperEffects ~= nil and (not chopperPSenabled or fruitTypeChanged) then |
670 | g_effectManager:stopEffects(spec.chopperEffects) |
671 | end |
672 | |
673 | spec.chopperPSenabled = chopperPSenabled |
674 | if self.isServer and isSynchronized then |
675 | spec.sentChopperPSenabled = chopperPSenabled |
676 | end |
677 | if chopperPSenabled and self.isClient then |
678 | if spec.chopperEffects ~= nil then |
679 | g_effectManager:setFillType(spec.chopperEffects, self:getFillUnitLastValidFillType(spec.fillUnitIndex)) |
680 | g_effectManager:startEffects(spec.chopperEffects) |
681 | end |
682 | end |
683 | end |
684 | end |
setCombineIsFilling
DescriptionSet combine is fillingDefinition
setCombineIsFilling(boolean isFilling, boolean fruitTypeChanged, boolean isSynchronized)Arguments
boolean | isFilling | combine is filling |
boolean | fruitTypeChanged | fruit type has changed |
boolean | isSynchronized | filling is synchronized |
720 | function Combine:setCombineIsFilling(isFilling, fruitTypeChanged, isSynchronized) |
721 | local spec = self.spec_combine |
722 | |
723 | if spec.isFilling ~= isFilling or fruitTypeChanged then |
724 | spec.isFilling = isFilling |
725 | |
726 | if isFilling then |
727 | g_animationManager:startAnimations(spec.fillingAnimationNodes) |
728 | else |
729 | g_animationManager:stopAnimations(spec.fillingAnimationNodes) |
730 | end |
731 | |
732 | g_animationManager:setFillType(spec.fillingAnimationNodes, self:getFillUnitLastValidFillType(spec.fillUnitIndex)) |
733 | |
734 | if self.isServer and isSynchronized then |
735 | spec.sentIsFilling = isFilling |
736 | end |
737 | |
738 | if spec.fillEffects ~= nil and (not isFilling or fruitTypeChanged) then |
739 | g_effectManager:stopEffects(spec.fillEffects) |
740 | end |
741 | |
742 | if isFilling then |
743 | if spec.fillEffects ~= nil then |
744 | g_effectManager:setFillType(spec.fillEffects, self:getFillUnitLastValidFillType(spec.fillUnitIndex)) |
745 | g_effectManager:startEffects(spec.fillEffects) |
746 | end |
747 | end |
748 | end |
749 | end |
setIsSwathActive
DescriptionSet is straw enabledDefinition
setIsSwathActive(boolean isSwathActive, boolean noEventSend, boolean force)Arguments
boolean | isSwathActive | new state |
boolean | noEventSend | no event send |
boolean | force | force action |
581 | function Combine:setIsSwathActive(isSwathActive, noEventSend, force) |
582 | local spec = self.spec_combine |
583 | |
584 | if isSwathActive ~= spec.isSwathActive or force then |
585 | CombineStrawEnableEvent.sendEvent(self, isSwathActive, noEventSend) |
586 | spec.isSwathActive = isSwathActive |
587 | |
588 | local anim = spec.chopper.animName |
589 | if self.playAnimation ~= nil and anim ~= nil then |
590 | local dir = 1 |
591 | if isSwathActive then |
592 | dir = -1 |
593 | end |
594 | self:playAnimation(anim, dir, self:getAnimationTime(anim), true) |
595 | |
596 | if force then |
597 | AnimatedVehicle.updateAnimationByName(self, anim, 9999999) |
598 | end |
599 | end |
600 | |
601 | Combine.updateToggleStrawText(self) |
602 | end |
603 | end |
setStrawPSEnabled
DescriptionSet straw PS enabledDefinition
setStrawPSEnabled(boolean strawPSenabled, boolean fruitTypeChanged, boolean isSynchronized)Arguments
boolean | strawPSenabled | set enabled |
boolean | fruitTypeChanged | fruit type has changed |
boolean | isSynchronized | filling is synchronized |
691 | function Combine:setStrawPSEnabled(strawPSenabled, fruitTypeChanged, isSynchronized) |
692 | local spec = self.spec_combine |
693 | |
694 | if spec.strawPSenabled ~= strawPSenabled or fruitTypeChanged then |
695 | if spec.strawEffects ~= nil and (not strawPSenabled or fruitTypeChanged) then |
696 | g_effectManager:stopEffects(spec.strawEffects) |
697 | end |
698 | |
699 | spec.strawPSenabled = strawPSenabled |
700 | if self.isServer and isSynchronized then |
701 | spec.sentStrawPSenabled = strawPSenabled |
702 | end |
703 | if not strawPSenabled then |
704 | spec.strawToDrop = 0 |
705 | end |
706 | if strawPSenabled and self.isClient then |
707 | if spec.strawEffects ~= nil then |
708 | g_effectManager:setFillType(spec.strawEffects, self:getFillUnitLastValidFillType(spec.fillUnitIndex)) |
709 | g_effectManager:startEffects(spec.strawEffects) |
710 | end |
711 | end |
712 | end |
713 | end |
setWorkedHectars
DescriptionSet worked hectars value and updated hudDefinition
setWorkedHectars(float hectars)Arguments
float | hectars | new hectars value |
816 | function Combine:setWorkedHectars(hectars) |
817 | local spec = self.spec_combine |
818 | |
819 | spec.workedHectars = hectars |
820 | |
821 | if self.isServer then |
822 | if math.abs(spec.workedHectars-spec.workedHectarsSent) > 0.01 then |
823 | self:raiseDirtyFlags(spec.dirtyFlag) |
824 | spec.workedHectarsSent = spec.workedHectars |
825 | end |
826 | end |
827 | end |
startThreshing
DescriptionStart threshingDefinition
startThreshing()Code
753 | function Combine:startThreshing() |
754 | local spec = self.spec_combine |
755 | |
756 | if spec.numAttachedCutters > 0 then |
757 | -- do not lower the cutter if the combine is turned on during headland (happens if ai was blocked during headland) |
758 | local allowLowering = not self:getIsAIActive() or not self:getRootVehicle():getAIIsTurning() |
759 | |
760 | for _,cutter in pairs(spec.attachedCutters) do |
761 | if allowLowering then |
762 | if cutter ~= self then |
763 | local jointDescIndex = self:getAttacherJointIndexFromObject(cutter) |
764 | self:setJointMoveDown(jointDescIndex, true, true) |
765 | end |
766 | end |
767 | |
768 | cutter:setIsTurnedOn(true, true) |
769 | end |
770 | |
771 | if spec.threshingStartAnimation ~= nil and self.playAnimation ~= nil then |
772 | self:playAnimation(spec.threshingStartAnimation, spec.threshingStartAnimationSpeedScale, self:getAnimationTime(spec.threshingStartAnimation), true) |
773 | end |
774 | |
775 | if self.isClient then |
776 | g_soundManager:stopSamples(spec.samples) |
777 | g_soundManager:playSample(spec.samples.start) |
778 | g_soundManager:playSample(spec.samples.work, 0, spec.samples.start) |
779 | end |
780 | |
781 | SpecializationUtil.raiseEvent(self, "onStartThreshing") |
782 | end |
783 | end |
stopThreshing
DescriptionStop threshingDefinition
stopThreshing()Code
787 | function Combine:stopThreshing() |
788 | local spec = self.spec_combine |
789 | |
790 | if self.isClient then |
791 | g_soundManager:stopSamples(spec.samples) |
792 | g_soundManager:playSample(spec.samples.stop) |
793 | end |
794 | |
795 | self:setCombineIsFilling(false, false, true) |
796 | |
797 | for cutter,_ in pairs(spec.attachedCutters) do |
798 | if cutter ~= self then |
799 | local jointDescIndex = self:getAttacherJointIndexFromObject(cutter) |
800 | self:setJointMoveDown(jointDescIndex, false, true) |
801 | end |
802 | |
803 | cutter:setIsTurnedOn(false, true) |
804 | end |
805 | |
806 | if spec.threshingStartAnimation ~= nil and spec.playAnimation ~= nil then |
807 | self:playAnimation(spec.threshingStartAnimation, -spec.threshingStartAnimationSpeedScale, self:getAnimationTime(spec.threshingStartAnimation), true) |
808 | end |
809 | |
810 | SpecializationUtil.raiseEvent(self, "onStopThreshing") |
811 | end |
updateToggleStrawText
DescriptionDefinitionupdateToggleStrawText()Code
1334 | function Combine.updateToggleStrawText(self) |
1335 | local spec = self.spec_combine |
1336 | local actionEvent = spec.actionEvents[InputAction.TOGGLE_CHOPPER] |
1337 | if actionEvent ~= nil and actionEvent.actionEventId ~= nil then |
1338 | local text |
1339 | if spec.isSwathActive then |
1340 | text = g_i18n:getText("action_disableStrawSwath") |
1341 | else |
1342 | text = g_i18n:getText("action_enableStrawSwath") |
1343 | end |
1344 | |
1345 | g_inputBinding:setActionEventText(actionEvent.actionEventId, text) |
1346 | end |
1347 | end |
verifyCombine
DescriptionDefinitionverifyCombine()Code
962 | function Combine:verifyCombine(fruitType, outputFillType) |
963 | local spec = self.spec_combine |
964 | |
965 | if self:getFillUnitFillLevel(spec.fillUnitIndex) > self:getFillTypeChangeThreshold() * self:getFillUnitCapacity(spec.fillUnitIndex) then |
966 | local currentFillType = self:getFillUnitFillType(spec.fillUnitIndex) |
967 | if currentFillType ~= FillType.UNKNOWN and fruitType ~= FruitType.UNKNOWN and currentFillType ~= outputFillType then |
968 | -- if we are a combine harvester without a "real" fill unit we empty the buffer if a new fill type comes from the cutter |
969 | if self:getIsBufferCombine() then |
970 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge, currentFillType, ToolType.UNDEFINED, nil) |
971 | return self |
972 | end |
973 | |
974 | return nil |
975 | end |
976 | end |
977 | |
978 | if not self:getIsThreshingAllowed() then |
979 | return nil |
980 | end |
981 | |
982 | if self:getFillUnitFreeCapacity(spec.fillUnitIndex) == 0 then |
983 | return nil |
984 | end |
985 | |
986 | return self |
987 | end |