LUADOC - Farming Simulator 19

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
314function Tedder:doCheckSpeedLimit(superFunc)
315 return superFunc(self) or (self:getIsTurnedOn() and self:getIsImplementChainLowered())
316end

getDefaultSpeedLimit

Description
Definition
getDefaultSpeedLimit()
Code
465function Tedder.getDefaultSpeedLimit()
466 return 15
467end

getDirtMultiplier

Description
Definition
getDirtMultiplier()
Code
286function Tedder:getDirtMultiplier(superFunc)
287 local spec = self.spec_tedder
288
289 local multiplier = superFunc(self)
290
291 if spec.isWorking then
292 multiplier = multiplier + self:getWorkDirtMultiplier() * self:getLastSpeed() / self.speedLimit
293 end
294
295 return multiplier
296end

getWearMultiplier

Description
Definition
getWearMultiplier()
Code
300function Tedder:getWearMultiplier(superFunc)
301 local spec = self.spec_tedder
302
303 local multiplier = superFunc(self)
304
305 if spec.isWorking then
306 multiplier = multiplier + self:getWorkWearMultiplier() * self:getLastSpeed() / self.speedLimit
307 end
308
309 return multiplier
310end

initSpecialization

Description
Definition
initSpecialization()
Code
16function Tedder.initSpecialization()
17 g_workAreaTypeManager:addWorkAreaType("tedder", false)
18end

loadWorkAreaFromXML

Description
Definition
loadWorkAreaFromXML()
Code
257function Tedder:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
258 local retValue = superFunc(self, workArea, xmlFile, key)
259
260 if workArea.type == WorkAreaType.DEFAULT then
261 workArea.type = WorkAreaType.TEDDER
262 end
263
264 if workArea.type == WorkAreaType.TEDDER then
265 workArea.dropWindrowWorkAreaIndex = Utils.getNoNil(getXMLInt(xmlFile, key .. ".tedder#dropWindrowWorkAreaIndex"), 1)
266 workArea.litersToDrop = 0
267 workArea.lastPickupLiters = 0
268 workArea.lastDropFillType = FillType.UNKNOWN
269 workArea.lastDroppedLiters = 0
270 workArea.tedderParticlesActive = false
271 workArea.tedderParticlesActiveSent = false
272
273 local spec = self.spec_tedder
274 if spec.tedderWorkAreaFillTypes == nil then
275 spec.tedderWorkAreaFillTypes = {}
276 end
277 table.insert(spec.tedderWorkAreaFillTypes, FruitType.UNKNOWN)
278 workArea.tedderWorkAreaIndex = #spec.tedderWorkAreaFillTypes
279 end
280
281 return retValue
282end

onDeactivate

Description
Definition
onDeactivate()
Code
454function Tedder:onDeactivate()
455 if self.isClient then
456 local spec = self.spec_tedder
457 for _, effect in ipairs(spec.effects) do
458 g_effectManager:stopEffects(effect.effects)
459 end
460 end
461end

onDelete

Description
Definition
onDelete()
Code
148function Tedder:onDelete()
149 local spec = self.spec_tedder
150
151 if self.isClient then
152 for _, effect in ipairs(spec.effects) do
153 g_effectManager:deleteEffects(effect.effects)
154 end
155 g_animationManager:deleteAnimations(spec.animationNodes)
156 end
157end

onEndWorkAreaProcessing

Description
Definition
onEndWorkAreaProcessing()
Code
423function Tedder:onEndWorkAreaProcessing(dt, hasProcessed)
424 local spec = self.spec_tedder
425
426 spec.isWorking = spec.lastDroppedLiters > 0
427end

onLoad

