LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

BaleLoader

Description
Specialization for automatic bale loaders
Functions

actionEventAbortEmpty

Description
Definition
actionEventAbortEmpty()
Code
1805function BaleLoader.actionEventAbortEmpty(self, actionName, inputValue, callbackState, isAnalog)
1806 g_client:getServerConnection():sendEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_BUTTON_EMPTY_ABORT))
1807end

actionEventEmpty

Description
Definition
actionEventEmpty()
Code
1799function BaleLoader.actionEventEmpty(self, actionName, inputValue, callbackState, isAnalog)
1800 g_client:getServerConnection():sendEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_BUTTON_EMPTY))
1801end

actionEventWorkTransport

Description
Definition
actionEventWorkTransport()
Code
1811function BaleLoader.actionEventWorkTransport(self, actionName, inputValue, callbackState, isAnalog)
1812 g_client:getServerConnection():sendEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_BUTTON_WORK_TRANSPORT))
1813end

addNodeObjectMapping

Description
Definition
addNodeObjectMapping()
Code
1758function BaleLoader:addNodeObjectMapping(superFunc, list)
1759 superFunc(self, list)
1760
1761 local spec = self.spec_baleLoader
1762 if spec.baleGrabber.trigger ~= nil then
1763 list[spec.baleGrabber.trigger] = self
1764 end
1765end

baleGrabberTriggerCallback

Description
Definition
baleGrabberTriggerCallback()
Code
1669function BaleLoader:baleGrabberTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
1670 if otherId ~= 0 then
1671 local object = g_currentMission:getNodeObject(otherId)
1672 if object ~= nil then
1673 if object:isa(Bale) then
1674 local spec = self.spec_baleLoader
1675 if onEnter then
1676 spec.baleGrabber.balesInTrigger[object] = Utils.getNoNil(spec.baleGrabber.balesInTrigger[object], 0) + 1
1677 elseif onLeave then
1678 if spec.baleGrabber.balesInTrigger[object] ~= nil then
1679 spec.baleGrabber.balesInTrigger[object] = math.max(0, spec.baleGrabber.balesInTrigger[object] - 1)
1680 if spec.baleGrabber.balesInTrigger[object] == 0 then
1681 spec.baleGrabber.balesInTrigger[object] = nil
1682 end
1683 end
1684 end
1685 end
1686 end
1687 end
1688end

doStateChange

Description
Change bale loader state
Definition
doStateChange(integer id, integer nearestBaleServerId)
Arguments
integeridid of new state
integernearestBaleServerIdserver id of nearest bale
Code
1222function 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
1536end

getAllowDynamicMountFillLevelInfo

Description
Definition
getAllowDynamicMountFillLevelInfo()
Code
1746function BaleLoader:getAllowDynamicMountFillLevelInfo(superFunc)
1747 local spec = self.spec_baleLoader
1748 if spec.mountDynamic then
1749 return false
1750 end
1751
1752 return superFunc(self)
1753end

getAllowsStartUnloading

Description
Returns if allows to start unloading bales
Definition
getAllowsStartUnloading()
Return Values
booleanallowsUnloadingallows unloading
Code
1541function BaleLoader.getAllowsStartUnloading(self)
1542 local spec = self.spec_baleLoader
1543
1544 if self:getFillUnitFillLevel(spec.fillUnitIndex) == 0 then
1545 return false
1546 end
1547
1548 if spec.rotatePlatformDirection ~= 0 then
1549 return false
1550 end
1551
1552 if spec.frontBalePusherDirection ~= 0 then
1553 return false
1554 end
1555
1556 if spec.grabberIsMoving or spec.grabberMoveState ~= nil then
1557 return false
1558 end
1559
1560 if spec.emptyState ~= BaleLoader.EMPTY_NONE then
1561 return false
1562 end
1563
1564 return true
1565end

getBaleGrabberDropBaleAnimName

