LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

Foldable

Description
Specialization for vehicle parts with two or three folding states (e.g. tedder, cultivator, sowing machine)
Functions

actionControllerFoldEvent

Description
Definition
actionControllerFoldEvent()
Code
1958function Foldable:actionControllerFoldEvent(direction)
1959 local spec = self.spec_foldable
1960
1961 if #spec.foldingParts > 0 then
1962 if self:getIsFoldMiddleAllowed() then
1963 if spec.foldAnimTime > 0 and spec.foldAnimTime < spec.foldMiddleAnimTime then
1964 return false
1965 end
1966 end
1967
1968 direction = spec.turnOnFoldDirection * direction
1969 if self:getIsFoldAllowed(direction, false) then
1970 if direction == spec.turnOnFoldDirection then
1971 self:setFoldState(direction, true)
1972 else
1973 self:setFoldState(direction, false)
1974 end
1975
1976 return true
1977 end
1978 end
1979
1980 return false
1981end

actionControllerLowerEvent

Description
Definition
actionControllerLowerEvent()
Code
1985function Foldable:actionControllerLowerEvent(direction)
1986 local spec = self.spec_foldable
1987
1988 if #spec.foldingParts > 0 then
1989 direction = spec.turnOnFoldDirection * direction
1990 if self:getIsFoldMiddleAllowed() then
1991 if direction == spec.turnOnFoldDirection then
1992 self:setFoldState(direction, false)
1993 else
1994 -- move to fold middle position, no matter where we are
1995 if spec.foldMiddleDirection > 0 then
1996 if spec.foldAnimTime >= spec.foldMiddleAnimTime - 0.01 then
1997 self:setFoldState(-direction, true)
1998 else
1999 self:setFoldState(direction, true)
2000 end
2001 else
2002 if spec.foldAnimTime <= spec.foldMiddleAnimTime + 0.01 then
2003 self:setFoldState(-direction, true)
2004 else
2005 self:setFoldState(direction, true)
2006 end
2007 end
2008 end
2009
2010 return true
2011 end
2012 end
2013
2014 return false
2015end

actionEventFold

Description
Definition
actionEventFold()
Code
2161function Foldable.actionEventFold(self, actionName, inputValue, callbackState, isAnalog)
2162 local spec = self.spec_foldable
2163
2164 if #spec.foldingParts > 0 then
2165 local toggleDirection = self:getToggledFoldDirection()
2166 local allowed, warning = self:getIsFoldAllowed(toggleDirection, false)
2167 if allowed then
2168 if toggleDirection == spec.turnOnFoldDirection then
2169 self:setFoldState(toggleDirection, true)
2170 else
2171 self:setFoldState(toggleDirection, false)
2172
2173 -- while using folding and the tool is still lowered
2174 -- so we need to lift up the attacher joint as well
2175 if self:getIsFoldMiddleAllowed() then
2176 if self.getAttacherVehicle ~= nil then
2177 local attacherVehicle = self:getAttacherVehicle()
2178 local attacherJointIndex = attacherVehicle:getAttacherJointIndexFromObject(self)
2179 if attacherJointIndex ~= nil then
2180 local moveDown = attacherVehicle:getJointMoveDown(attacherJointIndex)
2181 local targetMoveDown = toggleDirection == spec.turnOnFoldDirection
2182 if targetMoveDown ~= moveDown then
2183 attacherVehicle:setJointMoveDown(attacherJointIndex, targetMoveDown)
2184 end
2185 end
2186 end
2187 end
2188 end
2189 elseif warning ~= nil then
2190 g_currentMission:showBlinkingWarning(warning, 2000)
2191 end
2192 end
2193end

actionEventFoldAll

Description
Definition
actionEventFoldAll()
Code
2245function Foldable.actionEventFoldAll(self, actionName, inputValue, callbackState, isAnalog)
2246 local spec = self.spec_foldable
2247
2248 if #spec.foldingParts > 0 then
2249 local displayWarning = true
2250 local warningToDisplay = nil
2251 local toggleDirection = self:getToggledFoldDirection()
2252 local allowed, warning = self:getIsFoldAllowed(toggleDirection, false)
2253 if allowed then
2254 if toggleDirection == spec.turnOnFoldDirection then
2255 self:setFoldState(toggleDirection, true)
2256 else
2257 self:setFoldState(toggleDirection, false)
2258 end
2259 displayWarning = false
2260 elseif warning ~= nil then
2261 warningToDisplay = warning
2262 end
2263
2264 local vehicles = self.rootVehicle:getChildVehicles()
2265 for i=1, #vehicles do
2266 local vehicle = vehicles[i]
2267 if vehicle.setFoldState ~= nil then
2268 local spec2 = vehicle.spec_foldable
2269 if #spec2.foldingParts > 0 then
2270 local toggleDirection2 = vehicle:getToggledFoldDirection()
2271 local allowed2, warning2 = vehicle:getIsFoldAllowed(toggleDirection, false)
2272 if allowed2 then
2273 if (toggleDirection == spec.turnOnFoldDirection) == (toggleDirection2 == spec2.turnOnFoldDirection) then
2274 if toggleDirection2 == spec2.turnOnFoldDirection then
2275 vehicle:setFoldState(toggleDirection2, true)
2276 else
2277 vehicle:setFoldState(toggleDirection2, false)
2278 end
2279 displayWarning = false
2280 end
2281 elseif warning2 ~= nil then
2282 warningToDisplay = warning2
2283 end
2284 end
2285 end
2286 end
2287
2288 if displayWarning and warningToDisplay ~= nil then
2289 g_currentMission:showBlinkingWarning(warningToDisplay, 2000)
2290 end
2291 end
2292end

actionEventFoldMiddle

Description
Definition
actionEventFoldMiddle()
Code
2197function Foldable.actionEventFoldMiddle(self, actionName, inputValue, callbackState, isAnalog)
2198 local spec = self.spec_foldable
2199
2200 if #spec.foldingParts > 0 then
2201 if self:getIsFoldMiddleAllowed() then
2202 local ignoreFoldMiddle = false
2203 if spec.ignoreFoldMiddleWhileFolded then
2204 if self:getFoldAnimTime() > spec.foldMiddleAnimTime then
2205 ignoreFoldMiddle = true
2206 end
2207 end
2208
2209 if not ignoreFoldMiddle then
2210 local direction = self:getToggledFoldMiddleDirection()
2211 if direction ~= 0 then
2212 if direction == spec.turnOnFoldDirection then
2213 self:setFoldState(direction, false)
2214 else
2215 self:setFoldState(direction, true)
2216 end
2217
2218 -- equalize moveDown state of the attacher joint with the inverse fold middle state
2219 -- before we execute setJointMoveDown with the AttacherJoints.actionEventLowerImplement below
2220 -- so the fold middle state and the joint move down state are always in line
2221 if self.getAttacherVehicle ~= nil then
2222 local attacherVehicle = self:getAttacherVehicle()
2223 local attacherJointIndex = attacherVehicle:getAttacherJointIndexFromObject(self)
2224 if attacherJointIndex ~= nil then
2225 local moveDown = attacherVehicle:getJointMoveDown(attacherJointIndex)
2226 local targetMoveDown = direction == spec.turnOnFoldDirection
2227 if targetMoveDown ~= moveDown then
2228 attacherVehicle:setJointMoveDown(attacherJointIndex, targetMoveDown)
2229 end
2230 end
2231 end
2232 end
2233 else
2234 local attacherVehicle = self:getAttacherVehicle()
2235 if attacherVehicle ~= nil then
2236 attacherVehicle:handleLowerImplementEvent(self)
2237 end
2238 end
2239 end
2240 end
2241end

allowLoadMovingToolStates

Description
Definition
allowLoadMovingToolStates()
Code
924function Foldable:allowLoadMovingToolStates(superFunc)
925 local spec = self.spec_foldable
926
927 if spec.foldAnimTime > spec.loadMovingToolStatesMaxLimit or spec.foldAnimTime < spec.loadMovingToolStatesMinLimit then
928 return false
929 end
930
931 return superFunc(self)
932end

getAllowDynamicMountObjects

Description
Definition
getAllowDynamicMountObjects()
Code
1490function Foldable:getAllowDynamicMountObjects(superFunc)
1491 local spec = self.spec_foldable
1492 local foldAnimTime = self:getFoldAnimTime()
1493 if foldAnimTime < spec.dynamicMountMinLimit or foldAnimTime > spec.dynamicMountMaxLimit then
1494 return false
1495 end
1496
1497 return superFunc(self)
1498end

getAllowsLowering

Description
Returns true if tool can be lowered
Definition
getAllowsLowering()
Return Values
booleandetachAlloweddetach is allowed
stringwarning[optional] warning text to display
Code
1269function Foldable:getAllowsLowering(superFunc)
1270 local spec = self.spec_foldable
1271
1272 if spec.foldAnimTime > spec.loweringMaxLimit or spec.foldAnimTime < spec.loweringMinLimit then
1273 return false, spec.unfoldWarning
1274 end
1275
1276 return superFunc(self)
1277end

getBrakeForce

Description
Definition
getBrakeForce()
Code
1758function Foldable:getBrakeForce(superFunc)
1759 local spec = self.spec_foldable
1760 if spec.releaseBrakesWhileFolding then
1761 if spec.foldMoveDirection ~= 0 then
1762 return 0
1763 end
1764 end
1765
1766 return superFunc(self)
1767end

getCanAIImplementContinueWork

Description
Definition
getCanAIImplementContinueWork()
Code
1799function Foldable:getCanAIImplementContinueWork(superFunc)
1800 local canContinue, stopAI, stopReason = superFunc(self)
1801 if not canContinue then
1802 return false, stopAI, stopReason
1803 end
1804
1805 local spec = self.spec_foldable
1806
1807 if #spec.foldingParts > 0 and spec.allowUnfoldingByAI then
1808 canContinue = (spec.foldMiddleAnimTime ~= nil and math.abs(spec.foldAnimTime-spec.foldMiddleAnimTime) < 0.001) or spec.foldAnimTime == 0 or spec.foldAnimTime == 1
1809 end
1810
1811 return canContinue
1812end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
1435function Foldable:getCanBeSelected(superFunc)
1436 return true
1437end

getCanBeTurnedOn

Description
Definition
getCanBeTurnedOn()
Code
1197function Foldable:getCanBeTurnedOn(superFunc)
1198 local spec = self.spec_foldable
1199 if spec.foldAnimTime > spec.turnOnFoldMaxLimit or spec.foldAnimTime < spec.turnOnFoldMinLimit then
1200 return false
1201 end
1202
1203 return superFunc(self)
1204end

getCanChangePickupState

Description
Definition
getCanChangePickupState()
Code
1630function Foldable:getCanChangePickupState(superFunc, spec, newState)
1631 local foldAnimTime = self:getFoldAnimTime()
1632 if foldAnimTime < spec.foldMinLimit or foldAnimTime > spec.foldMaxLimit then
1633 return false
1634 end
1635
1636 return superFunc(self, spec, newState)
1637end

getCanToggleCrabSteering

Description
Definition
getCanToggleCrabSteering()
Code
1746function Foldable:getCanToggleCrabSteering(superFunc)
1747 local spec = self.spec_foldable
1748 local foldAnimTime = self:getFoldAnimTime()
1749 if foldAnimTime < spec.crabSteeringMinLimit or foldAnimTime > spec.crabSteeringMaxLimit then
1750 return false, spec.unfoldWarning
1751 end
1752
1753 return superFunc(self)
1754end

getCompensationAngleScale

Description
Definition
getCompensationAngleScale()
Code
983function Foldable:getCompensationAngleScale(superFunc, compensationNode)
984 local scale = superFunc(self, compensationNode)
985
986 if compensationNode.foldAngleScale ~= nil then
987 local spec = self.spec_foldable
988 local animTime = 1-spec.foldAnimTime
989 if compensationNode.invertFoldAngleScale then
990 animTime = 1 - animTime
991 end
992
993 if spec.foldMiddleAnimTime ~= nil then
994 scale = scale * MathUtil.lerp(compensationNode.foldAngleScale, 1, animTime / (1 - spec.foldMiddleAnimTime))
995 else
996 scale = scale * MathUtil.lerp(compensationNode.foldAngleScale, 1, animTime)
997 end
998 end
999
1000 return scale
1001end

getCutterTiltIsActive

Description
Returns if cutter tilt is active
Definition
getCutterTiltIsActive()
Return Values
booleanisActivecutter tilt is active
booleandoResetreset header tilt to initial position
Code
1659function Foldable:getCutterTiltIsActive(superFunc, automaticTilt)
1660 local isActive, doReset = superFunc(self, automaticTilt)
1661 if not isActive then
1662 return isActive, doReset
1663 end
1664
1665 local foldAnimTime = self:getFoldAnimTime()
1666 if foldAnimTime < automaticTilt.foldMinLimit or foldAnimTime > automaticTilt.foldMaxLimit then
1667 return false, true
1668 end
1669
1670 return true, false
1671end

getFillUnitSupportsToolType

Description
Definition
getFillUnitSupportsToolType()
Code
1561function Foldable:getFillUnitSupportsToolType(superFunc, fillUnitIndex, toolType)
1562 -- tool type undefined is always allowed
1563 if toolType ~= ToolType.UNDEFINED then
1564 local fillUnit = self.spec_fillUnit.fillUnits[fillUnitIndex]
1565 if fillUnit ~= nil then
1566 if fillUnit.foldMinLimit ~= nil and fillUnit.foldMaxLimit ~= nil then
1567 local foldAnimTime = self:getFoldAnimTime()
1568 if foldAnimTime < fillUnit.foldMinLimit or foldAnimTime > fillUnit.foldMaxLimit then
1569 return false
1570 end
1571 end
1572 end
1573 end
1574
1575 return superFunc(self, fillUnitIndex, toolType)
1576end

getFoldAnimTime

Description
Definition
getFoldAnimTime()
Code
845function Foldable:getFoldAnimTime()
846 local spec = self.spec_foldable
847 return spec.loadedFoldAnimTime or spec.foldAnimTime
848end

