LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

TreePlanter

Description
Class for all tree planters
Functions

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
21function TreePlanter.prerequisitesPresent(specializations)
22 return SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations);
23end

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
28function TreePlanter:load(savegame)
29
30 self.setPlantLimitToField = TreePlanter.setPlantLimitToField;
31 self.getDoGroundManipulation = Utils.overwrittenFunction(self.getDoGroundManipulation, TreePlanter.getDoGroundManipulation);
32 self.getDirtMultiplier = Utils.overwrittenFunction(self.getDirtMultiplier, TreePlanter.getDirtMultiplier);
33 self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, TreePlanter.getIsSpeedRotatingPartActive);
34 self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, TreePlanter.doCheckSpeedLimit);
35 self.setUnitFillLevel = Utils.overwrittenFunction(self.setUnitFillLevel, TreePlanter.setUnitFillLevel);
36 self.createTree = TreePlanter.createTree;
37 self.loadPallet = TreePlanter.loadPallet;
38 self.removeMountedObject = Utils.appendedFunction(self.removeMountedObject, TreePlanter.removeMountedObject);
39
40 if self.isClient then
41 self.sampleTreePlanter = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.treePlanterSound", nil, self.baseDirectory);
42 self.treePlanterTurnedOnRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "treePlanter", self.components);
43 end
44
45 self.treePlanterNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.treePlanter#node"));
46 self.treePlanterMinDistance = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.treePlanter#minDistance"), 20); -- distance to next tree
47 local refNodeIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.treePlanter#refNodeIndex"), 0) + 1;
48 self.treePlanterRefNode = self.groundReferenceNodes[refNodeIndex];
49 if table.getn(self.groundReferenceNodes) == 0 or self.treePlanterRefNode == nil then
50 print("Warning: No groundReferenceNode specified or invalid groundReferenceNode index in '".. self.configFileName .. "'");
51 end
52
53 self.treePlanterActivatable = TreePlanterActivatable:new(self);
54
55 self.saplingPalletGrabNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.treePlanter#saplingPalletGrabNode")), self.rootNode);
56 self.saplingPalletMountNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.treePlanter#saplingPalletMountNode")), self.rootNode);
57 self.mountedSaplingPallet = nil;
58
59 self.treePlanter = {};
60 self.treePlanter.fillUnitIndex = 1;
61
62 self.currentTree = 1;
63 self.lastTreePos = nil;
64 self.synchronizeFullFillLevel = true;
65
66 self.nearestPalletDistance = 6.0;
67 self.treePlantingRefNode = 1;
68 self.showFieldNotOwnedWarning = false;
69 self.showTooManyTreesWarning = false;
70 self.treePlanterHasGroundContact = false
71
72 self.plantLimitToField = true;
73 self.forcePlantLimitToField = false;
74
75 self.isTreePlanterSpeedLimitActive = false;
76
77 -- attributes for AI
78 table.insert(self.terrainDetailRequiredValueRanges, {g_currentMission.cultivatorValue, g_currentMission.cultivatorValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels});
79 table.insert(self.terrainDetailRequiredValueRanges, {g_currentMission.ploughValue, g_currentMission.ploughValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels});
80 table.insert(self.terrainDetailRequiredValueRanges, {g_currentMission.sowingValue, g_currentMission.sowingValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels});
81
82 self.aiProhibitedFruitType = FruitUtil.FRUITTYPE_POPLAR;
83
84 self.treePlanterDirtyFlag = self:getNextDirtyFlag();
85
86 if savegame ~= nil and not savegame.resetVehicles then
87 local lastTreePos = getXMLString(savegame.xmlFile, savegame.key.."#lastTreePos");
88 if lastTreePos ~= nil then
89 self.lastTreePos = Utils.getVectorNFromString(lastTreePos, 3);
90 end
91
92 local palletClassName = getXMLString(savegame.xmlFile, savegame.key..".pallet#className");
93 if palletClassName ~= nil then
94 local modName = getXMLString(savegame.xmlFile, savegame.key..".pallet#modName");
95 if modName == nil or g_modIsLoaded[modName] then
96 local itemClass = getClassObject(palletClassName);
97 if itemClass ~= nil and itemClass.new ~= nil then
98 local item = itemClass:new(self.isServer, self.isClient);
99 if item ~= nil and item.loadFromAttributesAndNodes ~= nil and item:loadFromAttributesAndNodes(savegame.xmlFile, savegame.key..".pallet") then
100 item:register();
101 self.palletIdToMount = networkGetObjectId(item);
102 end
103 end
104 end
105 end
106 end
107end

