Sprache Deutsch Language English

Script Dokumentation LS 2015 - Placeable (Patch 1.3)

Script Dokumentation Übersicht

scripts/placeables/Placeable.lua

Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
2
3Placeable = {};
4Placeable_mt = Class(Placeable, Object);
5
6InitStaticObjectClass(Placeable, "Placeable", ObjectIds.OBJECT_PLACEABLE);
7
8function Placeable:new(isServer, isClient, mt)
9 if mt == nil then
10 mt = Placeable_mt;
11 end;
12
13 local self = Object:new(isServer, isClient, mt);
14 self.nodeId = 0;
15
16 self.useRandomYRotation = false;
17 self.useManualYRotation = false;
18 self.placementSizeX = 1;
19 self.placementSizeZ = 1;
20 self.placementTestSizeX = 1;
21 self.placementTestSizeZ = 1;
22 self.pickObjects = {};
23 self.isolated = false;
24 self.isDeleted = false;
25 self.useMultiRootNode = false;
26
27 registerObjectClassName(self, "Placeable");
28 return self;
29end;
30
31function Placeable:delete()
32 self.isDeleted = true;
33 if self.i3dFilename ~= nil then
34 Utils.releaseSharedI3DFile(self.i3dFilename, nil, true);
35 end
36 unregisterObjectClassName(self);
37 g_currentMission:removeItemToSave(self);
38 g_currentMission:removePlaceable(self);
39 for _, node in pairs(self.pickObjects) do
40 g_currentMission:removeNodeObject(node);
41 end;
42 if self.nodeId ~= 0 and entityExists(self.nodeId) then
43 self:setCollisionMask(self.nodeId, 0);
44 setVisibility(self.nodeId, false);
45 else
46 self.nodeId = 0;
47 end;
48 g_currentMission:addPlaceableToDelete(self, 300);
49end;
50
51function Placeable:deleteFinal()
52 if self.nodeId ~= 0 then
53 delete(self.nodeId);
54 self.nodeId = 0;
55 end;
56end;
57
58function Placeable:setCollisionMask(nodeId, mask)
59 setCollisionMask(nodeId, mask);
60 local numChildren = getNumOfChildren(nodeId);
61 for i=0,numChildren-1 do
62 local childId = getChildAt(nodeId, i);
63 self:setCollisionMask(childId, mask)
64 end;
65end;
66
67function Placeable:getIsPlayerInRange(distance, player)
68 if self.nodeId ~= 0 then
69 distance = Utils.getNoNil(distance, 10);
70 if player == nil then
71 for _, player in pairs(g_currentMission.players) do
72 if self:isInActionDistance(player, self.nodeId, distance) then
73 return true, player;
74 end;
75 end;
76 else
77 return self:isInActionDistance(player, self.nodeId, distance), player;
78 end;
79 end
80 return false, nil;
81end;
82
83function Placeable:isInActionDistance(player, refNode, distance)
84 local x,y,z = getWorldTranslation(refNode);
85 local px,py,pz = getWorldTranslation(player.rootNode);
86 local dx,dz = px-x, pz-z;
87 if dx*dx + dz*dz < distance*distance then
88 return true;
89 end
90
91 return false;
92end;
93
94function Placeable:readStream(streamId, connection)
95 Placeable:superClass().readStream(self, streamId, connection);
96 if connection:getIsServer() then
97 local xmlFilename = Utils.convertFromNetworkFilename(streamReadString(streamId));
98 local x=streamReadFloat32(streamId);
99 local y=streamReadFloat32(streamId);
100 local z=streamReadFloat32(streamId);
101 local rx=Utils.readCompressedAngle(streamId);
102 local ry=Utils.readCompressedAngle(streamId);
103 local rz=Utils.readCompressedAngle(streamId);
104 self:load(xmlFilename, x,y,z, rx,ry,rz, false, false);
105 self:finalizePlacement();
106 end;
107end;
108
109function Placeable:writeStream(streamId, connection)
110 Placeable:superClass().writeStream(self, streamId, connection);
111 if not connection:getIsServer() then
112 streamWriteString(streamId, Utils.convertToNetworkFilename(self.xmlFilename));
113 local x,y,z = getTranslation(self.nodeId)
114 local x_rot,y_rot,z_rot = getRotation(self.nodeId);
115 streamWriteFloat32(streamId, x);
116 streamWriteFloat32(streamId, y);
117 streamWriteFloat32(streamId, z);
118 Utils.writeCompressedAngle(streamId, x_rot);
119 Utils.writeCompressedAngle(streamId, y_rot);
120 Utils.writeCompressedAngle(streamId, z_rot);
121 end;
122end;
123
124function Placeable:readUpdateStream(streamId, timestamp, connection)
125end;
126
127function Placeable:writeUpdateStream(streamId, connection, dirtyMask)
128end;
129
130function Placeable:createNode(i3dFilename)
131 self.i3dFilename = i3dFilename;
132 local nodeRoot = Utils.loadSharedI3DFile(i3dFilename, nil, false, false);
133 if nodeRoot == 0 then
134 return false;
135 end;
136
137 if self.useMultiRootNode then
138 link(getRootNode(), nodeRoot);
139 self.nodeId = nodeRoot;
140 else
141 local nodeId = getChildAt(nodeRoot, 0);
142 if nodeId == 0 then
143 delete(nodeRoot);
144 return false;
145 end
146 link(getRootNode(), nodeId);
147 delete(nodeRoot);
148 self.nodeId = nodeId;
149 end
150
151
152 return true;
153end;
154
155function Placeable:load(xmlFilename, x,y,z, rx,ry,rz, initRandom)
156 self.xmlFilename = xmlFilename;
157 self.customEnvironment, self.baseDirectory = Utils.getModNameAndBaseDirectory(xmlFilename);
158
159 local xmlFile = loadXMLFile("TempXML", xmlFilename);
160 if xmlFile == 0 then
161 return false;
162 end;
163 local i3dFilename = getXMLString(xmlFile, "placeable.filename");
164 self.placementSizeX = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.placement#sizeX"), self.placementSizeX);
165 self.placementSizeZ = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.placement#sizeZ"), self.placementSizeZ);
166 self.placementTestSizeX = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.placement#testSizeX"), self.placementSizeX);
167 self.placementTestSizeZ = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.placement#testSizeZ"), self.placementSizeZ);
168 self.useRandomYRotation = Utils.getNoNil(getXMLBool(xmlFile, "placeable.placement#useRandomYRotation"), self.useRandomYRotation);
169 self.useManualYRotation = Utils.getNoNil(getXMLBool(xmlFile, "placeable.placement#useManualYRotation"), self.useManualYRotation);
170 self.alignToWorldY = Utils.getNoNil(getXMLBool(xmlFile, "placeable.placement#alignToWorldY"), true);
171
172
173 if i3dFilename == nil then
174 delete(xmlFile);
175 return false;
176 end;
177 self.i3dFilename = Utils.getFilename(i3dFilename, self.baseDirectory);
178
179 if not self:createNode(self.i3dFilename) then
180 delete(xmlFile);
181 return false;
182 end;
183 self:initPose(x,y,z, rx,ry,rz, initRandom);
184
185 if not self.alignToWorldY then
186 self.pos1Node = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.placement#pos1Node"));
187 self.pos2Node = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.placement#pos2Node"));
188 self.pos3Node = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.placement#pos3Node"));
189 if self.pos1Node == nil or self.pos2Node == nil or self.pos3Node == nil then
190 self.alignToWorldY = true;
191 print("Warning: Pos1Node, Pos2Node and Pos3Node has to be set if alignToWorldY is false!");
192 end;
193 end;
194
195 delete(xmlFile);
196
197 return true;
198end;
199
200function Placeable:finalizePlacement()
201 if not self.isolated then
202 self:alignToTerrain()
203
204 addToPhysics(self.nodeId);
205 g_currentMission:addItemToSave(self);
206 g_currentMission:addPlaceable(self);
207
208 self:collectPickObjects(self.nodeId);
209
210 for _, node in pairs(self.pickObjects) do
211 g_currentMission:addNodeObject(node, self);
212 end;
213 end;
214end
215
216function Placeable:alignToTerrain()
217 if not self.alignToWorldY then
218 local x1,y1,z1 = getWorldTranslation(self.nodeId);
219 y1 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x1,y1,z1);
220 setTranslation(self.nodeId, x1,y1,z1);
221 local x2,y2,z2 = getWorldTranslation(self.pos1Node)
222 y2 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x2,y2,z2);
223 local x3,y3,z3 = getWorldTranslation(self.pos2Node)
224 y3 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x3,y3,z3);
225 local x4,y4,z4 = getWorldTranslation(self.pos3Node);
226 y4 = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x4,y4,z4);
227 local dirX = x2 - x1;
228 local dirY = y2 - y1;
229 local dirZ = z2 - z1;
230 local dir2X = x3 - x4;
231 local dir2Y = y3 - y4;
232 local dir2Z = z3 - z4;
233 local upX,upY,upZ = Utils.crossProduct(dir2X, dir2Y, dir2Z, dirX, dirY, dirZ);
234 setDirection(self.nodeId, dirX, dirY, dirZ, upX,upY,upZ);
235 end;
236end;
237
238function Placeable:initPose(x,y,z, rx,ry,rz, initRandom)
239 setTranslation(self.nodeId, x, y, z);
240 setRotation(self.nodeId, rx, ry, rz);
241end;
242
243function Placeable:collectPickObjects(node)
244 if getRigidBodyType(node) ~= "NoRigidBody" then
245 table.insert(self.pickObjects, node);
246 end;
247 local numChildren = getNumOfChildren(node);
248 for i=1, numChildren do
249 self:collectPickObjects(getChildAt(node, i-1));
250 end;
251end;
252
253function Placeable:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
254
255 local x,y,z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#position"));
256 local xRot,yRot,zRot = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rotation"));
257 if x == nil or y == nil or z == nil or xRot == nil or yRot == nil or zRot == nil then
258 return false;
259 end;
260 local xmlFilename = getXMLString(xmlFile, key.."#filename");
261 if xmlFilename == nil then
262 return false;
263 end;
264 xmlFilename = Utils.convertFromNetworkFilename(xmlFilename);
265
266 if self:load(xmlFilename, x,y,z, xRot, yRot, zRot, false, false) then
267 self:finalizePlacement();
268 return true;
269 else
270 return false;
271 end;
272end;
273
274function Placeable:getSaveAttributesAndNodes(nodeIdent)
275
276 local x,y,z = getTranslation(self.nodeId);
277 local xRot,yRot,zRot = getRotation(self.nodeId);
278 local attributes = 'filename="'.. Utils.encodeToHTML(Utils.convertToNetworkFilename(self.xmlFilename))..'" position="'..x..' '..y..' '..z..'" rotation="'..xRot..' '..yRot..' '..zRot..'"';
279 local nodes = "";
280 return attributes, nodes;
281end;
282
283function Placeable:getNeedsSaving()
284 return true;
285end;
286
287function Placeable:update(dt)
288end;
289
290function Placeable:updateTick(dt)
291end;
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