diff --git a/dCommon/dCommonVars.h b/dCommon/dCommonVars.h index c458b9fb..77d51125 100644 --- a/dCommon/dCommonVars.h +++ b/dCommon/dCommonVars.h @@ -387,6 +387,7 @@ enum eReplicaComponentType : int32_t { COMPONENT_TYPE_PROPERTY = 36, //!< The Property Component COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39, //!< The ScriptedActivity Component COMPONENT_TYPE_PHANTOM_PHYSICS = 40, //!< The PhantomPhysics Component + COMPONENT_TYPE_MODEL = 42, //!< The Model Component COMPONENT_TYPE_PROPERTY_ENTRANCE = 43, //!< The PhantomPhysics Component COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45, //!< The PropertyManagement Component COMPONENT_TYPE_REBUILD = 48, //!< The Rebuild Component @@ -411,8 +412,6 @@ enum eReplicaComponentType : int32_t { COMPONENT_TYPE_POSSESSOR = 110, //!< The Possessor Component COMPONENT_TYPE_BUILD_BORDER = 114, //!< The Build Border Component COMPONENT_TYPE_DESTROYABLE = 1000, //!< The Destroyable Component - - COMPONENT_TYPE_MODEL = 5398484 //look man idk }; enum class UseItemResponse : uint32_t { diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index a063b3c6..c44db6f1 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -182,12 +182,18 @@ void Entity::Initialize() SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this); m_Components.insert(std::make_pair(COMPONENT_TYPE_SIMPLE_PHYSICS, comp)); - ModelComponent* modelcomp = new ModelComponent(0, this); + ModelComponent* modelcomp = new ModelComponent(this); m_Components.insert(std::make_pair(COMPONENT_TYPE_MODEL, modelcomp)); RenderComponent* render = new RenderComponent(this); m_Components.insert(std::make_pair(COMPONENT_TYPE_RENDER, render)); + auto destroyableComponent = new DestroyableComponent(this); + destroyableComponent->SetHealth(1); + destroyableComponent->SetMaxHealth(1.0f); + destroyableComponent->SetFaction(-1, true); + destroyableComponent->SetIsSmashable(true); + m_Components.insert(std::make_pair(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)); // We have all our components. return; } @@ -226,11 +232,6 @@ void Entity::Initialize() m_Components.insert(std::make_pair(COMPONENT_TYPE_RACING_STATS, nullptr)); } - PetComponent* petComponent; - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_ITEM) > 0 && !TryGetComponent(COMPONENT_TYPE_PET, petComponent)) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_ITEM, nullptr)); - } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_EXHIBIT, -1) >= 0) { m_Components.insert(std::make_pair(COMPONENT_TYPE_EXHIBIT, new LUPExhibitComponent(this))); } @@ -628,6 +629,23 @@ void Entity::Initialize() m_Components.insert(std::make_pair(COMPONENT_TYPE_SCRIPTED_ACTIVITY, new ScriptedActivityComponent(this, scriptedActivityID))); } + if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MODEL, -1) != -1 && !GetComponent()) { + m_Components.insert(std::make_pair(COMPONENT_TYPE_MODEL, new ModelComponent(this))); + if (m_Components.find(COMPONENT_TYPE_DESTROYABLE) == m_Components.end()) { + auto destroyableComponent = new DestroyableComponent(this); + destroyableComponent->SetHealth(1); + destroyableComponent->SetMaxHealth(1.0f); + destroyableComponent->SetFaction(-1, true); + destroyableComponent->SetIsSmashable(true); + m_Components.insert(std::make_pair(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)); + } + } + + PetComponent* petComponent; + if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_ITEM) > 0 && !TryGetComponent(COMPONENT_TYPE_PET, petComponent) && !HasComponent(COMPONENT_TYPE_MODEL)) { + m_Components.insert(std::make_pair(COMPONENT_TYPE_ITEM, nullptr)); + } + // Shooting gallery component if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SHOOTING_GALLERY) > 0) { m_Components.insert(std::make_pair(COMPONENT_TYPE_SHOOTING_GALLERY, new ShootingGalleryComponent(this))); @@ -876,8 +894,8 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke const auto& syncLDF = GetVar>(u"syncLDF"); - //limiting it to lot 14 right now - if (m_Settings.size() > 0 && m_TemplateID == 14) { + // Only sync for models. + if (m_Settings.size() > 0 && (GetComponent() && !GetComponent())) { outBitStream->Write1(); //ldf data RakNet::BitStream settingStream; @@ -1170,23 +1188,23 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType renderComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } + if (modelComponent) { + DestroyableComponent* destroyableComponent; + if (TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent) && !destroyableSerialized) { + destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + destroyableSerialized = true; + } + } + if (HasComponent(COMPONENT_TYPE_ZONE_CONTROL)) { outBitStream->Write(0x40000000); } // BBB Component, unused currently - // Need to to write0 so that is serlaizese correctly + // Need to to write0 so that is serialized correctly // TODO: Implement BBB Component outBitStream->Write0(); - - /* - if (m_Trigger != nullptr) - { - outBitStream->Write1(); - outBitStream->Write(m_Trigger->id); - } - */ } void Entity::ResetFlags() { diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 72194568..37d74a55 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -829,11 +829,11 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType m_Parent->Kill(owner); } -void DestroyableComponent::SetFaction(int32_t factionID) { +void DestroyableComponent::SetFaction(int32_t factionID, bool ignoreChecks) { m_FactionIDs.clear(); m_EnemyFactionIDs.clear(); - AddFaction(factionID); + AddFaction(factionID, ignoreChecks); } void DestroyableComponent::PushImmunity(int32_t stacks) diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index a1f57be4..ade3f4e8 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -282,7 +282,7 @@ public: * Sets the faction ID of this entity, overriding all previously set entries * @param factionID the faction ID to set */ - void SetFaction(int32_t factionID); + void SetFaction(int32_t factionID, bool ignoreChecks = false); /** * Returns whether or not the provided entity is an enemy of this entity diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index bb8bdfe4..65259912 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -1,42 +1,32 @@ #include "ModelComponent.h" #include "Entity.h" -ModelComponent::ModelComponent(uint32_t componentID, Entity* parent) : Component(parent) +ModelComponent::ModelComponent(Entity* parent) : Component(parent) { - m_Position = m_Parent->GetDefaultPosition(); - m_Rotation = m_Parent->GetDefaultRotation(); + m_OriginalPosition = m_Parent->GetDefaultPosition(); + m_OriginalRotation = m_Parent->GetDefaultRotation(); m_userModelID = m_Parent->GetVarAs(u"userModelID"); - - /* - for (auto set : m_Parent->GetInfo().settings) { - if (set && set->GetKey() == u"userModelID") { - m_userModelID = std::stoull(set->GetValueAsString()); - } - } - */ -} - -ModelComponent::~ModelComponent() { } void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - //item component: - outBitStream->Write1(); - outBitStream->Write(m_userModelID); - outBitStream->Write(0); - outBitStream->Write0(); + // ItemComponent Serialization. Pets do not get this serialization. + if (!m_Parent->HasComponent(COMPONENT_TYPE_PET)) { + outBitStream->Write1(); + outBitStream->Write(m_userModelID != LWOOBJID_EMPTY ? m_userModelID : m_Parent->GetObjectID()); + outBitStream->Write(0); + outBitStream->Write0(); + } //actual model component: - outBitStream->Write1(); //yes we are writing model info - outBitStream->Write0(); //?? - outBitStream->Write(2); //model type, always 2 for BBB + outBitStream->Write1(); // Yes we are writing model info + outBitStream->Write0(); // Is pickable + outBitStream->Write(2); // Physics type + outBitStream->Write(m_OriginalPosition); // Original position + outBitStream->Write(m_OriginalRotation); // Original rotation - outBitStream->Write(m_Position); - outBitStream->Write(m_Rotation); - - outBitStream->Write1(); //second data flag, all unknown. Maybe skip? - outBitStream->Write(0); - outBitStream->Write1(); - outBitStream->Write0(); + outBitStream->Write1(); // We are writing behavior info + outBitStream->Write(0); // Number of behaviors + outBitStream->Write1(); // Is this model paused + if (bIsInitialUpdate) outBitStream->Write0(); // We are not writing model editing info } diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 3b13bab8..81342059 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -12,51 +12,50 @@ class Entity; */ class ModelComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_MODEL; + static const uint32_t ComponentType = COMPONENT_TYPE_MODEL; - ModelComponent(uint32_t componentID, Entity* parent); - ~ModelComponent() override; + ModelComponent(Entity* parent); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - /** - * Returns the position of the model - * @return the position of the model - */ - NiPoint3& GetPosition() { return m_Position; } + /** + * Returns the original position of the model + * @return the original position of the model + */ + const NiPoint3& GetPosition() { return m_OriginalPosition; } - /** - * Sets the position of the model - * @param pos the position to set - */ - void SetPosition(const NiPoint3& pos) { m_Position = pos; } + /** + * Sets the original position of the model + * @param pos the original position to set + */ + void SetPosition(const NiPoint3& pos) { m_OriginalPosition = pos; } - /** - * Returns the rotation of the model - * @return the rotation of the model - */ - NiQuaternion& GetRotation() { return m_Rotation; } + /** + * Returns the original rotation of the model + * @return the original rotation of the model + */ + const NiQuaternion& GetRotation() { return m_OriginalRotation; } - /** - * Sets the rotation of the model - * @param rot the rotation to set - */ - void SetRotation(const NiQuaternion& rot) { m_Rotation = rot; } + /** + * Sets the original rotation of the model + * @param rot the original rotation to set + */ + void SetRotation(const NiQuaternion& rot) { m_OriginalRotation = rot; } private: - /** - * The position of the model - */ - NiPoint3 m_Position; + /** + * The original position of the model + */ + NiPoint3 m_OriginalPosition; - /** - * The rotation of the model - */ - NiQuaternion m_Rotation; + /** + * The rotation original of the model + */ + NiQuaternion m_OriginalRotation; - /** - * The ID of the user that made the model - */ - LWOOBJID m_userModelID; -}; \ No newline at end of file + /** + * The ID of the user that made the model + */ + LWOOBJID m_userModelID; +}; diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index f27ea283..1168209c 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -360,20 +360,17 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N if (newEntity != nullptr) { EntityManager::Instance()->ConstructEntity(newEntity); - //Make sure the propMgmt doesn't delete our model after the server dies - //Trying to do this after the entity is constructed. Shouldn't really change anything but - //There was an issue with builds not appearing since it was placed above ConstructEntity. + // Make sure the propMgmt doesn't delete our model after the server dies + // Trying to do this after the entity is constructed. Shouldn't really change anything but + // There was an issue with builds not appearing since it was placed above ConstructEntity. PropertyManagementComponent::Instance()->AddModel(newEntity->GetObjectID(), spawnerID); } item->SetCount(item->GetCount() - 1); - //item->UnEquip(); - return; } item->SetCount(item->GetCount() - 1); - //item->UnEquip(); auto* node = new SpawnerNode(); @@ -402,6 +399,17 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId); + auto ldfModelBehavior = new LDFData(u"modelBehaviors", 0); + auto userModelID = new LDFData(u"userModelID", id); + auto modelType = new LDFData(u"modelType", 2); + auto propertyObjectID = new LDFData(u"propertyObjectID", true); + auto componentWhitelist = new LDFData(u"componentWhitelist", 1); + info.nodes[0]->config.push_back(componentWhitelist); + info.nodes[0]->config.push_back(ldfModelBehavior); + info.nodes[0]->config.push_back(modelType); + info.nodes[0]->config.push_back(propertyObjectID); + info.nodes[0]->config.push_back(userModelID); + auto* model = spawner->Spawn(); models.insert_or_assign(model->GetObjectID(), spawnerId); @@ -412,8 +420,6 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS); - //item->SetCount(item->GetCount() - 1); - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity); }); // Progress place model missions @@ -669,6 +675,18 @@ void PropertyManagementComponent::Load() settings.push_back(modelType); settings.push_back(propertyObjectID); settings.push_back(userModelID); + } else { + auto modelType = new LDFData(u"modelType", 2); + auto userModelID = new LDFData(u"userModelID", id); + auto ldfModelBehavior = new LDFData(u"modelBehaviors", 0); + auto propertyObjectID = new LDFData(u"propertyObjectID", true); + auto componentWhitelist = new LDFData(u"componentWhitelist", 1); + + settings.push_back(componentWhitelist); + settings.push_back(ldfModelBehavior); + settings.push_back(modelType); + settings.push_back(propertyObjectID); + settings.push_back(userModelID); } node->config = settings; @@ -680,21 +698,6 @@ void PropertyManagementComponent::Load() auto* model = spawner->Spawn(); models.insert_or_assign(model->GetObjectID(), spawnerId); - - /* - EntityInfo info; - info.lot = lot; - info.pos = position; - info.rot = rotation; - info.settings = settings; - info.spawnerID = id; - - auto* model = EntityManager::Instance()->CreateEntity(info); - - EntityManager::Instance()->ConstructEntity(model); - - models.insert_or_assign(model->GetObjectID(), id); - */ } delete lookup;