Sprache Deutsch Language English

Script Dokumentation LS 2015 - Plough (Patch 1.3)

Script Dokumentation Übersicht

scripts/vehicles/specializations/Plough.lua

Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1--
2-- Plough
3-- This is the specialization for ploughs
4--
5-- @author Stefan Geiger
6-- @date 30/11/08
7--
8-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
9
10Plough = {};
11source("dataS/scripts/vehicles/specializations/PloughRotationEvent.lua");
12source("dataS/scripts/vehicles/specializations/PloughLimitToFieldEvent.lua");
13source("dataS/scripts/vehicles/specializations/PloughAreaEvent.lua");
14
15function Plough.initSpecialization()
16 WorkArea.registerAreaType("plough");
17end;
18
19function Plough.prerequisitesPresent(specializations)
20 return SpecializationUtil.hasSpecialization(WorkArea, specializations);
21end
22
23function Plough:preLoad(xmlFile)
24 self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, Plough.loadSpeedRotatingPartFromXML);
25 self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Plough.loadWorkAreaFromXML);
26end
27
28function Plough:load(xmlFile)
29 self.setRotationMax = SpecializationUtil.callSpecializationsFunction("setRotationMax");
30 self.setPloughLimitToField = Plough.setPloughLimitToField;
31 self.getIsPloughRotationAllowed = Plough.getIsPloughRotationAllowed;
32 self.getIsFoldAllowed = Utils.overwrittenFunction(self.getIsFoldAllowed, Plough.getIsFoldAllowed);
33 self.getIsFoldMiddleAllowed = Utils.overwrittenFunction(self.getIsFoldMiddleAllowed, Plough.getIsFoldMiddleAllowed);
34 self.getDirtMultiplier = Utils.overwrittenFunction(self.getDirtMultiplier, Plough.getDirtMultiplier);
35 self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, Plough.getIsSpeedRotatingPartActive);
36 self.getSpeedRotatingPartDirection = Utils.overwrittenFunction(self.getSpeedRotatingPartDirection, Plough.getSpeedRotatingPartDirection);
37 self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Plough.doCheckSpeedLimit);
38
39 if next(self.groundReferenceNodes) == nil then
40 print("Warning: No ground reference nodes in "..self.configFileName);
41 end
42
43 self.rotationPart = {};
44 self.rotationPart.turnAnimation = getXMLString(xmlFile, "vehicle.rotationPart#turnAnimationName");
45 self.rotationPart.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotationPart#foldMinLimit"), 0);
46 self.rotationPart.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotationPart#foldMaxLimit"), 1);
47 self.rotationPart.limitFoldRotationMax = getXMLBool(xmlFile, "vehicle.rotationPart#limitFoldRotationMax");
48 self.rotationPart.foldRotationMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotationPart#foldRotationMinLimit"), 0);
49 self.rotationPart.foldRotationMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotationPart#foldRotationMaxLimit"), 1);
50 self.rotationPart.rotationFoldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotationPart#rotationFoldMinLimit"), 0);
51 self.rotationPart.rotationFoldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotationPart#rotationFoldMaxLimit"), 1);
52
53 self.ploughDirectionNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.ploughDirectionNode#index")), self.components[1].node);
54
55 if self.isClient then
56 self.samplePloughTurn = Utils.loadSample(xmlFile, {}, "vehicle.ploughTurnSound", nil, self.baseDirectory);
57 self.samplePlough = Utils.loadSample(xmlFile, {}, "vehicle.ploughSound", nil, self.baseDirectory);
58 end;
59
60 self.aiTerrainDetailChannel1 = g_currentMission.sowingChannel;
61 self.aiTerrainDetailChannel2 = g_currentMission.cultivatorChannel;
62 self.aiTerrainDetailChannel3 = g_currentMission.sowingWidthChannel;
63
64 self.rotateLeftToMax = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.rotateLeftToMax#value"), true);
65
66 self.onlyActiveWhenLowered = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.onlyActiveWhenLowered#value"), true);
67
68 self.ploughHasGroundContact = false;
69 self.rotationMax = false;
70 self.ploughContactReportsActive = false;
71 self.startActivationTimeout = 2000;
72 self.startActivationTime = 0;
73 self.lastPloughArea = 0;
74
75 self.ploughLimitToField = true;
76 self.forcePloughLimitToField = false;
77
78 self.showFieldNotOwnedWarning = false;
79 self.isPloughSpeedLimitActive = false;
80 self.wasTurnAnimationStopped = false;
81
82 self.isPloughLowered = false;
83
84 self.ploughGroundContactFlag = self:getNextDirtyFlag();
85end
86
87function Plough:delete()
88 if self.isClient then
89 Utils.deleteSample(self.samplePlough);
90 Utils.deleteSample(self.samplePloughTurn);
91 end;
92end
93
94function Plough:readStream(streamId, connection)
95 local rotationMax = streamReadBool(streamId);
96 local rotationAllowed = streamReadBool(streamId);
97 if rotationAllowed then
98 self:setRotationMax(rotationMax, true);
99 if self.rotationPart.turnAnimation ~= nil and self.playAnimation ~= nil then
100 local turnAnimTime = streamReadFloat32(streamId);
101 self:setAnimationTime(self.rotationPart.turnAnimation, turnAnimTime);
102
103 if self.updateCylinderedInitial ~= nil then
104 self:updateCylinderedInitial(false);
105 end
106 end
107 else
108 self.rotationMax = rotationMax;
109 end
110end
111
112function Plough:writeStream(streamId, connection)
113 streamWriteBool(streamId, self.rotationMax);
114 if streamWriteBool(streamId, self:getIsPloughRotationAllowed()) then
115 if self.rotationPart.turnAnimation ~= nil and self.playAnimation ~= nil then
116 local turnAnimTime = self:getAnimationTime(self.rotationPart.turnAnimation);
117 streamWriteFloat32(streamId, turnAnimTime);
118 end
119 end
120end
121
122function Plough:readUpdateStream(streamId, timestamp, connection)
123 if connection:getIsServer() then
124 self.ploughHasGroundContact = streamReadBool(streamId);
125 self.showFieldNotOwnedWarning = streamReadBool(streamId);
126 end
127end
128
129function Plough:writeUpdateStream(streamId, connection, dirtyMask)
130 if not connection:getIsServer() then
131 streamWriteBool(streamId, self.ploughHasGroundContact);
132 streamWriteBool(streamId, self.showFieldNotOwnedWarning);
133 end
134end
135
136function Plough:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
137 if not resetVehicles then
138 local rotationMax = getXMLBool(xmlFile, key.."#ploughRotationMax");
139 if rotationMax ~= nil then
140 if self:getIsPloughRotationAllowed() then
141 self:setRotationMax(rotationMax, true);
142 if self.rotationPart.turnAnimation ~= nil and self.playAnimation ~= nil then
143 local turnAnimTime = getXMLFloat(xmlFile, key.."#ploughTurnAnimTime");
144 if turnAnimTime ~= nil then
145 self:setAnimationTime(self.rotationPart.turnAnimation, turnAnimTime);
146
147 if self.updateCylinderedInitial ~= nil then
148 self:updateCylinderedInitial(false);
149 end
150 end
151 end
152 end
153 end
154 end
155
156 return BaseMission.VEHICLE_LOAD_OK;
157end;
158
159function Plough:getSaveAttributesAndNodes(nodeIdent)
160 local attributes = 'ploughRotationMax="'..tostring(self.rotationMax)..'"';
161 if self.rotationPart.turnAnimation ~= nil and self.playAnimation ~= nil then
162 local turnAnimTime = self:getAnimationTime(self.rotationPart.turnAnimation);
163 attributes = attributes..' ploughTurnAnimTime="'..turnAnimTime..'"';
164 end
165 local nodes = "";
166 return attributes, nodes;
167end;
168
169function Plough:mouseEvent(posX, posY, isDown, isUp, button)
170end
171
172function Plough:keyEvent(unicode, sym, modifier, isDown)
173end
174
175function Plough:update(dt)
176 if self:getIsActiveForInput() then
177 if self.rotationPart.turnAnimation ~= nil then
178 if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
179 if self:getIsPloughRotationAllowed() then
180 self:setRotationMax(not self.rotationMax);
181 end
182 end
183 end;
184 if not self.forcePloughLimitToField then
185 if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then
186 self:setPloughLimitToField(not self.ploughLimitToField);
187 end
188 end;
189 end
190end
191
192function Plough:updateTick(dt)
193 self.isPloughSpeedLimitActive = false;
194 if self:getIsActive() then
195 self.lastPloughArea = 0;
196 local showFieldNotOwnedWarning = false;
197
198 if self.isServer then
199 local hasGroundContact = self:getIsTypedWorkAreaActive(WorkArea.AREATYPE_PLOUGH);
200 if self.ploughHasGroundContact ~= hasGroundContact then
201 self:raiseDirtyFlags(self.ploughGroundContactFlag);
202 end
203 self.ploughHasGroundContact = hasGroundContact;
204 end
205 local hasGroundContact = self.ploughHasGroundContact;
206
207 if hasGroundContact then
208 if self.startActivationTime <= g_currentMission.time then
209 self.isPloughSpeedLimitActive = true;
210 if self.isServer then
211 if not self.onlyActiveWhenLowered or self:isLowered(false) then
212 --if not self.onlyActiveWhenLowered then --or self.isPloughLowered then
213 local workAreasSend, showWarning, _ = self:getTypedNetworkAreas(WorkArea.AREATYPE_PLOUGH, true);
214 showFieldNotOwnedWarning = showWarning;
215
216 if (table.getn(workAreasSend) > 0) then
217 local limitToField = self.ploughLimitToField or self.forcePloughLimitToField;
218 local limitGrassDestructionToField = self.ploughLimitToField or self.forcePloughLimitToField;
219 if not g_currentMission:getHasPermission("createFields", self:getOwner()) then
220 limitToField = true;
221 limitGrassDestructionToField = true;
222 end;
223
224 local dx,_,dz = localDirectionToWorld(self.ploughDirectionNode, 0, 0, 1);
225 local angle = Utils.convertToDensityMapAngle(Utils.getYRotationFromDirection(dx, dz), g_currentMission.terrainDetailAngleMaxValue);
226
227 local realArea = PloughAreaEvent.runLocally(workAreasSend, limitToField, limitGrassDestructionToField, angle);
228 g_server:broadcastEvent(PloughAreaEvent:new(workAreasSend, limitToField, limitGrassDestructionToField, angle));
229
230 self.lastPloughArea = Utils.areaToHa(realArea, g_currentMission:getFruitPixelsToSqm()); -- 4096px are mapped to 2048m
231 g_currentMission.missionStats:updateStats("hectaresWorked", self.lastPloughArea);
232 end
233 end
234 end
235 g_currentMission.missionStats:updateStats("workingDuration", dt/(1000*60));
236 end
237
238 if self.isClient and self:getLastSpeed() > 3 and self:getIsActiveForSound() then
239 Utils.playSample(self.samplePlough, 0, 0, nil);
240 else
241 Utils.stopSample(self.samplePlough);
242 end
243 else
244 if self.isClient then
245 Utils.stopSample(self.samplePlough);
246 end;
247 end
248
249 if self.rotationPart.turnAnimation ~= nil then
250 if self.isClient then
251 if self:getIsAnimationPlaying(self.rotationPart.turnAnimation) and self:getIsActiveForSound() then
252 Utils.playSample(self.samplePloughTurn, 0, 0, nil);
253 else
254 Utils.stopSample(self.samplePloughTurn);
255 end
256 end
257 end
258
259 if self.isServer then
260 if showFieldNotOwnedWarning ~= self.showFieldNotOwnedWarning then
261 self.showFieldNotOwnedWarning = showFieldNotOwnedWarning;
262 self:raiseDirtyFlags(self.ploughGroundContactFlag);
263 end
264 end
265
266 -- ToDo: move this to server side and create a flag to be transmited to the client
267 --[[
268 self.isPloughLowered = false;
269 if self.attacherVehicle ~= nil then
270 local implement = self.attacherVehicle:getImplementByObject(self);
271 if implement ~= nil then
272 local jointDesc = self.attacherVehicle.attacherJoints[implement.jointDescIndex];
273 --print(tostring(jointDesc.moveAlpha).." "..tostring(jointDesc.upperAlpha));
274 if jointDesc.moveAlpha == jointDesc.upperAlpha then
275
276 local allowLowering = true;
277 local turnAnimTime = self:getAnimationTime(self.rotationPart.turnAnimation);
278 if turnAnimTime ~= self.turnAnimTime then
279 self.turnAnimTime = turnAnimTime;
280 allowLowering = false;
281 end;
282 if self.foldAnimTime ~= self.lastFoldAnimTime then
283 self.lastFoldAnimTime = self.foldAnimTime
284 allowLowering = false;
285 end;
286 jointDesc.allowsLowering = allowLowering;
287
288 self.isPloughLowered = false;
289 else
290 self.isPloughLowered = true;
291 end;
292
293 end;
294 end;
295 ]]--
296
297 end
298end
299
300function Plough:draw()
301 if self:getIsActiveForInput(true) then
302 if self.rotationPart.turnAnimation ~= nil then
303 if self:getIsPloughRotationAllowed() then
304 g_currentMission:addHelpButtonText(g_i18n:getText("Turn_plough"), InputBinding.IMPLEMENT_EXTRA);
305 end
306 end;
307
308 if not self.forcePloughLimitToField then
309 if self.ploughLimitToField then
310 g_currentMission:addHelpButtonText(g_i18n:getText("allow_create_fields"), InputBinding.IMPLEMENT_EXTRA3);
311 else
312 g_currentMission:addHelpButtonText(g_i18n:getText("limit_to_fields"), InputBinding.IMPLEMENT_EXTRA3);
313 end
314 end;
315 end
316
317 if self.showFieldNotOwnedWarning then
318 g_currentMission:showBlinkingWarning(g_i18n:getText("You_dont_own_this_field"));
319 end
320end
321
322function Plough:onAttach(attacherVehicle)
323 Plough.onActivate(self);
324 self.startActivationTime = g_currentMission.time + self.startActivationTimeout;
325 if self.wasTurnAnimationStopped then
326 local dir = 1;
327 if not self.rotationMax then
328 dir = -1;
329 end;
330 self:playAnimation(self.rotationPart.turnAnimation, dir, self:getAnimationTime(self.rotationPart.turnAnimation), true);
331 self.wasTurnAnimationStopped = false;
332 end;
333end
334
335function Plough:onDetach()
336 self.ploughLimitToField = true;
337 if self:getIsAnimationPlaying(self.rotationPart.turnAnimation) then
338 self:stopAnimation(self.rotationPart.turnAnimation, true);
339 self.wasTurnAnimationStopped = true;
340 end;
341end
342
343function Plough:onActivate()
344end
345
346function Plough:onDeactivate()
347 self.showFieldNotOwnedWarning = false;
348end
349
350function Plough:onDeactivateSounds()
351 if self.isClient then
352 Utils.stopSample(self.samplePlough, true);
353 Utils.stopSample(self.samplePloughTurn, true);
354 end;
355end
356
357function Plough:aiRotateLeft(force)
358 if self:getIsPloughRotationAllowed() or force then
359 self:setRotationMax(self.rotateLeftToMax, true);
360 end
361end
362
363function Plough:aiRotateRight(force)
364 if self:getIsPloughRotationAllowed() or force then
365 self:setRotationMax(not self.rotateLeftToMax, true);
366 end
367end
368
369function Plough:aiTurnOn()
370 self.ploughLimitToField = true;
371end
372
373function Plough:aiTurnOff()
374end
375
376function Plough:aiInvertsMarkerOnTurn(turnLeft)
377 if turnLeft then
378 return self.rotationMax ~= self.rotateLeftToMax;
379 else
380 return self.rotationMax == self.rotateLeftToMax;
381 end
382end
383
384function Plough:setRotationMax(rotationMax, noEventSend)
385 if noEventSend == nil or noEventSend == false then
386 if g_server ~= nil then
387 g_server:broadcastEvent(PloughRotationEvent:new(self, rotationMax), nil, nil, self);
388 else
389 g_client:getServerConnection():sendEvent(PloughRotationEvent:new(self, rotationMax));
390 end
391 end
392 self.rotationMax = rotationMax;
393
394 if self.rotationPart.turnAnimation ~= nil then
395 local animTime = self:getAnimationTime(self.rotationPart.turnAnimation);
396 if self.rotationMax then
397 self:playAnimation(self.rotationPart.turnAnimation, 1, animTime, true);
398 else
399 self:playAnimation(self.rotationPart.turnAnimation, -1, animTime, true);
400 end
401 end
402end
403
404function Plough:setPloughLimitToField(ploughLimitToField, noEventSend)
405 if self.ploughLimitToField ~= ploughLimitToField then
406 if noEventSend == nil or noEventSend == false then
407 if g_server ~= nil then
408 g_server:broadcastEvent(PloughLimitToFieldEvent:new(self, ploughLimitToField), nil, nil, self);
409 else
410 g_client:getServerConnection():sendEvent(PloughLimitToFieldEvent:new(self, ploughLimitToField));
411 end
412 end
413 self.ploughLimitToField = ploughLimitToField;
414 end
415end
416
417function Plough:getIsPloughRotationAllowed()
418 --if self.isPloughLowered then
419 -- return false;
420 --end;
421 local foldAnimTime = self.foldAnimTime;
422 if foldAnimTime ~= nil and (foldAnimTime > self.rotationPart.rotationFoldMaxLimit or foldAnimTime < self.rotationPart.rotationFoldMinLimit) then
423 return false;
424 end
425 if superFunc ~= nil then
426 return superFunc(self);
427 end
428 return true;
429end
430
431function Plough:getIsFoldAllowed(superFunc)
432 --if self.isPloughLowered then
433 -- return false;
434 --end;
435 if self.rotationPart.limitFoldRotationMax ~= nil and self.rotationPart.limitFoldRotationMax == self.rotationMax then
436 return false;
437 end
438 if self.rotationPart.turnAnimation ~= nil and self.getAnimationTime ~= nil then
439 local rotationTime = self:getAnimationTime(self.rotationPart.turnAnimation);
440 if rotationTime > self.rotationPart.foldRotationMaxLimit or rotationTime < self.rotationPart.foldRotationMinLimit then
441 return false;
442 end
443 end
444 if superFunc ~= nil then
445 return superFunc(self);
446 end
447 return true;
448end
449
450function Plough:getIsFoldMiddleAllowed(superFunc)
451 --if self.isPloughLowered then
452 -- return false;
453 --end;
454 if self.rotationPart.limitFoldRotationMax ~= nil and self.rotationPart.limitFoldRotationMax == self.rotationMax then
455 return false;
456 end
457 if self.rotationPart.turnAnimation ~= nil and self.getAnimationTime ~= nil then
458 local rotationTime = self:getAnimationTime(self.rotationPart.turnAnimation);
459 if rotationTime > self.rotationPart.foldRotationMaxLimit or rotationTime < self.rotationPart.foldRotationMinLimit then
460 return false;
461 end
462 end
463 if superFunc ~= nil then
464 return superFunc(self);
465 end
466 return true;
467end
468
469function Plough:getDirtMultiplier(superFunc)
470 local multiplier = 0;
471 if superFunc ~= nil then
472 multiplier = multiplier + superFunc(self);
473 end;
474
475 if self.ploughHasGroundContact then
476 multiplier = multiplier + self.workMultiplier * self:getLastSpeed() / self.speedLimit;
477 end;
478
479 return multiplier;
480end;
481
482function Plough:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
483 if superFunc ~= nil then
484 if not superFunc(self, speedRotatingPart, xmlFile, key) then
485 return false;
486 end;
487 end;
488
489 speedRotatingPart.disableOnTurn = Utils.getNoNil(getXMLBool(xmlFile, key .. "#disableOnTurn"), true);
490 speedRotatingPart.turnAnimLimit = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#turnAnimLimit"), 0);
491 speedRotatingPart.turnAnimLimitSide = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#turnAnimLimitSide"), 0);
492 speedRotatingPart.invertDirectionOnRotation = Utils.getNoNil(getXMLBool(xmlFile, key .. "#invertDirectionOnRotation"), true);
493
494 return true;
495end
496
497function Plough:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
498 if self.rotationPart.turnAnimation ~= nil and speedRotatingPart.disableOnTurn then
499 local turnAnimTime = self:getAnimationTime(self.rotationPart.turnAnimation);
500 if turnAnimTime ~= nil then
501 local enabled = true;
502 if speedRotatingPart.turnAnimLimitSide < 0 then
503 enabled = (turnAnimTime <= speedRotatingPart.turnAnimLimit);
504 elseif speedRotatingPart.turnAnimLimitSide > 0 then
505 enabled = (1-turnAnimTime <= speedRotatingPart.turnAnimLimit);
506 else
507 enabled = (turnAnimTime <= speedRotatingPart.turnAnimLimit or 1-turnAnimTime <= speedRotatingPart.turnAnimLimit);
508 end;
509 if not enabled then
510 return false;
511 end;
512 end;
513 end;
514
515 if superFunc ~= nil then
516 return superFunc(self, speedRotatingPart);
517 end
518 return true;
519end;
520
521function Plough:getSpeedRotatingPartDirection(superFunc, speedRotatingPart)
522 if self.rotationPart.turnAnimation ~= nil then
523 local turnAnimTime = self:getAnimationTime(self.rotationPart.turnAnimation);
524 if turnAnimTime > 0.5 and speedRotatingPart.invertDirectionOnRotation then
525 return -1;
526 end;
527 end;
528
529 if superFunc ~= nil then
530 return superFunc(self, speedRotatingPart);
531 end
532 return 1;
533end;
534
535function Plough:doCheckSpeedLimit(superFunc)
536 local parent = true;
537 if superFunc ~= nil then
538 parent = superFunc(self);
539 end
540
541 return parent and self.isPloughSpeedLimitActive;
542end;
543
544function Plough:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
545 local retValue = true;
546 if superFunc ~= nil then
547 retValue = superFunc(self, workArea, xmlFile, key)
548 end
549
550 if workArea.type == WorkArea.AREATYPE_DEFAULT then
551 workArea.type = WorkArea.AREATYPE_PLOUGH;
552 end;
553
554 return retValue;
555end;
556
557function Plough.getDefaultSpeedLimit()
558 return 15;
559end;
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