LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

Tedder

Description
Class for all Tedders
Functions

initSpecialization

Description
Called on specialization initializing
Definition
initSpecialization()
Code
18function Tedder.initSpecialization()
19 WorkArea.registerAreaType("tedder");
20 WorkArea.registerAreaType("tedderDrop");
21end;

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
27function Tedder.prerequisitesPresent(specializations)
28 return SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations);
29end;

preLoad

Description
Called before loading
Definition
preLoad(table savegame)
Arguments
tablesavegamesavegame
Code
34function Tedder:preLoad(savegame)
35 self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Tedder.loadWorkAreaFromXML);
36end

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
41function Tedder:load(savegame)
42
43 self.getDirtMultiplier = Utils.overwrittenFunction(self.getDirtMultiplier, Tedder.getDirtMultiplier);
44 self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Tedder.doCheckSpeedLimit);
45
46 self.processTedderAreas = Tedder.processTedderAreas;
47
48 self.tedderTurnedOnRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "tedder", self.components);
49
50 if hasXMLProperty(self.xmlFile, "vehicle.rotors") then
51 print("Warning: vehicle.rotors are not supported anymore, use vehicle.turnedOnRotationNodes.turnedOnRotationNode (type: tedder) instead");
52 end;
53
54 local numTedderDropAreas = table.getn(self:getTypedWorkAreas(WorkArea.AREATYPE_TEDDERDROP));
55 if numTedderDropAreas == 0 then
56 print("Warning: No drop work areas specified in '"..self.configFileName.."'");
57 else
58 if numTedderDropAreas ~= 1 and numTedderDropAreas ~= table.getn(self:getTypedWorkAreas(WorkArea.AREATYPE_TEDDER)) then
59 print("Warning: Number of work areas and drop work areas should be equal in '"..self.configFileName.."'");
60 end;
61 end;
62
63 self.tedderParticleSystems = {}
64 local i=0;
65 while true do
66 local key = string.format("vehicle.tedderParticleSystems.emitterShape(%d)", i);
67 if not hasXMLProperty(self.xmlFile, key) then
68 break
69 end
70 local emitterShape = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node"));
71 local particleType = getXMLString(self.xmlFile, key.."#particleType")
72 if emitterShape ~= nil then
73 local particleSystem = MaterialUtil.getParticleSystem(FillUtil.FILLTYPE_DRYGRASS_WINDROW, particleType)
74 if particleSystem ~= nil then
75 local currentPS = ParticleUtil.copyParticleSystem(self.xmlFile, key, particleSystem, emitterShape)
76 currentPS.disableTime = 0;
77 currentPS.isEnabled = false;
78 table.insert(self.tedderParticleSystems, currentPS)
79 end
80 end
81
82 i=i+1;
83 end
84
85 if self.isClient then
86 self.sampleTedder = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.tedderSound", nil, self.baseDirectory);
87 end;
88
89 self.isTedderSpeedLimitActive = false;
90
91 self.showFieldNotOwnedWarning = false
92
93 local desc = FruitUtil.fruitTypes["grass"];
94 self.aiRequiredFruitType = desc.index;
95 self.aiRequiredMinGrowthState = 0;
96 self.aiRequiredMaxGrowthState = g_currentMission.numWindrowChannels;
97 self.aiUseDensityHeightMap = true;
98 self.aiUseWindrowFruitType = true;
99
100 table.insert(self.terrainDetailRequiredValueRanges, {g_currentMission.grassValue, g_currentMission.grassValue, g_currentMission.terrainDetailTypeFirstChannel, g_currentMission.terrainDetailTypeNumChannels});
101
102 self.tedderDirtyFlag = self:getNextDirtyFlag();
103end;

delete

Description
Called on deleting
Definition
delete()
Code
107function Tedder:delete()
108 ParticleUtil.deleteParticleSystems(self.tedderParticleSystems)
109
110 if self.isClient then
111 SoundUtil.deleteSample(self.sampleTedder);
112 end;
113end;

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
119function Tedder:readStream(streamId, connection)
120 for _, ps in ipairs(self.tedderParticleSystems) do
121 ParticleUtil.setEmittingState(ps, streamReadBool(streamId));
122 end
123end;

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
129function Tedder:writeStream(streamId, connection)
130 for _, ps in ipairs(self.tedderParticleSystems) do
131 streamWriteBool(streamId, ps.isEnabled);
132 end
133end;

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
140function Tedder:readUpdateStream(streamId, timestamp, connection)
141 if connection:getIsServer() then
142 if streamReadBool(streamId) then
143 for _, ps in ipairs(self.tedderParticleSystems) do
144 ParticleUtil.setEmittingState(ps, streamReadBool(streamId));
145 end
146 self.showFieldNotOwnedWarning = streamReadBool(streamId)
147 end
148 end
149end;

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
156function Tedder:writeUpdateStream(streamId, connection, dirtyMask)
157 if not connection:getIsServer() then
158 if streamWriteBool(streamId, bitAND(dirtyMask, self.tedderDirtyFlag) ~= 0) then
159 for _, ps in ipairs(self.tedderParticleSystems) do
160 streamWriteBool(streamId, ps.isEnabled);
161 end
162 streamWriteBool(streamId, self.showFieldNotOwnedWarning)
163 end
164 end
165end;

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
176function Tedder:update(dt)
177 if self.isClient then
178 Utils.updateRotationNodes(self, self.tedderTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn());
179 end;
180end;

updateTick

Description
Called on update tick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
185function Tedder:updateTick(dt)
186 local showFieldNotOwnedWarning = false
187 self.isTedderSpeedLimitActive = false;
188 self.isWorking = false;
189 if self:getIsActive() then
190 local hasGroundContact, typedWorkAreas = self:getIsTypedWorkAreaActive(WorkArea.AREATYPE_TEDDER);
191 self.hasGroundContact = hasGroundContact;
192
193 if self.hasGroundContact then
194 if self:getIsTurnedOn() then
195 self.isTedderSpeedLimitActive = true;
196 if self.isServer then
197 local workAreas = {};
198 local typedWorkAreasDrop, showWarning = self:getTypedNetworkAreas(WorkArea.AREATYPE_TEDDERDROP, true);
199 showFieldNotOwnedWarning = showWarning;
200
201 if not showWarning then
202 for k, workArea in pairs(typedWorkAreas) do
203 if self:getIsWorkAreaActive(workArea) then
204 local x,_,z = getWorldTranslation(workArea.start);
205 local x1,_,z1 = getWorldTranslation(workArea.width);
206 local x2,_,z2 = getWorldTranslation(workArea.height);
207
208 local dropArea = typedWorkAreasDrop[workArea.dropAreaIndex];
209 local dx, dz = dropArea[1], dropArea[2];
210 local dx1, dz1 = dropArea[3], dropArea[4];
211 local dx2, dz2 = dropArea[5], dropArea[6];
212
213 table.insert(workAreas, {x,z, x1,z1, x2,z2, dx,dz, dx1,dz1, dx2,dz2, 0, k});
214 end;
215 end;
216 if (table.getn(workAreas) > 0) then
217 local usedWorkAreas = self:processTedderAreas(workAreas, self.accumulatedWorkAreaValues);
218 if (table.getn(usedWorkAreas) > 0) then
219 self.isWorking = true;
220 if self:getLastSpeed(true) > 0.5 then
221 for i=1, table.getn(usedWorkAreas) do
222 local workArea = typedWorkAreas[usedWorkAreas[i][14]];
223 if workArea.tedderParticleSystemIndex ~= nil then
224 local ps = self.tedderParticleSystems[workArea.tedderParticleSystemIndex+1]
225 if ps ~= nil then
226 ps.disableTime = g_currentMission.time + 300;
227 if not ps.isEnabled then
228 ps.isEnabled = true;
229 self:raiseDirtyFlags(self.tedderDirtyFlag);
230 if self.isClient then
231 ParticleUtil.setEmittingState(ps, true);
232 end;
233 end;
234 end;
235 end;
236 end;
237 end;
238 end;
239 end;
240
241 end;
242 end;
243 end;
244 end;
245 if self.isServer then
246 for _, ps in pairs(self.tedderParticleSystems) do
247 if g_currentMission.time > ps.disableTime then
248 if ps.isEnabled then
249 ps.isEnabled = false;
250 self:raiseDirtyFlags(self.tedderDirtyFlag);
251 if self.isClient then
252 ParticleUtil.setEmittingState(ps, false);
253 end;
254 end;
255 end;
256 end;
257 end;
258
259 if self:getIsTurnedOn() then
260 if self.isClient and self:getIsActiveForSound() then
261 SoundUtil.playSample(self.sampleTedder, 0, 0, nil);
262 end;
263 end;
264 end;
265
266 if self.isServer then
267 if showFieldNotOwnedWarning ~= self.showFieldNotOwnedWarning then
268 self.showFieldNotOwnedWarning = showFieldNotOwnedWarning
269 self:raiseDirtyFlags(self.tedderDirtyFlag);
270 end
271 end
272end;

