LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

SpeedRotatingParts

Description
Specialization for vehicle with speedrotatingparts
Functions

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 SpeedRotatingParts.prerequisitesPresent(specializations)
18 return true;
19end;

preLoad

Description
Called before loading
Definition
preLoad(table savegame)
Arguments
tablesavegamesavegame
Code
24function SpeedRotatingParts:preLoad(savegame)
25 self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, SpeedRotatingParts.loadSpeedRotatingPartFromXML);
26 self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, SpeedRotatingParts.getIsSpeedRotatingPartActive);
27 self.getSpeedRotatingPartDirection = Utils.overwrittenFunction(self.getSpeedRotatingPartDirection, SpeedRotatingParts.getSpeedRotatingPartDirection);
28end;

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
33function SpeedRotatingParts:load(savegame)
34 self.speedRotatingParts = {};
35 local i=0;
36 while true do
37 local baseName = string.format("vehicle.speedRotatingParts.speedRotatingPart(%d)", i);
38 if not hasXMLProperty(self.xmlFile, baseName) then
39 break;
40 end;
41 local speedRotatingPart = {};
42 if self:loadSpeedRotatingPartFromXML(speedRotatingPart, self.xmlFile, baseName) then
43 table.insert(self.speedRotatingParts, speedRotatingPart);
44 end;
45 i = i + 1;
46 end;
47
48 self.speedRotatingPartsDirtyFlag = self:getNextDirtyFlag();
49end;

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
58function SpeedRotatingParts:readStream(streamId, connection)
59 for _, speedRotatingPart in pairs(self.speedRotatingParts) do
60 if speedRotatingPart.versatileYRot then
61 local yRot = streamReadUIntN(streamId, 9);
62 speedRotatingPart.steeringAngle = yRot / 511 * math.pi*2;
63 end;
64 end;
65end;

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
71function SpeedRotatingParts:writeStream(streamId, connection)
72 for _, speedRotatingPart in pairs(self.speedRotatingParts) do
73 if speedRotatingPart.versatileYRot then
74 streamWriteUIntN(streamId, Utils.clamp(math.floor(speedRotatingPart.steeringAngle / (math.pi*2) * 511), 0, 511), 9);
75 end;
76 end;
77end;

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
84function SpeedRotatingParts:readUpdateStream(streamId, timestamp, connection)
85 if connection.isServer then
86 local hasUpdate = streamReadBool(streamId);
87 if hasUpdate then
88 for _, speedRotatingPart in pairs(self.speedRotatingParts) do
89 if speedRotatingPart.versatileYRot then
90 local yRot = streamReadUIntN(streamId, 9);
91 speedRotatingPart.steeringAngle = yRot / 511 * math.pi*2;
92 end;
93 end;
94 end;
95 end;
96end;

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
103function SpeedRotatingParts:writeUpdateStream(streamId, connection, dirtyMask)
104 if not connection.isServer then
105 if streamWriteBool(streamId, bitAND(dirtyMask, self.speedRotatingPartsDirtyFlag) ~= 0) then
106 for _, speedRotatingPart in pairs(self.speedRotatingParts) do
107 if speedRotatingPart.versatileYRot then
108 local yRot = speedRotatingPart.steeringAngle % (math.pi*2);
109 streamWriteUIntN(streamId, Utils.clamp(math.floor(yRot / (math.pi*2) * 511), 0, 511), 9);
110 end;
111 end;
112 end;
113 end;
114end;

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
125function SpeedRotatingParts:update(dt)
126 if self:getIsActive() then
127 for _, speedRotatingPart in pairs(self.speedRotatingParts) do
128 local isActive = self:getIsSpeedRotatingPartActive(speedRotatingPart);
129 if isActive or (speedRotatingPart.lastSpeed ~= 0 and not speedRotatingPart.stopIfNotActive) then
130 local speed = speedRotatingPart.lastSpeed;
131 local dir = speedRotatingPart.lastDir;
132 if isActive then
133 if speedRotatingPart.wheel ~= nil then
134 local x,_,_ = getRotation(speedRotatingPart.wheel.driveNode);
135 local deltaRot = x-speedRotatingPart.lastWheelXRot;
136 speed = math.abs(deltaRot);
137 dir = Utils.sign(deltaRot);
138 speedRotatingPart.lastWheelXRot = x;
139 elseif speedRotatingPart.speedReferenceNode ~= nil then
140 local newX, newY, newZ = getWorldTranslation(speedRotatingPart.speedReferenceNode);
141 if speedRotatingPart.lastPosition == nil then
142 speedRotatingPart.lastPosition = {newX, newY, newZ};
143 end;
144
145 local dx, dy, dz = worldDirectionToLocal(speedRotatingPart.speedReferenceNode, newX-speedRotatingPart.lastPosition[1], newY-speedRotatingPart.lastPosition[2], newZ-speedRotatingPart.lastPosition[3]);
146 speed = Utils.vector3Length(dx, dy, dz);
147
148 if dz > 0.001 then
149 dir = 1;
150 elseif dz < -0.001 then
151 dir = -1;
152 else
153 dir = 0;
154 end;
155
156 speedRotatingPart.lastPosition[1], speedRotatingPart.lastPosition[2], speedRotatingPart.lastPosition[3] = newX, newY, newZ;
157 else
158 speed = self.lastSpeedReal * dt;
159 dir = self.movingDirection;
160 end;
161 speedRotatingPart.brakeForce = speed * dt/speedRotatingPart.fadeOutTime;
162 else
163 speed = math.max(speed - speedRotatingPart.brakeForce, 0);
164 end;
165
166 speedRotatingPart.lastSpeed = speed;
167 speedRotatingPart.lastDir = dir;
168 if speedRotatingPart.updateXDrive then
169 speedRotatingPart.xDrive = speedRotatingPart.xDrive + speed * dir * self:getSpeedRotatingPartDirection(speedRotatingPart) * speedRotatingPart.wheelScale
170 end
171
172 if speedRotatingPart.versatileYRot then
173 if self.isServer and self:getLastSpeed(true) > speedRotatingPart.activationSpeed then
174 local posX, posY, posZ = localToLocal(speedRotatingPart.repr, speedRotatingPart.componentNode, 0,0,0);
175 speedRotatingPart.steeringAngle = Utils.getVersatileRotation(speedRotatingPart.repr, speedRotatingPart.componentNode, dt, posX, posY, posZ, speedRotatingPart.steeringAngle, speedRotatingPart.minYRot, speedRotatingPart.maxYRot);
176 if math.abs(speedRotatingPart.steeringAngleSent-speedRotatingPart.steeringAngle) > 0.1 then
177 speedRotatingPart.steeringAngleSent = speedRotatingPart.steeringAngle;
178 self:raiseDirtyFlags(self.speedRotatingPartsDirtyFlag);
179 end;
180 end;
181 else
182 if speedRotatingPart.componentNode ~= nil and speedRotatingPart.dirRefNode ~= nil and not speedRotatingPart.alignDirection then
183 speedRotatingPart.steeringAngle = Utils.getYRotationBetweenNodes(speedRotatingPart.componentNode, speedRotatingPart.dirRefNode);
184 local _,yTrans,_ = localToLocal(speedRotatingPart.driveNode, speedRotatingPart.wheel.driveNode, 0, 0, 0);
185 setTranslation(speedRotatingPart.driveNode, 0, yTrans, 0);
186 end;
187
188 if speedRotatingPart.dirRefNode ~= nil and speedRotatingPart.alignDirection then
189 local upX, upY, upZ = localDirectionToWorld(speedRotatingPart.dirFrameNode, 0, 1, 0);
190 local dirX, dirY, dirZ = localDirectionToWorld(speedRotatingPart.dirRefNode, 0, 0, 1);
191 Utils.setWorldDirection(speedRotatingPart.repr, dirX, dirY, dirZ, upX, upY, upZ, 2);
192 if speedRotatingPart.wheel ~= nil and speedRotatingPart.useWheelReprTranslation then
193 local _,yTrans,_ = localToLocal(speedRotatingPart.wheel.driveNode, getParent(speedRotatingPart.repr), 0,0,0);
194 setTranslation(speedRotatingPart.repr, 0, yTrans, 0);
195 end;
196 end;
197 end;
198
199 if speedRotatingPart.driveNode ~= nil then
200 if speedRotatingPart.repr == speedRotatingPart.driveNode then
201 setRotation(speedRotatingPart.repr, speedRotatingPart.xDrive, speedRotatingPart.steeringAngle, 0);
202 else
203 if not speedRotatingPart.alignDirection then
204 setRotation(speedRotatingPart.repr, 0, speedRotatingPart.steeringAngle, 0);
205 end;
206 setRotation(speedRotatingPart.driveNode, speedRotatingPart.xDrive, 0, 0);
207 end;
208 end;
209
210 if speedRotatingPart.shaderNode ~= nil then
211 if speedRotatingPart.useShaderRotation then
212 setShaderParameter(speedRotatingPart.shaderNode, "offsetUV", 0, 0, speedRotatingPart.xDrive, 0, false);
213 else
214 local pos = (speedRotatingPart.xDrive % math.pi) / (2*math.pi); -- normalize rotation
215 setShaderParameter(speedRotatingPart.shaderNode, "offsetUV", pos*speedRotatingPart.scrollScale[1], pos*speedRotatingPart.scrollScale[2], 0, 0, false);
216 end;
217 end;
218 end;
219 end;
220 end;
221end;