delete

Description
Called on deleting
Definition
delete()
Code
111function TreePlanter:delete()
112 if self.isClient then
113 SoundUtil.deleteSample(self.sampleTreePlanter);
114 end
115 if self.treePlanterActivatable ~= nil then
116 g_currentMission:removeActivatableObject(self.treePlanterActivatable);
117 end
118 if self.mountedSaplingPallet ~= nil then
119 self.mountedSaplingPallet:unmount();
120 self.mountedSaplingPallet = nil;
121 end
122end

removeMountedObject

Description
Remove mounted object
Definition
removeMountedObject(integer object, boolean isDeleting)
Arguments
integerobjectobject to remove
booleanisDeletingcalled on delete
Code
128function TreePlanter:removeMountedObject(object, isDeleting)
129 if self.mountedSaplingPallet == object then
130 self.mountedSaplingPallet = nil;
131 end
132end

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
138function TreePlanter:readStream(streamId, connection)
139 local hasPallet = streamReadBool(streamId);
140 if hasPallet then
141 self.palletIdToMount = readNetworkNodeObjectId(streamId);
142 end
143end

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
149function TreePlanter:writeStream(streamId, connection)
150 streamWriteBool(streamId, self.mountedSaplingPallet ~= nil);
151 if self.mountedSaplingPallet ~= nil then
152 local palletId = networkGetObjectId(self.mountedSaplingPallet);
153 writeNetworkNodeObjectId(streamId, palletId);
154 end
155end

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
162function TreePlanter:readUpdateStream(streamId, timestamp, connection)
163 if connection:getIsServer() then
164 self.treePlanterHasGroundContact = streamReadBool(streamId);
165 self.showFieldNotOwnedWarning = streamReadBool(streamId);
166 end
167end

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
174function TreePlanter:writeUpdateStream(streamId, connection, dirtyMask)
175 if not connection:getIsServer() then
176 streamWriteBool(streamId, self.treePlanterHasGroundContact);
177 streamWriteBool(streamId, self.showFieldNotOwnedWarning);
178 end
179end

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
190function TreePlanter:update(dt)
191 if self.firstTimeRun then
192 if self.palletIdToMount ~= nil then
193 local pallet = networkGetObject(self.palletIdToMount);
194 if pallet ~= nil then
195 pallet:mount(self, self.saplingPalletMountNode, 0,0,0, 0,0,0);
196
197 self:setUnitCapacity(self.treePlanter.fillUnitIndex, pallet.fillLevel);
198 self:setUnitFillLevel(self.treePlanter.fillUnitIndex, pallet.fillLevel, pallet.fillType, false, nil);
199
200 self.mountedSaplingPallet = pallet;
201 g_currentMission:removeActivatableObject(self.treePlanterActivatable)
202 self.palletIdToMount = nil;
203 end
204 end
205 end
206
207 if self:getIsActive() then
208 if self.mountedSaplingPallet == nil then
209 self.nearestSaplingPallet = TreePlanter.getSaplingPalletInRange(self, self.saplingPalletGrabNode);
210 if self.nearestSaplingPallet ~= nil then
211 g_currentMission:addActivatableObject(self.treePlanterActivatable);
212 else
213 g_currentMission:removeActivatableObject(self.treePlanterActivatable);
214 end
215 end
216
217 if self:getIsActiveForInput() then
218 if not self.forcePlantLimitToField then
219 if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then
220 self:setPlantLimitToField(not self.plantLimitToField);
221 end
222 end
223 end
224 end
225
226 if self.isClient then
227 Utils.updateRotationNodes(self, self.treePlanterTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn());
228 end
229
230end

updateTick

