Files
DarkflameServer/tests/dGameTests/dComponentsTests/UseItemResultTests.cpp
Aaron Kimbrell 4fbebf7135 fix(inventory): an opened package reports success in UseItemResult, as live
Item::UseNonEquip declared a second `success` inside the package branch, so
the UseItemResult it sent (and its log line) was always false, even when the
package opened and its contents were given. The client
(LWOInventoryComponent_Client::sub_00c1bb20 (0x00c1bb20)) plays the item's
audioEventUse on true and a failure sound on false; live sent true for 183
of the 187 UseItemResult in the captures.

Test: UseItemResultTests.AnOpenedPackageReportsSuccess.

Check in game: opening a package (e.g. a starter pack or a reward bag) plays
its open sound rather than the failure sound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:47:24 -05:00

68 lines
2.8 KiB
C++

#include "GameDependencies.h"
#include "CDClientManager.h"
#include "CDComponentsRegistryTable.h"
#include "CDItemComponentTable.h"
#include "CDLootMatrixTable.h"
#include "CDPackageComponentTable.h"
#include "Entity.h"
#include "InventoryComponent.h"
#include "InventoryMessages.h"
#include "Item.h"
#include "eReplicaComponentType.h"
#include "dGameMessagesTests/GameMessageTestUtils.h"
#include <gtest/gtest.h>
using namespace GameMessageTestUtils;
// Opening a package: the client plays the item's use sound on a successful UseItemResult and a failure sound
// otherwise; live sent true for packages that opened (183 of the 187 in the captures).
class UseItemResultTests : public GameDependenciesTest {
protected:
static constexpr LOT PACKAGE = 2998;
static constexpr uint32_t PACKAGE_COMPONENT = 97000;
static constexpr uint32_t LOOT_MATRIX = 97001;
std::unique_ptr<Entity> entity;
InventoryComponent* inventoryComponent{};
void SetUp() override {
SetUpDependencies();
const auto itemComponent = static_cast<uint32_t>(96000 + PACKAGE);
auto& registry = CDClientManager::GetEntriesMutable<CDComponentsRegistryTable>();
registry.insert_or_assign(static_cast<uint64_t>(info.lot), 0);
registry.insert_or_assign(static_cast<uint64_t>(PACKAGE), itemComponent);
registry.insert_or_assign(static_cast<uint64_t>(eReplicaComponentType::ITEM) << 32 | static_cast<uint64_t>(PACKAGE), itemComponent);
registry.insert_or_assign(static_cast<uint64_t>(eReplicaComponentType::PACKAGE) << 32 | static_cast<uint64_t>(PACKAGE), PACKAGE_COMPONENT);
CDItemComponent component{};
component.id = itemComponent;
CDClientManager::GetEntriesMutable<CDItemComponentTable>().insert_or_assign(itemComponent, component);
CDClientManager::GetEntriesMutable<CDPackageComponentTable>().push_back({ PACKAGE_COMPONENT, LOOT_MATRIX, 0 });
CDClientManager::GetEntriesMutable<CDLootMatrixTable>()[LOOT_MATRIX] = {}; // an empty package
entity = std::make_unique<Entity>(1, info);
inventoryComponent = entity->AddComponent<InventoryComponent>(-1);
}
void TearDown() override {
entity.reset();
CDClientManager::GetEntriesMutable<CDPackageComponentTable>().clear();
CDClientManager::GetEntriesMutable<CDLootMatrixTable>().erase(LOOT_MATRIX);
TearDownDependencies();
}
};
TEST_F(UseItemResultTests, AnOpenedPackageReportsSuccess) {
auto* const items = inventoryComponent->GetInventory(eInventoryType::ITEMS);
auto* const package = new Item(0x7000, PACKAGE, items, 0, 2, false, {}, LWOOBJID_EMPTY, LWOOBJID_EMPTY, eLootSourceType::NONE);
const auto results = SentGameMessages<GameMessages::UseItemResult>(Capture([&] { package->UseNonEquip(package); }));
ASSERT_EQ(results.size(), 1u);
EXPECT_EQ(results[0].itemTemplateID, PACKAGE);
EXPECT_TRUE(results[0].useItemResult);
EXPECT_EQ(package->GetCount(), 1u);
}