Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2020
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.54 KB | None | 0 0
  1. void Game::playerMoveItem(Player* player, const Position& fromPos,
  2. uint16_t spriteId, uint8_t fromStackPos, const Position& toPos, uint8_t count, Item* item, Cylinder* toCylinder)
  3. {
  4. if (!player->canDoAction()) {
  5. uint32_t delay = player->getNextActionTime();
  6. SchedulerTask* task = createSchedulerTask(delay, std::bind(&Game::playerMoveItemByPlayerID, this,
  7. player->getID(), fromPos, spriteId, fromStackPos, toPos, count));
  8. player->setNextActionTask(task);
  9. return;
  10. }
  11.  
  12. player->setNextActionTask(nullptr);
  13.  
  14. if (item == nullptr) {
  15. uint8_t fromIndex = 0;
  16. if (fromPos.x == 0xFFFF) {
  17. if (fromPos.y & 0x40) {
  18. fromIndex = fromPos.z;
  19. } else {
  20. fromIndex = static_cast<uint8_t>(fromPos.y);
  21. }
  22. } else {
  23. fromIndex = fromStackPos;
  24. }
  25.  
  26. Thing* thing = internalGetThing(player, fromPos, fromIndex, 0, STACKPOS_MOVE);
  27. if (!thing || !thing->getItem()) {
  28. player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
  29. return;
  30. }
  31.  
  32. item = thing->getItem();
  33. }
  34.  
  35. if (item->getClientID() != spriteId) {
  36. player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
  37. return;
  38. }
  39.  
  40. Cylinder* fromCylinder = internalGetCylinder(player, fromPos);
  41. if (fromCylinder == nullptr) {
  42. player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
  43. return;
  44. }
  45.  
  46. if (toCylinder == nullptr) {
  47. toCylinder = internalGetCylinder(player, toPos);
  48. if (toCylinder == nullptr) {
  49. player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
  50. return;
  51. }
  52. }
  53.  
  54. if (!item->isPushable() || item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) {
  55. player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE);
  56. return;
  57. }
  58.  
  59. const Position& playerPos = player->getPosition();
  60. const Position& mapFromPos = fromCylinder->getTile()->getPosition();
  61. if (playerPos.z != mapFromPos.z) {
  62. player->sendCancelMessage(playerPos.z > mapFromPos.z ? RETURNVALUE_FIRSTGOUPSTAIRS : RETURNVALUE_FIRSTGODOWNSTAIRS);
  63. return;
  64. }
  65.  
  66. if (!Position::areInRange<1, 1>(playerPos, mapFromPos)) {
  67. //need to walk to the item first before using it
  68. std::forward_list<Direction> listDir;
  69. if (player->getPathTo(item->getPosition(), listDir, 0, 1, true, true)) {
  70. g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk,
  71. this, player->getID(), listDir)));
  72.  
  73. SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerMoveItemByPlayerID, this,
  74. player->getID(), fromPos, spriteId, fromStackPos, toPos, count));
  75. player->setNextWalkActionTask(task);
  76. } else {
  77. player->sendCancelMessage(RETURNVALUE_THEREISNOWAY);
  78. }
  79. return;
  80. }
  81.  
  82. const Tile* toCylinderTile = toCylinder->getTile();
  83. const Position& mapToPos = toCylinderTile->getPosition();
  84.  
  85. //hangable item specific code
  86. if (item->isHangable() && toCylinderTile->hasFlag(TILESTATE_SUPPORTS_HANGABLE)) {
  87. //destination supports hangable objects so need to move there first
  88. bool vertical = toCylinderTile->hasProperty(CONST_PROP_ISVERTICAL);
  89. if (vertical) {
  90. if (playerPos.x + 1 == mapToPos.x) {
  91. player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
  92. return;
  93. }
  94. } else { // horizontal
  95. if (playerPos.y + 1 == mapToPos.y) {
  96. player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
  97. return;
  98. }
  99. }
  100.  
  101. if (!Position::areInRange<1, 1, 0>(playerPos, mapToPos)) {
  102. Position walkPos = mapToPos;
  103. if (vertical) {
  104. walkPos.x++;
  105. } else {
  106. walkPos.y++;
  107. }
  108.  
  109. Position itemPos = fromPos;
  110. uint8_t itemStackPos = fromStackPos;
  111.  
  112. if (fromPos.x != 0xFFFF && Position::areInRange<1, 1>(mapFromPos, playerPos)
  113. && !Position::areInRange<1, 1, 0>(mapFromPos, walkPos)) {
  114. //need to pickup the item first
  115. Item* moveItem = nullptr;
  116.  
  117. ReturnValue ret = internalMoveItem(fromCylinder, player, INDEX_WHEREEVER, item, count, &moveItem);
  118. if (ret != RETURNVALUE_NOERROR) {
  119. player->sendCancelMessage(ret);
  120. return;
  121. }
  122.  
  123. //changing the position since its now in the inventory of the player
  124. internalGetPosition(moveItem, itemPos, itemStackPos);
  125. }
  126.  
  127. std::forward_list<Direction> listDir;
  128. if (player->getPathTo(walkPos, listDir, 0, 0, true, true)) {
  129. g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk,
  130. this, player->getID(), listDir)));
  131.  
  132. SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerMoveItemByPlayerID, this,
  133. player->getID(), itemPos, spriteId, itemStackPos, toPos, count));
  134. player->setNextWalkActionTask(task);
  135. } else {
  136. player->sendCancelMessage(RETURNVALUE_THEREISNOWAY);
  137. }
  138. return;
  139. }
  140. }
  141.  
  142. if ((Position::getDistanceX(playerPos, mapToPos) > item->getThrowRange()) ||
  143. (Position::getDistanceY(playerPos, mapToPos) > item->getThrowRange()) ||
  144. (Position::getDistanceZ(mapFromPos, mapToPos) * 4 > item->getThrowRange())) {
  145. player->sendCancelMessage(RETURNVALUE_DESTINATIONOUTOFREACH);
  146. return;
  147. }
  148.  
  149. if (!canThrowObjectTo(mapFromPos, mapToPos)) {
  150. player->sendCancelMessage(RETURNVALUE_CANNOTTHROW);
  151. return;
  152. }
  153.  
  154. if (!g_events->eventPlayerOnMoveItem(player, item, count, fromPos, toPos)) {
  155. return;
  156. }
  157.  
  158. uint8_t toIndex = 0;
  159. if (toPos.x == 0xFFFF) {
  160. if (toPos.y & 0x40) {
  161. toIndex = toPos.z;
  162. } else {
  163. toIndex = static_cast<uint8_t>(toPos.y);
  164. }
  165. }
  166.  
  167. ReturnValue ret = internalMoveItem(fromCylinder, toCylinder, toIndex, item, item->isRune() ? item->getItemCount() : count, nullptr, 0, player);
  168. if (ret != RETURNVALUE_NOERROR) {
  169. player->sendCancelMessage(ret);
  170. }
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement