LUADOC - Farming Simulator 19

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
455function Cover.actionEventToggleCover(self, actionName, inputValue, callbackState, isAnalog)
456 local spec = self.spec_cover
457
458 local newState = spec.state + 1
459 if newState > #spec.covers then
460 newState = 0
461 end
462
463 if self:getIsNextCoverStateAllowed(newState) then
464 self:setCoverState(newState)
465 spec.isStateSetAutomatically = false
466 end
467end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
344function Cover:getCanBeSelected(superFunc)
345 return true
346end

getCoverByFillUnitIndex

Description
Definition
getCoverByFillUnitIndex()
Code
313function Cover:getCoverByFillUnitIndex(fillUnitIndex)
314 return self.spec_cover.fillUnitIndexToCover[fillUnitIndex]
315end

getFillUnitSupportsToolType

Description
Definition
getFillUnitSupportsToolType()
Code
325function Cover:getFillUnitSupportsToolType(superFunc, fillUnitIndex, toolType)
326 local spec = self.spec_cover
327
328 if spec.hasCovers then
329 local cover = spec.fillUnitIndexToCover[fillUnitIndex]
330 if cover ~= nil then
331 if spec.state ~= cover.index then
332 if cover.blockedToolTypes[toolType] then
333 return false
334 end
335 end
336 end
337 end
338
339 return superFunc(self, fillUnitIndex, toolType)
340end

getIsNextCoverStateAllowed

Description
Definition
getIsNextCoverStateAllowed()
Code
319function Cover:getIsNextCoverStateAllowed(nextState)
320 return true
321end

getIsPipeStateChangeAllowed

Description
Definition
getIsPipeStateChangeAllowed()
Code
360function Cover:getIsPipeStateChangeAllowed(superFunc)
361 if not superFunc(self) then
362 return false
363 end
364
365 local spec = self.spec_pipe
366 local specCover = self.spec_cover
367 if specCover.state < spec.coverMinState or specCover.state > spec.coverMaxState then
368 return false
369 end
370
371 return true
372end

initSpecialization

Description
Definition
initSpecialization()
Code
58function Cover.initSpecialization()
59 g_configurationManager:addConfigurationType("cover", g_i18n:getText("configuration_cover"), "cover", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
60end

loadCoverFromXML

Description
Definition
loadCoverFromXML()
Code
222function Cover:loadCoverFromXML(xmlFile, key, cover)
223 cover.openAnimation = getXMLString(xmlFile, key.."#openAnimation")
224 cover.openAnimationStopTime = getXMLFloat(xmlFile, key.."#openAnimationStopTime")
225
226 if cover.openAnimation == nil then
227 g_logManager:xmlWarning(self.configFileName, "Missing 'openAnimation' for cover '%s'!", key)
228 return false
229 end
230
231 cover.closeAnimation = getXMLString(xmlFile, key.."#closeAnimation")
232 cover.closeAnimationStopTime = getXMLFloat(xmlFile, key.."#closeAnimationStopTime")
233
234 cover.startOpenState = Utils.getNoNil(getXMLBool(xmlFile, key.."#openOnBuy"), false)
235 cover.forceOpenOnTip = Utils.getNoNil(getXMLBool(xmlFile, key.."#forceOpenOnTip"), true)
236 cover.autoReactToTrigger = Utils.getNoNil(getXMLBool(xmlFile, key.."#autoReactToTrigger"), true)
237
238 local indices = getXMLString(xmlFile, key.."#fillUnitIndices")
239 if indices == nil then
240 g_logManager:xmlWarning(self.configFileName, "Missing 'fillUnitIndices' for cover '%s'!", key)
241 return false
242 end
243
244 cover.fillUnitIndices = {StringUtil.getVectorFromString(indices)}
245 cover.blockedToolTypes = {}
246
247 local strBlockedToolTypes = Utils.getNoNil(getXMLString(xmlFile, key.."#blockedToolTypes"), "dischargeable bale trigger")
248 strBlockedToolTypes = StringUtil.splitString(" ", StringUtil.trim(strBlockedToolTypes))
249 for _, toolType in ipairs(strBlockedToolTypes) do
250 local index = g_toolTypeManager:getToolTypeIndexByName(toolType)
251 if index ~= ToolType.UNDEFINED then
252 cover.blockedToolTypes[index] = true
253 end
254 end
255
256 return true
257end

loadPipeNodes

Description
Definition
loadPipeNodes()
Code
350function Cover:loadPipeNodes(superFunc, pipeNodes, xmlFile, baseKey)
351 superFunc(self, pipeNodes, xmlFile, baseKey)
352
353 local spec = self.spec_pipe
354 spec.coverMinState = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.pipe#coverMinState"), 0)
355 spec.coverMaxState = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.pipe#coverMaxState"), #self.spec_cover.covers)
356end

onAddedFillUnitTrigger

Description
Definition
onAddedFillUnitTrigger()
Code
407function Cover:onAddedFillUnitTrigger(fillTypeIndex, fillUnitIndex, numTriggers)
408 local spec = self.spec_cover
409 if spec.hasCovers then
410 local cover = spec.fillUnitIndexToCover[fillUnitIndex]
411 if cover ~= nil then
412 local isDifferentState = spec.state ~= cover.index
413 local isStateChangedAllowed = self:getIsNextCoverStateAllowed(cover.index)
414 if cover.autoReactToTrigger and isDifferentState and isStateChangedAllowed then
415 self:setCoverState(cover.index, true)
416 spec.isStateSetAutomatically = true
417 end
418 end
419 end
420end

onLoad

Description
Definition
onLoad()
Code
64function Cover:onLoad(savegame)
65 local spec = self.spec_cover
66
67 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.cover#animationName", "vehicle.cover.coverConfigurations.coverConfiguration.cover#openAnimation") --FS17 to FS19
68 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.foldable.foldingParts#closeCoverOnFold", "vehicle.cover.coverConfigurations.coverConfiguration.cover#closeCoverIfNotAllowed") --FS17 to FS19
69
70 local coverConfigurationId = Utils.getNoNil(self.configurations["cover"], 1)
71 local configKey = string.format("vehicle.cover.coverConfigurations.coverConfiguration(%d)", coverConfigurationId -1)
72 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.cover.coverConfigurations.coverConfiguration", coverConfigurationId , self.components, self)
73
74 spec.state = 0
75 spec.runningAnimations = {}
76 spec.covers = {}
77 spec.fillUnitIndexToCover = {}
78 spec.isStateSetAutomatically = false
79 local i = 0
80 while true do
81 local key = string.format("%s.cover(%d)", configKey, i)
82 if not hasXMLProperty(self.xmlFile, key) then
83 break
84 end
85
86 local cover = {}
87 if self:loadCoverFromXML(self.xmlFile, key, cover) then
88 for j=#cover.fillUnitIndices, 1, -1 do
89 local index = cover.fillUnitIndices[j]
90
91 if spec.fillUnitIndexToCover[index] == nil then
92 spec.fillUnitIndexToCover[index] = cover
93 else
94 table.remove(cover.fillUnitIndices, j)
95 g_logManager:xmlWarning(self.configFileName, "FillUnit '%d' for cover '%s' is already used by another cover. Only one cover per fillUnit is allowed. Ignoring it!", i, key)
96 end
97 end
98
99 table.insert(spec.covers, cover)
100 cover.index = #spec.covers
101 end
102
103 i = i + 1
104 end
105
106 spec.closeCoverIfNotAllowed = Utils.getNoNil(getXMLBool(self.xmlFile, configKey.."#closeCoverIfNotAllowed"), false)
107 spec.openCoverWhileTipping = Utils.getNoNil(getXMLBool(self.xmlFile, configKey.."#openCoverWhileTipping"), false)
108
109 spec.hasCovers = #spec.covers > 0
110 spec.isDirty = false
111end

onPostLoad

Description
Definition
onPostLoad()
Code
115function Cover:onPostLoad(savegame)
116 local spec = self.spec_cover
117 if spec.hasCovers then
118 local state = 0
119 if savegame ~= nil then
120 state = getXMLInt(savegame.xmlFile, savegame.key..".cover#state") or state
121 end
122
123 if state == 0 then
124 -- 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
125 spec.state = table.getn(spec.covers)
126 end
127
128 self:setCoverState(state, true)
129 for i=#spec.runningAnimations, 1, -1 do
130 local animation = spec.runningAnimations[i]
131 AnimatedVehicle.updateAnimationByName(self, animation.name, 9999999)
132 table.remove(spec.runningAnimations, i)
133 end
134 spec.isDirty = false
135 end
136end

onReadStream

Description
Definition
onReadStream()
Code
150function Cover:onReadStream(streamId, connection)
151 if connection:getIsServer() then
152 local spec = self.spec_cover
153 if spec.hasCovers then
154 local state = streamReadUIntN(streamId, Cover.SEND_NUM_BITS)
155 self:setCoverState(state, true)
156
157 for i=#spec.runningAnimations, 1, -1 do
158 local animation = spec.runningAnimations[i]
159 AnimatedVehicle.updateAnimationByName(self, animation.name, 9999999)
160 table.remove(spec.runningAnimations, i)
161 end
162 spec.isDirty = false
163 end
164 end
165end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
376function Cover:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
377 if self.isClient then
378 local spec = self.spec_cover
379 self:clearActionEventsTable(spec.actionEvents)
380
381 if isActiveForInputIgnoreSelection and spec.hasCovers then
382 local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_COVER, self, Cover.actionEventToggleCover, false, true, false, true, nil)
383 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
384 Cover.updateActionText(self)
385 end
386 end
387end

onRemovedFillUnitTrigger

Description
Definition
onRemovedFillUnitTrigger()
Code
424function Cover:onRemovedFillUnitTrigger(numTriggers)
425 local spec = self.spec_cover
426 if spec.hasCovers and numTriggers == 0 then
427 local cover = spec.covers[spec.state]
428 if cover ~= nil and spec.isStateSetAutomatically and cover.autoReactToTrigger then
429 self:setCoverState(0, true)
430 spec.isStateSetAutomatically = false
431 end
432 end
433end

onStartTipping

Description
Definition
onStartTipping()
Code
391function Cover:onStartTipping(tipSide)
392 if self.spec_cover.openCoverWhileTipping then
393 local trailerSpec = self.spec_trailer
394
395 local tipSideDesc = trailerSpec.tipSides[tipSide]
396 local dischargeNode = self:getDischargeNodeByIndex(tipSideDesc.dischargeNodeIndex)
397
398 local cover = self:getCoverByFillUnitIndex(dischargeNode.fillUnitIndex)
399 if cover ~= nil then
400 self:setCoverState(cover.index, true)
401 end
402 end
403end

onUpdate

Description
Definition
onUpdate()
Code
180function Cover:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
181 local spec = self.spec_cover
182 if spec.isDirty then
183 local animation = spec.runningAnimations[1]
184 if animation ~= nil then
185 local nextAnim = spec.runningAnimations[2]
186 -- if next animation is same as current animation, we stop the current animation and play the next
187 if nextAnim ~= nil and nextAnim.name == animation.name then
188 table.remove(spec.runningAnimations, 1)
189 self:stopAnimation(animation.name, true)
190 self:playCoverAnimation(nextAnim)
191 end
192
193 -- check if current animation is playing. if not play next
194 if not self:getIsAnimationPlaying(animation.name) then
195 table.remove(spec.runningAnimations, 1)
196 local nextAnimation = spec.runningAnimations[1]
197 if nextAnimation ~= nil then
198 self:playCoverAnimation(nextAnimation)
199 else
200 spec.isDirty = false
201 end
202 end
203 end
204 end
205
206 if spec.closeCoverIfNotAllowed then
207 if spec.state ~= 0 then
208 local newState = spec.state + 1
209 if newState > #spec.covers then
210 newState = 0
211 end
212
213 if not self:getIsNextCoverStateAllowed(newState) then
214 self:setCoverState(0, true)
215 end
216 end
217 end
218end

onWriteStream

Description
Definition
onWriteStream()
Code
169function Cover:onWriteStream(streamId, connection)
170 if not connection:getIsServer() then
171 local spec = self.spec_cover
172 if spec.hasCovers then
173 streamWriteUIntN(streamId, spec.state, Cover.SEND_NUM_BITS)
174 end
175 end
176end

playCoverAnimation

