LUADOC - Farming Simulator 17

Printable Version

GreenhousePlaceable

Description
Class for placeable greenhouse
Parent
Placeable
Functions

new

Description
Creating placeable greenhouse
Definition
new(boolean isServer, boolean isClient, table customMt)
Arguments
booleanisServeris server
booleanisClientis client
tablecustomMtcustom metatable
Return Values
tableinstanceInstance of object
Code
18function GreenhousePlaceable:new(isServer, isClient, customMt)
19 local mt = customMt;
20 if mt == nil then
21 mt = GreenhousePlaceable_mt;
22 end;
23
24 local self = Placeable:new(isServer, isClient, mt);
25
26 registerObjectClassName(self, "GreenhousePlaceable");
27
28 self.waterTankCapacity = 1000;
29 self.waterTankFillLevel = 1000;
30 self.sentWaterTankFillLevel = self.waterTankFillLevel;
31 self.waterTankUsagePerHour = 0;
32 self.waterTankFillLitersPerSecond = 200;
33 self.waterTrailers = {};
34 self.isFruitAlive = true;
35 self.displayFruit = false;
36
37 self.manureFillLevel = 0;
38 self.manureUsagePerHour = 0;
39 self.manureCapacity = 200;
40 self.manurePlaneMinY = 0;
41 self.manurePlaneMaxY = 1;
42 self.sentManureFillLevel = self.manureFillLevel;
43
44 self.vehiclesInRange = {};
45 self.playerInRange = false;
46
47 self.greenhousePlaceableDirtyFlag = self:getNextDirtyFlag();
48
49 self.waterTrailerActivatable = GreenhousePlaceableWaterTankActivatable:new(self);
50
51 return self;
52end;

delete

Description
Deleting placeable greenhouse
Definition
delete()
Code
56function GreenhousePlaceable:delete()
57 if self.shovelTarget ~= nil then
58 self.shovelTarget:delete()
59 end
60
61 g_currentMission:removeActivatableObject(self.waterTrailerActivatable);
62 unregisterObjectClassName(self);
63 g_currentMission.environment:removeHourChangeListener(self);
64
65 if self.waterTankTriggerNode ~= nil then
66 removeTrigger(self.waterTankTriggerNode);
67 end;
68 if self.sampleRefuel ~= nil then
69 SoundUtil.deleteSample(self.sampleRefuel);
70 end;
71
72 GreenhousePlaceable:superClass().delete(self);
73end;

deleteFinal

Description
Deleting placeable greenhouse final
Definition
deleteFinal()
Code
77function GreenhousePlaceable:deleteFinal()
78 GreenhousePlaceable:superClass().deleteFinal(self);
79end;

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, table connection)
Arguments
integerstreamIdstream ID
tableconnectionconnection
Code
85function GreenhousePlaceable:readStream(streamId, connection)
86 GreenhousePlaceable:superClass().readStream(self, streamId, connection);
87 if connection:getIsServer() then
88 local waterTankFillLevel = streamReadUInt8(streamId)/255*self.waterTankCapacity;
89 self:setWaterTankFillLevel(waterTankFillLevel);
90 local manureFillLevel = streamReadUInt8(streamId)/255*self.manureCapacity;
91 self:setManureFillLevel(manureFillLevel);
92 end;
93end;

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, table connection)
Arguments
integerstreamIdstream ID
tableconnectionconnection
Code
99function GreenhousePlaceable:writeStream(streamId, connection)
100 GreenhousePlaceable:superClass().writeStream(self, streamId, connection);
101 if not connection:getIsServer() then
102 streamWriteUInt8(streamId, math.floor(self.waterTankFillLevel/self.waterTankCapacity * 255));
103 streamWriteUInt8(streamId, math.floor(self.manureFillLevel/self.manureCapacity * 255));
104 end;
105end;

readUpdateStream

