diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 08360380..05461ba8 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -86,7 +86,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare m_TimerAway = 0; m_TimerBounce = 0; m_DatabaseId = LWOOBJID_EMPTY; - m_Flags = 1 << PetFlag::TAMEABLE; // Tameable + m_Flags = PetFlag::TAMEABLE; // Tameable m_Ability = ePetAbilityType::Invalid; m_StartPosition = m_Parent->GetPosition(); //NiPoint3::ZERO; m_MovementAI = nullptr; @@ -720,7 +720,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { currentActivities.erase(m_Tamer); - SetStatus(1 << PetFlag::TAMEABLE); + SetStatus(PetFlag::TAMEABLE); m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; @@ -771,7 +771,7 @@ void PetComponent::ClientFailTamingMinigame() { currentActivities.erase(m_Tamer); - SetStatus(1 << PetFlag::TAMEABLE); + SetStatus(PetFlag::TAMEABLE); m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; @@ -836,7 +836,7 @@ void PetComponent::OnSpawn() { m_Parent->SetOwnerOverride(m_Owner); m_MovementAI->SetMaxSpeed(m_SprintSpeed); m_MovementAI->SetHaltDistance(m_FollowRadius); - SetStatus(1 << PetFlag::NONE); + SetStatus(PetFlag::NONE); SetPetAiState(PetAiState::follow); } else { @@ -947,7 +947,7 @@ void PetComponent::StopInteract() { SetInteractType(PetInteractType::none); SetAbility(petAbility); SetPetAiState(PetAiState::follow); - SetStatus(1 << PetFlag::NONE); + SetStatus(PetFlag::NONE); SetIsReadyToInteract(false); SetIsHandlingInteraction(false); // Needed? m_MovementAI->SetMaxSpeed(m_SprintSpeed); @@ -977,7 +977,7 @@ void PetComponent::SetupInteractTreasureDig() { auto petAbility = ePetAbilityType::DigAtPosition; SetAbility(petAbility); - SetStatus(1 << PetFlag::NOT_WAITING); // TODO: Double-check this is the right flag being set + SetStatus(PetFlag::NOT_WAITING); // TODO: Double-check this is the right flag being set Game::entityManager->SerializeEntity(m_Parent); // TODO: Double-check pet packet captures const auto sysAddr = owner->GetSystemAddress(); @@ -1054,7 +1054,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { // auto* owner = GetOwner(); if (owner == nullptr) return; - SetStatus(1 << PetFlag::SPAWNING); + SetFlag(SPAWNING); //SetStatus(PetFlag::SPAWNING); auto databaseData = inventoryComponent->GetDatabasePet(m_DatabaseId); diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index bb36b924..32e6034f 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -34,23 +34,15 @@ enum PetInteractType : uint8_t { */ enum PetFlag : uint32_t { NONE, - BEING_TAMED = 4, - NOT_WAITING = 5, - SPAWNING = 7, - TAMEABLE = 8 + BEING_TAMED = 1 << 4, //0x10, + NOT_WAITING = 1 << 5, //0x20, + SPAWNING = 1 << 7, //0x80 + TAMEABLE = 1 << 26 //0x4000000 }; -/* -* DEPRECATED The status of the pet: Governs the icon above their head and the interactions available +/** + * The pet emote animation ids that can used in PetComponent::Command() */ -/*enum PetStatus : uint32_t { - NONE, - BEING_TAMED = 1 << 4, //PetFlag::BEING_TAMED, //0x10, - IS_NOT_WAITING = 1 << 5, //PetFlag::NOT_WAITING, //0x20, - PLAY_SPAWN_ANIM = 1 << 7, //PetFlag::PLAY_SPAWN_ANIM, //0x80, - TAMEABLE = 1 << 8 // PetFlag::TAMEABLE //0x4000000 -};*/ - enum PetEmote : int32_t { ActivateSwitch = 201, DigTreasure, @@ -93,36 +85,43 @@ public: /** * Sets one or more pet flags + * @param flag PetFlag(s) to set */ template - void SetFlag(varArg... flag) { - const auto initFlags = m_Flags; - m_Flags |= (static_cast(1 << flag) | ...); - LOG_DEBUG("SetFlag: %d + %d = %d", initFlags, 1 << (flag | ...), m_Flags); - } + void SetFlag(varArg... flag) { m_Flags |= (static_cast(flag) | ...); } + + /** + * Sets the pet to ONLY have the specified flag(s), clearing all others + * @param flag PetFlag(s) to set exclusively + */ + template + void SetOnlyFlag(varArg... flag) { m_Flags = (static_cast(flag) | ...); } /** * Unsets one or more pet flags + * @param flag PetFlag(s) to unset */ template - void UnsetFlag(varArg... flag) { - const auto initFlags = m_Flags; - m_Flags &= ~(static_cast(1 << flag) | ...); - LOG_DEBUG("UnsetFlag: %d - %d = %d", initFlags, 1 << (flag | ...), m_Flags); - } // THIS IS PROBLEMATIC + void UnsetFlag(varArg... flag) { m_Flags &= ~(static_cast(flag) | ...); } /** - * Gets one or more pet flags + * Returns true if the pet has all the specified flag(s) + * @param flag PetFlag(s) to check */ template - const bool HasFlag(varArg... flag) { - const auto lside = (m_Flags & (static_cast(1 << flag) | ...)); - const auto rside = (static_cast(1 << flag) | ...); - LOG_DEBUG("HasFlag: %d == %d", lside, rside); - return lside == rside; - //return (m_Flags & (static_cast(flag) | ...)) == (static_cast(flag) | ...); - } + const bool HasFlag(varArg... flag) { return (m_Flags & (static_cast(flag) | ...)) == (static_cast(flag) | ...); } + /** + * Returns true if the pet has ONLY the specified flag(s) + * @param flag PetFlag(s) to check if the pet has exclusively + */ + template + const bool HasOnlyFlag(varArg... flag) { return m_Flags == (static_cast(flag) | ...); } + + /** + * Governs the pet update loop + * @param deltaTime Time elapsed since last update + */ void Update(float deltaTime) override; /** diff --git a/tests/dGameTests/dComponentsTests/PetComponentTests.cpp b/tests/dGameTests/dComponentsTests/PetComponentTests.cpp index 2943ae0a..9e063f21 100644 --- a/tests/dGameTests/dComponentsTests/PetComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/PetComponentTests.cpp @@ -22,9 +22,7 @@ protected: petComponent = baseEntity->AddComponent(1); // Initialize some values to be not default - petComponent->SetStatus(0); - petComponent->SetPetAiState(PetAiState::spawn); - petComponent->SetAbility(ePetAbilityType::Invalid); + } void TearDown() override { @@ -34,11 +32,14 @@ protected: }; TEST_F(PetTest, PlacementNewAddComponentTest) { + // Test adding component ASSERT_NE(petComponent, nullptr); baseEntity->AddComponent(1); ASSERT_NE(baseEntity->GetComponent(), nullptr); + + // Test getting initial status ASSERT_EQ(petComponent->GetParent()->GetObjectID(), 15); - ASSERT_EQ(petComponent->GetStatus(), PetFlag::NONE); + ASSERT_TRUE(petComponent->HasFlag(NONE)); ASSERT_EQ(petComponent->GetPetAiState(), PetAiState::spawn); ASSERT_EQ(petComponent->GetAbility(), ePetAbilityType::Invalid); } @@ -47,12 +48,36 @@ TEST_F(PetTest, PlacementNewAddComponentTest) { * Test bitset pet flags */ TEST_F(PetTest, PetComponentFlagTest) { - // Test setting and reading single flags + // Test setting and reading single flags, exclusively + petComponent->SetOnlyFlag(NONE); + ASSERT_TRUE(petComponent->HasOnlyFlag(NONE)); + petComponent->SetOnlyFlag(TAMEABLE); + ASSERT_TRUE(petComponent->HasOnlyFlag(TAMEABLE)); + ASSERT_FALSE(petComponent->HasOnlyFlag(SPAWNING)); + + // Test setting and reading multiple flags, exclusively + petComponent->SetOnlyFlag(NOT_WAITING, SPAWNING); + ASSERT_FALSE(petComponent->HasFlag(TAMEABLE)); + ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING)); + ASSERT_TRUE(petComponent->HasFlag(SPAWNING)); + ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING, SPAWNING)); + ASSERT_FALSE(petComponent->HasOnlyFlag(NOT_WAITING)); + ASSERT_FALSE(petComponent->HasOnlyFlag(SPAWNING)); + ASSERT_TRUE(petComponent->HasOnlyFlag(NOT_WAITING, SPAWNING)); + + // Test flags are being properly reset for next batch of tests + petComponent->SetOnlyFlag(NONE); + ASSERT_TRUE(petComponent->HasFlag(NONE)); + ASSERT_TRUE(petComponent->HasOnlyFlag(NONE)); + ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING)); + ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING, SPAWNING, TAMEABLE)); + + // Test setting and reading single flags, non-exclusively petComponent->SetFlag(NOT_WAITING); ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING)); ASSERT_FALSE(petComponent->HasFlag(SPAWNING)); - // Test setting and reading multiple flags + // Test setting and reading multiple flags, non-exclusively petComponent->SetFlag(TAMEABLE, BEING_TAMED); ASSERT_TRUE(petComponent->HasFlag(TAMEABLE, BEING_TAMED)); ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING)); @@ -61,7 +86,7 @@ TEST_F(PetTest, PetComponentFlagTest) { ASSERT_FALSE(petComponent->HasFlag(SPAWNING)); ASSERT_FALSE(petComponent->HasFlag(SPAWNING, NOT_WAITING, TAMEABLE, BEING_TAMED)); - // Test unsetting and reading multiple flags + // Test unsetting and reading multiple flags, non-exclusively petComponent->UnsetFlag(NOT_WAITING, SPAWNING); ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING, SPAWNING)); ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING));