Entity: Add missing destroyable case (#1228)

Adds a missing edge case on the client where you may have the is_smashable flag set, but dont actually have a destroyable component.  In this case you should create only a destroyable component and add it to the component and serialize it last after all other data.  We also needed to add the set_faction var reading and setting as this is how Oliver Sudden actually gets their faction since they have no actual information in the database, it is all stored in ldf keys.

Tested that Oliver Sudden no longer logs Unable to unserialize logs when serialized or constructed.
This commit is contained in:
David Markowitz 2023-10-19 10:42:43 -07:00 committed by GitHub
parent 4c507e34a5
commit 131239538b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -345,7 +345,7 @@ void Entity::Initialize() {
int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF);
int rebuildComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD);
int componentID = 0;
int componentID = -1;
if (collectibleComponentID > 0) componentID = collectibleComponentID;
if (rebuildComponentID > 0) componentID = rebuildComponentID;
if (buffComponentID > 0) componentID = buffComponentID;
@ -353,7 +353,8 @@ void Entity::Initialize() {
CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable<CDDestructibleComponentTable>();
std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); });
if (buffComponentID > 0 || collectibleComponentID > 0) {
bool isSmashable = GetVarAs<int32_t>(u"is_smashable") != 0;
if (buffComponentID > 0 || collectibleComponentID > 0 || isSmashable) {
DestroyableComponent* comp = new DestroyableComponent(this);
if (m_Character) {
comp->LoadFromXml(m_Character->GetXMLDoc());
@ -394,7 +395,7 @@ void Entity::Initialize() {
}
// extraInfo overrides. Client ORs the database smashable and the luz smashable.
comp->SetIsSmashable(comp->GetIsSmashable() | (GetVarAs<int32_t>(u"is_smashable") != 0));
comp->SetIsSmashable(comp->GetIsSmashable() | isSmashable);
}
} else {
comp->SetHealth(1);
@ -427,6 +428,19 @@ void Entity::Initialize() {
}
}
// override the factions if needed.
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.
std::vector<std::string> factionsToAdd = GeneralUtils::SplitString(setFaction, ';');
int32_t factionToAdd;
for (const auto faction : factionsToAdd) {
if (GeneralUtils::TryParse(faction, factionToAdd)) {
comp->AddFaction(factionToAdd, true);
}
}
}
m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, comp));
}
@ -1223,7 +1237,7 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
renderComponent->Serialize(outBitStream, bIsInitialUpdate);
}
if (modelComponent) {
if (modelComponent || !destroyableSerialized) {
DestroyableComponent* destroyableComponent;
if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) {
destroyableComponent->Serialize(outBitStream, bIsInitialUpdate);