Description
Called on client side on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
112function GreenhousePlaceable:readUpdateStream(streamId, timestamp, connection)
113 GreenhousePlaceable:superClass().readUpdateStream(self, streamId, timestamp, connection);
114 if connection:getIsServer() then
115 local waterTankFillLevel = streamReadUInt8(streamId)/255*self.waterTankCapacity;
116 self:setWaterTankFillLevel(waterTankFillLevel);
117 local manureFillLevel = streamReadUInt8(streamId)/255*self.manureCapacity;
118 self:setManureFillLevel(manureFillLevel);
119 end;
120end;

writeUpdateStream

Description
Called on server side on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
127function GreenhousePlaceable:writeUpdateStream(streamId, connection, dirtyMask)
128 GreenhousePlaceable:superClass().writeUpdateStream(self, streamId, connection, dirtyMask);
129 if not connection:getIsServer() then
130 streamWriteUInt8(streamId, math.floor(self.waterTankFillLevel/self.waterTankCapacity * 255));
131 streamWriteUInt8(streamId, math.floor(self.manureFillLevel/self.manureCapacity * 255));
132 end;
133end;

createNode

Description
Create node
Definition
createNode(string i3dFilename)
Arguments
stringi3dFilenamei3d file name
Return Values
booleansuccesssuccess
Code
139function GreenhousePlaceable:createNode(i3dFilename)
140 if not GreenhousePlaceable:superClass().createNode(self, i3dFilename) then
141 return false;
142 end;
143
144 return true;
145end;

load

Description
Load greenhouse
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
158function GreenhousePlaceable:load(xmlFilename, x,y,z, rx,ry,rz, initRandom)
159 if not GreenhousePlaceable:superClass().load(self, xmlFilename, x,y,z, rx,ry,rz, initRandom) then
160 return false;
161 end;
162
163 local xmlFile = loadXMLFile("TempXML", xmlFilename);
164
165 local fruitAlive = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.fruit#alive"));
166 local fruitDead = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.fruit#dead"));
167 if fruitAlive ~= nil then
168 self.fruitAlive = fruitAlive;
169 end;
170 if fruitDead ~= nil then
171 self.fruitDead = fruitDead;
172 end;
173
174 self.waterTankTriggerNode = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.waterTank#triggerNode"));
175 self.waterTankCapacity = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.waterTank#capacity"), self.waterTankCapacity);
176 self.waterTankUsagePerHour = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.waterTank#usagePerHour"), self.waterTankUsagePerHour);
177 self.waterTankFillLitersPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.waterTank#fillLitersPerSecond"), self.waterTankFillLitersPerSecond);
178 if g_client ~= nil then
179 self.sampleRefuel = SoundUtil.loadSample(xmlFile, {}, "placeable.waterTank#refuelSound", "$data/maps/sounds/refuel.wav", self.baseDirectory, self.nodeId);
180 end;
181
182 self.manurePlane = Utils.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.manurePlane#node"));
183 self.shovelTargetNode = Utils.indexToObject(self.nodeId, Utils.getNoNil(getXMLString(xmlFile, "placeable.manurePlane#shovelTargetIndex"), getXMLString(xmlFile, "placeable.manurePlane#collisionNode")))
184 local minY, maxY = Utils.getVectorFromString(getXMLString(xmlFile, "placeable.manurePlane#minMaxY"));
185 if minY ~= nil and maxY ~= nil then
186 self.manurePlaneMinY = minY;
187 self.manurePlaneMaxY = maxY;
188 end;
189 self.manureCapacity = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.manurePlane#capacity"), self.manureCapacity);
190 self.manureUsagePerHour = Utils.getNoNil(getXMLFloat(xmlFile, "placeable.manurePlane#usagePerHour"), self.manureUsagePerHour);
191
192 delete(xmlFile);
193
194 self:setWaterTankFillLevel(0);
195 self.sentWaterTankFillLevel = self.waterTankFillLevel;
196
197 self:setManureFillLevel(0);
198 self.sentManureFillLevel = self.manureFillLevel;
199
200 return true;
201end;

finalizePlacement

