LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

Cover

Description
Specialization for adding a toggleable cover with options to automatically react to tipping/triggers
Functions

actionEventToggleCover

Description
Definition
actionEventToggleCover()
Code
571function Cover.actionEventToggleCover(self, actionName, inputValue, callbackState, isAnalog)
572 local spec = self.spec_cover
573
574 local newState = spec.state + 1
575 if newState > #spec.covers then
576 newState = 0
577 end
578
579 if self:getIsNextCoverStateAllowed(newState) then
580 self:setCoverState(newState)
581 spec.isStateSetAutomatically = false
582 end
583end

aiFinishLoading

Description
Definition
aiFinishLoading()
Code
509function Cover:aiFinishLoading(superFunc, fillUnitIndex, task)
510 local spec = self.spec_cover
511 if spec.hasCovers then
512 self:setCoverState(0)
513 end
514
515 superFunc(self, fillUnitIndex, task)
516end

aiPrepareLoading

Description
Definition
aiPrepareLoading()
Code
498function Cover:aiPrepareLoading(superFunc, fillUnitIndex, task)
499 local cover = self:getCoverByFillUnitIndex(fillUnitIndex)
500 if cover ~= nil then
501 self:setCoverState(cover.index)
502 end
503
504 superFunc(self, fillUnitIndex, task)
505end

finishedAIDischarge

Description
Definition
finishedAIDischarge()
Code
487function Cover:finishedAIDischarge(superFunc)
488 local spec = self.spec_cover
489 if spec.hasCovers then
490 self:setCoverState(0)
491 end
492
493 superFunc(self)
494end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
404function Cover:getCanBeSelected(superFunc)
405 return true
406end

getCoverByFillUnitIndex

Description
Definition
getCoverByFillUnitIndex()
Code
359function Cover:getCoverByFillUnitIndex(fillUnitIndex)
360 local covers = self.spec_cover.fillUnitIndexToCovers[fillUnitIndex]
361 if covers ~= nil then
362 return covers[1]
363 end
364
365 return nil
366end

getFillUnitSupportsToolType

Description
Definition
getFillUnitSupportsToolType()
Code
376function Cover:getFillUnitSupportsToolType(superFunc, fillUnitIndex, toolType)
377 local spec = self.spec_cover
378
379 if spec.hasCovers then
380 local covers = spec.fillUnitIndexToCovers[fillUnitIndex]
381 if covers ~= nil and #covers > 0 then
382 local isOpen = false
383 for i=1, #covers do
384 local cover = covers[i]
385 if spec.state == cover.index then
386 isOpen = true
387 break
388 end
389 end
390
391 if not isOpen then
392 if covers[1].blockedToolTypes[toolType] then
393 return false
394 end
395 end
396 end
397 end
398
399 return superFunc(self, fillUnitIndex, toolType)
400end

getIsNextCoverStateAllowed

Description
Definition
getIsNextCoverStateAllowed()
Code
370function Cover:getIsNextCoverStateAllowed(nextState)
371 return true
372end

getIsPipeStateChangeAllowed

Description
Definition
getIsPipeStateChangeAllowed()
Code
420function Cover:getIsPipeStateChangeAllowed(superFunc)
421 if not superFunc(self) then
422 return false
423 end
424
425 local spec = self.spec_pipe
426 local specCover = self.spec_cover
427 if specCover.state < spec.coverMinState or specCover.state > spec.coverMaxState then
428 return false
429 end
430
431 return true
432end

initSpecialization

Description
Definition
initSpecialization()
Code
27function Cover.initSpecialization()
28 g_configurationManager:addConfigurationType("cover", g_i18n:getText("configuration_cover"), "cover", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
29
30 local schema = Vehicle.xmlSchema
31 schema:setXMLSpecializationType("Cover")
32
33 schema:register(XMLValueType.STRING, Cover.COVER_XML_KEY .. "#openAnimation", "Open animation name")
34 schema:register(XMLValueType.FLOAT, Cover.COVER_XML_KEY .. "#openAnimationStopTime", "Open animation stop time")
35 schema:register(XMLValueType.FLOAT, Cover.COVER_XML_KEY .. "#openAnimationStartTime", "Open animation start time")
36 schema:register(XMLValueType.STRING, Cover.COVER_XML_KEY .. "#closeAnimation", "Close animation name")
37 schema:register(XMLValueType.FLOAT, Cover.COVER_XML_KEY .. "#closeAnimationStopTime", "Close animation stop time")
38 schema:register(XMLValueType.BOOL, Cover.COVER_XML_KEY .. "#openOnBuy", "Open after buying", false)
39 schema:register(XMLValueType.BOOL, Cover.COVER_XML_KEY .. "#forceOpenOnTip", "Open while tipping", true)
40 schema:register(XMLValueType.BOOL, Cover.COVER_XML_KEY .. "#autoReactToTrigger", "Automatically open in triggers", true)
41 schema:register(XMLValueType.VECTOR_N, Cover.COVER_XML_KEY .. "#fillUnitIndices", "Fill unit indices to cover")
42 schema:register(XMLValueType.STRING, Cover.COVER_XML_KEY .. "#blockedToolTypes", "List with blocked tool types", "dischargeable bale trigger pallet")
43
44 schema:register(XMLValueType.BOOL, "vehicle.cover.coverConfigurations.coverConfiguration(?)#closeCoverIfNotAllowed", "Close cover if not allowed to open it", false)
45 schema:register(XMLValueType.BOOL, "vehicle.cover.coverConfigurations.coverConfiguration(?)#openCoverWhileTipping", "Open cover while tipping", false)
46 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.cover.coverConfigurations.coverConfiguration(?)")
47
48 schema:register(XMLValueType.INT, "vehicle.pipe#coverMinState", "Min. cover state to allow pipe state change", 0)
49 schema:register(XMLValueType.INT, "vehicle.pipe#coverMaxState", "Max. cover state to allow pipe state change", "Max. cover state")
50
51 schema:setXMLSpecializationType()
52
53 local schemaSavegame = Vehicle.xmlSchemaSavegame
54 schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).cover#state", "Current cover state")
55end

loadCoverFromXML

Description
Definition
loadCoverFromXML()
Code
265function Cover:loadCoverFromXML(xmlFile, key, cover)
266 cover.openAnimation = xmlFile:getValue(key.."#openAnimation")
267 cover.openAnimationStartTime = xmlFile:getValue(key.."#openAnimationStartTime")
268 cover.openAnimationStopTime = xmlFile:getValue(key.."#openAnimationStopTime")
269
270 if cover.openAnimation == nil then
271 Logging.xmlWarning(self.xmlFile, "Missing 'openAnimation' for cover '%s'!", key)
272 return false
273 end
274
275 cover.closeAnimation = xmlFile:getValue(key.."#closeAnimation")
276 cover.closeAnimationStopTime = xmlFile:getValue(key.."#closeAnimationStopTime")
277
278 cover.startOpenState = xmlFile:getValue(key.."#openOnBuy", false)
279 cover.forceOpenOnTip = xmlFile:getValue(key.."#forceOpenOnTip", true)
280 cover.autoReactToTrigger = xmlFile:getValue(key.."#autoReactToTrigger", true)
281
282 cover.fillUnitIndices = xmlFile:getValue(key.."#fillUnitIndices", nil, true)
283 if cover.fillUnitIndices == nil then
284 Logging.xmlWarning(self.xmlFile, "Missing 'fillUnitIndices' for cover '%s'!", key)
285 return false
286 end
287
288 cover.blockedToolTypes = {}
289
290 local strBlockedToolTypes = xmlFile:getValue(key.."#blockedToolTypes", "dischargeable bale trigger pallet")
291 strBlockedToolTypes = strBlockedToolTypes:trim():split(" ")
292 for _, toolType in ipairs(strBlockedToolTypes) do
293 local index = g_toolTypeManager:getToolTypeIndexByName(toolType)
294 if index ~= ToolType.UNDEFINED then
295 cover.blockedToolTypes[index] = true
296 end
297 end
298
299 return true
300end

loadPipeNodes

Description
Definition
loadPipeNodes()
Code
410function Cover:loadPipeNodes(superFunc, pipeNodes, xmlFile, baseKey)
411 superFunc(self, pipeNodes, xmlFile, baseKey)
412
413 local spec = self.spec_pipe
414 spec.coverMinState = xmlFile:getValue("vehicle.pipe#coverMinState", 0)
415 spec.coverMaxState = xmlFile:getValue("vehicle.pipe#coverMaxState", #self.spec_cover.covers)
416end

onFillUnitTriggerChanged

Description
Definition
onFillUnitTriggerChanged()
Code
520function Cover:onFillUnitTriggerChanged(fillTrigger, fillTypeIndex, fillUnitIndex, numTriggers)
521 local spec = self.spec_cover
522 local covers = spec.fillUnitIndexToCovers[fillUnitIndex]
523 if covers ~= nil then
524 local isDifferentState = true
525 for _, cover in pairs(covers) do
526 isDifferentState = isDifferentState and spec.state ~= cover.index
527 end
528
529 local isStateChangedAllowed = self:getIsNextCoverStateAllowed(covers[1].index)
530 if covers[1].autoReactToTrigger and isDifferentState and isStateChangedAllowed then
531 self:setCoverState(covers[1].index, true)
532 spec.isStateSetAutomatically = true
533 end
534 end
535end

onLoad

Description
Definition
onLoad()
Code
96function Cover:onLoad(savegame)
97 local spec = self.spec_cover
98
99 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.cover#animationName", "vehicle.cover.coverConfigurations.coverConfiguration.cover#openAnimation") --FS17 to FS19
100 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.foldable.foldingParts#closeCoverOnFold", "vehicle.cover.coverConfigurations.coverConfiguration.cover#closeCoverIfNotAllowed") --FS17 to FS19
101
102 local coverConfigurationId = Utils.getNoNil(self.configurations["cover"], 1)
103 local configKey = string.format("vehicle.cover.coverConfigurations.coverConfiguration(%d)", coverConfigurationId -1)
104 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.cover.coverConfigurations.coverConfiguration", coverConfigurationId , self.components, self)
105
106 spec.state = 0
107 spec.runningAnimations = {}
108 spec.covers = {}
109 spec.fillUnitIndexToCovers = {}
110 spec.isStateSetAutomatically = false
111 local i = 0
112 while true do
113 local key = string.format("%s.cover(%d)", configKey, i)
114 if not self.xmlFile:hasProperty(key) then
115 break
116 end
117
118 local cover = {}
119 if self:loadCoverFromXML(self.xmlFile, key, cover) then
120 for j=#cover.fillUnitIndices, 1, -1 do
121 local index = cover.fillUnitIndices[j]
122
123 if spec.fillUnitIndexToCovers[index] == nil then
124 spec.fillUnitIndexToCovers[index] = {cover}
125 else
126 table.insert(spec.fillUnitIndexToCovers[index], cover)
127 end
128 end
129
130 table.insert(spec.covers, cover)
131 cover.index = #spec.covers
132 end
133
134 i = i + 1
135 end
136
137 spec.closeCoverIfNotAllowed = self.xmlFile:getValue(configKey.."#closeCoverIfNotAllowed", false)
138 spec.openCoverWhileTipping = self.xmlFile:getValue(configKey.."#openCoverWhileTipping", false)
139
140 spec.hasCovers = #spec.covers > 0
141 spec.isDirty = false
142
143 if not spec.hasCovers then
144 SpecializationUtil.removeEventListener(self, "onReadStream", Cover)
145 SpecializationUtil.removeEventListener(self, "onWriteStream", Cover)
146 SpecializationUtil.removeEventListener(self, "onUpdate", Cover)
147 SpecializationUtil.removeEventListener(self, "onRegisterActionEvents", Cover)
148 SpecializationUtil.removeEventListener(self, "onStartTipping", Cover)
149 SpecializationUtil.removeEventListener(self, "onFillUnitTriggerChanged", Cover)
150 SpecializationUtil.removeEventListener(self, "onRemovedFillUnitTrigger", Cover)
151 end
152end

onOpenBackDoor

Description
Definition
onOpenBackDoor()
Code
471function Cover:onOpenBackDoor(tipSide)
472 if self.spec_cover.openCoverWhileTipping then
473 local trailerSpec = self.spec_trailer
474
475 local tipSideDesc = trailerSpec.tipSides[tipSide]
476 local dischargeNode = self:getDischargeNodeByIndex(tipSideDesc.dischargeNodeIndex)
477
478 local cover = self:getCoverByFillUnitIndex(dischargeNode.fillUnitIndex)
479 if cover ~= nil then
480 self:setCoverState(cover.index, true)
481 end
482 end
483end

onPostLoad

Description
Definition
onPostLoad()
Code
156function Cover:onPostLoad(savegame)
157 local spec = self.spec_cover
158 if spec.hasCovers then
159 local state = 0
160 if savegame ~= nil then
161 state = savegame.xmlFile:getValue(savegame.key..".cover#state", state)
162 else
163 for i=1, #spec.covers do
164 local cover = spec.covers[i]
165 if cover.startOpenState then
166 state = i
167 end
168 end
169 end
170
171 if state == 0 then
172 -- set last state to max cover state to run the close animation of the last state. So we make sure the cover animations are at the currect time
173 spec.state = #spec.covers
174 end
175
176 self:setCoverState(state, true)
177 for i=#spec.runningAnimations, 1, -1 do
178 local animation = spec.runningAnimations[i]
179 AnimatedVehicle.updateAnimationByName(self, animation.name, 9999999, true)
180 table.remove(spec.runningAnimations, i)
181 end
182 spec.isDirty = false
183 end
184end

onReadStream

Description
Definition
onReadStream()
Code
198function Cover:onReadStream(streamId, connection)
199 if connection:getIsServer() then
200 local spec = self.spec_cover
201 local state = streamReadUIntN(streamId, Cover.SEND_NUM_BITS)
202 self:setCoverState(state, true)
203
204 for i=#spec.runningAnimations, 1, -1 do
205 local animation = spec.runningAnimations[i]
206 AnimatedVehicle.updateAnimationByName(self, animation.name, 9999999, true)
207 table.remove(spec.runningAnimations, i)
208 end
209 spec.isDirty = false
210 end
211end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
436function Cover:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
437 if self.isClient then
438 local spec = self.spec_cover
439 self:clearActionEventsTable(spec.actionEvents)
440
441 if isActiveForInputIgnoreSelection then
442 local state, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_COVER, self, Cover.actionEventToggleCover, false, true, false, true, nil, nil, true, true)
443 if not state then
444 local _
445 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA4, self, Cover.actionEventToggleCover, false, true, false, true, nil, nil, true, true)
446 end
447 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
448 Cover.updateActionText(self)
449 end
450 end
451end

