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
WorkMode
DescriptionSpecialization for tools with switchable work modes by providing grouping of different animations and work areasFunctions
- actionEventWorkModeChange
- actionEventWorkModeChangeDirect
- deactivateWindrowerEffects
- getAllowsLowering
- getAreEffectsVisible
- getCanBeSelected
- getIsMovingToolActive
- getIsSprayTypeActive
- getIsWorkAreaActive
- getIsWorkModeChangeAllowed
- initSpecialization
- loadMovingToolFromXML
- loadSprayTypeFromXML
- onDeactivate
- onDelete
- onDraw
- onFoldStateChanged
- onLoad
- onPostLoad
- onReadStream
- onReadUpdateStream
- onRegisterActionEvents
- onSetLowered
- onTurnedOff
- onTurnedOn
- onUpdate
- onUpdateTick
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- registerWorkModeXMLPaths
- saveToXMLFile
- setWorkMode
actionEventWorkModeChange
DescriptionDefinitionactionEventWorkModeChange()Code
965 | function WorkMode.actionEventWorkModeChange(self, actionName, inputValue, callbackState, isAnalog) |
966 | local spec = self.spec_workMode |
967 | local state = spec.state + 1 |
968 | if state > spec.stateMax then |
969 | state = 1 |
970 | end |
971 | |
972 | if state ~= spec.state then |
973 | self:setWorkMode(state) |
974 | end |
975 | end |
actionEventWorkModeChangeDirect
DescriptionDefinitionactionEventWorkModeChangeDirect()Code
979 | function WorkMode.actionEventWorkModeChangeDirect(self, actionName, inputValue, callbackState, isAnalog) |
980 | local spec = self.spec_workMode |
981 | |
982 | for state, mode in ipairs(spec.workModes) do |
983 | if mode.inputAction == InputAction[actionName] then |
984 | if state ~= spec.state then |
985 | self:setWorkMode(state) |
986 | end |
987 | end |
988 | end |
989 | end |
deactivateWindrowerEffects
DescriptionCalled on deactivateDefinition
deactivateWindrowerEffects()Code
579 | function WorkMode:deactivateWindrowerEffects() |
580 | if self.isClient then |
581 | local spec = self.spec_workMode |
582 | for _, mode in pairs(spec.workModes) do |
583 | if mode.windrowerEffects ~= nil then |
584 | g_effectManager:stopEffects(mode.windrowerEffects) |
585 | end |
586 | end |
587 | end |
588 | end |
getAllowsLowering
DescriptionDefinitiongetAllowsLowering()Code
725 | function WorkMode:getAllowsLowering(superFunc) |
726 | local allowLowering, warning = superFunc(self) |
727 | |
728 | local spec = self.spec_workMode |
729 | local hasLoweringAnimations = false |
730 | if #spec.workModes > 0 then |
731 | hasLoweringAnimations = #spec.workModes[spec.state].loweringAnimations > 0 |
732 | end |
733 | |
734 | return allowLowering or hasLoweringAnimations, warning |
735 | end |
getAreEffectsVisible
DescriptionDefinitiongetAreEffectsVisible()Code
790 | function WorkMode:getAreEffectsVisible(superFunc) |
791 | if not superFunc(self) then |
792 | return false |
793 | end |
794 | |
795 | local spec = self.spec_workMode |
796 | if spec.stateMax > 0 then |
797 | for i=1, #spec.workModes do |
798 | local workMode = spec.workModes[i] |
799 | |
800 | for j=1, #workMode.animations do |
801 | if self:getIsAnimationPlaying(workMode.animations[j].animName) then |
802 | return false |
803 | end |
804 | end |
805 | end |
806 | end |
807 | |
808 | return true |
809 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
719 | function WorkMode:getCanBeSelected(superFunc) |
720 | return true |
721 | end |
getIsMovingToolActive
DescriptionDefinitiongetIsMovingToolActive()Code
771 | function WorkMode:getIsMovingToolActive(superFunc, movingTool) |
772 | if not movingTool.allowWhileChangingWorkMode then |
773 | local spec = self.spec_workMode |
774 | for i=1, #spec.workModes do |
775 | local workMode = spec.workModes[i] |
776 | |
777 | for j=1, #workMode.animations do |
778 | if self:getIsAnimationPlaying(workMode.animations[j].animName) then |
779 | return false |
780 | end |
781 | end |
782 | end |
783 | end |
784 | |
785 | return superFunc(self, movingTool) |
786 | end |
getIsSprayTypeActive
DescriptionDefinitiongetIsSprayTypeActive()Code
747 | function WorkMode:getIsSprayTypeActive(superFunc, sprayType) |
748 | if sprayType.workModeIndex ~= nil then |
749 | if self.spec_workMode.state ~= sprayType.workModeIndex then |
750 | return false |
751 | end |
752 | end |
753 | |
754 | return superFunc(self, sprayType) |
755 | end |
getIsWorkAreaActive
DescriptionDefinitiongetIsWorkAreaActive()Code
700 | function WorkMode:getIsWorkAreaActive(superFunc, workArea) |
701 | local spec = self.spec_workMode |
702 | if spec.stateMax == 0 then |
703 | return superFunc(self, workArea) |
704 | end |
705 | |
706 | for _, workArea2 in pairs(spec.workModes[spec.state].workAreas) do |
707 | if workArea.index == workArea2.workAreaIndex then |
708 | if workArea2.dropAreaIndex == 0 then |
709 | return false |
710 | end |
711 | end |
712 | end |
713 | |
714 | return superFunc(self, workArea) |
715 | end |
getIsWorkModeChangeAllowed
DescriptionReturns if work mode change is allowedDefinition
getIsWorkModeChangeAllowed()Return Values
boolean | isAllowed | is allowed |
814 | function WorkMode:getIsWorkModeChangeAllowed() |
815 | local spec = self.spec_workMode |
816 | |
817 | if self.getFoldAnimTime ~= nil then |
818 | if self:getFoldAnimTime() > spec.foldMaxLimit or self:getFoldAnimTime() < spec.foldMinLimit then |
819 | return false |
820 | end |
821 | end |
822 | |
823 | if not spec.allowChangeOnLowered then |
824 | local attacherVehicle = self:getAttacherVehicle() |
825 | if attacherVehicle ~= nil then |
826 | local index = attacherVehicle:getAttacherJointIndexFromObject(self) |
827 | local attacherJoint = attacherVehicle:getAttacherJointByJointDescIndex(index) |
828 | |
829 | if attacherJoint.moveDown then |
830 | return false |
831 | end |
832 | end |
833 | end |
834 | |
835 | return true |
836 | end |
initSpecialization
DescriptionCalled on specialization initializingDefinition
initSpecialization()Code
28 | function WorkMode.initSpecialization() |
29 | g_configurationManager:addConfigurationType("workMode", g_i18n:getText("configuration_workMode"), "workModes", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION) |
30 | |
31 | local schema = Vehicle.xmlSchema |
32 | schema:setXMLSpecializationType("WorkMode") |
33 | |
34 | WorkMode.registerWorkModeXMLPaths(schema, "vehicle.workModes") |
35 | WorkMode.registerWorkModeXMLPaths(schema, "vehicle.workModes.workModeConfigurations.workModeConfiguration(?)") |
36 | |
37 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.workModes.workModeConfigurations.workModeConfiguration(?)") |
38 | |
39 | schema:setXMLSpecializationType() |
40 | |
41 | local schemaSavegame = Vehicle.xmlSchemaSavegame |
42 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).workMode#state", "Current work mode", 1) |
43 | end |
loadMovingToolFromXML
DescriptionDefinitionloadMovingToolFromXML()Code
759 | function WorkMode:loadMovingToolFromXML(superFunc, xmlFile, key, entry) |
760 | if not superFunc(self, xmlFile, key, entry) then |
761 | return false |
762 | end |
763 | |
764 | entry.allowWhileChangingWorkMode = self.xmlFile:getValue(key.. "#allowWhileChangingWorkMode", true) |
765 | |
766 | return true |
767 | end |
loadSprayTypeFromXML
DescriptionDefinitionloadSprayTypeFromXML()Code
739 | function WorkMode:loadSprayTypeFromXML(superFunc, xmlFile, key, sprayType) |
740 | sprayType.workModeIndex = self.xmlFile:getValue(key.. "#workModeIndex") |
741 | |
742 | return superFunc(self, xmlFile, key, sprayType) |
743 | end |
onDeactivate
DescriptionCalled on deactivateDefinition
onDeactivate()Code
573 | function WorkMode:onDeactivate() |
574 | WorkMode.deactivateWindrowerEffects(self) |
575 | end |
onDelete
DescriptionDefinitiononDelete()Code
329 | function WorkMode:onDelete() |
330 | local spec = self.spec_workMode |
331 | if spec.workModes ~= nil then |
332 | for _, mode in ipairs(spec.workModes) do |
333 | g_effectManager:deleteEffects(mode.windrowerEffects) |
334 | g_animationManager:deleteAnimations(mode.animationNodes) |
335 | end |
336 | end |
337 | 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 |
545 | function WorkMode:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
546 | local spec = self.spec_workMode |
547 | if spec.stateMax == 0 then |
548 | return |
549 | else |
550 | local mode = spec.workModes[spec.state] |
551 | g_currentMission:addExtraPrintText(string.format(g_i18n:getText("action_workModeSelected"), mode.name)) |
552 | |
553 | local allowWorkModeChange = self:getIsWorkModeChangeAllowed() |
554 | |
555 | local actionEvent = spec.actionEvents[InputAction.TOGGLE_WORKMODE] |
556 | if actionEvent ~= nil then |
557 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, allowWorkModeChange) |
558 | end |
559 | |
560 | for _, workMode in ipairs(spec.workModes) do |
561 | if workMode.inputAction ~= nil then |
562 | actionEvent = spec.actionEvents[workMode.inputAction] |
563 | if actionEvent ~= nil then |
564 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, allowWorkModeChange) |
565 | end |
566 | end |
567 | end |
568 | end |
569 | end |
onFoldStateChanged
DescriptionCalled on fold state changeDefinition
onFoldStateChanged(integer direction)Arguments
integer | direction | direction of folding |
913 | function WorkMode:onFoldStateChanged(direction, moveToMiddle) |
914 | local spec = self.spec_workMode |
915 | if spec.stateMax == 0 then |
916 | return |
917 | end |
918 | |
919 | if direction > 0 then |
920 | local mode = spec.workModes[spec.state] |
921 | |
922 | for _, anim in pairs(mode.animations) do |
923 | if anim.repeatAfterUnfolding then |
924 | anim.repeated = false |
925 | end |
926 | end |
927 | |
928 | -- if the tool is still lowered while folding we lift it |
929 | if self:getIsLowered() then |
930 | if self.getAttacherVehicle ~= nil then |
931 | local attacherVehicle = self:getAttacherVehicle() |
932 | if attacherVehicle ~= nil then |
933 | attacherVehicle:handleLowerImplementEvent() |
934 | end |
935 | end |
936 | end |
937 | end |
938 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
129 | function WorkMode:onLoad(savegame) |
130 | local spec = self.spec_workMode |
131 | |
132 | local baseKey = "vehicle.workModes" |
133 | local configurationId = Utils.getNoNil(self.configurations["workMode"], 1) |
134 | local configKey = string.format(baseKey .. ".workModeConfigurations.workModeConfiguration(%d)", configurationId -1) |
135 | ObjectChangeUtil.updateObjectChanges(self.xmlFile, baseKey .. ".workModeConfigurations.workModeConfiguration", configurationId , self.components, self) |
136 | |
137 | if not self.xmlFile:hasProperty(configKey) then |
138 | configKey = baseKey |
139 | end |
140 | |
141 | spec.state = 1 |
142 | spec.stateMax = 0 |
143 | |
144 | spec.foldMaxLimit = self.xmlFile:getValue(configKey .. "#foldMaxLimit", 1) |
145 | spec.foldMinLimit = self.xmlFile:getValue(configKey .. "#foldMinLimit", 0) |
146 | spec.allowChangeOnLowered = self.xmlFile:getValue(configKey .. "#allowChangeOnLowered", true) |
147 | spec.allowChangeWhileTurnedOn = self.xmlFile:getValue(configKey .. "#allowChangeWhileTurnedOn", true) |
148 | |
149 | spec.workModes = {} |
150 | local i = 0 |
151 | while true do |
152 | local key = string.format("%s.workMode(%d)", configKey, i) |
153 | if not self.xmlFile:hasProperty(key) then |
154 | break |
155 | end |
156 | |
157 | local entry = {} |
158 | entry.name = self.xmlFile:getValue(key .. "#name", nil, self.customEnvironment) |
159 | local inputBindingName = self.xmlFile:getValue(key .. "#inputBindingName") |
160 | if inputBindingName ~= nil then |
161 | if InputAction[inputBindingName] ~= nil then |
162 | entry.inputAction = InputAction[inputBindingName] |
163 | end |
164 | end |
165 | |
166 | entry.turnedOnAnimations = {} |
167 | local j = 0 |
168 | while true do |
169 | local key2 = string.format("%s.turnedOnAnimations.turnedOnAnimation(%d)", key, j) |
170 | if not self.xmlFile:hasProperty(key2) then |
171 | break |
172 | end |
173 | |
174 | local turnedOnAnimation = {} |
175 | turnedOnAnimation.name = self.xmlFile:getValue(key2.."#name") |
176 | turnedOnAnimation.turnOnFadeTime = self.xmlFile:getValue(key2.."#turnOnFadeTime", 1) * 1000 |
177 | turnedOnAnimation.turnOffFadeTime = self.xmlFile:getValue(key2.."#turnOffFadeTime", 1) * 1000 |
178 | turnedOnAnimation.speedScale = self.xmlFile:getValue(key2.."#speedScale", 1) |
179 | |
180 | turnedOnAnimation.speedDirection = 0 |
181 | turnedOnAnimation.currentSpeed = 0 |
182 | |
183 | if self:getAnimationExists(turnedOnAnimation.name) then |
184 | table.insert(entry.turnedOnAnimations, turnedOnAnimation) |
185 | end |
186 | |
187 | j = j + 1 |
188 | end |
189 | |
190 | entry.loweringAnimations = {} |
191 | j = 0 |
192 | while true do |
193 | local key2 = string.format("%s.loweringAnimations.loweringAnimation(%d)", key, j) |
194 | if not self.xmlFile:hasProperty(key2) then |
195 | break |
196 | end |
197 | |
198 | local loweringAnimation = {} |
199 | loweringAnimation.name = self.xmlFile:getValue(key2.."#name") |
200 | loweringAnimation.speed = self.xmlFile:getValue(key2.."#speed", 1) |
201 | |
202 | if self:getAnimationExists(loweringAnimation.name) then |
203 | table.insert(entry.loweringAnimations, loweringAnimation) |
204 | end |
205 | |
206 | j = j + 1 |
207 | end |
208 | |
209 | entry.workAreas = {} |
210 | j = 0 |
211 | while true do |
212 | local key2 = string.format("%s.workAreas.workArea(%d)", key, j) |
213 | if not self.xmlFile:hasProperty(key2) then |
214 | break |
215 | end |
216 | |
217 | local workArea = {} |
218 | workArea.workAreaIndex = self.xmlFile:getValue(key2.."#workAreaIndex", j+1) |
219 | workArea.dropAreaIndex = self.xmlFile:getValue(key2.."#dropAreaIndex", j+1) |
220 | |
221 | table.insert(entry.workAreas, workArea) |
222 | |
223 | j = j + 1 |
224 | end |
225 | |
226 | entry.animations = {} |
227 | j = 0 |
228 | while true do |
229 | local animKey = string.format("%s.animation(%d)", key, j) |
230 | if not self.xmlFile:hasProperty(animKey) then |
231 | break |
232 | end |
233 | |
234 | local animation = {} |
235 | animation.animName = self.xmlFile:getValue(animKey .. "#name") |
236 | animation.animSpeed = self.xmlFile:getValue(animKey .. "#speed", 1.0) |
237 | animation.stopTime = self.xmlFile:getValue(animKey .. "#stopTime") |
238 | animation.repeatAfterUnfolding = self.xmlFile:getValue(animKey .. "#repeatAfterUnfolding", false) |
239 | animation.repeatStartTime = self.xmlFile:getValue(animKey .. "#repeatStartTime") |
240 | animation.repeated = false |
241 | |
242 | if self:getAnimationExists(animation.animName) then |
243 | table.insert(entry.animations, animation) |
244 | end |
245 | |
246 | j = j + 1 |
247 | end |
248 | |
249 | local movingToolLimitNode = self.xmlFile:getValue(key .. ".movingToolLimit#node", nil, self.components, self.i3dMappings) |
250 | if movingToolLimitNode ~= nil then |
251 | entry.movingTool = self:getMovingToolByNode(movingToolLimitNode) |
252 | entry.movingToolMinRot = self.xmlFile:getValue(key .. ".movingToolLimit#minRot", 0) |
253 | entry.movingToolMaxRot = self.xmlFile:getValue(key .. ".movingToolLimit#maxRot", 0) |
254 | end |
255 | |
256 | entry.windrowerEffects = g_effectManager:loadEffect(self.xmlFile, string.format("%s.windrowerEffect", key), self.components, self, self.i3dMappings) |
257 | entry.animationNodes = g_animationManager:loadAnimations(self.xmlFile, key..".animationNodes", self.components, self, self.i3dMappings) |
258 | |
259 | table.insert(spec.workModes, entry) |
260 | i = i + 1 |
261 | end |
262 | |
263 | spec.stateMax = table.getn(spec.workModes) |
264 | if spec.stateMax > ((2^WorkMode.WORKMODE_SEND_NUM_BITS) - 1) then |
265 | print("Error: WorkMode only supports "..((2^WorkMode.WORKMODE_SEND_NUM_BITS) - 1).." modes!") |
266 | end |
267 | |
268 | if spec.stateMax > 0 then |
269 | self:setWorkMode(1, true) |
270 | end |
271 | |
272 | spec.accumulatedFruitType = FruitType.UNKNOWN |
273 | spec.dirtyFlag = self:getNextDirtyFlag() |
274 | |
275 | if spec.stateMax == 0 then |
276 | SpecializationUtil.removeEventListener(self, "onReadStream", WorkMode) |
277 | SpecializationUtil.removeEventListener(self, "onWriteStream", WorkMode) |
278 | SpecializationUtil.removeEventListener(self, "onReadUpdateStream", WorkMode) |
279 | SpecializationUtil.removeEventListener(self, "onWriteUpdateStream", WorkMode) |
280 | SpecializationUtil.removeEventListener(self, "onUpdate", WorkMode) |
281 | SpecializationUtil.removeEventListener(self, "onUpdateTick", WorkMode) |
282 | SpecializationUtil.removeEventListener(self, "onDraw", WorkMode) |
283 | SpecializationUtil.removeEventListener(self, "onTurnedOn", WorkMode) |
284 | SpecializationUtil.removeEventListener(self, "onTurnedOff", WorkMode) |
285 | SpecializationUtil.removeEventListener(self, "onDeactivate", WorkMode) |
286 | SpecializationUtil.removeEventListener(self, "onSetLowered", WorkMode) |
287 | SpecializationUtil.removeEventListener(self, "onFoldStateChanged", WorkMode) |
288 | SpecializationUtil.removeEventListener(self, "onRegisterActionEvents", WorkMode) |
289 | end |
290 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
294 | function WorkMode:onPostLoad(savegame) |
295 | if savegame ~= nil and not savegame.resetVehicles then |
296 | local spec = self.spec_workMode |
297 | if spec.stateMax > 0 then |
298 | if savegame.xmlFile:hasProperty(savegame.key..".workMode#state") then |
299 | local workMode = savegame.xmlFile:getValue(savegame.key..".workMode#state", 1) |
300 | workMode = MathUtil.clamp(workMode, 1, spec.stateMax) |
301 | |
302 | self:setWorkMode(workMode, true) |
303 | AnimatedVehicle.updateAnimations(self, 99999999, true) |
304 | |
305 | if self.getFoldAnimTime ~= nil then |
306 | if self.spec_foldable.foldMoveDirection == 0 then |
307 | if self:getFoldAnimTime() <= 0 then |
308 | self.spec_foldable.foldMoveDirection = -1 |
309 | else |
310 | self.spec_foldable.foldMoveDirection = 1 |
311 | end |
312 | end |
313 | end |
314 | end |
315 | end |
316 | end |
317 | end |
onReadStream
DescriptionCalled on client side on joinDefinition
onReadStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
343 | function WorkMode:onReadStream(streamId, connection) |
344 | local spec = self.spec_workMode |
345 | if spec.stateMax == 0 then |
346 | return |
347 | end |
348 | |
349 | local state = streamReadUIntN(streamId, WorkMode.WORKMODE_SEND_NUM_BITS) |
350 | self:setWorkMode(state, true) |
351 | end |
onReadUpdateStream
DescriptionCalled on on updateDefinition
onReadUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
371 | function WorkMode:onReadUpdateStream(streamId, timestamp, connection) |
372 | if connection:getIsServer() then |
373 | if streamReadBool(streamId) then |
374 | local spec = self.spec_workMode |
375 | |
376 | local mode = spec.workModes[spec.state] |
377 | for _, effect in ipairs(mode.windrowerEffects) do |
378 | if streamReadBool(streamId) then |
379 | effect.lastChargeTime = g_currentMission.time |
380 | end |
381 | end |
382 | |
383 | spec.accumulatedFruitType = streamReadUIntN(streamId, FruitTypeManager.SEND_NUM_BITS) |
384 | end |
385 | end |
386 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
942 | function WorkMode:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
943 | if self.isClient then |
944 | local spec = self.spec_workMode |
945 | if spec.stateMax > 0 then |
946 | self:clearActionEventsTable(spec.actionEvents) |
947 | |
948 | if isActiveForInputIgnoreSelection then |
949 | local _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.TOGGLE_WORKMODE, self, WorkMode.actionEventWorkModeChange, false, true, false, true, nil) |
950 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL) |
951 | |
952 | for _, mode in ipairs(spec.workModes) do |
953 | if mode.inputAction ~= nil then |
954 | _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, mode.inputAction, self, WorkMode.actionEventWorkModeChangeDirect, false, true, false, true, nil) |
955 | g_inputBinding:setActionEventTextVisibility(actionEventId, false) |
956 | end |
957 | end |
958 | end |
959 | end |
960 | end |
961 | end |
onSetLowered
DescriptionCalled on change lowering stateDefinition
onSetLowered(boolean lowered)Arguments
boolean | lowered | attachable is lowered |
881 | function WorkMode:onSetLowered(lowered) |
882 | local spec = self.spec_workMode |
883 | if spec.stateMax == 0 then |
884 | return |
885 | end |
886 | |
887 | if self.getFoldAnimTime ~= nil then |
888 | local foldAnimTime = self:getFoldAnimTime() |
889 | if foldAnimTime ~= 1 and foldAnimTime ~= 0 and foldAnimTime ~= self.foldMiddleAnimTime then |
890 | spec.playDelayedLoweringAnimation = lowered |
891 | return |
892 | end |
893 | end |
894 | |
895 | local mode = spec.workModes[spec.state] |
896 | |
897 | for _, loweringAnimation in pairs(mode.loweringAnimations) do |
898 | if lowered then |
899 | if self:getAnimationTime(loweringAnimation.name) < 1 then |
900 | self:playAnimation(loweringAnimation.name, loweringAnimation.speed, nil, true) |
901 | end |
902 | else |
903 | if self:getAnimationTime(loweringAnimation.name) > 0 then |
904 | self:playAnimation(loweringAnimation.name, -loweringAnimation.speed, nil, true) |
905 | end |
906 | end |
907 | end |
908 | end |
onTurnedOff
DescriptionCalled on turn offDefinition
onTurnedOff(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
841 | function WorkMode:onTurnedOff() |
842 | local spec = self.spec_workMode |
843 | if spec.stateMax == 0 then |
844 | return |
845 | end |
846 | |
847 | if self.isClient then |
848 | WorkMode.deactivateWindrowerEffects(self) |
849 | local mode = spec.workModes[spec.state] |
850 | |
851 | for _, turnedOnAnimation in pairs(mode.turnedOnAnimations) do |
852 | turnedOnAnimation.speedDirection = -1 |
853 | end |
854 | g_animationManager:stopAnimations(mode.animationNodes) |
855 | end |
856 | end |
onTurnedOn
DescriptionCalled on turn onDefinition
onTurnedOn(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
861 | function WorkMode:onTurnedOn() |
862 | local spec = self.spec_workMode |
863 | if spec.stateMax == 0 then |
864 | return |
865 | end |
866 | |
867 | if self.isClient then |
868 | local mode = spec.workModes[spec.state] |
869 | |
870 | for _, turnedOnAnimation in pairs(mode.turnedOnAnimations) do |
871 | turnedOnAnimation.speedDirection = 1 |
872 | end |
873 | |
874 | g_animationManager:startAnimations(mode.animationNodes) |
875 | end |
876 | end |
onUpdate
DescriptionCalled on updateDefinition
onUpdate(float dt)Arguments
float | dt | time since last call in ms |
411 | function WorkMode:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
412 | local spec = self.spec_workMode |
413 | if spec.stateMax == 0 then |
414 | return |
415 | end |
416 | |
417 | if self.isClient then |
418 | local mode = spec.workModes[spec.state] |
419 | |
420 | for i=1, #spec.workModes do |
421 | for _, turnedOnAnimation in pairs(spec.workModes[i].turnedOnAnimations) do |
422 | if turnedOnAnimation.speedDirection ~= 0 then |
423 | local duration = turnedOnAnimation.turnOnFadeTime |
424 | if turnedOnAnimation.speedDirection == -1 then |
425 | duration = turnedOnAnimation.turnOffFadeTime |
426 | end |
427 | local min, max = 0, 1 |
428 | if turnedOnAnimation.speedDirection == 1 then |
429 | min, max = -1, 1 |
430 | end |
431 | |
432 | turnedOnAnimation.currentSpeed = MathUtil.clamp(turnedOnAnimation.currentSpeed + turnedOnAnimation.speedDirection * dt/duration, min, max) |
433 | |
434 | if not self:getIsAnimationPlaying(turnedOnAnimation.name) then |
435 | self:playAnimation(turnedOnAnimation.name, turnedOnAnimation.currentSpeed*turnedOnAnimation.speedScale, self:getAnimationTime(turnedOnAnimation.name), true) |
436 | else |
437 | self:setAnimationSpeed(turnedOnAnimation.name, turnedOnAnimation.currentSpeed*turnedOnAnimation.speedScale) |
438 | end |
439 | |
440 | if turnedOnAnimation.speedDirection == -1 and turnedOnAnimation.currentSpeed == 0 then |
441 | self:stopAnimation(turnedOnAnimation.name, true) |
442 | end |
443 | |
444 | if turnedOnAnimation.currentSpeed == 1 or turnedOnAnimation.currentSpeed == 0 then |
445 | turnedOnAnimation.speedDirection = 0 |
446 | end |
447 | end |
448 | end |
449 | end |
450 | |
451 | for _, effect in pairs(mode.windrowerEffects) do |
452 | if effect.lastChargeTime + 500 > g_currentMission.time then |
453 | local fillType = g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(spec.accumulatedFruitType) |
454 | if fillType ~= nil then |
455 | effect:setFillType(fillType) |
456 | if not effect:isRunning() then |
457 | g_effectManager:startEffect(effect) |
458 | end |
459 | end |
460 | else |
461 | if effect.turnOffRequiredEffect == 0 or (effect.turnOffRequiredEffect ~= 0 and not mode.windrowerEffects[effect.turnOffRequiredEffect]:isRunning()) then |
462 | g_effectManager:stopEffect(effect) |
463 | end |
464 | end |
465 | end |
466 | end |
467 | |
468 | if self.isServer then |
469 | local mode = spec.workModes[spec.state] |
470 | |
471 | local fruitType |
472 | local workAreaCharge |
473 | for _, area in ipairs(mode.workAreas) do |
474 | local workArea = self.spec_workArea.workAreas[area.workAreaIndex] |
475 | if workArea ~= nil then |
476 | if workArea.lastValidPickupFruitType ~= FruitType.UNKNOWN then |
477 | fruitType = workArea.lastValidPickupFruitType |
478 | end |
479 | workAreaCharge = workAreaCharge or workArea.lastPickupLiters ~= 0 |
480 | end |
481 | end |
482 | |
483 | if fruitType ~= nil then |
484 | if fruitType ~= spec.accumulatedFruitType then |
485 | spec.accumulatedFruitType = fruitType |
486 | self:raiseDirtyFlags(spec.dirtyFlag) |
487 | end |
488 | end |
489 | |
490 | for _, effect in pairs(mode.windrowerEffects) do |
491 | if workAreaCharge then |
492 | effect.lastChargeTime = g_currentMission.time |
493 | self:raiseDirtyFlags(spec.dirtyFlag) |
494 | end |
495 | end |
496 | end |
497 | end |
onUpdateTick
DescriptionDefinitiononUpdateTick()Code
501 | function WorkMode:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
502 | local spec = self.spec_workMode |
503 | if spec.stateMax == 0 then |
504 | return |
505 | end |
506 | |
507 | if self.getFoldAnimTime ~= nil then |
508 | local foldAnimTime = self:getFoldAnimTime() |
509 | if foldAnimTime == 0 or foldAnimTime == self.spec_foldable.foldMiddleAnimTime then |
510 | local mode = spec.workModes[spec.state] |
511 | for _, anim in pairs(mode.animations) do |
512 | if anim.repeatAfterUnfolding then |
513 | if not anim.repeated then |
514 | local curTime = self:getAnimationTime(anim.animName) |
515 | if anim.stopTime ~= nil then |
516 | self:setAnimationStopTime(anim.animName, anim.stopTime) |
517 | local speed = math.abs(anim.animSpeed) |
518 | if curTime > anim.stopTime then |
519 | speed = -math.abs(anim.animSpeed) |
520 | end |
521 | self:playAnimation(anim.animName, speed, Utils.getNoNil(anim.repeatStartTime, curTime), true) |
522 | else |
523 | self:playAnimation(anim.animName, anim.animSpeed, Utils.getNoNil(anim.repeatStartTime, curTime), true) |
524 | end |
525 | |
526 | anim.repeated = true |
527 | end |
528 | end |
529 | end |
530 | end |
531 | |
532 | if spec.playDelayedLoweringAnimation ~= nil then |
533 | if foldAnimTime == 1 or foldAnimTime == 0 or foldAnimTime == self.spec_foldable.foldMiddleAnimTime then |
534 | WorkMode.onSetLowered(self, spec.playDelayedLoweringAnimation) |
535 | spec.playDelayedLoweringAnimation = nil |
536 | end |
537 | end |
538 | end |
539 | end |
onWriteStream
DescriptionCalled on server side on joinDefinition
onWriteStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
357 | function WorkMode:onWriteStream(streamId, connection) |
358 | local spec = self.spec_workMode |
359 | if spec.stateMax == 0 then |
360 | return |
361 | end |
362 | |
363 | streamWriteUIntN(streamId, spec.state, WorkMode.WORKMODE_SEND_NUM_BITS) |
364 | 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 |
393 | function WorkMode:onWriteUpdateStream(streamId, connection, dirtyMask) |
394 | if not connection:getIsServer() then |
395 | local spec = self.spec_workMode |
396 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
397 | local mode = spec.workModes[spec.state] |
398 | |
399 | for _, effect in ipairs(mode.windrowerEffects) do |
400 | streamWriteBool(streamId, effect.lastChargeTime + 500 > g_currentMission.time) |
401 | end |
402 | |
403 | streamWriteUIntN(streamId, spec.accumulatedFruitType, FruitTypeManager.SEND_NUM_BITS) |
404 | end |
405 | end |
406 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
21 | function WorkMode.prerequisitesPresent(specializations) |
22 | return SpecializationUtil.hasSpecialization(WorkArea, specializations) |
23 | and SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations) |
24 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
107 | function WorkMode.registerEventListeners(vehicleType) |
108 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", WorkMode) |
109 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", WorkMode) |
110 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", WorkMode) |
111 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", WorkMode) |
112 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", WorkMode) |
113 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", WorkMode) |
114 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", WorkMode) |
115 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", WorkMode) |
116 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", WorkMode) |
117 | SpecializationUtil.registerEventListener(vehicleType, "onDraw", WorkMode) |
118 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", WorkMode) |
119 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", WorkMode) |
120 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", WorkMode) |
121 | SpecializationUtil.registerEventListener(vehicleType, "onSetLowered", WorkMode) |
122 | SpecializationUtil.registerEventListener(vehicleType, "onFoldStateChanged", WorkMode) |
123 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", WorkMode) |
124 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
86 | function WorkMode.registerFunctions(vehicleType) |
87 | SpecializationUtil.registerFunction(vehicleType, "setWorkMode", WorkMode.setWorkMode) |
88 | SpecializationUtil.registerFunction(vehicleType, "getIsWorkModeChangeAllowed", WorkMode.getIsWorkModeChangeAllowed) |
89 | SpecializationUtil.registerFunction(vehicleType, "deactivateWindrowerEffects", WorkMode.deactivateWindrowerEffects) |
90 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
94 | function WorkMode.registerOverwrittenFunctions(vehicleType) |
95 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", WorkMode.getIsWorkAreaActive) |
96 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", WorkMode.getCanBeSelected) |
97 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowsLowering", WorkMode.getAllowsLowering) |
98 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSprayTypeFromXML", WorkMode.loadSprayTypeFromXML) |
99 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSprayTypeActive", WorkMode.getIsSprayTypeActive) |
100 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadMovingToolFromXML", WorkMode.loadMovingToolFromXML) |
101 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsMovingToolActive", WorkMode.getIsMovingToolActive) |
102 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAreEffectsVisible", WorkMode.getAreEffectsVisible) |
103 | end |
registerWorkModeXMLPaths
DescriptionCalled on specialization initializingDefinition
registerWorkModeXMLPaths()Code
48 | function WorkMode.registerWorkModeXMLPaths(schema, basePath) |
49 | schema:register(XMLValueType.FLOAT, basePath .. "#foldMaxLimit", "Fold max. limit to change mode", 1) |
50 | schema:register(XMLValueType.FLOAT, basePath .. "#foldMinLimit", "Fold min. limit to change mode", 0) |
51 | schema:register(XMLValueType.BOOL, basePath .. "#allowChangeOnLowered", "Allow change while lowered", true) |
52 | schema:register(XMLValueType.BOOL, basePath .. "#allowChangeWhileTurnedOn", "Allow change while turned on", true) |
53 | |
54 | schema:register(XMLValueType.L10N_STRING, basePath .. ".workMode(?)#name", "Work mode name") |
55 | schema:register(XMLValueType.STRING, basePath .. ".workMode(?)#inputBindingName", "Input action name for quick access") |
56 | schema:register(XMLValueType.STRING, basePath .. ".workMode(?).turnedOnAnimations.turnedOnAnimation(?)#name", "Turned on animation name") |
57 | schema:register(XMLValueType.FLOAT, basePath .. ".workMode(?).turnedOnAnimations.turnedOnAnimation(?)#turnOnFadeTime", "Turn on fade time (sec.)", 1) |
58 | schema:register(XMLValueType.FLOAT, basePath .. ".workMode(?).turnedOnAnimations.turnedOnAnimation(?)#turnOffFadeTime", "Turn off fade time (sec.)", 1) |
59 | schema:register(XMLValueType.FLOAT, basePath .. ".workMode(?).turnedOnAnimations.turnedOnAnimation(?)#speedScale", "Speed scale", 1) |
60 | |
61 | schema:register(XMLValueType.STRING, basePath .. ".workMode(?).loweringAnimations.loweringAnimation(?)#name", "Lowering animation name") |
62 | schema:register(XMLValueType.FLOAT, basePath .. ".workMode(?).loweringAnimations.loweringAnimation(?)#speed", "Speed scale", 1) |
63 | |
64 | schema:register(XMLValueType.INT, basePath .. ".workMode(?).workAreas.workArea(?)#workAreaIndex", "Work area index") |
65 | schema:register(XMLValueType.INT, basePath .. ".workMode(?).workAreas.workArea(?)#dropAreaIndex", "Drop area index") |
66 | |
67 | schema:register(XMLValueType.STRING, basePath .. ".workMode(?).animation(?)#name", "Mode change animation name") |
68 | schema:register(XMLValueType.FLOAT, basePath .. ".workMode(?).animation(?)#speed", "Mode change animation speed", 1) |
69 | schema:register(XMLValueType.FLOAT, basePath .. ".workMode(?).animation(?)#stopTime", "Mode change animation stop time") |
70 | schema:register(XMLValueType.BOOL, basePath .. ".workMode(?).animation(?)#repeatAfterUnfolding", "Repeat animation after unfolding", false) |
71 | schema:register(XMLValueType.FLOAT, basePath .. ".workMode(?).animation(?)#repeatStartTime", "Repeat start time") |
72 | |
73 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".workMode(?).movingToolLimit#node", "Target moving tool node") |
74 | schema:register(XMLValueType.ANGLE, basePath .. ".workMode(?).movingToolLimit#minRot", "Min. rotation", 0) |
75 | schema:register(XMLValueType.ANGLE, basePath .. ".workMode(?).movingToolLimit#maxRot", "Max. rotation", 0) |
76 | |
77 | EffectManager.registerEffectXMLPaths(schema, basePath .. ".workMode(?).windrowerEffect") |
78 | AnimationManager.registerAnimationNodesXMLPaths(schema, basePath .. ".workMode(?).animationNodes") |
79 | |
80 | schema:register(XMLValueType.INT, Sprayer.SPRAY_TYPE_XML_KEY .. "#workModeIndex", "Index of work mode to activate spray type") |
81 | schema:register(XMLValueType.BOOL, Cylindered.MOVING_TOOL_XML_KEY .. "#allowWhileChangingWorkMode", "Allow movement while changing work mode", true) |
82 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
321 | function WorkMode:saveToXMLFile(xmlFile, key, usedModNames) |
322 | local spec = self.spec_workMode |
323 | |
324 | xmlFile:setValue(key.."#state", spec.state) |
325 | end |
setWorkMode
DescriptionChange work modeDefinition
setWorkMode(integer state, boolean noEventSend)Arguments
integer | state | new state |
boolean | noEventSend | no event send |
594 | function WorkMode:setWorkMode(state, noEventSend) |
595 | local spec = self.spec_workMode |
596 | |
597 | if noEventSend == nil or noEventSend == false then |
598 | if g_server ~= nil then |
599 | g_server:broadcastEvent(SetWorkModeEvent.new(self, state), nil, nil, self) |
600 | else |
601 | g_client:getServerConnection():sendEvent(SetWorkModeEvent.new(self, state)) |
602 | end |
603 | end |
604 | |
605 | if state ~= spec.state then |
606 | local currentMode = spec.workModes[spec.state] |
607 | if currentMode.animations ~= nil then |
608 | for _,anim in pairs(currentMode.animations) do |
609 | local curTime = self:getAnimationTime(anim.animName) |
610 | if anim.stopTime == nil then |
611 | self:playAnimation(anim.animName, -anim.animSpeed, curTime, noEventSend) |
612 | end |
613 | end |
614 | g_animationManager:stopAnimations(currentMode.animationNodes) |
615 | end |
616 | |
617 | local newMode = spec.workModes[state] |
618 | if newMode.animations ~= nil then |
619 | for _,anim in pairs(newMode.animations) do |
620 | local curTime = self:getAnimationTime(anim.animName) |
621 | if anim.stopTime ~= nil then |
622 | self:setAnimationStopTime(anim.animName, anim.stopTime) |
623 | local speed = math.abs(anim.animSpeed) |
624 | if curTime > anim.stopTime then |
625 | speed = -math.abs(anim.animSpeed) |
626 | end |
627 | self:playAnimation(anim.animName, speed, curTime, noEventSend) |
628 | else |
629 | self:playAnimation(anim.animName, anim.animSpeed, curTime, noEventSend) |
630 | end |
631 | end |
632 | if self:getIsTurnedOn() then |
633 | g_animationManager:startAnimations(newMode.animationNodes) |
634 | end |
635 | end |
636 | |
637 | if self:getIsTurnedOn() then |
638 | for _, turnedOnAnimation in pairs(newMode.turnedOnAnimations) do |
639 | if self:getIsAnimationPlaying(turnedOnAnimation.name) then |
640 | for i=1, #spec.workModes do |
641 | local otherMode = spec.workModes[i] |
642 | if otherMode ~= newMode then |
643 | for j=1, #otherMode.turnedOnAnimations do |
644 | local otherAnimation = otherMode.turnedOnAnimations[j] |
645 | if otherAnimation.name == turnedOnAnimation.name then |
646 | local animationSpeed = self.spec_animatedVehicle.animations[turnedOnAnimation.name].currentSpeed |
647 | if animationSpeed ~= 0 then |
648 | local alpha = animationSpeed / turnedOnAnimation.speedScale |
649 | turnedOnAnimation.currentSpeed = alpha |
650 | otherAnimation.currentSpeed = 0 |
651 | otherAnimation.speedDirection = 0 |
652 | end |
653 | end |
654 | end |
655 | end |
656 | end |
657 | end |
658 | |
659 | turnedOnAnimation.speedDirection = 1 |
660 | end |
661 | end |
662 | |
663 | for _, effect in pairs(currentMode.windrowerEffects) do |
664 | g_effectManager:stopEffect(effect) |
665 | end |
666 | |
667 | if newMode.movingTool ~= nil then |
668 | local movingTool = newMode.movingTool |
669 | if newMode.movingToolMinRot ~= nil then |
670 | movingTool.rotMin = newMode.movingToolMinRot |
671 | end |
672 | |
673 | if newMode.movingToolMaxRot ~= nil then |
674 | movingTool.rotMax = newMode.movingToolMaxRot |
675 | end |
676 | |
677 | if self.isClient then |
678 | movingTool.networkInterpolators.rotation:setMinMax(movingTool.rotMin, movingTool.rotMax) |
679 | end |
680 | end |
681 | end |
682 | |
683 | local workAreaSpec = self.spec_workArea |
684 | if workAreaSpec ~= nil then |
685 | local workAreas = workAreaSpec.workAreas |
686 | for _, workArea in pairs(spec.workModes[state].workAreas) do |
687 | local workAreaToSet = workAreas[workArea.workAreaIndex] |
688 | if workAreaToSet ~= nil then |
689 | workAreaToSet.dropWindrowWorkAreaIndex = workArea.dropAreaIndex -- windrower |
690 | workAreaToSet.dropAreaIndex = workArea.dropAreaIndex -- mower |
691 | end |
692 | end |
693 | end |
694 | |
695 | spec.state = state |
696 | end |