Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
Wearable
DescriptionSpecialization allowing vehicles to wear off (with visual and funcional consequences) and be repaired againFunctions
- addAllSubWearableNodes
- addToGlobalWearableNode
- addToLocalWearableNode
- addWearableNodes
- addWearAmount
- getIntervalMultiplier
- getNodeWearAmount
- getRepairPrice
- getUsageCausesWear
- getVehicleDamage
- getWearMultiplier
- getWearTotalAmount
- getWorkWearMultiplier
- onLoad
- onPostLoad
- onReadStream
- onReadUpdateStream
- onUpdateTick
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- removeWearableNode
- repairVehicle
- saveToXMLFile
- setNodeWearAmount
- updateDebugValues
- updateWearAmount
- validateWearableNode
addAllSubWearableNodes
DescriptionDefinitionaddAllSubWearableNodes()Code
307 | function Wearable:addAllSubWearableNodes(rootNode) |
308 | if rootNode ~= nil then |
309 | local nodes = {} |
310 | I3DUtil.getNodesByShaderParam(rootNode, "RDT", nodes) |
311 | self:addWearableNodes(nodes) |
312 | end |
313 | end |
addToGlobalWearableNode
DescriptionDefinitionaddToGlobalWearableNode()Code
336 | function Wearable:addToGlobalWearableNode(node) |
337 | local spec = self.spec_wearable |
338 | if spec.wearableNodes[1] ~= nil then |
339 | table.insert(spec.wearableNodes[1].nodes, node) |
340 | end |
341 | end |
addToLocalWearableNode
DescriptionDefinitionaddToLocalWearableNode()Code
345 | function Wearable:addToLocalWearableNode(node, updateFunc, customIndex, extraParams) |
346 | local spec = self.spec_wearable |
347 | |
348 | local nodeData = {} |
349 | |
350 | --if wearableNode already exists we add node to existing wearableNode |
351 | if customIndex ~= nil then |
352 | if spec.wearableNodesByIndex[customIndex] ~= nil then |
353 | table.insert(spec.wearableNodesByIndex[customIndex].nodes, node) |
354 | return |
355 | else |
356 | spec.wearableNodesByIndex[customIndex] = nodeData |
357 | end |
358 | end |
359 | |
360 | --if wearableNode doesn't exists we create a new one |
361 | nodeData.nodes = {node} |
362 | nodeData.updateFunc = updateFunc |
363 | nodeData.wearAmount = 0 |
364 | nodeData.wearAmountSent = 0 |
365 | if extraParams ~= nil then |
366 | for i, v in pairs(extraParams) do |
367 | nodeData[i] = v |
368 | end |
369 | end |
370 | |
371 | table.insert(spec.wearableNodes, nodeData) |
372 | end |
addWearableNodes
DescriptionDefinitionaddWearableNodes()Code
317 | function Wearable:addWearableNodes(nodes) |
318 | for _, node in pairs(nodes) do |
319 | local isGlobal, updateFunc, customIndex, extraParams = self:validateWearableNode(node) |
320 | if isGlobal then |
321 | self:addToGlobalWearableNode(node) |
322 | elseif updateFunc ~= nil then |
323 | self:addToLocalWearableNode(node, updateFunc, customIndex, extraParams) |
324 | end |
325 | end |
326 | end |
addWearAmount
DescriptionDefinitionaddWearAmount()Code
224 | function Wearable:addWearAmount(wearAmount, force) |
225 | local spec = self.spec_wearable |
226 | if spec.wearableNodes ~= nil then |
227 | for _, nodeData in ipairs(spec.wearableNodes) do |
228 | self:setNodeWearAmount(nodeData, self:getNodeWearAmount(nodeData) + wearAmount, force) |
229 | end |
230 | end |
231 | end |
getIntervalMultiplier
DescriptionDefinitiongetIntervalMultiplier()Code
416 | function Wearable.getIntervalMultiplier() |
417 | return 0.5 |
418 | end |
getNodeWearAmount
DescriptionDefinitiongetNodeWearAmount()Code
262 | function Wearable:getNodeWearAmount(nodeData) |
263 | return nodeData.wearAmount |
264 | end |
getRepairPrice
DescriptionGet the price of a repairDefinition
getRepairPrice()Code
291 | function Wearable:getRepairPrice(superFunc, atSellingPoint) |
292 | local factor = 1 |
293 | if atSellingPoint ~= nil and atSellingPoint then |
294 | factor = 1 / EconomyManager.DIRECT_SELL_MULTIPLIER |
295 | end |
296 | return superFunc(self) + self:getPrice() * self:getWearTotalAmount() / 100 * factor |
297 | end |
getUsageCausesWear
DescriptionDefinitiongetUsageCausesWear()Code
218 | function Wearable:getUsageCausesWear() |
219 | return self:getPropertyState() ~= Vehicle.PROPERTY_STATE_MISSION |
220 | end |
getVehicleDamage
DescriptionDefinitiongetVehicleDamage()Code
301 | function Wearable:getVehicleDamage(superFunc) |
302 | return MathUtil.clamp(superFunc(self) + Wearable.DAMAGE_CURVE:get(self.spec_wearable.totalAmount), 0, 1) |
303 | end |
getWearMultiplier
DescriptionGet wear multiplierDefinition
getWearMultiplier()Return Values
number | multiplier |
390 | function Wearable:getWearMultiplier() |
391 | local spec = self.spec_wearable |
392 | |
393 | local multiplier = 1 |
394 | if self:getLastSpeed() < 1 then |
395 | multiplier = 0 |
396 | end |
397 | |
398 | if self:getIsOnField() then |
399 | multiplier = multiplier * spec.fieldMultiplier |
400 | end |
401 | |
402 | return multiplier |
403 | end |
getWearTotalAmount
DescriptionGet the total wearDefinition
getWearTotalAmount()Return Values
number | total |
269 | function Wearable:getWearTotalAmount() |
270 | return self.spec_wearable.totalAmount |
271 | end |
getWorkWearMultiplier
DescriptionGet work wear multiplierDefinition
getWorkWearMultiplier()Return Values
number | multiplier |
408 | function Wearable:getWorkWearMultiplier() |
409 | local spec = self.spec_wearable |
410 | |
411 | return spec.workMultiplier |
412 | end |
onLoad
DescriptionDefinitiononLoad()Code
72 | function Wearable:onLoad(savegame) |
73 | local spec = self.spec_wearable |
74 | |
75 | spec.wearableNodes = {} |
76 | spec.wearableNodesByIndex = {} |
77 | self:addToLocalWearableNode(nil, Wearable.updateWearAmount, nil, nil) -- create global / default wearableNode |
78 | |
79 | spec.wearDuration = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.wearable#wearDuration"), 600) * 60 * 1000 -- default 600min / 10h |
80 | if spec.wearDuration ~= 0 then |
81 | spec.wearDuration = 1 / spec.wearDuration |
82 | end |
83 | |
84 | spec.totalAmount = 0 |
85 | |
86 | spec.workMultiplier = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.wearable#workMultiplier"), 20) |
87 | spec.fieldMultiplier = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.wearable#fieldMultiplier"), 2) |
88 | |
89 | spec.dirtyFlag = self:getNextDirtyFlag() |
90 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
94 | function Wearable:onPostLoad(savegame) |
95 | local spec = self.spec_wearable |
96 | |
97 | -- getting als wearable nodes in postLoad to make sure also linked nodes are wearable |
98 | if spec.wearableNodes ~= nil then |
99 | for _, component in pairs(self.components) do |
100 | self:addAllSubWearableNodes(component.node) |
101 | end |
102 | |
103 | if savegame ~= nil and Wearable.getIntervalMultiplier() ~= 0 then |
104 | for i, nodeData in ipairs(spec.wearableNodes) do |
105 | local nodeKey = string.format("%s.wearable.wearNode(%d)", savegame.key, i-1) |
106 | local amount = Utils.getNoNil(getXMLFloat(savegame.xmlFile, nodeKey.."#amount"), 0) |
107 | self:setNodeWearAmount(nodeData, amount, true) |
108 | end |
109 | else |
110 | for _, nodeData in ipairs(spec.wearableNodes) do |
111 | self:setNodeWearAmount(nodeData, 0, true) |
112 | end |
113 | end |
114 | end |
115 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
132 | function Wearable:onReadStream(streamId, connection) |
133 | local spec = self.spec_wearable |
134 | |
135 | if spec.wearableNodes ~= nil then |
136 | for _, nodeData in ipairs(spec.wearableNodes) do |
137 | local wearAmount = streamReadUIntN(streamId, Wearable.SEND_NUM_BITS) / Wearable.SEND_MAX_VALUE |
138 | self:setNodeWearAmount(nodeData, wearAmount, true) |
139 | end |
140 | end |
141 | end |
onReadUpdateStream
DescriptionDefinitiononReadUpdateStream()Code
157 | function Wearable:onReadUpdateStream(streamId, timestamp, connection) |
158 | local spec = self.spec_wearable |
159 | |
160 | if connection:getIsServer() then |
161 | if spec.wearableNodes ~= nil then |
162 | if streamReadBool(streamId) then |
163 | for _, nodeData in ipairs(spec.wearableNodes) do |
164 | local wearAmount = streamReadUIntN(streamId, Wearable.SEND_NUM_BITS) / Wearable.SEND_MAX_VALUE |
165 | self:setNodeWearAmount(nodeData, wearAmount, true) |
166 | end |
167 | end |
168 | end |
169 | end |
170 | end |
onUpdateTick
DescriptionDefinitiononUpdateTick()Code
190 | function Wearable:onUpdateTick(dt, isActive, isActiveForInput, isSelected) |
191 | local spec = self.spec_wearable |
192 | |
193 | if spec.wearableNodes ~= nil then |
194 | if self.isServer then |
195 | for _, nodeData in ipairs(spec.wearableNodes) do |
196 | local changedAmount = nodeData.updateFunc(self, nodeData, dt) |
197 | if changedAmount ~= 0 then |
198 | self:setNodeWearAmount(nodeData, self:getNodeWearAmount(nodeData) + changedAmount) |
199 | end |
200 | end |
201 | end |
202 | end |
203 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
145 | function Wearable:onWriteStream(streamId, connection) |
146 | local spec = self.spec_wearable |
147 | |
148 | if spec.wearableNodes ~= nil then |
149 | for _, nodeData in ipairs(spec.wearableNodes) do |
150 | streamWriteUIntN(streamId, math.floor(self:getNodeWearAmount(nodeData) * Wearable.SEND_MAX_VALUE + 0.5), Wearable.SEND_NUM_BITS) |
151 | end |
152 | end |
153 | end |
onWriteUpdateStream
DescriptionDefinitiononWriteUpdateStream()Code
174 | function Wearable:onWriteUpdateStream(streamId, connection, dirtyMask) |
175 | local spec = self.spec_wearable |
176 | |
177 | if not connection:getIsServer() then |
178 | if spec.wearableNodes ~= nil then |
179 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
180 | for _, nodeData in ipairs(spec.wearableNodes) do |
181 | streamWriteUIntN(streamId, math.floor(self:getNodeWearAmount(nodeData) * Wearable.SEND_MAX_VALUE + 0.5), Wearable.SEND_NUM_BITS) |
182 | end |
183 | end |
184 | end |
185 | end |
186 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
27 | function Wearable.prerequisitesPresent(specializations) |
28 | return true |
29 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
60 | function Wearable.registerEventListeners(vehicleType) |
61 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Wearable) |
62 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Wearable) |
63 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Wearable) |
64 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Wearable) |
65 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Wearable) |
66 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Wearable) |
67 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Wearable) |
68 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
33 | function Wearable.registerFunctions(vehicleType) |
34 | SpecializationUtil.registerFunction(vehicleType, "updateWearAmount", Wearable.updateWearAmount) |
35 | SpecializationUtil.registerFunction(vehicleType, "addWearAmount", Wearable.addWearAmount) |
36 | SpecializationUtil.registerFunction(vehicleType, "setNodeWearAmount", Wearable.setNodeWearAmount) |
37 | SpecializationUtil.registerFunction(vehicleType, "getNodeWearAmount", Wearable.getNodeWearAmount) |
38 | SpecializationUtil.registerFunction(vehicleType, "addAllSubWearableNodes", Wearable.addAllSubWearableNodes) |
39 | SpecializationUtil.registerFunction(vehicleType, "addWearableNodes", Wearable.addWearableNodes) |
40 | SpecializationUtil.registerFunction(vehicleType, "validateWearableNode", Wearable.validateWearableNode) |
41 | SpecializationUtil.registerFunction(vehicleType, "addToGlobalWearableNode", Wearable.addToGlobalWearableNode) |
42 | SpecializationUtil.registerFunction(vehicleType, "addToLocalWearableNode", Wearable.addToLocalWearableNode) |
43 | SpecializationUtil.registerFunction(vehicleType, "removeWearableNode", Wearable.removeWearableNode) |
44 | SpecializationUtil.registerFunction(vehicleType, "getWearMultiplier", Wearable.getWearMultiplier) |
45 | SpecializationUtil.registerFunction(vehicleType, "getWorkWearMultiplier", Wearable.getWorkWearMultiplier) |
46 | SpecializationUtil.registerFunction(vehicleType, "getWearTotalAmount", Wearable.getWearTotalAmount) |
47 | SpecializationUtil.registerFunction(vehicleType, "repairVehicle", Wearable.repairVehicle) |
48 | SpecializationUtil.registerFunction(vehicleType, "getUsageCausesWear", Wearable.getUsageCausesWear) |
49 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
53 | function Wearable.registerOverwrittenFunctions(vehicleType) |
54 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getVehicleDamage", Wearable.getVehicleDamage) |
55 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getRepairPrice", Wearable.getRepairPrice) |
56 | end |
removeWearableNode
DescriptionRemove wearable nodeDefinition
removeWearableNode(node table)Arguments
node | table | node |
377 | function Wearable:removeWearableNode(node) |
378 | local spec = self.spec_wearable |
379 | |
380 | if spec.wearableNodes ~= nil and node ~= nil then |
381 | for _, nodeData in ipairs(spec.wearableNodes) do |
382 | nodeData.nodes[node] = nil |
383 | end |
384 | end |
385 | end |
repairVehicle
DescriptionRepair the vehicle. Owner pays.Definition
repairVehicle(atSellingPoint bool)Arguments
atSellingPoint | bool | Whether this is at selling point (influenced price) |
276 | function Wearable:repairVehicle(atSellingPoint) |
277 | if self.isServer then |
278 | g_currentMission:addMoney(-self:getRepairPrice(atSellingPoint), self:getOwnerFarmId(), MoneyType.VEHICLE_REPAIR, true, true) |
279 | |
280 | local spec = self.spec_wearable |
281 | for _, data in ipairs(spec.wearableNodes) do |
282 | self:setNodeWearAmount(data, 0, true) |
283 | end |
284 | |
285 | self:raiseDirtyFlags(spec.dirtyFlag) |
286 | end |
287 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
119 | function Wearable:saveToXMLFile(xmlFile, key, usedModNames) |
120 | local spec = self.spec_wearable |
121 | |
122 | if spec.wearableNodes ~= nil then |
123 | for i, nodeData in ipairs(spec.wearableNodes) do |
124 | local nodeKey = string.format("%s.wearNode(%d)", key, i-1) |
125 | setXMLFloat(xmlFile, nodeKey.."#amount", self:getNodeWearAmount(nodeData)) |
126 | end |
127 | end |
128 | end |
setNodeWearAmount
DescriptionDefinitionsetNodeWearAmount()Code
235 | function Wearable:setNodeWearAmount(nodeData, wearAmount, force) |
236 | local spec = self.spec_wearable |
237 | nodeData.wearAmount = MathUtil.clamp(wearAmount, 0, 1) |
238 | |
239 | local diff = nodeData.wearAmountSent - nodeData.wearAmount |
240 | if math.abs(diff) > Wearable.SEND_THRESHOLD or force then |
241 | for _, node in pairs(nodeData.nodes) do |
242 | local _, y, z, w = getShaderParameter(node, "RDT") |
243 | setShaderParameter(node, "RDT", nodeData.wearAmount, y, z, w, false) |
244 | end |
245 | |
246 | if self.isServer then |
247 | self:raiseDirtyFlags(spec.dirtyFlag) |
248 | nodeData.wearAmountSent = nodeData.wearAmount |
249 | end |
250 | |
251 | -- calculate total wearable amount |
252 | spec.totalAmount = 0 |
253 | for _, data in ipairs(spec.wearableNodes) do |
254 | spec.totalAmount = spec.totalAmount + data.wearAmount |
255 | end |
256 | spec.totalAmount = spec.totalAmount / #spec.wearableNodes |
257 | end |
258 | end |
updateDebugValues
DescriptionDefinitionupdateDebugValues()Code
422 | function Wearable:updateDebugValues(values) |
423 | local spec = self.spec_wearable |
424 | if spec.wearableNodes ~= nil then |
425 | if self.isServer then |
426 | for i, nodeData in ipairs(spec.wearableNodes) do |
427 | local changedAmount = nodeData.updateFunc(self, nodeData, 3600000) |
428 | table.insert(values, {name="WearableNode"..i, value=string.format("%.4f a/h (%.2f)", changedAmount, self:getNodeWearAmount(nodeData))}) |
429 | end |
430 | end |
431 | end |
432 | end |
updateWearAmount
DescriptionDefinitionupdateWearAmount()Code
207 | function Wearable:updateWearAmount(nodeData, dt) |
208 | local spec = self.spec_wearable |
209 | if self:getUsageCausesWear() then |
210 | return dt * spec.wearDuration * self:getWearMultiplier(nodeData) * Wearable.getIntervalMultiplier() |
211 | else |
212 | return 0 |
213 | end |
214 | end |
validateWearableNode
DescriptionDefinitionvalidateWearableNode()Code
330 | function Wearable:validateWearableNode(node) |
331 | return true, nil -- by default all nodes are global |
332 | end |