Sprache Deutsch Language English

Script Dokumentation LS 2015 - WorkParticles (Patch 1.3)

Script Dokumentation Übersicht

scripts/vehicles/specializations/WorkParticles.lua

Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1--
2-- WorkParticles
3-- Class for all vehicles with animated work particles
4--
5-- @author Manuel Leithner
6-- @date 21/07/14
7--
8-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
9
10WorkParticles = {};
11
12function WorkParticles.prerequisitesPresent(specializations)
13 return true;
14end;
15
16function WorkParticles:preLoad(xmlFile)
17 self.loadGroundReferenceNodeFromXML = Utils.overwrittenFunction(self.loadGroundReferenceNodeFromXML, WorkParticles.loadGroundReferenceNodeFromXML);
18 assert(self.getDoGroundManipulation == nil, "WorkParticles needs to be the first specialization which implements getDoGroundManipulation");
19 self.getDoGroundManipulation = WorkParticles.getDoGroundManipulation;
20end
21
22function WorkParticles:load(xmlFile)
23
24 if self.isClient then
25 if hasXMLProperty(xmlFile, "vehicle.groundParticleSystem") then
26 print("Warning: vehicle.groundParticleSystem is not supported anymore in "..self.configFileName..". Use vehicle.groundParticleSystems.groundParticleSystem instead!");
27 end;
28
29 self.groundParticleAnimations = {};
30 local i = 0;
31 while true do
32 local baseName = string.format("vehicle.groundParticleAnimations.groundParticleAnimation(%d)", i);
33 if not hasXMLProperty(xmlFile, baseName) then
34 break;
35 end;
36 local animation = {};
37 local filenameStr = getXMLString(xmlFile, baseName .. "#file");
38 local i3dNode = Utils.loadSharedI3DFile(filenameStr, self.baseDirectory);
39 if i3dNode ~= 0 then
40 animation.filename = filenameStr;
41 animation.mappings = {};
42 local j = 0;
43 while true do
44 local nodeBaseName = string.format(baseName .. ".node(%d)", j);
45 if not hasXMLProperty(xmlFile, nodeBaseName) then
46 break;
47 end;
48
49 local node = Utils.indexToObject(self.components, getXMLString(xmlFile, nodeBaseName.."#index"));
50 local animNode = Utils.indexToObject(i3dNode, getXMLString(xmlFile, nodeBaseName.."#animMeshIndex"));
51 local groundRefIndex = getXMLInt(xmlFile, nodeBaseName .. "#refNodeIndex");
52 if node == nil then
53 print("Warning: Invalid node index '"..getXMLString(xmlFile, nodeBaseName.."#index").."' in '"..self.configFileName.."'!");
54 break;
55 end;
56 if animNode == nil then
57 print("Warning: Invalid animMesh index '"..getXMLString(xmlFile, nodeBaseName.."#animMeshIndex").."' in '"..self.configFileName.."'!");
58 break;
59 end;
60 if groundRefIndex == nil or self.groundReferenceNodes[groundRefIndex+1] == nil then
61 print("Warning: Invalid refNodeIndex '"..getXMLString(xmlFile, nodeBaseName.."#refNodeIndex").."' in '"..self.configFileName.."'!");
62 break;
63 end;
64
65 local mapping = {};
66 mapping.node = node;
67 mapping.animNode = animNode;
68 mapping.groundRefNode = self.groundReferenceNodes[groundRefIndex+1];
69 mapping.lastDepth = 0;
70 mapping.speed = 0;
71 mapping.maxWorkDepth = Utils.getNoNil(getXMLFloat(xmlFile, nodeBaseName.."#maxDepth"), -0.1);
72 table.insert(animation.mappings, mapping);
73 j = j + 1;
74 end;
75
76 -- link after loading to make sure all indices are correct
77 for _, mapping in pairs(animation.mappings) do
78 link(mapping.node, mapping.animNode);
79 setVisibility(mapping.animNode, false);
80 end;
81
82 delete(i3dNode);
83 end;
84
85 table.insert(self.groundParticleAnimations, animation);
86 i = i+1;
87 end;
88
89 self.groundParticles = {};
90 local i = 0;
91 while true do
92 local baseName = string.format("vehicle.groundParticleAnimations.groundParticle(%d)", i);
93 if not hasXMLProperty(xmlFile, baseName) then
94 break;
95 end;
96 local particle = {};
97 local filenameStr = getXMLString(xmlFile, baseName .. "#file");
98 local filename = Utils.getFilename(filenameStr, self.baseDirectory)
99 local i3dNode = loadI3DFile(filename, true, true, false);
100 if i3dNode ~= 0 then
101 particle.filename = filename;
102 particle.mappings = {};
103 local j = 0;
104 while true do
105 local nodeBaseName = string.format(baseName .. ".node(%d)", j);
106 if not hasXMLProperty(xmlFile, nodeBaseName) then
107 break;
108 end;
109
110 local node = Utils.indexToObject(self.components, getXMLString(xmlFile, nodeBaseName.."#index"));
111 local particleNode = Utils.indexToObject(i3dNode, getXMLString(xmlFile, nodeBaseName.."#particleIndex"));
112 local groundRefIndex = getXMLInt(xmlFile, nodeBaseName .. "#refNodeIndex");
113 if node == nil then
114 print("Warning: Invalid node index '"..getXMLString(xmlFile, nodeBaseName.."#index").."' in '"..self.configFileName.."'!");
115 break;
116 end;
117 if particleNode == nil then
118 print("Warning: Invalid particle index '"..getXMLString(xmlFile, nodeBaseName.."#particleIndex").."' in '"..self.configFileName.."'!");
119 break;
120 end;
121 if groundRefIndex == nil or self.groundReferenceNodes[groundRefIndex+1] == nil then
122 print("Warning: Invalid refNodeIndex '"..getXMLString(xmlFile, nodeBaseName.."#refNodeIndex").."' in '"..self.configFileName.."'!");
123 break;
124 end;
125
126 local mapping = {};
127 mapping.particles = {};
128 mapping.node = node;
129 mapping.particleNode = particleNode;
130 mapping.groundRefNode = self.groundReferenceNodes[groundRefIndex+1];
131 table.insert(particle.mappings, mapping);
132 j = j + 1;
133 end;
134
135 -- link after loading to make sure all indices are correct
136 for _, mapping in pairs(particle.mappings) do
137 link(mapping.node, mapping.particleNode);
138 Utils.loadParticleSystemFromNode(mapping.particleNode, mapping.particles, false);
139 end;
140
141 delete(i3dNode);
142 end;
143
144 table.insert(self.groundParticles, particle);
145 i = i+1;
146 end;
147
148 -- Fallback
149 local i=0;
150 while true do
151 local baseName = string.format("vehicle.groundParticleSystems.groundParticleSystem(%d)", i);
152 if not hasXMLProperty(xmlFile, baseName) then
153 break;
154 end;
155 local mapping = {};
156 mapping.particles = {};
157 Utils.loadParticleSystem(xmlFile, mapping.particles, baseName, self.components, false, nil, self.baseDirectory);
158 if table.getn(mapping.particles) > 0 then
159 local groundRefIndex = Utils.getNoNil(getXMLInt(xmlFile, baseName .. "#refNodeIndex"), 0);
160 if self.groundReferenceNodes[groundRefIndex+1] == nil then
161 groundRefIndex = 0;
162 print("Warning: Invalid refNodeIndex '"..groundRefIndex.."' in '"..self.configFileName.."'! Using default groundreferencenode!");
163 end;
164 mapping.groundRefNode = self.groundReferenceNodes[groundRefIndex+1];
165
166 local particle = {mappings = {}};
167 table.insert(particle.mappings, mapping);
168 table.insert(self.groundParticles, particle);
169 end
170 i = i+1;
171 end;
172 end;
173
174 self.groundManipulationSpeedThreshold = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.groundManipulationSpeedThreshold#value"), 5);
175end;
176
177function WorkParticles:delete()
178 if self.isClient then
179 for _, animation in pairs(self.groundParticleAnimations) do
180 Utils.releaseSharedI3DFile(animation.filename, self.baseDirectory, true);
181 end;
182
183 for _, ps in pairs(self.groundParticles) do
184 for _, mapping in ipairs(ps.mappings) do
185 Utils.deleteParticleSystem(mapping.particles);
186 end;
187 end;
188 end;
189end;
190
191function WorkParticles:mouseEvent(posX, posY, isDown, isUp, button)
192end;
193
194function WorkParticles:keyEvent(unicode, sym, modifier, isDown)
195end;
196
197function WorkParticles:update(dt)
198end;
199
200function WorkParticles:updateTick(dt)
201 if self.isClient then
202 if self:getIsActive() then
203 for _, animation in pairs(self.groundParticleAnimations) do
204 for _, mapping in pairs(animation.mappings) do
205 local refNode = mapping.groundRefNode;
206 if refNode ~= nil and refNode.depthNode ~= nil then
207 local depth = Utils.clamp(refNode.depth / mapping.maxWorkDepth, 0, 1);
208 depth = Utils.clamp(math.min(depth, mapping.lastDepth + refNode.movingDirection*(refNode.movedDistance/0.5)), 0 ,1);
209 mapping.lastDepth = depth;
210 mapping.speed = mapping.speed - refNode.movedDistance*refNode.movingDirection;
211 setVisibility(mapping.animNode, depth ~= 0);
212 setShaderParameter(mapping.animNode, "VertxoffsetVertexdeformMotionUVscale", -6, depth, mapping.speed, 1.5, false);
213 end;
214 end;
215 end;
216
217 for _,ps in pairs(self.groundParticles) do
218 local enabled = self:getDoGroundManipulation();
219 for _, mapping in pairs(ps.mappings) do
220 local nodeEnabled = enabled;
221 if nodeEnabled then
222 nodeEnabled = mapping.groundRefNode.isActive;
223 end;
224 Utils.setEmittingState(mapping.particles, nodeEnabled);
225 end;
226 end;
227 end;
228 end;
229end;
230
231function WorkParticles:draw()
232end;
233
234function WorkParticles:onDeactivate()
235 if self.isClient then
236 for _,ps in pairs(self.groundParticles) do
237 for _, mapping in pairs(ps.mappings) do
238 Utils.setEmittingState(mapping.particles, false);
239 end;
240 end;
241 end;
242end;
243
244function WorkParticles:getDoGroundManipulation()
245 return self:getLastSpeed() > self.groundManipulationSpeedThreshold;
246end;
247
248function WorkParticles:loadGroundReferenceNodeFromXML(superFunc, groundReferenceNode, xmlFile, key)
249 groundReferenceNode.depthNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#depthNode"));
250 groundReferenceNode.movedDistance = 0;
251 groundReferenceNode.depth = 0;
252
253 if superFunc ~= nil then
254 return superFunc(self, groundReferenceNode, xmlFile, key);
255 end;
256 return true;
257end;
258
259function WorkParticles:updateGroundReferenceNode(groundReferenceNode, x, y, z, terrainHeight)
260 if self.isClient and groundReferenceNode.depthNode ~= nil then
261 local newX, newY, newZ = getWorldTranslation(groundReferenceNode.depthNode);
262 if groundReferenceNode.lastPosition == nil then
263 groundReferenceNode.lastPosition = {newX, newY, newZ};
264 end;
265 local dx, dy, dz = worldDirectionToLocal(groundReferenceNode.depthNode, newX-groundReferenceNode.lastPosition[1], newY-groundReferenceNode.lastPosition[2], newZ-groundReferenceNode.lastPosition[3]);
266 groundReferenceNode.movingDirection = 0;
267 if dz > 0.0001 then
268 groundReferenceNode.movingDirection = 1;
269 elseif dz < -0.0001 then
270 groundReferenceNode.movingDirection = -1;
271 end;
272 groundReferenceNode.movedDistance = Utils.vector3Length(dx, dy, dz);
273 groundReferenceNode.lastPosition = {newX, newY, newZ};
274 local terrainHeightDepthNode = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, newX, newY, newZ);
275 groundReferenceNode.depth = newY - terrainHeightDepthNode;
276 end;
277end;
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
Script Dokumentation Übersicht