Sprache Deutsch Language English

Script Dokumentation LS 2015 - BaleLoader (Patch 1.3)

Script Dokumentation Übersicht

scripts/vehicles/specializations/BaleLoader.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-- BaleLoader
3-- This is the specialization for automatic bale loaders
4--
5-- @author Stefan Geiger
6-- @date 12/10/09
7--
8-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
9
10source("dataS/scripts/vehicles/specializations/BaleLoaderStateEvent.lua");
11BaleLoader = {};
12
13function BaleLoader.prerequisitesPresent(specializations)
14 return SpecializationUtil.hasSpecialization(Fillable, specializations);
15end;
16
17BaleLoader.GRAB_MOVE_UP = 1;
18BaleLoader.GRAB_MOVE_DOWN = 2;
19BaleLoader.GRAB_DROP_BALE = 3;
20
21BaleLoader.EMPTY_NONE = 1;
22BaleLoader.EMPTY_TO_WORK = 2;
23BaleLoader.EMPTY_ROTATE_PLATFORM = 3;
24BaleLoader.EMPTY_ROTATE1 = 4;
25BaleLoader.EMPTY_CLOSE_GRIPPERS = 5;
26BaleLoader.EMPTY_HIDE_PUSHER1 = 6;
27BaleLoader.EMPTY_HIDE_PUSHER2 = 7;
28BaleLoader.EMPTY_ROTATE2 = 8;
29BaleLoader.EMPTY_WAIT_TO_DROP = 9;
30BaleLoader.EMPTY_WAIT_TO_SINK = 10;
31BaleLoader.EMPTY_SINK = 11;
32BaleLoader.EMPTY_CANCEL = 12;
33BaleLoader.EMPTY_WAIT_TO_REDO = 13;
34
35BaleLoader.CHANGE_DROP_BALES = 1;
36BaleLoader.CHANGE_SINK = 2;
37BaleLoader.CHANGE_EMPTY_REDO = 3;
38BaleLoader.CHANGE_EMPTY_START = 4;
39BaleLoader.CHANGE_EMPTY_CANCEL = 5;
40BaleLoader.CHANGE_MOVE_TO_WORK = 6;
41BaleLoader.CHANGE_MOVE_TO_TRANSPORT = 7;
42BaleLoader.CHANGE_GRAB_BALE = 8;
43BaleLoader.CHANGE_GRAB_MOVE_UP = 9;
44BaleLoader.CHANGE_GRAB_DROP_BALE = 10;
45BaleLoader.CHANGE_GRAB_MOVE_DOWN = 11;
46BaleLoader.CHANGE_FRONT_PUSHER = 12;
47BaleLoader.CHANGE_ROTATE_PLATFORM = 13;
48BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM = 14;
49BaleLoader.CHANGE_EMPTY_ROTATE1 = 15;
50BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS = 16;
51BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1 = 17;
52BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2 = 18;
53BaleLoader.CHANGE_EMPTY_ROTATE2 = 19;
54BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP = 20;
55BaleLoader.CHANGE_EMPTY_STATE_NIL = 21;
56BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO = 22;
57
58
59BaleLoader.CHANGE_BUTTON_EMPTY = 23;
60BaleLoader.CHANGE_BUTTON_EMPTY_ABORT = 24;
61BaleLoader.CHANGE_BUTTON_WORK_TRANSPORT = 25;
62
63
64
65-- emptying: user input state switch emptyState state switch automatically performed
66-- 1. move grabber to work position CHANGE_EMPTY_START -> (EMPTY_TO_WORK) -> CHANGE_EMPTY_ROTATE_PLATFORM ->
67-- 2. rotate platform (EMPTY_ROTATE_PLATFORM) -> CHANGE_EMPTY_ROTATE1 ->
68-- 3. rotate main to half rotation and move the bales to the back (EMPTY_ROTATE1) -> CHANGE_EMPTY_CLOSE_GRIPPERS ->
69-- 4. close grippers (EMPTY_CLOSE_GRIPPERS) -> CHANGE_EMPTY_HIDE_PUSHER1 ->
70-- 5. hide pushers part 1 (rotation) (EMPTY_HIDE_PUSHER1) -> CHANGE_EMPTY_HIDE_PUSHER2 ->
71-- 6. hide pushers part 2 (translation) (EMPTY_HIDE_PUSHER2) -> CHANGE_EMPTY_ROTATE2 ->
72-- 7. rotate main to full rotation (EMPTY_ROTATE2) -> CHANGE_EMPTY_WAIT_TO_DROP ->
73-- 8. wait for user input (EMPTY_WAIT_TO_DROP)
74
75-- 2 options:
76
77-- option 1:
78-- 9a. rotate main to no rotation CHANGE_EMPTY_CANCEL -> (EMPTY_CANCEL) -> CHANGE_EMPTY_WAIT_TO_REDO ->
79-- 10a. wait for user input (EMPTY_WAIT_TO_REDO)
80-- CHANGE_EMPTY_REDO -> (EMPTY_ROTATE2)
81
82-- option 2:
83-- 9b. CHANGE_DROP_BALES -> (EMPTY_WAIT_TO_SINK)
84-- 10b. wait for user input
85-- 11b. rotate main to no rotation CHANGE_SINK -> (EMPTY_SINK) -> CHANGE_EMPTY_STATE_NIL
86
87
88function BaleLoader:load(xmlFile)
89
90 self.doStateChange = BaleLoader.doStateChange;
91 self.getBaleGrabberDropBaleAnimName = BaleLoader.getBaleGrabberDropBaleAnimName;
92 self.pickupBale = BaleLoader.pickupBale;
93
94 self.balesToLoad = {}
95
96 self.balesToMount = {};
97
98 self.isInWorkPosition = false;
99 self.grabberIsMoving = false;
100 self.allowGrabbing = false;
101 self.synchronizeFillLevel = false;
102
103 self.rotatePlatformDirection = 0;
104 self.frontBalePusherDirection = 0;
105
106 self.emptyState = BaleLoader.EMPTY_NONE;
107
108 self.itemsToSave ={}
109 self.fillLevel = 0;
110 self.fillLevelMax = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.capacity"), 0);
111 self:setCapacity(self.fillLevelMax);
112
113 self.rotatePlatformAnimName = Utils.getNoNil(getXMLString(xmlFile, "vehicle.baleLoader#rotatePlatformAnimName"), "rotatePlatform");
114 self.rotatePlatformBackAnimName = Utils.getNoNil(getXMLString(xmlFile, "vehicle.baleLoader#rotatePlatformBackAnimName"), "rotatePlatform");
115 self.rotatePlatformEmptyAnimName = Utils.getNoNil(getXMLString(xmlFile, "vehicle.baleLoader#rotatePlatformEmptyAnimName"), "rotatePlatform");
116
117 self.moveBalePlacesAfterRotatePlatform = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.baleLoader#moveBalePlacesAfterRotatePlatform"), false);
118
119 self.baleGrabber = {};
120 self.baleGrabber.grabNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleGrabber#grabNode"));
121
122 self.startBalePlace = {};
123 self.startBalePlace.bales = {};
124 self.startBalePlace.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.balePlaces#startBalePlace"));
125 if self.startBalePlace.node ~= nil then
126 if getNumOfChildren(self.startBalePlace.node) < 2 then
127 self.startBalePlace.node = nil;
128 else
129 self.startBalePlace.origRot = {};
130 self.startBalePlace.origTrans = {};
131 for i=1, 2 do
132 local node = getChildAt(self.startBalePlace.node, i-1);
133 local x,y,z = getRotation(node);
134 self.startBalePlace.origRot[i] = {x,y,z};
135 local x,y,z = getTranslation(node);
136 self.startBalePlace.origTrans[i] = {x,y,z};
137 end;
138 end;
139 end;
140 self.startBalePlace.count = 0;
141
142 self.currentBalePlace = 1;
143 self.balePlaces = {};
144 local i=0;
145 while true do
146 local key = string.format("vehicle.balePlaces.balePlace(%d)", i);
147 if not hasXMLProperty(xmlFile, key) then
148 break;
149 end;
150 local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#node"));
151 if node ~= nil then
152 local entry = {};
153 entry.node = node;
154 table.insert(self.balePlaces, entry);
155 end;
156 i = i + 1;
157 end;
158
159 self.baleGrabParticleSystems = {};
160 local psName = "vehicle.baleGrabParticleSystem";
161 Utils.loadParticleSystem(xmlFile, self.baleGrabParticleSystems, psName, self.components, false, nil, self.baseDirectory);
162 self.baleGrabParticleSystemDisableTime = 0;
163 self.baleGrabParticleSystemDisableDuration = Utils.getNoNil(getXMLFloat(xmlFile, psName.."#disableDuration"), 0.6)*1000;
164
165 if self.isClient then
166 self.sampleBaleGrab = Utils.loadSample(xmlFile, {}, "vehicle.baleGrabSound", nil, self.baseDirectory);
167 self.sampleBaleLoaderHydraulic = Utils.loadSample(xmlFile, {}, "vehicle.baleLoaderHydraulicSound", nil, self.baseDirectory);
168 end;
169
170 self.workTransportButton = InputBinding.IMPLEMENT_EXTRA;
171 self.emptyAbortButton = InputBinding.IMPLEMENT_EXTRA2;
172 self.emptyButton = InputBinding.IMPLEMENT_EXTRA3;
173
174 --[[self.baleTypes = {};
175 local i = 0;
176 while true do
177 local key = string.format("vehicle.baleTypes.baleType(%d)", i);
178 if not hasXMLProperty(xmlFile, key) then
179 break;
180 end;
181 local filename = getXMLString(xmlFile, key.."#filename");
182 if filename ~= nil then
183 filename = Utils.getFilename(filename, self.baseDirectory);
184 table.insert(self.baleTypes, filename);
185 end;
186 i = i + 1;
187 end;
188 if table.getn(self.baleTypes) == 0 then
189 table.insert(self.baleTypes, "data/maps/models/objects/strawbale/strawbaleBaler.i3d");
190 end;]]
191
192 self.showInvalidBaleWarning = false;
193 self.allowedBaleTypes = {};
194 local i =0;
195 while true do
196 local key = string.format("vehicle.baleTypes.baleType(%d)", i);
197 if not hasXMLProperty(xmlFile, key) then
198 break;
199 end
200 local minBaleDiameter = getXMLFloat(xmlFile, key.."#minBaleDiameter");
201 local maxBaleDiameter = getXMLFloat(xmlFile, key.."#maxBaleDiameter");
202 local minBaleWidth = getXMLFloat(xmlFile, key.."#minBaleWidth");
203 local maxBaleWidth = getXMLFloat(xmlFile, key.."#maxBaleWidth");
204 local minBaleHeight = getXMLFloat(xmlFile, key.."#minBaleHeight");
205 local maxBaleHeight = getXMLFloat(xmlFile, key.."#maxBaleHeight");
206 local minBaleLength = getXMLFloat(xmlFile, key.."#minBaleLength");
207 local maxBaleLength = getXMLFloat(xmlFile, key.."#maxBaleLength");
208 if minBaleDiameter ~= nil and maxBaleDiameter ~= nil and minBaleWidth ~= nil and maxBaleWidth ~= nil then
209 table.insert(self.allowedBaleTypes, {
210 minBaleDiameter = Utils.round(minBaleDiameter, 2),
211 maxBaleDiameter = Utils.round(maxBaleDiameter, 2),
212 minBaleWidth = Utils.round(minBaleWidth, 2),
213 maxBaleWidth = Utils.round(maxBaleWidth, 2)});
214 elseif minBaleWidth ~= nil and maxBaleWidth ~= nil and minBaleHeight ~= nil and maxBaleHeight ~= nil and minBaleLength ~= nil and maxBaleLength ~= nil then
215 table.insert(self.allowedBaleTypes, {
216 minBaleWidth = Utils.round(minBaleWidth, 2),
217 maxBaleWidth = Utils.round(maxBaleWidth, 2),
218 minBaleHeight = Utils.round(minBaleHeight, 2),
219 maxBaleHeight = Utils.round(maxBaleHeight, 2),
220 minBaleLength = Utils.round(minBaleLength, 2),
221 maxBaleLength = Utils.round(maxBaleLength, 2)
222 });
223 end
224 i = i + 1;
225 end
226
227 self.baleloaderUVScrollParts = {};
228 local i = 0;
229 while true do
230 local key = string.format("vehicle.baleloaderUVScrollParts.baleloaderUVScrollPart(%d)", i);
231 if not hasXMLProperty(xmlFile, key) then
232 break;
233 end;
234 local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
235 local speed = Utils.getVectorNFromString(getXMLString(xmlFile, key.."#speed"), 2);
236 if node ~= nil and speed then
237 table.insert(self.baleloaderUVScrollParts, {node=node, speed=speed});
238 end;
239 i = i +1;
240 end;
241end;
242
243function BaleLoader:delete()
244
245 if (self.baleGrabParticleSystems) then
246 Utils.deleteParticleSystem(self.baleGrabParticleSystems);
247 end;
248
249 -- avoid the bale nodes to be deleted twice (because they are linked the vehicle and because the Bale object is deleted)
250 for i, balePlace in pairs(self.balePlaces) do
251 if balePlace.bales ~= nil then
252 for _, baleServerId in pairs(balePlace.bales) do
253 local bale = networkGetObject(baleServerId);
254 if bale ~= nil then
255 if bale.nodeId ~= 0 then
256 unlink(bale.nodeId);
257 end;
258 end;
259 end;
260 end;
261 end;
262 for i, baleServerId in ipairs(self.startBalePlace.bales) do
263 local bale = networkGetObject(baleServerId);
264 if bale ~= nil then
265 if bale.nodeId ~= 0 then
266 unlink(bale.nodeId);
267 end;
268 end;
269 end;
270
271 if self.isClient then
272 Utils.deleteSample(self.sampleBaleGrab);
273 Utils.deleteSample(self.sampleBaleLoaderHydraulic);
274 end;
275end;
276
277function BaleLoader:readStream(streamId, connection)
278
279 self.isInWorkPosition = streamReadBool(streamId);
280 self.frontBalePusherDirection = streamReadIntN(streamId, 3);
281 self.rotatePlatformDirection = streamReadIntN(streamId, 3);
282
283 -- note: we do not sync grabberMoveState, this may lead to visual artifacts for a few seconds at the bigging
284
285 if self.isInWorkPosition then
286 BaleLoader.moveToWorkPosition(self);
287 end;
288
289 local emptyState = streamReadUIntN(streamId, 4);
290
291 self.currentBalePlace = streamReadInt8(streamId);
292 self.fillLevel = streamReadInt8(streamId);
293
294 -- read bale at bale grabber
295 if streamReadBool(streamId) then
296 local baleServerId = streamReadInt32(streamId);
297
298 self.baleGrabber.currentBale = baleServerId;
299 self.balesToMount[baleServerId] = {serverId=baleServerId, linkNode=self.baleGrabber.grabNode, trans={0,0,0}, rot={0,0,0} };
300 end;
301
302 -- read bales at start bale places
303 self.startBalePlace.count = streamReadUIntN(streamId, 3);
304 for i=1, self.startBalePlace.count do
305 local baleServerId = streamReadInt32(streamId);
306
307 local attachNode = getChildAt(self.startBalePlace.node, i-1)
308 self.balesToMount[baleServerId] = {serverId=baleServerId, linkNode=attachNode, trans={0,0,0}, rot={0,0,0} };
309
310 table.insert(self.startBalePlace.bales, baleServerId);
311 end;
312
313
314 -- read bales at normal bale places
315 for i=1, table.getn(self.balePlaces) do
316 local balePlace = self.balePlaces[i];
317
318 local numBales = streamReadUIntN(streamId, 3);
319 if numBales > 0 then
320 balePlace.bales = {};
321
322 for baleI=1, numBales do
323 local baleServerId = streamReadInt32(streamId, baleServerId);
324 local x = streamReadFloat32(streamId);
325 local y = streamReadFloat32(streamId);
326 local z = streamReadFloat32(streamId);
327
328 table.insert(balePlace.bales, baleServerId);
329
330 self.balesToMount[baleServerId] = {serverId=baleServerId, linkNode=balePlace.node, trans={ x,y,z}, rot={0,0,0} };
331 end;
332 end;
333 end;
334
335 -- read num bales on platform
336 -- read bales on baleloader
337 -- ignore
338
339 -- grabberMoveState ? int:nil
340 -- isInWorkPosition bool
341 -- emptyState ? int:nil
342 -- rotatePlatformDirection
343 -- frontBalePusherDirection
344 -- grabberIsMoving: bool
345
346
347 -- update animations
348 BaleLoader.updateBalePlacesAnimations(self);
349
350 if emptyState >= BaleLoader.EMPTY_TO_WORK then
351 self:doStateChange(BaleLoader.CHANGE_EMPTY_START);
352 AnimatedVehicle.updateAnimations(self, 99999999);
353 if emptyState >= BaleLoader.EMPTY_ROTATE_PLATFORM then
354 self:doStateChange(BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM);
355 AnimatedVehicle.updateAnimations(self, 99999999);
356 if emptyState >= BaleLoader.EMPTY_ROTATE1 then
357 self:doStateChange(BaleLoader.CHANGE_EMPTY_ROTATE1);
358 AnimatedVehicle.updateAnimations(self, 99999999);
359 if emptyState >= BaleLoader.EMPTY_CLOSE_GRIPPERS then
360 self:doStateChange(BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS);
361 AnimatedVehicle.updateAnimations(self, 99999999);
362 if emptyState >= BaleLoader.EMPTY_HIDE_PUSHER1 then
363 self:doStateChange(BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1);
364 AnimatedVehicle.updateAnimations(self, 99999999);
365 if emptyState >= BaleLoader.EMPTY_HIDE_PUSHER2 then
366 self:doStateChange(BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2);
367 AnimatedVehicle.updateAnimations(self, 99999999);
368 if emptyState >= BaleLoader.EMPTY_ROTATE2 then
369 self:doStateChange(BaleLoader.CHANGE_EMPTY_ROTATE2);
370 AnimatedVehicle.updateAnimations(self, 99999999);
371 if emptyState >= BaleLoader.EMPTY_WAIT_TO_DROP then
372 self:doStateChange(BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP);
373 AnimatedVehicle.updateAnimations(self, 99999999);
374 if emptyState == BaleLoader.EMPTY_CANCEL or emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then
375 self:doStateChange(BaleLoader.CHANGE_EMPTY_CANCEL);
376 AnimatedVehicle.updateAnimations(self, 99999999);
377 if emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then
378 self:doStateChange(BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO);
379 AnimatedVehicle.updateAnimations(self, 99999999);
380 end;
381 elseif emptyState == BaleLoader.EMPTY_WAIT_TO_SINK or emptyState == BaleLoader.EMPTY_SINK then
382 self:doStateChange(BaleLoader.CHANGE_DROP_BALES);
383 AnimatedVehicle.updateAnimations(self, 99999999);
384
385 if emptyState == BaleLoader.EMPTY_SINK then
386 self:doStateChange(BaleLoader.CHANGE_SINK);
387 AnimatedVehicle.updateAnimations(self, 99999999);
388 end;
389 end;
390 end;
391
392 end;
393 end;
394 end;
395 end;
396 end;
397 end;
398 end;
399 self.emptyState = emptyState;
400end;
401
402function BaleLoader:writeStream(streamId, connection)
403 streamWriteBool(streamId, self.isInWorkPosition);
404 streamWriteIntN(streamId, self.frontBalePusherDirection, 3);
405 streamWriteIntN(streamId, self.rotatePlatformDirection, 3);
406
407 streamWriteUIntN(streamId, self.emptyState, 4);
408
409 streamWriteInt8(streamId, self.currentBalePlace);
410 streamWriteInt8(streamId, self.fillLevel);
411
412 -- write bale at bale grabber
413 if streamWriteBool(streamId, self.baleGrabber.currentBale ~= nil) then
414 streamWriteInt32(streamId, self.baleGrabber.currentBale);
415 end;
416
417 -- write bales at start bale places
418 streamWriteUIntN(streamId, self.startBalePlace.count, 3);
419 for i=1, self.startBalePlace.count do
420 local baleServerId = self.startBalePlace.bales[i];
421 streamWriteInt32(streamId, baleServerId);
422 end;
423
424 -- write bales at normal bale places
425 for i=1, table.getn(self.balePlaces) do
426 local balePlace = self.balePlaces[i];
427
428 local numBales = 0;
429 if balePlace.bales ~= nil then
430 numBales = table.getn(balePlace.bales);
431 end;
432 streamWriteUIntN(streamId, numBales, 3);
433 if balePlace.bales ~= nil then
434 for baleI=1, numBales do
435 local baleServerId = balePlace.bales[baleI];
436 local bale = networkGetObject(baleServerId);
437 local nodeId = bale.nodeId;
438 local x,y,z = getTranslation(nodeId);
439 streamWriteInt32(streamId, baleServerId);
440 streamWriteFloat32(streamId, x);
441 streamWriteFloat32(streamId, y);
442 streamWriteFloat32(streamId, z);
443 end;
444 end;
445 end;
446end;
447
448function BaleLoader.updateBalePlacesAnimations(self)
449 if self.currentBalePlace > 2 or (self.moveBalePlacesAfterRotatePlatform and self.currentBalePlace > 1) then
450 local delta = 1;
451 if self.moveBalePlacesAfterRotatePlatform then
452 delta = 0;
453 end
454 -- currentBalePlace-1 or -0 needs to be at the first position
455 self:playAnimation("moveBalePlaces", 1, 0, true);
456 self:setAnimationStopTime("moveBalePlaces", (self.currentBalePlace-delta)/table.getn(self.balePlaces));
457
458 AnimatedVehicle.updateAnimations(self, 99999999);
459 end;
460
461 if self.startBalePlace.count >= 1 then
462 self:playAnimation("balesToOtherRow", 20, nil, true);
463 AnimatedVehicle.updateAnimations(self, 99999999);
464 if self.startBalePlace.count >= 2 then
465 BaleLoader.rotatePlatform(self);
466 end;
467 end;
468end;
469
470function BaleLoader:mouseEvent(posX, posY, isDown, isUp, button)
471
472end;
473
474function BaleLoader:draw()
475
476 if self:getIsActiveForInput(true) then
477 if self.emptyState == BaleLoader.EMPTY_NONE then
478 if self.grabberMoveState == nil then
479 if self.isInWorkPosition then
480 g_currentMission:addHelpButtonText(g_i18n:getText("BALELOADER_TRANSPORT"), self.workTransportButton);
481 else
482 g_currentMission:addHelpButtonText(g_i18n:getText("BALELOADER_WORK"), self.workTransportButton);
483 end;
484 end;
485
486 if BaleLoader.getAllowsStartUnloading(self) then
487 g_currentMission:addHelpButtonText(g_i18n:getText("BALELOADER_UNLOAD"), self.emptyButton);
488 end;
489 else
490 if self.emptyState >= BaleLoader.EMPTY_TO_WORK and self.emptyState <= BaleLoader.EMPTY_ROTATE2 then
491 g_currentMission:addExtraPrintText(g_i18n:getText("BALELOADER_UP"));
492 elseif self.emptyState == BaleLoader.EMPTY_CANCEL or self.emptyState == BaleLoader.EMPTY_SINK then
493 g_currentMission:addExtraPrintText(g_i18n:getText("BALELOADER_DOWN"));
494 elseif self.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP then
495 g_currentMission:addHelpButtonText(g_i18n:getText("BALELOADER_READY"), self.emptyButton);
496 g_currentMission:addHelpButtonText(g_i18n:getText("BALELOADER_ABORT"), self.emptyAbortButton);
497 elseif self.emptyState == BaleLoader.EMPTY_WAIT_TO_SINK then
498 g_currentMission:addHelpButtonText(g_i18n:getText("BALELOADER_SINK"), self.emptyButton);
499 elseif self.emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then
500 g_currentMission:addHelpButtonText(g_i18n:getText("BALELOADER_UNLOAD"), self.emptyButton);
501 end;
502 end;
503 end
504 if self.showInvalidBaleWarning then
505 g_currentMission:showBlinkingWarning(g_i18n:getText("InvalidBaleWarning"));
506 end
507end
508
509
510function BaleLoader:keyEvent(unicode, sym, modifier, isDown)
511end;
512
513
514function BaleLoader:update(dt)
515
516 if self.firstTimeRun then
517 for k,v in pairs(self.balesToLoad) do
518 local baleObject = Bale:new(self.isServer, self.isClient);
519 local x,y,z = unpack(v.translation);
520 local rx,ry,rz = unpack(v.rotation);
521 baleObject:load(v.filename, x,y,z,rx,ry,rz, v.fillLevel);
522 baleObject:mount(self, v.parentNode, x,y,z, rx,ry,rz);
523 if v.baleValueScale ~= nil then
524 baleObject.baleValueScale = v.baleValueScale;
525 end
526 if v.wrappingState ~= nil and baleObject.setWrappingState ~= nil then
527 baleObject:setWrappingState(v.wrappingState);
528 end
529 baleObject:register();
530
531 table.insert(v.bales, networkGetObjectId(baleObject));
532 self.balesToLoad[k] = nil;
533 end;
534
535 for k, baleToMount in pairs(self.balesToMount) do
536 local bale = networkGetObject(baleToMount.serverId);
537 if bale ~= nil then
538 local x,y,z = unpack(baleToMount.trans);
539 local rx,ry,rz = unpack(baleToMount.rot);
540
541 --print("mounting bale delayed: "..baleToMount.serverId..", pos: "..x.." "..y.." "..z);
542 bale:mount(self, baleToMount.linkNode, x,y,z, rx,ry,rz);
543 self.balesToMount[k] = nil;
544 end;
545 end;
546 end;
547
548 if self:getIsActive() then
549 if self:getIsActiveForInput() and self.isClient then
550 if InputBinding.hasEvent(self.emptyButton) then
551 g_client:getServerConnection():sendEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_BUTTON_EMPTY));
552 elseif InputBinding.hasEvent(self.emptyAbortButton) then
553 g_client:getServerConnection():sendEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_BUTTON_EMPTY_ABORT));
554 elseif InputBinding.hasEvent(self.workTransportButton) then
555 g_client:getServerConnection():sendEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_BUTTON_WORK_TRANSPORT));
556 end;
557 end;
558
559 if self.isClient then
560 if self.baleGrabParticleSystemDisableTime ~= 0 and self.baleGrabParticleSystemDisableTime < g_currentMission.time then
561 Utils.setEmittingState(self.baleGrabParticleSystems, false);
562 self.baleGrabParticleSystemDisableTime = 0;
563 end;
564 end;
565
566 -- check if grabber is still moving
567 if self.grabberIsMoving then
568 if not self:getIsAnimationPlaying("baleGrabberTransportToWork") then
569 self.grabberIsMoving = false;
570 end;
571 end;
572
573 self.allowGrabbing = false;
574 if self.isInWorkPosition and not self.grabberIsMoving and self.grabberMoveState == nil and self.startBalePlace.count < 2 and self.frontBalePusherDirection == 0 and self.rotatePlatformDirection == 0 and self.emptyState == BaleLoader.EMPTY_NONE and self.fillLevel < self.fillLevelMax then
575 self.allowGrabbing = true;
576 end;
577
578 self.showInvalidBaleWarning = false;
579 if self.allowGrabbing then
580 if self.baleGrabber.grabNode ~= nil and self.baleGrabber.currentBale == nil then
581 -- find nearest bale
582 local nearestBale, nearestBaleType = BaleLoader.getBaleInRange(self, self.baleGrabber.grabNode);
583 if nearestBale ~= nil then
584 if nearestBaleType == nil then
585 self.showInvalidBaleWarning = true;
586 elseif self.isServer then
587 self:pickupBale(nearestBale, nearestBaleType);
588 end
589 end;
590 end;
591 end;
592 if self.isServer then
593 if self.grabberMoveState ~= nil then
594 if self.grabberMoveState == BaleLoader.GRAB_MOVE_UP then
595 if not self:getIsAnimationPlaying("baleGrabberWorkToDrop") then
596 --BaleLoader.CHANGE_GRAB_MOVE_UP
597 -- switch to grabberMoveState
598 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_MOVE_UP), true, nil, self);
599 end;
600 elseif self.grabberMoveState == BaleLoader.GRAB_DROP_BALE then
601 if not self:getIsAnimationPlaying(self.currentBaleGrabberDropBaleAnimName) then
602 --BaleLoader.CHANGE_GRAB_DROP_BALE
603 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_DROP_BALE), true, nil, self);
604 end;
605 elseif self.grabberMoveState == BaleLoader.GRAB_MOVE_DOWN then
606 --BaleLoader.CHANGE_GRAB_MOVE_DOWN
607 if not self:getIsAnimationPlaying("baleGrabberWorkToDrop") then
608 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_MOVE_DOWN), true, nil, self);
609 end;
610 end;
611 end;
612 if self.frontBalePusherDirection ~= 0 then
613 if not self:getIsAnimationPlaying("frontBalePusher") then
614 --BaleLoader.CHANGE_FRONT_PUSHER
615 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_FRONT_PUSHER), true, nil, self);
616 end;
617 end;
618 if self.rotatePlatformDirection ~= 0 then
619 local name = self.rotatePlatformAnimName;
620 if self.rotatePlatformDirection < 0 then
621 name = self.rotatePlatformBackAnimName;
622 end
623 if not self:getIsAnimationPlaying(name) and not self:getIsAnimationPlaying("moveBalePlacesExtrasOnce") then
624 --BaleLoader.CHANGE_ROTATE_PLATFORM
625 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_ROTATE_PLATFORM), true, nil, self);
626 end;
627 end;
628
629 if self.emptyState ~= BaleLoader.EMPTY_NONE then
630 if self.emptyState == BaleLoader.EMPTY_TO_WORK then
631 if not self:getIsAnimationPlaying("baleGrabberTransportToWork") then
632 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM), true, nil, self);
633 end;
634 elseif self.emptyState == BaleLoader.EMPTY_ROTATE_PLATFORM then
635 if not self:getIsAnimationPlaying(self.rotatePlatformEmptyAnimName) then
636 --BaleLoader.CHANGE_EMPTY_ROTATE1
637 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_ROTATE1), true, nil, self);
638 end;
639 elseif self.emptyState == BaleLoader.EMPTY_ROTATE1 then
640 if not self:getIsAnimationPlaying("emptyRotate") and not self:getIsAnimationPlaying("moveBalePlacesToEmpty") then
641 --BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS
642 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS), true, nil, self);
643 end;
644 elseif self.emptyState == BaleLoader.EMPTY_CLOSE_GRIPPERS then
645 if not self:getIsAnimationPlaying("closeGrippers") then
646 --BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1
647 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1), true, nil, self);
648 end;
649 elseif self.emptyState == BaleLoader.EMPTY_HIDE_PUSHER1 then
650 if not self:getIsAnimationPlaying("emptyHidePusher1") then
651 --BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2
652 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2), true, nil, self);
653 end;
654 elseif self.emptyState == BaleLoader.EMPTY_HIDE_PUSHER2 then
655 if self:getAnimationTime("moveBalePusherToEmpty") < 0.7 or not self:getIsAnimationPlaying("moveBalePusherToEmpty") then
656 --BaleLoader.CHANGE_EMPTY_ROTATE2
657 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_ROTATE2), true, nil, self);
658 end;
659 elseif self.emptyState == BaleLoader.EMPTY_ROTATE2 then
660 if not self:getIsAnimationPlaying("emptyRotate") then
661 --BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP
662 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP), true, nil, self);
663 end;
664 elseif self.emptyState == BaleLoader.EMPTY_SINK then
665 if not self:getIsAnimationPlaying("emptyRotate") and
666 not self:getIsAnimationPlaying("moveBalePlacesToEmpty") and
667 not self:getIsAnimationPlaying("emptyHidePusher1") and
668 not self:getIsAnimationPlaying(self.rotatePlatformEmptyAnimName)
669 then
670 --BaleLoader.CHANGE_EMPTY_STATE_NIL
671 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_STATE_NIL), true, nil, self);
672 end;
673 elseif self.emptyState == BaleLoader.EMPTY_CANCEL then
674 if not self:getIsAnimationPlaying("emptyRotate") then
675 --BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO
676 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO), true, nil, self);
677 end;
678 end;
679 end;
680 end;
681
682 if self.isClient then
683 local hasAnimationsPlaying = next(self.activeAnimations) ~= nil;
684 if hasAnimationsPlaying then
685 if self:getIsActiveForSound() then
686 Utils.playSample(self.sampleBaleLoaderHydraulic, 0, 0, nil);
687 end;
688 else
689 Utils.stopSample(self.sampleBaleLoaderHydraulic);
690 end;
691 end;
692 end;
693
694 -- re mount bale in grabber, which was unmounted to be saved as normal bale
695 if self.baleGrabber.currentBaleIsUnmounted == true then
696 self.baleGrabber.currentBaleIsUnmounted = false;
697 local bale = networkGetObject(self.baleGrabber.currentBale);
698 if bale ~= nil then
699 bale:mount(self, self.baleGrabber.grabNode, 0,0,0, 0,0,0);
700 end;
701 end;
702
703end;
704
705function BaleLoader.getBaleInRange(self, refNode)
706 local px, py, pz = getWorldTranslation(refNode);
707 local nearestDistance = 3.0;
708 local nearestBale = nil;
709 local nearestBaleType = nil;
710
711 for index, item in pairs(g_currentMission.itemsToSave) do
712 local bale = item.item;
713 if bale:isa(Bale) then
714 local vx, vy, vz = getWorldTranslation(bale.nodeId);
715 local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);
716 if distance < nearestDistance then
717 local foundBaleType;
718 for _, baleType in pairs(self.allowedBaleTypes) do
719 if baleType.minBaleDiameter ~= nil then
720 if bale.baleDiameter ~= nil and bale.baleWidth ~= nil and
721 bale.baleDiameter >= baleType.minBaleDiameter and bale.baleDiameter <= baleType.maxBaleDiameter and
722 bale.baleWidth >= baleType.minBaleWidth and bale.baleWidth <= baleType.maxBaleWidth
723 then
724 foundBaleType = baleType;
725 break;
726 end
727 else
728 if bale.baleWidth ~= nil and bale.baleHeight ~= nil and bale.baleLength ~= nil and
729 bale.baleWidth >= baleType.minBaleWidth and bale.baleWidth <= baleType.maxBaleWidth and
730 bale.baleHeight >= baleType.minBaleHeight and bale.baleHeight <= baleType.maxBaleHeight and
731 bale.baleLength >= baleType.minBaleLength and bale.baleLength <= baleType.maxBaleLength
732 then
733 foundBaleType = baleType;
734 break;
735 end
736 end
737 end
738 if foundBaleType ~= nil or nearestBaleType == nil then
739 if foundBaleType ~= nil then
740 nearestDistance = distance;
741 end
742 nearestBale = bale;
743 nearestBaleType = foundBaleType;
744 end
745 end
746 end;
747 end;
748 return nearestBale, nearestBaleType;
749end;
750
751function BaleLoader:onDeactivate()
752 Utils.setEmittingState(self.baleGrabParticleSystems, false);
753 for _, part in pairs(self.baleloaderUVScrollParts) do
754 setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
755 end;
756end;
757
758function BaleLoader:onDeactivateSounds()
759 if self.isClient then
760 Utils.stopSample(self.sampleBaleLoaderHydraulic, true);
761 end;
762end;
763
764function BaleLoader:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
765 self.currentBalePlace = 1;
766
767 self.startBalePlace.count = 0;
768 local numBales = 0
769 local i=0;
770 while true do
771 local baleKey = key..string.format(".bale(%d)", i);
772 if not hasXMLProperty(xmlFile, baleKey) then
773 break;
774 end;
775 local filename = getXMLString(xmlFile, baleKey.."#filename");
776 if filename ~= nil then
777 filename = Utils.convertFromNetworkFilename(filename);
778
779 local x,y,z = Utils.getVectorFromString(getXMLString(xmlFile, baleKey.."#position"));
780 local xRot,yRot,zRot = Utils.getVectorFromString(getXMLString(xmlFile, baleKey.."#rotation"));
781 local fillLevel = getXMLFloat(xmlFile, baleKey.."#fillLevel");
782 local balePlace = getXMLInt(xmlFile, baleKey.."#balePlace");
783 local helper = getXMLInt(xmlFile, baleKey.."#helper");
784 if balePlace == nil or (balePlace > 0 and (x == nil or y == nil or z == nil or xRot == nil or yRot == nil or zRot == nil)) or (balePlace < 1 and helper == nil) then
785 print("Warning: Corrupt savegame, bale "..filename.." could not be loaded");
786 else
787 local translation;
788 local rotation;
789 if balePlace > 0 then
790 translation = {x,y,z};
791 rotation={xRot, yRot, zRot};
792 else
793 translation = {0,0,0};
794 rotation={0,0,0};
795 end;
796 local parentNode = nil;
797 local bales = nil;
798 if balePlace < 1 then
799 if self.startBalePlace.node ~= nil and helper <= getNumOfChildren(self.startBalePlace.node) then
800 parentNode = getChildAt(self.startBalePlace.node, helper-1);
801 if self.startBalePlace.bales == nil then
802 self.startBalePlace.bales = {};
803 end;
804 bales = self.startBalePlace.bales;
805 self.startBalePlace.count = self.startBalePlace.count+1;
806 end;
807 elseif balePlace <= table.getn(self.balePlaces) then
808 self.currentBalePlace = math.max(self.currentBalePlace, balePlace+1);
809 parentNode = self.balePlaces[balePlace].node;
810 if self.balePlaces[balePlace].bales == nil then
811 self.balePlaces[balePlace].bales = {};
812 end;
813 bales = self.balePlaces[balePlace].bales;
814 end;
815 if parentNode ~= nil then
816 local baleValueScale = getXMLFloat(xmlFile, baleKey.."#baleValueScale");
817 local wrappingState = getXMLFloat(xmlFile, baleKey.."#wrappingState");
818 numBales = numBales+1;
819 table.insert(self.balesToLoad, {parentNode=parentNode, filename=filename, bales=bales, translation=translation, rotation=rotation, fillLevel=fillLevel, baleValueScale=baleValueScale, wrappingState=wrappingState});
820 end;
821 end;
822 end;
823 i = i +1;
824 end;
825
826 -- update animations
827 BaleLoader.updateBalePlacesAnimations(self);
828
829 self.fillLevel = numBales;
830 return BaseMission.VEHICLE_LOAD_OK;
831end
832
833function BaleLoader:getSaveAttributesAndNodes(nodeIdent)
834 local attributes = "";
835 local nodes = "";
836 local baleNum = 0;
837
838 for i, balePlace in pairs(self.balePlaces) do
839 if balePlace.bales ~= nil then
840 for _, baleServerId in pairs(balePlace.bales) do
841 local bale = networkGetObject(baleServerId);
842 if bale ~= nil then
843 local nodeId = bale.nodeId;
844 local x,y,z = getTranslation(nodeId);
845 local rx,ry,rz = getRotation(nodeId);
846 if baleNum>0 then
847 nodes = nodes.."\n";
848 end;
849 local wrappingState = Utils.getNoNil(bale.wrappingState, 0);
850 local baleValueScale = Utils.getNoNil(bale.baleValueScale, 1);
851 -- if there are no startbales, the filllevel is odd and this is the last bale -> the user had abort the unloading, so we have to add this last bale as an startbale
852 if table.getn(self.startBalePlace.bales) == 0 and self.fillLevel % 2 ~= 0 and (math.floor(self.fillLevel / 2) + 1) == i then
853 nodes = nodes..nodeIdent..'<bale filename="'..Utils.encodeToHTML(Utils.convertToNetworkFilename(bale.i3dFilename))..'" fillLevel="'..bale:getFillLevel()..'" wrappingState="'..wrappingState..'" baleValueScale="'..baleValueScale..'" balePlace="0" helper="1"/>';
854 else
855 nodes = nodes..nodeIdent..'<bale filename="'..Utils.encodeToHTML(Utils.convertToNetworkFilename(bale.i3dFilename))..'" fillLevel="'..bale:getFillLevel()..'" position="'..x..' '..y..' '..z..'" rotation="'..rx..' '..ry..' '..rz..'" wrappingState="'..wrappingState..'" baleValueScale="'..baleValueScale..'" balePlace="'..i..'" />';
856 end;
857
858 baleNum = baleNum+1;
859 end;
860 end;
861 end;
862 end;
863 for i, baleServerId in ipairs(self.startBalePlace.bales) do
864 local bale = networkGetObject(baleServerId);
865 if bale ~= nil then
866 if baleNum>0 then
867 nodes = nodes.."\n";
868 end;
869 local wrappingState = Utils.getNoNil(bale.wrappingState, 0);
870 local baleValueScale = Utils.getNoNil(bale.baleValueScale, 1);
871 nodes = nodes..nodeIdent..'<bale filename="'..Utils.encodeToHTML(Utils.convertToNetworkFilename(bale.i3dFilename))..'" fillLevel="'..bale:getFillLevel()..'" wrappingState="'..wrappingState..'" baleValueScale="'..baleValueScale..'" balePlace="0" helper="'..i..'"/>';
872 baleNum = baleNum+1;
873 end;
874 end;
875 -- unmount bale in grabber so it can be saved as a normal bale
876 if self.baleGrabber.currentBale ~= nil then
877 local bale = networkGetObject(self.baleGrabber.currentBale);
878 if bale ~= nil then
879 bale:unmount();
880 self.baleGrabber.currentBaleIsUnmounted = true;
881 end;
882 end;
883 return attributes,nodes;
884end
885
886function BaleLoader:doStateChange(id, nearestBaleServerId)
887
888 if id == BaleLoader.CHANGE_DROP_BALES then
889 -- drop all bales to ground (and add to save by mission)
890 self.currentBalePlace = 1;
891 for _, balePlace in pairs(self.balePlaces) do
892 if balePlace.bales ~= nil then
893 for _, baleServerId in pairs(balePlace.bales) do
894 local bale = networkGetObject(baleServerId);
895 if bale ~= nil then
896 bale:unmount();
897 end;
898 self.balesToMount[baleServerId] = nil;
899 end;
900 balePlace.bales = nil;
901 end;
902 end;
903 self.fillLevel = 0;
904 self:playAnimation("releaseFrontplattform", 1, nil, true);
905 self:playAnimation("closeGrippers", -1, nil, true);
906 self.emptyState = BaleLoader.EMPTY_WAIT_TO_SINK;
907 elseif id == BaleLoader.CHANGE_SINK then
908 self:playAnimation("emptyRotate", -1, nil, true);
909 self:playAnimation("moveBalePlacesToEmpty", -5, nil, true);
910 self:playAnimation("emptyHidePusher1", -1, nil, true);
911 self:playAnimation(self.rotatePlatformEmptyAnimName, -1, nil, true);
912 if not self.isInWorkPosition then
913 self:playAnimation("closeGrippers", 1, self:getAnimationTime("closeGrippers"), true);
914 self:playAnimation("baleGrabberTransportToWork", 1, nil, true);
915 end;
916 self.emptyState = BaleLoader.EMPTY_SINK;
917 elseif id == BaleLoader.CHANGE_EMPTY_REDO then
918 self:playAnimation("emptyRotate", 1, nil, true);
919 self.emptyState = BaleLoader.EMPTY_ROTATE2;
920 elseif id == BaleLoader.CHANGE_EMPTY_START then
921 -- move to work position in case it is not there now
922 BaleLoader.moveToWorkPosition(self);
923 self.emptyState = BaleLoader.EMPTY_TO_WORK;
924 elseif id == BaleLoader.CHANGE_EMPTY_CANCEL then
925 self:playAnimation("emptyRotate", -1, nil, true);
926 self.emptyState = BaleLoader.EMPTY_CANCEL;
927 elseif id == BaleLoader.CHANGE_MOVE_TO_TRANSPORT then
928 if self.isInWorkPosition then
929 self.grabberIsMoving = true;
930 self.isInWorkPosition = false;
931 -- move to transport position
932 BaleLoader.moveToTransportPosition(self);
933 for _, part in pairs(self.baleloaderUVScrollParts) do
934 setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
935 end;
936 end;
937 elseif id == BaleLoader.CHANGE_MOVE_TO_WORK then
938 if not self.isInWorkPosition then
939 self.grabberIsMoving = true;
940 self.isInWorkPosition = true;
941 -- move to work position
942 BaleLoader.moveToWorkPosition(self);
943 for _, part in pairs(self.baleloaderUVScrollParts) do
944 setShaderParameter(part.node, "uvScrollSpeed", part.speed[1], part.speed[2], 0, 0, false);
945 end;
946 end;
947 elseif id == BaleLoader.CHANGE_GRAB_BALE then
948 local bale = networkGetObject(nearestBaleServerId);
949 self.baleGrabber.currentBale = nearestBaleServerId;
950 if bale ~= nil then
951 bale:mount(self, self.baleGrabber.grabNode, 0,0,0, 0,0,0);
952 self.balesToMount[nearestBaleServerId] = nil;
953 else
954 self.balesToMount[nearestBaleServerId] = {serverId=nearestBaleServerId, linkNode=self.baleGrabber.grabNode, trans={0,0,0}, rot={0,0,0} };
955 end;
956 self.grabberMoveState = BaleLoader.GRAB_MOVE_UP;
957 self:playAnimation("baleGrabberWorkToDrop", 1, nil, true);
958
959 self.fillLevel = self.fillLevel + 1;
960 if self.isClient then
961 if self:getIsActiveForSound() then
962 Utils.playSample(self.sampleBaleGrab, 1, 0, nil);
963 end;
964 Utils.setEmittingState(self.baleGrabParticleSystems, true);
965 self.baleGrabParticleSystemDisableTime = g_currentMission.time + self.baleGrabParticleSystemDisableDuration;
966 end;
967 elseif id == BaleLoader.CHANGE_GRAB_MOVE_UP then
968 self.currentBaleGrabberDropBaleAnimName = self:getBaleGrabberDropBaleAnimName();
969 self:playAnimation(self.currentBaleGrabberDropBaleAnimName, 1, nil, true);
970 self.grabberMoveState = BaleLoader.GRAB_DROP_BALE;
971 elseif id == BaleLoader.CHANGE_GRAB_DROP_BALE then
972 -- drop bale at platform
973 if self.startBalePlace.count < 2 and self.startBalePlace.node ~= nil then
974 local attachNode = getChildAt(self.startBalePlace.node, self.startBalePlace.count)
975 local bale = networkGetObject(self.baleGrabber.currentBale);
976 if bale ~= nil then
977 bale:mount(self, attachNode, 0,0,0, 0,0,0);
978 self.balesToMount[self.baleGrabber.currentBale] = nil;
979 else
980 self.balesToMount[self.baleGrabber.currentBale] = {serverId=self.baleGrabber.currentBale, linkNode=attachNode, trans={0,0,0}, rot={0,0,0} };
981 end;
982
983 self.startBalePlace.count = self.startBalePlace.count + 1;
984 table.insert(self.startBalePlace.bales, self.baleGrabber.currentBale);
985 self.baleGrabber.currentBale = nil;
986 --setRotation(baleNode, 0, 0, 0);
987 --setTranslation(baleNode, 0, 0, 0);
988
989 if self.startBalePlace.count == 1 then
990 self.frontBalePusherDirection = 1;
991 self:playAnimation("balesToOtherRow", 1, nil, true);
992 self:playAnimation("frontBalePusher", 1, nil, true);
993 elseif self.startBalePlace.count == 2 then
994 BaleLoader.rotatePlatform(self);
995 end;
996
997 self:playAnimation(self.currentBaleGrabberDropBaleAnimName, -5, nil, true);
998 self:playAnimation("baleGrabberWorkToDrop", -1, nil, true);
999 self.grabberMoveState = BaleLoader.GRAB_MOVE_DOWN;
1000 end;
1001 elseif id == BaleLoader.CHANGE_GRAB_MOVE_DOWN then
1002 self.grabberMoveState = nil;
1003 elseif id == BaleLoader.CHANGE_FRONT_PUSHER then
1004 if self.frontBalePusherDirection > 0 then
1005 self:playAnimation("frontBalePusher", -1, nil, true);
1006 self.frontBalePusherDirection = -1;
1007 else
1008 self.frontBalePusherDirection = 0;
1009 end;
1010 elseif id == BaleLoader.CHANGE_ROTATE_PLATFORM then
1011 if self.rotatePlatformDirection > 0 then
1012 -- drop bales
1013 local balePlace = self.balePlaces[self.currentBalePlace];
1014 self.currentBalePlace = self.currentBalePlace + 1;
1015 for i=1, table.getn(self.startBalePlace.bales) do
1016 local node = getChildAt(self.startBalePlace.node, i-1);
1017 local x,y,z = getTranslation(node);
1018 local rx,ry,rz = getRotation(node);
1019 local baleServerId = self.startBalePlace.bales[i];
1020 local bale = networkGetObject(baleServerId);
1021 if bale ~= nil then
1022 bale:mount(self, balePlace.node, x,y,z, rx,ry,rz);
1023 self.balesToMount[baleServerId] = nil;
1024 else
1025 self.balesToMount[baleServerId] = {serverId=baleServerId, linkNode=balePlace.node, trans={ x,y,z}, rot={rx,ry,rz} };
1026 end;
1027 end;
1028 balePlace.bales = self.startBalePlace.bales;
1029 self.startBalePlace.bales = {};
1030 self.startBalePlace.count = 0;
1031
1032 for i=1, 2 do
1033 local node = getChildAt(self.startBalePlace.node, i-1);
1034 setRotation(node, unpack(self.startBalePlace.origRot[i]));
1035 setTranslation(node, unpack(self.startBalePlace.origTrans[i]));
1036 end;
1037
1038 if self.emptyState == BaleLoader.EMPTY_NONE then
1039 -- we are not waiting to start emptying, rotate back
1040 self.rotatePlatformDirection = -1;
1041 self:playAnimation(self.rotatePlatformBackAnimName, -1, nil, true);
1042
1043 if self.moveBalePlacesAfterRotatePlatform then
1044 -- currentBalePlace+1 needs to be at the first position
1045 if self.currentBalePlace <= table.getn(self.balePlaces) then
1046 self:playAnimation("moveBalePlaces", 1, (self.currentBalePlace-1)/table.getn(self.balePlaces), true);
1047 self:setAnimationStopTime("moveBalePlaces", (self.currentBalePlace)/table.getn(self.balePlaces));
1048 self:playAnimation("moveBalePlacesExtrasOnce", 1, nil, true);
1049 end
1050 end
1051 else
1052 self.rotatePlatformDirection = 0;
1053 end;
1054 else
1055 self.rotatePlatformDirection = 0;
1056 end;
1057 elseif id == BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM then
1058 self.emptyState = BaleLoader.EMPTY_ROTATE_PLATFORM;
1059 if self.startBalePlace.count == 0 then
1060 self:playAnimation(self.rotatePlatformEmptyAnimName, 1, nil, true);
1061 else
1062 BaleLoader.rotatePlatform(self)
1063 end;
1064 elseif id == BaleLoader.CHANGE_EMPTY_ROTATE1 then
1065 self:playAnimation("emptyRotate", 1, nil, true);
1066 self:setAnimationStopTime("emptyRotate", 0.2);
1067 local balePlacesTime = self:getRealAnimationTime("moveBalePlaces");
1068 self:playAnimation("moveBalePlacesToEmpty", 1.5, balePlacesTime/self:getAnimationDuration("moveBalePlacesToEmpty"), true);
1069 self:playAnimation("moveBalePusherToEmpty", 1.5, balePlacesTime/self:getAnimationDuration("moveBalePusherToEmpty"), true);
1070 self.emptyState = BaleLoader.EMPTY_ROTATE1;
1071 elseif id == BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS then
1072 self:playAnimation("closeGrippers", 1, nil, true);
1073 self.emptyState = BaleLoader.EMPTY_CLOSE_GRIPPERS;
1074 elseif id == BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1 then
1075 self:playAnimation("emptyHidePusher1", 1, nil, true);
1076 self.emptyState = BaleLoader.EMPTY_HIDE_PUSHER1;
1077 elseif id == BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2 then
1078 self:playAnimation("moveBalePusherToEmpty", -2, nil, true);
1079 self.emptyState = BaleLoader.EMPTY_HIDE_PUSHER2;
1080 elseif id == BaleLoader.CHANGE_EMPTY_ROTATE2 then
1081 self:playAnimation("emptyRotate", 1, self:getAnimationTime("emptyRotate"), true);
1082 self.emptyState = BaleLoader.EMPTY_ROTATE2;
1083 elseif id == BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP then
1084 -- wait for the user to react (abort or drop)
1085 self.emptyState = BaleLoader.EMPTY_WAIT_TO_DROP;
1086 elseif id == BaleLoader.CHANGE_EMPTY_STATE_NIL then
1087 self.emptyState = BaleLoader.EMPTY_NONE;
1088 BaleLoader.moveToTransportPosition(self);
1089 if self.isServer then
1090 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_MOVE_TO_TRANSPORT), true, nil, self);
1091 end;
1092 elseif id == BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO then
1093 self.emptyState = BaleLoader.EMPTY_WAIT_TO_REDO;
1094 elseif id == BaleLoader.CHANGE_BUTTON_EMPTY then
1095 -- Server only code
1096 assert(self.isServer);
1097 if self.emptyState ~= BaleLoader.EMPTY_NONE then
1098 if self.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP then
1099 -- BaleLoader.CHANGE_DROP_BALES
1100 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_DROP_BALES), true, nil, self);
1101 elseif self.emptyState == BaleLoader.EMPTY_WAIT_TO_SINK then
1102 -- BaleLoader.CHANGE_SINK
1103 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_SINK), true, nil, self);
1104 elseif self.emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then
1105 -- BaleLoader.CHANGE_EMPTY_REDO
1106 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_REDO), true, nil, self);
1107 end;
1108 else
1109 --BaleLoader.CHANGE_EMPTY_START
1110 if BaleLoader.getAllowsStartUnloading(self) then
1111 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_START), true, nil, self);
1112 end;
1113 end;
1114 elseif id == BaleLoader.CHANGE_BUTTON_EMPTY_ABORT then
1115 -- Server only code
1116 assert(self.isServer);
1117 if self.emptyState ~= BaleLoader.EMPTY_NONE then
1118 if self.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP then
1119 --BaleLoader.CHANGE_EMPTY_CANCEL
1120 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_CANCEL), true, nil, self);
1121 end;
1122 end;
1123 elseif id == BaleLoader.CHANGE_BUTTON_WORK_TRANSPORT then
1124 -- Server only code
1125 assert(self.isServer);
1126 if self.emptyState == BaleLoader.EMPTY_NONE and self.grabberMoveState == nil then
1127 if self.isInWorkPosition then
1128 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_MOVE_TO_TRANSPORT), true, nil, self);
1129 else
1130 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_MOVE_TO_WORK), true, nil, self);
1131 end;
1132 end;
1133 end;
1134end;
1135
1136function BaleLoader.getAllowsStartUnloading(self)
1137 return self.fillLevel > 0 and self.rotatePlatformDirection == 0 and self.frontBalePusherDirection == 0 and not self.grabberIsMoving and self.grabberMoveState == nil and self.emptyState == BaleLoader.EMPTY_NONE;
1138end;
1139
1140function BaleLoader.rotatePlatform(self)
1141 self.rotatePlatformDirection = 1;
1142 self:playAnimation(self.rotatePlatformAnimName, 1, nil, true);
1143 --[[if self.startBalePlace.count > 0 then
1144 self:playAnimation("rotatePlatformMoveBales"..self.startBalePlace.count, 1, nil, true);
1145 end;]]
1146 if self.currentBalePlace > 1 and not self.moveBalePlacesAfterRotatePlatform then
1147 -- currentBalePlace needs to be at the first position
1148 self:playAnimation("moveBalePlaces", 1, (self.currentBalePlace-1)/table.getn(self.balePlaces), true);
1149 self:setAnimationStopTime("moveBalePlaces", (self.currentBalePlace)/table.getn(self.balePlaces));
1150 self:playAnimation("moveBalePlacesExtrasOnce", 1, nil, true);
1151 end;
1152end;
1153
1154function BaleLoader.moveToWorkPosition(self)
1155 self:playAnimation("baleGrabberTransportToWork", 1, Utils.clamp(self:getAnimationTime("baleGrabberTransportToWork"), 0, 1), true);
1156 local animTime = nil;
1157 if self:getAnimationTime("closeGrippers") ~= 0 then
1158 animTime = self:getAnimationTime("closeGrippers");
1159 end;
1160 self:playAnimation("closeGrippers", -1, animTime, true);
1161end;
1162
1163function BaleLoader.moveToTransportPosition(self)
1164 self:playAnimation("baleGrabberTransportToWork", -1, Utils.clamp(self:getAnimationTime("baleGrabberTransportToWork"), 0, 1), true);
1165 self:playAnimation("closeGrippers", 1, Utils.clamp(self:getAnimationTime("closeGrippers"), 0, 1), true);
1166end;
1167
1168function BaleLoader:getBaleGrabberDropBaleAnimName()
1169 local name = string.format("baleGrabberDropBale%d", self.startBalePlace.count);
1170 if self.animations[name] ~= nil then
1171 return name;
1172 end
1173 return "baleGrabberDropBale";
1174end
1175
1176function BaleLoader:pickupBale(nearestBale, nearestBaleType)
1177 --BaleLoader.CHANGE_GRAB_BALE
1178 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_BALE, networkGetObjectId(nearestBale)), true, nil, self);
1179end
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