Description
Definition
onLoad()
Code
63function Tedder:onLoad(savegame)
64 local spec = self.spec_tedder
65
66 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.tedder.animationNodes.animationNode", "tedder") --FS17 to FS19
67 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.tedder.sounds", "vehicle.turnOnVehicle.sounds.work") --FS17 to FS19
68
69 spec.fillTypeConverters = {}
70 spec.fillTypeConvertersReverse = {}
71 local converter = getXMLString(self.xmlFile, "vehicle.tedder#fillTypeConverter")
72 if converter ~= nil then
73 local data = g_fillTypeManager:getConverterDataByName(converter)
74 if data ~= nil then
75 for input, converted in pairs(data) do
76 spec.fillTypeConverters[input] = converted
77
78 if spec.fillTypeConvertersReverse[converted.targetFillTypeIndex] == nil then
79 spec.fillTypeConvertersReverse[converted.targetFillTypeIndex] = {}
80 end
81 table.insert(spec.fillTypeConvertersReverse[converted.targetFillTypeIndex], input)
82 end
83 end
84 else
85 print(string.format("Warning: Missing fill type converter in '%s'", self.configFileName))
86 end
87
88 if self.isClient then
89 spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.tedder.animationNodes", self.components, self, self.i3dMappings)
90
91 spec.effects = {}
92 spec.workAreaToEffects = {}
93 local i = 0
94 while true do
95 local key = string.format("vehicle.tedder.effects.effect(%d)", i)
96 if not hasXMLProperty(self.xmlFile, key) then
97 break
98 end
99 local effects = g_effectManager:loadEffect(self.xmlFile, key, self.components, self, self.i3dMappings)
100 if effects ~= nil then
101 local effect = {}
102 effect.effects = effects
103 effect.workAreaIndex = Utils.getNoNil(getXMLInt(self.xmlFile, key .. "#workAreaIndex"), 1)
104 effect.activeTime = -1
105 effect.activeTimeDuration = 250
106 effect.isActive = false
107 effect.isActiveSent = false
108 table.insert(spec.effects, effect)
109 end
110 i = i + 1
111 end
112 end
113
114 spec.lastDroppedLiters = 0
115
116 spec.fillTypesDirtyFlag = self:getNextDirtyFlag()
117 spec.effectDirtyFlag = self:getNextDirtyFlag()
118
119 if self.addAIFruitRequirement ~= nil then
120 self:addAIFruitRequirement(FruitType.GRASS, 0, g_currentMission.terrainDetailHeightTypeNumChannels)
121 self:setAIFruitExtraRequirements(true, true)
122 end
123end

onPostLoad

Description
Definition
onPostLoad()
Code
127function Tedder:onPostLoad(savegame)
128 local spec = self.spec_tedder
129 for i=#spec.effects, 1, -1 do
130 local effect = spec.effects[i]
131 local workArea = self:getWorkAreaByIndex(effect.workAreaIndex)
132 if workArea ~= nil then
133 effect.tedderWorkAreaFillTypeIndex = workArea.tedderWorkAreaIndex
134
135 if spec.workAreaToEffects[workArea.index] == nil then
136 spec.workAreaToEffects[workArea.index] = {}
137 end
138 table.insert(spec.workAreaToEffects[workArea.index], effect)
139 else
140 g_logManager:xmlWarning(self.xmlFileName, "Invalid workAreaIndex '%d' for effect 'vehicle.tedder.effects.effect(%d)'!", effect.workAreaIndex, i)
141 table.insert(spec.effects, i)
142 end
143 end
144end

onReadStream

Description
Definition
onReadStream()
Code
161function Tedder:onReadStream(streamId, connection)
162 local spec = self.spec_tedder
163 for index, _ in ipairs(spec.tedderWorkAreaFillTypes) do
164 local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
165 spec.tedderWorkAreaFillTypes[index] = fillType
166 end
167 for _, effect in ipairs(spec.effects) do
168 if streamReadBool(streamId) then
169 local fillType = spec.tedderWorkAreaFillTypes[effect.tedderWorkAreaFillTypeIndex]
170 g_effectManager:setFillType(effect.effects, fillType)
171 g_effectManager:startEffects(effect.effects)
172 else
173 g_effectManager:stopEffects(effect.effects)
174 end
175 end
176end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
192function Tedder:onReadUpdateStream(streamId, timestamp, connection)
193 if connection:getIsServer() then
194 local spec = self.spec_tedder
195
196 if streamReadBool(streamId) then
197 for index, _ in ipairs(spec.tedderWorkAreaFillTypes) do
198 local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
199 spec.tedderWorkAreaFillTypes[index] = fillType
200 end
201 end
202
203 if streamReadBool(streamId) then
204 for _, effect in ipairs(spec.effects) do
205 if streamReadBool(streamId) then
206 local fillType = spec.tedderWorkAreaFillTypes[effect.tedderWorkAreaFillTypeIndex]
207 g_effectManager:setFillType(effect.effects, fillType)
208 g_effectManager:startEffects(effect.effects)
209 else
210 g_effectManager:stopEffects(effect.effects)
211 end
212 end
213 end
214 end
215end

