PetFlag system now functioning correctly

This commit is contained in:
jadebenn 2023-12-15 14:36:27 -06:00
parent e01fbfcc64
commit 9add2c944e
3 changed files with 70 additions and 46 deletions

View File

@ -86,7 +86,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
m_TimerAway = 0; m_TimerAway = 0;
m_TimerBounce = 0; m_TimerBounce = 0;
m_DatabaseId = LWOOBJID_EMPTY; m_DatabaseId = LWOOBJID_EMPTY;
m_Flags = 1 << PetFlag::TAMEABLE; // Tameable m_Flags = PetFlag::TAMEABLE; // Tameable
m_Ability = ePetAbilityType::Invalid; m_Ability = ePetAbilityType::Invalid;
m_StartPosition = m_Parent->GetPosition(); //NiPoint3::ZERO; m_StartPosition = m_Parent->GetPosition(); //NiPoint3::ZERO;
m_MovementAI = nullptr; m_MovementAI = nullptr;
@ -720,7 +720,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
currentActivities.erase(m_Tamer); currentActivities.erase(m_Tamer);
SetStatus(1 << PetFlag::TAMEABLE); SetStatus(PetFlag::TAMEABLE);
m_Tamer = LWOOBJID_EMPTY; m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0; m_Timer = 0;
@ -771,7 +771,7 @@ void PetComponent::ClientFailTamingMinigame() {
currentActivities.erase(m_Tamer); currentActivities.erase(m_Tamer);
SetStatus(1 << PetFlag::TAMEABLE); SetStatus(PetFlag::TAMEABLE);
m_Tamer = LWOOBJID_EMPTY; m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0; m_Timer = 0;
@ -836,7 +836,7 @@ void PetComponent::OnSpawn() {
m_Parent->SetOwnerOverride(m_Owner); m_Parent->SetOwnerOverride(m_Owner);
m_MovementAI->SetMaxSpeed(m_SprintSpeed); m_MovementAI->SetMaxSpeed(m_SprintSpeed);
m_MovementAI->SetHaltDistance(m_FollowRadius); m_MovementAI->SetHaltDistance(m_FollowRadius);
SetStatus(1 << PetFlag::NONE); SetStatus(PetFlag::NONE);
SetPetAiState(PetAiState::follow); SetPetAiState(PetAiState::follow);
} }
else { else {
@ -947,7 +947,7 @@ void PetComponent::StopInteract() {
SetInteractType(PetInteractType::none); SetInteractType(PetInteractType::none);
SetAbility(petAbility); SetAbility(petAbility);
SetPetAiState(PetAiState::follow); SetPetAiState(PetAiState::follow);
SetStatus(1 << PetFlag::NONE); SetStatus(PetFlag::NONE);
SetIsReadyToInteract(false); SetIsReadyToInteract(false);
SetIsHandlingInteraction(false); // Needed? SetIsHandlingInteraction(false); // Needed?
m_MovementAI->SetMaxSpeed(m_SprintSpeed); m_MovementAI->SetMaxSpeed(m_SprintSpeed);
@ -977,7 +977,7 @@ void PetComponent::SetupInteractTreasureDig() {
auto petAbility = ePetAbilityType::DigAtPosition; auto petAbility = ePetAbilityType::DigAtPosition;
SetAbility(petAbility); 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 Game::entityManager->SerializeEntity(m_Parent); // TODO: Double-check pet packet captures
const auto sysAddr = owner->GetSystemAddress(); const auto sysAddr = owner->GetSystemAddress();
@ -1054,7 +1054,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { //
auto* owner = GetOwner(); auto* owner = GetOwner();
if (owner == nullptr) return; if (owner == nullptr) return;
SetStatus(1 << PetFlag::SPAWNING); SetFlag(SPAWNING); //SetStatus(PetFlag::SPAWNING);
auto databaseData = inventoryComponent->GetDatabasePet(m_DatabaseId); auto databaseData = inventoryComponent->GetDatabasePet(m_DatabaseId);

View File

@ -34,23 +34,15 @@ enum PetInteractType : uint8_t {
*/ */
enum PetFlag : uint32_t { enum PetFlag : uint32_t {
NONE, NONE,
BEING_TAMED = 4, BEING_TAMED = 1 << 4, //0x10,
NOT_WAITING = 5, NOT_WAITING = 1 << 5, //0x20,
SPAWNING = 7, SPAWNING = 1 << 7, //0x80
TAMEABLE = 8 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 { enum PetEmote : int32_t {
ActivateSwitch = 201, ActivateSwitch = 201,
DigTreasure, DigTreasure,
@ -93,36 +85,43 @@ public:
/** /**
* Sets one or more pet flags * Sets one or more pet flags
* @param flag PetFlag(s) to set
*/ */
template <typename... varArg> template <typename... varArg>
void SetFlag(varArg... flag) { void SetFlag(varArg... flag) { m_Flags |= (static_cast<uint32_t>(flag) | ...); }
const auto initFlags = m_Flags;
m_Flags |= (static_cast<uint32_t>(1 << flag) | ...); /**
LOG_DEBUG("SetFlag: %d + %d = %d", initFlags, 1 << (flag | ...), m_Flags); * Sets the pet to ONLY have the specified flag(s), clearing all others
} * @param flag PetFlag(s) to set exclusively
*/
template <typename... varArg>
void SetOnlyFlag(varArg... flag) { m_Flags = (static_cast<uint32_t>(flag) | ...); }
/** /**
* Unsets one or more pet flags * Unsets one or more pet flags
* @param flag PetFlag(s) to unset
*/ */
template <typename... varArg> template <typename... varArg>
void UnsetFlag(varArg... flag) { void UnsetFlag(varArg... flag) { m_Flags &= ~(static_cast<uint32_t>(flag) | ...); }
const auto initFlags = m_Flags;
m_Flags &= ~(static_cast<uint32_t>(1 << flag) | ...);
LOG_DEBUG("UnsetFlag: %d - %d = %d", initFlags, 1 << (flag | ...), m_Flags);
} // THIS IS PROBLEMATIC
/** /**
* Gets one or more pet flags * Returns true if the pet has all the specified flag(s)
* @param flag PetFlag(s) to check
*/ */
template <typename... varArg> template <typename... varArg>
const bool HasFlag(varArg... flag) { const bool HasFlag(varArg... flag) { return (m_Flags & (static_cast<uint32_t>(flag) | ...)) == (static_cast<uint32_t>(flag) | ...); }
const auto lside = (m_Flags & (static_cast<uint32_t>(1 << flag) | ...));
const auto rside = (static_cast<uint32_t>(1 << flag) | ...);
LOG_DEBUG("HasFlag: %d == %d", lside, rside);
return lside == rside;
//return (m_Flags & (static_cast<uint32_t>(flag) | ...)) == (static_cast<uint32_t>(flag) | ...);
}
/**
* Returns true if the pet has ONLY the specified flag(s)
* @param flag PetFlag(s) to check if the pet has exclusively
*/
template <typename... varArg>
const bool HasOnlyFlag(varArg... flag) { return m_Flags == (static_cast<uint32_t>(flag) | ...); }
/**
* Governs the pet update loop
* @param deltaTime Time elapsed since last update
*/
void Update(float deltaTime) override; void Update(float deltaTime) override;
/** /**

View File

@ -22,9 +22,7 @@ protected:
petComponent = baseEntity->AddComponent<PetComponent>(1); petComponent = baseEntity->AddComponent<PetComponent>(1);
// Initialize some values to be not default // Initialize some values to be not default
petComponent->SetStatus(0);
petComponent->SetPetAiState(PetAiState::spawn);
petComponent->SetAbility(ePetAbilityType::Invalid);
} }
void TearDown() override { void TearDown() override {
@ -34,11 +32,14 @@ protected:
}; };
TEST_F(PetTest, PlacementNewAddComponentTest) { TEST_F(PetTest, PlacementNewAddComponentTest) {
// Test adding component
ASSERT_NE(petComponent, nullptr); ASSERT_NE(petComponent, nullptr);
baseEntity->AddComponent<PetComponent>(1); baseEntity->AddComponent<PetComponent>(1);
ASSERT_NE(baseEntity->GetComponent<PetComponent>(), nullptr); ASSERT_NE(baseEntity->GetComponent<PetComponent>(), nullptr);
// Test getting initial status
ASSERT_EQ(petComponent->GetParent()->GetObjectID(), 15); 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->GetPetAiState(), PetAiState::spawn);
ASSERT_EQ(petComponent->GetAbility(), ePetAbilityType::Invalid); ASSERT_EQ(petComponent->GetAbility(), ePetAbilityType::Invalid);
} }
@ -47,12 +48,36 @@ TEST_F(PetTest, PlacementNewAddComponentTest) {
* Test bitset pet flags * Test bitset pet flags
*/ */
TEST_F(PetTest, PetComponentFlagTest) { 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); petComponent->SetFlag(NOT_WAITING);
ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING)); ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING));
ASSERT_FALSE(petComponent->HasFlag(SPAWNING)); ASSERT_FALSE(petComponent->HasFlag(SPAWNING));
// Test setting and reading multiple flags // Test setting and reading multiple flags, non-exclusively
petComponent->SetFlag(TAMEABLE, BEING_TAMED); petComponent->SetFlag(TAMEABLE, BEING_TAMED);
ASSERT_TRUE(petComponent->HasFlag(TAMEABLE, BEING_TAMED)); ASSERT_TRUE(petComponent->HasFlag(TAMEABLE, BEING_TAMED));
ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING)); ASSERT_TRUE(petComponent->HasFlag(NOT_WAITING));
@ -61,7 +86,7 @@ TEST_F(PetTest, PetComponentFlagTest) {
ASSERT_FALSE(petComponent->HasFlag(SPAWNING)); ASSERT_FALSE(petComponent->HasFlag(SPAWNING));
ASSERT_FALSE(petComponent->HasFlag(SPAWNING, NOT_WAITING, TAMEABLE, BEING_TAMED)); 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); petComponent->UnsetFlag(NOT_WAITING, SPAWNING);
ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING, SPAWNING)); ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING, SPAWNING));
ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING)); ASSERT_FALSE(petComponent->HasFlag(NOT_WAITING));