diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index 8123a2f0b..d52aeef1d 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -1235,6 +1235,11 @@ void ClientConnection::handleTileUpdate(shared_ptr packet) PIXBeginNamedEvent(0,"Setting data\n"); bool tileWasSet = dimensionLevel->doSetTileAndData(packet->x, packet->y, packet->z, packet->block, packet->data); + if (tileWasSet && packet->block == 0 && minecraft->levelRenderer && minecraft->levelRenderer->destroyedTileManager) + { + minecraft->levelRenderer->destroyedTileManager->RemoveTileAt(dimensionLevel, packet->x, packet->y, packet->z); + } + PIXEndNamedEvent(); // 4J - remove any tite entities in this region which are associated with a tile that is now no longer a tile entity. Without doing this we end up with stray diff --git a/Minecraft.Client/LevelRenderer.cpp b/Minecraft.Client/LevelRenderer.cpp index 222a5c189..a88b9341b 100644 --- a/Minecraft.Client/LevelRenderer.cpp +++ b/Minecraft.Client/LevelRenderer.cpp @@ -3584,6 +3584,31 @@ void LevelRenderer::DestroyedTileManager::destroyingTileAt( Level *level, int x, LeaveCriticalSection(&m_csDestroyedTiles); } +void LevelRenderer::DestroyedTileManager::RemoveTileAt(const Level *level, int x, int y, int z) +{ + EnterCriticalSection(&m_csDestroyedTiles); + + // Remove ALL entries matching this position + for (auto it = m_destroyedTiles.begin(); it != m_destroyedTiles.end();) + { + const auto &tile = *it; + + if (tile->level == level && + tile->x == x && + tile->y == y && + tile->z == z) + { + it = m_destroyedTiles.erase(it); + } + else + { + ++it; + } + } + + LeaveCriticalSection(&m_csDestroyedTiles); +} + // For chunk rebuilding to inform the manager that a chunk (a 16x16x16 tile render chunk) has been updated void LevelRenderer::DestroyedTileManager::updatedChunkAt(Level *level, int x, int y, int z, int veryNearCount) { diff --git a/Minecraft.Client/LevelRenderer.h b/Minecraft.Client/LevelRenderer.h index bb2c0d13c..ab9520a86 100644 --- a/Minecraft.Client/LevelRenderer.h +++ b/Minecraft.Client/LevelRenderer.h @@ -205,6 +205,7 @@ public: void destroyingTileAt( Level *level, int x, int y, int z ); // For game to let this manager know that a tile is about to be destroyed (must be called before it actually is) void updatedChunkAt( Level * level, int x, int y, int z, int veryNearCount ); // For chunk rebuilding to inform the manager that a chunk (a 16x16x16 tile render chunk) has been updated void addAABBs( Level *level, AABB *box, AABBList *boxes ); // For game to get any AABBs that the user should be colliding with as render data has not yet been updated + void RemoveTileAt(const Level* level, int x, int y, int z); void tick(); DestroyedTileManager(); ~DestroyedTileManager(); diff --git a/Minecraft.Client/MultiPlayerGameMode.cpp b/Minecraft.Client/MultiPlayerGameMode.cpp index 844eb0e59..215a83b28 100644 --- a/Minecraft.Client/MultiPlayerGameMode.cpp +++ b/Minecraft.Client/MultiPlayerGameMode.cpp @@ -99,6 +99,11 @@ bool MultiPlayerGameMode::destroyBlock(int x, int y, int z, int face) } #endif + if (minecraft->levelRenderer && minecraft->levelRenderer->destroyedTileManager) + { + minecraft->levelRenderer->destroyedTileManager->RemoveTileAt(level, x, y, z); + } + if (minecraft->levelRenderer && minecraft->levelRenderer->destroyedTileManager) { minecraft->levelRenderer->destroyedTileManager->destroyingTileAt(level, x, y, z); @@ -114,6 +119,11 @@ bool MultiPlayerGameMode::destroyBlock(int x, int y, int z, int face) } yDestroyBlock = -1; + if (minecraft->levelRenderer && minecraft->levelRenderer->destroyedTileManager) + { + minecraft->levelRenderer->destroyedTileManager->RemoveTileAt(level, x, y, z); + } + if (!localPlayerMode->isCreative()) { const shared_ptr item = minecraft->player->getSelectedItem();