onRemovedFillUnitTrigger

Description
Definition
onRemovedFillUnitTrigger()
Code
539function Cover:onRemovedFillUnitTrigger(numTriggers)
540 local spec = self.spec_cover
541 if numTriggers == 0 then
542 local cover = spec.covers[spec.state]
543 if cover ~= nil and spec.isStateSetAutomatically and cover.autoReactToTrigger then
544 self:setCoverState(0, true)
545 spec.isStateSetAutomatically = false
546 end
547 end
548end

onStartTipping

Description
Definition
onStartTipping()
Code
455function Cover:onStartTipping(tipSide)
456 if self.spec_cover.openCoverWhileTipping then
457 local trailerSpec = self.spec_trailer
458
459 local tipSideDesc = trailerSpec.tipSides[tipSide]
460 local dischargeNode = self:getDischargeNodeByIndex(tipSideDesc.dischargeNodeIndex)
461
462 local cover = self:getCoverByFillUnitIndex(dischargeNode.fillUnitIndex)
463 if cover ~= nil then
464 self:setCoverState(cover.index, true)
465 end
466 end
467end

onUpdate

Description
Definition
onUpdate()
Code
223function Cover:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
224 local spec = self.spec_cover
225 if spec.isDirty then
226 local animation = spec.runningAnimations[1]
227 if animation ~= nil then
228 local nextAnim = spec.runningAnimations[2]
229 -- if next animation is same as current animation, we stop the current animation and play the next
230 if nextAnim ~= nil and nextAnim.name == animation.name then
231 table.remove(spec.runningAnimations, 1)
232 self:stopAnimation(animation.name, true)
233 self:playCoverAnimation(nextAnim)
234 end
235
236 -- check if current animation is playing. if not play next
237 if not self:getIsAnimationPlaying(animation.name) then
238 table.remove(spec.runningAnimations, 1)
239 local nextAnimation = spec.runningAnimations[1]
240 if nextAnimation ~= nil then
241 self:playCoverAnimation(nextAnimation)
242 else
243 spec.isDirty = false
244 end
245 end
246 end
247 end
248
249 if spec.closeCoverIfNotAllowed then
250 if spec.state ~= 0 then
251 local newState = spec.state + 1
252 if newState > #spec.covers then
253 newState = 0
254 end
255
256 if not self:getIsNextCoverStateAllowed(newState) then
257 self:setCoverState(0, true)
258 end
259 end
260 end
261end

onWriteStream

Description
Definition
onWriteStream()
Code
215function Cover:onWriteStream(streamId, connection)
216 if not connection:getIsServer() then
217 streamWriteUIntN(streamId, self.spec_cover.state, Cover.SEND_NUM_BITS)
218 end
219end

playCoverAnimation

Description
Definition
playCoverAnimation()
Code
347function Cover:playCoverAnimation(animation)
348 if animation.startTime ~= nil then
349 self:setAnimationTime(animation.name, animation.startTime, true)
350 end
351
352 local dir = MathUtil.sign(animation.stopTime - self:getAnimationTime(animation.name))
353 self:setAnimationStopTime(animation.name, animation.stopTime)
354 self:playAnimation(animation.name, dir, animation.startTime or self:getAnimationTime(animation.name), true)
355end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
21function Cover.prerequisitesPresent(specializations)
22 return SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations)
23end