getIsAdditionalCharacterActive

Description
Definition
getIsAdditionalCharacterActive()
Code
1476function Foldable:getIsAdditionalCharacterActive(superFunc)
1477 local spec = self.spec_enterable
1478 if spec.additionalCharacterFoldMinLimit ~= nil and spec.additionalCharacterFoldMaxLimit ~= nil then
1479 local foldAnimTime = self:getFoldAnimTime()
1480 if foldAnimTime >= spec.additionalCharacterFoldMinLimit and foldAnimTime <= spec.additionalCharacterFoldMaxLimit then
1481 return true
1482 end
1483 end
1484
1485 return superFunc(self)
1486end

getIsAIPreparingToDrive

Description
Definition
getIsAIPreparingToDrive()
Code
1836function Foldable:getIsAIPreparingToDrive(superFunc)
1837 local spec = self.spec_foldable
1838
1839 if #spec.foldingParts > 0 and spec.allowUnfoldingByAI then
1840 if spec.foldAnimTime ~= spec.foldMiddleAnimTime and spec.foldAnimTime ~= 0 and spec.foldAnimTime ~= 1 then
1841 return true
1842 end
1843 end
1844
1845 return superFunc(self)
1846end

getIsAIReadyToDrive

Description
Definition
getIsAIReadyToDrive()
Code
1816function Foldable:getIsAIReadyToDrive(superFunc)
1817 local spec = self.spec_foldable
1818
1819 if #spec.foldingParts > 0 and spec.allowUnfoldingByAI then
1820 if spec.turnOnFoldDirection > 0 then
1821 if spec.foldAnimTime > 0 then
1822 return false
1823 end
1824 else
1825 if spec.foldAnimTime < 1 then
1826 return false
1827 end
1828 end
1829 end
1830
1831 return superFunc(self)
1832end

getIsAttacherJointHeightNodeActive

Description
Definition
getIsAttacherJointHeightNodeActive()
Code
1610function Foldable:getIsAttacherJointHeightNodeActive(superFunc, heightNode)
1611 local foldAnimTime = self:getFoldAnimTime()
1612 if foldAnimTime < heightNode.foldMinLimit or foldAnimTime > heightNode.foldMaxLimit then
1613 return false
1614 end
1615
1616 return superFunc(self, heightNode)
1617end

getIsFoldAllowed

Description
Definition
getIsFoldAllowed()
Code
852function Foldable:getIsFoldAllowed(direction, onAiTurnOn)
853 if self.getAttacherVehicle ~= nil and self:getAttacherVehicle() ~= nil then
854 local inputAttacherJoint = self:getActiveInputAttacherJoint()
855 if inputAttacherJoint.foldMinLimit ~= nil and inputAttacherJoint.foldMaxLimit ~= nil then
856 local foldAnimTime = self:getFoldAnimTime()
857 if foldAnimTime < inputAttacherJoint.foldMinLimit or foldAnimTime > inputAttacherJoint.foldMaxLimit then
858 return false
859 end
860 end
861 end
862
863 return true
864end

getIsFoldMiddleAllowed

Description
Definition
getIsFoldMiddleAllowed()
Code
868function Foldable:getIsFoldMiddleAllowed()
869 local spec = self.spec_foldable
870 return spec.foldMiddleAnimTime ~= nil
871end

getIsGroundAdjustedNodeActive

Description
Definition
getIsGroundAdjustedNodeActive()
Code
1374function Foldable:getIsGroundAdjustedNodeActive(superFunc, adjustedNode)
1375 local spec = self.spec_foldable
1376
1377 local foldAnimTime = spec.foldAnimTime
1378 if foldAnimTime ~= nil and (foldAnimTime > adjustedNode.foldMaxLimit or foldAnimTime < adjustedNode.foldMinLimit) then
1379 return false
1380 end
1381
1382 return superFunc(self, adjustedNode)
1383end

getIsInputAttacherActive

Description
Returns true if input attacher is active and can be used to attach
Definition
getIsInputAttacherActive(table inputAttacherJoint)
Arguments
tableinputAttacherJointinput attacher joint
Return Values
booleanisActiveinput attacher is active
Code
1452function Foldable:getIsInputAttacherActive(superFunc, inputAttacherJoint)
1453 if inputAttacherJoint.foldMinLimit ~= nil and inputAttacherJoint.foldMaxLimit ~= nil then
1454 local foldAnimTime = self:getFoldAnimTime()
1455 if foldAnimTime < inputAttacherJoint.foldMinLimit or foldAnimTime > inputAttacherJoint.foldMaxLimit then
1456 return false
1457 end
1458 end
1459
1460 return superFunc(self, inputAttacherJoint)
1461end

getIsInWorkPosition

