Sprache Deutsch Language English

Script Dokumentation LS 2015 - HighPressureWasherPlaceable (Patch 1.3)

Script Dokumentation Übersicht

scripts/placeables/HighPressureWasherPlaceable.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
3HighPressureWasher = {};
4HighPressureWasher_mt = Class(HighPressureWasher, Placeable);
5
6InitStaticObjectClass(HighPressureWasher, "HighPressureWasher", ObjectIds.OBJECT_HIGHPRESSURE_WASHER_PLACEABLE);
7
8function HighPressureWasher:new(isServer, isClient, customMt)
9 local mt = customMt;
10 if mt == nil then
11 mt = HighPressureWasher_mt;
12 end;
13
14 local self = Placeable:new(isServer, isClient, mt);
15 registerObjectClassName(self, "HighPressureWasher");
16
17 self.messageShown = false;
18
19 return self;
20end;
21
22function HighPressureWasher:load(xmlFilename, x,y,z, rx,ry,rz, initRandom)
23 if not HighPressureWasher:superClass().load(self, xmlFilename, x,y,z, rx,ry,rz, initRandom) then
24 return false;
25 end;
26
27 local xmlFile = loadXMLFile("TempXML", xmlFilename);
28
29 self.playerInRangeDistance = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.playerInRangeDistance"), 3);
30
31 self.washDistance = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.washDistance"), 10);
32 self.actionRadius = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.actionRadius#distance"), 15);
33 self.washMultiplier = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.washMultiplier"), 1);
34 self.pricePerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.pricePerMinute"), 10) / 1000;
35 self.lanceNode = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.lance#index"));
36 self.linkPosition = Utils.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "placeable.lance#position"), "0 0 0"), 3);
37 self.linkRotation = Utils.getRadiansFromString(Utils.getNoNil(getXMLString(xmlFile, "placeable.lance#rotation"), "0 0 0"), 3);
38 self.lanceNodeParent = getParent(self.lanceNode);
39
40 self.lanceRaycastNode = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.lance#raycastNode"));
41
42 if self.isClient then
43 self.particleSystems = {};
44 Utils.loadParticleSystem(xmlFile, self.particleSystems, "placeable.particleSystem", self.nodeId, false, nil, g_currentMission.baseDirectory, nil);
45
46 self.waterEffect = EffectManager:loadEffect(xmlFile, "placeable.waterEffect", self.nodeId, self);
47
48 self.sampleCompressor = Utils.loadSample(xmlFile, {}, "placeable.compressorSound", nil, self.baseDirectory, self.nodeId);
49 self.compressorPitchMin = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.compressorSound#pitchMin"), 0.5);
50 self.sampleWashing = Utils.loadSample(xmlFile, {}, "placeable.washingSound", nil, self.baseDirectory);
51 self.sampleSwitch = Utils.loadSample(xmlFile, {}, "placeable.switchSound", nil, self.baseDirectory);
52
53 local filename = getXMLString(xmlFile, "placeable.exhaust#filename");
54 if filename ~= nil then
55 local i3dNode = Utils.loadSharedI3DFile(filename, self.baseDirectory, false, false, false);
56 if i3dNode ~= 0 then
57 local linkNode = Utils.getNoNil(Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.exhaust#index")), self.nodeId);
58 self.exhaustFilename = filename;
59 self.exhaustNode = getChildAt(i3dNode, 0);
60 link(linkNode, self.exhaustNode);
61 setVisibility(self.exhaustNode, false);
62 delete(i3dNode);
63 end;
64 end;
65
66 self.targets = {};
67 HandTool.loadTargets(xmlFile, "placeable", self.nodeId, self.targets);
68 end;
69
70 delete(xmlFile);
71
72 self.isPlayerInRange = false;
73 self.isTurnedOn = false;
74 self.activatable = HighPressureWasherActivatable:new(self);
75 self.doWashing = false;
76 self.lastInRangePosition = {0,0,0};
77 self.isTurningOff = false;
78 self.turnOffTime = 0;
79 self.turnOffDuration = 500;
80
81 return true;
82end;
83
84function HighPressureWasher:delete()
85 self:setIsTurnedOn(false, nil, false);
86 if self.isClient then
87 EffectManager:deleteEffect(self.waterEffect);
88 if self.exhaustFilename ~= nil then
89 Utils.releaseSharedI3DFile(self.exhaustFilename, self.baseDirectory, true);
90 end;
91 if self.particleSystems ~= nil then
92 Utils.deleteParticleSystem(self.particleSystems);
93 end;
94 if self.sampleCompressor ~= nil then
95 Utils.deleteSample(self.sampleCompressor);
96 end;
97 if self.sampleWashing ~= nil then
98 Utils.deleteSample(self.sampleWashing);
99 end;
100 if self.sampleSwitch ~= nil then
101 Utils.deleteSample(self.sampleSwitch);
102 end;
103 end;
104
105 unregisterObjectClassName(self);
106 g_currentMission:removeActivatableObject(self.activatable);
107 HighPressureWasher:superClass().delete(self);
108end;
109
110function HighPressureWasher:readStream(streamId, connection)
111 HighPressureWasher:superClass().readStream(self, streamId, connection);
112 if connection:getIsServer() then
113 local isTurnedOn = streamReadBool(streamId);
114 if isTurnedOn then
115 local player = networkGetObject(streamReadInt32(streamId));
116 if player ~= nil then
117 self:setIsTurnedOn(isTurnedOn, player, true);
118 end;
119 end;
120 end;
121end;
122
123function HighPressureWasher:writeStream(streamId, connection)
124 HighPressureWasher:superClass().writeStream(self, streamId, connection);
125 if not connection:getIsServer() then
126 streamWriteBool(streamId, self.isTurnedOn);
127 if self.isTurnedOn then
128 streamWriteInt32(streamId, networkGetObjectId(self.currentPlayer));
129 end;
130 end;
131end;
132
133function HighPressureWasher:activateHandtool(player)
134 self:setIsTurnedOn(true, player, true);
135end;
136
137function HighPressureWasher:update(dt)
138 HighPressureWasher:superClass().update(self, dt);
139
140 if self.currentPlayer ~= nil then
141 local isPlayerInRange = self:getIsPlayerInRange(self.actionRadius, self.currentPlayer);
142 if isPlayerInRange then
143 self.lastInRangePosition = {getTranslation(self.currentPlayer.rootNode)};
144 else
145 local kx, _, kz = getWorldTranslation(self.nodeId);
146 local px, _, pz = getWorldTranslation(self.currentPlayer.rootNode);
147 local len = Utils.vector2Length(px-kx, pz-kz);
148
149 local x,y,z = unpack(self.lastInRangePosition);
150 x = kx + ((px-kx) / len) * (self.actionRadius-0.00001*dt);
151 z = kz + ((pz-kz) / len) * (self.actionRadius-0.00001*dt);
152 y = math.max(y, getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 0, z));
153 self.currentPlayer:moveToAbsoluteInternal(x, y, z);
154 self.lastInRangePosition = {x,y,z};
155
156 if not self.messageShown and self.currentPlayer == g_currentMission.player then
157 g_currentMission:showBlinkingWarning(g_i18n:getText("HighPressureWasherRangeRestriction"), 6000);
158 self.messageShown = true;
159 end;
160 end;
161 end;
162
163 if self.isServer then
164 if self.isTurnedOn and self.doWashing then
165 self.foundVehicle = nil;
166 self:cleanVehicle(self.currentPlayer.cameraId, dt);
167 if self.lanceRaycastNode ~= nil then
168 self:cleanVehicle(self.lanceRaycastNode, dt);
169 end;
170
171 local price = self.pricePerSecond * (dt / 1000);
172 g_currentMission.missionStats:updateStats("expenses", price);
173 g_currentMission:addSharedMoney(-price, "vehicleRunningCost");
174 end;
175 end;
176
177 if self.isTurningOff then
178 if g_currentMission.time < self.turnOffTime then
179 if self.sampleCompressor ~= nil then
180 local pitch = Utils.lerp(self.compressorPitchMin, self.sampleCompressor.pitchOffset, Utils.clamp((self.turnOffTime - g_currentMission.time) / self.turnOffDuration, 0, 1));
181 local volume = Utils.lerp(0, self.sampleCompressor.volume, Utils.clamp((self.turnOffTime - g_currentMission.time) / self.turnOffDuration, 0, 1));
182 Utils.setSamplePitch(self.sampleCompressor, pitch);
183 Utils.setSampleVolume(self.sampleCompressor, volume);
184 end;
185 else
186 self.isTurningOff = false;
187 if self.sampleCompressor ~= nil then
188 Utils.stop3DSample(self.sampleCompressor);
189 end;
190 end;
191 end;
192end;
193
194function HighPressureWasher:cleanVehicle(node, dt)
195 local x,y,z = getWorldTranslation(node);
196 local dx, dy, dz = localDirectionToWorld(node, 0, 0, -1);
197 local lastFoundVehicle = self.foundVehicle;
198 --drawDebugLine(x, y, z, 1, 0, 0, x+dx*2, y+dy*2,z+dz*2, 0,0,1);
199 raycastAll(x, y, z, dx, dy, dz, "washRaycastCallback", self.washDistance, self, 32+64+128+256+4096+8194);
200
201 if self.foundVehicle ~= nil and lastFoundVehicle ~= self.foundVehicle then
202 --drawDebugPoint(self.foundCoords[1], self.foundCoords[2], self.foundCoords[3], 1,1,1,1);
203 self.foundVehicle:setDirtAmount(self.foundVehicle:getDirtAmount() - self.washMultiplier*dt/self.foundVehicle.washDuration);
204 end;
205end;
206
207function HighPressureWasher:updateTick(dt)
208 HighPressureWasher:superClass().updateTick(self, dt);
209 local isPlayerInRange, player = self:getIsPlayerInRange(self.playerInRangeDistance);
210 if isPlayerInRange then
211 self.playerInRange = player;
212 self.isPlayerInRange = true;
213 g_currentMission:addActivatableObject(self.activatable);
214 else
215 self.playerInRange = nil;
216 self.isPlayerInRange = false;
217 g_currentMission:removeActivatableObject(self.activatable);
218 end;
219end;
220
221function HighPressureWasher:setIsWashing(doWashing, force, noEventSend)
222 HPWPlaceableStateEvent.sendEvent(self, doWashing, noEventSend);
223 if self.doWashing ~= doWashing then
224 if self.isClient then
225 Utils.setEmittingState(self.particleSystems, doWashing and self:getIsActiveForInput());
226 if doWashing then
227 EffectManager:startEffect(self.waterEffect)
228 if self.sampleWashing ~= nil and self.currentPlayer == g_currentMission.player then
229 if self:getIsActiveForSound() then
230 Utils.playSample(self.sampleWashing, 0, 0, 1);
231 end;
232 end;
233 else
234 if force then
235 EffectManager:resetEffect(self.waterEffect);
236 else
237 EffectManager:stopEffect(self.waterEffect);
238 end;
239 if self.sampleWashing ~= nil then
240 Utils.stopSample(self.sampleWashing, true);
241 end;
242 end;
243 end;
244 self.doWashing = doWashing;
245 end;
246end;
247
248function HighPressureWasher:setIsTurnedOn(isTurnedOn, player, noEventSend)
249 HPWPlaceableTurnOnEvent.sendEvent(self, isTurnedOn, player, noEventSend);
250
251 if self.isTurnedOn ~= isTurnedOn then
252 if isTurnedOn then
253 self.isTurnedOn = isTurnedOn;
254 self.currentPlayer = player;
255
256 -- player stuff
257 local tool = {};
258 tool.node = self.lanceNode;
259 link(player.toolsRootNode, tool.node);
260 setVisibility(tool.node, false);
261 setTranslation(tool.node, unpack(self.linkPosition));
262 setRotation(tool.node, unpack(self.linkRotation));
263 tool.update = HighPressureWasher.updateLance;
264 tool.updateTick = HighPressureWasher.updateTickLance;
265 tool.delete = HighPressureWasher.deleteLance;
266 tool.draw = HighPressureWasher.drawLance;
267 tool.onActivate = HighPressureWasher.activateLance;
268 tool.onDeactivate = HighPressureWasher.deactivateLance;
269 tool.targets = self.targets;
270 tool.owner = self;
271 tool.static = false;
272 self.tool = tool;
273 self.currentPlayer:setTool(tool);
274 self.currentPlayer.hasHPWLance = true;
275
276 if self.isClient then
277 if self.sampleSwitch ~= nil and self:getIsActiveForSound() then
278 Utils.playSample(self.sampleSwitch, 1, 0, nil);
279 end;
280 if self.sampleCompressor ~= nil then
281 Utils.setSamplePitch(self.sampleCompressor, self.sampleCompressor.pitchOffset);
282 Utils.setSampleVolume(self.sampleCompressor, self.sampleCompressor.volume);
283 Utils.play3DSample(self.sampleCompressor);
284 end;
285 if self.isTurningOff then
286 self.isTurningOff = false;
287 end;
288 setVisibility(self.lanceNode, g_currentMission.player == player);
289 end;
290 else
291 self:onDeactivate();
292 end;
293 if self.exhaustNode ~= nil then
294 setVisibility(self.exhaustNode, isTurnedOn);
295 end;
296 end;
297end;
298
299function HighPressureWasher:onDeactivate()
300 if self.isClient then
301 if self.sampleSwitch ~= nil and self:getIsActiveForSound() then
302 Utils.playSample(self.sampleSwitch, 1, 0, nil);
303 end;
304 end;
305 self.isTurnedOn = false;
306 setVisibility(self.lanceNode, true);
307 self:setIsWashing(false, true, true);
308 if self.currentPlayer ~= nil then
309 self.currentPlayer:setToolById(0, true);
310 self.currentPlayer.hasHPWLance = false;
311 end;
312 if self.isClient then
313 if self.sampleWashing ~= nil then
314 Utils.stopSample(self.sampleWashing, true);
315 end;
316 self.isTurningOff = true;
317 self.turnOffTime = g_currentMission.time + self.turnOffDuration;
318 link(self.lanceNodeParent, self.lanceNode);
319 setTranslation(self.lanceNode, 0,0,0);
320 setRotation(self.lanceNode, 0,0,0);
321 end;
322 self.currentPlayer = nil;
323end;
324
325function HighPressureWasher:getIsActiveForInput()
326 if self.isTurnedOn and self.currentPlayer == g_currentMission.player and g_gui.currentGui == nil then
327 return true;
328 end;
329 return false;
330end;
331
332function HighPressureWasher:getIsActiveForSound()
333 return self:getIsActiveForInput();
334end;
335
336function HighPressureWasher:washRaycastCallback(hitObjectId, x, y, z, distance)
337 local vehicle = g_currentMission.nodeToVehicle[hitObjectId];
338 if vehicle ~= nil and vehicle.getDirtAmount ~= nil and vehicle.setDirtAmount ~= nil and vehicle.washDuration ~= nil then
339 self.foundCoords = {x,y,z};
340 self.foundVehicle = vehicle;
341 return false;
342 end;
343
344 return true;
345end;
346
347function HighPressureWasher.activateLance(tool)
348 setVisibility(tool.node, true);
349end
350
351function HighPressureWasher.deactivateLance(tool)
352 tool.owner:setIsTurnedOn(false, nil);
353end
354
355function HighPressureWasher.deleteLance(tool)
356 tool.owner:setIsTurnedOn(false, nil);
357end
358
359function HighPressureWasher.drawLance(tool)
360 if tool.owner.currentPlayer == g_currentMission.player then
361 g_currentMission:addHelpButtonText(g_i18n:getText("ACTIVATE_HANDTOOL"), InputBinding.ACTIVATE_HANDTOOL);
362 end;
363end
364
365function HighPressureWasher.updateLance(tool, dt, allowInput)
366 if allowInput then
367 tool.owner:setIsWashing(InputBinding.isPressed(InputBinding.ACTIVATE_HANDTOOL), false, false);
368 end;
369end;
370
371function HighPressureWasher.updateTickLance(tool, dt, allowInput)
372end;
373
374HighPressureWasherActivatable = {}
375local HighPressureWasherActivatable_mt = Class(HighPressureWasherActivatable);
376
377function HighPressureWasherActivatable:new(highPressureWasher)
378 local self = {};
379 setmetatable(self, HighPressureWasherActivatable_mt);
380
381 self.highPressureWasher = highPressureWasher;
382 self.activateText = "unknown";
383
384 return self;
385end;
386
387function HighPressureWasherActivatable:getIsActivatable()
388 if not self.highPressureWasher.isPlayerInRange then
389 return false;
390 end;
391
392 if self.highPressureWasher.playerInRange ~= g_currentMission.player then
393 return false;
394 end;
395
396 if not self.highPressureWasher.playerInRange.isControlled then
397 return false;
398 end;
399
400 if self.highPressureWasher.isTurnedOn and self.highPressureWasher.currentPlayer ~= g_currentMission.player then
401 return false;
402 end;
403
404 if not self.highPressureWasher.isTurnedOn and g_currentMission.player.hasHPWLance == true then
405 return false;
406 end;
407
408 if self.highPressureWasher.isDeleted then
409 return false;
410 end;
411
412 self:updateActivateText();
413 return true;
414end;
415
416function HighPressureWasherActivatable:onActivateObject()
417 self.highPressureWasher:setIsTurnedOn(not self.highPressureWasher.isTurnedOn, g_currentMission.player);
418 self:updateActivateText();
419 g_currentMission:addActivatableObject(self);
420end;
421
422function HighPressureWasherActivatable:drawActivate()
423end;
424
425function HighPressureWasherActivatable:updateActivateText()
426 if self.highPressureWasher.isTurnedOn then
427 self.activateText = string.format(g_i18n:getText("turn_off_OBJECT"), g_i18n:getText("TypeDesc_HighPressureWasher"));
428 else
429 self.activateText = string.format(g_i18n:getText("turn_on_OBJECT"), g_i18n:getText("TypeDesc_HighPressureWasher"));
430 end;
431end;
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