1222 | function BaleLoader:doStateChange(id, nearestBaleServerId) |
1223 | local spec = self.spec_baleLoader |
1224 | |
1225 | if id == BaleLoader.CHANGE_DROP_BALES then |
1226 | -- drop all bales to ground (and add to save by mission) |
1227 | spec.currentBalePlace = 1 |
1228 | for _, balePlace in pairs(spec.balePlaces) do |
1229 | if balePlace.bales ~= nil then |
1230 | for _, baleServerId in pairs(balePlace.bales) do |
1231 | local bale = NetworkUtil.getObject(baleServerId) |
1232 | if bale ~= nil then |
1233 | if spec.mountDynamic then |
1234 | self:unmountDynamicBale(bale) |
1235 | else |
1236 | bale:unmount() |
1237 | end |
1238 | |
1239 | -- clear bales in trigger table |
1240 | if spec.baleGrabber.balesInTrigger[bale] ~= nil then |
1241 | spec.baleGrabber.balesInTrigger[bale] = nil |
1242 | end |
1243 | end |
1244 | spec.balesToMount[baleServerId] = nil |
1245 | end |
1246 | balePlace.bales = nil |
1247 | end |
1248 | end |
1249 | |
1250 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -math.huge, self:getFillUnitFirstSupportedFillType(spec.fillUnitIndex), ToolType.UNDEFINED, nil) |
1251 | for _, place in pairs(spec.balePlaces) do |
1252 | if place.collision ~= nil then |
1253 | setIsCompoundChild(place.collision, false) |
1254 | end |
1255 | end |
1256 | |
1257 | self:playAnimation("releaseFrontplattform", 1, nil, true) |
1258 | self:playAnimation("closeGrippers", -1, nil, true) |
1259 | spec.emptyState = BaleLoader.EMPTY_WAIT_TO_SINK |
1260 | elseif id == BaleLoader.CHANGE_SINK then |
1261 | if spec.resetEmptyRotateAnimation then |
1262 | self:playAnimation("emptyRotate", -1, nil, true) |
1263 | end |
1264 | self:playAnimation("moveBalePlacesToEmpty", -1, nil, true) |
1265 | self:playAnimation("emptyHidePusher1", -1, nil, true) |
1266 | self:playAnimation(spec.animations.rotatePlatformEmpty, -1, nil, true) |
1267 | if not spec.isInWorkPosition then |
1268 | self:playAnimation("closeGrippers", 1, self:getAnimationTime("closeGrippers"), true) |
1269 | end |
1270 | spec.emptyState = BaleLoader.EMPTY_SINK |
1271 | elseif id == BaleLoader.CHANGE_EMPTY_REDO then |
1272 | self:playAnimation("emptyRotate", 1, nil, true) |
1273 | spec.emptyState = BaleLoader.EMPTY_ROTATE2 |
1274 | elseif id == BaleLoader.CHANGE_EMPTY_START then |
1275 | -- move to work position in case it is not there now |
1276 | BaleLoader.moveToWorkPosition(self) |
1277 | spec.emptyState = BaleLoader.EMPTY_TO_WORK |
1278 | elseif id == BaleLoader.CHANGE_EMPTY_CANCEL then |
1279 | self:playAnimation("emptyRotate", -1, nil, true) |
1280 | spec.emptyState = BaleLoader.EMPTY_CANCEL |
1281 | elseif id == BaleLoader.CHANGE_MOVE_TO_TRANSPORT then |
1282 | if spec.isInWorkPosition then |
1283 | spec.grabberIsMoving = true |
1284 | spec.isInWorkPosition = false |
1285 | g_animationManager:stopAnimations(spec.animationNodes) |
1286 | -- move to transport position |
1287 | BaleLoader.moveToTransportPosition(self) |
1288 | end |
1289 | elseif id == BaleLoader.CHANGE_MOVE_TO_WORK then |
1290 | if not spec.isInWorkPosition then |
1291 | spec.grabberIsMoving = true |
1292 | spec.isInWorkPosition = true |
1293 | g_animationManager:startAnimations(spec.animationNodes) |
1294 | -- move to work position |
1295 | BaleLoader.moveToWorkPosition(self) |
1296 | end |
1297 | elseif id == BaleLoader.CHANGE_GRAB_BALE then |
1298 | local bale = NetworkUtil.getObject(nearestBaleServerId) |
1299 | spec.baleGrabber.currentBale = nearestBaleServerId |
1300 | if bale ~= nil then |
1301 | if spec.mountDynamic then |
1302 | self:mountDynamicBale(bale, spec.baleGrabber.grabNode) |
1303 | else |
1304 | bale:mount(self, spec.baleGrabber.grabNode, 0,0,0, 0,0,0) |
1305 | end |
1306 | |
1307 | spec.balesToMount[nearestBaleServerId] = nil |
1308 | else |
1309 | spec.balesToMount[nearestBaleServerId] = {serverId=nearestBaleServerId, linkNode=spec.baleGrabber.grabNode, trans={0,0,0}, rot={0,0,0} } |
1310 | end |
1311 | spec.grabberMoveState = BaleLoader.GRAB_MOVE_UP |
1312 | self:playAnimation("baleGrabberWorkToDrop", 1, nil, true) |
1313 | |
1314 | self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, 1, self:getFillUnitFirstSupportedFillType(spec.fillUnitIndex), ToolType.UNDEFINED, nil) |
1315 | for i, place in pairs(spec.balePlaces) do |
1316 | if place.collision ~= nil then |
1317 | if i <= self:getFillUnitFillLevel(spec.fillUnitIndex) then |
1318 | setIsCompoundChild(place.collision, true) |
1319 | else |
1320 | setIsCompoundChild(place.collision, false) |
1321 | end |
1322 | end |
1323 | end |
1324 | |
1325 | if self.isClient then |
1326 | g_soundManager:playSample(spec.samples.grab) |
1327 | |
1328 | if spec.grabParticleSystem ~= nil then |
1329 | ParticleUtil.setEmittingState(spec.grabParticleSystem, true) |
1330 | spec.grabParticleSystemDisableTime = g_currentMission.time + spec.grabParticleSystemDisableDuration |
1331 | end |
1332 | end |
1333 | elseif id == BaleLoader.CHANGE_GRAB_MOVE_UP then |
1334 | spec.currentBaleGrabberDropBaleAnimName = self:getBaleGrabberDropBaleAnimName() |
1335 | self:playAnimation(spec.currentBaleGrabberDropBaleAnimName, 1, nil, true) |
1336 | spec.grabberMoveState = BaleLoader.GRAB_DROP_BALE |
1337 | elseif id == BaleLoader.CHANGE_GRAB_DROP_BALE then |
1338 | -- drop bale at platform |
1339 | if spec.startBalePlace.count < spec.startBalePlace.numOfPlaces and spec.startBalePlace.node ~= nil then |
1340 | local attachNode = getChildAt(spec.startBalePlace.node, spec.startBalePlace.count) |
1341 | local bale = NetworkUtil.getObject(spec.baleGrabber.currentBale) |
1342 | if bale ~= nil then |
1343 | if spec.mountDynamic then |
1344 | self:mountDynamicBale(bale, attachNode) |
1345 | else |
1346 | local rx, ry, rz = 0, 0, 0 |
1347 | if spec.keepBaleRotationDuringLoad then |
1348 | rx, ry, rz = localRotationToLocal(bale.nodeId, attachNode, 0, 0, 0) |
1349 | end |
1350 | |
1351 | bale:mount(self, attachNode, 0, 0, 0, rx, ry, rz) |
1352 | end |
1353 | |
1354 | spec.balesToMount[spec.baleGrabber.currentBale] = nil |
1355 | else |
1356 | spec.balesToMount[spec.baleGrabber.currentBale] = {serverId=spec.baleGrabber.currentBale, linkNode=attachNode, trans={0,0,0}, rot={0,0,0} } |
1357 | end |
1358 | |
1359 | spec.startBalePlace.count = spec.startBalePlace.count + 1 |
1360 | table.insert(spec.startBalePlace.bales, spec.baleGrabber.currentBale) |
1361 | spec.baleGrabber.currentBale = nil |
1362 | --setRotation(baleNode, 0, 0, 0) |
1363 | --setTranslation(baleNode, 0, 0, 0) |
1364 | |
1365 | if spec.startBalePlace.count < spec.startBalePlace.numOfPlaces then |
1366 | spec.frontBalePusherDirection = 1 |
1367 | self:playAnimation("balesToOtherRow", 1, nil, true) |
1368 | self:playAnimation("frontBalePusher", 1, nil, true) |
1369 | elseif spec.startBalePlace.count == spec.startBalePlace.numOfPlaces then |
1370 | BaleLoader.rotatePlatform(self) |
1371 | end |
1372 | |
1373 | if spec.animations.grabberDropToWork ~= nil then |
1374 | self:playAnimation(spec.animations.grabberDropToWork, 1, 0, true) |
1375 | else |
1376 | self:playAnimation(spec.currentBaleGrabberDropBaleAnimName, -spec.animations.grabberDropBaleReverseSpeed, nil, true) |
1377 | self:playAnimation("baleGrabberWorkToDrop", -1, nil, true) |
1378 | end |
1379 | spec.grabberMoveState = BaleLoader.GRAB_MOVE_DOWN |
1380 | end |
1381 | elseif id == BaleLoader.CHANGE_GRAB_MOVE_DOWN then |
1382 | spec.grabberMoveState = nil |
1383 | elseif id == BaleLoader.CHANGE_FRONT_PUSHER then |
1384 | if spec.frontBalePusherDirection > 0 then |
1385 | self:playAnimation("frontBalePusher", -1, nil, true) |
1386 | spec.frontBalePusherDirection = -1 |
1387 | else |
1388 | spec.frontBalePusherDirection = 0 |
1389 | end |
1390 | elseif id == BaleLoader.CHANGE_ROTATE_PLATFORM then |
1391 | if spec.rotatePlatformDirection > 0 then |
1392 | -- drop bales |
1393 | local balePlace = spec.balePlaces[spec.currentBalePlace] |
1394 | spec.currentBalePlace = spec.currentBalePlace + 1 |
1395 | for i=1, table.getn(spec.startBalePlace.bales) do |
1396 | local node = getChildAt(spec.startBalePlace.node, i-1) |
1397 | local x,y,z = getTranslation(node) |
1398 | local rx,ry,rz = getRotation(node) |
1399 | local baleServerId = spec.startBalePlace.bales[i] |
1400 | local bale = NetworkUtil.getObject(baleServerId) |
1401 | |
1402 | if bale ~= nil then |
1403 | if spec.keepBaleRotationDuringLoad then |
1404 | x, y, z = localToLocal(bale.nodeId, balePlace.node, 0, 0, 0) |
1405 | rx, ry, rz = localRotationToLocal(bale.nodeId, balePlace.node, 0, 0, 0) |
1406 | end |
1407 | |
1408 | if spec.mountDynamic then |
1409 | self:mountDynamicBale(bale, balePlace.node) |
1410 | else |
1411 | bale:mount(spec, balePlace.node, x,y,z, rx,ry,rz) |
1412 | end |
1413 | |
1414 | spec.balesToMount[baleServerId] = nil |
1415 | else |
1416 | spec.balesToMount[baleServerId] = {serverId=baleServerId, linkNode=balePlace.node, trans={ x,y,z}, rot={rx,ry,rz} } |
1417 | end |
1418 | end |
1419 | balePlace.bales = spec.startBalePlace.bales |
1420 | spec.startBalePlace.bales = {} |
1421 | spec.startBalePlace.count = 0 |
1422 | |
1423 | for i=1, spec.startBalePlace.numOfPlaces do |
1424 | local node = getChildAt(spec.startBalePlace.node, i-1) |
1425 | setRotation(node, unpack(spec.startBalePlace.origRot[i])) |
1426 | setTranslation(node, unpack(spec.startBalePlace.origTrans[i])) |
1427 | end |
1428 | |
1429 | if spec.emptyState == BaleLoader.EMPTY_NONE then |
1430 | -- we are not waiting to start emptying, rotate back |
1431 | if self:getAnimationTime("baleGrabberWorkToDrop") < spec.moveBalePlacesMaxGrabberTime or spec.moveBalePlacesMaxGrabberTime == math.huge then |
1432 | spec.rotatePlatformDirection = -1 |
1433 | self:playAnimation(spec.animations.rotatePlatformBack, -1, nil, true) |
1434 | |
1435 | if spec.moveBalePlacesAfterRotatePlatform then |
1436 | -- currentBalePlace+1 needs to be at the first position |
1437 | if spec.currentBalePlace <= table.getn(spec.balePlaces) or spec.alwaysMoveBalePlaces then |
1438 | self:playAnimation("moveBalePlaces", 1, (spec.currentBalePlace-1)/table.getn(spec.balePlaces), true) |
1439 | self:setAnimationStopTime("moveBalePlaces", (spec.currentBalePlace)/table.getn(spec.balePlaces)) |
1440 | self:playAnimation("moveBalePlacesExtrasOnce", 1, nil, true) |
1441 | end |
1442 | end |
1443 | else |
1444 | spec.rotatePlatformDirection = -1 |
1445 | spec.moveBalePlacesDelayedMovement = true |
1446 | end |
1447 | else |
1448 | spec.rotatePlatformDirection = 0 |
1449 | end |
1450 | else |
1451 | spec.rotatePlatformDirection = 0 |
1452 | end |
1453 | elseif id == BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM then |
1454 | spec.emptyState = BaleLoader.EMPTY_ROTATE_PLATFORM |
1455 | if spec.startBalePlace.count == 0 then |
1456 | self:playAnimation(spec.animations.rotatePlatformEmpty, 1, nil, true) |
1457 | else |
1458 | BaleLoader.rotatePlatform(self) |
1459 | end |
1460 | elseif id == BaleLoader.CHANGE_EMPTY_ROTATE1 then |
1461 | self:playAnimation("emptyRotate", 1, nil, true) |
1462 | self:setAnimationStopTime("emptyRotate", 0.2) |
1463 | local balePlacesTime = self:getRealAnimationTime("moveBalePlaces") |
1464 | self:playAnimation("moveBalePlacesToEmpty", 1.5, balePlacesTime/self:getAnimationDuration("moveBalePlacesToEmpty"), true) |
1465 | self:playAnimation("moveBalePusherToEmpty", 1.5, balePlacesTime/self:getAnimationDuration("moveBalePusherToEmpty"), true) |
1466 | spec.emptyState = BaleLoader.EMPTY_ROTATE1 |
1467 | |
1468 | if self.isClient then |
1469 | g_soundManager:playSample(spec.samples.emptyRotate) |
1470 | end |
1471 | elseif id == BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS then |
1472 | self:playAnimation("closeGrippers", 1, nil, true) |
1473 | spec.emptyState = BaleLoader.EMPTY_CLOSE_GRIPPERS |
1474 | elseif id == BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1 then |
1475 | self:playAnimation("emptyHidePusher1", 1, nil, true) |
1476 | spec.emptyState = BaleLoader.EMPTY_HIDE_PUSHER1 |
1477 | elseif id == BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2 then |
1478 | self:playAnimation("moveBalePusherToEmpty", -2, nil, true) |
1479 | spec.emptyState = BaleLoader.EMPTY_HIDE_PUSHER2 |
1480 | elseif id == BaleLoader.CHANGE_EMPTY_ROTATE2 then |
1481 | self:playAnimation("emptyRotate", 1, self:getAnimationTime("emptyRotate"), true) |
1482 | spec.emptyState = BaleLoader.EMPTY_ROTATE2 |
1483 | elseif id == BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP then |
1484 | -- wait for the user to react (abort or drop) |
1485 | spec.emptyState = BaleLoader.EMPTY_WAIT_TO_DROP |
1486 | elseif id == BaleLoader.CHANGE_EMPTY_STATE_NIL then |
1487 | spec.emptyState = BaleLoader.EMPTY_NONE |
1488 | if spec.transportPositionAfterUnloading then |
1489 | BaleLoader.moveToTransportPosition(self) |
1490 | if self.isServer then |
1491 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_MOVE_TO_TRANSPORT), true, nil, self) |
1492 | end |
1493 | end |
1494 | elseif id == BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO then |
1495 | spec.emptyState = BaleLoader.EMPTY_WAIT_TO_REDO |
1496 | elseif id == BaleLoader.CHANGE_BUTTON_EMPTY then |
1497 | -- Server only code |
1498 | assert(self.isServer) |
1499 | if spec.emptyState ~= BaleLoader.EMPTY_NONE then |
1500 | if spec.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP then |
1501 | -- BaleLoader.CHANGE_DROP_BALES |
1502 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_DROP_BALES), true, nil, self) |
1503 | elseif spec.emptyState == BaleLoader.EMPTY_WAIT_TO_SINK then |
1504 | -- BaleLoader.CHANGE_SINK |
1505 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_SINK), true, nil, self) |
1506 | elseif spec.emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then |
1507 | -- BaleLoader.CHANGE_EMPTY_REDO |
1508 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_REDO), true, nil, self) |
1509 | end |
1510 | else |
1511 | --BaleLoader.CHANGE_EMPTY_START |
1512 | if BaleLoader.getAllowsStartUnloading(self) then |
1513 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_START), true, nil, self) |
1514 | end |
1515 | end |
1516 | elseif id == BaleLoader.CHANGE_BUTTON_EMPTY_ABORT then |
1517 | -- Server only code |
1518 | assert(self.isServer) |
1519 | if spec.emptyState ~= BaleLoader.EMPTY_NONE then |
1520 | if spec.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP then |
1521 | --BaleLoader.CHANGE_EMPTY_CANCEL |
1522 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_CANCEL), true, nil, self) |
1523 | end |
1524 | end |
1525 | elseif id == BaleLoader.CHANGE_BUTTON_WORK_TRANSPORT then |
1526 | -- Server only code |
1527 | assert(self.isServer) |
1528 | if spec.emptyState == BaleLoader.EMPTY_NONE and spec.grabberMoveState == nil then |
1529 | if spec.isInWorkPosition then |
1530 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_MOVE_TO_TRANSPORT), true, nil, self) |
1531 | else |
1532 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_MOVE_TO_WORK), true, nil, self) |
1533 | end |
1534 | end |
1535 | end |
1536 | end |
134 | function BaleLoader:onLoad(savegame) |
135 | local spec = self.spec_baleLoader |
136 | |
137 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleloaderTurnedOnScrollers.baleloaderTurnedOnScroller", "vehicle.baleLoader.animationNodes.animationNode") --FS17 to FS19 |
138 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleGrabber", "vehicle.baleLoader.grabber") --FS17 to FS19 |
139 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.balePlaces", "vehicle.baleLoader.balePlaces") --FS17 to FS19 |
140 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.grabParticleSystem", "vehicle.baleLoader.grabber.grabParticleSystem") --FS17 to FS19 |
141 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#pickupRange", "vehicle.baleLoader.grabber#pickupRange") --FS17 to FS19 |
142 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleTypes", "vehicle.baleLoader.baleTypes") --FS17 to FS19 |
143 | |
144 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textTransportPosition", "vehicle.baleLoader.texts#transportPosition") --FS17 to FS19 |
145 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textOperatingPosition", "vehicle.baleLoader.texts#operatingPosition") --FS17 to FS19 |
146 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textUnload", "vehicle.baleLoader.texts#unload") --FS17 to FS19 |
147 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textTilting", "vehicle.baleLoader.texts#tilting") --FS17 to FS19 |
148 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textLowering", "vehicle.baleLoader.texts#lowering") --FS17 to FS19 |
149 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textLowerPlattform", "vehicle.baleLoader.texts#lowerPlattform") --FS17 to FS19 |
150 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textAbortUnloading", "vehicle.baleLoader.texts#abortUnloading") --FS17 to FS19 |
151 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#textUnloadHere", "vehicle.baleLoader.texts#unloadHere") --FS17 to FS19 |
152 | |
153 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#rotatePlatformAnimName", "vehicle.baleLoader.animations#rotatePlatform") --FS17 to FS19 |
154 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#rotatePlatformBackAnimName", "vehicle.baleLoader.animations#rotatePlatformBack") --FS17 to FS19 |
155 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.baleLoader#rotatePlatformEmptyAnimName", "vehicle.baleLoader.animations#rotatePlatformEmpty") --FS17 to FS19 |
156 | |
157 | local baseKey = "vehicle.baleLoader" |
158 | |
159 | spec.balesToLoad = {} |
160 | |
161 | spec.balesToMount = {} |
162 | |
163 | spec.isInWorkPosition = false |
164 | spec.grabberIsMoving = false |
165 | spec.synchronizeFillLevel = false |
166 | spec.synchronizeFullFillLevel = true |
167 | |
168 | spec.rotatePlatformDirection = 0 |
169 | spec.frontBalePusherDirection = 0 |
170 | |
171 | spec.emptyState = BaleLoader.EMPTY_NONE |
172 | spec.itemsToSave = {} |
173 | |
174 | spec.texts = {} |
175 | spec.texts.transportPosition = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#transportPosition"), "action_baleloaderTransportPosition") |
176 | spec.texts.operatingPosition = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#operatingPosition"), "action_baleloaderOperatingPosition") |
177 | spec.texts.unload = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#unload"), "action_baleloaderUnload") |
178 | spec.texts.tilting = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#tilting"), "info_baleloaderTiltingTable") |
179 | spec.texts.lowering = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#lowering"), "info_baleloaderLoweringTable") |
180 | spec.texts.lowerPlattform = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#lowerPlattform"), "action_baleloaderLowerPlatform") |
181 | spec.texts.abortUnloading = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#abortUnloading"), "action_baleloaderAbortUnloading") |
182 | spec.texts.unloadHere = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".texts#unloadHere"), "action_baleloaderUnloadHere") |
183 | |
184 | spec.animations = {} |
185 | spec.animations.rotatePlatform = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".animations#rotatePlatform"), "rotatePlatform") |
186 | spec.animations.rotatePlatformBack = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".animations#rotatePlatformBack"), "rotatePlatform") |
187 | spec.animations.rotatePlatformEmpty = Utils.getNoNil(getXMLString(self.xmlFile, baseKey..".animations#rotatePlatformEmpty"), "rotatePlatform") |
188 | spec.animations.grabberDropBaleReverseSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey..".animations#grabberDropBaleReverseSpeed"), 5) |
189 | spec.animations.grabberDropToWork = getXMLString(self.xmlFile, baseKey..".animations#grabberDropToWork") |
190 | |
191 | spec.moveBalePlacesAfterRotatePlatform = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#moveBalePlacesAfterRotatePlatform"), false) |
192 | spec.moveBalePlacesMaxGrabberTime = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey.."#moveBalePlacesMaxGrabberTime"), math.huge) |
193 | spec.alwaysMoveBalePlaces = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#alwaysMoveBalePlaces"), false) |
194 | spec.transportPositionAfterUnloading = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#transportPositionAfterUnloading"), true) |
195 | spec.useBalePlaceAsLoadPosition = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#useBalePlaceAsLoadPosition"), false) |
196 | spec.balePlaceOffset = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey.."#balePlaceOffset"), 0) |
197 | spec.keepBaleRotationDuringLoad = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#keepBaleRotationDuringLoad"), false) |
198 | |
199 | spec.automaticUnloading = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#automaticUnloading"), false) |
200 | spec.resetEmptyRotateAnimation = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey.."#resetEmptyRotateAnimation"), true) |
201 | |
202 | spec.mountDynamic = Utils.getNoNil(getXMLBool(self.xmlFile, baseKey..".dynamicMount#enabled"), false) |
203 | spec.updateBaleJointNodePosition = {} |
204 | spec.dynamicMountMinTransLimits = StringUtil.getVectorNFromString(getXMLString(self.xmlFile, baseKey..".dynamicMount#minTransLimits"), 3) |
205 | spec.dynamicMountMaxTransLimits = StringUtil.getVectorNFromString(getXMLString(self.xmlFile, baseKey..".dynamicMount#maxTransLimits"), 3) |
206 | spec.isBaleWeightDirty = false |
207 | spec.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, baseKey.."#fillUnitIndex"), 1) |
208 | |
209 | spec.baleGrabber = {} |
210 | spec.baleGrabber.grabNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, baseKey..".grabber#grabNode"), self.i3dMappings) |
211 | spec.baleGrabber.pickupRange = Utils.getNoNil(getXMLFloat(self.xmlFile, baseKey..".grabber#pickupRange"), 3.0) |
212 | spec.baleGrabber.balesInTrigger = {} |
213 | spec.baleGrabber.trigger = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, baseKey..".grabber#triggerNode"), self.i3dMappings) |
214 | if spec.baleGrabber.trigger ~= nil then |
215 | addTrigger(spec.baleGrabber.trigger, "baleGrabberTriggerCallback", self) |
216 | else |
217 | g_logManager:xmlError(self.configFileName, "Bale grabber needs a valid trigger!") |
218 | end |
219 | |
220 | spec.startBalePlace = {} |
221 | spec.startBalePlace.bales = {} |
222 | spec.startBalePlace.node = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, baseKey..".balePlaces#startBalePlace"), self.i3dMappings) |
223 | if spec.startBalePlace.node ~= nil then |
224 | spec.startBalePlace.numOfPlaces = getNumOfChildren(spec.startBalePlace.node) |
225 | if spec.startBalePlace.numOfPlaces == 0 then |
226 | spec.startBalePlace.node = nil |
227 | else |
228 | spec.startBalePlace.origRot = {} |
229 | spec.startBalePlace.origTrans = {} |
230 | for i=1, spec.startBalePlace.numOfPlaces do |
231 | local node = getChildAt(spec.startBalePlace.node, i-1) |
232 | spec.startBalePlace.origRot[i] = {getRotation(node)} |
233 | spec.startBalePlace.origTrans[i] = {getTranslation(node)} |
234 | end |
235 | end |
236 | end |
237 | spec.startBalePlace.count = 0 |
238 | |
239 | spec.currentBalePlace = 1 |
240 | spec.balePlaces = {} |
241 | local i = 0 |
242 | while true do |
243 | local key = string.format("%s.balePlaces.balePlace(%d)", baseKey, i) |
244 | if not hasXMLProperty(self.xmlFile, key) then |
245 | break |
246 | end |
247 | local node = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node"), self.i3dMappings) |
248 | local collision = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key.."#collision"), self.i3dMappings) |
249 | if node ~= nil then |
250 | local entry = {} |
251 | entry.node = node |
252 | if collision ~= nil then |
253 | entry.collision = collision |
254 | setIsCompoundChild(entry.collision, false) |
255 | end |
256 | table.insert(spec.balePlaces, entry) |
257 | end |
258 | i = i + 1 |
259 | end |
260 | |
261 | if self.isClient then |
262 | local grabParticleSystem = {} |
263 | local psName = baseKey..".grabber.grabParticleSystem" |
264 | if ParticleUtil.loadParticleSystem(self.xmlFile, grabParticleSystem, psName, self.components, false, nil, self.baseDirectory) then |
265 | spec.grabParticleSystem = grabParticleSystem |
266 | spec.grabParticleSystemDisableTime = 0 |
267 | spec.grabParticleSystemDisableDuration = Utils.getNoNil(getXMLFloat(self.xmlFile, psName.."#disableDuration"), 0.6)*1000 |
268 | end |
269 | |
270 | spec.samples = {} |
271 | spec.samples.grab = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey..".sounds", "grab", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
272 | spec.samples.emptyRotate = g_soundManager:loadSampleFromXML(self.xmlFile, baseKey..".sounds", "emptyRotate", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) |
273 | end |
274 | |
275 | spec.allowedBaleTypes = {} |
276 | i = 0 |
277 | while true do |
278 | local key = string.format("%s.baleTypes.baleType(%d)", baseKey, i) |
279 | if not hasXMLProperty(self.xmlFile, key) then |
280 | break |
281 | end |
282 | local minBaleDiameter = getXMLFloat(self.xmlFile, key.."#minBaleDiameter") |
283 | local maxBaleDiameter = getXMLFloat(self.xmlFile, key.."#maxBaleDiameter") |
284 | local minBaleWidth = getXMLFloat(self.xmlFile, key.."#minBaleWidth") |
285 | local maxBaleWidth = getXMLFloat(self.xmlFile, key.."#maxBaleWidth") |
286 | local minBaleHeight = getXMLFloat(self.xmlFile, key.."#minBaleHeight") |
287 | local maxBaleHeight = getXMLFloat(self.xmlFile, key.."#maxBaleHeight") |
288 | local minBaleLength = getXMLFloat(self.xmlFile, key.."#minBaleLength") |
289 | local maxBaleLength = getXMLFloat(self.xmlFile, key.."#maxBaleLength") |
290 | if minBaleDiameter ~= nil and maxBaleDiameter ~= nil and minBaleWidth ~= nil and maxBaleWidth ~= nil then |
291 | table.insert(spec.allowedBaleTypes, { |
292 | minBaleDiameter = MathUtil.round(minBaleDiameter, 2), |
293 | maxBaleDiameter = MathUtil.round(maxBaleDiameter, 2), |
294 | minBaleWidth = MathUtil.round(minBaleWidth, 2), |
295 | maxBaleWidth = MathUtil.round(maxBaleWidth, 2)}) |
296 | elseif minBaleWidth ~= nil and maxBaleWidth ~= nil and minBaleHeight ~= nil and maxBaleHeight ~= nil and minBaleLength ~= nil and maxBaleLength ~= nil then |
297 | table.insert(spec.allowedBaleTypes, { |
298 | minBaleWidth = MathUtil.round(minBaleWidth, 2), |
299 | maxBaleWidth = MathUtil.round(maxBaleWidth, 2), |
300 | minBaleHeight = MathUtil.round(minBaleHeight, 2), |
301 | maxBaleHeight = MathUtil.round(maxBaleHeight, 2), |
302 | minBaleLength = MathUtil.round(minBaleLength, 2), |
303 | maxBaleLength = MathUtil.round(maxBaleLength, 2) |
304 | }) |
305 | end |
306 | i = i + 1 |
307 | end |
308 | |
309 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, baseKey..".animationNodes", self.components, self, self.i3dMappings) |
310 | spec.showBaleNotSupportedWarning = false |
311 | end |
316 | function BaleLoader:onPostLoad(savegame) |
317 | if savegame ~= nil then |
318 | local spec = self.spec_baleLoader |
319 | |
320 | if Utils.getNoNil(getXMLBool(savegame.xmlFile, savegame.key..".baleLoader#isInWorkPosition"), false) then |
321 | if not spec.isInWorkPosition then |
322 | spec.grabberIsMoving = true |
323 | spec.isInWorkPosition = true |
324 | BaleLoader.moveToWorkPosition(self, true) |
325 | end |
326 | else |
327 | BaleLoader.moveToTransportPosition(self) |
328 | end |
329 | |
330 | spec.currentBalePlace = 1 |
331 | |
332 | spec.startBalePlace.count = 0 |
333 | local numBales = 0 |
334 | if not savegame.resetVehicles then |
335 | local i=0 |
336 | while true do |
337 | local baleKey = savegame.key..string.format(".baleLoader.bale(%d)", i) |
338 | if not hasXMLProperty(savegame.xmlFile, baleKey) then |
339 | break |
340 | end |
341 | local filename = getXMLString(savegame.xmlFile, baleKey.."#filename") |
342 | if filename ~= nil then |
343 | filename = NetworkUtil.convertFromNetworkFilename(filename) |
344 | |
345 | local x,y,z = StringUtil.getVectorFromString(getXMLString(savegame.xmlFile, baleKey.."#position")) |
346 | local xRot,yRot,zRot = StringUtil.getVectorFromString(getXMLString(savegame.xmlFile, baleKey.."#rotation")) |
347 | local fillLevel = getXMLFloat(savegame.xmlFile, baleKey.."#fillLevel") |
348 | local balePlace = getXMLInt(savegame.xmlFile, baleKey.."#balePlace") |
349 | local helper = getXMLInt(savegame.xmlFile, baleKey.."#helper") |
350 | local farmId = getXMLInt(savegame.xmlFile, baleKey.."#farmId") |
351 | 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 |
352 | print("Warning: Corrupt savegame, bale "..filename.." could not be loaded") |
353 | else |
354 | xRot = math.rad(xRot) |
355 | yRot = math.rad(yRot) |
356 | zRot = math.rad(zRot) |
357 | |
358 | local translation |
359 | local rotation |
360 | if balePlace > 0 then |
361 | translation = {x,y,z} |
362 | rotation={xRot, yRot, zRot} |
363 | else |
364 | translation = {0,0,0} |
365 | rotation={0,0,0} |
366 | end |
367 | local parentNode = nil |
368 | local bales = nil |
369 | if balePlace < 1 then |
370 | if spec.startBalePlace.node ~= nil and helper <= spec.startBalePlace.numOfPlaces then |
371 | parentNode = getChildAt(spec.startBalePlace.node, helper-1) |
372 | if spec.startBalePlace.bales == nil then |
373 | spec.startBalePlace.bales = {} |
374 | end |
375 | bales = spec.startBalePlace.bales |
376 | spec.startBalePlace.count = spec.startBalePlace.count+1 |
377 | end |
378 | elseif balePlace <= table.getn(spec.balePlaces) then |
379 | spec.currentBalePlace = math.max(spec.currentBalePlace, balePlace+1) |
380 | parentNode = spec.balePlaces[balePlace].node |
381 | if spec.balePlaces[balePlace].bales == nil then |
382 | spec.balePlaces[balePlace].bales = {} |
383 | end |
384 | bales = spec.balePlaces[balePlace].bales |
385 | end |
386 | if parentNode ~= nil then |
387 | local attributes = {} |
388 | Bale.loadExtraAttributesFromXMLFile(self, attributes, savegame.xmlFile, baleKey, savegame.resetVehicles) |
389 | |
390 | numBales = numBales + 1 |
391 | table.insert(spec.balesToLoad, {parentNode=parentNode, filename=filename, bales=bales, translation=translation, rotation=rotation, fillLevel=fillLevel, farmId=farmId, attributes=attributes}) |
392 | end |
393 | end |
394 | end |
395 | i = i +1 |
396 | end |
397 | end |
398 | |
399 | -- update animations |
400 | BaleLoader.updateBalePlacesAnimations(self) |
401 | for i, place in pairs(spec.balePlaces) do |
402 | if place.collision ~= nil then |
403 | if i <= numBales then |
404 | setIsCompoundChild(place.collision, true) |
405 | else |
406 | setIsCompoundChild(place.collision, false) |
407 | end |
408 | end |
409 | end |
410 | end |
411 | end |
568 | function BaleLoader:onReadStream(streamId, connection) |
569 | local spec = self.spec_baleLoader |
570 | |
571 | spec.isInWorkPosition = streamReadBool(streamId) |
572 | spec.frontBalePusherDirection = streamReadIntN(streamId, 3) |
573 | spec.rotatePlatformDirection = streamReadIntN(streamId, 3) |
574 | |
575 | -- note: we do not sync grabberMoveState, this may lead to visual artifacts for a few seconds at the bigging |
576 | |
577 | if spec.isInWorkPosition then |
578 | BaleLoader.moveToWorkPosition(self) |
579 | end |
580 | |
581 | local emptyState = streamReadUIntN(streamId, 4) |
582 | |
583 | spec.currentBalePlace = streamReadInt8(streamId) |
584 | |
585 | -- read bale at bale grabber |
586 | if streamReadBool(streamId) then |
587 | spec.baleGrabber.currentBale = NetworkUtil.readNodeObjectId(streamId) |
588 | spec.balesToMount[spec.baleGrabber.currentBale] = {serverId=spec.baleGrabber.currentBale, linkNode=spec.baleGrabber.grabNode, trans={0,0,0}, rot={0,0,0} } |
589 | end |
590 | |
591 | -- read bales at start bale places |
592 | spec.startBalePlace.count = streamReadUInt8(streamId) |
593 | for i=1, spec.startBalePlace.count do |
594 | local baleServerId = NetworkUtil.readNodeObjectId(streamId) |
595 | |
596 | local attachNode = getChildAt(spec.startBalePlace.node, i-1) |
597 | spec.balesToMount[baleServerId] = {serverId=baleServerId, linkNode=attachNode, trans={0,0,0}, rot={0,0,0} } |
598 | |
599 | table.insert(spec.startBalePlace.bales, baleServerId) |
600 | end |
601 | |
602 | |
603 | -- read bales at normal bale places |
604 | for i=1, table.getn(spec.balePlaces) do |
605 | local balePlace = spec.balePlaces[i] |
606 | |
607 | local numBales = streamReadUInt8(streamId) |
608 | if numBales > 0 then |
609 | balePlace.bales = {} |
610 | |
611 | for baleI=1, numBales do |
612 | local baleServerId = NetworkUtil.readNodeObjectId(streamId) |
613 | local x = streamReadFloat32(streamId) |
614 | local y = streamReadFloat32(streamId) |
615 | local z = streamReadFloat32(streamId) |
616 | |
617 | table.insert(balePlace.bales, baleServerId) |
618 | |
619 | spec.balesToMount[baleServerId] = {serverId=baleServerId, linkNode=balePlace.node, trans={ x,y,z}, rot={0,0,0} } |
620 | end |
621 | end |
622 | end |
623 | |
624 | -- read num bales on platform |
625 | -- read bales on baleloader |
626 | -- ignore |
627 | |
628 | -- grabberMoveState ? int:nil |
629 | -- isInWorkPosition bool |
630 | -- emptyState ? int:nil |
631 | -- rotatePlatformDirection |
632 | -- frontBalePusherDirection |
633 | -- grabberIsMoving: bool |
634 | |
635 | |
636 | -- update animations |
637 | BaleLoader.updateBalePlacesAnimations(self) |
638 | |
639 | if emptyState >= BaleLoader.EMPTY_TO_WORK then |
640 | self:doStateChange(BaleLoader.CHANGE_EMPTY_START) |
641 | AnimatedVehicle.updateAnimations(self, 99999999) |
642 | if emptyState >= BaleLoader.EMPTY_ROTATE_PLATFORM then |
643 | self:doStateChange(BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM) |
644 | AnimatedVehicle.updateAnimations(self, 99999999) |
645 | if emptyState >= BaleLoader.EMPTY_ROTATE1 then |
646 | self:doStateChange(BaleLoader.CHANGE_EMPTY_ROTATE1) |
647 | AnimatedVehicle.updateAnimations(self, 99999999) |
648 | if emptyState >= BaleLoader.EMPTY_CLOSE_GRIPPERS then |
649 | self:doStateChange(BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS) |
650 | AnimatedVehicle.updateAnimations(self, 99999999) |
651 | if emptyState >= BaleLoader.EMPTY_HIDE_PUSHER1 then |
652 | self:doStateChange(BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1) |
653 | AnimatedVehicle.updateAnimations(self, 99999999) |
654 | if emptyState >= BaleLoader.EMPTY_HIDE_PUSHER2 then |
655 | self:doStateChange(BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2) |
656 | AnimatedVehicle.updateAnimations(self, 99999999) |
657 | if emptyState >= BaleLoader.EMPTY_ROTATE2 then |
658 | self:doStateChange(BaleLoader.CHANGE_EMPTY_ROTATE2) |
659 | AnimatedVehicle.updateAnimations(self, 99999999) |
660 | if emptyState >= BaleLoader.EMPTY_WAIT_TO_DROP then |
661 | self:doStateChange(BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP) |
662 | AnimatedVehicle.updateAnimations(self, 99999999) |
663 | if emptyState == BaleLoader.EMPTY_CANCEL or emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then |
664 | self:doStateChange(BaleLoader.CHANGE_EMPTY_CANCEL) |
665 | AnimatedVehicle.updateAnimations(self, 99999999) |
666 | if emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then |
667 | self:doStateChange(BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO) |
668 | AnimatedVehicle.updateAnimations(self, 99999999) |
669 | end |
670 | elseif emptyState == BaleLoader.EMPTY_WAIT_TO_SINK or emptyState == BaleLoader.EMPTY_SINK then |
671 | self:doStateChange(BaleLoader.CHANGE_DROP_BALES) |
672 | AnimatedVehicle.updateAnimations(self, 99999999) |
673 | |
674 | if emptyState == BaleLoader.EMPTY_SINK then |
675 | self:doStateChange(BaleLoader.CHANGE_SINK) |
676 | AnimatedVehicle.updateAnimations(self, 99999999) |
677 | end |
678 | end |
679 | end |
680 | |
681 | end |
682 | end |
683 | end |
684 | end |
685 | end |
686 | end |
687 | end |
688 | spec.emptyState = emptyState |
689 | end |
780 | function BaleLoader:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
781 | local spec = self.spec_baleLoader |
782 | |
783 | if self.firstTimeRun then |
784 | for k, baleToMount in pairs(spec.balesToMount) do |
785 | local bale = NetworkUtil.getObject(baleToMount.serverId) |
786 | if bale ~= nil then |
787 | local x,y,z = unpack(baleToMount.trans) |
788 | local rx,ry,rz = unpack(baleToMount.rot) |
789 | |
790 | if spec.mountDynamic then |
791 | self:mountDynamicBale(bale, baleToMount.linkNode) |
792 | else |
793 | bale:mount(self, baleToMount.linkNode, x,y,z, rx,ry,rz) |
794 | end |
795 | |
796 | spec.balesToMount[k] = nil |
797 | end |
798 | end |
799 | end |
800 | |
801 | if self.isClient then |
802 | if spec.grabParticleSystem ~= nil then |
803 | if spec.grabParticleSystemDisableTime ~= 0 and spec.grabParticleSystemDisableTime < g_currentMission.time then |
804 | ParticleUtil.setEmittingState(spec.grabParticleSystem, false) |
805 | spec.grabParticleSystemDisableTime = 0 |
806 | end |
807 | end |
808 | end |
809 | |
810 | -- check if grabber is still moving |
811 | if spec.grabberIsMoving then |
812 | if not self:getIsAnimationPlaying("baleGrabberTransportToWork") then |
813 | spec.grabberIsMoving = false |
814 | end |
815 | end |
816 | |
817 | spec.showBaleNotSupportedWarning = false |
818 | if self:getIsBaleGrabbingAllowed() then |
819 | if spec.baleGrabber.grabNode ~= nil and spec.baleGrabber.currentBale == nil then |
820 | -- find nearest bale |
821 | local nearestBale, nearestBaleType = BaleLoader.getBaleInRange(self, spec.baleGrabber.grabNode, spec.baleGrabber.balesInTrigger) |
822 | if nearestBale ~= nil then |
823 | if nearestBaleType == nil then |
824 | spec.showBaleNotSupportedWarning = true |
825 | elseif self.isServer then |
826 | self:pickupBale(nearestBale, nearestBaleType) |
827 | end |
828 | end |
829 | end |
830 | end |
831 | if self.isServer then |
832 | if spec.grabberMoveState ~= nil then |
833 | if spec.grabberMoveState == BaleLoader.GRAB_MOVE_UP then |
834 | if not self:getIsAnimationPlaying("baleGrabberWorkToDrop") then |
835 | --BaleLoader.CHANGE_GRAB_MOVE_UP |
836 | -- switch to grabberMoveState |
837 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_MOVE_UP), true, nil, self) |
838 | end |
839 | elseif spec.grabberMoveState == BaleLoader.GRAB_DROP_BALE then |
840 | if not self:getIsAnimationPlaying(spec.currentBaleGrabberDropBaleAnimName) then |
841 | --BaleLoader.CHANGE_GRAB_DROP_BALE |
842 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_DROP_BALE), true, nil, self) |
843 | end |
844 | elseif spec.grabberMoveState == BaleLoader.GRAB_MOVE_DOWN then |
845 | --BaleLoader.CHANGE_GRAB_MOVE_DOWN |
846 | local name = spec.animations.grabberDropToWork or "baleGrabberWorkToDrop" |
847 | if not self:getIsAnimationPlaying(name) then |
848 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_MOVE_DOWN), true, nil, self) |
849 | self:setAnimationTime(spec.currentBaleGrabberDropBaleAnimName, 0, false) |
850 | self:setAnimationTime("baleGrabberWorkToDrop", 0, false) |
851 | end |
852 | end |
853 | end |
854 | if spec.frontBalePusherDirection ~= 0 then |
855 | if not self:getIsAnimationPlaying("frontBalePusher") then |
856 | --BaleLoader.CHANGE_FRONT_PUSHER |
857 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_FRONT_PUSHER), true, nil, self) |
858 | end |
859 | end |
860 | if spec.rotatePlatformDirection ~= 0 then |
861 | local name = spec.animations.rotatePlatform |
862 | if spec.rotatePlatformDirection < 0 then |
863 | name = spec.animations.rotatePlatformBack |
864 | end |
865 | if not self:getIsAnimationPlaying(name) and not self:getIsAnimationPlaying("moveBalePlacesExtrasOnce") and not spec.moveBalePlacesDelayedMovement then |
866 | --BaleLoader.CHANGE_ROTATE_PLATFORM |
867 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_ROTATE_PLATFORM), true, nil, self) |
868 | end |
869 | end |
870 | |
871 | if spec.emptyState ~= BaleLoader.EMPTY_NONE then |
872 | if spec.emptyState == BaleLoader.EMPTY_TO_WORK then |
873 | if not self:getIsAnimationPlaying("baleGrabberTransportToWork") then |
874 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_ROTATE_PLATFORM), true, nil, self) |
875 | end |
876 | elseif spec.emptyState == BaleLoader.EMPTY_ROTATE_PLATFORM then |
877 | if not self:getIsAnimationPlaying(spec.animations.rotatePlatformEmpty) then |
878 | --BaleLoader.CHANGE_EMPTY_ROTATE1 |
879 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_ROTATE1), true, nil, self) |
880 | end |
881 | elseif spec.emptyState == BaleLoader.EMPTY_ROTATE1 then |
882 | if not self:getIsAnimationPlaying("emptyRotate") and not self:getIsAnimationPlaying("moveBalePlacesToEmpty") then |
883 | --BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS |
884 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_CLOSE_GRIPPERS), true, nil, self) |
885 | end |
886 | elseif spec.emptyState == BaleLoader.EMPTY_CLOSE_GRIPPERS then |
887 | if not self:getIsAnimationPlaying("closeGrippers") then |
888 | --BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1 |
889 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_HIDE_PUSHER1), true, nil, self) |
890 | end |
891 | elseif spec.emptyState == BaleLoader.EMPTY_HIDE_PUSHER1 then |
892 | if not self:getIsAnimationPlaying("emptyHidePusher1") then |
893 | --BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2 |
894 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_HIDE_PUSHER2), true, nil, self) |
895 | end |
896 | elseif spec.emptyState == BaleLoader.EMPTY_HIDE_PUSHER2 then |
897 | if self:getAnimationTime("moveBalePusherToEmpty") < 0.7 or not self:getIsAnimationPlaying("moveBalePusherToEmpty") then |
898 | --BaleLoader.CHANGE_EMPTY_ROTATE2 |
899 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_ROTATE2), true, nil, self) |
900 | end |
901 | elseif spec.emptyState == BaleLoader.EMPTY_ROTATE2 then |
902 | if not self:getIsAnimationPlaying("emptyRotate") then |
903 | --BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP |
904 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_WAIT_TO_DROP), true, nil, self) |
905 | end |
906 | elseif spec.emptyState == BaleLoader.EMPTY_SINK then |
907 | if not self:getIsAnimationPlaying("emptyRotate") and |
908 | not self:getIsAnimationPlaying("moveBalePlacesToEmpty") and |
909 | not self:getIsAnimationPlaying("emptyHidePusher1") and |
910 | not self:getIsAnimationPlaying(spec.animations.rotatePlatformEmpty) |
911 | then |
912 | --BaleLoader.CHANGE_EMPTY_STATE_NIL |
913 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_STATE_NIL), true, nil, self) |
914 | end |
915 | elseif spec.emptyState == BaleLoader.EMPTY_CANCEL then |
916 | if not self:getIsAnimationPlaying("emptyRotate") then |
917 | --BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO |
918 | g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_EMPTY_WAIT_TO_REDO), true, nil, self) |
919 | end |
920 | end |
921 | end |
922 | end |
923 | |
924 | -- re mount bale in grabber, which was unmounted to be saved as normal bale |
925 | if spec.baleGrabber.currentBaleIsUnmounted then |
926 | spec.baleGrabber.currentBaleIsUnmounted = false |
927 | local bale = NetworkUtil.getObject(spec.baleGrabber.currentBale) |
928 | if bale ~= nil then |
929 | if spec.mountDynamic then |
930 | self:mountDynamicBale(bale, spec.baleGrabber.grabNode) |
931 | else |
932 | bale:mount(self, spec.baleGrabber.grabNode, 0,0,0, 0,0,0) |
933 | end |
934 | end |
935 | end |
936 | end |
943 | function BaleLoader:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
944 | local spec = self.spec_baleLoader |
945 | |
946 | if self.isClient then |
947 | local actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA] |
948 | if actionEvent ~= nil then |
949 | local showAction = false |
950 | if spec.emptyState == BaleLoader.EMPTY_NONE then |
951 | if spec.grabberMoveState == nil then |
952 | if spec.isInWorkPosition then |
953 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText(spec.texts.transportPosition, self.customEnvironment)) |
954 | showAction = true |
955 | else |
956 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText(spec.texts.operatingPosition, self.customEnvironment)) |
957 | showAction = true |
958 | end |
959 | end |
960 | end |
961 | |
962 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, showAction) |
963 | end |
964 | |
965 | actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA2] |
966 | if actionEvent ~= nil then |
967 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, spec.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP) |
968 | end |
969 | |
970 | actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA3] |
971 | if actionEvent ~= nil then |
972 | local showAction = false |
973 | |
974 | if spec.emptyState == BaleLoader.EMPTY_NONE then |
975 | if BaleLoader.getAllowsStartUnloading(self) then |
976 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText(spec.texts.unload, self.customEnvironment)) |
977 | showAction = true |
978 | end |
979 | elseif spec.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP then |
980 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText(spec.texts.unloadHere, self.customEnvironment)) |
981 | showAction = true |
982 | elseif spec.emptyState == BaleLoader.EMPTY_WAIT_TO_SINK then |
983 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText(spec.texts.lowerPlattform, self.customEnvironment)) |
984 | showAction = true |
985 | elseif spec.emptyState == BaleLoader.EMPTY_WAIT_TO_REDO then |
986 | g_inputBinding:setActionEventText(actionEvent.actionEventId, g_i18n:getText(spec.texts.unload, self.customEnvironment)) |
987 | showAction = true |
988 | end |
989 | |
990 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, showAction) |
991 | end |
992 | end |
993 | |
994 | if self.isServer then |
995 | if spec.automaticUnloading then |
996 | if spec.emptyState == BaleLoader.EMPTY_WAIT_TO_DROP then |
997 | self:doStateChange(BaleLoader.CHANGE_BUTTON_EMPTY) |
998 | end |
999 | |
1000 | if spec.emptyState == BaleLoader.EMPTY_WAIT_TO_SINK then |
1001 | self:doStateChange(BaleLoader.CHANGE_SINK) |
1002 | end |
1003 | end |
1004 | |
1005 | if spec.mountDynamic then |
1006 | local jointNodePositionChanged = false |
1007 | -- move bale smoothly to the joint position |
1008 | for i, jointNode in ipairs(spec.updateBaleJointNodePosition) do |
1009 | local x, y, z = getTranslation(jointNode.node) |
1010 | |
1011 | if jointNode.quaternion == nil then |
1012 | local qx, qy, qz, qw = getQuaternion(jointNode.node) |
1013 | jointNode.quaternion = {qx, qy, qz, qw} |
1014 | end |
1015 | |
1016 | jointNode.time = jointNode.time + dt |
1017 | if jointNode.time < 1000 then |
1018 | local qx, qy, qz, qw = 0, 0, 0, 1 |
1019 | if math.abs(jointNode.quaternion[2]) > 0.5 then |
1020 | qx, qy, qz, qw = MathUtil.slerpQuaternionShortestPath(jointNode.quaternion[1], jointNode.quaternion[2], jointNode.quaternion[3], jointNode.quaternion[4], 0, 1, 0, 0, jointNode.time/1000) |
1021 | elseif math.abs(jointNode.quaternion[2]) < 0.5 then |
1022 | qx, qy, qz, qw = MathUtil.slerpQuaternionShortestPath(jointNode.quaternion[1], jointNode.quaternion[2], jointNode.quaternion[3], jointNode.quaternion[4], 0, 0, 0, 1, jointNode.time/1000) |
1023 | end |
1024 | setQuaternion(jointNode.node, qx, qy, qz, qw) |
1025 | jointNodePositionChanged = true |
1026 | end |
1027 | |
1028 | if math.abs(x)+math.abs(y)+math.abs(z) > 0.001 then |
1029 | local move = 0.0001*dt |
1030 | |
1031 | local function moveValue(old, move) |
1032 | local limit = MathUtil.sign(old) > 0 and math.max or math.min |
1033 | return limit(old-MathUtil.sign(old)*move, 0) |
1034 | end |
1035 | |
1036 | setTranslation(jointNode.node, moveValue(x, move), moveValue(y, move), moveValue(z, move)) |
1037 | |
1038 | jointNodePositionChanged = true |
1039 | elseif jointNode.time > 1000 then |
1040 | table.remove(spec.updateBaleJointNodePosition, i) |
1041 | end |
1042 | end |
1043 | |
1044 | -- update dynamic bale joints as soon one of the available animations is playing |
1045 | local anyAnimationPlaying = false |
1046 | for name,_ in pairs(self.spec_animatedVehicle.animations) do |
1047 | if self:getIsAnimationPlaying(name) then |
1048 | anyAnimationPlaying = true |
1049 | end |
1050 | end |
1051 | |
1052 | if anyAnimationPlaying or jointNodePositionChanged or spec.isBaleWeightDirty then |
1053 | for _, balePlace in pairs(spec.balePlaces) do |
1054 | if balePlace.bales ~= nil then |
1055 | for _, baleServerId in pairs(balePlace.bales) do |
1056 | local bale = NetworkUtil.getObject(baleServerId) |
1057 | if bale ~= nil then |
1058 | if bale.dynamicMountJointIndex ~= nil then |
1059 | setJointFrame(bale.dynamicMountJointIndex, 0, bale.dynamicMountJointNode) |
1060 | end |
1061 | |
1062 | if bale.backupMass == nil then |
1063 | local mass = getMass(bale.nodeId) |
1064 | if mass ~= 1 then |
1065 | bale.backupMass = mass |
1066 | setMass(bale.nodeId, 0.1) |
1067 | spec.isBaleWeightDirty = false |
1068 | end |
1069 | end |
1070 | end |
1071 | end |
1072 | end |
1073 | end |
1074 | for _, baleServerId in ipairs(spec.startBalePlace.bales) do |
1075 | local bale = NetworkUtil.getObject(baleServerId) |
1076 | if bale ~= nil then |
1077 | if bale.dynamicMountJointIndex ~= nil then |
1078 | setJointFrame(bale.dynamicMountJointIndex, 0, bale.dynamicMountJointNode) |
1079 | end |
1080 | |
1081 | if bale.backupMass == nil then |
1082 | local mass = getMass(bale.nodeId) |
1083 | if mass ~= 1 then |
1084 | bale.backupMass = mass |
1085 | setMass(bale.nodeId, 0.1) |
1086 | spec.isBaleWeightDirty = false |
1087 | end |
1088 | end |
1089 | end |
1090 | end |
1091 | end |
1092 | end |
1093 | end |
1094 | |
1095 | if spec.moveBalePlacesDelayedMovement then |
1096 | if self:getAnimationTime("baleGrabberWorkToDrop") < spec.moveBalePlacesMaxGrabberTime then |
1097 | spec.rotatePlatformDirection = -1 |
1098 | self:playAnimation(spec.animations.rotatePlatformBack, -1, nil, true) |
1099 | |
1100 | if spec.moveBalePlacesAfterRotatePlatform then |
1101 | -- currentBalePlace+1 needs to be at the first position |
1102 | if spec.currentBalePlace <= table.getn(spec.balePlaces) or spec.alwaysMoveBalePlaces then |
1103 | self:playAnimation("moveBalePlaces", 1, (spec.currentBalePlace-1)/table.getn(spec.balePlaces), true) |
1104 | self:setAnimationStopTime("moveBalePlaces", (spec.currentBalePlace)/table.getn(spec.balePlaces)) |
1105 | self:playAnimation("moveBalePlacesExtrasOnce", 1, nil, true) |
1106 | end |
1107 | end |
1108 | |
1109 | spec.moveBalePlacesDelayedMovement = nil |
1110 | end |
1111 | end |
1112 | end |