Files
DarkflameServer/tests/dGameTests/dComponentsTests/DestroyableLevelConfigTests.cpp
Aaron Kimbrell 54cd9abd7a feat(loot): smashables use the level's smashable_loot_matrix
A level object's smashable_loot_matrix replaces the DestructibleComponent
LootMatrixIndex when smashable_loot_matrix_set is true or absent and the
matrix is not -1, as the client resolves it
(LWODestroyableComponent::LoadConfigData 0x00c44cb0). DLU only read the
key in BaseInteractDropLootServer, so tagged smashables dropped their
template's loot. Resolution in DestroyableComponent::GetLevelLootMatrix,
with tests. No wire change.

In game: smash level smashables that carry smashable_loot_matrix_set=1
(11 level objects in the 1.10.64 levels) and ones with a matrix but no _set key; they drop the
level's loot instead of the template's. Ordinary smashables
(smashable_loot_matrix_set=0) drop what they did before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 23:34:35 -05:00

77 lines
2.8 KiB
C++

#include "GameDependencies.h"
#include "DestroyableComponent.h"
#include "Entity.h"
#include <gtest/gtest.h>
// How a level object's config changes its DestroyableComponent, as the client's
// LWODestroyableComponent::LoadConfigData (0x00c44cb0) and LoadDataFromTemplate (0x00c9f900) resolve it.
class DestroyableLevelConfigTests : public GameDependenciesTest {
protected:
std::unique_ptr<Entity> entity;
void SetUp() override {
SetUpDependencies();
entity = std::make_unique<Entity>(1, info);
}
void TearDown() override {
entity.reset();
TearDownDependencies();
}
};
TEST_F(DestroyableLevelConfigTests, NoSetFactionKeepsTheTemplateFactions) {
EXPECT_FALSE(DestroyableComponent::GetLevelFactions(*entity));
entity->SetVar<bool>(u"override_faction", true);
EXPECT_FALSE(DestroyableComponent::GetLevelFactions(*entity));
}
TEST_F(DestroyableLevelConfigTests, SetFactionWithoutOverrideFactionIsUsed) {
entity->SetVar<std::string>(u"set_faction", "6 ");
EXPECT_EQ(DestroyableComponent::GetLevelFactions(*entity), std::vector<int32_t>{ 6 });
}
TEST_F(DestroyableLevelConfigTests, SetFactionWithOverrideFactionTrueIsUsed) {
entity->SetVar<std::string>(u"set_faction", "4; 6");
entity->SetVar<bool>(u"override_faction", true);
EXPECT_EQ(DestroyableComponent::GetLevelFactions(*entity), (std::vector<int32_t>{ 4, 6 }));
}
TEST_F(DestroyableLevelConfigTests, OverrideFactionFalseIgnoresSetFaction) {
entity->SetVar<std::string>(u"set_faction", "-1");
entity->SetVar<bool>(u"override_faction", false);
EXPECT_FALSE(DestroyableComponent::GetLevelFactions(*entity));
}
TEST_F(DestroyableLevelConfigTests, NoLootMatrixKeysKeepTheTemplateLootMatrix) {
EXPECT_FALSE(DestroyableComponent::GetLevelLootMatrix(*entity));
entity->SetVar<bool>(u"smashable_loot_matrix_set", true);
EXPECT_FALSE(DestroyableComponent::GetLevelLootMatrix(*entity));
}
TEST_F(DestroyableLevelConfigTests, LootMatrixWithoutTheSetKeyIsUsed) {
entity->SetVar<int32_t>(u"smashable_loot_matrix", 748);
EXPECT_EQ(DestroyableComponent::GetLevelLootMatrix(*entity), 748);
}
TEST_F(DestroyableLevelConfigTests, LootMatrixWithTheSetKeyTrueIsUsed) {
entity->SetVar<int32_t>(u"smashable_loot_matrix", 352);
entity->SetVar<bool>(u"smashable_loot_matrix_set", true);
EXPECT_EQ(DestroyableComponent::GetLevelLootMatrix(*entity), 352);
}
TEST_F(DestroyableLevelConfigTests, LootMatrixWithTheSetKeyFalseIsIgnored) {
entity->SetVar<int32_t>(u"smashable_loot_matrix", 227);
entity->SetVar<bool>(u"smashable_loot_matrix_set", false);
EXPECT_FALSE(DestroyableComponent::GetLevelLootMatrix(*entity));
}
TEST_F(DestroyableLevelConfigTests, LootMatrixMinusOneIsIgnored) {
entity->SetVar<int32_t>(u"smashable_loot_matrix", -1);
EXPECT_FALSE(DestroyableComponent::GetLevelLootMatrix(*entity));
entity->SetVar<bool>(u"smashable_loot_matrix_set", true);
EXPECT_FALSE(DestroyableComponent::GetLevelLootMatrix(*entity));
}