A bit of cleanup and documentation around the UI window handling
git-svn-id: http://mc-server.googlecode.com/svn/trunk@716 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
0b4a84969c
commit
e8366993ce
@ -27,21 +27,30 @@ public:
|
||||
virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta);
|
||||
virtual bool NeedsRandomTicks();
|
||||
virtual void DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z);
|
||||
//Checks if the block can stay at
|
||||
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z);
|
||||
//Checks if the block can be placed at this point. Default: CanBeAt(...) NOTE: In the block is not placed in this callback
|
||||
virtual bool CanBePlacedAt(cWorld *a_World, int a_X, int a_Y, int a_Z, char a_Dir);
|
||||
//This gets called if the player tries to place a block ontop of this block (Only if he aims directly on this block)
|
||||
virtual bool AllowBlockOnTop();
|
||||
virtual bool IsUseable();
|
||||
virtual bool IsClickedThrough();
|
||||
virtual bool IgnoreBuildCollision();
|
||||
//Indicates this block can be placed on the side of other blocks. Default: true
|
||||
|
||||
/// Checks if the block can stay at the specified coords in the
|
||||
virtual bool CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
/// Checks if the block can be placed at this point. Default: CanBeAt(...) NOTE: This call doesn't actually place the block
|
||||
virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
|
||||
|
||||
/// Called when the player tries to place a block on top of this block (Only if he aims directly on this block); return false to disallow
|
||||
virtual bool AllowBlockOnTop(void);
|
||||
|
||||
/// Called to check whether this block supports a rclk action. If it returns true, OnClicked() is called
|
||||
virtual bool IsUseable(void);
|
||||
|
||||
virtual bool IsClickedThrough(void);
|
||||
|
||||
virtual bool IgnoreBuildCollision(void);
|
||||
|
||||
/// Indicates this block can be placed on the side of other blocks. Default: true
|
||||
virtual bool CanBePlacedOnSide();
|
||||
//Does this block drops if it gets destroyed by an unsuitable situation? Default: true
|
||||
|
||||
/// Does this block drop if it gets destroyed by an unsuitable situation? Default: true
|
||||
virtual bool DropOnUnsuitable();
|
||||
|
||||
static cBlockHandler *GetBlockHandler(BLOCKTYPE a_BlockID);
|
||||
static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockID);
|
||||
|
||||
static void Deinit();
|
||||
|
||||
|
@ -1,7 +1,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Block.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockEntityHandler : public cBlockHandler
|
||||
{
|
||||
public:
|
||||
@ -9,14 +14,18 @@ public:
|
||||
: cBlockHandler(a_BlockID)
|
||||
{
|
||||
}
|
||||
virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) override
|
||||
|
||||
virtual void OnClick(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
{
|
||||
a_World->UseBlockEntity(a_Player, a_X, a_Y, a_Z);
|
||||
a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
virtual bool IsUseable() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -157,8 +157,8 @@ void cChestEntity::SaveToJson( Json::Value& a_Value )
|
||||
|
||||
void cChestEntity::SendTo( cClientHandle* a_Client, cServer* a_Server )
|
||||
{
|
||||
(void)a_Client;
|
||||
(void)a_Server;
|
||||
UNUSED(a_Client);
|
||||
UNUSED(a_Server);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -166,14 +166,12 @@ void cChestEntity::SendTo( cClientHandle* a_Client, cServer* a_Server )
|
||||
|
||||
|
||||
|
||||
void cChestEntity::UsedBy( cPlayer * a_Player )
|
||||
void cChestEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if( !GetWindow() )
|
||||
if (!GetWindow())
|
||||
{
|
||||
cWindow* Window = new cWindow( this, true );
|
||||
Window->SetSlots( GetContents(), GetChestHeight()*c_ChestWidth );
|
||||
Window->SetWindowID( 1 );
|
||||
Window->SetWindowType( cWindow::Chest );
|
||||
cWindow * Window = new cWindow(this, true, cWindow::Chest, 1);
|
||||
Window->SetSlots(GetContents(), GetChestHeight() * c_ChestWidth);
|
||||
Window->SetWindowTitle("UberChest");
|
||||
Window->GetOwner()->SetEntity(this);
|
||||
OpenWindow( Window );
|
||||
|
@ -262,18 +262,18 @@ void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket
|
||||
|
||||
|
||||
|
||||
void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z)
|
||||
void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// a_Player rclked block entity at the coords specified, handle it
|
||||
cCSLock Lock(m_CSLayers);
|
||||
int ChunkX, ChunkZ;
|
||||
cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
|
||||
cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ);
|
||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Chunk->UseBlockEntity(a_Player, a_X, a_Y, a_Z);
|
||||
Chunk->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
|
||||
|
@ -882,10 +882,12 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
|
||||
cWorld * World = m_Player->GetWorld();
|
||||
|
||||
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ));
|
||||
if(Handler->IsUseable())
|
||||
if (Handler->IsUseable())
|
||||
{
|
||||
Handler->OnClick(World, m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
cItemHandler *ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID);
|
||||
|
||||
if(ItemHandler->OnItemUse(World, m_Player, &Equipped, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction))
|
||||
|
@ -19,12 +19,9 @@
|
||||
|
||||
|
||||
cCraftingWindow::cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible )
|
||||
: cWindow( a_Owner, a_bInventoryVisible )
|
||||
: cWindow(a_Owner, a_bInventoryVisible, cWindow::Workbench, 1)
|
||||
{
|
||||
SetWindowID( 1 );
|
||||
SetWindowType( cWindow::Workbench ); // Workbench
|
||||
|
||||
cItem* Slots = new cItem[10];
|
||||
cItem * Slots = new cItem[10];
|
||||
SetSlots( Slots, 10 );
|
||||
}
|
||||
|
||||
|
@ -13,21 +13,23 @@
|
||||
|
||||
|
||||
cFurnaceWindow::cFurnaceWindow( cFurnaceEntity* a_Owner )
|
||||
: cWindow( a_Owner, true )
|
||||
: cWindow(a_Owner, true, cWindow::Furnace, 1)
|
||||
, m_Furnace( a_Owner )
|
||||
{
|
||||
SetWindowID( 1 );
|
||||
SetWindowType( cWindow::Furnace ); // Furnace
|
||||
}
|
||||
|
||||
void cFurnaceWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player )
|
||||
|
||||
|
||||
|
||||
|
||||
void cFurnaceWindow::Clicked(cPacket_WindowClick * a_ClickPacket, cPlayer & a_Player)
|
||||
{
|
||||
cItem Fuel = *GetSlot( 0 );
|
||||
|
||||
cWindow::Clicked( a_ClickPacket, a_Player );
|
||||
if( m_Furnace )
|
||||
if (m_Furnace != NULL)
|
||||
{
|
||||
if( a_ClickPacket->m_SlotNum >= 0 && a_ClickPacket->m_SlotNum <= 2 ) // them important slots
|
||||
if ((a_ClickPacket->m_SlotNum >= 0) && (a_ClickPacket->m_SlotNum <= 2)) // them important slots
|
||||
{
|
||||
if( Fuel.m_ItemID != GetSlot( 0 )->m_ItemID )
|
||||
m_Furnace->ResetCookTimer();
|
||||
@ -40,8 +42,16 @@ void cFurnaceWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Pl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cFurnaceWindow::Close( cPlayer & a_Player )
|
||||
{
|
||||
m_Furnace = 0;
|
||||
m_Furnace = NULL;
|
||||
cWindow::Close( a_Player );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -48,10 +48,9 @@ cInventory::cInventory(cPlayer* a_Owner)
|
||||
|
||||
if( !GetWindow() )
|
||||
{
|
||||
cWindow* Window = new cWindow( this, false );
|
||||
Window->SetSlots( m_Slots, c_NumSlots );
|
||||
Window->SetWindowID( 0 );
|
||||
OpenWindow( Window );
|
||||
cWindow* Window = new cWindow( this, false, cWindow::Inventory, 0);
|
||||
Window->SetSlots(m_Slots, c_NumSlots);
|
||||
OpenWindow(Window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,7 +460,7 @@ void cPlayer::CloseWindow(char a_WindowType)
|
||||
(m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0)
|
||||
)
|
||||
{
|
||||
LOG("Player holds item! Dropping it...");
|
||||
LOGD("Player holds item! Dropping it...");
|
||||
TossItem( true, m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount );
|
||||
}
|
||||
|
||||
@ -481,17 +481,18 @@ void cPlayer::CloseWindow(char a_WindowType)
|
||||
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2);
|
||||
}
|
||||
|
||||
if (m_CurrentWindow)
|
||||
if (m_CurrentWindow != NULL)
|
||||
{
|
||||
// FIXME: If the player entity is destroyed while having a chest window open, the chest will not close
|
||||
if (a_WindowType == 1 && strcmp(m_CurrentWindow->GetWindowTitle().c_str(), "UberChest") == 0) { // Chest
|
||||
cBlockEntity *block = m_CurrentWindow->GetOwner()->GetEntity();
|
||||
if ((a_WindowType == 1) && (m_CurrentWindow->GetWindowType() == cWindow::Chest))
|
||||
{
|
||||
// Chest
|
||||
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;
|
||||
int y = 0;
|
||||
m_CurrentWindow->GetOwner()->GetBlockPos(ChestClose.m_PosX, y, ChestClose.m_PosZ);
|
||||
ChestClose.m_PosY = (short)y;
|
||||
ChestClose.m_Byte1 = 1; // Unused, always 1
|
||||
ChestClose.m_Byte2 = 0; // 0 = closed
|
||||
m_World->Broadcast(ChestClose);
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,9 @@
|
||||
|
||||
|
||||
|
||||
cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible )
|
||||
: m_WindowID( 0 )
|
||||
, m_WindowType( 0 )
|
||||
cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible, cWindow::WindowType a_WindowType, int a_WindowID)
|
||||
: m_WindowID( a_WindowID )
|
||||
, m_WindowType( a_WindowType )
|
||||
, m_Owner( a_Owner )
|
||||
, m_bInventoryVisible( a_bInventoryVisible )
|
||||
, m_NumSlots( 0 )
|
||||
@ -28,8 +28,11 @@ cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible )
|
||||
, m_DraggingItem( 0 )
|
||||
, m_IsDestroyed(false)
|
||||
{
|
||||
LOGD("Created a window at %p", this);
|
||||
if( !m_bInventoryVisible ) m_DraggingItem = new cItem();
|
||||
LOGD("Created a window at %p, type = %d, ID = %i", this, a_WindowType, a_WindowID);
|
||||
if (!m_bInventoryVisible)
|
||||
{
|
||||
m_DraggingItem = new cItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -234,18 +237,18 @@ void cWindow::Open( cPlayer & a_Player )
|
||||
void cWindow::Close( cPlayer & a_Player )
|
||||
{
|
||||
//Checks wheather the player is still holding an item
|
||||
if(m_DraggingItem && m_DraggingItem->m_ItemCount > 0)
|
||||
if (m_DraggingItem && m_DraggingItem->m_ItemCount > 0)
|
||||
{
|
||||
LOG("Player holds item! Dropping it...");
|
||||
a_Player.TossItem( true, m_DraggingItem->m_ItemCount );
|
||||
LOGD("Player holds item! Dropping it...");
|
||||
a_Player.TossItem(true, m_DraggingItem->m_ItemCount);
|
||||
}
|
||||
|
||||
cPacket_WindowClose WindowClose;
|
||||
WindowClose.m_Close = (char)m_WindowID;
|
||||
cClientHandle * ClientHandle = a_Player.GetClientHandle();
|
||||
if ( ClientHandle != NULL)
|
||||
if (ClientHandle != NULL)
|
||||
{
|
||||
ClientHandle->Send( WindowClose );
|
||||
ClientHandle->Send(WindowClose);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1,3 +1,12 @@
|
||||
|
||||
// cWindow.h
|
||||
|
||||
// Interfaces to the cWindow class representing a UI window for a specific block
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -14,26 +23,32 @@ typedef std::list<cPlayer *> cPlayerList;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Represents a UI window (base class) for a specific block entity.
|
||||
|
||||
There is up to one instance of the class for each block entity
|
||||
Each window has a list of players that are currently using it
|
||||
When there's no player using a window, it is destroyed
|
||||
*/
|
||||
class cWindow
|
||||
{
|
||||
public:
|
||||
cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible );
|
||||
enum WindowType
|
||||
{
|
||||
Inventory = -1, // This value is never actually sent to a client
|
||||
Chest = 0,
|
||||
Workbench = 1,
|
||||
Furnace = 2,
|
||||
Dispenser = 3,
|
||||
Enchantment = 4,
|
||||
Brewery = 5
|
||||
};
|
||||
|
||||
cWindow(cWindowOwner * a_Owner, bool a_bInventoryVisible, WindowType a_WindowType, int a_WindowID);
|
||||
~cWindow();
|
||||
|
||||
int GetWindowID() { return m_WindowID; }
|
||||
void SetWindowID( int a_WindowID ) { m_WindowID = a_WindowID; }
|
||||
|
||||
enum WindowType {
|
||||
Chest,
|
||||
Workbench,
|
||||
Furnace,
|
||||
Dispenser,
|
||||
Enchantment,
|
||||
Brewery
|
||||
};
|
||||
|
||||
int GetWindowType() { return m_WindowType; }
|
||||
void SetWindowType( int a_WindowType ) { m_WindowType = a_WindowType; }
|
||||
int GetWindowType(void) const { return m_WindowType; }
|
||||
|
||||
cItem* GetSlots() { return m_Slots; }
|
||||
int GetNumSlots() { return m_NumSlots; }
|
||||
|
@ -1,13 +1,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cBlockEntity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cWindow;
|
||||
class cBlockEntity;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Implements the base behavior expected from a class that can handle UI windows for block entities.
|
||||
*/
|
||||
class cWindowOwner
|
||||
{
|
||||
public:
|
||||
@ -17,11 +25,17 @@ public:
|
||||
|
||||
cWindow* GetWindow() { return m_Window; }
|
||||
|
||||
void SetEntity(cBlockEntity *a_Entity) { m_Entity = a_Entity; }
|
||||
cBlockEntity *GetEntity() { return m_Entity; }
|
||||
void SetEntity(cBlockEntity * a_Entity) { m_Entity = a_Entity; }
|
||||
void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
|
||||
{
|
||||
a_BlockX = m_Entity->GetPosX();
|
||||
a_BlockY = m_Entity->GetPosY();
|
||||
a_BlockZ = m_Entity->GetPosZ();
|
||||
}
|
||||
|
||||
private:
|
||||
cWindow* m_Window;
|
||||
cBlockEntity *m_Entity;
|
||||
cWindow * m_Window;
|
||||
cBlockEntity * m_Entity;
|
||||
};
|
||||
|
||||
|
||||
|
@ -265,7 +265,7 @@ public:
|
||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // tolua_export
|
||||
|
||||
/// a_Player is using block entity at [x, y, z], handle that:
|
||||
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); }
|
||||
void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); }
|
||||
|
||||
void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
|
||||
void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export
|
||||
|
Loading…
Reference in New Issue
Block a user