LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

Crawlers

Description
Specialization for crawlers and tracks with rotating and/or scrolling elements
Functions

loadCrawlerFromConfigFile

Description
Definition
loadCrawlerFromConfigFile()
Code
201function Crawlers:loadCrawlerFromConfigFile(crawler, xmlFilename, linkNode, isLeft)
202 xmlFilename = Utils.getFilename(xmlFilename, self.baseDirectory)
203 local xmlFile = loadXMLFile("TempConfig", xmlFilename)
204 if xmlFile ~= nil then
205 local filename = getXMLString(xmlFile, "crawler.file#name")
206 if filename ~= nil then
207 crawler.filename = filename
208 local i3dNode = g_i3DManager:loadSharedI3DFile(filename, self.baseDirectory, false, false, false)
209 if i3dNode ~= 0 then
210 local key = (isLeft and "leftNode") or "rightNode"
211 crawler.loadedCrawler = I3DUtil.indexToObject(i3dNode, getXMLString(xmlFile, "crawler.file#"..key))
212 link(linkNode, crawler.loadedCrawler)
213 delete(i3dNode)
214 else
215 g_logManager:xmlWarning(self.configFileName, "Failed to find crawler in i3d file '%s'", filename, xmlFilename)
216 return false
217 end
218 else
219 g_logManager:xmlWarning(self.configFileName, "Failed to open crawler i3d file '%s' in '%s'", filename, xmlFilename)
220 return false
221 end
222
223 crawler.scrollerNodes = {}
224 local j = 0
225 while true do
226 local key = string.format("crawler.scrollerNodes.scrollerNode(%d)", j)
227 if not hasXMLProperty(xmlFile, key) then
228 break
229 end
230
231 local entry = {}
232 entry.node = I3DUtil.indexToObject(crawler.loadedCrawler, getXMLString(xmlFile, key.."#node"))
233 if entry.node ~= nil then
234 entry.scrollSpeed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#scrollSpeed"), 1)
235 entry.scrollLength = Utils.getNoNil(getXMLFloat(xmlFile, key.."#scrollLength"), 1)
236 entry.shaderParameterName = Utils.getNoNil(getXMLString(xmlFile, key.."#shaderParameterName"), "offsetUV")
237 entry.shaderParameterComponent = Utils.getNoNil(getXMLInt(xmlFile, key.."#shaderParameterComponent"), 1)
238 entry.scrollPosition = 0
239
240 if crawler.trackWidth ~= 1 then
241 if Utils.getNoNil(getXMLBool(xmlFile, key.."#isTrackPart"), true) then
242 setScale(entry.node, crawler.trackWidth, 1, 1)
243 end
244 end
245
246 table.insert(crawler.scrollerNodes, entry)
247 end
248 j = j + 1
249 end
250
251 crawler.rotatingParts = {}
252 j = 0
253 while true do
254 local key = string.format("crawler.rotatingParts.rotatingPart(%d)", j)
255 if not hasXMLProperty(xmlFile, key) then
256 break
257 end
258
259 local entry = {}
260 entry.node = I3DUtil.indexToObject(crawler.loadedCrawler, getXMLString(xmlFile, key.."#node"))
261 if entry.node ~= nil then
262 entry.radius = getXMLFloat(xmlFile, key.."#radius")
263 entry.speedScale = getXMLFloat(xmlFile, key.."#speedScale")
264 if entry.speedScale == nil and entry.radius ~= nil then
265 entry.speedScale = 1.0 / entry.radius
266 end
267
268 table.insert(crawler.rotatingParts, entry)
269 end
270
271 j = j + 1
272 end
273
274 local applyColor = function(name, color)
275 j = 0
276 while true do
277 local key = string.format("crawler.%s.%s(%d)", name.."s", name, j)
278 if not hasXMLProperty(xmlFile, key) then
279 break
280 end
281
282 local node = I3DUtil.indexToObject(crawler.loadedCrawler, getXMLString(xmlFile, key.."#node"))
283 if node ~= nil then
284 local shaderParameter = getXMLString(xmlFile, key.."#shaderParameter")
285 if getHasShaderParameter(node, shaderParameter) then
286 local r, g, b, mat = unpack(color)
287 if mat == nil then
288 _, _, _, mat = getShaderParameter(node, shaderParameter)
289 end
290 I3DUtil.setShaderParameterRec(node, shaderParameter, r, g, b, mat, true)
291 else
292 g_logManager:xmlWarning(self.configFileName, "Missing shaderParameter '%s' on object '%s' in %s", shaderParameter, getName(node), key)
293 end
294 end
295
296 j = j + 1
297 end
298 end
299
300 local rimColor = Utils.getNoNil(ConfigurationUtil.getColorByConfigId(self, "rimColor", self.configurations["rimColor"]), self.spec_wheels.rimColor)
301 if rimColor ~= nil then
302 crawler.rimColorNodes = applyColor("rimColorNode", rimColor)
303 end
304
305 crawler.objectChanges = {}
306 ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, "crawler", crawler.objectChanges, crawler.loadedCrawler, self)
307 ObjectChangeUtil.setObjectChanges(crawler.objectChanges, true)
308
309 delete(xmlFile)
310 return true
311 end
312
313 g_logManager:xmlWarning(self.configFileName, "Failed to open crawler config file '%s'", xmlFilename)
314 return false
315end