draw

Description
Called on draw
Definition
draw()
Code
276function Tedder:draw()
277 if self.isClient then
278 if self.showFieldNotOwnedWarning then
279 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_youDontOwnThisField"))
280 end
281 end
282end;

onDeactivate

Description
Called on deactivate
Definition
onDeactivate()
Code
286function Tedder:onDeactivate()
287 if self.isClient then
288 for _, ps in pairs(self.tedderParticleSystems) do
289 ps.isEnabled = false;
290 ParticleUtil.setEmittingState(ps, false);
291 end;
292 end;
293end;

onDeactivateSounds

Description
Called on deactivating sounds
Definition
onDeactivateSounds()
Code
297function Tedder:onDeactivateSounds()
298 if self.isClient then
299 SoundUtil.stopSample(self.sampleTedder, true);
300 end;
301end;

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
306function Tedder:onTurnedOff(noEventSend)
307 Tedder.onDeactivateSounds(self)
308end;

getDirtMultiplier

Description
Returns current dirt multiplier
Definition
getDirtMultiplier()
Return Values
floatdirtMultipliercurrent dirt multiplier
Code
313function Tedder:getDirtMultiplier(superFunc)
314 local multiplier = 0;
315 if superFunc ~= nil then
316 multiplier = multiplier + superFunc(self);
317 end;
318
319 if self.isWorking then
320 multiplier = multiplier + self.workMultiplier * self:getLastSpeed() / self.speedLimit;
321 end;
322
323 return multiplier;
324end;

loadWorkAreaFromXML

Description
Loads work areas from xml
Definition
loadWorkAreaFromXML(table workArea, integer xmlFile, string key)
Arguments
tableworkAreaworkArea
integerxmlFileid of xml object
stringkeykey
Return Values
booleansuccesssuccess
Code
332function Tedder:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
333 local retValue = true;
334 if superFunc ~= nil then
335 retValue = superFunc(self, workArea, xmlFile, key)
336 end
337
338 if workArea.type == WorkArea.AREATYPE_DEFAULT then
339 workArea.type = WorkArea.AREATYPE_TEDDER;
340 end;
341
342 if workArea.type == WorkArea.AREATYPE_TEDDER then
343 workArea.tedderParticleSystemIndex = getXMLInt(xmlFile, key .. "#particleSystemIndex");
344 workArea.dropAreaIndex = Utils.getNoNil(getXMLInt(xmlFile, key .. "#dropAreaIndex"), 0) + 1;
345
346 if self.accumulatedWorkAreaValues == nil then
347 self.accumulatedWorkAreaValues = {};
348 end;
349 self.accumulatedWorkAreaValues[table.getn(self.accumulatedWorkAreaValues)+1] = 0;
350 end;
351
352 return retValue;
353end;

doCheckSpeedLimit

Description
Returns if speed limit should be checked
Definition
doCheckSpeedLimit()
Return Values
booleancheckSpeedlimitcheck speed limit
Code
358function Tedder:doCheckSpeedLimit(superFunc)
359 local parent = false;
360 if superFunc ~= nil then
361 parent = superFunc(self);
362 end
363
364 return parent or self.isTedderSpeedLimitActive;
365end;

getDefaultSpeedLimit

Description
Returns default speed limit
Definition
getDefaultSpeedLimit()
Return Values
floatspeedLimitspeed limit
Code
370function Tedder.getDefaultSpeedLimit()
371 return 15;
372end;

