Sprache Deutsch Language English

Script Dokumentation LS 2015 - Steerable (Patch 1.3)

Script Dokumentation Übersicht

scripts/vehicles/specializations/Steerable.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-- Steerable
3-- Specialization class for steerables
4--
5-- @author Stefan Geiger
6-- @date 30/11/08
7--
8-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
9
10Steerable = {};
11source("dataS/scripts/vehicles/specializations/SteerableToggleLightEvent.lua");
12
13function Steerable.prerequisitesPresent(specializations)
14 return true; --SpecializationUtil.hasSpecialization(Attachable, specializations);
15end;
16
17function Steerable:load(xmlFile)
18
19 self.isSteerable = true;
20 self.isAttachable = SpecializationUtil.hasSpecialization(Attachable, self.specializations);
21
22 self.onEnter = SpecializationUtil.callSpecializationsFunction("onEnter");
23 self.onLeave = SpecializationUtil.callSpecializationsFunction("onLeave");
24 self.setLights = SpecializationUtil.callSpecializationsFunction("setLights");
25
26 self.addToolCameras = Steerable.addToolCameras;
27 self.removeToolCameras = Steerable.removeToolCameras;
28
29 self.setCharacterVisibility = Steerable.setCharacterVisibility;
30 self.drawUIInfo = Utils.overwrittenFunction(self.drawUIInfo, Steerable.drawUIInfo);
31 self.getIsActiveForInput = Utils.overwrittenFunction(self.getIsActiveForInput, Steerable.getIsActiveForInput);
32
33 self.isControlled = false;
34
35 Steerable.loadSettingsFromXML(self, xmlFile);
36
37 self.numCameras = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.cameras#count"), 0);
38 self.cameras = {};
39 for i=1, self.numCameras do
40 local cameraKey = string.format("vehicle.cameras.camera%d", i);
41 local camera = VehicleCamera:new(self);
42 if camera:loadFromXML(xmlFile, cameraKey) then
43 table.insert(self.cameras, camera);
44 end;
45 end;
46 self.numCameras = table.getn(self.cameras);
47 if self.numCameras == 0 then
48 print("Error: No cameras in xml file: ".. self.configFileName);
49 end;
50
51 self.camIndex = 1;
52
53 self.isEntered = false;
54
55 self.controllerName = "Unknown";
56
57 self.disableCharacterOnLeave = true;
58 self.deactivateOnLeave = true;
59
60 self.deactivateLightsOnLeave = true;
61
62 self.lightsState = 0;
63
64 self.numLightsStates = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.lights#numLightsStates"), self.numLightTypes);
65
66 self.showWaterWarning = false;
67 self.waterSplashSample = nil;
68
69 self.steerableGroundFlag = self:getNextDirtyFlag();
70end;
71
72function Steerable:loadSettingsFromXML(xmlFile)
73 self.enterReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.enterReferenceNode#index"));
74 self.exitPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.exitPoint#index"));
75
76 self.characterNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.characterNode#index"));
77 if self.characterNode ~= nil then
78 self.characterCameraMinDistance = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.characterNode#cameraMinDistance"), 1.5);
79 self.characterDistanceRefNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.characterNode#distanceRefNode"));
80 if self.characterDistanceRefNode == nil then
81 self.characterDistanceRefNode = self.characterNode;
82 end;
83 setVisibility(self.characterNode, false);
84
85 local skinBasenode = self.components;
86 local filename = getXMLString(xmlFile, "vehicle.characterNode#filename");
87 if filename ~= nil then
88 filename = Utils.getFilename(filename, self.baseDirectory);
89 local i3dNode = Utils.loadSharedI3DFile(filename);
90 if i3dNode ~= 0 then
91 self.characterSkin = Utils.indexToObject(i3dNode, getXMLString(xmlFile, "vehicle.characterNode#characterSkin"));
92 self.characterMesh = Utils.indexToObject(i3dNode, getXMLString(xmlFile, "vehicle.characterNode#characterMesh"));
93 self.characterGloves = Utils.indexToObject(i3dNode, getXMLString(xmlFile, "vehicle.characterNode#characterGloves"));
94 self.characterSpineNode = Utils.indexToObject(i3dNode, getXMLString(xmlFile, "vehicle.characterNode#spineNode"));
95 local x,y,z = Utils.getVectorFromString(Utils.getNoNil(getXMLString(xmlFile, "vehicle.characterNode#skinOffset"), "0 0.14 0"));
96 setClipDistance(self.characterMesh, 150);
97 setClipDistance(self.characterGloves, 50);
98 link(self.characterNode, self.characterSkin);
99 setTranslation(self.characterSkin, x,y,z);
100 link(self.characterNode, self.characterMesh);
101 if self.characterGloves ~= nil then
102 link(self.characterNode, self.characterGloves);
103 setVisibility(self.characterGloves, false);
104 end;
105 skinBasenode = self.characterNode;
106 delete(i3dNode);
107 end;
108 self.characterFilename = filename;
109 end;
110
111 local i = 0;
112 while true do
113 local key = string.format("vehicle.characterNode.ikChains.ikChain(%d)", i);
114 if not hasXMLProperty(xmlFile, key) then
115 break;
116 end;
117 local chain = IKUtil.loadIKChain(xmlFile, key, self.components, skinBasenode, self.ikChains, self.ikChainsById, self.getParentComponent, self);
118 if chain ~= nil then
119 self.characterIsSkinned = true;
120 end;
121 i = i + 1;
122 end;
123
124 self.characterLeftArmIKChainId = getXMLString(xmlFile, "vehicle.characterNode#leftArmIKChainId");
125 self.characterRightArmIKChainId = getXMLString(xmlFile, "vehicle.characterNode#rightArmIKChainId");
126 if self.characterSpineNode == nil then
127 self.characterSpineNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.characterNode#spineNode"));
128 end;
129 local rot = Utils.getRadiansFromString(getXMLString(xmlFile, "vehicle.characterNode#spineRotation"), 3);
130 if rot ~= nil and self.characterSpineNode ~= nil then
131 setRotation(self.characterSpineNode, unpack(rot));
132 end;
133 self.characterSpineSpeedDepended = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.characterNode#speedDependedSpine"), false);
134 self.characterSpineNodeMinRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.characterNode#spineNodeMinRot"), 10));
135 self.characterSpineNodeMaxRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.characterNode#spineNodeMaxRot"), -10));
136 self.characterSpineNodeMinAcc = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.characterNode#spineNodeMinAcc"), -1)/(1000*1000);
137 self.characterSpineNodeMaxAcc = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.characterNode#spineNodeMaxAcc"), 1)/(1000*1000);
138 self.characterSpineNodeAccDeadZone = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.characterNode#spineNodeAccDeadZone"), 0.2)/(1000*1000);
139 self.characterSpineLastRotation = 0;
140
141 self:setCharacterVisibility(false);
142 end;
143
144 self.nicknameRenderNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.nicknameRenderNode#index"));
145 self.nicknameRenderNodeOffset = Utils.getVectorNFromString(getXMLString(xmlFile, "vehicle.nicknameRenderNode#offset"), 3);
146 if self.nicknameRenderNode == nil then
147 if self.characterDistanceRefNode ~= nil then
148 self.nicknameRenderNode = self.characterDistanceRefNode;
149 if self.nicknameRenderNodeOffset == nil then
150 self.nicknameRenderNodeOffset = {0,1.5,0};
151 end;
152 else
153 self.nicknameRenderNode = self.components[1].node;
154 end;
155 end;
156 if self.nicknameRenderNodeOffset == nil then
157 self.nicknameRenderNodeOffset = {0,4,0};
158 end;
159
160 self.enterAnimation = getXMLString(xmlFile, "vehicle.enterAnimation#name");
161end;
162
163function Steerable:postLoad(xmlFile)
164 if self.steering ~= nil then
165 self.steeringSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.steering#rotationSpeed"), 0);
166 local indoorRotation = getXMLFloat(xmlFile, "vehicle.steering#indoorRotation");
167 if indoorRotation ~= nil then
168 self.steeringIndoorRotation = math.rad(indoorRotation);
169 end;
170 local outdoorRotation = getXMLFloat(xmlFile, "vehicle.steering#outdoorRotation");
171 if outdoorRotation ~= nil then
172 self.steeringOutdoorRotation = math.rad(outdoorRotation);
173 end;
174 _, self.steeringLastRotation, _ = getRotation(self.steering);
175 end;
176
177 if self.characterMesh ~= nil then
178 link(getRootNode(), self.characterMesh);
179 if self.characterGloves ~= nil then
180 link(getRootNode(), self.characterGloves);
181 end;
182 else
183 if self.characterNode ~= nil and self.characterIsSkinned then
184 link(getRootNode(), self.characterNode);
185 end;
186 end;
187end;
188
189function Steerable:delete()
190 if self.characterNode ~= nil then
191 if self.characterFilename ~= nil then
192 delete(self.characterMesh);
193 if self.characterGloves ~= nil then
194 delete(self.characterGloves);
195 end;
196 Utils.releaseSharedI3DFile(self.characterFilename, self.baseDirectory, true);
197 elseif self.characterIsSkinned then -- if character is skinned but not shared
198 delete(self.characterNode);
199 end;
200 end;
201
202 for _, camera in ipairs(self.cameras) do
203 camera:delete();
204 end;
205end;
206
207function Steerable:readStream(streamId, connection)
208 local isControlled = streamReadBool(streamId);
209 if isControlled then
210 self.controllerName = streamReadString(streamId);
211 self:onEnter(false);
212 end;
213end;
214
215function Steerable:writeStream(streamId, connection)
216 if streamWriteBool(streamId, self.isControlled) then
217 streamWriteString(streamId, self.controllerName);
218 end;
219end;
220
221function Steerable:readUpdateStream(streamId, timestamp, connection)
222end;
223
224function Steerable:writeUpdateStream(streamId, connection, dirtyMask)
225end;
226
227function Steerable:getXMLStatsAttributes()
228 if self.isControlled and self.controllerName ~= nil then
229 return string.format('controller="%s"', Utils.encodeToHTML(tostring(self.controllerName)));
230 end
231 return nil;
232end
233
234function Steerable:mouseEvent(posX, posY, isDown, isUp, button)
235 self.cameras[self.camIndex]:mouseEvent(posX, posY, isDown, isUp, button);
236end;
237
238function Steerable:keyEvent(unicode, sym, modifier, isDown)
239end;
240
241function Steerable:update(dt)
242 if self:getIsActive() then
243 if self.isClient then
244 if self.steering ~= nil then
245 local rotTime = self.rotatedTime;
246 local baseRotation = self.steeringSpeed;
247
248 if g_currentMission.controlledVehicle ~= self or not self.cameras[self.camIndex].isInside then
249 baseRotation = Utils.getNoNil(self.steeringOutdoorRotation, self.steeringSpeed);
250 else
251 baseRotation = Utils.getNoNil(self.steeringIndoorRotation, self.steeringSpeed);
252 end;
253
254 if self.steeringOutdoorRotation ~= nil or self.steeringIndoorRotation ~= nil then
255 if self.rotatedTime > 0 then
256 rotTime = self.rotatedTime/math.abs(self.maxRotTime);
257 else
258 rotTime = self.rotatedTime/math.abs(self.minRotTime);
259 end;
260 end;
261
262 local rotation = baseRotation * rotTime;
263
264 if self.steeringLastRotation ~= rotation then
265 self.steeringLastRotation = rotation;
266 setRotation(self.steering, 0, rotation, 0);
267
268 if self.characterLeftArmIKChainId ~= nil then
269 IKUtil.setIKChainDirty(self.ikChainsById, self.characterLeftArmIKChainId);
270 end;
271 if self.characterRightArmIKChainId ~= nil then
272 IKUtil.setIKChainDirty(self.ikChainsById, self.characterRightArmIKChainId);
273 end;
274 end;
275 end;
276
277 if self.isEntered then
278 if self.characterSpineNode ~= nil and self.characterSpineSpeedDepended then
279 local acc = 0;
280 if math.abs(self.lastSpeedAcceleration) > self.characterSpineNodeAccDeadZone then
281 acc = self.lastSpeedAcceleration;
282 end;
283 local alpha = Utils.clamp((acc - self.characterSpineNodeMinAcc)/(self.characterSpineNodeMaxAcc - self.characterSpineNodeMinAcc), 0, 1);
284 local rotation = Utils.lerp(self.characterSpineNodeMinRot, self.characterSpineNodeMaxRot, alpha);
285 if rotation ~= self.characterSpineLastRotation then
286 self.characterSpineLastRotation = self.characterSpineLastRotation * 0.95 + rotation * 0.05;
287
288 setRotation(self.characterSpineNode, self.characterSpineLastRotation, 0, 0);
289
290 if self.characterLeftArmIKChainId ~= nil then
291 IKUtil.setIKChainDirty(self.ikChainsById, self.characterLeftArmIKChainId);
292 end;
293 if self.characterRightArmIKChainId ~= nil then
294 IKUtil.setIKChainDirty(self.ikChainsById, self.characterRightArmIKChainId);
295 end;
296 end;
297 end;
298 end;
299 end;
300 end;
301
302 if self.isEntered and self.isClient then
303 if not g_currentMission.hasSpecialCamera then
304 setCamera(self.cameras[self.camIndex].cameraNode);
305 end;
306 self.cameras[self.camIndex]:update(dt);
307
308 -- do all the input handling
309 local activeForInput = true;
310 if g_gui.currentGui ~= nil or g_currentMission.isPlayerFrozen then
311 activeForInput = false;
312 end;
313
314 if activeForInput then --self:getIsActiveForInput(false) then
315
316 if InputBinding.hasEvent(InputBinding.CAMERA_SWITCH) then
317 self.cameras[self.camIndex]:onDeactivate();
318 self.camIndex = self.camIndex + 1;
319 if self.camIndex > self.numCameras then
320 self.camIndex = 1;
321 end;
322 self.cameras[self.camIndex]:onActivate();
323 if self.setMirrorVisible ~= nil and self.mirrorAvailable == true then
324 if self.cameras[self.camIndex].useMirror then
325 self:setMirrorVisible(true);
326 else
327 self:setMirrorVisible(false);
328 end;
329 end;
330 end;
331
332 -- camera zoom is handled here, otherwise the controls are laggy or don't work at all
333 if self.cameras[self.camIndex].allowTranslation then
334 if InputBinding.isPressed(InputBinding.CAMERA_ZOOM_IN) then
335 if InputBinding.getInputTypeOfDigitalAction(InputBinding.CAMERA_ZOOM_IN) == InputBinding.INPUTTYPE_MOUSE_WHEEL then
336 self.cameras[self.camIndex]:zoomSmoothly(-0.6);
337 else
338 self.cameras[self.camIndex]:zoomSmoothly(-0.005*dt);
339 end;
340 elseif InputBinding.isPressed(InputBinding.CAMERA_ZOOM_OUT) then
341 if InputBinding.getInputTypeOfDigitalAction(InputBinding.CAMERA_ZOOM_OUT) == InputBinding.INPUTTYPE_MOUSE_WHEEL then
342 self.cameras[self.camIndex]:zoomSmoothly(0.6);
343 else
344 self.cameras[self.camIndex]:zoomSmoothly(0.005*dt);
345 end;
346 end;
347 end;
348
349 if self:canToggleLight() then
350
351 if self.numLightTypes >= 1 and InputBinding.hasEvent(InputBinding.TOGGLE_LIGHT_FRONT) then
352 playSample(g_currentMission.toggleLightsSound, 1, 1.0, 0);
353 local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^0);
354 self:setLightsTypesMask(lightsTypesMask);
355 elseif InputBinding.hasEvent(InputBinding.TOGGLE_LIGHTS) then
356 Steerable.setNextLightsState(self);
357 end;
358
359 if self.numLightTypes >= 2 then
360 -- work light back has light type 1
361 if InputBinding.hasEvent(InputBinding.TOGGLE_WORK_LIGHT_BACK) then
362 playSample(g_currentMission.toggleLightsSound, 1, 1.0, 0);
363 local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^1);
364 self:setLightsTypesMask(lightsTypesMask);
365 end
366
367 if self.numLightTypes >= 3 then
368 -- work light front has light type 2
369 if InputBinding.hasEvent(InputBinding.TOGGLE_WORK_LIGHT_FRONT) then
370 playSample(g_currentMission.toggleLightsSound, 1, 1.0, 0);
371 local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^2);
372 self:setLightsTypesMask(lightsTypesMask);
373 end
374
375 if self.numLightTypes >= 4 then
376 -- work light has light type 3
377 if InputBinding.hasEvent(InputBinding.TOGGLE_HIGH_BEAM_LIGHT) then
378 playSample(g_currentMission.toggleLightsSound, 1, 1.0, 0);
379 local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^3);
380 self:setLightsTypesMask(lightsTypesMask);
381 end
382 end
383 end
384 end
385
386 end;
387
388 end;
389
390 -- update character visiblity
391 if self.characterNode ~= nil then
392 local cx, cy, cz = getWorldTranslation(self.characterDistanceRefNode);
393 local x,y,z = getWorldTranslation(getCamera());
394 local dist = Utils.vector3Length(cx-x, cy-y, cz-z);
395 local visible = dist >= self.characterCameraMinDistance;
396 self:setCharacterVisibility(visible);
397 end;
398 end;
399end;
400
401function Steerable:updateTick(dt)
402end;
403
404function Steerable:draw()
405 if not self.isEntered then
406 return;
407 end;
408
409 -- new in console version: show common commands (toggle lights, honk, etc) in button help
410 if GS_IS_CONSOLE_VERSION then
411 g_currentMission:addHelpButtonText(g_i18n:getText("ExitVehicle"), InputBinding.ENTER);
412 end;
413
414 if self:canToggleLight() and not self.isAttachable then
415 if g_currentMission.environment.currentHour > 20 or g_currentMission.environment.currentHour < 7 then
416 g_currentMission:addHelpButtonText(g_i18n:getText("TOGGLE_LIGHTS"), InputBinding.TOGGLE_LIGHTS);
417 end;
418 end;
419end;
420
421function Steerable:drawUIInfo(superFunc)
422 if superFunc ~= nil then
423 superFunc(self);
424 end;
425
426 if not self.isEntered and self.isClient and self:getIsActive() and self.isControlled and g_gui.currentGui == nil and g_currentMission.showHudEnv then
427 local x,y,z = getWorldTranslation(self.nicknameRenderNode);
428 local x1,y1,z1 = getWorldTranslation(getCamera())
429 local distSq = Utils.vector3LengthSq(x-x1,y-y1,z-z1);
430 if distSq <= 100*100 then
431 x = x + self.nicknameRenderNodeOffset[1];
432 y = y + self.nicknameRenderNodeOffset[2];
433 z = z + self.nicknameRenderNodeOffset[3];
434 local sx,sy,sz = project(x,y,z);
435 if sz <= 1 then
436 setTextAlignment(RenderText.ALIGN_CENTER);
437 setTextBold(false);
438 setTextColor(0.0, 0.0, 0.0, 0.75);
439 renderText(sx, sy-0.0015, getCorrectTextSize(0.02), self.controllerName);
440
441 setTextColor(0.5, 1.0, 0.5, 1.0);
442 renderText(sx, sy, getCorrectTextSize(0.02), self.controllerName);
443
444 setTextAlignment(RenderText.ALIGN_LEFT);
445 end;
446 end;
447 end;
448end;
449
450function Steerable:onEnter(isControlling)
451 self.isControlled = true;
452 if isControlling then
453 self.isEntered = true;
454
455 self.camIndex = 1;
456 self.cameras[self.camIndex]:onActivate();
457 end;
458
459 for _, chain in pairs(self.ikChains) do
460 IKUtil.setIKChainDirty(self.ikChainsById, chain.id);
461 end;
462
463 self:setCharacterVisibility(true);
464
465 if self.enterAnimation ~= nil and self.playAnimation ~= nil then
466 self:playAnimation(self.enterAnimation, 1, nil, true);
467 end;
468
469 g_currentMission.controlledVehicles[self] = self;
470end;
471
472function Steerable:onLeave()
473 self.isControlled = false;
474 self.cameras[self.camIndex]:onDeactivate();
475
476 self:setCharacterVisibility(not self.disableCharacterOnLeave);
477
478 if self.deactivateOnLeave then
479 self:onDeactivate();
480 if self.enterAnimation ~= nil and self.playAnimation ~= nil then
481 self:playAnimation(self.enterAnimation, -1, nil, true);
482 end;
483 else
484 self:onDeactivateSounds();
485 self:onDeactivateLights();
486 end;
487
488 self.isEntered = false;
489 g_currentMission.controlledVehicles[self] = nil;
490end;
491
492function Steerable:setCharacterVisibility(isVisible)
493 if self.characterNode ~= nil then
494 setVisibility(self.characterNode, isVisible);
495 if self.characterMesh ~= nil then
496 setVisibility(self.characterMesh, isVisible);
497 end;
498 end;
499end;
500
501function Steerable:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
502 return BaseMission.VEHICLE_LOAD_OK;
503end;
504
505function Steerable:getSaveAttributesAndNodes(nodeIdent)
506 local attributes = "";
507 local nodes = "";
508 return attributes, nodes;
509end;
510
511function Steerable:setLightsTypesMask(lightsTypesMask)
512 self.lightsState = 0;
513end
514
515function Steerable.setNextLightsState(self)
516 -- loop through light types and keep first light enabled
517
518 if self.numLightsStates > 0 then
519 playSample(g_currentMission.toggleLightsSound, 1, 1.0, 0);
520 local lightsState = self.lightsState + 1;
521 if lightsState > self.numLightsStates or (self.lightsState == 0 and self.lightsTypesMask > 0) then
522 lightsState = 0;
523 end
524
525 local lightsTypesMask = 0;
526 if lightsState > 0 then
527 lightsTypesMask = bitOR(1, 2^(lightsState-1));
528 end
529
530 if self.isAttachable and lightsState > 0 then
531 lightsState = math.max(lightsState, 2);
532 local stdLights = 0;
533 if self.attacherVehicle ~= nil then
534 stdLights = bitAND(self.attacherVehicle.lightsTypesMask, 1);
535 end;
536 lightsTypesMask = bitOR(stdLights, 2^(lightsState-1));
537 end;
538
539 self:setLightsTypesMask(lightsTypesMask);
540 self.lightsState = lightsState;
541 end
542end
543
544function Steerable:getIsActiveForInput(superFunc, onlyTrueIfSelected)
545 if not self.isAttachable then
546 return superFunc(self, onlyTrueIfSelected);
547 else
548 if g_gui.currentGui ~= nil or g_currentMission.isPlayerFrozen then
549 return false;
550 end;
551 if self.isEntered then
552 if self.attacherVehicle ~= nil then
553 return true;
554 else
555 return false;
556 end;
557 end;
558 return false;
559 end;
560end;
561
562function Steerable:addToolCameras(cameras)
563 for i,toolCamera in pairs(cameras) do
564 table.insert(self.cameras, toolCamera);
565 end;
566 self.numCameras = #self.cameras;
567end;
568
569function Steerable:removeToolCameras(cameras)
570 self.cameras[self.camIndex]:onDeactivate();
571 for i,toolCamera in pairs(cameras) do
572 for j,camera in pairs(self.cameras) do
573 if toolCamera == camera then
574 table.remove(self.cameras, j);
575 break;
576 end;
577 end;
578 end;
579 self.numCameras = #self.cameras;
580 if self.camIndex > self.numCameras then
581 self.camIndex = 1;
582 end;
583 self.cameras[self.camIndex]:onActivate();
584end;
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