loadCrawlerFromXML

Description
Load crawlers from xml
Definition
loadCrawlerFromXML(integer xmlFile)
Arguments
integerxmlFileid of xml object
Code
146function Crawlers:loadCrawlerFromXML(xmlFile, key, crawler)
147 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#crawlerIndex", "Moved to external crawler config file") -- FS17 to FS19
148 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#length", "Moved to external crawler config file") -- FS17 to FS19
149 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#shaderParameterComponent", "Moved to external crawler config file") -- FS17 to FS19
150 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#shaderParameterName", "Moved to external crawler config file") -- FS17 to FS19
151 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#scrollLength", "Moved to external crawler config file") -- FS17 to FS19
152 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#scrollSpeed", "Moved to external crawler config file") -- FS17 to FS19
153 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#index", "Moved to external crawler config file") -- FS17 to FS19
154 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key..".rotatingPart", "Moved to external crawler config file") -- FS17 to FS19
155
156 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#linkIndex", key.."#linkNode") -- FS17 to FS19
157 local linkNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#linkNode"), self.i3dMappings)
158 if linkNode == nil then
159 g_logManager:xmlWarning(self.configFileName, "Missing link node for crawler '%s'", key)
160 return false
161 end
162
163 local isLeft = Utils.getNoNil(getXMLBool(xmlFile, key .. "#isLeft"), false)
164 crawler.trackWidth = Utils.getNoNil(getXMLFloat(xmlFile, key.."#trackWidth"), 1)
165
166 local filename = getXMLString(xmlFile, key .. "#filename")
167 if not self:loadCrawlerFromConfigFile(crawler, filename, linkNode, isLeft) then
168 return false
169 end
170
171 local offset = StringUtil.getVectorNFromString(getXMLString(xmlFile, key .. "#offset"), 3)
172 if offset ~= nil then
173 setTranslation(crawler.loadedCrawler, unpack(offset))
174 end
175
176 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#speedRefWheel", key.."#wheelIndex") -- FS17 to FS19
177 local wheelIndex = getXMLInt(xmlFile, key.."#wheelIndex")
178 if wheelIndex ~= nil then
179 local wheels = self:getWheels()
180 if wheels[wheelIndex] ~= nil then
181 crawler.wheel = wheels[wheelIndex]
182 if not crawler.wheel.isSynchronized then
183 g_logManager:xmlWarning(self.configFileName, "Wheel for crawler '%s' in not synchronized! It won't rotate on the client side.", key)
184 end
185 end
186 end
187
188 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#speedRefNode", key.."#speedReferenceNode") -- FS17 to FS19
189 crawler.speedReferenceNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#speedReferenceNode"), self.i3dMappings), linkNode)
190 crawler.movedDistance = 0
191
192 crawler.fieldDirtMultiplier = Utils.getNoNil(getXMLInt(xmlFile, key.."#fieldDirtMultiplier"), 75)
193 crawler.streetDirtMultiplier = Utils.getNoNil(getXMLInt(xmlFile, key.."#streetDirtMultiplier"), -150)
194 crawler.minDirtPercentage = Utils.getNoNil(getXMLInt(xmlFile, key.."#minDirtPercentage"), 0.35)
195
196 return true
197end

onDelete

Description
Called on deleting
Definition
onDelete()
Code
70function Crawlers:onDelete()
71 local spec = self.spec_crawlers
72 for _, crawler in pairs(spec.crawlers) do
73 if crawler.filename ~= nil then
74 g_i3DManager:releaseSharedI3DFile(crawler.filename, self.baseDirectory, true)
75 end
76 end
77end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
45function Crawlers:onLoad(savegame)
46 local spec = self.spec_crawlers
47
48 local wheelConfigId = Utils.getNoNil(self.configurations["wheel"], 1)
49 local wheelKey = string.format("vehicle.wheels.wheelConfigurations.wheelConfiguration(%d)", wheelConfigId-1)
50
51 spec.crawlers = {}
52 local i = 0
53 while true do
54 local key = string.format(wheelKey..".crawlers.crawler(%d)", i)
55 if not hasXMLProperty(self.xmlFile, key) then
56 break
57 end
58
59 local crawler = {}
60 if self:loadCrawlerFromXML(self.xmlFile, key, crawler) then
61 table.insert(spec.crawlers, crawler)
62 end
63
64 i = i + 1
65 end
66end

onUpdate