Description
Called on update tick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
235function TreePlanter:updateTick(dt)
236 self.isTreePlanterSpeedLimitActive = false;
237 self.showTooManyTreesWarning = false;
238 if self:getIsActive() then
239 local showFieldNotOwnedWarning = false;
240
241 if self.isServer then
242 local hasGroundContact = false;
243 if self.treePlanterRefNode ~= nil then
244 hasGroundContact = self.treePlanterRefNode.isActive;
245 end
246 if self.treePlanterHasGroundContact ~= hasGroundContact then
247 self:raiseDirtyFlags(self.treePlanterDirtyFlag);
248 end
249 self.treePlanterHasGroundContact = hasGroundContact;
250 end
251 local hasGroundContact = self.treePlanterHasGroundContact;
252
253 if self:getIsHired() then
254 if self.mountedSaplingPallet == nil or (self:getUnitFillType(self.treePlanter.fillUnitIndex) == 0 and not g_currentMission.missionInfo.helperBuySeeds) then
255 local rootVehicle = self:getRootAttacherVehicle()
256 rootVehicle:stopAIVehicle(AIVehicle.STOP_REASON_OUT_OF_FILL);
257 end
258 end
259
260 if hasGroundContact and self.mountedSaplingPallet ~= nil then
261 if self:getIsTurnedOn() then
262 self.isTreePlanterSpeedLimitActive = true;
263
264 if self.isServer then
265 local fillLevel = self:getUnitFillLevel(self.treePlanter.fillUnitIndex);
266 local fillType = self:getUnitFillType(self.treePlanter.fillUnitIndex);
267
268 if fillLevel > 0 or g_currentMission.missionInfo.helperBuySeeds then
269
270 if fillType == FillUtil.FILLTYPE_TREESAPLINGS then
271 if self:getLastSpeed() > 1 then
272 local x,y,z = getWorldTranslation(self.treePlanterNode);
273 if g_currentMission:getIsFieldOwnedAtWorldPos(x,z) then
274 showFieldNotOwnedWarning = false;
275 if self.lastTreePos ~= nil then
276 local distance = Utils.vector3Length(x-self.lastTreePos[1], y-self.lastTreePos[2], z-self.lastTreePos[3]);
277 if distance > self.treePlanterMinDistance then
278 self:createTree();
279 end
280 else
281 self:createTree();
282 end
283 else
284 showFieldNotOwnedWarning = true;
285 end
286 end
287 else
288 local x,_,z = getWorldTranslation(self.treePlanterNode);
289 if g_currentMission:getIsFieldOwnedAtWorldPos(x,z) then
290 local width = math.sqrt( g_currentMission:getFruitPixelsToSqm() ) * 0.5;
291
292 local sx,_,sz = localToWorld(self.treePlanterNode, -width,0,width);
293 local wx,_,wz = localToWorld(self.treePlanterNode, width,0,width);
294 local hx,_,hz = localToWorld(self.treePlanterNode, -width,0,3*width);
295
296 local fruitType = FruitUtil.fillTypeToFruitType[fillType];
297 local fruitDesc = FruitUtil.fruitIndexToDesc[fruitType];
298
299 local dx,_,dz = localDirectionToWorld(self.treePlanterNode, 0, 0, 1);
300 local angleRad = Utils.getYRotationFromDirection(dx, dz)
301 local desc = FruitUtil.fruitIndexToDesc[fruitType];
302 if desc ~= nil and desc.directionSnapAngle ~= 0 then
303 angleRad = math.floor(angleRad / desc.directionSnapAngle + 0.5) * desc.directionSnapAngle;
304 end
305 local angle = Utils.convertToDensityMapAngle(angleRad, g_currentMission.terrainDetailAngleMaxValue);
306
307 -- cultivate
308 local limitToField = self.plantLimitToField or self.forcePlantLimitToField;
309 local limitGrassDestructionToField = self.plantLimitToField or self.forcePlantLimitToField;
310 Utils.updateCultivatorArea(sx,sz, wx,wz, hx,hz, not limitToField, not limitGrassDestructionToField, angle);
311 Utils.eraseTireTrack(sx,sz, wx,wz, hx,hz)
312
313 -- plant, shift area
314 local sx,_,sz = localToWorld(self.treePlanterNode, -width,0,-3*width);
315 local wx,_,wz = localToWorld(self.treePlanterNode, width,0,-3*width);
316 local hx,_,hz = localToWorld(self.treePlanterNode, -width,0,-width);
317 local area, _ = Utils.updateSowingArea(fruitType, sx,sz, wx,wz, hx,hz, angle, true, 2);
318
319 local usage = fruitDesc.seedUsagePerSqm * area;
320
321 if self:getIsHired() and g_currentMission.missionInfo.helperBuySeeds then
322 local price = usage * g_currentMission.economyManager:getCostPerLiter(FillUtil.FILLTYPE_SEEDS) * 1.5 -- increase price if AI is active to reward the player's manual work
323 g_currentMission.missionStats:updateStats("expenses", price);
324 g_currentMission:addSharedMoney(-price, "purchaseSeeds");
325 else
326 self:setUnitFillLevel(self.treePlanter.fillUnitIndex, fillLevel-usage, fillType, false, nil);
327 end
328
329 self.lastSowingArea = Utils.areaToHa(area, g_currentMission:getFruitPixelsToSqm());
330 g_currentMission.missionStats:updateStats("seedUsage", usage);
331 g_currentMission.missionStats:updateStats("sownHectares", self.lastSowingArea);
332 g_currentMission.missionStats:updateStats("sownTime", dt/(1000*60));
333 g_currentMission.missionStats:updateStats("workedHectares", self.lastSowingArea);
334 g_currentMission.missionStats:updateStats("workedTime", dt/(1000*60));
335 else
336 showFieldNotOwnedWarning = true;
337 end
338 end
339
340 end
341 end
342 end
343 end
344
345 if self.isServer then
346 if showFieldNotOwnedWarning ~= self.showFieldNotOwnedWarning then
347 self.showFieldNotOwnedWarning = showFieldNotOwnedWarning;
348 self:raiseDirtyFlags(self.treePlanterDirtyFlag);
349 end
350 end
351
352 if self.isClient then
353 if self:getIsTurnedOn() and self.treePlanterHasGroundContact and self:getIsActiveForSound() and self:getLastSpeed() > 1 then
354 SoundUtil.playSample(self.sampleTreePlanter, 0, 0, nil);
355 else
356 SoundUtil.stopSample(self.sampleTreePlanter, true);
357 end
358 end
359 end
360end

