summaryrefslogtreecommitdiffstats
path: root/src/UI
diff options
context:
space:
mode:
Diffstat (limited to 'src/UI')
-rw-r--r--src/UI/SlotArea.cpp259
-rw-r--r--src/UI/SlotArea.h20
-rw-r--r--src/UI/Window.cpp97
-rw-r--r--src/UI/Window.h7
4 files changed, 326 insertions, 57 deletions
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 48ebf489b..e220960ff 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -60,12 +60,35 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
return;
}
-
case caDblClick:
{
DblClicked(a_Player, a_SlotNum);
return;
}
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ case caDropKey:
+ case caCtrlDropKey:
+ {
+ DropClicked(a_Player, a_SlotNum, (a_ClickAction == caCtrlDropKey));
+ return;
+ }
+ case caNumber1:
+ case caNumber2:
+ case caNumber3:
+ case caNumber4:
+ case caNumber5:
+ case caNumber6:
+ case caNumber7:
+ case caNumber8:
+ case caNumber9:
+ {
+ NumberClicked(a_Player, a_SlotNum, a_ClickAction);
+ return;
+ }
default:
{
break;
@@ -226,6 +249,77 @@ void cSlotArea::DblClicked(cPlayer & a_Player, int a_SlotNum)
+void cSlotArea::MiddleClicked(cPlayer & a_Player, int a_SlotNum)
+{
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+ cItem & DraggingItem = a_Player.GetDraggingItem();
+
+ if (!a_Player.IsGameModeCreative() || Slot.IsEmpty() || !DraggingItem.IsEmpty())
+ {
+ return;
+ }
+
+ DraggingItem = Slot;
+ DraggingItem.m_ItemCount = DraggingItem.GetMaxStackSize();
+}
+
+
+
+
+
+void cSlotArea::DropClicked(cPlayer & a_Player, int a_SlotNum, bool a_DropStack)
+{
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+ if (Slot.IsEmpty())
+ {
+ return;
+ }
+
+ cItem ItemToDrop = Slot.CopyOne();
+ if (a_DropStack)
+ {
+ ItemToDrop.m_ItemCount = Slot.m_ItemCount;
+ }
+
+ Slot.m_ItemCount -= ItemToDrop.m_ItemCount;
+ if (Slot.m_ItemCount <= 0)
+ {
+ Slot.Empty();
+ }
+ SetSlot(a_SlotNum, a_Player, Slot);
+
+ a_Player.TossPickup(ItemToDrop);
+}
+
+
+
+
+
+void cSlotArea::NumberClicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction)
+{
+ if ((a_ClickAction < caNumber1) || (a_ClickAction > caNumber9))
+ {
+ return;
+ }
+
+ int HotbarSlot = (int)a_ClickAction - (int)caNumber1;
+ cItem ItemInHotbar(a_Player.GetInventory().GetHotbarSlot(HotbarSlot));
+ cItem ItemInSlot(*GetSlot(a_SlotNum, a_Player));
+
+ // The items are equal. Do nothing.
+ if (ItemInHotbar.IsEqual(ItemInSlot))
+ {
+ return;
+ }
+
+ a_Player.GetInventory().SetHotbarSlot(HotbarSlot, ItemInSlot);
+ SetSlot(a_SlotNum, a_Player, ItemInHotbar);
+}
+
+
+
+
+
void cSlotArea::OnPlayerAdded(cPlayer & a_Player)
{
UNUSED(a_Player);
@@ -410,6 +504,12 @@ cSlotAreaCrafting::cSlotAreaCrafting(int a_GridSize, cWindow & a_ParentWindow) :
void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem)
{
+ if (a_ClickAction == caMiddleClick)
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+
// Override for craft result slot
if (a_SlotNum == 0)
{
@@ -417,12 +517,17 @@ void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction
{
ShiftClickedResult(a_Player);
}
+ else if ((a_ClickAction == caDropKey) || (a_ClickAction == caCtrlDropKey))
+ {
+ DropClickedResult(a_Player);
+ }
else
{
ClickedResult(a_Player);
}
return;
}
+
super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem);
UpdateRecipe(a_Player);
}
@@ -468,6 +573,20 @@ void cSlotAreaCrafting::OnPlayerRemoved(cPlayer & a_Player)
+void cSlotAreaCrafting::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
+{
+ // Update the recipe after setting the slot, if the slot is not the result slot:
+ super::SetSlot(a_SlotNum, a_Player, a_Item);
+ if (a_SlotNum != 0)
+ {
+ UpdateRecipe(a_Player);
+ }
+}
+
+
+
+
+
void cSlotAreaCrafting::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
{
UNUSED(a_ItemStack);
@@ -545,16 +664,20 @@ void cSlotAreaCrafting::ShiftClickedResult(cPlayer & a_Player)
// Distribute the result, this time for real:
ResultCopy = Result;
m_ParentWindow.DistributeStack(ResultCopy, a_Player, this, true);
-
+
// Remove the ingredients from the crafting grid and update the recipe:
cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
cCraftingGrid Grid(PlayerSlots, m_GridSize, m_GridSize);
Recipe.ConsumeIngredients(Grid);
Grid.CopyToItems(PlayerSlots);
UpdateRecipe(a_Player);
+
+ // Broadcast the window, we sometimes move items to different locations than Vanilla, causing needless desyncs:
+ m_ParentWindow.BroadcastWholeWindow();
+
+ // If the recipe has changed, bail out:
if (!Recipe.GetResult().IsEqual(Result))
{
- // The recipe has changed, bail out
return;
}
}
@@ -564,6 +687,27 @@ void cSlotAreaCrafting::ShiftClickedResult(cPlayer & a_Player)
+void cSlotAreaCrafting::DropClickedResult(cPlayer & a_Player)
+{
+ // Get the current recipe:
+ cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
+ const cItem & Result = Recipe.GetResult();
+
+ cItem * PlayerSlots = GetPlayerSlots(a_Player) + 1;
+ cCraftingGrid Grid(PlayerSlots, m_GridSize, m_GridSize);
+
+ a_Player.TossPickup(Result);
+ Recipe.ConsumeIngredients(Grid);
+ Grid.CopyToItems(PlayerSlots);
+
+ HandleCraftItem(Result, a_Player);
+ UpdateRecipe(a_Player);
+}
+
+
+
+
+
void cSlotAreaCrafting::UpdateRecipe(cPlayer & a_Player)
{
cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize);
@@ -651,15 +795,37 @@ void cSlotAreaAnvil::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_C
return;
}
- if (a_ClickAction == caDblClick)
- {
- return;
- }
-
- if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
+ switch (a_ClickAction)
{
- ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
- return;
+ case caDblClick:
+ {
+ return;
+ }
+ case caShiftLeftClick:
+ case caShiftRightClick:
+ {
+ ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
+ return;
+ }
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ case caDropKey:
+ case caCtrlDropKey:
+ {
+ if (CanTakeResultItem(a_Player))
+ {
+ DropClicked(a_Player, a_SlotNum, true);
+ OnTakeResult(a_Player);
+ }
+ return;
+ }
+ default:
+ {
+ break;
+ }
}
cItem Slot(*GetSlot(a_SlotNum, a_Player));
@@ -1057,12 +1223,16 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio
ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
return;
}
-
case caDblClick:
{
DblClicked(a_Player, a_SlotNum);
return;
}
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
default:
{
break;
@@ -1407,11 +1577,32 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a
bAsync = true;
}
- if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
+ switch (a_ClickAction)
{
- HandleSmeltItem(Slot, a_Player);
- ShiftClicked(a_Player, a_SlotNum, Slot);
- return;
+ case caShiftLeftClick:
+ case caShiftRightClick:
+ {
+ HandleSmeltItem(Slot, a_Player);
+ ShiftClicked(a_Player, a_SlotNum, Slot);
+ return;
+ }
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ case caDropKey:
+ case caCtrlDropKey:
+ {
+ DropClicked(a_Player, a_SlotNum, (a_SlotNum == caCtrlDropKey));
+ Slot.m_ItemCount = Slot.m_ItemCount - GetSlot(a_SlotNum, a_Player)->m_ItemCount;
+ HandleSmeltItem(Slot, a_Player);
+ return;
+ }
+ default:
+ {
+ break;
+ }
}
cItem & DraggingItem = a_Player.GetDraggingItem();
@@ -1589,6 +1780,12 @@ void cSlotAreaInventoryBase::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAc
{
if (a_Player.IsGameModeCreative() && (m_ParentWindow.GetWindowType() == cWindow::wtInventory))
{
+ if ((a_ClickAction == caDropKey) || (a_ClickAction == caCtrlDropKey))
+ {
+ DropClicked(a_Player, a_SlotNum, (a_ClickAction == caCtrlDropKey));
+ return;
+ }
+
// Creative inventory must treat a_ClickedItem as a DraggedItem instead, replacing the inventory slot with it
SetSlot(a_SlotNum, a_Player, a_ClickedItem);
return;
@@ -1676,16 +1873,28 @@ void cSlotAreaArmor::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_C
return;
}
- if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
- {
- ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
- return;
- }
-
- // Armors haven't a dbl click
- if (a_ClickAction == caDblClick)
+ switch (a_ClickAction)
{
- return;
+ case caDblClick:
+ {
+ // Armors haven't a dbl click
+ return;
+ }
+ case caShiftLeftClick:
+ case caShiftRightClick:
+ {
+ ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
+ return;
+ }
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ default:
+ {
+ break;
+ }
}
cItem Slot(*GetSlot(a_SlotNum, a_Player));
diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h
index b4b693cf6..3dc5c3849 100644
--- a/src/UI/SlotArea.h
+++ b/src/UI/SlotArea.h
@@ -46,10 +46,19 @@ public:
/// Called from Clicked when the action is a shiftclick (left or right)
virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem);
-
+
/// Called from Clicked when the action is a caDblClick
virtual void DblClicked(cPlayer & a_Player, int a_SlotNum);
-
+
+ /** Called from Clicked when the action is a middleclick */
+ virtual void MiddleClicked(cPlayer & a_Player, int a_SlotNum);
+
+ /** Called from Clicked when the action is a drop click. */
+ virtual void DropClicked(cPlayer & a_Player, int a_SlotNum, bool a_DropStack);
+
+ /** Called from Clicked when the action is a number click. */
+ virtual void NumberClicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction);
+
/// Called when a new player opens the same parent window. The window already tracks the player. CS-locked.
virtual void OnPlayerAdded(cPlayer & a_Player);
@@ -232,10 +241,12 @@ public:
virtual void Clicked (cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual void DblClicked (cPlayer & a_Player, int a_SlotNum);
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
+ virtual void SetSlot (int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
// Distributing items into this area is completely disabled
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override;
+
protected:
/// Maps player's EntityID -> current recipe; not a std::map because cCraftingGrid needs proper constructor params
typedef std::list<std::pair<int, cCraftingRecipe> > cRecipeMap;
@@ -248,7 +259,10 @@ protected:
/// Handles a shift-click in the result slot. Crafts using the current recipe until it changes or no more space for result.
void ShiftClickedResult(cPlayer & a_Player);
-
+
+ /** Handles a drop-click in the result slot. */
+ void DropClickedResult(cPlayer & a_Player);
+
/// Updates the current recipe and result slot based on the ingredients currently in the crafting grid of the specified player
void UpdateRecipe(cPlayer & a_Player);
diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp
index 381c6e121..19db01b7a 100644
--- a/src/UI/Window.cpp
+++ b/src/UI/Window.cpp
@@ -178,6 +178,7 @@ void cWindow::Clicked(
switch (a_ClickAction)
{
+ case caLeftClickOutside:
case caRightClickOutside:
{
if (PlgMgr->CallHookPlayerTossingItem(a_Player))
@@ -190,25 +191,16 @@ void cWindow::Clicked(
a_Player.TossPickup(a_ClickedItem);
}
- // Toss one of the dragged items:
- a_Player.TossHeldItem();
- return;
- }
- case caLeftClickOutside:
- {
- if (PlgMgr->CallHookPlayerTossingItem(a_Player))
+ if (a_ClickAction == caLeftClickOutside)
{
- // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
- return;
+ // Toss all dragged items:
+ a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
}
-
- if (a_Player.IsGameModeCreative())
+ else
{
- a_Player.TossPickup(a_ClickedItem);
+ // Toss one of the dragged items:
+ a_Player.TossHeldItem();
}
-
- // Toss all dragged items:
- a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
return;
}
case caLeftClickOutsideHoldNothing:
@@ -913,21 +905,23 @@ void cEnchantingWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
// cChestWindow:
cChestWindow::cChestWindow(cChestEntity * a_Chest) :
- cWindow(wtChest, "Chest"),
+ cWindow(wtChest, (a_Chest->GetBlockType() == E_BLOCK_CHEST) ? "Chest" : "Trapped Chest"),
m_World(a_Chest->GetWorld()),
m_BlockX(a_Chest->GetPosX()),
m_BlockY(a_Chest->GetPosY()),
- m_BlockZ(a_Chest->GetPosZ())
+ m_BlockZ(a_Chest->GetPosZ()),
+ m_PrimaryChest(a_Chest),
+ m_SecondaryChest(NULL)
{
m_SlotAreas.push_back(new cSlotAreaChest(a_Chest, *this));
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
// Play the opening sound:
- m_World->BroadcastSoundEffect("random.chestopen", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
+ m_World->BroadcastSoundEffect("random.chestopen", (double)m_BlockX, (double)m_BlockY, (double)m_BlockZ, 1, 1);
// Send out the chest-open packet:
- m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, E_BLOCK_CHEST);
+ m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, a_Chest->GetBlockType());
}
@@ -935,11 +929,13 @@ cChestWindow::cChestWindow(cChestEntity * a_Chest) :
cChestWindow::cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_SecondaryChest) :
- cWindow(wtChest, "Double Chest"),
+ cWindow(wtChest, (a_PrimaryChest->GetBlockType() == E_BLOCK_CHEST) ? "Double Chest" : "Double Trapped Chest"),
m_World(a_PrimaryChest->GetWorld()),
m_BlockX(a_PrimaryChest->GetPosX()),
m_BlockY(a_PrimaryChest->GetPosY()),
- m_BlockZ(a_PrimaryChest->GetPosZ())
+ m_BlockZ(a_PrimaryChest->GetPosZ()),
+ m_PrimaryChest(a_PrimaryChest),
+ m_SecondaryChest(a_SecondaryChest)
{
m_SlotAreas.push_back(new cSlotAreaDoubleChest(a_PrimaryChest, a_SecondaryChest, *this));
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
@@ -948,10 +944,55 @@ cChestWindow::cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_Secon
m_ShouldDistributeToHotbarFirst = false;
// Play the opening sound:
- m_World->BroadcastSoundEffect("random.chestopen", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
+ m_World->BroadcastSoundEffect("random.chestopen", (double)m_BlockX, (double)m_BlockY, (double)m_BlockZ, 1, 1);
// Send out the chest-open packet:
- m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, E_BLOCK_CHEST);
+ m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, a_PrimaryChest->GetBlockType());
+}
+
+
+
+
+
+void cChestWindow::OpenedByPlayer(cPlayer & a_Player)
+{
+ int ChunkX, ChunkZ;
+
+ m_PrimaryChest->SetNumberOfPlayers(m_PrimaryChest->GetNumberOfPlayers() + 1);
+ cChunkDef::BlockToChunk(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosZ(), ChunkX, ChunkZ);
+ m_PrimaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
+
+ if (m_SecondaryChest != NULL)
+ {
+ m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() + 1);
+ cChunkDef::BlockToChunk(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosZ(), ChunkX, ChunkZ);
+ m_SecondaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
+ }
+
+ cWindow::OpenedByPlayer(a_Player);
+}
+
+
+
+
+
+bool cChestWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse)
+{
+ int ChunkX, ChunkZ;
+
+ m_PrimaryChest->SetNumberOfPlayers(m_PrimaryChest->GetNumberOfPlayers() - 1);
+ cChunkDef::BlockToChunk(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosZ(), ChunkX, ChunkZ);
+ m_PrimaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
+
+ if (m_SecondaryChest != NULL)
+ {
+ m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() - 1);
+ cChunkDef::BlockToChunk(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosZ(), ChunkX, ChunkZ);
+ m_SecondaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
+ }
+
+ cWindow::ClosedByPlayer(a_Player, a_CanRefuse);
+ return true;
}
@@ -961,9 +1002,9 @@ cChestWindow::cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_Secon
cChestWindow::~cChestWindow()
{
// Send out the chest-close packet:
- m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 0, E_BLOCK_CHEST);
+ m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 0, m_PrimaryChest->GetBlockType());
- m_World->BroadcastSoundEffect("random.chestclosed", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
+ m_World->BroadcastSoundEffect("random.chestclosed", (double)m_BlockX, (double)m_BlockY, (double)m_BlockZ, 1, 1);
}
@@ -974,7 +1015,7 @@ cChestWindow::~cChestWindow()
// cDropSpenserWindow:
cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_DropSpenser) :
- cWindow(wtDropSpenser, "Dropspenser")
+ cWindow(wtDropSpenser, (a_DropSpenser->GetBlockType() == E_BLOCK_DISPENSER) ? "Dispenser" : "Dropper")
{
m_ShouldDistributeToHotbarFirst = false;
m_SlotAreas.push_back(new cSlotAreaItemGrid(a_DropSpenser->GetContents(), *this));
@@ -1001,7 +1042,7 @@ cEnderChestWindow::cEnderChestWindow(cEnderChestEntity * a_EnderChest) :
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
// Play the opening sound:
- m_World->BroadcastSoundEffect("random.chestopen", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
+ m_World->BroadcastSoundEffect("random.chestopen", (double)m_BlockX, (double)m_BlockY, (double)m_BlockZ, 1, 1);
// Send out the chest-open packet:
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, E_BLOCK_ENDER_CHEST);
@@ -1017,7 +1058,7 @@ cEnderChestWindow::~cEnderChestWindow()
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 0, E_BLOCK_ENDER_CHEST);
// Play the closing sound
- m_World->BroadcastSoundEffect("random.chestclosed", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
+ m_World->BroadcastSoundEffect("random.chestclosed", (double)m_BlockX, (double)m_BlockY, (double)m_BlockZ, 1, 1);
}
diff --git a/src/UI/Window.h b/src/UI/Window.h
index 542dccb88..b170a9d78 100644
--- a/src/UI/Window.h
+++ b/src/UI/Window.h
@@ -114,7 +114,7 @@ public:
const cItem & a_ClickedItem
);
- void OpenedByPlayer(cPlayer & a_Player);
+ virtual void OpenedByPlayer(cPlayer & a_Player);
/// Called when a player closes this window; notifies all slot areas. Returns true if close accepted
virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse);
@@ -327,10 +327,15 @@ public:
cChestWindow(cChestEntity * a_Chest);
cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_SecondaryChest);
~cChestWindow();
+
+ virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) override;
+ virtual void OpenedByPlayer(cPlayer & a_Player) override;
protected:
cWorld * m_World;
int m_BlockX, m_BlockY, m_BlockZ; // Position of the chest, for the window-close packet
+ cChestEntity * m_PrimaryChest;
+ cChestEntity * m_SecondaryChest;
} ;