Description
Called on update
Definition
onUpdate(float dt, boolean isActive, boolean isActiveForInput, boolean isSelected)
Arguments
floatdttime since last call in ms
booleanisActivetrue if vehicle is active
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
85function Crawlers:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
86 local spec = self.spec_crawlers
87 for _, crawler in pairs(spec.crawlers) do
88 crawler.movedDistance = 0
89
90 if crawler.wheel ~= nil then
91 local newX, _, _ = getRotation(crawler.wheel.driveNode)
92 if crawler.lastRotation == nil then
93 crawler.lastRotation = newX
94 end
95
96 if newX - crawler.lastRotation < -math.pi then
97 crawler.lastRotation = crawler.lastRotation - 2*math.pi
98 elseif newX - crawler.lastRotation > math.pi then
99 crawler.lastRotation = crawler.lastRotation + 2*math.pi
100 end
101
102 crawler.movedDistance = crawler.wheel.radius * (newX-crawler.lastRotation)
103 crawler.lastRotation = newX
104 else
105 local newX, newY, newZ = getWorldTranslation(crawler.speedReferenceNode)
106 if crawler.lastPosition == nil then
107 crawler.lastPosition = {newX, newY, newZ}
108 end
109 local dx, dy, dz = worldDirectionToLocal(crawler.speedReferenceNode, newX-crawler.lastPosition[1], newY-crawler.lastPosition[2], newZ-crawler.lastPosition[3])
110 local movingDirection = 0
111 if dz > 0.0001 then
112 movingDirection = 1
113 elseif dz < -0.0001 then
114 movingDirection = -1
115 end
116 crawler.movedDistance = MathUtil.vector3Length(dx, dy, dz) * movingDirection
117 crawler.lastPosition[1] = newX
118 crawler.lastPosition[2] = newY
119 crawler.lastPosition[3] = newZ
120 end
121
122 for _, scrollerNode in pairs(crawler.scrollerNodes) do
123 scrollerNode.scrollPosition = (scrollerNode.scrollPosition + crawler.movedDistance*scrollerNode.scrollSpeed) % scrollerNode.scrollLength
124 if scrollerNode.shaderParameterComponent == 1 then
125 setShaderParameter(scrollerNode.node, scrollerNode.shaderParameterName, scrollerNode.scrollPosition,0,0,0, false)
126 else
127 setShaderParameter(scrollerNode.node, scrollerNode.shaderParameterName, 0,scrollerNode.scrollPosition,0,0, false)
128 end
129 end
130
131 for _, rotatingPart in pairs(crawler.rotatingParts) do
132 if crawler.wheel ~= nil and rotatingPart.speedScale == nil then
133 -- rotate the part exactly like the wheel
134 local newX, _, _ = getRotation(crawler.wheel.driveNode)
135 setRotation(rotatingPart.node, newX, 0, 0)
136 elseif rotatingPart.speedScale ~= nil then
137 rotate(rotatingPart.node, rotatingPart.speedScale * crawler.movedDistance, 0, 0)
138 end
139 end
140 end
141end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
17function Crawlers.prerequisitesPresent(specializations)
18 return SpecializationUtil.hasSpecialization(Wheels, specializations)
19end

registerEventListeners

Description
Definition
registerEventListeners()
Code
36function Crawlers.registerEventListeners(vehicleType)
37 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Crawlers)
38 SpecializationUtil.registerEventListener(vehicleType, "onDelete", Crawlers)
39 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Crawlers)
40end

registerFunctions

Description
Definition
registerFunctions()
Code
23function Crawlers.registerFunctions(vehicleType)
24 SpecializationUtil.registerFunction(vehicleType, "loadCrawlerFromXML", Crawlers.loadCrawlerFromXML)
25 SpecializationUtil.registerFunction(vehicleType, "loadCrawlerFromConfigFile", Crawlers.loadCrawlerFromConfigFile)
26end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
30function Crawlers.registerOverwrittenFunctions(vehicleType)
31 SpecializationUtil.registerOverwrittenFunction(vehicleType, "validateWashableNode", Crawlers.validateWashableNode)
32end

validateWashableNode

Description
Definition
validateWashableNode()
Code
319function Crawlers:validateWashableNode(superFunc, node)
320 local spec = self.spec_crawlers
321 for _, crawler in pairs(spec.crawlers) do
322
323 local crawlerNodes = {}
324 I3DUtil.getNodesByShaderParam(crawler.loadedCrawler, "RDT", crawlerNodes);
325
326 if crawlerNodes[node] ~= nil then
327 return false, self.updateWheelDirtAmount, crawler, {wheel=crawler.wheel, fieldDirtMultiplier=crawler.fieldDirtMultiplier, streetDirtMultiplier=crawler.streetDirtMultiplier, minDirtPercentage=crawler.minDirtPercentage}
328 end
329 end
330
331 return superFunc(self, node)
332end