LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

Washable

Description
Specialization for vehicles which can get dirty and be cleaned by a pressure washer
Functions

addAllSubWashableNodes

Description
Definition
addAllSubWashableNodes()
Code
273function Washable:addAllSubWashableNodes(rootNode)
274 if rootNode ~= nil then
275 local nodes = {}
276 I3DUtil.getNodesByShaderParam(rootNode, "RDT", nodes, true)
277 self:addWashableNodes(nodes)
278 end
279
280 -- if we are done with adding new nodes we apply the last dirt amount to all nodes
281 self:addDirtAmount(0, true)
282end

addDirtAmount

Description
Definition
addDirtAmount()
Code
236function Washable:addDirtAmount(dirtAmount, force)
237 local spec = self.spec_washable
238 if spec.washableNodes ~= nil then
239 for _, nodeData in ipairs(spec.washableNodes) do
240 self:setNodeDirtAmount(nodeData, self:getNodeDirtAmount(nodeData) + dirtAmount, force)
241 end
242 end
243end

addToGlobalWashableNode

Description
Definition
addToGlobalWashableNode()
Code
305function Washable:addToGlobalWashableNode(node)
306 local spec = self.spec_washable
307 if spec.washableNodes[1] ~= nil then
308 table.insert(spec.washableNodes[1].nodes, node)
309 end
310end

addToLocalWashableNode

Description
Definition
addToLocalWashableNode()
Code
314function Washable:addToLocalWashableNode(node, updateFunc, customIndex, extraParams)
315 local spec = self.spec_washable
316
317 local nodeData = {}
318
319 --if washableNode already exists we add node to existing washableNode
320 if customIndex ~= nil then
321 if spec.washableNodesByIndex[customIndex] ~= nil then
322 table.insert(spec.washableNodesByIndex[customIndex].nodes, node)
323 return
324 else
325 spec.washableNodesByIndex[customIndex] = nodeData
326 end
327 end
328
329 --if washableNode doesn't exists we create a new one
330 nodeData.nodes = {node}
331 nodeData.updateFunc = updateFunc
332 nodeData.dirtAmount = 0
333 nodeData.dirtAmountSent = 0
334 if extraParams ~= nil then
335 for i, v in pairs(extraParams) do
336 nodeData[i] = v
337 end
338 end
339
340 table.insert(spec.washableNodes, nodeData)
341end

addWashableNodes

Description
Definition
addWashableNodes()
Code
286function Washable:addWashableNodes(nodes)
287 for _, node in ipairs(nodes) do
288 local isGlobal, updateFunc, customIndex, extraParams = self:validateWashableNode(node)
289 if isGlobal then
290 self:addToGlobalWashableNode(node)
291 elseif updateFunc ~= nil then
292 self:addToLocalWashableNode(node, updateFunc, customIndex, extraParams)
293 end
294 end
295end

getAllowsWashingByType

Description
Definition
getAllowsWashingByType()
Code
421function Washable:getAllowsWashingByType(type)
422 local spec = self.spec_washable
423 return spec.blockedWashTypes[type] == nil
424end

getDirtMultiplier

Description
Definition
getDirtMultiplier()
Code
369function Washable:getDirtMultiplier()
370 local spec = self.spec_washable
371
372 local multiplier = 1
373 if self:getLastSpeed() < 1 then
374 multiplier = 0
375 end
376
377 if self:getIsOnField() then
378 multiplier = multiplier * spec.fieldMultiplier
379
380 local wetness = g_currentMission.environment.weather:getGroundWetness()
381 if wetness > 0 then
382 multiplier = multiplier * (1 + wetness)
383 end
384 end
385
386 return multiplier
387end

getIntervalMultiplier

Description
Definition
getIntervalMultiplier()
Code
407function Washable.getIntervalMultiplier()
408 if g_currentMission.missionInfo.dirtInterval == 1 then
409 return 0
410 elseif g_currentMission.missionInfo.dirtInterval == 2 then
411 return 0.25
412 elseif g_currentMission.missionInfo.dirtInterval == 3 then
413 return 0.5
414 elseif g_currentMission.missionInfo.dirtInterval == 4 then
415 return 1
416 end
417end

getNodeDirtAmount

Description
Definition
getNodeDirtAmount()
Code
267function Washable:getNodeDirtAmount(nodeData)
268 return nodeData.dirtAmount
269end

getWashDuration

Description
Definition
getWashDuration()
Code
399function Washable:getWashDuration()
400 local spec = self.spec_washable
401
402 return spec.washDuration
403end

getWorkDirtMultiplier

Description
Definition
getWorkDirtMultiplier()
Code
391function Washable:getWorkDirtMultiplier()
392 local spec = self.spec_washable
393
394 return spec.workMultiplier
395end

onLoad

Description
Definition
onLoad()
Code
61function Washable:onLoad(savegame)
62 local spec = self.spec_washable
63
64 spec.washableNodes = {}
65 spec.washableNodesByIndex = {}
66 self:addToLocalWashableNode(nil, Washable.updateDirtAmount, nil, nil) -- create global / default washableNode
67
68 spec.dirtDuration = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.washable#dirtDuration"), 90) * 60 * 1000
69 if spec.dirtDuration ~= 0 then
70 spec.dirtDuration = 1 / spec.dirtDuration
71 end
72
73 spec.washDuration = math.max(Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.washable#washDuration"), 1) * 60 * 1000, 0.00001) -- washDuration == 0 washes vehicle immediately
74
75 spec.workMultiplier = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.washable#workMultiplier"), 4)
76 spec.fieldMultiplier = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.washable#fieldMultiplier"), 2)
77
78 spec.blockedWashTypes = {}
79 local blockedWashTypesStr = getXMLString(self.xmlFile, "vehicle.washable#blockedWashTypes")
80 if blockedWashTypesStr ~= nil then
81 local blockedWashTypes = StringUtil.splitString(" ", blockedWashTypesStr)
82 for _, typeStr in pairs(blockedWashTypes) do
83 typeStr = "WASHTYPE_" .. typeStr
84 if Washable[typeStr] ~= nil then
85 spec.blockedWashTypes[Washable[typeStr]] = true
86 else
87 g_logManager:xmlWarning(self.configFileName, "Unknown wash type '%s' in '%s'", typeStr, "vehicle.washable#blockedWashTypes")
88 end
89 end
90 end
91
92 spec.dirtyFlag = self:getNextDirtyFlag()
93end

onPostLoad

Description
Definition
onPostLoad()
Code
97function Washable:onPostLoad(savegame)
98 local spec = self.spec_washable
99
100 -- getting als washable nodes in postLoad to make sure also linked nodes are washable
101 if spec.washableNodes ~= nil then
102 for _, component in pairs(self.components) do
103 self:addAllSubWashableNodes(component.node)
104 end
105
106 if savegame ~= nil and Washable.getIntervalMultiplier() ~= 0 then
107 for i, nodeData in ipairs(spec.washableNodes) do
108 local nodeKey = string.format("%s.washable.dirtNode(%d)", savegame.key, i-1)
109 local amount = Utils.getNoNil(getXMLFloat(savegame.xmlFile, nodeKey.."#amount"), 0)
110 self:setNodeDirtAmount(nodeData, amount, true)
111 end
112 else
113 for _, nodeData in ipairs(spec.washableNodes) do
114 self:setNodeDirtAmount(nodeData, 0, true)
115 end
116 end
117 end
118end

onReadStream

Description
Definition
onReadStream()
Code
135function Washable:onReadStream(streamId, connection)
136 local spec = self.spec_washable
137
138 if spec.washableNodes ~= nil then
139 for _, nodeData in ipairs(spec.washableNodes) do
140 local dirtAmount = streamReadUIntN(streamId, Washable.SEND_NUM_BITS) / Washable.SEND_MAX_VALUE
141 self:setNodeDirtAmount(nodeData, dirtAmount, true)
142 end
143 end
144end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
160function Washable:onReadUpdateStream(streamId, timestamp, connection)
161 local spec = self.spec_washable
162
163 if connection:getIsServer() then
164 if spec.washableNodes ~= nil then
165 if streamReadBool(streamId) then
166 for _, nodeData in ipairs(spec.washableNodes) do
167 local dirtAmount = streamReadUIntN(streamId, Washable.SEND_NUM_BITS) / Washable.SEND_MAX_VALUE
168 self:setNodeDirtAmount(nodeData, dirtAmount, true)
169 end
170 end
171 end
172 end
173end

onUpdateTick

Description
Definition
onUpdateTick()
Code
193function Washable:onUpdateTick(dt, isActive, isActiveForInput, isSelected)
194 local spec = self.spec_washable
195
196 if spec.washableNodes ~= nil then
197 if self.isServer then
198 for _, nodeData in ipairs(spec.washableNodes) do
199 local changedAmount = nodeData.updateFunc(self, nodeData, dt)
200 if changedAmount ~= 0 then
201 self:setNodeDirtAmount(nodeData, self:getNodeDirtAmount(nodeData) + changedAmount)
202 end
203 end
204 end
205 end
206end

onWriteStream

Description
Definition
onWriteStream()
Code
148function Washable:onWriteStream(streamId, connection)
149 local spec = self.spec_washable
150
151 if spec.washableNodes ~= nil then
152 for _, nodeData in ipairs(spec.washableNodes) do
153 streamWriteUIntN(streamId, math.floor(self:getNodeDirtAmount(nodeData) * Washable.SEND_MAX_VALUE + 0.5), Washable.SEND_NUM_BITS)
154 end
155 end
156end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
177function Washable:onWriteUpdateStream(streamId, connection, dirtyMask)
178 local spec = self.spec_washable
179
180 if not connection:getIsServer() then
181 if spec.washableNodes ~= nil then
182 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then
183 for _, nodeData in ipairs(spec.washableNodes) do
184 streamWriteUIntN(streamId, math.floor(self:getNodeDirtAmount(nodeData) * Washable.SEND_MAX_VALUE + 0.5), Washable.SEND_NUM_BITS)
185 end
186 end
187 end
188 end
189end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
23function Washable.prerequisitesPresent(specializations)
24 return true
25end

registerEventListeners

Description
Definition
registerEventListeners()
Code
49function Washable.registerEventListeners(vehicleType)
50 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Washable)
51 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Washable)
52 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Washable)
53 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Washable)
54 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Washable)
55 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Washable)
56 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Washable)
57end

