diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 26b1bb3c..37aeb093 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5763,11 +5763,7 @@ void GameMessages::HandleUseNonEquipmentItem(RakNet::BitStream* inStream, Entity auto* item = inv->FindItemById(itemConsumed); - if (item == nullptr) { - return; - } - - item->UseNonEquip(); + if (item) item->UseNonEquip(item); } void GameMessages::HandleMatchRequest(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 778d8237..a3d4cfc0 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -262,7 +262,7 @@ bool Item::Consume() { return success; } -void Item::UseNonEquip() { +void Item::UseNonEquip(Item* item) { LOT thisLot = this->GetLot(); if (!GetInventory()) { Game::logger->LogDebug("Item", "item %i has no inventory??", this->GetLot()); @@ -292,45 +292,49 @@ void Item::UseNonEquip() { } // This precondition response is taken care of in SpawnPet(). } else { - auto* compRegistryTable = CDClientManager::Instance()->GetTable("ComponentsRegistry"); - const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_PACKAGE); + bool success = false; + auto inventory = item->GetInventory(); + if (inventory && inventory->GetType() == eInventoryType::ITEMS) { + auto* compRegistryTable = CDClientManager::Instance()->GetTable("ComponentsRegistry"); + const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_PACKAGE); - if (packageComponentId == 0) return; + if (packageComponentId == 0) return; - auto* packCompTable = CDClientManager::Instance()->GetTable("PackageComponent"); - auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast(packageComponentId); }); + auto* packCompTable = CDClientManager::Instance()->GetTable("PackageComponent"); + auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast(packageComponentId); }); - auto success = !packages.empty(); - if (success) { - if (this->GetPreconditionExpression()->Check(playerInventoryComponent->GetParent())) { - auto* entityParent = playerInventoryComponent->GetParent(); - // Roll the loot for all the packages then see if it all fits. If it fits, give it to the player, otherwise don't. - std::unordered_map rolledLoot{}; - for (auto& pack : packages) { - auto thisPackage = LootGenerator::Instance().RollLootMatrix(entityParent, pack.LootMatrixIndex); - for (auto& loot : thisPackage) { - // If we already rolled this lot, add it to the existing one, otherwise create a new entry. - auto existingLoot = rolledLoot.find(loot.first); - if (existingLoot == rolledLoot.end()) { - rolledLoot.insert(loot); - } else { - existingLoot->second += loot.second; + auto success = !packages.empty(); + if (success) { + if (this->GetPreconditionExpression()->Check(playerInventoryComponent->GetParent())) { + auto* entityParent = playerInventoryComponent->GetParent(); + // Roll the loot for all the packages then see if it all fits. If it fits, give it to the player, otherwise don't. + std::unordered_map rolledLoot{}; + for (auto& pack : packages) { + auto thisPackage = LootGenerator::Instance().RollLootMatrix(entityParent, pack.LootMatrixIndex); + for (auto& loot : thisPackage) { + // If we already rolled this lot, add it to the existing one, otherwise create a new entry. + auto existingLoot = rolledLoot.find(loot.first); + if (existingLoot == rolledLoot.end()) { + rolledLoot.insert(loot); + } else { + existingLoot->second += loot.second; + } } } - } - if (playerInventoryComponent->HasSpaceForLoot(rolledLoot)) { - LootGenerator::Instance().GiveLoot(playerInventoryComponent->GetParent(), rolledLoot, eLootSourceType::LOOT_SOURCE_CONSUMPTION); - playerInventoryComponent->RemoveItem(lot, 1); + if (playerInventoryComponent->HasSpaceForLoot(rolledLoot)) { + LootGenerator::Instance().GiveLoot(playerInventoryComponent->GetParent(), rolledLoot, eLootSourceType::LOOT_SOURCE_CONSUMPTION); + item->SetCount(item->GetCount() - 1); + } else { + success = false; + } } else { + GameMessages::SendUseItemRequirementsResponse( + playerInventoryComponent->GetParent()->GetObjectID(), + playerInventoryComponent->GetParent()->GetSystemAddress(), + UseItemResponse::FailedPrecondition + ); success = false; } - } else { - GameMessages::SendUseItemRequirementsResponse( - playerInventoryComponent->GetParent()->GetObjectID(), - playerInventoryComponent->GetParent()->GetSystemAddress(), - UseItemResponse::FailedPrecondition - ); - success = false; } } Game::logger->LogDebug("Item", "Player %llu %s used item %i", playerEntity->GetObjectID(), success ? "successfully" : "unsuccessfully", thisLot); diff --git a/dGame/dInventory/Item.h b/dGame/dInventory/Item.h index bb8316d7..6993a0ba 100644 --- a/dGame/dInventory/Item.h +++ b/dGame/dInventory/Item.h @@ -195,7 +195,7 @@ public: /** * Uses this item if its non equip, essentially an interface for the linked GM */ - void UseNonEquip(); + void UseNonEquip(Item* item); /** * Disassembles the part LOTs of this item back into the inventory, if it has any