Description
Called if placeable is placed
Definition
finalizePlacement()
Code
205function GreenhousePlaceable:finalizePlacement()
206 GreenhousePlaceable:superClass().finalizePlacement(self);
207 g_currentMission.environment:addHourChangeListener(self);
208 if self.waterTankTriggerNode ~= nil then
209 addTrigger(self.waterTankTriggerNode, "onWaterTankTrigger", self);
210 end
211
212 if self.shovelTargetNode ~= nil then
213 if self.shovelTargetNode ~= nil then
214 self.shovelTarget = ShovelTarget:new(self)
215 if not self.shovelTarget:load(self.shovelTargetNode) then
216 self.shovelTarget:delete()
217 self.shovelTarget = nil
218 end
219 end
220 end;
221end

initPose

Description
Initialize pose
Definition
initPose(float x, float y, float z, float rx, float ry, float rz, boolean initRandom)
Arguments
floatxx world position
floatyy world position
floatzz world position
floatrxrx world rotation
floatryry world rotation
floatrzrz world rotation
booleaninitRandominitialize random
Code
232function GreenhousePlaceable:initPose(x,y,z, rx,ry,rz, initRandom)
233 GreenhousePlaceable:superClass().initPose(self, x,y,z, rx,ry,rz, initRandom);
234end;

loadFromAttributesAndNodes

Description
Loading from attributes and nodes
Definition
loadFromAttributesAndNodes(integer xmlFile, string key, boolean resetVehicles)
Arguments
integerxmlFileid of xml object
stringkeykey
booleanresetVehiclesreset vehicles
Return Values
booleansuccesssuccess
Code
242function GreenhousePlaceable:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
243
244 if not GreenhousePlaceable:superClass().loadFromAttributesAndNodes(self, xmlFile, key, resetVehicles) then
245 return false;
246 end;
247
248 local waterTankFillLevel = getXMLFloat(xmlFile, key.."#waterTankFillLevel");
249 if waterTankFillLevel ~= nil then
250 self:setWaterTankFillLevel(waterTankFillLevel);
251 end;
252 local manureFillLevel = getXMLFloat(xmlFile, key.."#manureFillLevel");
253 if manureFillLevel ~= nil then
254 self:setManureFillLevel(manureFillLevel);
255 end;
256
257 return true;
258end;

getSaveAttributesAndNodes

Description
Get save attributes and nodes
Definition
getSaveAttributesAndNodes(string nodeIdent)
Arguments
stringnodeIdentnode ident
Return Values
stringattributesattributes
stringnodesnodes
Code
265function GreenhousePlaceable:getSaveAttributesAndNodes(nodeIdent)
266 local attributes, nodes = GreenhousePlaceable:superClass().getSaveAttributesAndNodes(self, nodeIdent);
267 attributes = attributes .. ' waterTankFillLevel="'..self.waterTankFillLevel..'"';
268 attributes = attributes .. ' manureFillLevel="'..self.manureFillLevel..'"';
269 return attributes, nodes;
270end;

update

Description
Update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
275function GreenhousePlaceable:update(dt)
276 GreenhousePlaceable:superClass().update(self, dt);
277 if self:getShowInfo() then
278 g_currentMission:addExtraPrintText(g_i18n:getText("info_waterFillLevel").." "..math.floor(self.waterTankFillLevel).." ("..math.floor(100*self.waterTankFillLevel/self.waterTankCapacity).."%)");
279 g_currentMission:addExtraPrintText(g_i18n:getText("info_manureFillLevel").." "..math.floor(self.manureFillLevel).." ("..math.floor(100*self.manureFillLevel/self.manureCapacity).."%)");
280 end;
281end;

updateTick

