LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

ArticulatedAxis

Description
Specialization for vehicles which steer with an articulated axis (excavators, loaders ...)
Functions

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
32function ArticulatedAxis:onLoad(savegame)
33 local xmlFile = self.xmlFile
34 local spec = self.spec_articulatedAxis
35
36 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.articulatedAxis.rotatingPart(0)#index", "vehicle.articulatedAxis.rotatingPart(0)#node") -- FS17
37
38 local index = getXMLInt(xmlFile, "vehicle.articulatedAxis#componentJointIndex")
39 if index ~= nil then
40 if index == 0 then
41 g_logManager:xmlWarning(self.configFileName, "Invalid component joint index '0' for articulatedAxis. Indices start with 1!")
42 else
43 local componentJoint = self.componentJoints[index]
44 local rotSpeed = getXMLFloat(xmlFile, "vehicle.articulatedAxis#rotSpeed")
45 local rotMax = getXMLFloat(xmlFile, "vehicle.articulatedAxis#rotMax")
46 local rotMin = getXMLFloat(xmlFile, "vehicle.articulatedAxis#rotMin")
47 if componentJoint ~= nil and rotSpeed ~= nil and rotMax ~= nil and rotMin ~= nil then
48 spec.rotSpeed = math.rad(rotSpeed)
49 spec.rotMax = math.rad(rotMax)
50 spec.rotMin = math.rad(rotMin)
51
52 spec.componentJoint = componentJoint
53 spec.anchorActor = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.articulatedAxis#anchorActor"), 0)
54 spec.rotationNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, "vehicle.articulatedAxis#rotNode"), self.i3dMappings)
55 if spec.rotationNode == nil then
56 spec.rotationNode = spec.componentJoint.jointNode
57 end
58
59 spec.curRot = 0
60
61 local i = 0
62 spec.rotatingParts = {}
63 while true do
64 local key = string.format("vehicle.articulatedAxis.rotatingPart(%d)", i)
65 if not hasXMLProperty(xmlFile, key) then
66 break
67 end
68
69 local node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key .. "#node"), self.i3dMappings)
70 if node ~= nil then
71 local rotatingPart = {}
72 rotatingPart.node = node
73 rotatingPart.defRot = {getRotation(node)}
74 rotatingPart.posRot = StringUtil.getRadiansFromString(getXMLString(xmlFile, key .. "#posRot"), 3)
75 rotatingPart.negRot = StringUtil.getRadiansFromString(getXMLString(xmlFile, key .. "#negRot"), 3)
76 rotatingPart.negRotFactor = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#negRotFactor"), 1)
77 rotatingPart.posRotFactor = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#posRotFactor"), 1)
78 rotatingPart.invertSteeringAngle = Utils.getNoNil(getXMLBool(xmlFile, key .. "#invertSteeringAngle"), false)
79 table.insert(spec.rotatingParts, rotatingPart)
80 else
81 g_logManager:xmlWarning(self.configFileName, "Failed to load rotation part '%s'", key)
82 end
83 i = i + 1
84 end
85
86 -- adjust steering values
87 local maxRotTime = rotMax/rotSpeed
88 local minRotTime = rotMin/rotSpeed
89 if minRotTime > maxRotTime then
90 local temp = minRotTime
91 minRotTime = maxRotTime
92 maxRotTime = temp
93 end
94 if maxRotTime > self.maxRotTime then
95 self.maxRotTime = maxRotTime
96 end
97 if minRotTime < self.minRotTime then
98 self.minRotTime = minRotTime
99 end
100
101 self.maxRotation = rotMax
102 self.wheelSteeringDuration = MathUtil.sign(rotSpeed) * rotMax / rotSpeed
103
104 -- adjust variables used by AIVehicleUtil
105 local aiReverserNodeString = getXMLString(xmlFile, "vehicle.articulatedAxis#aiRevereserNode")
106 if aiReverserNodeString ~= nil then
107 spec.aiRevereserNode = I3DUtil.indexToObject(self.components, aiReverserNodeString, self.i3dMappings)
108 end
109
110 local maxTurningRadius = 0
111 local specWheels = self.spec_wheels
112 for i=1,2 do
113 local rootNode = self.components[componentJoint.componentIndices[i]].node
114
115 for _, wheel in ipairs(specWheels.wheels) do
116 if self:getParentComponent(wheel.repr) == rootNode then
117
118 local wx,_,wz = localToLocal(wheel.driveNode, rootNode, 0,0,0)
119 local dx1 = 1
120 if wx < 0 then
121 dx1 = -1
122 end
123 local dz1 = math.tan( math.max(wheel.rotMin, wheel.rotMax) )
124 if wz > 0 then
125 dz1 = -dz1
126 end
127
128 local x2, z2 = 0, 0
129 local dx2 = 1
130 if wx < 0 then
131 dx2 = -1
132 end
133 local dz2 = math.tan( math.max(rotMin, rotMax) )
134 if wz < 0 then
135 dz2 = -dz2
136 end
137
138 -- normalize directions
139 local l1 = MathUtil.vector2Length(dx1, dz1)
140 dx1, dz1 = dx1 / l1, dz1 / l1
141
142 local l2 = MathUtil.vector2Length(dx2, dz2)
143 dx2, dz2 = dx2 / l2, dz2 / l2
144
145 local intersect, _, f2 = MathUtil.getLineLineIntersection2D(wx,wz, dx1,dz1, x2,z2, dx2,dz2)
146 if intersect then
147 local radius = math.abs(f2)
148 maxTurningRadius = math.max(maxTurningRadius, radius)
149 end
150 end
151 end
152 end
153
154 if maxTurningRadius ~= 0 then
155 self.maxTurningRadius = maxTurningRadius
156 end
157 end
158 end
159 end
160
161 spec.interpolatedRotatedTime = 0
162end

onPostLoad

Description
Definition
onPostLoad()
Code
166function ArticulatedAxis:onPostLoad()
167 local spec = self.spec_articulatedAxis
168 if spec.componentJoint ~= nil then
169 if self.updateArticulatedAxisRotation ~= nil then
170 self:updateArticulatedAxisRotation(0, 99999)
171 end
172 end
173end

onUpdate

Description
Called on update
Definition
onUpdate(float dt, boolean isActiveForInput, boolean isSelected)
Arguments
floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
180function ArticulatedAxis:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
181 local spec = self.spec_articulatedAxis
182 if spec.componentJoint ~= nil then
183 -- interpolatedRotatedTime to manipulate camera rot
184 if spec.interpolatedRotatedTime < self.rotatedTime then
185 spec.interpolatedRotatedTime = math.min(self.rotatedTime, spec.interpolatedRotatedTime + math.abs(spec.rotSpeed) * dt/500)
186 elseif spec.interpolatedRotatedTime > self.rotatedTime then
187 spec.interpolatedRotatedTime = math.max(self.rotatedTime, spec.interpolatedRotatedTime - math.abs(spec.rotSpeed) * dt/500)
188 end
189
190 local steeringAngle = MathUtil.clamp(self.rotatedTime * spec.rotSpeed, spec.rotMin, spec.rotMax)
191 if self.updateArticulatedAxisRotation ~= nil then
192 steeringAngle = self:updateArticulatedAxisRotation(steeringAngle, dt)
193 end
194
195 if math.abs(steeringAngle - spec.curRot) > 0.000001 then
196 if self.isServer then
197 setRotation(spec.rotationNode, 0, steeringAngle, 0)
198 self:setComponentJointFrame(spec.componentJoint, spec.anchorActor)
199 spec.curRot = steeringAngle
200 end
201
202 if self.isClient then
203 local percent = 0
204 if steeringAngle > 0 then
205 percent = steeringAngle / spec.rotMax
206 elseif steeringAngle < 0 then
207 percent = steeringAngle / spec.rotMin
208 end
209
210 for _,rotPart in pairs(spec.rotatingParts) do
211 local rx,ry,rz
212 if (steeringAngle > 0 and not rotPart.invertSteeringAngle) or (steeringAngle < 0 and rotPart.invertSteeringAngle) then
213 rx,ry,rz = MathUtil.vector3ArrayLerp(rotPart.defRot, rotPart.posRot, math.min(1,percent*rotPart.posRotFactor))
214 else
215 rx,ry,rz = MathUtil.vector3ArrayLerp(rotPart.defRot, rotPart.negRot, math.min(1,percent*rotPart.negRotFactor))
216 end
217 setRotation(rotPart.node, rx,ry,rz)
218 if self.setMovingToolDirty ~= nil then
219 self:setMovingToolDirty(rotPart.node)
220 end
221 end
222 end
223 end
224 end
225end

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 ArticulatedAxis.prerequisitesPresent(specializations)
18 return SpecializationUtil.hasSpecialization(Drivable, specializations)
19end

registerEventListeners

Description
Definition
registerEventListeners()
Code
23function ArticulatedAxis.registerEventListeners(vehicleType)
24 SpecializationUtil.registerEventListener(vehicleType, "onLoad", ArticulatedAxis)
25 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", ArticulatedAxis)
26 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", ArticulatedAxis)
27end