diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 5d4da1bcd..ce573824b 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -474,24 +474,26 @@ void Entity::Initialize() { const auto tokenInt = GeneralUtils::TryParse(token); if (tokenInt == destCompData[0].faction) continue; - if (!token.empty()) { - comp->AddFaction(std::stoi(token)); - } + if (tokenInt) comp->AddFaction(tokenInt.value()); } } - // override the factions if needed. + // Level files can replace the factions with set_faction. The client splits the value on + // both ';' and ' ' and replaces its faction list with the result + // (LWODestroyableComponent::LoadConfigData), and many values have a trailing space ("13:6 "). const auto setFaction = GetVarAsString(u"set_faction"); - if (!setFaction.empty()) { - // TODO also split on space here however we do not have a general util for splitting on multiple characters yet. - const auto factionsToAdd = GeneralUtils::SplitString(setFaction, ';'); - for (const auto& faction : factionsToAdd) { + std::vector factionsToSet; + for (const auto& semicolonSplit : GeneralUtils::SplitString(setFaction, ';')) { + for (const auto& faction : GeneralUtils::SplitString(semicolonSplit, ' ')) { const auto factionToAdd = GeneralUtils::TryParse(faction); - if (factionToAdd) { - comp->AddFaction(factionToAdd.value(), true); - } + if (factionToAdd) factionsToSet.push_back(factionToAdd.value()); } } + + if (!factionsToSet.empty()) { + comp->SetFaction(factionsToSet.front(), true); + for (const auto faction : factionsToSet | std::views::drop(1)) comp->AddFaction(faction, true); + } } const auto characterID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CHARACTER);