summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--VC2008/MCServer.vcproj4
-rw-r--r--source/Blocks/BlockBed.h68
-rw-r--r--source/Chunk.cpp12
-rw-r--r--source/Chunk.h1
-rw-r--r--source/ChunkMap.cpp19
-rw-r--r--source/ChunkMap.h2
-rw-r--r--source/ClientHandle.cpp27
-rw-r--r--source/ClientHandle.h2
-rw-r--r--source/Protocol/Protocol.h1
-rw-r--r--source/Protocol/Protocol125.cpp20
-rw-r--r--source/Protocol/Protocol125.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.h1
15 files changed, 115 insertions, 63 deletions
diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj
index e5897bccd..cb3ebf8f4 100644
--- a/VC2008/MCServer.vcproj
+++ b/VC2008/MCServer.vcproj
@@ -1691,6 +1691,10 @@
Name="Blocks"
>
<File
+ RelativePath="..\source\Blocks\BlockBed.cpp"
+ >
+ </File>
+ <File
RelativePath="..\source\blocks\BlockBed.h"
>
</File>
diff --git a/source/Blocks/BlockBed.h b/source/Blocks/BlockBed.h
index cbef5bb4d..b7b055aa8 100644
--- a/source/Blocks/BlockBed.h
+++ b/source/Blocks/BlockBed.h
@@ -10,64 +10,18 @@ public:
cBlockBedHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
-
- }
-
-
-
-
-
- virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override
- {
- if( a_Dir != 1 ) // Can only be placed on the floor
- return;
-
- NIBBLETYPE Meta = RotationToMetaData( a_Player->GetRotation() );
- Vector3i Direction = MetaDataToDirection( Meta );
-
- if (a_World->GetBlock(a_X+Direction.x, a_Y, a_Z+Direction.z) != E_BLOCK_AIR)
- {
- return;
- }
-
- a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_BED, Meta);
- a_World->SetBlock(a_X + Direction.x, a_Y, a_Z + Direction.z, E_BLOCK_BED, Meta | 0x8);
-
- OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
+ virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override;
+ virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override;
+ virtual void OnUse(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) override;
-
-
- virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override
+ virtual bool IsUseable() override
{
- char OldMeta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
-
- Vector3i ThisPos( a_X, a_Y, a_Z );
- Vector3i Direction = MetaDataToDirection( OldMeta & 0x7 );
- if (OldMeta & 0x8)
- {
- // Was pillow
- if (a_World->GetBlock(ThisPos - Direction) == E_BLOCK_BED)
- {
- a_World->FastSetBlock(ThisPos - Direction, E_BLOCK_AIR, 0);
- }
- }
- else
- {
- // Was foot end
- if (a_World->GetBlock(ThisPos + Direction) == E_BLOCK_BED)
- {
- a_World->FastSetBlock(ThisPos + Direction, E_BLOCK_AIR, 0);
- }
- }
+ return true;
}
-
-
-
-
-
+
virtual int GetDropID() override
{
return E_ITEM_BED;
@@ -78,10 +32,6 @@ public:
return 0;
}
-
-
-
-
virtual bool AllowBlockOnTop() override
{
return false;
@@ -90,7 +40,7 @@ public:
-
+ // Bed specific helper functions
static NIBBLETYPE RotationToMetaData( float a_Rotation )
{
a_Rotation += 180 + (180/4); // So its not aligned with axis
@@ -101,10 +51,6 @@ public:
return ((char)a_Rotation+2) % 4;
}
-
-
-
-
static Vector3i MetaDataToDirection( NIBBLETYPE a_MetaData )
{
switch( a_MetaData )
diff --git a/source/Chunk.cpp b/source/Chunk.cpp
index e7a828c66..606134f38 100644
--- a/source/Chunk.cpp
+++ b/source/Chunk.cpp
@@ -1787,6 +1787,18 @@ void cChunk::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_bl
+void cChunk::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ )
+{
+ for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
+ {
+ (*itr)->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
+ } // 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 ac34640f8..a76ec4e58 100644
--- a/source/Chunk.h
+++ b/source/Chunk.h
@@ -189,6 +189,7 @@ 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 BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ );
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 ee69e6cc0..af8f09820 100644
--- a/source/ChunkMap.cpp
+++ b/source/ChunkMap.cpp
@@ -484,6 +484,25 @@ void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a
+void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ )
+{
+ 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->BroadcastUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
+}
+
+
+
+
+
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 8ddd9d6c7..87873cac2 100644
--- a/source/ChunkMap.h
+++ b/source/ChunkMap.h
@@ -79,6 +79,8 @@ public:
void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL);
+ void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ );
+
void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
/// Broadcasts the block entity, if it is at the coords specified, to all clients except a_Exclude
diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp
index 1585a08b0..af0f686d1 100644
--- a/source/ClientHandle.cpp
+++ b/source/ClientHandle.cpp
@@ -962,6 +962,24 @@ bool cClientHandle::HandleHandshake(const AString & a_Username)
+void cClientHandle::HandleEntityAction(int a_EntityID, char a_ActionID)
+{
+ if( a_EntityID != m_Player->GetUniqueID() )
+ {
+ // We should only receive entity actions from the entity that is performing the action
+ return;
+ }
+
+ if( a_ActionID == 3 ) // Leave bed
+ {
+ m_Player->GetWorld()->BroadcastPlayerAnimation( *m_Player, 3 );
+ }
+}
+
+
+
+
+
void cClientHandle::SendData(const char * a_Data, int a_Size)
{
{
@@ -1461,6 +1479,15 @@ void cClientHandle::SendBlockBreakAnim(int a_entityID, int a_blockX, int a_block
+void cClientHandle::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ )
+{
+ m_Protocol->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
+}
+
+
+
+
+
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 e5625eb20..94f132ea0 100644
--- a/source/ClientHandle.h
+++ b/source/ClientHandle.h
@@ -117,6 +117,7 @@ public:
void SendWholeInventory (const cWindow & a_Window);
void SendWindowClose (char a_WindowID);
void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots);
+ void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ );
const AString & GetUsername(void) const; //tolua_export
@@ -161,6 +162,7 @@ public:
void HandleDisconnect (const AString & a_Reason);
void HandleKeepAlive (int a_KeepAliveID);
bool HandleHandshake (const AString & a_Username);
+ void HandleEntityAction (int a_EntityID, char a_ActionID);
/** Called when the protocol has finished logging the user in.
Return true to allow the user in; false to kick them.
diff --git a/source/Protocol/Protocol.h b/source/Protocol/Protocol.h
index ada63af6b..c187387c1 100644
--- a/source/Protocol/Protocol.h
+++ b/source/Protocol/Protocol.h
@@ -84,6 +84,7 @@ public:
virtual void SendWholeInventory (const cWindow & a_Window) = 0;
virtual void SendWindowClose (char a_WindowID) = 0;
virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) = 0;
+ virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0;
/// Returns the ServerID used for authentication through session.minecraft.net
virtual AString GetAuthServerID(void) = 0;
diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp
index 1f2edad63..bec6a19b6 100644
--- a/source/Protocol/Protocol125.cpp
+++ b/source/Protocol/Protocol125.cpp
@@ -46,7 +46,7 @@ enum
PACKET_BLOCK_DIG = 0x0e,
PACKET_BLOCK_PLACE = 0x0f,
PACKET_SLOT_SELECTED = 0x10,
- PACKET_ADD_TO_INV = 0x11, // TODO: Sure this is not Use Bed??
+ PACKET_USE_BED = 0x11, // TODO: Sure this is not Use Bed??
PACKET_ANIMATION = 0x12,
PACKET_PACKET_ENTITY_ACTION = 0x13,
PACKET_PLAYER_SPAWN = 0x14,
@@ -778,6 +778,22 @@ void cProtocol125::SendWindowOpen(char a_WindowID, char a_WindowType, const AStr
+void cProtocol125::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ )
+{
+ cCSLock Lock(m_CSPacket);
+ WriteByte(PACKET_USE_BED);
+ WriteInt (a_Entity.GetUniqueID());
+ WriteByte(0); // Unknown byte only 0 has been observed
+ WriteInt (a_BlockX);
+ WriteByte(a_BlockY);
+ WriteInt (a_BlockZ);
+ Flush();
+}
+
+
+
+
+
AString cProtocol125::GetAuthServerID(void)
{
// http://wiki.vg/wiki/index.php?title=Session&oldid=2262
@@ -985,7 +1001,7 @@ int cProtocol125::ParseEntityAction(void)
{
HANDLE_PACKET_READ(ReadBEInt, int, EntityID);
HANDLE_PACKET_READ(ReadChar, char, ActionID);
- // TODO: m_Client->HandleEntityAction(...);
+ m_Client->HandleEntityAction(EntityID, ActionID);
return PARSE_OK;
}
diff --git a/source/Protocol/Protocol125.h b/source/Protocol/Protocol125.h
index 19a080506..84dfa7a72 100644
--- a/source/Protocol/Protocol125.h
+++ b/source/Protocol/Protocol125.h
@@ -68,6 +68,7 @@ public:
virtual void SendWholeInventory (const cWindow & a_Window) override;
virtual void SendWindowClose (char a_WindowID) override;
virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override;
+ virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override;
virtual AString GetAuthServerID(void) override;
diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp
index ac231bc51..edd34b7dc 100644
--- a/source/Protocol/ProtocolRecognizer.cpp
+++ b/source/Protocol/ProtocolRecognizer.cpp
@@ -485,6 +485,16 @@ void cProtocolRecognizer::SendWindowOpen(char a_WindowID, char a_WindowType, con
+void cProtocolRecognizer::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ )
+{
+ ASSERT(m_Protocol != NULL);
+ m_Protocol->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
+}
+
+
+
+
+
AString cProtocolRecognizer::GetAuthServerID(void)
{
ASSERT(m_Protocol != NULL);
diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h
index e870eca29..2e2f5a9e9 100644
--- a/source/Protocol/ProtocolRecognizer.h
+++ b/source/Protocol/ProtocolRecognizer.h
@@ -79,6 +79,7 @@ public:
virtual void SendWholeInventory (const cWindow & a_Window) override;
virtual void SendWindowClose (char a_WindowID) override;
virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override;
+ virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override;
virtual AString GetAuthServerID(void) override;
diff --git a/source/World.cpp b/source/World.cpp
index 03438b227..8bb14eb53 100644
--- a/source/World.cpp
+++ b/source/World.cpp
@@ -1440,6 +1440,15 @@ void cWorld::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_bl
+void cWorld::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ )
+{
+ m_ChunkMap->BroadcastUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
+}
+
+
+
+
+
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 08ccc4226..302461495 100644
--- a/source/World.h
+++ b/source/World.h
@@ -94,6 +94,7 @@ public:
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);
+ void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ );
/// 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);