Description
Definition
getIsInWorkPosition()
Code
1223function Foldable:getIsInWorkPosition(superFunc)
1224 local spec = self.spec_foldable
1225
1226 if spec.turnOnFoldDirection ~= 0 and not (#spec.foldingParts == 0 or (spec.turnOnFoldDirection == -1 and spec.foldAnimTime == 0) or (spec.turnOnFoldDirection == 1 and spec.foldAnimTime == 1)) then
1227 return false
1228 end
1229
1230 return superFunc(self)
1231end

getIsLevelerPickupNodeActive

Description
Definition
getIsLevelerPickupNodeActive()
Code
1107function Foldable:getIsLevelerPickupNodeActive(superFunc, levelerNode)
1108 local spec = self.spec_foldable
1109
1110 if not levelerNode.foldLimitedOuterRange then
1111 if spec.foldAnimTime > levelerNode.foldMaxLimit or spec.foldAnimTime < levelerNode.foldMinLimit then
1112 return false
1113 end
1114 else
1115 if spec.foldAnimTime <= levelerNode.foldMaxLimit and spec.foldAnimTime > levelerNode.foldMinLimit then
1116 return false
1117 end
1118 end
1119
1120 return superFunc(self, levelerNode)
1121end

getIsLowered

Description
Definition
getIsLowered()
Code
1281function Foldable:getIsLowered(superFunc, default)
1282 local spec = self.spec_foldable
1283
1284 if self:getIsFoldMiddleAllowed() then
1285 if spec.foldMiddleAnimTime ~= nil and spec.foldMiddleInputButton ~= nil then
1286 local ignoreFoldMiddle = false
1287 if spec.ignoreFoldMiddleWhileFolded then
1288 if self:getFoldAnimTime() > spec.foldMiddleAnimTime then
1289 ignoreFoldMiddle = true
1290 end
1291 end
1292
1293 if not ignoreFoldMiddle then
1294 if spec.foldMoveDirection ~= 0 then
1295 if spec.foldMiddleDirection > 0 then
1296 if spec.foldAnimTime < spec.foldMiddleAnimTime + 0.01 then
1297 return spec.foldMoveDirection < 0 and spec.moveToMiddle ~= true
1298 end
1299 else
1300 if spec.foldAnimTime > spec.foldMiddleAnimTime - 0.01 then
1301 return spec.foldMoveDirection > 0 and spec.moveToMiddle ~= true
1302 end
1303 end
1304 else
1305 if spec.foldMiddleDirection > 0 and spec.foldAnimTime < 0.01 then
1306 return true
1307 elseif spec.foldMiddleDirection < 0 and math.abs(1.0 - spec.foldAnimTime) < 0.01 then
1308 return true
1309 end
1310 end
1311
1312 return false
1313 else
1314 return superFunc(self, default)
1315 end
1316 end
1317 end
1318
1319 return superFunc(self, default)
1320end

getIsMovingPartActive

Description
Definition
getIsMovingPartActive()
Code
1186function Foldable:getIsMovingPartActive(superFunc, movingPart)
1187 local foldAnimTime = self:getFoldAnimTime()
1188 if foldAnimTime > movingPart.foldMaxLimit or foldAnimTime < movingPart.foldMinLimit then
1189 return false
1190 end
1191
1192 return superFunc(self, movingPart)
1193end

getIsMovingToolActive

Description
Definition
getIsMovingToolActive()
Code
1158function Foldable:getIsMovingToolActive(superFunc, movingTool)
1159 if not movingTool.hasRequiredFoldingConfiguration then
1160 return false
1161 end
1162
1163 local foldAnimTime = self:getFoldAnimTime()
1164 if foldAnimTime > movingTool.foldMaxLimit or foldAnimTime < movingTool.foldMinLimit then
1165 return false
1166 end
1167
1168 return superFunc(self, movingTool)
1169end

getIsNextCoverStateAllowed

Description
Definition
getIsNextCoverStateAllowed()
Code
1208function Foldable:getIsNextCoverStateAllowed(superFunc, nextState)
1209 if not superFunc(self, nextState) then
1210 return false
1211 end
1212
1213 local spec = self.spec_foldable
1214 if spec.foldAnimTime > spec.toggleCoverMaxLimit or spec.foldAnimTime < spec.toggleCoverMinLimit then
1215 return false
1216 end
1217
1218 return true
1219end

getIsPreprunerNodeActive

Description
Definition
getIsPreprunerNodeActive()
Code
1688function Foldable:getIsPreprunerNodeActive(superFunc, prunerNode)
1689 local foldAnimTime = self:getFoldAnimTime()
1690 if foldAnimTime < prunerNode.foldMinLimit or foldAnimTime > prunerNode.foldMaxLimit then
1691 return false
1692 end
1693
1694 return superFunc(self, prunerNode)
1695end

getIsSpeedRotatingPartActive

Description
Definition
getIsSpeedRotatingPartActive()
Code
956function Foldable:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
957 local spec = self.spec_foldable
958
959 if not speedRotatingPart.foldLimitedOuterRange then
960 if spec.foldAnimTime > speedRotatingPart.foldMaxLimit or spec.foldAnimTime < speedRotatingPart.foldMinLimit then
961 return false
962 end
963 else
964 if spec.foldAnimTime <= speedRotatingPart.foldMaxLimit and spec.foldAnimTime > speedRotatingPart.foldMinLimit then
965 return false
966 end
967 end
968
969 return superFunc(self, speedRotatingPart)
970end

getIsSprayTypeActive

Description
Definition
getIsSprayTypeActive()
Code
1416function Foldable:getIsSprayTypeActive(superFunc, sprayType)
1417 local spec = self.spec_foldable
1418
1419 if sprayType.foldMinLimit ~= nil and sprayType.foldMaxLimit ~= nil then
1420 local foldAnimTime = spec.foldAnimTime
1421 if foldAnimTime ~= nil and (foldAnimTime > sprayType.foldMaxLimit or foldAnimTime < sprayType.foldMinLimit) then
1422 return false
1423 end
1424 end
1425
1426 if not sprayType.hasRequiredFoldingConfiguration then
1427 return false
1428 end
1429
1430 return superFunc(self, sprayType)
1431end

getIsSteeringAxleAllowed

Description
Definition
getIsSteeringAxleAllowed()
Code
1540function Foldable:getIsSteeringAxleAllowed(superFunc)
1541 local spec = self.spec_attachable
1542 local foldAnimTime = self:getFoldAnimTime()
1543 if foldAnimTime < spec.foldMinLimit or foldAnimTime > spec.foldMaxLimit then
1544 return false
1545 end
1546
1547 return superFunc(self)
1548end

getIsSupportAnimationAllowed

Description
Returns if support animation is allowed to play
Definition
getIsSupportAnimationAllowed()
Code
1517function Foldable:getIsSupportAnimationAllowed(superFunc, supportAnimation)
1518 local foldAnimTime = self:getFoldAnimTime()
1519 if foldAnimTime < supportAnimation.foldMinLimit or foldAnimTime > supportAnimation.foldMaxLimit then
1520 return false
1521 end
1522
1523 return superFunc(self, supportAnimation)
1524end

getIsTurnedOnAnimationActive

Description
Definition
getIsTurnedOnAnimationActive()
Code
1590function Foldable:getIsTurnedOnAnimationActive(superFunc, turnedOnAnimation)
1591 local foldAnimTime = self:getFoldAnimTime()
1592 if foldAnimTime < turnedOnAnimation.foldMinLimit or foldAnimTime > turnedOnAnimation.foldMaxLimit then
1593 return false
1594 end
1595
1596 return superFunc(self, turnedOnAnimation)
1597end

getIsUnfolded

Description
Definition
getIsUnfolded()
Code
819function Foldable:getIsUnfolded()
820 local spec = self.spec_foldable
821
822 if #spec.foldingParts > 0 then
823 if spec.foldMiddleAnimTime ~= nil then
824 if (spec.turnOnFoldDirection == -1 and spec.foldAnimTime < spec.foldMiddleAnimTime + 0.01) or
825 (spec.turnOnFoldDirection == 1 and spec.foldAnimTime > spec.foldMiddleAnimTime - 0.01)
826 then
827 return true
828 else
829 return false
830 end
831 else
832 if (spec.turnOnFoldDirection == -1 and spec.foldAnimTime == 0) or (spec.turnOnFoldDirection == 1 and spec.foldAnimTime == 1) then
833 return true
834 else
835 return false
836 end
837 end
838 else
839 return true
840 end
841end

getIsVersatileYRotActive

Description
Definition
getIsVersatileYRotActive()
Code
1017function Foldable:getIsVersatileYRotActive(superFunc, wheel)
1018 local spec = self.spec_foldable
1019
1020 if spec.foldAnimTime > wheel.versatileFoldMaxLimit or spec.foldAnimTime < wheel.versatileFoldMinLimit then
1021 return false
1022 end
1023
1024 return superFunc(self, wheel)
1025end

getIsWorkAreaActive

Description
Definition
getIsWorkAreaActive()
Code
1049function Foldable:getIsWorkAreaActive(superFunc, workArea)
1050 local spec = self.spec_foldable
1051
1052 if not workArea.foldLimitedOuterRange then
1053 if spec.foldAnimTime > workArea.foldMaxLimit or spec.foldAnimTime < workArea.foldMinLimit then
1054 return false
1055 end
1056 else
1057 if spec.foldAnimTime <= workArea.foldMaxLimit and spec.foldAnimTime > workArea.foldMinLimit then
1058 return false
1059 end
1060 end
1061
1062 return superFunc(self, workArea)
1063end

getShovelNodeIsActive

Description
Definition
getShovelNodeIsActive()
Code
1710function Foldable:getShovelNodeIsActive(superFunc, shovelNode)
1711 local foldAnimTime = self:getFoldAnimTime()
1712 if foldAnimTime < shovelNode.foldMinLimit or foldAnimTime > shovelNode.foldMaxLimit then
1713 return false
1714 end
1715
1716 return superFunc(self, shovelNode)
1717end

getToggledFoldDirection

Description
Definition
getToggledFoldDirection()
Code
875function Foldable:getToggledFoldDirection()
876 local spec = self.spec_foldable
877
878 local foldMidTime = 0.5
879 if spec.foldMiddleAnimTime ~= nil then
880 if spec.foldMiddleDirection > 0 then
881 foldMidTime = (1 + spec.foldMiddleAnimTime) * 0.5
882 else
883 foldMidTime = spec.foldMiddleAnimTime * 0.5
884 end
885 end
886 if spec.moveToMiddle then
887 return spec.foldMiddleDirection
888 elseif spec.foldMoveDirection > 0.1 or (spec.foldMoveDirection == 0 and spec.foldAnimTime > foldMidTime) then
889 return -1
890 else
891 return 1
892 end
893end

getToggledFoldMiddleDirection

Description
Definition
getToggledFoldMiddleDirection()
Code
897function Foldable:getToggledFoldMiddleDirection()
898 local spec = self.spec_foldable
899
900 local ret = 0
901 if spec.foldMiddleAnimTime ~= nil then
902 if spec.foldMoveDirection > 0.1 then
903 ret = -1
904 else
905 ret = 1
906 end
907 if spec.foldMiddleDirection > 0 then
908 if spec.foldAnimTime >= spec.foldMiddleAnimTime - 0.01 then
909 ret = -1
910 end
911 else
912 if spec.foldAnimTime <= spec.foldMiddleAnimTime + 0.01 then
913 ret = 1
914 else
915 ret = -1
916 end
917 end
918 end
919 return ret
920end

getTurnedOnNotAllowedWarning

Description
Definition
getTurnedOnNotAllowedWarning()
Code
1235function Foldable:getTurnedOnNotAllowedWarning(superFunc)
1236 local spec = self.spec_foldable
1237
1238 if spec.foldAnimTime > spec.turnOnFoldMaxLimit or spec.foldAnimTime < spec.turnOnFoldMinLimit then
1239 return spec.unfoldWarning
1240 end
1241
1242 return superFunc(self)
1243end

initSpecialization

Description
Definition
initSpecialization()
Code
23function Foldable.initSpecialization()
24 g_configurationManager:addConfigurationType("folding", g_i18n:getText("configuration_folding"), "foldable", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
25
26 local schema = Vehicle.xmlSchema
27 schema:setXMLSpecializationType("Foldable")
28
29 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.foldable.foldingConfigurations.foldingConfiguration(?)")
30 schema:register(XMLValueType.FLOAT, "vehicle.foldable.foldingConfigurations.foldingConfiguration(?)#workingWidth", "Working width to display in shop")
31
32 Foldable.registerFoldingXMLPaths(schema, "vehicle.foldable.foldingConfigurations.foldingConfiguration(?).foldingParts")
33
34 schema:register(XMLValueType.BOOL, WorkArea.WORK_AREA_XML_KEY .. "#foldLimitedOuterRange", "Fold limit outer range", false)
35 schema:register(XMLValueType.FLOAT, WorkArea.WORK_AREA_XML_KEY .. ".folding#minLimit", "Min. fold limit", 0)
36 schema:register(XMLValueType.FLOAT, WorkArea.WORK_AREA_XML_KEY .. ".folding#maxLimit", "Max. fold limit", 1)
37
38 schema:register(XMLValueType.BOOL, WorkArea.WORK_AREA_XML_CONFIG_KEY .. "#foldLimitedOuterRange", "Fold limit outer range", false)
39 schema:register(XMLValueType.FLOAT, WorkArea.WORK_AREA_XML_CONFIG_KEY .. ".folding#minLimit", "Min. fold limit", 0)
40 schema:register(XMLValueType.FLOAT, WorkArea.WORK_AREA_XML_CONFIG_KEY .. ".folding#maxLimit", "Max. fold limit", 1)
41
42 schema:register(XMLValueType.FLOAT, GroundReference.GROUND_REFERENCE_XML_KEY .. ".folding#minLimit", "Min. fold limit", 0)
43 schema:register(XMLValueType.FLOAT, GroundReference.GROUND_REFERENCE_XML_KEY .. ".folding#maxLimit", "Max. fold limit", 1)
44
45 schema:register(XMLValueType.BOOL, SpeedRotatingParts.SPEED_ROTATING_PART_XML_KEY .. "#foldLimitedOuterRange", "Fold limit outer range", false)
46 schema:register(XMLValueType.FLOAT, SpeedRotatingParts.SPEED_ROTATING_PART_XML_KEY .. "#foldMinLimit", "Min. fold limit", 0)
47 schema:register(XMLValueType.FLOAT, SpeedRotatingParts.SPEED_ROTATING_PART_XML_KEY .. "#foldMaxLimit", "Max. fold limit", 1)
48
49 schema:register(XMLValueType.BOOL, Leveler.LEVELER_NODE_XML_KEY .. "#foldLimitedOuterRange", "Fold limit outer range", false)
50 schema:register(XMLValueType.FLOAT, Leveler.LEVELER_NODE_XML_KEY .. "#foldMinLimit", "Min. fold limit", 0)
51 schema:register(XMLValueType.FLOAT, Leveler.LEVELER_NODE_XML_KEY .. "#foldMaxLimit", "Max. fold limit", 1)
52
53 schema:register(XMLValueType.FLOAT, SlopeCompensation.COMPENSATION_NODE_XML_KEY .. "#foldAngleScale", "Fold angle scale")
54 schema:register(XMLValueType.BOOL, SlopeCompensation.COMPENSATION_NODE_XML_KEY .. "#invertFoldAngleScale", "Invert fold angle scale", false)
55
56 schema:register(XMLValueType.FLOAT, Cylindered.MOVING_TOOL_XML_KEY .. "#foldMinLimit", "Fold min. time", 0)
57 schema:register(XMLValueType.FLOAT, Cylindered.MOVING_TOOL_XML_KEY .. "#foldMaxLimit", "Fold max. time", 1)
58
59 schema:register(XMLValueType.INT, Cylindered.MOVING_TOOL_XML_KEY .. "#foldingConfigurationIndex", "Index of folding configuration to activate the moving tool")
60 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_TOOL_XML_KEY .. "#foldingConfigurationIndices", "List of folding configuration indices to activate the moving tool")
61
62 schema:register(XMLValueType.FLOAT, Cylindered.MOVING_PART_XML_KEY .. "#foldMinLimit", "Fold min. time", 0)
63 schema:register(XMLValueType.FLOAT, Cylindered.MOVING_PART_XML_KEY .. "#foldMaxLimit", "Fold max. time", 1)
64
65 schema:register(XMLValueType.FLOAT, GroundAdjustedNodes.GROUND_ADJUSTED_NODE_XML_KEY .. ".foldable#minLimit", "Fold min. time", 0)
66 schema:register(XMLValueType.FLOAT, GroundAdjustedNodes.GROUND_ADJUSTED_NODE_XML_KEY .. ".foldable#maxLimit", "Fold max. time", 1)
67
68 schema:register(XMLValueType.FLOAT, Sprayer.SPRAY_TYPE_XML_KEY .. "#foldMinLimit", "Fold min. time", 0)
69 schema:register(XMLValueType.FLOAT, Sprayer.SPRAY_TYPE_XML_KEY .. "#foldMaxLimit", "Fold max. time", 1)
70 schema:register(XMLValueType.INT, Sprayer.SPRAY_TYPE_XML_KEY .. "#foldingConfigurationIndex", "Index of folding configuration to activate spray type")
71 schema:register(XMLValueType.VECTOR_N, Sprayer.SPRAY_TYPE_XML_KEY .. "#foldingConfigurationIndices", "List of folding configuration indices to activate spray type")
72
73 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_XML_KEY .. "#foldMinLimit", "Fold min. time", 0)
74 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_XML_KEY .. "#foldMaxLimit", "Fold max. time", 1)
75
76 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_CONFIG_XML_KEY .. "#foldMinLimit", "Fold min. time", 0)
77 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_CONFIG_XML_KEY .. "#foldMaxLimit", "Fold max. time", 1)
78
79 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_XML_KEY .. ".heightNode(?)#foldMinLimit", "Fold min. time", 0)
80 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_XML_KEY .. ".heightNode(?)#foldMaxLimit", "Fold max. time", 1)
81
82 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_CONFIG_XML_KEY .. ".heightNode(?)#foldMinLimit", "Fold min. time", 0)
83 schema:register(XMLValueType.FLOAT, Attachable.INPUT_ATTACHERJOINT_CONFIG_XML_KEY .. ".heightNode(?)#foldMaxLimit", "Fold max. time", 1)
84
85 schema:register(XMLValueType.FLOAT, Enterable.ADDITIONAL_CHARACTER_XML_KEY .. "#foldMinLimit", "Fold min. time", 0)
86 schema:register(XMLValueType.FLOAT, Enterable.ADDITIONAL_CHARACTER_XML_KEY .. "#foldMaxLimit", "Fold max. time", 1)
87
88 schema:register(XMLValueType.FLOAT, Attachable.SUPPORT_XML_KEY .. ".folding#minLimit", "Min. fold limit", 0)
89 schema:register(XMLValueType.FLOAT, Attachable.SUPPORT_XML_KEY .. ".folding#maxLimit", "Max. fold limit", 1)
90
91 schema:register(XMLValueType.FLOAT, Attachable.STEERING_AXLE_XML_KEY .. ".folding#minLimit", "Min. fold limit", 0)
92 schema:register(XMLValueType.FLOAT, Attachable.STEERING_AXLE_XML_KEY .. ".folding#maxLimit", "Max. fold limit", 1)
93
94 schema:register(XMLValueType.FLOAT, Wheels.WHEEL_XML_PATH .. "#versatileFoldMinLimit", "Fold min. time for versatility", 0)
95 schema:register(XMLValueType.FLOAT, Wheels.WHEEL_XML_PATH .. "#versatileFoldMaxLimit", "Fold max. time for versatility", 1)
96
97 schema:register(XMLValueType.FLOAT, FillUnit.FILL_UNIT_XML_KEY .. "#foldMinLimit", "Fold min. time for filling", 0)
98 schema:register(XMLValueType.FLOAT, FillUnit.FILL_UNIT_XML_KEY .. "#foldMaxLimit", "Fold max. time for filling", 1)
99
100 schema:register(XMLValueType.FLOAT, TurnOnVehicle.TURNED_ON_ANIMATION_XML_PATH .. "#foldMinLimit", "Fold min. time for running turned on animation", 0)
101 schema:register(XMLValueType.FLOAT, TurnOnVehicle.TURNED_ON_ANIMATION_XML_PATH .. "#foldMaxLimit", "Fold max. time for running turned on animation", 1)
102
103 schema:register(XMLValueType.FLOAT, Pickup.PICKUP_XML_KEY .. "#foldMinLimit", "Fold min. time for pickup lowering", 0)
104 schema:register(XMLValueType.FLOAT, Pickup.PICKUP_XML_KEY .. "#foldMaxLimit", "Fold max. time for pickup lowering", 1)
105
106 schema:register(XMLValueType.FLOAT, Cutter.CUTTER_TILT_XML_KEY .. "#foldMinLimit", "Fold min. time for cutter automatic tilt", 0)
107 schema:register(XMLValueType.FLOAT, Cutter.CUTTER_TILT_XML_KEY .. "#foldMaxLimit", "Fold max. time for cutter automatic tilt", 1)
108
109 schema:register(XMLValueType.FLOAT, VinePrepruner.PRUNER_NODE_XML_KEY .. "#foldMinLimit", "Fold min. time for pruner node update", 0)
110 schema:register(XMLValueType.FLOAT, VinePrepruner.PRUNER_NODE_XML_KEY .. "#foldMaxLimit", "Fold max. time for pruner node update", 1)
111
112 schema:register(XMLValueType.FLOAT, Shovel.SHOVEL_NODE_XML_KEY .. "#foldMinLimit", "Fold min. time for shovel pickup", 0)
113 schema:register(XMLValueType.FLOAT, Shovel.SHOVEL_NODE_XML_KEY.. "#foldMaxLimit", "Fold max. time for shovel pickup", 1)
114
115 schema:register(XMLValueType.FLOAT, Attachable.STEERING_ANGLE_NODE_XML_KEY .. "#foldMinLimit", "Fold min. time for steering angle nodes to update", 0)
116 schema:register(XMLValueType.FLOAT, Attachable.STEERING_ANGLE_NODE_XML_KEY.. "#foldMaxLimit", "Fold max. time for steering angle nodes to update", 1)
117
118 schema:setXMLSpecializationType()
119
120 local schemaSavegame = Vehicle.xmlSchemaSavegame
121 schemaSavegame:register(XMLValueType.FLOAT, "vehicles.vehicle(?).foldable#foldAnimTime", "Fold animation time")
122end

isDetachAllowed

Description
Returns true if detach is allowed
Definition
isDetachAllowed()
Return Values
booleandetachAlloweddetach is allowed
stringwarning[optional] warning text to display
Code
1249function Foldable:isDetachAllowed(superFunc)
1250 local spec = self.spec_foldable
1251
1252 if spec.foldAnimTime > spec.detachingMaxLimit or spec.foldAnimTime < spec.detachingMinLimit then
1253 return false, spec.unfoldWarning
1254 end
1255
1256 if not spec.allowDetachingWhileFolding then
1257 if (spec.foldMiddleAnimTime == nil or math.abs(spec.foldAnimTime-spec.foldMiddleAnimTime) > 0.001) and (spec.foldAnimTime > 0 and spec.foldAnimTime < 1) then
1258 return false, spec.detachWarning
1259 end
1260 end
1261
1262 return superFunc(self)
1263end