Description
Returns bale grabber drop bale animation name
Definition
getBaleGrabberDropBaleAnimName()
Return Values
stringnamename of bale grabber drop bale animation name
Code
1610function BaleLoader:getBaleGrabberDropBaleAnimName()
1611 local spec = self.spec_baleLoader
1612 local name = string.format("baleGrabberDropBale%d", spec.startBalePlace.count)
1613 if self:getAnimationExists(name) then
1614 return name
1615 end
1616 return "baleGrabberDropBale"
1617end

getBaleInRange

Description
Returns if nearest bale in range
Definition
getBaleInRange(integer refNode)
Arguments
integerrefNodeid of reference node
Return Values
tablebalebale
integernearestBaleTypeid of bale type
Code
1130function BaleLoader.getBaleInRange(self, refNode, balesInTrigger)
1131 local spec = self.spec_baleLoader
1132
1133 local nearestDistance = spec.baleGrabber.pickupRange
1134 local nearestBale = nil
1135 local nearestBaleType = nil
1136
1137 for bale, state in pairs(balesInTrigger) do
1138 if state ~= nil and state > 0 then
1139
1140 local isValidBale = true
1141 for _, balePlace in pairs(spec.balePlaces) do
1142 if balePlace.bales ~= nil then
1143 for _, baleServerId in pairs(balePlace.bales) do
1144 local baleInPlace = NetworkUtil.getObject(baleServerId)
1145 if baleInPlace ~= nil and baleInPlace == bale then
1146 isValidBale = false
1147 end
1148 end
1149 end
1150 end
1151 for _, baleServerId in ipairs(spec.startBalePlace.bales) do
1152 local baleInPlace = NetworkUtil.getObject(baleServerId)
1153 if baleInPlace ~= nil and baleInPlace == bale then
1154 isValidBale = false
1155 end
1156 end
1157
1158 if bale == nil or not entityExists(bale.nodeId) then
1159 isValidBale = false
1160 end
1161
1162 if bale.dynamicMountJointIndex ~= nil then
1163 isValidBale = false
1164 end
1165
1166 if not bale:getBaleSupportsBaleLoader() then
1167 isValidBale = false
1168 end
1169
1170 if isValidBale then
1171 local distance = calcDistanceFrom(refNode, bale.nodeId)
1172 if distance < nearestDistance then
1173 local foundBaleType
1174 for _, baleType in pairs(spec.allowedBaleTypes) do
1175 if baleType.minBaleDiameter ~= nil then
1176 if bale.baleDiameter ~= nil and bale.baleWidth ~= nil and
1177 bale.baleDiameter >= baleType.minBaleDiameter and bale.baleDiameter <= baleType.maxBaleDiameter and
1178 bale.baleWidth >= baleType.minBaleWidth and bale.baleWidth <= baleType.maxBaleWidth
1179 then
1180 foundBaleType = baleType
1181 break
1182 end
1183 else
1184 if bale.baleWidth ~= nil and bale.baleHeight ~= nil and bale.baleLength ~= nil and
1185 bale.baleWidth >= baleType.minBaleWidth and bale.baleWidth <= baleType.maxBaleWidth and
1186 bale.baleHeight >= baleType.minBaleHeight and bale.baleHeight <= baleType.maxBaleHeight and
1187 bale.baleLength >= baleType.minBaleLength and bale.baleLength <= baleType.maxBaleLength
1188 then
1189 foundBaleType = baleType
1190 break
1191 end
1192 end
1193 end
1194 if foundBaleType ~= nil or nearestBaleType == nil then
1195 if foundBaleType ~= nil then
1196 nearestDistance = distance
1197 end
1198 nearestBale = bale
1199 nearestBaleType = foundBaleType
1200 end
1201 end
1202
1203 end
1204 end
1205 end
1206 return nearestBale, nearestBaleType
1207end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
1740function BaleLoader:getCanBeSelected(superFunc)
1741 return true
1742end

getIsBaleGrabbingAllowed

