LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

VariableWorkWidth

Description
Specialization to change the work width by keys
Functions

actionEventWorkWidthLeft

Description
Definition
actionEventWorkWidthLeft()
Code
296function VariableWorkWidth.actionEventWorkWidthLeft(self, actionName, inputValue, callbackState, isAnalog)
297 local spec = self.spec_variableWorkWidth
298 self:setSectionsActive(spec.leftSide - inputValue, spec.rightSide)
299end

actionEventWorkWidthRight

Description
Definition
actionEventWorkWidthRight()
Code
303function VariableWorkWidth.actionEventWorkWidthRight(self, actionName, inputValue, callbackState, isAnalog)
304 local spec = self.spec_variableWorkWidth
305 self:setSectionsActive(spec.leftSide, spec.rightSide - inputValue)
306end

actionEventWorkWidthToggle

Description
Definition
actionEventWorkWidthToggle()
Code
310function VariableWorkWidth.actionEventWorkWidthToggle(self, actionName, inputValue, callbackState, isAnalog)
311 local spec = self.spec_variableWorkWidth
312
313 local minValue = math.min(spec.leftSide, spec.rightSide)
314 local newState = minValue - 1
315 if newState < spec.minSideState then
316 newState = math.min(spec.leftSideMax, spec.rightSideMax)
317 end
318
319 self:setSectionsActive(newState, newState)
320end

getEffectByNode

Description
Returns the effect object with the given node
Definition
getEffectByNode(integer node)
Arguments
integernodenode
Code
427function VariableWorkWidth:getEffectByNode(node)
428 return
429end

getIsWorkAreaActive

Description
Definition
getIsWorkAreaActive()
Code
473function VariableWorkWidth:getIsWorkAreaActive(superFunc, workArea)
474 if workArea.sectionIndex ~= nil then
475 local section = self.spec_variableWorkWidth.sections[workArea.sectionIndex]
476 if section ~= nil then
477 if not section.isActive then
478 return false
479 end
480 end
481 end
482
483 return superFunc(self, workArea)
484end

getVariableWorkWidth

Description
Returns the current work width for the given side
Definition
getVariableWorkWidth(bool isLeft)
Arguments
boolisLeftis left effect
Return Values
floatwidthwidth
floatmaxWidthmax width
boolisValidis valid - has variable working width sections
Code
437function VariableWorkWidth:getVariableWorkWidth(isLeft)
438 local spec = self.spec_variableWorkWidth
439 local sections = isLeft and spec.sectionsLeft or spec.sectionsRight
440 if #sections == 0 then
441 return 1, 1, false
442 end
443
444 local maxWidth
445 for i=#sections, 1, -1 do
446 local section = sections[i]
447 maxWidth = maxWidth or section.widthAbs
448 if section.isActive then
449 return section.widthAbs, maxWidth, true
450 end
451 end
452
453 return 0, maxWidth or 1, true
454end

getVariableWorkWidthUsage

Description
Returns the current usage for variable work width (nil if usage should not be displayed)
Definition
getVariableWorkWidthUsage()
Return Values
floatusageusage
Code
459function VariableWorkWidth:getVariableWorkWidthUsage()
460 return nil
461end

initSpecialization

Description
Definition
initSpecialization()
Code
28function VariableWorkWidth.initSpecialization()
29 g_configurationManager:addConfigurationType("variableWorkWidth", g_i18n:getText("configuration_workingWidth"), "variableWorkWidth", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
30
31 local schema = Vehicle.xmlSchema
32 schema:setXMLSpecializationType("VariableWorkWidth")
33
34 VariableWorkWidth.registerSectionPaths(schema, "vehicle.variableWorkWidth")
35 VariableWorkWidth.registerSectionPaths(schema, "vehicle.variableWorkWidth.variableWorkWidthConfigurations.variableWorkWidthConfiguration(?)")
36
37 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.variableWorkWidth.variableWorkWidthConfigurations.variableWorkWidthConfiguration(?)")
38
39 schema:register(XMLValueType.INT, "vehicle.variableWorkWidth#widthReferenceWorkAreaIndex", "Width of this work area is used as reference for the HUD display", 1)
40 schema:register(XMLValueType.INT, "vehicle.variableWorkWidth#defaultStateLeft", "Default state on left side", "Max. possible state")
41 schema:register(XMLValueType.INT, "vehicle.variableWorkWidth#defaultStateRight", "Default state on right side", "Max. possible state")
42
43 schema:register(XMLValueType.BOOL, "vehicle.variableWorkWidth#aiKeepCurrentWidth", "Defines if the ai should keep the current width or change it", false)
44 schema:register(XMLValueType.INT, "vehicle.variableWorkWidth#aiStateLeft", "AI state on left side", "Max. possible state")
45 schema:register(XMLValueType.INT, "vehicle.variableWorkWidth#aiStateRight", "AI state on right side", "Max. possible state")
46
47 schema:register(XMLValueType.INT, WorkArea.WORK_AREA_XML_KEY .. ".section#index", "Section index (Section needs to be active to activate workArea)")
48 schema:register(XMLValueType.INT, WorkArea.WORK_AREA_XML_CONFIG_KEY .. ".section#index", "Section index (Section needs to be active to activate workArea)")
49
50 schema:setXMLSpecializationType()
51
52 local schemaSavegame = Vehicle.xmlSchemaSavegame
53 schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).variableWorkWidth#leftSide", "Left side section states", "Max. state")
54 schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).variableWorkWidth#rightSide", "Right side section states", "Max. state")
55end

loadWorkAreaFromXML

Description
Definition
loadWorkAreaFromXML()
Code
465function VariableWorkWidth:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
466 workArea.sectionIndex = xmlFile:getValue(key..".section#index")
467
468 return superFunc(self, workArea, xmlFile, key)
469end

onAIFieldWorkerStart

Description
Definition
onAIFieldWorkerStart()
Code
324function VariableWorkWidth:onAIFieldWorkerStart()
325 if self.isServer then
326 local spec = self.spec_variableWorkWidth
327 if not spec.aiKeepCurrentWidth then
328 self:setSectionsActive(spec.aiStateLeft, spec.aiStateRight)
329 end
330 end
331end

onAIImplementStart

Description
Definition
onAIImplementStart()
Code
335function VariableWorkWidth:onAIImplementStart()
336 if self.isServer then
337 local spec = self.spec_variableWorkWidth
338 if not spec.aiKeepCurrentWidth then
339 self:setSectionsActive(spec.aiStateLeft, spec.aiStateRight)
340 end
341 end
342end

onPostLoad

Description
Definition
onPostLoad()
Code
113function VariableWorkWidth:onPostLoad(savegame)
114 local spec = self.spec_variableWorkWidth
115
116 local configurationId = Utils.getNoNil(self.configurations["variableWorkWidth"], 1)
117 local configKey = string.format("vehicle.variableWorkWidth.variableWorkWidthConfigurations.variableWorkWidthConfiguration(%d)", configurationId - 1)
118 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.variableWorkWidth.variableWorkWidthConfigurations.variableWorkWidthConfiguration", configurationId , self.components, self)
119
120 if not self.xmlFile:hasProperty(configKey) then
121 configKey = "vehicle.variableWorkWidth"
122 end
123
124 local deleteListener = function(section, effect)
125 for i=#section.effects, 1, -1 do
126 if section.effects[i] == effect then
127 section.effects[i] = nil
128 break
129 end
130 end
131 end
132
133 local startRestriction = function(section)
134 return section.isActive
135 end
136
137 spec.hasCenter = false
138
139 spec.sections = {}
140 spec.sectionsLeft = {}
141 spec.sectionsRight = {}
142 self.xmlFile:iterate(configKey .. ".sections.section", function(index, key)
143 local section = {}
144 section.isLeft = self.xmlFile:getValue(key .. "#isLeft", false)
145 section.isCenter = self.xmlFile:getValue(key .. "#isCenter", false)
146
147 section.maxWidthNode = self.xmlFile:getValue(key .. "#maxWidthNode", nil, self.components, self.i3dMappings)
148 section.width = self.xmlFile:getValue(key .. "#width")
149
150 section.effects = {}
151 self.xmlFile:iterate(key .. ".effect", function(effectIndex, effectKey)
152 local effectNode = self.xmlFile:getValue(effectKey .. "#node", nil, self.components, self.i3dMappings)
153 if effectNode ~= nil then
154 local effect = self:getEffectByNode(effectNode)
155 if effect ~= nil then
156 effect:addDeleteListener(deleteListener, section, effect)
157 effect:addStartRestriction(startRestriction, section)
158 table.insert(section.effects, effect)
159 end
160 end
161 end)
162
163 section.isActive = true
164
165 if section.isLeft then
166 table.insert(spec.sectionsLeft, section)
167 elseif not section.isCenter then
168 table.insert(spec.sectionsRight, section)
169 else
170 spec.hasCenter = true
171 end
172
173 table.insert(spec.sections, section)
174 end)
175
176 spec.sectionNodes = {}
177 spec.sectionNodesLeft = {}
178 spec.sectionNodesRight = {}
179 self.xmlFile:iterate(configKey .. ".sectionNodes.sectionNode", function(index, key)
180 local sectionNode = {}
181 sectionNode.node = self.xmlFile:getValue(key .. "#node", nil, self.components, self.i3dMappings)
182 if sectionNode.node ~= nil then
183 sectionNode.isLeft = self.xmlFile:getValue(key .. "#isLeft", false)
184
185 sectionNode.startTrans = self.xmlFile:getValue(key .. "#minTrans", nil, true)
186 sectionNode.startTransX = self.xmlFile:getValue(key .. "#minTransX")
187 sectionNode.endTrans = self.xmlFile:getValue(key .. "#maxTrans", nil, true)
188 sectionNode.endTransX = self.xmlFile:getValue(key .. "#maxTransX")
189 sectionNode.startRot = self.xmlFile:getValue(key .. "#minRot", nil, true)
190 sectionNode.endRot = self.xmlFile:getValue(key .. "#endRot", nil, true)
191
192 sectionNode.workAreaIndex = self.xmlFile:getValue(key .. "#workAreaIndex", 1)
193
194 if sectionNode.isLeft then
195 table.insert(spec.sectionNodesLeft, sectionNode)
196 else
197 table.insert(spec.sectionNodesRight, sectionNode)
198 end
199
200 table.insert(spec.sectionNodes, sectionNode)
201 end
202 end)
203
204 for i=1, #spec.sections do
205 local section = spec.sections[i]
206 if section.maxWidthNode ~= nil then
207 if not section.isCenter then
208 for j=1, #spec.sectionNodes do
209 local sectionNode = spec.sectionNodes[j]
210 if sectionNode.isLeft == section.isLeft then
211 local x, _, _ = localToLocal(section.maxWidthNode, getParent(sectionNode.node), 0, 0, 0)
212
213 local minX, maxX = sectionNode.startTransX or sectionNode.startTrans[1], sectionNode.endTransX or sectionNode.endTrans[1]
214 section.width = MathUtil.clamp(math.abs((x - minX) / (maxX - minX)), 0, 1)
215 section.widthAbs = x
216 break
217 end
218 end
219 end
220 else
221 section.width = 0
222 end
223
224 if section.width == nil then
225 Logging.xmlWarning(self.xmlFile, "Unable to get width for section 'vehicle.variableWorkWidth.sections.section(%d)'", i)
226 section.width = 0
227 end
228 end
229
230 local function sort(a, b)
231 return a.width < b.width
232 end
233 table.sort(spec.sectionsLeft, sort)
234 table.sort(spec.sectionsRight, sort)
235
236 spec.widthReferenceWorkArea = self.xmlFile:getValue("vehicle.variableWorkWidth#widthReferenceWorkAreaIndex", 1)
237
238 spec.leftSideMax = #spec.sectionsLeft
239 spec.leftSide = self.xmlFile:getValue("vehicle.variableWorkWidth#defaultStateLeft", spec.leftSideMax)
240 spec.rightSideMax = #spec.sectionsRight
241 spec.rightSide = self.xmlFile:getValue("vehicle.variableWorkWidth#defaultStateRight", spec.rightSideMax)
242
243 spec.aiKeepCurrentWidth = self.xmlFile:getValue("vehicle.variableWorkWidth#aiKeepCurrentWidth", false)
244 spec.aiStateLeft = self.xmlFile:getValue("vehicle.variableWorkWidth#aiStateLeft", spec.leftSideMax)
245 spec.aiStateRight = self.xmlFile:getValue("vehicle.variableWorkWidth#aiStateRight", spec.rightSideMax)
246
247 spec.minSideState = spec.hasCenter and 0 or 1
248
249 if savegame ~= nil and not savegame.resetVehicles then
250 spec.leftSide = math.min(savegame.xmlFile:getValue(savegame.key .. ".variableWorkWidth#leftSide", spec.leftSide), spec.leftSideMax)
251 spec.rightSide = math.min(savegame.xmlFile:getValue(savegame.key .. ".variableWorkWidth#rightSide", spec.rightSide), spec.rightSideMax)
252 end
253
254 self:updateSections()
255
256 spec.drawInputHelp = false
257 spec.hasSections = #spec.sections > 0
258
259 if not self.isClient or not spec.hasSections then
260 SpecializationUtil.removeEventListener(self, "onRegisterActionEvents", VariableWorkWidth)
261 end
262end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
276function VariableWorkWidth:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
277 local spec = self.spec_variableWorkWidth
278 self:clearActionEventsTable(spec.actionEvents)
279
280 if isActiveForInputIgnoreSelection then
281 local _, actionEventIdLeft = self:addActionEvent(spec.actionEvents, InputAction.VARIABLE_WORK_WIDTH_LEFT, self, VariableWorkWidth.actionEventWorkWidthLeft, false, true, false, true, nil)
282 g_inputBinding:setActionEventTextPriority(actionEventIdLeft, GS_PRIO_HIGH)
283
284 local _, actionEventIdRight = self:addActionEvent(spec.actionEvents, InputAction.VARIABLE_WORK_WIDTH_RIGHT, self, VariableWorkWidth.actionEventWorkWidthRight, false, true, false, true, nil)
285 g_inputBinding:setActionEventTextPriority(actionEventIdRight, GS_PRIO_HIGH)
286
287 local _, actionEventIdToggle = self:addActionEvent(spec.actionEvents, InputAction.VARIABLE_WORK_WIDTH_TOGGLE, self, VariableWorkWidth.actionEventWorkWidthToggle, false, true, false, true, nil)
288 g_inputBinding:setActionEventTextPriority(actionEventIdToggle, GS_PRIO_HIGH)
289
290 spec.drawInputHelp = g_inputBinding:getActionEventsHasBinding(actionEventIdLeft) or g_inputBinding:getActionEventsHasBinding(actionEventIdRight) or g_inputBinding:getActionEventsHasBinding(actionEventIdToggle)
291 end
292end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
22function VariableWorkWidth.prerequisitesPresent(specializations)
23 return true
24end

registerEventListeners

Description
Definition
registerEventListeners()
Code
104function VariableWorkWidth.registerEventListeners(vehicleType)
105 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", VariableWorkWidth)
106 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", VariableWorkWidth)
107 SpecializationUtil.registerEventListener(vehicleType, "onAIFieldWorkerStart", VariableWorkWidth)
108 SpecializationUtil.registerEventListener(vehicleType, "onAIImplementStart", VariableWorkWidth)
109end

registerEvents

Description
Definition
registerEvents()
Code
79function VariableWorkWidth.registerEvents(vehicleType)
80 SpecializationUtil.registerEvent(vehicleType, "onVariableWorkWidthSectionChanged")
81end

registerFunctions

Description
Definition
registerFunctions()
Code
85function VariableWorkWidth.registerFunctions(vehicleType)
86 SpecializationUtil.registerFunction(vehicleType, "setSectionsActive", VariableWorkWidth.setSectionsActive)
87 SpecializationUtil.registerFunction(vehicleType, "setSectionNodePercentage", VariableWorkWidth.setSectionNodePercentage)
88 SpecializationUtil.registerFunction(vehicleType, "updateSections", VariableWorkWidth.updateSections)
89 SpecializationUtil.registerFunction(vehicleType, "updateSectionStates", VariableWorkWidth.updateSectionStates)
90 SpecializationUtil.registerFunction(vehicleType, "getEffectByNode", VariableWorkWidth.getEffectByNode)
91 SpecializationUtil.registerFunction(vehicleType, "getVariableWorkWidth", VariableWorkWidth.getVariableWorkWidth)
92 SpecializationUtil.registerFunction(vehicleType, "getVariableWorkWidthUsage", VariableWorkWidth.getVariableWorkWidthUsage)
93end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
97function VariableWorkWidth.registerOverwrittenFunctions(vehicleType)
98 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", VariableWorkWidth.loadWorkAreaFromXML)
99 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", VariableWorkWidth.getIsWorkAreaActive)
100end

