From cdc452916e3ec7e61f4a1ad822666192593b4b08 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Thu, 2 Apr 2020 12:42:15 +0000 Subject: Replace buckets to the selected hotbar slot, rather than the first available. (#4580) * Replace buckets to the selected hotbar slot, rather than the first available. Replicates vanilla behaviour, as well as being more logical. * Refactor cInventory::AddItem. Behaviour is now documented * Add new cInventory::ReplaceOneEquippedItem and ::SetEquippedItem methods * Return empty potion to the same slot after drinking * Replace buckets correctly in other situations, not simply water and lava Uses the new ReplaceOneEquippedItem method * Correct collecting water from source block with bottle * Add cPlayer::ReplaceOneEquippedItemTossRest method * Handle stacked filled buckets (in theory) Use new cPlayer::ReplaceOneEquippedItemTossRest method --- src/Inventory.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 18 deletions(-) (limited to 'src/Inventory.cpp') 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(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(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(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(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(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(); -- cgit v1.2.3