Description
Returns if bale grabbing is allowed
Definition
getIsBaleGrabbingAllowed()
Return Values
stringnamename of bale grabber drop bale animation name
Code
1622function BaleLoader:getIsBaleGrabbingAllowed()
1623 local spec = self.spec_baleLoader
1624
1625 if not spec.isInWorkPosition then
1626 return false
1627 end
1628
1629 if spec.grabberIsMoving or spec.grabberMoveState ~= nil then
1630 return false
1631 end
1632
1633 if spec.startBalePlace.count >= spec.startBalePlace.numOfPlaces then
1634 return false
1635 end
1636
1637 if spec.frontBalePusherDirection ~= 0 then
1638 return false
1639 end
1640
1641 if spec.rotatePlatformDirection ~= 0 then
1642 return false
1643 end
1644
1645 if spec.alwaysMoveBalePlaces and self:getIsAnimationPlaying("moveBalePlaces") then
1646 return false
1647 end
1648
1649 if spec.emptyState ~= BaleLoader.EMPTY_NONE then
1650 return false
1651 end
1652
1653 if self:getFillUnitFreeCapacity(spec.fillUnitIndex) == 0 then
1654 return false
1655 end
1656
1657 return true
1658end

mountDynamicBale

Description
Definition
mountDynamicBale()
Code
1692function BaleLoader:mountDynamicBale(bale, node)
1693 if self.isServer then
1694 local spec = self.spec_baleLoader
1695 if bale.dynamicMountJointIndex ~= nil then
1696 link(node, bale.dynamicMountJointNode)
1697 setWorldTranslation(bale.dynamicMountJointNode, getWorldTranslation(bale.nodeId))
1698 setWorldRotation(bale.dynamicMountJointNode, getWorldRotation(bale.nodeId))
1699 setJointFrame(bale.dynamicMountJointIndex, 0, bale.dynamicMountJointNode)
1700
1701 table.insert(spec.updateBaleJointNodePosition, {node=bale.dynamicMountJointNode, time=0})
1702 else
1703 local jointNode = createTransformGroup("baleJoint")
1704 link(node, jointNode)
1705 setWorldTranslation(jointNode, getWorldTranslation(bale.nodeId))
1706 setWorldRotation(jointNode, getWorldRotation(bale.nodeId))
1707 bale:mountDynamic(self, self:getParentComponent(node), jointNode, DynamicMountUtil.TYPE_FIX_ATTACH, 0, false)
1708 if spec.dynamicMountMinTransLimits ~= nil and spec.dynamicMountMaxTransLimits ~= nil then
1709 for i=1, 3 do
1710 local active = spec.dynamicMountMinTransLimits[i] ~= 0 or spec.dynamicMountMaxTransLimits[i] ~= 0
1711 if active then
1712 setJointTranslationLimit(bale.dynamicMountJointIndex, i-1, active, spec.dynamicMountMinTransLimits[i], spec.dynamicMountMaxTransLimits[i])
1713 end
1714 end
1715 end
1716 table.insert(spec.updateBaleJointNodePosition, {node=jointNode, time=0})
1717
1718 spec.isBaleWeightDirty = true
1719 g_currentMission:removeItemToSave(bale)
1720 end
1721 end
1722end

moveToTransportPosition

Description
Move to transport position
Definition
moveToTransportPosition()
Code
1602function BaleLoader.moveToTransportPosition(self)
1603 self:playAnimation("baleGrabberTransportToWork", -1, MathUtil.clamp(self:getAnimationTime("baleGrabberTransportToWork"), 0, 1), true)
1604 self:playAnimation("closeGrippers", 1, MathUtil.clamp(self:getAnimationTime("closeGrippers"), 0, 1), true)
1605end

moveToWorkPosition

Description
Move bale Loader to work position
Definition
moveToWorkPosition(boolean onLoad)
Arguments
booleanonLoadcalled on load
Code
1586function BaleLoader.moveToWorkPosition(self, onLoad)
1587 local speed = 1
1588 if onLoad then
1589 speed = 9999
1590 end
1591
1592 self:playAnimation("baleGrabberTransportToWork", speed, MathUtil.clamp(self:getAnimationTime("baleGrabberTransportToWork"), 0, 1), true)
1593 local animTime = nil
1594 if self:getAnimationTime("closeGrippers") ~= 0 then
1595 animTime = self:getAnimationTime("closeGrippers")
1596 end
1597 self:playAnimation("closeGrippers", -1, animTime, true)
1598end