Description
updateTick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
286function GreenhousePlaceable:updateTick(dt)
287 if self.isServer then
288
289 if self.waterTankFillLevel ~= self.sentWaterTankFillLevel then
290 self:raiseDirtyFlags(self.greenhousePlaceableDirtyFlag);
291
292 self.sentWaterTankFillLevel = self.waterTankFillLevel;
293 end;
294 if self.manureFillLevel ~= self.sentManureFillLevel then
295 self:raiseDirtyFlags(self.greenhousePlaceableDirtyFlag);
296
297 self.sentManureFillLevel = self.manureFillLevel;
298 end;
299
300 if self.isWaterTankFilling then
301 local disableFilling = false;
302 local waterFillLevel = self.waterTankFillTrailer:getFillLevel(FillUtil.FILLTYPE_WATER);
303 if waterFillLevel > 0 then
304 local oldFillLevel = self.waterTankFillLevel;
305
306 local delta = self.waterTankFillLitersPerSecond*dt*0.001;
307 delta = math.min(delta, waterFillLevel);
308
309 self:setWaterTankFillLevel(self.waterTankFillLevel + delta);
310
311 local delta = self.waterTankFillLevel - oldFillLevel;
312 if delta <= 0 then
313 disableFilling = true;
314 end;
315 self.waterTankFillTrailer:setFillLevel(waterFillLevel - delta, FillUtil.FILLTYPE_WATER, true);
316 else
317 disableFilling = true;
318 end;
319 if disableFilling then
320 self:setIsWaterTankFilling(false);
321 end;
322 end;
323
324 end;
325end;

getShowInfo

Description
Returns true if info should show
Definition
getShowInfo()
Return Values
booleanshowInfoshow info
Code
330function GreenhousePlaceable:getShowInfo()
331 if (g_currentMission.controlPlayer and self.playerInRange) then
332 return true;
333 end;
334 if not g_currentMission.controlPlayer then
335 for vehicle in pairs(self.vehiclesInRange) do
336 if vehicle:getIsActiveForInput() then
337 return true;
338 end;
339 end;
340 end;
341 return false;
342end;

hourChanged

Description
Called if hour changed
Definition
hourChanged()
Code
346function GreenhousePlaceable:hourChanged()
347 if self.isServer then
348 self:setWaterTankFillLevel(self.waterTankFillLevel - self.waterTankUsagePerHour);
349 self:setManureFillLevel(self.manureFillLevel - self.manureUsagePerHour);
350
351 if self.isFruitAlive then
352 local income = self.incomePerHour;
353 if self.manureFillLevel > 0 then
354 income = income * 2;
355 end;
356 g_currentMission:addSharedMoney(income, "propertyIncome");
357 g_currentMission:addMoneyChange(income, EconomyManager.MONEY_TYPE_PROPERTY_INCOME);
358 end;
359 end;
360end;

setWaterTankFillLevel

Description
Set water tank fill level
Definition
setWaterTankFillLevel(float fillLevel)
Arguments
floatfillLevelnew fill level
Code
365function GreenhousePlaceable:setWaterTankFillLevel(fillLevel)
366 self.waterTankFillLevel = Utils.clamp(fillLevel, 0, self.waterTankCapacity);
367
368 self.isFruitAlive = self.waterTankFillLevel > 0.0001;
369
370 if self.waterTankFillLevel > 0 then
371 self.displayFruit = true;
372 end;
373
374 if self.fruitAlive ~= nil then
375 setVisibility(self.fruitAlive, self.isFruitAlive and self.displayFruit);
376 end;
377 if self.fruitDead ~= nil then
378 setVisibility(self.fruitDead, not self.isFruitAlive and self.displayFruit);
379 end;
380end;

addFillLevelFromTool

Description
Add fill level from tool to trigger
Definition
addFillLevelFromTool(table object, float fillDelta, integer fillType, integer toolType)
Arguments
tableobjectobject
floatfillDeltadelta to fill
integerfillTypefill type index
integertoolTypetool type index
Return Values
floatfillDeltareal fill delta
Code
389function GreenhousePlaceable:addFillLevelFromTool(object, fillDelta, fillType, toolType)
390 fillDelta = math.min(fillDelta, self.manureCapacity-self.manureFillLevel)
391
392 if fillDelta > 0 then
393 self:setManureFillLevel(self.manureFillLevel+fillDelta);
394 end;
395
396 return fillDelta;
397end

getAllowFillTypeFromTool

Description
Returns if shovel fill type is allowed
Definition
getAllowFillTypeFromTool()
Return Values
floatisAllowedis allowed
Code
402function GreenhousePlaceable:getAllowFillTypeFromTool(fillType)
403 return fillType == FillUtil.FILLTYPE_MANURE;
404end;

setManureFillLevel

