fix(destroyable): take template factions from factionList, keeping -1

The client reads an object's factions only from the DestructibleComponent
factionList (LWODestroyableComponent::LoadDataFromTemplate 0x00c9f900: one
atol per comma-separated token, -1 kept; the faction column is not read),
and live replicated that list: [-1] on 12,829 constructions (vendors,
quickbuilds, bouncers). DLU added the faction column and dropped -1,
so those objects were sent with no factions, and the four rows with faction 6
but factionList "-1" were sent as [6].

-1 has no Factions row, so it adds no friends or enemies.

Test: ReplicaConstructionTest.TemplateFactionMinusOneIsReplicated.

Check in game: vendors, quickbuilds, bouncers and NPCs still can't be
attacked; enemies still fight players and pets; smashables still smash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 05:25:40 -05:00
parent c711eb8045
commit 545db47a40
4 changed files with 43 additions and 12 deletions

View File

@@ -475,18 +475,7 @@ void Entity::Initialize() {
}
}
if (!destCompData.empty()) {
comp->AddFaction(destCompData[0].faction);
std::stringstream ss(destCompData[0].factionList);
std::string token;
while (std::getline(ss, token, ',')) {
const auto tokenInt = GeneralUtils::TryParse<int32_t>(token);
if (tokenInt == destCompData[0].faction) continue;
if (tokenInt) comp->AddFaction(tokenInt.value());
}
}
if (!destCompData.empty()) comp->AddTemplateFactions(destCompData[0].factionList);
// Level files can replace the factions with set_faction, unless override_faction is 0
const auto levelFactions = DestroyableComponent::GetLevelFactions(*this);