Properly fixed piston non-animation

Fixes #57
master
Tiger Wang 2013-08-18 14:52:38 +01:00
parent 9e0b8b5bee
commit 8a3174164b
7 changed files with 128 additions and 16 deletions

View File

@ -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) 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. // The coords must be valid, because the upper level already does chunk lookup. No need to check them again.

View File

@ -148,6 +148,8 @@ public:
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); 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 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. /** 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. Will return self if appropriate. Returns NULL if not reachable through neighbors.
*/ */

View File

@ -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) 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; int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;

View File

@ -135,6 +135,7 @@ public:
NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ); 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 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 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 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); bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);

View File

@ -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 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->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 oldx = pistx; //Shift the selectors down a block and repeat
oldy = pisty; oldy = pisty;
oldz = pistz; oldz = pistz;
@ -126,10 +126,19 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz )
int extz = pistz; int extz = pistz;
AddDir(pistx, pisty, pistz, pistonMeta & 7, -1) //Move back one block to the piston base 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->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->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); //Set the base
m_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky + pistonMeta); //Set the arm 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 // Already retracted, bail out
return; return;
} }
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->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->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 AddDir(pistx, pisty, pistz, pistonMeta & 7, 1) //Move forwards to the extension coord
if (m_World->GetBlock(pistx, pisty, pistz) != E_BLOCK_PISTON_EXTENSION) 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 // 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; return;
} }
m_World->SetBlock(pistx, pisty, pistz, tempblock, tempmeta); m_World->SetServerBlock(pistx, pisty, pistz, tempblock, tempmeta);
m_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0); m_World->SetServerBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0);
} }
else else
{ {
m_World->SetServerBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0);
m_World->SetBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0);
} }
} }

View File

@ -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) BLOCKTYPE cWorld::GetBlock(int a_X, int a_Y, int a_Z)
{ {
// First check if it isn't queued in the m_FastSetBlockQueue: // 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); cCSLock Lock(m_CSPlayers);
for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr) for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr)
{ {
unsigned LastSpace = a_Text.find_last_of(" "); 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());
std::string LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); //Find the last word
std::string PlayerName ((*itr)->GetName()); 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) if (Found!=0)
{ {
continue; continue; //No match
} }
a_Results.push_back((*itr)->GetName());
a_Results.push_back((*itr)->GetName()); //Match!
} }
} }

View File

@ -313,6 +313,7 @@ public:
// tolua_begin // tolua_begin
void SetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); 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 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); BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ);
NIBBLETYPE GetBlockMeta (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); void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData);