LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

SlopeCompensation

Description
Specialization for automatic slope compensation in vehicles based on the angle between two wheel nodes
Functions

getCompensationAngleScale

Description
Definition
getCompensationAngleScale()
Code
125function SlopeCompensation:getCompensationAngleScale(compensationNode)
126 return 1
127end

getCompensationGroundPosition

Description
Definition
getCompensationGroundPosition()
Code
131function SlopeCompensation:getCompensationGroundPosition(compensationNode, wheelId)
132 local spec = self.spec_slopeCompensation
133 local x, y, z = getWorldTranslation(compensationNode["wheel"..wheelId.."Node"])
134
135 spec.lastRaycastDistance = 0
136 raycastAll(x, y, z, 0, -1, 0, "slopeDetectionCallback", compensationNode.raycastDistance, self, SlopeCompensation.SLOPE_COLLISION_MASK)
137 local distance = spec.lastRaycastDistance
138 if distance == 0 then
139 distance = compensationNode["lastDistance"..wheelId]
140 else
141 compensationNode["lastDistance"..wheelId] = spec.lastRaycastDistance
142 end
143
144 return x, y - distance, z, distance ~= 0
145end

loadCompensationNodeFromXML

Description
Definition
loadCompensationNodeFromXML()
Code
91function SlopeCompensation:loadCompensationNodeFromXML(compensationNode, xmlFile, key)
92 compensationNode.raycastDistance = 0
93 compensationNode.lastDistance1 = 0
94 compensationNode.lastDistance2 = 0
95 for _, name in ipairs({"wheel1", "wheel2"}) do
96 local wheelId = getXMLInt(self.xmlFile, key.."#"..name)
97 if wheelId == nil then
98 g_logManager:xmlWarning(self.configFileName, "Missing %s for compensation node '%s'", name, key)
99 return false
100 end
101
102 local wheel = self:getWheels()[wheelId]
103 if wheel ~= nil then
104 compensationNode[name.."Node"] = wheel.repr
105 compensationNode.raycastDistance = math.max(compensationNode.raycastDistance, wheel.radius+1)
106 else
107 g_logManager:xmlWarning(self.configFileName, "Unable to find wheel index '%d' for compensation node '%s'", wheelId, key)
108 return false
109 end
110 end
111
112 compensationNode.maxAngle = Utils.getNoNilRad(getXMLFloat(self.xmlFile, key.."#maxAngle"), math.rad(5))
113 compensationNode.minAngle = Utils.getNoNilRad(getXMLFloat(self.xmlFile, key.."#minAngle"), -compensationNode.maxAngle)
114
115 compensationNode.animationName = getXMLString(self.xmlFile, key.."#animationName")
116 if compensationNode.animationName ~= nil then
117 self:setAnimationTime(compensationNode.animationName, 0.5, true)
118 end
119
120 return true
121end

onPostLoad

Description
Definition
onPostLoad()
Code
38function SlopeCompensation:onPostLoad(savegame)
39 local spec = self.spec_slopeCompensation
40
41 spec.lastRaycastDistance = 0
42 spec.nodes = {}
43 local i = 0
44 while true do
45 local key = string.format("vehicle.slopeCompensation.compensationNode(%d)", i)
46 if not hasXMLProperty(self.xmlFile, key) then
47 break
48 end
49
50 local compensationNode = {}
51 if self:loadCompensationNodeFromXML(compensationNode, self.xmlFile, key) then
52 table.insert(spec.nodes, compensationNode)
53 end
54
55 i = i + 1
56 end
57
58 spec.lastPos = -1
59 spec.threshold = getXMLFloat(self.xmlFile, "vehicle.slopeCompensation#threshold") or 0.002
60end

onUpdateTick

Description
Definition
onUpdateTick()
Code
64function SlopeCompensation:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
65 local spec = self.spec_slopeCompensation
66
67 for _, compensationNode in ipairs(spec.nodes) do
68 local x1, y1, z1, valid1 = self:getCompensationGroundPosition(compensationNode, 1)
69 local x2, y2, z2, valid2 = self:getCompensationGroundPosition(compensationNode, 2)
70
71 if valid1 and valid2 then
72 local h = y1 - y2
73 local l = MathUtil.vector2Length(x1-x2, z1-z2)
74 local angle = math.tan(h/l) * self:getCompensationAngleScale(compensationNode)
75 local pos = MathUtil.clamp((angle - compensationNode.minAngle) / (compensationNode.maxAngle - compensationNode.minAngle), 0, 1)
76
77 if math.abs(spec.lastPos - pos) > spec.threshold then
78 spec.lastPos = pos
79 if self.setAnimationTime ~= nil then
80 if compensationNode.animationName ~= nil then
81 self:setAnimationTime(compensationNode.animationName, pos, true)
82 end
83 end
84 end
85 end
86 end
87end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
16function SlopeCompensation.prerequisitesPresent(specializations)
17 return SpecializationUtil.hasSpecialization(Wheels, specializations)
18end

registerEventListeners

Description
Definition
registerEventListeners()
Code
31function SlopeCompensation.registerEventListeners(vehicleType)
32 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", SlopeCompensation)
33 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", SlopeCompensation)
34end

registerFunctions

Description
Definition
registerFunctions()
Code
22function SlopeCompensation.registerFunctions(vehicleType)
23 SpecializationUtil.registerFunction(vehicleType, "loadCompensationNodeFromXML", SlopeCompensation.loadCompensationNodeFromXML)
24 SpecializationUtil.registerFunction(vehicleType, "getCompensationAngleScale", SlopeCompensation.getCompensationAngleScale)
25 SpecializationUtil.registerFunction(vehicleType, "getCompensationGroundPosition", SlopeCompensation.getCompensationGroundPosition)
26 SpecializationUtil.registerFunction(vehicleType, "slopeDetectionCallback", SlopeCompensation.slopeDetectionCallback)
27end

slopeDetectionCallback

Description
Definition
slopeDetectionCallback()
Code
149function SlopeCompensation:slopeDetectionCallback(hitObjectId, x, y, z, distance)
150 if getRigidBodyType(hitObjectId) ~= "Static" then
151 return true
152 end
153
154 self.spec_slopeCompensation.lastRaycastDistance = distance
155
156 return false
157end