From c4f4ae5c7122c58af239a01328c168627ed68e27 Mon Sep 17 00:00:00 2001 From: "mtilden@gmail.com" Date: Thu, 29 Dec 2011 13:16:23 +0000 Subject: [PATCH] - Chests open and close on clients when opened/closed - Beginnings of "Double Chest". All that's needed is detection when 2 chests get put next to each other, block other chests from then touching them on any side, load/save with the m_JoinedChest seeing each other and adding and making sure the left side is always the top rows. I'm not sure exactly at this moment how to do all of the detection and saving/loading of the double chest stuff so if you've any ideas feel free to point out some areas in the server code or implement it yourself. git-svn-id: http://mc-server.googlecode.com/svn/trunk@154 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cChestEntity.cpp | 52 ++++++++++++++++++++++++++++++++++++--- source/cChestEntity.h | 10 ++++++++ source/cClientHandle.cpp | 2 +- source/cFurnaceEntity.cpp | 1 + source/cPlayer.cpp | 21 ++++++++++++++-- source/cWindowOwner.h | 5 ++++ 6 files changed, 84 insertions(+), 7 deletions(-) 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