loadSpeedRotatingPartFromXML

Description
Loads speed rotating parts from xml
Definition
loadSpeedRotatingPartFromXML(table speedRotatingPart, integer xmlFile, string key)
Arguments
tablespeedRotatingPartspeedRotatingPart
integerxmlFileid of xml object
stringkeykey
Return Values
booleansuccesssuccess
Code
235function SpeedRotatingParts:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
236 if superFunc ~= nil then
237 if not superFunc(self, speedRotatingPart, xmlFile, key) then
238 return false;
239 end;
240 end;
241 speedRotatingPart.repr = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
242 speedRotatingPart.shaderNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#shaderNode"));
243 if speedRotatingPart.shaderNode ~= nil then
244 speedRotatingPart.useShaderRotation = Utils.getNoNil(getXMLBool(xmlFile, key.."#useRotation"), true);
245 local scale = Utils.getNoNil(getXMLString(xmlFile, key.."#scrollScale"), "1 0");
246 speedRotatingPart.scrollScale = Utils.getVectorNFromString(scale, 2);
247 end;
248
249 if speedRotatingPart.repr == nil and speedRotatingPart.shaderNode == nil then
250 print("Warning: Invalid speedrotationpart '"..tostring(getXMLString(xmlFile, key.."#index")).."'! in '"..self.configFileName.."'");
251 return false;
252 end;
253 speedRotatingPart.driveNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#driveNode")), speedRotatingPart.repr);
254
255 local componentIndex = getXMLInt(xmlFile, key.."#refComponentIndex");
256 if componentIndex ~= nil and self.components[componentIndex] ~= nil then
257 speedRotatingPart.componentNode = self.components[componentIndex].node;
258 else
259 local node = Utils.getNoNil(speedRotatingPart.driveNode, speedRotatingPart.shaderNode)
260 speedRotatingPart.componentNode = self:getParentComponent(node);
261 end;
262
263
264 speedRotatingPart.xDrive = 0;
265 local wheelIndex = getXMLInt(xmlFile, key.."#wheelIndex");
266 if wheelIndex ~= nil then
267 local wheel = self.wheels[wheelIndex + 1];
268 if wheel == nil then
269 print("SpeedRotatingParts: Invalid wheel index ("..tostring(wheelIndex)..")");
270 return false;
271 end;
272 speedRotatingPart.wheel = wheel;
273 speedRotatingPart.lastWheelXRot = 0;
274 end;
275 speedRotatingPart.dirRefNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#dirRefNode"));
276 speedRotatingPart.dirFrameNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#dirFrameNode"));
277 speedRotatingPart.alignDirection = Utils.getNoNil(getXMLBool(xmlFile, key .. "#alignDirection"), false);
278 speedRotatingPart.useWheelReprTranslation = Utils.getNoNil(getXMLBool(xmlFile, key .. "#useWheelReprTranslation"), true);
279 speedRotatingPart.updateXDrive = Utils.getNoNil(getXMLBool(xmlFile, key .. "#updateXDrive"), true);
280
281 speedRotatingPart.versatileYRot = Utils.getNoNil(getXMLBool(xmlFile, key .. "#versatileYRot"), false);
282 if speedRotatingPart.versatileYRot and speedRotatingPart.repr == nil then
283 print("Warning: Versatile speedrotationpart does not support shaderNodes in '"..self.configFileName.."'");
284 return false;
285 end;
286
287 local minYRot = getXMLFloat(xmlFile, key .. "#minYRot");
288 if minYRot ~= nil then
289 speedRotatingPart.minYRot = math.rad(minYRot);
290 end;
291 local maxYRot = getXMLFloat(xmlFile, key .. "#maxYRot");
292 if maxYRot ~= nil then
293 speedRotatingPart.maxYRot = math.rad(maxYRot);
294 end;
295 speedRotatingPart.steeringAngle = 0;
296 speedRotatingPart.steeringAngleSent = 0;
297
298 speedRotatingPart.wheelScale = getXMLFloat(xmlFile, key .. "#wheelScale");
299 if speedRotatingPart.wheelScale == nil then
300 local baseRadius = 1.0;
301 local radius = 1.0;
302 if speedRotatingPart.wheel ~= nil then
303 baseRadius = speedRotatingPart.wheel.radius;
304 radius = speedRotatingPart.wheel.radius;
305 end;
306 speedRotatingPart.wheelScale = baseRadius / Utils.getNoNil(getXMLFloat(xmlFile, key.."#radius"), radius);
307 end;
308
309 speedRotatingPart.wheelScaleBackup = speedRotatingPart.wheelScale;
310
311 speedRotatingPart.onlyActiveWhenLowered = Utils.getNoNil(getXMLBool(xmlFile, key .. "#onlyActiveWhenLowered"), false);
312 speedRotatingPart.stopIfNotActive = Utils.getNoNil(getXMLBool(xmlFile, key .. "#stopIfNotActive"), false);
313 speedRotatingPart.fadeOutTime = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#fadeOutTime"), 3) * 1000
314 speedRotatingPart.activationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#activationSpeed"), 1);
315 speedRotatingPart.speedReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#speedReferenceNode"));
316 if speedRotatingPart.speedReferenceNode ~= nil and speedRotatingPart.speedReferenceNode == speedRotatingPart.driveNode then
317 print("Warning: Ignoring speedRotationPart '"..key.."' because speedReferenceNode is identical with driveNode in '"..self.configFileName.."'. Need to be different!")
318 return false
319 end
320 speedRotatingPart.lastSpeed = 0;
321 speedRotatingPart.lastDir = 1;
322
323 return true;
324end;

getIsSpeedRotatingPartActive

Description
Returns true if speed rotating part is active
Definition
getIsSpeedRotatingPartActive(table speedRotatingPart)
Arguments
tablespeedRotatingPartspeedRotatingPart
Return Values
booleanisActivespeed rotating part is active
Code
330function SpeedRotatingParts:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
331 if superFunc ~= nil then
332 if not superFunc(self, speedRotatingPart) then
333 return false;
334 end;
335 end;
336 if speedRotatingPart.onlyActiveWhenLowered and not self:isLowered(true) then
337 return false;
338 end;
339
340 return true;
341end;

getSpeedRotatingPartDirection

Description
Return direction of speed rotating part
Definition
getSpeedRotatingPartDirection(table speedRotatingPart)
Arguments
tablespeedRotatingPartspeed rotating part
Return Values
integerdirectiondirection
Code
347function SpeedRotatingParts:getSpeedRotatingPartDirection(superFunc, speedRotatingPart)
348 if superFunc ~= nil then
349 return superFunc(self, speedRotatingPart);
350 end;
351 return 1;
352end;