Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1 | -- |
2 | -- Baler |
3 | -- Class for all Balers |
4 | -- |
5 | -- @author Stefan Geiger |
6 | -- @date 10/09/08 |
7 | -- |
8 | -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved. |
9 | |
10 | source("dataS/scripts/vehicles/specializations/SetTurnedOnEvent.lua"); |
11 | source("dataS/scripts/vehicles/specializations/BalerSetIsUnloadingBaleEvent.lua"); |
12 | source("dataS/scripts/vehicles/specializations/BalerSetBaleTimeEvent.lua"); |
13 | source("dataS/scripts/vehicles/specializations/BalerCreateBaleEvent.lua"); |
14 | source("dataS/scripts/vehicles/specializations/BalerAreaEvent.lua"); |
15 | |
16 | Baler = {}; |
17 | |
18 | Baler.UNLOADING_CLOSED = 1; |
19 | Baler.UNLOADING_OPENING = 2; |
20 | Baler.UNLOADING_OPEN = 3; |
21 | Baler.UNLOADING_CLOSING = 4; |
22 | |
23 | function Baler.initSpecialization() |
24 | WorkArea.registerAreaType("baler"); |
25 | end; |
26 | |
27 | function Baler.prerequisitesPresent(specializations) |
28 | return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) and SpecializationUtil.hasSpecialization(Pickup, specializations); |
29 | end; |
30 | |
31 | function Baler:preLoad(xmlFile) |
32 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, Baler.loadWorkAreaFromXML); |
33 | end |
34 | |
35 | function Baler:load(xmlFile) |
36 | |
37 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, Baler.doCheckSpeedLimit); |
38 | self.allowPickingUp = Utils.overwrittenFunction(self.allowPickingUp, Baler.allowPickingUp); |
39 | |
40 | self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, Baler.getIsTurnedOnAllowed); |
41 | |
42 | self.getIsFoldAllowed = Utils.overwrittenFunction(self.getIsFoldAllowed, Baler.getIsFoldAllowed); |
43 | self.setFillLevel = Utils.appendedFunction(self.setFillLevel, Baler.setFillLevel); |
44 | self.isUnloadingAllowed = Baler.isUnloadingAllowed; |
45 | self.getTimeFromLevel = Baler.getTimeFromLevel; |
46 | self.moveBales = SpecializationUtil.callSpecializationsFunction("moveBales"); |
47 | self.moveBale = SpecializationUtil.callSpecializationsFunction("moveBale"); |
48 | self.allowFillType = Baler.allowFillType; |
49 | self.setIsUnloadingBale = Baler.setIsUnloadingBale; |
50 | self.dropBale = Baler.dropBale; |
51 | self.createBale = Baler.createBale; |
52 | self.setBaleTime = Baler.setBaleTime; |
53 | |
54 | self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1); |
55 | |
56 | local firstBaleMarker = getXMLFloat(xmlFile, "vehicle.baleAnimation#firstBaleMarker"); |
57 | if firstBaleMarker ~= nil then |
58 | local baleAnimCurve = AnimCurve:new(linearInterpolatorN); |
59 | local keyI = 0; |
60 | while true do |
61 | local key = string.format("vehicle.baleAnimation.key(%d)", keyI); |
62 | local t = getXMLFloat(xmlFile, key.."#time"); |
63 | local x,y,z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#pos")); |
64 | if x == nil or y == nil or z == nil then |
65 | break; |
66 | end; |
67 | local rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rot")); |
68 | rx = math.rad(Utils.getNoNil(rx, 0)); |
69 | ry = math.rad(Utils.getNoNil(ry, 0)); |
70 | rz = math.rad(Utils.getNoNil(rz, 0)); |
71 | baleAnimCurve:addKeyframe({ v={x, y, z, rx, ry, rz}, time = t}); |
72 | keyI = keyI +1; |
73 | end; |
74 | if keyI > 0 then |
75 | self.baleAnimCurve = baleAnimCurve; |
76 | self.firstBaleMarker = firstBaleMarker; |
77 | --self.baleFilename = Utils.getNoNil(getXMLString(xmlFile, "vehicle.baleAnimation#filename"), "data/maps/models/objects/strawbale/strawbaleBaler.i3d"); |
78 | end; |
79 | end; |
80 | self.baleAnimRoot, self.baleAnimRootComponent = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleAnimation#node")); |
81 | if self.baleAnimRoot == nil then |
82 | self.baleAnimRoot = self.components[1].node; |
83 | self.baleAnimRootComponent = self.components[1].node; |
84 | end |
85 | |
86 | |
87 | -- there is no standard bale animation, load the unload animation (for round baler) |
88 | if self.firstBaleMarker == nil then |
89 | local unloadAnimationName = getXMLString(xmlFile, "vehicle.baleAnimation#unloadAnimationName"); |
90 | local closeAnimationName = getXMLString(xmlFile, "vehicle.baleAnimation#closeAnimationName"); |
91 | local unloadAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.baleAnimation#unloadAnimationSpeed"), 1); |
92 | local closeAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.baleAnimation#closeAnimationSpeed"), 1); |
93 | if unloadAnimationName ~= nil and closeAnimationName ~= nil then |
94 | if self.playAnimation ~= nil and self.animations ~= nil then |
95 | if self.animations[unloadAnimationName] ~= nil and self.animations[closeAnimationName] ~= nil then |
96 | --print("has unload animation"); |
97 | self.baleUnloadAnimationName = unloadAnimationName; |
98 | self.baleUnloadAnimationSpeed = unloadAnimationSpeed; |
99 | |
100 | self.baleCloseAnimationName = closeAnimationName; |
101 | self.baleCloseAnimationSpeed = closeAnimationSpeed; |
102 | |
103 | self.baleDropAnimTime = getXMLFloat(xmlFile, "vehicle.baleAnimation#baleDropAnimTime"); |
104 | if self.baleDropAnimTime == nil then |
105 | self.baleDropAnimTime = self:getAnimationDuration(self.baleUnloadAnimationName); |
106 | else |
107 | self.baleDropAnimTime = self.baleDropAnimTime * 1000; |
108 | end; |
109 | else |
110 | print("Error: Failed to find unload animations '"..unloadAnimationName.."' and '"..closeAnimationName.."' in '"..self.configFileName.."'."); |
111 | end; |
112 | else |
113 | print("Error: There is an unload animation in '"..self.configFileName.."' but it is not a AnimatedVehicle. Change to a vehicle type which has the AnimatedVehicle specialization."); |
114 | end; |
115 | end; |
116 | end; |
117 | |
118 | -- Backward compatibility: Convert non-windrow fill types to the correspoding windrow fill types |
119 | local convertToWindrowFillType = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.fillTypes#convertToWindrowFillType"), true) |
120 | if convertToWindrowFillType then |
121 | local fillTypesToAdd = {}; |
122 | for fillType, enabled in pairs(self.fillTypes) do |
123 | if fillType ~= Fillable.FILLTYPE_UNKNOWN and enabled then |
124 | local fruitType = FruitUtil.fillTypeToFruitType[fillType]; |
125 | if fruitType ~= nil and not FruitUtil.fillTypeIsWindrow[fillType] then |
126 | local windrowFillType = FruitUtil.fruitTypeToWindrowFillType[fruitType]; |
127 | if windrowFillType ~= nil and not self.fillTypes[windrowFillType] then |
128 | self.fillTypes[fillType] = nil; |
129 | table.insert(fillTypesToAdd, windrowFillType); |
130 | print("Warning: converted non-windrow fill type to windrow fill type in "..self.configFileName); |
131 | end |
132 | end |
133 | end |
134 | end |
135 | for _,fillType in pairs(fillTypesToAdd) do |
136 | self.fillTypes[fillType] = true; |
137 | end |
138 | end |
139 | |
140 | self.baleTypes = {}; |
141 | local i = 0; |
142 | while true do |
143 | local key = string.format("vehicle.baleTypes.baleType(%d)", i); |
144 | if not hasXMLProperty(xmlFile, key) then |
145 | break; |
146 | end; |
147 | local isRoundBale = Utils.getNoNil(getXMLBool(xmlFile, key.."#isRoundBale"), false); |
148 | local width = Utils.round(Utils.getNoNil(getXMLFloat(xmlFile, key.."#width"), 1.2), 2); |
149 | local height = Utils.round(Utils.getNoNil(getXMLFloat(xmlFile, key.."#height"), 0.9), 2); |
150 | local length = Utils.round(Utils.getNoNil(getXMLFloat(xmlFile, key.."#length"), 2.4), 2); |
151 | local diameter = Utils.round(Utils.getNoNil(getXMLFloat(xmlFile, key.."#diameter"), 1.8), 2); |
152 | table.insert(self.baleTypes, {isRoundBale=isRoundBale, width=width, height=height, length=length, diameter=diameter}); |
153 | i = i + 1; |
154 | end; |
155 | self.currentBaleTypeId = 1; |
156 | |
157 | if table.getn(self.baleTypes) == 0 then |
158 | self.baleTypes = nil; |
159 | end; |
160 | |
161 | if self.isClient then |
162 | self.sampleBaler = Utils.loadSample(xmlFile, {}, "vehicle.balerSound", nil, self.baseDirectory); |
163 | self.sampleBalerAlarm = Utils.loadSample(xmlFile, {}, "vehicle.balerAlarm", nil, self.baseDirectory); |
164 | self.sampleBalerEject = Utils.loadSample(xmlFile, {}, "vehicle.balerBaleEject", nil, self.baseDirectory); |
165 | self.sampleBalerDoor = Utils.loadSample(xmlFile, {}, "vehicle.balerDoor", nil, self.baseDirectory); |
166 | self.sampleBalerKnotCleaning = Utils.loadSample(xmlFile, {}, "vehicle.balerKnotCleaning", nil, self.baseDirectory); |
167 | self.balerKnotCleaningTime = 100000; |
168 | |
169 | self.balerUVScrollParts = Utils.loadScrollers(self.components, xmlFile, "vehicle.balerUVScrollParts.balerUVScrollPart", {}, false); |
170 | self.balerTurnedOnRotationNodes = Utils.loadRotationNodes(xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "baler", self.components); |
171 | end; |
172 | |
173 | self.balingAnimationName = Utils.getNoNil(getXMLString(xmlFile, "vehicle.balingAnimation#name"), ""); |
174 | if self.playAnimation == nil or self.getIsAnimationPlaying == nil then |
175 | self.balingAnimationName = ""; |
176 | end; |
177 | |
178 | self.balerUnloadingState = Baler.UNLOADING_CLOSED; |
179 | self.balerPickupFillTypes = {}; |
180 | |
181 | self.bales = {}; |
182 | self.hasBaler = true; |
183 | |
184 | self.knotingAnimation = getXMLString(xmlFile, "vehicle.knotingAnimation#name"); |
185 | self.knotingAnimationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.knotingAnimation#speed"), 1); |
186 | |
187 | self.dummyBale = {}; |
188 | self.dummyBale.scaleNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleAnimation#scaleNode")); |
189 | self.dummyBale.baleNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleAnimation#baleNode")); |
190 | self.dummyBale.currentBaleFillType = Fillable.FILLTYPE_UNKNOWN; |
191 | self.dummyBale.currentBale = nil; |
192 | |
193 | self.allowsBaleUnloading = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.baleUnloading#allowed"), false); |
194 | self.baleUnloadingTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.baleUnloading#time"), 4) * 1000; |
195 | self.baleFoldThreshold = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.baleUnloading#foldThreshold"), 0.25) * self:getCapacity(); |
196 | |
197 | self.isBaleUnloading = false; |
198 | self.isBalerSpeedLimitActive = false; |
199 | end; |
200 | |
201 | function Baler:postLoad(xmlFile) |
202 | |
203 | for fillType, enabled in pairs(self.fillTypes) do |
204 | if enabled and fillType ~= Fillable.FILLTYPE_UNKNOWN then |
205 | if FruitUtil.fillTypeIsWindrow[fillType] then |
206 | table.insert(self.balerPickupFillTypes, fillType); |
207 | end |
208 | end |
209 | end |
210 | end |
211 | |
212 | function Baler:delete() |
213 | for k, bale in pairs(self.bales) do |
214 | self:dropBale(k); |
215 | end; |
216 | |
217 | if self.dummyBale.currentBale ~= nil then |
218 | delete(self.dummyBale.currentBale); |
219 | self.dummyBale.currentBale = nil; |
220 | end; |
221 | |
222 | if self.isClient then |
223 | Utils.deleteSample(self.sampleBaler); |
224 | Utils.deleteSample(self.sampleBalerAlarm); |
225 | Utils.deleteSample(self.sampleBalerDoor); |
226 | Utils.deleteSample(self.sampleBalerEject); |
227 | Utils.deleteSample(self.sampleBalerKnotCleaning); |
228 | end; |
229 | end; |
230 | |
231 | function Baler:readStream(streamId, connection) |
232 | if self.baleUnloadAnimationName ~= nil then |
233 | local state = streamReadUIntN(streamId, 7); |
234 | local animTime = streamReadFloat32(streamId); |
235 | if state == Baler.UNLOADING_CLOSED or state == Baler.UNLOADING_CLOSING then |
236 | self:setIsUnloadingBale(false, true); |
237 | self:setRealAnimationTime(self.baleCloseAnimationName, animTime); |
238 | elseif state == Baler.UNLOADING_OPEN or state == Baler.UNLOADING_OPENING then |
239 | self:setIsUnloadingBale(true, true); |
240 | self:setRealAnimationTime(self.baleUnloadAnimationName, animTime); |
241 | end |
242 | end; |
243 | |
244 | local numBales = streamReadUInt8(streamId); |
245 | for i=1, numBales do |
246 | local fillType = streamReadInt8(streamId); |
247 | local fillLevel = streamReadFloat32(streamId); |
248 | self:createBale(fillType, fillLevel); |
249 | if self.baleAnimCurve ~= nil then |
250 | local baleTime = streamReadFloat32(streamId); |
251 | self:setBaleTime(i, baleTime); |
252 | end; |
253 | end; |
254 | end; |
255 | |
256 | function Baler:writeStream(streamId, connection) |
257 | |
258 | if self.baleUnloadAnimationName ~= nil then |
259 | streamWriteUIntN(streamId, self.balerUnloadingState, 7); |
260 | local animTime = 0; |
261 | if self.balerUnloadingState == Baler.UNLOADING_CLOSED or self.balerUnloadingState == Baler.UNLOADING_CLOSING then |
262 | animTime = self:getRealAnimationTime(self.baleCloseAnimationName); |
263 | elseif self.balerUnloadingState == Baler.UNLOADING_OPEN or self.balerUnloadingState == Baler.UNLOADING_OPENING then |
264 | animTime = self:getRealAnimationTime(self.baleUnloadAnimationName); |
265 | end |
266 | streamWriteFloat32(streamId, animTime); |
267 | end |
268 | |
269 | streamWriteUInt8(streamId, table.getn(self.bales)); |
270 | for i=1, table.getn(self.bales) do |
271 | local bale = self.bales[i]; |
272 | streamWriteInt8(streamId, bale.fillType); |
273 | streamWriteFloat32(streamId, bale.fillLevel); |
274 | if self.baleAnimCurve ~= nil then |
275 | streamWriteFloat32(streamId, bale.time); |
276 | end; |
277 | end; |
278 | end; |
279 | |
280 | function Baler:readUpdateStream(streamId, timestamp, connection) |
281 | |
282 | end; |
283 | |
284 | function Baler:writeUpdateStream(streamId, connection, dirtyMask) |
285 | |
286 | end; |
287 | |
288 | function Baler:loadFromAttributesAndNodes(xmlFile, key, resetVehicles) |
289 | if not resetVehicles then |
290 | local numBales = getXMLInt(xmlFile, key.."#numBales"); |
291 | if numBales ~= nil then |
292 | self.balesToLoad = {}; |
293 | for i=1, numBales do |
294 | local baleKey = key..string.format(".bale(%d)", i-1); |
295 | |
296 | local bale = {}; |
297 | local fillTypeStr = getXMLString(xmlFile, baleKey.."#fillType"); |
298 | local fillType = Fillable.fillTypeNameToInt[fillTypeStr]; |
299 | bale.fillType = fillType; |
300 | bale.fillLevel = getXMLFloat(xmlFile, baleKey.."#fillLevel"); |
301 | bale.baleTime = getXMLFloat(xmlFile, baleKey.."#baleTime"); |
302 | table.insert(self.balesToLoad, bale); |
303 | end; |
304 | end; |
305 | end; |
306 | return BaseMission.VEHICLE_LOAD_OK; |
307 | end |
308 | |
309 | function Baler:getSaveAttributesAndNodes(nodeIdent) |
310 | |
311 | local attributes = 'numBales="'..table.getn(self.bales)..'"'; |
312 | local nodes = ""; |
313 | local baleNum = 0; |
314 | |
315 | for i=1, table.getn(self.bales) do |
316 | local bale = self.bales[i]; |
317 | local fillTypeStr = "unknown"; |
318 | if bale.fillType ~= Fillable.FILLTYPE_UNKNOWN then |
319 | fillTypeStr = Fillable.fillTypeIntToName[bale.fillType]; |
320 | end; |
321 | |
322 | if baleNum>0 then |
323 | nodes = nodes.."\n"; |
324 | end; |
325 | nodes = nodes..nodeIdent..'<bale fillType="'..fillTypeStr..'" fillLevel="'..bale.fillLevel..'"'; |
326 | if self.baleAnimCurve ~= nil then |
327 | nodes = nodes..' baleTime="'..bale.time..'"'; |
328 | end; |
329 | nodes = nodes..' />'; |
330 | baleNum = baleNum+1; |
331 | end; |
332 | return attributes,nodes; |
333 | end |
334 | |
335 | function Baler:mouseEvent(posX, posY, isDown, isUp, button) |
336 | end; |
337 | |
338 | function Baler:keyEvent(unicode, sym, modifier, isDown) |
339 | end; |
340 | |
341 | function Baler:update(dt) |
342 | |
343 | if self.firstTimeRun and self.balesToLoad ~= nil then |
344 | for k,v in pairs(self.balesToLoad) do |
345 | self:createBale(v.fillType, v.fillLevel); |
346 | self:setBaleTime(k, v.baleTime, true); |
347 | end; |
348 | self.balesToLoad = nil; |
349 | end; |
350 | |
351 | if self:getIsActiveForInput() then |
352 | if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then |
353 | if self:isUnloadingAllowed() then |
354 | if self.baleUnloadAnimationName ~= nil or self.allowsBaleUnloading then |
355 | if self.balerUnloadingState == Baler.UNLOADING_CLOSED then |
356 | if table.getn(self.bales) > 0 then |
357 | self:setIsUnloadingBale(true); |
358 | end; |
359 | elseif self.balerUnloadingState == Baler.UNLOADING_OPEN then |
360 | if self.baleUnloadAnimationName ~= nil then |
361 | self:setIsUnloadingBale(false); |
362 | end; |
363 | end; |
364 | end; |
365 | end; |
366 | end; |
367 | end; |
368 | |
369 | if self.isClient then |
370 | Utils.updateRotationNodes(self, self.balerTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn() ); |
371 | Utils.updateScrollers(self.balerUVScrollParts, dt, self:getIsActive() and self:getIsTurnedOn()); |
372 | end; |
373 | end; |
374 | |
375 | function Baler:updateTick(dt) |
376 | self.isBalerSpeedLimitActive = false; |
377 | if self:getIsActive() then |
378 | if self:getIsTurnedOn() then |
379 | if self:allowPickingUp() then |
380 | self.isBalerSpeedLimitActive = true; |
381 | if self.isServer then |
382 | local workAreasSend, _, _ = self:getTypedNetworkAreas(WorkArea.AREATYPE_BALER, false); |
383 | local totalArea =0; |
384 | local usedFillType = Fillable.FILLTYPE_UNKNOWN; |
385 | if table.getn(workAreasSend) > 0 then |
386 | |
387 | totalArea, usedFillType = BalerAreaEvent.runLocally(workAreasSend, self.balerPickupFillTypes); |
388 | if totalArea > 0 then |
389 | g_server:broadcastEvent(BalerAreaEvent:new(workAreasSend, usedFillType)); |
390 | end; |
391 | end; |
392 | |
393 | if totalArea > 0 then |
394 | local literPerSqm = FruitUtil.getFillTypeLiterPerSqm(usedFillType, 1); |
395 | local literPerPixel = g_currentMission:getFruitPixelsToSqm()*literPerSqm; |
396 | local deltaLevel = totalArea * literPerPixel * self.fillScale; |
397 | |
398 | if self.baleUnloadAnimationName == nil then |
399 | -- move all bales |
400 | local deltaTime = self:getTimeFromLevel(deltaLevel); |
401 | self:moveBales(deltaTime); |
402 | end; |
403 | |
404 | local oldFillLevel = self.fillLevel; |
405 | self:setFillLevel(self.fillLevel+deltaLevel, usedFillType); |
406 | if self.fillLevel >= self:getCapacity() then |
407 | if self.baleTypes ~= nil then |
408 | -- create bale |
409 | if self.baleAnimCurve ~= nil then |
410 | local restDeltaFillLevel = deltaLevel - (self.fillLevel-oldFillLevel) |
411 | self:setFillLevel(restDeltaFillLevel, usedFillType); |
412 | |
413 | self:createBale(usedFillType, self:getCapacity()); |
414 | |
415 | local numBales = table.getn(self.bales); |
416 | local bale = self.bales[numBales] |
417 | |
418 | self:moveBale(numBales, self:getTimeFromLevel(restDeltaFillLevel), true); |
419 | -- note: self.bales[numBales] can not be accessed anymore since the bale might be dropped already |
420 | g_server:broadcastEvent(BalerCreateBaleEvent:new(self, usedFillType, bale.time), nil, nil, self); |
421 | elseif self.baleUnloadAnimationName ~= nil then |
422 | |
423 | self:createBale(usedFillType, self:getCapacity()); |
424 | g_server:broadcastEvent(BalerCreateBaleEvent:new(self, usedFillType, 0), nil, nil, self); |
425 | end; |
426 | end; |
427 | end; |
428 | end; |
429 | end; |
430 | end; |
431 | |
432 | if self.isClient and self:getIsActiveForSound() then |
433 | if self.balerKnotCleaningTime <= g_currentMission.time then |
434 | Utils.playSample(self.sampleBalerKnotCleaning, 1, 0, nil); |
435 | self.balerKnotCleaningTime = g_currentMission.time + 120000; |
436 | end; |
437 | Utils.playSample(self.sampleBaler, 0, 0, nil); |
438 | end; |
439 | |
440 | else |
441 | if self.isBaleUnloading and self.isServer then |
442 | local deltaTime = dt / self.baleUnloadingTime; |
443 | self:moveBales(deltaTime); |
444 | end; |
445 | end; |
446 | |
447 | if self.isClient then |
448 | if not self:getIsTurnedOn() then |
449 | Utils.stopSample(self.sampleBalerKnotCleaning); |
450 | Utils.stopSample(self.sampleBaler); |
451 | end; |
452 | |
453 | if self:getIsTurnedOn() and self.fillLevel > (self:getCapacity() * 0.88) and self.fillLevel < self:getCapacity() then |
454 | -- start alarm sound |
455 | if self:getIsActiveForSound() then |
456 | Utils.playSample(self.sampleBalerAlarm, 0, 0, nil); |
457 | end; |
458 | else |
459 | Utils.stopSample(self.sampleBalerAlarm); |
460 | end; |
461 | end; |
462 | |
463 | if self.balerUnloadingState == Baler.UNLOADING_OPENING then |
464 | local isPlaying = self:getIsAnimationPlaying(self.baleUnloadAnimationName); |
465 | local animTime = self:getRealAnimationTime(self.baleUnloadAnimationName); |
466 | if not isPlaying or animTime >= self.baleDropAnimTime then |
467 | if table.getn(self.bales) > 0 then |
468 | self:dropBale(1); |
469 | if self.isServer then |
470 | self:setFillLevel(0, self.currentFillType); |
471 | end; |
472 | end; |
473 | if not isPlaying then |
474 | self.balerUnloadingState = Baler.UNLOADING_OPEN; |
475 | |
476 | if self.isClient then |
477 | Utils.stopSample(self.sampleBalerEject); |
478 | Utils.stopSample(self.sampleBalerDoor); |
479 | end; |
480 | end; |
481 | end; |
482 | elseif self.balerUnloadingState == Baler.UNLOADING_CLOSING then |
483 | if not self:getIsAnimationPlaying(self.baleCloseAnimationName) then |
484 | self.balerUnloadingState = Baler.UNLOADING_CLOSED; |
485 | if self.isClient then |
486 | Utils.stopSample(self.sampleBalerDoor); |
487 | end; |
488 | end; |
489 | end; |
490 | end; |
491 | end; |
492 | |
493 | function Baler:draw() |
494 | if self.isClient then |
495 | if self:getIsActiveForInput(true) then |
496 | if self:isUnloadingAllowed() then |
497 | if self.baleUnloadAnimationName ~= nil or self.allowsBaleUnloading then |
498 | if self.balerUnloadingState == Baler.UNLOADING_CLOSED then |
499 | if table.getn(self.bales) > 0 then |
500 | g_currentMission:addHelpButtonText(g_i18n:getText("baler_unload"), InputBinding.IMPLEMENT_EXTRA3); |
501 | end; |
502 | elseif self.balerUnloadingState == Baler.UNLOADING_OPEN then |
503 | if self.baleUnloadAnimationName ~= nil then |
504 | g_currentMission:addHelpButtonText(g_i18n:getText("baler_unload_stop"), InputBinding.IMPLEMENT_EXTRA3); |
505 | end; |
506 | end; |
507 | end; |
508 | end; |
509 | end |
510 | end; |
511 | end; |
512 | |
513 | function Baler:getIsFoldAllowed(superFunc) |
514 | if (table.getn(self.bales) > 0 and self.fillLevel > self.baleFoldThreshold) or self:getIsTurnedOn() then |
515 | return false; |
516 | end; |
517 | |
518 | if superFunc ~= nil then |
519 | return superFunc(self); |
520 | end |
521 | |
522 | return true; |
523 | end |
524 | |
525 | function Baler:onDeactivate() |
526 | if self.balingAnimationName ~= "" then |
527 | self:stopAnimation(self.balingAnimationName, true); |
528 | end; |
529 | end; |
530 | |
531 | function Baler:onDeactivateSounds() |
532 | if self.isClient then |
533 | Utils.stopSample(self.sampleBaler, true); |
534 | Utils.stopSample(self.sampleBalerAlarm, true); |
535 | Utils.stopSample(self.sampleBalerDoor, true); |
536 | Utils.stopSample(self.sampleBalerEject, true); |
537 | Utils.stopSample(self.sampleBalerKnotCleaning, true); |
538 | end; |
539 | end; |
540 | |
541 | function Baler:setFillLevel(fillLevel, fillType, force) |
542 | if self.dummyBale.baleNode ~= nil and fillLevel > 0 and (self.dummyBale.currentBale == nil or self.dummyBale.currentBaleFillType ~= fillType) then |
543 | if self.dummyBale.currentBale ~= nil then |
544 | delete(self.dummyBale.currentBale); |
545 | self.dummyBale.currentBale = nil; |
546 | end; |
547 | local t = self.baleTypes[self.currentBaleTypeId]; |
548 | local baleType = BaleUtil.getBale(fillType, t.width, t.height, t.length, t.diameter, t.isRoundBale); |
549 | |
550 | local baleRoot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory, false, false); |
551 | local baleId = getChildAt(baleRoot, 0); |
552 | setRigidBodyType(baleId, "NoRigidBody"); |
553 | link(self.dummyBale.baleNode, baleId); |
554 | delete(baleRoot); |
555 | self.dummyBale.currentBale = baleId; |
556 | self.dummyBale.currentBaleFillType = fillType; |
557 | end; |
558 | |
559 | if self.dummyBale.currentBale ~= nil then |
560 | local percent = fillLevel / self:getCapacity(); |
561 | local y = 1; |
562 | if getUserAttribute(self.dummyBale.currentBale, "isRoundbale") then |
563 | y = percent; |
564 | end; |
565 | setScale(self.dummyBale.scaleNode, 1, y, percent); |
566 | end; |
567 | end; |
568 | |
569 | function Baler:onTurnedOn(noEventSend) |
570 | if self.setFoldState ~= nil then |
571 | self:setFoldState(-1); |
572 | end; |
573 | if self.balingAnimationName ~= "" then |
574 | self:playAnimation(self.balingAnimationName, 1, self:getAnimationTime(self.balingAnimationName), true); |
575 | end; |
576 | end; |
577 | |
578 | function Baler:onTurnedOff(noEventSend) |
579 | if self.balingAnimationName ~= "" then |
580 | self:stopAnimation(self.balingAnimationName, true); |
581 | end; |
582 | end; |
583 | |
584 | function Baler:doCheckSpeedLimit(superFunc) |
585 | local parent = true; |
586 | if superFunc ~= nil then |
587 | parent = superFunc(self); |
588 | end |
589 | |
590 | return parent and self.isBalerSpeedLimitActive; |
591 | end; |
592 | |
593 | function Baler:isUnloadingAllowed() |
594 | if self.hasBaleWrapper == nil or not self.hasBaleWrapper then |
595 | return not self.allowsBaleUnloading or (self.allowsBaleUnloading and not self:getIsTurnedOn() and not self.isBaleUnloading); |
596 | end; |
597 | |
598 | return self:allowsGrabbingBale(); |
599 | end; |
600 | |
601 | function Baler:setIsUnloadingBale(isUnloadingBale, noEventSend) |
602 | if self.baleUnloadAnimationName ~= nil then |
603 | if isUnloadingBale then |
604 | if self.balerUnloadingState ~= Baler.UNLOADING_OPENING then |
605 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
606 | self.balerUnloadingState = Baler.UNLOADING_OPENING; |
607 | if self.isClient and self:getIsActiveForSound() then |
608 | Utils.playSample(self.sampleBalerEject, 1, 0, nil); |
609 | Utils.playSample(self.sampleBalerDoor, 1, 0, nil); |
610 | end; |
611 | self:playAnimation(self.baleUnloadAnimationName, self.baleUnloadAnimationSpeed, nil, true); |
612 | end; |
613 | else |
614 | if self.balerUnloadingState ~= Baler.UNLOADING_CLOSING then |
615 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend) |
616 | self.balerUnloadingState = Baler.UNLOADING_CLOSING; |
617 | if self.isClient and self:getIsActiveForSound() then |
618 | Utils.playSample(self.sampleBalerDoor, 1, 0, nil); |
619 | end; |
620 | self:playAnimation(self.baleCloseAnimationName, self.baleCloseAnimationSpeed, nil, true); |
621 | end; |
622 | end; |
623 | elseif self.allowsBaleUnloading then |
624 | if isUnloadingBale then |
625 | BalerSetIsUnloadingBaleEvent.sendEvent(self, isUnloadingBale, noEventSend); |
626 | self.isBaleUnloading = true; |
627 | end; |
628 | end; |
629 | end; |
630 | |
631 | function Baler:getTimeFromLevel(level) |
632 | -- level = capacity -> time = firstBaleMarker |
633 | -- level = 0 -> time = 0 |
634 | if self.firstBaleMarker ~= nil then |
635 | return level / self:getCapacity() * self.firstBaleMarker; |
636 | end; |
637 | return 0; |
638 | end; |
639 | |
640 | function Baler:moveBales(dt) |
641 | for i=table.getn(self.bales), 1, -1 do |
642 | self:moveBale(i, dt); |
643 | end; |
644 | end; |
645 | |
646 | function Baler:moveBale(i, dt, noEventSend) |
647 | local bale = self.bales[i]; |
648 | self:setBaleTime(i, bale.time + dt, noEventSend) |
649 | end; |
650 | |
651 | function Baler:setBaleTime(i, baleTime, noEventSend) |
652 | if self.baleAnimCurve ~= nil then |
653 | local bale = self.bales[i]; |
654 | bale.time = baleTime; |
655 | if self.isServer then |
656 | local v = self.baleAnimCurve:get(bale.time); |
657 | --setTranslation(bale.id, v[1], v[2], v[3]); |
658 | --setRotation(bale.id, v[4], v[5], v[6]); |
659 | setTranslation(bale.baleJointNode, v[1], v[2], v[3]); |
660 | setRotation(bale.baleJointNode, v[4], v[5], v[6]); |
661 | setJointFrame(bale.baleJointIndex, 0, bale.baleJointNode); |
662 | end; |
663 | if bale.time >= 1 then |
664 | self:dropBale(i); |
665 | end; |
666 | if table.getn(self.bales) == 0 then |
667 | self.isBaleUnloading = false; |
668 | end; |
669 | if self.isServer then |
670 | if noEventSend == nil or not noEventSend then |
671 | g_server:broadcastEvent(BalerSetBaleTimeEvent:new(self, i, bale.time), nil, nil, self); |
672 | end; |
673 | end; |
674 | end; |
675 | end; |
676 | |
677 | -- overwrite Fillable.allowFillType |
678 | function Baler:allowFillType(fillType) |
679 | return self.fillTypes[fillType] == true; |
680 | end; |
681 | |
682 | function Baler:allowPickingUp(superFunc) |
683 | if self.baleUnloadAnimationName ~= nil then |
684 | if table.getn(self.bales) > 0 or self.balerUnloadingState ~= Baler.UNLOADING_CLOSED then |
685 | return false; |
686 | end; |
687 | end; |
688 | |
689 | if superFunc ~= nil then |
690 | return superFunc(self); |
691 | end |
692 | return true; |
693 | end; |
694 | |
695 | function Baler:createBale(baleFillType, fillLevel) |
696 | |
697 | if self.knotingAnimation ~= nil then |
698 | self:playAnimation(self.knotingAnimation, self.knotingAnimationSpeed, nil, true); |
699 | end; |
700 | |
701 | if self.dummyBale.currentBale ~= nil then |
702 | delete(self.dummyBale.currentBale); |
703 | self.dummyBale.currentBale = nil; |
704 | end; |
705 | |
706 | local t = self.baleTypes[self.currentBaleTypeId]; |
707 | local baleType = BaleUtil.getBale(baleFillType, t.width, t.height, t.length, t.diameter, t.isRoundBale); |
708 | |
709 | local bale = {}; |
710 | bale.filename = Utils.getFilename(baleType.filename, self.baseDirectory); |
711 | bale.time = 0; |
712 | bale.fillType = baleFillType; |
713 | bale.fillLevel = fillLevel; |
714 | |
715 | if self.baleUnloadAnimationName ~= nil then |
716 | local baleRoot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory, false, false); |
717 | local baleId = getChildAt(baleRoot, 0); |
718 | link(self.baleAnimRoot, baleId); |
719 | delete(baleRoot); |
720 | bale.id = baleId; |
721 | end; |
722 | |
723 | if self.isServer and self.baleUnloadAnimationName == nil then |
724 | local x,y,z = getWorldTranslation(self.baleAnimRoot); |
725 | local rx,ry,rz = getWorldRotation(self.baleAnimRoot); |
726 | |
727 | local baleObject = Bale:new(self.isServer, self.isClient); |
728 | baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel); |
729 | baleObject:register(); |
730 | |
731 | local baleJointNode = createTransformGroup("BaleJointTG"); |
732 | link(self.baleAnimRoot, baleJointNode); |
733 | setTranslation(baleJointNode, 0,0,0); |
734 | setRotation(baleJointNode, 0,0,0); |
735 | |
736 | local constr = JointConstructor:new(); |
737 | constr:setActors(self.baleAnimRootComponent, baleObject.nodeId); |
738 | constr:setJointTransforms(baleJointNode, baleObject.nodeId); |
739 | for i=1, 3 do |
740 | constr:setRotationLimit(i-1, 0, 0); |
741 | constr:setTranslationLimit(i-1, true, 0, 0); |
742 | end; |
743 | constr:setEnableCollision(false); |
744 | local baleJointIndex = constr:finalize(); |
745 | |
746 | g_currentMission:removeItemToSave(baleObject); |
747 | |
748 | bale.baleJointNode = baleJointNode; |
749 | bale.baleJointIndex = baleJointIndex; |
750 | bale.baleObject = baleObject; |
751 | end; |
752 | |
753 | table.insert(self.bales, bale); |
754 | end; |
755 | |
756 | function Baler:dropBale(baleIndex) |
757 | local bale = self.bales[baleIndex]; |
758 | |
759 | if self.isServer then |
760 | local baleObject; |
761 | |
762 | if bale.baleJointIndex ~= nil then |
763 | baleObject = bale.baleObject; |
764 | removeJoint(bale.baleJointIndex); |
765 | delete(bale.baleJointNode); |
766 | g_currentMission:addItemToSave(bale.baleObject); |
767 | else |
768 | baleObject = Bale:new(self.isServer, self.isClient); |
769 | local x,y,z = getWorldTranslation(bale.id); |
770 | local rx,ry,rz = getWorldRotation(bale.id); |
771 | baleObject:load(bale.filename, x,y,z,rx,ry,rz, bale.fillLevel); |
772 | baleObject:register(); |
773 | delete(bale.id) |
774 | end; |
775 | |
776 | if (not self.hasBaleWrapper or self.moveBaleToWrapper == nil) and baleObject.nodeId ~= nil then |
777 | -- release bale if there's no bale wrapper |
778 | local x,y,z = getWorldTranslation(baleObject.nodeId) |
779 | local vx,vy,vz = getVelocityAtWorldPos(self.baleAnimRootComponent, x,y,z); |
780 | setLinearVelocity(baleObject.nodeId, vx,vy,vz); |
781 | elseif self.moveBaleToWrapper ~= nil then |
782 | -- move bale to wrapper |
783 | self:moveBaleToWrapper(baleObject); |
784 | end; |
785 | end; |
786 | |
787 | Utils.releaseSharedI3DFile(bale.filename, nil, true); |
788 | --delete(bale.id); |
789 | table.remove(self.bales, baleIndex); |
790 | |
791 | g_currentMission.missionStats:updateStats("baleCount", 1); |
792 | end; |
793 | |
794 | function Baler:getIsTurnedOnAllowed(superFunc, isTurnedOn) |
795 | if isTurnedOn and self.isBaleUnloading then |
796 | return false; |
797 | end; |
798 | |
799 | if superFunc ~= nil then |
800 | return superFunc(self, isTurnedOn); |
801 | end |
802 | |
803 | return true; |
804 | end; |
805 | |
806 | function Baler:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
807 | local retValue = true; |
808 | if superFunc ~= nil then |
809 | retValue = superFunc(self, workArea, xmlFile, key) |
810 | end |
811 | |
812 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
813 | workArea.type = WorkArea.AREATYPE_BALER; |
814 | end; |
815 | |
816 | return retValue; |
817 | end; |
818 | |
819 | function Baler.getDefaultSpeedLimit() |
820 | return 25; |
821 | end;
|
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de