diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp index d0cd85536..ee70a6fb8 100644 --- a/source/cChestEntity.cpp +++ b/source/cChestEntity.cpp @@ -5,14 +5,21 @@ #include "cMCLogger.h" #include "cPlayer.h" #include "cWindow.h" +#include "cWorld.h" +#include "cRoot.h" #include "cPickup.h" #include "cMCLogger.h" #include "cChunk.h" +class cWorld; +class cRoot; + #include cChestEntity::cChestEntity(int a_X, int a_Y, int a_Z, cChunk* a_Chunk) : cBlockEntity( E_BLOCK_CHEST, a_X, a_Y, a_Z, a_Chunk ) + , m_TopChest( false ) + , m_JoinedChest( 0 ) { m_Content = new cItem[ c_ChestHeight*c_ChestWidth ]; } @@ -33,7 +40,7 @@ cChestEntity::~cChestEntity() void cChestEntity::Destroy() { // Drop items - for( int i = 0; i < c_ChestHeight*c_ChestWidth; ++i ) + for( int i = 0; i < c_ChestHeight * c_ChestWidth; ++i ) { if( !m_Content[i].IsEmpty() ) { @@ -42,6 +49,8 @@ void cChestEntity::Destroy() m_Content[i].Empty(); } } + if (m_JoinedChest) + m_JoinedChest->RemoveJoinedChest(this); } cItem * cChestEntity::GetSlot( int a_Slot ) @@ -154,19 +163,54 @@ void cChestEntity::UsedBy( cPlayer & a_Player ) if( !GetWindow() ) { cWindow* Window = new cWindow( this, true ); - Window->SetSlots( m_Content, c_ChestHeight*c_ChestWidth ); + Window->SetSlots( GetContents(), GetChestHeight()*c_ChestWidth ); Window->SetWindowID( 1 ); Window->SetWindowType( cWindow::Chest ); Window->SetWindowTitle("UberChest"); + Window->GetOwner()->SetEntity(this); OpenWindow( Window ); } - if( GetWindow() ) + if ( GetWindow() ) { if( a_Player.GetWindow() != GetWindow() ) { a_Player.OpenWindow( GetWindow() ); - GetWindow()->SendWholeWindow( a_Player.GetClientHandle() ); } } + cPacket_BlockAction ChestOpen; + ChestOpen.m_PosX = GetPosX(); + ChestOpen.m_PosY = (short)GetPosY(); + ChestOpen.m_PosZ = GetPosZ(); + ChestOpen.m_Byte1 = (char)1; + ChestOpen.m_Byte2 = (char)1; + cWorld::PlayerList PlayerList = cRoot::Get()->GetWorld()->GetAllPlayers(); + for( cWorld::PlayerList::iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr ) + { + if ((*itr) && (*itr)->GetClientHandle() && !((*itr)->GetClientHandle()->IsDestroyed())) { + (*itr)->GetClientHandle()->Send( ChestOpen ); + } + } +} + +cItem *cChestEntity::GetContents(bool a_OnlyThis) +{ + if (m_JoinedChest && !a_OnlyThis) + { + cItem *Combined = new cItem[GetChestHeight()*c_ChestWidth]; + int i; + cItem *first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + cItem *second = (!m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + for (i=0; i < GetChestHeight()*c_ChestWidth; i++) + { + int index = i % c_ChestHeight*c_ChestWidth; + if (i < c_ChestHeight*c_ChestWidth) + Combined[index] = first[index]; + else + Combined[index] = second[index]; + } + return Combined; + } + else + return m_Content; } diff --git a/source/cChestEntity.h b/source/cChestEntity.h index 785f57553..599d71c18 100644 --- a/source/cChestEntity.h +++ b/source/cChestEntity.h @@ -3,6 +3,7 @@ #include "cBlockEntity.h" #include "cWindowOwner.h" #include "FileDefine.h" +#include "packets\cPacket_BlockAction.h" namespace Json { @@ -35,8 +36,17 @@ public: virtual void UsedBy( cPlayer & a_Player ); + cChestEntity *GetJoinedChest() { return m_JoinedChest; } + void SetJoinedChest(cChestEntity *a_Chest) { m_JoinedChest = a_Chest; } + void RemoveJoinedChest(cChestEntity *a_Chest) { if (m_JoinedChest && m_JoinedChest == a_Chest) { m_JoinedChest = NULL; m_TopChest = false; } } + + int GetChestHeight() { return ((m_JoinedChest) ? c_ChestHeight * 2 : c_ChestHeight); } + cItem *GetContents(bool a_OnlyThis = false); + static const int c_ChestWidth = 9; static const int c_ChestHeight = 3; private: cItem* m_Content; + bool m_TopChest; + cChestEntity *m_JoinedChest; }; \ No newline at end of file diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 22adc2207..920963c28 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -629,7 +629,7 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) if(PossibleBlock == E_BLOCK_FIRE) { PacketData->m_PosX = pX; - PacketData->m_PosY = pY; + PacketData->m_PosY = (char)pY; PacketData->m_PosZ = pZ; bBroken = true; } diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp index 36524e3b7..46cadf5f2 100644 --- a/source/cFurnaceEntity.cpp +++ b/source/cFurnaceEntity.cpp @@ -69,6 +69,7 @@ void cFurnaceEntity::UsedBy( cPlayer & a_Player ) cWindow* Window = new cFurnaceWindow( this ); Window->SetSlots( m_Items, 3 ); Window->SetWindowTitle("UberFurnace"); + Window->GetOwner()->SetEntity(this); OpenWindow( Window ); } if( GetWindow() ) diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 92b16478a..820b11f8b 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -32,6 +32,7 @@ #include "packets/cPacket_Chat.h" #include "packets/cPacket_NewInvalidState.h" #include "packets/cPacket_PlayerListItem.h" +#include "packets/cPacket_BlockAction.h" #include "Vector3d.h" #include "Vector3f.h" @@ -377,8 +378,7 @@ void cPlayer::OpenWindow( cWindow* a_Window ) void cPlayer::CloseWindow(char a_WindowType) { - if( m_CurrentWindow ) m_CurrentWindow->Close( *this ); - if (a_WindowType == 0) { + if (a_WindowType == 0) { // Inventory if(GetInventory().GetWindow()->GetDraggingItem() && GetInventory().GetWindow()->GetDraggingItem()->m_ItemCount > 0) { LOG("Player holds item! Dropping it..."); @@ -400,6 +400,23 @@ void cPlayer::CloseWindow(char a_WindowType) Item->Empty(); } } + if (a_WindowType == 1 && strcmp(m_CurrentWindow->GetWindowTitle().c_str(), "UberChest") == 0) { // Chest + cBlockEntity *block = m_CurrentWindow->GetOwner()->GetEntity(); + cPacket_BlockAction ChestClose; + ChestClose.m_PosX = block->GetPosX(); + ChestClose.m_PosY = (short)block->GetPosY(); + ChestClose.m_PosZ = block->GetPosZ(); + ChestClose.m_Byte1 = 1; + ChestClose.m_Byte2 = 0; + cWorld::PlayerList PlayerList = cRoot::Get()->GetWorld()->GetAllPlayers(); + for( cWorld::PlayerList::iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr ) + { + if ((*itr) && (*itr)->GetClientHandle() && !((*itr)->GetClientHandle()->IsDestroyed())) { + (*itr)->GetClientHandle()->Send( ChestClose ); + } + } + } + if( m_CurrentWindow ) m_CurrentWindow->Close( *this ); m_CurrentWindow = 0; } diff --git a/source/cWindowOwner.h b/source/cWindowOwner.h index b60b97b6c..fed44d2d1 100644 --- a/source/cWindowOwner.h +++ b/source/cWindowOwner.h @@ -3,6 +3,7 @@ #include "MemoryLeak.h" class cWindow; +class cBlockEntity; class cWindowOwner { public: @@ -11,6 +12,10 @@ public: void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; } cWindow* GetWindow() { return m_Window; } + + void SetEntity(cBlockEntity *a_Entity) { m_Entity = a_Entity; } + cBlockEntity *GetEntity() { return m_Entity; } private: cWindow* m_Window; + cBlockEntity *m_Entity; }; \ No newline at end of file