LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

ForageWagon

Description
Specialization for a forage wagon, expands functions of FillUnit, Pickup and WorkArea by adding a fillEffect
Functions

doCheckSpeedLimit

Description
Definition
doCheckSpeedLimit()
Code
386function ForageWagon:doCheckSpeedLimit(superFunc)
387 return superFunc(self) or (self:getIsTurnedOn() and self:getIsLowered())
388end

fillForageWagon

Description
Definition
fillForageWagon()
Code
310function ForageWagon:fillForageWagon()
311 local spec = self.spec_forageWagon
312
313 local loadInfo = self:getFillVolumeLoadInfo(spec.loadInfoIndex)
314 local filledLiters = self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, spec.workAreaParameters.litersToFill, spec.lastFillType, ToolType.UNDEFINED, loadInfo)
315
316 if filledLiters + 0.01 < spec.workAreaParameters.litersToFill then
317 self:setIsTurnedOn(false)
318 self:setPickupState(false)
319 end
320
321 spec.workAreaParameters.litersToFill = spec.workAreaParameters.litersToFill - filledLiters
322 if spec.workAreaParameters.litersToFill < 0.01 then
323 spec.workAreaParameters.litersToFill = 0
324 end
325end

getConsumingLoad

Description
Definition
getConsumingLoad()
Code
392function ForageWagon:getConsumingLoad(superFunc)
393 local value, count = superFunc(self)
394
395 local spec = self.spec_forageWagon
396 local loadPercentage = spec.pickUpLitersBuffer:get(1000) / spec.maxPickupLitersPerSecond
397
398 return value+loadPercentage, count+1
399end

getDefaultSpeedLimit

Description
Definition
getDefaultSpeedLimit()
Code
476function ForageWagon.getDefaultSpeedLimit()
477 return 20
478end

getFillVolumeUVScrollSpeed

Description
Definition
getFillVolumeUVScrollSpeed()
Code
355function ForageWagon:getFillVolumeUVScrollSpeed(superFunc, fillVolumeIndex)
356 local spec = self.spec_forageWagon
357
358 if spec.isFilling then
359 return spec.loadUVScrollSpeed[1], spec.loadUVScrollSpeed[2], spec.loadUVScrollSpeed[3]
360 end
361
362 if self:getDischargeState() ~= Dischargeable.DISCHARGE_STATE_OFF then
363 return spec.dischargeUVScrollSpeed[1], spec.dischargeUVScrollSpeed[2], spec.dischargeUVScrollSpeed[3]
364 end
365
366 return superFunc(self, fillVolumeIndex)
367end

getIsSpeedRotatingPartActive

Description
Definition
getIsSpeedRotatingPartActive()
Code
341function ForageWagon:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
342 local spec = self.spec_forageWagon
343
344 if speedRotatingPart.rotateOnlyIfFillLevelIncreased ~= nil then
345 if speedRotatingPart.rotateOnlyIfFillLevelIncreased and not spec.isFilling then
346 return false
347 end
348 end
349
350 return superFunc(self, speedRotatingPart)
351end

getIsWorkAreaActive

Description
Definition
getIsWorkAreaActive()
Code
371function ForageWagon:getIsWorkAreaActive(superFunc, workArea)
372 local spec = self.spec_forageWagon
373
374 local forageWagonArea = self.spec_workArea.workAreas[spec.workAreaIndex]
375 if forageWagonArea ~= nil and workArea == forageWagonArea then
376 if not self:getIsTurnedOn() or not self:allowPickingUp() then
377 return false
378 end
379 end
380
381 return superFunc(self, workArea)
382end

initSpecialization

Description
Definition
initSpecialization()
Code
15function ForageWagon.initSpecialization()
16 g_workAreaTypeManager:addWorkAreaType("forageWagon", false)
17
18 local schema = Vehicle.xmlSchema
19 schema:setXMLSpecializationType("ForageWagon")
20
21 schema:register(XMLValueType.INT, "vehicle.forageWagon#workAreaIndex", "Work area index", 1)
22 schema:register(XMLValueType.INT, "vehicle.forageWagon#fillUnitIndex", "Fill unit index", 1)
23 schema:register(XMLValueType.INT, "vehicle.forageWagon#loadInfoIndex", "Load info index", 1)
24 schema:register(XMLValueType.FLOAT, "vehicle.forageWagon#maxPickupLitersPerSecond", "Max. pickup liters per second", 500)
25
26 schema:register(XMLValueType.INT, "vehicle.forageWagon.additives#fillUnitIndex", "Additives fill unit index")
27 schema:register(XMLValueType.FLOAT, "vehicle.forageWagon.additives#usage", "Usage per picked up liter", 0.0000275)
28 schema:register(XMLValueType.STRING, "vehicle.forageWagon.additives#fillTypes", "Fill types to apply additives", "GRASS_WINDROW")
29
30 schema:register(XMLValueType.FLOAT, "vehicle.forageWagon.startFillEffect#fillStartDelay", "if defined the filling of the fill unit will be delayed until this time has passed", 0)
31 schema:register(XMLValueType.FLOAT, "vehicle.forageWagon.startFillEffect#fillStartFadeOff", "Fade out fill level for start fill effect (fillLevel 0: density 1 | fillLevel at fillStartFadeOff: density 0)", 0)
32
33 schema:register(XMLValueType.VECTOR_3, "vehicle.forageWagon.fillVolume#loadScrollSpeed", "Scroll speed while loading", "0 0 0")
34 schema:register(XMLValueType.VECTOR_3, "vehicle.forageWagon.fillVolume#dischargeScrollSpeed", "Scroll speed while unloading", "0 0 0")
35
36 schema:register(XMLValueType.BOOL, SpeedRotatingParts.SPEED_ROTATING_PART_XML_KEY .. "#rotateOnlyIfFillLevelIncreased", "Rotate only if fill level increased", false)
37
38 EffectManager.registerEffectXMLPaths(schema, "vehicle.forageWagon.fillEffect")
39 EffectManager.registerEffectXMLPaths(schema, "vehicle.forageWagon.startFillEffect")
40
41 schema:setXMLSpecializationType()
42end

loadSpeedRotatingPartFromXML

Description
Definition
loadSpeedRotatingPartFromXML()
Code
329function ForageWagon:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
330 if not superFunc(self, speedRotatingPart, xmlFile, key) then
331 return false
332 end
333
334 speedRotatingPart.rotateOnlyIfFillLevelIncreased = xmlFile:getValue(key .. "#rotateOnlyIfFillLevelIncreased", false)
335
336 return true
337end

onDeactivate

Description
Definition
onDeactivate()
Code
456function ForageWagon:onDeactivate()
457 if self.isClient then
458 local spec = self.spec_forageWagon
459 spec.fillTimer = 0
460 self:setFillEffectActive(false)
461 end
462end

onDelete

Description
Definition
onDelete()
Code
141function ForageWagon:onDelete()
142 local spec = self.spec_forageWagon
143 g_effectManager:deleteEffects(spec.fillEffects)
144 g_effectManager:deleteEffects(spec.startFillEffect)
145end

onEndWorkAreaProcessing

Description
Definition
onEndWorkAreaProcessing()
Code
421function ForageWagon:onEndWorkAreaProcessing(dt, hasProcessed)
422 local spec = self.spec_forageWagon
423
424 if self.isServer then
425 if spec.workAreaParameters.lastPickupLiters > 0 then
426 local allowToFill = true
427 if spec.fillStartEffectTimer > 0 then
428 spec.fillStartEffectTimer = spec.fillStartEffectTimer - dt
429 if spec.fillStartEffectTimer > 0 then
430 allowToFill = false
431 end
432 end
433
434 if allowToFill then
435 self:fillForageWagon()
436 end
437
438 spec.fillTimer = 500
439 end
440 end
441end

onFillUnitFillLevelChanged

Description
Definition
onFillUnitFillLevelChanged()
Code
466function ForageWagon:onFillUnitFillLevelChanged(fillUnitIndex, fillLevelDelta, fillTypeIndex, toolType, fillPositionData, appliedDelta)
467 if self.isClient then
468 local spec = self.spec_forageWagon
469 local density = 1 - math.min(self:getFillUnitFillLevel(spec.fillUnitIndex) / spec.fillStartEffectFadeOff, 1)
470 g_effectManager:setDensity(spec.startFillEffect, density)
471 end
472end

onLoad