loadAdditionalCharacterFromXML

Description
Definition
loadAdditionalCharacterFromXML()
Code
1465function Foldable:loadAdditionalCharacterFromXML(superFunc, xmlFile)
1466 local spec = self.spec_enterable
1467
1468 spec.additionalCharacterFoldMinLimit = xmlFile:getValue("vehicle.enterable.additionalCharacter#foldMinLimit")
1469 spec.additionalCharacterFoldMaxLimit = xmlFile:getValue("vehicle.enterable.additionalCharacter#foldMaxLimit")
1470
1471 return superFunc(self, xmlFile)
1472end

loadAttacherJointHeightNode

Description
Definition
loadAttacherJointHeightNode()
Code
1601function Foldable:loadAttacherJointHeightNode(superFunc, xmlFile, key, heightNode, attacherJointNode)
1602 heightNode.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1603 heightNode.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1604
1605 return superFunc(self, xmlFile, key, heightNode, attacherJointNode)
1606end

loadCompensationNodeFromXML

Description
Definition
loadCompensationNodeFromXML()
Code
974function Foldable:loadCompensationNodeFromXML(superFunc, compensationNode, xmlFile, key)
975 compensationNode.foldAngleScale = xmlFile:getValue(key.."#foldAngleScale")
976 compensationNode.invertFoldAngleScale = xmlFile:getValue(key.."#invertFoldAngleScale", false)
977
978 return superFunc(self, compensationNode, xmlFile, key)
979end

loadCutterTiltFromXML

Description
Loads header tilt from xml file
Definition
loadCutterTiltFromXML(table xmlFile, string key)
Arguments
tablexmlFilexml file object
stringkeykey to load from
Return Values
boolsuccesssuccessfully loaded
Code
1644function Foldable:loadCutterTiltFromXML(superFunc, xmlFile, key, target)
1645 if not superFunc(self, xmlFile, key, target) then
1646 return false
1647 end
1648
1649 target.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1650 target.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1651
1652 return true
1653end

loadFillUnitFromXML

Description
Definition
loadFillUnitFromXML()
Code
1552function Foldable:loadFillUnitFromXML(superFunc, xmlFile, key, entry, index)
1553 entry.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1554 entry.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1555
1556 return superFunc(self, xmlFile, key, entry, index)
1557end

loadFoldingPartFromXML

Description
Load folding part from xml
Definition
loadFoldingPartFromXML(table xmlFile, string baseKey, table foldingPart)
Arguments
tablexmlFilexml file object
stringbaseKeyxml key
tablefoldingPartfolding part data
Return Values
boolsuccesssuccessfully loaded folding part
Code
619function Foldable:loadFoldingPartFromXML(xmlFile, baseKey, foldingPart)
620 local isValid = false
621
622 foldingPart.speedScale = xmlFile:getValue(baseKey.."#speedScale", 1)
623 if foldingPart.speedScale <= 0 then
624 Logging.xmlWarning(xmlFile, "Negative speed scale for folding part '%s' not allowed!", baseKey)
625 return false
626 end
627
628 local componentJointIndex = xmlFile:getValue(baseKey.. "#componentJointIndex")
629 local componentJoint = nil
630 if componentJointIndex ~= nil then
631 if componentJointIndex == 0 then
632 Logging.xmlWarning(xmlFile, "Invalid componentJointIndex for folding part '%s'. Indexing starts with 1!", baseKey)
633 return false
634 else
635 componentJoint = self.componentJoints[componentJointIndex]
636 foldingPart.componentJoint = componentJoint
637 end
638 end
639 foldingPart.anchorActor = xmlFile:getValue( baseKey.."#anchorActor", 0)
640
641 foldingPart.animCharSet = 0
642
643 local rootNode = xmlFile:getValue(baseKey.."#rootNode", nil, self.components, self.i3dMappings)
644 if rootNode ~= nil then
645 local animCharSet = getAnimCharacterSet(rootNode)
646 if animCharSet ~= 0 then
647 local clip = getAnimClipIndex(animCharSet, xmlFile:getValue(baseKey.."#animationClip"))
648 if clip >= 0 then
649 isValid = true
650
651 foldingPart.animCharSet = animCharSet
652 assignAnimTrackClip(foldingPart.animCharSet, 0, clip)
653 setAnimTrackLoopState(foldingPart.animCharSet, 0, false)
654 foldingPart.animDuration = getAnimClipDuration(foldingPart.animCharSet, clip)
655 end
656 end
657 end
658
659 if not isValid then
660 if SpecializationUtil.hasSpecialization(AnimatedVehicle, self.specializations) then
661 local animationName = xmlFile:getValue(baseKey.."#animationName")
662 if animationName ~= nil then
663 if self:getAnimationExists(animationName) then
664 isValid = true
665 foldingPart.animDuration = self:getAnimationDuration(animationName)
666 foldingPart.animationName = animationName
667
668 local animation = self:getAnimationByName(animationName)
669 animation.resetOnStart = true
670 end
671 end
672 else
673 if xmlFile:getValue(baseKey.."#animationName") ~= nil then
674 Logging.xmlWarning(xmlFile, "Found animationName in folding part '%s', but vehicle has no animations!", baseKey)
675 return false
676 end
677 end
678 end
679
680 if not isValid then
681 Logging.xmlWarning(xmlFile, "Invalid folding part '%s'. Either a animationClip or animationName needs to be defined!", baseKey)
682 return false
683 end
684
685 local distance = xmlFile:getValue(baseKey.."#delayDistance")
686 if distance ~= nil then
687 foldingPart.delayedLowering = {}
688
689 foldingPart.delayedLowering.distance = distance
690 foldingPart.delayedLowering.previousDuration = xmlFile:getValue(baseKey.."#previousDuration", 1) * 1000
691 foldingPart.delayedLowering.loweringDuration = xmlFile:getValue(baseKey.."#loweringDuration", 1) * 1000
692 foldingPart.delayedLowering.maxDelayDuration = xmlFile:getValue(baseKey.."#maxDelayDuration", 7.5) * 1000
693 foldingPart.delayedLowering.aiSkipDelay = xmlFile:getValue(baseKey.."#aiSkipDelay", false)
694 foldingPart.delayedLowering.currentDistance = -1
695 foldingPart.delayedLowering.startTime = math.huge
696 foldingPart.delayedLowering.speedScale = 0
697 foldingPart.delayedLowering.animTime = 0
698 foldingPart.delayedLowering.stopAnimTime = 0
699 foldingPart.delayedLowering.prevDistance = nil
700 end
701
702 if componentJoint ~= nil then
703 local node = self.components[componentJoint.componentIndices[((foldingPart.anchorActor+1)%2)+1] ].node
704 foldingPart.x, foldingPart.y, foldingPart.z = worldToLocal(componentJoint.jointNode, getWorldTranslation(node))
705 foldingPart.upX, foldingPart.upY, foldingPart.upZ = worldDirectionToLocal(componentJoint.jointNode, localDirectionToWorld(node, 0, 1, 0))
706 foldingPart.dirX, foldingPart.dirY, foldingPart.dirZ = worldDirectionToLocal(componentJoint.jointNode, localDirectionToWorld(node, 0, 0, 1))
707 end
708
709 return true
710end

loadGroundAdjustedNodeFromXML

Description
Definition
loadGroundAdjustedNodeFromXML()
Code
1358function Foldable:loadGroundAdjustedNodeFromXML(superFunc, xmlFile, key, adjustedNode)
1359 if not superFunc(self, xmlFile, key, adjustedNode) then
1360 return false
1361 end
1362
1363 XMLUtil.checkDeprecatedXMLElements(xmlFile, key.."#foldMinLimit", key..".foldable#minLimit") --FS17 to FS19
1364 XMLUtil.checkDeprecatedXMLElements(xmlFile, key.."#foldMaxLimit", key..".foldable#maxLimit") --FS17 to FS19
1365
1366 adjustedNode.foldMinLimit = xmlFile:getValue(key..".foldable#minLimit", 0)
1367 adjustedNode.foldMaxLimit = xmlFile:getValue(key..".foldable#maxLimit", 1)
1368
1369 return true
1370end

loadGroundReferenceNode

Description
Definition
loadGroundReferenceNode()
Code
1067function Foldable:loadGroundReferenceNode(superFunc, xmlFile, key, groundReferenceNode)
1068 local returnValue = superFunc(self, xmlFile, key, groundReferenceNode)
1069
1070 if returnValue then
1071 groundReferenceNode.foldMinLimit = xmlFile:getValue(key..".folding#minLimit", 0)
1072 groundReferenceNode.foldMaxLimit = xmlFile:getValue(key..".folding#maxLimit", 1)
1073 end
1074
1075 return returnValue
1076end

loadInputAttacherJoint

Description
Definition
loadInputAttacherJoint()
Code
1441function Foldable:loadInputAttacherJoint(superFunc, xmlFile, key, inputAttacherJoint, index)
1442 inputAttacherJoint.foldMinLimit = xmlFile:getValue(key .. "#foldMinLimit")
1443 inputAttacherJoint.foldMaxLimit = xmlFile:getValue(key .. "#foldMaxLimit")
1444
1445 return superFunc(self, xmlFile, key, inputAttacherJoint, index)
1446end

loadLevelerNodeFromXML

Description
Definition
loadLevelerNodeFromXML()
Code
1091function Foldable:loadLevelerNodeFromXML(superFunc, levelerNode, xmlFile, key)
1092 levelerNode.foldLimitedOuterRange = xmlFile:getValue(key.."#foldLimitedOuterRange", false)
1093 local minFoldLimit = 0
1094 local maxFoldLimit = 1
1095 if levelerNode.foldLimitedOuterRange then
1096 minFoldLimit = 0.5
1097 maxFoldLimit = 0.5
1098 end
1099 levelerNode.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", minFoldLimit)
1100 levelerNode.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", maxFoldLimit)
1101
1102 return superFunc(self, levelerNode, xmlFile, key)
1103end

loadMovingPartFromXML

Description
Definition
loadMovingPartFromXML()
Code
1173function Foldable:loadMovingPartFromXML(superFunc, xmlFile, key, entry)
1174 if not superFunc(self, xmlFile, key, entry) then
1175 return false
1176 end
1177
1178 entry.foldMinLimit = xmlFile:getValue(key .. "#foldMinLimit", 0)
1179 entry.foldMaxLimit = xmlFile:getValue(key .. "#foldMaxLimit", 1)
1180
1181 return true
1182end

loadMovingToolFromXML

Description
Definition
loadMovingToolFromXML()
Code
1125function Foldable:loadMovingToolFromXML(superFunc, xmlFile, key, entry)
1126 if not superFunc(self, xmlFile, key, entry) then
1127 return false
1128 end
1129
1130 entry.foldMinLimit = xmlFile:getValue(key .. "#foldMinLimit", 0)
1131 entry.foldMaxLimit = xmlFile:getValue(key .. "#foldMaxLimit", 1)
1132
1133 entry.hasRequiredFoldingConfiguration = true
1134 if self.configurations["folding"] ~= nil then
1135 local foldingConfigurationIndex = xmlFile:getValue(key .. "#foldingConfigurationIndex")
1136 if foldingConfigurationIndex ~= nil then
1137 if self.configurations["folding"] ~= foldingConfigurationIndex then
1138 entry.hasRequiredFoldingConfiguration = false
1139 end
1140 end
1141 local foldingConfigurationIndices = xmlFile:getValue(key .. "#foldingConfigurationIndices", nil, true)
1142 if #foldingConfigurationIndices > 0 then
1143 entry.hasRequiredFoldingConfiguration = false
1144 for i=1, #foldingConfigurationIndices do
1145 if self.configurations["folding"] == foldingConfigurationIndices[i] then
1146 entry.hasRequiredFoldingConfiguration = true
1147 break
1148 end
1149 end
1150 end
1151 end
1152
1153 return true
1154end

loadPickupFromXML

Description
Definition
loadPickupFromXML()
Code
1621function Foldable:loadPickupFromXML(superFunc, xmlFile, key, spec)
1622 spec.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1623 spec.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1624
1625 return superFunc(self, xmlFile, key, spec)
1626end

loadPreprunerNodeFromXML

Description
Definition
loadPreprunerNodeFromXML()
Code
1675function Foldable:loadPreprunerNodeFromXML(superFunc, xmlFile, key, prunerNode)
1676 if not superFunc(self, xmlFile, key, prunerNode) then
1677 return false
1678 end
1679
1680 prunerNode.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1681 prunerNode.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1682
1683 return true
1684end

loadShovelNode

Description
Definition
loadShovelNode()
Code
1699function Foldable:loadShovelNode(superFunc, xmlFile, key, shovelNode)
1700 superFunc(self, xmlFile, key, shovelNode)
1701
1702 shovelNode.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1703 shovelNode.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1704
1705 return true
1706end

loadSpeedRotatingPartFromXML

Description
Definition
loadSpeedRotatingPartFromXML()
Code
936function Foldable:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
937 if not superFunc(self, speedRotatingPart, xmlFile, key) then
938 return false
939 end
940
941 speedRotatingPart.foldLimitedOuterRange = xmlFile:getValue(key.."#foldLimitedOuterRange", false)
942 local minFoldLimit = 0
943 local maxFoldLimit = 1
944 if speedRotatingPart.foldLimitedOuterRange then
945 minFoldLimit = 0.5
946 maxFoldLimit = 0.5
947 end
948 speedRotatingPart.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", minFoldLimit)
949 speedRotatingPart.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", maxFoldLimit)
950
951 return true
952end

loadSprayTypeFromXML

