1
0

Added the block dig animation packet (patch contributed by l0udPL)

git-svn-id: http://mc-server.googlecode.com/svn/trunk@892 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-09-25 09:54:36 +00:00
parent 7a43f6be09
commit fb9a00a64e
15 changed files with 144 additions and 6 deletions

View File

@ -1771,6 +1771,22 @@ void cChunk::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a
void cChunk::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude)
{
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
{
if (*itr == a_Exclude)
{
continue;
}
(*itr)->SendBlockBreakAnim(a_entityID, a_blockX, a_blockY, a_blockZ, a_stage);
} // for itr - LoadedByClient[]
}
void cChunk::BroadcastChunkData(cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
{
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )

View File

@ -188,6 +188,7 @@ public:
void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // a_Src coords are Block * 8
void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL);
void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
void SendBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);

View File

@ -465,6 +465,25 @@ void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, in
void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
cChunkDef::BlockToChunk(a_blockX, a_blockY, a_blockZ, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ);
if (Chunk == NULL)
{
return;
}
// It's perfectly legal to broadcast packets even to invalid chunks!
Chunk->BroadcastBlockBreakAnimation(a_entityID, a_blockX, a_blockY, a_blockZ, a_stage, a_Exclude);
}
void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);

View File

@ -76,6 +76,8 @@ public:
void BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // a_Src coords are Block * 8
void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL);
void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);

View File

@ -91,6 +91,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance)
, m_LastStreamedChunkZ(0x7fffffff)
, m_ShouldCheckDownloaded(false)
, m_UniqueID(0)
, m_BlockDigAnim(-1)
{
m_Protocol = new cProtocolRecognizer(this);
@ -534,9 +535,28 @@ void cClientHandle::HandleBlockDig(int a_BlockX, int a_BlockY, int a_BlockZ, cha
((a_Status == DIG_STATUS_STARTED) && (m_Player->GetGameMode() == 1))
);
if ((a_Status == DIG_STATUS_STARTED) && (m_Player->GetGameMode() != eGameMode_Creative))
{
// Start dig animation
// TODO: calculate real animation speed
m_BlockDigAnimSpeed = 10;
m_BlockDigX = a_BlockX;
m_BlockDigY = a_BlockY;
m_BlockDigZ = a_BlockZ;
m_BlockDigAnim = 0;
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigX, m_BlockDigY, m_BlockDigZ, 0, this);
}
else if (m_BlockDigAnim != -1)
{
// End dig animation
m_BlockDigAnim = -1;
// It seems that 10 ends block animation
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigX, m_BlockDigY, m_BlockDigZ, 10, this);
}
cItem & Equipped = m_Player->GetInventory().GetEquippedItem();
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID);
if (bBroken)
{
ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ);
@ -550,7 +570,6 @@ void cClientHandle::HandleBlockDig(int a_BlockX, int a_BlockY, int a_BlockZ, cha
Handler->OnDigging(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
ItemHandler->OnDiggingBlock(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for clickthrough-blocks:
int pX = a_BlockX;
@ -1049,6 +1068,21 @@ void cClientHandle::Tick(float a_Dt)
m_Protocol->SendKeepAlive(m_PingID);
m_LastPingTime = m_PingStartTime;
}
// Handle block break animation:
if ((m_Player != NULL) && (m_BlockDigAnim > -1))
{
int lastAnimVal = m_BlockDigAnim;
m_BlockDigAnim += (int)(m_BlockDigAnimSpeed * a_Dt);
if (m_BlockDigAnim > 9000)
{
m_BlockDigAnim = 9000;
}
if (m_BlockDigAnim / 1000 != lastAnimVal / 1000)
{
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigX, m_BlockDigY, m_BlockDigZ, (char)(m_BlockDigAnim / 1000), this);
}
}
}
@ -1418,6 +1452,15 @@ void cClientHandle::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int
void cClientHandle::SendBlockBreakAnim(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage)
{
m_Protocol->SendBlockBreakAnim(a_entityID, a_blockX, a_blockY, a_blockZ, a_stage);
}
void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
{
// Check chunks being sent, erase them from m_ChunksToSend:

View File

@ -101,6 +101,7 @@ public:
void SendPlayerSpawn (const cPlayer & a_Player);
void SendRespawn (void);
void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch); // a_Src coords are Block * 8
void SendBlockBreakAnim (int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage);
void SendSpawnMob (const cMonster & a_Mob);
void SendTeleportEntity (const cEntity & a_Entity);
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ);
@ -204,6 +205,13 @@ private:
long long m_PingStartTime;
long long m_LastPingTime;
static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms)
// Values required for block dig animation
int m_BlockDigAnim; // Current stage of the animation; -1 if not digging
int m_BlockDigAnimSpeed; // Current speed of the animation (units ???)
int m_BlockDigX;
int m_BlockDigY;
int m_BlockDigZ;
enum eState
{

View File

@ -72,6 +72,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
virtual void SendRespawn (void) = 0;
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) = 0; // a_Src coords are Block * 8
virtual void SendBlockBreakAnim (int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage) = 0;
virtual void SendSpawnMob (const cMonster & a_Mob) = 0;
virtual void SendTeleportEntity (const cEntity & a_Entity) = 0;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0;

View File

@ -585,8 +585,16 @@ void cProtocol125::SendRespawn(void)
void cProtocol125::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch)
{
cCSLock Lock(m_CSPacket);
//TODO: Not needed in this protocol?
// Not needed in this protocol version
}
void cProtocol125::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage)
{
// Not supported in this protocol version
}

View File

@ -56,6 +56,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendRespawn (void) override;
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
virtual void SendBlockBreakAnim (int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;

View File

@ -61,7 +61,8 @@ enum
PACKET_CHUNK_DATA = 0x33,
PACKET_BLOCK_CHANGE = 0x35,
PACKET_BLOCK_ACTION = 0x36,
PACKET_SOUND_EFFECT = 0x3e
PACKET_BLOCK_BREAK_ANIM = 0x37,
PACKET_SOUND_EFFECT = 0x3e
} ;
@ -349,6 +350,22 @@ void cProtocol132::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int
void cProtocol132::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage)
{
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_BLOCK_BREAK_ANIM);
WriteInt (a_entityID);
WriteInt (a_BlockX);
WriteInt (a_BlockY);
WriteInt (a_BlockZ);
WriteByte (stage);
Flush();
}
void cProtocol132::SendSpawnMob(const cMonster & a_Mob)
{
cCSLock Lock(m_CSPacket);

View File

@ -38,6 +38,7 @@ public:
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
virtual void SendBlockBreakAnim (int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendWholeInventory (const cWindow & a_Window) override;

View File

@ -364,6 +364,16 @@ void cProtocolRecognizer::SendSoundEffect(const AString & a_SoundName, int a_Src
void cProtocolRecognizer::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage)
{
ASSERT(m_Protocol != NULL);
m_Protocol->SendBlockBreakAnim(a_entityID, a_BlockX, a_BlockY, a_BlockZ, stage);
}
void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob)
{
ASSERT(m_Protocol != NULL);

View File

@ -67,6 +67,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendRespawn (void) override;
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override;
virtual void SendBlockBreakAnim (int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;

View File

@ -1431,6 +1431,15 @@ void cWorld::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a
void cWorld::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude )
{
m_ChunkMap->BroadcastBlockBreakAnimation(a_entityID, a_blockX, a_blockY, a_blockZ, a_stage, a_Exclude);
}
void cWorld::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Exclude);

View File

@ -93,7 +93,8 @@ public:
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // a_Src coords are Block * 8
void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL);
/// If there is a block entity at the specified coods, sends it to all clients except a_Exclude
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);