registerEventListeners

Description
Definition
registerEventListeners()
Code
81function Cover.registerEventListeners(vehicleType)
82 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Cover)
83 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Cover)
84 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Cover)
85 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Cover)
86 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Cover)
87 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Cover)
88 SpecializationUtil.registerEventListener(vehicleType, "onStartTipping", Cover)
89 SpecializationUtil.registerEventListener(vehicleType, "onOpenBackDoor", Cover)
90 SpecializationUtil.registerEventListener(vehicleType, "onFillUnitTriggerChanged", Cover)
91 SpecializationUtil.registerEventListener(vehicleType, "onRemovedFillUnitTrigger", Cover)
92end

registerFunctions

Description
Definition
registerFunctions()
Code
59function Cover.registerFunctions(vehicleType)
60 SpecializationUtil.registerFunction(vehicleType, "loadCoverFromXML", Cover.loadCoverFromXML)
61 SpecializationUtil.registerFunction(vehicleType, "getIsNextCoverStateAllowed", Cover.getIsNextCoverStateAllowed)
62 SpecializationUtil.registerFunction(vehicleType, "setCoverState", Cover.setCoverState)
63 SpecializationUtil.registerFunction(vehicleType, "playCoverAnimation", Cover.playCoverAnimation)
64 SpecializationUtil.registerFunction(vehicleType, "getCoverByFillUnitIndex", Cover.getCoverByFillUnitIndex)
65end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
69function Cover.registerOverwrittenFunctions(vehicleType)
70 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillUnitSupportsToolType", Cover.getFillUnitSupportsToolType)
71 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Cover.getCanBeSelected)
72 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadPipeNodes", Cover.loadPipeNodes)
73 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsPipeStateChangeAllowed", Cover.getIsPipeStateChangeAllowed)
74 SpecializationUtil.registerOverwrittenFunction(vehicleType, "aiPrepareLoading", Cover.aiPrepareLoading)
75 SpecializationUtil.registerOverwrittenFunction(vehicleType, "aiFinishLoading", Cover.aiFinishLoading)
76 SpecializationUtil.registerOverwrittenFunction(vehicleType, "finishedAIDischarge", Cover.finishedAIDischarge)
77end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
188function Cover:saveToXMLFile(xmlFile, key, usedModNames)
189 local spec = self.spec_cover
190
191 if spec.hasCovers then
192 xmlFile:setValue(key.."#state", spec.state)
193 end
194end

setCoverState

Description
Definition
setCoverState()
Code
304function Cover:setCoverState(state, noEventSend)
305 local spec = self.spec_cover
306
307 if spec.hasCovers and state >= 0 and state <= #spec.covers and spec.state ~= state then
308 SetCoverStateEvent.sendEvent(self, state, noEventSend)
309
310 local startAnim = #spec.runningAnimations == 0
311
312 -- check if we need to close previous cover
313 if spec.state > 0 then
314 local cover = spec.covers[spec.state]
315 local animation = cover.closeAnimation
316 local stopTime = cover.closeAnimationStopTime or 1
317
318 if animation == nil then
319 animation = cover.openAnimation
320 stopTime = cover.openAnimationStopTime or 0
321 end
322
323 if self:getAnimationExists(animation) then
324 table.insert(spec.runningAnimations, {name=animation, stopTime=stopTime})
325 end
326 end
327
328 -- open next cover if state is not 'All-closed' (0)
329 if state > 0 then
330 local cover = spec.covers[state]
331 table.insert(spec.runningAnimations, {name=cover.openAnimation, startTime=cover.openAnimationStartTime, stopTime=cover.openAnimationStopTime or 1})
332 end
333
334 spec.state = state
335 spec.isDirty = #spec.runningAnimations > 0
336
337 if startAnim and #spec.runningAnimations > 0 then
338 self:playCoverAnimation(spec.runningAnimations[1])
339 end
340
341 Cover.updateActionText(self)
342 end
343end

updateActionText

Description
Definition
updateActionText()
Code
552function Cover.updateActionText(self)
553 local spec = self.spec_cover
554 if next(spec.actionEvents) ~= nil then
555 local actionEvent = spec.actionEvents[next(spec.actionEvents)]
556 if actionEvent ~= nil then
557 local text = g_i18n:getText("action_nextCover")
558 if spec.state == #spec.covers then
559 text = g_i18n:getText("action_closeCover")
560 elseif spec.state == 0 then
561 text = g_i18n:getText("action_openCover")
562 end
563
564 g_inputBinding:setActionEventText(actionEvent.actionEventId, text)
565 end
566 end
567end