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
RandomlyMovingParts
DescriptionSpecialization for making parts randomly move during work using rotation changesFunctions
- getIsRandomlyMovingPartActive
- loadRandomlyMovingPartFromXML
- onLoad
- onUpdate
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- updateRandomlyMovingPart
- updateRotationTargetValues
getIsRandomlyMovingPartActive
DescriptionReturns if randomly moving part is activeDefinition
getIsRandomlyMovingPartActive(table part)Arguments
table | part | part to check |
boolean | isActive | is active |
218 | function RandomlyMovingParts:getIsRandomlyMovingPartActive(part) |
219 | local retValue = true |
220 | if part.groundReferenceNode ~= nil then |
221 | retValue = self:getIsGroundReferenceNodeActive(part.groundReferenceNode) |
222 | end |
223 | |
224 | return retValue |
225 | end |
loadRandomlyMovingPartFromXML
DescriptionLoad randomly moving part from xmlDefinition
loadRandomlyMovingPartFromXML(table part, integer xmlFile, string key)Arguments
table | part | part |
integer | xmlFile | id of xml object |
string | key | key |
boolean | success |
78 | function RandomlyMovingParts:loadRandomlyMovingPartFromXML(part, xmlFile, key) |
79 | if not hasXMLProperty(self.xmlFile, key) then |
80 | return false |
81 | end |
82 | |
83 | XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key .. "#index", key .. "#node") --FS17 to FS19 |
84 | |
85 | local node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#node"), self.i3dMappings) |
86 | if node == nil then |
87 | g_logManager:xmlWarning(self.configFileName, "Unknown node for randomlyMovingPart in '%s'", key) |
88 | return false |
89 | end |
90 | |
91 | part.node = node |
92 | |
93 | if self.getGroundReferenceNodeFromIndex ~= nil then |
94 | local refNodeIndex = getXMLInt(xmlFile, key .. "#refNodeIndex") |
95 | if refNodeIndex ~= nil then |
96 | if refNodeIndex ~= 0 then |
97 | local groundReferenceNode = self:getGroundReferenceNodeFromIndex(refNodeIndex) |
98 | if groundReferenceNode ~= nil then |
99 | part.groundReferenceNode = groundReferenceNode |
100 | end |
101 | else |
102 | g_logManager:xmlWarning(self.configFileName, "Unknown ground reference node in '%s'! Indices start with '0'", key.."#refNodeIndex") |
103 | end |
104 | end |
105 | end |
106 | |
107 | local rx, ry, rz = getRotation(part.node) |
108 | local rotMean = StringUtil.getRadiansFromString(getXMLString(xmlFile, key .. "#rotMean"), 2) |
109 | if rotMean then |
110 | part.rotOrig = {rx, ry, rz} |
111 | part.rotCur = {rx, ry, rz} |
112 | |
113 | part.rotAxis = getXMLInt(xmlFile, key .. "#rotAxis") |
114 | |
115 | part.rotMean = rotMean |
116 | part.rotVar = StringUtil.getRadiansFromString(getXMLString(xmlFile, key .. "#rotVariance"), 2) |
117 | |
118 | part.rotTimeMean = StringUtil.getVectorNFromString(getXMLString(xmlFile, key .. "#rotTimeMean"), 2) |
119 | part.rotTimeVar = StringUtil.getVectorNFromString(getXMLString(xmlFile, key .. "#rotTimeVariance"), 2) |
120 | |
121 | part.pauseMean = StringUtil.getVectorNFromString(getXMLString(xmlFile, key .. "#pauseMean"), 2) |
122 | part.pauseVar = StringUtil.getVectorNFromString(getXMLString(xmlFile, key .. "#pauseVariance"), 2) |
123 | |
124 | for i=1,2 do |
125 | part.rotTimeMean[i] = part.rotTimeMean[i] * 1000 |
126 | part.rotTimeVar[i] = part.rotTimeVar[i] * 1000 |
127 | part.pauseMean[i] = part.pauseMean[i] * 1000 |
128 | part.pauseVar[i] = part.pauseVar[i] * 1000 |
129 | end |
130 | |
131 | part.rotTarget = {} |
132 | part.rotSpeed = {} |
133 | part.pause = {} |
134 | |
135 | part.isSpeedDependent = Utils.getNoNil(getXMLBool(xmlFile, key .. "#isSpeedDependent"), false) |
136 | |
137 | self:updateRotationTargetValues(part) |
138 | end |
139 | |
140 | part.nextMoveTime = g_currentMission.time + part.pause[2] |
141 | part.curMoveDirection = 1 |
142 | part.isActive = true |
143 | |
144 | return true |
145 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
40 | function RandomlyMovingParts:onLoad(savegame) |
41 | local spec = self.spec_randomlyMovingParts |
42 | |
43 | spec.nodes = {} |
44 | local i = 0 |
45 | while true do |
46 | local baseName = string.format("vehicle.randomlyMovingParts.randomlyMovingPart(%d)", i) |
47 | if not hasXMLProperty(self.xmlFile, baseName) then |
48 | break |
49 | end |
50 | |
51 | local randomlyMovingPart = {} |
52 | if self:loadRandomlyMovingPartFromXML(randomlyMovingPart, self.xmlFile, baseName) then |
53 | table.insert(spec.nodes, randomlyMovingPart) |
54 | end |
55 | |
56 | i = i + 1 |
57 | end |
58 | 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 |
65 | function RandomlyMovingParts:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
66 | local spec = self.spec_randomlyMovingParts |
67 | for _, part in pairs(spec.nodes) do |
68 | self:updateRandomlyMovingPart(part, dt) |
69 | end |
70 | 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 RandomlyMovingParts.prerequisitesPresent(specializations) |
18 | return true |
19 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
32 | function RandomlyMovingParts.registerEventListeners(vehicleType) |
33 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", RandomlyMovingParts) |
34 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", RandomlyMovingParts) |
35 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
23 | function RandomlyMovingParts.registerFunctions(vehicleType) |
24 | SpecializationUtil.registerFunction(vehicleType, "loadRandomlyMovingPartFromXML", RandomlyMovingParts.loadRandomlyMovingPartFromXML) |
25 | SpecializationUtil.registerFunction(vehicleType, "updateRandomlyMovingPart", RandomlyMovingParts.updateRandomlyMovingPart) |
26 | SpecializationUtil.registerFunction(vehicleType, "updateRotationTargetValues", RandomlyMovingParts.updateRotationTargetValues) |
27 | SpecializationUtil.registerFunction(vehicleType, "getIsRandomlyMovingPartActive", RandomlyMovingParts.getIsRandomlyMovingPartActive) |
28 | end |
updateRandomlyMovingPart
DescriptionUpdate randomly moving partsDefinition
updateRandomlyMovingPart(table part, float dt)Arguments
table | part | part to update |
float | dt | time since last call in ms |
boolean | updated | part was updated |
152 | function RandomlyMovingParts:updateRandomlyMovingPart(part, dt) |
153 | if part.nextMoveTime < g_currentMission.time then |
154 | local speed = dt |
155 | if part.isSpeedDependent then |
156 | speed = speed * math.min(self:getLastSpeed() / self:getSpeedLimit(true), 1) |
157 | end |
158 | |
159 | part.isActive = self:getIsRandomlyMovingPartActive(part) |
160 | if part.curMoveDirection > 0 then |
161 | if part.isActive then |
162 | part.rotCur[part.rotAxis] = math.min(part.rotTarget[1], part.rotCur[part.rotAxis] + (part.rotSpeed[1] * speed)) |
163 | if part.rotCur[part.rotAxis] == part.rotTarget[1] then |
164 | part.curMoveDirection = -1 |
165 | part.nextMoveTime = g_currentMission.time + part.pause[1] |
166 | end |
167 | end |
168 | else |
169 | part.rotCur[part.rotAxis] = math.max(part.rotTarget[2], part.rotCur[part.rotAxis] + (part.rotSpeed[2] * speed)) |
170 | if part.rotCur[part.rotAxis] == part.rotTarget[2] then |
171 | -- start next movement only if active |
172 | if part.isActive then |
173 | part.curMoveDirection = 1 |
174 | part.nextMoveTime = g_currentMission.time + part.pause[2] |
175 | self:updateRotationTargetValues(part) |
176 | end |
177 | end |
178 | end |
179 | |
180 | setRotation(part.node, part.rotCur[1], part.rotCur[2], part.rotCur[3]) |
181 | |
182 | if self.setMovingToolDirty ~= nil then |
183 | self:setMovingToolDirty(part.node) |
184 | end |
185 | |
186 | return true |
187 | else |
188 | return false |
189 | end |
190 | end |
updateRotationTargetValues
DescriptionUpdate rotation target valuesDefinition
updateRotationTargetValues(table part)Arguments
table | part | part to update |
195 | function RandomlyMovingParts:updateRotationTargetValues(part) |
196 | for i=1,2 do |
197 | part.rotTarget[i] = part.rotMean[i] + (part.rotVar[i] * (-0.5 + math.random())) |
198 | end |
199 | |
200 | for i=1,2 do |
201 | local rotTime = part.rotTimeMean[i] + (part.rotTimeVar[i] * (-0.5 + math.random())) |
202 | if i == 1 then |
203 | part.rotSpeed[i] = (part.rotTarget[1] - part.rotTarget[2]) / rotTime |
204 | else |
205 | part.rotSpeed[i] = (part.rotTarget[2] - part.rotTarget[1]) / rotTime |
206 | end |
207 | end |
208 | |
209 | for i=1,2 do |
210 | part.pause[i] = part.pauseMean[i] + (part.pauseVar[i] * (-0.5 + math.random())) |
211 | end |
212 | end |