draw

Description
Called on draw
Definition
draw()
Code
364function TreePlanter:draw()
365 if self.isClient then
366 if self:getIsActiveForInput(true) then
367 if self:getFillLevel(FillUtil.FILLTYPE_TREESAPLINGS) <= 0 and self:getCapacity(FillUtil.FILLTYPE_TREESAPLINGS) ~= 0 then
368 g_currentMission:addExtraPrintText(g_i18n:getText("info_firstFillTheTool"));
369 end
370
371 if self:getFillLevel(FillUtil.FILLTYPE_TREESAPLINGS) > 0 then
372 if g_currentMission:getHasPermission("createFields", self:getOwner()) then
373 if not self.forcePlantLimitToField then
374 if self.plantLimitToField then
375 g_currentMission:addHelpButtonText(g_i18n:getText("action_allowCreateFields"), InputBinding.IMPLEMENT_EXTRA3, nil, GS_PRIO_NORMAL);
376 else
377 g_currentMission:addHelpButtonText(g_i18n:getText("action_limitToFields"), InputBinding.IMPLEMENT_EXTRA3, nil, GS_PRIO_NORMAL);
378 end
379 end
380 end
381 end
382 end
383
384 if self.showFieldNotOwnedWarning then
385 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_youDontOwnThisField"));
386 end
387 if self.showTooManyTreesWarning then
388 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_tooManyTrees"));
389 end
390 end
391end

onDeactivateSounds

Description
Called on deactivating sounds
Definition
onDeactivateSounds()
Code
398function TreePlanter:onDeactivateSounds()
399 if self.isClient then
400 SoundUtil.stopSample(self.sampleTreePlanter, true);
401 end
402end

setPlantLimitToField

Description
Set plant limit to field state
Definition
setPlantLimitToField(boolean plantLimitToField, boolean noEventSend)
Arguments
booleanplantLimitToFieldplant limit to field state
booleannoEventSendno event send
Code
408function TreePlanter:setPlantLimitToField(plantLimitToField, noEventSend)
409 if self.plantLimitToField ~= plantLimitToField then
410 if noEventSend == nil or noEventSend == false then
411 if g_server ~= nil then
412 g_server:broadcastEvent(PlantLimitToFieldEvent:new(self, plantLimitToField), nil, nil, self);
413 else
414 g_client:getServerConnection():sendEvent(PlantLimitToFieldEvent:new(self, plantLimitToField));
415 end
416 end
417 self.plantLimitToField = plantLimitToField;
418 end
419end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
424function TreePlanter:onTurnedOff(noEventSend)
425 TreePlanter.onDeactivateSounds(self)
426end

createTree

