Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- AIConveyorBelt
- AIImplement
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BunkerSiloCompacter
- BunkerSiloInteractor
- BuyableBale
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- JigglingParts
- Leveler
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- MixerWagon
- Motorized
- Mountable
- Mower
- Pickup
- Pipe
- Plow
- PowerConsumer
- PowerTakeOffs
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StrawBlower
- StumpCutter
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TipOccluder
- Trailer
- TreePlanter
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Wearable
- Weeder
- Wheels
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
SpeedRotatingParts
DescriptionSpecialization for vehicle with (non-wheel) parts rotating or scrolling dependent on its driving speedFunctions
- getIsSpeedRotatingPartActive
- getSpeedRotatingPartDirection
- loadSpeedRotatingPartFromXML
- onLoad
- onReadStream
- onReadUpdateStream
- onUpdate
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- updateSpeedRotatingPart
- validateWashableNode
getIsSpeedRotatingPartActive
DescriptionReturns true if speed rotating part is activeDefinition
getIsSpeedRotatingPartActive(table speedRotatingPart)Arguments
table | speedRotatingPart | speedRotatingPart |
boolean | isActive | speed rotating part is active |
259 | function SpeedRotatingParts:getIsSpeedRotatingPartActive(speedRotatingPart) |
260 | if speedRotatingPart.onlyActiveWhenLowered then |
261 | if self.getIsLowered ~= nil and not self:getIsLowered() then |
262 | return false |
263 | else |
264 | return true |
265 | end |
266 | end |
267 | |
268 | return true |
269 | end |
getSpeedRotatingPartDirection
DescriptionReturn direction of speed rotating partDefinition
getSpeedRotatingPartDirection(table speedRotatingPart)Arguments
table | speedRotatingPart | speed rotating part |
integer | direction | direction |
275 | function SpeedRotatingParts:getSpeedRotatingPartDirection(speedRotatingPart) |
276 | return 1 |
277 | end |
loadSpeedRotatingPartFromXML
DescriptionLoads speed rotating parts from xmlDefinition
loadSpeedRotatingPartFromXML(table speedRotatingPart, integer xmlFile, string key)Arguments
table | speedRotatingPart | speedRotatingPart |
integer | xmlFile | id of xml object |
string | key | key |
boolean | success | success |
160 | function SpeedRotatingParts:loadSpeedRotatingPartFromXML(speedRotatingPart, xmlFile, key) |
161 | speedRotatingPart.repr = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#node"), self.i3dMappings) |
162 | speedRotatingPart.shaderNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#shaderNode"), self.i3dMappings) |
163 | if speedRotatingPart.shaderNode ~= nil then |
164 | speedRotatingPart.useShaderRotation = Utils.getNoNil(getXMLBool(xmlFile, key.."#useRotation"), true) |
165 | local scale = Utils.getNoNil(getXMLString(xmlFile, key.."#scrollScale"), "1 0") |
166 | speedRotatingPart.scrollScale = StringUtil.getVectorNFromString(scale, 2) |
167 | end |
168 | |
169 | if speedRotatingPart.repr == nil and speedRotatingPart.shaderNode == nil then |
170 | g_logManager:xmlWarning(self.configFileName, "Invalid speedRotationPart node '%s' in '%s'", tostring(getXMLString(xmlFile, key.."#node")), key) |
171 | return false |
172 | end |
173 | speedRotatingPart.driveNode = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#driveNode"), self.i3dMappings), speedRotatingPart.repr) |
174 | |
175 | local componentIndex = getXMLInt(xmlFile, key.."#refComponentIndex") |
176 | if componentIndex ~= nil and self.components[componentIndex] ~= nil then |
177 | speedRotatingPart.componentNode = self.components[componentIndex].node |
178 | else |
179 | local node = Utils.getNoNil(speedRotatingPart.driveNode, speedRotatingPart.shaderNode) |
180 | speedRotatingPart.componentNode = self:getParentComponent(node) |
181 | end |
182 | |
183 | speedRotatingPart.xDrive = 0 |
184 | local wheelIndex = getXMLInt(xmlFile, key.."#wheelIndex") |
185 | if wheelIndex ~= nil then |
186 | if self.getWheels == nil then |
187 | g_logManager:xmlWarning(self.configFileName, "wheelIndex for speedRotatingPart '%s' given, but no wheels loaded/defined", key) |
188 | else |
189 | local wheels = self:getWheels() |
190 | local wheel = wheels[wheelIndex] |
191 | if wheel == nil then |
192 | g_logManager:xmlWarning(self.configFileName, "Invalid wheel index '%s' for speedRotatingPart '%s'", tostring(wheelIndex), key) |
193 | return false |
194 | end |
195 | if not wheel.isSynchronized then |
196 | g_logManager:xmlDevWarning(self.configFileName, "referenced wheel with index '%s' for speedRotatingPart '%s' is not synchronized in multiplayer", tostring(wheelIndex), key) |
197 | end |
198 | speedRotatingPart.wheel = wheel |
199 | speedRotatingPart.lastWheelXRot = 0 |
200 | end |
201 | end |
202 | |
203 | speedRotatingPart.dirRefNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#dirRefNode"), self.i3dMappings) |
204 | speedRotatingPart.dirFrameNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#dirFrameNode"), self.i3dMappings) |
205 | speedRotatingPart.alignDirection = Utils.getNoNil(getXMLBool(xmlFile, key .. "#alignDirection"), false) |
206 | speedRotatingPart.applySteeringAngle = Utils.getNoNil(getXMLBool(xmlFile, key .. "#applySteeringAngle"), false) |
207 | speedRotatingPart.useWheelReprTranslation = Utils.getNoNil(getXMLBool(xmlFile, key .. "#useWheelReprTranslation"), true) |
208 | speedRotatingPart.updateXDrive = Utils.getNoNil(getXMLBool(xmlFile, key .. "#updateXDrive"), true) |
209 | |
210 | speedRotatingPart.versatileYRot = Utils.getNoNil(getXMLBool(xmlFile, key .. "#versatileYRot"), false) |
211 | if speedRotatingPart.versatileYRot and speedRotatingPart.repr == nil then |
212 | g_logManager:xmlWarning(self.configFileName, "Versatile speedRotationPart '%s' does not support shaderNodes", key) |
213 | return false |
214 | end |
215 | |
216 | local minYRot = getXMLFloat(xmlFile, key .. "#minYRot") |
217 | if minYRot ~= nil then |
218 | speedRotatingPart.minYRot = math.rad(minYRot) |
219 | end |
220 | local maxYRot = getXMLFloat(xmlFile, key .. "#maxYRot") |
221 | if maxYRot ~= nil then |
222 | speedRotatingPart.maxYRot = math.rad(maxYRot) |
223 | end |
224 | speedRotatingPart.steeringAngle = 0 |
225 | speedRotatingPart.steeringAngleSent = 0 |
226 | |
227 | speedRotatingPart.wheelScale = getXMLFloat(xmlFile, key .. "#wheelScale") |
228 | if speedRotatingPart.wheelScale == nil then |
229 | local baseRadius = 1.0 |
230 | local radius = 1.0 |
231 | if speedRotatingPart.wheel ~= nil then |
232 | baseRadius = speedRotatingPart.wheel.radius |
233 | radius = speedRotatingPart.wheel.radius |
234 | end |
235 | speedRotatingPart.wheelScale = baseRadius / Utils.getNoNil(getXMLFloat(xmlFile, key.."#radius"), radius) |
236 | end |
237 | |
238 | speedRotatingPart.wheelScaleBackup = speedRotatingPart.wheelScale |
239 | |
240 | speedRotatingPart.onlyActiveWhenLowered = Utils.getNoNil(getXMLBool(xmlFile, key .. "#onlyActiveWhenLowered"), false) |
241 | speedRotatingPart.stopIfNotActive = Utils.getNoNil(getXMLBool(xmlFile, key .. "#stopIfNotActive"), false) |
242 | speedRotatingPart.fadeOutTime = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#fadeOutTime"), 3) * 1000 |
243 | speedRotatingPart.activationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#activationSpeed"), 1) |
244 | speedRotatingPart.speedReferenceNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#speedReferenceNode"), self.i3dMappings) |
245 | if speedRotatingPart.speedReferenceNode ~= nil and speedRotatingPart.speedReferenceNode == speedRotatingPart.driveNode then |
246 | g_logManager:xmlWarning(self.configFileName, "Ignoring speedRotationPart '%s' because speedReferenceNode is identical with driveNode. Need to be different!", key) |
247 | return false |
248 | end |
249 | speedRotatingPart.lastSpeed = 0 |
250 | speedRotatingPart.lastDir = 1 |
251 | |
252 | return true |
253 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
50 | function SpeedRotatingParts:onLoad(savegame) |
51 | local spec = self.spec_speedRotatingParts |
52 | |
53 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.speedRotatingParts.speedRotatingPart(0)#index", "vehicle.speedRotatingParts.speedRotatingPart(0)#node") -- FS17 |
54 | |
55 | spec.speedRotatingParts = {} |
56 | local i = 0 |
57 | while true do |
58 | local baseName = string.format("vehicle.speedRotatingParts.speedRotatingPart(%d)", i) |
59 | if not hasXMLProperty(self.xmlFile, baseName) then |
60 | break |
61 | end |
62 | local speedRotatingPart = {} |
63 | if self:loadSpeedRotatingPartFromXML(speedRotatingPart, self.xmlFile, baseName) then |
64 | table.insert(spec.speedRotatingParts, speedRotatingPart) |
65 | end |
66 | i = i + 1 |
67 | end |
68 | |
69 | spec.dirtyFlag = self:getNextDirtyFlag() |
70 | end |
onReadStream
DescriptionCalled on client side on joinDefinition
onReadStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
76 | function SpeedRotatingParts:onReadStream(streamId, connection) |
77 | local spec = self.spec_speedRotatingParts |
78 | for _, speedRotatingPart in pairs(spec.speedRotatingParts) do |
79 | if speedRotatingPart.versatileYRot then |
80 | local yRot = streamReadUIntN(streamId, 9) |
81 | speedRotatingPart.steeringAngle = yRot / 511 * math.pi*2 |
82 | end |
83 | end |
84 | end |
onReadUpdateStream
DescriptionCalled on on updateDefinition
onReadUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
104 | function SpeedRotatingParts:onReadUpdateStream(streamId, timestamp, connection) |
105 | if connection.isServer then |
106 | local spec = self.spec_speedRotatingParts |
107 | local hasUpdate = streamReadBool(streamId) |
108 | if hasUpdate then |
109 | for _, speedRotatingPart in pairs(spec.speedRotatingParts) do |
110 | if speedRotatingPart.versatileYRot then |
111 | local yRot = streamReadUIntN(streamId, 9) |
112 | speedRotatingPart.steeringAngle = yRot / 511 * math.pi*2 |
113 | end |
114 | end |
115 | end |
116 | end |
117 | end |
onUpdate
DescriptionCalled on updateDefinition
onUpdate(float dt, boolean isActiveForInput, boolean isSelected)Arguments
float | dt | time since last call in ms |
boolean | isActiveForInput | true if vehicle is active for input |
boolean | isSelected | true if vehicle is selected |
143 | function SpeedRotatingParts:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
144 | local spec = self.spec_speedRotatingParts |
145 | |
146 | for _, speedRotatingPart in pairs(spec.speedRotatingParts) do |
147 | local isPartActive = self:getIsSpeedRotatingPartActive(speedRotatingPart) |
148 | if isPartActive or (speedRotatingPart.lastSpeed ~= 0 and not speedRotatingPart.stopIfNotActive) then |
149 | self:updateSpeedRotatingPart(speedRotatingPart, dt, isPartActive) |
150 | end |
151 | end |
152 | end |
onWriteStream
DescriptionCalled on server side on joinDefinition
onWriteStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
90 | function SpeedRotatingParts:onWriteStream(streamId, connection) |
91 | local spec = self.spec_speedRotatingParts |
92 | for _, speedRotatingPart in pairs(spec.speedRotatingParts) do |
93 | if speedRotatingPart.versatileYRot then |
94 | streamWriteUIntN(streamId, MathUtil.clamp(math.floor(speedRotatingPart.steeringAngle / (math.pi*2) * 511), 0, 511), 9) |
95 | end |
96 | end |
97 | end |
onWriteUpdateStream
DescriptionCalled on on updateDefinition
onWriteUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
124 | function SpeedRotatingParts:onWriteUpdateStream(streamId, connection, dirtyMask) |
125 | if not connection.isServer then |
126 | local spec = self.spec_speedRotatingParts |
127 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
128 | for _, speedRotatingPart in pairs(spec.speedRotatingParts) do |
129 | if speedRotatingPart.versatileYRot then |
130 | local yRot = speedRotatingPart.steeringAngle % (math.pi*2) |
131 | streamWriteUIntN(streamId, MathUtil.clamp(math.floor(yRot / (math.pi*2) * 511), 0, 511), 9) |
132 | end |
133 | end |
134 | end |
135 | end |
136 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
17 | function SpeedRotatingParts.prerequisitesPresent(specializations) |
18 | return true |
19 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
38 | function SpeedRotatingParts.registerEventListeners(vehicleType) |
39 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", SpeedRotatingParts) |
40 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", SpeedRotatingParts) |
41 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", SpeedRotatingParts) |
42 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", SpeedRotatingParts) |
43 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", SpeedRotatingParts) |
44 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", SpeedRotatingParts) |
45 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
23 | function SpeedRotatingParts.registerFunctions(vehicleType) |
24 | SpecializationUtil.registerFunction(vehicleType, "loadSpeedRotatingPartFromXML", SpeedRotatingParts.loadSpeedRotatingPartFromXML) |
25 | SpecializationUtil.registerFunction(vehicleType, "getIsSpeedRotatingPartActive", SpeedRotatingParts.getIsSpeedRotatingPartActive) |
26 | SpecializationUtil.registerFunction(vehicleType, "getSpeedRotatingPartDirection", SpeedRotatingParts.getSpeedRotatingPartDirection) |
27 | SpecializationUtil.registerFunction(vehicleType, "updateSpeedRotatingPart", SpeedRotatingParts.updateSpeedRotatingPart) |
28 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
32 | function SpeedRotatingParts.registerOverwrittenFunctions(vehicleType) |
33 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "validateWashableNode", SpeedRotatingParts.validateWashableNode) |
34 | end |
updateSpeedRotatingPart
DescriptionDefinitionupdateSpeedRotatingPart()Code
281 | function SpeedRotatingParts:updateSpeedRotatingPart(speedRotatingPart, dt, isPartActive) |
282 | local spec = self.spec_speedRotatingParts |
283 | local speed = speedRotatingPart.lastSpeed |
284 | local dir = speedRotatingPart.lastDir |
285 | |
286 | -- use angle from the repr node since the repr node could be rotated by another spec |
287 | if speedRotatingPart.repr ~= nil then |
288 | _, speedRotatingPart.steeringAngle, _ = getRotation(speedRotatingPart.repr) |
289 | end |
290 | |
291 | if isPartActive then |
292 | if speedRotatingPart.wheel ~= nil then |
293 | |
294 | local rotDiff = speedRotatingPart.wheel.netInfo.xDrive - speedRotatingPart.lastWheelXRot |
295 | if rotDiff > math.pi then |
296 | rotDiff = rotDiff - (2*math.pi) |
297 | elseif rotDiff < -math.pi then |
298 | rotDiff = rotDiff + (2*math.pi) |
299 | end |
300 | speed = math.abs(rotDiff) |
301 | dir = MathUtil.sign(rotDiff) |
302 | speedRotatingPart.lastWheelXRot = speedRotatingPart.wheel.netInfo.xDrive |
303 | |
304 | _, speedRotatingPart.steeringAngle, _ = getRotation(speedRotatingPart.wheel.repr) |
305 | |
306 | elseif speedRotatingPart.speedReferenceNode ~= nil then |
307 | local newX, newY, newZ = getWorldTranslation(speedRotatingPart.speedReferenceNode) |
308 | if speedRotatingPart.lastPosition == nil then |
309 | speedRotatingPart.lastPosition = {newX, newY, newZ} |
310 | end |
311 | |
312 | local dx, dy, dz = worldDirectionToLocal(speedRotatingPart.speedReferenceNode, newX-speedRotatingPart.lastPosition[1], newY-speedRotatingPart.lastPosition[2], newZ-speedRotatingPart.lastPosition[3]) |
313 | speed = MathUtil.vector3Length(dx, dy, dz) |
314 | |
315 | if dz > 0.001 then |
316 | dir = 1 |
317 | elseif dz < -0.001 then |
318 | dir = -1 |
319 | else |
320 | dir = 0 |
321 | end |
322 | |
323 | speedRotatingPart.lastPosition[1], speedRotatingPart.lastPosition[2], speedRotatingPart.lastPosition[3] = newX, newY, newZ |
324 | else |
325 | speed = self.lastSpeedReal * dt |
326 | dir = self.movingDirection |
327 | end |
328 | speedRotatingPart.brakeForce = speed * dt/speedRotatingPart.fadeOutTime |
329 | else |
330 | speed = math.max(speed - speedRotatingPart.brakeForce, 0) |
331 | end |
332 | |
333 | speedRotatingPart.lastSpeed = speed |
334 | speedRotatingPart.lastDir = dir |
335 | if speedRotatingPart.updateXDrive then |
336 | speedRotatingPart.xDrive = speedRotatingPart.xDrive + speed * dir * self:getSpeedRotatingPartDirection(speedRotatingPart) * speedRotatingPart.wheelScale |
337 | end |
338 | |
339 | if speedRotatingPart.versatileYRot then |
340 | if speed > 0.0017 then -- 0.1deg threshold cause float accuracy |
341 | if self.isServer and self:getLastSpeed(true) > speedRotatingPart.activationSpeed then |
342 | local posX, posY, posZ = localToLocal(speedRotatingPart.repr, speedRotatingPart.componentNode, 0,0,0) |
343 | speedRotatingPart.steeringAngle = Utils.getVersatileRotation(speedRotatingPart.repr, speedRotatingPart.componentNode, dt, posX, posY, posZ, speedRotatingPart.steeringAngle, speedRotatingPart.minYRot, speedRotatingPart.maxYRot) |
344 | if math.abs(speedRotatingPart.steeringAngleSent-speedRotatingPart.steeringAngle) > 0.1 then |
345 | speedRotatingPart.steeringAngleSent = speedRotatingPart.steeringAngle |
346 | self:raiseDirtyFlags(spec.dirtyFlag) |
347 | end |
348 | end |
349 | end |
350 | else |
351 | if speedRotatingPart.componentNode ~= nil and speedRotatingPart.dirRefNode ~= nil and not speedRotatingPart.alignDirection then |
352 | speedRotatingPart.steeringAngle = Utils.getYRotationBetweenNodes(speedRotatingPart.componentNode, speedRotatingPart.dirRefNode) |
353 | local _,yTrans,_ = localToLocal(speedRotatingPart.driveNode, speedRotatingPart.wheel.driveNode, 0, 0, 0) |
354 | setTranslation(speedRotatingPart.driveNode, 0, yTrans, 0) |
355 | end |
356 | |
357 | if speedRotatingPart.dirRefNode ~= nil and speedRotatingPart.alignDirection then |
358 | local upX, upY, upZ = localDirectionToWorld(speedRotatingPart.dirFrameNode, 0, 1, 0) |
359 | local dirX, dirY, dirZ = localDirectionToWorld(speedRotatingPart.dirRefNode, 0, 0, 1) |
360 | I3DUtil.setWorldDirection(speedRotatingPart.repr, dirX, dirY, dirZ, upX, upY, upZ, 2) |
361 | if speedRotatingPart.wheel ~= nil and speedRotatingPart.useWheelReprTranslation then |
362 | local _,yTrans,_ = localToLocal(speedRotatingPart.wheel.driveNode, getParent(speedRotatingPart.repr), 0,0,0) |
363 | setTranslation(speedRotatingPart.repr, 0, yTrans, 0) |
364 | end |
365 | end |
366 | end |
367 | |
368 | if speedRotatingPart.driveNode ~= nil then |
369 | if speedRotatingPart.repr == speedRotatingPart.driveNode then |
370 | local steeringAngle =speedRotatingPart.steeringAngle |
371 | if not speedRotatingPart.applySteeringAngle then |
372 | steeringAngle = 0 |
373 | end |
374 | |
375 | setRotation(speedRotatingPart.repr, speedRotatingPart.xDrive, steeringAngle, 0) |
376 | else |
377 | if not speedRotatingPart.alignDirection and (speedRotatingPart.versatileYRot or speedRotatingPart.applySteeringAngle) then |
378 | setRotation(speedRotatingPart.repr, 0, speedRotatingPart.steeringAngle, 0) |
379 | end |
380 | setRotation(speedRotatingPart.driveNode, speedRotatingPart.xDrive, 0, 0) |
381 | end |
382 | end |
383 | |
384 | if speedRotatingPart.shaderNode ~= nil then |
385 | if speedRotatingPart.useShaderRotation then |
386 | setShaderParameter(speedRotatingPart.shaderNode, "offsetUV", 0, 0, speedRotatingPart.xDrive, 0, false) |
387 | else |
388 | local pos = (speedRotatingPart.xDrive % math.pi) / (2*math.pi) -- normalize rotation |
389 | setShaderParameter(speedRotatingPart.shaderNode, "offsetUV", pos*speedRotatingPart.scrollScale[1], pos*speedRotatingPart.scrollScale[2], 0, 0, false) |
390 | end |
391 | end |
392 | end |
validateWashableNode
DescriptionDefinitionvalidateWashableNode()Code
396 | function SpeedRotatingParts:validateWashableNode(superFunc, node) |
397 | local spec = self.spec_speedRotatingParts |
398 | for _, speedRotatingPart in pairs(spec.speedRotatingParts) do |
399 | if speedRotatingPart.wheel ~= nil then |
400 | local speedRotatingPartsNodes = {} |
401 | |
402 | if speedRotatingPart.repr ~= nil then |
403 | I3DUtil.getNodesByShaderParam(speedRotatingPart.repr, "RDT", speedRotatingPartsNodes) |
404 | end |
405 | |
406 | if speedRotatingPart.shaderNode ~= nil then |
407 | I3DUtil.getNodesByShaderParam(speedRotatingPart.shaderNode, "RDT", speedRotatingPartsNodes) |
408 | end |
409 | |
410 | if speedRotatingPart.driveNode ~= nil then |
411 | I3DUtil.getNodesByShaderParam(speedRotatingPart.driveNode, "RDT", speedRotatingPartsNodes) |
412 | end |
413 | |
414 | if speedRotatingPartsNodes[node] ~= nil then |
415 | return false, self.updateWheelDirtAmount, speedRotatingPart.wheel, {wheel=speedRotatingPart.wheel, fieldDirtMultiplier=speedRotatingPart.wheel.fieldDirtMultiplier, streetDirtMultiplier=speedRotatingPart.wheel.streetDirtMultiplier, minDirtPercentage=speedRotatingPart.wheel.minDirtPercentage} |
416 | end |
417 | end |
418 | end |
419 | |
420 | return superFunc(self, node) |
421 | end |