summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexander Harkness <me@bearbin.net>2020-04-02 14:42:15 +0200
committerGitHub <noreply@github.com>2020-04-02 14:42:15 +0200
commitcdc452916e3ec7e61f4a1ad822666192593b4b08 (patch)
treefcf35adfb6f907b7c2cd4388facc551cfe6c684a /src
parentTweak attack ranges (diff)
downloadcuberite-cdc452916e3ec7e61f4a1ad822666192593b4b08.tar
cuberite-cdc452916e3ec7e61f4a1ad822666192593b4b08.tar.gz
cuberite-cdc452916e3ec7e61f4a1ad822666192593b4b08.tar.bz2
cuberite-cdc452916e3ec7e61f4a1ad822666192593b4b08.tar.lz
cuberite-cdc452916e3ec7e61f4a1ad822666192593b4b08.tar.xz
cuberite-cdc452916e3ec7e61f4a1ad822666192593b4b08.tar.zst
cuberite-cdc452916e3ec7e61f4a1ad822666192593b4b08.zip
Diffstat (limited to 'src')
-rw-r--r--src/Blocks/BlockCauldron.h40
-rw-r--r--src/ClientHandle.cpp6
-rw-r--r--src/Entities/Player.cpp19
-rw-r--r--src/Entities/Player.h7
-rw-r--r--src/Inventory.cpp92
-rw-r--r--src/Inventory.h10
-rw-r--r--src/Items/ItemArmor.h2
-rw-r--r--src/Items/ItemBottle.h7
-rw-r--r--src/Items/ItemBucket.h32
-rw-r--r--src/Items/ItemPotion.h3
-rw-r--r--src/Mobs/Cow.cpp4
-rw-r--r--src/Mobs/Mooshroom.cpp8
12 files changed, 167 insertions, 63 deletions
diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h
index 5b45b2828..d6ef721ad 100644
--- a/src/Blocks/BlockCauldron.h
+++ b/src/Blocks/BlockCauldron.h
@@ -27,17 +27,31 @@ public:
virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
- switch (a_Player.GetEquippedItem().m_ItemType)
+ auto EquippedItem = a_Player.GetEquippedItem();
+ switch (EquippedItem.m_ItemType)
{
+ case E_ITEM_BUCKET:
+ {
+ if (Meta == 3)
+ {
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
+ // Give new bucket, filled with fluid when the gamemode is not creative:
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_WATER_BUCKET));
+ }
+ }
+ break;
+ }
case E_ITEM_WATER_BUCKET:
{
if (Meta < 3)
{
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 3);
+ // Give empty bucket back when the gamemode is not creative:
if (!a_Player.IsGameModeCreative())
{
- a_Player.GetInventory().RemoveOneEquippedItem();
- a_Player.GetInventory().AddItem(cItem(E_ITEM_BUCKET));
+ a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_BUCKET));
}
}
break;
@@ -47,11 +61,27 @@ public:
if (Meta > 0)
{
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, --Meta);
- a_Player.GetInventory().RemoveOneEquippedItem();
- a_Player.GetInventory().AddItem(cItem(E_ITEM_POTION));
+ // Give new potion when the gamemode is not creative:
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_POTION));
+ }
}
break;
}
+ case E_ITEM_POTION:
+ {
+ // Refill cauldron with water bottles.
+ if ((Meta < 3) && (EquippedItem.m_ItemDamage == 0))
+ {
+ a_ChunkInterface.SetBlockMeta(Vector3i(a_BlockX, a_BlockY, a_BlockZ), ++Meta);
+ // Give empty bottle when the gamemode is not creative:
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_GLASS_BOTTLE));
+ }
+ }
+ }
}
return true;
}
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index ef121cf12..9a92a3005 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -1211,9 +1211,9 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
cItem EquippedItem = m_Player->GetEquippedItem();
cItem OffhandItem = m_Player->GetOffHandEquipedItem();
- cInventory & Intentory = m_Player->GetInventory();
- Intentory.SetShieldSlot(EquippedItem);
- Intentory.SetHotbarSlot(Intentory.GetEquippedSlotNum(), OffhandItem);
+ cInventory & Inventory = m_Player->GetInventory();
+ Inventory.SetShieldSlot(EquippedItem);
+ Inventory.SetEquippedItem(OffhandItem);
return;
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index b5d7f7c83..02cb7378d 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1959,6 +1959,25 @@ void cPlayer::TossEquippedItem(char a_Amount)
+void cPlayer::ReplaceOneEquippedItemTossRest(const cItem & a_Item)
+{
+ auto PlacedCount = GetInventory().ReplaceOneEquippedItem(a_Item);
+ char ItemCountToToss = a_Item.m_ItemCount - static_cast<char>(PlacedCount);
+
+ if (ItemCountToToss == 0)
+ {
+ return;
+ }
+
+ cItem Pickup = a_Item;
+ Pickup.m_ItemCount = ItemCountToToss;
+ TossPickup(Pickup);
+}
+
+
+
+
+
void cPlayer::TossHeldItem(char a_Amount)
{
cItems Drops;
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index fafdd04eb..3ba87f748 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -313,6 +313,13 @@ public:
/** tosses the item in the selected hotbar slot */
void TossEquippedItem(char a_Amount = 1);
+ /** Removes one item from the the current equipped item stack, and attempts to add the specified item stack
+ back to the same slot. If it is not possible to place the item in the same slot, tries to place the specified
+ item elsewhere in the inventory. If this is not possible, then any remaining items are tossed. If the currently
+ equipped slot is empty, its contents are simply set to the given Item.
+ */
+ void ReplaceOneEquippedItemTossRest(const cItem &);
+
/** tosses the item held in hand (when in UI windows) */
void TossHeldItem(char a_Amount = 1);
diff --git a/src/Inventory.cpp b/src/Inventory.cpp
index d8b67835e..42c243f17 100644
--- a/src/Inventory.cpp
+++ b/src/Inventory.cpp
@@ -121,35 +121,38 @@ int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks)
}
}
- for (int SlotIdx = 0; SlotIdx < m_InventorySlots.GetNumSlots(); ++SlotIdx)
+ // Add to existing stacks in the hotbar.
+ res += m_HotbarSlots.AddItem(ToAdd, false);
+ ToAdd.m_ItemCount = static_cast<char>(a_Item.m_ItemCount - res);
+ if (ToAdd.m_ItemCount == 0)
{
- auto & Slot = m_InventorySlots.GetSlot(SlotIdx);
- if (Slot.IsEqual(a_Item))
- {
- cItemHandler Handler(Slot.m_ItemType);
- int AmountToAdd = std::min(static_cast<char>(Handler.GetMaxStackSize() - Slot.m_ItemCount), ToAdd.m_ItemCount);
- res += AmountToAdd;
+ return res;
+ }
- cItem SlotAdjusted(Slot);
- SlotAdjusted.m_ItemCount += AmountToAdd;
- m_InventorySlots.SetSlot(SlotIdx, SlotAdjusted);
+ // Add to existing stacks in main inventory.
+ res += m_InventorySlots.AddItem(ToAdd, false);
+ ToAdd.m_ItemCount = static_cast<char>(a_Item.m_ItemCount - res);
+ if (ToAdd.m_ItemCount == 0)
+ {
+ return res;
+ }
- ToAdd.m_ItemCount -= AmountToAdd;
- if (ToAdd.m_ItemCount == 0)
- {
- return res;
- }
- }
+ // All existing stacks are now filled.
+ if (!a_AllowNewStacks)
+ {
+ return res;
}
- res += m_HotbarSlots.AddItem(ToAdd, a_AllowNewStacks);
+ // Try adding new stacks to the hotbar.
+ res += m_HotbarSlots.AddItem(ToAdd, true);
ToAdd.m_ItemCount = static_cast<char>(a_Item.m_ItemCount - res);
if (ToAdd.m_ItemCount == 0)
{
return res;
}
- res += m_InventorySlots.AddItem(ToAdd, a_AllowNewStacks);
+ // Try adding new stacks to the main inventory.
+ res += m_InventorySlots.AddItem(ToAdd, true);
return res;
}
@@ -219,6 +222,50 @@ bool cInventory::RemoveOneEquippedItem(void)
+int cInventory::ReplaceOneEquippedItem(const cItem & a_Item, bool a_TryOtherSlots)
+{
+ // Ignore whether there was an item in the slot to remove.
+ RemoveOneEquippedItem();
+
+ auto EquippedItem = GetEquippedItem();
+ if (EquippedItem.IsEmpty())
+ {
+ SetEquippedItem(a_Item);
+ return a_Item.m_ItemCount;
+ }
+
+ // Handle case when equipped item is the same as the replacement item.
+ cItem ItemsToAdd = a_Item;
+ if (EquippedItem.IsEqual(ItemsToAdd))
+ {
+ cItemHandler Handler(ItemsToAdd.m_ItemType);
+ auto AmountToAdd = std::min(static_cast<char>(Handler.GetMaxStackSize() - EquippedItem.m_ItemCount), ItemsToAdd.m_ItemCount);
+
+ EquippedItem.m_ItemCount += AmountToAdd;
+ SetEquippedItem(EquippedItem);
+ ItemsToAdd.m_ItemCount -= AmountToAdd;
+ }
+
+ auto ItemsAdded = a_Item.m_ItemCount - ItemsToAdd.m_ItemCount;
+
+ if (ItemsToAdd.m_ItemCount == 0)
+ {
+ return ItemsAdded;
+ }
+
+ if (!a_TryOtherSlots)
+ {
+ return ItemsAdded;
+ }
+
+ // Try the rest of the inventory.
+ return AddItem(ItemsToAdd) + ItemsAdded;
+}
+
+
+
+
+
int cInventory::HowManyItems(const cItem & a_Item)
{
return
@@ -300,6 +347,15 @@ void cInventory::SetShieldSlot(const cItem & a_Item)
+void cInventory::SetEquippedItem(const cItem & a_Item)
+{
+ SetHotbarSlot(GetEquippedSlotNum(), a_Item);
+}
+
+
+
+
+
void cInventory::SendEquippedSlot()
{
int EquippedSlotNum = cInventory::invArmorCount + cInventory::invInventoryCount + GetEquippedSlotNum();
diff --git a/src/Inventory.h b/src/Inventory.h
index b91b16c8b..7436d7528 100644
--- a/src/Inventory.h
+++ b/src/Inventory.h
@@ -71,6 +71,7 @@ public:
/** Adds as many items out of a_ItemStack as can fit.
If a_AllowNewStacks is set to false, only existing stacks can be topped up;
if a_AllowNewStacks is set to true, empty slots can be used for the rest.
+ Fills existing stacks first and fills the hotbar before the main inventory.
Returns the number of items that fit.
*/
int AddItem(const cItem & a_ItemStack, bool a_AllowNewStacks = true);
@@ -90,6 +91,13 @@ public:
/** Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed */
bool RemoveOneEquippedItem(void);
+ /** Removes one item from the the current equipped item stack, and attempts to add the specified item stack
+ back to the same slot. If it is not possible to place the item in the same slot, optionally (default true) tries to
+ place the specified item elsewhere in the inventory. Returns the number of items successfully added. If the
+ currently equipped slot is empty, its contents are simply set to the given Item.
+ */
+ int ReplaceOneEquippedItem(const cItem & a_Item, bool a_TryOtherSlots = true);
+
/** Returns the number of items of type a_Item that are stored */
int HowManyItems(const cItem & a_Item);
@@ -143,6 +151,8 @@ public:
void SetHotbarSlot(int a_HotBarSlotNum, const cItem & a_Item);
/** Sets current item in shield slot */
void SetShieldSlot(const cItem & a_Item);
+ /** Sets current item in the equipped hotbar slot */
+ void SetEquippedItem(const cItem & a_Item);
/** Sets equiped item to the a_SlotNum slot number */
void SetEquippedSlotNum(int a_SlotNum);
/** Returns slot number of equiped item */
diff --git a/src/Items/ItemArmor.h b/src/Items/ItemArmor.h
index 906993a5b..d218c22b3 100644
--- a/src/Items/ItemArmor.h
+++ b/src/Items/ItemArmor.h
@@ -61,7 +61,7 @@ public:
{
Item.Empty();
}
- a_Player->GetInventory().SetHotbarSlot(a_Player->GetInventory().GetEquippedSlotNum(), Item);
+ a_Player->GetInventory().SetEquippedItem(Item);
return true;
}
diff --git a/src/Items/ItemBottle.h b/src/Items/ItemBottle.h
index b261937e5..18767dcde 100644
--- a/src/Items/ItemBottle.h
+++ b/src/Items/ItemBottle.h
@@ -83,8 +83,11 @@ public:
return false; // Nothing in range.
}
- a_Player->GetInventory().RemoveOneEquippedItem();
- a_Player->GetInventory().AddItem(cItem(E_ITEM_POTION));
+ // Give back a filled water bottle if gamemode is not creative:
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->ReplaceOneEquippedItemTossRest(cItem(E_ITEM_POTION));
+ }
return true;
}
} ;
diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h
index 7a91149d1..8affff6ca 100644
--- a/src/Items/ItemBucket.h
+++ b/src/Items/ItemBucket.h
@@ -70,15 +70,15 @@ public:
}
BLOCKTYPE Block = a_World->GetBlock(BlockPos.x, BlockPos.y, BlockPos.z);
- ENUM_ITEM_ID NewItem;
+ ENUM_ITEM_ID NewItemType;
if (IsBlockWater(Block))
{
- NewItem = E_ITEM_WATER_BUCKET;
+ NewItemType = E_ITEM_WATER_BUCKET;
}
else if (IsBlockLava(Block))
{
- NewItem = E_ITEM_LAVA_BUCKET;
+ NewItemType = E_ITEM_LAVA_BUCKET;
}
else
{
@@ -101,18 +101,7 @@ public:
// Give new bucket, filled with fluid when the gamemode is not creative:
if (!a_Player->IsGameModeCreative())
{
- // Remove the bucket from the inventory
- if (!a_Player->GetInventory().RemoveOneEquippedItem())
- {
- LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
- ASSERT(!"Inventory bucket mismatch");
- return true;
- }
- if (a_Player->GetInventory().AddItem(cItem(NewItem)) != 1)
- {
- // The bucket didn't fit, toss it as a pickup:
- a_Player->TossPickup(cItem(NewItem));
- }
+ a_Player->ReplaceOneEquippedItemTossRest(cItem(NewItemType));
}
return true;
@@ -154,19 +143,10 @@ public:
return false;
}
+ // Give back an empty bucket if the gamemode is not creative:
if (!a_Player->IsGameModeCreative())
{
- // Remove fluid bucket, add empty bucket:
- if (!a_Player->GetInventory().RemoveOneEquippedItem())
- {
- LOG("Clicked with a full bucket, but cannot remove one from the inventory? WTF?");
- ASSERT(!"Inventory bucket mismatch");
- return false;
- }
- if (!a_Player->GetInventory().AddItem(cItem(E_ITEM_BUCKET)))
- {
- return false;
- }
+ a_Player->ReplaceOneEquippedItemTossRest(cItem(E_ITEM_BUCKET));
}
// Wash away anything that was there prior to placing:
diff --git a/src/Items/ItemPotion.h b/src/Items/ItemPotion.h
index 470a7c67f..86330d1c0 100644
--- a/src/Items/ItemPotion.h
+++ b/src/Items/ItemPotion.h
@@ -77,8 +77,7 @@ public:
if (!a_Player->IsGameModeCreative())
{
- a_Player->GetInventory().RemoveOneEquippedItem();
- a_Player->GetInventory().AddItem(cItem(E_ITEM_GLASS_BOTTLE));
+ a_Player->ReplaceOneEquippedItemTossRest(cItem(E_ITEM_GLASS_BOTTLE));
}
return true;
}
diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp
index a7fb0d476..559b6caea 100644
--- a/src/Mobs/Cow.cpp
+++ b/src/Mobs/Cow.cpp
@@ -44,10 +44,10 @@ void cCow::OnRightClicked(cPlayer & a_Player)
short HeldItem = a_Player.GetEquippedItem().m_ItemType;
if (HeldItem == E_ITEM_BUCKET)
{
+ // Milk the cow.
if (!a_Player.IsGameModeCreative())
{
- a_Player.GetInventory().RemoveOneEquippedItem();
- a_Player.GetInventory().AddItem(cItem(E_ITEM_MILK));
+ a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_MILK));
}
}
}
diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp
index 31a1b8978..135a8ba90 100644
--- a/src/Mobs/Mooshroom.cpp
+++ b/src/Mobs/Mooshroom.cpp
@@ -43,18 +43,18 @@ void cMooshroom::OnRightClicked(cPlayer & a_Player)
{
case E_ITEM_BUCKET:
{
+ // Milk the cow.
if (!a_Player.IsGameModeCreative())
{
- a_Player.GetInventory().RemoveOneEquippedItem();
- a_Player.GetInventory().AddItem(cItem(E_ITEM_MILK));
+ a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_MILK));
}
} break;
case E_ITEM_BOWL:
{
+ // Soup the cow.
if (!a_Player.IsGameModeCreative())
{
- a_Player.GetInventory().RemoveOneEquippedItem();
- a_Player.GetInventory().AddItem(cItem(E_ITEM_MUSHROOM_SOUP));
+ a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_MUSHROOM_SOUP));
}
} break;
case E_ITEM_SHEARS: