From e8366993ce3f1cc0c2c6cde1d133773d1f23c474 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Mon, 6 Aug 2012 20:10:16 +0000 Subject: 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 --- source/blocks/Block.h | 33 +++++++++++++++++++++------------ source/blocks/BlockEntity.h | 19 ++++++++++++++----- source/cChestEntity.cpp | 14 ++++++-------- source/cChunkMap.cpp | 6 +++--- source/cClientHandle.cpp | 6 ++++-- source/cCraftingWindow.cpp | 7 ++----- source/cFurnaceWindow.cpp | 26 ++++++++++++++++++-------- source/cInventory.cpp | 7 +++---- source/cPlayer.cpp | 19 ++++++++++--------- source/cWindow.cpp | 23 +++++++++++++---------- source/cWindow.h | 43 +++++++++++++++++++++++++++++-------------- source/cWindowOwner.h | 24 +++++++++++++++++++----- source/cWorld.h | 2 +- 13 files changed, 143 insertions(+), 86 deletions(-) diff --git a/source/blocks/Block.h b/source/blocks/Block.h index 0a5724ca3..50c541551 100644 --- a/source/blocks/Block.h +++ b/source/blocks/Block.h @@ -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(); diff --git a/source/blocks/BlockEntity.h b/source/blocks/BlockEntity.h index c7b8b0859..085b65158 100644 --- a/source/blocks/BlockEntity.h +++ b/source/blocks/BlockEntity.h @@ -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; } - - -}; \ No newline at end of file +}; + + + + diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp index d2cc168b0..4a46167c0 100644 --- a/source/cChestEntity.cpp +++ b/source/cChestEntity.cpp @@ -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 ); diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp index 53c49041c..a0f1e128c 100644 --- a/source/cChunkMap.cpp +++ b/source/cChunkMap.cpp @@ -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); } diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 5bbf0f512..b1a90f5b8 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -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)) diff --git a/source/cCraftingWindow.cpp b/source/cCraftingWindow.cpp index 9e6b565c6..03102123b 100644 --- a/source/cCraftingWindow.cpp +++ b/source/cCraftingWindow.cpp @@ -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 ); } diff --git a/source/cFurnaceWindow.cpp b/source/cFurnaceWindow.cpp index 963c848ec..8dcd0c8a5 100644 --- a/source/cFurnaceWindow.cpp +++ b/source/cFurnaceWindow.cpp @@ -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 ); -} \ No newline at end of file +} + + + + diff --git a/source/cInventory.cpp b/source/cInventory.cpp index 8854ad29a..8a0c06472 100644 --- a/source/cInventory.cpp +++ b/source/cInventory.cpp @@ -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); } } diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index b7b7919fd..c260330f6 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -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); } diff --git a/source/cWindow.cpp b/source/cWindow.cpp index fe029cfd9..f2c66420e 100644 --- a/source/cWindow.cpp +++ b/source/cWindow.cpp @@ -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); } { diff --git a/source/cWindow.h b/source/cWindow.h index 7d31d71e3..9d62dc43a 100644 --- a/source/cWindow.h +++ b/source/cWindow.h @@ -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 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; } diff --git a/source/cWindowOwner.h b/source/cWindowOwner.h index 3a1797f74..ef08bbe44 100644 --- a/source/cWindowOwner.h +++ b/source/cWindowOwner.h @@ -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; }; diff --git a/source/cWorld.h b/source/cWorld.h index d2cb94b50..ebba2ca5d 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -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 -- cgit v1.2.3