LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

Tedder

Description
Specialization for tedders providing dropAreas and fruitType conversion
Functions

doCheckSpeedLimit

Description
Definition
doCheckSpeedLimit()
Code
340function Tedder:doCheckSpeedLimit(superFunc)
341 return superFunc(self) or (self:getIsTurnedOn() and self:getIsImplementChainLowered())
342end

getDefaultSpeedLimit

Description
Definition
getDefaultSpeedLimit()
Code
504function Tedder.getDefaultSpeedLimit()
505 return 15
506end

getDirtMultiplier

Description
Definition
getDirtMultiplier()
Code
307function Tedder:getDirtMultiplier(superFunc)
308 local spec = self.spec_tedder
309
310 local multiplier = superFunc(self)
311
312 if spec.isWorking then
313 multiplier = multiplier + self:getWorkDirtMultiplier() * self:getLastSpeed() / self.speedLimit
314 end
315
316 return multiplier
317end

getWearMultiplier

Description
Definition
getWearMultiplier()
Code
321function Tedder:getWearMultiplier(superFunc)
322 local spec = self.spec_tedder
323
324 local multiplier = superFunc(self)
325
326 if spec.isWorking then
327 local stoneMultiplier = 1
328 if spec.stoneLastState ~= 0 and spec.stoneWearMultiplierData ~= nil then
329 stoneMultiplier = spec.stoneWearMultiplierData[spec.stoneLastState] or 1
330 end
331
332 multiplier = multiplier + self:getWorkWearMultiplier() * self:getLastSpeed() / self.speedLimit * stoneMultiplier
333 end
334
335 return multiplier
336end

initSpecialization

Description
Definition
initSpecialization()
Code
16function Tedder.initSpecialization()
17 g_workAreaTypeManager:addWorkAreaType("tedder", false)
18
19 local schema = Vehicle.xmlSchema
20 schema:setXMLSpecializationType("Tedder")
21
22 schema:register(XMLValueType.STRING, "vehicle.tedder#fillTypeConverter", "Fill type converter name")
23 EffectManager.registerEffectXMLPaths(schema, "vehicle.tedder.effects.effect(?)")
24 schema:register(XMLValueType.INT, "vehicle.tedder.effects.effect(?)#workAreaIndex", "Work area index", 1)
25
26 AnimationManager.registerAnimationNodesXMLPaths(schema, "vehicle.tedder.animationNodes")
27
28 schema:register(XMLValueType.INT, WorkArea.WORK_AREA_XML_KEY .. ".tedder#dropWindrowWorkAreaIndex", "Drop work area index", 1)
29 schema:register(XMLValueType.INT, WorkArea.WORK_AREA_XML_CONFIG_KEY .. ".tedder#dropWindrowWorkAreaIndex", "Drop work area index", 1)
30
31 schema:setXMLSpecializationType()
32end

loadWorkAreaFromXML

Description
Definition
loadWorkAreaFromXML()
Code
278function Tedder:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
279 local retValue = superFunc(self, workArea, xmlFile, key)
280
281 if workArea.type == WorkAreaType.DEFAULT then
282 workArea.type = WorkAreaType.TEDDER
283 end
284
285 if workArea.type == WorkAreaType.TEDDER then
286 workArea.dropWindrowWorkAreaIndex = xmlFile:getValue(key .. ".tedder#dropWindrowWorkAreaIndex", 1)
287 workArea.litersToDrop = 0
288 workArea.lastPickupLiters = 0
289 workArea.lastDropFillType = FillType.UNKNOWN
290 workArea.lastDroppedLiters = 0
291 workArea.tedderParticlesActive = false
292 workArea.tedderParticlesActiveSent = false
293
294 local spec = self.spec_tedder
295 if spec.tedderWorkAreaFillTypes == nil then
296 spec.tedderWorkAreaFillTypes = {}
297 end
298 table.insert(spec.tedderWorkAreaFillTypes, FruitType.UNKNOWN)
299 workArea.tedderWorkAreaIndex = #spec.tedderWorkAreaFillTypes
300 end
301
302 return retValue
303end

onDeactivate

Description
Definition
onDeactivate()
Code
493function Tedder:onDeactivate()
494 if self.isClient then
495 local spec = self.spec_tedder
496 for _, effect in ipairs(spec.effects) do
497 g_effectManager:stopEffects(effect.effects)
498 end
499 end
500end

onDelete

Description
Definition
onDelete()
Code
168function Tedder:onDelete()
169 local spec = self.spec_tedder
170
171 if spec.effects ~= nil then
172 for _, effect in ipairs(spec.effects) do
173 g_effectManager:deleteEffects(effect.effects)
174 end
175 end
176
177 g_animationManager:deleteAnimations(spec.animationNodes)
178end

onEndWorkAreaProcessing

Description
Definition
onEndWorkAreaProcessing()
Code
462function Tedder:onEndWorkAreaProcessing(dt, hasProcessed)
463 local spec = self.spec_tedder
464
465 spec.isWorking = spec.lastDroppedLiters > 0
466end

onLoad

Description
Definition
onLoad()
Code
77function Tedder:onLoad(savegame)
78 local spec = self.spec_tedder
79
80 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.tedder.animationNodes.animationNode", "tedder") --FS17 to FS19
81 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.tedder.sounds", "vehicle.turnOnVehicle.sounds.work") --FS17 to FS19
82
83 spec.fillTypeConverters = {}
84 spec.fillTypeConvertersReverse = {}
85 local converter = self.xmlFile:getValue("vehicle.tedder#fillTypeConverter")
86 if converter ~= nil then
87 local data = g_fillTypeManager:getConverterDataByName(converter)
88 if data ~= nil then
89 for input, converted in pairs(data) do
90 spec.fillTypeConverters[input] = converted
91
92 if spec.fillTypeConvertersReverse[converted.targetFillTypeIndex] == nil then
93 spec.fillTypeConvertersReverse[converted.targetFillTypeIndex] = {}
94 end
95 table.insert(spec.fillTypeConvertersReverse[converted.targetFillTypeIndex], input)
96 end
97 end
98 else
99 print(string.format("Warning: Missing fill type converter in '%s'", self.configFileName))
100 end
101
102 if self.isClient then
103 spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.tedder.animationNodes", self.components, self, self.i3dMappings)
104
105 spec.effects = {}
106 spec.workAreaToEffects = {}
107 local i = 0
108 while true do
109 local key = string.format("vehicle.tedder.effects.effect(%d)", i)
110 if not self.xmlFile:hasProperty(key) then
111 break
112 end
113 local effects = g_effectManager:loadEffect(self.xmlFile, key, self.components, self, self.i3dMappings)
114 if effects ~= nil then
115 local effect = {}
116 effect.effects = effects
117 effect.workAreaIndex = self.xmlFile:getValue(key .. "#workAreaIndex", 1)
118 effect.activeTime = -1
119 effect.activeTimeDuration = 250
120 effect.isActive = false
121 effect.isActiveSent = false
122 table.insert(spec.effects, effect)
123 end
124 i = i + 1
125 end
126 end
127
128 spec.lastDroppedLiters = 0
129
130 spec.stoneLastState = 0
131 spec.stoneWearMultiplierData = g_currentMission.stoneSystem:getWearMultiplierByType("TEDDER")
132
133 spec.fillTypesDirtyFlag = self:getNextDirtyFlag()
134 spec.effectDirtyFlag = self:getNextDirtyFlag()
135
136 if self.addAIDensityHeightTypeRequirement ~= nil then
137 self:addAIDensityHeightTypeRequirement(FillType.GRASS_WINDROW)
138 end
139end

onPostLoad

Description
Definition
onPostLoad()
Code
143function Tedder:onPostLoad(savegame)
144 local spec = self.spec_tedder
145 for i=#spec.effects, 1, -1 do
146 local effect = spec.effects[i]
147 local workArea = self:getWorkAreaByIndex(effect.workAreaIndex)
148 if workArea ~= nil then
149 effect.tedderWorkAreaFillTypeIndex = workArea.tedderWorkAreaIndex
150
151 if spec.workAreaToEffects[workArea.index] == nil then
152 spec.workAreaToEffects[workArea.index] = {}
153 end
154 table.insert(spec.workAreaToEffects[workArea.index], effect)
155 else
156 Logging.xmlWarning(self.xmlFile, "Invalid workAreaIndex '%d' for effect 'vehicle.tedder.effects.effect(%d)'!", effect.workAreaIndex, i)
157 table.insert(spec.effects, i)
158 end
159 end
160
161 if not self.isServer then
162 SpecializationUtil.removeEventListener(self, "onUpdateTick", Tedder)
163 end
164end

onReadStream

Description
Definition
onReadStream()
Code
182function Tedder:onReadStream(streamId, connection)
183 local spec = self.spec_tedder
184 for index, _ in ipairs(spec.tedderWorkAreaFillTypes) do
185 local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
186 spec.tedderWorkAreaFillTypes[index] = fillType
187 end
188 for _, effect in ipairs(spec.effects) do
189 if streamReadBool(streamId) then
190 local fillType = spec.tedderWorkAreaFillTypes[effect.tedderWorkAreaFillTypeIndex]
191 g_effectManager:setFillType(effect.effects, fillType)
192 g_effectManager:startEffects(effect.effects)
193 else
194 g_effectManager:stopEffects(effect.effects)
195 end
196 end
197end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
213function Tedder:onReadUpdateStream(streamId, timestamp, connection)
214 if connection:getIsServer() then
215 local spec = self.spec_tedder
216
217 if streamReadBool(streamId) then
218 for index, _ in ipairs(spec.tedderWorkAreaFillTypes) do
219 local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
220 spec.tedderWorkAreaFillTypes[index] = fillType
221 end
222 end
223
224 if streamReadBool(streamId) then
225 for _, effect in ipairs(spec.effects) do
226 if streamReadBool(streamId) then
227 local fillType = spec.tedderWorkAreaFillTypes[effect.tedderWorkAreaFillTypeIndex]
228 g_effectManager:setFillType(effect.effects, fillType)
229 g_effectManager:startEffects(effect.effects)
230 else
231 g_effectManager:stopEffects(effect.effects)
232 end
233 end
234 end
235 end
236end