Description
Definition
onLoad()
Code
92function ForageWagon:onLoad(savegame)
93 local spec = self.spec_forageWagon
94
95 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.forageWagon#turnedOnTipScrollerSpeedFactor") -- FS17 to FS19
96 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.turnOnVehicle.rotationNodes.rotationNode", "forageWagon") -- FS17 to FS19
97
98 spec.isFilling = false
99 spec.isFillingSent = false
100 spec.lastFillType = FillType.UNKNOWN
101 spec.lastFillTypeSent = FillType.UNKNOWN
102 spec.fillTimer = 0
103
104 spec.workAreaIndex = self.xmlFile:getValue("vehicle.forageWagon#workAreaIndex", 1)
105 spec.fillUnitIndex = self.xmlFile:getValue("vehicle.forageWagon#fillUnitIndex", 1)
106 spec.loadInfoIndex = self.xmlFile:getValue("vehicle.forageWagon#loadInfoIndex", 1)
107
108 spec.additives = {}
109 spec.additives.fillUnitIndex = self.xmlFile:getValue("vehicle.forageWagon.additives#fillUnitIndex")
110 spec.additives.available = self:getFillUnitByIndex(spec.additives.fillUnitIndex) ~= nil
111 spec.additives.usage = self.xmlFile:getValue("vehicle.forageWagon.additives#usage", 0.0000275)
112 local additivesFillTypeNames = self.xmlFile:getValue("vehicle.forageWagon.additives#fillTypes", "GRASS_WINDROW")
113 spec.additives.fillTypes = g_fillTypeManager:getFillTypesByNames(additivesFillTypeNames, "Warning: '"..self.xmlFile:getFilename().. "' has invalid fillType '%s'.")
114
115 spec.loadUVScrollSpeed = self.xmlFile:getValue("vehicle.forageWagon.fillVolume#loadScrollSpeed", "0 0 0", true)
116 spec.dischargeUVScrollSpeed = self.xmlFile:getValue("vehicle.forageWagon.fillVolume#dischargeScrollSpeed", "0 0 0", true)
117
118 spec.maxPickupLitersPerSecond = self.xmlFile:getValue("vehicle.forageWagon#maxPickupLitersPerSecond", 500)
119
120 if self.isClient then
121 spec.fillEffects = g_effectManager:loadEffect(self.xmlFile, "vehicle.forageWagon.fillEffect", self.components, self, self.i3dMappings)
122 spec.startFillEffect = g_effectManager:loadEffect(self.xmlFile, "vehicle.forageWagon.startFillEffect", self.components, self, self.i3dMappings)
123 end
124
125 spec.fillStartEffectDelay = self.xmlFile:getValue("vehicle.forageWagon.startFillEffect#fillStartDelay", 0) * 0.001
126 spec.fillStartEffectTimer = 0
127 spec.fillStartEffectFadeOff = self.xmlFile:getValue("vehicle.forageWagon.startFillEffect#fillStartFadeOff", 0)
128
129 spec.workAreaParameters = {}
130 spec.workAreaParameters.forcedFillType = FillType.UNKNOWN
131 spec.workAreaParameters.lastPickupLiters = 0
132 spec.workAreaParameters.litersToFill = 0
133
134 spec.pickUpLitersBuffer = ValueBuffer.new(750)
135
136 spec.dirtyFlag = self:getNextDirtyFlag()
137end

onReadStream

Description
Definition
onReadStream()
Code
149function ForageWagon:onReadStream(streamId, connection)
150 local spec = self.spec_forageWagon
151 spec.isFilling = streamReadBool(streamId)
152 spec.lastFillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
153 self:setFillEffectActive(spec.isFilling)
154end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
166function ForageWagon:onReadUpdateStream(streamId, timestamp, connection)
167 if connection:getIsServer() then
168 if streamReadBool(streamId) then
169 local spec = self.spec_forageWagon
170 spec.isFilling = streamReadBool(streamId)
171 spec.lastFillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS)
172 self:setFillEffectActive(spec.isFilling)
173 end
174 end
175end

onStartWorkAreaProcessing