onDeactivate

Description
Called on deactivate
Definition
onDeactivate()
Code
1211function BaleLoader:onDeactivate()
1212 local spec = self.spec_baleLoader
1213 if spec.grabParticleSystem ~= nil then
1214 ParticleUtil.setEmittingState(spec.grabParticleSystem, false)
1215 end
1216end

onDelete

Description
Called on deleting
Definition
onDelete()
Code
442function BaleLoader:onDelete()
443 local spec = self.spec_baleLoader
444
445 -- avoid the bale nodes to be deleted twice (because they are linked the vehicle and because the Bale object is deleted)
446 for _, balePlace in pairs(spec.balePlaces) do
447 if balePlace.bales ~= nil then
448 for _, baleServerId in pairs(balePlace.bales) do
449 local bale = NetworkUtil.getObject(baleServerId)
450 if bale ~= nil then
451 if spec.mountDynamic then
452 self:unmountDynamicBale(bale)
453 else
454 bale:unmount()
455 end
456
457 -- if the vehicle is reloaded we remove the bale since it will be regenerated on load
458 if self.isReconfigurating ~= nil and self.isReconfigurating then
459 bale:delete()
460 end
461 end
462 end
463 end
464 end
465 for _, baleServerId in ipairs(spec.startBalePlace.bales) do
466 local bale = NetworkUtil.getObject(baleServerId)
467 if bale ~= nil then
468 if spec.mountDynamic then
469 self:unmountDynamicBale(bale)
470 else
471 bale:unmount()
472 end
473
474 -- if the vehicle is reloaded we remove the bale since it will be regenerated on load
475 if self.isReconfigurating ~= nil and self.isReconfigurating then
476 bale:delete()
477 end
478 end
479 end
480
481 if spec.baleGrabber.currentBale ~= nil then
482 local bale = NetworkUtil.getObject(spec.baleGrabber.currentBale)
483 if bale ~= nil then
484 if spec.mountDynamic then
485 self:unmountDynamicBale(bale)
486 else
487 bale:unmount()
488 end
489 end
490 end
491
492 if self.isClient then
493 if spec.grabParticleSystem ~= nil then
494 ParticleUtil.deleteParticleSystem(spec.grabParticleSystem)
495 end
496
497 for i,sample in pairs(spec.samples) do
498 g_soundManager:deleteSample(sample)
499 end
500 end
501
502 if spec.baleGrabber.trigger ~= nil then
503 removeTrigger(spec.baleGrabber.trigger)
504 end
505
506 g_animationManager:deleteAnimations(spec.animationNodes)
507end

onDraw

Description
Called on draw
Definition
onDraw(boolean isActiveForInput, boolean isSelected)
Arguments
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
1118function BaleLoader:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
1119 local spec = self.spec_baleLoader
1120 if spec.showBaleNotSupportedWarning then
1121 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_baleNotSupported", self.customEnvironment), 2000)
1122 end
1123end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
134function 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
311end

onLoadFinished

Description
Called after vehicle was added to phyiscs
Definition
onLoadFinished(table savegame)
Arguments
tablesavegamesavegame
Code
416function BaleLoader:onLoadFinished(savegame)
417 local spec = self.spec_baleLoader
418
419 for k,v in pairs(spec.balesToLoad) do
420 local baleObject = Bale:new(self.isServer, self.isClient)
421 local x,y,z = unpack(v.translation)
422 local rx,ry,rz = unpack(v.rotation)
423 baleObject:load(v.filename, x,y,z,rx,ry,rz, v.fillLevel)
424 baleObject.ownerFarmId = Utils.getNoNil(v.farmId, AccessHandler.EVERYONE)
425
426 if spec.mountDynamic then
427 self:mountDynamicBale(baleObject, v.parentNode)
428 else
429 baleObject:mount(self, v.parentNode, x,y,z, rx,ry,rz)
430 end
431
432 baleObject:applyExtraAttributes(v.attributes)
433 baleObject:register()
434
435 table.insert(v.bales, NetworkUtil.getObjectId(baleObject))
436 spec.balesToLoad[k] = nil
437 end
438end