registerFunctions

Description
Definition
registerFunctions()
Code
29function Washable.registerFunctions(vehicleType)
30 SpecializationUtil.registerFunction(vehicleType, "updateDirtAmount", Washable.updateDirtAmount)
31 SpecializationUtil.registerFunction(vehicleType, "addDirtAmount", Washable.addDirtAmount)
32 SpecializationUtil.registerFunction(vehicleType, "setNodeDirtAmount", Washable.setNodeDirtAmount)
33 SpecializationUtil.registerFunction(vehicleType, "getNodeDirtAmount", Washable.getNodeDirtAmount)
34 SpecializationUtil.registerFunction(vehicleType, "addAllSubWashableNodes", Washable.addAllSubWashableNodes)
35 SpecializationUtil.registerFunction(vehicleType, "addWashableNodes", Washable.addWashableNodes)
36 SpecializationUtil.registerFunction(vehicleType, "validateWashableNode", Washable.validateWashableNode)
37 SpecializationUtil.registerFunction(vehicleType, "addToGlobalWashableNode", Washable.addToGlobalWashableNode)
38 SpecializationUtil.registerFunction(vehicleType, "addToLocalWashableNode", Washable.addToLocalWashableNode)
39 SpecializationUtil.registerFunction(vehicleType, "removeAllSubWashableNodes", Washable.removeAllSubWashableNodes)
40 SpecializationUtil.registerFunction(vehicleType, "removeWashableNode", Washable.removeWashableNode)
41 SpecializationUtil.registerFunction(vehicleType, "getDirtMultiplier", Washable.getDirtMultiplier)
42 SpecializationUtil.registerFunction(vehicleType, "getWorkDirtMultiplier", Washable.getWorkDirtMultiplier)
43 SpecializationUtil.registerFunction(vehicleType, "getWashDuration", Washable.getWashDuration)
44 SpecializationUtil.registerFunction(vehicleType, "getAllowsWashingByType", Washable.getAllowsWashingByType)
45end

