LUADOC - Farming Simulator 17

Printable Version

HighPressureWasherPlaceable

Functions

new

Description
Creating placeable high pressure washer
Definition
new(boolean isServer, boolean isClient, table customMt)
Arguments
booleanisServeris server
booleanisClientis client
tablecustomMtcustom metatable
Return Values
tableinstanceInstance of object
Code
18function HighPressureWasher:new(isServer, isClient, customMt)
19 local mt = customMt;
20 if mt == nil then
21 mt = HighPressureWasher_mt;
22 end;
23
24 local self = Placeable:new(isServer, isClient, mt);
25 registerObjectClassName(self, "HighPressureWasher");
26
27 self.messageShown = false;
28
29 return self;
30end;

load

Description
Load high pressure washer
Definition
load(string xmlFilename, float x, float y, float z, float rx, float ry, float rz, boolean initRandom)
Arguments
stringxmlFilenamexml file name
floatxx world position
floatyz world position
floatzz world position
floatrxrx world rotation
floatryry world rotation
floatrzrz world rotation
booleaninitRandominitialize random
Return Values
booleansuccesssuccess
Code
43function HighPressureWasher:load(xmlFilename, x,y,z, rx,ry,rz, initRandom)
44 if not HighPressureWasher:superClass().load(self, xmlFilename, x,y,z, rx,ry,rz, initRandom) then
45 return false;
46 end;
47
48 local xmlFile = loadXMLFile("TempXML", xmlFilename);
49
50 self.playerInRangeDistance = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.highPressureWasher.playerInRangeDistance"), 3);
51
52 self.washDistance = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.highPressureWasher.washDistance"), 10);
53 self.actionRadius = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.highPressureWasher.actionRadius#distance"), 15);
54 self.washMultiplier = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.highPressureWasher.washMultiplier"), 1);
55 self.pricePerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.highPressureWasher.pricePerMinute"), 10) / 1000;
56 self.lanceNode = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.highPressureWasher.lance#index"));
57 self.linkPosition = Utils.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "placeable.highPressureWasher.lance#position"), "0 0 0"), 3);
58 self.linkRotation = Utils.getRadiansFromString(Utils.getNoNil(getXMLString(xmlFile, "placeable.highPressureWasher.lance#rotation"), "0 0 0"), 3);
59 self.lanceNodeParent = getParent(self.lanceNode);
60
61 self.lanceRaycastNode = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.highPressureWasher.lance#raycastNode"));
62
63 if self.isClient then
64 self.washerParticleSystems = {};
65
66 local i = 0
67 while true do
68 local key = string.format("placeable.highPressureWasher.emitterShape(%d)", i);
69 if not hasXMLProperty(xmlFile, key) then
70 break
71 end
72
73 local emitterShape = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, key.."#node"));
74 local particleType = getXMLString(xmlFile, key.."#particleType")
75 if emitterShape ~= nil then
76 local fillType = FillUtil.FILLTYPE_WATER;
77 local particleSystem = MaterialUtil.getParticleSystem(fillType, particleType)
78 if particleSystem ~= nil then
79 table.insert(self.washerParticleSystems, ParticleUtil.copyParticleSystem(xmlFile, key, particleSystem, emitterShape))
80 end
81 end
82 i = i + 1
83 end
84
85 self.waterEffects = EffectManager:loadEffect(xmlFile, "placeable.highPressureWasher.waterEffect", self.nodeId, self);
86
87
88 self.sampleCompressor = SoundUtil.loadSample(xmlFile, {}, "placeable.highPressureWasher.compressorSound", nil, self.baseDirectory, self.nodeId);
89 self.compressorPitchMin = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.highPressureWasher.compressorSound#pitchMin"), 0.5);
90 self.sampleWashing = SoundUtil.loadSample(xmlFile, {}, "placeable.highPressureWasher.washingSound", nil, self.baseDirectory);
91 self.sampleSwitch = SoundUtil.loadSample(xmlFile, {}, "placeable.highPressureWasher.switchSound", nil, self.baseDirectory);
92
93 local filename = getXMLString(xmlFile, "placeable.highPressureWasher.exhaust#filename");
94 if filename ~= nil then
95 local i3dNode = Utils.loadSharedI3DFile(filename, self.baseDirectory, false, false, false);
96 if i3dNode ~= 0 then
97 local linkNode = Utils.getNoNil(Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.highPressureWasher.exhaust#index")), self.nodeId);
98 self.exhaustFilename = filename;
99 self.exhaustNode = getChildAt(i3dNode, 0);
100 link(linkNode, self.exhaustNode);
101 setVisibility(self.exhaustNode, false);
102 delete(i3dNode);
103 end;
104 end;
105
106 self.targets = {};
107 IKUtil.loadIKChainTargets(xmlFile, "placeable.highPressureWasher.targets", self.nodeId, self.targets);
108 end;
109
110 delete(xmlFile);
111
112 self.isPlayerInRange = false;
113 self.isTurnedOn = false;
114 self.activatable = HighPressureWasherActivatable:new(self);
115 self.doWashing = false;
116 self.lastInRangePosition = {0,0,0};
117 self.isTurningOff = false;
118 self.turnOffTime = 0;
119 self.turnOffDuration = 500;
120
121 return true;
122end;

delete

Description
Deleting placeable high pressure washer
Definition
delete()
Code
126function HighPressureWasher:delete()
127 self:setIsTurnedOn(false, nil, false);
128 if self.isClient then
129 EffectManager:deleteEffects(self.waterEffects);
130 if self.exhaustFilename ~= nil then
131 Utils.releaseSharedI3DFile(self.exhaustFilename, self.baseDirectory, true);
132 end;
133 ParticleUtil.deleteParticleSystems(self.washerParticleSystems)
134 if self.sampleCompressor ~= nil then
135 SoundUtil.deleteSample(self.sampleCompressor);
136 end;
137 if self.sampleWashing ~= nil then
138 SoundUtil.deleteSample(self.sampleWashing);
139 end;
140 if self.sampleSwitch ~= nil then
141 SoundUtil.deleteSample(self.sampleSwitch);
142 end;
143 end;
144
145 unregisterObjectClassName(self);
146 g_currentMission:removeActivatableObject(self.activatable);
147 HighPressureWasher:superClass().delete(self);
148end;

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, table connection)
Arguments
integerstreamIdstream ID
tableconnectionconnection
Code
154function HighPressureWasher:readStream(streamId, connection)
155 HighPressureWasher:superClass().readStream(self, streamId, connection);
156 if connection:getIsServer() then
157 local isTurnedOn = streamReadBool(streamId);
158 if isTurnedOn then
159 local player = readNetworkNodeObject(streamId);
160 if player ~= nil then
161 self:setIsTurnedOn(isTurnedOn, player, true);
162 end;
163 end;
164 end;
165end;

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, table connection)
Arguments
integerstreamIdstream ID
tableconnectionconnection
Code
171function HighPressureWasher:writeStream(streamId, connection)
172 HighPressureWasher:superClass().writeStream(self, streamId, connection);
173 if not connection:getIsServer() then
174 streamWriteBool(streamId, self.isTurnedOn);
175 if self.isTurnedOn then
176 writeNetworkNodeObject(streamId, self.currentPlayer);
177 end;
178 end;
179end;

activateHandtool

Description
Activate hand tool
Definition
activateHandtool(table player)
Arguments
tableplayerplayer
Code
184function HighPressureWasher:activateHandtool(player)
185 self:setIsTurnedOn(true, player, true);
186end;

update

Description
Update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
191function HighPressureWasher:update(dt)
192 HighPressureWasher:superClass().update(self, dt);
193
194 if self.currentPlayer ~= nil then
195 local isPlayerInRange = self:getIsPlayerInRange(self.actionRadius, self.currentPlayer);
196 if isPlayerInRange then
197 self.lastInRangePosition = {getTranslation(self.currentPlayer.rootNode)};
198 else
199 local kx, _, kz = getWorldTranslation(self.nodeId);
200 local px, py, pz = getWorldTranslation(self.currentPlayer.rootNode);
201 local len = Utils.vector2Length(px-kx, pz-kz);
202
203 local x,y,z = unpack(self.lastInRangePosition);
204 x = kx + ((px-kx) / len) * (self.actionRadius-0.00001*dt);
205 z = kz + ((pz-kz) / len) * (self.actionRadius-0.00001*dt);
206 self.currentPlayer:moveToAbsoluteInternal(x, py, z);
207 self.lastInRangePosition = {x,y,z};
208
209 if not self.messageShown and self.currentPlayer == g_currentMission.player then
210 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_hpwRangeRestriction"), 6000);
211 self.messageShown = true;
212 end;
213 end;
214 end;
215
216 if self.isServer then
217 if self.isTurnedOn and self.doWashing then
218 self.foundVehicle = nil;
219 self:cleanVehicle(self.currentPlayer.cameraNode, dt);
220 if self.lanceRaycastNode ~= nil then
221 self:cleanVehicle(self.lanceRaycastNode, dt);
222 end;
223
224 local price = self.pricePerSecond * (dt / 1000);
225 g_currentMission.missionStats:updateStats("expenses", price);
226 g_currentMission:addSharedMoney(-price, "vehicleRunningCost");
227 end;
228 end;
229
230 if self.isTurningOff then
231 if g_currentMission.time < self.turnOffTime then
232 if self.sampleCompressor ~= nil then
233 local pitch = Utils.lerp(self.compressorPitchMin, self.sampleCompressor.pitchOffset, Utils.clamp((self.turnOffTime - g_currentMission.time) / self.turnOffDuration, 0, 1));
234 local volume = Utils.lerp(0, self.sampleCompressor.volume, Utils.clamp((self.turnOffTime - g_currentMission.time) / self.turnOffDuration, 0, 1));
235 SoundUtil.setSamplePitch(self.sampleCompressor, pitch);
236 SoundUtil.setSampleVolume(self.sampleCompressor, volume);
237 end;
238 else
239 self.isTurningOff = false;
240 if self.sampleCompressor ~= nil then
241 SoundUtil.stop3DSample(self.sampleCompressor);
242 end;
243 end;
244 end;
245end;

cleanVehicle

Description
Clean vehicle
Definition
cleanVehicle(integer node, float dt)
Arguments
integernodenode id
floatdttime since last call in ms
Code
251function HighPressureWasher:cleanVehicle(node, dt)
252 local x,y,z = getWorldTranslation(node);
253 local dx, dy, dz = localDirectionToWorld(node, 0, 0, -1);
254 local lastFoundVehicle = self.foundVehicle;
255 raycastAll(x, y, z, dx, dy, dz, "washRaycastCallback", self.washDistance, self, 32+64+128+256+4096+8194);
256
257 if self.foundVehicle ~= nil and lastFoundVehicle ~= self.foundVehicle then
258 self.foundVehicle:setDirtAmount(self.foundVehicle:getDirtAmount() - self.washMultiplier*dt/self.foundVehicle.washDuration);
259 end;
260end;

updateTick

Description
updateTick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
265function HighPressureWasher:updateTick(dt)
266 HighPressureWasher:superClass().updateTick(self, dt);
267 local isPlayerInRange, player = self:getIsPlayerInRange(self.playerInRangeDistance);
268 if isPlayerInRange then
269 self.playerInRange = player;
270 self.isPlayerInRange = true;
271 g_currentMission:addActivatableObject(self.activatable);
272 else
273 self.playerInRange = nil;
274 self.isPlayerInRange = false;
275 g_currentMission:removeActivatableObject(self.activatable);
276 end;
277end;

setIsWashing

Description
Set is washing
Definition
setIsWashing(boolean doWashing, boolean force, boolean noEventSend)
Arguments
booleandoWashingdo washing
booleanforceforce
booleannoEventSendno event send
Code
284function HighPressureWasher:setIsWashing(doWashing, force, noEventSend)
285 HPWPlaceableStateEvent.sendEvent(self, doWashing, noEventSend);
286 if self.doWashing ~= doWashing then
287 if self.isClient then
288 if self.washerParticleSystems ~= nil then
289 for _,ps in pairs(self.washerParticleSystems) do
290 ParticleUtil.setEmittingState(ps, doWashing and self:getIsActiveForInput());
291 end
292 end;
293
294 if doWashing then
295 EffectManager:setFillType(self.waterEffects, FillUtil.FILLTYPE_WATER)
296 EffectManager:startEffects(self.waterEffects)
297 if self.sampleWashing ~= nil and self.currentPlayer == g_currentMission.player then
298 if self:getIsActiveForSound() then
299 SoundUtil.playSample(self.sampleWashing, 0, 0, 1);
300 end;
301 end;
302 else
303 if force then
304 EffectManager:resetEffects(self.waterEffects);
305 else
306 EffectManager:stopEffects(self.waterEffects);
307 end;
308 if self.sampleWashing ~= nil then
309 SoundUtil.stopSample(self.sampleWashing, true);
310 end;
311 end;
312 end;
313 self.doWashing = doWashing;
314 end;
315end;

setIsTurnedOn

Description
Set is turned on
Definition
setIsTurnedOn(boolean isTurnedOn, table player, boolean noEventSend)
Arguments
booleanisTurnedOnis turned on
tableplayerplayer
booleannoEventSendno event send
Code
322function HighPressureWasher:setIsTurnedOn(isTurnedOn, player, noEventSend)
323 HPWPlaceableTurnOnEvent.sendEvent(self, isTurnedOn, player, noEventSend);
324
325 if self.isTurnedOn ~= isTurnedOn then
326 if isTurnedOn then
327 self.isTurnedOn = isTurnedOn;
328 self.currentPlayer = player;
329
330 -- player stuff
331 local tool = {};
332 tool.node = self.lanceNode;
333 link(player.toolsRootNode, tool.node);
334 setVisibility(tool.node, false);
335 setTranslation(tool.node, unpack(self.linkPosition));
336 setRotation(tool.node, unpack(self.linkRotation));
337 tool.update = HighPressureWasher.updateLance;
338 tool.updateTick = HighPressureWasher.updateTickLance;
339 tool.delete = HighPressureWasher.deleteLance;
340 tool.draw = HighPressureWasher.drawLance;
341 tool.onActivate = HighPressureWasher.activateLance;
342 tool.onDeactivate = HighPressureWasher.deactivateLance;
343 tool.targets = self.targets;
344 tool.owner = self;
345 tool.static = false;
346 self.tool = tool;
347 self.currentPlayer:setTool(tool);
348 self.currentPlayer.hasHPWLance = true;
349
350 if self.isClient then
351 if self.sampleSwitch ~= nil and self:getIsActiveForSound() then
352 SoundUtil.playSample(self.sampleSwitch, 1, 0, nil);
353 end;
354 if self.sampleCompressor ~= nil then
355 SoundUtil.setSamplePitch(self.sampleCompressor, self.sampleCompressor.pitchOffset);
356 SoundUtil.setSampleVolume(self.sampleCompressor, self.sampleCompressor.volume);
357 SoundUtil.play3DSample(self.sampleCompressor);
358 end;
359 if self.isTurningOff then
360 self.isTurningOff = false;
361 end;
362 setVisibility(self.lanceNode, g_currentMission.player == player);
363 end;
364 else
365 self:onDeactivate();
366 end;
367 if self.exhaustNode ~= nil then
368 setVisibility(self.exhaustNode, isTurnedOn);
369 end;
370 end;
371end;

onDeactivate

Description
On deactivate
Definition
onDeactivate()
Code
375function HighPressureWasher:onDeactivate()
376 if self.isClient then
377 if self.sampleSwitch ~= nil and self:getIsActiveForSound() then
378 SoundUtil.playSample(self.sampleSwitch, 1, 0, nil);
379 end;
380 end;
381 self.isTurnedOn = false;
382 setVisibility(self.lanceNode, true);
383 self:setIsWashing(false, true, true);
384 if self.currentPlayer ~= nil then
385 self.currentPlayer:setToolById(0, true);
386 self.currentPlayer.hasHPWLance = false;
387 end;
388 if self.isClient then
389 if self.sampleWashing ~= nil then
390 SoundUtil.stopSample(self.sampleWashing, true);
391 end;
392 self.isTurningOff = true;
393 self.turnOffTime = g_currentMission.time + self.turnOffDuration;
394 link(self.lanceNodeParent, self.lanceNode);
395 setTranslation(self.lanceNode, 0,0,0);
396 setRotation(self.lanceNode, 0,0,0);
397 end;
398 self.currentPlayer = nil;
399end;