onStartWorkAreaProcessing

Description
Definition
onStartWorkAreaProcessing()
Code
415function Tedder:onStartWorkAreaProcessing(dt)
416 local spec = self.spec_tedder
417
418 spec.lastDroppedLiters = 0
419end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
442function Tedder:onTurnedOff()
443 if self.isClient then
444 local spec = self.spec_tedder
445 g_animationManager:stopAnimations(spec.animationNodes)
446 for _, effect in ipairs(spec.effects) do
447 g_effectManager:stopEffects(effect.effects)
448 end
449 end
450end

onTurnedOn

Description
Called on turn off
Definition
onTurnedOn(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
432function Tedder:onTurnedOn()
433 if self.isClient then
434 local spec = self.spec_tedder
435 g_animationManager:startAnimations(spec.animationNodes)
436 end
437end

onUpdateTick

Description
Definition
onUpdateTick()
Code
239function Tedder:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
240 local spec = self.spec_tedder
241 if self.isServer then
242 for _, effect in ipairs(spec.effects) do
243 if effect.isActive and g_currentMission.time > effect.activeTime then
244 effect.isActive = false
245 if effect.isActiveSent then
246 effect.isActiveSent = false
247 self:raiseDirtyFlags(spec.effectDirtyFlag)
248 end
249 g_effectManager:stopEffects(effect.effects)
250 end
251 end
252 end
253end

onWriteStream

Description
Definition
onWriteStream()
Code
180function Tedder:onWriteStream(streamId, connection)
181 local spec = self.spec_tedder
182 for _, fillTypeIndex in ipairs(spec.tedderWorkAreaFillTypes) do
183 streamWriteUIntN(streamId, fillTypeIndex, FillTypeManager.SEND_NUM_BITS)
184 end
185 for _, effect in ipairs(spec.effects) do
186 streamWriteBool(streamId, effect.isActiveSent)
187 end
188end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
219function Tedder:onWriteUpdateStream(streamId, connection, dirtyMask)
220 if not connection:getIsServer() then
221 local spec = self.spec_tedder
222
223 if streamWriteBool(streamId, bitAND(dirtyMask, spec.fillTypesDirtyFlag) ~= 0) then
224 for _, fillTypeIndex in ipairs(spec.tedderWorkAreaFillTypes) do
225 streamWriteUIntN(streamId, fillTypeIndex, FillTypeManager.SEND_NUM_BITS)
226 end
227 end
228
229 if streamWriteBool(streamId, bitAND(dirtyMask, spec.effectDirtyFlag) ~= 0) then
230 for _, effect in ipairs(spec.effects) do
231 streamWriteBool(streamId, effect.isActiveSent)
232 end
233 end
234 end
235end

preprocessTedderArea

Description
Definition
preprocessTedderArea()
Code
320function Tedder:preprocessTedderArea(workArea)
321 workArea.lastPickupLiters = 0
322 workArea.lastDroppedLiters = 0
323end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
22function Tedder.prerequisitesPresent(specializations)
23 return SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations)
24end

processDropArea

Description
Definition
processDropArea()
Code
405function Tedder:processDropArea(dropArea, fillType, litersToDrop)
406 local lsx, lsy, lsz, lex, ley, lez, lineRadius = DensityMapHeightUtil.getLineByArea(dropArea.start, dropArea.width, dropArea.height, true)
407 local dropped, lineOffset = DensityMapHeightUtil.tipToGroundAroundLine(self, litersToDrop, fillType, lsx, lsy, lsz, lex, ley, lez, lineRadius, nil, dropArea.lineOffset, false, nil, false)
408 dropArea.lineOffset = lineOffset
409
410 return dropped
411end

processTedderArea