Description
Create tree on current position
Definition
createTree()
Code
430function TreePlanter:createTree()
431 if not TreePlantUtil.canPlantTree() then
432 self.showTooManyTreesWarning = true;
433 return;
434 end
435 if self.isServer and self.mountedSaplingPallet ~= nil then
436 local x,y,z = getWorldTranslation(self.treePlanterNode);
437 local yRot = math.random() * 2*math.pi;
438 TreePlantUtil.plantTree(g_currentMission.plantedTrees, self.mountedSaplingPallet.treeType, x,y,z, 0,yRot,0, 0);
439 self.lastTreePos = {x,y,z};
440
441 if g_currentMission.missionInfo.helperBuySeeds and self:getIsHired() then
442
443 local filename = self.mountedSaplingPallet.xmlFilename;
444 local storeItem = StoreItemsUtil.storeItemsByXMLFilename[filename:lower()];
445 local pricePerSapling = 1.5 * (storeItem.price / self.mountedSaplingPallet.capacity);
446
447 g_currentMission.missionStats:updateStats("expenses", pricePerSapling);
448 g_currentMission:addSharedMoney(-pricePerSapling, "purchaseSeeds");
449
450 else
451
452 local fillLevel = self:getUnitFillLevel(self.treePlanter.fillUnitIndex);
453 local fillType = self:getUnitFillType(self.treePlanter.fillUnitIndex);
454 self:setUnitFillLevel(self.treePlanter.fillUnitIndex, fillLevel - 1, fillType, false, nil);
455
456 end
457
458 -- increase tree plant counter for achievements
459 g_currentMission.missionStats:updateStats("plantedTreeCount", 1);
460 end
461end

setUnitFillLevel

Description
Set unit fill level
Definition
setUnitFillLevel(integer fillUnitIndex, float fillLevel, integer fillType, boolean force, table fillInfo)
Arguments
integerfillUnitIndexindex of fill unit
floatfillLevelnew fill level
integerfillTypefill type
booleanforceforce action
tablefillInfofill info for fill volume
Code
476function TreePlanter:setUnitFillLevel(superFunc, fillUnitIndex, fillLevel, fillType, force, fillInfo)
477 superFunc(self, fillUnitIndex, fillLevel, fillType, force, fillInfo);
478
479 if self.mountedSaplingPallet ~= nil then
480 self.mountedSaplingPallet:setFillLevel(fillLevel);
481 if self.mountedSaplingPallet.fillLevel <= 0 then
482 self.mountedSaplingPallet:delete();
483 self.mountedSaplingPallet = nil;
484
485 local rootAttacherVehicle = self:getRootAttacherVehicle();
486 if rootAttacherVehicle ~= nil then
487 if rootAttacherVehicle.aiIsStarted then
488 rootAttacherVehicle:stopAIVehicle(AIVehicle.STOP_REASON_OUT_OF_FILL);
489 end
490 end
491 end
492 end
493end

loadPallet

Description
Called on loading
Definition
loadPallet(table savegame)
Arguments
tablesavegamesavegame
Code
498function TreePlanter:loadPallet(palletObjectId, noEventSend)
499 TreePlanterLoadPalletEvent.sendEvent(self, palletObjectId, noEventSend);
500
501 self.palletIdToMount = palletObjectId;
502end

getDirtMultiplier

Description
Returns current dirt multiplier
Definition
getDirtMultiplier()
Return Values
floatdirtMultipliercurrent dirt multiplier
Code
507function TreePlanter:getDirtMultiplier(superFunc)
508 local multiplier = 0;
509 if superFunc ~= nil then
510 multiplier = multiplier + superFunc(self);
511 end
512
513 if self.treePlanterHasGroundContact then
514 multiplier = multiplier + self.workMultiplier * self:getLastSpeed() / self.speedLimit;
515 end
516
517 return multiplier;
518end

getIsSpeedRotatingPartActive

Description
Returns true if speed rotating part is active
Definition
getIsSpeedRotatingPartActive(table speedRotatingPart)
Arguments
tablespeedRotatingPartspeedRotatingPart
Return Values
booleanisActivespeed rotating part is active
Code
524function TreePlanter:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
525 if not self.treePlanterHasGroundContact then
526 return false;
527 end
528
529 if superFunc ~= nil then
530 return superFunc(self, speedRotatingPart);
531 end
532 return true;
533end

doCheckSpeedLimit