onStartWorkAreaProcessing

Description
Definition
onStartWorkAreaProcessing()
Code
454function Tedder:onStartWorkAreaProcessing(dt)
455 local spec = self.spec_tedder
456
457 spec.lastDroppedLiters = 0
458end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
481function Tedder:onTurnedOff()
482 if self.isClient then
483 local spec = self.spec_tedder
484 g_animationManager:stopAnimations(spec.animationNodes)
485 for _, effect in ipairs(spec.effects) do
486 g_effectManager:stopEffects(effect.effects)
487 end
488 end
489end

onTurnedOn

Description
Called on turn off
Definition
onTurnedOn(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
471function Tedder:onTurnedOn()
472 if self.isClient then
473 local spec = self.spec_tedder
474 g_animationManager:startAnimations(spec.animationNodes)
475 end
476end

onUpdateTick

Description
Definition
onUpdateTick()
Code
260function Tedder:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
261 local spec = self.spec_tedder
262 if self.isServer then
263 for _, effect in ipairs(spec.effects) do
264 if effect.isActive and g_currentMission.time > effect.activeTime then
265 effect.isActive = false
266 if effect.isActiveSent then
267 effect.isActiveSent = false
268 self:raiseDirtyFlags(spec.effectDirtyFlag)
269 end
270 g_effectManager:stopEffects(effect.effects)
271 end
272 end
273 end
274end

onWriteStream

Description
Definition
onWriteStream()
Code
201function Tedder:onWriteStream(streamId, connection)
202 local spec = self.spec_tedder
203 for _, fillTypeIndex in ipairs(spec.tedderWorkAreaFillTypes) do
204 streamWriteUIntN(streamId, fillTypeIndex, FillTypeManager.SEND_NUM_BITS)
205 end
206 for _, effect in ipairs(spec.effects) do
207 streamWriteBool(streamId, effect.isActiveSent)
208 end
209end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
240function Tedder:onWriteUpdateStream(streamId, connection, dirtyMask)
241 if not connection:getIsServer() then
242 local spec = self.spec_tedder
243
244 if streamWriteBool(streamId, bitAND(dirtyMask, spec.fillTypesDirtyFlag) ~= 0) then
245 for _, fillTypeIndex in ipairs(spec.tedderWorkAreaFillTypes) do
246 streamWriteUIntN(streamId, fillTypeIndex, FillTypeManager.SEND_NUM_BITS)
247 end
248 end
249
250 if streamWriteBool(streamId, bitAND(dirtyMask, spec.effectDirtyFlag) ~= 0) then
251 for _, effect in ipairs(spec.effects) do
252 streamWriteBool(streamId, effect.isActiveSent)
253 end
254 end
255 end
256end

preprocessTedderArea

Description
Definition
preprocessTedderArea()
Code
346function Tedder:preprocessTedderArea(workArea)
347 workArea.lastPickupLiters = 0
348 workArea.lastDroppedLiters = 0
349end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
36function Tedder.prerequisitesPresent(specializations)
37 return SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations)
38end

processDropArea

Description
Definition
processDropArea()
Code
444function Tedder:processDropArea(dropArea, fillType, litersToDrop)
445 local lsx, lsy, lsz, lex, ley, lez, lineRadius = DensityMapHeightUtil.getLineByArea(dropArea.start, dropArea.width, dropArea.height, true)
446 local dropped, lineOffset = DensityMapHeightUtil.tipToGroundAroundLine(self, litersToDrop, fillType, lsx, lsy, lsz, lex, ley, lez, lineRadius, nil, dropArea.lineOffset, false, nil, false)
447 dropArea.lineOffset = lineOffset
448
449 return dropped
450end

processTedderArea