processTedderAreas

Description
Process tedder areas
Definition
processTedderAreas(table workAreas, table accumulatedWorkAreaValues)
Arguments
tableworkAreaswork areas to process
tableaccumulatedWorkAreaValuescontains remaining liters to drop for every work area
Return Values
tableretWorkAreascontains work areas that dropped something
Code
379function Tedder:processTedderAreas(workAreas, accumulatedWorkAreaValues)
380
381 local numAreas = table.getn(workAreas);
382
383 local retWorkAreas = {};
384 for i=1, numAreas do
385 local x0 = workAreas[i][1];
386 local z0 = workAreas[i][2];
387 local x1 = workAreas[i][3];
388 local z1 = workAreas[i][4];
389 local x2 = workAreas[i][5];
390 local z2 = workAreas[i][6];
391 local dx0 = workAreas[i][7];
392 local dz0 = workAreas[i][8];
393 local dx1 = workAreas[i][9];
394 local dz1 = workAreas[i][10];
395 local dx2 = workAreas[i][11];
396 local dz2 = workAreas[i][12];
397
398 -- pick up
399 local hx = x2 - x0;
400 local hz = z2 - z0;
401 local hLength = Utils.vector2Length(hx, hz);
402 local hLength_2 = 0.5 * hLength;
403
404 local wx = x1 - x0;
405 local wz = z1 - z0;
406 local wLength = Utils.vector2Length(wx, wz);
407
408 local sx = x0 + (hx * 0.5) + ((wx/wLength)*hLength_2);
409 local sz = z0 + (hz * 0.5) + ((wz/wLength)*hLength_2);
410
411 local ex = x1 + (hx * 0.5) - ((wx/wLength)*hLength_2);
412 local ez = z1 + (hz * 0.5) - ((wz/wLength)*hLength_2);
413
414 local sy = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, sx,0,sz);
415 local ey = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, ex,0,ez);
416
417 local fillType1 = FruitUtil.fruitTypeToWindrowFillType[FruitUtil.FRUITTYPE_GRASS];
418 local liters1 = TipUtil.tipToGroundAroundLine(self, -math.huge, fillType1, sx,sy,sz, ex,ey,ez, hLength_2, nil, nil, false, nil);
419
420 local fillType2 = FruitUtil.fruitTypeToWindrowFillType[FruitUtil.FRUITTYPE_DRYGRASS];
421 local liters2 = TipUtil.tipToGroundAroundLine(self, -math.huge, fillType2, sx,sy,sz, ex,ey,ez, hLength_2, nil, nil, false, nil);
422
423 local liters = -liters1 - liters2;
424
425 -- drop
426 local hx = dx2 - dx0;
427 local hz = dz2 - dz0;
428 local hLength = Utils.vector2Length(hx, hz);
429 local hLength_2 = 0.5 * hLength;
430
431 local wx = dx1 - dx0;
432 local wz = dz1 - dz0;
433 local wLength = Utils.vector2Length(wx, wz);
434
435 local sx = dx0 + (hx * 0.5) + ((wx/wLength)*hLength_2);
436 local sz = dz0 + (hz * 0.5) + ((wz/wLength)*hLength_2);
437
438 local ex = dx1 + (hx * 0.5) - ((wx/wLength)*hLength_2);
439 local ez = dz1 + (hz * 0.5) - ((wz/wLength)*hLength_2);
440
441 local sy = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, sx,0,sz);
442 local ey = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, ex,0,ez);
443
444 local toDrop = accumulatedWorkAreaValues[i] + liters;
445 local dropped, lineOffset = TipUtil.tipToGroundAroundLine(self, toDrop, FruitUtil.fruitTypeToWindrowFillType[FruitUtil.FRUITTYPE_DRYGRASS], sx,sy,sz, ex,ey,ez, hLength_2, nil, self.tedderLineOffset, false, nil, false);
446 self.tedderLineOffset = lineOffset;
447 local remain = toDrop - dropped;
448
449 accumulatedWorkAreaValues[i] = remain;
450 workAreas[i][13] = remain;
451
452 if liters > remain then
453 table.insert(retWorkAreas, workAreas[i]);
454 end
455
456 end;
457 return retWorkAreas;
458end