summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/Chunk.cpp16
-rw-r--r--source/Chunk.h1
-rw-r--r--source/ChunkMap.cpp19
-rw-r--r--source/ChunkMap.h2
-rw-r--r--source/ClientHandle.cpp47
-rw-r--r--source/ClientHandle.h8
-rw-r--r--source/Protocol/Protocol.h1
-rw-r--r--source/Protocol/Protocol125.cpp12
-rw-r--r--source/Protocol/Protocol125.h1
-rw-r--r--source/Protocol/Protocol132.cpp19
-rw-r--r--source/Protocol/Protocol132.h1
-rw-r--r--source/Protocol/ProtocolRecognizer.cpp10
-rw-r--r--source/Protocol/ProtocolRecognizer.h1
-rw-r--r--source/World.cpp9
-rw-r--r--source/World.h3
15 files changed, 144 insertions, 6 deletions
diff --git a/source/Chunk.cpp b/source/Chunk.cpp
index 7cd3b961f..cb4e5511f 100644
--- a/source/Chunk.cpp
+++ b/source/Chunk.cpp
@@ -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 )
diff --git a/source/Chunk.h b/source/Chunk.h
index c9d1e0899..ac34640f8 100644
--- a/source/Chunk.h
+++ b/source/Chunk.h
@@ -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);
diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp
index 508d5ae11..ee69e6cc0 100644
--- a/source/ChunkMap.cpp
+++ b/source/ChunkMap.cpp
@@ -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);
diff --git a/source/ChunkMap.h b/source/ChunkMap.h
index 4165be089..8ddd9d6c7 100644
--- a/source/ChunkMap.h
+++ b/source/ChunkMap.h
@@ -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);
diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp
index 2296ae23e..e32e03f16 100644
--- a/source/ClientHandle.cpp
+++ b/source/ClientHandle.cpp
@@ -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:
diff --git a/source/ClientHandle.h b/source/ClientHandle.h
index 8beecd7e4..1e627a017 100644
--- a/source/ClientHandle.h
+++ b/source/ClientHandle.h
@@ -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
{
diff --git a/source/Protocol/Protocol.h b/source/Protocol/Protocol.h
index e871e958a..ada63af6b 100644
--- a/source/Protocol/Protocol.h
+++ b/source/Protocol/Protocol.h
@@ -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;
diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp
index 2ae82fb43..1f2edad63 100644
--- a/source/Protocol/Protocol125.cpp
+++ b/source/Protocol/Protocol125.cpp
@@ -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
}
diff --git a/source/Protocol/Protocol125.h b/source/Protocol/Protocol125.h
index 62c91c2e1..19a080506 100644
--- a/source/Protocol/Protocol125.h
+++ b/source/Protocol/Protocol125.h
@@ -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;
diff --git a/source/Protocol/Protocol132.cpp b/source/Protocol/Protocol132.cpp
index a39697526..d8c9f1f27 100644
--- a/source/Protocol/Protocol132.cpp
+++ b/source/Protocol/Protocol132.cpp
@@ -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);
diff --git a/source/Protocol/Protocol132.h b/source/Protocol/Protocol132.h
index 5fb82148d..977ddca92 100644
--- a/source/Protocol/Protocol132.h
+++ b/source/Protocol/Protocol132.h
@@ -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;
diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp
index 96a831063..aadd20de0 100644
--- a/source/Protocol/ProtocolRecognizer.cpp
+++ b/source/Protocol/ProtocolRecognizer.cpp
@@ -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);
diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h
index 0a42c279f..e870eca29 100644
--- a/source/Protocol/ProtocolRecognizer.h
+++ b/source/Protocol/ProtocolRecognizer.h
@@ -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;
diff --git a/source/World.cpp b/source/World.cpp
index 9b241c8ee..184cff869 100644
--- a/source/World.cpp
+++ b/source/World.cpp
@@ -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);
diff --git a/source/World.h b/source/World.h
index 1cbd6a2fb..f688efebf 100644
--- a/source/World.h
+++ b/source/World.h
@@ -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);