registerSectionPaths

Description
Definition
registerSectionPaths()
Code
59function VariableWorkWidth.registerSectionPaths(schema, basePath)
60 schema:register(XMLValueType.BOOL, basePath .. ".sections.section(?)#isLeft", "Section side", false)
61 schema:register(XMLValueType.BOOL, basePath .. ".sections.section(?)#isCenter", "Is center section", false)
62 schema:register(XMLValueType.FLOAT, basePath .. ".sections.section(?)#width", "Section max. width as percentage [0..1]", "Automatically calculated")
63 schema:register(XMLValueType.NODE_INDEX, basePath .. ".sections.section(?)#maxWidthNode", "Position of this node defines max. width of this section")
64 schema:register(XMLValueType.NODE_INDEX, basePath .. ".sections.section(?).effect(?)#node", "Effect to deactivate/activate")
65
66 schema:register(XMLValueType.NODE_INDEX, basePath .. ".sectionNodes.sectionNode(?)#node", "Section node")
67 schema:register(XMLValueType.BOOL, basePath .. ".sectionNodes.sectionNode(?)#isLeft", "Section node")
68 schema:register(XMLValueType.VECTOR_TRANS, basePath .. ".sectionNodes.sectionNode(?)#minTrans", "Min. translation")
69 schema:register(XMLValueType.FLOAT, basePath .. ".sectionNodes.sectionNode(?)#minTransX", "Min. X translation")
70 schema:register(XMLValueType.VECTOR_TRANS, basePath .. ".sectionNodes.sectionNode(?)#maxTrans", "Max. translation")
71 schema:register(XMLValueType.FLOAT, basePath .. ".sectionNodes.sectionNode(?)#maxTransX", "Max. X translation")
72 schema:register(XMLValueType.VECTOR_ROT, basePath .. ".sectionNodes.sectionNode(?)#minRot", "Min. rotation")
73 schema:register(XMLValueType.VECTOR_ROT, basePath .. ".sectionNodes.sectionNode(?)#endRot", "Max. rotation")
74 schema:register(XMLValueType.INT, basePath .. ".sectionNodes.sectionNode(?)#workAreaIndex", "Work area index", 1)
75end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
266function VariableWorkWidth:saveToXMLFile(xmlFile, key, usedModNames)
267 local spec = self.spec_variableWorkWidth
268 if spec.hasSections then
269 xmlFile:setValue(key .. "#leftSide", spec.leftSide)
270 xmlFile:setValue(key .. "#rightSide", spec.rightSide)
271 end
272end

setSectionNodePercentage

Description
Definition
setSectionNodePercentage()
Code
363function VariableWorkWidth:setSectionNodePercentage(sectionNodes, percentage)
364 percentage = math.max(math.min(percentage, 1), 0)
365 for i=1, #sectionNodes do
366 local sectionNode = sectionNodes[i]
367
368 if sectionNode.startTrans ~= nil and sectionNode.endTrans ~= nil then
369 setTranslation(sectionNode.node, MathUtil.vector3ArrayLerp(sectionNode.startTrans, sectionNode.endTrans, percentage))
370 end
371
372 if sectionNode.startTransX ~= nil and sectionNode.endTransX ~= nil then
373 local _, y, z = getTranslation(sectionNode.node)
374 local x = MathUtil.lerp(sectionNode.startTransX, sectionNode.endTransX, percentage)
375 setTranslation(sectionNode.node, x, y, z)
376 end
377
378 if sectionNode.startRot ~= nil and sectionNode.endRot ~= nil then
379 setRotation(sectionNode.node, MathUtil.vector3ArrayLerp(sectionNode.startRot, sectionNode.endRot, percentage))
380 end
381
382 if sectionNode.workAreaIndex ~= nil then
383 self:updateWorkAreaWidth(sectionNode.workAreaIndex)
384 end
385 end
386end

setSectionsActive

Description
Definition
setSectionsActive()
Code
346function VariableWorkWidth:setSectionsActive(leftSide, rightSide, noEventSend)
347 local spec = self.spec_variableWorkWidth
348 leftSide = MathUtil.clamp(leftSide, 0, spec.leftSideMax)
349 rightSide = MathUtil.clamp(rightSide, 0, spec.rightSideMax)
350
351 if spec.leftSide ~= leftSide or spec.rightSide ~= rightSide then
352 spec.leftSide = leftSide
353 spec.rightSide = rightSide
354
355 self:updateSections()
356
357 VariableWorkWidthStateEvent.sendEvent(self, spec.leftSide, spec.rightSide, noEventSend)
358 end
359end

updateSections

Description
Definition
updateSections()
Code
390function VariableWorkWidth:updateSections()
391 local spec = self.spec_variableWorkWidth
392
393 self:updateSectionStates(spec.sectionsLeft, spec.leftSide)
394 self:updateSectionStates(spec.sectionsRight, spec.rightSide)
395
396 local leftSectionWidth = spec.leftSide == 0 and 0 or spec.sectionsLeft[spec.leftSide].width
397 self:setSectionNodePercentage(spec.sectionNodesLeft, leftSectionWidth)
398
399 local rightSectionWidth = spec.rightSide == 0 and 0 or spec.sectionsRight[spec.rightSide].width
400 self:setSectionNodePercentage(spec.sectionNodesRight, rightSectionWidth)
401
402 SpecializationUtil.raiseEvent(self, "onVariableWorkWidthSectionChanged")
403end

updateSectionStates

Description
Definition
updateSectionStates()
Code
407function VariableWorkWidth:updateSectionStates(sections, state)
408 for i=1, #sections do
409 local section = sections[i]
410 section.isActive = i <= state
411
412 for j=1, #section.effects do
413 local effect = section.effects[j]
414
415 if not section.isActive then
416 if effect:isRunning() then
417 effect:stop()
418 end
419 end
420 end
421 end
422end