mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-01-27 22:19:53 +00:00
clean up PetComponent
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define PETCOMPONENT_H
|
||||
|
||||
#include "Entity.h"
|
||||
#include "Flag.h"
|
||||
#include "MovementAIComponent.h"
|
||||
#include "Component.h"
|
||||
#include "Preconditions.h"
|
||||
@@ -11,6 +12,13 @@
|
||||
#include "CDPetComponentTable.h"
|
||||
#include "CDClientManager.h"
|
||||
|
||||
#include <optional>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Forward declarations
|
||||
class PetTest;
|
||||
class PetComponentFlagTest;
|
||||
|
||||
/*
|
||||
* The current state of the pet AI
|
||||
*/
|
||||
@@ -37,44 +45,18 @@ enum class PetInteractType : uint8_t {
|
||||
*/
|
||||
enum class PetFlag : uint32_t {
|
||||
NONE,
|
||||
IDLE = 1 << 0, //0x01 - Seems to be "idle," which the game doesn't differentiate from "follow"
|
||||
UNKNOWN2 = 1 << 1, //0x02,
|
||||
UNKNOWN4 = 1 << 2, //0x04 - FOLLOWING(?)
|
||||
BEING_TAMED = 1 << 4, //0x10,
|
||||
NOT_WAITING = 1 << 5, //0x20,
|
||||
IMMOBILE = 1 << 6, //0x40 - Seems to be the "stop moving" flag - called when taming begins and stays active until a name is submitted
|
||||
SPAWNING = 1 << 7, //0x80
|
||||
ON_SWITCH = 1 << 8, //0x100
|
||||
UNKNOWN1024 = 1 << 10, //0x400
|
||||
TAMEABLE = 1 << 26 //0x4000000
|
||||
IDLE, //0x01 - Seems to be "idle," which the game doesn't differentiate from "follow"
|
||||
UNKNOWN2, //0x02,
|
||||
UNKNOWN4, //0x04 - FOLLOWING(?)
|
||||
BEING_TAMED, //0x10,
|
||||
NOT_WAITING, //0x20,
|
||||
IMMOBILE, //0x40 - Seems to be the "stop moving" flag - called when taming begins and stays active until a name is submitted
|
||||
SPAWNING, //0x80
|
||||
ON_SWITCH, //0x100
|
||||
UNKNOWN1024 = 10, //0x400
|
||||
TAMEABLE = 26 //0x4000000
|
||||
};
|
||||
|
||||
/**
|
||||
* Define bitwise operators for PetFlag (TODO: Encapsulate into proper class)
|
||||
*/
|
||||
constexpr PetFlag operator|(const PetFlag lhs, const PetFlag rhs) {
|
||||
using underlying_type = std::underlying_type_t<PetFlag>;
|
||||
return static_cast<PetFlag>(static_cast<underlying_type>(lhs) | static_cast<underlying_type>(rhs));
|
||||
}
|
||||
|
||||
constexpr PetFlag& operator|=(PetFlag& lhs, const PetFlag rhs) {
|
||||
return lhs = lhs | rhs;
|
||||
}
|
||||
|
||||
constexpr PetFlag operator&(const PetFlag lhs, const PetFlag rhs) {
|
||||
using underlying_type = std::underlying_type_t<PetFlag>;
|
||||
return static_cast<PetFlag>(static_cast<underlying_type>(lhs) & static_cast<underlying_type>(rhs));
|
||||
}
|
||||
|
||||
constexpr PetFlag& operator&=(PetFlag& lhs, const PetFlag rhs) {
|
||||
return lhs = lhs & rhs;
|
||||
}
|
||||
|
||||
constexpr PetFlag operator~(const PetFlag flag) {
|
||||
using underlying_type = std::underlying_type_t<PetFlag>;
|
||||
return static_cast<PetFlag>(~static_cast<underlying_type>(flag));
|
||||
}
|
||||
|
||||
/**
|
||||
* The pet emote animation ids that can used in PetComponent::Command()
|
||||
*/
|
||||
@@ -88,8 +70,7 @@ enum class PetEmote : int32_t {
|
||||
* Represents an entity that is a pet. This pet can be tamed and consequently follows the tamer around, allowing it
|
||||
* to dig for treasure and activate pet bouncers.
|
||||
*/
|
||||
class PetComponent final : public Component
|
||||
{
|
||||
class PetComponent final : public Component {
|
||||
public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PET;
|
||||
|
||||
@@ -99,8 +80,8 @@ public:
|
||||
* @param componentId The component id
|
||||
*/
|
||||
explicit PetComponent(Entity* parentEntity, uint32_t componentId);
|
||||
|
||||
~PetComponent() override;
|
||||
|
||||
~PetComponent() override = default;
|
||||
|
||||
/**
|
||||
* Serializes the pet
|
||||
@@ -113,56 +94,16 @@ public:
|
||||
* Sets the AI state of the pet
|
||||
* @param newState New pet AI state
|
||||
*/
|
||||
void SetPetAiState(PetAiState newState);
|
||||
void SetPetAiState(const PetAiState newState) noexcept {
|
||||
m_State = newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the AI state of the pet
|
||||
*/
|
||||
PetAiState GetPetAiState() const { return m_State; }
|
||||
|
||||
/**
|
||||
* Sets one or more pet flags
|
||||
* @param flag PetFlag(s) to set
|
||||
*/
|
||||
template <typename... varArg>
|
||||
void SetFlag(varArg... flag) {
|
||||
m_Flags |= (flag | ...);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = (flag | ...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets one or more pet flags
|
||||
* @param flag PetFlag(s) to unset
|
||||
*/
|
||||
template <typename... varArg>
|
||||
void UnsetFlag(varArg... flag) {
|
||||
m_Flags &= ~(flag | ...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the pet has all the specified flag(s)
|
||||
* @param flag PetFlag(s) to check
|
||||
*/
|
||||
template <typename... varArg>
|
||||
bool HasFlag(varArg... flag) const {
|
||||
return (m_Flags & (flag | ...)) == (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>
|
||||
bool HasOnlyFlag(varArg... flag) const {
|
||||
return m_Flags == (flag | ...);
|
||||
[[nodiscard]]
|
||||
PetAiState GetPetAiState() const noexcept {
|
||||
return m_State;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,7 +179,7 @@ public:
|
||||
/**
|
||||
* Start a pet interaction with an object at a given position
|
||||
*/
|
||||
void StartInteract(const NiPoint3& position, const PetInteractType interactType, const LWOOBJID& interactID);
|
||||
void StartInteract(const NiPoint3& position, const PetInteractType interactionType, const LWOOBJID& interactID);
|
||||
|
||||
/**
|
||||
* Stop a pet interaction with an object
|
||||
@@ -246,16 +187,6 @@ public:
|
||||
*/
|
||||
void StopInteract(bool bDontSerialize = false);
|
||||
|
||||
/**
|
||||
* Set the type of interaction the pet is executing
|
||||
*/
|
||||
void SetInteractType(PetInteractType interactType) { m_InteractType = interactType; };
|
||||
|
||||
/**
|
||||
* Get the type of interaction the pet is executing
|
||||
*/
|
||||
PetInteractType GetInteractType() { return m_InteractType; };
|
||||
|
||||
/**
|
||||
* Spawns a pet from an item in the inventory of an owner
|
||||
* @param item the item to create the pet from
|
||||
@@ -287,90 +218,75 @@ public:
|
||||
* Returns the ID of the owner of this pet (if any)
|
||||
* @return the ID of the owner of this pet
|
||||
*/
|
||||
LWOOBJID GetOwnerId() const;
|
||||
[[nodiscard]]
|
||||
LWOOBJID GetOwnerId() const noexcept {
|
||||
return m_Owner;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the entity that owns this pet (if any)
|
||||
* @return the entity that owns this pet
|
||||
*/
|
||||
[[nodiscard]]
|
||||
Entity* GetOwner() const;
|
||||
|
||||
/**
|
||||
* Returns the ID that is stored in the database with regards to this pet, only set for pets that are tamed
|
||||
* @return the ID that is stored in the database with regards to this pet
|
||||
*/
|
||||
LWOOBJID GetDatabaseId() const;
|
||||
|
||||
/**
|
||||
* Returns the ID of the object that the pet is currently interacting with, could be a treasure chest or a switch
|
||||
* @return the ID of the object that the pet is currently interacting with
|
||||
*/
|
||||
LWOOBJID GetInteraction() const;
|
||||
|
||||
/**
|
||||
* Sets the ID that the pet is interacting with
|
||||
* @param value the ID that the pet is interacting with
|
||||
*/
|
||||
void SetInteraction(LWOOBJID value);
|
||||
[[nodiscard]]
|
||||
LWOOBJID GetDatabaseId() const noexcept {
|
||||
return m_DatabaseId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID that this pet was spawned from, only set for tamed pets
|
||||
* @return the ID that this pet was spawned from
|
||||
*/
|
||||
LWOOBJID GetItemId() const;
|
||||
|
||||
/**
|
||||
* Returns the status of this pet, e.g. tamable or tamed. The values here are still a bit of mystery and likely a
|
||||
* bit map
|
||||
* @return the status of this pet
|
||||
*/
|
||||
/*uint32_t GetStatus() const;*/
|
||||
|
||||
/**
|
||||
* Sets the current status of the pet
|
||||
* @param value the current status of the pet to set
|
||||
*/
|
||||
/*void SetStatus(uint32_t value);*/
|
||||
|
||||
/**
|
||||
* Returns an ability the pet may perform, currently unused
|
||||
* @return an ability the pet may perform
|
||||
*/
|
||||
ePetAbilityType GetAbility() const;
|
||||
|
||||
/**
|
||||
* Sets the ability of the pet, currently unused
|
||||
* @param value the ability to set
|
||||
*/
|
||||
void SetAbility(ePetAbilityType value);
|
||||
[[nodiscard]]
|
||||
LWOOBJID GetItemId() const noexcept {
|
||||
return m_ItemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets preconditions for the pet that need to be met before it can be tamed
|
||||
* @param conditions the preconditions to set
|
||||
*/
|
||||
void SetPreconditions(std::string& conditions);
|
||||
void SetPreconditions(const std::string& preconditions) {
|
||||
m_Preconditions = PreconditionExpression(preconditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the pet is ready to interact with an object
|
||||
* @param isReady whether the pet is ready to interact (true) or not (false)
|
||||
*/
|
||||
void SetIsReadyToInteract(bool isReady) { m_ReadyToInteract = isReady; };
|
||||
void SetIsReadyToInteract(const bool isReady) {
|
||||
m_ReadyToInteract = isReady;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return is pet ready to interact with an object
|
||||
*/
|
||||
bool IsReadyToInteract() { return m_ReadyToInteract; };
|
||||
[[nodiscard]]
|
||||
bool IsReadyToInteract() const noexcept {
|
||||
return m_ReadyToInteract;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the pet is currently handling an interaction with an object
|
||||
* @param isHandlingInteraction whether the pet is currently handling an interaction with an object
|
||||
*/
|
||||
void SetIsHandlingInteraction(bool isHandlingInteraction) { m_IsHandlingInteraction = isHandlingInteraction; };
|
||||
void SetIsHandlingInteraction(const bool isHandlingInteraction) {
|
||||
m_IsHandlingInteraction = isHandlingInteraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return is pet currently handling an interaction with an object
|
||||
*/
|
||||
bool IsHandlingInteraction() { return m_IsHandlingInteraction; };
|
||||
[[nodiscard]]
|
||||
bool IsHandlingInteraction() const noexcept {
|
||||
return m_IsHandlingInteraction;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set up the pet bouncer interaction
|
||||
@@ -406,7 +322,10 @@ public:
|
||||
* Returns the entity that this component belongs to
|
||||
* @return the entity that this component belongs to
|
||||
*/
|
||||
Entity* GetParentEntity() const;
|
||||
[[nodiscard]]
|
||||
Entity* GetParentEntity() const noexcept {
|
||||
return m_Parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the pet to be moderated
|
||||
@@ -425,6 +344,7 @@ public:
|
||||
* @param tamer the entity that's currently taming
|
||||
* @return the pet component of the entity that's being tamed
|
||||
*/
|
||||
[[nodiscard]]
|
||||
static PetComponent* GetTamingPet(LWOOBJID tamer);
|
||||
|
||||
/**
|
||||
@@ -432,6 +352,7 @@ public:
|
||||
* @param owner the owner of the pet that's spawned
|
||||
* @return the pet component of the entity that was spawned by the owner
|
||||
*/
|
||||
[[nodiscard]]
|
||||
static PetComponent* GetActivePet(LWOOBJID owner);
|
||||
|
||||
/**
|
||||
@@ -443,11 +364,15 @@ public:
|
||||
void AddDrainImaginationTimer(Item* item, bool fromTaming = false);
|
||||
|
||||
private:
|
||||
// Needed so these can access flags
|
||||
friend class DamagingPets;
|
||||
friend class PetTest;
|
||||
FRIEND_TEST(PetTest, PetComponentFlagTest);
|
||||
|
||||
/**
|
||||
* Information for the minigame to be completed
|
||||
*/
|
||||
struct PetPuzzleData
|
||||
struct PuzzleData
|
||||
{
|
||||
/**
|
||||
* The LOT of the object that is to be created
|
||||
@@ -475,6 +400,28 @@ private:
|
||||
int32_t numValidPieces;
|
||||
};
|
||||
|
||||
struct Interaction {
|
||||
/**
|
||||
* The type of object that the pet is currently interacting with (e.g. a treasure chest or switch)
|
||||
*/
|
||||
PetInteractType type = PetInteractType::none;
|
||||
|
||||
/**
|
||||
* The interaction ability
|
||||
*/
|
||||
ePetAbilityType ability = ePetAbilityType::Invalid;
|
||||
|
||||
/**
|
||||
* The ID of the object that the pet is currently interacting with (e.g. a treasure chest or switch)
|
||||
*/
|
||||
LWOOBJID obj = LWOOBJID_EMPTY;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pet interaction info
|
||||
*/
|
||||
Interaction m_Interaction{};
|
||||
|
||||
/**
|
||||
* Cache of all the pets that are currently spawned, indexed by tamer
|
||||
*/
|
||||
@@ -488,7 +435,7 @@ private:
|
||||
/**
|
||||
* Cache of all the minigames and their information from the database
|
||||
*/
|
||||
static std::unordered_map<LOT, PetComponent::PetPuzzleData> buildCache;
|
||||
static std::unordered_map<LOT, PetComponent::PuzzleData> buildCache;
|
||||
|
||||
/**
|
||||
* Flags that indicate that a player has tamed a pet, indexed by the LOT of the pet
|
||||
@@ -508,32 +455,22 @@ private:
|
||||
/**
|
||||
* The ID of the model that was built to complete the taming minigame for this pet
|
||||
*/
|
||||
LWOOBJID m_ModelId;
|
||||
|
||||
/**
|
||||
* The ID of the object that the pet is currently interacting with (e.g. a treasure chest or switch)
|
||||
*/
|
||||
LWOOBJID m_Interaction;
|
||||
|
||||
/**
|
||||
* The type of object that the pet is currently interacting with (e.g. a treasure chest or switch)
|
||||
*/
|
||||
PetInteractType m_InteractType;
|
||||
LWOOBJID m_ModelId = LWOOBJID_EMPTY;
|
||||
|
||||
/**
|
||||
* The ID of the entity that owns this pet
|
||||
*/
|
||||
LWOOBJID m_Owner;
|
||||
LWOOBJID m_Owner = LWOOBJID_EMPTY;
|
||||
|
||||
/**
|
||||
* The ID of the entity that is currently taming this pet
|
||||
*/
|
||||
LWOOBJID m_Tamer;
|
||||
LWOOBJID m_Tamer = LWOOBJID_EMPTY;
|
||||
|
||||
/**
|
||||
* The ID under which this pet is stored in the database (if it's tamed)
|
||||
*/
|
||||
LWOOBJID m_DatabaseId;
|
||||
LWOOBJID m_DatabaseId = LWOOBJID_EMPTY;
|
||||
|
||||
/**
|
||||
* The ID of the item from which this pet was created
|
||||
@@ -543,7 +480,7 @@ private:
|
||||
/**
|
||||
* The moderation status for the name of this pet
|
||||
*/
|
||||
uint32_t m_ModerationStatus;
|
||||
uint32_t m_ModerationStatus = 0;
|
||||
|
||||
/**
|
||||
* The name of this pet
|
||||
@@ -558,32 +495,27 @@ private:
|
||||
/**
|
||||
* The current flags of the pet (e.g. tamable, tamed, etc).
|
||||
*/
|
||||
PetFlag m_Flags;
|
||||
Flag<PetFlag> m_Flags;
|
||||
|
||||
/**
|
||||
* The current state of the pet AI
|
||||
*/
|
||||
PetAiState m_State;
|
||||
|
||||
/**
|
||||
* A currently active ability, mostly unused
|
||||
*/
|
||||
ePetAbilityType m_Ability;
|
||||
|
||||
/**
|
||||
* The time an entity has left to complete the minigame
|
||||
*/
|
||||
float m_Timer;
|
||||
float m_Timer = 0;
|
||||
|
||||
/**
|
||||
* A timer that tracks how long a tamed pet has been to far away from its owner, triggering a teleport after timeout
|
||||
*/
|
||||
float m_TimerAway;
|
||||
float m_TimerAway = 0;
|
||||
|
||||
/**
|
||||
* A timer that tracks how long until a tamed pet will bounce again when standing over a treasure dig site
|
||||
*/
|
||||
float m_TimerBounce;
|
||||
float m_TimerBounce = 0;
|
||||
|
||||
/**
|
||||
* Boolean that sets if a pet is ready to interact with an object
|
||||
@@ -608,7 +540,7 @@ private:
|
||||
/**
|
||||
* Preconditions that need to be met before an entity can tame this pet
|
||||
*/
|
||||
PreconditionExpression* m_Preconditions;
|
||||
std::optional<PreconditionExpression> m_Preconditions;
|
||||
|
||||
/**
|
||||
* Pet information loaded from the CDClientDatabase
|
||||
|
||||
Reference in New Issue
Block a user