| 785 | |
| 786 | |
| 787 | void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta) |
| 788 | { |
| 789 | if ( |
| 790 | m_HasStartedDigging && |
| 791 | (a_BlockX == m_LastDigBlockX) && |
| 792 | (a_BlockY == m_LastDigBlockY) && |
| 793 | (a_BlockZ == m_LastDigBlockZ) |
| 794 | ) |
| 795 | { |
| 796 | // It is a duplicate packet, drop it right away |
| 797 | return; |
| 798 | } |
| 799 | |
| 800 | if ( |
| 801 | m_Player->IsGameModeCreative() && |
| 802 | ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType) |
| 803 | ) |
| 804 | { |
| 805 | // Players can't destroy blocks with a Sword in the hand. |
| 806 | return; |
| 807 | } |
| 808 | |
| 809 | if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta)) |
| 810 | { |
| 811 | // A plugin doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows: |
| 812 | m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); |
| 813 | return; |
| 814 | } |
| 815 | |
| 816 | // Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig/aim bug in the client: |
| 817 | m_HasStartedDigging = true; |
| 818 | m_LastDigBlockX = a_BlockX; |
| 819 | m_LastDigBlockY = a_BlockY; |
| 820 | m_LastDigBlockZ = a_BlockZ; |
| 821 | |
| 822 | if ( |
| 823 | (m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately |
| 824 | cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too |
| 825 | ) |
| 826 | { |
| 827 | HandleBlockDigFinished(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta); |
| 828 | return; |
| 829 | } |
| 830 | |
| 831 | // Start dig animation |
| 832 | // TODO: calculate real animation speed |
| 833 | // TODO: Send animation packets even without receiving any other packets |
| 834 | m_BlockDigAnimSpeed = 10; |
| 835 | m_BlockDigAnimX = a_BlockX; |
| 836 | m_BlockDigAnimY = a_BlockY; |
| 837 | m_BlockDigAnimZ = a_BlockZ; |
| 838 | m_BlockDigAnimStage = 0; |
| 839 | m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, 0, this); |
| 840 | |
| 841 | cWorld * World = m_Player->GetWorld(); |
| 842 | cChunkInterface ChunkInterface(World->GetChunkMap()); |
| 843 | cBlockHandler * Handler = cBlockInfo::GetHandler(a_OldBlock); |
| 844 | Handler->OnDigging(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ); |
nothing calls this directly
no test coverage detected