Description
Set manure fill level
Definition
setManureFillLevel(float fillLevel)
Arguments
floatfillLevelnew fill level
Code
409function GreenhousePlaceable:setManureFillLevel(fillLevel)
410 self.manureFillLevel = Utils.clamp(fillLevel, 0, self.manureCapacity);
411
412 if self.manurePlane ~= nil then
413 setVisibility(self.manurePlane, self.manureFillLevel > 0.0001);
414 local x,y,z = getTranslation(self.manurePlane);
415 y = self.manurePlaneMinY + self.manureFillLevel/self.manureCapacity * (self.manurePlaneMaxY - self.manurePlaneMinY);
416
417 setTranslation(self.manurePlane, x,y,z);
418 end;
419end;

setIsWaterTankFilling

Description
Set is water tank filling
Definition
setIsWaterTankFilling(boolean isWaterTankFilling, table trailer, boolean noEventSend)
Arguments
booleanisWaterTankFillingis water tank filling
tabletrailertrailer
booleannoEventSendno event send
Code
426function GreenhousePlaceable:setIsWaterTankFilling(isWaterTankFilling, trailer, noEventSend)
427 GreenhouseSetIsWaterTankFillingEvent.sendEvent(self, isWaterTankFilling, trailer, noEventSend)
428 if self.isWaterTankFilling ~= isWaterTankFilling then
429 self.isWaterTankFilling = isWaterTankFilling;
430 self.waterTankFillTrailer = trailer;
431 end;
432 if self.sampleRefuel ~= nil then
433 if isWaterTankFilling then
434 SoundUtil.play3DSample(self.sampleRefuel);
435 else
436 SoundUtil.stop3DSample(self.sampleRefuel);
437 end;
438 end;
439end;

addWaterTrailer

Description
Add water trailer in range
Definition
addWaterTrailer(table trailer)
Arguments
tabletrailertrailer
Code
444function GreenhousePlaceable:addWaterTrailer(trailer)
445 if table.getn(self.waterTrailers) == 0 then
446 g_currentMission:addActivatableObject(self.waterTrailerActivatable);
447 end;
448 table.insert(self.waterTrailers, trailer);
449end;

removeWaterTrailer

Description
Remove water trailer in range
Definition
removeWaterTrailer(table trailer)
Arguments
tabletrailertrailer
Code
454function GreenhousePlaceable:removeWaterTrailer(trailer)
455 for i=1, table.getn(self.waterTrailers) do
456 if self.waterTrailers[i] == trailer then
457 table.remove(self.waterTrailers, i);
458 break;
459 end;
460 end;
461 if table.getn(self.waterTrailers) == 0 then
462 if self.isServer then
463 self:setIsWaterTankFilling(false);
464 end;
465 g_currentMission:removeActivatableObject(self.waterTrailerActivatable);
466 end;
467end;

onWaterTankTrigger

Description
Water tank trigger
Definition
onWaterTankTrigger(integer triggerId, integer otherId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)
Arguments
integertriggerIdid of trigger
integerotherIdid of actor
booleanonEnteron enter
booleanonLeaveon leave
booleanonStayon stay
integerotherShapeIdid of other actor
Code
477function GreenhousePlaceable:onWaterTankTrigger(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId)
478 if onEnter or onLeave then
479
480 if g_currentMission.player ~= nil and otherActorId == g_currentMission.player.rootNode then
481 if onEnter then
482 self.playerInRange = true;
483 else
484 self.playerInRange = false;
485 end;
486 else
487 local vehicle = g_currentMission.nodeToVehicle[otherActorId];
488 if vehicle ~= nil then
489 if onEnter then
490 self.vehiclesInRange[vehicle] = true;
491 else
492 self.vehiclesInRange[vehicle] = nil;
493 end;
494 end;
495
496
497 local trailer = g_currentMission.objectToTrailer[otherShapeId];
498 if trailer ~= nil and trailer:allowFillType(FillUtil.FILLTYPE_WATER, false) then
499 if onEnter then
500 self:addWaterTrailer(trailer);
501 else -- onLeave
502 self:removeWaterTrailer(trailer);
503 end;
504 end;
505 end;
506 end;
507end;