mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-04-26 16:46:31 +00:00
Further redid pet update loop
This commit is contained in:
parent
200d679dd8
commit
5b738dfc58
@ -34,7 +34,6 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id):
|
||||
m_MovementAI = nullptr;
|
||||
m_Disabled = false;
|
||||
m_SkillEntries = {};
|
||||
m_MovementAI = nullptr;
|
||||
m_SoftTimer = 5.0f;
|
||||
|
||||
//Grab the aggro information from BaseCombatAI:
|
||||
|
@ -73,6 +73,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
|
||||
m_ComponentId = componentId;
|
||||
|
||||
m_Interaction = LWOOBJID_EMPTY;
|
||||
m_InteractType = PetInteractType::none;
|
||||
m_Owner = LWOOBJID_EMPTY;
|
||||
m_ModerationStatus = 0;
|
||||
m_Tamer = LWOOBJID_EMPTY;
|
||||
@ -89,6 +90,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
|
||||
|
||||
m_ReadyToDig = false;
|
||||
SetPetAiState(PetAiState::spawn);
|
||||
m_FollowRadius = 5.0f;
|
||||
|
||||
std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parent->GetVar<std::u16string>(u"CheckPrecondition"));
|
||||
|
||||
@ -104,17 +106,10 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (!result.eof()) {
|
||||
if (!result.fieldIsNull(0))
|
||||
m_walkSpeed = result.getFloatField(0);
|
||||
|
||||
if (!result.fieldIsNull(1))
|
||||
m_RunSpeed = result.getFloatField(1);
|
||||
|
||||
if (!result.fieldIsNull(2))
|
||||
m_SprintSpeed = result.getFloatField(2);
|
||||
|
||||
if (!result.fieldIsNull(3))
|
||||
imaginationDrainRate = result.getFloatField(3);
|
||||
m_walkSpeed = result.getFloatField(0, 2.5f);
|
||||
m_RunSpeed = result.getFloatField(1, 5.0f);
|
||||
m_SprintSpeed = result.getFloatField(2, 10.0f);
|
||||
imaginationDrainRate = result.getFloatField(3, 60.0f);
|
||||
}
|
||||
|
||||
result.finalize();
|
||||
@ -176,22 +171,16 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
if (m_Tamer != LWOOBJID_EMPTY) {
|
||||
auto* tamer = Game::entityManager->GetEntity(m_Tamer);
|
||||
|
||||
if (tamer != nullptr) {
|
||||
return;
|
||||
}
|
||||
if (tamer != nullptr) return;
|
||||
|
||||
m_Tamer = LWOOBJID_EMPTY;
|
||||
}
|
||||
|
||||
auto* inventoryComponent = originator->GetComponent<InventoryComponent>();
|
||||
|
||||
if (inventoryComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (inventoryComponent == nullptr) return;
|
||||
|
||||
if (m_Preconditions != nullptr && !m_Preconditions->Check(originator, true)) {
|
||||
return;
|
||||
}
|
||||
if (m_Preconditions != nullptr && !m_Preconditions->Check(originator, true)) return;
|
||||
|
||||
auto* movementAIComponent = m_Parent->GetComponent<MovementAIComponent>();
|
||||
|
||||
@ -246,15 +235,11 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
|
||||
auto* destroyableComponent = originator->GetComponent<DestroyableComponent>();
|
||||
|
||||
if (destroyableComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (destroyableComponent == nullptr) return;
|
||||
|
||||
auto imagination = destroyableComponent->GetImagination();
|
||||
|
||||
if (imagination < imaginationCost) {
|
||||
return;
|
||||
}
|
||||
if (imagination < imaginationCost) return;
|
||||
|
||||
const auto& bricks = BrickDatabase::GetBricks(buildFile);
|
||||
|
||||
@ -344,7 +329,7 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
|
||||
void PetComponent::Update(float deltaTime) {
|
||||
// If pet does not have an owner, use the UpdateUnowned() loop
|
||||
if (m_Owner == LWOOBJID_EMPTY) {
|
||||
/*if (m_Owner == LWOOBJID_EMPTY) {
|
||||
UpdateUnowned(deltaTime);
|
||||
return;
|
||||
}
|
||||
@ -354,6 +339,10 @@ void PetComponent::Update(float deltaTime) {
|
||||
if (!owner) {
|
||||
m_Parent->Kill(); // Kill pet if no owner
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (m_StartPosition == NiPoint3::ZERO) {
|
||||
m_StartPosition = m_Parent->GetPosition();
|
||||
}
|
||||
|
||||
// Update timer
|
||||
@ -362,138 +351,40 @@ void PetComponent::Update(float deltaTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle treasure timer
|
||||
if (m_TresureTime > 0.0f) { //TODO: Find better trigger?
|
||||
InteractDig(deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle pet AI states
|
||||
switch (m_State) {
|
||||
// Handle idle state
|
||||
case PetAiState::idle: {
|
||||
LOG_DEBUG("Pet in idle state!");
|
||||
m_Timer = 1.0f;
|
||||
break;
|
||||
case PetAiState::spawn:
|
||||
LOG_DEBUG("Pet spawn beginning!");
|
||||
OnSpawn();
|
||||
break;
|
||||
|
||||
case PetAiState::idle:
|
||||
Wander();
|
||||
break;
|
||||
|
||||
case PetAiState::follow:
|
||||
OnFollow();
|
||||
break;
|
||||
|
||||
case PetAiState::goToObj:
|
||||
LOG_DEBUG("Going to object!");
|
||||
if (m_MovementAI->AtFinalWaypoint()) {
|
||||
LOG_DEBUG("Reached object!");
|
||||
m_MovementAI->Stop();
|
||||
SetPetAiState(PetAiState::interact);
|
||||
}
|
||||
// Handle follow state
|
||||
case PetAiState::follow: {
|
||||
// Get movement AI component
|
||||
m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
|
||||
if (!m_MovementAI) return;
|
||||
|
||||
// Get and set destination
|
||||
//auto position = m_MovementAI->GetParent()->GetPosition();
|
||||
auto ownerPos = owner->GetPosition();
|
||||
NiPoint3 destination = ownerPos;
|
||||
NiPoint3 interactPos = NiPoint3::ZERO;
|
||||
|
||||
// Determine if the "Lost Tags" mission has been completed and digging has been unlocked
|
||||
auto* missionComponent = owner->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE;
|
||||
|
||||
// Interactions checks
|
||||
SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(ownerPos);
|
||||
Entity* closestTreasure = PetDigServer::GetClosestTresure(ownerPos);
|
||||
if (closestSwitch != nullptr && !closestSwitch->GetActive()) {
|
||||
m_Interaction = closestSwitch->GetParentEntity()->GetObjectID();
|
||||
interactPos = closestSwitch->GetParentEntity()->GetPosition();
|
||||
m_Ability = PetAbilityType::GoToObject;
|
||||
}
|
||||
if (closestTreasure != nullptr && digUnlocked) {
|
||||
m_Interaction = closestTreasure->GetObjectID();
|
||||
interactPos = closestTreasure->GetPosition();
|
||||
m_Ability = PetAbilityType::GoToObject;
|
||||
}
|
||||
|
||||
// Trigger interaction if checks are valid
|
||||
if (m_Ability != PetAbilityType::Invalid) {
|
||||
float distance = Vector3::DistanceSquared(ownerPos, interactPos);
|
||||
if (distance < 20 * 20) {
|
||||
destination = interactPos;
|
||||
m_MovementAI->SetHaltDistance(0.0f);
|
||||
SetPetAiState(PetAiState::interact);
|
||||
}
|
||||
}
|
||||
|
||||
m_MovementAI->SetDestination(destination);
|
||||
//LOG_DEBUG("Pet destination: %f %f %f", destination.x, destination.y, destination.z);
|
||||
m_Timer = 1.0f;
|
||||
|
||||
break;
|
||||
else {
|
||||
m_Timer += 0.5f;
|
||||
}
|
||||
// Handle interact state
|
||||
case PetAiState::interact: {
|
||||
LOG_DEBUG("Interacting with object!");
|
||||
break;
|
||||
|
||||
// Get movement AI component
|
||||
m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
|
||||
if (!m_MovementAI) return;
|
||||
case PetAiState::interact:
|
||||
OnInteract();
|
||||
break;
|
||||
|
||||
// Get distance from owner
|
||||
auto ownerPos = owner->GetPosition();
|
||||
auto position = m_MovementAI->GetParent()->GetPosition();
|
||||
float distanceFromOwner = Vector3::DistanceSquared(position, ownerPos);
|
||||
|
||||
// Switch back to follow AI state if player moves too far away from pet
|
||||
if (distanceFromOwner > 15 * 15) {
|
||||
m_MovementAI->SetHaltDistance(5.0f); // TODO: Remove this magic number
|
||||
m_Interaction = LWOOBJID_EMPTY;
|
||||
m_Ability = PetAbilityType::Invalid;
|
||||
SetIsReadyToDig(false);
|
||||
SetPetAiState(PetAiState::follow);
|
||||
LOG_DEBUG("Pet interaction aborted due to player distance!");
|
||||
break;
|
||||
}
|
||||
|
||||
// Get distance from interactable
|
||||
auto destination = m_MovementAI->GetDestination();
|
||||
float distanceFromInteract = Vector3::DistanceSquared(position, destination);
|
||||
|
||||
// Handle the interaction
|
||||
if (m_MovementAI->AtFinalWaypoint()) {
|
||||
Entity* interactEntity = Game::entityManager->GetEntity(m_Interaction);
|
||||
|
||||
/*auto* switchComponent = interactEntity->GetComponent<SwitchComponent>();
|
||||
if (switchComponent != nullptr) {
|
||||
switchComponent->EntityEnter(m_Parent);
|
||||
}
|
||||
else {*/
|
||||
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce, true); // Plays 'bounce' animation
|
||||
SetIsReadyToDig(true);
|
||||
//}
|
||||
}
|
||||
|
||||
m_Timer = 1.0f;
|
||||
break;
|
||||
}
|
||||
// Handle spawn state
|
||||
case PetAiState::spawn: {
|
||||
LOG_DEBUG("Pet spawned!");
|
||||
|
||||
// Get movement AI component
|
||||
m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
|
||||
if (!m_MovementAI) return;
|
||||
|
||||
// Determine the pet start position
|
||||
if (m_StartPosition == NiPoint3::ZERO) m_StartPosition = m_Parent->GetPosition();
|
||||
|
||||
// Determine next state;
|
||||
if (m_Owner == LWOOBJID_EMPTY) {
|
||||
SetPetAiState(PetAiState::idle);
|
||||
}
|
||||
else {
|
||||
SetPetAiState(PetAiState::follow);
|
||||
m_MovementAI->SetMaxSpeed(m_SprintSpeed);
|
||||
m_MovementAI->SetHaltDistance(5.0f); // TODO: Remove magic number
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
/*
|
||||
|
||||
auto destination = owner->GetPosition();
|
||||
@ -577,7 +468,7 @@ skipTresure:
|
||||
m_Timer = 1;*/
|
||||
}
|
||||
|
||||
void PetComponent::UpdateUnowned(float deltaTime) {
|
||||
void PetComponent::UpdateUnowned(float deltaTime) { //CURRENTLY UNUSED
|
||||
if (m_Tamer != LWOOBJID_EMPTY) {
|
||||
if (m_Timer > 0) {
|
||||
m_Timer -= deltaTime;
|
||||
@ -967,9 +858,7 @@ void PetComponent::ClientFailTamingMinigame() {
|
||||
void PetComponent::Wander() {
|
||||
m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
|
||||
|
||||
if (m_MovementAI == nullptr || !m_MovementAI->AtFinalWaypoint()) {
|
||||
return;
|
||||
}
|
||||
if (m_MovementAI == nullptr || !m_MovementAI->AtFinalWaypoint()) return;
|
||||
|
||||
m_MovementAI->SetHaltDistance(0);
|
||||
|
||||
@ -1007,6 +896,135 @@ void PetComponent::Wander() {
|
||||
m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / info.wanderSpeed;
|
||||
}
|
||||
|
||||
void PetComponent::OnSpawn() {
|
||||
m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
|
||||
if (!m_MovementAI) return;
|
||||
|
||||
LOG_DEBUG("Pet spawn complete, setting AI state.");
|
||||
|
||||
if (m_Owner != LWOOBJID_EMPTY) SetPetAiState(PetAiState::follow);
|
||||
else SetPetAiState(PetAiState::idle);
|
||||
}
|
||||
|
||||
void PetComponent::OnFollow() {
|
||||
m_MovementAI->SetHaltDistance(5.0f); // TODO: Remove this magic number
|
||||
|
||||
Entity* owner = GetOwner();
|
||||
NiPoint3 ownerPos = owner->GetPosition();
|
||||
NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
|
||||
|
||||
// If the player's position is within range, stop moving
|
||||
if (Vector3::DistanceSquared(currentPos, ownerPos) <= m_FollowRadius * m_FollowRadius) {
|
||||
m_MovementAI->Stop();
|
||||
}
|
||||
else { // Chase the player's new position
|
||||
m_MovementAI->SetMaxSpeed(m_SprintSpeed);
|
||||
m_MovementAI->SetDestination(ownerPos);
|
||||
LOG_DEBUG("New pet destination: %f %f %f", ownerPos.x, ownerPos.y, ownerPos.z);
|
||||
//SetPetAiState(PetAiState::tether);
|
||||
}
|
||||
|
||||
//TEST SECTION
|
||||
SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(ownerPos);
|
||||
if (closestSwitch != nullptr && !closestSwitch->GetActive()) {
|
||||
NiPoint3 switchPos = closestSwitch->GetParentEntity()->GetPosition();
|
||||
const float distance = Vector3::DistanceSquared(ownerPos, switchPos);
|
||||
if (distance < 20 * 20) {
|
||||
StartInteract(switchPos, PetInteractType::bouncer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if the "Lost Tags" mission has been completed and digging has been unlocked
|
||||
auto* missionComponent = owner->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE;
|
||||
|
||||
Entity* closestTreasure = PetDigServer::GetClosestTresure(ownerPos);
|
||||
if (closestTreasure != nullptr && digUnlocked) {
|
||||
NiPoint3 treasurePos = closestTreasure->GetPosition();
|
||||
const float distance = Vector3::DistanceSquared(ownerPos, treasurePos);
|
||||
if (distance < 10 * 10) {
|
||||
StartInteract(treasurePos, PetInteractType::treasure);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_Timer += 0.5f;
|
||||
}
|
||||
|
||||
void PetComponent::OnInteract() {
|
||||
LOG_DEBUG("Beginning interaction with object!");
|
||||
|
||||
NiPoint3 ownerPos = GetOwner()->GetPosition();
|
||||
NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
|
||||
const float distanceFromOwner = Vector3::DistanceSquared(ownerPos, currentPos);
|
||||
|
||||
if (distanceFromOwner > 25 * 25) {
|
||||
LOG_DEBUG("Disengaging from object interaction due to player distance.");
|
||||
StopInteract();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (GetInteractType()) {
|
||||
case PetInteractType::bouncer:
|
||||
StartInteractBouncer();
|
||||
break;
|
||||
|
||||
case PetInteractType::treasure:
|
||||
StartInteractDig();
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_DEBUG("INTERACT = NONE! RETURNING!");
|
||||
StopInteract();
|
||||
m_Timer += 0.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PetComponent::OnTether() {
|
||||
m_Timer += 0.5f;
|
||||
}
|
||||
|
||||
void PetComponent::StartInteract(NiPoint3 position, PetInteractType interactType) {
|
||||
SetInteractType(interactType);
|
||||
SetAbility(PetAbilityType::GoToObject);
|
||||
SetPetAiState(PetAiState::goToObj);
|
||||
m_MovementAI->SetMaxSpeed(m_RunSpeed);
|
||||
m_MovementAI->SetHaltDistance(0.0f);
|
||||
m_MovementAI->SetDestination(position);
|
||||
LOG_DEBUG("Starting interaction!");
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void PetComponent::StopInteract() {
|
||||
SetInteractType(PetInteractType::none);
|
||||
SetAbility(PetAbilityType::Invalid);
|
||||
SetPetAiState(PetAiState::follow);
|
||||
m_MovementAI->SetMaxSpeed(m_SprintSpeed);
|
||||
m_MovementAI->SetHaltDistance(m_FollowRadius);
|
||||
LOG_DEBUG("Stopping interaction!");
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void PetComponent::StartInteractBouncer() {
|
||||
SetAbility(PetAbilityType::JumpOnObject);
|
||||
NiPoint3 destination = m_MovementAI->GetDestination();
|
||||
SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(destination);
|
||||
m_Interaction = closestSwitch->GetParentEntity()->GetObjectID();
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
closestSwitch->EntityEnter(m_Parent);
|
||||
}
|
||||
|
||||
void PetComponent::StartInteractDig() {
|
||||
//m_InInteract = true;
|
||||
//m_TresureTime = 2.0f; //TODO: Remove magic number
|
||||
m_Interaction == LWOOBJID_EMPTY; //TODO: Make this not empty
|
||||
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce, true);\
|
||||
m_Timer = 2.0f;
|
||||
}
|
||||
|
||||
void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
||||
AddDrainImaginationTimer(item, fromTaming);
|
||||
|
||||
@ -1282,13 +1300,3 @@ void PetComponent::LoadPetNameFromModeration() {
|
||||
void PetComponent::SetPreconditions(std::string& preconditions) {
|
||||
m_Preconditions = new PreconditionExpression(preconditions);
|
||||
}
|
||||
|
||||
void PetComponent::StartInteractDig() {
|
||||
//m_InInteract = true;
|
||||
m_TresureTime = 2.0f; //TODO: Remove magic number
|
||||
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::DigTreasure, true);
|
||||
}
|
||||
|
||||
void PetComponent::EndInteractDig() {
|
||||
//m_InInteract = false;
|
||||
}
|
@ -9,22 +9,31 @@
|
||||
/*
|
||||
* The current state of the pet AI
|
||||
*/
|
||||
enum class PetAiState : uint {
|
||||
enum class PetAiState : uint8_t {
|
||||
idle = 0, // Doing nothing
|
||||
spawn, // Spawning into the world
|
||||
follow, // Following player
|
||||
interact, // Beginning interaction
|
||||
follow, // Begin following
|
||||
goToObj, // Go to object
|
||||
interact, // Interact with an object
|
||||
despawn // Despawning from world
|
||||
};
|
||||
|
||||
/*
|
||||
* The type of object the pet is interacting with
|
||||
*/
|
||||
enum class PetInteractType : uint8_t {
|
||||
none, // Not interacting
|
||||
treasure, // Treasure dig
|
||||
bouncer // Bouncer switch
|
||||
};
|
||||
|
||||
/*
|
||||
* The status of the pet: Governs the icon above their head and the interactions available
|
||||
*/
|
||||
enum PetStatus : uint32_t {
|
||||
NONE,
|
||||
BEING_TAMED = 0x10,
|
||||
IS_NOT_WAITING = 0x20, // Right name? - used to be decimal 20
|
||||
IS_NOT_WAITING = 0x20,
|
||||
PLAY_SPAWN_ANIM = 0x80,
|
||||
TAMEABLE = 0x4000000
|
||||
};
|
||||
@ -35,8 +44,7 @@ enum PetEmote : int32_t {
|
||||
Bounce
|
||||
};
|
||||
|
||||
enum class PetAbilityType
|
||||
{
|
||||
enum class PetAbilityType {
|
||||
Invalid,
|
||||
GoToObject,
|
||||
JumpOnObject,
|
||||
@ -125,6 +133,46 @@ public:
|
||||
*/
|
||||
void Wander();
|
||||
|
||||
/**
|
||||
* Called when the pet is first spawned
|
||||
*/
|
||||
void OnSpawn();
|
||||
|
||||
/**
|
||||
* Continues a step in the follow state, making sure that the entity is around its start position
|
||||
*/
|
||||
void OnFollow();
|
||||
|
||||
/**
|
||||
* Continues a step in the interact state, handling the pet's interaction with an entity
|
||||
*/
|
||||
void OnInteract();
|
||||
|
||||
/**
|
||||
* Continues a step in the tether state, making the entity run towards its target
|
||||
*/
|
||||
void OnTether();
|
||||
|
||||
/**
|
||||
* Start a pet interaction with an object at a given position
|
||||
*/
|
||||
void StartInteract(NiPoint3 position, PetInteractType interactType);
|
||||
|
||||
/**
|
||||
* Stop a pet interaction with an object
|
||||
*/
|
||||
void StopInteract();
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -231,7 +279,12 @@ public:
|
||||
bool GetIsReadyToDig() { return m_ReadyToDig; };
|
||||
|
||||
/**
|
||||
* Start the dig interaction
|
||||
* Start the pet bouncer interaction
|
||||
*/
|
||||
void StartInteractBouncer();
|
||||
|
||||
/**
|
||||
* Start the treasure dig interaction
|
||||
*/
|
||||
void StartInteractDig();
|
||||
|
||||
@ -360,6 +413,11 @@ private:
|
||||
*/
|
||||
LWOOBJID m_Interaction;
|
||||
|
||||
/**
|
||||
* The type of object that the pet is currently interacting with (e.g. a treasure chest or switch)
|
||||
*/
|
||||
PetInteractType m_InteractType;
|
||||
|
||||
/**
|
||||
* The ID of the entity that owns this pet
|
||||
*/
|
||||
@ -436,6 +494,11 @@ private:
|
||||
*/
|
||||
NiPoint3 m_StartPosition;
|
||||
|
||||
/**
|
||||
* The halting radius of the pet while following a player
|
||||
*/
|
||||
float m_FollowRadius;
|
||||
|
||||
/**
|
||||
* The movement AI component that is related to this pet, required to move it around
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user