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 | |
10 | source("dataS/scripts/vehicles/specializations/BaleLoaderStateEvent.lua"); |
11 | BaleLoader = {}; |
12 | |
13 | function BaleLoader.prerequisitesPresent(specializations) |
14 | return SpecializationUtil.hasSpecialization(Fillable, specializations); |
15 | end; |
16 | |
17 | BaleLoader.GRAB_MOVE_UP = 1; |
18 | BaleLoader.GRAB_MOVE_DOWN = 2; |
19 | BaleLoader.GRAB_DROP_BALE = 3; |
20 | |
21 | BaleLoader.EMPTY_NONE = 1; |
22 | BaleLoader.EMPTY_TO_WORK = 2; |
23 | BaleLoader.EMPTY_ROTATE_PLATFORM = 3; |
24 | BaleLoader.EMPTY_ROTATE1 = 4; |
25 | BaleLoader.EMPTY_CLOSE_GRIPPERS = 5; |
26 | BaleLoader.EMPTY_HIDE_PUSHER1 = 6; |
27 | BaleLoader.EMPTY_HIDE_PUSHER2 = 7; |
28 | BaleLoader.EMPTY_ROTATE2 = 8; |
29 | BaleLoader.EMPTY_WAIT_TO_DROP = 9; |
30 | BaleLoader.EMPTY_WAIT_TO_SINK = 10; |
31 | BaleLoader.EMPTY_SINK = 11; |
32 | BaleLoader.EMPTY_CANCEL = 12; |
33 | BaleLoader.EMPTY_WAIT_TO_REDO = 13; |
34 | |
35 | BaleLoader.CHANGE_DROP_BALES = 1; |
36 | BaleLoader.CHANGE_SINK = 2; |
37 | BaleLoader.CHANGE_EMPTY_REDO = 3; |
38 | BaleLoader.CHANGE_EMPTY_START = 4; |
39 | BaleLoader.CHANGE_EMPTY_CANCEL = 5; |
40 | BaleLoader.CHANGE_MOVE_TO_WORK = 6; |
41 | BaleLoader.CHANGE_MOVE_TO_TRANSPORT = 7; |
42 | BaleLoader.CHANGE_GRAB_BALE = 8; |
43 | BaleLoader.CHANGE_GRAB_MOVE_UP = 9; |
44 | BaleLoader.CHANGE_GRAB_DROP_BALE = 10; |
45 | BaleLoader.CHANGE_GRAB_MOVE_DOWN = 11; |
46 | BaleLoader.CHANGE_FRONT_PUSHER = 12; |
47 | BaleLoader.CHANGE_ROTATE_PLATFORM = 13; |
48 | BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM = 14; |
49 | BaleLoader.CHANGE_EMPTY_ROTATE1 = 15; |
50 | BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS = 16; |
51 | BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1 = 17; |
52 | BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2 = 18; |
53 | BaleLoader.CHANGE_EMPTY_ROTATE2 = 19; |
54 | BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP = 20; |
55 | BaleLoader.CHANGE_EMPTY_STATE_NIL = 21; |
56 | BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO = 22; |
57 | |
58 | |
59 | BaleLoader.CHANGE_BUTTON_EMPTY = 23; |
60 | BaleLoader.CHANGE_BUTTON_EMPTY_ABORT = 24; |
61 | BaleLoader.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 | |
88 | function 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; |
241 | end; |
242 | |
243 | function 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; |
275 | end; |
276 | |
277 | function 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; |
400 | end; |
401 | |
402 | function 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; |
446 | end; |
447 | |
448 | function 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; |
468 | end; |
469 | |
470 | function BaleLoader:mouseEvent(posX, posY, isDown, isUp, button) |
471 | |
472 | end; |
473 | |
474 | function 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 |
507 | end |
508 | |
509 | |
510 | function BaleLoader:keyEvent(unicode, sym, modifier, isDown) |
511 | end; |
512 | |
513 | |
514 | function 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 | |
703 | end; |
704 | |
705 | function 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; |
749 | end; |
750 | |
751 | function 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; |
756 | end; |
757 | |
758 | function BaleLoader:onDeactivateSounds() |
759 | if self.isClient then |
760 | Utils.stopSample(self.sampleBaleLoaderHydraulic, true); |
761 | end; |
762 | end; |
763 | |
764 | function 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; |
831 | end |
832 | |
833 | function 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; |
884 | end |
885 | |
886 | function 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; |
1134 | end; |
1135 | |
1136 | function 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; |
1138 | end; |
1139 | |
1140 | function 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; |
1152 | end; |
1153 | |
1154 | function 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); |
1161 | end; |
1162 | |
1163 | function 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); |
1166 | end; |
1167 | |
1168 | function 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"; |
1174 | end |
1175 | |
1176 | function 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); |
1179 | end
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de