Description
Definition
onStartWorkAreaProcessing()
Code
403function ForageWagon:onStartWorkAreaProcessing(dt)
404 local spec = self.spec_forageWagon
405
406 spec.workAreaParameters.forcedFillType = FillType.UNKNOWN
407 local fillLevel = self:getFillUnitFillLevel(spec.fillUnitIndex)
408 if fillLevel > self:getFillTypeChangeThreshold(spec.fillUnitIndex) then
409 spec.workAreaParameters.forcedFillType = self:getFillUnitFillType(spec.fillUnitIndex)
410 end
411
412 if fillLevel == 0 and spec.fillStartEffectDelay > 0 and spec.fillStartEffectTimer <= 0 then
413 spec.fillStartEffectTimer = spec.fillStartEffectDelay
414 end
415
416 spec.workAreaParameters.lastPickupLiters = 0
417end

onTurnedOff

Description
Definition
onTurnedOff()
Code
445function ForageWagon:onTurnedOff()
446 local spec = self.spec_forageWagon
447
448 if self.isClient then
449 spec.fillTimer = 0
450 self:setFillEffectActive(false)
451 end
452end

onUpdateTick

Description
Definition
onUpdateTick()
Code
191function ForageWagon:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
192 local spec = self.spec_forageWagon
193
194 if self.isServer then
195 local isFilling = false
196 if spec.fillTimer > 0 then
197 spec.fillTimer = spec.fillTimer - dt
198 isFilling = true
199 end
200 spec.isFilling = isFilling
201
202 if spec.isFilling ~= spec.isFillingSent then
203 self:raiseDirtyFlags(spec.dirtyFlag)
204 spec.isFillingSent = spec.isFilling
205 self:setFillEffectActive(spec.isFilling)
206 end
207
208 spec.pickUpLitersBuffer:add(spec.workAreaParameters.lastPickupLiters)
209 end
210end

onWriteStream

Description
Definition
onWriteStream()
Code
158function ForageWagon:onWriteStream(streamId, connection)
159 local spec = self.spec_forageWagon
160 streamWriteBool(streamId, spec.isFillingSent)
161 streamWriteUIntN(streamId, spec.lastFillType, FillTypeManager.SEND_NUM_BITS)
162end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
179function ForageWagon:onWriteUpdateStream(streamId, connection, dirtyMask)
180 if not connection:getIsServer() then
181 local spec = self.spec_forageWagon
182 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then
183 streamWriteBool(streamId, spec.isFillingSent)
184 streamWriteUIntN(streamId, spec.lastFillType, FillTypeManager.SEND_NUM_BITS)
185 end
186 end
187end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
46function ForageWagon.prerequisitesPresent(specializations)
47 return SpecializationUtil.hasSpecialization(FillUnit, specializations) and
48 SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) and
49 SpecializationUtil.hasSpecialization(Pickup, specializations) and
50 SpecializationUtil.hasSpecialization(WorkArea, specializations)
51end

processForageWagonArea