Description
Definition
loadSprayTypeFromXML()
Code
1387function Foldable:loadSprayTypeFromXML(superFunc, xmlFile, key, sprayType)
1388 sprayType.foldMinLimit = xmlFile:getValue(key.. "#foldMinLimit")
1389 sprayType.foldMaxLimit = xmlFile:getValue(key.. "#foldMaxLimit")
1390
1391 sprayType.hasRequiredFoldingConfiguration = true
1392 if self.configurations["folding"] ~= nil then
1393 local foldingConfigurationIndex = xmlFile:getValue(key .. "#foldingConfigurationIndex")
1394 if foldingConfigurationIndex ~= nil then
1395 if self.configurations["folding"] ~= foldingConfigurationIndex then
1396 sprayType.hasRequiredFoldingConfiguration = false
1397 end
1398 end
1399 local foldingConfigurationIndices = xmlFile:getValue(key .. "#foldingConfigurationIndices", nil, true)
1400 if #foldingConfigurationIndices > 0 then
1401 sprayType.hasRequiredFoldingConfiguration = false
1402 for i=1, #foldingConfigurationIndices do
1403 if self.configurations["folding"] == foldingConfigurationIndices[i] then
1404 sprayType.hasRequiredFoldingConfiguration = true
1405 break
1406 end
1407 end
1408 end
1409 end
1410
1411 return superFunc(self, xmlFile, key, sprayType)
1412end

loadSteeringAngleNodeFromXML

Description
Definition
loadSteeringAngleNodeFromXML()
Code
1722function Foldable:loadSteeringAngleNodeFromXML(superFunc, entry, xmlFile, key)
1723 if not superFunc(self, entry, xmlFile, key) then
1724 return false
1725 end
1726
1727 entry.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1728 entry.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1729
1730 return true
1731end

loadSteeringAxleFromXML

Description
Definition
loadSteeringAxleFromXML()
Code
1528function Foldable:loadSteeringAxleFromXML(superFunc, spec, xmlFile, key)
1529 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key .. "#foldMinLimit", key .. ".folding#minLimit") --FS19 to FS22
1530 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key .. "#foldMaxLimit", key .. ".folding#maxLimit") --FS19 to FS22
1531
1532 spec.foldMinLimit = xmlFile:getValue(key..".folding#minLimit", 0)
1533 spec.foldMaxLimit = xmlFile:getValue(key..".folding#maxLimit", 1)
1534
1535 return superFunc(self, spec, xmlFile, key)
1536end

loadSupportAnimationFromXML

Description
Loads support animation from xml
Definition
loadSupportAnimationFromXML(table spec, int xmlFile, string key)
Arguments
tablespecspec
intxmlFilexmlFile id
stringkeykey to load from
Code
1505function Foldable:loadSupportAnimationFromXML(superFunc, supportAnimation, xmlFile, key)
1506 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key .. "#foldMinLimit", key .. ".folding#minLimit") --FS19 to FS22
1507 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, key .. "#foldMaxLimit", key .. ".folding#maxLimit") --FS19 to FS22
1508
1509 supportAnimation.foldMinLimit = xmlFile:getValue(key..".folding#minLimit", 0)
1510 supportAnimation.foldMaxLimit = xmlFile:getValue(key..".folding#maxLimit", 1)
1511
1512 return superFunc(self, supportAnimation, xmlFile, key)
1513end

loadTurnedOnAnimationFromXML

Description
Definition
loadTurnedOnAnimationFromXML()
Code
1580function Foldable:loadTurnedOnAnimationFromXML(superFunc, xmlFile, key, turnedOnAnimation)
1581 turnedOnAnimation.foldMinLimit = xmlFile:getValue(key.."#foldMinLimit", 0)
1582 turnedOnAnimation.foldMaxLimit = xmlFile:getValue(key.."#foldMaxLimit", 1)
1583
1584 return superFunc(self, xmlFile, key, turnedOnAnimation)
1585end

loadWheelFromXML

Description
Definition
loadWheelFromXML()
Code
1005function Foldable:loadWheelFromXML(superFunc, xmlFile, key, wheelnamei, wheel)
1006 XMLUtil.checkDeprecatedXMLElements(xmlFile, "vehicle.wheels#versatileFoldMinLimit", key .. wheelnamei .. "#versatileFoldMinLimit")
1007 XMLUtil.checkDeprecatedXMLElements(xmlFile, "vehicle.wheels#versatileFoldMaxLimit", key .. wheelnamei .. "#versatileFoldMaxLimit")
1008
1009 wheel.versatileFoldMinLimit = xmlFile:getValue(key .. wheelnamei .. "#versatileFoldMinLimit", 0)
1010 wheel.versatileFoldMaxLimit = xmlFile:getValue(key .. wheelnamei .. "#versatileFoldMaxLimit", 1)
1011
1012 return superFunc(self, xmlFile, key, wheelnamei, wheel)
1013end

loadWorkAreaFromXML

Description
Definition
loadWorkAreaFromXML()
Code
1029function Foldable:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
1030 workArea.foldLimitedOuterRange = xmlFile:getValue(key.."#foldLimitedOuterRange", false)
1031 local minFoldLimit = 0
1032 local maxFoldLimit = 1
1033 if workArea.foldLimitedOuterRange then
1034 minFoldLimit = 0.5
1035 maxFoldLimit = 0.5
1036 end
1037
1038 XMLUtil.checkDeprecatedXMLElements(xmlFile, key.."#foldMinLimit", key..".folding#minLimit") --FS17 to FS19
1039 XMLUtil.checkDeprecatedXMLElements(xmlFile, key.."#foldMaxLimit", key..".folding#maxLimit") --FS17 to FS19
1040
1041 workArea.foldMinLimit = xmlFile:getValue(key..".folding#minLimit", minFoldLimit)
1042 workArea.foldMaxLimit = xmlFile:getValue(key..".folding#maxLimit", maxFoldLimit)
1043
1044 return superFunc(self, workArea, xmlFile, key)
1045end

onDeactivate

Description
Definition
onDeactivate()
Code
1850function Foldable:onDeactivate()
1851 -- keep on folding while on mobile version since tools are folded when detached
1852 local spec = self.spec_foldable
1853 if not spec.keepFoldingWhileDetached and not spec.lowerWhileDetach then
1854 self:setFoldDirection(0, true)
1855 end
1856end

onLoad

Description
Definition
onLoad()
Code
294function Foldable:onLoad(savegame)
295 local spec = self.spec_foldable
296
297 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.foldingParts", "vehicle.foldable.foldingConfigurations.foldingConfiguration.foldingParts") --FS17 to FS19
298 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.foldable.foldingParts", "vehicle.foldable.foldingConfigurations.foldingConfiguration.foldingParts") --FS19 to FS21
299
300 local foldingConfigurationId = Utils.getNoNil(self.configurations["folding"], 1)
301 local configKey = string.format("vehicle.foldable.foldingConfigurations.foldingConfiguration(%d).foldingParts", foldingConfigurationId - 1)
302 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.foldable.foldingConfigurations.foldingConfiguration", foldingConfigurationId, self.components, self)
303
304 spec.objectText = self.xmlFile:getValue(configKey.."#objectText", self.typeDesc, self.customEnvironment, false)
305 spec.posDirectionText = string.format(self.xmlFile:getValue(configKey.."#posDirectionText", "action_foldOBJECT", self.customEnvironment, false), spec.objectText)
306 spec.negDirectionText = string.format(self.xmlFile:getValue(configKey.."#negDirectionText", "action_unfoldOBJECT", self.customEnvironment, false), spec.objectText)
307 spec.middlePosDirectionText = string.format(self.xmlFile:getValue(configKey.."#middlePosDirectionText", "action_liftOBJECT", self.customEnvironment, false), spec.objectText)
308 spec.middleNegDirectionText = string.format(self.xmlFile:getValue(configKey.."#middleNegDirectionText", "action_lowerOBJECT", self.customEnvironment, false), spec.objectText)
309
310 spec.startAnimTime = self.xmlFile:getValue(configKey.."#startAnimTime")
311 spec.foldMoveDirection = 0
312 spec.moveToMiddle = false
313 if spec.startAnimTime == nil then
314 spec.startAnimTime = 0
315 local startMoveDirection = self.xmlFile:getValue(configKey.."#startMoveDirection", 0)
316 if startMoveDirection > 0.1 then
317 spec.startAnimTime = 1
318 end
319 end
320 spec.turnOnFoldDirection = 1
321 if spec.startAnimTime > 0.5 then
322 spec.turnOnFoldDirection = -1
323 end
324
325 spec.turnOnFoldDirection = MathUtil.sign(self.xmlFile:getValue(configKey.."#turnOnFoldDirection", spec.turnOnFoldDirection))
326 if spec.turnOnFoldDirection == 0 then
327 Logging.xmlWarning(self.xmlFile, "Foldable 'turnOnFoldDirection' not allowed to be 0! Only -1 and 1 are allowed")
328 spec.turnOnFoldDirection = -1
329 end
330
331 spec.allowUnfoldingByAI = self.xmlFile:getValue(configKey.."#allowUnfoldingByAI", true)
332
333 local foldInputButtonStr = self.xmlFile:getValue(configKey.."#foldInputButton")
334 if foldInputButtonStr ~= nil then
335 spec.foldInputButton = InputAction[foldInputButtonStr]
336 end
337 spec.foldInputButton = Utils.getNoNil(spec.foldInputButton, InputAction.IMPLEMENT_EXTRA2)
338
339 local foldMiddleInputButtonStr = self.xmlFile:getValue(configKey.."#foldMiddleInputButton")
340 if foldMiddleInputButtonStr ~= nil then
341 spec.foldMiddleInputButton = InputAction[foldMiddleInputButtonStr]
342 end
343 spec.foldMiddleInputButton = Utils.getNoNil(spec.foldMiddleInputButton, InputAction.LOWER_IMPLEMENT)
344
345 spec.foldMiddleAnimTime = self.xmlFile:getValue(configKey.."#foldMiddleAnimTime")
346 spec.foldMiddleDirection = self.xmlFile:getValue(configKey.."#foldMiddleDirection", 1)
347 spec.foldMiddleAIRaiseDirection = self.xmlFile:getValue(configKey.."#foldMiddleAIRaiseDirection", spec.foldMiddleDirection)
348
349 spec.turnOnFoldMaxLimit = self.xmlFile:getValue(configKey.."#turnOnFoldMaxLimit", 1)
350 spec.turnOnFoldMinLimit = self.xmlFile:getValue(configKey.."#turnOnFoldMinLimit", 0)
351 spec.toggleCoverMaxLimit = self.xmlFile:getValue(configKey.."#toggleCoverMaxLimit", 1)
352 spec.toggleCoverMinLimit = self.xmlFile:getValue(configKey.."#toggleCoverMinLimit", 0)
353 spec.detachingMaxLimit = self.xmlFile:getValue(configKey.."#detachingMaxLimit", 1)
354 spec.detachingMinLimit = self.xmlFile:getValue(configKey.."#detachingMinLimit", 0)
355 spec.allowDetachingWhileFolding = self.xmlFile:getValue(configKey.."#allowDetachingWhileFolding", false)
356 spec.loweringMaxLimit = self.xmlFile:getValue(configKey.."#loweringMaxLimit", 1)
357 spec.loweringMinLimit = self.xmlFile:getValue(configKey.."#loweringMinLimit", 0)
358 spec.loadMovingToolStatesMaxLimit = self.xmlFile:getValue(configKey.."#loadMovingToolStatesMaxLimit", 1)
359 spec.loadMovingToolStatesMinLimit = self.xmlFile:getValue(configKey.."#loadMovingToolStatesMinLimit", 0)
360 spec.dynamicMountMinLimit = self.xmlFile:getValue(configKey.."#dynamicMountMinLimit", 0)
361 spec.dynamicMountMaxLimit = self.xmlFile:getValue(configKey.."#dynamicMountMaxLimit", 1)
362 spec.crabSteeringMinLimit = self.xmlFile:getValue(configKey.."#crabSteeringMinLimit", 0)
363 spec.crabSteeringMaxLimit = self.xmlFile:getValue(configKey.."#crabSteeringMaxLimit", 1)
364 spec.unfoldWarning = string.format(self.xmlFile:getValue(configKey.."#unfoldWarning", "warning_firstUnfoldTheTool", self.customEnvironment, false), spec.objectText)
365 spec.detachWarning = string.format(self.xmlFile:getValue(configKey.."#detachWarning", "warning_doNotDetachWhileFolding", self.customEnvironment, false), spec.objectText)
366
367 spec.useParentFoldingState = self.xmlFile:getValue(configKey.."#useParentFoldingState", false)
368 spec.subFoldingStateVehicles = {}
369
370 spec.ignoreFoldMiddleWhileFolded = self.xmlFile:getValue(configKey.."#ignoreFoldMiddleWhileFolded", false)
371 spec.lowerWhileDetach = self.xmlFile:getValue(configKey.."#lowerWhileDetach", false)
372 spec.keepFoldingWhileDetached = self.xmlFile:getValue(configKey.."#keepFoldingWhileDetached", Platform.gameplay.keepFoldingWhileDetached)
373 spec.releaseBrakesWhileFolding = self.xmlFile:getValue(configKey.."#releaseBrakesWhileFolding", false)
374 spec.requiresPower = self.xmlFile:getValue(configKey.."#requiresPower", true)
375
376 spec.foldAnimTime = 0
377 spec.maxFoldAnimDuration = 0.0001
378
379 spec.foldingParts = {}
380 local i = 0
381 while true do
382 local baseKey = string.format(configKey..".foldingPart(%d)", i)
383 if not self.xmlFile:hasProperty(baseKey) then
384 break
385 end
386
387 local foldingPart = {}
388 if self:loadFoldingPartFromXML(self.xmlFile, baseKey, foldingPart) then
389 table.insert(spec.foldingParts, foldingPart)
390 spec.maxFoldAnimDuration = math.max(spec.maxFoldAnimDuration, foldingPart.animDuration)
391 end
392
393 i = i + 1
394 end
395
396 spec.actionEventsLowering = {}
397
398 if #spec.foldingParts > 0 then
399 self.isSelectable = true
400
401 if savegame ~= nil and not savegame.resetVehicles then
402 spec.loadedFoldAnimTime = savegame.xmlFile:getValue(savegame.key..".foldable#foldAnimTime")
403 end
404 end
405
406 if spec.loadedFoldAnimTime == nil then
407 spec.loadedFoldAnimTime = spec.startAnimTime
408 end
409
410 if self.additionalLoadParameters ~= nil then
411 if self.additionalLoadParameters.foldableInvertFoldState then
412 spec.loadedFoldAnimTime = 1 - spec.loadedFoldAnimTime
413 elseif self.additionalLoadParameters.foldableFoldingTime ~= nil then
414 spec.loadedFoldAnimTime = self.additionalLoadParameters.foldableFoldingTime
415 end
416 end
417end

onPostAttach

Description
Definition
onPostAttach()
Code
1875function Foldable:onPostAttach(attacherVehicle, inputJointDescIndex, jointDescIndex)
1876 local spec = self.spec_foldable
1877 if spec.lowerWhileDetach then
1878 if attacherVehicle ~= nil then
1879 local jointDesc = attacherVehicle:getAttacherJointByJointDescIndex(jointDescIndex)
1880 if not jointDesc.moveDown then
1881 if self:getFoldAnimTime() < 0.001 then
1882 self:setFoldState(1, true, true)
1883 end
1884 end
1885 end
1886 end
1887end

onPostLoad

Description
Definition
onPostLoad()
Code
421function Foldable:onPostLoad(savegame)
422 local spec = self.spec_foldable
423 Foldable.setAnimTime(self, spec.loadedFoldAnimTime, false)
424
425 if #spec.foldingParts == 0 or spec.useParentFoldingState then
426 SpecializationUtil.removeEventListener(self, "onReadStream", Foldable)
427 SpecializationUtil.removeEventListener(self, "onWriteStream", Foldable)
428 SpecializationUtil.removeEventListener(self, "onUpdate", Foldable)
429 SpecializationUtil.removeEventListener(self, "onUpdateTick", Foldable)
430 SpecializationUtil.removeEventListener(self, "onRegisterActionEvents", Foldable)
431 SpecializationUtil.removeEventListener(self, "onDeactivate", Foldable)
432 SpecializationUtil.removeEventListener(self, "onSetLoweredAll", Foldable)
433 SpecializationUtil.removeEventListener(self, "onPostAttach", Foldable)
434 SpecializationUtil.removeEventListener(self, "onPreDetach", Foldable)
435 end
436end

onPreAttachImplement

Description
Called if vehicle gets detached
Definition
onPreAttachImplement(table attacherVehicle, table implement)
Arguments
tableattacherVehicleattacher vehicle
tableimplementimplement
Code
2035function Foldable:onPreAttachImplement(object, inputJointDescIndex, jointDescIndex)
2036 local subSpec = object.spec_foldable
2037 if subSpec ~= nil then
2038 if subSpec.useParentFoldingState then
2039 self.spec_foldable.subFoldingStateVehicles[object] = object
2040 Foldable.setAnimTime(object, self.spec_foldable.foldAnimTime, false)
2041 end
2042 end
2043end

onPreDetach

Description
Called if vehicle gets detached
Definition
onPreDetach(table attacherVehicle, table implement)
Arguments
tableattacherVehicleattacher vehicle
tableimplementimplement
Code
2021function Foldable:onPreDetach(attacherVehicle, implement)
2022 local spec = self.spec_foldable
2023 if spec.lowerWhileDetach then
2024 local foldAnimTime = self:getFoldAnimTime()
2025 if math.abs(foldAnimTime - spec.foldMiddleAnimTime) < 0.001 then
2026 self:setFoldState(-1, false, true)
2027 end
2028 end
2029end

onPreDetachImplement

Description
Called if vehicle gets detached
Definition
onPreDetachImplement(table attacherVehicle, table implement)
Arguments
tableattacherVehicleattacher vehicle
tableimplementimplement
Code
2049function Foldable:onPreDetachImplement(implement)
2050 local subSpec = implement.object.spec_foldable
2051 if subSpec ~= nil then
2052 if subSpec.useParentFoldingState then
2053 self.spec_foldable.subFoldingStateVehicles[implement.object] = nil
2054 end
2055 end
2056end

onReadStream

Description
Definition
onReadStream()
Code
449function Foldable:onReadStream(streamId, connection)
450 local direction = streamReadUIntN(streamId, 2)-1
451 local moveToMiddle = streamReadBool(streamId)
452 local animTime = streamReadFloat32(streamId)
453 Foldable.setAnimTime(self, animTime, false)
454 self:setFoldState(direction, moveToMiddle, true)
455end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
1772function Foldable:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
1773 if self.isClient then
1774 local spec = self.spec_foldable
1775 self:clearActionEventsTable(spec.actionEvents)
1776
1777 if isActiveForInputIgnoreSelection then
1778 local isOnlyLowering = spec.foldMiddleAnimTime ~= nil and spec.foldMiddleAnimTime == 1
1779 if not isOnlyLowering then
1780 local _, actionEventId
1781 if spec.requiresPower then
1782 _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, spec.foldInputButton, self, Foldable.actionEventFold, false, true, false, true, nil)
1783 else
1784 _, actionEventId = self:addActionEvent(spec.actionEvents, spec.foldInputButton, self, Foldable.actionEventFold, false, true, false, true, nil)
1785 end
1786
1787 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH)
1788 Foldable.updateActionEventFold(self)
1789
1790 _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.FOLD_ALL_IMPLEMENTS, self, Foldable.actionEventFoldAll, false, true, false, true, nil)
1791 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
1792 end
1793 end
1794 end
1795end

onRootVehicleChanged

Description
Called if root vehicle changes
Definition
onRootVehicleChanged(table rootVehicle)
Arguments
tablerootVehicleroot vehicle
Code
1892function Foldable:onRootVehicleChanged(rootVehicle)
1893 local spec = self.spec_foldable
1894 if #spec.foldingParts > 0 then
1895 local actionController = rootVehicle.actionController
1896 if actionController ~= nil then
1897 if spec.controlledActionFold ~= nil then
1898 spec.controlledActionFold:updateParent(actionController)
1899
1900 if spec.controlledActionLower ~= nil then
1901 spec.controlledActionLower:updateParent(actionController)
1902 end
1903
1904 return
1905 end
1906
1907 local unfoldedTime = spec.foldMiddleAnimTime
1908 if unfoldedTime == nil then
1909 unfoldedTime = 1
1910 if spec.turnOnFoldDirection < 0 then
1911 unfoldedTime = 0
1912 end
1913 end
1914
1915 local foldedTime = 0
1916 if spec.turnOnFoldDirection < 0 then
1917 foldedTime = 1
1918 end
1919
1920 spec.controlledActionFold = actionController:registerAction("fold", spec.toggleTurnOnInputBinding, 4)
1921 spec.controlledActionFold:setCallback(self, Foldable.actionControllerFoldEvent)
1922 spec.controlledActionFold:setFinishedFunctions(self, self.getFoldAnimTime, unfoldedTime, foldedTime)
1923 if spec.allowUnfoldingByAI then
1924 spec.controlledActionFold:addAIEventListener(self, "onAIFieldWorkerStart", 1)
1925 spec.controlledActionFold:addAIEventListener(self, "onAIImplementStart", 1)
1926
1927 spec.controlledActionFold:addAIEventListener(self, "onAIImplementPrepare", -1, true)
1928
1929 if Platform.gameplay.foldAfterAIFinished then
1930 spec.controlledActionFold:addAIEventListener(self, "onAIImplementEnd", -1, true)
1931 spec.controlledActionFold:addAIEventListener(self, "onAIFieldWorkerEnd", -1)
1932 end
1933 end
1934
1935 if self:getIsFoldMiddleAllowed() then
1936 spec.controlledActionLower = actionController:registerAction("lowerFoldable", spec.toggleTurnOnInputBinding, 3)
1937 spec.controlledActionLower:setCallback(self, Foldable.actionControllerLowerEvent)
1938 spec.controlledActionLower:setFinishedFunctions(self, self.getFoldAnimTime, 1-foldedTime, spec.foldMiddleAnimTime)
1939 spec.controlledActionLower:setResetOnDeactivation(false)
1940 if spec.allowUnfoldingByAI then
1941 spec.controlledActionLower:addAIEventListener(self, "onAIImplementStartLine", 1)
1942 spec.controlledActionLower:addAIEventListener(self, "onAIImplementEndLine", -1)
1943 end
1944 end
1945 else
1946 if spec.controlledActionFold ~= nil then
1947 spec.controlledActionFold:remove()
1948 end
1949 if spec.controlledActionLower ~= nil then
1950 spec.controlledActionLower:remove()
1951 end
1952 end
1953 end
1954end

onSetLoweredAll

Description
Definition
onSetLoweredAll()
Code
1860function Foldable:onSetLoweredAll(doLowering, jointDescIndex)
1861 local spec = self.spec_foldable
1862 if spec.foldMiddleAnimTime ~= nil then
1863 if self:getIsFoldMiddleAllowed() then
1864 if doLowering then
1865 self:setFoldState(-spec.foldMiddleAIRaiseDirection, false)
1866 else
1867 self:setFoldState(spec.foldMiddleAIRaiseDirection, true)
1868 end
1869 end
1870 end
1871end

onUpdate

Description
Definition
onUpdate()
Code
470function Foldable:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
471 local spec = self.spec_foldable
472 if math.abs(spec.foldMoveDirection) > 0.1 then
473 local isInvalid = false
474 local foldAnimTime = 0
475 if spec.foldMoveDirection < -0.1 then
476 foldAnimTime = 1
477 end
478 for _,foldingPart in pairs(spec.foldingParts) do
479 local charSet = foldingPart.animCharSet
480 if spec.foldMoveDirection > 0 then
481 local animTime
482 if charSet ~= 0 then
483 animTime = getAnimTrackTime(charSet, 0)
484 else
485 animTime = self:getRealAnimationTime(foldingPart.animationName)
486 end
487 if animTime < foldingPart.animDuration then
488 isInvalid = true
489 end
490 foldAnimTime = math.max(foldAnimTime, animTime / spec.maxFoldAnimDuration)
491 elseif spec.foldMoveDirection < 0 then
492 local animTime
493 if charSet ~= 0 then
494 animTime = getAnimTrackTime(charSet, 0)
495 else
496 animTime = self:getRealAnimationTime(foldingPart.animationName)
497 end
498 if animTime > 0 then
499 isInvalid = true
500 end
501 foldAnimTime = math.min(foldAnimTime, animTime / spec.maxFoldAnimDuration)
502 end
503 end
504 foldAnimTime = MathUtil.clamp(foldAnimTime, 0, 1)
505 if foldAnimTime ~= spec.foldAnimTime then
506 spec.foldAnimTime = foldAnimTime
507 SpecializationUtil.raiseEvent(self, "onFoldTimeChanged", spec.foldAnimTime)
508 end
509
510 if spec.foldMoveDirection > 0 then
511 if not spec.moveToMiddle or spec.foldMiddleAnimTime == nil then
512 if spec.foldAnimTime == 1 then
513 spec.foldMoveDirection = 0
514 end
515 else
516 if spec.foldAnimTime == spec.foldMiddleAnimTime then
517 spec.foldMoveDirection = 0
518 end
519 end
520 elseif spec.foldMoveDirection < 0 then
521 if not spec.moveToMiddle or spec.foldMiddleAnimTime == nil then
522 if spec.foldAnimTime == 0 then
523 spec.foldMoveDirection = 0
524 end
525 else
526 if spec.foldAnimTime == spec.foldMiddleAnimTime then
527 spec.foldMoveDirection = 0
528 end
529 end
530 end
531
532 if isInvalid and self.isServer then
533 for _,foldingPart in pairs(spec.foldingParts) do
534 if foldingPart.componentJoint ~= nil then
535 self:setComponentJointFrame(foldingPart.componentJoint, foldingPart.anchorActor)
536 end
537 end
538 end
539
540 for _, vehicle in pairs(spec.subFoldingStateVehicles) do
541 Foldable.setAnimTime(vehicle, spec.foldAnimTime, false)
542 end
543 end
544
545
546 for i=1, #spec.foldingParts do
547 local foldingPart = spec.foldingParts[i]
548
549 local delayedLowering = foldingPart.delayedLowering
550 if delayedLowering ~= nil then
551 if delayedLowering.currentDistance >= 0 then
552 delayedLowering.currentDistance = delayedLowering.currentDistance + self.lastMovedDistance
553
554 if delayedLowering.prevDistance == nil and delayedLowering.startTime + delayedLowering.previousDuration < g_time then
555 delayedLowering.prevDistance = delayedLowering.currentDistance
556 end
557
558 local lowerDistance = self.lastSpeedReal * delayedLowering.loweringDuration
559 local prevDistance = delayedLowering.prevDistance or (self.lastSpeedReal * delayedLowering.previousDuration)
560
561 local distance = (delayedLowering.distance + prevDistance) - lowerDistance
562 local force = g_time > delayedLowering.startTime + delayedLowering.maxDelayDuration * MathUtil.clamp((delayedLowering.currentDistance / distance) * 0.5 + 0.5, 0, 1)
563
564 if delayedLowering.aiSkipDelay then
565 force = force or self:getIsAIActive()
566 end
567
568 if delayedLowering.currentDistance >= distance or force then
569 self:playAnimation(foldingPart.animationName, delayedLowering.speedScale, delayedLowering.animTime, true)
570
571 if delayedLowering.stopAnimTime ~= nil then
572 self:setAnimationStopTime(foldingPart.animationName, delayedLowering.stopAnimTime)
573 end
574
575 delayedLowering.currentDistance = -1
576 end
577 end
578 end
579 end
580end

onUpdateTick

Description
Definition
onUpdateTick()
Code
584function Foldable:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
585 local spec = self.spec_foldable
586
587 -- update actionEvents
588 if self.isClient then
589 Foldable.updateActionEventFold(self)
590 if spec.foldMiddleAnimTime ~= nil then
591 Foldable.updateActionEventFoldMiddle(self)
592 end
593 end
594
595 if self.isServer then
596 -- after the tool has been unfolded we need to sync the attacher joint lowering state with the folding lowering state to be in line
597 if spec.ignoreFoldMiddleWhileFolded then
598 if math.abs(spec.foldAnimTime-spec.foldMiddleAnimTime) < 0.001 and (spec.foldMoveDirection == 1) == (spec.turnOnFoldDirection == 1) then
599 local attacherVehicle = self:getAttacherVehicle()
600 if attacherVehicle ~= nil then
601 local jointDesc = attacherVehicle:getAttacherJointDescFromObject(self)
602 if jointDesc.allowsLowering or jointDesc.isDefaultLowered then
603 if jointDesc.moveDown then
604 self:setFoldState(-1, false)
605 end
606 end
607 end
608 end
609 end
610 end
611end

onWriteStream

Description
Definition
onWriteStream()
Code
459function Foldable:onWriteStream(streamId, connection)
460 local spec = self.spec_foldable
461
462 local direction = MathUtil.sign(spec.foldMoveDirection)+1
463 streamWriteUIntN(streamId, direction, 2)
464 streamWriteBool(streamId, spec.moveToMiddle)
465 streamWriteFloat32(streamId, spec.foldAnimTime)
466end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
17function Foldable.prerequisitesPresent(specializations)
18 return true
19end

registerEventListeners

Description
Definition
registerEventListeners()
Code
275function Foldable.registerEventListeners(vehicleType)
276 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Foldable)
277 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Foldable)
278 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Foldable)
279 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Foldable)
280 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Foldable)
281 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Foldable)
282 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Foldable)
283 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Foldable)
284 SpecializationUtil.registerEventListener(vehicleType, "onSetLoweredAll", Foldable)
285 SpecializationUtil.registerEventListener(vehicleType, "onPostAttach", Foldable)
286 SpecializationUtil.registerEventListener(vehicleType, "onPreDetach", Foldable)
287 SpecializationUtil.registerEventListener(vehicleType, "onRootVehicleChanged", Foldable)
288 SpecializationUtil.registerEventListener(vehicleType, "onPreAttachImplement", Foldable)
289 SpecializationUtil.registerEventListener(vehicleType, "onPreDetachImplement", Foldable)
290end

registerEvents

Description
Definition
registerEvents()
Code
188function Foldable.registerEvents(vehicleType)
189 SpecializationUtil.registerEvent(vehicleType, "onFoldStateChanged")
190 SpecializationUtil.registerEvent(vehicleType, "onFoldTimeChanged")
191end

registerFoldingXMLPaths

Description
Definition
registerFoldingXMLPaths()
Code
126function Foldable.registerFoldingXMLPaths(schema, basePath)
127 schema:register(XMLValueType.L10N_STRING, basePath .. "#objectText", "override OBJECT text inserted in folding action string", "vehicle typeDesc")
128 schema:register(XMLValueType.L10N_STRING, basePath .. "#posDirectionText", "Positive direction text", "$l10n_action_foldOBJECT")
129 schema:register(XMLValueType.L10N_STRING, basePath .. "#negDirectionText", "Negative direction text", "$l10n_action_unfoldOBJECT")
130 schema:register(XMLValueType.L10N_STRING, basePath .. "#middlePosDirectionText", "Positive middle direction text", "$l10n_action_liftOBJECT")
131 schema:register(XMLValueType.L10N_STRING, basePath .. "#middleNegDirectionText", "Negative middle direction text", "$l10n_action_lowerOBJECT")
132
133 schema:register(XMLValueType.FLOAT, basePath .. "#startAnimTime", "Start animation time", "Depending on startMoveDirection")
134 schema:register(XMLValueType.INT, basePath .. "#startMoveDirection", "Start move direction", 0)
135 schema:register(XMLValueType.INT, basePath .. "#turnOnFoldDirection", "Turn on fold direction")
136 schema:register(XMLValueType.BOOL, basePath .. "#allowUnfoldingByAI", "Allow folding by AI", true)
137
138 schema:register(XMLValueType.STRING, basePath .. "#foldInputButton", "Fold Input action", "IMPLEMENT_EXTRA2")
139 schema:register(XMLValueType.STRING, basePath .. "#foldMiddleInputButton", "Fold middle Input action", "LOWER_IMPLEMENT")
140
141 schema:register(XMLValueType.FLOAT, basePath .. "#foldMiddleAnimTime", "Fold middle anim time")
142 schema:register(XMLValueType.INT, basePath .. "#foldMiddleDirection", "Fold middle direction", 1)
143 schema:register(XMLValueType.INT, basePath .. "#foldMiddleAIRaiseDirection", "Fold middle AI raise direction", "same as foldMiddleDirection")
144
145 schema:register(XMLValueType.FLOAT, basePath .. "#turnOnFoldMaxLimit", "Turn on fold max. limit", 1)
146 schema:register(XMLValueType.FLOAT, basePath .. "#turnOnFoldMinLimit", "Turn on fold min. limit", 0)
147 schema:register(XMLValueType.FLOAT, basePath .. "#toggleCoverMaxLimit", "Toggle cover fold max. limit", 1)
148 schema:register(XMLValueType.FLOAT, basePath .. "#toggleCoverMinLimit", "Toggle cover fold min. limit", 0)
149 schema:register(XMLValueType.FLOAT, basePath .. "#detachingMaxLimit", "Detach fold max. limit", 1)
150 schema:register(XMLValueType.FLOAT, basePath .. "#detachingMinLimit", "Detach fold min. limit", 0)
151 schema:register(XMLValueType.BOOL, basePath .. "#allowDetachingWhileFolding", "Allow detaching while folding", false)
152 schema:register(XMLValueType.FLOAT, basePath .. "#loweringMaxLimit", "Lowering fold max. limit", 1)
153 schema:register(XMLValueType.FLOAT, basePath .. "#loweringMinLimit", "Lowering fold min. limit", 0)
154 schema:register(XMLValueType.FLOAT, basePath .. "#loadMovingToolStatesMaxLimit", "Load moving tool states fold max. limit", 1)
155 schema:register(XMLValueType.FLOAT, basePath .. "#loadMovingToolStatesMinLimit", "Load moving tool states fold min. limit", 0)
156 schema:register(XMLValueType.FLOAT, basePath .. "#dynamicMountMaxLimit", "Dynamic mount fold max. limit", 1)
157 schema:register(XMLValueType.FLOAT, basePath .. "#dynamicMountMinLimit", "Dynamic mount fold min. limit", 0)
158 schema:register(XMLValueType.FLOAT, basePath .. "#crabSteeringMinLimit", "Crab steering change fold max. limit", 1)
159 schema:register(XMLValueType.FLOAT, basePath .. "#crabSteeringMaxLimit", "Crab steering change fold min. limit", 0)
160
161 schema:register(XMLValueType.L10N_STRING, basePath .. "#unfoldWarning", "Unfold warning", "$l10n_warning_firstUnfoldTheTool")
162 schema:register(XMLValueType.L10N_STRING, basePath .. "#detachWarning", "Detach warning", "$l10n_warning_doNotDetachWhileFolding")
163
164 schema:register(XMLValueType.BOOL, basePath .. "#useParentFoldingState", "The fold state can not be controlled manually. It's always a copy of the fold state of the parent vehicle.", false)
165 schema:register(XMLValueType.BOOL, basePath .. "#ignoreFoldMiddleWhileFolded", "While the tool is folded pressing the lowering button will only control the attacher joint state, not the fold state. The lowering key has only function if the tool is unfolded. (only if fold middle time defined)", false)
166 schema:register(XMLValueType.BOOL, basePath .. "#lowerWhileDetach", "If tool is in fold middle state it gets lowered on detach and lifted while it's attached again", false)
167 schema:register(XMLValueType.BOOL, basePath .. "#keepFoldingWhileDetached", "If set to 'true' the tool is still continuing with the folding animation after the tool is detached, otherwise it's stopped", "true for mobile platform, otherwise false")
168 schema:register(XMLValueType.BOOL, basePath .. "#releaseBrakesWhileFolding", "If set to 'true' the tool is releasing it's brakes while the folding is active", false)
169 schema:register(XMLValueType.BOOL, basePath .. "#requiresPower", "Vehicle needs to be powered to change folding state", true)
170
171 schema:register(XMLValueType.FLOAT, basePath .. ".foldingPart(?)#speedScale", "Speed scale", 1)
172 schema:register(XMLValueType.INT, basePath .. ".foldingPart(?)#componentJointIndex", "Component joint index")
173 schema:register(XMLValueType.INT, basePath .. ".foldingPart(?)#anchorActor", "Component joint anchor actor", 0)
174
175 schema:register(XMLValueType.NODE_INDEX, basePath .. ".foldingPart(?)#rootNode", "Root node for animation clip")
176 schema:register(XMLValueType.STRING, basePath .. ".foldingPart(?)#animationClip", "Animation clip name")
177 schema:register(XMLValueType.STRING, basePath .. ".foldingPart(?)#animationName", "Animation name")
178
179 schema:register(XMLValueType.FLOAT, basePath .. ".foldingPart(?)#delayDistance", "Distance to be moved by the vehicle until part is played")
180 schema:register(XMLValueType.FLOAT, basePath .. ".foldingPart(?)#previousDuration", "lowering duration if previous part", 1)
181 schema:register(XMLValueType.FLOAT, basePath .. ".foldingPart(?)#loweringDuration", "lowering duration if folding part", 1)
182 schema:register(XMLValueType.FLOAT, basePath .. ".foldingPart(?)#maxDelayDuration", "Max. duration of distance delay until movement is forced. Decreases by half when not moving", 7.5)
183 schema:register(XMLValueType.BOOL, basePath .. ".foldingPart(?)#aiSkipDelay", "Defines if the AI uses the delayed lowering/lifting or is controls all parts synchronized", false)
184end

registerFunctions

Description
Definition
registerFunctions()
Code
195function Foldable.registerFunctions(vehicleType)
196 SpecializationUtil.registerFunction(vehicleType, "loadFoldingPartFromXML", Foldable.loadFoldingPartFromXML)
197 SpecializationUtil.registerFunction(vehicleType, "setFoldDirection", Foldable.setFoldDirection)
198 SpecializationUtil.registerFunction(vehicleType, "setFoldState", Foldable.setFoldState)
199 SpecializationUtil.registerFunction(vehicleType, "getIsUnfolded", Foldable.getIsUnfolded)
200 SpecializationUtil.registerFunction(vehicleType, "getFoldAnimTime", Foldable.getFoldAnimTime)
201 SpecializationUtil.registerFunction(vehicleType, "getIsFoldAllowed", Foldable.getIsFoldAllowed)
202 SpecializationUtil.registerFunction(vehicleType, "getIsFoldMiddleAllowed", Foldable.getIsFoldMiddleAllowed)
203 SpecializationUtil.registerFunction(vehicleType, "getToggledFoldDirection", Foldable.getToggledFoldDirection)
204 SpecializationUtil.registerFunction(vehicleType, "getToggledFoldMiddleDirection", Foldable.getToggledFoldMiddleDirection)
205end

registerLoweringActionEvent

Description
Definition
registerLoweringActionEvent()
Code
1324function Foldable:registerLoweringActionEvent(superFunc, actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName, ignoreCollisions)
1325 local spec = self.spec_foldable
1326 if #spec.foldingParts > 0 then
1327 if spec.foldMiddleAnimTime ~= nil then
1328 self:clearActionEventsTable(spec.actionEventsLowering)
1329
1330 local state, actionEventId
1331 if spec.requiresPower then
1332 state, actionEventId = self:addPoweredActionEvent(spec.actionEventsLowering, spec.foldMiddleInputButton, self, Foldable.actionEventFoldMiddle, false, true, false, true, nil, nil, ignoreCollisions)
1333 else
1334 state, actionEventId = self:addActionEvent(spec.actionEventsLowering, spec.foldMiddleInputButton, self, Foldable.actionEventFoldMiddle, false, true, false, true, nil, nil, ignoreCollisions)
1335 end
1336
1337 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH)
1338 Foldable.updateActionEventFoldMiddle(self)
1339
1340 -- if we are using the same button we use only Foldable.actionEventFoldMiddle, if not, we use both
1341 if spec.foldMiddleInputButton == inputAction then
1342 return state, actionEventId
1343 end
1344 end
1345 end
1346
1347 return superFunc(self, actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName)
1348end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
209function Foldable.registerOverwrittenFunctions(vehicleType)
210 SpecializationUtil.registerOverwrittenFunction(vehicleType, "allowLoadMovingToolStates", Foldable.allowLoadMovingToolStates)
211 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSpeedRotatingPartFromXML", Foldable.loadSpeedRotatingPartFromXML)
212 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSpeedRotatingPartActive", Foldable.getIsSpeedRotatingPartActive)
213 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadCompensationNodeFromXML", Foldable.loadCompensationNodeFromXML)
214 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCompensationAngleScale", Foldable.getCompensationAngleScale)
215 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWheelFromXML", Foldable.loadWheelFromXML)
216 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsVersatileYRotActive", Foldable.getIsVersatileYRotActive)
217 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", Foldable.loadWorkAreaFromXML)
218 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", Foldable.getIsWorkAreaActive)
219 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadGroundReferenceNode", Foldable.loadGroundReferenceNode)
220 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateGroundReferenceNode", Foldable.updateGroundReferenceNode)
221 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadLevelerNodeFromXML", Foldable.loadLevelerNodeFromXML)
222 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsLevelerPickupNodeActive", Foldable.getIsLevelerPickupNodeActive)
223 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadMovingToolFromXML", Foldable.loadMovingToolFromXML)
224 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsMovingToolActive", Foldable.getIsMovingToolActive)
225 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadMovingPartFromXML", Foldable.loadMovingPartFromXML)
226 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsMovingPartActive", Foldable.getIsMovingPartActive)
227 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", Foldable.getCanBeTurnedOn)
228 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsNextCoverStateAllowed", Foldable.getIsNextCoverStateAllowed)
229 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsInWorkPosition", Foldable.getIsInWorkPosition)
230 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getTurnedOnNotAllowedWarning", Foldable.getTurnedOnNotAllowedWarning)
231 SpecializationUtil.registerOverwrittenFunction(vehicleType, "isDetachAllowed", Foldable.isDetachAllowed)
232 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowsLowering", Foldable.getAllowsLowering)
233 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsLowered", Foldable.getIsLowered)
234 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanAIImplementContinueWork", Foldable.getCanAIImplementContinueWork)
235 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsAIReadyToDrive", Foldable.getIsAIReadyToDrive)
236 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsAIPreparingToDrive", Foldable.getIsAIPreparingToDrive)
237 SpecializationUtil.registerOverwrittenFunction(vehicleType, "registerLoweringActionEvent", Foldable.registerLoweringActionEvent)
238 SpecializationUtil.registerOverwrittenFunction(vehicleType, "registerSelfLoweringActionEvent", Foldable.registerSelfLoweringActionEvent)
239 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadGroundAdjustedNodeFromXML", Foldable.loadGroundAdjustedNodeFromXML)
240 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsGroundAdjustedNodeActive", Foldable.getIsGroundAdjustedNodeActive)
241 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSprayTypeFromXML", Foldable.loadSprayTypeFromXML)
242 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSprayTypeActive", Foldable.getIsSprayTypeActive)
243 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Foldable.getCanBeSelected)
244 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadInputAttacherJoint", Foldable.loadInputAttacherJoint)
245 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsInputAttacherActive", Foldable.getIsInputAttacherActive)
246 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadAdditionalCharacterFromXML", Foldable.loadAdditionalCharacterFromXML)
247 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsAdditionalCharacterActive", Foldable.getIsAdditionalCharacterActive)
248 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowDynamicMountObjects", Foldable.getAllowDynamicMountObjects)
249 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSupportAnimationFromXML", Foldable.loadSupportAnimationFromXML)
250 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSupportAnimationAllowed", Foldable.getIsSupportAnimationAllowed)
251 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSteeringAxleFromXML", Foldable.loadSteeringAxleFromXML)
252 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsSteeringAxleAllowed", Foldable.getIsSteeringAxleAllowed)
253 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadFillUnitFromXML", Foldable.loadFillUnitFromXML)
254 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillUnitSupportsToolType", Foldable.getFillUnitSupportsToolType)
255 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadTurnedOnAnimationFromXML", Foldable.loadTurnedOnAnimationFromXML)
256 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsTurnedOnAnimationActive", Foldable.getIsTurnedOnAnimationActive)
257 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadAttacherJointHeightNode", Foldable.loadAttacherJointHeightNode)
258 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsAttacherJointHeightNodeActive", Foldable.getIsAttacherJointHeightNodeActive)
259 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadPickupFromXML", Foldable.loadPickupFromXML)
260 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanChangePickupState", Foldable.getCanChangePickupState)
261 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadCutterTiltFromXML", Foldable.loadCutterTiltFromXML)
262 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCutterTiltIsActive", Foldable.getCutterTiltIsActive)
263 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadPreprunerNodeFromXML", Foldable.loadPreprunerNodeFromXML)
264 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsPreprunerNodeActive", Foldable.getIsPreprunerNodeActive)
265 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadShovelNode", Foldable.loadShovelNode)
266 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getShovelNodeIsActive", Foldable.getShovelNodeIsActive)
267 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadSteeringAngleNodeFromXML", Foldable.loadSteeringAngleNodeFromXML)
268 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateSteeringAngleNode", Foldable.updateSteeringAngleNode)
269 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanToggleCrabSteering", Foldable.getCanToggleCrabSteering)
270 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getBrakeForce", Foldable.getBrakeForce)
271end

registerSelfLoweringActionEvent

Description
Definition
registerSelfLoweringActionEvent()
Code
1352function Foldable:registerSelfLoweringActionEvent(superFunc, actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName, ignoreCollisions)
1353 return Foldable.registerLoweringActionEvent(self, superFunc, actionEventsTable, inputAction, target, callback, triggerUp, triggerDown, triggerAlways, startActive, callbackState, customIconName, ignoreCollisions)
1354end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
440function Foldable:saveToXMLFile(xmlFile, key, usedModNames)
441 local spec = self.spec_foldable
442 if #spec.foldingParts > 0 then
443 xmlFile:setValue(key.."#foldAnimTime", spec.foldAnimTime)
444 end
445end

setAnimTime

Description
Definition
setAnimTime()
Code
2060function Foldable.setAnimTime(self, animTime, placeComponents)
2061 local spec = self.spec_foldable
2062
2063 spec.foldAnimTime = animTime
2064 spec.loadedFoldAnimTime = nil
2065 for _,foldingPart in pairs(spec.foldingParts) do
2066 if foldingPart.animCharSet ~= 0 then
2067 enableAnimTrack(foldingPart.animCharSet, 0)
2068 setAnimTrackTime(foldingPart.animCharSet, 0, spec.foldAnimTime * foldingPart.animDuration, true)
2069 disableAnimTrack(foldingPart.animCharSet, 0)
2070 else
2071 animTime = (spec.foldAnimTime * spec.maxFoldAnimDuration) / self:getAnimationDuration(foldingPart.animationName)
2072 self:setAnimationTime(foldingPart.animationName, animTime, true)
2073 end
2074 end
2075
2076 if placeComponents == nil then
2077 placeComponents = true
2078 end
2079
2080 if self.updateCylinderedInitial ~= nil then
2081 self:updateCylinderedInitial(placeComponents)
2082 end
2083
2084 if placeComponents then
2085 if self.isServer then
2086 for _,foldingPart in pairs(spec.foldingParts) do
2087 if foldingPart.componentJoint ~= nil then
2088 local componentJoint = foldingPart.componentJoint
2089
2090 local jointNode = componentJoint.jointNode
2091 if foldingPart.anchorActor == 1 then
2092 jointNode = componentJoint.jointNodeActor1
2093 end
2094
2095 local node = self.components[componentJoint.componentIndices[ ((foldingPart.anchorActor + 1) % 2) + 1] ].node
2096 local x,y,z = localToWorld(jointNode, foldingPart.x, foldingPart.y, foldingPart.z)
2097 local upX,upY,upZ = localDirectionToWorld(jointNode, foldingPart.upX,foldingPart.upY,foldingPart.upZ)
2098 local dirX,dirY,dirZ = localDirectionToWorld(jointNode, foldingPart.dirX,foldingPart.dirY,foldingPart.dirZ)
2099 setWorldTranslation(node, x,y,z)
2100 I3DUtil.setWorldDirection(node, dirX,dirY,dirZ, upX,upY,upZ)
2101
2102 self:setComponentJointFrame(componentJoint, foldingPart.anchorActor)
2103 end
2104 end
2105 end
2106 end
2107
2108 for _, vehicle in pairs(spec.subFoldingStateVehicles) do
2109 Foldable.setAnimTime(vehicle, animTime, placeComponents)
2110 end
2111
2112 SpecializationUtil.raiseEvent(self, "onFoldTimeChanged", spec.foldAnimTime)
2113end

setFoldDirection

Description
Definition
setFoldDirection()
Code
714function Foldable:setFoldDirection(direction, noEventSend)
715 self:setFoldState(direction, false, noEventSend)
716end

setFoldState

Description
Definition
setFoldState()
Code
720function Foldable:setFoldState(direction, moveToMiddle, noEventSend)
721 local spec = self.spec_foldable
722
723 if spec.foldMiddleAnimTime == nil then
724 moveToMiddle = false
725 end
726 if spec.foldMoveDirection ~= direction or spec.moveToMiddle ~= moveToMiddle then
727 if noEventSend == nil or noEventSend == false then
728 if g_server ~= nil then
729 g_server:broadcastEvent(FoldableSetFoldDirectionEvent.new(self, direction, moveToMiddle), nil, nil, self)
730 else
731 g_client:getServerConnection():sendEvent(FoldableSetFoldDirectionEvent.new(self, direction, moveToMiddle))
732 end
733 end
734 spec.foldMoveDirection = direction
735 spec.moveToMiddle = moveToMiddle
736
737 for _,foldingPart in pairs(spec.foldingParts) do
738 local speedScale = nil
739 -- We don't do any animations if we are already past the middle time
740 if spec.foldMoveDirection > 0.1 then
741 if not spec.moveToMiddle or spec.foldAnimTime < spec.foldMiddleAnimTime then
742 speedScale = foldingPart.speedScale
743 end
744 elseif spec.foldMoveDirection < -0.1 then
745 if not spec.moveToMiddle or spec.foldAnimTime > spec.foldMiddleAnimTime then
746 speedScale = -foldingPart.speedScale
747 end
748 end
749
750 local charSet = foldingPart.animCharSet
751 if charSet ~= 0 then
752 if speedScale ~= nil then
753 if speedScale > 0 then
754 if getAnimTrackTime(charSet, 0) < 0.0 then
755 setAnimTrackTime(charSet, 0, 0.0)
756 end
757 else
758 if getAnimTrackTime(charSet, 0) > foldingPart.animDuration then
759 setAnimTrackTime(charSet, 0, foldingPart.animDuration)
760 end
761 end
762 setAnimTrackSpeedScale(charSet, 0, speedScale)
763 enableAnimTrack(charSet, 0)
764 else
765 disableAnimTrack(charSet, 0)
766 end
767 else
768 -- always stop to make sure the animation state is reset
769 local animTime
770 if self:getIsAnimationPlaying(foldingPart.animationName) then
771 animTime = self:getAnimationTime(foldingPart.animationName)
772 else
773 animTime = (spec.foldAnimTime * spec.maxFoldAnimDuration) / self:getAnimationDuration(foldingPart.animationName)
774 end
775 local alreadyPlaying = self:getIsAnimationPlaying(foldingPart.animationName)
776 self:stopAnimation(foldingPart.animationName, true)
777 if speedScale ~= nil then
778 local stopAnimTime
779 if moveToMiddle then
780 stopAnimTime = (spec.foldMiddleAnimTime * spec.maxFoldAnimDuration)/ self:getAnimationDuration(foldingPart.animationName)
781 end
782
783 local isFolding = (direction ~= spec.turnOnFoldDirection == not moveToMiddle)
784 if foldingPart.delayedLowering == nil or isFolding or alreadyPlaying then
785 self:playAnimation(foldingPart.animationName, speedScale, animTime, true)
786
787 if moveToMiddle then
788 self:setAnimationStopTime(foldingPart.animationName, stopAnimTime)
789 end
790
791 if foldingPart.delayedLowering ~= nil then
792 foldingPart.delayedLowering.currentDistance = -1
793 end
794 else
795 local delayedLowering = foldingPart.delayedLowering
796 delayedLowering.currentDistance = 0
797 delayedLowering.speedScale = speedScale
798 delayedLowering.animTime = animTime
799 delayedLowering.stopAnimTime = stopAnimTime
800 delayedLowering.startTime = g_time
801 delayedLowering.prevDistance = nil
802 end
803 end
804 end
805 end
806 -- slightly move fold anim time, so that fold limits can trigger for different actions
807 if spec.foldMoveDirection > 0.1 then
808 spec.foldAnimTime = math.min(spec.foldAnimTime + 0.0001, math.max(spec.foldAnimTime, 1))
809 elseif spec.foldMoveDirection < -0.1 then
810 spec.foldAnimTime = math.max(spec.foldAnimTime - 0.0001, math.min(spec.foldAnimTime, 0))
811 end
812
813 SpecializationUtil.raiseEvent(self, "onFoldStateChanged", direction, moveToMiddle)
814 end
815end

updateActionEventFold

Description
Definition
updateActionEventFold()
Code
2117function Foldable.updateActionEventFold(self)
2118 local spec = self.spec_foldable
2119 local actionEvent = spec.actionEvents[spec.foldInputButton]
2120 if actionEvent ~= nil then
2121 local direction = self:getToggledFoldDirection()
2122 local text
2123 if direction == spec.turnOnFoldDirection then
2124 text = spec.negDirectionText
2125 else
2126 text = spec.posDirectionText
2127 end
2128 g_inputBinding:setActionEventText(actionEvent.actionEventId, text)
2129 end
2130end

updateActionEventFoldMiddle

Description
Definition
updateActionEventFoldMiddle()
Code
2134function Foldable.updateActionEventFoldMiddle(self)
2135 local spec = self.spec_foldable
2136 local actionEvent = spec.actionEventsLowering[spec.foldMiddleInputButton]
2137 if actionEvent ~= nil then
2138 local state = self:getIsFoldMiddleAllowed()
2139 g_inputBinding:setActionEventActive(actionEvent.actionEventId, state)
2140 if state then
2141 local direction = self:getToggledFoldMiddleDirection() == spec.foldMiddleDirection
2142 if spec.ignoreFoldMiddleWhileFolded then
2143 if self:getFoldAnimTime() > spec.foldMiddleAnimTime then
2144 direction = self:getIsLowered(true)
2145 end
2146 end
2147
2148 local text
2149 if direction then
2150 text = spec.middlePosDirectionText
2151 else
2152 text = spec.middleNegDirectionText
2153 end
2154 g_inputBinding:setActionEventText(actionEvent.actionEventId, text)
2155 end
2156 end
2157end

updateGroundReferenceNode

Description
Definition
updateGroundReferenceNode()
Code
1080function Foldable:updateGroundReferenceNode(superFunc, groundReferenceNode)
1081 superFunc(self, groundReferenceNode)
1082
1083 local foldAnimTime = self:getFoldAnimTime()
1084 if foldAnimTime > groundReferenceNode.foldMaxLimit or foldAnimTime < groundReferenceNode.foldMinLimit then
1085 groundReferenceNode.isActive = false
1086 end
1087end

updateSteeringAngleNode

Description
Definition
updateSteeringAngleNode()
Code
1735function Foldable:updateSteeringAngleNode(superFunc, steeringAngleNode, angle, dt)
1736 local foldAnimTime = self:getFoldAnimTime()
1737 if foldAnimTime < steeringAngleNode.foldMinLimit or foldAnimTime > steeringAngleNode.foldMaxLimit then
1738 return
1739 end
1740
1741 return superFunc(self, steeringAngleNode, angle, dt)
1742end