Description
Definition
processTedderArea()
Code
353function Tedder:processTedderArea(workArea, dt)
354 local spec = self.spec_tedder
355 local workAreaSpec = self.spec_workArea
356
357 local sx, sy, sz = getWorldTranslation(workArea.start)
358 local wx, wy, wz = getWorldTranslation(workArea.width)
359 local hx, hy, hz = getWorldTranslation(workArea.height)
360
361 -- pick up
362 local lsx, lsy, lsz, lex, ley, lez, lineRadius = DensityMapHeightUtil.getLineByAreaDimensions(sx, sy, sz, wx, wy, wz, hx, hy, hz, true)
363
364 for targetFillType, inputFillTypes in pairs(spec.fillTypeConvertersReverse) do
365 local pickedUpLiters = 0
366 for _, inputFillType in ipairs(inputFillTypes) do
367 pickedUpLiters = pickedUpLiters + DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, inputFillType, lsx, lsy, lsz, lex, ley, lez, lineRadius, nil, nil, false, nil)
368 end
369
370 if pickedUpLiters == 0 and workArea.lastDropFillType ~= FillType.UNKNOWN then
371 targetFillType = workArea.lastDropFillType
372 end
373
374 workArea.lastPickupLiters = -pickedUpLiters
375 workArea.litersToDrop = workArea.litersToDrop + workArea.lastPickupLiters
376
377 -- drop
378 local dropArea = workAreaSpec.workAreas[workArea.dropWindrowWorkAreaIndex]
379 if dropArea ~= nil and workArea.litersToDrop > 0 then
380 local dropped = self:processDropArea(dropArea, targetFillType, workArea.litersToDrop)
381
382 workArea.lastDropFillType = targetFillType
383 workArea.lastDroppedLiters = dropped
384 spec.lastDroppedLiters = spec.lastDroppedLiters + dropped
385 workArea.litersToDrop = workArea.litersToDrop - dropped
386
387 if self.isServer then
388 --particles
389 local lastSpeed = self:getLastSpeed(true)
390 if dropped > 0 and lastSpeed > 0.5 then
391 local changedFillType = false
392 if spec.tedderWorkAreaFillTypes[workArea.tedderWorkAreaIndex] ~= targetFillType then
393 spec.tedderWorkAreaFillTypes[workArea.tedderWorkAreaIndex] = targetFillType
394 self:raiseDirtyFlags(spec.fillTypesDirtyFlag)
395 changedFillType = true
396 end
397
398 local effects = spec.workAreaToEffects[workArea.index]
399 if effects ~= nil then
400 for _, effect in ipairs(effects) do
401 effect.activeTime = g_currentMission.time + effect.activeTimeDuration
402
403 -- sync mp
404 if not effect.isActiveSent then
405 effect.isActiveSent = true
406 self:raiseDirtyFlags(spec.effectDirtyFlag)
407 end
408
409 if changedFillType then
410 g_effectManager:setFillType(effect.effects, targetFillType)
411 end
412
413 -- enable effect
414 if not effect.isActive then
415 g_effectManager:setFillType(effect.effects, targetFillType)
416 g_effectManager:startEffects(effect.effects)
417 end
418
419 g_effectManager:setDensity(effect.effects, math.max(lastSpeed / self:getSpeedLimit(), 0.6))
420
421 effect.isActive = true
422 end
423 end
424 end
425 end
426 end
427 end
428
429 if self:getLastSpeed() > 0.5 then
430 spec.stoneLastState = FSDensityMapUtil.getStoneArea(sx, sz, wx, wz, hx, hz)
431 else
432 spec.stoneLastState = 0
433 end
434
435 --calculating area by area width multiplied by last moved distance (not 100% accuracy in corners)
436 local areaWidth = MathUtil.vector3Length(lsx-lex, lsy-ley, lsz-lez)
437 local area = areaWidth * self.lastMovedDistance
438
439 return area, area
440end

registerEventListeners

Description
Definition
registerEventListeners()
Code
59function Tedder.registerEventListeners(vehicleType)
60 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Tedder)
61 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Tedder)
62 SpecializationUtil.registerEventListener(vehicleType, "onDelete", Tedder)
63 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Tedder)
64 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Tedder)
65 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Tedder)
66 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Tedder)
67 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Tedder)
68 SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Tedder)
69 SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Tedder)
70 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Tedder)
71 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", Tedder)
72 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", Tedder)
73end

registerFunctions

Description
Definition
registerFunctions()
Code
42function Tedder.registerFunctions(vehicleType)
43 SpecializationUtil.registerFunction(vehicleType, "preprocessTedderArea", Tedder.preprocessTedderArea)
44 SpecializationUtil.registerFunction(vehicleType, "processTedderArea", Tedder.processTedderArea)
45 SpecializationUtil.registerFunction(vehicleType, "processDropArea", Tedder.processDropArea)
46end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
50function Tedder.registerOverwrittenFunctions(vehicleType)
51 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", Tedder.getDirtMultiplier)
52 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", Tedder.getWearMultiplier)
53 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", Tedder.loadWorkAreaFromXML)
54 SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Tedder.doCheckSpeedLimit)
55end