onPostLoad

Description
Called after loading
Definition
onPostLoad(table savegame)
Arguments
tablesavegamesavegame
Code
316function 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
411end

onReadStream

Description
Called on client side on join
Definition
onReadStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
568function 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
689end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
1780function BaleLoader:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
1781 if self.isClient then
1782 local spec = self.spec_baleLoader
1783 self:clearActionEventsTable(spec.actionEvents)
1784
1785 if isActiveForInputIgnoreSelection then
1786 local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA3, self, BaleLoader.actionEventEmpty, false, true, false, true, nil)
1787 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
1788 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA, self, BaleLoader.actionEventWorkTransport, false, true, false, true, nil)
1789 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
1790 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA2, self, BaleLoader.actionEventAbortEmpty, false, true, false, true, nil)
1791 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
1792 g_inputBinding:setActionEventText(actionEventId, g_i18n:getText(spec.texts.abortUnloading, self.customEnvironment))
1793 end
1794 end
1795end

onUpdate

Description
Called on update
Definition
onUpdate(float dt, boolean isActiveForInput, boolean isSelected)
Arguments
floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
780function 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
936end

onUpdateTick

Description
Called on update tick
Definition
onUpdateTick(float dt, boolean isActiveForInput, boolean isSelected)
Arguments
floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
943function 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
1112end

onWriteStream

Description
Called on server side on join
Definition
onWriteStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
695function BaleLoader:onWriteStream(streamId, connection)
696 local spec = self.spec_baleLoader
697
698 streamWriteBool(streamId, spec.isInWorkPosition)
699 streamWriteIntN(streamId, spec.frontBalePusherDirection, 3)
700 streamWriteIntN(streamId, spec.rotatePlatformDirection, 3)
701
702 streamWriteUIntN(streamId, spec.emptyState, 4)
703
704 streamWriteInt8(streamId, spec.currentBalePlace)
705
706 -- write bale at bale grabber
707 if streamWriteBool(streamId, spec.baleGrabber.currentBale ~= nil) then
708 NetworkUtil.writeNodeObjectId(streamId, spec.baleGrabber.currentBale)
709 end
710
711 -- write bales at start bale places
712 streamWriteUInt8(streamId, spec.startBalePlace.count)
713 for i=1, spec.startBalePlace.count do
714 local baleServerId = spec.startBalePlace.bales[i]
715 NetworkUtil.writeNodeObjectId(streamId, baleServerId)
716 end
717
718 -- write bales at normal bale places
719 for i=1, table.getn(spec.balePlaces) do
720 local balePlace = spec.balePlaces[i]
721
722 local numBales = 0
723 if balePlace.bales ~= nil then
724 numBales = table.getn(balePlace.bales)
725 end
726 streamWriteUInt8(streamId, numBales)
727 if balePlace.bales ~= nil then
728 for baleI=1, numBales do
729 local baleServerId = balePlace.bales[baleI]
730 local bale = NetworkUtil.getObject(baleServerId)
731 local nodeId = bale.nodeId
732 local x,y,z = getTranslation(nodeId)
733 NetworkUtil.writeNodeObjectId(streamId, baleServerId)
734 streamWriteFloat32(streamId, x)
735 streamWriteFloat32(streamId, y)
736 streamWriteFloat32(streamId, z)
737 end
738 end
739 end
740end

pickupBale

Description
Pickup bale
Definition
pickupBale(table nearestBale, integer nearestBaleType)
Arguments
tablenearestBalenearest bale
integernearestBaleTypenearest bale type
Code
1663function BaleLoader:pickupBale(nearestBale, nearestBaleType)
1664 g_server:broadcastEvent(BaleLoaderStateEvent:new(self, BaleLoader.CHANGE_GRAB_BALE, NetworkUtil.getObjectId(nearestBale)), true, nil, self)
1665end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
19function BaleLoader.prerequisitesPresent(specializations)
20 return SpecializationUtil.hasSpecialization(FillUnit, specializations)
21end

registerEventListeners

Description
Definition
registerEventListeners()
Code
117function BaleLoader.registerEventListeners(vehicleType)
118 SpecializationUtil.registerEventListener(vehicleType, "onLoad", BaleLoader)
119 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", BaleLoader)
120 SpecializationUtil.registerEventListener(vehicleType, "onLoadFinished", BaleLoader)
121 SpecializationUtil.registerEventListener(vehicleType, "onDelete", BaleLoader)
122 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", BaleLoader)
123 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", BaleLoader)
124 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", BaleLoader)
125 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", BaleLoader)
126 SpecializationUtil.registerEventListener(vehicleType, "onDraw", BaleLoader)
127 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", BaleLoader)
128 SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", BaleLoader)
129end

registerFunctions

Description
Definition
registerFunctions()
Code
96function BaleLoader.registerFunctions(vehicleType)
97 SpecializationUtil.registerFunction(vehicleType, "doStateChange", BaleLoader.doStateChange)
98 SpecializationUtil.registerFunction(vehicleType, "getBaleGrabberDropBaleAnimName", BaleLoader.getBaleGrabberDropBaleAnimName)
99 SpecializationUtil.registerFunction(vehicleType, "getIsBaleGrabbingAllowed", BaleLoader.getIsBaleGrabbingAllowed)
100 SpecializationUtil.registerFunction(vehicleType, "pickupBale", BaleLoader.pickupBale)
101 SpecializationUtil.registerFunction(vehicleType, "baleGrabberTriggerCallback", BaleLoader.baleGrabberTriggerCallback)
102 SpecializationUtil.registerFunction(vehicleType, "mountDynamicBale", BaleLoader.mountDynamicBale)
103 SpecializationUtil.registerFunction(vehicleType, "unmountDynamicBale", BaleLoader.unmountDynamicBale)
104end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
108function BaleLoader.registerOverwrittenFunctions(vehicleType)
109 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", BaleLoader.getCanBeSelected)
110 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowDynamicMountFillLevelInfo", BaleLoader.getAllowDynamicMountFillLevelInfo)
111 SpecializationUtil.registerOverwrittenFunction(vehicleType, "addNodeObjectMapping", BaleLoader.addNodeObjectMapping)
112 SpecializationUtil.registerOverwrittenFunction(vehicleType, "removeNodeObjectMapping", BaleLoader.removeNodeObjectMapping)
113end

removeNodeObjectMapping

Description
Definition
removeNodeObjectMapping()
Code
1769function BaleLoader:removeNodeObjectMapping(superFunc, list)
1770 superFunc(self, list)
1771
1772 local spec = self.spec_baleLoader
1773 if spec.baleGrabber.trigger ~= nil then
1774 list[spec.baleGrabber.trigger] = nil
1775 end
1776end

rotatePlatform