Description
Definition
processTedderArea()
Code
327function Tedder:processTedderArea(workArea, dt)
328 local spec = self.spec_tedder
329 local workAreaSpec = self.spec_workArea
330
331 -- pick up
332 local lsx, lsy, lsz, lex, ley, lez, lineRadius = DensityMapHeightUtil.getLineByArea(workArea.start, workArea.width, workArea.height)
333
334 for targetFillType, inputFillTypes in pairs(spec.fillTypeConvertersReverse) do
335 local pickedUpLiters = 0
336 for _, inputFillType in ipairs(inputFillTypes) do
337 pickedUpLiters = pickedUpLiters + DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, inputFillType, lsx, lsy, lsz, lex, ley, lez, lineRadius, nil, nil, false, nil)
338 end
339
340 if pickedUpLiters == 0 and workArea.lastDropFillType ~= FillType.UNKNOWN then
341 targetFillType = workArea.lastDropFillType
342 end
343
344 workArea.lastPickupLiters = -pickedUpLiters
345 workArea.litersToDrop = workArea.litersToDrop + workArea.lastPickupLiters
346
347 -- drop
348 local dropArea = workAreaSpec.workAreas[workArea.dropWindrowWorkAreaIndex]
349 if dropArea ~= nil and workArea.litersToDrop > 0 then
350 local dropped = self:processDropArea(dropArea, targetFillType, workArea.litersToDrop)
351
352 workArea.lastDropFillType = targetFillType
353 workArea.lastDroppedLiters = dropped
354 spec.lastDroppedLiters = spec.lastDroppedLiters + dropped
355 workArea.litersToDrop = workArea.litersToDrop - dropped
356
357 if self.isServer then
358 --particles
359 if dropped > 0 and self:getLastSpeed(true) > 0.5 then
360 local changedFillType = false
361 if spec.tedderWorkAreaFillTypes[workArea.tedderWorkAreaIndex] ~= targetFillType then
362 spec.tedderWorkAreaFillTypes[workArea.tedderWorkAreaIndex] = targetFillType
363 self:raiseDirtyFlags(spec.fillTypesDirtyFlag)
364 changedFillType = true
365 end
366
367 local effects = spec.workAreaToEffects[workArea.index]
368 if effects ~= nil then
369 for _, effect in ipairs(effects) do
370 effect.activeTime = g_currentMission.time + effect.activeTimeDuration
371
372 -- sync mp
373 if not effect.isActiveSent then
374 effect.isActiveSent = true
375 self:raiseDirtyFlags(spec.effectDirtyFlag)
376 end
377
378 if changedFillType then
379 g_effectManager:setFillType(effect.effects, targetFillType)
380 end
381
382 -- enable effect
383 if not effect.isActive then
384 g_effectManager:setFillType(effect.effects, targetFillType)
385 g_effectManager:startEffects(effect.effects)
386 end
387
388 effect.isActive = true
389 end
390 end
391 end
392 end
393 end
394 end
395
396 --calculating area by area width multiplied by last moved distance (not 100% accuracy in corners)
397 local areaWidth = MathUtil.vector3Length(lsx-lex, lsy-ley, lsz-lez)
398 local area = areaWidth * self.lastMovedDistance
399
400 return area, area
401end

registerEventListeners

Description
Definition
registerEventListeners()
Code
45function Tedder.registerEventListeners(vehicleType)
46 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Tedder)
47 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Tedder)
48 SpecializationUtil.registerEventListener(vehicleType, "onDelete", Tedder)
49 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Tedder)
50 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Tedder)
51 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Tedder)
52 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Tedder)
53 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Tedder)
54 SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Tedder)
55 SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Tedder)
56 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Tedder)
57 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", Tedder)
58 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", Tedder)
59end

registerFunctions

Description
Definition
registerFunctions()
Code
28function Tedder.registerFunctions(vehicleType)
29 SpecializationUtil.registerFunction(vehicleType, "preprocessTedderArea", Tedder.preprocessTedderArea)
30 SpecializationUtil.registerFunction(vehicleType, "processTedderArea", Tedder.processTedderArea)
31 SpecializationUtil.registerFunction(vehicleType, "processDropArea", Tedder.processDropArea)
32end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
36function Tedder.registerOverwrittenFunctions(vehicleType)
37 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", Tedder.getDirtMultiplier)
38 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", Tedder.getWearMultiplier)
39 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", Tedder.loadWorkAreaFromXML)
40 SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Tedder.doCheckSpeedLimit)
41end