getIsActiveForInput

Description
Get is active for input
Definition
getIsActiveForInput()
Return Values
booleanisActiveForInputis active for input
Code
404function HighPressureWasher:getIsActiveForInput()
405 if self.isTurnedOn and self.currentPlayer == g_currentMission.player and not g_gui:getIsGuiVisible() then
406 return true;
407 end;
408 return false;
409end;

getIsActiveForSound

Description
Get is active for sound
Definition
getIsActiveForSound()
Return Values
booleanisActiveForSoundis active for sound
Code
414function HighPressureWasher:getIsActiveForSound()
415 return self:getIsActiveForInput();
416end;

canBeSold

Description
Get can be sold in current state
Definition
canBeSold()
Return Values
boolean
stringwarningMessagewarning message displayed in the shop
Code
422function HighPressureWasher:canBeSold()
423 local warning = g_i18n:getText("shop_messageReturnVehicleInUse")
424 if self.currentPlayer ~= nil then
425 return false, warning
426 end
427 return true, nil
428end

washRaycastCallback

Description
Wash raycast callback
Definition
washRaycastCallback(integer hitActorId, float x, float y, float z, float distance, float nx, float ny, float nz, integer subShapeIndex, integer hitShapeId)
Arguments
integerhitActorIdid of hit object actor
floatxx raycast position
floatyy raycast position
floatzz raycast position
floatdistancedistance to raycast position
floatnxx component of hit surface normal (unused)
floatnyy component of hit surface normal (unused)
floatnzz component of hit surface normal (unused)
integersubShapeIndexsub shape index of hit object
integerhitShapeIdid of hit object shape
Code
442function HighPressureWasher:washRaycastCallback(hitActorId, x, y, z, distance, nx, ny, nz, subShapeIndex, hitShapeId)
443 local vehicle = g_currentMission.nodeToVehicle[hitActorId];
444 if hitActorId ~= hitShapeId then
445 -- object is a compoundChild. Try to find the compound
446 local parentId = hitShapeId
447 while parentId ~= 0 do
448 if g_currentMission.nodeToVehicle[parentId] ~= nil then
449 -- found valid compound
450 vehicle = g_currentMission.nodeToVehicle[parentId]
451 break
452 end
453 parentId = getParent(parentId)
454 end
455 end
456
457 if vehicle ~= nil and vehicle.getDirtAmount ~= nil and vehicle.setDirtAmount ~= nil and vehicle.washDuration ~= nil then
458 self.foundCoords = {x,y,z};
459 self.foundVehicle = vehicle;
460 return false;
461 end;
462
463 return true;
464end;

activateLance

Description
Activate lance
Definition
activateLance(table tool)
Arguments
tabletooltool
Code
469function HighPressureWasher.activateLance(tool)
470 setVisibility(tool.node, true);
471end

deactivateLance

Description
Deactivate lance
Definition
deactivateLance(table tool)
Arguments
tabletooltool
Code
476function HighPressureWasher.deactivateLance(tool)
477 tool.owner:setIsTurnedOn(false, nil);
478end

deleteLance

Description
Delete lance
Definition
deleteLance(table tool)
Arguments
tabletooltool
Code
483function HighPressureWasher.deleteLance(tool)
484 tool.owner:setIsTurnedOn(false, nil);
485end

drawLance

Description
Draw lance
Definition
drawLance(table tool)
Arguments
tabletooltool
Code
490function HighPressureWasher.drawLance(tool)
491 if tool.owner.currentPlayer == g_currentMission.player then
492 g_currentMission:addHelpButtonText(g_i18n:getText("input_ACTIVATE_HANDTOOL"), InputBinding.ACTIVATE_HANDTOOL);
493 end;
494end

updateLance

Description
Update lance
Definition
updateLance(table tool, float dt, boolean allowInput)
Arguments
tabletooltool
floatdttime since last call in ms
booleanallowInputallow input
Code
501function HighPressureWasher.updateLance(tool, dt, allowInput)
502 if allowInput then
503 tool.owner:setIsWashing(InputBinding.isPressed(InputBinding.ACTIVATE_HANDTOOL), false, false);
504 end;
505end;