diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 132a0eb7..16b2f0af 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -79,6 +79,7 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) m_Components = {}; m_DieCallbacks = {}; m_PhantomCollisionCallbacks = {}; + m_IsParentChildDirty = true; m_Settings = info.settings; m_NetworkSettings = info.networkSettings; @@ -561,19 +562,6 @@ void Entity::Initialize() comp->SetPostImaginationCost(rebCompData[0].post_imagination_cost); comp->SetTimeBeforeSmash(rebCompData[0].time_before_smash); - const auto rebuildActivatorValue = GetVarAsString(u"rebuild_activators"); - - if (!rebuildActivatorValue.empty()) { - std::vector split = GeneralUtils::SplitString(rebuildActivatorValue, 0x1f); - NiPoint3 pos; - - pos.x = std::stof(split[0]); - pos.y = std::stof(split[1]); - pos.z = std::stof(split[2]); - - comp->SetActivatorPosition(pos); - } - const auto rebuildResetTime = GetVar(u"rebuild_reset_time"); if (rebuildResetTime != 0.0f) { @@ -974,8 +962,11 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke } else outBitStream->Write0(); //No GM Level } - outBitStream->Write((m_ParentEntity != nullptr || m_ChildEntities.size() > 0)); - if (m_ParentEntity || m_ChildEntities.size() > 0) { + + // Only serialize parent / child info should the info be dirty (changed) or if this is the construction of the entity. + outBitStream->Write(m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION); + if (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION) { + m_IsParentChildDirty = false; outBitStream->Write(m_ParentEntity != nullptr); if (m_ParentEntity) { outBitStream->Write(m_ParentEntity->GetObjectID()); @@ -1661,6 +1652,7 @@ void Entity::RegisterCoinDrop(uint64_t count) { } void Entity::AddChild(Entity* child) { + m_IsParentChildDirty = true; m_ChildEntities.push_back(child); } diff --git a/dGame/Entity.h b/dGame/Entity.h index cef7b97f..f2bc4237 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -322,6 +322,8 @@ protected: int8_t m_Observers = 0; + bool m_IsParentChildDirty = true; + /* * Collision */ diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index abee5e16..5e313a7a 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -22,6 +22,20 @@ RebuildComponent::RebuildComponent(Entity* entity) : Component(entity) { { m_Precondition = new PreconditionExpression(GeneralUtils::UTF16ToWTF8(checkPreconditions)); } + + // Should a setting that has the build activator position exist, fetch that setting here and parse it for position. + // It is assumed that the user who sets this setting uses the correct character delimiter (character 31 or in hex 0x1F) + auto positionAsVector = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rebuild_activators"), 0x1F); + if (positionAsVector.size() == 3 && + GeneralUtils::TryParse(positionAsVector[0], m_ActivatorPosition.x) && + GeneralUtils::TryParse(positionAsVector[1], m_ActivatorPosition.y) && + GeneralUtils::TryParse(positionAsVector[2], m_ActivatorPosition.z)) { + } else { + Game::logger->Log("RebuildComponent", "Failed to find activator position for lot %i. Defaulting to parents position.\n", m_Parent->GetLOT()); + m_ActivatorPosition = m_Parent->GetPosition(); + } + + SpawnActivator(); } RebuildComponent::~RebuildComponent() {