removeAllSubWashableNodes

Description
Definition
removeAllSubWashableNodes()
Code
345function Washable:removeAllSubWashableNodes(rootNode)
346 if rootNode ~= nil then
347 local nodes = {}
348 I3DUtil.getNodesByShaderParam(rootNode, "RDT", nodes)
349 for _, node in pairs(nodes) do
350 self:removeWashableNode(node)
351 end
352 end
353end

removeWashableNode

Description
Definition
removeWashableNode()
Code
357function Washable:removeWashableNode(node)
358 local spec = self.spec_washable
359
360 if spec.washableNodes ~= nil and node ~= nil then
361 for _, nodeData in ipairs(spec.washableNodes) do
362 ListUtil.removeElementFromList(nodeData.nodes, node)
363 end
364 end
365end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
122function Washable:saveToXMLFile(xmlFile, key, usedModNames)
123 local spec = self.spec_washable
124
125 if spec.washableNodes ~= nil then
126 for i, nodeData in ipairs(spec.washableNodes) do
127 local nodeKey = string.format("%s.dirtNode(%d)", key, i-1)
128 setXMLFloat(xmlFile, nodeKey.."#amount", self:getNodeDirtAmount(nodeData))
129 end
130 end
131end

setNodeDirtAmount

Description
Definition
setNodeDirtAmount()
Code
247function Washable:setNodeDirtAmount(nodeData, dirtAmount, force)
248 local spec = self.spec_washable
249 nodeData.dirtAmount = MathUtil.clamp(dirtAmount, 0, 1)
250
251 local diff = nodeData.dirtAmountSent - nodeData.dirtAmount
252 if math.abs(diff) > Washable.SEND_THRESHOLD or force then
253 for _, node in pairs(nodeData.nodes) do
254 local x, _, z, w = getShaderParameter(node, "RDT")
255 setShaderParameter(node, "RDT", x, nodeData.dirtAmount, z, w, false)
256 end
257
258 if self.isServer then
259 self:raiseDirtyFlags(spec.dirtyFlag)
260 nodeData.dirtAmountSent = nodeData.dirtAmount
261 end
262 end
263end

updateDebugValues

Description
Definition
updateDebugValues()
Code
428function Washable:updateDebugValues(values)
429 local spec = self.spec_washable
430 if spec.washableNodes ~= nil then
431 if self.isServer then
432 for i, nodeData in ipairs(spec.washableNodes) do
433 local changedAmount = nodeData.updateFunc(self, nodeData, 3600000)
434 table.insert(values, {name="WashableNode"..i, value=string.format("%.4f a/h (%.2f)", changedAmount, self:getNodeDirtAmount(nodeData))})
435 end
436 end
437 end
438end

updateDirtAmount

Description
Definition
updateDirtAmount()
Code
210function Washable:updateDirtAmount(nodeData, dt)
211 local spec = self.spec_washable
212 local change = 0
213
214 if self:getAllowsWashingByType(Washable.WASHTYPE_RAIN) then
215 local weather = g_currentMission.environment.weather
216 local rainScale = weather:getRainFallScale()
217 local timeSinceLastRain = weather:getTimeSinceLastRain()
218 if rainScale > 0.1 and timeSinceLastRain < 30 then
219 local amount = self:getNodeDirtAmount(nodeData)
220 if amount > 0.5 then
221 change = -(dt / spec.washDuration)
222 end
223 end
224 end
225
226 local dirtMultiplier = self:getDirtMultiplier()
227 if dirtMultiplier ~= 0 then
228 change = dt * spec.dirtDuration * dirtMultiplier * Washable.getIntervalMultiplier()
229 end
230
231 return change
232end

validateWashableNode

Description
Definition
validateWashableNode()
Code
299function Washable:validateWashableNode(node)
300 return true, nil -- by default all nodes are global
301end