From 8a3174164b0ee3e902031d631c690ed555b74f05 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 18 Aug 2013 14:52:38 +0100 Subject: Properly fixed piston non-animation Fixes #57 --- source/Chunk.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ source/Chunk.h | 2 ++ source/ChunkMap.cpp | 18 ++++++++++++++++++ source/ChunkMap.h | 1 + source/Piston.cpp | 39 ++++++++++++++++++++++++++----------- source/World.cpp | 28 ++++++++++++++++++++++----- source/World.h | 1 + 7 files changed, 128 insertions(+), 16 deletions(-) diff --git a/source/Chunk.cpp b/source/Chunk.cpp index 62d411b0c..7bff3fdc9 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -1607,6 +1607,61 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT +void cChunk::SetServerBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +{ + ASSERT(!((a_RelX < 0) || (a_RelX >= Width) || (a_RelY < 0) || (a_RelY >= Height) || (a_RelZ < 0) || (a_RelZ >= Width))); + + ASSERT(IsValid()); + + const int index = MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + const BLOCKTYPE OldBlockType = cChunkDef::GetBlock(m_BlockTypes, index); + const BLOCKTYPE OldBlockMeta = GetNibble(m_BlockMeta, index); + if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta)) + { + return; + } + + MarkDirty(); + + m_BlockTypes[index] = a_BlockType; + + SetNibble(m_BlockMeta, index, a_BlockMeta); + + // ONLY recalculate lighting if it's necessary! + if( + (g_BlockLightValue[OldBlockType ] != g_BlockLightValue[a_BlockType]) || + (g_BlockSpreadLightFalloff[OldBlockType] != g_BlockSpreadLightFalloff[a_BlockType]) || + (g_BlockTransparent[OldBlockType] != g_BlockTransparent[a_BlockType]) + ) + { + m_IsLightValid = false; + } + + // Update heightmap, if needed: + if (a_RelY >= m_HeightMap[a_RelX + a_RelZ * Width]) + { + if (a_BlockType != E_BLOCK_AIR) + { + m_HeightMap[a_RelX + a_RelZ * Width] = (unsigned char)a_RelY; + } + else + { + for (int y = a_RelY - 1; y > 0; --y) + { + if (m_BlockTypes[MakeIndexNoCheck(a_RelX, y, a_RelZ)] != E_BLOCK_AIR) + { + m_HeightMap[a_RelX + a_RelZ * Width] = (unsigned char)y; + break; + } + } // for y - column in m_BlockData + } + } +} + + + + + void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_Client) { // The coords must be valid, because the upper level already does chunk lookup. No need to check them again. diff --git a/source/Chunk.h b/source/Chunk.h index c4eeab6ae..61f11d6d5 100644 --- a/source/Chunk.h +++ b/source/Chunk.h @@ -148,6 +148,8 @@ public: void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); + void SetServerBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ); + /** Returns the chunk into which the specified block belongs, by walking the neighbors. Will return self if appropriate. Returns NULL if not reachable through neighbors. */ diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 5a16495e6..4180ae327 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -1171,6 +1171,24 @@ void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_B +void cChunkMap::SetServerBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + Chunk->SetServerBlock(X, Y, Z, a_BlockType, a_BlockMeta ); + m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); + } +} + + + + + bool cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; diff --git a/source/ChunkMap.h b/source/ChunkMap.h index 208d2824e..07ad4feaa 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -135,6 +135,7 @@ public: NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ); void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockMeta); void SetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta); + void SetServerBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta); bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); diff --git a/source/Piston.cpp b/source/Piston.cpp index 058f92a0e..4c8d56261 100644 --- a/source/Piston.cpp +++ b/source/Piston.cpp @@ -114,7 +114,7 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) { AddDir(pistx, pisty, pistz, pistonMeta & 7, -1) //Move one set of coords one back from breakable dropped block m_World->GetBlockTypeMeta(pistx, pisty, pistz, currBlock, currBlockMeta); //Get the block - m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta); //Set the block at the location of the original coords + m_World->SetServerBlock( oldx, oldy, oldz, currBlock, currBlockMeta); //Set the block at the location of the original coords oldx = pistx; //Shift the selectors down a block and repeat oldy = pisty; oldz = pistz; @@ -126,10 +126,19 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) int extz = pistz; AddDir(pistx, pisty, pistz, pistonMeta & 7, -1) //Move back one block to the piston base - m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta, E_BLOCK_PISTON); //Set the base + + if (pistonBlock == E_BLOCK_STICKY_PISTON) + { + m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta, E_BLOCK_STICKY_PISTON); + } + else + { + m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta, E_BLOCK_PISTON); + } + m_World->BroadcastSoundEffect("tile.piston.out", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f); - m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); - m_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky + pistonMeta); //Set the arm + m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); //Set the base + m_World->SetServerBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky + pistonMeta); //Set the arm } @@ -146,9 +155,18 @@ void cPiston::RetractPiston( int pistx, int pisty, int pistz ) // Already retracted, bail out return; } - m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), E_BLOCK_PISTON); + + if (pistonBlock == E_BLOCK_STICKY_PISTON) + { + m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), E_BLOCK_STICKY_PISTON); + } + else + { + m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), E_BLOCK_PISTON); + } + m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f); - m_World->FastSetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8)); //Set the base + m_World->SetServerBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8)); //Set the base AddDir(pistx, pisty, pistz, pistonMeta & 7, 1) //Move forwards to the extension coord if (m_World->GetBlock(pistx, pisty, pistz) != E_BLOCK_PISTON_EXTENSION) @@ -173,17 +191,16 @@ void cPiston::RetractPiston( int pistx, int pisty, int pistz ) ) { // These cannot be moved by the sticky piston, bail out - m_World->SetBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0); + m_World->SetServerBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0); return; } - m_World->SetBlock(pistx, pisty, pistz, tempblock, tempmeta); - m_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0); + m_World->SetServerBlock(pistx, pisty, pistz, tempblock, tempmeta); + m_World->SetServerBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0); } else { - - m_World->SetBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0); + m_World->SetServerBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0); } } diff --git a/source/World.cpp b/source/World.cpp index 6b82dce0f..97186fa24 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -1385,6 +1385,21 @@ void cWorld::FastSetBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBB +void cWorld::SetServerBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + if (a_BlockType == E_BLOCK_AIR) + { + BlockHandler(GetBlock(a_X, a_Y, a_Z))->OnDestroyed(this, a_X, a_Y, a_Z); + } + m_ChunkMap->SetServerBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta); + + BlockHandler(a_BlockType)->OnPlaced(this, a_X, a_Y, a_Z, a_BlockType, a_BlockMeta); +} + + + + + BLOCKTYPE cWorld::GetBlock(int a_X, int a_Y, int a_Z) { // First check if it isn't queued in the m_FastSetBlockQueue: @@ -2635,15 +2650,18 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr) { - unsigned LastSpace = a_Text.find_last_of(" "); - std::string LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); + size_t LastSpace = a_Text.find_last_of(" "); //Find the position of the last space + + std::string LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); //Find the last word std::string PlayerName ((*itr)->GetName()); - std::size_t Found = PlayerName.find(LastWord); + std::size_t Found = PlayerName.find(LastWord); //Try to find last word in playername + if (Found!=0) { - continue; + continue; //No match } - a_Results.push_back((*itr)->GetName()); + + a_Results.push_back((*itr)->GetName()); //Match! } } diff --git a/source/World.h b/source/World.h index 5d3de06d0..34e350a04 100644 --- a/source/World.h +++ b/source/World.h @@ -313,6 +313,7 @@ public: // tolua_begin void SetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void FastSetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + void SetServerBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ); void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData); -- cgit v1.2.3