Description
Definition
processForageWagonArea()
Code
214function ForageWagon:processForageWagonArea(workArea)
215 local spec = self.spec_forageWagon
216
217 local radius = 0.5
218 local lsx, lsy, lsz, lex, ley, lez = DensityMapHeightUtil.getLineByArea(workArea.start, workArea.width, workArea.height)
219 local pickupLiters = 0
220
221 if spec.workAreaParameters.forcedFillType ~= FillType.UNKNOWN then
222 pickupLiters = -DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, spec.workAreaParameters.forcedFillType, lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, false, nil)
223
224 if spec.workAreaParameters.forcedFillType == FillType.GRASS_WINDROW then
225 pickupLiters = pickupLiters - DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, FillType.DRYGRASS_WINDROW, lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, false, nil)
226 elseif spec.workAreaParameters.forcedFillType == FillType.DRYGRASS_WINDROW then
227 pickupLiters = pickupLiters - DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, FillType.GRASS_WINDROW, lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, false, nil)
228 end
229 else
230 local supportedFillTypes = self:getFillUnitSupportedFillTypes(spec.fillUnitIndex)
231 if supportedFillTypes ~= nil then
232 for fillType,state in pairs(supportedFillTypes) do
233 if state then
234 pickupLiters = -DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, fillType, lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, false, nil)
235 if pickupLiters > 0 then
236 spec.workAreaParameters.forcedFillType = fillType
237 break
238 end
239 end
240 end
241 end
242 end
243
244 if self.isServer then
245 if spec.additives.available then
246 local fillTypeSupported = false
247 for i=1, #spec.additives.fillTypes do
248 if spec.workAreaParameters.forcedFillType == spec.additives.fillTypes[i] then
249 fillTypeSupported = true
250 break
251 end
252 end
253
254 if fillTypeSupported then
255 local additivesFillLevel = self:getFillUnitFillLevel(spec.additives.fillUnitIndex)
256 if additivesFillLevel > 0 then
257 local usage = spec.additives.usage * pickupLiters
258 if usage > 0 then
259 local availableUsage = math.min(additivesFillLevel / usage, 1)
260
261 pickupLiters = pickupLiters * (1 + 0.05 * availableUsage)
262
263 self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.additives.fillUnitIndex, -usage, self:getFillUnitFillType(spec.additives.fillUnitIndex), ToolType.UNDEFINED)
264 end
265 end
266 end
267 end
268 end
269
270 workArea.lastPickUpLiters = pickupLiters
271 workArea.pickupParticlesActive = pickupLiters > 0
272 spec.workAreaParameters.lastPickupLiters = spec.workAreaParameters.lastPickupLiters + pickupLiters
273 spec.workAreaParameters.litersToFill = spec.workAreaParameters.litersToFill + pickupLiters
274 if spec.workAreaParameters.forcedFillType ~= FillType.UNKNOWN then
275 spec.lastFillType = spec.workAreaParameters.forcedFillType
276 if spec.lastFillType ~= spec.lastFillTypeSent then
277 spec.lastFillTypeSent = spec.lastFillType
278 self:raiseDirtyFlags(spec.dirtyFlag)
279 end
280 end
281
282 local realArea, area = 0, 0
283
284 if self.movingDirection == 1 then
285 local width = MathUtil.vector3Length(lsx-lex, lsy-ley, lsz-lez)
286 area = width * self.lastMovedDistance
287 realArea = area
288 end
289
290 return realArea, area
291end

registerEventListeners

Description
Definition
registerEventListeners()
Code
74function ForageWagon.registerEventListeners(vehicleType)
75 SpecializationUtil.registerEventListener(vehicleType, "onLoad", ForageWagon)
76 SpecializationUtil.registerEventListener(vehicleType, "onDelete", ForageWagon)
77 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", ForageWagon)
78 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", ForageWagon)
79 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", ForageWagon)
80 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", ForageWagon)
81 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", ForageWagon)
82 SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", ForageWagon)
83 SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", ForageWagon)
84 SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", ForageWagon)
85 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", ForageWagon)
86 SpecializationUtil.registerEventListener(vehicleType, "onFillUnitFillLevelChanged", ForageWagon)
87end

registerFunctions

Description
Definition
registerFunctions()
Code
55function ForageWagon.registerFunctions(vehicleType)
56 SpecializationUtil.registerFunction(vehicleType, "processForageWagonArea", ForageWagon.processForageWagonArea)
57 SpecializationUtil.registerFunction(vehicleType, "setFillEffectActive", ForageWagon.setFillEffectActive)
58 SpecializationUtil.registerFunction(vehicleType, "fillForageWagon", ForageWagon.fillForageWagon)
59end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
63function ForageWagon.registerOverwrittenFunctions(vehicleType)
64 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSpeedRotatingPartFromXML", ForageWagon.loadSpeedRotatingPartFromXML)
65 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", ForageWagon.getIsWorkAreaActive)
66 SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", ForageWagon.doCheckSpeedLimit)
67 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getConsumingLoad", ForageWagon.getConsumingLoad)
68 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSpeedRotatingPartActive", ForageWagon.getIsSpeedRotatingPartActive)
69 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillVolumeUVScrollSpeed", ForageWagon.getFillVolumeUVScrollSpeed)
70end

setFillEffectActive

Description
Definition
setFillEffectActive()
Code
295function ForageWagon:setFillEffectActive(isActive)
296 local spec = self.spec_forageWagon
297 if isActive then
298 g_effectManager:setFillType(spec.fillEffects, spec.lastFillType)
299 g_effectManager:setFillType(spec.startFillEffect, spec.lastFillType)
300 g_effectManager:startEffects(spec.fillEffects)
301 g_effectManager:startEffects(spec.startFillEffect)
302 else
303 g_effectManager:stopEffects(spec.fillEffects)
304 g_effectManager:stopEffects(spec.startFillEffect)
305 end
306end