diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 04390052..e6670206 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1,6 +1,7 @@ #include "InventoryComponent.h" #include +#include #include "Entity.h" #include "Item.h" @@ -194,7 +195,12 @@ void InventoryComponent::AddItem( auto* inventory = GetInventory(inventoryType); + if (!config.empty() || bound) { + if (inventoryType == eInventoryType::VENDOR_BUYBACK && buybackItems.size() >= 27) { + RemoveItem(buybackItems.back()); + buybackItems.pop_back(); + } const auto slot = preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot) ? preferredSlot : inventory->FindEmptySlot(); if (slot == -1) { @@ -202,10 +208,8 @@ void InventoryComponent::AddItem( } auto* item = new Item(lot, inventory, slot, count, config, parent, showFlyingLoot, isModMoveAndEquip, subKey, bound, lootSourceType); - - // Check if inventory type is VENDOR_BUYBACK and manage the inventory size - if (inventoryType == eInventoryType::VENDOR_BUYBACK) { - ManageVendorBuybackInventory(item->GetId(), inventory); + if (inventoryType == eInventoryType::VENDOR_BUYBACK && buybackItems.size() <= 27) { + buybackItems.push_front(item->GetId()); } if (missions != nullptr && !IsTransferInventory(inventoryType)) { @@ -250,6 +254,11 @@ void InventoryComponent::AddItem( const auto size = std::min(left, stack); left -= size; + if (inventoryType == eInventoryType::VENDOR_BUYBACK && buybackItems.size() >= 27) { + RemoveItem(buybackItems.back()); + buybackItems.pop_back(); + } + int32_t slot; if (preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot)) { slot = preferredSlot; @@ -280,10 +289,8 @@ void InventoryComponent::AddItem( } auto* item = new Item(lot, inventory, slot, size, {}, parent, showFlyingLoot, isModMoveAndEquip, subKey, false, lootSourceType); - - // Check if inventory type is VENDOR_BUYBACK and manage the inventory size - if (inventoryType == eInventoryType::VENDOR_BUYBACK) { - ManageVendorBuybackInventory(item->GetId(), inventory); + if (inventoryType == eInventoryType::VENDOR_BUYBACK && buybackItems.size() <= 27) { + buybackItems.push_front(item->GetId()); } isModMoveAndEquip = false; @@ -325,6 +332,9 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in } auto* origin = item->GetInventory(); + if (origin->GetType() == eInventoryType::VENDOR_BUYBACK) { + buybackItems.erase(std::ranges::find(buybackItems, item->GetId())); + } const auto lot = item->GetLot(); @@ -366,6 +376,16 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in item->SetCount(item->GetCount() - delta, false, false); } + + // if (origin->GetType() == eInventoryType::VENDOR_BUYBACK) { + // auto& items = origin->GetItems(); + // int32_t slotItr = 0; + // for (auto* item : items | std::views::values) { + // GameMessages::SendMoveItemInInventory(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), inventory, item->GetId(), origin->GetType(), 0, slotItr); + // item->SetSlot(slotItr); + // slotItr++; + // } + // } auto* missionComponent = m_Parent->GetComponent(); if (missionComponent != nullptr) { @@ -1606,26 +1626,7 @@ bool InventoryComponent::SetSkill(BehaviorSlot slot, uint32_t skillId) { return true; } -void InventoryComponent::ManageVendorBuybackInventory(LWOOBJID newItem, Inventory* inventory) { - const size_t maxVendorBuybackItems = 27; - - if (buybackItems.size() == 26) { - LWOOBJID oldestItemId = buybackItems.front(); - buybackItems.pop(); - - RemoveItem(oldestItemId, inventory->GetType()); - } - if (buybackItems.size() >= maxVendorBuybackItems) { - LWOOBJID oldestItemId = buybackItems.front(); - buybackItems.pop(); - - RemoveItem(oldestItemId, inventory->GetType()); - } - - buybackItems.push(newItem); -} - -void InventoryComponent::RemoveItem(LWOOBJID itemId, eInventoryType inventoryType) { +void InventoryComponent::RemoveItem(LWOOBJID itemId) { auto* item = FindItemById(itemId); if (item) { item->SetCount(0); diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index 7b5cd4ab..94b7be0d 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -372,21 +372,12 @@ public: bool SetSkill(int slot, uint32_t skillId); bool SetSkill(BehaviorSlot slot, uint32_t skillId); - /** - * Called during AddItem to manage the vendor buyback inventory if the inventory is of that type - * - * @param newItem The item ID which is being moved to the vendor buyback inventory - * @param inventory The entity/vendor's inventory - */ - void ManageVendorBuybackInventory(LWOOBJID newItem, Inventory* inventory); - /** * Called in ManageVendorBuybackInventory to remove an item given the ItemId * * @param itemId item ID for item being removed - * @param inventoryType inventory type */ - void RemoveItem(LWOOBJID itemId, eInventoryType inventoryType); + void RemoveItem(LWOOBJID itemId); ~InventoryComponent() override; @@ -398,7 +389,7 @@ private: /** *A queue of LWOOBJIDs representing the buybackItems which are sold to a vendor */ - std::queue buybackItems; + std::deque buybackItems; /** * The skills that this entity currently has active */ diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 1f757d7e..12a558b5 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -980,7 +980,7 @@ void GameMessages::SendResurrect(Entity* entity) { destroyableComponent->SetImagination(imaginationToRestore); } } - }); + }); CBITSTREAM; CMSGHEADER; @@ -5110,12 +5110,12 @@ void GameMessages::HandleMissionDialogOK(RakNet::BitStream& inStream, Entity* en } if (Game::config->GetValue("allow_players_to_skip_cinematics") != "1" - || !player->GetCharacter() - || !player->GetCharacter()->GetPlayerFlag(ePlayerFlag::DLU_SKIP_CINEMATICS)) return; + || !player->GetCharacter() + || !player->GetCharacter()->GetPlayerFlag(ePlayerFlag::DLU_SKIP_CINEMATICS)) return; player->AddCallbackTimer(0.5f, [player]() { if (!player) return; GameMessages::SendEndCinematic(player->GetObjectID(), u"", player->GetSystemAddress()); - }); + }); } void GameMessages::HandleRequestLinkedMission(RakNet::BitStream& inStream, Entity* entity) { @@ -6210,3 +6210,27 @@ void GameMessages::SendSlashCommandFeedbackText(Entity* entity, std::u16string t auto sysAddr = entity->GetSystemAddress(); SEND_PACKET; } + +void GameMessages::SendMoveItemInInventory( + const LWOOBJID objectId, + const SystemAddress& sysAddr, + eInventoryType destination, + const LWOOBJID item, + const eInventoryType source, + const int32_t responseCode, + const int32_t slot) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(eGameMessageType::MOVE_ITEM_IN_INVENTORY); + + bitStream.Write(destination != eInventoryType::INVALID); + if (destination != eInventoryType::INVALID) bitStream.Write(destination); + bitStream.Write(item); + bitStream.Write(source); + bitStream.Write(responseCode); + bitStream.Write(slot); + + SEND_PACKET; +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index b842710e..efab2f45 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -666,6 +666,16 @@ namespace GameMessages { void HandleCancelDonationOnPlayer(RakNet::BitStream& inStream, Entity* entity); void SendSlashCommandFeedbackText(Entity* entity, std::u16string text); + + void SendMoveItemInInventory( + const LWOOBJID objectId, + const SystemAddress& sysAddr, + eInventoryType destination, + const LWOOBJID item, + const eInventoryType source, + const int32_t responseCode, + const int32_t slot + ); }; #endif // GAMEMESSAGES_H diff --git a/dGame/dInventory/Inventory.cpp b/dGame/dInventory/Inventory.cpp index 35222bea..465d84fd 100644 --- a/dGame/dInventory/Inventory.cpp +++ b/dGame/dInventory/Inventory.cpp @@ -82,13 +82,11 @@ void Inventory::SetSize(const uint32_t value) { int32_t Inventory::FindEmptySlot() { if (free <= 6) // Up from 1 { - if (type != ITEMS && type != VAULT_ITEMS && type != eInventoryType::VAULT_MODELS) { + if (type != ITEMS && type != VAULT_ITEMS && type != eInventoryType::VAULT_MODELS && type != eInventoryType::VENDOR_BUYBACK) { uint32_t newSize = size; if (type == MODELS) { newSize = 240; - } else if (type == eInventoryType::VENDOR_BUYBACK) { - newSize += 9u; } else { newSize += 10u; }