1
0
Fork 0
cuberite-2a/src/UI/SlotArea.h

562 lines
16 KiB
C
Raw Normal View History

// SlotArea.h
// Interfaces to the cSlotArea class representing a contiguous area of slots in a UI window
#pragma once
#include "../Inventory.h"
class cHorse;
class cWindow;
class cPlayer;
2014-07-30 19:59:35 +00:00
class cBeaconEntity;
2015-09-24 08:48:33 +00:00
class cBrewingstandEntity;
class cChestEntity;
class cEnderChestEntity;
class cFurnaceEntity;
2014-09-12 22:18:02 +00:00
class cMinecartWithChest;
class cCraftingRecipe;
2014-04-15 19:10:44 +00:00
class cWorld;
class cSlotArea
{
public:
cSlotArea(int a_NumSlots, cWindow & a_ParentWindow);
virtual ~cSlotArea() {} // force a virtual destructor in all subclasses
2016-02-05 21:45:45 +00:00
int GetNumSlots(void) const { return m_NumSlots; }
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** Called to retrieve an item in the specified slot for the specified player. Must return a valid cItem. */
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const = 0;
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** Called to set an item in the specified slot for the specified player */
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) = 0;
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** Called when a player clicks in the window. Parameters taken from the click packet. */
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem);
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** 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);
2014-07-05 12:00:04 +00:00
2015-07-31 14:49:10 +00:00
/** Called from Clicked when the action is a caDblClick */
virtual void DblClicked(cPlayer & a_Player, int a_SlotNum);
2014-07-05 12:00:04 +00:00
/** Called from Clicked when the action is a middleclick */
virtual void MiddleClicked(cPlayer & a_Player, int a_SlotNum);
2014-07-05 22:40:59 +00:00
/** Called from Clicked when the action is a drop click. */
virtual void DropClicked(cPlayer & a_Player, int a_SlotNum, bool a_DropStack);
2014-07-09 12:30:06 +00:00
/** Called from Clicked when the action is a number click. */
virtual void NumberClicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction);
2015-07-31 14:49:10 +00:00
/** Called when a new player opens the same parent window. The window already tracks the player. CS-locked. */
virtual void OnPlayerAdded(cPlayer & a_Player);
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** Called when one of the players closes the parent window. The window already doesn't track the player. CS-locked. */
virtual void OnPlayerRemoved(cPlayer & a_Player);
2016-02-05 21:45:45 +00:00
/** Called to store as much of a_ItemStack in the area as possible. a_ItemStack is modified to reflect the change.
The default implementation searches each slot for available space and distributes the stack there.
if a_ShouldApply is true, the changes are written into the slots;
if a_ShouldApply is false, only a_ItemStack is modified to reflect the number of fits (for fit-testing purposes)
2015-07-31 14:49:10 +00:00
If a_KeepEmptySlots is true, empty slots will be skipped and won't be filled */
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill);
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** Called on DblClicking to collect all stackable items into hand.
The items are accumulated in a_Dragging and removed from the slots immediately.
If a_CollectFullStacks is false, slots with full stacks are skipped while collecting.
Returns true if full stack has been collected in a_Dragging, false if there's space remaining to fill. */
virtual bool CollectItemsToHand(cItem & a_Dragging, cPlayer & a_Player, bool a_CollectFullStacks);
protected:
int m_NumSlots;
cWindow & m_ParentWindow;
} ;
2015-07-31 14:49:10 +00:00
/** Handles any part of the inventory, using parameters in constructor to distinguish between the parts */
2020-04-13 16:38:06 +00:00
class cSlotAreaInventoryBase:
public cSlotArea
{
2020-04-13 16:38:06 +00:00
using Super = cSlotArea;
2016-02-05 21:45:45 +00:00
public:
2020-04-13 16:38:06 +00:00
cSlotAreaInventoryBase(int a_NumSlots, int a_SlotOffset, cWindow & a_ParentWindow);
2016-02-05 21:45:45 +00:00
// Creative inventory's click handling is somewhat different from survival inventory's, handle that here:
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
2016-02-05 21:45:45 +00:00
protected:
int m_SlotOffset; // Index that this area's slot 0 has in the underlying cInventory
} ;
2015-07-31 14:49:10 +00:00
/** Handles the main inventory of each player, excluding the armor and hotbar */
2020-04-13 16:38:06 +00:00
class cSlotAreaInventory:
public cSlotAreaInventoryBase
{
2020-04-13 16:38:06 +00:00
using Super = cSlotAreaInventoryBase;
2016-02-05 21:45:45 +00:00
public:
2020-04-13 16:38:06 +00:00
cSlotAreaInventory(cWindow & a_ParentWindow):
Super(cInventory::invInventoryCount, cInventory::invInventoryOffset, a_ParentWindow)
{
}
} ;
2015-07-31 14:49:10 +00:00
/** Handles the hotbar of each player */
2020-04-13 16:38:06 +00:00
class cSlotAreaHotBar:
public cSlotAreaInventoryBase
{
2020-04-13 16:38:06 +00:00
using Super = cSlotAreaInventoryBase;
2016-02-05 21:45:45 +00:00
public:
2020-04-13 16:38:06 +00:00
cSlotAreaHotBar(cWindow & a_ParentWindow):
Super(cInventory::invHotbarCount, cInventory::invHotbarOffset, a_ParentWindow)
{
}
} ;
/** Handles the shield of each player */
2020-04-13 16:38:06 +00:00
class cSlotAreaShield:
public cSlotAreaInventoryBase
{
2020-04-13 16:38:06 +00:00
using Super = cSlotAreaInventoryBase;
public:
2020-04-13 16:38:06 +00:00
cSlotAreaShield(cWindow & a_ParentWindow):
Super(cInventory::invShieldCount, cInventory::invShieldOffset, a_ParentWindow)
{
}
};
2015-07-31 14:49:10 +00:00
/** Handles the armor area of the player's inventory */
2020-04-13 16:38:06 +00:00
class cSlotAreaArmor:
public cSlotAreaInventoryBase
{
2020-04-13 16:38:06 +00:00
using Super = cSlotAreaInventoryBase;
public:
2020-04-13 16:38:06 +00:00
cSlotAreaArmor(cWindow & a_ParentWindow):
Super(cInventory::invArmorCount, cInventory::invArmorOffset, a_ParentWindow)
{
}
2014-04-24 18:41:25 +00:00
/** Distributing the stack is allowed only for compatible items (helmets into helmet slot etc.) */
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
2014-04-24 18:41:25 +00:00
/** Called when a player clicks in the window. Parameters taken from the click packet. */
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
static bool CanPlaceArmorInSlot(int a_SlotNum, const cItem & a_Item);
} ;
2015-07-31 14:49:10 +00:00
/** Handles any slot area that is representing a cItemGrid; same items for all the players */
2020-04-13 16:38:06 +00:00
class cSlotAreaItemGrid:
public cSlotArea,
public cItemGrid::cListener
{
2020-04-13 16:38:06 +00:00
using Super = cSlotArea;
2016-02-05 21:45:45 +00:00
public:
2020-04-13 16:38:06 +00:00
cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentWindow);
2016-02-05 21:45:45 +00:00
virtual ~cSlotAreaItemGrid() override;
2016-02-05 21:45:45 +00:00
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
protected:
cItemGrid & m_ItemGrid;
2016-02-05 21:45:45 +00:00
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
} ;
/** A cSlotArea with items layout that is private to each player and is temporary, such as
a crafting grid or an enchantment table.
2015-07-31 14:49:10 +00:00
This common ancestor stores the items in a per-player map. It also implements tossing items from the map. */
2020-04-13 16:38:06 +00:00
class cSlotAreaTemporary:
public cSlotArea
{
2020-04-13 16:38:06 +00:00
using Super = cSlotArea;
2016-02-05 21:45:45 +00:00
public:
2020-04-13 16:38:06 +00:00
cSlotAreaTemporary(int a_NumSlots, cWindow & a_ParentWindow);
2016-02-05 21:45:45 +00:00
// cSlotArea overrides:
virtual const cItem * GetSlot (int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot (int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
virtual void OnPlayerAdded (cPlayer & a_Player) override;
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** Tosses the player's items in slots [a_Begin, a_End) (ie. incl. a_Begin, but excl. a_End) */
void TossItems(cPlayer & a_Player, int a_Begin, int a_End);
2016-02-05 21:45:45 +00:00
protected:
2020-04-13 16:38:06 +00:00
using cItemMap = std::map<UInt32, std::vector<cItem> >; // Maps EntityID -> items
2016-02-05 21:45:45 +00:00
cItemMap m_Items;
2016-02-05 21:45:45 +00:00
2015-07-31 14:49:10 +00:00
/** Returns the pointer to the slot array for the player specified. */
cItem * GetPlayerSlots(cPlayer & a_Player);
} ;
2020-04-13 16:38:06 +00:00
class cSlotAreaCrafting:
public cSlotAreaTemporary
{
2020-04-13 16:38:06 +00:00
using Super = cSlotAreaTemporary;
2016-02-05 21:45:45 +00:00
public:
2020-04-13 16:38:06 +00:00
2015-07-31 14:49:10 +00:00
/** a_GridSize is allowed to be only 2 or 3 */
cSlotAreaCrafting(int a_GridSize, cWindow & a_ParentWindow);
// cSlotAreaTemporary overrides:
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) override;
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
virtual void SetSlot (int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
2016-02-05 21:45:45 +00:00
// Distributing items into this area is completely disabled
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
2014-07-09 12:30:06 +00:00
protected:
2015-03-21 14:18:17 +00:00
/** Maps player's EntityID -> current recipe.
Not a std::map because cCraftingGrid needs proper constructor params. */
typedef std::list<std::pair<UInt32, cCraftingRecipe> > cRecipeMap;
2016-02-05 21:45:45 +00:00
int m_GridSize;
cRecipeMap m_Recipes;
2016-02-05 21:45:45 +00:00
2015-03-21 14:18:17 +00:00
/** Handles a click in the result slot.
Crafts using the current recipe, if possible. */
void ClickedResult(cPlayer & a_Player);
2016-02-05 21:45:45 +00:00
2015-03-21 14:18:17 +00:00
/** 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);
2014-07-05 22:40:59 +00:00
/** Handles a drop-click in the result slot. */
void DropClickedResult(cPlayer & a_Player);
2014-07-09 12:30:06 +00:00
2015-03-21 14:18:17 +00:00
/** 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);
2016-02-05 21:45:45 +00:00
2015-03-21 14:18:17 +00:00
/** Retrieves the recipe for the specified player from the map, or creates one if not found. */
cCraftingRecipe & GetRecipeForPlayer(cPlayer & a_Player);
2015-03-21 14:18:17 +00:00
/** Called after an item has been crafted to handle statistics e.t.c. */
void HandleCraftItem(const cItem & a_Result, cPlayer & a_Player);
} ;
2020-04-13 16:38:06 +00:00
class cSlotAreaAnvil:
2014-04-30 22:47:57 +00:00
public cSlotAreaTemporary
{
2020-04-13 16:38:06 +00:00
using Super = cSlotAreaTemporary;
2014-04-30 22:47:57 +00:00
public:
2020-04-13 16:38:06 +00:00
2014-12-13 14:06:55 +00:00
cSlotAreaAnvil(cWindow & a_ParentWindow);
2014-04-30 22:47:57 +00:00
// cSlotArea overrides:
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
2014-05-04 09:11:07 +00:00
virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem) override;
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
2014-04-30 22:47:57 +00:00
// cSlotAreaTemporary overrides:
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
/** Can the player take the item from the slot? */
bool CanTakeResultItem(cPlayer & a_Player);
/** This function will call, when the player take the item from the slot. */
2014-05-04 09:11:07 +00:00
void OnTakeResult(cPlayer & a_Player);
2014-04-30 22:47:57 +00:00
/** Handles a click in the item slot. */
void UpdateResult(cPlayer & a_Player);
protected:
/** The maximum cost of repairing / renaming in the anvil. */
2014-04-30 22:47:57 +00:00
int m_MaximumCost;
/** The stack size of the second item where was used for repair */
char m_StackSizeToBeUsedInRepair;
2014-04-30 22:47:57 +00:00
} ;
2020-04-13 16:38:06 +00:00
class cSlotAreaBeacon:
2014-07-30 19:59:35 +00:00
public cSlotArea,
public cItemGrid::cListener
{
2020-04-13 16:38:06 +00:00
using Super = cSlotArea;
2016-02-05 21:45:45 +00:00
2014-07-30 19:59:35 +00:00
public:
2020-04-13 16:38:06 +00:00
2014-07-30 19:59:35 +00:00
cSlotAreaBeacon(cBeaconEntity * a_Beacon, cWindow & a_ParentWindow);
virtual ~cSlotAreaBeacon() override;
2014-07-30 19:59:35 +00:00
static bool IsPlaceableItem(short a_ItemType);
2016-02-05 21:45:45 +00:00
2014-07-30 19:59:35 +00:00
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
2014-07-30 19:59:35 +00:00
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
protected:
cBeaconEntity * m_Beacon;
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
} ;
2020-04-13 16:38:06 +00:00
class cSlotAreaEnchanting:
public cSlotAreaTemporary
{
2020-04-13 16:38:06 +00:00
using Super = cSlotAreaTemporary;
public:
2020-04-13 16:38:06 +00:00
cSlotAreaEnchanting(cWindow & a_ParentWindow, Vector3i a_BlockPos);
2014-04-15 19:10:44 +00:00
// cSlotArea overrides:
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
2014-08-27 23:21:54 +00:00
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
2014-04-15 19:10:44 +00:00
// cSlotAreaTemporary overrides:
2014-08-27 23:21:54 +00:00
virtual void OnPlayerAdded (cPlayer & a_Player) override;
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
2014-04-15 19:10:44 +00:00
/* Get the count of bookshelves who stand in the near of the enchanting table */
int GetBookshelvesCount(cWorld & a_World);
2014-04-15 19:10:44 +00:00
protected:
/** Handles a click in the item slot. */
void UpdateResult(cPlayer & a_Player);
2014-08-27 23:21:54 +00:00
Vector3i m_BlockPos;
};
class cSlotAreaChest :
public cSlotArea
{
public:
cSlotAreaChest(cChestEntity * a_Chest, cWindow & a_ParentWindow);
2016-02-05 21:45:45 +00:00
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
2016-02-05 21:45:45 +00:00
protected:
cChestEntity * m_Chest;
} ;
class cSlotAreaDoubleChest :
public cSlotArea
{
public:
cSlotAreaDoubleChest(cChestEntity * a_TopChest, cChestEntity * a_BottomChest, cWindow & a_ParentWindow);
2016-02-05 21:45:45 +00:00
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
2016-02-05 21:45:45 +00:00
protected:
cChestEntity * m_TopChest;
cChestEntity * m_BottomChest;
} ;
class cSlotAreaEnderChest :
public cSlotArea
{
public:
cSlotAreaEnderChest(cEnderChestEntity * a_EnderChest, cWindow & a_ParentWindow);
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
protected:
cEnderChestEntity * m_EnderChest;
};
2020-04-13 16:38:06 +00:00
class cSlotAreaFurnace:
public cSlotArea,
public cItemGrid::cListener
{
2020-04-13 16:38:06 +00:00
using Super = cSlotArea;
2016-02-05 21:45:45 +00:00
public:
2020-04-13 16:38:06 +00:00
cSlotAreaFurnace(cFurnaceEntity * a_Furnace, cWindow & a_ParentWindow);
2016-02-05 21:45:45 +00:00
virtual ~cSlotAreaFurnace() override;
2016-02-05 21:45:45 +00:00
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
2016-02-05 21:45:45 +00:00
protected:
cFurnaceEntity * m_Furnace;
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
2015-07-31 14:49:10 +00:00
/** Called after an item has been smelted to handle statistics etc. */
void HandleSmeltItem(const cItem & a_Result, cPlayer & a_Player);
} ;
2014-09-12 22:18:02 +00:00
2020-04-13 16:38:06 +00:00
class cSlotAreaBrewingstand:
2015-09-24 08:48:33 +00:00
public cSlotArea,
public cItemGrid::cListener
{
2020-04-13 16:38:06 +00:00
using Super = cSlotArea;
2015-09-24 08:48:33 +00:00
public:
2020-04-13 16:38:06 +00:00
2015-09-24 08:48:33 +00:00
cSlotAreaBrewingstand(cBrewingstandEntity * a_Brewingstand, cWindow & a_ParentWindow);
virtual ~cSlotAreaBrewingstand() override;
2015-09-24 08:48:33 +00:00
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
protected:
cBrewingstandEntity * m_Brewingstand;
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
/** Called after an item has been brewed to handle statistics etc. */
void HandleBrewedItem(cPlayer & a_Player, const cItem & a_ClickedItem);
2015-09-24 08:48:33 +00:00
} ;
2014-09-12 22:18:02 +00:00
class cSlotAreaMinecartWithChest :
public cSlotArea
{
public:
cSlotAreaMinecartWithChest(cMinecartWithChest * a_ChestCart, cWindow & a_ParentWindow);
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
protected:
cMinecartWithChest * m_Chest;
2014-09-13 10:14:17 +00:00
};
/** Slot area holding horse saddle and armor. */
class cSlotAreaHorse:
public cSlotArea
{
public:
enum
{
SaddleSlot,
ArmorSlot
};
cSlotAreaHorse(cHorse & a_Horse, cWindow & a_ParentWindow);
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override;
private:
cHorse & m_Horse;
};