Description
Definition
playCoverAnimation()
Code
305function Cover:playCoverAnimation(animation)
306 local dir = MathUtil.sign(animation.stopTime - self:getAnimationTime(animation.name))
307 self:setAnimationStopTime(animation.name, animation.stopTime)
308 self:playAnimation(animation.name, dir, self:getAnimationTime(animation.name), true)
309end

prerequisitesPresent

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

registerEventListeners

Description
Definition
registerEventListeners()
Code
44function Cover.registerEventListeners(vehicleType)
45 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Cover)
46 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Cover)
47 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Cover)
48 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Cover)
49 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Cover)
50 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Cover)
51 SpecializationUtil.registerEventListener(vehicleType, "onStartTipping", Cover)
52 SpecializationUtil.registerEventListener(vehicleType, "onAddedFillUnitTrigger", Cover)
53 SpecializationUtil.registerEventListener(vehicleType, "onRemovedFillUnitTrigger", Cover)
54end

registerFunctions

Description
Definition
registerFunctions()
Code
25function Cover.registerFunctions(vehicleType)
26 SpecializationUtil.registerFunction(vehicleType, "loadCoverFromXML", Cover.loadCoverFromXML)
27 SpecializationUtil.registerFunction(vehicleType, "getIsNextCoverStateAllowed", Cover.getIsNextCoverStateAllowed)
28 SpecializationUtil.registerFunction(vehicleType, "setCoverState", Cover.setCoverState)
29 SpecializationUtil.registerFunction(vehicleType, "playCoverAnimation", Cover.playCoverAnimation)
30 SpecializationUtil.registerFunction(vehicleType, "getCoverByFillUnitIndex", Cover.getCoverByFillUnitIndex)
31end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
35function Cover.registerOverwrittenFunctions(vehicleType)
36 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillUnitSupportsToolType", Cover.getFillUnitSupportsToolType)
37 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Cover.getCanBeSelected)
38 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadPipeNodes", Cover.loadPipeNodes)
39 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsPipeStateChangeAllowed", Cover.getIsPipeStateChangeAllowed)
40end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
140function Cover:saveToXMLFile(xmlFile, key, usedModNames)
141 local spec = self.spec_cover
142
143 if spec.hasCovers then
144 setXMLInt(xmlFile, key.."#state", spec.state)
145 end
146end

setCoverState

Description
Definition
setCoverState()
Code
261function Cover:setCoverState(state, noEventSend)
262 local spec = self.spec_cover
263
264 if spec.hasCovers and state >= 0 and state <= #spec.covers then
265
266 SetCoverStateEvent.sendEvent(self, state, noEventSend)
267
268 local startAnim = #spec.runningAnimations == 0
269
270 -- check if we need to close previous cover
271 if spec.state > 0 then
272 local cover = spec.covers[spec.state]
273 local animation = cover.closeAnimation
274 local stopTime = cover.closeAnimationStopTime or 1
275
276 if animation == nil then
277 animation = cover.openAnimation
278 stopTime = cover.openAnimationStopTime or 0
279 end
280
281 if self:getAnimationExists(animation) then
282 table.insert(spec.runningAnimations, {name=animation, stopTime=stopTime})
283 end
284 end
285
286 -- open next cover if state is not 'All-closed' (0)
287 if state > 0 then
288 local cover = spec.covers[state]
289 table.insert(spec.runningAnimations, {name=cover.openAnimation, stopTime=cover.openAnimationStopTime or 1})
290 end
291
292 spec.state = state
293 spec.isDirty = #spec.runningAnimations > 0
294
295 if startAnim and #spec.runningAnimations > 0 then
296 self:playCoverAnimation(spec.runningAnimations[1])
297 end
298
299 Cover.updateActionText(self)
300 end
301end

updateActionText

Description
Definition
updateActionText()
Code
437function Cover.updateActionText(self)
438 local spec = self.spec_cover
439 local actionEvent = spec.actionEvents[InputAction.TOGGLE_COVER]
440
441 if actionEvent ~= nil then
442 local text = g_i18n:getText("action_nextCover")
443 if spec.state == #spec.covers then
444 text = g_i18n:getText("action_closeCover")
445 elseif spec.state == 0 then
446 text = g_i18n:getText("action_openCover")
447 end
448
449 g_inputBinding:setActionEventText(actionEvent.actionEventId, text)
450 end
451end