Description
Rotate bale loader platform
Definition
rotatePlatform()
Code
1569function BaleLoader.rotatePlatform(self)
1570 local spec = self.spec_baleLoader
1571
1572 spec.rotatePlatformDirection = 1
1573 self:playAnimation(spec.animations.rotatePlatform, 1, nil, true)
1574
1575 if (spec.currentBalePlace > 1 and not spec.moveBalePlacesAfterRotatePlatform) or spec.alwaysMoveBalePlaces then
1576 -- currentBalePlace needs to be at the first position
1577 self:playAnimation("moveBalePlaces", 1, (spec.currentBalePlace-1)/table.getn(spec.balePlaces), true)
1578 self:setAnimationStopTime("moveBalePlaces", (spec.currentBalePlace)/table.getn(spec.balePlaces))
1579 self:playAnimation("moveBalePlacesExtrasOnce", 1, nil, true)
1580 end
1581end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
511function BaleLoader:saveToXMLFile(xmlFile, key, usedModNames)
512 local spec = self.spec_baleLoader
513
514 setXMLBool(xmlFile, key.."#isInWorkPosition", spec.isInWorkPosition)
515
516 local baleIndex = 0
517 for i, balePlace in pairs(spec.balePlaces) do
518 if balePlace.bales ~= nil then
519 for _, baleServerId in pairs(balePlace.bales) do
520 local bale = NetworkUtil.getObject(baleServerId)
521 if bale ~= nil then
522 local baleKey = string.format("%s.bale(%d)", key, baleIndex)
523 bale:saveToXMLFile(xmlFile, baleKey)
524
525 local startBaleEmpty = table.getn(spec.startBalePlace.bales) == 0
526 local loadPlaceEmpty = self:getFillUnitFillLevel(spec.fillUnitIndex) % spec.startBalePlace.numOfPlaces ~= 0
527 local lastItem = (math.floor(self:getFillUnitFillLevel(spec.fillUnitIndex) / spec.startBalePlace.numOfPlaces) + 1) == i
528 local evenCapacity = self:getFillUnitCapacity(spec.fillUnitIndex) % 2 == 0
529 if startBaleEmpty and loadPlaceEmpty and lastItem and evenCapacity then
530 setXMLInt(xmlFile, baleKey.."#balePlace", 0)
531 setXMLInt(xmlFile, baleKey.."#helper", 1)
532 else
533 setXMLInt(xmlFile, baleKey.."#balePlace", i)
534 end
535
536 baleIndex = baleIndex + 1
537 end
538 end
539 end
540 end
541
542 for i, baleServerId in ipairs(spec.startBalePlace.bales) do
543 local bale = NetworkUtil.getObject(baleServerId)
544 if bale ~= nil then
545 local baleKey = string.format("%s.bale(%d)", key, baleIndex)
546 bale:saveToXMLFile(xmlFile, baleKey)
547 setXMLInt(xmlFile, baleKey.."#balePlace", 0)
548 setXMLInt(xmlFile, baleKey.."#helper", i)
549
550 baleIndex = baleIndex + 1
551 end
552 end
553
554 -- unmount bale in grabber so it can be saved as a normal bale
555 if spec.baleGrabber.currentBale ~= nil then
556 local bale = NetworkUtil.getObject(spec.baleGrabber.currentBale)
557 if bale ~= nil then
558 bale:unmount()
559 spec.baleGrabber.currentBaleIsUnmounted = true
560 end
561 end
562end

unmountDynamicBale

Description
Definition
unmountDynamicBale()
Code
1726function BaleLoader:unmountDynamicBale(bale)
1727 if self.isServer then
1728 bale:unmountDynamic()
1729 delete(bale.dynamicMountJointNode)
1730 if bale.backupMass ~= nil then
1731 setMass(bale.nodeId, bale.backupMass)
1732 bale.backupMass = nil
1733 end
1734 g_currentMission:addItemToSave(bale)
1735 end
1736end

updateBalePlacesAnimations

Description
Update bale place animations
Definition
updateBalePlacesAnimations()
Code
744function BaleLoader.updateBalePlacesAnimations(self)
745 local spec = self.spec_baleLoader
746
747 if spec.currentBalePlace > spec.startBalePlace.numOfPlaces or (spec.moveBalePlacesAfterRotatePlatform and spec.currentBalePlace > 1) then
748 local delta = 1
749 local numBalePlaces = table.getn(spec.balePlaces)
750 if spec.moveBalePlacesAfterRotatePlatform and not spec.alwaysMoveBalePlaces and not spec.useBalePlaceAsLoadPosition then
751 delta = 0
752 end
753
754 if spec.useBalePlaceAsLoadPosition then
755 numBalePlaces = numBalePlaces - 1
756 delta = delta + spec.balePlaceOffset
757 end
758
759 -- currentBalePlace-1 or -0 needs to be at the first position
760 self:playAnimation("moveBalePlaces", 1, 0, true)
761 self:setAnimationStopTime("moveBalePlaces", (spec.currentBalePlace-delta)/numBalePlaces)
762
763 AnimatedVehicle.updateAnimations(self, 99999999)
764 end
765
766 if spec.startBalePlace.count >= 1 then
767 self:playAnimation("balesToOtherRow", 20, nil, true)
768 AnimatedVehicle.updateAnimations(self, 99999999)
769 if spec.startBalePlace.count >= spec.startBalePlace.numOfPlaces then
770 BaleLoader.rotatePlatform(self)
771 end
772 end
773end