Description
Returns if speed limit should be checked
Definition
doCheckSpeedLimit()
Return Values
booleancheckSpeedlimitcheck speed limit
Code
538function TreePlanter:doCheckSpeedLimit(superFunc)
539 local parent = false;
540 if superFunc ~= nil then
541 parent = superFunc(self);
542 end
543
544 return parent or self.treePlanterHasGroundContact; --self.isTreePlanterSpeedLimitActive;
545end

getSaveAttributesAndNodes

Description
Returns attributes and nodes to save
Definition
getSaveAttributesAndNodes(table nodeIdent, table usedModNames)
Arguments
tablenodeIdentnode ident
tableusedModNamesused mod names
Return Values
stringattributesattributes
stringnodesnodes
Code
553function TreePlanter:getSaveAttributesAndNodes(nodeIdent, usedModNames)
554 local attributes = '';
555 local nodes = '';
556 if self.lastTreePos ~= nil then
557 attributes = 'lastTreePos="'..self.lastTreePos[1]..' ' .. self.lastTreePos[2] .. ' ' .. self.lastTreePos[3] ..'"';
558 end
559 if self.mountedSaplingPallet ~= nil then
560 local modExtra = "";
561 local modName = self.mountedSaplingPallet.customEnvironment;
562 local classModName = getClassModName(self.mountedSaplingPallet.className);
563 if modName == nil then
564 modName = classModName;
565 end
566 if modName ~= nil then
567 if usedModNames ~= nil then
568 usedModNames[modName] = modName;
569 end
570 modExtra = ' modName="'..modName..'"';
571 end
572 if classModName ~= nil then
573 if usedModNames ~= nil then
574 usedModNames[classModName] = classModName;
575 end
576 end
577 nodes = nodeIdent..'<pallet className="'..self.mountedSaplingPallet.className..'"'..modExtra;
578 local palletAttributes, palletNodes = self.mountedSaplingPallet:getSaveAttributesAndNodes(nodeIdent.." ", usedModNames);
579 if palletAttributes ~= nil and palletAttributes ~= "" then
580 nodes = nodes.." "..palletAttributes;
581 end
582 if palletNodes ~= nil and palletNodes ~= "" then
583 nodes = nodes..">\n"..palletNodes.."\n"..nodeIdent.."</pallet>\n";
584 else
585 nodes = nodes..'/>';
586 end
587 end
588 return attributes, nodes;
589end

getDoGroundManipulation

Description
Returns if tool does ground manipulation
Definition
getDoGroundManipulation()
Return Values
booleandoGroundManipulationdo ground manipulation
Code
594function TreePlanter:getDoGroundManipulation(supreFunc)
595 if not self:getIsTurnedOn() then
596 return false;
597 end
598 if superFunc ~= nil then
599 return superFunc(self);
600 end
601 return true;
602end

getDefaultSpeedLimit

Description
Returns default speed limit
Definition
getDefaultSpeedLimit()
Return Values
floatspeedLimitspeed limit
Code
607function TreePlanter.getDefaultSpeedLimit()
608 return 5;
609end

getSaplingPalletInRange

Description
Returns nearest sapling pallet in range
Definition
getSaplingPalletInRange(integer refNode)
Arguments
integerrefNodeid of reference node
Return Values
tableobjectobject of sapling pallet
Code
615function TreePlanter.getSaplingPalletInRange(self, refNode)
616 local px, py, pz = getWorldTranslation(refNode);
617 local nearestDistance = self.nearestPalletDistance;
618 local nearestSaplingPallet = nil;
619
620 for _, item in pairs(g_currentMission.itemsToSave) do
621 local object = item.item;
622 local validPallet = false;
623 validPallet = object:isa(SaplingPallet);
624 if not validPallet then
625 if object:isa(FillablePallet) then
626 local fillTypeAvailable = object:getFillType();
627 for fillType,state in pairs(self.fillUnits[self.treePlanter.fillUnitIndex].fillTypes) do
628 if state and fillType == fillTypeAvailable then
629 if object:getFillLevel() > 0 then
630 validPallet = true;
631 break;
632 end
633 end
634 end
635 end
636 end
637 if validPallet then
638 local vx, vy, vz = getWorldTranslation(object.nodeId);
639 local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);
640 if distance < nearestDistance then
641 nearestSaplingPallet = object;
642 end
643 end
644 end
645 return nearestSaplingPallet;
646end