- 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
This commit is contained in:
parent
2ca40c819e
commit
c4f4ae5c71
@ -5,14 +5,21 @@
|
|||||||
#include "cMCLogger.h"
|
#include "cMCLogger.h"
|
||||||
#include "cPlayer.h"
|
#include "cPlayer.h"
|
||||||
#include "cWindow.h"
|
#include "cWindow.h"
|
||||||
|
#include "cWorld.h"
|
||||||
|
#include "cRoot.h"
|
||||||
#include "cPickup.h"
|
#include "cPickup.h"
|
||||||
#include "cMCLogger.h"
|
#include "cMCLogger.h"
|
||||||
#include "cChunk.h"
|
#include "cChunk.h"
|
||||||
|
|
||||||
|
class cWorld;
|
||||||
|
class cRoot;
|
||||||
|
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
cChestEntity::cChestEntity(int a_X, int a_Y, int a_Z, cChunk* a_Chunk)
|
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 )
|
: 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 ];
|
m_Content = new cItem[ c_ChestHeight*c_ChestWidth ];
|
||||||
}
|
}
|
||||||
@ -33,7 +40,7 @@ cChestEntity::~cChestEntity()
|
|||||||
void cChestEntity::Destroy()
|
void cChestEntity::Destroy()
|
||||||
{
|
{
|
||||||
// Drop items
|
// 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() )
|
if( !m_Content[i].IsEmpty() )
|
||||||
{
|
{
|
||||||
@ -42,6 +49,8 @@ void cChestEntity::Destroy()
|
|||||||
m_Content[i].Empty();
|
m_Content[i].Empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (m_JoinedChest)
|
||||||
|
m_JoinedChest->RemoveJoinedChest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
cItem * cChestEntity::GetSlot( int a_Slot )
|
cItem * cChestEntity::GetSlot( int a_Slot )
|
||||||
@ -154,19 +163,54 @@ void cChestEntity::UsedBy( cPlayer & a_Player )
|
|||||||
if( !GetWindow() )
|
if( !GetWindow() )
|
||||||
{
|
{
|
||||||
cWindow* Window = new cWindow( this, true );
|
cWindow* Window = new cWindow( this, true );
|
||||||
Window->SetSlots( m_Content, c_ChestHeight*c_ChestWidth );
|
Window->SetSlots( GetContents(), GetChestHeight()*c_ChestWidth );
|
||||||
Window->SetWindowID( 1 );
|
Window->SetWindowID( 1 );
|
||||||
Window->SetWindowType( cWindow::Chest );
|
Window->SetWindowType( cWindow::Chest );
|
||||||
Window->SetWindowTitle("UberChest");
|
Window->SetWindowTitle("UberChest");
|
||||||
|
Window->GetOwner()->SetEntity(this);
|
||||||
OpenWindow( Window );
|
OpenWindow( Window );
|
||||||
}
|
}
|
||||||
if( GetWindow() )
|
if ( GetWindow() )
|
||||||
{
|
{
|
||||||
if( a_Player.GetWindow() != GetWindow() )
|
if( a_Player.GetWindow() != GetWindow() )
|
||||||
{
|
{
|
||||||
a_Player.OpenWindow( GetWindow() );
|
a_Player.OpenWindow( GetWindow() );
|
||||||
|
|
||||||
GetWindow()->SendWholeWindow( a_Player.GetClientHandle() );
|
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;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "cBlockEntity.h"
|
#include "cBlockEntity.h"
|
||||||
#include "cWindowOwner.h"
|
#include "cWindowOwner.h"
|
||||||
#include "FileDefine.h"
|
#include "FileDefine.h"
|
||||||
|
#include "packets\cPacket_BlockAction.h"
|
||||||
|
|
||||||
namespace Json
|
namespace Json
|
||||||
{
|
{
|
||||||
@ -35,8 +36,17 @@ public:
|
|||||||
|
|
||||||
virtual void UsedBy( cPlayer & a_Player );
|
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_ChestWidth = 9;
|
||||||
static const int c_ChestHeight = 3;
|
static const int c_ChestHeight = 3;
|
||||||
private:
|
private:
|
||||||
cItem* m_Content;
|
cItem* m_Content;
|
||||||
|
bool m_TopChest;
|
||||||
|
cChestEntity *m_JoinedChest;
|
||||||
};
|
};
|
@ -629,7 +629,7 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
|
|||||||
if(PossibleBlock == E_BLOCK_FIRE)
|
if(PossibleBlock == E_BLOCK_FIRE)
|
||||||
{
|
{
|
||||||
PacketData->m_PosX = pX;
|
PacketData->m_PosX = pX;
|
||||||
PacketData->m_PosY = pY;
|
PacketData->m_PosY = (char)pY;
|
||||||
PacketData->m_PosZ = pZ;
|
PacketData->m_PosZ = pZ;
|
||||||
bBroken = true;
|
bBroken = true;
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ void cFurnaceEntity::UsedBy( cPlayer & a_Player )
|
|||||||
cWindow* Window = new cFurnaceWindow( this );
|
cWindow* Window = new cFurnaceWindow( this );
|
||||||
Window->SetSlots( m_Items, 3 );
|
Window->SetSlots( m_Items, 3 );
|
||||||
Window->SetWindowTitle("UberFurnace");
|
Window->SetWindowTitle("UberFurnace");
|
||||||
|
Window->GetOwner()->SetEntity(this);
|
||||||
OpenWindow( Window );
|
OpenWindow( Window );
|
||||||
}
|
}
|
||||||
if( GetWindow() )
|
if( GetWindow() )
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "packets/cPacket_Chat.h"
|
#include "packets/cPacket_Chat.h"
|
||||||
#include "packets/cPacket_NewInvalidState.h"
|
#include "packets/cPacket_NewInvalidState.h"
|
||||||
#include "packets/cPacket_PlayerListItem.h"
|
#include "packets/cPacket_PlayerListItem.h"
|
||||||
|
#include "packets/cPacket_BlockAction.h"
|
||||||
|
|
||||||
#include "Vector3d.h"
|
#include "Vector3d.h"
|
||||||
#include "Vector3f.h"
|
#include "Vector3f.h"
|
||||||
@ -377,8 +378,7 @@ void cPlayer::OpenWindow( cWindow* a_Window )
|
|||||||
|
|
||||||
void cPlayer::CloseWindow(char a_WindowType)
|
void cPlayer::CloseWindow(char a_WindowType)
|
||||||
{
|
{
|
||||||
if( m_CurrentWindow ) m_CurrentWindow->Close( *this );
|
if (a_WindowType == 0) { // Inventory
|
||||||
if (a_WindowType == 0) {
|
|
||||||
if(GetInventory().GetWindow()->GetDraggingItem() && GetInventory().GetWindow()->GetDraggingItem()->m_ItemCount > 0)
|
if(GetInventory().GetWindow()->GetDraggingItem() && GetInventory().GetWindow()->GetDraggingItem()->m_ItemCount > 0)
|
||||||
{
|
{
|
||||||
LOG("Player holds item! Dropping it...");
|
LOG("Player holds item! Dropping it...");
|
||||||
@ -400,6 +400,23 @@ void cPlayer::CloseWindow(char a_WindowType)
|
|||||||
Item->Empty();
|
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;
|
m_CurrentWindow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "MemoryLeak.h"
|
#include "MemoryLeak.h"
|
||||||
|
|
||||||
class cWindow;
|
class cWindow;
|
||||||
|
class cBlockEntity;
|
||||||
class cWindowOwner
|
class cWindowOwner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -11,6 +12,10 @@ public:
|
|||||||
void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; }
|
void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; }
|
||||||
|
|
||||||
cWindow* GetWindow() { return m_Window; }
|
cWindow* GetWindow() { return m_Window; }
|
||||||
|
|
||||||
|
void SetEntity(cBlockEntity *a_Entity) { m_Entity = a_Entity; }
|
||||||
|
cBlockEntity *GetEntity() { return m_Entity; }
|
||||||
private:
|
private:
|
||||||
cWindow* m_Window;
|
cWindow* m_Window;
|
||||||
|
cBlockEntity *m_Entity;
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user